@dative-gpi/foundation-shared-components 0.0.87 → 0.0.89
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/components/FSButton.vue +23 -7
- package/components/FSCalendar.vue +3 -1
- package/components/FSCalendarTwin.vue +16 -6
- package/components/FSCard.vue +9 -3
- package/components/FSCheckbox.vue +6 -2
- package/components/FSClickable.vue +33 -9
- package/components/FSDialog.vue +9 -5
- package/components/FSDialogMenu.vue +80 -0
- package/components/FSDialogSubmit.vue +0 -1
- package/components/FSEditImage.vue +196 -34
- package/components/FSImage.vue +21 -7
- package/components/FSLink.vue +4 -2
- package/components/FSOptionGroup.vue +61 -72
- package/components/FSOptionItem.vue +22 -7
- package/components/FSRadioGroup.vue +11 -3
- package/components/FSToggleSet.vue +22 -60
- package/components/FSWindow.vue +2 -0
- package/components/autocompletes/FSAutocompleteLanguage.vue +28 -22
- package/components/autocompletes/FSAutocompleteTimeZone.vue +117 -17
- package/components/buttons/FSButtonFileMini.vue +6 -1
- package/components/fields/FSAutocompleteField.vue +139 -72
- package/components/fields/FSBaseField.vue +134 -0
- package/components/fields/FSColorField.vue +1 -1
- package/components/fields/FSDateField.vue +124 -35
- package/components/fields/FSDateTimeField.vue +171 -63
- package/components/fields/FSIconField.vue +4 -2
- package/components/fields/FSNumberField.vue +9 -3
- package/components/fields/FSPasswordField.vue +15 -5
- package/components/fields/FSRichTextField.vue +34 -18
- package/components/fields/FSSearchField.vue +24 -8
- package/components/fields/FSSelectField.vue +254 -93
- package/components/fields/FSTagField.vue +15 -9
- package/components/fields/FSTextArea.vue +31 -59
- package/components/fields/FSTextField.vue +22 -70
- package/components/fields/FSTimeField.vue +20 -55
- package/components/fields/FSTimeSlotField.vue +13 -59
- package/components/lists/FSDataIteratorItem.vue +16 -4
- package/components/lists/FSDataTableUI.vue +433 -181
- package/components/lists/FSDraggable.vue +26 -13
- package/components/lists/FSFilterButton.vue +10 -4
- package/components/lists/FSHeaderButton.vue +3 -1
- package/components/lists/FSHiddenButton.vue +3 -1
- package/composables/useAutocomplete.ts +6 -7
- package/composables/useSlots.ts +6 -18
- package/package.json +4 -4
- package/styles/components/fs_base_field.scss +12 -0
- package/styles/components/fs_dialog.scss +10 -2
- package/styles/components/fs_dialog_menu.scss +11 -0
- package/styles/components/fs_draggable.scss +12 -0
- package/styles/components/fs_edit_image.scss +29 -2
- package/styles/components/fs_text_area.scss +0 -13
- package/styles/components/fs_text_field.scss +1 -14
- package/styles/components/index.scss +2 -0
- package/styles/globals/overrides.scss +4 -0
- package/components/autocompletes/FSAutocompleteOrganisation.vue +0 -77
|
@@ -1,48 +1,96 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<FSCol
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
<FSCol
|
|
3
|
+
gap="16px"
|
|
4
|
+
>
|
|
5
|
+
<FSRow
|
|
6
|
+
align="bottom-center"
|
|
7
|
+
:wrap="isExtraSmall ? false : true"
|
|
8
|
+
width="fill"
|
|
9
|
+
>
|
|
10
|
+
<template
|
|
11
|
+
v-if="$props.showSearch"
|
|
12
|
+
>
|
|
13
|
+
<FSSearchField
|
|
14
|
+
prependInnerIcon="mdi-magnify"
|
|
6
15
|
:hideHeader="true"
|
|
7
|
-
v-model="innerSearch"
|
|
8
|
-
|
|
16
|
+
v-model="innerSearch"
|
|
17
|
+
/>
|
|
18
|
+
<FSButton
|
|
19
|
+
v-if="filterableHeaders.length > 0"
|
|
9
20
|
prependIcon="mdi-filter-variant"
|
|
10
21
|
:variant="showFilters ? 'full' : 'standard'"
|
|
11
|
-
@click="showFilters = !showFilters"
|
|
22
|
+
@click="showFilters = !showFilters"
|
|
23
|
+
/>
|
|
12
24
|
</template>
|
|
13
|
-
<slot
|
|
25
|
+
<slot
|
|
26
|
+
v-if="!isExtraSmall"
|
|
27
|
+
name="toolbar"
|
|
28
|
+
/>
|
|
14
29
|
<v-spacer />
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
<FSRow
|
|
31
|
+
v-if="!$props.disableTable && !$props.disableIterator"
|
|
32
|
+
align="center-right"
|
|
33
|
+
>
|
|
34
|
+
<FSOptionGroup
|
|
35
|
+
:values="modeOptions"
|
|
36
|
+
:singleColor="true"
|
|
37
|
+
:required="true"
|
|
38
|
+
v-model="innerMode"
|
|
39
|
+
/>
|
|
40
|
+
</FSRow>
|
|
19
41
|
</FSRow>
|
|
20
|
-
<FSRow
|
|
21
|
-
|
|
22
|
-
|
|
42
|
+
<FSRow
|
|
43
|
+
v-if="isExtraSmall && hasToolbar"
|
|
44
|
+
>
|
|
45
|
+
<FSWrapGroup>
|
|
46
|
+
<slot
|
|
47
|
+
name="toolbar"
|
|
48
|
+
/>
|
|
49
|
+
</FSWrapGroup>
|
|
50
|
+
</FSRow>
|
|
51
|
+
<FSRow
|
|
52
|
+
v-if="showFiltersRow"
|
|
53
|
+
>
|
|
54
|
+
<template
|
|
55
|
+
v-if="showFilters"
|
|
56
|
+
>
|
|
57
|
+
<FSFilterButton
|
|
58
|
+
v-for="(header, index) in filterableHeaders"
|
|
23
59
|
:key="index"
|
|
24
60
|
:header="header"
|
|
25
61
|
:filters="filters[header.value]"
|
|
26
|
-
@update:filter="(value) => toggleFilter(header.value, value)"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
62
|
+
@update:filter="(value) => toggleFilter(header.value, value)"
|
|
63
|
+
>
|
|
64
|
+
<template
|
|
65
|
+
#default="{ filter }"
|
|
66
|
+
>
|
|
67
|
+
<slot
|
|
68
|
+
:name="filterSlot(header)"
|
|
69
|
+
v-bind="{ filter }"
|
|
70
|
+
/>
|
|
30
71
|
</template>
|
|
31
72
|
</FSFilterButton>
|
|
32
|
-
<FSChip
|
|
73
|
+
<FSChip
|
|
74
|
+
v-if="resetable"
|
|
33
75
|
variant="standard"
|
|
34
76
|
:label="$tr('ui.data-table.reset-filters', 'Reset')"
|
|
35
77
|
:color="ColorEnum.Error"
|
|
36
78
|
:editable="true"
|
|
37
|
-
@click="resetFilter"
|
|
79
|
+
@click="resetFilter"
|
|
80
|
+
/>
|
|
38
81
|
</template>
|
|
39
|
-
<FSHiddenButton
|
|
82
|
+
<FSHiddenButton
|
|
83
|
+
v-if="innerMode === 'table' && hiddenHeaders.length > 0"
|
|
40
84
|
:headers="hiddenHeaders"
|
|
41
85
|
:color="$props.color"
|
|
42
|
-
@update:show="(value) => updateHeader(value, 'hidden', false)"
|
|
86
|
+
@update:show="(value) => updateHeader(value, 'hidden', false)"
|
|
87
|
+
/>
|
|
43
88
|
</FSRow>
|
|
44
|
-
<template
|
|
45
|
-
|
|
89
|
+
<template
|
|
90
|
+
v-if="innerMode === 'table'"
|
|
91
|
+
>
|
|
92
|
+
<v-data-table
|
|
93
|
+
v-if="!isExtraSmall"
|
|
46
94
|
:selectStrategy="$props.singleSelect ? 'single' : 'all'"
|
|
47
95
|
:itemValue="$props.itemValue"
|
|
48
96
|
:showSelect="$props.showSelect"
|
|
@@ -65,66 +113,121 @@
|
|
|
65
113
|
@dragover.prevent
|
|
66
114
|
@drop:row="(event, row) => onDrop(event, row, 'tr.v-data-table__tr')"
|
|
67
115
|
@dragover="onDragOver($event, 'tr.v-data-table__tr', 'tbody')"
|
|
68
|
-
@dragleave="onDragLeave"
|
|
69
|
-
|
|
70
|
-
|
|
116
|
+
@dragleave="onDragLeave"
|
|
117
|
+
>
|
|
118
|
+
<template
|
|
119
|
+
#no-data
|
|
120
|
+
>
|
|
121
|
+
<FSText
|
|
122
|
+
font="text-overline"
|
|
123
|
+
>
|
|
71
124
|
{{ $tr("ui.data-table.empty", "No data") }}
|
|
72
125
|
</FSText>
|
|
73
126
|
</template>
|
|
74
|
-
<template
|
|
75
|
-
|
|
127
|
+
<template
|
|
128
|
+
#header.data-table-select="props"
|
|
129
|
+
>
|
|
130
|
+
<FSRow
|
|
131
|
+
v-if="!$props.singleSelect"
|
|
76
132
|
class="fs-data-table-select"
|
|
77
133
|
align="bottom-center"
|
|
78
|
-
width="hug"
|
|
79
|
-
|
|
134
|
+
width="hug"
|
|
135
|
+
>
|
|
136
|
+
<FSCheckbox
|
|
137
|
+
:indeterminate="props.someSelected && !props.allSelected"
|
|
80
138
|
:modelValue="props.allSelected"
|
|
81
|
-
@update:modelValue="toggleSelectAll(props.allSelected)"
|
|
139
|
+
@update:modelValue="toggleSelectAll(props.allSelected)"
|
|
140
|
+
/>
|
|
82
141
|
</FSRow>
|
|
83
142
|
</template>
|
|
84
|
-
<template
|
|
85
|
-
|
|
143
|
+
<template
|
|
144
|
+
#item.data-table-select="props"
|
|
145
|
+
>
|
|
146
|
+
<FSRow
|
|
147
|
+
class="fs-data-table-select"
|
|
86
148
|
align="bottom-center"
|
|
87
|
-
width="hug"
|
|
88
|
-
|
|
89
|
-
|
|
149
|
+
width="hug"
|
|
150
|
+
>
|
|
151
|
+
<FSCheckbox
|
|
152
|
+
:modelValue="innerValue.includes(props.item[$props.itemValue])"
|
|
153
|
+
@update:modelValue="toggleSelect(props.item)"
|
|
154
|
+
/>
|
|
90
155
|
</FSRow>
|
|
91
156
|
</template>
|
|
92
|
-
<template
|
|
93
|
-
|
|
157
|
+
<template
|
|
158
|
+
#item.data-table-draggable="props"
|
|
159
|
+
>
|
|
160
|
+
<FSDraggable
|
|
161
|
+
elementSelector="tr.v-data-table__tr"
|
|
94
162
|
:disabled="draggableDisabled"
|
|
95
163
|
:item="props"
|
|
96
|
-
@update:dragend="(event, dragged) => onDragEnd(event, dragged, 'tbody')"
|
|
97
|
-
|
|
164
|
+
@update:dragend="(event, dragged) => onDragEnd(event, dragged, 'tbody')"
|
|
165
|
+
>
|
|
166
|
+
<FSRow
|
|
167
|
+
class="fs-data-table-draggable"
|
|
98
168
|
align="bottom-center"
|
|
99
|
-
width="hug"
|
|
100
|
-
|
|
169
|
+
width="hug"
|
|
170
|
+
>
|
|
171
|
+
<FSIcon
|
|
172
|
+
size="l"
|
|
173
|
+
>
|
|
101
174
|
mdi-drag-vertical
|
|
102
175
|
</FSIcon>
|
|
103
176
|
</FSRow>
|
|
104
177
|
</FSDraggable>
|
|
105
178
|
</template>
|
|
106
|
-
<template
|
|
107
|
-
|
|
108
|
-
|
|
179
|
+
<template
|
|
180
|
+
#header.data-table-group="props"
|
|
181
|
+
>
|
|
182
|
+
<slot
|
|
183
|
+
name="header.data-table-group"
|
|
184
|
+
v-bind="props"
|
|
185
|
+
/>
|
|
109
186
|
</template>
|
|
110
|
-
<template
|
|
111
|
-
|
|
112
|
-
|
|
187
|
+
<template
|
|
188
|
+
#item.data-table-group="props"
|
|
189
|
+
>
|
|
190
|
+
<slot
|
|
191
|
+
name="item.data-table-group"
|
|
192
|
+
v-bind="props"
|
|
193
|
+
/>
|
|
113
194
|
</template>
|
|
114
|
-
<template
|
|
115
|
-
|
|
116
|
-
|
|
195
|
+
<template
|
|
196
|
+
#group-header="props"
|
|
197
|
+
>
|
|
198
|
+
<template
|
|
199
|
+
:ref="() => { if (!props.isGroupOpen(props.item)) { props.toggleGroup(props.item) } }"
|
|
200
|
+
/>
|
|
201
|
+
<tr
|
|
202
|
+
class="fs-data-table-group-header"
|
|
203
|
+
>
|
|
117
204
|
<td />
|
|
118
|
-
<td
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
205
|
+
<td
|
|
206
|
+
class="fs-data-table-group-header"
|
|
207
|
+
:colspan="extraHeaders.concat(innerHeaders).length + 1"
|
|
208
|
+
>
|
|
209
|
+
<slot
|
|
210
|
+
name="group-header"
|
|
211
|
+
v-bind="{ ...props, toggleSelectGroup }"
|
|
212
|
+
>
|
|
213
|
+
<FSCard
|
|
214
|
+
padding="12px 16px"
|
|
215
|
+
>
|
|
216
|
+
<FSRow
|
|
217
|
+
align="center-left"
|
|
218
|
+
width="hug"
|
|
219
|
+
>
|
|
220
|
+
<FSCheckbox
|
|
221
|
+
v-if="showSelect"
|
|
222
|
+
:modelValue="props.item.items.every((item) => innerValue.includes(item.key))"
|
|
223
|
+
:indeterminate="innerValue.some((id) => props.item.items.some((item) => item.key === id)) && !props.item.items.every((item) => innerValue.includes(item.key))"
|
|
224
|
+
@update:modelValue="toggleSelectGroup(props.item)"
|
|
225
|
+
/>
|
|
125
226
|
<FSText>
|
|
126
|
-
<slot
|
|
127
|
-
|
|
227
|
+
<slot
|
|
228
|
+
name="group-header-title"
|
|
229
|
+
v-bind="props"
|
|
230
|
+
>
|
|
128
231
|
{{ props.item.value }}
|
|
129
232
|
</slot>
|
|
130
233
|
</FSText>
|
|
@@ -134,58 +237,98 @@
|
|
|
134
237
|
</td>
|
|
135
238
|
</tr>
|
|
136
239
|
</template>
|
|
137
|
-
<template
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
240
|
+
<template
|
|
241
|
+
v-for="(header, index) in headersSlots"
|
|
242
|
+
#[header.slotName]="props"
|
|
243
|
+
>
|
|
244
|
+
<slot
|
|
245
|
+
:name="header.slotName"
|
|
246
|
+
v-bind="props"
|
|
247
|
+
>
|
|
248
|
+
<FSRow
|
|
249
|
+
align="center-left"
|
|
142
250
|
:wrap="false"
|
|
143
|
-
:key="index"
|
|
144
|
-
|
|
145
|
-
<slot
|
|
251
|
+
:key="index"
|
|
252
|
+
>
|
|
253
|
+
<slot
|
|
254
|
+
:name="`${header.slotName}-prepend`"
|
|
255
|
+
/>
|
|
256
|
+
<slot
|
|
257
|
+
:name="`${header.slotName}-title`"
|
|
258
|
+
>
|
|
146
259
|
<FSText>
|
|
147
260
|
{{ header.text }}
|
|
148
261
|
</FSText>
|
|
149
262
|
</slot>
|
|
150
|
-
<slot
|
|
263
|
+
<slot
|
|
264
|
+
:name="`${header.slotName}-append`"
|
|
265
|
+
/>
|
|
151
266
|
<v-spacer />
|
|
152
|
-
<slot
|
|
153
|
-
|
|
267
|
+
<slot
|
|
268
|
+
:name="`${header.slotName}-configuration`"
|
|
269
|
+
>
|
|
270
|
+
<FSHeaderButton
|
|
271
|
+
:first="index === 0"
|
|
154
272
|
:last="index === headersSlots.length - 1"
|
|
155
273
|
@update:hide="updateHeader(header, 'hidden', !header.hidden)"
|
|
156
274
|
@update:left="updateHeader(header, 'index', -1)"
|
|
157
|
-
@update:right="updateHeader(header, 'index', 1)"
|
|
158
|
-
|
|
275
|
+
@update:right="updateHeader(header, 'index', 1)"
|
|
276
|
+
/>
|
|
277
|
+
<FSButton
|
|
278
|
+
v-if="header.sortable"
|
|
159
279
|
variant="icon"
|
|
160
280
|
:color="sortColor(header, props)"
|
|
161
|
-
:icon="sortIcon(header, props)"
|
|
281
|
+
:icon="sortIcon(header, props)"
|
|
282
|
+
/>
|
|
162
283
|
</slot>
|
|
163
284
|
</FSRow>
|
|
164
285
|
</slot>
|
|
165
286
|
</template>
|
|
166
|
-
<template
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
287
|
+
<template
|
|
288
|
+
v-for="(item, index) in itemsSlots"
|
|
289
|
+
#[item.slotName]="props"
|
|
290
|
+
>
|
|
291
|
+
<div
|
|
292
|
+
class="fs-td-color"
|
|
293
|
+
>
|
|
294
|
+
<slot
|
|
295
|
+
:name="item.slotName"
|
|
296
|
+
v-bind="props"
|
|
297
|
+
>
|
|
298
|
+
<FSRow
|
|
299
|
+
align="center-left"
|
|
300
|
+
:key="index"
|
|
301
|
+
>
|
|
302
|
+
<FSSpan
|
|
303
|
+
font="text-overline"
|
|
304
|
+
>
|
|
174
305
|
{{ props.item[item.value] }}
|
|
175
306
|
</FSSpan>
|
|
176
307
|
</FSRow>
|
|
177
308
|
</slot>
|
|
178
309
|
</div>
|
|
179
310
|
</template>
|
|
180
|
-
<template
|
|
181
|
-
|
|
311
|
+
<template
|
|
312
|
+
#bottom
|
|
313
|
+
>
|
|
314
|
+
<FSRow
|
|
315
|
+
class="fs-data-table-footer"
|
|
182
316
|
align="center-right"
|
|
183
317
|
padding="16px"
|
|
184
|
-
gap="24px"
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
318
|
+
gap="24px"
|
|
319
|
+
>
|
|
320
|
+
<template
|
|
321
|
+
v-if="$props.modelValue.length"
|
|
322
|
+
>
|
|
323
|
+
<template
|
|
324
|
+
v-if="$props.modelValue.length >= innerItems.length"
|
|
325
|
+
>
|
|
326
|
+
<FSRow
|
|
327
|
+
gap="2px"
|
|
328
|
+
>
|
|
329
|
+
<FSText
|
|
330
|
+
font="text-button"
|
|
331
|
+
>
|
|
189
332
|
{{ $tr("ui.data-table.all-selected-bold", "Warning:") }}
|
|
190
333
|
</FSText>
|
|
191
334
|
<FSText>
|
|
@@ -193,50 +336,70 @@
|
|
|
193
336
|
</FSText>
|
|
194
337
|
</FSRow>
|
|
195
338
|
</template>
|
|
196
|
-
<template
|
|
339
|
+
<template
|
|
340
|
+
v-else
|
|
341
|
+
>
|
|
197
342
|
<FSText>
|
|
198
|
-
{{ $tr("ui.data-table.some-selected", "{0} element(s) selected", $props.modelValue.length.toString())
|
|
199
|
-
}}
|
|
343
|
+
{{ $tr("ui.data-table.some-selected", "{0} element(s) selected", $props.modelValue.length.toString()) }}
|
|
200
344
|
</FSText>
|
|
201
345
|
</template>
|
|
202
346
|
</template>
|
|
203
347
|
<v-spacer />
|
|
204
|
-
<FSRow
|
|
348
|
+
<FSRow
|
|
349
|
+
align="center-right"
|
|
205
350
|
width="hug"
|
|
206
|
-
:wrap="false"
|
|
207
|
-
|
|
351
|
+
:wrap="false"
|
|
352
|
+
>
|
|
353
|
+
<FSText
|
|
354
|
+
font="text-overline"
|
|
355
|
+
>
|
|
208
356
|
{{ $tr("ui.data-table.rows-per-page", "Rows per page") }}
|
|
209
357
|
</FSText>
|
|
210
|
-
<FSSelectField
|
|
358
|
+
<FSSelectField
|
|
359
|
+
class="fs-data-table-rows-per-page"
|
|
211
360
|
:clearable="false"
|
|
212
361
|
:hideHeader="true"
|
|
213
362
|
:items="rowsPerPageOptions"
|
|
214
|
-
v-model="innerRowsPerPage"
|
|
363
|
+
v-model="innerRowsPerPage"
|
|
364
|
+
/>
|
|
215
365
|
</FSRow>
|
|
216
|
-
<FSToggleSet
|
|
366
|
+
<FSToggleSet
|
|
367
|
+
v-if="innerRowsPerPage !== -1"
|
|
217
368
|
class="fs-data-table-pagination"
|
|
218
369
|
variant="slide"
|
|
219
370
|
:dash="pageOptions.length > 8"
|
|
220
371
|
:values="pageOptions"
|
|
221
372
|
:required="true"
|
|
222
|
-
v-model="innerPage"
|
|
373
|
+
v-model="innerPage"
|
|
374
|
+
/>
|
|
223
375
|
</FSRow>
|
|
224
376
|
</template>
|
|
225
|
-
<template
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
377
|
+
<template
|
|
378
|
+
v-for="(_, name) in innerSlots"
|
|
379
|
+
#[name]="props"
|
|
380
|
+
>
|
|
381
|
+
<slot
|
|
382
|
+
:name="name"
|
|
383
|
+
v-bind="props"
|
|
384
|
+
/>
|
|
229
385
|
</template>
|
|
230
386
|
</v-data-table>
|
|
231
|
-
<v-data-iterator
|
|
387
|
+
<v-data-iterator
|
|
388
|
+
v-else
|
|
232
389
|
class="fs-data-table-iterator"
|
|
233
390
|
:items="innerItems"
|
|
234
391
|
:page="innerPage"
|
|
235
|
-
:itemsPerPage="innerRowsPerPage"
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
392
|
+
:itemsPerPage="innerRowsPerPage"
|
|
393
|
+
>
|
|
394
|
+
<template
|
|
395
|
+
#default="{ items }"
|
|
396
|
+
>
|
|
397
|
+
<FSCol
|
|
398
|
+
class="fs-data-iterator-container"
|
|
399
|
+
width="fill"
|
|
400
|
+
>
|
|
401
|
+
<FSDraggable
|
|
402
|
+
v-for="(item, index) in items"
|
|
240
403
|
elementSelector=".fs-draggable-item"
|
|
241
404
|
:disabled="draggableDisabled"
|
|
242
405
|
:item="item"
|
|
@@ -245,10 +408,14 @@
|
|
|
245
408
|
@dragover="(event) => onDragOver(event, '.fs-draggable-item', '.fs-data-iterator-container')"
|
|
246
409
|
@drop="(event) => onDrop(event, item, '.fs-draggable-item')"
|
|
247
410
|
@dragleave="onDragLeave"
|
|
248
|
-
@dragover.prevent
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
411
|
+
@dragover.prevent
|
|
412
|
+
>
|
|
413
|
+
<slot
|
|
414
|
+
name="item.iterator"
|
|
415
|
+
v-bind="{ item, index }"
|
|
416
|
+
>
|
|
417
|
+
<FSDataIteratorItem
|
|
418
|
+
v-if="item.type === 'item'"
|
|
252
419
|
:itemColor="$props.rowColor ? $props.rowColor(item.raw) : ColorEnum.Background"
|
|
253
420
|
:headers="innerHeaders.filter(h => !$props.sneakyHeaders.includes(h.value))"
|
|
254
421
|
:showSelect="$props.showSelect"
|
|
@@ -257,38 +424,65 @@
|
|
|
257
424
|
:item="item.raw"
|
|
258
425
|
:key="index"
|
|
259
426
|
:modelValue="innerValue.includes(item.raw[$props.itemValue])"
|
|
260
|
-
@update:modelValue="toggleSelect"
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
427
|
+
@update:modelValue="toggleSelect"
|
|
428
|
+
>
|
|
429
|
+
<template
|
|
430
|
+
#item.top="props"
|
|
431
|
+
>
|
|
432
|
+
<slot
|
|
433
|
+
name="item.top"
|
|
434
|
+
v-bind="props"
|
|
435
|
+
/>
|
|
264
436
|
</template>
|
|
265
|
-
<template
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
437
|
+
<template
|
|
438
|
+
v-for="item in itemsSlots"
|
|
439
|
+
#[item.slotName]="props"
|
|
440
|
+
>
|
|
441
|
+
<slot
|
|
442
|
+
:name="item.slotName"
|
|
443
|
+
v-bind="props"
|
|
444
|
+
>
|
|
445
|
+
<FSSpan
|
|
446
|
+
font="text-overline"
|
|
447
|
+
>
|
|
270
448
|
{{ props.item[item.value] }}
|
|
271
449
|
</FSSpan>
|
|
272
450
|
</slot>
|
|
273
451
|
</template>
|
|
274
|
-
<template
|
|
275
|
-
|
|
276
|
-
|
|
452
|
+
<template
|
|
453
|
+
#item.bottom="props"
|
|
454
|
+
>
|
|
455
|
+
<slot
|
|
456
|
+
name="item.bottom"
|
|
457
|
+
v-bind="props"
|
|
458
|
+
/>
|
|
277
459
|
</template>
|
|
278
460
|
</FSDataIteratorItem>
|
|
279
461
|
</slot>
|
|
280
462
|
</FSDraggable>
|
|
281
463
|
</FSCol>
|
|
282
464
|
</template>
|
|
283
|
-
<template
|
|
284
|
-
|
|
465
|
+
<template
|
|
466
|
+
#footer
|
|
467
|
+
>
|
|
468
|
+
<FSRow
|
|
469
|
+
class="fs-data-table-footer"
|
|
285
470
|
align="center-right"
|
|
286
471
|
padding="16px"
|
|
287
|
-
gap="24px"
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
472
|
+
gap="24px"
|
|
473
|
+
>
|
|
474
|
+
<template
|
|
475
|
+
v-if="$props.modelValue.length"
|
|
476
|
+
>
|
|
477
|
+
<template
|
|
478
|
+
v-if="$props.modelValue.length >= innerItems.length"
|
|
479
|
+
>
|
|
480
|
+
<FSRow
|
|
481
|
+
gap="2px"
|
|
482
|
+
>
|
|
483
|
+
<FSText
|
|
484
|
+
font="text-button"
|
|
485
|
+
>
|
|
292
486
|
{{ $tr("ui.data-table.all-selected-bold", "Warning:") }}
|
|
293
487
|
</FSText>
|
|
294
488
|
<FSText>
|
|
@@ -296,47 +490,67 @@
|
|
|
296
490
|
</FSText>
|
|
297
491
|
</FSRow>
|
|
298
492
|
</template>
|
|
299
|
-
<template
|
|
493
|
+
<template
|
|
494
|
+
v-else
|
|
495
|
+
>
|
|
300
496
|
<FSText>
|
|
301
|
-
{{ $tr("ui.data-table.some-selected", "{0} element(s) selected", $props.modelValue.length.toString())
|
|
302
|
-
}}
|
|
497
|
+
{{ $tr("ui.data-table.some-selected", "{0} element(s) selected", $props.modelValue.length.toString()) }}
|
|
303
498
|
</FSText>
|
|
304
499
|
</template>
|
|
305
500
|
</template>
|
|
306
501
|
<v-spacer />
|
|
307
|
-
<FSRow
|
|
308
|
-
|
|
309
|
-
|
|
502
|
+
<FSRow
|
|
503
|
+
align="center-right"
|
|
504
|
+
:wrap="false"
|
|
505
|
+
>
|
|
506
|
+
<FSText
|
|
507
|
+
font="text-overline"
|
|
508
|
+
>
|
|
310
509
|
{{ $tr("ui.data-table.rows-per-page", "Rows per page") }}
|
|
311
510
|
</FSText>
|
|
312
|
-
<FSRow
|
|
313
|
-
|
|
511
|
+
<FSRow
|
|
512
|
+
width="120px"
|
|
513
|
+
>
|
|
514
|
+
<FSSelectField
|
|
515
|
+
class="fs-data-table-rows-per-page"
|
|
314
516
|
:clearable="false"
|
|
315
517
|
:hideHeader="true"
|
|
316
518
|
:items="rowsPerPageOptions"
|
|
317
|
-
v-model="innerRowsPerPage"
|
|
519
|
+
v-model="innerRowsPerPage"
|
|
520
|
+
/>
|
|
318
521
|
</FSRow>
|
|
319
522
|
</FSRow>
|
|
320
|
-
<FSToggleSet
|
|
523
|
+
<FSToggleSet
|
|
524
|
+
v-if="innerRowsPerPage !== -1"
|
|
321
525
|
class="fs-data-table-pagination"
|
|
322
526
|
variant="slide"
|
|
323
527
|
:dash="pageOptions.length > 8"
|
|
324
528
|
:values="pageOptions"
|
|
325
529
|
:required="true"
|
|
326
|
-
v-model="innerPage"
|
|
530
|
+
v-model="innerPage"
|
|
531
|
+
/>
|
|
327
532
|
</FSRow>
|
|
328
533
|
</template>
|
|
329
534
|
</v-data-iterator>
|
|
330
535
|
</template>
|
|
331
|
-
<template
|
|
332
|
-
|
|
536
|
+
<template
|
|
537
|
+
v-else
|
|
538
|
+
>
|
|
539
|
+
<v-data-iterator
|
|
540
|
+
class="fs-data-table-iterator"
|
|
333
541
|
:items="innerItems"
|
|
334
|
-
:itemsPerPage="size"
|
|
335
|
-
|
|
336
|
-
|
|
542
|
+
:itemsPerPage="size"
|
|
543
|
+
>
|
|
544
|
+
<template
|
|
545
|
+
#default="{ items }"
|
|
546
|
+
>
|
|
547
|
+
<FSRow
|
|
548
|
+
width="hug"
|
|
337
549
|
class="fs-data-iterator-container"
|
|
338
|
-
:gap="$props.tileGap"
|
|
339
|
-
|
|
550
|
+
:gap="$props.tileGap"
|
|
551
|
+
>
|
|
552
|
+
<FSDraggable
|
|
553
|
+
v-for="(item, index) in items.filter((item) => item.type === 'item')"
|
|
340
554
|
elementSelector=".fs-draggable-item"
|
|
341
555
|
:disabled="draggableDisabled"
|
|
342
556
|
:item="item"
|
|
@@ -345,10 +559,14 @@
|
|
|
345
559
|
@dragover="(event) => onDragOver(event, '.fs-draggable-item', '.fs-data-iterator-container')"
|
|
346
560
|
@drop="(event) => onDrop(event, item, '.fs-draggable-item')"
|
|
347
561
|
@dragleave="onDragLeave"
|
|
348
|
-
@dragover.prevent
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
562
|
+
@dragover.prevent
|
|
563
|
+
>
|
|
564
|
+
<slot
|
|
565
|
+
name="item.tile"
|
|
566
|
+
v-bind="{ index, item: item.raw, toggleSelect }"
|
|
567
|
+
>
|
|
568
|
+
<FSDataIteratorItem
|
|
569
|
+
:itemColor="$props.rowColor ? $props.rowColor(item.raw) : ColorEnum.Background"
|
|
352
570
|
:headers="innerHeaders.filter(h => !$props.sneakyHeaders.includes(h.value))"
|
|
353
571
|
:showSelect="$props.showSelect"
|
|
354
572
|
:itemTo="$props.itemTo"
|
|
@@ -356,23 +574,38 @@
|
|
|
356
574
|
:item="item.raw"
|
|
357
575
|
:key="index"
|
|
358
576
|
:modelValue="innerValue.includes(item.raw[$props.itemValue])"
|
|
359
|
-
@update:modelValue="toggleSelect"
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
577
|
+
@update:modelValue="toggleSelect"
|
|
578
|
+
>
|
|
579
|
+
<template
|
|
580
|
+
#item.top="props"
|
|
581
|
+
>
|
|
582
|
+
<slot
|
|
583
|
+
name="item.top"
|
|
584
|
+
v-bind="props"
|
|
585
|
+
/>
|
|
363
586
|
</template>
|
|
364
|
-
<template
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
587
|
+
<template
|
|
588
|
+
v-for="item in itemsSlots"
|
|
589
|
+
#[item.slotName]="props"
|
|
590
|
+
>
|
|
591
|
+
<slot
|
|
592
|
+
:name="item.slotName"
|
|
593
|
+
v-bind="props"
|
|
594
|
+
>
|
|
595
|
+
<FSSpan
|
|
596
|
+
font="text-overline"
|
|
597
|
+
>
|
|
369
598
|
{{ props.item[item.value] }}
|
|
370
599
|
</FSSpan>
|
|
371
600
|
</slot>
|
|
372
601
|
</template>
|
|
373
|
-
<template
|
|
374
|
-
|
|
375
|
-
|
|
602
|
+
<template
|
|
603
|
+
#item.bottom="props"
|
|
604
|
+
>
|
|
605
|
+
<slot
|
|
606
|
+
name="item.bottom"
|
|
607
|
+
v-bind="props"
|
|
608
|
+
/>
|
|
376
609
|
</template>
|
|
377
610
|
</FSDataIteratorItem>
|
|
378
611
|
</slot>
|
|
@@ -381,12 +614,14 @@
|
|
|
381
614
|
</template>
|
|
382
615
|
</v-data-iterator>
|
|
383
616
|
</template>
|
|
384
|
-
<div
|
|
617
|
+
<div
|
|
618
|
+
class="fs-data-table-intersection"
|
|
619
|
+
/>
|
|
385
620
|
</FSCol>
|
|
386
621
|
</template>
|
|
387
622
|
|
|
388
623
|
<script lang="ts">
|
|
389
|
-
import { computed, defineComponent, getCurrentInstance, onMounted, onUnmounted, PropType, ref, Slot, watch } from "vue";
|
|
624
|
+
import { computed, defineComponent, getCurrentInstance, onMounted, onUnmounted, PropType, ref, Ref, Slot, watch } from "vue";
|
|
390
625
|
import { useRouter } from "vue-router";
|
|
391
626
|
|
|
392
627
|
import { ColorEnum, FSDataTableColumn, FSDataTableFilter, FSDataTableOrder, FSToggle } from "@dative-gpi/foundation-shared-components/models";
|
|
@@ -574,12 +809,12 @@ export default defineComponent({
|
|
|
574
809
|
const lights = getColors(ColorEnum.Light);
|
|
575
810
|
|
|
576
811
|
const filters = ref<{ [key: string]: FSDataTableFilter[] }>({});
|
|
812
|
+
const innerSearch: Ref<string | null> = ref(null);
|
|
577
813
|
const innerRowsPerPage = ref(props.rowsPerPage);
|
|
578
814
|
const innerValue = ref(props.modelValue);
|
|
579
815
|
const innerSortBy = ref(props.sortBy);
|
|
580
816
|
const innerMode = ref(props.mode);
|
|
581
817
|
const innerPage = ref(props.page);
|
|
582
|
-
const innerSearch = ref(null);
|
|
583
818
|
const showFilters = ref(true);
|
|
584
819
|
const resetable = ref(false);
|
|
585
820
|
|
|
@@ -602,6 +837,10 @@ export default defineComponent({
|
|
|
602
837
|
return (props.showSearch && showFilters.value && filterableHeaders.value.length > 0) || hiddenHeaders.value.length > 0;
|
|
603
838
|
});
|
|
604
839
|
|
|
840
|
+
const hasToolbar = computed((): boolean => {
|
|
841
|
+
return !!useSlots().slots["toolbar"];
|
|
842
|
+
});
|
|
843
|
+
|
|
605
844
|
const innerSlots = computed((): { [label: string]: Slot<any> } => {
|
|
606
845
|
const slots = { ...useSlots().slots };
|
|
607
846
|
delete slots["toolbar"];
|
|
@@ -619,21 +858,21 @@ export default defineComponent({
|
|
|
619
858
|
delete slots[filterSlot(header)];
|
|
620
859
|
}
|
|
621
860
|
for (const header of headersSlots.value) {
|
|
622
|
-
delete slots[header.slotName];
|
|
861
|
+
delete slots[header.slotName!];
|
|
623
862
|
delete slots[header.slotName + "-prepend"];
|
|
624
863
|
delete slots[header.slotName + "-title"];
|
|
625
864
|
delete slots[header.slotName + "-append"];
|
|
626
865
|
delete slots[header.slotName + "-configuration"];
|
|
627
866
|
}
|
|
628
867
|
for (const item of itemsSlots.value) {
|
|
629
|
-
delete slots[item.slotName];
|
|
868
|
+
delete slots[item.slotName!];
|
|
630
869
|
}
|
|
631
870
|
return slots;
|
|
632
871
|
});
|
|
633
872
|
|
|
634
873
|
const style = computed((): { [key: string]: string | undefined } => {
|
|
635
874
|
return {
|
|
636
|
-
"--fs-data-table-background-color": backgrounds.
|
|
875
|
+
"--fs-data-table-background-color": backgrounds.base,
|
|
637
876
|
"--fs-data-table-border-color": lights.base,
|
|
638
877
|
"--fs-data-table-row-gap": sizeToVar(props.rowGap)
|
|
639
878
|
};
|
|
@@ -695,7 +934,7 @@ export default defineComponent({
|
|
|
695
934
|
const innerItems = computed((): any[] => {
|
|
696
935
|
const activeFilters: { key: string, filter: FSDataTableFilter }[] = Object.keys(filters.value).reduce((acc, key) => {
|
|
697
936
|
return acc.concat(filters.value[key].filter((filter) => filter.hidden).map((filter) => ({ key, filter })));
|
|
698
|
-
}, []);
|
|
937
|
+
}, [] as { key: string, filter: FSDataTableFilter }[]);
|
|
699
938
|
if (props.items && props.items.length) {
|
|
700
939
|
return props.items.filter((item) => {
|
|
701
940
|
if (props.selectedOnly && !innerValue.value.includes(item[props.itemValue])) {
|
|
@@ -706,7 +945,7 @@ export default defineComponent({
|
|
|
706
945
|
return false;
|
|
707
946
|
}
|
|
708
947
|
}
|
|
709
|
-
if (activeFilters.some(af => af.filter.filter(af.filter.value, item[af.key], item))) {
|
|
948
|
+
if (activeFilters.some(af => af.filter.filter && af.filter.filter(af.filter.value, item[af.key], item))) {
|
|
710
949
|
return false;
|
|
711
950
|
}
|
|
712
951
|
return true;
|
|
@@ -785,6 +1024,16 @@ export default defineComponent({
|
|
|
785
1024
|
emit("update:modelValue", innerValue.value);
|
|
786
1025
|
};
|
|
787
1026
|
|
|
1027
|
+
const toggleSelectGroup = (group: any): void => {
|
|
1028
|
+
if (group.items.every((item: any) => innerValue.value.includes(item.key))) {
|
|
1029
|
+
innerValue.value = innerValue.value.filter((id) => !group.items.some((item: any) => item.key === id));
|
|
1030
|
+
}
|
|
1031
|
+
else {
|
|
1032
|
+
innerValue.value = [...new Set(innerValue.value.concat(group.items.map((item: any) => item.key)))];
|
|
1033
|
+
}
|
|
1034
|
+
emit("update:modelValue", innerValue.value);
|
|
1035
|
+
};
|
|
1036
|
+
|
|
788
1037
|
const toggleSelect = (item: any): void => {
|
|
789
1038
|
const index = innerValue.value.indexOf(item[props.itemValue]);
|
|
790
1039
|
if (index > -1) {
|
|
@@ -932,7 +1181,7 @@ export default defineComponent({
|
|
|
932
1181
|
switch (innerMode.value) {
|
|
933
1182
|
case "table":
|
|
934
1183
|
if (intersectionObserver.value && document.querySelector(".fs-data-table-intersection")) {
|
|
935
|
-
intersectionObserver.value.unobserve(document.querySelector(".fs-data-table-intersection"));
|
|
1184
|
+
intersectionObserver.value.unobserve(document.querySelector(".fs-data-table-intersection")!);
|
|
936
1185
|
}
|
|
937
1186
|
return;
|
|
938
1187
|
case "iterator":
|
|
@@ -948,7 +1197,7 @@ export default defineComponent({
|
|
|
948
1197
|
}, { threshold: [0.9] });
|
|
949
1198
|
}
|
|
950
1199
|
if (document.querySelector(".fs-data-table-intersection")) {
|
|
951
|
-
intersectionObserver.value.observe(document.querySelector(".fs-data-table-intersection"));
|
|
1200
|
+
intersectionObserver.value.observe(document.querySelector(".fs-data-table-intersection")!);
|
|
952
1201
|
}
|
|
953
1202
|
return;
|
|
954
1203
|
}
|
|
@@ -997,6 +1246,7 @@ export default defineComponent({
|
|
|
997
1246
|
|
|
998
1247
|
if (dragged != null) {
|
|
999
1248
|
const target = (event.target as HTMLElement)?.closest(elementSelector);
|
|
1249
|
+
dragged.classList.remove("fs-draggable-dragging-grabbegin");
|
|
1000
1250
|
|
|
1001
1251
|
if (target != null && (target !== dragged || (props.sortDraggable && props.includeDraggable))) {
|
|
1002
1252
|
if (props.includeDraggable) {
|
|
@@ -1018,7 +1268,7 @@ export default defineComponent({
|
|
|
1018
1268
|
else if (dragged?.getAttribute("data-initial-index") !== null) {
|
|
1019
1269
|
target.classList.add("fs-dropzone-include");
|
|
1020
1270
|
const tbodyElement = (event.target as HTMLElement)?.closest(elementContainerSelector) as HTMLElement;
|
|
1021
|
-
resetRowIndex(+dragged?.getAttribute('data-initial-index')
|
|
1271
|
+
resetRowIndex(+dragged?.getAttribute('data-initial-index')!, Array.from(tbodyElement.children).indexOf(dragged), dragged, tbodyElement);
|
|
1022
1272
|
}
|
|
1023
1273
|
}
|
|
1024
1274
|
}
|
|
@@ -1072,11 +1322,11 @@ export default defineComponent({
|
|
|
1072
1322
|
};
|
|
1073
1323
|
|
|
1074
1324
|
const onDrop = (event: DragEvent, row: any, elementSelector: string) => {
|
|
1075
|
-
const draggedElement = document.querySelector(".fs-draggable-dragging");
|
|
1325
|
+
const draggedElement = document.querySelector(".fs-draggable-dragging") as HTMLElement;
|
|
1076
1326
|
|
|
1077
1327
|
if (draggedElement != null) {
|
|
1078
1328
|
const target = (event.target as HTMLElement)?.closest(elementSelector);
|
|
1079
|
-
const draggedData = JSON.parse(event.dataTransfer?.getData("text/plain") ??
|
|
1329
|
+
const draggedData = JSON.parse(event.dataTransfer?.getData("text/plain") ?? draggedElement.dataset.item ?? '{}');
|
|
1080
1330
|
const itemsData = draggedData.item ?? draggedData.raw;
|
|
1081
1331
|
const rowData = row.item ?? row.raw;
|
|
1082
1332
|
|
|
@@ -1135,6 +1385,7 @@ export default defineComponent({
|
|
|
1135
1385
|
innerMode,
|
|
1136
1386
|
modeOptions,
|
|
1137
1387
|
innerPage,
|
|
1388
|
+
hasToolbar,
|
|
1138
1389
|
pageOptions,
|
|
1139
1390
|
showFilters,
|
|
1140
1391
|
showFiltersRow,
|
|
@@ -1156,6 +1407,7 @@ export default defineComponent({
|
|
|
1156
1407
|
isExtraSmall,
|
|
1157
1408
|
draggableDisabled,
|
|
1158
1409
|
toggleSelectAll,
|
|
1410
|
+
toggleSelectGroup,
|
|
1159
1411
|
toggleSelect,
|
|
1160
1412
|
updateHeader,
|
|
1161
1413
|
toggleFilter,
|