@dative-gpi/foundation-shared-components 0.0.100 → 0.0.102

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.
@@ -228,7 +228,6 @@ export default defineComponent({
228
228
  };
229
229
 
230
230
  const onSubmit = () => {
231
- console.log(valid.value)
232
231
  if (valid.value) {
233
232
  switch (currentStep.value) {
234
233
  case props.steps:
@@ -0,0 +1,653 @@
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"
9
+ >
10
+ <FSForm
11
+ v-model="valid"
12
+ >
13
+ <FSRow>
14
+ <FSSelectDateSetting
15
+ :lastPeriod="$props.lastPeriod"
16
+ :editable="$props.editable"
17
+ :variant="$props.variant"
18
+ :modelValue="localDateSetting"
19
+ @update:modelValue="localDateSettingChange"
20
+ />
21
+ <FSNumberField
22
+ v-if="pastSettings.includes(localDateSetting)"
23
+ :rules="[NumberRules.required(), NumberRules.min(0)]"
24
+ :editable="$props.editable"
25
+ :hideHeader="true"
26
+ :modelValue="localDateValue"
27
+ @update:modelValue="localDateValueChange"
28
+ />
29
+ <template
30
+ v-else-if="localDateSetting === DateSetting.Expression"
31
+ >
32
+ <FSRow
33
+ align="center-left"
34
+ :wrap="false"
35
+ >
36
+ <FSIcon>
37
+ mdi-clock-start
38
+ </FSIcon>
39
+ <FSTextField
40
+ :rules="[TextRules.required(), DateRules.validateExpression($props.variant)]"
41
+ :editable="$props.editable"
42
+ :hideHeader="true"
43
+ :modelValue="localStartDate"
44
+ @update:modelValue="localStartDateChange"
45
+ />
46
+ </FSRow>
47
+ <FSRow
48
+ align="center-left"
49
+ :wrap="false"
50
+ >
51
+ <FSIcon>
52
+ mdi-clock-end
53
+ </FSIcon>
54
+ <FSTextField
55
+ :rules="[TextRules.required(), DateRules.validateExpression($props.variant)]"
56
+ :editable="$props.editable"
57
+ :hideHeader="true"
58
+ :modelValue="localEndDate"
59
+ @update:modelValue="localEndDateChange"
60
+ />
61
+ </FSRow>
62
+ </template>
63
+ <FSDateTimeRangeField
64
+ v-else-if="localDateSetting === DateSetting.Pick"
65
+ :rules="[DateRules.required()]"
66
+ :editable="$props.editable"
67
+ :hideHeader="true"
68
+ :modelValue="[parseForPicker(localStartDate)!, parseForPicker(localEndDate)!]"
69
+ @update:modelValue="onPickDates"
70
+ />
71
+ </FSRow>
72
+ </FSForm>
73
+ </FSBaseField>
74
+ </template>
75
+
76
+ <script lang="ts">
77
+ import { computed, defineComponent, onMounted, PropType, ref} from "vue";
78
+ import _ from "lodash";
79
+
80
+ import { DateRules, NumberRules, TextRules } from "@dative-gpi/foundation-shared-components/models";
81
+ import { useAppTimeZone } from "@dative-gpi/foundation-shared-services/composables";
82
+ import { useRules } from "@dative-gpi/foundation-shared-components/composables";
83
+ import { DateSetting } from "@dative-gpi/foundation-shared-domain/models";
84
+
85
+ import FSSelectDateSetting from "../selects/FSSelectDateSetting.vue";
86
+ import FSDateTimeRangeField from "./FSDateTimeRangeField.vue";
87
+ import FSNumberField from "./FSNumberField.vue";
88
+ import FSBaseField from "./FSBaseField.vue";
89
+ import FSTextField from "./FSTextField.vue";
90
+ import FSForm from "../FSForm.vue";
91
+ import FSIcon from "../FSIcon.vue";
92
+ import FSRow from "../FSRow.vue";
93
+
94
+ export default defineComponent({
95
+ name: "FSTermField",
96
+ components: {
97
+ FSDateTimeRangeField,
98
+ FSSelectDateSetting,
99
+ FSNumberField,
100
+ FSBaseField,
101
+ FSTextField,
102
+ FSForm,
103
+ FSIcon,
104
+ FSRow
105
+ },
106
+ props: {
107
+ label: {
108
+ type: String as PropType<string | null>,
109
+ required: false,
110
+ default: null
111
+ },
112
+ description: {
113
+ type: String as PropType<string | null>,
114
+ required: false,
115
+ default: null
116
+ },
117
+ startDate: {
118
+ type: String,
119
+ required: true
120
+ },
121
+ endDate: {
122
+ type: String,
123
+ required: true
124
+ },
125
+ variant : {
126
+ type: String as PropType<"default" | "before-after">,
127
+ required: false,
128
+ default: "default"
129
+ },
130
+ hideHeader: {
131
+ type: Boolean,
132
+ required: false,
133
+ default: false
134
+ },
135
+ lastPeriod: {
136
+ type: Boolean,
137
+ required: false,
138
+ default: false
139
+ },
140
+ required: {
141
+ type: Boolean,
142
+ required: false,
143
+ default: false
144
+ },
145
+ rules: {
146
+ type: Array as PropType<any[]>,
147
+ required: false,
148
+ default: () => []
149
+ },
150
+ messages: {
151
+ type: Array as PropType<string[]>,
152
+ required: false,
153
+ default: null
154
+ },
155
+ editable: {
156
+ type: Boolean,
157
+ required: false,
158
+ default: true
159
+ }
160
+ },
161
+ emits: ["update:startDate", "update:endDate"],
162
+ setup(props, { emit }) {
163
+ const { parseForPicker,formatFromPicker, formatCurrentForPicker } = useAppTimeZone();
164
+ const { getMessages } = useRules();
165
+
166
+ const localDateSetting = ref<DateSetting>(DateSetting.PastDays);
167
+ const localDateValue = ref<number>(1);
168
+ const localStartDate = ref<string>("now - 1d");
169
+ const localEndDate = ref<string>("now");
170
+
171
+ const valid = ref<boolean>(false);
172
+
173
+ const pastSettings = computed((): DateSetting[] => {
174
+ return [
175
+ DateSetting.PastHours, DateSetting.PastDays, DateSetting.PastWeeks, DateSetting.PastMonths, DateSetting.PastYears,
176
+ DateSetting.MinutesBeforeAfter, DateSetting.HoursBeforeAfter, DateSetting.DaysBeforeAfter, DateSetting.WeeksBeforeAfter,
177
+ DateSetting.MinutesBefore, DateSetting.HoursBefore, DateSetting.DaysBefore, DateSetting.WeeksBefore
178
+ ];
179
+ });
180
+
181
+ const messages = computed((): string[] => {
182
+ return props.messages ??
183
+ getMessages(props.startDate, props.rules).concat(getMessages(props.endDate, props.rules));
184
+ });
185
+
186
+ const localStartDateChange = (value: string) => {
187
+ debouncedStartDate(value);
188
+ };
189
+
190
+ const onStartDateChange = (value: string) => {
191
+ localStartDate.value = value;
192
+ if (valid.value) {
193
+ emit("update:startDate", value);
194
+ }
195
+ };
196
+
197
+ const debouncedStartDate = _.debounce(onStartDateChange, 1000);
198
+
199
+ const localEndDateChange = (value: string) => {
200
+ debouncedEndDate(value);
201
+ };
202
+
203
+ const onEndDateChange = (value: string) => {
204
+ localEndDate.value = value;
205
+ if (valid.value) {
206
+ emit("update:endDate", value);
207
+ }
208
+ };
209
+
210
+ const debouncedEndDate = _.debounce(onEndDateChange, 1000);
211
+
212
+ const localDateSettingChange = (value: DateSetting) => {
213
+ localDateSetting.value = value;
214
+ switch (value) {
215
+ case DateSetting.None:
216
+ return;
217
+ case DateSetting.PastHours:
218
+ localStartDate.value = `now - ${localDateValue.value}h`;
219
+ localEndDate.value = "now";
220
+ break;
221
+ case DateSetting.PastDays:
222
+ localStartDate.value = `now - ${localDateValue.value}d`;
223
+ localEndDate.value = "now";
224
+ break;
225
+ case DateSetting.PastWeeks:
226
+ localStartDate.value = `now - ${localDateValue.value}w`;
227
+ localEndDate.value = "now";
228
+ break;
229
+ case DateSetting.PastMonths:
230
+ localStartDate.value = `now - ${localDateValue.value}M`;
231
+ localEndDate.value = "now";
232
+ break;
233
+ case DateSetting.PastYears:
234
+ localStartDate.value = `now - ${localDateValue.value}y`;
235
+ localEndDate.value = "now";
236
+ break;
237
+ case DateSetting.CurrentHour:
238
+ localStartDate.value = "now/h";
239
+ localEndDate.value = "now";
240
+ break;
241
+ case DateSetting.CurrentDay:
242
+ localStartDate.value = "now/d";
243
+ localEndDate.value = "now";
244
+ break;
245
+ case DateSetting.CurrentWeek:
246
+ localStartDate.value = "now/w";
247
+ localEndDate.value = "now";
248
+ break;
249
+ case DateSetting.CurrentMonth:
250
+ localStartDate.value = "now/M";
251
+ localEndDate.value = "now";
252
+ break;
253
+ case DateSetting.CurrentYear:
254
+ localStartDate.value = "now/y";
255
+ localEndDate.value = "now";
256
+ break;
257
+ case DateSetting.LastDay:
258
+ localStartDate.value = `now - 1d/d`;
259
+ localEndDate.value = "now/d";
260
+ break;
261
+ case DateSetting.LastWeek:
262
+ localStartDate.value = `now - 1w/w`;
263
+ localEndDate.value = "now/w";
264
+ break;
265
+ case DateSetting.LastMonth:
266
+ localStartDate.value = `now - 1M/M`;
267
+ localEndDate.value = "now/M";
268
+ break;
269
+ case DateSetting.LastYear:
270
+ localStartDate.value = `now - 1y/y`;
271
+ localEndDate.value = "now/y";
272
+ break;
273
+ case DateSetting.SinceLastDay:
274
+ localStartDate.value = `now - 1d/d`;
275
+ localEndDate.value = "now";
276
+ break;
277
+ case DateSetting.SinceLastWeek:
278
+ localStartDate.value = `now - 1w/w`;
279
+ localEndDate.value = "now";
280
+ break;
281
+ case DateSetting.SinceLastMonth:
282
+ localStartDate.value = `now - 1M/M`;
283
+ localEndDate.value = "now";
284
+ break;
285
+ case DateSetting.SinceLastYear:
286
+ localStartDate.value = `now - 1y/y`;
287
+ localEndDate.value = "now";
288
+ break;
289
+ case DateSetting.LastPeriod:
290
+ localStartDate.value = "from - to + from";
291
+ localEndDate.value = "from";
292
+ break;
293
+ case DateSetting.MinutesBeforeAfter:
294
+ localStartDate.value = `alertstart - ${localDateValue.value}m`;
295
+ localEndDate.value = `alertend + ${localDateValue.value}m`;
296
+ break;
297
+ case DateSetting.HoursBeforeAfter:
298
+ localStartDate.value = `alertstart - ${localDateValue.value}h`;
299
+ localEndDate.value = `alertend + ${localDateValue.value}h`;
300
+ break;
301
+ case DateSetting.DaysBeforeAfter:
302
+ localStartDate.value = `alertstart - ${localDateValue.value}d`;
303
+ localEndDate.value = `alertend + ${localDateValue.value}d`;
304
+ break;
305
+ case DateSetting.WeeksBeforeAfter:
306
+ localStartDate.value = `alertstart - ${localDateValue.value}w`;
307
+ localEndDate.value = `alertend + ${localDateValue.value}w`;
308
+ break;
309
+ case DateSetting.MinutesBefore:
310
+ localStartDate.value = `alertstart - ${localDateValue.value}m`;
311
+ localEndDate.value = "alertend";
312
+ break;
313
+ case DateSetting.HoursBefore:
314
+ localStartDate.value = `alertstart - ${localDateValue.value}h`;
315
+ localEndDate.value = "alertend";
316
+ break;
317
+ case DateSetting.DaysBefore:
318
+ localStartDate.value = `alertstart - ${localDateValue.value}d`;
319
+ localEndDate.value = "alertend";
320
+ break;
321
+ case DateSetting.WeeksBefore:
322
+ localStartDate.value = `alertstart - ${localDateValue.value}w`;
323
+ localEndDate.value = "alertend";
324
+ break;
325
+ case DateSetting.Expression:
326
+ if (props.variant === "before-after") {
327
+ localStartDate.value = `alertstart - ${localDateValue.value}d`;
328
+ localEndDate.value = "alertend";
329
+ }
330
+ else {
331
+ localStartDate.value = `now - ${localDateValue.value}d`;
332
+ localEndDate.value = "now";
333
+ }
334
+ break;
335
+ case DateSetting.Pick:
336
+ localEndDate.value = formatCurrentForPicker(0);
337
+ localStartDate.value = formatCurrentForPicker(-1);
338
+ break;
339
+ }
340
+ emit("update:startDate", localStartDate.value);
341
+ emit("update:endDate", localEndDate.value);
342
+ };
343
+
344
+ const localDateValueChange = (value: number) => {
345
+ localDateValue.value = value ? value : 1;
346
+
347
+ switch (localDateSetting.value) {
348
+ case DateSetting.None:
349
+ return;
350
+ case DateSetting.PastHours:
351
+ localStartDate.value = `now - ${localDateValue.value}h`;
352
+ localEndDate.value = "now";
353
+ break;
354
+ case DateSetting.PastDays:
355
+ localStartDate.value = `now - ${localDateValue.value}d`;
356
+ localEndDate.value = "now";
357
+ break;
358
+ case DateSetting.PastWeeks:
359
+ localStartDate.value = `now - ${localDateValue.value}w`;
360
+ localEndDate.value = "now";
361
+ break;
362
+ case DateSetting.PastMonths:
363
+ localStartDate.value = `now - ${localDateValue.value}M`;
364
+ localEndDate.value = "now";
365
+ break;
366
+ case DateSetting.PastYears:
367
+ localStartDate.value = `now - ${localDateValue.value}y`;
368
+ localEndDate.value = "now";
369
+ break;
370
+ case DateSetting.MinutesBeforeAfter:
371
+ localStartDate.value = `alertstart - ${localDateValue.value}m`;
372
+ localEndDate.value = `alertend + ${localDateValue.value}m`;
373
+ break;
374
+ case DateSetting.HoursBeforeAfter:
375
+ localStartDate.value = `alertstart - ${localDateValue.value}h`;
376
+ localEndDate.value = `alertend + ${localDateValue.value}h`;
377
+ break;
378
+ case DateSetting.DaysBeforeAfter:
379
+ localStartDate.value = `alertstart - ${localDateValue.value}d`;
380
+ localEndDate.value = `alertend + ${localDateValue.value}d`;
381
+ break;
382
+ case DateSetting.WeeksBeforeAfter:
383
+ localStartDate.value = `alertstart - ${localDateValue.value}w`;
384
+ localEndDate.value = `alertend + ${localDateValue.value}w`;
385
+ break;
386
+ case DateSetting.MinutesBefore:
387
+ localStartDate.value = `alertstart - ${localDateValue.value}m`;
388
+ localEndDate.value = "alertend";
389
+ break;
390
+ case DateSetting.HoursBefore:
391
+ localStartDate.value = `alertstart - ${localDateValue.value}h`;
392
+ localEndDate.value = "alertend";
393
+ break;
394
+ case DateSetting.DaysBefore:
395
+ localStartDate.value = `alertstart - ${localDateValue.value}d`;
396
+ localEndDate.value = "alertend";
397
+ break;
398
+ case DateSetting.WeeksBefore:
399
+ localStartDate.value = `alertstart - ${localDateValue.value}w`;
400
+ localEndDate.value = "alertend";
401
+ break;
402
+ }
403
+ emit("update:startDate", localStartDate.value);
404
+ emit("update:endDate", localEndDate.value);
405
+ };
406
+
407
+ const onPickDates = (value: number[] | null) => {
408
+ if (!value) {
409
+ localEndDate.value = formatCurrentForPicker(0);
410
+ localStartDate.value = formatCurrentForPicker(-1);
411
+ if (valid.value) {
412
+ emit("update:startDate", localStartDate.value);
413
+ emit("update:endDate", localEndDate.value);
414
+ }
415
+ }
416
+ else {
417
+ if (value && value[0] != null && formatFromPicker(value[0]) !== localStartDate.value) {
418
+ localStartDate.value = formatFromPicker(value[0]);
419
+ if (valid.value) {
420
+ emit("update:startDate", localStartDate.value);
421
+ }
422
+ }
423
+ if (value && value[1] != null && formatFromPicker(value[1]) !== localEndDate.value) {
424
+ localEndDate.value = formatFromPicker(value[1]);
425
+ if (valid.value) {
426
+ emit("update:endDate", localEndDate.value);
427
+ }
428
+ }
429
+ }
430
+ };
431
+
432
+ const reset = (): void => {
433
+ localStartDate.value = props.startDate;
434
+ localEndDate.value = props.endDate;
435
+
436
+ if (props.variant === "before-after") {
437
+ if (props.endDate === "alertend") {
438
+ let match = /^alertstart-([\d]+)([mhdw])$/g.exec(props.startDate.replaceAll(" ", ""));
439
+ if (match != null) {
440
+ localDateValue.value = parseInt(match[1]);
441
+ switch (match[2]) {
442
+ case 'm': {
443
+ localDateSetting.value = DateSetting.MinutesBefore;
444
+ return;
445
+ }
446
+ case 'h': {
447
+ localDateSetting.value = DateSetting.HoursBefore;
448
+ return;
449
+ }
450
+ case 'd': {
451
+ localDateSetting.value = DateSetting.DaysBefore;
452
+ return;
453
+ }
454
+ case 'w': {
455
+ localDateSetting.value = DateSetting.WeeksBefore;
456
+ return;
457
+ }
458
+ default: {
459
+ localDateSetting.value = DateSetting.Expression;
460
+ localDateValue.value = 1;
461
+ return;
462
+ }
463
+ }
464
+ }
465
+ }
466
+
467
+ if (
468
+ /^alertstart-([\d]+)([mhdw])$/g.test(props.startDate.replaceAll(" ", "")) &&
469
+ /^alertend\+([\d]+)([mhdw])$/g.test(props.endDate.replaceAll(" ", ""))
470
+ ) {
471
+ let startMatch = /^alertstart-([\d]+)([mhdw])$/g.exec(props.startDate.replaceAll(" ", ""));
472
+ let endMatch = /^alertend\+([\d]+)([mhdw])$/g.exec(props.endDate.replaceAll(" ", ""));
473
+ if (startMatch != null && endMatch != null && startMatch[1] === endMatch[1] && startMatch[2] === endMatch[2]) {
474
+ localDateValue.value = parseInt(startMatch[1]);
475
+ switch(startMatch[2]) {
476
+ case 'm': {
477
+ localDateSetting.value = DateSetting.MinutesBeforeAfter;
478
+ return;
479
+ }
480
+ case 'h': {
481
+ localDateSetting.value = DateSetting.HoursBeforeAfter;
482
+ return;
483
+ }
484
+ case 'd': {
485
+ localDateSetting.value = DateSetting.DaysBeforeAfter;
486
+ return;
487
+ }
488
+ case 'w': {
489
+ localDateSetting.value = DateSetting.WeeksBeforeAfter;
490
+ return;
491
+ }
492
+ default: {
493
+ localDateSetting.value = DateSetting.Expression;
494
+ localDateValue.value = 1;
495
+ return;
496
+ }
497
+ }
498
+ }
499
+ }
500
+
501
+ localDateSetting.value = DateSetting.Expression;
502
+ localDateValue.value = 1;
503
+ return;
504
+ }
505
+
506
+ if (props.lastPeriod && props.endDate === "from" && props.startDate === "from - to + from") {
507
+ localDateSetting.value = DateSetting.LastPeriod;
508
+ return;
509
+ }
510
+ if (props.endDate === "now/d" && props.startDate === "now - 1d/d") {
511
+ localDateSetting.value = DateSetting.LastDay;
512
+ return;
513
+ }
514
+ if (props.endDate === "now/w" && props.startDate === "now - 1w/w") {
515
+ localDateSetting.value = DateSetting.LastWeek;
516
+ return;
517
+ }
518
+ if (props.endDate === "now/M" && props.startDate === "now - 1M/M") {
519
+ localDateSetting.value = DateSetting.LastMonth;
520
+ return;
521
+ }
522
+ if (props.endDate === "now/y" && props.startDate === "now - 1y/y") {
523
+ localDateSetting.value = DateSetting.LastYear;
524
+ return;
525
+ }
526
+
527
+ if (props.endDate === "now") {
528
+ let match = /^now-1([dwMy])\/([dwMy])$/g.exec(props.startDate.replaceAll(" ", ""));
529
+ if (match != null) {
530
+ localDateValue.value = 1;
531
+ switch (match[1]) {
532
+ case 'd': {
533
+ localDateSetting.value = DateSetting.SinceLastDay;
534
+ return;
535
+ }
536
+ case 'w': {
537
+ localDateSetting.value = DateSetting.SinceLastWeek;
538
+ return;
539
+ }
540
+ case 'M': {
541
+ localDateSetting.value = DateSetting.SinceLastMonth;
542
+ return;
543
+ }
544
+ case 'y': {
545
+ localDateSetting.value = DateSetting.SinceLastYear;
546
+ return;
547
+ }
548
+ default: {
549
+ localDateSetting.value = DateSetting.Expression;
550
+ return;
551
+ }
552
+ }
553
+ }
554
+ match = /^now-([\d]+)([hdwMy])$/g.exec(props.startDate.replaceAll(" ", ""));
555
+ if (match != null) {
556
+ localDateValue.value = parseInt(match[1]);
557
+ switch (match[2]) {
558
+ case 'h': {
559
+ localDateSetting.value = DateSetting.PastHours;
560
+ return;
561
+ }
562
+ case 'd': {
563
+ localDateSetting.value = DateSetting.PastDays;
564
+ return;
565
+ }
566
+ case 'w': {
567
+ localDateSetting.value = DateSetting.PastWeeks;
568
+ return;
569
+ }
570
+ case 'M': {
571
+ localDateSetting.value = DateSetting.PastMonths;
572
+ return;
573
+ }
574
+ case 'y': {
575
+ localDateSetting.value = DateSetting.PastYears;
576
+ return;
577
+ }
578
+ default: {
579
+ localDateSetting.value = DateSetting.Expression;
580
+ localDateValue.value = 1;
581
+ return;
582
+ }
583
+ }
584
+ }
585
+
586
+ match = /^now\/([hdwMy])$/g.exec(props.startDate.replaceAll(" ", ""));
587
+ if (match != null) {
588
+ localDateValue.value = 1;
589
+ switch (match[1]) {
590
+ case 'h': {
591
+ localDateSetting.value = DateSetting.CurrentHour;
592
+ return;
593
+ }
594
+ case 'd': {
595
+ localDateSetting.value = DateSetting.CurrentDay;
596
+ return;
597
+ }
598
+ case 'w': {
599
+ localDateSetting.value = DateSetting.CurrentWeek;
600
+ return;
601
+ }
602
+ case 'M': {
603
+ localDateSetting.value = DateSetting.CurrentMonth;
604
+ return;
605
+ }
606
+ case 'y': {
607
+ localDateSetting.value = DateSetting.CurrentYear;
608
+ return;
609
+ }
610
+ default: {
611
+ localDateSetting.value = DateSetting.Expression;
612
+ return;
613
+ }
614
+ }
615
+ }
616
+ }
617
+
618
+ if (parseForPicker(props.endDate) != null && parseForPicker(props.startDate) != null) {
619
+ localDateSetting.value = DateSetting.Pick;
620
+ localDateValue.value = 1;
621
+ return;
622
+ }
623
+
624
+ localDateSetting.value = DateSetting.Expression;
625
+ localDateValue.value = 1;
626
+ };
627
+
628
+ onMounted(() => {
629
+ reset();
630
+ });
631
+
632
+ return {
633
+ localDateSetting,
634
+ localDateValue,
635
+ localStartDate,
636
+ localEndDate,
637
+ pastSettings,
638
+ DateSetting,
639
+ NumberRules,
640
+ DateRules,
641
+ TextRules,
642
+ messages,
643
+ valid,
644
+ localDateSettingChange,
645
+ localDateValueChange,
646
+ localStartDateChange,
647
+ localEndDateChange,
648
+ parseForPicker,
649
+ onPickDates
650
+ };
651
+ }
652
+ });
653
+ </script>
@@ -124,7 +124,7 @@ export default defineComponent({
124
124
  },
125
125
  emits: ["update:modelValue"],
126
126
  setup(props, { emit }) {
127
- const { validateOn, blurred, getMessages } = useRules();
127
+ const { validateOn, getMessages } = useRules();
128
128
  const { getColors } = useColors();
129
129
 
130
130
  const errors = getColors(ColorEnum.Error);
@@ -238,7 +238,6 @@ export default defineComponent({
238
238
  ColorEnum,
239
239
  dayStart,
240
240
  messages,
241
- blurred,
242
241
  dayEnd,
243
242
  style,
244
243
  onChangeHourStart,
@@ -0,0 +1,99 @@
1
+ <template>
2
+ <FSSelectField
3
+ :editable="$props.editable"
4
+ :items="dateSettings"
5
+ :hideHeader="true"
6
+ :clearable="false"
7
+ :modelValue="$props.modelValue"
8
+ @update:modelValue="$emit('update:modelValue', $event)"
9
+ v-bind="$attrs"
10
+ />
11
+ </template>
12
+
13
+ <script lang="ts">
14
+ import { computed, defineComponent, PropType } from "vue";
15
+
16
+ import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
17
+ import { DateSetting } from "@dative-gpi/foundation-shared-domain/models";
18
+
19
+ import FSSelectField from "../fields/FSSelectField.vue";
20
+
21
+ export default defineComponent({
22
+ name: "FSSelectDateSetting",
23
+ components: {
24
+ FSSelectField
25
+ },
26
+ props: {
27
+ variant: {
28
+ type: String as PropType<"default" | "before-after">,
29
+ required: false,
30
+ default: "default"
31
+ },
32
+ modelValue: {
33
+ type: Number as PropType<DateSetting>,
34
+ required: true
35
+ },
36
+ lastPeriod: {
37
+ type: Boolean,
38
+ required: false,
39
+ default: false
40
+ },
41
+ editable: {
42
+ type: Boolean,
43
+ required: false,
44
+ default: true
45
+ }
46
+ },
47
+ emits: ["update:modelValue"],
48
+ setup(props) {
49
+ const { $tr } = useTranslationsProvider();
50
+
51
+ const dateSettings = computed((): { id: DateSetting, label: string }[] => {
52
+ if (props.variant === "before-after") {
53
+ return [
54
+ { id: DateSetting.Pick, label: $tr("ui.common.pick-dates", "Pick dates") },
55
+ { id: DateSetting.MinutesBeforeAfter, label: $tr("ui.common.x-minutes-before-after-hour", "x Minutes before/after") },
56
+ { id: DateSetting.HoursBeforeAfter, label: $tr("ui.common.x-hours-before-after-hour", "x Hours before/after") },
57
+ { id: DateSetting.DaysBeforeAfter, label: $tr("ui.common.x-days-before-after-hour", "x Days before/after") },
58
+ { id: DateSetting.WeeksBeforeAfter, label: $tr("ui.common.x-weeks-before-after-hour", "x Weeks before/after") },
59
+ { id: DateSetting.MinutesBefore, label: $tr("ui.common.x-minutes-before", "x Minutes before") },
60
+ { id: DateSetting.HoursBefore, label: $tr("ui.common.x-hours-before", "x Hours before") },
61
+ { id: DateSetting.DaysBefore, label: $tr("ui.common.x-days-before", "x Days before") },
62
+ { id: DateSetting.WeeksBefore, label: $tr("ui.common.x-weeks-before", "x Weeks before") },
63
+ { id: DateSetting.Expression, label: $tr("ui.common.expression", "Expression") }
64
+ ];
65
+ }
66
+ let dateSettings = [
67
+ { id: DateSetting.Pick, label: $tr("ui.common.pick-dates", "Pick dates") },
68
+ { id: DateSetting.CurrentHour, label: $tr("ui.common.this-hour", "This hour") },
69
+ { id: DateSetting.CurrentDay, label: $tr("ui.common.this-day", "This day") },
70
+ { id: DateSetting.CurrentWeek, label: $tr("ui.common.this-week", "This week") },
71
+ { id: DateSetting.CurrentMonth, label: $tr("ui.common.this-month", "This month") },
72
+ { id: DateSetting.CurrentYear, label: $tr("ui.common.this-year", "This year") },
73
+ { id: DateSetting.LastDay, label: $tr("ui.common.last-day", "Last day") },
74
+ { id: DateSetting.LastWeek, label: $tr("ui.common.last-week", "Last week") },
75
+ { id: DateSetting.LastMonth, label: $tr("ui.common.last-month", "Last month") },
76
+ { id: DateSetting.LastYear, label: $tr("ui.common.last-year", "Last year") },
77
+ { id: DateSetting.SinceLastDay, label: $tr("ui.common.since-last-day", "Since last day") },
78
+ { id: DateSetting.SinceLastWeek, label: $tr("ui.common.since-last-week", "Since last week") },
79
+ { id: DateSetting.SinceLastMonth, label: $tr("ui.common.since-last-month", "Since last month") },
80
+ { id: DateSetting.SinceLastYear, label: $tr("ui.common.since-last-year", "Since last year") },
81
+ { id: DateSetting.PastHours, label: $tr("ui.common.past-x-hours", "Past x hours") },
82
+ { id: DateSetting.PastDays, label: $tr("ui.common.past-x-days", "Past x days") },
83
+ { id: DateSetting.PastWeeks, label: $tr("ui.common.past-x-weeks", "Past x weeks") },
84
+ { id: DateSetting.PastMonths, label: $tr("ui.common.past-x-months", "Past x months") },
85
+ { id: DateSetting.PastYears, label: $tr("ui.common.past-x-years", "Past x years") },
86
+ { id: DateSetting.Expression, label: $tr("ui.common.expression", "Expression") }
87
+ ];
88
+ if (props.lastPeriod) {
89
+ dateSettings.push({ id: DateSetting.LastPeriod, label: $tr("ui.common.last-period", "Last period") });
90
+ }
91
+ return dateSettings;
92
+ })
93
+
94
+ return {
95
+ dateSettings
96
+ };
97
+ }
98
+ });
99
+ </script>
@@ -1,15 +1,23 @@
1
1
  <template>
2
- <FSSelectField itemTitle="id"
2
+ <FSSelectField
3
+ itemTitle="id"
3
4
  :items="timeZones"
4
5
  :modelValue="$props.modelValue"
5
6
  @update:modelValue="$emit('update:modelValue', $event)"
6
- v-bind="$attrs">
7
- <template #append-inner>
8
- <slot name="append-inner">
9
- <FSChip v-if="offset"
7
+ v-bind="$attrs"
8
+ >
9
+ <template
10
+ #append-inner
11
+ >
12
+ <slot
13
+ name="append-inner"
14
+ >
15
+ <FSChip
16
+ v-if="offset"
10
17
  variant="standard"
11
18
  :color="ColorEnum.Dark"
12
- :label="offset" />
19
+ :label="offset"
20
+ />
13
21
  </slot>
14
22
  </template>
15
23
  </FSSelectField>
@@ -1,9 +1,9 @@
1
1
  import { RouteLocationRaw } from "vue-router";
2
2
  export interface FSBreadcrumbItem {
3
- to?: RouteLocationRaw,
4
- disabled?: boolean,
5
- replace?: boolean,
6
- exact?: boolean,
7
- title: string,
8
- href?: string
3
+ to?: RouteLocationRaw | null;
4
+ disabled?: boolean | null;
5
+ replace?: boolean | null;
6
+ exact?: boolean | null;
7
+ title: string | null;
8
+ href?: string | null;
9
9
  }
package/models/colors.ts CHANGED
@@ -6,17 +6,17 @@ export enum ColorEnum {
6
6
  Error = "error",
7
7
  Warning = "warning",
8
8
  Success = "success"
9
- };
9
+ }
10
10
 
11
11
  export interface ColorVariations {
12
12
  light: string;
13
- lightContrast?: string;
13
+ lightContrast?: string | null;
14
14
  soft: string;
15
- softContrast?: string;
15
+ softContrast?: string | null;
16
16
  base: string;
17
- baseContrast?: string;
17
+ baseContrast?: string | null;
18
18
  dark: string;
19
- darkContrast?: string;
20
- };
19
+ darkContrast?: string | null;
20
+ }
21
21
 
22
22
  export type ColorBase = (string | ColorEnum);
@@ -5,6 +5,6 @@ export interface FSDeviceAlert {
5
5
  label: string;
6
6
  status: AlertStatus;
7
7
  criticity: Criticity;
8
- sourceTimestamp?: number;
9
- enqueuedTimestamp?: number;
8
+ sourceTimestamp?: number | null;
9
+ enqueuedTimestamp?: number | null;
10
10
  }
@@ -2,9 +2,9 @@ import { ConnectivityStatus } from "@dative-gpi/foundation-shared-domain/models"
2
2
 
3
3
  export interface FSDeviceConnectivity {
4
4
  id: string;
5
- sourceTimestamp?: number;
6
- enqueuedTimestamp?: number;
7
- processedTimestamp?: number;
5
+ sourceTimestamp?: number | null;
6
+ enqueuedTimestamp?: number | null;
7
+ processedTimestamp?: number | null;
8
8
  status: ConnectivityStatus;
9
9
  icon: string;
10
10
  color: string;
@@ -5,12 +5,12 @@ export interface FSDeviceStatus {
5
5
 
6
6
  export interface FSDeviceStatusGroup {
7
7
  label: string;
8
- groupByValue?: string;
9
- value?: string;
10
- unit?: string;
8
+ groupByValue?: string | null;
9
+ value?: string | null;
10
+ unit?: string | null;
11
11
  icon: string;
12
12
  color: string;
13
- sourceTimestamp?: number;
14
- enqueuedTimestamp?: number;
15
- processedTimestamp?: number;
13
+ sourceTimestamp?: number | null;
14
+ enqueuedTimestamp?: number | null;
15
+ processedTimestamp?: number | null;
16
16
  }
package/models/grids.ts CHANGED
@@ -7,6 +7,6 @@ export interface FSGridMosaic {
7
7
  export interface FSGridItem {
8
8
  label: string;
9
9
  code: string;
10
- value?: string;
11
- hideDefault?: boolean;
10
+ value?: string | null;
11
+ hideDefault?: boolean | null;
12
12
  }
@@ -3,9 +3,9 @@ export interface FSModelStatus {
3
3
  label: string;
4
4
  inline: boolean;
5
5
  index: number;
6
- groupById?: string;
7
- groupByLabel?: string;
6
+ groupById?: string | null;
7
+ groupByLabel?: string | null;
8
8
  showDefault: boolean;
9
- iconDefault?: string;
10
- colorDefault?: string;
9
+ iconDefault?: string | null;
10
+ colorDefault?: string | null;
11
11
  }
package/models/rules.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
2
2
  import { useAppTimeZone } from "@dative-gpi/foundation-shared-services/composables";
3
+ import { validateExpression } from "@dative-gpi/foundation-shared-domain/tools";
3
4
 
4
5
  import { getTimeBestString } from "../utils";
5
6
 
@@ -12,7 +13,7 @@ export const TextRules = {
12
13
  min: (min: number, message: string | undefined = undefined) => (value: string) => value.length >= min || (message ?? $tr("ui.rules.text-min", "Must be at least {0} characters", min.toString())),
13
14
  max: (max: number, message: string | undefined = undefined) => (value: string) => value.length <= max || (message ?? $tr("ui.rules.text-max", "Must be at most {0} characters", max.toString())),
14
15
  email: (message: string | undefined = undefined) => (value: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || (message ?? $tr("ui.rules.text-email", "Must be a valid email")),
15
- phone: (message: string | undefined = undefined) => (value: string) => /^[\+]?([0-9]+[ -]?)+$/.test(value) || (message ?? $tr("ui.rules.text-phone", "Must be a valid phone number")),
16
+ phone: (message: string | undefined = undefined) => (value: string) => /^[+]?([0-9]+[ -]?)+$/.test(value) || (message ?? $tr("ui.rules.text-phone", "Must be a valid phone number")),
16
17
  digit: (message: string | undefined = undefined) => (value: string) => /(?=.*\d)/.test(value) || (message ?? $tr("ui.rules.text-digit", "Must contain a digit")),
17
18
  uppercase: (message: string | undefined = undefined) => (value: string) => /(?=.*[A-Z])/.test(value) || (message ?? $tr("ui.rules.text-uppercase", "Must contain an uppercase letter")),
18
19
  lowercase: (message: string | undefined = undefined) => (value: string) => /(?=.*[a-z])/.test(value) || (message ?? $tr("ui.rules.text-lowercase", "Must contain a lowercase letter")),
@@ -39,7 +40,8 @@ export const IconRules = {
39
40
  export const DateRules = {
40
41
  required: (message: string | undefined = undefined) => (value: string) => !!value || (message ?? $tr("ui.rules.required", "Required")),
41
42
  min: (min: number, message: string | undefined = undefined) => (value: number) => (!value || value >= min) || (message ?? $tr("ui.rules.date-min", "Must be after {0}", epochToLongDateFormat(min))),
42
- max: (max: number, message: string | undefined = undefined) => (value: number) => (!value || value <= max) || (message ?? $tr("ui.rules.date-max", "Must be before {0}", epochToLongDateFormat(max)))
43
+ max: (max: number, message: string | undefined = undefined) => (value: number) => (!value || value <= max) || (message ?? $tr("ui.rules.date-max", "Must be before {0}", epochToLongDateFormat(max))),
44
+ validateExpression: (variant: "default" | "before-after") => (value: string) => validateExpression(value, variant)
43
45
  };
44
46
 
45
47
  export const SelectRules = {
@@ -62,4 +64,4 @@ export const TimeRules = {
62
64
 
63
65
  export const ToggleRules = {
64
66
  required: (message: string | undefined = undefined) => (value: boolean) => value || (message ?? $tr("ui.rules.required", "Required"))
65
- }
67
+ };
package/models/tables.ts CHANGED
@@ -1,30 +1,30 @@
1
1
  export interface FSDataTableColumn {
2
2
  [key: string]: any;
3
- text?: string;
4
- value?: string;
3
+ text?: string | null;
4
+ value?: string | null;
5
5
  index: number;
6
6
  hidden: boolean;
7
- width?: string | number;
7
+ width?: string | number | null;
8
8
 
9
- sortable?: boolean;
10
- sort?: (a: any, b: any) => number;
9
+ sortable?: boolean | null;
10
+ sort?: ((a: any, b: any) => number) | null;
11
11
 
12
- filterable?: boolean;
13
- fixedFilters?: { value: any, text: string }[];
14
- methodFilter?: (value: any, item: any) => boolean;
15
- filter?: (value: any, search: string, item: any) => boolean;
12
+ filterable?: boolean | null;
13
+ fixedFilters?: { value: any, text: string }[] | null;
14
+ methodFilter?: ((value: any, item: any) => boolean) | null;
15
+ filter?: ((value: any, search: string, item: any) => boolean) | null;
16
16
 
17
- innerValue?: (value: any) => any;
17
+ innerValue?: ((value: any) => any) | null;
18
18
 
19
19
  // Should not be set directly !
20
- slotName?: string;
20
+ slotName?: string | null;
21
21
  }
22
22
 
23
23
  export interface FSDataTableFilter {
24
24
  text: string;
25
25
  value: string;
26
26
  hidden: boolean;
27
- filter?: (value: any, property: any, item: any) => boolean;
27
+ filter?: ((value: any, property: any, item: any) => boolean) | null;
28
28
  }
29
29
 
30
30
  export interface FSDataTableOrder {
@@ -1,7 +1,7 @@
1
1
  export interface FSToggle {
2
2
  id: string | number;
3
- prependIcon?: string;
4
- label?: string;
5
- appendIcon?: string;
6
- icon?: string;
3
+ prependIcon?: string | null;
4
+ label?: string | null;
5
+ appendIcon?: string | null;
6
+ icon?: string | null;
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dative-gpi/foundation-shared-components",
3
3
  "sideEffects": false,
4
- "version": "0.0.100",
4
+ "version": "0.0.102",
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": "0.0.100",
14
- "@dative-gpi/foundation-shared-services": "0.0.100",
13
+ "@dative-gpi/foundation-shared-domain": "0.0.102",
14
+ "@dative-gpi/foundation-shared-services": "0.0.102",
15
15
  "@fontsource/montserrat": "^5.0.16",
16
16
  "@lexical/clipboard": "^0.12.5",
17
17
  "@lexical/history": "^0.12.5",
@@ -32,5 +32,5 @@
32
32
  "sass": "^1.69.5",
33
33
  "sass-loader": "^13.3.2"
34
34
  },
35
- "gitHead": "f1231dafad8eae9bf349af5f0e238dd88d20f2e2"
35
+ "gitHead": "d2534b5fa79d557769bcdfd5da4b8dffa0f42c3e"
36
36
  }