@dative-gpi/foundation-shared-components 1.1.24-unit-formatter → 1.1.24-unit-formatter-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 (74) hide show
  1. package/assets/images/map/open-street-map.png +0 -0
  2. package/components/FSAccordionPanel.vue +2 -0
  3. package/components/FSButton.vue +43 -87
  4. package/components/FSCard.vue +208 -100
  5. package/components/FSCardPlaceholder.vue +29 -25
  6. package/components/FSChip.vue +54 -127
  7. package/components/FSChipGroup.vue +141 -23
  8. package/components/FSClickable.vue +24 -326
  9. package/components/FSColor.vue +3 -3
  10. package/components/FSColorIcon.vue +1 -0
  11. package/components/FSDialogContent.vue +39 -28
  12. package/components/FSDialogFormBody.vue +2 -0
  13. package/components/FSDialogMenu.vue +8 -1
  14. package/components/FSDialogMultiFormBody.vue +6 -5
  15. package/components/FSDivider.vue +5 -1
  16. package/components/FSEditImageUI.vue +21 -30
  17. package/components/FSGridMosaic.vue +2 -0
  18. package/components/FSGroupingChip.vue +115 -0
  19. package/components/FSIconCard.vue +3 -1
  20. package/components/FSIconCheck.vue +8 -0
  21. package/components/FSImageCard.vue +4 -4
  22. package/components/FSInstantPicker.vue +2 -0
  23. package/components/FSLink.vue +1 -13
  24. package/components/FSOptionItem.vue +4 -4
  25. package/components/FSOptionsMenu.vue +6 -6
  26. package/components/FSPlayButtons.vue +11 -9
  27. package/components/FSProgressBar.vue +142 -28
  28. package/components/FSRangePicker.vue +2 -0
  29. package/components/FSRouterLink.vue +84 -14
  30. package/components/FSSlideGroup.vue +5 -1
  31. package/components/FSSnackbar.vue +146 -0
  32. package/components/FSSubgroupingChip.vue +138 -0
  33. package/components/FSWindow.vue +2 -0
  34. package/components/agenda/FSAgendaHorizontalEvent.vue +4 -4
  35. package/components/agenda/FSAgendaVerticalEvent.vue +4 -4
  36. package/components/deviceOrganisations/FSStatusRichCard.vue +4 -7
  37. package/components/fields/FSAutocompleteField.vue +1 -0
  38. package/components/fields/FSDurationField.vue +184 -0
  39. package/components/fields/FSEntityFieldUI.vue +12 -0
  40. package/components/fields/FSRichTextField.vue +2 -0
  41. package/components/lists/FSDataIteratorItem.vue +2 -0
  42. package/components/lists/FSDataTableUI.vue +12 -0
  43. package/components/lists/FSFilterButton.vue +34 -23
  44. package/components/lists/FSHeaderButton.vue +6 -3
  45. package/components/lists/FSTileList.vue +23 -6
  46. package/components/map/FSMap.vue +1 -1
  47. package/components/map/FSMapMarker.vue +4 -3
  48. package/components/selects/FSSelectMapLayer.vue +5 -0
  49. package/components/tiles/FSChartTileUI.vue +2 -0
  50. package/components/tiles/FSFolderTileUI.vue +2 -2
  51. package/components/tiles/FSLocationTileUI.vue +2 -0
  52. package/components/tiles/FSPlaylistTileUI.vue +149 -0
  53. package/components/tiles/FSServiceAccountOrganisationTileUI.vue +2 -0
  54. package/components/tiles/FSSubgroupingTileUI.vue +97 -0
  55. package/components/tiles/FSTile.vue +32 -64
  56. package/components/tiles/FSUserOrganisationTileUI.vue +2 -0
  57. package/components/toggleSets/FSToggleSetPosition.vue +5 -0
  58. package/composables/useMapLayers.ts +12 -0
  59. package/models/index.ts +2 -1
  60. package/models/map.ts +2 -1
  61. package/models/tables.ts +1 -0
  62. package/models/variants.ts +33 -0
  63. package/package.json +4 -4
  64. package/styles/components/fs_button.scss +1 -7
  65. package/styles/components/fs_card.scss +75 -4
  66. package/styles/components/fs_chip.scss +0 -29
  67. package/styles/components/fs_filter_button.scss +6 -1
  68. package/styles/components/fs_map.scss +7 -1
  69. package/styles/components/fs_progress_bar.scss +62 -6
  70. package/styles/components/fs_snackbar.scss +7 -0
  71. package/styles/components/index.scss +1 -2
  72. package/styles/globals/overrides.scss +1 -1
  73. package/styles/components/fs_clickable.scss +0 -69
  74. package/styles/components/fs_color_icon.scss +0 -3
@@ -0,0 +1,184 @@
1
+ <template>
2
+ <FSBaseField
3
+ :description="$props.description"
4
+ :hideHeader="$props.hideHeader"
5
+ :required="$props.required"
6
+ :disabled="$props.disabled"
7
+ :label="$props.label"
8
+ :messages="messages"
9
+ >
10
+ <FSRow
11
+ :wrap="false"
12
+ align="center-left"
13
+ >
14
+ <FSNumberField
15
+ suffix="h"
16
+ :hideHeader="true"
17
+ :modelValue="innerHours"
18
+ :disabled="$props.disabled"
19
+ :rules="[() => messages.length === 0 || '']"
20
+ @update:modelValue="onChangeHours"
21
+ />
22
+ <FSSpan>:</FSSpan>
23
+ <FSNumberField
24
+ suffix="min"
25
+ :hideHeader="true"
26
+ :disabled="$props.disabled"
27
+ :rules="[() => messages.length === 0 || '']"
28
+ :modelValue="innerMinutes"
29
+ @update:modelValue="onChangeMinutes"
30
+ />
31
+ </FSRow>
32
+ </FSBaseField>
33
+ </template>
34
+
35
+ <script lang="ts">
36
+ import { computed, defineComponent, type PropType, ref, watch } from "vue";
37
+
38
+ import { NumberRules } from "@dative-gpi/foundation-shared-components/models";
39
+ import { useRules } from "@dative-gpi/foundation-shared-components/composables";
40
+
41
+ import FSNumberField from "./FSNumberField.vue";
42
+ import FSBaseField from "./FSBaseField.vue";
43
+ import FSSpan from "../FSSpan.vue";
44
+ import FSRow from "../FSRow.vue";
45
+
46
+ export default defineComponent({
47
+ name: "FSDurationField",
48
+ components: {
49
+ FSNumberField,
50
+ FSBaseField,
51
+ FSSpan,
52
+ FSRow
53
+ },
54
+ props: {
55
+ label: {
56
+ type: String as PropType<string | null>,
57
+ required: false,
58
+ default: null
59
+ },
60
+ description: {
61
+ type: String as PropType<string | null>,
62
+ required: false,
63
+ default: null
64
+ },
65
+ modelValue: {
66
+ type: Number as PropType<number | null>,
67
+ required: false,
68
+ default: null
69
+ },
70
+ maxDuration: {
71
+ type: Number as PropType<number | null>,
72
+ required: false,
73
+ default: null
74
+ },
75
+ minDuration: {
76
+ type: Number as PropType<number | null>,
77
+ required: false,
78
+ default: null
79
+ },
80
+ hideHeader: {
81
+ type: Boolean,
82
+ required: false,
83
+ default: false
84
+ },
85
+ required: {
86
+ type: Boolean,
87
+ required: false,
88
+ default: false
89
+ },
90
+ rules: {
91
+ type: Array as PropType<any[]>,
92
+ required: false,
93
+ default: () => []
94
+ },
95
+ messages: {
96
+ type: Array as PropType<string[]>,
97
+ required: false,
98
+ default: null
99
+ },
100
+ disabled: {
101
+ type: Boolean,
102
+ required: false,
103
+ default: false
104
+ }
105
+ },
106
+ emits: ["update:modelValue"],
107
+ setup(props, { emit }) {
108
+ const { getMessages } = useRules();
109
+ const MS_PER_MINUTE = 60 * 1000;
110
+ const MS_PER_HOUR = 60 * MS_PER_MINUTE;
111
+
112
+ const innerHours = ref<number | null>(null);
113
+ const innerMinutes = ref<number | null>(null);
114
+
115
+ const durationRules = computed(() => {
116
+ const rules: any[] = [...props.rules];
117
+ if (props.required) {
118
+ rules.push(NumberRules.required());
119
+ }
120
+ if (props.minDuration != null) {
121
+ const minHours = Math.floor(props.minDuration / MS_PER_HOUR);
122
+ const minMinutes = Math.floor((props.minDuration % MS_PER_HOUR) / MS_PER_MINUTE);
123
+ const label = minHours > 0 ? `${minHours}h${minMinutes.toString().padStart(2, '0')}` : `${minMinutes}min`;
124
+ rules.push((v: any) => (v != null && v >= props.minDuration!) || `Min. ${label}`);
125
+ }
126
+ if (props.maxDuration != null) {
127
+ const maxHours = Math.floor(props.maxDuration / MS_PER_HOUR);
128
+ const maxMinutes = Math.floor((props.maxDuration % MS_PER_HOUR) / MS_PER_MINUTE);
129
+ const label = maxHours > 0 ? `${maxHours}h${maxMinutes.toString().padStart(2, '0')}` : `${maxMinutes}min`;
130
+ rules.push((v: any) => (v != null && v <= props.maxDuration!) || `Max. ${label}`);
131
+ }
132
+ return rules;
133
+ });
134
+
135
+ const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, durationRules.value));
136
+
137
+ const reset = (): void => {
138
+ if (props.modelValue == null) {
139
+ innerHours.value = null;
140
+ innerMinutes.value = null;
141
+ return;
142
+ }
143
+ innerHours.value = Math.floor(props.modelValue / MS_PER_HOUR);
144
+ innerMinutes.value = Math.floor((props.modelValue % MS_PER_HOUR) / MS_PER_MINUTE);
145
+ };
146
+
147
+ const emitValue = (): void => {
148
+ const hours = innerHours.value ?? 0;
149
+ const minutes = innerMinutes.value ?? 0;
150
+ emit("update:modelValue", (hours * MS_PER_HOUR) + (minutes * MS_PER_MINUTE));
151
+ };
152
+
153
+ const onChangeHours = (value: number | null): void => {
154
+ innerHours.value = value;
155
+ emitValue();
156
+ };
157
+
158
+ const onChangeMinutes = (value: number | null): void => {
159
+ value = Math.min(59, Math.max(0, value ?? 0));
160
+ innerMinutes.value = value;
161
+ emitValue();
162
+ };
163
+
164
+ watch(() => props.modelValue, () => {
165
+ const currentHours = innerHours.value ?? 0;
166
+ const currentMinutes = innerMinutes.value ?? 0;
167
+ const currentTotal = (currentHours * MS_PER_HOUR) + (currentMinutes * MS_PER_MINUTE);
168
+ if (currentTotal !== (props.modelValue ?? 0)) {
169
+ reset();
170
+ }
171
+ }, { immediate: true });
172
+
173
+ return {
174
+ NumberRules,
175
+ innerHours,
176
+ innerMinutes,
177
+ durationRules,
178
+ messages,
179
+ onChangeHours,
180
+ onChangeMinutes
181
+ };
182
+ }
183
+ });
184
+ </script>
@@ -233,6 +233,14 @@ export default defineComponent({
233
233
  {
234
234
  id: EntityType.Folder,
235
235
  label: $tr("ui.common.folders", "Folders")
236
+ },
237
+ {
238
+ id: EntityType.Grouping,
239
+ label: $tr("ui.common.groupings", "Groupings")
240
+ },
241
+ {
242
+ id: EntityType.Subgrouping,
243
+ label: $tr("ui.common.subgroupings", "Categories")
236
244
  }
237
245
  ];
238
246
 
@@ -259,6 +267,10 @@ export default defineComponent({
259
267
  return "mdi-view-dashboard";
260
268
  case EntityType.Folder:
261
269
  return "mdi-folder";
270
+ case EntityType.Grouping:
271
+ return "mdi-chart-donut";
272
+ case EntityType.Subgrouping:
273
+ return "mdi-shape-outline";
262
274
  default:
263
275
  return "mdi-cube";
264
276
  }
@@ -246,6 +246,7 @@ import FSTextField from "./FSTextField.vue";
246
246
  import FSIcon from "../FSIcon.vue";
247
247
  import FSCard from "../FSCard.vue";
248
248
  import FSText from "../FSText.vue";
249
+ import FSSpan from "../FSSpan.vue";
249
250
  import FSMenu from '../FSMenu.vue';
250
251
  import FSCol from "../FSCol.vue";
251
252
  import FSRow from "../FSRow.vue";
@@ -256,6 +257,7 @@ export default defineComponent({
256
257
  FSAutoCompleteField,
257
258
  FSTextField,
258
259
  FSText,
260
+ FSSpan,
259
261
  FSIcon,
260
262
  FSCard,
261
263
  FSMenu,
@@ -63,6 +63,7 @@ import { defineComponent, type PropType } from "vue";
63
63
  import { type FSDataTableColumn } from "@dative-gpi/foundation-shared-components/models";
64
64
 
65
65
  import FSRow from "../FSRow.vue";
66
+ import FSCol from "../FSCol.vue";
66
67
  import FSText from "../FSText.vue";
67
68
  import FSTile from '../tiles/FSTile.vue';
68
69
 
@@ -71,6 +72,7 @@ export default defineComponent({
71
72
  components: {
72
73
  FSTile,
73
74
  FSText,
75
+ FSCol,
74
76
  FSRow
75
77
  },
76
78
  props: {
@@ -97,6 +97,14 @@
97
97
  :filters="filters[header.value]"
98
98
  @update:filter="(value) => toggleFilter(header.value, value)"
99
99
  >
100
+ <template
101
+ #custom="{ filter, toggle, variant }"
102
+ >
103
+ <slot
104
+ :name="`${filterSlot(header)}-custom`"
105
+ v-bind="{ filter, toggle, variant }"
106
+ />
107
+ </template>
100
108
  <template
101
109
  #default="{ filter }"
102
110
  >
@@ -741,10 +749,12 @@ import FSFilterButton from "./FSFilterButton.vue";
741
749
  import FSHiddenButton from "./FSHiddenButton.vue";
742
750
  import FSHeaderButton from "./FSHeaderButton.vue";
743
751
  import FSOptionGroup from "../FSOptionGroup.vue";
752
+ import FSSlideGroup from "../FSSlideGroup.vue";
744
753
  import FSToggleSet from "../FSToggleSet.vue";
745
754
  import FSDraggable from "./FSDraggable.vue";
746
755
  import FSCheckbox from "../FSCheckbox.vue";
747
756
  import FSDivider from "../FSDivider.vue";
757
+ import FSButton from '../FSButton.vue';
748
758
  import FSCard from "../FSCard.vue";
749
759
  import FSChip from "../FSChip.vue";
750
760
  import FSIcon from "../FSIcon.vue";
@@ -763,10 +773,12 @@ export default defineComponent({
763
773
  FSSearchField,
764
774
  FSSelectField,
765
775
  FSOptionGroup,
776
+ FSSlideGroup,
766
777
  FSDraggable,
767
778
  FSToggleSet,
768
779
  FSCheckbox,
769
780
  FSDivider,
781
+ FSButton,
770
782
  FSCard,
771
783
  FSChip,
772
784
  FSIcon,
@@ -40,6 +40,7 @@
40
40
  :height="['30px', '24px']"
41
41
  :variant="getAllVariant()"
42
42
  :color="$props.color"
43
+ align="center-left"
43
44
  :clickable="true"
44
45
  @click="onToggleAll"
45
46
  />
@@ -56,25 +57,35 @@
56
57
  <FSCol
57
58
  gap="6px"
58
59
  >
59
- <FSChip
60
+ <template
60
61
  v-for="(filter, index) in searchedFilters"
61
- class="fs-filter-button-chip"
62
- :variant="getVariant(filter)"
63
- :height="['30px', '24px']"
64
- :color="$props.color"
65
- :label="filter.text"
66
- :clickable="true"
67
62
  :key="index"
68
- @click="() => onToggle(filter)"
69
63
  >
70
- <template
71
- #default
64
+ <slot
65
+ name="custom"
66
+ v-bind="{ filter, toggle: () => onToggle(filter), variant: getVariant(filter) }"
72
67
  >
73
- <slot
74
- v-bind="{ filter }"
75
- />
76
- </template>
77
- </FSChip>
68
+ <FSChip
69
+ class="fs-filter-button-chip"
70
+ :variant="getVariant(filter)"
71
+ :height="['30px', '24px']"
72
+ :color="$props.color"
73
+ :label="filter.text"
74
+ align="center-left"
75
+ :clickable="true"
76
+ :border="false"
77
+ @click="() => onToggle(filter)"
78
+ >
79
+ <template
80
+ #default
81
+ >
82
+ <slot
83
+ v-bind="{ filter }"
84
+ />
85
+ </template>
86
+ </FSChip>
87
+ </slot>
88
+ </template>
78
89
  </FSCol>
79
90
  </FSFadeOut>
80
91
  </FSCol>
@@ -85,7 +96,7 @@
85
96
  <script lang="ts">
86
97
  import { computed, defineComponent, type PropType, ref } from "vue";
87
98
 
88
- import { type ColorBase, ColorEnum, type FSDataTableColumn, type FSDataTableFilter } from "@dative-gpi/foundation-shared-components/models";
99
+ import { type CardVariant, CardVariants, type ColorBase, ColorEnum, type FSDataTableColumn, type FSDataTableFilter } from "@dative-gpi/foundation-shared-components/models";
89
100
  import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
90
101
 
91
102
  import FSSearchField from "../fields/FSSearchField.vue";
@@ -153,21 +164,21 @@ export default defineComponent({
153
164
  return props.filters;
154
165
  });
155
166
 
156
- const getVariant = (filter: FSDataTableFilter): "standard" | "full" | "borderless" => {
167
+ const getVariant = (filter: FSDataTableFilter): CardVariant => {
157
168
  if (singlePick.value || props.filters.filter(f => f.hidden).length > 0) {
158
169
  if (filter.hidden) {
159
- return "borderless";
170
+ return CardVariants.Background;
160
171
  }
161
- return "full";
172
+ return CardVariants.Full;
162
173
  }
163
- return "borderless";
174
+ return CardVariants.Background;
164
175
  };
165
176
 
166
- const getAllVariant = (): "standard" | "full" => {
177
+ const getAllVariant = (): CardVariant => {
167
178
  if (singlePick.value || props.filters.filter(f => f.hidden).length > 0) {
168
- return "standard";
179
+ return CardVariants.Background;
169
180
  }
170
- return "full";
181
+ return CardVariants.Full;
171
182
  };
172
183
 
173
184
  const onToggle = (filter: FSDataTableFilter): void => {
@@ -32,7 +32,8 @@
32
32
  <FSChip
33
33
  prependIcon="mdi-eye-off-outline"
34
34
  class="fs-header-button-chip"
35
- variant="borderless"
35
+ variant="background"
36
+ :border="false"
36
37
  :label="$tr('data-table.hide-column', 'Hide column')"
37
38
  :height="[30, 24]"
38
39
  :clickable="true"
@@ -41,7 +42,8 @@
41
42
  <FSChip
42
43
  v-if="!$props.first"
43
44
  class="fs-header-button-chip"
44
- variant="borderless"
45
+ variant="background"
46
+ :border="false"
45
47
  prependIcon="mdi-chevron-left"
46
48
  :label="$tr('data-table.move-left', 'Move to the left')"
47
49
  :height="[30, 24]"
@@ -51,7 +53,8 @@
51
53
  <FSChip
52
54
  v-if="!$props.last"
53
55
  class="fs-header-button-chip"
54
- variant="borderless"
56
+ variant="background"
57
+ :border="false"
55
58
  prependIcon="mdi-chevron-right"
56
59
  :label="$tr('data-table.move-right', 'Move to the right')"
57
60
  :height="[30, 24]"
@@ -2,12 +2,21 @@
2
2
  <FSCol
3
3
  gap="12px"
4
4
  >
5
- <FSSearchField
6
- v-if="$props.searchable"
7
- :hideHeader="true"
8
- :modelValue="actualSearch"
9
- @update:modelValue="onSearch"
10
- />
5
+ <FSRow
6
+ v-if="$props.searchable || $slots.action"
7
+ :wrap="false"
8
+ align="center-left"
9
+ >
10
+ <FSSearchField
11
+ v-if="$props.searchable"
12
+ :hideHeader="true"
13
+ :modelValue="actualSearch"
14
+ @update:modelValue="onSearch"
15
+ />
16
+ <slot
17
+ name="action"
18
+ />
19
+ </FSRow>
11
20
  <FSFadeOut
12
21
  v-if="$props.direction == ListDirections.Column"
13
22
  :maxHeight="$props.maxHeight"
@@ -109,11 +118,13 @@ import FSFadeOut from "../FSFadeOut.vue";
109
118
  import FSSlideGroup from "../FSSlideGroup.vue"
110
119
  import FSSearchField from "../fields/FSSearchField.vue";
111
120
  import FSSimpleTileUI from "../tiles/FSSimpleTileUI.vue";
121
+ import FSRow from "../FSRow.vue";
112
122
 
113
123
  export default defineComponent({
114
124
  name: "FSTileList",
115
125
  components: {
116
126
  FSCol,
127
+ FSRow,
117
128
  FSFadeOut,
118
129
  FSLoader,
119
130
  FSSlideGroup,
@@ -223,6 +234,12 @@ export default defineComponent({
223
234
  actualSearch.value = value;
224
235
  });
225
236
 
237
+ watch(() => props.singleSelect, () => {
238
+ if(props.singleSelect && props.modelValue.length > 1) {
239
+ emit("update:modelValue", []);
240
+ }
241
+ }, { immediate: true });
242
+
226
243
  return {
227
244
  actualSearch,
228
245
  filteredItems,
@@ -389,7 +389,7 @@ export default defineComponent({
389
389
  if(!map.value || !props.bounds) {
390
390
  return;
391
391
  }
392
- fitBounds(props.bounds, { maxZoom: 14 });
392
+ fitBounds(props.bounds, { maxZoom: props.zoom });
393
393
  });
394
394
 
395
395
  watch(() => props.enableScrollWheelZoom, (newValue) => {
@@ -11,8 +11,9 @@ import { type Map, divIcon, type LatLng, marker, type Marker, type MarkerCluster
11
11
  import { useColors } from "../../composables";
12
12
  import { useRouting } from '@dative-gpi/foundation-shared-services/composables';
13
13
 
14
- import { gpsMarkerHtml, locationMarkerHtml, pinMarkerHtml } from '../../utils/leafletMarkers';
15
14
  import { MAP, MARKERCLUSTERGROUP } from './keys';
15
+ import { ColorEnum, type ColorBase } from '@dative-gpi/foundation-shared-components/models';
16
+ import { gpsMarkerHtml, locationMarkerHtml, pinMarkerHtml } from '../../utils/leafletMarkers';
16
17
 
17
18
  export default {
18
19
  name: 'FSMapMarker',
@@ -23,8 +24,8 @@ export default {
23
24
  required: false
24
25
  },
25
26
  color: {
26
- type: String,
27
- default: 'primary',
27
+ type: String as PropType<ColorBase>,
28
+ default: ColorEnum.Primary,
28
29
  required: false
29
30
  },
30
31
  latlng: {
@@ -48,6 +48,11 @@ export default defineComponent({
48
48
  icon: 'mdi-map',
49
49
  label: $tr("ui.map-layer.map", "Map")
50
50
  },
51
+ {
52
+ id: MapLayers.OpenStreetMap,
53
+ icon: 'mdi-map-plus',
54
+ label: $tr("ui.map-layer.open-street-map", "Open Street Map")
55
+ },
51
56
  {
52
57
  id: MapLayers.Imagery,
53
58
  icon: 'mdi-satellite',
@@ -68,6 +68,7 @@ import { ApplicationScope, ChartType } from "@dative-gpi/foundation-shared-domai
68
68
  import { chartIcon } from "@dative-gpi/foundation-shared-components/tools";
69
69
 
70
70
  import FSImage from "../FSImage.vue";
71
+ import FSIcon from "../FSIcon.vue";
71
72
  import FSTile from "./FSTile.vue";
72
73
  import FSSpan from "../FSSpan.vue";
73
74
  import FSRow from "../FSRow.vue";
@@ -80,6 +81,7 @@ export default defineComponent({
80
81
  name: "FSChartTileUI",
81
82
  components: {
82
83
  FSImage,
84
+ FSIcon,
83
85
  FSTile,
84
86
  FSRow,
85
87
  FSCol,
@@ -14,12 +14,12 @@
14
14
  gap="6px"
15
15
  >
16
16
  <FSEntityCountBadge
17
- :label="$tr('ui.common.folders', 'Folder(s)')"
17
+ :label="$tr('ui.common.folders', 'Folders')"
18
18
  :count="$props.recursiveFoldersIds?.length ?? 0"
19
19
  :color="ColorEnum.Primary"
20
20
  />
21
21
  <FSEntityCountBadge
22
- :label="$tr('ui.common.dashboards', 'Dashboard(s)')"
22
+ :label="$tr('ui.common.dashboards', 'Dashboards')"
23
23
  :count="dashboardCount"
24
24
  :color="ColorEnum.Success"
25
25
  />
@@ -60,6 +60,7 @@ import { type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-compone
60
60
 
61
61
  import FSEntityCountBadge from './FSEntityCountBadge.vue';
62
62
  import FSSimpleTileUI from './FSSimpleTileUI.vue';
63
+ import FSIcon from "../FSIcon.vue";
63
64
  import FSColor from "../FSColor.vue";
64
65
  import FSSpan from "../FSSpan.vue";
65
66
  import FSCol from "../FSCol.vue";
@@ -70,6 +71,7 @@ export default defineComponent({
70
71
  components: {
71
72
  FSEntityCountBadge,
72
73
  FSSimpleTileUI,
74
+ FSIcon,
73
75
  FSColor,
74
76
  FSSpan,
75
77
  FSCol,