@dative-gpi/foundation-shared-components 1.0.70 → 1.0.71-groupings-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/assets/images/map/snow.png +0 -0
  2. package/components/FSAccordionPanel.vue +40 -21
  3. package/components/FSBreadcrumbs.vue +21 -12
  4. package/components/FSButton.vue +11 -9
  5. package/components/FSCalendar.vue +50 -12
  6. package/components/FSCalendarTwin.vue +95 -43
  7. package/components/FSCard.vue +61 -9
  8. package/components/FSCardPlaceholder.vue +8 -5
  9. package/components/FSCheckbox.vue +5 -4
  10. package/components/FSChip.vue +73 -45
  11. package/components/FSChipGroup.vue +69 -0
  12. package/components/FSClickable.vue +11 -9
  13. package/components/FSClock.vue +30 -12
  14. package/components/FSCol.vue +11 -5
  15. package/components/FSDialog.vue +2 -1
  16. package/components/FSDialogContent.vue +12 -11
  17. package/components/FSDialogForm.vue +22 -2
  18. package/components/FSDialogFormBody.vue +50 -31
  19. package/components/FSDialogMenu.vue +17 -8
  20. package/components/FSDialogMultiFormBody.vue +23 -13
  21. package/components/FSDialogRemove.vue +7 -8
  22. package/components/FSDialogSubmit.vue +20 -11
  23. package/components/FSEditImageUI.vue +13 -5
  24. package/components/FSFadeOut.vue +53 -21
  25. package/components/FSForm.vue +10 -8
  26. package/components/FSGrid.vue +0 -1
  27. package/components/FSIcon.vue +2 -2
  28. package/components/FSIconCard.vue +68 -12
  29. package/components/FSInformationsMenu.vue +142 -0
  30. package/components/FSInstantPicker.vue +268 -0
  31. package/components/FSLink.vue +25 -9
  32. package/components/FSLoader.vue +28 -10
  33. package/components/FSMenu.vue +47 -0
  34. package/components/FSOptionGroup.vue +8 -8
  35. package/components/FSOptionItem.vue +4 -4
  36. package/components/FSOptionsMenu.vue +165 -0
  37. package/components/FSPagination.vue +1 -1
  38. package/components/FSPlayButtons.vue +72 -0
  39. package/components/FSProgressBar.vue +94 -0
  40. package/components/FSRadio.vue +5 -4
  41. package/components/FSRadioGroup.vue +3 -3
  42. package/components/FSRangePicker.vue +275 -0
  43. package/components/FSRangeSlider.vue +84 -0
  44. package/components/FSRouterLink.vue +42 -0
  45. package/components/FSSlideGroup.vue +9 -7
  46. package/components/FSSlider.vue +44 -79
  47. package/components/FSSpan.vue +22 -8
  48. package/components/FSSwitch.vue +44 -48
  49. package/components/FSTab.vue +15 -13
  50. package/components/FSTabs.vue +5 -2
  51. package/components/FSTag.vue +3 -3
  52. package/components/FSTagGroup.vue +6 -4
  53. package/components/FSText.vue +21 -8
  54. package/components/FSToggleSet.vue +7 -7
  55. package/components/FSTreeView.vue +107 -0
  56. package/components/FSWindow.vue +122 -5
  57. package/components/agenda/FSAgenda.vue +26 -7
  58. package/components/agenda/FSAgendaDialogCalendar.vue +2 -2
  59. package/components/agenda/FSAgendaHeader.vue +35 -10
  60. package/components/agenda/FSAgendaHorizontalEvent.vue +18 -6
  61. package/components/agenda/FSAgendaHoursRow.vue +48 -8
  62. package/components/agenda/FSAgendaVerticalEvent.vue +1 -1
  63. package/components/agenda/FSDayAgenda.vue +0 -1
  64. package/components/agenda/FSMonthAgenda.vue +1 -6
  65. package/components/agenda/FSSelectAgendaMode.vue +2 -2
  66. package/components/agenda/FSWeekAgenda.vue +5 -10
  67. package/components/autocompletes/FSAutoCompleteAddress.vue +25 -20
  68. package/components/autocompletes/FSAutocompleteLanguage.vue +7 -1
  69. package/components/autocompletes/FSAutocompleteTimeZone.vue +7 -1
  70. package/components/buttons/FSButtonAdd.vue +1 -1
  71. package/components/buttons/FSButtonAddLabel.vue +1 -1
  72. package/components/buttons/FSButtonCancel.vue +1 -1
  73. package/components/buttons/FSButtonCancelLabel.vue +1 -1
  74. package/components/buttons/FSButtonCheckbox.vue +4 -4
  75. package/components/buttons/FSButtonCopy.vue +1 -1
  76. package/components/buttons/FSButtonCopyLabel.vue +1 -1
  77. package/components/buttons/FSButtonDuplicate.vue +1 -1
  78. package/components/buttons/FSButtonDuplicateLabel.vue +1 -1
  79. package/components/buttons/FSButtonEdit.vue +1 -1
  80. package/components/buttons/FSButtonEditLabel.vue +1 -1
  81. package/components/buttons/FSButtonFile.vue +1 -1
  82. package/components/buttons/FSButtonFileLabel.vue +1 -1
  83. package/components/buttons/FSButtonNext.vue +1 -1
  84. package/components/buttons/FSButtonNextLabel.vue +1 -1
  85. package/components/buttons/FSButtonPrevious.vue +1 -1
  86. package/components/buttons/FSButtonPreviousLabel.vue +1 -1
  87. package/components/buttons/FSButtonRedo.vue +1 -1
  88. package/components/buttons/FSButtonRedoLabel.vue +1 -1
  89. package/components/buttons/FSButtonRemove.vue +1 -1
  90. package/components/buttons/FSButtonRemoveLabel.vue +1 -1
  91. package/components/buttons/FSButtonSave.vue +1 -1
  92. package/components/buttons/FSButtonSaveLabel.vue +1 -1
  93. package/components/buttons/FSButtonSearch.vue +1 -1
  94. package/components/buttons/FSButtonSearchLabel.vue +1 -1
  95. package/components/buttons/FSButtonUndo.vue +1 -1
  96. package/components/buttons/FSButtonUndoLabel.vue +1 -1
  97. package/components/buttons/FSButtonUpdate.vue +1 -1
  98. package/components/buttons/FSButtonUpdateLabel.vue +1 -1
  99. package/components/buttons/FSButtonValidate.vue +1 -1
  100. package/components/buttons/FSButtonValidateLabel.vue +1 -1
  101. package/components/calendar/FSSimpleCalendar.vue +145 -0
  102. package/components/calendar/FSSimpleCalendarHeader.vue +60 -0
  103. package/components/calendar/FSSimpleMonthSelector.vue +138 -0
  104. package/components/carousels/FSCarousel.vue +23 -0
  105. package/components/carousels/FSCarouselItem.vue +14 -0
  106. package/components/deviceOrganisations/FSConnectivity.vue +5 -3
  107. package/components/deviceOrganisations/FSStatus.vue +5 -3
  108. package/components/deviceOrganisations/FSStatusCard.vue +7 -9
  109. package/components/deviceOrganisations/FSStatusRichCard.vue +171 -0
  110. package/components/deviceOrganisations/FSWorstAlert.vue +24 -36
  111. package/components/deviceOrganisations/FSWorstAlertCard.vue +8 -47
  112. package/components/fields/FSAutocompleteField.vue +85 -82
  113. package/components/fields/FSAutocompleteTag.vue +1 -1
  114. package/components/fields/FSBaseField.vue +42 -25
  115. package/components/fields/FSClosableSearchField.vue +83 -0
  116. package/components/fields/FSColorField.vue +12 -10
  117. package/components/fields/FSCommentField.vue +28 -16
  118. package/components/fields/FSDateField.vue +13 -10
  119. package/components/fields/FSDateRangeField.vue +6 -5
  120. package/components/fields/FSDateTimeField.vue +14 -11
  121. package/components/fields/FSDateTimeRangeDialog.vue +160 -0
  122. package/components/fields/FSDateTimeRangeField.vue +23 -115
  123. package/components/fields/FSEntityFieldUI.vue +19 -16
  124. package/components/fields/FSGradientField.vue +5 -5
  125. package/components/fields/FSIconField.vue +16 -9
  126. package/components/fields/FSMapAddressField.vue +187 -0
  127. package/components/fields/FSNumberField.vue +8 -4
  128. package/components/fields/FSPasswordField.vue +7 -7
  129. package/components/fields/FSPoliciesValidationField.vue +101 -0
  130. package/components/fields/FSRichTextField.vue +78 -58
  131. package/components/fields/FSSearchField.vue +9 -115
  132. package/components/fields/FSSelectField.vue +69 -71
  133. package/components/fields/FSTagField.vue +9 -9
  134. package/components/fields/FSTermField.vue +69 -46
  135. package/components/fields/FSTextArea.vue +17 -11
  136. package/components/fields/FSTextField.vue +15 -10
  137. package/components/fields/FSTimeField.vue +14 -10
  138. package/components/fields/FSTimeRangeField.vue +117 -187
  139. package/components/fields/FSTimeStepField.vue +5 -5
  140. package/components/fields/FSTranslateField.vue +10 -10
  141. package/components/fields/FSTranslateRichTextField.vue +41 -20
  142. package/components/fields/FSTranslateTextArea.vue +10 -10
  143. package/components/fields/FSTreeViewField.vue +21 -19
  144. package/components/fields/periodicField/FSPeriodicDailyField.vue +7 -7
  145. package/components/fields/periodicField/FSPeriodicField.vue +15 -15
  146. package/components/fields/periodicField/FSPeriodicMonthlyField.vue +16 -16
  147. package/components/fields/periodicField/FSPeriodicWeeklyField.vue +28 -18
  148. package/components/fields/periodicField/FSPeriodicYearlyField.vue +12 -12
  149. package/components/lists/FSDataIteratorItem.vue +23 -67
  150. package/components/lists/FSDataTableUI.vue +194 -119
  151. package/components/lists/FSFilterButton.vue +14 -16
  152. package/components/lists/FSHeaderButton.vue +11 -9
  153. package/components/lists/FSHiddenButton.vue +9 -9
  154. package/components/lists/FSLoadDataTable.vue +10 -7
  155. package/components/lists/FSSimpleList.vue +95 -88
  156. package/components/lists/FSSimpleListItem.vue +131 -0
  157. package/components/map/FSMap.vue +144 -158
  158. package/components/map/FSMapFeatureGroup.vue +7 -1
  159. package/components/map/FSMapLayerButton.vue +3 -3
  160. package/components/map/FSMapMarker.vue +103 -42
  161. package/components/map/FSMapMarkerClusterGroup.vue +32 -7
  162. package/components/map/FSMapOverlay.vue +44 -24
  163. package/components/map/FSMapPolygon.vue +16 -4
  164. package/components/map/FSMapTileLayer.vue +26 -9
  165. package/components/map/layers.ts +0 -0
  166. package/components/selects/FSSelectAutoRefresh.vue +8 -8
  167. package/components/selects/FSSelectDashboardVariableType.vue +4 -3
  168. package/components/selects/FSSelectDateSetting.vue +2 -2
  169. package/components/selects/FSSelectDays.vue +8 -8
  170. package/components/selects/FSSelectListMode.vue +2 -2
  171. package/components/selects/FSSelectMapLayer.vue +68 -0
  172. package/components/selects/FSSelectMonths.vue +13 -13
  173. package/components/selects/chartSelectors/FSAggregationSelector.vue +52 -0
  174. package/components/selects/chartSelectors/FSAxisTypeSelector.vue +49 -0
  175. package/components/selects/chartSelectors/FSDisplayAsSelector.vue +53 -0
  176. package/components/selects/chartSelectors/FSFilterTypeSelector.vue +54 -0
  177. package/components/selects/chartSelectors/FSHeatmapRuleSelector.vue +54 -0
  178. package/components/selects/chartSelectors/FSOperationOnSelector.vue +53 -0
  179. package/components/selects/chartSelectors/FSPlanningTypeSelector.vue +53 -0
  180. package/components/selects/chartSelectors/FSSelectEntityType.vue +59 -0
  181. package/components/selects/chartSelectors/FSSerieTypeSelector.vue +53 -0
  182. package/components/tiles/FSAlertTileUI.vue +90 -0
  183. package/components/tiles/FSChartTileUI.vue +61 -52
  184. package/components/tiles/FSCommentTileUI.vue +38 -13
  185. package/components/tiles/FSDashboardOrganisationTypeTileUI.vue +14 -2
  186. package/components/tiles/FSDashboardShallowTileUI.vue +14 -2
  187. package/components/tiles/FSDeviceOrganisationTileUI.vue +0 -6
  188. package/components/tiles/FSEntityCountBadge.vue +83 -0
  189. package/components/tiles/FSFolderTileUI.vue +38 -4
  190. package/components/tiles/FSGroupTileUI.vue +32 -136
  191. package/components/tiles/FSGroupingTileUI.vue +52 -0
  192. package/components/tiles/FSLoadTile.vue +16 -10
  193. package/components/tiles/FSLocationTileUI.vue +50 -80
  194. package/components/tiles/FSServiceAccountOrganisationTileUI.vue +0 -6
  195. package/components/tiles/FSSimpleTileUI.vue +32 -27
  196. package/components/tiles/FSTile.vue +46 -39
  197. package/components/tiles/FSUserOrganisationTileUI.vue +1 -7
  198. package/components/tiles/FSUserTileUI.vue +119 -0
  199. package/components/toggleSets/FSToggleSetPosition.vue +1 -1
  200. package/components/views/FSBaseView.vue +64 -0
  201. package/components/views/FSEntityView.vue +12 -146
  202. package/components/views/FSSimpleView.vue +29 -0
  203. package/components/views/desktop/FSBaseDefaultDesktopView.vue +135 -0
  204. package/components/views/desktop/FSBaseDesktopView.vue +53 -0
  205. package/components/views/desktop/FSBaseEntityDesktopView.vue +211 -0
  206. package/components/views/mobile/FSBaseDefaultMobileView.vue +133 -0
  207. package/components/views/mobile/FSBaseEntityMobileView.vue +206 -0
  208. package/components/views/mobile/FSBaseMobileView.vue +53 -0
  209. package/composables/index.ts +1 -1
  210. package/composables/useAddress.ts +40 -8
  211. package/composables/useBreakpoints.ts +40 -4
  212. package/composables/useColors.ts +16 -7
  213. package/composables/useMapLayers.ts +69 -0
  214. package/composables/useSlots.ts +2 -1
  215. package/models/colors.ts +2 -1
  216. package/models/deviceAlerts.ts +1 -0
  217. package/models/index.ts +0 -1
  218. package/models/map.ts +12 -10
  219. package/models/rules.ts +5 -2
  220. package/models/tables.ts +2 -1
  221. package/models/variableNode.ts +8 -5
  222. package/package.json +5 -5
  223. package/styles/components/fs_agenda.scss +4 -0
  224. package/styles/components/fs_agenda_event.scss +1 -1
  225. package/styles/components/fs_agenda_hours_row.scss +0 -8
  226. package/styles/components/fs_autocomplete_field.scss +0 -13
  227. package/styles/components/fs_breadcrumbs.scss +18 -36
  228. package/styles/components/fs_button.scss +7 -5
  229. package/styles/components/fs_calendar.scss +1 -0
  230. package/styles/components/fs_card.scss +9 -0
  231. package/styles/components/fs_chip.scss +13 -7
  232. package/styles/components/fs_clickable.scss +16 -23
  233. package/styles/components/fs_clock.scss +0 -10
  234. package/styles/components/fs_col.scss +1 -1
  235. package/styles/components/fs_color_field.scss +0 -4
  236. package/styles/components/fs_data_table.scss +6 -9
  237. package/styles/components/fs_dialog.scss +4 -10
  238. package/styles/components/fs_dialog_menu.scss +4 -2
  239. package/styles/components/fs_draggable.scss +0 -5
  240. package/styles/components/fs_fade_out.scss +10 -2
  241. package/styles/components/fs_filter_button.scss +1 -1
  242. package/styles/components/fs_hidden_button.scss +2 -7
  243. package/styles/components/fs_image_card.scss +6 -4
  244. package/styles/components/fs_magic_config_field.scss +1 -2
  245. package/styles/components/fs_map.scss +57 -17
  246. package/styles/components/fs_meta_field.scss +3 -5
  247. package/styles/components/fs_password_field.scss +4 -2
  248. package/styles/components/fs_progress_bar.scss +14 -0
  249. package/styles/components/fs_radio.scss +0 -11
  250. package/styles/components/fs_rich_text_field.scss +1 -10
  251. package/styles/components/fs_select_field.scss +4 -13
  252. package/styles/components/fs_slide_group.scss +3 -1
  253. package/styles/components/fs_slider.scss +0 -40
  254. package/styles/components/fs_span.scss +17 -5
  255. package/styles/components/fs_status_rich_card.scss +6 -0
  256. package/styles/components/fs_tabs.scss +18 -37
  257. package/styles/components/fs_tag.scss +8 -22
  258. package/styles/components/fs_text_area.scss +2 -21
  259. package/styles/components/fs_tile.scss +0 -19
  260. package/styles/components/fs_window.scss +3 -1
  261. package/styles/components/fs_wrap_group.scss +3 -0
  262. package/styles/components/index.scss +2 -6
  263. package/styles/globals/index.scss +1 -5
  264. package/styles/globals/overrides.scss +26 -44
  265. package/styles/globals/scrollbars.scss +8 -0
  266. package/styles/globals/text_fonts.scss +18 -66
  267. package/styles/globals/touchscreen.scss +2 -2
  268. package/tools/alertsTools.ts +94 -18
  269. package/tools/chartsTools.ts +156 -16
  270. package/tools/index.ts +1 -0
  271. package/tools/reportsTools.ts +38 -0
  272. package/tools/timeRangeTools.ts +99 -40
  273. package/utils/badge.ts +9 -5
  274. package/utils/index.ts +2 -0
  275. package/utils/leafletMarkers.ts +4 -4
  276. package/utils/operations.ts +108 -0
  277. package/utils/picker.ts +40 -0
  278. package/utils/sort.ts +2 -2
  279. package/utils/time.ts +13 -13
  280. package/components/fields/FSMagicConfigField.vue +0 -163
  281. package/components/fields/FSMagicField.vue +0 -193
  282. package/components/fields/FSTimeSlotField.vue +0 -250
  283. package/components/views/FSEntityHeader.vue +0 -343
  284. package/components/views/FSListHeader.vue +0 -83
  285. package/components/views/FSListView.vue +0 -83
  286. package/components/views/FSSkeletonView.vue +0 -100
  287. package/composables/useMagicFieldProvider.ts +0 -23
  288. package/models/magicFields.ts +0 -10
  289. package/styles/components/fs_data_iterator_item.scss +0 -33
  290. package/styles/components/fs_icon_field.scss +0 -12
  291. package/styles/components/fs_search_field.scss +0 -3
  292. package/styles/components/fs_tag_field.scss +0 -8
  293. package/styles/components/fs_time_field.scss +0 -12
  294. package/styles/components/fs_timeslot_field.scss +0 -12
  295. package/styles/globals/breakpoints.scss +0 -20
  296. package/styles/globals/fixes.scss +0 -5
@@ -1,20 +1,22 @@
1
1
  <template>
2
- <span
2
+ <div
3
3
  :class="classes"
4
4
  :style="style"
5
5
  v-bind="$attrs"
6
6
  >
7
- <slot>
8
- {{ $props.label }}
9
- </slot>
10
- </span>
7
+ <span>
8
+ <slot>
9
+ {{ $props.label }}
10
+ </slot>
11
+ </span>
12
+ </div>
11
13
  </template>
12
14
 
13
15
  <script lang="ts">
14
16
  import { computed, defineComponent, type PropType, type StyleValue } from "vue";
15
17
 
18
+ import { useBreakpoints, useColors, useSlots } from "@dative-gpi/foundation-shared-components/composables";
16
19
  import { type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
17
- import { useColors, useSlots } from "@dative-gpi/foundation-shared-components/composables";
18
20
 
19
21
  export default defineComponent({
20
22
  name: "FSText",
@@ -48,9 +50,15 @@ export default defineComponent({
48
50
  type: String as PropType<"base" | "baseContrast" | "light" | "lightContrast" | "dark" | "darkContrast" | "soft" | "softContrast">,
49
51
  required: false,
50
52
  default: "base"
51
- }
53
+ },
54
+ wordBreak: {
55
+ type: String as PropType<"normal" | "break-all" | "keep-all" | "break-word">,
56
+ required: false,
57
+ default: "normal"
58
+ },
52
59
  },
53
60
  setup(props) {
61
+ const { fontStyles } = useBreakpoints();
54
62
  const { getColors } = useColors();
55
63
  const { slots } = useSlots();
56
64
 
@@ -58,7 +66,9 @@ export default defineComponent({
58
66
 
59
67
  const style = computed((): StyleValue => ({
60
68
  "--fs-span-line-clamp": props.lineClamp.toString(),
61
- "--fs-text-color" : colors.value[props.variant]!
69
+ "--fs-text-color" : colors.value[props.variant]!,
70
+ "--fs-span-word-break": props.wordBreak,
71
+ ...fontStyles.value
62
72
  }));
63
73
 
64
74
  const classes = computed((): string[] => {
@@ -72,6 +82,9 @@ export default defineComponent({
72
82
  else if (props.ellipsis) {
73
83
  classNames.push("fs-span-ellipsis");
74
84
  }
85
+ if (props.wordBreak !== "normal") {
86
+ classNames.push("fs-span-word-break");
87
+ }
75
88
  return classNames;
76
89
  });
77
90
 
@@ -5,13 +5,13 @@
5
5
  :modelValue="$props.modelValue"
6
6
  >
7
7
  <FSWrapGroup
8
- v-if="['wrap'].includes($props.variant)"
8
+ v-if="$props.variant && ['wrap'].includes($props.variant)"
9
9
  ref="toggleSetRef"
10
10
  :padding="$props.padding"
11
11
  :gap="$props.gap"
12
12
  >
13
13
  <template
14
- v-if="$props.values.length"
14
+ v-if="$props.values && $props.values.length"
15
15
  >
16
16
  <template
17
17
  v-if="!$slots.item"
@@ -20,7 +20,7 @@
20
20
  v-for="(item, index) in $props.values"
21
21
  :prependIcon="item.prependIcon"
22
22
  :appendIcon="item.appendIcon"
23
- :editable="$props.editable"
23
+ :disabled="$props.disabled"
24
24
  :variant="getVariant(item)"
25
25
  :color="getColor(item)"
26
26
  :class="getClass(item)"
@@ -54,7 +54,7 @@
54
54
  :gap="$props.gap"
55
55
  >
56
56
  <template
57
- v-if="$props.values.length"
57
+ v-if="$props.values && $props.values.length"
58
58
  >
59
59
  <template
60
60
  v-if="!$slots.item"
@@ -63,7 +63,7 @@
63
63
  v-for="(item, index) in $props.values"
64
64
  :prependIcon="item.prependIcon"
65
65
  :appendIcon="item.appendIcon"
66
- :editable="$props.editable"
66
+ :disabled="$props.disabled"
67
67
  :variant="getVariant(item)"
68
68
  :color="getColor(item)"
69
69
  :class="getClass(item)"
@@ -197,10 +197,10 @@ export default defineComponent({
197
197
  required: false,
198
198
  default: false
199
199
  },
200
- editable: {
200
+ disabled: {
201
201
  type: Boolean,
202
202
  required: false,
203
- default: true
203
+ default: false
204
204
  }
205
205
  },
206
206
  emits: ["update:modelValue"],
@@ -0,0 +1,107 @@
1
+ <template>
2
+ <template
3
+ v-if="$props.loading"
4
+ >
5
+ <FSCol>
6
+ <FSLoader
7
+ v-if="$props.loading"
8
+ width="100%"
9
+ :height="['40px', '36px']"
10
+ />
11
+ </FSCol>
12
+ </template>
13
+ <template
14
+ v-else
15
+ >
16
+ <v-treeview
17
+ :itemTitle="$props.itemTitle"
18
+ :itemValue="$props.itemValue"
19
+ :items="treeItems"
20
+ >
21
+ <template
22
+ v-for="(_, name) in $slots"
23
+ v-slot:[name]="slotData"
24
+ >
25
+ <slot
26
+ :name="name"
27
+ v-bind="slotData"
28
+ />
29
+ </template>
30
+ </v-treeview>
31
+ </template>
32
+ </template>
33
+
34
+ <script lang="ts">
35
+ import { computed, defineComponent, type PropType } from "vue";
36
+ import { VTreeview } from "vuetify/labs/VTreeview";
37
+
38
+
39
+ import FSLoader from "./FSLoader.vue";
40
+ import FSCol from "./FSCol.vue";
41
+
42
+ export default defineComponent({
43
+ name: "FSTreeView",
44
+ components: {
45
+ VTreeview,
46
+ FSLoader,
47
+ FSCol,
48
+ },
49
+ props: {
50
+ items: {
51
+ type: Array as PropType<any[]>,
52
+ required: true
53
+ },
54
+ itemValue: {
55
+ type: String,
56
+ required: false,
57
+ default: "id"
58
+ },
59
+ itemTitle: {
60
+ type: String,
61
+ required: false,
62
+ default: "label"
63
+ },
64
+ itemParent: {
65
+ type: String,
66
+ required: false,
67
+ default: "parentId"
68
+ },
69
+ exclude: {
70
+ type: Array as PropType<string[]>,
71
+ required: false,
72
+ default: () => []
73
+ },
74
+ loading: {
75
+ type: Boolean,
76
+ required: false,
77
+ default: false
78
+ }
79
+ },
80
+ setup(props) {
81
+ const treeItems = computed((): any[] => {
82
+ const filter = ((parentId: string | null) => {
83
+ return props.items.filter((item: any) => {
84
+ if (props.exclude.includes(item[props.itemValue])) {
85
+ return false;
86
+ }
87
+ return item[props.itemParent] == parentId;
88
+ });
89
+ });
90
+ const process = ((item: any): any => {
91
+ if (props.items.some((child: any) => child[props.itemParent] === item[props.itemValue])) {
92
+ return {
93
+ ...item,
94
+ children: filter(item[props.itemValue]).map(process)
95
+ };
96
+ }
97
+ return item;
98
+ });
99
+ return filter(null).map(process);
100
+ });
101
+
102
+ return {
103
+ treeItems
104
+ };
105
+ }
106
+ });
107
+ </script>
@@ -1,8 +1,54 @@
1
1
  <template>
2
+ <template
3
+ v-if="showError"
4
+ >
5
+ <slot
6
+ name="error"
7
+ v-bind="{ goBack, width: $props.width, height: $props.height }"
8
+ >
9
+ <FSRow
10
+ padding="16px"
11
+ :width="$props.width"
12
+ >
13
+ <FSCol
14
+ align="center-center"
15
+ gap="16px"
16
+ >
17
+ <FSCol
18
+ align="center-center"
19
+ >
20
+ <FSIcon
21
+ size="42px"
22
+ :color="ColorEnum.Error"
23
+ >
24
+ mdi-alert-outline
25
+ </FSIcon>
26
+ <FSText
27
+ font="text-h3"
28
+ >
29
+ {{ $tr("window.no-access-title", "Nothing to see here") }}
30
+ </FSText>
31
+ </FSCol>
32
+ <FSText
33
+ :lineClamp="2"
34
+ >
35
+ {{ $tr("window.no-access-body", "It seems you either do not have access to this content, or there is nothing to display here") }}
36
+ </FSText>
37
+ <FSButton
38
+ :label="$tr('window.no-access-button', 'Go back')"
39
+ :color="ColorEnum.Primary"
40
+ @click="goBack"
41
+ />
42
+ </FSCol>
43
+ </FSRow>
44
+ </slot>
45
+ </template>
2
46
  <v-window
3
47
  class="fs-window"
4
- :style="style"
48
+ ref="windowRef"
5
49
  :touch="false"
50
+ :style="style"
51
+ :modelValue="$props.modelValue"
6
52
  v-bind="$attrs"
7
53
  >
8
54
  <template
@@ -28,13 +74,28 @@
28
74
  </template>
29
75
 
30
76
  <script lang="ts">
31
- import { computed, defineComponent, type PropType, type StyleValue, type VNode } from "vue";
77
+ import { computed, defineComponent, type PropType, ref, type StyleValue, type VNode, watch } from "vue";
32
78
 
33
79
  import { useSlots } from "@dative-gpi/foundation-shared-components/composables";
34
80
  import { sizeToVar } from "@dative-gpi/foundation-shared-components/utils";
35
81
 
82
+ import { ColorEnum } from "../models";
83
+
84
+ import FSButton from "./FSButton.vue";
85
+ import FSCard from "./FSCard.vue";
86
+ import FSIcon from "./FSIcon.vue";
87
+ import FSText from "./FSText.vue";
88
+ import FSRow from "./FSRow.vue";
89
+
36
90
  export default defineComponent({
37
91
  name: "FSWindow",
92
+ components: {
93
+ FSButton,
94
+ FSCard,
95
+ FSIcon,
96
+ FSText,
97
+ FSRow
98
+ },
38
99
  props: {
39
100
  width: {
40
101
  type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
@@ -45,26 +106,82 @@ export default defineComponent({
45
106
  type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
46
107
  required: false,
47
108
  default: null
109
+ },
110
+ modelValue: {
111
+ type: [String, Number, Object] as PropType<any>,
112
+ required: false,
113
+ default: 0
48
114
  }
49
115
  },
50
- setup(props) {
116
+ emits: ["update:modelValue", "error"],
117
+ setup(props, { emit }) {
51
118
  const { slots, getChildren } = useSlots();
52
119
 
53
120
  delete slots.default;
54
121
 
122
+ const windowRef = ref<any | null>(null);
123
+
124
+ const showOverflow = ref(true);
125
+ const overflowTimeout = ref<NodeJS.Timeout | null>(null);
126
+
55
127
  const style = computed((): StyleValue => ({
56
- "--fs-window-width": sizeToVar(props.width),
57
- "--fs-window-height": sizeToVar(props.height)
128
+ "--fs-window-overflow": showOverflow.value ? "visible" : "hidden",
129
+ "--fs-window-height" : sizeToVar(props.height),
130
+ "--fs-window-width" : sizeToVar(props.width)
58
131
  }));
59
132
 
60
133
  const value = (component: VNode, index: number): any => {
61
134
  return component?.props?.value ?? index;
62
135
  };
63
136
 
137
+ // Hide horizontal overflow when switching windows, otherwise let it visible for the FSFadeOut scrollbar
138
+ watch(() => props.modelValue, (): void => {
139
+ showOverflow.value = false;
140
+ if (overflowTimeout.value) {
141
+ clearTimeout(overflowTimeout.value);
142
+ }
143
+ overflowTimeout.value = setTimeout(() => {
144
+ showOverflow.value = true;
145
+ }, 560);
146
+ });
147
+
148
+ const showError = computed((): boolean => {
149
+ if (!windowRef.value) {
150
+ return false;
151
+ }
152
+
153
+ // https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/components/VWindow/VWindow.tsx
154
+ // https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/composables/group.ts#L161
155
+ const group = windowRef.value.group;
156
+
157
+ if (!group.items.value.length) {
158
+ return false;
159
+ }
160
+ return !group.items.value.find((item: any) => item.value === props.modelValue);
161
+ });
162
+
163
+ const goBack = (): void => {
164
+ if (!windowRef.value) {
165
+ emit("error");
166
+ return;
167
+ }
168
+
169
+ const group = windowRef.value.group;
170
+ if (!group.items.value.length) {
171
+ emit("error");
172
+ return;
173
+ }
174
+ emit("update:modelValue", group.items.value[0].value);
175
+ };
176
+
64
177
  return {
178
+ ColorEnum,
179
+ windowRef,
180
+ showError,
65
181
  slots,
66
182
  style,
67
183
  getChildren,
184
+ goBack,
68
185
  value
69
186
  };
70
187
  }
@@ -141,7 +141,7 @@ export default defineComponent({
141
141
  required: false
142
142
  }
143
143
  },
144
- emits: ['update:mode', 'click:eventId', 'update:start', 'update:end'],
144
+ emits: ['update', 'update:mode', 'click:eventId', 'update:start', 'update:end'],
145
145
  setup(props, { emit }) {
146
146
  const { todayToEpoch, epochToLocalDayStart, epochToLocalDayEnd } = useDateFormat();
147
147
  const { isExtraSmall } = useBreakpoints();
@@ -167,18 +167,27 @@ export default defineComponent({
167
167
  return;
168
168
  }
169
169
  if (props.mode === AgendaMode.Week) {
170
- emit("update:start", epochToLocalDayStart(now.value - (new Date(now.value).getDay() - 1) * 24 * 60 * 60 * 1000));
171
- emit("update:end", epochToLocalDayEnd(now.value + (7 - new Date(now.value).getDay()) * 24 * 60 * 60 * 1000));
170
+ const newStart = epochToLocalDayStart(now.value - (new Date(now.value).getDay() - 1) * 24 * 60 * 60 * 1000);
171
+ const newEnd = epochToLocalDayEnd(now.value + (7 - new Date(now.value).getDay()) * 24 * 60 * 60 * 1000);
172
+ emit("update:start", newStart);
173
+ emit("update:end", newEnd);
174
+ emit("update", { start: newStart, end: newEnd, mode: props.mode });
172
175
  return;
173
176
  }
174
177
  if (props.mode === AgendaMode.Month) {
175
178
  const lastDayOfMonth = new Date(new Date(now.value).getFullYear(), new Date(now.value).getMonth() + 1, 0);
176
- emit("update:start", epochToLocalDayStart(new Date(now.value).setDate(1)));
177
- emit("update:end", lastDayOfMonth.getTime());
179
+ const newStart = epochToLocalDayStart(new Date(now.value).setDate(1));
180
+ const newEnd = lastDayOfMonth.getTime()
181
+ emit("update:start", newStart);
182
+ emit("update:end", newEnd );
183
+ emit("update", { start: newStart, end: newEnd, mode: props.mode });
178
184
  return;
179
185
  }
180
- emit("update:start", epochToLocalDayStart(now.value));
181
- emit("update:end", epochToLocalDayEnd(now.value));
186
+ const newStart = epochToLocalDayStart(now.value);
187
+ const newEnd = epochToLocalDayEnd(now.value);
188
+ emit("update:start", newStart);
189
+ emit("update:end", newEnd);
190
+ emit("update", { start: newStart, end: newEnd, mode: props.mode });
182
191
  });
183
192
 
184
193
  onUnmounted(() => {
@@ -188,8 +197,18 @@ export default defineComponent({
188
197
  watch(isExtraSmall, (value) => {
189
198
  if (value && props.mode !== AgendaMode.Day) {
190
199
  emit('update:mode', AgendaMode.Day);
200
+ emit("update", {
201
+ start: props.start,
202
+ end: props.end,
203
+ mode: AgendaMode.Day
204
+ });
191
205
  } else if (!value && defaultMode.value !== AgendaMode.Day) {
192
206
  emit('update:mode', defaultMode.value);
207
+ emit("update", {
208
+ start: props.start,
209
+ end: props.end,
210
+ mode: defaultMode.value
211
+ });
193
212
  }
194
213
  });
195
214
 
@@ -7,8 +7,8 @@
7
7
  :elevation="true"
8
8
  >
9
9
  <FSCol
10
- gap="12px"
11
10
  padding="16px"
11
+ gap="12px"
12
12
  >
13
13
  <FSCalendar
14
14
  v-model="calendarValue"
@@ -16,7 +16,7 @@
16
16
  <FSButton
17
17
  color="primary"
18
18
  width="100%"
19
- :label="$tr('ui.agenda.calendar.dialog.submit', 'Validate')"
19
+ :label="$tr('ui.common.submit', 'Validate')"
20
20
  @click="onSubmit"
21
21
  />
22
22
  </FSCol>
@@ -16,12 +16,18 @@
16
16
  @click="onPrevious"
17
17
  />
18
18
  <FSButton
19
- width="180px"
19
+ width="220px"
20
20
  color="primary"
21
21
  :border="false"
22
- :label="epochToMonthYearOnlyFormat($props.start)"
23
22
  @click="showCalendarDialog = true"
24
- />
23
+ >
24
+ <FSSpan
25
+ class="fs-agenda-header-text"
26
+ font="text-button"
27
+ >
28
+ {{ epochToMonthYearOnlyFormat($props.start) }}
29
+ </FSSpan>
30
+ </FSButton>
25
31
  <FSButton
26
32
  variant="icon"
27
33
  icon="mdi-chevron-right"
@@ -41,7 +47,7 @@
41
47
  />
42
48
  <FSButton
43
49
  prependIcon="mdi-calendar-today-outline"
44
- :label="$tr('ui.agenda.today', 'Today')"
50
+ :label="$tr('ui.common.today', 'Today')"
45
51
  @click="onToday"
46
52
  />
47
53
  </FSRow>
@@ -52,7 +58,7 @@
52
58
  >
53
59
  <FSButton
54
60
  prependIcon="mdi-calendar-today-outline"
55
- :label="$tr('ui.agenda.today', 'Today')"
61
+ :label="$tr('ui.common.today', 'Today')"
56
62
  width="100%"
57
63
  @click="onToday"
58
64
  />
@@ -89,7 +95,7 @@
89
95
  </template>
90
96
 
91
97
  <script lang="ts">
92
- import { defineComponent, type PropType, ref } from 'vue';
98
+ import { defineComponent, type PropType, ref, watch } from 'vue';
93
99
 
94
100
  import { useDateFormat } from '@dative-gpi/foundation-shared-services/composables';
95
101
 
@@ -100,6 +106,7 @@ import FSRow from '../FSRow.vue';
100
106
  import FSButton from '../FSButton.vue';
101
107
  import FSSelectAgendaMode from './FSSelectAgendaMode.vue';
102
108
  import FSAgendaDialogCalendar from './FSAgendaDialogCalendar.vue';
109
+ import FSSpan from '../FSSpan.vue';
103
110
 
104
111
  export default defineComponent({
105
112
  name: 'FSAgendaHeader',
@@ -108,6 +115,7 @@ export default defineComponent({
108
115
  FSSelectAgendaMode,
109
116
  FSCol,
110
117
  FSButton,
118
+ FSSpan,
111
119
  FSRow
112
120
  },
113
121
  props: {
@@ -128,7 +136,7 @@ export default defineComponent({
128
136
  required: true
129
137
  }
130
138
  },
131
- emits: ['update:start', 'update:end', 'update:mode'],
139
+ emits: ['update', 'update:start', 'update:end', 'update:mode'],
132
140
  setup(props, { emit }) {
133
141
  const { epochToMonthYearOnlyFormat, epochToDayMonthLongOnly, epochToLocalDayStart, epochToLocalDayEnd } = useDateFormat();
134
142
 
@@ -137,18 +145,24 @@ export default defineComponent({
137
145
  const updateDateRange = (dayStart: number) => {
138
146
  const newStart = epochToLocalDayStart(dayStart);
139
147
  if (props.mode === AgendaMode.Week) {
148
+ const newEnd = epochToLocalDayEnd(newStart + (7 - new Date(newStart).getDay()) * 24 * 60 * 60 * 1000)
140
149
  emit('update:start', newStart);
141
- emit('update:end', epochToLocalDayEnd(newStart + (7 - new Date(newStart).getDay()) * 24 * 60 * 60 * 1000));
150
+ emit('update:end', newEnd);
151
+ emit('update', { start: newStart, end: newEnd, mode: props.mode })
142
152
  return;
143
153
  }
144
154
  if (props.mode === AgendaMode.Month) {
145
155
  emit('update:start', newStart);
146
156
  const lastDayOfMonth = new Date(new Date(newStart).getFullYear(), new Date(newStart).getMonth() + 1, 0);
147
- emit('update:end', epochToLocalDayEnd(lastDayOfMonth.getTime()));
157
+ const newEnd = epochToLocalDayEnd(lastDayOfMonth.getTime());
158
+ emit('update:end', newEnd);
159
+ emit('update', { start: newStart, end: newEnd, mode: props.mode })
148
160
  return;
149
161
  }
162
+ const newEnd = epochToLocalDayEnd(newStart);
150
163
  emit('update:start', newStart);
151
- emit('update:end', epochToLocalDayEnd(newStart));
164
+ emit('update:end', newEnd);
165
+ emit('update', { start: newStart, end: newEnd, mode: props.mode })
152
166
  }
153
167
 
154
168
  const onNext = () => {
@@ -175,6 +189,17 @@ export default defineComponent({
175
189
  }
176
190
  }
177
191
 
192
+ watch(() => props.mode, (newMode) => {
193
+ const dayBtwStartAndEnd = props.start + (props.end - props.start) / 2;
194
+ if (newMode === AgendaMode.Week) {
195
+ updateDateRange(dayBtwStartAndEnd - (new Date(dayBtwStartAndEnd).getDay() - 1) * 24 * 60 * 60 * 1000);
196
+ } else if (newMode === AgendaMode.Month) {
197
+ updateDateRange(new Date(dayBtwStartAndEnd).setDate(1));
198
+ } else if (newMode === AgendaMode.Day) {
199
+ updateDateRange(dayBtwStartAndEnd);
200
+ }
201
+ });
202
+
178
203
  return {
179
204
  AgendaMode,
180
205
  showCalendarDialog,
@@ -15,7 +15,7 @@
15
15
  @click="$emit('click', $props.id)"
16
16
  >
17
17
  <template
18
- #default="{ label, icon, timeStart, timeEnd, iconBis, variant }"
18
+ #default="{ label, icon, timeStart, timeEnd, iconBis, variant, width }"
19
19
  >
20
20
  <slot
21
21
  name="default"
@@ -25,6 +25,7 @@
25
25
  :timeStart="timeStart"
26
26
  :timeEnd="timeEnd"
27
27
  :variant="variant"
28
+ :width="width"
28
29
  />
29
30
  </template>
30
31
  </FSAgendaHorizontalEvent>
@@ -43,10 +44,11 @@
43
44
  name="default"
44
45
  :label="label"
45
46
  :icon="icon"
46
- :iconBis="iconBis"
47
+ :iconBis="endToday ? iconBis : null"
47
48
  :timeStart="epochToShortTimeOnlyFormat($props.start)"
48
49
  :timeEnd="epochToShortTimeOnlyFormat($props.end)"
49
50
  :variant="$props.variant"
51
+ :width="width"
50
52
  />
51
53
  </FSClickable>
52
54
  </template>
@@ -118,12 +120,20 @@ export default defineComponent({
118
120
  return dayEnd.value - props.dayStart;
119
121
  });
120
122
 
123
+ const startToday = computed(() => {
124
+ return props.start >= props.dayStart;
125
+ });
126
+
127
+ const endToday = computed(() => {
128
+ return props.end <= dayEnd.value;
129
+ });
130
+
121
131
  const dayDurationOffset = computed(() => {
122
132
  return dayDuration.value - dayToMillisecond(1);
123
133
  });
124
134
 
125
135
  const leftPosition = computed(() => {
126
- if (props.start < props.dayStart) {
136
+ if (!startToday.value) {
127
137
  return 0;
128
138
  }
129
139
  return millisecondToDay(props.start - props.dayStart - dayDurationOffset.value) * 100;
@@ -132,12 +142,12 @@ export default defineComponent({
132
142
  const width = computed(() => {
133
143
  let start = props.start - dayDurationOffset.value;
134
144
  let end = props.end - dayDurationOffset.value;
135
- if(props.variant === 'current') {
145
+ if(props.variant === 'current' && dayEnd.value > props.now) {
136
146
  end = props.now;
137
- } else if (props.end > dayEnd.value) {
147
+ } else if (!endToday.value) {
138
148
  end = dayEnd.value - dayDurationOffset.value;
139
149
  }
140
- if (props.start < props.dayStart) {
150
+ if (!startToday.value) {
141
151
  start = props.dayStart;
142
152
  }
143
153
 
@@ -148,12 +158,14 @@ export default defineComponent({
148
158
  const style = computed((): StyleValue => {
149
159
  return {
150
160
  '--fs-agenda-event-left': `${leftPosition.value}%`,
161
+ '--fs-agenda-event-border-width': startToday.value ? '3px' : '0px',
151
162
  };
152
163
  });
153
164
 
154
165
  return {
155
166
  style,
156
167
  width,
168
+ endToday,
157
169
  epochToShortTimeOnlyFormat
158
170
  };
159
171
  }