@uxland/primary-shell 5.3.6 → 5.3.7
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/dist/index.js +62 -32
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +25 -12
- package/dist/index.umd.cjs.map +1 -1
- package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/list/merge-history-items-and-subgroups/merge-history-items-and-subgroups.d.ts +12 -0
- package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/list/merge-history-items-and-subgroups/merge-history-items-and-subgroups.test.d.ts +1 -0
- package/package.json +1 -1
- package/src/internal-plugins/activity-history/activity-history-item/list/UI/timeline/template.ts +40 -21
- package/src/internal-plugins/activity-history/activity-history-item/list/merge-history-items-and-subgroups/merge-history-items-and-subgroups.test.ts +93 -0
- package/src/internal-plugins/activity-history/activity-history-item/list/merge-history-items-and-subgroups/merge-history-items-and-subgroups.ts +34 -0
- package/src/internal-plugins/activity-history/activity-history-item/list/sort-history-items-by-date/sort-history-items-by-date.ts +31 -26
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IActivityHistoryGroup, IActivityHistoryItemWithComponent, IActivityHistorySubGroup } from '../../domain/model';
|
|
2
|
+
|
|
3
|
+
export type ActivityHistoryEntry = {
|
|
4
|
+
type: "item";
|
|
5
|
+
date: Date;
|
|
6
|
+
item: IActivityHistoryItemWithComponent;
|
|
7
|
+
} | {
|
|
8
|
+
type: "subGroup";
|
|
9
|
+
date: Date;
|
|
10
|
+
subGroup: IActivityHistorySubGroup;
|
|
11
|
+
};
|
|
12
|
+
export declare const mergeHistoryItemsAndSubgroups: (group: IActivityHistoryGroup) => ActivityHistoryEntry[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
package/src/internal-plugins/activity-history/activity-history-item/list/UI/timeline/template.ts
CHANGED
|
@@ -14,6 +14,10 @@ import {
|
|
|
14
14
|
import { translate } from "../../../../localization";
|
|
15
15
|
import { virtualize } from "@lit-labs/virtualizer/virtualize.js";
|
|
16
16
|
import { hasItemDivider, shouldShowRole } from "../../../domain/business-rules";
|
|
17
|
+
import {
|
|
18
|
+
ActivityHistoryEntry,
|
|
19
|
+
mergeHistoryItemsAndSubgroups,
|
|
20
|
+
} from "../../merge-history-items-and-subgroups/merge-history-items-and-subgroups";
|
|
17
21
|
|
|
18
22
|
export const template = (props: ActivityHistoryTimeline) => {
|
|
19
23
|
if (!props._hasUpdatedOnce) {
|
|
@@ -32,26 +36,41 @@ export const template = (props: ActivityHistoryTimeline) => {
|
|
|
32
36
|
${visitHeaderTemplate(props, itemGroup.items[0] || itemGroup.subGroups[0]?.items[0])}
|
|
33
37
|
<div class="visit__items">
|
|
34
38
|
${repeat(
|
|
35
|
-
itemGroup
|
|
36
|
-
(
|
|
37
|
-
(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
39
|
+
mergeHistoryItemsAndSubgroups(itemGroup),
|
|
40
|
+
(entry) => (entry.type === "item" ? entry.item.id : entry.subGroup.id),
|
|
41
|
+
(entry: ActivityHistoryEntry) => {
|
|
42
|
+
if (entry.type === "item") {
|
|
43
|
+
const item = entry.item;
|
|
44
|
+
return html`
|
|
45
|
+
<div
|
|
46
|
+
class="item"
|
|
47
|
+
?has-divider=${hasItemDivider(item, itemGroup.items as IActivityHistoryItemWithComponent[])}
|
|
48
|
+
>
|
|
49
|
+
${item.component}
|
|
50
|
+
</div>
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
const subGroup = entry.subGroup;
|
|
54
|
+
return html`
|
|
55
|
+
<div class="diagnostics">
|
|
56
|
+
${diagnosticHeaderTemplate(subGroup.items[0])}
|
|
57
|
+
<div class="diagnostics__items">
|
|
58
|
+
${repeat(
|
|
59
|
+
subGroup.items,
|
|
60
|
+
(item) => item.id,
|
|
61
|
+
(item: IActivityHistoryItemWithComponent) => html`
|
|
62
|
+
<div
|
|
63
|
+
class="item"
|
|
64
|
+
?has-divider=${hasItemDivider(item, subGroup.items as IActivityHistoryItemWithComponent[])}
|
|
65
|
+
>
|
|
66
|
+
${item.component}
|
|
67
|
+
</div>
|
|
68
|
+
`,
|
|
69
|
+
)}
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
`;
|
|
73
|
+
},
|
|
55
74
|
)}
|
|
56
75
|
</div>
|
|
57
76
|
</div>
|
|
@@ -96,7 +115,7 @@ const renderProfessionalValues = (props: ActivityHistoryTimeline, item: IActivit
|
|
|
96
115
|
const professionalItems = [
|
|
97
116
|
props.highlighted(item.professional.name),
|
|
98
117
|
showRole ? props.highlighted(item.professional.role.description) : null,
|
|
99
|
-
props.highlighted(item.center.description),
|
|
118
|
+
props.highlighted(item.up.description) ?? props.highlighted(item.center.description),
|
|
100
119
|
props.highlighted(item.professional.speciality.description),
|
|
101
120
|
props.highlighted(item.service.description),
|
|
102
121
|
].filter(Boolean);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { mergeHistoryItemsAndSubgroups } from "./merge-history-items-and-subgroups";
|
|
3
|
+
import {
|
|
4
|
+
IActivityHistoryGroup,
|
|
5
|
+
IActivityHistoryItemWithComponent,
|
|
6
|
+
IActivityHistorySubGroup,
|
|
7
|
+
} from "../../domain/model";
|
|
8
|
+
|
|
9
|
+
type RenderEntry =
|
|
10
|
+
| { type: "item"; date: Date; item: IActivityHistoryItemWithComponent }
|
|
11
|
+
| { type: "subGroup"; date: Date; subGroup: IActivityHistorySubGroup };
|
|
12
|
+
|
|
13
|
+
describe("mergeHistoryItemsAndSubgroups", () => {
|
|
14
|
+
it("should sort only items by date descending", () => {
|
|
15
|
+
const group: IActivityHistoryGroup = {
|
|
16
|
+
id: "g1",
|
|
17
|
+
items: [
|
|
18
|
+
{ id: "i1", date: "2025-05-05T10:00:00Z", component: "<div/>" },
|
|
19
|
+
{ id: "i2", date: "2025-05-05T12:00:00Z", component: "<div/>" },
|
|
20
|
+
{ id: "i3", date: "2025-05-05T08:00:00Z", component: "<div/>" },
|
|
21
|
+
],
|
|
22
|
+
subGroups: [],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const result = mergeHistoryItemsAndSubgroups(group) as RenderEntry[];
|
|
26
|
+
const ids = result.map((e) => (e.type === "item" ? e.item.id : e.subGroup.id));
|
|
27
|
+
|
|
28
|
+
expect(ids).toEqual(["i2", "i1", "i3"]);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should sort only subGroups by their most recent item", () => {
|
|
32
|
+
const subGroupA: IActivityHistorySubGroup = {
|
|
33
|
+
id: "sgA",
|
|
34
|
+
items: [{ id: "a1", date: "2025-05-05T09:00:00Z", component: "<div/>" }],
|
|
35
|
+
};
|
|
36
|
+
const subGroupB: IActivityHistorySubGroup = {
|
|
37
|
+
id: "sgB",
|
|
38
|
+
items: [
|
|
39
|
+
{ id: "b1", date: "2025-05-05T15:00:00Z", component: "<div/>" },
|
|
40
|
+
{ id: "b2", date: "2025-05-05T14:00:00Z", component: "<div/>" },
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
const group: IActivityHistoryGroup = {
|
|
44
|
+
id: "g2",
|
|
45
|
+
items: [],
|
|
46
|
+
subGroups: [subGroupA, subGroupB],
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const result = mergeHistoryItemsAndSubgroups(group) as RenderEntry[];
|
|
50
|
+
const ids = result.map((e) => (e.type === "item" ? e.item.id : e.subGroup.id));
|
|
51
|
+
|
|
52
|
+
expect(ids).toEqual(["sgB", "sgA"]);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("should interleave items and subGroups by date", () => {
|
|
56
|
+
const group: IActivityHistoryGroup = {
|
|
57
|
+
id: "g3",
|
|
58
|
+
items: [
|
|
59
|
+
{ id: "i1", date: "2025-05-05T10:00:00Z", component: "<div/>" },
|
|
60
|
+
{ id: "i2", date: "2025-05-05T14:00:00Z", component: "<div/>" },
|
|
61
|
+
],
|
|
62
|
+
subGroups: [
|
|
63
|
+
{
|
|
64
|
+
id: "sg1",
|
|
65
|
+
items: [{ id: "s1", date: "2025-05-05T12:00:00Z", component: "<div/>" }],
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const result = mergeHistoryItemsAndSubgroups(group) as RenderEntry[];
|
|
71
|
+
const ids = result.map((e) => (e.type === "item" ? e.item.id : e.subGroup.id));
|
|
72
|
+
|
|
73
|
+
// Expected order: i2 (14:00), sg1 (12:00), i1 (10:00)
|
|
74
|
+
expect(ids).toEqual(["i2", "sg1", "i1"]);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should place subGroups without items at the end", () => {
|
|
78
|
+
const emptySubGroup: IActivityHistorySubGroup = {
|
|
79
|
+
id: "sgEmpty",
|
|
80
|
+
items: [],
|
|
81
|
+
};
|
|
82
|
+
const group: IActivityHistoryGroup = {
|
|
83
|
+
id: "g4",
|
|
84
|
+
items: [{ id: "i1", date: "2025-05-05T11:00:00Z", component: "<div/>" }],
|
|
85
|
+
subGroups: [emptySubGroup],
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const result = mergeHistoryItemsAndSubgroups(group) as RenderEntry[];
|
|
89
|
+
const ids = result.map((e) => (e.type === "item" ? e.item.id : e.subGroup.id));
|
|
90
|
+
|
|
91
|
+
expect(ids).toEqual(["i1", "sgEmpty"]);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
IActivityHistoryGroup,
|
|
3
|
+
IActivityHistoryItemWithComponent,
|
|
4
|
+
IActivityHistorySubGroup,
|
|
5
|
+
} from "../../domain/model";
|
|
6
|
+
|
|
7
|
+
export type ActivityHistoryEntry =
|
|
8
|
+
| { type: "item"; date: Date; item: IActivityHistoryItemWithComponent }
|
|
9
|
+
| { type: "subGroup"; date: Date; subGroup: IActivityHistorySubGroup };
|
|
10
|
+
|
|
11
|
+
export const mergeHistoryItemsAndSubgroups = (
|
|
12
|
+
group: IActivityHistoryGroup,
|
|
13
|
+
): ActivityHistoryEntry[] => {
|
|
14
|
+
// 1. Prepara los items sueltos
|
|
15
|
+
const itemEntries: ActivityHistoryEntry[] = group.items.map((item) => ({
|
|
16
|
+
type: "item",
|
|
17
|
+
date: new Date(item.date),
|
|
18
|
+
item,
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
// 2. Prepara los subGroups, usando la fecha del ítem más reciente de cada subgrupo
|
|
22
|
+
const subGroupEntries: ActivityHistoryEntry[] = group.subGroups.map((subGroup) => {
|
|
23
|
+
// Asumimos que subGroup.items ya está ordenado de más reciente a más antiguo
|
|
24
|
+
const mostRecent = subGroup.items.length ? new Date(subGroup.items[0].date) : new Date(0);
|
|
25
|
+
return {
|
|
26
|
+
type: "subGroup",
|
|
27
|
+
date: mostRecent,
|
|
28
|
+
subGroup,
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// 3. Fusiona y ordena
|
|
33
|
+
return [...itemEntries, ...subGroupEntries].sort((a, b) => b.date.getTime() - a.date.getTime());
|
|
34
|
+
};
|
|
@@ -1,47 +1,52 @@
|
|
|
1
1
|
import { IActivityHistoryGroup } from "../../domain/model";
|
|
2
2
|
|
|
3
3
|
export const sortGroupsByMostRecentDate = (arr: IActivityHistoryGroup[]) => {
|
|
4
|
-
// Helper
|
|
5
|
-
const getMostRecentDate = (items) => {
|
|
4
|
+
// Helper: obtener la fecha más reciente de una lista de items
|
|
5
|
+
const getMostRecentDate = (items: { date: string }[]): Date => {
|
|
6
6
|
return items.reduce((latest, item) => {
|
|
7
7
|
const itemDate = new Date(item.date);
|
|
8
8
|
return itemDate > latest ? itemDate : latest;
|
|
9
|
-
}, new Date(0));
|
|
9
|
+
}, new Date(0));
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
//
|
|
13
|
-
const sortItemsByDate = (items) => {
|
|
14
|
-
return items.sort((a, b) => new Date(b.date) - new Date(a.date));
|
|
12
|
+
// Ordenar items de más reciente a más antiguo
|
|
13
|
+
const sortItemsByDate = (items: { date: string }[]) => {
|
|
14
|
+
return items.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// Collect dates from group items
|
|
22
|
-
if (group.items.length > 0) {
|
|
23
|
-
allDates.push(getMostRecentDate(group.items));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Collect dates from subgroups items
|
|
27
|
-
group.subGroups.forEach((subGroup) => {
|
|
28
|
-
if (subGroup.items.length > 0) {
|
|
29
|
-
allDates.push(getMostRecentDate(subGroup.items));
|
|
30
|
-
}
|
|
31
|
-
});
|
|
17
|
+
// Obtener la fecha más reciente de un subgrupo
|
|
18
|
+
const getSubGroupMostRecentDate = (subGroup: { items: { date: string }[] }): Date => {
|
|
19
|
+
return getMostRecentDate(subGroup.items);
|
|
20
|
+
};
|
|
32
21
|
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
// Obtener la fecha más reciente de un grupo (considerando sus items y subgroups)
|
|
23
|
+
const getGroupMostRecentDate = (group: IActivityHistoryGroup): Date => {
|
|
24
|
+
const itemDates = group.items.length > 0 ? [getMostRecentDate(group.items)] : [];
|
|
25
|
+
const subGroupDates = group.subGroups.map(getSubGroupMostRecentDate);
|
|
26
|
+
const allDates = [...itemDates, ...subGroupDates];
|
|
27
|
+
return allDates.length > 0
|
|
28
|
+
? new Date(Math.max(...allDates.map((d) => d.getTime())))
|
|
29
|
+
: new Date(0);
|
|
35
30
|
};
|
|
36
31
|
|
|
37
|
-
//
|
|
32
|
+
// Procesar cada grupo
|
|
38
33
|
arr.forEach((group) => {
|
|
34
|
+
// Ordenar items del grupo
|
|
39
35
|
group.items = sortItemsByDate(group.items);
|
|
36
|
+
|
|
37
|
+
// Ordenar items de cada subgrupo
|
|
40
38
|
group.subGroups.forEach((subGroup) => {
|
|
41
39
|
subGroup.items = sortItemsByDate(subGroup.items);
|
|
42
40
|
});
|
|
41
|
+
|
|
42
|
+
// Ordenar subgrupos según el item más reciente en cada uno
|
|
43
|
+
group.subGroups.sort(
|
|
44
|
+
(a, b) => getSubGroupMostRecentDate(b).getTime() - getSubGroupMostRecentDate(a).getTime(),
|
|
45
|
+
);
|
|
43
46
|
});
|
|
44
47
|
|
|
45
|
-
//
|
|
46
|
-
return arr.sort(
|
|
48
|
+
// Finalmente, ordenar los grupos por su fecha más reciente
|
|
49
|
+
return arr.sort(
|
|
50
|
+
(a, b) => getGroupMostRecentDate(b).getTime() - getGroupMostRecentDate(a).getTime(),
|
|
51
|
+
);
|
|
47
52
|
};
|