@dative-gpi/foundation-shared-components 1.0.26 → 1.0.28-remove-deprecated2

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 (265) hide show
  1. package/components/FSBreadcrumbs.vue +1 -0
  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 +20 -12
  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 +51 -32
  15. package/components/FSDialogMultiFormBody.vue +79 -56
  16. package/components/FSDialogRemove.vue +7 -7
  17. package/components/FSDialogSubmit.vue +20 -11
  18. package/components/FSEditImage.vue +1 -1
  19. package/components/FSEditImageUI.vue +20 -10
  20. package/components/FSFadeOut.vue +44 -18
  21. package/components/FSForm.vue +10 -8
  22. package/components/FSGrid.vue +1 -1
  23. package/components/FSIcon.vue +2 -1
  24. package/components/FSIconCard.vue +21 -4
  25. package/components/FSImage.vue +12 -4
  26. package/components/FSImageUI.vue +8 -15
  27. package/components/FSLink.vue +25 -9
  28. package/components/FSLoader.vue +28 -11
  29. package/components/FSOptionGroup.vue +51 -3
  30. package/components/FSRouterLink.vue +42 -0
  31. package/components/FSSlideGroup.vue +19 -5
  32. package/components/FSSpan.vue +9 -2
  33. package/components/FSSwitch.vue +57 -27
  34. package/components/FSTab.vue +15 -13
  35. package/components/FSTabs.vue +32 -7
  36. package/components/FSTag.vue +14 -3
  37. package/components/FSTagGroup.vue +1 -1
  38. package/components/FSText.vue +4 -2
  39. package/components/FSWindow.vue +128 -4
  40. package/components/FSWrapGroup.vue +13 -1
  41. package/components/agenda/FSAgenda.vue +223 -0
  42. package/components/agenda/FSAgendaDialogCalendar.vue +76 -0
  43. package/components/agenda/FSAgendaHeader.vue +215 -0
  44. package/components/agenda/FSAgendaHorizontalEvent.vue +174 -0
  45. package/components/agenda/FSAgendaHorizontalTimeLineMarker.vue +46 -0
  46. package/components/agenda/FSAgendaHoursCol.vue +103 -0
  47. package/components/agenda/FSAgendaHoursRow.vue +164 -0
  48. package/components/agenda/FSAgendaVerticalEvent.vue +160 -0
  49. package/components/agenda/FSAgendaVerticalTimeLineMarker.vue +46 -0
  50. package/components/agenda/FSDayAgenda.vue +199 -0
  51. package/components/agenda/FSMonthAgenda.vue +252 -0
  52. package/components/agenda/FSSelectAgendaMode.vue +54 -0
  53. package/components/agenda/FSWeekAgenda.vue +323 -0
  54. package/components/autocompletes/FSAutoCompleteAddress.vue +22 -20
  55. package/components/autocompletes/FSAutocompleteLanguage.vue +24 -39
  56. package/components/autocompletes/FSAutocompleteTimeZone.vue +26 -38
  57. package/components/buttons/FSButtonAdd.vue +1 -1
  58. package/components/buttons/FSButtonAddLabel.vue +1 -1
  59. package/components/buttons/FSButtonCancel.vue +1 -1
  60. package/components/buttons/FSButtonCancelLabel.vue +1 -1
  61. package/components/buttons/FSButtonCopy.vue +28 -0
  62. package/components/buttons/FSButtonCopyIcon.vue +28 -0
  63. package/components/buttons/FSButtonCopyLabel.vue +27 -0
  64. package/components/buttons/FSButtonCopyMini.vue +28 -0
  65. package/components/buttons/FSButtonDragIcon.vue +27 -0
  66. package/components/buttons/FSButtonDuplicate.vue +1 -1
  67. package/components/buttons/FSButtonDuplicateLabel.vue +1 -1
  68. package/components/buttons/FSButtonEdit.vue +1 -1
  69. package/components/buttons/FSButtonEditLabel.vue +1 -1
  70. package/components/buttons/FSButtonFile.vue +1 -1
  71. package/components/buttons/FSButtonFileLabel.vue +1 -1
  72. package/components/buttons/FSButtonNext.vue +1 -1
  73. package/components/buttons/FSButtonNextLabel.vue +1 -1
  74. package/components/buttons/FSButtonPrevious.vue +1 -1
  75. package/components/buttons/FSButtonPreviousLabel.vue +1 -1
  76. package/components/buttons/FSButtonRedo.vue +1 -1
  77. package/components/buttons/FSButtonRedoLabel.vue +1 -1
  78. package/components/buttons/FSButtonRemove.vue +1 -1
  79. package/components/buttons/FSButtonRemoveLabel.vue +1 -1
  80. package/components/buttons/FSButtonSave.vue +1 -1
  81. package/components/buttons/FSButtonSaveLabel.vue +1 -1
  82. package/components/buttons/FSButtonSearch.vue +1 -1
  83. package/components/buttons/FSButtonSearchLabel.vue +1 -1
  84. package/components/buttons/FSButtonUndo.vue +1 -1
  85. package/components/buttons/FSButtonUndoLabel.vue +1 -1
  86. package/components/buttons/FSButtonUpdate.vue +1 -1
  87. package/components/buttons/FSButtonUpdateLabel.vue +1 -1
  88. package/components/buttons/FSButtonValidate.vue +1 -1
  89. package/components/buttons/FSButtonValidateLabel.vue +1 -1
  90. package/components/calendar/FSSimpleCalendar.vue +145 -0
  91. package/components/calendar/FSSimpleCalendarHeader.vue +60 -0
  92. package/components/calendar/FSSimpleMonthSelector.vue +138 -0
  93. package/components/deviceOrganisations/FSConnectivity.vue +11 -1
  94. package/components/deviceOrganisations/FSConnectivityCard.vue +19 -47
  95. package/components/deviceOrganisations/FSStatus.vue +11 -1
  96. package/components/deviceOrganisations/FSStatusCard.vue +35 -61
  97. package/components/deviceOrganisations/FSStatusesCarousel.vue +1 -0
  98. package/components/deviceOrganisations/FSStatusesRow.vue +9 -3
  99. package/components/deviceOrganisations/FSWorstAlert.vue +30 -37
  100. package/components/deviceOrganisations/FSWorstAlertCard.vue +36 -85
  101. package/components/fields/FSAutocompleteField.vue +516 -341
  102. package/components/fields/FSAutocompleteTag.vue +100 -0
  103. package/components/fields/FSBaseField.vue +44 -27
  104. package/components/fields/FSColorField.vue +42 -39
  105. package/components/fields/FSCommentField.vue +105 -0
  106. package/components/fields/FSDateField.vue +2 -2
  107. package/components/fields/FSDateRangeField.vue +3 -2
  108. package/components/fields/FSDateTimeField.vue +4 -3
  109. package/components/fields/FSDateTimeRangeField.vue +8 -6
  110. package/components/fields/FSEntityFieldUI.vue +271 -0
  111. package/components/fields/FSGradientField.vue +27 -33
  112. package/components/fields/FSIconField.vue +0 -1
  113. package/components/fields/FSMagicConfigField.vue +34 -19
  114. package/components/fields/FSMagicField.vue +9 -4
  115. package/components/fields/FSNumberField.vue +13 -6
  116. package/components/fields/FSRichTextField.vue +102 -52
  117. package/components/fields/FSSearchField.vue +9 -115
  118. package/components/fields/FSSelectField.vue +489 -252
  119. package/components/fields/FSTagField.vue +1 -1
  120. package/components/fields/FSTermField.vue +33 -11
  121. package/components/fields/FSTextArea.vue +26 -7
  122. package/components/fields/FSTextField.vue +19 -10
  123. package/components/fields/FSTimeRangeField.vue +304 -0
  124. package/components/fields/FSTimeStepField.vue +3 -3
  125. package/components/fields/FSTranslateField.vue +4 -3
  126. package/components/fields/FSTranslateRichTextField.vue +15 -10
  127. package/components/fields/FSTranslateTextArea.vue +233 -0
  128. package/components/fields/FSTreeViewField.vue +3 -3
  129. package/components/fields/periodicField/FSPeriodicDailyField.vue +120 -0
  130. package/components/fields/periodicField/FSPeriodicField.vue +131 -0
  131. package/components/fields/periodicField/FSPeriodicMonthlyField.vue +222 -0
  132. package/components/fields/periodicField/FSPeriodicWeeklyField.vue +120 -0
  133. package/components/fields/periodicField/FSPeriodicYearlyField.vue +144 -0
  134. package/components/lists/FSDataTableUI.vue +148 -89
  135. package/components/lists/FSDraggable.vue +2 -2
  136. package/components/lists/FSFilterButton.vue +23 -28
  137. package/components/lists/FSHeaderButton.vue +4 -4
  138. package/components/lists/FSHiddenButton.vue +11 -15
  139. package/components/lists/FSLoadDataTable.vue +10 -7
  140. package/components/lists/FSSimpleList.vue +234 -0
  141. package/components/lists/FSSimpleListItem.vue +132 -0
  142. package/components/map/FSMap.vue +280 -399
  143. package/components/map/FSMapFeatureGroup.vue +51 -0
  144. package/components/map/FSMapLayerButton.vue +5 -5
  145. package/components/map/FSMapMarker.vue +120 -0
  146. package/components/map/FSMapMarkerClusterGroup.vue +72 -0
  147. package/components/map/FSMapOverlay.vue +70 -82
  148. package/components/map/FSMapPolygon.vue +81 -0
  149. package/components/map/FSMapTileLayer.vue +50 -0
  150. package/components/map/keys.ts +4 -0
  151. package/components/selects/FSSelectAutoRefresh.vue +9 -9
  152. package/components/selects/FSSelectDashboardVariableType.vue +5 -4
  153. package/components/selects/FSSelectDateSetting.vue +3 -2
  154. package/components/selects/FSSelectDays.vue +9 -9
  155. package/components/selects/FSSelectListMode.vue +51 -0
  156. package/components/selects/FSSelectMonths.vue +67 -0
  157. package/components/selects/chartSelectors/FSAggregationSelector.vue +52 -0
  158. package/components/selects/chartSelectors/FSAxisTypeSelector.vue +49 -0
  159. package/components/selects/chartSelectors/FSDisplayAsSelector.vue +53 -0
  160. package/components/selects/chartSelectors/FSFilterTypeSelector.vue +54 -0
  161. package/components/selects/chartSelectors/FSHeatmapRuleSelector.vue +54 -0
  162. package/components/selects/chartSelectors/FSOperationOnSelector.vue +53 -0
  163. package/components/selects/chartSelectors/FSPlanningTypeSelector.vue +53 -0
  164. package/components/selects/chartSelectors/FSPlotPerSelector.vue +52 -0
  165. package/components/selects/chartSelectors/FSSelectEntityType.vue +59 -0
  166. package/components/selects/chartSelectors/FSSerieTypeSelector.vue +53 -0
  167. package/components/tiles/FSAlertTileUI.vue +90 -0
  168. package/components/tiles/FSChartTile.vue +73 -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 +134 -0
  184. package/components/views/desktop/FSBaseDesktopView.vue +53 -0
  185. package/components/views/desktop/FSBaseEntityDesktopView.vue +208 -0
  186. package/components/views/mobile/FSBaseDefaultMobileView.vue +132 -0
  187. package/components/views/mobile/FSBaseEntityMobileView.vue +198 -0
  188. package/components/views/mobile/FSBaseMobileView.vue +53 -0
  189. package/composables/useAddress.ts +2 -2
  190. package/composables/useBreakpoints.ts +39 -3
  191. package/composables/useColors.ts +3 -2
  192. package/composables/useMagicFieldProvider.ts +1 -0
  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 +5 -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 +6 -12
  210. package/styles/components/fs_card.scss +0 -1
  211. package/styles/components/fs_clickable.scss +7 -14
  212. package/styles/components/fs_clock.scss +0 -10
  213. package/styles/components/fs_color_field.scss +1 -4
  214. package/styles/components/fs_data_table.scss +6 -9
  215. package/styles/components/fs_dialog.scss +7 -17
  216. package/styles/components/fs_edit_image.scss +8 -0
  217. package/styles/components/fs_fade_out.scss +11 -2
  218. package/styles/components/fs_filter_button.scss +1 -6
  219. package/styles/components/fs_gradient_field.scss +11 -11
  220. package/styles/components/fs_hidden_button.scss +2 -7
  221. package/styles/components/fs_image_card.scss +1 -1
  222. package/styles/components/fs_magic_config_field.scss +1 -2
  223. package/styles/components/fs_map.scss +36 -30
  224. package/styles/components/fs_meta_field.scss +3 -5
  225. package/styles/components/fs_option_group.scss +15 -5
  226. package/styles/components/fs_rich_text_field.scss +1 -9
  227. package/styles/components/fs_select_date_settings.scss +3 -0
  228. package/styles/components/fs_select_field.scss +0 -13
  229. package/styles/components/fs_slide_group.scss +7 -0
  230. package/styles/components/fs_span.scss +2 -1
  231. package/styles/components/fs_switch.scss +1 -0
  232. package/styles/components/fs_tabs.scss +10 -24
  233. package/styles/components/fs_tag.scss +3 -19
  234. package/styles/components/fs_text_area.scss +13 -17
  235. package/styles/components/fs_tile.scss +21 -15
  236. package/styles/components/fs_window.scss +7 -0
  237. package/styles/components/fs_wrap_group.scss +7 -0
  238. package/styles/components/index.scss +5 -5
  239. package/styles/globals/index.scss +1 -5
  240. package/styles/globals/overrides.scss +17 -57
  241. package/styles/globals/text_fonts.scss +18 -66
  242. package/tools/alertsTools.ts +69 -0
  243. package/tools/chartsTools.ts +427 -0
  244. package/tools/index.ts +3 -0
  245. package/tools/timeRangeTools.ts +125 -0
  246. package/utils/filter.ts +18 -0
  247. package/utils/index.ts +1 -0
  248. package/utils/leafletMarkers.ts +9 -3
  249. package/utils/sort.ts +2 -2
  250. package/utils/statuses.ts +1 -1
  251. package/utils/time.ts +17 -17
  252. package/components/autocompletes/FSAutocompleteTag.vue +0 -138
  253. package/components/fields/FSTimeSlotField.vue +0 -250
  254. package/components/map/FSMapEditPointAddressOverlay.vue +0 -164
  255. package/components/views/FSEntityHeader.vue +0 -350
  256. package/components/views/FSListHeader.vue +0 -83
  257. package/components/views/FSListView.vue +0 -83
  258. package/components/views/FSSkeletonView.vue +0 -100
  259. package/styles/components/fs_icon_field.scss +0 -12
  260. package/styles/components/fs_map_overlay.scss +0 -38
  261. package/styles/components/fs_tag_field.scss +0 -8
  262. package/styles/components/fs_time_field.scss +0 -12
  263. package/styles/components/fs_timeslot_field.scss +0 -12
  264. package/styles/globals/breakpoints.scss +0 -20
  265. package/styles/globals/fixes.scss +0 -5
@@ -1,202 +1,364 @@
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
- :height="height"
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
+ v-model="dialog"
126
+ >
127
+ <template
128
+ #body
129
+ >
130
+ <FSFadeOut
131
+ :maxHeight="maxHeight"
132
+ >
133
+ <FSCol
134
+ gap="12px"
65
135
  >
66
- <FSCol
67
- v-if="$props.multiple"
68
- gap="12px"
136
+ <FSRow
137
+ v-for="(item, index) in $props.items"
138
+ :key="index"
69
139
  >
70
- <FSRow
71
- v-for="(item, index) in $props.items"
72
- :key="index"
140
+ <FSCheckbox
141
+ v-if="$props.multiple"
142
+ :label="item[$props.itemTitle!]"
143
+ :editable="$props.editable"
144
+ :modelValue="$props.modelValue?.includes(item[$props.itemValue!])"
145
+ @update:modelValue="() => onCheckboxChange(item[$props.itemValue!])"
73
146
  >
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])"
147
+ <template
148
+ #label="{ font }"
79
149
  >
80
- <template
81
- #label="{ font }"
150
+ <FSRow
151
+ align="center-left"
152
+ :wrap="false"
82
153
  >
83
154
  <slot
84
- name="item-label"
85
- v-bind="mobileItemProps(item, font)"
155
+ name="item-prepend"
156
+ v-bind="{ item }"
86
157
  />
87
- </template>
88
- </FSCheckbox>
89
- </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 }"
158
+ <FSSpan
159
+ :font="font"
160
+ >
161
+ {{ item[$props.itemTitle!] }}
162
+ </FSSpan>
163
+ </FSRow>
164
+ </template>
165
+ </FSCheckbox>
166
+ <FSRadio
167
+ v-else
168
+ :selected="$props.modelValue === item[$props.itemValue!]"
169
+ :label="item[$props.itemTitle!]"
170
+ :editable="$props.editable"
171
+ :item="item"
172
+ :modelValue="item[$props.itemValue!]"
173
+ @update:modelValue="() => onRadioChange(item[$props.itemValue!])"
174
+ >
175
+ <template
176
+ #label="{ font }"
177
+ >
178
+ <FSRow
179
+ align="center-left"
180
+ :wrap="false"
181
+ >
182
+ <slot
183
+ name="item-prepend"
184
+ v-bind="{ item }"
185
+ />
186
+ <FSSpan
187
+ :font="font"
188
+ >
189
+ {{ item[$props.itemTitle!] }}
190
+ </FSSpan>
191
+ </FSRow>
192
+ </template>
193
+ </FSRadio>
194
+ <FSRow
195
+ align="center-right"
101
196
  >
102
197
  <slot
103
- name="item-label"
104
- v-bind="mobileItemProps(item, font)"
198
+ name="item-append"
199
+ v-bind="{ item }"
105
200
  />
106
- </template>
107
- </FSRadioGroup>
108
- </FSFadeOut>
109
- </template>
110
- </FSDialogMenu>
111
- </template>
112
- <template
201
+ </FSRow>
202
+ </FSRow>
203
+ </FSCol>
204
+ </FSFadeOut>
205
+ <FSRow
206
+ v-if="!$props.items || $props.items.length === 0"
207
+ padding="4px 3px"
208
+ >
209
+ <FSSpan>
210
+ {{ $tr("ui.common.no-data", "No data") }}
211
+ </FSSpan>
212
+ </FSRow>
213
+ </template>
214
+ </FSDialogMenu>
215
+ </FSCol>
216
+ <FSBaseField
217
+ v-else
218
+ :description="$props.description"
219
+ :hideHeader="$props.hideHeader"
220
+ :required="$props.required"
221
+ :editable="$props.editable"
222
+ :label="$props.label"
223
+ :messages="messages"
224
+ >
225
+ <FSToggleSet
226
+ v-if="$props.toggleSet"
227
+ :editable="$props.editable"
228
+ :multiple="$props.multiple"
229
+ :required="$props.required"
230
+ :values="$props.items"
231
+ :rules="$props.rules"
232
+ :modelValue="$props.modelValue"
233
+ @update:modelValue="$emit('update:modelValue', $event)"
234
+ v-bind="$attrs"
235
+ >
236
+ <template
237
+ v-for="(_, name) in toggleSetSlots"
238
+ v-slot:[name]="slotData"
239
+ >
240
+ <slot
241
+ :name="`toggle-set-${name}`"
242
+ v-bind="slotData"
243
+ />
244
+ </template>
245
+ </FSToggleSet>
246
+ <FSCol
113
247
  v-else
114
248
  >
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"
249
+ <v-select
250
+ class="fs-select-field"
251
+ variant="outlined"
252
+ :clearable="$props.clearable && $props.editable && !!$props.modelValue"
253
+ :itemTitle="$props.itemTitle"
254
+ :itemValue="$props.itemValue"
255
+ :readonly="!$props.editable"
256
+ :multiple="$props.multiple"
257
+ :validateOn="validateOn"
258
+ :persistentClear="true"
259
+ :listProps="listStyle"
260
+ :returnObject="false"
261
+ :items="$props.items"
262
+ :rules="$props.rules"
263
+ :hideDetails="true"
264
+ :menuIcon="null"
265
+ :style="style"
266
+ :modelValue="$props.modelValue"
267
+ @update:modelValue="onSingleChange"
268
+ v-bind="$attrs"
122
269
  >
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"
270
+ <template
271
+ v-for="(_, name) in selectSlots"
272
+ v-slot:[name]="slotData"
143
273
  >
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 }"
274
+ <slot
275
+ :name="`select-${name}`"
276
+ v-bind="slotData"
277
+ />
278
+ </template>
279
+ <template
280
+ #item="{ props, item }"
281
+ >
282
+ <v-list-item
283
+ v-bind="{ ...props, title: '' }"
155
284
  >
156
- <v-list-item
157
- v-bind="{ ...props, title: '' }"
285
+ <FSRow
286
+ align="center-left"
287
+ :wrap="false"
158
288
  >
159
- <FSRow
160
- align="center-left"
289
+ <FSCheckbox
290
+ v-if="$props.multiple"
291
+ :modelValue="$props.modelValue?.includes(item.raw[$props.itemValue!])"
292
+ @click="props.onClick"
161
293
  >
162
- <FSCheckbox
163
- v-if="$props.multiple"
164
- :modelValue="$props.modelValue?.includes(item.raw[$props.itemValue])"
165
- @click="props.onClick"
294
+ <template
295
+ #label="{ font }"
166
296
  >
167
- <template
168
- #label="{ font }"
297
+ <slot
298
+ name="item-prepend"
299
+ v-bind="{ item: item.raw }"
300
+ />
301
+ <FSSpan
302
+ :font="font"
169
303
  >
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>
304
+ {{ item.raw[$props.itemTitle!] }}
305
+ </FSSpan>
306
+ </template>
307
+ </FSCheckbox>
308
+ <template
309
+ v-else
310
+ >
311
+ <slot
312
+ name="item-prepend"
313
+ v-bind="{ item: item.raw }"
314
+ />
182
315
  <FSSpan
183
- v-else
316
+ :font="$props.modelValue === item.raw[$props.itemTitle!] ? 'text-button' : 'text-body'"
184
317
  >
185
- <slot
186
- name="item-label"
187
- v-bind="{ item }"
188
- >
189
- <FSSpan>
190
- {{ item.raw[$props.itemTitle] }}
191
- </FSSpan>
192
- </slot>
318
+ {{ item.raw[$props.itemTitle!] }}
193
319
  </FSSpan>
320
+ </template>
321
+ <FSRow
322
+ align="center-right"
323
+ >
324
+ <slot
325
+ name="item-append"
326
+ v-bind="{ item: item.raw }"
327
+ />
194
328
  </FSRow>
195
- </v-list-item>
196
- </template>
197
- <template
198
- #clear
329
+ </FSRow>
330
+ </v-list-item>
331
+ </template>
332
+ <template
333
+ #prepend-inner
334
+ >
335
+ <slot
336
+ v-if="selectedItem"
337
+ name="item-prepend"
338
+ v-bind="{ item: selectedItem }"
339
+ />
340
+ </template>
341
+ <template
342
+ v-if="$props.multiple"
343
+ #selection="{ index }"
344
+ >
345
+ <FSSpan
346
+ v-if="index === $props.modelValue.length - 1"
347
+ >
348
+ {{ $props.placeholder }}
349
+ </FSSpan>
350
+ </template>
351
+ <template
352
+ #clear
353
+ >
354
+ <FSRow
355
+ :wrap="false"
199
356
  >
357
+ <slot
358
+ v-if="selectedItem"
359
+ name="item-append"
360
+ v-bind="{ item: selectedItem }"
361
+ />
200
362
  <slot
201
363
  name="clear"
202
364
  >
@@ -205,54 +367,94 @@
205
367
  icon="mdi-close"
206
368
  variant="icon"
207
369
  :color="ColorEnum.Dark"
208
- @click="$emit('update:modelValue', null)"
370
+ @click="onClear"
209
371
  />
210
372
  </slot>
211
- </template>
212
- <template
213
- #append-inner
373
+ </FSRow>
374
+ </template>
375
+ <template
376
+ #append-inner
377
+ >
378
+ <slot
379
+ name="append-inner"
214
380
  >
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
381
+ <FSButton
382
+ icon="mdi-chevron-down"
383
+ variant="icon"
384
+ :editable="$props.editable"
385
+ :color="ColorEnum.Dark"
386
+ />
387
+ </slot>
388
+ </template>
389
+ <template
390
+ #no-data
391
+ >
392
+ <FSRow
393
+ v-if="!$props.items || $props.items.length === 0"
394
+ padding="15px"
228
395
  >
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>
396
+ <FSSpan>
397
+ {{ $tr("ui.common.no-data", "No data") }}
398
+ </FSSpan>
399
+ </FSRow>
400
+ </template>
401
+ </v-select>
402
+ <FSSlideGroup
403
+ v-if="$props.multiple && Array.isArray($props.modelValue)"
404
+ >
405
+ <FSCard
406
+ v-for="(item, index) in $props.items.filter((item: any) => $props.modelValue.includes(item[$props.itemValue!]))"
407
+ variant="standard"
408
+ :height="['40px', '36px']"
409
+ :color="ColorEnum.Light"
410
+ :border="false"
411
+ :key="index"
412
+ >
413
+ <FSRow
414
+ align="center-left"
415
+ padding="0 8px"
416
+ >
417
+ <slot
418
+ name="item-prepend"
419
+ v-bind="{ item }"
420
+ />
421
+ <FSSpan>
422
+ {{ item[$props.itemTitle!] }}
423
+ </FSSpan>
424
+ <slot
425
+ name="item-append"
426
+ v-bind="{ item }"
427
+ />
428
+ <FSButton
429
+ icon="mdi-close"
430
+ variant="icon"
431
+ :color="ColorEnum.Dark"
432
+ @click="() => onCheckboxChange(item[$props.itemValue!])"
433
+ />
434
+ </FSRow>
435
+ </FSCard>
436
+ </FSSlideGroup>
437
+ </FSCol>
438
+ </FSBaseField>
241
439
  </template>
242
440
 
243
441
  <script lang="ts">
244
- import { computed, defineComponent, type PropType, ref, type StyleValue } from "vue";
442
+ import { computed, defineComponent, type PropType, ref, type Slot, type StyleValue } from "vue";
245
443
 
246
- import { useBreakpoints, useColors, useRules } from "@dative-gpi/foundation-shared-components/composables";
444
+ import { useBreakpoints, useColors, useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
247
445
  import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
248
446
 
249
447
  import FSDialogMenu from "../FSDialogMenu.vue";
250
- import FSRadioGroup from "../FSRadioGroup.vue";
448
+ import FSSlideGroup from "../FSSlideGroup.vue";
449
+ import FSToggleSet from "../FSToggleSet.vue";
251
450
  import FSBaseField from "./FSBaseField.vue";
252
451
  import FSTextField from "./FSTextField.vue";
253
452
  import FSCheckbox from "../FSCheckbox.vue";
254
453
  import FSFadeOut from "../FSFadeOut.vue";
255
454
  import FSButton from "../FSButton.vue";
455
+ import FSLoader from "../FSLoader.vue";
456
+ import FSRadio from "../FSRadio.vue";
457
+ import FSCard from "../FSCard.vue";
256
458
  import FSSpan from "../FSSpan.vue";
257
459
  import FSCol from "../FSCol.vue";
258
460
  import FSRow from "../FSRow.vue";
@@ -261,12 +463,16 @@ export default defineComponent({
261
463
  name: "FSSelectField",
262
464
  components: {
263
465
  FSDialogMenu,
264
- FSRadioGroup,
466
+ FSSlideGroup,
265
467
  FSBaseField,
266
468
  FSTextField,
469
+ FSToggleSet,
267
470
  FSCheckbox,
268
471
  FSFadeOut,
269
472
  FSButton,
473
+ FSLoader,
474
+ FSRadio,
475
+ FSCard,
270
476
  FSSpan,
271
477
  FSCol,
272
478
  FSRow
@@ -277,6 +483,11 @@ export default defineComponent({
277
483
  required: false,
278
484
  default: null
279
485
  },
486
+ placeholder: {
487
+ type: String as PropType<string | null>,
488
+ required: false,
489
+ default: null
490
+ },
280
491
  description: {
281
492
  type: String as PropType<string | null>,
282
493
  required: false,
@@ -297,21 +508,21 @@ export default defineComponent({
297
508
  default: "label"
298
509
  },
299
510
  modelValue: {
300
- type: [Array, String, Number] as PropType<(string | number)[] | string | number | null>,
511
+ type: [Array, String, Number] as PropType<(string | number)[] | string | number | null | any>,
301
512
  required: false,
302
513
  default: null
303
514
  },
304
- hideHeader: {
515
+ multiple: {
305
516
  type: Boolean,
306
517
  required: false,
307
518
  default: false
308
519
  },
309
- required: {
520
+ hideHeader: {
310
521
  type: Boolean,
311
522
  required: false,
312
523
  default: false
313
524
  },
314
- multiple: {
525
+ required: {
315
526
  type: Boolean,
316
527
  required: false,
317
528
  default: false
@@ -335,13 +546,27 @@ export default defineComponent({
335
546
  type: Boolean,
336
547
  required: false,
337
548
  default: true
549
+ },
550
+ loading: {
551
+ type: Boolean,
552
+ required: false,
553
+ default: false
554
+ },
555
+ toggleSet: {
556
+ type: Boolean,
557
+ required: false,
558
+ default: false
338
559
  }
339
560
  },
340
561
  emits: ["update:modelValue"],
341
562
  setup(props, { emit }) {
563
+ const { fontStyles, isExtraSmall, isMobileSized } = useBreakpoints();
342
564
  const { validateOn, getMessages } = useRules();
343
- const { isExtraSmall } = useBreakpoints();
344
565
  const { getColors } = useColors();
566
+ const { slots } = useSlots();
567
+
568
+ delete slots.label;
569
+ delete slots.description;
345
570
 
346
571
  const backgrounds = getColors(ColorEnum.Background);
347
572
  const errors = getColors(ColorEnum.Error);
@@ -356,7 +581,9 @@ export default defineComponent({
356
581
  "--fs-select-field-cursor" : "default",
357
582
  "--fs-select-field-border-color" : lights.base,
358
583
  "--fs-select-field-color" : lights.dark,
359
- "--fs-select-field-active-border-color": lights.base
584
+ "--fs-select-field-active-border-color": lights.base,
585
+ "--fs-base-field-input-height" : isMobileSized.value ? "34px" : "38px",
586
+ ...fontStyles.value
360
587
  };
361
588
  }
362
589
  return {
@@ -365,11 +592,27 @@ export default defineComponent({
365
592
  "--fs-select-field-border-color" : lights.dark,
366
593
  "--fs-select-field-color" : darks.base,
367
594
  "--fs-select-field-active-border-color": darks.dark,
368
- "--fs-select-field-error-border-color" : errors.base
595
+ "--fs-select-field-error-border-color" : errors.base,
596
+ "--fs-base-field-input-height" : isMobileSized.value ? "34px" : "38px",
597
+ ...fontStyles.value
369
598
  };
370
599
  });
371
600
 
372
- const listStyle = computed((): { [key: string] : object } => {
601
+ const selectSlots = computed((): { [key: string]: Slot<any> } => {
602
+ return Object.keys(slots).filter(k => k.startsWith("select-")).reduce((acc: { [key: string]: Slot<any> }, key) => {
603
+ acc[key.substring("select-".length)] = slots[key];
604
+ return acc;
605
+ }, {});
606
+ });
607
+
608
+ const toggleSetSlots = computed((): { [key: string]: Slot<any> } => {
609
+ return Object.keys(slots).filter(k => k.startsWith("toggle-set-")).reduce((acc: { [key: string]: Slot<any> }, key) => {
610
+ acc[key.substring("toggle-set-".length)] = slots[key];
611
+ return acc;
612
+ }, {});
613
+ });
614
+
615
+ const listStyle = computed((): { style: StyleValue } => {
373
616
  return {
374
617
  style: style.value
375
618
  };
@@ -377,64 +620,46 @@ export default defineComponent({
377
620
 
378
621
  const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
379
622
 
380
- const height = computed(() => {
381
- const other = 8 + 8; // Paddings
382
- return `calc(100vh - 40px - ${other}px)`;
623
+ const selectedItem = computed((): any => {
624
+ if (props.multiple) {
625
+ return null;
626
+ }
627
+ if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
628
+ return props.items.find((item: any) => item[props.itemValue] === props.modelValue[0]) ?? null;
629
+ }
630
+ else if (props.modelValue) {
631
+ return props.items.find((item: any) => item[props.itemValue] === props.modelValue) ?? null;
632
+ }
633
+ return null;
383
634
  });
384
635
 
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
- }
636
+ const selectedItems = computed((): any[] => {
637
+ if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
638
+ return props.items.filter((item: any) => props.modelValue.includes(item[props.itemValue]));
395
639
  }
396
- if (props.modelValue) {
397
- const item = props.items.find((item: object) => item[props.itemValue] === props.modelValue);
640
+ else if (props.modelValue) {
641
+ const item = props.items.find((item: any) => item[props.itemValue] === props.modelValue);
398
642
  if (item) {
399
- return item[props.itemTitle];
643
+ return [item];
400
644
  }
401
645
  }
402
- return null;
646
+ return [];
403
647
  });
404
648
 
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;
649
+ const maxHeight = computed(() => {
650
+ const other = 8 + 8; // Paddings
651
+ return `calc(100vh - 40px - ${other}px)`;
422
652
  });
423
653
 
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
654
+ const mobileValue = computed((): string | null => {
655
+ if (props.multiple && Array.isArray(props.modelValue) && props.modelValue.length > 0) {
656
+ return props.placeholder;
436
657
  }
437
- };
658
+ if (selectedItem.value) {
659
+ return selectedItem.value[props.itemTitle];
660
+ }
661
+ return null;
662
+ });
438
663
 
439
664
  const openMobileOverlay = () => {
440
665
  if (!props.editable) {
@@ -470,21 +695,33 @@ export default defineComponent({
470
695
  }
471
696
  };
472
697
 
698
+ const onSingleChange = (value: string) => {
699
+ emit("update:modelValue", value);
700
+ };
701
+
702
+ const onClear = () => {
703
+ emit("update:modelValue", null);
704
+ };
705
+
473
706
  return {
474
- mobileSelectionProps,
707
+ toggleSetSlots,
708
+ selectedItems,
475
709
  isExtraSmall,
710
+ selectedItem,
476
711
  mobileValue,
712
+ selectSlots,
477
713
  validateOn,
478
714
  ColorEnum,
479
715
  listStyle,
716
+ maxHeight,
480
717
  messages,
481
718
  dialog,
482
- height,
483
719
  style,
484
720
  openMobileOverlay,
485
721
  onCheckboxChange,
486
- mobileItemProps,
487
- onRadioChange
722
+ onSingleChange,
723
+ onRadioChange,
724
+ onClear
488
725
  };
489
726
  }
490
727
  });