@cnamts/synapse 0.0.11-alpha → 0.0.12-alpha
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.
- package/dist/design-system-v3.js +3878 -3189
- package/dist/design-system-v3.umd.cjs +1 -1
- package/dist/src/components/Amelipro/types/languages.d.ts +6 -0
- package/dist/src/components/Amelipro/types/types.d.ts +65 -0
- package/dist/src/components/CookieBanner/CookieBanner.d.ts +1 -1
- package/dist/src/components/Customs/SyInputSelect/SyInputSelect.d.ts +2 -0
- package/dist/src/components/Customs/SyTextField/SyTextField.d.ts +29 -23
- package/dist/src/components/Customs/SyTextField/types.d.ts +1 -0
- package/dist/src/components/DatePicker/DatePicker.d.ts +70 -59
- package/dist/src/components/DatePicker/DateTextInput.d.ts +67 -56
- package/dist/src/components/ErrorPage/ErrorPage.d.ts +1 -1
- package/dist/src/components/FileList/FileList.d.ts +1 -0
- package/dist/src/components/FileList/UploadItem/UploadItem.d.ts +1 -1
- package/dist/src/components/FilterSideBar/FilterSideBar.d.ts +31 -0
- package/dist/src/components/FilterSideBar/locales.d.ts +7 -0
- package/dist/src/components/FilterSideBar/tests/FilterSideBar.spec.d.ts +1 -0
- package/dist/src/components/LangBtn/LangBtn.d.ts +2 -2
- package/dist/src/components/NirField/NirField.d.ts +940 -0
- package/dist/src/components/NotificationBar/NotificationBar.d.ts +1 -1
- package/dist/src/components/PasswordField/PasswordField.d.ts +40 -8
- package/dist/src/components/PeriodField/PeriodField.d.ts +142 -120
- package/dist/src/components/PhoneField/PhoneField.d.ts +11 -2
- package/dist/src/components/RatingPicker/EmotionPicker/EmotionPicker.d.ts +1 -1
- package/dist/src/components/RatingPicker/NumberPicker/NumberPicker.d.ts +1 -1
- package/dist/src/components/RatingPicker/StarsPicker/StarsPicker.d.ts +1 -1
- package/dist/src/components/UploadWorkflow/config.d.ts +29 -0
- package/dist/src/components/UploadWorkflow/locales.d.ts +7 -0
- package/dist/src/components/UploadWorkflow/tests/UploadWorkflow.spec.d.ts +1 -0
- package/dist/src/components/UploadWorkflow/types.d.ts +19 -0
- package/dist/src/components/UploadWorkflow/useFileList.d.ts +10 -0
- package/dist/src/components/UploadWorkflow/useFileUploadJourney.d.ts +9 -0
- package/dist/src/components/index.d.ts +2 -0
- package/dist/src/composables/rules/useFieldValidation.d.ts +1 -0
- package/dist/src/composables/validation/tests/useValidation.spec.d.ts +1 -0
- package/dist/src/composables/validation/useValidation.d.ts +39 -0
- package/dist/src/designTokens/index.d.ts +3 -1
- package/dist/src/vuetifyConfig.d.ts +81 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/assets/_elevations.scss +89 -0
- package/src/assets/_fonts.scss +6 -0
- package/src/assets/_radius.scss +86 -0
- package/src/assets/_spacers.scss +149 -0
- package/src/assets/settings.scss +7 -3
- package/src/assets/tokens.scss +32 -29
- package/src/components/Amelipro/types/languages.d.ts +6 -0
- package/src/components/Amelipro/types/types.d.ts +65 -0
- package/src/components/Customs/SyInputSelect/SyInputSelect.stories.ts +65 -0
- package/src/components/Customs/SyInputSelect/SyInputSelect.vue +13 -3
- package/src/components/Customs/SySelect/SySelect.stories.ts +88 -5
- package/src/components/Customs/SySelect/SySelect.vue +36 -10
- package/src/components/Customs/SySelect/tests/SySelect.spec.ts +135 -2
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +576 -85
- package/src/components/Customs/SyTextField/SyTextField.vue +132 -104
- package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +190 -38
- package/src/components/Customs/SyTextField/types.d.ts +1 -0
- package/src/components/DatePicker/DatePicker.vue +405 -137
- package/src/components/DatePicker/DateTextInput.vue +15 -0
- package/src/components/DatePicker/tests/DatePicker.spec.ts +8 -15
- package/src/components/FileList/FileList.vue +2 -1
- package/src/components/FileList/UploadItem/UploadItem.vue +10 -0
- package/src/components/FileUpload/FileUpload.stories.ts +84 -0
- package/src/components/FileUpload/FileUpload.vue +1 -0
- package/src/components/FileUpload/tests/FileUpload.spec.ts +4 -4
- package/src/components/FilterInline/FilterInline.mdx +180 -34
- package/src/components/FilterInline/FilterInline.stories.ts +363 -6
- package/src/components/FilterSideBar/FilterSideBar.mdx +237 -0
- package/src/components/FilterSideBar/FilterSideBar.stories.ts +798 -0
- package/src/components/FilterSideBar/FilterSideBar.vue +193 -0
- package/src/components/FilterSideBar/locales.ts +8 -0
- package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +305 -0
- package/src/components/FilterSideBar/tests/__snapshots__/FilterSideBar.spec.ts.snap +39 -0
- package/src/components/HeaderBar/Usages.mdx +1 -1
- package/src/components/NirField/NirField.stories.ts +573 -29
- package/src/components/NirField/NirField.vue +397 -359
- package/src/components/NirField/tests/NirField.spec.ts +88 -52
- package/src/components/NirField/tests//342/200/257dataset/342/200/257.md +12 -0
- package/src/components/NotificationBar/Accessibilite.stories.ts +4 -0
- package/src/components/NotificationBar/NotificationBar.stories.ts +18 -13
- package/src/components/PasswordField/PasswordField.mdx +129 -47
- package/src/components/PasswordField/PasswordField.stories.ts +924 -120
- package/src/components/PasswordField/PasswordField.vue +209 -99
- package/src/components/PasswordField/tests/PasswordField.spec.ts +138 -9
- package/src/components/PeriodField/PeriodField.vue +55 -54
- package/src/components/PhoneField/PhoneField.stories.ts +69 -0
- package/src/components/PhoneField/PhoneField.vue +3 -0
- package/src/components/PhoneField/indicatifs.ts +1 -1
- package/src/components/UploadWorkflow/UploadWorkflow.mdx +75 -0
- package/src/components/UploadWorkflow/UploadWorkflow.stories.ts +943 -0
- package/src/components/UploadWorkflow/UploadWorkflow.vue +230 -0
- package/src/components/UploadWorkflow/config.ts +29 -0
- package/src/components/UploadWorkflow/locales.ts +8 -0
- package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +257 -0
- package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +54 -0
- package/src/components/UploadWorkflow/types.ts +21 -0
- package/src/components/UploadWorkflow/useFileList.ts +84 -0
- package/src/components/UploadWorkflow/useFileUploadJourney.ts +18 -0
- package/src/components/index.ts +2 -0
- package/src/composables/rules/useFieldValidation.ts +5 -2
- package/src/composables/validation/tests/useValidation.spec.ts +154 -0
- package/src/composables/validation/useValidation.ts +165 -0
- package/src/designTokens/index.ts +4 -0
- package/src/stories/Demarrer/Accueil.mdx +1 -1
- package/src/stories/DesignTokens/ThemePA.mdx +4 -30
- package/src/stories/GuideDuDev/UtiliserLesRules.mdx +319 -76
- package/src/stories/GuideDuDev/moduleDeNotification.mdx +1 -1
- package/src/vuetifyConfig.ts +61 -0
- package/src/composables/useFilterable/__snapshots__/useFilterable.spec.ts.snap +0 -3
|
@@ -2,12 +2,20 @@ import { mount } from '@vue/test-utils'
|
|
|
2
2
|
import NirField from '../NirField.vue'
|
|
3
3
|
import { describe, it, expect, beforeEach } from 'vitest'
|
|
4
4
|
import { createVuetify } from 'vuetify'
|
|
5
|
+
import * as components from 'vuetify/components'
|
|
6
|
+
import * as directives from 'vuetify/directives'
|
|
7
|
+
import { useValidation } from '@/composables/validation/useValidation'
|
|
5
8
|
|
|
6
|
-
const vuetify = createVuetify(
|
|
9
|
+
const vuetify = createVuetify({
|
|
10
|
+
components,
|
|
11
|
+
directives,
|
|
12
|
+
})
|
|
7
13
|
|
|
8
14
|
describe('NirField.vue', () => {
|
|
9
|
-
|
|
10
|
-
|
|
15
|
+
let wrapper: ReturnType<typeof mount<typeof NirField & {
|
|
16
|
+
numberValidation: ReturnType<typeof useValidation>
|
|
17
|
+
keyValidation: ReturnType<typeof useValidation>
|
|
18
|
+
}>>
|
|
11
19
|
|
|
12
20
|
beforeEach(() => {
|
|
13
21
|
wrapper = mount(NirField, {
|
|
@@ -15,106 +23,134 @@ describe('NirField.vue', () => {
|
|
|
15
23
|
plugins: [vuetify],
|
|
16
24
|
},
|
|
17
25
|
props: {
|
|
18
|
-
modelValue:
|
|
26
|
+
modelValue: undefined,
|
|
19
27
|
required: true,
|
|
20
28
|
showSuccessMessages: true,
|
|
29
|
+
outlined: true,
|
|
21
30
|
},
|
|
22
31
|
})
|
|
23
32
|
})
|
|
24
33
|
|
|
25
34
|
it('renders correctly', () => {
|
|
26
35
|
expect(wrapper.exists()).toBe(true)
|
|
27
|
-
expect(wrapper.find('.
|
|
28
|
-
expect(wrapper.find('.
|
|
36
|
+
expect(wrapper.find('.number-field').exists()).toBe(true)
|
|
37
|
+
expect(wrapper.find('.key-field').exists()).toBe(true)
|
|
29
38
|
})
|
|
30
39
|
|
|
31
40
|
it('displays error message for invalid NIR length', async () => {
|
|
32
|
-
|
|
33
|
-
await
|
|
34
|
-
await
|
|
35
|
-
expect(wrapper.
|
|
41
|
+
await wrapper.find('.number-field input').setValue('123')
|
|
42
|
+
await wrapper.find('.number-field input').trigger('blur')
|
|
43
|
+
await wrapper.vm.$nextTick()
|
|
44
|
+
expect(wrapper.vm.numberValidation.errors.value[0]).toBe('Le numéro de sécurité sociale est invalide.')
|
|
36
45
|
})
|
|
37
46
|
|
|
38
47
|
it('validates the NIR field successfully', async () => {
|
|
39
|
-
|
|
40
|
-
await
|
|
41
|
-
|
|
48
|
+
await wrapper.find('.number-field input').setValue('2940375120005')
|
|
49
|
+
await wrapper.find('.number-field input').trigger('blur')
|
|
50
|
+
await wrapper.vm.$nextTick()
|
|
51
|
+
expect(wrapper.vm.numberValidation.successes.value).toContain('Le numéro de sécurité sociale est valide.')
|
|
42
52
|
})
|
|
43
53
|
|
|
44
54
|
it('displays error message for invalid key length', async () => {
|
|
45
|
-
|
|
46
|
-
await
|
|
47
|
-
|
|
48
|
-
await
|
|
49
|
-
|
|
50
|
-
expect(wrapper.find('.v-messages__message').text()).toContain('La clé du numéro de sécurité sociale doit contenir 2 caractères.')
|
|
55
|
+
await wrapper.find('.number-field input').setValue('2940375120005')
|
|
56
|
+
await wrapper.find('.key-field input').setValue('1')
|
|
57
|
+
await wrapper.find('.key-field input').trigger('blur')
|
|
58
|
+
await wrapper.vm.$nextTick()
|
|
59
|
+
expect(wrapper.vm.keyValidation.errors.value[0]).toBe('La clé du numéro de sécurité sociale est invalide.')
|
|
51
60
|
})
|
|
52
61
|
|
|
53
62
|
it('validates the key field successfully', async () => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
await
|
|
57
|
-
await
|
|
58
|
-
expect(wrapper.
|
|
63
|
+
await wrapper.find('.number-field input').setValue('2940375120005')
|
|
64
|
+
await wrapper.find('.key-field input').setValue('91')
|
|
65
|
+
await wrapper.find('.key-field input').trigger('blur')
|
|
66
|
+
await wrapper.vm.$nextTick()
|
|
67
|
+
expect(wrapper.vm.keyValidation.successes.value).toContain('Le champ Clé est valide.')
|
|
59
68
|
})
|
|
60
69
|
|
|
61
70
|
it('hides the key field when displayKey is false', async () => {
|
|
62
71
|
await wrapper.setProps({ displayKey: false })
|
|
63
|
-
expect(wrapper.find('.
|
|
72
|
+
expect(wrapper.find('.key-field').exists()).toBe(false)
|
|
64
73
|
})
|
|
65
74
|
|
|
66
75
|
it('calls validateOnSubmit and returns true if no errors', async () => {
|
|
67
|
-
|
|
68
|
-
|
|
76
|
+
wrapper = mount(NirField, {
|
|
77
|
+
global: {
|
|
78
|
+
plugins: [vuetify],
|
|
79
|
+
},
|
|
80
|
+
props: {
|
|
81
|
+
modelValue: undefined,
|
|
82
|
+
required: false,
|
|
83
|
+
outlined: true,
|
|
84
|
+
},
|
|
85
|
+
})
|
|
69
86
|
|
|
87
|
+
const numberField = wrapper.find('.number-field input')
|
|
70
88
|
await numberField.setValue('2940375120005')
|
|
71
|
-
await
|
|
89
|
+
await numberField.trigger('blur')
|
|
72
90
|
|
|
73
91
|
await wrapper.vm.$nextTick()
|
|
74
|
-
|
|
75
|
-
wrapper.vm.validateFields()
|
|
76
|
-
|
|
77
|
-
const isValid = wrapper.vm.validateOnSubmit()
|
|
92
|
+
const isValid = await wrapper.vm.validateOnSubmit()
|
|
78
93
|
|
|
79
94
|
expect(isValid).toBe(true)
|
|
80
|
-
expect(wrapper.vm.errors.length).toBe(0)
|
|
81
95
|
})
|
|
96
|
+
|
|
82
97
|
it('applies custom key rules when provided', async () => {
|
|
83
|
-
const customKeyRules = [
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
successMessage: 'Custom key validation passed.',
|
|
91
|
-
},
|
|
98
|
+
const customKeyRules = [{
|
|
99
|
+
type: 'custom',
|
|
100
|
+
options: {
|
|
101
|
+
validate: (value: string) => value === '91',
|
|
102
|
+
message: 'Custom key validation failed.',
|
|
103
|
+
successMessage: 'Custom key validation passed.',
|
|
104
|
+
fieldIdentifier: 'clé',
|
|
92
105
|
},
|
|
93
|
-
]
|
|
106
|
+
}]
|
|
94
107
|
|
|
95
108
|
wrapper = mount(NirField, {
|
|
96
109
|
global: {
|
|
97
110
|
plugins: [vuetify],
|
|
98
111
|
},
|
|
99
112
|
props: {
|
|
100
|
-
modelValue:
|
|
101
|
-
required: true,
|
|
113
|
+
modelValue: undefined,
|
|
102
114
|
customKeyRules,
|
|
115
|
+
showSuccessMessages: true,
|
|
116
|
+
outlined: true,
|
|
103
117
|
},
|
|
104
118
|
})
|
|
105
|
-
|
|
106
|
-
const
|
|
119
|
+
|
|
120
|
+
const numberField = wrapper.find('.number-field input')
|
|
121
|
+
const keyField = wrapper.find('.key-field input')
|
|
107
122
|
await numberField.setValue('2940375120005')
|
|
108
123
|
await keyField.setValue('91')
|
|
109
|
-
|
|
124
|
+
await keyField.trigger('blur')
|
|
110
125
|
await wrapper.vm.$nextTick()
|
|
126
|
+
expect(wrapper.vm.keyValidation.successes.value).toContain('Custom key validation passed.')
|
|
127
|
+
})
|
|
111
128
|
|
|
112
|
-
|
|
113
|
-
|
|
129
|
+
it('emits update:modelValue with correct format', async () => {
|
|
130
|
+
const numberField = wrapper.find('.number-field input')
|
|
131
|
+
const keyField = wrapper.find('.key-field input')
|
|
132
|
+
await numberField.setValue('2940375120005')
|
|
133
|
+
await wrapper.vm.$nextTick()
|
|
134
|
+
await keyField.setValue('91')
|
|
135
|
+
await wrapper.vm.$nextTick()
|
|
136
|
+
expect(wrapper.emitted('update:modelValue')?.slice(-1)[0]).toEqual(['294037512000591'])
|
|
137
|
+
})
|
|
114
138
|
|
|
115
|
-
|
|
139
|
+
it('emits undefined when both fields are empty', async () => {
|
|
140
|
+
const numberField = wrapper.find('.number-field input')
|
|
141
|
+
const keyField = wrapper.find('.key-field input')
|
|
142
|
+
await numberField.setValue('')
|
|
143
|
+
await keyField.setValue('')
|
|
116
144
|
await wrapper.vm.$nextTick()
|
|
145
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([undefined])
|
|
146
|
+
})
|
|
117
147
|
|
|
118
|
-
|
|
148
|
+
it('splits modelValue correctly when provided', async () => {
|
|
149
|
+
await wrapper.setProps({ modelValue: '294037512000591' })
|
|
150
|
+
await wrapper.vm.$nextTick()
|
|
151
|
+
const numberInput = wrapper.find('.number-field input').element as HTMLInputElement
|
|
152
|
+
const keyInput = wrapper.find('.key-field input').element as HTMLInputElement
|
|
153
|
+
expect(numberInput.value.replace(/\s/g, '')).toBe('2940375120005')
|
|
154
|
+
expect(keyInput.value).toBe('91')
|
|
119
155
|
})
|
|
120
156
|
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
| # | Input | Expected Result | Description |
|
|
2
|
+
|----|-------------------|-----------------|-----------------------------------------------------------------------------------------------|
|
|
3
|
+
| 1 | 1840275123456 74 | valid | NIR complet avec clé correcte (ex. homme né en 1984, département 75...). |
|
|
4
|
+
| 2 | 2910256012345 46 | valid | NIR complet avec clé correcte (ex. femme née en 1991, département 25...). |
|
|
5
|
+
| 3 | 198012312345690 | valid | NIR complet (ex. homme né en 1980, département 12...), clé calculée et valide. |
|
|
6
|
+
| 4 | 2551299123457 80 | valid | NIR complet (ex. femme née en 1951, département 29...). |
|
|
7
|
+
| 5 | 2100121101003 73 | valid | NIR complet (ex. femme née en 2000, département 21...). |
|
|
8
|
+
| 6 | 3840275123456 74 | invalid | Le premier chiffre (3) n'est pas valide (doit être 1 ou 2). |
|
|
9
|
+
| 7 | 1841375123456 74 | invalid | Le mois 13 est invalide (doit être compris entre 01 et 12). |
|
|
10
|
+
| 8 | 1840275123456 73 | invalid | Clé de contrôle incorrecte (73 au lieu de 74). |
|
|
11
|
+
| 9 | 1840A75123456 74 | invalid | Contient une lettre 'A' dans la chaîne, format strictement numérique attendu. |
|
|
12
|
+
| 10 | 1840275123456 | invalid | Chaîne trop courte (13 chiffres sans clé). Le NIR doit comporter 15 chiffres. |
|
|
@@ -159,6 +159,10 @@ export const Legende: StoryObj = {
|
|
|
159
159
|
</div>
|
|
160
160
|
</div>
|
|
161
161
|
</div>
|
|
162
|
+
<div class="mt-4">
|
|
163
|
+
<p>Rapport d’audit manuel : <a href="/audits/NotificationBar.xlsx" style="color:#0C41BD;">Voir le rapport</a></p>
|
|
164
|
+
<p style="color: grey; font-size: 14px">Correctifs en cours (<a href="https://github.com/assurance-maladie-digital/design-system/issues/3967" target="_blank" style="color:#0C41BD;">issue #3967</a>)</p>
|
|
165
|
+
</div>
|
|
162
166
|
`,
|
|
163
167
|
}
|
|
164
168
|
},
|
|
@@ -115,7 +115,7 @@ Default.args = {
|
|
|
115
115
|
closeBtnText: 'Fermer',
|
|
116
116
|
type: 'info',
|
|
117
117
|
bottom: false,
|
|
118
|
-
rounded: '
|
|
118
|
+
rounded: '4',
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
Default.parameters = {
|
|
@@ -128,7 +128,6 @@ Default.parameters = {
|
|
|
128
128
|
v-model="showNotification"
|
|
129
129
|
:close-btn-text="closeBtnText"
|
|
130
130
|
:bottom="bottom"
|
|
131
|
-
:rounded="rounded"
|
|
132
131
|
:type="type"
|
|
133
132
|
>
|
|
134
133
|
<template #default>This is a {{ type }} notification</template>
|
|
@@ -150,7 +149,7 @@ Default.parameters = {
|
|
|
150
149
|
import { VBtn } from 'vuetify/components'
|
|
151
150
|
import { NotificationBar } from '@cnamts/synapse'
|
|
152
151
|
import { ref } from 'vue'
|
|
153
|
-
import { useNotificationService } from '
|
|
152
|
+
import { useNotificationService } from '@cnamts/synpase'
|
|
154
153
|
|
|
155
154
|
const { addNotification } = useNotificationService()
|
|
156
155
|
const showNotification = ref(false)
|
|
@@ -174,6 +173,7 @@ Default.parameters = {
|
|
|
174
173
|
export const Success: Story = Default.bind({})
|
|
175
174
|
Success.args = {
|
|
176
175
|
...Default.args,
|
|
176
|
+
rounded: 'pill',
|
|
177
177
|
type: 'success',
|
|
178
178
|
}
|
|
179
179
|
Success.parameters = {
|
|
@@ -186,7 +186,7 @@ Success.parameters = {
|
|
|
186
186
|
v-model="showNotification"
|
|
187
187
|
:close-btn-text="closeBtnText"
|
|
188
188
|
:bottom="bottom"
|
|
189
|
-
:rounded="
|
|
189
|
+
:rounded="pill"
|
|
190
190
|
type="success"
|
|
191
191
|
>
|
|
192
192
|
<template #default>This is a success notification</template>
|
|
@@ -208,7 +208,7 @@ Success.parameters = {
|
|
|
208
208
|
import { VBtn } from 'vuetify/components'
|
|
209
209
|
import { NotificationBar } from '@cnamts/synapse'
|
|
210
210
|
import { ref } from 'vue'
|
|
211
|
-
import { useNotificationService } from '
|
|
211
|
+
import { useNotificationService } from '@cnamts/synpase'
|
|
212
212
|
|
|
213
213
|
const { addNotification } = useNotificationService()
|
|
214
214
|
const showNotification = ref(false)
|
|
@@ -232,6 +232,7 @@ Success.parameters = {
|
|
|
232
232
|
export const Warning: Story = Default.bind({})
|
|
233
233
|
Warning.args = {
|
|
234
234
|
...Default.args,
|
|
235
|
+
rounded: 'pill',
|
|
235
236
|
type: 'warning',
|
|
236
237
|
}
|
|
237
238
|
Warning.parameters = {
|
|
@@ -244,7 +245,7 @@ Warning.parameters = {
|
|
|
244
245
|
v-model="showNotification"
|
|
245
246
|
:close-btn-text="closeBtnText"
|
|
246
247
|
:bottom="bottom"
|
|
247
|
-
:rounded="
|
|
248
|
+
:rounded="pill"
|
|
248
249
|
type="warning"
|
|
249
250
|
>
|
|
250
251
|
<template #default>This is a warning notification</template>
|
|
@@ -266,7 +267,7 @@ Warning.parameters = {
|
|
|
266
267
|
import { VBtn } from 'vuetify/components'
|
|
267
268
|
import { NotificationBar } from '@cnamts/synapse'
|
|
268
269
|
import { ref } from 'vue'
|
|
269
|
-
import { useNotificationService } from '
|
|
270
|
+
import { useNotificationService } from '@cnamts/synpase'
|
|
270
271
|
|
|
271
272
|
const { addNotification } = useNotificationService()
|
|
272
273
|
const showNotification = ref(false)
|
|
@@ -290,6 +291,7 @@ Warning.parameters = {
|
|
|
290
291
|
export const Error: Story = Default.bind({})
|
|
291
292
|
Error.args = {
|
|
292
293
|
...Default.args,
|
|
294
|
+
rounded: 'pill',
|
|
293
295
|
type: 'error',
|
|
294
296
|
}
|
|
295
297
|
Error.parameters = {
|
|
@@ -302,7 +304,7 @@ Error.parameters = {
|
|
|
302
304
|
v-model="showNotification"
|
|
303
305
|
:close-btn-text="closeBtnText"
|
|
304
306
|
:bottom="bottom"
|
|
305
|
-
:rounded="
|
|
307
|
+
:rounded="pill"
|
|
306
308
|
type="error"
|
|
307
309
|
>
|
|
308
310
|
<template #default>This is an error notification</template>
|
|
@@ -324,7 +326,7 @@ Error.parameters = {
|
|
|
324
326
|
import { VBtn } from 'vuetify/components'
|
|
325
327
|
import { NotificationBar } from '@cnamts/synapse'
|
|
326
328
|
import { ref } from 'vue'
|
|
327
|
-
import { useNotificationService } from '
|
|
329
|
+
import { useNotificationService } from '@cnamts/synpase'
|
|
328
330
|
|
|
329
331
|
const { addNotification } = useNotificationService()
|
|
330
332
|
const showNotification = ref(false)
|
|
@@ -348,6 +350,7 @@ Error.parameters = {
|
|
|
348
350
|
export const Bottom: Story = Default.bind({})
|
|
349
351
|
Bottom.args = {
|
|
350
352
|
...Default.args,
|
|
353
|
+
rounded: 'pill',
|
|
351
354
|
bottom: true,
|
|
352
355
|
}
|
|
353
356
|
Bottom.parameters = {
|
|
@@ -360,7 +363,7 @@ Bottom.parameters = {
|
|
|
360
363
|
v-model="showNotification"
|
|
361
364
|
:close-btn-text="closeBtnText"
|
|
362
365
|
:bottom="true"
|
|
363
|
-
:rounded="
|
|
366
|
+
:rounded="pill"
|
|
364
367
|
:type="type"
|
|
365
368
|
>
|
|
366
369
|
<template #default>This is a bottom-positioned notification</template>
|
|
@@ -382,7 +385,7 @@ Bottom.parameters = {
|
|
|
382
385
|
import { VBtn } from 'vuetify/components'
|
|
383
386
|
import { NotificationBar } from '@cnamts/synapse'
|
|
384
387
|
import { ref } from 'vue'
|
|
385
|
-
import { useNotificationService } from '
|
|
388
|
+
import { useNotificationService } from '@cnamts/synpase'
|
|
386
389
|
|
|
387
390
|
const { addNotification } = useNotificationService()
|
|
388
391
|
const showNotification = ref(false)
|
|
@@ -406,6 +409,7 @@ Bottom.parameters = {
|
|
|
406
409
|
export const CustomCloseBtnText: Story = Default.bind({})
|
|
407
410
|
CustomCloseBtnText.args = {
|
|
408
411
|
...Default.args,
|
|
412
|
+
rounded: 'pill',
|
|
409
413
|
closeBtnText: 'Masquer',
|
|
410
414
|
}
|
|
411
415
|
CustomCloseBtnText.parameters = {
|
|
@@ -418,7 +422,7 @@ CustomCloseBtnText.parameters = {
|
|
|
418
422
|
v-model="showNotification"
|
|
419
423
|
close-btn-text="Masquer"
|
|
420
424
|
:bottom="bottom"
|
|
421
|
-
:rounded="
|
|
425
|
+
:rounded="pill"
|
|
422
426
|
:type="type"
|
|
423
427
|
>
|
|
424
428
|
<template #default>This is a notification with custom close button text</template>
|
|
@@ -440,10 +444,11 @@ CustomCloseBtnText.parameters = {
|
|
|
440
444
|
import { VBtn } from 'vuetify/components'
|
|
441
445
|
import { NotificationBar } from '@cnamts/synapse'
|
|
442
446
|
import { ref } from 'vue'
|
|
443
|
-
import { useNotificationService } from '
|
|
447
|
+
import { useNotificationService } from '@cnamts/synpase'
|
|
444
448
|
|
|
445
449
|
const { addNotification } = useNotificationService()
|
|
446
450
|
const showNotification = ref(false)
|
|
451
|
+
const rounded = 'pill'
|
|
447
452
|
|
|
448
453
|
const envoyerNotification = (message: string) => {
|
|
449
454
|
const notification = {
|
|
@@ -1,70 +1,152 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as PasswordFieldStories from './PasswordField.stories'
|
|
3
|
-
import PasswordField from './PasswordField.vue';
|
|
1
|
+
import { Meta, Canvas, Controls, Source } from '@storybook/blocks'
|
|
2
|
+
import * as PasswordFieldStories from './PasswordField.stories'
|
|
4
3
|
|
|
5
|
-
<Meta
|
|
4
|
+
<Meta of={PasswordFieldStories} />
|
|
6
5
|
|
|
7
6
|
# PasswordField
|
|
8
7
|
|
|
9
|
-
Le composant `PasswordField` est
|
|
10
|
-
Il permet également d’afficher ou de masquer le contenu du champ à l’aide d’une icône.
|
|
8
|
+
Le composant `PasswordField` est un champ de saisie sécurisé conçu pour la gestion des mots de passe. Il hérite des fonctionnalités du composant `SyTextField` tout en ajoutant des fonctionnalités spécifiques à la saisie de mots de passe.
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
## Utilisation basique
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
La version de base du composant avec le style outlined par défaut.
|
|
15
13
|
|
|
16
|
-
<
|
|
14
|
+
<Canvas of={PasswordFieldStories.Default} />
|
|
17
15
|
|
|
18
|
-
##
|
|
16
|
+
## Fonctionnalités principales
|
|
17
|
+
|
|
18
|
+
- **Masquage/affichage du mot de passe** : Une icône permet de basculer entre l'affichage en clair et masqué
|
|
19
|
+
- **Validation personnalisable** : Support des messages d'erreur, d'avertissement et de succès
|
|
20
|
+
- **Styles configurables** : Choix entre les styles `outlined` et `underlined`
|
|
21
|
+
- **États spéciaux** : Support des états désactivé et lecture seule
|
|
22
|
+
- **Validation automatique** : Validation à la perte de focus configurable
|
|
23
|
+
|
|
24
|
+
## API
|
|
25
|
+
|
|
26
|
+
<Controls of={PasswordFieldStories.Default} />
|
|
27
|
+
|
|
28
|
+
<Source
|
|
29
|
+
dark code={`
|
|
30
|
+
<template>
|
|
31
|
+
<PasswordField
|
|
32
|
+
v-model="password"
|
|
33
|
+
label="Mot de passe"
|
|
34
|
+
/>
|
|
35
|
+
</template>
|
|
19
36
|
|
|
20
|
-
<Source
|
|
21
|
-
dark
|
|
22
|
-
code={`
|
|
23
37
|
<script setup lang="ts">
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const password = ref('')
|
|
28
|
-
const passwordFieldRef = ref() // Référence Vue pour accéder au composant enfant
|
|
29
|
-
|
|
30
|
-
function handleSubmit() {
|
|
31
|
-
// Appeler la méthode exposée validateOnSubmit via la référence
|
|
32
|
-
const isValid = passwordFieldRef.value?.validateOnSubmit()
|
|
33
|
-
if (!isValid) {
|
|
34
|
-
alert('Veuillez corriger les erreurs avant de soumettre.')
|
|
35
|
-
} else {
|
|
36
|
-
alert('Formulaire soumis avec succès !')
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
</script>
|
|
38
|
+
import { ref } from 'vue'
|
|
39
|
+
import { PasswordField } from '@cnamts/synapse'
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<PasswordField
|
|
44
|
-
ref="passwordFieldRef"
|
|
45
|
-
v-model="password"
|
|
46
|
-
outlined
|
|
47
|
-
:is-validate-on-blur="true"
|
|
48
|
-
/>
|
|
49
|
-
<button type="submit">Soumettre</button>
|
|
50
|
-
</form>
|
|
51
|
-
</template>
|
|
41
|
+
const password = ref('')
|
|
42
|
+
</script>
|
|
52
43
|
`}
|
|
53
44
|
/>
|
|
54
45
|
|
|
55
|
-
##
|
|
46
|
+
## Validation
|
|
47
|
+
|
|
48
|
+
### Validation simple
|
|
49
|
+
|
|
50
|
+
Le composant peut être requis et afficher un message d'erreur si le champ est vide.
|
|
51
|
+
|
|
52
|
+
<Canvas of={PasswordFieldStories.Required} />
|
|
53
|
+
|
|
54
|
+
### Validation avancée
|
|
55
|
+
|
|
56
|
+
Exemple complet montrant les différents types de validation (erreurs, avertissements, succès).
|
|
57
|
+
|
|
58
|
+
<Canvas of={PasswordFieldStories.WithValidation} />
|
|
59
|
+
|
|
60
|
+
### Exemples d'états de validation
|
|
61
|
+
|
|
62
|
+
<div className="sb-grid">
|
|
63
|
+
<div>
|
|
64
|
+
<h4>Avec erreur</h4>
|
|
65
|
+
<Canvas of={PasswordFieldStories.WithError} />
|
|
66
|
+
</div>
|
|
67
|
+
<div>
|
|
68
|
+
<h4>Avec avertissement</h4>
|
|
69
|
+
<Canvas of={PasswordFieldStories.WithWarning} />
|
|
70
|
+
</div>
|
|
71
|
+
<div>
|
|
72
|
+
<h4>Avec succès</h4>
|
|
73
|
+
<Canvas of={PasswordFieldStories.WithSuccess} />
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
### Validation de formulaire
|
|
78
|
+
|
|
79
|
+
Le composant expose une méthode `validateOnSubmit` pour valider le champ lors de la soumission d'un formulaire.
|
|
80
|
+
|
|
81
|
+
<Canvas of={PasswordFieldStories.WithFormValidation} />
|
|
82
|
+
|
|
83
|
+
<Source
|
|
84
|
+
dark code={`
|
|
85
|
+
<template>
|
|
86
|
+
<form @submit.prevent="handleSubmit">
|
|
87
|
+
<PasswordField
|
|
88
|
+
ref="passwordFieldRef"
|
|
89
|
+
v-model="password"
|
|
90
|
+
required
|
|
91
|
+
:custom-rules="customRules"
|
|
92
|
+
/>
|
|
93
|
+
<button type="submit">Valider</button>
|
|
94
|
+
</form>
|
|
95
|
+
</template>
|
|
96
|
+
|
|
97
|
+
<script setup lang="ts">
|
|
98
|
+
import { ref } from 'vue'
|
|
99
|
+
import { PasswordField } from '@cnamts/synapse'
|
|
100
|
+
|
|
101
|
+
const password = ref('')
|
|
102
|
+
const passwordFieldRef = ref()
|
|
103
|
+
|
|
104
|
+
const customRules = [{
|
|
105
|
+
type: 'custom',
|
|
106
|
+
options: {
|
|
107
|
+
message: 'Le mot de passe doit contenir au moins 8 caractères',
|
|
108
|
+
validate: (value: string) => value.length >= 8
|
|
109
|
+
}
|
|
110
|
+
}]
|
|
111
|
+
|
|
112
|
+
function handleSubmit() {
|
|
113
|
+
const isValid = passwordFieldRef.value?.validateOnSubmit()
|
|
114
|
+
if (!isValid) {
|
|
115
|
+
// Gérer l'erreur
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
// Continuer avec la soumission
|
|
119
|
+
}
|
|
120
|
+
</script>
|
|
121
|
+
`}
|
|
122
|
+
/>
|
|
56
123
|
|
|
57
|
-
###
|
|
124
|
+
### Méthodes exposées
|
|
58
125
|
|
|
59
|
-
|
|
60
|
-
- **isValidateOnBlur** : Si `true`, la validation se déclenche automatiquement lors du blur (perte de focus).
|
|
126
|
+
Le composant expose les méthodes et propriétés suivantes via `defineExpose` :
|
|
61
127
|
|
|
62
|
-
|
|
128
|
+
- **showEyeIcon** : (ref) Contrôle l'affichage du mot de passe
|
|
129
|
+
- **errors** : (ref) Liste des erreurs de validation actuelles
|
|
130
|
+
- **warnings** : (ref) Liste des avertissements actuels
|
|
131
|
+
- **successes** : (ref) Liste des messages de succès actuels
|
|
132
|
+
- **validateOnSubmit** : () => boolean - Méthode pour valider le champ, retourne true si valide
|
|
63
133
|
|
|
64
|
-
|
|
134
|
+
## Bonnes pratiques
|
|
65
135
|
|
|
66
|
-
|
|
136
|
+
1. **Validation progressive** :
|
|
137
|
+
- Utilisez `isValidateOnBlur` pour une validation en temps réel
|
|
138
|
+
- Combinez erreurs, avertissements et succès pour guider l'utilisateur
|
|
67
139
|
|
|
140
|
+
2. **Messages clairs** :
|
|
141
|
+
- Utilisez des messages d'erreur explicites
|
|
142
|
+
- Fournissez des suggestions d'amélioration via les warnings
|
|
143
|
+
- Confirmez les bonnes pratiques avec les messages de succès
|
|
68
144
|
|
|
145
|
+
3. **Accessibilité** :
|
|
146
|
+
- Toujours fournir un label explicite
|
|
147
|
+
- Utiliser la prop `required` quand nécessaire
|
|
148
|
+
- Considérer l'utilisation de `displayAsterisk` pour les champs requis
|
|
69
149
|
|
|
150
|
+
## En savoir plus
|
|
70
151
|
|
|
152
|
+
Pour plus d'informations sur l'utilisation des règles de validation, consultez la section [Comment utiliser les rules](/docs/guide-du-dev-comment-utiliser-les-rules--docs).
|