@dative-gpi/foundation-shared-components 1.0.161 → 1.0.163-notification
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/FSInstantPicker.vue +36 -51
- package/components/FSOptionsMenu.vue +165 -0
- package/components/FSRangePicker.vue +261 -0
- package/components/FSRangeSlider.vue +84 -0
- package/components/FSSlider.vue +41 -77
- package/components/lists/FSDataTableUI.vue +16 -11
- package/package.json +4 -4
- package/styles/components/fs_slider.scss +0 -40
- package/tools/alertsTools.ts +10 -9
- package/utils/index.ts +1 -0
- package/utils/picker.ts +40 -0
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
:required="$props.required"
|
|
6
6
|
:disabled="$props.disabled"
|
|
7
7
|
:label="$props.label"
|
|
8
|
+
:maxWidth="$props.maxWidth"
|
|
8
9
|
>
|
|
9
10
|
<FSRow
|
|
10
11
|
align="bottom-center"
|
|
@@ -23,15 +24,12 @@
|
|
|
23
24
|
padding="0 0 2px 0"
|
|
24
25
|
align="center-center"
|
|
25
26
|
>
|
|
26
|
-
<FSCol
|
|
27
|
-
width="fill"
|
|
28
|
-
>
|
|
27
|
+
<FSCol>
|
|
29
28
|
<FSSlider
|
|
30
29
|
minWidth='min(300px, 90vw)'
|
|
31
30
|
:disabled="$props.disabled"
|
|
32
31
|
:color="ColorEnum.Light"
|
|
33
32
|
:thumbColor="ColorEnum.Primary"
|
|
34
|
-
:thumbSize="18"
|
|
35
33
|
:trackSize="8"
|
|
36
34
|
thumb-label="always"
|
|
37
35
|
:step="$props.stepTime"
|
|
@@ -52,20 +50,14 @@
|
|
|
52
50
|
</FSSpan>
|
|
53
51
|
</template>
|
|
54
52
|
<template
|
|
55
|
-
#tick-label="{ tick
|
|
53
|
+
#tick-label="{ tick }"
|
|
56
54
|
>
|
|
57
|
-
<FSRow
|
|
58
|
-
v-if="index % Math.trunc(ticks.length / maximumTickToShow) === 0 || ticks.length < maximumTickToShow"
|
|
59
|
-
>
|
|
55
|
+
<FSRow>
|
|
60
56
|
<FSText
|
|
61
57
|
:color="lightColors.dark"
|
|
62
58
|
font="text-overline"
|
|
63
59
|
>
|
|
64
|
-
{{
|
|
65
|
-
?
|
|
66
|
-
epochToShortTimeOnlyFormat(tick.value)
|
|
67
|
-
:
|
|
68
|
-
epochToDayMonthShortOnly(tick.value)
|
|
60
|
+
{{ tickPrecision === TimePrecision.Hours ? epochToShortTimeOnlyFormat(tick.value) : epochToDayMonthShortOnly(tick.value)
|
|
69
61
|
}}
|
|
70
62
|
</FSText>
|
|
71
63
|
</FSRow>
|
|
@@ -88,18 +80,19 @@
|
|
|
88
80
|
<script lang="ts">
|
|
89
81
|
import { computed, defineComponent, ref, watch } from "vue";
|
|
90
82
|
|
|
83
|
+
import { useBreakpoints, useColors } from '@dative-gpi/foundation-shared-components/composables';
|
|
91
84
|
import { useDateFormat, useDateExpression } from "@dative-gpi/foundation-shared-services/composables";
|
|
92
85
|
|
|
93
86
|
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
94
|
-
import {
|
|
87
|
+
import { computeTicks, TimePrecision } from '@dative-gpi/foundation-shared-components/utils';
|
|
95
88
|
|
|
96
89
|
import FSCol from '@dative-gpi/foundation-shared-components/components/FSCol.vue';
|
|
97
90
|
import FSSpan from '@dative-gpi/foundation-shared-components/components/FSSpan.vue';
|
|
98
91
|
import FSText from '@dative-gpi/foundation-shared-components/components/FSText.vue';
|
|
99
92
|
import FSSlider from '@dative-gpi/foundation-shared-components/components/FSSlider.vue';
|
|
93
|
+
import FSPlayButtons from '@dative-gpi/foundation-shared-components/components/FSPlayButtons.vue';
|
|
100
94
|
import FSBaseField from '@dative-gpi/foundation-shared-components/components/fields/FSBaseField.vue';
|
|
101
95
|
import FSTermField from '@dative-gpi/foundation-shared-components/components/fields/FSTermField.vue';
|
|
102
|
-
import FSPlayButtons from '@dative-gpi/foundation-shared-components/components/FSPlayButtons.vue';
|
|
103
96
|
|
|
104
97
|
export default defineComponent({
|
|
105
98
|
name: "FSInstantPicker",
|
|
@@ -110,7 +103,7 @@ export default defineComponent({
|
|
|
110
103
|
FSSlider,
|
|
111
104
|
FSTermField,
|
|
112
105
|
FSBaseField,
|
|
113
|
-
FSPlayButtons
|
|
106
|
+
FSPlayButtons,
|
|
114
107
|
},
|
|
115
108
|
props: {
|
|
116
109
|
label: {
|
|
@@ -119,8 +112,7 @@ export default defineComponent({
|
|
|
119
112
|
},
|
|
120
113
|
modelValue: {
|
|
121
114
|
type: Number,
|
|
122
|
-
required: false
|
|
123
|
-
default: 0,
|
|
115
|
+
required: false
|
|
124
116
|
},
|
|
125
117
|
startDate: {
|
|
126
118
|
type: String,
|
|
@@ -164,6 +156,11 @@ export default defineComponent({
|
|
|
164
156
|
type: Number,
|
|
165
157
|
required: false,
|
|
166
158
|
default: 50
|
|
159
|
+
},
|
|
160
|
+
maxWidth: {
|
|
161
|
+
type: String as PropType<string | null>,
|
|
162
|
+
required: false,
|
|
163
|
+
default: null
|
|
167
164
|
}
|
|
168
165
|
},
|
|
169
166
|
emits: ['update:modelValue', 'update:startDate', 'update:endDate'],
|
|
@@ -180,38 +177,26 @@ export default defineComponent({
|
|
|
180
177
|
const startTimestamp = computed(() => convertTermToEpoch(props.startDate));
|
|
181
178
|
const endTimestamp = computed(() => convertTermToEpoch(props.endDate));
|
|
182
179
|
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
return (endTimestamp.value - startTimestamp.value) / interval < 100;
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
if (interval) {
|
|
191
|
-
return interval;
|
|
192
|
-
}
|
|
193
|
-
return 86400000;
|
|
180
|
+
const tickCount = computed(() => {
|
|
181
|
+
if (isExtraSmall.value) { return 3; }
|
|
182
|
+
if (isMobileSized.value) { return 4; }
|
|
183
|
+
return 5;
|
|
194
184
|
});
|
|
195
185
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
return ticks;
|
|
186
|
+
// Pour la précision, on peut rester sur l'heure ou le jour selon la plage
|
|
187
|
+
const tickPrecision = computed(() => {
|
|
188
|
+
const rangeDuration = endTimestamp.value - startTimestamp.value;
|
|
189
|
+
if (rangeDuration <= 86400000 * tickCount.value) { return TimePrecision.Hours; }
|
|
190
|
+
if (rangeDuration <= 2592000000 * tickCount.value) { return TimePrecision.Days; }
|
|
191
|
+
return TimePrecision.Months;
|
|
204
192
|
});
|
|
205
193
|
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
return 6;
|
|
214
|
-
});
|
|
194
|
+
const ticks = computed(() => computeTicks({
|
|
195
|
+
start: startTimestamp.value,
|
|
196
|
+
end: endTimestamp.value,
|
|
197
|
+
tickCount: tickCount.value,
|
|
198
|
+
precision: tickPrecision.value
|
|
199
|
+
}));
|
|
215
200
|
|
|
216
201
|
const onPlayingChange = (value: boolean) => {
|
|
217
202
|
playing.value = value;
|
|
@@ -225,8 +210,8 @@ export default defineComponent({
|
|
|
225
210
|
emit('update:modelValue', endTimestamp.value);
|
|
226
211
|
};
|
|
227
212
|
|
|
228
|
-
watch(() =>
|
|
229
|
-
if(props.modelValue < startTimestamp.value || props.modelValue > endTimestamp.value) {
|
|
213
|
+
watch([() => props.startDate, () => props.endDate, () => props.modelValue], () => {
|
|
214
|
+
if(!props.modelValue || props.modelValue < startTimestamp.value || props.modelValue > endTimestamp.value) {
|
|
230
215
|
emit('update:modelValue', endTimestamp.value);
|
|
231
216
|
}
|
|
232
217
|
}, { immediate: true });
|
|
@@ -236,7 +221,7 @@ export default defineComponent({
|
|
|
236
221
|
clearInterval(playingInterval.value);
|
|
237
222
|
} else {
|
|
238
223
|
playingInterval.value = setInterval(() => {
|
|
239
|
-
if(props.modelValue + props.stepTime <= endTimestamp.value) {
|
|
224
|
+
if(props.modelValue && props.modelValue + props.stepTime <= endTimestamp.value) {
|
|
240
225
|
emit('update:modelValue', props.modelValue + props.stepTime);
|
|
241
226
|
} else {
|
|
242
227
|
emit('update:modelValue', endTimestamp.value);
|
|
@@ -251,10 +236,10 @@ export default defineComponent({
|
|
|
251
236
|
playing,
|
|
252
237
|
ColorEnum,
|
|
253
238
|
lightColors,
|
|
254
|
-
intervalTime,
|
|
255
239
|
endTimestamp,
|
|
240
|
+
TimePrecision,
|
|
241
|
+
tickPrecision,
|
|
256
242
|
startTimestamp,
|
|
257
|
-
maximumTickToShow,
|
|
258
243
|
epochToISO,
|
|
259
244
|
onPlayingChange,
|
|
260
245
|
onClickForward,
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FSMenu
|
|
3
|
+
:location="$props.location"
|
|
4
|
+
:closeOnContentClick="true"
|
|
5
|
+
:contained="false"
|
|
6
|
+
minWidth="0"
|
|
7
|
+
v-model="modelValue"
|
|
8
|
+
v-bind="$attrs"
|
|
9
|
+
>
|
|
10
|
+
<template
|
|
11
|
+
#activator="{ props }"
|
|
12
|
+
>
|
|
13
|
+
<slot
|
|
14
|
+
name="activator"
|
|
15
|
+
v-bind="props"
|
|
16
|
+
>
|
|
17
|
+
<FSButton
|
|
18
|
+
v-bind="props"
|
|
19
|
+
:icon="$props.icon"
|
|
20
|
+
:iconSize="$props.iconSize"
|
|
21
|
+
:color="$props.buttonColor"
|
|
22
|
+
:variant="$props.buttonVariant"
|
|
23
|
+
/>
|
|
24
|
+
</slot>
|
|
25
|
+
</template>
|
|
26
|
+
<FSCard
|
|
27
|
+
:maxWidth="$props.maxWidth"
|
|
28
|
+
:width="$props.width"
|
|
29
|
+
padding="2px"
|
|
30
|
+
:border="false"
|
|
31
|
+
:elevation="true"
|
|
32
|
+
align="center-center"
|
|
33
|
+
>
|
|
34
|
+
<slot
|
|
35
|
+
name="content"
|
|
36
|
+
>
|
|
37
|
+
<FSCol
|
|
38
|
+
gap="0px"
|
|
39
|
+
>
|
|
40
|
+
<FSFadeOut
|
|
41
|
+
:scrollOutside="false"
|
|
42
|
+
maxHeight="80dvh"
|
|
43
|
+
>
|
|
44
|
+
<FSClickable
|
|
45
|
+
v-for="(item, index) in $props.items"
|
|
46
|
+
width="100%"
|
|
47
|
+
padding="8px"
|
|
48
|
+
height="40px"
|
|
49
|
+
:key="index"
|
|
50
|
+
:border="false"
|
|
51
|
+
@click="onClickItem(item)"
|
|
52
|
+
>
|
|
53
|
+
<slot
|
|
54
|
+
name="item"
|
|
55
|
+
v-bind="{ item, index }"
|
|
56
|
+
>
|
|
57
|
+
<FSRow
|
|
58
|
+
align="center-left"
|
|
59
|
+
>
|
|
60
|
+
<FSIcon
|
|
61
|
+
v-if="item.icon"
|
|
62
|
+
:icon="item.icon"
|
|
63
|
+
/>
|
|
64
|
+
<FSText
|
|
65
|
+
font="text-body"
|
|
66
|
+
>
|
|
67
|
+
{{ item.label }}
|
|
68
|
+
</FSText>
|
|
69
|
+
</FSRow>
|
|
70
|
+
</slot>
|
|
71
|
+
</FSClickable>
|
|
72
|
+
</FSFadeOut>
|
|
73
|
+
</FSCol>
|
|
74
|
+
</slot>
|
|
75
|
+
</FSCard>
|
|
76
|
+
</FSMenu>
|
|
77
|
+
</template>
|
|
78
|
+
|
|
79
|
+
<script lang="ts">
|
|
80
|
+
import { defineComponent, ref, type PropType } from "vue";
|
|
81
|
+
|
|
82
|
+
import { useColors } from "@dative-gpi/foundation-shared-components/composables";
|
|
83
|
+
|
|
84
|
+
import { ColorEnum, type ColorBase } from '@dative-gpi/foundation-shared-components/models';
|
|
85
|
+
|
|
86
|
+
import FSRow from '@dative-gpi/foundation-shared-components/components/FSRow.vue';
|
|
87
|
+
import FSCol from '@dative-gpi/foundation-shared-components/components/FSCol.vue';
|
|
88
|
+
import FSIcon from '@dative-gpi/foundation-shared-components/components/FSIcon.vue';
|
|
89
|
+
import FSMenu from '@dative-gpi/foundation-shared-components/components/FSMenu.vue';
|
|
90
|
+
import FSCard from '@dative-gpi/foundation-shared-components/components/FSCard.vue';
|
|
91
|
+
import FSText from '@dative-gpi/foundation-shared-components/components/FSText.vue';
|
|
92
|
+
import FSButton from '@dative-gpi/foundation-shared-components/components/FSButton.vue';
|
|
93
|
+
import FSClickable from '@dative-gpi/foundation-shared-components/components/FSClickable.vue';
|
|
94
|
+
|
|
95
|
+
export default defineComponent({
|
|
96
|
+
name: "FSInformationsMenu",
|
|
97
|
+
components: {
|
|
98
|
+
FSMenu,
|
|
99
|
+
FSCard,
|
|
100
|
+
FSRow,
|
|
101
|
+
FSText,
|
|
102
|
+
FSButton,
|
|
103
|
+
FSCol,
|
|
104
|
+
FSIcon,
|
|
105
|
+
FSClickable
|
|
106
|
+
},
|
|
107
|
+
props: {
|
|
108
|
+
items: {
|
|
109
|
+
type: Array as PropType<{label: string, icon?: string, onClick: () => void, closeOnContentClick?: boolean}[]>,
|
|
110
|
+
default: () => []
|
|
111
|
+
},
|
|
112
|
+
location: {
|
|
113
|
+
type: String,
|
|
114
|
+
default: "bottom"
|
|
115
|
+
},
|
|
116
|
+
width: {
|
|
117
|
+
type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
|
|
118
|
+
default: null
|
|
119
|
+
},
|
|
120
|
+
maxWidth: {
|
|
121
|
+
type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
|
|
122
|
+
default: "90dvw"
|
|
123
|
+
},
|
|
124
|
+
icon: {
|
|
125
|
+
type: String,
|
|
126
|
+
default: "mdi-dots-horizontal"
|
|
127
|
+
},
|
|
128
|
+
iconSize: {
|
|
129
|
+
type: String,
|
|
130
|
+
default: "18px"
|
|
131
|
+
},
|
|
132
|
+
buttonColor: {
|
|
133
|
+
type: String as PropType<ColorBase>,
|
|
134
|
+
default: ColorEnum.Light
|
|
135
|
+
},
|
|
136
|
+
buttonVariant: {
|
|
137
|
+
type: String as PropType<"standard" | "full" | "icon">,
|
|
138
|
+
required: false,
|
|
139
|
+
default: "icon"
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
emits: ["update:modelValue"],
|
|
143
|
+
setup() {
|
|
144
|
+
const modelValue = ref(false);
|
|
145
|
+
|
|
146
|
+
const { getColors } = useColors();
|
|
147
|
+
|
|
148
|
+
const lightColors = getColors(ColorEnum.Light);
|
|
149
|
+
|
|
150
|
+
const onClickItem = (item: { onClick: () => void, closeOnContentClick?: boolean }) => {
|
|
151
|
+
item.onClick();
|
|
152
|
+
if (item.closeOnContentClick !== false) {
|
|
153
|
+
modelValue.value = false;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
ColorEnum,
|
|
159
|
+
modelValue,
|
|
160
|
+
lightColors,
|
|
161
|
+
onClickItem
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
</script>
|
|
@@ -0,0 +1,261 @@
|
|
|
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
|
+
:maxWidth="$props.maxWidth"
|
|
9
|
+
>
|
|
10
|
+
<FSRow
|
|
11
|
+
align="bottom-center"
|
|
12
|
+
gap="32px"
|
|
13
|
+
>
|
|
14
|
+
<FSTermField
|
|
15
|
+
width="430px"
|
|
16
|
+
:label="$tr('ui.instant-picker.analyze-period', 'Analyze Period')"
|
|
17
|
+
:startDate="$props.startDate"
|
|
18
|
+
:endDate="$props.endDate"
|
|
19
|
+
:disabled="$props.disabled"
|
|
20
|
+
@update:startDate="$emit('update:startDate', $event)"
|
|
21
|
+
@update:endDate="$emit('update:endDate', $event)"
|
|
22
|
+
/>
|
|
23
|
+
<FSRow
|
|
24
|
+
padding="0 0 2px 0"
|
|
25
|
+
align="center-center"
|
|
26
|
+
>
|
|
27
|
+
<FSCol>
|
|
28
|
+
<FSRangeSlider
|
|
29
|
+
minWidth='min(300px, 90vw)'
|
|
30
|
+
:disabled="$props.disabled"
|
|
31
|
+
:color="ColorEnum.Light"
|
|
32
|
+
:thumbColor="ColorEnum.Primary"
|
|
33
|
+
:trackFillColor="ColorEnum.Primary"
|
|
34
|
+
:trackSize="8"
|
|
35
|
+
thumb-label="always"
|
|
36
|
+
:step="$props.stepTime"
|
|
37
|
+
:min="startTimestamp"
|
|
38
|
+
:max="endTimestamp"
|
|
39
|
+
:ticks="ticks"
|
|
40
|
+
showTicks="always"
|
|
41
|
+
:modelValue="$props.modelValue"
|
|
42
|
+
@update:modelValue="$emit('update:modelValue', $event)"
|
|
43
|
+
>
|
|
44
|
+
<template
|
|
45
|
+
#thumb-label="{ modelValue }"
|
|
46
|
+
>
|
|
47
|
+
<FSSpan
|
|
48
|
+
font="text-overline"
|
|
49
|
+
>
|
|
50
|
+
{{ epochToMonthShortTimeFormat(modelValue) }}
|
|
51
|
+
</FSSpan>
|
|
52
|
+
</template>
|
|
53
|
+
<template
|
|
54
|
+
#tick-label="{ tick }"
|
|
55
|
+
>
|
|
56
|
+
<FSRow>
|
|
57
|
+
<FSText
|
|
58
|
+
:color="lightColors.dark"
|
|
59
|
+
font="text-overline"
|
|
60
|
+
>
|
|
61
|
+
{{ tickPrecision === TimePrecision.Hours ? epochToShortTimeOnlyFormat(tick.value) : epochToDayMonthShortOnly(tick.value) }}
|
|
62
|
+
</FSText>
|
|
63
|
+
</FSRow>
|
|
64
|
+
</template>
|
|
65
|
+
</FSRangeSlider>
|
|
66
|
+
</FSCol>
|
|
67
|
+
<FSPlayButtons
|
|
68
|
+
v-if="$props.playable"
|
|
69
|
+
:disabled="$props.disabled"
|
|
70
|
+
:modelValue="playing"
|
|
71
|
+
@click:backward="onClickBackward"
|
|
72
|
+
@click:forward="onClickForward"
|
|
73
|
+
@update:modelValue="onPlayingChange"
|
|
74
|
+
/>
|
|
75
|
+
</FSRow>
|
|
76
|
+
</FSRow>
|
|
77
|
+
</FSBaseField>
|
|
78
|
+
</template>
|
|
79
|
+
|
|
80
|
+
<script lang="ts">
|
|
81
|
+
import { computed, defineComponent, ref, watch, type PropType } from "vue";
|
|
82
|
+
|
|
83
|
+
import { useBreakpoints, useColors } from '@dative-gpi/foundation-shared-components/composables';
|
|
84
|
+
import { useDateFormat, useDateExpression } from "@dative-gpi/foundation-shared-services/composables";
|
|
85
|
+
|
|
86
|
+
import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
87
|
+
import { computeTicks, TimePrecision } from '@dative-gpi/foundation-shared-components/utils';
|
|
88
|
+
|
|
89
|
+
import FSCol from '@dative-gpi/foundation-shared-components/components/FSCol.vue';
|
|
90
|
+
import FSSpan from '@dative-gpi/foundation-shared-components/components/FSSpan.vue';
|
|
91
|
+
import FSText from '@dative-gpi/foundation-shared-components/components/FSText.vue';
|
|
92
|
+
import FSPlayButtons from '@dative-gpi/foundation-shared-components/components/FSPlayButtons.vue';
|
|
93
|
+
import FSRangeSlider from '@dative-gpi/foundation-shared-components/components/FSRangeSlider.vue';
|
|
94
|
+
import FSBaseField from '@dative-gpi/foundation-shared-components/components/fields/FSBaseField.vue';
|
|
95
|
+
import FSTermField from '@dative-gpi/foundation-shared-components/components/fields/FSTermField.vue';
|
|
96
|
+
|
|
97
|
+
export default defineComponent({
|
|
98
|
+
name: "FSRangePicker",
|
|
99
|
+
components: {
|
|
100
|
+
FSCol,
|
|
101
|
+
FSSpan,
|
|
102
|
+
FSText,
|
|
103
|
+
FSTermField,
|
|
104
|
+
FSBaseField,
|
|
105
|
+
FSRangeSlider,
|
|
106
|
+
FSPlayButtons,
|
|
107
|
+
},
|
|
108
|
+
props: {
|
|
109
|
+
label: {
|
|
110
|
+
type: String,
|
|
111
|
+
required: false,
|
|
112
|
+
},
|
|
113
|
+
mode: {
|
|
114
|
+
type: String as () => 'single' | 'range',
|
|
115
|
+
required: false,
|
|
116
|
+
default: 'single'
|
|
117
|
+
},
|
|
118
|
+
modelValue: {
|
|
119
|
+
type: Object as () => [number, number],
|
|
120
|
+
required: true
|
|
121
|
+
},
|
|
122
|
+
startDate: {
|
|
123
|
+
type: String,
|
|
124
|
+
required: true
|
|
125
|
+
},
|
|
126
|
+
endDate: {
|
|
127
|
+
type: String,
|
|
128
|
+
required: true
|
|
129
|
+
},
|
|
130
|
+
description: {
|
|
131
|
+
type: String,
|
|
132
|
+
required: false,
|
|
133
|
+
default: null
|
|
134
|
+
},
|
|
135
|
+
hideHeader: {
|
|
136
|
+
type: Boolean,
|
|
137
|
+
required: false,
|
|
138
|
+
default: false
|
|
139
|
+
},
|
|
140
|
+
required: {
|
|
141
|
+
type: Boolean,
|
|
142
|
+
required: false,
|
|
143
|
+
default: false
|
|
144
|
+
},
|
|
145
|
+
disabled: {
|
|
146
|
+
type: Boolean,
|
|
147
|
+
required: false,
|
|
148
|
+
default: false
|
|
149
|
+
},
|
|
150
|
+
playable: {
|
|
151
|
+
type: Boolean,
|
|
152
|
+
required: false,
|
|
153
|
+
default: true
|
|
154
|
+
},
|
|
155
|
+
stepTime: {
|
|
156
|
+
type: Number,
|
|
157
|
+
required: false,
|
|
158
|
+
default: 60000
|
|
159
|
+
},
|
|
160
|
+
playingStepDuration: {
|
|
161
|
+
type: Number,
|
|
162
|
+
required: false,
|
|
163
|
+
default: 50
|
|
164
|
+
},
|
|
165
|
+
maxWidth: {
|
|
166
|
+
type: String as PropType<string | null>,
|
|
167
|
+
required: false,
|
|
168
|
+
default: null
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
emits: ['update:modelValue', 'update:startDate', 'update:endDate'],
|
|
172
|
+
setup(props, { emit }) {
|
|
173
|
+
const { epochToShortTimeOnlyFormat, epochToShortDateFormat, epochToDayMonthShortOnly, epochToISO, epochToMonthShortTimeFormat } = useDateFormat();
|
|
174
|
+
const { convert : convertTermToEpoch } = useDateExpression();
|
|
175
|
+
const { isMobileSized, isExtraSmall } = useBreakpoints();
|
|
176
|
+
const { getColors } = useColors();
|
|
177
|
+
|
|
178
|
+
const lightColors = getColors(ColorEnum.Light);
|
|
179
|
+
const playing = ref(false);
|
|
180
|
+
const playingInterval = ref();
|
|
181
|
+
|
|
182
|
+
const startTimestamp = computed(() => convertTermToEpoch(props.startDate));
|
|
183
|
+
const endTimestamp = computed(() => convertTermToEpoch(props.endDate));
|
|
184
|
+
|
|
185
|
+
const tickCount = computed(() => {
|
|
186
|
+
if (isExtraSmall.value) { return 3; }
|
|
187
|
+
if (isMobileSized.value) { return 4; }
|
|
188
|
+
return 5;
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const tickPrecision = computed(() => {
|
|
192
|
+
const rangeDuration = endTimestamp.value - startTimestamp.value;
|
|
193
|
+
if (rangeDuration <= 86400000 * tickCount.value) { return TimePrecision.Hours; }
|
|
194
|
+
if (rangeDuration <= 2592000000 * tickCount.value) { return TimePrecision.Days; }
|
|
195
|
+
return TimePrecision.Months;
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Génération des ticks via la fonction utilitaire
|
|
199
|
+
const ticks = computed(() => computeTicks({
|
|
200
|
+
start: startTimestamp.value,
|
|
201
|
+
end: endTimestamp.value,
|
|
202
|
+
tickCount: tickCount.value,
|
|
203
|
+
precision: tickPrecision.value
|
|
204
|
+
}));
|
|
205
|
+
|
|
206
|
+
const onPlayingChange = (value: boolean) => {
|
|
207
|
+
playing.value = value;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const onClickBackward = () => {
|
|
211
|
+
const modelValueDuration = props.modelValue[1] - props.modelValue[0];
|
|
212
|
+
emit('update:modelValue', [startTimestamp.value, startTimestamp.value + modelValueDuration]);
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
const onClickForward = () => {
|
|
216
|
+
const modelValueDuration = props.modelValue[1] - props.modelValue[0];
|
|
217
|
+
emit('update:modelValue', [endTimestamp.value - modelValueDuration, endTimestamp.value]);
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
watch([() => props.startDate, () => props.endDate, () => props.modelValue], () => {
|
|
221
|
+
if((props.modelValue[0] < startTimestamp.value || props.modelValue[1] > endTimestamp.value)) {
|
|
222
|
+
emit('update:modelValue', [startTimestamp.value, endTimestamp.value]);
|
|
223
|
+
}
|
|
224
|
+
}, { immediate: true });
|
|
225
|
+
|
|
226
|
+
watch(playing, (value) => {
|
|
227
|
+
if(!value && playingInterval.value) {
|
|
228
|
+
clearInterval(playingInterval.value);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
playingInterval.value = setInterval(() => {
|
|
233
|
+
if(props.modelValue[0] + props.stepTime <= endTimestamp.value && props.modelValue[1] + props.stepTime <= endTimestamp.value) {
|
|
234
|
+
emit('update:modelValue', [props.modelValue[0] + props.stepTime, props.modelValue[1] + props.stepTime]);
|
|
235
|
+
} else {
|
|
236
|
+
playing.value = false;
|
|
237
|
+
}
|
|
238
|
+
}, props.playingStepDuration);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
ticks,
|
|
243
|
+
playing,
|
|
244
|
+
ColorEnum,
|
|
245
|
+
lightColors,
|
|
246
|
+
endTimestamp,
|
|
247
|
+
TimePrecision,
|
|
248
|
+
tickPrecision,
|
|
249
|
+
startTimestamp,
|
|
250
|
+
epochToISO,
|
|
251
|
+
onPlayingChange,
|
|
252
|
+
onClickForward,
|
|
253
|
+
onClickBackward,
|
|
254
|
+
epochToShortDateFormat,
|
|
255
|
+
epochToShortTimeOnlyFormat,
|
|
256
|
+
epochToDayMonthShortOnly,
|
|
257
|
+
epochToMonthShortTimeFormat
|
|
258
|
+
};
|
|
259
|
+
},
|
|
260
|
+
});
|
|
261
|
+
</script>
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FSBaseField
|
|
3
|
+
:label="$props.label"
|
|
4
|
+
:description="$props.description"
|
|
5
|
+
:required="$props.required"
|
|
6
|
+
:disabled="$props.disabled"
|
|
7
|
+
>
|
|
8
|
+
<FSRow>
|
|
9
|
+
<v-range-slider
|
|
10
|
+
hide-details
|
|
11
|
+
width="100%"
|
|
12
|
+
:disabled="$props.disabled"
|
|
13
|
+
:ripple="false"
|
|
14
|
+
:color="$props.color"
|
|
15
|
+
:trackSize="6"
|
|
16
|
+
:elevation="0"
|
|
17
|
+
:tickSize="4"
|
|
18
|
+
:modelValue="$props.modelValue ?? undefined"
|
|
19
|
+
@update:modelValue="$emit('update:modelValue', $event)"
|
|
20
|
+
v-bind="$attrs"
|
|
21
|
+
>
|
|
22
|
+
<template
|
|
23
|
+
v-for="(_, name) in $slots"
|
|
24
|
+
v-slot:[name]="slotData"
|
|
25
|
+
>
|
|
26
|
+
<slot
|
|
27
|
+
:name="name"
|
|
28
|
+
v-bind="slotData"
|
|
29
|
+
/>
|
|
30
|
+
</template>
|
|
31
|
+
</v-range-slider>
|
|
32
|
+
</FSRow>
|
|
33
|
+
</FSBaseField>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script lang="ts">
|
|
37
|
+
import { defineComponent, type PropType } from "vue";
|
|
38
|
+
|
|
39
|
+
import { type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
40
|
+
|
|
41
|
+
import FSRow from '@dative-gpi/foundation-shared-components/components/FSRow.vue';
|
|
42
|
+
import FSBaseField from '@dative-gpi/foundation-shared-components/components/fields/FSBaseField.vue';
|
|
43
|
+
|
|
44
|
+
export default defineComponent({
|
|
45
|
+
name: "FSRangeSlider",
|
|
46
|
+
components: {
|
|
47
|
+
FSBaseField,
|
|
48
|
+
FSRow
|
|
49
|
+
},
|
|
50
|
+
props: {
|
|
51
|
+
label: {
|
|
52
|
+
type: String as PropType<string | null>,
|
|
53
|
+
required: false,
|
|
54
|
+
default: null
|
|
55
|
+
},
|
|
56
|
+
description: {
|
|
57
|
+
type: String as PropType<string | null>,
|
|
58
|
+
required: false,
|
|
59
|
+
default: null
|
|
60
|
+
},
|
|
61
|
+
modelValue: {
|
|
62
|
+
type: Object as PropType<[number, number] | null>,
|
|
63
|
+
required: false,
|
|
64
|
+
default: null
|
|
65
|
+
},
|
|
66
|
+
color: {
|
|
67
|
+
type: String as PropType<ColorBase>,
|
|
68
|
+
required: false,
|
|
69
|
+
default: ColorEnum.Dark
|
|
70
|
+
},
|
|
71
|
+
required: {
|
|
72
|
+
type: Boolean,
|
|
73
|
+
required: false,
|
|
74
|
+
default: false
|
|
75
|
+
},
|
|
76
|
+
disabled: {
|
|
77
|
+
type: Boolean,
|
|
78
|
+
required: false,
|
|
79
|
+
default: false
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
emits: ["update:modelValue"]
|
|
83
|
+
});
|
|
84
|
+
</script>
|
package/components/FSSlider.vue
CHANGED
|
@@ -1,85 +1,55 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
<FSBaseField
|
|
3
|
+
:label="$props.label"
|
|
4
|
+
:description="$props.description"
|
|
5
|
+
:required="$props.required"
|
|
6
|
+
:disabled="$props.disabled"
|
|
7
|
+
:style="style"
|
|
8
|
+
>
|
|
9
|
+
<FSRow>
|
|
10
|
+
<v-slider
|
|
11
|
+
hide-details
|
|
12
|
+
class="fs-slider"
|
|
13
|
+
width="100%"
|
|
14
|
+
:color="$props.color"
|
|
15
|
+
:disabled="$props.disabled"
|
|
16
|
+
:ripple="false"
|
|
17
|
+
:trackSize="6"
|
|
18
|
+
:elevation="0"
|
|
19
|
+
:tickSize="4"
|
|
20
|
+
:modelValue="$props.modelValue ?? undefined"
|
|
21
|
+
@update:modelValue="$emit('update:modelValue', $event)"
|
|
22
|
+
v-bind="$attrs"
|
|
8
23
|
>
|
|
9
|
-
<
|
|
10
|
-
v-
|
|
11
|
-
|
|
12
|
-
font="text-overline"
|
|
13
|
-
:style="style"
|
|
24
|
+
<template
|
|
25
|
+
v-for="(_, name) in $slots"
|
|
26
|
+
v-slot:[name]="slotData"
|
|
14
27
|
>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
:style="style"
|
|
24
|
-
>
|
|
25
|
-
*
|
|
26
|
-
</FSSpan>
|
|
27
|
-
</FSRow>
|
|
28
|
-
</slot>
|
|
29
|
-
<v-slider
|
|
30
|
-
class="fs-slider"
|
|
31
|
-
hide-details
|
|
32
|
-
:disabled="$props.disabled"
|
|
33
|
-
:ripple="false"
|
|
34
|
-
:style="style"
|
|
35
|
-
:elevation="0"
|
|
36
|
-
:tickSize="4"
|
|
37
|
-
:modelValue="$props.modelValue ?? undefined"
|
|
38
|
-
@update:modelValue="$emit('update:modelValue', $event)"
|
|
39
|
-
v-bind="$attrs"
|
|
40
|
-
>
|
|
41
|
-
<template
|
|
42
|
-
v-for="(_, name) in $slots"
|
|
43
|
-
v-slot:[name]="slotData"
|
|
44
|
-
>
|
|
45
|
-
<slot
|
|
46
|
-
:name="name"
|
|
47
|
-
v-bind="slotData"
|
|
48
|
-
/>
|
|
49
|
-
</template>
|
|
50
|
-
</v-slider>
|
|
51
|
-
<slot
|
|
52
|
-
name="description"
|
|
53
|
-
>
|
|
54
|
-
<FSSpan
|
|
55
|
-
v-if="$props.description"
|
|
56
|
-
class="fs-slider-description"
|
|
57
|
-
font="text-overline"
|
|
58
|
-
:lineClamp="2"
|
|
59
|
-
:style="style"
|
|
60
|
-
>
|
|
61
|
-
{{ $props.description }}
|
|
62
|
-
</FSSpan>
|
|
63
|
-
</slot>
|
|
64
|
-
</FSCol>
|
|
28
|
+
<slot
|
|
29
|
+
:name="name"
|
|
30
|
+
v-bind="slotData"
|
|
31
|
+
/>
|
|
32
|
+
</template>
|
|
33
|
+
</v-slider>
|
|
34
|
+
</FSRow>
|
|
35
|
+
</FSBaseField>
|
|
65
36
|
</template>
|
|
66
37
|
|
|
67
38
|
<script lang="ts">
|
|
68
39
|
import { computed, defineComponent, type PropType, type StyleValue } from "vue";
|
|
69
40
|
|
|
41
|
+
import { useColors } from '@dative-gpi/foundation-shared-components/composables';
|
|
42
|
+
|
|
70
43
|
import { type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
71
|
-
import { useColors } from "@dative-gpi/foundation-shared-components/composables";
|
|
72
44
|
|
|
73
|
-
import
|
|
74
|
-
import
|
|
75
|
-
import FSRow from "./FSRow.vue";
|
|
45
|
+
import FSRow from '@dative-gpi/foundation-shared-components/components/FSRow.vue';
|
|
46
|
+
import FSBaseField from '@dative-gpi/foundation-shared-components/components/fields/FSBaseField.vue';
|
|
76
47
|
|
|
77
48
|
export default defineComponent({
|
|
78
49
|
name: "FSSlider",
|
|
79
50
|
components: {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
FSRow
|
|
51
|
+
FSRow,
|
|
52
|
+
FSBaseField
|
|
83
53
|
},
|
|
84
54
|
props: {
|
|
85
55
|
label: {
|
|
@@ -118,26 +88,20 @@ export default defineComponent({
|
|
|
118
88
|
|
|
119
89
|
const colors = computed(() => getColors(props.color));
|
|
120
90
|
const lights = getColors(ColorEnum.Light);
|
|
121
|
-
const darks = getColors(ColorEnum.Dark);
|
|
122
91
|
|
|
123
92
|
const style = computed((): StyleValue => {
|
|
124
93
|
if (props.disabled) {
|
|
125
94
|
return {
|
|
126
|
-
"--fs-slider-
|
|
127
|
-
"--fs-slider-track-color": lights.base,
|
|
128
|
-
"--fs-slider-thumb-color": lights.base,
|
|
129
|
-
"--fs-slider-color" : lights.dark
|
|
95
|
+
"--fs-slider-thumb-color": lights.base
|
|
130
96
|
};
|
|
131
97
|
}
|
|
132
98
|
return {
|
|
133
|
-
"--fs-slider-
|
|
134
|
-
"--fs-slider-track-color": colors.value.light,
|
|
135
|
-
"--fs-slider-thumb-color": colors.value.base,
|
|
136
|
-
"--fs-slider-color" : darks.base
|
|
99
|
+
"--fs-slider-thumb-color": colors.value.base
|
|
137
100
|
};
|
|
138
101
|
});
|
|
139
102
|
|
|
140
103
|
return {
|
|
104
|
+
colors,
|
|
141
105
|
style
|
|
142
106
|
};
|
|
143
107
|
}
|
|
@@ -17,19 +17,24 @@
|
|
|
17
17
|
align="top-left"
|
|
18
18
|
>
|
|
19
19
|
<FSRow
|
|
20
|
-
v-if="$props.showSearch ||
|
|
20
|
+
v-if="$props.showSearch || $slots['toolbar']"
|
|
21
21
|
align="bottom-left"
|
|
22
22
|
>
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
<template
|
|
24
|
+
v-if="$props.showSearch"
|
|
25
|
+
>
|
|
26
|
+
<FSSearchField
|
|
27
|
+
v-if="$props.showSearch"
|
|
28
|
+
:hideHeader="true"
|
|
29
|
+
v-model="innerSearch"
|
|
30
|
+
/>
|
|
31
|
+
<FSButton
|
|
32
|
+
v-if="filterableHeaders.length > 0"
|
|
33
|
+
prependIcon="mdi-filter-variant"
|
|
34
|
+
:variant="innerShowFilters ? 'full' : 'standard'"
|
|
35
|
+
@click="innerShowFilters = !innerShowFilters"
|
|
36
|
+
/>
|
|
37
|
+
</template>
|
|
33
38
|
<slot
|
|
34
39
|
v-if="!isMobileSized"
|
|
35
40
|
name="toolbar"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dative-gpi/foundation-shared-components",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.163-notification",
|
|
5
5
|
"description": "",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"author": "",
|
|
11
11
|
"license": "ISC",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@dative-gpi/foundation-shared-domain": "1.0.
|
|
14
|
-
"@dative-gpi/foundation-shared-services": "1.0.
|
|
13
|
+
"@dative-gpi/foundation-shared-domain": "1.0.163-notification",
|
|
14
|
+
"@dative-gpi/foundation-shared-services": "1.0.163-notification"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
17
|
"@dative-gpi/bones-ui": "^1.0.0",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"sass": "1.71.1",
|
|
36
36
|
"sass-loader": "13.3.2"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "ba817255c72600f95a231534932c34cb648fd192"
|
|
39
39
|
}
|
|
@@ -1,50 +1,10 @@
|
|
|
1
1
|
.fs-slider {
|
|
2
|
-
padding: 0px !important;
|
|
3
|
-
width: calc(100% - 16px);
|
|
4
|
-
|
|
5
|
-
& .v-slider__container {
|
|
6
|
-
cursor: var(--fs-slider-cursor);
|
|
7
|
-
margin-left: 8px;
|
|
8
|
-
margin-right: 8px;
|
|
9
|
-
opacity: 1 !important;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
& .v-slider-track__background {
|
|
13
|
-
background-color: var(--fs-slider-track-color);
|
|
14
|
-
height: 6px !important;
|
|
15
|
-
opacity: 1;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
2
|
& .v-slider-track__fill {
|
|
19
3
|
display: none;
|
|
20
4
|
}
|
|
21
5
|
|
|
22
6
|
& .v-slider-track__tick {
|
|
23
7
|
background-color: var(--fs-slider-thumb-color);
|
|
24
|
-
border-radius: 50%;
|
|
25
8
|
}
|
|
26
9
|
|
|
27
|
-
& .v-slider-thumb {
|
|
28
|
-
color: var(--fs-slider-thumb-color);
|
|
29
|
-
|
|
30
|
-
&__surface:before {
|
|
31
|
-
display: none !important;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
&__surface:after {
|
|
35
|
-
display: none !important;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
&__ripple {
|
|
39
|
-
display: none !important;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.fs-slider-label {
|
|
45
|
-
color: var(--fs-slider-color);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.fs-slider-description {
|
|
49
|
-
color: var(--fs-slider-color);
|
|
50
10
|
}
|
package/tools/alertsTools.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
|
|
2
2
|
import { AlertStatus, Criticity } from "@dative-gpi/foundation-shared-domain/enums";
|
|
3
|
-
import { ColorEnum } from "../models"
|
|
3
|
+
import { ColorEnum } from "../models";
|
|
4
4
|
import { getTimeBestString } from "../utils";
|
|
5
5
|
|
|
6
6
|
const { $tr } = useTranslationsProvider();
|
|
@@ -8,12 +8,12 @@ const { $tr } = useTranslationsProvider();
|
|
|
8
8
|
export const AlertTools = {
|
|
9
9
|
statusIcon(value: AlertStatus): string {
|
|
10
10
|
switch (value) {
|
|
11
|
-
case AlertStatus.Pending: return "mdi-timer-
|
|
12
|
-
case AlertStatus.Untriggered: return "mdi-
|
|
13
|
-
case AlertStatus.Unresolved: return "mdi-
|
|
14
|
-
case AlertStatus.Resolved: return "mdi-check-circle
|
|
15
|
-
case AlertStatus.Expired: return "mdi-clock-outline";
|
|
16
|
-
case AlertStatus.Triggered: return "mdi-
|
|
11
|
+
case AlertStatus.Pending: return "mdi-timer-sand";
|
|
12
|
+
case AlertStatus.Untriggered: return "mdi-close-octagon";
|
|
13
|
+
case AlertStatus.Unresolved: return "mdi-cancel";
|
|
14
|
+
case AlertStatus.Resolved: return "mdi-check-circle";
|
|
15
|
+
case AlertStatus.Expired: return "mdi-timeline-clock-outline";
|
|
16
|
+
case AlertStatus.Triggered: return "mdi-timer-sand";
|
|
17
17
|
case AlertStatus.Abandoned: return "mdi-cancel"
|
|
18
18
|
default: return "";
|
|
19
19
|
}
|
|
@@ -82,10 +82,11 @@ export const AlertTools = {
|
|
|
82
82
|
},
|
|
83
83
|
statusColor(status: AlertStatus): ColorEnum {
|
|
84
84
|
switch (status) {
|
|
85
|
-
case AlertStatus.None:
|
|
86
85
|
case AlertStatus.Pending:
|
|
87
|
-
case AlertStatus.Expired:
|
|
88
86
|
return ColorEnum.Warning;
|
|
87
|
+
case AlertStatus.Expired:
|
|
88
|
+
case AlertStatus.Abandoned:
|
|
89
|
+
return ColorEnum.Dark;
|
|
89
90
|
case AlertStatus.Unresolved:
|
|
90
91
|
case AlertStatus.Triggered:
|
|
91
92
|
return ColorEnum.Error;
|
package/utils/index.ts
CHANGED
package/utils/picker.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export enum TimePrecision {
|
|
2
|
+
Hours = 1,
|
|
3
|
+
Days = 2,
|
|
4
|
+
Months = 3
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Compute ticks for a time range based on the specified precision.
|
|
9
|
+
*/
|
|
10
|
+
export const computeTicks = ({ start, end, tickCount, precision }: { start: number, end: number, tickCount: number, precision: TimePrecision }): number[] => {
|
|
11
|
+
const ticks: number[] = [];
|
|
12
|
+
const range = end - start;
|
|
13
|
+
|
|
14
|
+
if (precision === TimePrecision.Hours) {
|
|
15
|
+
// Tick toutes les X heures, aligné sur l'heure pleine
|
|
16
|
+
const step = Math.ceil(range / tickCount / 3600000) * 3600000;
|
|
17
|
+
const alignedStart = Math.ceil(start / 3600000) * 3600000;
|
|
18
|
+
for (let i = 0; i < tickCount; i++) {
|
|
19
|
+
const tick = alignedStart + i * step;
|
|
20
|
+
if (tick < end) { ticks.push(tick); }
|
|
21
|
+
}
|
|
22
|
+
} else if (precision === TimePrecision.Days) {
|
|
23
|
+
// Tick tous les X jours, aligné sur minuit
|
|
24
|
+
const step = Math.ceil(range / tickCount / 86400000) * 86400000;
|
|
25
|
+
const date = new Date(start);
|
|
26
|
+
date.setHours(0, 0, 0, 0);
|
|
27
|
+
const alignedStart = date.getTime() + (date.getTime() < start ? step : 0);
|
|
28
|
+
for (let i = 0; i < tickCount; i++) {
|
|
29
|
+
const tick = alignedStart + i * step;
|
|
30
|
+
if (tick < end) { ticks.push(tick); }
|
|
31
|
+
}
|
|
32
|
+
} else {
|
|
33
|
+
// Tick tous les X mois (approximation linéaire)
|
|
34
|
+
const interval = range / tickCount;
|
|
35
|
+
for (let i = 0; i < tickCount; i++) {
|
|
36
|
+
ticks.push(start + i * interval);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return ticks;
|
|
40
|
+
}
|