@dative-gpi/foundation-shared-services 0.0.230 → 0.1.68
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/composables/app/index.ts +1 -1
- package/composables/app/useAppAuthToken.ts +17 -0
- package/composables/app/useAppLanguages.ts +2 -2
- package/composables/app/useAppTimeZone.ts +39 -260
- package/composables/index.ts +2 -1
- package/composables/services/index.ts +1 -0
- package/composables/services/useImages.ts +8 -7
- package/composables/services/useNotifications.ts +41 -0
- package/composables/useDateFormat.ts +220 -0
- package/config/index.ts +1 -0
- package/config/literals/hubs.ts +16 -0
- package/config/literals/index.ts +1 -0
- package/config/urls/base.ts +3 -1
- package/config/urls/images.ts +15 -9
- package/config/urls/index.ts +1 -0
- package/config/urls/notifications.ts +6 -0
- package/package.json +3 -3
- package/tools/hubFactory.ts +6 -1
- package/tools/index.ts +2 -1
- package/tools/translate.ts +17 -0
- package/composables/app/useExtensionJwt.ts +0 -17
package/composables/app/index.ts
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { computed, ref } from "vue";
|
|
2
|
+
|
|
3
|
+
const authToken = ref<string | undefined>(undefined);
|
|
4
|
+
|
|
5
|
+
export const useAppAuthToken = () => {
|
|
6
|
+
const setAppAuthToken = (payload: string) => {
|
|
7
|
+
authToken.value = payload;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const ready = computed(() => authToken.value !== null);
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
authToken,
|
|
14
|
+
ready,
|
|
15
|
+
setAppAuthToken
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -5,7 +5,7 @@ import { type LanguageInfos } from "@dative-gpi/foundation-shared-domain/models"
|
|
|
5
5
|
const languages = ref<LanguageInfos[] | undefined>(undefined);
|
|
6
6
|
|
|
7
7
|
export const useAppLanguages = () => {
|
|
8
|
-
const
|
|
8
|
+
const setAppLanguages = (payload: LanguageInfos[]) => {
|
|
9
9
|
languages.value = payload;
|
|
10
10
|
};
|
|
11
11
|
|
|
@@ -14,6 +14,6 @@ export const useAppLanguages = () => {
|
|
|
14
14
|
return {
|
|
15
15
|
ready,
|
|
16
16
|
languages,
|
|
17
|
-
|
|
17
|
+
setAppLanguages
|
|
18
18
|
};
|
|
19
19
|
}
|
|
@@ -1,265 +1,56 @@
|
|
|
1
|
-
import { format, subDays, addDays, addMilliseconds, parse } from "date-fns";
|
|
2
|
-
import type { Locale } from "date-fns/locale";
|
|
3
|
-
import { enUS, enGB, fr, it, es, de } from "date-fns/locale";
|
|
4
1
|
import { computed, ref } from "vue";
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
import type { TimeZoneInfos } from "@dative-gpi/foundation-shared-domain/models";
|
|
8
|
-
import { isoTimeFormat } from "@dative-gpi/foundation-shared-domain/tools";
|
|
9
|
-
|
|
10
|
-
import { useAppLanguageCode } from "./useAppLanguageCode";
|
|
11
|
-
|
|
12
|
-
const timeZone = ref<TimeZoneInfos | null>(null);
|
|
3
|
+
const timeZone = ref<string | undefined>(undefined);
|
|
13
4
|
|
|
14
5
|
export const useAppTimeZone = () => {
|
|
15
|
-
const setAppTimeZone = (payload:
|
|
6
|
+
const setAppTimeZone = (payload: string) => {
|
|
16
7
|
timeZone.value = payload;
|
|
17
8
|
};
|
|
18
9
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
case "utc-08:00:00": offset = -8; break;
|
|
26
|
-
case "utc-07:00:00": offset = -7; break;
|
|
27
|
-
case "utc-06:00:00": offset = -6; break;
|
|
28
|
-
case "utc-05:00:00": offset = -5; break;
|
|
29
|
-
case "utc-04:00:00": offset = -4; break;
|
|
30
|
-
case "utc-03:00:00": offset = -3; break;
|
|
31
|
-
case "utc-02:00:00": offset = -2; break;
|
|
32
|
-
case "utc-01:00:00": offset = -1; break;
|
|
33
|
-
case "utc+01:00:00": offset = +1; break;
|
|
34
|
-
case "utc+02:00:00": offset = +2; break;
|
|
35
|
-
case "utc+03:00:00": offset = +3; break;
|
|
36
|
-
case "utc+04:00:00": offset = +4; break;
|
|
37
|
-
case "utc+05:00:00": offset = +5; break;
|
|
38
|
-
case "utc+06:00:00": offset = +6; break;
|
|
39
|
-
case "utc+07:00:00": offset = +7; break;
|
|
40
|
-
case "utc+08:00:00": offset = +8; break;
|
|
41
|
-
case "utc+09:00:00": offset = +9; break;
|
|
42
|
-
case "utc+10:00:00": offset = +10; break;
|
|
43
|
-
case "utc+11:00:00": offset = +11; break;
|
|
44
|
-
case "utc+12:00:00": offset = +12; break;
|
|
45
|
-
case "utc+13:00:00": offset = +13; break;
|
|
46
|
-
case "utc+14:00:00": offset = +14; break;
|
|
47
|
-
}
|
|
48
|
-
return hours ? offset : offset * 60 * 60 * 1000;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const userOffset = (): number => {
|
|
52
|
-
return getOffsetNumber(getUserOffset());
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const machineOffset = (): number => {
|
|
56
|
-
return getOffsetNumber(getMachineOffset());
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const getUserOffset = (): string => {
|
|
60
|
-
return timeZone?.value?.offset ?? "UTC +00:00:00";
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const getUserOffsetMillis = (): number => {
|
|
64
|
-
const offset = timeZone?.value?.offset.slice(3) ?? "";
|
|
65
|
-
const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
|
|
66
|
-
if (matchData) {
|
|
67
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
68
|
-
const [_, sign, hour, minute] = matchData;
|
|
69
|
-
return parseInt(sign + "1") * ((hour ? parseInt(hour) : 0) * 60 + (minute ? parseInt(minute) : 0)) * 60 * 1000;
|
|
70
|
-
}
|
|
71
|
-
return 0;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const getMachineOffset = (): string => {
|
|
75
|
-
const timeZoneName = Intl.DateTimeFormat("ia", {
|
|
76
|
-
timeZoneName: "short",
|
|
77
|
-
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
78
|
-
}).formatToParts().find((i) => i.type === "timeZoneName")?.value ?? "";
|
|
79
|
-
|
|
80
|
-
const offset = timeZoneName.slice(3);
|
|
81
|
-
if (!offset) {
|
|
82
|
-
return "UTC +00:00:00";
|
|
83
|
-
}
|
|
84
|
-
const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
|
|
85
|
-
if (matchData) {
|
|
86
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
87
|
-
const [_, sign, hour, minute] = matchData;
|
|
88
|
-
return `UTC ${sign}${hour.padStart(2, "0")}:${(minute ?? "").padStart(2, "0")}:00`;
|
|
89
|
-
}
|
|
90
|
-
return "UTC +00:00:00";
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const getMachineOffsetMillis = (): number => {
|
|
94
|
-
const timeZoneName = Intl.DateTimeFormat("ia", {
|
|
95
|
-
timeZoneName: "short",
|
|
96
|
-
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
97
|
-
}).formatToParts().find((i) => i.type === "timeZoneName")?.value ?? "";
|
|
98
|
-
|
|
99
|
-
const offset = timeZoneName.slice(3);
|
|
100
|
-
if (!offset) {
|
|
101
|
-
return 0;
|
|
102
|
-
}
|
|
103
|
-
const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
|
|
104
|
-
if (matchData) {
|
|
105
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
106
|
-
const [_, sign, hour, minute] = matchData;
|
|
107
|
-
return parseInt(sign + "1") * ((hour ? parseInt(hour) : 0) * 60 + (minute ? parseInt(minute) : 0)) * 60 * 1000;
|
|
108
|
-
}
|
|
109
|
-
return 0;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const todayToEpoch = (resetHours: boolean): number => {
|
|
113
|
-
const today = new Date();
|
|
114
|
-
if (resetHours) {
|
|
115
|
-
today.setHours(0, 0, 0, 0);
|
|
116
|
-
}
|
|
117
|
-
return today.getTime() + getMachineOffsetMillis() - getUserOffsetMillis();
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const pickerToEpoch = (value: Date | null | undefined): number => {
|
|
121
|
-
if (value != null) {
|
|
122
|
-
// FSCalendar is always in machine time zone, so we need to convert it to user time zone
|
|
123
|
-
return value.getTime() + getMachineOffsetMillis() - getUserOffsetMillis();
|
|
124
|
-
}
|
|
125
|
-
return 0;
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
const epochToPicker = (value: number | null | undefined): Date => {
|
|
129
|
-
const date = new Date(0);
|
|
130
|
-
if (value != null) {
|
|
131
|
-
// Epoch is always without time zone, so we need to convert it to user time zone
|
|
132
|
-
date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
|
|
133
|
-
}
|
|
134
|
-
return date;
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
const epochToPickerHeader = (value: number): { d: number, m: number, y: number } => {
|
|
138
|
-
const date = new Date(0);
|
|
139
|
-
if (value != null) {
|
|
140
|
-
date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
|
|
141
|
-
}
|
|
142
|
-
return { d: date.getDate(), m: date.getMonth(), y: date.getFullYear() };
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const epochToLongDateFormat = (value: number | null | undefined): string => {
|
|
146
|
-
if (value == null || !isFinite(value)) {
|
|
147
|
-
return "";
|
|
148
|
-
}
|
|
149
|
-
const date = new Date(0);
|
|
150
|
-
date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
|
|
151
|
-
return format(date, "EEEE dd LLLL yyyy", { locale: getLocale() });
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
const epochToLongTimeFormat = (value: number | null | undefined): string => {
|
|
155
|
-
if (value == null || !isFinite(value)) {
|
|
156
|
-
return "";
|
|
157
|
-
}
|
|
158
|
-
const date = new Date(0);
|
|
159
|
-
date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
|
|
160
|
-
return format(date, overrideFormat(date, "EEEE dd LLLL yyyy HH:mm"), { locale: getLocale() })
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const epochToShortDateFormat = (value: number | null | undefined): string => {
|
|
164
|
-
if (value == null || !isFinite(value)) {
|
|
165
|
-
return "";
|
|
166
|
-
}
|
|
167
|
-
const date = new Date(0);
|
|
168
|
-
date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
|
|
169
|
-
switch (getLocale()) {
|
|
170
|
-
case enUS: {
|
|
171
|
-
return format(date, "MM/dd/yyyy", { locale: getLocale() });
|
|
172
|
-
}
|
|
173
|
-
default: {
|
|
174
|
-
return format(date, "dd/MM/yyyy", { locale: getLocale() });
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
const epochToTimeOnlyFormat = (value: number | null | undefined): string => {
|
|
180
|
-
if (value == null || !isFinite(value)) {
|
|
181
|
-
return "";
|
|
182
|
-
}
|
|
183
|
-
const date = new Date(0);
|
|
184
|
-
date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
|
|
185
|
-
return format(date, "HH:mm:ss", { locale: getLocale() });
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
const epochToShortTimeFormat = (value: number | null | undefined): string => {
|
|
189
|
-
if (value == null || !isFinite(value)) {
|
|
190
|
-
return "";
|
|
191
|
-
}
|
|
192
|
-
const date = new Date(0);
|
|
193
|
-
date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
|
|
194
|
-
switch (getLocale()) {
|
|
195
|
-
case enUS: {
|
|
196
|
-
return format(date, "MM/dd/yyyy HH:mm", { locale: getLocale() });
|
|
197
|
-
}
|
|
198
|
-
default: {
|
|
199
|
-
return format(date, "dd/MM/yyyy HH:mm", { locale: getLocale() });
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
};
|
|
10
|
+
const getUserFormatter = (): Intl.DateTimeFormat => {
|
|
11
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
12
|
+
timeZone: timeZone.value || Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
13
|
+
timeZoneName: "longOffset"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
203
16
|
|
|
204
|
-
const
|
|
205
|
-
return
|
|
206
|
-
|
|
17
|
+
const getMachineFormatter = (): Intl.DateTimeFormat => {
|
|
18
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
19
|
+
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
20
|
+
timeZoneName: "longOffset"
|
|
21
|
+
});
|
|
22
|
+
}
|
|
207
23
|
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
24
|
+
const getUserOffsetName = (): string => {
|
|
25
|
+
const formatter = getUserFormatter();
|
|
26
|
+
const currentDate = formatter.formatToParts(new Date());
|
|
27
|
+
const timeZoneName = currentDate.find((part) => part.type === "timeZoneName")?.value || "UTC+00:00";
|
|
28
|
+
return timeZoneName
|
|
29
|
+
}
|
|
211
30
|
|
|
212
|
-
const
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
return todayTimeFormat();
|
|
216
|
-
}
|
|
217
|
-
if (date.toDateString() === subDays(now, 1).toDateString()) {
|
|
218
|
-
return yesterdayTimeFormat();
|
|
219
|
-
}
|
|
220
|
-
return askedFormat;
|
|
221
|
-
};
|
|
31
|
+
const getUserOffset = (): number => {
|
|
32
|
+
const timeZoneName = getUserOffsetName();
|
|
33
|
+
const [hours, minutes] = timeZoneName.slice(3).split(':');
|
|
222
34
|
|
|
223
|
-
|
|
224
|
-
switch (useAppLanguageCode().languageCode.value) {
|
|
225
|
-
case "fr-FR": return fr;
|
|
226
|
-
case "es-ES": return es;
|
|
227
|
-
case "it-IT": return it;
|
|
228
|
-
case "en-GB": return enGB;
|
|
229
|
-
case "de-DE": return de;
|
|
230
|
-
default: return enUS;
|
|
231
|
-
}
|
|
35
|
+
return (parseInt(hours) * 60 + parseInt(minutes)) * 60 * 1000;
|
|
232
36
|
};
|
|
233
37
|
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
return date.getTime();
|
|
38
|
+
const getMachineOffsetName = (): string => {
|
|
39
|
+
const formatter = getMachineFormatter();
|
|
40
|
+
const currentDate = formatter.formatToParts(new Date());
|
|
41
|
+
const timeZoneName = currentDate.find((part) => part.type === "timeZoneName")?.value || "UTC+00:00";
|
|
42
|
+
return timeZoneName;
|
|
241
43
|
};
|
|
242
44
|
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
date = addMilliseconds(addDays(date, daysOffset), -machineOffset());
|
|
247
|
-
return format(date, isoTimeFormat());
|
|
248
|
-
};
|
|
45
|
+
const getMachineOffset = (): number => {
|
|
46
|
+
const timeZoneName = getMachineOffsetName();
|
|
47
|
+
const [hours, minutes] = timeZoneName.slice(3).split(':');
|
|
249
48
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const epoch = date - machineOffset() + (machineOffset() - userOffset());
|
|
253
|
-
return format(epoch, isoTimeFormat());
|
|
254
|
-
}
|
|
255
|
-
return "";
|
|
256
|
-
};
|
|
49
|
+
return (parseInt(hours) * 60 + parseInt(minutes)) * 60 * 1000;
|
|
50
|
+
}
|
|
257
51
|
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
return "";
|
|
261
|
-
}
|
|
262
|
-
return format(epoch - machineOffset(), isoTimeFormat());
|
|
52
|
+
const getOffsetDifference = (): number => {
|
|
53
|
+
return getUserOffset() - getMachineOffset();
|
|
263
54
|
};
|
|
264
55
|
|
|
265
56
|
const ready = computed(() => timeZone.value !== null);
|
|
@@ -269,21 +60,9 @@ export const useAppTimeZone = () => {
|
|
|
269
60
|
timeZone,
|
|
270
61
|
setAppTimeZone,
|
|
271
62
|
getUserOffset,
|
|
63
|
+
getUserOffsetName,
|
|
272
64
|
getMachineOffset,
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
todayToEpoch,
|
|
276
|
-
pickerToEpoch,
|
|
277
|
-
epochToPicker,
|
|
278
|
-
epochToPickerHeader,
|
|
279
|
-
epochToLongDateFormat,
|
|
280
|
-
epochToLongTimeFormat,
|
|
281
|
-
epochToShortDateFormat,
|
|
282
|
-
epochToShortTimeFormat,
|
|
283
|
-
epochToTimeOnlyFormat,
|
|
284
|
-
parseForPicker,
|
|
285
|
-
formatCurrentForPicker,
|
|
286
|
-
formatFromPicker,
|
|
287
|
-
formatEpochToVariable
|
|
65
|
+
getMachineOffsetName,
|
|
66
|
+
getOffsetDifference,
|
|
288
67
|
};
|
|
289
68
|
}
|
package/composables/index.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ComposableFactory, ServiceFactory } from "@dative-gpi/bones-ui/core";
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
2
|
+
import type { ImageDetailsDTO } from "@dative-gpi/foundation-shared-domain/models";
|
|
3
|
+
import { ImageDetails } from "@dative-gpi/foundation-shared-domain/models";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { IMAGE_URL } from "../../config/urls";
|
|
6
6
|
|
|
7
|
-
const ImageServiceFactory =
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const ImageServiceFactory = new ServiceFactory<ImageDetailsDTO, ImageDetails>("image", ImageDetails).create(factory => factory.build(
|
|
8
|
+
factory.addGet(IMAGE_URL),
|
|
9
|
+
factory.addNotify()
|
|
10
|
+
));
|
|
10
11
|
|
|
11
|
-
export const
|
|
12
|
+
export const useImage = ComposableFactory.get(ImageServiceFactory);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type NotificationDetailsDTO, type NotificationFilters, type NotificationInfosDTO } from "@dative-gpi/foundation-shared-domain/models";
|
|
2
|
+
import { NotificationDetails, NotificationInfos } from "@dative-gpi/foundation-shared-domain/models";
|
|
3
|
+
import { ComposableFactory, ServiceFactory } from "@dative-gpi/bones-ui/core";
|
|
4
|
+
|
|
5
|
+
import { HUBS, NOTIFICATION_URL, NOTIFICATIONS_HUB_URL, NOTIFICATIONS_URL } from "../../config";
|
|
6
|
+
import { HubFactory } from "../../tools";
|
|
7
|
+
|
|
8
|
+
const NotificationServiceFactory = new ServiceFactory<NotificationDetailsDTO, NotificationDetails>("notification", NotificationDetails).create(factory => factory.build(
|
|
9
|
+
factory.addGet(NOTIFICATION_URL),
|
|
10
|
+
factory.addGetMany<NotificationInfosDTO, NotificationInfos, NotificationFilters>(NOTIFICATIONS_URL, NotificationInfos),
|
|
11
|
+
factory.addNotify(notifyService => ({
|
|
12
|
+
notifyCreate: (notification: NotificationDetails) => notifyService.notify("add", notification),
|
|
13
|
+
...ServiceFactory.addCustom("acknowledge", (axios, notificationId: string) => axios.patch(NOTIFICATION_URL(notificationId)), (dto: NotificationDetailsDTO) => {
|
|
14
|
+
const result = new NotificationDetails(dto);
|
|
15
|
+
notifyService.notify("update", result);
|
|
16
|
+
return result;
|
|
17
|
+
})
|
|
18
|
+
}))
|
|
19
|
+
));
|
|
20
|
+
|
|
21
|
+
const useNotificationsHub = HubFactory.create(NOTIFICATIONS_HUB_URL,
|
|
22
|
+
(connection, { hasWatchers }) => {
|
|
23
|
+
connection.on(HUBS.CREATE_NOTIFICATION, (notificationId: string) => hasWatchers()
|
|
24
|
+
? NotificationServiceFactory.get(notificationId).then(NotificationServiceFactory.notifyCreate)
|
|
25
|
+
: null);
|
|
26
|
+
},
|
|
27
|
+
async (connection) => {
|
|
28
|
+
await connection.invoke(HUBS.SUBSCRIBE);
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const useWatchNotifications = HubFactory.createWatcher(useNotificationsHub);
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
export const useNotifications = ComposableFactory.getMany(NotificationServiceFactory, () => {
|
|
36
|
+
const { watchMany } = useWatchNotifications();
|
|
37
|
+
return () => {
|
|
38
|
+
watchMany();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
export const useAcknowledgeNotification = ComposableFactory.custom(NotificationServiceFactory.acknowledge);
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { addMilliseconds, format, parse, subDays } from "date-fns";
|
|
2
|
+
|
|
3
|
+
import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
|
|
4
|
+
import { ISO_FORMAT, OPTIONS } from "@dative-gpi/foundation-shared-domain/tools";
|
|
5
|
+
|
|
6
|
+
import { useAppLanguageCode, useAppTimeZone } from "./app/";
|
|
7
|
+
|
|
8
|
+
export const useDateFormat = () => {
|
|
9
|
+
const { $tr } = useTranslationsProvider();
|
|
10
|
+
|
|
11
|
+
const { languageCode } = useAppLanguageCode();
|
|
12
|
+
const { timeZone, getOffsetDifference, getMachineOffset, getUserOffset } = useAppTimeZone();
|
|
13
|
+
|
|
14
|
+
const isEpochToday = (value: number | null | undefined): boolean => {
|
|
15
|
+
if (value == null || !isFinite(value)) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
const date = new Date(value);
|
|
19
|
+
const now = new Date();
|
|
20
|
+
return date.toLocaleString(languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value })
|
|
21
|
+
=== now.toLocaleString(languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const isEpochYesterday = (value: number | null | undefined): boolean => {
|
|
25
|
+
if (value == null || !isFinite(value)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const date = new Date(value);
|
|
29
|
+
const now = new Date();
|
|
30
|
+
return date.toLocaleString(languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value })
|
|
31
|
+
=== subDays(now, 1).toLocaleString(languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const dayToMillisecond = (value: number): number => {
|
|
35
|
+
return value * 24 * 60 * 60 * 1000
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const epochToDayMonthLongOnly = (value: number | null | undefined): string => {
|
|
39
|
+
if (value == null || !isFinite(value)) {
|
|
40
|
+
return "";
|
|
41
|
+
}
|
|
42
|
+
const date = new Date(value);
|
|
43
|
+
return date.toLocaleString(languageCode.value, { ...OPTIONS.dayMonthLongOnly, timeZone: timeZone.value });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const epochToShortDateFormat = (value: number | null | undefined): string => {
|
|
47
|
+
if (value == null || !isFinite(value)) {
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
const date = new Date(value);
|
|
51
|
+
return date.toLocaleString(languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value });
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const epochToLongDateFormat = (value: number | null | undefined): string => {
|
|
55
|
+
if (value == null || !isFinite(value)) {
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
58
|
+
const date = new Date(value);
|
|
59
|
+
if (isEpochToday(value)) {
|
|
60
|
+
return $tr("ui.time-zone.today", "Today");
|
|
61
|
+
}
|
|
62
|
+
if (isEpochYesterday(value)) {
|
|
63
|
+
return $tr("ui.time-zone.yesterday", "Yesterday");
|
|
64
|
+
}
|
|
65
|
+
const dateString = date.toLocaleString(languageCode.value, { ...OPTIONS.longDate, timeZone: timeZone.value });
|
|
66
|
+
return dateString[0].toLocaleUpperCase() + dateString.slice(1);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const epochToShortTimeFormat = (value: number | null | undefined): string => {
|
|
70
|
+
if (value == null || !isFinite(value)) {
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
73
|
+
const date = new Date(value);
|
|
74
|
+
return date.toLocaleString(languageCode.value, { ...OPTIONS.shortTime, timeZone: timeZone.value });
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const epochToLocalDayStart = (value: number | null | undefined): number => {
|
|
78
|
+
if (value == null || !isFinite(value)) {
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
const date = new Date(value);
|
|
82
|
+
return date.setHours(0, 0, 0, 0);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const epochToLocalDayEnd = (value: number | null | undefined): number => {
|
|
86
|
+
if (value == null || !isFinite(value)) {
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
const date = new Date(value);
|
|
90
|
+
return date.setHours(23, 59, 59, 999);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const epochToLongTimeFormat = (value: number | null | undefined): string => {
|
|
94
|
+
if (value == null || !isFinite(value)) {
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
const date = new Date(value);
|
|
98
|
+
if (isEpochToday(value)) {
|
|
99
|
+
return `${$tr("ui.time-zone.today-at", "Today at")} ${date.toLocaleString(languageCode.value, { ...OPTIONS.time, timeZone: timeZone.value })}`;
|
|
100
|
+
}
|
|
101
|
+
if (isEpochYesterday(value)) {
|
|
102
|
+
return `${$tr("ui.time-zone.yesterday-at", "Yesterday at")} ${date.toLocaleString(languageCode.value, { ...OPTIONS.time, timeZone: timeZone.value })}`;
|
|
103
|
+
}
|
|
104
|
+
const dateString = date.toLocaleString(languageCode.value, { ...OPTIONS.longTime, timeZone: timeZone.value });
|
|
105
|
+
return dateString[0].toLocaleUpperCase() + dateString.slice(1);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const epochToMonthYearOnlyFormat = (value: number | null | undefined): string => {
|
|
109
|
+
if (value == null || !isFinite(value)) {
|
|
110
|
+
return "";
|
|
111
|
+
}
|
|
112
|
+
const date = new Date(value);
|
|
113
|
+
return date.toLocaleString(languageCode.value, { ...OPTIONS.monthYearOnly, timeZone: timeZone.value });
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const epochToTimeOnlyFormat = (value: number | null | undefined): string => {
|
|
117
|
+
if (value == null || !isFinite(value)) {
|
|
118
|
+
return "";
|
|
119
|
+
}
|
|
120
|
+
const date = new Date(value);
|
|
121
|
+
return date.toLocaleString(languageCode.value, { ...OPTIONS.time, timeZone: timeZone.value });
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const epochToShortTimeOnlyFormat = (value: number | null | undefined): string => {
|
|
125
|
+
if (value == null || !isFinite(value)) {
|
|
126
|
+
return "";
|
|
127
|
+
}
|
|
128
|
+
const date = new Date(value);
|
|
129
|
+
return date.toLocaleString(languageCode.value, { ...OPTIONS.shortTimeOnly, timeZone: timeZone.value });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const epochToWeekNumber = (value: number | null | undefined): string => {
|
|
133
|
+
if (value == null || !isFinite(value)) {
|
|
134
|
+
return "";
|
|
135
|
+
}
|
|
136
|
+
const date = new Date(value);
|
|
137
|
+
date.setHours(0, 0, 0, 0);
|
|
138
|
+
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
|
|
139
|
+
const week1 = new Date(date.getFullYear(), 0, 4);
|
|
140
|
+
return `${1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7)}`;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const todayToEpoch = (): number => {
|
|
144
|
+
return new Date().getTime() + getOffsetDifference();
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const pickerToEpoch = (value: Date | null | undefined): number => {
|
|
148
|
+
if (value != null) {
|
|
149
|
+
return value.getTime() - getOffsetDifference();
|
|
150
|
+
}
|
|
151
|
+
return 0;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const epochToPicker = (value: number | null | undefined): Date => {
|
|
155
|
+
if (value != null) {
|
|
156
|
+
return new Date(value + getOffsetDifference());
|
|
157
|
+
}
|
|
158
|
+
return new Date(0);
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const epochToPickerHeader = (value: number): { d: number, m: number, y: number } => {
|
|
162
|
+
const date = epochToPicker(value);
|
|
163
|
+
return { d: date.getDate(), m: date.getMonth(), y: date.getFullYear() };
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const millisecondToDay = (value: number): number => {
|
|
167
|
+
return value / 1000 / 60 / 60 / 24;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const todayToPicker = (): string => {
|
|
171
|
+
const date = addMilliseconds(new Date(), -getMachineOffset());
|
|
172
|
+
date.setSeconds(0, 0);
|
|
173
|
+
return format(date, ISO_FORMAT);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const yesterdayToPicker = (): string => {
|
|
177
|
+
const date = addMilliseconds(subDays(new Date(), 1), -getMachineOffset());
|
|
178
|
+
date.setSeconds(0, 0);
|
|
179
|
+
return format(date, ISO_FORMAT);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const parseForPicker = (value: string, dateFormat: string = ISO_FORMAT): number | null => {
|
|
183
|
+
const date = addMilliseconds(parse(value, dateFormat, new Date()), getUserOffset());
|
|
184
|
+
if (!isFinite(date.getTime())) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
return date.getTime();
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const epochToISO = (date: number | null): string => {
|
|
191
|
+
if (date != null) {
|
|
192
|
+
return format(date - getMachineOffset(), ISO_FORMAT);
|
|
193
|
+
}
|
|
194
|
+
return "";
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
todayToEpoch,
|
|
199
|
+
pickerToEpoch,
|
|
200
|
+
dayToMillisecond,
|
|
201
|
+
epochToDayMonthLongOnly,
|
|
202
|
+
epochToPicker,
|
|
203
|
+
epochToPickerHeader,
|
|
204
|
+
epochToLocalDayStart,
|
|
205
|
+
epochToLocalDayEnd,
|
|
206
|
+
epochToLongDateFormat,
|
|
207
|
+
epochToLongTimeFormat,
|
|
208
|
+
epochToMonthYearOnlyFormat,
|
|
209
|
+
epochToShortDateFormat,
|
|
210
|
+
epochToShortTimeFormat,
|
|
211
|
+
epochToShortTimeOnlyFormat,
|
|
212
|
+
epochToTimeOnlyFormat,
|
|
213
|
+
epochToWeekNumber,
|
|
214
|
+
millisecondToDay,
|
|
215
|
+
parseForPicker,
|
|
216
|
+
todayToPicker,
|
|
217
|
+
yesterdayToPicker,
|
|
218
|
+
epochToISO
|
|
219
|
+
};
|
|
220
|
+
}
|
package/config/index.ts
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const SUBSCRIBE = "Subscribe";
|
|
2
|
+
export const UNSUBSCRIBE = "Unsubscribe";
|
|
3
|
+
|
|
4
|
+
export const UPDATE_DEVICE_STATUS = "UpdateDeviceStatus";
|
|
5
|
+
|
|
6
|
+
export const UPDATE_DEVICE_CONNECTIVITY = "UpdateDeviceConnectivity";
|
|
7
|
+
|
|
8
|
+
export const CREATE_ALERT = "CreateAlert";
|
|
9
|
+
export const UPDATE_ALERT = "UpdateAlert";
|
|
10
|
+
export const REMOVE_ALERT = "RemoveAlert";
|
|
11
|
+
|
|
12
|
+
export const CREATE_CONNECTIVITY_ALERT = "CreateConnectivityAlert";
|
|
13
|
+
export const UPDATE_CONNECTIVITY_ALERT = "UpdateConnectivityAlert";
|
|
14
|
+
export const REMOVE_CONNECTIVITY_ALERT = "RemoveConnectivityAlert";
|
|
15
|
+
|
|
16
|
+
export const CREATE_NOTIFICATION = "CreateNotification";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as HUBS from "./hubs";
|
package/config/urls/base.ts
CHANGED
package/config/urls/images.ts
CHANGED
|
@@ -2,12 +2,18 @@ import { GATEWAY_URL } from "./base";
|
|
|
2
2
|
|
|
3
3
|
export const IMAGES_URL = () => `${GATEWAY_URL()}/images`;
|
|
4
4
|
|
|
5
|
-
export const
|
|
6
|
-
export const IMAGE_RAW_URL = (imageId: string) =>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export const
|
|
5
|
+
export const IMAGE_URL = (imageId: string) => `${IMAGES_URL()}/${encodeURIComponent(imageId)}`;
|
|
6
|
+
export const IMAGE_RAW_URL = (imageId: string, accessToken?: string) => {
|
|
7
|
+
let url = `${IMAGE_URL(imageId)}/raw`;
|
|
8
|
+
if (accessToken) {
|
|
9
|
+
url += `?access_token=${encodeURIComponent(accessToken)}`;
|
|
10
|
+
}
|
|
11
|
+
return url;
|
|
12
|
+
};
|
|
13
|
+
export const IMAGE_THUMBNAIL_URL = (imageId: string, accessToken?: string) => {
|
|
14
|
+
let url = `${IMAGE_URL(imageId)}/thumbnail`;
|
|
15
|
+
if (accessToken) {
|
|
16
|
+
url += `?access_token=${encodeURIComponent(accessToken)}`;
|
|
17
|
+
}
|
|
18
|
+
return url;
|
|
19
|
+
};
|
package/config/urls/index.ts
CHANGED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { GATEWAY_URL, HUBS_URL } from "./base";
|
|
2
|
+
|
|
3
|
+
export const NOTIFICATIONS_URL = () => `${GATEWAY_URL()}/notifications`;
|
|
4
|
+
export const NOTIFICATION_URL = (notificationId: string) => `${GATEWAY_URL()}/notifications/${notificationId}`;
|
|
5
|
+
|
|
6
|
+
export const NOTIFICATIONS_HUB_URL = () => `${HUBS_URL()}/notifications`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dative-gpi/foundation-shared-services",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.1.68",
|
|
5
5
|
"description": "",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"author": "",
|
|
11
11
|
"license": "ISC",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@dative-gpi/foundation-shared-domain": "0.
|
|
13
|
+
"@dative-gpi/foundation-shared-domain": "0.1.68"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
16
|
"@dative-gpi/bones-ui": "^0.0.75",
|
|
@@ -18,5 +18,5 @@
|
|
|
18
18
|
"vue": "^3.4.29",
|
|
19
19
|
"vue-router": "^4.3.0"
|
|
20
20
|
},
|
|
21
|
-
"gitHead": "
|
|
21
|
+
"gitHead": "fa2ed7031088f422751fc1d939f2fbe168ae0596"
|
|
22
22
|
}
|
package/tools/hubFactory.ts
CHANGED
|
@@ -28,7 +28,12 @@ export class HubFactory {
|
|
|
28
28
|
})
|
|
29
29
|
}
|
|
30
30
|
if (connection.state !== signalR.HubConnectionState.Connected) {
|
|
31
|
-
|
|
31
|
+
try {
|
|
32
|
+
await connection.start();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
32
37
|
}
|
|
33
38
|
if (!subscribed) {
|
|
34
39
|
await init(connection);
|
package/tools/index.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from "./hubFactory";
|
|
1
|
+
export * from "./hubFactory";
|
|
2
|
+
export * from "./translate";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useAppLanguageCode } from "../composables";
|
|
2
|
+
|
|
3
|
+
export const translate = <TTranslation extends { languageCode: string }>(
|
|
4
|
+
translations: TTranslation[],
|
|
5
|
+
accessor: (item: TTranslation) => string,
|
|
6
|
+
defaultValue: string): string => {
|
|
7
|
+
|
|
8
|
+
const { languageCode } = useAppLanguageCode();
|
|
9
|
+
|
|
10
|
+
if(!languageCode.value) {
|
|
11
|
+
return defaultValue;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const translation = translations.find(t => t.languageCode === languageCode.value);
|
|
15
|
+
|
|
16
|
+
return translation ? accessor(translation) : defaultValue;
|
|
17
|
+
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { computed, ref } from "vue";
|
|
2
|
-
|
|
3
|
-
const jwt = ref<string | undefined>(undefined);
|
|
4
|
-
|
|
5
|
-
export const useExtensionJwt = () => {
|
|
6
|
-
const setExtensionJwt = (payload: string) => {
|
|
7
|
-
jwt.value = payload;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const ready = computed(() => jwt.value !== null);
|
|
11
|
-
|
|
12
|
-
return {
|
|
13
|
-
jwt,
|
|
14
|
-
ready,
|
|
15
|
-
setExtensionJwt
|
|
16
|
-
};
|
|
17
|
-
}
|