@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,9 +2,10 @@ import type { Meta, StoryObj } from '@storybook/vue3'
|
|
|
2
2
|
import SyServerTable from './SyServerTable.vue'
|
|
3
3
|
import { StateEnum } from '../common/constants/StateEnum'
|
|
4
4
|
import type { DataOptions, FilterType } from '../common/types'
|
|
5
|
-
import { ref } from 'vue'
|
|
5
|
+
import { ref, watch } from 'vue'
|
|
6
6
|
import type { VDataTable } from 'vuetify/components'
|
|
7
7
|
import dayjs from 'dayjs'
|
|
8
|
+
import { fn } from '@storybook/test'
|
|
8
9
|
|
|
9
10
|
interface User {
|
|
10
11
|
[key: string]: string
|
|
@@ -31,7 +32,7 @@ const meta = {
|
|
|
31
32
|
},
|
|
32
33
|
argTypes: {
|
|
33
34
|
headers: {
|
|
34
|
-
description: 'Liste des colonnes du tableau',
|
|
35
|
+
description: 'Liste des colonnes du tableau (voir : https://vuetifyjs.com/en/api/v-data-table/#props-headers)',
|
|
35
36
|
control: { type: 'object' },
|
|
36
37
|
table: {
|
|
37
38
|
category: 'props',
|
|
@@ -42,6 +43,9 @@ const meta = {
|
|
|
42
43
|
control: { type: 'object' },
|
|
43
44
|
table: {
|
|
44
45
|
category: 'props',
|
|
46
|
+
defaultValue: {
|
|
47
|
+
summary: '[]',
|
|
48
|
+
},
|
|
45
49
|
},
|
|
46
50
|
},
|
|
47
51
|
density: {
|
|
@@ -83,10 +87,6 @@ const meta = {
|
|
|
83
87
|
},
|
|
84
88
|
required: true,
|
|
85
89
|
},
|
|
86
|
-
itemsPerPage: {
|
|
87
|
-
description: 'Nombre d\'éléments par page',
|
|
88
|
-
control: { type: 'number' },
|
|
89
|
-
},
|
|
90
90
|
caption: {
|
|
91
91
|
description: 'Texte de la légende du tableau',
|
|
92
92
|
control: { type: 'text' },
|
|
@@ -94,6 +94,25 @@ const meta = {
|
|
|
94
94
|
resizableColumns: {
|
|
95
95
|
description: 'Permet de redimensionner les colonnes du tableau',
|
|
96
96
|
},
|
|
97
|
+
enableColumnControls: {
|
|
98
|
+
description: 'Allow the users to re-organize the columns',
|
|
99
|
+
table: {
|
|
100
|
+
defaultValue: {
|
|
101
|
+
summary: 'false',
|
|
102
|
+
},
|
|
103
|
+
type: { summary: 'boolean' },
|
|
104
|
+
category: 'props',
|
|
105
|
+
},
|
|
106
|
+
control: { type: 'boolean' },
|
|
107
|
+
},
|
|
108
|
+
showSelect: {
|
|
109
|
+
description: 'Affiche des cases à cocher pour sélectionner des lignes',
|
|
110
|
+
control: { type: 'boolean' },
|
|
111
|
+
table: {
|
|
112
|
+
category: 'props',
|
|
113
|
+
type: { summary: 'boolean' },
|
|
114
|
+
},
|
|
115
|
+
},
|
|
97
116
|
},
|
|
98
117
|
} satisfies Meta<typeof SyServerTable & typeof VDataTable>
|
|
99
118
|
|
|
@@ -167,7 +186,7 @@ export const Default: Story = {
|
|
|
167
186
|
return new Promise(resolve => setTimeout(resolve, ms))
|
|
168
187
|
}
|
|
169
188
|
|
|
170
|
-
const getDataFromApi = async ({ sortBy, page, itemsPerPage }: DataOptions): Promise<DataObj> => {
|
|
189
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
171
190
|
state.value = StateEnum.PENDING
|
|
172
191
|
await wait(1000)
|
|
173
192
|
|
|
@@ -212,27 +231,31 @@ export const Default: Story = {
|
|
|
212
231
|
{ firstname: 'Alexandre', lastname: 'Lazure', email: 'alexandre.lazure@example.com' },
|
|
213
232
|
]
|
|
214
233
|
}
|
|
234
|
+
|
|
235
|
+
// Initialize data
|
|
236
|
+
fetchData()
|
|
215
237
|
</script>
|
|
216
238
|
`,
|
|
217
239
|
},
|
|
218
240
|
],
|
|
219
241
|
},
|
|
220
242
|
args: {
|
|
221
|
-
options: {
|
|
243
|
+
'options': {
|
|
222
244
|
itemsPerPage: 5,
|
|
223
245
|
sortBy: [{ key: 'lastname', order: 'asc' }],
|
|
224
246
|
page: 1,
|
|
225
247
|
},
|
|
226
|
-
headers: [
|
|
248
|
+
'headers': [
|
|
227
249
|
{ title: 'Nom', key: 'lastname' },
|
|
228
250
|
{ title: 'Prénom', key: 'firstname' },
|
|
229
251
|
{ title: 'Email', key: 'email' },
|
|
230
252
|
],
|
|
231
|
-
caption: '',
|
|
232
|
-
serverItemsLength: 15,
|
|
233
|
-
suffix: 'server-default',
|
|
234
|
-
density: 'default',
|
|
235
|
-
striped: false,
|
|
253
|
+
'caption': '',
|
|
254
|
+
'serverItemsLength': 15,
|
|
255
|
+
'suffix': 'server-default',
|
|
256
|
+
'density': 'default',
|
|
257
|
+
'striped': false,
|
|
258
|
+
'onUpdate:options': fn(),
|
|
236
259
|
},
|
|
237
260
|
render: (args) => {
|
|
238
261
|
return {
|
|
@@ -242,9 +265,16 @@ export const Default: Story = {
|
|
|
242
265
|
const users = ref<User[]>([])
|
|
243
266
|
const state = ref(StateEnum.IDLE)
|
|
244
267
|
|
|
268
|
+
const options = ref({ ...args.options })
|
|
269
|
+
|
|
270
|
+
watch(options, (newVal) => {
|
|
271
|
+
if (args.options) {
|
|
272
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
273
|
+
}
|
|
274
|
+
}, { deep: true })
|
|
275
|
+
|
|
245
276
|
const fetchData = async (): Promise<void> => {
|
|
246
|
-
|
|
247
|
-
const { items, total } = await getDataFromApi(args.options)
|
|
277
|
+
const { items, total } = await getDataFromApi(options.value as DataOptions)
|
|
248
278
|
users.value = items
|
|
249
279
|
totalUsers.value = total
|
|
250
280
|
}
|
|
@@ -299,21 +329,19 @@ export const Default: Story = {
|
|
|
299
329
|
]
|
|
300
330
|
}
|
|
301
331
|
|
|
302
|
-
|
|
332
|
+
// Initialize data
|
|
333
|
+
fetchData()
|
|
334
|
+
|
|
335
|
+
return { args, users, state, fetchData, options, totalUsers, StateEnum }
|
|
303
336
|
},
|
|
304
337
|
template: `
|
|
305
338
|
<div>
|
|
306
339
|
<SyServerTable
|
|
307
|
-
v-model:options="
|
|
340
|
+
v-model:options="options"
|
|
308
341
|
:items="users"
|
|
309
|
-
:headers="args.headers"
|
|
310
|
-
:caption="args.caption"
|
|
311
342
|
:server-items-length="totalUsers"
|
|
312
343
|
:loading="state === StateEnum.PENDING"
|
|
313
|
-
|
|
314
|
-
:density="args.density"
|
|
315
|
-
:striped="args.striped"
|
|
316
|
-
:resizable-columns="args.resizableColumns"
|
|
344
|
+
v-bind="args"
|
|
317
345
|
@update:options="fetchData"
|
|
318
346
|
/>
|
|
319
347
|
</div>
|
|
@@ -328,127 +356,136 @@ export const ServerSortBy: Story = {
|
|
|
328
356
|
{
|
|
329
357
|
name: 'Template',
|
|
330
358
|
code: `
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
359
|
+
<template>
|
|
360
|
+
<SyServerTable
|
|
361
|
+
v-model:options="options"
|
|
362
|
+
:items="users"
|
|
363
|
+
:headers="headers"
|
|
364
|
+
:server-items-length="totalUsers"
|
|
365
|
+
:loading="state === StateEnum.PENDING"
|
|
366
|
+
suffix="server-sort"
|
|
367
|
+
@update:options="fetchData"
|
|
368
|
+
/>
|
|
369
|
+
</template>
|
|
370
|
+
`,
|
|
343
371
|
},
|
|
344
372
|
{
|
|
345
373
|
name: 'Script',
|
|
346
374
|
code: `
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
375
|
+
<script setup lang="ts">
|
|
376
|
+
import { ref } from 'vue'
|
|
377
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
378
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
379
|
+
import type { DataOptions } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
380
|
+
|
|
381
|
+
interface User {
|
|
382
|
+
[key: string]: string
|
|
383
|
+
firstname: string
|
|
384
|
+
lastname: string
|
|
385
|
+
email: string
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
interface DataObj {
|
|
389
|
+
items: User[]
|
|
390
|
+
total: number
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const totalUsers = ref(0)
|
|
394
|
+
const users = ref<User[]>([])
|
|
395
|
+
const state = ref(StateEnum.IDLE)
|
|
396
|
+
|
|
397
|
+
const options = ref<DataOptions>({
|
|
398
|
+
itemsPerPage: 5,
|
|
399
|
+
sortBy: [{ key: 'lastname', order: 'desc' }],
|
|
400
|
+
page: 1,
|
|
401
|
+
})
|
|
402
|
+
|
|
403
|
+
const headers = [
|
|
404
|
+
{ title: 'Nom', key: 'lastname' },
|
|
405
|
+
{ title: 'Prénom', key: 'firstname' },
|
|
406
|
+
{ title: 'Email', key: 'email' },
|
|
407
|
+
]
|
|
408
|
+
|
|
409
|
+
const fetchData = async (): Promise<void> => {
|
|
410
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
411
|
+
users.value = items
|
|
412
|
+
totalUsers.value = total
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const wait = async (ms: number) => {
|
|
416
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage }: DataOptions): Promise<DataObj> => {
|
|
420
|
+
state.value = StateEnum.PENDING
|
|
421
|
+
await wait(1000)
|
|
422
|
+
|
|
423
|
+
return new Promise((resolve) => {
|
|
424
|
+
let items: User[] = getUsers()
|
|
425
|
+
const total = items.length
|
|
426
|
+
|
|
427
|
+
if (sortBy && sortBy.length > 0) {
|
|
428
|
+
items = items.sort((a, b) => {
|
|
429
|
+
const key = sortBy[0].key
|
|
430
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
431
|
+
|
|
432
|
+
return a[key] > b[key] ? order : -order
|
|
433
|
+
})
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (itemsPerPage > 0) {
|
|
437
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
resolve({ items, total })
|
|
441
|
+
state.value = StateEnum.RESOLVED
|
|
442
|
+
})
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const getUsers = (): User[] => {
|
|
446
|
+
return [
|
|
447
|
+
{ firstname: 'Virginie', lastname: 'Beauchesne', email: 'virginie.beauchesne@example.com' },
|
|
448
|
+
{ firstname: 'Simone', lastname: 'Bellefeuille', email: 'simone.bellefeuille@example.com' },
|
|
449
|
+
{ firstname: 'Étienne', lastname: 'Salois', email: 'etienne.salois@example.com' },
|
|
450
|
+
{ firstname: 'Bernadette', lastname: 'Langelier', email: 'bernadette.langelier@example.com' },
|
|
451
|
+
{ firstname: 'Agate', lastname: 'Roy', email: 'agate.roy@example.com' },
|
|
452
|
+
{ firstname: 'Louis', lastname: 'Denis', email: 'louis.denis@example.com' },
|
|
453
|
+
{ firstname: 'Édith', lastname: 'Cartier', email: 'edith.cartier@example.com' },
|
|
454
|
+
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
455
|
+
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
456
|
+
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
457
|
+
{ firstname: 'Serge', lastname: 'Rivard', email: 'serge.rivard@example.com' },
|
|
458
|
+
{ firstname: 'Jacques', lastname: 'Demers', email: 'jacques.demers@example.com' },
|
|
459
|
+
{ firstname: 'Aimée', lastname: 'Josseaume', email: 'aimee.josseaume@example.com' },
|
|
460
|
+
{ firstname: 'Delphine', lastname: 'Robillard', email: 'delphine.robillard@example.com' },
|
|
461
|
+
{ firstname: 'Alexandre', lastname: 'Lazure', email: 'alexandre.lazure@example.com' },
|
|
462
|
+
]
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Initialize data
|
|
466
|
+
fetchData()
|
|
467
|
+
</script>
|
|
468
|
+
`,
|
|
433
469
|
},
|
|
434
470
|
],
|
|
435
471
|
},
|
|
436
472
|
args: {
|
|
437
|
-
options: {
|
|
473
|
+
'options': {
|
|
438
474
|
itemsPerPage: 5,
|
|
439
475
|
sortBy: [{ key: 'lastname', order: 'desc' }],
|
|
440
476
|
page: 1,
|
|
441
477
|
},
|
|
442
|
-
headers: [
|
|
478
|
+
'headers': [
|
|
443
479
|
{ title: 'Nom', key: 'lastname' },
|
|
444
480
|
{ title: 'Prénom', key: 'firstname' },
|
|
445
481
|
{ title: 'Email', key: 'email' },
|
|
446
482
|
],
|
|
447
|
-
caption: '',
|
|
448
|
-
serverItemsLength:
|
|
449
|
-
suffix: 'server-sort',
|
|
450
|
-
density: 'default',
|
|
451
|
-
striped: false,
|
|
483
|
+
'caption': '',
|
|
484
|
+
'serverItemsLength': 15,
|
|
485
|
+
'suffix': 'server-sort',
|
|
486
|
+
'density': 'default',
|
|
487
|
+
'striped': false,
|
|
488
|
+
'onUpdate:options': fn(),
|
|
452
489
|
},
|
|
453
490
|
render: (args) => {
|
|
454
491
|
return {
|
|
@@ -458,8 +495,16 @@ export const ServerSortBy: Story = {
|
|
|
458
495
|
const users = ref<User[]>([])
|
|
459
496
|
const state = ref(StateEnum.IDLE)
|
|
460
497
|
|
|
498
|
+
const options = ref({ ...args.options })
|
|
499
|
+
|
|
500
|
+
watch(options, (newVal) => {
|
|
501
|
+
if (args.options) {
|
|
502
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
503
|
+
}
|
|
504
|
+
}, { deep: true })
|
|
505
|
+
|
|
461
506
|
const fetchData = async (): Promise<void> => {
|
|
462
|
-
const { items, total } = await getDataFromApi(
|
|
507
|
+
const { items, total } = await getDataFromApi(options.value as DataOptions)
|
|
463
508
|
users.value = items
|
|
464
509
|
totalUsers.value = total
|
|
465
510
|
}
|
|
@@ -506,28 +551,31 @@ export const ServerSortBy: Story = {
|
|
|
506
551
|
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
507
552
|
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
508
553
|
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
554
|
+
{ firstname: 'Serge', lastname: 'Rivard', email: 'serge.rivard@example.com' },
|
|
555
|
+
{ firstname: 'Jacques', lastname: 'Demers', email: 'jacques.demers@example.com' },
|
|
556
|
+
{ firstname: 'Aimée', lastname: 'Josseaume', email: 'aimee.josseaume@example.com' },
|
|
557
|
+
{ firstname: 'Delphine', lastname: 'Robillard', email: 'delphine.robillard@example.com' },
|
|
558
|
+
{ firstname: 'Alexandre', lastname: 'Lazure', email: 'alexandre.lazure@example.com' },
|
|
509
559
|
]
|
|
510
560
|
}
|
|
511
561
|
|
|
512
|
-
|
|
562
|
+
// Initialize data
|
|
563
|
+
fetchData()
|
|
564
|
+
|
|
565
|
+
return { args, users, state, fetchData, options, totalUsers, StateEnum }
|
|
513
566
|
},
|
|
514
567
|
template: `
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
:
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
:resizable-columns="args.resizableColumns"
|
|
527
|
-
@update:options="fetchData"
|
|
528
|
-
/>
|
|
529
|
-
</div>
|
|
530
|
-
`,
|
|
568
|
+
<div>
|
|
569
|
+
<SyServerTable
|
|
570
|
+
v-model:options="options"
|
|
571
|
+
:items="users"
|
|
572
|
+
:server-items-length="totalUsers"
|
|
573
|
+
:loading="state === StateEnum.PENDING"
|
|
574
|
+
v-bind="args"
|
|
575
|
+
@update:options="fetchData"
|
|
576
|
+
/>
|
|
577
|
+
</div>
|
|
578
|
+
`,
|
|
531
579
|
}
|
|
532
580
|
},
|
|
533
581
|
}
|
|
@@ -538,153 +586,153 @@ export const ServerFilterByText: Story = {
|
|
|
538
586
|
{
|
|
539
587
|
name: 'Template',
|
|
540
588
|
code: `
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
589
|
+
<template>
|
|
590
|
+
<SyServerTable
|
|
591
|
+
v-model:options="options"
|
|
592
|
+
:items="filteredUsers"
|
|
593
|
+
:headers="headers"
|
|
594
|
+
:server-items-length="totalFilteredUsers"
|
|
595
|
+
:loading="state === StateEnum.PENDING"
|
|
596
|
+
suffix="server-filter-text"
|
|
597
|
+
:show-filters="true"
|
|
598
|
+
@update:options="fetchData"
|
|
599
|
+
/>
|
|
600
|
+
</template>
|
|
601
|
+
`,
|
|
554
602
|
},
|
|
555
603
|
{
|
|
556
604
|
name: 'Script',
|
|
557
605
|
code: `
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
606
|
+
<script setup lang="ts">
|
|
607
|
+
import { ref } from 'vue'
|
|
608
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
609
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
610
|
+
import type { DataOptions, FilterOption } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
611
|
+
|
|
612
|
+
interface User {
|
|
613
|
+
firstname: string
|
|
614
|
+
lastname: string
|
|
615
|
+
email: string
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
interface DataObj {
|
|
619
|
+
items: User[]
|
|
620
|
+
total: number
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
const totalFilteredUsers = ref(0)
|
|
624
|
+
const filteredUsers = ref<User[]>([])
|
|
625
|
+
const state = ref(StateEnum.IDLE)
|
|
626
|
+
|
|
627
|
+
const options = ref<DataOptions>({
|
|
628
|
+
itemsPerPage: 5,
|
|
629
|
+
page: 1,
|
|
630
|
+
filters: [],
|
|
631
|
+
})
|
|
632
|
+
|
|
633
|
+
const headers = [
|
|
634
|
+
{
|
|
635
|
+
title: 'Prénom',
|
|
636
|
+
key: 'firstname',
|
|
637
|
+
filterable: true,
|
|
638
|
+
filterType: 'text'
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
title: 'Nom',
|
|
642
|
+
key: 'lastname',
|
|
643
|
+
filterable: true,
|
|
644
|
+
filterType: 'text'
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
title: 'Email',
|
|
648
|
+
key: 'email',
|
|
649
|
+
filterable: true,
|
|
650
|
+
filterType: 'text'
|
|
651
|
+
}
|
|
652
|
+
]
|
|
653
|
+
|
|
654
|
+
const fetchData = async (): Promise<void> => {
|
|
655
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
656
|
+
filteredUsers.value = items
|
|
657
|
+
totalFilteredUsers.value = total
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
const wait = async (ms: number) => {
|
|
661
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
665
|
+
state.value = StateEnum.PENDING
|
|
666
|
+
await wait(1000)
|
|
667
|
+
|
|
668
|
+
return new Promise((resolve) => {
|
|
669
|
+
// Get all users
|
|
670
|
+
let items: User[] = getUsers()
|
|
671
|
+
|
|
672
|
+
// Apply filters on server side
|
|
673
|
+
if (filters && filters.length > 0) {
|
|
674
|
+
filters.forEach((filter: FilterOption) => {
|
|
675
|
+
const { key, value } = filter
|
|
676
|
+
|
|
677
|
+
items = items.filter(item => {
|
|
678
|
+
const itemValue = item[key as keyof User]
|
|
679
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
680
|
+
})
|
|
681
|
+
})
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
const total = items.length
|
|
685
|
+
|
|
686
|
+
// Apply sorting
|
|
687
|
+
if (sortBy && sortBy.length > 0) {
|
|
688
|
+
items = items.sort((a, b) => {
|
|
689
|
+
const key = sortBy[0].key as keyof User
|
|
690
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
691
|
+
|
|
692
|
+
return String(a[key]) > String(b[key]) ? order : -order
|
|
693
|
+
})
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// Apply pagination
|
|
697
|
+
if (itemsPerPage > 0) {
|
|
698
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
resolve({ items, total })
|
|
702
|
+
state.value = StateEnum.RESOLVED
|
|
703
|
+
})
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
const getUsers = (): User[] => {
|
|
707
|
+
return [
|
|
708
|
+
{ firstname: 'Virginie', lastname: 'Beauchesne', email: 'virginie.beauchesne@example.com' },
|
|
709
|
+
{ firstname: 'Simone', lastname: 'Bellefeuille', email: 'simone.bellefeuille@example.com' },
|
|
710
|
+
{ firstname: 'Étienne', lastname: 'Salois', email: 'etienne.salois@example.com' },
|
|
711
|
+
{ firstname: 'Bernadette', lastname: 'Langelier', email: 'bernadette.langelier@example.com' },
|
|
712
|
+
{ firstname: 'Agate', lastname: 'Roy', email: 'agate.roy@example.com' },
|
|
713
|
+
{ firstname: 'Louis', lastname: 'Denis', email: 'louis.denis@example.com' },
|
|
714
|
+
{ firstname: 'Édith', lastname: 'Cartier', email: 'edith.cartier@example.com' },
|
|
715
|
+
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
716
|
+
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
717
|
+
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
718
|
+
{ firstname: 'Martin', lastname: 'Lavoie', email: 'martin.lavoie@example.com' },
|
|
719
|
+
{ firstname: 'Céline', lastname: 'Tremblay', email: 'celine.tremblay@example.com' },
|
|
720
|
+
{ firstname: 'Jacques', lastname: 'Gagnon', email: 'jacques.gagnon@example.com' },
|
|
721
|
+
{ firstname: 'Isabelle', lastname: 'Côté', email: 'isabelle.cote@example.com' },
|
|
722
|
+
{ firstname: 'Philippe', lastname: 'Bouchard', email: 'philippe.bouchard@example.com' },
|
|
723
|
+
]
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// Initialize data
|
|
727
|
+
fetchData()
|
|
728
|
+
</script>
|
|
729
|
+
`,
|
|
682
730
|
},
|
|
683
731
|
],
|
|
684
732
|
},
|
|
685
733
|
args: {
|
|
686
|
-
serverItemsLength: 15,
|
|
687
|
-
headers: [
|
|
734
|
+
'serverItemsLength': 15,
|
|
735
|
+
'headers': [
|
|
688
736
|
{
|
|
689
737
|
title: 'Prénom',
|
|
690
738
|
key: 'firstname',
|
|
@@ -704,22 +752,30 @@ export const ServerFilterByText: Story = {
|
|
|
704
752
|
filterType: 'text',
|
|
705
753
|
},
|
|
706
754
|
],
|
|
707
|
-
caption: '',
|
|
708
|
-
options: {
|
|
755
|
+
'caption': '',
|
|
756
|
+
'options': {
|
|
709
757
|
itemsPerPage: 5,
|
|
710
758
|
page: 1,
|
|
711
759
|
filters: [],
|
|
712
760
|
},
|
|
713
|
-
showFilters: true,
|
|
714
|
-
suffix: 'server-filter-text',
|
|
715
|
-
density: 'default',
|
|
716
|
-
striped: false,
|
|
761
|
+
'showFilters': true,
|
|
762
|
+
'suffix': 'server-filter-text',
|
|
763
|
+
'density': 'default',
|
|
764
|
+
'striped': false,
|
|
765
|
+
'onUpdate:options': fn(),
|
|
717
766
|
},
|
|
718
767
|
render(args) {
|
|
719
768
|
return {
|
|
720
769
|
components: { SyServerTable },
|
|
721
770
|
setup() {
|
|
722
|
-
const options = ref(args.options)
|
|
771
|
+
const options = ref({ ...args.options })
|
|
772
|
+
|
|
773
|
+
watch(options, (newVal) => {
|
|
774
|
+
if (args.options) {
|
|
775
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
776
|
+
}
|
|
777
|
+
}, { deep: true })
|
|
778
|
+
|
|
723
779
|
const totalFilteredUsers = ref(0)
|
|
724
780
|
const filteredUsers = ref<Record<string, unknown>[]>([])
|
|
725
781
|
const state = ref(StateEnum.IDLE)
|
|
@@ -779,10 +835,10 @@ export const ServerFilterByText: Story = {
|
|
|
779
835
|
|
|
780
836
|
return {
|
|
781
837
|
args,
|
|
782
|
-
options,
|
|
783
838
|
filteredUsers,
|
|
784
839
|
totalFilteredUsers,
|
|
785
840
|
state,
|
|
841
|
+
options,
|
|
786
842
|
fetchData,
|
|
787
843
|
StateEnum,
|
|
788
844
|
}
|
|
@@ -790,17 +846,12 @@ export const ServerFilterByText: Story = {
|
|
|
790
846
|
template: `
|
|
791
847
|
<div>
|
|
792
848
|
<SyServerTable
|
|
849
|
+
v-bind="args"
|
|
793
850
|
v-model:options="options"
|
|
794
851
|
:items="filteredUsers"
|
|
795
|
-
:headers="args.headers"
|
|
796
|
-
:caption="args.caption"
|
|
797
852
|
:server-items-length="totalFilteredUsers"
|
|
798
853
|
:loading="state === StateEnum.PENDING"
|
|
799
|
-
|
|
800
|
-
:suffix="args.suffix"
|
|
801
|
-
:density="args.density"
|
|
802
|
-
:striped="args.striped"
|
|
803
|
-
:resizable-columns="args.resizableColumns"
|
|
854
|
+
suffix="server-filter-text"
|
|
804
855
|
@update:options="fetchData"
|
|
805
856
|
/>
|
|
806
857
|
</div>
|
|
@@ -815,161 +866,161 @@ export const ServerFilterByNumber: Story = {
|
|
|
815
866
|
{
|
|
816
867
|
name: 'Template',
|
|
817
868
|
code: `
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
869
|
+
<template>
|
|
870
|
+
<SyServerTable
|
|
871
|
+
v-model:options="options"
|
|
872
|
+
:items="filteredUsers"
|
|
873
|
+
:headers="headers"
|
|
874
|
+
:server-items-length="totalFilteredUsers"
|
|
875
|
+
:loading="state === StateEnum.PENDING"
|
|
876
|
+
suffix="server-filter-number"
|
|
877
|
+
:show-filters="true"
|
|
878
|
+
@update:options="fetchData"
|
|
879
|
+
/>
|
|
880
|
+
</template>
|
|
881
|
+
`,
|
|
831
882
|
},
|
|
832
883
|
{
|
|
833
884
|
name: 'Script',
|
|
834
885
|
code: `
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
886
|
+
<script setup lang="ts">
|
|
887
|
+
import { ref } from 'vue'
|
|
888
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
889
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
890
|
+
import type { DataOptions, FilterOption } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
891
|
+
|
|
892
|
+
interface User {
|
|
893
|
+
name: string
|
|
894
|
+
age: number
|
|
895
|
+
salary: number
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
interface DataObj {
|
|
899
|
+
items: User[]
|
|
900
|
+
total: number
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
const totalFilteredUsers = ref(0)
|
|
904
|
+
const filteredUsers = ref<User[]>([])
|
|
905
|
+
const state = ref(StateEnum.IDLE)
|
|
906
|
+
|
|
907
|
+
const options = ref<DataOptions>({
|
|
908
|
+
itemsPerPage: 5,
|
|
909
|
+
page: 1,
|
|
910
|
+
filters: [],
|
|
911
|
+
})
|
|
912
|
+
|
|
913
|
+
const headers = [
|
|
914
|
+
{
|
|
915
|
+
title: 'Nom',
|
|
916
|
+
key: 'name',
|
|
917
|
+
filterable: true,
|
|
918
|
+
filterType: 'text'
|
|
919
|
+
},
|
|
920
|
+
{
|
|
921
|
+
title: 'Âge',
|
|
922
|
+
key: 'age',
|
|
923
|
+
filterable: true,
|
|
924
|
+
filterType: 'number'
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
title: 'Salaire',
|
|
928
|
+
key: 'salary',
|
|
929
|
+
filterable: true,
|
|
930
|
+
filterType: 'number'
|
|
931
|
+
}
|
|
932
|
+
]
|
|
933
|
+
|
|
934
|
+
const fetchData = async (): Promise<void> => {
|
|
935
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
936
|
+
filteredUsers.value = items
|
|
937
|
+
totalFilteredUsers.value = total
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
const wait = async (ms: number) => {
|
|
941
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
945
|
+
state.value = StateEnum.PENDING
|
|
946
|
+
await wait(1000)
|
|
947
|
+
|
|
948
|
+
return new Promise((resolve) => {
|
|
949
|
+
// Get all users
|
|
950
|
+
let items: User[] = getUsers()
|
|
951
|
+
|
|
952
|
+
// Apply filters on server side
|
|
953
|
+
if (filters && filters.length > 0) {
|
|
954
|
+
filters.forEach((filter: FilterOption) => {
|
|
955
|
+
const { key, value, type } = filter
|
|
956
|
+
|
|
957
|
+
items = items.filter(item => {
|
|
958
|
+
const itemValue = item[key as keyof User]
|
|
959
|
+
|
|
960
|
+
if (type === 'number') {
|
|
961
|
+
return Number(itemValue) === Number(value)
|
|
962
|
+
} else {
|
|
963
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
964
|
+
}
|
|
965
|
+
})
|
|
966
|
+
})
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
const total = items.length
|
|
970
|
+
|
|
971
|
+
// Apply sorting
|
|
972
|
+
if (sortBy && sortBy.length > 0) {
|
|
973
|
+
items = items.sort((a, b) => {
|
|
974
|
+
const key = sortBy[0].key as keyof User
|
|
975
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
976
|
+
|
|
977
|
+
if (typeof a[key] === 'number' && typeof b[key] === 'number') {
|
|
978
|
+
return (a[key] as number) > (b[key] as number) ? order : -order
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
return String(a[key]) > String(b[key]) ? order : -order
|
|
982
|
+
})
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
// Apply pagination
|
|
986
|
+
if (itemsPerPage > 0) {
|
|
987
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
resolve({ items, total })
|
|
991
|
+
state.value = StateEnum.RESOLVED
|
|
992
|
+
})
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
const getUsers = (): User[] => {
|
|
996
|
+
return [
|
|
997
|
+
{ name: 'Jean Dupont', age: 32, salary: 45000 },
|
|
998
|
+
{ name: 'Marie Martin', age: 28, salary: 52000 },
|
|
999
|
+
{ name: 'Pierre Durand', age: 45, salary: 65000 },
|
|
1000
|
+
{ name: 'Sophie Petit', age: 36, salary: 48000 },
|
|
1001
|
+
{ name: 'Thomas Leroy', age: 41, salary: 58000 },
|
|
1002
|
+
{ name: 'Julie Bernard', age: 29, salary: 47000 },
|
|
1003
|
+
{ name: 'Nicolas Moreau', age: 38, salary: 61000 },
|
|
1004
|
+
{ name: 'Camille Dubois', age: 33, salary: 49000 },
|
|
1005
|
+
{ name: 'Alexandre Lefebvre', age: 44, salary: 67000 },
|
|
1006
|
+
{ name: 'Émilie Girard', age: 31, salary: 51000 },
|
|
1007
|
+
{ name: 'Lucas Roux', age: 39, salary: 59000 },
|
|
1008
|
+
{ name: 'Chloé Lambert', age: 27, salary: 46000 },
|
|
1009
|
+
{ name: 'Maxime Simon', age: 42, salary: 63000 },
|
|
1010
|
+
{ name: 'Laura Fournier', age: 35, salary: 54000 },
|
|
1011
|
+
{ name: 'Antoine Mercier', age: 40, salary: 60000 },
|
|
1012
|
+
]
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Initialize data
|
|
1016
|
+
fetchData()
|
|
1017
|
+
</script>
|
|
1018
|
+
`,
|
|
968
1019
|
},
|
|
969
1020
|
],
|
|
970
1021
|
},
|
|
971
1022
|
args: {
|
|
972
|
-
headers: [
|
|
1023
|
+
'headers': [
|
|
973
1024
|
{
|
|
974
1025
|
title: 'Nom',
|
|
975
1026
|
key: 'name',
|
|
@@ -989,23 +1040,31 @@ export const ServerFilterByNumber: Story = {
|
|
|
989
1040
|
filterType: 'number',
|
|
990
1041
|
},
|
|
991
1042
|
],
|
|
992
|
-
caption: '',
|
|
993
|
-
options: {
|
|
1043
|
+
'caption': '',
|
|
1044
|
+
'options': {
|
|
994
1045
|
itemsPerPage: 5,
|
|
995
1046
|
page: 1,
|
|
996
1047
|
filters: [],
|
|
997
1048
|
},
|
|
998
|
-
serverItemsLength: 15,
|
|
999
|
-
showFilters: true,
|
|
1000
|
-
suffix: 'server-filter-number',
|
|
1001
|
-
density: 'default',
|
|
1002
|
-
striped: false,
|
|
1049
|
+
'serverItemsLength': 15,
|
|
1050
|
+
'showFilters': true,
|
|
1051
|
+
'suffix': 'server-filter-number',
|
|
1052
|
+
'density': 'default',
|
|
1053
|
+
'striped': false,
|
|
1054
|
+
'onUpdate:options': fn(),
|
|
1003
1055
|
},
|
|
1004
1056
|
render(args) {
|
|
1005
1057
|
return {
|
|
1006
1058
|
components: { SyServerTable },
|
|
1007
1059
|
setup() {
|
|
1008
|
-
const options = ref(args.options)
|
|
1060
|
+
const options = ref({ ...args.options })
|
|
1061
|
+
|
|
1062
|
+
watch(options, (newVal) => {
|
|
1063
|
+
if (args.options) {
|
|
1064
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
1065
|
+
}
|
|
1066
|
+
}, { deep: true })
|
|
1067
|
+
|
|
1009
1068
|
const totalFilteredUsers = ref(0)
|
|
1010
1069
|
const filteredUsers = ref<Record<string, unknown>[]>([])
|
|
1011
1070
|
const state = ref(StateEnum.IDLE)
|
|
@@ -1071,9 +1130,9 @@ export const ServerFilterByNumber: Story = {
|
|
|
1071
1130
|
|
|
1072
1131
|
return {
|
|
1073
1132
|
args,
|
|
1074
|
-
options,
|
|
1075
1133
|
filteredUsers,
|
|
1076
1134
|
totalFilteredUsers,
|
|
1135
|
+
options,
|
|
1077
1136
|
state,
|
|
1078
1137
|
fetchData,
|
|
1079
1138
|
StateEnum,
|
|
@@ -1082,17 +1141,11 @@ export const ServerFilterByNumber: Story = {
|
|
|
1082
1141
|
template: `
|
|
1083
1142
|
<div>
|
|
1084
1143
|
<SyServerTable
|
|
1144
|
+
v-bind="args"
|
|
1085
1145
|
v-model:options="options"
|
|
1086
1146
|
:items="filteredUsers"
|
|
1087
|
-
:headers="args.headers"
|
|
1088
|
-
:caption="args.caption"
|
|
1089
1147
|
:server-items-length="totalFilteredUsers"
|
|
1090
1148
|
:loading="state === StateEnum.PENDING"
|
|
1091
|
-
:show-filters="args.showFilters"
|
|
1092
|
-
:suffix="args.suffix"
|
|
1093
|
-
:density="args.density"
|
|
1094
|
-
:striped="args.striped"
|
|
1095
|
-
:resizable-columns="args.resizableColumns"
|
|
1096
1149
|
@update:options="fetchData"
|
|
1097
1150
|
/>
|
|
1098
1151
|
</div>
|
|
@@ -1107,170 +1160,170 @@ export const ServerFilterBySelect: Story = {
|
|
|
1107
1160
|
{
|
|
1108
1161
|
name: 'Template',
|
|
1109
1162
|
code: `
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1163
|
+
<template>
|
|
1164
|
+
<SyServerTable
|
|
1165
|
+
v-model:options="options"
|
|
1166
|
+
:items="filteredUsers"
|
|
1167
|
+
:headers="headers"
|
|
1168
|
+
:server-items-length="totalFilteredUsers"
|
|
1169
|
+
:loading="state === StateEnum.PENDING"
|
|
1170
|
+
suffix="server-filter-select"
|
|
1171
|
+
:show-filters="true"
|
|
1172
|
+
@update:options="fetchData"
|
|
1173
|
+
/>
|
|
1174
|
+
</template>
|
|
1175
|
+
`,
|
|
1123
1176
|
},
|
|
1124
1177
|
{
|
|
1125
1178
|
name: 'Script',
|
|
1126
1179
|
code: `
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1180
|
+
<script setup lang="ts">
|
|
1181
|
+
import { ref } from 'vue'
|
|
1182
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
1183
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
1184
|
+
import type { DataOptions, FilterOption } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
1185
|
+
|
|
1186
|
+
interface User {
|
|
1187
|
+
name: string
|
|
1188
|
+
department: string
|
|
1189
|
+
status: string
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
interface DataObj {
|
|
1193
|
+
items: User[]
|
|
1194
|
+
total: number
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
const totalFilteredUsers = ref(0)
|
|
1198
|
+
const filteredUsers = ref<User[]>([])
|
|
1199
|
+
const state = ref(StateEnum.IDLE)
|
|
1200
|
+
|
|
1201
|
+
const options = ref<DataOptions>({
|
|
1202
|
+
itemsPerPage: 5,
|
|
1203
|
+
page: 1,
|
|
1204
|
+
filters: [],
|
|
1205
|
+
})
|
|
1206
|
+
|
|
1207
|
+
const headers = [
|
|
1208
|
+
{
|
|
1209
|
+
title: 'Nom',
|
|
1210
|
+
key: 'name',
|
|
1211
|
+
filterable: true,
|
|
1212
|
+
filterType: 'text'
|
|
1213
|
+
},
|
|
1214
|
+
{
|
|
1215
|
+
title: 'Département',
|
|
1216
|
+
key: 'department',
|
|
1217
|
+
filterable: true,
|
|
1218
|
+
filterType: 'select',
|
|
1219
|
+
hideMessages: true,
|
|
1220
|
+
filterOptions: [
|
|
1221
|
+
{ text: 'RH', value: 'RH' },
|
|
1222
|
+
{ text: 'IT', value: 'IT' },
|
|
1223
|
+
{ text: 'Finance', value: 'Finance' },
|
|
1224
|
+
{ text: 'Marketing', value: 'Marketing' },
|
|
1225
|
+
]
|
|
1226
|
+
},
|
|
1227
|
+
{
|
|
1228
|
+
title: 'Statut',
|
|
1229
|
+
key: 'status',
|
|
1230
|
+
filterable: true,
|
|
1231
|
+
filterType: 'select',
|
|
1232
|
+
hideMessages: true,
|
|
1233
|
+
filterOptions: [
|
|
1234
|
+
{ text: 'Actif', value: 'Actif' },
|
|
1235
|
+
{ text: 'En congé', value: 'En congé' },
|
|
1236
|
+
{ text: 'Inactif', value: 'Inactif' },
|
|
1237
|
+
]
|
|
1238
|
+
}
|
|
1239
|
+
]
|
|
1240
|
+
|
|
1241
|
+
const fetchData = async (): Promise<void> => {
|
|
1242
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
1243
|
+
filteredUsers.value = items
|
|
1244
|
+
totalFilteredUsers.value = total
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
const wait = async (ms: number) => {
|
|
1248
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
1252
|
+
state.value = StateEnum.PENDING
|
|
1253
|
+
await wait(1000)
|
|
1254
|
+
|
|
1255
|
+
return new Promise((resolve) => {
|
|
1256
|
+
// Get all users
|
|
1257
|
+
let items: User[] = getUsers()
|
|
1258
|
+
|
|
1259
|
+
// Apply filters on server side
|
|
1260
|
+
if (filters && filters.length > 0) {
|
|
1261
|
+
filters.forEach((filter: FilterOption) => {
|
|
1262
|
+
const { key, value, type } = filter
|
|
1263
|
+
|
|
1264
|
+
items = items.filter(item => {
|
|
1265
|
+
const itemValue = item[key as keyof User]
|
|
1266
|
+
|
|
1267
|
+
if (type === 'select') {
|
|
1268
|
+
return itemValue === value
|
|
1269
|
+
} else {
|
|
1270
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
1271
|
+
}
|
|
1272
|
+
})
|
|
1273
|
+
})
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
const total = items.length
|
|
1277
|
+
|
|
1278
|
+
// Apply sorting
|
|
1279
|
+
if (sortBy && sortBy.length > 0) {
|
|
1280
|
+
items = items.sort((a, b) => {
|
|
1281
|
+
const key = sortBy[0].key as keyof User
|
|
1282
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
1283
|
+
|
|
1284
|
+
return String(a[key]) > String(b[key]) ? order : -order
|
|
1285
|
+
})
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
// Apply pagination
|
|
1289
|
+
if (itemsPerPage > 0) {
|
|
1290
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
resolve({ items, total })
|
|
1294
|
+
state.value = StateEnum.RESOLVED
|
|
1295
|
+
})
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
const getUsers = (): User[] => {
|
|
1299
|
+
return [
|
|
1300
|
+
{ name: 'Jean Dupont', department: 'RH', status: 'Actif' },
|
|
1301
|
+
{ name: 'Marie Martin', department: 'IT', status: 'En congé' },
|
|
1302
|
+
{ name: 'Pierre Durand', department: 'Finance', status: 'Actif' },
|
|
1303
|
+
{ name: 'Sophie Petit', department: 'Marketing', status: 'Actif' },
|
|
1304
|
+
{ name: 'Thomas Leroy', department: 'IT', status: 'Inactif' },
|
|
1305
|
+
{ name: 'Julie Bernard', department: 'RH', status: 'Actif' },
|
|
1306
|
+
{ name: 'Nicolas Moreau', department: 'Finance', status: 'En congé' },
|
|
1307
|
+
{ name: 'Camille Dubois', department: 'Marketing', status: 'Inactif' },
|
|
1308
|
+
{ name: 'Alexandre Lefebvre', department: 'IT', status: 'Actif' },
|
|
1309
|
+
{ name: 'Émilie Girard', department: 'RH', status: 'En congé' },
|
|
1310
|
+
{ name: 'Lucas Roux', department: 'Finance', status: 'Actif' },
|
|
1311
|
+
{ name: 'Chloé Lambert', department: 'Marketing', status: 'Actif' },
|
|
1312
|
+
{ name: 'Maxime Simon', department: 'IT', status: 'Inactif' },
|
|
1313
|
+
{ name: 'Laura Fournier', department: 'RH', status: 'Actif' },
|
|
1314
|
+
{ name: 'Antoine Mercier', department: 'Finance', status: 'En congé' },
|
|
1315
|
+
]
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
// Initialize data
|
|
1319
|
+
fetchData()
|
|
1320
|
+
</script>
|
|
1321
|
+
`,
|
|
1269
1322
|
},
|
|
1270
1323
|
],
|
|
1271
1324
|
},
|
|
1272
1325
|
args: {
|
|
1273
|
-
headers: [
|
|
1326
|
+
'headers': [
|
|
1274
1327
|
{
|
|
1275
1328
|
title: 'Nom',
|
|
1276
1329
|
key: 'name',
|
|
@@ -1303,23 +1356,31 @@ export const ServerFilterBySelect: Story = {
|
|
|
1303
1356
|
],
|
|
1304
1357
|
},
|
|
1305
1358
|
],
|
|
1306
|
-
caption: '',
|
|
1307
|
-
options: {
|
|
1359
|
+
'caption': '',
|
|
1360
|
+
'options': {
|
|
1308
1361
|
itemsPerPage: 5,
|
|
1309
1362
|
page: 1,
|
|
1310
1363
|
filters: [],
|
|
1311
1364
|
},
|
|
1312
|
-
serverItemsLength: 15,
|
|
1313
|
-
showFilters: true,
|
|
1314
|
-
suffix: 'server-filter-select',
|
|
1315
|
-
density: 'default',
|
|
1316
|
-
striped: false,
|
|
1365
|
+
'serverItemsLength': 15,
|
|
1366
|
+
'showFilters': true,
|
|
1367
|
+
'suffix': 'server-filter-select',
|
|
1368
|
+
'density': 'default',
|
|
1369
|
+
'striped': false,
|
|
1370
|
+
'onUpdate:options': fn(),
|
|
1317
1371
|
},
|
|
1318
1372
|
render(args) {
|
|
1319
1373
|
return {
|
|
1320
1374
|
components: { SyServerTable },
|
|
1321
1375
|
setup() {
|
|
1322
|
-
const options = ref(args.options)
|
|
1376
|
+
const options = ref({ ...args.options })
|
|
1377
|
+
|
|
1378
|
+
watch(options, (newVal) => {
|
|
1379
|
+
if (args.options) {
|
|
1380
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
1381
|
+
}
|
|
1382
|
+
}, { deep: true })
|
|
1383
|
+
|
|
1323
1384
|
const totalFilteredUsers = ref(0)
|
|
1324
1385
|
const filteredUsers = ref<Record<string, unknown>[]>([])
|
|
1325
1386
|
const state = ref(StateEnum.IDLE)
|
|
@@ -1385,9 +1446,9 @@ export const ServerFilterBySelect: Story = {
|
|
|
1385
1446
|
|
|
1386
1447
|
return {
|
|
1387
1448
|
args,
|
|
1388
|
-
options,
|
|
1389
1449
|
filteredUsers,
|
|
1390
1450
|
totalFilteredUsers,
|
|
1451
|
+
options,
|
|
1391
1452
|
state,
|
|
1392
1453
|
fetchData,
|
|
1393
1454
|
StateEnum,
|
|
@@ -1396,17 +1457,11 @@ export const ServerFilterBySelect: Story = {
|
|
|
1396
1457
|
template: `
|
|
1397
1458
|
<div>
|
|
1398
1459
|
<SyServerTable
|
|
1460
|
+
v-bind="args"
|
|
1399
1461
|
v-model:options="options"
|
|
1400
1462
|
:items="filteredUsers"
|
|
1401
|
-
:headers="args.headers"
|
|
1402
|
-
:caption="args.caption"
|
|
1403
1463
|
:server-items-length="totalFilteredUsers"
|
|
1404
1464
|
:loading="state === StateEnum.PENDING"
|
|
1405
|
-
:show-filters="args.showFilters"
|
|
1406
|
-
:suffix="args.suffix"
|
|
1407
|
-
:density="args.density"
|
|
1408
|
-
:striped="args.striped"
|
|
1409
|
-
:resizable-columns="args.resizableColumns"
|
|
1410
1465
|
@update:options="fetchData"
|
|
1411
1466
|
/>
|
|
1412
1467
|
</div>
|
|
@@ -1415,158 +1470,180 @@ export const ServerFilterBySelect: Story = {
|
|
|
1415
1470
|
},
|
|
1416
1471
|
}
|
|
1417
1472
|
|
|
1418
|
-
export const
|
|
1473
|
+
export const ServerFilterBySelectMultiple: Story = {
|
|
1419
1474
|
parameters: {
|
|
1420
1475
|
sourceCode: [
|
|
1421
1476
|
{
|
|
1422
1477
|
name: 'Template',
|
|
1423
1478
|
code: `
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1479
|
+
<template>
|
|
1480
|
+
<SyServerTable
|
|
1481
|
+
v-model:options="options"
|
|
1482
|
+
:items="filteredUsers"
|
|
1483
|
+
:headers="headers"
|
|
1484
|
+
:server-items-length="totalFilteredUsers"
|
|
1485
|
+
:loading="state === StateEnum.PENDING"
|
|
1486
|
+
suffix="server-filter-select"
|
|
1487
|
+
:show-filters="true"
|
|
1488
|
+
@update:options="fetchData"
|
|
1489
|
+
/>
|
|
1490
|
+
</template>
|
|
1491
|
+
`,
|
|
1437
1492
|
},
|
|
1438
1493
|
{
|
|
1439
1494
|
name: 'Script',
|
|
1440
1495
|
code: `
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1496
|
+
<script setup lang="ts">
|
|
1497
|
+
import { ref } from 'vue'
|
|
1498
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
1499
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
1500
|
+
import type { DataOptions, FilterOption } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
1501
|
+
|
|
1502
|
+
interface User {
|
|
1503
|
+
name: string
|
|
1504
|
+
department: string
|
|
1505
|
+
status: string
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
interface DataObj {
|
|
1509
|
+
items: User[]
|
|
1510
|
+
total: number
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
const totalFilteredUsers = ref(0)
|
|
1514
|
+
const filteredUsers = ref<User[]>([])
|
|
1515
|
+
const state = ref(StateEnum.IDLE)
|
|
1516
|
+
|
|
1517
|
+
const options = ref<DataOptions>({
|
|
1518
|
+
itemsPerPage: 5,
|
|
1519
|
+
page: 1,
|
|
1520
|
+
filters: [],
|
|
1521
|
+
})
|
|
1522
|
+
|
|
1523
|
+
const headers = [
|
|
1524
|
+
{
|
|
1525
|
+
title: 'Nom',
|
|
1526
|
+
key: 'name',
|
|
1527
|
+
filterable: true,
|
|
1528
|
+
filterType: 'text'
|
|
1529
|
+
},
|
|
1530
|
+
{
|
|
1531
|
+
title: 'Département',
|
|
1532
|
+
key: 'department',
|
|
1533
|
+
filterable: true,
|
|
1534
|
+
filterType: 'select',
|
|
1535
|
+
multiple: true,
|
|
1536
|
+
chips: true,
|
|
1537
|
+
hideMessages: true,
|
|
1538
|
+
filterOptions: [
|
|
1539
|
+
{ text: 'RH', value: 'RH' },
|
|
1540
|
+
{ text: 'IT', value: 'IT' },
|
|
1541
|
+
{ text: 'Finance', value: 'Finance' },
|
|
1542
|
+
{ text: 'Marketing', value: 'Marketing' },
|
|
1543
|
+
]
|
|
1544
|
+
},
|
|
1545
|
+
{
|
|
1546
|
+
title: 'Statut',
|
|
1547
|
+
key: 'status',
|
|
1548
|
+
filterable: true,
|
|
1549
|
+
filterType: 'select',
|
|
1550
|
+
multiple: true,
|
|
1551
|
+
chips: true,
|
|
1552
|
+
hideMessages: true,
|
|
1553
|
+
filterOptions: [
|
|
1554
|
+
{ text: 'Actif', value: 'Actif' },
|
|
1555
|
+
{ text: 'En congé', value: 'En congé' },
|
|
1556
|
+
{ text: 'Inactif', value: 'Inactif' },
|
|
1557
|
+
]
|
|
1558
|
+
}
|
|
1559
|
+
]
|
|
1560
|
+
|
|
1561
|
+
const fetchData = async (): Promise<void> => {
|
|
1562
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
1563
|
+
filteredUsers.value = items
|
|
1564
|
+
totalFilteredUsers.value = total
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
const wait = async (ms: number) => {
|
|
1568
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
1572
|
+
state.value = StateEnum.PENDING
|
|
1573
|
+
await wait(1000)
|
|
1574
|
+
|
|
1575
|
+
return new Promise((resolve) => {
|
|
1576
|
+
// Get all users
|
|
1577
|
+
let items: User[] = getUsers()
|
|
1578
|
+
|
|
1579
|
+
// Apply filters on server side
|
|
1580
|
+
if (filters && filters.length > 0) {
|
|
1581
|
+
filters.forEach((filter: FilterOption) => {
|
|
1582
|
+
const { key, value, type } = filter
|
|
1583
|
+
|
|
1584
|
+
items = items.filter(item => {
|
|
1585
|
+
const itemValue = item[key as keyof User]
|
|
1586
|
+
|
|
1587
|
+
if (type === 'select') {
|
|
1588
|
+
return itemValue === value
|
|
1589
|
+
} else {
|
|
1590
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
1591
|
+
}
|
|
1592
|
+
})
|
|
1593
|
+
})
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
const total = items.length
|
|
1597
|
+
|
|
1598
|
+
// Apply sorting
|
|
1599
|
+
if (sortBy && sortBy.length > 0) {
|
|
1600
|
+
items = items.sort((a, b) => {
|
|
1601
|
+
const key = sortBy[0].key as keyof User
|
|
1602
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
1603
|
+
|
|
1604
|
+
return String(a[key]) > String(b[key]) ? order : -order
|
|
1605
|
+
})
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
// Apply pagination
|
|
1609
|
+
if (itemsPerPage > 0) {
|
|
1610
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
resolve({ items, total })
|
|
1614
|
+
state.value = StateEnum.RESOLVED
|
|
1615
|
+
})
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
const getUsers = (): User[] => {
|
|
1619
|
+
return [
|
|
1620
|
+
{ name: 'Jean Dupont', department: 'RH', status: 'Actif' },
|
|
1621
|
+
{ name: 'Marie Martin', department: 'IT', status: 'En congé' },
|
|
1622
|
+
{ name: 'Pierre Durand', department: 'Finance', status: 'Actif' },
|
|
1623
|
+
{ name: 'Sophie Petit', department: 'Marketing', status: 'Actif' },
|
|
1624
|
+
{ name: 'Thomas Leroy', department: 'IT', status: 'Inactif' },
|
|
1625
|
+
{ name: 'Julie Bernard', department: 'RH', status: 'Actif' },
|
|
1626
|
+
{ name: 'Nicolas Moreau', department: 'Finance', status: 'En congé' },
|
|
1627
|
+
{ name: 'Camille Dubois', department: 'Marketing', status: 'Inactif' },
|
|
1628
|
+
{ name: 'Alexandre Lefebvre', department: 'IT', status: 'Actif' },
|
|
1629
|
+
{ name: 'Émilie Girard', department: 'RH', status: 'En congé' },
|
|
1630
|
+
{ name: 'Lucas Roux', department: 'Finance', status: 'Actif' },
|
|
1631
|
+
{ name: 'Chloé Lambert', department: 'Marketing', status: 'Actif' },
|
|
1632
|
+
{ name: 'Maxime Simon', department: 'IT', status: 'Inactif' },
|
|
1633
|
+
{ name: 'Laura Fournier', department: 'RH', status: 'Actif' },
|
|
1634
|
+
{ name: 'Antoine Mercier', department: 'Finance', status: 'En congé' },
|
|
1635
|
+
]
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
// Initialize data
|
|
1639
|
+
fetchData()
|
|
1640
|
+
</script>
|
|
1641
|
+
`,
|
|
1563
1642
|
},
|
|
1564
1643
|
],
|
|
1565
1644
|
},
|
|
1566
1645
|
args: {
|
|
1567
|
-
|
|
1568
|
-
showFilters: true,
|
|
1569
|
-
headers: [
|
|
1646
|
+
'headers': [
|
|
1570
1647
|
{
|
|
1571
1648
|
title: 'Nom',
|
|
1572
1649
|
key: 'name',
|
|
@@ -1574,81 +1651,362 @@ export const ServerFilterByDate: Story = {
|
|
|
1574
1651
|
filterType: 'text',
|
|
1575
1652
|
},
|
|
1576
1653
|
{
|
|
1577
|
-
title: '
|
|
1578
|
-
key: '
|
|
1654
|
+
title: 'Département',
|
|
1655
|
+
key: 'department',
|
|
1579
1656
|
filterable: true,
|
|
1580
|
-
filterType: '
|
|
1581
|
-
|
|
1657
|
+
filterType: 'select',
|
|
1658
|
+
multiple: true,
|
|
1659
|
+
chips: true,
|
|
1660
|
+
hideMessages: true,
|
|
1661
|
+
filterOptions: [
|
|
1662
|
+
{ text: 'RH', value: 'RH' },
|
|
1663
|
+
{ text: 'IT', value: 'IT' },
|
|
1664
|
+
{ text: 'Finance', value: 'Finance' },
|
|
1665
|
+
{ text: 'Marketing', value: 'Marketing' },
|
|
1666
|
+
],
|
|
1582
1667
|
},
|
|
1583
1668
|
{
|
|
1584
|
-
title: '
|
|
1585
|
-
key: '
|
|
1669
|
+
title: 'Statut',
|
|
1670
|
+
key: 'status',
|
|
1586
1671
|
filterable: true,
|
|
1587
|
-
filterType: '
|
|
1588
|
-
|
|
1672
|
+
filterType: 'select',
|
|
1673
|
+
multiple: true,
|
|
1674
|
+
chips: true,
|
|
1675
|
+
hideMessages: true,
|
|
1676
|
+
filterOptions: [
|
|
1677
|
+
{ text: 'Actif', value: 'Actif' },
|
|
1678
|
+
{ text: 'En congé', value: 'En congé' },
|
|
1679
|
+
{ text: 'Inactif', value: 'Inactif' },
|
|
1680
|
+
],
|
|
1589
1681
|
},
|
|
1590
1682
|
],
|
|
1591
|
-
caption: '',
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1683
|
+
'caption': '',
|
|
1684
|
+
'options': {
|
|
1685
|
+
itemsPerPage: 5,
|
|
1686
|
+
page: 1,
|
|
1687
|
+
filters: [],
|
|
1688
|
+
},
|
|
1689
|
+
'serverItemsLength': 15,
|
|
1690
|
+
'showFilters': true,
|
|
1691
|
+
'suffix': 'server-filter-select',
|
|
1692
|
+
'density': 'default',
|
|
1693
|
+
'striped': false,
|
|
1694
|
+
'onUpdate:options': fn(),
|
|
1595
1695
|
},
|
|
1596
1696
|
render(args) {
|
|
1597
1697
|
return {
|
|
1598
1698
|
components: { SyServerTable },
|
|
1599
1699
|
setup() {
|
|
1600
|
-
|
|
1601
|
-
const originalUsers = [
|
|
1602
|
-
{
|
|
1603
|
-
name: 'Jean-Pierre Dubois',
|
|
1604
|
-
hireDate: dayjs('2025-05-15').format('DD/MM/YYYY'),
|
|
1605
|
-
vacationPeriod: {
|
|
1606
|
-
from: dayjs('2025-07-01').format('DD/MM/YYYY'),
|
|
1607
|
-
to: dayjs('2025-07-15').format('DD/MM/YYYY'),
|
|
1608
|
-
},
|
|
1609
|
-
},
|
|
1610
|
-
{
|
|
1611
|
-
name: 'Marie-Claire Lefèvre',
|
|
1612
|
-
hireDate: dayjs('2025-03-10').format('DD/MM/YYYY'),
|
|
1613
|
-
vacationPeriod: {
|
|
1614
|
-
from: dayjs('2025-08-01').format('DD/MM/YYYY'),
|
|
1615
|
-
to: dayjs('2025-08-20').format('DD/MM/YYYY'),
|
|
1616
|
-
},
|
|
1617
|
-
},
|
|
1618
|
-
{
|
|
1619
|
-
name: 'François Moreau',
|
|
1620
|
-
hireDate: dayjs('2025-11-22').format('DD/MM/YYYY'),
|
|
1621
|
-
vacationPeriod: {
|
|
1622
|
-
from: dayjs('2025-06-15').format('DD/MM/YYYY'),
|
|
1623
|
-
to: dayjs('2025-07-05').format('DD/MM/YYYY'),
|
|
1624
|
-
},
|
|
1625
|
-
},
|
|
1626
|
-
{
|
|
1627
|
-
name: 'Céline Rousseau',
|
|
1628
|
-
hireDate: dayjs('2025-01-08').format('DD/MM/YYYY'),
|
|
1629
|
-
vacationPeriod: {
|
|
1630
|
-
from: dayjs('2025-12-20').format('DD/MM/YYYY'),
|
|
1631
|
-
to: dayjs('2026-01-05').format('DD/MM/YYYY'),
|
|
1632
|
-
},
|
|
1633
|
-
},
|
|
1634
|
-
{
|
|
1635
|
-
name: 'Thierry Bertrand',
|
|
1636
|
-
hireDate: dayjs('2025-07-30').format('DD/MM/YYYY'),
|
|
1637
|
-
vacationPeriod: {
|
|
1638
|
-
from: dayjs('2025-09-10').format('DD/MM/YYYY'),
|
|
1639
|
-
to: dayjs('2025-09-25').format('DD/MM/YYYY'),
|
|
1640
|
-
},
|
|
1641
|
-
},
|
|
1642
|
-
]
|
|
1700
|
+
const options = ref({ ...args.options })
|
|
1643
1701
|
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
const
|
|
1702
|
+
watch(options, (newVal) => {
|
|
1703
|
+
if (args.options) {
|
|
1704
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
1705
|
+
}
|
|
1706
|
+
}, { deep: true })
|
|
1707
|
+
|
|
1708
|
+
const totalFilteredUsers = ref(0)
|
|
1709
|
+
const filteredUsers = ref<Record<string, unknown>[]>([])
|
|
1710
|
+
const state = ref(StateEnum.IDLE)
|
|
1711
|
+
|
|
1712
|
+
const fetchData = async (): Promise<void> => {
|
|
1713
|
+
state.value = StateEnum.PENDING
|
|
1714
|
+
|
|
1715
|
+
// Simulate API call
|
|
1716
|
+
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
1717
|
+
|
|
1718
|
+
// Get all users
|
|
1719
|
+
let items = [
|
|
1720
|
+
{ name: 'Jean Dupont', department: 'RH', status: 'Actif' },
|
|
1721
|
+
{ name: 'Marie Martin', department: 'IT', status: 'En congé' },
|
|
1722
|
+
{ name: 'Pierre Durand', department: 'Finance', status: 'Actif' },
|
|
1723
|
+
{ name: 'Sophie Petit', department: 'Marketing', status: 'Actif' },
|
|
1724
|
+
{ name: 'Thomas Leroy', department: 'IT', status: 'Inactif' },
|
|
1725
|
+
{ name: 'Julie Bernard', department: 'RH', status: 'Actif' },
|
|
1726
|
+
{ name: 'Nicolas Moreau', department: 'Finance', status: 'En congé' },
|
|
1727
|
+
{ name: 'Camille Dubois', department: 'Marketing', status: 'Inactif' },
|
|
1728
|
+
{ name: 'Alexandre Lefebvre', department: 'IT', status: 'Actif' },
|
|
1729
|
+
{ name: 'Émilie Girard', department: 'RH', status: 'En congé' },
|
|
1730
|
+
{ name: 'Lucas Roux', department: 'Finance', status: 'Actif' },
|
|
1731
|
+
{ name: 'Chloé Lambert', department: 'Marketing', status: 'Actif' },
|
|
1732
|
+
{ name: 'Maxime Simon', department: 'IT', status: 'Inactif' },
|
|
1733
|
+
{ name: 'Laura Fournier', department: 'RH', status: 'Actif' },
|
|
1734
|
+
{ name: 'Antoine Mercier', department: 'Finance', status: 'En congé' },
|
|
1735
|
+
]
|
|
1736
|
+
|
|
1737
|
+
// Apply filters on server side
|
|
1738
|
+
if (options.value?.filters && options.value.filters.length > 0) {
|
|
1739
|
+
options.value.filters.forEach((filter) => {
|
|
1740
|
+
const { key, value, type } = filter
|
|
1741
|
+
|
|
1742
|
+
items = items.filter((item) => {
|
|
1743
|
+
const itemValue = item[key]
|
|
1744
|
+
|
|
1745
|
+
if (type === 'select') {
|
|
1746
|
+
if (Array.isArray(value)) {
|
|
1747
|
+
// Empty array means no filter applied
|
|
1748
|
+
if (value.length === 0) return true
|
|
1749
|
+
// Check if item value is in the selected values
|
|
1750
|
+
return value.includes(itemValue)
|
|
1751
|
+
}
|
|
1752
|
+
else {
|
|
1753
|
+
return itemValue === value
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
else {
|
|
1757
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
1758
|
+
}
|
|
1759
|
+
})
|
|
1760
|
+
})
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
const total = items.length
|
|
1764
|
+
|
|
1765
|
+
// Apply pagination
|
|
1766
|
+
const { page = 1, itemsPerPage = 10 } = options.value || {}
|
|
1767
|
+
if (itemsPerPage > 0) {
|
|
1768
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
filteredUsers.value = items as Record<string, unknown>[]
|
|
1772
|
+
totalFilteredUsers.value = total
|
|
1773
|
+
state.value = StateEnum.RESOLVED
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
// Initialize data
|
|
1777
|
+
fetchData()
|
|
1778
|
+
|
|
1779
|
+
return {
|
|
1780
|
+
args,
|
|
1781
|
+
filteredUsers,
|
|
1782
|
+
totalFilteredUsers,
|
|
1783
|
+
options,
|
|
1784
|
+
state,
|
|
1785
|
+
fetchData,
|
|
1786
|
+
StateEnum,
|
|
1787
|
+
}
|
|
1788
|
+
},
|
|
1789
|
+
template: `
|
|
1790
|
+
<div>
|
|
1791
|
+
<SyServerTable
|
|
1792
|
+
v-bind="args"
|
|
1793
|
+
v-model:options="options"
|
|
1794
|
+
:items="filteredUsers"
|
|
1795
|
+
:server-items-length="totalFilteredUsers"
|
|
1796
|
+
:loading="state === StateEnum.PENDING"
|
|
1797
|
+
@update:options="fetchData"
|
|
1798
|
+
/>
|
|
1799
|
+
</div>
|
|
1800
|
+
`,
|
|
1801
|
+
}
|
|
1802
|
+
},
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
export const ServerFilterByExacteDate: Story = {
|
|
1806
|
+
parameters: {
|
|
1807
|
+
sourceCode: [
|
|
1808
|
+
{
|
|
1809
|
+
name: 'Template',
|
|
1810
|
+
code: `
|
|
1811
|
+
<template>
|
|
1812
|
+
<SyServerTable
|
|
1813
|
+
v-model:options="options"
|
|
1814
|
+
:items="filteredUsers"
|
|
1815
|
+
:headers="headers"
|
|
1816
|
+
:server-items-length="totalFilteredUsers"
|
|
1817
|
+
:loading="state === StateEnum.PENDING"
|
|
1818
|
+
suffix="server-filter-date"
|
|
1819
|
+
:show-filters="true"
|
|
1820
|
+
@update:options="fetchData"
|
|
1821
|
+
/>
|
|
1822
|
+
</template>
|
|
1823
|
+
`,
|
|
1824
|
+
},
|
|
1825
|
+
{
|
|
1826
|
+
name: 'Script',
|
|
1827
|
+
code: `
|
|
1828
|
+
<script setup lang="ts">
|
|
1829
|
+
import { ref } from 'vue'
|
|
1830
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
1831
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
1832
|
+
import type { DataOptions, FilterOption } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
1833
|
+
|
|
1834
|
+
interface User {
|
|
1835
|
+
name: string
|
|
1836
|
+
hireDate: string
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
interface DataObj {
|
|
1840
|
+
items: User[]
|
|
1841
|
+
total: number
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
const totalFilteredUsers = ref(0)
|
|
1845
|
+
const filteredUsers = ref<User[]>([])
|
|
1846
|
+
const state = ref(StateEnum.IDLE)
|
|
1847
|
+
|
|
1848
|
+
const options = ref<DataOptions>({
|
|
1849
|
+
itemsPerPage: 5,
|
|
1850
|
+
page: 1,
|
|
1851
|
+
filters: [],
|
|
1852
|
+
})
|
|
1853
|
+
|
|
1854
|
+
const headers = [
|
|
1855
|
+
{
|
|
1856
|
+
title: 'Nom',
|
|
1857
|
+
key: 'name',
|
|
1858
|
+
filterable: true,
|
|
1859
|
+
filterType: 'text'
|
|
1860
|
+
},
|
|
1861
|
+
{
|
|
1862
|
+
title: 'Date d'embauche',
|
|
1863
|
+
key: 'hireDate',
|
|
1864
|
+
filterable: true,
|
|
1865
|
+
filterType: 'date',
|
|
1866
|
+
dateFormat: 'DD/MM/YYYY'
|
|
1867
|
+
},
|
|
1868
|
+
]
|
|
1869
|
+
|
|
1870
|
+
const fetchData = async (): Promise<void> => {
|
|
1871
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
1872
|
+
filteredUsers.value = items
|
|
1873
|
+
totalFilteredUsers.value = total
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
const wait = async (ms: number) => {
|
|
1877
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
1881
|
+
state.value = StateEnum.PENDING
|
|
1882
|
+
await wait(1000)
|
|
1883
|
+
|
|
1884
|
+
return new Promise((resolve) => {
|
|
1885
|
+
// Get all users
|
|
1886
|
+
let items: User[] = getUsers()
|
|
1887
|
+
|
|
1888
|
+
// Apply filters on server side
|
|
1889
|
+
if (filters && filters.length > 0) {
|
|
1890
|
+
filters.forEach((filter: FilterOption) => {
|
|
1891
|
+
const { key, value, type } = filter
|
|
1892
|
+
|
|
1893
|
+
items = items.filter(item => {
|
|
1894
|
+
const itemValue = item[key as keyof User]
|
|
1895
|
+
|
|
1896
|
+
if (type === 'date') {
|
|
1897
|
+
// Simple date comparison for demo purposes
|
|
1898
|
+
return itemValue === value
|
|
1899
|
+
} else {
|
|
1900
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
1901
|
+
}
|
|
1902
|
+
})
|
|
1903
|
+
})
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
const total = items.length
|
|
1907
|
+
|
|
1908
|
+
// Apply sorting
|
|
1909
|
+
if (sortBy && sortBy.length > 0) {
|
|
1910
|
+
items = items.sort((a, b) => {
|
|
1911
|
+
const key = sortBy[0].key as keyof User
|
|
1912
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
1913
|
+
|
|
1914
|
+
return String(a[key]) > String(b[key]) ? order : -order
|
|
1915
|
+
})
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
// Apply pagination
|
|
1919
|
+
if (itemsPerPage > 0) {
|
|
1920
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
resolve({ items, total })
|
|
1924
|
+
state.value = StateEnum.RESOLVED
|
|
1925
|
+
})
|
|
1926
|
+
})
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
// Update the displayed data
|
|
1930
|
+
users.value = filteredData
|
|
1931
|
+
totalUsers.value = filteredData.length
|
|
1932
|
+
|
|
1933
|
+
state.value = StateEnum.RESOLVED
|
|
1934
|
+
}
|
|
1935
|
+
// Initialize data
|
|
1936
|
+
fetchData()
|
|
1937
|
+
</script>
|
|
1938
|
+
`,
|
|
1939
|
+
},
|
|
1940
|
+
],
|
|
1941
|
+
},
|
|
1942
|
+
args: {
|
|
1943
|
+
'serverItemsLength': 5,
|
|
1944
|
+
'showFilters': true,
|
|
1945
|
+
'headers': [
|
|
1946
|
+
{
|
|
1947
|
+
title: 'Nom',
|
|
1948
|
+
key: 'name',
|
|
1949
|
+
filterable: true,
|
|
1950
|
+
filterType: 'text',
|
|
1951
|
+
},
|
|
1952
|
+
{
|
|
1953
|
+
title: 'Date d\'embauche',
|
|
1954
|
+
key: 'hireDate',
|
|
1955
|
+
filterable: true,
|
|
1956
|
+
filterType: 'date',
|
|
1957
|
+
dateFormat: 'DD/MM/YYYY',
|
|
1958
|
+
},
|
|
1959
|
+
],
|
|
1960
|
+
'options': {
|
|
1961
|
+
itemsPerPage: 5,
|
|
1962
|
+
page: 1,
|
|
1963
|
+
filters: [],
|
|
1964
|
+
},
|
|
1965
|
+
'caption': '',
|
|
1966
|
+
'suffix': 'server-filter-date',
|
|
1967
|
+
'density': 'default',
|
|
1968
|
+
'striped': false,
|
|
1969
|
+
'onUpdate:options': fn(),
|
|
1970
|
+
},
|
|
1971
|
+
render(args) {
|
|
1972
|
+
return {
|
|
1973
|
+
components: { SyServerTable },
|
|
1974
|
+
setup() {
|
|
1975
|
+
// Original data that never changes
|
|
1976
|
+
const originalUsers = [
|
|
1977
|
+
{
|
|
1978
|
+
name: 'Jean-Pierre Dubois',
|
|
1979
|
+
hireDate: dayjs('2025-05-15').format('DD/MM/YYYY'),
|
|
1980
|
+
},
|
|
1981
|
+
{
|
|
1982
|
+
name: 'Marie-Claire Lefèvre',
|
|
1983
|
+
hireDate: dayjs('2025-03-10').format('DD/MM/YYYY'),
|
|
1984
|
+
},
|
|
1985
|
+
{
|
|
1986
|
+
name: 'François Moreau',
|
|
1987
|
+
hireDate: dayjs('2025-11-22').format('DD/MM/YYYY'),
|
|
1988
|
+
},
|
|
1989
|
+
{
|
|
1990
|
+
name: 'Céline Rousseau',
|
|
1991
|
+
hireDate: dayjs('2025-01-08').format('DD/MM/YYYY'),
|
|
1992
|
+
},
|
|
1993
|
+
{
|
|
1994
|
+
name: 'Thierry Bertrand',
|
|
1995
|
+
hireDate: dayjs('2025-07-30').format('DD/MM/YYYY'),
|
|
1996
|
+
},
|
|
1997
|
+
]
|
|
1998
|
+
|
|
1999
|
+
const options = ref({ ...args.options })
|
|
2000
|
+
|
|
2001
|
+
watch(options, (newVal) => {
|
|
2002
|
+
if (args.options) {
|
|
2003
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
2004
|
+
}
|
|
2005
|
+
}, { deep: true })
|
|
2006
|
+
|
|
2007
|
+
const totalUsers = ref(originalUsers.length)
|
|
2008
|
+
const users = ref([...originalUsers])
|
|
2009
|
+
const state = ref(StateEnum.IDLE)
|
|
1652
2010
|
|
|
1653
2011
|
const fetchData = async () => {
|
|
1654
2012
|
state.value = StateEnum.PENDING
|
|
@@ -1673,20 +2031,20 @@ export const ServerFilterByDate: Story = {
|
|
|
1673
2031
|
return itemValue === value
|
|
1674
2032
|
}
|
|
1675
2033
|
else if (type === 'period') {
|
|
1676
|
-
|
|
1677
|
-
const
|
|
1678
|
-
const
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
if (
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
return period.from === filterPeriod.from && period.to === filterPeriod.to
|
|
2034
|
+
const filter = value as { from: string, to: string }
|
|
2035
|
+
const start = new Date(filter.from)
|
|
2036
|
+
const end = new Date(filter.to)
|
|
2037
|
+
const itemDate = new Date(itemValue)
|
|
2038
|
+
|
|
2039
|
+
if (itemDate) {
|
|
2040
|
+
if (end && itemDate < end) {
|
|
2041
|
+
return false
|
|
2042
|
+
}
|
|
2043
|
+
if (start && itemDate > start) {
|
|
2044
|
+
return false
|
|
2045
|
+
}
|
|
1689
2046
|
}
|
|
2047
|
+
|
|
1690
2048
|
return true
|
|
1691
2049
|
}
|
|
1692
2050
|
else {
|
|
@@ -1703,6 +2061,9 @@ export const ServerFilterByDate: Story = {
|
|
|
1703
2061
|
state.value = StateEnum.RESOLVED
|
|
1704
2062
|
}
|
|
1705
2063
|
|
|
2064
|
+
// Initialize data
|
|
2065
|
+
fetchData()
|
|
2066
|
+
|
|
1706
2067
|
return {
|
|
1707
2068
|
args,
|
|
1708
2069
|
users,
|
|
@@ -1716,17 +2077,11 @@ export const ServerFilterByDate: Story = {
|
|
|
1716
2077
|
template: `
|
|
1717
2078
|
<div>
|
|
1718
2079
|
<SyServerTable
|
|
2080
|
+
v-bind="args"
|
|
1719
2081
|
v-model:options="options"
|
|
1720
2082
|
:items="users"
|
|
1721
|
-
:headers="args.headers"
|
|
1722
|
-
:caption="args.caption"
|
|
1723
2083
|
:server-items-length="totalUsers"
|
|
1724
2084
|
:loading="state === StateEnum.PENDING"
|
|
1725
|
-
:resizable-columns="args.resizableColumns"
|
|
1726
|
-
:show-filters="true"
|
|
1727
|
-
:suffix="args.suffix"
|
|
1728
|
-
:density="args.density"
|
|
1729
|
-
:striped="args.striped"
|
|
1730
2085
|
@update:options="fetchData"
|
|
1731
2086
|
/>
|
|
1732
2087
|
</div>
|
|
@@ -1735,71 +2090,376 @@ export const ServerFilterByDate: Story = {
|
|
|
1735
2090
|
},
|
|
1736
2091
|
}
|
|
1737
2092
|
|
|
1738
|
-
export const
|
|
2093
|
+
export const ServerFilterByPeriod: Story = {
|
|
1739
2094
|
parameters: {
|
|
1740
2095
|
sourceCode: [
|
|
1741
2096
|
{
|
|
1742
2097
|
name: 'Template',
|
|
1743
2098
|
code: `
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
<div class="custom-filter-info mb-2">
|
|
1758
|
-
Filtre personnalisé :
|
|
1759
|
-
</div>
|
|
1760
|
-
<v-select
|
|
1761
|
-
v-model="customFilterValue"
|
|
1762
|
-
:items="statusOptions"
|
|
1763
|
-
label="Statut"
|
|
1764
|
-
variant="outlined"
|
|
1765
|
-
density="compact"
|
|
1766
|
-
color="primary"
|
|
1767
|
-
bg-color="white"
|
|
1768
|
-
@update:model-value="(val) => {
|
|
1769
|
-
// Utiliser la fonction updateFilter fournie par le slot
|
|
1770
|
-
updateFilter(val)
|
|
1771
|
-
}"
|
|
1772
|
-
/>
|
|
1773
|
-
</div>
|
|
1774
|
-
</template>
|
|
1775
|
-
</SyServerTable>
|
|
1776
|
-
</template>
|
|
1777
|
-
`,
|
|
2099
|
+
<template>
|
|
2100
|
+
<SyServerTable
|
|
2101
|
+
v-model:options="options"
|
|
2102
|
+
:items="filteredUsers"
|
|
2103
|
+
:headers="headers"
|
|
2104
|
+
:server-items-length="totalFilteredUsers"
|
|
2105
|
+
:loading="state === StateEnum.PENDING"
|
|
2106
|
+
suffix="server-filter-date"
|
|
2107
|
+
:show-filters="true"
|
|
2108
|
+
@update:options="fetchData"
|
|
2109
|
+
/>
|
|
2110
|
+
</template>
|
|
2111
|
+
`,
|
|
1778
2112
|
},
|
|
1779
2113
|
{
|
|
1780
2114
|
name: 'Script',
|
|
1781
2115
|
code: `
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
2116
|
+
<script setup lang="ts">
|
|
2117
|
+
import { ref } from 'vue'
|
|
2118
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
2119
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
2120
|
+
import type { DataOptions, FilterOption } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
2121
|
+
|
|
2122
|
+
interface User {
|
|
2123
|
+
name: string
|
|
2124
|
+
hireDate: string
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
interface DataObj {
|
|
2128
|
+
items: User[]
|
|
2129
|
+
total: number
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
const totalFilteredUsers = ref(0)
|
|
2133
|
+
const filteredUsers = ref<User[]>([])
|
|
2134
|
+
const state = ref(StateEnum.IDLE)
|
|
2135
|
+
|
|
2136
|
+
const options = ref<DataOptions>({
|
|
2137
|
+
itemsPerPage: 5,
|
|
2138
|
+
page: 1,
|
|
2139
|
+
filters: [],
|
|
2140
|
+
})
|
|
2141
|
+
|
|
2142
|
+
const headers = [
|
|
2143
|
+
{
|
|
2144
|
+
title: 'Nom',
|
|
2145
|
+
key: 'name',
|
|
2146
|
+
filterable: true,
|
|
2147
|
+
filterType: 'text'
|
|
2148
|
+
},
|
|
2149
|
+
{
|
|
2150
|
+
title: 'Date d'embauche',
|
|
2151
|
+
key: 'hireDate',
|
|
2152
|
+
filterable: true,
|
|
2153
|
+
filterType: 'periode',
|
|
2154
|
+
dateFormat: 'DD/MM/YYYY'
|
|
2155
|
+
},
|
|
2156
|
+
]
|
|
2157
|
+
|
|
2158
|
+
const fetchData = async (): Promise<void> => {
|
|
2159
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
2160
|
+
filteredUsers.value = items
|
|
2161
|
+
totalFilteredUsers.value = total
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
const wait = async (ms: number) => {
|
|
2165
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
2169
|
+
state.value = StateEnum.PENDING
|
|
2170
|
+
await wait(1000)
|
|
2171
|
+
|
|
2172
|
+
return new Promise((resolve) => {
|
|
2173
|
+
// Get all users
|
|
2174
|
+
let items: User[] = getUsers()
|
|
2175
|
+
|
|
2176
|
+
// Apply filters on server side
|
|
2177
|
+
if (filters && filters.length > 0) {
|
|
2178
|
+
filters.forEach((filter: FilterOption) => {
|
|
2179
|
+
const { key, value, type } = filter
|
|
2180
|
+
|
|
2181
|
+
items = items.filter(item => {
|
|
2182
|
+
const itemValue = item[key as keyof User]
|
|
1797
2183
|
|
|
1798
|
-
|
|
1799
|
-
{
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
2184
|
+
if (type === 'period') {
|
|
2185
|
+
function formatDate(date: string): Date | null {
|
|
2186
|
+
if (!date) return null
|
|
2187
|
+
const parsedDate = dayjs(date, 'DD/MM/YYYY')
|
|
2188
|
+
return parsedDate.isValid() ? parsedDate.toDate() : null
|
|
2189
|
+
}
|
|
2190
|
+
const filter = value as { from: string, to: string }
|
|
2191
|
+
const start = formatDate(filter.from)
|
|
2192
|
+
const end = formatDate(filter.to)
|
|
2193
|
+
const itemDate = formatDate(itemValue)
|
|
2194
|
+
|
|
2195
|
+
if (itemDate) {
|
|
2196
|
+
if (end && itemDate > end) {
|
|
2197
|
+
return false
|
|
2198
|
+
}
|
|
2199
|
+
if (start && itemDate < start) {
|
|
2200
|
+
return false
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
return true
|
|
2204
|
+
} else {
|
|
2205
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
2206
|
+
}
|
|
2207
|
+
})
|
|
2208
|
+
})
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
const total = items.length
|
|
2212
|
+
|
|
2213
|
+
// Apply sorting
|
|
2214
|
+
if (sortBy && sortBy.length > 0) {
|
|
2215
|
+
items = items.sort((a, b) => {
|
|
2216
|
+
const key = sortBy[0].key as keyof User
|
|
2217
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
2218
|
+
|
|
2219
|
+
return String(a[key]) > String(b[key]) ? order : -order
|
|
2220
|
+
})
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
// Apply pagination
|
|
2224
|
+
if (itemsPerPage > 0) {
|
|
2225
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
resolve({ items, total })
|
|
2229
|
+
state.value = StateEnum.RESOLVED
|
|
2230
|
+
})
|
|
2231
|
+
})
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2234
|
+
// Update the displayed data
|
|
2235
|
+
users.value = filteredData
|
|
2236
|
+
totalUsers.value = filteredData.length
|
|
2237
|
+
|
|
2238
|
+
state.value = StateEnum.RESOLVED
|
|
2239
|
+
}
|
|
2240
|
+
// Initialize data
|
|
2241
|
+
fetchData()
|
|
2242
|
+
</script>
|
|
2243
|
+
`,
|
|
2244
|
+
},
|
|
2245
|
+
],
|
|
2246
|
+
},
|
|
2247
|
+
args: {
|
|
2248
|
+
'serverItemsLength': 5,
|
|
2249
|
+
'showFilters': true,
|
|
2250
|
+
'headers': [
|
|
2251
|
+
{
|
|
2252
|
+
title: 'Nom',
|
|
2253
|
+
key: 'name',
|
|
2254
|
+
filterable: true,
|
|
2255
|
+
filterType: 'text',
|
|
2256
|
+
},
|
|
2257
|
+
{
|
|
2258
|
+
title: 'Date d\'embauche',
|
|
2259
|
+
key: 'hireDate',
|
|
2260
|
+
filterable: true,
|
|
2261
|
+
filterType: 'period',
|
|
2262
|
+
dateFormat: 'DD/MM/YYYY',
|
|
2263
|
+
},
|
|
2264
|
+
],
|
|
2265
|
+
'options': {
|
|
2266
|
+
itemsPerPage: 5,
|
|
2267
|
+
page: 1,
|
|
2268
|
+
filters: [],
|
|
2269
|
+
},
|
|
2270
|
+
'caption': '',
|
|
2271
|
+
'suffix': 'server-filter-date',
|
|
2272
|
+
'density': 'default',
|
|
2273
|
+
'striped': false,
|
|
2274
|
+
'onUpdate:options': fn(),
|
|
2275
|
+
},
|
|
2276
|
+
render(args) {
|
|
2277
|
+
return {
|
|
2278
|
+
components: { SyServerTable },
|
|
2279
|
+
setup() {
|
|
2280
|
+
// Original data that never changes
|
|
2281
|
+
const originalUsers = [
|
|
2282
|
+
{
|
|
2283
|
+
name: 'Jean-Pierre Dubois',
|
|
2284
|
+
hireDate: dayjs('2025-05-15').format('DD/MM/YYYY'),
|
|
2285
|
+
},
|
|
2286
|
+
{
|
|
2287
|
+
name: 'Marie-Claire Lefèvre',
|
|
2288
|
+
hireDate: dayjs('2025-03-10').format('DD/MM/YYYY'),
|
|
2289
|
+
},
|
|
2290
|
+
{
|
|
2291
|
+
name: 'François Moreau',
|
|
2292
|
+
hireDate: dayjs('2025-11-22').format('DD/MM/YYYY'),
|
|
2293
|
+
},
|
|
2294
|
+
{
|
|
2295
|
+
name: 'Céline Rousseau',
|
|
2296
|
+
hireDate: dayjs('2025-01-08').format('DD/MM/YYYY'),
|
|
2297
|
+
},
|
|
2298
|
+
{
|
|
2299
|
+
name: 'Thierry Bertrand',
|
|
2300
|
+
hireDate: dayjs('2025-07-30').format('DD/MM/YYYY'),
|
|
2301
|
+
},
|
|
2302
|
+
]
|
|
2303
|
+
|
|
2304
|
+
const options = ref({ ...args.options })
|
|
2305
|
+
|
|
2306
|
+
watch(options, (newVal) => {
|
|
2307
|
+
if (args.options) {
|
|
2308
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
2309
|
+
}
|
|
2310
|
+
}, { deep: true })
|
|
2311
|
+
|
|
2312
|
+
const totalUsers = ref(originalUsers.length)
|
|
2313
|
+
const users = ref([...originalUsers])
|
|
2314
|
+
const state = ref(StateEnum.IDLE)
|
|
2315
|
+
|
|
2316
|
+
const fetchData = async () => {
|
|
2317
|
+
state.value = StateEnum.PENDING
|
|
2318
|
+
|
|
2319
|
+
// Simulate API delay
|
|
2320
|
+
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
2321
|
+
|
|
2322
|
+
// Start with original data
|
|
2323
|
+
let filteredData = [...originalUsers]
|
|
2324
|
+
|
|
2325
|
+
// Apply filters if any
|
|
2326
|
+
if (options.value.filters && options.value.filters.length > 0) {
|
|
2327
|
+
filteredData = filteredData.filter((user) => {
|
|
2328
|
+
return options.value.filters!.every((filter) => {
|
|
2329
|
+
const { key, value, type } = filter
|
|
2330
|
+
const itemValue = user[key as keyof typeof user]
|
|
2331
|
+
|
|
2332
|
+
if (!value) return true
|
|
2333
|
+
|
|
2334
|
+
else if (type === 'period') {
|
|
2335
|
+
function formatDate(date: string): Date | null {
|
|
2336
|
+
if (!date) return null
|
|
2337
|
+
const parsedDate = dayjs(date, 'DD/MM/YYYY')
|
|
2338
|
+
return parsedDate.isValid() ? parsedDate.toDate() : null
|
|
2339
|
+
}
|
|
2340
|
+
const filter = value as { from: string, to: string }
|
|
2341
|
+
const start = formatDate(filter.from)
|
|
2342
|
+
const end = formatDate(filter.to)
|
|
2343
|
+
const itemDate = formatDate(itemValue)
|
|
2344
|
+
|
|
2345
|
+
if (itemDate) {
|
|
2346
|
+
if (end && itemDate > end) {
|
|
2347
|
+
return false
|
|
2348
|
+
}
|
|
2349
|
+
if (start && itemDate < start) {
|
|
2350
|
+
return false
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
return true
|
|
2354
|
+
}
|
|
2355
|
+
else {
|
|
2356
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
2357
|
+
}
|
|
2358
|
+
})
|
|
2359
|
+
})
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
// Update the displayed data
|
|
2363
|
+
users.value = filteredData
|
|
2364
|
+
totalUsers.value = filteredData.length
|
|
2365
|
+
|
|
2366
|
+
state.value = StateEnum.RESOLVED
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
// Initialize data
|
|
2370
|
+
fetchData()
|
|
2371
|
+
|
|
2372
|
+
return {
|
|
2373
|
+
args,
|
|
2374
|
+
users,
|
|
2375
|
+
totalUsers,
|
|
2376
|
+
options,
|
|
2377
|
+
state,
|
|
2378
|
+
fetchData,
|
|
2379
|
+
StateEnum,
|
|
2380
|
+
}
|
|
2381
|
+
},
|
|
2382
|
+
template: `
|
|
2383
|
+
<div>
|
|
2384
|
+
<SyServerTable
|
|
2385
|
+
v-bind="args"
|
|
2386
|
+
v-model:options="options"
|
|
2387
|
+
:items="users"
|
|
2388
|
+
:server-items-length="totalUsers"
|
|
2389
|
+
:loading="state === StateEnum.PENDING"
|
|
2390
|
+
@update:options="fetchData"
|
|
2391
|
+
/>
|
|
2392
|
+
</div>
|
|
2393
|
+
`,
|
|
2394
|
+
}
|
|
2395
|
+
},
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
export const CustomFilterSlot: Story = {
|
|
2399
|
+
parameters: {
|
|
2400
|
+
sourceCode: [
|
|
2401
|
+
{
|
|
2402
|
+
name: 'Template',
|
|
2403
|
+
code: `
|
|
2404
|
+
<template>
|
|
2405
|
+
<SyServerTable
|
|
2406
|
+
v-model:options="options"
|
|
2407
|
+
:headers="headers"
|
|
2408
|
+
:items="items"
|
|
2409
|
+
:server-items-length="serverItemsLength"
|
|
2410
|
+
:loading="loading"
|
|
2411
|
+
show-filters
|
|
2412
|
+
suffix="server-custom-filter-slot"
|
|
2413
|
+
@update:options="fetchData"
|
|
2414
|
+
>
|
|
2415
|
+
<template #filter.custom="{ header, value, updateFilter }">
|
|
2416
|
+
<div class="custom-filter-container">
|
|
2417
|
+
<div class="custom-filter-info mb-2">
|
|
2418
|
+
Filtre personnalisé :
|
|
2419
|
+
</div>
|
|
2420
|
+
<v-select
|
|
2421
|
+
v-model="customFilterValue"
|
|
2422
|
+
:items="statusOptions"
|
|
2423
|
+
label="Statut"
|
|
2424
|
+
variant="outlined"
|
|
2425
|
+
density="compact"
|
|
2426
|
+
color="primary"
|
|
2427
|
+
bg-color="white"
|
|
2428
|
+
@update:model-value="(val) => {
|
|
2429
|
+
// Utiliser la fonction updateFilter fournie par le slot
|
|
2430
|
+
updateFilter(val)
|
|
2431
|
+
}"
|
|
2432
|
+
/>
|
|
2433
|
+
</div>
|
|
2434
|
+
</template>
|
|
2435
|
+
</SyServerTable>
|
|
2436
|
+
</template>
|
|
2437
|
+
`,
|
|
2438
|
+
},
|
|
2439
|
+
{
|
|
2440
|
+
name: 'Script',
|
|
2441
|
+
code: `
|
|
2442
|
+
<script setup lang="ts">
|
|
2443
|
+
import { ref, watch } from 'vue'
|
|
2444
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
2445
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
2446
|
+
import type { DataOptions, FilterOption } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
2447
|
+
|
|
2448
|
+
const options = ref<Partial<DataOptions>>({
|
|
2449
|
+
itemsPerPage: 4,
|
|
2450
|
+
filters: []
|
|
2451
|
+
})
|
|
2452
|
+
|
|
2453
|
+
const customFilterValue = ref('')
|
|
2454
|
+
const statusOptions = ['Actif', 'Inactif', 'En attente']
|
|
2455
|
+
const loading = ref(false)
|
|
2456
|
+
const serverItemsLength = ref(6)
|
|
2457
|
+
|
|
2458
|
+
const headers = [
|
|
2459
|
+
{
|
|
2460
|
+
title: 'Nom',
|
|
2461
|
+
key: 'lastname',
|
|
2462
|
+
filterable: true,
|
|
1803
2463
|
filterType: 'text'
|
|
1804
2464
|
},
|
|
1805
2465
|
{
|
|
@@ -1916,8 +2576,8 @@ export const CustomFilterSlot: Story = {
|
|
|
1916
2576
|
],
|
|
1917
2577
|
},
|
|
1918
2578
|
args: {
|
|
1919
|
-
serverItemsLength: 6,
|
|
1920
|
-
headers: [
|
|
2579
|
+
'serverItemsLength': 6,
|
|
2580
|
+
'headers': [
|
|
1921
2581
|
{
|
|
1922
2582
|
title: 'Nom',
|
|
1923
2583
|
key: 'lastname',
|
|
@@ -1937,7 +2597,7 @@ export const CustomFilterSlot: Story = {
|
|
|
1937
2597
|
filterType: 'custom' as FilterType,
|
|
1938
2598
|
},
|
|
1939
2599
|
],
|
|
1940
|
-
items: [
|
|
2600
|
+
'items': [
|
|
1941
2601
|
{
|
|
1942
2602
|
firstname: 'Virginie',
|
|
1943
2603
|
lastname: 'Beauchesne',
|
|
@@ -1969,22 +2629,31 @@ export const CustomFilterSlot: Story = {
|
|
|
1969
2629
|
status: 'En attente',
|
|
1970
2630
|
},
|
|
1971
2631
|
],
|
|
1972
|
-
caption: '',
|
|
1973
|
-
options: {
|
|
2632
|
+
'caption': '',
|
|
2633
|
+
'options': {
|
|
1974
2634
|
itemsPerPage: 4,
|
|
2635
|
+
page: 1,
|
|
1975
2636
|
filters: [],
|
|
1976
2637
|
},
|
|
1977
|
-
showFilters: true,
|
|
1978
|
-
suffix: 'server-custom-filter-slot',
|
|
1979
|
-
density: 'default',
|
|
1980
|
-
striped: false,
|
|
2638
|
+
'showFilters': true,
|
|
2639
|
+
'suffix': 'server-custom-filter-slot',
|
|
2640
|
+
'density': 'default',
|
|
2641
|
+
'striped': false,
|
|
2642
|
+
'onUpdate:options': fn(),
|
|
1981
2643
|
},
|
|
1982
2644
|
render(args) {
|
|
1983
2645
|
return {
|
|
1984
2646
|
components: { SyServerTable },
|
|
1985
2647
|
setup() {
|
|
1986
2648
|
// Create reactive references
|
|
1987
|
-
const options = ref(args.options)
|
|
2649
|
+
const options = ref({ ...args.options })
|
|
2650
|
+
|
|
2651
|
+
watch(options, (newVal) => {
|
|
2652
|
+
if (args.options) {
|
|
2653
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
2654
|
+
}
|
|
2655
|
+
}, { deep: true })
|
|
2656
|
+
|
|
1988
2657
|
const items = ref(args.items)
|
|
1989
2658
|
const customFilterValue = ref('')
|
|
1990
2659
|
const statusOptions = ['Actif', 'Inactif', 'En attente']
|
|
@@ -2031,6 +2700,35 @@ export const CustomFilterSlot: Story = {
|
|
|
2031
2700
|
loading.value = false
|
|
2032
2701
|
}
|
|
2033
2702
|
|
|
2703
|
+
function handleFilterChange(val) {
|
|
2704
|
+
// Ensure options.value.filters is initialized
|
|
2705
|
+
if (!options.value.filters) {
|
|
2706
|
+
options.value.filters = []
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
// Create a new filters array with proper typing
|
|
2710
|
+
const currentFilters = options.value.filters as import('../common/types').FilterOption[]
|
|
2711
|
+
const newFilters = [...currentFilters].filter(f => f.key !== 'status')
|
|
2712
|
+
|
|
2713
|
+
// Add the new filter if a value is selected
|
|
2714
|
+
if (val) {
|
|
2715
|
+
newFilters.push({
|
|
2716
|
+
key: 'status',
|
|
2717
|
+
value: val,
|
|
2718
|
+
type: 'select' as FilterType, // Use 'select' type for compatibility with filtering logic
|
|
2719
|
+
})
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
// Update the options with the new filters
|
|
2723
|
+
options.value = {
|
|
2724
|
+
...options.value,
|
|
2725
|
+
filters: newFilters,
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
|
|
2729
|
+
// Initialize data
|
|
2730
|
+
fetchData()
|
|
2731
|
+
|
|
2034
2732
|
return {
|
|
2035
2733
|
args,
|
|
2036
2734
|
options,
|
|
@@ -2039,22 +2737,17 @@ export const CustomFilterSlot: Story = {
|
|
|
2039
2737
|
statusOptions,
|
|
2040
2738
|
loading,
|
|
2041
2739
|
serverItemsLength,
|
|
2740
|
+
handleFilterChange,
|
|
2042
2741
|
fetchData,
|
|
2043
2742
|
}
|
|
2044
2743
|
},
|
|
2045
2744
|
template: `
|
|
2046
2745
|
<SyServerTable
|
|
2746
|
+
v-bind="args"
|
|
2047
2747
|
v-model:options="options"
|
|
2048
|
-
:headers="args.headers"
|
|
2049
2748
|
:items="items"
|
|
2050
|
-
:caption="args.caption"
|
|
2051
2749
|
:server-items-length="serverItemsLength"
|
|
2052
2750
|
:loading="loading"
|
|
2053
|
-
:show-filters="args.showFilters"
|
|
2054
|
-
:suffix="args.suffix"
|
|
2055
|
-
:density="args.density"
|
|
2056
|
-
:striped="args.striped"
|
|
2057
|
-
:resizable-columns="args.resizableColumns"
|
|
2058
2751
|
@update:options="fetchData"
|
|
2059
2752
|
>
|
|
2060
2753
|
<template #filter.custom="{ header, value, updateFilter }">
|
|
@@ -2071,8 +2764,10 @@ export const CustomFilterSlot: Story = {
|
|
|
2071
2764
|
color="primary"
|
|
2072
2765
|
bg-color="white"
|
|
2073
2766
|
@update:model-value="(val) => {
|
|
2074
|
-
//
|
|
2075
|
-
updateFilter(val)
|
|
2767
|
+
// Use updateFilter provided by the slot props
|
|
2768
|
+
updateFilter(val);
|
|
2769
|
+
// Also update our local state
|
|
2770
|
+
handleFilterChange(val);
|
|
2076
2771
|
}"
|
|
2077
2772
|
/>
|
|
2078
2773
|
</div>
|
|
@@ -2089,73 +2784,73 @@ export const CustomFilterInputs: Story = {
|
|
|
2089
2784
|
{
|
|
2090
2785
|
name: 'Template',
|
|
2091
2786
|
code: `
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2787
|
+
<template>
|
|
2788
|
+
<SyServerTable
|
|
2789
|
+
v-model:options="options"
|
|
2790
|
+
:items="filteredUsers"
|
|
2791
|
+
:headers="headers"
|
|
2792
|
+
:server-items-length="totalFilteredUsers"
|
|
2793
|
+
:filter-input-config="filterInputConfig"
|
|
2794
|
+
:loading="state === StateEnum.PENDING"
|
|
2795
|
+
suffix="server-filter-text"
|
|
2796
|
+
:show-filters="true"
|
|
2797
|
+
@update:options="fetchData"
|
|
2798
|
+
/>
|
|
2799
|
+
</template>
|
|
2800
|
+
`,
|
|
2106
2801
|
},
|
|
2107
2802
|
{
|
|
2108
2803
|
name: 'Script',
|
|
2109
2804
|
code: `
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2805
|
+
<script setup lang="ts">
|
|
2806
|
+
import { ref } from 'vue'
|
|
2807
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
2808
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
2809
|
+
import type { DataOptions, FilterOption } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
2810
|
+
|
|
2811
|
+
interface User {
|
|
2812
|
+
firstname: string
|
|
2813
|
+
lastname: string
|
|
2814
|
+
email: string
|
|
2815
|
+
}
|
|
2816
|
+
|
|
2817
|
+
interface DataObj {
|
|
2818
|
+
items: User[]
|
|
2819
|
+
total: number
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2822
|
+
const totalFilteredUsers = ref(0)
|
|
2823
|
+
const filteredUsers = ref<User[]>([])
|
|
2824
|
+
const state = ref(StateEnum.IDLE)
|
|
2825
|
+
|
|
2826
|
+
const options = ref<DataOptions>({
|
|
2827
|
+
itemsPerPage: 5,
|
|
2828
|
+
page: 1,
|
|
2829
|
+
filters: [],
|
|
2830
|
+
})
|
|
2831
|
+
|
|
2832
|
+
const headers = [
|
|
2833
|
+
{
|
|
2834
|
+
title: 'Prénom',
|
|
2835
|
+
key: 'firstname',
|
|
2836
|
+
filterable: true,
|
|
2837
|
+
filterType: 'text'
|
|
2838
|
+
},
|
|
2839
|
+
{
|
|
2840
|
+
title: 'Nom',
|
|
2841
|
+
key: 'lastname',
|
|
2842
|
+
filterable: true,
|
|
2843
|
+
filterType: 'text'
|
|
2844
|
+
},
|
|
2845
|
+
{
|
|
2846
|
+
title: 'Email',
|
|
2847
|
+
key: 'email',
|
|
2848
|
+
filterable: true,
|
|
2849
|
+
filterType: 'text'
|
|
2850
|
+
}
|
|
2851
|
+
]
|
|
2852
|
+
|
|
2853
|
+
const filterInputConfig = {
|
|
2159
2854
|
filterInputConfig: {
|
|
2160
2855
|
variant: 'outlined',
|
|
2161
2856
|
density: 'comfortable',
|
|
@@ -2165,88 +2860,88 @@ export const CustomFilterInputs: Story = {
|
|
|
2165
2860
|
},
|
|
2166
2861
|
}
|
|
2167
2862
|
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2863
|
+
const fetchData = async (): Promise<void> => {
|
|
2864
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
2865
|
+
filteredUsers.value = items
|
|
2866
|
+
totalFilteredUsers.value = total
|
|
2867
|
+
}
|
|
2868
|
+
|
|
2869
|
+
const wait = async (ms: number) => {
|
|
2870
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
2871
|
+
}
|
|
2872
|
+
|
|
2873
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
2874
|
+
state.value = StateEnum.PENDING
|
|
2875
|
+
await wait(1000)
|
|
2876
|
+
|
|
2877
|
+
return new Promise((resolve) => {
|
|
2878
|
+
// Get all users
|
|
2879
|
+
let items: User[] = getUsers()
|
|
2880
|
+
|
|
2881
|
+
// Apply filters on server side
|
|
2882
|
+
if (filters && filters.length > 0) {
|
|
2883
|
+
filters.forEach((filter: FilterOption) => {
|
|
2884
|
+
const { key, value } = filter
|
|
2885
|
+
|
|
2886
|
+
items = items.filter(item => {
|
|
2887
|
+
const itemValue = item[key as keyof User]
|
|
2888
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
2889
|
+
})
|
|
2890
|
+
})
|
|
2891
|
+
}
|
|
2892
|
+
|
|
2893
|
+
const total = items.length
|
|
2894
|
+
|
|
2895
|
+
// Apply sorting
|
|
2896
|
+
if (sortBy && sortBy.length > 0) {
|
|
2897
|
+
items = items.sort((a, b) => {
|
|
2898
|
+
const key = sortBy[0].key as keyof User
|
|
2899
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
2900
|
+
|
|
2901
|
+
return String(a[key]) > String(b[key]) ? order : -order
|
|
2902
|
+
})
|
|
2903
|
+
}
|
|
2904
|
+
|
|
2905
|
+
// Apply pagination
|
|
2906
|
+
if (itemsPerPage > 0) {
|
|
2907
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2910
|
+
resolve({ items, total })
|
|
2911
|
+
state.value = StateEnum.RESOLVED
|
|
2912
|
+
})
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2915
|
+
const getUsers = (): User[] => {
|
|
2916
|
+
return [
|
|
2917
|
+
{ firstname: 'Virginie', lastname: 'Beauchesne', email: 'virginie.beauchesne@example.com' },
|
|
2918
|
+
{ firstname: 'Simone', lastname: 'Bellefeuille', email: 'simone.bellefeuille@example.com' },
|
|
2919
|
+
{ firstname: 'Étienne', lastname: 'Salois', email: 'etienne.salois@example.com' },
|
|
2920
|
+
{ firstname: 'Bernadette', lastname: 'Langelier', email: 'bernadette.langelier@example.com' },
|
|
2921
|
+
{ firstname: 'Agate', lastname: 'Roy', email: 'agate.roy@example.com' },
|
|
2922
|
+
{ firstname: 'Louis', lastname: 'Denis', email: 'louis.denis@example.com' },
|
|
2923
|
+
{ firstname: 'Édith', lastname: 'Cartier', email: 'edith.cartier@example.com' },
|
|
2924
|
+
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
2925
|
+
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
2926
|
+
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
2927
|
+
{ firstname: 'Martin', lastname: 'Lavoie', email: 'martin.lavoie@example.com' },
|
|
2928
|
+
{ firstname: 'Céline', lastname: 'Tremblay', email: 'celine.tremblay@example.com' },
|
|
2929
|
+
{ firstname: 'Jacques', lastname: 'Gagnon', email: 'jacques.gagnon@example.com' },
|
|
2930
|
+
{ firstname: 'Isabelle', lastname: 'Côté', email: 'isabelle.cote@example.com' },
|
|
2931
|
+
{ firstname: 'Philippe', lastname: 'Bouchard', email: 'philippe.bouchard@example.com' },
|
|
2932
|
+
]
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
// Initialize data
|
|
2936
|
+
fetchData()
|
|
2937
|
+
</script>
|
|
2938
|
+
`,
|
|
2244
2939
|
},
|
|
2245
2940
|
],
|
|
2246
2941
|
},
|
|
2247
2942
|
args: {
|
|
2248
|
-
serverItemsLength: 15,
|
|
2249
|
-
headers: [
|
|
2943
|
+
'serverItemsLength': 15,
|
|
2944
|
+
'headers': [
|
|
2250
2945
|
{
|
|
2251
2946
|
title: 'Prénom',
|
|
2252
2947
|
key: 'firstname',
|
|
@@ -2266,29 +2961,37 @@ export const CustomFilterInputs: Story = {
|
|
|
2266
2961
|
filterType: 'text',
|
|
2267
2962
|
},
|
|
2268
2963
|
],
|
|
2269
|
-
caption: '',
|
|
2270
|
-
options: {
|
|
2964
|
+
'caption': '',
|
|
2965
|
+
'options': {
|
|
2271
2966
|
itemsPerPage: 5,
|
|
2272
2967
|
page: 1,
|
|
2273
2968
|
filters: [],
|
|
2274
2969
|
},
|
|
2275
|
-
filterInputConfig: {
|
|
2970
|
+
'filterInputConfig': {
|
|
2276
2971
|
variant: 'outlined',
|
|
2277
2972
|
density: 'comfortable',
|
|
2278
2973
|
hideDetails: true,
|
|
2279
2974
|
clearable: false,
|
|
2280
2975
|
disableErrorHandling: true,
|
|
2281
2976
|
},
|
|
2282
|
-
showFilters: true,
|
|
2283
|
-
suffix: 'server-filter-text',
|
|
2284
|
-
density: 'default',
|
|
2285
|
-
striped: false,
|
|
2977
|
+
'showFilters': true,
|
|
2978
|
+
'suffix': 'server-filter-text',
|
|
2979
|
+
'density': 'default',
|
|
2980
|
+
'striped': false,
|
|
2981
|
+
'onUpdate:options': fn(),
|
|
2286
2982
|
},
|
|
2287
2983
|
render(args) {
|
|
2288
2984
|
return {
|
|
2289
2985
|
components: { SyServerTable },
|
|
2290
2986
|
setup() {
|
|
2291
|
-
const options = ref(args.options)
|
|
2987
|
+
const options = ref({ ...args.options })
|
|
2988
|
+
|
|
2989
|
+
watch(options, (newVal) => {
|
|
2990
|
+
if (args.options) {
|
|
2991
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
2992
|
+
}
|
|
2993
|
+
}, { deep: true })
|
|
2994
|
+
|
|
2292
2995
|
const totalFilteredUsers = ref(0)
|
|
2293
2996
|
const filteredUsers = ref<Record<string, unknown>[]>([])
|
|
2294
2997
|
const state = ref(StateEnum.IDLE)
|
|
@@ -2299,8 +3002,817 @@ export const CustomFilterInputs: Story = {
|
|
|
2299
3002
|
// Simulate API call
|
|
2300
3003
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
2301
3004
|
|
|
2302
|
-
// Get all users
|
|
2303
|
-
let items = [
|
|
3005
|
+
// Get all users
|
|
3006
|
+
let items = [
|
|
3007
|
+
{ firstname: 'Virginie', lastname: 'Beauchesne', email: 'virginie.beauchesne@example.com' },
|
|
3008
|
+
{ firstname: 'Simone', lastname: 'Bellefeuille', email: 'simone.bellefeuille@example.com' },
|
|
3009
|
+
{ firstname: 'Étienne', lastname: 'Salois', email: 'etienne.salois@example.com' },
|
|
3010
|
+
{ firstname: 'Bernadette', lastname: 'Langelier', email: 'bernadette.langelier@example.com' },
|
|
3011
|
+
{ firstname: 'Agate', lastname: 'Roy', email: 'agate.roy@example.com' },
|
|
3012
|
+
{ firstname: 'Louis', lastname: 'Denis', email: 'louis.denis@example.com' },
|
|
3013
|
+
{ firstname: 'Édith', lastname: 'Cartier', email: 'edith.cartier@example.com' },
|
|
3014
|
+
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
3015
|
+
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
3016
|
+
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
3017
|
+
{ firstname: 'Martin', lastname: 'Lavoie', email: 'martin.lavoie@example.com' },
|
|
3018
|
+
{ firstname: 'Céline', lastname: 'Tremblay', email: 'celine.tremblay@example.com' },
|
|
3019
|
+
{ firstname: 'Jacques', lastname: 'Gagnon', email: 'jacques.gagnon@example.com' },
|
|
3020
|
+
{ firstname: 'Isabelle', lastname: 'Côté', email: 'isabelle.cote@example.com' },
|
|
3021
|
+
{ firstname: 'Philippe', lastname: 'Bouchard', email: 'philippe.bouchard@example.com' },
|
|
3022
|
+
]
|
|
3023
|
+
|
|
3024
|
+
// Apply filters on server side
|
|
3025
|
+
if (options.value?.filters && options.value.filters.length > 0) {
|
|
3026
|
+
options.value.filters.forEach((filter) => {
|
|
3027
|
+
const { key, value } = filter
|
|
3028
|
+
|
|
3029
|
+
items = items.filter((item) => {
|
|
3030
|
+
const itemValue = item[key]
|
|
3031
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
3032
|
+
})
|
|
3033
|
+
})
|
|
3034
|
+
}
|
|
3035
|
+
|
|
3036
|
+
const total = items.length
|
|
3037
|
+
|
|
3038
|
+
// Apply pagination
|
|
3039
|
+
const { page = 1, itemsPerPage = 10 } = options.value || {}
|
|
3040
|
+
if (itemsPerPage > 0) {
|
|
3041
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
3042
|
+
}
|
|
3043
|
+
|
|
3044
|
+
filteredUsers.value = items as Record<string, unknown>[]
|
|
3045
|
+
totalFilteredUsers.value = total
|
|
3046
|
+
state.value = StateEnum.RESOLVED
|
|
3047
|
+
}
|
|
3048
|
+
|
|
3049
|
+
// Initialize data
|
|
3050
|
+
fetchData()
|
|
3051
|
+
|
|
3052
|
+
return {
|
|
3053
|
+
args,
|
|
3054
|
+
filteredUsers,
|
|
3055
|
+
totalFilteredUsers,
|
|
3056
|
+
options,
|
|
3057
|
+
state,
|
|
3058
|
+
fetchData,
|
|
3059
|
+
StateEnum,
|
|
3060
|
+
}
|
|
3061
|
+
},
|
|
3062
|
+
template: `
|
|
3063
|
+
<div>
|
|
3064
|
+
<SyServerTable
|
|
3065
|
+
v-bind="args"
|
|
3066
|
+
v-model:options="options"
|
|
3067
|
+
:items="filteredUsers"
|
|
3068
|
+
:server-items-length="totalFilteredUsers"
|
|
3069
|
+
:loading="state === StateEnum.PENDING"
|
|
3070
|
+
@update:options="fetchData"
|
|
3071
|
+
/>
|
|
3072
|
+
</div>
|
|
3073
|
+
`,
|
|
3074
|
+
}
|
|
3075
|
+
},
|
|
3076
|
+
}
|
|
3077
|
+
|
|
3078
|
+
export const ManyServerTables: Story = {
|
|
3079
|
+
parameters: {
|
|
3080
|
+
sourceCode: [
|
|
3081
|
+
{
|
|
3082
|
+
name: 'Template',
|
|
3083
|
+
code: `
|
|
3084
|
+
<template>
|
|
3085
|
+
<div>
|
|
3086
|
+
<SyServerTable
|
|
3087
|
+
v-model:options="optionsTable1"
|
|
3088
|
+
:items="usersTable1"
|
|
3089
|
+
:headers="headers"
|
|
3090
|
+
:server-items-length="totalUsersTable1"
|
|
3091
|
+
:loading="stateTable1 === StateEnum.PENDING"
|
|
3092
|
+
suffix="table1"
|
|
3093
|
+
@update:options="fetchDataTable1"
|
|
3094
|
+
/>
|
|
3095
|
+
<SyServerTable
|
|
3096
|
+
v-model:options="optionsTable2"
|
|
3097
|
+
:items="usersTable2"
|
|
3098
|
+
:headers="headers"
|
|
3099
|
+
:server-items-length="totalUsersTable2"
|
|
3100
|
+
:loading="stateTable2 === StateEnum.PENDING"
|
|
3101
|
+
suffix="table2"
|
|
3102
|
+
@update:options="fetchDataTable2"
|
|
3103
|
+
/>
|
|
3104
|
+
</div>
|
|
3105
|
+
</template>
|
|
3106
|
+
`,
|
|
3107
|
+
},
|
|
3108
|
+
{
|
|
3109
|
+
name: 'Script',
|
|
3110
|
+
code: `
|
|
3111
|
+
<script setup lang="ts">
|
|
3112
|
+
import { ref } from 'vue'
|
|
3113
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
3114
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
3115
|
+
import type { DataOptions } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
3116
|
+
|
|
3117
|
+
interface User {
|
|
3118
|
+
[key: string]: string
|
|
3119
|
+
firstname: string
|
|
3120
|
+
lastname: string
|
|
3121
|
+
email: string
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
interface DataObj {
|
|
3125
|
+
items: User[]
|
|
3126
|
+
total: number
|
|
3127
|
+
}
|
|
3128
|
+
|
|
3129
|
+
const headers = [
|
|
3130
|
+
{ title: 'Nom', key: 'lastname' },
|
|
3131
|
+
{ title: 'Prénom', key: 'firstname' },
|
|
3132
|
+
{ title: 'Email', key: 'email' },
|
|
3133
|
+
]
|
|
3134
|
+
|
|
3135
|
+
// Table 1
|
|
3136
|
+
const totalUsersTable1 = ref(0)
|
|
3137
|
+
const usersTable1 = ref<User[]>([])
|
|
3138
|
+
const stateTable1 = ref(StateEnum.IDLE)
|
|
3139
|
+
const optionsTable1 = ref<DataOptions>({
|
|
3140
|
+
itemsPerPage: 5,
|
|
3141
|
+
sortBy: [{ key: 'lastname', order: 'asc' }],
|
|
3142
|
+
page: 1,
|
|
3143
|
+
})
|
|
3144
|
+
|
|
3145
|
+
const fetchDataTable1 = async (options?: DataOptions): Promise<void> => {
|
|
3146
|
+
const optionsToUse = options || optionsTable1.value
|
|
3147
|
+
const { items, total } = await getDataFromApi(optionsToUse)
|
|
3148
|
+
usersTable1.value = items
|
|
3149
|
+
totalUsersTable1.value = total
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
// Table 2
|
|
3153
|
+
const totalUsersTable2 = ref(0)
|
|
3154
|
+
const usersTable2 = ref<User[]>([])
|
|
3155
|
+
const stateTable2 = ref(StateEnum.IDLE)
|
|
3156
|
+
const optionsTable2 = ref<DataOptions>({
|
|
3157
|
+
itemsPerPage: 3,
|
|
3158
|
+
sortBy: [{ key: 'firstname', order: 'asc' }],
|
|
3159
|
+
page: 1,
|
|
3160
|
+
})
|
|
3161
|
+
|
|
3162
|
+
const fetchDataTable2 = async (options?: DataOptions): Promise<void> => {
|
|
3163
|
+
const optionsToUse = options || optionsTable2.value
|
|
3164
|
+
const { items, total } = await getDataFromApi(optionsToUse)
|
|
3165
|
+
usersTable2.value = items
|
|
3166
|
+
totalUsersTable2.value = total
|
|
3167
|
+
}
|
|
3168
|
+
|
|
3169
|
+
const wait = async (ms: number) => {
|
|
3170
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
3171
|
+
}
|
|
3172
|
+
|
|
3173
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage }: DataOptions): Promise<DataObj> => {
|
|
3174
|
+
const state = sortBy[0].key === 'lastname' ? stateTable1 : stateTable2
|
|
3175
|
+
state.value = StateEnum.PENDING
|
|
3176
|
+
await wait(1000)
|
|
3177
|
+
|
|
3178
|
+
return new Promise((resolve) => {
|
|
3179
|
+
let items: User[] = getUsers()
|
|
3180
|
+
const total = items.length
|
|
3181
|
+
|
|
3182
|
+
if (sortBy && sortBy.length > 0) {
|
|
3183
|
+
items = items.sort((a, b) => {
|
|
3184
|
+
const key = sortBy[0].key
|
|
3185
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
3186
|
+
|
|
3187
|
+
return a[key] > b[key] ? order : -order
|
|
3188
|
+
})
|
|
3189
|
+
}
|
|
3190
|
+
|
|
3191
|
+
if (itemsPerPage > 0) {
|
|
3192
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
3193
|
+
}
|
|
3194
|
+
|
|
3195
|
+
resolve({ items, total })
|
|
3196
|
+
state.value = StateEnum.RESOLVED
|
|
3197
|
+
})
|
|
3198
|
+
}
|
|
3199
|
+
|
|
3200
|
+
const getUsers = (): User[] => {
|
|
3201
|
+
return [
|
|
3202
|
+
{ firstname: 'Virginie', lastname: 'Beauchesne', email: 'virginie.beauchesne@example.com' },
|
|
3203
|
+
{ firstname: 'Simone', lastname: 'Bellefeuille', email: 'simone.bellefeuille@example.com' },
|
|
3204
|
+
{ firstname: 'Étienne', lastname: 'Salois', email: 'etienne.salois@example.com' },
|
|
3205
|
+
{ firstname: 'Bernadette', lastname: 'Langelier', email: 'bernadette.langelier@example.com' },
|
|
3206
|
+
{ firstname: 'Agate', lastname: 'Roy', email: 'agate.roy@example.com' },
|
|
3207
|
+
{ firstname: 'Louis', lastname: 'Denis', email: 'louis.denis@example.com' },
|
|
3208
|
+
{ firstname: 'Édith', lastname: 'Cartier', email: 'edith.cartier@example.com' },
|
|
3209
|
+
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
3210
|
+
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
3211
|
+
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
3212
|
+
]
|
|
3213
|
+
}
|
|
3214
|
+
|
|
3215
|
+
fetchDataTable1()
|
|
3216
|
+
fetchDataTable2()
|
|
3217
|
+
</script>
|
|
3218
|
+
`,
|
|
3219
|
+
},
|
|
3220
|
+
],
|
|
3221
|
+
},
|
|
3222
|
+
args: {
|
|
3223
|
+
'serverItemsLength': 15, // Add required serverItemsLength property
|
|
3224
|
+
'headers': [
|
|
3225
|
+
{ title: 'Nom', key: 'lastname' },
|
|
3226
|
+
{ title: 'Prénom', key: 'firstname' },
|
|
3227
|
+
{ title: 'Email', key: 'email' },
|
|
3228
|
+
],
|
|
3229
|
+
'caption': '',
|
|
3230
|
+
'suffix': 'multi',
|
|
3231
|
+
'density': 'default',
|
|
3232
|
+
'striped': false,
|
|
3233
|
+
'onUpdate:options': fn(),
|
|
3234
|
+
},
|
|
3235
|
+
render: (args) => {
|
|
3236
|
+
return {
|
|
3237
|
+
components: { SyServerTable },
|
|
3238
|
+
setup() {
|
|
3239
|
+
// Table 1
|
|
3240
|
+
const totalUsersTable1 = ref(0)
|
|
3241
|
+
const usersTable1 = ref<User[]>([])
|
|
3242
|
+
const stateTable1 = ref(StateEnum.IDLE)
|
|
3243
|
+
|
|
3244
|
+
const optionsTable1 = ref<Partial<DataOptions>>({
|
|
3245
|
+
itemsPerPage: 5,
|
|
3246
|
+
sortBy: [{ key: 'lastname', order: 'asc' }],
|
|
3247
|
+
page: 1,
|
|
3248
|
+
})
|
|
3249
|
+
|
|
3250
|
+
const fetchDataTable1 = async (options?: DataOptions): Promise<void> => {
|
|
3251
|
+
const optionsToUse = options || optionsTable1.value as DataOptions
|
|
3252
|
+
const { items, total } = await getDataFromApi(optionsToUse)
|
|
3253
|
+
usersTable1.value = items
|
|
3254
|
+
totalUsersTable1.value = total
|
|
3255
|
+
}
|
|
3256
|
+
|
|
3257
|
+
// Table 2
|
|
3258
|
+
const totalUsersTable2 = ref(0)
|
|
3259
|
+
const usersTable2 = ref<User[]>([])
|
|
3260
|
+
const stateTable2 = ref(StateEnum.IDLE)
|
|
3261
|
+
|
|
3262
|
+
const optionsTable2 = ref<Partial<DataOptions>>({
|
|
3263
|
+
itemsPerPage: 3,
|
|
3264
|
+
sortBy: [{ key: 'firstname', order: 'asc' }],
|
|
3265
|
+
page: 1,
|
|
3266
|
+
})
|
|
3267
|
+
|
|
3268
|
+
const fetchDataTable2 = async (options?: DataOptions): Promise<void> => {
|
|
3269
|
+
const optionsToUse = options || optionsTable2.value as DataOptions
|
|
3270
|
+
const { items, total } = await getDataFromApi(optionsToUse)
|
|
3271
|
+
usersTable2.value = items
|
|
3272
|
+
totalUsersTable2.value = total
|
|
3273
|
+
}
|
|
3274
|
+
|
|
3275
|
+
const wait = async (ms: number) => {
|
|
3276
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
3277
|
+
}
|
|
3278
|
+
|
|
3279
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage }: DataOptions): Promise<DataObj> => {
|
|
3280
|
+
const state = sortBy[0].key === 'lastname' ? stateTable1 : stateTable2
|
|
3281
|
+
state.value = StateEnum.PENDING
|
|
3282
|
+
await wait(1000)
|
|
3283
|
+
|
|
3284
|
+
return new Promise((resolve) => {
|
|
3285
|
+
let items: User[] = getUsers()
|
|
3286
|
+
const total = items.length
|
|
3287
|
+
|
|
3288
|
+
if (sortBy && sortBy.length > 0) {
|
|
3289
|
+
items = items.sort((a, b) => {
|
|
3290
|
+
const key = sortBy[0].key
|
|
3291
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
3292
|
+
|
|
3293
|
+
return a[key] > b[key] ? order : -order
|
|
3294
|
+
})
|
|
3295
|
+
}
|
|
3296
|
+
|
|
3297
|
+
if (itemsPerPage > 0) {
|
|
3298
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
3299
|
+
}
|
|
3300
|
+
|
|
3301
|
+
resolve({ items, total })
|
|
3302
|
+
state.value = StateEnum.RESOLVED
|
|
3303
|
+
})
|
|
3304
|
+
}
|
|
3305
|
+
|
|
3306
|
+
const getUsers = (): User[] => {
|
|
3307
|
+
return [
|
|
3308
|
+
{ firstname: 'Virginie', lastname: 'Beauchesne', email: 'virginie.beauchesne@example.com' },
|
|
3309
|
+
{ firstname: 'Simone', lastname: 'Bellefeuille', email: 'simone.bellefeuille@example.com' },
|
|
3310
|
+
{ firstname: 'Étienne', lastname: 'Salois', email: 'etienne.salois@example.com' },
|
|
3311
|
+
{ firstname: 'Bernadette', lastname: 'Langelier', email: 'bernadette.langelier@example.com' },
|
|
3312
|
+
{ firstname: 'Agate', lastname: 'Roy', email: 'agate.roy@example.com' },
|
|
3313
|
+
{ firstname: 'Louis', lastname: 'Denis', email: 'louis.denis@example.com' },
|
|
3314
|
+
{ firstname: 'Édith', lastname: 'Cartier', email: 'edith.cartier@example.com' },
|
|
3315
|
+
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
3316
|
+
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
3317
|
+
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
3318
|
+
]
|
|
3319
|
+
}
|
|
3320
|
+
|
|
3321
|
+
// Chargement initial des données
|
|
3322
|
+
fetchDataTable1()
|
|
3323
|
+
fetchDataTable2()
|
|
3324
|
+
|
|
3325
|
+
return {
|
|
3326
|
+
args,
|
|
3327
|
+
usersTable1,
|
|
3328
|
+
totalUsersTable1,
|
|
3329
|
+
optionsTable1,
|
|
3330
|
+
stateTable1,
|
|
3331
|
+
fetchDataTable1,
|
|
3332
|
+
usersTable2,
|
|
3333
|
+
totalUsersTable2,
|
|
3334
|
+
optionsTable2,
|
|
3335
|
+
stateTable2,
|
|
3336
|
+
fetchDataTable2,
|
|
3337
|
+
StateEnum,
|
|
3338
|
+
}
|
|
3339
|
+
},
|
|
3340
|
+
template: `
|
|
3341
|
+
<div>
|
|
3342
|
+
<SyServerTable
|
|
3343
|
+
v-bind="args"
|
|
3344
|
+
v-model:options="optionsTable1"
|
|
3345
|
+
:items="usersTable1"
|
|
3346
|
+
:server-items-length="totalUsersTable1"
|
|
3347
|
+
:loading="stateTable1 === StateEnum.PENDING"
|
|
3348
|
+
suffix="table1"
|
|
3349
|
+
class="mb-10"
|
|
3350
|
+
@update:options="fetchDataTable1"
|
|
3351
|
+
/>
|
|
3352
|
+
<SyServerTable
|
|
3353
|
+
v-bind="args"
|
|
3354
|
+
v-model:options="optionsTable2"
|
|
3355
|
+
:items="usersTable2"
|
|
3356
|
+
:server-items-length="totalUsersTable2"
|
|
3357
|
+
:loading="stateTable2 === StateEnum.PENDING"
|
|
3358
|
+
suffix="table2"
|
|
3359
|
+
@update:options="fetchDataTable2"
|
|
3360
|
+
/>
|
|
3361
|
+
</div>
|
|
3362
|
+
`,
|
|
3363
|
+
}
|
|
3364
|
+
},
|
|
3365
|
+
}
|
|
3366
|
+
|
|
3367
|
+
export const DataAlignment: Story = {
|
|
3368
|
+
parameters: {
|
|
3369
|
+
sourceCode: [
|
|
3370
|
+
{
|
|
3371
|
+
name: 'Template',
|
|
3372
|
+
code: `
|
|
3373
|
+
<template>
|
|
3374
|
+
<SyServerTable
|
|
3375
|
+
v-model:options="options"
|
|
3376
|
+
:items="users"
|
|
3377
|
+
:headers="headers"
|
|
3378
|
+
:server-items-length="totalUsers"
|
|
3379
|
+
:loading="state === StateEnum.PENDING"
|
|
3380
|
+
suffix="server-resizable-columns"
|
|
3381
|
+
@update:options="fetchData"
|
|
3382
|
+
/>
|
|
3383
|
+
</template>
|
|
3384
|
+
`,
|
|
3385
|
+
},
|
|
3386
|
+
{
|
|
3387
|
+
name: 'Script',
|
|
3388
|
+
code: `
|
|
3389
|
+
<script setup lang="ts">
|
|
3390
|
+
import { ref, watch } from 'vue'
|
|
3391
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
3392
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
3393
|
+
import type { DataOptions } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
3394
|
+
|
|
3395
|
+
const totalUsers = ref(0)
|
|
3396
|
+
const users = ref<User[]>([])
|
|
3397
|
+
const state = ref(StateEnum.IDLE)
|
|
3398
|
+
|
|
3399
|
+
const options = ref({
|
|
3400
|
+
itemsPerPage: 5,
|
|
3401
|
+
sortBy: [{ key: 'lastname', order: 'asc' }],
|
|
3402
|
+
page: 1,
|
|
3403
|
+
})
|
|
3404
|
+
|
|
3405
|
+
const headers = [
|
|
3406
|
+
{
|
|
3407
|
+
title: 'ID',
|
|
3408
|
+
key: 'id',
|
|
3409
|
+
align: 'center',
|
|
3410
|
+
},
|
|
3411
|
+
{
|
|
3412
|
+
title: 'Nom',
|
|
3413
|
+
key: 'lastname',
|
|
3414
|
+
align: 'start',
|
|
3415
|
+
},
|
|
3416
|
+
{
|
|
3417
|
+
title: 'Date de naissance',
|
|
3418
|
+
key: 'birthdate',
|
|
3419
|
+
align: 'center',
|
|
3420
|
+
},
|
|
3421
|
+
{
|
|
3422
|
+
title: 'NIR',
|
|
3423
|
+
key: 'nir',
|
|
3424
|
+
align: 'end',
|
|
3425
|
+
},
|
|
3426
|
+
]
|
|
3427
|
+
|
|
3428
|
+
const fetchData = async (): Promise<void> => {
|
|
3429
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
3430
|
+
users.value = items
|
|
3431
|
+
totalUsers.value = total
|
|
3432
|
+
}
|
|
3433
|
+
|
|
3434
|
+
const wait = async (ms: number) => {
|
|
3435
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage }: DataOptions) => {
|
|
3439
|
+
state.value = StateEnum.PENDING
|
|
3440
|
+
await wait(1000)
|
|
3441
|
+
|
|
3442
|
+
return new Promise((resolve) => {
|
|
3443
|
+
let items: User[] = getUsers()
|
|
3444
|
+
const total = items.length
|
|
3445
|
+
|
|
3446
|
+
if (sortBy && sortBy.length > 0) {
|
|
3447
|
+
items = items.sort((a, b) => {
|
|
3448
|
+
const key = sortBy[0].key
|
|
3449
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
3450
|
+
|
|
3451
|
+
return a[key] > b[key] ? order : -order
|
|
3452
|
+
})
|
|
3453
|
+
}
|
|
3454
|
+
|
|
3455
|
+
if (itemsPerPage > 0) {
|
|
3456
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3459
|
+
resolve({ items, total })
|
|
3460
|
+
state.value = StateEnum.RESOLVED
|
|
3461
|
+
})
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3464
|
+
const getUsers = () => {
|
|
3465
|
+
return [
|
|
3466
|
+
{
|
|
3467
|
+
id: '1',
|
|
3468
|
+
lastname: 'Lefebvre',
|
|
3469
|
+
birthdate: '18/02/1989',
|
|
3470
|
+
nir: '1 89 02 75 120 005 79',
|
|
3471
|
+
},
|
|
3472
|
+
{
|
|
3473
|
+
id: '2',
|
|
3474
|
+
lastname: 'Richard',
|
|
3475
|
+
birthdate: '22/05/1991',
|
|
3476
|
+
nir: '2 91 05 75 120 005 76',
|
|
3477
|
+
},
|
|
3478
|
+
{
|
|
3479
|
+
id: '3',
|
|
3480
|
+
lastname: 'Fournier',
|
|
3481
|
+
birthdate: '11/11/2000',
|
|
3482
|
+
nir: '2 00 11 42 120 008 87',
|
|
3483
|
+
},
|
|
3484
|
+
]
|
|
3485
|
+
}
|
|
3486
|
+
|
|
3487
|
+
fetchData()
|
|
3488
|
+
</script>
|
|
3489
|
+
`,
|
|
3490
|
+
},
|
|
3491
|
+
],
|
|
3492
|
+
},
|
|
3493
|
+
args: {
|
|
3494
|
+
'options': {
|
|
3495
|
+
itemsPerPage: 5,
|
|
3496
|
+
sortBy: [{ key: 'lastname', order: 'asc' }],
|
|
3497
|
+
page: 1,
|
|
3498
|
+
},
|
|
3499
|
+
'headers': [
|
|
3500
|
+
{
|
|
3501
|
+
title: 'ID',
|
|
3502
|
+
key: 'id',
|
|
3503
|
+
align: 'center',
|
|
3504
|
+
},
|
|
3505
|
+
{
|
|
3506
|
+
title: 'Nom',
|
|
3507
|
+
key: 'lastname',
|
|
3508
|
+
align: 'start',
|
|
3509
|
+
},
|
|
3510
|
+
{
|
|
3511
|
+
title: 'Date de naissance',
|
|
3512
|
+
key: 'birthdate',
|
|
3513
|
+
align: 'center',
|
|
3514
|
+
},
|
|
3515
|
+
{
|
|
3516
|
+
title: 'NIR',
|
|
3517
|
+
key: 'nir',
|
|
3518
|
+
align: 'end',
|
|
3519
|
+
},
|
|
3520
|
+
],
|
|
3521
|
+
'caption': '',
|
|
3522
|
+
'serverItemsLength': 3,
|
|
3523
|
+
'suffix': 'server-resizable-columns',
|
|
3524
|
+
'density': 'default',
|
|
3525
|
+
'striped': false,
|
|
3526
|
+
'onUpdate:options': fn(),
|
|
3527
|
+
},
|
|
3528
|
+
render: (args) => {
|
|
3529
|
+
return {
|
|
3530
|
+
components: { SyServerTable },
|
|
3531
|
+
setup() {
|
|
3532
|
+
const totalUsers = ref(0)
|
|
3533
|
+
const users = ref<User[]>([])
|
|
3534
|
+
const state = ref(StateEnum.IDLE)
|
|
3535
|
+
|
|
3536
|
+
const options = ref({ ...args.options })
|
|
3537
|
+
|
|
3538
|
+
watch(options, (newVal) => {
|
|
3539
|
+
if (args.options) {
|
|
3540
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
3541
|
+
}
|
|
3542
|
+
}, { deep: true })
|
|
3543
|
+
|
|
3544
|
+
const fetchData = async (): Promise<void> => {
|
|
3545
|
+
// @ts-expect-error - fetchData is not defined
|
|
3546
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
3547
|
+
users.value = items
|
|
3548
|
+
totalUsers.value = total
|
|
3549
|
+
}
|
|
3550
|
+
|
|
3551
|
+
const wait = async (ms: number) => {
|
|
3552
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
3553
|
+
}
|
|
3554
|
+
|
|
3555
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage }: DataOptions) => {
|
|
3556
|
+
state.value = StateEnum.PENDING
|
|
3557
|
+
await wait(1000)
|
|
3558
|
+
|
|
3559
|
+
return new Promise((resolve) => {
|
|
3560
|
+
let items = getUsers()
|
|
3561
|
+
const total = items.length
|
|
3562
|
+
|
|
3563
|
+
if (sortBy && sortBy.length > 0) {
|
|
3564
|
+
items = items.sort((a, b) => {
|
|
3565
|
+
const key = sortBy[0].key
|
|
3566
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
3567
|
+
|
|
3568
|
+
return a[key] > b[key] ? order : -order
|
|
3569
|
+
})
|
|
3570
|
+
}
|
|
3571
|
+
|
|
3572
|
+
if (itemsPerPage > 0) {
|
|
3573
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
resolve({ items, total })
|
|
3577
|
+
state.value = StateEnum.RESOLVED
|
|
3578
|
+
})
|
|
3579
|
+
}
|
|
3580
|
+
|
|
3581
|
+
const getUsers = () => {
|
|
3582
|
+
return [
|
|
3583
|
+
{
|
|
3584
|
+
id: '1',
|
|
3585
|
+
lastname: 'Lefebvre',
|
|
3586
|
+
birthdate: '18/02/1989',
|
|
3587
|
+
nir: '1 89 02 75 120 005 79',
|
|
3588
|
+
},
|
|
3589
|
+
{
|
|
3590
|
+
id: '2',
|
|
3591
|
+
lastname: 'Richard',
|
|
3592
|
+
birthdate: '22/05/1991',
|
|
3593
|
+
nir: '2 91 05 75 120 005 76',
|
|
3594
|
+
},
|
|
3595
|
+
{
|
|
3596
|
+
id: '3',
|
|
3597
|
+
lastname: 'Fournier',
|
|
3598
|
+
birthdate: '11/11/2000',
|
|
3599
|
+
nir: '2 00 11 42 120 008 87',
|
|
3600
|
+
},
|
|
3601
|
+
]
|
|
3602
|
+
}
|
|
3603
|
+
|
|
3604
|
+
fetchData()
|
|
3605
|
+
|
|
3606
|
+
return { args, users, state, fetchData, options, totalUsers, StateEnum }
|
|
3607
|
+
},
|
|
3608
|
+
template: `
|
|
3609
|
+
<SyServerTable
|
|
3610
|
+
v-bind="args"
|
|
3611
|
+
v-model:options="options"
|
|
3612
|
+
:items="users"
|
|
3613
|
+
:server-items-length="totalUsers"
|
|
3614
|
+
:loading="state === StateEnum.PENDING"
|
|
3615
|
+
suffix="server-data-alignment"
|
|
3616
|
+
@update:options="[fetchData, args['onUpdate:options']]"
|
|
3617
|
+
/>
|
|
3618
|
+
`,
|
|
3619
|
+
}
|
|
3620
|
+
},
|
|
3621
|
+
}
|
|
3622
|
+
|
|
3623
|
+
export const ResizableColumns: Story = {
|
|
3624
|
+
parameters: {
|
|
3625
|
+
sourceCode: [
|
|
3626
|
+
{
|
|
3627
|
+
name: 'Template',
|
|
3628
|
+
code: `
|
|
3629
|
+
<template>
|
|
3630
|
+
<SyServerTable
|
|
3631
|
+
v-model:options="options"
|
|
3632
|
+
:items="users"
|
|
3633
|
+
:headers="headers"
|
|
3634
|
+
:server-items-length="totalUsers"
|
|
3635
|
+
:loading="state === StateEnum.PENDING"
|
|
3636
|
+
:resizable-columns="true"
|
|
3637
|
+
suffix="server-resizable-columns"
|
|
3638
|
+
@update:options="fetchData"
|
|
3639
|
+
/>
|
|
3640
|
+
</template>
|
|
3641
|
+
`,
|
|
3642
|
+
},
|
|
3643
|
+
{
|
|
3644
|
+
name: 'Script',
|
|
3645
|
+
code: `
|
|
3646
|
+
<script setup lang="ts">
|
|
3647
|
+
import { ref, watch } from 'vue'
|
|
3648
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
3649
|
+
import { StateEnum } from '@cnamts/synapse/src/components/Tables/common/constants/StateEnum'
|
|
3650
|
+
import type { DataOptions } from '@cnamts/synapse/src/components/Tables/common/types'
|
|
3651
|
+
|
|
3652
|
+
interface User {
|
|
3653
|
+
[key: string]: string
|
|
3654
|
+
firstname: string
|
|
3655
|
+
lastname: string
|
|
3656
|
+
email: string
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3659
|
+
interface DataObj {
|
|
3660
|
+
items: User[]
|
|
3661
|
+
total: number
|
|
3662
|
+
}
|
|
3663
|
+
|
|
3664
|
+
const totalUsers = ref(0)
|
|
3665
|
+
const users = ref<User[]>([])
|
|
3666
|
+
const state = ref(StateEnum.IDLE)
|
|
3667
|
+
|
|
3668
|
+
const options = ref({
|
|
3669
|
+
itemsPerPage: 5,
|
|
3670
|
+
sortBy: [{ key: 'lastname', order: 'asc' }],
|
|
3671
|
+
page: 1,
|
|
3672
|
+
})
|
|
3673
|
+
|
|
3674
|
+
const headers = [
|
|
3675
|
+
{ title: 'Nom', key: 'lastname' },
|
|
3676
|
+
{ title: 'Prénom', key: 'firstname' },
|
|
3677
|
+
{ title: 'Email', key: 'email' },
|
|
3678
|
+
]
|
|
3679
|
+
|
|
3680
|
+
const fetchData = async (): Promise<void> => {
|
|
3681
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
3682
|
+
users.value = items
|
|
3683
|
+
totalUsers.value = total
|
|
3684
|
+
}
|
|
3685
|
+
|
|
3686
|
+
const wait = async (ms: number) => {
|
|
3687
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
3688
|
+
}
|
|
3689
|
+
|
|
3690
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
3691
|
+
state.value = StateEnum.PENDING
|
|
3692
|
+
await wait(1000)
|
|
3693
|
+
|
|
3694
|
+
return new Promise((resolve) => {
|
|
3695
|
+
let items: User[] = getUsers()
|
|
3696
|
+
const total = items.length
|
|
3697
|
+
|
|
3698
|
+
if (sortBy && sortBy.length > 0) {
|
|
3699
|
+
items = items.sort((a, b) => {
|
|
3700
|
+
const key = sortBy[0].key
|
|
3701
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
3702
|
+
|
|
3703
|
+
return a[key] > b[key] ? order : -order
|
|
3704
|
+
})
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3707
|
+
if (itemsPerPage > 0) {
|
|
3708
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
3709
|
+
}
|
|
3710
|
+
|
|
3711
|
+
resolve({ items, total })
|
|
3712
|
+
state.value = StateEnum.RESOLVED
|
|
3713
|
+
})
|
|
3714
|
+
}
|
|
3715
|
+
|
|
3716
|
+
const getUsers = (): User[] => {
|
|
3717
|
+
return [
|
|
3718
|
+
{ firstname: 'Virginie', lastname: 'Beauchesne', email: 'virginie.beauchesne@example.com' },
|
|
3719
|
+
{ firstname: 'Simone', lastname: 'Bellefeuille', email: 'simone.bellefeuille@example.com' },
|
|
3720
|
+
{ firstname: 'Étienne', lastname: 'Salois', email: 'etienne.salois@example.com' },
|
|
3721
|
+
{ firstname: 'Bernadette', lastname: 'Langelier', email: 'bernadette.langelier@example.com' },
|
|
3722
|
+
{ firstname: 'Agate', lastname: 'Roy', email: 'agate.roy@example.com' },
|
|
3723
|
+
{ firstname: 'Louis', lastname: 'Denis', email: 'louis.denis@example.com' },
|
|
3724
|
+
{ firstname: 'Édith', lastname: 'Cartier', email: 'edith.cartier@example.com' },
|
|
3725
|
+
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
3726
|
+
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
3727
|
+
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
3728
|
+
{ firstname: 'Serge', lastname: 'Rivard', email: 'serge.rivard@example.com' },
|
|
3729
|
+
{ firstname: 'Jacques', lastname: 'Demers', email: 'jacques.demers@example.com' },
|
|
3730
|
+
{ firstname: 'Aimée', lastname: 'Josseaume', email: 'aimee.josseaume@example.com' },
|
|
3731
|
+
{ firstname: 'Delphine', lastname: 'Robillard', email: 'delphine.robillard@example.com' },
|
|
3732
|
+
{ firstname: 'Alexandre', lastname: 'Lazure', email: 'alexandre.lazure@example.com' },
|
|
3733
|
+
]
|
|
3734
|
+
}
|
|
3735
|
+
|
|
3736
|
+
fetchData()
|
|
3737
|
+
</script>
|
|
3738
|
+
`,
|
|
3739
|
+
},
|
|
3740
|
+
],
|
|
3741
|
+
},
|
|
3742
|
+
args: {
|
|
3743
|
+
'options': {
|
|
3744
|
+
itemsPerPage: 5,
|
|
3745
|
+
sortBy: [{ key: 'lastname', order: 'asc' }],
|
|
3746
|
+
page: 1,
|
|
3747
|
+
},
|
|
3748
|
+
'headers': [
|
|
3749
|
+
{ title: 'Nom', key: 'lastname' },
|
|
3750
|
+
{ title: 'Prénom', key: 'firstname' },
|
|
3751
|
+
{ title: 'Email', key: 'email' },
|
|
3752
|
+
],
|
|
3753
|
+
'caption': '',
|
|
3754
|
+
'serverItemsLength': 15,
|
|
3755
|
+
'suffix': 'server-resizable-columns',
|
|
3756
|
+
'density': 'default',
|
|
3757
|
+
'striped': false,
|
|
3758
|
+
'resizableColumns': true,
|
|
3759
|
+
'onUpdate:options': fn(),
|
|
3760
|
+
},
|
|
3761
|
+
render: (args) => {
|
|
3762
|
+
return {
|
|
3763
|
+
components: { SyServerTable },
|
|
3764
|
+
setup() {
|
|
3765
|
+
const totalUsers = ref(0)
|
|
3766
|
+
const users = ref<User[]>([])
|
|
3767
|
+
const state = ref(StateEnum.IDLE)
|
|
3768
|
+
|
|
3769
|
+
const options = ref({ ...args.options })
|
|
3770
|
+
|
|
3771
|
+
watch(options, (newVal) => {
|
|
3772
|
+
if (args.options) {
|
|
3773
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
3774
|
+
}
|
|
3775
|
+
}, { deep: true })
|
|
3776
|
+
|
|
3777
|
+
const fetchData = async (): Promise<void> => {
|
|
3778
|
+
// @ts-expect-error - fetchData is not defined
|
|
3779
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
3780
|
+
users.value = items
|
|
3781
|
+
totalUsers.value = total
|
|
3782
|
+
}
|
|
3783
|
+
|
|
3784
|
+
const wait = async (ms: number) => {
|
|
3785
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
3786
|
+
}
|
|
3787
|
+
|
|
3788
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage }: DataOptions): Promise<DataObj> => {
|
|
3789
|
+
state.value = StateEnum.PENDING
|
|
3790
|
+
await wait(1000)
|
|
3791
|
+
|
|
3792
|
+
return new Promise((resolve) => {
|
|
3793
|
+
let items: User[] = getUsers()
|
|
3794
|
+
const total = items.length
|
|
3795
|
+
|
|
3796
|
+
if (sortBy && sortBy.length > 0) {
|
|
3797
|
+
items = items.sort((a, b) => {
|
|
3798
|
+
const key = sortBy[0].key
|
|
3799
|
+
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
3800
|
+
|
|
3801
|
+
return a[key] > b[key] ? order : -order
|
|
3802
|
+
})
|
|
3803
|
+
}
|
|
3804
|
+
|
|
3805
|
+
if (itemsPerPage > 0) {
|
|
3806
|
+
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
3807
|
+
}
|
|
3808
|
+
|
|
3809
|
+
resolve({ items, total })
|
|
3810
|
+
state.value = StateEnum.RESOLVED
|
|
3811
|
+
})
|
|
3812
|
+
}
|
|
3813
|
+
|
|
3814
|
+
const getUsers = (): User[] => {
|
|
3815
|
+
return [
|
|
2304
3816
|
{ firstname: 'Virginie', lastname: 'Beauchesne', email: 'virginie.beauchesne@example.com' },
|
|
2305
3817
|
{ firstname: 'Simone', lastname: 'Bellefeuille', email: 'simone.bellefeuille@example.com' },
|
|
2306
3818
|
{ firstname: 'Étienne', lastname: 'Salois', email: 'etienne.salois@example.com' },
|
|
@@ -2311,275 +3823,237 @@ export const CustomFilterInputs: Story = {
|
|
|
2311
3823
|
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
2312
3824
|
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
2313
3825
|
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
2314
|
-
{ firstname: '
|
|
2315
|
-
{ firstname: '
|
|
2316
|
-
{ firstname: '
|
|
2317
|
-
{ firstname: '
|
|
2318
|
-
{ firstname: '
|
|
3826
|
+
{ firstname: 'Serge', lastname: 'Rivard', email: 'serge.rivard@example.com' },
|
|
3827
|
+
{ firstname: 'Jacques', lastname: 'Demers', email: 'jacques.demers@example.com' },
|
|
3828
|
+
{ firstname: 'Aimée', lastname: 'Josseaume', email: 'aimee.josseaume@example.com' },
|
|
3829
|
+
{ firstname: 'Delphine', lastname: 'Robillard', email: 'delphine.robillard@example.com' },
|
|
3830
|
+
{ firstname: 'Alexandre', lastname: 'Lazure', email: 'alexandre.lazure@example.com' },
|
|
2319
3831
|
]
|
|
2320
|
-
|
|
2321
|
-
// Apply filters on server side
|
|
2322
|
-
if (options.value?.filters && options.value.filters.length > 0) {
|
|
2323
|
-
options.value.filters.forEach((filter) => {
|
|
2324
|
-
const { key, value } = filter
|
|
2325
|
-
|
|
2326
|
-
items = items.filter((item) => {
|
|
2327
|
-
const itemValue = item[key]
|
|
2328
|
-
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
2329
|
-
})
|
|
2330
|
-
})
|
|
2331
|
-
}
|
|
2332
|
-
|
|
2333
|
-
const total = items.length
|
|
2334
|
-
|
|
2335
|
-
// Apply pagination
|
|
2336
|
-
const { page = 1, itemsPerPage = 10 } = options.value || {}
|
|
2337
|
-
if (itemsPerPage > 0) {
|
|
2338
|
-
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
2339
|
-
}
|
|
2340
|
-
|
|
2341
|
-
filteredUsers.value = items as Record<string, unknown>[]
|
|
2342
|
-
totalFilteredUsers.value = total
|
|
2343
|
-
state.value = StateEnum.RESOLVED
|
|
2344
3832
|
}
|
|
2345
3833
|
|
|
2346
|
-
// Initialize data
|
|
2347
3834
|
fetchData()
|
|
2348
3835
|
|
|
2349
|
-
return {
|
|
2350
|
-
args,
|
|
2351
|
-
options,
|
|
2352
|
-
filteredUsers,
|
|
2353
|
-
totalFilteredUsers,
|
|
2354
|
-
state,
|
|
2355
|
-
fetchData,
|
|
2356
|
-
StateEnum,
|
|
2357
|
-
}
|
|
3836
|
+
return { args, users, state, fetchData, options, totalUsers, StateEnum }
|
|
2358
3837
|
},
|
|
2359
3838
|
template: `
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
:density="args.density"
|
|
2372
|
-
:striped="args.striped"
|
|
2373
|
-
:resizable-columns="args.resizableColumns"
|
|
2374
|
-
@update:options="fetchData"
|
|
2375
|
-
/>
|
|
2376
|
-
</div>
|
|
3839
|
+
<div>
|
|
3840
|
+
<SyServerTable
|
|
3841
|
+
v-bind="args"
|
|
3842
|
+
v-model:options="options"
|
|
3843
|
+
:items="users"
|
|
3844
|
+
:server-items-length="totalUsers"
|
|
3845
|
+
:loading="state === StateEnum.PENDING"
|
|
3846
|
+
suffix="server-resizable-columns"
|
|
3847
|
+
@update:options="fetchData"
|
|
3848
|
+
/>
|
|
3849
|
+
</div>
|
|
2377
3850
|
`,
|
|
2378
3851
|
}
|
|
2379
3852
|
},
|
|
2380
3853
|
}
|
|
2381
3854
|
|
|
2382
|
-
export const
|
|
3855
|
+
export const RowSelection: Story = {
|
|
3856
|
+
name: 'Row Selection',
|
|
2383
3857
|
parameters: {
|
|
2384
3858
|
sourceCode: [
|
|
2385
3859
|
{
|
|
2386
3860
|
name: 'Template',
|
|
2387
3861
|
code: `
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
`,
|
|
3862
|
+
<template>
|
|
3863
|
+
<SyServerTable
|
|
3864
|
+
v-model:options="options"
|
|
3865
|
+
v-model="selection"
|
|
3866
|
+
:headers="headers"
|
|
3867
|
+
:items="items"
|
|
3868
|
+
:serverItemsLength="items.length"
|
|
3869
|
+
show-select
|
|
3870
|
+
show-filters
|
|
3871
|
+
suffix="selection-server-table"
|
|
3872
|
+
/>
|
|
3873
|
+
<div v-if="selection.length" class="mt-4 pa-4 bg-grey-lighten-4">
|
|
3874
|
+
<h3 class="text-h6 mb-3">Item(s) sélectionné(s) ({{ selection.length }})</h3>
|
|
3875
|
+
<div v-for="(item, index) in selection" :key="index" class="mb-2 pa-2 bg-grey-lighten-3">
|
|
3876
|
+
<div><strong>Nom:</strong> {{ typeof item === 'object' ? item.lastname : users.find(i => JSON.stringify(i) === item)?.lastname }}</div>
|
|
3877
|
+
<div><strong>Prénom:</strong> {{ typeof item === 'object' ? item.firstname : users.find(i => JSON.stringify(i) === item)?.firstname }}</div>
|
|
3878
|
+
<div><strong>Email:</strong> {{ typeof item === 'object' ? item.email : users.find(i => JSON.stringify(i) === item)?.email }}</div>
|
|
3879
|
+
</div>
|
|
3880
|
+
</div>
|
|
3881
|
+
</div>
|
|
3882
|
+
</template>
|
|
3883
|
+
`,
|
|
2411
3884
|
},
|
|
2412
3885
|
{
|
|
2413
3886
|
name: 'Script',
|
|
2414
3887
|
code: `
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
return new Promise(resolve => setTimeout(resolve, ms))
|
|
2473
|
-
}
|
|
2474
|
-
|
|
2475
|
-
const getDataFromApi = async ({ sortBy, page, itemsPerPage }: DataOptions): Promise<DataObj> => {
|
|
2476
|
-
const state = sortBy[0].key === 'lastname' ? stateTable1 : stateTable2
|
|
2477
|
-
state.value = StateEnum.PENDING
|
|
2478
|
-
await wait(1000)
|
|
2479
|
-
|
|
2480
|
-
return new Promise((resolve) => {
|
|
2481
|
-
let items: User[] = getUsers()
|
|
2482
|
-
const total = items.length
|
|
2483
|
-
|
|
2484
|
-
if (sortBy && sortBy.length > 0) {
|
|
2485
|
-
items = items.sort((a, b) => {
|
|
2486
|
-
const key = sortBy[0].key
|
|
2487
|
-
const order = sortBy[0].order === 'asc' ? 1 : -1
|
|
2488
|
-
|
|
2489
|
-
return a[key] > b[key] ? order : -order
|
|
2490
|
-
})
|
|
2491
|
-
}
|
|
2492
|
-
|
|
2493
|
-
if (itemsPerPage > 0) {
|
|
2494
|
-
items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
|
|
2495
|
-
}
|
|
2496
|
-
|
|
2497
|
-
resolve({ items, total })
|
|
2498
|
-
state.value = StateEnum.RESOLVED
|
|
2499
|
-
})
|
|
2500
|
-
}
|
|
2501
|
-
|
|
2502
|
-
const getUsers = (): User[] => {
|
|
2503
|
-
return [
|
|
2504
|
-
{ firstname: 'Virginie', lastname: 'Beauchesne', email: 'virginie.beauchesne@example.com' },
|
|
2505
|
-
{ firstname: 'Simone', lastname: 'Bellefeuille', email: 'simone.bellefeuille@example.com' },
|
|
2506
|
-
{ firstname: 'Étienne', lastname: 'Salois', email: 'etienne.salois@example.com' },
|
|
2507
|
-
{ firstname: 'Bernadette', lastname: 'Langelier', email: 'bernadette.langelier@example.com' },
|
|
2508
|
-
{ firstname: 'Agate', lastname: 'Roy', email: 'agate.roy@example.com' },
|
|
2509
|
-
{ firstname: 'Louis', lastname: 'Denis', email: 'louis.denis@example.com' },
|
|
2510
|
-
{ firstname: 'Édith', lastname: 'Cartier', email: 'edith.cartier@example.com' },
|
|
2511
|
-
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
2512
|
-
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
2513
|
-
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
2514
|
-
]
|
|
2515
|
-
}
|
|
2516
|
-
</script>
|
|
2517
|
-
`,
|
|
3888
|
+
<script setup lang="ts">
|
|
3889
|
+
import { ref } from 'vue'
|
|
3890
|
+
import { SyServerTable } from '@cnamts/synapse'
|
|
3891
|
+
|
|
3892
|
+
const options = ref({
|
|
3893
|
+
itemsPerPage: 4,
|
|
3894
|
+
})
|
|
3895
|
+
|
|
3896
|
+
const headers = ref([
|
|
3897
|
+
{
|
|
3898
|
+
title: 'Nom',
|
|
3899
|
+
key: 'lastname',
|
|
3900
|
+
},
|
|
3901
|
+
{
|
|
3902
|
+
title: 'Prénom',
|
|
3903
|
+
key: 'firstname',
|
|
3904
|
+
},
|
|
3905
|
+
{
|
|
3906
|
+
title: 'Email',
|
|
3907
|
+
value: 'email',
|
|
3908
|
+
},
|
|
3909
|
+
])
|
|
3910
|
+
|
|
3911
|
+
const items = ref([
|
|
3912
|
+
{
|
|
3913
|
+
firstname: 'Virginie',
|
|
3914
|
+
lastname: 'Beauchesne',
|
|
3915
|
+
email: 'virginie.beauchesne@example.com',
|
|
3916
|
+
},
|
|
3917
|
+
{
|
|
3918
|
+
firstname: 'Simone',
|
|
3919
|
+
lastname: 'Bellefeuille',
|
|
3920
|
+
email: 'simone.bellefeuille@example.com',
|
|
3921
|
+
},
|
|
3922
|
+
{
|
|
3923
|
+
firstname: 'Étienne',
|
|
3924
|
+
lastname: 'Salois',
|
|
3925
|
+
email: 'etienne.salois@example.com',
|
|
3926
|
+
},
|
|
3927
|
+
{
|
|
3928
|
+
firstname: 'Thierry',
|
|
3929
|
+
lastname: 'Bobu',
|
|
3930
|
+
email: 'thierry.bobu@example.com',
|
|
3931
|
+
},
|
|
3932
|
+
{
|
|
3933
|
+
firstname: 'Bernadette',
|
|
3934
|
+
lastname: 'Langelier',
|
|
3935
|
+
email: 'bernadette.langelier@exemple.com'
|
|
3936
|
+
},
|
|
3937
|
+
{
|
|
3938
|
+
firstname: 'Agate',
|
|
3939
|
+
lastname: 'Roy',
|
|
3940
|
+
email: 'agate.roy@exemple.com'
|
|
3941
|
+
}
|
|
3942
|
+
])
|
|
3943
|
+
</script>
|
|
3944
|
+
`,
|
|
2518
3945
|
},
|
|
2519
3946
|
],
|
|
2520
3947
|
},
|
|
2521
3948
|
args: {
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
3949
|
+
'headers': [
|
|
3950
|
+
{
|
|
3951
|
+
title: 'Nom',
|
|
3952
|
+
key: 'lastname',
|
|
3953
|
+
},
|
|
3954
|
+
{
|
|
3955
|
+
title: 'Prénom',
|
|
3956
|
+
key: 'firstname',
|
|
3957
|
+
},
|
|
3958
|
+
{
|
|
3959
|
+
title: 'Email',
|
|
3960
|
+
value: 'email',
|
|
3961
|
+
},
|
|
3962
|
+
],
|
|
3963
|
+
'items': [
|
|
3964
|
+
{
|
|
3965
|
+
firstname: 'Virginie',
|
|
3966
|
+
lastname: 'Beauchesne',
|
|
3967
|
+
email: 'virginie.beauchesne@example.com',
|
|
3968
|
+
},
|
|
3969
|
+
{
|
|
3970
|
+
firstname: 'Simone',
|
|
3971
|
+
lastname: 'Bellefeuille',
|
|
3972
|
+
email: 'simone.bellefeuille@example.com',
|
|
3973
|
+
},
|
|
3974
|
+
{
|
|
3975
|
+
firstname: 'Étienne',
|
|
3976
|
+
lastname: 'Salois',
|
|
3977
|
+
email: 'etienne.salois@example.com',
|
|
3978
|
+
},
|
|
3979
|
+
{
|
|
3980
|
+
firstname: 'Thierry',
|
|
3981
|
+
lastname: 'Bobu',
|
|
3982
|
+
email: 'thierry.bobu@example.com',
|
|
3983
|
+
},
|
|
3984
|
+
{
|
|
3985
|
+
firstname: 'Bernadette',
|
|
3986
|
+
lastname: 'Langelier',
|
|
3987
|
+
email: 'bernadette.langelier@exemple.com',
|
|
3988
|
+
},
|
|
3989
|
+
{
|
|
3990
|
+
firstname: 'Agate',
|
|
3991
|
+
lastname: 'Roy',
|
|
3992
|
+
email: 'agate.roy@exemple.com',
|
|
3993
|
+
},
|
|
2527
3994
|
],
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
3995
|
+
'options': {
|
|
3996
|
+
itemsPerPage: 4,
|
|
3997
|
+
page: 1,
|
|
3998
|
+
filters: [],
|
|
3999
|
+
},
|
|
4000
|
+
'caption': '',
|
|
4001
|
+
'suffix': 'selection-server-table',
|
|
4002
|
+
'density': 'default',
|
|
4003
|
+
'striped': false,
|
|
4004
|
+
'showSelect': true,
|
|
4005
|
+
'showFilters': true,
|
|
4006
|
+
'serverItemsLength': 6,
|
|
4007
|
+
'onUpdate:options': fn(),
|
|
2532
4008
|
},
|
|
2533
|
-
render
|
|
4009
|
+
render(args) {
|
|
2534
4010
|
return {
|
|
2535
4011
|
components: { SyServerTable },
|
|
2536
4012
|
setup() {
|
|
2537
|
-
|
|
2538
|
-
const
|
|
2539
|
-
const
|
|
2540
|
-
const
|
|
2541
|
-
|
|
2542
|
-
const optionsTable1 = ref<Partial<DataOptions>>({
|
|
2543
|
-
itemsPerPage: 5,
|
|
2544
|
-
sortBy: [{ key: 'lastname', order: 'asc' }],
|
|
2545
|
-
page: 1,
|
|
2546
|
-
})
|
|
2547
|
-
|
|
2548
|
-
const fetchDataTable1 = async (): Promise<void> => {
|
|
2549
|
-
const { items, total } = await getDataFromApi(optionsTable1.value as DataOptions)
|
|
2550
|
-
usersTable1.value = items
|
|
2551
|
-
totalUsersTable1.value = total
|
|
2552
|
-
}
|
|
2553
|
-
|
|
2554
|
-
// Table 2
|
|
2555
|
-
const totalUsersTable2 = ref(0)
|
|
2556
|
-
const usersTable2 = ref<User[]>([])
|
|
2557
|
-
const stateTable2 = ref(StateEnum.IDLE)
|
|
2558
|
-
|
|
2559
|
-
const optionsTable2 = ref<Partial<DataOptions>>({
|
|
2560
|
-
itemsPerPage: 3,
|
|
2561
|
-
sortBy: [{ key: 'firstname', order: 'asc' }],
|
|
2562
|
-
page: 1,
|
|
2563
|
-
})
|
|
4013
|
+
const totalUsers = ref(0)
|
|
4014
|
+
const users = ref<User[]>([])
|
|
4015
|
+
const selection = ref([])
|
|
4016
|
+
const state = ref(StateEnum.IDLE)
|
|
2564
4017
|
|
|
2565
|
-
const
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
4018
|
+
const fetchData = async (): Promise<void> => {
|
|
4019
|
+
// Create a complete DataOptions object with all required properties
|
|
4020
|
+
const defaultOptions: DataOptions = {
|
|
4021
|
+
page: 1,
|
|
4022
|
+
itemsPerPage: 10,
|
|
4023
|
+
sortBy: [],
|
|
4024
|
+
multiSort: false,
|
|
4025
|
+
}
|
|
4026
|
+
const options = args.options ? { ...defaultOptions, ...args.options } : defaultOptions
|
|
4027
|
+
const { items, total } = await getDataFromApi(options)
|
|
4028
|
+
users.value = items
|
|
4029
|
+
totalUsers.value = total
|
|
2569
4030
|
}
|
|
2570
4031
|
|
|
2571
4032
|
const wait = async (ms: number) => {
|
|
2572
4033
|
return new Promise(resolve => setTimeout(resolve, ms))
|
|
2573
4034
|
}
|
|
2574
4035
|
|
|
2575
|
-
const getDataFromApi = async ({ sortBy, page, itemsPerPage }: DataOptions): Promise<DataObj> => {
|
|
2576
|
-
const state = sortBy[0].key === 'lastname' ? stateTable1 : stateTable2
|
|
4036
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
2577
4037
|
state.value = StateEnum.PENDING
|
|
2578
4038
|
await wait(1000)
|
|
2579
4039
|
|
|
2580
4040
|
return new Promise((resolve) => {
|
|
2581
4041
|
let items: User[] = getUsers()
|
|
2582
|
-
|
|
4042
|
+
let total = items.length // Changed from const to let
|
|
4043
|
+
|
|
4044
|
+
// Add filtering logic here
|
|
4045
|
+
if (filters && filters.length > 0) {
|
|
4046
|
+
filters.forEach((filter) => {
|
|
4047
|
+
const { key, value } = filter
|
|
4048
|
+
|
|
4049
|
+
items = items.filter((item) => {
|
|
4050
|
+
const itemValue = item[key]
|
|
4051
|
+
return String(itemValue).toLowerCase().includes(String(value).toLowerCase())
|
|
4052
|
+
})
|
|
4053
|
+
})
|
|
4054
|
+
// Update total after filtering
|
|
4055
|
+
total = items.length
|
|
4056
|
+
}
|
|
2583
4057
|
|
|
2584
4058
|
if (sortBy && sortBy.length > 0) {
|
|
2585
4059
|
items = items.sort((a, b) => {
|
|
@@ -2604,66 +4078,50 @@ export const ManyServerTables: Story = {
|
|
|
2604
4078
|
{ firstname: 'Virginie', lastname: 'Beauchesne', email: 'virginie.beauchesne@example.com' },
|
|
2605
4079
|
{ firstname: 'Simone', lastname: 'Bellefeuille', email: 'simone.bellefeuille@example.com' },
|
|
2606
4080
|
{ firstname: 'Étienne', lastname: 'Salois', email: 'etienne.salois@example.com' },
|
|
2607
|
-
{ firstname: '
|
|
2608
|
-
{ firstname: '
|
|
4081
|
+
{ firstname: 'Thierry', lastname: 'Bobu', email: 'thierry.bobu@example.com' },
|
|
4082
|
+
{ firstname: 'Bernadette', lastname: 'Langelier', email: 'bernadette.langelier@exemple.com' },
|
|
4083
|
+
{ firstname: 'Agate', lastname: 'Roy', email: 'agate.roy@exemple.com' },
|
|
2609
4084
|
{ firstname: 'Louis', lastname: 'Denis', email: 'louis.denis@example.com' },
|
|
2610
4085
|
{ firstname: 'Édith', lastname: 'Cartier', email: 'edith.cartier@example.com' },
|
|
2611
4086
|
{ firstname: 'Alphonse', lastname: 'Bouvier', email: 'alphonse.bouvier@example.com' },
|
|
2612
4087
|
{ firstname: 'Eustache', lastname: 'Dubois', email: 'eustache.dubois@example.com' },
|
|
2613
4088
|
{ firstname: 'Rosemarie', lastname: 'Quessy', email: 'rosemarie.quessy@example.com' },
|
|
4089
|
+
{ firstname: 'Serge', lastname: 'Rivard', email: 'serge.rivard@example.com' },
|
|
2614
4090
|
]
|
|
2615
4091
|
}
|
|
2616
4092
|
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
optionsTable1,
|
|
2622
|
-
stateTable1,
|
|
2623
|
-
fetchDataTable1,
|
|
2624
|
-
usersTable2,
|
|
2625
|
-
totalUsersTable2,
|
|
2626
|
-
optionsTable2,
|
|
2627
|
-
stateTable2,
|
|
2628
|
-
fetchDataTable2,
|
|
2629
|
-
StateEnum,
|
|
2630
|
-
}
|
|
4093
|
+
// Call fetchData on mount
|
|
4094
|
+
fetchData()
|
|
4095
|
+
|
|
4096
|
+
return { args, users, state, fetchData, totalUsers, selection, StateEnum }
|
|
2631
4097
|
},
|
|
2632
4098
|
template: `
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
:loading="stateTable2 === StateEnum.PENDING"
|
|
2655
|
-
:density="args.density"
|
|
2656
|
-
:striped="args.striped"
|
|
2657
|
-
suffix="table2"
|
|
2658
|
-
:resizable-columns="args.resizableColumns"
|
|
2659
|
-
@update:options="fetchDataTable2"
|
|
2660
|
-
/>
|
|
2661
|
-
</div>
|
|
2662
|
-
`,
|
|
4099
|
+
<div>
|
|
4100
|
+
<SyServerTable
|
|
4101
|
+
v-bind="args"
|
|
4102
|
+
v-model:options="args.options"
|
|
4103
|
+
v-model="selection"
|
|
4104
|
+
:items="users"
|
|
4105
|
+
:server-items-length="totalUsers"
|
|
4106
|
+
:loading="state === StateEnum.PENDING"
|
|
4107
|
+
suffix="selection-server-table"
|
|
4108
|
+
@update:options="fetchData"
|
|
4109
|
+
/>
|
|
4110
|
+
<div v-if="selection.length" class="mt-4 pa-4 bg-grey-lighten-4">
|
|
4111
|
+
<h3 class="text-h6 mb-3">Item(s) sélectionné(s) ({{ selection.length }})</h3>
|
|
4112
|
+
<div v-for="(item, index) in selection" :key="index" class="mb-2 pa-2 bg-grey-lighten-3">
|
|
4113
|
+
<div><strong>Nom:</strong> {{ typeof item === 'object' ? item.lastname : users.find(i => JSON.stringify(i) === item)?.lastname }}</div>
|
|
4114
|
+
<div><strong>Prénom:</strong> {{ typeof item === 'object' ? item.firstname : users.find(i => JSON.stringify(i) === item)?.firstname }}</div>
|
|
4115
|
+
<div><strong>Email:</strong> {{ typeof item === 'object' ? item.email : users.find(i => JSON.stringify(i) === item)?.email }}</div>
|
|
4116
|
+
</div>
|
|
4117
|
+
</div>
|
|
4118
|
+
</div>
|
|
4119
|
+
`,
|
|
2663
4120
|
}
|
|
2664
4121
|
},
|
|
2665
4122
|
}
|
|
2666
|
-
|
|
4123
|
+
|
|
4124
|
+
export const ColumnControls: StoryObj<typeof SyServerTable> = {
|
|
2667
4125
|
parameters: {
|
|
2668
4126
|
sourceCode: [
|
|
2669
4127
|
{
|
|
@@ -2676,8 +4134,8 @@ export const ResizableColumns: Story = {
|
|
|
2676
4134
|
:headers="headers"
|
|
2677
4135
|
:server-items-length="totalUsers"
|
|
2678
4136
|
:loading="state === StateEnum.PENDING"
|
|
2679
|
-
|
|
2680
|
-
|
|
4137
|
+
suffix="server-control-columns"
|
|
4138
|
+
enable-column-controls
|
|
2681
4139
|
@update:options="fetchData"
|
|
2682
4140
|
/>
|
|
2683
4141
|
</template>
|
|
@@ -2730,7 +4188,7 @@ export const ResizableColumns: Story = {
|
|
|
2730
4188
|
return new Promise(resolve => setTimeout(resolve, ms))
|
|
2731
4189
|
}
|
|
2732
4190
|
|
|
2733
|
-
const getDataFromApi = async ({ sortBy, page, itemsPerPage }: DataOptions): Promise<DataObj> => {
|
|
4191
|
+
const getDataFromApi = async ({ sortBy, page, itemsPerPage, filters }: DataOptions): Promise<DataObj> => {
|
|
2734
4192
|
state.value = StateEnum.PENDING
|
|
2735
4193
|
await wait(1000)
|
|
2736
4194
|
|
|
@@ -2775,28 +4233,31 @@ export const ResizableColumns: Story = {
|
|
|
2775
4233
|
{ firstname: 'Alexandre', lastname: 'Lazure', email: 'alexandre.lazure@example.com' },
|
|
2776
4234
|
]
|
|
2777
4235
|
}
|
|
4236
|
+
|
|
4237
|
+
fetchData()
|
|
2778
4238
|
</script>
|
|
2779
4239
|
`,
|
|
2780
4240
|
},
|
|
2781
4241
|
],
|
|
2782
4242
|
},
|
|
2783
4243
|
args: {
|
|
2784
|
-
options: {
|
|
4244
|
+
'options': {
|
|
2785
4245
|
itemsPerPage: 5,
|
|
2786
4246
|
sortBy: [{ key: 'lastname', order: 'asc' }],
|
|
2787
4247
|
page: 1,
|
|
2788
4248
|
},
|
|
2789
|
-
headers: [
|
|
4249
|
+
'headers': [
|
|
2790
4250
|
{ title: 'Nom', key: 'lastname' },
|
|
2791
4251
|
{ title: 'Prénom', key: 'firstname' },
|
|
2792
4252
|
{ title: 'Email', key: 'email' },
|
|
2793
4253
|
],
|
|
2794
|
-
caption: '',
|
|
2795
|
-
serverItemsLength: 15,
|
|
2796
|
-
suffix: 'server-
|
|
2797
|
-
density: 'default',
|
|
2798
|
-
striped: false,
|
|
2799
|
-
|
|
4254
|
+
'caption': '',
|
|
4255
|
+
'serverItemsLength': 15,
|
|
4256
|
+
'suffix': 'server-control-columns',
|
|
4257
|
+
'density': 'default',
|
|
4258
|
+
'striped': false,
|
|
4259
|
+
'enableColumnControls': true,
|
|
4260
|
+
'onUpdate:options': fn(),
|
|
2800
4261
|
},
|
|
2801
4262
|
render: (args) => {
|
|
2802
4263
|
return {
|
|
@@ -2806,9 +4267,17 @@ export const ResizableColumns: Story = {
|
|
|
2806
4267
|
const users = ref<User[]>([])
|
|
2807
4268
|
const state = ref(StateEnum.IDLE)
|
|
2808
4269
|
|
|
4270
|
+
const options = ref({ ...args.options })
|
|
4271
|
+
|
|
4272
|
+
watch(options, (newVal) => {
|
|
4273
|
+
if (args.options) {
|
|
4274
|
+
Object.assign(args.options, JSON.parse(JSON.stringify(newVal)))
|
|
4275
|
+
}
|
|
4276
|
+
}, { deep: true })
|
|
4277
|
+
|
|
2809
4278
|
const fetchData = async (): Promise<void> => {
|
|
2810
4279
|
// @ts-expect-error - fetchData is not defined
|
|
2811
|
-
const { items, total } = await getDataFromApi(
|
|
4280
|
+
const { items, total } = await getDataFromApi(options.value)
|
|
2812
4281
|
users.value = items
|
|
2813
4282
|
totalUsers.value = total
|
|
2814
4283
|
}
|
|
@@ -2863,21 +4332,19 @@ export const ResizableColumns: Story = {
|
|
|
2863
4332
|
]
|
|
2864
4333
|
}
|
|
2865
4334
|
|
|
2866
|
-
|
|
4335
|
+
fetchData()
|
|
4336
|
+
|
|
4337
|
+
return { args, users, state, fetchData, options, totalUsers, StateEnum }
|
|
2867
4338
|
},
|
|
2868
4339
|
template: `
|
|
2869
4340
|
<div>
|
|
2870
4341
|
<SyServerTable
|
|
2871
|
-
v-
|
|
4342
|
+
v-bind="args"
|
|
4343
|
+
v-model:options="options"
|
|
2872
4344
|
:items="users"
|
|
2873
|
-
:headers="args.headers"
|
|
2874
|
-
:caption="args.caption"
|
|
2875
4345
|
:server-items-length="totalUsers"
|
|
2876
4346
|
:loading="state === StateEnum.PENDING"
|
|
2877
|
-
|
|
2878
|
-
:density="args.density"
|
|
2879
|
-
:striped="args.striped"
|
|
2880
|
-
:resizable-columns="args.resizableColumns"
|
|
4347
|
+
suffix="server-control-columns"
|
|
2881
4348
|
@update:options="fetchData"
|
|
2882
4349
|
/>
|
|
2883
4350
|
</div>
|