@dative-gpi/foundation-shared-components 0.0.83 → 0.0.85

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 (35) hide show
  1. package/components/FSDialogForm.vue +3 -0
  2. package/components/FSForm.vue +1 -1
  3. package/components/FSToggleSet.vue +124 -82
  4. package/components/autocompletes/FSAutocompleteLanguage.vue +122 -0
  5. package/components/autocompletes/FSAutocompleteOrganisation.vue +43 -0
  6. package/components/autocompletes/FSAutocompleteTimeZone.vue +49 -0
  7. package/components/fields/FSAutocompleteField.vue +117 -62
  8. package/components/fields/FSDateField.vue +21 -7
  9. package/components/fields/FSDateRangeField.vue +18 -6
  10. package/components/fields/FSDateTimeField.vue +24 -8
  11. package/components/fields/FSDateTimeRangeField.vue +20 -6
  12. package/components/fields/FSTextField.vue +21 -6
  13. package/components/lists/FSDataTableUI.vue +5 -5
  14. package/composables/index.ts +1 -0
  15. package/composables/useAutocomplete.ts +81 -0
  16. package/composables/useDebounce.ts +15 -15
  17. package/icons/sets.ts +28 -0
  18. package/icons/widgetTemplates/AlertsPodiumWidget.vue +18 -0
  19. package/icons/widgetTemplates/AlertsWidget.vue +54 -0
  20. package/icons/widgetTemplates/ChartsWidget.vue +18 -0
  21. package/icons/widgetTemplates/DashboardsWidget.vue +18 -0
  22. package/icons/widgetTemplates/DevicesWidget.vue +274 -0
  23. package/icons/widgetTemplates/EditWidget.vue +18 -0
  24. package/icons/widgetTemplates/GroupsWidget.vue +18 -0
  25. package/icons/widgetTemplates/LocationsWidget.vue +46 -0
  26. package/icons/widgetTemplates/MapWidget.vue +18 -0
  27. package/icons/widgetTemplates/ModelsWidget.vue +26 -0
  28. package/icons/widgetTemplates/ProfileWidget.vue +30 -0
  29. package/icons/widgetTemplates/TextWidget.vue +62 -0
  30. package/package.json +4 -4
  31. package/styles/components/fs_data_iterator_item.scss +1 -1
  32. package/styles/components/fs_toggle_set.scss +4 -0
  33. package/styles/components/index.scss +1 -0
  34. package/styles/globals/overrides.scss +2 -2
  35. package/utils/icons.ts +139 -3
@@ -32,6 +32,7 @@
32
32
  #body
33
33
  >
34
34
  <FSForm
35
+ ref="formRef"
35
36
  :variant="$props.variant"
36
37
  @submit="onSubmit"
37
38
  v-model="valid"
@@ -198,6 +199,7 @@ export default defineComponent({
198
199
  const { isMobileSized } = useBreakpoints();
199
200
  const { $tr } = useTranslationsProvider();
200
201
 
202
+ const formRef = ref<HTMLElement | null>(null);
201
203
  const valid = ref(false);
202
204
 
203
205
  const height = computed(() => {
@@ -227,6 +229,7 @@ export default defineComponent({
227
229
  cancelButtonLabel,
228
230
  submitButtonLabel,
229
231
  ColorEnum,
232
+ formRef,
230
233
  height,
231
234
  valid,
232
235
  onSubmit
@@ -36,7 +36,7 @@ export default defineComponent({
36
36
  switch (props.variant) {
37
37
  case "standard": return "input";
38
38
  case "lazy": return "blur";
39
- case "submit": return "submit";
39
+ default: return "submit";
40
40
  }
41
41
  });
42
42
 
@@ -1,86 +1,109 @@
1
1
  <template>
2
- <FSWrapGroup
3
- v-if="['wrap'].includes($props.variant)"
4
- ref="toggleSetRef"
5
- :padding="$props.padding"
6
- :gap="$props.gap"
2
+ <v-input
3
+ class="fs-toggle-set"
4
+ ref="inputRef"
5
+ :modelValue="$props.modelValue"
6
+ :rules="$props.rules"
7
7
  >
8
- <template v-if="$props.values.length">
9
- <template v-if="!firstChild">
10
- <FSButton
11
- v-for="(item, index) in $props.values"
12
- :prependIcon="item.prependIcon"
13
- :appendIcon="item.appendIcon"
14
- :editable="$props.editable"
15
- :variant="getVariant(item)"
16
- :color="getColor(item)"
17
- :class="getClass(item)"
18
- :label="item.label"
19
- :icon="item.icon"
20
- :key="index"
21
- @click="toggle(item)"
22
- />
8
+ <FSWrapGroup
9
+ v-if="['wrap'].includes($props.variant)"
10
+ ref="toggleSetRef"
11
+ :padding="$props.padding"
12
+ :gap="$props.gap"
13
+ >
14
+ <template
15
+ v-if="$props.values.length"
16
+ >
17
+ <template
18
+ v-if="!firstChild"
19
+ >
20
+ <FSButton
21
+ v-for="(item, index) in $props.values"
22
+ :prependIcon="item.prependIcon"
23
+ :appendIcon="item.appendIcon"
24
+ :editable="$props.editable"
25
+ :variant="getVariant(item)"
26
+ :color="getColor(item)"
27
+ :class="getClass(item)"
28
+ :label="item.label"
29
+ :icon="item.icon"
30
+ :key="index"
31
+ @click="toggle(item)"
32
+ />
33
+ </template>
34
+ <template
35
+ v-else
36
+ >
37
+ <component
38
+ v-for="(item, index) in $props.values"
39
+ :key="index"
40
+ :is="firstChild"
41
+ :prependIcon="getFromFirstChild('prependIcon', item)"
42
+ :appendIcon="getFromFirstChild('appendIcon', item)"
43
+ :variant="getFromFirstChild('variant', item)"
44
+ :color="getFromFirstChild('color', item)"
45
+ :class="getFromFirstChild('class', item)"
46
+ :label="getFromFirstChild('label', item)"
47
+ :icon="getFromFirstChild('icon', item)"
48
+ :editable="$props.editable"
49
+ @click="toggle(item)"
50
+ />
51
+ </template>
23
52
  </template>
24
- <template v-else>
25
- <component
26
- v-for="(item, index) in $props.values"
27
- :key="index"
28
- :is="firstChild"
29
- :prependIcon="getFromFirstChild('prependIcon', item)"
30
- :appendIcon="getFromFirstChild('appendIcon', item)"
31
- :variant="getFromFirstChild('variant', item)"
32
- :color="getFromFirstChild('color', item)"
33
- :class="getFromFirstChild('class', item)"
34
- :label="getFromFirstChild('label', item)"
35
- :icon="getFromFirstChild('icon', item)"
36
- :editable="$props.editable"
37
- @click="toggle(item)"
38
- />
53
+ <slot
54
+ v-else
55
+ />
56
+ </FSWrapGroup>
57
+ <FSSlideGroup
58
+ v-else
59
+ ref="toggleSetRef"
60
+ :padding="$props.padding"
61
+ :gap="$props.gap"
62
+ >
63
+ <template
64
+ v-if="$props.values.length"
65
+ >
66
+ <template
67
+ v-if="!firstChild"
68
+ >
69
+ <FSButton
70
+ v-for="(item, index) in $props.values"
71
+ :prependIcon="item.prependIcon"
72
+ :appendIcon="item.appendIcon"
73
+ :editable="$props.editable"
74
+ :variant="getVariant(item)"
75
+ :color="getColor(item)"
76
+ :class="getClass(item)"
77
+ :label="item.label"
78
+ :icon="item.icon"
79
+ :key="index"
80
+ @click="toggle(item)"
81
+ />
82
+ </template>
83
+ <template
84
+ v-else
85
+ >
86
+ <component
87
+ v-for="(item, index) in $props.values"
88
+ :key="index"
89
+ :is="firstChild"
90
+ :prependIcon="getFromFirstChild('prependIcon', item)"
91
+ :appendIcon="getFromFirstChild('appendIcon', item)"
92
+ :variant="getFromFirstChild('variant', item)"
93
+ :color="getFromFirstChild('color', item)"
94
+ :class="getFromFirstChild('class', item)"
95
+ :label="getFromFirstChild('label', item)"
96
+ :icon="getFromFirstChild('icon', item)"
97
+ :editable="$props.editable"
98
+ @click="toggle(item)"
99
+ />
100
+ </template>
39
101
  </template>
40
- </template>
41
- <slot v-else />
42
- </FSWrapGroup>
43
- <FSSlideGroup
44
- v-else
45
- ref="toggleSetRef"
46
- :padding="$props.padding"
47
- :gap="$props.gap"
48
- >
49
- <template v-if="$props.values.length">
50
- <template v-if="!firstChild">
51
- <FSButton
52
- v-for="(item, index) in $props.values"
53
- :prependIcon="item.prependIcon"
54
- :appendIcon="item.appendIcon"
55
- :editable="$props.editable"
56
- :variant="getVariant(item)"
57
- :color="getColor(item)"
58
- :class="getClass(item)"
59
- :label="item.label"
60
- :icon="item.icon"
61
- :key="index"
62
- @click="toggle(item)"
63
- />
64
- </template>
65
- <template v-else>
66
- <component
67
- v-for="(item, index) in $props.values"
68
- :key="index"
69
- :is="firstChild"
70
- :prependIcon="getFromFirstChild('prependIcon', item)"
71
- :appendIcon="getFromFirstChild('appendIcon', item)"
72
- :variant="getFromFirstChild('variant', item)"
73
- :color="getFromFirstChild('color', item)"
74
- :class="getFromFirstChild('class', item)"
75
- :label="getFromFirstChild('label', item)"
76
- :icon="getFromFirstChild('icon', item)"
77
- :editable="$props.editable"
78
- @click="toggle(item)"
79
- />
80
- </template>
81
- </template>
82
- <slot v-else />
83
- </FSSlideGroup>
102
+ <slot
103
+ v-else
104
+ />
105
+ </FSSlideGroup>
106
+ </v-input>
84
107
  </template>
85
108
 
86
109
  <script lang="ts">
@@ -88,7 +111,7 @@ import { defineComponent, PropType, ref } from "vue";
88
111
 
89
112
  import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
90
113
  import { useSlots } from "@dative-gpi/foundation-shared-components/composables";
91
- import { FSToggle } from "@dative-gpi/foundation-shared-components/models";
114
+ import { FSToggle } from "@dative-gpi/foundation-shared-components/models";
92
115
 
93
116
  import FSSlideGroup from "./FSSlideGroup.vue";
94
117
  import FSWrapGroup from "./FSWrapGroup.vue";
@@ -157,6 +180,11 @@ export default defineComponent({
157
180
  required: false,
158
181
  default: "8px"
159
182
  },
183
+ rules: {
184
+ type: Array as PropType<any[]>,
185
+ required: false,
186
+ default: () => []
187
+ },
160
188
  multiple: {
161
189
  type: Boolean,
162
190
  required: false,
@@ -176,9 +204,10 @@ export default defineComponent({
176
204
  emits: ["update:modelValue"],
177
205
  setup(props, { emit }) {
178
206
  const { getFirstChild } = useSlots();
179
-
207
+
180
208
  const firstChild = getFirstChild("item");
181
-
209
+
210
+ const inputRef = ref(null);
182
211
  const toggleSetRef = ref(null);
183
212
 
184
213
  const getFromFirstChild = (prop: string, value: FSToggle): any => {
@@ -264,11 +293,23 @@ export default defineComponent({
264
293
  else {
265
294
  if (props.modelValue === value.id) {
266
295
  if (!props.required) {
296
+ if (props.multiple) {
297
+ emit("update:modelValue", []);
298
+ return;
299
+ }
267
300
  emit("update:modelValue", null);
268
301
  return;
269
302
  }
270
303
  }
271
304
  else {
305
+ if (props.multiple) {
306
+ if (props.modelValue) {
307
+ emit("update:modelValue", [props.modelValue, value.id]);
308
+ return;
309
+ }
310
+ emit("update:modelValue", [value.id]);
311
+ return;
312
+ }
272
313
  emit("update:modelValue", value.id);
273
314
  return;
274
315
  }
@@ -288,6 +329,7 @@ export default defineComponent({
288
329
  };
289
330
 
290
331
  return {
332
+ inputRef,
291
333
  toggleSetRef,
292
334
  firstChild,
293
335
  getFromFirstChild,
@@ -0,0 +1,122 @@
1
+ <template>
2
+ <FSAutocompleteField
3
+ :toggleSet="!$props.toggleSetDisabled && toggleSet"
4
+ :multiple="$props.multiple"
5
+ :loading="loading"
6
+ :items="languages"
7
+ :modelValue="$props.modelValue"
8
+ @update:modelValue="onUpdate"
9
+ v-model:search="search"
10
+ v-bind="$attrs"
11
+ >
12
+ <template
13
+ #selection="{ item }"
14
+ >
15
+ <FSRow
16
+ align="center-center"
17
+ >
18
+ <FSIcon>
19
+ {{ item.raw.icon }}
20
+ </FSIcon>
21
+ <FSSpan>
22
+ {{ item.raw.label }}
23
+ </FSSpan>
24
+ </FSRow>
25
+ </template>
26
+ <template
27
+ #item="{ props, item }"
28
+ >
29
+ <v-list-item
30
+ v-bind="{ ...props, title: '' }"
31
+ >
32
+ <FSRow
33
+ align="center-left"
34
+ >
35
+ <FSCheckbox
36
+ v-if="$props.multiple"
37
+ :modelValue="isSelected(item.value)"
38
+ />
39
+ <FSIcon>
40
+ {{ item.raw.icon }}
41
+ </FSIcon>
42
+ <FSSpan>
43
+ {{ item.raw.label }}
44
+ </FSSpan>
45
+ </FSRow>
46
+ </v-list-item>
47
+ </template>
48
+ </FSAutocompleteField>
49
+ </template>
50
+
51
+ <script lang="ts">
52
+ import { computed, PropType, defineComponent } from "vue"
53
+
54
+ import { useAutocomplete } from "@dative-gpi/foundation-shared-components/composables";
55
+ import { useLanguages } from "@dative-gpi/foundation-shared-services/composables";
56
+ import { LanguageFilters } from "@dative-gpi/foundation-shared-domain/models";
57
+
58
+ import FSCheckbox from "../FSCheckbox.vue"
59
+ import FSAutocompleteField from "../fields/FSAutocompleteField.vue"
60
+
61
+ export default defineComponent({
62
+ name: "FSAutocompleteLanguage",
63
+ components: {
64
+ FSAutocompleteField,
65
+ FSCheckbox
66
+ },
67
+ props: {
68
+ languageFilters: {
69
+ type: Object as PropType<LanguageFilters>,
70
+ required: false,
71
+ default: null
72
+ },
73
+ modelValue: {
74
+ type: [Array, String] as PropType<string[] | string | null>,
75
+ required: false,
76
+ default: null
77
+ },
78
+ multiple: {
79
+ type: Boolean,
80
+ required: false,
81
+ default: false
82
+ },
83
+ toggleSetDisabled: {
84
+ type: Boolean,
85
+ required: false,
86
+ default: false
87
+ }
88
+ },
89
+ emits: ["update:modelValue"],
90
+ setup(props, { emit }) {
91
+ const { getMany: getManyLanguages, fetching: fetchingLanguages, entities: languages } = useLanguages();
92
+
93
+ const innerFetch = (search: string | null) => {
94
+ return getManyLanguages({ ...props.languageFilters, search: search ?? undefined });
95
+ };
96
+
97
+ const { toggleSet, search, init, onUpdate } = useAutocomplete(
98
+ languages,
99
+ [() => props.languageFilters],
100
+ emit,
101
+ innerFetch
102
+ );
103
+
104
+ const isSelected = (id: any) => {
105
+ return props.modelValue?.includes(id);
106
+ }
107
+
108
+ const loading = computed((): boolean => {
109
+ return init.value && fetchingLanguages.value;
110
+ });
111
+
112
+ return {
113
+ languages,
114
+ toggleSet,
115
+ loading,
116
+ search,
117
+ isSelected,
118
+ onUpdate
119
+ };
120
+ }
121
+ })
122
+ </script>
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <FSAutocompleteField
3
+ :loading="fetching"
4
+ :items="organisations"
5
+ v-bind="$attrs" />
6
+ </template>
7
+ <script lang="ts">
8
+ import { PropType, defineComponent, watch } from 'vue'
9
+ import _ from 'lodash';
10
+
11
+ import { OrganisationFilters } from '@dative-gpi/foundation-shared-domain/models';
12
+ import { useOrganisations } from '@dative-gpi/foundation-shared-services/composables';
13
+
14
+ import FSAutocompleteField from '../fields/FSAutocompleteField.vue'
15
+
16
+ export default defineComponent({
17
+ name: 'FSAutocompleteOrganisation',
18
+ components: {
19
+ FSAutocompleteField
20
+ },
21
+ props: {
22
+ organisationFilters: {
23
+ type: Object as PropType<OrganisationFilters>,
24
+ required: false,
25
+ default: null
26
+ }
27
+ },
28
+ setup(props) {
29
+ const { entities: organisations, fetching, getMany } = useOrganisations();
30
+
31
+ watch(() => props.organisationFilters, async (newValue, oldValue) => {
32
+ if (!_.isEqual(newValue, oldValue)) {
33
+ await getMany(newValue);
34
+ }
35
+ }, { immediate: true });
36
+
37
+ return {
38
+ organisations,
39
+ fetching
40
+ }
41
+ }
42
+ })
43
+ </script>
@@ -0,0 +1,49 @@
1
+ <template>
2
+ <FSAutocompleteField
3
+ :loading="fetchingTimeZones"
4
+ :items="timeZones"
5
+ v-model:search="search"
6
+ v-bind="$attrs"
7
+ />
8
+ </template>
9
+
10
+ <script lang="ts">
11
+ import { defineComponent, PropType, ref, watch } from "vue";
12
+ import _ from "lodash";
13
+
14
+ import { useTimeZones } from "@dative-gpi/foundation-shared-services/composables";
15
+ import { TimeZoneFilters } from "@dative-gpi/foundation-shared-domain/models";
16
+
17
+ import FSAutocompleteField from "../fields/FSAutocompleteField.vue";
18
+
19
+ export default defineComponent({
20
+ name: "FSAutocompleteTimeZone",
21
+ components: {
22
+ FSAutocompleteField
23
+ },
24
+ props: {
25
+ timeZoneFilters: {
26
+ type: Object as PropType<TimeZoneFilters>,
27
+ required: false,
28
+ default: null
29
+ }
30
+ },
31
+ setup(props) {
32
+ const { getMany: getManyTimeZones, fetching: fetchingTimeZones, entities: timeZones } = useTimeZones();
33
+
34
+ const search = ref<string | null>(null);
35
+
36
+ watch([() => props.timeZoneFilters, () => search.value], async (newValue, oldValue) => {
37
+ if (!_.isEqual(newValue, oldValue)) {
38
+ await getManyTimeZones({ ...props.timeZoneFilters, search: search.value ?? undefined });
39
+ }
40
+ }, { immediate: true });
41
+
42
+ return {
43
+ fetchingTimeZones,
44
+ timeZones,
45
+ search
46
+ }
47
+ }
48
+ });
49
+ </script>