Browse Source

apply prettier lint

Olivier Massot 11 tháng trước cách đây
mục cha
commit
6ed5f3019b
90 tập tin đã thay đổi với 1059 bổ sung902 xóa
  1. 137 153
      components/Form/Freemium/Event.vue
  2. 6 8
      components/Form/Parameter/AttendanceBookingReason.vue
  3. 4 7
      components/Form/Parameter/EducationTiming.vue
  4. 4 7
      components/Form/Parameter/ResidenceArea.vue
  5. 1 1
      components/Layout/AlertBar/Cotisation.vue
  6. 1 1
      components/Layout/AlertBar/OnlineRegistration.vue
  7. 1 1
      components/Layout/AlertBar/RegistrationStatus.vue
  8. 1 1
      components/Layout/Header.vue
  9. 2 2
      components/Layout/Header/Notification.vue
  10. 8 3
      components/Layout/MobytStatus.vue
  11. 2 3
      components/Layout/Parameters/EntityTable.vue
  12. 2 2
      components/Layout/SubHeader/PersonnalizedList.vue
  13. 4 1
      components/Layout/Subheader.vue
  14. 6 7
      components/Ui/Button/Delete.vue
  15. 25 23
      components/Ui/DatePicker.vue
  16. 46 30
      components/Ui/EventList.vue
  17. 5 6
      components/Ui/Form.vue
  18. 22 20
      components/Ui/Form/Creation.vue
  19. 30 27
      components/Ui/Form/Edition.vue
  20. 10 2
      components/Ui/Input/Autocomplete/Accesses.vue
  21. 26 18
      components/Ui/Input/Autocomplete/ApiResources.vue
  22. 2 2
      components/Ui/Input/Autocomplete/Enum.vue
  23. 16 17
      components/Ui/Input/DatePicker.vue
  24. 15 6
      components/Ui/Input/DateTimePicker.vue
  25. 1 4
      components/Ui/Input/Email.vue
  26. 2 2
      components/Ui/Input/Number.vue
  27. 4 8
      components/Ui/Input/Phone.vue
  28. 1 1
      components/Ui/Input/TextArea.vue
  29. 49 30
      components/Ui/Input/TreeSelect.vue
  30. 1 3
      components/Ui/Input/TreeSelect/EventCategories.vue
  31. 69 56
      components/Ui/MapLeaflet.client.vue
  32. 9 11
      composables/data/useEntityFetch.ts
  33. 3 3
      composables/data/useEntityManager.ts
  34. 1 1
      composables/form/useDeleteItem.ts
  35. 3 3
      composables/utils/useHomeUrl.ts
  36. 1 1
      eslint.config.mjs
  37. 109 62
      layouts/freemium.vue
  38. 2 2
      models/Billing/ResidenceArea.ts
  39. 2 2
      models/Booking/AttendanceBookingReason.ts
  40. 2 2
      models/Education/Cycle.ts
  41. 2 2
      models/Education/EducationTiming.ts
  42. 9 9
      models/Freemium/Event.ts
  43. 10 10
      models/Freemium/Organization.ts
  44. 4 4
      models/Freemium/Place.ts
  45. 2 2
      models/Organization/Parameters.ts
  46. 95 60
      pages/freemium/dashboard.vue
  47. 1 4
      pages/freemium/events/[id].vue
  48. 1 4
      pages/freemium/events/new.vue
  49. 126 112
      pages/freemium/organization.vue
  50. 5 3
      pages/my-settings.vue
  51. 4 2
      pages/parameters/attendance_booking_reasons/[id].vue
  52. 0 1
      pages/parameters/attendance_booking_reasons/new.vue
  53. 3 5
      pages/parameters/attendances.vue
  54. 1 2
      pages/parameters/bulletin.vue
  55. 1 2
      pages/parameters/cycles/[id].vue
  56. 4 4
      pages/parameters/education_notation.vue
  57. 4 2
      pages/parameters/education_timings/[id].vue
  58. 0 1
      pages/parameters/education_timings/index.vue
  59. 0 1
      pages/parameters/education_timings/new.vue
  60. 10 11
      pages/parameters/general_parameters.vue
  61. 1 2
      pages/parameters/intranet.vue
  62. 0 1
      pages/parameters/residence_areas/[id].vue
  63. 0 1
      pages/parameters/residence_areas/index.vue
  64. 0 1
      pages/parameters/residence_areas/new.vue
  65. 11 9
      pages/parameters/sms.vue
  66. 1 1
      pages/parameters/subdomains/[id].vue
  67. 7 9
      pages/parameters/super_admin.vue
  68. 5 3
      pages/parameters/teaching.vue
  69. 1 1
      pages/parameters/website.vue
  70. 1 1
      pages/subscription.vue
  71. 6 6
      plugins/vPhoneInput.ts
  72. 14 16
      services/asserts/AssertRuleRegistry.ts
  73. 5 3
      services/asserts/MaxAssert.ts
  74. 7 6
      services/asserts/NullableAssert.ts
  75. 9 8
      services/asserts/TypeAssert.ts
  76. 4 4
      services/asserts/getAssertUtils.ts
  77. 1 1
      services/data/Filters/EqualFilter.ts
  78. 2 2
      services/data/Filters/InArrayFilter.ts
  79. 1 1
      services/data/Filters/OrderBy.ts
  80. 1 1
      services/data/Filters/PageFilter.ts
  81. 1 1
      services/data/Filters/SearchFilter.ts
  82. 8 8
      services/data/Filters/TimeFilter.ts
  83. 1 1
      services/data/Query.ts
  84. 33 13
      services/data/entityManager.ts
  85. 3 5
      services/data/normalizer/hydraNormalizer.ts
  86. 3 1
      services/layout/menuBuilder/accountMenuBuilder.ts
  87. 1 1
      stores/page.ts
  88. 11 11
      tests/units/services/data/normalizer/hydraNormalizer.test.ts
  89. 2 2
      types/data.d.ts
  90. 2 2
      types/interfaces.d.ts

+ 137 - 153
components/Form/Freemium/Event.vue

@@ -1,58 +1,55 @@
 <template>
-    <LayoutCommonSection>
-      <v-row>
-        <v-col cols="12" sm="12">
-          <h4 class="mb-8">{{ $t('general_informations') }}</h4>
-
-          <UiInputText
-            v-model="entity.name"
-            field="name"
-            :rules="getAsserts('name')"
-          />
-
-          <span class="label">{{$t('datetimeStart')}}</span>
-          <UiInputDateTimePicker
-            :model-value="entity.datetimeStart"
-            field="datetimeStart"
-            label="datetimeStart"
-            :with-time-picker="true"
-            class="my-2"
-            :rules="getAsserts('datetimeStart')"
-            validate-on-blur
-            @update:model-value="onUpdateDateTimeStart(entity, $event)"
-          />
-
-          <span class="label">{{$t('datetimeEnd')}}</span>
-          <UiInputDateTimePicker
-            :model-value="entity.datetimeEnd"
-            field="datetimeEnd"
-            label="datetimeEnd"
-            :with-time-picker="true"
-            class="my-2"
-            :rules="getAsserts('datetimeEnd')"
-            @update:model-value="onUpdateDateTimeEnd(entity, $event)"
-          />
-
-          <span class="label">{{$t('description')}}</span>
-          <UiInputTextArea
-            v-model="entity.description"
-            class="mt-3"
-          />
-
-          <UiInputTreeSelectEventCategories
-            v-model="entity.categories"
-            label="event_categories_choices"
-          />
-
-          <UiInputImage
-            v-model="entity.image"
-            field="image"
-            :width="240"
-            :cropping-enabled="true"
-          />
-        </v-col>
-      </v-row>
-    </LayoutCommonSection>
+  <LayoutCommonSection>
+    <v-row>
+      <v-col cols="12" sm="12">
+        <h4 class="mb-8">{{ $t('general_informations') }}</h4>
+
+        <UiInputText
+          v-model="entity.name"
+          field="name"
+          :rules="getAsserts('name')"
+        />
+
+        <span class="label">{{ $t('datetimeStart') }}</span>
+        <UiInputDateTimePicker
+          :model-value="entity.datetimeStart"
+          field="datetimeStart"
+          label="datetimeStart"
+          :with-time-picker="true"
+          class="my-2"
+          :rules="getAsserts('datetimeStart')"
+          validate-on-blur
+          @update:model-value="onUpdateDateTimeStart(entity, $event)"
+        />
+
+        <span class="label">{{ $t('datetimeEnd') }}</span>
+        <UiInputDateTimePicker
+          :model-value="entity.datetimeEnd"
+          field="datetimeEnd"
+          label="datetimeEnd"
+          :with-time-picker="true"
+          class="my-2"
+          :rules="getAsserts('datetimeEnd')"
+          @update:model-value="onUpdateDateTimeEnd(entity, $event)"
+        />
+
+        <span class="label">{{ $t('description') }}</span>
+        <UiInputTextArea v-model="entity.description" class="mt-3" />
+
+        <UiInputTreeSelectEventCategories
+          v-model="entity.categories"
+          label="event_categories_choices"
+        />
+
+        <UiInputImage
+          v-model="entity.image"
+          field="image"
+          :width="240"
+          :cropping-enabled="true"
+        />
+      </v-col>
+    </v-row>
+  </LayoutCommonSection>
 
   <LayoutCommonSection>
     <v-row>
@@ -69,26 +66,22 @@
           @update:model-value="getPlace(entity)"
         />
 
-        <v-row  v-if="!newPlace" class="mb-6 justify-center">
+        <v-row v-if="!newPlace" class="mb-6 justify-center">
           <v-col
             v-if="entity.place && !editPlace"
             cols="12"
             sm="6"
             class="d-flex justify-center mb-2"
           >
-              <v-btn
-                prepend-icon="fa-solid fa-pencil"
-                @click="onEditPlaceClick(entity)"
-              >
-                {{ $t('edit_place') }}
-              </v-btn>
+            <v-btn
+              prepend-icon="fa-solid fa-pencil"
+              @click="onEditPlaceClick(entity)"
+            >
+              {{ $t('edit_place') }}
+            </v-btn>
           </v-col>
 
-          <v-col
-            cols="12"
-            sm="6"
-            class="d-flex justify-center mb-2"
-          >
+          <v-col cols="12" sm="6" class="d-flex justify-center mb-2">
             <v-btn
               prepend-icon="fa-solid fa-plus"
               @click="onAddPlaceClick(entity)"
@@ -157,106 +150,97 @@
             :search-button="true"
           ></UiMapLeaflet>
         </client-only>
+      </v-col>
+    </v-row>
+  </LayoutCommonSection>
+
+  <LayoutCommonSection>
+    <v-row>
+      <v-col cols="12">
+        <h4 class="mb-8">{{ $t('communication_params') }}</h4>
+
+        <UiInputText v-model="entity.url" field="url" />
 
+        <UiInputAutocompleteEnum
+          v-model="entity.pricing"
+          enum-name="pricing_event"
+          field="pricing"
+        />
+
+        <UiInputText
+          v-if="entity.pricing === 'PAID'"
+          v-model="entity.urlTicket"
+          field="urlTicket"
+        />
+
+        <UiInputNumber
+          v-if="entity.pricing === 'PAID'"
+          v-model="entity.priceMini"
+          field="priceMini"
+        />
+
+        <UiInputNumber
+          v-if="entity.pricing === 'PAID'"
+          v-model="entity.priceMaxi"
+          field="priceMaxi"
+        />
       </v-col>
     </v-row>
   </LayoutCommonSection>
 
-    <LayoutCommonSection>
-      <v-row>
-        <v-col cols="12">
-
-          <h4 class="mb-8">{{ $t('communication_params') }}</h4>
-
-          <UiInputText
-            v-model="entity.url"
-            field="url"
-          />
-
-          <UiInputAutocompleteEnum
-            v-model="entity.pricing"
-            enum-name="pricing_event"
-            field="pricing"
-          />
-
-          <UiInputText
-            v-if="entity.pricing==='PAID'"
-            v-model="entity.urlTicket"
-            field="urlTicket"
-          />
-
-          <UiInputNumber
-            v-if="entity.pricing==='PAID'"
-            v-model="entity.priceMini"
-            field="priceMini"
-          />
-
-          <UiInputNumber
-            v-if="entity.pricing==='PAID'"
-            v-model="entity.priceMaxi"
-            field="priceMaxi"
-          />
-
-        </v-col>
-      </v-row>
-    </LayoutCommonSection>
-
-    <LazyLayoutDialog :show="showAlert" theme="warning">
-      <template #dialogType>{{ $t('important') }}</template>
-      <template #dialogTitle>{{ $t('place_change_everywhere') }}</template>
-      <template #dialogText>
-        <v-card-text class="text">
-          <p>
-            {{$t('warning_edit_place')}}
-          </p>
-        </v-card-text>
-      </template>
-      <template #dialogBtn>
-        <v-btn class="mr-4 submitBtn theme-neutral-strong" @click="closeDialog">
-          {{ $t('cancel') }}
-        </v-btn>
-        <v-btn class="mr-4 submitBtn theme-warning" @click="onEditPlaceConfirm">
-          {{ $t('i_understand') }}
-        </v-btn>
-      </template>
-    </LazyLayoutDialog>
+  <LazyLayoutDialog :show="showAlert" theme="warning">
+    <template #dialogType>{{ $t('important') }}</template>
+    <template #dialogTitle>{{ $t('place_change_everywhere') }}</template>
+    <template #dialogText>
+      <v-card-text class="text">
+        <p>
+          {{ $t('warning_edit_place') }}
+        </p>
+      </v-card-text>
+    </template>
+    <template #dialogBtn>
+      <v-btn class="mr-4 submitBtn theme-neutral-strong" @click="closeDialog">
+        {{ $t('cancel') }}
+      </v-btn>
+      <v-btn class="mr-4 submitBtn theme-warning" @click="onEditPlaceConfirm">
+        {{ $t('i_understand') }}
+      </v-btn>
+    </template>
+  </LazyLayoutDialog>
 </template>
 
 <script setup lang="ts">
-import Event from "~/models/Freemium/Event";
-import Place from "~/models/Freemium/Place";
-import {getAssertUtils} from "~/services/asserts/getAssertUtils";
-import DateUtils from "~/services/utils/dateUtils";
-import Country from "~/models/Core/Country";
-import PlaceSearchItem from "~/models/Custom/Search/PlaceSearchItem";
-import {useEntityManager} from "~/composables/data/useEntityManager";
+import Event from '~/models/Freemium/Event'
+import Place from '~/models/Freemium/Place'
+import { getAssertUtils } from '~/services/asserts/getAssertUtils'
+import DateUtils from '~/services/utils/dateUtils'
+import Country from '~/models/Core/Country'
+import PlaceSearchItem from '~/models/Custom/Search/PlaceSearchItem'
+import { useEntityManager } from '~/composables/data/useEntityManager'
 
 const props = defineProps<{
   modelValue: Event
 }>()
 
-const {em} = useEntityManager()
+const { em } = useEntityManager()
 const getAsserts = (key) => getAssertUtils(Event.getAsserts(), key)
 
-const emit = defineEmits([
-  'update:modelValue',
-])
+const emit = defineEmits(['update:modelValue'])
 
 // Pour éviter l'erreur eslint "Unexpected mutation of "modelValue" prop"
 const entity = computed({
   get: () => props.modelValue,
-  set: (value) => emit('update:modelValue', value)
+  set: (value) => emit('update:modelValue', value),
 })
 
-
 /**
  * Si la date de début est mise à jour, on s'assure que la date de fin est
  * après elle, sinon elle devient égale
  * @param entity
  * @param dateTime
  */
-const onUpdateDateTimeStart = (entity, dateTime) =>{
-  if(DateUtils.isBefore(props.entity.datetimeEnd, dateTime, false)){
+const onUpdateDateTimeStart = (entity, dateTime) => {
+  if (DateUtils.isBefore(props.entity.datetimeEnd, dateTime, false)) {
     entity.datetimeEnd = dateTime
   }
   entity.datetimeStart = dateTime
@@ -269,8 +253,8 @@ const onUpdateDateTimeStart = (entity, dateTime) =>{
  * @param entity
  * @param dateTime
  */
-const onUpdateDateTimeEnd = (entity, dateTime) =>{
-  if(DateUtils.isBefore(dateTime, props.entity.datetimeStart, false)){
+const onUpdateDateTimeEnd = (entity, dateTime) => {
+  if (DateUtils.isBefore(dateTime, props.entity.datetimeStart, false)) {
     entity.datetimeStart = dateTime
   }
   entity.datetimeEnd = dateTime
@@ -286,7 +270,7 @@ const editPlace: Ref<boolean> = ref(false)
  * est mise à nulle, et les champs input de l'adresse sont vidées
  * @param entity
  */
-const onAddPlaceClick = function(entity: Event){
+const onAddPlaceClick = function (entity: Event) {
   newPlace.value = true
   entity.place = null
   resetPlace(entity)
@@ -295,21 +279,21 @@ const onAddPlaceClick = function(entity: Event){
 /**
  * Quand on clic sur le bouton "Editer le lieu", une alerte s'affiche
  */
-const onEditPlaceClick = function(){
+const onEditPlaceClick = function () {
   showAlert.value = true
 }
 
 /**
  * Quand on ferme la boite de dialogue
  */
-const closeDialog = function(){
+const closeDialog = function () {
   showAlert.value = false
 }
 
 /**
  * Si on décide d'éditer le lieu
  */
-const onEditPlaceConfirm = function(){
+const onEditPlaceConfirm = function () {
   showAlert.value = false
   editPlace.value = true
 }
@@ -319,8 +303,8 @@ const onEditPlaceConfirm = function(){
  * input de l'adresse
  * @param entity
  */
-const getPlace = async (entity: Event)=>{
-  if(entity.place){
+const getPlace = async (entity: Event) => {
+  if (entity.place) {
     const placeInstance = await em.fetch(Place, entity.place as number)
     entity.placeName = placeInstance.name
     entity.streetAddress = placeInstance.streetAddress
@@ -332,7 +316,7 @@ const getPlace = async (entity: Event)=>{
     entity.latitude = placeInstance.latitude
     entity.longitude = placeInstance.longitude
     editPlace.value = false
-  }else{
+  } else {
     //Dans le cas où l'on ne récupère aucune place on remet a null le formulaire de l'adresse
     resetPlace(entity)
   }
@@ -344,7 +328,7 @@ const getPlace = async (entity: Event)=>{
  * fonction permettant de remettre à vide tous les champs input de l'adresse
  * @param entity
  */
-const resetPlace = (entity: Event)=>{
+const resetPlace = (entity: Event) => {
   entity.placeName = null
   entity.streetAddress = null
   entity.streetAddressSecond = null
@@ -367,8 +351,8 @@ onBeforeUnmount(() => {
 </script>
 
 <style scoped lang="scss">
-  .label{
-    font-size: 16px;
-    color: rgb(var(--v-theme-on-primary-alt));
-  }
+.label {
+  font-size: 16px;
+  color: rgb(var(--v-theme-on-primary-alt));
+}
 </style>

+ 6 - 8
components/Form/Parameter/AttendanceBookingReason.vue

@@ -14,23 +14,21 @@
 </template>
 
 <script setup lang="ts">
-import AttendanceBookingReason from "~/models/Booking/AttendanceBookingReason";
-import {getAssertUtils} from "~/services/asserts/getAssertUtils";
+import AttendanceBookingReason from '~/models/Booking/AttendanceBookingReason'
+import { getAssertUtils } from '~/services/asserts/getAssertUtils'
 
 const props = defineProps<{
   entity: AttendanceBookingReason
 }>()
 
-const emit = defineEmits([
-  'update:entity',
-])
+const emit = defineEmits(['update:entity'])
 
 // Pour éviter l'erreur eslint "Unexpected mutation of "modelValue" prop"
 const localEntity = computed({
   get: () => props.entity,
-  set: (value) => emit('update:entity', value)
+  set: (value) => emit('update:entity', value),
 })
 
-const getAsserts = (key) => getAssertUtils(AttendanceBookingReason.getAsserts(), key)
-
+const getAsserts = (key) =>
+  getAssertUtils(AttendanceBookingReason.getAsserts(), key)
 </script>

+ 4 - 7
components/Form/Parameter/EducationTiming.vue

@@ -13,23 +13,20 @@
 </template>
 
 <script setup lang="ts">
-import {getAssertUtils} from "~/services/asserts/getAssertUtils";
-import EducationTiming from "~/models/Education/EducationTiming";
+import { getAssertUtils } from '~/services/asserts/getAssertUtils'
+import EducationTiming from '~/models/Education/EducationTiming'
 
 const props = defineProps<{
   entity: EducationTiming
 }>()
 
-const emit = defineEmits([
-  'update:entity',
-])
+const emit = defineEmits(['update:entity'])
 
 // Pour éviter l'erreur eslint "Unexpected mutation of "modelValue" prop"
 const localEntity = computed({
   get: () => props.entity,
-  set: (value) => emit('update:entity', value)
+  set: (value) => emit('update:entity', value),
 })
 
 const getAsserts = (key) => getAssertUtils(EducationTiming.getAsserts(), key)
-
 </script>

+ 4 - 7
components/Form/Parameter/ResidenceArea.vue

@@ -14,23 +14,20 @@
 </template>
 
 <script setup lang="ts">
-import ResidenceArea from "~/models/Billing/ResidenceArea";
-import {getAssertUtils} from "~/services/asserts/getAssertUtils";
+import ResidenceArea from '~/models/Billing/ResidenceArea'
+import { getAssertUtils } from '~/services/asserts/getAssertUtils'
 
 const props = defineProps<{
   entity: ResidenceArea
 }>()
 
-const emit = defineEmits([
-  'update:entity',
-])
+const emit = defineEmits(['update:entity'])
 
 // Pour éviter l'erreur eslint "Unexpected mutation of "modelValue" prop"
 const localEntity = computed({
   get: () => props.entity,
-  set: (value) => emit('update:entity', value)
+  set: (value) => emit('update:entity', value),
 })
 
 const getAsserts = (key) => getAssertUtils(ResidenceArea.getAsserts(), key)
-
 </script>

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

@@ -22,7 +22,7 @@ import UrlUtils from '~/services/utils/urlUtils'
 import type { ALERT_STATE_COTISATION } from '~/types/enum/enums'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import Cotisation from '~/models/Organization/Cotisation'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 const organizationProfile = useOrganizationProfileStore()
 

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

@@ -17,7 +17,7 @@ import type { ComputedRef } from 'vue'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useAccessProfileStore } from '~/stores/accessProfile'
 import RegistrationAvailability from '~/models/OnlineRegistration/RegistrationAvailability'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 const { fetch } = useEntityFetch()
 

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

@@ -17,7 +17,7 @@ import type { ComputedRef } from 'vue'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useAccessProfileStore } from '~/stores/accessProfile'
 import RegistrationStatus from '~/models/OnlineRegistration/RegistrationStatus'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 const { fetch } = useEntityFetch()
 

+ 1 - 1
components/Layout/Header.vue

@@ -96,7 +96,7 @@ const hasLateralMenu = computed(() => {
   return (
     layoutStore.name !== 'freemium' &&
     ((layoutStore.name !== 'parameters' && hasMenu('Main')) ||
-    (layoutStore.name === 'parameters' && hasMenu('Parameters')))
+      (layoutStore.name === 'parameters' && hasMenu('Parameters')))
   )
 })
 

+ 2 - 2
components/Layout/Header/Notification.vue

@@ -54,7 +54,7 @@
           <span v-intersect="onLastNotificationIntersect" />
 
           <v-row
-            v-if="status==FETCHING_STATUS.PENDING"
+            v-if="status == FETCHING_STATUS.PENDING"
             class="fill-height mt-3 mb-3"
             align="center"
             justify="center"
@@ -96,7 +96,7 @@ import UrlUtils from '~/services/utils/urlUtils'
 import NotificationRepository from '~/stores/repositories/NotificationRepository'
 import Query from '~/services/data/Query'
 import PageFilter from '~/services/data/Filters/PageFilter'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 const accessProfileStore = useAccessProfileStore()
 

+ 8 - 3
components/Layout/MobytStatus.vue

@@ -1,7 +1,13 @@
 <template>
   <v-col cols="12" lg="12">
     <strong>{{ $t('remaining_sms_credit') }}</strong> -
-    <span v-if="mobytPendingStatus == FETCHING_STATUS.SUCCESS && mobytStatus !== null && mobytStatus.active">
+    <span
+      v-if="
+        mobytPendingStatus == FETCHING_STATUS.SUCCESS &&
+        mobytStatus !== null &&
+        mobytStatus.active
+      "
+    >
       {{
         mobytStatus.money.toLocaleString($i18n.locale, {
           style: 'currency',
@@ -22,8 +28,7 @@ import type { AsyncData } from '#app'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 import MobytUserStatus from '~/models/Organization/MobytUserStatus'
-import {FETCHING_STATUS} from "~/types/enum/data";
-
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 const { fetch } = useEntityFetch()
 const i18n = useI18n()

+ 2 - 3
components/Layout/Parameters/EntityTable.vue

@@ -3,7 +3,7 @@ A data table for the parameters page
 -->
 <template>
   <div class="container">
-    <UiLoadingPanel v-if="status===FETCHING_STATUS.PENDING" />
+    <UiLoadingPanel v-if="status === FETCHING_STATUS.PENDING" />
     <div v-else>
       <LayoutParametersTable
         :items="items"
@@ -34,7 +34,7 @@ import type { AssociativeArray } from '~/types/data'
 import type { ColumnDefinition } from '~/types/interfaces'
 import { useDeleteItem } from '~/composables/form/useDeleteItem'
 import { useEntityManager } from '~/composables/data/useEntityManager'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 const props = defineProps({
   /**
@@ -204,7 +204,6 @@ onBeforeUnmount(() => {
     useRepo(props.model).flush()
   }
 })
-
 </script>
 
 <style scoped lang="scss"></style>

+ 2 - 2
components/Layout/SubHeader/PersonnalizedList.vue

@@ -26,7 +26,7 @@
           <v-text-field
             v-model="search"
             :label="$t('searchList')"
-            :loading="status==FETCHING_STATUS.PENDING"
+            :loading="status == FETCHING_STATUS.PENDING"
             density="compact"
             clear-icon="header-personalized"
           />
@@ -58,7 +58,7 @@ import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import type { AnyJson } from '~/types/data'
 import type ApiResource from '~/models/ApiResource'
 import UrlUtils from '~/services/utils/urlUtils'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 const btn: Ref = ref(null)
 

+ 4 - 1
components/Layout/Subheader.vue

@@ -17,7 +17,10 @@ Contient entre autres le breadcrumb, les commandes de changement d'année et les
 
       <v-card
         v-if="!organizationProfile.isFreemiumProduct"
-        class="d-flex flex-row align-center mr-6" :flat="true" tile>
+        class="d-flex flex-row align-center mr-6"
+        :flat="true"
+        tile
+      >
         <LayoutSubHeaderActivityYear
           v-if="smAndUp && !showDateTimeRange"
           class="activity-year"

+ 6 - 7
components/Ui/Button/Delete.vue

@@ -6,7 +6,7 @@ Bouton Delete avec modale de confirmation de la suppression
   <main>
     <div class="div_to_clicked" @click="onDeleteClicked()">
       <!-- Content -->
-      <slot/>
+      <slot />
     </div>
 
     <UiFormDeletionConfirmationDialog
@@ -18,10 +18,10 @@ Bouton Delete avec modale de confirmation de la suppression
 </template>
 
 <script setup lang="ts" generic="T extends ApiResource">
-import {type Ref, ref} from 'vue'
+import { type Ref, ref } from 'vue'
 import type ApiResource from '~/models/ApiResource'
 import { useDeleteItem } from '~/composables/form/useDeleteItem'
-import {useEntityManager} from "~/composables/data/useEntityManager";
+import { useEntityManager } from '~/composables/data/useEntityManager'
 
 const props = defineProps<{
   entity: T
@@ -34,7 +34,7 @@ const { em } = useEntityManager()
 const showDeletionConfirmationDialog: Ref<boolean> = ref(false)
 const itemToDelete: Ref<ApiResource | null> = ref(null)
 
-const onDeleteClicked =  () => {
+const onDeleteClicked = () => {
   itemToDelete.value = em.cast(em.getModel(props.entity), props.entity)
   showDeletionConfirmationDialog.value = true
 }
@@ -44,17 +44,16 @@ const onCancelClicked = () => {
 }
 
 const onDeleteConfirmed = async () => {
-  if(itemToDelete.value != null){
+  if (itemToDelete.value != null) {
     pageStore.loading = true
     await deleteItem(itemToDelete.value)
     pageStore.loading = false
   }
 }
-
 </script>
 
 <style scoped>
-.div_to_clicked{
+.div_to_clicked {
   cursor: pointer;
 }
 </style>

+ 25 - 23
components/Ui/DatePicker.vue

@@ -5,28 +5,28 @@ Sélecteur de dates
 -->
 
 <template>
-    <VueDatePicker
-      :model-value="modelValue"
-      :locale="locale"
-      :format="dateFormatPattern"
-      :format-locale="fnsLocale"
-      :range="range"
-      :multi-calendars="range"
-      :enable-time-picker="withTimePicker"
-      :auto-apply="autoApply"
-      :auto-position="true"
-      :start-date="today"
-      close-on-scroll
-      text-input
-      :readonly="readonly"
-      position="left"
-      :teleport="true"
-      :select-text="$t('select')"
-      :cancel-text="$t('cancel')"
-      input-class-name="date-picker-input"
-      @update:model-value="emit('update:modelValue', $event)"
-    />
-  </template>
+  <VueDatePicker
+    :model-value="modelValue"
+    :locale="locale"
+    :format="dateFormatPattern"
+    :format-locale="fnsLocale"
+    :range="range"
+    :multi-calendars="range"
+    :enable-time-picker="withTimePicker"
+    :auto-apply="autoApply"
+    :auto-position="true"
+    :start-date="today"
+    close-on-scroll
+    text-input
+    :readonly="readonly"
+    position="left"
+    :teleport="true"
+    :select-text="$t('select')"
+    :cancel-text="$t('cancel')"
+    input-class-name="date-picker-input"
+    @update:model-value="emit('update:modelValue', $event)"
+  />
+</template>
 
 <script setup lang="ts">
 import { useI18n } from 'vue-i18n'
@@ -70,7 +70,9 @@ const fnsLocale: ComputedRef<Locale> = computed(() =>
 )
 
 const dateFormatPattern: ComputedRef<string> = computed(() =>
-  props.withTimePicker ? DateUtils.getFormatPattern(locale.value as supportedLocales) : DateUtils.getShortFormatPattern(locale.value as supportedLocales),
+  props.withTimePicker
+    ? DateUtils.getFormatPattern(locale.value as supportedLocales)
+    : DateUtils.getShortFormatPattern(locale.value as supportedLocales),
 )
 
 const today = new Date()

+ 46 - 30
components/Ui/EventList.vue

@@ -1,12 +1,7 @@
 <template>
   <div>
-    <v-list  height="420">
-
-      <v-list-item
-        v-for="event in events"
-        :key="event.id"
-        class="event-item"
-      >
+    <v-list height="420">
+      <v-list-item v-for="event in events" :key="event.id" class="event-item">
         <template #prepend>
           <v-avatar color="grey-lighten-1">
             <UiImage :image-id="event.image" :width="50" />
@@ -14,18 +9,17 @@
         </template>
 
         <template #default>
-          <div
-            class="flex-grow-1"
-            @click="$emit('edit', event.id)"
-          >
-            <span class="text-subtitle-1">{{event.name}}</span>
-            <br>
-            <span class="text-subtitle-2">{{date.format(event.datetimeStart, 'fullDateWithWeekday')}}</span>
+          <div class="flex-grow-1" @click="$emit('edit', event.id)">
+            <span class="text-subtitle-1">{{ event.name }}</span>
+            <br />
+            <span class="text-subtitle-2">{{
+              date.format(event.datetimeStart, 'fullDateWithWeekday')
+            }}</span>
           </div>
         </template>
 
         <template #append>
-          <v-avatar class="edit-btn"  @click="$emit('edit', event.id)">
+          <v-avatar class="edit-btn" @click="$emit('edit', event.id)">
             <v-icon>fas fa-pencil</v-icon>
           </v-avatar>
 
@@ -36,26 +30,48 @@
           </UiButtonDelete>
         </template>
       </v-list-item>
-
     </v-list>
 
-    <div v-if="events.length > 0" class="d-flex justify-space-between px-4 py-2 pagination mb-5">
-      <v-btn variant="flat" class="pagination-btn" :disabled="!pagination.first || !pagination.previous" @click="$emit('load', pagination.first)">
+    <div
+      v-if="events.length > 0"
+      class="d-flex justify-space-between px-4 py-2 pagination mb-5"
+    >
+      <v-btn
+        variant="flat"
+        class="pagination-btn"
+        :disabled="!pagination.first || !pagination.previous"
+        @click="$emit('load', pagination.first)"
+      >
         <v-avatar>
-        <v-icon>fas fa-angles-left</v-icon>
-      </v-avatar>
+          <v-icon>fas fa-angles-left</v-icon>
+        </v-avatar>
       </v-btn>
-      <v-btn variant="flat" class="pagination-btn" :disabled="!pagination.previous" @click="$emit('load', pagination.previous)">
+      <v-btn
+        variant="flat"
+        class="pagination-btn"
+        :disabled="!pagination.previous"
+        @click="$emit('load', pagination.previous)"
+      >
         <v-avatar>
           <v-icon>fas fa-angle-left</v-icon>
         </v-avatar>
       </v-btn>
-      <v-btn variant="flat" class="pagination-btn" :disabled="!pagination.next" @click="$emit('load', pagination.next)">
+      <v-btn
+        variant="flat"
+        class="pagination-btn"
+        :disabled="!pagination.next"
+        @click="$emit('load', pagination.next)"
+      >
         <v-avatar>
           <v-icon>fas fa-angle-right</v-icon>
         </v-avatar>
       </v-btn>
-      <v-btn variant="flat" class="pagination-btn" :disabled="pagination.last == 1" @click="$emit('load', pagination.last)">
+      <v-btn
+        variant="flat"
+        class="pagination-btn"
+        :disabled="pagination.last == 1"
+        @click="$emit('load', pagination.last)"
+      >
         <v-avatar>
           <v-icon>fas fa-angles-right</v-icon>
         </v-avatar>
@@ -66,13 +82,13 @@
 
 <script lang="ts" setup>
 import { defineProps, defineEmits } from 'vue'
-import type {Collection} from "pinia-orm";
-import type Event from "~/models/Freemium/Event";
-import type {Pagination} from "~/types/data";
+import type { Collection } from 'pinia-orm'
+import type Event from '~/models/Freemium/Event'
+import type { Pagination } from '~/types/data'
 import { useDate } from 'vuetify'
 
 const props = defineProps<{
-  events: Collection<Event>,
+  events: Collection<Event>
   pagination: Pagination
 }>()
 
@@ -84,7 +100,7 @@ const date = useDate()
 .event-item {
   margin-top: 20px;
   color: rgb(var(--v-theme-on-neutral));
-  .text-subtitle-2{
+  .text-subtitle-2 {
     text-transform: capitalize !important;
     color: rgb(var(--v-theme-on-neutral--sub));
   }
@@ -92,10 +108,10 @@ const date = useDate()
 .pagination-btn[disabled] {
   opacity: 0.3;
 }
-.edit-btn{
+.edit-btn {
   cursor: pointer;
 }
-:deep(.v-list-item):hover{
+:deep(.v-list-item):hover {
   cursor: pointer;
   background-color: rgb(var(--v-theme-neutral));
 }

+ 5 - 6
components/Ui/Form.vue

@@ -102,9 +102,9 @@ import type ApiModel from '~/models/ApiModel'
 import { usePageStore } from '~/stores/page'
 import type { AnyJson } from '~/types/data'
 import { useRefreshProfile } from '~/composables/data/useRefreshProfile'
-import Organization from "~/models/Freemium/Organization";
-import type Event from "~/models/Freemium/Event";
-import Country from "~/models/Core/Country";
+import Organization from '~/models/Freemium/Organization'
+import type Event from '~/models/Freemium/Event'
+import Country from '~/models/Core/Country'
 
 const props = defineProps({
   /**
@@ -162,7 +162,6 @@ const props = defineProps({
   },
 })
 
-
 // ### Définitions
 const i18n = useI18n()
 const router = useRouter()
@@ -333,14 +332,14 @@ onBeforeRouteLeave(
 )
 
 onMounted(() => {
-  window.addEventListener('beforeunload', quitWithoutSaving )
+  window.addEventListener('beforeunload', quitWithoutSaving)
 })
 
 onBeforeUnmount(() => {
   window.removeEventListener('beforeunload', quitWithoutSaving)
 })
 
-function quitWithoutSaving(event){
+function quitWithoutSaving(event) {
   if (formStore.dirty === true) {
     event.returnValue = i18n.t('quit_without_saving_warning')
   }

+ 22 - 20
components/Ui/Form/Creation.vue

@@ -11,32 +11,34 @@
 </template>
 
 <script setup lang="ts" generic="T extends typeof ApiModel">
-
 import type { RouteLocationRaw } from 'vue-router'
 import type ApiModel from '~/models/ApiModel'
 import type { AnyJson } from '~/types/data'
 import { SUBMIT_TYPE } from '~/types/enum/enums'
 import { useEntityManager } from '~/composables/data/useEntityManager'
 
-const props = withDefaults(defineProps<{
-  model: T
-  /**
-   * Route de retour
-   */
-  goBackRoute?: RouteLocationRaw | null
-  /**
-   * La validation est en cours
-   */
-  validationPending?: boolean
-  /**
-   * Faut-il rafraîchir le profil à la soumission du formulaire ?
-   */
-  refreshProfile?: boolean
-}>(), {
-  goBackRoute: null,
-  validationPending: false,
-  refreshProfile: false
-})
+const props = withDefaults(
+  defineProps<{
+    model: T
+    /**
+     * Route de retour
+     */
+    goBackRoute?: RouteLocationRaw | null
+    /**
+     * La validation est en cours
+     */
+    validationPending?: boolean
+    /**
+     * Faut-il rafraîchir le profil à la soumission du formulaire ?
+     */
+    refreshProfile?: boolean
+  }>(),
+  {
+    goBackRoute: null,
+    validationPending: false,
+    refreshProfile: false,
+  },
+)
 
 const router = useRouter()
 const { em } = useEntityManager()

+ 30 - 27
components/Ui/Form/Edition.vue

@@ -1,6 +1,6 @@
 <template>
   <LayoutContainer>
-    <UiLoadingPanel v-if="status==FETCHING_STATUS.PENDING" />
+    <UiLoadingPanel v-if="status == FETCHING_STATUS.PENDING" />
     <UiForm v-else v-model="entity" :submit-actions="submitActions">
       <template #form.button>
         <v-btn v-if="goBackRoute" class="theme-neutral mr-3" @click="quit">
@@ -20,33 +20,36 @@ import type ApiModel from '~/models/ApiModel'
 import type { AnyJson } from '~/types/data'
 import { SUBMIT_TYPE } from '~/types/enum/enums'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
-const props = withDefaults(defineProps<{
-  model: T
-  /**
-   * Id de l'objet
-   * Si non renseigné, le composant essaiera de l'extraire de la route actuelle
-   */
-  id?: number | null
-  /**
-   * Route de retour
-   */
-  goBackRoute?: RouteLocationRaw | null
-  /**
-   * La validation est en cours
-   */
-  validationPending?: boolean
-  /**
-   * Faut-il rafraîchir le profil à la soumission du formulaire ?
-   */
-  refreshProfile?: boolean
-}>(), {
-  id: null,
-  goBackRoute: null,
-  validationPending: false,
-  refreshProfile: false
-})
+const props = withDefaults(
+  defineProps<{
+    model: T
+    /**
+     * Id de l'objet
+     * Si non renseigné, le composant essaiera de l'extraire de la route actuelle
+     */
+    id?: number | null
+    /**
+     * Route de retour
+     */
+    goBackRoute?: RouteLocationRaw | null
+    /**
+     * La validation est en cours
+     */
+    validationPending?: boolean
+    /**
+     * Faut-il rafraîchir le profil à la soumission du formulaire ?
+     */
+    refreshProfile?: boolean
+  }>(),
+  {
+    id: null,
+    goBackRoute: null,
+    validationPending: false,
+    refreshProfile: false,
+  },
+)
 
 const { fetch } = useEntityFetch()
 const route = useRoute()

+ 10 - 2
components/Ui/Input/Autocomplete/Accesses.vue

@@ -36,7 +36,11 @@ import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import Access from '~/models/Access/Access'
 import Query from '~/services/data/Query'
 import OrderBy from '~/services/data/Filters/OrderBy'
-import {FETCHING_STATUS, ORDER_BY_DIRECTION, SEARCH_STRATEGY} from '~/types/enum/data'
+import {
+  FETCHING_STATUS,
+  ORDER_BY_DIRECTION,
+  SEARCH_STRATEGY,
+} from '~/types/enum/data'
 import PageFilter from '~/services/data/Filters/PageFilter'
 import InArrayFilter from '~/services/data/Filters/InArrayFilter'
 import SearchFilter from '~/services/data/Filters/SearchFilter'
@@ -199,7 +203,11 @@ const {
   refresh: refreshSearch,
 } = fetchCollection(UserSearchItem, null, querySearch)
 
-const pending = computed(() => statusSearch.value == FETCHING_STATUS.PENDING || statusActive.value == FETCHING_STATUS.PENDING)
+const pending = computed(
+  () =>
+    statusSearch.value == FETCHING_STATUS.PENDING ||
+    statusActive.value == FETCHING_STATUS.PENDING,
+)
 
 /**
  * Contenu de la liste autocomplete

+ 26 - 18
components/Ui/Input/Autocomplete/ApiResources.vue

@@ -38,18 +38,22 @@ Exemple : on souhaite lister les lieux d'une structure
 </template>
 
 <script setup lang="ts">
-import type {PropType, ComputedRef, Ref, WatchStopHandle} from 'vue'
+import type { PropType, ComputedRef, Ref, WatchStopHandle } from 'vue'
 import { computed } from 'vue'
 import * as _ from 'lodash-es'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import Query from '~/services/data/Query'
 import OrderBy from '~/services/data/Filters/OrderBy'
-import {FETCHING_STATUS, ORDER_BY_DIRECTION, SEARCH_STRATEGY} from '~/types/enum/data'
+import {
+  FETCHING_STATUS,
+  ORDER_BY_DIRECTION,
+  SEARCH_STRATEGY,
+} from '~/types/enum/data'
 import PageFilter from '~/services/data/Filters/PageFilter'
 import InArrayFilter from '~/services/data/Filters/InArrayFilter'
 import SearchFilter from '~/services/data/Filters/SearchFilter'
-import type ApiModel from "~/models/ApiModel";
-import PlaceSearchItem from "~/models/Custom/Search/PlaceSearchItem";
+import type ApiModel from '~/models/ApiModel'
+import PlaceSearchItem from '~/models/Custom/Search/PlaceSearchItem'
 
 const props = defineProps({
   /**
@@ -73,7 +77,7 @@ const props = defineProps({
   query: {
     type: Object as PropType<typeof Query | null>,
     required: false,
-    default: null
+    default: null,
   },
   /**
    * Nom de la propriété d'une entité lorsque l'input concerne cette propriété
@@ -181,18 +185,16 @@ const activeIds = computed(() => {
   return []
 })
 
-
 /**
  * Query transmise à l'API lors de l'initialisation afin de récupérer les items actifs
  */
 const queryActive = computed(() => {
   return new Query(
-      new OrderBy(props.listLabel, ORDER_BY_DIRECTION.ASC),
-      new PageFilter(ref(1), ref(20)),
-      new InArrayFilter(props.listValue, activeIds),
-    )
-  }
-)
+    new OrderBy(props.listLabel, ORDER_BY_DIRECTION.ASC),
+    new PageFilter(ref(1), ref(20)),
+    new InArrayFilter(props.listValue, activeIds),
+  )
+})
 
 /**
  * On commence par fetcher les models déjà actifs, pour affichage des labels correspondant
@@ -200,10 +202,10 @@ const queryActive = computed(() => {
 const {
   data: collectionActive,
   status: statusActive,
-  refresh: refreshActive
+  refresh: refreshActive,
 } = fetchCollection(props.model, null, queryActive.value)
 
-const unwatch: WatchStopHandle = watch(activeIds, ()=>{
+const unwatch: WatchStopHandle = watch(activeIds, () => {
   refreshActive()
 })
 
@@ -230,7 +232,11 @@ const {
 } = fetchCollection(props.model, null, querySearch)
 
 //Le pending global dépend des deux recherche (actif, et globale)
-const pending = computed(() => statusSearch.value == FETCHING_STATUS.PENDING || statusActive.value == FETCHING_STATUS.PENDING)
+const pending = computed(
+  () =>
+    statusSearch.value == FETCHING_STATUS.PENDING ||
+    statusActive.value == FETCHING_STATUS.PENDING,
+)
 
 /**
  * Génère un ListItem à partir des props
@@ -259,7 +265,9 @@ const items: ComputedRef<Array<ListItem>> = computed(() => {
     .map(item)
     .filter(
       (item) =>
-        !collectionActive.value!.items.find((other) => other[props.listValue] === item[props.listValue]),
+        !collectionActive.value!.items.find(
+          (other) => other[props.listValue] === item[props.listValue],
+        ),
     )
   return activeItems.concat(searchedItems)
 })
@@ -283,12 +291,12 @@ const refreshDebounced: _.DebouncedFunc<() => void> = _.debounce(async () => {
  */
 const onUpdateSearch = (event: string) => {
   let search = true
-  if(searchFilter.value === null){
+  if (searchFilter.value === null) {
     search = false
   }
 
   searchFilter.value = event
-  if(search){
+  if (search) {
     refreshDebounced()
   }
 }

+ 2 - 2
components/Ui/Input/Autocomplete/Enum.vue

@@ -3,7 +3,7 @@
     :model-value="modelValue"
     :field="field"
     :items="items"
-    :is-loading="status===FETCHING_STATUS.PENDING"
+    :is-loading="status === FETCHING_STATUS.PENDING"
     :return-object="false"
     item-title="label"
     item-value="value"
@@ -17,7 +17,7 @@ import type { ComputedRef, PropType } from 'vue'
 import { useEnumFetch } from '~/composables/data/useEnumFetch'
 import ArrayUtils from '~/services/utils/arrayUtils'
 import type { Enum } from '~/types/data'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 const emit = defineEmits(['update:model-value'])
 

+ 16 - 17
components/Ui/Input/DatePicker.vue

@@ -19,21 +19,21 @@ Sélecteur de dates, à placer dans un composant `UiForm`
         "
         :validate-on="'lazy input'"
       >
-          <UiDatePicker
-            v-model="date"
-            :readonly="readonly"
-            :with-time-picker="withTimePicker"
-            class="date-picker"
-            @update:model-value="onUpdate($event)"
-          />
-
-        <div v-if="errorMessages.value.length > 0" class="v-input__details error_message">
+        <UiDatePicker
+          v-model="date"
+          :readonly="readonly"
+          :with-time-picker="withTimePicker"
+          class="date-picker"
+          @update:model-value="onUpdate($event)"
+        />
+
+        <div
+          v-if="errorMessages.value.length > 0"
+          class="v-input__details error_message"
+        >
           <div class="v-messages__message">
-            <span
-              v-for="(msg, i) in errorMessages.value"
-              :key="i"
-            >
-                {{ msg }}
+            <span v-for="(msg, i) in errorMessages.value" :key="i">
+              {{ msg }}
             </span>
           </div>
         </div>
@@ -177,11 +177,10 @@ onBeforeUnmount(() => {
   }
 }
 
-.error_message{
+.error_message {
   padding-inline: 16px;
 }
-.v-messages__message{
+.v-messages__message {
   color: rgb(var(--v-theme-error));
-
 }
 </style>

+ 15 - 6
components/Ui/Input/DateTimePicker.vue

@@ -2,7 +2,11 @@
   <v-row>
     <v-col cols="12" md="6">
       <v-text-field
-        :model-value="dateModel ? _useDate.format(dateModel, 'fullDateWithWeekday') : undefined"
+        :model-value="
+          dateModel
+            ? _useDate.format(dateModel, 'fullDateWithWeekday')
+            : undefined
+        "
         :label="$t('choose_day')"
         prepend-icon="fas fa-calendar"
         :rules="rules"
@@ -63,7 +67,7 @@ import type { PropType, Ref } from 'vue'
 import { ref } from 'vue'
 import { useFieldViolation } from '~/composables/form/useFieldViolation'
 import { useDate } from 'vuetify'
-import DateUtils from "~/services/utils/dateUtils";
+import DateUtils from '~/services/utils/dateUtils'
 
 const props = defineProps({
   /**
@@ -149,8 +153,14 @@ const showMenuDate = ref(false)
 const _useDate = useDate()
 const { fieldViolations, updateViolationState } = useFieldViolation(props.field)
 
-const dateModel = computed(()=> props.modelValue ? new Date(props.modelValue) : undefined)
-const time = computed(()=>   props.modelValue ? _useDate.format(new Date(props.modelValue),'fullTime24h') : undefined)
+const dateModel = computed(() =>
+  props.modelValue ? new Date(props.modelValue) : undefined,
+)
+const time = computed(() =>
+  props.modelValue
+    ? _useDate.format(new Date(props.modelValue), 'fullTime24h')
+    : undefined,
+)
 const emit = defineEmits(['update:model-value'])
 
 const onUpdateDate = (event: string) => {
@@ -170,5 +180,4 @@ onBeforeUnmount(() => {
 })
 </script>
 
-<style scoped lang="scss">
-</style>
+<style scoped lang="scss"></style>

+ 1 - 4
components/Ui/Input/Email.vue

@@ -9,9 +9,7 @@ Champs de saisie de type Text dédié à la saisie d'emails
     :readonly="readonly"
     :rules="rules"
     :error="error || !!fieldViolations"
-    :error-messages="
-        errorMessage || fieldViolations ? $t(fieldViolations) : ''
-      "
+    :error-messages="errorMessage || fieldViolations ? $t(fieldViolations) : ''"
     @update:model-value="onUpdate($event)"
   />
 </template>
@@ -77,7 +75,6 @@ const props = defineProps({
   },
 })
 
-
 const i18n = useI18n()
 
 const fieldLabel = props.label ?? props.field

+ 2 - 2
components/Ui/Input/Number.vue

@@ -23,14 +23,14 @@ An input for numeric values
 
 <script setup lang="ts">
 import type { PropType, Ref } from 'vue'
-import {useFieldViolation} from "~/composables/form/useFieldViolation";
+import { useFieldViolation } from '~/composables/form/useFieldViolation'
 
 type ValidationRule = (value: string | number | null) => boolean | string
 
 const props = defineProps({
   modelValue: {
     type: Number,
-    required: true
+    required: true,
   },
   /**
    * Nom de la propriété d'une entité lorsque l'input concerne cette propriété

+ 4 - 8
components/Ui/Input/Phone.vue

@@ -12,13 +12,12 @@ Champs de saisie d'un numéro de téléphone
     :variant="variant"
     :label="label || field ? $t(label ?? field) : undefined"
     default-country="FR"
-    :invalid-message="(n) => $t('invalid_phone_number', { example: n.example})"
+    :invalid-message="(n) => $t('invalid_phone_number', { example: n.example })"
     @update:model-value="onUpdate($event)"
   />
 </template>
 
 <script setup lang="ts">
-
 type ValidationRule = (value: string | number | null) => boolean | string
 
 defineProps({
@@ -75,15 +74,12 @@ defineProps({
 
 const emit = defineEmits(['update:modelValue'])
 
-const onUpdate = (event: string|null) => {
-  if(event === ''){
+const onUpdate = (event: string | null) => {
+  if (event === '') {
     event = null
   }
   emit('update:modelValue', event)
 }
-
 </script>
 
-<style lang="scss">
-
-</style>
+<style lang="scss"></style>

+ 1 - 1
components/Ui/Input/TextArea.vue

@@ -22,7 +22,7 @@ Champs de saisie de bloc texte
 
 <script setup lang="ts">
 import { useFieldViolation } from '~/composables/form/useFieldViolation'
-import type {PropType} from "vue";
+import type { PropType } from 'vue'
 
 type ValidationRule = (value: string | number | null) => boolean | string
 

+ 49 - 30
components/Ui/Input/TreeSelect.vue

@@ -54,9 +54,7 @@ et sélectionner des éléments organisés en catégories et sous-catégories.
         closable
         @click:close="removeItem(item.raw.value!)"
       >
-        {{
-          selectedItemsMap[item.raw] || selectedItemsMap[item.raw.value]
-        }}
+        {{ selectedItemsMap[item.raw] || selectedItemsMap[item.raw.value] }}
       </v-chip>
       <span
         v-if="
@@ -152,7 +150,7 @@ et sélectionner des éléments organisés en catégories et sous-catégories.
 <script setup lang="ts">
 import StringUtils from '~/services/utils/stringUtils'
 import _ from 'lodash'
-import type {PropType} from "vue";
+import type { PropType } from 'vue'
 
 interface SelectItem {
   id: string
@@ -203,7 +201,7 @@ const props = defineProps({
     >,
     required: false,
     default: 'outlined',
-  }
+  },
 })
 
 const searchInput = ref()
@@ -230,7 +228,9 @@ const onKeyDown = (event: KeyboardEvent) => {
   // et les touches spéciales de navigation
   if (
     event.key.length === 1 || // Caractères simples (a, c, etc.)
-    ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)
+    ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(
+      event.key,
+    )
   ) {
     event.stopPropagation()
   }
@@ -250,9 +250,9 @@ const onKeyDown = (event: KeyboardEvent) => {
  * This avoids having to normalize labels during each search operation.
  */
 const normalizedItems = computed(() => {
-  return props.items.map(item => ({
+  return props.items.map((item) => ({
     ...item,
-    normalizedLabel: StringUtils.normalize(item.label)
+    normalizedLabel: StringUtils.normalize(item.label),
   }))
 })
 
@@ -270,17 +270,21 @@ const expandParentsOfSelectedItems = () => {
   expandedSubcategories.value.clear()
 
   for (const selectedId of props.modelValue) {
-    const item = normalizedItems.value.find(i => i.value === selectedId)
+    const item = normalizedItems.value.find((i) => i.value === selectedId)
     if (!item) continue
 
     // Trouver la sous-catégorie
-    const subcategory = normalizedItems.value.find(i => i.id === item.parentId)
+    const subcategory = normalizedItems.value.find(
+      (i) => i.id === item.parentId,
+    )
     if (subcategory) {
       expandedSubcategories.value.add(subcategory.id)
 
       // Trouver la catégorie
       if (subcategory.parentId) {
-        const category = normalizedItems.value.find(i => i.id === subcategory.parentId)
+        const category = normalizedItems.value.find(
+          (i) => i.id === subcategory.parentId,
+        )
         if (category) {
           expandedCategories.value.add(category.id)
         }
@@ -389,12 +393,16 @@ const onSearchInput = () => {
     // Pour chaque élément correspondant, ajouter ses parents aux ensembles d'expansion
     for (const item of matchingItems) {
       // Trouver et ajouter la sous-catégorie parente
-      const subcategory = normalizedItems.value.find((i) => i.id === item.parentId)
+      const subcategory = normalizedItems.value.find(
+        (i) => i.id === item.parentId,
+      )
       if (subcategory) {
         expandedSubcategories.value.add(subcategory.id)
 
         // Trouver et ajouter la catégorie parente
-        const category = normalizedItems.value.find((i) => i.id === subcategory.parentId)
+        const category = normalizedItems.value.find(
+          (i) => i.id === subcategory.parentId,
+        )
         if (category) {
           expandedCategories.value.add(category.id)
         }
@@ -428,8 +436,7 @@ const anyWordStartsWith = (
 
   return normalizedText
     .split(' ')
-    .some(word => word.startsWith(normalizedSearch))
-
+    .some((word) => word.startsWith(normalizedSearch))
 }
 
 /**
@@ -457,35 +464,40 @@ const itemMatchesSearch = (item: SelectItem): boolean => {
   const normalizedSearch = StringUtils.normalize(searchText.value)
 
   // Find the item with normalized label from our computed property
-  const itemWithNormalizedLabel = normalizedItems.value.find(i => i.id === item.id)
+  const itemWithNormalizedLabel = normalizedItems.value.find(
+    (i) => i.id === item.id,
+  )
   if (!itemWithNormalizedLabel) return false
 
   // Si c'est un élément de niveau 2, vérifier son label et les labels de ses parents
   if (item.type === 'item' && item.level === 2) {
     // Vérifier le label de l'élément
-    if (anyWordStartsWith(itemWithNormalizedLabel.normalizedLabel!, normalizedSearch))
+    if (
+      anyWordStartsWith(
+        itemWithNormalizedLabel.normalizedLabel!,
+        normalizedSearch,
+      )
+    )
       return true
 
     // Trouver et vérifier le label de la sous-catégorie parente
-    const subcategory = normalizedItems.value.find((i) => i.id === item.parentId)
+    const subcategory = normalizedItems.value.find(
+      (i) => i.id === item.parentId,
+    )
     if (
       subcategory &&
-      anyWordStartsWith(
-        subcategory.normalizedLabel!,
-        normalizedSearch,
-      )
+      anyWordStartsWith(subcategory.normalizedLabel!, normalizedSearch)
     )
       return true
 
     // Trouver et vérifier le label de la catégorie parente
     if (subcategory && subcategory.parentId) {
-      const category = normalizedItems.value.find((i) => i.id === subcategory.parentId)
+      const category = normalizedItems.value.find(
+        (i) => i.id === subcategory.parentId,
+      )
       if (
         category &&
-        anyWordStartsWith(
-          category.normalizedLabel!,
-          normalizedSearch,
-        )
+        anyWordStartsWith(category.normalizedLabel!, normalizedSearch)
       )
         return true
     }
@@ -494,7 +506,10 @@ const itemMatchesSearch = (item: SelectItem): boolean => {
   }
 
   // Pour les autres types d'éléments, vérifier simplement leur label
-  return anyWordStartsWith(itemWithNormalizedLabel.normalizedLabel!, normalizedSearch)
+  return anyWordStartsWith(
+    itemWithNormalizedLabel.normalizedLabel!,
+    normalizedSearch,
+  )
 }
 
 /**
@@ -523,11 +538,15 @@ const buildSearchResultsList = (matchingItems: SelectItem[]): SelectItem[] => {
 
   for (const item of matchingItems) {
     // Trouver la sous-catégorie parente
-    const subcategory = normalizedItems.value.find((i) => i.id === item.parentId)
+    const subcategory = normalizedItems.value.find(
+      (i) => i.id === item.parentId,
+    )
     if (!subcategory) continue
 
     // Trouver la catégorie parente
-    const category = normalizedItems.value.find((i) => i.id === subcategory.parentId)
+    const category = normalizedItems.value.find(
+      (i) => i.id === subcategory.parentId,
+    )
     if (!category) continue
 
     // Ajouter la catégorie si elle n'est pas déjà présente

+ 1 - 3
components/Ui/Input/TreeSelect/EventCategories.vue

@@ -13,7 +13,7 @@
 <script setup lang="ts">
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import EventCategory from '~/models/Core/EventCategory'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 const props = defineProps({
   modelValue: {
@@ -31,7 +31,6 @@ const props = defineProps({
   },
 })
 
-
 const i18n = useI18n()
 
 const emit = defineEmits(['update:modelValue'])
@@ -137,7 +136,6 @@ const hierarchicalItems = computed(() => {
   return result
 })
 
-
 // Nettoyer les données lors du démontage du composant
 onBeforeUnmount(() => {
   // Nettoyer les références du store si nécessaire

+ 69 - 56
components/Ui/MapLeaflet.client.vue

@@ -9,10 +9,9 @@
       :center="position"
       :use-global-leaflet="false"
     >
-
       <LTileLayer
         url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
-        attribution="&amp;copy; <a href=&quot;https://www.openstreetmap.org/&quot;>OpenStreetMap</a> contributors"
+        attribution='&amp;copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors'
         layer-type="base"
         name="OpenStreetMap"
       />
@@ -21,7 +20,7 @@
         :lat-lng="position"
         :draggable="!readonly"
         @update:lat-lng="onPositionUpdate($event)"
-         />
+      />
     </LMap>
 
     <v-btn
@@ -30,33 +29,35 @@
       class="mt-3"
       @click="search()"
     >
-      {{$t('search_gps_button')}}
+      {{ $t('search_gps_button') }}
     </v-btn>
 
     <div v-if="!pending && gpsResponses.length > 0">
-      <div v-for="(gpsResponse, key) in gpsResponses" :key="key" class="address_choices" @click="addressChoice(key)">
-        {{gpsResponse['displayName']}}
-        <v-btn
-          prepend-icon="fas fa-map-location"
-          @click="addressChoice(key)"
-        >Choisir</v-btn>
+      <div
+        v-for="(gpsResponse, key) in gpsResponses"
+        :key="key"
+        class="address_choices"
+        @click="addressChoice(key)"
+      >
+        {{ gpsResponse['displayName'] }}
+        <v-btn prepend-icon="fas fa-map-location" @click="addressChoice(key)"
+          >Choisir</v-btn
+        >
       </div>
     </div>
-
   </div>
 </template>
 
 <script setup lang="ts">
-
 import 'leaflet/dist/leaflet.css'
 import { LMap, LTileLayer, LMarker } from '@vue-leaflet/vue-leaflet'
-import {type ComputedRef, defineProps, type PropType} from 'vue'
-import {LatLng, type PointTuple} from 'leaflet'
-import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
-import UrlUtils from "~/services/utils/urlUtils";
-import type {AnyJson, CollectionResponsePromise} from "~/types/data";
-import Country from "~/models/Core/Country";
-import {useEntityManager} from "~/composables/data/useEntityManager";
+import { type ComputedRef, defineProps, type PropType } from 'vue'
+import { LatLng, type PointTuple } from 'leaflet'
+import { useAp2iRequestService } from '~/composables/data/useAp2iRequestService'
+import UrlUtils from '~/services/utils/urlUtils'
+import type { AnyJson, CollectionResponsePromise } from '~/types/data'
+import Country from '~/models/Core/Country'
+import { useEntityManager } from '~/composables/data/useEntityManager'
 
 const props = defineProps({
   latitude: {
@@ -67,40 +68,40 @@ const props = defineProps({
     type: Number as PropType<number | null>,
     required: true,
   },
-  streetAddress:{
+  streetAddress: {
     type: String as PropType<string | null>,
     required: false,
-    default: null
+    default: null,
   },
-  streetAddressSecond:{
+  streetAddressSecond: {
     type: String as PropType<string | null>,
     required: false,
-    default: null
+    default: null,
   },
-  streetAddressThird:{
+  streetAddressThird: {
     type: String as PropType<string | null>,
     required: false,
-    default: null
+    default: null,
   },
-  postalCode:{
+  postalCode: {
     type: String as PropType<string | null>,
     required: false,
-    default: null
+    default: null,
   },
-  addressCity:{
+  addressCity: {
     type: String as PropType<string | null>,
     required: false,
-    default: null
+    default: null,
   },
-  addressCountryId:{
+  addressCountryId: {
     type: Number as PropType<number | null>,
     required: false,
-    default: null
+    default: null,
   },
-  searchButton:{
+  searchButton: {
     type: Boolean,
     required: false,
-    default: false
+    default: false,
   },
   readonly: {
     type: Boolean,
@@ -111,11 +112,14 @@ const props = defineProps({
 
 const FRANCE_LATITUDE = 46.603354
 const FRANCE_LONGITUDE = 1.888334
-const {apiRequestService, pending} = useAp2iRequestService()
+const { apiRequestService, pending } = useAp2iRequestService()
 const { em } = useEntityManager()
 
-const position:ComputedRef<PointTuple> = computed(()=>{
-  return [props.latitude || FRANCE_LATITUDE, props.longitude || FRANCE_LONGITUDE]
+const position: ComputedRef<PointTuple> = computed(() => {
+  return [
+    props.latitude || FRANCE_LATITUDE,
+    props.longitude || FRANCE_LONGITUDE,
+  ]
 })
 
 const zoom = computed({
@@ -124,52 +128,61 @@ const zoom = computed({
   },
   set(newValue: string) {
     zoom.value = newValue
-  }
+  },
 })
 
 const emit = defineEmits(['update:latitude', 'update:longitude'])
 
-const onPositionUpdate = (event: LatLng):void => {
+const onPositionUpdate = (event: LatLng): void => {
   emit('update:latitude', event.lat)
   emit('update:longitude', event.lng)
 }
 
-const gpsResponses:Ref<Array<AnyJson>> = ref([])
+const gpsResponses: Ref<Array<AnyJson>> = ref([])
 const search = async () => {
   gpsResponses.value = []
   const baseUrl = UrlUtils.join('api', 'gps-coordinate-searching')
-  const query:AnyJson = {
-    'streetAddress': props.streetAddress,
-    'streetAddressSecond': props.streetAddressSecond,
-    'streetAddressThird': props.streetAddressThird,
-    'cp': props.postalCode,
-    'city': props.addressCity
+  const query: AnyJson = {
+    streetAddress: props.streetAddress,
+    streetAddressSecond: props.streetAddressSecond,
+    streetAddressThird: props.streetAddressThird,
+    cp: props.postalCode,
+    city: props.addressCity,
   }
 
-  if(props.addressCountryId){
-    const country:Country = em.find(Country, props.addressCountryId)
+  if (props.addressCountryId) {
+    const country: Country = em.find(Country, props.addressCountryId)
     query['country'] = country?.name
   }
 
   const url = UrlUtils.addQuery(baseUrl, query)
-  const responses:CollectionResponsePromise = await apiRequestService.get(url)
-
-  if(responses['member'].length > 0){
-    onPositionUpdate(new LatLng(responses['member'][0]['latitude'], responses['member'][0]['longitude']))
-    if(responses['member'].length > 1){
+  const responses: CollectionResponsePromise = await apiRequestService.get(url)
+
+  if (responses['member'].length > 0) {
+    onPositionUpdate(
+      new LatLng(
+        responses['member'][0]['latitude'],
+        responses['member'][0]['longitude'],
+      ),
+    )
+    if (responses['member'].length > 1) {
       zoom.value = 6
       gpsResponses.value = responses['member']
-    }else{
+    } else {
       zoom.value = 12
     }
   }
 }
 
-const addressChoice = (key:number):void => {
+const addressChoice = (key: number): void => {
   zoom.value = 12
-  onPositionUpdate(new LatLng(gpsResponses.value[key]['latitude'] as number, gpsResponses.value[key]['longitude']  as number))
+  onPositionUpdate(
+    new LatLng(
+      gpsResponses.value[key]['latitude'] as number,
+      gpsResponses.value[key]['longitude'] as number,
+    ),
+  )
 }
-
 </script>
 
 <style scoped lang="scss">

+ 9 - 11
composables/data/useEntityFetch.ts

@@ -13,13 +13,13 @@ import type Query from '~/services/data/Query'
 interface useEntityFetchReturnType {
   fetch: <T extends typeof ApiResource>(
     model: T,
-    id?: number | null
+    id?: number | null,
   ) => AsyncData<InstanceType<T> | null, Error | null>
 
   fetchCollection: <T extends typeof ApiResource>(
     model: T,
     parent?: T | null,
-    query?: typeof Query | Query| null,
+    query?: typeof Query | Query | null,
   ) => {
     data: ComputedRef<Collection<InstanceType<T>> | null>
     refresh: (
@@ -40,7 +40,10 @@ export const useEntityFetch = (
 ): useEntityFetchReturnType => {
   const { em } = useEntityManager()
 
-  const fetch = <T extends typeof ApiResource>(model: T, id?: number|null): AsyncData<InstanceType<T> | null, Error | null> => {
+  const fetch = <T extends typeof ApiResource>(
+    model: T,
+    id?: number | null,
+  ): AsyncData<InstanceType<T> | null, Error | null> => {
     return useAsyncData(
       model.entity + '_' + id + '_' + uuid4(),
       () => em.fetch(model, id),
@@ -48,17 +51,12 @@ export const useEntityFetch = (
     )
   }
 
-  const fetchCollection = <T extends typeof ApiResource> (
+  const fetchCollection = <T extends typeof ApiResource>(
     model: T,
     parent: T | null = null,
     query: Query | null = null,
-  )  => {
-    const {
-      data,
-      refresh,
-      error,
-      status
-    } = useAsyncData(
+  ) => {
+    const { data, refresh, error, status } = useAsyncData(
       model.entity + '_many_' + uuid4(),
       () => em.fetchCollection(model, parent, query),
       { lazy, deep: true },

+ 3 - 3
composables/data/useEntityManager.ts

@@ -2,15 +2,15 @@ import { useRepo } from 'pinia-orm'
 import EntityManager from '~/services/data/entityManager'
 import { useAp2iRequestService } from '~/composables/data/useAp2iRequestService'
 import { useAccessProfileStore } from '~/stores/accessProfile'
-import type ApiResource from "~/models/ApiResource";
-import type {AsyncData} from "#app";
+import type ApiResource from '~/models/ApiResource'
+import type { AsyncData } from '#app'
 
 let entityManager: EntityManager | null = null
 
 interface _useEntityManagerReturnType {
   fetch: <T extends typeof ApiResource>(
     model: T,
-    id?: number | null
+    id?: number | null,
   ) => AsyncData<InstanceType<T> | null, Error | null>
 }
 

+ 1 - 1
composables/form/useDeleteItem.ts

@@ -4,7 +4,7 @@ import { TYPE_ALERT } from '~/types/enum/enums'
 import { useEntityManager } from '~/composables/data/useEntityManager'
 
 export function useDeleteItem() {
-  async function deleteItem <T extends ApiResource>(item: T) {
+  async function deleteItem<T extends ApiResource>(item: T) {
     const { em } = useEntityManager()
 
     try {

+ 3 - 3
composables/utils/useHomeUrl.ts

@@ -1,15 +1,15 @@
 import { useAdminUrl } from '~/composables/utils/useAdminUrl'
-import {useAbility} from "@casl/vue";
+import { useAbility } from '@casl/vue'
 export const useHomeUrl = () => {
   const ability = useAbility()
 
   let homeUrl = null
 
-  if(ability.can('display', 'freemium_dashboard_page')){
+  if (ability.can('display', 'freemium_dashboard_page')) {
     const router = useRouter()
     const to = router.resolve({ name: 'freemium_dashboard_page' })
     homeUrl = to.href
-  }else{
+  } else {
     const { makeAdminUrl } = useAdminUrl()
     homeUrl = makeAdminUrl('dashboard')
   }

+ 1 - 1
eslint.config.mjs

@@ -51,7 +51,7 @@ const customConfig = [
       'vue/multi-word-component-names': 0,
       '@typescript-eslint/no-inferrable-types': 0,
       '@typescript-eslint/no-extraneous-class': 0,
-      'vue/html-self-closing': 0
+      'vue/html-self-closing': 0,
     },
   },
   // Directory-specific configurations

+ 109 - 62
layouts/freemium.vue

@@ -9,7 +9,6 @@
       <LayoutHeader />
 
       <v-main class="main">
-
         <!-- Page will be rendered here-->
         <div>
           <LayoutSubheader />
@@ -22,73 +21,121 @@
 
       <!-- Footer -->
       <v-footer class="white--text footer theme-secondary">
-
-          <v-row v-if="smAndUp">
-            <v-col cols="12" sm="3">
-              <p class="text-h6 font-weight-bold text-center">{{$t('DÉCOUVREZ NOS SOLUTIONS')}}</p>
-            </v-col>
-            <v-col cols="12" sm="2" class="text-center text-product">
-              <a href="https://logiciels.opentalent.fr/opentalent-artist" target="_blank">
-                <img src="/images/Opentalent_Artist-Blanc.png" height="70" class="mb-2" />
-                <p>{{$t('artist_def')}}</p>
-              </a>
-            </v-col>
-            <v-col cols="12" sm="2" class="text-center text-product">
-              <a href="https://logiciels.opentalent.fr/opentalent-school" target="_blank">
-                <img src="/images/Opentalent_School-Blanc.png" height="70" class="mb-2" />
-                <p>{{$t('school_def')}}</p>
-              </a>
-            </v-col>
-            <v-col cols="12" sm="2" class="text-center text-product">
-              <a href="https://logiciels.opentalent.fr/opentalent-manager" target="_blank">
-                <img src="/images/Opentalent_Manager-Blanc.png" height="70" class="mb-2" />
-                <p>{{$t('manager_def')}}</p>
-              </a>
-            </v-col>
-            <v-col cols="12" sm="2" class="text-center text-product">
-              <a href="https://opentalent.fr/" target="_blank">
-                <img src="/images/OT_Logo_Agenda.png" height="70" class="mb-2" />
-                <p>{{$t('agenda_def')}}</p>
-              </a>
-            </v-col>
-          </v-row>
-
-          <v-row v-else>
-            <v-col cols="12">
-              <p class="text-h6 font-weight-bold text-center">{{$t('DÉCOUVREZ NOS SOLUTIONS')}}</p>
-            </v-col>
-            <v-col cols="3" class="text-center text-product">
-              <a href="https://logiciels.opentalent.fr/opentalent-artist" target="_blank">
-                <img src="/images/Opentalent_Artist_Griffe.png" height="70" class="mb-2" />
-              </a>
-            </v-col>
-            <v-col cols="3" class="text-center text-product">
-              <a href="https://logiciels.opentalent.fr/opentalent-school" target="_blank">
-                <img src="/images/Opentalent_School_Griffe.png" height="70" class="mb-2" />
-              </a>
-            </v-col>
-            <v-col cols="3" class="text-center text-product">
-              <a href="https://logiciels.opentalent.fr/opentalent-manager" target="_blank">
-                <img src="/images/Opentalent_Manager_Griffe.png" height="70" class="mb-2" />
-              </a>
-            </v-col>
-            <v-col cols="3" class="text-center text-product">
-              <a href="https://opentalent.fr" target="_blank">
-                <img src="/images/Opentalent_Griffe.png" height="70" class="mb-2" />
-              </a>
-            </v-col>
-          </v-row>
+        <v-row v-if="smAndUp">
+          <v-col cols="12" sm="3">
+            <p class="text-h6 font-weight-bold text-center">
+              {{ $t('DÉCOUVREZ NOS SOLUTIONS') }}
+            </p>
+          </v-col>
+          <v-col cols="12" sm="2" class="text-center text-product">
+            <a
+              href="https://logiciels.opentalent.fr/opentalent-artist"
+              target="_blank"
+            >
+              <img
+                src="/images/Opentalent_Artist-Blanc.png"
+                height="70"
+                class="mb-2"
+              />
+              <p>{{ $t('artist_def') }}</p>
+            </a>
+          </v-col>
+          <v-col cols="12" sm="2" class="text-center text-product">
+            <a
+              href="https://logiciels.opentalent.fr/opentalent-school"
+              target="_blank"
+            >
+              <img
+                src="/images/Opentalent_School-Blanc.png"
+                height="70"
+                class="mb-2"
+              />
+              <p>{{ $t('school_def') }}</p>
+            </a>
+          </v-col>
+          <v-col cols="12" sm="2" class="text-center text-product">
+            <a
+              href="https://logiciels.opentalent.fr/opentalent-manager"
+              target="_blank"
+            >
+              <img
+                src="/images/Opentalent_Manager-Blanc.png"
+                height="70"
+                class="mb-2"
+              />
+              <p>{{ $t('manager_def') }}</p>
+            </a>
+          </v-col>
+          <v-col cols="12" sm="2" class="text-center text-product">
+            <a href="https://opentalent.fr/" target="_blank">
+              <img src="/images/OT_Logo_Agenda.png" height="70" class="mb-2" />
+              <p>{{ $t('agenda_def') }}</p>
+            </a>
+          </v-col>
+        </v-row>
+
+        <v-row v-else>
+          <v-col cols="12">
+            <p class="text-h6 font-weight-bold text-center">
+              {{ $t('DÉCOUVREZ NOS SOLUTIONS') }}
+            </p>
+          </v-col>
+          <v-col cols="3" class="text-center text-product">
+            <a
+              href="https://logiciels.opentalent.fr/opentalent-artist"
+              target="_blank"
+            >
+              <img
+                src="/images/Opentalent_Artist_Griffe.png"
+                height="70"
+                class="mb-2"
+              />
+            </a>
+          </v-col>
+          <v-col cols="3" class="text-center text-product">
+            <a
+              href="https://logiciels.opentalent.fr/opentalent-school"
+              target="_blank"
+            >
+              <img
+                src="/images/Opentalent_School_Griffe.png"
+                height="70"
+                class="mb-2"
+              />
+            </a>
+          </v-col>
+          <v-col cols="3" class="text-center text-product">
+            <a
+              href="https://logiciels.opentalent.fr/opentalent-manager"
+              target="_blank"
+            >
+              <img
+                src="/images/Opentalent_Manager_Griffe.png"
+                height="70"
+                class="mb-2"
+              />
+            </a>
+          </v-col>
+          <v-col cols="3" class="text-center text-product">
+            <a href="https://opentalent.fr" target="_blank">
+              <img
+                src="/images/Opentalent_Griffe.png"
+                height="70"
+                class="mb-2"
+              />
+            </a>
+          </v-col>
+        </v-row>
       </v-footer>
 
       <LazyLayoutAlertContainer />
-
     </v-app>
   </div>
 </template>
 
 <script setup lang="ts">
 import { useLayoutStore } from '~/stores/layout'
-import {useDisplay} from "vuetify";
+import { useDisplay } from 'vuetify'
 
 const { smAndUp, sm } = useDisplay()
 const layoutStore = useLayoutStore()
@@ -109,7 +156,7 @@ const pageTitle = computed(() => i18n.t(route.name || 'freemium_page'))
 }
 
 .main {
-  flex: 1 0 auto;  /* Prend tout l’espace restant */
+  flex: 1 0 auto; /* Prend tout l’espace restant */
 }
 
 .v-footer {
@@ -119,11 +166,11 @@ const pageTitle = computed(() => i18n.t(route.name || 'freemium_page'))
   padding-bottom: 20px;
   flex: 0 0 auto !important;
 
-  .text-product{
+  .text-product {
     font-size: 13px;
   }
 
-  a{
+  a {
     color: white;
     text-decoration: none;
   }

+ 2 - 2
models/Billing/ResidenceArea.ts

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

+ 2 - 2
models/Booking/AttendanceBookingReason.ts

@@ -1,6 +1,6 @@
 import { Str, Uid } from 'pinia-orm/dist/decorators'
 import ApiModel from '~/models/ApiModel'
-import {Assert} from "~/models/decorators";
+import { Assert } from '~/models/decorators'
 
 /**
  * Motif d'absence ou de retard
@@ -14,6 +14,6 @@ export default class AttendanceBookingReason extends ApiModel {
   declare id: number | string
 
   @Str(null)
-  @Assert({'nullable': false, 'max':255})
+  @Assert({ nullable: false, max: 255 })
   declare reason: string | null
 }

+ 2 - 2
models/Education/Cycle.ts

@@ -1,6 +1,6 @@
 import { Num, Str, Uid } from 'pinia-orm/dist/decorators'
 import ApiModel from '~/models/ApiModel'
-import {Assert} from "~/models/decorators";
+import { Assert } from '~/models/decorators'
 
 /**
  * AP2i Model: Cycle
@@ -14,7 +14,7 @@ export default class Cycle extends ApiModel {
   declare id: number | string | null
 
   @Str(null)
-  @Assert({'nullable': false, 'max':255})
+  @Assert({ nullable: false, max: 255 })
   declare label: string | null
 
   @Str(null)

+ 2 - 2
models/Education/EducationTiming.ts

@@ -1,6 +1,6 @@
 import { Num, Uid } from 'pinia-orm/dist/decorators'
 import ApiModel from '~/models/ApiModel'
-import {Assert} from "~/models/decorators";
+import { Assert } from '~/models/decorators'
 
 /**
  * AP2i Model : EducationTiming
@@ -14,6 +14,6 @@ export default class EducationTiming extends ApiModel {
   declare id: number | string
 
   @Num(null)
-  @Assert({'nullable': false, 'type' : 'integer'})
+  @Assert({ nullable: false, type: 'integer' })
   declare timing: number
 }

+ 9 - 9
models/Freemium/Event.ts

@@ -1,10 +1,10 @@
-import { Str, Uid,Attr, Num } from 'pinia-orm/dist/decorators'
+import { Str, Uid, Attr, Num } from 'pinia-orm/dist/decorators'
 import ApiModel from '~/models/ApiModel'
-import {Assert, IriEncoded} from '~/models/decorators'
-import File from "~/models/Core/File";
-import Place from "~/models/Place/Place";
-import Country from "~/models/Core/Country";
-import Category from "~/models/Core/Category";
+import { Assert, IriEncoded } from '~/models/decorators'
+import File from '~/models/Core/File'
+import Place from '~/models/Place/Place'
+import Country from '~/models/Core/Country'
+import Category from '~/models/Core/Category'
 
 /**
  * AP2i Model : Freemium / Event
@@ -17,15 +17,15 @@ export default class Event extends ApiModel {
   declare id: number | string | null
 
   @Str(null)
-  @Assert({'nullable': false, 'max':255})
+  @Assert({ nullable: false, max: 255 })
   declare name: string | null
 
   @Str(null)
-  @Assert({'nullable': false})
+  @Assert({ nullable: false })
   declare datetimeStart: string
 
   @Str(null)
-  @Assert({'nullable': false})
+  @Assert({ nullable: false })
   declare datetimeEnd: string
 
   @Str(null)

+ 10 - 10
models/Freemium/Organization.ts

@@ -1,8 +1,8 @@
-import { Str, Uid,Attr, Bool, Num } from 'pinia-orm/dist/decorators'
+import { Str, Uid, Attr, Bool, Num } from 'pinia-orm/dist/decorators'
 import ApiModel from '~/models/ApiModel'
-import {Assert, IdLess, IriEncoded} from '~/models/decorators'
-import Country from "~/models/Core/Country";
-import File from "~/models/Core/File";
+import { Assert, IdLess, IriEncoded } from '~/models/decorators'
+import Country from '~/models/Core/Country'
+import File from '~/models/Core/File'
 
 /**
  * AP2i Model : Freemium / Organization
@@ -16,14 +16,14 @@ export default class Organization extends ApiModel {
   declare id: number | string | null
 
   @Str(null)
-  @Assert({'nullable': false, 'max':128})
+  @Assert({ nullable: false, max: 128 })
   declare name: string | null
 
   @Str(null)
   declare description: string | null
 
   @Str(null)
-  @Assert({'nullable': false, 'type' : 'email'})
+  @Assert({ nullable: false, type: 'email' })
   declare email: string | null
 
   @Str(null)
@@ -55,19 +55,19 @@ export default class Organization extends ApiModel {
   declare longitude: number | null
 
   @Str(null)
-  @Assert({'max':255})
+  @Assert({ max: 255 })
   declare facebook: string
 
   @Str(null)
-  @Assert({'max':255})
+  @Assert({ max: 255 })
   declare twitter: string
 
   @Str(null)
-  @Assert({'max':255})
+  @Assert({ max: 255 })
   declare youtube: string
 
   @Str(null)
-  @Assert({'max':255})
+  @Assert({ max: 255 })
   declare instagram: string
 
   @Bool(true)

+ 4 - 4
models/Freemium/Place.ts

@@ -1,7 +1,7 @@
-import { Str, Uid,Attr, Num } from 'pinia-orm/dist/decorators'
+import { Str, Uid, Attr, Num } from 'pinia-orm/dist/decorators'
 import ApiModel from '~/models/ApiModel'
-import {Assert, IriEncoded} from '~/models/decorators'
-import Country from "~/models/Core/Country";
+import { Assert, IriEncoded } from '~/models/decorators'
+import Country from '~/models/Core/Country'
 
 /**
  * AP2i Model : Freemium / Place
@@ -17,7 +17,7 @@ export default class Place extends ApiModel {
   declare EventId: number | null
 
   @Str(null)
-  @Assert({'nullable': false, 'max':255})
+  @Assert({ nullable: false, max: 255 })
   declare name: string | null
 
   @Str(null)

+ 2 - 2
models/Organization/Parameters.ts

@@ -1,7 +1,7 @@
 import { Bool, Num, Str, Uid, Attr } from 'pinia-orm/dist/decorators'
 import ApiModel from '~/models/ApiModel'
 import Access from '~/models/Access/Access'
-import {Assert, IriEncoded} from '~/models/decorators'
+import { Assert, IriEncoded } from '~/models/decorators'
 import File from '~/models/Core/File'
 
 /**
@@ -141,7 +141,7 @@ export default class Parameters extends ApiModel {
   declare notifyAdministrationAbsence: boolean
 
   @Num(2, { notNullable: true })
-  @Assert({'nullable': false, 'type' : 'integer'})
+  @Assert({ nullable: false, type: 'integer' })
   declare numberConsecutiveAbsences: number
 
   @Bool(false, { notNullable: false })

+ 95 - 60
pages/freemium/dashboard.vue

@@ -6,35 +6,46 @@
         <v-col cols="12" md="7">
           <v-card>
             <v-tabs v-model="tab" class="tabs-title">
-              <v-tab value="future">{{$t('futur_event')}}</v-tab>
-              <v-tab value="past">{{$t('past_event')}}</v-tab>
+              <v-tab value="future">{{ $t('futur_event') }}</v-tab>
+              <v-tab value="past">{{ $t('past_event') }}</v-tab>
             </v-tabs>
 
-            <v-btn color="primary" to="events/new" class="ml-5 mt-5">{{$t('add_event')}}</v-btn>
+            <v-btn color="primary" to="events/new" class="ml-5 mt-5">{{
+              $t('add_event')
+            }}</v-btn>
 
             <v-tabs-window v-model="tab">
               <v-tabs-window-item value="future">
-                <UiLoadingPanel v-if="statusUpcomingEvents == FETCHING_STATUS.PENDING" />
+                <UiLoadingPanel
+                  v-if="statusUpcomingEvents == FETCHING_STATUS.PENDING"
+                />
 
                 <span v-if="upcomingEvents.items.length == 0" class="no_event">
-                  {{$t('no_future_event')}}
+                  {{ $t('no_future_event') }}
                 </span>
                 <UiEventList
-                  v-if="statusUpcomingEvents == FETCHING_STATUS.SUCCESS && upcomingEvents?.items"
+                  v-if="
+                    statusUpcomingEvents == FETCHING_STATUS.SUCCESS &&
+                    upcomingEvents?.items
+                  "
                   :events="upcomingEvents.items"
                   :pagination="upcomingEvents.pagination"
                   @load="loadUpcomingEvents"
                   @edit="editEvent"
                 />
-
               </v-tabs-window-item>
               <v-tabs-window-item value="past">
-                <UiLoadingPanel v-if="statusPastEvents == FETCHING_STATUS.PENDING" />
+                <UiLoadingPanel
+                  v-if="statusPastEvents == FETCHING_STATUS.PENDING"
+                />
                 <span v-if="pastEvents.items.length == 0" class="no_event">
-                  {{$t('no_past_event')}}
+                  {{ $t('no_past_event') }}
                 </span>
                 <UiEventList
-                  v-if="statusPastEvents == FETCHING_STATUS.SUCCESS && pastEvents?.items"
+                  v-if="
+                    statusPastEvents == FETCHING_STATUS.SUCCESS &&
+                    pastEvents?.items
+                  "
                   :events="pastEvents.items"
                   :pagination="pastEvents.pagination"
                   @load="loadPastEvents"
@@ -42,34 +53,44 @@
                 />
               </v-tabs-window-item>
             </v-tabs-window>
-
           </v-card>
         </v-col>
 
         <!-- Bloc structure -->
         <v-col cols="12" md="5">
-          <v-card v-if="statusOrganization == FETCHING_STATUS.SUCCESS" class="pa-5">
-            <v-card-title class="text-h6" >
-              <v-icon icon="fa fa-hotel" class="text-button icon-hotel"  />
-              <span class="organization_title">{{$t('my_organization')}}</span>
+          <v-card
+            v-if="statusOrganization == FETCHING_STATUS.SUCCESS"
+            class="pa-5"
+          >
+            <v-card-title class="text-h6">
+              <v-icon icon="fa fa-hotel" class="text-button icon-hotel" />
+              <span class="organization_title">{{
+                $t('my_organization')
+              }}</span>
             </v-card-title>
             <v-card-text>
-              <div><strong>{{$t('name')}} :</strong> {{ organization?.name }}</div>
-              <div><strong>{{$t('email')}} :</strong> {{ organization?.email }}</div>
+              <div>
+                <strong>{{ $t('name') }} :</strong> {{ organization?.name }}
+              </div>
+              <div>
+                <strong>{{ $t('email') }} :</strong> {{ organization?.email }}
+              </div>
             </v-card-text>
           </v-card>
 
           <v-btn block class="mb-2 btn btn_edit_orga" to="organization">
-            <i class="fa fa-pen mr-2" />{{$t('edit_organization')}}
+            <i class="fa fa-pen mr-2" />{{ $t('edit_organization') }}
           </v-btn>
 
           <v-btn block class="text-black btn btn_trial" @click="startTrial">
-            <span><v-icon icon="fa fa-ticket" /> {{$t('try_premium_light')}}<br /> {{$t('30_days_free')}}</span>
+            <span
+              ><v-icon icon="fa fa-ticket" /> {{ $t('try_premium_light')
+              }}<br />
+              {{ $t('30_days_free') }}</span
+            >
           </v-btn>
-
         </v-col>
       </v-row>
-
     </v-container>
 
     <LayoutDialogTrialAlreadyDid
@@ -80,23 +101,26 @@
 </template>
 
 <script setup lang="ts">
-
-import Query from "~/services/data/Query";
-
-import {type Ref, ref} from 'vue'
-import {useEntityFetch} from "~/composables/data/useEntityFetch";
-import Organization from "~/models/Freemium/Organization";
-import Event from "~/models/Freemium/Event";
-import type {AsyncData} from "#app";
-import OrderBy from "~/services/data/Filters/OrderBy";
-import {FETCHING_STATUS, ORDER_BY_DIRECTION, TIME_STRATEGY} from "~/types/enum/data";
-import PageFilter from "~/services/data/Filters/PageFilter";
-import TimeFilter from "~/services/data/Filters/TimeFilter";
-import Country from "~/models/Core/Country";
-import DateUtils from "~/services/utils/dateUtils";
-import UrlUtils from "~/services/utils/urlUtils";
-import {useApiLegacyRequestService} from "~/composables/data/useApiLegacyRequestService";
-import {useAdminUrl} from "~/composables/utils/useAdminUrl";
+import Query from '~/services/data/Query'
+
+import { type Ref, ref } from 'vue'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import Organization from '~/models/Freemium/Organization'
+import Event from '~/models/Freemium/Event'
+import type { AsyncData } from '#app'
+import OrderBy from '~/services/data/Filters/OrderBy'
+import {
+  FETCHING_STATUS,
+  ORDER_BY_DIRECTION,
+  TIME_STRATEGY,
+} from '~/types/enum/data'
+import PageFilter from '~/services/data/Filters/PageFilter'
+import TimeFilter from '~/services/data/Filters/TimeFilter'
+import Country from '~/models/Core/Country'
+import DateUtils from '~/services/utils/dateUtils'
+import UrlUtils from '~/services/utils/urlUtils'
+import { useApiLegacyRequestService } from '~/composables/data/useApiLegacyRequestService'
+import { useAdminUrl } from '~/composables/utils/useAdminUrl'
 
 definePageMeta({
   name: 'freemium_dashboard_page',
@@ -106,16 +130,24 @@ definePageMeta({
 const runtimeConfig = useRuntimeConfig()
 const { fetch, fetchCollection } = useEntityFetch()
 const { apiRequestService } = useApiLegacyRequestService()
-const {makeAdminUrl} = useAdminUrl()
+const { makeAdminUrl } = useAdminUrl()
 const tab = ref(null)
 const upcomingPage = ref(1)
 const pastPage = ref(1)
 const showDialogTrialAlReadyDid: Ref<boolean> = ref(false)
 
 //Fetch
-const { data: organization, status:statusOrganization } = fetch(Organization)
-const { data: upcomingEvents, status: statusUpcomingEvents, refresh: refreshUpcomingEvents } = fetchEvents()
-const { data: pastEvents, status: statusPastEvents, refresh: refreshPastEvents } = fetchEvents(true)
+const { data: organization, status: statusOrganization } = fetch(Organization)
+const {
+  data: upcomingEvents,
+  status: statusUpcomingEvents,
+  refresh: refreshUpcomingEvents,
+} = fetchEvents()
+const {
+  data: pastEvents,
+  status: statusPastEvents,
+  refresh: refreshPastEvents,
+} = fetchEvents(true)
 
 /**
  * Charge une page des événements à venir
@@ -147,14 +179,20 @@ function editEvent(eventId: number) {
  * Récupère la liste des événements
  * @param past
  */
-function fetchEvents(past:boolean = false){
+function fetchEvents(past: boolean = false) {
   const today = computed(() => DateUtils.formatIsoShortDate(new Date()))
-  const query =
-    new Query(
-      new OrderBy('datetimeStart', past ? ORDER_BY_DIRECTION.DESC : ORDER_BY_DIRECTION.ASC),
-      new PageFilter(past ? pastPage : upcomingPage, ref(5)),
-      new TimeFilter('datetimeStart', today, past ? TIME_STRATEGY.BEFORE : TIME_STRATEGY.AFTER)
-    )
+  const query = new Query(
+    new OrderBy(
+      'datetimeStart',
+      past ? ORDER_BY_DIRECTION.DESC : ORDER_BY_DIRECTION.ASC,
+    ),
+    new PageFilter(past ? pastPage : upcomingPage, ref(5)),
+    new TimeFilter(
+      'datetimeStart',
+      today,
+      past ? TIME_STRATEGY.BEFORE : TIME_STRATEGY.AFTER,
+    ),
+  )
 
   return fetchCollection(Event, null, query)
 }
@@ -181,37 +219,34 @@ onUnmounted(() => {
   useRepo(Event).flush()
   useRepo(Country).flush()
 })
-
 </script>
 
 <style scoped lang="scss">
-
-.tabs-title{
+.tabs-title {
   margin-top: 20px;
   padding-left: 20px;
   background-color: rgb(var(--v-theme-neutral));
-  .v-tab--selected{
+  .v-tab--selected {
     color: rgb(var(--v-theme-on-neutral--clickable));
   }
 }
 
-
 .v-card {
   margin-bottom: 16px;
   color: rgb(var(--v-theme-on-primary-alt));
 }
 
-.v-card-text{
-  div{
+.v-card-text {
+  div {
     line-height: 2;
   }
 }
 
-.organization_title{
+.organization_title {
   font-weight: 500;
 }
 
-.icon-hotel{
+.icon-hotel {
   margin: 0 5px 4px 0;
 }
 
@@ -241,11 +276,11 @@ onUnmounted(() => {
   }
 }
 
-.btn_edit_orga{
+.btn_edit_orga {
   color: rgb(var(--v-theme-on-primary-alt)) !important;
 }
 
-.no_event{
+.no_event {
   padding: 25px;
   font-size: 16px;
   display: block;

+ 1 - 4
pages/freemium/events/[id].vue

@@ -11,18 +11,15 @@
 </template>
 
 <script setup lang="ts">
-import Event from "~/models/Freemium/Event";
+import Event from '~/models/Freemium/Event'
 
 definePageMeta({
   name: 'freemium_event_edit_page',
 })
-
 </script>
 
 <style scoped lang="scss">
-
 .inner-container {
   max-width: 1200px;
 }
-
 </style>

+ 1 - 4
pages/freemium/events/new.vue

@@ -11,18 +11,15 @@
 </template>
 
 <script setup lang="ts">
-import Event from "~/models/Freemium/Event";
+import Event from '~/models/Freemium/Event'
 
 definePageMeta({
   name: 'freemium_event_create_page',
 })
-
 </script>
 
 <style scoped lang="scss">
-
 .inner-container {
   max-width: 1200px;
 }
-
 </style>

+ 126 - 112
pages/freemium/organization.vue

@@ -1,116 +1,133 @@
 <template>
-      <UiFormEdition
-:model="Organization"
-                     class="inner-container"
-      >
-        <template #default="{ entity : organization }">
-          <div v-if="organization">
-            <LayoutCommonSection>
-              <v-row>
-                <v-col cols="12">
-                  <h4 class="mb-8">{{ $t('general_informations') }}</h4>
-
-                  <UiInputText v-model="organization.name" field="name" :rules="getAsserts('name')" />
-
-                  <UiInputTextArea v-model="organization.description" field="description"  />
-
-                  <UiInputImage
-                    v-model="organization.logo"
-                    field="logo"
-                    :width="120"
-                    :cropping-enabled="true"
-                  />
-                </v-col>
-
-              </v-row>
-            </LayoutCommonSection>
-
-            <LayoutCommonSection>
-              <v-row>
-                <v-col cols="12">
-                  <h4 class="mb-8">{{ $t('coordinate') }}</h4>
-
-                  <UiInputText v-model="organization.email" field="email" :rules="getAsserts('email')" />
-
-                  <UiInputPhone v-model="organization.tel" field="tel"/>
-
-                </v-col>
-              </v-row>
-            </LayoutCommonSection>
-
-            <LayoutCommonSection>
-              <v-row>
-                <v-col cols="12">
-                  <h4 class="mb-8">{{ $t('postal_address') }}</h4>
-
-                  <UiInputText v-model="organization.streetAddress" field="streetAddress" />
-
-                  <UiInputText v-model="organization.streetAddressSecond" field="streetAddressSecond" />
-
-                  <UiInputText v-model="organization.streetAddressThird" field="streetAddressThird" />
-
-                  <UiInputText v-model="organization.postalCode" field="postalCode" />
-
-                  <UiInputText v-model="organization.addressCity" field="addressCity" />
-
-                  <UiInputAutocompleteApiResources
-                    v-model="organization.addressCountry"
-                    field="addressCountry"
-                    :model="Country"
-                    list-value="id"
-                    list-label="name"
-                  />
-
-                  <client-only>
-                    <UiMapLeaflet
-                      v-model:latitude="organization.latitude"
-                      v-model:longitude="organization.longitude"
-                      :street-address="organization.streetAddress"
-                      :street-address-second="organization.streetAddressSecond"
-                      :street-address-third="organization.streetAddressThird"
-                      :postal-code="organization.postalCode"
-                      :address-city="organization.addressCity"
-                      :address-country-id="organization.addressCountry"
-                      :search-button="true"
-                    ></UiMapLeaflet>
-                  </client-only>
-
-                </v-col>
-              </v-row>
-            </LayoutCommonSection>
-
-            <LayoutCommonSection>
-              <v-row>
-                <v-col cols="12">
-
-                  <h4 class="mb-8">{{ $t('communication_params') }}</h4>
-
-                  <UiInputText v-model="organization.facebook" field="facebook" />
-
-                  <UiInputText v-model="organization.twitter" field="twitter" />
-
-                  <UiInputText v-model="organization.youtube" field="youtube" />
-
-                  <UiInputText v-model="organization.instagram" field="instagram" />
-
-                  <UiInputCheckbox
-                    v-model="organization.portailVisibility"
-                    field="portailVisibility"
-                  />
-                </v-col>
-              </v-row>
-            </LayoutCommonSection>
-          </div>
-        </template>
-      </UiFormEdition>
-
+  <UiFormEdition :model="Organization" class="inner-container">
+    <template #default="{ entity: organization }">
+      <div v-if="organization">
+        <LayoutCommonSection>
+          <v-row>
+            <v-col cols="12">
+              <h4 class="mb-8">{{ $t('general_informations') }}</h4>
+
+              <UiInputText
+                v-model="organization.name"
+                field="name"
+                :rules="getAsserts('name')"
+              />
+
+              <UiInputTextArea
+                v-model="organization.description"
+                field="description"
+              />
+
+              <UiInputImage
+                v-model="organization.logo"
+                field="logo"
+                :width="120"
+                :cropping-enabled="true"
+              />
+            </v-col>
+          </v-row>
+        </LayoutCommonSection>
+
+        <LayoutCommonSection>
+          <v-row>
+            <v-col cols="12">
+              <h4 class="mb-8">{{ $t('coordinate') }}</h4>
+
+              <UiInputText
+                v-model="organization.email"
+                field="email"
+                :rules="getAsserts('email')"
+              />
+
+              <UiInputPhone v-model="organization.tel" field="tel" />
+            </v-col>
+          </v-row>
+        </LayoutCommonSection>
+
+        <LayoutCommonSection>
+          <v-row>
+            <v-col cols="12">
+              <h4 class="mb-8">{{ $t('postal_address') }}</h4>
+
+              <UiInputText
+                v-model="organization.streetAddress"
+                field="streetAddress"
+              />
+
+              <UiInputText
+                v-model="organization.streetAddressSecond"
+                field="streetAddressSecond"
+              />
+
+              <UiInputText
+                v-model="organization.streetAddressThird"
+                field="streetAddressThird"
+              />
+
+              <UiInputText
+                v-model="organization.postalCode"
+                field="postalCode"
+              />
+
+              <UiInputText
+                v-model="organization.addressCity"
+                field="addressCity"
+              />
+
+              <UiInputAutocompleteApiResources
+                v-model="organization.addressCountry"
+                field="addressCountry"
+                :model="Country"
+                list-value="id"
+                list-label="name"
+              />
+
+              <client-only>
+                <UiMapLeaflet
+                  v-model:latitude="organization.latitude"
+                  v-model:longitude="organization.longitude"
+                  :street-address="organization.streetAddress"
+                  :street-address-second="organization.streetAddressSecond"
+                  :street-address-third="organization.streetAddressThird"
+                  :postal-code="organization.postalCode"
+                  :address-city="organization.addressCity"
+                  :address-country-id="organization.addressCountry"
+                  :search-button="true"
+                ></UiMapLeaflet>
+              </client-only>
+            </v-col>
+          </v-row>
+        </LayoutCommonSection>
+
+        <LayoutCommonSection>
+          <v-row>
+            <v-col cols="12">
+              <h4 class="mb-8">{{ $t('communication_params') }}</h4>
+
+              <UiInputText v-model="organization.facebook" field="facebook" />
+
+              <UiInputText v-model="organization.twitter" field="twitter" />
+
+              <UiInputText v-model="organization.youtube" field="youtube" />
+
+              <UiInputText v-model="organization.instagram" field="instagram" />
+
+              <UiInputCheckbox
+                v-model="organization.portailVisibility"
+                field="portailVisibility"
+              />
+            </v-col>
+          </v-row>
+        </LayoutCommonSection>
+      </div>
+    </template>
+  </UiFormEdition>
 </template>
 
 <script setup lang="ts">
-
-import Organization from "~/models/Freemium/Organization";
-import {getAssertUtils} from "~/services/asserts/getAssertUtils";
-import Country from "~/models/Core/Country";
+import Organization from '~/models/Freemium/Organization'
+import { getAssertUtils } from '~/services/asserts/getAssertUtils'
+import Country from '~/models/Core/Country'
 
 definePageMeta({
   name: 'freemium_organization_page',
@@ -122,13 +139,10 @@ onUnmounted(() => {
 })
 
 const getAsserts = (key) => getAssertUtils(Organization.getAsserts(), key)
-
 </script>
 
 <style scoped lang="scss">
-
 .inner-container {
   max-width: 1200px;
 }
-
 </style>

+ 5 - 3
pages/my-settings.vue

@@ -8,8 +8,11 @@ Page 'Mes préférences'
         <UiExpansionPanel title="message_settings" icon="fas fa-inbox">
           <v-container fluid class="container">
             <v-row>
-              <UiFormEdition :id="accessProfileStore.preferencesId" :model="Preferences">
-                <template #default="{ entity : preferences }">
+              <UiFormEdition
+                :id="accessProfileStore.preferencesId"
+                :model="Preferences"
+              >
+                <template #default="{ entity: preferences }">
                   <div v-if="preferences">
                     <v-row>
                       <v-col cols="12">
@@ -46,7 +49,6 @@ if (accessProfileStore.preferencesId === null) {
 }
 
 const openedPanels: Ref<Array<number>> = ref([0])
-
 </script>
 
 <style scoped lang="scss"></style>

+ 4 - 2
pages/parameters/attendance_booking_reasons/[id].vue

@@ -6,7 +6,10 @@
         go-back-route="/parameters/attendances"
       >
         <template #default="{ entity }">
-          <FormParameterAttendanceBookingReason v-if="entity !== null" :entity="entity" />
+          <FormParameterAttendanceBookingReason
+            v-if="entity !== null"
+            :entity="entity"
+          />
         </template>
       </UiFormEdition>
     </LayoutCommonSection>
@@ -18,5 +21,4 @@ import AttendanceBookingReason from '~/models/Booking/AttendanceBookingReason'
 definePageMeta({
   name: 'attendanceBookingReason',
 })
-
 </script>

+ 0 - 1
pages/parameters/attendance_booking_reasons/new.vue

@@ -19,5 +19,4 @@ import AttendanceBookingReason from '~/models/Booking/AttendanceBookingReason'
 definePageMeta({
   name: 'new_attendance_booking_reason',
 })
-
 </script>

+ 3 - 5
pages/parameters/attendances.vue

@@ -3,11 +3,10 @@
     <LayoutCommonSection>
       <h4>{{ $t('configuration') }}</h4>
       <UiFormEdition :id="organizationProfile.parametersId" :model="Parameters">
-        <template #default="{ entity : parameters }">
+        <template #default="{ entity: parameters }">
           <div v-if="parameters">
             <v-row>
               <v-col cols="12">
-
                 <h5 class="pa-2">{{ $t('showing') }}</h5>
                 <UiInputCheckbox
                   v-model="parameters.handlePresence"
@@ -60,9 +59,9 @@
 </template>
 <script setup lang="ts">
 import Parameters from '~/models/Organization/Parameters'
-import {useOrganizationProfileStore} from '~/stores/organizationProfile'
+import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 import AttendanceBookingReason from '~/models/Booking/AttendanceBookingReason'
-import {getAssertUtils} from "~/services/asserts/getAssertUtils";
+import { getAssertUtils } from '~/services/asserts/getAssertUtils'
 
 definePageMeta({
   name: 'parameters_attendances_page',
@@ -75,5 +74,4 @@ if (organizationProfile.parametersId === null) {
 }
 
 const getAsserts = (key) => getAssertUtils(Parameters.getAsserts(), key)
-
 </script>

+ 1 - 2
pages/parameters/bulletin.vue

@@ -2,7 +2,7 @@
   <LayoutContainer>
     <LayoutCommonSection>
       <UiFormEdition :id="organizationProfile.parametersId" :model="Parameters">
-        <template #default="{ entity : parameters }">
+        <template #default="{ entity: parameters }">
           <div v-if="parameters">
             <v-row>
               <v-col cols="12">
@@ -83,7 +83,6 @@ definePageMeta({
   name: 'parameters_bulletin_page',
 })
 
-
 const organizationProfile = useOrganizationProfileStore()
 
 if (organizationProfile.parametersId === null) {

+ 1 - 2
pages/parameters/cycles/[id].vue

@@ -16,12 +16,11 @@
 </template>
 <script setup lang="ts">
 import Cycle from '~/models/Education/Cycle'
-import {getAssertUtils} from "~/services/asserts/getAssertUtils";
+import { getAssertUtils } from '~/services/asserts/getAssertUtils'
 
 definePageMeta({
   name: 'cycle',
 })
 
 const getAsserts = (key) => getAssertUtils(Cycle.getAsserts(), key)
-
 </script>

+ 4 - 4
pages/parameters/education_notation.vue

@@ -2,7 +2,7 @@
   <LayoutContainer>
     <LayoutCommonSection>
       <UiFormEdition :id="organizationProfile.parametersId" :model="Parameters">
-        <template #default="{ entity : parameters }">
+        <template #default="{ entity: parameters }">
           <div v-if="parameters">
             <v-row>
               <v-col cols="12">
@@ -25,7 +25,9 @@
                 />
 
                 <UiInputAutocompleteEnum
-                  v-if="organizationProfile.hasModule('AdvancedEducationNotation')"
+                  v-if="
+                    organizationProfile.hasModule('AdvancedEducationNotation')
+                  "
                   v-model="parameters.advancedEducationNotationType"
                   enum-name="advanced_education_notation"
                   field="advancedEducationNotationType"
@@ -53,7 +55,6 @@
       </UiFormEdition>
     </LayoutCommonSection>
   </LayoutContainer>
-
 </template>
 
 <script setup lang="ts">
@@ -69,7 +70,6 @@ const organizationProfile = useOrganizationProfileStore()
 if (organizationProfile.parametersId === null) {
   throw new Error('Missing organization parameters id')
 }
-
 </script>
 
 <style scoped lang="scss"></style>

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

@@ -6,7 +6,10 @@
         go-back-route="/parameters/education_timings"
       >
         <template #default="{ entity }">
-          <FormParameterEducationTiming v-if="entity !== null" :entity="entity" />
+          <FormParameterEducationTiming
+            v-if="entity !== null"
+            :entity="entity"
+          />
         </template>
       </UiFormEdition>
     </LayoutCommonSection>
@@ -18,5 +21,4 @@ import EducationTiming from '~/models/Education/EducationTiming'
 definePageMeta({
   name: 'educationTiming',
 })
-
 </script>

+ 0 - 1
pages/parameters/education_timings/index.vue

@@ -22,7 +22,6 @@ const organizationProfile = useOrganizationProfileStore()
 if (organizationProfile.parametersId === null) {
   throw new Error('Missing organization parameters id')
 }
-
 </script>
 
 <style scoped lang="scss"></style>

+ 0 - 1
pages/parameters/education_timings/new.vue

@@ -19,5 +19,4 @@ import EducationTiming from '~/models/Education/EducationTiming'
 definePageMeta({
   name: 'new_education_timing',
 })
-
 </script>

+ 10 - 11
pages/parameters/general_parameters.vue

@@ -2,15 +2,15 @@
   <LayoutContainer>
     <LayoutCommonSection>
       <UiFormEdition :id="organizationProfile.parametersId" :model="Parameters">
-        <template #default="{ entity : parameters }">
+        <template #default="{ entity: parameters }">
           <div v-if="parameters">
             <v-row>
               <v-col cols="12">
                 <UiInputDatePicker
                   v-if="
-                organizationProfile.isSchool ||
-                organizationProfile.isManagerProduct
-              "
+                    organizationProfile.isSchool ||
+                    organizationProfile.isManagerProduct
+                  "
                   v-model="parameters.financialDate"
                   field="financialDate"
                   label="start_date_of_financial_season"
@@ -59,9 +59,9 @@
 
                 <UiInputCheckbox
                   v-if="
-                organizationProfile.isSchool &&
-                organizationProfile.isAssociation
-              "
+                    organizationProfile.isSchool &&
+                    organizationProfile.isAssociation
+                  "
                   v-model="parameters.studentsAreAdherents"
                   field="studentsAreAdherents"
                   label="students_are_also_association_members"
@@ -71,9 +71,9 @@
                   v-if="organizationProfile.isCMFCentralService"
                   class="d-flex flex-column"
                 >
-              <span class="mb-1 v-label" style="font-size: 12px"
-              >{{ $t('licenceQrCode') }}
-              </span>
+                  <span class="mb-1 v-label" style="font-size: 12px"
+                    >{{ $t('licenceQrCode') }}
+                  </span>
                   <UiInputImage
                     v-model="parameters.qrCode"
                     field="qrCode"
@@ -103,7 +103,6 @@ const organizationProfile = useOrganizationProfileStore()
 if (organizationProfile.parametersId === null) {
   throw new Error('Missing organization parameters id')
 }
-
 </script>
 
 <style scoped lang="scss"></style>

+ 1 - 2
pages/parameters/intranet.vue

@@ -2,7 +2,7 @@
   <LayoutContainer>
     <LayoutCommonSection>
       <UiFormEdition :id="organizationProfile.parametersId" :model="Parameters">
-        <template #default="{ entity : parameters }">
+        <template #default="{ entity: parameters }">
           <div v-if="parameters">
             <v-row>
               <v-col cols="12">
@@ -66,7 +66,6 @@ const organizationProfile = useOrganizationProfileStore()
 if (organizationProfile.parametersId === null) {
   throw new Error('Missing organization parameters id')
 }
-
 </script>
 
 <style scoped lang="scss"></style>

+ 0 - 1
pages/parameters/residence_areas/[id].vue

@@ -19,5 +19,4 @@ import ResidenceArea from '~/models/Billing/ResidenceArea'
 definePageMeta({
   name: 'edit_resident_area',
 })
-
 </script>

+ 0 - 1
pages/parameters/residence_areas/index.vue

@@ -15,7 +15,6 @@ import ResidenceArea from '~/models/Billing/ResidenceArea'
 definePageMeta({
   name: 'parameters_residence_areas_page',
 })
-
 </script>
 
 <style scoped lang="scss"></style>

+ 0 - 1
pages/parameters/residence_areas/new.vue

@@ -19,5 +19,4 @@ import ResidenceArea from '~/models/Billing/ResidenceArea'
 definePageMeta({
   name: 'create_a_new_residence_area',
 })
-
 </script>

+ 11 - 9
pages/parameters/sms.vue

@@ -2,11 +2,14 @@
   <div>
     <LayoutCommonSection>
       <UiFormEdition :id="organizationProfile.parametersId" :model="Parameters">
-        <template #default="{ entity : parameters }">
+        <template #default="{ entity: parameters }">
           <div v-if="parameters">
             <v-row>
               <v-col cols="12">
-                <UiInputText v-model="parameters.usernameSMS" field="usernameSMS" />
+                <UiInputText
+                  v-model="parameters.usernameSMS"
+                  field="usernameSMS"
+                />
               </v-col>
               <v-col cols="12">
                 <UiInputText
@@ -17,7 +20,8 @@
               </v-col>
               <v-col cols="12">
                 <div class="mb-3">
-                  {{ $t('smsSenderName') }} : <b>{{ parameters.smsSenderName }}</b>
+                  {{ $t('smsSenderName') }} :
+                  <b>{{ parameters.smsSenderName }}</b>
                 </div>
               </v-col>
             </v-row>
@@ -29,10 +33,10 @@
         <v-btn
           class="theme-info btn"
           :href="
-                runtimeConfig.public.fileStorageBaseUrl +
-                '/Bon_de_commande/' +
-                (organizationProfile.isCmf ? 'SMS_CMF.pdf' : 'SMS_Public.pdf')
-              "
+            runtimeConfig.public.fileStorageBaseUrl +
+            '/Bon_de_commande/' +
+            (organizationProfile.isCmf ? 'SMS_CMF.pdf' : 'SMS_Public.pdf')
+          "
           target="_blank"
         >
           {{ $t('buy_more_sms_credits') }}
@@ -42,7 +46,6 @@
   </div>
 </template>
 <script setup lang="ts">
-
 import Parameters from '~/models/Organization/Parameters'
 import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 
@@ -58,7 +61,6 @@ const organizationProfile = useOrganizationProfileStore()
 if (organizationProfile.parametersId === null) {
   throw new Error('Missing organization parameters id')
 }
-
 </script>
 
 <style scoped lang="scss">

+ 1 - 1
pages/parameters/subdomains/[id].vue

@@ -45,7 +45,7 @@ import { usePageStore } from '~/stores/page'
 import { TYPE_ALERT } from '~/types/enum/enums'
 import { useRefreshProfile } from '~/composables/data/useRefreshProfile'
 import { useRouteUtils } from '~/composables/utils/useRouteUtils'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 definePageMeta({
   name: 'activate_a_subdomain',

+ 7 - 9
pages/parameters/super_admin.vue

@@ -11,16 +11,16 @@
       </div>
 
       <UiFormEdition :id="accessProfile.id" :model="AdminAccess" class="w-100">
-        <template #default="{ entity : adminAccess }">
+        <template #default="{ entity: adminAccess }">
           <div v-if="adminAccess">
             <v-table class="mb-4">
               <tbody>
-              <tr>
-                <td>{{ $t('username') }} :</td>
-                <td>
-                  <b>{{ adminAccess.username }}</b>
-                </td>
-              </tr>
+                <tr>
+                  <td>{{ $t('username') }} :</td>
+                  <td>
+                    <b>{{ adminAccess.username }}</b>
+                  </td>
+                </tr>
               </tbody>
             </v-table>
 
@@ -33,7 +33,6 @@
           </div>
         </template>
       </UiFormEdition>
-
     </LayoutCommonSection>
   </div>
 </template>
@@ -50,7 +49,6 @@ const accessProfile = useAccessProfileStore()
 if (accessProfile.id === null) {
   throw new Error('Missing access profile id')
 }
-
 </script>
 
 <style scoped lang="scss">

+ 5 - 3
pages/parameters/teaching.vue

@@ -4,7 +4,7 @@
       <h4>{{ $t('configuration') }}</h4>
 
       <UiFormEdition :id="organizationProfile.parametersId" :model="Parameters">
-        <template #default="{ entity : parameters }">
+        <template #default="{ entity: parameters }">
           <div v-if="parameters">
             <v-row>
               <v-col cols="12">
@@ -45,7 +45,7 @@ import { useOrganizationProfileStore } from '~/stores/organizationProfile'
 import type { AnyJson } from '~/types/data'
 import { useEnumFetch } from '~/composables/data/useEnumFetch'
 import { TABLE_ACTION } from '~/types/enum/enums'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 definePageMeta({
   name: 'parameters_teaching_page',
@@ -65,7 +65,9 @@ const { data: cycleEnum, status: enumStatus } = fetchEnum('education_cycle')
 const { data: cycles, status: cyclesStatus } = fetchCollection(Cycle)
 
 const pending: ComputedRef<boolean> = computed(
-  () => enumStatus.value == FETCHING_STATUS.PENDING || cyclesStatus.value == FETCHING_STATUS.PENDING,
+  () =>
+    enumStatus.value == FETCHING_STATUS.PENDING ||
+    cyclesStatus.value == FETCHING_STATUS.PENDING,
 )
 
 const orderedCycles: ComputedRef<AnyJson> = computed(() => {

+ 1 - 1
pages/parameters/website.vue

@@ -130,7 +130,7 @@ import Subdomain from '~/models/Organization/Subdomain'
 import type ApiResource from '~/models/ApiResource'
 import EqualFilter from '~/services/data/Filters/EqualFilter'
 import Query from '~/services/data/Query'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 definePageMeta({
   name: 'parameters_website_page',

+ 1 - 1
pages/subscription.vue

@@ -485,7 +485,7 @@ import { useApiLegacyRequestService } from '~/composables/data/useApiLegacyReque
 import { usePageStore } from '~/stores/page'
 import { DOLIBARR_BILLING_DOC_TYPE } from '~/types/enum/enums'
 import LayoutMobytStatus from '~/components/Layout/MobytStatus.vue'
-import {FETCHING_STATUS} from "~/types/enum/data";
+import { FETCHING_STATUS } from '~/types/enum/data'
 
 // meta
 definePageMeta({

+ 6 - 6
plugins/vPhoneInput.ts

@@ -1,11 +1,11 @@
-import 'flag-icons/css/flag-icons.min.css';
-import 'v-phone-input/dist/v-phone-input.css';
-import { createVPhoneInput } from 'v-phone-input';
+import 'flag-icons/css/flag-icons.min.css'
+import 'v-phone-input/dist/v-phone-input.css'
+import { createVPhoneInput } from 'v-phone-input'
 
 export default defineNuxtPlugin((nuxtApp) => {
   const vPhoneInput = createVPhoneInput({
     countryIconMode: 'svg',
-  });
+  })
 
-  nuxtApp.vueApp.use(vPhoneInput);
-});
+  nuxtApp.vueApp.use(vPhoneInput)
+})

+ 14 - 16
services/asserts/AssertRuleRegistry.ts

@@ -1,31 +1,29 @@
-import type {AssertRule} from "~/types/interfaces";
-import { MaxAssert } from './MaxAssert';
-import { NullableAssert } from './NullableAssert';
-import { TypeAssert } from './TypeAssert';
+import type { AssertRule } from '~/types/interfaces'
+import { MaxAssert } from './MaxAssert'
+import { NullableAssert } from './NullableAssert'
+import { TypeAssert } from './TypeAssert'
 
 export class AssertRuleRegistry {
-  private rules: AssertRule[] = [];
+  private rules: AssertRule[] = []
 
   constructor() {
-    this.rules = [
-      new MaxAssert(),
-      new NullableAssert(),
-      new TypeAssert(),
-    ];
+    this.rules = [new MaxAssert(), new NullableAssert(), new TypeAssert()]
   }
 
-  getValidators(asserts: Record<string, unknown>): ((value: unknown) => true | string)[] {
-    const allRules: ((value: unknown) => true | string)[] = [];
+  getValidators(
+    asserts: Record<string, unknown>,
+  ): ((value: unknown) => true | string)[] {
+    const allRules: ((value: unknown) => true | string)[] = []
 
     for (const key in asserts) {
-      const criteria = asserts[key];
+      const criteria = asserts[key]
 
-      const rule = this.rules.find(r => r.supports(key));
+      const rule = this.rules.find((r) => r.supports(key))
       if (rule) {
-        allRules.push(rule.createRule(criteria));
+        allRules.push(rule.createRule(criteria))
       }
     }
 
-    return allRules;
+    return allRules
   }
 }

+ 5 - 3
services/asserts/MaxAssert.ts

@@ -1,12 +1,14 @@
-import type {AssertRule} from "~/types/interfaces";
+import type { AssertRule } from '~/types/interfaces'
 
 export class MaxAssert implements AssertRule {
   supports(key: string): boolean {
-    return key === 'max';
+    return key === 'max'
   }
 
   createRule(criteria: number): (value: string) => true | string {
     return (value: string) =>
-      value === null || value.length <= criteria || `Maximum ${criteria} caractères`;
+      value === null ||
+      value.length <= criteria ||
+      `Maximum ${criteria} caractères`
   }
 }

+ 7 - 6
services/asserts/NullableAssert.ts

@@ -1,15 +1,16 @@
-import type {AssertRule} from "~/types/interfaces";
-import { useI18n } from 'vue-i18n';
+import type { AssertRule } from '~/types/interfaces'
+import { useI18n } from 'vue-i18n'
 
 export class NullableAssert implements AssertRule {
   supports(key: string): boolean {
-    return key === 'nullable';
+    return key === 'nullable'
   }
 
   createRule(criteria: boolean): (value: unknown) => true | string {
-
-    const { t } = useI18n();
+    const { t } = useI18n()
     return (value: unknown) =>
-      !criteria ? value !== null && !!value || t('please_enter_a_value') : true
+      !criteria
+        ? (value !== null && !!value) || t('please_enter_a_value')
+        : true
   }
 }

+ 9 - 8
services/asserts/TypeAssert.ts

@@ -1,26 +1,27 @@
-import type {AssertRule} from "~/types/interfaces";
-import { useI18n } from 'vue-i18n';
-import ValidationUtils from "~/services/utils/validationUtils";
+import type { AssertRule } from '~/types/interfaces'
+import { useI18n } from 'vue-i18n'
+import ValidationUtils from '~/services/utils/validationUtils'
 
 export class TypeAssert implements AssertRule {
   supports(key: string): boolean {
-    return key === 'type';
+    return key === 'type'
   }
 
   createRule(criteria: string): (value: unknown) => true | string {
     const validationUtils = new ValidationUtils()
-    const { t } = useI18n();
+    const { t } = useI18n()
 
     if (criteria === 'email') {
       return (email: unknown) =>
-        typeof email === 'string' && validationUtils.validEmail(email) || t('email_error');
+        (typeof email === 'string' && validationUtils.validEmail(email)) ||
+        t('email_error')
     }
 
     if (criteria === 'integer') {
       return (value: unknown) =>
-        Number.isInteger(value as number) || t('need_to_be_integer');
+        Number.isInteger(value as number) || t('need_to_be_integer')
     }
 
-    return () => true;
+    return () => true
   }
 }

+ 4 - 4
services/asserts/getAssertUtils.ts

@@ -1,8 +1,8 @@
-import { AssertRuleRegistry } from './AssertRuleRegistry';
+import { AssertRuleRegistry } from './AssertRuleRegistry'
 
 export function getAssertUtils(asserts: Record<string, unknown>, key: string) {
-  if (!asserts || !(key in asserts)) return [];
+  if (!asserts || !(key in asserts)) return []
 
-  const registry = new AssertRuleRegistry();
-  return registry.getValidators(asserts[key]);
+  const registry = new AssertRuleRegistry()
+  return registry.getValidators(asserts[key])
 }

+ 1 - 1
services/data/Filters/EqualFilter.ts

@@ -24,7 +24,7 @@ export default class EqualFilter extends AbstractFilter implements ApiFilter {
     this.filterValue = value
   }
 
-  public applyToPiniaOrmQuery <T extends ApiResource>(
+  public applyToPiniaOrmQuery<T extends ApiResource>(
     query: PiniaOrmQuery<T>,
   ): PiniaOrmQuery<T> {
     const filterValue = RefUtils.castToRef(

+ 2 - 2
services/data/Filters/InArrayFilter.ts

@@ -30,7 +30,7 @@ export default class InArrayFilter extends AbstractFilter implements ApiFilter {
     this.filterValue = value
   }
 
-  public applyToPiniaOrmQuery <T extends ApiResource>(
+  public applyToPiniaOrmQuery<T extends ApiResource>(
     query: PiniaOrmQuery<T>,
   ): PiniaOrmQuery<T> {
     const filterValue = RefUtils.castToRef(
@@ -59,7 +59,7 @@ export default class InArrayFilter extends AbstractFilter implements ApiFilter {
       filterValue.value = [filterValue.value]
     }
 
-    filterValue.value = filterValue.value.filter((value)=> value !== null)
+    filterValue.value = filterValue.value.filter((value) => value !== null)
 
     if (!filterValue.value.length > 0) {
       return ''

+ 1 - 1
services/data/Filters/OrderBy.ts

@@ -20,7 +20,7 @@ export default class OrderBy implements ApiFilter {
     this.mode = mode
   }
 
-  public applyToPiniaOrmQuery <T extends ApiResource>(
+  public applyToPiniaOrmQuery<T extends ApiResource>(
     query: PiniaOrmQuery<T>,
   ): PiniaOrmQuery<T> {
     return query.orderBy(

+ 1 - 1
services/data/Filters/PageFilter.ts

@@ -16,7 +16,7 @@ export default class PageFilter implements ApiFilter {
     this.itemsPerPage = itemsPerPage
   }
 
-  public applyToPiniaOrmQuery <T extends ApiResource>(
+  public applyToPiniaOrmQuery<T extends ApiResource>(
     query: PiniaOrmQuery<T>,
   ): PiniaOrmQuery<T> {
     const page = RefUtils.castToRef(this.page, false)

+ 1 - 1
services/data/Filters/SearchFilter.ts

@@ -63,7 +63,7 @@ export default class SearchFilter extends AbstractFilter implements ApiFilter {
     }
   }
 
-  public applyToPiniaOrmQuery <T extends ApiResource>(
+  public applyToPiniaOrmQuery<T extends ApiResource>(
     query: PiniaOrmQuery<T>,
   ): PiniaOrmQuery<T> {
     const filterValue = RefUtils.castToRef(

+ 8 - 8
services/data/Filters/TimeFilter.ts

@@ -1,11 +1,11 @@
-import type {Query as PiniaOrmQuery} from 'pinia-orm'
-import type {Ref} from 'vue'
-import type {ApiFilter} from '~/types/data'
+import type { Query as PiniaOrmQuery } from 'pinia-orm'
+import type { Ref } from 'vue'
+import type { ApiFilter } from '~/types/data'
 import type ApiResource from '~/models/ApiResource'
-import {TIME_STRATEGY} from '~/types/enum/data'
+import { TIME_STRATEGY } from '~/types/enum/data'
 import AbstractFilter from '~/services/data/Filters/AbstractFilter'
-import RefUtils from "~/services/utils/refUtils";
-import DateUtils from "~/services/utils/dateUtils";
+import RefUtils from '~/services/utils/refUtils'
+import DateUtils from '~/services/utils/dateUtils'
 
 export default class TimeFilter extends AbstractFilter implements ApiFilter {
   field: string
@@ -37,7 +37,7 @@ export default class TimeFilter extends AbstractFilter implements ApiFilter {
       return false
     }
 
-    switch (this.mode){
+    switch (this.mode) {
       case TIME_STRATEGY.BEFORE:
         return DateUtils.isBefore(value, filterValue.value, false)
       case TIME_STRATEGY.AFTER:
@@ -51,7 +51,7 @@ export default class TimeFilter extends AbstractFilter implements ApiFilter {
     }
   }
 
-  public applyToPiniaOrmQuery <T extends ApiResource>(
+  public applyToPiniaOrmQuery<T extends ApiResource>(
     query: PiniaOrmQuery<T>,
   ): PiniaOrmQuery<T> {
     const filterValue = RefUtils.castToRef(

+ 1 - 1
services/data/Query.ts

@@ -58,7 +58,7 @@ export default class Query {
    * @see https://pinia-orm.codedredd.de/guide/repository/retrieving-data
    * @param query
    */
-  public applyToPiniaOrmQuery <T extends ApiResource>(
+  public applyToPiniaOrmQuery<T extends ApiResource>(
     query: PiniaOrmQuery<T>,
   ): PiniaOrmQuery<T> {
     // 'Where' filters shall be applied first, then orderBy filters, and finally pagination

+ 33 - 13
services/data/entityManager.ts

@@ -5,7 +5,7 @@ import type {
 } from 'pinia-orm'
 import { v4 as uuid4 } from 'uuid'
 import * as _ from 'lodash-es'
-import {computed, type ComputedRef} from 'vue'
+import { computed, type ComputedRef } from 'vue'
 import type ApiRequestService from './apiRequestService'
 import UrlUtils from '~/services/utils/urlUtils'
 import type ApiModel from '~/models/ApiModel'
@@ -35,13 +35,17 @@ class EntityManager {
    * A method to retrieve the repository of a given ApiResource
    * @protected
    */
-  protected _getRepo: <T extends typeof ApiResource>(model: T) => Repository<InstanceType<T>>
+  protected _getRepo: <T extends typeof ApiResource>(
+    model: T,
+  ) => Repository<InstanceType<T>>
 
   protected _getProfileMask: () => object
 
   public constructor(
     apiRequestService: ApiRequestService,
-    getRepo: <T extends typeof ApiResource>(model: T) => Repository<InstanceType<T>>,
+    getRepo: <T extends typeof ApiResource>(
+      model: T,
+    ) => Repository<InstanceType<T>>,
     getProfileMask: () => object,
   ) {
     this.apiRequestService = apiRequestService
@@ -54,7 +58,9 @@ class EntityManager {
    *
    * @param model
    */
-  public getRepository<T extends typeof ApiResource>(model: T): Repository<InstanceType<T>> {
+  public getRepository<T extends typeof ApiResource>(
+    model: T,
+  ): Repository<InstanceType<T>> {
     return this._getRepo(model)
   }
 
@@ -63,7 +69,9 @@ class EntityManager {
    *
    * @param model
    */
-  public getQuery<T extends typeof ApiResource>(model: T): PiniaOrmQuery<InstanceType<T>> {
+  public getQuery<T extends typeof ApiResource>(
+    model: T,
+  ): PiniaOrmQuery<InstanceType<T>> {
     // TODO: quid des uuid?
     return this.getRepository(model).where((val) => Number.isInteger(val.id))
   }
@@ -80,7 +88,10 @@ class EntityManager {
    * @param instance
    */
   // noinspection JSMethodCanBeStatic
-  public cast<T extends typeof ApiResource>(model: T, instance: InstanceType<T>): InstanceType<T> {
+  public cast<T extends typeof ApiResource>(
+    model: T,
+    instance: InstanceType<T>,
+  ): InstanceType<T> {
     return new model(instance) as InstanceType<T>
   }
 
@@ -121,7 +132,7 @@ class EntityManager {
   ): InstanceType<T> {
     const repository = this.getRepository(model)
 
-    const instance  = repository.make(properties)
+    const instance = repository.make(properties)
 
     if (
       !Object.prototype.hasOwnProperty.call(properties, 'id') ||
@@ -142,7 +153,10 @@ class EntityManager {
    * @param permanent Is the change already persisted in the datasource? If this is the case, the initial state of this
    *                  record is also updated.
    */
-  public save<T extends ApiResource>(instance: T, permanent: boolean = false): T {
+  public save<T extends ApiResource>(
+    instance: T,
+    permanent: boolean = false,
+  ): T {
     const model = this.getModel(instance)
 
     this.validateEntity(instance)
@@ -172,7 +186,7 @@ class EntityManager {
    * @param model  Model of the object to fetch
    * @param id   Id of the object to fetch
    */
-  public async fetch <T extends typeof ApiResource>(
+  public async fetch<T extends typeof ApiResource>(
     model: T,
     id?: number | null,
   ): Promise<InstanceType<T>> {
@@ -194,7 +208,7 @@ class EntityManager {
    * @param parent
    * @param query
    */
-  public async fetchCollection <T extends typeof ApiResource>(
+  public async fetchCollection<T extends typeof ApiResource>(
     model: T,
     parent: T | null,
     query: Query | null = null,
@@ -265,7 +279,7 @@ class EntityManager {
     const headers = { profileHash: await this.makeProfileHash() }
 
     if (!instance.isNew()) {
-      if(!model.isIdLess()){
+      if (!model.isIdLess()) {
         url = UrlUtils.join(url, String(instance.id))
       }
       response = await this.apiRequestService.patch(url, data, null, headers)
@@ -382,7 +396,10 @@ class EntityManager {
    * @param model
    * @param id
    */
-  public isNewInstance<T extends typeof ApiResource>(model: T, id: number | string): boolean {
+  public isNewInstance<T extends typeof ApiResource>(
+    model: T,
+    id: number | string,
+  ): boolean {
     const repository = this.getRepository(model)
 
     const item = repository.find(id)
@@ -402,7 +419,10 @@ class EntityManager {
    * @param instance
    * @private
    */
-  protected saveInitialState<T extends typeof ApiResource>(model: T, instance: InstanceType<T>) {
+  protected saveInitialState<T extends typeof ApiResource>(
+    model: T,
+    instance: InstanceType<T>,
+  ) {
     const repository = this.getRepository(model)
 
     // Clone and prefix id

+ 3 - 5
services/data/normalizer/hydraNormalizer.ts

@@ -102,11 +102,9 @@ class HydraNormalizer {
         if (!iri) {
           return default_
         }
-        return UrlUtils.getParameter(
-          data['view'][pos],
-          'page',
-          default_,
-        ) as number | undefined
+        return UrlUtils.getParameter(data['view'][pos], 'page', default_) as
+          | number
+          | undefined
       }
 
       metadata.first = extractPageNumber('first', 1)

+ 3 - 1
services/layout/menuBuilder/accountMenuBuilder.ts

@@ -172,7 +172,9 @@ export default class AccountMenuBuilder extends AbstractMenuBuilder {
       ]),
     )
 
-    children.push(...this.makeChildren([{ pageName: 'freemium_organization_page' }]))
+    children.push(
+      ...this.makeChildren([{ pageName: 'freemium_organization_page' }]),
+    )
 
     actions.push(
       this.createItem('logout', undefined, `/logout`, MENU_LINK_TYPE.V1),

+ 1 - 1
stores/page.ts

@@ -42,6 +42,6 @@ export const usePageStore = defineStore('page', () => {
     loading,
     removeSlowlyAlert,
     addAlert,
-    clearAlertTimeout
+    clearAlertTimeout,
   }
 })

+ 11 - 11
tests/units/services/data/normalizer/hydraNormalizer.test.ts

@@ -153,15 +153,15 @@ describe('getMetadata', () => {
       '@context': '/api/contexts/Foo',
       '@id': '/api/foo',
       '@type': 'Collection',
-      'member': ['foo'],
-      'totalItems': 10,
-      'view': {
+      member: ['foo'],
+      totalItems: 10,
+      view: {
         '@id': '/api/foo?page=3',
         '@type': 'PartialCollectionView',
-        'first': '/api/foo?page=1',
-        'last': '/api/foo?page=5',
-        'next': '/api/foo?page=4',
-        'previous': '/api/foo?page=2',
+        first: '/api/foo?page=1',
+        last: '/api/foo?page=5',
+        next: '/api/foo?page=4',
+        previous: '/api/foo?page=2',
       },
     }
 
@@ -180,12 +180,12 @@ describe('getMetadata', () => {
       '@context': '/api/contexts/Foo',
       '@id': '/api/foo',
       '@type': 'Collection',
-      'member': ['foo'],
-      'totalItems': 10,
-      'view': {
+      member: ['foo'],
+      totalItems: 10,
+      view: {
         '@id': '/api/foo?page=3',
         '@type': 'PartialCollectionView',
-        'first': '/api/foo?page=1',
+        first: '/api/foo?page=1',
       },
     }
 

+ 2 - 2
types/data.d.ts

@@ -47,7 +47,7 @@ interface Pagination {
   previous?: number
 }
 
-interface Collection <T extends ApiResource>{
+interface Collection<T extends ApiResource> {
   items: PiniaOrmCollection<T>
   pagination: Pagination
   totalItems: number | undefined
@@ -66,7 +66,7 @@ interface EnumItem {
 }
 
 interface CollectionResponse {
-  member: Array<AnyJson>,
+  member: Array<AnyJson>
   totalItems: number
 }
 

+ 2 - 2
types/interfaces.d.ts

@@ -214,6 +214,6 @@ interface ColumnDefinition {
 }
 
 interface AssertRule {
-  supports(key: string): boolean;
-  createRule(criteria: unknown): (value: unknown) => true | string;
+  supports(key: string): boolean
+  createRule(criteria: unknown): (value: unknown) => true | string
 }