瀏覽代碼

various eslint fixes

Olivier Massot 6 月之前
父節點
當前提交
ccb3bd0b24

+ 7 - 6
components/Layout/Alert/Container.vue

@@ -1,13 +1,14 @@
 <!--
 Container principal pour l'affichage d'une ou plusieurs alertes
 -->
+<!-- eslint-disable vue/valid-v-for -->
 
 <template>
   <main class="alertContainer">
     <client-only>
       <LayoutAlertContent
-        v-for="(alert, key) in alerts"
-        :key="key"
+        v-for="(alert, index) in alerts"
+        :key="index"
         :alert="alert"
         class="alertContent"
       />
@@ -16,15 +17,15 @@ Container principal pour l'affichage d'une ou plusieurs alertes
 </template>
 
 <script setup lang="ts">
-import type { ComputedRef } from 'vue'
+import { computed } from 'vue'
 import type { Alert } from '~/types/interfaces'
 import { usePageStore } from '~/stores/page'
 
 const pageStore = usePageStore()
 
-const alerts: ComputedRef<Array<Alert>> = computed(() => {
-  return pageStore.alerts
-})
+// Using alerts in the template v-for directive
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+const alerts = computed<Array<Alert>>(() => pageStore.alerts)
 </script>
 
 <style scoped>

+ 6 - 3
components/Layout/Alert/Content.vue

@@ -1,4 +1,5 @@
 <!-- Message d'alerte -->
+<!-- eslint-disable vue/valid-v-for -->
 
 <template>
   <v-alert
@@ -47,7 +48,7 @@ const props = defineProps({
 })
 
 const show: Ref<boolean> = ref(true)
-let timeout: any = null
+let timeoutId: ReturnType<typeof setTimeout> | null = null
 
 const pageStore = usePageStore()
 
@@ -56,7 +57,7 @@ const pageStore = usePageStore()
  * @param time
  */
 const clearAlert = (time: number = 4000) => {
-  timeout = setTimeout(() => {
+  timeoutId = setTimeout(() => {
     show.value = false
     pageStore.removeSlowlyAlert()
   }, time)
@@ -65,13 +66,15 @@ const clearAlert = (time: number = 4000) => {
 /**
  * Réinitialise et suspend le délai avant le retrait de l'alerte au survol du curseur
  */
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
 const onMouseOver = () => {
-  clearTimeout(timeout)
+  clearTimeout(timeoutId)
 }
 
 /**
  * Relance le timer avant le retrait de l'alerte lorsque le curseur quitte l'alerte
  */
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
 const onMouseOut = () => {
   clearAlert(props.timeout)
 }

+ 2 - 2
components/Layout/Dialog.vue

@@ -14,8 +14,8 @@
         "
       >
         <h3 :class="'d-flex theme-' + theme">
-          <v-icon icon="fa-solid fa-bullhorn" width="25" htight="25"/>
-          <span class="pt-4"><slot name="dialogType"/></span>
+          <v-icon icon="fa-solid fa-bullhorn" width="25" htight="25" />
+          <span class="pt-4"><slot name="dialogType" /></span>
         </h3>
       </div>
 

+ 3 - 3
components/Ui/DatePicker.vue

@@ -25,17 +25,17 @@ Sélecteur de dates
       :select-text="$t('select')"
       :cancel-text="$t('cancel')"
       input-class-name="date-picker-input"
-      @update:model-value="$emit('update:modelValue', $event)"
       class="mb-6"
+      @update:model-value="$emit('update:modelValue', $event)"
     />
   </div>
 </template>
 
 <script setup lang="ts">
 import { useI18n } from 'vue-i18n'
-import DateUtils, { supportedLocales } from '~/services/utils/dateUtils'
-import type { PropType } from '@vue/runtime-core'
+import type { PropType } from 'vue'
 import type { Locale } from 'date-fns'
+import DateUtils, { supportedLocales } from '~/services/utils/dateUtils'
 
 const props = defineProps({
   modelValue: {

+ 5 - 5
components/Ui/Form/Creation.vue

@@ -1,5 +1,5 @@
 <template>
-  <UiForm v-model="entity" :submitActions="submitActions">
+  <UiForm v-model="entity" :submit-actions="submitActions">
     <template #form.button>
       <v-btn v-if="goBackRoute" class="theme-neutral mr-3" @click="quit">
         {{ $t('cancel') }}
@@ -11,7 +11,7 @@
 </template>
 
 <script setup lang="ts">
-import type { PropType } from '@vue/runtime-core'
+import type { PropType } from 'vue'
 import type { RouteLocationRaw } from '@intlify/vue-router-bridge'
 import ApiModel from '~/models/ApiModel'
 import type { AnyJson } from '~/types/data'
@@ -55,11 +55,11 @@ const props = defineProps({
 const router = useRouter()
 const { em } = useEntityManager()
 
-//@ts-ignore Pour une raison que j'ignore, le type Ref<ApiModel> met en erreur la prop entity de UiForm...
+// @ts-ignore Pour une raison que j'ignore, le type Ref<ApiModel> met en erreur la prop entity de UiForm...
 const entity: ApiModel = reactive(em.newInstance(props.model))
 
 const submitActions = computed(() => {
-  let actions: AnyJson = {}
+  const actions: AnyJson = {}
 
   if (props.goBackRoute !== null) {
     actions[SUBMIT_TYPE.SAVE_AND_BACK] = props.goBackRoute
@@ -71,7 +71,7 @@ const submitActions = computed(() => {
 
 const quit = () => {
   if (!props.goBackRoute) {
-    throw Error('no go back route defined')
+    throw new Error('no go back route defined')
   }
 
   router.push(props.goBackRoute)

+ 7 - 7
components/Ui/Form/Edition.vue

@@ -1,7 +1,7 @@
 <template>
   <LayoutContainer>
     <UiLoadingPanel v-if="pending" />
-    <UiForm v-else v-model="entity" :submitActions="submitActions">
+    <UiForm v-else v-model="entity" :submit-actions="submitActions">
       <template #form.button>
         <v-btn v-if="goBackRoute" class="theme-neutral mr-3" @click="quit">
           {{ $t('cancel') }}
@@ -14,14 +14,14 @@
 </template>
 
 <script setup lang="ts">
-import type { PropType } from '@vue/runtime-core'
+import type { PropType } from 'vue'
+import { useRoute } from 'vue-router'
+import type { RouteLocationRaw } from 'vue-router'
+import type { AsyncData } from '#app'
 import ApiModel from '~/models/ApiModel'
 import type { AnyJson } from '~/types/data'
 import { SUBMIT_TYPE } from '~/types/enum/enums'
-import { useRoute } from 'vue-router'
-import type { RouteLocationRaw } from 'vue-router'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
-import type { AsyncData } from '#app'
 
 const props = defineProps({
   /**
@@ -79,7 +79,7 @@ const { data: entity, pending } = fetch(props.model, entityId) as AsyncData<
 >
 
 const submitActions = computed(() => {
-  let actions: AnyJson = {}
+  const actions: AnyJson = {}
 
   if (props.goBackRoute !== null) {
     actions[SUBMIT_TYPE.SAVE_AND_BACK] = props.goBackRoute
@@ -91,7 +91,7 @@ const submitActions = computed(() => {
 
 const quit = () => {
   if (!props.goBackRoute) {
-    throw Error('no go back route defined')
+    throw new Error('no go back route defined')
   }
 
   router.push(props.goBackRoute)

+ 2 - 2
components/Ui/Image.vue

@@ -36,9 +36,9 @@ Permet d'afficher une image par défaut si l'image demandée n'est pas disponibl
 </template>
 
 <script setup lang="ts">
+import type { WatchStopHandle } from 'vue'
 import { useImageFetch } from '~/composables/data/useImageFetch'
 import ImageManager from '~/services/data/imageManager'
-import type { WatchStopHandle } from '@vue/runtime-core'
 import { IMAGE_SIZE } from '~/types/enum/enums'
 
 const props = defineProps({
@@ -77,7 +77,7 @@ const props = defineProps({
   size: {
     type: String as PropType<IMAGE_SIZE>,
     required: false,
-    default: IMAGE_SIZE.MD
+    default: IMAGE_SIZE.MD,
   },
   /**
    * Icône à afficher en overlay au survol de la souris

+ 7 - 8
components/Ui/Input/Autocomplete.vue

@@ -8,6 +8,7 @@ Liste déroulante avec autocompletion, à placer dans un composant `UiForm`
   <main>
     <!--suppress TypeScriptValidateTypes -->
     <v-autocomplete
+      v-model:search-input="search"
       :model-value="modelValue"
       autocomplete="search"
       :items="items"
@@ -19,7 +20,6 @@ Liste déroulante avec autocompletion, à placer dans un composant `UiForm`
       :multiple="multiple"
       :loading="isLoading"
       :return-object="returnObject"
-      :search-input.sync="search"
       :prepend-inner-icon="prependInnerIcon"
       :error="error || !!fieldViolations"
       :error-messages="
@@ -34,11 +34,11 @@ Liste déroulante avec autocompletion, à placer dans un composant `UiForm`
       "
       :variant="variant"
       density="compact"
+      class="mb-3"
       @update:model-value="onUpdate"
       @update:search="emit('update:search', $event)"
       @update:menu="emit('update:menu', $event)"
       @update:focused="emit('update:focused', $event)"
-      class="mb-3"
     >
       <template v-if="slotText" #item="data">
         <!--        <v-list-item-content v-text="data.item.slotTextDisplay"></v-list-item-content>-->
@@ -48,12 +48,11 @@ Liste déroulante avec autocompletion, à placer dans un composant `UiForm`
 </template>
 
 <script setup lang="ts">
-import { computed } from '@vue/reactivity'
-import type { ComputedRef, Ref } from '@vue/reactivity'
+import { computed } from 'vue'
+import type { ComputedRef, Ref, PropType } from 'vue'
 import { useFieldViolation } from '~/composables/form/useFieldViolation'
 import ObjectUtils from '~/services/utils/objectUtils'
 import type { AnyJson } from '~/types/data'
-import type { PropType } from '@vue/runtime-core'
 
 const props = defineProps({
   /**
@@ -88,7 +87,7 @@ const props = defineProps({
    * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-items
    */
   items: {
-    type: Array as PropType<Array<Object>>,
+    type: Array as PropType<Array<object>>,
     required: false,
     default: () => [],
   },
@@ -272,7 +271,7 @@ const onUpdate = (event: string) => {
  * TODO: à revoir
  */
 const items: ComputedRef<Array<AnyJson>> = computed(() => {
-  let _items: Array<any> = props.items
+  const _items: Array<any> = props.items
   return _items
   // if (props.group !== null) {
   //   _items = groupItems(props.items)
@@ -342,7 +341,7 @@ const prepareGroups = (groupedItems: Array<Array<string>>): Array<AnyJson> => {
  *
  * @param item
  */
-const prepareItem = (item: Object): AnyJson => {
+const prepareItem = (item: object): AnyJson => {
   const slotTextDisplay: Array<string> = []
   const itemTextDisplay: Array<string> = []
 

+ 5 - 6
components/Ui/Input/Autocomplete/Accesses.vue

@@ -12,7 +12,7 @@ Champs autocomplete dédié à la recherche des Accesses d'une structure
       :label="label"
       :items="items"
       item-value="id"
-      :isLoading="pending"
+      :is-loading="pending"
       :multiple="multiple"
       hide-no-data
       :chips="chips"
@@ -21,21 +21,20 @@ Champs autocomplete dédié à la recherche des Accesses d'une structure
       prepend-inner-icon="fas fa-magnifying-glass"
       :return-object="false"
       :variant="variant"
+      :class="pending || pageStore.loading ? 'hide-selection' : ''"
       @update:model-value="onUpdateModelValue"
       @update:search="onUpdateSearch"
-      :class="pending || pageStore.loading ? 'hide-selection' : ''"
     />
   </main>
 </template>
 
 <script setup lang="ts">
-import type { PropType } from '@vue/runtime-core'
-import type { ComputedRef, Ref } from '@vue/reactivity'
-import { computed } from '@vue/reactivity'
+import type { PropType, ComputedRef, Ref } from 'vue'
+import { computed } from 'vue'
+import * as _ from 'lodash-es'
 import type { AssociativeArray } from '~/types/data'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import Access from '~/models/Access/Access'
-import * as _ from 'lodash-es'
 import Query from '~/services/data/Query'
 import OrderBy from '~/services/data/Filters/OrderBy'
 import { ORDER_BY_DIRECTION, SEARCH_STRATEGY } from '~/types/enum/data'

+ 4 - 5
components/Ui/Input/AutocompleteWithAp2i.vue

@@ -10,21 +10,20 @@ Liste déroulante avec autocompletion issue de Ap2i
       :field="field"
       :label="label"
       :items="items"
-      :isLoading="pending"
+      :is-loading="pending"
       item-title="title"
       item-value="id"
       :multiple="multiple"
       :chips="chips"
-      prependIcon="fas fa-magnifying-glass"
+      prepend-icon="fas fa-magnifying-glass"
       :return-object="false"
     />
   </main>
 </template>
 
 <script setup lang="ts">
-import { computed } from '@vue/reactivity'
-import type { ComputedRef, Ref } from '@vue/reactivity'
-import type { PropType } from '@vue/runtime-core'
+import { computed } from 'vue'
+import type { ComputedRef, Ref, PropType } from 'vue'
 import { useEntityFetch } from '~/composables/data/useEntityFetch'
 import ApiResource from '~/models/ApiResource'
 import ApiModel from '~/models/ApiModel'

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

@@ -16,10 +16,10 @@ Champs de saisie de type Text dédié à la saisie d'emails
 
 <script setup lang="ts">
 import { useNuxtApp } from '#app'
+import type { PropType } from 'vue'
+import { useI18n } from 'vue-i18n'
 import { useFieldViolation } from '~/composables/form/useFieldViolation'
 import { useValidationUtils } from '~/composables/utils/useValidationUtils'
-import type { PropType } from '@vue/runtime-core'
-import { useI18n } from 'vue-i18n'
 
 const props = defineProps({
   label: {

+ 2 - 3
components/Ui/Input/Image.vue

@@ -82,8 +82,8 @@ Assistant de création d'image
         </v-btn>
         <v-btn
           class="submitBtn theme-primary"
-          @click="save"
           :disabled="pending"
+          @click="save"
         >
           {{ $t('save') }}
         </v-btn>
@@ -95,9 +95,8 @@ Assistant de création d'image
 <script setup lang="ts">
 import { Cropper } from 'vue-advanced-cropper'
 import 'vue-advanced-cropper/dist/style.css'
-import { type Ref, ref } from '@vue/reactivity'
+import { type Ref, ref, PropType } from 'vue'
 import File from '~/models/Core/File'
-import type { PropType } from '@vue/runtime-core'
 import { useEntityManager } from '~/composables/data/useEntityManager'
 import { useImageManager } from '~/composables/data/useImageManager'
 import { FILE_VISIBILITY, IMAGE_SIZE, TYPE_ALERT } from '~/types/enum/enums'

+ 1 - 2
components/Ui/Input/Text.vue

@@ -28,9 +28,8 @@ Champs de saisie de texte, à placer dans un composant `UiForm`
 </template>
 
 <script setup lang="ts">
-import { type Ref, ref } from '@vue/reactivity'
+import { type Ref, ref, PropType } from 'vue'
 import { useFieldViolation } from '~/composables/form/useFieldViolation'
-import type { PropType } from '@vue/runtime-core'
 
 const props = defineProps({
   /**

+ 1 - 1
composables/data/useImageFetch.ts

@@ -21,7 +21,7 @@ export const useImageFetch = (): useImageFetchReturnType => {
   const fetch = (
     id: Ref<number | null>, // If id is null, fetch shall return the default image url
     size: IMAGE_SIZE = IMAGE_SIZE.MD,
-    defaultImage: string | null = null
+    defaultImage: string | null = null,
   ) =>
     useAsyncData(
       'img' + (id ?? defaultImage ?? 0) + '_' + uuid4(),

+ 4 - 1
pages/parameters/subdomains/new.vue

@@ -119,7 +119,10 @@ const checkAvailabilityDebounced: _.DebouncedFunc<() => void> = _.debounce(
 const onSubdomainUpdate = () => {
   subdomainAvailable.value = null
 
-  if (subdomain.value.subdomain !== null && SubdomainValidation.isValid(subdomain.value.subdomain)) {
+  if (
+    subdomain.value.subdomain !== null &&
+    SubdomainValidation.isValid(subdomain.value.subdomain)
+  ) {
     // Le sous domaine est valide: on vérifie sa disponibilité
     validationPending.value = true
     checkAvailabilityDebounced()

+ 3 - 2
pages/parameters/website.vue

@@ -101,7 +101,9 @@
             <div class="px-4 d-flex flex-row align-center justify-center py-2">
               <v-icon class="theme-info">fa fa-info</v-icon>
             </div>
-            <div class="px-2 d-flex flex-row align-center justify-left flex-grow-1">
+            <div
+              class="px-2 d-flex flex-row align-center justify-left flex-grow-1"
+            >
               {{ $t('a_short_subdomains_definition') }}
             </div>
             <v-img
@@ -183,7 +185,6 @@ const onAddSubdomainClick = () => {
   }
 
   @media (max-width: 600px) {
-
     :deep(.v-btn) {
       height: auto;
       margin: 15px 0;

+ 14 - 17
services/data/imageManager.ts

@@ -25,7 +25,7 @@ class ImageManager {
    * @param size
    * @param defaultImage The path of an image in the 'public' folder, default: '/images/default/picture.jpeg'
    */
-  public async get(
+  public get(
     id: number | string | null,
     size: IMAGE_SIZE = IMAGE_SIZE.MD,
     defaultImage: string | null = null,
@@ -33,7 +33,7 @@ class ImageManager {
     const defaultUrl = defaultImage ?? ImageManager.defaultImage
 
     if (id === null) {
-      return defaultUrl
+      return Promise.resolve(defaultUrl)
     }
 
     const matches = id.toString().match(/\/api\/files\/(\d+)(?:\/\w+)?/)
@@ -45,17 +45,16 @@ class ImageManager {
     }
 
     if (!(typeof id === 'number' && Number.isInteger(id))) {
-      throw new Error('Error: image ' + id + ' is invalid')
+      throw new TypeError('Error: image ' + id + ' is invalid')
     }
 
     try {
-      return size === IMAGE_SIZE.RAW ?
-        this.getRaw(id) :
-        this.getProcessed(id, size)
-
+      return size === IMAGE_SIZE.RAW
+        ? this.getRaw(id)
+        : this.getProcessed(id, size)
     } catch (error) {
       console.error(error)
-      return defaultUrl
+      return Promise.resolve(defaultUrl)
     }
   }
 
@@ -67,20 +66,19 @@ class ImageManager {
    */
   private async getProcessed(
     id: number | null,
-    size: IMAGE_SIZE = IMAGE_SIZE.MD
+    size: IMAGE_SIZE = IMAGE_SIZE.MD,
   ): Promise<string> {
-
-    let imageUrl = `api/image/download/${id}/${size}`
+    const imageUrl = `api/image/download/${id}/${size}`
 
     // Une image doit toujours avoir le time en options pour éviter les problèmes de cache
-    const query: AssociativeArray = {0: this.getCacheKey()}
+    const query: AssociativeArray = { 0: this.getCacheKey() }
 
-    const response = await this.apiRequestService.get(imageUrl, query);
+    const response = await this.apiRequestService.get(imageUrl, query)
 
     const cachedImageUrl = response.toString()
 
     if (!cachedImageUrl) {
-      throw new Error('Error: image ' + id + ' not found');
+      throw new Error('Error: image ' + id + ' not found')
     }
 
     return UrlUtils.addQuery(cachedImageUrl, query)
@@ -94,7 +92,6 @@ class ImageManager {
    * @private
    */
   private async getRaw(id: number | null): Promise<string> {
-
     const imageUrl = `api/file/download/${id}`
 
     // Une image doit toujours avoir le time en options pour éviter les problèmes de cache
@@ -102,11 +99,11 @@ class ImageManager {
 
     const blobPart = await this.apiRequestService.get(imageUrl, query)
     if (!blobPart) {
-      throw new Error('Error: image ' + id + ' not found');
+      throw new Error('Error: image ' + id + ' not found')
     }
 
     if (!(blobPart instanceof Blob) || blobPart.size === 0) {
-      throw new Error('Error: image ' + id + ' is invalid');
+      throw new Error('Error: image ' + id + ' is invalid')
     }
 
     return await this.toBase64(blobPart)

+ 1 - 1
types/enum/enums.ts

@@ -116,5 +116,5 @@ export const enum IMAGE_SIZE {
   SM = 'sm',
   MD = 'md',
   LG = 'lg',
-  RAW = 'raw'
+  RAW = 'raw',
 }