@memberjunction/ng-explorer-core 2.121.0 → 2.122.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 (127) hide show
  1. package/README.md +0 -1
  2. package/dist/app-routing.module.d.ts +6 -5
  3. package/dist/app-routing.module.d.ts.map +1 -1
  4. package/dist/app-routing.module.js +266 -132
  5. package/dist/app-routing.module.js.map +1 -1
  6. package/dist/lib/app-view/application-view.component.js +10 -10
  7. package/dist/lib/app-view/application-view.component.js.map +1 -1
  8. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +11 -12
  9. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
  10. package/dist/lib/data-browser-component/data-browser.component.js +8 -8
  11. package/dist/lib/data-browser-component/data-browser.component.js.map +1 -1
  12. package/dist/lib/generic-browse-list/generic-browse-list.component.js +10 -7
  13. package/dist/lib/generic-browse-list/generic-browse-list.component.js.map +1 -1
  14. package/dist/lib/generic-browser-list/generic-browser-list.component.js +14 -11
  15. package/dist/lib/generic-browser-list/generic-browser-list.component.js.map +1 -1
  16. package/dist/lib/list-view/list-view.component.js +24 -21
  17. package/dist/lib/list-view/list-view.component.js.map +1 -1
  18. package/dist/lib/navigation/navigation.component.d.ts +0 -1
  19. package/dist/lib/navigation/navigation.component.d.ts.map +1 -1
  20. package/dist/lib/navigation/navigation.component.js +11 -19
  21. package/dist/lib/navigation/navigation.component.js.map +1 -1
  22. package/dist/lib/resource-browser/resource-browser.component.js +14 -11
  23. package/dist/lib/resource-browser/resource-browser.component.js.map +1 -1
  24. package/dist/lib/resource-wrappers/artifact-resource.component.d.ts +20 -0
  25. package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -0
  26. package/dist/lib/resource-wrappers/artifact-resource.component.js +92 -0
  27. package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -0
  28. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts +119 -0
  29. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -0
  30. package/dist/lib/resource-wrappers/chat-collections-resource.component.js +500 -0
  31. package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -0
  32. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +87 -0
  33. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -0
  34. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +345 -0
  35. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -0
  36. package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +67 -0
  37. package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -0
  38. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +244 -0
  39. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -0
  40. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +46 -3
  41. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  42. package/dist/lib/resource-wrappers/dashboard-resource.component.js +298 -21
  43. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  44. package/dist/lib/resource-wrappers/list-detail-resource.component.js +1 -1
  45. package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
  46. package/dist/lib/resource-wrappers/query-resource.component.js +1 -1
  47. package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
  48. package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
  49. package/dist/lib/resource-wrappers/record-resource.component.js +22 -5
  50. package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
  51. package/dist/lib/resource-wrappers/report-resource.component.js +1 -1
  52. package/dist/lib/resource-wrappers/report-resource.component.js.map +1 -1
  53. package/dist/lib/resource-wrappers/resource-wrappers-loader.d.ts.map +1 -1
  54. package/dist/lib/resource-wrappers/resource-wrappers-loader.js +15 -0
  55. package/dist/lib/resource-wrappers/resource-wrappers-loader.js.map +1 -1
  56. package/dist/lib/resource-wrappers/search-results-resource.component.js +1 -1
  57. package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
  58. package/dist/lib/resource-wrappers/view-resource.component.js +1 -1
  59. package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
  60. package/dist/lib/shell/components/header/app-nav.component.d.ts +45 -0
  61. package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -0
  62. package/dist/lib/shell/components/header/app-nav.component.js +127 -0
  63. package/dist/lib/shell/components/header/app-nav.component.js.map +1 -0
  64. package/dist/lib/shell/components/header/app-switcher.component.d.ts +53 -0
  65. package/dist/lib/shell/components/header/app-switcher.component.d.ts.map +1 -0
  66. package/dist/lib/shell/components/header/app-switcher.component.js +190 -0
  67. package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -0
  68. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +83 -0
  69. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -0
  70. package/dist/lib/shell/components/tabs/component-cache-manager.js +175 -0
  71. package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -0
  72. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +138 -0
  73. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -0
  74. package/dist/lib/shell/components/tabs/tab-container.component.js +920 -0
  75. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -0
  76. package/dist/lib/shell/services/settings-dialog.service.d.ts +28 -0
  77. package/dist/lib/shell/services/settings-dialog.service.d.ts.map +1 -0
  78. package/dist/lib/shell/services/settings-dialog.service.js +67 -0
  79. package/dist/lib/shell/services/settings-dialog.service.js.map +1 -0
  80. package/dist/lib/shell/shell.component.d.ts +166 -0
  81. package/dist/lib/shell/shell.component.d.ts.map +1 -0
  82. package/dist/lib/shell/shell.component.js +1173 -0
  83. package/dist/lib/shell/shell.component.js.map +1 -0
  84. package/dist/lib/shell/shell.module.d.ts +14 -0
  85. package/dist/lib/shell/shell.module.d.ts.map +1 -0
  86. package/dist/lib/shell/shell.module.js +42 -0
  87. package/dist/lib/shell/shell.module.js.map +1 -0
  88. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +17 -13
  89. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
  90. package/dist/lib/single-dashboard/single-dashboard.component.d.ts +2 -1
  91. package/dist/lib/single-dashboard/single-dashboard.component.d.ts.map +1 -1
  92. package/dist/lib/single-dashboard/single-dashboard.component.js +6 -1
  93. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  94. package/dist/lib/single-entity/single-entity.component.js +21 -17
  95. package/dist/lib/single-entity/single-entity.component.js.map +1 -1
  96. package/dist/lib/single-list-detail/single-list-detail.component.js +36 -30
  97. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  98. package/dist/lib/single-record/single-record.component.d.ts +1 -0
  99. package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
  100. package/dist/lib/single-record/single-record.component.js +16 -9
  101. package/dist/lib/single-record/single-record.component.js.map +1 -1
  102. package/dist/lib/single-report/single-report.component.d.ts +1 -7
  103. package/dist/lib/single-report/single-report.component.d.ts.map +1 -1
  104. package/dist/lib/single-report/single-report.component.js +16 -37
  105. package/dist/lib/single-report/single-report.component.js.map +1 -1
  106. package/dist/lib/single-view/single-view.component.d.ts +1 -2
  107. package/dist/lib/single-view/single-view.component.d.ts.map +1 -1
  108. package/dist/lib/single-view/single-view.component.js +35 -43
  109. package/dist/lib/single-view/single-view.component.js.map +1 -1
  110. package/dist/lib/style-guide-test/style-guide-test.component.js +20 -13
  111. package/dist/lib/style-guide-test/style-guide-test.component.js.map +1 -1
  112. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.d.ts +1 -1
  113. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.d.ts.map +1 -1
  114. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js +8 -11
  115. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js.map +1 -1
  116. package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
  117. package/dist/lib/user-notifications/user-notifications.component.js +0 -5
  118. package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
  119. package/dist/module.d.ts +50 -46
  120. package/dist/module.d.ts.map +1 -1
  121. package/dist/module.js +23 -11
  122. package/dist/module.js.map +1 -1
  123. package/dist/public-api.d.ts +4 -0
  124. package/dist/public-api.d.ts.map +1 -1
  125. package/dist/public-api.js +5 -0
  126. package/dist/public-api.js.map +1 -1
  127. package/package.json +36 -35
@@ -0,0 +1,190 @@
1
+ import { Component, Input, Output, EventEmitter, HostListener, ViewChild } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@memberjunction/ng-base-application";
4
+ import * as i2 from "@angular/common";
5
+ import * as i3 from "@memberjunction/ng-explorer-settings";
6
+ const _c0 = ["appConfigDialog"];
7
+ function AppSwitcherComponent_i_2_Template(rf, ctx) { if (rf & 1) {
8
+ i0.ɵɵelement(0, "i", 8);
9
+ } }
10
+ function AppSwitcherComponent_i_3_Template(rf, ctx) { if (rf & 1) {
11
+ i0.ɵɵelement(0, "i", 9);
12
+ } if (rf & 2) {
13
+ const ctx_r1 = i0.ɵɵnextContext();
14
+ i0.ɵɵclassMap((ctx_r1.activeApp == null ? null : ctx_r1.activeApp.Icon) || "fa-solid fa-cube");
15
+ i0.ɵɵstyleProp("color", ctx_r1.activeApp == null ? null : ctx_r1.activeApp.GetColor())("--active-color", ctx_r1.activeApp == null ? null : ctx_r1.activeApp.GetColor());
16
+ } }
17
+ function AppSwitcherComponent_div_5_div_1_i_1_Template(rf, ctx) { if (rf & 1) {
18
+ i0.ɵɵelement(0, "i", 18);
19
+ } }
20
+ function AppSwitcherComponent_div_5_div_1_i_2_Template(rf, ctx) { if (rf & 1) {
21
+ i0.ɵɵelement(0, "i");
22
+ } if (rf & 2) {
23
+ const app_r5 = i0.ɵɵnextContext().$implicit;
24
+ i0.ɵɵclassMap(app_r5.Icon || "fa-solid fa-cube");
25
+ } }
26
+ function AppSwitcherComponent_div_5_div_1_Template(rf, ctx) { if (rf & 1) {
27
+ const _r4 = i0.ɵɵgetCurrentView();
28
+ i0.ɵɵelementStart(0, "div", 15);
29
+ i0.ɵɵlistener("click", function AppSwitcherComponent_div_5_div_1_Template_div_click_0_listener() { const app_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.selectApp(app_r5)); });
30
+ i0.ɵɵtemplate(1, AppSwitcherComponent_div_5_div_1_i_1_Template, 1, 0, "i", 16)(2, AppSwitcherComponent_div_5_div_1_i_2_Template, 1, 2, "i", 17);
31
+ i0.ɵɵelementStart(3, "span");
32
+ i0.ɵɵtext(4);
33
+ i0.ɵɵelementEnd()();
34
+ } if (rf & 2) {
35
+ const app_r5 = ctx.$implicit;
36
+ const ctx_r1 = i0.ɵɵnextContext(2);
37
+ i0.ɵɵstyleProp("--item-color", app_r5.GetColor());
38
+ i0.ɵɵclassProp("active", app_r5.ID === (ctx_r1.activeApp == null ? null : ctx_r1.activeApp.ID))("loading", app_r5.ID === ctx_r1.loadingAppId);
39
+ i0.ɵɵadvance();
40
+ i0.ɵɵproperty("ngIf", app_r5.ID === ctx_r1.loadingAppId);
41
+ i0.ɵɵadvance();
42
+ i0.ɵɵproperty("ngIf", app_r5.ID !== ctx_r1.loadingAppId);
43
+ i0.ɵɵadvance(2);
44
+ i0.ɵɵtextInterpolate(app_r5.Name);
45
+ } }
46
+ function AppSwitcherComponent_div_5_Template(rf, ctx) { if (rf & 1) {
47
+ const _r3 = i0.ɵɵgetCurrentView();
48
+ i0.ɵɵelementStart(0, "div", 10);
49
+ i0.ɵɵtemplate(1, AppSwitcherComponent_div_5_div_1_Template, 5, 9, "div", 11);
50
+ i0.ɵɵelement(2, "div", 12);
51
+ i0.ɵɵelementStart(3, "div", 13);
52
+ i0.ɵɵlistener("click", function AppSwitcherComponent_div_5_Template_div_click_3_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openConfigDialog()); });
53
+ i0.ɵɵelement(4, "i", 14);
54
+ i0.ɵɵelementStart(5, "span");
55
+ i0.ɵɵtext(6, "Configure...");
56
+ i0.ɵɵelementEnd()()();
57
+ } if (rf & 2) {
58
+ const ctx_r1 = i0.ɵɵnextContext();
59
+ i0.ɵɵadvance();
60
+ i0.ɵɵproperty("ngForOf", ctx_r1.apps);
61
+ } }
62
+ /**
63
+ * App switcher dropdown in the header.
64
+ * Displays current app and allows switching between apps.
65
+ */
66
+ export class AppSwitcherComponent {
67
+ appManager;
68
+ activeApp = null;
69
+ isViewingSystemTab = false;
70
+ /** ID of the app currently being loaded (shows loading indicator) */
71
+ loadingAppId = null;
72
+ appSelected = new EventEmitter();
73
+ appConfigDialog;
74
+ showDropdown = false;
75
+ showConfigDialog = false;
76
+ constructor(appManager) {
77
+ this.appManager = appManager;
78
+ }
79
+ /**
80
+ * Check if the app switcher should show loading state
81
+ */
82
+ get isLoading() {
83
+ return this.loadingAppId !== null;
84
+ }
85
+ /**
86
+ * Get applications that should appear in the app switcher dropdown
87
+ * (NavigationStyle = 'App Switcher' or 'Both')
88
+ */
89
+ get apps() {
90
+ return this.appManager.GetAppSwitcherApps();
91
+ }
92
+ /**
93
+ * Toggle dropdown visibility
94
+ */
95
+ toggleDropdown() {
96
+ this.showDropdown = !this.showDropdown;
97
+ }
98
+ /**
99
+ * Select an application
100
+ * When viewing a system tab, always emit to allow returning to the app
101
+ */
102
+ selectApp(app) {
103
+ this.showDropdown = false;
104
+ if (app.ID !== this.activeApp?.ID || this.isViewingSystemTab) {
105
+ this.appSelected.emit(app.ID);
106
+ }
107
+ }
108
+ /**
109
+ * Close dropdown when clicking outside
110
+ */
111
+ onClickOutside(event) {
112
+ const target = event.target;
113
+ if (!target.closest('.app-switcher-container') && this.showDropdown) {
114
+ this.showDropdown = false;
115
+ }
116
+ }
117
+ /**
118
+ * Open the app configuration dialog
119
+ */
120
+ openConfigDialog() {
121
+ this.showDropdown = false;
122
+ this.showConfigDialog = true;
123
+ // Use setTimeout to ensure ViewChild is available
124
+ setTimeout(() => {
125
+ if (this.appConfigDialog) {
126
+ this.appConfigDialog.open();
127
+ }
128
+ }, 0);
129
+ }
130
+ /**
131
+ * Handle when config is saved - reload the app list
132
+ */
133
+ onConfigSaved() {
134
+ // The ApplicationManager will be refreshed by the dialog
135
+ // Force a re-render by triggering change detection
136
+ this.showConfigDialog = false;
137
+ }
138
+ static ɵfac = function AppSwitcherComponent_Factory(t) { return new (t || AppSwitcherComponent)(i0.ɵɵdirectiveInject(i1.ApplicationManager)); };
139
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AppSwitcherComponent, selectors: [["mj-app-switcher"]], viewQuery: function AppSwitcherComponent_Query(rf, ctx) { if (rf & 1) {
140
+ i0.ɵɵviewQuery(_c0, 5);
141
+ } if (rf & 2) {
142
+ let _t;
143
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.appConfigDialog = _t.first);
144
+ } }, hostBindings: function AppSwitcherComponent_HostBindings(rf, ctx) { if (rf & 1) {
145
+ i0.ɵɵlistener("click", function AppSwitcherComponent_click_HostBindingHandler($event) { return ctx.onClickOutside($event); }, false, i0.ɵɵresolveDocument);
146
+ } }, inputs: { activeApp: "activeApp", isViewingSystemTab: "isViewingSystemTab", loadingAppId: "loadingAppId" }, outputs: { appSelected: "appSelected" }, decls: 8, vars: 6, consts: [["appConfigDialog", ""], [1, "app-switcher-container"], [1, "app-switcher-button", 3, "click"], ["class", "app-icon loading-spinner fa-solid fa-spinner fa-spin", 4, "ngIf"], ["class", "app-icon", 3, "class", "color", "--active-color", 4, "ngIf"], [1, "dropdown-arrow", "fa-solid", "fa-chevron-down"], ["class", "app-switcher-dropdown", 4, "ngIf"], [3, "showDialogChange", "configSaved", "showDialog"], [1, "app-icon", "loading-spinner", "fa-solid", "fa-spinner", "fa-spin"], [1, "app-icon"], [1, "app-switcher-dropdown"], ["class", "app-switcher-item", 3, "active", "loading", "--item-color", "click", 4, "ngFor", "ngForOf"], [1, "app-switcher-divider"], [1, "app-switcher-item", "configure-item", 3, "click"], [1, "fa-solid", "fa-gear"], [1, "app-switcher-item", 3, "click"], ["class", "fa-solid fa-spinner fa-spin", 4, "ngIf"], [3, "class", 4, "ngIf"], [1, "fa-solid", "fa-spinner", "fa-spin"]], template: function AppSwitcherComponent_Template(rf, ctx) { if (rf & 1) {
147
+ const _r1 = i0.ɵɵgetCurrentView();
148
+ i0.ɵɵelementStart(0, "div", 1)(1, "div", 2);
149
+ i0.ɵɵlistener("click", function AppSwitcherComponent_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleDropdown()); });
150
+ i0.ɵɵtemplate(2, AppSwitcherComponent_i_2_Template, 1, 0, "i", 3)(3, AppSwitcherComponent_i_3_Template, 1, 6, "i", 4);
151
+ i0.ɵɵelement(4, "i", 5);
152
+ i0.ɵɵelementEnd();
153
+ i0.ɵɵtemplate(5, AppSwitcherComponent_div_5_Template, 7, 1, "div", 6);
154
+ i0.ɵɵelementEnd();
155
+ i0.ɵɵelementStart(6, "mj-user-app-config", 7, 0);
156
+ i0.ɵɵtwoWayListener("showDialogChange", function AppSwitcherComponent_Template_mj_user_app_config_showDialogChange_6_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.showConfigDialog, $event) || (ctx.showConfigDialog = $event); return i0.ɵɵresetView($event); });
157
+ i0.ɵɵlistener("configSaved", function AppSwitcherComponent_Template_mj_user_app_config_configSaved_6_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onConfigSaved()); });
158
+ i0.ɵɵelementEnd();
159
+ } if (rf & 2) {
160
+ i0.ɵɵclassProp("loading", ctx.isLoading);
161
+ i0.ɵɵadvance(2);
162
+ i0.ɵɵproperty("ngIf", ctx.isLoading);
163
+ i0.ɵɵadvance();
164
+ i0.ɵɵproperty("ngIf", !ctx.isLoading);
165
+ i0.ɵɵadvance(2);
166
+ i0.ɵɵproperty("ngIf", ctx.showDropdown);
167
+ i0.ɵɵadvance();
168
+ i0.ɵɵtwoWayProperty("showDialog", ctx.showConfigDialog);
169
+ } }, dependencies: [i2.NgForOf, i2.NgIf, i3.UserAppConfigComponent], styles: [".app-switcher-container[_ngcontent-%COMP%] {\n position: relative;\n margin-left: -2px; \n\n}\n\n.app-switcher-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 10px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s;\n user-select: none;\n position: relative;\n}\n.app-switcher-button[_ngcontent-%COMP%] .app-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n width: 24px;\n text-align: center;\n position: relative;\n}\n\n\n.app-switcher-button[_ngcontent-%COMP%] .app-icon[_ngcontent-%COMP%]::after {\n content: \"\";\n position: absolute;\n bottom: -6px;\n left: 2px;\n right: 2px;\n height: 3px;\n border-radius: 2px;\n background-color: var(--active-color, #757575);\n}\n.app-switcher-button[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n}\n.app-switcher-button[_ngcontent-%COMP%] .dropdown-arrow[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #9e9e9e;\n}\n\n.app-switcher-dropdown[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 8px);\n left: 0;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n min-width: 220px;\n width: max-content;\n overflow: hidden;\n z-index: 10000;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n transition: all 0.15s;\n font-weight: 500;\n color: #616161;\n position: relative;\n white-space: nowrap;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 8px;\n bottom: 8px;\n width: 3px;\n border-radius: 2px;\n background-color: var(--item-color, #757575);\n opacity: 0.8;\n transition: all 0.15s;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: var(--item-color, #757575);\n width: 20px;\n text-align: center;\n opacity: 1;\n transition: all 0.15s;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item[_ngcontent-%COMP%]:hover::before {\n opacity: 1;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--item-color, #1976d2) 10%, white);\n color: var(--item-color, #1976d2);\n font-weight: 600;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item.active[_ngcontent-%COMP%]::before {\n width: 4px;\n left: 3px;\n opacity: 1;\n}\n\n\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item.configure-item[_ngcontent-%COMP%] {\n color: #616161;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item.configure-item[_ngcontent-%COMP%]::before {\n display: none;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item.configure-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #757575;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item.configure-item[_ngcontent-%COMP%]:hover {\n color: #424242;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item.configure-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #424242;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: #e0e0e0;\n margin: 4px 12px;\n}\n\n\n\n.app-switcher-button[_ngcontent-%COMP%] .loading-spinner[_ngcontent-%COMP%] {\n color: #757575;\n}\n.app-switcher-button[_ngcontent-%COMP%] .loading-spinner[_ngcontent-%COMP%]::after {\n \n\n display: none;\n}\n\n\n\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item.loading[_ngcontent-%COMP%] {\n pointer-events: none;\n opacity: 0.7;\n}\n.app-switcher-dropdown[_ngcontent-%COMP%] .app-switcher-item.loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--item-color, #757575);\n}"] });
170
+ }
171
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AppSwitcherComponent, [{
172
+ type: Component,
173
+ args: [{ selector: 'mj-app-switcher', template: "<div class=\"app-switcher-container\" [class.loading]=\"isLoading\">\n <div class=\"app-switcher-button\"\n (click)=\"toggleDropdown()\">\n <!-- Show spinner when loading, otherwise show app icon -->\n <i *ngIf=\"isLoading\" class=\"app-icon loading-spinner fa-solid fa-spinner fa-spin\"></i>\n <i *ngIf=\"!isLoading\" class=\"app-icon\" [class]=\"activeApp?.Icon || 'fa-solid fa-cube'\"\n [style.color]=\"activeApp?.GetColor()\"\n [style.--active-color]=\"activeApp?.GetColor()\"></i>\n <i class=\"dropdown-arrow fa-solid fa-chevron-down\"></i>\n </div>\n\n <div class=\"app-switcher-dropdown\" *ngIf=\"showDropdown\">\n <div\n *ngFor=\"let app of apps\"\n class=\"app-switcher-item\"\n [class.active]=\"app.ID === activeApp?.ID\"\n [class.loading]=\"app.ID === loadingAppId\"\n [style.--item-color]=\"app.GetColor()\"\n (click)=\"selectApp(app)\">\n <i *ngIf=\"app.ID === loadingAppId\" class=\"fa-solid fa-spinner fa-spin\"></i>\n <i *ngIf=\"app.ID !== loadingAppId\" [class]=\"app.Icon || 'fa-solid fa-cube'\"></i>\n <span>{{ app.Name }}</span>\n </div>\n\n <!-- Divider -->\n <div class=\"app-switcher-divider\"></div>\n\n <!-- Configure option -->\n <div class=\"app-switcher-item configure-item\" (click)=\"openConfigDialog()\">\n <i class=\"fa-solid fa-gear\"></i>\n <span>Configure...</span>\n </div>\n </div>\n</div>\n\n<!-- App Configuration Dialog -->\n<mj-user-app-config\n #appConfigDialog\n [(showDialog)]=\"showConfigDialog\"\n (configSaved)=\"onConfigSaved()\">\n</mj-user-app-config>\n", styles: [".app-switcher-container {\n position: relative;\n margin-left: -2px; /* Fine-tune alignment when no nav-bar icons to the left */\n}\n\n.app-switcher-button {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 10px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s;\n user-select: none;\n position: relative;\n}\n.app-switcher-button .app-icon {\n font-size: 20px;\n width: 24px;\n text-align: center;\n position: relative;\n}\n/* Color underline under the icon only, not the caret */\n.app-switcher-button .app-icon::after {\n content: \"\";\n position: absolute;\n bottom: -6px;\n left: 2px;\n right: 2px;\n height: 3px;\n border-radius: 2px;\n background-color: var(--active-color, #757575);\n}\n.app-switcher-button:hover {\n background: #f5f5f5;\n}\n.app-switcher-button .dropdown-arrow {\n font-size: 10px;\n color: #9e9e9e;\n}\n\n.app-switcher-dropdown {\n position: absolute;\n top: calc(100% + 8px);\n left: 0;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n min-width: 220px;\n width: max-content;\n overflow: hidden;\n z-index: 10000;\n}\n.app-switcher-dropdown .app-switcher-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n transition: all 0.15s;\n font-weight: 500;\n color: #616161;\n position: relative;\n white-space: nowrap;\n}\n.app-switcher-dropdown .app-switcher-item::before {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 8px;\n bottom: 8px;\n width: 3px;\n border-radius: 2px;\n background-color: var(--item-color, #757575);\n opacity: 0.8;\n transition: all 0.15s;\n}\n.app-switcher-dropdown .app-switcher-item i {\n font-size: 18px;\n color: var(--item-color, #757575);\n width: 20px;\n text-align: center;\n opacity: 1;\n transition: all 0.15s;\n}\n.app-switcher-dropdown .app-switcher-item:hover {\n background: #f5f5f5;\n}\n.app-switcher-dropdown .app-switcher-item:hover::before {\n opacity: 1;\n}\n.app-switcher-dropdown .app-switcher-item.active {\n background: color-mix(in srgb, var(--item-color, #1976d2) 10%, white);\n color: var(--item-color, #1976d2);\n font-weight: 600;\n}\n.app-switcher-dropdown .app-switcher-item.active::before {\n width: 4px;\n left: 3px;\n opacity: 1;\n}\n/* Configure option - no color line, neutral gray styling */\n.app-switcher-dropdown .app-switcher-item.configure-item {\n color: #616161;\n}\n.app-switcher-dropdown .app-switcher-item.configure-item::before {\n display: none;\n}\n.app-switcher-dropdown .app-switcher-item.configure-item i {\n color: #757575;\n}\n.app-switcher-dropdown .app-switcher-item.configure-item:hover {\n color: #424242;\n}\n.app-switcher-dropdown .app-switcher-item.configure-item:hover i {\n color: #424242;\n}\n.app-switcher-dropdown .app-switcher-divider {\n height: 1px;\n background: #e0e0e0;\n margin: 4px 12px;\n}\n\n/* Loading state for app switcher button */\n.app-switcher-button .loading-spinner {\n color: #757575;\n}\n.app-switcher-button .loading-spinner::after {\n /* Hide the underline when showing spinner */\n display: none;\n}\n\n/* Loading state for dropdown items */\n.app-switcher-dropdown .app-switcher-item.loading {\n pointer-events: none;\n opacity: 0.7;\n}\n.app-switcher-dropdown .app-switcher-item.loading i {\n color: var(--item-color, #757575);\n}\n"] }]
174
+ }], () => [{ type: i1.ApplicationManager }], { activeApp: [{
175
+ type: Input
176
+ }], isViewingSystemTab: [{
177
+ type: Input
178
+ }], loadingAppId: [{
179
+ type: Input
180
+ }], appSelected: [{
181
+ type: Output
182
+ }], appConfigDialog: [{
183
+ type: ViewChild,
184
+ args: ['appConfigDialog']
185
+ }], onClickOutside: [{
186
+ type: HostListener,
187
+ args: ['document:click', ['$event']]
188
+ }] }); })();
189
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AppSwitcherComponent, { className: "AppSwitcherComponent", filePath: "src/lib/shell/components/header/app-switcher.component.ts", lineNumber: 14 }); })();
190
+ //# sourceMappingURL=app-switcher.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-switcher.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-switcher.component.ts","../../../../../src/lib/shell/components/header/app-switcher.component.html"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import { ComponentRef, ApplicationRef } from '@angular/core';
2
+ import { BaseResourceComponent } from '@memberjunction/ng-shared';
3
+ import { ResourceData } from '@memberjunction/core-entities';
4
+ /**
5
+ * Metadata about a cached component
6
+ */
7
+ export interface CachedComponentInfo {
8
+ componentRef: ComponentRef<BaseResourceComponent>;
9
+ wrapperElement: HTMLElement;
10
+ resourceType: string;
11
+ resourceRecordId: string;
12
+ applicationId: string;
13
+ isAttached: boolean;
14
+ attachedToTabId: string | null;
15
+ lastUsed: Date;
16
+ createdAt: Date;
17
+ resourceData: ResourceData;
18
+ }
19
+ /**
20
+ * Smart component cache manager that preserves component state across tab switches.
21
+ *
22
+ * Features:
23
+ * - Caches components by resource identity (not just tab ID)
24
+ * - Tracks component usage to prevent double-attachment
25
+ * - Detaches/reattaches DOM elements without destroying Angular components
26
+ * - Provides manual cache clearing (no automatic periodic cleanup)
27
+ */
28
+ export declare class ComponentCacheManager {
29
+ private appRef;
30
+ private cache;
31
+ constructor(appRef: ApplicationRef);
32
+ /**
33
+ * Generate a unique cache key from resource identity
34
+ */
35
+ private getCacheKey;
36
+ /**
37
+ * Check if a component exists in cache and is available for reuse
38
+ */
39
+ hasAvailableComponent(resourceType: string, recordId: string, appId: string): boolean;
40
+ /**
41
+ * Get a cached component if available (not currently attached)
42
+ */
43
+ getCachedComponent(resourceType: string, recordId: string, appId: string): CachedComponentInfo | null;
44
+ /**
45
+ * Store a component in the cache
46
+ */
47
+ cacheComponent(componentRef: ComponentRef<BaseResourceComponent>, wrapperElement: HTMLElement, resourceData: ResourceData, tabId: string): void;
48
+ /**
49
+ * Mark a component as attached to a tab
50
+ */
51
+ markAsAttached(resourceType: string, recordId: string, appId: string, tabId: string): void;
52
+ /**
53
+ * Mark a component as detached (available for reuse)
54
+ */
55
+ markAsDetached(tabId: string): CachedComponentInfo | null;
56
+ /**
57
+ * Get component info by tab ID (for finding what's attached to a tab)
58
+ */
59
+ getComponentByTabId(tabId: string): CachedComponentInfo | null;
60
+ /**
61
+ * Remove and destroy a specific component from cache
62
+ */
63
+ destroyComponent(resourceType: string, recordId: string, appId: string): void;
64
+ /**
65
+ * Remove and destroy component by tab ID
66
+ */
67
+ destroyComponentByTabId(tabId: string): void;
68
+ /**
69
+ * Clear the entire cache, destroying all components
70
+ * Call this manually when needed (e.g., user logout, app shutdown)
71
+ */
72
+ clearCache(): void;
73
+ /**
74
+ * Get cache statistics for debugging
75
+ */
76
+ getCacheStats(): {
77
+ total: number;
78
+ attached: number;
79
+ detached: number;
80
+ byResourceType: Map<string, number>;
81
+ };
82
+ }
83
+ //# sourceMappingURL=component-cache-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-cache-manager.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAElC,YAAY,EAAE,YAAY,CAAC,qBAAqB,CAAC,CAAC;IAGlD,cAAc,EAAE,WAAW,CAAC;IAG5B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IAGtB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAG/B,QAAQ,EAAE,IAAI,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAGhB,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,qBAAa,qBAAqB;IAGpB,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,KAAK,CAA0C;gBAEnC,MAAM,EAAE,cAAc;IAE1C;;OAEG;IACH,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAMrF;;OAEG;IACH,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAgBrG;;OAEG;IACH,cAAc,CACZ,YAAY,EAAE,YAAY,CAAC,qBAAqB,CAAC,EACjD,cAAc,EAAE,WAAW,EAC3B,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,MAAM,GACZ,IAAI;IAwBP;;OAEG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAY1F;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAkBzD;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAO9D;;OAEG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAkB7E;;OAEG;IACH,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAoB5C;;;OAGG;IACH,UAAU,IAAI,IAAI;IAalB;;OAEG;IACH,aAAa,IAAI;QACf,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACrC;CAqBF"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Smart component cache manager that preserves component state across tab switches.
3
+ *
4
+ * Features:
5
+ * - Caches components by resource identity (not just tab ID)
6
+ * - Tracks component usage to prevent double-attachment
7
+ * - Detaches/reattaches DOM elements without destroying Angular components
8
+ * - Provides manual cache clearing (no automatic periodic cleanup)
9
+ */
10
+ export class ComponentCacheManager {
11
+ appRef;
12
+ cache = new Map();
13
+ constructor(appRef) {
14
+ this.appRef = appRef;
15
+ }
16
+ /**
17
+ * Generate a unique cache key from resource identity
18
+ */
19
+ getCacheKey(resourceType, recordId, appId) {
20
+ // Normalize empty/null recordId to ensure consistent matching
21
+ const normalizedRecordId = recordId || '__no_record__';
22
+ return `${appId}::${resourceType}::${normalizedRecordId}`;
23
+ }
24
+ /**
25
+ * Check if a component exists in cache and is available for reuse
26
+ */
27
+ hasAvailableComponent(resourceType, recordId, appId) {
28
+ const key = this.getCacheKey(resourceType, recordId, appId);
29
+ const info = this.cache.get(key);
30
+ return info !== undefined && !info.isAttached;
31
+ }
32
+ /**
33
+ * Get a cached component if available (not currently attached)
34
+ */
35
+ getCachedComponent(resourceType, recordId, appId) {
36
+ const key = this.getCacheKey(resourceType, recordId, appId);
37
+ const info = this.cache.get(key);
38
+ if (!info) {
39
+ return null;
40
+ }
41
+ // Can only reuse if not currently attached elsewhere
42
+ if (info.isAttached) {
43
+ return null;
44
+ }
45
+ return info;
46
+ }
47
+ /**
48
+ * Store a component in the cache
49
+ */
50
+ cacheComponent(componentRef, wrapperElement, resourceData, tabId) {
51
+ const key = this.getCacheKey(resourceData.ResourceType, resourceData.ResourceRecordID || '', resourceData.Configuration?.applicationId || '');
52
+ const info = {
53
+ componentRef,
54
+ wrapperElement,
55
+ resourceType: resourceData.ResourceType,
56
+ resourceRecordId: resourceData.ResourceRecordID || '',
57
+ applicationId: resourceData.Configuration?.applicationId || '',
58
+ isAttached: true,
59
+ attachedToTabId: tabId,
60
+ lastUsed: new Date(),
61
+ createdAt: new Date(),
62
+ resourceData
63
+ };
64
+ this.cache.set(key, info);
65
+ console.log(`💾 Cached component: ${resourceData.ResourceType} (key: ${key})`);
66
+ }
67
+ /**
68
+ * Mark a component as attached to a tab
69
+ */
70
+ markAsAttached(resourceType, recordId, appId, tabId) {
71
+ const key = this.getCacheKey(resourceType, recordId, appId);
72
+ const info = this.cache.get(key);
73
+ if (info) {
74
+ info.isAttached = true;
75
+ info.attachedToTabId = tabId;
76
+ info.lastUsed = new Date();
77
+ console.log(`📌 Attached component: ${resourceType} to tab ${tabId}`);
78
+ }
79
+ }
80
+ /**
81
+ * Mark a component as detached (available for reuse)
82
+ */
83
+ markAsDetached(tabId) {
84
+ // Find component by tab ID
85
+ const entry = Array.from(this.cache.entries())
86
+ .find(([_, info]) => info.attachedToTabId === tabId);
87
+ if (!entry) {
88
+ return null;
89
+ }
90
+ const [key, info] = entry;
91
+ info.isAttached = false;
92
+ info.attachedToTabId = null;
93
+ info.lastUsed = new Date();
94
+ console.log(`📎 Detached component: ${info.resourceType} from tab ${tabId}`);
95
+ return info;
96
+ }
97
+ /**
98
+ * Get component info by tab ID (for finding what's attached to a tab)
99
+ */
100
+ getComponentByTabId(tabId) {
101
+ const entry = Array.from(this.cache.entries())
102
+ .find(([_, info]) => info.attachedToTabId === tabId);
103
+ return entry ? entry[1] : null;
104
+ }
105
+ /**
106
+ * Remove and destroy a specific component from cache
107
+ */
108
+ destroyComponent(resourceType, recordId, appId) {
109
+ const key = this.getCacheKey(resourceType, recordId, appId);
110
+ const info = this.cache.get(key);
111
+ if (!info) {
112
+ return;
113
+ }
114
+ // Destroy Angular component
115
+ this.appRef.detachView(info.componentRef.hostView);
116
+ info.componentRef.destroy();
117
+ // Remove from cache
118
+ this.cache.delete(key);
119
+ console.log(`🗑️ Destroyed component: ${resourceType}`);
120
+ }
121
+ /**
122
+ * Remove and destroy component by tab ID
123
+ */
124
+ destroyComponentByTabId(tabId) {
125
+ const entry = Array.from(this.cache.entries())
126
+ .find(([_, info]) => info.attachedToTabId === tabId);
127
+ if (!entry) {
128
+ return;
129
+ }
130
+ const [key, info] = entry;
131
+ // Destroy Angular component
132
+ this.appRef.detachView(info.componentRef.hostView);
133
+ info.componentRef.destroy();
134
+ // Remove from cache
135
+ this.cache.delete(key);
136
+ console.log(`🗑️ Destroyed component by tab ID: ${tabId}`);
137
+ }
138
+ /**
139
+ * Clear the entire cache, destroying all components
140
+ * Call this manually when needed (e.g., user logout, app shutdown)
141
+ */
142
+ clearCache() {
143
+ console.log(`🧹 Clearing component cache (${this.cache.size} components)`);
144
+ // Destroy all components
145
+ this.cache.forEach(info => {
146
+ this.appRef.detachView(info.componentRef.hostView);
147
+ info.componentRef.destroy();
148
+ });
149
+ // Clear the map
150
+ this.cache.clear();
151
+ }
152
+ /**
153
+ * Get cache statistics for debugging
154
+ */
155
+ getCacheStats() {
156
+ const stats = {
157
+ total: this.cache.size,
158
+ attached: 0,
159
+ detached: 0,
160
+ byResourceType: new Map()
161
+ };
162
+ this.cache.forEach(info => {
163
+ if (info.isAttached) {
164
+ stats.attached++;
165
+ }
166
+ else {
167
+ stats.detached++;
168
+ }
169
+ const count = stats.byResourceType.get(info.resourceType) || 0;
170
+ stats.byResourceType.set(info.resourceType, count + 1);
171
+ });
172
+ return stats;
173
+ }
174
+ }
175
+ //# sourceMappingURL=component-cache-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-cache-manager.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ import { OnInit, OnDestroy, AfterViewInit, ElementRef, ApplicationRef, EnvironmentInjector, ChangeDetectorRef } from '@angular/core';
2
+ import { GoldenLayoutManager, WorkspaceStateManager, ApplicationManager } from '@memberjunction/ng-base-application';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Container for Golden Layout tabs with app-colored styling.
6
+ *
7
+ * Handles:
8
+ * - Golden Layout initialization
9
+ * - Tab creation and styling
10
+ * - Lazy loading of tab content
11
+ * - Context menu for pin/close
12
+ * - Layout persistence
13
+ */
14
+ export declare class TabContainerComponent implements OnInit, OnDestroy, AfterViewInit {
15
+ private layoutManager;
16
+ private workspaceManager;
17
+ private appManager;
18
+ private appRef;
19
+ private environmentInjector;
20
+ private cdr;
21
+ glContainer: ElementRef<HTMLDivElement>;
22
+ directContentContainer: ElementRef<HTMLDivElement>;
23
+ private subscriptions;
24
+ private layoutInitialized;
25
+ private componentRefs;
26
+ private cacheManager;
27
+ useSingleResourceMode: boolean;
28
+ private singleResourceComponentRef;
29
+ private previousTabBarVisible;
30
+ private currentSingleResourceSignature;
31
+ private isCreatingInitialTabs;
32
+ contextMenuVisible: boolean;
33
+ contextMenuX: number;
34
+ contextMenuY: number;
35
+ contextMenuTabId: string | null;
36
+ constructor(layoutManager: GoldenLayoutManager, workspaceManager: WorkspaceStateManager, appManager: ApplicationManager, appRef: ApplicationRef, environmentInjector: EnvironmentInjector, cdr: ChangeDetectorRef);
37
+ ngOnInit(): void;
38
+ ngAfterViewInit(): void;
39
+ /**
40
+ * Initialize Golden Layout and load tabs
41
+ * @param forceCreateTabs - If true, always creates tabs fresh from config.tabs instead of restoring saved layout
42
+ */
43
+ private initializeGoldenLayout;
44
+ ngOnDestroy(): void;
45
+ /**
46
+ * Handle changes to tab bar visibility - switches between single-resource and multi-tab modes
47
+ */
48
+ private handleTabBarVisibilityChange;
49
+ /**
50
+ * Load content directly for single-resource mode (bypasses Golden Layout)
51
+ */
52
+ private loadSingleResourceContent;
53
+ /**
54
+ * Clean up single-resource mode component
55
+ */
56
+ private cleanupSingleResourceComponent;
57
+ /**
58
+ * Generate a signature for tab content to detect when content changes
59
+ * This is needed because in single-resource mode, the same tab ID can have different content
60
+ */
61
+ private getTabContentSignature;
62
+ /**
63
+ * Create a tab in Golden Layout from workspace tab data
64
+ */
65
+ private createTab;
66
+ /**
67
+ * Handle tab shown event for lazy loading
68
+ */
69
+ private onTabShown;
70
+ /**
71
+ * Load content into a tab container
72
+ * Uses component cache to reuse components for same resources
73
+ */
74
+ private loadTabContent;
75
+ /**
76
+ * Update tab display name in background without loading full component
77
+ * This ensures all tabs show proper names immediately, not just when clicked
78
+ */
79
+ private updateTabDisplayName;
80
+ /**
81
+ * Update tab title with resource display name after resource loads
82
+ */
83
+ private updateTabTitleFromResource;
84
+ /**
85
+ * Convert tab configuration to ResourceData
86
+ */
87
+ private getResourceDataFromTab;
88
+ private static _resourceTypesDataset;
89
+ /**
90
+ * Get ResourceType entity by name (includes DriverClass field)
91
+ */
92
+ private getResourceTypeEntity;
93
+ private getResourceTypeId;
94
+ /**
95
+ * Determine resource type from route
96
+ */
97
+ private getResourceTypeFromRoute;
98
+ /**
99
+ * Cleanup a tab's component
100
+ * Detaches from DOM but keeps in cache for potential reuse
101
+ */
102
+ private cleanupTabComponent;
103
+ /**
104
+ * Sync tabs with configuration changes
105
+ */
106
+ private syncTabsWithConfiguration;
107
+ /**
108
+ * Show context menu
109
+ */
110
+ showContextMenu(x: number, y: number, tabId: string): void;
111
+ /**
112
+ * Hide context menu
113
+ */
114
+ hideContextMenu(): void;
115
+ /**
116
+ * Check if context menu tab is pinned
117
+ */
118
+ get isContextTabPinned(): boolean;
119
+ /**
120
+ * Toggle pin from context menu
121
+ */
122
+ onContextPin(): void;
123
+ /**
124
+ * Close tab from context menu
125
+ */
126
+ onContextClose(): void;
127
+ /**
128
+ * Close all other tabs from context menu
129
+ */
130
+ onContextCloseOthers(): void;
131
+ /**
132
+ * Close tabs to the right from context menu
133
+ */
134
+ onContextCloseToRight(): void;
135
+ static ɵfac: i0.ɵɵFactoryDeclaration<TabContainerComponent, never>;
136
+ static ɵcmp: i0.ɵɵComponentDeclaration<TabContainerComponent, "mj-tab-container", never, {}, {}, never, never, false, never>;
137
+ }
138
+ //# sourceMappingURL=tab-container.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tab-container.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,SAAS,EACT,aAAa,EAEb,UAAU,EACV,cAAc,EACd,mBAAmB,EAInB,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAInB,MAAM,qCAAqC,CAAC;;AAO7C;;;;;;;;;GASG;AACH,qBAMa,qBAAsB,YAAW,MAAM,EAAE,SAAS,EAAE,aAAa;IA4B1E,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,GAAG;IAhCgC,WAAW,EAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAC9B,sBAAsB,EAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAE5G,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,iBAAiB,CAAS;IAGlC,OAAO,CAAC,aAAa,CAA0D;IAG/E,OAAO,CAAC,YAAY,CAAwB;IAI5C,qBAAqB,UAAS;IAC9B,OAAO,CAAC,0BAA0B,CAAoD;IACtF,OAAO,CAAC,qBAAqB,CAAwB;IACrD,OAAO,CAAC,8BAA8B,CAAuB;IAC7D,OAAO,CAAC,qBAAqB,CAAS;IAGtC,kBAAkB,UAAS;IAC3B,YAAY,SAAK;IACjB,YAAY,SAAK;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;gBAG7B,aAAa,EAAE,mBAAmB,EAClC,gBAAgB,EAAE,qBAAqB,EACvC,UAAU,EAAE,kBAAkB,EAC9B,MAAM,EAAE,cAAc,EACtB,mBAAmB,EAAE,mBAAmB,EACxC,GAAG,EAAE,iBAAiB;IAMhC,QAAQ,IAAI,IAAI;IA0DhB,eAAe,IAAI,IAAI;IAUvB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IA+D9B,WAAW,IAAI,IAAI;IAiBnB;;OAEG;IACH,OAAO,CAAC,4BAA4B;IA2EpC;;OAEG;YACW,yBAAyB;IAmHvC;;OAEG;IACH,OAAO,CAAC,8BAA8B;IActC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;OAEG;IACH,OAAO,CAAC,SAAS;IAoBjB;;OAEG;YACW,UAAU;IAQxB;;;OAGG;YACW,cAAc;IAgI5B;;;OAGG;YACW,oBAAoB;IA+ClC;;OAEG;YACW,0BAA0B;IA+BxC;;OAEG;YACW,sBAAsB;IA2DpC,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAkC;IAEtE;;OAEG;YACW,qBAAqB;YAoBrB,iBAAiB;IAQ/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAgChC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAuFjC;;OAEG;IACH,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IA8B1D;;OAEG;IACH,eAAe,IAAI,IAAI;IAKvB;;OAEG;IACH,IAAI,kBAAkB,IAAI,OAAO,CAIhC;IAED;;OAEG;IACH,YAAY,IAAI,IAAI;IAOpB;;OAEG;IACH,cAAc,IAAI,IAAI;IAOtB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAU5B;;OAEG;IACH,qBAAqB,IAAI,IAAI;yCAx+BlB,qBAAqB;2CAArB,qBAAqB;CAi/BjC"}