@dative-gpi/foundation-shared-services 1.0.66 → 1.0.67-map-edit
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 +2 -1
- package/composables/app/useAppHost.ts +17 -0
- package/composables/app/useAppTimeZone.ts +43 -16
- package/composables/index.ts +3 -1
- package/composables/services/index.ts +2 -0
- package/composables/services/useLegalInformations.ts +10 -0
- package/composables/services/useUserLegalInformations.ts +11 -0
- package/composables/useDateExpression.ts +138 -0
- package/composables/useDateFormat.ts +36 -13
- package/composables/useFiles.ts +6 -1
- package/composables/useRouting.ts +37 -0
- package/config/urls/files.ts +7 -1
- package/config/urls/images.ts +6 -6
- package/config/urls/index.ts +2 -0
- package/config/urls/legalInformations.ts +4 -0
- package/config/urls/userLegalInformations.ts +3 -0
- package/package.json +5 -5
- package/tools/hubFactory.ts +5 -5
package/composables/app/index.ts
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { computed, ref } from "vue";
|
|
2
|
+
|
|
3
|
+
const host = ref<string | undefined>(undefined);
|
|
4
|
+
|
|
5
|
+
export const useAppHost = () => {
|
|
6
|
+
const setAppHost = (payload: string) => {
|
|
7
|
+
host.value = payload;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const ready = computed(() => host.value !== null);
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
host,
|
|
14
|
+
ready,
|
|
15
|
+
setAppHost
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -2,6 +2,9 @@ import { computed, ref } from "vue";
|
|
|
2
2
|
|
|
3
3
|
const timeZone = ref<string | undefined>(undefined);
|
|
4
4
|
|
|
5
|
+
const currentUserOffset = ref<number | null>(null);
|
|
6
|
+
const currentMachineOffset = ref<number | null>(null);
|
|
7
|
+
|
|
5
8
|
export const useAppTimeZone = () => {
|
|
6
9
|
const setAppTimeZone = (payload: string) => {
|
|
7
10
|
timeZone.value = payload;
|
|
@@ -21,47 +24,71 @@ export const useAppTimeZone = () => {
|
|
|
21
24
|
});
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
const getUserOffsetName = (): string => {
|
|
27
|
+
const getUserOffsetName = (epoch: number | null = null): string => {
|
|
25
28
|
const formatter = getUserFormatter();
|
|
26
|
-
const
|
|
27
|
-
const timeZoneName =
|
|
29
|
+
const date = formatter.formatToParts(epoch ? new Date(epoch) : new Date());
|
|
30
|
+
const timeZoneName = date.find((part) => part.type === "timeZoneName")?.value || "UTC+00:00";
|
|
28
31
|
return timeZoneName
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
const getUserOffset = (): number => {
|
|
32
|
-
const timeZoneName = getUserOffsetName();
|
|
34
|
+
const getUserOffset = (epoch: number | null = null): number => {
|
|
35
|
+
const timeZoneName = getUserOffsetName(epoch);
|
|
33
36
|
const [hours, minutes] = timeZoneName.slice(3).split(':');
|
|
34
|
-
|
|
37
|
+
if (isNaN(parseInt(hours)) || isNaN(parseInt(minutes))) {
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
35
40
|
return (parseInt(hours) * 60 + parseInt(minutes)) * 60 * 1000;
|
|
36
41
|
};
|
|
37
42
|
|
|
38
|
-
const getMachineOffsetName = (): string => {
|
|
43
|
+
const getMachineOffsetName = (epoch: number | null = null): string => {
|
|
39
44
|
const formatter = getMachineFormatter();
|
|
40
|
-
const
|
|
41
|
-
const timeZoneName =
|
|
45
|
+
const date = formatter.formatToParts(epoch ? new Date(epoch) : new Date());
|
|
46
|
+
const timeZoneName = date.find((part) => part.type === "timeZoneName")?.value || "UTC+00:00";
|
|
42
47
|
return timeZoneName;
|
|
43
48
|
};
|
|
44
49
|
|
|
45
|
-
const getMachineOffset = (): number => {
|
|
46
|
-
const timeZoneName = getMachineOffsetName();
|
|
50
|
+
const getMachineOffset = (epoch: number | null = null): number => {
|
|
51
|
+
const timeZoneName = getMachineOffsetName(epoch);
|
|
47
52
|
const [hours, minutes] = timeZoneName.slice(3).split(':');
|
|
48
|
-
|
|
53
|
+
if (isNaN(parseInt(hours)) || isNaN(parseInt(minutes))) {
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
49
56
|
return (parseInt(hours) * 60 + parseInt(minutes)) * 60 * 1000;
|
|
50
57
|
}
|
|
51
58
|
|
|
52
|
-
const getOffsetDifference = (): number => {
|
|
53
|
-
return
|
|
59
|
+
const getOffsetDifference = (epoch: number | null = null): number => {
|
|
60
|
+
return cachedUserOffset(epoch) - cachedMachineOffset(epoch);
|
|
54
61
|
};
|
|
55
62
|
|
|
56
63
|
const ready = computed(() => timeZone.value !== null);
|
|
57
64
|
|
|
65
|
+
const cachedUserOffset = (epoch: number | null = null): number => {
|
|
66
|
+
if (epoch === null) {
|
|
67
|
+
if (currentUserOffset.value === null) {
|
|
68
|
+
currentUserOffset.value = getUserOffset();
|
|
69
|
+
}
|
|
70
|
+
return currentUserOffset.value;
|
|
71
|
+
}
|
|
72
|
+
return getUserOffset(epoch);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const cachedMachineOffset = (epoch: number | null = null): number => {
|
|
76
|
+
if (epoch === null) {
|
|
77
|
+
if (currentMachineOffset.value === null) {
|
|
78
|
+
currentMachineOffset.value = getMachineOffset();
|
|
79
|
+
}
|
|
80
|
+
return currentMachineOffset.value;
|
|
81
|
+
}
|
|
82
|
+
return getMachineOffset(epoch);
|
|
83
|
+
}
|
|
84
|
+
|
|
58
85
|
return {
|
|
59
86
|
ready,
|
|
60
87
|
timeZone,
|
|
61
88
|
setAppTimeZone,
|
|
62
|
-
getUserOffset,
|
|
89
|
+
getUserOffset: cachedUserOffset,
|
|
63
90
|
getUserOffsetName,
|
|
64
|
-
getMachineOffset,
|
|
91
|
+
getMachineOffset: cachedMachineOffset,
|
|
65
92
|
getMachineOffsetName,
|
|
66
93
|
getOffsetDifference,
|
|
67
94
|
};
|
package/composables/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export * from "./services";
|
|
2
2
|
export * from "./app";
|
|
3
3
|
|
|
4
|
+
export * from "./useDateFormat";
|
|
4
5
|
export * from "./useFiles";
|
|
5
6
|
export * from "./useFoundationShared";
|
|
6
|
-
export * from "./
|
|
7
|
+
export * from "./useRouting";
|
|
8
|
+
export * from "./useDateExpression";
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export * from "./useAuthTokens";
|
|
2
2
|
export * from "./useImages";
|
|
3
3
|
export * from "./useLanguages";
|
|
4
|
+
export * from "./useLegalInformations";
|
|
4
5
|
export * from "./useNotifications";
|
|
5
6
|
export * from "./useOrganisations";
|
|
6
7
|
export * from "./useTerminals";
|
|
7
8
|
export * from "./useTimeZones";
|
|
8
9
|
export * from "./useTranslations";
|
|
10
|
+
export * from "./useUserLegalInformations";
|
|
9
11
|
export * from "./useUsers";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LegalInformationDetails, type LegalInformationDetailsDTO } from "@dative-gpi/foundation-shared-domain/models";
|
|
2
|
+
import { ComposableFactory, ServiceFactory } from "@dative-gpi/bones-ui";
|
|
3
|
+
|
|
4
|
+
import { LEGAL_INFORMATION_CURRENT_URL } from "../../config/urls";
|
|
5
|
+
|
|
6
|
+
const LegalInformationServiceFactory = {
|
|
7
|
+
...ServiceFactory.addCustom("getCurrent", axios => axios.get(LEGAL_INFORMATION_CURRENT_URL()), (dto: LegalInformationDetailsDTO) => new LegalInformationDetails(dto))
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const useCurrentLegalInformation = ComposableFactory.custom(LegalInformationServiceFactory.getCurrent);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type CreateUserLegalInformationDTO, UserLegalInformationDetails, type UserLegalInformationDetailsDTO } from "@dative-gpi/foundation-shared-domain/models";
|
|
2
|
+
import { ComposableFactory, ServiceFactory } from "@dative-gpi/bones-ui/core";
|
|
3
|
+
|
|
4
|
+
import { USER_LEGAL_INFORMATIONS_URL } from "../../config/urls";
|
|
5
|
+
|
|
6
|
+
const UserLegalInformationServiceFactory = new ServiceFactory<UserLegalInformationDetailsDTO, UserLegalInformationDetails>("userLegalInformation", UserLegalInformationDetails).create(factory => factory.build(
|
|
7
|
+
factory.addCreate<CreateUserLegalInformationDTO>(USER_LEGAL_INFORMATIONS_URL),
|
|
8
|
+
factory.addNotify()
|
|
9
|
+
));
|
|
10
|
+
|
|
11
|
+
export const useCreateUserLegalInformation = ComposableFactory.create(UserLegalInformationServiceFactory);
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { useAppTimeZone } from './app/useAppTimeZone';
|
|
2
|
+
import { useDateFormat } from '@dative-gpi/foundation-shared-services/composables/useDateFormat';
|
|
3
|
+
|
|
4
|
+
export const useDateExpression = () => {
|
|
5
|
+
const { getOffsetDifference } = useAppTimeZone();
|
|
6
|
+
const { parseForPicker } = useDateFormat();
|
|
7
|
+
|
|
8
|
+
const EXPRESSION = /(?:(?:([-\+])(\d*))?(\w+))?(?:\/(\w))?/g;
|
|
9
|
+
const NOW = 'now';
|
|
10
|
+
|
|
11
|
+
const convert = (value: string, variables: { [key: string]: number | string } = {}): number => {
|
|
12
|
+
//Try to convert the value to a date
|
|
13
|
+
const date = parseForPicker(value);
|
|
14
|
+
if (date) {
|
|
15
|
+
return date;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const currentVariables = {
|
|
19
|
+
...variables,
|
|
20
|
+
[NOW]: new Date().getTime()
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return applyFormula(value, currentVariables);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const applyFormula = (expression: string, variables: { [key: string]: number | string }): number => {
|
|
27
|
+
expression = expression.replace(/\s/g, '');
|
|
28
|
+
const matches = expression.matchAll(EXPRESSION);
|
|
29
|
+
|
|
30
|
+
if (!matches) {
|
|
31
|
+
console.error('Invalid expression');
|
|
32
|
+
return NaN;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let timestamp = 0;
|
|
36
|
+
|
|
37
|
+
// Retrieving group in order are: operator (+ or -), number, unit, and special (variable)
|
|
38
|
+
matches.forEach(match => {
|
|
39
|
+
const operator = match[1];
|
|
40
|
+
const number = match[2];
|
|
41
|
+
const unit = match[3];
|
|
42
|
+
const special = match[4];
|
|
43
|
+
|
|
44
|
+
if (unit) {
|
|
45
|
+
timestamp = applyUnit(timestamp, operator, number, unit, variables);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (special) {
|
|
49
|
+
timestamp = applySpecial(timestamp, special);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return timestamp;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const applyUnit = (timestamp: number, operator: string, number: string, unit: string, variables: { [key: string]: number | string }): number => {
|
|
57
|
+
let factor = operator === '-' ? -1 : 1;
|
|
58
|
+
factor *= Number.isNaN(parseInt(number)) ? 1 : parseInt(number);
|
|
59
|
+
|
|
60
|
+
switch (unit) {
|
|
61
|
+
case 's':
|
|
62
|
+
return timestamp + factor * 1000;
|
|
63
|
+
case 'm':
|
|
64
|
+
return timestamp + factor * 60 * 1000;
|
|
65
|
+
case 'h':
|
|
66
|
+
return timestamp + factor * 60 * 60 * 1000;
|
|
67
|
+
case 'd':
|
|
68
|
+
return new Date(timestamp).setDate(new Date(timestamp).getDate() + factor)
|
|
69
|
+
case 'w':
|
|
70
|
+
return new Date(timestamp).setDate(new Date(timestamp).getDate() + factor * 7);
|
|
71
|
+
case 'M':
|
|
72
|
+
return new Date(timestamp).setMonth(new Date(timestamp).getMonth() + factor);
|
|
73
|
+
case 'y':
|
|
74
|
+
return new Date(timestamp).setFullYear(new Date(timestamp).getFullYear() + factor);
|
|
75
|
+
default:
|
|
76
|
+
if(variables[unit]) {
|
|
77
|
+
const variableValue = getVariableValue(unit, variables);
|
|
78
|
+
return timestamp + factor * variableValue;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.error(`Invalid unit expression, unit ${unit} is not defined in the variables`);
|
|
82
|
+
return timestamp;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const getVariableValue = (unit: string, variables: { [key: string]: number | string }): number => {
|
|
88
|
+
if(variables[unit]) {
|
|
89
|
+
const variableValue = parseInt(variables[unit].toString());
|
|
90
|
+
if (typeof variables[unit] === 'number') {
|
|
91
|
+
return variableValue;
|
|
92
|
+
} else if (!isNaN(variableValue)) {
|
|
93
|
+
return variableValue;
|
|
94
|
+
} else {
|
|
95
|
+
const variableExpression = variables[unit].toString();
|
|
96
|
+
const variableValue = applyFormula(variableExpression, variables);
|
|
97
|
+
if (!isNaN(variableValue)) {
|
|
98
|
+
return variableValue;
|
|
99
|
+
} else {
|
|
100
|
+
console.error(`Invalid unit expression, unit ${unit} is not defined in the variables`);
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
console.error(`Invalid unit expression, unit ${unit} is not defined in the variables`);
|
|
107
|
+
return 0;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const applySpecial = (timestamp: number, special: string): number => {
|
|
112
|
+
timestamp += getOffsetDifference(timestamp);
|
|
113
|
+
switch (special) {
|
|
114
|
+
case "h":
|
|
115
|
+
return new Date(timestamp).setMinutes(0, 0, 0) - getOffsetDifference(timestamp);
|
|
116
|
+
case "d":
|
|
117
|
+
return new Date(timestamp).setHours(0, 0, 0, 0) - getOffsetDifference(timestamp);
|
|
118
|
+
case "w":
|
|
119
|
+
const date = new Date(timestamp);
|
|
120
|
+
const day = date.getDay();
|
|
121
|
+
const diff = date.getDate() - day + (day === 0 ? -6 : 1);
|
|
122
|
+
return new Date(date.setDate(diff)).setHours(0, 0, 0, 0) - getOffsetDifference(timestamp);
|
|
123
|
+
case "M":
|
|
124
|
+
const dateM = new Date(timestamp);
|
|
125
|
+
return new Date(dateM.setMonth(dateM.getMonth(), 1)).setHours(0, 0, 0, 0) - getOffsetDifference(timestamp);
|
|
126
|
+
case "y":
|
|
127
|
+
const dateY = new Date(timestamp);
|
|
128
|
+
return new Date(dateY.setMonth(0, 1)).setHours(0, 0, 0, 0) - getOffsetDifference(timestamp);
|
|
129
|
+
default:
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
return timestamp;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
convert
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -9,7 +9,7 @@ export const useDateFormat = () => {
|
|
|
9
9
|
const { $tr } = useTranslationsProvider();
|
|
10
10
|
|
|
11
11
|
const { languageCode } = useAppLanguageCode();
|
|
12
|
-
const { timeZone, getOffsetDifference, getMachineOffset
|
|
12
|
+
const { timeZone, getOffsetDifference, getMachineOffset } = useAppTimeZone();
|
|
13
13
|
|
|
14
14
|
const isEpochToday = (value: number | null | undefined): boolean => {
|
|
15
15
|
if (value == null || !isFinite(value)) {
|
|
@@ -43,6 +43,14 @@ export const useDateFormat = () => {
|
|
|
43
43
|
return date.toLocaleString(languageCode.value, { ...OPTIONS.dayMonthLongOnly, timeZone: timeZone.value });
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
const epochToDayMonthShortOnly = (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.dayMonthShortOnly, timeZone: timeZone.value });
|
|
52
|
+
}
|
|
53
|
+
|
|
46
54
|
const epochToShortDateFormat = (value: number | null | undefined): string => {
|
|
47
55
|
if (value == null || !isFinite(value)) {
|
|
48
56
|
return "";
|
|
@@ -57,10 +65,10 @@ export const useDateFormat = () => {
|
|
|
57
65
|
}
|
|
58
66
|
const date = new Date(value);
|
|
59
67
|
if (isEpochToday(value)) {
|
|
60
|
-
return $tr("ui.
|
|
68
|
+
return $tr("ui.common.today", "Today");
|
|
61
69
|
}
|
|
62
70
|
if (isEpochYesterday(value)) {
|
|
63
|
-
return $tr("ui.
|
|
71
|
+
return $tr("ui.common.yesterday", "Yesterday");
|
|
64
72
|
}
|
|
65
73
|
const dateString = date.toLocaleString(languageCode.value, { ...OPTIONS.longDate, timeZone: timeZone.value });
|
|
66
74
|
return dateString[0].toLocaleUpperCase() + dateString.slice(1);
|
|
@@ -74,6 +82,14 @@ export const useDateFormat = () => {
|
|
|
74
82
|
return date.toLocaleString(languageCode.value, { ...OPTIONS.shortTime, timeZone: timeZone.value });
|
|
75
83
|
};
|
|
76
84
|
|
|
85
|
+
const epochToMonthShortTimeFormat = (value: number | null | undefined): string => {
|
|
86
|
+
if (value == null || !isFinite(value)) {
|
|
87
|
+
return "";
|
|
88
|
+
}
|
|
89
|
+
const date = new Date(value);
|
|
90
|
+
return date.toLocaleString(languageCode.value, { ...OPTIONS.monthShortTime, timeZone: timeZone.value });
|
|
91
|
+
};
|
|
92
|
+
|
|
77
93
|
const epochToLocalDayStart = (value: number | null | undefined): number => {
|
|
78
94
|
if (value == null || !isFinite(value)) {
|
|
79
95
|
return 0;
|
|
@@ -96,10 +112,10 @@ export const useDateFormat = () => {
|
|
|
96
112
|
}
|
|
97
113
|
const date = new Date(value);
|
|
98
114
|
if (isEpochToday(value)) {
|
|
99
|
-
return `${$tr("ui.
|
|
115
|
+
return `${$tr("ui.common.today-at", "Today at")} ${date.toLocaleString(languageCode.value, { ...OPTIONS.time, timeZone: timeZone.value })}`;
|
|
100
116
|
}
|
|
101
117
|
if (isEpochYesterday(value)) {
|
|
102
|
-
return `${$tr("ui.
|
|
118
|
+
return `${$tr("ui.common.yesterday-at", "Yesterday at")} ${date.toLocaleString(languageCode.value, { ...OPTIONS.time, timeZone: timeZone.value })}`;
|
|
103
119
|
}
|
|
104
120
|
const dateString = date.toLocaleString(languageCode.value, { ...OPTIONS.longTime, timeZone: timeZone.value });
|
|
105
121
|
return dateString[0].toLocaleUpperCase() + dateString.slice(1);
|
|
@@ -146,14 +162,14 @@ export const useDateFormat = () => {
|
|
|
146
162
|
|
|
147
163
|
const pickerToEpoch = (value: Date | null | undefined): number => {
|
|
148
164
|
if (value != null) {
|
|
149
|
-
return value.getTime() - getOffsetDifference();
|
|
165
|
+
return value.getTime() - getOffsetDifference(value.getTime());
|
|
150
166
|
}
|
|
151
167
|
return 0;
|
|
152
168
|
};
|
|
153
169
|
|
|
154
170
|
const epochToPicker = (value: number | null | undefined): Date => {
|
|
155
171
|
if (value != null) {
|
|
156
|
-
return new Date(value + getOffsetDifference());
|
|
172
|
+
return new Date(value + getOffsetDifference(value));
|
|
157
173
|
}
|
|
158
174
|
return new Date(0);
|
|
159
175
|
};
|
|
@@ -174,22 +190,27 @@ export const useDateFormat = () => {
|
|
|
174
190
|
};
|
|
175
191
|
|
|
176
192
|
const yesterdayToPicker = (): string => {
|
|
177
|
-
const
|
|
193
|
+
const yesterday = subDays(new Date(), 1);
|
|
194
|
+
const date = addMilliseconds(yesterday, -getMachineOffset(yesterday.getTime()));
|
|
178
195
|
date.setSeconds(0, 0);
|
|
179
196
|
return format(date, ISO_FORMAT);
|
|
180
197
|
};
|
|
181
198
|
|
|
182
199
|
const parseForPicker = (value: string, dateFormat: string = ISO_FORMAT): number | null => {
|
|
183
|
-
|
|
184
|
-
|
|
200
|
+
// parse the date with the machine's current timezone. The last parameter is used to fill the gaps in the date string
|
|
201
|
+
const dateWithoutCorrection = parse(value, dateFormat, new Date());
|
|
202
|
+
if (!isFinite(dateWithoutCorrection.getTime())) {
|
|
185
203
|
return null;
|
|
186
204
|
}
|
|
205
|
+
// check if the timezone at the time of the date is different from the current machine timezone
|
|
206
|
+
// adjust if needed (this is the case when the date is at summer time and the machine is at winter time, for example)
|
|
207
|
+
const date = addMilliseconds(dateWithoutCorrection, getMachineOffset(dateWithoutCorrection.getTime()));
|
|
187
208
|
return date.getTime();
|
|
188
209
|
};
|
|
189
210
|
|
|
190
|
-
const epochToISO = (
|
|
191
|
-
if (
|
|
192
|
-
return format(
|
|
211
|
+
const epochToISO = (epoch: number | null): string => {
|
|
212
|
+
if (epoch != null) {
|
|
213
|
+
return format(epoch - getMachineOffset(epoch), ISO_FORMAT);
|
|
193
214
|
}
|
|
194
215
|
return "";
|
|
195
216
|
};
|
|
@@ -208,6 +229,8 @@ export const useDateFormat = () => {
|
|
|
208
229
|
epochToMonthYearOnlyFormat,
|
|
209
230
|
epochToShortDateFormat,
|
|
210
231
|
epochToShortTimeFormat,
|
|
232
|
+
epochToDayMonthShortOnly,
|
|
233
|
+
epochToMonthShortTimeFormat,
|
|
211
234
|
epochToShortTimeOnlyFormat,
|
|
212
235
|
epochToTimeOnlyFormat,
|
|
213
236
|
epochToWeekNumber,
|
package/composables/useFiles.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { FILE_URL } from "../config/urls";
|
|
2
2
|
|
|
3
|
+
import { useAppAuthToken, useRouting } from "@dative-gpi/foundation-shared-services/composables";
|
|
4
|
+
|
|
3
5
|
export const useFiles = () => {
|
|
6
|
+
const { authToken } = useAppAuthToken();
|
|
7
|
+
const { openTab } = useRouting();
|
|
8
|
+
|
|
4
9
|
const downloadFile = (id: string): void => {
|
|
5
|
-
|
|
10
|
+
openTab(FILE_URL(id, authToken.value));
|
|
6
11
|
};
|
|
7
12
|
|
|
8
13
|
const readFile = (file: File): Promise<string | ArrayBuffer | null> => {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type RouteLocation, useRouter } from "vue-router";
|
|
2
|
+
|
|
3
|
+
import { useAppHost } from "@dative-gpi/foundation-shared-services/composables";
|
|
4
|
+
|
|
5
|
+
export const useRouting = () => {
|
|
6
|
+
const { host } = useAppHost();
|
|
7
|
+
const router = useRouter();
|
|
8
|
+
|
|
9
|
+
const handleRoutingEvent = (event: MouseEvent, target: string | RouteLocation, handleDefaultBehavior: boolean = false): void => {
|
|
10
|
+
// If a redirection is requested, check if it comes from an extension and act accordingly
|
|
11
|
+
if (event.ctrlKey || event.metaKey || event.button === 1) {
|
|
12
|
+
event.preventDefault();
|
|
13
|
+
openTab(target);
|
|
14
|
+
}
|
|
15
|
+
else if (handleDefaultBehavior) {
|
|
16
|
+
router.push(target);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const openTab = (target: string | RouteLocation): void => {
|
|
21
|
+
// Check if target is a href (string) or a to (RouteLocation), get the absolute url in either case
|
|
22
|
+
const href = typeof target === "string" ? target : router.resolve(target).href;
|
|
23
|
+
|
|
24
|
+
// If the app is in an iframe, open the link in a new tab with the parent iframe host
|
|
25
|
+
if (window.top != window.self && host.value) {
|
|
26
|
+
window.open(host.value + href, "_blank");
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
window.open(href, "_blank");
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
handleRoutingEvent,
|
|
35
|
+
openTab
|
|
36
|
+
};
|
|
37
|
+
}
|
package/config/urls/files.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { GATEWAY_URL } from "./base";
|
|
2
2
|
|
|
3
3
|
export const FILES_URL = () => `${GATEWAY_URL()}/files`;
|
|
4
|
-
export const FILE_URL = (fileId: string) =>
|
|
4
|
+
export const FILE_URL = (fileId: string, accessToken?: string) => {
|
|
5
|
+
let url = `${FILES_URL()}/${encodeURIComponent(fileId)}`;
|
|
6
|
+
if (accessToken) {
|
|
7
|
+
url += `?access_token=${encodeURIComponent(accessToken)}`;
|
|
8
|
+
}
|
|
9
|
+
return url;
|
|
10
|
+
};
|
package/config/urls/images.ts
CHANGED
|
@@ -3,17 +3,17 @@ import { GATEWAY_URL } from "./base";
|
|
|
3
3
|
export const IMAGES_URL = () => `${GATEWAY_URL()}/images`;
|
|
4
4
|
|
|
5
5
|
export const IMAGE_URL = (imageId: string) => `${IMAGES_URL()}/${encodeURIComponent(imageId)}`;
|
|
6
|
-
export const IMAGE_RAW_URL = (imageId: string,
|
|
6
|
+
export const IMAGE_RAW_URL = (imageId: string, accessToken?: string) => {
|
|
7
7
|
let url = `${IMAGE_URL(imageId)}/raw`;
|
|
8
|
-
if (
|
|
9
|
-
url += `?
|
|
8
|
+
if (accessToken) {
|
|
9
|
+
url += `?access_token=${encodeURIComponent(accessToken)}`;
|
|
10
10
|
}
|
|
11
11
|
return url;
|
|
12
12
|
};
|
|
13
|
-
export const IMAGE_THUMBNAIL_URL = (imageId: string,
|
|
13
|
+
export const IMAGE_THUMBNAIL_URL = (imageId: string, accessToken?: string) => {
|
|
14
14
|
let url = `${IMAGE_URL(imageId)}/thumbnail`;
|
|
15
|
-
if (
|
|
16
|
-
url += `?
|
|
15
|
+
if (accessToken) {
|
|
16
|
+
url += `?access_token=${encodeURIComponent(accessToken)}`;
|
|
17
17
|
}
|
|
18
18
|
return url;
|
|
19
19
|
};
|
package/config/urls/index.ts
CHANGED
|
@@ -2,9 +2,11 @@ export * from "./authTokens";
|
|
|
2
2
|
export * from "./files";
|
|
3
3
|
export * from "./images";
|
|
4
4
|
export * from "./languages";
|
|
5
|
+
export * from "./legalInformations";
|
|
5
6
|
export * from "./notifications";
|
|
6
7
|
export * from "./organisations";
|
|
7
8
|
export * from "./terminals";
|
|
8
9
|
export * from "./timeZones";
|
|
9
10
|
export * from "./translations";
|
|
11
|
+
export * from "./userLegalInformations";
|
|
10
12
|
export * from "./users";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dative-gpi/foundation-shared-services",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.67-map-edit",
|
|
5
5
|
"description": "",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
"author": "",
|
|
11
11
|
"license": "ISC",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@dative-gpi/foundation-shared-domain": "1.0.
|
|
13
|
+
"@dative-gpi/foundation-shared-domain": "1.0.67-map-edit"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"@dative-gpi/bones-ui": "^0.0
|
|
16
|
+
"@dative-gpi/bones-ui": "^1.0.0",
|
|
17
17
|
"@microsoft/signalr": "^8.0.0",
|
|
18
|
-
"vue": "^3.4.
|
|
18
|
+
"vue": "^3.4.38",
|
|
19
19
|
"vue-router": "^4.3.0"
|
|
20
20
|
},
|
|
21
|
-
"gitHead": "
|
|
21
|
+
"gitHead": "725635256ebf2bb6450c38e5a3077fb907ea550c"
|
|
22
22
|
}
|
package/tools/hubFactory.ts
CHANGED
|
@@ -10,7 +10,7 @@ export class HubFactory {
|
|
|
10
10
|
|
|
11
11
|
let connection: signalR.HubConnection | null = null;
|
|
12
12
|
let subscribed = false;
|
|
13
|
-
|
|
13
|
+
const watchManySubscribers = ref(0);
|
|
14
14
|
const watcheds = ref<string[]>([]);
|
|
15
15
|
|
|
16
16
|
return () => {
|
|
@@ -24,7 +24,7 @@ export class HubFactory {
|
|
|
24
24
|
|
|
25
25
|
configureHooks(connection, {
|
|
26
26
|
isWatched: (id: string) => watcheds.value.includes(id),
|
|
27
|
-
hasWatchers: () => watchManySubscribers > 0,
|
|
27
|
+
hasWatchers: () => watchManySubscribers.value > 0,
|
|
28
28
|
})
|
|
29
29
|
}
|
|
30
30
|
if (connection.state !== signalR.HubConnectionState.Connected) {
|
|
@@ -48,7 +48,7 @@ export class HubFactory {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const hasSubscribers = computed(() => watcheds.value.length > 0 || watchManySubscribers > 0);
|
|
51
|
+
const hasSubscribers = computed(() => watcheds.value.length > 0 || watchManySubscribers.value > 0);
|
|
52
52
|
|
|
53
53
|
watch(hasSubscribers, async (value) => {
|
|
54
54
|
if (value) {
|
|
@@ -68,11 +68,11 @@ export class HubFactory {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
const subscribeToMany = () => {
|
|
71
|
-
watchManySubscribers++;
|
|
71
|
+
watchManySubscribers.value++;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
const unsubscribeFromMany = () => {
|
|
75
|
-
watchManySubscribers--;
|
|
75
|
+
watchManySubscribers.value--;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
return {
|