@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,202 +1,348 @@
1
1
  <template>
2
- <FSCol>
3
- <template
4
- v-if="isExtraSmall"
2
+ <FSCol
3
+ v-if="$props.loading"
4
+ >
5
+ <FSLoader
6
+ v-if="!$props.hideHeader"
7
+ variant="text-overline"
8
+ />
9
+ <FSLoader
10
+ v-if="$props.loading"
11
+ width="100%"
12
+ :height="['40px', '36px']"
13
+ />
14
+ </FSCol>
15
+ <FSCol
16
+ v-else-if="isExtraSmall"
17
+ >
18
+ <FSTextField
19
+ :validationValue="$props.modelValue"
20
+ :description="$props.description"
21
+ :hideHeader="$props.hideHeader"
22
+ :clearable="$props.clearable"
23
+ :editable="$props.editable"
24
+ :required="$props.required"
25
+ :validateOn="validateOn"
26
+ :label="$props.label"
27
+ :rules="$props.rules"
28
+ :messages="messages"
29
+ :readonly="true"
30
+ :modelValue="mobileValue"
31
+ @click="openMobileOverlay"
32
+ v-bind="$attrs"
5
33
  >
6
- <FSTextField
7
- :validationValue="$props.modelValue"
8
- :description="$props.description"
9
- :hideHeader="$props.hideHeader"
10
- :clearable="$props.clearable"
11
- :editable="$props.editable"
12
- :required="$props.required"
13
- :validateOn="validateOn"
14
- :label="$props.label"
15
- :rules="$props.rules"
16
- :messages="messages"
17
- :readonly="true"
18
- :modelValue="mobileValue"
19
- @update:modelValue="$emit('update:modelValue', $event)"
20
- @click="openMobileOverlay"
21
- v-bind="$attrs"
34
+ <template
35
+ v-for="(_, name) in $slots"
36
+ v-slot:[name]="slotData"
22
37
  >
23
- <template
24
- v-for="(_, name) in $slots"
25
- v-slot:[name]="slotData"
26
- >
27
- <slot
28
- :name="name"
29
- v-bind="slotData"
30
- />
31
- </template>
32
- <template
33
- v-if="mobileSelectionProps"
34
- #prepend-inner
38
+ <slot
39
+ :name="name"
40
+ v-bind="slotData"
41
+ />
42
+ </template>
43
+ <template
44
+ #prepend-inner
45
+ >
46
+ <slot
47
+ v-if="selectedItem"
48
+ name="item-prepend"
49
+ v-bind="{ item: selectedItem }"
50
+ />
51
+ </template>
52
+ <template
53
+ #clear
54
+ >
55
+ <FSRow
56
+ :wrap="false"
35
57
  >
36
58
  <slot
37
- name="selection-mobile"
38
- v-bind="mobileSelectionProps"
59
+ v-if="selectedItem"
60
+ name="item-append"
61
+ v-bind="{ item: selectedItem }"
39
62
  />
40
- </template>
41
- <template
42
- #append-inner
43
- >
44
63
  <slot
45
- name="append-inner"
64
+ name="clear"
46
65
  >
47
66
  <FSButton
48
- icon="mdi-chevron-down"
67
+ v-if="$props.clearable && $props.editable && !!$props.modelValue"
68
+ icon="mdi-close"
49
69
  variant="icon"
50
- :editable="$props.editable"
51
70
  :color="ColorEnum.Dark"
52
- @click="openMobileOverlay"
71
+ @click="onClear"
53
72
  />
54
73
  </slot>
55
- </template>
56
- </FSTextField>
57
- <FSDialogMenu
58
- v-model="dialog"
74
+ </FSRow>
75
+ </template>
76
+ <template
77
+ #append-inner
59
78
  >
60
- <template
61
- #body
79
+ <FSButton
80
+ icon="mdi-chevron-down"
81
+ variant="icon"
82
+ :editable="$props.editable"
83
+ :color="ColorEnum.Dark"
84
+ @click="openMobileOverlay"
85
+ />
86
+ </template>
87
+ </FSTextField>
88
+ <FSSlideGroup
89
+ v-if="$props.multiple && Array.isArray($props.modelValue)"
90
+ >
91
+ <FSCard
92
+ v-for="(item, index) in $props.items.filter((item: any) => $props.modelValue.includes(item[$props.itemValue!]))"
93
+ variant="standard"
94
+ :height="['40px', '36px']"
95
+ :color="ColorEnum.Light"
96
+ :border="false"
97
+ :key="index"
98
+ >
99
+ <FSRow
100
+ align="center-left"
101
+ padding="0 8px"
102
+ :wrap="false"
62
103
  >
63
- <FSFadeOut
64
- :maxHeight="maxHeight"
104
+ <slot
105
+ name="item-prepend"
106
+ v-bind="{ item }"
107
+ />
108
+ <FSSpan>
109
+ {{ item[$props.itemTitle!] }}
110
+ </FSSpan>
111
+ <slot
112
+ name="item-append"
113
+ v-bind="{ item }"
114
+ />
115
+ <FSButton
116
+ icon="mdi-close"
117
+ variant="icon"
118
+ :color="ColorEnum.Dark"
119
+ @click="() => onCheckboxChange(item[$props.itemValue!])"
120
+ />
121
+ </FSRow>
122
+ </FSCard>
123
+ </FSSlideGroup>
124
+ <FSDialogMenu
125
+ padding="16px"
126
+ v-model="dialog"
127
+ >
128
+ <template
129
+ #body
130
+ >
131
+ <FSFadeOut
132
+ :maxHeight="maxHeight"
133
+ >
134
+ <FSCol
135
+ gap="12px"
65
136
  >
66
- <FSCol
67
- v-if="$props.multiple"
68
- gap="12px"
137
+ <FSRow
138
+ v-for="(item, index) in $props.items"
139
+ align="center-left"
140
+ height="36px"
141
+ :wrap="false"
142
+ :key="index"
143
+ @click="$props.multiple ?
144
+ onCheckboxChange(item[$props.itemValue!]) :
145
+ onRadioChange(item[$props.itemValue!])
146
+ "
69
147
  >
70
148
  <FSRow
71
- v-for="(item, index) in $props.items"
72
- :key="index"
149
+ style="min-width: 0;"
150
+ :wrap="false"
73
151
  >
74
- <FSCheckbox
75
- :label="item[$props.itemTitle]"
76
- :editable="$props.editable"
77
- :modelValue="$props.modelValue?.includes(item[$props.itemValue])"
78
- @update:modelValue="() => onCheckboxChange(item[$props.itemValue])"
152
+ <slot
153
+ name="item-prepend"
154
+ v-bind="{ item }"
155
+ />
156
+ <FSSpan
157
+ :font="selectedItems.includes(item) ? 'text-button' : 'text-body'"
79
158
  >
80
- <template
81
- #label="{ font }"
82
- >
83
- <slot
84
- name="item-label"
85
- v-bind="mobileItemProps(item, font)"
86
- />
87
- </template>
88
- </FSCheckbox>
159
+ {{ item[$props.itemTitle!] }}
160
+ </FSSpan>
89
161
  </FSRow>
90
- </FSCol>
91
- <FSRadioGroup
92
- v-else
93
- gap="12px"
94
- :values="$props.items.map((item: any) => ({ value: item[$props.itemValue], label: item[$props.itemTitle], item: item }))"
95
- :editable="$props.editable"
96
- :modelValue="$props.modelValue"
97
- @update:modelValue="onRadioChange"
98
- >
99
- <template
100
- #label="{ item, font }"
162
+ <FSRow
163
+ align="center-right"
164
+ width="hug"
165
+ :wrap="false"
101
166
  >
102
167
  <slot
103
- name="item-label"
104
- v-bind="mobileItemProps(item, font)"
168
+ name="item-append"
169
+ v-bind="{ item }"
105
170
  />
106
- </template>
107
- </FSRadioGroup>
108
- </FSFadeOut>
109
- </template>
110
- </FSDialogMenu>
111
- </template>
112
- <template
171
+ <FSCheckbox
172
+ v-if="$props.multiple"
173
+ :editable="$props.editable"
174
+ :modelValue="$props.modelValue?.includes(item[$props.itemValue!])"
175
+ @update:modelValue="onCheckboxChange(item[$props.itemValue!])"
176
+ />
177
+ <FSRadio
178
+ v-else
179
+ :selected="$props.modelValue === item[$props.itemValue!]"
180
+ :editable="$props.editable"
181
+ :item="item"
182
+ :modelValue="item[$props.itemValue!]"
183
+ @update:modelValue="onRadioChange(item[$props.itemValue!])"
184
+ />
185
+ </FSRow>
186
+ </FSRow>
187
+ </FSCol>
188
+ </FSFadeOut>
189
+ <FSRow
190
+ v-if="!$props.items || $props.items.length === 0"
191
+ padding="4px 3px"
192
+ >
193
+ <FSSpan>
194
+ {{ $tr("ui.common.no-data", "No data") }}
195
+ </FSSpan>
196
+ </FSRow>
197
+ </template>
198
+ </FSDialogMenu>
199
+ </FSCol>
200
+ <FSBaseField
201
+ v-else
202
+ :style="style"
203
+ :description="$props.description"
204
+ :hideHeader="$props.hideHeader"
205
+ :required="$props.required"
206
+ :editable="$props.editable"
207
+ :label="$props.label"
208
+ :messages="messages"
209
+ >
210
+ <FSToggleSet
211
+ v-if="$props.toggleSet"
212
+ :editable="$props.editable"
213
+ :multiple="$props.multiple"
214
+ :required="$props.required"
215
+ :values="$props.items"
216
+ :rules="$props.rules"
217
+ :modelValue="$props.modelValue"
218
+ @update:modelValue="$emit('update:modelValue', $event)"
219
+ v-bind="$attrs"
220
+ >
221
+ <template
222
+ v-for="(_, name) in toggleSetSlots"
223
+ v-slot:[name]="slotData"
224
+ >
225
+ <slot
226
+ :name="`toggle-set-${name}`"
227
+ v-bind="slotData"
228
+ />
229
+ </template>
230
+ </FSToggleSet>
231
+ <FSCol
113
232
  v-else
114
233
  >
115
- <FSBaseField
116
- :description="$props.description"
117
- :hideHeader="$props.hideHeader"
118
- :required="$props.required"
119
- :editable="$props.editable"
120
- :label="$props.label"
121
- :messages="messages"
234
+ <v-select
235
+ class="fs-select-field"
236
+ variant="outlined"
237
+ :clearable="$props.clearable && $props.editable && !!$props.modelValue"
238
+ :itemTitle="$props.itemTitle"
239
+ :itemValue="$props.itemValue"
240
+ :readonly="!$props.editable"
241
+ :multiple="$props.multiple"
242
+ :validateOn="validateOn"
243
+ :persistentClear="true"
244
+ :listProps="listStyle"
245
+ :returnObject="false"
246
+ :items="$props.items"
247
+ :rules="$props.rules"
248
+ :hideDetails="true"
249
+ :menuIcon="null"
250
+ :modelValue="$props.modelValue"
251
+ @update:modelValue="onSingleChange"
252
+ v-bind="$attrs"
122
253
  >
123
- <v-select
124
- class="fs-select-field"
125
- variant="outlined"
126
- :clearable="$props.clearable && $props.editable && !!$props.modelValue"
127
- :itemTitle="$props.itemTitle"
128
- :itemValue="$props.itemValue"
129
- :readonly="!$props.editable"
130
- :multiple="$props.multiple"
131
- :validateOn="validateOn"
132
- :persistentClear="true"
133
- :listProps="listStyle"
134
- :returnObject="false"
135
- :items="$props.items"
136
- :rules="$props.rules"
137
- :hideDetails="true"
138
- :menuIcon="null"
139
- :style="style"
140
- :modelValue="$props.modelValue"
141
- @update:modelValue="$emit('update:modelValue', $event)"
142
- v-bind="$attrs"
254
+ <template
255
+ v-for="(_, name) in selectSlots"
256
+ v-slot:[name]="slotData"
143
257
  >
144
- <template
145
- v-for="(_, name) in $slots"
146
- v-slot:[name]="slotData"
147
- >
148
- <slot
149
- :name="name"
150
- v-bind="slotData"
151
- />
152
- </template>
153
- <template
154
- #item="{ props, item }"
258
+ <slot
259
+ :name="`select-${name}`"
260
+ v-bind="slotData"
261
+ />
262
+ </template>
263
+ <template
264
+ #item="{ props, item }"
265
+ >
266
+ <v-list-item
267
+ v-bind="{ ...props, title: '' }"
155
268
  >
156
- <v-list-item
157
- v-bind="{ ...props, title: '' }"
269
+ <FSRow
270
+ align="center-left"
271
+ :wrap="false"
158
272
  >
159
- <FSRow
160
- align="center-left"
273
+ <FSCheckbox
274
+ v-if="$props.multiple"
275
+ :modelValue="$props.modelValue?.includes(item.raw[$props.itemValue!])"
276
+ @click="props.onClick"
161
277
  >
162
- <FSCheckbox
163
- v-if="$props.multiple"
164
- :modelValue="$props.modelValue?.includes(item.raw[$props.itemValue])"
165
- @click="props.onClick"
278
+ <template
279
+ #label="{ font }"
166
280
  >
167
- <template
168
- #label="{ font }"
281
+ <slot
282
+ name="item-prepend"
283
+ v-bind="{ item: item.raw }"
284
+ />
285
+ <FSSpan
286
+ :font="font"
169
287
  >
170
- <slot
171
- name="item-label"
172
- v-bind="{ item, font }"
173
- >
174
- <FSSpan
175
- :font="font"
176
- >
177
- {{ item.raw[$props.itemTitle] }}
178
- </FSSpan>
179
- </slot>
180
- </template>
181
- </FSCheckbox>
288
+ {{ item.raw[$props.itemTitle!] }}
289
+ </FSSpan>
290
+ </template>
291
+ </FSCheckbox>
292
+ <template
293
+ v-else
294
+ >
295
+ <slot
296
+ name="item-prepend"
297
+ v-bind="{ item: item.raw }"
298
+ />
182
299
  <FSSpan
183
- v-else
300
+ :font="$props.modelValue === item.raw[$props.itemTitle!] ? 'text-button' : 'text-body'"
184
301
  >
185
- <slot
186
- name="item-label"
187
- v-bind="{ item }"
188
- >
189
- <FSSpan>
190
- {{ item.raw[$props.itemTitle] }}
191
- </FSSpan>
192
- </slot>
302
+ {{ item.raw[$props.itemTitle!] }}
193
303
  </FSSpan>
304
+ </template>
305
+ <FSRow
306
+ align="center-right"
307
+ >
308
+ <slot
309
+ name="item-append"
310
+ v-bind="{ item: item.raw }"
311
+ />
194
312
  </FSRow>
195
- </v-list-item>
196
- </template>
197
- <template
198
- #clear
313
+ </FSRow>
314
+ </v-list-item>
315
+ </template>
316
+ <template
317
+ #prepend-inner
318
+ >
319
+ <slot
320
+ v-if="selectedItem"
321
+ name="item-prepend"
322
+ v-bind="{ item: selectedItem }"
323
+ />
324
+ </template>
325
+ <template
326
+ v-if="$props.multiple"
327
+ #selection="{ index }"
328
+ >
329
+ <FSSpan
330
+ v-if="index === $props.modelValue.length - 1"
199
331
  >
332
+ {{ $props.placeholder }}
333
+ </FSSpan>
334
+ </template>
335
+ <template
336
+ #clear
337
+ >
338
+ <FSRow
339
+ :wrap="false"
340
+ >
341
+ <slot
342
+ v-if="selectedItem"
343
+ name="item-append"
344
+ v-bind="{ item: selectedItem }"
345
+ />
200
346
  <slot
201
347
  name="clear"
202
348
  >
@@ -205,54 +351,96 @@
205
351
  icon="mdi-close"
206
352
  variant="icon"
207
353
  :color="ColorEnum.Dark"
208
- @click="$emit('update:modelValue', null)"
354
+ @click="onClear"
209
355
  />
210
356
  </slot>
211
- </template>
212
- <template
213
- #append-inner
357
+ </FSRow>
358
+ </template>
359
+ <template
360
+ #append-inner
361
+ >
362
+ <slot
363
+ name="append-inner"
214
364
  >
215
- <slot
216
- name="append-inner"
217
- >
218
- <FSButton
219
- icon="mdi-chevron-down"
220
- variant="icon"
221
- :editable="$props.editable"
222
- :color="ColorEnum.Dark"
223
- />
224
- </slot>
225
- </template>
226
- <template
227
- #no-data
365
+ <FSButton
366
+ icon="mdi-chevron-down"
367
+ variant="icon"
368
+ :editable="$props.editable"
369
+ :color="ColorEnum.Dark"
370
+ />
371
+ </slot>
372
+ </template>
373
+ <template
374
+ #no-data
375
+ >
376
+ <FSRow
377
+ v-if="!$props.items || $props.items.length === 0"
378
+ padding="15px"
228
379
  >
229
- <FSRow
230
- padding="17px"
231
- >
232
- <FSSpan>
233
- {{ $tr("ui.common.no-data", "No data") }}
234
- </FSSpan>
235
- </FSRow>
236
- </template>
237
- </v-select>
238
- </FSBaseField>
239
- </template>
240
- </FSCol>
380
+ <FSSpan>
381
+ {{ $tr("ui.common.no-data", "No data") }}
382
+ </FSSpan>
383
+ </FSRow>
384
+ </template>
385
+ </v-select>
386
+ <FSSlideGroup
387
+ v-if="$props.multiple && Array.isArray($props.modelValue)"
388
+ class="fs-select-field-multiple-slide-group"
389
+ >
390
+ <FSCard
391
+ v-for="(item, index) in $props.items.filter((item: any) => $props.modelValue.includes(item[$props.itemValue!]))"
392
+ variant="standard"
393
+ :height="['40px', '36px']"
394
+ :color="ColorEnum.Light"
395
+ :border="false"
396
+ :key="index"
397
+ >
398
+ <FSRow
399
+ align="center-left"
400
+ padding="0 8px"
401
+ >
402
+ <slot
403
+ name="item-prepend"
404
+ v-bind="{ item }"
405
+ />
406
+ <FSSpan>
407
+ {{ item[$props.itemTitle!] }}
408
+ </FSSpan>
409
+ <slot
410
+ name="item-append"
411
+ v-bind="{ item }"
412
+ />
413
+ <FSButton
414
+ icon="mdi-close"
415
+ variant="icon"
416
+ :editable="$props.editable"
417
+ :color="ColorEnum.Dark"
418
+ @click="() => onCheckboxChange(item[$props.itemValue!])"
419
+ />
420
+ </FSRow>
421
+ </FSCard>
422
+ </FSSlideGroup>
423
+ </FSCol>
424
+ </FSBaseField>
241
425
  </template>
242
426
 
243
427
  <script lang="ts">
244
- import { computed, defineComponent, type PropType, ref, type StyleValue } from "vue";
428
+ import { computed, defineComponent, type PropType, ref, type Slot, type StyleValue } from "vue";
245
429
 
246
- import { useBreakpoints, useColors, useRules } from "@dative-gpi/foundation-shared-components/composables";
430
+ import { useBreakpoints, useColors, useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
247
431
  import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
248
432
 
249
433
  import FSDialogMenu from "../FSDialogMenu.vue";
250
- import FSRadioGroup from "../FSRadioGroup.vue";
434
+ import FSSlideGroup from "../FSSlideGroup.vue";
435
+ import FSToggleSet from "../FSToggleSet.vue";
251
436
  import FSBaseField from "./FSBaseField.vue";
252
437
  import FSTextField from "./FSTextField.vue";
253
438
  import FSCheckbox from "../FSCheckbox.vue";
254
439
  import FSFadeOut from "../FSFadeOut.vue";
255
440
  import FSButton from "../FSButton.vue";
441
+ import FSLoader from "../FSLoader.vue";
442
+ import FSRadio from "../FSRadio.vue";
443
+ import FSCard from "../FSCard.vue";
256
444
  import FSSpan from "../FSSpan.vue";
257
445
  import FSCol from "../FSCol.vue";
258
446
  import FSRow from "../FSRow.vue";
@@ -261,12 +449,16 @@ export default defineComponent({
261
449
  name: "FSSelectField",
262
450
  components: {
263
451
  FSDialogMenu,
264
- FSRadioGroup,
452
+ FSSlideGroup,
265
453
  FSBaseField,
266
454
  FSTextField,
455
+ FSToggleSet,
267
456
  FSCheckbox,
268
457
  FSFadeOut,
269
458
  FSButton,
459
+ FSLoader,
460
+ FSRadio,
461
+ FSCard,
270
462
  FSSpan,
271
463
  FSCol,
272
464
  FSRow
@@ -277,6 +469,11 @@ export default defineComponent({
277
469
  required: false,
278
470
  default: null
279
471
  },
472
+ placeholder: {
473
+ type: String as PropType<string | null>,
474
+ required: false,
475
+ default: null
476
+ },
280
477
  description: {
281
478
  type: String as PropType<string | null>,
282
479
  required: false,
@@ -297,21 +494,21 @@ export default defineComponent({
297
494
  default: "label"
298
495
  },
299
496
  modelValue: {
300
- type: [Array, String, Number] as PropType<(string | number)[] | string | number | null>,
497
+ type: [Array, String, Number] as PropType<(string | number)[] | string | number | null | any>,
301
498
  required: false,
302
499
  default: null
303
500
  },
304
- hideHeader: {
501
+ multiple: {
305
502
  type: Boolean,
306
503
  required: false,
307
504
  default: false
308
505
  },
309
- required: {
506
+ hideHeader: {
310
507
  type: Boolean,
311
508
  required: false,
312
509
  default: false
313
510
  },
314
- multiple: {
511
+ required: {
315
512
  type: Boolean,
316
513
  required: false,
317
514
  default: false
@@ -335,13 +532,27 @@ export default defineComponent({
335
532
  type: Boolean,
336
533
  required: false,
337
534
  default: true
535
+ },
536
+ loading: {
537
+ type: Boolean,
538
+ required: false,
539
+ default: false
540
+ },
541
+ toggleSet: {
542
+ type: Boolean,
543
+ required: false,
544
+ default: false
338
545
  }
339
546
  },
340
547
  emits: ["update:modelValue"],
341
548
  setup(props, { emit }) {
549
+ const { fontStyles, isExtraSmall, isMobileSized } = useBreakpoints();
342
550
  const { validateOn, getMessages } = useRules();
343
- const { isExtraSmall } = useBreakpoints();
344
551
  const { getColors } = useColors();
552
+ const { slots } = useSlots();
553
+
554
+ delete slots.label;
555
+ delete slots.description;
345
556
 
346
557
  const backgrounds = getColors(ColorEnum.Background);
347
558
  const errors = getColors(ColorEnum.Error);
@@ -356,7 +567,10 @@ export default defineComponent({
356
567
  "--fs-select-field-cursor" : "default",
357
568
  "--fs-select-field-border-color" : lights.base,
358
569
  "--fs-select-field-color" : lights.dark,
359
- "--fs-select-field-active-border-color": lights.base
570
+ "--fs-select-field-active-border-color": lights.base,
571
+ "--fs-select-field-multiple-opacity" : "var(--v-disabled-opacity)",
572
+ "--fs-base-field-input-height" : isMobileSized.value ? "34px" : "38px",
573
+ ...fontStyles.value
360
574
  };
361
575
  }
362
576
  return {
@@ -365,11 +579,28 @@ export default defineComponent({
365
579
  "--fs-select-field-border-color" : lights.dark,
366
580
  "--fs-select-field-color" : darks.base,
367
581
  "--fs-select-field-active-border-color": darks.dark,
368
- "--fs-select-field-error-border-color" : errors.base
582
+ "--fs-select-field-error-border-color" : errors.base,
583
+ "--fs-select-field-multiple-opacity" : "1",
584
+ "--fs-base-field-input-height" : isMobileSized.value ? "34px" : "38px",
585
+ ...fontStyles.value
369
586
  };
370
587
  });
371
588
 
372
- const listStyle = computed((): { [key: string] : object } => {
589
+ const selectSlots = computed((): { [key: string]: Slot<any> } => {
590
+ return Object.keys(slots).filter(k => k.startsWith("select-")).reduce((acc: { [key: string]: Slot<any> }, key) => {
591
+ acc[key.substring("select-".length)] = slots[key];
592
+ return acc;
593
+ }, {});
594
+ });
595
+
596
+ const toggleSetSlots = computed((): { [key: string]: Slot<any> } => {
597
+ return Object.keys(slots).filter(k => k.startsWith("toggle-set-")).reduce((acc: { [key: string]: Slot<any> }, key) => {
598
+ acc[key.substring("toggle-set-".length)] = slots[key];
599
+ return acc;
600
+ }, {});
601
+ });
602
+
603
+ const listStyle = computed((): { style: StyleValue } => {
373
604
  return {
374
605
  style: style.value
375
606
  };
@@ -377,64 +608,46 @@ export default defineComponent({
377
608
 
378
609
  const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
379
610
 
380
- const maxHeight = computed(() => {
381
- const other = 8 + 8; // Paddings
382
- return `calc(100vh - 40px - ${other}px)`;
611
+ const selectedItem = computed((): any => {
612
+ if (props.multiple) {
613
+ return null;
614
+ }
615
+ if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
616
+ return props.items.find((item: any) => item[props.itemValue] === props.modelValue[0]) ?? null;
617
+ }
618
+ else if (props.modelValue) {
619
+ return props.items.find((item: any) => item[props.itemValue] === props.modelValue) ?? null;
620
+ }
621
+ return null;
383
622
  });
384
623
 
385
- const mobileValue = computed((): string | null => {
386
- if (props.multiple) {
387
- if (Array.isArray(props.modelValue)) {
388
- return props.modelValue.map((value: any) => {
389
- const item = props.items.find((item: object) => item[props.itemValue] === value);
390
- if (item) {
391
- return item[props.itemTitle];
392
- }
393
- }).filter(value => !!value).join(", ");
394
- }
624
+ const selectedItems = computed((): any[] => {
625
+ if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
626
+ return props.items.filter((item: any) => props.modelValue.includes(item[props.itemValue]));
395
627
  }
396
- if (props.modelValue) {
397
- const item = props.items.find((item: object) => item[props.itemValue] === props.modelValue);
628
+ else if (props.modelValue) {
629
+ const item = props.items.find((item: any) => item[props.itemValue] === props.modelValue);
398
630
  if (item) {
399
- return item[props.itemTitle];
631
+ return [item];
400
632
  }
401
633
  }
402
- return null;
634
+ return [];
403
635
  });
404
636
 
405
- const mobileSelectionProps = computed((): any | null => {
406
- const item = props.items.find((item: any) => item[props.itemValue] === props.modelValue);
407
- if (item) {
408
- return {
409
- item: {
410
- title: "",
411
- value: item[props.itemValue],
412
- props: {
413
- title: item[props.itemTitle],
414
- value: item[props.itemValue]
415
- },
416
- raw: { ...item }
417
- },
418
- font: "text-body"
419
- };
420
- }
421
- return null;
637
+ const maxHeight = computed(() => {
638
+ const other = 8 + 8; // Paddings
639
+ return `calc(100vh - 40px - ${other}px)`;
422
640
  });
423
641
 
424
- const mobileItemProps = (item: any, font: "text-body" | "text-button" | null): any => {
425
- return {
426
- item: {
427
- title: "",
428
- value: item[props.itemValue],
429
- props: {
430
- title: item[props.itemTitle],
431
- value: item[props.itemValue]
432
- },
433
- raw: { ...item }
434
- },
435
- font
642
+ const mobileValue = computed((): string | null => {
643
+ if (props.multiple && Array.isArray(props.modelValue) && props.modelValue.length > 0) {
644
+ return props.placeholder;
436
645
  }
437
- };
646
+ if (selectedItem.value) {
647
+ return selectedItem.value[props.itemTitle];
648
+ }
649
+ return null;
650
+ });
438
651
 
439
652
  const openMobileOverlay = () => {
440
653
  if (!props.editable) {
@@ -470,10 +683,21 @@ export default defineComponent({
470
683
  }
471
684
  };
472
685
 
686
+ const onSingleChange = (value: string) => {
687
+ emit("update:modelValue", value);
688
+ };
689
+
690
+ const onClear = () => {
691
+ emit("update:modelValue", null);
692
+ };
693
+
473
694
  return {
474
- mobileSelectionProps,
695
+ toggleSetSlots,
696
+ selectedItems,
475
697
  isExtraSmall,
698
+ selectedItem,
476
699
  mobileValue,
700
+ selectSlots,
477
701
  validateOn,
478
702
  ColorEnum,
479
703
  listStyle,
@@ -483,8 +707,9 @@ export default defineComponent({
483
707
  style,
484
708
  openMobileOverlay,
485
709
  onCheckboxChange,
486
- mobileItemProps,
487
- onRadioChange
710
+ onSingleChange,
711
+ onRadioChange,
712
+ onClear
488
713
  };
489
714
  }
490
715
  });