@dative-gpi/foundation-shared-components 0.0.118 → 0.1.120

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 (37) hide show
  1. package/components/FSBreadcrumbs.vue +1 -1
  2. package/components/FSButton.vue +1 -1
  3. package/components/FSChip.vue +1 -1
  4. package/components/FSClickable.vue +2 -2
  5. package/components/FSClock.vue +1 -7
  6. package/components/FSCol.vue +1 -1
  7. package/components/FSDialogForm.vue +141 -52
  8. package/components/FSDialogMultiForm.vue +39 -40
  9. package/components/FSDialogRemove.vue +2 -2
  10. package/components/FSDialogSubmit.vue +44 -39
  11. package/components/FSDivider.vue +1 -1
  12. package/components/FSSlideGroup.vue +1 -1
  13. package/components/FSTabs.vue +12 -12
  14. package/components/FSTagGroup.vue +28 -5
  15. package/components/FSText.vue +1 -1
  16. package/components/FSWrapGroup.vue +1 -1
  17. package/components/deviceOrganisations/FSStatusCard.vue +0 -1
  18. package/components/fields/FSAutocompleteField.vue +284 -106
  19. package/components/fields/FSDateRangeField.vue +2 -2
  20. package/components/fields/FSDateTimeRangeField.vue +5 -11
  21. package/components/fields/FSSelectField.vue +11 -3
  22. package/components/fields/FSTagField.vue +2 -2
  23. package/components/fields/FSTermField.vue +3 -1
  24. package/components/lists/FSDataTableUI.vue +1 -0
  25. package/components/tiles/FSDeviceOrganisationTileUI.vue +1 -1
  26. package/components/tiles/FSGroupTileUI.vue +1 -1
  27. package/components/tiles/FSSimpleIconTileUI.vue +1 -1
  28. package/components/tiles/FSUserOrganisationTileUI.vue +2 -2
  29. package/composables/useColors.ts +39 -49
  30. package/package.json +4 -4
  31. package/styles/components/fs_data_table.scss +100 -94
  32. package/styles/components/fs_dialog.scss +4 -3
  33. package/styles/components/fs_dialog_menu.scss +2 -2
  34. package/styles/components/fs_slider.scss +9 -1
  35. package/styles/components/fs_tabs.scss +5 -4
  36. package/styles/globals/overrides.scss +2 -2
  37. package/styles/globals/scrollbars.scss +46 -36
@@ -1,111 +1,42 @@
1
1
  <template>
2
- <FSBaseField
3
- :label="$props.label"
4
- :description="$props.description"
5
- :hideHeader="$props.hideHeader"
6
- :required="$props.required"
7
- :editable="$props.editable"
8
- :messages="messages"
2
+ <FSLoader
3
+ v-if="$props.loading"
4
+ width="100%"
5
+ :height="['40px', '36px']"
6
+ />
7
+ <template
8
+ v-else
9
9
  >
10
- <FSLoader
11
- v-if="$props.loading"
12
- width="100%"
13
- :height="['40px', '36px']"
14
- />
15
10
  <template
16
- v-else
11
+ v-if="isExtraSmall"
17
12
  >
18
- <FSToggleSet
19
- v-if="$props.toggleSet"
20
- variant="slide"
21
- :values="$props.items"
22
- :multiple="$props.multiple"
23
- :rules="$props.rules"
24
- :modelValue="$props.modelValue"
25
- @update:modelValue="onUpdate"
26
- v-bind="$attrs"
27
- >
28
- <template
29
- v-for="(_, name) in toggleSetSlots"
30
- v-slot:[name]="slotData"
31
- >
32
- <slot
33
- :name="`toggle-set-${name}`"
34
- v-bind="slotData"
35
- />
36
- </template>
37
- </FSToggleSet>
38
- <v-autocomplete
39
- v-else
40
- class="fs-autocomplete-field"
41
- variant="outlined"
42
- :menuIcon="null"
43
- :style="style"
44
- :listProps="listStyle"
45
- :class="classes"
46
- :hideDetails="true"
47
- :items="$props.items"
48
- :autoSelectFirst="true"
49
- :multiple="$props.multiple"
50
- :itemTitle="$props.itemTitle"
51
- :itemValue="$props.itemValue"
52
- :readonly="!$props.editable"
53
- :loading="$props.loading"
54
- :clearable="$props.clearable && $props.editable && !!$props.modelValue"
55
- :returnObject="$props.returnObject"
13
+ <FSTextField
14
+ :label="$props.label"
15
+ :description="$props.description"
16
+ :hideHeader="$props.hideHeader"
17
+ :required="$props.required"
18
+ :clearable="$props.clearable"
19
+ :editable="$props.editable"
20
+ :readonly="true"
56
21
  :rules="$props.rules"
22
+ :messages="messages"
57
23
  :validateOn="validateOn"
58
- :modelValue="$props.modelValue"
59
- @update:modelValue="onUpdate"
24
+ :validationValue="$props.modelValue"
25
+ :modelValue="mobileValue"
26
+ @update:modelValue="$emit('update:modelValue', $event)"
27
+ @click="openMobileOverlay"
60
28
  @blur="blurred = true"
61
- v-model:search="innerSearch"
62
29
  v-bind="$attrs"
63
30
  >
64
31
  <template
65
- #item="{ props, item }"
66
- >
67
- <v-list-item
68
- v-bind="{ ...props, title: '' }"
69
- >
70
- <FSRow
71
- align="center-left"
72
- :wrap="false"
73
- >
74
- <FSCheckbox
75
- v-if="$props.multiple"
76
- :modelValue="$props.modelValue?.includes(item.raw[$props.itemValue])"
77
- @click="props.onClick"
78
- />
79
- <FSSpan>
80
- {{ item.raw[$props.itemTitle] }}
81
- </FSSpan>
82
- </FSRow>
83
- </v-list-item>
84
- </template>
85
- <template
86
- v-for="(_, name) in autocompleteSlots"
32
+ v-for="(_, name) in $slots"
87
33
  v-slot:[name]="slotData"
88
34
  >
89
35
  <slot
90
- :name="`autocomplete-${name}`"
36
+ :name="name"
91
37
  v-bind="slotData"
92
38
  />
93
39
  </template>
94
- <template
95
- #clear
96
- >
97
- <slot
98
- name="clear"
99
- >
100
- <FSButton
101
- v-if="$props.clearable && $props.editable && !!$props.modelValue"
102
- icon="mdi-close"
103
- variant="icon"
104
- :color="ColorEnum.Dark"
105
- @click="$emit('update:modelValue', null)"
106
- />
107
- </slot>
108
- </template>
109
40
  <template
110
41
  #append-inner
111
42
  >
@@ -117,48 +48,222 @@
117
48
  variant="icon"
118
49
  :editable="$props.editable"
119
50
  :color="ColorEnum.Dark"
51
+ @click="openMobileOverlay"
120
52
  />
121
53
  </slot>
122
54
  </template>
55
+ </FSTextField>
56
+ <FSDialogMenu
57
+ v-model="dialog"
58
+ >
123
59
  <template
124
- #no-data
60
+ #body
125
61
  >
126
- <FSRow
127
- padding="17px"
62
+ <FSSearchField
63
+ v-model="search"
64
+ />
65
+ <FSFadeOut
66
+ :height="height"
128
67
  >
129
- <FSSpan>
130
- {{ $tr("ui.common.no-data", "No data") }}
131
- </FSSpan>
132
- </FSRow>
68
+ <FSCol
69
+ gap="12px"
70
+ >
71
+ <template
72
+ v-if="$props.multiple"
73
+ >
74
+ <FSRow
75
+ v-for="(item, index) in searchItems"
76
+ :key="index"
77
+ >
78
+ <FSCheckbox
79
+ :label="item[$props.itemTitle]"
80
+ :editable="$props.editable"
81
+ :modelValue="$props.modelValue?.includes(item[$props.itemValue])"
82
+ @update:modelValue="() => onCheckboxChange(item[$props.itemValue])"
83
+ />
84
+ </FSRow>
85
+ </template>
86
+ <FSRadioGroup
87
+ v-else
88
+ gap="12px"
89
+ :values="searchItems.map((item: any) => ({ value: item[$props.itemValue], label: item[$props.itemTitle] }))"
90
+ :modelValue="$props.modelValue"
91
+ :editable="$props.editable"
92
+ @update:modelValue="onRadioChange"
93
+ />
94
+ </FSCol>
95
+ </FSFadeOut>
133
96
  </template>
134
- </v-autocomplete>
97
+ </FSDialogMenu>
98
+ </template>
99
+ <template
100
+ v-else
101
+ >
102
+ <FSBaseField
103
+ :label="$props.label"
104
+ :description="$props.description"
105
+ :hideHeader="$props.hideHeader"
106
+ :required="$props.required"
107
+ :editable="$props.editable"
108
+ :messages="messages"
109
+ >
110
+ <FSToggleSet
111
+ v-if="$props.toggleSet"
112
+ variant="slide"
113
+ :values="$props.items"
114
+ :multiple="$props.multiple"
115
+ :rules="$props.rules"
116
+ :modelValue="$props.modelValue"
117
+ @update:modelValue="onUpdate"
118
+ v-bind="$attrs"
119
+ >
120
+ <template
121
+ v-for="(_, name) in toggleSetSlots"
122
+ v-slot:[name]="slotData"
123
+ >
124
+ <slot
125
+ :name="`toggle-set-${name}`"
126
+ v-bind="slotData"
127
+ />
128
+ </template>
129
+ </FSToggleSet>
130
+ <v-autocomplete
131
+ v-else
132
+ class="fs-autocomplete-field"
133
+ variant="outlined"
134
+ :menuIcon="null"
135
+ :style="style"
136
+ :listProps="listStyle"
137
+ :class="classes"
138
+ :hideDetails="true"
139
+ :items="$props.items"
140
+ :autoSelectFirst="true"
141
+ :multiple="$props.multiple"
142
+ :itemTitle="$props.itemTitle"
143
+ :itemValue="$props.itemValue"
144
+ :readonly="!$props.editable"
145
+ :loading="$props.loading"
146
+ :clearable="$props.clearable && $props.editable && !!$props.modelValue"
147
+ :returnObject="$props.returnObject"
148
+ :rules="$props.rules"
149
+ :validateOn="validateOn"
150
+ :modelValue="$props.modelValue"
151
+ @update:modelValue="onUpdate"
152
+ @blur="blurred = true"
153
+ v-model:search="search"
154
+ v-bind="$attrs"
155
+ >
156
+ <template
157
+ #item="{ props, item }"
158
+ >
159
+ <v-list-item
160
+ v-bind="{ ...props, title: '' }"
161
+ >
162
+ <FSRow
163
+ align="center-left"
164
+ :wrap="false"
165
+ >
166
+ <FSCheckbox
167
+ v-if="$props.multiple"
168
+ :modelValue="$props.modelValue?.includes(item.raw[$props.itemValue])"
169
+ @click="props.onClick"
170
+ />
171
+ <FSSpan>
172
+ {{ item.raw[$props.itemTitle] }}
173
+ </FSSpan>
174
+ </FSRow>
175
+ </v-list-item>
176
+ </template>
177
+ <template
178
+ v-for="(_, name) in autocompleteSlots"
179
+ v-slot:[name]="slotData"
180
+ >
181
+ <slot
182
+ :name="`autocomplete-${name}`"
183
+ v-bind="slotData"
184
+ />
185
+ </template>
186
+ <template
187
+ #clear
188
+ >
189
+ <slot
190
+ name="clear"
191
+ >
192
+ <FSButton
193
+ v-if="$props.clearable && $props.editable && !!$props.modelValue"
194
+ icon="mdi-close"
195
+ variant="icon"
196
+ :color="ColorEnum.Dark"
197
+ @click="$emit('update:modelValue', null)"
198
+ />
199
+ </slot>
200
+ </template>
201
+ <template
202
+ #append-inner
203
+ >
204
+ <slot
205
+ name="append-inner"
206
+ >
207
+ <FSButton
208
+ icon="mdi-chevron-down"
209
+ variant="icon"
210
+ :editable="$props.editable"
211
+ :color="ColorEnum.Dark"
212
+ />
213
+ </slot>
214
+ </template>
215
+ <template
216
+ #no-data
217
+ >
218
+ <FSRow
219
+ padding="17px"
220
+ >
221
+ <FSSpan>
222
+ {{ $tr("ui.common.no-data", "No data") }}
223
+ </FSSpan>
224
+ </FSRow>
225
+ </template>
226
+ </v-autocomplete>
227
+ </FSBaseField>
135
228
  </template>
136
- </FSBaseField>
229
+ </template>
137
230
  </template>
138
231
 
139
232
  <script lang="ts">
140
233
  import { computed, defineComponent, PropType, ref, watch } from "vue";
141
234
 
142
- import { useColors, useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
235
+ import { useBreakpoints, useColors, useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
143
236
  import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
144
237
 
238
+ import FSSearchField from "./FSSearchField.vue";
239
+ import FSDialogMenu from "../FSDialogMenu.vue";
240
+ import FSRadioGroup from "../FSRadioGroup.vue";
145
241
  import FSToggleSet from "../FSToggleSet.vue";
146
242
  import FSBaseField from "./FSBaseField.vue";
243
+ import FSTextField from "./FSTextField.vue";
147
244
  import FSCheckbox from "../FSCheckbox.vue";
245
+ import FSFadeOut from "../FSFadeOut.vue";
148
246
  import FSButton from "../FSButton.vue";
149
247
  import FSLoader from "../FSLoader.vue";
150
248
  import FSSpan from "../FSSpan.vue";
249
+ import FSCol from "../FSCol.vue";
151
250
  import FSRow from "../FSRow.vue";
152
251
 
153
252
  export default defineComponent({
154
253
  name: "FSAutocompleteField",
155
254
  components: {
255
+ FSSearchField,
256
+ FSDialogMenu,
257
+ FSRadioGroup,
156
258
  FSToggleSet,
157
259
  FSBaseField,
260
+ FSTextField,
158
261
  FSCheckbox,
262
+ FSFadeOut,
159
263
  FSButton,
160
264
  FSLoader,
161
265
  FSSpan,
266
+ FSCol,
162
267
  FSRow
163
268
  },
164
269
  props: {
@@ -244,6 +349,7 @@ export default defineComponent({
244
349
  },
245
350
  emits: ["update:modelValue", "update:search"],
246
351
  setup: (props, { emit }) => {
352
+ const { isExtraSmall, isMobileSized } = useBreakpoints();
247
353
  const { validateOn, blurred, getMessages } = useRules();
248
354
  const { getColors } = useColors();
249
355
  const { slots } = useSlots();
@@ -256,7 +362,8 @@ export default defineComponent({
256
362
  const lights = getColors(ColorEnum.Light);
257
363
  const darks = getColors(ColorEnum.Dark);
258
364
 
259
- const innerSearch = ref("");
365
+ const dialog = ref(false);
366
+ const search = ref("");
260
367
 
261
368
  const style = computed((): { [key: string]: string | undefined } => {
262
369
  if (!props.editable) {
@@ -308,26 +415,97 @@ export default defineComponent({
308
415
 
309
416
  const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
310
417
 
418
+ const searchItems = computed(() => {
419
+ return props.items.filter((item: any) => {
420
+ return item[props.itemTitle].toLowerCase().includes(search.value.toLowerCase());
421
+ });
422
+ });
423
+
424
+ const height = computed(() => {
425
+ const other = 8 + 8 // Paddings
426
+ + (isMobileSized ? 36 : 40) + 8; // Header
427
+ return `calc(100vh - 40px - ${other}px)`;
428
+ });
429
+
430
+ const mobileValue = computed((): string | null => {
431
+ if (props.multiple) {
432
+ if (Array.isArray(props.modelValue)) {
433
+ return props.modelValue.map((value: any) => {
434
+ const item = props.items.find((item: Object) => item[props.itemValue] === value);
435
+ if (item) {
436
+ return item[props.itemTitle];
437
+ }
438
+ }).filter(value => !!value).join(", ");
439
+ }
440
+ }
441
+ if (props.modelValue) {
442
+ const item = props.items.find((item: Object) => item[props.itemValue] === props.modelValue);
443
+ if (item) {
444
+ return item[props.itemTitle];
445
+ }
446
+ }
447
+ return null;
448
+ });
449
+
450
+ const openMobileOverlay = () => {
451
+ if (!props.editable) {
452
+ return;
453
+ }
454
+ dialog.value = true;
455
+ };
456
+
457
+ const onRadioChange = (value: any) => {
458
+ emit('update:modelValue', value);
459
+ dialog.value = false;
460
+ };
461
+
462
+ const onCheckboxChange = (value: any) => {
463
+ if (Array.isArray(props.modelValue)) {
464
+ if (props.modelValue.includes(value)) {
465
+ emit('update:modelValue', props.modelValue.filter((item: any) => item !== value));
466
+ }
467
+ else {
468
+ emit('update:modelValue', [...props.modelValue, value]);
469
+ }
470
+ }
471
+ else {
472
+ if (props.modelValue === value) {
473
+ emit('update:modelValue', []);
474
+ }
475
+ else {
476
+ emit('update:modelValue', [props.modelValue, value]);
477
+ }
478
+ }
479
+ };
480
+
311
481
  const onUpdate = (value: string[] | string) => {
312
482
  emit('update:modelValue', value);
313
483
  };
314
484
 
315
- watch(innerSearch, () => {
316
- emit("update:search", innerSearch.value);
485
+ watch(search, () => {
486
+ emit("update:search", search.value);
317
487
  });
318
488
 
319
489
  return {
320
490
  autocompleteSlots,
321
491
  toggleSetSlots,
322
- innerSearch,
492
+ isExtraSmall,
493
+ mobileValue,
494
+ searchItems,
323
495
  validateOn,
324
496
  ColorEnum,
325
497
  listStyle,
326
498
  messages,
327
499
  blurred,
328
500
  classes,
501
+ dialog,
502
+ height,
503
+ search,
329
504
  slots,
330
505
  style,
506
+ openMobileOverlay,
507
+ onCheckboxChange,
508
+ onRadioChange,
331
509
  onUpdate
332
510
  };
333
511
  }
@@ -43,8 +43,8 @@
43
43
  </FSTextField>
44
44
  <FSDialogSubmit
45
45
  :title="$props.label"
46
- :rightButtonColor="$props.color"
47
- @click:rightButton="onSubmit"
46
+ :submitButtonColor="$props.color"
47
+ @click:submitButton="onSubmit"
48
48
  v-model="dialog"
49
49
  >
50
50
  <template
@@ -43,8 +43,8 @@
43
43
  </FSTextField>
44
44
  <FSDialogSubmit
45
45
  :title="$props.label"
46
- :rightButtonColor="$props.color"
47
- @click:rightButton="onSubmit"
46
+ :submitButtonColor="$props.color"
47
+ @click:submitButton="onSubmit"
48
48
  v-model="dialog"
49
49
  >
50
50
  <template
@@ -55,21 +55,15 @@
55
55
  :color="$props.color"
56
56
  v-model="innerDateRange"
57
57
  />
58
- <FSRow
59
- width="100%"
60
- >
61
- <FSCol
62
- width="calc(50% - 4px)"
63
- >
58
+ <FSRow>
59
+ <FSCol>
64
60
  <FSClock
65
61
  :color="$props.color"
66
62
  :date="innerDateLeft"
67
63
  v-model="innerTimeLeft"
68
64
  />
69
65
  </FSCol>
70
- <FSCol
71
- width="calc(50% - 4px)"
72
- >
66
+ <FSCol>
73
67
  <FSClock
74
68
  :color="$props.color"
75
69
  :date="innerDateRight"
@@ -53,7 +53,7 @@
53
53
  #body
54
54
  >
55
55
  <FSFadeOut
56
- height="calc(90vh - 164px)"
56
+ :height="height"
57
57
  >
58
58
  <FSCol
59
59
  v-if="$props.multiple"
@@ -188,6 +188,7 @@ import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
188
188
  import FSDialogMenu from "../FSDialogMenu.vue";
189
189
  import FSRadioGroup from "../FSRadioGroup.vue";
190
190
  import FSBaseField from "./FSBaseField.vue";
191
+ import FSTextField from "./FSTextField.vue";
191
192
  import FSCheckbox from "../FSCheckbox.vue";
192
193
  import FSFadeOut from "../FSFadeOut.vue";
193
194
  import FSButton from "../FSButton.vue";
@@ -201,6 +202,7 @@ export default defineComponent({
201
202
  FSDialogMenu,
202
203
  FSRadioGroup,
203
204
  FSBaseField,
205
+ FSTextField,
204
206
  FSCheckbox,
205
207
  FSFadeOut,
206
208
  FSButton,
@@ -285,13 +287,13 @@ export default defineComponent({
285
287
  const { isExtraSmall } = useBreakpoints();
286
288
  const { getColors } = useColors();
287
289
 
288
- const dialog = ref(false);
289
-
290
290
  const backgrounds = getColors(ColorEnum.Background);
291
291
  const errors = getColors(ColorEnum.Error);
292
292
  const lights = getColors(ColorEnum.Light);
293
293
  const darks = getColors(ColorEnum.Dark);
294
294
 
295
+ const dialog = ref(false);
296
+
295
297
  const style = computed((): { [key: string] : string | null | undefined } => {
296
298
  if (!props.editable) {
297
299
  return {
@@ -319,6 +321,11 @@ export default defineComponent({
319
321
 
320
322
  const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
321
323
 
324
+ const height = computed(() => {
325
+ const other = 8 + 8; // Paddings
326
+ return `calc(100vh - 40px - ${other}px)`;
327
+ });
328
+
322
329
  const mobileValue = computed((): string | null => {
323
330
  if (props.multiple) {
324
331
  if (Array.isArray(props.modelValue)) {
@@ -379,6 +386,7 @@ export default defineComponent({
379
386
  messages,
380
387
  blurred,
381
388
  dialog,
389
+ height,
382
390
  style,
383
391
  openMobileOverlay,
384
392
  onCheckboxChange,
@@ -41,10 +41,10 @@
41
41
  </template>
42
42
  </FSTextField>
43
43
  <FSTagGroup
44
+ :tagVariant="$props.tagVariant"
45
+ :editable="$props.editable"
44
46
  :tags="$props.modelValue"
45
- :variant="$props.tagVariant"
46
47
  :color="$props.tagColor"
47
- :editable="$props.editable"
48
48
  @remove="onRemove"
49
49
  />
50
50
  </FSCol>
@@ -10,7 +10,9 @@
10
10
  <FSForm
11
11
  v-model="valid"
12
12
  >
13
- <FSRow>
13
+ <FSRow
14
+ :wrap="false"
15
+ >
14
16
  <FSSelectDateSetting
15
17
  :lastPeriod="$props.lastPeriod"
16
18
  :editable="$props.editable"
@@ -1456,6 +1456,7 @@ export default defineComponent({
1456
1456
  onClickRow,
1457
1457
  isExtraSmall,
1458
1458
  draggableDisabled,
1459
+ elementId,
1459
1460
  toggleSelectAll,
1460
1461
  toggleSelectGroup,
1461
1462
  toggleSelect,
@@ -30,7 +30,7 @@
30
30
  </FSText>
31
31
  <FSText
32
32
  font="text-overline"
33
- variant="light"
33
+ variant="soft"
34
34
  >
35
35
  {{ $props.code }}
36
36
  </FSText>
@@ -29,7 +29,7 @@
29
29
  </FSText>
30
30
  <FSText
31
31
  font="text-overline"
32
- variant="light"
32
+ variant="soft"
33
33
  >
34
34
  {{ $props.code }}
35
35
  </FSText>
@@ -26,7 +26,7 @@
26
26
  </FSText>
27
27
  <FSText
28
28
  font="text-overline"
29
- variant="light"
29
+ variant="soft"
30
30
  >
31
31
  {{ $props.code }}
32
32
  </FSText>
@@ -31,14 +31,14 @@
31
31
  >
32
32
  <FSIcon
33
33
  v-if="roleIcon"
34
- variant="light"
34
+ variant="soft"
35
35
  :color="ColorEnum.Dark"
36
36
  >
37
37
  {{ roleIcon }}
38
38
  </FSIcon>
39
39
  <FSText
40
40
  font="text-overline"
41
- variant="light"
41
+ variant="soft"
42
42
  >
43
43
  {{ roleLabel }}
44
44
  </FSText>