@startinblox/components-ds4go 2.2.4 → 3.0.0
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/.gitlab-ci.yml +8 -2
- package/AGENTS.md +516 -0
- package/cypress/component/no-component-test.cy.ts +9 -0
- package/cypress/e2e/helpers/components/setupCacheInvalidation.cy.ts +512 -0
- package/cypress/e2e/helpers/components/setupCacheOnResourceReady.cy.ts +483 -0
- package/cypress/e2e/helpers/components/setupComponentSubscriptions.cy.ts +239 -0
- package/cypress/e2e/helpers/components/setupOnSaveReset.cy.ts +380 -0
- package/cypress/e2e/helpers/datas/checkValueInIntervalRecursive.cy.ts +563 -0
- package/cypress/e2e/helpers/datas/dataBuilder.cy.ts +508 -0
- package/cypress/e2e/helpers/datas/filterGenerator.cy.ts +285 -0
- package/cypress/e2e/helpers/datas/filterObjectByDateAfter.cy.ts +389 -0
- package/cypress/e2e/helpers/datas/filterObjectByDateInterval.cy.ts +613 -0
- package/cypress/e2e/helpers/datas/filterObjectById.cy.ts +276 -0
- package/cypress/e2e/helpers/datas/filterObjectByInterval.cy.ts +237 -0
- package/cypress/e2e/helpers/datas/filterObjectByNamedValue.cy.ts +299 -0
- package/cypress/e2e/helpers/datas/filterObjectByType.cy.ts +307 -0
- package/cypress/e2e/helpers/datas/filterObjectByValue.cy.ts +375 -0
- package/cypress/e2e/helpers/datas/sort.cy.ts +293 -0
- package/cypress/e2e/helpers/ui/formatDate.cy.ts +233 -0
- package/cypress/e2e/helpers/utils/requestNavigation.cy.ts +257 -0
- package/cypress/e2e/helpers/utils/uniq.cy.ts +160 -0
- package/cypress/support/e2e.ts +1 -0
- package/cypress.config.ts +2 -0
- package/dist/index.js +932 -734
- package/locales/en.xlf +75 -0
- package/package.json +10 -10
- package/src/components/solid-boilerplate.ts +76 -0
- package/src/components/solid-fact-bundle-creation.ts +202 -59
- package/src/helpers/components/componentObjectHandler.ts +5 -7
- package/src/helpers/components/componentObjectsHandler.ts +8 -3
- package/src/helpers/components/orbitComponent.ts +87 -68
- package/src/helpers/components/setupCacheInvalidation.ts +50 -23
- package/src/helpers/components/setupCacheOnResourceReady.ts +42 -23
- package/src/helpers/components/setupComponentSubscriptions.ts +10 -9
- package/src/helpers/components/setupOnSaveReset.ts +27 -5
- package/src/helpers/datas/checkValueInIntervalRecursive.ts +66 -0
- package/src/helpers/datas/dataBuilder.ts +4 -4
- package/src/helpers/datas/filterGenerator.ts +13 -10
- package/src/helpers/datas/filterObjectByDateAfter.ts +3 -3
- package/src/helpers/datas/filterObjectByDateInterval.ts +44 -0
- package/src/helpers/datas/filterObjectById.ts +7 -6
- package/src/helpers/datas/filterObjectByInterval.ts +6 -110
- package/src/helpers/datas/filterObjectByNamedValue.ts +35 -33
- package/src/helpers/datas/filterObjectByType.ts +3 -3
- package/src/helpers/datas/filterObjectByValue.ts +17 -16
- package/src/helpers/datas/sort.ts +50 -23
- package/src/helpers/index.ts +2 -0
- package/src/helpers/ui/formatDate.ts +14 -1
- package/src/helpers/utils/requestNavigation.ts +5 -2
- package/src/helpers/utils/uniq.ts +1 -1
- package/src/styles/fact-bundle-creation.scss +102 -0
- package/cypress/component/solid-boilerplate.cy.ts +0 -9
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { UnknownResource } from "@src/component";
|
|
2
|
+
import checkValueInIntervalRecursive from "@src/helpers/datas/checkValueInIntervalRecursive";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Filters an array of Resource objects based on whether a specific date/number property
|
|
6
|
+
* falls within a given interval string (e.g., "2023-01-01/2023-01-31" or "3/6").
|
|
7
|
+
* Checks the property recursively within nested objects and arrays.
|
|
8
|
+
*/
|
|
9
|
+
const filterObjectByDateInterval = (
|
|
10
|
+
array: UnknownResource[],
|
|
11
|
+
propName: string,
|
|
12
|
+
interval: string,
|
|
13
|
+
): UnknownResource[] => {
|
|
14
|
+
if (!propName || !interval || typeof interval !== "string") {
|
|
15
|
+
return array;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const [startStr, endStr] = interval.split("/");
|
|
19
|
+
if (!startStr) {
|
|
20
|
+
return array;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const startDate = new Date(startStr);
|
|
24
|
+
|
|
25
|
+
const endDate = new Date(endStr ?? startStr);
|
|
26
|
+
|
|
27
|
+
if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) {
|
|
28
|
+
console.warn(`Invalid date interval provided: ${interval}`);
|
|
29
|
+
return array;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
endDate.setHours(23, 59, 59, 999);
|
|
33
|
+
|
|
34
|
+
if (startDate > endDate) {
|
|
35
|
+
console.warn(`Start date is after end date in interval: ${interval}`);
|
|
36
|
+
return array;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return array.filter((obj) =>
|
|
40
|
+
checkValueInIntervalRecursive(obj, propName, startDate, endDate),
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default filterObjectByDateInterval;
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UnknownResource } from "@src/component";
|
|
2
2
|
|
|
3
3
|
const filterObjectById = (
|
|
4
|
-
array:
|
|
4
|
+
array: UnknownResource[],
|
|
5
5
|
propName: string,
|
|
6
|
-
targetId: string
|
|
7
|
-
):
|
|
6
|
+
targetId: string,
|
|
7
|
+
): UnknownResource[] => {
|
|
8
8
|
if (!propName || !targetId) {
|
|
9
9
|
return array;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
const propPath = propName.split(".");
|
|
13
|
+
|
|
12
14
|
return array.filter((obj) => {
|
|
13
15
|
let current = obj;
|
|
14
|
-
const propPath = propName.split(".");
|
|
15
16
|
|
|
16
17
|
for (const segment of propPath) {
|
|
17
18
|
if (current && typeof current === "object" && segment in current) {
|
|
@@ -43,7 +44,7 @@ const filterObjectById = (
|
|
|
43
44
|
typeof item === "object" &&
|
|
44
45
|
item !== null &&
|
|
45
46
|
"@id" in item &&
|
|
46
|
-
item["@id"] === targetId
|
|
47
|
+
item["@id"] === targetId,
|
|
47
48
|
);
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -1,115 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
function isValidDateValue(value: unknown): value is string | number | Date {
|
|
5
|
-
if (
|
|
6
|
-
typeof value !== "string" &&
|
|
7
|
-
typeof value !== "number" &&
|
|
8
|
-
!(value instanceof Date)
|
|
9
|
-
) {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return !Number.isNaN(new Date(value).getTime());
|
|
14
|
-
}
|
|
15
|
-
const checkValueInIntervalRecursive = (
|
|
16
|
-
data: any,
|
|
17
|
-
propName: string,
|
|
18
|
-
startValue: number | Date,
|
|
19
|
-
endValue: number | Date
|
|
20
|
-
): boolean => {
|
|
21
|
-
if (data === null || data === undefined) {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const propPath = propName.split(".");
|
|
26
|
-
let current = data;
|
|
27
|
-
|
|
28
|
-
for (const segment of propPath) {
|
|
29
|
-
if (current && typeof current === "object" && segment in current) {
|
|
30
|
-
current = current[segment];
|
|
31
|
-
} else {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (typeof current === "number") {
|
|
37
|
-
if (typeof startValue === "number" && typeof endValue === "number") {
|
|
38
|
-
if (startValue <= current && current <= endValue) {
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
} else if (isValidDateValue(current)) {
|
|
43
|
-
const date = new Date(current);
|
|
44
|
-
if (startValue instanceof Date && endValue instanceof Date) {
|
|
45
|
-
if (startValue <= date && date <= endValue) {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
} else {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (Array.isArray(data)) {
|
|
54
|
-
return data.some((item) =>
|
|
55
|
-
checkValueInIntervalRecursive(item, propName, startValue, endValue)
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (typeof data === "object") {
|
|
60
|
-
return Object.entries(data).some(([key, value]) =>
|
|
61
|
-
checkValueInIntervalRecursive(value, propName, startValue, endValue)
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return false;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Filters an array of Resource objects based on whether a specific date/number property
|
|
70
|
-
* falls within a given interval string (e.g., "2023-01-01/2023-01-31" or "3/6").
|
|
71
|
-
* Checks the property recursively within nested objects and arrays.
|
|
72
|
-
*/
|
|
73
|
-
const filterObjectByDateInterval = (
|
|
74
|
-
array: Resource[],
|
|
75
|
-
propName: string,
|
|
76
|
-
interval: string
|
|
77
|
-
): Resource[] => {
|
|
78
|
-
if (!propName || !interval || typeof interval !== "string") {
|
|
79
|
-
return array;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const [startStr, endStr] = interval.split("/");
|
|
83
|
-
if (!startStr) {
|
|
84
|
-
return array;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const startDate = new Date(startStr);
|
|
88
|
-
|
|
89
|
-
const endDate = new Date(endStr ?? startStr);
|
|
90
|
-
|
|
91
|
-
if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) {
|
|
92
|
-
console.warn(`Invalid date interval provided: ${interval}`);
|
|
93
|
-
return array;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
endDate.setHours(23, 59, 59, 999);
|
|
97
|
-
|
|
98
|
-
if (startDate > endDate) {
|
|
99
|
-
console.warn(`Start date is after end date in interval: ${interval}`);
|
|
100
|
-
return array;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return array.filter((obj) =>
|
|
104
|
-
checkValueInIntervalRecursive(obj, propName, startDate, endDate)
|
|
105
|
-
);
|
|
106
|
-
};
|
|
1
|
+
import type { UnknownResource } from "@src/component";
|
|
2
|
+
import checkValueInIntervalRecursive from "@src/helpers/datas/checkValueInIntervalRecursive";
|
|
107
3
|
|
|
108
4
|
const filterObjectByInterval = (
|
|
109
|
-
array:
|
|
5
|
+
array: UnknownResource[],
|
|
110
6
|
propName: string,
|
|
111
|
-
interval: string
|
|
112
|
-
):
|
|
7
|
+
interval: string,
|
|
8
|
+
): UnknownResource[] => {
|
|
113
9
|
if (!propName || !interval || typeof interval !== "string") {
|
|
114
10
|
return array;
|
|
115
11
|
}
|
|
@@ -126,7 +22,7 @@ const filterObjectByInterval = (
|
|
|
126
22
|
}
|
|
127
23
|
|
|
128
24
|
return array.filter((obj) =>
|
|
129
|
-
checkValueInIntervalRecursive(obj, propName, startStr, endStr)
|
|
25
|
+
checkValueInIntervalRecursive(obj, propName, startStr, endStr),
|
|
130
26
|
);
|
|
131
27
|
};
|
|
132
28
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UnknownResource } from "@src/component";
|
|
2
2
|
|
|
3
3
|
const calculatePertinenceScoreRecursive = (
|
|
4
4
|
data: any,
|
|
5
5
|
lowerCaseString: string,
|
|
6
|
-
isTargetProperty: boolean
|
|
6
|
+
isTargetProperty: boolean,
|
|
7
7
|
): number => {
|
|
8
8
|
if (data === null || data === undefined) {
|
|
9
9
|
return 0;
|
|
@@ -18,7 +18,7 @@ const calculatePertinenceScoreRecursive = (
|
|
|
18
18
|
|
|
19
19
|
const escapedString = lowerCaseString.replace(
|
|
20
20
|
/[.*+?^${}()|[\]\\]/g,
|
|
21
|
-
"\\$&"
|
|
21
|
+
"\\$&",
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
const wholeWordRegex = new RegExp(`\\b${escapedString}\\b`);
|
|
@@ -40,8 +40,8 @@ const calculatePertinenceScoreRecursive = (
|
|
|
40
40
|
calculatePertinenceScoreRecursive(
|
|
41
41
|
item,
|
|
42
42
|
lowerCaseString,
|
|
43
|
-
isTargetProperty
|
|
44
|
-
)
|
|
43
|
+
isTargetProperty,
|
|
44
|
+
),
|
|
45
45
|
);
|
|
46
46
|
if (maxScore === 2) break;
|
|
47
47
|
}
|
|
@@ -55,8 +55,8 @@ const calculatePertinenceScoreRecursive = (
|
|
|
55
55
|
calculatePertinenceScoreRecursive(
|
|
56
56
|
value,
|
|
57
57
|
lowerCaseString,
|
|
58
|
-
isTargetProperty
|
|
59
|
-
)
|
|
58
|
+
isTargetProperty,
|
|
59
|
+
),
|
|
60
60
|
);
|
|
61
61
|
if (maxScore === 2) break;
|
|
62
62
|
}
|
|
@@ -64,40 +64,42 @@ const calculatePertinenceScoreRecursive = (
|
|
|
64
64
|
};
|
|
65
65
|
|
|
66
66
|
const filterObjectByNamedValue = (
|
|
67
|
-
array:
|
|
67
|
+
array: UnknownResource[],
|
|
68
68
|
propName: string,
|
|
69
|
-
searchString: string
|
|
70
|
-
):
|
|
69
|
+
searchString: string,
|
|
70
|
+
): UnknownResource[] => {
|
|
71
71
|
if (!propName || !searchString || searchString.trim() === "") {
|
|
72
72
|
return array;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
const lowerCaseString = searchString.toLowerCase();
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
current
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
76
|
+
const propPath = propName.split(".");
|
|
77
|
+
|
|
78
|
+
return array
|
|
79
|
+
.map((obj) => {
|
|
80
|
+
let current: any = obj;
|
|
81
|
+
for (const segment of propPath) {
|
|
82
|
+
if (current && typeof current === "object" && segment in current) {
|
|
83
|
+
current = current[segment];
|
|
84
|
+
} else {
|
|
85
|
+
current = null;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
86
88
|
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
let score = 0;
|
|
90
|
-
if (current) {
|
|
91
|
-
score = calculatePertinenceScoreRecursive(current, lowerCaseString, true);
|
|
92
|
-
}
|
|
93
|
-
return { obj, score };
|
|
94
|
-
});
|
|
95
89
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
90
|
+
let score = 0;
|
|
91
|
+
if (current) {
|
|
92
|
+
score = calculatePertinenceScoreRecursive(
|
|
93
|
+
current,
|
|
94
|
+
lowerCaseString,
|
|
95
|
+
true,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
return { obj, score };
|
|
99
|
+
})
|
|
100
|
+
.filter((item) => item.score > 0)
|
|
101
|
+
.sort((a, b) => b.score - a.score)
|
|
102
|
+
.map((item) => item.obj);
|
|
101
103
|
};
|
|
102
104
|
|
|
103
105
|
export default filterObjectByNamedValue;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UnknownResource } from "@src/component";
|
|
2
2
|
|
|
3
3
|
const filterObjectByType = (
|
|
4
|
-
array:
|
|
4
|
+
array: UnknownResource[],
|
|
5
5
|
targetType: string
|
|
6
|
-
):
|
|
6
|
+
): UnknownResource[] => {
|
|
7
7
|
if (!targetType) {
|
|
8
8
|
return array;
|
|
9
9
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UnknownResource } from "@src/component";
|
|
2
2
|
|
|
3
3
|
const calculatePertinenceScore = (
|
|
4
4
|
data: any,
|
|
5
5
|
lowerCaseString: string,
|
|
6
|
-
key?: string
|
|
6
|
+
key?: string,
|
|
7
7
|
): number => {
|
|
8
8
|
if (data === null || data === undefined) {
|
|
9
9
|
return 0;
|
|
@@ -14,7 +14,7 @@ const calculatePertinenceScore = (
|
|
|
14
14
|
|
|
15
15
|
const escapedString = lowerCaseString.replace(
|
|
16
16
|
/[.*+?^${}()|[\]\\]/g,
|
|
17
|
-
"\\$&"
|
|
17
|
+
"\\$&",
|
|
18
18
|
);
|
|
19
19
|
|
|
20
20
|
const wholeWordRegex = new RegExp(`\\b${escapedString}\\b`);
|
|
@@ -41,7 +41,7 @@ const calculatePertinenceScore = (
|
|
|
41
41
|
for (const item of data) {
|
|
42
42
|
maxScore = Math.max(
|
|
43
43
|
maxScore,
|
|
44
|
-
calculatePertinenceScore(item, lowerCaseString)
|
|
44
|
+
calculatePertinenceScore(item, lowerCaseString),
|
|
45
45
|
);
|
|
46
46
|
if (maxScore === 4) break;
|
|
47
47
|
}
|
|
@@ -52,30 +52,31 @@ const calculatePertinenceScore = (
|
|
|
52
52
|
for (const [currentKey, value] of Object.entries(data)) {
|
|
53
53
|
maxScore = Math.max(
|
|
54
54
|
maxScore,
|
|
55
|
-
calculatePertinenceScore(value, lowerCaseString, currentKey)
|
|
55
|
+
calculatePertinenceScore(value, lowerCaseString, currentKey),
|
|
56
56
|
);
|
|
57
57
|
if (maxScore === 4) break;
|
|
58
58
|
}
|
|
59
59
|
return maxScore;
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
const filterObjectByValue = (
|
|
62
|
+
const filterObjectByValue = (
|
|
63
|
+
array: UnknownResource[],
|
|
64
|
+
searchString: string,
|
|
65
|
+
): UnknownResource[] => {
|
|
63
66
|
if (!searchString || searchString.trim() === "") {
|
|
64
67
|
return array;
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
const lowerCaseString = searchString.toLowerCase();
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
obj
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return filteredObjects.map((item) => item.obj);
|
|
72
|
+
return array
|
|
73
|
+
.map((obj) => ({
|
|
74
|
+
obj,
|
|
75
|
+
score: calculatePertinenceScore(obj, lowerCaseString),
|
|
76
|
+
}))
|
|
77
|
+
.filter((item) => item.score > 0)
|
|
78
|
+
.sort((a, b) => b.score - a.score)
|
|
79
|
+
.map((item) => item.obj);
|
|
79
80
|
};
|
|
80
81
|
|
|
81
82
|
export default filterObjectByValue;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const getValueFromAnyKey = (obj: any, keys: string[]): any => {
|
|
2
2
|
let value = obj;
|
|
3
|
-
for (
|
|
4
|
-
if (value &&
|
|
5
|
-
value = value[
|
|
3
|
+
for (const key of keys) {
|
|
4
|
+
if (value && key in value) {
|
|
5
|
+
value = value[key];
|
|
6
6
|
} else {
|
|
7
|
-
|
|
7
|
+
return undefined;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
return value;
|
|
@@ -13,28 +13,55 @@ const getValueFromAnyKey = (obj: any, keys: string[]): any => {
|
|
|
13
13
|
type Sort = (arr: any[], k: string | string[], order?: "asc" | "desc") => any[];
|
|
14
14
|
|
|
15
15
|
const sort: Sort = (arr, k, order = "asc") => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
const keys = Array.isArray(k) ? k : [k];
|
|
17
|
+
const shouldReverse = order !== "asc";
|
|
18
|
+
|
|
19
|
+
const result = [...arr];
|
|
20
|
+
|
|
21
|
+
const getComparator = () => {
|
|
22
|
+
const sampleValue = getValueFromAnyKey(result[0], keys);
|
|
23
|
+
|
|
24
|
+
if (typeof sampleValue === "number") {
|
|
25
|
+
return (a: any, b: any) => {
|
|
26
|
+
const aN = getValueFromAnyKey(a, keys);
|
|
27
|
+
const bN = getValueFromAnyKey(b, keys);
|
|
28
|
+
if (aN == null) return bN == null ? 0 : 1;
|
|
29
|
+
if (bN == null) return -1;
|
|
30
|
+
return (aN as number) - (bN as number);
|
|
31
|
+
};
|
|
25
32
|
}
|
|
26
|
-
|
|
27
|
-
if (typeof
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
|
|
34
|
+
if (typeof sampleValue === "string") {
|
|
35
|
+
return (a: any, b: any) => {
|
|
36
|
+
const aN = getValueFromAnyKey(a, keys);
|
|
37
|
+
const bN = getValueFromAnyKey(b, keys);
|
|
38
|
+
if (aN == null) return bN == null ? 0 : 1;
|
|
39
|
+
if (bN == null) return -1;
|
|
40
|
+
return (aN as string).localeCompare(bN as string);
|
|
41
|
+
};
|
|
35
42
|
}
|
|
36
|
-
|
|
43
|
+
|
|
44
|
+
if (sampleValue instanceof Date) {
|
|
45
|
+
return (a: any, b: any) => {
|
|
46
|
+
const aN = getValueFromAnyKey(a, keys);
|
|
47
|
+
const bN = getValueFromAnyKey(b, keys);
|
|
48
|
+
if (aN == null) return bN == null ? 0 : 1;
|
|
49
|
+
if (bN == null) return -1;
|
|
50
|
+
return (aN as Date).getTime() - (bN as Date).getTime();
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
throw new TypeError(`Unsupported data type for key "${k}"`);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const comparator = getComparator();
|
|
58
|
+
|
|
59
|
+
result.sort((a, b) => {
|
|
60
|
+
const comparison = comparator(a, b);
|
|
61
|
+
return shouldReverse ? -comparison : comparison;
|
|
37
62
|
});
|
|
63
|
+
|
|
64
|
+
return result;
|
|
38
65
|
};
|
|
39
66
|
|
|
40
67
|
export default sort;
|
package/src/helpers/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import setupComponentSubscriptions from "@helpers/components/setupComponentSubsc
|
|
|
8
8
|
import setupOnSaveReset from "@helpers/components/setupOnSaveReset";
|
|
9
9
|
import filterGenerator from "@helpers/datas/filterGenerator";
|
|
10
10
|
import filterObjectByDateAfter from "@helpers/datas/filterObjectByDateAfter";
|
|
11
|
+
import filterObjectByDateInterval from "@helpers/datas/filterObjectByDateInterval";
|
|
11
12
|
import filterObjectById from "@helpers/datas/filterObjectById";
|
|
12
13
|
import filterObjectByInterval from "@helpers/datas/filterObjectByInterval";
|
|
13
14
|
import filterObjectByNamedValue from "@helpers/datas/filterObjectByNamedValue";
|
|
@@ -29,6 +30,7 @@ export {
|
|
|
29
30
|
filterObjectByNamedValue,
|
|
30
31
|
filterObjectByValue,
|
|
31
32
|
filterObjectByType,
|
|
33
|
+
filterObjectByDateInterval,
|
|
32
34
|
formatDate,
|
|
33
35
|
ComponentObjectHandler,
|
|
34
36
|
ComponentObjectsHandler,
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
const formatters = new Map<string, Intl.DateTimeFormat>();
|
|
2
|
+
|
|
3
|
+
const getFormatter = (format: Intl.DateTimeFormatOptions): Intl.DateTimeFormat => {
|
|
4
|
+
const key = JSON.stringify(format);
|
|
5
|
+
let formatter = formatters.get(key);
|
|
6
|
+
if (!formatter) {
|
|
7
|
+
formatter = new Intl.DateTimeFormat(undefined, format);
|
|
8
|
+
formatters.set(key, formatter);
|
|
9
|
+
}
|
|
10
|
+
return formatter;
|
|
11
|
+
};
|
|
12
|
+
|
|
1
13
|
const formatDate = (
|
|
2
14
|
originalDate: string | Date | undefined,
|
|
3
15
|
format: Intl.DateTimeFormatOptions = {
|
|
@@ -9,7 +21,8 @@ const formatDate = (
|
|
|
9
21
|
if (!originalDate) return "";
|
|
10
22
|
const date =
|
|
11
23
|
typeof originalDate === "string" ? new Date(originalDate) : originalDate;
|
|
12
|
-
const
|
|
24
|
+
const formatter = getFormatter(format);
|
|
25
|
+
const formattedDate = formatter.format(date);
|
|
13
26
|
if (typeof originalDate === "string" && formattedDate === "Invalid Date")
|
|
14
27
|
return originalDate;
|
|
15
28
|
return formattedDate;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
const requestNavigation = (
|
|
1
|
+
const requestNavigation = (
|
|
2
|
+
route: string,
|
|
3
|
+
resource: string | boolean = false,
|
|
4
|
+
) => {
|
|
2
5
|
window.dispatchEvent(
|
|
3
6
|
new CustomEvent("requestNavigation", {
|
|
4
7
|
detail: {
|
|
5
|
-
route
|
|
8
|
+
route,
|
|
6
9
|
resource: typeof resource === "string" ? { "@id": resource } : resource,
|
|
7
10
|
},
|
|
8
11
|
}),
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
@use "sass:meta";
|
|
2
|
+
|
|
3
|
+
@include meta.load-css("./_helpers/flex");
|
|
4
|
+
|
|
5
|
+
[slot="content"] {
|
|
6
|
+
height: 100%;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
section {
|
|
10
|
+
gap: var(--scale-400);
|
|
11
|
+
padding: var(--scale-900) 0;
|
|
12
|
+
height: calc(100% - var(--scale-900) * 2);
|
|
13
|
+
|
|
14
|
+
> div {
|
|
15
|
+
height: 100%;
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
gap: var(--scale-400);
|
|
19
|
+
flex: 1;
|
|
20
|
+
|
|
21
|
+
&:first-child {
|
|
22
|
+
max-width: 400px;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.card-grid {
|
|
28
|
+
flex: 1;
|
|
29
|
+
overflow-y: scroll;
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: row;
|
|
32
|
+
flex-wrap: wrap;
|
|
33
|
+
gap: 20px;
|
|
34
|
+
align-content: flex-start;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.card-grid-vertical {
|
|
38
|
+
justify-content: stretch;
|
|
39
|
+
|
|
40
|
+
tems-card-catalog {
|
|
41
|
+
width: 354px;
|
|
42
|
+
height: fit-content;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
tems-card-catalog {
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
|
|
49
|
+
&[selected] {
|
|
50
|
+
--color-border-primary: var(--color-surface-action-solid);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
tems-search-bar {
|
|
55
|
+
--scale-900: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.gap-400 {
|
|
59
|
+
gap: var(--scale-400);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
div.select {
|
|
63
|
+
align-items: flex-start;
|
|
64
|
+
display: flex;
|
|
65
|
+
flex-direction: column;
|
|
66
|
+
gap: var(--scale-200);
|
|
67
|
+
width: 100%;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
select {
|
|
71
|
+
width: 100%;
|
|
72
|
+
background-color: var(--color-surface-primary);
|
|
73
|
+
border: var(--border-width-sm) solid var(--color-border-primary);
|
|
74
|
+
border-radius: var(--border-radius-md);
|
|
75
|
+
color: var(--color-text-body);
|
|
76
|
+
font-family: var(--font-family-body);
|
|
77
|
+
font-size: var(--typography-size-body-sm);
|
|
78
|
+
font-style: normal;
|
|
79
|
+
font-weight: var(--font-weight-regular);
|
|
80
|
+
line-height: var(--line-height-body-sm);
|
|
81
|
+
letter-spacing: var(--font-letter-spacing-default);
|
|
82
|
+
padding: var(--scale-100) var(--scale-300);
|
|
83
|
+
appearance: none;
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
|
|
86
|
+
&:hover {
|
|
87
|
+
border: var(--border-width-sm) solid var(--color-border-action);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
option {
|
|
91
|
+
background-color: var(--color-surface-primary);
|
|
92
|
+
color: var(--color-text-body);
|
|
93
|
+
font-family: var(--font-family-body);
|
|
94
|
+
font-size: var(--typography-size-body-sm);
|
|
95
|
+
font-style: normal;
|
|
96
|
+
font-weight: var(--font-weight-regular);
|
|
97
|
+
line-height: var(--line-height-body-sm);
|
|
98
|
+
letter-spacing: var(--font-letter-spacing-default);
|
|
99
|
+
padding: var(--scale-100) var(--scale-300);
|
|
100
|
+
cursor: pointer;
|
|
101
|
+
}
|
|
102
|
+
}
|