Browse Source

post MR fixes and other minor improvements

Olivier Massot 2 năm trước cách đây
mục cha
commit
ed7cfa68db

+ 1 - 1
components/Layout/AlertBar/Cotisation.vue

@@ -7,7 +7,7 @@ Barre d'alerte qui s'affiche pour donner l'état de la cotisation
 <template>
   <main>
     <UiSystemBar
-        v-if="alert !== null"
+        v-if="alert"
         :text="$t(alert.text)"
         icon="fas fa-info-circle"
         :on-click="alert.callback"

+ 34 - 30
components/Layout/Parameters/General.vue

@@ -9,61 +9,65 @@
       <v-row>
         <v-col cols="6">
           <UiInputDatePicker
+              v-if="organizationProfile.isSchool"
               v-model="parameters.financialDate"
               field="financialDate"
               label="start_date_of_financial_season"
+              class="my-2"
+          />
+
+          <UiInputDatePicker
+              v-if="organizationProfile.isSchool"
+              v-model="parameters.startCourseDate"
+              field="startCourseDate"
+              label="start_date_of_courses"
+              class="my-2"
+          />
+
+          <UiInputCheckbox
+              v-model="parameters.showAdherentList"
+              field="showAdherentList"
+              label="show_adherents_list_and_their_coordinates"
+          />
+
+          <UiInputAutocompleteWithEnum
+              v-model="parameters.timezone"
+              enum-name="timezone"
+              field="timezone"
           />
         </v-col>
 
         <v-col cols="6">
           <UiInputDatePicker
+              v-if="organizationProfile.isSchool"
               v-model="parameters.musicalDate"
               field="musicalDate"
               label="start_date_of_activity_season"
+              class="my-2"
           />
-        </v-col>
-      </v-row>
 
-      <v-row>
-        <v-col cols="6">
-          <UiInputDatePicker
-              v-model="parameters.startCourseDate"
-              field="startCourseDate"
-              label="start_date_of_courses"
-          />
-        </v-col>
-        <v-col cols="6">
           <UiInputDatePicker
+              v-if="organizationProfile.isSchool"
               v-model="parameters.endCourseDate"
               field="endCourseDate"
               label="end_date_of_courses"
+              class="my-2"
           />
-        </v-col>
-      </v-row>
 
-      <v-row>
-        <v-col cols="6">
-          <UiInputCheckbox
-              v-model="parameters.showAdherentList"
-              field="showAdherentList"
-              label="show_adherents_list_and_their_coordinates"
-          />
-        </v-col>
-        <v-col cols="6">
           <UiInputCheckbox
+              v-if="organizationProfile.isSchool && organizationProfile.isAssociation"
               v-model="parameters.studentsAreAdherents"
               field="studentsAreAdherents"
               label="students_are_also_association_members"
           />
-        </v-col>
-      </v-row>
 
-      <v-row>
-        <UiInputCombobox
-            v-model="parameters.timezone"
-            field="timezone"
-            :items="['Europe/Paris', 'Europe/Zurich', 'Indian/Reunion']"
-        />
+          <!-- TODO: reprendre l'UiInput -->
+          <UiInputImage
+              v-model="parameters['qrCode_id']"
+              field="qrCode_id"
+              label="licenceQrCode"
+          />
+        </v-col>
       </v-row>
     </UiForm>
   </LayoutContainer>

+ 1 - 1
components/Layout/Parameters/Website.vue

@@ -65,7 +65,7 @@
             />
           </v-row>
 
-          <v-row class="my-8">
+          <v-row class="my-8" v-if="!organizationProfile.isCmf">
             <v-btn
               v-if="!parameters.desactivateOpentalentSiteWeb"
               color="error"

+ 11 - 1
components/Ui/Input/AutocompleteWithEnum.vue

@@ -3,7 +3,7 @@
   <UiInputAutocomplete
       :model-value="modelValue"
       :field="field"
-      :items="enumItems ?? []"
+      :items="items"
       :is-loading="pending"
       :return-object="false"
       item-title="label"
@@ -16,6 +16,9 @@
 
 
 import {useEnumFetch} from "~/composables/data/useEnumFetch";
+import ArrayUtils from "~/services/utils/arrayUtils";
+import {ComputedRef} from "@vue/reactivity";
+import {Enum} from "~/types/data";
 
 const props = defineProps({
   modelValue: {
@@ -43,6 +46,13 @@ const { fetch } = useEnumFetch()
 
 const { data: enumItems, pending } = fetch(props.enumName)
 
+const items: ComputedRef<Array<Enum>> = computed(() => {
+  if (!enumItems.value) {
+    return []
+  }
+  return ArrayUtils.sortObjectsByProp(enumItems.value, 'label') as Array<Enum>
+})
+
 </script>
 
 <style scoped lang="scss">

+ 5 - 1
lang/fr.json

@@ -639,5 +639,9 @@
   "evaluation_criterium_edition_is_admin_only": "Autoriser uniquement l'administration à modifier les critères d'évaluation",
   "max_note_for_pedagogical_followup": "Note maximale pour les notes du suivi pédagogique (entre 1 et 100) ",
   "Bad Request": "Requête invalide",
-  "bulletins": "Bulletins"
+  "bulletins": "Bulletins",
+  "Indian/Reunion": "Indian/Reunion",
+  "Europe/Zurich": "Europe/Zurich",
+  "Europe/Paris": "Europe/Paris",
+  "licenceQrCode": "QrCode pour la licence"
 }

+ 0 - 9
nuxt.config.ts

@@ -40,15 +40,6 @@ export default defineNuxtConfig({
             baseUrlTypo3: '',
             baseUrlMercure: '',
             supportUrl: '',
-            school_product: 'school',
-            school_premium_product: 'school-premium',
-            artist_product: 'artist',
-            artist_premium_product: 'artist-premium',
-            manager_product: 'manager',
-            cmf_network: 'CMF',
-            ffec_network: 'FFEC',
-            OPENTALENT_MANAGER_ID: 93931,
-            CMF_ID: 12097
         }
     },
     hooks: {

+ 23 - 18
pages/parameters/index.vue

@@ -27,32 +27,32 @@ Page Paramètres
             <LayoutParametersWebsite />
           </v-window-item>
 
-          <v-window-item value="teaching">
+          <v-window-item v-if="organizationProfile.isSchool" value="teaching">
             <LayoutParametersTeaching />
           </v-window-item>
 
-          <v-window-item value="intranet_access">
+          <v-window-item v-if="organizationProfile.isSchool" value="intranet_access">
             <LayoutParametersIntranet />
           </v-window-item>
 
-          <v-window-item value="educationNotations">
+          <v-window-item v-if="organizationProfile.isSchool" value="educationNotations">
             <LayoutParametersEducationNotation />
           </v-window-item>
 
-          <v-window-item value="bulletin">
+          <v-window-item v-if="organizationProfile.isSchool" value="bulletin">
             <LayoutParametersBulletin />
           </v-window-item>
 
-          <v-window-item value="educationTimings">
+          <v-window-item v-if="organizationProfile.isSchool" value="educationTimings">
           </v-window-item>
 
-          <v-window-item value="attendances">
+          <v-window-item v-if="organizationProfile.isSchool" value="attendances">
           </v-window-item>
 
-          <v-window-item value="residenceAreas">
+          <v-window-item v-if="organizationProfile.isSchool" value="residenceAreas">
           </v-window-item>
 
-          <v-window-item value="sms_option">
+          <v-window-item v-if="organizationProfile.hasModule('Sms')" value="sms_option">
           </v-window-item>
 
           <v-window-item value="super_admin">
@@ -66,24 +66,29 @@ Page Paramètres
 
 <script setup lang="ts">
 
+  import {useOrganizationProfileStore} from "~/stores/organizationProfile";
+
+  const organizationProfile = useOrganizationProfileStore()
+
   const tabs = [
     'general_parameters',
     'website',
-    'teaching',
-    'intranet_access',
-    'educationNotations',
-    'bulletin',
-    'educationTimings',
-    'attendances',
-    'residenceAreas',
-    'sms_option',
+    organizationProfile.isSchool ? 'teaching' : null,
+    organizationProfile.isSchool ? 'intranet_access' : null,
+    organizationProfile.isSchool ? 'educationNotations': null,
+    organizationProfile.isSchool ? 'bulletin' : null,
+    organizationProfile.isSchool ? 'educationTimings' : null,
+    organizationProfile.isSchool ? 'attendances' : null,
+    organizationProfile.isSchool ? 'residenceAreas' : null,
+    organizationProfile.hasModule('Sms') ? 'sms_option' : null,
     'super_admin',
-  ]
+  ].filter((v) => v !== null)
 
   const router = useRouter()
   const route = useRoute()
   let mounted = false
 
+
   /**
    * Update the current route's query with a new value for 'tab' parameter
    * @param tab
@@ -96,7 +101,7 @@ Page Paramètres
 
   onMounted(() => {
     if (!route.query || !route.query.tab || !tabs.includes(route.query.tab as string)) {
-      updateQuery(tabs[0])
+      updateQuery(tabs[0] ?? 'general_parameters')
     }
     currentTab.value = route.query.tab as string
     mounted = true

+ 2 - 6
services/validation/subdomainValidation.ts

@@ -14,7 +14,7 @@ export default class SubdomainValidation {
      * @param subdomain
      */
     public static isValid(subdomain: string | null): boolean {
-        return subdomain !== null && subdomain.match(/^[\w\-]{2,60}$/) !== null
+        return subdomain !== null && subdomain.match(/^[a-z0-9][a-z0-9\-]{0,61}[a-z0-9]$/) !== null
     }
 
     /**
@@ -22,11 +22,7 @@ export default class SubdomainValidation {
      * @param subdomain
      */
     public async isAvailable(subdomain: string): Promise<boolean> {
-        if (subdomain === null) {
-            return true
-        }
-        const { apiRequestService } = useAp2iRequestService()
-        const subdomainAvailability: any = await apiRequestService.get('/api/subdomains/is_available', {'subdomain': subdomain})
+        const subdomainAvailability: any = await this.apiRequestService.get('/api/subdomains/is_available', {'subdomain': subdomain})
         return subdomainAvailability && subdomainAvailability['available'] === true
     }
 }

+ 12 - 14
stores/organizationProfile.ts

@@ -2,6 +2,7 @@ import { BaseOrganizationProfile } from '~/types/interfaces'
 import { defineStore } from "pinia";
 import {computed, Ref} from "@vue/reactivity";
 import * as _ from 'lodash-es'
+import {LEGAL_STATUS, NETWORK, ORGANIZATION_ID, PRODUCT} from '~/types/enum/enums';
 
 export const useOrganizationProfileStore = defineStore('organizationProfile', () => {
 
@@ -19,8 +20,6 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
   const website: Ref<string | null>  = ref(null)
   const parents: Ref<Array<BaseOrganizationProfile>> = ref([])
 
-  const runtimeConfig = useRuntimeConfig()
-
   // Getters
   /**
    * L'organization fait-elle partie du réseau CMF ?
@@ -29,7 +28,7 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
    */
   const isCmf = computed( (): boolean => {
     return networks.value && networks.value.filter((network: string) => {
-      return network === runtimeConfig.cmf_network
+      return network === NETWORK.CMF
     }).length > 0
   })
 
@@ -40,7 +39,7 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
    */
   const isFfec = computed( (): boolean => {
     return networks.value && networks.value.filter((network: string) => {
-      return network === runtimeConfig.ffec_network
+      return network === NETWORK.FFEC
     }).length > 0
   })
 
@@ -58,7 +57,7 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
    * @return {boolean}
    */
   const isArtistProduct = computed( (): boolean => {
-    return product.value === runtimeConfig.artist_product
+    return product.value === PRODUCT.ARTIST
   })
 
   /**
@@ -66,7 +65,7 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
    * @return {boolean}
    */
   const isArtistPremiumProduct = computed( (): boolean => {
-    return product.value === runtimeConfig.artist_premium_product
+    return product.value === PRODUCT.ARTIST_PREMIUM
   })
 
   /**
@@ -83,7 +82,7 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
    * @return {boolean}
    */
   const isSchoolProduct = computed( (): boolean => {
-    return product.value === runtimeConfig.school_product
+    return product.value === PRODUCT.SCHOOL
   })
 
   /**
@@ -92,7 +91,7 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
    * @return {boolean}
    */
   const isSchoolPremiumProduct = computed( (): boolean => {
-    return product.value === runtimeConfig.school_premium_product
+    return product.value === PRODUCT.SCHOOL_PREMIUM
   })
 
   /**
@@ -104,11 +103,11 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
   })
 
   /**
-   * L'organization possède t'elle un produit manager
+   * L'organization possède-t-elle un produit manager
    * @return {boolean}
    */
   const isManagerProduct = computed( (): boolean => {
-    return product.value === runtimeConfig.manager_product
+    return product.value === PRODUCT.MANAGER
   })
 
   /**
@@ -124,7 +123,7 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
    * @return {boolean|null}
    */
   const isAssociation = computed(():any => {
-    return legalStatus.value === 'ASSOCIATION_LAW_1901';
+    return legalStatus.value === LEGAL_STATUS.ASSOCIATION_LAW_1901;
   })
 
   /**
@@ -133,9 +132,7 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
    * @return {boolean}
    */
   const isCMFCentralService = computed((): boolean => {
-    if(runtimeConfig.CMF_ID)
-      return id.value === parseInt(runtimeConfig.CMF_ID)
-    return false
+    return id.value === ORGANIZATION_ID.CMF
   })
 
   const getWebsite = computed((): string | null => {
@@ -200,6 +197,7 @@ export const useOrganizationProfileStore = defineStore('organizationProfile', ()
     website,
     parents,
     isCmf,
+    isCMFCentralService,
     isFfec,
     isInsideNetwork,
     isArtistProduct,

+ 25 - 0
types/enum/enums.ts

@@ -1,3 +1,27 @@
+
+
+export const enum PRODUCT {
+  SCHOOL = 'school',
+  SCHOOL_PREMIUM = 'school-premium',
+  ARTIST = 'artist',
+  ARTIST_PREMIUM = 'artist-premium',
+  MANAGER = 'manager'
+}
+
+export const enum NETWORK {
+  CMF = 'CMF',
+  FFEC = 'FFEC',
+}
+
+export const enum LEGAL_STATUS {
+  ASSOCIATION_LAW_1901= 'ASSOCIATION_LAW_1901'
+}
+
+export const enum ORGANIZATION_ID {
+  CMF = 12097,
+  OPENTALENT_MANAGER = 93931
+}
+
 export const enum FORM_FUNCTION {
   CREATE = 'CREATE',
   EDIT = 'EDIT'
@@ -50,3 +74,4 @@ export const enum SUBMIT_TYPE {
   SAVE = 'save',
   SAVE_AND_BACK= 'save_and_back'
 }
+