@uxland/primary-shell 5.6.4 → 5.6.6
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 +142 -83
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +43 -30
- package/dist/index.umd.cjs.map +1 -1
- package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/add/handle-busy/is-grouping-busy/component.d.ts +6 -0
- package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/add/handle-busy/is-grouping-busy/template.d.ts +3 -0
- package/dist/primary/shell/src/internal-plugins/activity-history/localization.d.ts +5 -0
- package/package.json +1 -1
- package/src/internal-plugins/activity-history/activity-history-item/add/add-history-item/handler.ts +2 -2
- package/src/internal-plugins/activity-history/activity-history-item/add/add-history-items/handler.ts +2 -2
- package/src/internal-plugins/activity-history/activity-history-item/add/handle-busy/is-grouping-busy/component.ts +15 -0
- package/src/internal-plugins/activity-history/activity-history-item/add/handle-busy/is-grouping-busy/styles.css +8 -0
- package/src/internal-plugins/activity-history/activity-history-item/add/handle-busy/is-grouping-busy/template.ts +10 -0
- package/src/internal-plugins/activity-history/activity-history-item/list/UI/timeline/activity-history-timeline.ts +12 -5
- package/src/internal-plugins/activity-history/activity-history-item/list/UI/timeline/template.ts +20 -13
- package/src/internal-plugins/activity-history/activity-history-item/list/group-history-items/group-history-items.ts +69 -36
- package/src/internal-plugins/activity-history/localization.ts +5 -0
|
@@ -18,6 +18,11 @@ export declare const locales: {
|
|
|
18
18
|
goToDate: string;
|
|
19
19
|
busyEntriesLoading: string;
|
|
20
20
|
noResults: string;
|
|
21
|
+
noData: {
|
|
22
|
+
title: string;
|
|
23
|
+
description: string;
|
|
24
|
+
};
|
|
25
|
+
isGrouping: string;
|
|
21
26
|
searchBarResults: string;
|
|
22
27
|
actions: {
|
|
23
28
|
cronogram: string;
|
package/package.json
CHANGED
package/src/internal-plugins/activity-history/activity-history-item/add/add-history-item/handler.ts
CHANGED
|
@@ -9,14 +9,14 @@ export class AddHistoryItemHandler extends StoreBaseHandler {
|
|
|
9
9
|
async handle(payload: AddHistoryItemPayload) {
|
|
10
10
|
try {
|
|
11
11
|
ensureAreValidBasicActivityHistoryItems([payload.item]);
|
|
12
|
+
handleAddDiagnosticsFilter([payload.item], this.store);
|
|
13
|
+
handleAddUpFilter([payload.item], this.store);
|
|
12
14
|
this.store.dispatch(
|
|
13
15
|
addActivityHistoryItem({
|
|
14
16
|
id: payload.entityId,
|
|
15
17
|
item: payload.item,
|
|
16
18
|
}),
|
|
17
19
|
);
|
|
18
|
-
handleAddDiagnosticsFilter([payload.item], this.store);
|
|
19
|
-
handleAddUpFilter([payload.item], this.store);
|
|
20
20
|
} catch (e) {
|
|
21
21
|
console.log(e.message);
|
|
22
22
|
}
|
package/src/internal-plugins/activity-history/activity-history-item/add/add-history-items/handler.ts
CHANGED
|
@@ -9,6 +9,8 @@ export class AddHistoryItemsHandler extends StoreBaseHandler {
|
|
|
9
9
|
async handle(payload: AddHistoryItemsPayload) {
|
|
10
10
|
try {
|
|
11
11
|
const validItems = validateAndFilterBasicItems(payload.items);
|
|
12
|
+
handleAddDiagnosticsFilter(validItems, this.store);
|
|
13
|
+
handleAddUpFilter(validItems, this.store);
|
|
12
14
|
this.store.dispatch(
|
|
13
15
|
addActivityHistoryItems({
|
|
14
16
|
id: payload.entityId,
|
|
@@ -17,8 +19,6 @@ export class AddHistoryItemsHandler extends StoreBaseHandler {
|
|
|
17
19
|
searchPredicate: payload.searchPredicate,
|
|
18
20
|
}),
|
|
19
21
|
);
|
|
20
|
-
handleAddDiagnosticsFilter(validItems, this.store);
|
|
21
|
-
handleAddUpFilter(validItems, this.store);
|
|
22
22
|
} catch (e) {
|
|
23
23
|
console.log(e.message);
|
|
24
24
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { LitElement, html, css, unsafeCSS } from "lit";
|
|
2
|
+
import { customElement } from "lit/decorators.js";
|
|
3
|
+
import styles from "./styles.css?inline";
|
|
4
|
+
import { template } from "./template";
|
|
5
|
+
|
|
6
|
+
@customElement("activity-history-is-grouping-busy")
|
|
7
|
+
export class ActivityHistoryIsGroupingBusy extends LitElement {
|
|
8
|
+
static styles = css`
|
|
9
|
+
${unsafeCSS(styles)}
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
render() {
|
|
13
|
+
return template(this);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import { ActivityHistoryIsGroupingBusy } from "./component";
|
|
3
|
+
import { translate } from "../../../../localization";
|
|
4
|
+
|
|
5
|
+
export const template = (_props: ActivityHistoryIsGroupingBusy) => html`
|
|
6
|
+
<div class="grouping-busy-container">
|
|
7
|
+
<dss-spinner size="sm"></dss-spinner>
|
|
8
|
+
<div>${translate("isGrouping")}</div>
|
|
9
|
+
</div>
|
|
10
|
+
`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, PropertyValues, css, html, unsafeCSS } from "lit";
|
|
2
|
-
import { customElement, query } from "lit/decorators.js";
|
|
2
|
+
import { customElement, query, state } from "lit/decorators.js";
|
|
3
3
|
import { connectedProperty } from "../../../../infrastructure/state/connected-property";
|
|
4
4
|
import { IActivityHistoryGroup } from "../../../domain/model";
|
|
5
5
|
import { activityHistorySearchStringSelector } from "../../../search/selectors";
|
|
@@ -52,11 +52,18 @@ export class ActivityHistoryTimeline extends LitElement {
|
|
|
52
52
|
|
|
53
53
|
@query(".virtualizer") private _virtualizer!: HTMLElement;
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
@state()
|
|
56
|
+
renderGroupsControlTimeExpired = false;
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
super.
|
|
59
|
-
|
|
58
|
+
connectedCallback(): void {
|
|
59
|
+
super.connectedCallback();
|
|
60
|
+
setTimeout(() => {
|
|
61
|
+
this.renderGroupsControlTimeExpired = true;
|
|
62
|
+
}, 8000);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
disconnectedCallback(): void {
|
|
66
|
+
super.disconnectedCallback();
|
|
60
67
|
}
|
|
61
68
|
|
|
62
69
|
async updated(changedProperties) {
|
package/src/internal-plugins/activity-history/activity-history-item/list/UI/timeline/template.ts
CHANGED
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
IActivityHistoryGroup,
|
|
10
10
|
IActivityHistoryItem,
|
|
11
11
|
IActivityHistoryItemWithComponent,
|
|
12
|
-
IActivityHistorySubGroup,
|
|
13
12
|
} from "../../../domain/model";
|
|
14
13
|
import { translate } from "../../../../localization";
|
|
15
14
|
import { hasItemDivider, shouldShowRole } from "../../../domain/business-rules";
|
|
@@ -17,11 +16,9 @@ import {
|
|
|
17
16
|
ActivityHistoryEntry,
|
|
18
17
|
mergeHistoryItemsAndSubgroups,
|
|
19
18
|
} from "../../merge-history-items-and-subgroups/merge-history-items-and-subgroups";
|
|
19
|
+
import "../../../add/handle-busy/is-grouping-busy/component";
|
|
20
20
|
|
|
21
21
|
export const template = (props: ActivityHistoryTimeline) => {
|
|
22
|
-
if (!props._hasUpdatedOnce) {
|
|
23
|
-
return html`<div class="container"></div>`;
|
|
24
|
-
}
|
|
25
22
|
return html`
|
|
26
23
|
<div class="container">
|
|
27
24
|
<activity-history-full-data-error></activity-history-full-data-error>
|
|
@@ -78,20 +75,30 @@ export const template = (props: ActivityHistoryTimeline) => {
|
|
|
78
75
|
`}
|
|
79
76
|
></lit-virtualizer>
|
|
80
77
|
`
|
|
81
|
-
:
|
|
82
|
-
? html`
|
|
83
|
-
<dss-user-feedback
|
|
84
|
-
class="feedback"
|
|
85
|
-
imagesrc=${notFound}
|
|
86
|
-
title=${translate("noResults")}>
|
|
87
|
-
</dss-user-feedback>
|
|
88
|
-
`
|
|
89
|
-
: nothing
|
|
78
|
+
: noGroupsTemplate(props)
|
|
90
79
|
}
|
|
91
80
|
</div>
|
|
92
81
|
`;
|
|
93
82
|
};
|
|
94
83
|
|
|
84
|
+
const noGroupsTemplate = (props: ActivityHistoryTimeline)=> html `
|
|
85
|
+
${props.searchString?.length > 1
|
|
86
|
+
? html`
|
|
87
|
+
<dss-user-feedback
|
|
88
|
+
class="feedback"
|
|
89
|
+
imagesrc=${notFound}
|
|
90
|
+
title=${translate("noResults")}>
|
|
91
|
+
</dss-user-feedback>
|
|
92
|
+
`
|
|
93
|
+
: props.renderGroupsControlTimeExpired
|
|
94
|
+
? html`<dss-user-feedback
|
|
95
|
+
class="feedback"
|
|
96
|
+
imagesrc=${notFound}
|
|
97
|
+
title=${translate("noData.title")}
|
|
98
|
+
description=${translate("noData.description")}>
|
|
99
|
+
</dss-user-feedback>`
|
|
100
|
+
: html`<activity-history-is-grouping-busy></activity-history-is-grouping-busy>`}`;
|
|
101
|
+
|
|
95
102
|
const visitHeaderTemplate = (props: ActivityHistoryTimeline, item: IActivityHistoryItem | undefined) => {
|
|
96
103
|
if (!item) return nothing;
|
|
97
104
|
return html`
|
|
@@ -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 };
|
|
@@ -32,6 +32,11 @@ export const locales = {
|
|
|
32
32
|
goToDate: "Anar a data",
|
|
33
33
|
busyEntriesLoading: "Carregant totes les entrades",
|
|
34
34
|
noResults: "Sense resultats. Modifica la cerca",
|
|
35
|
+
noData: {
|
|
36
|
+
title: "Sense dades",
|
|
37
|
+
description: "No existeix informació per a mostrar"
|
|
38
|
+
},
|
|
39
|
+
isGrouping: "Creant agrupacions i preparant les dades...",
|
|
35
40
|
searchBarResults: "Resultats per",
|
|
36
41
|
actions: {
|
|
37
42
|
cronogram: "Cronograma",
|