@uxland/primary-shell 5.1.2 → 5.2.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.
Files changed (109) hide show
  1. package/dist/index.js +27047 -26702
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.umd.cjs +1637 -1519
  4. package/dist/index.umd.cjs.map +1 -1
  5. package/dist/primary/shell/src/UI/bootstrapper.d.ts +1 -0
  6. package/dist/primary/shell/src/UI/components/bootstrapper.d.ts +1 -0
  7. package/dist/primary/shell/src/UI/components/{shell-header → primaria-shell/shell-header}/shell-header.d.ts +3 -3
  8. package/dist/primary/shell/src/UI/components/primaria-shell/shell-header/template.d.ts +3 -0
  9. package/dist/primary/shell/src/UI/index.d.ts +0 -1
  10. package/dist/primary/shell/src/UI/shared-components/bootstrapper.d.ts +1 -0
  11. package/dist/primary/shell/src/UI/shared-components/index.d.ts +0 -1
  12. package/dist/primary/shell/src/api/api.d.ts +4 -4
  13. package/dist/primary/shell/src/api/ecap-event-manager/ecap-event-manager.test.d.ts +1 -0
  14. package/dist/primary/shell/src/api/notification-service/notification-service-impl.test.d.ts +1 -0
  15. package/dist/primary/shell/src/api/pdf-viewer-manager/constants.d.ts +1 -0
  16. package/dist/primary/shell/src/api/pdf-viewer-manager/handle-views.d.ts +2 -0
  17. package/dist/primary/shell/src/api/pdf-viewer-manager/pdf-viewer-manager.d.ts +2 -4
  18. package/dist/primary/shell/src/api/pdf-viewer-manager/pdf-viewer-manager.test.d.ts +1 -0
  19. package/dist/primary/shell/src/api/region-manager/region-manager.test.d.ts +1 -0
  20. package/dist/primary/shell/src/bootstrapper.d.ts +0 -1
  21. package/dist/primary/shell/src/constants.d.ts +0 -2
  22. package/dist/primary/shell/src/features/bootstrapper.d.ts +2 -2
  23. package/dist/primary/shell/src/features/clinical-monitoring/bootstrapper.d.ts +4 -0
  24. package/dist/primary/shell/src/features/clinical-monitoring/constants.d.ts +1 -0
  25. package/dist/primary/shell/src/features/clinical-monitoring/handle-views.d.ts +1 -0
  26. package/dist/primary/shell/src/features/exit/bootstrapper.d.ts +4 -2
  27. package/dist/primary/shell/src/features/exit/handler.test.d.ts +1 -0
  28. package/dist/primary/shell/src/features/get-patient-cip/action.d.ts +3 -0
  29. package/dist/primary/shell/src/features/get-user-info/bootstrapper.d.ts +4 -2
  30. package/dist/primary/shell/src/features/get-user-info/handler.d.ts +1 -1
  31. package/dist/primary/shell/src/features/get-user-info/handler.test.d.ts +1 -0
  32. package/dist/primary/shell/src/features/navigate-to-ecap/navigate-without-closing-and-with-cip.d.ts +1 -0
  33. package/dist/primary/shell/src/handle-views.d.ts +1 -2
  34. package/dist/primary/shell/src/internal-plugins/activity-history/utils/get-unique-values-by-prop-path.test.d.ts +1 -0
  35. package/dist/primary/shell/src/internal-plugins/activity-history/utils/normalize-string.d.ts +1 -1
  36. package/dist/primary/shell/src/internal-plugins/activity-history/utils/normalize-string.test.d.ts +1 -0
  37. package/dist/primary/shell/src/internal-plugins/activity-history/utils/prop-contains-string.test.d.ts +1 -0
  38. package/dist/primary/shell/src/locales.d.ts +1 -1
  39. package/package.json +2 -2
  40. package/src/UI/bootstrapper.ts +12 -0
  41. package/src/UI/components/bootstrapper.ts +17 -0
  42. package/src/UI/components/{primaria-error-view → error-view}/component.ts +2 -3
  43. package/src/UI/components/poc-events-ecap/poc-events-ecap.ts +3 -7
  44. package/src/UI/components/primaria-shell/primaria-shell.ts +8 -10
  45. package/src/UI/components/{shell-header → primaria-shell/shell-header}/shell-header.ts +8 -9
  46. package/src/UI/components/{shell-header → primaria-shell/shell-header}/template.ts +4 -4
  47. package/src/UI/components/primaria-shell/template.ts +14 -8
  48. package/src/UI/components/quick-actions-menu/quick-actions-menu.ts +0 -2
  49. package/src/UI/index.ts +0 -1
  50. package/src/UI/shared-components/bootstrapper.ts +12 -0
  51. package/src/UI/shared-components/index.ts +0 -3
  52. package/src/UI/shared-components/primaria-content-switcher/primaria-content-switcher.ts +1 -2
  53. package/src/UI/shared-components/primaria-nav-item/primaria-nav-item.ts +6 -7
  54. package/src/UI/shared-components/primaria-nav-tree-menu/primaria-nav-tree-menu.ts +3 -4
  55. package/src/UI/shared-components/primaria-text-editor/primaria-rich-text-editor.ts +1 -2
  56. package/src/api/api.ts +17 -14
  57. package/src/api/ecap-event-manager/ecap-event-manager.test.ts +48 -0
  58. package/src/api/notification-service/notification-service-impl.test.ts +56 -0
  59. package/src/api/pdf-viewer-manager/constants.ts +1 -0
  60. package/src/api/pdf-viewer-manager/handle-views.ts +32 -0
  61. package/src/api/pdf-viewer-manager/pdf-viewer-manager.test.ts +99 -0
  62. package/src/api/pdf-viewer-manager/pdf-viewer-manager.ts +15 -25
  63. package/src/{UI/components → api/pdf-viewer-manager}/pdf-visor/pdf-selector/pdf-selector.ts +3 -4
  64. package/src/{UI/components → api/pdf-viewer-manager}/pdf-visor/pdf-visor.ts +8 -9
  65. package/src/api/plugin-busy-manager/plugin-busy-list/component.ts +0 -2
  66. package/src/api/plugin-busy-manager/plugin-busy-manager.ts +7 -1
  67. package/src/api/region-manager/region-manager.test.ts +123 -0
  68. package/src/bootstrapper.ts +8 -9
  69. package/src/constants.ts +0 -2
  70. package/src/disposer.ts +2 -2
  71. package/src/features/bootstrapper.ts +14 -8
  72. package/src/features/clinical-monitoring/bootstrapper.ts +39 -0
  73. package/src/{UI/components/clinical-monitoring → features/clinical-monitoring/component}/clinical-monitoring.ts +3 -6
  74. package/src/features/clinical-monitoring/constants.ts +1 -0
  75. package/src/features/clinical-monitoring/handle-views.ts +6 -0
  76. package/src/features/exit/bootstrapper.ts +5 -5
  77. package/src/features/exit/handler.test.ts +103 -0
  78. package/src/features/get-patient-cip/action.ts +5 -0
  79. package/src/features/get-user-info/bootstrapper.ts +5 -5
  80. package/src/features/get-user-info/handler.test.ts +60 -0
  81. package/src/features/get-user-info/handler.ts +2 -4
  82. package/src/features/navigate-to-ecap/navigate-without-closing-and-with-cip.ts +7 -0
  83. package/src/handle-views.ts +91 -133
  84. package/src/internal-plugins/activity-history/utils/get-unique-values-by-prop-path.test.ts +61 -0
  85. package/src/internal-plugins/activity-history/utils/get-unique-values-by-prop-path.ts +2 -2
  86. package/src/internal-plugins/activity-history/utils/normalize-string.test.ts +29 -0
  87. package/src/internal-plugins/activity-history/utils/normalize-string.ts +5 -3
  88. package/src/internal-plugins/activity-history/utils/prop-contains-string.test.ts +47 -0
  89. package/src/locales.ts +1 -1
  90. package/dist/primary/shell/src/UI/components/index.d.ts +0 -1
  91. package/dist/primary/shell/src/UI/components/shell-header/template.d.ts +0 -3
  92. package/src/UI/components/index.ts +0 -7
  93. /package/dist/primary/shell/src/UI/components/{primaria-error-view → error-view}/component.d.ts +0 -0
  94. /package/dist/primary/shell/src/UI/components/{primaria-error-view → error-view}/template.d.ts +0 -0
  95. /package/dist/primary/shell/src/{UI/components → api/pdf-viewer-manager}/pdf-visor/pdf-selector/pdf-selector.d.ts +0 -0
  96. /package/dist/primary/shell/src/{UI/components → api/pdf-viewer-manager}/pdf-visor/pdf-selector/template.d.ts +0 -0
  97. /package/dist/primary/shell/src/{UI/components → api/pdf-viewer-manager}/pdf-visor/pdf-visor.d.ts +0 -0
  98. /package/dist/primary/shell/src/{UI/components → api/pdf-viewer-manager}/pdf-visor/utils.d.ts +0 -0
  99. /package/dist/primary/shell/src/{UI/components/clinical-monitoring → features/clinical-monitoring/component}/clinical-monitoring.d.ts +0 -0
  100. /package/dist/primary/shell/src/{UI/components/clinical-monitoring → features/clinical-monitoring/component}/template.d.ts +0 -0
  101. /package/src/UI/components/{primaria-error-view → error-view}/styles.css +0 -0
  102. /package/src/UI/components/{primaria-error-view → error-view}/template.ts +0 -0
  103. /package/src/UI/components/{shell-header → primaria-shell/shell-header}/styles.css +0 -0
  104. /package/src/{UI/components → api/pdf-viewer-manager}/pdf-visor/pdf-selector/styles.css +0 -0
  105. /package/src/{UI/components → api/pdf-viewer-manager}/pdf-visor/pdf-selector/template.ts +0 -0
  106. /package/src/{UI/components → api/pdf-viewer-manager}/pdf-visor/styles.css +0 -0
  107. /package/src/{UI/components → api/pdf-viewer-manager}/pdf-visor/utils.ts +0 -0
  108. /package/src/{UI/components/clinical-monitoring → features/clinical-monitoring/component}/styles.css +0 -0
  109. /package/src/{UI/components/clinical-monitoring → features/clinical-monitoring/component}/template.ts +0 -0
@@ -0,0 +1,48 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { createEcapEventManager } from "./ecap-event-manager";
3
+
4
+ describe("EcapEventManagerImpl", () => {
5
+ const mockPostMessage = vi.fn();
6
+ const mockConsoleLog = vi.fn();
7
+
8
+ beforeEach(() => {
9
+ vi.clearAllMocks();
10
+ vi.stubGlobal("console", {
11
+ ...console,
12
+ log: mockConsoleLog,
13
+ });
14
+ (window.parent as any) = {
15
+ postMessage: mockPostMessage,
16
+ };
17
+ });
18
+
19
+ it("should publish and post the event correctly", () => {
20
+ const eventManager = createEcapEventManager();
21
+ const payload = { url: "https://example.com", user: "john" };
22
+
23
+ eventManager.publish("click", "navigate", payload);
24
+
25
+ const expectedEvent = {
26
+ TipusEvent: "click",
27
+ Accio: "navigate",
28
+ ...payload,
29
+ };
30
+
31
+ expect(mockPostMessage).toHaveBeenCalledWith(JSON.stringify(expectedEvent), "*");
32
+ expect(mockConsoleLog).toHaveBeenCalledWith("method", JSON.stringify(expectedEvent));
33
+ });
34
+
35
+ it("should not fail if window.parent is undefined", () => {
36
+ (window as any).parent = undefined;
37
+
38
+ const eventManager = createEcapEventManager();
39
+ const payload = { id: "123" };
40
+
41
+ // No error should be thrown
42
+ expect(() => {
43
+ eventManager.publish("custom", "action", payload);
44
+ }).not.toThrow();
45
+
46
+ expect(mockConsoleLog).toHaveBeenCalled();
47
+ });
48
+ });
@@ -0,0 +1,56 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { PrimariaNotificationServiceImpl } from "./notification.service-impl";
3
+
4
+ describe("PrimariaNotificationServiceImpl", () => {
5
+ let service: PrimariaNotificationServiceImpl;
6
+
7
+ beforeEach(() => {
8
+ service = new PrimariaNotificationServiceImpl();
9
+ document.body.innerHTML = ""; // limpia el DOM antes de cada test
10
+ vi.useFakeTimers(); // usamos timers falsos para testear setTimeout
11
+ });
12
+
13
+ afterEach(() => {
14
+ vi.clearAllTimers();
15
+ vi.useRealTimers();
16
+ });
17
+
18
+ const assertToast = (expectedState: string, message: string, duration: number = 3000) => {
19
+ const toast = document.querySelector("dss-toast") as HTMLElement;
20
+ expect(toast).not.toBeNull();
21
+ expect(toast.getAttribute("isshow")).toBe("true");
22
+ expect(toast.getAttribute("state")).toBe(expectedState);
23
+ expect(toast.getAttribute("position")).toBe("bottom-left");
24
+ expect(toast.getAttribute("text")).toBe(message);
25
+ expect(toast.getAttribute("hasicon")).toBe("true");
26
+ expect(toast.getAttribute("duration")).toBe(duration.toString());
27
+ };
28
+
29
+ it.each([
30
+ ["info", "info"],
31
+ ["warning", "warning"],
32
+ ["error", "error"],
33
+ ["success", "success"],
34
+ ] as const)("should create a '%s' toast", (method, state) => {
35
+ const message = `Test ${state}`;
36
+ (service[method] as any)(message);
37
+ assertToast(state, message);
38
+ });
39
+
40
+ it("should remove the toast after the duration", () => {
41
+ service.info("Temporary toast", 2000);
42
+
43
+ let toast = document.querySelector("dss-toast") as HTMLElement;
44
+ expect(toast).not.toBeNull();
45
+ expect(toast.getAttribute("isshow")).toBe("true");
46
+
47
+ // Avanza el primer timeout (esconde el toast)
48
+ vi.advanceTimersByTime(2000);
49
+ expect(toast.getAttribute("isshow")).toBe("false");
50
+
51
+ // Avanza el segundo timeout (remueve del DOM)
52
+ vi.advanceTimersByTime(300);
53
+ toast = document.querySelector("dss-toast") as HTMLElement;
54
+ expect(toast).toBeNull();
55
+ });
56
+ });
@@ -0,0 +1 @@
1
+ export const pdfViewerId = "pdf-viewer";
@@ -0,0 +1,32 @@
1
+ import { pdfViewerId } from "./constants";
2
+ import { translate } from "../../locales";
3
+ import { PrimariaNavItem } from "../../UI/shared-components/primaria-nav-item/primaria-nav-item";
4
+ import { shellApi } from "../api";
5
+ import { shellRegions } from "../region-manager/regions";
6
+ import { PdfVisor } from "./pdf-visor/pdf-visor";
7
+
8
+ export const registerPdfViewerNavItem = () => {
9
+ shellApi.regionManager.registerView(shellRegions.navigationMenu, {
10
+ id: pdfViewerId,
11
+ factory: () => {
12
+ const menuItem = new PrimariaNavItem({
13
+ icon: "picture_as_pdf",
14
+ label: translate("pdfManager.navButtonLabel"),
15
+ callbackFn: () => {
16
+ shellApi.regionManager.activateMainView(pdfViewerId);
17
+ },
18
+ });
19
+ return Promise.resolve(menuItem);
20
+ },
21
+ });
22
+ };
23
+
24
+ export const registerPDFVisorMainView = () => {
25
+ shellApi.regionManager.registerMainView({
26
+ id: pdfViewerId,
27
+ factory: () => {
28
+ const mainItem = new PdfVisor();
29
+ return Promise.resolve(mainItem as unknown as HTMLElement);
30
+ },
31
+ });
32
+ };
@@ -0,0 +1,99 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { createPdfViewerManager } from "./pdf-viewer-manager";
3
+ import { pdfViwerEvents } from "./events";
4
+ import { registerPdfViewerNavItem } from "./handle-views";
5
+
6
+ vi.mock("@primaria/plugins-core", () => ({
7
+ generateId: () => "generated-id",
8
+ }));
9
+
10
+ vi.mock("./handle-views", () => ({
11
+ registerPdfViewerNavItem: vi.fn(),
12
+ }));
13
+
14
+ vi.mock("../../locales", () => ({
15
+ translate: (key: string) => key,
16
+ }));
17
+
18
+ describe("PdfViewerManager", () => {
19
+ let manager: ReturnType<typeof createPdfViewerManager>;
20
+ let broker: any;
21
+ let notificationService: any;
22
+
23
+ beforeEach(() => {
24
+ broker = {
25
+ publish: vi.fn(),
26
+ };
27
+
28
+ notificationService = {
29
+ error: vi.fn(),
30
+ warning: vi.fn(),
31
+ success: vi.fn(),
32
+ };
33
+
34
+ manager = createPdfViewerManager(broker, notificationService);
35
+
36
+ vi.clearAllMocks();
37
+ });
38
+
39
+ it("should show error if neither url nor b64 is provided", () => {
40
+ manager.add("Doc1", {});
41
+ expect(notificationService.error).toHaveBeenCalledWith("pdfManager.missingData");
42
+ expect(manager.getPdfs()).toHaveLength(0);
43
+ });
44
+
45
+ it("should show error if both url and b64 are provided", () => {
46
+ manager.add("Doc1", { url: "url", b64: "b64" });
47
+ expect(notificationService.error).toHaveBeenCalledWith("pdfManager.duplicatedSource");
48
+ expect(manager.getPdfs()).toHaveLength(0);
49
+ });
50
+
51
+ it("should add a valid pdf and notify success", () => {
52
+ manager.add("Doc1", { url: "https://test.com/doc1.pdf" });
53
+
54
+ expect(manager.getPdfs()).toHaveLength(1);
55
+ expect(notificationService.success).toHaveBeenCalledWith("pdfManager.uploaded");
56
+ expect(broker.publish).toHaveBeenCalledWith(pdfViwerEvents.added, {
57
+ id: "generated-id",
58
+ pdfName: "Doc1",
59
+ data: { url: "https://test.com/doc1.pdf" },
60
+ });
61
+ });
62
+
63
+ it("should warn if pdf with same name already exists", () => {
64
+ manager.add("Doc1", { b64: "xxx" });
65
+ manager.add("Doc1", { b64: "xxx" });
66
+
67
+ expect(notificationService.warning).toHaveBeenCalledWith("pdfManager.alreadyUploaded");
68
+ expect(manager.getPdfs()).toHaveLength(1); // solo el primero
69
+ });
70
+
71
+ it("should call registerNavButton only once", () => {
72
+ manager.add("Doc1", { url: "u" });
73
+ manager.add("Doc2", { url: "u2" });
74
+
75
+ expect(registerPdfViewerNavItem).toHaveBeenCalledTimes(1);
76
+ });
77
+
78
+ it("should delete a pdf and publish deletion event", () => {
79
+ manager.add("Doc1", { url: "u" });
80
+ const id = manager.getPdfs()[0].id;
81
+
82
+ manager.delete(id);
83
+
84
+ expect(manager.getPdfs()).toHaveLength(0);
85
+ expect(broker.publish).toHaveBeenCalledWith(pdfViwerEvents.deleted, { id });
86
+ });
87
+
88
+ it("should clear activePdf if deleted", () => {
89
+ manager.add("Doc1", { url: "u" });
90
+ const id = manager.getPdfs()[0].id;
91
+
92
+ // simula que esté activo
93
+ (manager as any).activePdf = { id } as any;
94
+
95
+ manager.delete(id);
96
+
97
+ expect((manager as any).activePdf).toBeNull();
98
+ });
99
+ });
@@ -1,12 +1,12 @@
1
+ import { generateId } from "@primaria/plugins-core";
2
+ import { customElement } from "lit/decorators.js";
3
+ import { registerPdfViewerNavItem } from "./handle-views";
1
4
  import { translate } from "../../locales";
2
- import { PrimariaNavItem } from "../../UI/shared-components/primaria-nav-item/primaria-nav-item";
3
5
  import { PrimariaBroker } from "../broker/primaria-broker";
4
6
  import { PrimariaNotificationService } from "../notification-service/notification-service";
5
- import { shellRegions } from "../region-manager/regions";
6
7
  import { pdfViwerEvents } from "./events";
7
- import { pdfViewerId } from "../../constants";
8
- import { PrimariaRegionManager } from "../region-manager/region-manager";
9
- import { generateId } from "@primaria/plugins-core";
8
+ import { PdfSelector } from "./pdf-visor/pdf-selector/pdf-selector";
9
+ import { PdfVisor } from "./pdf-visor/pdf-visor";
10
10
 
11
11
  export interface IPdfDocument {
12
12
  pdfName: string;
@@ -23,8 +23,14 @@ export class PdfViewerManager {
23
23
  constructor(
24
24
  private broker: PrimariaBroker,
25
25
  private notificationService: PrimariaNotificationService,
26
- private regionManager: PrimariaRegionManager,
27
- ) {}
26
+ ) {
27
+ if (!customElements.get("pdf-visor")) {
28
+ customElement("pdf-visor")(PdfVisor);
29
+ }
30
+ if (!customElements.get("pdf-selector")) {
31
+ customElement("pdf-selector")(PdfSelector);
32
+ }
33
+ }
28
34
 
29
35
  private pdfs: IPdfDocument[] = [];
30
36
  private activePdf: IPdfDocument | null = null;
@@ -71,27 +77,11 @@ export class PdfViewerManager {
71
77
  }
72
78
 
73
79
  private registerNavButton() {
74
- this.regionManager.registerView(shellRegions.navigationMenu, {
75
- id: pdfViewerId,
76
- factory: () => {
77
- const menuItem = new PrimariaNavItem({
78
- icon: "picture_as_pdf",
79
- label: translate("pdfManager.navButtonLabel"),
80
- callbackFn: () => {
81
- this.regionManager.activateMainView(pdfViewerId);
82
- },
83
- });
84
- return Promise.resolve(menuItem);
85
- },
86
- });
80
+ registerPdfViewerNavItem();
87
81
  }
88
82
  }
89
83
 
90
- const pdfViewerManager = (broker, interactionManager, regionManager) =>
91
- new PdfViewerManager(broker, interactionManager, regionManager);
92
-
93
84
  export const createPdfViewerManager = (
94
85
  broker: PrimariaBroker,
95
86
  notificationService: PrimariaNotificationService,
96
- regionManager: PrimariaRegionManager,
97
- ) => pdfViewerManager(broker, notificationService, regionManager);
87
+ ) => new PdfViewerManager(broker, notificationService);
@@ -1,11 +1,10 @@
1
1
  import { LitElement, css, unsafeCSS } from "lit";
2
- import { customElement, property } from "lit/decorators.js";
2
+ import { property } from "lit/decorators.js";
3
3
  import { IPdfDocument } from "../../../../../src/api/pdf-viewer-manager/pdf-viewer-manager";
4
- import { template } from "./template";
5
- import styles from "./styles.css?inline";
6
4
  import { createUrlFromBase64 } from "../utils";
5
+ import styles from "./styles.css?inline";
6
+ import { template } from "./template";
7
7
 
8
- @customElement("pdf-selector")
9
8
  export class PdfSelector extends LitElement {
10
9
  render() {
11
10
  return template(this);
@@ -1,16 +1,15 @@
1
- import styles from "./styles.css?inline";
2
- import { html, LitElement, css, unsafeCSS } from "lit";
3
- import { customElement, property } from "lit/decorators.js";
4
- import { BrokerDisposableHandler } from "../../../api/broker/primaria-broker";
5
- import { PrimariaApi } from "../../../api/api";
6
- import { TYPES } from "../../../../src/infrastructure/ioc/types";
7
- import { lazyInject } from "../../../../src/infrastructure/ioc/container";
1
+ import { css, html, LitElement, unsafeCSS } from "lit";
2
+ import { property } from "lit/decorators.js";
8
3
  import { pdfViwerEvents } from "../../../../src/api/pdf-viewer-manager/events";
9
- import { IPdfDocument } from "../../../api/pdf-viewer-manager/pdf-viewer-manager";
4
+ import { lazyInject } from "../../../../src/infrastructure/ioc/container";
5
+ import { TYPES } from "../../../../src/infrastructure/ioc/types";
10
6
  import { translate } from "../../../../src/locales";
7
+ import { PrimariaApi } from "../../../api/api";
8
+ import { BrokerDisposableHandler } from "../../../api/broker/primaria-broker";
9
+ import { IPdfDocument } from "../../../api/pdf-viewer-manager/pdf-viewer-manager";
10
+ import styles from "./styles.css?inline";
11
11
  import { createUrlFromBase64 } from "./utils";
12
12
 
13
- @customElement("pdf-visor")
14
13
  export class PdfVisor extends LitElement {
15
14
  static styles = css`${unsafeCSS(styles)}`;
16
15
 
@@ -1,10 +1,8 @@
1
1
  import { LitElement, css, html, unsafeCSS } from "lit";
2
- import { customElement } from "lit/decorators.js";
3
2
  import { PluginBusyTask } from "../plugin-busy-manager";
4
3
  import styles from "./styles.css?inline";
5
4
  import { template } from "./template";
6
5
 
7
- @customElement("plugin-busy-list")
8
6
  export class PluginBusyList extends LitElement {
9
7
  static styles = css`
10
8
  ${unsafeCSS(styles)}
@@ -1,5 +1,7 @@
1
+ import { customElement } from "lit/decorators.js";
1
2
  import { shellEvents } from "../../events";
2
3
  import { PrimariaBroker } from "../broker/primaria-broker";
4
+ import { PluginBusyList } from "./plugin-busy-list/component";
3
5
 
4
6
  export interface PluginBusyTask {
5
7
  taskId: string;
@@ -21,7 +23,11 @@ export abstract class PluginBusyManager {
21
23
  abstract getBusyPluginTasks(): PluginBusyTask[];
22
24
  }
23
25
  export class PluginBusyManagerImpl implements PluginBusyManager {
24
- constructor(public broker: PrimariaBroker) {}
26
+ constructor(public broker: PrimariaBroker) {
27
+ if (!customElements.get("plugin-busy-list")) {
28
+ customElement("plugin-busy-list")(PluginBusyList);
29
+ }
30
+ }
25
31
  private busyPluginTasks: PluginBusyTask[] = [];
26
32
  private busyQuickActionTasks: QuickActionBusyTask[] = [];
27
33
 
@@ -0,0 +1,123 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { createRegionManagerProxy } from "./region-manager";
3
+ import { shellRegions } from "./regions";
4
+ import { shellEvents } from "../../events";
5
+
6
+ const pluginId = "test-plugin";
7
+ const mockView = { id: "view1" };
8
+
9
+ const createMockRegion = () => ({
10
+ activate: vi.fn(),
11
+ deactivate: vi.fn(),
12
+ removeView: vi.fn(),
13
+ containsView: vi.fn().mockReturnValue(true),
14
+ isViewActive: vi.fn().mockReturnValue(false),
15
+ currentActiveViews: [{ id: "view1" }],
16
+ });
17
+
18
+ describe("RegionManagerProxy", () => {
19
+ let proxy: ReturnType<typeof createRegionManagerProxy>;
20
+ let regionManager: any;
21
+ let broker: any;
22
+ let regionMock: any;
23
+
24
+ beforeEach(() => {
25
+ regionMock = createMockRegion();
26
+ regionManager = {
27
+ registerViewWithRegion: vi.fn(),
28
+ getRegion: vi.fn().mockReturnValue(regionMock),
29
+ destroy: vi.fn(),
30
+ };
31
+
32
+ broker = {
33
+ publish: vi.fn(),
34
+ };
35
+
36
+ proxy = createRegionManagerProxy({ pluginId }, regionManager, broker);
37
+ });
38
+
39
+ it("registerView should delegate to regionManager", async () => {
40
+ await proxy.registerView("test-region", mockView);
41
+ expect(regionManager.registerViewWithRegion).toHaveBeenCalledWith(
42
+ "test-region",
43
+ `${pluginId}::${mockView.id}`,
44
+ mockView,
45
+ );
46
+ });
47
+
48
+ it("removeView should remove view from region", async () => {
49
+ await proxy.removeView("main", "view1");
50
+ expect(regionMock.removeView).toHaveBeenCalledWith(`${pluginId}::view1`);
51
+ });
52
+
53
+ it("activateView should activate the view and notify if region is main", async () => {
54
+ await proxy.activateView(shellRegions.main, "view1");
55
+ expect(regionMock.activate).toHaveBeenCalledWith(`${pluginId}::view1`);
56
+ expect(broker.publish).toHaveBeenCalledWith(shellEvents.mainViewChanged, { viewId: "view1" });
57
+ });
58
+
59
+ it("deactivateView should deactivate the view", async () => {
60
+ await proxy.deactivateView("main", "view1");
61
+ expect(regionMock.deactivate).toHaveBeenCalledWith(`${pluginId}::view1`);
62
+ });
63
+
64
+ it("getRegion should return the region", async () => {
65
+ const region = await proxy.getRegion("main");
66
+ expect(region).toEqual(regionMock);
67
+ });
68
+
69
+ it("containsView should check for view existence", async () => {
70
+ const result = await proxy.containsView("main", "view1");
71
+ expect(regionMock.containsView).toHaveBeenCalledWith(`${pluginId}::view1`);
72
+ expect(result).toBe(true);
73
+ });
74
+
75
+ it("isViewActive should check if view is active", async () => {
76
+ const result = await proxy.isViewActive("main", "view1");
77
+ expect(regionMock.isViewActive).toHaveBeenCalledWith(`${pluginId}::view1`);
78
+ expect(result).toBe(false);
79
+ });
80
+
81
+ it("registerQuickAction should register in quickActions region", async () => {
82
+ await proxy.registerQuickAction(mockView);
83
+ expect(regionManager.registerViewWithRegion).toHaveBeenCalledWith(
84
+ shellRegions.quickActions,
85
+ `${pluginId}::${mockView.id}`,
86
+ mockView,
87
+ );
88
+ });
89
+
90
+ it("registerNavigationMenu should register in navigationMenu region", async () => {
91
+ await proxy.registerNavigationMenu(mockView);
92
+ expect(regionManager.registerViewWithRegion).toHaveBeenCalledWith(
93
+ shellRegions.navigationMenu,
94
+ `${pluginId}::${mockView.id}`,
95
+ mockView,
96
+ );
97
+ });
98
+
99
+ it("registerMainView should register in main region", async () => {
100
+ await proxy.registerMainView(mockView);
101
+ expect(regionManager.registerViewWithRegion).toHaveBeenCalledWith(
102
+ shellRegions.main,
103
+ `${pluginId}::${mockView.id}`,
104
+ mockView,
105
+ );
106
+ });
107
+
108
+ it("activateMainView should activate main view and notify broker", async () => {
109
+ await proxy.activateMainView("view1");
110
+ expect(regionMock.activate).toHaveBeenCalledWith(`${pluginId}::view1`);
111
+ expect(broker.publish).toHaveBeenCalledWith(shellEvents.mainViewChanged, { viewId: "view1" });
112
+ });
113
+
114
+ it("getCurrentMainViewActive should return id of the active main view", () => {
115
+ const result = proxy.getCurrentMainViewActive();
116
+ expect(result).toBe("view1");
117
+ });
118
+
119
+ it("_destroy should call regionManager.destroy", () => {
120
+ proxy._destroy();
121
+ expect(regionManager.destroy).toHaveBeenCalled();
122
+ });
123
+ });
@@ -1,16 +1,15 @@
1
- import { selectableAdapterFactory as factory, regionAdapterRegistry } from "@uxland/regions";
2
- import "./UI/components/primaria-error-view/component";
3
1
  import { PrimariaShell } from "./UI/components/primaria-shell/primaria-shell";
4
2
  import { shellApi } from "./api/api";
5
- import { bootstrapFeatures } from "./features/bootstrapper";
6
- import { registerInternalViews } from "./handle-views";
7
- import { initializeLocalization } from "./locales";
3
+ import { useFeatures } from "./features/bootstrapper";
4
+ import { useInternalViews } from "./handle-views";
5
+ import { useLocalization } from "./locales";
6
+ import { useUI } from "./UI/bootstrapper";
8
7
 
9
8
  export const initializeShell = (hostAppElement: HTMLElement) => {
10
- initializeLocalization(shellApi);
11
- regionAdapterRegistry.registerAdapterFactory("primaria-content-switcher", factory);
9
+ useLocalization(shellApi);
10
+ useUI();
11
+ useInternalViews();
12
+ useFeatures(shellApi);
12
13
  const shell = new PrimariaShell();
13
14
  hostAppElement.appendChild(shell as any);
14
- registerInternalViews();
15
- bootstrapFeatures(shellApi);
16
15
  };
package/src/constants.ts CHANGED
@@ -1,4 +1,2 @@
1
1
  export const primariaShellId = "primaria-shell";
2
- export const clinicalMonitoringId = "clinical-monitoring";
3
2
  export const pocTestEventsId = "poc-events-ecap";
4
- export const pdfViewerId = "pdf-viewer";
package/src/disposer.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { shellApi } from "./api/api";
2
- import { teardownFeatures } from "./features/bootstrapper";
2
+ import { disposeFeatures } from "./features/bootstrapper";
3
3
  export const disposeShell = () => {
4
- teardownFeatures(shellApi);
4
+ disposeFeatures(shellApi);
5
5
  };
6
6
 
7
7
  export const raiseCloseEvent = () => {
@@ -2,20 +2,26 @@ import { mediatorSettings } from "mediatr-ts";
2
2
  import { PrimariaApi } from "../api/api";
3
3
  import { container } from "../infrastructure/ioc/container";
4
4
  import { TYPES } from "../infrastructure/ioc/types";
5
- import { bootstrapExitShell, teardownExitShell } from "./exit/bootstrapper";
6
- import { bootstrapGetUserInfo, teardownGetUserInfo } from "./get-user-info/bootstrapper";
5
+ import { useExitShell, disposeExitShell } from "./exit/bootstrapper";
6
+ import { useGetUserInfo, disposeGetUserInfo } from "./get-user-info/bootstrapper";
7
7
  import { GetUserInfo } from "./get-user-info/request";
8
+ import {
9
+ disposeClinicalMonitoring,
10
+ useClinicalMonitoring,
11
+ } from "./clinical-monitoring/bootstrapper";
8
12
 
9
- export const bootstrapFeatures = (api: PrimariaApi) => {
13
+ export const useFeatures = (api: PrimariaApi) => {
10
14
  container.bind(TYPES.primaryApi).toConstantValue(api);
11
- bootstrapGetUserInfo();
12
- bootstrapExitShell();
15
+ useGetUserInfo(api);
16
+ useExitShell(api);
17
+ useClinicalMonitoring(api);
13
18
  api.broker.send(new GetUserInfo());
14
19
  };
15
20
 
16
- export const teardownFeatures = (api: PrimariaApi) => {
17
- teardownGetUserInfo();
18
- teardownExitShell();
21
+ export const disposeFeatures = (api: PrimariaApi) => {
22
+ disposeGetUserInfo();
23
+ disposeExitShell();
24
+ disposeClinicalMonitoring(api);
19
25
  container.unbindAll();
20
26
  api.regionManager._destroy();
21
27
  mediatorSettings.resolver.clear();
@@ -0,0 +1,39 @@
1
+ import { customElement } from "lit/decorators.js";
2
+ import { PrimariaApi } from "../../api/api";
3
+ import { shellRegions } from "../../api/region-manager/regions";
4
+ import { clinicalMonitoringId } from "./constants";
5
+ import { ClinicalMonitoring } from "./component/clinical-monitoring";
6
+ import { shellEvents } from "../../events";
7
+ import { PrimariaNavItem } from "../../UI/shared-components/primaria-nav-item/primaria-nav-item";
8
+
9
+ export const useClinicalMonitoring = (api: PrimariaApi) => {
10
+ //@ts-ignore
11
+ customElement("clinical-monitoring")(ClinicalMonitoring);
12
+ api.regionManager.registerMainView({
13
+ id: clinicalMonitoringId,
14
+ factory: () => {
15
+ const mainItem = new ClinicalMonitoring();
16
+ return Promise.resolve(mainItem as unknown as HTMLElement);
17
+ },
18
+ isDefault: true,
19
+ });
20
+ api.regionManager.registerView(shellRegions.navigationMenu, {
21
+ id: clinicalMonitoringId,
22
+ factory: () => {
23
+ const menuItem = new PrimariaNavItem({
24
+ icon: "account_box",
25
+ label: "Seguiment clínic",
26
+ callbackFn: () => {
27
+ api.regionManager.activateMainView(clinicalMonitoringId);
28
+ api.broker.publish(shellEvents.openClinicalMonitoringRequested);
29
+ },
30
+ });
31
+ return Promise.resolve(menuItem);
32
+ },
33
+ sortHint: "000200",
34
+ });
35
+ };
36
+
37
+ export const disposeClinicalMonitoring = (api: PrimariaApi) => {
38
+ api.regionManager.removeView(shellRegions.main, clinicalMonitoringId);
39
+ };
@@ -1,13 +1,10 @@
1
+ import { IRegion, region } from "@uxland/regions";
1
2
  import { LitElement, css, html, unsafeCSS } from "lit";
2
- import { customElement } from "lit/decorators.js";
3
- import styles from "./styles.css?inline";
4
- import { template } from "./template";
5
3
  import { PrimariaRegionHost } from "../../../api/api";
6
- import { IRegion, region } from "@uxland/regions";
7
4
  import { clinicalMonitoringRegions } from "../../../api/region-manager/regions";
5
+ import styles from "./styles.css?inline";
6
+ import { template } from "./template";
8
7
 
9
- //@ts-ignore
10
- @customElement("clinical-monitoring")
11
8
  export class ClinicalMonitoring extends PrimariaRegionHost(LitElement) {
12
9
  render() {
13
10
  return html`${template(this)}`;
@@ -0,0 +1 @@
1
+ export const clinicalMonitoringId = "clinical-monitoring";
@@ -0,0 +1,6 @@
1
+ import { shellApi } from "../../api/api";
2
+ import { clinicalMonitoringId } from "./constants";
3
+
4
+ export const activateClinicalMonitoringView = () => {
5
+ shellApi.regionManager.activateMainView(clinicalMonitoringId);
6
+ };