瀏覽代碼

Merge branch 'feature/v8-4026_validate_alerts_notifs_sse' into develop

Olivier Massot 2 年之前
父節點
當前提交
11b1bd9b55

+ 2 - 2
components/Layout/AlertBar.vue

@@ -11,7 +11,7 @@ Contient les différentes barres d'alertes qui s'affichent dans certains cas
     <LayoutAlertBarSwitchUser />
 
     <client-only>
-      <LayoutAlertBarCotisation v-if="organizationProfile.isCmf && can('manage', 'cotisation')" />
+      <LayoutAlertBarCotisation v-if="organizationProfile.isCmf && ability.can('manage', 'cotisation')" />
     </client-only>
 
     <LayoutAlertBarSwitchYear />
@@ -24,5 +24,5 @@ Contient les différentes barres d'alertes qui s'affichent dans certains cas
   import {useAbility} from "@casl/vue";
 
   const organizationProfile = useOrganizationProfileStore()
-  const { can } = useAbility()
+  const ability = useAbility()
 </script>

+ 6 - 2
components/Layout/AlertBar/Cotisation.vue

@@ -6,7 +6,6 @@ Barre d'alerte qui s'affiche pour donner l'état de la cotisation
 
 <template>
   <main>
-    <!-- TODO : vérifier le bon fonctionnement -->
     <UiSystemBar
         v-if="alert !== null"
         :text="$t(alert.text)"
@@ -32,7 +31,6 @@ const baseLegacyUrl: string = runtimeConfig.baseUrlAdminLegacy
 
 const cotisationYear: Ref<number | null> = ref(null)
 
-
 /**
  * Redirige l'utilisateur vers la page des cotisations
  */
@@ -96,3 +94,9 @@ if (cotisation.value !== null) {
 }
 
 </script>
+
+<style scoped lang="scss">
+  :deep(.clickable:hover) {
+    text-decoration: none !important;
+  }
+</style>

+ 5 - 5
components/Layout/AlertBar/SuperAdmin.vue

@@ -6,12 +6,12 @@ Barre d'alerte qui s'affiche lorsque l'utilisateur est un super admin en mode sw
 
 <template>
   <!-- TODO : fonctionnement à valider -->
-  <UiSystemBar v-if="show" text-color="danger">
+  <UiSystemBar v-if="show" class="theme-danger">
     <v-icon small>fas fa-exclamation-triangle</v-icon>
-    <span>{{ $t('super_admin_switch_account') }}</span>
+    <span>{{ $t('super_admin_switch_account') }} </span>
 
-    <a v-if="url" :href="url" class="text-neutral-strong text-decoration-none">
-      <strong>{{ $t('click_here') }}</strong>
+    <a v-if="url" :href="url" class="text-decoration-none on-danger">
+      &nbsp;<strong>{{ $t('click_here') }}</strong>
     </a>
   </UiSystemBar>
 </template>
@@ -36,7 +36,7 @@ Barre d'alerte qui s'affiche lorsque l'utilisateur est un super admin en mode sw
     const originalAccessId = accessProfile.originalAccess ? accessProfile.originalAccess.id : null
 
     if (show && orgId && originalAccessId) {
-      return UrlUtils.join(baseLegacyUrl, 'switch_user', orgId, originalAccessId, 'exit')
+      return UrlUtils.join(baseLegacyUrl, '#', 'switch_user', orgId, originalAccessId, 'exit')
     }
     return ''
   })

+ 7 - 7
components/Layout/AlertBar/SwitchUser.vue

@@ -5,12 +5,11 @@ Barre qui s'affiche lorsque l'utilisateur possède un compte multi user
 -->
 
 <template>
-  <!-- TODO : fonctionnement à valider -->
-  <UiSystemBar v-if="show" text-color="info">
+  <UiSystemBar v-if="show" class="theme-info">
     <v-icon small icon="fas fa-info-circle" />
-    <span v-html="$t('multi_account_alert', { fullname })" />
-    <v-icon class="ml-1" small icon="fa fa-users" />
-    {{$t('multi_account_alert_next')}}
+    <span v-html="$t('multi_account_alert', { fullName })" />&nbsp;
+
+    <v-icon class="pl-1" small icon="fa fa-users"/> &nbsp;{{$t('multi_account_alert_next')}}
   </UiSystemBar>
 </template>
 
@@ -21,8 +20,9 @@ Barre qui s'affiche lorsque l'utilisateur possède un compte multi user
   const accessProfile = useAccessProfileStore()
   const { hasMenu } = useMenu()
 
-  const show = hasMenu('Family')
-  const fullname = `${accessProfile.givenName} ${accessProfile.name}`
+  const show = computed(() => hasMenu('MyFamily'))
+
+  const fullName = `${accessProfile.givenName} ${accessProfile.name}`
 </script>
 
 <style scoped lang="scss">

+ 4 - 5
components/Layout/AlertBar/SwitchYear.vue

@@ -6,13 +6,11 @@ Barre d'alerte qui s'affiche lorsque l'utilisateur n'est pas sur l'année couran
 
 <template>
   <!-- TODO : fonctionnement à valider -->
-  <UiSystemBar v-if="show" text-color="warning">
+  <UiSystemBar v-if="show" class="theme-warning">
     {{$t('not_current_year')}}
 
-    <a @click="resetYear">
-      <strong class="text-neutral-strong">
-        {{$t('not_current_year_reset')}}
-      </strong>
+    <a @click="resetYear" class="text-decoration-none on-warning" style="cursor: pointer;">
+      &nbsp;<strong>{{$t('not_current_year_reset')}}</strong>
     </a>
   </UiSystemBar>
 </template>
@@ -43,6 +41,7 @@ Barre d'alerte qui s'affiche lorsque l'utilisateur n'est pas sur l'année couran
       accessProfile.activityYear = organizationProfile.currentActivityYear
     }
 
+    // Il faut ajouter un patch sur le profile ici
     setDirty(false)
 
     window.location.reload()

+ 4 - 4
components/Layout/Header/Menu.vue

@@ -9,8 +9,8 @@ header principal (configuration, paramètres du compte...)
     <v-btn
         ref="btn"
         icon
-        width="48px"
         size="small"
+        class="ml-2"
     >
       <v-avatar
           v-if="menu.icon.avatarId || menu.icon.avatarByDefault"
@@ -54,9 +54,9 @@ header principal (configuration, paramètres du compte...)
                   :href="!isInternalLink(child) ? child.to : undefined"
                   :to="isInternalLink(child) ? child.to : undefined"
               >
-                <v-list-item-title>
-                    <span v-if="child.icon">
-                      <v-avatar v-if="menu.icon.avatarId || child.icon.avatarByDefault" size="30">
+                <v-list-item-title class="d-flex align-center">
+                    <span v-if="child.icon" class="pr-2">
+                      <v-avatar v-if="menu.icon.avatarId || child.icon.avatarByDefault" size="30" >
                         <UiImage :id="child.icon.avatarId" :defaultImage="child.icon.avatarByDefault" :width="30" />
                       </v-avatar>
                       <v-icon v-else class="on-primary" size="small">

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

@@ -2,8 +2,8 @@
   <v-btn
       ref="btn"
       icon
-      width="48px"
       size="small"
+      class="ml-2"
   >
     <v-badge
         color="warning"

+ 11 - 12
components/Layout/SubHeader/PersonnalizedList.vue

@@ -1,18 +1,14 @@
 <template>
   <main>
-    <a ref="btn">
+    <a ref="btn" id="activator">
       {{ $t('my_list') }}
     </a>
 
     <v-menu
         :activator="btn"
-        :model-value="showMenu"
-        location="start"
+        offset="10"
         :close-on-content-click="false"
-        min-width="500"
-        @update:modelValue="onMenuToggled($event)"
     >
-
       <v-card v-if="collection.totalItems === 0" height="80" class="pa-4">
         <v-card-text class="ma-0 pa-0 header_menu">
           {{ $t('nothing_to_show') }}
@@ -59,11 +55,6 @@ import {AnyJson} from "~/types/data";
 import ApiResource from "~/models/ApiResource";
 
 const btn: Ref = ref(null)
-const showMenu: Ref<boolean> = ref(false)
-
-const onMenuToggled = (event: any) => {
-  showMenu.value = event
-}
 
 const { fetch, fetchCollection } = useEntityFetch()
 
@@ -100,7 +91,15 @@ const getListURL = (list: PersonalizedList) => {
 }
 </script>
 
-<style lang="scss">
+<style scoped lang="scss">
+  #activator {
+    cursor: pointer;
+  }
+
+  #activator:hover {
+    color: rgb(var(--var-theme-on-neutral)) !important;
+  }
+
   .header-personalized {
     margin-bottom: 0;
     padding-bottom: 0;

+ 11 - 1
composables/data/useEntityFetch.ts

@@ -2,12 +2,17 @@ import {useEntityManager} from "~/composables/data/useEntityManager";
 import ApiResource from "~/models/ApiResource";
 import {AssociativeArray, Collection} from "~/types/data";
 import {AsyncData} from "#app";
+import {ComputedRef, Ref} from "vue";
 
 interface useEntityFetchReturnType {
     fetch: (model: typeof ApiResource, id: number) => AsyncData<ApiResource, ApiResource | true>,
     fetchCollection: (model: typeof ApiResource, parent?: ApiResource | null, query?: AssociativeArray) => AsyncData<Collection, any>
+    // @ts-ignore
+    getRef: <T extends ApiResource>(model: typeof T, id: Ref<number | null>) => ComputedRef<null | T>
 }
 
+
+// TODO: améliorer le typage des fonctions sur le modèle de getRef
 export const useEntityFetch = (lazy: boolean = false): useEntityFetchReturnType => {
     const { em } = useEntityManager()
 
@@ -23,6 +28,11 @@ export const useEntityFetch = (lazy: boolean = false): useEntityFetchReturnType
         { lazy }
     )
 
+    // @ts-ignore
+    const getRef = <T extends ApiResource>(model: typeof T, id: Ref<number | null>): ComputedRef<T | null> => {
+        return computed(() => (id.value ? em.find(model, id.value) as T : null))
+    }
+
     //@ts-ignore
-    return { fetch, fetchCollection }
+    return { fetch, fetchCollection, getRef }
 }

+ 2 - 3
composables/data/useEntityManager.ts

@@ -3,11 +3,10 @@ import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
 import ApiResource from "~/models/ApiResource";
 import {useRepo} from "pinia-orm";
 
-let entityManager:EntityManager|null = null
+let entityManager: EntityManager | null = null
 
 export const useEntityManager = () => {
-    //Avoid memory leak
-    if(entityManager === null){
+    if (entityManager === null) {
         const { apiRequestService } = useAp2iRequestService()
         const getRepo = (model: typeof ApiResource) => useRepo(model)
 

+ 3 - 0
composables/layout/useMenu.ts

@@ -26,6 +26,9 @@ export const useMenu = () => {
 
   /**
    * Construct all Menus
+   * TODO: ce serait mieux de conserver les ids des menus même non possédés, de façon à pouvoir différencier un menu
+   * non possédé et un id incorrect dans getMenu par exemple. J'ai eu du mal capter pourquoi hasMenu('Family') renvoyait
+   * false, jusqu'à ce que je tilte que le menu s'appellait MyFamily, et pas Family
    */
   const buildAllMenu = () => {
     MenuComposer.build(runtimeConfig, ability, organizationProfile, accessProfile as AccessProfile, layoutState)

+ 19 - 0
composables/utils/useDownloadFile.ts

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

+ 2 - 2
lang/fr.json

@@ -386,9 +386,9 @@
   "cotisation_access": "Accéder au renouvellement de cotisation à ma fédération",
   "information_new_online_registration": "Nouvelle préinscription",
   "not_production_environment": "ATTENTION ! Vous êtes sur un environnement {env}.",
-  "multi_account_alert": "Vous êtes connecté, en tant que <strong>{fullname}</strong>, avec un accès famille. Utilisez l'icône",
+  "multi_account_alert": "Vous êtes connecté, en tant que <strong>{fullName}</strong>, avec un accès famille. Utilisez l'icône",
   "multi_account_alert_next": "en haut à droite pour changer les informations des autres membres de votre famille.",
-  "not_current_year": "Votre logiciel est actuellement placé dans une autre année que celle actuelle, et/ou affiche des données passées/futures.",
+  "not_current_year": "Les données affichées correspondent à une autre année que l'année actuelle, et/ou sont des données passées ou futures.",
   "not_current_year_reset": "Cliquez ici pour afficher les données de l'année actuelle.",
   "welcome": "Accueil",
   "address_book": "Répertoire",

+ 5 - 2
models/Export/LicenceCmfOrganizationER.ts

@@ -7,7 +7,7 @@ import ApiResource from "~/models/ApiResource";
  * @see https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/src/ApiResources/Export/LicenceCmf/LicenceCmfOrganizationER.php
  */
 export default class LicenceCmfOrganizationER extends ApiResource {
-  static entity = ''
+  static entity = 'export/cmf-licence/organization'
 
   @Uid()
   declare id: number | string | null
@@ -15,9 +15,12 @@ export default class LicenceCmfOrganizationER extends ApiResource {
   @Str(null)
   declare format: string | null
 
-  @Num(0)
+  @Num(null)
   declare requesterId: number | string | null
 
   @Bool(false)
   declare async: boolean
+
+  @Num(null)
+  declare fileId: number | string | null
 }

+ 3 - 1
package.json

@@ -30,11 +30,13 @@
     "@nuxtjs/i18n": "^8.0.0-beta.9",
     "@pinia-orm/nuxt": "^1.1.7",
     "@pinia/nuxt": "0.4.6",
+    "@types/file-saver": "^2.0.5",
     "@types/js-yaml": "^4.0.5",
     "@types/vue-the-mask": "^0.11.1",
     "cleave.js": "^1.6.0",
     "date-fns": "^2.29.3",
     "event-source-polyfill": "^1.0.31",
+    "file-saver": "^2.0.5",
     "js-yaml": "^4.1.0",
     "libphonenumber-js": "1.10.19",
     "nuxt": "^3.2.0",
@@ -46,7 +48,7 @@
     "vite-plugin-vuetify": "^1.0.1",
     "vue-tel-input-vuetify": "^1.5.3",
     "vue-the-mask": "^0.11.1",
-    "vuetify": "3.1.5",
+    "vuetify": "3.1.6",
     "yaml-import": "^2.0.0"
   },
   "devDependencies": {

+ 121 - 0
pages/cmf_licence/organization.vue

@@ -0,0 +1,121 @@
+<template>
+  <div class="d-flex flex-column align-center">
+    <h2 class="ma-4">{{ $t('cmf_structure_licence')}}</h2>
+    <a
+        href="https://www.cmf-musique.org/services/tarifs-preferentiels/"
+        target="_blank"
+    >
+      {{ $t('cmf_licence_details_url')}}
+    </a>
+
+    <v-form
+        ref="form"
+        lazy-validation
+    >
+      <div class="ma-12">
+        <v-btn
+            v-if="!pending && file === null"
+            @click="submit"
+        >
+          {{ $t('generate') }}
+        </v-btn>
+
+        <v-btn
+            v-else
+            color="primary"
+            :loading="pending"
+            :disabled="pending"
+            target="_blank"
+            @click="download"
+        >
+          {{ $t('download') }}
+        </v-btn>
+      </div>
+    </v-form>
+  </div>
+</template>
+
+<script setup lang="ts">
+import File from "~/models/Core/File"
+import {ComputedRef, Ref} from "vue";
+import {useEntityFetch} from "~/composables/data/useEntityFetch";
+import {useSseStore} from "~/stores/sse";
+import {useEntityManager} from "~/composables/data/useEntityManager";
+import LicenceCmfOrganizationER from "~/models/Export/LicenceCmfOrganizationER";
+import {useDownloadFile} from "~/composables/utils/useDownloadFile";
+import {useRepo} from "pinia-orm";
+
+const { em } = useEntityManager()
+const { getRef } = useEntityFetch()
+
+const sseStore = useSseStore()
+const async = () => { return sseStore.connected }
+
+const fileId = ref(null)
+
+// TODO: il y a quelque chose à creuser ici, cette ref est nécessaire pour garder le lien avec le store,
+//       car on ne peut pas directement passer par le fetch de useEntityFetch ici (puisqu'on a pas encore l'id
+//       au chargement). Il faudrait voir si on ne pourrait pas intégrer ça au fetch, ou faire un fetchOrNull, qui
+//       combine fetch et getRef?
+const file: ComputedRef<File | null> = getRef(File, fileId)
+
+// Submitting export request
+const submitting: Ref<boolean> = ref(false)
+
+// File is downloading
+const downloading: Ref<boolean> = ref(false)
+
+const pending: ComputedRef<boolean> = computed(() => {
+  return submitting.value || (file.value !== null && file.value.status === 'PENDING') || downloading.value
+})
+
+const submit = async () => {
+  submitting.value = true
+
+  const exportRequest = em.newInstance(LicenceCmfOrganizationER)
+
+  exportRequest.format = 'pdf'
+
+  if (async()) {
+    exportRequest.async = true
+  } else {
+    console.error('SSE unavailable - File will be downloaded synchronously')
+  }
+
+  try {
+    // Send the export request and get the receipt
+    const receipt = await em.persist(LicenceCmfOrganizationER, exportRequest)
+    if (receipt.fileId === null) {
+      throw new Error("Missing file's id, abort")
+    }
+    fileId.value = receipt.fileId
+
+    // Fetch the newly created file from API. If export is async, it will be a record about a pending file,
+    // SSE will update its status to ready when it'll be.
+    await em.fetch(File, receipt.fileId)
+
+  } finally {
+    submitting.value = false
+  }
+}
+
+const download = async () => {
+  downloading.value = true
+
+  if (file.value === null) {
+    console.error("File is not defined yet, impossible to download")
+    return
+  }
+
+  if (file.value.status === 'PENDING') {
+    console.error("File is still pending, impossible to download")
+    return
+  }
+
+  try {
+    await useDownloadFile(file.value)
+  } finally {
+    downloading.value = false
+  }
+}
+</script>

+ 3 - 1
plugins/init.server.ts

@@ -8,6 +8,7 @@ export default defineNuxtPlugin(async () => {
 
     const bearer = useCookie('BEARER')
     let accessCookieId = useCookie('AccessId')
+    const switchId = useCookie('SwitchAccessId')
 
     if (accessCookieId.value === null || Number.isNaN(accessCookieId.value)) {
         redirectToLogout()
@@ -20,7 +21,8 @@ export default defineNuxtPlugin(async () => {
 
     accessProfile.$patch({
         bearer: bearer.value,
-        id: accessId
+        id: accessId,
+        switchId: switchId.value !== null ? parseInt(switchId.value) : null
     })
 
     const {em} = useEntityManager()

+ 11 - 3
plugins/sse.client.ts

@@ -1,6 +1,7 @@
 import SseSource from "~/services/sse/sseSource";
 import {useAccessProfileStore} from "~/stores/accessProfile";
 import {useSseStore} from "~/stores/sse";
+import {AnyJson} from "~/types/data";
 
 /**
  * Setup SSE EventSource, allowing the app to listen for Mercure updates
@@ -19,12 +20,19 @@ export default defineNuxtPlugin(nuxtApp => {
     const accessProfile = useAccessProfileStore()
     const sseStore = useSseStore()
 
+    const onOpen = () => sseStore.connected = true
+    const onClose = () => sseStore.connected = false
+
+    const onMessage = (eventData: AnyJson) => {
+        sseStore.addEvent(eventData as any)
+    }
+
     const sseSource = new SseSource(
         runtimeConfig.baseUrlMercure,
         "access/" + accessProfile.id,
-        () => { sseStore.connected = true },
-        (eventData) => { sseStore.addEvent(eventData as any) },
-        () => { sseStore.connected = false },
+        onOpen,
+        onMessage,
+        onClose,
     )
 
     sseSource.subscribe()

+ 3 - 1
services/data/entityManager.ts

@@ -14,6 +14,7 @@ import _ from "lodash"
 /**
  * Entity manager: make operations on the models defined with the Pinia-Orm library
  *
+ * TODO: améliorer le typage des méthodes sur le modèle de find()
  * @see https://pinia-orm.codedredd.de/
  */
 class EntityManager {
@@ -116,6 +117,7 @@ class EntityManager {
      *                  record is also updated.
      */
     public save(model: typeof ApiResource, instance: ApiResource, permanent: boolean = false): ApiResource {
+        instance = this.cast(model, instance)
         if (permanent) {
             this.saveInitialState(model, instance)
         }
@@ -124,7 +126,7 @@ class EntityManager {
 
     /**
      * Find the model instance in the store
-     * TODO: comment réagit la fonction si l'id n'existe pas?
+     * TODO: comment réagit la fonction si l'id n'existe pas dans le store?
      *
      * @param model
      * @param id

+ 0 - 15
services/data/fileManager.ts

@@ -1,15 +0,0 @@
-import ApiRequestService from "./apiRequestService";
-
-class FileManager {
-    private apiRequestService: ApiRequestService;
-
-    public constructor(apiRequestService: ApiRequestService) {
-        this.apiRequestService = apiRequestService
-    }
-
-    public fetch() {
-        // TODO: récupérer le contenu de fileNormalizer ici
-    }
-}
-
-export default FileManager

+ 0 - 24
services/data/normalizer/fileNormalizer.ts

@@ -1,24 +0,0 @@
-/**
- * @category Services/serializer/normalizer
- * @class Default
- * Classe assurant la normalization par défaut
- */
-class FileNormalizer {
-  /**
-   * On transforme les data en FormData et on les renvois
-   * @return {any} réponse
-   * @param data
-   * @param file
-   */
-  public static normalize (data: any, file: string): any {
-    // TODO : intégrer au FileManager
-    const fileData = new FormData();
-    for(const key in data){
-      fileData.set(key, data[key])
-    }
-
-    fileData.set('file', file as string)
-    return fileData
-  }
-}
-export default FileNormalizer

+ 2 - 2
services/sse/sseSource.ts

@@ -7,7 +7,7 @@ class SseSource {
   protected readonly onClose: (() => void)
   protected readonly withCredentials: boolean
   protected eventSource: EventSourcePolyfill | null = null
-  constructor(
+  constructor (
     mercureHubBaseUrl: string,
     topic: string,
     onOpen: (() => void),
@@ -28,7 +28,7 @@ class SseSource {
       url,
       {
         withCredentials: withCredentials,
-        heartbeatTimeout: 45 * 1000 // in ms, timeout can not be disabled yet, so I set it very large instead
+        heartbeatTimeout: 45 * 1000 // in ms
       }
     );
   }

+ 19 - 38
stores/accessProfile.ts

@@ -120,51 +120,34 @@ export const useAccessProfileStore = defineStore('accessProfile', () => {
     isPayer.value = profile.isPayor
     roles.value = RoleUtils.filterFunctionRoles(profileRoles)
 
-    // Time to add the original Access (switch User case)
-    originalAccess.value = profile.originalAccess
+    // Add the original Access (switch User case)
+    if (profile.originalAccess !== null) {
+      originalAccess.value = {
+        id: profile.originalAccess.id,
+        name: profile.originalAccess.name,
+        givenName: profile.originalAccess.givenName,
+        gender: profile.originalAccess.gender,
+        isSuperAdminAccess: profile.originalAccess.isSuperAdminAccess,
+        avatarId: profile.originalAccess.avatarId,
+        organization: {
+          id: profile.originalAccess.organization.id,
+          name: profile.originalAccess.organization.name
+        } as BaseOrganizationProfile
+      } as OrignalAccessProfile
+    }
 
-    // Time to set Multi Accesses
+    // Set multi-accesses
     setMultiAccesses(profile.multiAccesses)
 
-    // Time to set Family Accesses
+    // Set family-accesses
     setFamilyAccesses(profile.familyAccesses)
 
-    // Time to set Organization Profile
+    // Set organization profile
+    // TODO: à voir si c'est bien d'appeler un autre store d'ici où s'il vaudrait mieux le faire dans la couche supérieure
     const organizationProfile = useOrganizationProfileStore()
     organizationProfile.setProfile(profile.organization)
   }
 
-  const refreshProfile = (profile: any) => {
-    name.value = profile.name
-    givenName.value = profile.givenName
-    gender.value = profile.gender
-    avatarId.value = profile.avatarId
-    activityYear.value = profile.activityYear
-
-    const organizationProfileStore = useOrganizationProfileStore()
-    organizationProfileStore.refreshProfile(profile.organization)
-  }
-
-  const setOriginalAccess = (access: any) => {
-    if (access) {
-      const organization: BaseOrganizationProfile = {
-        id: access.organization.id,
-        name: access.organization.name
-      }
-
-      const originalAccess: OrignalAccessProfile = {
-        id: access.id,
-        name: access.name,
-        givenName: access.givenName,
-        gender: access.gender,
-        isSuperAdminAccess: access.isSuperAdminAccess,
-        avatarId: access.avatarId,
-        organization: organization
-      }
-      setOriginalAccess(originalAccess)
-    }
-  }
-
   const setHistorical = (past: boolean, present: boolean, future: boolean) => {
     historical.value = <Historical> {
       past,
@@ -216,8 +199,6 @@ export const useAccessProfileStore = defineStore('accessProfile', () => {
     setMultiAccesses,
     setFamilyAccesses,
     setProfile,
-    refreshProfile,
-    setOriginalAccess,
     setHistorical,
     setHistoricalRange
   }

+ 14 - 4
yarn.lock

@@ -1321,6 +1321,11 @@
   resolved "https://registry.yarnpkg.com/@types/event-source-polyfill/-/event-source-polyfill-1.0.1.tgz#ffcb4ca17bc35bc1ca5d3e047fe833292bb73c32"
   integrity sha512-dls8b0lUgJ/miRApF0efboQ9QZnAm7ofTO6P1ILu8bRPxUFKDxVwFf8+TeuuErmNui6blpltyr7+eV72dbQXlQ==
 
+"@types/file-saver@^2.0.5":
+  version "2.0.5"
+  resolved "https://registry.yarnpkg.com/@types/file-saver/-/file-saver-2.0.5.tgz#9ee342a5d1314bb0928375424a2f162f97c310c7"
+  integrity sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==
+
 "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44"
@@ -3886,6 +3891,11 @@ file-entry-cache@^6.0.1:
   dependencies:
     flat-cache "^3.0.4"
 
+file-saver@^2.0.5:
+  version "2.0.5"
+  resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38"
+  integrity sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==
+
 file-uri-to-path@1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
@@ -8158,10 +8168,10 @@ vue@^3.2.47:
     "@vue/server-renderer" "3.2.47"
     "@vue/shared" "3.2.47"
 
-vuetify@3.1.5:
-  version "3.1.5"
-  resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-3.1.5.tgz#6cf56891f2fa7502feec1a7b50bef6aa4bc4623e"
-  integrity sha512-6DJYNuKrbxuL+MThmj+VbtvK9X3mY+s8Rqj1juj4RyeLSIAhE3byZf8Bo2/GxrU5Jv3zR07LZdpiq4wIl0ONzA==
+vuetify@3.1.6:
+  version "3.1.6"
+  resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-3.1.6.tgz#9ba513ac7b3ca9b0c7817dc63a8c18079eea9e49"
+  integrity sha512-4We27L5ksy8esNKfUPWPucEU+M7XJDO2o66zXL5qiBVbALwshcK2CAobLQMx+ALtkLENXAYNH3RzvfAYjTi3Aw==
 
 vuetify@^2.2.11:
   version "2.6.14"