@cnamts/synapse 1.0.6 → 1.0.8
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/{DateFilter-BlOpwEVq.js → DateFilter-DkqG0pmr.js} +1 -1
- package/dist/{NumberFilter-BPUXE4wY.js → NumberFilter-Ck7AwD39.js} +1 -1
- package/dist/{PeriodFilter-B2yx329_.js → PeriodFilter-LRI6YpgU.js} +1 -1
- package/dist/{SelectFilter-CedKn1oV.js → SelectFilter-DPc70Jk7.js} +1 -1
- package/dist/{TextFilter-DkhJjRtR.js → TextFilter-DRQL7uD8.js} +1 -1
- package/dist/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.d.ts +116 -0
- package/dist/components/Amelipro/AmeliproAccordionGroup/types.d.ts +4 -0
- package/dist/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.d.ts +220 -0
- package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.d.ts +68 -0
- package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.d.ts +70 -0
- package/dist/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.d.ts +204 -0
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +26 -26
- package/dist/components/Amelipro/AmeliproBadge/AmeliproBadge.d.ts +59 -0
- package/dist/components/Amelipro/AmeliproBtn/AmeliproBtn.d.ts +3 -3
- package/dist/components/Amelipro/AmeliproCaptcha/AmeliproCaptcha.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarousel.d.ts +214 -0
- package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/AmeliproCarouselItem.d.ts +70 -0
- package/dist/components/Amelipro/AmeliproCarousel/types.d.ts +7 -0
- package/dist/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.d.ts +125 -0
- package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproIllustratedDataTile/AmeliproIllustratedDataTile.d.ts +2 -2
- package/dist/components/Amelipro/AmeliproResultList/AmeliproResultList.d.ts +164 -0
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +27 -27
- package/dist/components/Amelipro/AmeliproStateTile/AmeliproStateTile.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproTable/AmeliproTable.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +32 -32
- package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +6 -6
- package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +7 -7
- package/dist/components/Amelipro/AmeliproTileBtn/AmeliproTileBtn.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproTooltips/AmeliproTooltips.d.ts +2 -2
- package/dist/components/ChipList/ChipList.d.ts +4 -0
- package/dist/components/ChipList/locales.d.ts +4 -2
- package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +8 -8
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +329 -1296
- package/dist/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.d.ts +0 -1
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +2 -0
- package/dist/components/Customs/SyTabs/SyTabs.d.ts +71 -0
- package/dist/components/Customs/SyTabs/config.d.ts +17 -0
- package/dist/components/Customs/SyTabs/types.d.ts +11 -0
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +9 -9
- package/dist/components/DataList/DataList.d.ts +1 -1
- package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +4811 -240
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +52 -33
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +23 -10
- package/dist/components/DatePicker/composables/useDateInputEditing.d.ts +1 -0
- package/dist/components/DatePicker/composables/useTodayButton.d.ts +1 -0
- package/dist/components/DialogBox/DialogBox.d.ts +219 -0
- package/dist/components/HeaderLoading/HeaderLoading.d.ts +27 -0
- package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +110 -3
- package/dist/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.d.ts +19 -1
- package/dist/components/LangBtn/LangBtn.d.ts +2 -2
- package/dist/components/NirField/NirField.d.ts +18 -18
- package/dist/components/PeriodField/PeriodField.d.ts +10766 -1620
- package/dist/components/PhoneField/PhoneField.d.ts +1866 -2
- package/dist/components/PhoneField/indicatifs.d.ts +1 -0
- package/dist/components/PhoneField/locales.d.ts +1 -0
- package/dist/components/RangeField/RangeField.d.ts +1 -1
- package/dist/components/RangeField/RangeSlider/RangeSlider.d.ts +1 -1
- package/dist/components/SubHeader/SubHeader.d.ts +8 -0
- package/dist/components/SubHeader/locales.d.ts +1 -0
- package/dist/components/SyTextArea/SyTextArea.d.ts +6 -6
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +5 -4
- package/dist/components/Tables/SyTable/SyTable.d.ts +5 -4
- package/dist/components/Tables/common/SyTablePagination.d.ts +333 -1296
- package/dist/components/Tables/common/organizeColumns/OrganizeColumns.d.ts +2 -2
- package/dist/components/Tables/common/types.d.ts +2 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/design-system-v3.js +173 -164
- package/dist/design-system-v3.umd.cjs +286 -263
- package/dist/{main-BXPFSAB4.js → main-DXMoMtj5.js} +13176 -11457
- package/dist/services/NotificationService.d.ts +1 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/assets/amelipro/icons.ts +38 -11
- package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.mdx +20 -0
- package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.stories.ts +135 -0
- package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.vue +107 -0
- package/src/components/Amelipro/AmeliproAccordionGroup/__tests__/AmeliproAccordionGroup.spec.ts +37 -0
- package/src/components/Amelipro/AmeliproAccordionGroup/__tests__/__snapshots__/AmeliproAccordionGroup.spec.ts.snap +513 -0
- package/src/components/Amelipro/AmeliproAccordionGroup/types.d.ts +4 -0
- package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.mdx +16 -0
- package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.stories.ts +300 -0
- package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.vue +288 -0
- package/src/components/Amelipro/AmeliproAccordionList/__tests__/AmeliproAccordionList.spec.ts +38 -0
- package/src/components/Amelipro/AmeliproAccordionList/__tests__/__snapshots__/AmeliproAccordionList.spec.ts.snap +1712 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.mdx +19 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.stories.ts +68 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.vue +66 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.vue +145 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/__tests__/AmeliproAccordionResultTemplate.spec.ts +24 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/__tests__/__snapshots__/AmeliproAccordionResultTemplate.spec.ts.snap +127 -0
- package/src/components/Amelipro/AmeliproAccordionResult/__tests__/AmeliproAccordionResult.spec.ts +24 -0
- package/src/components/Amelipro/AmeliproAccordionResult/__tests__/__snapshots__/AmeliproAccordionResult.spec.ts.snap +123 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.mdx +20 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.stories.ts +273 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.vue +275 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/__tests__/AmeliproAccordionResultList.spec.ts +38 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/__tests__/__snapshots__/AmeliproAccordionResultList.spec.ts.snap +1593 -0
- package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.mdx +15 -0
- package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.stories.ts +54 -0
- package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.vue +76 -0
- package/src/components/Amelipro/AmeliproBadge/__tests__/AmeliproBadge.spec.ts +20 -0
- package/src/components/Amelipro/AmeliproBadge/__tests__/__snapshots__/AmeliproBadge.spec.ts.snap +19 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.mdx +15 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.stories.ts +191 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.vue +263 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/AmeliproCarouselItem.vue +93 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/__tests__/AmeliproCarouselItem.spec.ts +24 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/__tests__/__snapshots__/AmeliproCarouselItem.spec.ts.snap +43 -0
- package/src/components/Amelipro/AmeliproCarousel/__tests__/AmeliproCarousel.spec.ts +40 -0
- package/src/components/Amelipro/AmeliproCarousel/__tests__/__snapshots__/AmeliproCarousel.spec.ts.snap +342 -0
- package/src/components/Amelipro/AmeliproCarousel/types.d.ts +8 -0
- package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.mdx +18 -0
- package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.stories.ts +67 -0
- package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.vue +233 -0
- package/src/components/Amelipro/AmeliproClickableTile/tests/AmeliproClickableTile.spec.ts +21 -0
- package/src/components/Amelipro/AmeliproClickableTile/tests/__snapshots__/AmeliproClickableTile.spec.ts.snap +140 -0
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeader.vue +7 -1
- package/src/components/Amelipro/AmeliproHeader/tests/__snapshots__/AmeliproHeader.spec.ts.snap +5 -4
- package/src/components/Amelipro/AmeliproIcon/iconList.ts +6 -0
- package/src/components/Amelipro/AmeliproPageLayout/tests/__snapshots__/AmeliproPageLayout.spec.ts.snap +5 -4
- package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.mdx +15 -0
- package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.stories.ts +264 -0
- package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.vue +231 -0
- package/src/components/Amelipro/AmeliproResultList/__tests__/AmeliproResultList.spec.ts +37 -0
- package/src/components/Amelipro/AmeliproResultList/__tests__/__snapshots__/AmeliproResultList.spec.ts.snap +434 -0
- package/src/components/Amelipro/AmeliproTable/AmeliproTable.vue +6 -5
- package/src/components/Amelipro/AmeliproTable/__tests__/__snapshots__/AmeliproTable.spec.ts.snap +23 -26
- package/src/components/Amelipro/AmeliproTileBtn/AmeliproTileBtn.stories.ts +2 -2
- package/src/components/ChipList/Accessibilite.stories.ts +4 -0
- package/src/components/ChipList/ChipList.vue +185 -42
- package/src/components/ChipList/locales.ts +4 -2
- package/src/components/ChipList/tests/chipList.spec.ts +7 -4
- package/src/components/Customs/Selects/SelectOverview.mdx +34 -66
- package/src/components/Customs/Selects/SyBtnSelect/SyBtnSelect.stories.ts +10 -10
- package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.mdx +3 -0
- package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.stories.ts +14 -0
- package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +14 -6
- package/src/components/Customs/Selects/SySelect/SySelect.vue +268 -205
- package/src/components/Customs/Selects/SySelect/composables/tests/useSySelectKeyboard.spec.ts +0 -10
- package/src/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.ts +0 -5
- package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +184 -25
- package/src/components/Customs/SyCheckbox/SyCheckbox.mdx +3 -1
- package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +165 -0
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +28 -9
- package/src/components/Customs/SyTabs/Accessibilite.mdx +309 -0
- package/src/components/Customs/SyTabs/SyTabs.mdx +117 -0
- package/src/components/Customs/SyTabs/SyTabs.stories.ts +354 -0
- package/src/components/Customs/SyTabs/SyTabs.vue +413 -0
- package/src/components/Customs/SyTabs/config.ts +17 -0
- package/src/components/Customs/SyTabs/tests/SyTabs.spec.ts +425 -0
- package/src/components/Customs/SyTabs/types.ts +12 -0
- package/src/components/Customs/SyTextField/SyTextField.mdx +3 -0
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +142 -1
- package/src/components/Customs/SyTextField/SyTextField.vue +19 -16
- package/src/components/DataList/DataList.vue +47 -49
- package/src/components/DataListGroup/DataListGroup.vue +1 -1
- package/src/components/DataListItem/DataListItem.vue +67 -63
- package/src/components/DataListItem/tests/DataListItem.spec.ts +2 -2
- package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +3 -3
- package/src/components/DatePicker/CalendarMode/DatePicker.vue +49 -13
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +412 -649
- package/src/components/DatePicker/DatePickerValidationExample/CalendarMode.stories.ts +215 -0
- package/src/components/DatePicker/DatePickerValidationExample/ComplexDatePicker.stories.ts +218 -0
- package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.mdx +2 -0
- package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.stories.ts +1 -1
- package/src/components/DatePicker/DatePickerValidationExample/DateTextInput.stories.ts +218 -0
- package/src/components/DatePicker/DatePickerValidationExample/MultiMode.stories.ts +281 -0
- package/src/components/DatePicker/DateTextInput/DateTextInput.events.spec.ts +17 -4
- package/src/components/DatePicker/DateTextInput/DateTextInput.range.spec.ts +111 -18
- package/src/components/DatePicker/DateTextInput/DateTextInput.spec.ts +238 -6
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +716 -757
- package/src/components/DatePicker/composables/tests/useDateInputEditing.spec.ts +4 -4
- package/src/components/DatePicker/composables/tests/useDisplayedDateString.spec.ts +17 -10
- package/src/components/DatePicker/composables/useDateInputEditing.ts +52 -22
- package/src/components/DatePicker/composables/useDisplayedDateString.ts +18 -4
- package/src/components/DatePicker/composables/useTodayButton.ts +13 -1
- package/src/components/DatePicker/utils/dateFormattingUtils.ts +79 -14
- package/src/components/DialogBox/DialogBox.stories.ts +12 -0
- package/src/components/DialogBox/DialogBox.vue +16 -11
- package/src/components/DialogBox/tests/DialogBox.spec.ts +22 -0
- package/src/components/HeaderLoading/Accessibilite.mdx +429 -8
- package/src/components/HeaderLoading/Accessibilite.stories.ts +4 -0
- package/src/components/HeaderLoading/HeaderLoading.vue +59 -0
- package/src/components/HeaderNavigationBar/HeaderNavigationBar.mdx +17 -2
- package/src/components/HeaderNavigationBar/HeaderNavigationBar.stories.ts +91 -2
- package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +37 -1
- package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +284 -21
- package/src/components/HeaderNavigationBar/tests/HeaderNavigationBar.spec.ts +2 -2
- package/src/components/NirField/NirField.mdx +3 -0
- package/src/components/NirField/NirField.vue +10 -1
- package/src/components/NirField/tests/NirField.spec.ts +81 -0
- package/src/components/NotificationBar/NotificationBar.stories.ts +128 -2
- package/src/components/NotificationBar/NotificationBar.vue +16 -1
- package/src/components/NotificationBar/tests/NotificationBar.spec.ts +65 -0
- package/src/components/PasswordField/PasswordField.mdx +3 -0
- package/src/components/PeriodField/PeriodField.mdx +2 -0
- package/src/components/PeriodField/PeriodField.stories.ts +195 -0
- package/src/components/PhoneField/Accessibilite.stories.ts +4 -0
- package/src/components/PhoneField/PhoneField.mdx +3 -1
- package/src/components/PhoneField/PhoneField.stories.ts +285 -1
- package/src/components/PhoneField/PhoneField.vue +228 -95
- package/src/components/PhoneField/indicatifs.ts +102 -102
- package/src/components/PhoneField/locales.ts +1 -0
- package/src/components/PhoneField/tests/PhoneField.spec.ts +419 -2
- package/src/components/SkipLink/SkipLink.vue +3 -31
- package/src/components/SkipLink/tests/skipLink.spec.ts +0 -21
- package/src/components/SubHeader/Accessibilite.stories.ts +8 -0
- package/src/components/SubHeader/SubHeader.mdx +1 -0
- package/src/components/SubHeader/SubHeader.stories.ts +179 -60
- package/src/components/SubHeader/SubHeader.vue +45 -15
- package/src/components/SubHeader/locales.ts +1 -0
- package/src/components/SyAlert/SyAlert.vue +6 -0
- package/src/components/Tables/SyServerTable/SyServerTable.mdx +3 -10
- package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +242 -0
- package/src/components/Tables/SyServerTable/SyServerTable.vue +29 -10
- package/src/components/Tables/SyTable/SyTable.mdx +3 -10
- package/src/components/Tables/SyTable/SyTable.stories.ts +242 -0
- package/src/components/Tables/SyTable/SyTable.vue +2 -0
- package/src/components/Tables/common/SyTablePagination.vue +13 -6
- package/src/components/Tables/common/filters/tests/SelectFilter.spec.ts +6 -1
- package/src/components/Tables/common/tests/SyTablePagination.spec.ts +157 -0
- package/src/components/Tables/common/types.ts +2 -0
- package/src/components/index.ts +9 -0
- package/src/composables/useFilterable/useFilterable.ts +10 -0
- package/src/designTokens/tokens/amelipro/apColors.ts +1 -1
- package/src/designTokens/tokens/cnam/cnamSemantic.ts +3 -3
- package/src/services/NotificationService.ts +9 -0
- package/src/stories/Components/Components.stories.ts +1 -1
- package/src/stories/GuideDuDev/FormValidationGuide.mdx +342 -0
- package/src/stories/Templates/Templates.stories.ts +1 -1
- package/src/utils/functions/ameliproColors/ameliproColors.ts +1 -1
- package/dist/components/DataList/locales.d.ts +0 -3
- package/src/components/DataList/locales.ts +0 -3
- package/src/components/PhoneField/tests/PhoneField.additional.spec.ts +0 -266
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import HeaderMenuSection from '@/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.vue'
|
|
6
6
|
import useHeaderResponsiveMode from '@/components/HeaderBar/useHeaderResponsiveMode'
|
|
7
7
|
import type { CustomizableOptions } from '@/composables/useCustomizableOptions'
|
|
8
|
-
import { computed } from 'vue'
|
|
8
|
+
import { computed, ref } from 'vue'
|
|
9
9
|
import { type RouteLocationRaw } from 'vue-router'
|
|
10
10
|
import HorizontalNavbar from './HorizontalNavbar/HorizontalNavbar.vue'
|
|
11
11
|
import type { NavigationItem } from './types'
|
|
@@ -35,8 +35,16 @@
|
|
|
35
35
|
* The items to show in the horizontal menu
|
|
36
36
|
*/
|
|
37
37
|
items?: NavigationItem[]
|
|
38
|
+
/** Si activé, une confirmation sera demandée avant de changer d'onglet */
|
|
39
|
+
confirmTabChange?: boolean
|
|
40
|
+
/** Message affiché dans la boîte de dialogue de confirmation */
|
|
41
|
+
confirmationMessage?: boolean
|
|
38
42
|
}>(),
|
|
39
43
|
{
|
|
44
|
+
// Confirmation related defaults
|
|
45
|
+
confirmTabChange: false,
|
|
46
|
+
confirmationMessage: false,
|
|
47
|
+
// Navigation related defaults
|
|
40
48
|
homeAriaLabel: undefined,
|
|
41
49
|
serviceTitle: undefined,
|
|
42
50
|
serviceSubtitle: undefined,
|
|
@@ -47,6 +55,9 @@
|
|
|
47
55
|
items: undefined,
|
|
48
56
|
})
|
|
49
57
|
|
|
58
|
+
// Définition des événements émis
|
|
59
|
+
const emit = defineEmits(['confirm-tab-change'])
|
|
60
|
+
|
|
50
61
|
type SlotProps = {
|
|
51
62
|
menuOpen: boolean | undefined
|
|
52
63
|
}
|
|
@@ -76,6 +87,19 @@
|
|
|
76
87
|
|
|
77
88
|
const { isDesktop } = useHeaderResponsiveMode()
|
|
78
89
|
|
|
90
|
+
const horizontalNavbarRef = ref<InstanceType<typeof HorizontalNavbar> | null>(null)
|
|
91
|
+
|
|
92
|
+
// Exposer une méthode pour réinitialiser la sélection d'onglet
|
|
93
|
+
defineExpose({
|
|
94
|
+
resetTabSelection: () => {
|
|
95
|
+
// Déléguer au composant HorizontalNavbar si disponible
|
|
96
|
+
if (horizontalNavbarRef.value && !verticalMenu.value) {
|
|
97
|
+
return horizontalNavbarRef.value.resetTabSelection()
|
|
98
|
+
}
|
|
99
|
+
return null
|
|
100
|
+
},
|
|
101
|
+
})
|
|
102
|
+
|
|
79
103
|
const verticalMenu = computed<boolean>(() => {
|
|
80
104
|
return (
|
|
81
105
|
!isDesktop.value
|
|
@@ -84,6 +108,15 @@
|
|
|
84
108
|
&& props.items.length > props.maxHorizontalMenuItems)
|
|
85
109
|
)
|
|
86
110
|
})
|
|
111
|
+
|
|
112
|
+
// Fonction qui gère la confirmation de changement d'onglet
|
|
113
|
+
// Cette fonction est appelée quand un utilisateur essaie de changer d'onglet
|
|
114
|
+
// et que la confirmation est activée
|
|
115
|
+
function handleConfirmTabChange(message: string, callback: (confirmed: boolean) => void) {
|
|
116
|
+
// Émettre un événement avec le message et le callback
|
|
117
|
+
// Le composant parent pourra écouter cet événement et afficher sa propre UI de confirmation
|
|
118
|
+
emit('confirm-tab-change', message, callback)
|
|
119
|
+
}
|
|
87
120
|
</script>
|
|
88
121
|
|
|
89
122
|
<template>
|
|
@@ -167,8 +200,11 @@
|
|
|
167
200
|
<template #append>
|
|
168
201
|
<HorizontalNavbar
|
|
169
202
|
v-if="props.items && !verticalMenu"
|
|
203
|
+
ref="horizontalNavbarRef"
|
|
170
204
|
:items="items"
|
|
171
205
|
:vuetify-options
|
|
206
|
+
:confirm-tab-change="confirmTabChange"
|
|
207
|
+
@confirm-tab-change="handleConfirmTabChange"
|
|
172
208
|
>
|
|
173
209
|
<template #navigation-bar-prepend>
|
|
174
210
|
<slot name="navigation-bar-prepend" />
|
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import { VSheet } from 'vuetify/components'
|
|
3
|
+
import { computed, ref, watch, onMounted, getCurrentInstance } from 'vue'
|
|
4
|
+
import type { Router, RouteLocationNormalizedLoaded } from 'vue-router'
|
|
5
|
+
|
|
6
|
+
import SyTabs from '../../Customs/SyTabs/SyTabs.vue'
|
|
7
|
+
import type { TabItem } from '../../Customs/SyTabs/types'
|
|
8
|
+
|
|
9
|
+
import { type NavigationItem } from '../types'
|
|
3
10
|
import useCustomizableOptions, { type CustomizableOptions } from '@/composables/useCustomizableOptions'
|
|
4
11
|
import { config } from './config'
|
|
5
12
|
|
|
6
|
-
|
|
13
|
+
// Type des méthodes exposées
|
|
14
|
+
type ExposedMethods = {
|
|
15
|
+
resetTabSelection: () => { activeTab: number, activeItemIndex: number }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const props = withDefaults(defineProps<CustomizableOptions & {
|
|
7
19
|
items: NavigationItem[]
|
|
8
|
-
|
|
20
|
+
/** Si activé, une confirmation sera demandée avant de changer d'onglet */
|
|
21
|
+
confirmTabChange?: boolean
|
|
22
|
+
/** Message affiché dans la boîte de dialogue de confirmation */
|
|
23
|
+
confirmationMessage?: boolean
|
|
24
|
+
}>(), {
|
|
25
|
+
confirmTabChange: false,
|
|
26
|
+
confirmationMessage: false,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// Définition des événements émis
|
|
30
|
+
const emit = defineEmits(['cancel-navigation', 'confirm-tab-change'])
|
|
9
31
|
|
|
10
32
|
defineSlots<{
|
|
11
33
|
'navigation-bar-prepend': () => unknown
|
|
@@ -13,33 +35,217 @@
|
|
|
13
35
|
'default': () => unknown
|
|
14
36
|
}>()
|
|
15
37
|
|
|
38
|
+
// Exposer les méthodes pour permettre au composant parent d'interagir
|
|
39
|
+
defineExpose<ExposedMethods>({
|
|
40
|
+
resetTabSelection,
|
|
41
|
+
})
|
|
42
|
+
|
|
16
43
|
const options = useCustomizableOptions(config, props)
|
|
17
44
|
|
|
45
|
+
// Safely get route and router through getCurrentInstance - they might not be available in all contexts
|
|
46
|
+
const instance = getCurrentInstance()
|
|
47
|
+
const route = instance?.appContext.config.globalProperties.$route as RouteLocationNormalizedLoaded | null || null
|
|
48
|
+
const router = instance?.appContext.config.globalProperties.$router as Router | null || null
|
|
49
|
+
|
|
50
|
+
// État pour suivre l'élément actif
|
|
51
|
+
const activeTab = ref<number>(0)
|
|
52
|
+
const activeItemIndex = ref<number>(-1)
|
|
53
|
+
|
|
54
|
+
// Convertir les items de navigation en format TabItem pour SyTabs
|
|
55
|
+
const tabItems = computed<TabItem[]>(() => {
|
|
56
|
+
if (!Array.isArray(props.items)) return []
|
|
57
|
+
return props.items.map((item, index) => ({
|
|
58
|
+
label: item.label,
|
|
59
|
+
value: index,
|
|
60
|
+
content: '',
|
|
61
|
+
href: item.href,
|
|
62
|
+
to: item.to,
|
|
63
|
+
}))
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
// Fonction pour déterminer si un élément de navigation est actif
|
|
67
|
+
function isActive(item: NavigationItem, index: number): boolean {
|
|
68
|
+
// Si l'élément est explicitement activé par un clic ou initialisé
|
|
69
|
+
if (activeItemIndex.value === index) {
|
|
70
|
+
return true
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Pour les liens internes (router-link)
|
|
74
|
+
if (item.to && route) {
|
|
75
|
+
// Gestion des objets de route
|
|
76
|
+
if (typeof item.to === 'object') {
|
|
77
|
+
// Comparer avec le chemin de la route actuelle
|
|
78
|
+
const path = item.to.path || ''
|
|
79
|
+
const isActiveRoute = route.path === path
|
|
80
|
+
if (isActiveRoute) activeItemIndex.value = index
|
|
81
|
+
return isActiveRoute
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Gestion des chaînes de caractères
|
|
85
|
+
if (typeof item.to === 'string') {
|
|
86
|
+
// Comparer exactement ou vérifier si c'est un sous-chemin
|
|
87
|
+
const isActiveRoute = route.path === item.to || (item.to !== '/' && route.path.startsWith(item.to))
|
|
88
|
+
if (isActiveRoute) activeItemIndex.value = index
|
|
89
|
+
return isActiveRoute
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Pour les liens externes, on pourrait comparer avec window.location.href
|
|
94
|
+
if (item.href && typeof window !== 'undefined') {
|
|
95
|
+
const isActiveLink = window.location.href === item.href
|
|
96
|
+
if (isActiveLink) activeItemIndex.value = index
|
|
97
|
+
return isActiveLink
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return false
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Fonction pour activer un élément au clic
|
|
104
|
+
function setActiveItem(index: number) {
|
|
105
|
+
activeItemIndex.value = index
|
|
106
|
+
activeTab.value = index
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Fonction pour gérer la navigation lors d'un changement d'onglet
|
|
110
|
+
async function handleTabChange(index: number) {
|
|
111
|
+
// Mettre à jour l'élément actif
|
|
112
|
+
setActiveItem(index)
|
|
113
|
+
|
|
114
|
+
// Si confirmTabChange est activé, ne pas gérer la navigation ici
|
|
115
|
+
// car c'est SyTabs qui s'en charge après la confirmation
|
|
116
|
+
if (props.confirmTabChange) {
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Récupérer l'élément correspondant à cet index
|
|
121
|
+
const item = props.items?.[index]
|
|
122
|
+
if (!item) return
|
|
123
|
+
|
|
124
|
+
// Navigation vers la destination si nécessaire
|
|
125
|
+
if (item.to && router) {
|
|
126
|
+
try {
|
|
127
|
+
await router.push(item.to)
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.error('Erreur de navigation:', error)
|
|
131
|
+
}
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Gestion des liens externes avec href si nécessaire
|
|
136
|
+
if (item.href && item.href.trim() !== '') {
|
|
137
|
+
window.location.href = item.href
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Fonction pour gérer les confirmations de changement d'onglet
|
|
142
|
+
function handleConfirmTabChange(message: string, callback: (confirmed: boolean) => void) {
|
|
143
|
+
// Transmettre l'événement au composant parent HeaderNavigationBar
|
|
144
|
+
// en passant le callback qui sera appelé plus tard avec le résultat
|
|
145
|
+
emit('confirm-tab-change', message, callback)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Fonction pour synchroniser l'onglet actif avec l'URL courante
|
|
149
|
+
function resetTabSelection() {
|
|
150
|
+
// Si les items ne sont pas un tableau ou vides, ne rien faire
|
|
151
|
+
if (!Array.isArray(props.items) || props.items.length === 0 || !route) {
|
|
152
|
+
return { activeTab: activeTab.value, activeItemIndex: activeItemIndex.value }
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let foundActiveItem = false
|
|
156
|
+
|
|
157
|
+
// Trouver l'élément actif basé sur la route courante
|
|
158
|
+
for (let i = 0; i < props.items.length; i++) {
|
|
159
|
+
if (isActive(props.items[i], i)) {
|
|
160
|
+
activeItemIndex.value = i
|
|
161
|
+
activeTab.value = i
|
|
162
|
+
foundActiveItem = true
|
|
163
|
+
break
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Si aucun élément n'est actif, sélectionner le premier par défaut
|
|
168
|
+
if (!foundActiveItem && props.items.length > 0) {
|
|
169
|
+
activeItemIndex.value = 0
|
|
170
|
+
activeTab.value = 0
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return { activeTab: activeTab.value, activeItemIndex: activeItemIndex.value }
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Initialiser l'élément actif au montage
|
|
177
|
+
onMounted(() => {
|
|
178
|
+
resetTabSelection()
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
// Surveiller les changements de route pour mettre à jour l'élément actif
|
|
182
|
+
watch(() => route?.path, () => {
|
|
183
|
+
// Si route est undefined, ne rien faire
|
|
184
|
+
if (!route) return
|
|
185
|
+
if (Array.isArray(props.items)) {
|
|
186
|
+
// Reset activeItemIndex
|
|
187
|
+
activeItemIndex.value = -1
|
|
188
|
+
|
|
189
|
+
// Trouver l'élément actif basé sur la nouvelle route
|
|
190
|
+
for (let i = 0; i < props.items.length; i++) {
|
|
191
|
+
if (isActive(props.items[i], i)) {
|
|
192
|
+
activeItemIndex.value = i
|
|
193
|
+
activeTab.value = i
|
|
194
|
+
break
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
})
|
|
18
199
|
</script>
|
|
19
200
|
|
|
20
201
|
<template>
|
|
21
|
-
<VSheet
|
|
202
|
+
<VSheet
|
|
203
|
+
v-bind="{
|
|
204
|
+
theme: options.sheet.theme,
|
|
205
|
+
color: options.sheet.color,
|
|
206
|
+
class: { 'v-sheet--dense': options.sheet.dense }
|
|
207
|
+
}"
|
|
208
|
+
>
|
|
22
209
|
<div class="horizontal-menu px-xl-0 px-14">
|
|
23
210
|
<slot name="navigation-bar-prepend" />
|
|
24
211
|
<slot>
|
|
25
|
-
<
|
|
212
|
+
<SyTabs
|
|
26
213
|
class="horizontal-menu__tabs"
|
|
27
|
-
|
|
214
|
+
:items="tabItems"
|
|
215
|
+
:model-value="Number(activeTab)"
|
|
216
|
+
:confirm-tab-change="props.confirmTabChange"
|
|
217
|
+
:confirmation-message="props.confirmationMessage"
|
|
218
|
+
:vuetify-options="{
|
|
219
|
+
sheet: { theme: 'dark', color: '#07275C' },
|
|
220
|
+
tab: { 'base-color': '#B5BECE', 'active-color': '#ffffff', 'slider-color': '#fff' },
|
|
221
|
+
tabs: { height: '60' }
|
|
222
|
+
}"
|
|
223
|
+
@update:model-value="async (val) => {
|
|
224
|
+
activeTab = Number(val);
|
|
225
|
+
await handleTabChange(Number(val));
|
|
226
|
+
}"
|
|
227
|
+
@cancel-navigation="emit('cancel-navigation')"
|
|
228
|
+
@confirm-tab-change="handleConfirmTabChange"
|
|
28
229
|
>
|
|
29
|
-
|
|
30
|
-
|
|
230
|
+
<!-- Ajout des slots pour le contenu personnalisé -->
|
|
231
|
+
<template #tabs-prepend>
|
|
232
|
+
<!-- Contenu optionnel avant les onglets -->
|
|
233
|
+
</template>
|
|
234
|
+
|
|
235
|
+
<template #default>
|
|
236
|
+
<!-- Contenu personnalisé pour les onglets si nécessaire -->
|
|
237
|
+
</template>
|
|
238
|
+
|
|
239
|
+
<!-- Utiliser v-for directement sur les slots dynamiques sans template imbriqués -->
|
|
240
|
+
<template
|
|
241
|
+
v-for="(item, index) in props.items"
|
|
242
|
+
#[`panel-${index}`]
|
|
31
243
|
:key="index"
|
|
32
|
-
:href="item.href"
|
|
33
|
-
:to="item.to"
|
|
34
|
-
v-bind="options.tab"
|
|
35
|
-
tabindex="0"
|
|
36
|
-
class="horizontal-menu__item"
|
|
37
244
|
>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
</VTabs>
|
|
245
|
+
<!-- Le contenu du panneau est intentionnellement vide -->
|
|
246
|
+
<!-- Les liens sont générés directement dans les onglets, pas besoin de contenu dans les panneaux -->
|
|
247
|
+
</template>
|
|
248
|
+
</SyTabs>
|
|
43
249
|
</slot>
|
|
44
250
|
<slot name="navigation-bar-append" />
|
|
45
251
|
</div>
|
|
@@ -57,20 +263,77 @@
|
|
|
57
263
|
margin: 0 auto;
|
|
58
264
|
}
|
|
59
265
|
|
|
60
|
-
.horizontal-
|
|
266
|
+
.horizontal-menu__nav {
|
|
61
267
|
flex: 1 1 0;
|
|
268
|
+
width: 100%;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.horizontal-menu__list {
|
|
272
|
+
display: flex;
|
|
273
|
+
list-style-type: none;
|
|
274
|
+
padding: 0;
|
|
275
|
+
margin: 0;
|
|
276
|
+
width: 100%;
|
|
62
277
|
}
|
|
63
278
|
|
|
64
279
|
.horizontal-menu__item {
|
|
65
280
|
cursor: pointer;
|
|
281
|
+
display: flex;
|
|
282
|
+
align-items: stretch;
|
|
66
283
|
}
|
|
67
284
|
|
|
68
|
-
.horizontal-
|
|
285
|
+
.horizontal-menu__link {
|
|
286
|
+
display: flex;
|
|
287
|
+
align-items: center;
|
|
288
|
+
justify-content: center;
|
|
289
|
+
padding: 0 16px;
|
|
290
|
+
min-height: 53px; /* Correspond à la hauteur définie dans config.ts */
|
|
69
291
|
font-size: 0.875rem;
|
|
70
292
|
font-weight: 700;
|
|
293
|
+
text-decoration: none;
|
|
294
|
+
color: v-bind("options.tab['base-color']"); /* Utilise la couleur du texte définie dans les options */
|
|
295
|
+
transition: color 0.2s ease;
|
|
296
|
+
|
|
297
|
+
&:hover {
|
|
298
|
+
color: #fff;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
&:focus-visible {
|
|
302
|
+
outline: 3px solid #fff; /* Bordure blanche pour un ratio de contraste élevé */
|
|
303
|
+
outline-offset: -3px;
|
|
304
|
+
box-shadow: 0 0 0 1px #07275c; /* Contour secondaire pour améliorer la visibilité */
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
&--active,
|
|
308
|
+
&[aria-current='page'] {
|
|
309
|
+
color: #fff;
|
|
310
|
+
border-bottom: 3px solid #fff; /* Bordure solide et plus visible pour les éléments actifs */
|
|
311
|
+
box-shadow: 0 3px 0 0 #fff; /* Double effet pour être sûr que la bordure est bien visible */
|
|
312
|
+
|
|
313
|
+
&:focus-visible {
|
|
314
|
+
outline: 3px solid #fff;
|
|
315
|
+
outline-offset: 12px;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
71
318
|
}
|
|
72
319
|
|
|
73
|
-
.
|
|
320
|
+
.horizontal-menu__panel-link {
|
|
321
|
+
display: inline-block;
|
|
322
|
+
padding: 8px 16px;
|
|
323
|
+
margin-top: 8px;
|
|
324
|
+
background-color: v-bind('options.sheet.color');
|
|
74
325
|
color: #fff;
|
|
326
|
+
text-decoration: none;
|
|
327
|
+
border-radius: 4px;
|
|
328
|
+
transition: background-color 0.2s ease;
|
|
329
|
+
|
|
330
|
+
&:hover {
|
|
331
|
+
filter: brightness(90%);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
&:focus-visible {
|
|
335
|
+
outline: 3px solid #fff;
|
|
336
|
+
outline-offset: 2px;
|
|
337
|
+
}
|
|
75
338
|
}
|
|
76
339
|
</style>
|
|
@@ -43,8 +43,8 @@ describe('HeaderNavigationBar', () => {
|
|
|
43
43
|
})
|
|
44
44
|
|
|
45
45
|
await wrapper.vm.$nextTick()
|
|
46
|
-
|
|
47
|
-
expect(wrapper.html()).toContain('
|
|
46
|
+
// le vtabs generait des btn dans lesquels le text etait en majuscule ici cela se via le code de SyTabs (toUpperCase() sur les items)
|
|
47
|
+
expect(wrapper.html()).toContain('HOME')
|
|
48
48
|
expect(wrapper.findComponent(HeaderBurgerMenu).exists()).toBe(false)
|
|
49
49
|
expect(wrapper.findComponent(HorizontalNavbar).exists()).toBe(true)
|
|
50
50
|
|
|
@@ -224,3 +224,6 @@ Pour utiliser cette méthode, vous devez ajouter une référence Vue au composan
|
|
|
224
224
|
</template>
|
|
225
225
|
`}
|
|
226
226
|
/>
|
|
227
|
+
|
|
228
|
+
<a href="/?path=/docs/guide-du-dev-guide-de-validation-des-formulaires--docs" className="action-link">Pour plus d'informations sur la validation, consultez le guide de validation des formulaires.</a>
|
|
229
|
+
|
|
@@ -718,7 +718,7 @@
|
|
|
718
718
|
|
|
719
719
|
/* Styles pour le mode fieldset */
|
|
720
720
|
.nir-field--fieldset .number-field-container {
|
|
721
|
-
flex: v-bind('props.clearable ? "0 0 70%" : "0 0
|
|
721
|
+
flex: v-bind('props.clearable ? "0 0 70%" : "0 0 75%"');
|
|
722
722
|
}
|
|
723
723
|
|
|
724
724
|
.nir-field--fieldset .key-field-container {
|
|
@@ -729,4 +729,13 @@
|
|
|
729
729
|
.key-field {
|
|
730
730
|
width: 100%;
|
|
731
731
|
}
|
|
732
|
+
|
|
733
|
+
.key-field {
|
|
734
|
+
min-width: 110px;
|
|
735
|
+
|
|
736
|
+
:deep(.v-messages .v-messages__message) {
|
|
737
|
+
min-width: 100px !important;
|
|
738
|
+
margin-left: -10px !important;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
732
741
|
</style>
|
|
@@ -219,4 +219,85 @@ describe('NirField.vue', () => {
|
|
|
219
219
|
expect(numberInput.value.replace(/\s/g, '')).toBe('2940375120005')
|
|
220
220
|
expect(keyInput.value).toBe('91')
|
|
221
221
|
})
|
|
222
|
+
|
|
223
|
+
it('applies numberMask correctly with vMaska directive', async () => {
|
|
224
|
+
// On teste d'abord la saisie normale de chiffres
|
|
225
|
+
const numberInput = wrapper.find('.number-field input')
|
|
226
|
+
await numberInput.setValue('294037512000')
|
|
227
|
+
await wrapper.vm.$nextTick()
|
|
228
|
+
await flushPromises()
|
|
229
|
+
|
|
230
|
+
// Vérifier que le masque applique correctement les espaces
|
|
231
|
+
const inputElement = numberInput.element as Element & { value: string }
|
|
232
|
+
expect(inputElement.value).toBe('2 94 03 75 120 00')
|
|
233
|
+
|
|
234
|
+
// On ajoute un caractère '5' supplémentaire
|
|
235
|
+
await numberInput.setValue('2940375120005')
|
|
236
|
+
await wrapper.vm.$nextTick()
|
|
237
|
+
await flushPromises()
|
|
238
|
+
expect(inputElement.value).toBe('2 94 03 75 120 005')
|
|
239
|
+
|
|
240
|
+
// Testons le cas où on utilise le caractère spécial 'A' dans le NIR
|
|
241
|
+
// Plutôt que de tester la valeur formatée exacte (qui peut changer selon l'implémentation),
|
|
242
|
+
// testons simplement que la valeur contient 'A' et que la valeur sans espaces est celle attendue
|
|
243
|
+
|
|
244
|
+
// Test plus simple avec juste des chiffres pour vérifier que le masque accepte 13 chiffres
|
|
245
|
+
await numberInput.setValue('1234567891234')
|
|
246
|
+
await wrapper.vm.$nextTick()
|
|
247
|
+
await flushPromises()
|
|
248
|
+
|
|
249
|
+
// Vérifier que la valeur masquée contient bien 13 chiffres (sans les espaces)
|
|
250
|
+
const maskedValue = inputElement.value.replace(/\s/g, '')
|
|
251
|
+
expect(maskedValue.length).toBe(13)
|
|
252
|
+
expect(maskedValue).toBe('1234567891234')
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
it('applies keyMask correctly with vMaska directive', async () => {
|
|
256
|
+
// On teste la saisie de la clé (seulement 2 chiffres autorisés)
|
|
257
|
+
const keyInput = wrapper.find('.key-field input')
|
|
258
|
+
await keyInput.setValue('9')
|
|
259
|
+
await wrapper.vm.$nextTick()
|
|
260
|
+
await flushPromises()
|
|
261
|
+
|
|
262
|
+
// Vérifier qu'un seul chiffre est accepté
|
|
263
|
+
const inputElement = keyInput.element as Element & { value: string }
|
|
264
|
+
expect(inputElement.value).toBe('9')
|
|
265
|
+
|
|
266
|
+
// On ajoute un deuxième chiffre
|
|
267
|
+
await keyInput.setValue('91')
|
|
268
|
+
await wrapper.vm.$nextTick()
|
|
269
|
+
await flushPromises()
|
|
270
|
+
expect(inputElement.value).toBe('91')
|
|
271
|
+
|
|
272
|
+
// On essaie d'ajouter un troisième chiffre
|
|
273
|
+
await keyInput.setValue('913')
|
|
274
|
+
await wrapper.vm.$nextTick()
|
|
275
|
+
await flushPromises()
|
|
276
|
+
// Vérifier que le troisième chiffre n'est pas accepté
|
|
277
|
+
expect(inputElement.value).toBe('91')
|
|
278
|
+
|
|
279
|
+
// On essaie d'ajouter une lettre (non autorisée par le masque)
|
|
280
|
+
await keyInput.setValue('9A')
|
|
281
|
+
await wrapper.vm.$nextTick()
|
|
282
|
+
await flushPromises()
|
|
283
|
+
// Vérifier que la lettre n'est pas acceptée
|
|
284
|
+
expect(inputElement.value).toBe('9')
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
it('automatically focuses key field when number field is complete', async () => {
|
|
288
|
+
// Spy sur la méthode focus de l'élément input
|
|
289
|
+
const focusSpy = vi.spyOn(HTMLElement.prototype, 'focus')
|
|
290
|
+
|
|
291
|
+
// On remplit complètement le champ NIR
|
|
292
|
+
await wrapper.find('.number-field input').setValue('2940375120005')
|
|
293
|
+
await wrapper.vm.$nextTick()
|
|
294
|
+
await flushPromises()
|
|
295
|
+
|
|
296
|
+
// Vérifier que le focus a été appelé au moins une fois
|
|
297
|
+
// (la méthode focusField est appelée et met le focus sur le champ clé)
|
|
298
|
+
expect(focusSpy).toHaveBeenCalled()
|
|
299
|
+
|
|
300
|
+
// Restaurer le spy
|
|
301
|
+
focusSpy.mockRestore()
|
|
302
|
+
})
|
|
222
303
|
})
|
|
@@ -160,9 +160,9 @@ Default.parameters = {
|
|
|
160
160
|
code: `
|
|
161
161
|
<script setup lang="ts">
|
|
162
162
|
import { VBtn } from 'vuetify/components'
|
|
163
|
-
|
|
163
|
+
import { NotificationBar } from '@cnamts/synapse'
|
|
164
164
|
import { ref } from 'vue'
|
|
165
|
-
|
|
165
|
+
import { useNotificationService } from '@cnamts/synpase'
|
|
166
166
|
|
|
167
167
|
const { addNotification } = useNotificationService()
|
|
168
168
|
const showNotification = ref(false)
|
|
@@ -527,3 +527,129 @@ Customization.parameters = {
|
|
|
527
527
|
},
|
|
528
528
|
],
|
|
529
529
|
}
|
|
530
|
+
|
|
531
|
+
export const WithClearQueue: Story = (args) => {
|
|
532
|
+
return {
|
|
533
|
+
components: { NotificationBar, VBtn },
|
|
534
|
+
setup() {
|
|
535
|
+
const { addNotification, clearQueue } = useNotificationService()
|
|
536
|
+
const { closeBtnText, bottom, rounded } = toRefs(args)
|
|
537
|
+
|
|
538
|
+
// Fonction pour ajouter une notification avec un type spécifique
|
|
539
|
+
const envoyerNotification = (message: string, type: Notification['type'] = 'info') => {
|
|
540
|
+
const notification: Notification = {
|
|
541
|
+
id: Date.now().toString(),
|
|
542
|
+
message,
|
|
543
|
+
type,
|
|
544
|
+
timeout: -1,
|
|
545
|
+
}
|
|
546
|
+
addNotification(notification)
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
return {
|
|
550
|
+
closeBtnText,
|
|
551
|
+
bottom,
|
|
552
|
+
rounded,
|
|
553
|
+
envoyerNotification,
|
|
554
|
+
clearQueue,
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
template: `
|
|
558
|
+
<div class="d-flex flex-column align-center justify-center gap-4">
|
|
559
|
+
<NotificationBar
|
|
560
|
+
:close-btn-text="closeBtnText"
|
|
561
|
+
:bottom="true"
|
|
562
|
+
:rounded="rounded"
|
|
563
|
+
/>
|
|
564
|
+
<div class="d-flex flex-wrap justify-center gap-4">
|
|
565
|
+
<VBtn
|
|
566
|
+
color="primary"
|
|
567
|
+
@click="envoyerNotification('Notification info', 'info')"
|
|
568
|
+
>
|
|
569
|
+
Ajouter info
|
|
570
|
+
</VBtn>
|
|
571
|
+
<VBtn
|
|
572
|
+
color="success"
|
|
573
|
+
@click="envoyerNotification('Notification succès', 'success')"
|
|
574
|
+
>
|
|
575
|
+
Ajouter succès
|
|
576
|
+
</VBtn>
|
|
577
|
+
<VBtn
|
|
578
|
+
color="warning"
|
|
579
|
+
@click="envoyerNotification('Notification avertissement', 'warning')"
|
|
580
|
+
>
|
|
581
|
+
Ajouter avertissement
|
|
582
|
+
</VBtn>
|
|
583
|
+
<VBtn
|
|
584
|
+
color="error"
|
|
585
|
+
@click="envoyerNotification('Notification erreur', 'error')"
|
|
586
|
+
>
|
|
587
|
+
Ajouter erreur
|
|
588
|
+
</VBtn>
|
|
589
|
+
<VBtn
|
|
590
|
+
color="grey-darken-1"
|
|
591
|
+
@click="clearQueue()"
|
|
592
|
+
>
|
|
593
|
+
Fermer toutes les notifications
|
|
594
|
+
</VBtn>
|
|
595
|
+
</div>
|
|
596
|
+
</div>
|
|
597
|
+
`,
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
WithClearQueue.args = {
|
|
602
|
+
...Default.args,
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
WithClearQueue.parameters = {
|
|
606
|
+
sourceCode: [
|
|
607
|
+
{
|
|
608
|
+
name: 'Template',
|
|
609
|
+
code: `
|
|
610
|
+
<div class="d-flex flex-column align-center justify-center gap-4">
|
|
611
|
+
<NotificationBar
|
|
612
|
+
:close-btn-text="closeBtnText"
|
|
613
|
+
:bottom="true"
|
|
614
|
+
:rounded="rounded"
|
|
615
|
+
/>
|
|
616
|
+
<div class="d-flex flex-wrap justify-center gap-4">
|
|
617
|
+
<!-- Boutons pour ajouter des notifications -->
|
|
618
|
+
<VBtn
|
|
619
|
+
color="primary"
|
|
620
|
+
@click="envoyerNotification('Notification info', 'info')"
|
|
621
|
+
>
|
|
622
|
+
Ajouter info
|
|
623
|
+
</VBtn>
|
|
624
|
+
<!-- ... autres boutons ... -->
|
|
625
|
+
<VBtn
|
|
626
|
+
color="grey-darken-1"
|
|
627
|
+
@click="clearQueue()"
|
|
628
|
+
>
|
|
629
|
+
Fermer toutes les notifications
|
|
630
|
+
</VBtn>
|
|
631
|
+
</div>
|
|
632
|
+
</div>
|
|
633
|
+
`,
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
name: 'Script',
|
|
637
|
+
code: `
|
|
638
|
+
<script setup lang="ts">
|
|
639
|
+
|
|
640
|
+
const { addNotification, clearQueue } = useNotificationService()
|
|
641
|
+
|
|
642
|
+
const envoyerNotification = (message: string, type = 'info') => {
|
|
643
|
+
const notification = {
|
|
644
|
+
id: Date.now().toString(),
|
|
645
|
+
message,
|
|
646
|
+
type,
|
|
647
|
+
timeout: -1,
|
|
648
|
+
}
|
|
649
|
+
addNotification(notification)
|
|
650
|
+
}
|
|
651
|
+
</script>
|
|
652
|
+
`,
|
|
653
|
+
},
|
|
654
|
+
],
|
|
655
|
+
}
|