@dative-gpi/foundation-shared-components 1.0.102 → 1.0.103-fix

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.
@@ -165,8 +165,6 @@ export default defineComponent({
165
165
  const innerRightMonth = ref(new Date().getMonth());
166
166
  const innerRightYear = ref(new Date().getFullYear());
167
167
 
168
- const toggle = ref((props.modelValue?.length ?? 0) % 2);
169
-
170
168
  const colors = computed(() => getColors(props.color));
171
169
  const backgrounds = getColors(ColorEnum.Background);
172
170
  const darks = getColors(ColorEnum.Dark);
@@ -323,43 +321,42 @@ export default defineComponent({
323
321
 
324
322
  const onClickLeft = (value: unknown): void => {
325
323
  const dates = value as Date[];
326
- const clicked = pickerToEpoch(dates[dates.length - 1]);
327
- if (!props.modelValue || !props.modelValue.length) {
328
- emit("update:modelValue", [clicked, clicked]);
324
+
325
+ // Click on the same date while only one date is selected on the left calendar
326
+ if (dates.length === 0) {
327
+ if (props.modelValue && props.modelValue.length > 0) {
328
+ emit("update:modelValue", [props.modelValue[0], props.modelValue[0]]);
329
+ }
330
+ return;
329
331
  }
330
- else if (props.modelValue.length === 1) {
332
+
333
+ const clicked = pickerToEpoch(dates[dates.length - 1]);
334
+ if (props.modelValue && props.modelValue[0] === props.modelValue[1]) {
331
335
  emit("update:modelValue", [props.modelValue[0], clicked].sort());
332
336
  }
333
337
  else {
334
- if (innerLeftValue.value.length === 0) {
335
- emit("update:modelValue", [clicked, props.modelValue[1]]);
336
- }
337
- else {
338
- emit("update:modelValue", [clicked, props.modelValue[toggle.value]].sort());
339
- toggle.value = (++toggle.value) % 2;
340
- }
338
+ emit("update:modelValue", [clicked, clicked]);
341
339
  }
342
340
  };
343
341
 
344
342
  const onClickRight = (value: unknown): void => {
345
343
  const dates = value as Date[];
346
- const clicked = pickerToEpoch(dates[dates.length - 1]);
347
- if (!props.modelValue || !props.modelValue.length) {
348
- emit("update:modelValue", [clicked, clicked]);
344
+
345
+ // Click on the same date while only one date is selected on the right calendar
346
+ if (dates.length === 0) {
347
+ if (props.modelValue && props.modelValue.length > 0) {
348
+ emit("update:modelValue", [props.modelValue[props.modelValue.length - 1], props.modelValue[props.modelValue.length - 1]]);
349
+ }
350
+ return;
349
351
  }
350
- else if (props.modelValue.length === 1) {
352
+
353
+ const clicked = pickerToEpoch(dates[dates.length - 1]);
354
+ if (props.modelValue && props.modelValue[0] === props.modelValue[1]) {
351
355
  emit("update:modelValue", [props.modelValue[0], clicked].sort());
352
356
  }
353
357
  else {
354
- if (innerRightValue.value.length === 0) {
355
- emit("update:modelValue", [props.modelValue[0], clicked]);
356
- }
357
- else {
358
- emit("update:modelValue", [clicked, props.modelValue[toggle.value]].sort());
359
- toggle.value = (++toggle.value) % 2;
360
- }
358
+ emit("update:modelValue", [clicked, clicked]);
361
359
  }
362
- toggle.value = (++toggle.value) % 2;
363
360
  };
364
361
 
365
362
  const allowedDates = (value: unknown): boolean => {
@@ -11,12 +11,14 @@
11
11
  #body
12
12
  >
13
13
  <FSDialogFormBody
14
+ ref="bodyRef"
14
15
  v-bind="$attrs"
15
16
  :subtitle="$props.subtitle"
16
17
  :validation="$props.validation"
17
18
  @click:cancelButton="$emit('update:modelValue', false)"
18
19
  @click:submitButton="$emit('click:submitButton')"
19
20
  @click:validateButton="onValidate"
21
+ @update:validForm="validForm = $event"
20
22
  >
21
23
  <template
22
24
  v-for="(_, name) in $slots"
@@ -33,8 +35,8 @@
33
35
  </template>
34
36
 
35
37
  <script lang="ts">
36
- import type { PropType} from "vue";
37
- import { defineComponent } from "vue";
38
+ import type { PropType } from "vue";
39
+ import { defineComponent, ref } from "vue";
38
40
 
39
41
  import FSDialogFormBody from "./FSDialogFormBody.vue";
40
42
  import FSDialog from "./FSDialog.vue";
@@ -74,6 +76,8 @@ export default defineComponent({
74
76
  },
75
77
  emits: ["update:modelValue", "click:validateButton", "click:submitButton"],
76
78
  setup(props, { emit }) {
79
+ const bodyRef = ref<typeof FSDialogFormBody | null>(null);
80
+ const validForm = ref(false);
77
81
 
78
82
  const onClose = () => {
79
83
  if (props.validation) {
@@ -87,8 +91,24 @@ export default defineComponent({
87
91
  emit("update:modelValue", false);
88
92
  };
89
93
 
94
+ const resetFormValidation = () => {
95
+ if (bodyRef.value) {
96
+ bodyRef.value.resetFormValidation();
97
+ }
98
+ };
99
+
100
+ const validateForm = async () => {
101
+ if (bodyRef.value) {
102
+ await bodyRef.value.validateForm();
103
+ }
104
+ };
105
+
90
106
  return {
107
+ resetFormValidation,
108
+ validateForm,
91
109
  onValidate,
110
+ validForm,
111
+ bodyRef,
92
112
  onClose
93
113
  };
94
114
  }
@@ -6,7 +6,7 @@
6
6
  ref="formRef"
7
7
  :variant="$props.variant"
8
8
  @submit="onSubmit"
9
- v-model="valid"
9
+ v-model="validForm"
10
10
  >
11
11
  <FSCol
12
12
  gap="24px"
@@ -89,7 +89,7 @@
89
89
  </template>
90
90
 
91
91
  <script lang="ts">
92
- import { computed, defineComponent, type PropType, ref } from "vue";
92
+ import { computed, defineComponent, type PropType, ref, watch } from "vue";
93
93
 
94
94
  import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
95
95
  import { type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
@@ -114,11 +114,6 @@ export default defineComponent({
114
114
  required: false,
115
115
  default: "submit"
116
116
  },
117
- modelValue: {
118
- type: Boolean,
119
- required: false,
120
- default: false
121
- },
122
117
  subtitle: {
123
118
  type: String as PropType<string | null>,
124
119
  required: false,
@@ -225,13 +220,13 @@ export default defineComponent({
225
220
  default: true
226
221
  }
227
222
  },
228
- emits: ["click:cancelButton", "click:submitButton", "click:validateButton"],
223
+ emits: ["click:cancelButton", "click:submitButton", "click:validateButton", "update:validForm"],
229
224
  setup(props, { emit }) {
230
225
  const { isMobileSized } = useBreakpoints();
231
226
  const { $tr } = useTranslationsProvider();
232
227
 
233
- const formRef = ref<HTMLElement | null>(null);
234
- const valid = ref(false);
228
+ const formRef = ref<typeof FSForm | null>(null);
229
+ const validForm = ref(false);
235
230
 
236
231
  const maxHeight = computed(() => {
237
232
  const other = 24 + 24 // Paddings
@@ -253,8 +248,20 @@ export default defineComponent({
253
248
  return props.validateButtonLabel ?? $tr("ui.button.validate", "Done");
254
249
  });
255
250
 
251
+ const resetFormValidation = () => {
252
+ if (formRef.value) {
253
+ formRef.value.resetValidation();
254
+ }
255
+ };
256
+
257
+ const validateForm = async () => {
258
+ if (formRef.value) {
259
+ await formRef.value.validate();
260
+ }
261
+ };
262
+
256
263
  const onSubmit = () => {
257
- if (valid.value) {
264
+ if (validForm.value) {
258
265
  emit("click:submitButton");
259
266
  }
260
267
  };
@@ -262,17 +269,23 @@ export default defineComponent({
262
269
  const onValidate = () => {
263
270
  emit("click:validateButton");
264
271
  };
272
+
273
+ watch(() => validForm.value, () => {
274
+ emit("update:validForm", validForm.value);
275
+ }, { immediate: true });
265
276
 
266
277
  return {
278
+ resetFormValidation,
267
279
  validateLabel,
280
+ validateForm,
268
281
  cancelLabel,
269
282
  submitLabel,
283
+ onValidate,
270
284
  ColorEnum,
271
285
  maxHeight,
272
- formRef,
273
- valid,
274
- onValidate,
275
- onSubmit
286
+ validForm,
287
+ onSubmit,
288
+ formRef
276
289
  };
277
290
  }
278
291
  });
@@ -85,8 +85,8 @@ export default defineComponent({
85
85
  const elementId = `id${uuidv4()}`;
86
86
 
87
87
  const style = computed((): StyleValue => ({
88
- "--fs-fade-out-height" : props.height ? sizeToVar(props.height) : undefined,
89
- "--fs-fade-out-max-height" : props.maxHeight ? sizeToVar(props.maxHeight) : undefined,
88
+ "--fs-fade-out-height" : props.height ? sizeToVar(props.height) : "initial",
89
+ "--fs-fade-out-max-height" : props.maxHeight ? sizeToVar(props.maxHeight) : "initial",
90
90
  "--fs-fade-out-width" : sizeToVar(props.width),
91
91
  "--fs-fade-out-padding" : sizeToVar(props.padding),
92
92
  "--fs-fade-out-width-offset" : props.scrollOutside ? '12px' : '0px',
@@ -214,7 +214,7 @@ export default defineComponent({
214
214
  }
215
215
  default: {
216
216
  innerTimeLeft.value = Math.floor((props.modelValue[0] + getUserOffset(props.modelValue[0])) % (24 * 60 * 60 * 1000));
217
- innerTimeRight.value = Math.floor((props.modelValue[1] + getUserOffset(props.modelValue[0])) % (24 * 60 * 60 * 1000));
217
+ innerTimeRight.value = Math.floor((props.modelValue[1] + getUserOffset(props.modelValue[1])) % (24 * 60 * 60 * 1000));
218
218
  innerDateRange.value = [props.modelValue[0] - innerTimeLeft.value, props.modelValue[1] - innerTimeRight.value];
219
219
  break;
220
220
  }
@@ -1,6 +1,5 @@
1
1
  <template>
2
2
  <FSCol
3
- v-bind="$props"
4
3
  gap="12px"
5
4
  >
6
5
  <FSSearchField
@@ -15,39 +14,102 @@
15
14
  :maskHeight="0"
16
15
  >
17
16
  <FSCol>
18
- <FSSimpleListItem
19
- loaderWidth="100%"
20
- tileWidth="100%"
21
- :filteredItems="filteredItems"
22
- @click:edit="$emit('click:edit', $event)"
23
- @click:remove="$emit('click:remove', $event)"
24
- v-bind="$props"
25
- />
17
+ <template
18
+ v-if="$props.loading"
19
+ >
20
+ <FSLoader
21
+ v-for="i in 4"
22
+ :key="i"
23
+ width="100%"
24
+ height="50px"
25
+ />
26
+ </template>
27
+ <template
28
+ v-else
29
+ >
30
+ <FSSimpleListItem
31
+ v-for="item in filteredItems"
32
+ :key="item.id"
33
+ :id="item.id"
34
+ :label="item[$props.itemLabel ?? 'label']"
35
+ :icon="item.icon"
36
+ :imageId="item.imageId"
37
+ :showEdit="$props.showEdit"
38
+ :showRemove="$props.showRemove"
39
+ :showDraggable="$props.showDraggable"
40
+ :tileProps="$props.tileProps ? $props.tileProps(item) : undefined"
41
+ width="100%"
42
+ @click:edit="$emit('click:edit', $event)"
43
+ @click:remove="$emit('click:remove', $event)"
44
+ />
45
+ </template>
26
46
  </FSCol>
27
47
  </FSFadeOut>
28
48
  <FSRow
29
49
  v-else-if="$props.direction == 'row'"
30
50
  >
31
- <FSSimpleListItem
32
- loaderWidth="220px"
33
- tileWidth="fit-content"
34
- :filteredItems="filteredItems"
35
- @click:edit="$emit('click:edit', $event)"
36
- @click:remove="$emit('click:remove', $event)"
37
- v-bind="$props"
38
- />
51
+ <template
52
+ v-if="$props.loading"
53
+ >
54
+ <FSLoader
55
+ v-for="i in 4"
56
+ :key="i"
57
+ width="100%"
58
+ height="50px"
59
+ />
60
+ </template>
61
+ <template
62
+ v-else
63
+ >
64
+ <FSSimpleListItem
65
+ v-for="item in filteredItems"
66
+ :key="item.id"
67
+ :id="item.id"
68
+ :label="item[$props.itemLabel ?? 'label']"
69
+ :icon="item.icon"
70
+ :imageId="item.imageId"
71
+ :showEdit="$props.showEdit"
72
+ :showRemove="$props.showRemove"
73
+ :showDraggable="$props.showDraggable"
74
+ :tileProps="$props.tileProps ? $props.tileProps(item) : undefined"
75
+ width="fit-content"
76
+ @click:edit="$emit('click:edit', $event)"
77
+ @click:remove="$emit('click:remove', $event)"
78
+ />
79
+ </template>
39
80
  </FSRow>
40
81
  <FSSlideGroup
41
82
  v-else
42
83
  >
43
- <FSSimpleListItem
44
- loaderWidth="220px"
45
- tileWidth="fit-content"
46
- :filteredItems="filteredItems"
47
- @click:edit="$emit('click:edit', $event)"
48
- @click:remove="$emit('click:remove', $event)"
49
- v-bind="$props"
50
- />
84
+ <template
85
+ v-if="$props.loading"
86
+ >
87
+ <FSLoader
88
+ v-for="i in 4"
89
+ :key="i"
90
+ width="100%"
91
+ height="50px"
92
+ />
93
+ </template>
94
+ <template
95
+ v-else
96
+ >
97
+ <FSSimpleListItem
98
+ v-for="item in filteredItems"
99
+ :key="item.id"
100
+ :id="item.id"
101
+ :label="item[$props.itemLabel ?? 'label']"
102
+ :icon="item.icon"
103
+ :imageId="item.imageId"
104
+ :showEdit="$props.showEdit"
105
+ :showRemove="$props.showRemove"
106
+ :showDraggable="$props.showDraggable"
107
+ :tileProps="$props.tileProps ? $props.tileProps(item) : undefined"
108
+ width="fit-content"
109
+ @click:edit="$emit('click:edit', $event)"
110
+ @click:remove="$emit('click:remove', $event)"
111
+ />
112
+ </template>
51
113
  </FSSlideGroup>
52
114
  </FSCol>
53
115
  </template>
@@ -62,6 +124,7 @@ import { filterItems } from "../../utils";
62
124
 
63
125
  import FSRow from "../FSRow.vue";
64
126
  import FSCol from "../FSCol.vue";
127
+ import FSLoader from '../FSLoader.vue';
65
128
  import FSFadeOut from "../FSFadeOut.vue";
66
129
  import FSSlideGroup from "../FSSlideGroup.vue"
67
130
  import FSSearchField from "../fields/FSSearchField.vue";
@@ -73,6 +136,7 @@ export default defineComponent({
73
136
  FSRow,
74
137
  FSCol,
75
138
  FSFadeOut,
139
+ FSLoader,
76
140
  FSSlideGroup,
77
141
  FSSearchField,
78
142
  FSSimpleListItem
@@ -84,8 +148,7 @@ export default defineComponent({
84
148
  },
85
149
  tileProps: {
86
150
  type: Function as PropType<(item: any) => Record<string, any>>,
87
- required: false,
88
- default: () => () => ({})
151
+ required: false
89
152
  },
90
153
  showEdit: {
91
154
  type: Boolean,
@@ -128,7 +191,7 @@ export default defineComponent({
128
191
  default: "column"
129
192
  },
130
193
  itemLabel: {
131
- type: String,
194
+ type: String as PropType<string>,
132
195
  required: false,
133
196
  default: "label"
134
197
  },
@@ -1,78 +1,62 @@
1
1
  <template>
2
- <template
3
- v-if="$props.loading"
2
+ <FSTile
3
+ v-bind="$props.tileProps"
4
+ :width="$props.width"
5
+ height="fit-content"
6
+ :editable="false"
4
7
  >
5
- <FSLoader
6
- v-for="i in 4"
7
- :key="i"
8
- :width="loaderWidth"
9
- height="50px"
10
- />
11
- </template>
12
- <template
13
- v-else
14
- >
15
- <FSTile
16
- v-for="item in filteredItems"
17
- :key="item.id"
18
- v-bind="tileProps(item)"
19
- :width="tileWidth"
20
- height="fit-content"
21
- :editable="false"
8
+ <slot
9
+ name="item"
10
+ :item="{ label, icon, imageId, id }"
22
11
  >
23
- <slot
24
- name="item"
25
- :item="item"
12
+ <FSRow
13
+ align="center-left"
14
+ height="24px"
15
+ :wrap="false"
26
16
  >
17
+ <FSButtonDragIcon
18
+ v-if="showDraggable"
19
+ />
20
+ <slot
21
+ name="itemContent"
22
+ :item="{ label, icon, imageId, id }"
23
+ >
24
+ <!-- TODO : add draggable option -->
25
+ <FSImage
26
+ v-if="$props.imageId"
27
+ width="24px"
28
+ height="24px"
29
+ :imageId="$props.imageId"
30
+ :thumbnail="true"
31
+ />
32
+ <FSIcon
33
+ size="24px"
34
+ v-else-if="$props.icon"
35
+ :icon="$props.icon"
36
+ />
37
+ <FSSpan
38
+ font="text-overline"
39
+ >
40
+ {{ $props.label }}
41
+ </FSSpan>
42
+ </slot>
27
43
  <FSRow
28
- align="center-left"
29
- height="24px"
44
+ v-if="showEdit || showRemove"
45
+ align="center-right"
30
46
  :wrap="false"
31
47
  >
32
- <FSButtonDragIcon
33
- v-if="showDraggable"
48
+ <FSButtonEditIcon
49
+ v-if="showEdit"
50
+ @click="$emit('click:edit', $props.id)"
51
+ />
52
+ <FSButtonRemoveIcon
53
+ v-if="showRemove"
54
+ @click="$emit('click:remove', $props.id)"
34
55
  />
35
- <slot
36
- name="itemContent"
37
- :item="item"
38
- >
39
- <!-- TODO : add draggable option -->
40
- <FSImage
41
- v-if="item.imageId"
42
- width="24px"
43
- height="24px"
44
- :imageId="item.imageId"
45
- :thumbnail="true"
46
- />
47
- <FSIcon
48
- size="24px"
49
- v-else-if="item.icon"
50
- :icon="item.icon"
51
- />
52
- <FSSpan
53
- font="text-overline"
54
- >
55
- {{ item[$props.itemLabel || 'label'] }}
56
- </FSSpan>
57
- </slot>
58
- <FSRow
59
- v-if="showEdit || showRemove"
60
- align="center-right"
61
- :wrap="false"
62
- >
63
- <FSButtonEditIcon
64
- v-if="showEdit"
65
- @click="$emit('click:edit', item.id)"
66
- />
67
- <FSButtonRemoveIcon
68
- v-if="showRemove"
69
- @click="$emit('click:remove', item.id)"
70
- />
71
- </FSRow>
72
56
  </FSRow>
73
- </slot>
74
- </FSTile>
75
- </template>
57
+ </FSRow>
58
+ </slot>
59
+ </FSTile>
76
60
  </template>
77
61
 
78
62
 
@@ -83,7 +67,6 @@ import FSRow from "../FSRow.vue";
83
67
  import FSIcon from "../FSIcon.vue";
84
68
  import FSSpan from "../FSSpan.vue";
85
69
  import FSImage from "../FSImage.vue";
86
- import FSLoader from "../FSLoader.vue";
87
70
  import FSTile from "../tiles/FSTile.vue";
88
71
  import FSButtonEditIcon from "../buttons/FSButtonEditIcon.vue";
89
72
  import FSButtonDragIcon from "../buttons/FSButtonDragIcon.vue";
@@ -97,20 +80,15 @@ export default defineComponent({
97
80
  FSIcon,
98
81
  FSSpan,
99
82
  FSImage,
100
- FSLoader,
101
83
  FSButtonEditIcon,
102
84
  FSButtonDragIcon,
103
85
  FSButtonRemoveIcon,
104
86
  },
105
87
  props: {
106
- filteredItems: {
107
- type: Array as PropType<{id: string, label?: string, icon?: string, imageId?: string | null, [index: string]: any}[]>,
108
- required: true
109
- },
110
88
  tileProps: {
111
- type: Function as PropType<(item: any) => Record<string, any>>,
89
+ type: Object as PropType<Record<string, any>>,
112
90
  required: false,
113
- default: () => () => ({})
91
+ default: () => ({})
114
92
  },
115
93
  showEdit: {
116
94
  type: Boolean,
@@ -127,35 +105,26 @@ export default defineComponent({
127
105
  required: false,
128
106
  default: false
129
107
  },
130
- search: {
131
- type: String,
132
- required: false,
133
- default: ""
134
- },
135
- noFilter: {
136
- type: Boolean,
108
+ width:{
109
+ type: [Array, String, Number] as PropType<string[] | number[] | string | number | null | undefined>,
137
110
  required: false,
138
- default: false
111
+ default: undefined
139
112
  },
140
- itemLabel: {
113
+ id: {
141
114
  type: String,
142
- required: false,
143
- default: "label"
115
+ required: true
144
116
  },
145
- loaderWidth:{
146
- type: [Array, String, Number] as PropType<string[] | number[] | string | number | null | undefined>,
147
- required: false,
148
- default: undefined
117
+ label: {
118
+ type: String,
119
+ required: true
149
120
  },
150
- tileWidth:{
151
- type: [Array, String, Number] as PropType<string[] | number[] | string | number | null | undefined>,
152
- required: false,
153
- default: undefined
121
+ icon: {
122
+ type: String,
123
+ required: false
154
124
  },
155
- loading: {
156
- type: Boolean,
157
- required: false,
158
- default: false
125
+ imageId: {
126
+ type: String as PropType<string | null>,
127
+ required: false
159
128
  }
160
129
  },
161
130
  emits: ["click:edit", "click:remove"]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dative-gpi/foundation-shared-components",
3
3
  "sideEffects": false,
4
- "version": "1.0.102",
4
+ "version": "1.0.103-fix",
5
5
  "description": "",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -10,8 +10,8 @@
10
10
  "author": "",
11
11
  "license": "ISC",
12
12
  "dependencies": {
13
- "@dative-gpi/foundation-shared-domain": "1.0.102",
14
- "@dative-gpi/foundation-shared-services": "1.0.102"
13
+ "@dative-gpi/foundation-shared-domain": "1.0.103-fix",
14
+ "@dative-gpi/foundation-shared-services": "1.0.103-fix"
15
15
  },
16
16
  "peerDependencies": {
17
17
  "@dative-gpi/bones-ui": "^1.0.0",
@@ -35,5 +35,5 @@
35
35
  "sass": "1.71.1",
36
36
  "sass-loader": "13.3.2"
37
37
  },
38
- "gitHead": "fd73b73f8107a44b608c04b092a41a70af78f8fa"
38
+ "gitHead": "8b23f1e0e6577413595129fec1354285bf7e6d20"
39
39
  }