Browse Source

apply prettier lint

Olivier Massot 4 months ago
parent
commit
6ed5f3019b
90 changed files with 1059 additions and 902 deletions
  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
 }