@memberjunction/ng-explorer-core 2.121.0 → 2.122.1
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/README.md +0 -1
- package/dist/app-routing.module.d.ts +6 -5
- package/dist/app-routing.module.d.ts.map +1 -1
- package/dist/app-routing.module.js +266 -132
- package/dist/app-routing.module.js.map +1 -1
- package/dist/lib/app-view/application-view.component.js +10 -10
- package/dist/lib/app-view/application-view.component.js.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +11 -12
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
- package/dist/lib/data-browser-component/data-browser.component.js +8 -8
- package/dist/lib/data-browser-component/data-browser.component.js.map +1 -1
- package/dist/lib/generic-browse-list/generic-browse-list.component.js +10 -7
- package/dist/lib/generic-browse-list/generic-browse-list.component.js.map +1 -1
- package/dist/lib/generic-browser-list/generic-browser-list.component.js +14 -11
- package/dist/lib/generic-browser-list/generic-browser-list.component.js.map +1 -1
- package/dist/lib/list-view/list-view.component.js +24 -21
- package/dist/lib/list-view/list-view.component.js.map +1 -1
- package/dist/lib/navigation/navigation.component.d.ts +0 -1
- package/dist/lib/navigation/navigation.component.d.ts.map +1 -1
- package/dist/lib/navigation/navigation.component.js +11 -19
- package/dist/lib/navigation/navigation.component.js.map +1 -1
- package/dist/lib/resource-browser/resource-browser.component.js +14 -11
- package/dist/lib/resource-browser/resource-browser.component.js.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts +20 -0
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/artifact-resource.component.js +92 -0
- package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -0
- package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts +119 -0
- package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js +500 -0
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -0
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +87 -0
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +345 -0
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -0
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +67 -0
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +244 -0
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -0
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +46 -3
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +298 -21
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/list-detail-resource.component.js +1 -1
- package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/query-resource.component.js +1 -1
- package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.js +22 -5
- package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/report-resource.component.js +1 -1
- package/dist/lib/resource-wrappers/report-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/resource-wrappers-loader.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/resource-wrappers-loader.js +15 -0
- package/dist/lib/resource-wrappers/resource-wrappers-loader.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.d.ts +45 -0
- package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -0
- package/dist/lib/shell/components/header/app-nav.component.js +127 -0
- package/dist/lib/shell/components/header/app-nav.component.js.map +1 -0
- package/dist/lib/shell/components/header/app-switcher.component.d.ts +53 -0
- package/dist/lib/shell/components/header/app-switcher.component.d.ts.map +1 -0
- package/dist/lib/shell/components/header/app-switcher.component.js +190 -0
- package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -0
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +83 -0
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -0
- package/dist/lib/shell/components/tabs/component-cache-manager.js +175 -0
- package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -0
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts +138 -0
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -0
- package/dist/lib/shell/components/tabs/tab-container.component.js +920 -0
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -0
- package/dist/lib/shell/services/settings-dialog.service.d.ts +28 -0
- package/dist/lib/shell/services/settings-dialog.service.d.ts.map +1 -0
- package/dist/lib/shell/services/settings-dialog.service.js +67 -0
- package/dist/lib/shell/services/settings-dialog.service.js.map +1 -0
- package/dist/lib/shell/shell.component.d.ts +166 -0
- package/dist/lib/shell/shell.component.d.ts.map +1 -0
- package/dist/lib/shell/shell.component.js +1173 -0
- package/dist/lib/shell/shell.component.js.map +1 -0
- package/dist/lib/shell/shell.module.d.ts +14 -0
- package/dist/lib/shell/shell.module.d.ts.map +1 -0
- package/dist/lib/shell/shell.module.js +42 -0
- package/dist/lib/shell/shell.module.js.map +1 -0
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +17 -13
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.d.ts +2 -1
- package/dist/lib/single-dashboard/single-dashboard.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js +6 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
- package/dist/lib/single-entity/single-entity.component.js +21 -17
- package/dist/lib/single-entity/single-entity.component.js.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.js +36 -30
- package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.d.ts +1 -0
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +16 -9
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- package/dist/lib/single-report/single-report.component.d.ts +1 -7
- package/dist/lib/single-report/single-report.component.d.ts.map +1 -1
- package/dist/lib/single-report/single-report.component.js +16 -37
- package/dist/lib/single-report/single-report.component.js.map +1 -1
- package/dist/lib/single-view/single-view.component.d.ts +1 -2
- package/dist/lib/single-view/single-view.component.d.ts.map +1 -1
- package/dist/lib/single-view/single-view.component.js +35 -43
- package/dist/lib/single-view/single-view.component.js.map +1 -1
- package/dist/lib/style-guide-test/style-guide-test.component.js +20 -13
- package/dist/lib/style-guide-test/style-guide-test.component.js.map +1 -1
- package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.d.ts +1 -1
- package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.d.ts.map +1 -1
- package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js +8 -11
- package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +0 -5
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/module.d.ts +50 -46
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +23 -11
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +4 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +5 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +44 -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"}
|