@cnamts/synapse 1.0.1 → 1.0.2
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/README.md +1 -1
- package/dist/{DateFilter-BmRuzQ9Z.js → DateFilter-YWOTbfeL.js} +1 -1
- package/dist/{NumberFilter-CnIPDHqx.js → NumberFilter-DMmMgALM.js} +1 -1
- package/dist/{PeriodFilter-CZwZ8CnQ.js → PeriodFilter-Bok5BHcn.js} +1 -1
- package/dist/SelectFilter-BKud2WhN.js +136 -0
- package/dist/{TextFilter-DTxZHJwX.js → TextFilter-DvMf2thH.js} +1 -1
- package/dist/components/Accordion/Accordion.d.ts +2 -1
- package/dist/components/Accordion/composables/useAccordionGroupCommunication.d.ts +5 -0
- package/dist/components/Accordion/composables/useAccordionKeyboardNavigation.d.ts +12 -0
- package/dist/components/Accordion/composables/useAccordionState.d.ts +13 -0
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +85 -0
- package/dist/components/Customs/SyInputSelect/SyInputSelect.d.ts +2 -0
- package/dist/components/Customs/SySelect/SySelect.d.ts +33 -13
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +2 -2
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +1585 -1452
- package/dist/components/DatePicker/DatePicker/DatePicker.d.ts +16 -2
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +3 -1
- package/dist/components/DatePicker/composables/index.d.ts +2 -0
- package/dist/components/DatePicker/composables/useAsteriskDisplay.d.ts +14 -0
- package/dist/components/DatePicker/composables/useDateAutoClamp.d.ts +16 -0
- package/dist/components/DatePicker/composables/useDateRangeInput.d.ts +1 -1
- package/dist/components/DatePicker/composables/useDisplayedDateString.d.ts +3 -0
- package/dist/components/DatePicker/composables/useInputBlurHandler.d.ts +1 -0
- package/dist/components/DatePicker/composables/useMonthButtonCustomization.d.ts +5 -2
- package/dist/components/NirField/NirField.d.ts +7 -3
- package/dist/components/NirField/nirValidation.d.ts +1 -1
- package/dist/components/PasswordField/PasswordField.d.ts +2 -0
- package/dist/components/PeriodField/PeriodField.d.ts +52 -8
- package/dist/components/PhoneField/PhoneField.d.ts +2 -2
- package/dist/components/RangeField/RangeField.d.ts +2 -0
- package/dist/components/SearchListField/SearchListField.d.ts +9 -0
- package/dist/components/SyTextArea/SyTextArea.d.ts +2 -0
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +14 -9
- package/dist/components/Tables/SyTable/SyTable.d.ts +12 -7
- package/dist/components/Tables/common/SyTablePagination.d.ts +1636 -0
- package/dist/components/Tables/common/TableHeader.d.ts +2 -20
- package/dist/components/Tables/common/filters/SelectFilter.d.ts +5 -5
- package/dist/components/Tables/common/filters/getFilterComponent.d.ts +1 -0
- package/dist/components/Tables/common/filters/locales.d.ts +4 -0
- package/dist/components/Tables/common/filters/logics/date.d.ts +1 -0
- package/dist/components/Tables/common/filters/logics/number.d.ts +1 -0
- package/dist/components/Tables/common/filters/logics/period.d.ts +1 -0
- package/dist/components/Tables/common/filters/logics/select.d.ts +1 -0
- package/dist/components/Tables/common/filters/logics/text.d.ts +1 -0
- package/dist/components/Tables/common/locales.d.ts +21 -0
- package/dist/components/Tables/common/organizeColumns/OrganizeColumns.d.ts +267 -0
- package/dist/components/Tables/common/organizeColumns/sortHeaders.d.ts +2 -0
- package/dist/components/Tables/common/tableFilterUtils.d.ts +1 -0
- package/dist/components/Tables/common/tableStorageUtils.d.ts +41 -1
- package/dist/components/Tables/common/tableUtils.d.ts +42 -5
- package/dist/components/Tables/common/types.d.ts +19 -8
- package/dist/components/Tables/common/usePagination.d.ts +22 -0
- package/dist/components/Tables/common/useTableCheckbox.d.ts +20 -0
- package/dist/components/Tables/common/useTableHeaders.d.ts +76 -0
- package/dist/components/Tables/common/useTableItems.d.ts +24 -0
- package/dist/components/Tables/common/useTableOptions.d.ts +18 -0
- package/dist/components/ToolbarContainer/ToolbarContainer.d.ts +11 -0
- package/dist/components/UserMenuBtn/UserMenuBtn.d.ts +9 -2
- package/dist/components/index.d.ts +8 -6
- package/dist/design-system-v3.js +58 -56
- package/dist/design-system-v3.umd.cjs +22 -22
- package/dist/main-Cx8qG7YR.js +16344 -0
- package/dist/stories/Accessibilite/Vuetify/VuetifyItems.d.ts +14 -2
- package/dist/stories/DesignTokens/StylesTypographiques.stories.new.d.ts +8 -0
- package/dist/stories/DesignTokens/TypographyDisplay.d.ts +28 -0
- package/dist/stories/DesignTokens/vue-shims.d.ts +6 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/common/imgs/accessibility-svgrepo-com.svg +4 -0
- package/src/components/Accordion/Accessibilite/AccessibilityGuide.mdx +249 -0
- package/src/components/Accordion/Accordion.vue +48 -76
- package/src/components/Accordion/composables/__tests__/useAccordionGroupCommunication.spec.ts +146 -0
- package/src/components/Accordion/composables/__tests__/useAccordionKeyboardNavigation.spec.ts +209 -0
- package/src/components/Accordion/composables/__tests__/useAccordionState.spec.ts +144 -0
- package/src/components/Accordion/composables/useAccordionGroupCommunication.ts +52 -0
- package/src/components/Accordion/composables/useAccordionKeyboardNavigation.ts +111 -0
- package/src/components/Accordion/composables/useAccordionState.ts +59 -0
- package/src/components/Accordion/tests/__snapshots__/accordion.spec.ts.snap +3 -0
- package/src/components/Customs/SyCheckbox/Accessibilite.mdx +303 -0
- package/src/components/Customs/SyCheckbox/SyCheckbox.mdx +50 -0
- package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +630 -0
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +326 -0
- package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +201 -0
- package/src/components/Customs/SyInputSelect/SyInputSelect.stories.ts +1 -0
- package/src/components/Customs/SyInputSelect/SyInputSelect.vue +8 -1
- package/src/components/Customs/SySelect/SySelect.stories.ts +160 -0
- package/src/components/Customs/SySelect/SySelect.vue +291 -32
- package/src/components/Customs/SySelect/tests/SySelect.spec.ts +230 -0
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +3 -2
- package/src/components/Customs/SyTextField/SyTextField.vue +19 -8
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +241 -31
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +305 -57
- package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.events.spec.ts +161 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +4 -2
- package/src/components/DatePicker/DatePicker/DatePicker.stories.ts +259 -137
- package/src/components/DatePicker/DatePicker/DatePicker.vue +153 -25
- package/src/components/DatePicker/DatePicker/tests/DatePicker.events.spec.ts +189 -0
- package/src/components/DatePicker/DatePicker/{DatePicker.spec.ts → tests/DatePicker.spec.ts} +1 -15
- package/src/components/DatePicker/DateTextInput/DateRange.stories.ts +24 -14
- package/src/components/DatePicker/DateTextInput/DateTextInput.events.spec.ts +148 -0
- package/src/components/DatePicker/DateTextInput/DateTextInput.spec.ts +3 -1
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +200 -5
- package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +241 -31
- package/src/components/DatePicker/composables/index.ts +2 -0
- package/src/components/DatePicker/composables/tests/useDateAutoClamp.spec.ts +190 -0
- package/src/components/DatePicker/composables/tests/useInputBlurHandler.spec.ts +182 -4
- package/src/components/DatePicker/composables/tests/useMonthButtonCustomization.spec.ts +105 -80
- package/src/components/DatePicker/composables/useAsteriskDisplay.ts +31 -0
- package/src/components/DatePicker/composables/useDateAutoClamp.ts +136 -0
- package/src/components/DatePicker/composables/useDateRangeInput.ts +21 -18
- package/src/components/DatePicker/composables/useDisplayedDateString.ts +13 -1
- package/src/components/DatePicker/composables/useInputBlurHandler.ts +84 -20
- package/src/components/DatePicker/composables/useMonthButtonCustomization.ts +149 -51
- package/src/components/DiacriticPicker/DiacriticPicker.stories.ts +10 -0
- package/src/components/ErrorPage/Accessibilite.stories.ts +8 -0
- package/src/components/ErrorPage/ErrorPage.vue +12 -6
- package/src/components/ErrorPage/tests/__snapshots__/ErrorPage.spec.ts.snap +4 -4
- package/src/components/NirField/NirField.mdx +22 -9
- package/src/components/NirField/NirField.stories.ts +26 -2
- package/src/components/NirField/NirField.vue +209 -22
- package/src/components/NirField/nirValidation.ts +17 -3
- package/src/components/NirField/tests/NirField.spec.ts +2 -2
- package/src/components/NotFoundPage/Accessibilite.stories.ts +8 -0
- package/src/components/NotFoundPage/NotFoundPage.vue +2 -1
- package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +8 -6
- package/src/components/PaginatedTable/PaginatedTable.mdx +2 -0
- package/src/components/PasswordField/PasswordField.stories.ts +4 -0
- package/src/components/PasswordField/PasswordField.vue +3 -0
- package/src/components/PeriodField/PeriodField.vue +2 -0
- package/src/components/PhoneField/PhoneField.stories.ts +15 -15
- package/src/components/PhoneField/PhoneField.vue +1 -1
- package/src/components/RangeField/RangeField.stories.ts +9 -0
- package/src/components/RangeField/RangeField.vue +4 -0
- package/src/components/RangeField/tests/__snapshots__/RangeField.spec.ts.snap +12 -0
- package/src/components/SearchListField/SearchListField.vue +5 -0
- package/src/components/SyTextArea/SyTextArea.vue +3 -0
- package/src/components/SyTextArea/tests/SyTextArea.spec.ts +0 -1
- package/src/components/Tables/SyServerTable/FilterRules.stories.ts +632 -15
- package/src/components/Tables/SyServerTable/SyServerTable.mdx +15 -5
- package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +2844 -1377
- package/src/components/Tables/SyServerTable/SyServerTable.vue +155 -66
- package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +256 -4
- package/src/components/Tables/SyTable/FilterRules.stories.ts +183 -0
- package/src/components/Tables/SyTable/SyTable.mdx +14 -4
- package/src/components/Tables/SyTable/SyTable.stories.ts +1265 -477
- package/src/components/Tables/SyTable/SyTable.vue +152 -72
- package/src/components/Tables/SyTable/tests/SyTable.spec.ts +366 -4
- package/src/components/Tables/common/SyTableFilter.vue +3 -56
- package/src/components/Tables/common/SyTablePagination.vue +375 -0
- package/src/components/Tables/common/TableHeader.vue +10 -26
- package/src/components/Tables/common/filters/SelectFilter.vue +131 -22
- package/src/components/Tables/common/filters/getFilterComponent.ts +54 -0
- package/src/components/Tables/common/filters/locales.ts +4 -0
- package/src/components/Tables/common/filters/logics/date.ts +12 -0
- package/src/components/Tables/common/filters/logics/number.ts +48 -0
- package/src/components/Tables/common/filters/logics/period.ts +25 -0
- package/src/components/Tables/common/filters/logics/select.ts +27 -0
- package/src/components/Tables/common/filters/logics/tests/TextFilterLogic.spec.ts +177 -0
- package/src/components/Tables/common/filters/logics/text.ts +62 -0
- package/src/components/Tables/common/filters/tests/TextFilter.spec.ts +11 -11
- package/src/components/Tables/common/locales.ts +24 -0
- package/src/components/Tables/common/organizeColumns/OrganizeColumns.vue +269 -0
- package/src/components/Tables/common/organizeColumns/sortHeaders.ts +9 -0
- package/src/components/Tables/common/tableFilterUtils.ts +43 -295
- package/src/components/Tables/common/tableStorageUtils.ts +27 -2
- package/src/components/Tables/common/tableStyles.scss +26 -0
- package/src/components/Tables/common/tableUtils.ts +3 -16
- package/src/components/Tables/common/tests/SyTablePagination.spec.ts +170 -0
- package/src/components/Tables/common/tests/filterByRange.spec.ts +215 -0
- package/src/components/Tables/common/tests/tableFilterUtils.spec.ts +0 -14
- package/src/components/Tables/common/tests/tableUtils.spec.ts +7 -51
- package/src/components/Tables/common/types.ts +17 -6
- package/src/components/Tables/common/usePagination.ts +83 -0
- package/src/components/Tables/common/useTableCheckbox.ts +58 -0
- package/src/components/Tables/common/useTableHeaders.ts +88 -0
- package/src/components/Tables/common/useTableItems.ts +87 -0
- package/src/components/Tables/common/useTableOptions.ts +93 -0
- package/src/components/ToolbarContainer/ToolbarContainer.mdx +16 -0
- package/src/components/ToolbarContainer/ToolbarContainer.stories.ts +675 -0
- package/src/components/ToolbarContainer/ToolbarContainer.vue +128 -0
- package/src/components/ToolbarContainer/tests/ToolbarContainer.spec.ts +156 -0
- package/src/components/UserMenuBtn/UserMenuBtn.stories.ts +74 -0
- package/src/components/UserMenuBtn/UserMenuBtn.vue +19 -17
- package/src/components/index.ts +8 -6
- package/src/stories/Accessibilite/Aculturation/AuditDesignSystem.mdx +293 -20
- package/src/stories/Accessibilite/Aculturation/SensibilisationAccessibilite.mdx +448 -54
- package/src/stories/Accessibilite/Audit/RGAA.mdx +231 -23
- package/src/stories/Accessibilite/Avancement/Avancement.mdx +591 -7
- package/src/stories/Accessibilite/Avancement/Avancement.stories.ts +139 -38
- package/src/stories/Accessibilite/Introduction.mdx +258 -18
- package/src/stories/Accessibilite/KitDePreAudit/Echantillonnage.mdx +221 -31
- package/src/stories/Accessibilite/KitDePreAudit/Introduction.mdx +204 -22
- package/src/stories/Accessibilite/KitDePreAudit/Outils/Introduction.mdx +537 -24
- package/src/stories/Accessibilite/KitDePreAudit/Outils/LecteursDEcran.mdx +577 -70
- package/src/stories/Accessibilite/KitDePreAudit/Outils/Tanaguru.mdx +382 -31
- package/src/stories/Accessibilite/KitDePreAudit/Preaudit.mdx +419 -81
- package/src/stories/Accessibilite/Vuetify/Vuetify.mdx +132 -6
- package/src/stories/Accessibilite/Vuetify/Vuetify.stories.ts +370 -146
- package/src/stories/Accessibilite/Vuetify/VuetifyItems.ts +35 -57
- package/src/stories/Demarrer/Accueil.stories.ts +20 -5
- package/src/stories/DesignTokens/StylesTypographiques.mdx +10 -9
- package/src/stories/DesignTokens/StylesTypographiques.stories.new.ts +397 -0
- package/src/stories/DesignTokens/StylesTypographiques.stories.ts +397 -0
- package/src/stories/DesignTokens/TypographyDisplay.vue +155 -0
- package/src/stories/DesignTokens/vue-shims.d.ts +6 -0
- package/src/stories/GuideDuDev/LesBreackingChanges.mdx +0 -2
- package/src/stories/GuideDuDev/MigrationDepuisBridge.mdx +1 -1
- package/src/stories/GuideDuDev/MigrationDepuisVue2.mdx +1 -1
- package/src/stories/GuideDuDev/PortailAgent.mdx +10 -0
- package/src/stories/GuideDuDev/PortailAgent.stories.ts +506 -0
- package/src/stories/GuideDuDev/Theme.mdx +41 -0
- package/dist/SelectFilter-Cj-GW2Cc.js +0 -97
- package/dist/main-WDqeoGM-.js +0 -14788
- package/src/components/PaginatedTable/tests/__snapshots__/PaginatedTable.spec.ts.snap +0 -886
- package/src/components/Tables/SyServerTable/tests/__snapshots__/SyServerTable.spec.ts.snap +0 -521
- package/src/components/Tables/SyTable/tests/__snapshots__/SyTable.spec.ts.snap +0 -521
- package/src/stories/DesignTokens/ThemePA.mdx +0 -35
|
@@ -25,13 +25,20 @@ export interface DataOptions {
|
|
|
25
25
|
|
|
26
26
|
export type DataTableHeaders = {
|
|
27
27
|
title?: string
|
|
28
|
+
text?: string
|
|
28
29
|
value?: string
|
|
29
30
|
key?: string
|
|
30
31
|
filterable?: boolean
|
|
31
32
|
filterType?: FilterType
|
|
32
33
|
filterOptions?: Array<{ text: string, value: unknown }>
|
|
34
|
+
multiple?: boolean
|
|
35
|
+
chips?: boolean
|
|
36
|
+
sortable?: boolean
|
|
33
37
|
hideMessages?: boolean
|
|
34
38
|
dateFormat?: string
|
|
39
|
+
align?: 'start' | 'end' | 'center'
|
|
40
|
+
order?: number
|
|
41
|
+
hidden?: boolean
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
// Type to handle both Vuetify internal headers and our custom headers
|
|
@@ -42,6 +49,8 @@ export type TableColumnHeader = {
|
|
|
42
49
|
filterable?: boolean
|
|
43
50
|
filterType?: FilterType
|
|
44
51
|
filterOptions?: Array<{ text: string, value: unknown }>
|
|
52
|
+
multiple?: boolean
|
|
53
|
+
chips?: boolean
|
|
45
54
|
hideMessages?: boolean
|
|
46
55
|
dateFormat?: string
|
|
47
56
|
sort?: unknown
|
|
@@ -53,29 +62,31 @@ export type TableColumnHeader = {
|
|
|
53
62
|
}
|
|
54
63
|
|
|
55
64
|
// Component-specific props interfaces
|
|
56
|
-
export
|
|
65
|
+
export type SyTableProps = {
|
|
57
66
|
items?: Record<string, unknown>[]
|
|
58
67
|
suffix: string
|
|
59
|
-
itemsPerPage?: number
|
|
60
68
|
caption?: string
|
|
61
69
|
showFilters?: boolean
|
|
62
|
-
headers?: DataTableHeaders[]
|
|
63
70
|
filterInputConfig?: Record<string, unknown>
|
|
64
71
|
density?: TableDensityType
|
|
65
72
|
striped?: boolean
|
|
66
73
|
resizableColumns?: boolean
|
|
74
|
+
enableColumnControls?: boolean
|
|
75
|
+
headers?: DataTableHeaders[]
|
|
76
|
+
showSelect?: boolean
|
|
67
77
|
}
|
|
68
78
|
|
|
69
|
-
export
|
|
79
|
+
export type SyServerTableProps = {
|
|
70
80
|
serverItemsLength: number
|
|
71
81
|
items?: Record<string, unknown>[]
|
|
72
82
|
suffix: string
|
|
73
|
-
itemsPerPage?: number
|
|
74
83
|
caption?: string
|
|
75
84
|
showFilters?: boolean
|
|
76
|
-
headers?: DataTableHeaders[]
|
|
77
85
|
resizableColumns?: boolean
|
|
78
86
|
filterInputConfig?: Record<string, unknown>
|
|
79
87
|
density?: TableDensityType
|
|
80
88
|
striped?: boolean
|
|
89
|
+
enableColumnControls?: boolean
|
|
90
|
+
headers?: DataTableHeaders[]
|
|
91
|
+
showSelect?: boolean
|
|
81
92
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { computed, nextTick, type Ref } from 'vue'
|
|
2
|
+
import type { DataOptions } from './types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Composable for managing table pagination
|
|
6
|
+
*
|
|
7
|
+
* @param options - Reactive reference to table options
|
|
8
|
+
* @param itemsLength - Total number of items (for client-side) or serverItemsLength (for server-side)
|
|
9
|
+
* @param table - Reference to the table component
|
|
10
|
+
* @param emit - Emit function for update:options event
|
|
11
|
+
* @returns Pagination utilities and computed properties
|
|
12
|
+
*/
|
|
13
|
+
export function usePagination({
|
|
14
|
+
options,
|
|
15
|
+
itemsLength,
|
|
16
|
+
table,
|
|
17
|
+
emit,
|
|
18
|
+
}: {
|
|
19
|
+
options: Ref<Partial<DataOptions>>
|
|
20
|
+
itemsLength: Ref<number>
|
|
21
|
+
table: Ref<unknown>
|
|
22
|
+
emit: (event: 'update:options', options: Partial<DataOptions>) => void
|
|
23
|
+
}) {
|
|
24
|
+
// Current page with getter/setter
|
|
25
|
+
const page = computed({
|
|
26
|
+
get: () => options.value.page || 1,
|
|
27
|
+
set: (newPage: number) => {
|
|
28
|
+
options.value = {
|
|
29
|
+
...options.value,
|
|
30
|
+
page: newPage,
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Items per page with fallback to default
|
|
36
|
+
const itemsPerPageValue = computed(() => {
|
|
37
|
+
const value = options.value.itemsPerPage || 10
|
|
38
|
+
// If value is -1, it means "Tous" (all items)
|
|
39
|
+
return value
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// Calculate total number of pages
|
|
43
|
+
const pageCount = computed(() => {
|
|
44
|
+
if (!itemsLength.value) return 0
|
|
45
|
+
// If itemsPerPageValue is -1 ("Tous"), return 1 page
|
|
46
|
+
if (itemsPerPageValue.value === -1) return 1
|
|
47
|
+
return Math.ceil(itemsLength.value / itemsPerPageValue.value)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Update items per page from pagination component
|
|
52
|
+
*/
|
|
53
|
+
function updateItemsPerPage(newItemsPerPage: number) {
|
|
54
|
+
// Create a completely new options object to force reactivity
|
|
55
|
+
const newOptions = {
|
|
56
|
+
...options.value,
|
|
57
|
+
itemsPerPage: newItemsPerPage,
|
|
58
|
+
page: 1, // Reset to first page when changing items per page
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Update options with the new object
|
|
62
|
+
options.value = newOptions
|
|
63
|
+
|
|
64
|
+
// Force a refresh of the table
|
|
65
|
+
nextTick(() => {
|
|
66
|
+
// Try to force update if the table has that method
|
|
67
|
+
const tableValue = table.value as { $forceUpdate?: () => void }
|
|
68
|
+
if (tableValue && typeof tableValue.$forceUpdate === 'function') {
|
|
69
|
+
tableValue.$forceUpdate()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Emit an event to notify parent components
|
|
73
|
+
emit('update:options', newOptions)
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
page,
|
|
79
|
+
pageCount,
|
|
80
|
+
itemsPerPageValue,
|
|
81
|
+
updateItemsPerPage,
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter } from 'vue'
|
|
2
|
+
import { toRef } from 'vue'
|
|
3
|
+
|
|
4
|
+
interface UseTableCheckboxOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The items to be displayed in the table
|
|
7
|
+
*/
|
|
8
|
+
items: MaybeRefOrGetter<Record<string, unknown>[]>
|
|
9
|
+
/**
|
|
10
|
+
* The model value for selected items
|
|
11
|
+
*/
|
|
12
|
+
modelValue: MaybeRefOrGetter<unknown[]>
|
|
13
|
+
/**
|
|
14
|
+
* Function to update the model value
|
|
15
|
+
*/
|
|
16
|
+
updateModelValue: (value: unknown[]) => void
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function useTableCheckbox(options: UseTableCheckboxOptions) {
|
|
20
|
+
const itemsRef = toRef(options.items)
|
|
21
|
+
const modelValueRef = toRef(options.modelValue)
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Function to get a unique identifier for each item
|
|
25
|
+
*/
|
|
26
|
+
const getItemValue = (item: Record<string, unknown>) => {
|
|
27
|
+
// If the item has an id field, use that
|
|
28
|
+
if (item.id !== undefined) {
|
|
29
|
+
return item.id
|
|
30
|
+
}
|
|
31
|
+
// Otherwise, create a unique string representation of the item
|
|
32
|
+
return JSON.stringify(item)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Function to toggle selection of all rows
|
|
37
|
+
*/
|
|
38
|
+
const toggleAllRows = () => {
|
|
39
|
+
// Ensure items is an array
|
|
40
|
+
const itemsArray = Array.isArray(itemsRef.value) ? itemsRef.value : []
|
|
41
|
+
const items = itemsArray.length > 0 ? itemsArray : []
|
|
42
|
+
|
|
43
|
+
if (modelValueRef.value.length === items.length) {
|
|
44
|
+
// If all items are selected, deselect all
|
|
45
|
+
options.updateModelValue([])
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Otherwise, select all items
|
|
49
|
+
// We need to map the items to their values to ensure proper selection
|
|
50
|
+
options.updateModelValue(items.map(item => getItemValue(item)))
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
getItemValue,
|
|
56
|
+
toggleAllRows,
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { computed, ref, watch, type Ref } from 'vue'
|
|
2
|
+
import type { DataTableHeaders, TableColumnHeader } from './types'
|
|
3
|
+
import { sortHeaders } from './organizeColumns/sortHeaders'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Composable for processing and enhancing table headers
|
|
7
|
+
*
|
|
8
|
+
* @param headersProp - Reference to headers from props
|
|
9
|
+
* @param filterInputConfig - Configuration for filter inputs
|
|
10
|
+
* @returns Header utilities and computed properties
|
|
11
|
+
*/
|
|
12
|
+
export function useTableHeaders({
|
|
13
|
+
headersProp,
|
|
14
|
+
filterInputConfig = {},
|
|
15
|
+
}: {
|
|
16
|
+
headersProp: Ref<DataTableHeaders[] | undefined>
|
|
17
|
+
filterInputConfig?: Record<string, unknown>
|
|
18
|
+
}) {
|
|
19
|
+
// Process headers to ensure they have title property
|
|
20
|
+
const normalizedHeaders = computed(() => {
|
|
21
|
+
if (!Array.isArray(headersProp?.value)) {
|
|
22
|
+
return undefined
|
|
23
|
+
}
|
|
24
|
+
return headersProp.value.map(header => ({
|
|
25
|
+
...header,
|
|
26
|
+
title: header.title ?? header.text,
|
|
27
|
+
}))
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
// Get filterable headers
|
|
31
|
+
const filterableHeaders = computed(() => {
|
|
32
|
+
if (!normalizedHeaders.value) return []
|
|
33
|
+
return normalizedHeaders.value.filter(header => header.filterable)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Enhance header with filter type and configuration
|
|
38
|
+
*/
|
|
39
|
+
function getEnhancedHeader(column: TableColumnHeader): TableColumnHeader {
|
|
40
|
+
// If column is not filterable, return as is
|
|
41
|
+
if (!column.filterable) return column
|
|
42
|
+
|
|
43
|
+
// Default filter type is 'text' if not specified
|
|
44
|
+
const filterType = column.filterType || 'text'
|
|
45
|
+
|
|
46
|
+
// Get column-specific filter config or empty object
|
|
47
|
+
const columnFilterConfig = column.key && filterInputConfig[column.key as string] ? filterInputConfig[column.key as string] : {}
|
|
48
|
+
|
|
49
|
+
// Return enhanced header with filter properties
|
|
50
|
+
return {
|
|
51
|
+
...(column as object),
|
|
52
|
+
filterType,
|
|
53
|
+
filterConfig: columnFilterConfig as Record<string, unknown>,
|
|
54
|
+
} as TableColumnHeader
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Mutable internal headers to manage state inside the component
|
|
58
|
+
const internalHeaders = ref<DataTableHeaders[] | undefined>([])
|
|
59
|
+
|
|
60
|
+
watch(normalizedHeaders, (newHeaders) => {
|
|
61
|
+
// Update internal headers when props.headers changes
|
|
62
|
+
internalHeaders.value = newHeaders
|
|
63
|
+
}, { immediate: true, deep: true })
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get header by key
|
|
67
|
+
*/
|
|
68
|
+
function getHeaderByKey(key: string): TableColumnHeader | undefined {
|
|
69
|
+
return normalizedHeaders.value?.find(header => header.key === key)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The headers filtered by visibility and sorted by order
|
|
74
|
+
*/
|
|
75
|
+
const displayHeaders = computed(() => {
|
|
76
|
+
if (!internalHeaders.value) return undefined
|
|
77
|
+
const filteredHeaders = internalHeaders.value.filter(header => header.hidden !== true)
|
|
78
|
+
return sortHeaders(filteredHeaders)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
headers: internalHeaders,
|
|
83
|
+
displayHeaders,
|
|
84
|
+
filterableHeaders,
|
|
85
|
+
getEnhancedHeader,
|
|
86
|
+
getHeaderByKey,
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { computed, type Ref } from 'vue'
|
|
2
|
+
import { processItems } from './formatters'
|
|
3
|
+
import type { DataOptions, FilterOption, TableColumnHeader } from './types'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Composable for handling table items processing
|
|
7
|
+
*
|
|
8
|
+
* @param items - Reference to table items
|
|
9
|
+
* @param headers - Reference to table headers
|
|
10
|
+
* @param filters - Reference to active filters
|
|
11
|
+
* @param options - Reference to table options
|
|
12
|
+
* @param filterItems - Function to filter items (from useTableFilter)
|
|
13
|
+
* @returns Item utilities and computed properties
|
|
14
|
+
*/
|
|
15
|
+
export function useTableItems({
|
|
16
|
+
items,
|
|
17
|
+
headers,
|
|
18
|
+
filters,
|
|
19
|
+
options,
|
|
20
|
+
filterItems,
|
|
21
|
+
}: {
|
|
22
|
+
items: Ref<Record<string, unknown>[]>
|
|
23
|
+
headers: Ref<TableColumnHeader[] | undefined>
|
|
24
|
+
filters: Ref<FilterOption[]>
|
|
25
|
+
options: Ref<Partial<DataOptions>>
|
|
26
|
+
filterItems: <T extends Record<string, unknown>>(items: T[], filters: FilterOption[]) => T[]
|
|
27
|
+
}) {
|
|
28
|
+
// Process items with formatters based on headers
|
|
29
|
+
const processedItems = computed(() => {
|
|
30
|
+
if (!headers.value) return items.value
|
|
31
|
+
// Just return the items as is since we can't process them with headers
|
|
32
|
+
return processItems(items.value)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Filter items based on active filters
|
|
36
|
+
const filteredItems = computed(() => {
|
|
37
|
+
// Create a deep copy of items to avoid modifying originals
|
|
38
|
+
const itemsCopy = processedItems.value.map((item) => {
|
|
39
|
+
return JSON.parse(JSON.stringify(item))
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// Apply filters to copied items
|
|
43
|
+
return filterItems(itemsCopy, filters.value)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// Apply pagination to filtered items
|
|
47
|
+
const paginatedItems = computed(() => {
|
|
48
|
+
if (!filteredItems.value.length) return []
|
|
49
|
+
|
|
50
|
+
const page = options.value.page || 1
|
|
51
|
+
const itemsPerPage = options.value.itemsPerPage || 10
|
|
52
|
+
|
|
53
|
+
// If itemsPerPage is -1 ("Tous"), return all items
|
|
54
|
+
if (itemsPerPage === -1) return filteredItems.value
|
|
55
|
+
|
|
56
|
+
const start = (page - 1) * itemsPerPage
|
|
57
|
+
const end = start + itemsPerPage
|
|
58
|
+
|
|
59
|
+
return filteredItems.value.slice(start, end)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Create an empty item that maintains the structure of columns
|
|
64
|
+
* Useful for displaying empty state with correct column structure
|
|
65
|
+
*/
|
|
66
|
+
function createEmptyItemWithStructure(): Record<string, unknown>[] {
|
|
67
|
+
if (!headers.value || !headers.value.length) return []
|
|
68
|
+
|
|
69
|
+
const emptyItem: Record<string, unknown> = {}
|
|
70
|
+
|
|
71
|
+
// Create an empty object with all header keys
|
|
72
|
+
headers.value.forEach((header) => {
|
|
73
|
+
if (header.key) {
|
|
74
|
+
emptyItem[header.key] = ''
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
return [emptyItem]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
processedItems,
|
|
83
|
+
filteredItems,
|
|
84
|
+
paginatedItems,
|
|
85
|
+
createEmptyItemWithStructure,
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { computed, type Ref } from 'vue'
|
|
2
|
+
import type { DataOptions, FilterOption } from './types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Composable for managing table options and filters
|
|
6
|
+
*
|
|
7
|
+
* @param options - Reactive reference to table options
|
|
8
|
+
* @returns Table options utilities and computed properties
|
|
9
|
+
*/
|
|
10
|
+
export function useTableOptions({
|
|
11
|
+
options,
|
|
12
|
+
}: {
|
|
13
|
+
options: Ref<Partial<DataOptions>>
|
|
14
|
+
}) {
|
|
15
|
+
// Computed for filters with getter/setter
|
|
16
|
+
const filters = computed({
|
|
17
|
+
get: () => options.value.filters || [],
|
|
18
|
+
set: (newFilters: FilterOption[]) => {
|
|
19
|
+
options.value = {
|
|
20
|
+
...options.value,
|
|
21
|
+
filters: newFilters,
|
|
22
|
+
page: 1, // reset
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
// Computed for sorting options
|
|
28
|
+
const sortBy = computed({
|
|
29
|
+
get: () => options.value.sortBy || [],
|
|
30
|
+
set: (newSortBy) => {
|
|
31
|
+
options.value = {
|
|
32
|
+
...options.value,
|
|
33
|
+
sortBy: newSortBy,
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Update options with new values
|
|
40
|
+
*/
|
|
41
|
+
function updateOptions(newOptions: Partial<DataOptions>) {
|
|
42
|
+
options.value = {
|
|
43
|
+
...options.value,
|
|
44
|
+
...newOptions,
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Reset filters to empty array
|
|
50
|
+
*/
|
|
51
|
+
function resetFilters() {
|
|
52
|
+
options.value = {
|
|
53
|
+
...options.value,
|
|
54
|
+
filters: [],
|
|
55
|
+
page: 1, // Reset to first page when clearing filters
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Update a specific filter or add it if it doesn't exist
|
|
61
|
+
*/
|
|
62
|
+
function updateFilter(filter: FilterOption) {
|
|
63
|
+
const currentFilters = [...filters.value]
|
|
64
|
+
const existingFilterIndex = currentFilters.findIndex(f => f.key === filter.key)
|
|
65
|
+
|
|
66
|
+
if (existingFilterIndex >= 0) {
|
|
67
|
+
// Update existing filter
|
|
68
|
+
currentFilters[existingFilterIndex] = filter
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Add new filter
|
|
72
|
+
currentFilters.push(filter)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
filters.value = currentFilters
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Remove a filter by key
|
|
80
|
+
*/
|
|
81
|
+
function removeFilter(key: string) {
|
|
82
|
+
filters.value = filters.value.filter(f => f.key !== key)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
filters,
|
|
87
|
+
sortBy,
|
|
88
|
+
updateOptions,
|
|
89
|
+
resetFilters,
|
|
90
|
+
updateFilter,
|
|
91
|
+
removeFilter,
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {Controls, Canvas, Meta, Source} from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
import * as ToolbarContainerStories from './ToolbarContainer.stories';
|
|
4
|
+
|
|
5
|
+
<Meta of={ToolbarContainerStories} />
|
|
6
|
+
|
|
7
|
+
# ToolbarContainer
|
|
8
|
+
|
|
9
|
+
Le composant `ToolbarContainer` est un conteneur pour les barres d'outils, il permet de regrouper plusieurs bouttons d'actions sous un simple action 'tab'. Les bouttons sont alors accessibles au clavier via l'usage des flèches directionnelles.
|
|
10
|
+
|
|
11
|
+
Ce composant intègre [le pattern `toolbar` tel que défini par le W3C](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/).
|
|
12
|
+
|
|
13
|
+
<Canvas of={ToolbarContainerStories.Default} />
|
|
14
|
+
# API
|
|
15
|
+
|
|
16
|
+
<Controls of={ToolbarContainerStories.Default} />
|