@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.
- package/components/FSButton.vue +1 -1
- package/components/FSCheckbox.vue +3 -3
- package/components/FSClock.vue +45 -30
- package/components/FSDivider.vue +46 -7
- package/components/FSForm.vue +52 -0
- package/components/FSImage.vue +41 -32
- package/components/FSLabel.vue +105 -0
- package/components/FSPagination.vue +25 -9
- package/components/FSPermissions.vue +0 -0
- package/components/FSRadio.vue +3 -3
- package/components/FSSubmitDialog.vue +1 -1
- package/components/FSSwitch.vue +3 -3
- package/components/FSText.vue +1 -1
- package/components/{FSAutocompleteField.vue → fields/FSAutocompleteField.vue} +18 -17
- package/components/fields/FSColorField.vue +194 -0
- package/components/{FSDateField.vue → fields/FSDateField.vue} +14 -49
- package/components/{FSDateRangeField.vue → fields/FSDateRangeField.vue} +18 -64
- package/components/{FSDateTimeField.vue → fields/FSDateTimeField.vue} +16 -51
- package/components/{FSDateTimeRangeField.vue → fields/FSDateTimeRangeField.vue} +23 -67
- package/components/{FSIconField.vue → fields/FSIconField.vue} +15 -50
- package/components/{FSNumberField.vue → fields/FSNumberField.vue} +0 -24
- package/components/{FSPasswordField.vue → fields/FSPasswordField.vue} +5 -29
- package/components/{FSRichTextField.vue → fields/FSRichTextField.vue} +3 -3
- package/components/{FSSearchField.vue → fields/FSSearchField.vue} +1 -1
- package/components/{FSSelectField.vue → fields/FSSelectField.vue} +17 -21
- package/components/{FSTagField.vue → fields/FSTagField.vue} +15 -50
- package/components/{FSTextArea.vue → fields/FSTextArea.vue} +24 -24
- package/components/{FSTextField.vue → fields/FSTextField.vue} +18 -18
- package/components/fields/FSTimeField.vue +104 -0
- package/components/fields/FSTimeSlotField.vue +263 -0
- package/components/lists/FSDataTableUI.vue +2 -2
- package/components/lists/FSFilterButton.vue +1 -1
- package/components/tiles/FSDeviceOrganisationTileUI.vue +4 -9
- package/components/tiles/FSGroupTileUI.vue +4 -9
- package/composables/index.ts +1 -0
- package/composables/useBreakpoints.ts +7 -5
- package/composables/useRules.ts +72 -0
- package/elements/FSFormElement.ts +17 -0
- package/icons/flags/France.vue +9 -0
- package/icons/flags/Germany.vue +7 -0
- package/icons/flags/GreatBritain.vue +9 -0
- package/icons/flags/Italy.vue +9 -0
- package/icons/flags/Portugal.vue +59 -0
- package/icons/flags/Spain.vue +546 -0
- package/icons/flags/UnitedStates.vue +12 -0
- package/icons/sets.ts +17 -0
- package/models/rules.ts +8 -0
- package/package.json +4 -4
- package/pages/FSExternalIdentityButton.vue +64 -0
- package/pages/FSLanguageSetter.vue +140 -0
- package/pages/FSLoginPage.vue +253 -0
- package/styles/components/fs_clock.scss +4 -0
- package/styles/components/fs_color_field.scss +17 -0
- package/styles/components/fs_divider.scss +5 -0
- package/styles/components/fs_image.scss +12 -1
- package/styles/components/fs_label.scss +86 -0
- package/styles/components/fs_pagination.scss +3 -3
- package/styles/components/fs_time_field.scss +3 -0
- package/styles/components/fs_timeslot_field.scss +75 -0
- package/styles/components/index.scss +4 -0
- package/styles/globals/text_fonts.scss +18 -0
- package/styles/main.scss +3 -1
- package/styles/pages/fs_language_setter.scss +55 -0
- package/styles/pages/index.scss +1 -0
- package/utils/color.ts +7 -0
- package/utils/css.ts +2 -1
- package/utils/index.ts +3 -1
- package/utils/time.ts +29 -0
- package/components/FSHeaderButton.vue +0 -17
- 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 "
|
|
78
|
-
import FSCol from "
|
|
79
|
-
import FSRow from "
|
|
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 "
|
|
100
|
-
import FSButton from "
|
|
101
|
-
import FSCard from "
|
|
102
|
-
import FSCol from "
|
|
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
|
-
:
|
|
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 "
|
|
86
|
-
import FSCalendarTwin from "
|
|
56
|
+
import FSSubmitDialog from "../FSSubmitDialog.vue";
|
|
57
|
+
import FSCalendarTwin from "../FSCalendarTwin.vue";
|
|
87
58
|
import FSTextField from "./FSTextField.vue";
|
|
88
|
-
import FSButton from "
|
|
89
|
-
import FSCard from "
|
|
90
|
-
import FSCol from "
|
|
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
|
|
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
|
-
|
|
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 "
|
|
124
|
-
import FSWindow from "
|
|
125
|
-
import FSButton from "
|
|
126
|
-
import FSClock from "
|
|
127
|
-
import FSCard from "
|
|
128
|
-
import FSCol from "
|
|
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,
|