@memberjunction/ng-dashboards 5.3.1 → 5.4.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.
Files changed (173) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  2. package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
  3. package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
  4. package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
  5. package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
  6. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  7. package/dist/AI/components/models/model-management.component.js.map +1 -1
  8. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
  9. package/dist/AI/components/prompts/prompt-filter-panel.component.js.map +1 -1
  10. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  11. package/dist/AI/components/prompts/prompt-version-control.component.js.map +1 -1
  12. package/dist/AI/components/system/system-config-filter-panel.component.js.map +1 -1
  13. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  14. package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
  15. package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
  16. package/dist/AI/index.js.map +1 -1
  17. package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
  18. package/dist/APIKeys/api-applications-panel.component.js +2 -2
  19. package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
  20. package/dist/APIKeys/api-key-create-dialog.component.js +2 -2
  21. package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
  22. package/dist/APIKeys/api-key-edit-panel.component.js +2 -2
  23. package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
  24. package/dist/APIKeys/api-key-list.component.js +2 -2
  25. package/dist/APIKeys/api-key-list.component.js.map +1 -1
  26. package/dist/APIKeys/api-keys-resource.component.js +2 -2
  27. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  28. package/dist/APIKeys/api-scopes-panel.component.js +2 -2
  29. package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
  30. package/dist/APIKeys/api-usage-panel.component.js +2 -2
  31. package/dist/APIKeys/api-usage-panel.component.js.map +1 -1
  32. package/dist/APIKeys/index.js.map +1 -1
  33. package/dist/Actions/components/actions-list-view.component.js.map +1 -1
  34. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  35. package/dist/Actions/components/categories-list-view.component.js.map +1 -1
  36. package/dist/Actions/components/code-management.component.js.map +1 -1
  37. package/dist/Actions/components/entity-integration.component.js.map +1 -1
  38. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  39. package/dist/Actions/components/executions-list-view.component.js.map +1 -1
  40. package/dist/Actions/components/explorer/action-breadcrumb.component.js.map +1 -1
  41. package/dist/Actions/components/explorer/action-card.component.js.map +1 -1
  42. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  43. package/dist/Actions/components/explorer/action-list-item.component.js.map +1 -1
  44. package/dist/Actions/components/explorer/action-toolbar.component.js.map +1 -1
  45. package/dist/Actions/components/explorer/action-tree-panel.component.js.map +1 -1
  46. package/dist/Actions/components/explorer/index.js.map +1 -1
  47. package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
  48. package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
  49. package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
  50. package/dist/Actions/components/security-permissions.component.js.map +1 -1
  51. package/dist/Actions/index.js.map +1 -1
  52. package/dist/Actions/services/action-explorer-state.service.js.map +1 -1
  53. package/dist/Communication/communication-dashboard.component.js.map +1 -1
  54. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  55. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  56. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  57. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  58. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  59. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  60. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
  61. package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
  62. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
  63. package/dist/ComponentStudio/components/browser/component-browser.component.js.map +1 -1
  64. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
  65. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
  66. package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
  67. package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
  68. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js.map +1 -1
  69. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
  70. package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
  71. package/dist/ComponentStudio/components/workspace/component-preview.component.js.map +1 -1
  72. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
  73. package/dist/ComponentStudio/index.js.map +1 -1
  74. package/dist/ComponentStudio/services/component-studio-state.service.js.map +1 -1
  75. package/dist/ComponentStudio/services/component-version.service.js.map +1 -1
  76. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  77. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  78. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  79. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  80. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  81. package/dist/Credentials/credentials-dashboard.component.js.map +1 -1
  82. package/dist/Credentials/index.js.map +1 -1
  83. package/dist/Credentials/pipes/group-by.pipe.js.map +1 -1
  84. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  85. package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
  86. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js.map +1 -1
  87. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +25 -3
  88. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
  89. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +158 -34
  90. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
  91. package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +1 -1
  92. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +57 -23
  93. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  94. package/dist/DataExplorer/data-explorer-dashboard.component.js +600 -445
  95. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  96. package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
  97. package/dist/DataExplorer/index.js.map +1 -1
  98. package/dist/DataExplorer/models/explorer-state.interface.d.ts +25 -0
  99. package/dist/DataExplorer/models/explorer-state.interface.d.ts.map +1 -1
  100. package/dist/DataExplorer/models/explorer-state.interface.js +6 -1
  101. package/dist/DataExplorer/models/explorer-state.interface.js.map +1 -1
  102. package/dist/DataExplorer/services/explorer-state.service.d.ts +21 -3
  103. package/dist/DataExplorer/services/explorer-state.service.d.ts.map +1 -1
  104. package/dist/DataExplorer/services/explorer-state.service.js +70 -36
  105. package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
  106. package/dist/EntityAdmin/entity-admin-dashboard.component.js +2 -2
  107. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  108. package/dist/Home/home-application.js.map +1 -1
  109. package/dist/Home/home-dashboard.component.d.ts +20 -5
  110. package/dist/Home/home-dashboard.component.d.ts.map +1 -1
  111. package/dist/Home/home-dashboard.component.js +128 -79
  112. package/dist/Home/home-dashboard.component.js.map +1 -1
  113. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  114. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  115. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  116. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  117. package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
  118. package/dist/Lists/index.js.map +1 -1
  119. package/dist/Lists/services/list-set-operations.service.js.map +1 -1
  120. package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
  121. package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
  122. package/dist/MCP/components/mcp-server-dialog.component.js.map +1 -1
  123. package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
  124. package/dist/MCP/index.js.map +1 -1
  125. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  126. package/dist/MCP/mcp-filter-panel.component.js.map +1 -1
  127. package/dist/MCP/mcp-resource.component.js.map +1 -1
  128. package/dist/MCP/mcp.module.js.map +1 -1
  129. package/dist/MCP/services/mcp-tools.service.js.map +1 -1
  130. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  131. package/dist/Scheduling/components/index.js.map +1 -1
  132. package/dist/Scheduling/components/job-slideout.component.js.map +1 -1
  133. package/dist/Scheduling/components/scheduling-activity-resource.component.js.map +1 -1
  134. package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
  135. package/dist/Scheduling/components/scheduling-jobs-resource.component.js.map +1 -1
  136. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  137. package/dist/Scheduling/components/scheduling-overview-resource.component.js.map +1 -1
  138. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  139. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  140. package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
  141. package/dist/SystemDiagnostics/index.js.map +1 -1
  142. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
  143. package/dist/SystemDiagnostics/system-diagnostics.component.js +3 -3
  144. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  145. package/dist/Testing/components/index.js.map +1 -1
  146. package/dist/Testing/components/testing-analytics-resource.component.js.map +1 -1
  147. package/dist/Testing/components/testing-analytics.component.js.map +1 -1
  148. package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -1
  149. package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
  150. package/dist/Testing/components/testing-explorer-resource.component.js.map +1 -1
  151. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  152. package/dist/Testing/components/testing-review-resource.component.js.map +1 -1
  153. package/dist/Testing/components/testing-review.component.js.map +1 -1
  154. package/dist/Testing/components/testing-runs-resource.component.js.map +1 -1
  155. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  156. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
  157. package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
  158. package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
  159. package/dist/Testing/services/testing-instrumentation.service.js.map +1 -1
  160. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  161. package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
  162. package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
  163. package/dist/VersionHistory/components/index.js.map +1 -1
  164. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  165. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  166. package/dist/VersionHistory/index.js.map +1 -1
  167. package/dist/__tests__/dashboards.test.js.map +1 -1
  168. package/dist/module.js.map +1 -1
  169. package/dist/public-api.js.map +1 -1
  170. package/dist/shared/pipes/highlight-search.pipe.js.map +1 -1
  171. package/dist/shared/pipes/index.js.map +1 -1
  172. package/dist/shared/shared-pipes.module.js.map +1 -1
  173. package/package.json +38 -38
@@ -134,22 +134,19 @@ function HomeDashboardComponent_Conditional_10_Conditional_8_For_8_Template(rf,
134
134
  const _r8 = i0.ɵɵgetCurrentView();
135
135
  i0.ɵɵelementStart(0, "div", 46);
136
136
  i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_10_Conditional_8_For_8_Template_div_click_0_listener() { const notification_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r3 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r3.onNotificationClick(notification_r9)); });
137
- i0.ɵɵelementStart(1, "div", 47);
138
- i0.ɵɵelement(2, "i", 42);
137
+ i0.ɵɵelementStart(1, "div", 47)(2, "span", 48);
138
+ i0.ɵɵtext(3);
139
139
  i0.ɵɵelementEnd();
140
- i0.ɵɵelementStart(3, "div", 48)(4, "span", 49);
140
+ i0.ɵɵelementStart(4, "span", 49);
141
141
  i0.ɵɵtext(5);
142
- i0.ɵɵelementEnd();
143
- i0.ɵɵelementStart(6, "span", 50);
144
- i0.ɵɵtext(7);
145
- i0.ɵɵpipe(8, "slice");
142
+ i0.ɵɵpipe(6, "slice");
146
143
  i0.ɵɵelementEnd()()();
147
144
  } if (rf & 2) {
148
145
  const notification_r9 = ctx.$implicit;
149
- i0.ɵɵadvance(5);
146
+ i0.ɵɵadvance(3);
150
147
  i0.ɵɵtextInterpolate(notification_r9.Title);
151
148
  i0.ɵɵadvance(2);
152
- i0.ɵɵtextInterpolate2("", i0.ɵɵpipeBind3(8, 3, notification_r9.Message, 0, 40), "", ((notification_r9.Message == null ? null : notification_r9.Message.length) || 0) > 40 ? "..." : "");
149
+ i0.ɵɵtextInterpolate2("", i0.ɵɵpipeBind3(6, 3, notification_r9.Message, 0, 40), "", ((notification_r9.Message == null ? null : notification_r9.Message.length) || 0) > 40 ? "..." : "");
153
150
  } }
154
151
  function HomeDashboardComponent_Conditional_10_Conditional_8_Template(rf, ctx) { if (rf & 1) {
155
152
  i0.ɵɵelementStart(0, "div", 37)(1, "h4", 41);
@@ -159,7 +156,7 @@ function HomeDashboardComponent_Conditional_10_Conditional_8_Template(rf, ctx) {
159
156
  i0.ɵɵtext(5);
160
157
  i0.ɵɵelementEnd()();
161
158
  i0.ɵɵelementStart(6, "div", 44);
162
- i0.ɵɵrepeaterCreate(7, HomeDashboardComponent_Conditional_10_Conditional_8_For_8_Template, 9, 7, "div", 45, i0.ɵɵcomponentInstance().trackByNotification, true);
159
+ i0.ɵɵrepeaterCreate(7, HomeDashboardComponent_Conditional_10_Conditional_8_For_8_Template, 7, 7, "div", 45, i0.ɵɵcomponentInstance().trackByNotification, true);
163
160
  i0.ɵɵelementEnd()();
164
161
  } if (rf & 2) {
165
162
  const ctx_r3 = i0.ɵɵnextContext(2);
@@ -170,30 +167,30 @@ function HomeDashboardComponent_Conditional_10_Conditional_8_Template(rf, ctx) {
170
167
  } }
171
168
  function HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
172
169
  const _r10 = i0.ɵɵgetCurrentView();
173
- i0.ɵɵelementStart(0, "div", 54);
170
+ i0.ɵɵelementStart(0, "div", 53);
174
171
  i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_4_For_2_Template_div_click_0_listener() { const favorite_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r3 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r3.onFavoriteClick(favorite_r11)); });
175
- i0.ɵɵelementStart(1, "div", 47);
172
+ i0.ɵɵelementStart(1, "div", 54);
176
173
  i0.ɵɵelement(2, "i");
177
174
  i0.ɵɵelementEnd();
178
- i0.ɵɵelementStart(3, "div", 48)(4, "span", 49);
175
+ i0.ɵɵelementStart(3, "div", 47)(4, "span", 48);
179
176
  i0.ɵɵtext(5);
180
177
  i0.ɵɵelementEnd();
181
- i0.ɵɵelementStart(6, "span", 50);
178
+ i0.ɵɵelementStart(6, "span", 49);
182
179
  i0.ɵɵtext(7);
183
180
  i0.ɵɵelementEnd()()();
184
181
  } if (rf & 2) {
185
182
  const favorite_r11 = ctx.$implicit;
186
183
  const ctx_r3 = i0.ɵɵnextContext(4);
187
184
  i0.ɵɵadvance(2);
188
- i0.ɵɵclassMap(ctx_r3.getFavoriteIcon(favorite_r11));
185
+ i0.ɵɵclassMap(ctx_r3.getEntityIconByName(favorite_r11.Entity));
189
186
  i0.ɵɵadvance(3);
190
- i0.ɵɵtextInterpolate(favorite_r11.RecordID);
187
+ i0.ɵɵtextInterpolate(ctx_r3.getFavoriteDisplayName(favorite_r11));
191
188
  i0.ɵɵadvance(2);
192
189
  i0.ɵɵtextInterpolate(favorite_r11.Entity);
193
190
  } }
194
191
  function HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_4_Template(rf, ctx) { if (rf & 1) {
195
192
  i0.ɵɵelementStart(0, "div", 44);
196
- i0.ɵɵrepeaterCreate(1, HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_4_For_2_Template, 8, 4, "div", 53, i0.ɵɵcomponentInstance().trackByFavorite, true);
193
+ i0.ɵɵrepeaterCreate(1, HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_4_For_2_Template, 8, 4, "div", 52, i0.ɵɵcomponentInstance().trackByFavorite, true);
197
194
  i0.ɵɵelementEnd();
198
195
  } if (rf & 2) {
199
196
  const ctx_r3 = i0.ɵɵnextContext(3);
@@ -201,7 +198,7 @@ function HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_4_Templ
201
198
  i0.ɵɵrepeater(ctx_r3.favorites);
202
199
  } }
203
200
  function HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_5_Template(rf, ctx) { if (rf & 1) {
204
- i0.ɵɵelementStart(0, "div", 52);
201
+ i0.ɵɵelementStart(0, "div", 51);
205
202
  i0.ɵɵelement(1, "i", 55);
206
203
  i0.ɵɵelementStart(2, "span");
207
204
  i0.ɵɵtext(3, "Loading...");
@@ -209,11 +206,11 @@ function HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_5_Templ
209
206
  } }
210
207
  function HomeDashboardComponent_Conditional_10_Conditional_9_Template(rf, ctx) { if (rf & 1) {
211
208
  i0.ɵɵelementStart(0, "div", 38)(1, "h4", 41);
212
- i0.ɵɵelement(2, "i", 51);
209
+ i0.ɵɵelement(2, "i", 50);
213
210
  i0.ɵɵtext(3, " Favorites ");
214
211
  i0.ɵɵelementEnd();
215
212
  i0.ɵɵconditionalCreate(4, HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_4_Template, 3, 0, "div", 44);
216
- i0.ɵɵconditionalCreate(5, HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_5_Template, 4, 0, "div", 52);
213
+ i0.ɵɵconditionalCreate(5, HomeDashboardComponent_Conditional_10_Conditional_9_Conditional_5_Template, 4, 0, "div", 51);
217
214
  i0.ɵɵelementEnd();
218
215
  } if (rf & 2) {
219
216
  const ctx_r3 = i0.ɵɵnextContext(2);
@@ -226,20 +223,20 @@ function HomeDashboardComponent_Conditional_10_Conditional_10_Conditional_4_For_
226
223
  const _r12 = i0.ɵɵgetCurrentView();
227
224
  i0.ɵɵelementStart(0, "div", 58);
228
225
  i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_10_Conditional_10_Conditional_4_For_2_Template_div_click_0_listener() { const item_r13 = i0.ɵɵrestoreView(_r12).$implicit; const ctx_r3 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r3.onRecentClick(item_r13)); });
229
- i0.ɵɵelementStart(1, "div", 47);
226
+ i0.ɵɵelementStart(1, "div", 54);
230
227
  i0.ɵɵelement(2, "i");
231
228
  i0.ɵɵelementEnd();
232
- i0.ɵɵelementStart(3, "div", 48)(4, "span", 49);
229
+ i0.ɵɵelementStart(3, "div", 47)(4, "span", 48);
233
230
  i0.ɵɵtext(5);
234
231
  i0.ɵɵelementEnd();
235
- i0.ɵɵelementStart(6, "span", 50);
232
+ i0.ɵɵelementStart(6, "span", 49);
236
233
  i0.ɵɵtext(7);
237
234
  i0.ɵɵelementEnd()()();
238
235
  } if (rf & 2) {
239
236
  const item_r13 = ctx.$implicit;
240
237
  const ctx_r3 = i0.ɵɵnextContext(4);
241
238
  i0.ɵɵadvance(2);
242
- i0.ɵɵclassMap(ctx_r3.getResourceIcon(item_r13.resourceType));
239
+ i0.ɵɵclassMap(ctx_r3.getEntityIconByName(item_r13.entityName));
243
240
  i0.ɵɵadvance(3);
244
241
  i0.ɵɵtextInterpolate(item_r13.recordName || item_r13.recordId);
245
242
  i0.ɵɵadvance(2);
@@ -255,7 +252,7 @@ function HomeDashboardComponent_Conditional_10_Conditional_10_Conditional_4_Temp
255
252
  i0.ɵɵrepeater(ctx_r3.recentItems);
256
253
  } }
257
254
  function HomeDashboardComponent_Conditional_10_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
258
- i0.ɵɵelementStart(0, "div", 52);
255
+ i0.ɵɵelementStart(0, "div", 51);
259
256
  i0.ɵɵelement(1, "i", 55);
260
257
  i0.ɵɵelementStart(2, "span");
261
258
  i0.ɵɵtext(3, "Loading...");
@@ -267,7 +264,7 @@ function HomeDashboardComponent_Conditional_10_Conditional_10_Template(rf, ctx)
267
264
  i0.ɵɵtext(3, " Recent ");
268
265
  i0.ɵɵelementEnd();
269
266
  i0.ɵɵconditionalCreate(4, HomeDashboardComponent_Conditional_10_Conditional_10_Conditional_4_Template, 3, 0, "div", 44);
270
- i0.ɵɵconditionalCreate(5, HomeDashboardComponent_Conditional_10_Conditional_10_Conditional_5_Template, 4, 0, "div", 52);
267
+ i0.ɵɵconditionalCreate(5, HomeDashboardComponent_Conditional_10_Conditional_10_Conditional_5_Template, 4, 0, "div", 51);
271
268
  i0.ɵɵelementEnd();
272
269
  } if (rf & 2) {
273
270
  const ctx_r3 = i0.ɵɵnextContext(2);
@@ -367,6 +364,8 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
367
364
  // Cached icon lookups to avoid repeated method calls
368
365
  favoriteIconCache = new Map();
369
366
  resourceIconCache = new Map();
367
+ // Resolved display names for favorites (keyed by favorite ID)
368
+ favoriteDisplayNames = new Map();
370
369
  /**
371
370
  * Check if sidebar has any content to show
372
371
  */
@@ -492,7 +491,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
492
491
  this.showConfigDialog = true;
493
492
  setTimeout(() => {
494
493
  if (this.appConfigDialog) {
495
- this.appConfigDialog.open();
494
+ this.appConfigDialog.Open();
496
495
  }
497
496
  }, 0);
498
497
  }
@@ -537,13 +536,15 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
537
536
  return item.Label;
538
537
  }
539
538
  /**
540
- * Load user favorites from UserInfoEngine (cached)
539
+ * Load user favorites from UserInfoEngine (cached) and resolve record display names
541
540
  */
542
541
  async loadFavorites() {
543
542
  try {
544
543
  this.favoritesLoading = true;
545
544
  // Get first 10 favorites (already ordered by __mj_CreatedAt DESC in engine)
546
545
  this.favorites = UserInfoEngine.Instance.UserFavorites.slice(0, 10);
546
+ // Batch-resolve record names for all favorites
547
+ await this.resolveFavoriteNames();
547
548
  }
548
549
  catch (error) {
549
550
  console.error('Error loading favorites:', error);
@@ -553,6 +554,76 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
553
554
  this.cdr.markForCheck();
554
555
  }
555
556
  }
557
+ /**
558
+ * Batch-resolve record display names for favorites using GetEntityRecordNames()
559
+ */
560
+ async resolveFavoriteNames() {
561
+ const nameInputs = [];
562
+ const favoriteIdByKey = new Map(); // map key -> favorite ID
563
+ for (const fav of this.favorites) {
564
+ if (!fav.Entity || !fav.RecordID)
565
+ continue;
566
+ const compositeKey = this.buildCompositeKeyForRecord(fav.Entity, fav.RecordID);
567
+ if (!compositeKey)
568
+ continue;
569
+ nameInputs.push({ EntityName: fav.Entity, CompositeKey: compositeKey });
570
+ favoriteIdByKey.set(`${fav.Entity}||${compositeKey.ToConcatenatedString()}`, fav.ID);
571
+ }
572
+ if (nameInputs.length === 0)
573
+ return;
574
+ try {
575
+ const nameResults = await this.metadata.GetEntityRecordNames(nameInputs);
576
+ for (const result of nameResults) {
577
+ if (result.Success && result.RecordName) {
578
+ const key = `${result.EntityName}||${result.CompositeKey.ToConcatenatedString()}`;
579
+ const favId = favoriteIdByKey.get(key);
580
+ if (favId) {
581
+ this.favoriteDisplayNames.set(favId, result.RecordName);
582
+ }
583
+ }
584
+ }
585
+ }
586
+ catch (error) {
587
+ console.warn('Failed to resolve favorite record names:', error);
588
+ }
589
+ }
590
+ /**
591
+ * Build a CompositeKey for a record. RecordID may be stored as either:
592
+ * - Concatenated format: "FieldName|Value" or "Field1|Val1||Field2|Val2"
593
+ * - Plain value: just the raw value (e.g. a GUID)
594
+ */
595
+ buildCompositeKeyForRecord(entityName, recordId) {
596
+ if (!recordId)
597
+ return null;
598
+ // If recordId contains '|', it's in concatenated format
599
+ if (recordId.includes('|')) {
600
+ try {
601
+ const compositeKey = new CompositeKey();
602
+ compositeKey.LoadFromConcatenatedString(recordId);
603
+ if (compositeKey.KeyValuePairs.length > 0)
604
+ return compositeKey;
605
+ }
606
+ catch {
607
+ // Fall through to entity-based lookup
608
+ }
609
+ }
610
+ // Plain value — look up entity primary key field(s) to construct the key
611
+ const entityInfo = this.metadata.Entities.find(e => e.Name === entityName);
612
+ if (!entityInfo)
613
+ return null;
614
+ const pkField = entityInfo.FirstPrimaryKey;
615
+ if (!pkField)
616
+ return null;
617
+ const compositeKey = new CompositeKey();
618
+ compositeKey.KeyValuePairs = [{ FieldName: pkField.Name, Value: recordId }];
619
+ return compositeKey;
620
+ }
621
+ /**
622
+ * Get the display name for a favorite (resolved name or entity name fallback)
623
+ */
624
+ getFavoriteDisplayName(favorite) {
625
+ return this.favoriteDisplayNames.get(favorite.ID) || favorite.Entity || favorite.RecordID;
626
+ }
556
627
  /**
557
628
  * Load recent items via the RecentAccessService
558
629
  */
@@ -630,59 +701,37 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
630
701
  this.navigationService.OpenDynamicView('MJ: User Notifications');
631
702
  }
632
703
  /**
633
- * Get icon for a resource type (cached)
704
+ * Get icon for an entity by name, using entity metadata Icon field (cached)
634
705
  */
635
- getResourceIcon(resourceType) {
636
- if (this.resourceIconCache.has(resourceType)) {
637
- return this.resourceIconCache.get(resourceType);
638
- }
639
- let icon;
640
- switch (resourceType) {
641
- case 'view':
642
- icon = 'fa-solid fa-table';
643
- break;
644
- case 'dashboard':
645
- icon = 'fa-solid fa-gauge-high';
646
- break;
647
- case 'artifact':
648
- icon = 'fa-solid fa-cube';
649
- break;
650
- case 'report':
651
- icon = 'fa-solid fa-chart-bar';
652
- break;
653
- default:
654
- icon = 'fa-solid fa-file';
655
- }
656
- this.resourceIconCache.set(resourceType, icon);
706
+ getEntityIconByName(entityName) {
707
+ if (!entityName)
708
+ return 'fa-solid fa-file';
709
+ const cached = this.resourceIconCache.get(entityName);
710
+ if (cached)
711
+ return cached;
712
+ const entityInfo = this.metadata.Entities.find(e => e.Name === entityName);
713
+ const icon = entityInfo ? this.resolveEntityIcon(entityInfo.Icon) : 'fa-solid fa-file';
714
+ this.resourceIconCache.set(entityName, icon);
657
715
  return icon;
658
716
  }
659
717
  /**
660
- * Get icon for a favorite based on its entity type (cached)
718
+ * Resolve an entity's Icon field to a full Font Awesome class string
661
719
  */
662
- getFavoriteIcon(favorite) {
663
- const cacheKey = favorite.ID;
664
- if (this.favoriteIconCache.has(cacheKey)) {
665
- return this.favoriteIconCache.get(cacheKey);
720
+ resolveEntityIcon(icon) {
721
+ if (!icon)
722
+ return 'fa-solid fa-table';
723
+ // Already has a style prefix
724
+ if (icon.startsWith('fa-solid') || icon.startsWith('fa-regular') ||
725
+ icon.startsWith('fa-light') || icon.startsWith('fa-brands') ||
726
+ icon.startsWith('fa ')) {
727
+ return icon;
666
728
  }
667
- let icon;
668
- const entityName = favorite.Entity?.toLowerCase();
669
- if (entityName === 'dashboards') {
670
- icon = 'fa-solid fa-gauge-high';
671
- }
672
- else if (entityName === 'user views') {
673
- icon = 'fa-solid fa-table';
674
- }
675
- else if (entityName === 'reports') {
676
- icon = 'fa-solid fa-chart-bar';
729
+ // Has fa- prefix but no style
730
+ if (icon.startsWith('fa-')) {
731
+ return `fa-solid ${icon}`;
677
732
  }
678
- else if (entityName?.includes('artifact')) {
679
- icon = 'fa-solid fa-cube';
680
- }
681
- else {
682
- icon = 'fa-solid fa-star';
683
- }
684
- this.favoriteIconCache.set(cacheKey, icon);
685
- return icon;
733
+ // Just an icon name like "table" or "users"
734
+ return `fa-solid fa-${icon}`;
686
735
  }
687
736
  /**
688
737
  * Format a date for display (pure function, safe to call in template)
@@ -739,7 +788,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
739
788
  } if (rf & 2) {
740
789
  let _t;
741
790
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.appConfigDialog = _t.first);
742
- } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 14, vars: 10, consts: [["appConfigDialog", ""], [1, "home-dashboard"], [1, "main-content"], [1, "home-header"], [1, "greeting-section"], [1, "date"], [1, "loading-container"], [1, "apps-section"], [1, "quick-access-sidebar"], ["title", "Quick Access", 1, "sidebar-fab-toggle"], [3, "showDialogChange", "configSaved", "showDialog"], ["text", "Loading your applications...", "size", "large"], [1, "section-title"], [1, "fa-solid", "fa-grid-2"], [1, "apps-grid"], [1, "app-card", 3, "--app-color"], [1, "empty-state"], [1, "app-card", 3, "click"], [1, "app-icon-wrapper"], [1, "app-icon"], [1, "app-info"], [1, "app-name"], [1, "app-description"], [1, "nav-preview"], [1, "app-arrow"], [1, "fa-solid", "fa-arrow-right"], [1, "nav-item-chip"], [1, "more-items"], [1, "empty-icon"], [1, "fa-solid", "fa-folder-open"], ["kendoButton", "", "themeColor", "primary", 3, "click"], [1, "fa-solid", "fa-gear"], [1, "sidebar-header"], [1, "fa-solid", "fa-bolt"], ["title", "Close panel", 1, "sidebar-close-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "sidebar-content"], [1, "sidebar-section", "notifications-section"], [1, "sidebar-section", "favorites-section"], [1, "sidebar-section", "recents-section"], [1, "sidebar-empty"], [1, "sidebar-section-title"], [1, "fa-solid", "fa-bell"], [1, "section-badge"], [1, "sidebar-items"], [1, "sidebar-item", "notification-item"], [1, "sidebar-item", "notification-item", 3, "click"], [1, "sidebar-item-icon"], [1, "sidebar-item-info"], [1, "sidebar-item-title"], [1, "sidebar-item-subtitle"], [1, "fa-solid", "fa-star"], [1, "sidebar-loading"], [1, "sidebar-item", "favorite-item"], [1, "sidebar-item", "favorite-item", 3, "click"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "sidebar-item", "recent-item"], [1, "sidebar-item", "recent-item", 3, "click"], [1, "fa-solid", "fa-inbox"], ["title", "Quick Access", 1, "sidebar-fab-toggle", 3, "click"], [1, "fab-badge"]], template: function HomeDashboardComponent_Template(rf, ctx) { if (rf & 1) {
791
+ } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 14, vars: 10, consts: [["appConfigDialog", ""], [1, "home-dashboard"], [1, "main-content"], [1, "home-header"], [1, "greeting-section"], [1, "date"], [1, "loading-container"], [1, "apps-section"], [1, "quick-access-sidebar"], ["title", "Quick Access", 1, "sidebar-fab-toggle"], [3, "ShowDialogChange", "ConfigSaved", "ShowDialog"], ["text", "Loading your applications...", "size", "large"], [1, "section-title"], [1, "fa-solid", "fa-grid-2"], [1, "apps-grid"], [1, "app-card", 3, "--app-color"], [1, "empty-state"], [1, "app-card", 3, "click"], [1, "app-icon-wrapper"], [1, "app-icon"], [1, "app-info"], [1, "app-name"], [1, "app-description"], [1, "nav-preview"], [1, "app-arrow"], [1, "fa-solid", "fa-arrow-right"], [1, "nav-item-chip"], [1, "more-items"], [1, "empty-icon"], [1, "fa-solid", "fa-folder-open"], ["kendoButton", "", "themeColor", "primary", 3, "click"], [1, "fa-solid", "fa-gear"], [1, "sidebar-header"], [1, "fa-solid", "fa-bolt"], ["title", "Close panel", 1, "sidebar-close-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "sidebar-content"], [1, "sidebar-section", "notifications-section"], [1, "sidebar-section", "favorites-section"], [1, "sidebar-section", "recents-section"], [1, "sidebar-empty"], [1, "sidebar-section-title"], [1, "fa-solid", "fa-bell"], [1, "section-badge"], [1, "sidebar-items"], [1, "sidebar-item", "notification-item"], [1, "sidebar-item", "notification-item", 3, "click"], [1, "sidebar-item-info"], [1, "sidebar-item-title"], [1, "sidebar-item-subtitle"], [1, "fa-solid", "fa-star"], [1, "sidebar-loading"], [1, "sidebar-item", "favorite-item"], [1, "sidebar-item", "favorite-item", 3, "click"], [1, "sidebar-item-icon"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "sidebar-item", "recent-item"], [1, "sidebar-item", "recent-item", 3, "click"], [1, "fa-solid", "fa-inbox"], ["title", "Quick Access", 1, "sidebar-fab-toggle", 3, "click"], [1, "fab-badge"]], template: function HomeDashboardComponent_Template(rf, ctx) { if (rf & 1) {
743
792
  const _r1 = i0.ɵɵgetCurrentView();
744
793
  i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "div", 3)(3, "div", 4)(4, "h1");
745
794
  i0.ɵɵtext(5);
@@ -753,8 +802,8 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
753
802
  i0.ɵɵconditionalCreate(10, HomeDashboardComponent_Conditional_10_Template, 12, 4, "div", 8);
754
803
  i0.ɵɵconditionalCreate(11, HomeDashboardComponent_Conditional_11_Template, 3, 1, "button", 9);
755
804
  i0.ɵɵelementStart(12, "mj-user-app-config", 10, 0);
756
- i0.ɵɵtwoWayListener("showDialogChange", function HomeDashboardComponent_Template_mj_user_app_config_showDialogChange_12_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.showConfigDialog, $event) || (ctx.showConfigDialog = $event); return i0.ɵɵresetView($event); });
757
- i0.ɵɵlistener("configSaved", function HomeDashboardComponent_Template_mj_user_app_config_configSaved_12_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onConfigSaved()); });
805
+ i0.ɵɵtwoWayListener("ShowDialogChange", function HomeDashboardComponent_Template_mj_user_app_config_ShowDialogChange_12_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.showConfigDialog, $event) || (ctx.showConfigDialog = $event); return i0.ɵɵresetView($event); });
806
+ i0.ɵɵlistener("ConfigSaved", function HomeDashboardComponent_Template_mj_user_app_config_ConfigSaved_12_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onConfigSaved()); });
758
807
  i0.ɵɵelementEnd()();
759
808
  } if (rf & 2) {
760
809
  i0.ɵɵclassProp("sidebar-open", ctx.sidebarOpen && ctx.hasSidebarContent);
@@ -771,7 +820,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
771
820
  i0.ɵɵadvance();
772
821
  i0.ɵɵconditional(ctx.hasSidebarContent && !ctx.sidebarOpen ? 11 : -1);
773
822
  i0.ɵɵadvance();
774
- i0.ɵɵtwoWayProperty("showDialog", ctx.showConfigDialog);
823
+ i0.ɵɵtwoWayProperty("ShowDialog", ctx.showConfigDialog);
775
824
  } }, dependencies: [i3.ButtonComponent, i4.UserAppConfigComponent, i5.LoadingComponent, i6.SlicePipe], styles: [".home-dashboard[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\n overflow: hidden;\n position: relative;\n}\n\n\n\n.main-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right 0.3s ease;\n}\n\n\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 320px;\n}\n\n\n\n.home-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 32px;\n font-weight: 600;\n color: #212529;\n}\n\n.greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n color: #6c757d;\n}\n\n\n\n.sidebar-fab-toggle[_ngcontent-%COMP%] {\n position: fixed;\n top: 80px; \n\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: 50%;\n background: #1976d2;\n color: white;\n font-size: 20px;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(25, 118, 210, 0.4);\n transition: all 0.2s ease;\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle[_ngcontent-%COMP%]:hover {\n background: #1565c0;\n transform: scale(1.05);\n box-shadow: 0 6px 16px rgba(25, 118, 210, 0.5);\n}\n\n.fab-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: #e53935;\n color: white;\n font-size: 11px;\n font-weight: 600;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: #6c757d;\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #1976d2;\n}\n\n\n\n.apps-section[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: 20px;\n font-weight: 600;\n color: #495057;\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6c757d;\n}\n\n\n\n.apps-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n\n\n.app-card[_ngcontent-%COMP%] {\n --app-color: #757575;\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: white;\n border-radius: 14px;\n border: 1px solid #e9ecef;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover {\n border-color: var(--app-color);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);\n transform: translateY(-3px);\n}\n\n.app-card[_ngcontent-%COMP%]:hover::before {\n opacity: 1;\n}\n\n\n\n.app-icon-wrapper[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.app-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 22px;\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-icon[_ngcontent-%COMP%] {\n background: var(--app-color);\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: white;\n transform: scale(1.1);\n}\n\n\n\n.app-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.app-name[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 17px;\n font-weight: 600;\n color: #212529;\n}\n\n.app-description[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n font-size: 13px;\n color: #6c757d;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n\n\n.nav-preview[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: #f8f9fa;\n border-radius: 5px;\n font-size: 11px;\n color: #495057;\n}\n\n.nav-item-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n color: #6c757d;\n}\n\n.more-items[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #6c757d;\n font-style: italic;\n}\n\n\n\n.app-arrow[_ngcontent-%COMP%] {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: 16px;\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-arrow[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n background: white;\n border-radius: 16px;\n border: 2px dashed #dee2e6;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: #f8f9fa;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #adb5bd;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #495057;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #6c757d;\n max-width: 400px;\n}\n\n.empty-state[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n\n\n\n\n.quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 320px;\n background: white;\n border-left: 1px solid #e9ecef;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s ease;\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.08);\n}\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .quick-access-sidebar[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.sidebar-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid #e9ecef;\n background: #fafbfc;\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #212529;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n font-size: 14px;\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: #6c757d;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%]:hover {\n background: #f1f3f4;\n color: #212529;\n}\n\n.sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n\n\n.sidebar-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.sidebar-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.notifications-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f57c00;\n}\n\n.favorites-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #ffc107;\n}\n\n.recents-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n}\n\n.section-badge[_ngcontent-%COMP%] {\n background: #e53935;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 8px;\n margin-left: auto;\n}\n\n\n\n.sidebar-items[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: #f8f9fa;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sidebar-item[_ngcontent-%COMP%]:hover {\n background: #e9ecef;\n transform: translateX(4px);\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: white;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #6c757d;\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: #fff3e0;\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f57c00;\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: #fff8e1;\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f9a825;\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: #e3f2fd;\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n}\n\n.sidebar-item-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: #212529;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #6c757d;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #6c757d;\n font-size: 13px;\n padding: 8px 0;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: #adb5bd;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n}\n\n\n\n\n\n\n\n\n\n@media (max-width: 1200px) {\n .quick-access-sidebar[_ngcontent-%COMP%] {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 280px;\n }\n\n .apps-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n\n\n@media (max-width: 992px) {\n .main-content[_ngcontent-%COMP%] {\n padding: 24px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 28px;\n }\n\n \n\n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 0;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 320px;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 999;\n }\n}\n\n\n\n@media (max-width: 768px) {\n .home-dashboard[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 20px;\n padding-bottom: 100px; \n\n overflow: visible;\n }\n\n .home-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 24px;\n }\n\n \n\n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 100; \n\n border-left: none;\n border-top: 1px solid #e9ecef;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::before {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 99;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n display: none;\n }\n\n .apps-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .app-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n }\n\n .app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .app-name[_ngcontent-%COMP%] {\n font-size: 15px;\n }\n\n .nav-preview[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: 18px;\n }\n}\n\n@media (max-width: 480px) {\n .main-content[_ngcontent-%COMP%] {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .section-title[_ngcontent-%COMP%] {\n font-size: 16px;\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: 16px;\n }\n}"], changeDetection: 0 });
776
825
  };
777
826
  HomeDashboardComponent = __decorate([
@@ -780,7 +829,7 @@ HomeDashboardComponent = __decorate([
780
829
  export { HomeDashboardComponent };
781
830
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HomeDashboardComponent, [{
782
831
  type: Component,
783
- args: [{ standalone: false, selector: 'mj-home-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"home-dashboard\" [class.sidebar-open]=\"sidebarOpen && hasSidebarContent\">\n <!-- Main Content Area -->\n <div class=\"main-content\">\n <!-- Header Section -->\n <div class=\"home-header\">\n <div class=\"greeting-section\">\n <h1>{{ greeting }}, {{ currentUser?.Name }}</h1>\n <p class=\"date\">{{ formattedDate }}</p>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading your applications...\" size=\"large\"></mj-loading>\n </div>\n }\n\n <!-- Apps Grid -->\n @if (!isLoading) {\n <div class=\"apps-section\">\n <h2 class=\"section-title\">\n <i class=\"fa-solid fa-grid-2\"></i>\n Your Applications\n </h2>\n <div class=\"apps-grid\">\n @for (appData of appsDisplayData; track trackByApp($index, appData)) {\n <div\n class=\"app-card\"\n [style.--app-color]=\"appData.color\"\n (click)=\"onAppClick(appData.app)\">\n <!-- App Icon -->\n <div class=\"app-icon-wrapper\">\n <div class=\"app-icon\">\n <i [class]=\"appData.icon\"></i>\n </div>\n </div>\n <!-- App Info -->\n <div class=\"app-info\">\n <h3 class=\"app-name\">{{ appData.app.Name }}</h3>\n @if (appData.app.Description) {\n <p class=\"app-description\">{{ appData.app.Description }}</p>\n }\n <!-- Nav Items Preview -->\n @if (appData.navItemsCount > 0) {\n <div class=\"nav-preview\">\n @for (item of appData.navItemsPreview; track trackByNavItem($index, item)) {\n <div class=\"nav-item-chip\">\n <i [class]=\"item.Icon\"></i>\n <span>{{ item.Label }}</span>\n </div>\n }\n @if (appData.showMoreItems) {\n <span class=\"more-items\">\n +{{ appData.moreItemsCount }} more\n </span>\n }\n </div>\n }\n </div>\n <!-- Hover Arrow -->\n <div class=\"app-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n <!-- Empty State -->\n @if (apps.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-folder-open\"></i>\n </div>\n <h3>No Applications Available</h3>\n <p>You don't have any applications configured yet.</p>\n <button kendoButton\n themeColor=\"primary\"\n (click)=\"openConfigDialog()\">\n <i class=\"fa-solid fa-gear\"></i>\n Configure Applications\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Collapsible Right Sidebar -->\n @if (hasSidebarContent) {\n <div class=\"quick-access-sidebar\">\n <div class=\"sidebar-header\">\n <h3>\n <i class=\"fa-solid fa-bolt\"></i>\n Quick Access\n </h3>\n <button class=\"sidebar-close-btn\" (click)=\"toggleSidebar()\" title=\"Close panel\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"sidebar-content\">\n <!-- Unread Notifications Section -->\n @if (unreadNotifications.length > 0) {\n <div class=\"sidebar-section notifications-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-bell\"></i>\n Notifications\n <span class=\"section-badge\">{{ unreadNotifications.length }}</span>\n </h4>\n <div class=\"sidebar-items\">\n @for (notification of unreadNotifications; track trackByNotification($index, notification)) {\n <div\n class=\"sidebar-item notification-item\"\n (click)=\"onNotificationClick(notification)\">\n <div class=\"sidebar-item-icon\">\n <i class=\"fa-solid fa-bell\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ notification.Title }}</span>\n <span class=\"sidebar-item-subtitle\">{{ notification.Message | slice:0:40 }}{{ (notification.Message?.length || 0) > 40 ? '...' : '' }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Favorites Section -->\n @if (favorites.length > 0 || favoritesLoading) {\n <div class=\"sidebar-section favorites-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-star\"></i>\n Favorites\n </h4>\n @if (!favoritesLoading) {\n <div class=\"sidebar-items\">\n @for (favorite of favorites; track trackByFavorite($index, favorite)) {\n <div\n class=\"sidebar-item favorite-item\"\n (click)=\"onFavoriteClick(favorite)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getFavoriteIcon(favorite)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ favorite.RecordID }}</span>\n <span class=\"sidebar-item-subtitle\">{{ favorite.Entity }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (favoritesLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Recents Section -->\n @if (recentItems.length > 0 || recentsLoading) {\n <div class=\"sidebar-section recents-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Recent\n </h4>\n @if (!recentsLoading) {\n <div class=\"sidebar-items\">\n @for (item of recentItems; track trackByRecent($index, item)) {\n <div\n class=\"sidebar-item recent-item\"\n (click)=\"onRecentClick(item)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getResourceIcon(item.resourceType)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ item.recordName || item.recordId }}</span>\n <span class=\"sidebar-item-subtitle\">{{ item.entityName }} \u00B7 {{ formatDate(item.latestAt) }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (recentsLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Empty sidebar state -->\n @if (!favoritesLoading && !recentsLoading && unreadNotifications.length === 0 && favorites.length === 0 && recentItems.length === 0) {\n <div class=\"sidebar-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No quick access items</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Quick Access FAB Toggle (Fixed Button) -->\n @if (hasSidebarContent && !sidebarOpen) {\n <button class=\"sidebar-fab-toggle\"\n (click)=\"toggleSidebar()\"\n title=\"Quick Access\">\n <i class=\"fa-solid fa-bolt\"></i>\n @if (unreadNotifications.length > 0) {\n <span class=\"fab-badge\">{{ unreadNotifications.length }}</span>\n }\n </button>\n }\n\n <!-- App Configuration Dialog -->\n <mj-user-app-config\n #appConfigDialog\n [(showDialog)]=\"showConfigDialog\"\n (configSaved)=\"onConfigSaved()\">\n </mj-user-app-config>\n</div>\n", styles: [".home-dashboard {\n display: flex;\n height: 100%;\n background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\n overflow: hidden;\n position: relative;\n}\n\n/* Main Content Area */\n.main-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right 0.3s ease;\n}\n\n/* Sidebar open state adjusts main content on desktop */\n.home-dashboard.sidebar-open .main-content {\n margin-right: 320px;\n}\n\n/* Header */\n.home-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section h1 {\n margin: 0 0 8px 0;\n font-size: 32px;\n font-weight: 600;\n color: #212529;\n}\n\n.greeting-section .date {\n margin: 0;\n font-size: 16px;\n color: #6c757d;\n}\n\n/* FAB Toggle Button for Quick Access - top-right on desktop */\n.sidebar-fab-toggle {\n position: fixed;\n top: 80px; /* Below shell header with some spacing */\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: 50%;\n background: #1976d2;\n color: white;\n font-size: 20px;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(25, 118, 210, 0.4);\n transition: all 0.2s ease;\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle:hover {\n background: #1565c0;\n transform: scale(1.05);\n box-shadow: 0 6px 16px rgba(25, 118, 210, 0.5);\n}\n\n.fab-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: #e53935;\n color: white;\n font-size: 11px;\n font-weight: 600;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: #6c757d;\n}\n\n.loading-spinner {\n font-size: 32px;\n color: #1976d2;\n}\n\n/* Apps Section */\n.apps-section {\n flex: 0 0 auto;\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: 20px;\n font-weight: 600;\n color: #495057;\n}\n\n.section-title i {\n color: #6c757d;\n}\n\n/* Apps Grid */\n.apps-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n/* App Card */\n.app-card {\n --app-color: #757575;\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: white;\n border-radius: 14px;\n border: 1px solid #e9ecef;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card:hover {\n border-color: var(--app-color);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);\n transform: translateY(-3px);\n}\n\n.app-card:hover::before {\n opacity: 1;\n}\n\n/* App Icon */\n.app-icon-wrapper {\n flex-shrink: 0;\n}\n\n.app-icon {\n width: 52px;\n height: 52px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon i {\n font-size: 22px;\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card:hover .app-icon {\n background: var(--app-color);\n}\n\n.app-card:hover .app-icon i {\n color: white;\n transform: scale(1.1);\n}\n\n/* App Info */\n.app-info {\n flex: 1;\n min-width: 0;\n}\n\n.app-name {\n margin: 0 0 4px 0;\n font-size: 17px;\n font-weight: 600;\n color: #212529;\n}\n\n.app-description {\n margin: 0 0 10px 0;\n font-size: 13px;\n color: #6c757d;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Nav Items Preview */\n.nav-preview {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: #f8f9fa;\n border-radius: 5px;\n font-size: 11px;\n color: #495057;\n}\n\n.nav-item-chip i {\n font-size: 9px;\n color: #6c757d;\n}\n\n.more-items {\n font-size: 11px;\n color: #6c757d;\n font-style: italic;\n}\n\n/* App Arrow */\n.app-arrow {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: 16px;\n}\n\n.app-card:hover .app-arrow {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n background: white;\n border-radius: 16px;\n border: 2px dashed #dee2e6;\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: #f8f9fa;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon i {\n font-size: 32px;\n color: #adb5bd;\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #495057;\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #6c757d;\n max-width: 400px;\n}\n\n.empty-state button i {\n margin-right: 8px;\n}\n\n/* ========================================\n RIGHT SIDEBAR\n ======================================== */\n.quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below shell header */\n right: 0;\n bottom: 0;\n width: 320px;\n background: white;\n border-left: 1px solid #e9ecef;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s ease;\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.08);\n}\n\n.home-dashboard.sidebar-open .quick-access-sidebar {\n transform: translateX(0);\n}\n\n.sidebar-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid #e9ecef;\n background: #fafbfc;\n}\n\n.sidebar-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #212529;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header h3 i {\n color: #1976d2;\n font-size: 14px;\n}\n\n.sidebar-close-btn {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: #6c757d;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.sidebar-close-btn:hover {\n background: #f1f3f4;\n color: #212529;\n}\n\n.sidebar-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n/* Sidebar Sections */\n.sidebar-section {\n margin-bottom: 20px;\n}\n\n.sidebar-section:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title i {\n font-size: 12px;\n}\n\n.notifications-section .sidebar-section-title i {\n color: #f57c00;\n}\n\n.favorites-section .sidebar-section-title i {\n color: #ffc107;\n}\n\n.recents-section .sidebar-section-title i {\n color: #1976d2;\n}\n\n.section-badge {\n background: #e53935;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 8px;\n margin-left: auto;\n}\n\n/* Sidebar Items */\n.sidebar-items {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: #f8f9fa;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sidebar-item:hover {\n background: #e9ecef;\n transform: translateX(4px);\n}\n\n.sidebar-item-icon {\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: white;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon i {\n font-size: 14px;\n color: #6c757d;\n}\n\n.notification-item .sidebar-item-icon {\n background: #fff3e0;\n}\n\n.notification-item .sidebar-item-icon i {\n color: #f57c00;\n}\n\n.favorite-item .sidebar-item-icon {\n background: #fff8e1;\n}\n\n.favorite-item .sidebar-item-icon i {\n color: #f9a825;\n}\n\n.recent-item .sidebar-item-icon {\n background: #e3f2fd;\n}\n\n.recent-item .sidebar-item-icon i {\n color: #1976d2;\n}\n\n.sidebar-item-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title {\n font-size: 13px;\n font-weight: 500;\n color: #212529;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle {\n font-size: 11px;\n color: #6c757d;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #6c757d;\n font-size: 13px;\n padding: 8px 0;\n}\n\n.sidebar-loading i {\n color: #1976d2;\n}\n\n.sidebar-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: #adb5bd;\n}\n\n.sidebar-empty i {\n font-size: 32px;\n margin-bottom: 12px;\n}\n\n.sidebar-empty p {\n margin: 0;\n font-size: 13px;\n}\n\n\n/* ========================================\n RESPONSIVE DESIGN\n ======================================== */\n\n/* Tablet and smaller desktop */\n@media (max-width: 1200px) {\n .quick-access-sidebar {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 280px;\n }\n\n .apps-grid {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n/* Tablet */\n@media (max-width: 992px) {\n .main-content {\n padding: 24px;\n }\n\n .greeting-section h1 {\n font-size: 28px;\n }\n\n /* Make sidebar an overlay on tablet */\n .quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below shell header */\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 0;\n }\n\n /* Show backdrop when sidebar is open on tablet */\n .home-dashboard.sidebar-open::after {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 320px;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 999;\n }\n}\n\n/* Mobile */\n@media (max-width: 768px) {\n .home-dashboard {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content {\n padding: 20px;\n padding-bottom: 100px; /* Space for FAB button */\n overflow: visible;\n }\n\n .home-header {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section h1 {\n font-size: 24px;\n }\n\n /* Full-width sidebar on mobile - positioned below top nav */\n .quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below the shell header */\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 100; /* Below shell header */\n border-left: none;\n border-top: 1px solid #e9ecef;\n }\n\n /* Add backdrop on mobile when sidebar is open */\n .home-dashboard.sidebar-open::before {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 99;\n }\n\n /* No ::after backdrop needed on mobile */\n .home-dashboard.sidebar-open::after {\n display: none;\n }\n\n .apps-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card {\n padding: 16px;\n }\n\n .app-icon {\n width: 44px;\n height: 44px;\n }\n\n .app-icon i {\n font-size: 18px;\n }\n\n .app-name {\n font-size: 15px;\n }\n\n .nav-preview {\n display: none;\n }\n\n /* Move FAB to bottom-right on mobile */\n .sidebar-fab-toggle {\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: 18px;\n }\n}\n\n@media (max-width: 480px) {\n .main-content {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section h1 {\n font-size: 20px;\n }\n\n .greeting-section .date {\n font-size: 14px;\n }\n\n .section-title {\n font-size: 16px;\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: 16px;\n }\n}\n"] }]
832
+ args: [{ standalone: false, selector: 'mj-home-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"home-dashboard\" [class.sidebar-open]=\"sidebarOpen && hasSidebarContent\">\n <!-- Main Content Area -->\n <div class=\"main-content\">\n <!-- Header Section -->\n <div class=\"home-header\">\n <div class=\"greeting-section\">\n <h1>{{ greeting }}, {{ currentUser?.Name }}</h1>\n <p class=\"date\">{{ formattedDate }}</p>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading your applications...\" size=\"large\"></mj-loading>\n </div>\n }\n\n <!-- Apps Grid -->\n @if (!isLoading) {\n <div class=\"apps-section\">\n <h2 class=\"section-title\">\n <i class=\"fa-solid fa-grid-2\"></i>\n Your Applications\n </h2>\n <div class=\"apps-grid\">\n @for (appData of appsDisplayData; track trackByApp($index, appData)) {\n <div\n class=\"app-card\"\n [style.--app-color]=\"appData.color\"\n (click)=\"onAppClick(appData.app)\">\n <!-- App Icon -->\n <div class=\"app-icon-wrapper\">\n <div class=\"app-icon\">\n <i [class]=\"appData.icon\"></i>\n </div>\n </div>\n <!-- App Info -->\n <div class=\"app-info\">\n <h3 class=\"app-name\">{{ appData.app.Name }}</h3>\n @if (appData.app.Description) {\n <p class=\"app-description\">{{ appData.app.Description }}</p>\n }\n <!-- Nav Items Preview -->\n @if (appData.navItemsCount > 0) {\n <div class=\"nav-preview\">\n @for (item of appData.navItemsPreview; track trackByNavItem($index, item)) {\n <div class=\"nav-item-chip\">\n <i [class]=\"item.Icon\"></i>\n <span>{{ item.Label }}</span>\n </div>\n }\n @if (appData.showMoreItems) {\n <span class=\"more-items\">\n +{{ appData.moreItemsCount }} more\n </span>\n }\n </div>\n }\n </div>\n <!-- Hover Arrow -->\n <div class=\"app-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n <!-- Empty State -->\n @if (apps.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-folder-open\"></i>\n </div>\n <h3>No Applications Available</h3>\n <p>You don't have any applications configured yet.</p>\n <button kendoButton\n themeColor=\"primary\"\n (click)=\"openConfigDialog()\">\n <i class=\"fa-solid fa-gear\"></i>\n Configure Applications\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Collapsible Right Sidebar -->\n @if (hasSidebarContent) {\n <div class=\"quick-access-sidebar\">\n <div class=\"sidebar-header\">\n <h3>\n <i class=\"fa-solid fa-bolt\"></i>\n Quick Access\n </h3>\n <button class=\"sidebar-close-btn\" (click)=\"toggleSidebar()\" title=\"Close panel\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"sidebar-content\">\n <!-- Unread Notifications Section -->\n @if (unreadNotifications.length > 0) {\n <div class=\"sidebar-section notifications-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-bell\"></i>\n Notifications\n <span class=\"section-badge\">{{ unreadNotifications.length }}</span>\n </h4>\n <div class=\"sidebar-items\">\n @for (notification of unreadNotifications; track trackByNotification($index, notification)) {\n <div\n class=\"sidebar-item notification-item\"\n (click)=\"onNotificationClick(notification)\">\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ notification.Title }}</span>\n <span class=\"sidebar-item-subtitle\">{{ notification.Message | slice:0:40 }}{{ (notification.Message?.length || 0) > 40 ? '...' : '' }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Favorites Section -->\n @if (favorites.length > 0 || favoritesLoading) {\n <div class=\"sidebar-section favorites-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-star\"></i>\n Favorites\n </h4>\n @if (!favoritesLoading) {\n <div class=\"sidebar-items\">\n @for (favorite of favorites; track trackByFavorite($index, favorite)) {\n <div\n class=\"sidebar-item favorite-item\"\n (click)=\"onFavoriteClick(favorite)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getEntityIconByName(favorite.Entity)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ getFavoriteDisplayName(favorite) }}</span>\n <span class=\"sidebar-item-subtitle\">{{ favorite.Entity }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (favoritesLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Recents Section -->\n @if (recentItems.length > 0 || recentsLoading) {\n <div class=\"sidebar-section recents-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Recent\n </h4>\n @if (!recentsLoading) {\n <div class=\"sidebar-items\">\n @for (item of recentItems; track trackByRecent($index, item)) {\n <div\n class=\"sidebar-item recent-item\"\n (click)=\"onRecentClick(item)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getEntityIconByName(item.entityName)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ item.recordName || item.recordId }}</span>\n <span class=\"sidebar-item-subtitle\">{{ item.entityName }} \u00B7 {{ formatDate(item.latestAt) }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (recentsLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Empty sidebar state -->\n @if (!favoritesLoading && !recentsLoading && unreadNotifications.length === 0 && favorites.length === 0 && recentItems.length === 0) {\n <div class=\"sidebar-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No quick access items</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Quick Access FAB Toggle (Fixed Button) -->\n @if (hasSidebarContent && !sidebarOpen) {\n <button class=\"sidebar-fab-toggle\"\n (click)=\"toggleSidebar()\"\n title=\"Quick Access\">\n <i class=\"fa-solid fa-bolt\"></i>\n @if (unreadNotifications.length > 0) {\n <span class=\"fab-badge\">{{ unreadNotifications.length }}</span>\n }\n </button>\n }\n\n <!-- App Configuration Dialog -->\n <mj-user-app-config\n #appConfigDialog\n [(ShowDialog)]=\"showConfigDialog\"\n (ConfigSaved)=\"onConfigSaved()\">\n </mj-user-app-config>\n</div>\n", styles: [".home-dashboard {\n display: flex;\n height: 100%;\n background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\n overflow: hidden;\n position: relative;\n}\n\n/* Main Content Area */\n.main-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right 0.3s ease;\n}\n\n/* Sidebar open state adjusts main content on desktop */\n.home-dashboard.sidebar-open .main-content {\n margin-right: 320px;\n}\n\n/* Header */\n.home-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section h1 {\n margin: 0 0 8px 0;\n font-size: 32px;\n font-weight: 600;\n color: #212529;\n}\n\n.greeting-section .date {\n margin: 0;\n font-size: 16px;\n color: #6c757d;\n}\n\n/* FAB Toggle Button for Quick Access - top-right on desktop */\n.sidebar-fab-toggle {\n position: fixed;\n top: 80px; /* Below shell header with some spacing */\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: 50%;\n background: #1976d2;\n color: white;\n font-size: 20px;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(25, 118, 210, 0.4);\n transition: all 0.2s ease;\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle:hover {\n background: #1565c0;\n transform: scale(1.05);\n box-shadow: 0 6px 16px rgba(25, 118, 210, 0.5);\n}\n\n.fab-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: #e53935;\n color: white;\n font-size: 11px;\n font-weight: 600;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: #6c757d;\n}\n\n.loading-spinner {\n font-size: 32px;\n color: #1976d2;\n}\n\n/* Apps Section */\n.apps-section {\n flex: 0 0 auto;\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: 20px;\n font-weight: 600;\n color: #495057;\n}\n\n.section-title i {\n color: #6c757d;\n}\n\n/* Apps Grid */\n.apps-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n/* App Card */\n.app-card {\n --app-color: #757575;\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: white;\n border-radius: 14px;\n border: 1px solid #e9ecef;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card:hover {\n border-color: var(--app-color);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);\n transform: translateY(-3px);\n}\n\n.app-card:hover::before {\n opacity: 1;\n}\n\n/* App Icon */\n.app-icon-wrapper {\n flex-shrink: 0;\n}\n\n.app-icon {\n width: 52px;\n height: 52px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon i {\n font-size: 22px;\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card:hover .app-icon {\n background: var(--app-color);\n}\n\n.app-card:hover .app-icon i {\n color: white;\n transform: scale(1.1);\n}\n\n/* App Info */\n.app-info {\n flex: 1;\n min-width: 0;\n}\n\n.app-name {\n margin: 0 0 4px 0;\n font-size: 17px;\n font-weight: 600;\n color: #212529;\n}\n\n.app-description {\n margin: 0 0 10px 0;\n font-size: 13px;\n color: #6c757d;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Nav Items Preview */\n.nav-preview {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: #f8f9fa;\n border-radius: 5px;\n font-size: 11px;\n color: #495057;\n}\n\n.nav-item-chip i {\n font-size: 9px;\n color: #6c757d;\n}\n\n.more-items {\n font-size: 11px;\n color: #6c757d;\n font-style: italic;\n}\n\n/* App Arrow */\n.app-arrow {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: 16px;\n}\n\n.app-card:hover .app-arrow {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n background: white;\n border-radius: 16px;\n border: 2px dashed #dee2e6;\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: #f8f9fa;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon i {\n font-size: 32px;\n color: #adb5bd;\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #495057;\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #6c757d;\n max-width: 400px;\n}\n\n.empty-state button i {\n margin-right: 8px;\n}\n\n/* ========================================\n RIGHT SIDEBAR\n ======================================== */\n.quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below shell header */\n right: 0;\n bottom: 0;\n width: 320px;\n background: white;\n border-left: 1px solid #e9ecef;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s ease;\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.08);\n}\n\n.home-dashboard.sidebar-open .quick-access-sidebar {\n transform: translateX(0);\n}\n\n.sidebar-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid #e9ecef;\n background: #fafbfc;\n}\n\n.sidebar-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #212529;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header h3 i {\n color: #1976d2;\n font-size: 14px;\n}\n\n.sidebar-close-btn {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: #6c757d;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.sidebar-close-btn:hover {\n background: #f1f3f4;\n color: #212529;\n}\n\n.sidebar-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n/* Sidebar Sections */\n.sidebar-section {\n margin-bottom: 20px;\n}\n\n.sidebar-section:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title i {\n font-size: 12px;\n}\n\n.notifications-section .sidebar-section-title i {\n color: #f57c00;\n}\n\n.favorites-section .sidebar-section-title i {\n color: #ffc107;\n}\n\n.recents-section .sidebar-section-title i {\n color: #1976d2;\n}\n\n.section-badge {\n background: #e53935;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 8px;\n margin-left: auto;\n}\n\n/* Sidebar Items */\n.sidebar-items {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: #f8f9fa;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sidebar-item:hover {\n background: #e9ecef;\n transform: translateX(4px);\n}\n\n.sidebar-item-icon {\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: white;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon i {\n font-size: 14px;\n color: #6c757d;\n}\n\n.notification-item .sidebar-item-icon {\n background: #fff3e0;\n}\n\n.notification-item .sidebar-item-icon i {\n color: #f57c00;\n}\n\n.favorite-item .sidebar-item-icon {\n background: #fff8e1;\n}\n\n.favorite-item .sidebar-item-icon i {\n color: #f9a825;\n}\n\n.recent-item .sidebar-item-icon {\n background: #e3f2fd;\n}\n\n.recent-item .sidebar-item-icon i {\n color: #1976d2;\n}\n\n.sidebar-item-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title {\n font-size: 13px;\n font-weight: 500;\n color: #212529;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle {\n font-size: 11px;\n color: #6c757d;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #6c757d;\n font-size: 13px;\n padding: 8px 0;\n}\n\n.sidebar-loading i {\n color: #1976d2;\n}\n\n.sidebar-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: #adb5bd;\n}\n\n.sidebar-empty i {\n font-size: 32px;\n margin-bottom: 12px;\n}\n\n.sidebar-empty p {\n margin: 0;\n font-size: 13px;\n}\n\n\n/* ========================================\n RESPONSIVE DESIGN\n ======================================== */\n\n/* Tablet and smaller desktop */\n@media (max-width: 1200px) {\n .quick-access-sidebar {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 280px;\n }\n\n .apps-grid {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n/* Tablet */\n@media (max-width: 992px) {\n .main-content {\n padding: 24px;\n }\n\n .greeting-section h1 {\n font-size: 28px;\n }\n\n /* Make sidebar an overlay on tablet */\n .quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below shell header */\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 0;\n }\n\n /* Show backdrop when sidebar is open on tablet */\n .home-dashboard.sidebar-open::after {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 320px;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 999;\n }\n}\n\n/* Mobile */\n@media (max-width: 768px) {\n .home-dashboard {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content {\n padding: 20px;\n padding-bottom: 100px; /* Space for FAB button */\n overflow: visible;\n }\n\n .home-header {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section h1 {\n font-size: 24px;\n }\n\n /* Full-width sidebar on mobile - positioned below top nav */\n .quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below the shell header */\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 100; /* Below shell header */\n border-left: none;\n border-top: 1px solid #e9ecef;\n }\n\n /* Add backdrop on mobile when sidebar is open */\n .home-dashboard.sidebar-open::before {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 99;\n }\n\n /* No ::after backdrop needed on mobile */\n .home-dashboard.sidebar-open::after {\n display: none;\n }\n\n .apps-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card {\n padding: 16px;\n }\n\n .app-icon {\n width: 44px;\n height: 44px;\n }\n\n .app-icon i {\n font-size: 18px;\n }\n\n .app-name {\n font-size: 15px;\n }\n\n .nav-preview {\n display: none;\n }\n\n /* Move FAB to bottom-right on mobile */\n .sidebar-fab-toggle {\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: 18px;\n }\n}\n\n@media (max-width: 480px) {\n .main-content {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section h1 {\n font-size: 20px;\n }\n\n .greeting-section .date {\n font-size: 14px;\n }\n\n .section-title {\n font-size: 16px;\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: 16px;\n }\n}\n"] }]
784
833
  }], () => [{ type: i1.ApplicationManager }, { type: i2.NavigationService }, { type: i2.RecentAccessService }, { type: i0.ChangeDetectorRef }], { appConfigDialog: [{
785
834
  type: ViewChild,
786
835
  args: ['appConfigDialog']