Browse Source

apply eslint - prettier fixer and manual fixes

Olivier Massot 1 year ago
parent
commit
d2444bd94b
100 changed files with 2218 additions and 2041 deletions
  1. 17 1
      .eslintrc.cjs
  2. 5 0
      README.md
  3. 87 90
      composables/data/useAp2iRequestService.ts
  4. 46 30
      composables/data/useEntityFetch.ts
  5. 9 9
      composables/data/useEntityManager.ts
  6. 8 12
      composables/data/useEnumFetch.ts
  7. 12 11
      composables/data/useEnumManager.ts
  8. 22 17
      composables/data/useImageFetch.ts
  9. 9 9
      composables/data/useImageManager.ts
  10. 55 50
      composables/data/useRefreshProfile.ts
  11. 9 9
      composables/form/useFieldViolation.ts
  12. 20 11
      composables/form/useValidation.ts
  13. 2 3
      composables/form/validation/useSubdomainValidation.ts
  14. 13 8
      composables/layout/useExtensionPanel.ts
  15. 15 9
      composables/layout/useMenu.ts
  16. 14 9
      composables/utils/useAdminUrl.ts
  17. 14 11
      composables/utils/useDownloadFile.ts
  18. 4 5
      composables/utils/useHomeUrl.ts
  19. 10 10
      composables/utils/useI18nUtils.ts
  20. 17 13
      composables/utils/useRedirect.ts
  21. 8 8
      composables/utils/useValidationUtils.ts
  22. 1 1
      config/abilities/pages/myAccount.yaml
  23. 111 115
      config/theme.ts
  24. 33 24
      i18n.config.ts
  25. 2 1
      lang/fr.json
  26. 6 0
      layouts/.eslintrc.cjs
  27. 1 3
      layouts/default.vue
  28. 21 15
      layouts/error.vue
  29. 7 10
      layouts/parameters.vue
  30. 5 5
      models/Access/Access.ts
  31. 4 4
      models/Access/AdminAccess.ts
  32. 4 4
      models/Access/MyProfile.ts
  33. 5 5
      models/Access/PersonalizedList.ts
  34. 2 3
      models/ApiModel.ts
  35. 30 28
      models/ApiResource.ts
  36. 3 3
      models/Billing/ResidenceArea.ts
  37. 7 9
      models/Booking/AttendanceBookingReason.ts
  38. 9 9
      models/Core/AddressPostal.ts
  39. 9 9
      models/Core/BankAccount.ts
  40. 10 10
      models/Core/ContactPoint.ts
  41. 2 2
      models/Core/Country.ts
  42. 2 2
      models/Core/File.ts
  43. 5 5
      models/Core/Notification.ts
  44. 5 5
      models/Core/NotificationMessage.ts
  45. 4 4
      models/Core/NotificationUsers.ts
  46. 9 9
      models/Core/Tagg.ts
  47. 4 4
      models/Education/Cycle.ts
  48. 2 2
      models/Education/EducationTiming.ts
  49. 2 2
      models/Export/LicenceCmfOrganizationER.ts
  50. 2 2
      models/Network/Network.ts
  51. 3 3
      models/Network/NetworkOrganization.ts
  52. 9 9
      models/OnlineRegistration/RegistrationAvailability.ts
  53. 2 2
      models/OnlineRegistration/RegistrationStatus.ts
  54. 9 9
      models/Organization/Cotisation.ts
  55. 20 15
      models/Organization/DolibarrAccount.ts
  56. 13 16
      models/Organization/MobytUserStatus.ts
  57. 34 34
      models/Organization/Organization.ts
  58. 2 2
      models/Organization/OrganizationAddressPostal.ts
  59. 2 2
      models/Organization/OrganizationArticle.ts
  60. 5 5
      models/Organization/OrganizationLicence.ts
  61. 2 2
      models/Organization/OrganizationNetwork.ts
  62. 25 25
      models/Organization/OrganizationProfile.ts
  63. 4 4
      models/Organization/Parameters.ts
  64. 2 2
      models/Organization/Subdomain.ts
  65. 9 9
      models/Organization/SubdomainAvailability.ts
  66. 2 2
      models/Organization/TypeOfPractice.ts
  67. 5 5
      models/Person/Person.ts
  68. 9 10
      models/decorators.ts
  69. 6 4
      models/models.ts
  70. 190 143
      nuxt.config.ts
  71. 3 2
      package.json
  72. 6 0
      pages/.eslintrc.cjs
  73. 32 31
      pages/cmf_licence_structure.vue
  74. 0 11
      pages/index.vue
  75. 18 26
      pages/organization.vue.off
  76. 0 548
      pages/organization/index.vue
  77. 580 0
      pages/organization/index.vue.off
  78. 8 9
      pages/parameters.vue
  79. 3 3
      pages/parameters/attendance_booking_reasons/[id].vue
  80. 4 4
      pages/parameters/attendance_booking_reasons/new.vue
  81. 47 40
      pages/parameters/attendances.vue
  82. 39 40
      pages/parameters/bulletin.vue
  83. 6 12
      pages/parameters/cycles/[id].vue
  84. 31 32
      pages/parameters/education_notation.vue
  85. 3 4
      pages/parameters/education_timings/[id].vue
  86. 24 21
      pages/parameters/education_timings/index.vue
  87. 4 4
      pages/parameters/education_timings/new.vue
  88. 59 54
      pages/parameters/general_parameters.vue
  89. 2 3
      pages/parameters/index.vue
  90. 36 35
      pages/parameters/intranet.vue
  91. 4 4
      pages/parameters/residence_areas/[id].vue
  92. 28 28
      pages/parameters/residence_areas/index.vue
  93. 2 2
      pages/parameters/residence_areas/new.vue
  94. 15 16
      pages/parameters/sms.vue
  95. 38 43
      pages/parameters/subdomains/[id].vue
  96. 12 12
      pages/parameters/subdomains/new.vue
  97. 35 35
      pages/parameters/super_admin.vue
  98. 38 29
      pages/parameters/teaching.vue
  99. 80 64
      pages/parameters/website.vue
  100. 5 6
      pages/poc.vue

+ 17 - 1
.eslintrc.cjs

@@ -23,7 +23,8 @@ module.exports = {
     ".nuxt",
     ".nuxt",
     "coverage/*",
     "coverage/*",
     "vendor/*",
     "vendor/*",
-    "dist/*"
+    "dist/*",
+    "tests/*",
   ],
   ],
   plugins: [
   plugins: [
     "vue",
     "vue",
@@ -31,5 +32,20 @@ module.exports = {
   ],
   ],
   // add your custom rules here
   // add your custom rules here
   rules: {
   rules: {
+    "no-console": 0, // on autorise les appels à la console (puisque ceux ci seront de toute façon nettoyés à la compilation)
+    'vue/valid-v-slot': ['error', {
+      allowModifiers: true,
+    }],
+  },
+  "globals": {
+    "useRuntimeConfig": "readonly",
+    "navigateTo": "readonly",
+    "computed": "readonly",
+    "ref": "readonly",
+    "definePageMeta": "readonly",
+    "useRouter": "readonly",
+    "useRoute": "readonly",
+    "useI18n": "readonly",
+    "onMounted": "readonly",
   }
   }
 }
 }

+ 5 - 0
README.md

@@ -97,6 +97,11 @@ Sur les environnements où app est servie par supervisor, on peut consulter les
 > le `-6000` étant le nombre de bytes à afficher
 > le `-6000` étant le nombre de bytes à afficher
 > Voir plus : http://supervisord.org/running.html#supervisorctl-command-line-options
 > Voir plus : http://supervisord.org/running.html#supervisorctl-command-line-options
 
 
+### Exécuter ESLint
+
+    yarn eslint
+
+
 ### Faire fonctionner le HMR
 ### Faire fonctionner le HMR
 
 
 Si le HMR (Hot Module Reload) ne fontionne pas et qu'un message d'erreur est logué en console disant que l'adresse
 Si le HMR (Hot Module Reload) ne fontionne pas et qu'un message d'erreur est logué en console disant que l'adresse

+ 87 - 90
composables/data/useAp2iRequestService.ts

@@ -1,109 +1,106 @@
-import {TYPE_ALERT} from "~/types/enum/enums";
-import ApiRequestService from "~/services/data/apiRequestService";
-import type {Ref} from "@vue/reactivity";
-import {usePageStore} from "~/stores/page";
-import UnauthorizedError from "~/services/error/UnauthorizedError";
-import {useAccessProfileStore} from "~/stores/accessProfile";
-import type {AssociativeArray} from "~/types/data";
-import type {FetchContext, FetchOptions} from "ofetch";
+import type { Ref } from 'vue'
+import type { FetchContext, FetchOptions } from 'ofetch'
+import { TYPE_ALERT } from '~/types/enum/enums'
+import ApiRequestService from '~/services/data/apiRequestService'
+import { usePageStore } from '~/stores/page'
+import UnauthorizedError from '~/services/error/UnauthorizedError'
+import { useAccessProfileStore } from '~/stores/accessProfile'
+import type { AssociativeArray } from '~/types/data'
 
 
 /**
 /**
  * Retourne une instance de ApiRequestService configurée pour interroger l'api Ap2i
  * Retourne une instance de ApiRequestService configurée pour interroger l'api Ap2i
  *
  *
  * @see https://github.com/unjs/ohmyfetch/blob/main/README.md#%EF%B8%8F-create-fetch-with-default-options
  * @see https://github.com/unjs/ohmyfetch/blob/main/README.md#%EF%B8%8F-create-fetch-with-default-options
  */
  */
-let apiRequestServiceClass:null|ApiRequestService = null
+let apiRequestServiceClass: null | ApiRequestService = null
 export const useAp2iRequestService = () => {
 export const useAp2iRequestService = () => {
-    const runtimeConfig = useRuntimeConfig()
-
-    const baseURL = runtimeConfig.baseUrl ?? runtimeConfig.public.baseUrl
-
-    const pending: Ref<boolean> = ref(false)
-
-    /**
-     * Peuple les headers avant l'envoi de la requête
-     *
-     * @param request
-     * @param options
-     */
-    const onRequest = async function ({ request, options }: FetchContext) {
-        // @ts-ignore
-        if(options && options.noXaccessId) {
-            return
-        }
-
-        const accessProfileStore = useAccessProfileStore()
-
-        const headers: AssociativeArray = {
-            'x-accessid': String(accessProfileStore.id),
-            'Authorization': 'BEARER ' + accessProfileStore.bearer,
-        }
-
-        if (accessProfileStore.switchId) {
-            headers['x-switch-user'] = String(accessProfileStore.switchId)
-        }
+  const runtimeConfig = useRuntimeConfig()
+
+  const baseURL = runtimeConfig.baseUrl ?? runtimeConfig.public.baseUrl
+
+  const pending: Ref<boolean> = ref(false)
+
+  /**
+   * Peuple les headers avant l'envoi de la requête
+   *
+   * @param request
+   * @param options
+   */
+  const onRequest = function ({ request, options }: FetchContext) {
+    // @ts-expect-error options is not aware of noXaccessId
+    if (options && options.noXaccessId) {
+      return
+    }
 
 
-        options.headers = { ...options.headers, ...headers }
+    const accessProfileStore = useAccessProfileStore()
 
 
-        pending.value = true
-        console.log('Request : ' + request + ' (SSR: ' + process.server + ')')
+    const headers: AssociativeArray = {
+      'x-accessid': String(accessProfileStore.id),
+      Authorization: 'BEARER ' + accessProfileStore.bearer,
     }
     }
 
 
-    const onRequestError = async function({ request, options, response }: FetchContext) {
-        pending.value = false
+    if (accessProfileStore.switchId) {
+      headers['x-switch-user'] = String(accessProfileStore.switchId)
     }
     }
 
 
-    /**
-     * Server responded
-     *
-     * @param request
-     * @param options
-     * @param response
-     */
-    const onResponse = async function({ request, options, response }: FetchContext) {
-        pending.value = false
+    options.headers = { ...options.headers, ...headers }
+
+    pending.value = true
+    console.log('Request : ' + request + ' (SSR: ' + process.server + ')')
+  }
+
+  const onRequestError = function (_: FetchContext) {
+    pending.value = false
+  }
+
+  /**
+   * Server responded
+   */
+  const onResponse = function (_: FetchContext) {
+    pending.value = false
+  }
+
+  /**
+   * Gère les erreurs retournées par l'api
+   *
+   * @param request
+   * @param response
+   * @param error
+   */
+  const onResponseError = function ({ response, error }: FetchContext) {
+    pending.value = false
+
+    if (response && response.status === 401) {
+      throw new UnauthorizedError('Ap2i - Unauthorized')
+    } else if (response && response.status === 403) {
+      console.error('! Request error: Forbidden')
+      usePageStore().addAlert(TYPE_ALERT.ALERT, ['forbidden'])
+    } else if (
+      response &&
+      (response.status === 400 || response.status >= 404)
+    ) {
+      // @see https://developer.mozilla.org/fr/docs/Web/HTTP/Status
+      const errorMsg = error ? error.message : response.statusText
+      console.error('! Request error: ' + errorMsg)
+      usePageStore().addAlert(TYPE_ALERT.ALERT, [errorMsg])
     }
     }
+  }
 
 
-    /**
-     * Gère les erreurs retournées par l'api
-     *
-     * @param request
-     * @param response
-     * @param error
-     */
-    const onResponseError = async function ({ request, response, error }: FetchContext) {
-        pending.value = false
-
-        if (response && response.status === 401) {
-            throw new UnauthorizedError('Ap2i - Unauthorized')
-        }
-        else if (response && response.status === 403) {
-            console.error('! Request error: Forbidden')
-            usePageStore().addAlert(TYPE_ALERT.ALERT, ['forbidden'])
-        }
-        else if (response && (response.status === 400 || response.status >= 404)) {
-            // @see https://developer.mozilla.org/fr/docs/Web/HTTP/Status
-            const error_msg = error ? error.message : response.statusText
-            console.error('! Request error: ' + error_msg)
-            usePageStore().addAlert(TYPE_ALERT.ALERT, [error_msg])
-        }
-    }
+  const config: FetchOptions = {
+    baseURL,
+    onRequest,
+    onRequestError,
+    onResponse,
+    onResponseError,
+  }
 
 
-    const config : FetchOptions = {
-        baseURL,
-        onRequest,
-        onRequestError,
-        onResponse,
-        onResponseError
-    }
+  // Avoid memory leak
+  if (apiRequestServiceClass === null) {
+    // Utilise la fonction `create` d'ohmyfetch pour générer un fetcher dédié à l'interrogation de Ap2i
+    const fetcher = $fetch.create(config)
 
 
-    //Avoid memory leak
-    if (apiRequestServiceClass === null) {
-        // Utilise la fonction `create` d'ohmyfetch pour générer un fetcher dédié à l'interrogation de Ap2i
-        const fetcher = $fetch.create(config)
-        // @ts-ignore
-        apiRequestServiceClass = new ApiRequestService(fetcher)
-    }
+    apiRequestServiceClass = new ApiRequestService(fetcher)
+  }
 
 
-    return { apiRequestService: apiRequestServiceClass, pending: pending }
+  return { apiRequestService: apiRequestServiceClass, pending }
 }
 }

+ 46 - 30
composables/data/useEntityFetch.ts

@@ -1,42 +1,58 @@
-import {useEntityManager} from "~/composables/data/useEntityManager";
-import ApiResource from "~/models/ApiResource";
-import type {AssociativeArray, Collection} from "~/types/data";
-import type {AsyncData} from "#app";
-import type {ComputedRef, Ref} from "vue";
-import {v4 as uuid4} from "uuid";
+import type { AsyncData } from '#app'
+import type { ComputedRef, Ref } from 'vue'
+import { v4 as uuid4 } from 'uuid'
+import { useEntityManager } from '~/composables/data/useEntityManager'
+import ApiResource from '~/models/ApiResource'
+import type { AssociativeArray, Collection } from '~/types/data'
 
 
 interface useEntityFetchReturnType {
 interface useEntityFetchReturnType {
-    fetch: (model: typeof ApiResource, id: number) => AsyncData<ApiResource, ApiResource | true>,
-    fetchCollection: (model: typeof ApiResource, parent?: ApiResource | null, query?: Ref<AssociativeArray>) => AsyncData<Collection, any>
-    // @ts-ignore
-    getRef: <T extends ApiResource>(model: typeof T, id: Ref<number | null>) => ComputedRef<null | T>
+  fetch: (
+    model: typeof ApiResource,
+    id: number,
+  ) => AsyncData<ApiResource | null, Error | null>
+
+  fetchCollection: (
+    model: typeof ApiResource,
+    parent?: ApiResource | null,
+    query?: Ref<AssociativeArray>,
+  ) => AsyncData<Collection | null, Error | null>
+
+  getRef: <T extends ApiResource>(
+    model: new () => T,
+    id: Ref<number | null>,
+  ) => ComputedRef<null | T>
 }
 }
 
 
 // TODO: améliorer le typage des fonctions sur le modèle de getRef
 // TODO: améliorer le typage des fonctions sur le modèle de getRef
-export const useEntityFetch = (lazy: boolean = false): useEntityFetchReturnType => {
-    const { em } = useEntityManager()
+export const useEntityFetch = (
+  lazy: boolean = false,
+): useEntityFetchReturnType => {
+  const { em } = useEntityManager()
 
 
-    const fetch = (model: typeof ApiResource, id: number) => useAsyncData(
-        model.entity + '_' + id + '_' + uuid4(),
-        () => em.fetch(model, id, true),
-        { lazy }
+  const fetch = (model: typeof ApiResource, id: number) =>
+    useAsyncData(
+      model.entity + '_' + id + '_' + uuid4(),
+      () => em.fetch(model, id, true),
+      { lazy },
     )
     )
 
 
-    const fetchCollection = (
-        model: typeof ApiResource,
-        parent: ApiResource | null = null,
-        query: Ref<AssociativeArray | null> = ref(null)
-    ) => useAsyncData(
-        model.entity + '_many_' + uuid4(),
-        () => em.fetchCollection(model, parent, query.value ?? undefined),
-        { lazy }
+  const fetchCollection = (
+    model: typeof ApiResource,
+    parent: ApiResource | null = null,
+    query: Ref<AssociativeArray | null> = ref(null),
+  ) =>
+    useAsyncData(
+      model.entity + '_many_' + uuid4(),
+      () => em.fetchCollection(model, parent, query.value ?? undefined),
+      { lazy },
     )
     )
 
 
-    // @ts-ignore
-    const getRef = <T extends ApiResource>(model: typeof T, id: Ref<number | null>): ComputedRef<T | null> => {
-        return computed(() => (id.value ? em.find(model, id.value) as T : null))
-    }
+  const getRef = <T extends ApiResource>(
+    model: new () => T,
+    id: Ref<number | null>,
+  ): ComputedRef<T | null> => {
+    return computed(() => (id.value ? (em.find(model, id.value) as T) : null))
+  }
 
 
-    //@ts-ignore
-    return { fetch, fetchCollection, getRef }
+  return { fetch, fetchCollection, getRef }
 }
 }

+ 9 - 9
composables/data/useEntityManager.ts

@@ -1,15 +1,15 @@
-import EntityManager from "~/services/data/entityManager";
-import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
-import {useRepo} from "pinia-orm";
+import { useRepo } from 'pinia-orm'
+import EntityManager from '~/services/data/entityManager'
+import { useAp2iRequestService } from '~/composables/data/useAp2iRequestService'
 
 
 let entityManager: EntityManager | null = null
 let entityManager: EntityManager | null = null
 
 
 export const useEntityManager = () => {
 export const useEntityManager = () => {
-    if (entityManager === null) {
-        const { apiRequestService } = useAp2iRequestService()
-        const getRepo = useRepo
+  if (entityManager === null) {
+    const { apiRequestService } = useAp2iRequestService()
+    const getRepo = useRepo
 
 
-        entityManager = new EntityManager(apiRequestService, getRepo)
-    }
-    return { em: entityManager }
+    entityManager = new EntityManager(apiRequestService, getRepo)
+  }
+  return { em: entityManager }
 }
 }

+ 8 - 12
composables/data/useEnumFetch.ts

@@ -1,20 +1,16 @@
-import {useEnumManager} from "~/composables/data/useEnumManager";
-import type {Enum} from "~/types/data";
-import type {AsyncData} from "#app";
+import type { AsyncData } from '#app'
+import { useEnumManager } from '~/composables/data/useEnumManager'
+import type { Enum } from '~/types/data'
 
 
 interface useEnumFetchReturnType {
 interface useEnumFetchReturnType {
-    fetch: (enumName: string) => AsyncData<Enum, null | true | Error>,
+  fetch: (enumName: string) => AsyncData<Enum | null, Error | null>
 }
 }
 
 
 export const useEnumFetch = (lazy: boolean = false): useEnumFetchReturnType => {
 export const useEnumFetch = (lazy: boolean = false): useEnumFetchReturnType => {
-    const { enumManager } = useEnumManager()
+  const { enumManager } = useEnumManager()
 
 
-    const fetch = (enumName: string) => useAsyncData(
-        enumName,
-        () => enumManager.fetch(enumName),
-        { lazy }
-    )
+  const fetch = (enumName: string) =>
+    useAsyncData(enumName, () => enumManager.fetch(enumName), { lazy })
 
 
-    //@ts-ignore
-    return { fetch }
+  return { fetch }
 }
 }

+ 12 - 11
composables/data/useEnumManager.ts

@@ -1,15 +1,16 @@
-import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
-import EnumManager from "~/services/data/enumManager";
-import {useI18n} from "vue-i18n";
+import { useI18n } from 'vue-i18n'
+import { useAp2iRequestService } from '~/composables/data/useAp2iRequestService'
+import EnumManager from '~/services/data/enumManager'
 
 
-let enumManager:EnumManager | null = null
+let enumManager: EnumManager | null = null
 
 
 export const useEnumManager = () => {
 export const useEnumManager = () => {
-    //Avoid memory leak
-    if (enumManager === null) {
-        const { apiRequestService } = useAp2iRequestService()
-        const i18n = useI18n() as any
-        enumManager = new EnumManager(apiRequestService, i18n)
-    }
-    return { enumManager: enumManager }
+  // Avoid memory leak
+  if (enumManager === null) {
+    const { apiRequestService } = useAp2iRequestService()
+    const i18n = useI18n()
+    // @ts-expect-error TODO: explain the error of conversion from useI18n result to VueI18n
+    enumManager = new EnumManager(apiRequestService, i18n)
+  }
+  return { enumManager }
 }
 }

+ 22 - 17
composables/data/useImageFetch.ts

@@ -1,29 +1,34 @@
-import {useImageManager} from "~/composables/data/useImageManager";
-import type {AsyncData, FetchResult} from "#app";
-import {v4 as uuid4} from "uuid";
-import type {Ref} from "@vue/reactivity";
+import type { AsyncData } from '#app'
+import { v4 as uuid4 } from 'uuid'
+import type { Ref } from 'vue'
+import { useImageManager } from '~/composables/data/useImageManager'
 
 
 interface useImageFetchReturnType {
 interface useImageFetchReturnType {
-    fetch: (id: Ref<number | null>, defaultImage?: string | null, height?: number, width?: number) => AsyncData<string | ArrayBuffer | null, Error | null>
+  fetch: (
+    id: Ref<number | null>,
+    defaultImage?: string | null,
+    height?: number,
+    width?: number,
+  ) => AsyncData<string | ArrayBuffer | null, Error | null>
 }
 }
 
 
 /**
 /**
  * Sert d'intermédiaire entre les composants et l'ImageManager en fournissant une méthode useAsyncData toute prête.
  * Sert d'intermédiaire entre les composants et l'ImageManager en fournissant une méthode useAsyncData toute prête.
  */
  */
 export const useImageFetch = (): useImageFetchReturnType => {
 export const useImageFetch = (): useImageFetchReturnType => {
-    const { imageManager } = useImageManager()
-
-    const fetch = (
-        id: Ref<number | null>,  // If id is null, fetch shall return the default image url
-        defaultImage: string | null = null,
-        height: number = 0,
-        width: number = 0
-    ) => useAsyncData(
-        'img' + (id ?? defaultImage ?? 0) + '_' + uuid4(),
-        () => imageManager.get(id.value, defaultImage, height, width),
-        { lazy: true, server: false },  // Always fetch images client-side
+  const { imageManager } = useImageManager()
 
 
+  const fetch = (
+    id: Ref<number | null>, // If id is null, fetch shall return the default image url
+    defaultImage: string | null = null,
+    height: number = 0,
+    width: number = 0,
+  ) =>
+    useAsyncData(
+      'img' + (id ?? defaultImage ?? 0) + '_' + uuid4(),
+      () => imageManager.get(id.value, defaultImage, height, width),
+      { lazy: true, server: false }, // Always fetch images client-side
     )
     )
 
 
-    return { fetch }
+  return { fetch }
 }
 }

+ 9 - 9
composables/data/useImageManager.ts

@@ -1,14 +1,14 @@
-import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
-import ImageManager from "~/services/data/imageManager";
+import { useAp2iRequestService } from '~/composables/data/useAp2iRequestService'
+import ImageManager from '~/services/data/imageManager'
 
 
-let imageManager:ImageManager | null = null
+let imageManager: ImageManager | null = null
 
 
 export const useImageManager = () => {
 export const useImageManager = () => {
-    //Avoid memory leak
-    if (imageManager === null) {
-        const { apiRequestService } = useAp2iRequestService()
-        imageManager = new ImageManager(apiRequestService)
-    }
+  // Avoid memory leak
+  if (imageManager === null) {
+    const { apiRequestService } = useAp2iRequestService()
+    imageManager = new ImageManager(apiRequestService)
+  }
 
 
-    return { imageManager: imageManager }
+  return { imageManager }
 }
 }

+ 55 - 50
composables/data/useRefreshProfile.ts

@@ -1,61 +1,66 @@
-import {useEntityManager} from "~/composables/data/useEntityManager";
-import MyProfile from "~/models/Access/MyProfile";
-import {useAccessProfileStore} from "~/stores/accessProfile";
-import {useOrganizationProfileStore} from "~/stores/organizationProfile";
+import { useEntityManager } from '~/composables/data/useEntityManager'
+import MyProfile from '~/models/Access/MyProfile'
+import { useAccessProfileStore } from '~/stores/accessProfile'
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 
 
 export const useRefreshProfile = () => {
 export const useRefreshProfile = () => {
+  const accessProfileStore = useAccessProfileStore()
+  const organizationProfileStore = useOrganizationProfileStore()
+  const { em } = useEntityManager()
 
 
-    const accessProfileStore = useAccessProfileStore()
-    const organizationProfileStore = useOrganizationProfileStore()
-    const { em } = useEntityManager()
+  const fetchProfile = async (
+    accessId: number | null = null,
+  ): Promise<MyProfile> => {
+    if (accessId === null) {
+      accessId = accessProfileStore.currentAccessId
+    }
 
 
-    const fetchProfile = async (accessId: number | null = null): Promise<MyProfile> => {
-        if (accessId === null) {
-            accessId = accessProfileStore.currentAccessId
-        }
+    return (await em.fetch(MyProfile, accessId, true)) as MyProfile
+  }
 
 
-        return await em.fetch(MyProfile, accessId, true) as MyProfile
-    }
+  /**
+   * Fetch the access profile and initiate the user profile and organization profile stores
+   *
+   * /!\ Server side only!
+   *
+   * @param accessId
+   * @param bearer
+   * @param switchId
+   */
+  const initiateProfile = async (
+    accessId: number,
+    bearer: string,
+    switchId: number | null,
+  ): Promise<void> => {
+    accessProfileStore.$patch({
+      bearer,
+      id: accessId,
+      switchId,
+    })
 
 
-    /**
-     * Fetch the access profile and initiate the user profile and organization profile stores
-     *
-     * /!\ Server side only!
-     *
-     * @param accessId
-     * @param bearer
-     * @param switchId
-     */
-    const initiateProfile = async (accessId: number, bearer: string, switchId: number | null): Promise<void> => {
-        accessProfileStore.$patch({
-            bearer: bearer,
-            id: accessId,
-            switchId: switchId
-        })
-
-        const profile = await fetchProfile(accessId)
-
-        // Sans le flush, on observe un bug non-expliqué au rechargement de la page en mode dev : la fonction save
-        //  du repo de MyProfile ne fonctionne pas quand le plugin init.server.ts re-fetch le profil
-        em.flush(MyProfile)
-
-        accessProfileStore.initiateProfile(profile)
-        organizationProfileStore.initiateProfile(profile.organization)
-    }
+    const profile = await fetchProfile(accessId)
 
 
-    /**
-     * Re-fetch the user profile and update the store
-     */
-    const refreshProfile = async (accessId: number | null = null) => {
-        const profile = await fetchProfile(accessId)
+    // Sans le flush, on observe un bug non-expliqué au rechargement de la page en mode dev : la fonction save
+    //  du repo de MyProfile ne fonctionne pas quand le plugin init.server.ts re-fetch le profil
+    em.flush(MyProfile)
 
 
-        // Sans le flush, on observe un bug non-expliqué au rechargement de la page en mode dev : la fonction save
-        //  du repo de MyProfile ne fonctionne pas quand le plugin init.server.ts re-fetch le profil
-        em.flush(MyProfile)
+    accessProfileStore.initiateProfile(profile)
+    organizationProfileStore.initiateProfile(profile.organization)
+  }
 
 
-        accessProfileStore.setProfile(profile)
-        organizationProfileStore.setProfile(profile.organization)
-    }
+  /**
+   * Re-fetch the user profile and update the store
+   */
+  const refreshProfile = async (accessId: number | null = null) => {
+    const profile = await fetchProfile(accessId)
+
+    // Sans le flush, on observe un bug non-expliqué au rechargement de la page en mode dev : la fonction save
+    //  du repo de MyProfile ne fonctionne pas quand le plugin init.server.ts re-fetch le profil
+    em.flush(MyProfile)
+
+    accessProfileStore.setProfile(profile)
+    organizationProfileStore.setProfile(profile.organization)
+  }
 
 
-    return { initiateProfile, refreshProfile }
+  return { initiateProfile, refreshProfile }
 }
 }

+ 9 - 9
composables/form/useFieldViolation.ts

@@ -1,7 +1,7 @@
-import {computed} from "@vue/reactivity";
-import type {ComputedRef} from "@vue/reactivity";
-import {useFormStore} from "~/stores/form";
+import { computed } from 'vue'
+import type { ComputedRef } from 'vue'
 import * as _ from 'lodash-es'
 import * as _ from 'lodash-es'
+import { useFormStore } from '~/stores/form'
 
 
 /**
 /**
  * Composable pour gérer l'apparition de message d'erreurs de validation d'un champ de formulaire
  * Composable pour gérer l'apparition de message d'erreurs de validation d'un champ de formulaire
@@ -9,22 +9,22 @@ import * as _ from 'lodash-es'
  * @param field
  * @param field
  */
  */
 export function useFieldViolation(field: string) {
 export function useFieldViolation(field: string) {
-  const fieldViolations: ComputedRef<string> = computed(()=> {
+  const fieldViolations: ComputedRef<string> = computed(() => {
     return _.get(useFormStore().violations, field, '')
     return _.get(useFormStore().violations, field, '')
   })
   })
 
 
   /**
   /**
    * Lorsque la valeur d'un champ change, on supprime le fait qu'il puisse être "faux" dans le store
    * Lorsque la valeur d'un champ change, on supprime le fait qu'il puisse être "faux" dans le store
    * @param field
    * @param field
-   * @param value
    */
    */
-  function updateViolationState(field: string, value: any) {
-    //@ts-ignore
-    useFormStore().setViolations(_.omit(useFormStore().violations, field))
+  function updateViolationState(field: string) {
+    useFormStore().setViolations(
+      _.omit(useFormStore().violations, field) as string[],
+    )
   }
   }
 
 
   return {
   return {
     fieldViolations,
     fieldViolations,
-    updateViolationState: (fieldValue: any) => updateViolationState(fieldValue, field)
+    updateViolationState,
   }
   }
 }
 }

+ 20 - 11
composables/form/useValidation.ts

@@ -1,14 +1,13 @@
-import  {useI18n} from 'vue-i18n'
-import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
-import UrlUtils from "~/services/utils/urlUtils";
-import type {Ref} from "@vue/reactivity";
+import { useI18n } from 'vue-i18n'
+import type { Ref } from 'vue'
+import { useAp2iRequestService } from '~/composables/data/useAp2iRequestService'
+import UrlUtils from '~/services/utils/urlUtils'
 
 
 /**
 /**
  * @category composables/form
  * @category composables/form
  * Composable pour des utils de verifications
  * Composable pour des utils de verifications
  */
  */
 export function useValidation() {
 export function useValidation() {
-
   /**
   /**
    * Use méthode fournissant une fonction pour tester la validité d'un Siret ainsi que la gestion du message d'erreur
    * Use méthode fournissant une fonction pour tester la validité d'un Siret ainsi que la gestion du message d'erreur
    */
    */
@@ -17,28 +16,38 @@ export function useValidation() {
     const siretErrorMessage: Ref<string> = ref('')
     const siretErrorMessage: Ref<string> = ref('')
 
 
     const validateSiret = async (siret: string) => {
     const validateSiret = async (siret: string) => {
-
       const { apiRequestService } = useAp2iRequestService()
       const { apiRequestService } = useAp2iRequestService()
-      const response: any = await apiRequestService.get(UrlUtils.join('/api/siret-checking', siret))
+      const response: Response = await apiRequestService.get(
+        UrlUtils.join('/api/siret-checking', siret),
+      )
 
 
       if (typeof response === 'undefined') {
       if (typeof response === 'undefined') {
         siretError.value = false
         siretError.value = false
         siretErrorMessage.value = ''
         siretErrorMessage.value = ''
       }
       }
 
 
+      if (!Object.prototype.hasOwnProperty.call(response, 'isCorrect')) {
+        throw new Error('Invalid response format')
+      }
+
+      // @ts-expect-error At this point, response has an 'isCorrect' property
+      const isCorrect = response.isCorrect
+
       const i18n = useI18n()
       const i18n = useI18n()
-      siretError.value = !response.isCorrect
-      siretErrorMessage.value = response.isCorrect ? '' : i18n.t('siret_error') as string
+      siretError.value = !isCorrect
+      siretErrorMessage.value = isCorrect
+        ? ''
+        : (i18n.t('siret_error') as string)
     }
     }
 
 
     return {
     return {
       siretError,
       siretError,
       siretErrorMessage,
       siretErrorMessage,
-      validateSiret
+      validateSiret,
     }
     }
   }
   }
 
 
   return {
   return {
-    useValidateSiret
+    useValidateSiret,
   }
   }
 }
 }

+ 2 - 3
composables/form/validation/useSubdomainValidation.ts

@@ -1,9 +1,8 @@
-import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
-import SubdomainValidation from "~/services/validation/subdomainValidation";
+import { useAp2iRequestService } from '~/composables/data/useAp2iRequestService'
+import SubdomainValidation from '~/services/validation/subdomainValidation'
 
 
 let subdomainValidation: SubdomainValidation | null = null
 let subdomainValidation: SubdomainValidation | null = null
 
 
-
 export function useSubdomainValidation() {
 export function useSubdomainValidation() {
   if (subdomainValidation === null) {
   if (subdomainValidation === null) {
     const { apiRequestService } = useAp2iRequestService()
     const { apiRequestService } = useAp2iRequestService()

+ 13 - 8
composables/layout/useExtensionPanel.ts

@@ -1,4 +1,4 @@
-import type {Ref} from "@vue/reactivity";
+import type { Ref } from 'vue'
 import * as _ from 'lodash-es'
 import * as _ from 'lodash-es'
 
 
 /**
 /**
@@ -11,16 +11,21 @@ export function useExtensionPanel(route: Ref) {
 
 
   onMounted(() => {
   onMounted(() => {
     setTimeout(function () {
     setTimeout(function () {
-      _.each(document.getElementsByClassName('v-expansion-panel'), (element, index) => {
-        if (element.id == activeAccordionId) {
-          panel.value = index
-        }
-      })
-      if (!panel.value) { panel.value = 0 }
+      _.each(
+        document.getElementsByClassName('v-expansion-panel'),
+        (element, index) => {
+          if (element.id === activeAccordionId) {
+            panel.value = index
+          }
+        },
+      )
+      if (!panel.value) {
+        panel.value = 0
+      }
     }, 0)
     }, 0)
   })
   })
 
 
   return {
   return {
-    panel
+    panel,
   }
   }
 }
 }

+ 15 - 9
composables/layout/useMenu.ts

@@ -1,11 +1,11 @@
-import {useAccessProfileStore} from "~/stores/accessProfile";
-import {useAbility} from "@casl/vue";
-import {useOrganizationProfileStore} from "~/stores/organizationProfile";
-import type {MenuGroup, MenuItem} from "~/types/layout";
-import {MENU_LINK_TYPE} from "~/types/enum/layout";
-import type {AccessProfile} from "~/types/interfaces";
-import {useLayoutStore} from "~/stores/layout";
-import MenuComposer from "~/services/layout/menuComposer";
+import { useAbility } from '@casl/vue'
+import { useAccessProfileStore } from '~/stores/accessProfile'
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
+import type { MenuGroup, MenuItem } from '~/types/layout'
+import { MENU_LINK_TYPE } from '~/types/enum/layout'
+import type { AccessProfile } from '~/types/interfaces'
+import { useLayoutStore } from '~/stores/layout'
+import MenuComposer from '~/services/layout/menuComposer'
 
 
 /**
 /**
  * Renvoie des méthodes pour interagir avec les menus
  * Renvoie des méthodes pour interagir avec les menus
@@ -31,7 +31,13 @@ export const useMenu = () => {
    * false, jusqu'à ce que je tilte que le menu s'appelait MyFamily, et pas Family
    * false, jusqu'à ce que je tilte que le menu s'appelait MyFamily, et pas Family
    */
    */
   const buildAllMenu = () => {
   const buildAllMenu = () => {
-    MenuComposer.build(runtimeConfig, ability, organizationProfile, accessProfile as AccessProfile, layoutState)
+    MenuComposer.build(
+      runtimeConfig,
+      ability,
+      organizationProfile,
+      accessProfile as AccessProfile,
+      layoutState,
+    )
   }
   }
 
 
   /**
   /**

+ 14 - 9
composables/utils/useAdminUrl.ts

@@ -1,14 +1,19 @@
-import UrlUtils from "~/services/utils/urlUtils";
+import UrlUtils from '~/services/utils/urlUtils'
 
 
 export const useAdminUrl = () => {
 export const useAdminUrl = () => {
-    const runtimeConfig = useRuntimeConfig()
+  const runtimeConfig = useRuntimeConfig()
 
 
-    const makeAdminUrl = (tail: string, query: Record<string, string> = {}): string => {
-        const baseUrl = runtimeConfig.baseUrlAdminLegacy ?? runtimeConfig.public.baseUrlAdminLegacy
-        let url = UrlUtils.join(baseUrl, '#', tail)
-        url = UrlUtils.addQuery(url, query)
-        return url
-    }
+  const makeAdminUrl = (
+    tail: string,
+    query: Record<string, string> = {},
+  ): string => {
+    const baseUrl =
+      runtimeConfig.baseUrlAdminLegacy ??
+      runtimeConfig.public.baseUrlAdminLegacy
+    let url = UrlUtils.join(baseUrl, '#', tail)
+    url = UrlUtils.addQuery(url, query)
+    return url
+  }
 
 
-    return { makeAdminUrl }
+  return { makeAdminUrl }
 }
 }

+ 14 - 11
composables/utils/useDownloadFile.ts

@@ -1,19 +1,22 @@
-import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
-import File from "~/models/Core/File"
-import FileSaver from "file-saver";
+import FileSaver from 'file-saver'
+import { useAp2iRequestService } from '~/composables/data/useAp2iRequestService'
+import File from '~/models/Core/File'
 
 
 export const useDownloadFile = async (file: File) => {
 export const useDownloadFile = async (file: File) => {
-    const { apiRequestService } = useAp2iRequestService()
+  const { apiRequestService } = useAp2iRequestService()
 
 
-    const downloadUrl = `api/download/${file.id}`
+  const downloadUrl = `api/download/${file.id}`
 
 
-    const response: any = await apiRequestService.get(downloadUrl)
+  const response = await apiRequestService.get(downloadUrl)
 
 
-    if (!response || response.size === 0) {
-        console.error('Error: file ' + file.id + ' not found')
-    }
+  const blobPart = await response.blob()
 
 
-    const blob = new Blob([response], { type: response.type })
+  if (!response || blobPart.size === 0) {
+    console.error('Error: file ' + file.id + ' not found')
+  }
 
 
-    FileSaver.saveAs(blob, file.name ?? 'unknown');
+  const blob = new Blob([blobPart], { type: response.type })
+
+  // eslint-disable-next-line import/no-named-as-default-member
+  FileSaver.saveAs(blob, file.name ?? 'unknown')
 }
 }

+ 4 - 5
composables/utils/useHomeUrl.ts

@@ -1,10 +1,9 @@
-import {useAdminUrl} from "~/composables/utils/useAdminUrl";
+import { useAdminUrl } from '~/composables/utils/useAdminUrl'
 
 
 export const useHomeUrl = () => {
 export const useHomeUrl = () => {
+  const { makeAdminUrl } = useAdminUrl()
 
 
-    const { makeAdminUrl } = useAdminUrl()
+  const homeUrl = makeAdminUrl('dashboard')
 
 
-    const homeUrl = makeAdminUrl('dashboard')
-
-    return { homeUrl }
+  return { homeUrl }
 }
 }

+ 10 - 10
composables/utils/useI18nUtils.ts

@@ -1,13 +1,13 @@
-import {useI18n} from "vue-i18n";
-import I18nUtils from "~/services/utils/i18nUtils";
+import { useI18n } from 'vue-i18n'
+import I18nUtils from '~/services/utils/i18nUtils'
 
 
-let i18nUtilsClass:null|I18nUtils = null
+let i18nUtilsClass: null | I18nUtils = null
 export const useI18nUtils = () => {
 export const useI18nUtils = () => {
-    //Avoid memory leak
-    if(i18nUtilsClass === null){
-        const i18n = useI18n()
-        //@ts-ignore
-        i18nUtilsClass = new I18nUtils(i18n)
-    }
-    return i18nUtilsClass
+  // Avoid memory leak
+  if (i18nUtilsClass === null) {
+    const i18n = useI18n()
+    // @ts-expect-error TODO: explain the error of conversion from useI18n result to VueI18n
+    i18nUtilsClass = new I18nUtils(i18n)
+  }
+  return i18nUtilsClass
 }
 }

+ 17 - 13
composables/utils/useRedirect.ts

@@ -1,21 +1,25 @@
-import UrlUtils from "~/services/utils/urlUtils";
+import UrlUtils from '~/services/utils/urlUtils'
 
 
 export const useRedirect = () => {
 export const useRedirect = () => {
-    const runtimeConfig = useRuntimeConfig()
+  const runtimeConfig = useRuntimeConfig()
 
 
-    const redirectToLogout = () => {
-        if (!runtimeConfig.baseUrlAdminLegacy) {
-            throw new Error('Configuration error : no redirection target')
-        }
-        navigateTo(UrlUtils.join(runtimeConfig.baseUrlAdminLegacy, '#/logout'), {external: true})
+  const redirectToLogout = () => {
+    if (!runtimeConfig.baseUrlAdminLegacy) {
+      throw new Error('Configuration error : no redirection target')
     }
     }
+    navigateTo(UrlUtils.join(runtimeConfig.baseUrlAdminLegacy, '#/logout'), {
+      external: true,
+    })
+  }
 
 
-    const redirectToHome = () => {
-        if (!runtimeConfig.baseUrlAdminLegacy) {
-            throw new Error('Configuration error : no redirection target')
-        }
-        navigateTo(UrlUtils.join(runtimeConfig.baseUrlAdminLegacy, '#/dashboard'), {external: true})
+  const redirectToHome = () => {
+    if (!runtimeConfig.baseUrlAdminLegacy) {
+      throw new Error('Configuration error : no redirection target')
     }
     }
+    navigateTo(UrlUtils.join(runtimeConfig.baseUrlAdminLegacy, '#/dashboard'), {
+      external: true,
+    })
+  }
 
 
-    return { redirectToLogout, redirectToHome }
+  return { redirectToLogout, redirectToHome }
 }
 }

+ 8 - 8
composables/utils/useValidationUtils.ts

@@ -1,10 +1,10 @@
-import ValidationUtils from "~/services/utils/validationUtils";
+import ValidationUtils from '~/services/utils/validationUtils'
 
 
-let validationUtilsClass:null|ValidationUtils = null
+let validationUtilsClass: null | ValidationUtils = null
 export const useValidationUtils = () => {
 export const useValidationUtils = () => {
-    //Avoid memory leak
-    if(validationUtilsClass === null){
-        validationUtilsClass = new ValidationUtils()
-    }
-    return validationUtilsClass
-}
+  // Avoid memory leak
+  if (validationUtilsClass === null) {
+    validationUtilsClass = new ValidationUtils()
+  }
+  return validationUtilsClass
+}

+ 1 - 1
config/abilities/pages/myAccount.yaml

@@ -6,7 +6,7 @@
   attendance_bookings_page:
   attendance_bookings_page:
     action: 'display'
     action: 'display'
     conditions:
     conditions:
-      - {function: organizationHasAnyModule, parameters: ['Attendances']}
+      - { function: organizationHasAnyModule, parameters: ['Attendances'] }
       # TODO: l'action write existe-t-elle?
       # TODO: l'action write existe-t-elle?
       - { function: accessHasAnyRoleAbility, parameters: [{action: 'write', subject: 'attendances'}] }
       - { function: accessHasAnyRoleAbility, parameters: [{action: 'write', subject: 'attendances'}] }
       - { function: accessIsAdminAccount, expectedResult: false }
       - { function: accessIsAdminAccount, expectedResult: false }

+ 111 - 115
config/theme.ts

@@ -1,151 +1,147 @@
-
 interface Theme {
 interface Theme {
-    dark: boolean,
-    colors: {
-        /**
-         * @see Cf. doc/colors.md pour le rôle de chaque couleur
-         */
-        // Global
-        'background': string,
-        'on-background': string,
-        'surface': string,
-        'on-surface': string,
-        'primary': string,
-        'on-primary': string,
-        'primary-alt': string,
-        'on-primary-alt': string,
-        'secondary': string,
-        'on-secondary': string,
-        'secondary-alt': string,
-        'on-secondary-alt': string,
-        'neutral-strong': string,
-        'on-neutral-strong': string,
-        'neutral': string,
-        'on-neutral': string,
-        'on-neutral--clickable': string,
-        'neutral-soft': string,
-        'on-neutral-soft': string,
-        'neutral-very-soft': string,
-        'on-neutral-very-soft': string,
-        'danger': string,
-        'on-danger': string,
-        'success': string,
-        'on-success': string,
-        'warning': string,
-        'on-warning': string,
-        'info': string,
-        'on-info': string,
-
-        // Special cases
-        // TODO: voir ceux dont on peut se passer
-        'x-create-btn': string,
-        'on-x-create-btn': string
-    }
+  dark: boolean
+  colors: {
+    /**
+     * @see Cf. doc/colors.md pour le rôle de chaque couleur
+     */
+    // Global
+    background: string
+    'on-background': string
+    surface: string
+    'on-surface': string
+    primary: string
+    'on-primary': string
+    'primary-alt': string
+    'on-primary-alt': string
+    secondary: string
+    'on-secondary': string
+    'secondary-alt': string
+    'on-secondary-alt': string
+    'neutral-strong': string
+    'on-neutral-strong': string
+    neutral: string
+    'on-neutral': string
+    'on-neutral--clickable': string
+    'neutral-soft': string
+    'on-neutral-soft': string
+    'neutral-very-soft': string
+    'on-neutral-very-soft': string
+    danger: string
+    'on-danger': string
+    success: string
+    'on-success': string
+    warning: string
+    'on-warning': string
+    info: string
+    'on-info': string
+
+    // Special cases
+    // TODO: voir ceux dont on peut se passer
+    'x-create-btn': string
+    'on-x-create-btn': string
+  }
 }
 }
 
 
-
 export const lightTheme: Theme = {
 export const lightTheme: Theme = {
-    dark: false,
-    colors: {
-        'background': '#ecf0f5',
-        'on-background': '#000000',
+  dark: false,
+  colors: {
+    background: '#ecf0f5',
+    'on-background': '#000000',
 
 
-        'surface': '#ffffff',
-        'on-surface': '#000000',
+    surface: '#ffffff',
+    'on-surface': '#000000',
 
 
-        'primary': '#00ad8e',
-        'on-primary': '#ffffff',
+    primary: '#00ad8e',
+    'on-primary': '#ffffff',
 
 
-        'primary-alt': '#a9e0d6',
-        'on-primary-alt': '#777777',
+    'primary-alt': '#a9e0d6',
+    'on-primary-alt': '#777777',
 
 
-        'secondary': '#324150',
-        'on-secondary': '#f5f5f5',
+    secondary: '#324150',
+    'on-secondary': '#f5f5f5',
 
 
-        'secondary-alt': '#2a3745',
-        'on-secondary-alt': '#ffffff',
+    'secondary-alt': '#2a3745',
+    'on-secondary-alt': '#ffffff',
 
 
-        'neutral-strong': '#777777',
-        'on-neutral-strong': '#ecf0f5',
+    'neutral-strong': '#777777',
+    'on-neutral-strong': '#ecf0f5',
 
 
-        'neutral': '#e6e6e6',
-        'on-neutral': '#666666',
-        'on-neutral--clickable': '#00997d',
+    neutral: '#e6e6e6',
+    'on-neutral': '#666666',
+    'on-neutral--clickable': '#00997d',
 
 
-        'neutral-soft': '#f2f2f2',
-        'on-neutral-soft': '#333333',
+    'neutral-soft': '#f2f2f2',
+    'on-neutral-soft': '#333333',
 
 
-        'neutral-very-soft': '#ffffff',
-        'on-neutral-very-soft': '#333333',
+    'neutral-very-soft': '#ffffff',
+    'on-neutral-very-soft': '#333333',
 
 
-        // Content
-        'danger': '#f56954',
-        'on-danger': '#ffffff',
+    // Content
+    danger: '#f56954',
+    'on-danger': '#ffffff',
 
 
-        'success': '#00a65a',
-        'on-success': '#ffffff',
+    success: '#00a65a',
+    'on-success': '#ffffff',
 
 
-        'warning': '#f39c12',
-        'on-warning': '#ffffff',
+    warning: '#f39c12',
+    'on-warning': '#ffffff',
 
 
-        'info': '#3c8dbc',
-        'on-info': '#ffffff',
+    info: '#3c8dbc',
+    'on-info': '#ffffff',
 
 
-        'x-create-btn': '#f39c12',
-        'on-x-create-btn': '#ffffff',
-    }
+    'x-create-btn': '#f39c12',
+    'on-x-create-btn': '#ffffff',
+  },
 }
 }
 
 
 export const darkTheme: Theme = {
 export const darkTheme: Theme = {
-    dark: true,
-    colors: {
-        'background': '#1a1a1a',
-        'on-background': '#ffffff',
+  dark: true,
+  colors: {
+    background: '#1a1a1a',
+    'on-background': '#ffffff',
 
 
-        'surface': '#262626',
-        'on-surface': '#ffffff',
+    surface: '#262626',
+    'on-surface': '#ffffff',
 
 
-        'primary': '#00ad8e',
-        'on-primary': '#ffffff',
+    primary: '#00ad8e',
+    'on-primary': '#ffffff',
 
 
-        'primary-alt': '#a9e0d6',
-        'on-primary-alt': '#777777',
+    'primary-alt': '#a9e0d6',
+    'on-primary-alt': '#777777',
 
 
-        'secondary': '#324150',
-        'on-secondary': '#f5f5f5',
+    secondary: '#324150',
+    'on-secondary': '#f5f5f5',
 
 
-        'secondary-alt': '#2c3a48',
-        'on-secondary-alt': '#ffffff',
+    'secondary-alt': '#2c3a48',
+    'on-secondary-alt': '#ffffff',
 
 
-        'neutral-strong': '#595959',
-        'on-neutral-strong': '#ecf0f5',
+    'neutral-strong': '#595959',
+    'on-neutral-strong': '#ecf0f5',
 
 
-        'neutral': '#324150',
-        'on-neutral': '#cccccc',
-        'on-neutral--clickable': '#a9e0d6',
+    neutral: '#324150',
+    'on-neutral': '#cccccc',
+    'on-neutral--clickable': '#a9e0d6',
 
 
-        'neutral-soft': '#090c11',
-        'on-neutral-soft': '#cccccc',
+    'neutral-soft': '#090c11',
+    'on-neutral-soft': '#cccccc',
 
 
-        'neutral-very-soft': '#333333',
-        'on-neutral-very-soft': '#ecf0f5',
+    'neutral-very-soft': '#333333',
+    'on-neutral-very-soft': '#ecf0f5',
 
 
-        // Content
-        'danger': '#f56954',
-        'on-danger': '#ffffff',
+    // Content
+    danger: '#f56954',
+    'on-danger': '#ffffff',
 
 
-        'success': '#00a65a',
-        'on-success': '#ffffff',
+    success: '#00a65a',
+    'on-success': '#ffffff',
 
 
-        'warning': '#f39c12',
-        'on-warning': '#ffffff',
+    warning: '#f39c12',
+    'on-warning': '#ffffff',
 
 
-        'info': '#3c8dbc',
-        'on-info': '#ffffff',
+    info: '#3c8dbc',
+    'on-info': '#ffffff',
 
 
-        'x-create-btn': '#f39c12',
-        'on-x-create-btn': '#ffffff',
-    }
+    'x-create-btn': '#f39c12',
+    'on-x-create-btn': '#ffffff',
+  },
 }
 }
-
-

+ 33 - 24
i18n.config.ts

@@ -1,26 +1,35 @@
-import {defineI18nConfig} from "#i18n";
+import { defineI18nConfig } from '#i18n'
 
 
 export default defineI18nConfig(() => ({
 export default defineI18nConfig(() => ({
-        legacy: false,
-        datetimeFormats: {
-            'fr': {
-                short: {
-                    year: 'numeric', month: 'numeric', day: 'numeric'
-                },
-                long: {
-                    year: 'numeric', month: 'numeric', day: 'numeric',
-                    hour: 'numeric', minute: 'numeric'
-                }
-            },
-            'en': {
-                short: {
-                    year: 'numeric', month: 'numeric', day: 'numeric'
-                },
-                long: {
-                    year: 'numeric', month: 'numeric', day: 'numeric',
-                    hour: 'numeric', minute: 'numeric'
-                }
-            }
-        }
-    })
-)
+  legacy: false,
+  datetimeFormats: {
+    fr: {
+      short: {
+        year: 'numeric',
+        month: 'numeric',
+        day: 'numeric',
+      },
+      long: {
+        year: 'numeric',
+        month: 'numeric',
+        day: 'numeric',
+        hour: 'numeric',
+        minute: 'numeric',
+      },
+    },
+    en: {
+      short: {
+        year: 'numeric',
+        month: 'numeric',
+        day: 'numeric',
+      },
+      long: {
+        year: 'numeric',
+        month: 'numeric',
+        day: 'numeric',
+        hour: 'numeric',
+        minute: 'numeric',
+      },
+    },
+  },
+}))

+ 2 - 1
lang/fr.json

@@ -680,5 +680,6 @@
   "cycles_breadcrumbs": "Enseignements",
   "cycles_breadcrumbs": "Enseignements",
   "cmf_licence_structure_breadcrumbs": "Licence CMF - Structure",
   "cmf_licence_structure_breadcrumbs": "Licence CMF - Structure",
   "no_recorded_subdomain": "Aucun sous-domaine enregistré",
   "no_recorded_subdomain": "Aucun sous-domaine enregistré",
-  "no_admin_access_recorded": "Aucun compte super-admin enregistré"
+  "no_admin_access_recorded": "Aucun compte super-admin enregistré",
+  "redirecting": "Redirection en cours"
 }
 }

+ 6 - 0
layouts/.eslintrc.cjs

@@ -0,0 +1,6 @@
+/** On désactive cette règle pour les pages et les layouts seulement : https://eslint.vuejs.org/rules/multi-word-component-names.html */
+module.exports = {
+  rules: {
+    'vue/multi-word-component-names': 0,
+  }
+}

+ 1 - 3
layouts/default.vue

@@ -11,7 +11,6 @@
       <LayoutMainMenu />
       <LayoutMainMenu />
 
 
       <v-main class="main">
       <v-main class="main">
-
         <LayoutSubheader />
         <LayoutSubheader />
 
 
         <LayoutAlertBar class="mt-1" />
         <LayoutAlertBar class="mt-1" />
@@ -21,13 +20,12 @@
       </v-main>
       </v-main>
 
 
       <LazyLayoutAlertContainer />
       <LazyLayoutAlertContainer />
-
     </v-app>
     </v-app>
   </div>
   </div>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import {useLayoutStore} from "~/stores/layout";
+import { useLayoutStore } from '~/stores/layout'
 
 
 const layoutStore = useLayoutStore()
 const layoutStore = useLayoutStore()
 layoutStore.name = 'default'
 layoutStore.name = 'default'

+ 21 - 15
layouts/error.vue

@@ -7,25 +7,31 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-  import UrlUtils from "~/services/utils/urlUtils";
-  import {useLayoutStore} from "~/stores/layout";
+import UrlUtils from '~/services/utils/urlUtils'
+import { useLayoutStore } from '~/stores/layout'
 
 
-  const layoutStore = useLayoutStore()
-  layoutStore.name = 'error'
+const layoutStore = useLayoutStore()
+layoutStore.name = 'error'
 
 
-  const props = defineProps({
-    error: {
-      type: Object,
-      default: null
-    }
-  })
+const props = defineProps({
+  error: {
+    type: Object,
+    default: null,
+  },
+})
 
 
-  if(process.client && props.error.statusCode === 404 && process.env.NODE_ENV === 'production') {
-    const runtimeConfig = useRuntimeConfig()
-    navigateTo(UrlUtils.join(runtimeConfig.baseUrlAdminLegacy, 'dashboard'), {external: true})
-  }
+if (
+  process.client &&
+  props.error.statusCode === 404 &&
+  process.env.NODE_ENV === 'production'
+) {
+  const runtimeConfig = useRuntimeConfig()
+  navigateTo(UrlUtils.join(runtimeConfig.baseUrlAdminLegacy, 'dashboard'), {
+    external: true,
+  })
+}
 
 
-  const otherError = ref('Une erreur est parvenue')
+const otherError = ref('Une erreur est parvenue')
 </script>
 </script>
 
 
 <style scoped>
 <style scoped>

+ 7 - 10
layouts/parameters.vue

@@ -11,7 +11,6 @@
       <LayoutParametersMenu />
       <LayoutParametersMenu />
 
 
       <v-main class="main">
       <v-main class="main">
-
         <LayoutSubheader />
         <LayoutSubheader />
 
 
         <LayoutAlertBar class="mt-1" />
         <LayoutAlertBar class="mt-1" />
@@ -23,24 +22,22 @@
       </v-main>
       </v-main>
 
 
       <LazyLayoutAlertContainer />
       <LazyLayoutAlertContainer />
-
     </v-app>
     </v-app>
   </div>
   </div>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-
-import {useLayoutStore} from "~/stores/layout";
+import { useLayoutStore } from '~/stores/layout'
 
 
 const layoutStore = useLayoutStore()
 const layoutStore = useLayoutStore()
 layoutStore.name = 'parameters'
 layoutStore.name = 'parameters'
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
-  .parameters-page-card {
-    background-color: rgb(var(--v-theme-neutral-very-soft));
-    color: rgb(var(--v-theme-on-neutral-very-soft));
-    margin: 3%;
-    padding: 24px;
-  }
+.parameters-page-card {
+  background-color: rgb(var(--v-theme-neutral-very-soft));
+  color: rgb(var(--v-theme-on-neutral-very-soft));
+  margin: 3%;
+  padding: 24px;
+}
 </style>
 </style>

+ 5 - 5
models/Access/Access.ts

@@ -1,9 +1,9 @@
+import { HasOne, Num, Uid, Attr } from 'pinia-orm/dist/decorators'
 import type { Historical } from '~/types/interfaces'
 import type { Historical } from '~/types/interfaces'
-import Person from "~/models/Person/Person";
-import ApiModel from "~/models/ApiModel";
-import {HasOne, Num, Uid, Attr} from "pinia-orm/dist/decorators";
-import {IriEncoded} from "~/models/decorators";
-import Organization from "~/models/Organization/Organization";
+import Person from '~/models/Person/Person'
+import ApiModel from '~/models/ApiModel'
+import { IriEncoded } from '~/models/decorators'
+import Organization from '~/models/Organization/Organization'
 
 
 /**
 /**
  * AP2i Model : Access
  * AP2i Model : Access

+ 4 - 4
models/Access/AdminAccess.ts

@@ -1,5 +1,5 @@
-import {Str, Uid} from "pinia-orm/dist/decorators";
-import ApiResource from "~/models/ApiResource";
+import { Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Access/AdminAccess.php
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Access/AdminAccess.php
@@ -11,8 +11,8 @@ export default class AdminAccess extends ApiResource {
   declare id: number
   declare id: number
 
 
   @Str(null)
   @Str(null)
-  declare username: string|null
+  declare username: string | null
 
 
   @Str(null)
   @Str(null)
-  declare email: string|null
+  declare email: string | null
 }
 }

+ 4 - 4
models/Access/MyProfile.ts

@@ -1,8 +1,8 @@
-import {Num, Uid, Attr, Bool, Str} from 'pinia-orm/dist/decorators'
+import { Num, Uid, Attr, Bool, Str } from 'pinia-orm/dist/decorators'
 import type { Historical } from '~/types/interfaces'
 import type { Historical } from '~/types/interfaces'
-import Access from "~/models/Access/Access";
-import OrganizationProfile from "~/models/Organization/OrganizationProfile";
-import ApiResource from "~/models/ApiResource";
+import Access from '~/models/Access/Access'
+import OrganizationProfile from '~/models/Organization/OrganizationProfile'
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * Ap2i ApiResource : AccessProfile
  * Ap2i ApiResource : AccessProfile

+ 5 - 5
models/Access/PersonalizedList.ts

@@ -1,5 +1,5 @@
-import {Str, Uid} from "pinia-orm/dist/decorators";
-import ApiModel from "~/models/ApiModel";
+import { Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * Ap2i Model : PersonalizedList
  * Ap2i Model : PersonalizedList
@@ -13,11 +13,11 @@ export default class PersonalizedList extends ApiModel {
   declare id: number | string | null
   declare id: number | string | null
 
 
   @Str(null)
   @Str(null)
-  declare label:string|null
+  declare label: string | null
 
 
   @Str(null)
   @Str(null)
-  declare entity:string|null
+  declare entity: string | null
 
 
   @Str('')
   @Str('')
-  declare menuKey:string
+  declare menuKey: string
 }
 }

+ 2 - 3
models/ApiModel.ts

@@ -1,11 +1,10 @@
-import ApiResource from "~/models/ApiResource";
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * Entities from the API
  * Entities from the API
  *
  *
  * These models support CRUD operations
  * These models support CRUD operations
  */
  */
-export class ApiModel extends ApiResource {
-}
+class ApiModel extends ApiResource {}
 
 
 export default ApiModel
 export default ApiModel

+ 30 - 28
models/ApiResource.ts

@@ -1,40 +1,42 @@
-import {Model} from "pinia-orm";
+import { Model } from 'pinia-orm'
 
 
 /**
 /**
  * Base class for resources that can be fetched from the API
  * Base class for resources that can be fetched from the API
  */
  */
-export class ApiResource extends Model {
+class ApiResource extends Model {
+  // eslint-disable-next-line no-use-before-define
+  protected static _iriEncodedFields: Record<string, ApiResource>
 
 
-    protected static _iriEncodedFields: Record<string, ApiResource>
-
-    public static addIriEncodedField(name: string, target: ApiResource) {
-        if (!this._iriEncodedFields) {
-            this._iriEncodedFields = {}
-        }
-        this._iriEncodedFields[name] = target
+  public static addIriEncodedField(name: string, target: ApiResource) {
+    if (!this._iriEncodedFields) {
+      this._iriEncodedFields = {}
     }
     }
+    this._iriEncodedFields[name] = target
+  }
 
 
-    public static getIriEncodedFields() {
-        return this._iriEncodedFields
-    }
+  public static getIriEncodedFields() {
+    return this._iriEncodedFields
+  }
 
 
-    /**
-     * Fix the 'Cannot stringify arbitrary non-POJOs' warning, meaning server can not parse the store
-     *
-     * @see https://github.com/vuex-orm/vuex-orm/issues/255#issuecomment-876378684
-     */
-    toJSON () {
-        return { ...this }
-    }
+  /**
+   * Fix the 'Cannot stringify arbitrary non-POJOs' warning, meaning server can not parse the store
+   *
+   * @see https://github.com/vuex-orm/vuex-orm/issues/255#issuecomment-876378684
+   */
+  toJSON() {
+    return { ...this }
+  }
 
 
-    /**
-     * Is it a newly created entity?
-     *
-     * If it is, it means this entity does not exist in the data source and that it has a temporary id
-     */
-    public isNew(): boolean {
-        return !this.id || (typeof this.id === 'string' && this.id.slice(0, 3) === 'tmp')
-    }
+  /**
+   * Is it a newly created entity?
+   *
+   * If it is, it means this entity does not exist in the data source and that it has a temporary id
+   */
+  public isNew(): boolean {
+    return (
+      !this.id || (typeof this.id === 'string' && this.id.slice(0, 3) === 'tmp')
+    )
+  }
 }
 }
 
 
 export default ApiResource
 export default ApiResource

+ 3 - 3
models/Billing/ResidenceArea.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Str, Uid} from "pinia-orm/dist/decorators";
+import { Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * Ap2i Model : ResidenceArea
  * Ap2i Model : ResidenceArea
@@ -13,5 +13,5 @@ export default class ResidenceArea extends ApiModel {
   declare id: number | string
   declare id: number | string
 
 
   @Str(null)
   @Str(null)
-  declare label: string|null
+  declare label: string | null
 }
 }

+ 7 - 9
models/Booking/AttendanceBookingReason.ts

@@ -1,7 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Attr, Str, Uid} from "pinia-orm/dist/decorators";
-import {IriEncoded} from "~/models/decorators";
-import Organization from "~/models/Organization/Organization";
+import { Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * Motif d'absence ou de retard
  * Motif d'absence ou de retard
@@ -9,11 +7,11 @@ import Organization from "~/models/Organization/Organization";
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/Entity/Booking/AttendanceBookingReason.php
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/Entity/Booking/AttendanceBookingReason.php
  */
  */
 export default class AttendanceBookingReason extends ApiModel {
 export default class AttendanceBookingReason extends ApiModel {
-    static entity = 'attendance_booking_reasons'
+  static entity = 'attendance_booking_reasons'
 
 
-    @Uid()
-    declare id: number | string
+  @Uid()
+  declare id: number | string
 
 
-    @Str(null)
-    declare reason: string|null
+  @Str(null)
+  declare reason: string | null
 }
 }

+ 9 - 9
models/Core/AddressPostal.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Num, Str, Uid, Attr} from "pinia-orm/dist/decorators";
+import { Num, Str, Uid, Attr } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * Ap2i Model : AddressPostal
  * Ap2i Model : AddressPostal
@@ -16,25 +16,25 @@ export default class AddressPostal extends ApiModel {
   declare organizationAddressPostalId: number | null
   declare organizationAddressPostalId: number | null
 
 
   @Str(null)
   @Str(null)
-  declare addressCountry: string|null
+  declare addressCountry: string | null
 
 
   @Str(null)
   @Str(null)
-  declare addressCity: string|null
+  declare addressCity: string | null
 
 
   @Str(null)
   @Str(null)
-  declare addressOwner: string|null
+  declare addressOwner: string | null
 
 
   @Str(null)
   @Str(null)
-  declare postalCode: string|null
+  declare postalCode: string | null
 
 
   @Str(null)
   @Str(null)
-  declare streetAddress: string|null
+  declare streetAddress: string | null
 
 
   @Str(null)
   @Str(null)
-  declare streetAddressSecond: string|null
+  declare streetAddressSecond: string | null
 
 
   @Str(null)
   @Str(null)
-  declare streetAddressThird: string|null
+  declare streetAddressThird: string | null
 
 
   @Num(0)
   @Num(0)
   declare latitude: number
   declare latitude: number

+ 9 - 9
models/Core/BankAccount.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Bool, Str, Uid, Attr} from "pinia-orm/dist/decorators";
+import { Bool, Str, Uid, Attr } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : BankAccount
  * AP2i Model : BankAccount
@@ -13,25 +13,25 @@ export default class BankAccount extends ApiModel {
   declare id: number | string | null
   declare id: number | string | null
 
 
   @Str(null)
   @Str(null)
-  declare bankName: string|null
+  declare bankName: string | null
 
 
   @Str(null)
   @Str(null)
-  declare bic: string|null
+  declare bic: string | null
 
 
   @Str(null)
   @Str(null)
-  declare bicInvalid: string|null
+  declare bicInvalid: string | null
 
 
   @Str(null)
   @Str(null)
-  declare iban: string|null
+  declare iban: string | null
 
 
   @Str(null)
   @Str(null)
-  declare ibanInvalid: string|null
+  declare ibanInvalid: string | null
 
 
   @Str(null)
   @Str(null)
-  declare debitAddress: string|null
+  declare debitAddress: string | null
 
 
   @Str(null)
   @Str(null)
-  declare holder: string|null
+  declare holder: string | null
 
 
   @Bool(false)
   @Bool(false)
   declare principal: boolean
   declare principal: boolean

+ 10 - 10
models/Core/ContactPoint.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Str, Uid, Attr} from "pinia-orm/dist/decorators";
+import { Str, Uid, Attr } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : ContactPoint
  * AP2i Model : ContactPoint
@@ -16,28 +16,28 @@ export default class ContactPoint extends ApiModel {
   declare contactType: string
   declare contactType: string
 
 
   @Str(null)
   @Str(null)
-  declare email: string|null
+  declare email: string | null
 
 
   @Str(null)
   @Str(null)
-  declare emailInvalid: string|null
+  declare emailInvalid: string | null
 
 
   @Str(null)
   @Str(null)
-  declare telphone: string|null
+  declare telphone: string | null
 
 
   @Str(null)
   @Str(null)
-  declare telphoneInvalid: string|null
+  declare telphoneInvalid: string | null
 
 
   @Str(null)
   @Str(null)
-  declare mobilPhone: string|null
+  declare mobilPhone: string | null
 
 
   @Str(null)
   @Str(null)
-  declare mobilPhoneInvalid: string|null
+  declare mobilPhoneInvalid: string | null
 
 
   @Str(null)
   @Str(null)
-  declare faxNumber: string|null
+  declare faxNumber: string | null
 
 
   @Str(null)
   @Str(null)
-  declare faxNumberInvalid: string|null
+  declare faxNumberInvalid: string | null
 
 
   @Attr([])
   @Attr([])
   declare organization: []
   declare organization: []

+ 2 - 2
models/Core/Country.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Str, Uid} from "pinia-orm/dist/decorators";
+import { Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : Country
  * AP2i Model : Country

+ 2 - 2
models/Core/File.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Num, Str, Uid} from "pinia-orm/dist/decorators";
+import { Num, Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : File
  * AP2i Model : File

+ 5 - 5
models/Core/Notification.ts

@@ -1,6 +1,6 @@
-import NotificationMessage from "~/models/Core/NotificationMessage";
-import {HasOne, Str, Uid, Attr} from "pinia-orm/dist/decorators";
-import ApiModel from "~/models/ApiModel";
+import { Str, Uid, Attr } from 'pinia-orm/dist/decorators'
+import NotificationMessage from '~/models/Core/NotificationMessage'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : Notification
  * AP2i Model : Notification
@@ -23,10 +23,10 @@ export default class Notification extends ApiModel {
   declare createDate: string
   declare createDate: string
 
 
   @Str(null)
   @Str(null)
-  declare type: string|null
+  declare type: string | null
 
 
   @Str(null)
   @Str(null)
-  declare link: string|null
+  declare link: string | null
 
 
   @Attr({})
   @Attr({})
   declare notificationUsers: Array<string>
   declare notificationUsers: Array<string>

+ 5 - 5
models/Core/NotificationMessage.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Str, Uid} from "pinia-orm/dist/decorators";
+import { Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * // TODO: qu'est-ce que c'est?
  * // TODO: qu'est-ce que c'est?
@@ -11,11 +11,11 @@ export default class NotificationMessage extends ApiModel {
   declare id: number | string | null
   declare id: number | string | null
 
 
   @Str(null)
   @Str(null)
-  declare about: string|null
+  declare about: string | null
 
 
   @Str(null)
   @Str(null)
-  declare action: string|null
+  declare action: string | null
 
 
   @Str(null)
   @Str(null)
-  declare fileName: string|null
+  declare fileName: string | null
 }
 }

+ 4 - 4
models/Core/NotificationUsers.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Bool, Str, Uid} from "pinia-orm/dist/decorators";
+import { Bool, Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : NotificationUser
  * AP2i Model : NotificationUser
@@ -13,10 +13,10 @@ export default class NotificationUsers extends ApiModel {
   declare id: number | string | null
   declare id: number | string | null
 
 
   @Str(null)
   @Str(null)
-  declare notification: string|null
+  declare notification: string | null
 
 
   @Str(null)
   @Str(null)
-  declare access: string|null
+  declare access: string | null
 
 
   @Bool(false)
   @Bool(false)
   declare isRead: boolean
   declare isRead: boolean

+ 9 - 9
models/Core/Tagg.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Attr, Str, Uid} from "pinia-orm/dist/decorators";
+import { Attr, Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : Tagg
  * AP2i Model : Tagg
@@ -7,14 +7,14 @@ import {Attr, Str, Uid} from "pinia-orm/dist/decorators";
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/Entity/Core/Tagg.php
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/Entity/Core/Tagg.php
  */
  */
 export default class Tagg extends ApiModel {
 export default class Tagg extends ApiModel {
-    static entity = 'taggs'
+  static entity = 'taggs'
 
 
-    @Uid()
-    declare id: number | string | null
+  @Uid()
+  declare id: number | string | null
 
 
-    @Str('')
-    declare label: string
+  @Str('')
+  declare label: string
 
 
-    @Attr([])
-    declare organization: []
+  @Attr([])
+  declare organization: []
 }
 }

+ 4 - 4
models/Education/Cycle.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Num, Str, Uid} from "pinia-orm/dist/decorators";
+import { Num, Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model: Cycle
  * AP2i Model: Cycle
@@ -13,10 +13,10 @@ export default class Cycle extends ApiModel {
   declare id: number | string | null
   declare id: number | string | null
 
 
   @Str(null)
   @Str(null)
-  declare label: string|null
+  declare label: string | null
 
 
   @Str(null)
   @Str(null)
-  declare cycleEnum: string|null
+  declare cycleEnum: string | null
 
 
   @Num(0)
   @Num(0)
   declare order: number
   declare order: number

+ 2 - 2
models/Education/EducationTiming.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Num, Uid} from "pinia-orm/dist/decorators";
+import { Num, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : EducationTiming
  * AP2i Model : EducationTiming

+ 2 - 2
models/Export/LicenceCmfOrganizationER.ts

@@ -1,5 +1,5 @@
-import {Bool, Num, Str, Uid} from "pinia-orm/dist/decorators";
-import ApiResource from "~/models/ApiResource";
+import { Bool, Num, Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * Ap2i ApiResource : LicenceCmfOrganizationER
  * Ap2i ApiResource : LicenceCmfOrganizationER

+ 2 - 2
models/Network/Network.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Str, Uid, Attr} from "pinia-orm/dist/decorators";
+import { Str, Uid, Attr } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : Network
  * AP2i Model : Network

+ 3 - 3
models/Network/NetworkOrganization.ts

@@ -1,6 +1,6 @@
-import Network from "~/models/Network/Network";
-import ApiModel from "~/models/ApiModel";
-import {HasOne, Str, Uid} from "pinia-orm/dist/decorators";
+import { HasOne, Str, Uid } from 'pinia-orm/dist/decorators'
+import Network from '~/models/Network/Network'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : NetworkOrganization
  * AP2i Model : NetworkOrganization

+ 9 - 9
models/OnlineRegistration/RegistrationAvailability.ts

@@ -1,18 +1,18 @@
-import ApiResource from "~/models/ApiResource";
-import {Bool, Str, Uid} from "pinia-orm/dist/decorators";
+import { Bool, Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * Disponibilité (ouverture) de l'IEL
  * Disponibilité (ouverture) de l'IEL
  */
  */
 export default class RegistrationAvailability extends ApiResource {
 export default class RegistrationAvailability extends ApiResource {
-    static entity = 'online_registration/availability'
+  static entity = 'online_registration/availability'
 
 
-    @Uid()
-    declare id: number | string | null
+  @Uid()
+  declare id: number | string | null
 
 
-    @Bool(false)
-    declare available: boolean
+  @Bool(false)
+  declare available: boolean
 
 
-    @Str(null)
-    declare message: string
+  @Str(null)
+  declare message: string
 }
 }

+ 2 - 2
models/OnlineRegistration/RegistrationStatus.ts

@@ -1,5 +1,5 @@
-import {Num, Str, Uid} from "pinia-orm/dist/decorators";
-import ApiResource from "~/models/ApiResource";
+import { Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * AP2i Model : File
  * AP2i Model : File

+ 9 - 9
models/Organization/Cotisation.ts

@@ -1,5 +1,5 @@
-import ApiResource from "~/models/ApiResource";
-import {Num, Str, Uid} from "pinia-orm/dist/decorators";
+import { Num, Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * Ap2i ApiResource : Cotisation
  * Ap2i ApiResource : Cotisation
@@ -7,14 +7,14 @@ import {Num, Str, Uid} from "pinia-orm/dist/decorators";
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Cotisation/Cotisation.php
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Cotisation/Cotisation.php
  */
  */
 export default class Cotisation extends ApiResource {
 export default class Cotisation extends ApiResource {
-    static entity = 'cotisations'
+  static entity = 'cotisations'
 
 
-    @Uid()
-    declare id: number | string | null
+  @Uid()
+  declare id: number | string | null
 
 
-    @Str(null)
-    declare alertState: string | null
+  @Str(null)
+  declare alertState: string | null
 
 
-    @Num(null)
-    declare cotisationYear: number | null
+  @Num(null)
+  declare cotisationYear: number | null
 }
 }

+ 20 - 15
models/Organization/DolibarrAccount.ts

@@ -1,5 +1,5 @@
-import ApiResource from "~/models/ApiResource";
-import {Attr, Num, Str, Uid} from "pinia-orm/dist/decorators";
+import { Attr, Num, Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * The Dolibarr account of an organization
  * The Dolibarr account of an organization
@@ -7,23 +7,28 @@ import {Attr, Num, Str, Uid} from "pinia-orm/dist/decorators";
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Dolibarr/DolibarrAccount.php
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Dolibarr/DolibarrAccount.php
  */
  */
 export default class DolibarrAccount extends ApiResource {
 export default class DolibarrAccount extends ApiResource {
-    static entity = 'dolibarr/account'
+  static entity = 'dolibarr/account'
 
 
-    @Uid()
-    declare id: number | string | null
+  @Uid()
+  declare id: number | string | null
 
 
-    @Num(0, { notNullable: true })
-    declare organizationId: number
+  @Num(0, { notNullable: true })
+  declare organizationId: number
 
 
-    @Str(null)
-    declare clientNumber: string
+  @Str(null)
+  declare clientNumber: string
 
 
-    @Str(null)
-    declare product: string
+  @Str(null)
+  declare product: string
 
 
-    @Attr({})
-    declare contract: object
+  @Attr({})
+  declare contract: object
 
 
-    @Attr([])
-    declare bills: Array<object>
+  @Attr([])
+  declare bills: Array<{
+    ref: string
+    date: string
+    taxExcludedAmount: number
+    paid: boolean
+  }>
 }
 }

+ 13 - 16
models/Organization/MobytUserStatus.ts

@@ -1,6 +1,5 @@
-import ApiResource from "~/models/ApiResource";
-import {Bool, Num, Uid} from "pinia-orm/dist/decorators";
-
+import { Bool, Num, Uid } from 'pinia-orm/dist/decorators'
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * The Mobyt user status of an organization
  * The Mobyt user status of an organization
@@ -8,22 +7,20 @@ import {Bool, Num, Uid} from "pinia-orm/dist/decorators";
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Mobyt/MobytUserStatus.php
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Mobyt/MobytUserStatus.php
  */
  */
 export default class MobytUserStatus extends ApiResource {
 export default class MobytUserStatus extends ApiResource {
-    static entity = 'mobyt/status'
+  static entity = 'mobyt/status'
 
 
-    @Uid()
-    declare id: number | string | null
+  @Uid()
+  declare id: number | string | null
 
 
-    @Num(0, { notNullable: true })
-    declare organizationId: number
+  @Num(0, { notNullable: true })
+  declare organizationId: number
 
 
-    @Bool(false, { notNullable: true })
-    declare active: boolean
+  @Bool(false, { notNullable: true })
+  declare active: boolean
 
 
-    @Num(0, { notNullable: true })
-    declare amount: number
+  @Num(0, { notNullable: true })
+  declare amount: number
 
 
-    @Num(0, { notNullable: true })
-    declare money: number
+  @Num(0, { notNullable: true })
+  declare money: number
 }
 }
-
-

+ 34 - 34
models/Organization/Organization.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Bool, Str, Attr, Num, Uid} from "pinia-orm/dist/decorators";
+import { Bool, Str, Attr, Num, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : Organization
  * AP2i Model : Organization
@@ -13,103 +13,103 @@ export default class Organization extends ApiModel {
   declare id: number | string
   declare id: number | string
 
 
   @Str(null)
   @Str(null)
-  declare name: string|null
+  declare name: string | null
 
 
   @Str(null)
   @Str(null)
-  declare acronym: string|null
+  declare acronym: string | null
 
 
   @Str(null)
   @Str(null)
-  declare siretNumber: string|null
+  declare siretNumber: string | null
 
 
   @Str(null)
   @Str(null)
-  declare apeNumber: string|null
+  declare apeNumber: string | null
 
 
   @Str(null)
   @Str(null)
-  declare waldecNumber: string|null
+  declare waldecNumber: string | null
 
 
   @Str(null)
   @Str(null)
-  declare identifier: string|null
+  declare identifier: string | null
 
 
   @Str(null)
   @Str(null)
-  declare ffecApproval: string|null
+  declare ffecApproval: string | null
 
 
   @Str(null)
   @Str(null)
-  declare description: string|null
+  declare description: string | null
 
 
   @Attr([])
   @Attr([])
   declare typeOfPractices: []
   declare typeOfPractices: []
 
 
   @Str(null)
   @Str(null)
-  declare otherPractice: string|null
+  declare otherPractice: string | null
 
 
   @Str(null)
   @Str(null)
-  declare legalStatus: string|null
+  declare legalStatus: string | null
 
 
   @Str(null)
   @Str(null)
-  declare principalType: string|null
+  declare principalType: string | null
 
 
   @Str(null)
   @Str(null)
-  declare youngApproval: string|null
+  declare youngApproval: string | null
 
 
   @Str(null)
   @Str(null)
-  declare trainingApproval: string|null
+  declare trainingApproval: string | null
 
 
   @Str(null)
   @Str(null)
-  declare otherApproval: string|null
+  declare otherApproval: string | null
 
 
   @Str(null)
   @Str(null)
-  declare collectiveAgreement: string|null
+  declare collectiveAgreement: string | null
 
 
   @Str(null)
   @Str(null)
-  declare opca: string|null
+  declare opca: string | null
 
 
   @Str(null)
   @Str(null)
-  declare icomNumber: string|null
+  declare icomNumber: string | null
 
 
   @Str(null)
   @Str(null)
-  declare urssafNumber: string|null
+  declare urssafNumber: string | null
 
 
   @Str(null)
   @Str(null)
-  declare twitter: string|null
+  declare twitter: string | null
 
 
   @Str(null)
   @Str(null)
-  declare youtube: string|null
+  declare youtube: string | null
 
 
   @Str(null)
   @Str(null)
-  declare facebook: string|null
+  declare facebook: string | null
 
 
   @Str(null)
   @Str(null)
-  declare instagram: string|null
+  declare instagram: string | null
 
 
   @Bool(true, { notNullable: true })
   @Bool(true, { notNullable: true })
   declare portailVisibility: boolean
   declare portailVisibility: boolean
 
 
   @Str(null)
   @Str(null)
-  declare image: string|null
+  declare image: string | null
 
 
   @Str(null)
   @Str(null)
-  declare creationDate: string|null
+  declare creationDate: string | null
 
 
   @Str(null)
   @Str(null)
-  declare prefectureName: string|null
+  declare prefectureName: string | null
 
 
   @Str(null)
   @Str(null)
-  declare prefectureNumber: string|null
+  declare prefectureNumber: string | null
 
 
   @Str(null)
   @Str(null)
-  declare declarationDate: string|null
+  declare declarationDate: string | null
 
 
   @Str(null)
   @Str(null)
-  declare tvaNumber: string|null
+  declare tvaNumber: string | null
 
 
   @Str(null)
   @Str(null)
-  declare schoolCategory: string|null
+  declare schoolCategory: string | null
 
 
   @Str(null)
   @Str(null)
-  declare typeEstablishment: string|null
+  declare typeEstablishment: string | null
 
 
   @Str(null)
   @Str(null)
-  declare typeEstablishmentDetail: string|null
+  declare typeEstablishmentDetail: string | null
 
 
   @Bool(false, { notNullable: true })
   @Bool(false, { notNullable: true })
   declare isPerformanceContractor: boolean
   declare isPerformanceContractor: boolean
@@ -124,5 +124,5 @@ export default class Organization extends ApiModel {
   declare pedagogicBudget: number
   declare pedagogicBudget: number
 
 
   @Str(null)
   @Str(null)
-  declare logo: string|null
+  declare logo: string | null
 }
 }

+ 2 - 2
models/Organization/OrganizationAddressPostal.ts

@@ -1,6 +1,6 @@
+import { HasOne, Str, Uid } from 'pinia-orm/dist/decorators'
 import AddressPostal from '~/models/Core/AddressPostal'
 import AddressPostal from '~/models/Core/AddressPostal'
-import ApiModel from "~/models/ApiModel";
-import {HasOne, Str, Uid} from "pinia-orm/dist/decorators";
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : OrganizationAddressPostal
  * AP2i Model : OrganizationAddressPostal

+ 2 - 2
models/Organization/OrganizationArticle.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Str, Uid} from "pinia-orm/dist/decorators";
+import { Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : OrganizationArticle
  * AP2i Model : OrganizationArticle

+ 5 - 5
models/Organization/OrganizationLicence.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Str, Uid} from "pinia-orm/dist/decorators";
+import { Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : OrganizationLicence
  * AP2i Model : OrganizationLicence
@@ -16,11 +16,11 @@ export default class OrganizationLicence extends ApiModel {
   declare licensee: string
   declare licensee: string
 
 
   @Str(null)
   @Str(null)
-  declare licenceNumber: string|null
+  declare licenceNumber: string | null
 
 
   @Str(null)
   @Str(null)
-  declare categorie: string|null
+  declare categorie: string | null
 
 
   @Str(null)
   @Str(null)
-  declare validityDate: string|null
+  declare validityDate: string | null
 }
 }

+ 2 - 2
models/Organization/OrganizationNetwork.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Uid} from "pinia-orm/dist/decorators";
+import { Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 export default class OrganizationNetwork extends ApiModel {
 export default class OrganizationNetwork extends ApiModel {
   static entity = 'organization_networks'
   static entity = 'organization_networks'

+ 25 - 25
models/Organization/OrganizationProfile.ts

@@ -1,5 +1,5 @@
-import ApiResource from "~/models/ApiResource";
-import {Str, Uid, Attr, Bool, Num} from "pinia-orm/dist/decorators";
+import { Str, Uid, Attr, Bool, Num } from 'pinia-orm/dist/decorators'
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * ApiResource : OrganizationProfile
  * ApiResource : OrganizationProfile
@@ -7,38 +7,38 @@ import {Str, Uid, Attr, Bool, Num} from "pinia-orm/dist/decorators";
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Profile/OrganizationProfile.php
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Profile/OrganizationProfile.php
  */
  */
 export default class OrganizationProfile extends ApiResource {
 export default class OrganizationProfile extends ApiResource {
-    static entity = 'organization_profile'
+  static entity = 'organization_profile'
 
 
-    @Uid()
-    declare id: number | string | null
+  @Uid()
+  declare id: number | string | null
 
 
-    @Str(null)
-    declare name: string
+  @Str(null)
+  declare name: string
 
 
-    @Str(null)
-    declare product: string
+  @Str(null)
+  declare product: string
 
 
-    @Str(null)
-    declare legalStatus: string
+  @Str(null)
+  declare legalStatus: string
 
 
-    @Attr([])
-    declare networks: Array<string>
+  @Attr([])
+  declare networks: Array<string>
 
 
-    @Attr([])
-    declare modules: Array<string>
+  @Attr([])
+  declare modules: Array<string>
 
 
-    @Bool(false)
-    declare hasChildren: boolean
+  @Bool(false)
+  declare hasChildren: boolean
 
 
-    @Attr([])
-    declare parents: Array<number>
+  @Attr([])
+  declare parents: Array<{ id: number; name: string; website: string }>
 
 
-    @Bool(false)
-    declare showAdherentList: boolean
+  @Bool(false)
+  declare showAdherentList: boolean
 
 
-    @Num(null)
-    declare currentYear: null
+  @Num(null)
+  declare currentYear: null
 
 
-    @Num(null)
-    declare parametersId: null
+  @Num(null)
+  declare parametersId: null
 }
 }

+ 4 - 4
models/Organization/Parameters.ts

@@ -1,8 +1,8 @@
-import ApiModel from '~/models/ApiModel'
 import { Bool, Num, Str, Uid, Attr } from 'pinia-orm/dist/decorators'
 import { Bool, Num, Str, Uid, Attr } from 'pinia-orm/dist/decorators'
-import Access from "~/models/Access/Access";
-import {IriEncoded} from "~/models/decorators";
-import File from "~/models/Core/File";
+import ApiModel from '~/models/ApiModel'
+import Access from '~/models/Access/Access'
+import { IriEncoded } from '~/models/decorators'
+import File from '~/models/Core/File'
 
 
 /**
 /**
  * AP2i Model : Parameters
  * AP2i Model : Parameters

+ 2 - 2
models/Organization/Subdomain.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Bool, Str, Uid} from "pinia-orm/dist/decorators";
+import { Bool, Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : Subdomain
  * AP2i Model : Subdomain

+ 9 - 9
models/Organization/SubdomainAvailability.ts

@@ -1,15 +1,15 @@
-import ApiResource from "~/models/ApiResource";
-import {Str, Uid, Attr, Bool, Num} from "pinia-orm/dist/decorators";
+import { Str, Uid, Bool } from 'pinia-orm/dist/decorators'
+import ApiResource from '~/models/ApiResource'
 
 
 export default class SubdomainAvailability extends ApiResource {
 export default class SubdomainAvailability extends ApiResource {
-    static entity = 'subdomains/is_available'
+  static entity = 'subdomains/is_available'
 
 
-    @Uid()
-    declare id: number | string | null
+  @Uid()
+  declare id: number | string | null
 
 
-    @Str(null)
-    declare subdomain: string
+  @Str(null)
+  declare subdomain: string
 
 
-    @Bool(false)
-    declare available: boolean
+  @Bool(false)
+  declare available: boolean
 }
 }

+ 2 - 2
models/Organization/TypeOfPractice.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Str, Uid} from "pinia-orm/dist/decorators";
+import { Str, Uid } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : TypeOfPractice
  * AP2i Model : TypeOfPractice

+ 5 - 5
models/Person/Person.ts

@@ -1,5 +1,5 @@
-import ApiModel from "~/models/ApiModel";
-import {Str, Uid, Attr} from "pinia-orm/dist/decorators";
+import { Str, Uid, Attr } from 'pinia-orm/dist/decorators'
+import ApiModel from '~/models/ApiModel'
 
 
 /**
 /**
  * AP2i Model : Person
  * AP2i Model : Person
@@ -16,11 +16,11 @@ export default class Person extends ApiModel {
   declare accessId: number | null
   declare accessId: number | null
 
 
   @Str(null)
   @Str(null)
-  declare username: string|null
+  declare username: string | null
 
 
   @Str(null)
   @Str(null)
-  declare name: string|null
+  declare name: string | null
 
 
   @Str(null)
   @Str(null)
-  declare givenName: string|null
+  declare givenName: string | null
 }
 }

+ 9 - 10
models/decorators.ts

@@ -1,4 +1,4 @@
-import ApiResource from "~/models/ApiResource";
+import ApiResource from '~/models/ApiResource'
 
 
 /**
 /**
  * Decorates an ApiResource's property to signal it as a field that is provided
  * Decorates an ApiResource's property to signal it as a field that is provided
@@ -7,14 +7,13 @@ import ApiResource from "~/models/ApiResource";
  * If the property is decorated, the HydraNormalizer will parse the IRI when de-normalizing
  * If the property is decorated, the HydraNormalizer will parse the IRI when de-normalizing
  * to get the id(s), then re-encode it as IRI(s) when re-normalizing.
  * to get the id(s), then re-encode it as IRI(s) when re-normalizing.
  */
  */
-export function IriEncoded (
-    apiResource: typeof ApiResource
-): PropertyDecorator {
-    return (target: Object, propertyKey: string | symbol) => {
-        //@ts-ignore
-        const self = target.$self()
+export function IriEncoded(apiResource: typeof ApiResource): PropertyDecorator {
+  // We have to comply with the PropertyDecorator return type
+  // eslint-disable-next-line @typescript-eslint/ban-types
+  return (target: Object, propertyKey: string | symbol) => {
+    // @ts-expect-error The object is an ApiResource
+    const self = target.$self()
 
 
-        //@ts-ignore
-        self.addIriEncodedField(propertyKey, apiResource)
-    }
+    self.addIriEncodedField(propertyKey as string, apiResource)
+  }
 }
 }

+ 6 - 4
models/models.ts

@@ -1,12 +1,14 @@
+import ApiResource from '~/models/ApiResource'
+
 const modules = import.meta.glob('~/models/*/*.ts')
 const modules = import.meta.glob('~/models/*/*.ts')
-import ApiResource from "~/models/ApiResource";
 
 
 const models: Record<string, typeof ApiResource> = {}
 const models: Record<string, typeof ApiResource> = {}
 
 
 for (const path in modules) {
 for (const path in modules) {
-    modules[path]().then((mod: any) => {
-        models[mod.default.entity] = mod.default
-    })
+  modules[path]().then((mod) => {
+    // @ts-expect-error On est dépendant du retour de import.meta.glob pour le type
+    models[mod.default.entity] = mod.default
+  })
 }
 }
 
 
 export default models
 export default models

+ 190 - 143
nuxt.config.ts

@@ -1,21 +1,27 @@
-import fs from 'fs';
+import fs from 'fs'
 import vuetify from 'vite-plugin-vuetify'
 import vuetify from 'vite-plugin-vuetify'
 
 
 let https = {}
 let https = {}
 
 
-let transpile = ['vuetify', '@vuepic/vue-datepicker', 'pinia', 'pinia-orm', 'date-fns']
+const transpile = [
+  'vuetify',
+  '@vuepic/vue-datepicker',
+  'pinia',
+  'pinia-orm',
+  'date-fns',
+]
 
 
 if (!process.env.NUXT_ENV) {
 if (!process.env.NUXT_ENV) {
-    throw Error('Missing environment file - Run yarn install')
+  throw new Error('Missing environment file - Run yarn install')
 }
 }
 
 
 if (process.env.NUXT_ENV === 'dev') {
 if (process.env.NUXT_ENV === 'dev') {
-    https = {
-        key: fs.readFileSync('env/local.app.opentalent.fr.key'),
-        cert: fs.readFileSync('env/local.app.opentalent.fr.crt'),
-    }
+  https = {
+    key: fs.readFileSync('env/local.app.opentalent.fr.key'),
+    cert: fs.readFileSync('env/local.app.opentalent.fr.crt'),
+  }
 } else {
 } else {
-    transpile.push('lodash')
+  transpile.push('lodash')
 }
 }
 
 
 /**
 /**
@@ -24,148 +30,189 @@ if (process.env.NUXT_ENV === 'dev') {
  * @see https://nuxt.com/docs/api/configuration/nuxt-config
  * @see https://nuxt.com/docs/api/configuration/nuxt-config
  */
  */
 export default defineNuxtConfig({
 export default defineNuxtConfig({
-    ssr: true,
-    experimental: {
-        // Fix the 'Cannot stringify non POJO' bug
-        // @see https://github.com/nuxt/nuxt/issues/20787
-        renderJsonPayloads: false
+  ssr: true,
+  experimental: {
+    // Fix the 'Cannot stringify non POJO' bug
+    // @see https://github.com/nuxt/nuxt/issues/20787
+    renderJsonPayloads: false,
+  },
+  runtimeConfig: {
+    // Private config that is only available on the server
+    env: '',
+    baseUrl: '',
+    baseUrlLegacy: '',
+    baseUrlAdminLegacy: '',
+    baseUrlTypo3: '',
+    baseUrlMercure: '',
+    supportUrl: '',
+    // Config within public will be also exposed to the client
+    public: {
+      env: '',
+      baseUrl: '',
+      baseUrlLegacy: '',
+      baseUrlAdminLegacy: '',
+      baseUrlTypo3: '',
+      baseUrlMercure: '',
+      supportUrl: '',
     },
     },
-    runtimeConfig: {
-        // Private config that is only available on the server
-        env: '',
-        baseUrl: '',
-        baseUrlLegacy: '',
-        baseUrlAdminLegacy: '',
-        baseUrlTypo3: '',
-        baseUrlMercure: '',
-        supportUrl: '',
-        // Config within public will be also exposed to the client
-        public: {
-            env: '',
-            baseUrl: '',
-            baseUrlLegacy: '',
-            baseUrlAdminLegacy: '',
-            baseUrlTypo3: '',
-            baseUrlMercure: '',
-            supportUrl: '',
-        }
-    },
-    hooks: {
-        'builder:watch': console.log,
-    },
-    app: {
-        head: {
-            title: 'Opentalent',
-            meta: [
-                { charset: 'utf-8' },
-                { name: 'viewport', content: 'width=device-width, initial-scale=1' },
-                { name: 'msapplication-TileColor', content: '#324250' },
-                { name: 'msapplication-TileImage', content: '/favicon/mstile-144x144.png' }
-            ],
-            link: [
-                { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
-                { rel: 'apple-touch-icon-precomposed', sizes: '57x57', href: '/favicon/apple-touch-icon-57x57.png' },
-                { rel: 'apple-touch-icon-precomposed', sizes: '114x114', href: '/favicon/apple-touch-icon-114x114.png' },
-                { rel: 'apple-touch-icon-precomposed', sizes: '72x72', href: '/favicon/apple-touch-icon-72x72.png' },
-                { rel: 'apple-touch-icon-precomposed', sizes: '144x144', href: '/favicon/apple-touch-icon-144x144.png' },
-                { rel: 'apple-touch-icon-precomposed', sizes: '120x120', href: '/favicon/apple-touch-icon-120x120.png' },
-                { rel: 'apple-touch-icon-precomposed', sizes: '152x152', href: '/favicon/apple-touch-icon-152x152.png' },
-                { rel: 'icon', sizes: '32x32', type: 'image/x-icon', href: '/favicon/favicon-32x32.png' },
-                { rel: 'icon', sizes: '16x16', type: 'image/x-icon', href: '/favicon/favicon-16x16.png' },
-            ]
-        }
-    },
-    css: [
-        '@/assets/css/global.scss',
-        '@/assets/css/theme.scss',
-        '@/assets/css/import.scss',
-        '@vuepic/vue-datepicker/dist/main.css'
-    ],
-    typescript: {
-        strict: true
-    },
-    modules: [
-        async (options, nuxt) => {
-            nuxt.hooks.hook('vite:extendConfig', config => (config.plugins ?? []).push(
-                vuetify()
-                //Remplacer par cela quand l'issue https://github.com/vuetifyjs/vuetify-loader/issues/273 sera règlée..
-                // voir aussi : https://github.com/nuxt/nuxt/issues/15412 et https://github.com/vuetifyjs/vuetify-loader/issues/290
-                // voir aussi : https://github.com/jrutila/nuxt3-vuetify3-bug
-                // vuetify({
-                //     styles: { configFile: './assets/css/settings.scss' }
-                // })
-            ) as any );
+  },
+  hooks: {
+    'builder:watch': console.log,
+  },
+  app: {
+    head: {
+      title: 'Opentalent',
+      meta: [
+        { charset: 'utf-8' },
+        { name: 'viewport', content: 'width=device-width, initial-scale=1' },
+        { name: 'msapplication-TileColor', content: '#324250' },
+        {
+          name: 'msapplication-TileImage',
+          content: '/favicon/mstile-144x144.png',
         },
         },
-        [
-            '@pinia/nuxt',
-            {
-                autoImports: [
-                    // automatically imports `usePinia()`
-                    'defineStore',
-                    // automatically imports `usePinia()` as `usePiniaStore()`
-                    ['defineStore', 'definePiniaStore'],
-                ],
-            }
-        ],
-        '@pinia-orm/nuxt',
-        '@nuxtjs/i18n',
-        '@nuxt/devtools',
-        '@nuxt/image'
-    ],
-    vite: {
-        esbuild: {
-            drop: process.env.DEBUG ? [] : ['console', 'debugger'],
-            tsconfigRaw: {
-                compilerOptions: {
-                    experimentalDecorators: true,
-                }
-            }
+      ],
+      link: [
+        { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
+        {
+          rel: 'apple-touch-icon-precomposed',
+          sizes: '57x57',
+          href: '/favicon/apple-touch-icon-57x57.png',
+        },
+        {
+          rel: 'apple-touch-icon-precomposed',
+          sizes: '114x114',
+          href: '/favicon/apple-touch-icon-114x114.png',
+        },
+        {
+          rel: 'apple-touch-icon-precomposed',
+          sizes: '72x72',
+          href: '/favicon/apple-touch-icon-72x72.png',
         },
         },
-        ssr: {
-            // with ssr enabled, this config is required to load vuetify properly
-            noExternal: ['vuetify']
+        {
+          rel: 'apple-touch-icon-precomposed',
+          sizes: '144x144',
+          href: '/favicon/apple-touch-icon-144x144.png',
         },
         },
-        server : {
-            https,
-            //@ts-ignore
-            port: 443,
-            hmr: {
-                protocol: 'wss',
-                port: 24678
-            }
-        }
+        {
+          rel: 'apple-touch-icon-precomposed',
+          sizes: '120x120',
+          href: '/favicon/apple-touch-icon-120x120.png',
+        },
+        {
+          rel: 'apple-touch-icon-precomposed',
+          sizes: '152x152',
+          href: '/favicon/apple-touch-icon-152x152.png',
+        },
+        {
+          rel: 'icon',
+          sizes: '32x32',
+          type: 'image/x-icon',
+          href: '/favicon/favicon-32x32.png',
+        },
+        {
+          rel: 'icon',
+          sizes: '16x16',
+          type: 'image/x-icon',
+          href: '/favicon/favicon-16x16.png',
+        },
+      ],
     },
     },
-    // Hide the sourcemaps warnings with vuetify
-    // @see https://github.com/vuetifyjs/vuetify-loader/issues/290#issuecomment-1435702713
-    sourcemap: {
-        server: false,
-        client: false,
+  },
+  css: [
+    '@/assets/css/global.scss',
+    '@/assets/css/theme.scss',
+    '@/assets/css/import.scss',
+    '@vuepic/vue-datepicker/dist/main.css',
+  ],
+  typescript: {
+    strict: true,
+  },
+  modules: [
+    // eslint-disable-next-line require-await
+    async (_, nuxt) => {
+      nuxt.hooks.hook('vite:extendConfig', (config) =>
+        // @ts-expect-error A revoir après que les lignes aient été décommentées
+        (config.plugins ?? []).push(
+          vuetify(),
+          // Remplacer par cela quand l'issue https://github.com/vuetifyjs/vuetify-loader/issues/273 sera règlée..
+          // voir aussi : https://github.com/nuxt/nuxt/issues/15412 et https://github.com/vuetifyjs/vuetify-loader/issues/290
+          // voir aussi : https://github.com/jrutila/nuxt3-vuetify3-bug
+          // vuetify({
+          //     styles: { configFile: './assets/css/settings.scss' }
+          // })
+        ),
+      )
     },
     },
-    i18n: {
-        langDir: 'lang',
-        lazy: true,
-        locales: [
-            {
-                code: 'en',
-                iso: 'en-US',
-                file: 'en.json',
-                name: 'English'
-            },
-            {
-                code: 'fr',
-                iso: 'fr-FR',
-                file: 'fr.json',
-                name: 'Français'
-            }
+    [
+      '@pinia/nuxt',
+      {
+        autoImports: [
+          // automatically imports `usePinia()`
+          'defineStore',
+          // automatically imports `usePinia()` as `usePiniaStore()`
+          ['defineStore', 'definePiniaStore'],
         ],
         ],
-        defaultLocale: 'fr',
-        detectBrowserLanguage: false,
-        vueI18n: './i18n.config.ts'
+      },
+    ],
+    '@pinia-orm/nuxt',
+    '@nuxtjs/i18n',
+    '@nuxt/devtools',
+    '@nuxt/image',
+  ],
+  vite: {
+    esbuild: {
+      drop: process.env.DEBUG ? [] : ['console', 'debugger'],
+      tsconfigRaw: {
+        compilerOptions: {
+          experimentalDecorators: true,
+        },
+      },
     },
     },
-    image: {
-        provider: 'none'
+    ssr: {
+      // with ssr enabled, this config is required to load vuetify properly
+      noExternal: ['vuetify'],
     },
     },
-    build: {
-        transpile: transpile,
-    }
+    server: {
+      https,
+      // @ts-expect-error J'ignore pourquoi cette erreur TS se produit, cette propriété est valide
+      port: 443,
+      hmr: {
+        protocol: 'wss',
+        port: 24678,
+      },
+    },
+  },
+  // Hide the sourcemaps warnings with vuetify
+  // @see https://github.com/vuetifyjs/vuetify-loader/issues/290#issuecomment-1435702713
+  sourcemap: {
+    server: false,
+    client: false,
+  },
+  i18n: {
+    langDir: 'lang',
+    lazy: true,
+    locales: [
+      {
+        code: 'en',
+        iso: 'en-US',
+        file: 'en.json',
+        name: 'English',
+      },
+      {
+        code: 'fr',
+        iso: 'fr-FR',
+        file: 'fr.json',
+        name: 'Français',
+      },
+    ],
+    defaultLocale: 'fr',
+    detectBrowserLanguage: false,
+    vueI18n: './i18n.config.ts',
+  },
+  image: {
+    provider: 'none',
+  },
+  build: {
+    transpile,
+  },
 })
 })

+ 3 - 2
package.json

@@ -16,7 +16,8 @@
     "lint-fix": "eslint --fix --ext \".ts,.js,.vue\" --ignore-path .gitignore .",
     "lint-fix": "eslint --fix --ext \".ts,.js,.vue\" --ignore-path .gitignore .",
     "test": "vitest run",
     "test": "vitest run",
     "enable-devtools": "nuxi devtools enable",
     "enable-devtools": "nuxi devtools enable",
-    "nuxt-upgrade": "nuxi upgrade --force"
+    "nuxt-upgrade": "nuxi upgrade --force",
+    "eslint":  "eslint ."
   },
   },
   "dependencies": {
   "dependencies": {
     "@casl/ability": "^6.5.0",
     "@casl/ability": "^6.5.0",
@@ -24,7 +25,7 @@
     "@fortawesome/fontawesome-free": "^6.5.1",
     "@fortawesome/fontawesome-free": "^6.5.1",
     "@mdi/font": "^7.3.67",
     "@mdi/font": "^7.3.67",
     "@nuxt/image": "1.1.0",
     "@nuxt/image": "1.1.0",
-    "@nuxtjs/i18n": "^8.0.0-rc.8",
+    "@nuxtjs/i18n": "^8.2.0",
     "@pinia-orm/nuxt": "^1.7.0",
     "@pinia-orm/nuxt": "^1.7.0",
     "@pinia/nuxt": "0.5.1",
     "@pinia/nuxt": "0.5.1",
     "@vuepic/vue-datepicker": "^7.4.0",
     "@vuepic/vue-datepicker": "^7.4.0",

+ 6 - 0
pages/.eslintrc.cjs

@@ -0,0 +1,6 @@
+/** On désactive cette règle pour les pages et les layouts seulement : https://eslint.vuejs.org/rules/multi-word-component-names.html */
+module.exports = {
+  rules: {
+    'vue/multi-word-component-names': 0,
+  }
+}

+ 32 - 31
pages/cmf_licence_structure.vue

@@ -1,32 +1,26 @@
 <template>
 <template>
   <div class="d-flex flex-column align-center">
   <div class="d-flex flex-column align-center">
-    <h2 class="ma-4">{{ $t('cmf_structure_licence')}}</h2>
+    <h2 class="ma-4">{{ $t('cmf_structure_licence') }}</h2>
     <a
     <a
-        href="https://www.cmf-musique.org/services/tarifs-preferentiels/"
-        target="_blank"
+      href="https://www.cmf-musique.org/services/tarifs-preferentiels/"
+      target="_blank"
     >
     >
-      {{ $t('cmf_licence_details_url')}}
+      {{ $t('cmf_licence_details_url') }}
     </a>
     </a>
 
 
-    <v-form
-        ref="form"
-        lazy-validation
-    >
+    <v-form ref="form" lazy-validation>
       <div class="ma-12">
       <div class="ma-12">
-        <v-btn
-            v-if="!pending && file === null"
-            @click="submit"
-        >
+        <v-btn v-if="!pending && file === null" @click="submit">
           {{ $t('generate') }}
           {{ $t('generate') }}
         </v-btn>
         </v-btn>
 
 
         <v-btn
         <v-btn
-            v-else
-            color="primary"
-            :loading="pending"
-            :disabled="pending"
-            target="_blank"
-            @click="download"
+          v-else
+          color="primary"
+          :loading="pending"
+          :disabled="pending"
+          target="_blank"
+          @click="download"
         >
         >
           {{ $t('download') }}
           {{ $t('download') }}
         </v-btn>
         </v-btn>
@@ -36,19 +30,21 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import File from "~/models/Core/File"
-import type {ComputedRef, Ref} from "vue";
-import {useEntityFetch} from "~/composables/data/useEntityFetch";
-import {useSseStore} from "~/stores/sse";
-import {useEntityManager} from "~/composables/data/useEntityManager";
-import LicenceCmfOrganizationER from "~/models/Export/LicenceCmfOrganizationER";
-import {useDownloadFile} from "~/composables/utils/useDownloadFile";
+import type { ComputedRef, Ref } from 'vue'
+import File from '~/models/Core/File'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import { useSseStore } from '~/stores/sse'
+import { useEntityManager } from '~/composables/data/useEntityManager'
+import LicenceCmfOrganizationER from '~/models/Export/LicenceCmfOrganizationER'
+import { useDownloadFile } from '~/composables/utils/useDownloadFile'
 
 
 const { em } = useEntityManager()
 const { em } = useEntityManager()
 const { getRef } = useEntityFetch()
 const { getRef } = useEntityFetch()
 
 
 const sseStore = useSseStore()
 const sseStore = useSseStore()
-const async = () => { return sseStore.connected }
+const async = () => {
+  return sseStore.connected
+}
 
 
 const fileId = ref(null)
 const fileId = ref(null)
 
 
@@ -65,7 +61,11 @@ const submitting: Ref<boolean> = ref(false)
 const downloading: Ref<boolean> = ref(false)
 const downloading: Ref<boolean> = ref(false)
 
 
 const pending: ComputedRef<boolean> = computed(() => {
 const pending: ComputedRef<boolean> = computed(() => {
-  return submitting.value || (file.value !== null && file.value.status === 'PENDING') || downloading.value
+  return (
+    submitting.value ||
+    (file.value !== null && file.value.status === 'PENDING') ||
+    downloading.value
+  )
 })
 })
 
 
 const submit = async () => {
 const submit = async () => {
@@ -97,12 +97,13 @@ const submit = async () => {
     for (let i = 0; i < 3; i++) {
     for (let i = 0; i < 3; i++) {
       setTimeout(async () => {
       setTimeout(async () => {
         if (file.value && file.value.status === 'PENDING') {
         if (file.value && file.value.status === 'PENDING') {
-          console.warn("File's status has not been updated : force a status checkup")
+          console.warn(
+            "File's status has not been updated : force a status checkup",
+          )
           await em.fetch(File, receipt.fileId, true)
           await em.fetch(File, receipt.fileId, true)
         }
         }
       }, i * 4000)
       }, i * 4000)
     }
     }
-
   } finally {
   } finally {
     submitting.value = false
     submitting.value = false
   }
   }
@@ -112,12 +113,12 @@ const download = async () => {
   downloading.value = true
   downloading.value = true
 
 
   if (file.value === null) {
   if (file.value === null) {
-    console.error("File is not defined yet, impossible to download")
+    console.error('File is not defined yet, impossible to download')
     return
     return
   }
   }
 
 
   if (file.value.status === 'PENDING') {
   if (file.value.status === 'PENDING') {
-    console.error("File is still pending, impossible to download")
+    console.error('File is still pending, impossible to download')
     return
     return
   }
   }
 
 

+ 0 - 11
pages/index.vue

@@ -1,11 +0,0 @@
-<template>
-  <main>
-    <nuxt-link to="/poc/1">Goto organizations</nuxt-link>
-  </main>
-</template>
-
-<script setup lang="ts">
-
-</script>
-
-

+ 18 - 26
pages/organization.vue → pages/organization.vue.off

@@ -8,9 +8,7 @@
         <template #block1>
         <template #block1>
           {{ organization.name }}
           {{ organization.name }}
         </template>
         </template>
-        <template #block2>
-          N°Siret : {{ organization.siretNumber }}
-        </template>
+        <template #block2> N°Siret : {{ organization.siretNumber }} </template>
         <template #block3>
         <template #block3>
           {{ organization.description }}
           {{ organization.description }}
         </template>
         </template>
@@ -19,29 +17,26 @@
       <!-- Rend le contenu de la page -->
       <!-- Rend le contenu de la page -->
       <NuxtPage />
       <NuxtPage />
     </LayoutContainer>
     </LayoutContainer>
-    <LayoutContainer v-else>
-      Pending : {{ emPending }}
-    </LayoutContainer>
+    <LayoutContainer v-else> Pending : {{ emPending }} </LayoutContainer>
   </div>
   </div>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-
-import {useEntityManager} from "~/composables/data/useEntityManager";
-import {useEntityFetch} from "~/composables/data/useEntityFetch";
-import {computed, ComputedRef, Ref} from "@vue/reactivity";
-import {useOrganizationProfileStore} from "~/stores/organizationProfile";
-import Organization from "~/models/Organization/Organization";
-import ContactPoint from "~/models/Core/ContactPoint";
-import BankAccount from "~/models/Core/BankAccount";
-import OrganizationAddressPostal from "~/models/Organization/OrganizationAddressPostal";
-import AddressPostal from "~/models/Core/AddressPostal";
-import Country from "~/models/Core/Country";
-import TypeOfPractice from "~/models/Organization/TypeOfPractice";
-import Network from "~/models/Network/Network";
-import NetworkOrganization from "~/models/Network/NetworkOrganization";
-import OrganizationArticle from "~/models/Organization/OrganizationArticle";
-import File from "~/models/Core/File";
+import { computed, ComputedRef } from 'vue'
+import { useEntityManager } from '~/composables/data/useEntityManager'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
+import Organization from '~/models/Organization/Organization'
+import ContactPoint from '~/models/Core/ContactPoint'
+import BankAccount from '~/models/Core/BankAccount'
+import OrganizationAddressPostal from '~/models/Organization/OrganizationAddressPostal'
+import AddressPostal from '~/models/Core/AddressPostal'
+import Country from '~/models/Core/Country'
+import TypeOfPractice from '~/models/Organization/TypeOfPractice'
+import Network from '~/models/Network/Network'
+import NetworkOrganization from '~/models/Network/NetworkOrganization'
+import OrganizationArticle from '~/models/Organization/OrganizationArticle'
+import File from '~/models/Core/File'
 
 
 const { em, pending: emPending } = useEntityManager()
 const { em, pending: emPending } = useEntityManager()
 
 
@@ -55,19 +50,16 @@ const { fetch } = useEntityFetch()
 const { pending } = fetch(Organization, id)
 const { pending } = fetch(Organization, id)
 
 
 // Get file from store
 // Get file from store
-const organization: ComputedRef<Organization> = computed( () => {
+const organization: ComputedRef<Organization> = computed(() => {
   return em.find(Organization, id)
   return em.find(Organization, id)
 })
 })
 
 
-
-
 // TODO: restaurer le middleware  (peut-être utiliser beforeMount?)
 // TODO: restaurer le middleware  (peut-être utiliser beforeMount?)
 // middleware({ $ability, redirect }) {
 // middleware({ $ability, redirect }) {
 //   if(!$ability.can('display', 'organization_page'))
 //   if(!$ability.can('display', 'organization_page'))
 //     return redirect('/error')
 //     return redirect('/error')
 // }
 // }
 
 
-
 onBeforeUnmount(() => {
 onBeforeUnmount(() => {
   console.log('flush store') // TODO: vérifier le bon fonctionnement
   console.log('flush store') // TODO: vérifier le bon fonctionnement
   em.flush(Organization)
   em.flush(Organization)

+ 0 - 548
pages/organization/index.vue

@@ -1,548 +0,0 @@
-<!--
-Contenu de la page pages/organization.vue
-Contient toutes les informations sur l'organization courante
--->
-<template>
-  <LayoutContainer>
-    <UiForm v-if="!pending" :model="models().Organization" :entity="organization">
-      <template #form.input="{model, entity: organization}">
-        <v-expansion-panels :value="panel" focusable accordion>
-          <!-- Description -->
-          <UiExpansionPanel id="description" icon="fa-info">
-            <v-container fluid class="container">
-              <v-row>
-                <v-col cols="12" sm="6">
-                  <UiInputText field="name" v-model="organization.name" :rules="rules.name" />
-                </v-col>
-
-                <v-col cols="12" sm="6">
-                  <UiInputText field="acronym" v-model="organization.acronym" />
-                </v-col>
-
-                <v-col v-if="organizationProfile.isInsideNetwork()" cols="12" sm="6">
-                  <UiInputText
-                      :label="organizationProfile.isCmf() ? 'identifierCmf' : 'identifierFfec'"
-                      field="identifier"
-                      v-model="organization.identifier"
-                  />
-                </v-col>
-
-                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">
-                  <UiInputText field="ffecApproval" v-model="organization.ffecApproval"/>
-                </v-col>
-
-                <v-col cols="12" sm="6">
-                  <UiInputText field="description" v-model="organization.description"/>
-                </v-col>
-
-                <v-col cols="12" sm="6">
-                  <div>
-                    <span>{{ $t('logo') }}</span>
-                    <UiHelp right>
-                      <p v-html="$t('logo_upload')"/>
-                    </UiHelp>
-                  </div>
-                  <UiImage
-                    :imageId="getIdFromUri(organization.logo)"
-                    :width="200"
-                    field="logo"
-                    :ownerId="id"
-                  ></UiImage>
-                </v-col>
-
-                <v-col v-if="!organizationProfile.isManagerProduct()" cols="12" sm="6">
-<!--                  <UiInputEnum field="principalType" v-model="organization.principalType" enum-type="organization_principal_type"/>-->
-                </v-col>
-
-<!--                <v-col v-if="!organizationProfile.isFfec() && !organizationProfile.isManagerProduct() && !organizationProfile.isArtist()" cols="12" sm="6">-->
-<!--                  <UiInputEnum field="schoolCategory" v-model="organization.schoolCategory" enum-type="organization_school_cat"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">-->
-<!--                  <UiInputEnum field="typeEstablishment" v-model="organization.typeEstablishment" enum-type="organization_type_establishment"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col v-if="organization.typeEstablishment === 'MULTIPLE'" cols="12" sm="6">-->
-<!--                  <UiInputEnum field="typeEstablishmentDetail" v-model="organization.typeEstablishmentDetail" enum-type="organization_type_establishment_detail" />-->
-<!--                </v-col>-->
-
-                <v-col cols="12" sm="6" v-if="organizationProfile.isCmf()">
-                  <div class="d-flex flex-row">
-<!--                    <UiInputAutocomplete-->
-<!--                      field="typeOfPractices"-->
-<!--                      :items="typeOfPractices"-->
-<!--                      :isLoading="typeOfPracticesFetchingState.pending"-->
-<!--                      :item-text="['name']"-->
-<!--                      :data="getIdsFromUris(organization.typeOfPractices)"-->
-<!--                      :translate="true"-->
-<!--                      :multiple="true"-->
-<!--                      group="category"-->
-<!--                      :rules="rules.typeOfPractice"-->
-<!--                      @update="updateRepository($event.map((id) => `/api/type_of_practices/${id}`), 'typeOfPractices')"-->
-<!--                      class="flex"-->
-<!--                    />-->
-                    <UiHelp>
-                      {{ $t('type_of_practices_autocomplete') }}
-                    </UiHelp>
-                  </div>
-                </v-col>
-
-                <!-- TODO: essayer de faire une condition plus explicite pour le v-if -->
-<!--                <v-col cols="12" sm="6" v-if="getIdsFromUris(organization.typeOfPractices).indexOf(37) >= 0">-->
-<!--                  <UiInputTextArea field="otherPractice" v-model="organization.otherPractice" />-->
-<!--                </v-col>-->
-              </v-row>
-            </v-container>
-          </UiExpansionPanel>
-
-          <!-- Adresses -->
-<!--          <UiExpansionPanel id="address_postal" icon="fa-globe-europe">-->
-<!--            <v-container fluid class="container">-->
-<!--              <v-row>-->
-<!--                <v-col cols="12" sm="12">-->
-<!--                  <UiCollection-->
-<!--                    :model="models().OrganizationAddressPostal"-->
-<!--                    :parent="entity"-->
-<!--                    loaderType="image"-->
-<!--                    newLink="/organization/address/new"-->
-<!--                  >-->
-<!--                    <template #list.item="{items}">-->
-<!--                      <v-container fluid>-->
-<!--                        <v-row dense>-->
-<!--                          <v-col-->
-<!--                            v-for="item in items"-->
-<!--                            :key="item.id"-->
-<!--                            cols="4"-->
-<!--                          >-->
-<!--                            <UiCard-->
-<!--                              :link="`/organization/address/${item.id}`"-->
-<!--                              :model="models().OrganizationAddressPostal"-->
-<!--                              :entity="item"-->
-<!--                            >-->
-<!--                              <template #card.title>-->
-<!--                                {{ $t(item.type) }}-->
-<!--                              </template>-->
-<!--                              <template #card.text>-->
-<!--                                {{ item.addressPostal.streetAddress }} <br>-->
-<!--                                <span v-if="item.addressPostal.streetAddressSecond">{{ item.addressPostal.streetAddressSecond }} <br></span>-->
-<!--                                <span v-if="item.addressPostal.streetAddressThird">{{ item.addressPostal.streetAddressThird }} <br></span>-->
-<!--                                {{ item.addressPostal.postalCode }} {{ item.addressPostal.addressCity }}<br>-->
-<!--                                <span v-if="item.addressPostal.addressCountry">-->
-<!--                                  <UiItemFromUri-->
-<!--                                    :model="models().Country"-->
-<!--                                    :query="repositories().countryRepository.query()"-->
-<!--                                    :uri="item.addressPostal.addressCountry"-->
-<!--                                  >-->
-<!--                                    <template #item.text="{item}">-->
-<!--                                      {{item.name}}-->
-<!--                                    </template>-->
-<!--                                  </UiItemFromUri>-->
-<!--                                </span>-->
-<!--                              </template>-->
-<!--                            </UiCard>-->
-<!--                          </v-col>-->
-<!--                        </v-row>-->
-<!--                      </v-container>-->
-<!--                    </template>-->
-<!--                  </UiCollection>-->
-<!--                </v-col>-->
-<!--              </v-row>-->
-<!--            </v-container>-->
-<!--          </UiExpansionPanel>-->
-
-<!--          &lt;!&ndash;  Point de Contact&ndash;&gt;-->
-<!--          <UiExpansionPanel id="contact_point" icon="fa-phone">-->
-<!--            <v-container class="container">-->
-<!--              <v-row>-->
-<!--                <v-col cols="12" sm="12">-->
-<!--                  <UiCollection-->
-<!--                    :model="models().ContactPoint"-->
-<!--                    :parent="entity"-->
-<!--                    loaderType="image"-->
-<!--                    newLink="/organization/contact_points/new"-->
-<!--                  >-->
-<!--                    <template #list.item="{items}">-->
-<!--                      <v-container fluid>-->
-<!--                        <v-row :dense="true">-->
-<!--                          <v-col-->
-<!--                            v-for="item in items"-->
-<!--                            :key="item.id"-->
-<!--                            cols="4"-->
-<!--                          >-->
-<!--                            <UiCard-->
-<!--                              :link="`/organization/contact_points/${item.id}`"-->
-<!--                              :model="models().ContactPoint"-->
-<!--                              :entity="item"-->
-<!--                            >-->
-<!--                              <template #card.title>-->
-<!--                                {{ $t(item.contactType) }}-->
-<!--                              </template>-->
-<!--                              <template #card.text>-->
-<!--                                <span v-if="item.email"><strong>{{ $t('email') }}</strong> : {{ item.email }} <br></span>-->
-<!--                                <span v-if="item.emailInvalid" class="danger&#45;&#45;text"><v-icon class="danger&#45;&#45;text">mdi-alert</v-icon> <strong>{{ $t('emailInvalid') }}</strong> : {{ item.emailInvalid }} <br></span>-->
-
-<!--                                <span v-if="item.telphone"><strong>{{ $t('telphone') }}</strong> : {{ formatPhoneNumber(item.telphone) }} <br></span>-->
-<!--                                <span v-if="item.telphoneInvalid" class="danger&#45;&#45;text"><v-icon class="danger&#45;&#45;text">mdi-alert</v-icon> <strong>{{ $t('telphoneInvalid') }}</strong> : {{ formatPhoneNumber(item.telphoneInvalid) }} <br></span>-->
-
-<!--                                <span v-if="item.mobilPhone"><strong>{{ $t('mobilPhone') }}</strong> : {{ formatPhoneNumber(item.mobilPhone) }} <br></span>-->
-<!--                                <span v-if="item.mobilPhoneInvalid" class="danger&#45;&#45;text"><v-icon class="danger&#45;&#45;text">mdi-alert</v-icon> <strong>{{ $t('mobilPhoneInvalid') }}</strong> : {{ formatPhoneNumber(item.mobilPhoneInvalid) }} </span>-->
-<!--                              </template>-->
-<!--                            </UiCard>-->
-<!--                          </v-col>-->
-<!--                        </v-row>-->
-<!--                      </v-container>-->
-<!--                    </template>-->
-<!--                  </UiCollection>-->
-<!--                </v-col>-->
-<!--              </v-row>-->
-<!--            </v-container>-->
-<!--          </UiExpansionPanel>-->
-
-<!--          &lt;!&ndash; Informations légales &ndash;&gt;-->
-<!--          <UiExpansionPanel id="legalInformation" icon="fa-gavel">-->
-<!--            <v-container fluid class="container">-->
-<!--              <v-row>-->
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText-->
-<!--                    field="siretNumber"-->
-<!--                    :data="entity['siretNumber']"-->
-<!--                    :error="siretError"-->
-<!--                    :error-message="siretErrorMessage"-->
-<!--                    :rules="rules.siretRule"-->
-<!--                    @update="checkSiretHook($event, 'siretNumber')"-->
-<!--                  />-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="apeNumber" :data="entity['apeNumber']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col v-if="entity['legalStatus'] === 'ASSOCIATION_LAW_1901'" cols="12" sm="6">-->
-<!--                  <UiInputText field="waldecNumber" :data="entity['waldecNumber']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputDatePicker field="creationDate" :data="entity['creationDate']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="prefectureName" :data="entity['prefectureName']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="prefectureNumber" :data="entity['prefectureNumber']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputDatePicker field="declarationDate" :data="entity['declarationDate']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="tvaNumber" :data="entity['tvaNumber']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputEnum field="legalStatus" :data="entity['legalStatus']" enum-type="organization_legal"/>-->
-<!--                </v-col>-->
-
-<!--              </v-row>-->
-<!--            </v-container>-->
-<!--          </UiExpansionPanel>-->
-
-<!--          &lt;!&ndash;  Agréments &ndash;&gt;-->
-<!--          <UiExpansionPanel id="agrements" icon="fa-certificate">-->
-<!--            <v-container class="container">-->
-<!--              <v-row>-->
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="youngApproval" :data="entity['youngApproval']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="trainingApproval" :data="entity['trainingApproval']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="otherApproval" :data="entity['otherApproval']"/>-->
-<!--                </v-col>-->
-<!--              </v-row>-->
-<!--            </v-container>-->
-<!--          </UiExpansionPanel>-->
-
-<!--          &lt;!&ndash; Salariés &ndash;&gt;-->
-<!--          <UiExpansionPanel id="salary" icon="fa-users">-->
-<!--            <v-container class="container">-->
-<!--              <v-row>-->
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="collectiveAgreement" :data="entity['collectiveAgreement']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputEnum field="opca" :data="entity['opca']" enum-type="organization_opca"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="icomNumber" :data="entity['icomNumber']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="urssafNumber" :data="entity['urssafNumber']"/>-->
-<!--                </v-col>-->
-<!--              </v-row>-->
-<!--            </v-container>-->
-<!--          </UiExpansionPanel>-->
-
-<!--          &lt;!&ndash; Réseaux &ndash;&gt;-->
-<!--          <UiExpansionPanel v-if="organizationProfile.isInsideNetwork()" id="network" icon="fa-share-alt">-->
-<!--            <v-container class="container">-->
-<!--              <v-row>-->
-<!--                <v-col cols="12" sm="12">-->
-<!--                  <UiCollection-->
-<!--                    :model="models().NetworkOrganization"-->
-<!--                    :parent="entity"-->
-<!--                    loaderType="text"-->
-<!--                  >-->
-<!--                    <template #list.item="{items}">-->
-<!--                      <div v-for="item in items" :key="item.id">-->
-<!--                        <span>{{ item.network.name }}</span> - <span>{{$t('first_subscription')}} : <UiTemplateDate :data="item.startDate" /></span>-->
-<!--                      </div>-->
-<!--                    </template>-->
-<!--                  </UiCollection>-->
-<!--                </v-col>-->
-<!--                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">-->
-<!--                  <UiInputText field="budget" :data="entity['budget']" type="number" />-->
-<!--                </v-col>-->
-
-<!--                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">-->
-<!--                  <UiInputCheckbox field="isPedagogicIsPrincipalActivity" :data="entity['isPedagogicIsPrincipalActivity']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">-->
-<!--                  <UiInputText field="pedagogicBudget" :data="entity['pedagogicBudget']" type="number"/>-->
-<!--                </v-col>-->
-<!--              </v-row>-->
-<!--            </v-container>-->
-<!--          </UiExpansionPanel>-->
-
-<!--          &lt;!&ndash; Communication &ndash;&gt;-->
-<!--          <UiExpansionPanel id="communication" icon="fa-rss">-->
-<!--            <v-container class="container">-->
-<!--              <v-row>-->
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="twitter" :data="entity['twitter']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="youtube" :data="entity['youtube']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="facebook" :data="entity['facebook']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputText field="instagram" :data="entity['instagram']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <UiInputCheckbox field="portailVisibility" :data="entity['portailVisibility']"/>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="6">-->
-<!--                  <div class="d-flex flex-column">-->
-<!--                    <UiHelp class="d-flex flex-row">-->
-<!--                      <span>{{ $t('image') }}</span>-->
-<!--                      <p v-html="$t('communication_image_upload')"/>-->
-<!--                    </UiHelp>-->
-<!--                    <UiImage-->
-<!--                      :id="getIdFromUri(entity['image'])"-->
-<!--                      :upload="true"-->
-<!--                      :width="200"-->
-<!--                      field="image"-->
-<!--                      :ownerId="id"-->
-
-<!--                    ></UiImage>-->
-<!--                  </div>-->
-<!--                </v-col>-->
-
-<!--                <v-col cols="12" sm="12">-->
-<!--                  <UiCollection-->
-<!--                    :model="models().OrganizationArticle"-->
-<!--                    :parent="entity"-->
-<!--                    loaderType="text"-->
-<!--                  >-->
-<!--                    <template #list.item="{items}">-->
-<!--                      <h4 class="neutral-strong&#45;&#45;text font-weight-regular">{{$t('organizationArticle')}}</h4>-->
-<!--                      <UiTemplateDataTable-->
-<!--                        :headers="[-->
-<!--                          { text: $t('title'), value: 'title' },-->
-<!--                          { text: $t('link'), value: 'link' },-->
-<!--                          { text: $t('date'), value: 'date' },-->
-<!--                        ]"-->
-<!--                        :items="items"-->
-<!--                      >-->
-<!--                        <template #item.date="{item}">-->
-<!--                          <UiTemplateDate :data="item.date" />-->
-<!--                        </template>-->
-<!--                      </UiTemplateDataTable>-->
-<!--                    </template>-->
-<!--                  </UiCollection>-->
-<!--                </v-col>-->
-
-<!--              </v-row>-->
-<!--            </v-container>-->
-<!--          </UiExpansionPanel>-->
-
-<!--          &lt;!&ndash; IBAN &ndash;&gt;-->
-<!--          <UiExpansionPanel id="bank_account" icon="fa-euro-sign">-->
-<!--            <v-container class="container">-->
-<!--              <v-row>-->
-<!--                <v-col cols="12" sm="12">-->
-<!--                  <UiCollection-->
-<!--                    :model="models().BankAccount"-->
-<!--                    :parent="entity"-->
-<!--                    loaderType="image"-->
-<!--                    newLink="/organization/bank_account/new"-->
-<!--                  >-->
-<!--                    <template #list.item="{items}">-->
-<!--                      <v-container fluid>-->
-<!--                        <v-row :dense="true">-->
-<!--                          <v-col-->
-<!--                            v-for="item in items"-->
-<!--                            :key="item.id"-->
-<!--                            cols="4"-->
-<!--                          >-->
-<!--                            <UiCard-->
-<!--                              :id="item.id"-->
-<!--                              :link="`/organization/bank_account/${item.id}`"-->
-<!--                              :model="models().BankAccount"-->
-<!--                            >-->
-<!--                              <template #card.text>-->
-<!--                                <span v-if="item.bankName"><strong>{{ $t('bankName') }}</strong> : {{ item.bankName }} <br></span>-->
-
-<!--                                <span v-if="item.bic"><strong>{{ $t('bic') }}</strong> : {{ item.bic }} <br></span>-->
-<!--                                <span v-if="item.bicInvalid" class="danger&#45;&#45;text"><v-icon class="danger&#45;&#45;text">mdi-alert</v-icon> <strong>{{ $t('bicInvalid') }}</strong> : {{ item.bicInvalid }} <br></span>-->
-
-<!--                                <span v-if="item.iban"><strong>{{ $t('iban') }}</strong> : {{ item.iban }} <br></span>-->
-<!--                                <span v-if="item.ibanInvalid" class="danger&#45;&#45;text"><v-icon class="danger&#45;&#45;text">mdi-alert</v-icon> <strong>{{ $t('ibanInvalid') }}</strong> : {{ item.ibanInvalid }} <br></span>-->
-
-<!--                              </template>-->
-<!--                            </UiCard>-->
-<!--                          </v-col>-->
-<!--                        </v-row>-->
-<!--                      </v-container>-->
-<!--                    </template>-->
-<!--                  </UiCollection>-->
-<!--                </v-col>-->
-<!--              </v-row>-->
-<!--            </v-container>-->
-<!--          </UiExpansionPanel>-->
-        </v-expansion-panels>
-      </template>
-    </UiForm>
-  </LayoutContainer>
-</template>
-
-<script setup lang="ts">
-
-import {useEntityFetch} from "~/composables/data/useEntityFetch";
-import TypeOfPractice from "~/models/Organization/TypeOfPractice";
-import {computed, reactive, ref} from "@vue/reactivity";
-import type {ComputedRef} from "@vue/reactivity";
-import {useExtensionPanel} from "~/composables/layout/useExtensionPanel";
-import {useRoute} from "#app";
-import { useValidation } from "~/composables/form/useValidation";
-import {useEntityManager} from "~/composables/data/useEntityManager";
-import UrlUtils from "~/services/utils/urlUtils";
-import Organization from "~/models/Organization/Organization";
-import {useI18nUtils} from "~/composables/utils/useI18nUtils";
-import ContactPoint from "~/models/Core/ContactPoint";
-import BankAccount from "~/models/Core/BankAccount";
-import OrganizationAddressPostal from "~/models/Organization/OrganizationAddressPostal";
-import Country from "~/models/Core/Country";
-import NetworkOrganization from "~/models/Network/NetworkOrganization";
-import OrganizationArticle from "~/models/Organization/OrganizationArticle";
-import {useI18n} from "vue-i18n";
-
-const id: number | null = useOrganizationProfileStore().id
-if (id === null) {
-  throw new Error('Missing organization id')
-}
-
-const organizationProfile = reactive($organizationProfile())
-
-const { em } = useEntityManager()
-const { fetch, fetchCollection } = useEntityFetch()
-const { pending } = fetch(Organization, id)
-
-const organization: ComputedRef<Organization> = computed(() => {
-  return em.find(Organization, id)
-})
-
-const { data: typeOfPractices, pending: typeOfPracticesPending } = fetchCollection(TypeOfPractice)
-
-const route = ref(useRoute())
-const { panel } = useExtensionPanel(route)
-
-const { siretError, siretErrorMessage, validateSiret } = useValidation().useValidateSiret()
-
-const validateSiretHook = async (siret: string, field: string, updateRepository: any) => {
-  await validateSiret(siret)
-  if (!siretError.value) {
-    em.save(Organization, organization.value)
-  }
-}
-
-const formatPhoneNumber = (number: string): string => {
-  return useI18nUtils().formatPhoneNumber(number)
-}
-
-// TODO: voir si l'extraction de cette id ne pourrait pas être faite en amont, au niveau des post-processors
-const getIdsFromUris = (uris: Array<string>) => {
-  const ids:Array<any> = []
-  for(const uri of uris){
-    ids.push(UrlUtils.extractIdFromUri(uri))
-  }
-  return ids
-}
-
-// TODO: voir si l'extraction de cette id ne pourrait pas être faite en amont, au niveau des post-processors
-const getIdFromUri = (uri: string) => UrlUtils.extractIdFromUri(uri)
-
-const models = () => {
-  return {
-    Organization,
-    ContactPoint,
-    BankAccount,
-    OrganizationAddressPostal,
-    Country,
-    NetworkOrganization,
-    OrganizationArticle
-  }
-}
-
-const i18n = useI18n()
-
-const rules = {
-  name: [
-    (nameValue: string) => !!nameValue || i18n.t('required'),
-    (nameValue: string) => (nameValue || '').length <= 128 || i18n.t('name_length_rule')
-  ],
-  siret: [
-    (siretValue: string) => /^([0-9]{9}|[0-9]{14})$/.test(siretValue) || i18n.t('siret_error')
-  ],
-  typeOfPractice: [
-    (typeOfPracticeValue: Array<number>) => {
-      if(!$organizationProfile().isManagerProduct())
-      return typeOfPracticeValue.length > 0 || i18n.t('required')
-      return true
-    }
-  ]
-}
-
-</script>
-
-<style scoped>
-  .v-icon.v-icon {
-    font-size: 14px;
-  }
-</style>

+ 580 - 0
pages/organization/index.vue.off

@@ -0,0 +1,580 @@
+<!--
+Contenu de la page pages/organization.vue
+Contient toutes les informations sur l'organization courante
+-->
+<template>
+  <LayoutContainer>
+    <UiForm
+      v-if="!pending"
+      :model="models().Organization"
+      :entity="organization"
+    >
+      <template #form.input="{ model, entity: organization }">
+        <v-expansion-panels :value="panel" focusable accordion>
+          <!-- Description -->
+          <UiExpansionPanel id="description" icon="fa-info">
+            <v-container fluid class="container">
+              <v-row>
+                <v-col cols="12" sm="6">
+                  <UiInputText
+                    v-model="organization.name"
+                    field="name"
+                    :rules="rules.name"
+                  />
+                </v-col>
+
+                <v-col cols="12" sm="6">
+                  <UiInputText v-model="organization.acronym" field="acronym" />
+                </v-col>
+
+                <v-col
+                  v-if="organizationProfile.isInsideNetwork()"
+                  cols="12"
+                  sm="6"
+                >
+                  <UiInputText
+                    v-model="organization.identifier"
+                    :label="
+                      organizationProfile.isCmf()
+                        ? 'identifierCmf'
+                        : 'identifierFfec'
+                    "
+                    field="identifier"
+                  />
+                </v-col>
+
+                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">
+                  <UiInputText
+                    v-model="organization.ffecApproval"
+                    field="ffecApproval"
+                  />
+                </v-col>
+
+                <v-col cols="12" sm="6">
+                  <UiInputText
+                    v-model="organization.description"
+                    field="description"
+                  />
+                </v-col>
+
+                <v-col cols="12" sm="6">
+                  <div>
+                    <span>{{ $t('logo') }}</span>
+                    <UiHelp right>
+                      <p v-html="$t('logo_upload')" />
+                    </UiHelp>
+                  </div>
+                  <UiImage
+                    :image-id="getIdFromUri(organization.logo)"
+                    :width="200"
+                    field="logo"
+                    :owner-id="id"
+                  ></UiImage>
+                </v-col>
+
+                <v-col
+                  v-if="!organizationProfile.isManagerProduct()"
+                  cols="12"
+                  sm="6"
+                >
+                  <!--                  <UiInputEnum field="principalType" v-model="organization.principalType" enum-type="organization_principal_type"/>-->
+                </v-col>
+
+                <!--                <v-col v-if="!organizationProfile.isFfec() && !organizationProfile.isManagerProduct() && !organizationProfile.isArtist()" cols="12" sm="6">-->
+                <!--                  <UiInputEnum field="schoolCategory" v-model="organization.schoolCategory" enum-type="organization_school_cat"/>-->
+                <!--                </v-col>-->
+
+                <!--                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">-->
+                <!--                  <UiInputEnum field="typeEstablishment" v-model="organization.typeEstablishment" enum-type="organization_type_establishment"/>-->
+                <!--                </v-col>-->
+
+                <!--                <v-col v-if="organization.typeEstablishment === 'MULTIPLE'" cols="12" sm="6">-->
+                <!--                  <UiInputEnum field="typeEstablishmentDetail" v-model="organization.typeEstablishmentDetail" enum-type="organization_type_establishment_detail" />-->
+                <!--                </v-col>-->
+
+                <v-col v-if="organizationProfile.isCmf()" cols="12" sm="6">
+                  <div class="d-flex flex-row">
+                    <!--                    <UiInputAutocomplete-->
+                    <!--                      field="typeOfPractices"-->
+                    <!--                      :items="typeOfPractices"-->
+                    <!--                      :isLoading="typeOfPracticesFetchingState.pending"-->
+                    <!--                      :item-text="['name']"-->
+                    <!--                      :data="getIdsFromUris(organization.typeOfPractices)"-->
+                    <!--                      :translate="true"-->
+                    <!--                      :multiple="true"-->
+                    <!--                      group="category"-->
+                    <!--                      :rules="rules.typeOfPractice"-->
+                    <!--                      @update="updateRepository($event.map((id) => `/api/type_of_practices/${id}`), 'typeOfPractices')"-->
+                    <!--                      class="flex"-->
+                    <!--                    />-->
+                    <UiHelp>
+                      {{ $t('type_of_practices_autocomplete') }}
+                    </UiHelp>
+                  </div>
+                </v-col>
+
+                <!-- TODO: essayer de faire une condition plus explicite pour le v-if -->
+                <!--                <v-col cols="12" sm="6" v-if="getIdsFromUris(organization.typeOfPractices).indexOf(37) >= 0">-->
+                <!--                  <UiInputTextArea field="otherPractice" v-model="organization.otherPractice" />-->
+                <!--                </v-col>-->
+              </v-row>
+            </v-container>
+          </UiExpansionPanel>
+
+          <!-- Adresses -->
+          <!--          <UiExpansionPanel id="address_postal" icon="fa-globe-europe">-->
+          <!--            <v-container fluid class="container">-->
+          <!--              <v-row>-->
+          <!--                <v-col cols="12" sm="12">-->
+          <!--                  <UiCollection-->
+          <!--                    :model="models().OrganizationAddressPostal"-->
+          <!--                    :parent="entity"-->
+          <!--                    loaderType="image"-->
+          <!--                    newLink="/organization/address/new"-->
+          <!--                  >-->
+          <!--                    <template #list.item="{items}">-->
+          <!--                      <v-container fluid>-->
+          <!--                        <v-row dense>-->
+          <!--                          <v-col-->
+          <!--                            v-for="item in items"-->
+          <!--                            :key="item.id"-->
+          <!--                            cols="4"-->
+          <!--                          >-->
+          <!--                            <UiCard-->
+          <!--                              :link="`/organization/address/${item.id}`"-->
+          <!--                              :model="models().OrganizationAddressPostal"-->
+          <!--                              :entity="item"-->
+          <!--                            >-->
+          <!--                              <template #card.title>-->
+          <!--                                {{ $t(item.type) }}-->
+          <!--                              </template>-->
+          <!--                              <template #card.text>-->
+          <!--                                {{ item.addressPostal.streetAddress }} <br>-->
+          <!--                                <span v-if="item.addressPostal.streetAddressSecond">{{ item.addressPostal.streetAddressSecond }} <br></span>-->
+          <!--                                <span v-if="item.addressPostal.streetAddressThird">{{ item.addressPostal.streetAddressThird }} <br></span>-->
+          <!--                                {{ item.addressPostal.postalCode }} {{ item.addressPostal.addressCity }}<br>-->
+          <!--                                <span v-if="item.addressPostal.addressCountry">-->
+          <!--                                  <UiItemFromUri-->
+          <!--                                    :model="models().Country"-->
+          <!--                                    :query="repositories().countryRepository.query()"-->
+          <!--                                    :uri="item.addressPostal.addressCountry"-->
+          <!--                                  >-->
+          <!--                                    <template #item.text="{item}">-->
+          <!--                                      {{item.name}}-->
+          <!--                                    </template>-->
+          <!--                                  </UiItemFromUri>-->
+          <!--                                </span>-->
+          <!--                              </template>-->
+          <!--                            </UiCard>-->
+          <!--                          </v-col>-->
+          <!--                        </v-row>-->
+          <!--                      </v-container>-->
+          <!--                    </template>-->
+          <!--                  </UiCollection>-->
+          <!--                </v-col>-->
+          <!--              </v-row>-->
+          <!--            </v-container>-->
+          <!--          </UiExpansionPanel>-->
+
+          <!--          &lt;!&ndash;  Point de Contact&ndash;&gt;-->
+          <!--          <UiExpansionPanel id="contact_point" icon="fa-phone">-->
+          <!--            <v-container class="container">-->
+          <!--              <v-row>-->
+          <!--                <v-col cols="12" sm="12">-->
+          <!--                  <UiCollection-->
+          <!--                    :model="models().ContactPoint"-->
+          <!--                    :parent="entity"-->
+          <!--                    loaderType="image"-->
+          <!--                    newLink="/organization/contact_points/new"-->
+          <!--                  >-->
+          <!--                    <template #list.item="{items}">-->
+          <!--                      <v-container fluid>-->
+          <!--                        <v-row :dense="true">-->
+          <!--                          <v-col-->
+          <!--                            v-for="item in items"-->
+          <!--                            :key="item.id"-->
+          <!--                            cols="4"-->
+          <!--                          >-->
+          <!--                            <UiCard-->
+          <!--                              :link="`/organization/contact_points/${item.id}`"-->
+          <!--                              :model="models().ContactPoint"-->
+          <!--                              :entity="item"-->
+          <!--                            >-->
+          <!--                              <template #card.title>-->
+          <!--                                {{ $t(item.contactType) }}-->
+          <!--                              </template>-->
+          <!--                              <template #card.text>-->
+          <!--                                <span v-if="item.email"><strong>{{ $t('email') }}</strong> : {{ item.email }} <br></span>-->
+          <!--                                <span v-if="item.emailInvalid" class="danger&#45;&#45;text"><v-icon class="danger&#45;&#45;text">mdi-alert</v-icon> <strong>{{ $t('emailInvalid') }}</strong> : {{ item.emailInvalid }} <br></span>-->
+
+          <!--                                <span v-if="item.telphone"><strong>{{ $t('telphone') }}</strong> : {{ formatPhoneNumber(item.telphone) }} <br></span>-->
+          <!--                                <span v-if="item.telphoneInvalid" class="danger&#45;&#45;text"><v-icon class="danger&#45;&#45;text">mdi-alert</v-icon> <strong>{{ $t('telphoneInvalid') }}</strong> : {{ formatPhoneNumber(item.telphoneInvalid) }} <br></span>-->
+
+          <!--                                <span v-if="item.mobilPhone"><strong>{{ $t('mobilPhone') }}</strong> : {{ formatPhoneNumber(item.mobilPhone) }} <br></span>-->
+          <!--                                <span v-if="item.mobilPhoneInvalid" class="danger&#45;&#45;text"><v-icon class="danger&#45;&#45;text">mdi-alert</v-icon> <strong>{{ $t('mobilPhoneInvalid') }}</strong> : {{ formatPhoneNumber(item.mobilPhoneInvalid) }} </span>-->
+          <!--                              </template>-->
+          <!--                            </UiCard>-->
+          <!--                          </v-col>-->
+          <!--                        </v-row>-->
+          <!--                      </v-container>-->
+          <!--                    </template>-->
+          <!--                  </UiCollection>-->
+          <!--                </v-col>-->
+          <!--              </v-row>-->
+          <!--            </v-container>-->
+          <!--          </UiExpansionPanel>-->
+
+          <!--          &lt;!&ndash; Informations légales &ndash;&gt;-->
+          <!--          <UiExpansionPanel id="legalInformation" icon="fa-gavel">-->
+          <!--            <v-container fluid class="container">-->
+          <!--              <v-row>-->
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText-->
+          <!--                    field="siretNumber"-->
+          <!--                    :data="entity['siretNumber']"-->
+          <!--                    :error="siretError"-->
+          <!--                    :error-message="siretErrorMessage"-->
+          <!--                    :rules="rules.siretRule"-->
+          <!--                    @update="checkSiretHook($event, 'siretNumber')"-->
+          <!--                  />-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="apeNumber" :data="entity['apeNumber']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col v-if="entity['legalStatus'] === 'ASSOCIATION_LAW_1901'" cols="12" sm="6">-->
+          <!--                  <UiInputText field="waldecNumber" :data="entity['waldecNumber']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputDatePicker field="creationDate" :data="entity['creationDate']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="prefectureName" :data="entity['prefectureName']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="prefectureNumber" :data="entity['prefectureNumber']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputDatePicker field="declarationDate" :data="entity['declarationDate']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="tvaNumber" :data="entity['tvaNumber']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputEnum field="legalStatus" :data="entity['legalStatus']" enum-type="organization_legal"/>-->
+          <!--                </v-col>-->
+
+          <!--              </v-row>-->
+          <!--            </v-container>-->
+          <!--          </UiExpansionPanel>-->
+
+          <!--          &lt;!&ndash;  Agréments &ndash;&gt;-->
+          <!--          <UiExpansionPanel id="agrements" icon="fa-certificate">-->
+          <!--            <v-container class="container">-->
+          <!--              <v-row>-->
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="youngApproval" :data="entity['youngApproval']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="trainingApproval" :data="entity['trainingApproval']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="otherApproval" :data="entity['otherApproval']"/>-->
+          <!--                </v-col>-->
+          <!--              </v-row>-->
+          <!--            </v-container>-->
+          <!--          </UiExpansionPanel>-->
+
+          <!--          &lt;!&ndash; Salariés &ndash;&gt;-->
+          <!--          <UiExpansionPanel id="salary" icon="fa-users">-->
+          <!--            <v-container class="container">-->
+          <!--              <v-row>-->
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="collectiveAgreement" :data="entity['collectiveAgreement']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputEnum field="opca" :data="entity['opca']" enum-type="organization_opca"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="icomNumber" :data="entity['icomNumber']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="urssafNumber" :data="entity['urssafNumber']"/>-->
+          <!--                </v-col>-->
+          <!--              </v-row>-->
+          <!--            </v-container>-->
+          <!--          </UiExpansionPanel>-->
+
+          <!--          &lt;!&ndash; Réseaux &ndash;&gt;-->
+          <!--          <UiExpansionPanel v-if="organizationProfile.isInsideNetwork()" id="network" icon="fa-share-alt">-->
+          <!--            <v-container class="container">-->
+          <!--              <v-row>-->
+          <!--                <v-col cols="12" sm="12">-->
+          <!--                  <UiCollection-->
+          <!--                    :model="models().NetworkOrganization"-->
+          <!--                    :parent="entity"-->
+          <!--                    loaderType="text"-->
+          <!--                  >-->
+          <!--                    <template #list.item="{items}">-->
+          <!--                      <div v-for="item in items" :key="item.id">-->
+          <!--                        <span>{{ item.network.name }}</span> - <span>{{$t('first_subscription')}} : <UiTemplateDate :data="item.startDate" /></span>-->
+          <!--                      </div>-->
+          <!--                    </template>-->
+          <!--                  </UiCollection>-->
+          <!--                </v-col>-->
+          <!--                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">-->
+          <!--                  <UiInputText field="budget" :data="entity['budget']" type="number" />-->
+          <!--                </v-col>-->
+
+          <!--                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">-->
+          <!--                  <UiInputCheckbox field="isPedagogicIsPrincipalActivity" :data="entity['isPedagogicIsPrincipalActivity']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">-->
+          <!--                  <UiInputText field="pedagogicBudget" :data="entity['pedagogicBudget']" type="number"/>-->
+          <!--                </v-col>-->
+          <!--              </v-row>-->
+          <!--            </v-container>-->
+          <!--          </UiExpansionPanel>-->
+
+          <!--          &lt;!&ndash; Communication &ndash;&gt;-->
+          <!--          <UiExpansionPanel id="communication" icon="fa-rss">-->
+          <!--            <v-container class="container">-->
+          <!--              <v-row>-->
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="twitter" :data="entity['twitter']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="youtube" :data="entity['youtube']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="facebook" :data="entity['facebook']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputText field="instagram" :data="entity['instagram']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <UiInputCheckbox field="portailVisibility" :data="entity['portailVisibility']"/>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="6">-->
+          <!--                  <div class="d-flex flex-column">-->
+          <!--                    <UiHelp class="d-flex flex-row">-->
+          <!--                      <span>{{ $t('image') }}</span>-->
+          <!--                      <p v-html="$t('communication_image_upload')"/>-->
+          <!--                    </UiHelp>-->
+          <!--                    <UiImage-->
+          <!--                      :id="getIdFromUri(entity['image'])"-->
+          <!--                      :upload="true"-->
+          <!--                      :width="200"-->
+          <!--                      field="image"-->
+          <!--                      :ownerId="id"-->
+
+          <!--                    ></UiImage>-->
+          <!--                  </div>-->
+          <!--                </v-col>-->
+
+          <!--                <v-col cols="12" sm="12">-->
+          <!--                  <UiCollection-->
+          <!--                    :model="models().OrganizationArticle"-->
+          <!--                    :parent="entity"-->
+          <!--                    loaderType="text"-->
+          <!--                  >-->
+          <!--                    <template #list.item="{items}">-->
+          <!--                      <h4 class="neutral-strong&#45;&#45;text font-weight-regular">{{$t('organizationArticle')}}</h4>-->
+          <!--                      <UiTemplateDataTable-->
+          <!--                        :headers="[-->
+          <!--                          { text: $t('title'), value: 'title' },-->
+          <!--                          { text: $t('link'), value: 'link' },-->
+          <!--                          { text: $t('date'), value: 'date' },-->
+          <!--                        ]"-->
+          <!--                        :items="items"-->
+          <!--                      >-->
+          <!--                        <template #item.date="{item}">-->
+          <!--                          <UiTemplateDate :data="item.date" />-->
+          <!--                        </template>-->
+          <!--                      </UiTemplateDataTable>-->
+          <!--                    </template>-->
+          <!--                  </UiCollection>-->
+          <!--                </v-col>-->
+
+          <!--              </v-row>-->
+          <!--            </v-container>-->
+          <!--          </UiExpansionPanel>-->
+
+          <!--          &lt;!&ndash; IBAN &ndash;&gt;-->
+          <!--          <UiExpansionPanel id="bank_account" icon="fa-euro-sign">-->
+          <!--            <v-container class="container">-->
+          <!--              <v-row>-->
+          <!--                <v-col cols="12" sm="12">-->
+          <!--                  <UiCollection-->
+          <!--                    :model="models().BankAccount"-->
+          <!--                    :parent="entity"-->
+          <!--                    loaderType="image"-->
+          <!--                    newLink="/organization/bank_account/new"-->
+          <!--                  >-->
+          <!--                    <template #list.item="{items}">-->
+          <!--                      <v-container fluid>-->
+          <!--                        <v-row :dense="true">-->
+          <!--                          <v-col-->
+          <!--                            v-for="item in items"-->
+          <!--                            :key="item.id"-->
+          <!--                            cols="4"-->
+          <!--                          >-->
+          <!--                            <UiCard-->
+          <!--                              :id="item.id"-->
+          <!--                              :link="`/organization/bank_account/${item.id}`"-->
+          <!--                              :model="models().BankAccount"-->
+          <!--                            >-->
+          <!--                              <template #card.text>-->
+          <!--                                <span v-if="item.bankName"><strong>{{ $t('bankName') }}</strong> : {{ item.bankName }} <br></span>-->
+
+          <!--                                <span v-if="item.bic"><strong>{{ $t('bic') }}</strong> : {{ item.bic }} <br></span>-->
+          <!--                                <span v-if="item.bicInvalid" class="danger&#45;&#45;text"><v-icon class="danger&#45;&#45;text">mdi-alert</v-icon> <strong>{{ $t('bicInvalid') }}</strong> : {{ item.bicInvalid }} <br></span>-->
+
+          <!--                                <span v-if="item.iban"><strong>{{ $t('iban') }}</strong> : {{ item.iban }} <br></span>-->
+          <!--                                <span v-if="item.ibanInvalid" class="danger&#45;&#45;text"><v-icon class="danger&#45;&#45;text">mdi-alert</v-icon> <strong>{{ $t('ibanInvalid') }}</strong> : {{ item.ibanInvalid }} <br></span>-->
+
+          <!--                              </template>-->
+          <!--                            </UiCard>-->
+          <!--                          </v-col>-->
+          <!--                        </v-row>-->
+          <!--                      </v-container>-->
+          <!--                    </template>-->
+          <!--                  </UiCollection>-->
+          <!--                </v-col>-->
+          <!--              </v-row>-->
+          <!--            </v-container>-->
+          <!--          </UiExpansionPanel>-->
+        </v-expansion-panels>
+      </template>
+    </UiForm>
+  </LayoutContainer>
+</template>
+
+<script setup lang="ts">
+import { computed, reactive, ref } from 'vue'
+import type { ComputedRef } from 'vue'
+import { useRoute } from '#app'
+import { useI18n } from 'vue-i18n'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import TypeOfPractice from '~/models/Organization/TypeOfPractice'
+import { useExtensionPanel } from '~/composables/layout/useExtensionPanel'
+import { useValidation } from '~/composables/form/useValidation'
+import { useEntityManager } from '~/composables/data/useEntityManager'
+import UrlUtils from '~/services/utils/urlUtils'
+import Organization from '~/models/Organization/Organization'
+import { useI18nUtils } from '~/composables/utils/useI18nUtils'
+import ContactPoint from '~/models/Core/ContactPoint'
+import BankAccount from '~/models/Core/BankAccount'
+import OrganizationAddressPostal from '~/models/Organization/OrganizationAddressPostal'
+import Country from '~/models/Core/Country'
+import NetworkOrganization from '~/models/Network/NetworkOrganization'
+import OrganizationArticle from '~/models/Organization/OrganizationArticle'
+
+const id: number | null = useOrganizationProfileStore().id
+if (id === null) {
+  throw new Error('Missing organization id')
+}
+
+const organizationProfile = reactive($organizationProfile())
+
+const { em } = useEntityManager()
+const { fetch, fetchCollection } = useEntityFetch()
+const { pending } = fetch(Organization, id)
+
+const organization: ComputedRef<Organization> = computed(() => {
+  return em.find(Organization, id)
+})
+
+const { data: typeOfPractices, pending: typeOfPracticesPending } =
+  fetchCollection(TypeOfPractice)
+
+const route = ref(useRoute())
+const { panel } = useExtensionPanel(route)
+
+const { siretError, siretErrorMessage, validateSiret } =
+  useValidation().useValidateSiret()
+
+const validateSiretHook = async (
+  siret: string,
+  field: string,
+  updateRepository: any,
+) => {
+  await validateSiret(siret)
+  if (!siretError.value) {
+    em.save(Organization, organization.value)
+  }
+}
+
+const formatPhoneNumber = (number: string): string => {
+  return useI18nUtils().formatPhoneNumber(number)
+}
+
+// TODO: voir si l'extraction de cette id ne pourrait pas être faite en amont, au niveau des post-processors
+const getIdsFromUris = (uris: Array<string>) => {
+  const ids: Array<any> = []
+  for (const uri of uris) {
+    ids.push(UrlUtils.extractIdFromUri(uri))
+  }
+  return ids
+}
+
+// TODO: voir si l'extraction de cette id ne pourrait pas être faite en amont, au niveau des post-processors
+const getIdFromUri = (uri: string) => UrlUtils.extractIdFromUri(uri)
+
+const models = () => {
+  return {
+    Organization,
+    ContactPoint,
+    BankAccount,
+    OrganizationAddressPostal,
+    Country,
+    NetworkOrganization,
+    OrganizationArticle,
+  }
+}
+
+const i18n = useI18n()
+
+const rules = {
+  name: [
+    (nameValue: string) => !!nameValue || i18n.t('required'),
+    (nameValue: string) =>
+      (nameValue || '').length <= 128 || i18n.t('name_length_rule'),
+  ],
+  siret: [
+    (siretValue: string) =>
+      /^([0-9]{9}|[0-9]{14})$/.test(siretValue) || i18n.t('siret_error'),
+  ],
+  typeOfPractice: [
+    (typeOfPracticeValue: Array<number>) => {
+      if (!$organizationProfile().isManagerProduct())
+        return typeOfPracticeValue.length > 0 || i18n.t('required')
+      return true
+    },
+  ],
+}
+</script>
+
+<style scoped>
+.v-icon.v-icon {
+  font-size: 14px;
+}
+</style>

+ 8 - 9
pages/parameters.vue

@@ -8,14 +8,13 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-  /**
-   * Disable the default layout, the page will use the layout defined with <NuxtLayout />
-   * @see https://nuxt.com/docs/guide/directory-structure/layouts#overriding-a-layout-on-a-per-page-basis
-   */
-  definePageMeta({
-    layout: false,
-  });
+/**
+ * Disable the default layout, the page will use the layout defined with <NuxtLayout />
+ * @see https://nuxt.com/docs/guide/directory-structure/layouts#overriding-a-layout-on-a-per-page-basis
+ */
+definePageMeta({
+  layout: false,
+})
 </script>
 </script>
 
 
-<style scoped lang="scss">
-</style>
+<style scoped lang="scss"></style>

+ 3 - 3
pages/parameters/attendance_booking_reasons/[id].vue

@@ -6,10 +6,10 @@
         :model="AttendanceBookingReason"
         :model="AttendanceBookingReason"
         go-back-route="/parameters/attendances"
         go-back-route="/parameters/attendances"
       >
       >
-        <template v-slot="{ entity }">
+        <template #default="{ entity }">
           <UiInputText
           <UiInputText
-            field="reason"
             v-model="entity.reason"
             v-model="entity.reason"
+            field="reason"
             :rules="rules()"
             :rules="rules()"
           />
           />
         </template>
         </template>
@@ -19,7 +19,7 @@
 </template>
 </template>
 <script setup lang="ts">
 <script setup lang="ts">
 import { useI18n } from 'vue-i18n'
 import { useI18n } from 'vue-i18n'
-import AttendanceBookingReason from "~/models/Booking/AttendanceBookingReason";
+import AttendanceBookingReason from '~/models/Booking/AttendanceBookingReason'
 
 
 const i18n = useI18n()
 const i18n = useI18n()
 
 

+ 4 - 4
pages/parameters/attendance_booking_reasons/new.vue

@@ -1,12 +1,12 @@
 <template>
 <template>
   <LayoutContainer>
   <LayoutContainer>
     <div>
     <div>
-      <h2>{{ $t("new_attendance_booking_reason")}}</h2>
+      <h2>{{ $t('new_attendance_booking_reason') }}</h2>
       <UiFormCreation
       <UiFormCreation
         :model="AttendanceBookingReason"
         :model="AttendanceBookingReason"
         go-back-route="/parameters/attendances"
         go-back-route="/parameters/attendances"
       >
       >
-        <template v-slot="{ entity }">
+        <template #default="{ entity }">
           <v-container :fluid="true" class="container">
           <v-container :fluid="true" class="container">
             <v-row>
             <v-row>
               <v-col cols="12" sm="6"> </v-col>
               <v-col cols="12" sm="6"> </v-col>
@@ -29,12 +29,12 @@
 
 
 <script setup lang="ts">
 <script setup lang="ts">
 import { useI18n } from 'vue-i18n'
 import { useI18n } from 'vue-i18n'
-import AttendanceBookingReason from "~/models/Booking/AttendanceBookingReason";
+import AttendanceBookingReason from '~/models/Booking/AttendanceBookingReason'
 
 
 const i18n = useI18n()
 const i18n = useI18n()
 
 
 const rules = () => [
 const rules = () => [
   (reason: string | null) =>
   (reason: string | null) =>
-      (reason !== null && reason.length > 0) || i18n.t('please_enter_a_value'),
+    (reason !== null && reason.length > 0) || i18n.t('please_enter_a_value'),
 ]
 ]
 </script>
 </script>

+ 47 - 40
pages/parameters/attendances.vue

@@ -2,10 +2,10 @@
   <LayoutContainer>
   <LayoutContainer>
     <UiLoadingPanel v-if="pending" />
     <UiLoadingPanel v-if="pending" />
     <UiForm
     <UiForm
-        v-else
-        :model="Parameters"
-        :entity="parameters"
-        action-position="bottom"
+      v-else-if="parameters !== null"
+      :model="Parameters"
+      :entity="parameters"
+      action-position="bottom"
     >
     >
       <v-row>
       <v-row>
         <v-col cols="12">
         <v-col cols="12">
@@ -28,48 +28,52 @@
       </v-row>
       </v-row>
     </UiForm>
     </UiForm>
 
 
-    <v-divider class="my-10"/>
+    <v-divider class="my-10" />
 
 
     <UiLoadingPanel v-if="attendanceBookingReasonsPending" />
     <UiLoadingPanel v-if="attendanceBookingReasonsPending" />
     <div v-else>
     <div v-else>
       <v-table>
       <v-table>
         <thead>
         <thead>
-        <tr>
-          <td>{{ $t('attendanceBookingReasons') }}</td>
-          <td></td>
-        </tr>
+          <tr>
+            <td>{{ $t('attendanceBookingReasons') }}</td>
+            <td></td>
+          </tr>
         </thead>
         </thead>
-        <tbody>
-        <tr v-if="attendanceBookingReasons.length > 0" v-for="reason in attendanceBookingReasons" :key="reason.id">
-          <td class="cycle-editable-cell">
-            {{ reason.reason }}
-          </td>
-          <td class="d-flex flex-row">
-            <v-btn
+        <tbody v-if="attendanceBookingReasons.length > 0">
+          <tr v-for="reason in attendanceBookingReasons" :key="reason.id">
+            <td class="cycle-editable-cell">
+              {{ reason.reason }}
+            </td>
+            <td class="d-flex flex-row">
+              <v-btn
                 :flat="true"
                 :flat="true"
                 icon="fa fa-pen"
                 icon="fa fa-pen"
                 class="cycle-edit-icon mr-3"
                 class="cycle-edit-icon mr-3"
                 @click="goToEditPage(reason.id as number)"
                 @click="goToEditPage(reason.id as number)"
-            />
-            <UiButtonDelete
+              />
+              <UiButtonDelete
                 :model="AttendanceBookingReason"
                 :model="AttendanceBookingReason"
                 :entity="reason"
                 :entity="reason"
                 :flat="true"
                 :flat="true"
                 class="cycle-edit-icon"
                 class="cycle-edit-icon"
-            />
-          </td>
-        </tr>
-        <tr v-else class="theme-neutral">
-          <td><i>{{ $t('nothing_to_show')}}</i></td>
-          <td></td>
-        </tr>
+              />
+            </td>
+          </tr>
+        </tbody>
+        <tbody v-else>
+          <tr class="theme-neutral">
+            <td>
+              <i>{{ $t('nothing_to_show') }}</i>
+            </td>
+            <td></td>
+          </tr>
         </tbody>
         </tbody>
       </v-table>
       </v-table>
       <v-btn
       <v-btn
-          :flat="true"
-          prepend-icon="fa fa-plus"
-          class="theme-primary mt-4"
-          @click="goToCreatePage"
+        :flat="true"
+        prepend-icon="fa fa-plus"
+        class="theme-primary mt-4"
+        @click="goToCreatePage"
       >
       >
         {{ $t('add') }}
         {{ $t('add') }}
       </v-btn>
       </v-btn>
@@ -77,16 +81,15 @@
   </LayoutContainer>
   </LayoutContainer>
 </template>
 </template>
 <script setup lang="ts">
 <script setup lang="ts">
+import type { AsyncData } from '#app'
+import { type Collection, useRepo } from 'pinia-orm'
+import type { ComputedRef } from 'vue'
 import Parameters from '~/models/Organization/Parameters'
 import Parameters from '~/models/Organization/Parameters'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 import { useOrganizationProfileStore } from '~/stores/organizationProfile'
-import type { AsyncData } from '#app'
-import {type Collection, useRepo} from "pinia-orm";
-import type {ComputedRef} from "vue";
-import UrlUtils from "~/services/utils/urlUtils";
-import AttendanceBookingReason from "~/models/Booking/AttendanceBookingReason";
-import AttendanceBookingReasonRepository from "~/stores/repositories/AttendanceBookingReasonRepository";
-
+import UrlUtils from '~/services/utils/urlUtils'
+import AttendanceBookingReason from '~/models/Booking/AttendanceBookingReason'
+import AttendanceBookingReasonRepository from '~/stores/repositories/AttendanceBookingReasonRepository'
 
 
 const { fetch } = useEntityFetch()
 const { fetch } = useEntityFetch()
 
 
@@ -98,12 +101,14 @@ if (organizationProfile.parametersId === null) {
 
 
 const { data: parameters, pending } = fetch(
 const { data: parameters, pending } = fetch(
   Parameters,
   Parameters,
-  organizationProfile.parametersId
-) as AsyncData<Parameters, Parameters | true>
+  organizationProfile.parametersId,
+) as AsyncData<Parameters | null, Error | null>
 
 
 const { fetchCollection } = useEntityFetch()
 const { fetchCollection } = useEntityFetch()
 
 
-const { pending: attendanceBookingReasonsPending } = fetchCollection(AttendanceBookingReason)
+const { pending: attendanceBookingReasonsPending } = fetchCollection(
+  AttendanceBookingReason,
+)
 
 
 const attendanceBookingReasonsRepo = useRepo(AttendanceBookingReasonRepository)
 const attendanceBookingReasonsRepo = useRepo(AttendanceBookingReasonRepository)
 
 
@@ -111,7 +116,9 @@ const attendanceBookingReasonsRepo = useRepo(AttendanceBookingReasonRepository)
  * On récupère les timings via le store
  * On récupère les timings via le store
  * (sans ça, les mises à jour SSE ne seront pas prises en compte)
  * (sans ça, les mises à jour SSE ne seront pas prises en compte)
  */
  */
-const attendanceBookingReasons: ComputedRef<Collection<AttendanceBookingReason>> = computed(() => {
+const attendanceBookingReasons: ComputedRef<
+  Collection<AttendanceBookingReason>
+> = computed(() => {
   return attendanceBookingReasonsRepo.getReasons()
   return attendanceBookingReasonsRepo.getReasons()
 })
 })
 
 

+ 39 - 40
pages/parameters/bulletin.vue

@@ -1,72 +1,71 @@
-
 <template>
 <template>
   <LayoutContainer>
   <LayoutContainer>
     <UiLoadingPanel v-if="pending" />
     <UiLoadingPanel v-if="pending" />
     <UiForm
     <UiForm
-        v-else
-        :model="Parameters"
-        :entity="parameters"
-        action-position="bottom"
+      v-else
+      :model="Parameters"
+      :entity="parameters"
+      action-position="bottom"
     >
     >
       <v-row>
       <v-row>
         <v-col cols="12">
         <v-col cols="12">
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.bulletinWithTeacher"
-              field="bulletinWithTeacher"
+            v-model="parameters.bulletinWithTeacher"
+            field="bulletinWithTeacher"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.bulletinSignatureDirector"
-              field="bulletinSignatureDirector"
+            v-model="parameters.bulletinSignatureDirector"
+            field="bulletinSignatureDirector"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.bulletinShowEducationWithoutEvaluation"
-              field="bulletinShowEducationWithoutEvaluation"
+            v-model="parameters.bulletinShowEducationWithoutEvaluation"
+            field="bulletinShowEducationWithoutEvaluation"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.bulletinShowAbsences"
-              field="bulletinShowAbsences"
+            v-model="parameters.bulletinShowAbsences"
+            field="bulletinShowAbsences"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.bulletinEditWithoutEvaluation"
-              field="bulletinEditWithoutEvaluation"
+            v-model="parameters.bulletinEditWithoutEvaluation"
+            field="bulletinEditWithoutEvaluation"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.bulletinPrintAddress"
-              field="bulletinPrintAddress"
+            v-model="parameters.bulletinPrintAddress"
+            field="bulletinPrintAddress"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.bulletinDisplayLevelAcquired"
-              field="bulletinDisplayLevelAcquired"
+            v-model="parameters.bulletinDisplayLevelAcquired"
+            field="bulletinDisplayLevelAcquired"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.bulletinViewTestResults"
-              field="bulletinViewTestResults"
+            v-model="parameters.bulletinViewTestResults"
+            field="bulletinViewTestResults"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.bulletinShowAverages"
-              field="bulletinShowAverages"
+            v-model="parameters.bulletinShowAverages"
+            field="bulletinShowAverages"
           />
           />
 
 
           <UiInputAutocompleteWithEnum
           <UiInputAutocompleteWithEnum
-              v-model="parameters.bulletinReceiver"
-              field="bulletinReceiver"
-              enum-name="organization_bulletin_send_to"
-              variant="underlined"
+            v-model="parameters.bulletinReceiver"
+            field="bulletinReceiver"
+            enum-name="organization_bulletin_send_to"
+            variant="underlined"
           />
           />
 
 
           <UiInputAutocompleteWithEnum
           <UiInputAutocompleteWithEnum
-              v-model="parameters.bulletinCriteriaSort"
-              field="bulletinCriteriaSort"
-              enum-name="organization_bulletin_criteria_sort"
-              variant="underlined"
+            v-model="parameters.bulletinCriteriaSort"
+            field="bulletinCriteriaSort"
+            enum-name="organization_bulletin_criteria_sort"
+            variant="underlined"
           />
           />
         </v-col>
         </v-col>
       </v-row>
       </v-row>
@@ -75,10 +74,10 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import Parameters from "~/models/Organization/Parameters";
-import {useEntityFetch} from "~/composables/data/useEntityFetch";
-import {useOrganizationProfileStore} from "~/stores/organizationProfile";
-import type {AsyncData} from "#app";
+import type { AsyncData } from '#app'
+import Parameters from '~/models/Organization/Parameters'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 
 
 const { fetch } = useEntityFetch()
 const { fetch } = useEntityFetch()
 
 
@@ -88,10 +87,10 @@ if (organizationProfile.parametersId === null) {
   throw new Error('Missing organization parameters id')
   throw new Error('Missing organization parameters id')
 }
 }
 
 
-const { data: parameters, pending } = fetch(Parameters, organizationProfile.parametersId) as AsyncData<Parameters, Parameters | true>
-
+const { data: parameters, pending } = fetch(
+  Parameters,
+  organizationProfile.parametersId,
+) as AsyncData<Parameters, Parameters | true>
 </script>
 </script>
 
 
-<style scoped lang="scss">
-
-</style>
+<style scoped lang="scss"></style>

+ 6 - 12
pages/parameters/cycles/[id].vue

@@ -2,16 +2,9 @@
   <LayoutContainer>
   <LayoutContainer>
     <div>
     <div>
       <h2>{{ $t('cycle') }}</h2>
       <h2>{{ $t('cycle') }}</h2>
-      <UiFormEdition
-          :model="Cycle"
-          go-back-route="/parameters/teaching"
-      >
-        <template v-slot="{ entity }">
-          <UiInputText
-              field="label"
-              v-model="entity.label"
-              :rules="rules()"
-          />
+      <UiFormEdition :model="Cycle" go-back-route="/parameters/teaching">
+        <template #default="{ entity }">
+          <UiInputText v-model="entity.label" field="label" :rules="rules()" />
         </template>
         </template>
       </UiFormEdition>
       </UiFormEdition>
     </div>
     </div>
@@ -19,11 +12,12 @@
 </template>
 </template>
 <script setup lang="ts">
 <script setup lang="ts">
 import { useI18n } from 'vue-i18n'
 import { useI18n } from 'vue-i18n'
-import Cycle from "~/models/Education/Cycle";
+import Cycle from '~/models/Education/Cycle'
 
 
 const i18n = useI18n()
 const i18n = useI18n()
 
 
 const rules = () => [
 const rules = () => [
-  (label: string | null) => (label !== null && label.length > 0) || i18n.t('please_enter_a_value'),
+  (label: string | null) =>
+    (label !== null && label.length > 0) || i18n.t('please_enter_a_value'),
 ]
 ]
 </script>
 </script>

+ 31 - 32
pages/parameters/education_notation.vue

@@ -2,44 +2,44 @@
   <LayoutContainer>
   <LayoutContainer>
     <UiLoadingPanel v-if="pending" />
     <UiLoadingPanel v-if="pending" />
     <UiForm
     <UiForm
-        v-else
-        :model="Parameters"
-        :entity="parameters"
-        action-position="bottom"
+      v-else
+      :model="Parameters"
+      :entity="parameters"
+      action-position="bottom"
     >
     >
       <v-row>
       <v-row>
         <v-col cols="12">
         <v-col cols="12">
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.periodValidation"
-              field="periodValidation"
-              label="define_validation_periods_for_teachers"
+            v-model="parameters.periodValidation"
+            field="periodValidation"
+            label="define_validation_periods_for_teachers"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.editCriteriaNotationByAdminOnly"
-              field="editCriteriaNotationByAdminOnly"
-              label="evaluation_criterium_edition_is_admin_only"
+            v-model="parameters.editCriteriaNotationByAdminOnly"
+            field="editCriteriaNotationByAdminOnly"
+            label="evaluation_criterium_edition_is_admin_only"
           />
           />
 
 
           <UiInputAutocompleteWithEnum
           <UiInputAutocompleteWithEnum
-              v-if="organizationProfile.hasModule('AdvancedEducationNotation')"
-              v-model="parameters.advancedEducationNotationType"
-              enum-name="advanced_education_notation"
-              field="advancedEducationNotationType"
-              variant="underlined"
+            v-if="organizationProfile.hasModule('AdvancedEducationNotation')"
+            v-model="parameters.advancedEducationNotationType"
+            enum-name="advanced_education_notation"
+            field="advancedEducationNotationType"
+            variant="underlined"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.requiredValidation"
-              field="requiredValidation"
-              label="mandatory_validation_for_evaluations"
+            v-model="parameters.requiredValidation"
+            field="requiredValidation"
+            label="mandatory_validation_for_evaluations"
           />
           />
 
 
           <UiInputAutocompleteWithEnum
           <UiInputAutocompleteWithEnum
-              v-model="parameters.educationPeriodicity"
-              enum-name="education_periodicity"
-              field="educationPeriodicity"
-              variant="underlined"
+            v-model="parameters.educationPeriodicity"
+            enum-name="education_periodicity"
+            field="educationPeriodicity"
+            variant="underlined"
           />
           />
 
 
           <UiInputNumber
           <UiInputNumber
@@ -59,12 +59,11 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import Parameters from "~/models/Organization/Parameters";
-import {useEntityFetch} from "~/composables/data/useEntityFetch";
-import {useOrganizationProfileStore} from "~/stores/organizationProfile";
-import type {AsyncData} from "#app";
+import type { AsyncData } from '#app'
+import Parameters from '~/models/Organization/Parameters'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 
 
-const i18n = useI18n()
 const { fetch } = useEntityFetch()
 const { fetch } = useEntityFetch()
 
 
 const organizationProfile = useOrganizationProfileStore()
 const organizationProfile = useOrganizationProfileStore()
@@ -73,10 +72,10 @@ if (organizationProfile.parametersId === null) {
   throw new Error('Missing organization parameters id')
   throw new Error('Missing organization parameters id')
 }
 }
 
 
-const { data: parameters, pending } = fetch(Parameters, organizationProfile.parametersId) as AsyncData<Parameters, Parameters | true>
-
+const { data: parameters, pending } = fetch(
+  Parameters,
+  organizationProfile.parametersId,
+) as AsyncData<Parameters | null, Error | null>
 </script>
 </script>
 
 
-<style scoped lang="scss">
-
-</style>
+<style scoped lang="scss"></style>

+ 3 - 4
pages/parameters/education_timings/[id].vue

@@ -6,10 +6,10 @@
         :model="EducationTiming"
         :model="EducationTiming"
         go-back-route="/parameters/education_timings"
         go-back-route="/parameters/education_timings"
       >
       >
-        <template v-slot="{ entity }">
+        <template #default="{ entity }">
           <UiInputNumber
           <UiInputNumber
-            field="educationTiming"
             v-model="entity.timing"
             v-model="entity.timing"
+            field="educationTiming"
             :rules="rules()"
             :rules="rules()"
           />
           />
         </template>
         </template>
@@ -18,9 +18,8 @@
   </LayoutContainer>
   </LayoutContainer>
 </template>
 </template>
 <script setup lang="ts">
 <script setup lang="ts">
-import EducationTiming from '~/models/Education/EducationTiming'
-import type {RouteLocationPathRaw} from 'vue-router'
 import { useI18n } from 'vue-i18n'
 import { useI18n } from 'vue-i18n'
+import EducationTiming from '~/models/Education/EducationTiming'
 
 
 const i18n = useI18n()
 const i18n = useI18n()
 
 

+ 24 - 21
pages/parameters/education_timings/index.vue

@@ -9,53 +9,56 @@
             <td></td>
             <td></td>
           </tr>
           </tr>
         </thead>
         </thead>
-        <tbody>
-          <tr v-if="educationTimings.length > 0" v-for="timing in educationTimings" :key="timing.id">
+        <tbody v-if="educationTimings.length > 0">
+          <tr v-for="timing in educationTimings" :key="timing.id">
             <td class="cycle-editable-cell">
             <td class="cycle-editable-cell">
               {{ timing.timing }}
               {{ timing.timing }}
             </td>
             </td>
             <td class="d-flex flex-row">
             <td class="d-flex flex-row">
               <v-btn
               <v-btn
-                  :flat="true"
-                  icon="fa fa-pen"
-                  class="cycle-edit-icon mr-3"
-                  @click="goToEditPage(timing.id as number)"
+                :flat="true"
+                icon="fa fa-pen"
+                class="cycle-edit-icon mr-3"
+                @click="goToEditPage(timing.id as number)"
               />
               />
               <UiButtonDelete
               <UiButtonDelete
-                  :model="EducationTiming"
-                  :entity="timing"
-                  :flat="true"
-                  class="cycle-edit-icon"
+                :model="EducationTiming"
+                :entity="timing"
+                :flat="true"
+                class="cycle-edit-icon"
               />
               />
             </td>
             </td>
           </tr>
           </tr>
-          <tr v-else class="theme-neutral">
-            <td><i>{{ $t('nothing_to_show')}}</i></td>
+        </tbody>
+        <tbody v-else>
+          <tr class="theme-neutral">
+            <td>
+              <i>{{ $t('nothing_to_show') }}</i>
+            </td>
             <td></td>
             <td></td>
           </tr>
           </tr>
         </tbody>
         </tbody>
       </v-table>
       </v-table>
       <v-btn
       <v-btn
-          :flat="true"
-          prepend-icon="fa fa-plus"
-          class="theme-primary mt-4"
-          @click="goToCreatePage"
+        :flat="true"
+        prepend-icon="fa fa-plus"
+        class="theme-primary mt-4"
+        @click="goToCreatePage"
       >
       >
         {{ $t('add') }}
         {{ $t('add') }}
       </v-btn>
       </v-btn>
     </div>
     </div>
   </LayoutContainer>
   </LayoutContainer>
-
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
+import { useRepo } from 'pinia-orm'
+import type { ComputedRef } from 'vue'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import EducationTiming from '~/models/Education/EducationTiming'
 import EducationTiming from '~/models/Education/EducationTiming'
-import { useRepo } from 'pinia-orm'
 import EducationTimingsRepository from '~/stores/repositories/EducationTimingsRepository'
 import EducationTimingsRepository from '~/stores/repositories/EducationTimingsRepository'
-import type {ComputedRef} from "vue";
-import {useOrganizationProfileStore} from "~/stores/organizationProfile";
-import UrlUtils from "~/services/utils/urlUtils";
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
+import UrlUtils from '~/services/utils/urlUtils'
 
 
 const organizationProfile = useOrganizationProfileStore()
 const organizationProfile = useOrganizationProfileStore()
 
 

+ 4 - 4
pages/parameters/education_timings/new.vue

@@ -1,12 +1,12 @@
 <template>
 <template>
   <LayoutContainer>
   <LayoutContainer>
     <div>
     <div>
-      <h2>{{ $t("new_education_timing")}}</h2>
+      <h2>{{ $t('new_education_timing') }}</h2>
       <UiFormCreation
       <UiFormCreation
         :model="EducationTiming"
         :model="EducationTiming"
         go-back-route="/parameters/education_timings"
         go-back-route="/parameters/education_timings"
       >
       >
-        <template v-slot="{ entity }">
+        <template #default="{ entity }">
           <v-container :fluid="true" class="container">
           <v-container :fluid="true" class="container">
             <v-row>
             <v-row>
               <v-col cols="12" sm="6"> </v-col>
               <v-col cols="12" sm="6"> </v-col>
@@ -28,13 +28,13 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import EducationTiming from '~/models/Education/EducationTiming'
 import { useI18n } from 'vue-i18n'
 import { useI18n } from 'vue-i18n'
+import EducationTiming from '~/models/Education/EducationTiming'
 
 
 const i18n = useI18n()
 const i18n = useI18n()
 
 
 const rules = () => [
 const rules = () => [
-  (timing: number | null ) =>
+  (timing: number | null) =>
     (timing !== null && timing > 0) || i18n.t('please_enter_a_value'),
     (timing !== null && timing > 0) || i18n.t('please_enter_a_value'),
 ]
 ]
 </script>
 </script>

+ 59 - 54
pages/parameters/general_parameters.vue

@@ -2,82 +2,85 @@
   <LayoutContainer>
   <LayoutContainer>
     <UiLoadingPanel v-if="pending" />
     <UiLoadingPanel v-if="pending" />
     <UiForm
     <UiForm
-        v-else
-        :model="Parameters"
-        :entity="parameters"
-        action-position="bottom"
+      v-else
+      :model="Parameters"
+      :entity="parameters"
+      action-position="bottom"
     >
     >
       <v-row>
       <v-row>
         <v-col cols="12">
         <v-col cols="12">
           <UiInputDatePicker
           <UiInputDatePicker
-              v-if="organizationProfile.isSchool"
-              v-model="parameters.financialDate"
-              field="financialDate"
-              label="start_date_of_financial_season"
-              position="left"
-              class="my-2"
+            v-if="organizationProfile.isSchool"
+            v-model="parameters.financialDate"
+            field="financialDate"
+            label="start_date_of_financial_season"
+            position="left"
+            class="my-2"
           />
           />
 
 
           <UiInputDatePicker
           <UiInputDatePicker
-              v-if="organizationProfile.isSchool"
-              v-model="parameters.startCourseDate"
-              field="startCourseDate"
-              label="start_date_of_courses"
-              position="left"
-              class="my-2"
+            v-if="organizationProfile.isSchool"
+            v-model="parameters.startCourseDate"
+            field="startCourseDate"
+            label="start_date_of_courses"
+            position="left"
+            class="my-2"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.showAdherentList"
-              field="showAdherentList"
-              label="show_adherents_list_and_their_coordinates"
+            v-model="parameters.showAdherentList"
+            field="showAdherentList"
+            label="show_adherents_list_and_their_coordinates"
           />
           />
 
 
           <UiInputAutocompleteWithEnum
           <UiInputAutocompleteWithEnum
-              v-model="parameters.timezone"
-              enum-name="timezone"
-              field="timezone"
-              variant="underlined"
+            v-model="parameters.timezone"
+            enum-name="timezone"
+            field="timezone"
+            variant="underlined"
           />
           />
 
 
           <UiInputDatePicker
           <UiInputDatePicker
-              v-if="organizationProfile.isSchool"
-              v-model="parameters.musicalDate"
-              field="musicalDate"
-              label="start_date_of_activity_season"
-              position="left"
-              class="my-2"
+            v-if="organizationProfile.isSchool"
+            v-model="parameters.musicalDate"
+            field="musicalDate"
+            label="start_date_of_activity_season"
+            position="left"
+            class="my-2"
           />
           />
 
 
           <UiInputDatePicker
           <UiInputDatePicker
-              v-if="organizationProfile.isSchool"
-              v-model="parameters.endCourseDate"
-              field="endCourseDate"
-              label="end_date_of_courses"
-              position="left"
-              class="my-2"
+            v-if="organizationProfile.isSchool"
+            v-model="parameters.endCourseDate"
+            field="endCourseDate"
+            label="end_date_of_courses"
+            position="left"
+            class="my-2"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-if="organizationProfile.isSchool && organizationProfile.isAssociation"
-              v-model="parameters.studentsAreAdherents"
-              field="studentsAreAdherents"
-              label="students_are_also_association_members"
+            v-if="
+              organizationProfile.isSchool && organizationProfile.isAssociation
+            "
+            v-model="parameters.studentsAreAdherents"
+            field="studentsAreAdherents"
+            label="students_are_also_association_members"
           />
           />
 
 
           <div
           <div
-              v-if="organizationProfile.isCMFCentralService"
-              class="d-flex flex-column"
+            v-if="organizationProfile.isCMFCentralService"
+            class="d-flex flex-column"
           >
           >
-            <span class="mb-1 v-label" style="font-size: 12px;">{{ $t('qrCode')}} </span>
+            <span class="mb-1 v-label" style="font-size: 12px"
+              >{{ $t('qrCode') }}
+            </span>
             <UiInputImage
             <UiInputImage
-                v-model="parameters.qrCode"
-                field="qrCode"
-                label="licenceQrCode"
-                :width="120"
+              v-model="parameters.qrCode"
+              field="qrCode"
+              label="licenceQrCode"
+              :width="120"
             />
             />
           </div>
           </div>
-
         </v-col>
         </v-col>
       </v-row>
       </v-row>
     </UiForm>
     </UiForm>
@@ -85,10 +88,10 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import Parameters from "~/models/Organization/Parameters";
-import {useEntityFetch} from "~/composables/data/useEntityFetch";
-import {useOrganizationProfileStore} from "~/stores/organizationProfile";
-import type {AsyncData} from "#app";
+import type { AsyncData } from '#app'
+import Parameters from '~/models/Organization/Parameters'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 
 
 const { fetch } = useEntityFetch()
 const { fetch } = useEntityFetch()
 
 
@@ -98,8 +101,10 @@ if (organizationProfile.parametersId === null) {
   throw new Error('Missing organization parameters id')
   throw new Error('Missing organization parameters id')
 }
 }
 
 
-const { data: parameters, pending } = fetch(Parameters, organizationProfile.parametersId) as AsyncData<Parameters, Parameters | true>
+const { data: parameters, pending } = fetch(
+  Parameters,
+  organizationProfile.parametersId,
+) as AsyncData<Parameters, Parameters | true>
 </script>
 </script>
 
 
-<style scoped lang="scss">
-</style>
+<style scoped lang="scss"></style>

+ 2 - 3
pages/parameters/index.vue

@@ -1,4 +1,5 @@
 <template>
 <template>
+  <span>{{ $t('redirecting') }}...</span>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
@@ -8,7 +9,5 @@
  * Voir aussi : pages/parameters.vue
  * Voir aussi : pages/parameters.vue
  * */
  * */
 const router = useRouter()
 const router = useRouter()
-router.push(
-    { path: `/parameters/general_parameters` }
-)
+router.push({ path: `/parameters/general_parameters` })
 </script>
 </script>

+ 36 - 35
pages/parameters/intranet.vue

@@ -2,47 +2,47 @@
   <LayoutContainer>
   <LayoutContainer>
     <UiLoadingPanel v-if="pending" />
     <UiLoadingPanel v-if="pending" />
     <UiForm
     <UiForm
-        v-else
-        :model="Parameters"
-        :entity="parameters"
-        action-position="bottom"
+      v-else
+      :model="Parameters"
+      :entity="parameters"
+      action-position="bottom"
     >
     >
       <v-row>
       <v-row>
         <v-col cols="12">
         <v-col cols="12">
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.generateAttendanceReport"
-              field="generateAttendanceReport"
-              label="allow_teachers_to_generate_attendance_reports"
+            v-model="parameters.generateAttendanceReport"
+            field="generateAttendanceReport"
+            label="allow_teachers_to_generate_attendance_reports"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.administrationCc"
-              field="administrationCc"
-              label="send_teachers_mail_reports_copy_to_administration"
+            v-model="parameters.administrationCc"
+            field="administrationCc"
+            label="send_teachers_mail_reports_copy_to_administration"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.allowMembersToChangeGivenNameAndName"
-              field="allowMembersToChangeGivenNameAndName"
-              label="allow_members_to_change_their_names_and_firstnames"
+            v-model="parameters.allowMembersToChangeGivenNameAndName"
+            field="allowMembersToChangeGivenNameAndName"
+            label="allow_members_to_change_their_names_and_firstnames"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.createCourse"
-              field="createCourse"
-              label="allow_teachers_to_create_courses"
+            v-model="parameters.createCourse"
+            field="createCourse"
+            label="allow_teachers_to_create_courses"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.consultTeacherListing"
-              field="consultTeacherListing"
-              label="allow_teachers_to_consult_colleagues_informations"
+            v-model="parameters.consultTeacherListing"
+            field="consultTeacherListing"
+            label="allow_teachers_to_consult_colleagues_informations"
           />
           />
 
 
           <UiInputCheckbox
           <UiInputCheckbox
-              v-model="parameters.showAdherentList"
-              field="showAdherentList"
-              label="allow_students_to_consult_their_pedagogical_followup"
+            v-model="parameters.showAdherentList"
+            field="showAdherentList"
+            label="allow_students_to_consult_their_pedagogical_followup"
           />
           />
         </v-col>
         </v-col>
       </v-row>
       </v-row>
@@ -51,22 +51,23 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-  import Parameters from "~/models/Organization/Parameters";
-  import {useEntityFetch} from "~/composables/data/useEntityFetch";
-  import {useOrganizationProfileStore} from "~/stores/organizationProfile";
-  import type {AsyncData} from "#app";
+import type { AsyncData } from '#app'
+import Parameters from '~/models/Organization/Parameters'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 
 
-  const { fetch } = useEntityFetch()
+const { fetch } = useEntityFetch()
 
 
-  const organizationProfile = useOrganizationProfileStore()
+const organizationProfile = useOrganizationProfileStore()
 
 
-  if (organizationProfile.parametersId === null) {
-    throw new Error('Missing organization parameters id')
-  }
+if (organizationProfile.parametersId === null) {
+  throw new Error('Missing organization parameters id')
+}
 
 
-  const { data: parameters, pending } = fetch(Parameters, organizationProfile.parametersId) as AsyncData<Parameters, Parameters | true>
+const { data: parameters, pending } = fetch(
+  Parameters,
+  organizationProfile.parametersId,
+) as AsyncData<Parameters, Parameters | true>
 </script>
 </script>
 
 
-<style scoped lang="scss">
-
-</style>
+<style scoped lang="scss"></style>

+ 4 - 4
pages/parameters/residence_areas/[id].vue

@@ -6,10 +6,11 @@
         :model="ResidenceArea"
         :model="ResidenceArea"
         go-back-route="/parameters/residence_areas"
         go-back-route="/parameters/residence_areas"
       >
       >
-        <template v-slot="{ entity }">
+        <template #default="{ entity }">
           <UiInputText
           <UiInputText
-            field="label"
+            v-if="entity !== null"
             v-model="entity.label"
             v-model="entity.label"
+            field="label"
             :rules="rules()"
             :rules="rules()"
           />
           />
         </template>
         </template>
@@ -19,9 +20,8 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import { useEntityFetch } from '~/composables/data/useEntityFetch'
-import ResidenceArea from '~/models/Billing/ResidenceArea'
 import { useI18n } from 'vue-i18n'
 import { useI18n } from 'vue-i18n'
+import ResidenceArea from '~/models/Billing/ResidenceArea'
 
 
 const i18n = useI18n()
 const i18n = useI18n()
 
 

+ 28 - 28
pages/parameters/residence_areas/index.vue

@@ -9,42 +9,42 @@
             <td></td>
             <td></td>
           </tr>
           </tr>
         </thead>
         </thead>
-        <tbody>
-        <tr
-            v-if="residenceAreas.length > 0"
-            v-for="residenceArea in residenceAreas"
-            :key="residenceArea.id"
-        >
-          <td class="cycle-editable-cell">
-            {{ residenceArea.label }}
-          </td>
-          <td class="d-flex flex-row">
-            <v-btn
+        <tbody v-if="residenceAreas.length > 0">
+          <tr v-for="residenceArea in residenceAreas" :key="residenceArea.id">
+            <td class="cycle-editable-cell">
+              {{ residenceArea.label }}
+            </td>
+            <td class="d-flex flex-row">
+              <v-btn
                 :flat="true"
                 :flat="true"
                 icon="fa fa-pen"
                 icon="fa fa-pen"
                 class="cycle-edit-icon mr-3"
                 class="cycle-edit-icon mr-3"
                 @click="goToEditPage(residenceArea.id as number)"
                 @click="goToEditPage(residenceArea.id as number)"
-            />
-            <UiButtonDelete
+              />
+              <UiButtonDelete
                 :model="ResidenceArea"
                 :model="ResidenceArea"
                 :entity="residenceArea"
                 :entity="residenceArea"
                 :flat="true"
                 :flat="true"
                 class="cycle-edit-icon"
                 class="cycle-edit-icon"
-            />
-          </td>
-        </tr>
-        <tr v-else class="theme-neutral">
-          <td><i>{{ $t('nothing_to_show')}}</i></td>
-          <td></td>
-        </tr>
+              />
+            </td>
+          </tr>
+        </tbody>
+        <tbody v-else>
+          <tr class="theme-neutral">
+            <td>
+              <i>{{ $t('nothing_to_show') }}</i>
+            </td>
+            <td></td>
+          </tr>
         </tbody>
         </tbody>
       </v-table>
       </v-table>
 
 
       <v-btn
       <v-btn
-          :flat="true"
-          prepend-icon="fa fa-plus"
-          class="theme-primary mt-4"
-          @click="goToCreatePage"
+        :flat="true"
+        prepend-icon="fa fa-plus"
+        class="theme-primary mt-4"
+        @click="goToCreatePage"
       >
       >
         {{ $t('add') }}
         {{ $t('add') }}
       </v-btn>
       </v-btn>
@@ -53,12 +53,12 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
+import { useRepo } from 'pinia-orm'
+import type { ComputedRef } from 'vue'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import ResidenceArea from '~/models/Billing/ResidenceArea'
 import ResidenceArea from '~/models/Billing/ResidenceArea'
-import { useRepo } from 'pinia-orm'
 import ResidenceAreasRepository from '~/stores/repositories/ResidenceAreasRepository'
 import ResidenceAreasRepository from '~/stores/repositories/ResidenceAreasRepository'
-import { useRouter } from 'vue-router'
-import UrlUtils from "~/services/utils/urlUtils";
+import UrlUtils from '~/services/utils/urlUtils'
 
 
 const residenceAreasRepo = useRepo(ResidenceAreasRepository)
 const residenceAreasRepo = useRepo(ResidenceAreasRepository)
 
 
@@ -70,7 +70,7 @@ const { pending } = fetchCollection(ResidenceArea)
  * On récupère les Residence Area via le store
  * On récupère les Residence Area via le store
  * (sans ça, les mises à jour SSE ne seront pas prises en compte)
  * (sans ça, les mises à jour SSE ne seront pas prises en compte)
  */
  */
- const residenceAreas: ComputedRef<Array<ResidenceArea>> = computed(() => {
+const residenceAreas: ComputedRef<Array<ResidenceArea>> = computed(() => {
   return residenceAreasRepo.getResidenceAreas()
   return residenceAreasRepo.getResidenceAreas()
 })
 })
 
 

+ 2 - 2
pages/parameters/residence_areas/new.vue

@@ -6,7 +6,7 @@
         :model="ResidenceArea"
         :model="ResidenceArea"
         go-back-route="/parameters/residence_areas"
         go-back-route="/parameters/residence_areas"
       >
       >
-        <template v-slot="{ entity }">
+        <template #default="{ entity }">
           <v-container :fluid="true" class="container">
           <v-container :fluid="true" class="container">
             <v-row>
             <v-row>
               <v-col cols="12" sm="6">
               <v-col cols="12" sm="6">
@@ -26,8 +26,8 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import ResidenceArea from '~/models/Billing/ResidenceArea'
 import { useI18n } from 'vue-i18n'
 import { useI18n } from 'vue-i18n'
+import ResidenceArea from '~/models/Billing/ResidenceArea'
 
 
 const i18n = useI18n()
 const i18n = useI18n()
 
 

+ 15 - 16
pages/parameters/sms.vue

@@ -1,16 +1,17 @@
 <template>
 <template>
   <div>
   <div>
     <UiForm
     <UiForm
-        :model="Parameters"
-        :entity="parameters"
-        action-position="bottom"
+      v-if="parameters"
+      :model="Parameters"
+      :entity="parameters"
+      action-position="bottom"
     >
     >
       <v-row>
       <v-row>
         <v-col cols="12">
         <v-col cols="12">
           <UiInputText
           <UiInputText
-              v-model="parameters.smsSenderName"
-              field="smsSenderName"
-              variant="underlined"
+            v-model="parameters.smsSenderName"
+            field="smsSenderName"
+            variant="underlined"
           />
           />
         </v-col>
         </v-col>
         <v-col cols="12">
         <v-col cols="12">
@@ -23,10 +24,10 @@
         </v-col>
         </v-col>
         <v-col cols="12">
         <v-col cols="12">
           <UiInputText
           <UiInputText
-              v-model="parameters.passwordSMS"
-              field="passwordSMS"
-              class="password"
-              variant="underlined"
+            v-model="parameters.passwordSMS"
+            field="passwordSMS"
+            class="password"
+            variant="underlined"
           />
           />
         </v-col>
         </v-col>
       </v-row>
       </v-row>
@@ -34,10 +35,10 @@
   </div>
   </div>
 </template>
 </template>
 <script setup lang="ts">
 <script setup lang="ts">
+import type { AsyncData } from '#app'
 import Parameters from '~/models/Organization/Parameters'
 import Parameters from '~/models/Organization/Parameters'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 import { useOrganizationProfileStore } from '~/stores/organizationProfile'
-import type { AsyncData } from '#app'
 
 
 const { fetch } = useEntityFetch()
 const { fetch } = useEntityFetch()
 
 
@@ -47,14 +48,13 @@ if (organizationProfile.parametersId === null) {
   throw new Error('Missing organization parameters id')
   throw new Error('Missing organization parameters id')
 }
 }
 
 
-const { data: parameters, pending } = fetch(
+const { data: parameters } = fetch(
   Parameters,
   Parameters,
-  organizationProfile.parametersId
-) as AsyncData<Parameters, Parameters | true>
+  organizationProfile.parametersId,
+) as AsyncData<Parameters | null, Error | null>
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
-
 /**
 /**
 Simule une apparence de saisie de type mot de passe
 Simule une apparence de saisie de type mot de passe
 Sans ça, les navigateurs proposent la saisie semi auto et la mémorisation du mot de passe
 Sans ça, les navigateurs proposent la saisie semi auto et la mémorisation du mot de passe
@@ -69,5 +69,4 @@ Sans ça, les navigateurs proposent la saisie semi auto et la mémorisation du m
 :deep(.password input) {
 :deep(.password input) {
   font-family: 'password';
   font-family: 'password';
 }
 }
-
 </style>
 </style>

+ 38 - 43
pages/parameters/subdomains/[id].vue

@@ -3,10 +3,8 @@
   <main>
   <main>
     <LayoutContainer>
     <LayoutContainer>
       <UiLoadingPanel v-if="pending" />
       <UiLoadingPanel v-if="pending" />
-      <div v-else>
-        <div>
-          {{ $t('youRegisteredTheFollowingSubdomain')}} :
-        </div>
+      <div v-else-if="subdomain !== null">
+        <div>{{ $t('youRegisteredTheFollowingSubdomain') }} :</div>
 
 
         <div class="pa-8">
         <div class="pa-8">
           <b>{{ subdomain.subdomain }}</b>
           <b>{{ subdomain.subdomain }}</b>
@@ -20,9 +18,7 @@
             </v-icon>
             </v-icon>
             {{ $t('subdomainIsCurrentlyActive') }}
             {{ $t('subdomainIsCurrentlyActive') }}
           </div>
           </div>
-          <div v-else>
-            {{ $t('doYouWantToActivateThisSubdomain') }} ?
-          </div>
+          <div v-else>{{ $t('doYouWantToActivateThisSubdomain') }} ?</div>
         </div>
         </div>
 
 
         <div class="mt-6 d-flex flex-row">
         <div class="mt-6 d-flex flex-row">
@@ -30,7 +26,7 @@
             {{ $t('back') }}
             {{ $t('back') }}
           </v-btn>
           </v-btn>
           <div v-if="!subdomain.active">
           <div v-if="!subdomain.active">
-            <v-btn color="primary" @click="activateAndQuit" >
+            <v-btn color="primary" @click="activateAndQuit">
               {{ $t('activate') }}
               {{ $t('activate') }}
             </v-btn>
             </v-btn>
           </div>
           </div>
@@ -41,48 +37,47 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-  import Subdomain from "~/models/Organization/Subdomain";
-  import {useEntityFetch} from "~/composables/data/useEntityFetch";
-  import {useOrganizationProfileStore} from "~/stores/organizationProfile";
-  import {useEntityManager} from "~/composables/data/useEntityManager";
-  import {usePageStore} from "~/stores/page";
-  import {TYPE_ALERT} from "~/types/enum/enums";
-  import {useRefreshProfile} from "~/composables/data/useRefreshProfile";
-
-  const { em } = useEntityManager()
-  const { fetch } = useEntityFetch()
-  const organizationProfile = useOrganizationProfileStore()
-
-  const router = useRouter()
-  const route = useRoute()
+import type { Ref } from 'vue'
+import Subdomain from '~/models/Organization/Subdomain'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import { useEntityManager } from '~/composables/data/useEntityManager'
+import { usePageStore } from '~/stores/page'
+import { TYPE_ALERT } from '~/types/enum/enums'
+import { useRefreshProfile } from '~/composables/data/useRefreshProfile'
 
 
-  const { refreshProfile } = useRefreshProfile()
+const { em } = useEntityManager()
+const { fetch } = useEntityFetch()
 
 
-  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 router = useRouter()
+const route = useRoute()
 
 
-  const { data: subdomain, pending } = fetch(Subdomain, id)
+const { refreshProfile } = useRefreshProfile()
 
 
-  const activationPending: Ref<boolean> = ref(false)
+if (!route.params.id || /\d+/.test(route.params.id as string)) {
+  throw new Error('no id found')
+}
+const id: number = parseInt(route.params.id as string)
 
 
-  const pageStore = usePageStore()
+const { data: subdomain, pending } = fetch(Subdomain, id)
 
 
-  const activateAndQuit = async () => {
-    activationPending.value = true
-    pageStore.loading = true
-    await em.patch(Subdomain, id, { active: true} )
-    await refreshProfile()
-    usePageStore().addAlert(TYPE_ALERT.SUCCESS, ['subdomain_activated_and_available_in_a_few_minutes'])
-    quit()
-  }
+const activationPending: Ref<boolean> = ref(false)
 
 
-  const quit = () => {
-    router.push('/parameters/website')
-    activationPending.value = false
-    pageStore.loading = false
-  }
+const pageStore = usePageStore()
 
 
+const activateAndQuit = async () => {
+  activationPending.value = true
+  pageStore.loading = true
+  await em.patch(Subdomain, id, { active: true })
+  await refreshProfile()
+  usePageStore().addAlert(TYPE_ALERT.SUCCESS, [
+    'subdomain_activated_and_available_in_a_few_minutes',
+  ])
+  quit()
+}
 
 
+const quit = () => {
+  router.push('/parameters/website')
+  activationPending.value = false
+  pageStore.loading = false
+}
 </script>
 </script>

+ 12 - 12
pages/parameters/subdomains/new.vue

@@ -5,7 +5,7 @@
         ref="form"
         ref="form"
         :model="Subdomain"
         :model="Subdomain"
         :entity="subdomain"
         :entity="subdomain"
-        :submitActions="submitActions"
+        :submit-actions="submitActions"
         :validation-pending="validationPending"
         :validation-pending="validationPending"
         :refresh-profile="true"
         :refresh-profile="true"
       >
       >
@@ -22,7 +22,7 @@
                 field="subdomain"
                 field="subdomain"
                 type="string"
                 type="string"
                 :rules="rules()"
                 :rules="rules()"
-                @update:modelValue="onSubdomainUpdate"
+                @update:model-value="onSubdomainUpdate"
               />
               />
             </v-col>
             </v-col>
           </v-row>
           </v-row>
@@ -51,30 +51,31 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
+import type { Ref } from 'vue'
+import _ from 'lodash'
 import { useEntityManager } from '~/composables/data/useEntityManager'
 import { useEntityManager } from '~/composables/data/useEntityManager'
 import Subdomain from '~/models/Organization/Subdomain'
 import Subdomain from '~/models/Organization/Subdomain'
 import { SUBMIT_TYPE } from '~/types/enum/enums'
 import { SUBMIT_TYPE } from '~/types/enum/enums'
 import type { AnyJson } from '~/types/data'
 import type { AnyJson } from '~/types/data'
 import SubdomainValidation from '~/services/validation/subdomainValidation'
 import SubdomainValidation from '~/services/validation/subdomainValidation'
-import type { Ref } from '@vue/reactivity'
 import { useSubdomainValidation } from '~/composables/form/validation/useSubdomainValidation'
 import { useSubdomainValidation } from '~/composables/form/validation/useSubdomainValidation'
-import _ from 'lodash'
+import Form from '~/components/Ui/Form.vue'
 
 
 const i18n = useI18n()
 const i18n = useI18n()
 
 
 const { em } = useEntityManager()
 const { em } = useEntityManager()
 const { subdomainValidation } = useSubdomainValidation()
 const { subdomainValidation } = useSubdomainValidation()
 
 
-//@ts-ignore
-const subdomain: Ref<Subdomain> = ref(em.newInstance(Subdomain) as Subdomain)
+// @ts-expect-error TODO à résoudre quand l'EM pourra gérer les types génériques
+const subdomain: Ref<Subdomain> = ref(em.newInstance(Subdomain))
 
 
 const submitActions = computed(() => {
 const submitActions = computed(() => {
-  let actions: AnyJson = {}
+  const actions: AnyJson = {}
   actions[SUBMIT_TYPE.SAVE_AND_BACK] = '/parameters/website'
   actions[SUBMIT_TYPE.SAVE_AND_BACK] = '/parameters/website'
   return actions
   return actions
 })
 })
 
 
-const form: Ref<HTMLCanvasElement | null> = ref(null)
+const form: Ref<typeof Form | null> = ref(null)
 const subdomainAvailable: Ref<boolean | null> = ref(null)
 const subdomainAvailable: Ref<boolean | null> = ref(null)
 const validationPending: Ref<boolean> = ref(false)
 const validationPending: Ref<boolean> = ref(false)
 
 
@@ -91,8 +92,7 @@ const checkAvailability = async (subdomain: string) => {
   subdomainAvailable.value = await subdomainValidation.isAvailable(subdomain)
   subdomainAvailable.value = await subdomainValidation.isAvailable(subdomain)
   validationPending.value = false
   validationPending.value = false
 
 
-  //@ts-ignore
-  form.value.validate()
+  form.value!.validate()
 }
 }
 
 
 /**
 /**
@@ -106,7 +106,7 @@ const checkAvailabilityDebounced: _.DebouncedFunc<() => void> = _.debounce(
     }
     }
     await checkAvailability(subdomain.value.subdomain)
     await checkAvailability(subdomain.value.subdomain)
   },
   },
-  inputDelay
+  inputDelay,
 )
 )
 
 
 const onSubdomainUpdate = () => {
 const onSubdomainUpdate = () => {
@@ -128,7 +128,7 @@ const rules = () => [
   (subdomain: string | null) =>
   (subdomain: string | null) =>
     SubdomainValidation.isValid(subdomain) ||
     SubdomainValidation.isValid(subdomain) ||
     i18n.t('subdomain_can_not_contain_spaces_or_special_cars'),
     i18n.t('subdomain_can_not_contain_spaces_or_special_cars'),
-  async () =>
+  () =>
     subdomainAvailable.value !== false ||
     subdomainAvailable.value !== false ||
     i18n.t('this_subdomain_is_already_in_use'),
     i18n.t('this_subdomain_is_already_in_use'),
 ]
 ]

+ 35 - 35
pages/parameters/super_admin.vue

@@ -1,41 +1,41 @@
 <template>
 <template>
   <div>
   <div>
-      <div class="explanation">
-        <div class="px-6 d-flex flex-row align-center">
-          <v-icon class="theme-primary">fa fa-info</v-icon>
-        </div>
-        <div class="px-2">
-          {{ $t('super_admin_explanation_text')}}
-        </div>
+    <div class="explanation">
+      <div class="px-6 d-flex flex-row align-center">
+        <v-icon class="theme-primary">fa fa-info</v-icon>
       </div>
       </div>
+      <div class="px-2">
+        {{ $t('super_admin_explanation_text') }}
+      </div>
+    </div>
 
 
-      <UiLoadingPanel v-if="pending"/>
-      <UiForm
-          v-else-if="adminAccess"
-          ref="form"
-          :model="AdminAccess"
-          :entity="adminAccess"
-          class="w-100"
-          action-position="bottom"
-      >
-        <v-table class="mb-4">
-          <tbody>
-            <tr>
-              <td>{{ $t('username') }} : </td>
-              <td>{{ adminAccess.username }}</td>
-            </tr>
-          </tbody>
-        </v-table>
+    <UiLoadingPanel v-if="pending" />
+    <UiForm
+      v-else-if="adminAccess"
+      ref="form"
+      :model="AdminAccess"
+      :entity="adminAccess"
+      class="w-100"
+      action-position="bottom"
+    >
+      <v-table class="mb-4">
+        <tbody>
+          <tr>
+            <td>{{ $t('username') }} :</td>
+            <td>{{ adminAccess.username }}</td>
+          </tr>
+        </tbody>
+      </v-table>
 
 
-        <UiInputText
-            field="email"
-            v-model="adminAccess.email"
-            :rules="rules()"
-            class="mx-4"
-            variant="underlined"
-        />
-      </UiForm>
-      <span v-else>{{ $t('no_admin_access_recorded') }}</span>
+      <UiInputText
+        v-model="adminAccess.email"
+        field="email"
+        :rules="rules()"
+        class="mx-4"
+        variant="underlined"
+      />
+    </UiForm>
+    <span v-else>{{ $t('no_admin_access_recorded') }}</span>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -43,7 +43,7 @@
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useAccessProfileStore } from '~/stores/accessProfile'
 import { useAccessProfileStore } from '~/stores/accessProfile'
 import AdminAccess from '~/models/Access/AdminAccess'
 import AdminAccess from '~/models/Access/AdminAccess'
-import {useValidationUtils} from "~/composables/utils/useValidationUtils";
+import { useValidationUtils } from '~/composables/utils/useValidationUtils'
 
 
 const { fetch } = useEntityFetch()
 const { fetch } = useEntityFetch()
 
 
@@ -60,7 +60,7 @@ const validationUtils = useValidationUtils()
 
 
 const rules = () => [
 const rules = () => [
   (email: string | null) =>
   (email: string | null) =>
-    (email && validationUtils.validEmail(email)) || i18n.t('email_error')
+    (email && validationUtils.validEmail(email)) || i18n.t('email_error'),
 ]
 ]
 </script>
 </script>
 
 

+ 38 - 29
pages/parameters/teaching.vue

@@ -2,10 +2,10 @@
   <LayoutContainer>
   <LayoutContainer>
     <UiLoadingPanel v-if="pending" />
     <UiLoadingPanel v-if="pending" />
     <UiForm
     <UiForm
-        v-else
-        :model="Parameters"
-        :entity="parameters"
-        action-position="bottom"
+      v-else-if="parameters !== null"
+      :model="Parameters"
+      :entity="parameters"
+      action-position="bottom"
     >
     >
       <v-table>
       <v-table>
         <thead>
         <thead>
@@ -16,18 +16,22 @@
         </thead>
         </thead>
 
 
         <tbody>
         <tbody>
-          <tr v-for="enumItem in cycleEnum">
+          <tr v-for="enumItem in cycleEnum" :key="enumItem.value">
             <td>{{ $t(enumItem.value) }}</td>
             <td>{{ $t(enumItem.value) }}</td>
             <td class="cycle-editable-cell">
             <td class="cycle-editable-cell">
-              {{ orderedCycles[enumItem.value] ? orderedCycles[enumItem.value].label : $t(enumItem.value) }}
+              {{
+                orderedCycles[enumItem.value]
+                  ? orderedCycles[enumItem.value].label
+                  : $t(enumItem.value)
+              }}
             </td>
             </td>
-            <td style="max-width: 24px;">
+            <td style="max-width: 24px">
               <v-btn
               <v-btn
-                  v-if="orderedCycles[enumItem.value]"
-                  :flat="true"
-                  icon="fa fa-pen"
-                  class="cycle-edit-icon"
-                  @click="goToCycleEditPage(orderedCycles[enumItem.value].id)"
+                v-if="orderedCycles[enumItem.value]"
+                :flat="true"
+                icon="fa fa-pen"
+                class="cycle-edit-icon"
+                @click="goToCycleEditPage(orderedCycles[enumItem.value].id)"
               />
               />
             </td>
             </td>
           </tr>
           </tr>
@@ -35,22 +39,24 @@
       </v-table>
       </v-table>
 
 
       <UiInputCheckbox
       <UiInputCheckbox
-          v-model="parameters.showEducationIsACollectivePractice"
-          field="showEducationIsACollectivePractice"
-          label="allow_to_configure_teachings_with_played_instrument_choice"
+        v-model="parameters.showEducationIsACollectivePractice"
+        field="showEducationIsACollectivePractice"
+        label="allow_to_configure_teachings_with_played_instrument_choice"
       />
       />
     </UiForm>
     </UiForm>
   </LayoutContainer>
   </LayoutContainer>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import Parameters from "~/models/Organization/Parameters";
-import {useEntityFetch} from "~/composables/data/useEntityFetch";
-import Cycle from "~/models/Education/Cycle";
-import type {AsyncData} from "#app";
-import {useOrganizationProfileStore} from "~/stores/organizationProfile";
-import type {AnyJson} from "~/types/data";
-import {useEnumFetch} from "~/composables/data/useEnumFetch";
+import type { AsyncData } from '#app'
+import type { ComputedRef } from 'vue'
+import Parameters from '~/models/Organization/Parameters'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import Cycle from '~/models/Education/Cycle'
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
+import type { AnyJson } from '~/types/data'
+import { useEnumFetch } from '~/composables/data/useEnumFetch'
+import ApiResource from '~/models/ApiResource'
 
 
 const organizationProfile = useOrganizationProfileStore()
 const organizationProfile = useOrganizationProfileStore()
 
 
@@ -61,28 +67,32 @@ if (organizationProfile.parametersId === null) {
 const { fetch, fetchCollection } = useEntityFetch()
 const { fetch, fetchCollection } = useEntityFetch()
 const { fetch: fetchEnum } = useEnumFetch()
 const { fetch: fetchEnum } = useEnumFetch()
 
 
-
 const { data: cycleEnum, pending: enumPending } = fetchEnum('education_cycle')
 const { data: cycleEnum, pending: enumPending } = fetchEnum('education_cycle')
 
 
-const { data: parameters, pending: parametersPending } = fetch(Parameters, organizationProfile.parametersId) as AsyncData<Parameters, Parameters | true>
+const { data: parameters, pending: parametersPending } = fetch(
+  Parameters,
+  organizationProfile.parametersId,
+) as AsyncData<ApiResource | null, Error | null>
 
 
 const { data: cycles, pending: cyclesPending } = fetchCollection(Cycle)
 const { data: cycles, pending: cyclesPending } = fetchCollection(Cycle)
 
 
-const pending: ComputedRef<boolean> = computed(() => enumPending.value || parametersPending.value || cyclesPending.value)
+const pending: ComputedRef<boolean> = computed(
+  () => enumPending.value || parametersPending.value || cyclesPending.value,
+)
 
 
 const orderedCycles: ComputedRef<AnyJson> = computed(() => {
 const orderedCycles: ComputedRef<AnyJson> = computed(() => {
-  if (pending.value) {
+  if (pending.value || cycleEnum.value === null || cycles.value === null) {
     return []
     return []
   }
   }
 
 
-  let orderedCycles: AnyJson = {}
+  const orderedCycles: AnyJson = {}
 
 
   for (const enumItem of cycleEnum.value) {
   for (const enumItem of cycleEnum.value) {
     orderedCycles[enumItem.value] = null
     orderedCycles[enumItem.value] = null
   }
   }
 
 
   for (const cycle of cycles.value.items) {
   for (const cycle of cycles.value.items) {
-    if (!orderedCycles.hasOwnProperty(cycle.cycleEnum)) {
+    if (!Object.prototype.hasOwnProperty.call(orderedCycles, cycle.cycleEnum)) {
       console.error('Unknown cycle enum : ' + cycle.cycleEnum)
       console.error('Unknown cycle enum : ' + cycle.cycleEnum)
       continue
       continue
     }
     }
@@ -93,7 +103,6 @@ const orderedCycles: ComputedRef<AnyJson> = computed(() => {
   return orderedCycles
   return orderedCycles
 })
 })
 
 
-
 const goToCycleEditPage = (id: number) => {
 const goToCycleEditPage = (id: number) => {
   navigateTo(`/parameters/cycles/${id}`)
   navigateTo(`/parameters/cycles/${id}`)
 }
 }

+ 80 - 64
pages/parameters/website.vue

@@ -2,15 +2,15 @@
   <LayoutContainer>
   <LayoutContainer>
     <UiLoadingPanel v-if="pending" />
     <UiLoadingPanel v-if="pending" />
     <UiForm
     <UiForm
-        v-else
-        :model="Parameters"
-        :entity="parameters"
-        action-position="bottom"
+      v-else-if="parameters !== null"
+      :model="Parameters"
+      :entity="parameters"
+      action-position="bottom"
     >
     >
       <v-row>
       <v-row>
         <v-col cols="12">
         <v-col cols="12">
           <div class="my-5">
           <div class="my-5">
-            <span>{{ $t('your_opentalent_website_address_is')}} : </span>
+            <span>{{ $t('your_opentalent_website_address_is') }} : </span>
             <strong class="ml-2">
             <strong class="ml-2">
               <a :href="organizationProfile.website ?? '#'" target="_blank">
               <a :href="organizationProfile.website ?? '#'" target="_blank">
                 {{ organizationProfile.website }}
                 {{ organizationProfile.website }}
@@ -20,105 +20,115 @@
 
 
           <!-- les publicationDirectors sont des entités Access -->
           <!-- les publicationDirectors sont des entités Access -->
           <UiInputAutocompleteAccesses
           <UiInputAutocompleteAccesses
-              v-model="parameters.publicationDirectors"
-              field="publicationDirectors"
-              multiple
-              chips
-              variant="underlined"
-              class="my-4"
+            v-model="parameters.publicationDirectors"
+            field="publicationDirectors"
+            multiple
+            chips
+            variant="underlined"
+            class="my-4"
           />
           />
 
 
           <div>
           <div>
             <UiInputText
             <UiInputText
-                v-model="parameters.otherWebsite"
-                field="otherWebsite"
-                variant="underlined"
-                class="my-4"
+              v-model="parameters.otherWebsite"
+              field="otherWebsite"
+              variant="underlined"
+              class="my-4"
             />
             />
           </div>
           </div>
 
 
-          <v-divider class="my-10"/>
+          <v-divider class="my-10" />
 
 
           <div class="mb-6">
           <div class="mb-6">
-            <div><h4>{{ $t('your_subdomains') }} : </h4></div>
+            <div>
+              <h4>{{ $t('your_subdomains') }} :</h4>
+            </div>
             <UiLoadingPanel v-if="subdomainsPending" />
             <UiLoadingPanel v-if="subdomainsPending" />
             <div v-else>
             <div v-else>
               <v-table v-if="subdomains" class="subdomains-table my-2">
               <v-table v-if="subdomains" class="subdomains-table my-2">
                 <tbody>
                 <tbody>
                   <tr
                   <tr
-                      v-for="subdomain in subdomains.items"
-                      :key="subdomain.id"
-                      :title="subdomain.subdomain"
-                      :class="'subdomainItem' + (subdomain.active ? ' active' : '')"
-                      @click="goToEditPage(subdomain.id)"
+                    v-for="subdomain in subdomains.items"
+                    :key="subdomain.id"
+                    :title="subdomain.subdomain"
+                    :class="
+                      'subdomainItem' + (subdomain.active ? ' active' : '')
+                    "
+                    @click="goToEditPage(subdomain.id)"
                   >
                   >
                     <td>{{ subdomain.subdomain }}</td>
                     <td>{{ subdomain.subdomain }}</td>
                     <td>
                     <td>
-                        <span v-if="subdomain.active">
-                          <v-icon class="text-success icon">
-                            fa-solid fa-check
-                          </v-icon> {{ $t('active') }}
-                        </span>
+                      <span v-if="subdomain.active">
+                        <v-icon class="text-success icon">
+                          fa-solid fa-check
+                        </v-icon>
+                        {{ $t('active') }}
+                      </span>
                     </td>
                     </td>
-
                   </tr>
                   </tr>
-
                 </tbody>
                 </tbody>
-
               </v-table>
               </v-table>
               <span v-else>{{ $t('no_recorded_subdomain') }}</span>
               <span v-else>{{ $t('no_recorded_subdomain') }}</span>
 
 
               <div class="d-flex flex-row justify-center w-100">
               <div class="d-flex flex-row justify-center w-100">
                 <v-btn
                 <v-btn
-                    :disabled="!canAddNewSubdomain"
-                    class="my-5"
-                    @click="onAddSubdomainClick"
+                  :disabled="!canAddNewSubdomain"
+                  class="my-5"
+                  @click="onAddSubdomainClick"
                 >
                 >
-                  {{ $t('record_a_new_subdomain')}}
+                  {{ $t('record_a_new_subdomain') }}
                 </v-btn>
                 </v-btn>
               </div>
               </div>
             </div>
             </div>
           </div>
           </div>
 
 
           <div v-if="!organizationProfile.isCmf">
           <div v-if="!organizationProfile.isCmf">
-            <v-divider class="my-10"/>
+            <v-divider class="my-10" />
 
 
-            <div class="my-8 d-flex flex-row justify-center w-100" v-if="!organizationProfile.isCmf">
+            <div
+              v-if="!organizationProfile.isCmf"
+              class="my-8 d-flex flex-row justify-center w-100"
+            >
               <v-btn
               <v-btn
                 v-if="!parameters.desactivateOpentalentSiteWeb"
                 v-if="!parameters.desactivateOpentalentSiteWeb"
                 color="error"
                 color="error"
-                @click="showWebsiteDeactivationDialog=true"
+                @click="showWebsiteDeactivationDialog = true"
               >
               >
                 {{ $t('deactivateOpentalentSiteWeb') }}
                 {{ $t('deactivateOpentalentSiteWeb') }}
               </v-btn>
               </v-btn>
-              <v-btn
-                v-else
-                color="primary"
-                @click="reactivateWebsite"
-              >
+              <v-btn v-else color="primary" @click="reactivateWebsite">
                 {{ $t('reactivateOpentalentSiteWeb') }}
                 {{ $t('reactivateOpentalentSiteWeb') }}
               </v-btn>
               </v-btn>
 
 
               <LazyLayoutDialog :show="showWebsiteDeactivationDialog">
               <LazyLayoutDialog :show="showWebsiteDeactivationDialog">
                 <template #dialogTitle>
                 <template #dialogTitle>
-                  {{ $t('please_confirm')}}
+                  {{ $t('please_confirm') }}
                 </template>
                 </template>
                 <template #dialogText>
                 <template #dialogText>
                   <v-col>
                   <v-col>
-                    <div>{{ $t('yourOpentalentWebsiteWillBeDeactivatedOnceYouLlHaveSaved')}}.</div>
-                    <span>{{ $t('doYouWantToContinue')}} ?</span>
+                    <div>
+                      {{
+                        $t(
+                          'yourOpentalentWebsiteWillBeDeactivatedOnceYouLlHaveSaved',
+                        )
+                      }}.
+                    </div>
+                    <span>{{ $t('doYouWantToContinue') }} ?</span>
                   </v-col>
                   </v-col>
                 </template>
                 </template>
                 <template #dialogBtn>
                 <template #dialogBtn>
                   <v-btn
                   <v-btn
-                      class="theme-neutral-soft mr-4"
-                      @click="showWebsiteDeactivationDialog=false"
+                    class="theme-neutral-soft mr-4"
+                    @click="showWebsiteDeactivationDialog = false"
                   >
                   >
                     {{ $t('cancel') }}
                     {{ $t('cancel') }}
                   </v-btn>
                   </v-btn>
                   <v-btn
                   <v-btn
-                      class="theme-primary"
-                      @click="showWebsiteDeactivationDialog=false; deactivateWebsite()"
+                    class="theme-primary"
+                    @click="
+                      showWebsiteDeactivationDialog = false
+                      deactivateWebsite()
+                    "
                   >
                   >
                     {{ $t('yes') }}
                     {{ $t('yes') }}
                   </v-btn>
                   </v-btn>
@@ -133,13 +143,13 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import {useOrganizationProfileStore} from "~/stores/organizationProfile";
-import Parameters from "~/models/Organization/Parameters";
-import {useEntityFetch} from "~/composables/data/useEntityFetch";
-import type {AsyncData} from "#app";
-import Subdomain from "~/models/Organization/Subdomain";
-
-const i18n = useI18n()
+import type { AsyncData } from '#app'
+import type { ComputedRef, Ref } from 'vue'
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
+import Parameters from '~/models/Organization/Parameters'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import Subdomain from '~/models/Organization/Subdomain'
+import ApiResource from '~/models/ApiResource'
 
 
 const { fetch, fetchCollection } = useEntityFetch()
 const { fetch, fetchCollection } = useEntityFetch()
 
 
@@ -149,11 +159,20 @@ if (organizationProfile.parametersId === null) {
   throw new Error('Missing organization parameters id')
   throw new Error('Missing organization parameters id')
 }
 }
 
 
-const { data: parameters, pending } = fetch(Parameters, organizationProfile.parametersId) as AsyncData<Parameters, Parameters | true>
+const { data: parameters, pending } = fetch(
+  Parameters,
+  organizationProfile.parametersId,
+) as AsyncData<ApiResource | null, Error | null>
 
 
-const { data: subdomains, pending: subdomainsPending } = fetchCollection(Subdomain, null, ref({ 'organization' : organizationProfile.id }) )
+const { data: subdomains, pending: subdomainsPending } = fetchCollection(
+  Subdomain,
+  null,
+  ref({ organization: organizationProfile.id }),
+)
 
 
-const canAddNewSubdomain: ComputedRef<boolean> = computed(() => subdomains.value && subdomains.value.items.length < 3)
+const canAddNewSubdomain: ComputedRef<boolean> = computed(
+  () => subdomains.value !== null && subdomains.value.items.length < 3,
+)
 
 
 const goToEditPage = (id: number) => {
 const goToEditPage = (id: number) => {
   console.log(parameters.value)
   console.log(parameters.value)
@@ -169,18 +188,16 @@ const onAddSubdomainClick = () => {
 
 
 const showWebsiteDeactivationDialog: Ref<boolean> = ref(false)
 const showWebsiteDeactivationDialog: Ref<boolean> = ref(false)
 
 
-
 const deactivateWebsite = () => {
 const deactivateWebsite = () => {
-  parameters.value.desactivateOpentalentSiteWeb = true
+  parameters.value!.desactivateOpentalentSiteWeb = true
 }
 }
 
 
 const reactivateWebsite = () => {
 const reactivateWebsite = () => {
-  parameters.value.desactivateOpentalentSiteWeb = false
+  parameters.value!.desactivateOpentalentSiteWeb = false
 }
 }
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
-
 .subdomains-table {
 .subdomains-table {
   max-width: 450px;
   max-width: 450px;
 }
 }
@@ -203,5 +220,4 @@ const reactivateWebsite = () => {
 .subdomainItem.active td:first-child {
 .subdomainItem.active td:first-child {
   border-left: solid 2px rgb(var(--v-theme-primary));
   border-left: solid 2px rgb(var(--v-theme-primary));
 }
 }
-
 </style>
 </style>

+ 5 - 6
pages/poc.vue

@@ -2,16 +2,15 @@
   <main>
   <main>
     <div class="pa-8">
     <div class="pa-8">
       <h1>POC</h1>
       <h1>POC</h1>
-      <NuxtPage/>
+      <NuxtPage />
     </div>
     </div>
   </main>
   </main>
 </template>
 </template>
 
 
-<script setup lang="ts">
-</script>
+<script setup lang="ts"></script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
-  h1 {
-    color: rgb(var(--v-theme-primary))
-  }
+h1 {
+  color: rgb(var(--v-theme-primary));
+}
 </style>
 </style>

Some files were not shown because too many files changed in this diff