@uxland/primary-shell 5.6.5 → 5.6.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 +53 -30
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +18 -13
- package/dist/index.umd.cjs.map +1 -1
- package/package.json +1 -1
- package/src/api/plugin-busy-manager/plugin-busy-list/styles.css +7 -0
- package/src/api/plugin-busy-manager/plugin-busy-list/template.ts +8 -1
- package/src/api/plugin-busy-manager/plugin-busy-manager.test.ts +15 -4
- package/src/api/plugin-busy-manager/plugin-busy-manager.ts +4 -1
- package/src/internal-plugins/activity-history/activity-history-item/filter/utils.ts +1 -1
- package/src/internal-plugins/activity-history/activity-history-item/list/UI/main-view/template.ts +2 -2
- package/src/internal-plugins/activity-history/activity-history-item/list/UI/timeline/template.ts +5 -5
- package/src/internal-plugins/activity-history/activity-history-item/list/group-history-items/group-history-items.ts +69 -36
- package/src/locales.ts +1 -1
package/package.json
CHANGED
|
@@ -17,4 +17,11 @@
|
|
|
17
17
|
display: flex;
|
|
18
18
|
flex-direction: column;
|
|
19
19
|
gap: 8px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.plugin-busy-item{
|
|
23
|
+
text-align: center;
|
|
24
|
+
border: var(--dss-border-width-sm) solid var(--color-neutral-100);
|
|
25
|
+
border-radius: var(--dss-radius-lg);
|
|
26
|
+
padding: var(--dss-spacing-md);
|
|
20
27
|
}
|
|
@@ -7,7 +7,14 @@ export const template = (props: PluginBusyList) => html`
|
|
|
7
7
|
<div class="container">
|
|
8
8
|
<div class="title">${translate("busyManager.title")}</div>
|
|
9
9
|
<div class="list">
|
|
10
|
-
${props.data?.busyTasks?.map(
|
|
10
|
+
${props.data?.busyTasks?.map(
|
|
11
|
+
(item: PluginBusyTask) => html`
|
|
12
|
+
<div class="plugin-busy-item">
|
|
13
|
+
<dss-typography tag="div" variant="body-3" fontweight="regular">
|
|
14
|
+
${item.taskDescription}
|
|
15
|
+
</dss-typography>
|
|
16
|
+
</div>`,
|
|
17
|
+
)}
|
|
11
18
|
</div>
|
|
12
19
|
</div>
|
|
13
20
|
`;
|
|
@@ -15,10 +15,21 @@ describe("PluginBusyManagerImpl", () => {
|
|
|
15
15
|
|
|
16
16
|
describe("addBusyPluginTask", () => {
|
|
17
17
|
it("should add a plugin busy task", () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const task = { taskId: "1", taskDescription: "Loading plugin" };
|
|
19
|
+
manager.addBusyPluginTask(task);
|
|
20
|
+
expect(manager.getBusyPluginTasks()).toContain(task);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should not add a task if taskId already exists", () => {
|
|
24
|
+
const task1 = { taskId: "1", taskDescription: "First task" };
|
|
25
|
+
const task2 = { taskId: "1", taskDescription: "Duplicate task" }; // mismo taskId
|
|
26
|
+
manager.addBusyPluginTask(task1);
|
|
27
|
+
manager.addBusyPluginTask(task2);
|
|
28
|
+
const tasks = manager.getBusyPluginTasks();
|
|
29
|
+
|
|
30
|
+
expect(tasks.length).toBe(1);
|
|
31
|
+
expect(tasks[0]).toEqual(task1); // Asegura que no fue reemplazado ni duplicado
|
|
32
|
+
});
|
|
22
33
|
});
|
|
23
34
|
|
|
24
35
|
describe("removeBusyPluginTask", () => {
|
|
@@ -32,7 +32,10 @@ export class PluginBusyManagerImpl implements PluginBusyManager {
|
|
|
32
32
|
private busyQuickActionTasks: QuickActionBusyTask[] = [];
|
|
33
33
|
|
|
34
34
|
public addBusyPluginTask(busyTask: PluginBusyTask): void {
|
|
35
|
-
this.busyPluginTasks.
|
|
35
|
+
const exists = this.busyPluginTasks.some((task) => task.taskId === busyTask.taskId);
|
|
36
|
+
if (!exists) {
|
|
37
|
+
this.busyPluginTasks.push(busyTask);
|
|
38
|
+
}
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
public addBusyQuickActionTask(busyTask: QuickActionBusyTask): void {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { translate } from "../../localization";
|
|
2
2
|
|
|
3
3
|
export const formatShowFilterTitle = (title: string) => {
|
|
4
|
-
const filterTitle = title.replace(/veure/gi, "")
|
|
4
|
+
const filterTitle = title.replace(/veure/gi, "")?.trim();
|
|
5
5
|
return filterTitle.charAt(0).toUpperCase() + filterTitle.slice(1);
|
|
6
6
|
};
|
|
7
7
|
|
package/src/internal-plugins/activity-history/activity-history-item/list/UI/main-view/template.ts
CHANGED
|
@@ -54,9 +54,9 @@ export const headerMaximizedTemplate = (props: ActivityHistoryMain) => html`
|
|
|
54
54
|
<div class="header__maximized__right">
|
|
55
55
|
<div>
|
|
56
56
|
<dss-button variant="subtle" size="md" label="${translate("actions.moreOptions")}" icon="more_horiz" iconposition="left"></dss-button>
|
|
57
|
-
<dss-action-menu position="bottom-start">
|
|
57
|
+
<!-- <dss-action-menu position="bottom-start">
|
|
58
58
|
<dss-action-menu-item @click=${() => props.api.broker.send(new ExportPdf())} lefticon="file_download" label=${translate("actions.exportPdf")}></dss-action-menu-item>
|
|
59
|
-
</dss-action-menu>
|
|
59
|
+
</dss-action-menu> -->
|
|
60
60
|
</div>
|
|
61
61
|
<dss-button label="${translate("actions.entryLegend")}" size="md" variant="secondary" icon="info"></dss-button>
|
|
62
62
|
<dss-button label="${translate("actions.cronogram")}" size="md" variant="primary" icon="view_timeline" @click=${props._raiseEcapCronogramEvent}></dss-button>
|
package/src/internal-plugins/activity-history/activity-history-item/list/UI/timeline/template.ts
CHANGED
|
@@ -33,7 +33,7 @@ export const template = (props: ActivityHistoryTimeline) => {
|
|
|
33
33
|
.renderItem=${(itemGroup: IActivityHistoryGroup, index: number) => html`
|
|
34
34
|
<div class="visit zIndex${props.historyGroups.length - index}"
|
|
35
35
|
data-date=${ifDefined(itemGroup?.items[0]?.date || itemGroup?.subGroups[0]?.items[0]?.date)}>
|
|
36
|
-
${visitHeaderTemplate(props, itemGroup
|
|
36
|
+
${visitHeaderTemplate(props, itemGroup?.items[0] || itemGroup?.subGroups[0]?.items[0])}
|
|
37
37
|
<div class="visit__items">
|
|
38
38
|
${repeat(
|
|
39
39
|
mergeHistoryItemsAndSubgroups(itemGroup),
|
|
@@ -44,7 +44,7 @@ export const template = (props: ActivityHistoryTimeline) => {
|
|
|
44
44
|
return html`
|
|
45
45
|
<div
|
|
46
46
|
class="item"
|
|
47
|
-
?has-divider=${hasItemDivider(item, itemGroup
|
|
47
|
+
?has-divider=${hasItemDivider(item, itemGroup?.items as IActivityHistoryItemWithComponent[])}
|
|
48
48
|
>
|
|
49
49
|
${item.component}
|
|
50
50
|
</div>
|
|
@@ -53,14 +53,14 @@ export const template = (props: ActivityHistoryTimeline) => {
|
|
|
53
53
|
const subGroup = entry.subGroup;
|
|
54
54
|
return html`
|
|
55
55
|
<div class="diagnostics">
|
|
56
|
-
${diagnosticHeaderTemplate(subGroup
|
|
56
|
+
${diagnosticHeaderTemplate(subGroup?.items[0])}
|
|
57
57
|
<div class="diagnostics__items">
|
|
58
58
|
${repeat(
|
|
59
|
-
subGroup
|
|
59
|
+
subGroup?.items,
|
|
60
60
|
(item) => item.id,
|
|
61
61
|
(item: IActivityHistoryItemWithComponent) => html`
|
|
62
62
|
<div class="item"
|
|
63
|
-
?has-divider=${hasItemDivider(item, subGroup
|
|
63
|
+
?has-divider=${hasItemDivider(item, subGroup?.items as IActivityHistoryItemWithComponent[])}>
|
|
64
64
|
${item.component}
|
|
65
65
|
</div>
|
|
66
66
|
`,
|
|
@@ -2,25 +2,37 @@ import { IActivityHistoryItem, IActivityHistoryGroup, IActivityHistorySubGroup }
|
|
|
2
2
|
import { areSameDiagnostics } from "../../domain/validation/diagnostics/are-same-diagnostics";
|
|
3
3
|
import { hasValidDiagnostics } from "../../domain/validation/diagnostics/has-valid-diagnostics";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
// Cache para evitar recalcular fechas
|
|
6
|
+
const dateStringCache = new Map<string, string>();
|
|
7
|
+
const dateObjectCache = new Map<string, Date>();
|
|
8
|
+
|
|
9
|
+
const getDateString = (dateStr: string): string => {
|
|
10
|
+
if (!dateStringCache.has(dateStr)) {
|
|
11
|
+
dateStringCache.set(dateStr, new Date(dateStr).toDateString());
|
|
12
|
+
}
|
|
13
|
+
return dateStringCache.get(dateStr)!;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const getDateObject = (dateStr: string): Date => {
|
|
17
|
+
if (!dateObjectCache.has(dateStr)) {
|
|
18
|
+
dateObjectCache.set(dateStr, new Date(dateStr));
|
|
19
|
+
}
|
|
20
|
+
return dateObjectCache.get(dateStr)!;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Crear una clave única para cada combinación de visita
|
|
24
|
+
const createVisitKey = (item: IActivityHistoryItem): string => {
|
|
25
|
+
const professionalKey = `${item.professional?.id || 'null'}-${item.professional?.role?.id || 'null'}-${item.professional?.speciality?.id || 'null'}`;
|
|
26
|
+
const locationKey = `${item.ep?.id || 'null'}-${item.up?.id || 'null'}-${item.center?.id || 'null'}-${item.service?.id || 'null'}`;
|
|
27
|
+
const dayKey = getDateString(item.date);
|
|
28
|
+
|
|
29
|
+
return `${professionalKey}|${locationKey}|${dayKey}`;
|
|
19
30
|
};
|
|
20
31
|
|
|
21
32
|
const withinEightHours = (date1: string, date2: string): boolean => {
|
|
22
|
-
const
|
|
23
|
-
|
|
33
|
+
const time1 = getDateObject(date1).getTime();
|
|
34
|
+
const time2 = getDateObject(date2).getTime();
|
|
35
|
+
return Math.abs(time1 - time2) <= 8 * 60 * 60 * 1000; // 8 hours in milliseconds
|
|
24
36
|
};
|
|
25
37
|
|
|
26
38
|
function groupByValidDiagnostics(groups: IActivityHistoryGroup[]) {
|
|
@@ -30,12 +42,12 @@ function groupByValidDiagnostics(groups: IActivityHistoryGroup[]) {
|
|
|
30
42
|
|
|
31
43
|
group.items.forEach((item) => {
|
|
32
44
|
const diagnostics = item.diagnostics;
|
|
33
|
-
|
|
34
45
|
const allDiagnosticsValid = diagnostics?.length > 0 && hasValidDiagnostics(diagnostics);
|
|
35
46
|
|
|
36
47
|
if (allDiagnosticsValid) {
|
|
37
48
|
let addedToSubGroup = false;
|
|
38
49
|
|
|
50
|
+
// Optimización: usar for...of con break para salir temprano
|
|
39
51
|
for (const subGroup of subGroups) {
|
|
40
52
|
const firstSubGroupItem = subGroup.items[0];
|
|
41
53
|
|
|
@@ -63,38 +75,59 @@ function groupByValidDiagnostics(groups: IActivityHistoryGroup[]) {
|
|
|
63
75
|
}
|
|
64
76
|
|
|
65
77
|
const groupActivityHistoryItems = (items: IActivityHistoryItem[]): IActivityHistoryGroup[] => {
|
|
66
|
-
|
|
78
|
+
if (!items?.length) return [];
|
|
67
79
|
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
// Limpiar caches al inicio
|
|
81
|
+
dateStringCache.clear();
|
|
82
|
+
dateObjectCache.clear();
|
|
70
83
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
84
|
+
// Mapa para agrupar por clave de visita
|
|
85
|
+
const visitGroups = new Map<string, IActivityHistoryGroup>();
|
|
86
|
+
|
|
87
|
+
items.forEach((item) => {
|
|
88
|
+
const visitKey = createVisitKey(item);
|
|
89
|
+
|
|
90
|
+
if (!visitGroups.has(visitKey)) {
|
|
91
|
+
// Crear nuevo grupo
|
|
92
|
+
visitGroups.set(visitKey, {
|
|
93
|
+
idGroup: Math.random().toString(36).substr(2, 9),
|
|
94
|
+
items: [item],
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
// Verificar si está dentro del rango de 8 horas
|
|
98
|
+
const existingGroup = visitGroups.get(visitKey)!;
|
|
99
|
+
const firstItem = existingGroup.items[0];
|
|
100
|
+
const lastItem = existingGroup.items[existingGroup.items.length - 1];
|
|
74
101
|
|
|
75
102
|
if (
|
|
76
|
-
isSameVisit(firstItem, item) &&
|
|
77
103
|
withinEightHours(firstItem.date, item.date) &&
|
|
78
104
|
withinEightHours(lastItem.date, item.date)
|
|
79
105
|
) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
106
|
+
existingGroup.items.push(item);
|
|
107
|
+
} else {
|
|
108
|
+
// Si no está dentro del rango, crear un nuevo grupo con un sufijo
|
|
109
|
+
let counter = 1;
|
|
110
|
+
let newKey = `${visitKey}_${counter}`;
|
|
111
|
+
|
|
112
|
+
while (visitGroups.has(newKey)) {
|
|
113
|
+
counter++;
|
|
114
|
+
newKey = `${visitKey}_${counter}`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
visitGroups.set(newKey, {
|
|
118
|
+
idGroup: Math.random().toString(36).substr(2, 9),
|
|
119
|
+
items: [item],
|
|
120
|
+
});
|
|
83
121
|
}
|
|
84
122
|
}
|
|
85
|
-
|
|
86
|
-
if (!added) {
|
|
87
|
-
groups.push({
|
|
88
|
-
idGroup: Math.random().toString(36).substr(2, 9),
|
|
89
|
-
items: [item],
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
123
|
});
|
|
93
124
|
|
|
94
|
-
|
|
125
|
+
const groups = Array.from(visitGroups.values());
|
|
126
|
+
|
|
127
|
+
// Crear subgrupos por diagnósticos iguales
|
|
95
128
|
groupByValidDiagnostics(groups);
|
|
96
129
|
|
|
97
130
|
return groups;
|
|
98
131
|
};
|
|
99
132
|
|
|
100
|
-
export { groupActivityHistoryItems };
|
|
133
|
+
export { groupActivityHistoryItems };
|
package/src/locales.ts
CHANGED