@dative-gpi/foundation-shared-components 0.0.12 → 0.0.13

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 (70) hide show
  1. package/components/FSButton.vue +1 -1
  2. package/components/FSCheckbox.vue +3 -3
  3. package/components/FSClock.vue +45 -30
  4. package/components/FSDivider.vue +46 -7
  5. package/components/FSForm.vue +52 -0
  6. package/components/FSImage.vue +41 -32
  7. package/components/FSLabel.vue +105 -0
  8. package/components/FSPagination.vue +25 -9
  9. package/components/FSPermissions.vue +0 -0
  10. package/components/FSRadio.vue +3 -3
  11. package/components/FSSubmitDialog.vue +1 -1
  12. package/components/FSSwitch.vue +3 -3
  13. package/components/FSText.vue +1 -1
  14. package/components/{FSAutocompleteField.vue → fields/FSAutocompleteField.vue} +18 -17
  15. package/components/fields/FSColorField.vue +194 -0
  16. package/components/{FSDateField.vue → fields/FSDateField.vue} +14 -49
  17. package/components/{FSDateRangeField.vue → fields/FSDateRangeField.vue} +18 -64
  18. package/components/{FSDateTimeField.vue → fields/FSDateTimeField.vue} +16 -51
  19. package/components/{FSDateTimeRangeField.vue → fields/FSDateTimeRangeField.vue} +23 -67
  20. package/components/{FSIconField.vue → fields/FSIconField.vue} +15 -50
  21. package/components/{FSNumberField.vue → fields/FSNumberField.vue} +0 -24
  22. package/components/{FSPasswordField.vue → fields/FSPasswordField.vue} +5 -29
  23. package/components/{FSRichTextField.vue → fields/FSRichTextField.vue} +3 -3
  24. package/components/{FSSearchField.vue → fields/FSSearchField.vue} +1 -1
  25. package/components/{FSSelectField.vue → fields/FSSelectField.vue} +17 -21
  26. package/components/{FSTagField.vue → fields/FSTagField.vue} +15 -50
  27. package/components/{FSTextArea.vue → fields/FSTextArea.vue} +24 -24
  28. package/components/{FSTextField.vue → fields/FSTextField.vue} +18 -18
  29. package/components/fields/FSTimeField.vue +104 -0
  30. package/components/fields/FSTimeSlotField.vue +263 -0
  31. package/components/lists/FSDataTableUI.vue +2 -2
  32. package/components/lists/FSFilterButton.vue +1 -1
  33. package/components/tiles/FSDeviceOrganisationTileUI.vue +4 -9
  34. package/components/tiles/FSGroupTileUI.vue +4 -9
  35. package/composables/index.ts +1 -0
  36. package/composables/useBreakpoints.ts +7 -5
  37. package/composables/useRules.ts +72 -0
  38. package/elements/FSFormElement.ts +17 -0
  39. package/icons/flags/France.vue +9 -0
  40. package/icons/flags/Germany.vue +7 -0
  41. package/icons/flags/GreatBritain.vue +9 -0
  42. package/icons/flags/Italy.vue +9 -0
  43. package/icons/flags/Portugal.vue +59 -0
  44. package/icons/flags/Spain.vue +546 -0
  45. package/icons/flags/UnitedStates.vue +12 -0
  46. package/icons/sets.ts +17 -0
  47. package/models/rules.ts +8 -0
  48. package/package.json +4 -4
  49. package/pages/FSExternalIdentityButton.vue +64 -0
  50. package/pages/FSLanguageSetter.vue +140 -0
  51. package/pages/FSLoginPage.vue +253 -0
  52. package/styles/components/fs_clock.scss +4 -0
  53. package/styles/components/fs_color_field.scss +17 -0
  54. package/styles/components/fs_divider.scss +5 -0
  55. package/styles/components/fs_image.scss +12 -1
  56. package/styles/components/fs_label.scss +86 -0
  57. package/styles/components/fs_pagination.scss +3 -3
  58. package/styles/components/fs_time_field.scss +3 -0
  59. package/styles/components/fs_timeslot_field.scss +75 -0
  60. package/styles/components/index.scss +4 -0
  61. package/styles/globals/text_fonts.scss +18 -0
  62. package/styles/main.scss +3 -1
  63. package/styles/pages/fs_language_setter.scss +55 -0
  64. package/styles/pages/index.scss +1 -0
  65. package/utils/color.ts +7 -0
  66. package/utils/css.ts +2 -1
  67. package/utils/index.ts +3 -1
  68. package/utils/time.ts +29 -0
  69. package/components/FSHeaderButton.vue +0 -17
  70. package/components/lists/FSDataIteratorGroup.vue +0 -7
@@ -41,13 +41,15 @@
41
41
  :items="$props.items"
42
42
  :autoSelectFirst="true"
43
43
  :multiple="$props.multiple"
44
- :error="messages.length > 0"
45
44
  :itemTitle="$props.itemTitle"
46
45
  :itemValue="$props.itemValue"
47
46
  :readonly="!$props.editable"
48
- :clearable="$props.editable"
47
+ :clearable="$props.editable && !!$props.modelValue"
48
+ :rules="$props.rules"
49
+ :validateOn="validateOn"
49
50
  :modelValue="$props.modelValue"
50
51
  @update:modelValue="(value) => $emit('update:modelValue', value)"
52
+ @blur="blurred = true"
51
53
  v-model:search="innerSearch"
52
54
  v-bind="$attrs"
53
55
  >
@@ -71,12 +73,12 @@
71
73
  <script lang="ts">
72
74
  import { computed, defineComponent, PropType, ref, watch } from "vue";
73
75
 
74
- import { useColors, useSlots } from "@dative-gpi/foundation-shared-components/composables";
76
+ import { useColors, useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
75
77
  import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
76
78
 
77
- import FSSpan from "./FSSpan.vue";
78
- import FSCol from "./FSCol.vue";
79
- import FSRow from "./FSRow.vue";
79
+ import FSSpan from "../FSSpan.vue";
80
+ import FSCol from "../FSCol.vue";
81
+ import FSRow from "../FSRow.vue";
80
82
 
81
83
  export default defineComponent({
82
84
  name: "FSAutocompleteField",
@@ -135,6 +137,11 @@ export default defineComponent({
135
137
  required: false,
136
138
  default: () => []
137
139
  },
140
+ messages: {
141
+ type: Array as PropType<string[]>,
142
+ required: false,
143
+ default: null
144
+ },
138
145
  editable: {
139
146
  type: Boolean,
140
147
  required: false,
@@ -143,6 +150,7 @@ export default defineComponent({
143
150
  },
144
151
  emits: ["update:modelValue", "update:search"],
145
152
  setup: (props, { emit }) => {
153
+ const { validateOn, blurred, getMessages } = useRules();
146
154
  const { getColors } = useColors();
147
155
  const { slots } = useSlots();
148
156
 
@@ -174,17 +182,6 @@ export default defineComponent({
174
182
  };
175
183
  });
176
184
 
177
- const messages = computed((): string[] => {
178
- const messages = [];
179
- for (const rule of props.rules) {
180
- const message = rule(props.modelValue ?? "");
181
- if (typeof(message) === "string") {
182
- messages.push(message);
183
- }
184
- }
185
- return messages;
186
- });
187
-
188
185
  const classes = computed((): string[] => {
189
186
  const classNames = ["fs-autocomplete-field"];
190
187
  if (props.multiple) {
@@ -193,12 +190,16 @@ export default defineComponent({
193
190
  return classNames;
194
191
  });
195
192
 
193
+ const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
194
+
196
195
  watch(innerSearch, () => {
197
196
  emit("update:search", innerSearch.value);
198
197
  });
199
198
 
200
199
  return {
200
+ validateOn,
201
201
  messages,
202
+ blurred,
202
203
  slots,
203
204
  style,
204
205
  classes,
@@ -0,0 +1,194 @@
1
+ <template>
2
+ <v-menu
3
+ :closeOnContentClick="false"
4
+ :modelValue="menu && $props.editable"
5
+ @update:modelValue="(value) => menu = value"
6
+ >
7
+ <template #activator="{ props }">
8
+ <FSRow
9
+ height="fill"
10
+ v-bind="props"
11
+ >
12
+ <FSTextField
13
+ class="fs-color-field"
14
+ :hideHeader="$props.hideHeader"
15
+ :required="$props.required"
16
+ :editable="$props.editable"
17
+ :clearable="false"
18
+ :readonly="true"
19
+ :modelValue="innerColor"
20
+ v-bind="$attrs"
21
+ >
22
+ <template #prepend-inner>
23
+ <slot name="prepend-inner">
24
+ <FSIcon
25
+ size="xl"
26
+ :color="innerColor"
27
+ >
28
+ mdi-circle
29
+ </FSIcon>
30
+ </slot>
31
+ </template>
32
+ <template #append>
33
+ <FSButton
34
+ prependIcon="mdi-pencil"
35
+ variant="full"
36
+ :editable="$props.editable"
37
+ />
38
+ </template>
39
+ </FSTextField>
40
+ <FSTextField
41
+ class="fs-color-field-opacity"
42
+ :label="$tr('ui.color-field.opacity', 'Opacity')"
43
+ :hideHeader="$props.hideHeader"
44
+ :required="$props.required"
45
+ :editable="$props.editable"
46
+ :clearable="false"
47
+ :readonly="true"
48
+ :modelValue="(Math.round(getPercentageFromHex(innerOpacity)*100)) + ' %'"
49
+ >
50
+ <template #prepend-inner>
51
+ <slot name="prepend-inner">
52
+ <FSIcon
53
+ icon="mdi-circle"
54
+ size="xl"
55
+ :color="ColorEnum.Dark"
56
+ :editable="$props.editable"
57
+ :style="{ opacity: getPercentageFromHex(innerOpacity) }"
58
+ />
59
+ </slot>
60
+ </template>
61
+ <template #append>
62
+ <FSButton
63
+ prependIcon="mdi-pencil"
64
+ variant="full"
65
+ :editable="$props.editable"
66
+ />
67
+ </template>
68
+ </FSTextField>
69
+ </FSRow>
70
+ </template>
71
+ <FSCard
72
+ :elevation="true"
73
+ :border="false"
74
+ >
75
+ <FSCol
76
+ width="fill"
77
+ >
78
+ <v-color-picker
79
+ class="fs-color-field-picker"
80
+ mode="hexa"
81
+ :elevation="0"
82
+ :modes="['hexa', 'rgba']"
83
+ :modelValue="fullColor"
84
+ @update:modelValue="onSubmit"
85
+ />
86
+ </FSCol>
87
+ </FSCard>
88
+ </v-menu>
89
+ </template>
90
+
91
+ <script lang="ts">
92
+ import { computed, defineComponent, ref } from "vue";
93
+
94
+ import { getPercentageFromHex, getHexFromPercentage } from "@dative-gpi/foundation-shared-components/utils";
95
+ import { useColors } from "@dative-gpi/foundation-shared-components/composables";
96
+ import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
97
+
98
+ import FSTextField from "./FSTextField.vue";
99
+ import FSButton from "../FSButton.vue";
100
+ import FSCard from "../FSCard.vue";
101
+ import FSIcon from "../FSIcon.vue";
102
+ import FSRow from "../FSRow.vue";
103
+ import FSCol from "../FSCol.vue";
104
+
105
+ export default defineComponent({
106
+ name: "FSColorField",
107
+ components: {
108
+ FSTextField,
109
+ FSButton,
110
+ FSCard,
111
+ FSIcon,
112
+ FSCol,
113
+ FSRow
114
+ },
115
+ props: {
116
+ modelValue: {
117
+ type: String,
118
+ required: false,
119
+ default: "#000000"
120
+ },
121
+ opacityValue: {
122
+ type: Number,
123
+ required: false,
124
+ default: 1
125
+ },
126
+ hideHeader: {
127
+ type: Boolean,
128
+ required: false,
129
+ default: false
130
+ },
131
+ required: {
132
+ type: Boolean,
133
+ required: false,
134
+ default: false
135
+ },
136
+ editable: {
137
+ type: Boolean,
138
+ required: false,
139
+ default: true
140
+ }
141
+ },
142
+ emits: ["update:modelValue", "update:opacity"],
143
+ setup(props, { emit }) {
144
+ const innerColor = ref(props.modelValue.toString().substring(0, 7));
145
+ const innerOpacity = ref(getHexFromPercentage(props.opacityValue));
146
+ const fullColor = ref(innerColor.value + innerOpacity.value);
147
+
148
+ const menu = ref(false);
149
+
150
+ const errors = useColors().getColors(ColorEnum.Error);
151
+ const lights = useColors().getColors(ColorEnum.Light);
152
+ const darks = useColors().getColors(ColorEnum.Dark);
153
+
154
+ const style = computed((): {[code: string]: string} & Partial<CSSStyleDeclaration> => {
155
+ if (!props.editable) {
156
+ return {
157
+ "--fs-color-field-cursor" : "default",
158
+ "--fs-color-field-border-color" : lights.base,
159
+ "--fs-color-field-color" : lights.dark,
160
+ "--fs-color-field-active-border-color": lights.base
161
+ };
162
+ }
163
+ return {
164
+ "--fs-color-field-cursor" : "text",
165
+ "--fs-color-field-border-color" : lights.dark,
166
+ "--fs-color-field-color" : darks.base,
167
+ "--fs-color-field-active-border-color": darks.dark,
168
+ "--fs-color-field-error-color" : errors.base,
169
+ "--fs-color-field-error-border-color" : errors.base
170
+ };
171
+ });
172
+
173
+
174
+ const onSubmit = (value: string) => {
175
+ innerColor.value = value.substring(0, 7);
176
+ innerOpacity.value = value.length === 9 ? value.substring(7, 9) : "FF";
177
+ fullColor.value = innerColor.value + innerOpacity.value;
178
+ emit("update:modelValue", innerColor.value);
179
+ emit("update:opacity", getPercentageFromHex(innerOpacity.value));
180
+ };
181
+
182
+ return {
183
+ ColorEnum,
184
+ getPercentageFromHex,
185
+ onSubmit,
186
+ innerColor,
187
+ innerOpacity,
188
+ fullColor,
189
+ style,
190
+ menu
191
+ };
192
+ }
193
+ });
194
+ </script>
@@ -13,45 +13,16 @@
13
13
  :hideHeader="$props.hideHeader"
14
14
  :required="$props.required"
15
15
  :editable="$props.editable"
16
- :error="messages.length > 0"
17
16
  :readonly="true"
17
+ :rules="$props.rules"
18
+ :messages="messages"
19
+ :validateOn="validateOn"
20
+ :validationValue="$props.modelValue"
18
21
  :modelValue="epochToLongDateFormat($props.modelValue)"
19
22
  @click:clear="onClear"
23
+ @blur="blurred = true"
20
24
  v-bind="props"
21
25
  >
22
- <template v-if="!$props.hideHeader" #label>
23
- <slot name="label">
24
- <FSRow :wrap="false">
25
- <FSSpan
26
- v-if="$props.label"
27
- class="fs-date-field-label"
28
- font="text-overline"
29
- :style="style"
30
- >
31
- {{ $props.label }}
32
- </FSSpan>
33
- <FSSpan
34
- v-if="$props.label && $props.required"
35
- class="fs-date-field-label"
36
- style="margin-left: -8px;"
37
- font="text-overline"
38
- :ellipsis="false"
39
- :style="style"
40
- >
41
- *
42
- </FSSpan>
43
- <v-spacer style="min-width: 40px;" />
44
- <FSSpan
45
- v-if="messages.length > 0"
46
- class="fs-date-field-messages"
47
- font="text-overline"
48
- :style="style"
49
- >
50
- {{ messages.join(", ") }}
51
- </FSSpan>
52
- </FSRow>
53
- </slot>
54
- </template>
55
26
  <template #prepend-inner>
56
27
  <slot name="prepend-inner">
57
28
  <FSButton
@@ -91,15 +62,15 @@
91
62
  <script lang="ts">
92
63
  import { computed, defineComponent, PropType, ref } from "vue";
93
64
 
65
+ import { useColors, useRules } from "@dative-gpi/foundation-shared-components/composables";
94
66
  import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
95
67
  import { useTimeZone } from "@dative-gpi/foundation-shared-services/composables";
96
- import { useColors } from "@dative-gpi/foundation-shared-components/composables";
97
68
 
98
69
  import FSTextField from "./FSTextField.vue";
99
- import FSCalendar from "./FSCalendar.vue";
100
- import FSButton from "./FSButton.vue";
101
- import FSCard from "./FSCard.vue";
102
- import FSCol from "./FSCol.vue";
70
+ import FSCalendar from "../FSCalendar.vue";
71
+ import FSButton from "../FSButton.vue";
72
+ import FSCard from "../FSCard.vue";
73
+ import FSCol from "../FSCol.vue";
103
74
 
104
75
  export default defineComponent({
105
76
  name: "FSDateField",
@@ -154,6 +125,7 @@ export default defineComponent({
154
125
  },
155
126
  emits: ["update:modelValue"],
156
127
  setup(props, { emit }) {
128
+ const {validateOn, blurred, getMessages} = useRules();
157
129
  const { epochToLongDateFormat } = useTimeZone();
158
130
  const { getColors } = useColors();
159
131
 
@@ -176,16 +148,7 @@ export default defineComponent({
176
148
  };
177
149
  });
178
150
 
179
- const messages = computed((): string[] => {
180
- const messages = [];
181
- for (const rule of props.rules) {
182
- const message = rule(props.modelValue ?? null);
183
- if (typeof(message) === "string") {
184
- messages.push(message);
185
- }
186
- }
187
- return messages;
188
- });
151
+ const messages = computed((): string[] => getMessages(props.modelValue, props.rules));
189
152
 
190
153
  const onClear = (): void => {
191
154
  emit("update:modelValue", null);
@@ -200,7 +163,9 @@ export default defineComponent({
200
163
  return {
201
164
  ColorEnum,
202
165
  innerDate,
166
+ validateOn,
203
167
  messages,
168
+ blurred,
204
169
  style,
205
170
  menu,
206
171
  onClear,
@@ -7,45 +7,16 @@
7
7
  :hideHeader="$props.hideHeader"
8
8
  :required="$props.required"
9
9
  :editable="$props.editable"
10
- :error="messages.length > 0"
11
10
  :readonly="true"
12
- :modelValue="placeholder"
11
+ :rules="$props.rules"
12
+ :messages="messages"
13
+ :validateOn="validateOn"
14
+ :validationValue="$props.modelValue"
15
+ :modelValue="toShortDateFormat"
13
16
  @click="onClick"
14
17
  @click:clear="onClear"
18
+ @blur="blurred = true"
15
19
  >
16
- <template v-if="!$props.hideHeader" #label>
17
- <slot name="label">
18
- <FSRow :wrap="false">
19
- <FSSpan
20
- v-if="$props.label"
21
- class="fs-date-field-label"
22
- font="text-overline"
23
- :style="style"
24
- >
25
- {{ $props.label }}
26
- </FSSpan>
27
- <FSSpan
28
- v-if="$props.label && $props.required"
29
- class="fs-date-field-label"
30
- style="margin-left: -8px;"
31
- font="text-overline"
32
- :ellipsis="false"
33
- :style="style"
34
- >
35
- *
36
- </FSSpan>
37
- <v-spacer style="min-width: 40px;" />
38
- <FSSpan
39
- v-if="messages.length > 0"
40
- class="fs-date-field-messages"
41
- font="text-overline"
42
- :style="style"
43
- >
44
- {{ messages.join(", ") }}
45
- </FSSpan>
46
- </FSRow>
47
- </slot>
48
- </template>
49
20
  <template #prepend-inner>
50
21
  <slot name="prepend-inner">
51
22
  <FSButton
@@ -78,16 +49,16 @@
78
49
  <script lang="ts">
79
50
  import { computed, defineComponent, PropType, ref } from "vue";
80
51
 
52
+ import { useColors, useRules } from "@dative-gpi/foundation-shared-components/composables";
81
53
  import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
82
54
  import { useTimeZone } from "@dative-gpi/foundation-shared-services/composables";
83
- import { useColors } from "@dative-gpi/foundation-shared-components/composables";
84
55
 
85
- import FSSubmitDialog from "./FSSubmitDialog.vue";
86
- import FSCalendarTwin from "./FSCalendarTwin.vue";
56
+ import FSSubmitDialog from "../FSSubmitDialog.vue";
57
+ import FSCalendarTwin from "../FSCalendarTwin.vue";
87
58
  import FSTextField from "./FSTextField.vue";
88
- import FSButton from "./FSButton.vue";
89
- import FSCard from "./FSCard.vue";
90
- import FSCol from "./FSCol.vue";
59
+ import FSButton from "../FSButton.vue";
60
+ import FSCard from "../FSCard.vue";
61
+ import FSCol from "../FSCol.vue";
91
62
 
92
63
  export default defineComponent({
93
64
  name: "FSDateRangeField",
@@ -143,6 +114,7 @@ export default defineComponent({
143
114
  },
144
115
  emits: ["update:modelValue"],
145
116
  setup(props, { emit }) {
117
+ const { validateOn, blurred, getMessages } = useRules();
146
118
  const { epochToShortDateFormat } = useTimeZone();
147
119
  const { getColors } = useColors();
148
120
 
@@ -165,34 +137,14 @@ export default defineComponent({
165
137
  };
166
138
  });
167
139
 
168
- const placeholder = computed((): string => {
140
+ const toShortDateFormat = computed((): string => {
169
141
  if (!props.modelValue || !Array.isArray(props.modelValue) || !props.modelValue.length) {
170
142
  return "";
171
143
  }
172
144
  return props.modelValue.map((epoch) => epochToShortDateFormat(epoch)).join(" - ");
173
145
  });
174
146
 
175
- const messages = computed((): string[] => {
176
- const messages = [];
177
- for (const rule of props.rules) {
178
- if (props.modelValue && Array.isArray(props.modelValue)) {
179
- for (const value of props.modelValue) {
180
- const message = rule(value);
181
- if (typeof(message) === "string") {
182
- messages.push(message);
183
- break;
184
- }
185
- }
186
- }
187
- else {
188
- const message = rule(null);
189
- if (typeof(message) === "string") {
190
- messages.push(message);
191
- }
192
- }
193
- }
194
- return messages;
195
- });
147
+ const messages = computed((): string[] => getMessages(props.modelValue, props.rules, true));
196
148
 
197
149
  const onClick = (): void => {
198
150
  if (props.editable) {
@@ -212,10 +164,12 @@ export default defineComponent({
212
164
 
213
165
  return {
214
166
  ColorEnum,
167
+ validateOn,
215
168
  messages,
169
+ blurred,
216
170
  style,
217
171
  dialog,
218
- placeholder,
172
+ toShortDateFormat,
219
173
  innerDateRange,
220
174
  onClick,
221
175
  onClear,
@@ -13,45 +13,16 @@
13
13
  :hideHeader="$props.hideHeader"
14
14
  :required="$props.required"
15
15
  :editable="$props.editable"
16
- :error="messages.length > 0"
17
16
  :readonly="true"
17
+ :rules="$props.rules"
18
+ :messages="messages"
19
+ :validateOn="validateOn"
20
+ :validationValue="$props.modelValue"
18
21
  :modelValue="epochToLongTimeFormat($props.modelValue)"
19
22
  @click:clear="onClear"
23
+ @blur="blurred = true"
20
24
  v-bind="props"
21
25
  >
22
- <template v-if="!$props.hideHeader" #label>
23
- <slot name="label">
24
- <FSRow :wrap="false">
25
- <FSSpan
26
- v-if="$props.label"
27
- class="fs-date-field-label"
28
- font="text-overline"
29
- :style="style"
30
- >
31
- {{ $props.label }}
32
- </FSSpan>
33
- <FSSpan
34
- v-if="$props.label && $props.required"
35
- class="fs-date-field-label"
36
- style="margin-left: -8px;"
37
- font="text-overline"
38
- :ellipsis="false"
39
- :style="style"
40
- >
41
- *
42
- </FSSpan>
43
- <v-spacer style="min-width: 40px;" />
44
- <FSSpan
45
- v-if="messages.length > 0"
46
- class="fs-date-field-messages"
47
- font="text-overline"
48
- :style="style"
49
- >
50
- {{ messages.join(", ") }}
51
- </FSSpan>
52
- </FSRow>
53
- </slot>
54
- </template>
55
26
  <template #prepend-inner>
56
27
  <slot name="prepend-inner">
57
28
  <FSButton
@@ -115,17 +86,17 @@
115
86
  <script lang="ts">
116
87
  import { computed, defineComponent, PropType, ref, watch } from "vue";
117
88
 
89
+ import { useColors, useRules } from "@dative-gpi/foundation-shared-components/composables";
118
90
  import { ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
119
91
  import { useTimeZone } from "@dative-gpi/foundation-shared-services/composables";
120
- import { useColors } from "@dative-gpi/foundation-shared-components/composables";
121
92
 
122
93
  import FSTextField from "./FSTextField.vue";
123
- import FSCalendar from "./FSCalendar.vue";
124
- import FSWindow from "./FSWindow.vue";
125
- import FSButton from "./FSButton.vue";
126
- import FSClock from "./FSClock.vue";
127
- import FSCard from "./FSCard.vue";
128
- import FSCol from "./FSCol.vue";
94
+ import FSCalendar from "../FSCalendar.vue";
95
+ import FSWindow from "../FSWindow.vue";
96
+ import FSButton from "../FSButton.vue";
97
+ import FSClock from "../FSClock.vue";
98
+ import FSCard from "../FSCard.vue";
99
+ import FSCol from "../FSCol.vue";
129
100
 
130
101
  export default defineComponent({
131
102
  name: "FSDateTimeField",
@@ -183,6 +154,7 @@ export default defineComponent({
183
154
  emits: ["update:modelValue"],
184
155
  setup(props, { emit }) {
185
156
  const { getUserOffsetMillis, epochToLongTimeFormat } = useTimeZone();
157
+ const { validateOn, blurred, getMessages } = useRules();
186
158
  const { getColors } = useColors();
187
159
 
188
160
  const errors = getColors(ColorEnum.Error);
@@ -213,16 +185,7 @@ export default defineComponent({
213
185
  };
214
186
  });
215
187
 
216
- const messages = computed((): string[] => {
217
- const messages = [];
218
- for (const rule of props.rules) {
219
- const message = rule(props.modelValue ?? null);
220
- if (typeof(message) === "string") {
221
- messages.push(message);
222
- }
223
- }
224
- return messages;
225
- });
188
+ const messages = computed((): string[] => getMessages(props.modelValue, props.rules));
226
189
 
227
190
  const onClear = (): void => {
228
191
  emit("update:modelValue", null);
@@ -245,7 +208,9 @@ export default defineComponent({
245
208
  ColorEnum,
246
209
  innerDate,
247
210
  innerTime,
211
+ validateOn,
248
212
  messages,
213
+ blurred,
249
214
  style,
250
215
  menu,
251
216
  tabs,