@dative-gpi/foundation-shared-components 0.0.7 → 0.0.9

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 (139) hide show
  1. package/{models/FSButtons.ts → aliases/FSButton.ts} +24 -21
  2. package/aliases/index.ts +1 -0
  3. package/components/FSAutocompleteField.vue +207 -0
  4. package/components/FSBadge.vue +38 -0
  5. package/components/FSBreadcrumbs.vue +49 -55
  6. package/components/FSButton.vue +116 -101
  7. package/components/FSCalendar.vue +184 -0
  8. package/components/FSCalendarTwin.vue +412 -0
  9. package/components/FSCard.vue +77 -0
  10. package/components/FSCarousel.vue +63 -0
  11. package/components/FSCheckbox.vue +111 -104
  12. package/components/FSChip.vue +140 -0
  13. package/components/FSClock.vue +172 -0
  14. package/components/FSCol.vue +104 -98
  15. package/components/FSColor.vue +61 -64
  16. package/components/FSColorIcon.vue +67 -0
  17. package/components/FSContainer.vue +64 -0
  18. package/components/FSDateField.vue +211 -0
  19. package/components/FSDateRangeField.vue +225 -0
  20. package/components/FSDateTimeField.vue +257 -0
  21. package/components/FSDateTimeRangeField.vue +286 -0
  22. package/components/FSDialog.vue +103 -0
  23. package/components/FSDivider.vue +39 -0
  24. package/components/FSFadeOut.vue +49 -59
  25. package/components/FSFileButton.vue +245 -0
  26. package/components/FSHeaderButton.vue +17 -0
  27. package/components/FSIcon.vue +23 -23
  28. package/components/FSIconField.vue +232 -0
  29. package/components/FSImage.vue +142 -0
  30. package/components/FSLoadTile.vue +93 -0
  31. package/components/FSNumberField.vue +51 -53
  32. package/components/FSPasswordField.vue +99 -99
  33. package/components/FSRadio.vue +107 -110
  34. package/components/FSRadioGroup.vue +55 -57
  35. package/components/FSRemoveDialog.vue +123 -0
  36. package/components/FSRichTextField.vue +551 -0
  37. package/components/FSRow.vue +110 -104
  38. package/components/FSSearchField.vue +114 -105
  39. package/components/FSSelectField.vue +188 -0
  40. package/components/FSSlideGroup.vue +45 -49
  41. package/components/FSSlider.vue +130 -0
  42. package/components/FSSpan.vue +53 -37
  43. package/components/FSSubmitDialog.vue +165 -0
  44. package/components/FSSwitch.vue +110 -109
  45. package/components/FSTab.vue +61 -61
  46. package/components/FSTabs.vue +53 -55
  47. package/components/FSTag.vue +88 -84
  48. package/components/FSTagField.vue +183 -128
  49. package/components/FSTagGroup.vue +38 -45
  50. package/components/FSText.vue +74 -64
  51. package/components/FSTextArea.vue +209 -0
  52. package/components/FSTextField.vue +152 -149
  53. package/components/FSTile.vue +90 -0
  54. package/components/FSToggleSet.vue +282 -0
  55. package/components/FSTooltip.vue +21 -0
  56. package/components/FSWindow.vue +26 -16
  57. package/components/FSWrapGroup.vue +44 -47
  58. package/components/deviceOrganisations/FSConnectivity.vue +114 -0
  59. package/components/deviceOrganisations/FSStatus.vue +117 -0
  60. package/components/deviceOrganisations/FSStatusesCarousel.vue +105 -0
  61. package/components/deviceOrganisations/FSStatusesRow.vue +66 -0
  62. package/components/deviceOrganisations/FSWorstAlert.vue +165 -0
  63. package/components/lists/FSDataIteratorGroup.vue +7 -0
  64. package/components/lists/FSDataIteratorItem.vue +103 -0
  65. package/components/lists/FSDataTable.vue +964 -0
  66. package/components/lists/FSFilterButton.vue +176 -0
  67. package/components/lists/FSHeaderButton.vue +99 -0
  68. package/components/lists/FSHiddenButton.vue +79 -0
  69. package/components/tiles/FSDeviceOrganisationTileUI.vue +232 -0
  70. package/components/tiles/FSGroupTileUI.vue +192 -0
  71. package/composables/index.ts +2 -1
  72. package/composables/useBreakpoints.ts +33 -0
  73. package/composables/useColors.ts +53 -23
  74. package/composables/useSlots.ts +43 -0
  75. package/index.ts +6 -0
  76. package/models/breadcrumbs.ts +8 -0
  77. package/models/colors.ts +17 -0
  78. package/models/deviceAlerts.ts +10 -0
  79. package/models/deviceConnectivities.ts +11 -0
  80. package/models/deviceStatuses.ts +16 -0
  81. package/models/dispositions.ts +33 -0
  82. package/models/index.ts +9 -0
  83. package/models/modelStatuses.ts +11 -0
  84. package/models/rules.ts +50 -0
  85. package/models/toggleSets.ts +7 -0
  86. package/package.json +13 -4
  87. package/plugins/colorPlugin.ts +2 -2
  88. package/shims-plugin.d.ts +1 -1
  89. package/styles/components/fs_autocomplete_field.scss +123 -0
  90. package/styles/components/fs_button.scss +4 -14
  91. package/styles/components/fs_calendar.scss +138 -0
  92. package/styles/components/fs_card.scss +4 -0
  93. package/styles/components/fs_carousel.scss +4 -0
  94. package/styles/components/fs_chip.scss +33 -0
  95. package/styles/components/fs_clock.scss +43 -0
  96. package/styles/components/fs_col.scss +2 -0
  97. package/styles/components/fs_color_icon.scss +37 -0
  98. package/styles/components/fs_container.scss +16 -0
  99. package/styles/components/fs_data_iterator_item.scss +19 -0
  100. package/styles/components/fs_data_table.scss +97 -0
  101. package/styles/components/fs_date_field.scss +8 -0
  102. package/styles/components/fs_dialog.scss +30 -0
  103. package/styles/components/fs_divider.scss +5 -0
  104. package/styles/components/fs_fade_out.scss +10 -2
  105. package/styles/components/fs_filter_button.scss +12 -0
  106. package/styles/components/fs_header_button.scss +4 -0
  107. package/styles/components/fs_icon.scss +14 -4
  108. package/styles/components/fs_icon_field.scss +12 -0
  109. package/styles/components/fs_image.scss +7 -0
  110. package/styles/components/fs_load_tile.scss +49 -0
  111. package/styles/components/fs_password_field.scss +2 -2
  112. package/styles/components/fs_rich_text_field.scss +67 -0
  113. package/styles/components/fs_row.scss +4 -1
  114. package/styles/components/fs_select_field.scss +71 -0
  115. package/styles/components/fs_slide_group.scss +6 -0
  116. package/styles/components/fs_slider.scss +40 -0
  117. package/styles/components/fs_span.scss +8 -0
  118. package/styles/components/fs_submit_dialog.scss +9 -0
  119. package/styles/components/fs_tabs.scss +4 -0
  120. package/styles/components/fs_tag_field.scss +6 -8
  121. package/styles/components/fs_text_area.scss +105 -0
  122. package/styles/components/fs_text_field.scss +23 -15
  123. package/styles/components/fs_tile.scss +33 -0
  124. package/styles/components/fs_tooltip.scss +5 -0
  125. package/styles/components/fs_wrap_group.scss +7 -8
  126. package/styles/components/index.scss +26 -0
  127. package/styles/globals/breakpoints.scss +7 -0
  128. package/styles/globals/overrides.scss +20 -7
  129. package/styles/globals/text_fonts.scss +8 -8
  130. package/themes/default.ts +1 -11
  131. package/utils/css.ts +11 -0
  132. package/utils/icons.ts +75416 -0
  133. package/utils/index.ts +5 -0
  134. package/utils/levenshtein.ts +97 -0
  135. package/utils/lexical.ts +27 -0
  136. package/utils/sort.ts +9 -0
  137. package/composables/useTouch.ts +0 -9
  138. package/models/FSTags.ts +0 -8
  139. package/models/FSTextFields.ts +0 -17
@@ -0,0 +1,90 @@
1
+ <template>
2
+ <FSCard
3
+ class="fs-tile"
4
+ padding="12px"
5
+ :style="style"
6
+ :width="width"
7
+ :height="height"
8
+ >
9
+ <slot />
10
+ <FSContainer
11
+ v-if="$props.editable"
12
+ class="fs-tile-checkbox"
13
+ :border="false"
14
+ >
15
+ <FSCheckbox
16
+ :color="ColorEnum.Dark"
17
+ :modelValue="$props.modelValue"
18
+ @update:modelValue="() => $emit('update:modelValue', !$props.modelValue)"
19
+ />
20
+ </FSContainer>
21
+ <div
22
+ class="fs-tile-bottom"
23
+ :style="style"
24
+ />
25
+ </FSCard>
26
+ </template>
27
+
28
+ <script lang="ts">
29
+ import { computed, defineComponent, PropType } from "vue";
30
+
31
+ import { useBreakpoints, useColors } from "@dative-gpi/foundation-shared-components/composables";
32
+ import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
33
+
34
+ import FSContainer from "./FSContainer.vue";
35
+ import FSCheckbox from "./FSCheckbox.vue";
36
+ import FSCard from "./FSCard.vue";
37
+
38
+ export default defineComponent({
39
+ name: "FSTile",
40
+ components: {
41
+ FSContainer,
42
+ FSCheckbox,
43
+ FSCard
44
+ },
45
+ props: {
46
+ modelValue: {
47
+ type: Boolean,
48
+ required: false,
49
+ default: false
50
+ },
51
+ bottomColor: {
52
+ type: [Array, String] as PropType<ColorBase[] | ColorBase>,
53
+ required: false,
54
+ default: ColorEnum.Primary
55
+ },
56
+ editable: {
57
+ type: Boolean,
58
+ required: false,
59
+ default: false
60
+ }
61
+ },
62
+ emits: ["update:modelValue"],
63
+ setup(props) {
64
+ const { isMobileSized } = useBreakpoints();
65
+
66
+ const bottomColors = computed(() => useColors().getGradients(props.bottomColor));
67
+
68
+ const style = computed((): {[code: string]: string} & Partial<CSSStyleDeclaration> => {
69
+ return {
70
+ "--fs-tile-border-color": bottomColors.value.base
71
+ };
72
+ });
73
+
74
+ const width = computed(() => {
75
+ return isMobileSized.value ? 336 : 352;
76
+ });
77
+
78
+ const height = computed(() => {
79
+ return isMobileSized.value ? 156 : 170;
80
+ });
81
+
82
+ return {
83
+ ColorEnum,
84
+ style,
85
+ width,
86
+ height
87
+ };
88
+ }
89
+ });
90
+ </script>
@@ -0,0 +1,282 @@
1
+ <template>
2
+ <FSWrapGroup
3
+ v-if="['wrap'].includes($props.variant)"
4
+ :padding="$props.padding"
5
+ :gap="$props.gap"
6
+ >
7
+ <template v-if="$props.values.length">
8
+ <template v-if="!firstChild">
9
+ <FSButton
10
+ v-for="(item, index) in $props.values"
11
+ :prependIcon="item.prependIcon"
12
+ :appendIcon="item.appendIcon"
13
+ :editable="$props.editable"
14
+ :variant="getVariant(item)"
15
+ :color="getColor(item)"
16
+ :class="getClass(item)"
17
+ :label="item.label"
18
+ :key="index"
19
+ @click="toggle(item)"
20
+ />
21
+ </template>
22
+ <template v-else>
23
+ <component
24
+ v-for="(item, index) in $props.values"
25
+ :key="index"
26
+ :is="firstChild"
27
+ :prependIcon="getFromFirstChild('prependIcon', item)"
28
+ :appendIcon="getFromFirstChild('appendIcon', item)"
29
+ :variant="getFromFirstChild('variant', item)"
30
+ :color="getFromFirstChild('color', item)"
31
+ :class="getFromFirstChild('class', item)"
32
+ :label="getFromFirstChild('label', item)"
33
+ :icon="getFromFirstChild('icon', item)"
34
+ :editable="$props.editable"
35
+ @click="toggle(item)"
36
+ />
37
+ </template>
38
+ </template>
39
+ <slot v-else />
40
+ </FSWrapGroup>
41
+ <FSSlideGroup
42
+ v-else
43
+ :padding="$props.padding"
44
+ :gap="$props.gap"
45
+ >
46
+ <template v-if="$props.values.length">
47
+ <template v-if="!firstChild">
48
+ <FSButton
49
+ v-for="(item, index) in $props.values"
50
+ :prependIcon="item.prependIcon"
51
+ :appendIcon="item.appendIcon"
52
+ :editable="$props.editable"
53
+ :variant="getVariant(item)"
54
+ :color="getColor(item)"
55
+ :class="getClass(item)"
56
+ :label="item.label"
57
+ :key="index"
58
+ @click="toggle(item)"
59
+ />
60
+ </template>
61
+ <template v-else>
62
+ <component
63
+ v-for="(item, index) in $props.values"
64
+ :key="index"
65
+ :is="firstChild"
66
+ :prependIcon="getFromFirstChild('prependIcon', item)"
67
+ :appendIcon="getFromFirstChild('appendIcon', item)"
68
+ :variant="getFromFirstChild('variant', item)"
69
+ :color="getFromFirstChild('color', item)"
70
+ :class="getFromFirstChild('class', item)"
71
+ :label="getFromFirstChild('label', item)"
72
+ :icon="getFromFirstChild('icon', item)"
73
+ :editable="$props.editable"
74
+ @click="toggle(item)"
75
+ />
76
+ </template>
77
+ </template>
78
+ <slot v-else />
79
+ </FSSlideGroup>
80
+ </template>
81
+
82
+ <script lang="ts">
83
+ import { defineComponent, PropType } from "vue";
84
+
85
+ import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
86
+ import { useSlots } from "@dative-gpi/foundation-shared-components/composables";
87
+ import { FSToggle } from "@dative-gpi/foundation-shared-components/models";
88
+
89
+ import FSSlideGroup from "./FSSlideGroup.vue";
90
+ import FSWrapGroup from "./FSWrapGroup.vue";
91
+ import FSButton from "./FSButton.vue";
92
+
93
+ export default defineComponent({
94
+ name: "FSToggleSet",
95
+ components: {
96
+ FSSlideGroup,
97
+ FSWrapGroup,
98
+ FSButton
99
+ },
100
+ props: {
101
+ values: {
102
+ type: Array as PropType<FSToggle[]>,
103
+ required: false,
104
+ default: () => []
105
+ },
106
+ variant: {
107
+ type: String as PropType<"wrap" | "slide">,
108
+ required: false,
109
+ default: "wrap"
110
+ },
111
+ buttonVariant: {
112
+ type: String as PropType<"standard" | "full" | "icon">,
113
+ required: false,
114
+ default: "standard"
115
+ },
116
+ activeVariant: {
117
+ type: String as PropType<"standard" | "full" | "icon">,
118
+ required: false,
119
+ default: "standard"
120
+ },
121
+ buttonClass: {
122
+ type: [Array, String] as PropType<string[] | string>,
123
+ required: false,
124
+ default: null
125
+ },
126
+ activeClass: {
127
+ type: [Array, String] as PropType<string[] | string>,
128
+ required: false,
129
+ default: null
130
+ },
131
+ modelValue: {
132
+ type: [Array, String, Number] as PropType<(string | number)[] | string | number>,
133
+ required: false,
134
+ default: false
135
+ },
136
+ buttonColor: {
137
+ type: String as PropType<ColorBase>,
138
+ required: false,
139
+ default: ColorEnum.Light
140
+ },
141
+ activeColor: {
142
+ type: String as PropType<ColorBase>,
143
+ required: false,
144
+ default: ColorEnum.Primary
145
+ },
146
+ padding: {
147
+ type: [String, Number],
148
+ required: false,
149
+ default: 0
150
+ },
151
+ gap: {
152
+ type: Number,
153
+ required: false,
154
+ default: 8
155
+ },
156
+ multiple: {
157
+ type: Boolean,
158
+ required: false,
159
+ default: false
160
+ },
161
+ required: {
162
+ type: Boolean,
163
+ required: false,
164
+ default: false
165
+ },
166
+ editable: {
167
+ type: Boolean,
168
+ required: false,
169
+ default: true
170
+ }
171
+ },
172
+ emits: ["update:modelValue"],
173
+ setup(props, { emit }) {
174
+ const { getFirstChild } = useSlots();
175
+
176
+ const firstChild = getFirstChild("item");
177
+
178
+ const getFromFirstChild = (prop: string, value: FSToggle): any => {
179
+ switch (prop) {
180
+ case "prependIcon":
181
+ return firstChild.props.prependIcon ?? value.prependIcon;
182
+ case "label":
183
+ return firstChild.props.label ?? value.label;
184
+ case "appendIcon":
185
+ return firstChild.props.appendIcon ?? value.appendIcon;
186
+ case "icon":
187
+ return firstChild.props.icon ?? value.icon;
188
+ case "variant":
189
+ return firstChild.props.variant ?? getVariant(value);
190
+ case "color":
191
+ return firstChild.props.color ?? getColor(value);
192
+ default:
193
+ return firstChild.props[prop];
194
+ }
195
+ }
196
+
197
+ const getVariant = (value: FSToggle): "standard" | "full" | "icon" => {
198
+ if (Array.isArray(props.modelValue) && props.modelValue.some(v => v === value.id)) {
199
+ return props.activeVariant;
200
+ }
201
+ if (!Array.isArray(props.modelValue) && props.modelValue === value.id) {
202
+ return props.activeVariant;
203
+ }
204
+ return props.buttonVariant;
205
+ };
206
+
207
+ const getColor = (value: FSToggle): ColorBase => {
208
+ if (Array.isArray(props.modelValue) && props.modelValue.some(v => v === value.id)) {
209
+ return props.activeColor;
210
+ }
211
+ if (!Array.isArray(props.modelValue) && props.modelValue === value.id) {
212
+ return props.activeColor;
213
+ }
214
+ return props.buttonColor;
215
+ };
216
+
217
+ const getClass = (value: FSToggle): string[] | string => {
218
+ if (Array.isArray(props.modelValue) && props.modelValue.some(v => v === value.id)) {
219
+ return props.activeClass;
220
+ }
221
+ if (!Array.isArray(props.modelValue) && props.modelValue === value.id) {
222
+ return props.activeClass;
223
+ }
224
+ return props.buttonClass;
225
+ };
226
+
227
+ const toggle = (value: FSToggle): void => {
228
+ if (Array.isArray(props.modelValue)) {
229
+ if (props.multiple) {
230
+ if (props.modelValue.length && props.modelValue.every(v => v === value.id)) {
231
+ if (!props.required) {
232
+ emit("update:modelValue", []);
233
+ return;
234
+ }
235
+ }
236
+ else if (props.modelValue.some(v => v === value.id)) {
237
+ emit("update:modelValue", props.modelValue.filter(v => v !== value.id));
238
+ return;
239
+ }
240
+ else {
241
+ emit("update:modelValue", [...props.modelValue, value.id]);
242
+ return;
243
+ }
244
+ }
245
+ else {
246
+ if (props.modelValue.some(v => v === value.id)) {
247
+ if (!props.required) {
248
+ emit("update:modelValue", []);
249
+ return;
250
+ }
251
+ }
252
+ else {
253
+ emit("update:modelValue", [value.id]);
254
+ return;
255
+ }
256
+ }
257
+ }
258
+ else {
259
+ if (props.modelValue === value.id) {
260
+ if (!props.required) {
261
+ emit("update:modelValue", null);
262
+ return;
263
+ }
264
+ }
265
+ else {
266
+ emit("update:modelValue", value.id);
267
+ return;
268
+ }
269
+ }
270
+ };
271
+
272
+ return {
273
+ firstChild,
274
+ getFromFirstChild,
275
+ getVariant,
276
+ getColor,
277
+ getClass,
278
+ toggle
279
+ };
280
+ }
281
+ })
282
+ </script>
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <v-tooltip
3
+ class="fs-tooltip"
4
+ location="top"
5
+ >
6
+ <template #activator="{ props }">
7
+ <slot name="activator" v-bind="props" />
8
+ </template>
9
+ <template v-for="(_, name) in $slots" v-slot:[name]="slotData">
10
+ <slot :name="name" v-bind="slotData" />
11
+ </template>
12
+ </v-tooltip>
13
+ </template>
14
+
15
+ <script lang="ts">
16
+ import { defineComponent } from "vue";
17
+
18
+ export default defineComponent({
19
+ name: "FSTooltip"
20
+ });
21
+ </script>
@@ -1,26 +1,36 @@
1
1
  <template>
2
- <v-window
3
- class="fs-window"
4
- :modelValue="$props.tab"
5
- v-bind="$attrs"
2
+ <v-window
3
+ class="fs-window"
4
+ v-bind="$attrs"
5
+ >
6
+ <v-window-item
7
+ v-for="(component, index) in getChildren()"
8
+ :value="value(component, index)"
9
+ :key="index"
6
10
  >
7
- <v-window-item v-for="(component, index) in $slots.default()" :key="index">
8
- <component :is="component" />
9
- </v-window-item>
10
- </v-window>
11
+ <component :is="component" />
12
+ </v-window-item>
13
+ </v-window>
11
14
  </template>
12
15
 
13
16
  <script lang="ts">
14
- import { defineComponent } from "vue";
17
+ import { defineComponent, VNode } from "vue";
18
+
19
+ import { useSlots } from "@dative-gpi/foundation-shared-components/composables";
15
20
 
16
21
  export default defineComponent({
17
- name: "FSWindow",
18
- props: {
19
- tab: {
20
- type: Number,
21
- required: false,
22
- default: 0
23
- }
22
+ name: "FSWindow",
23
+ setup() {
24
+ const { getChildren } = useSlots();
25
+
26
+ const value = (component: VNode, index: number): any => {
27
+ return component?.props?.value ?? index;
28
+ };
29
+
30
+ return {
31
+ getChildren,
32
+ value
24
33
  }
34
+ }
25
35
  });
26
36
  </script>
@@ -1,59 +1,56 @@
1
1
  <template>
2
- <v-slide-group
3
- class="fs-wrap-group"
4
- :style="style"
5
- v-bind="$attrs"
2
+ <v-slide-group
3
+ class="fs-wrap-group"
4
+ :style="style"
5
+ v-bind="$attrs"
6
+ >
7
+ <v-slide-group-item
8
+ v-for="(component, index) in getChildren()"
9
+ :key="index"
6
10
  >
7
- <FSRow>
8
- <v-slide-group-item v-for="(component, index) in $slots.default()" :key="index">
9
- <component :is="component" v-bind="{ color, colors, style }" />
10
- </v-slide-group-item>
11
- </FSRow>
12
- </v-slide-group>
11
+ <component :is="component" />
12
+ </v-slide-group-item>
13
+ </v-slide-group>
13
14
  </template>
14
15
 
15
16
  <script lang="ts">
16
- import { defineComponent, PropType, Ref, ref, toRefs } from "vue";
17
+ import { computed, defineComponent } from "vue";
17
18
 
18
- import { useColors } from "@dative-gpi/foundation-shared-components/composables";
19
- import { ColorBase } from "@dative-gpi/foundation-shared-components/themes";
20
-
21
- import FSRow from "./FSRow.vue";
19
+ import { useColors, useSlots } from "@dative-gpi/foundation-shared-components/composables";
20
+ import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
22
21
 
23
22
  export default defineComponent({
24
- name: "FSWrapGroup",
25
- components: {
26
- FSRow
27
- },
28
- props: {
29
- color: {
30
- type: String as PropType<ColorBase>,
31
- required: false,
32
- default: ColorBase.Primary
33
- }
23
+ name: "FSWrapGroup",
24
+ props: {
25
+ padding: {
26
+ type: [String, Number],
27
+ required: false,
28
+ default: 0
34
29
  },
35
- setup(props) {
36
- const { color } = toRefs(props);
37
-
38
- const colors = useColors().getColors(color.value);
39
-
40
- const darks = useColors().getColors(ColorBase.Dark);
41
-
42
- const style: Ref<{ [code: string]: string } & Partial<CSSStyleDeclaration>> = ref({
43
- "--fs-group-color": darks.base,
44
- "--fs-group-hover-background-color": colors.light,
45
- "--fs-group-hover-color": darks.dark,
46
- "--fs-group-disabled-color": darks.light,
47
- "--fs-group-light": colors.light,
48
- "--fs-group-base": colors.base,
49
- "--fs-group-dark": colors.dark
50
- });
51
-
52
- return {
53
- color,
54
- colors,
55
- style
56
- };
30
+ gap: {
31
+ type: Number,
32
+ required: false,
33
+ default: 8
57
34
  }
35
+ },
36
+ setup(props) {
37
+ const { getChildren } = useSlots();
38
+
39
+ const darks = useColors().getColors(ColorEnum.Dark);
40
+
41
+ const style = computed((): { [code: string]: string } & Partial<CSSStyleDeclaration> => {
42
+ return {
43
+ "--fs-group-padding" : typeof(props.padding) === "string" ? props.padding : `${props.padding}px`,
44
+ "--fs-group-gap" : `${props.gap}px`,
45
+ "--fs-group-color" : darks.light,
46
+ "--fs-group-hover-color": darks.dark
47
+ }
48
+ });
49
+
50
+ return {
51
+ style,
52
+ getChildren
53
+ };
54
+ }
58
55
  });
59
56
  </script>
@@ -0,0 +1,114 @@
1
+ <template>
2
+ <v-menu
3
+ v-if="$props.deviceConnectivity"
4
+ :closeOnContentClick="false"
5
+ v-model="menu"
6
+ >
7
+ <template #activator="{ props }">
8
+ <FSColorIcon
9
+ size="m"
10
+ variant="fill"
11
+ :color="$props.deviceConnectivity.color"
12
+ v-bind="props"
13
+ >
14
+ {{ $props.deviceConnectivity.icon }}
15
+ </FSColorIcon>
16
+ </template>
17
+ <FSCard
18
+ :elevation="true"
19
+ :border="false"
20
+ >
21
+ <FSCol
22
+ align="center-center"
23
+ padding="6px 24px"
24
+ >
25
+ <FSCol
26
+ align="center-center"
27
+ gap="12px"
28
+ >
29
+ <FSChip
30
+ :color="$props.deviceConnectivity.color"
31
+ :prependIcon="$props.deviceConnectivity.icon"
32
+ :label="connectivityLabel"
33
+ />
34
+ <FSRow
35
+ width="hug"
36
+ >
37
+ <FSText>
38
+ {{ $tr("ui.shared.device-connectivity.last-message", "Last message") }}
39
+ </FSText>
40
+ </FSRow>
41
+ </FSCol>
42
+ <FSRow
43
+ v-if="deviceTimestamp"
44
+ width="hug"
45
+ >
46
+ <FSSpan
47
+ font="text-overline"
48
+ >
49
+ {{ deviceTimestamp }}
50
+ </FSSpan>
51
+ </FSRow>
52
+ </FSCol>
53
+ </FSCard>
54
+ </v-menu>
55
+ </template>
56
+
57
+ <script lang="ts">
58
+ import { computed, defineComponent, PropType, ref } from "vue";
59
+
60
+ import { useTimeZone, useTranslationsProvider } from "@dative-gpi/foundation-shared-services/composables";
61
+ import { FSDeviceConnectivity } from "@dative-gpi/foundation-shared-components/models";
62
+ import { ConnectivityStatus } from "@dative-gpi/foundation-shared-domain/models";
63
+
64
+ import FSColorIcon from "../FSColorIcon.vue";
65
+ import FSCard from "../FSCard.vue";
66
+ import FSChip from "../FSChip.vue";
67
+ import FSText from "../FSText.vue";
68
+ import FSSpan from "../FSSpan.vue";
69
+
70
+ export default defineComponent({
71
+ name: "FSConnectivity",
72
+ components: {
73
+ FSColorIcon,
74
+ FSCard,
75
+ FSChip,
76
+ FSText,
77
+ FSSpan
78
+ },
79
+ props: {
80
+ deviceConnectivity: {
81
+ type: Object as PropType<FSDeviceConnectivity>,
82
+ required: true
83
+ }
84
+ },
85
+ setup(props) {
86
+ const { epochToLongTimeFormat } = useTimeZone();
87
+ const { $tr } = useTranslationsProvider();
88
+
89
+ const menu = ref(false);
90
+
91
+ const connectivityLabel = computed((): string => {
92
+ switch (props.deviceConnectivity.status) {
93
+ case ConnectivityStatus.Connected: return $tr("ui.connectivity-status.connected", "Connected");
94
+ case ConnectivityStatus.PartiallyConnected: return $tr("ui.connectivity-status.partially-connected", "Partially connected");
95
+ case ConnectivityStatus.AlmostOffline: return $tr("ui.connectivity-status.almost-offline", "Almost offline");
96
+ default: return $tr("ui.connectivity-status.offline", "Offline");
97
+ }
98
+ });
99
+
100
+ const deviceTimestamp = computed((): string => {
101
+ if (props.deviceConnectivity.sourceTimestamp) {
102
+ return epochToLongTimeFormat(props.deviceConnectivity.sourceTimestamp);
103
+ }
104
+ return "";
105
+ });
106
+
107
+ return {
108
+ connectivityLabel,
109
+ deviceTimestamp,
110
+ menu
111
+ };
112
+ }
113
+ });
114
+ </script>