codevdesign 1.0.70 → 1.0.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,58 +1,46 @@
1
- <template>
2
- <v-icon
3
- end
4
- color="grisMoyen"
5
- icon="mdi-microsoft-excel"
6
- @click="exportToXLSX"
7
- >
8
- </v-icon>
9
- </template>
10
-
11
- <script setup lang="ts">
12
- import { utils, writeFileXLSX } from '@e965/xlsx'
13
- import { computed } from 'vue'
14
-
15
- const props = defineProps<{
16
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
- liste: any[]
18
- nomFichier: string
19
- chargementListe: boolean
20
- }>()
21
-
22
- // Extraction des clés uniques de tous les objets
23
- const cleDynamique = computed(() => {
24
- const keys: Set<string> = new Set()
25
-
26
- // Parcours tous les objets de la liste et ajoute leurs clés
27
- props.liste.forEach(item => {
28
- if (typeof item === 'object' && item !== null) {
29
- Object.keys(item).forEach(key => keys.add(key))
30
- }
31
- })
32
- return Array.from(keys)
33
- })
34
-
35
- // Fonction pour exporter les données en Excel
36
- const exportToXLSX = () => {
37
- if (!props.liste.length) {
38
- console.warn('La liste est vide, exportation annulée.')
39
- return
40
- }
41
-
42
- // Récupération des en-têtes depuis la fonction cleDynamique
43
- const headers = cleDynamique.value
44
-
45
- // Construction des lignes en respectant l'ordre des en-têtes
46
- const rows = props.liste.map(item => {
47
- return headers.map(key => (key in item ? item[key] : '')) // Valeur ou vide si absente
48
- })
49
-
50
- // Création des données Excel (en-têtes + lignes)
51
- const data = [headers, ...rows]
52
- // Génération du fichier Excel
53
- const ws = utils.aoa_to_sheet(data)
54
- const wb = utils.book_new()
55
- utils.book_append_sheet(wb, ws, '1')
56
- writeFileXLSX(wb, `${props.nomFichier}.xlsx`)
57
- }
58
- </script>
1
+ <template>
2
+ <v-icon
3
+ end
4
+ color="grisMoyen"
5
+ icon="mdi-microsoft-excel"
6
+ @click="exportToXLSX"
7
+ >
8
+ </v-icon>
9
+ </template>
10
+
11
+ <script setup lang="ts">
12
+ import { utils, writeFileXLSX } from '@e965/xlsx'
13
+ import type Colonne from '../../modeles/composants/datatableColonne'
14
+
15
+ const props = defineProps<{
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ liste: any[]
18
+ nomFichier: string
19
+ chargementListe: boolean
20
+ colonnes: Colonne[]
21
+ }>()
22
+
23
+ // Fonction pour exporter les données en Excel
24
+ const exportToXLSX = () => {
25
+ if (!props.liste.length) {
26
+ console.warn('La liste est vide, exportation annulée.')
27
+ return
28
+ }
29
+
30
+ // Colonnes affichées (on exclut action et ancre)
31
+ const colonnesExport = props.colonnes.filter(c => c.key && c.key !== 'action' && c.key !== 'ancre')
32
+
33
+ const headers = colonnesExport.map(c => c.title ?? String(c.key))
34
+ const keys = colonnesExport.map(c => String(c.key))
35
+
36
+ const rows = props.liste.map(item => {
37
+ return keys.map(key => (key in item ? item[key] : ''))
38
+ })
39
+
40
+ const data = [headers, ...rows]
41
+ const ws = utils.aoa_to_sheet(data)
42
+ const wb = utils.book_new()
43
+ utils.book_append_sheet(wb, ws, '1')
44
+ writeFileXLSX(wb, `${props.nomFichier}.xlsx`)
45
+ }
46
+ </script>
@@ -60,9 +60,19 @@
60
60
  </v-card-actions>
61
61
  </v-card>
62
62
  </v-navigation-drawer>
63
+ <Teleport to="body">
64
+ <v-fab
65
+ v-if="retourEnHaut && afficherBoutonHaut"
66
+ style="position: fixed; bottom: 24px; right: 24px; z-index: 2000"
67
+ elevation="8"
68
+ color="primary"
69
+ icon="mdi-arrow-up"
70
+ @click="allerEnHaut"
71
+ />
72
+ </Teleport>
63
73
  </template>
64
74
  <script lang="ts" setup>
65
- import { ref, computed } from 'vue'
75
+ import { ref, computed, watch, nextTick } from 'vue'
66
76
  import { useDisplay } from 'vuetify'
67
77
 
68
78
  const visible = ref(false)
@@ -102,11 +112,40 @@
102
112
  default: '',
103
113
  required: false,
104
114
  },
115
+ retourEnHaut: {
116
+ type: Boolean,
117
+ default: true,
118
+ },
105
119
  })
106
120
 
107
121
  // Déclaration des événements
108
122
  const emit = defineEmits(['fermer', 'ok'])
109
123
 
124
+ // Back to top
125
+ const afficherBoutonHaut = ref(false)
126
+ let conteneurScroll: Element | null = null
127
+
128
+ function onScroll() {
129
+ afficherBoutonHaut.value = (conteneurScroll?.scrollTop ?? 0) > 350
130
+ }
131
+
132
+ function allerEnHaut() {
133
+ conteneurScroll?.scrollTo({ top: 0, behavior: 'smooth' })
134
+ }
135
+
136
+ watch(visible, async val => {
137
+ if (!props.retourEnHaut) return
138
+ if (val) {
139
+ await nextTick()
140
+ conteneurScroll = document.querySelector('.v-navigation-drawer--active .v-navigation-drawer__content')
141
+ conteneurScroll?.addEventListener('scroll', onScroll)
142
+ } else {
143
+ conteneurScroll?.removeEventListener('scroll', onScroll)
144
+ conteneurScroll = null
145
+ afficherBoutonHaut.value = false
146
+ }
147
+ })
148
+
110
149
  // Méthodes
111
150
  const ouvrir = () => {
112
151
  visible.value = true
@@ -59,6 +59,12 @@ class RafraichisseurToken {
59
59
  private estJetonValide(nomTemoin: string): boolean {
60
60
  if (this.popupAffiche || !nomTemoin) return true //On fait semblant que c'est valide pour ne pas provoquer un autre affichage du popup.
61
61
 
62
+ // Vérifier aussi le cookie principal (csqc_jeton_secure) en plus du sentinel d'expiration
63
+ const nomPrincipal = nomTemoin.replace('_expiration', '')
64
+ if (nomPrincipal !== nomTemoin && !this.lireCookie(nomPrincipal)) {
65
+ return false
66
+ }
67
+
62
68
  const tokenEncode = this.lireCookie(nomTemoin)
63
69
  if (!tokenEncode) {
64
70
  return false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codevdesign",
3
- "version": "1.0.70",
3
+ "version": "1.0.72",
4
4
  "description": "Composants Vuetify 3 pour les projets Codev",
5
5
  "files": [
6
6
  "./**/*.vue",