@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
|
@@ -2,6 +2,46 @@ import type { Meta, StoryObj } from '@storybook/vue3'
|
|
|
2
2
|
import SyServerTable from './SyServerTable.vue'
|
|
3
3
|
import { ref } from 'vue'
|
|
4
4
|
import type { VDataTable } from 'vuetify/components'
|
|
5
|
+
import dayjs from 'dayjs'
|
|
6
|
+
|
|
7
|
+
interface TextItem {
|
|
8
|
+
example: string
|
|
9
|
+
description: string
|
|
10
|
+
[key: string]: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface NumberItem {
|
|
14
|
+
example: number
|
|
15
|
+
description: string
|
|
16
|
+
[key: string]: string | number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface SelectItem {
|
|
20
|
+
category: string
|
|
21
|
+
description: string
|
|
22
|
+
[key: string]: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface DateItem {
|
|
26
|
+
date: string
|
|
27
|
+
description: string
|
|
28
|
+
[key: string]: string
|
|
29
|
+
}
|
|
30
|
+
enum StateEnum {
|
|
31
|
+
IDLE = 'idle',
|
|
32
|
+
PENDING = 'pending',
|
|
33
|
+
RESOLVED = 'resolved',
|
|
34
|
+
REJECTED = 'rejected',
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface DataOptions {
|
|
38
|
+
sortBy?: Array<{ key: string, order: string }>
|
|
39
|
+
page?: number
|
|
40
|
+
itemsPerPage?: number
|
|
41
|
+
groupBy?: Array<string>
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
+
filters?: Array<{ key: string, value: any, type: string }>
|
|
44
|
+
}
|
|
5
45
|
|
|
6
46
|
const meta = {
|
|
7
47
|
title: 'Composants/Tableaux/SyServerTable/Rules',
|
|
@@ -21,10 +61,10 @@ export default meta
|
|
|
21
61
|
|
|
22
62
|
type Story = StoryObj<typeof meta>
|
|
23
63
|
|
|
24
|
-
export const
|
|
64
|
+
export const TextFilterRules: Story = {
|
|
25
65
|
args: {
|
|
26
|
-
serverItemsLength:
|
|
27
|
-
suffix: '
|
|
66
|
+
serverItemsLength: 9,
|
|
67
|
+
suffix: 'text-filter-rules',
|
|
28
68
|
showFilters: true,
|
|
29
69
|
},
|
|
30
70
|
parameters: {
|
|
@@ -42,26 +82,64 @@ export const FilterRules: Story = {
|
|
|
42
82
|
{ title: 'Description', key: 'description', filterable: false },
|
|
43
83
|
])
|
|
44
84
|
|
|
45
|
-
const
|
|
46
|
-
{ example: '
|
|
47
|
-
{ example: '*', description: '
|
|
48
|
-
{ example: '
|
|
49
|
-
{ example: '
|
|
50
|
-
{ example: '
|
|
51
|
-
{ example: '=????', description: 'Tous les mots de 4 lettres exactement' },
|
|
52
|
-
{ example: '<>?*', description: 'Toutes les valeurs vides ou nulles' },
|
|
53
|
-
{ example: '>
|
|
54
|
-
|
|
85
|
+
const demoItems = [
|
|
86
|
+
{ example: 'Paris', description: 'Recherche simple (insensible à la casse) - trouve "Paris", "paris", etc.' },
|
|
87
|
+
{ example: 'p*', description: 'Tous les mots commençant par "p" - trouve "Paris", "pomme", "Portugal", etc.' },
|
|
88
|
+
{ example: '*is', description: 'Tous les mots finissant par "is" - trouve "Paris", "tennis", etc.' },
|
|
89
|
+
{ example: 'p?r?s', description: 'Remplace chaque ? par un caractère - trouve "Paris", "parus", etc.' },
|
|
90
|
+
{ example: '"Paris"', description: 'Recherche sensible à la casse - trouve "Paris" mais pas "paris"' },
|
|
91
|
+
{ example: '=????', description: 'Tous les mots de 4 lettres exactement - trouve "Lyon", "Nice", etc.' },
|
|
92
|
+
{ example: '<>?*', description: 'Toutes les valeurs vides ou nulles - trouve les cellules vides' },
|
|
93
|
+
{ example: '>m', description: 'Tous les mots classés après "m" - trouve "Nice", "Paris", "Rome", etc.' },
|
|
94
|
+
{ example: '*a*i*', description: 'Combinaison de wildcards - trouve "Paris", "Madrid", etc.' },
|
|
95
|
+
]
|
|
55
96
|
|
|
97
|
+
const items = ref<TextItem[]>([])
|
|
98
|
+
const totalItems = ref(0)
|
|
99
|
+
const state = ref(StateEnum.IDLE)
|
|
56
100
|
const options = ref({
|
|
57
101
|
itemsPerPage: 10,
|
|
102
|
+
page: 1,
|
|
58
103
|
})
|
|
59
104
|
|
|
105
|
+
const wait = async (ms: number): Promise<void> => {
|
|
106
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const fetchData = async (newOptions?: DataOptions): Promise<void> => {
|
|
110
|
+
state.value = StateEnum.PENDING
|
|
111
|
+
await wait(1000)
|
|
112
|
+
|
|
113
|
+
// Filtrer les éléments selon les filtres
|
|
114
|
+
let filteredItems = [...demoItems]
|
|
115
|
+
if (newOptions?.filters && newOptions.filters.length > 0) {
|
|
116
|
+
newOptions.filters.forEach((filter) => {
|
|
117
|
+
if (filter.value !== null && filter.value !== undefined) {
|
|
118
|
+
const filterValue = String(filter.value).toLowerCase()
|
|
119
|
+
filteredItems = filteredItems.filter((item) => {
|
|
120
|
+
const itemValue = String(item[filter.key]).toLowerCase()
|
|
121
|
+
return itemValue.includes(filterValue)
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
totalItems.value = filteredItems.length
|
|
128
|
+
items.value = filteredItems
|
|
129
|
+
state.value = StateEnum.RESOLVED
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Charger les données initiales
|
|
133
|
+
fetchData()
|
|
134
|
+
|
|
60
135
|
return {
|
|
61
136
|
headers,
|
|
62
137
|
items,
|
|
63
138
|
options,
|
|
64
|
-
|
|
139
|
+
state,
|
|
140
|
+
StateEnum,
|
|
141
|
+
fetchData,
|
|
142
|
+
serverItemsLength: totalItems,
|
|
65
143
|
}
|
|
66
144
|
},
|
|
67
145
|
template: `
|
|
@@ -69,13 +147,552 @@ export const FilterRules: Story = {
|
|
|
69
147
|
<h2>Règles de filtrage textuel</h2>
|
|
70
148
|
<p class="mb-4">Le filtre textuel s'applique à une colonne de texte. Pour éviter qu'il ne soit lancé à chaque caractère saisi, il n'est déclenché qu'après un laps de temps de 300ms (par défaut) sans saisie.</p>
|
|
71
149
|
|
|
150
|
+
<h3 class="mb-2">Opérateurs et caractères spéciaux supportés</h3>
|
|
151
|
+
<p class="mb-4">Le filtre textuel prend en charge les caractères spéciaux suivants :</p>
|
|
152
|
+
|
|
153
|
+
<div class="mb-4">
|
|
154
|
+
<table class="mb-4" style="width: auto; border-collapse: collapse;">
|
|
155
|
+
<thead>
|
|
156
|
+
<tr>
|
|
157
|
+
<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Caractère</th>
|
|
158
|
+
<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Description</th>
|
|
159
|
+
<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Exemple</th>
|
|
160
|
+
</tr>
|
|
161
|
+
</thead>
|
|
162
|
+
<tbody>
|
|
163
|
+
<tr>
|
|
164
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>*</code></td>
|
|
165
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Remplace n'importe quelle séquence de caractères (y compris aucun)</td>
|
|
166
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>p*s</code> (trouve "paris", "pains", "pas", etc.)</td>
|
|
167
|
+
</tr>
|
|
168
|
+
<tr>
|
|
169
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>?</code></td>
|
|
170
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Remplace exactement un caractère</td>
|
|
171
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>p?ris</code> (trouve "paris", "pâris", etc.)</td>
|
|
172
|
+
</tr>
|
|
173
|
+
<tr>
|
|
174
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>"..."</code></td>
|
|
175
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Recherche sensible à la casse</td>
|
|
176
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>"Paris"</code> (trouve "Paris" mais pas "paris")</td>
|
|
177
|
+
</tr>
|
|
178
|
+
<tr>
|
|
179
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>=</code></td>
|
|
180
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Recherche de longueur exacte</td>
|
|
181
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>=????</code> (trouve tous les mots de 4 lettres)</td>
|
|
182
|
+
</tr>
|
|
183
|
+
<tr>
|
|
184
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code><></code></td>
|
|
185
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Recherche de valeurs vides ou nulles</td>
|
|
186
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code><>?*</code> (trouve les cellules vides)</td>
|
|
187
|
+
</tr>
|
|
188
|
+
<tr>
|
|
189
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>></code></td>
|
|
190
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Supérieur à (ordre alphabétique)</td>
|
|
191
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>>m</code> (trouve les mots après "m" dans l'alphabet)</td>
|
|
192
|
+
</tr>
|
|
193
|
+
<tr>
|
|
194
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code><</code></td>
|
|
195
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Inférieur à (ordre alphabétique)</td>
|
|
196
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code><m</code> (trouve les mots avant "m" dans l'alphabet)</td>
|
|
197
|
+
</tr>
|
|
198
|
+
</tbody>
|
|
199
|
+
</table>
|
|
200
|
+
<p>Sans opérateur spécial, le filtre effectue une recherche insensible à la casse.</p>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<SyServerTable
|
|
204
|
+
v-model:options="options"
|
|
205
|
+
:headers="headers"
|
|
206
|
+
:items="items"
|
|
207
|
+
:server-items-length="serverItemsLength"
|
|
208
|
+
:loading="state === StateEnum.PENDING"
|
|
209
|
+
suffix="text-filter-rules-doc"
|
|
210
|
+
show-filters
|
|
211
|
+
@update:options="fetchData"
|
|
212
|
+
/>
|
|
213
|
+
</div>
|
|
214
|
+
`,
|
|
215
|
+
}),
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export const NumberFilterRules: Story = {
|
|
219
|
+
args: {
|
|
220
|
+
serverItemsLength: 8,
|
|
221
|
+
suffix: 'number-filter-rules',
|
|
222
|
+
showFilters: true,
|
|
223
|
+
},
|
|
224
|
+
parameters: {
|
|
225
|
+
docs: {
|
|
226
|
+
description: {
|
|
227
|
+
story: 'Documentation des règles de filtrage numérique pour le composant SyServerTable.',
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
render: () => ({
|
|
232
|
+
components: { SyServerTable },
|
|
233
|
+
setup() {
|
|
234
|
+
const headers = ref([
|
|
235
|
+
{ title: 'Exemple', key: 'example', filterable: true, filterType: 'number' },
|
|
236
|
+
{ title: 'Description', key: 'description', filterable: false },
|
|
237
|
+
])
|
|
238
|
+
|
|
239
|
+
const demoItems = [
|
|
240
|
+
{ example: 42, description: 'Recherche exacte (42)' },
|
|
241
|
+
{ example: 10, description: 'Recherche exacte (10)' },
|
|
242
|
+
{ example: 25, description: 'Recherche exacte (25)' },
|
|
243
|
+
{ example: 100, description: 'Recherche exacte (100)' },
|
|
244
|
+
{ example: 75, description: 'Recherche exacte (75)' },
|
|
245
|
+
{ example: 50, description: 'Recherche exacte (50)' },
|
|
246
|
+
{ example: 30, description: 'Recherche exacte (30)' },
|
|
247
|
+
{ example: 90, description: 'Recherche exacte (90)' },
|
|
248
|
+
]
|
|
249
|
+
|
|
250
|
+
const items = ref<NumberItem[]>([])
|
|
251
|
+
const totalItems = ref(0)
|
|
252
|
+
const state = ref(StateEnum.IDLE)
|
|
253
|
+
const options = ref({
|
|
254
|
+
itemsPerPage: 10,
|
|
255
|
+
page: 1,
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
const wait = async (ms: number): Promise<void> => {
|
|
259
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const fetchData = async (newOptions?: DataOptions): Promise<void> => {
|
|
263
|
+
state.value = StateEnum.PENDING
|
|
264
|
+
await wait(1000)
|
|
265
|
+
|
|
266
|
+
// Filtrer les éléments selon les filtres
|
|
267
|
+
let filteredItems = [...demoItems]
|
|
268
|
+
if (newOptions?.filters && newOptions.filters.length > 0) {
|
|
269
|
+
newOptions.filters.forEach((filter) => {
|
|
270
|
+
if (filter.value !== null && filter.value !== undefined) {
|
|
271
|
+
const filterValue = String(filter.value).toLowerCase()
|
|
272
|
+
filteredItems = filteredItems.filter((item) => {
|
|
273
|
+
const itemValue = String(item[filter.key])
|
|
274
|
+
return itemValue.includes(filterValue)
|
|
275
|
+
})
|
|
276
|
+
}
|
|
277
|
+
})
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
totalItems.value = filteredItems.length
|
|
281
|
+
items.value = filteredItems
|
|
282
|
+
state.value = StateEnum.RESOLVED
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Charger les données initiales
|
|
286
|
+
fetchData()
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
headers,
|
|
290
|
+
items,
|
|
291
|
+
options,
|
|
292
|
+
state,
|
|
293
|
+
StateEnum,
|
|
294
|
+
fetchData,
|
|
295
|
+
serverItemsLength: totalItems,
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
template: `
|
|
299
|
+
<div>
|
|
300
|
+
<h2>Règles de filtrage numérique</h2>
|
|
301
|
+
<p class="mb-4">Le filtre numérique s'applique à une colonne de nombres. Pour éviter qu'il ne soit lancé à chaque caractère saisi, il n'est déclenché qu'après un laps de temps de 300ms (par défaut) sans saisie.</p>
|
|
302
|
+
|
|
303
|
+
<h3 class="mb-2">Opérateurs supportés</h3>
|
|
304
|
+
<p class="mb-4">Le filtre numérique prend en charge les opérateurs suivants lorsqu'ils sont placés au début de la valeur :</p>
|
|
305
|
+
|
|
306
|
+
<div class="mb-4">
|
|
307
|
+
<table class="mb-4" style="width: auto; border-collapse: collapse;">
|
|
308
|
+
<thead>
|
|
309
|
+
<tr>
|
|
310
|
+
<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Opérateur</th>
|
|
311
|
+
<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Description</th>
|
|
312
|
+
<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Exemple</th>
|
|
313
|
+
</tr>
|
|
314
|
+
</thead>
|
|
315
|
+
<tbody>
|
|
316
|
+
<tr>
|
|
317
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>=</code></td>
|
|
318
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Égal à</td>
|
|
319
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>=42</code> (égal à 42)</td>
|
|
320
|
+
</tr>
|
|
321
|
+
<tr>
|
|
322
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code><></code></td>
|
|
323
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Différent de</td>
|
|
324
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code><>42</code> (différent de 42)</td>
|
|
325
|
+
</tr>
|
|
326
|
+
<tr>
|
|
327
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code><</code></td>
|
|
328
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Inférieur à</td>
|
|
329
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code><42</code> (inférieur à 42)</td>
|
|
330
|
+
</tr>
|
|
331
|
+
<tr>
|
|
332
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code><=</code></td>
|
|
333
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Inférieur ou égal à</td>
|
|
334
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code><=42</code> (inférieur ou égal à 42)</td>
|
|
335
|
+
</tr>
|
|
336
|
+
<tr>
|
|
337
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>></code></td>
|
|
338
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Supérieur à</td>
|
|
339
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>>42</code> (supérieur à 42)</td>
|
|
340
|
+
</tr>
|
|
341
|
+
<tr>
|
|
342
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>>=</code></td>
|
|
343
|
+
<td style="border: 1px solid #ddd; padding: 8px;">Supérieur ou égal à</td>
|
|
344
|
+
<td style="border: 1px solid #ddd; padding: 8px;"><code>>=42</code> (supérieur ou égal à 42)</td>
|
|
345
|
+
</tr>
|
|
346
|
+
</tbody>
|
|
347
|
+
</table>
|
|
348
|
+
<p>Sans opérateur, le filtre effectue une recherche d'égalité exacte.</p>
|
|
349
|
+
</div>
|
|
350
|
+
|
|
351
|
+
<SyServerTable
|
|
352
|
+
v-model:options="options"
|
|
353
|
+
:headers="headers"
|
|
354
|
+
:items="items"
|
|
355
|
+
:server-items-length="serverItemsLength"
|
|
356
|
+
:loading="state === StateEnum.PENDING"
|
|
357
|
+
suffix="number-filter-rules-doc"
|
|
358
|
+
show-filters
|
|
359
|
+
@update:options="fetchData"
|
|
360
|
+
/>
|
|
361
|
+
</div>
|
|
362
|
+
`,
|
|
363
|
+
}),
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export const SelectFilterRules: Story = {
|
|
367
|
+
args: {
|
|
368
|
+
serverItemsLength: 5,
|
|
369
|
+
suffix: 'select-filter-rules',
|
|
370
|
+
showFilters: true,
|
|
371
|
+
},
|
|
372
|
+
parameters: {
|
|
373
|
+
docs: {
|
|
374
|
+
description: {
|
|
375
|
+
story: 'Documentation des règles de filtrage par sélection pour le composant SyServerTable.',
|
|
376
|
+
},
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
render: () => ({
|
|
380
|
+
components: { SyServerTable },
|
|
381
|
+
setup() {
|
|
382
|
+
const headers = ref([
|
|
383
|
+
{
|
|
384
|
+
title: 'Catégorie',
|
|
385
|
+
key: 'category',
|
|
386
|
+
filterable: true,
|
|
387
|
+
filterType: 'select',
|
|
388
|
+
filterOptions: [
|
|
389
|
+
{ text: 'Fruits', value: 'Fruits' },
|
|
390
|
+
{ text: 'Légumes', value: 'Légumes' },
|
|
391
|
+
{ text: 'Boissons', value: 'Boissons' },
|
|
392
|
+
{ text: '(vide)', value: '' },
|
|
393
|
+
],
|
|
394
|
+
},
|
|
395
|
+
{ title: 'Description', key: 'description', filterable: false },
|
|
396
|
+
])
|
|
397
|
+
|
|
398
|
+
const demoItems = [
|
|
399
|
+
{ category: 'Fruits', description: 'Catégorie standard avec valeur non vide' },
|
|
400
|
+
{ category: 'Légumes', description: 'Catégorie standard avec valeur non vide' },
|
|
401
|
+
{ category: '', description: 'Catégorie avec valeur vide, affichée comme "(vide)" dans la liste' },
|
|
402
|
+
{ category: 'Fruits', description: 'Valeur dupliquée, apparaît une seule fois dans la liste' },
|
|
403
|
+
{ category: 'Boissons', description: 'Catégorie standard avec valeur non vide' },
|
|
404
|
+
]
|
|
405
|
+
|
|
406
|
+
const items = ref<SelectItem[]>([])
|
|
407
|
+
const totalItems = ref(0)
|
|
408
|
+
const state = ref(StateEnum.IDLE)
|
|
409
|
+
const options = ref({
|
|
410
|
+
itemsPerPage: 10,
|
|
411
|
+
page: 1,
|
|
412
|
+
})
|
|
413
|
+
|
|
414
|
+
const wait = async (ms: number): Promise<void> => {
|
|
415
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const fetchData = async (newOptions?: DataOptions): Promise<void> => {
|
|
419
|
+
state.value = StateEnum.PENDING
|
|
420
|
+
await wait(1000)
|
|
421
|
+
|
|
422
|
+
let filteredItems = [...demoItems]
|
|
423
|
+
const filters = newOptions?.filters || []
|
|
424
|
+
|
|
425
|
+
filters.forEach((filter) => {
|
|
426
|
+
if (filter.key === 'category') {
|
|
427
|
+
// Si la valeur est une chaîne vide, on filtre les lignes avec des valeurs vides
|
|
428
|
+
// Sinon, on filtre normalement par la valeur sélectionnée
|
|
429
|
+
filteredItems = filteredItems.filter((item) => {
|
|
430
|
+
// Gestion spéciale pour les valeurs vides
|
|
431
|
+
if (filter.value === '') {
|
|
432
|
+
return item[filter.key] === ''
|
|
433
|
+
}
|
|
434
|
+
// Pour les autres valeurs, filtre normal
|
|
435
|
+
else if (filter.value) {
|
|
436
|
+
return item[filter.key] === filter.value
|
|
437
|
+
}
|
|
438
|
+
// Si pas de valeur de filtre, on garde tout
|
|
439
|
+
return true
|
|
440
|
+
})
|
|
441
|
+
}
|
|
442
|
+
})
|
|
443
|
+
|
|
444
|
+
totalItems.value = filteredItems.length
|
|
445
|
+
items.value = filteredItems
|
|
446
|
+
state.value = StateEnum.RESOLVED
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Chargement initial des données
|
|
450
|
+
fetchData(options.value)
|
|
451
|
+
|
|
452
|
+
return {
|
|
453
|
+
headers,
|
|
454
|
+
items,
|
|
455
|
+
options,
|
|
456
|
+
state,
|
|
457
|
+
StateEnum,
|
|
458
|
+
serverItemsLength: totalItems,
|
|
459
|
+
fetchData,
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
template: `
|
|
463
|
+
<div>
|
|
464
|
+
<h2>Règles de filtrage par sélection</h2>
|
|
465
|
+
<p class="mb-4">Les filtres de sélection permettent de choisir parmi les valeurs uniques présentes dans la colonne.</p>
|
|
466
|
+
|
|
467
|
+
<div class="mb-4">
|
|
468
|
+
<p>Les filtres de choix sont des listes reprenant les éléments uniques présents dans l'ensemble des colonnes non filtrés. Pour faciliter l'accessibilité de la liste, le premier élément contient la valeur « - choisir - » pour indiquer qu'aucune ligne n'est filtré. Si l'une des cellules de la colonne est vide, l'élément de liste correspondant doit afficher la valeur « (vide) ».</p>
|
|
469
|
+
<p>L'action de filtrage est effectuée à la sélection d'une option de la liste de choix.</p>
|
|
470
|
+
</div>
|
|
471
|
+
|
|
72
472
|
<SyServerTable
|
|
73
473
|
v-model:options="options"
|
|
74
474
|
:headers="headers"
|
|
75
475
|
:items="items"
|
|
76
476
|
:server-items-length="serverItemsLength"
|
|
77
|
-
|
|
477
|
+
:loading="state === StateEnum.PENDING"
|
|
478
|
+
suffix="select-filter-rules-doc"
|
|
479
|
+
show-filters
|
|
480
|
+
@update:options="fetchData"
|
|
481
|
+
/>
|
|
482
|
+
</div>
|
|
483
|
+
`,
|
|
484
|
+
}),
|
|
485
|
+
}
|
|
486
|
+
export const DateFilterRules = {
|
|
487
|
+
args: {
|
|
488
|
+
serverItemsLength: 10,
|
|
489
|
+
suffix: 'date-filter-rules',
|
|
490
|
+
showFilters: true,
|
|
491
|
+
},
|
|
492
|
+
parameters: {
|
|
493
|
+
docs: {
|
|
494
|
+
description: {
|
|
495
|
+
story: 'Documentation des règles de filtrage par date pour le composant SyServerTable.',
|
|
496
|
+
},
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
render: () => ({
|
|
500
|
+
components: { SyServerTable },
|
|
501
|
+
setup() {
|
|
502
|
+
// Exemple 1: Filtrage par date seule
|
|
503
|
+
const headersSingleDate = ref([
|
|
504
|
+
{
|
|
505
|
+
title: 'Date',
|
|
506
|
+
key: 'date',
|
|
507
|
+
filterable: true,
|
|
508
|
+
filterType: 'date',
|
|
509
|
+
},
|
|
510
|
+
{ title: 'Description', key: 'description', filterable: false },
|
|
511
|
+
])
|
|
512
|
+
|
|
513
|
+
const demoItemsSingleDate = [
|
|
514
|
+
{ date: dayjs('2025-01-15').format('DD/MM/YYYY'), description: 'Date simple' },
|
|
515
|
+
{ date: dayjs('2025-02-20').format('DD/MM/YYYY'), description: 'Date simple' },
|
|
516
|
+
{ date: dayjs('2024-12-10').format('DD/MM/YYYY'), description: 'Date simple' },
|
|
517
|
+
{ date: dayjs('2025-05-05').format('DD/MM/YYYY'), description: 'Date simple' },
|
|
518
|
+
]
|
|
519
|
+
|
|
520
|
+
const itemsSingleDate = ref<DateItem[]>([])
|
|
521
|
+
const totalItemsSingleDate = ref(0)
|
|
522
|
+
const stateSingleDate = ref(StateEnum.IDLE)
|
|
523
|
+
const optionsSingleDate = ref({
|
|
524
|
+
itemsPerPage: 10,
|
|
525
|
+
page: 1,
|
|
526
|
+
})
|
|
527
|
+
|
|
528
|
+
// Exemple 2: Filtrage par période
|
|
529
|
+
const headersPeriod = ref([
|
|
530
|
+
{
|
|
531
|
+
title: 'Date',
|
|
532
|
+
key: 'date',
|
|
533
|
+
filterable: true,
|
|
534
|
+
filterType: 'period',
|
|
535
|
+
dateFormat: 'DD/MM/YYYY',
|
|
536
|
+
},
|
|
537
|
+
{ title: 'Description', key: 'description', filterable: false },
|
|
538
|
+
])
|
|
539
|
+
|
|
540
|
+
// Définir une période du 01/01/2025 au 31/03/2025 pour l'exemple
|
|
541
|
+
const periodStart = dayjs('2025-01-01').format('DD/MM/YYYY')
|
|
542
|
+
const periodEnd = dayjs('2025-03-31').format('DD/MM/YYYY')
|
|
543
|
+
|
|
544
|
+
const demoItemsPeriod = [
|
|
545
|
+
{ date: dayjs('2025-01-15').format('DD/MM/YYYY'), description: `Date incluse dans la période ${periodStart} - ${periodEnd}` },
|
|
546
|
+
{ date: dayjs('2025-02-20').format('DD/MM/YYYY'), description: `Date incluse dans la période ${periodStart} - ${periodEnd}` },
|
|
547
|
+
{ date: dayjs('2024-12-10').format('DD/MM/YYYY'), description: `Date avant la période ${periodStart} - ${periodEnd}` },
|
|
548
|
+
{ date: dayjs('2025-05-05').format('DD/MM/YYYY'), description: `Date après la période ${periodStart} - ${periodEnd}` },
|
|
549
|
+
{ date: dayjs('2025-01-01').format('DD/MM/YYYY'), description: `Date limite inférieure de la période (${periodStart})` },
|
|
550
|
+
{ date: dayjs('2025-03-31').format('DD/MM/YYYY'), description: `Date limite supérieure de la période (${periodEnd})` },
|
|
551
|
+
]
|
|
552
|
+
|
|
553
|
+
const itemsPeriod = ref<DateItem[]>([])
|
|
554
|
+
const totalItemsPeriod = ref(0)
|
|
555
|
+
const statePeriod = ref(StateEnum.IDLE)
|
|
556
|
+
const optionsPeriod = ref({
|
|
557
|
+
itemsPerPage: 10,
|
|
558
|
+
page: 1,
|
|
559
|
+
})
|
|
560
|
+
|
|
561
|
+
const wait = async (ms: number): Promise<void> => {
|
|
562
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// Fonction de filtrage pour l'exemple 1 (date simple)
|
|
566
|
+
const fetchDataSingleDate = async (newOptions?: DataOptions): Promise<void> => {
|
|
567
|
+
stateSingleDate.value = StateEnum.PENDING
|
|
568
|
+
await wait(1000)
|
|
569
|
+
|
|
570
|
+
// Filtrer les éléments selon les filtres
|
|
571
|
+
let filteredItems = [...demoItemsSingleDate]
|
|
572
|
+
if (newOptions?.filters && newOptions.filters.length > 0) {
|
|
573
|
+
newOptions.filters.forEach((filter) => {
|
|
574
|
+
if (filter.value !== null && filter.value !== undefined && filter.value !== '') {
|
|
575
|
+
const filterValue = String(filter.value).toLowerCase()
|
|
576
|
+
filteredItems = filteredItems.filter((item) => {
|
|
577
|
+
const itemValue = String(item[filter.key]).toLowerCase()
|
|
578
|
+
return itemValue === filterValue
|
|
579
|
+
})
|
|
580
|
+
}
|
|
581
|
+
})
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
totalItemsSingleDate.value = filteredItems.length
|
|
585
|
+
itemsSingleDate.value = filteredItems
|
|
586
|
+
stateSingleDate.value = StateEnum.RESOLVED
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// Fonction de filtrage pour l'exemple 2 (période)
|
|
590
|
+
const fetchDataPeriod = async (newOptions?: DataOptions): Promise<void> => {
|
|
591
|
+
statePeriod.value = StateEnum.PENDING
|
|
592
|
+
await wait(1000)
|
|
593
|
+
|
|
594
|
+
// Filtrer les éléments selon les filtres
|
|
595
|
+
let filteredItems = [...demoItemsPeriod]
|
|
596
|
+
if (newOptions?.filters && newOptions.filters.length > 0) {
|
|
597
|
+
newOptions.filters.forEach((filter) => {
|
|
598
|
+
if (filter.value !== null && filter.value !== undefined) {
|
|
599
|
+
// Pour le filtre de période, la valeur peut être un objet avec from et to
|
|
600
|
+
if (filter.type === 'period' && typeof filter.value === 'object') {
|
|
601
|
+
const { from, to } = filter.value
|
|
602
|
+
|
|
603
|
+
filteredItems = filteredItems.filter((item) => {
|
|
604
|
+
const itemDate = dayjs(item[filter.key], 'DD/MM/YYYY')
|
|
605
|
+
|
|
606
|
+
// Si from et to sont définis, vérifier si la date est dans l'intervalle
|
|
607
|
+
if (from && to) {
|
|
608
|
+
return itemDate.isAfter(dayjs(from, 'DD/MM/YYYY').subtract(1, 'day'))
|
|
609
|
+
&& itemDate.isBefore(dayjs(to, 'DD/MM/YYYY').add(1, 'day'))
|
|
610
|
+
}
|
|
611
|
+
// Si seulement from est défini, vérifier si la date est après from
|
|
612
|
+
else if (from) {
|
|
613
|
+
return itemDate.isAfter(dayjs(from, 'DD/MM/YYYY').subtract(1, 'day'))
|
|
614
|
+
}
|
|
615
|
+
// Si seulement to est défini, vérifier si la date est avant to
|
|
616
|
+
else if (to) {
|
|
617
|
+
return itemDate.isBefore(dayjs(to, 'DD/MM/YYYY').add(1, 'day'))
|
|
618
|
+
}
|
|
619
|
+
return true
|
|
620
|
+
})
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
const filterValue = String(filter.value).toLowerCase()
|
|
624
|
+
filteredItems = filteredItems.filter((item) => {
|
|
625
|
+
const itemValue = String(item[filter.key]).toLowerCase()
|
|
626
|
+
return itemValue === filterValue
|
|
627
|
+
})
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
})
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
totalItemsPeriod.value = filteredItems.length
|
|
634
|
+
itemsPeriod.value = filteredItems
|
|
635
|
+
statePeriod.value = StateEnum.RESOLVED
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Charger les données initiales
|
|
639
|
+
fetchDataSingleDate()
|
|
640
|
+
fetchDataPeriod()
|
|
641
|
+
|
|
642
|
+
return {
|
|
643
|
+
headersSingleDate,
|
|
644
|
+
itemsSingleDate,
|
|
645
|
+
optionsSingleDate,
|
|
646
|
+
stateSingleDate,
|
|
647
|
+
serverItemsLengthSingleDate: totalItemsSingleDate,
|
|
648
|
+
fetchDataSingleDate,
|
|
649
|
+
|
|
650
|
+
headersPeriod,
|
|
651
|
+
itemsPeriod,
|
|
652
|
+
optionsPeriod,
|
|
653
|
+
statePeriod,
|
|
654
|
+
serverItemsLengthPeriod: totalItemsPeriod,
|
|
655
|
+
fetchDataPeriod,
|
|
656
|
+
|
|
657
|
+
StateEnum,
|
|
658
|
+
}
|
|
659
|
+
},
|
|
660
|
+
template: `
|
|
661
|
+
<div>
|
|
662
|
+
<h2>Règles de filtrage par date</h2>
|
|
663
|
+
<p class="mb-4">Le filtre de date s'applique à une colonne de dates.</p>
|
|
664
|
+
|
|
665
|
+
<div class="mb-4">
|
|
666
|
+
<p>Le filtre de période comporte deux champs de saisies permettant de saisir une période du … au …</p>
|
|
667
|
+
<ul class="mb-4 pl-4">
|
|
668
|
+
<li>Le premier champ de saisie représente la date minimale recherchée (inclue). S'il n'est pas renseigné, il n'y a pas de limite minimale.</li>
|
|
669
|
+
<li>Le deuxième champ de saisie représente la date maximale recherchée (inclue). S'il n'est pas renseigné, il n'y a pas de limite maximale.</li>
|
|
670
|
+
</ul>
|
|
671
|
+
<p>L'action de filtrage est effectuée lorsque 10 caractères sont présents dans le champ de saisie actif.</p>
|
|
672
|
+
</div>
|
|
673
|
+
|
|
674
|
+
<h3 class="mb-3">Exemple 1: Filtrage par date seule</h3>
|
|
675
|
+
<SyServerTable
|
|
676
|
+
v-model:options="optionsSingleDate"
|
|
677
|
+
:headers="headersSingleDate"
|
|
678
|
+
:items="itemsSingleDate"
|
|
679
|
+
:server-items-length="serverItemsLengthSingleDate"
|
|
680
|
+
:loading="stateSingleDate === StateEnum.PENDING"
|
|
681
|
+
suffix="date-filter-single"
|
|
682
|
+
show-filters
|
|
683
|
+
@update:options="fetchDataSingleDate"
|
|
684
|
+
/>
|
|
685
|
+
|
|
686
|
+
<h3 class="mt-6 mb-3">Exemple 2: Filtrage par période</h3>
|
|
687
|
+
<SyServerTable
|
|
688
|
+
v-model:options="optionsPeriod"
|
|
689
|
+
:headers="headersPeriod"
|
|
690
|
+
:items="itemsPeriod"
|
|
691
|
+
:server-items-length="serverItemsLengthPeriod"
|
|
692
|
+
:loading="statePeriod === StateEnum.PENDING"
|
|
693
|
+
suffix="date-filter-period"
|
|
78
694
|
show-filters
|
|
695
|
+
@update:options="fetchDataPeriod"
|
|
79
696
|
/>
|
|
80
697
|
</div>
|
|
81
698
|
`,
|