소스 검색

add cycle table and cycle edition

Olivier Massot 2 년 전
부모
커밋
d88348f688

+ 1 - 1
components/Layout/Dialog.vue

@@ -38,7 +38,7 @@ import {PropType} from "@vue/runtime-core";
 
 const props = defineProps({
   show: {
-    type: Object as PropType<Ref<Boolean>>,
+    type: [Boolean, Object],
     required: true
   },
   contentClass: {

+ 41 - 0
components/Layout/Parameters/CycleEditForm.vue

@@ -0,0 +1,41 @@
+<template>
+    <UiForm
+        ref="form"
+        :model="Cycle"
+        :entity="cycle"
+        :submitActions="submitActions"
+    >
+      <UiInputText field="label" v-model="cycle.label" :rules="rules()" />
+    </UiForm>
+</template>
+
+<script setup lang="ts">
+import Cycle from "~/models/Education/Cycle";
+import {AnyJson} from "~/types/data";
+import {SUBMIT_TYPE} from "~/types/enum/enums";
+
+const props = defineProps({
+  cycle: {
+    type: Object as () => Cycle,
+    required: true
+  }
+})
+
+const i18n = useI18n()
+
+const goBackRoute = { path: `/parameters`, query: { tab: 'teaching' } }
+
+const submitActions = computed(() => {
+  let actions: AnyJson = {}
+  actions[SUBMIT_TYPE.SAVE_AND_BACK] = goBackRoute
+  return actions
+})
+
+const rules = () => [
+  (label: string | null) => (label !== null && label.length > 0) || i18n.t('please_enter_a_value'),
+]
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 108 - 1
components/Layout/Parameters/Teaching.vue

@@ -1,13 +1,120 @@
 <template>
   <LayoutContainer>
-    <i>Teaching</i>
+    <UiLoadingPanel v-if="pending" />
+    <UiForm
+        v-else
+        :model="Parameters"
+        :entity="parameters"
+    >
+      <v-table>
+        <thead>
+          <tr>
+            <td>{{ $t('originalLabel') }}</td>
+            <td>{{ $t('effectiveLabel') }}</td>
+          </tr>
+        </thead>
+
+        <tbody>
+          <tr v-for="enumItem in cycleEnum">
+            <td>{{ $t(enumItem.value) }}</td>
+            <td class="cycle-editable-cell">
+              {{ orderedCycles[enumItem.value] ? orderedCycles[enumItem.value].label : $t(enumItem.value) }}
+            </td>
+            <td style="max-width: 24px;">
+              <v-btn
+                  :flat="true"
+                  icon="fa fa-pen"
+                  class="cycle-edit-icon"
+                  @click="orderedCycles[enumItem.value] ? goToCycleEditPage(orderedCycles[enumItem.value].id) : goToCycleCreatePage(enumItem.value)"
+              />
+            </td>
+          </tr>
+        </tbody>
+      </v-table>
+
+      <v-row>
+        <v-col cols="6">
+          <UiInputCheckbox
+              v-model="parameters.showEducationIsACollectivePractice"
+              field="showEducationIsACollectivePractice"
+              label="allow_to_configure_teachings_with_played_instrument_choice"
+          />
+        </v-col>
+      </v-row>
+    </UiForm>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
+import Parameters from "~/models/Organization/Parameters";
+import {useEntityFetch} from "~/composables/data/useEntityFetch";
+import Cycle from "~/models/Education/Cycle";
+import {AsyncData} from "#app";
+import {useOrganizationProfileStore} from "~/stores/organizationProfile";
+import {AnyJson} from "~/types/data";
+import {useEnumFetch} from "~/composables/data/useEnumFetch";
+
+const organizationProfile = useOrganizationProfileStore()
+
+if (organizationProfile.parametersId === null) {
+  throw new Error('Missing organization parameters id')
+}
+
+const { fetch, fetchCollection } = useEntityFetch()
+const { fetch: fetchEnum } = useEnumFetch()
+
+
+const { data: cycleEnum, pending: enumPending } = fetchEnum('education_cycle')
+
+const { data: parameters, pending: parametersPending } = fetch(Parameters, organizationProfile.parametersId) as AsyncData<Parameters, Parameters | true>
+
+const { data: cycles, pending: cyclesPending } = fetchCollection(Cycle)
+
+const pending: ComputedRef<boolean> = computed(() => enumPending.value || parametersPending.value || cyclesPending.value)
+
+const orderedCycles: ComputedRef<AnyJson> = computed(() => {
+  if (pending.value) {
+    return []
+  }
+
+  let orderedCycles: AnyJson = {}
+
+  for (const enumItem of cycleEnum.value) {
+    orderedCycles[enumItem.value] = null
+  }
+
+  for (const cycle of cycles.value.items) {
+    if (!orderedCycles.hasOwnProperty(cycle.cycleEnum)) {
+      console.error('Unknown cycle enum : ' + cycle.cycleEnum)
+      continue
+    }
+
+    orderedCycles[cycle.cycleEnum] = cycle
+  }
+
+  return orderedCycles
+})
+
+
+const goToCycleEditPage = (id: number) => {
+  navigateTo(`parameters/cycles/${id}`)
+}
+
+const goToCycleCreatePage = (cycleEnumItem: string) => {
+  navigateTo(`parameters/cycles/new?cycleEnum=` + cycleEnumItem)
+}
 
 </script>
 
 <style scoped lang="scss">
 
+.cycle-edit-icon {
+  color: rgb(var(--v-theme-primary));
+}
+
+:deep(.cycle-edit-icon .v-icon) {
+  font-size: 18px;
+}
+
+
 </style>

+ 3 - 1
lang/fr.json

@@ -19,6 +19,7 @@
   "this_subdomain_is_already_in_use": "Ce sous-domaine est déjà utilisé",
   "this_subdomain_is_available": "Ce sous-domaine est disponible",
   "subdomain_can_not_contain_spaces_or_special_cars": "Le sous-domaine ne doit pas contenir d'espaces ni de caractères spéciaux",
+  "please_enter_a_value": "Veuillez saisir une valeur",
   "please_enter_a_value_for_the_subdomain": "Veuillez saisir une valeur pour le sous-domaine",
   "validation_ongoing": "Validation en cours",
   "until": "Jusqu'au",
@@ -632,5 +633,6 @@
   "originalLabel": "Libellés d'origine",
   "effectiveLabel": "Libellés actuellement utilisés",
   "allow_to_configure_teachings_with_played_instrument_choice": "Permettre de configurer les enseignements avec le choix sur l'instrument joué",
-  "label": "Libellé"
+  "label": "Libellé",
+  "undefined": "Indéfini"
 }

+ 3 - 0
models/Education/Cycle.ts

@@ -15,6 +15,9 @@ export default class Cycle extends ApiModel {
   @Str(null)
   declare label: string|null
 
+  @Str(null)
+  declare cycleEnum: string|null
+
   @Num(0)
   declare order: number
 }

+ 30 - 0
pages/parameters/cycles/[id].vue

@@ -0,0 +1,30 @@
+<template>
+  <main>
+    <LayoutContainer>
+      <UiLoadingPanel v-if="pending" />
+      <div v-else>
+        <LayoutParametersCycleEditForm :cycle="cycle" />
+      </div>
+    </LayoutContainer>
+  </main>
+</template>
+
+<script setup lang="ts">
+import {useEntityFetch} from "~/composables/data/useEntityFetch";
+import Cycle from "~/models/Education/Cycle";
+
+const { fetch } = useEntityFetch()
+const route = useRoute()
+
+if (!route.params.id || isNaN(route.params.id as any)) {
+  throw new Error('no id found')
+}
+
+const id: number = parseInt(route.params.id as string)
+
+const { data: cycle, pending } = fetch(Cycle, id)
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 27 - 0
pages/parameters/cycles/new.vue

@@ -0,0 +1,27 @@
+<template>
+  <main>
+    <LayoutContainer>
+      <div>
+        <LayoutParametersCycleEditForm :cycle="cycle" />
+      </div>
+    </LayoutContainer>
+  </main>
+</template>
+
+<script setup lang="ts">
+import Cycle from "~/models/Education/Cycle";
+import {useEntityManager} from "~/composables/data/useEntityManager";
+
+const { em } = useEntityManager()
+const route = useRoute()
+
+if (!route.query || !route.query.cycleEnum) {
+  throw new Error('Missing cycle enum parameter')
+}
+
+const cycle = em.newInstance(Cycle, { cycleEnum: route.query.cycleEnum })
+</script>
+
+<style scoped lang="scss">
+
+</style>