@memberjunction/ng-explorer-core 2.128.0 → 2.129.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 (154) hide show
  1. package/dist/app-routing.module.d.ts +7 -1
  2. package/dist/app-routing.module.d.ts.map +1 -1
  3. package/dist/app-routing.module.js +41 -74
  4. package/dist/app-routing.module.js.map +1 -1
  5. package/dist/generic/Item.types.d.ts +0 -54
  6. package/dist/generic/Item.types.d.ts.map +1 -1
  7. package/dist/generic/Item.types.js +0 -79
  8. package/dist/generic/Item.types.js.map +1 -1
  9. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +49 -2
  10. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  11. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +263 -27
  12. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  13. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  14. package/dist/lib/resource-wrappers/dashboard-resource.component.js +20 -26
  15. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  16. package/dist/lib/shell/components/dialogs/app-access-dialog.component.d.ts +108 -0
  17. package/dist/lib/shell/components/dialogs/app-access-dialog.component.d.ts.map +1 -0
  18. package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +371 -0
  19. package/dist/lib/shell/components/dialogs/app-access-dialog.component.js.map +1 -0
  20. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +22 -2
  21. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  22. package/dist/lib/shell/components/tabs/tab-container.component.js +40 -14
  23. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  24. package/dist/lib/shell/loading-themes.d.ts +160 -0
  25. package/dist/lib/shell/loading-themes.d.ts.map +1 -0
  26. package/dist/lib/shell/loading-themes.js +838 -0
  27. package/dist/lib/shell/loading-themes.js.map +1 -0
  28. package/dist/lib/shell/shell.component.d.ts +118 -0
  29. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  30. package/dist/lib/shell/shell.component.js +744 -226
  31. package/dist/lib/shell/shell.component.js.map +1 -1
  32. package/dist/lib/shell/shell.module.d.ts +8 -7
  33. package/dist/lib/shell/shell.module.d.ts.map +1 -1
  34. package/dist/lib/shell/shell.module.js +5 -2
  35. package/dist/lib/shell/shell.module.js.map +1 -1
  36. package/dist/lib/single-dashboard/single-dashboard.component.d.ts +1 -0
  37. package/dist/lib/single-dashboard/single-dashboard.component.d.ts.map +1 -1
  38. package/dist/lib/single-dashboard/single-dashboard.component.js +4 -0
  39. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  40. package/dist/lib/single-list-detail/single-list-detail.component.js +1 -1
  41. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  42. package/dist/module.d.ts +62 -88
  43. package/dist/module.d.ts.map +1 -1
  44. package/dist/module.js +9 -149
  45. package/dist/module.js.map +1 -1
  46. package/dist/public-api.d.ts +0 -19
  47. package/dist/public-api.d.ts.map +1 -1
  48. package/dist/public-api.js +0 -19
  49. package/dist/public-api.js.map +1 -1
  50. package/package.json +35 -40
  51. package/dist/generic/Events.types.d.ts +0 -174
  52. package/dist/generic/Events.types.d.ts.map +0 -1
  53. package/dist/generic/Events.types.js +0 -220
  54. package/dist/generic/Events.types.js.map +0 -1
  55. package/dist/lib/app-view/application-view.component.d.ts +0 -65
  56. package/dist/lib/app-view/application-view.component.d.ts.map +0 -1
  57. package/dist/lib/app-view/application-view.component.js +0 -611
  58. package/dist/lib/app-view/application-view.component.js.map +0 -1
  59. package/dist/lib/auth-button/auth-button.component.d.ts +0 -13
  60. package/dist/lib/auth-button/auth-button.component.d.ts.map +0 -1
  61. package/dist/lib/auth-button/auth-button.component.js +0 -36
  62. package/dist/lib/auth-button/auth-button.component.js.map +0 -1
  63. package/dist/lib/base-browser-component/base-browser-component.d.ts +0 -44
  64. package/dist/lib/base-browser-component/base-browser-component.d.ts.map +0 -1
  65. package/dist/lib/base-browser-component/base-browser-component.js +0 -195
  66. package/dist/lib/base-browser-component/base-browser-component.js.map +0 -1
  67. package/dist/lib/chat-wrapper/chat-wrapper.component.d.ts +0 -54
  68. package/dist/lib/chat-wrapper/chat-wrapper.component.d.ts.map +0 -1
  69. package/dist/lib/chat-wrapper/chat-wrapper.component.js +0 -257
  70. package/dist/lib/chat-wrapper/chat-wrapper.component.js.map +0 -1
  71. package/dist/lib/dashboard-browser-component/dashboard-browser.component.d.ts +0 -32
  72. package/dist/lib/dashboard-browser-component/dashboard-browser.component.d.ts.map +0 -1
  73. package/dist/lib/dashboard-browser-component/dashboard-browser.component.js +0 -244
  74. package/dist/lib/dashboard-browser-component/dashboard-browser.component.js.map +0 -1
  75. package/dist/lib/data-browser-component/data-browser.component.d.ts +0 -23
  76. package/dist/lib/data-browser-component/data-browser.component.d.ts.map +0 -1
  77. package/dist/lib/data-browser-component/data-browser.component.js +0 -267
  78. package/dist/lib/data-browser-component/data-browser.component.js.map +0 -1
  79. package/dist/lib/expansion-panel-component/expansion-panel-component.d.ts +0 -21
  80. package/dist/lib/expansion-panel-component/expansion-panel-component.d.ts.map +0 -1
  81. package/dist/lib/expansion-panel-component/expansion-panel-component.js +0 -158
  82. package/dist/lib/expansion-panel-component/expansion-panel-component.js.map +0 -1
  83. package/dist/lib/favorites/favorites.component.d.ts +0 -15
  84. package/dist/lib/favorites/favorites.component.d.ts.map +0 -1
  85. package/dist/lib/favorites/favorites.component.js +0 -135
  86. package/dist/lib/favorites/favorites.component.js.map +0 -1
  87. package/dist/lib/files/files.component.d.ts +0 -10
  88. package/dist/lib/files/files.component.d.ts.map +0 -1
  89. package/dist/lib/files/files.component.js +0 -41
  90. package/dist/lib/files/files.component.js.map +0 -1
  91. package/dist/lib/generic-browse-list/generic-browse-list.component.d.ts +0 -30
  92. package/dist/lib/generic-browse-list/generic-browse-list.component.d.ts.map +0 -1
  93. package/dist/lib/generic-browse-list/generic-browse-list.component.js +0 -171
  94. package/dist/lib/generic-browse-list/generic-browse-list.component.js.map +0 -1
  95. package/dist/lib/generic-browser-list/generic-browser-list.component.d.ts +0 -120
  96. package/dist/lib/generic-browser-list/generic-browser-list.component.d.ts.map +0 -1
  97. package/dist/lib/generic-browser-list/generic-browser-list.component.js +0 -1093
  98. package/dist/lib/generic-browser-list/generic-browser-list.component.js.map +0 -1
  99. package/dist/lib/header/MSFT_UserImageService.d.ts +0 -12
  100. package/dist/lib/header/MSFT_UserImageService.d.ts.map +0 -1
  101. package/dist/lib/header/MSFT_UserImageService.js +0 -25
  102. package/dist/lib/header/MSFT_UserImageService.js.map +0 -1
  103. package/dist/lib/header/header.component.d.ts +0 -69
  104. package/dist/lib/header/header.component.d.ts.map +0 -1
  105. package/dist/lib/header/header.component.js +0 -342
  106. package/dist/lib/header/header.component.js.map +0 -1
  107. package/dist/lib/home-component/home.component.d.ts +0 -22
  108. package/dist/lib/home-component/home.component.d.ts.map +0 -1
  109. package/dist/lib/home-component/home.component.js +0 -194
  110. package/dist/lib/home-component/home.component.js.map +0 -1
  111. package/dist/lib/home-wrapper/home-wrapper.component.d.ts +0 -7
  112. package/dist/lib/home-wrapper/home-wrapper.component.d.ts.map +0 -1
  113. package/dist/lib/home-wrapper/home-wrapper.component.js +0 -30
  114. package/dist/lib/home-wrapper/home-wrapper.component.js.map +0 -1
  115. package/dist/lib/list-view/list-view.component.d.ts +0 -45
  116. package/dist/lib/list-view/list-view.component.d.ts.map +0 -1
  117. package/dist/lib/list-view/list-view.component.js +0 -329
  118. package/dist/lib/list-view/list-view.component.js.map +0 -1
  119. package/dist/lib/navigation/navigation.component.d.ts +0 -142
  120. package/dist/lib/navigation/navigation.component.d.ts.map +0 -1
  121. package/dist/lib/navigation/navigation.component.js +0 -1212
  122. package/dist/lib/navigation/navigation.component.js.map +0 -1
  123. package/dist/lib/query-browser-component/query-browser.component.d.ts +0 -75
  124. package/dist/lib/query-browser-component/query-browser.component.d.ts.map +0 -1
  125. package/dist/lib/query-browser-component/query-browser.component.js +0 -908
  126. package/dist/lib/query-browser-component/query-browser.component.js.map +0 -1
  127. package/dist/lib/report-browser-component/report-browser.component.d.ts +0 -22
  128. package/dist/lib/report-browser-component/report-browser.component.d.ts.map +0 -1
  129. package/dist/lib/report-browser-component/report-browser.component.js +0 -80
  130. package/dist/lib/report-browser-component/report-browser.component.js.map +0 -1
  131. package/dist/lib/resource-browser/resource-browser.component.d.ts +0 -178
  132. package/dist/lib/resource-browser/resource-browser.component.d.ts.map +0 -1
  133. package/dist/lib/resource-browser/resource-browser.component.js +0 -1012
  134. package/dist/lib/resource-browser/resource-browser.component.js.map +0 -1
  135. package/dist/lib/shared/custom-icon/custom-icon.component.d.ts +0 -11
  136. package/dist/lib/shared/custom-icon/custom-icon.component.d.ts.map +0 -1
  137. package/dist/lib/shared/custom-icon/custom-icon.component.js +0 -44
  138. package/dist/lib/shared/custom-icon/custom-icon.component.js.map +0 -1
  139. package/dist/lib/single-application/single-application.component.d.ts +0 -24
  140. package/dist/lib/single-application/single-application.component.d.ts.map +0 -1
  141. package/dist/lib/single-application/single-application.component.js +0 -122
  142. package/dist/lib/single-application/single-application.component.js.map +0 -1
  143. package/dist/lib/single-entity/single-entity.component.d.ts +0 -34
  144. package/dist/lib/single-entity/single-entity.component.d.ts.map +0 -1
  145. package/dist/lib/single-entity/single-entity.component.js +0 -245
  146. package/dist/lib/single-entity/single-entity.component.js.map +0 -1
  147. package/dist/lib/style-guide-test/style-guide-test.component.d.ts +0 -70
  148. package/dist/lib/style-guide-test/style-guide-test.component.d.ts.map +0 -1
  149. package/dist/lib/style-guide-test/style-guide-test.component.js +0 -1024
  150. package/dist/lib/style-guide-test/style-guide-test.component.js.map +0 -1
  151. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.d.ts +0 -46
  152. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.d.ts.map +0 -1
  153. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js +0 -547
  154. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js.map +0 -1
@@ -0,0 +1,371 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/common";
4
+ function AppAccessDialogComponent_div_0_p_8_Template(rf, ctx) { if (rf & 1) {
5
+ i0.ɵɵelementStart(0, "p", 11);
6
+ i0.ɵɵtext(1);
7
+ i0.ɵɵelementEnd();
8
+ } if (rf & 2) {
9
+ const ctx_r1 = i0.ɵɵnextContext(2);
10
+ i0.ɵɵadvance();
11
+ i0.ɵɵtextInterpolate(ctx_r1.helpMessage);
12
+ } }
13
+ function AppAccessDialogComponent_div_0_button_10_i_1_Template(rf, ctx) { if (rf & 1) {
14
+ i0.ɵɵelement(0, "i", 15);
15
+ } }
16
+ function AppAccessDialogComponent_div_0_button_10_span_2_Template(rf, ctx) { if (rf & 1) {
17
+ i0.ɵɵelementStart(0, "span");
18
+ i0.ɵɵtext(1);
19
+ i0.ɵɵelementEnd();
20
+ } if (rf & 2) {
21
+ const ctx_r1 = i0.ɵɵnextContext(3);
22
+ i0.ɵɵadvance();
23
+ i0.ɵɵtextInterpolate(ctx_r1.primaryActionText);
24
+ } }
25
+ function AppAccessDialogComponent_div_0_button_10_span_3_Template(rf, ctx) { if (rf & 1) {
26
+ i0.ɵɵelementStart(0, "span");
27
+ i0.ɵɵtext(1, "Processing...");
28
+ i0.ɵɵelementEnd();
29
+ } }
30
+ function AppAccessDialogComponent_div_0_button_10_Template(rf, ctx) { if (rf & 1) {
31
+ const _r3 = i0.ɵɵgetCurrentView();
32
+ i0.ɵɵelementStart(0, "button", 12);
33
+ i0.ɵɵlistener("click", function AppAccessDialogComponent_div_0_button_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onPrimaryAction()); });
34
+ i0.ɵɵtemplate(1, AppAccessDialogComponent_div_0_button_10_i_1_Template, 1, 0, "i", 13)(2, AppAccessDialogComponent_div_0_button_10_span_2_Template, 2, 1, "span", 14)(3, AppAccessDialogComponent_div_0_button_10_span_3_Template, 2, 0, "span", 14);
35
+ i0.ɵɵelementEnd();
36
+ } if (rf & 2) {
37
+ const ctx_r1 = i0.ɵɵnextContext(2);
38
+ i0.ɵɵproperty("disabled", ctx_r1.isProcessing);
39
+ i0.ɵɵadvance();
40
+ i0.ɵɵproperty("ngIf", ctx_r1.isProcessing);
41
+ i0.ɵɵadvance();
42
+ i0.ɵɵproperty("ngIf", !ctx_r1.isProcessing);
43
+ i0.ɵɵadvance();
44
+ i0.ɵɵproperty("ngIf", ctx_r1.isProcessing);
45
+ } }
46
+ function AppAccessDialogComponent_div_0_Template(rf, ctx) { if (rf & 1) {
47
+ const _r1 = i0.ɵɵgetCurrentView();
48
+ i0.ɵɵelementStart(0, "div", 1);
49
+ i0.ɵɵlistener("click", function AppAccessDialogComponent_div_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDismiss()); });
50
+ i0.ɵɵelementStart(1, "div", 2);
51
+ i0.ɵɵlistener("click", function AppAccessDialogComponent_div_0_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView($event.stopPropagation()); });
52
+ i0.ɵɵelementStart(2, "div", 3);
53
+ i0.ɵɵelement(3, "i", 4);
54
+ i0.ɵɵelementEnd();
55
+ i0.ɵɵelementStart(4, "h2", 5);
56
+ i0.ɵɵtext(5);
57
+ i0.ɵɵelementEnd();
58
+ i0.ɵɵelementStart(6, "p", 6);
59
+ i0.ɵɵtext(7);
60
+ i0.ɵɵelementEnd();
61
+ i0.ɵɵtemplate(8, AppAccessDialogComponent_div_0_p_8_Template, 2, 1, "p", 7);
62
+ i0.ɵɵelementStart(9, "div", 8);
63
+ i0.ɵɵtemplate(10, AppAccessDialogComponent_div_0_button_10_Template, 4, 4, "button", 9);
64
+ i0.ɵɵelementStart(11, "button", 10);
65
+ i0.ɵɵlistener("click", function AppAccessDialogComponent_div_0_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDismiss()); });
66
+ i0.ɵɵtext(12);
67
+ i0.ɵɵelementEnd()()()();
68
+ } if (rf & 2) {
69
+ const ctx_r1 = i0.ɵɵnextContext();
70
+ i0.ɵɵadvance(2);
71
+ i0.ɵɵstyleProp("color", ctx_r1.iconColor);
72
+ i0.ɵɵadvance();
73
+ i0.ɵɵproperty("ngClass", ctx_r1.icon);
74
+ i0.ɵɵadvance(2);
75
+ i0.ɵɵtextInterpolate(ctx_r1.title);
76
+ i0.ɵɵadvance(2);
77
+ i0.ɵɵtextInterpolate(ctx_r1.message);
78
+ i0.ɵɵadvance();
79
+ i0.ɵɵproperty("ngIf", ctx_r1.helpMessage);
80
+ i0.ɵɵadvance(2);
81
+ i0.ɵɵproperty("ngIf", ctx_r1.showPrimaryAction);
82
+ i0.ɵɵadvance();
83
+ i0.ɵɵclassProp("secondary", ctx_r1.showPrimaryAction);
84
+ i0.ɵɵproperty("disabled", ctx_r1.isProcessing);
85
+ i0.ɵɵadvance();
86
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.dismissButtonText, " ");
87
+ } }
88
+ /**
89
+ * Dialog component for handling app access errors.
90
+ * Shows appropriate messages and actions based on the type of access issue.
91
+ * Features auto-dismiss with countdown timer for certain dialog types.
92
+ */
93
+ export class AppAccessDialogComponent {
94
+ cdr;
95
+ visible = false;
96
+ visibleChange = new EventEmitter();
97
+ result = new EventEmitter();
98
+ config = null;
99
+ isProcessing = false;
100
+ // Auto-dismiss countdown
101
+ countdownInterval = null;
102
+ countdownSeconds = 0;
103
+ AUTO_DISMISS_SECONDS = 5;
104
+ constructor(cdr) {
105
+ this.cdr = cdr;
106
+ }
107
+ /**
108
+ * Show the dialog with the specified configuration
109
+ */
110
+ show(config) {
111
+ this.config = config;
112
+ this.visible = true;
113
+ this.isProcessing = false;
114
+ this.visibleChange.emit(true);
115
+ // Start countdown for types that auto-dismiss
116
+ if (this.shouldAutoDismiss()) {
117
+ this.startCountdown();
118
+ }
119
+ this.cdr.detectChanges();
120
+ }
121
+ /**
122
+ * Hide the dialog
123
+ */
124
+ hide() {
125
+ this.stopCountdown();
126
+ this.visible = false;
127
+ this.visibleChange.emit(false);
128
+ this.cdr.detectChanges();
129
+ }
130
+ ngOnDestroy() {
131
+ this.stopCountdown();
132
+ }
133
+ /**
134
+ * Get the dialog title based on type
135
+ */
136
+ get title() {
137
+ if (!this.config)
138
+ return '';
139
+ switch (this.config.type) {
140
+ case 'not_installed':
141
+ return 'Install Application?';
142
+ case 'disabled':
143
+ return 'Enable Application?';
144
+ case 'no_access':
145
+ return 'Access Denied';
146
+ case 'not_found':
147
+ return 'Application Not Found';
148
+ case 'inactive':
149
+ return 'Application Unavailable';
150
+ case 'no_apps':
151
+ return 'No Applications Available';
152
+ case 'layout_error':
153
+ return 'Display Error';
154
+ default:
155
+ return 'Application Error';
156
+ }
157
+ }
158
+ /**
159
+ * Get the dialog icon based on type
160
+ */
161
+ get icon() {
162
+ if (!this.config)
163
+ return 'fa-circle-info';
164
+ switch (this.config.type) {
165
+ case 'not_installed':
166
+ case 'disabled':
167
+ return 'fa-circle-question';
168
+ case 'no_access':
169
+ return 'fa-lock';
170
+ case 'not_found':
171
+ return 'fa-circle-xmark';
172
+ case 'inactive':
173
+ return 'fa-circle-pause';
174
+ case 'no_apps':
175
+ return 'fa-folder-open';
176
+ case 'layout_error':
177
+ return 'fa-triangle-exclamation';
178
+ default:
179
+ return 'fa-circle-info';
180
+ }
181
+ }
182
+ /**
183
+ * Get the dialog icon color based on type
184
+ */
185
+ get iconColor() {
186
+ if (!this.config)
187
+ return '#666';
188
+ switch (this.config.type) {
189
+ case 'not_installed':
190
+ case 'disabled':
191
+ return '#2196F3'; // Blue for actionable
192
+ case 'no_access':
193
+ case 'inactive':
194
+ return '#FF9800'; // Orange for warning
195
+ case 'not_found':
196
+ case 'layout_error':
197
+ return '#F44336'; // Red for error
198
+ case 'no_apps':
199
+ return '#9E9E9E'; // Gray for info
200
+ default:
201
+ return '#666';
202
+ }
203
+ }
204
+ /**
205
+ * Get the main message based on type
206
+ */
207
+ get message() {
208
+ if (!this.config)
209
+ return '';
210
+ const appName = this.config.appName || 'this application';
211
+ switch (this.config.type) {
212
+ case 'not_installed':
213
+ return `You don't have "${appName}" installed yet. Would you like to add it to your applications?`;
214
+ case 'disabled':
215
+ return `You have disabled "${appName}" in your app configuration. Would you like to enable it?`;
216
+ case 'no_access':
217
+ return `You don't have permission to access "${appName}".`;
218
+ case 'not_found':
219
+ return `The application "${appName}" doesn't exist in this system.`;
220
+ case 'inactive':
221
+ return `The application "${appName}" is currently inactive and unavailable.`;
222
+ case 'no_apps':
223
+ return `You don't have any applications configured. Your system administrator needs to set up your application access.`;
224
+ case 'layout_error':
225
+ return `There was an error displaying the application interface. The system will redirect you to an available application.`;
226
+ default:
227
+ return 'An error occurred while loading the application.';
228
+ }
229
+ }
230
+ /**
231
+ * Get the secondary/help message based on type
232
+ */
233
+ get helpMessage() {
234
+ if (!this.config)
235
+ return '';
236
+ switch (this.config.type) {
237
+ case 'not_installed':
238
+ case 'disabled':
239
+ return '';
240
+ case 'no_access':
241
+ case 'not_found':
242
+ case 'inactive':
243
+ return 'If you believe this is an error, please contact your system administrator.';
244
+ case 'no_apps':
245
+ return 'Please contact your system administrator to configure your application access.';
246
+ case 'layout_error':
247
+ return 'If this error persists, try clearing your browser cache or contact your system administrator.';
248
+ default:
249
+ return '';
250
+ }
251
+ }
252
+ /**
253
+ * Check if the primary action button should be shown
254
+ */
255
+ get showPrimaryAction() {
256
+ if (!this.config)
257
+ return false;
258
+ return this.config.type === 'not_installed' || this.config.type === 'disabled';
259
+ }
260
+ /**
261
+ * Get the primary action button text
262
+ */
263
+ get primaryActionText() {
264
+ if (!this.config)
265
+ return '';
266
+ switch (this.config.type) {
267
+ case 'not_installed':
268
+ return 'Install';
269
+ case 'disabled':
270
+ return 'Enable';
271
+ default:
272
+ return 'OK';
273
+ }
274
+ }
275
+ /**
276
+ * Get the secondary/dismiss button text with countdown if applicable
277
+ * For actionable dialogs (install/enable), show "Cancel"
278
+ * For non-actionable dialogs (errors), show "OK" with countdown
279
+ */
280
+ get dismissButtonText() {
281
+ // For actionable dialogs, use "Cancel"
282
+ if (this.showPrimaryAction) {
283
+ return 'Cancel';
284
+ }
285
+ // For non-actionable dialogs, show countdown if active
286
+ if (this.countdownSeconds > 0) {
287
+ return `OK (${this.countdownSeconds})`;
288
+ }
289
+ return 'OK';
290
+ }
291
+ /**
292
+ * Check if this dialog type should auto-dismiss
293
+ */
294
+ shouldAutoDismiss() {
295
+ if (!this.config)
296
+ return false;
297
+ return ['no_access', 'not_found', 'inactive', 'layout_error'].includes(this.config.type);
298
+ }
299
+ /**
300
+ * Start the countdown timer for auto-dismiss
301
+ */
302
+ startCountdown() {
303
+ this.stopCountdown();
304
+ this.countdownSeconds = this.AUTO_DISMISS_SECONDS;
305
+ this.countdownInterval = setInterval(() => {
306
+ this.countdownSeconds--;
307
+ this.cdr.detectChanges();
308
+ if (this.countdownSeconds <= 0) {
309
+ this.onDismiss();
310
+ }
311
+ }, 1000);
312
+ }
313
+ /**
314
+ * Stop the countdown timer
315
+ */
316
+ stopCountdown() {
317
+ if (this.countdownInterval) {
318
+ clearInterval(this.countdownInterval);
319
+ this.countdownInterval = null;
320
+ }
321
+ this.countdownSeconds = 0;
322
+ }
323
+ /**
324
+ * Handle primary action (install/enable)
325
+ */
326
+ async onPrimaryAction() {
327
+ if (!this.config)
328
+ return;
329
+ this.isProcessing = true;
330
+ this.cdr.detectChanges();
331
+ const action = this.config.type === 'not_installed' ? 'install' : 'enable';
332
+ this.result.emit({
333
+ action,
334
+ appId: this.config.appId
335
+ });
336
+ // Don't hide yet - let the parent component handle the result and close when ready
337
+ }
338
+ /**
339
+ * Handle dismiss/redirect action
340
+ */
341
+ onDismiss() {
342
+ this.stopCountdown();
343
+ this.result.emit({ action: 'redirect' });
344
+ this.hide();
345
+ }
346
+ /**
347
+ * Mark processing as complete (called by parent after install/enable)
348
+ */
349
+ completeProcessing() {
350
+ this.isProcessing = false;
351
+ this.hide();
352
+ }
353
+ static ɵfac = function AppAccessDialogComponent_Factory(t) { return new (t || AppAccessDialogComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
354
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AppAccessDialogComponent, selectors: [["mj-app-access-dialog"]], inputs: { visible: "visible" }, outputs: { visibleChange: "visibleChange", result: "result" }, decls: 1, vars: 1, consts: [["class", "dialog-overlay", 3, "click", 4, "ngIf"], [1, "dialog-overlay", 3, "click"], [1, "dialog-container", 3, "click"], [1, "dialog-icon"], [1, "fa-solid", 3, "ngClass"], [1, "dialog-title"], [1, "dialog-message"], ["class", "dialog-help", 4, "ngIf"], [1, "dialog-actions"], ["class", "dialog-btn primary", 3, "disabled", "click", 4, "ngIf"], [1, "dialog-btn", 3, "click", "disabled"], [1, "dialog-help"], [1, "dialog-btn", "primary", 3, "click", "disabled"], ["class", "fa-solid fa-spinner fa-spin", 4, "ngIf"], [4, "ngIf"], [1, "fa-solid", "fa-spinner", "fa-spin"]], template: function AppAccessDialogComponent_Template(rf, ctx) { if (rf & 1) {
355
+ i0.ɵɵtemplate(0, AppAccessDialogComponent_div_0_Template, 13, 11, "div", 0);
356
+ } if (rf & 2) {
357
+ i0.ɵɵproperty("ngIf", ctx.visible);
358
+ } }, dependencies: [i1.NgClass, i1.NgIf], styles: [".dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.6);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10001; \n\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-out;\n padding: 16px; \n\n box-sizing: border-box;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n.dialog-container[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 32px;\n max-width: 420px;\n width: 90%;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n animation: _ngcontent-%COMP%_slideUp 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.dialog-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n}\n\n.dialog-title[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.dialog-message[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 14px;\n line-height: 1.5;\n color: #4a4a4a;\n}\n\n.dialog-help[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 12px;\n color: #888;\n font-style: italic;\n}\n\n.dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n justify-content: center;\n margin-top: 24px;\n}\n\n.dialog-btn[_ngcontent-%COMP%] {\n padding: 10px 24px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n border: none;\n min-width: 100px;\n}\n\n.dialog-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.dialog-btn.primary[_ngcontent-%COMP%] {\n background: #2196F3;\n color: white;\n}\n\n.dialog-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #1976D2;\n}\n\n.dialog-btn.primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #1565C0;\n}\n\n.dialog-btn.secondary[_ngcontent-%COMP%], \n.dialog-btn[_ngcontent-%COMP%]:not(.primary):not(.secondary) {\n background: #f5f5f5;\n color: #333;\n border: 1px solid #ddd;\n}\n\n.dialog-btn.secondary[_ngcontent-%COMP%]:hover:not(:disabled), \n.dialog-btn[_ngcontent-%COMP%]:not(.primary):not(.secondary):hover:not(:disabled) {\n background: #e0e0e0;\n}\n\n.dialog-btn.secondary[_ngcontent-%COMP%]:active:not(:disabled), \n.dialog-btn[_ngcontent-%COMP%]:not(.primary):not(.secondary):active:not(:disabled) {\n background: #d0d0d0;\n}\n\n\n\n.fa-spin[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_spin 1s linear infinite;\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n\n\n@media (max-width: 768px) {\n .dialog-container[_ngcontent-%COMP%] {\n max-width: 380px;\n }\n\n .dialog-message[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n}\n\n\n\n@media (max-width: 480px) {\n .dialog-container[_ngcontent-%COMP%] {\n padding: 20px;\n margin: 0;\n max-width: none;\n width: 100%;\n border-radius: 8px;\n }\n\n .dialog-icon[_ngcontent-%COMP%] {\n font-size: 36px;\n margin-bottom: 12px;\n }\n\n .dialog-title[_ngcontent-%COMP%] {\n font-size: 17px;\n margin-bottom: 10px;\n }\n\n .dialog-message[_ngcontent-%COMP%] {\n font-size: 13px;\n margin-bottom: 6px;\n }\n\n .dialog-help[_ngcontent-%COMP%] {\n font-size: 11px;\n margin-bottom: 16px;\n }\n\n .dialog-actions[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 10px;\n margin-top: 20px;\n }\n\n .dialog-btn[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 20px;\n font-size: 15px;\n }\n}\n\n\n\n@media (max-width: 360px) {\n .dialog-container[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .dialog-icon[_ngcontent-%COMP%] {\n font-size: 32px;\n }\n\n .dialog-title[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n}"] });
359
+ }
360
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AppAccessDialogComponent, [{
361
+ type: Component,
362
+ args: [{ selector: 'mj-app-access-dialog', template: "<div class=\"dialog-overlay\" *ngIf=\"visible\" (click)=\"onDismiss()\">\n <div class=\"dialog-container\" (click)=\"$event.stopPropagation()\">\n <!-- Icon -->\n <div class=\"dialog-icon\" [style.color]=\"iconColor\">\n <i class=\"fa-solid\" [ngClass]=\"icon\"></i>\n </div>\n\n <!-- Title -->\n <h2 class=\"dialog-title\">{{ title }}</h2>\n\n <!-- Message -->\n <p class=\"dialog-message\">{{ message }}</p>\n\n <!-- Help message -->\n <p class=\"dialog-help\" *ngIf=\"helpMessage\">{{ helpMessage }}</p>\n\n <!-- Actions -->\n <div class=\"dialog-actions\">\n <button\n *ngIf=\"showPrimaryAction\"\n class=\"dialog-btn primary\"\n [disabled]=\"isProcessing\"\n (click)=\"onPrimaryAction()\">\n <i class=\"fa-solid fa-spinner fa-spin\" *ngIf=\"isProcessing\"></i>\n <span *ngIf=\"!isProcessing\">{{ primaryActionText }}</span>\n <span *ngIf=\"isProcessing\">Processing...</span>\n </button>\n\n <button\n class=\"dialog-btn\"\n [class.secondary]=\"showPrimaryAction\"\n [disabled]=\"isProcessing\"\n (click)=\"onDismiss()\">\n {{ dismissButtonText }}\n </button>\n </div>\n </div>\n</div>\n", styles: [".dialog-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.6);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10001; /* Higher than loading screen (10000) */\n animation: fadeIn 0.2s ease-out;\n padding: 16px; /* Ensure padding on small screens */\n box-sizing: border-box;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n.dialog-container {\n background: white;\n border-radius: 12px;\n padding: 32px;\n max-width: 420px;\n width: 90%;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n animation: slideUp 0.3s ease-out;\n}\n\n@keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.dialog-icon {\n font-size: 48px;\n margin-bottom: 16px;\n}\n\n.dialog-title {\n margin: 0 0 12px 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.dialog-message {\n margin: 0 0 8px 0;\n font-size: 14px;\n line-height: 1.5;\n color: #4a4a4a;\n}\n\n.dialog-help {\n margin: 0 0 20px 0;\n font-size: 12px;\n color: #888;\n font-style: italic;\n}\n\n.dialog-actions {\n display: flex;\n gap: 12px;\n justify-content: center;\n margin-top: 24px;\n}\n\n.dialog-btn {\n padding: 10px 24px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n border: none;\n min-width: 100px;\n}\n\n.dialog-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.dialog-btn.primary {\n background: #2196F3;\n color: white;\n}\n\n.dialog-btn.primary:hover:not(:disabled) {\n background: #1976D2;\n}\n\n.dialog-btn.primary:active:not(:disabled) {\n background: #1565C0;\n}\n\n.dialog-btn.secondary,\n.dialog-btn:not(.primary):not(.secondary) {\n background: #f5f5f5;\n color: #333;\n border: 1px solid #ddd;\n}\n\n.dialog-btn.secondary:hover:not(:disabled),\n.dialog-btn:not(.primary):not(.secondary):hover:not(:disabled) {\n background: #e0e0e0;\n}\n\n.dialog-btn.secondary:active:not(:disabled),\n.dialog-btn:not(.primary):not(.secondary):active:not(:disabled) {\n background: #d0d0d0;\n}\n\n/* Spinner animation */\n.fa-spin {\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n/* Responsive - Tablet */\n@media (max-width: 768px) {\n .dialog-container {\n max-width: 380px;\n }\n\n .dialog-message {\n font-size: 13px;\n }\n}\n\n/* Responsive - Mobile */\n@media (max-width: 480px) {\n .dialog-container {\n padding: 20px;\n margin: 0;\n max-width: none;\n width: 100%;\n border-radius: 8px;\n }\n\n .dialog-icon {\n font-size: 36px;\n margin-bottom: 12px;\n }\n\n .dialog-title {\n font-size: 17px;\n margin-bottom: 10px;\n }\n\n .dialog-message {\n font-size: 13px;\n margin-bottom: 6px;\n }\n\n .dialog-help {\n font-size: 11px;\n margin-bottom: 16px;\n }\n\n .dialog-actions {\n flex-direction: column;\n gap: 10px;\n margin-top: 20px;\n }\n\n .dialog-btn {\n width: 100%;\n padding: 12px 20px;\n font-size: 15px;\n }\n}\n\n/* Very small screens */\n@media (max-width: 360px) {\n .dialog-container {\n padding: 16px;\n }\n\n .dialog-icon {\n font-size: 32px;\n }\n\n .dialog-title {\n font-size: 16px;\n }\n}\n"] }]
363
+ }], () => [{ type: i0.ChangeDetectorRef }], { visible: [{
364
+ type: Input
365
+ }], visibleChange: [{
366
+ type: Output
367
+ }], result: [{
368
+ type: Output
369
+ }] }); })();
370
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AppAccessDialogComponent, { className: "AppAccessDialogComponent", filePath: "src/lib/shell/components/dialogs/app-access-dialog.component.ts", lineNumber: 42 }); })();
371
+ //# sourceMappingURL=app-access-dialog.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-access-dialog.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/dialogs/app-access-dialog.component.ts","../../../../../src/lib/shell/components/dialogs/app-access-dialog.component.html"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { OnInit, OnDestroy, AfterViewInit, ElementRef, ApplicationRef, EnvironmentInjector, ChangeDetectorRef } from '@angular/core';
1
+ import { OnInit, OnDestroy, AfterViewInit, ElementRef, ApplicationRef, EnvironmentInjector, ChangeDetectorRef, EventEmitter } from '@angular/core';
2
2
  import { GoldenLayoutManager, WorkspaceStateManager, ApplicationManager } from '@memberjunction/ng-base-application';
3
3
  import * as i0 from "@angular/core";
4
4
  /**
@@ -20,7 +20,21 @@ export declare class TabContainerComponent implements OnInit, OnDestroy, AfterVi
20
20
  private cdr;
21
21
  glContainer: ElementRef<HTMLDivElement>;
22
22
  directContentContainer: ElementRef<HTMLDivElement>;
23
+ /**
24
+ * Emitted when the first resource component finishes loading.
25
+ * This allows the shell to keep showing its loading indicator until the first
26
+ * resource is ready, eliminating the visual gap between shell loading and resource loading.
27
+ */
28
+ firstResourceLoadComplete: EventEmitter<void>;
29
+ /**
30
+ * Emitted when Golden Layout fails to initialize after multiple retries.
31
+ * The shell can use this to show an error dialog and redirect.
32
+ */
33
+ layoutInitError: EventEmitter<void>;
23
34
  private subscriptions;
35
+ private layoutInitRetryCount;
36
+ private readonly MAX_LAYOUT_INIT_RETRIES;
37
+ private hasEmittedFirstLoadComplete;
24
38
  private layoutInitialized;
25
39
  private componentRefs;
26
40
  private cacheManager;
@@ -143,7 +157,13 @@ export declare class TabContainerComponent implements OnInit, OnDestroy, AfterVi
143
157
  * Close tabs to the right from context menu
144
158
  */
145
159
  onContextCloseToRight(): void;
160
+ /**
161
+ * While the naming implies this is only invoked once, components we DO NOT CONTROL might have race
162
+ * conditions that result in unpredictable behavior. To avoid those causing loading screen overaly to show
163
+ * forever we emit all events upstream
164
+ */
165
+ private emitFirstLoadCompleteOnce;
146
166
  static ɵfac: i0.ɵɵFactoryDeclaration<TabContainerComponent, never>;
147
- static ɵcmp: i0.ɵɵComponentDeclaration<TabContainerComponent, "mj-tab-container", never, {}, {}, never, never, false, never>;
167
+ static ɵcmp: i0.ɵɵComponentDeclaration<TabContainerComponent, "mj-tab-container", never, {}, { "firstResourceLoadComplete": "firstResourceLoadComplete"; "layoutInitError": "layoutInitError"; }, never, never, false, never>;
148
168
  }
149
169
  //# sourceMappingURL=tab-container.component.d.ts.map
@@ -1 +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,EAElB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAKnB,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;IA6E9B,WAAW,IAAI,IAAI;IAiBnB;;;;OAIG;IAEH,cAAc,IAAI,IAAI;IAMtB;;OAEG;IACH,OAAO,CAAC,4BAA4B;IA2EpC;;OAEG;YACW,yBAAyB;IAmHvC;;OAEG;IACH,OAAO,CAAC,8BAA8B;IActC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAe9B;;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,qBAAqB;IAkB7B;;;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;yCA3hClB,qBAAqB;2CAArB,qBAAqB;CAoiCjC"}
1
+ {"version":3,"file":"tab-container.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Component, ViewChild, createComponent, ViewEncapsulation, HostListener } from '@angular/core';
1
+ import { Component, ViewChild, createComponent, ViewEncapsulation, HostListener, Output, EventEmitter } from '@angular/core';
2
2
  import { MJGlobal } from '@memberjunction/global';
3
3
  import { BaseResourceComponent } from '@memberjunction/ng-shared';
4
4
  import { ResourceData } from '@memberjunction/core-entities';
@@ -67,7 +67,21 @@ export class TabContainerComponent {
67
67
  cdr;
68
68
  glContainer;
69
69
  directContentContainer;
70
+ /**
71
+ * Emitted when the first resource component finishes loading.
72
+ * This allows the shell to keep showing its loading indicator until the first
73
+ * resource is ready, eliminating the visual gap between shell loading and resource loading.
74
+ */
75
+ firstResourceLoadComplete = new EventEmitter();
76
+ /**
77
+ * Emitted when Golden Layout fails to initialize after multiple retries.
78
+ * The shell can use this to show an error dialog and redirect.
79
+ */
80
+ layoutInitError = new EventEmitter();
70
81
  subscriptions = [];
82
+ layoutInitRetryCount = 0;
83
+ MAX_LAYOUT_INIT_RETRIES = 5;
84
+ hasEmittedFirstLoadComplete = false;
71
85
  layoutInitialized = false;
72
86
  // Track component references for cleanup (legacy - keep for backward compat during transition)
73
87
  componentRefs = new Map();
@@ -156,10 +170,18 @@ export class TabContainerComponent {
156
170
  */
157
171
  initializeGoldenLayout(forceCreateTabs = false) {
158
172
  if (!this.glContainer?.nativeElement) {
159
- console.warn('Golden Layout container not available, waiting...');
173
+ this.layoutInitRetryCount++;
174
+ if (this.layoutInitRetryCount > this.MAX_LAYOUT_INIT_RETRIES) {
175
+ console.error(`Golden Layout container not available after ${this.MAX_LAYOUT_INIT_RETRIES} retries, emitting error`);
176
+ this.layoutInitError.emit();
177
+ return;
178
+ }
179
+ console.warn(`Golden Layout container not available, retry ${this.layoutInitRetryCount}/${this.MAX_LAYOUT_INIT_RETRIES}...`);
160
180
  setTimeout(() => this.initializeGoldenLayout(forceCreateTabs), 50);
161
181
  return;
162
182
  }
183
+ // Reset retry counter on success
184
+ this.layoutInitRetryCount = 0;
163
185
  if (this.layoutInitialized) {
164
186
  return; // Already initialized
165
187
  }
@@ -255,7 +277,6 @@ export class TabContainerComponent {
255
277
  // Determine if we should use single-resource mode
256
278
  const shouldUseSingleResourceMode = !tabBarVisible;
257
279
  if (shouldUseSingleResourceMode !== this.useSingleResourceMode) {
258
- console.log(`🔄 Switching to ${shouldUseSingleResourceMode ? 'single-resource' : 'multi-tab'} mode`);
259
280
  this.useSingleResourceMode = shouldUseSingleResourceMode;
260
281
  this.cdr.detectChanges();
261
282
  if (this.useSingleResourceMode) {
@@ -265,7 +286,6 @@ export class TabContainerComponent {
265
286
  setTimeout(() => {
266
287
  // First, destroy Golden Layout if it was initialized (prevents stale state)
267
288
  if (this.layoutInitialized) {
268
- console.log('[TabContainer] Destroying Golden Layout when transitioning to single-resource mode');
269
289
  this.layoutManager.Destroy();
270
290
  this.layoutInitialized = false;
271
291
  }
@@ -355,7 +375,6 @@ export class TabContainerComponent {
355
375
  // **OPTIMIZATION: Check cache first to reuse existing loaded component**
356
376
  const cached = this.cacheManager.getCachedComponent(driverClass, resourceData.ResourceRecordID || '', activeTab.applicationId);
357
377
  if (cached) {
358
- console.log(`♻️ Reusing cached component for single-resource mode: ${driverClass}`);
359
378
  // Clean up previous single-resource component (if different)
360
379
  this.cleanupSingleResourceComponent();
361
380
  // Detach from tab tracking (it was attached to a tab in Golden Layout)
@@ -365,11 +384,8 @@ export class TabContainerComponent {
365
384
  container.appendChild(cached.wrapperElement);
366
385
  // Store reference for cleanup
367
386
  this.singleResourceComponentRef = cached.componentRef;
368
- console.log('✅ Single-resource component transferred from cache (instant!)');
369
387
  return;
370
388
  }
371
- // **Fallback: Create new component if not in cache**
372
- console.log(`📦 Creating new component for single-resource mode: ${driverClass}`);
373
389
  // Get the component registration
374
390
  const resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
375
391
  if (!resourceReg) {
@@ -389,7 +405,7 @@ export class TabContainerComponent {
389
405
  instance.Data = resourceData;
390
406
  // Wire up events
391
407
  instance.LoadCompleteEvent = () => {
392
- console.log('✅ Single-resource component loaded');
408
+ this.emitFirstLoadCompleteOnce();
393
409
  };
394
410
  // Get the native element and append to container
395
411
  const nativeElement = componentRef.hostView.rootNodes[0];
@@ -493,7 +509,6 @@ export class TabContainerComponent {
493
509
  // Check if we have a cached component for this resource
494
510
  const cached = this.cacheManager.getCachedComponent(driverClass, resourceData.ResourceRecordID || '', tab.applicationId);
495
511
  if (cached) {
496
- console.log(`♻️ Reusing cached component for ${resourceData.ResourceType} (driver: ${driverClass})`);
497
512
  // Reattach the cached wrapper element
498
513
  glContainer.element.appendChild(cached.wrapperElement);
499
514
  // Mark as attached to this tab
@@ -507,8 +522,6 @@ export class TabContainerComponent {
507
522
  }
508
523
  return;
509
524
  }
510
- // No cached component found - create new one
511
- console.log(`🆕 Creating new component for ${resourceData.ResourceType} using driver class: ${driverClass}`);
512
525
  // Get the component registration using the driver class
513
526
  const resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
514
527
  if (!resourceReg) {
@@ -528,6 +541,7 @@ export class TabContainerComponent {
528
541
  instance.LoadCompleteEvent = () => {
529
542
  // Tab content loaded - update tab title with resource display name
530
543
  this.updateTabTitleFromResource(tabId, instance, resourceData);
544
+ this.emitFirstLoadCompleteOnce();
531
545
  };
532
546
  instance.ResourceRecordSavedEvent = (entity) => {
533
547
  // Update tab title if needed
@@ -931,6 +945,14 @@ export class TabContainerComponent {
931
945
  }
932
946
  this.hideContextMenu();
933
947
  }
948
+ /**
949
+ * While the naming implies this is only invoked once, components we DO NOT CONTROL might have race
950
+ * conditions that result in unpredictable behavior. To avoid those causing loading screen overaly to show
951
+ * forever we emit all events upstream
952
+ */
953
+ emitFirstLoadCompleteOnce() {
954
+ this.firstResourceLoadComplete.emit(); // do this each time to be sure we don't suppress messages
955
+ }
934
956
  static ɵfac = function TabContainerComponent_Factory(t) { return new (t || TabContainerComponent)(i0.ɵɵdirectiveInject(i1.GoldenLayoutManager), i0.ɵɵdirectiveInject(i1.WorkspaceStateManager), i0.ɵɵdirectiveInject(i1.ApplicationManager), i0.ɵɵdirectiveInject(i0.ApplicationRef), i0.ɵɵdirectiveInject(i0.EnvironmentInjector), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
935
957
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TabContainerComponent, selectors: [["mj-tab-container"]], viewQuery: function TabContainerComponent_Query(rf, ctx) { if (rf & 1) {
936
958
  i0.ɵɵviewQuery(_c0, 5);
@@ -941,7 +963,7 @@ export class TabContainerComponent {
941
963
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.directContentContainer = _t.first);
942
964
  } }, hostBindings: function TabContainerComponent_HostBindings(rf, ctx) { if (rf & 1) {
943
965
  i0.ɵɵlistener("resize", function TabContainerComponent_resize_HostBindingHandler() { return ctx.onWindowResize(); }, false, i0.ɵɵresolveWindow);
944
- } }, decls: 4, vars: 2, consts: [["directContentContainer", ""], ["glContainer", ""], [1, "tab-container"], [1, "direct-content-container"], [1, "gl-container"], ["class", "context-menu", 3, "left", "top", 4, "ngIf"], [1, "context-menu"], [1, "context-menu-item", 3, "click"], [1, "fa-solid", "fa-thumbtack"], [1, "context-menu-divider"], [1, "fa-solid", "fa-xmark"], [1, "fa-solid", "fa-layer-group"], [1, "fa-solid", "fa-angles-right"]], template: function TabContainerComponent_Template(rf, ctx) { if (rf & 1) {
966
+ } }, outputs: { firstResourceLoadComplete: "firstResourceLoadComplete", layoutInitError: "layoutInitError" }, decls: 4, vars: 2, consts: [["directContentContainer", ""], ["glContainer", ""], [1, "tab-container"], [1, "direct-content-container"], [1, "gl-container"], ["class", "context-menu", 3, "left", "top", 4, "ngIf"], [1, "context-menu"], [1, "context-menu-item", 3, "click"], [1, "fa-solid", "fa-thumbtack"], [1, "context-menu-divider"], [1, "fa-solid", "fa-xmark"], [1, "fa-solid", "fa-layer-group"], [1, "fa-solid", "fa-angles-right"]], template: function TabContainerComponent_Template(rf, ctx) { if (rf & 1) {
945
967
  i0.ɵɵelementStart(0, "div", 2);
946
968
  i0.ɵɵtemplate(1, TabContainerComponent_Conditional_1_Template, 2, 0, "div", 3)(2, TabContainerComponent_Conditional_2_Template, 2, 0, "div", 4)(3, TabContainerComponent_div_3_Template, 18, 5, "div", 5);
947
969
  i0.ɵɵelementEnd();
@@ -961,9 +983,13 @@ export class TabContainerComponent {
961
983
  }], directContentContainer: [{
962
984
  type: ViewChild,
963
985
  args: ['directContentContainer', { static: false }]
986
+ }], firstResourceLoadComplete: [{
987
+ type: Output
988
+ }], layoutInitError: [{
989
+ type: Output
964
990
  }], onWindowResize: [{
965
991
  type: HostListener,
966
992
  args: ['window:resize']
967
993
  }] }); })();
968
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TabContainerComponent, { className: "TabContainerComponent", filePath: "src/lib/shell/components/tabs/tab-container.component.ts", lineNumber: 48 }); })();
994
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TabContainerComponent, { className: "TabContainerComponent", filePath: "src/lib/shell/components/tabs/tab-container.component.ts", lineNumber: 51 }); })();
969
995
  //# sourceMappingURL=tab-container.component.js.map