@dative-gpi/foundation-shared-components 1.0.36 → 1.0.37-report-v1

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.
Files changed (271) hide show
  1. package/components/FSBreadcrumbs.vue +21 -12
  2. package/components/FSButton.vue +10 -10
  3. package/components/FSCalendar.vue +52 -14
  4. package/components/FSCalendarTwin.vue +96 -40
  5. package/components/FSCard.vue +28 -7
  6. package/components/FSCardPlaceholder.vue +8 -5
  7. package/components/FSChip.vue +12 -2
  8. package/components/FSClickable.vue +12 -13
  9. package/components/FSClock.vue +16 -7
  10. package/components/FSColorIcon.vue +23 -5
  11. package/components/FSDialog.vue +2 -1
  12. package/components/FSDialogContent.vue +12 -11
  13. package/components/FSDialogForm.vue +22 -2
  14. package/components/FSDialogFormBody.vue +47 -28
  15. package/components/FSDialogMenu.vue +17 -8
  16. package/components/FSDialogMultiFormBody.vue +77 -54
  17. package/components/FSDialogRemove.vue +8 -8
  18. package/components/FSDialogSubmit.vue +17 -8
  19. package/components/FSEditImage.vue +1 -1
  20. package/components/FSEditImageUI.vue +20 -10
  21. package/components/FSFadeOut.vue +53 -21
  22. package/components/FSForm.vue +10 -8
  23. package/components/FSGrid.vue +1 -1
  24. package/components/FSIcon.vue +2 -1
  25. package/components/FSIconCard.vue +47 -7
  26. package/components/FSImage.vue +12 -4
  27. package/components/FSImageUI.vue +8 -15
  28. package/components/FSInstantPicker.vue +266 -0
  29. package/components/FSLink.vue +25 -9
  30. package/components/FSLoader.vue +28 -11
  31. package/components/FSOptionGroup.vue +51 -3
  32. package/components/FSPlayButtons.vue +72 -0
  33. package/components/FSProgressBar.vue +94 -0
  34. package/components/FSRouterLink.vue +42 -0
  35. package/components/FSSlideGroup.vue +19 -5
  36. package/components/FSSpan.vue +17 -7
  37. package/components/FSSwitch.vue +57 -27
  38. package/components/FSTab.vue +15 -13
  39. package/components/FSTabs.vue +32 -7
  40. package/components/FSTag.vue +14 -3
  41. package/components/FSTagGroup.vue +1 -1
  42. package/components/FSText.vue +11 -7
  43. package/components/FSWindow.vue +128 -4
  44. package/components/FSWrapGroup.vue +13 -1
  45. package/components/agenda/FSAgenda.vue +223 -0
  46. package/components/agenda/FSAgendaDialogCalendar.vue +76 -0
  47. package/components/agenda/FSAgendaHeader.vue +215 -0
  48. package/components/agenda/FSAgendaHorizontalEvent.vue +174 -0
  49. package/components/agenda/FSAgendaHorizontalTimeLineMarker.vue +46 -0
  50. package/components/agenda/FSAgendaHoursCol.vue +103 -0
  51. package/components/agenda/FSAgendaHoursRow.vue +164 -0
  52. package/components/agenda/FSAgendaVerticalEvent.vue +160 -0
  53. package/components/agenda/FSAgendaVerticalTimeLineMarker.vue +46 -0
  54. package/components/agenda/FSDayAgenda.vue +199 -0
  55. package/components/agenda/FSMonthAgenda.vue +252 -0
  56. package/components/agenda/FSSelectAgendaMode.vue +54 -0
  57. package/components/agenda/FSWeekAgenda.vue +323 -0
  58. package/components/autocompletes/FSAutoCompleteAddress.vue +22 -20
  59. package/components/autocompletes/FSAutocompleteLanguage.vue +7 -1
  60. package/components/autocompletes/FSAutocompleteTimeZone.vue +7 -1
  61. package/components/buttons/FSButtonAdd.vue +1 -1
  62. package/components/buttons/FSButtonAddLabel.vue +1 -1
  63. package/components/buttons/FSButtonCancel.vue +1 -1
  64. package/components/buttons/FSButtonCancelLabel.vue +1 -1
  65. package/components/buttons/FSButtonCopy.vue +1 -1
  66. package/components/buttons/FSButtonCopyLabel.vue +1 -1
  67. package/components/buttons/FSButtonDragIcon.vue +27 -0
  68. package/components/buttons/FSButtonDuplicate.vue +1 -1
  69. package/components/buttons/FSButtonDuplicateLabel.vue +1 -1
  70. package/components/buttons/FSButtonEdit.vue +1 -1
  71. package/components/buttons/FSButtonEditLabel.vue +1 -1
  72. package/components/buttons/FSButtonFile.vue +1 -1
  73. package/components/buttons/FSButtonFileLabel.vue +1 -1
  74. package/components/buttons/FSButtonNext.vue +1 -1
  75. package/components/buttons/FSButtonNextLabel.vue +1 -1
  76. package/components/buttons/FSButtonPrevious.vue +1 -1
  77. package/components/buttons/FSButtonPreviousLabel.vue +1 -1
  78. package/components/buttons/FSButtonRedo.vue +1 -1
  79. package/components/buttons/FSButtonRedoLabel.vue +1 -1
  80. package/components/buttons/FSButtonRemove.vue +1 -1
  81. package/components/buttons/FSButtonRemoveLabel.vue +1 -1
  82. package/components/buttons/FSButtonSave.vue +1 -1
  83. package/components/buttons/FSButtonSaveLabel.vue +1 -1
  84. package/components/buttons/FSButtonSearch.vue +1 -1
  85. package/components/buttons/FSButtonSearchLabel.vue +1 -1
  86. package/components/buttons/FSButtonUndo.vue +1 -1
  87. package/components/buttons/FSButtonUndoLabel.vue +1 -1
  88. package/components/buttons/FSButtonUpdate.vue +1 -1
  89. package/components/buttons/FSButtonUpdateLabel.vue +1 -1
  90. package/components/buttons/FSButtonValidate.vue +1 -1
  91. package/components/buttons/FSButtonValidateLabel.vue +1 -1
  92. package/components/calendar/FSSimpleCalendar.vue +145 -0
  93. package/components/calendar/FSSimpleCalendarHeader.vue +60 -0
  94. package/components/calendar/FSSimpleMonthSelector.vue +138 -0
  95. package/components/deviceOrganisations/FSConnectivity.vue +11 -1
  96. package/components/deviceOrganisations/FSConnectivityCard.vue +19 -47
  97. package/components/deviceOrganisations/FSStatus.vue +11 -1
  98. package/components/deviceOrganisations/FSStatusCard.vue +35 -61
  99. package/components/deviceOrganisations/FSStatusesCarousel.vue +1 -0
  100. package/components/deviceOrganisations/FSStatusesRow.vue +9 -3
  101. package/components/deviceOrganisations/FSWorstAlert.vue +30 -37
  102. package/components/deviceOrganisations/FSWorstAlertCard.vue +36 -85
  103. package/components/fields/FSAutocompleteField.vue +445 -463
  104. package/components/fields/FSAutocompleteTag.vue +1 -1
  105. package/components/fields/FSBaseField.vue +44 -27
  106. package/components/fields/FSColorField.vue +42 -39
  107. package/components/fields/FSCommentField.vue +105 -0
  108. package/components/fields/FSDateField.vue +3 -2
  109. package/components/fields/FSDateRangeField.vue +3 -2
  110. package/components/fields/FSDateTimeField.vue +4 -3
  111. package/components/fields/FSDateTimeRangeField.vue +8 -6
  112. package/components/fields/FSEntityFieldUI.vue +271 -0
  113. package/components/fields/FSGradientField.vue +27 -33
  114. package/components/fields/FSIconField.vue +0 -1
  115. package/components/fields/FSMagicConfigField.vue +10 -3
  116. package/components/fields/FSMagicField.vue +9 -4
  117. package/components/fields/FSNumberField.vue +6 -1
  118. package/components/fields/FSRichTextField.vue +102 -52
  119. package/components/fields/FSSearchField.vue +9 -115
  120. package/components/fields/FSSelectField.vue +477 -252
  121. package/components/fields/FSTagField.vue +1 -1
  122. package/components/fields/FSTermField.vue +42 -17
  123. package/components/fields/FSTextArea.vue +26 -7
  124. package/components/fields/FSTextField.vue +8 -3
  125. package/components/fields/FSTimeRangeField.vue +304 -0
  126. package/components/fields/FSTimeStepField.vue +3 -3
  127. package/components/fields/FSTranslateField.vue +4 -3
  128. package/components/fields/FSTranslateRichTextField.vue +32 -12
  129. package/components/fields/FSTranslateTextArea.vue +233 -0
  130. package/components/fields/periodicField/FSPeriodicDailyField.vue +2 -2
  131. package/components/fields/periodicField/FSPeriodicField.vue +8 -8
  132. package/components/fields/periodicField/FSPeriodicMonthlyField.vue +8 -8
  133. package/components/fields/periodicField/FSPeriodicWeeklyField.vue +23 -13
  134. package/components/fields/periodicField/FSPeriodicYearlyField.vue +6 -6
  135. package/components/lists/FSDataTableUI.vue +173 -103
  136. package/components/lists/FSDraggable.vue +2 -2
  137. package/components/lists/FSFilterButton.vue +7 -11
  138. package/components/lists/FSHeaderButton.vue +4 -4
  139. package/components/lists/FSHiddenButton.vue +3 -5
  140. package/components/lists/FSLoadDataTable.vue +10 -7
  141. package/components/lists/FSSimpleList.vue +234 -0
  142. package/components/lists/FSSimpleListItem.vue +132 -0
  143. package/components/map/FSMap.vue +83 -33
  144. package/components/map/FSMapFeatureGroup.vue +2 -2
  145. package/components/map/FSMapLayerButton.vue +3 -3
  146. package/components/map/FSMapMarker.vue +11 -7
  147. package/components/map/FSMapMarkerClusterGroup.vue +8 -3
  148. package/components/map/FSMapOverlay.vue +37 -20
  149. package/components/map/FSMapPolygon.vue +5 -5
  150. package/components/map/FSMapTileLayer.vue +2 -2
  151. package/components/map/keys.ts +3 -3
  152. package/components/selects/FSSelectAutoRefresh.vue +9 -9
  153. package/components/selects/FSSelectDashboardVariableType.vue +5 -4
  154. package/components/selects/FSSelectDateSetting.vue +3 -2
  155. package/components/selects/FSSelectDays.vue +9 -9
  156. package/components/selects/FSSelectListMode.vue +51 -0
  157. package/components/selects/FSSelectMonths.vue +14 -14
  158. package/components/selects/chartSelectors/FSAggregationSelector.vue +52 -0
  159. package/components/selects/chartSelectors/FSAxisTypeSelector.vue +49 -0
  160. package/components/selects/chartSelectors/FSDisplayAsSelector.vue +53 -0
  161. package/components/selects/chartSelectors/FSFilterTypeSelector.vue +54 -0
  162. package/components/selects/chartSelectors/FSHeatmapRuleSelector.vue +54 -0
  163. package/components/selects/chartSelectors/FSOperationOnSelector.vue +53 -0
  164. package/components/selects/chartSelectors/FSPlanningTypeSelector.vue +53 -0
  165. package/components/selects/chartSelectors/FSPlotPerSelector.vue +52 -0
  166. package/components/selects/chartSelectors/FSSelectEntityType.vue +59 -0
  167. package/components/selects/chartSelectors/FSSerieTypeSelector.vue +53 -0
  168. package/components/tiles/FSAlertTileUI.vue +90 -0
  169. package/components/tiles/FSChartTileUI.vue +111 -0
  170. package/components/tiles/FSCommentTileUI.vue +174 -0
  171. package/components/tiles/FSDeviceOrganisationTileUI.vue +6 -0
  172. package/components/tiles/FSGroupTileUI.vue +2 -2
  173. package/components/tiles/FSLoadTile.vue +2 -0
  174. package/components/tiles/FSLocationTileUI.vue +192 -0
  175. package/components/tiles/FSModelTileUI.vue +18 -0
  176. package/components/tiles/FSSimpleTileUI.vue +9 -4
  177. package/components/tiles/FSTile.vue +93 -74
  178. package/components/tiles/FSUserOrganisationTileUI.vue +1 -1
  179. package/components/toggleSets/FSToggleSetPosition.vue +2 -2
  180. package/components/views/FSBaseView.vue +64 -0
  181. package/components/views/FSEntityView.vue +12 -140
  182. package/components/views/FSSimpleView.vue +29 -0
  183. package/components/views/desktop/FSBaseDefaultDesktopView.vue +135 -0
  184. package/components/views/desktop/FSBaseDesktopView.vue +53 -0
  185. package/components/views/desktop/FSBaseEntityDesktopView.vue +209 -0
  186. package/components/views/mobile/FSBaseDefaultMobileView.vue +133 -0
  187. package/components/views/mobile/FSBaseEntityMobileView.vue +199 -0
  188. package/components/views/mobile/FSBaseMobileView.vue +53 -0
  189. package/composables/useBreakpoints.ts +39 -3
  190. package/composables/useColors.ts +3 -2
  191. package/composables/useMagicFieldProvider.ts +1 -0
  192. package/composables/useSlots.ts +2 -1
  193. package/models/agenda.ts +9 -0
  194. package/models/deviceAlerts.ts +1 -1
  195. package/models/deviceConnectivities.ts +1 -1
  196. package/models/index.ts +1 -0
  197. package/models/magicFields.ts +1 -0
  198. package/models/map.ts +2 -2
  199. package/models/rules.ts +8 -5
  200. package/models/tables.ts +5 -2
  201. package/models/variableNode.ts +8 -5
  202. package/package.json +5 -5
  203. package/styles/components/fs_agenda.scss +36 -0
  204. package/styles/components/fs_agenda_event.scss +41 -0
  205. package/styles/components/fs_agenda_hours_col.scss +4 -0
  206. package/styles/components/fs_agenda_hours_row.scss +5 -0
  207. package/styles/components/fs_agenda_time_line_marker.scss +19 -0
  208. package/styles/components/fs_autocomplete_field.scss +0 -13
  209. package/styles/components/fs_breadcrumbs.scss +18 -36
  210. package/styles/components/fs_button.scss +7 -5
  211. package/styles/components/fs_chip.scss +8 -6
  212. package/styles/components/fs_clickable.scss +18 -23
  213. package/styles/components/fs_clock.scss +0 -10
  214. package/styles/components/fs_color_field.scss +1 -4
  215. package/styles/components/fs_data_iterator_item.scss +12 -10
  216. package/styles/components/fs_data_table.scss +6 -9
  217. package/styles/components/fs_dialog.scss +7 -17
  218. package/styles/components/fs_dialog_menu.scss +4 -2
  219. package/styles/components/fs_edit_image.scss +8 -0
  220. package/styles/components/fs_fade_out.scss +10 -2
  221. package/styles/components/fs_filter_button.scss +1 -6
  222. package/styles/components/fs_gradient_field.scss +11 -11
  223. package/styles/components/fs_hidden_button.scss +2 -7
  224. package/styles/components/fs_image_card.scss +6 -4
  225. package/styles/components/fs_magic_config_field.scss +1 -2
  226. package/styles/components/fs_map.scss +11 -7
  227. package/styles/components/fs_meta_field.scss +3 -5
  228. package/styles/components/fs_option_group.scss +15 -5
  229. package/styles/components/fs_password_field.scss +4 -2
  230. package/styles/components/fs_progress_bar.scss +14 -0
  231. package/styles/components/fs_radio.scss +0 -11
  232. package/styles/components/fs_rich_text_field.scss +1 -9
  233. package/styles/components/fs_select_date_settings.scss +3 -0
  234. package/styles/components/fs_select_field.scss +4 -13
  235. package/styles/components/fs_slide_group.scss +7 -0
  236. package/styles/components/fs_span.scss +13 -4
  237. package/styles/components/fs_switch.scss +1 -0
  238. package/styles/components/fs_tabs.scss +19 -33
  239. package/styles/components/fs_tag.scss +8 -22
  240. package/styles/components/fs_text_area.scss +13 -17
  241. package/styles/components/fs_tile.scss +21 -15
  242. package/styles/components/fs_window.scss +7 -0
  243. package/styles/components/fs_wrap_group.scss +7 -0
  244. package/styles/components/index.scss +6 -4
  245. package/styles/globals/index.scss +1 -5
  246. package/styles/globals/overrides.scss +28 -61
  247. package/styles/globals/scrollbars.scss +10 -0
  248. package/styles/globals/text_fonts.scss +18 -66
  249. package/tools/alertsTools.ts +69 -0
  250. package/tools/chartsTools.ts +427 -0
  251. package/tools/index.ts +4 -0
  252. package/tools/reportsTools.ts +38 -0
  253. package/tools/timeRangeTools.ts +125 -0
  254. package/utils/filter.ts +18 -0
  255. package/utils/index.ts +2 -0
  256. package/utils/leafletMarkers.ts +4 -4
  257. package/utils/operations.ts +69 -0
  258. package/utils/sort.ts +2 -2
  259. package/utils/statuses.ts +1 -1
  260. package/utils/time.ts +17 -17
  261. package/components/fields/FSTimeSlotField.vue +0 -250
  262. package/components/views/FSEntityHeader.vue +0 -350
  263. package/components/views/FSListHeader.vue +0 -83
  264. package/components/views/FSListView.vue +0 -83
  265. package/components/views/FSSkeletonView.vue +0 -100
  266. package/styles/components/fs_icon_field.scss +0 -12
  267. package/styles/components/fs_tag_field.scss +0 -8
  268. package/styles/components/fs_time_field.scss +0 -12
  269. package/styles/components/fs_timeslot_field.scss +0 -12
  270. package/styles/globals/breakpoints.scss +0 -20
  271. package/styles/globals/fixes.scss +0 -5
@@ -1,67 +1,79 @@
1
1
  <template>
2
2
  <FSCol
3
3
  gap="16px"
4
+ style="position: relative;"
4
5
  >
5
6
  <FSRow
6
- align="bottom-center"
7
- :wrap="isExtraSmall ? false : true"
7
+ v-if="$props.showSearch || (!isMobileSized && ($slots['prepend-toolbar'] || $slots['toolbar'] || $slots['append-toolbar'])) || (!$props.disableTable && !$props.disableIterator)"
8
+ align="bottom-left"
9
+ :wrap="isMobileSized ? false : true"
8
10
  width="fill"
9
11
  >
10
12
  <slot
11
- v-if="!isExtraSmall"
13
+ v-if="!isMobileSized"
12
14
  name="prepend-toolbar"
13
15
  />
14
16
  <template
15
17
  v-if="$props.showSearch"
16
18
  >
17
19
  <FSSearchField
18
- prependInnerIcon="mdi-magnify"
19
20
  :hideHeader="true"
20
21
  v-model="innerSearch"
21
22
  />
22
23
  <FSButton
23
24
  v-if="filterableHeaders.length > 0"
24
25
  prependIcon="mdi-filter-variant"
25
- padding="0 7px"
26
- :variant="showFilters ? 'full' : 'standard'"
27
- @click="showFilters = !showFilters"
26
+ :variant="innerShowFilters ? 'full' : 'standard'"
27
+ @click="innerShowFilters = !innerShowFilters"
28
28
  />
29
29
  </template>
30
30
  <slot
31
- v-if="!isExtraSmall"
31
+ v-if="!isMobileSized"
32
32
  name="toolbar"
33
33
  />
34
34
  <template
35
- v-if="!$props.disableTable && !$props.disableIterator"
35
+ v-if="$slots['append-toolbar'] || (!$props.disableTable && !$props.disableIterator)"
36
36
  >
37
- <v-spacer />
38
37
  <FSRow
39
38
  align="center-right"
39
+ :width="isExtraSmall ? 'hug' : 'fill'"
40
40
  >
41
+ <slot
42
+ v-if="!isMobileSized"
43
+ name="append-toolbar"
44
+ />
41
45
  <FSOptionGroup
46
+ v-if="!$props.disableTable && !$props.disableIterator"
42
47
  :values="modeOptions"
43
48
  :singleColor="true"
44
49
  :required="true"
50
+ variant="slide"
45
51
  v-model="innerMode"
46
52
  />
47
53
  </FSRow>
48
54
  </template>
49
55
  </FSRow>
50
56
  <FSRow
51
- v-if="isExtraSmall && hasToolbar"
57
+ v-if="isMobileSized && ($slots['prepend-toolbar'] || $slots['toolbar'] || $slots['append-toolbar'])"
52
58
  >
53
- <FSWrapGroup>
59
+ <FSSlideGroup>
60
+ <slot
61
+ name="prepend-toolbar"
62
+ />
54
63
  <slot
55
64
  name="toolbar"
56
65
  />
57
- </FSWrapGroup>
66
+ <slot
67
+ name="append-toolbar"
68
+ />
69
+ </FSSlideGroup>
58
70
  </FSRow>
59
71
  <FSRow
60
72
  v-if="showFiltersRow"
61
73
  gap="16px"
62
74
  >
63
75
  <FSCol
64
- v-if="showFilters && hasVisibleFilters"
76
+ v-if="innerShowFilters && hasVisibleFilters"
65
77
  width="hug"
66
78
  >
67
79
  <FSRow
@@ -95,9 +107,9 @@
95
107
  gap="8px"
96
108
  >
97
109
  <FSChip
98
- v-if="showFilters && resetable"
110
+ v-if="innerShowFilters && resetable"
99
111
  variant="standard"
100
- :label="$tr('ui.data-table.reset-filters', 'Reset')"
112
+ :label="$tr('data-table.reset-filters', 'Reset')"
101
113
  :height="['30px', '24px']"
102
114
  :color="ColorEnum.Error"
103
115
  :editable="true"
@@ -149,7 +161,7 @@
149
161
  <FSText
150
162
  font="text-overline"
151
163
  >
152
- {{ $tr("ui.data-table.empty", "No data") }}
164
+ {{ $tr("ui.common.no-data", "No data") }}
153
165
  </FSText>
154
166
  </template>
155
167
  <template
@@ -291,25 +303,29 @@
291
303
  <slot
292
304
  :name="`${header.slotName}-append`"
293
305
  />
294
- <v-spacer />
295
- <slot
296
- :name="`${header.slotName}-configuration`"
306
+ <FSRow
307
+ align="center-right"
308
+ :wrap="false"
297
309
  >
298
- <FSHeaderButton
299
- :first="index === 0"
300
- :last="index === headersSlots.length - 1"
301
- @update:hide="updateHeader(header, 'hidden', !header.hidden)"
302
- @update:left="updateHeader(header, 'index', -1)"
303
- @update:right="updateHeader(header, 'index', 1)"
304
- />
305
- <FSButton
306
- v-if="header.sortable"
307
- variant="icon"
308
- :color="sortColor(header, props)"
309
- :icon="sortIcon(header, props)"
310
- @click="toggleSort(header)"
311
- />
312
- </slot>
310
+ <slot
311
+ :name="`${header.slotName}-configuration`"
312
+ >
313
+ <FSHeaderButton
314
+ :first="index === 0"
315
+ :last="index === headersSlots.length - 1"
316
+ @update:hide="updateHeader(header, 'hidden', !header.hidden)"
317
+ @update:left="updateHeader(header, 'index', -1)"
318
+ @update:right="updateHeader(header, 'index', 1)"
319
+ />
320
+ <FSButton
321
+ v-if="header.sortable"
322
+ variant="icon"
323
+ :color="sortColor(header, props)"
324
+ :icon="sortIcon(header, props)"
325
+ @click="toggleSort(header)"
326
+ />
327
+ </slot>
328
+ </FSRow>
313
329
  </FSRow>
314
330
  </slot>
315
331
  </template>
@@ -357,22 +373,23 @@
357
373
  <FSText
358
374
  font="text-button"
359
375
  >
360
- {{ $tr("ui.data-table.all-selected-bold", "Warning:") }}
376
+ {{ $tr("data-table.all-selected-bold", "Warning:") }}
361
377
  </FSText>
362
378
  <FSText>
363
- {{ $tr("ui.data-table.all-selected-regular", "All elements selected") }}
379
+ {{ $tr("data-table.all-selected-regular", "All elements selected") }}
364
380
  </FSText>
365
381
  </FSRow>
366
382
  </template>
367
383
  <template
368
384
  v-else
369
385
  >
370
- <FSText>
371
- {{ $tr("ui.data-table.some-selected", "{0} element(s) selected", $props.modelValue.length.toString()) }}
372
- </FSText>
386
+ <FSRow>
387
+ <FSText>
388
+ {{ $tr("data-table.some-selected", "{0} element(s) selected", $props.modelValue.length.toString()) }}
389
+ </FSText>
390
+ </FSRow>
373
391
  </template>
374
392
  </template>
375
- <v-spacer />
376
393
  <FSRow
377
394
  align="center-right"
378
395
  width="hug"
@@ -381,7 +398,7 @@
381
398
  <FSText
382
399
  font="text-overline"
383
400
  >
384
- {{ $tr("ui.data-table.rows-per-page", "Rows per page") }}
401
+ {{ $tr("data-table.rows-per-page", "Rows per page") }}
385
402
  </FSText>
386
403
  <FSSelectField
387
404
  class="fs-data-table-rows-per-page fs-small-input"
@@ -433,7 +450,7 @@
433
450
  <FSText
434
451
  font="text-overline"
435
452
  >
436
- {{ $tr("ui.data-table.empty", "No data") }}
453
+ {{ $tr("ui.common.no-data", "No data") }}
437
454
  </FSText>
438
455
  </template>
439
456
  <template
@@ -447,7 +464,7 @@
447
464
  v-for="(item, index) in items"
448
465
  elementSelector=".fs-draggable-item"
449
466
  :disabled="draggableDisabled"
450
- :item="item"
467
+ :item="{ ...item, index }"
451
468
  :key="index"
452
469
  @update:dragend="(event, dragged) => onDragEnd(event, dragged, '.fs-data-iterator-container')"
453
470
  @dragover="(event) => onDragOver(event, '.fs-draggable-item', '.fs-data-iterator-container')"
@@ -531,22 +548,23 @@
531
548
  <FSText
532
549
  font="text-button"
533
550
  >
534
- {{ $tr("ui.data-table.all-selected-bold", "Warning:") }}
551
+ {{ $tr("data-table.all-selected-bold", "Warning:") }}
535
552
  </FSText>
536
553
  <FSText>
537
- {{ $tr("ui.data-table.all-selected-regular", "All elements selected") }}
554
+ {{ $tr("data-table.all-selected-regular", "All elements selected") }}
538
555
  </FSText>
539
556
  </FSRow>
540
557
  </template>
541
558
  <template
542
559
  v-else
543
560
  >
544
- <FSText>
545
- {{ $tr("ui.data-table.some-selected", "{0} element(s) selected", $props.modelValue.length.toString()) }}
546
- </FSText>
561
+ <FSRow>
562
+ <FSText>
563
+ {{ $tr("data-table.some-selected", "{0} element(s) selected", $props.modelValue.length.toString()) }}
564
+ </FSText>
565
+ </FSRow>
547
566
  </template>
548
567
  </template>
549
- <v-spacer />
550
568
  <FSRow
551
569
  align="center-right"
552
570
  :wrap="false"
@@ -554,7 +572,7 @@
554
572
  <FSText
555
573
  font="text-overline"
556
574
  >
557
- {{ $tr("ui.data-table.rows-per-page", "Rows per page") }}
575
+ {{ $tr("data-table.rows-per-page", "Rows per page") }}
558
576
  </FSText>
559
577
  <FSRow
560
578
  width="120px"
@@ -603,7 +621,7 @@
603
621
  <FSText
604
622
  font="text-overline"
605
623
  >
606
- {{ $tr("ui.data-table.empty", "No data") }}
624
+ {{ $tr("ui.common.no-data", "No data") }}
607
625
  </FSText>
608
626
  </template>
609
627
  <template
@@ -618,7 +636,7 @@
618
636
  v-for="(item, index) in items.filter((item) => item.type === 'item')"
619
637
  elementSelector=".fs-draggable-item"
620
638
  :disabled="draggableDisabled"
621
- :item="item"
639
+ :item="{ ...item, index }"
622
640
  :key="index"
623
641
  @update:dragend="(event, dragged) => onDragEnd(event, dragged, '.fs-data-iterator-container')"
624
642
  @dragover="(event) => onDragOver(event, '.fs-draggable-item', '.fs-data-iterator-container')"
@@ -685,7 +703,7 @@
685
703
  <div
686
704
  class="fs-data-table-intersection"
687
705
  :id="elementId"
688
- />
706
+ />
689
707
  </FSCol>
690
708
  </template>
691
709
 
@@ -696,9 +714,10 @@ import { useRouter } from "vue-router";
696
714
  import { ColorEnum, type FSDataTableColumn, type FSDataTableFilter, type FSDataTableOrder, type FSToggle } from "@dative-gpi/foundation-shared-components/models";
697
715
  import { useBreakpoints, useColors, useSlots } from "@dative-gpi/foundation-shared-components/composables";
698
716
  import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
717
+ import { useRouting } from "@dative-gpi/foundation-shared-services/composables";
699
718
  import { uuidv4 } from "@dative-gpi/bones-ui/tools/uuid"
700
719
 
701
- import { alphanumericSort, sizeToVar } from "../../utils";
720
+ import { alphanumericSort, containsSearchTerm, sizeToVar } from "../../utils";
702
721
 
703
722
  import FSDataIteratorItem from "./FSDataIteratorItem.vue";
704
723
  import FSSearchField from "../fields/FSSearchField.vue";
@@ -746,6 +765,11 @@ export default defineComponent({
746
765
  type: Array as PropType<FSDataTableColumn[]>,
747
766
  required: true
748
767
  },
768
+ showFilters: {
769
+ type: Boolean,
770
+ required: false,
771
+ default: false
772
+ },
749
773
  filters: {
750
774
  type: Object as PropType<{ [key: string]: FSDataTableFilter[] }>,
751
775
  required: false,
@@ -815,6 +839,11 @@ export default defineComponent({
815
839
  required: false,
816
840
  default: true
817
841
  },
842
+ noSearch: {
843
+ type: Boolean,
844
+ required: false,
845
+ default: false
846
+ },
818
847
  singleSelect: {
819
848
  type: Boolean,
820
849
  required: false,
@@ -881,9 +910,10 @@ export default defineComponent({
881
910
  default: "12px"
882
911
  },
883
912
  },
884
- emits: ["update:modelValue", "update:headers", "update:filters", "update:mode", "update:sortBy", "update:rowsPerPage", "update:page", "update:include", "update:items", "click:row"],
913
+ emits: ["update:modelValue", "update:headers", "update:search", "update:showFilters", "update:filters", "update:mode", "update:sortBy", "update:rowsPerPage", "update:page", "update:include", "update:items", "click:row"],
885
914
  setup(props, { emit }) {
886
- const { isExtraSmall } = useBreakpoints();
915
+ const { isExtraSmall, isMobileSized } = useBreakpoints();
916
+ const { handleRoutingEvent } = useRouting();
887
917
  const { $tr } = useTranslationsProvider();
888
918
  const { getColors } = useColors();
889
919
  const router = useRouter();
@@ -895,9 +925,9 @@ export default defineComponent({
895
925
  const innerSearch: Ref<string | null> = ref(null);
896
926
  const innerRowsPerPage = ref(props.rowsPerPage);
897
927
  const innerSortBy = ref(props.sortBy);
898
- const innerMode = ref(props.mode);
928
+ const innerMode = ref(props.disableTable ? "iterator" : props.disableIterator ? "table" : props.mode);
899
929
  const innerPage = ref(props.page);
900
- const showFilters = ref(true);
930
+ const innerShowFilters = ref(props.showFilters);
901
931
  const resetable = ref(false);
902
932
 
903
933
  const intersectionObserver = ref<IntersectionObserver | null>(null);
@@ -906,19 +936,26 @@ export default defineComponent({
906
936
  const elementId = `id${uuidv4()}`;
907
937
 
908
938
  const modeOptions: FSToggle[] = [
909
- { id: "table", prependIcon: "mdi-table" },
910
- { id: "iterator", prependIcon: "mdi-apps" }
939
+ { id: "iterator", prependIcon: "mdi-view-grid-outline" },
940
+ { id: "table", prependIcon: "mdi-format-list-bulleted" }
911
941
  ];
912
942
 
913
943
  const rowsPerPageOptions: { id: number, label: string }[] = [
914
944
  { id: 5, label: "5" },
915
945
  { id: 10, label: "10" },
916
946
  { id: 30, label: "30" },
917
- { id: -1, label: $tr("ui.data-table.all-rows", "All") }
947
+ { id: -1, label: $tr("ui.common.all", "All") }
918
948
  ];
919
949
 
920
950
  const showFiltersRow = computed((): boolean => {
921
- return (props.showSearch && showFilters.value && filterableHeaders.value.length > 0) || hiddenHeaders.value.length > 0;
951
+ switch (innerMode.value) {
952
+ case "iterator": {
953
+ return (props.showSearch && innerShowFilters.value && filterableHeaders.value.length > 0);
954
+ }
955
+ case "table": {
956
+ return (props.showSearch && innerShowFilters.value && filterableHeaders.value.length > 0) || hiddenHeaders.value.length > 0;
957
+ }
958
+ }
922
959
  });
923
960
 
924
961
  const hasVisibleFilters = computed((): boolean => {
@@ -926,11 +963,15 @@ export default defineComponent({
926
963
  });
927
964
 
928
965
  const showFiltersDivider = computed((): boolean => {
929
- return resetable.value || (hiddenHeaders.value.length > 0 && hasVisibleFilters.value);
930
- });
931
-
932
- const hasToolbar = computed((): boolean => {
933
- return !!useSlots().slots["toolbar"];
966
+ switch (innerMode.value) {
967
+ case "iterator": {
968
+ return resetable.value;
969
+ }
970
+ case "table": {
971
+ return resetable.value || (hiddenHeaders.value.length > 0 && hasVisibleFilters.value);
972
+ }
973
+ }
974
+
934
975
  });
935
976
 
936
977
  const innerSlots = computed((): { [label: string]: Slot<any> } => {
@@ -1021,21 +1062,27 @@ export default defineComponent({
1021
1062
  });
1022
1063
 
1023
1064
  const innerItems = computed((): any[] => {
1024
- const activeFilters: { key: string, filter: FSDataTableFilter }[] = Object.keys(filters.value).reduce((acc, key) => {
1025
- return acc.concat(filters.value[key].filter((filter) => filter.hidden).map((filter) => ({ key, filter })));
1026
- }, [] as { key: string, filter: FSDataTableFilter }[]);
1065
+ // Select only the filters where a value is hidden, for others, accept all values
1066
+ const activeFilters: { [key: string]: FSDataTableFilter[] } = Object.keys(filters.value).reduce((acc, key) => {
1067
+ if (filters.value[key].some((filter) => filter.hidden)) {
1068
+ acc[key] = filters.value[key].filter((filter) => !filter.hidden);
1069
+ }
1070
+ return acc;
1071
+ }, {} as { [key: string]: FSDataTableFilter[] });
1072
+
1027
1073
  if (props.items && props.items.length) {
1074
+ const innerSearchFormatted = innerSearch.value ? innerSearch.value.toLowerCase() : null;
1028
1075
  return props.items.filter((item) => {
1029
1076
  if (props.selectedOnly && !props.modelValue.includes(item[props.itemValue])) {
1030
1077
  return false;
1031
1078
  }
1032
- if (innerSearch.value) {
1033
- if (!JSON.stringify(item).toLowerCase().includes(innerSearch.value.toString().toLowerCase())) {
1079
+ for (const property in activeFilters) {
1080
+ if (!activeFilters[property].some((filter) => filter.filter && filter.filter(filter.value, item[property], item))) {
1034
1081
  return false;
1035
1082
  }
1036
1083
  }
1037
- if (activeFilters.some(af => af.filter.filter && af.filter.filter(af.filter.value, item[af.key], item))) {
1038
- return false;
1084
+ if (!props.noSearch && innerSearchFormatted) {
1085
+ return containsSearchTerm(item, innerSearchFormatted);
1039
1086
  }
1040
1087
  return true;
1041
1088
  });
@@ -1084,12 +1131,7 @@ export default defineComponent({
1084
1131
  clickable: true,
1085
1132
  row: (event: PointerEvent, row: any) => {
1086
1133
  if (props.itemTo && router) {
1087
- if (event.metaKey || event.ctrlKey || event.button === 1) {
1088
- window.open(router.resolve(props.itemTo(row.item)).href, "_blank");
1089
- }
1090
- else {
1091
- router.push(props.itemTo(row.item));
1092
- }
1134
+ handleRoutingEvent(event, props.itemTo(row.item), true);
1093
1135
  }
1094
1136
  else {
1095
1137
  emit("click:row", row.item);
@@ -1214,39 +1256,52 @@ export default defineComponent({
1214
1256
  const key = header.value!;
1215
1257
  const currentFilters = filters.value[key];
1216
1258
 
1259
+ const getPath = (object: any, keys: string[]) => keys.reduce((acc, key) => acc[key] ?? null, object);
1260
+
1217
1261
  let value: FSDataTableFilter[] = [];
1218
1262
 
1219
1263
  if (header.fixedFilters) {
1220
1264
  value = header.fixedFilters.map((ff): FSDataTableFilter => ({
1221
1265
  hidden: currentFilters?.find((cf) => cf.value == (ff.value || null))?.hidden ?? false,
1222
1266
  text: ff.text?.toString() ?? "—",
1223
- value: ff.value || null,
1224
- filter: header.methodFilter ?? ((value, property) => {
1225
- property = [property].flat();
1226
- return Array.isArray(property) ? property.includes(value) || (!value && property.length == 0) : (!value && !property) || value == property;
1267
+ value: ff.value ?? null,
1268
+ filter: header.methodFilter ?? ((_, property, item) => {
1269
+ if (header.methodFilterRaw) {
1270
+ return header.methodFilterRaw(ff.value, item);
1271
+ }
1272
+ const flat = property = [property].flat();
1273
+ return (!ff.value && flat.length == 0) || flat.some(f => f == ff.value);
1227
1274
  })
1228
1275
  }));
1276
+ filterDictionary[key] = value;
1229
1277
  }
1230
1278
  else {
1231
1279
  if (props.items && props.items.length) {
1232
1280
  const mapToInnerValue = header.innerValue ? header.innerValue : (i: any) => i;
1233
- const itemValues = props.items.flatMap((item) => Array.isArray(item[key]) && item[key].length == 0 ? undefined : item[key]).map(mapToInnerValue);
1281
+ const itemValues = props.items.flatMap((item) => {
1282
+ return Array.isArray(getPath(item, key.split("."))) && getPath(item, key.split(".")).length == 0 ? undefined : getPath(item, key.split("."))
1283
+ }).map(mapToInnerValue);
1234
1284
  const distinctValues = [...new Set(itemValues)];
1235
1285
 
1236
- value = distinctValues.map((dv): FSDataTableFilter => ({
1237
- hidden: currentFilters?.find((cf) => cf.value == (dv || null))?.hidden ?? false,
1238
- text: dv?.toString() ?? "—",
1239
- value: dv || null,
1240
- filter: header.methodFilter ?? ((_, property) => {
1241
- property = [property].flat().map(mapToInnerValue);
1242
- return Array.isArray(property) ? property.includes(dv) || (!dv && property.length == 0) : (!dv && !property) || dv == property;
1243
- })
1244
- }));
1286
+ value = distinctValues.map((dv): FSDataTableFilter => {
1287
+ return {
1288
+ hidden: currentFilters?.find((cf) => cf.value == (dv || null))?.hidden ?? false,
1289
+ text: dv?.toString() ?? "—",
1290
+ value: dv || null,
1291
+ filter: header.methodFilter ?? ((_, property, item) => {
1292
+ if (header.methodFilterRaw) {
1293
+ return header.methodFilterRaw(dv, item);
1294
+ }
1295
+ const flat = [property].flat().map(mapToInnerValue);
1296
+ return (!dv && flat.length == 0) || flat.some(f => f == dv);
1297
+ })
1298
+ }
1299
+ });
1245
1300
  }
1301
+ filterDictionary[key] = value.sort((v1, v2) => {
1302
+ return v1.text.localeCompare(v2.text, undefined, { numeric: true });
1303
+ });
1246
1304
  }
1247
- filterDictionary[key] = value.sort((v1, v2) => {
1248
- return v1.text.localeCompare(v2.text, undefined, { numeric: true });
1249
- });
1250
1305
  }
1251
1306
  for (const [key, filters] of Object.entries(props.filters)) {
1252
1307
  for (const filter of filters) {
@@ -1313,6 +1368,7 @@ export default defineComponent({
1313
1368
  }, { threshold: [0.9] });
1314
1369
  }
1315
1370
  if (document.querySelector(`#${elementId}`)) {
1371
+ intersectionObserver.value.unobserve(document.querySelector(`#${elementId}`)!);
1316
1372
  intersectionObserver.value.observe(document.querySelector(`#${elementId}`)!);
1317
1373
  }
1318
1374
  return;
@@ -1349,10 +1405,10 @@ export default defineComponent({
1349
1405
  };
1350
1406
 
1351
1407
  const resetRowIndex = (initialIndex: number, currentIndex: number, draggedElement: HTMLElement, tbodyElement: HTMLElement) => {
1352
- if (initialIndex > currentIndex) {
1408
+ if (initialIndex > currentIndex && tbodyElement.children[initialIndex]) {
1353
1409
  tbodyElement.children[initialIndex].insertAdjacentElement("afterend", draggedElement);
1354
1410
  }
1355
- else {
1411
+ else if(tbodyElement.children[initialIndex]) {
1356
1412
  tbodyElement.children[initialIndex].insertAdjacentElement("beforebegin", draggedElement);
1357
1413
  }
1358
1414
  };
@@ -1468,8 +1524,17 @@ export default defineComponent({
1468
1524
  }
1469
1525
  });
1470
1526
 
1527
+ watch(() => props.showFilters, () => {
1528
+ innerShowFilters.value = props.showFilters;
1529
+ });
1530
+
1471
1531
  watch(innerSearch, () => {
1472
1532
  innerPage.value = 1;
1533
+ emit("update:search", innerSearch.value);
1534
+ });
1535
+
1536
+ watch(innerShowFilters, () => {
1537
+ emit("update:showFilters", innerShowFilters.value);
1473
1538
  });
1474
1539
 
1475
1540
  watch(filters, () => {
@@ -1477,6 +1542,10 @@ export default defineComponent({
1477
1542
  .some((key) => filters.value[key].some((filter) => filter.hidden));
1478
1543
  }, { deep: true });
1479
1544
 
1545
+ watch(size, () => {
1546
+ observeIntersection();
1547
+ });
1548
+
1480
1549
  watch(innerMode, () => {
1481
1550
  emit("update:mode", innerMode.value);
1482
1551
  size.value = props.sizeIterator;
@@ -1501,13 +1570,14 @@ export default defineComponent({
1501
1570
 
1502
1571
  watch(() => props.items, async () => {
1503
1572
  computeFilters();
1573
+ observeIntersection();
1504
1574
  if (innerPage.value !== 1) {
1505
1575
  const formerPage = innerPage.value;
1506
1576
  innerPage.value = 1;
1507
1577
  await nextTick();
1508
1578
  innerPage.value = formerPage;
1509
1579
  }
1510
- });
1580
+ }, { deep: true });
1511
1581
 
1512
1582
  return {
1513
1583
  ColorEnum,
@@ -1518,9 +1588,8 @@ export default defineComponent({
1518
1588
  innerMode,
1519
1589
  modeOptions,
1520
1590
  innerPage,
1521
- hasToolbar,
1522
1591
  pageOptions,
1523
- showFilters,
1592
+ innerShowFilters,
1524
1593
  showFiltersRow,
1525
1594
  showFiltersDivider,
1526
1595
  hasVisibleFilters,
@@ -1537,6 +1606,7 @@ export default defineComponent({
1537
1606
  classes,
1538
1607
  style,
1539
1608
  size,
1609
+ isMobileSized,
1540
1610
  isExtraSmall,
1541
1611
  draggableDisabled,
1542
1612
  elementId,
@@ -74,7 +74,7 @@ export default defineComponent({
74
74
  const dragged = (event.target as HTMLElement)?.closest(props.elementSelector) as HTMLElement;
75
75
  dragged.classList.add("fs-draggable-dragging");
76
76
  dragged.classList.add("fs-draggable-dragging-grabbegin");
77
- dragged.dataset.initialIndex = props.item?.index ?? props.item?.value;
77
+ dragged.dataset.initialIndex = props.item.index;
78
78
  event.preventDefault();
79
79
  }
80
80
  }, mobileGrabThreshold);
@@ -171,7 +171,7 @@ export default defineComponent({
171
171
  return;
172
172
  }
173
173
  const dragged = (event.target as HTMLElement)?.closest(props.elementSelector) as HTMLElement;
174
- dragged.dataset.initialIndex = props.item?.index ?? props.item?.value;
174
+ dragged.dataset.initialIndex = props.item.index;
175
175
  event.dataTransfer?.setDragImage(dragged, 25, 25);
176
176
 
177
177
  if (event.dataTransfer) {
@@ -23,38 +23,34 @@
23
23
  :border="false"
24
24
  >
25
25
  <FSCol
26
- padding="16px 0 24px 16px"
26
+ padding="20px"
27
27
  gap="12px"
28
28
  >
29
29
  <FSCol
30
- padding="0 16px 0 0"
31
30
  gap="12px"
32
31
  >
33
32
  <FSSpan
34
33
  font="text-overline"
35
34
  >
36
- {{ $tr("ui.data-table.filter", "Filter") }}
35
+ {{ $tr("ui.common.filter", "Filter") }}
37
36
  </FSSpan>
38
37
  <FSChip
39
38
  class="fs-filter-button-chip"
40
- :label="$tr('ui.data-table.all-values', 'All values')"
39
+ :label="$tr('ui.common.all-values', 'All values')"
41
40
  :height="['30px', '24px']"
42
41
  :variant="getAllVariant()"
43
42
  :color="$props.color"
44
43
  :editable="true"
45
44
  @click="onToggleAll"
46
45
  />
47
- <FSDivider
48
- padding="0 8px 0 0"
49
- />
46
+ <FSDivider />
50
47
  <FSSearchField
48
+ :hideHeader="true"
51
49
  class="fs-filter-button-search"
52
- prependInnerIcon="mdi-magnify"
53
50
  v-model="search"
54
51
  />
55
52
  </FSCol>
56
53
  <FSFadeOut
57
- padding="0 8px 0 0"
58
54
  maxHeight="360px"
59
55
  >
60
56
  <FSCol
@@ -140,10 +136,10 @@ export default defineComponent({
140
136
  if (props.filters) {
141
137
  const hidden = props.filters.filter(f => f.hidden).length;
142
138
  if (hidden > 0) {
143
- return $tr("ui.data-table.some-filters-visible", "{0}: {1} visible", props.header.text, (props.filters.length - hidden).toString());
139
+ return $tr("filter-button.some-filters-visible", "{0}: {1} visible", props.header.text, (props.filters.length - hidden).toString());
144
140
  }
145
141
  }
146
- return $tr("ui.data-table.all-filters-visible", "{0}: All visible", props.header.text);
142
+ return $tr("filter-button.all-filters-visible", "{0}: All visible", props.header.text);
147
143
  }
148
144
  return null;
149
145
  });