@dative-gpi/foundation-shared-components 1.1.15 → 1.1.17

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.
@@ -0,0 +1,184 @@
1
+ <template>
2
+ <FSBaseField
3
+ :description="$props.description"
4
+ :hideHeader="$props.hideHeader"
5
+ :required="$props.required"
6
+ :disabled="$props.disabled"
7
+ :label="$props.label"
8
+ :messages="messages"
9
+ >
10
+ <FSRow
11
+ :wrap="false"
12
+ align="center-left"
13
+ >
14
+ <FSNumberField
15
+ suffix="h"
16
+ :hideHeader="true"
17
+ :modelValue="innerHours"
18
+ :disabled="$props.disabled"
19
+ :rules="[() => messages.length === 0 || '']"
20
+ @update:modelValue="onChangeHours"
21
+ />
22
+ <FSSpan>:</FSSpan>
23
+ <FSNumberField
24
+ suffix="min"
25
+ :hideHeader="true"
26
+ :disabled="$props.disabled"
27
+ :rules="[() => messages.length === 0 || '']"
28
+ :modelValue="innerMinutes"
29
+ @update:modelValue="onChangeMinutes"
30
+ />
31
+ </FSRow>
32
+ </FSBaseField>
33
+ </template>
34
+
35
+ <script lang="ts">
36
+ import { computed, defineComponent, type PropType, ref, watch } from "vue";
37
+
38
+ import { NumberRules } from "@dative-gpi/foundation-shared-components/models";
39
+ import { useRules } from "@dative-gpi/foundation-shared-components/composables";
40
+
41
+ import FSNumberField from "./FSNumberField.vue";
42
+ import FSBaseField from "./FSBaseField.vue";
43
+ import FSSpan from "../FSSpan.vue";
44
+ import FSRow from "../FSRow.vue";
45
+
46
+ export default defineComponent({
47
+ name: "FSDurationField",
48
+ components: {
49
+ FSNumberField,
50
+ FSBaseField,
51
+ FSSpan,
52
+ FSRow
53
+ },
54
+ props: {
55
+ label: {
56
+ type: String as PropType<string | null>,
57
+ required: false,
58
+ default: null
59
+ },
60
+ description: {
61
+ type: String as PropType<string | null>,
62
+ required: false,
63
+ default: null
64
+ },
65
+ modelValue: {
66
+ type: Number as PropType<number | null>,
67
+ required: false,
68
+ default: null
69
+ },
70
+ maxDuration: {
71
+ type: Number as PropType<number | null>,
72
+ required: false,
73
+ default: null
74
+ },
75
+ minDuration: {
76
+ type: Number as PropType<number | null>,
77
+ required: false,
78
+ default: null
79
+ },
80
+ hideHeader: {
81
+ type: Boolean,
82
+ required: false,
83
+ default: false
84
+ },
85
+ required: {
86
+ type: Boolean,
87
+ required: false,
88
+ default: false
89
+ },
90
+ rules: {
91
+ type: Array as PropType<any[]>,
92
+ required: false,
93
+ default: () => []
94
+ },
95
+ messages: {
96
+ type: Array as PropType<string[]>,
97
+ required: false,
98
+ default: null
99
+ },
100
+ disabled: {
101
+ type: Boolean,
102
+ required: false,
103
+ default: false
104
+ }
105
+ },
106
+ emits: ["update:modelValue"],
107
+ setup(props, { emit }) {
108
+ const { getMessages } = useRules();
109
+ const MS_PER_MINUTE = 60 * 1000;
110
+ const MS_PER_HOUR = 60 * MS_PER_MINUTE;
111
+
112
+ const innerHours = ref<number | null>(null);
113
+ const innerMinutes = ref<number | null>(null);
114
+
115
+ const durationRules = computed(() => {
116
+ const rules: any[] = [...props.rules];
117
+ if (props.required) {
118
+ rules.push(NumberRules.required());
119
+ }
120
+ if (props.minDuration != null) {
121
+ const minHours = Math.floor(props.minDuration / MS_PER_HOUR);
122
+ const minMinutes = Math.floor((props.minDuration % MS_PER_HOUR) / MS_PER_MINUTE);
123
+ const label = minHours > 0 ? `${minHours}h${minMinutes.toString().padStart(2, '0')}` : `${minMinutes}min`;
124
+ rules.push((v: any) => (v != null && v >= props.minDuration!) || `Min. ${label}`);
125
+ }
126
+ if (props.maxDuration != null) {
127
+ const maxHours = Math.floor(props.maxDuration / MS_PER_HOUR);
128
+ const maxMinutes = Math.floor((props.maxDuration % MS_PER_HOUR) / MS_PER_MINUTE);
129
+ const label = maxHours > 0 ? `${maxHours}h${maxMinutes.toString().padStart(2, '0')}` : `${maxMinutes}min`;
130
+ rules.push((v: any) => (v != null && v <= props.maxDuration!) || `Max. ${label}`);
131
+ }
132
+ return rules;
133
+ });
134
+
135
+ const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, durationRules.value));
136
+
137
+ const reset = (): void => {
138
+ if (props.modelValue == null) {
139
+ innerHours.value = null;
140
+ innerMinutes.value = null;
141
+ return;
142
+ }
143
+ innerHours.value = Math.floor(props.modelValue / MS_PER_HOUR);
144
+ innerMinutes.value = Math.floor((props.modelValue % MS_PER_HOUR) / MS_PER_MINUTE);
145
+ };
146
+
147
+ const emitValue = (): void => {
148
+ const hours = innerHours.value ?? 0;
149
+ const minutes = innerMinutes.value ?? 0;
150
+ emit("update:modelValue", (hours * MS_PER_HOUR) + (minutes * MS_PER_MINUTE));
151
+ };
152
+
153
+ const onChangeHours = (value: number | null): void => {
154
+ innerHours.value = value;
155
+ emitValue();
156
+ };
157
+
158
+ const onChangeMinutes = (value: number | null): void => {
159
+ value = Math.min(59, Math.max(0, value ?? 0));
160
+ innerMinutes.value = value;
161
+ emitValue();
162
+ };
163
+
164
+ watch(() => props.modelValue, () => {
165
+ const currentHours = innerHours.value ?? 0;
166
+ const currentMinutes = innerMinutes.value ?? 0;
167
+ const currentTotal = (currentHours * MS_PER_HOUR) + (currentMinutes * MS_PER_MINUTE);
168
+ if (currentTotal !== (props.modelValue ?? 0)) {
169
+ reset();
170
+ }
171
+ }, { immediate: true });
172
+
173
+ return {
174
+ NumberRules,
175
+ innerHours,
176
+ innerMinutes,
177
+ durationRules,
178
+ messages,
179
+ onChangeHours,
180
+ onChangeMinutes
181
+ };
182
+ }
183
+ });
184
+ </script>
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "url": "https://github.com/Dative-GPI/foundation-shared-ui.git"
5
5
  },
6
6
  "sideEffects": false,
7
- "version": "1.1.15",
7
+ "version": "1.1.17",
8
8
  "description": "",
9
9
  "publishConfig": {
10
10
  "access": "public"
@@ -13,8 +13,8 @@
13
13
  "author": "",
14
14
  "license": "ISC",
15
15
  "dependencies": {
16
- "@dative-gpi/foundation-shared-domain": "1.1.15",
17
- "@dative-gpi/foundation-shared-services": "1.1.15"
16
+ "@dative-gpi/foundation-shared-domain": "1.1.17",
17
+ "@dative-gpi/foundation-shared-services": "1.1.17"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "@dative-gpi/bones-ui": "^1.0.0",
@@ -38,5 +38,5 @@
38
38
  "sass": "1.71.1",
39
39
  "sass-loader": "13.3.2"
40
40
  },
41
- "gitHead": "2ede680103cbec86d21636377bb03c9c300cb8c8"
41
+ "gitHead": "5486c2e9a50444f235f00c57fc4e32663cb15b25"
42
42
  }