codevdesign 0.0.89 → 0.0.91

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,260 +1,260 @@
1
- <template>
2
- <div>
3
- <v-form
4
- ref="form"
5
- v-model="formValide"
6
- @submit.prevent
7
- >
8
- <v-combobox
9
- v-model="codeBudgetaire"
10
- :items="codeBudgetairesProp"
11
- :label="label"
12
- persistent-hint
13
- variant="outlined"
14
- hide-details="auto"
15
- :error="!estValide"
16
- :rules="[v => (estValide ? true : regleMessageErreur)]"
17
- :disabled="disable"
18
- :density="density"
19
- :hint="afficherHint ? placeholder : ''"
20
- :max-width="maxWidth || '100%'"
21
- :min-width="minWidth || '100%'"
22
- @blur="sauvegarder"
23
- @keydown.enter="sauvegarder"
24
- @keydown="caractereAutorises"
25
- @update:modelValue="gererChangement"
26
- @paste="gererPaste"
27
- />
28
- </v-form>
29
- </div>
30
- </template>
31
-
32
- <script setup lang="ts">
33
- import { ref, computed, onMounted, nextTick } from 'vue'
34
- import type { VForm } from 'vuetify/components'
35
-
36
- const emit = defineEmits(['update:modelValue', 'update:codeBudgetairesProp'])
37
-
38
- const props = withDefaults(
39
- defineProps<{
40
- codeBudgetairesProp: string[]
41
- modelValue: string | null
42
- label: string
43
- disable: boolean
44
- afficherHint?: boolean
45
- regleMessageErreur: string
46
- density?: 'default' | 'comfortable' | 'compact'
47
- maxWidth?: string | number
48
- minWidth?: string | number
49
- format?: string
50
- activerExtension?: boolean
51
- }>(),
52
- {
53
- afficherHint: false,
54
- format: '999-9-99999-999',
55
- activerExtension: false,
56
- },
57
- )
58
-
59
- const formValide = ref(false)
60
- const form = ref<VForm | null>(null)
61
- const codeBudgetaire = ref(props.modelValue ?? '')
62
- const derniereValeurSauvegardee = ref<string | null>(null)
63
- const format = props.format
64
- const activerExtension = props.activerExtension
65
-
66
- const estValide = computed(() => {
67
- const val = codeBudgetaire.value?.toUpperCase().trim() || ''
68
- const base = val.slice(0, 15)
69
- const extension = val.slice(15)
70
-
71
- if (!/^\d{3}-\d{1}-\d{5}-\d{3}$/.test(base)) return false
72
-
73
- if (!activerExtension) return val.length === 15
74
-
75
- if (val.length === 15) return true
76
- if (val.length !== 22) return false
77
- if (extension.length !== 7) return false
78
-
79
- if (extension[3] !== '/') return false
80
- if (!/^[A-Z0-9/]$/i.test(extension[0]!)) return false
81
-
82
- const alphanumAt = [1, 2, 4, 5, 6]
83
- return alphanumAt.every(i => /^[A-Z0-9]$/i.test(extension[i]!))
84
- })
85
-
86
- const caractereAutorises = (e: KeyboardEvent) => {
87
- if (e.ctrlKey || e.metaKey) return
88
-
89
- const touchesSpecifiques = ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab', 'Home', 'End']
90
- if (touchesSpecifiques.includes(e.key)) return
91
-
92
- const input = e.target as HTMLInputElement
93
- let position = input.selectionStart ?? 0
94
-
95
- // Gestion de la partie de base (15 premiers caractères)
96
- if (position < 15) {
97
- if (!/^\d$/.test(e.key)) {
98
- e.preventDefault()
99
- return
100
- }
101
-
102
- // Insérer chiffre et auto-ajout des tirets
103
- e.preventDefault()
104
-
105
- const value = codeBudgetaire.value.replace(/-/g, '')
106
- const clean = value.slice(0, 12) + e.key
107
-
108
- let formatted = ''
109
- if (clean.length > 0) formatted += clean.slice(0, 3)
110
- if (clean.length > 3) formatted += '-' + clean.slice(3, 4)
111
- if (clean.length > 4) formatted += '-' + clean.slice(4, 9)
112
- if (clean.length > 9) formatted += '-' + clean.slice(9, 12)
113
-
114
- codeBudgetaire.value = formatted.slice(0, 15)
115
-
116
- nextTick(() => {
117
- const newPos = codeBudgetaire.value.length
118
- input.selectionStart = input.selectionEnd = newPos
119
- })
120
-
121
- return
122
- }
123
-
124
- // --- Gestion de l'extension ---
125
- if (!activerExtension || position >= 22 || codeBudgetaire.value.length >= 22) {
126
- e.preventDefault()
127
- return
128
- }
129
-
130
- const extensionPos = position - 15
131
-
132
- // Règle 1 : extension[0] = alphanum ou /
133
- if (extensionPos === 0) {
134
- if (!/^[A-Z0-9/]$/i.test(e.key)) {
135
- e.preventDefault()
136
- return
137
- }
138
- return
139
- }
140
-
141
- // Règle 2 : extension[1,2,4,5,6] = alphanum
142
- if ([1, 2, 4, 5, 6].includes(extensionPos)) {
143
- if (!/^[A-Z0-9]$/i.test(e.key)) {
144
- e.preventDefault()
145
- return
146
- }
147
- return
148
- }
149
-
150
- // Règle 3 : slash automatique à position 3 (index 18)
151
- if (extensionPos === 3) {
152
- e.preventDefault()
153
- const before = codeBudgetaire.value.slice(0, position)
154
- const after = codeBudgetaire.value.slice(position)
155
- codeBudgetaire.value = before + '/' + after
156
- nextTick(() => {
157
- input.selectionStart = input.selectionEnd = position + 1
158
- })
159
- return
160
- }
161
-
162
- // Tout autre cas = bloqué
163
- e.preventDefault()
164
- }
165
-
166
- const formaterCodeBudgetaire = (valeur: string): string => {
167
- if (!valeur) return ''
168
-
169
- const upper = valeur.toUpperCase().replace(/[^A-Z0-9/]/g, '')
170
- const chiffres = upper.replace(/[^0-9]/g, '').slice(0, 12)
171
-
172
- let base = ''
173
- if (chiffres.length > 0) base += chiffres.slice(0, 3)
174
- if (chiffres.length > 3) base += '-' + chiffres.slice(3, 4)
175
- if (chiffres.length > 4) base += '-' + chiffres.slice(4, 9)
176
- if (chiffres.length > 9) base += '-' + chiffres.slice(9, 12)
177
-
178
- if (!activerExtension || base.length < 15) return base
179
-
180
- const reste = upper.slice(chiffres.length).replace(/[^A-Z0-9/]/gi, '')
181
-
182
- // Extraire les 7 premiers caractères restants pour l’extension
183
- let ext = reste.slice(0, 7).split('')
184
-
185
- // Ne garder que le premier slash s’il est à l’index 0 ou 3
186
- ext = ext.filter((c, i) => {
187
- if (c !== '/') return true
188
- return i === 0 || i === 3
189
- })
190
-
191
- // Enlever les slash non autorisés
192
- ext = ext.map((c, i) => {
193
- if (c === '/' && i !== 0 && i !== 3) return ''
194
- if (c !== '/' && !/^[A-Z0-9]$/i.test(c)) return ''
195
- return c
196
- })
197
-
198
- // Forcer le slash à la 4e position
199
- if (ext.length > 3) {
200
- ext[3] = '/'
201
- }
202
-
203
- // Réduire à 7 caractères
204
- ext = ext.slice(0, 7)
205
-
206
- return (base + ext.join('')).slice(0, 22)
207
- }
208
-
209
- const gererPaste = (e: ClipboardEvent) => {
210
- e.preventDefault()
211
- const clipboardData = e.clipboardData
212
- if (!clipboardData) return
213
- let pasted = clipboardData.getData('text') || ''
214
- codeBudgetaire.value = formaterCodeBudgetaire(pasted)
215
-
216
- setTimeout(() => {
217
- const input = e.target as HTMLInputElement
218
- input.selectionStart = input.selectionEnd = codeBudgetaire.value.length
219
- }, 0)
220
- }
221
-
222
- const sauvegarder = () => {
223
- codeBudgetaire.value = formaterCodeBudgetaire(codeBudgetaire.value)
224
- if (!estValide.value) return
225
- if (codeBudgetaire.value === derniereValeurSauvegardee.value) return
226
-
227
- const existe = props.codeBudgetairesProp.some(
228
- item => item.trim().toUpperCase() === codeBudgetaire.value.trim().toUpperCase(),
229
- )
230
-
231
- if (!existe) {
232
- const nouvelleListe = [...props.codeBudgetairesProp, codeBudgetaire.value]
233
- emit('update:codeBudgetairesProp', nouvelleListe)
234
- }
235
-
236
- derniereValeurSauvegardee.value = codeBudgetaire.value
237
- emit('update:modelValue', codeBudgetaire.value)
238
- }
239
-
240
- const gererChangement = (val: string) => {
241
- codeBudgetaire.value = formaterCodeBudgetaire(val)
242
-
243
- const valeurFormatee = codeBudgetaire.value
244
- const estDansListe = props.codeBudgetairesProp.includes(valeurFormatee)
245
-
246
- if (estDansListe && valeurFormatee !== derniereValeurSauvegardee.value && estValide.value) {
247
- sauvegarder()
248
- }
249
- }
250
-
251
- onMounted(() => {
252
- derniereValeurSauvegardee.value = codeBudgetaire.value
253
- })
254
-
255
- const placeholder = computed(() => {
256
- const base = format.replace(/9/g, '0')
257
- const extension = activerExtension ? '-XXX/XXX' : ''
258
- return base + extension
259
- })
260
- </script>
1
+ <template>
2
+ <div>
3
+ <v-form
4
+ ref="form"
5
+ v-model="formValide"
6
+ @submit.prevent
7
+ >
8
+ <v-combobox
9
+ v-model="codeBudgetaire"
10
+ :items="codeBudgetairesProp"
11
+ :label="label"
12
+ persistent-hint
13
+ variant="outlined"
14
+ hide-details="auto"
15
+ :error="!estValide"
16
+ :rules="[v => (estValide ? true : regleMessageErreur)]"
17
+ :disabled="disable"
18
+ :density="density"
19
+ :hint="afficherHint ? placeholder : ''"
20
+ :max-width="maxWidth || '100%'"
21
+ :min-width="minWidth || '100%'"
22
+ @blur="sauvegarder"
23
+ @keydown.enter="sauvegarder"
24
+ @keydown="caractereAutorises"
25
+ @update:modelValue="gererChangement"
26
+ @paste="gererPaste"
27
+ />
28
+ </v-form>
29
+ </div>
30
+ </template>
31
+
32
+ <script setup lang="ts">
33
+ import { ref, computed, onMounted, nextTick } from 'vue'
34
+ import type { VForm } from 'vuetify/components'
35
+
36
+ const emit = defineEmits(['update:modelValue', 'update:codeBudgetairesProp'])
37
+
38
+ const props = withDefaults(
39
+ defineProps<{
40
+ codeBudgetairesProp: string[]
41
+ modelValue: string | null
42
+ label: string
43
+ disable: boolean
44
+ afficherHint?: boolean
45
+ regleMessageErreur: string
46
+ density?: 'default' | 'comfortable' | 'compact'
47
+ maxWidth?: string | number
48
+ minWidth?: string | number
49
+ format?: string
50
+ activerExtension?: boolean
51
+ }>(),
52
+ {
53
+ afficherHint: false,
54
+ format: '999-9-99999-999',
55
+ activerExtension: false,
56
+ },
57
+ )
58
+
59
+ const formValide = ref(false)
60
+ const form = ref<VForm | null>(null)
61
+ const codeBudgetaire = ref(props.modelValue ?? '')
62
+ const derniereValeurSauvegardee = ref<string | null>(null)
63
+ const format = props.format
64
+ const activerExtension = props.activerExtension
65
+
66
+ const estValide = computed(() => {
67
+ const val = codeBudgetaire.value?.toUpperCase().trim() || ''
68
+ const base = val.slice(0, 15)
69
+ const extension = val.slice(15)
70
+
71
+ if (!/^\d{3}-\d{1}-\d{5}-\d{3}$/.test(base)) return false
72
+
73
+ if (!activerExtension) return val.length === 15
74
+
75
+ if (val.length === 15) return true
76
+ if (val.length !== 22) return false
77
+ if (extension.length !== 7) return false
78
+
79
+ if (extension[3] !== '/') return false
80
+ if (!/^[A-Z0-9/]$/i.test(extension[0]!)) return false
81
+
82
+ const alphanumAt = [1, 2, 4, 5, 6]
83
+ return alphanumAt.every(i => /^[A-Z0-9]$/i.test(extension[i]!))
84
+ })
85
+
86
+ const caractereAutorises = (e: KeyboardEvent) => {
87
+ if (e.ctrlKey || e.metaKey) return
88
+
89
+ const touchesSpecifiques = ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab', 'Home', 'End']
90
+ if (touchesSpecifiques.includes(e.key)) return
91
+
92
+ const input = e.target as HTMLInputElement
93
+ let position = input.selectionStart ?? 0
94
+
95
+ // Gestion de la partie de base (15 premiers caractères)
96
+ if (position < 15) {
97
+ if (!/^\d$/.test(e.key)) {
98
+ e.preventDefault()
99
+ return
100
+ }
101
+
102
+ // Insérer chiffre et auto-ajout des tirets
103
+ e.preventDefault()
104
+
105
+ const value = codeBudgetaire.value.replace(/-/g, '')
106
+ const clean = value.slice(0, 12) + e.key
107
+
108
+ let formatted = ''
109
+ if (clean.length > 0) formatted += clean.slice(0, 3)
110
+ if (clean.length > 3) formatted += '-' + clean.slice(3, 4)
111
+ if (clean.length > 4) formatted += '-' + clean.slice(4, 9)
112
+ if (clean.length > 9) formatted += '-' + clean.slice(9, 12)
113
+
114
+ codeBudgetaire.value = formatted.slice(0, 15)
115
+
116
+ nextTick(() => {
117
+ const newPos = codeBudgetaire.value.length
118
+ input.selectionStart = input.selectionEnd = newPos
119
+ })
120
+
121
+ return
122
+ }
123
+
124
+ // --- Gestion de l'extension ---
125
+ if (!activerExtension || position >= 22 || codeBudgetaire.value.length >= 22) {
126
+ e.preventDefault()
127
+ return
128
+ }
129
+
130
+ const extensionPos = position - 15
131
+
132
+ // Règle 1 : extension[0] = alphanum ou /
133
+ if (extensionPos === 0) {
134
+ if (!/^[A-Z0-9/]$/i.test(e.key)) {
135
+ e.preventDefault()
136
+ return
137
+ }
138
+ return
139
+ }
140
+
141
+ // Règle 2 : extension[1,2,4,5,6] = alphanum
142
+ if ([1, 2, 4, 5, 6].includes(extensionPos)) {
143
+ if (!/^[A-Z0-9]$/i.test(e.key)) {
144
+ e.preventDefault()
145
+ return
146
+ }
147
+ return
148
+ }
149
+
150
+ // Règle 3 : slash automatique à position 3 (index 18)
151
+ if (extensionPos === 3) {
152
+ e.preventDefault()
153
+ const before = codeBudgetaire.value.slice(0, position)
154
+ const after = codeBudgetaire.value.slice(position)
155
+ codeBudgetaire.value = before + '/' + after
156
+ nextTick(() => {
157
+ input.selectionStart = input.selectionEnd = position + 1
158
+ })
159
+ return
160
+ }
161
+
162
+ // Tout autre cas = bloqué
163
+ e.preventDefault()
164
+ }
165
+
166
+ const formaterCodeBudgetaire = (valeur: string): string => {
167
+ if (!valeur) return ''
168
+
169
+ const upper = valeur.toUpperCase().replace(/[^A-Z0-9/]/g, '')
170
+ const chiffres = upper.replace(/[^0-9]/g, '').slice(0, 12)
171
+
172
+ let base = ''
173
+ if (chiffres.length > 0) base += chiffres.slice(0, 3)
174
+ if (chiffres.length > 3) base += '-' + chiffres.slice(3, 4)
175
+ if (chiffres.length > 4) base += '-' + chiffres.slice(4, 9)
176
+ if (chiffres.length > 9) base += '-' + chiffres.slice(9, 12)
177
+
178
+ if (!activerExtension || base.length < 15) return base
179
+
180
+ const reste = upper.slice(chiffres.length).replace(/[^A-Z0-9/]/gi, '')
181
+
182
+ // Extraire les 7 premiers caractères restants pour l’extension
183
+ let ext = reste.slice(0, 7).split('')
184
+
185
+ // Ne garder que le premier slash s’il est à l’index 0 ou 3
186
+ ext = ext.filter((c, i) => {
187
+ if (c !== '/') return true
188
+ return i === 0 || i === 3
189
+ })
190
+
191
+ // Enlever les slash non autorisés
192
+ ext = ext.map((c, i) => {
193
+ if (c === '/' && i !== 0 && i !== 3) return ''
194
+ if (c !== '/' && !/^[A-Z0-9]$/i.test(c)) return ''
195
+ return c
196
+ })
197
+
198
+ // Forcer le slash à la 4e position
199
+ if (ext.length > 3) {
200
+ ext[3] = '/'
201
+ }
202
+
203
+ // Réduire à 7 caractères
204
+ ext = ext.slice(0, 7)
205
+
206
+ return (base + ext.join('')).slice(0, 22)
207
+ }
208
+
209
+ const gererPaste = (e: ClipboardEvent) => {
210
+ e.preventDefault()
211
+ const clipboardData = e.clipboardData
212
+ if (!clipboardData) return
213
+ let pasted = clipboardData.getData('text') || ''
214
+ codeBudgetaire.value = formaterCodeBudgetaire(pasted)
215
+
216
+ setTimeout(() => {
217
+ const input = e.target as HTMLInputElement
218
+ input.selectionStart = input.selectionEnd = codeBudgetaire.value.length
219
+ }, 0)
220
+ }
221
+
222
+ const sauvegarder = () => {
223
+ codeBudgetaire.value = formaterCodeBudgetaire(codeBudgetaire.value)
224
+ if (!estValide.value) return
225
+ if (codeBudgetaire.value === derniereValeurSauvegardee.value) return
226
+
227
+ const existe = props.codeBudgetairesProp.some(
228
+ item => item.trim().toUpperCase() === codeBudgetaire.value.trim().toUpperCase(),
229
+ )
230
+
231
+ if (!existe) {
232
+ const nouvelleListe = [...props.codeBudgetairesProp, codeBudgetaire.value]
233
+ emit('update:codeBudgetairesProp', nouvelleListe)
234
+ }
235
+
236
+ derniereValeurSauvegardee.value = codeBudgetaire.value
237
+ emit('update:modelValue', codeBudgetaire.value)
238
+ }
239
+
240
+ const gererChangement = (val: string) => {
241
+ codeBudgetaire.value = formaterCodeBudgetaire(val)
242
+
243
+ const valeurFormatee = codeBudgetaire.value
244
+ const estDansListe = props.codeBudgetairesProp.includes(valeurFormatee)
245
+
246
+ if (estDansListe && valeurFormatee !== derniereValeurSauvegardee.value && estValide.value) {
247
+ sauvegarder()
248
+ }
249
+ }
250
+
251
+ onMounted(() => {
252
+ derniereValeurSauvegardee.value = codeBudgetaire.value
253
+ })
254
+
255
+ const placeholder = computed(() => {
256
+ const base = format.replace(/9/g, '0')
257
+ const extension = activerExtension ? '-XXX/XXX' : ''
258
+ return base + extension
259
+ })
260
+ </script>
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <v-date-input
3
3
  v-model="dateValeur"
4
- @update:model-value="formatDate"
5
4
  v-bind="$attrs"
5
+ @update:model-value="formatDate"
6
6
  variant="outlined"
7
7
  prepend-icon=""
8
8
  prepend-inner-icon="$calendar"
@@ -1,117 +1,118 @@
1
- <template>
2
- <v-dialog
3
- v-model="dialog"
4
- class="pa-0 ma-0"
5
- :width="largeur"
6
- :fullscreen="display.xs.value"
7
- max-width="650"
8
- :persistent="props.persistant"
9
- @keydown.esc="!persistant ? annuler : ''"
10
- @click:outside="!persistant ? annuler : ''"
11
- >
12
- <v-card class="pa-0 ma-0 pl-8 pt-8">
13
- <!-- Bouton en haut à droite -->
14
- <v-btn
15
- icon="mdi-close"
16
- variant="text"
17
- class="position-absolute couleurHover"
18
- style="top: 5px; right: 5px"
19
- @click="annuler"
20
- ></v-btn>
21
-
22
- <v-card-title
23
- class="pa-0 ma-0 pb-6"
24
- style="font-size: 24px; white-space: normal; word-break: break-word"
25
- >
26
- <slot name="titre"></slot>
27
- <div text-h5><span v-html="titre"></span></div>
28
- </v-card-title>
29
-
30
- <v-card-text class="pa-0 ma-0 pb-6 pr-6">
31
- <v-container>
32
- <slot></slot>
33
- <slot name="content"></slot>
34
- </v-container>
35
- </v-card-text>
36
- <v-card-actions class="my-2 d-flex justify-end pr-6 pb-5">
37
- <slot name="actions"></slot>
38
- <v-btn
39
- v-if="btnAnnuler"
40
- color="primary"
41
- :loading="operationEnCours"
42
- variant="text"
43
- @click="annuler"
44
- >
45
- {{ btnAnnulerTexte ? btnAnnulerTexte : $t('csqc.bouton.annuler') }}
46
- </v-btn>
47
-
48
- <v-btn
49
- v-if="btnOk"
50
- class="Gouttiere"
51
- color="primary"
52
- :loading="operationEnCours"
53
- :disabled="btnOkDesactiver"
54
- variant="flat"
55
- @click="okBouton"
56
- >
57
- {{ btnOkTexte ? btnOkTexte : $t('csqc.bouton.ok') }}
58
- </v-btn>
59
- </v-card-actions>
60
- </v-card>
61
- </v-dialog>
62
- </template>
63
-
64
- <script setup lang="ts">
65
- import { ref } from 'vue'
66
- import { useDisplay } from 'vuetify'
67
-
68
- const display = useDisplay()
69
-
70
- // Déclaration des props
71
- const props = defineProps({
72
- largeur: { type: String, default: '50vw' },
73
- persistant: { type: Boolean, default: true },
74
- operationEnCours: { type: Boolean, default: false },
75
- btnAnnuler: { type: Boolean, default: true },
76
- btnOk: { type: Boolean, default: true },
77
- btnAnnulerTexte: { type: String, default: '' },
78
- btnOkTexte: { type: String, default: '' },
79
- titre: { type: String, default: '' },
80
- btnOkDesactiver: { type: Boolean, default: false },
81
- })
82
-
83
- // Déclaration des événements émis
84
- const emit = defineEmits(['annuler', 'ok'])
85
-
86
- // Gestion de l'état du dialogue
87
- const dialog = ref(false)
88
-
89
- // Méthodes pour gérer l'ouverture et la fermeture
90
- const ouvrir = () => {
91
- dialog.value = true
92
- }
93
-
94
- const fermer = () => {
95
- dialog.value = false
96
- }
97
-
98
- // Gestion des actions des boutons
99
- const annuler = () => {
100
- emit('annuler')
101
- fermer()
102
- }
103
-
104
- const okBouton = () => {
105
- emit('ok')
106
- }
107
-
108
- // permet d'exporter les 2 actions
109
- defineExpose({ ouvrir, fermer })
110
- </script>
111
-
112
- <style lang="css" scoped>
113
- .v-card__text,
114
- .v-card__title {
115
- word-break: normal; /* empeche le wrap de couper un mot en XS */
116
- }
117
- </style>
1
+ <template>
2
+ <v-dialog
3
+ v-model="dialog"
4
+ v-bind="$attrs"
5
+ class="pa-0 ma-0"
6
+ :width="largeur"
7
+ :fullscreen="display.xs.value"
8
+ max-width="650"
9
+ :persistent="props.persistant"
10
+ @keydown.esc="!persistant ? annuler : ''"
11
+ @click:outside="!persistant ? annuler : ''"
12
+ >
13
+ <v-card class="pa-0 ma-0 pl-8 pt-8">
14
+ <!-- Bouton en haut à droite -->
15
+ <v-btn
16
+ icon="mdi-close"
17
+ variant="text"
18
+ class="position-absolute couleurHover"
19
+ style="top: 5px; right: 5px"
20
+ @click="annuler"
21
+ ></v-btn>
22
+
23
+ <v-card-title
24
+ class="pa-0 ma-0 pb-6"
25
+ style="font-size: 24px; white-space: normal; word-break: break-word"
26
+ >
27
+ <slot name="titre"></slot>
28
+ <div text-h5><span v-html="titre"></span></div>
29
+ </v-card-title>
30
+
31
+ <v-card-text class="pa-0 ma-0 pb-6 pr-6">
32
+ <v-container>
33
+ <slot></slot>
34
+ <slot name="content"></slot>
35
+ </v-container>
36
+ </v-card-text>
37
+ <v-card-actions class="my-2 d-flex justify-end pr-6 pb-5">
38
+ <slot name="actions"></slot>
39
+ <v-btn
40
+ v-if="btnAnnuler"
41
+ color="primary"
42
+ :loading="operationEnCours"
43
+ variant="text"
44
+ @click="annuler"
45
+ >
46
+ {{ btnAnnulerTexte ? btnAnnulerTexte : $t('csqc.bouton.annuler') }}
47
+ </v-btn>
48
+
49
+ <v-btn
50
+ v-if="btnOk"
51
+ class="Gouttiere"
52
+ color="primary"
53
+ :loading="operationEnCours"
54
+ :disabled="btnOkDesactiver"
55
+ variant="flat"
56
+ @click="okBouton"
57
+ >
58
+ {{ btnOkTexte ? btnOkTexte : $t('csqc.bouton.ok') }}
59
+ </v-btn>
60
+ </v-card-actions>
61
+ </v-card>
62
+ </v-dialog>
63
+ </template>
64
+
65
+ <script setup lang="ts">
66
+ import { ref } from 'vue'
67
+ import { useDisplay } from 'vuetify'
68
+
69
+ const display = useDisplay()
70
+
71
+ // Déclaration des props
72
+ const props = defineProps({
73
+ largeur: { type: String, default: '50vw' },
74
+ persistant: { type: Boolean, default: true },
75
+ operationEnCours: { type: Boolean, default: false },
76
+ btnAnnuler: { type: Boolean, default: true },
77
+ btnOk: { type: Boolean, default: true },
78
+ btnAnnulerTexte: { type: String, default: '' },
79
+ btnOkTexte: { type: String, default: '' },
80
+ titre: { type: String, default: '' },
81
+ btnOkDesactiver: { type: Boolean, default: false },
82
+ })
83
+
84
+ // Déclaration des événements émis
85
+ const emit = defineEmits(['annuler', 'ok'])
86
+
87
+ // Gestion de l'état du dialogue
88
+ const dialog = ref(false)
89
+
90
+ // Méthodes pour gérer l'ouverture et la fermeture
91
+ const ouvrir = () => {
92
+ dialog.value = true
93
+ }
94
+
95
+ const fermer = () => {
96
+ dialog.value = false
97
+ }
98
+
99
+ // Gestion des actions des boutons
100
+ const annuler = () => {
101
+ emit('annuler')
102
+ fermer()
103
+ }
104
+
105
+ const okBouton = () => {
106
+ emit('ok')
107
+ }
108
+
109
+ // permet d'exporter les 2 actions
110
+ defineExpose({ ouvrir, fermer })
111
+ </script>
112
+
113
+ <style lang="css" scoped>
114
+ .v-card__text,
115
+ .v-card__title {
116
+ word-break: normal; /* empeche le wrap de couper un mot en XS */
117
+ }
118
+ </style>
package/index.ts CHANGED
@@ -1,65 +1,66 @@
1
- import csqcAlerteErreur from './composants/csqcAlerteErreur.vue'
2
- import csqcDialogue from './composants/csqcDialogue.vue'
3
- import csqcOptionSwitch from './composants/csqcOptionSwitch.vue'
4
- import csqcRecherche from './composants/csqcRecherche.vue'
5
- import csqcSnackbar from './composants/csqcSnackbar.vue'
6
- import csqcTiroir from './composants/csqcTiroir.vue'
7
- import pivEntete from './composants/gabarit/pivEntete.vue'
8
- import pivFooter from './composants/gabarit/pivPiedPage.vue'
9
- import csqcMenu from './composants/gabarit/csqcMenu.vue'
10
- import csqcConfirmation from './composants/csqcConfirmation.vue'
11
- import csqcTable from './composants/csqcTable/csqcTable.vue'
12
- import csqcCodeBudgetaire from './composants/codeBudgetaireGenerique.vue'
13
- import csqcChaise from './composants/csqcChaise/chaiseConteneur.vue'
14
- import csqcAide from './composants/csqcAide.vue'
15
- import csqcEntete from './composants/csqcEntete.vue'
16
- import csqcTexteBilingue from './composants/csqcTexteBilingue.vue'
17
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
- import csqcEditeurTexteRiche from './composants/csqcEditeurTexteRiche.vue'
19
- import csqcImportCSV from './composants/csqcImportCSV.vue'
20
- import csqcRechercheUtilisateur from './composants/csqcRechercheUtilisateur.vue'
21
- import validateurs from './composants/validateurs'
22
-
23
- // modèles
24
- import NotificationGabaritDefaut from './modeles/notificationGabaritDefaut'
25
- import modeleSnackbar from './modeles/composants/snackbar'
26
- import modeleDatatableColonne from './modeles/composants/datatableColonne'
27
- import apiReponse from './modeles/apiReponse'
28
- import data from './modeles/data'
29
- import response from './modeles/response'
30
-
31
- // i18n
32
- import csqcEn from './locales/en.json'
33
- import csqcFr from './locales/fr.json'
34
-
35
- export {
36
- csqcFr,
37
- csqcEn,
38
- csqcAlerteErreur,
39
- csqcDialogue,
40
- csqcConfirmation,
41
- csqcOptionSwitch,
42
- csqcRecherche,
43
- csqcSnackbar,
44
- csqcTable,
45
- csqcTiroir,
46
- csqcMenu,
47
- csqcCodeBudgetaire,
48
- csqcChaise,
49
- pivFooter,
50
- pivEntete,
51
- csqcAide,
52
- csqcEntete,
53
- csqcTexteBilingue,
54
- csqcEditeurTexteRiche,
55
- validateurs,
56
- csqcImportCSV,
57
- csqcRechercheUtilisateur,
58
-
59
- modeleSnackbar,
60
- modeleDatatableColonne,
61
- apiReponse,
62
- data,
63
- response,
64
- NotificationGabaritDefaut,
65
- }
1
+ import csqcAlerteErreur from './composants/csqcAlerteErreur.vue'
2
+ import csqcDialogue from './composants/csqcDialogue.vue'
3
+ import csqcOptionSwitch from './composants/csqcOptionSwitch.vue'
4
+ import csqcRecherche from './composants/csqcRecherche.vue'
5
+ import csqcSnackbar from './composants/csqcSnackbar.vue'
6
+ import csqcTiroir from './composants/csqcTiroir.vue'
7
+ import pivEntete from './composants/gabarit/pivEntete.vue'
8
+ import pivFooter from './composants/gabarit/pivPiedPage.vue'
9
+ import csqcMenu from './composants/gabarit/csqcMenu.vue'
10
+ import csqcConfirmation from './composants/csqcConfirmation.vue'
11
+ import csqcDate from './composants/csqcDate/csqcDate.vue'
12
+ import csqcTable from './composants/csqcTable/csqcTable.vue'
13
+ import csqcCodeBudgetaire from './composants/codeBudgetaireGenerique.vue'
14
+ import csqcChaise from './composants/csqcChaise/chaiseConteneur.vue'
15
+ import csqcAide from './composants/csqcAide.vue'
16
+ import csqcEntete from './composants/csqcEntete.vue'
17
+ import csqcTexteBilingue from './composants/csqcTexteBilingue.vue'
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ import csqcEditeurTexteRiche from './composants/csqcEditeurTexteRiche.vue'
20
+ import csqcImportCSV from './composants/csqcImportCSV.vue'
21
+ import csqcRechercheUtilisateur from './composants/csqcRechercheUtilisateur.vue'
22
+ import validateurs from './composants/validateurs'
23
+
24
+ // modèles
25
+ import NotificationGabaritDefaut from './modeles/notificationGabaritDefaut'
26
+ import modeleSnackbar from './modeles/composants/snackbar'
27
+ import modeleDatatableColonne from './modeles/composants/datatableColonne'
28
+ import apiReponse from './modeles/apiReponse'
29
+ import data from './modeles/data'
30
+ import response from './modeles/response'
31
+
32
+ // i18n
33
+ import csqcEn from './locales/en.json'
34
+ import csqcFr from './locales/fr.json'
35
+
36
+ export {
37
+ csqcFr,
38
+ csqcEn,
39
+ csqcAlerteErreur,
40
+ csqcDialogue,
41
+ csqcConfirmation,
42
+ csqcDate,
43
+ csqcOptionSwitch,
44
+ csqcRecherche,
45
+ csqcSnackbar,
46
+ csqcTable,
47
+ csqcTiroir,
48
+ csqcMenu,
49
+ csqcCodeBudgetaire,
50
+ csqcChaise,
51
+ pivFooter,
52
+ pivEntete,
53
+ csqcAide,
54
+ csqcEntete,
55
+ csqcTexteBilingue,
56
+ csqcEditeurTexteRiche,
57
+ validateurs,
58
+ csqcImportCSV,
59
+ csqcRechercheUtilisateur,
60
+ modeleSnackbar,
61
+ modeleDatatableColonne,
62
+ apiReponse,
63
+ data,
64
+ response,
65
+ NotificationGabaritDefaut,
66
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codevdesign",
3
- "version": "0.0.89",
3
+ "version": "0.0.91",
4
4
  "description": "Composants Vuetify 3 pour les projets Codev",
5
5
  "files": [
6
6
  "./**/*.vue",
@@ -13,7 +13,7 @@
13
13
  "build": "vite build"
14
14
  },
15
15
  "dependencies": {
16
- "vuetify": "^3.9.0",
16
+ "vuetify": "^3.10.2",
17
17
  "vue-i18n": "^11.0.0",
18
18
  "@e965/xlsx": "^0.20.3",
19
19
  "tinymce": "^8.0.2",