@memberjunction/ng-dashboards 6.2.0-edge.2 → 6.2.0-edge.4

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 (229) hide show
  1. package/dist/AI/components/analytics/realtime/realtime-transcripts-data.d.ts +4 -3
  2. package/dist/AI/components/analytics/realtime/realtime-transcripts-data.d.ts.map +1 -1
  3. package/dist/AI/components/analytics/realtime/realtime-transcripts-data.js +8 -5
  4. package/dist/AI/components/analytics/realtime/realtime-transcripts-data.js.map +1 -1
  5. package/dist/AI/components/duplicates/compare-value.component.d.ts +67 -0
  6. package/dist/AI/components/duplicates/compare-value.component.d.ts.map +1 -0
  7. package/dist/AI/components/duplicates/compare-value.component.js +168 -0
  8. package/dist/AI/components/duplicates/compare-value.component.js.map +1 -0
  9. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +49 -3
  10. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  11. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +287 -169
  12. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  13. package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts +77 -0
  14. package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts.map +1 -0
  15. package/dist/AI/components/duplicates/duplicate-detection-run-scope.js +116 -0
  16. package/dist/AI/components/duplicates/duplicate-detection-run-scope.js.map +1 -0
  17. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +1 -0
  18. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
  19. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +16 -4
  20. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
  21. package/dist/AI/components/tags/tags-resource.component.d.ts +2 -0
  22. package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
  23. package/dist/AI/components/tags/tags-resource.component.js +12 -6
  24. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  25. package/dist/AI/components/vectors/vector-index-auto.d.ts +29 -0
  26. package/dist/AI/components/vectors/vector-index-auto.d.ts.map +1 -0
  27. package/dist/AI/components/vectors/vector-index-auto.js +59 -0
  28. package/dist/AI/components/vectors/vector-index-auto.js.map +1 -0
  29. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +9 -0
  30. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  31. package/dist/AI/components/vectors/vector-management-resource.component.js +65 -20
  32. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  33. package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
  34. package/dist/Actions/components/actions-overview.component.js +7 -3
  35. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  36. package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
  37. package/dist/Actions/components/categories-list-view.component.js +3 -2
  38. package/dist/Actions/components/categories-list-view.component.js.map +1 -1
  39. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  40. package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -0
  41. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  42. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +0 -3
  43. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
  44. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +5 -14
  45. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
  46. package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
  47. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -0
  48. package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
  49. package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
  50. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +1 -0
  51. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
  52. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts +12 -1
  53. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts.map +1 -1
  54. package/dist/ComponentStudio/components/form-override-dialog.component.js +128 -81
  55. package/dist/ComponentStudio/components/form-override-dialog.component.js.map +1 -1
  56. package/dist/Credentials/components/credentials-list-resource.component.d.ts +2 -0
  57. package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
  58. package/dist/Credentials/components/credentials-list-resource.component.js +12 -10
  59. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  60. package/dist/DashboardBrowser/dashboard-browser-agent-context.d.ts +14 -43
  61. package/dist/DashboardBrowser/dashboard-browser-agent-context.d.ts.map +1 -1
  62. package/dist/DashboardBrowser/dashboard-browser-agent-context.js +6 -29
  63. package/dist/DashboardBrowser/dashboard-browser-agent-context.js.map +1 -1
  64. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +174 -321
  65. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
  66. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +522 -1195
  67. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  68. package/dist/DashboardBrowser/dashboard-library-filter.d.ts +116 -0
  69. package/dist/DashboardBrowser/dashboard-library-filter.d.ts.map +1 -0
  70. package/dist/DashboardBrowser/dashboard-library-filter.js +277 -0
  71. package/dist/DashboardBrowser/dashboard-library-filter.js.map +1 -0
  72. package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts +1 -1
  73. package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
  74. package/dist/DashboardBrowser/dashboards-agent-tools.d.ts +26 -0
  75. package/dist/DashboardBrowser/dashboards-agent-tools.d.ts.map +1 -0
  76. package/dist/DashboardBrowser/dashboards-agent-tools.js +32 -0
  77. package/dist/DashboardBrowser/dashboards-agent-tools.js.map +1 -0
  78. package/dist/DashboardBrowser/dashboards-categories-resource.component.d.ts +58 -0
  79. package/dist/DashboardBrowser/dashboards-categories-resource.component.d.ts.map +1 -0
  80. package/dist/DashboardBrowser/dashboards-categories-resource.component.js +391 -0
  81. package/dist/DashboardBrowser/dashboards-categories-resource.component.js.map +1 -0
  82. package/dist/DashboardBrowser/dashboards-categories.helpers.d.ts +37 -0
  83. package/dist/DashboardBrowser/dashboards-categories.helpers.d.ts.map +1 -0
  84. package/dist/DashboardBrowser/dashboards-categories.helpers.js +68 -0
  85. package/dist/DashboardBrowser/dashboards-categories.helpers.js.map +1 -0
  86. package/dist/DashboardEditor/dashboard-editor.component.d.ts +295 -0
  87. package/dist/DashboardEditor/dashboard-editor.component.d.ts.map +1 -0
  88. package/dist/DashboardEditor/dashboard-editor.component.js +1022 -0
  89. package/dist/DashboardEditor/dashboard-editor.component.js.map +1 -0
  90. package/dist/DashboardEditor/dashboard-editor.types.d.ts +23 -0
  91. package/dist/DashboardEditor/dashboard-editor.types.d.ts.map +1 -0
  92. package/dist/DashboardEditor/dashboard-editor.types.js +3 -0
  93. package/dist/DashboardEditor/dashboard-editor.types.js.map +1 -0
  94. package/dist/DashboardEditor/dashboard-viewer-factory.d.ts +11 -0
  95. package/dist/DashboardEditor/dashboard-viewer-factory.d.ts.map +1 -0
  96. package/dist/DashboardEditor/dashboard-viewer-factory.js +17 -0
  97. package/dist/DashboardEditor/dashboard-viewer-factory.js.map +1 -0
  98. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +30 -0
  99. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  100. package/dist/DataExplorer/data-explorer-dashboard.component.js +349 -232
  101. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  102. package/dist/DataExplorer/services/explorer-state.service.d.ts +1 -1
  103. package/dist/DataExplorer/services/explorer-state.service.js +2 -5
  104. package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
  105. package/dist/FormBuilder/form-builder-resource.component.d.ts +0 -14
  106. package/dist/FormBuilder/form-builder-resource.component.d.ts.map +1 -1
  107. package/dist/FormBuilder/form-builder-resource.component.js +7 -29
  108. package/dist/FormBuilder/form-builder-resource.component.js.map +1 -1
  109. package/dist/Home/home-agent-context.d.ts +29 -10
  110. package/dist/Home/home-agent-context.d.ts.map +1 -1
  111. package/dist/Home/home-agent-context.js +50 -24
  112. package/dist/Home/home-agent-context.js.map +1 -1
  113. package/dist/Home/home-dashboard-switcher.component.d.ts +95 -0
  114. package/dist/Home/home-dashboard-switcher.component.d.ts.map +1 -0
  115. package/dist/Home/home-dashboard-switcher.component.js +442 -0
  116. package/dist/Home/home-dashboard-switcher.component.js.map +1 -0
  117. package/dist/Home/home-dashboard.component.d.ts +330 -17
  118. package/dist/Home/home-dashboard.component.d.ts.map +1 -1
  119. package/dist/Home/home-dashboard.component.js +1702 -1014
  120. package/dist/Home/home-dashboard.component.js.map +1 -1
  121. package/dist/Home/home-menus.d.ts +38 -0
  122. package/dist/Home/home-menus.d.ts.map +1 -0
  123. package/dist/Home/home-menus.js +53 -0
  124. package/dist/Home/home-menus.js.map +1 -0
  125. package/dist/Home/home-pinned-dashboards.d.ts +33 -0
  126. package/dist/Home/home-pinned-dashboards.d.ts.map +1 -0
  127. package/dist/Home/home-pinned-dashboards.js +76 -0
  128. package/dist/Home/home-pinned-dashboards.js.map +1 -0
  129. package/dist/PredictiveStudio/components/ps-production.component.d.ts +5 -1
  130. package/dist/PredictiveStudio/components/ps-production.component.d.ts.map +1 -1
  131. package/dist/PredictiveStudio/components/ps-production.component.js +64 -41
  132. package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
  133. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  134. package/dist/QueryBrowser/query-browser-resource.component.js +3 -2
  135. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  136. package/dist/RealtimeRecordings/realtime-recordings-dashboard.component.js +2 -2
  137. package/dist/RealtimeRecordings/realtime-recordings-dashboard.component.js.map +1 -1
  138. package/dist/TelephonyOperations/telephony-operations-agent-context.d.ts +107 -0
  139. package/dist/TelephonyOperations/telephony-operations-agent-context.d.ts.map +1 -0
  140. package/dist/TelephonyOperations/telephony-operations-agent-context.js +216 -0
  141. package/dist/TelephonyOperations/telephony-operations-agent-context.js.map +1 -0
  142. package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts +58 -0
  143. package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts.map +1 -0
  144. package/dist/TelephonyOperations/telephony-operations-dashboard.component.js +812 -0
  145. package/dist/TelephonyOperations/telephony-operations-dashboard.component.js.map +1 -0
  146. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
  147. package/dist/Testing/components/testing-explorer.component.js +7 -7
  148. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  149. package/dist/WorkQueue/components/work-queue-bindings.component.d.ts +37 -0
  150. package/dist/WorkQueue/components/work-queue-bindings.component.d.ts.map +1 -0
  151. package/dist/WorkQueue/components/work-queue-bindings.component.js +210 -0
  152. package/dist/WorkQueue/components/work-queue-bindings.component.js.map +1 -0
  153. package/dist/WorkQueue/components/work-queue-dead-letters.component.d.ts +70 -0
  154. package/dist/WorkQueue/components/work-queue-dead-letters.component.d.ts.map +1 -0
  155. package/dist/WorkQueue/components/work-queue-dead-letters.component.js +496 -0
  156. package/dist/WorkQueue/components/work-queue-dead-letters.component.js.map +1 -0
  157. package/dist/WorkQueue/components/work-queue-discard-dialog.component.d.ts +22 -0
  158. package/dist/WorkQueue/components/work-queue-discard-dialog.component.d.ts.map +1 -0
  159. package/dist/WorkQueue/components/work-queue-discard-dialog.component.js +99 -0
  160. package/dist/WorkQueue/components/work-queue-discard-dialog.component.js.map +1 -0
  161. package/dist/WorkQueue/components/work-queue-overview.component.d.ts +29 -0
  162. package/dist/WorkQueue/components/work-queue-overview.component.d.ts.map +1 -0
  163. package/dist/WorkQueue/components/work-queue-overview.component.js +278 -0
  164. package/dist/WorkQueue/components/work-queue-overview.component.js.map +1 -0
  165. package/dist/WorkQueue/components/work-queue-partitions.component.d.ts +59 -0
  166. package/dist/WorkQueue/components/work-queue-partitions.component.d.ts.map +1 -0
  167. package/dist/WorkQueue/components/work-queue-partitions.component.js +359 -0
  168. package/dist/WorkQueue/components/work-queue-partitions.component.js.map +1 -0
  169. package/dist/WorkQueue/services/work-queue-operator.service.d.ts +22 -0
  170. package/dist/WorkQueue/services/work-queue-operator.service.d.ts.map +1 -0
  171. package/dist/WorkQueue/services/work-queue-operator.service.js +44 -0
  172. package/dist/WorkQueue/services/work-queue-operator.service.js.map +1 -0
  173. package/dist/WorkQueue/work-queue-agent-context.d.ts +67 -0
  174. package/dist/WorkQueue/work-queue-agent-context.d.ts.map +1 -0
  175. package/dist/WorkQueue/work-queue-agent-context.js +119 -0
  176. package/dist/WorkQueue/work-queue-agent-context.js.map +1 -0
  177. package/dist/WorkQueue/work-queue-dashboard.component.d.ts +94 -0
  178. package/dist/WorkQueue/work-queue-dashboard.component.d.ts.map +1 -0
  179. package/dist/WorkQueue/work-queue-dashboard.component.js +545 -0
  180. package/dist/WorkQueue/work-queue-dashboard.component.js.map +1 -0
  181. package/dist/WorkQueue/work-queue-types.d.ts +40 -0
  182. package/dist/WorkQueue/work-queue-types.d.ts.map +1 -0
  183. package/dist/WorkQueue/work-queue-types.js +2 -0
  184. package/dist/WorkQueue/work-queue-types.js.map +1 -0
  185. package/dist/ai-dashboards.module.d.ts +21 -20
  186. package/dist/ai-dashboards.module.d.ts.map +1 -1
  187. package/dist/ai-dashboards.module.js +4 -1
  188. package/dist/ai-dashboards.module.js.map +1 -1
  189. package/dist/core-dashboards.module.d.ts +69 -61
  190. package/dist/core-dashboards.module.d.ts.map +1 -1
  191. package/dist/core-dashboards.module.js +29 -2
  192. package/dist/core-dashboards.module.js.map +1 -1
  193. package/dist/data-explorer-dashboards.module.d.ts +1 -1
  194. package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
  195. package/dist/data-explorer-dashboards.module.js +3 -1
  196. package/dist/data-explorer-dashboards.module.js.map +1 -1
  197. package/dist/module.d.ts +14 -13
  198. package/dist/module.d.ts.map +1 -1
  199. package/dist/module.js +7 -0
  200. package/dist/module.js.map +1 -1
  201. package/dist/public-api.d.ts +6 -0
  202. package/dist/public-api.d.ts.map +1 -1
  203. package/dist/public-api.js +9 -0
  204. package/dist/public-api.js.map +1 -1
  205. package/dist/shared/dashboard-library-changes.d.ts +23 -0
  206. package/dist/shared/dashboard-library-changes.d.ts.map +1 -0
  207. package/dist/shared/dashboard-library-changes.js +26 -0
  208. package/dist/shared/dashboard-library-changes.js.map +1 -0
  209. package/dist/shared/dashboard-owner-names.d.ts +17 -0
  210. package/dist/shared/dashboard-owner-names.d.ts.map +1 -0
  211. package/dist/shared/dashboard-owner-names.js +65 -0
  212. package/dist/shared/dashboard-owner-names.js.map +1 -0
  213. package/dist/shared/dashboard-recents.d.ts +34 -0
  214. package/dist/shared/dashboard-recents.d.ts.map +1 -0
  215. package/dist/shared/dashboard-recents.js +87 -0
  216. package/dist/shared/dashboard-recents.js.map +1 -0
  217. package/dist/shared/dashboards-app-install.d.ts +59 -0
  218. package/dist/shared/dashboards-app-install.d.ts.map +1 -0
  219. package/dist/shared/dashboards-app-install.js +97 -0
  220. package/dist/shared/dashboards-app-install.js.map +1 -0
  221. package/dist/shared/dashboards-app.helpers.d.ts +42 -0
  222. package/dist/shared/dashboards-app.helpers.d.ts.map +1 -0
  223. package/dist/shared/dashboards-app.helpers.js +143 -0
  224. package/dist/shared/dashboards-app.helpers.js.map +1 -0
  225. package/dist/work-queue-dashboards.module.d.ts +23 -0
  226. package/dist/work-queue-dashboards.module.d.ts.map +1 -0
  227. package/dist/work-queue-dashboards.module.js +92 -0
  228. package/dist/work-queue-dashboards.module.js.map +1 -0
  229. package/package.json +73 -66
@@ -4,17 +4,24 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { Component, ViewChild, ChangeDetectionStrategy, inject } from '@angular/core';
7
+ import { Component, ViewChild, ChangeDetectionStrategy, ElementRef, inject } from '@angular/core';
8
8
  import { Subject } from 'rxjs';
9
9
  import { takeUntil } from 'rxjs/operators';
10
- import { BaseResourceComponent, HomeAppPinService } from '@memberjunction/ng-shared';
11
- import { RegisterClass } from '@memberjunction/global';
12
- import { CompositeKey } from '@memberjunction/core';
10
+ import { BaseResourceComponent, HomeAppPinService, IsDashboardEntity, SafeDetectChanges, BuildDashboardPinInput } from '@memberjunction/ng-shared';
11
+ import { ResourceTypeForEntity } from '@memberjunction/ng-shared-generic';
12
+ import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
13
+ import { CompositeKey, LogError } from '@memberjunction/core';
13
14
  import { UserInfoEngine, DashboardEngine, UserViewEngine, QueryEngine } from '@memberjunction/core-entities';
14
15
  import { ActionEngineBase } from '@memberjunction/actions-base';
16
+ import { DASHBOARD_NAME_MAX_LENGTH } from '@memberjunction/ng-dashboard-viewer';
15
17
  import { MJNotificationService } from '@memberjunction/ng-notifications';
18
+ import { MJConfirmService } from '@memberjunction/ng-ui-components';
16
19
  import { BuildHomeAgentContext, BuildHomeNotFoundError, ResolveNamedRecord } from './home-agent-context';
20
+ import { MenuAnchorOf, NextMenuFocusIndex, PlaceMenu } from './home-menus';
21
+ import { BuildPinDashboardNames, BuildPinnedDashboards, CanShowInHome, DashboardIdOfPin, FindDashboard, ResolvePinnedDashboardReference, ResolvePinResourceType, } from './home-pinned-dashboards';
17
22
  import { ValidateStringParam } from '../shared/agent-tool-validation';
23
+ import { ObserveDashboardLibraryChanges } from '../shared/dashboard-library-changes';
24
+ import { AutoInstallDashboardsApp, CreateBlankDashboard, DashboardNameMaxLength, EnsureDashboardsApp } from '../shared/dashboards-app.helpers';
18
25
  import * as i0 from "@angular/core";
19
26
  import * as i1 from "@memberjunction/ng-base-application";
20
27
  import * as i2 from "@memberjunction/ng-shared";
@@ -22,477 +29,480 @@ import * as i3 from "@angular/forms";
22
29
  import * as i4 from "@memberjunction/ng-ui-components";
23
30
  import * as i5 from "@memberjunction/ng-shared-generic";
24
31
  import * as i6 from "@memberjunction/ng-explorer-settings";
25
- import * as i7 from "./action-pin-config-dialog.component";
26
- import * as i8 from "./action-pin-runner-dialog.component";
27
- import * as i9 from "@angular/common";
32
+ import * as i7 from "@memberjunction/ng-dashboard-viewer";
33
+ import * as i8 from "./home-dashboard-switcher.component";
34
+ import * as i9 from "./action-pin-config-dialog.component";
35
+ import * as i10 from "./action-pin-runner-dialog.component";
36
+ import * as i11 from "../DashboardEditor/dashboard-editor.component";
37
+ import * as i12 from "@angular/common";
28
38
  const _c0 = ["appConfigDialog"];
29
- const _forTrack0 = ($index, $item) => $item.appId;
30
- const _forTrack1 = ($index, $item) => $item.label;
31
- const _forTrack2 = ($index, $item) => $item.id;
32
- function HomeDashboardComponent_Conditional_8_Conditional_6_Template(rf, ctx) { if (rf & 1) {
33
- const _r2 = i0.ɵɵgetCurrentView();
34
- i0.ɵɵelementStart(0, "button", 23);
35
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.ToggleEditMode()); });
36
- i0.ɵɵelement(1, "i", 24);
37
- i0.ɵɵtext(2, " Done ");
39
+ const _c1 = ["pinMenu"];
40
+ const _c2 = ["dashboardEditor"];
41
+ const _forTrack0 = ($index, $item) => $item.Key;
42
+ const _forTrack1 = ($index, $item) => $item.Id;
43
+ const _forTrack2 = ($index, $item) => $item.appId;
44
+ const _forTrack3 = ($index, $item) => $item.label;
45
+ const _forTrack4 = ($index, $item) => $item.id;
46
+ function HomeDashboardComponent_Conditional_2_ng_template_8_Template(rf, ctx) { if (rf & 1) {
47
+ i0.ɵɵelementStart(0, "span", 28);
48
+ i0.ɵɵelement(1, "i", 29);
49
+ i0.ɵɵtext(2, " Pinned");
38
50
  i0.ɵɵelementEnd();
39
51
  } }
40
- function HomeDashboardComponent_Conditional_8_Conditional_7_Conditional_3_Template(rf, ctx) { if (rf & 1) {
52
+ function HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
53
+ const _r4 = i0.ɵɵgetCurrentView();
54
+ i0.ɵɵelementStart(0, "button", 32);
55
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.ToggleEditMode()); });
56
+ i0.ɵɵelement(1, "i", 33);
57
+ i0.ɵɵelementStart(2, "span", 34);
58
+ i0.ɵɵtext(3, "Done");
59
+ i0.ɵɵelementEnd()();
60
+ } }
61
+ function HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
62
+ const _r6 = i0.ɵɵgetCurrentView();
63
+ i0.ɵɵelementStart(0, "button", 39);
64
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_2_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.ToggleEditMode()); });
65
+ i0.ɵɵelement(1, "i", 40);
66
+ i0.ɵɵelementStart(2, "span", 34);
67
+ i0.ɵɵtext(3, "Edit");
68
+ i0.ɵɵelementEnd()();
69
+ } }
70
+ function HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_2_Template(rf, ctx) { if (rf & 1) {
41
71
  const _r5 = i0.ɵɵgetCurrentView();
42
- i0.ɵɵelementStart(0, "button", 28);
43
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_7_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.ToggleEditMode()); });
44
- i0.ɵɵelement(1, "i", 29);
45
- i0.ɵɵtext(2, " Edit ");
72
+ i0.ɵɵelementStart(0, "button", 35);
73
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenAddPinPanel()); });
74
+ i0.ɵɵelement(1, "i", 36);
75
+ i0.ɵɵelementStart(2, "span", 34);
76
+ i0.ɵɵtext(3, "Add Pin");
77
+ i0.ɵɵelementEnd()();
78
+ i0.ɵɵelementStart(4, "mj-home-dashboard-switcher", 37);
79
+ i0.ɵɵlistener("Pick", function HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_2_Template_mj_home_dashboard_switcher_Pick_4_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnSwitcherPick($event)); })("New", function HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_2_Template_mj_home_dashboard_switcher_New_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenNewDashboardDialog()); })("ManagePins", function HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_2_Template_mj_home_dashboard_switcher_ManagePins_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.ManagePins()); });
46
80
  i0.ɵɵelementEnd();
81
+ i0.ɵɵconditionalCreate(5, HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_2_Conditional_5_Template, 4, 0, "button", 38);
82
+ } if (rf & 2) {
83
+ const ctx_r2 = i0.ɵɵnextContext(3);
84
+ i0.ɵɵadvance(4);
85
+ i0.ɵɵproperty("Dashboards", ctx_r2.PinnedDashboards)("CurrentId", null);
86
+ i0.ɵɵadvance();
87
+ i0.ɵɵconditional(ctx_r2.PinnedItems.length > 0 ? 5 : -1);
47
88
  } }
48
- function HomeDashboardComponent_Conditional_8_Conditional_7_Template(rf, ctx) { if (rf & 1) {
49
- const _r4 = i0.ɵɵgetCurrentView();
50
- i0.ɵɵelementStart(0, "button", 25);
51
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OpenAddPinPanel()); });
52
- i0.ɵɵelement(1, "i", 26);
53
- i0.ɵɵtext(2, " Add Pin ");
89
+ function HomeDashboardComponent_Conditional_2_ng_template_9_Template(rf, ctx) { if (rf & 1) {
90
+ i0.ɵɵelementStart(0, "div", 30);
91
+ i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_1_Template, 4, 0, "button", 31)(2, HomeDashboardComponent_Conditional_2_ng_template_9_Conditional_2_Template, 6, 3);
54
92
  i0.ɵɵelementEnd();
55
- i0.ɵɵconditionalCreate(3, HomeDashboardComponent_Conditional_8_Conditional_7_Conditional_3_Template, 3, 0, "button", 27);
56
93
  } if (rf & 2) {
57
94
  const ctx_r2 = i0.ɵɵnextContext(2);
58
- i0.ɵɵadvance(3);
59
- i0.ɵɵconditional(ctx_r2.PinnedItems.length > 0 ? 3 : -1);
95
+ i0.ɵɵadvance();
96
+ i0.ɵɵconditional(ctx_r2.EditMode ? 1 : 2);
60
97
  } }
61
- function HomeDashboardComponent_Conditional_8_Conditional_8_Template(rf, ctx) { if (rf & 1) {
62
- i0.ɵɵelementStart(0, "div", 20);
63
- i0.ɵɵelement(1, "i", 30);
98
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_1_Template(rf, ctx) { if (rf & 1) {
99
+ i0.ɵɵelementStart(0, "div", 42);
100
+ i0.ɵɵelement(1, "i", 45);
64
101
  i0.ɵɵelementStart(2, "span")(3, "strong");
65
102
  i0.ɵɵtext(4, "Edit mode");
66
103
  i0.ɵɵelementEnd();
67
104
  i0.ɵɵtext(5, " \u2014 Drag cards to reorder. Click names to rename.");
68
105
  i0.ɵɵelementEnd()();
69
106
  } }
70
- function HomeDashboardComponent_Conditional_8_Conditional_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
71
- const _r7 = i0.ɵɵgetCurrentView();
72
- i0.ɵɵelementStart(0, "button", 35);
73
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_9_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.DismissPinEmptyState()); });
74
- i0.ɵɵelement(1, "i", 36);
107
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
108
+ const _r8 = i0.ɵɵgetCurrentView();
109
+ i0.ɵɵelementStart(0, "button", 51);
110
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_2_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.DismissPinEmptyState()); });
111
+ i0.ɵɵelement(1, "i", 52);
75
112
  i0.ɵɵelementEnd();
76
113
  } }
77
- function HomeDashboardComponent_Conditional_8_Conditional_9_Conditional_6_Template(rf, ctx) { if (rf & 1) {
78
- const _r8 = i0.ɵɵgetCurrentView();
79
- i0.ɵɵelementStart(0, "button", 37);
80
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_9_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.DismissPinEmptyState()); });
114
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
115
+ const _r9 = i0.ɵɵgetCurrentView();
116
+ i0.ɵɵelementStart(0, "button", 53);
117
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_2_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.DismissPinEmptyState()); });
81
118
  i0.ɵɵtext(1, " Don't show this again ");
82
119
  i0.ɵɵelementEnd();
83
120
  } }
84
- function HomeDashboardComponent_Conditional_8_Conditional_9_Template(rf, ctx) { if (rf & 1) {
85
- const _r6 = i0.ɵɵgetCurrentView();
86
- i0.ɵɵelementStart(0, "div", 21);
87
- i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_8_Conditional_9_Conditional_1_Template, 2, 0, "button", 31);
88
- i0.ɵɵelementStart(2, "mj-empty-state", 32)(3, "button", 33);
89
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_9_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OpenAddPinPanel()); });
90
- i0.ɵɵelement(4, "i", 26);
121
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_2_Template(rf, ctx) { if (rf & 1) {
122
+ const _r7 = i0.ɵɵgetCurrentView();
123
+ i0.ɵɵelementStart(0, "div", 43);
124
+ i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_2_Conditional_1_Template, 2, 0, "button", 46);
125
+ i0.ɵɵelementStart(2, "mj-empty-state", 47)(3, "button", 48);
126
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_2_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenAddPinPanel()); });
127
+ i0.ɵɵelement(4, "i", 49);
91
128
  i0.ɵɵtext(5, " Add your first pin ");
92
129
  i0.ɵɵelementEnd();
93
- i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_8_Conditional_9_Conditional_6_Template, 2, 0, "button", 34);
130
+ i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_2_Conditional_6_Template, 2, 0, "button", 50);
94
131
  i0.ɵɵelementEnd()();
95
132
  } if (rf & 2) {
96
- const ctx_r2 = i0.ɵɵnextContext(2);
133
+ const ctx_r2 = i0.ɵɵnextContext(3);
97
134
  i0.ɵɵadvance();
98
135
  i0.ɵɵconditional(!ctx_r2.EditMode ? 1 : -1);
99
136
  i0.ɵɵadvance(5);
100
137
  i0.ɵɵconditional(!ctx_r2.EditMode && !ctx_r2.HidePinEmptyState ? 6 : -1);
101
138
  } }
102
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
103
- const _r11 = i0.ɵɵgetCurrentView();
104
- i0.ɵɵelementStart(0, "div", 41)(1, "div", 50);
105
- i0.ɵɵelement(2, "i", 51);
139
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
140
+ const _r10 = i0.ɵɵgetCurrentView();
141
+ i0.ɵɵelementStart(0, "input", 62);
142
+ i0.ɵɵlistener("blur", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Conditional_1_Template_input_blur_0_listener($event) { i0.ɵɵrestoreView(_r10); const section_r11 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.SaveGroupName(section_r11.Group, ctx_r2.GetInputValue($event))); })("keydown.enter", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Conditional_1_Template_input_keydown_enter_0_listener($event) { i0.ɵɵrestoreView(_r10); const section_r11 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.SaveGroupName(section_r11.Group, ctx_r2.GetInputValue($event))); });
106
143
  i0.ɵɵelementEnd();
107
- i0.ɵɵelementStart(3, "div", 52)(4, "button", 53);
108
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_1_Template_button_click_4_listener($event) { i0.ɵɵrestoreView(_r11); const pin_r10 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.RemovePin(pin_r10.Id); return i0.ɵɵresetView($event.stopPropagation()); });
109
- i0.ɵɵelement(5, "i", 36);
110
- i0.ɵɵelementEnd()()();
144
+ } if (rf & 2) {
145
+ const section_r11 = i0.ɵɵnextContext(2).$implicit;
146
+ i0.ɵɵproperty("value", section_r11.Group);
111
147
  } }
112
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
148
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
113
149
  const _r12 = i0.ɵɵgetCurrentView();
114
- i0.ɵɵelementStart(0, "div", 55)(1, "button", 56);
115
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_2_Conditional_2_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r12); const pin_r10 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.OnPinClick(pin_r10); return i0.ɵɵresetView($event.stopPropagation()); });
116
- i0.ɵɵtext(2, "Open");
117
- i0.ɵɵelementEnd()();
118
- } }
119
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
120
- i0.ɵɵelementStart(0, "div", 42);
121
- i0.ɵɵelement(1, "img", 54);
122
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_2_Conditional_2_Template, 3, 0, "div", 55);
150
+ i0.ɵɵelementStart(0, "span", 63);
151
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Conditional_2_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r12); const section_r11 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.EditMode ? ctx_r2.StartEditingGroup(section_r11.Group) : null); });
152
+ i0.ɵɵtext(1);
123
153
  i0.ɵɵelementEnd();
124
154
  } if (rf & 2) {
125
- const pin_r10 = i0.ɵɵnextContext().$implicit;
126
- const ctx_r2 = i0.ɵɵnextContext(3);
127
- i0.ɵɵadvance();
128
- i0.ɵɵproperty("src", pin_r10.Thumbnail, i0.ɵɵsanitizeUrl)("alt", pin_r10.DisplayName);
155
+ const section_r11 = i0.ɵɵnextContext(2).$implicit;
129
156
  i0.ɵɵadvance();
130
- i0.ɵɵconditional(!ctx_r2.EditMode ? 2 : -1);
157
+ i0.ɵɵtextInterpolate(section_r11.Group);
131
158
  } }
132
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
159
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Conditional_6_Template(rf, ctx) { if (rf & 1) {
133
160
  const _r13 = i0.ɵɵgetCurrentView();
134
- i0.ɵɵelementStart(0, "div", 55)(1, "button", 56);
135
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_3_Conditional_2_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r13); const pin_r10 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.OnPinClick(pin_r10); return i0.ɵɵresetView($event.stopPropagation()); });
136
- i0.ɵɵtext(2, "Run");
161
+ i0.ɵɵelementStart(0, "div", 61)(1, "button", 64);
162
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Conditional_6_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r13); const section_r11 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.RemoveGroup(section_r11.Group)); });
163
+ i0.ɵɵelement(2, "i", 65);
164
+ i0.ɵɵtext(3, " Remove Group ");
137
165
  i0.ɵɵelementEnd()();
138
166
  } }
139
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
140
- i0.ɵɵelementStart(0, "div", 57);
141
- i0.ɵɵelement(1, "i");
142
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_3_Conditional_2_Template, 3, 0, "div", 55);
167
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
168
+ i0.ɵɵelementStart(0, "div", 55);
169
+ i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Conditional_1_Template, 1, 1, "input", 57)(2, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Conditional_2_Template, 2, 1, "span", 58);
170
+ i0.ɵɵelement(3, "div", 59);
171
+ i0.ɵɵelementStart(4, "span", 60);
172
+ i0.ɵɵtext(5);
173
+ i0.ɵɵelementEnd();
174
+ i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Conditional_6_Template, 4, 0, "div", 61);
143
175
  i0.ɵɵelementEnd();
144
176
  } if (rf & 2) {
145
- const pin_r10 = i0.ɵɵnextContext().$implicit;
146
- const ctx_r2 = i0.ɵɵnextContext(3);
147
- i0.ɵɵstyleProp("background", "linear-gradient(135deg, " + ctx_r2.GetPinAccentColor(pin_r10) + " 0%, " + ctx_r2.GetPinAccentColor(pin_r10) + "cc 100%)");
177
+ const section_r11 = i0.ɵɵnextContext().$implicit;
178
+ const ctx_r2 = i0.ɵɵnextContext(4);
148
179
  i0.ɵɵadvance();
149
- i0.ɵɵclassMap(ctx_r2.GetPinIcon(pin_r10));
180
+ i0.ɵɵconditional(ctx_r2.EditMode && ctx_r2.EditingGroupName === section_r11.Group ? 1 : 2);
181
+ i0.ɵɵadvance(4);
182
+ i0.ɵɵtextInterpolate1("", section_r11.Pins.length, " pins");
150
183
  i0.ɵɵadvance();
151
- i0.ɵɵconditional(!ctx_r2.EditMode ? 2 : -1);
184
+ i0.ɵɵconditional(ctx_r2.EditMode ? 6 : -1);
152
185
  } }
153
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
154
- const _r14 = i0.ɵɵgetCurrentView();
155
- i0.ɵɵelementStart(0, "div", 55)(1, "button", 56);
156
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_4_Conditional_2_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r14); const pin_r10 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.OnPinClick(pin_r10); return i0.ɵɵresetView($event.stopPropagation()); });
186
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
187
+ const _r16 = i0.ɵɵgetCurrentView();
188
+ i0.ɵɵelementStart(0, "div", 67)(1, "div", 77);
189
+ i0.ɵɵelement(2, "i", 78);
190
+ i0.ɵɵelementEnd();
191
+ i0.ɵɵelementStart(3, "div", 79)(4, "button", 80);
192
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_1_Template_button_click_4_listener($event) { i0.ɵɵrestoreView(_r16); const pin_r15 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); ctx_r2.RemovePin(pin_r15.Id); return i0.ɵɵresetView($event.stopPropagation()); });
193
+ i0.ɵɵelement(5, "i", 81);
194
+ i0.ɵɵelementEnd()()();
195
+ } }
196
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
197
+ const _r17 = i0.ɵɵgetCurrentView();
198
+ i0.ɵɵelementStart(0, "div", 83)(1, "button", 39);
199
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_2_Conditional_2_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r17); const pin_r15 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); ctx_r2.OnPinClick(pin_r15); return i0.ɵɵresetView($event.stopPropagation()); });
157
200
  i0.ɵɵtext(2, "Open");
158
201
  i0.ɵɵelementEnd()();
202
+ } if (rf & 2) {
203
+ const pin_r15 = i0.ɵɵnextContext(2).$implicit;
204
+ const ctx_r2 = i0.ɵɵnextContext(5);
205
+ i0.ɵɵadvance();
206
+ i0.ɵɵattribute("aria-label", "Open " + ctx_r2.PinName(pin_r15));
159
207
  } }
160
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
161
- i0.ɵɵelementStart(0, "div", 58);
162
- i0.ɵɵelement(1, "i");
163
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_4_Conditional_2_Template, 3, 0, "div", 55);
208
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
209
+ i0.ɵɵelementStart(0, "div", 68);
210
+ i0.ɵɵelement(1, "img", 82);
211
+ i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_2_Conditional_2_Template, 3, 1, "div", 83);
164
212
  i0.ɵɵelementEnd();
165
213
  } if (rf & 2) {
166
- const pin_r10 = i0.ɵɵnextContext().$implicit;
167
- const ctx_r2 = i0.ɵɵnextContext(3);
168
- i0.ɵɵstyleProp("--pin-icon-color", pin_r10.Color || "var(--mj-text-muted)");
214
+ const pin_r15 = i0.ɵɵnextContext().$implicit;
215
+ const ctx_r2 = i0.ɵɵnextContext(5);
169
216
  i0.ɵɵadvance();
170
- i0.ɵɵclassMap(ctx_r2.GetPinIcon(pin_r10));
217
+ i0.ɵɵproperty("src", pin_r15.Thumbnail, i0.ɵɵsanitizeUrl)("alt", ctx_r2.PinName(pin_r15));
171
218
  i0.ɵɵadvance();
172
219
  i0.ɵɵconditional(!ctx_r2.EditMode ? 2 : -1);
173
220
  } }
174
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
175
- const _r15 = i0.ɵɵgetCurrentView();
176
- i0.ɵɵelementStart(0, "input", 59);
177
- i0.ɵɵlistener("blur", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_6_Template_input_blur_0_listener($event) { i0.ɵɵrestoreView(_r15); const pin_r10 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.SavePinName(pin_r10.Id, ctx_r2.GetInputValue($event))); })("keydown.enter", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_6_Template_input_keydown_enter_0_listener($event) { i0.ɵɵrestoreView(_r15); const pin_r10 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.SavePinName(pin_r10.Id, ctx_r2.GetInputValue($event))); })("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_6_Template_input_click_0_listener($event) { return $event.stopPropagation(); });
178
- i0.ɵɵelementEnd();
221
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
222
+ const _r18 = i0.ɵɵgetCurrentView();
223
+ i0.ɵɵelementStart(0, "div", 83)(1, "button", 39);
224
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_3_Conditional_2_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r18); const pin_r15 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); ctx_r2.OnPinClick(pin_r15); return i0.ɵɵresetView($event.stopPropagation()); });
225
+ i0.ɵɵtext(2, "Run");
226
+ i0.ɵɵelementEnd()();
179
227
  } if (rf & 2) {
180
- const pin_r10 = i0.ɵɵnextContext().$implicit;
181
- i0.ɵɵproperty("value", pin_r10.DisplayName);
182
- } }
183
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
184
- const _r17 = i0.ɵɵgetCurrentView();
185
- i0.ɵɵelementStart(0, "button", 62);
186
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_7_Conditional_2_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r17); const pin_r10 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.ShowPinMenu($event, pin_r10)); });
187
- i0.ɵɵelement(1, "i", 63);
188
- i0.ɵɵelementEnd();
228
+ const pin_r15 = i0.ɵɵnextContext(2).$implicit;
229
+ const ctx_r2 = i0.ɵɵnextContext(5);
230
+ i0.ɵɵadvance();
231
+ i0.ɵɵattribute("aria-label", "Run " + ctx_r2.PinName(pin_r15));
189
232
  } }
190
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
191
- const _r16 = i0.ɵɵgetCurrentView();
192
- i0.ɵɵelementStart(0, "div", 60);
193
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_7_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r16); const pin_r10 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.EditMode ? ctx_r2.StartEditingPin(pin_r10.Id, $event) : null); });
194
- i0.ɵɵtext(1);
195
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_7_Conditional_2_Template, 2, 0, "button", 61);
233
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
234
+ i0.ɵɵelementStart(0, "div", 84);
235
+ i0.ɵɵelement(1, "i", 85);
236
+ i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_3_Conditional_2_Template, 3, 1, "div", 83);
196
237
  i0.ɵɵelementEnd();
197
238
  } if (rf & 2) {
198
- const pin_r10 = i0.ɵɵnextContext().$implicit;
199
- const ctx_r2 = i0.ɵɵnextContext(3);
239
+ const pin_r15 = i0.ɵɵnextContext().$implicit;
240
+ const ctx_r2 = i0.ɵɵnextContext(5);
241
+ i0.ɵɵstyleProp("background", "linear-gradient(135deg, " + ctx_r2.GetPinAccentColor(pin_r15) + " 0%, " + ctx_r2.GetPinAccentColor(pin_r15) + "cc 100%)");
200
242
  i0.ɵɵadvance();
201
- i0.ɵɵtextInterpolate1(" ", pin_r10.DisplayName, " ");
243
+ i0.ɵɵclassMap(ctx_r2.GetPinIcon(pin_r15));
202
244
  i0.ɵɵadvance();
203
245
  i0.ɵɵconditional(!ctx_r2.EditMode ? 2 : -1);
204
246
  } }
205
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_11_Template(rf, ctx) { if (rf & 1) {
206
- i0.ɵɵelementStart(0, "span", 49);
207
- i0.ɵɵtext(1);
208
- i0.ɵɵelementEnd();
247
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
248
+ const _r19 = i0.ɵɵgetCurrentView();
249
+ i0.ɵɵelementStart(0, "div", 83)(1, "button", 39);
250
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_4_Conditional_2_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r19); const pin_r15 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); ctx_r2.OnPinClick(pin_r15); return i0.ɵɵresetView($event.stopPropagation()); });
251
+ i0.ɵɵtext(2, "Open");
252
+ i0.ɵɵelementEnd()();
209
253
  } if (rf & 2) {
210
- const pin_r10 = i0.ɵɵnextContext().$implicit;
254
+ const pin_r15 = i0.ɵɵnextContext(2).$implicit;
255
+ const ctx_r2 = i0.ɵɵnextContext(5);
211
256
  i0.ɵɵadvance();
212
- i0.ɵɵtextInterpolate(pin_r10.ApplicationName);
257
+ i0.ɵɵattribute("aria-label", "Open " + ctx_r2.PinName(pin_r15));
213
258
  } }
214
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Template(rf, ctx) { if (rf & 1) {
215
- const _r9 = i0.ɵɵgetCurrentView();
216
- i0.ɵɵelementStart(0, "div", 40);
217
- i0.ɵɵlistener("dragstart", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Template_div_dragstart_0_listener($event) { const pin_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnDragStart($event, pin_r10)); })("dragover", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Template_div_dragover_0_listener($event) { const pin_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnDragOver($event, pin_r10)); })("dragleave", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Template_div_dragleave_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnDragLeave()); })("drop", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Template_div_drop_0_listener($event) { const pin_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnDrop($event, pin_r10)); })("dragend", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnDragEnd()); })("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Template_div_click_0_listener() { const pin_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPinClick(pin_r10)); });
218
- i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_1_Template, 6, 0, "div", 41);
219
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_2_Template, 3, 3, "div", 42)(3, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_3_Template, 3, 5, "div", 43)(4, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_4_Template, 3, 5, "div", 44);
220
- i0.ɵɵelementStart(5, "div", 45);
221
- i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_6_Template, 1, 1, "input", 46)(7, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_7_Template, 3, 2, "div", 47);
222
- i0.ɵɵelementStart(8, "div", 48);
223
- i0.ɵɵelement(9, "i");
224
- i0.ɵɵtext(10);
225
- i0.ɵɵconditionalCreate(11, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Conditional_11_Template, 2, 1, "span", 49);
226
- i0.ɵɵelementEnd()()();
259
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
260
+ i0.ɵɵelementStart(0, "div", 70);
261
+ i0.ɵɵelement(1, "i", 85);
262
+ i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_4_Conditional_2_Template, 3, 1, "div", 83);
263
+ i0.ɵɵelementEnd();
227
264
  } if (rf & 2) {
228
- const pin_r10 = ctx.$implicit;
229
- const ctx_r2 = i0.ɵɵnextContext(3);
230
- i0.ɵɵclassProp("edit-mode", ctx_r2.EditMode)("dragging", ctx_r2.DraggingPinId === pin_r10.Id)("drag-over", ctx_r2.DragOverPinId === pin_r10.Id);
231
- i0.ɵɵproperty("draggable", ctx_r2.EditMode);
265
+ const pin_r15 = i0.ɵɵnextContext().$implicit;
266
+ const ctx_r2 = i0.ɵɵnextContext(5);
232
267
  i0.ɵɵadvance();
233
- i0.ɵɵconditional(ctx_r2.EditMode ? 1 : -1);
268
+ i0.ɵɵclassMap(ctx_r2.GetPinIcon(pin_r15));
234
269
  i0.ɵɵadvance();
235
- i0.ɵɵconditional(pin_r10.Thumbnail ? 2 : pin_r10.ResourceType === "Actions" ? 3 : 4);
236
- i0.ɵɵadvance(4);
237
- i0.ɵɵconditional(ctx_r2.EditMode && ctx_r2.EditingPinId === pin_r10.Id ? 6 : 7);
238
- i0.ɵɵadvance(3);
239
- i0.ɵɵclassMap(ctx_r2.GetPinIcon(pin_r10));
240
- i0.ɵɵadvance();
241
- i0.ɵɵtextInterpolate1(" ", ctx_r2.GetResourceTypeLabel(pin_r10), " ");
242
- i0.ɵɵadvance();
243
- i0.ɵɵconditional(pin_r10.ApplicationName && pin_r10.ResourceType !== "Custom" ? 11 : -1);
270
+ i0.ɵɵconditional(!ctx_r2.EditMode ? 2 : -1);
244
271
  } }
245
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
246
- const _r18 = i0.ɵɵgetCurrentView();
247
- i0.ɵɵelementStart(0, "input", 70);
248
- i0.ɵɵlistener("blur", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Conditional_1_Template_input_blur_0_listener($event) { i0.ɵɵrestoreView(_r18); const group_r19 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.SaveGroupName(group_r19, ctx_r2.GetInputValue($event))); })("keydown.enter", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Conditional_1_Template_input_keydown_enter_0_listener($event) { i0.ɵɵrestoreView(_r18); const group_r19 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.SaveGroupName(group_r19, ctx_r2.GetInputValue($event))); });
272
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
273
+ const _r20 = i0.ɵɵgetCurrentView();
274
+ i0.ɵɵelementStart(0, "input", 86);
275
+ i0.ɵɵlistener("blur", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_6_Template_input_blur_0_listener($event) { i0.ɵɵrestoreView(_r20); const pin_r15 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.SavePinName(pin_r15.Id, ctx_r2.GetInputValue($event))); })("keydown.enter", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_6_Template_input_keydown_enter_0_listener($event) { i0.ɵɵrestoreView(_r20); const pin_r15 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OnPinNameEnter(pin_r15.Id, $event)); })("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_6_Template_input_click_0_listener($event) { return $event.stopPropagation(); });
249
276
  i0.ɵɵelementEnd();
250
277
  } if (rf & 2) {
251
- const group_r19 = i0.ɵɵnextContext().$implicit;
252
- i0.ɵɵproperty("value", group_r19);
278
+ const pin_r15 = i0.ɵɵnextContext().$implicit;
279
+ const ctx_r2 = i0.ɵɵnextContext(5);
280
+ i0.ɵɵproperty("value", ctx_r2.PinName(pin_r15));
281
+ i0.ɵɵattribute("aria-label", "Name of " + ctx_r2.PinName(pin_r15));
253
282
  } }
254
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
255
- const _r20 = i0.ɵɵgetCurrentView();
256
- i0.ɵɵelementStart(0, "span", 71);
257
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Conditional_2_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r20); const group_r19 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.EditMode ? ctx_r2.StartEditingGroup(group_r19) : null); });
258
- i0.ɵɵtext(1);
283
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_7_Conditional_3_Template(rf, ctx) { if (rf & 1) {
284
+ const _r22 = i0.ɵɵgetCurrentView();
285
+ i0.ɵɵelementStart(0, "button", 90);
286
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_7_Conditional_3_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r22); const pin_r15 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.ShowPinMenu($event, pin_r15)); });
287
+ i0.ɵɵelement(1, "i", 91);
259
288
  i0.ɵɵelementEnd();
260
289
  } if (rf & 2) {
261
- const group_r19 = i0.ɵɵnextContext().$implicit;
262
- i0.ɵɵadvance();
263
- i0.ɵɵtextInterpolate(group_r19);
290
+ const pin_r15 = i0.ɵɵnextContext(2).$implicit;
291
+ const ctx_r2 = i0.ɵɵnextContext(5);
292
+ i0.ɵɵattribute("aria-label", "Pin options for " + ctx_r2.PinName(pin_r15))("aria-expanded", (ctx_r2.PinMenuPin == null ? null : ctx_r2.PinMenuPin.Id) === pin_r15.Id);
264
293
  } }
265
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Conditional_6_Template(rf, ctx) { if (rf & 1) {
294
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
266
295
  const _r21 = i0.ɵɵgetCurrentView();
267
- i0.ɵɵelementStart(0, "div", 69)(1, "button", 72);
268
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Conditional_6_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r21); const group_r19 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.RemoveGroup(group_r19)); });
269
- i0.ɵɵelement(2, "i", 73);
270
- i0.ɵɵtext(3, " Remove Group ");
271
- i0.ɵɵelementEnd()();
272
- } }
273
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_1_Template(rf, ctx) { if (rf & 1) {
274
- const _r24 = i0.ɵɵgetCurrentView();
275
- i0.ɵɵelementStart(0, "div", 41)(1, "div", 50);
276
- i0.ɵɵelement(2, "i", 51);
296
+ i0.ɵɵelementStart(0, "div", 87);
297
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_7_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r21); const pin_r15 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.EditMode ? ctx_r2.StartEditingPin(pin_r15.Id, $event) : null); });
298
+ i0.ɵɵelementStart(1, "span", 88);
299
+ i0.ɵɵtext(2);
277
300
  i0.ɵɵelementEnd();
278
- i0.ɵɵelementStart(3, "div", 52)(4, "button", 53);
279
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_1_Template_button_click_4_listener($event) { i0.ɵɵrestoreView(_r24); const pin_r23 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(4); ctx_r2.RemovePin(pin_r23.Id); return i0.ɵɵresetView($event.stopPropagation()); });
280
- i0.ɵɵelement(5, "i", 36);
281
- i0.ɵɵelementEnd()()();
282
- } }
283
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
284
- const _r25 = i0.ɵɵgetCurrentView();
285
- i0.ɵɵelementStart(0, "div", 55)(1, "button", 56);
286
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_2_Conditional_2_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r25); const pin_r23 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); ctx_r2.OnPinClick(pin_r23); return i0.ɵɵresetView($event.stopPropagation()); });
287
- i0.ɵɵtext(2, "Open");
288
- i0.ɵɵelementEnd()();
289
- } }
290
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_2_Template(rf, ctx) { if (rf & 1) {
291
- i0.ɵɵelementStart(0, "div", 42);
292
- i0.ɵɵelement(1, "img", 54);
293
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_2_Conditional_2_Template, 3, 0, "div", 55);
301
+ i0.ɵɵconditionalCreate(3, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_7_Conditional_3_Template, 2, 2, "button", 89);
294
302
  i0.ɵɵelementEnd();
295
303
  } if (rf & 2) {
296
- const pin_r23 = i0.ɵɵnextContext().$implicit;
297
- const ctx_r2 = i0.ɵɵnextContext(4);
298
- i0.ɵɵadvance();
299
- i0.ɵɵproperty("src", pin_r23.Thumbnail, i0.ɵɵsanitizeUrl)("alt", pin_r23.DisplayName);
304
+ const pin_r15 = i0.ɵɵnextContext().$implicit;
305
+ const ctx_r2 = i0.ɵɵnextContext(5);
306
+ i0.ɵɵadvance(2);
307
+ i0.ɵɵtextInterpolate(ctx_r2.PinName(pin_r15));
300
308
  i0.ɵɵadvance();
301
- i0.ɵɵconditional(!ctx_r2.EditMode ? 2 : -1);
309
+ i0.ɵɵconditional(!ctx_r2.EditMode ? 3 : -1);
302
310
  } }
303
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
304
- const _r26 = i0.ɵɵgetCurrentView();
305
- i0.ɵɵelementStart(0, "div", 55)(1, "button", 56);
306
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_3_Conditional_2_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r26); const pin_r23 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); ctx_r2.OnPinClick(pin_r23); return i0.ɵɵresetView($event.stopPropagation()); });
307
- i0.ɵɵtext(2, "Run");
308
- i0.ɵɵelementEnd()();
311
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
312
+ i0.ɵɵelement(0, "i", 75);
309
313
  } }
310
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_3_Template(rf, ctx) { if (rf & 1) {
311
- i0.ɵɵelementStart(0, "div", 57);
312
- i0.ɵɵelement(1, "i");
313
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_3_Conditional_2_Template, 3, 0, "div", 55);
314
- i0.ɵɵelementEnd();
315
- } if (rf & 2) {
316
- const pin_r23 = i0.ɵɵnextContext().$implicit;
317
- const ctx_r2 = i0.ɵɵnextContext(4);
318
- i0.ɵɵstyleProp("background", "linear-gradient(135deg, " + ctx_r2.GetPinAccentColor(pin_r23) + " 0%, " + ctx_r2.GetPinAccentColor(pin_r23) + "cc 100%)");
314
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Template(rf, ctx) { if (rf & 1) {
315
+ const _r14 = i0.ɵɵgetCurrentView();
316
+ i0.ɵɵelementStart(0, "div", 66);
317
+ i0.ɵɵlistener("dragstart", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Template_div_dragstart_0_listener($event) { const pin_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OnDragStart($event, pin_r15)); })("dragover", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Template_div_dragover_0_listener($event) { const pin_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OnDragOver($event, pin_r15)); })("dragleave", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Template_div_dragleave_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OnDragLeave()); })("drop", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Template_div_drop_0_listener($event) { const pin_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OnDrop($event, pin_r15)); })("dragend", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OnDragEnd()); })("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Template_div_click_0_listener() { const pin_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OnPinClick(pin_r15)); });
318
+ i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_1_Template, 6, 0, "div", 67);
319
+ i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_2_Template, 3, 3, "div", 68)(3, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_3_Template, 3, 5, "div", 69)(4, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_4_Template, 3, 3, "div", 70);
320
+ i0.ɵɵelementStart(5, "div", 71);
321
+ i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_6_Template, 1, 2, "input", 72)(7, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_7_Template, 4, 2, "div", 73);
322
+ i0.ɵɵelementStart(8, "div", 74);
323
+ i0.ɵɵconditionalCreate(9, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Conditional_9_Template, 1, 0, "i", 75);
324
+ i0.ɵɵelementStart(10, "span", 76);
325
+ i0.ɵɵtext(11);
326
+ i0.ɵɵelementEnd()()()();
327
+ } if (rf & 2) {
328
+ const pin_r15 = ctx.$implicit;
329
+ const ctx_r2 = i0.ɵɵnextContext(5);
330
+ i0.ɵɵclassProp("edit-mode", ctx_r2.EditMode)("dragging", ctx_r2.DraggingPinId === pin_r15.Id)("drag-over", ctx_r2.DragOverPinId === pin_r15.Id)("menu-open", (ctx_r2.PinMenuPin == null ? null : ctx_r2.PinMenuPin.Id) === pin_r15.Id);
331
+ i0.ɵɵproperty("draggable", ctx_r2.EditMode);
319
332
  i0.ɵɵadvance();
320
- i0.ɵɵclassMap(ctx_r2.GetPinIcon(pin_r23));
333
+ i0.ɵɵconditional(ctx_r2.EditMode ? 1 : -1);
321
334
  i0.ɵɵadvance();
322
- i0.ɵɵconditional(!ctx_r2.EditMode ? 2 : -1);
323
- } }
324
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
325
- const _r27 = i0.ɵɵgetCurrentView();
326
- i0.ɵɵelementStart(0, "div", 55)(1, "button", 56);
327
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_4_Conditional_2_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r27); const pin_r23 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); ctx_r2.OnPinClick(pin_r23); return i0.ɵɵresetView($event.stopPropagation()); });
328
- i0.ɵɵtext(2, "Open");
329
- i0.ɵɵelementEnd()();
335
+ i0.ɵɵconditional(pin_r15.Thumbnail ? 2 : pin_r15.ResourceType === "Actions" ? 3 : 4);
336
+ i0.ɵɵadvance(4);
337
+ i0.ɵɵconditional(ctx_r2.EditMode && ctx_r2.EditingPinId === pin_r15.Id ? 6 : 7);
338
+ i0.ɵɵadvance(3);
339
+ i0.ɵɵconditional(pin_r15.ResourceType === "Dashboards" ? 9 : -1);
340
+ i0.ɵɵadvance(2);
341
+ i0.ɵɵtextInterpolate(ctx_r2.GetResourceTypeLabel(pin_r15));
330
342
  } }
331
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_4_Template(rf, ctx) { if (rf & 1) {
332
- i0.ɵɵelementStart(0, "div", 58);
333
- i0.ɵɵelement(1, "i");
334
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_4_Conditional_2_Template, 3, 0, "div", 55);
335
- i0.ɵɵelementEnd();
343
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
344
+ i0.ɵɵconditionalCreate(0, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Conditional_0_Template, 7, 3, "div", 55);
345
+ i0.ɵɵrepeaterCreate(1, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_For_2_Template, 12, 14, "div", 56, _forTrack1);
336
346
  } if (rf & 2) {
337
- const pin_r23 = i0.ɵɵnextContext().$implicit;
338
- const ctx_r2 = i0.ɵɵnextContext(4);
339
- i0.ɵɵstyleProp("--pin-icon-color", pin_r23.Color || "var(--mj-text-muted)");
347
+ const section_r11 = ctx.$implicit;
348
+ i0.ɵɵconditional(section_r11.Group !== null ? 0 : -1);
340
349
  i0.ɵɵadvance();
341
- i0.ɵɵclassMap(ctx_r2.GetPinIcon(pin_r23));
342
- i0.ɵɵadvance();
343
- i0.ɵɵconditional(!ctx_r2.EditMode ? 2 : -1);
350
+ i0.ɵɵrepeater(section_r11.Pins);
344
351
  } }
345
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_6_Template(rf, ctx) { if (rf & 1) {
346
- const _r28 = i0.ɵɵgetCurrentView();
347
- i0.ɵɵelementStart(0, "input", 59);
348
- i0.ɵɵlistener("blur", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_6_Template_input_blur_0_listener($event) { i0.ɵɵrestoreView(_r28); const pin_r23 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.SavePinName(pin_r23.Id, $event.target.value)); })("keydown.enter", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_6_Template_input_keydown_enter_0_listener($event) { i0.ɵɵrestoreView(_r28); const pin_r23 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.SavePinName(pin_r23.Id, $event.target.value)); })("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_6_Template_input_click_0_listener($event) { return $event.stopPropagation(); });
349
- i0.ɵɵelementEnd();
350
- } if (rf & 2) {
351
- const pin_r23 = i0.ɵɵnextContext().$implicit;
352
- i0.ɵɵproperty("value", pin_r23.DisplayName);
352
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
353
+ const _r23 = i0.ɵɵgetCurrentView();
354
+ i0.ɵɵelementStart(0, "div", 92);
355
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_Conditional_3_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.OpenAddPinPanel()); });
356
+ i0.ɵɵelement(1, "i", 36);
357
+ i0.ɵɵelementStart(2, "span");
358
+ i0.ɵɵtext(3, "Add Pin");
359
+ i0.ɵɵelementEnd()();
353
360
  } }
354
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
355
- i0.ɵɵelementStart(0, "button", 62);
356
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_7_Conditional_2_Template_button_click_0_listener($event) { return $event.stopPropagation(); });
357
- i0.ɵɵelement(1, "i", 63);
361
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_Template(rf, ctx) { if (rf & 1) {
362
+ i0.ɵɵelementStart(0, "div", 44);
363
+ i0.ɵɵrepeaterCreate(1, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_For_2_Template, 3, 1, null, null, _forTrack0);
364
+ i0.ɵɵconditionalCreate(3, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_Conditional_3_Template, 4, 0, "div", 54);
358
365
  i0.ɵɵelementEnd();
366
+ } if (rf & 2) {
367
+ const ctx_r2 = i0.ɵɵnextContext(3);
368
+ i0.ɵɵadvance();
369
+ i0.ɵɵrepeater(ctx_r2.PinSections);
370
+ i0.ɵɵadvance(2);
371
+ i0.ɵɵconditional(ctx_r2.EditMode ? 3 : -1);
359
372
  } }
360
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_7_Template(rf, ctx) { if (rf & 1) {
361
- const _r29 = i0.ɵɵgetCurrentView();
362
- i0.ɵɵelementStart(0, "div", 60);
363
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_7_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r29); const pin_r23 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.EditMode ? ctx_r2.StartEditingPin(pin_r23.Id, $event) : null); });
364
- i0.ɵɵtext(1);
365
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_7_Conditional_2_Template, 2, 0, "button", 61);
373
+ function HomeDashboardComponent_Conditional_2_ng_template_10_Template(rf, ctx) { if (rf & 1) {
374
+ i0.ɵɵelementStart(0, "div", 41);
375
+ i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_1_Template, 6, 0, "div", 42);
376
+ i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_2_Template, 7, 2, "div", 43);
377
+ i0.ɵɵconditionalCreate(3, HomeDashboardComponent_Conditional_2_ng_template_10_Conditional_3_Template, 4, 1, "div", 44);
366
378
  i0.ɵɵelementEnd();
367
379
  } if (rf & 2) {
368
- const pin_r23 = i0.ɵɵnextContext().$implicit;
369
- const ctx_r2 = i0.ɵɵnextContext(4);
380
+ const ctx_r2 = i0.ɵɵnextContext(2);
381
+ i0.ɵɵadvance();
382
+ i0.ɵɵconditional(ctx_r2.EditMode ? 1 : -1);
370
383
  i0.ɵɵadvance();
371
- i0.ɵɵtextInterpolate1(" ", pin_r23.DisplayName, " ");
384
+ i0.ɵɵconditional(ctx_r2.PinnedItems.length === 0 && (ctx_r2.EditMode || !ctx_r2.HidePinEmptyState) ? 2 : -1);
372
385
  i0.ɵɵadvance();
373
- i0.ɵɵconditional(!ctx_r2.EditMode ? 2 : -1);
386
+ i0.ɵɵconditional(ctx_r2.PinnedItems.length > 0 ? 3 : -1);
374
387
  } }
375
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_11_Template(rf, ctx) { if (rf & 1) {
376
- i0.ɵɵelementStart(0, "span", 49);
388
+ function HomeDashboardComponent_Conditional_2_For_16_Conditional_6_Template(rf, ctx) { if (rf & 1) {
389
+ i0.ɵɵelementStart(0, "p", 97);
377
390
  i0.ɵɵtext(1);
378
391
  i0.ɵɵelementEnd();
379
392
  } if (rf & 2) {
380
- const pin_r23 = i0.ɵɵnextContext().$implicit;
393
+ const appData_r25 = i0.ɵɵnextContext().$implicit;
381
394
  i0.ɵɵadvance();
382
- i0.ɵɵtextInterpolate(pin_r23.ApplicationName);
395
+ i0.ɵɵtextInterpolate(appData_r25.app.Description);
383
396
  } }
384
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Template(rf, ctx) { if (rf & 1) {
385
- const _r22 = i0.ɵɵgetCurrentView();
386
- i0.ɵɵelementStart(0, "div", 40);
387
- i0.ɵɵlistener("dragstart", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Template_div_dragstart_0_listener($event) { const pin_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.OnDragStart($event, pin_r23)); })("dragover", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Template_div_dragover_0_listener($event) { const pin_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.OnDragOver($event, pin_r23)); })("dragleave", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Template_div_dragleave_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.OnDragLeave()); })("drop", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Template_div_drop_0_listener($event) { const pin_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.OnDrop($event, pin_r23)); })("dragend", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.OnDragEnd()); })("click", function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Template_div_click_0_listener() { const pin_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.OnPinClick(pin_r23)); });
388
- i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_1_Template, 6, 0, "div", 41);
389
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_2_Template, 3, 3, "div", 42)(3, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_3_Template, 3, 5, "div", 43)(4, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_4_Template, 3, 5, "div", 44);
390
- i0.ɵɵelementStart(5, "div", 45);
391
- i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_6_Template, 1, 1, "input", 46)(7, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_7_Template, 3, 2, "div", 47);
392
- i0.ɵɵelementStart(8, "div", 48);
393
- i0.ɵɵelement(9, "i");
394
- i0.ɵɵtext(10);
395
- i0.ɵɵconditionalCreate(11, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Conditional_11_Template, 2, 1, "span", 49);
396
- i0.ɵɵelementEnd()()();
397
+ function HomeDashboardComponent_Conditional_2_For_16_Template(rf, ctx) { if (rf & 1) {
398
+ const _r24 = i0.ɵɵgetCurrentView();
399
+ i0.ɵɵelementStart(0, "div", 93);
400
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_2_For_16_Template_div_click_0_listener() { const appData_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnAppClick(appData_r25.app)); });
401
+ i0.ɵɵelementStart(1, "div", 94);
402
+ i0.ɵɵelement(2, "i");
403
+ i0.ɵɵelementEnd();
404
+ i0.ɵɵelementStart(3, "div", 95)(4, "h3", 96);
405
+ i0.ɵɵtext(5);
406
+ i0.ɵɵelementEnd();
407
+ i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_2_For_16_Conditional_6_Template, 2, 1, "p", 97);
408
+ i0.ɵɵelementEnd()();
397
409
  } if (rf & 2) {
398
- const pin_r23 = ctx.$implicit;
399
- const ctx_r2 = i0.ɵɵnextContext(4);
400
- i0.ɵɵclassProp("edit-mode", ctx_r2.EditMode)("dragging", ctx_r2.DraggingPinId === pin_r23.Id)("drag-over", ctx_r2.DragOverPinId === pin_r23.Id);
401
- i0.ɵɵproperty("draggable", ctx_r2.EditMode);
402
- i0.ɵɵadvance();
403
- i0.ɵɵconditional(ctx_r2.EditMode ? 1 : -1);
404
- i0.ɵɵadvance();
405
- i0.ɵɵconditional(pin_r23.Thumbnail ? 2 : pin_r23.ResourceType === "Actions" ? 3 : 4);
406
- i0.ɵɵadvance(4);
407
- i0.ɵɵconditional(ctx_r2.EditMode && ctx_r2.EditingPinId === pin_r23.Id ? 6 : 7);
410
+ const appData_r25 = ctx.$implicit;
411
+ i0.ɵɵstyleProp("--app-color", appData_r25.color);
412
+ i0.ɵɵproperty("mjClickable", appData_r25.app.Name)("TestId", "app-tile-" + appData_r25.app.Name);
413
+ i0.ɵɵadvance(2);
414
+ i0.ɵɵclassMap(appData_r25.icon);
408
415
  i0.ɵɵadvance(3);
409
- i0.ɵɵclassMap(ctx_r2.GetPinIcon(pin_r23));
410
- i0.ɵɵadvance();
411
- i0.ɵɵtextInterpolate1(" ", ctx_r2.GetResourceTypeLabel(pin_r23), " ");
416
+ i0.ɵɵtextInterpolate(appData_r25.app.Name);
412
417
  i0.ɵɵadvance();
413
- i0.ɵɵconditional(pin_r23.ApplicationName ? 11 : -1);
418
+ i0.ɵɵconditional(appData_r25.app.Description ? 6 : -1);
414
419
  } }
415
- function HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Template(rf, ctx) { if (rf & 1) {
416
- i0.ɵɵelementStart(0, "div", 64);
417
- i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Conditional_1_Template, 1, 1, "input", 65)(2, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Conditional_2_Template, 2, 1, "span", 66);
418
- i0.ɵɵelement(3, "div", 67);
419
- i0.ɵɵelementStart(4, "span", 68);
420
- i0.ɵɵtext(5);
420
+ function HomeDashboardComponent_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
421
+ const _r26 = i0.ɵɵgetCurrentView();
422
+ i0.ɵɵelementStart(0, "mj-empty-state", 98);
423
+ i0.ɵɵlistener("Action", function HomeDashboardComponent_Conditional_2_Conditional_17_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OpenConfigDialog()); });
424
+ i0.ɵɵelementEnd();
425
+ } }
426
+ function HomeDashboardComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
427
+ const _r2 = i0.ɵɵgetCurrentView();
428
+ i0.ɵɵelementStart(0, "div", 6)(1, "div", 16)(2, "div", 17)(3, "h1");
429
+ i0.ɵɵtext(4);
430
+ i0.ɵɵelementEnd();
431
+ i0.ɵɵelementStart(5, "p", 18);
432
+ i0.ɵɵtext(6);
433
+ i0.ɵɵelementEnd()()();
434
+ i0.ɵɵelementStart(7, "mj-accordion-panel", 19);
435
+ i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_2_Template_mj_accordion_panel_ExpandedChange_7_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnPinnedExpandedChange($event)); });
436
+ i0.ɵɵtemplate(8, HomeDashboardComponent_Conditional_2_ng_template_8_Template, 3, 0, "ng-template", 20)(9, HomeDashboardComponent_Conditional_2_ng_template_9_Template, 3, 1, "ng-template", 21)(10, HomeDashboardComponent_Conditional_2_ng_template_10_Template, 4, 3, "ng-template", 22);
421
437
  i0.ɵɵelementEnd();
422
- i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Conditional_6_Template, 4, 0, "div", 69);
438
+ i0.ɵɵelementStart(11, "section", 23)(12, "h2", 24);
439
+ i0.ɵɵtext(13, "My applications");
423
440
  i0.ɵɵelementEnd();
424
- i0.ɵɵrepeaterCreate(7, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_For_8_Template, 12, 14, "div", 38, i0.ɵɵcomponentInstance().trackByPin, true);
441
+ i0.ɵɵelementStart(14, "div", 25);
442
+ i0.ɵɵrepeaterCreate(15, HomeDashboardComponent_Conditional_2_For_16_Template, 7, 8, "div", 26, i0.ɵɵcomponentInstance().TrackByApp, true);
443
+ i0.ɵɵelementEnd();
444
+ i0.ɵɵconditionalCreate(17, HomeDashboardComponent_Conditional_2_Conditional_17_Template, 1, 0, "mj-empty-state", 27);
445
+ i0.ɵɵelementEnd()();
425
446
  } if (rf & 2) {
426
- const group_r19 = ctx.$implicit;
427
- const ctx_r2 = i0.ɵɵnextContext(3);
428
- i0.ɵɵadvance();
429
- i0.ɵɵconditional(ctx_r2.EditMode && ctx_r2.EditingGroupName === group_r19 ? 1 : 2);
447
+ const ctx_r2 = i0.ɵɵnextContext();
430
448
  i0.ɵɵadvance(4);
431
- i0.ɵɵtextInterpolate1("", ctx_r2.GetPinsInGroup(group_r19).length, " pins");
432
- i0.ɵɵadvance();
433
- i0.ɵɵconditional(ctx_r2.EditMode ? 6 : -1);
449
+ i0.ɵɵtextInterpolate2("", ctx_r2.Greeting, ", ", ctx_r2.GreetingName);
450
+ i0.ɵɵadvance(2);
451
+ i0.ɵɵtextInterpolate(ctx_r2.FormattedDate);
434
452
  i0.ɵɵadvance();
435
- i0.ɵɵrepeater(ctx_r2.GetPinsInGroup(group_r19));
436
- } }
437
- function HomeDashboardComponent_Conditional_8_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
438
- const _r30 = i0.ɵɵgetCurrentView();
439
- i0.ɵɵelementStart(0, "div", 74);
440
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_8_Conditional_10_Conditional_5_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r30); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenAddPinPanel()); });
441
- i0.ɵɵelement(1, "i", 26);
442
- i0.ɵɵelementStart(2, "span");
443
- i0.ɵɵtext(3, "Add Pin");
444
- i0.ɵɵelementEnd()();
453
+ i0.ɵɵproperty("Bare", true)("TitleIconMuted", true)("HeadingLevel", 2)("FlushBody", true)("Expanded", ctx_r2.PinnedExpanded);
454
+ i0.ɵɵadvance(8);
455
+ i0.ɵɵrepeater(ctx_r2.AppsDisplayData);
456
+ i0.ɵɵadvance(2);
457
+ i0.ɵɵconditional(ctx_r2.Apps.length === 0 ? 17 : -1);
445
458
  } }
446
- function HomeDashboardComponent_Conditional_8_Conditional_10_Template(rf, ctx) { if (rf & 1) {
447
- i0.ɵɵelementStart(0, "div", 22);
448
- i0.ɵɵrepeaterCreate(1, HomeDashboardComponent_Conditional_8_Conditional_10_For_2_Template, 12, 14, "div", 38, i0.ɵɵcomponentInstance().trackByPin, true);
449
- i0.ɵɵrepeaterCreate(3, HomeDashboardComponent_Conditional_8_Conditional_10_For_4_Template, 9, 3, null, null, i0.ɵɵcomponentInstance().trackByGroup, true);
450
- i0.ɵɵconditionalCreate(5, HomeDashboardComponent_Conditional_8_Conditional_10_Conditional_5_Template, 4, 0, "div", 39);
459
+ function HomeDashboardComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
460
+ const _r27 = i0.ɵɵgetCurrentView();
461
+ i0.ɵɵelementStart(0, "mj-dashboard-editor", 99, 2);
462
+ i0.ɵɵtwoWayListener("StartInEditModeChange", function HomeDashboardComponent_Conditional_3_Template_mj_dashboard_editor_StartInEditModeChange_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.DashboardStartsInEditMode, $event) || (ctx_r2.DashboardStartsInEditMode = $event); return i0.ɵɵresetView($event); });
463
+ i0.ɵɵlistener("Loaded", function HomeDashboardComponent_Conditional_3_Template_mj_dashboard_editor_Loaded_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnDashboardViewLoaded($event)); })("EditingChange", function HomeDashboardComponent_Conditional_3_Template_mj_dashboard_editor_EditingChange_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnDashboardEditingChange($event)); })("NameChanged", function HomeDashboardComponent_Conditional_3_Template_mj_dashboard_editor_NameChanged_0_listener() { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnDashboardSaved()); })("Saved", function HomeDashboardComponent_Conditional_3_Template_mj_dashboard_editor_Saved_0_listener() { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnDashboardSaved()); })("LoadFailed", function HomeDashboardComponent_Conditional_3_Template_mj_dashboard_editor_LoadFailed_0_listener() { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnDashboardViewLoadFailed()); })("OpenInDashboardsRequested", function HomeDashboardComponent_Conditional_3_Template_mj_dashboard_editor_OpenInDashboardsRequested_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenDashboardInDashboardsApp($event)); })("NavigationRequested", function HomeDashboardComponent_Conditional_3_Template_mj_dashboard_editor_NavigationRequested_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnDashboardNavigationRequested($event)); });
451
464
  i0.ɵɵelementEnd();
452
465
  } if (rf & 2) {
453
- const ctx_r2 = i0.ɵɵnextContext(2);
454
- i0.ɵɵadvance();
455
- i0.ɵɵrepeater(ctx_r2.UngroupedPins);
456
- i0.ɵɵadvance(2);
457
- i0.ɵɵrepeater(ctx_r2.PinGroups);
458
- i0.ɵɵadvance(2);
459
- i0.ɵɵconditional(ctx_r2.EditMode ? 5 : -1);
466
+ const ctx_r2 = i0.ɵɵnextContext();
467
+ const homeDashboardTitle_r28 = i0.ɵɵreference(5);
468
+ i0.ɵɵproperty("Provider", ctx_r2.Provider)("DashboardId", ctx_r2.CurrentDashboardId);
469
+ i0.ɵɵtwoWayProperty("StartInEditMode", ctx_r2.DashboardStartsInEditMode);
470
+ i0.ɵɵproperty("TitleTemplate", homeDashboardTitle_r28)("ShowOpenInDashboards", true);
460
471
  } }
461
- function HomeDashboardComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
462
- i0.ɵɵelementStart(0, "div", 6)(1, "div", 15)(2, "h2", 16);
463
- i0.ɵɵelement(3, "i", 17);
464
- i0.ɵɵtext(4, " Pinned ");
472
+ function HomeDashboardComponent_ng_template_4_Template(rf, ctx) { if (rf & 1) {
473
+ const _r29 = i0.ɵɵgetCurrentView();
474
+ i0.ɵɵelementStart(0, "div", 100)(1, "nav", 101)(2, "button", 102);
475
+ i0.ɵɵlistener("click", function HomeDashboardComponent_ng_template_4_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r29); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnSwitcherPick(null)); });
476
+ i0.ɵɵelement(3, "i", 103);
477
+ i0.ɵɵtext(4, " Home");
465
478
  i0.ɵɵelementEnd();
466
- i0.ɵɵelementStart(5, "div", 18);
467
- i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_8_Conditional_6_Template, 3, 0, "button", 19)(7, HomeDashboardComponent_Conditional_8_Conditional_7_Template, 4, 1);
468
- i0.ɵɵelementEnd()();
469
- i0.ɵɵconditionalCreate(8, HomeDashboardComponent_Conditional_8_Conditional_8_Template, 6, 0, "div", 20);
470
- i0.ɵɵconditionalCreate(9, HomeDashboardComponent_Conditional_8_Conditional_9_Template, 7, 2, "div", 21);
471
- i0.ɵɵconditionalCreate(10, HomeDashboardComponent_Conditional_8_Conditional_10_Template, 6, 1, "div", 22);
479
+ i0.ɵɵelementStart(5, "span", 85);
480
+ i0.ɵɵtext(6, "/");
472
481
  i0.ɵɵelementEnd();
482
+ i0.ɵɵelementStart(7, "span");
483
+ i0.ɵɵtext(8, "Pinned dashboards");
484
+ i0.ɵɵelementEnd()();
485
+ i0.ɵɵelementStart(9, "mj-home-dashboard-switcher", 104);
486
+ i0.ɵɵlistener("Pick", function HomeDashboardComponent_ng_template_4_Template_mj_home_dashboard_switcher_Pick_9_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnSwitcherPick($event)); })("New", function HomeDashboardComponent_ng_template_4_Template_mj_home_dashboard_switcher_New_9_listener() { i0.ɵɵrestoreView(_r29); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenNewDashboardDialog()); })("ManagePins", function HomeDashboardComponent_ng_template_4_Template_mj_home_dashboard_switcher_ManagePins_9_listener() { i0.ɵɵrestoreView(_r29); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ManagePins()); });
487
+ i0.ɵɵelementEnd()();
473
488
  } if (rf & 2) {
489
+ const dashboard_r30 = ctx.$implicit;
474
490
  const ctx_r2 = i0.ɵɵnextContext();
475
- i0.ɵɵadvance(6);
476
- i0.ɵɵconditional(ctx_r2.EditMode ? 6 : 7);
477
- i0.ɵɵadvance(2);
478
- i0.ɵɵconditional(ctx_r2.EditMode ? 8 : -1);
479
- i0.ɵɵadvance();
480
- i0.ɵɵconditional(ctx_r2.PinnedItems.length === 0 && (ctx_r2.EditMode || !ctx_r2.HidePinEmptyState) ? 9 : -1);
481
- i0.ɵɵadvance();
482
- i0.ɵɵconditional(ctx_r2.PinnedItems.length > 0 ? 10 : -1);
491
+ i0.ɵɵadvance(9);
492
+ i0.ɵɵproperty("HeadingLevel", 1)("Label", dashboard_r30.Name)("Dashboards", ctx_r2.PinnedDashboards)("CurrentId", dashboard_r30.ID);
483
493
  } }
484
- function HomeDashboardComponent_Conditional_9_Conditional_11_Template(rf, ctx) { if (rf & 1) {
494
+ function HomeDashboardComponent_Conditional_6_Conditional_12_Template(rf, ctx) { if (rf & 1) {
485
495
  const _r32 = i0.ɵɵgetCurrentView();
486
- i0.ɵɵelementStart(0, "div", 84);
487
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_9_Conditional_11_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnPinMenuMoveToGroup(undefined)); });
496
+ i0.ɵɵelementStart(0, "button", 114);
497
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_6_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r32); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnPinMenuMoveToGroup(undefined)); });
488
498
  i0.ɵɵelementStart(1, "span");
489
499
  i0.ɵɵtext(2, "(No group)");
490
500
  i0.ɵɵelementEnd()();
491
501
  } }
492
- function HomeDashboardComponent_Conditional_9_For_13_Conditional_0_Template(rf, ctx) { if (rf & 1) {
502
+ function HomeDashboardComponent_Conditional_6_For_14_Conditional_0_Template(rf, ctx) { if (rf & 1) {
493
503
  const _r33 = i0.ɵɵgetCurrentView();
494
- i0.ɵɵelementStart(0, "div", 84);
495
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_9_For_13_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r33); const group_r34 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnPinMenuMoveToGroup(group_r34)); });
504
+ i0.ɵɵelementStart(0, "button", 114);
505
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_6_For_14_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r33); const group_r34 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnPinMenuMoveToGroup(group_r34)); });
496
506
  i0.ɵɵelementStart(1, "span");
497
507
  i0.ɵɵtext(2);
498
508
  i0.ɵɵelementEnd()();
@@ -501,47 +511,54 @@ function HomeDashboardComponent_Conditional_9_For_13_Conditional_0_Template(rf,
501
511
  i0.ɵɵadvance(2);
502
512
  i0.ɵɵtextInterpolate(group_r34);
503
513
  } }
504
- function HomeDashboardComponent_Conditional_9_For_13_Template(rf, ctx) { if (rf & 1) {
505
- i0.ɵɵconditionalCreate(0, HomeDashboardComponent_Conditional_9_For_13_Conditional_0_Template, 3, 1, "div", 81);
514
+ function HomeDashboardComponent_Conditional_6_For_14_Template(rf, ctx) { if (rf & 1) {
515
+ i0.ɵɵconditionalCreate(0, HomeDashboardComponent_Conditional_6_For_14_Conditional_0_Template, 3, 1, "button", 111);
506
516
  } if (rf & 2) {
507
517
  const group_r34 = ctx.$implicit;
508
518
  const ctx_r2 = i0.ɵɵnextContext(2);
509
519
  i0.ɵɵconditional(group_r34 !== ctx_r2.PinMenuPin.Group ? 0 : -1);
510
520
  } }
511
- function HomeDashboardComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
521
+ function HomeDashboardComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
512
522
  const _r31 = i0.ɵɵgetCurrentView();
513
- i0.ɵɵelementStart(0, "div", 75)(1, "div", 76);
514
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_9_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnPinMenuEdit()); });
515
- i0.ɵɵelement(2, "i", 29);
516
- i0.ɵɵelementStart(3, "span");
517
- i0.ɵɵtext(4, "Edit");
523
+ i0.ɵɵelementStart(0, "div", 105, 3);
524
+ i0.ɵɵlistener("keydown", function HomeDashboardComponent_Conditional_6_Template_div_keydown_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnPinMenuKeydown($event)); });
525
+ i0.ɵɵelementStart(2, "button", 106);
526
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_6_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnPinMenuEdit()); });
527
+ i0.ɵɵelement(3, "i", 40);
528
+ i0.ɵɵelementStart(4, "span");
529
+ i0.ɵɵtext(5, "Edit");
518
530
  i0.ɵɵelementEnd()();
519
- i0.ɵɵelement(5, "div", 77);
520
- i0.ɵɵelementStart(6, "div", 78)(7, "div", 79);
521
- i0.ɵɵelement(8, "i", 80);
522
- i0.ɵɵelementStart(9, "span");
523
- i0.ɵɵtext(10, "Move to Group");
531
+ i0.ɵɵelement(6, "div", 107);
532
+ i0.ɵɵelementStart(7, "div", 108)(8, "div", 109);
533
+ i0.ɵɵelement(9, "i", 110);
534
+ i0.ɵɵelementStart(10, "span");
535
+ i0.ɵɵtext(11, "Move to Group");
524
536
  i0.ɵɵelementEnd()();
525
- i0.ɵɵconditionalCreate(11, HomeDashboardComponent_Conditional_9_Conditional_11_Template, 3, 0, "div", 81);
526
- i0.ɵɵrepeaterCreate(12, HomeDashboardComponent_Conditional_9_For_13_Template, 1, 1, null, null, i0.ɵɵrepeaterTrackByIdentity);
527
- i0.ɵɵelementEnd();
528
- i0.ɵɵelement(14, "div", 77);
529
- i0.ɵɵelementStart(15, "div", 82);
530
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_9_Template_div_click_15_listener() { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnPinMenuUnpin()); });
531
- i0.ɵɵelement(16, "i", 83);
532
- i0.ɵɵelementStart(17, "span");
533
- i0.ɵɵtext(18, "Unpin");
537
+ i0.ɵɵconditionalCreate(12, HomeDashboardComponent_Conditional_6_Conditional_12_Template, 3, 0, "button", 111);
538
+ i0.ɵɵrepeaterCreate(13, HomeDashboardComponent_Conditional_6_For_14_Template, 1, 1, null, null, i0.ɵɵrepeaterTrackByIdentity);
539
+ i0.ɵɵelementEnd();
540
+ i0.ɵɵelement(15, "div", 107);
541
+ i0.ɵɵelementStart(16, "button", 112);
542
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_6_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnPinMenuUnpin()); });
543
+ i0.ɵɵelement(17, "i", 113);
544
+ i0.ɵɵelementStart(18, "span");
545
+ i0.ɵɵtext(19, "Unpin");
534
546
  i0.ɵɵelementEnd()()();
535
547
  } if (rf & 2) {
536
548
  const ctx_r2 = i0.ɵɵnextContext();
537
- i0.ɵɵstyleProp("left", ctx_r2.PinMenuX, "px")("top", ctx_r2.PinMenuY, "px");
538
- i0.ɵɵadvance(11);
539
- i0.ɵɵconditional(ctx_r2.PinMenuPin.Group ? 11 : -1);
549
+ i0.ɵɵstyleProp("left", ctx_r2.PinMenuX, "px")("top", ctx_r2.PinMenuY, "px")("max-height", ctx_r2.PinMenuMaxHeight, "px");
550
+ i0.ɵɵattribute("aria-label", "Options for " + ctx_r2.PinName(ctx_r2.PinMenuPin));
551
+ i0.ɵɵadvance(7);
552
+ i0.ɵɵattribute("aria-labelledby", ctx_r2.PinMenuGroupLabelId);
553
+ i0.ɵɵadvance();
554
+ i0.ɵɵproperty("id", ctx_r2.PinMenuGroupLabelId);
555
+ i0.ɵɵadvance(4);
556
+ i0.ɵɵconditional(ctx_r2.PinMenuPin.Group ? 12 : -1);
540
557
  i0.ɵɵadvance();
541
558
  i0.ɵɵrepeater(ctx_r2.PinGroups);
542
559
  } }
543
- function HomeDashboardComponent_Conditional_10_For_20_Template(rf, ctx) { if (rf & 1) {
544
- i0.ɵɵelementStart(0, "option", 96);
560
+ function HomeDashboardComponent_Conditional_7_For_20_Template(rf, ctx) { if (rf & 1) {
561
+ i0.ɵɵelementStart(0, "option", 128);
545
562
  i0.ɵɵtext(1);
546
563
  i0.ɵɵelementEnd();
547
564
  } if (rf & 2) {
@@ -550,25 +567,25 @@ function HomeDashboardComponent_Conditional_10_For_20_Template(rf, ctx) { if (rf
550
567
  i0.ɵɵadvance();
551
568
  i0.ɵɵtextInterpolate(group_r36);
552
569
  } }
553
- function HomeDashboardComponent_Conditional_10_Conditional_23_Template(rf, ctx) { if (rf & 1) {
570
+ function HomeDashboardComponent_Conditional_7_Conditional_23_Template(rf, ctx) { if (rf & 1) {
554
571
  const _r37 = i0.ɵɵgetCurrentView();
555
- i0.ɵɵelementStart(0, "div", 98)(1, "input", 101);
556
- i0.ɵɵtwoWayListener("ngModelChange", function HomeDashboardComponent_Conditional_10_Conditional_23_Template_input_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r37); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.AddPanelNewGroupName, $event) || (ctx_r2.AddPanelNewGroupName = $event); return i0.ɵɵresetView($event); });
572
+ i0.ɵɵelementStart(0, "div", 130)(1, "input", 133);
573
+ i0.ɵɵtwoWayListener("ngModelChange", function HomeDashboardComponent_Conditional_7_Conditional_23_Template_input_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r37); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.AddPanelNewGroupName, $event) || (ctx_r2.AddPanelNewGroupName = $event); return i0.ɵɵresetView($event); });
557
574
  i0.ɵɵelementEnd()();
558
575
  } if (rf & 2) {
559
576
  const ctx_r2 = i0.ɵɵnextContext(2);
560
577
  i0.ɵɵadvance();
561
578
  i0.ɵɵtwoWayProperty("ngModel", ctx_r2.AddPanelNewGroupName);
562
579
  } }
563
- function HomeDashboardComponent_Conditional_10_Conditional_25_Template(rf, ctx) { if (rf & 1) {
564
- i0.ɵɵelementStart(0, "div", 100);
565
- i0.ɵɵelement(1, "mj-loading", 102);
580
+ function HomeDashboardComponent_Conditional_7_Conditional_25_Template(rf, ctx) { if (rf & 1) {
581
+ i0.ɵɵelementStart(0, "div", 132);
582
+ i0.ɵɵelement(1, "mj-loading", 134);
566
583
  i0.ɵɵelementEnd();
567
584
  } }
568
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_1_Template(rf, ctx) { if (rf & 1) {
569
- i0.ɵɵelement(0, "i", 107);
585
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_1_Template(rf, ctx) { if (rf & 1) {
586
+ i0.ɵɵelement(0, "i", 137);
570
587
  i0.ɵɵtext(1, " Applications ");
571
- i0.ɵɵelementStart(2, "span", 108);
588
+ i0.ɵɵelementStart(2, "span", 138);
572
589
  i0.ɵɵtext(3);
573
590
  i0.ɵɵelementEnd();
574
591
  } if (rf & 2) {
@@ -576,29 +593,29 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_t
576
593
  i0.ɵɵadvance(3);
577
594
  i0.ɵɵtextInterpolate(ctx_r2.FilterApps().length);
578
595
  } }
579
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Conditional_7_Template(rf, ctx) { if (rf & 1) {
580
- i0.ɵɵelementStart(0, "button", 117);
581
- i0.ɵɵelement(1, "i", 24);
596
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Conditional_7_Template(rf, ctx) { if (rf & 1) {
597
+ i0.ɵɵelementStart(0, "button", 147);
598
+ i0.ɵɵelement(1, "i", 149);
582
599
  i0.ɵɵtext(2, " Pinned");
583
600
  i0.ɵɵelementEnd();
584
601
  } }
585
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Conditional_8_Template(rf, ctx) { if (rf & 1) {
602
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Conditional_8_Template(rf, ctx) { if (rf & 1) {
586
603
  const _r39 = i0.ɵɵgetCurrentView();
587
- i0.ɵɵelementStart(0, "button", 119);
588
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r39); const ni_r40 = i0.ɵɵnextContext().$implicit; const app_r41 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.PinAppNavItem(app_r41.appName, app_r41.icon, app_r41.color, ni_r40.label, ni_r40.icon)); });
589
- i0.ɵɵelement(1, "i", 26);
604
+ i0.ɵɵelementStart(0, "button", 150);
605
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r39); const ni_r40 = i0.ɵɵnextContext().$implicit; const app_r41 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.PinAppNavItem(app_r41.appName, app_r41.icon, app_r41.color, ni_r40.label, ni_r40.icon)); });
606
+ i0.ɵɵelement(1, "i", 49);
590
607
  i0.ɵɵtext(2, " Pin ");
591
608
  i0.ɵɵelementEnd();
592
609
  } }
593
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Template(rf, ctx) { if (rf & 1) {
594
- i0.ɵɵelementStart(0, "div", 112)(1, "div", 113);
610
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Template(rf, ctx) { if (rf & 1) {
611
+ i0.ɵɵelementStart(0, "div", 142)(1, "div", 143);
595
612
  i0.ɵɵelement(2, "i");
596
613
  i0.ɵɵelementEnd();
597
- i0.ɵɵelementStart(3, "div", 114)(4, "div", 115);
614
+ i0.ɵɵelementStart(3, "div", 144)(4, "div", 145);
598
615
  i0.ɵɵtext(5);
599
616
  i0.ɵɵelementEnd()();
600
- i0.ɵɵelementStart(6, "div", 116);
601
- i0.ɵɵconditionalCreate(7, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Conditional_7_Template, 3, 0, "button", 117)(8, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Conditional_8_Template, 3, 0, "button", 118);
617
+ i0.ɵɵelementStart(6, "div", 146);
618
+ i0.ɵɵconditionalCreate(7, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Conditional_7_Template, 3, 0, "button", 147)(8, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Conditional_8_Template, 3, 0, "button", 148);
602
619
  i0.ɵɵelementEnd()();
603
620
  } if (rf & 2) {
604
621
  const ni_r40 = ctx.$implicit;
@@ -613,14 +630,14 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_t
613
630
  i0.ɵɵadvance(2);
614
631
  i0.ɵɵconditional(ni_r40.pinned ? 7 : 8);
615
632
  } }
616
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_For_1_Template(rf, ctx) { if (rf & 1) {
617
- i0.ɵɵelementStart(0, "div", 109)(1, "div", 110);
633
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_For_1_Template(rf, ctx) { if (rf & 1) {
634
+ i0.ɵɵelementStart(0, "div", 139)(1, "div", 140);
618
635
  i0.ɵɵelement(2, "i");
619
636
  i0.ɵɵelementEnd();
620
- i0.ɵɵelementStart(3, "span", 111);
637
+ i0.ɵɵelementStart(3, "span", 141);
621
638
  i0.ɵɵtext(4);
622
639
  i0.ɵɵelementEnd()();
623
- i0.ɵɵrepeaterCreate(5, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Template, 9, 8, "div", 112, _forTrack1);
640
+ i0.ɵɵrepeaterCreate(5, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_For_1_For_6_Template, 9, 8, "div", 142, _forTrack3);
624
641
  } if (rf & 2) {
625
642
  const app_r41 = ctx.$implicit;
626
643
  i0.ɵɵstyleProp("--panel-app-color", app_r41.color);
@@ -631,26 +648,26 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_t
631
648
  i0.ɵɵadvance();
632
649
  i0.ɵɵrepeater(app_r41.navItems);
633
650
  } }
634
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_Template(rf, ctx) { if (rf & 1) {
635
- i0.ɵɵrepeaterCreate(0, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_For_1_Template, 7, 5, null, null, _forTrack0);
651
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_Template(rf, ctx) { if (rf & 1) {
652
+ i0.ɵɵrepeaterCreate(0, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_For_1_Template, 7, 5, null, null, _forTrack2);
636
653
  } if (rf & 2) {
637
654
  const ctx_r2 = i0.ɵɵnextContext(4);
638
655
  i0.ɵɵrepeater(ctx_r2.FilterApps());
639
656
  } }
640
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_Template(rf, ctx) { if (rf & 1) {
657
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_Template(rf, ctx) { if (rf & 1) {
641
658
  const _r38 = i0.ɵɵgetCurrentView();
642
- i0.ɵɵelementStart(0, "mj-accordion-panel", 104);
643
- i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_Template_mj_accordion_panel_ExpandedChange_0_listener($event) { i0.ɵɵrestoreView(_r38); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPanelSectionExpandedChange("apps", $event)); });
644
- i0.ɵɵtemplate(1, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_1_Template, 4, 1, "ng-template", 105)(2, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_ng_template_2_Template, 2, 0, "ng-template", 106);
659
+ i0.ɵɵelementStart(0, "mj-accordion-panel", 136);
660
+ i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_Template_mj_accordion_panel_ExpandedChange_0_listener($event) { i0.ɵɵrestoreView(_r38); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPanelSectionExpandedChange("apps", $event)); });
661
+ i0.ɵɵtemplate(1, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_1_Template, 4, 1, "ng-template", 20)(2, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_ng_template_2_Template, 2, 0, "ng-template", 22);
645
662
  i0.ɵɵelementEnd();
646
663
  } if (rf & 2) {
647
664
  const ctx_r2 = i0.ɵɵnextContext(3);
648
665
  i0.ɵɵproperty("FlushBody", true)("Expanded", !ctx_r2.PanelSectionCollapsed["apps"]);
649
666
  } }
650
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_1_Template(rf, ctx) { if (rf & 1) {
651
- i0.ɵɵelement(0, "i", 120);
667
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_1_Template(rf, ctx) { if (rf & 1) {
668
+ i0.ɵɵelement(0, "i", 151);
652
669
  i0.ɵɵtext(1, " Dashboards ");
653
- i0.ɵɵelementStart(2, "span", 108);
670
+ i0.ɵɵelementStart(2, "span", 138);
654
671
  i0.ɵɵtext(3);
655
672
  i0.ɵɵelementEnd();
656
673
  } if (rf & 2) {
@@ -658,29 +675,29 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_t
658
675
  i0.ɵɵadvance(3);
659
676
  i0.ɵɵtextInterpolate(ctx_r2.FilterPanelItems(ctx_r2.AvailableDashboards).length);
660
677
  } }
661
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_2_For_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
662
- i0.ɵɵelementStart(0, "button", 117);
663
- i0.ɵɵelement(1, "i", 24);
678
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_2_For_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
679
+ i0.ɵɵelementStart(0, "button", 147);
680
+ i0.ɵɵelement(1, "i", 149);
664
681
  i0.ɵɵtext(2, " Pinned");
665
682
  i0.ɵɵelementEnd();
666
683
  } }
667
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_2_For_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
684
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_2_For_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
668
685
  const _r43 = i0.ɵɵgetCurrentView();
669
- i0.ɵɵelementStart(0, "button", 119);
670
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_2_For_1_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r43); const item_r44 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.PinFromPanel("Dashboards", item_r44.id, item_r44.name)); });
671
- i0.ɵɵelement(1, "i", 26);
686
+ i0.ɵɵelementStart(0, "button", 150);
687
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_2_For_1_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r43); const item_r44 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.PinFromPanel("Dashboards", item_r44.id, item_r44.name)); });
688
+ i0.ɵɵelement(1, "i", 49);
672
689
  i0.ɵɵtext(2, " Pin ");
673
690
  i0.ɵɵelementEnd();
674
691
  } }
675
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_2_For_1_Template(rf, ctx) { if (rf & 1) {
676
- i0.ɵɵelementStart(0, "div", 121)(1, "div", 122);
677
- i0.ɵɵelement(2, "i", 123);
692
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_2_For_1_Template(rf, ctx) { if (rf & 1) {
693
+ i0.ɵɵelementStart(0, "div", 152)(1, "div", 153);
694
+ i0.ɵɵelement(2, "i", 154);
678
695
  i0.ɵɵelementEnd();
679
- i0.ɵɵelementStart(3, "div", 114)(4, "div", 115);
696
+ i0.ɵɵelementStart(3, "div", 144)(4, "div", 145);
680
697
  i0.ɵɵtext(5);
681
698
  i0.ɵɵelementEnd()();
682
- i0.ɵɵelementStart(6, "div", 116);
683
- i0.ɵɵconditionalCreate(7, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_2_For_1_Conditional_7_Template, 3, 0, "button", 117)(8, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_2_For_1_Conditional_8_Template, 3, 0, "button", 118);
699
+ i0.ɵɵelementStart(6, "div", 146);
700
+ i0.ɵɵconditionalCreate(7, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_2_For_1_Conditional_7_Template, 3, 0, "button", 147)(8, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_2_For_1_Conditional_8_Template, 3, 0, "button", 148);
684
701
  i0.ɵɵelementEnd()();
685
702
  } if (rf & 2) {
686
703
  const item_r44 = ctx.$implicit;
@@ -689,26 +706,26 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_t
689
706
  i0.ɵɵadvance(2);
690
707
  i0.ɵɵconditional(item_r44.pinned ? 7 : 8);
691
708
  } }
692
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_2_Template(rf, ctx) { if (rf & 1) {
693
- i0.ɵɵrepeaterCreate(0, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_2_For_1_Template, 9, 2, "div", 121, _forTrack2);
709
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_2_Template(rf, ctx) { if (rf & 1) {
710
+ i0.ɵɵrepeaterCreate(0, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_2_For_1_Template, 9, 2, "div", 152, _forTrack4);
694
711
  } if (rf & 2) {
695
712
  const ctx_r2 = i0.ɵɵnextContext(4);
696
713
  i0.ɵɵrepeater(ctx_r2.FilterPanelItems(ctx_r2.AvailableDashboards));
697
714
  } }
698
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_Template(rf, ctx) { if (rf & 1) {
715
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_Template(rf, ctx) { if (rf & 1) {
699
716
  const _r42 = i0.ɵɵgetCurrentView();
700
- i0.ɵɵelementStart(0, "mj-accordion-panel", 104);
701
- i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_Template_mj_accordion_panel_ExpandedChange_0_listener($event) { i0.ɵɵrestoreView(_r42); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPanelSectionExpandedChange("dashboards", $event)); });
702
- i0.ɵɵtemplate(1, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_1_Template, 4, 1, "ng-template", 105)(2, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_ng_template_2_Template, 2, 0, "ng-template", 106);
717
+ i0.ɵɵelementStart(0, "mj-accordion-panel", 136);
718
+ i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_Template_mj_accordion_panel_ExpandedChange_0_listener($event) { i0.ɵɵrestoreView(_r42); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPanelSectionExpandedChange("dashboards", $event)); });
719
+ i0.ɵɵtemplate(1, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_1_Template, 4, 1, "ng-template", 20)(2, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_ng_template_2_Template, 2, 0, "ng-template", 22);
703
720
  i0.ɵɵelementEnd();
704
721
  } if (rf & 2) {
705
722
  const ctx_r2 = i0.ɵɵnextContext(3);
706
723
  i0.ɵɵproperty("FlushBody", true)("Expanded", !ctx_r2.PanelSectionCollapsed["dashboards"]);
707
724
  } }
708
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_1_Template(rf, ctx) { if (rf & 1) {
709
- i0.ɵɵelement(0, "i", 124);
725
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_1_Template(rf, ctx) { if (rf & 1) {
726
+ i0.ɵɵelement(0, "i", 155);
710
727
  i0.ɵɵtext(1, " Views ");
711
- i0.ɵɵelementStart(2, "span", 108);
728
+ i0.ɵɵelementStart(2, "span", 138);
712
729
  i0.ɵɵtext(3);
713
730
  i0.ɵɵelementEnd();
714
731
  } if (rf & 2) {
@@ -716,32 +733,32 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_t
716
733
  i0.ɵɵadvance(3);
717
734
  i0.ɵɵtextInterpolate(ctx_r2.FilterPanelItems(ctx_r2.AvailableViews).length);
718
735
  } }
719
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_2_For_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
720
- i0.ɵɵelementStart(0, "button", 117);
721
- i0.ɵɵelement(1, "i", 24);
736
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_2_For_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
737
+ i0.ɵɵelementStart(0, "button", 147);
738
+ i0.ɵɵelement(1, "i", 149);
722
739
  i0.ɵɵtext(2, " Pinned");
723
740
  i0.ɵɵelementEnd();
724
741
  } }
725
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_2_For_1_Conditional_10_Template(rf, ctx) { if (rf & 1) {
742
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_2_For_1_Conditional_10_Template(rf, ctx) { if (rf & 1) {
726
743
  const _r46 = i0.ɵɵgetCurrentView();
727
- i0.ɵɵelementStart(0, "button", 119);
728
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_2_For_1_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r46); const item_r47 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.PinFromPanel("User Views", item_r47.id, item_r47.name)); });
729
- i0.ɵɵelement(1, "i", 26);
744
+ i0.ɵɵelementStart(0, "button", 150);
745
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_2_For_1_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r46); const item_r47 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.PinFromPanel("User Views", item_r47.id, item_r47.name)); });
746
+ i0.ɵɵelement(1, "i", 49);
730
747
  i0.ɵɵtext(2, " Pin ");
731
748
  i0.ɵɵelementEnd();
732
749
  } }
733
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_2_For_1_Template(rf, ctx) { if (rf & 1) {
734
- i0.ɵɵelementStart(0, "div", 121)(1, "div", 122);
735
- i0.ɵɵelement(2, "i", 125);
750
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_2_For_1_Template(rf, ctx) { if (rf & 1) {
751
+ i0.ɵɵelementStart(0, "div", 152)(1, "div", 153);
752
+ i0.ɵɵelement(2, "i", 156);
736
753
  i0.ɵɵelementEnd();
737
- i0.ɵɵelementStart(3, "div", 114)(4, "div", 115);
754
+ i0.ɵɵelementStart(3, "div", 144)(4, "div", 145);
738
755
  i0.ɵɵtext(5);
739
756
  i0.ɵɵelementEnd();
740
- i0.ɵɵelementStart(6, "div", 126);
757
+ i0.ɵɵelementStart(6, "div", 157);
741
758
  i0.ɵɵtext(7);
742
759
  i0.ɵɵelementEnd()();
743
- i0.ɵɵelementStart(8, "div", 116);
744
- i0.ɵɵconditionalCreate(9, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_2_For_1_Conditional_9_Template, 3, 0, "button", 117)(10, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_2_For_1_Conditional_10_Template, 3, 0, "button", 118);
760
+ i0.ɵɵelementStart(8, "div", 146);
761
+ i0.ɵɵconditionalCreate(9, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_2_For_1_Conditional_9_Template, 3, 0, "button", 147)(10, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_2_For_1_Conditional_10_Template, 3, 0, "button", 148);
745
762
  i0.ɵɵelementEnd()();
746
763
  } if (rf & 2) {
747
764
  const item_r47 = ctx.$implicit;
@@ -752,26 +769,26 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_t
752
769
  i0.ɵɵadvance(2);
753
770
  i0.ɵɵconditional(item_r47.pinned ? 9 : 10);
754
771
  } }
755
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_2_Template(rf, ctx) { if (rf & 1) {
756
- i0.ɵɵrepeaterCreate(0, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_2_For_1_Template, 11, 3, "div", 121, _forTrack2);
772
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_2_Template(rf, ctx) { if (rf & 1) {
773
+ i0.ɵɵrepeaterCreate(0, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_2_For_1_Template, 11, 3, "div", 152, _forTrack4);
757
774
  } if (rf & 2) {
758
775
  const ctx_r2 = i0.ɵɵnextContext(4);
759
776
  i0.ɵɵrepeater(ctx_r2.FilterPanelItems(ctx_r2.AvailableViews));
760
777
  } }
761
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_Template(rf, ctx) { if (rf & 1) {
778
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_Template(rf, ctx) { if (rf & 1) {
762
779
  const _r45 = i0.ɵɵgetCurrentView();
763
- i0.ɵɵelementStart(0, "mj-accordion-panel", 104);
764
- i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_Template_mj_accordion_panel_ExpandedChange_0_listener($event) { i0.ɵɵrestoreView(_r45); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPanelSectionExpandedChange("views", $event)); });
765
- i0.ɵɵtemplate(1, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_1_Template, 4, 1, "ng-template", 105)(2, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_ng_template_2_Template, 2, 0, "ng-template", 106);
780
+ i0.ɵɵelementStart(0, "mj-accordion-panel", 136);
781
+ i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_Template_mj_accordion_panel_ExpandedChange_0_listener($event) { i0.ɵɵrestoreView(_r45); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPanelSectionExpandedChange("views", $event)); });
782
+ i0.ɵɵtemplate(1, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_1_Template, 4, 1, "ng-template", 20)(2, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_ng_template_2_Template, 2, 0, "ng-template", 22);
766
783
  i0.ɵɵelementEnd();
767
784
  } if (rf & 2) {
768
785
  const ctx_r2 = i0.ɵɵnextContext(3);
769
786
  i0.ɵɵproperty("FlushBody", true)("Expanded", !ctx_r2.PanelSectionCollapsed["views"]);
770
787
  } }
771
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_1_Template(rf, ctx) { if (rf & 1) {
772
- i0.ɵɵelement(0, "i", 127);
788
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_1_Template(rf, ctx) { if (rf & 1) {
789
+ i0.ɵɵelement(0, "i", 158);
773
790
  i0.ɵɵtext(1, " Queries ");
774
- i0.ɵɵelementStart(2, "span", 108);
791
+ i0.ɵɵelementStart(2, "span", 138);
775
792
  i0.ɵɵtext(3);
776
793
  i0.ɵɵelementEnd();
777
794
  } if (rf & 2) {
@@ -779,29 +796,29 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_t
779
796
  i0.ɵɵadvance(3);
780
797
  i0.ɵɵtextInterpolate(ctx_r2.FilterPanelItems(ctx_r2.AvailableQueries).length);
781
798
  } }
782
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_2_For_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
783
- i0.ɵɵelementStart(0, "button", 117);
784
- i0.ɵɵelement(1, "i", 24);
799
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_2_For_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
800
+ i0.ɵɵelementStart(0, "button", 147);
801
+ i0.ɵɵelement(1, "i", 149);
785
802
  i0.ɵɵtext(2, " Pinned");
786
803
  i0.ɵɵelementEnd();
787
804
  } }
788
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_2_For_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
805
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_2_For_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
789
806
  const _r49 = i0.ɵɵgetCurrentView();
790
- i0.ɵɵelementStart(0, "button", 119);
791
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_2_For_1_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r49); const item_r50 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.PinFromPanel("Queries", item_r50.id, item_r50.name)); });
792
- i0.ɵɵelement(1, "i", 26);
807
+ i0.ɵɵelementStart(0, "button", 150);
808
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_2_For_1_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r49); const item_r50 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.PinFromPanel("Queries", item_r50.id, item_r50.name)); });
809
+ i0.ɵɵelement(1, "i", 49);
793
810
  i0.ɵɵtext(2, " Pin ");
794
811
  i0.ɵɵelementEnd();
795
812
  } }
796
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_2_For_1_Template(rf, ctx) { if (rf & 1) {
797
- i0.ɵɵelementStart(0, "div", 121)(1, "div", 122);
798
- i0.ɵɵelement(2, "i", 128);
813
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_2_For_1_Template(rf, ctx) { if (rf & 1) {
814
+ i0.ɵɵelementStart(0, "div", 152)(1, "div", 153);
815
+ i0.ɵɵelement(2, "i", 159);
799
816
  i0.ɵɵelementEnd();
800
- i0.ɵɵelementStart(3, "div", 114)(4, "div", 115);
817
+ i0.ɵɵelementStart(3, "div", 144)(4, "div", 145);
801
818
  i0.ɵɵtext(5);
802
819
  i0.ɵɵelementEnd()();
803
- i0.ɵɵelementStart(6, "div", 116);
804
- i0.ɵɵconditionalCreate(7, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_2_For_1_Conditional_7_Template, 3, 0, "button", 117)(8, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_2_For_1_Conditional_8_Template, 3, 0, "button", 118);
820
+ i0.ɵɵelementStart(6, "div", 146);
821
+ i0.ɵɵconditionalCreate(7, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_2_For_1_Conditional_7_Template, 3, 0, "button", 147)(8, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_2_For_1_Conditional_8_Template, 3, 0, "button", 148);
805
822
  i0.ɵɵelementEnd()();
806
823
  } if (rf & 2) {
807
824
  const item_r50 = ctx.$implicit;
@@ -810,26 +827,26 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_t
810
827
  i0.ɵɵadvance(2);
811
828
  i0.ɵɵconditional(item_r50.pinned ? 7 : 8);
812
829
  } }
813
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_2_Template(rf, ctx) { if (rf & 1) {
814
- i0.ɵɵrepeaterCreate(0, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_2_For_1_Template, 9, 2, "div", 121, _forTrack2);
830
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_2_Template(rf, ctx) { if (rf & 1) {
831
+ i0.ɵɵrepeaterCreate(0, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_2_For_1_Template, 9, 2, "div", 152, _forTrack4);
815
832
  } if (rf & 2) {
816
833
  const ctx_r2 = i0.ɵɵnextContext(4);
817
834
  i0.ɵɵrepeater(ctx_r2.FilterPanelItems(ctx_r2.AvailableQueries));
818
835
  } }
819
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_Template(rf, ctx) { if (rf & 1) {
836
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_Template(rf, ctx) { if (rf & 1) {
820
837
  const _r48 = i0.ɵɵgetCurrentView();
821
- i0.ɵɵelementStart(0, "mj-accordion-panel", 104);
822
- i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_Template_mj_accordion_panel_ExpandedChange_0_listener($event) { i0.ɵɵrestoreView(_r48); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPanelSectionExpandedChange("queries", $event)); });
823
- i0.ɵɵtemplate(1, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_1_Template, 4, 1, "ng-template", 105)(2, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_ng_template_2_Template, 2, 0, "ng-template", 106);
838
+ i0.ɵɵelementStart(0, "mj-accordion-panel", 136);
839
+ i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_Template_mj_accordion_panel_ExpandedChange_0_listener($event) { i0.ɵɵrestoreView(_r48); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPanelSectionExpandedChange("queries", $event)); });
840
+ i0.ɵɵtemplate(1, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_1_Template, 4, 1, "ng-template", 20)(2, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_ng_template_2_Template, 2, 0, "ng-template", 22);
824
841
  i0.ɵɵelementEnd();
825
842
  } if (rf & 2) {
826
843
  const ctx_r2 = i0.ɵɵnextContext(3);
827
844
  i0.ɵɵproperty("FlushBody", true)("Expanded", !ctx_r2.PanelSectionCollapsed["queries"]);
828
845
  } }
829
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_template_1_Template(rf, ctx) { if (rf & 1) {
830
- i0.ɵɵelement(0, "i", 129);
846
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_ng_template_1_Template(rf, ctx) { if (rf & 1) {
847
+ i0.ɵɵelement(0, "i", 160);
831
848
  i0.ɵɵtext(1, " Quick Actions ");
832
- i0.ɵɵelementStart(2, "span", 108);
849
+ i0.ɵɵelementStart(2, "span", 138);
833
850
  i0.ɵɵtext(3);
834
851
  i0.ɵɵelementEnd();
835
852
  } if (rf & 2) {
@@ -837,8 +854,8 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_t
837
854
  i0.ɵɵadvance(3);
838
855
  i0.ɵɵtextInterpolate(ctx_r2.FilterPanelItems(ctx_r2.AvailableActions).length);
839
856
  } }
840
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_template_2_For_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
841
- i0.ɵɵelementStart(0, "div", 126);
857
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_ng_template_2_For_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
858
+ i0.ɵɵelementStart(0, "div", 157);
842
859
  i0.ɵɵtext(1);
843
860
  i0.ɵɵelementEnd();
844
861
  } if (rf & 2) {
@@ -846,19 +863,19 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_t
846
863
  i0.ɵɵadvance();
847
864
  i0.ɵɵtextInterpolate(item_r53.description);
848
865
  } }
849
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_template_2_For_1_Template(rf, ctx) { if (rf & 1) {
866
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_ng_template_2_For_1_Template(rf, ctx) { if (rf & 1) {
850
867
  const _r52 = i0.ɵɵgetCurrentView();
851
- i0.ɵɵelementStart(0, "div", 121)(1, "div", 122);
852
- i0.ɵɵelement(2, "i", 130);
868
+ i0.ɵɵelementStart(0, "div", 152)(1, "div", 153);
869
+ i0.ɵɵelement(2, "i", 161);
853
870
  i0.ɵɵelementEnd();
854
- i0.ɵɵelementStart(3, "div", 114)(4, "div", 115);
871
+ i0.ɵɵelementStart(3, "div", 144)(4, "div", 145);
855
872
  i0.ɵɵtext(5);
856
873
  i0.ɵɵelementEnd();
857
- i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_template_2_For_1_Conditional_6_Template, 2, 1, "div", 126);
874
+ i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_ng_template_2_For_1_Conditional_6_Template, 2, 1, "div", 157);
858
875
  i0.ɵɵelementEnd();
859
- i0.ɵɵelementStart(7, "div", 116)(8, "button", 119);
860
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_template_2_For_1_Template_button_click_8_listener() { const item_r53 = i0.ɵɵrestoreView(_r52).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OpenActionPinConfig(item_r53.id, item_r53.name, item_r53.description)); });
861
- i0.ɵɵelement(9, "i", 131);
876
+ i0.ɵɵelementStart(7, "div", 146)(8, "button", 150);
877
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_ng_template_2_For_1_Template_button_click_8_listener() { const item_r53 = i0.ɵɵrestoreView(_r52).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OpenActionPinConfig(item_r53.id, item_r53.name, item_r53.description)); });
878
+ i0.ɵɵelement(9, "i", 162);
862
879
  i0.ɵɵtext(10, " Configure ");
863
880
  i0.ɵɵelementEnd()()();
864
881
  } if (rf & 2) {
@@ -868,28 +885,28 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_t
868
885
  i0.ɵɵadvance();
869
886
  i0.ɵɵconditional(item_r53.description ? 6 : -1);
870
887
  } }
871
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_template_2_Template(rf, ctx) { if (rf & 1) {
872
- i0.ɵɵrepeaterCreate(0, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_template_2_For_1_Template, 11, 2, "div", 121, _forTrack2);
888
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_ng_template_2_Template(rf, ctx) { if (rf & 1) {
889
+ i0.ɵɵrepeaterCreate(0, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_ng_template_2_For_1_Template, 11, 2, "div", 152, _forTrack4);
873
890
  } if (rf & 2) {
874
891
  const ctx_r2 = i0.ɵɵnextContext(4);
875
892
  i0.ɵɵrepeater(ctx_r2.FilterPanelItems(ctx_r2.AvailableActions));
876
893
  } }
877
- function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_Template(rf, ctx) { if (rf & 1) {
894
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_Template(rf, ctx) { if (rf & 1) {
878
895
  const _r51 = i0.ɵɵgetCurrentView();
879
- i0.ɵɵelementStart(0, "mj-accordion-panel", 104);
880
- i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_Template_mj_accordion_panel_ExpandedChange_0_listener($event) { i0.ɵɵrestoreView(_r51); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPanelSectionExpandedChange("actions", $event)); });
881
- i0.ɵɵtemplate(1, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_template_1_Template, 4, 1, "ng-template", 105)(2, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_ng_template_2_Template, 2, 0, "ng-template", 106);
896
+ i0.ɵɵelementStart(0, "mj-accordion-panel", 136);
897
+ i0.ɵɵlistener("ExpandedChange", function HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_Template_mj_accordion_panel_ExpandedChange_0_listener($event) { i0.ɵɵrestoreView(_r51); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnPanelSectionExpandedChange("actions", $event)); });
898
+ i0.ɵɵtemplate(1, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_ng_template_1_Template, 4, 1, "ng-template", 20)(2, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_ng_template_2_Template, 2, 0, "ng-template", 22);
882
899
  i0.ɵɵelementEnd();
883
900
  } if (rf & 2) {
884
901
  const ctx_r2 = i0.ɵɵnextContext(3);
885
902
  i0.ɵɵproperty("FlushBody", true)("Expanded", !ctx_r2.PanelSectionCollapsed["actions"]);
886
903
  } }
887
- function HomeDashboardComponent_Conditional_10_Conditional_26_Template(rf, ctx) { if (rf & 1) {
888
- i0.ɵɵconditionalCreate(0, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_0_Template, 3, 2, "mj-accordion-panel", 103);
889
- i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_1_Template, 3, 2, "mj-accordion-panel", 103);
890
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_2_Template, 3, 2, "mj-accordion-panel", 103);
891
- i0.ɵɵconditionalCreate(3, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_3_Template, 3, 2, "mj-accordion-panel", 103);
892
- i0.ɵɵconditionalCreate(4, HomeDashboardComponent_Conditional_10_Conditional_26_Conditional_4_Template, 3, 2, "mj-accordion-panel", 103);
904
+ function HomeDashboardComponent_Conditional_7_Conditional_26_Template(rf, ctx) { if (rf & 1) {
905
+ i0.ɵɵconditionalCreate(0, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_0_Template, 3, 2, "mj-accordion-panel", 135);
906
+ i0.ɵɵconditionalCreate(1, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_1_Template, 3, 2, "mj-accordion-panel", 135);
907
+ i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_2_Template, 3, 2, "mj-accordion-panel", 135);
908
+ i0.ɵɵconditionalCreate(3, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_3_Template, 3, 2, "mj-accordion-panel", 135);
909
+ i0.ɵɵconditionalCreate(4, HomeDashboardComponent_Conditional_7_Conditional_26_Conditional_4_Template, 3, 2, "mj-accordion-panel", 135);
893
910
  } if (rf & 2) {
894
911
  const ctx_r2 = i0.ɵɵnextContext(2);
895
912
  i0.ɵɵconditional(ctx_r2.FilterApps().length > 0 ? 0 : -1);
@@ -902,40 +919,40 @@ function HomeDashboardComponent_Conditional_10_Conditional_26_Template(rf, ctx)
902
919
  i0.ɵɵadvance();
903
920
  i0.ɵɵconditional(ctx_r2.FilterPanelItems(ctx_r2.AvailableActions).length > 0 ? 4 : -1);
904
921
  } }
905
- function HomeDashboardComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
922
+ function HomeDashboardComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
906
923
  const _r35 = i0.ɵɵgetCurrentView();
907
- i0.ɵɵelementStart(0, "div", 85);
908
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_10_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseAddPinPanel()); });
924
+ i0.ɵɵelementStart(0, "div", 115);
925
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_7_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseAddPinPanel()); });
909
926
  i0.ɵɵelementEnd();
910
- i0.ɵɵelementStart(1, "div", 86)(2, "div", 87)(3, "h3");
911
- i0.ɵɵelement(4, "i", 17);
927
+ i0.ɵɵelementStart(1, "div", 116)(2, "div", 117)(3, "h3");
928
+ i0.ɵɵelement(4, "i", 118);
912
929
  i0.ɵɵtext(5, " Add Pin");
913
930
  i0.ɵɵelementEnd();
914
- i0.ɵɵelementStart(6, "button", 88);
915
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_10_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseAddPinPanel()); });
916
- i0.ɵɵelement(7, "i", 36);
931
+ i0.ɵɵelementStart(6, "button", 119);
932
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_7_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseAddPinPanel()); });
933
+ i0.ɵɵelement(7, "i", 52);
917
934
  i0.ɵɵelementEnd()();
918
- i0.ɵɵelementStart(8, "div", 89)(9, "div", 90);
919
- i0.ɵɵelement(10, "i", 91);
920
- i0.ɵɵelementStart(11, "input", 92);
921
- i0.ɵɵtwoWayListener("ngModelChange", function HomeDashboardComponent_Conditional_10_Template_input_ngModelChange_11_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.AddPanelSearchQuery, $event) || (ctx_r2.AddPanelSearchQuery = $event); return i0.ɵɵresetView($event); });
935
+ i0.ɵɵelementStart(8, "div", 120)(9, "div", 121);
936
+ i0.ɵɵelement(10, "i", 122);
937
+ i0.ɵɵelementStart(11, "input", 123);
938
+ i0.ɵɵtwoWayListener("ngModelChange", function HomeDashboardComponent_Conditional_7_Template_input_ngModelChange_11_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.AddPanelSearchQuery, $event) || (ctx_r2.AddPanelSearchQuery = $event); return i0.ɵɵresetView($event); });
922
939
  i0.ɵɵelementEnd()()();
923
- i0.ɵɵelementStart(12, "div", 93)(13, "label");
924
- i0.ɵɵelement(14, "i", 80);
940
+ i0.ɵɵelementStart(12, "div", 124)(13, "label");
941
+ i0.ɵɵelement(14, "i", 125);
925
942
  i0.ɵɵtext(15, " Add to group:");
926
943
  i0.ɵɵelementEnd();
927
- i0.ɵɵelementStart(16, "select", 94);
928
- i0.ɵɵtwoWayListener("ngModelChange", function HomeDashboardComponent_Conditional_10_Template_select_ngModelChange_16_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.AddPanelSelectedGroup, $event) || (ctx_r2.AddPanelSelectedGroup = $event); return i0.ɵɵresetView($event); });
929
- i0.ɵɵelementStart(17, "option", 95);
944
+ i0.ɵɵelementStart(16, "select", 126);
945
+ i0.ɵɵtwoWayListener("ngModelChange", function HomeDashboardComponent_Conditional_7_Template_select_ngModelChange_16_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.AddPanelSelectedGroup, $event) || (ctx_r2.AddPanelSelectedGroup = $event); return i0.ɵɵresetView($event); });
946
+ i0.ɵɵelementStart(17, "option", 127);
930
947
  i0.ɵɵtext(18, "(No group)");
931
948
  i0.ɵɵelementEnd();
932
- i0.ɵɵrepeaterCreate(19, HomeDashboardComponent_Conditional_10_For_20_Template, 2, 2, "option", 96, i0.ɵɵrepeaterTrackByIdentity);
933
- i0.ɵɵelementStart(21, "option", 97);
949
+ i0.ɵɵrepeaterCreate(19, HomeDashboardComponent_Conditional_7_For_20_Template, 2, 2, "option", 128, i0.ɵɵrepeaterTrackByIdentity);
950
+ i0.ɵɵelementStart(21, "option", 129);
934
951
  i0.ɵɵtext(22, "+ New group...");
935
952
  i0.ɵɵelementEnd()()();
936
- i0.ɵɵconditionalCreate(23, HomeDashboardComponent_Conditional_10_Conditional_23_Template, 2, 1, "div", 98);
937
- i0.ɵɵelementStart(24, "div", 99);
938
- i0.ɵɵconditionalCreate(25, HomeDashboardComponent_Conditional_10_Conditional_25_Template, 2, 0, "div", 100)(26, HomeDashboardComponent_Conditional_10_Conditional_26_Template, 5, 5);
953
+ i0.ɵɵconditionalCreate(23, HomeDashboardComponent_Conditional_7_Conditional_23_Template, 2, 1, "div", 130);
954
+ i0.ɵɵelementStart(24, "div", 131);
955
+ i0.ɵɵconditionalCreate(25, HomeDashboardComponent_Conditional_7_Conditional_25_Template, 2, 0, "div", 132)(26, HomeDashboardComponent_Conditional_7_Conditional_26_Template, 5, 5);
939
956
  i0.ɵɵelementEnd()();
940
957
  } if (rf & 2) {
941
958
  const ctx_r2 = i0.ɵɵnextContext();
@@ -950,134 +967,39 @@ function HomeDashboardComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
950
967
  i0.ɵɵadvance(2);
951
968
  i0.ɵɵconditional(ctx_r2.AddPanelLoading ? 25 : 26);
952
969
  } }
953
- function HomeDashboardComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
954
- i0.ɵɵelementStart(0, "div", 10);
955
- i0.ɵɵelement(1, "mj-loading", 132);
956
- i0.ɵɵelementEnd();
957
- } }
958
- function HomeDashboardComponent_Conditional_14_For_6_Conditional_7_Template(rf, ctx) { if (rf & 1) {
959
- i0.ɵɵelementStart(0, "p", 141);
960
- i0.ɵɵtext(1);
961
- i0.ɵɵelementEnd();
962
- } if (rf & 2) {
963
- const appData_r55 = i0.ɵɵnextContext().$implicit;
964
- i0.ɵɵadvance();
965
- i0.ɵɵtextInterpolate(appData_r55.app.Description);
966
- } }
967
- function HomeDashboardComponent_Conditional_14_For_6_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
968
- i0.ɵɵelementStart(0, "div", 145);
969
- i0.ɵɵelement(1, "i");
970
- i0.ɵɵelementStart(2, "span");
971
- i0.ɵɵtext(3);
972
- i0.ɵɵelementEnd()();
973
- } if (rf & 2) {
974
- const item_r56 = ctx.$implicit;
975
- i0.ɵɵadvance();
976
- i0.ɵɵclassMap(item_r56.Icon);
977
- i0.ɵɵadvance(2);
978
- i0.ɵɵtextInterpolate(item_r56.Label);
979
- } }
980
- function HomeDashboardComponent_Conditional_14_For_6_Conditional_8_Conditional_3_Template(rf, ctx) { if (rf & 1) {
981
- i0.ɵɵelementStart(0, "span", 146);
982
- i0.ɵɵtext(1);
983
- i0.ɵɵelementEnd();
984
- } if (rf & 2) {
985
- const appData_r55 = i0.ɵɵnextContext(2).$implicit;
986
- i0.ɵɵadvance();
987
- i0.ɵɵtextInterpolate1(" +", appData_r55.moreItemsCount, " more ");
988
- } }
989
- function HomeDashboardComponent_Conditional_14_For_6_Conditional_8_Template(rf, ctx) { if (rf & 1) {
990
- i0.ɵɵelementStart(0, "div", 142);
991
- i0.ɵɵrepeaterCreate(1, HomeDashboardComponent_Conditional_14_For_6_Conditional_8_For_2_Template, 4, 3, "div", 145, i0.ɵɵcomponentInstance().trackByNavItem, true);
992
- i0.ɵɵconditionalCreate(3, HomeDashboardComponent_Conditional_14_For_6_Conditional_8_Conditional_3_Template, 2, 1, "span", 146);
993
- i0.ɵɵelementEnd();
994
- } if (rf & 2) {
995
- const appData_r55 = i0.ɵɵnextContext().$implicit;
996
- i0.ɵɵadvance();
997
- i0.ɵɵrepeater(appData_r55.navItemsPreview);
998
- i0.ɵɵadvance(2);
999
- i0.ɵɵconditional(appData_r55.showMoreItems ? 3 : -1);
1000
- } }
1001
- function HomeDashboardComponent_Conditional_14_For_6_Template(rf, ctx) { if (rf & 1) {
1002
- const _r54 = i0.ɵɵgetCurrentView();
1003
- i0.ɵɵelementStart(0, "div", 136);
1004
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_14_For_6_Template_div_click_0_listener() { const appData_r55 = i0.ɵɵrestoreView(_r54).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onAppClick(appData_r55.app)); });
1005
- i0.ɵɵelementStart(1, "div", 137)(2, "div", 138);
1006
- i0.ɵɵelement(3, "i");
1007
- i0.ɵɵelementEnd()();
1008
- i0.ɵɵelementStart(4, "div", 139)(5, "h3", 140);
1009
- i0.ɵɵtext(6);
1010
- i0.ɵɵelementEnd();
1011
- i0.ɵɵconditionalCreate(7, HomeDashboardComponent_Conditional_14_For_6_Conditional_7_Template, 2, 1, "p", 141);
1012
- i0.ɵɵconditionalCreate(8, HomeDashboardComponent_Conditional_14_For_6_Conditional_8_Template, 4, 1, "div", 142);
1013
- i0.ɵɵelementEnd();
1014
- i0.ɵɵelementStart(9, "div", 143);
1015
- i0.ɵɵelement(10, "i", 144);
1016
- i0.ɵɵelementEnd()();
1017
- } if (rf & 2) {
1018
- const appData_r55 = ctx.$implicit;
1019
- i0.ɵɵstyleProp("--app-color", appData_r55.color);
1020
- i0.ɵɵproperty("mjClickable", appData_r55.app.Name)("testId", "app-tile-" + appData_r55.app.Name);
1021
- i0.ɵɵadvance(3);
1022
- i0.ɵɵclassMap(appData_r55.icon);
1023
- i0.ɵɵadvance(3);
1024
- i0.ɵɵtextInterpolate(appData_r55.app.Name);
1025
- i0.ɵɵadvance();
1026
- i0.ɵɵconditional(appData_r55.app.Description ? 7 : -1);
1027
- i0.ɵɵadvance();
1028
- i0.ɵɵconditional(appData_r55.navItemsCount > 0 ? 8 : -1);
1029
- } }
1030
- function HomeDashboardComponent_Conditional_14_Conditional_7_Template(rf, ctx) { if (rf & 1) {
1031
- const _r57 = i0.ɵɵgetCurrentView();
1032
- i0.ɵɵelementStart(0, "mj-empty-state", 147);
1033
- i0.ɵɵlistener("Action", function HomeDashboardComponent_Conditional_14_Conditional_7_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r57); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.openConfigDialog()); });
970
+ function HomeDashboardComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
971
+ i0.ɵɵelementStart(0, "div", 12);
972
+ i0.ɵɵelement(1, "mj-loading", 163);
1034
973
  i0.ɵɵelementEnd();
1035
974
  } }
1036
- function HomeDashboardComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
1037
- i0.ɵɵelementStart(0, "div", 11)(1, "h2", 16);
1038
- i0.ɵɵelement(2, "i", 107);
1039
- i0.ɵɵtext(3, " My Applications ");
1040
- i0.ɵɵelementEnd();
1041
- i0.ɵɵelementStart(4, "div", 133);
1042
- i0.ɵɵrepeaterCreate(5, HomeDashboardComponent_Conditional_14_For_6_Template, 11, 9, "div", 134, i0.ɵɵcomponentInstance().trackByApp, true);
1043
- i0.ɵɵelementEnd();
1044
- i0.ɵɵconditionalCreate(7, HomeDashboardComponent_Conditional_14_Conditional_7_Template, 1, 0, "mj-empty-state", 135);
1045
- i0.ɵɵelementEnd();
1046
- } if (rf & 2) {
1047
- const ctx_r2 = i0.ɵɵnextContext();
1048
- i0.ɵɵadvance(5);
1049
- i0.ɵɵrepeater(ctx_r2.appsDisplayData);
1050
- i0.ɵɵadvance(2);
1051
- i0.ɵɵconditional(ctx_r2.apps.length === 0 ? 7 : -1);
1052
- } }
1053
- function HomeDashboardComponent_Conditional_15_Conditional_8_For_8_Template(rf, ctx) { if (rf & 1) {
1054
- const _r59 = i0.ɵɵgetCurrentView();
1055
- i0.ɵɵelementStart(0, "div", 160);
1056
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_15_Conditional_8_For_8_Template_div_click_0_listener() { const notification_r60 = i0.ɵɵrestoreView(_r59).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onNotificationClick(notification_r60)); });
1057
- i0.ɵɵelementStart(1, "div", 161)(2, "span", 162);
975
+ function HomeDashboardComponent_Conditional_12_Conditional_8_For_8_Template(rf, ctx) { if (rf & 1) {
976
+ const _r55 = i0.ɵɵgetCurrentView();
977
+ i0.ɵɵelementStart(0, "div", 176);
978
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_12_Conditional_8_For_8_Template_div_click_0_listener() { const notification_r56 = i0.ɵɵrestoreView(_r55).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onNotificationClick(notification_r56)); });
979
+ i0.ɵɵelementStart(1, "div", 177)(2, "span", 178);
1058
980
  i0.ɵɵtext(3);
1059
981
  i0.ɵɵelementEnd();
1060
- i0.ɵɵelementStart(4, "span", 163);
982
+ i0.ɵɵelementStart(4, "span", 179);
1061
983
  i0.ɵɵtext(5);
1062
984
  i0.ɵɵpipe(6, "slice");
1063
985
  i0.ɵɵelementEnd()()();
1064
986
  } if (rf & 2) {
1065
- const notification_r60 = ctx.$implicit;
1066
- i0.ɵɵproperty("mjClickable", notification_r60.Title);
987
+ const notification_r56 = ctx.$implicit;
988
+ i0.ɵɵproperty("mjClickable", notification_r56.Title);
1067
989
  i0.ɵɵadvance(3);
1068
- i0.ɵɵtextInterpolate(notification_r60.Title);
990
+ i0.ɵɵtextInterpolate(notification_r56.Title);
1069
991
  i0.ɵɵadvance(2);
1070
- i0.ɵɵtextInterpolate2("", i0.ɵɵpipeBind3(6, 4, notification_r60.Message, 0, 40), "", ((notification_r60.Message == null ? null : notification_r60.Message.length) || 0) > 40 ? "..." : "");
992
+ i0.ɵɵtextInterpolate2("", i0.ɵɵpipeBind3(6, 4, notification_r56.Message, 0, 40), "", ((notification_r56.Message == null ? null : notification_r56.Message.length) || 0) > 40 ? "..." : "");
1071
993
  } }
1072
- function HomeDashboardComponent_Conditional_15_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1073
- i0.ɵɵelementStart(0, "div", 151)(1, "h4", 155);
1074
- i0.ɵɵelement(2, "i", 156);
994
+ function HomeDashboardComponent_Conditional_12_Conditional_8_Template(rf, ctx) { if (rf & 1) {
995
+ i0.ɵɵelementStart(0, "div", 167)(1, "h4", 171);
996
+ i0.ɵɵelement(2, "i", 172);
1075
997
  i0.ɵɵtext(3, " Notifications ");
1076
- i0.ɵɵelementStart(4, "span", 157);
998
+ i0.ɵɵelementStart(4, "span", 173);
1077
999
  i0.ɵɵtext(5);
1078
1000
  i0.ɵɵelementEnd()();
1079
- i0.ɵɵelementStart(6, "div", 158);
1080
- i0.ɵɵrepeaterCreate(7, HomeDashboardComponent_Conditional_15_Conditional_8_For_8_Template, 7, 8, "div", 159, i0.ɵɵcomponentInstance().trackByNotification, true);
1001
+ i0.ɵɵelementStart(6, "div", 174);
1002
+ i0.ɵɵrepeaterCreate(7, HomeDashboardComponent_Conditional_12_Conditional_8_For_8_Template, 7, 8, "div", 175, i0.ɵɵcomponentInstance().trackByNotification, true);
1081
1003
  i0.ɵɵelementEnd()();
1082
1004
  } if (rf & 2) {
1083
1005
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -1086,53 +1008,53 @@ function HomeDashboardComponent_Conditional_15_Conditional_8_Template(rf, ctx) {
1086
1008
  i0.ɵɵadvance(2);
1087
1009
  i0.ɵɵrepeater(ctx_r2.unreadNotifications);
1088
1010
  } }
1089
- function HomeDashboardComponent_Conditional_15_Conditional_9_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
1090
- const _r61 = i0.ɵɵgetCurrentView();
1091
- i0.ɵɵelementStart(0, "div", 167);
1092
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_15_Conditional_9_Conditional_4_For_2_Template_div_click_0_listener() { const favorite_r62 = i0.ɵɵrestoreView(_r61).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.onFavoriteClick(favorite_r62)); });
1093
- i0.ɵɵelementStart(1, "div", 168);
1011
+ function HomeDashboardComponent_Conditional_12_Conditional_9_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
1012
+ const _r57 = i0.ɵɵgetCurrentView();
1013
+ i0.ɵɵelementStart(0, "div", 183);
1014
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_12_Conditional_9_Conditional_4_For_2_Template_div_click_0_listener() { const favorite_r58 = i0.ɵɵrestoreView(_r57).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.onFavoriteClick(favorite_r58)); });
1015
+ i0.ɵɵelementStart(1, "div", 184);
1094
1016
  i0.ɵɵelement(2, "i");
1095
1017
  i0.ɵɵelementEnd();
1096
- i0.ɵɵelementStart(3, "div", 161)(4, "span", 162);
1018
+ i0.ɵɵelementStart(3, "div", 177)(4, "span", 178);
1097
1019
  i0.ɵɵtext(5);
1098
1020
  i0.ɵɵelementEnd();
1099
- i0.ɵɵelementStart(6, "span", 163);
1021
+ i0.ɵɵelementStart(6, "span", 179);
1100
1022
  i0.ɵɵtext(7);
1101
1023
  i0.ɵɵelementEnd()()();
1102
1024
  } if (rf & 2) {
1103
- const favorite_r62 = ctx.$implicit;
1025
+ const favorite_r58 = ctx.$implicit;
1104
1026
  const ctx_r2 = i0.ɵɵnextContext(4);
1105
- i0.ɵɵproperty("mjClickable", ctx_r2.getFavoriteDisplayName(favorite_r62));
1027
+ i0.ɵɵproperty("mjClickable", ctx_r2.getFavoriteDisplayName(favorite_r58));
1106
1028
  i0.ɵɵadvance(2);
1107
- i0.ɵɵclassMap(ctx_r2.getEntityIconByName(favorite_r62.Entity));
1029
+ i0.ɵɵclassMap(ctx_r2.getEntityIconByName(favorite_r58.Entity));
1108
1030
  i0.ɵɵadvance(3);
1109
- i0.ɵɵtextInterpolate(ctx_r2.getFavoriteDisplayName(favorite_r62));
1031
+ i0.ɵɵtextInterpolate(ctx_r2.getFavoriteDisplayName(favorite_r58));
1110
1032
  i0.ɵɵadvance(2);
1111
- i0.ɵɵtextInterpolate(favorite_r62.Entity);
1033
+ i0.ɵɵtextInterpolate(favorite_r58.Entity);
1112
1034
  } }
1113
- function HomeDashboardComponent_Conditional_15_Conditional_9_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1114
- i0.ɵɵelementStart(0, "div", 158);
1115
- i0.ɵɵrepeaterCreate(1, HomeDashboardComponent_Conditional_15_Conditional_9_Conditional_4_For_2_Template, 8, 5, "div", 166, i0.ɵɵcomponentInstance().trackByFavorite, true);
1035
+ function HomeDashboardComponent_Conditional_12_Conditional_9_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1036
+ i0.ɵɵelementStart(0, "div", 174);
1037
+ i0.ɵɵrepeaterCreate(1, HomeDashboardComponent_Conditional_12_Conditional_9_Conditional_4_For_2_Template, 8, 5, "div", 182, i0.ɵɵcomponentInstance().trackByFavorite, true);
1116
1038
  i0.ɵɵelementEnd();
1117
1039
  } if (rf & 2) {
1118
1040
  const ctx_r2 = i0.ɵɵnextContext(3);
1119
1041
  i0.ɵɵadvance();
1120
1042
  i0.ɵɵrepeater(ctx_r2.favorites);
1121
1043
  } }
1122
- function HomeDashboardComponent_Conditional_15_Conditional_9_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1123
- i0.ɵɵelementStart(0, "div", 165);
1124
- i0.ɵɵelement(1, "i", 169);
1044
+ function HomeDashboardComponent_Conditional_12_Conditional_9_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1045
+ i0.ɵɵelementStart(0, "div", 181);
1046
+ i0.ɵɵelement(1, "i", 185);
1125
1047
  i0.ɵɵelementStart(2, "span");
1126
1048
  i0.ɵɵtext(3, "Loading...");
1127
1049
  i0.ɵɵelementEnd()();
1128
1050
  } }
1129
- function HomeDashboardComponent_Conditional_15_Conditional_9_Template(rf, ctx) { if (rf & 1) {
1130
- i0.ɵɵelementStart(0, "div", 152)(1, "h4", 155);
1131
- i0.ɵɵelement(2, "i", 164);
1051
+ function HomeDashboardComponent_Conditional_12_Conditional_9_Template(rf, ctx) { if (rf & 1) {
1052
+ i0.ɵɵelementStart(0, "div", 168)(1, "h4", 171);
1053
+ i0.ɵɵelement(2, "i", 180);
1132
1054
  i0.ɵɵtext(3, " Favorites ");
1133
1055
  i0.ɵɵelementEnd();
1134
- i0.ɵɵconditionalCreate(4, HomeDashboardComponent_Conditional_15_Conditional_9_Conditional_4_Template, 3, 0, "div", 158);
1135
- i0.ɵɵconditionalCreate(5, HomeDashboardComponent_Conditional_15_Conditional_9_Conditional_5_Template, 4, 0, "div", 165);
1056
+ i0.ɵɵconditionalCreate(4, HomeDashboardComponent_Conditional_12_Conditional_9_Conditional_4_Template, 3, 0, "div", 174);
1057
+ i0.ɵɵconditionalCreate(5, HomeDashboardComponent_Conditional_12_Conditional_9_Conditional_5_Template, 4, 0, "div", 181);
1136
1058
  i0.ɵɵelementEnd();
1137
1059
  } if (rf & 2) {
1138
1060
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -1141,53 +1063,53 @@ function HomeDashboardComponent_Conditional_15_Conditional_9_Template(rf, ctx) {
1141
1063
  i0.ɵɵadvance();
1142
1064
  i0.ɵɵconditional(ctx_r2.favoritesLoading ? 5 : -1);
1143
1065
  } }
1144
- function HomeDashboardComponent_Conditional_15_Conditional_10_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
1145
- const _r63 = i0.ɵɵgetCurrentView();
1146
- i0.ɵɵelementStart(0, "div", 172);
1147
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_15_Conditional_10_Conditional_4_For_2_Template_div_click_0_listener() { const item_r64 = i0.ɵɵrestoreView(_r63).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.onRecentClick(item_r64)); });
1148
- i0.ɵɵelementStart(1, "div", 168);
1066
+ function HomeDashboardComponent_Conditional_12_Conditional_10_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
1067
+ const _r59 = i0.ɵɵgetCurrentView();
1068
+ i0.ɵɵelementStart(0, "div", 188);
1069
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_12_Conditional_10_Conditional_4_For_2_Template_div_click_0_listener() { const item_r60 = i0.ɵɵrestoreView(_r59).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.onRecentClick(item_r60)); });
1070
+ i0.ɵɵelementStart(1, "div", 184);
1149
1071
  i0.ɵɵelement(2, "i");
1150
1072
  i0.ɵɵelementEnd();
1151
- i0.ɵɵelementStart(3, "div", 161)(4, "span", 162);
1073
+ i0.ɵɵelementStart(3, "div", 177)(4, "span", 178);
1152
1074
  i0.ɵɵtext(5);
1153
1075
  i0.ɵɵelementEnd();
1154
- i0.ɵɵelementStart(6, "span", 163);
1076
+ i0.ɵɵelementStart(6, "span", 179);
1155
1077
  i0.ɵɵtext(7);
1156
1078
  i0.ɵɵelementEnd()()();
1157
1079
  } if (rf & 2) {
1158
- const item_r64 = ctx.$implicit;
1080
+ const item_r60 = ctx.$implicit;
1159
1081
  const ctx_r2 = i0.ɵɵnextContext(4);
1160
- i0.ɵɵproperty("mjClickable", item_r64.recordName || item_r64.recordId);
1082
+ i0.ɵɵproperty("mjClickable", item_r60.recordName || item_r60.recordId);
1161
1083
  i0.ɵɵadvance(2);
1162
- i0.ɵɵclassMap(ctx_r2.getEntityIconByName(item_r64.entityName));
1084
+ i0.ɵɵclassMap(ctx_r2.getEntityIconByName(item_r60.entityName));
1163
1085
  i0.ɵɵadvance(3);
1164
- i0.ɵɵtextInterpolate(item_r64.recordName || item_r64.recordId);
1086
+ i0.ɵɵtextInterpolate(item_r60.recordName || item_r60.recordId);
1165
1087
  i0.ɵɵadvance(2);
1166
- i0.ɵɵtextInterpolate2("", item_r64.entityName, " \u00B7 ", ctx_r2.formatDate(item_r64.latestAt));
1088
+ i0.ɵɵtextInterpolate2("", item_r60.entityName, " \u00B7 ", ctx_r2.formatDate(item_r60.latestAt));
1167
1089
  } }
1168
- function HomeDashboardComponent_Conditional_15_Conditional_10_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1169
- i0.ɵɵelementStart(0, "div", 158);
1170
- i0.ɵɵrepeaterCreate(1, HomeDashboardComponent_Conditional_15_Conditional_10_Conditional_4_For_2_Template, 8, 6, "div", 171, i0.ɵɵcomponentInstance().trackByRecent, true);
1090
+ function HomeDashboardComponent_Conditional_12_Conditional_10_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1091
+ i0.ɵɵelementStart(0, "div", 174);
1092
+ i0.ɵɵrepeaterCreate(1, HomeDashboardComponent_Conditional_12_Conditional_10_Conditional_4_For_2_Template, 8, 6, "div", 187, i0.ɵɵcomponentInstance().trackByRecent, true);
1171
1093
  i0.ɵɵelementEnd();
1172
1094
  } if (rf & 2) {
1173
1095
  const ctx_r2 = i0.ɵɵnextContext(3);
1174
1096
  i0.ɵɵadvance();
1175
1097
  i0.ɵɵrepeater(ctx_r2.recentItems);
1176
1098
  } }
1177
- function HomeDashboardComponent_Conditional_15_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1178
- i0.ɵɵelementStart(0, "div", 165);
1179
- i0.ɵɵelement(1, "i", 169);
1099
+ function HomeDashboardComponent_Conditional_12_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1100
+ i0.ɵɵelementStart(0, "div", 181);
1101
+ i0.ɵɵelement(1, "i", 185);
1180
1102
  i0.ɵɵelementStart(2, "span");
1181
1103
  i0.ɵɵtext(3, "Loading...");
1182
1104
  i0.ɵɵelementEnd()();
1183
1105
  } }
1184
- function HomeDashboardComponent_Conditional_15_Conditional_10_Template(rf, ctx) { if (rf & 1) {
1185
- i0.ɵɵelementStart(0, "div", 153)(1, "h4", 155);
1186
- i0.ɵɵelement(2, "i", 170);
1106
+ function HomeDashboardComponent_Conditional_12_Conditional_10_Template(rf, ctx) { if (rf & 1) {
1107
+ i0.ɵɵelementStart(0, "div", 169)(1, "h4", 171);
1108
+ i0.ɵɵelement(2, "i", 186);
1187
1109
  i0.ɵɵtext(3, " Recent ");
1188
1110
  i0.ɵɵelementEnd();
1189
- i0.ɵɵconditionalCreate(4, HomeDashboardComponent_Conditional_15_Conditional_10_Conditional_4_Template, 3, 0, "div", 158);
1190
- i0.ɵɵconditionalCreate(5, HomeDashboardComponent_Conditional_15_Conditional_10_Conditional_5_Template, 4, 0, "div", 165);
1111
+ i0.ɵɵconditionalCreate(4, HomeDashboardComponent_Conditional_12_Conditional_10_Conditional_4_Template, 3, 0, "div", 174);
1112
+ i0.ɵɵconditionalCreate(5, HomeDashboardComponent_Conditional_12_Conditional_10_Conditional_5_Template, 4, 0, "div", 181);
1191
1113
  i0.ɵɵelementEnd();
1192
1114
  } if (rf & 2) {
1193
1115
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -1196,24 +1118,24 @@ function HomeDashboardComponent_Conditional_15_Conditional_10_Template(rf, ctx)
1196
1118
  i0.ɵɵadvance();
1197
1119
  i0.ɵɵconditional(ctx_r2.recentsLoading ? 5 : -1);
1198
1120
  } }
1199
- function HomeDashboardComponent_Conditional_15_Conditional_11_Template(rf, ctx) { if (rf & 1) {
1200
- i0.ɵɵelement(0, "mj-empty-state", 154);
1121
+ function HomeDashboardComponent_Conditional_12_Conditional_11_Template(rf, ctx) { if (rf & 1) {
1122
+ i0.ɵɵelement(0, "mj-empty-state", 170);
1201
1123
  } }
1202
- function HomeDashboardComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
1203
- const _r58 = i0.ɵɵgetCurrentView();
1204
- i0.ɵɵelementStart(0, "div", 12)(1, "div", 148)(2, "h3");
1205
- i0.ɵɵelement(3, "i", 129);
1124
+ function HomeDashboardComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
1125
+ const _r54 = i0.ɵɵgetCurrentView();
1126
+ i0.ɵɵelementStart(0, "div", 13)(1, "div", 164)(2, "h3");
1127
+ i0.ɵɵelement(3, "i", 160);
1206
1128
  i0.ɵɵtext(4, " Quick Access ");
1207
1129
  i0.ɵɵelementEnd();
1208
- i0.ɵɵelementStart(5, "button", 149);
1209
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_15_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r58); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleSidebar()); });
1210
- i0.ɵɵelement(6, "i", 36);
1130
+ i0.ɵɵelementStart(5, "button", 165);
1131
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_12_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r54); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleSidebar()); });
1132
+ i0.ɵɵelement(6, "i", 52);
1211
1133
  i0.ɵɵelementEnd()();
1212
- i0.ɵɵelementStart(7, "div", 150);
1213
- i0.ɵɵconditionalCreate(8, HomeDashboardComponent_Conditional_15_Conditional_8_Template, 9, 1, "div", 151);
1214
- i0.ɵɵconditionalCreate(9, HomeDashboardComponent_Conditional_15_Conditional_9_Template, 6, 2, "div", 152);
1215
- i0.ɵɵconditionalCreate(10, HomeDashboardComponent_Conditional_15_Conditional_10_Template, 6, 2, "div", 153);
1216
- i0.ɵɵconditionalCreate(11, HomeDashboardComponent_Conditional_15_Conditional_11_Template, 1, 0, "mj-empty-state", 154);
1134
+ i0.ɵɵelementStart(7, "div", 166);
1135
+ i0.ɵɵconditionalCreate(8, HomeDashboardComponent_Conditional_12_Conditional_8_Template, 9, 1, "div", 167);
1136
+ i0.ɵɵconditionalCreate(9, HomeDashboardComponent_Conditional_12_Conditional_9_Template, 6, 2, "div", 168);
1137
+ i0.ɵɵconditionalCreate(10, HomeDashboardComponent_Conditional_12_Conditional_10_Template, 6, 2, "div", 169);
1138
+ i0.ɵɵconditionalCreate(11, HomeDashboardComponent_Conditional_12_Conditional_11_Template, 1, 0, "mj-empty-state", 170);
1217
1139
  i0.ɵɵelementEnd()();
1218
1140
  } if (rf & 2) {
1219
1141
  const ctx_r2 = i0.ɵɵnextContext();
@@ -1226,8 +1148,8 @@ function HomeDashboardComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
1226
1148
  i0.ɵɵadvance();
1227
1149
  i0.ɵɵconditional(!ctx_r2.favoritesLoading && !ctx_r2.recentsLoading && ctx_r2.unreadNotifications.length === 0 && ctx_r2.favorites.length === 0 && ctx_r2.recentItems.length === 0 ? 11 : -1);
1228
1150
  } }
1229
- function HomeDashboardComponent_Conditional_16_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1230
- i0.ɵɵelementStart(0, "span", 174);
1151
+ function HomeDashboardComponent_Conditional_13_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1152
+ i0.ɵɵelementStart(0, "span", 190);
1231
1153
  i0.ɵɵtext(1);
1232
1154
  i0.ɵɵelementEnd();
1233
1155
  } if (rf & 2) {
@@ -1235,18 +1157,32 @@ function HomeDashboardComponent_Conditional_16_Conditional_2_Template(rf, ctx) {
1235
1157
  i0.ɵɵadvance();
1236
1158
  i0.ɵɵtextInterpolate(ctx_r2.unreadNotifications.length);
1237
1159
  } }
1238
- function HomeDashboardComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
1239
- const _r65 = i0.ɵɵgetCurrentView();
1240
- i0.ɵɵelementStart(0, "button", 173);
1241
- i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_16_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r65); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleSidebar()); });
1242
- i0.ɵɵelement(1, "i", 129);
1243
- i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_16_Conditional_2_Template, 2, 1, "span", 174);
1160
+ function HomeDashboardComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
1161
+ const _r61 = i0.ɵɵgetCurrentView();
1162
+ i0.ɵɵelementStart(0, "button", 189);
1163
+ i0.ɵɵlistener("click", function HomeDashboardComponent_Conditional_13_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r61); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleSidebar()); });
1164
+ i0.ɵɵelement(1, "i", 160);
1165
+ i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_13_Conditional_2_Template, 2, 1, "span", 190);
1244
1166
  i0.ɵɵelementEnd();
1245
1167
  } if (rf & 2) {
1246
1168
  const ctx_r2 = i0.ɵɵnextContext();
1247
1169
  i0.ɵɵadvance(2);
1248
1170
  i0.ɵɵconditional(ctx_r2.unreadNotifications.length > 0 ? 2 : -1);
1249
1171
  } }
1172
+ /** User setting for the Pinned section: 'true' when collapsed, 'false' when open. A missing setting means open. */
1173
+ const PINNED_COLLAPSED_SETTING = 'HomeApp.PinnedCollapsed';
1174
+ /** The query param that names the dashboard Home shows in place of its overview. */
1175
+ const DASHBOARD_QUERY_PARAM = 'dashboard';
1176
+ /** The dashboard view's title: the switcher button that names the open dashboard. */
1177
+ const DASHBOARD_TITLE_SELECTOR = '.dashboard-title .switcher-title';
1178
+ /** The notice when Home cannot show the dashboard the URL or the editor names. */
1179
+ const DASHBOARD_NOT_AVAILABLE = 'That dashboard is not available';
1180
+ /** The name the SwitchHomeDashboard agent tool takes for Home's overview (any letter case). */
1181
+ const HOME_OVERVIEW_NAME = 'Home';
1182
+ /** Width of the pin options menu, in pixels. */
1183
+ const PIN_MENU_WIDTH = 220;
1184
+ /** Process-wide counter for the ids that label each Home's pin menu groups. */
1185
+ let nextPinMenuUid = 0;
1250
1186
  /**
1251
1187
  * Home Dashboard - Personalized home screen showing all available applications
1252
1188
  * with quick access navigation and configuration options.
@@ -1262,7 +1198,11 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1262
1198
  destroy$ = new Subject();
1263
1199
  metadata = this.ProviderToUse;
1264
1200
  pinService = inject(HomeAppPinService);
1201
+ confirmService = inject(MJConfirmService);
1202
+ hostElement = inject(ElementRef);
1265
1203
  AppConfigDialog;
1204
+ pinMenuEl;
1205
+ dashboardEditor;
1266
1206
  /** @deprecated Use {@link AppConfigDialog}. */
1267
1207
  get appConfigDialog() {
1268
1208
  return this.AppConfigDialog;
@@ -1272,6 +1212,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1272
1212
  this.AppConfigDialog = value;
1273
1213
  }
1274
1214
  // State
1215
+ /** True until Home's first load finishes; the page shows its loading view meanwhile. A later app-list reload does not set it. */
1275
1216
  isLoading = true;
1276
1217
  Apps = [];
1277
1218
  /** @deprecated Use {@link Apps}. */
@@ -1378,10 +1319,14 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1378
1319
  }
1379
1320
  // Pin empty-state dismissal preference (persisted in UserSettings via UserInfoEngine)
1380
1321
  HidePinEmptyState = false;
1322
+ /** Whether the Pinned section is open. Saved for each user in the HomeApp.PinnedCollapsed setting. */
1323
+ PinnedExpanded = true;
1381
1324
  // Pin state
1382
1325
  PinnedItems = [];
1383
1326
  UngroupedPins = [];
1384
1327
  PinGroups = [];
1328
+ /** The pin grid's runs: ungrouped pins first, then each group in group order. */
1329
+ PinSections = [];
1385
1330
  EditMode = false;
1386
1331
  AddPanelOpen = false;
1387
1332
  AddPanelSearchQuery = '';
@@ -1409,9 +1354,50 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1409
1354
  PinMenuVisible = false;
1410
1355
  PinMenuX = 0;
1411
1356
  PinMenuY = 0;
1357
+ /** The pin menu's max height in pixels: the room on its side of the button. Null while the menu is measured. */
1358
+ PinMenuMaxHeight = null;
1412
1359
  PinMenuPin = null;
1413
- // Whether Data Explorer app is available (if so, dashboards/queries/views are accessible via its nav items)
1360
+ /** Id of the menu's "Move to Group" header, which names the group rows. */
1361
+ PinMenuGroupLabelId = `home-pin-menu-groups-${nextPinMenuUid++}`;
1362
+ /** The ellipsis button that opened the pin options menu. Escape and Tab put focus back on it. */
1363
+ pinMenuTrigger = null;
1364
+ // Whether the Add Pin panel found the Data Explorer app. Query pins then open in its Queries nav item.
1414
1365
  HasDataExplorerApp = false;
1366
+ // Dashboard view: a pinned dashboard shown in place of the overview
1367
+ /** The dashboard Home shows in place of its overview, or null on the overview. */
1368
+ CurrentDashboard = null;
1369
+ /** ID of that dashboard, or null. */
1370
+ CurrentDashboardId = null;
1371
+ /** True when the dashboard view opens in edit mode. The editor reads it once, then sets it back to false. */
1372
+ DashboardStartsInEditMode = false;
1373
+ /** True while the dashboard Home shows is in edit mode. */
1374
+ IsDashboardEditing = false;
1375
+ /** The pinned Config dashboards, in pin order, for the Dashboards switcher. */
1376
+ PinnedDashboards = [];
1377
+ /** The names dashboard pins show, by pin id: their dashboards' names from the dashboard cache. */
1378
+ pinDashboardNames = new Map();
1379
+ /** True once the first load of the dashboard cache has finished, also when it failed. */
1380
+ dashboardCacheLoaded = false;
1381
+ /** The dashboard the URL asks for; shown once the dashboard cache has loaded. */
1382
+ requestedDashboardId = null;
1383
+ /**
1384
+ * The dashboard Home shows because a URL change named it: back, forward or a deep link into the open tab. When the
1385
+ * editor cannot show it, Home leaves the URL as it is. Home's first load does not set it, and any other change of the
1386
+ * shown dashboard clears it.
1387
+ */
1388
+ urlShownDashboardId = null;
1389
+ /**
1390
+ * The dashboard whose title gets focus when the editor has shown it: one the user picked in a switcher or opened from a
1391
+ * pin, or one an agent showed after its switch removed the part of Home that had focus.
1392
+ */
1393
+ focusTitleOnLoad = null;
1394
+ // New dashboard: the name dialog
1395
+ /** True while the New dashboard name dialog is open. */
1396
+ ShowNewDashboardDialog = false;
1397
+ /** True while the named dashboard is being created. */
1398
+ IsCreatingDashboard = false;
1399
+ /** The longest name the dialog accepts. */
1400
+ NewDashboardNameMaxLength = DASHBOARD_NAME_MAX_LENGTH;
1415
1401
  // Drag state
1416
1402
  DraggingPinId = null;
1417
1403
  DragOverPinId = null;
@@ -1428,6 +1414,26 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1428
1414
  set favoriteDisplayNames(value) {
1429
1415
  this.FavoriteDisplayNames = value;
1430
1416
  }
1417
+ /** True when Home shows its overview: the greeting, Pinned and My applications. */
1418
+ get ShowOverview() {
1419
+ return !this.isLoading && !this.CurrentDashboard;
1420
+ }
1421
+ /** True when Home shows a dashboard in place of its overview. */
1422
+ get ShowDashboardView() {
1423
+ return !this.isLoading && this.CurrentDashboard !== null;
1424
+ }
1425
+ /** The Quick Access button and sidebar show on the overview only: in the dashboard view the button would cover the header's actions. */
1426
+ get ShowQuickAccess() {
1427
+ return this.HasSidebarContent && !this.CurrentDashboard;
1428
+ }
1429
+ /** The name of the dashboard Home shows, from the dashboard cache; null on the overview. */
1430
+ get CurrentDashboardName() {
1431
+ return this.CurrentDashboardId ? this.cachedDashboardName(this.CurrentDashboardId) : null;
1432
+ }
1433
+ /** True while the dashboard Home shows is in edit mode (see BaseResourceComponent.IsEditing). */
1434
+ IsEditing() {
1435
+ return this.IsDashboardEditing;
1436
+ }
1431
1437
  /**
1432
1438
  * Check if sidebar has any content to show
1433
1439
  */
@@ -1443,10 +1449,12 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1443
1449
  return this.HasSidebarContent;
1444
1450
  }
1445
1451
  /**
1446
- * Toggle sidebar visibility
1452
+ * Opens or closes the Quick Access sidebar and marks Home for check, so the change shows at the next render also
1453
+ * when the agent's ToggleSidebar tool calls this outside a template event.
1447
1454
  */
1448
1455
  ToggleSidebar() {
1449
1456
  this.SidebarOpen = !this.SidebarOpen;
1457
+ this.cdr.markForCheck();
1450
1458
  }
1451
1459
  /** @deprecated Use {@link ToggleSidebar}. */
1452
1460
  toggleSidebar() {
@@ -1474,20 +1482,20 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1474
1482
  // Get current user info
1475
1483
  this.CurrentUser = {
1476
1484
  Name: this.metadata.CurrentUser?.Name || 'User',
1477
- Email: this.metadata.CurrentUser?.Email || ''
1485
+ Email: this.metadata.CurrentUser?.Email || '',
1486
+ FirstName: this.metadata.CurrentUser?.FirstName || ''
1478
1487
  };
1479
- // Subscribe to loading state from ApplicationManager
1480
- this.appManager.Loading
1481
- .pipe(takeUntil(this.destroy$))
1482
- .subscribe(loading => {
1483
- // Only update isLoading if manager is actively loading
1484
- // (we start with isLoading=true and only set to false when we have apps)
1485
- if (loading) {
1486
- this.isLoading = true;
1487
- this.cdr.markForCheck();
1488
- }
1489
- });
1490
- // Subscribe to applications list, filtering out the Home app
1488
+ this.loadSectionStates();
1489
+ // The dashboard the tab's data names, for when the query-param stream has not delivered one
1490
+ const initialDashboard = this.GetQueryParams()[DASHBOARD_QUERY_PARAM]?.trim();
1491
+ if (initialDashboard && !this.requestedDashboardId) {
1492
+ this.requestedDashboardId = initialDashboard;
1493
+ }
1494
+ // The Dashboards part of the first load: the automatic app install and the dashboard cache
1495
+ const dashboardsLoad = this.loadDashboards();
1496
+ // Subscribe to applications list, filtering out the Home app. The loading view shows during the first load
1497
+ // only: a later reload of the list (an app install) keeps the page as it is, so an open dashboard and its edit
1498
+ // stay, and the overview keeps its apps until the new list arrives.
1491
1499
  this.appManager.Applications
1492
1500
  .pipe(takeUntil(this.destroy$))
1493
1501
  .subscribe(async (apps) => {
@@ -1495,6 +1503,8 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1495
1503
  this.Apps = apps.filter(app => app.Name !== 'Home');
1496
1504
  // Pre-compute display data for all apps
1497
1505
  await this.computeAppsDisplayData();
1506
+ // The page shows once the Dashboards part of the first load is done (see loadDashboards)
1507
+ await dashboardsLoad;
1498
1508
  this.isLoading = false;
1499
1509
  this.NotifyLoadComplete();
1500
1510
  // Apps changed → keep the agent's view of the launcher in sync.
@@ -1519,6 +1529,10 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1519
1529
  this.publishAgentContext();
1520
1530
  this.cdr.markForCheck();
1521
1531
  });
1532
+ // The switcher, the dashboard pin names and the open dashboard follow changes to the dashboard cache
1533
+ ObserveDashboardLibraryChanges()
1534
+ .pipe(takeUntil(this.destroy$))
1535
+ .subscribe(() => this.refreshPinnedDashboards());
1522
1536
  // Favorites and recents load asynchronously in the sidebar
1523
1537
  this.NotifyLoadComplete();
1524
1538
  // Load favorites and recents asynchronously (don't block rendering)
@@ -1535,8 +1549,11 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1535
1549
  this.PinnedItems = pins;
1536
1550
  this.UngroupedPins = this.pinService.GetUngroupedPins();
1537
1551
  this.PinGroups = this.pinService.GetGroups();
1538
- this.publishAgentContext();
1539
- this.cdr.markForCheck();
1552
+ this.PinSections = [
1553
+ { Key: 'ungrouped', Group: null, Pins: this.UngroupedPins },
1554
+ ...this.PinGroups.map(group => ({ Key: `group:${group}`, Group: group, Pins: this.pinService.GetPinsInGroup(group) })),
1555
+ ];
1556
+ this.refreshPinnedDashboards();
1540
1557
  });
1541
1558
  // Resolve display names for record-type pins that have raw ID titles
1542
1559
  this.resolveRecordPinNames();
@@ -1562,11 +1579,16 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1562
1579
  //
1563
1580
  // 🚨 SAFETY BOUNDARY: the Home dashboard exposes ONLY navigation / discovery /
1564
1581
  // panel-toggle operations to the agent. No pin create, no pin delete, no pin
1565
- // rename, no group mutation, no reordering — those are user-confirm-driven or
1566
- // destructive and stay in the UI. Every tool below maps to the exact same
1567
- // component method a user click would call (OpenApp→onAppClick, OpenPin→OnPinClick,
1568
- // search→AddPanel search field, panel/sidebar/edit-mode toggles). Handlers are
1569
- // tolerant: they never throw, returning { Success, Data?, ErrorMessage? }.
1582
+ // rename, no group mutation, no reordering, and no dashboard create, rename,
1583
+ // edit, save or delete — those are user-confirm-driven or destructive and stay
1584
+ // in the UI. Home registers no dashboard edit tools for the dashboard it shows
1585
+ // (those are on the dashboard tab). Every tool below maps to the exact same
1586
+ // component method a user click would call (OpenApp→OnAppClick, OpenPin→openPin,
1587
+ // which a pin click calls, SwitchHomeDashboard→OpenDashboardInHome / GoHome,
1588
+ // which a switcher pick calls, search→AddPanel search field, panel/sidebar/
1589
+ // edit-mode toggles). Leaving a dashboard with unsaved changes asks the user
1590
+ // first, as it does for a click. Handlers are tolerant: they never throw,
1591
+ // returning { Success, Data?, ErrorMessage? }.
1570
1592
  /**
1571
1593
  * Publish the current Home dashboard state to the AI agent via NavigationService.
1572
1594
  * The shaping lives in the pure {@link buildHomeAgentContext} helper so it stays
@@ -1580,7 +1602,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1580
1602
  PinnedItemCount: this.PinnedItems.length,
1581
1603
  PinGroupCount: this.PinGroups.length,
1582
1604
  PinGroupNames: this.PinGroups,
1583
- PinNames: this.PinnedItems.map(p => p.DisplayName),
1605
+ PinNames: this.PinnedItems.map(p => this.PinName(p)),
1584
1606
  UnreadNotifications: this.UnreadNotifications.length,
1585
1607
  NotificationTitles: this.UnreadNotifications.map(n => n.Title ?? '(untitled)'),
1586
1608
  RecentItemsCount: this.RecentItems.length,
@@ -1589,6 +1611,11 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1589
1611
  AddPanelOpen: this.AddPanelOpen,
1590
1612
  SidebarOpen: this.SidebarOpen,
1591
1613
  AddPanelSearchQuery: this.AddPanelSearchQuery,
1614
+ PinnedCollapsed: !this.PinnedExpanded,
1615
+ CurrentDashboardName: this.CurrentDashboardName,
1616
+ CurrentDashboardID: this.CurrentDashboardId,
1617
+ IsEditingDashboard: this.IsDashboardEditing,
1618
+ PinnedDashboardNames: this.PinnedDashboards.map(d => d.Name),
1592
1619
  });
1593
1620
  this.navigationService.SetAgentContext(this, context);
1594
1621
  }
@@ -1607,14 +1634,16 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1607
1634
  *
1608
1635
  * Tools:
1609
1636
  * - OpenApp: switch to an application by name (exact or partial match).
1610
- * - OpenPin: open a pinned item by its display name (exact or partial match).
1637
+ * - OpenPin: open a pinned item by the name it shows (exact or partial match). A pinned dashboard opens inside Home.
1611
1638
  * - SearchPins: find pinned items by a name query (read-only — returns matches).
1612
1639
  * - OpenRecent: open a recently-accessed item by display name (read-only navigation).
1613
1640
  * - SearchAddPinPanel: open the Add Pin panel (if needed) and apply a search query.
1614
1641
  * - ClearAddPinPanelSearch: clear the Add Pin panel search query.
1615
1642
  * - OpenAddPinPanel / CloseAddPinPanel: toggle the Add Pin panel.
1616
- * - ToggleSidebar: toggle the notifications/favorites/recents sidebar.
1617
- * - TogglePinEditMode: toggle pin edit mode (reorder/rename UI affordances).
1643
+ * - ToggleSidebar: toggle the notifications/favorites/recents sidebar (on the overview only).
1644
+ * - TogglePinEditMode: toggle pin edit mode (reorder/rename UI affordances; on the overview only).
1645
+ * - SwitchHomeDashboard: show a pinned dashboard inside Home by its name (exact or partial match) or id, or "Home"
1646
+ * for the overview.
1618
1647
  */
1619
1648
  registerAgentClientTools() {
1620
1649
  this.navigationService.SetAgentClientTools(this, [
@@ -1626,13 +1655,13 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1626
1655
  },
1627
1656
  {
1628
1657
  Name: 'OpenPin',
1629
- Description: 'Open a pinned item on the Home screen by its display name (exact or partial match).',
1658
+ Description: 'Open a pinned item on the Home screen by the name it shows (exact or partial match). A pinned dashboard opens inside Home; other pins open as before.',
1630
1659
  ParameterSchema: { type: 'object', properties: { pinName: { type: 'string' } }, required: ['pinName'] },
1631
1660
  Handler: async (params) => this.toolOpenPin(params),
1632
1661
  },
1633
1662
  {
1634
1663
  Name: 'SearchPins',
1635
- Description: 'Find pinned items on the Home screen whose display name matches a query (case-insensitive contains). Read-only — returns the matching pin names; does not open anything.',
1664
+ Description: 'Find pinned items on the Home screen whose name, as the pin shows it, matches a query (case-insensitive contains). Read-only — returns the matching pin names; does not open anything.',
1636
1665
  ParameterSchema: { type: 'object', properties: { query: { type: 'string' } }, required: ['query'] },
1637
1666
  Handler: async (params) => this.toolSearchPins(params),
1638
1667
  },
@@ -1676,23 +1705,21 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1676
1705
  },
1677
1706
  {
1678
1707
  Name: 'ToggleSidebar',
1679
- Description: 'Toggle the Home sidebar (unread notifications, favorites, and recent items).',
1708
+ Description: `Toggle the Home sidebar (unread notifications, favorites, and recent items). Quick Access shows on the ${HOME_OVERVIEW_NAME} overview only: while Home shows a dashboard, use SwitchHomeDashboard with "${HOME_OVERVIEW_NAME}" first.`,
1680
1709
  ParameterSchema: { type: 'object', properties: {} },
1681
- Handler: async () => {
1682
- this.ToggleSidebar();
1683
- this.publishAgentContext();
1684
- return { Success: true, Data: { SidebarOpen: this.SidebarOpen } };
1685
- },
1710
+ Handler: async () => this.toolToggleSidebar(),
1686
1711
  },
1687
1712
  {
1688
1713
  Name: 'TogglePinEditMode',
1689
- Description: 'Toggle pin edit mode on the Home screen (lets the user rename/reorder pins). This only changes the UI mode — it does not modify any pins.',
1714
+ Description: `Toggle pin edit mode on the Home overview (lets the user rename/reorder pins). This only changes the UI mode — it does not modify any pins. Pin edit mode shows on the ${HOME_OVERVIEW_NAME} overview only: while Home shows a dashboard, use SwitchHomeDashboard with "${HOME_OVERVIEW_NAME}" first.`,
1690
1715
  ParameterSchema: { type: 'object', properties: {} },
1691
- Handler: async () => {
1692
- this.ToggleEditMode();
1693
- this.publishAgentContext();
1694
- return { Success: true, Data: { EditMode: this.EditMode } };
1695
- },
1716
+ Handler: async () => this.toolTogglePinEditMode(),
1717
+ },
1718
+ {
1719
+ Name: 'SwitchHomeDashboard',
1720
+ Description: `Show a pinned dashboard inside Home by its name (exact or partial match) or id, or "${HOME_OVERVIEW_NAME}" to return to the Home overview. Navigation only — it does not pin, unpin, rename or edit dashboards. When the open dashboard has unsaved changes, the user is asked first.`,
1721
+ ParameterSchema: { type: 'object', properties: { dashboard: { type: 'string' } }, required: ['dashboard'] },
1722
+ Handler: async (params) => this.toolSwitchHomeDashboard(params),
1696
1723
  },
1697
1724
  ]);
1698
1725
  }
@@ -1718,12 +1745,15 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1718
1745
  await this.OnAppClick(app);
1719
1746
  return { Success: true, Data: { AppName: app.Name } };
1720
1747
  }
1721
- /** The pinned items narrowed to the resolver's structural shape (Name == DisplayName). */
1748
+ /** The pinned items with the names they show, for the resolver. */
1722
1749
  get pinNamedRecords() {
1723
- return this.PinnedItems.map(p => ({ Name: p.DisplayName }));
1750
+ return this.PinnedItems.map(pin => ({ Name: this.PinName(pin), Pin: pin }));
1724
1751
  }
1725
- /** Resolve a pinned item by display name (exact then partial, case-insensitive) and open it. */
1726
- toolOpenPin(params) {
1752
+ /**
1753
+ * Resolve a pinned item by the name it shows (exact then partial, case-insensitive) and open it. A pinned dashboard
1754
+ * opens inside Home. Focus stays where it is unless the change removed it (see refocusIfRemoved).
1755
+ */
1756
+ async toolOpenPin(params) {
1727
1757
  const parsed = ValidateStringParam(params['pinName'], 'pinName');
1728
1758
  if (!parsed.ok) {
1729
1759
  return parsed.result;
@@ -1732,32 +1762,35 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1732
1762
  if (!pinName) {
1733
1763
  return { Success: false, ErrorMessage: 'pinName is required.' };
1734
1764
  }
1735
- const match = ResolveNamedRecord(pinName, this.pinNamedRecords);
1765
+ const records = this.pinNamedRecords;
1766
+ const match = ResolveNamedRecord(pinName, records);
1736
1767
  if (!match) {
1737
- return { Success: false, ErrorMessage: BuildHomeNotFoundError(pinName, 'pinned item', this.pinNamedRecords) };
1768
+ return { Success: false, ErrorMessage: BuildHomeNotFoundError(pinName, 'pinned item', records) };
1738
1769
  }
1739
- const pin = this.PinnedItems.find(p => p.DisplayName === match.Name);
1740
- if (!pin) {
1741
- return { Success: false, ErrorMessage: BuildHomeNotFoundError(pinName, 'pinned item', this.pinNamedRecords) };
1770
+ const opened = await this.switchViewForAgent(() => this.leaveEditModeAndOpenPin(match.Pin));
1771
+ if (!opened) {
1772
+ return { Success: false, ErrorMessage: `"${match.Name}" did not open. The pin may be broken, or the user kept editing the open dashboard.` };
1742
1773
  }
1743
- // OnPinClick is a no-op while in edit mode; clear edit mode so the open succeeds.
1774
+ return { Success: true, Data: { PinName: match.Name } };
1775
+ }
1776
+ /** Opens a pin for the agent. A pin does not open in edit mode: Home leaves it first, as Done does, and tells the agent. */
1777
+ leaveEditModeAndOpenPin(pin) {
1744
1778
  if (this.EditMode) {
1745
- this.EditMode = false;
1779
+ this.ToggleEditMode();
1780
+ this.publishAgentContext();
1746
1781
  }
1747
- this.OnPinClick(pin);
1748
- return { Success: true, Data: { PinName: pin.DisplayName } };
1782
+ return this.openPin(pin);
1749
1783
  }
1750
- /** Find pinned items whose display name matches a query (read-only — returns matches). */
1784
+ /** Find pinned items whose shown name matches a query (read-only — returns matches). */
1751
1785
  toolSearchPins(params) {
1752
1786
  const parsed = ValidateStringParam(params['query'], 'query');
1753
1787
  if (!parsed.ok) {
1754
1788
  return parsed.result;
1755
1789
  }
1756
1790
  const query = parsed.value.trim().toLowerCase();
1757
- const matches = query
1758
- ? this.PinnedItems.filter(p => p.DisplayName.toLowerCase().includes(query))
1759
- : [...this.PinnedItems];
1760
- return { Success: true, Data: { Matches: matches.map(p => p.DisplayName), MatchCount: matches.length } };
1791
+ const names = this.PinnedItems.map(p => this.PinName(p));
1792
+ const matches = query ? names.filter(name => name.toLowerCase().includes(query)) : names;
1793
+ return { Success: true, Data: { Matches: matches, MatchCount: matches.length } };
1761
1794
  }
1762
1795
  /** Resolve a recent item by display name (exact then partial) and navigate to it. */
1763
1796
  toolOpenRecent(params) {
@@ -1785,6 +1818,60 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1785
1818
  this.OnRecentClick(item);
1786
1819
  return { Success: true, Data: { Name: match.Name, ResourceType: item.resourceType } };
1787
1820
  }
1821
+ /**
1822
+ * Shows a pinned dashboard in Home by id (any letter case) or name (exact, then partial), or the overview for
1823
+ * "Home". It uses the methods a switcher pick uses, so the user is asked first about unsaved changes. Unlike a pick,
1824
+ * it moves focus only when the switch removed it (see refocusIfRemoved).
1825
+ */
1826
+ async toolSwitchHomeDashboard(params) {
1827
+ const parsed = ValidateStringParam(params['dashboard'], 'dashboard');
1828
+ if (!parsed.ok) {
1829
+ return parsed.result;
1830
+ }
1831
+ const reference = parsed.value.trim();
1832
+ if (!reference) {
1833
+ return { Success: false, ErrorMessage: 'dashboard is required.' };
1834
+ }
1835
+ if (reference.toLowerCase() === HOME_OVERVIEW_NAME.toLowerCase()) {
1836
+ return (await this.switchViewForAgent(() => this.GoHome()))
1837
+ ? { Success: true, Data: { HomeView: 'Overview' } }
1838
+ : { Success: false, ErrorMessage: `The ${HOME_OVERVIEW_NAME} overview did not open. The user kept editing the open dashboard.` };
1839
+ }
1840
+ const target = ResolvePinnedDashboardReference(reference, this.PinnedDashboards);
1841
+ if (!target) {
1842
+ const candidates = [{ Name: HOME_OVERVIEW_NAME }, ...this.PinnedDashboards.map(d => ({ Name: d.Name }))];
1843
+ return { Success: false, ErrorMessage: BuildHomeNotFoundError(reference, 'pinned dashboard', candidates) };
1844
+ }
1845
+ // The switcher's list can trail the dashboard cache by a moment
1846
+ if (!this.findHomeDashboard(target.ID)) {
1847
+ return { Success: false, ErrorMessage: `"${target.Name}" did not open. The dashboard is not available.` };
1848
+ }
1849
+ if (!(await this.switchViewForAgent(() => this.OpenDashboardInHome(target.ID)))) {
1850
+ return { Success: false, ErrorMessage: `"${target.Name}" did not open. The user kept editing the open dashboard.` };
1851
+ }
1852
+ return { Success: true, Data: { CurrentDashboardName: target.Name } };
1853
+ }
1854
+ /** Opens or closes Quick Access. While a dashboard shows, where Quick Access does not show, it changes nothing. */
1855
+ toolToggleSidebar() {
1856
+ if (this.CurrentDashboardId) {
1857
+ return { Success: false, ErrorMessage: overviewOnlyError('Quick Access') };
1858
+ }
1859
+ this.ToggleSidebar();
1860
+ this.publishAgentContext();
1861
+ return { Success: true, Data: { SidebarOpen: this.SidebarOpen } };
1862
+ }
1863
+ /**
1864
+ * Turns pin edit mode on or off. While a dashboard shows, where the pins do not show, it changes nothing: it neither
1865
+ * opens a collapsed Pinned section nor saves that.
1866
+ */
1867
+ toolTogglePinEditMode() {
1868
+ if (this.CurrentDashboardId) {
1869
+ return { Success: false, ErrorMessage: overviewOnlyError('Pin edit mode') };
1870
+ }
1871
+ this.ToggleEditMode();
1872
+ this.publishAgentContext();
1873
+ return { Success: true, Data: { EditMode: this.EditMode } };
1874
+ }
1788
1875
  /** Open the Add Pin panel (if needed) and apply a search query. */
1789
1876
  async toolSearchAddPinPanel(params) {
1790
1877
  const parsed = ValidateStringParam(params['query'], 'query');
@@ -1826,6 +1913,10 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1826
1913
  get greeting() {
1827
1914
  return this.Greeting;
1828
1915
  }
1916
+ /** The first name the greeting uses, or the user's display name. */
1917
+ get GreetingName() {
1918
+ return this.CurrentUser?.FirstName || this.CurrentUser?.Name || 'User';
1919
+ }
1829
1920
  /**
1830
1921
  * Get formatted date string
1831
1922
  */
@@ -1889,7 +1980,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
1889
1980
  }));
1890
1981
  return {
1891
1982
  app,
1892
- color: app.GetColor() || '#1976d2',
1983
+ color: app.GetColor() || 'var(--mj-brand-primary)',
1893
1984
  icon: app.Icon || 'fa-solid fa-cube',
1894
1985
  navItemsCount,
1895
1986
  navItemsPreview,
@@ -2019,10 +2110,10 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2019
2110
  // Navigate based on entity type using NavigationService
2020
2111
  const entityName = favorite.Entity?.toLowerCase();
2021
2112
  const recordId = favorite.RecordID;
2022
- if (entityName === 'dashboards') {
2023
- this.navigationService.OpenDashboard(recordId, 'Dashboard');
2113
+ if (IsDashboardEntity(favorite.Entity)) {
2114
+ this.openDashboard(recordId, 'Dashboard');
2024
2115
  }
2025
- else if (entityName === 'user views') {
2116
+ else if (ResourceTypeForEntity(favorite.Entity) === 'view') {
2026
2117
  this.navigationService.OpenView(recordId, 'View');
2027
2118
  }
2028
2119
  else if (entityName?.includes('artifact')) {
@@ -2051,7 +2142,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2051
2142
  this.navigationService.OpenView(item.recordId, name || 'View');
2052
2143
  break;
2053
2144
  case 'dashboard':
2054
- this.navigationService.OpenDashboard(item.recordId, name || 'Dashboard');
2145
+ this.openDashboard(item.recordId, name || 'Dashboard');
2055
2146
  break;
2056
2147
  case 'artifact':
2057
2148
  this.navigationService.OpenArtifact(item.recordId, name || 'Artifact');
@@ -2065,118 +2156,534 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2065
2156
  }
2066
2157
  }
2067
2158
  }
2068
- /** @deprecated Use {@link OnRecentClick}. */
2069
- onRecentClick(item) {
2070
- return this.OnRecentClick(item);
2159
+ /** @deprecated Use {@link OnRecentClick}. */
2160
+ onRecentClick(item) {
2161
+ return this.OnRecentClick(item);
2162
+ }
2163
+ /**
2164
+ * Navigate to a notification using NavigationService
2165
+ */
2166
+ OnNotificationClick(notification) {
2167
+ // Navigate to the notifications view using NavigationService
2168
+ this.navigationService.OpenDynamicView('MJ: User Notifications');
2169
+ }
2170
+ /** @deprecated Use {@link OnNotificationClick}. */
2171
+ onNotificationClick(notification) {
2172
+ return this.OnNotificationClick(notification);
2173
+ }
2174
+ /**
2175
+ * Get icon for an entity by name, using entity metadata Icon field (cached)
2176
+ */
2177
+ GetEntityIconByName(entityName) {
2178
+ if (!entityName)
2179
+ return 'fa-solid fa-file';
2180
+ const cached = this.resourceIconCache.get(entityName);
2181
+ if (cached)
2182
+ return cached;
2183
+ const entityInfo = this.metadata.Entities.find(e => e.Name === entityName);
2184
+ const icon = entityInfo ? this.resolveEntityIcon(entityInfo.Icon) : 'fa-solid fa-file';
2185
+ this.resourceIconCache.set(entityName, icon);
2186
+ return icon;
2187
+ }
2188
+ /** @deprecated Use {@link GetEntityIconByName}. */
2189
+ getEntityIconByName(entityName) {
2190
+ return this.GetEntityIconByName(entityName);
2191
+ }
2192
+ /**
2193
+ * Resolve an entity's Icon field to a full Font Awesome class string
2194
+ */
2195
+ resolveEntityIcon(icon) {
2196
+ if (!icon)
2197
+ return 'fa-solid fa-table';
2198
+ // Already has a style prefix
2199
+ if (icon.startsWith('fa-solid') || icon.startsWith('fa-regular') ||
2200
+ icon.startsWith('fa-light') || icon.startsWith('fa-brands') ||
2201
+ icon.startsWith('fa ')) {
2202
+ return icon;
2203
+ }
2204
+ // Has fa- prefix but no style
2205
+ if (icon.startsWith('fa-')) {
2206
+ return `fa-solid ${icon}`;
2207
+ }
2208
+ // Just an icon name like "table" or "users"
2209
+ return `fa-solid fa-${icon}`;
2210
+ }
2211
+ /**
2212
+ * Format a date for display (pure function, safe to call in template)
2213
+ */
2214
+ formatDate(date) {
2215
+ if (!date)
2216
+ return '';
2217
+ const now = new Date();
2218
+ const diff = now.getTime() - new Date(date).getTime();
2219
+ const days = Math.floor(diff / (1000 * 60 * 60 * 24));
2220
+ if (days === 0)
2221
+ return 'Today';
2222
+ if (days === 1)
2223
+ return 'Yesterday';
2224
+ if (days < 7)
2225
+ return `${days} days ago`;
2226
+ return new Date(date).toLocaleDateString();
2227
+ }
2228
+ /**
2229
+ * Track function for favorites
2230
+ */
2231
+ TrackByFavorite(_index, item) {
2232
+ return item.ID;
2233
+ }
2234
+ /** @deprecated Use {@link TrackByFavorite}. */
2235
+ trackByFavorite(_index, item) {
2236
+ return this.TrackByFavorite(_index, item);
2237
+ }
2238
+ /**
2239
+ * Remove duplicate recent items (same entity + recordId). Keeps the first occurrence.
2240
+ */
2241
+ deduplicateRecents(items) {
2242
+ const seen = new Set();
2243
+ return items.filter(item => {
2244
+ const key = `${item.entityName}-${item.recordId}`;
2245
+ if (seen.has(key)) {
2246
+ return false;
2247
+ }
2248
+ seen.add(key);
2249
+ return true;
2250
+ });
2251
+ }
2252
+ /**
2253
+ * Track function for recent items
2254
+ */
2255
+ TrackByRecent(_index, item) {
2256
+ return `${item.entityName}-${item.recordId}`;
2257
+ }
2258
+ /** @deprecated Use {@link TrackByRecent}. */
2259
+ trackByRecent(_index, item) {
2260
+ return this.TrackByRecent(_index, item);
2261
+ }
2262
+ /**
2263
+ * Track function for notifications
2264
+ */
2265
+ TrackByNotification(_index, item) {
2266
+ return item.ID;
2267
+ }
2268
+ /** @deprecated Use {@link TrackByNotification}. */
2269
+ trackByNotification(_index, item) {
2270
+ return this.TrackByNotification(_index, item);
2271
+ }
2272
+ // =============================================
2273
+ // DASHBOARDS APP AND CACHE
2274
+ // =============================================
2275
+ /**
2276
+ * The Dashboards part of Home's first load: the automatic Dashboards app install (at most once
2277
+ * per user) and the dashboard cache. Home stays on its loading view until both finish, so the
2278
+ * app-list reload that an install causes does not show a second loading view. Each install step
2279
+ * gives up after DASHBOARDS_APP_INSTALL_STEP_TIMEOUT_MS. The cache load has no time limit: Home
2280
+ * shows its loading view until the server answers or the load fails. Never rejects.
2281
+ */
2282
+ async loadDashboards() {
2283
+ await Promise.allSettled([AutoInstallDashboardsApp(this.appManager), this.loadDashboardCache()]);
2284
+ }
2285
+ /**
2286
+ * Loads the dashboard cache if it is not loaded yet, then reads the switcher's list and the dashboard pin names
2287
+ * from it and shows the dashboard the URL asks for (one Home cannot show is removed from the URL). A failed load is
2288
+ * only logged. Never rejects.
2289
+ */
2290
+ async loadDashboardCache() {
2291
+ try {
2292
+ await DashboardEngine.Instance.Config(false, this.ProviderToUse.CurrentUser, this.ProviderToUse);
2293
+ }
2294
+ catch (error) {
2295
+ LogError(`Home: could not load the dashboards: ${errorMessage(error)}`);
2296
+ }
2297
+ this.dashboardCacheLoaded = true;
2298
+ this.refreshPinnedDashboards();
2299
+ this.applyRequestedDashboard(true);
2300
+ }
2301
+ /** Reloads the dashboard cache, so a dashboard saved a moment ago is in it. A failure is only logged. */
2302
+ async reloadDashboardCache() {
2303
+ try {
2304
+ await DashboardEngine.Instance.Config(true, this.ProviderToUse.CurrentUser, this.ProviderToUse);
2305
+ }
2306
+ catch (error) {
2307
+ LogError(`Home: could not reload the dashboards: ${errorMessage(error)}`);
2308
+ }
2309
+ }
2310
+ /** The dashboards the user can open, from the dashboard cache; none when the user cannot read the cache. */
2311
+ accessibleDashboards() {
2312
+ const engine = DashboardEngine.Instance;
2313
+ return engine.IsPermissionConstrained ? [] : engine.GetAccessibleDashboards(this.ProviderToUse.CurrentUser.ID);
2314
+ }
2315
+ /** Re-reads the switcher's list and the names dashboard pins show, and keeps the open dashboard in step with the cache. */
2316
+ refreshPinnedDashboards() {
2317
+ const dashboards = this.accessibleDashboards();
2318
+ this.PinnedDashboards = BuildPinnedDashboards(this.PinnedItems, dashboards);
2319
+ this.pinDashboardNames = BuildPinDashboardNames(this.PinnedItems, dashboards);
2320
+ this.syncCurrentDashboard(dashboards);
2321
+ this.publishAgentContext();
2322
+ this.cdr.markForCheck();
2323
+ }
2324
+ /**
2325
+ * Opens a dashboard in place of the preview tab, which is usually the tab that shows Home, so Back
2326
+ * returns to Home. A Shift-click opens it in a separate tab.
2327
+ */
2328
+ openDashboard(dashboardId, dashboardName) {
2329
+ this.navigationService.OpenDashboard(dashboardId, dashboardName);
2330
+ }
2331
+ /**
2332
+ * Follows a link from a panel of the dashboard Home shows: a record, a dashboard or a query, as the
2333
+ * dashboard tab does. Other link types are only logged.
2334
+ */
2335
+ OnDashboardNavigationRequested(event) {
2336
+ const request = event.request;
2337
+ switch (request.type) {
2338
+ case 'OpenEntityRecord': {
2339
+ const key = CompositeKey.FromURLSegment(this.ProviderToUse.EntityByName(request.entityName), request.recordId);
2340
+ this.navigationService.OpenEntityRecord(request.entityName, key);
2341
+ break;
2342
+ }
2343
+ case 'OpenDashboard':
2344
+ this.openDashboard(request.dashboardId, this.cachedDashboardName(request.dashboardId));
2345
+ break;
2346
+ case 'OpenQuery':
2347
+ this.navigationService.OpenQuery(request.queryId, 'Query');
2348
+ break;
2349
+ default:
2350
+ console.warn(`[Home] A dashboard panel asked for a link type that Home does not open: ${request.type}`);
2351
+ }
2352
+ }
2353
+ /** The dashboard's name from the dashboard cache, or 'Dashboard' when the cache does not have it. */
2354
+ cachedDashboardName(dashboardId) {
2355
+ const engine = DashboardEngine.Instance;
2356
+ if (engine.IsPermissionConstrained) {
2357
+ return 'Dashboard';
2358
+ }
2359
+ return engine.Dashboards.find(d => UUIDsEqual(d.ID, dashboardId))?.Name ?? 'Dashboard';
2360
+ }
2361
+ // =============================================
2362
+ // DASHBOARD VIEW
2363
+ // =============================================
2364
+ /**
2365
+ * Shows a dashboard inside Home in place of the overview and writes it to the URL (?dashboard=<id>). Only a Config
2366
+ * dashboard the user can open shows in Home. Asks first when the open dashboard has unsaved changes. Returns false
2367
+ * when the dashboard did not open.
2368
+ */
2369
+ async OpenDashboardInHome(dashboardId, startInEditMode = false) {
2370
+ const dashboard = this.findHomeDashboard(dashboardId);
2371
+ if (!dashboard)
2372
+ return false;
2373
+ if (UUIDsEqual(dashboard.ID, this.CurrentDashboardId))
2374
+ return true;
2375
+ if (!(await this.confirmLeaveDashboard()))
2376
+ return false;
2377
+ // Another open of the same dashboard (a double click) finished meanwhile
2378
+ if (UUIDsEqual(dashboard.ID, this.CurrentDashboardId))
2379
+ return true;
2380
+ this.requestedDashboardId = dashboard.ID;
2381
+ this.setCurrentDashboard(dashboard, startInEditMode);
2382
+ this.UpdateQueryParams({ [DASHBOARD_QUERY_PARAM]: dashboard.ID });
2383
+ void this.recentAccessService.LogAccess('MJ: Dashboards', dashboard.ID, 'dashboard');
2384
+ return true;
2385
+ }
2386
+ /**
2387
+ * Returns to the overview (switcher Home, breadcrumb Home) and removes the dashboard from the URL. Asks first when
2388
+ * the open dashboard has unsaved changes. Returns false when the user keeps editing.
2389
+ */
2390
+ async GoHome() {
2391
+ if (!this.CurrentDashboardId)
2392
+ return true;
2393
+ if (!(await this.confirmLeaveDashboard()))
2394
+ return false;
2395
+ this.closeDashboardView();
2396
+ return true;
2397
+ }
2398
+ /**
2399
+ * A pick in a Dashboards switcher, or the breadcrumb's Home: null returns to the overview, an id opens that
2400
+ * dashboard in Home. Focus then moves to what shows.
2401
+ */
2402
+ OnSwitcherPick(dashboardId) {
2403
+ void this.followSwitcherPick(dashboardId);
2404
+ }
2405
+ /**
2406
+ * Manage pins (switcher): the overview with the pins in edit mode, and focus on the Pinned header. When the user
2407
+ * keeps editing the open dashboard, Home stays on it and focus goes to its title.
2408
+ */
2409
+ async ManagePins() {
2410
+ const home = await this.GoHome();
2411
+ if (home && !this.EditMode) {
2412
+ this.ToggleEditMode();
2413
+ }
2414
+ this.focusShownView();
2415
+ }
2416
+ /** The switcher's New dashboard: asks to leave unsaved changes first, then asks for the name. */
2417
+ async OpenNewDashboardDialog() {
2418
+ if (!(await this.confirmLeaveDashboard()))
2419
+ return;
2420
+ this.NewDashboardNameMaxLength = DashboardNameMaxLength(this.ProviderToUse);
2421
+ this.ShowNewDashboardDialog = true;
2422
+ this.cdr.markForCheck();
2423
+ }
2424
+ /** Closes the name dialog; nothing is created. */
2425
+ OnNewDashboardCancelled() {
2426
+ this.ShowNewDashboardDialog = false;
2427
+ this.cdr.markForCheck();
2428
+ }
2429
+ /**
2430
+ * Creates the named dashboard, pins it to Home and shows it in Home in edit mode. When the save fails, the
2431
+ * dialog stays open with the name and the user is told. A second Create while one runs is ignored.
2432
+ */
2433
+ async OnNewDashboardNamed(name) {
2434
+ if (this.IsCreatingDashboard)
2435
+ return;
2436
+ this.IsCreatingDashboard = true;
2437
+ this.cdr.markForCheck();
2438
+ try {
2439
+ const dashboard = await CreateBlankDashboard(this.ProviderToUse, name);
2440
+ if (!dashboard) {
2441
+ MJNotificationService.Instance.CreateSimpleNotification('Could not create the dashboard', 'error', 3000);
2442
+ return;
2443
+ }
2444
+ await this.reloadDashboardCache();
2445
+ this.pinService.AddPin(BuildDashboardPinInput(dashboard));
2446
+ this.ShowNewDashboardDialog = false;
2447
+ if (!(await this.OpenDashboardInHome(dashboard.ID, true))) {
2448
+ this.openDashboard(dashboard.ID, dashboard.Name);
2449
+ }
2450
+ }
2451
+ catch (error) {
2452
+ LogError(`Home: could not open the new dashboard: ${errorMessage(error)}`);
2453
+ MJNotificationService.Instance.CreateSimpleNotification('Could not open the new dashboard', 'error', 3000);
2454
+ }
2455
+ finally {
2456
+ this.IsCreatingDashboard = false;
2457
+ this.cdr.markForCheck();
2458
+ }
2459
+ }
2460
+ /** Opens the dashboard in a tab of the Dashboards app, installing the app first when the user lacks it. */
2461
+ async OpenDashboardInDashboardsApp(dashboard) {
2462
+ const app = await EnsureDashboardsApp(this.appManager);
2463
+ this.navigationService.OpenDashboard(dashboard.ID, dashboard.Name, app ? { applicationId: app.ID } : undefined);
2071
2464
  }
2072
2465
  /**
2073
- * Navigate to a notification using NavigationService
2466
+ * The editor entered or left edit mode. The editor can report leaving it while Home renders (it drops an edit when
2467
+ * it gets another dashboard), so this sets no state the template reads, and tells the agent after the render.
2074
2468
  */
2075
- OnNotificationClick(notification) {
2076
- // Navigate to the notifications view using NavigationService
2077
- this.navigationService.OpenDynamicView('MJ: User Notifications');
2078
- }
2079
- /** @deprecated Use {@link OnNotificationClick}. */
2080
- onNotificationClick(notification) {
2081
- return this.OnNotificationClick(notification);
2469
+ OnDashboardEditingChange(editing) {
2470
+ this.IsDashboardEditing = editing;
2471
+ queueMicrotask(() => this.publishAgentContext());
2082
2472
  }
2083
2473
  /**
2084
- * Get icon for an entity by name, using entity metadata Icon field (cached)
2474
+ * The editor saved the dashboard, or its saved name changed: the switcher and the pin names read the new name from
2475
+ * the cache.
2085
2476
  */
2086
- GetEntityIconByName(entityName) {
2087
- if (!entityName)
2088
- return 'fa-solid fa-file';
2089
- const cached = this.resourceIconCache.get(entityName);
2090
- if (cached)
2091
- return cached;
2092
- const entityInfo = this.metadata.Entities.find(e => e.Name === entityName);
2093
- const icon = entityInfo ? this.resolveEntityIcon(entityInfo.Icon) : 'fa-solid fa-file';
2094
- this.resourceIconCache.set(entityName, icon);
2095
- return icon;
2477
+ OnDashboardSaved() {
2478
+ this.refreshPinnedDashboards();
2479
+ }
2480
+ /** The editor has shown a dashboard. Its title gets focus when Home asked for that (see focusTitleOnLoad). */
2481
+ OnDashboardViewLoaded(dashboard) {
2482
+ if (this.focusTitleOnLoad && UUIDsEqual(dashboard.ID, this.focusTitleOnLoad)) {
2483
+ this.focusTitleOnLoad = null;
2484
+ this.focusInHome(DASHBOARD_TITLE_SELECTOR);
2485
+ }
2096
2486
  }
2097
- /** @deprecated Use {@link GetEntityIconByName}. */
2098
- getEntityIconByName(entityName) {
2099
- return this.GetEntityIconByName(entityName);
2487
+ /**
2488
+ * The editor could not show the dashboard: Home returns to its overview and tells the user. A dashboard that a URL
2489
+ * change named stays in the URL, since a write would add a history entry that every later Back lands on again. Any
2490
+ * other dashboard is removed from the URL: one the user opened in Home, or the one Home opened with on its first load,
2491
+ * so the tab does not keep it.
2492
+ */
2493
+ OnDashboardViewLoadFailed() {
2494
+ const namedByUrl = this.urlShownDashboardId !== null && UUIDsEqual(this.urlShownDashboardId, this.CurrentDashboardId);
2495
+ this.closeDashboardView(DASHBOARD_NOT_AVAILABLE, !namedByUrl);
2496
+ }
2497
+ /** Applies the dashboard the URL names, for back and forward, deep links and pins of Home. */
2498
+ OnQueryParamsChanged(params, _source) {
2499
+ const requested = params[DASHBOARD_QUERY_PARAM]?.trim() || null;
2500
+ if (UUIDsEqual(requested, this.requestedDashboardId))
2501
+ return;
2502
+ if (this.hasUnsavedDashboardChanges()) {
2503
+ void this.followDashboardParamAfterConfirm(requested);
2504
+ return;
2505
+ }
2506
+ this.requestedDashboardId = requested;
2507
+ this.applyRequestedDashboard(false);
2100
2508
  }
2101
2509
  /**
2102
- * Resolve an entity's Icon field to a full Font Awesome class string
2510
+ * Asks before a URL change leaves unsaved changes. When the user keeps editing, writes the open dashboard back to the
2511
+ * URL.
2103
2512
  */
2104
- resolveEntityIcon(icon) {
2105
- if (!icon)
2106
- return 'fa-solid fa-table';
2107
- // Already has a style prefix
2108
- if (icon.startsWith('fa-solid') || icon.startsWith('fa-regular') ||
2109
- icon.startsWith('fa-light') || icon.startsWith('fa-brands') ||
2110
- icon.startsWith('fa ')) {
2111
- return icon;
2513
+ async followDashboardParamAfterConfirm(requested) {
2514
+ if (!(await this.confirmLeaveDashboard())) {
2515
+ this.UpdateQueryParams({ [DASHBOARD_QUERY_PARAM]: this.CurrentDashboardId });
2516
+ return;
2112
2517
  }
2113
- // Has fa- prefix but no style
2114
- if (icon.startsWith('fa-')) {
2115
- return `fa-solid ${icon}`;
2518
+ this.requestedDashboardId = requested;
2519
+ this.applyRequestedDashboard(false);
2520
+ }
2521
+ /**
2522
+ * Shows the dashboard the URL asks for, once the dashboard cache has loaded: the dashboard view for a Config
2523
+ * dashboard the user can open, else the overview. For a dashboard Home cannot show, the user is told, and
2524
+ * `removeFromUrl` removes it from the URL. After a URL change (back, forward, a deep link into the open tab) the URL
2525
+ * stays as it is: a write then would add a history entry that every later Back lands on again. After a URL change,
2526
+ * Home also notes that the URL named the dashboard it shows (see OnDashboardViewLoadFailed).
2527
+ */
2528
+ applyRequestedDashboard(removeFromUrl) {
2529
+ if (!this.dashboardCacheLoaded)
2530
+ return;
2531
+ const requested = this.requestedDashboardId;
2532
+ const dashboard = requested ? this.findHomeDashboard(requested) : null;
2533
+ if (requested && !dashboard) {
2534
+ this.closeDashboardView(DASHBOARD_NOT_AVAILABLE, removeFromUrl);
2535
+ return;
2116
2536
  }
2117
- // Just an icon name like "table" or "users"
2118
- return `fa-solid fa-${icon}`;
2537
+ this.setCurrentDashboard(dashboard, false);
2538
+ this.urlShownDashboardId = removeFromUrl ? null : dashboard?.ID ?? null;
2119
2539
  }
2120
2540
  /**
2121
- * Format a date for display (pure function, safe to call in template)
2541
+ * Keeps the open dashboard in step with the cache: one that is gone, or that the user can no longer open, returns
2542
+ * Home to the overview.
2122
2543
  */
2123
- formatDate(date) {
2124
- if (!date)
2125
- return '';
2126
- const now = new Date();
2127
- const diff = now.getTime() - new Date(date).getTime();
2128
- const days = Math.floor(diff / (1000 * 60 * 60 * 24));
2129
- if (days === 0)
2130
- return 'Today';
2131
- if (days === 1)
2132
- return 'Yesterday';
2133
- if (days < 7)
2134
- return `${days} days ago`;
2135
- return new Date(date).toLocaleDateString();
2544
+ syncCurrentDashboard(dashboards) {
2545
+ if (!this.dashboardCacheLoaded || !this.CurrentDashboardId || FindDashboard(dashboards, this.CurrentDashboardId))
2546
+ return;
2547
+ this.closeDashboardView('The dashboard is no longer available');
2136
2548
  }
2137
2549
  /**
2138
- * Track function for favorites
2550
+ * Returns Home to its overview and, with a notice, tells the user. `removeFromUrl` also removes the dashboard from
2551
+ * the URL; that write runs after the current call stack, and only when no dashboard shows by then.
2139
2552
  */
2140
- TrackByFavorite(_index, item) {
2141
- return item.ID;
2553
+ closeDashboardView(notice, removeFromUrl = true) {
2554
+ this.requestedDashboardId = null;
2555
+ this.setCurrentDashboard(null, false);
2556
+ if (removeFromUrl) {
2557
+ queueMicrotask(() => {
2558
+ if (!this.CurrentDashboardId) {
2559
+ this.UpdateQueryParams({ [DASHBOARD_QUERY_PARAM]: null });
2560
+ }
2561
+ });
2562
+ }
2563
+ if (notice) {
2564
+ MJNotificationService.Instance.CreateSimpleNotification(notice, 'warning', 3000);
2565
+ }
2142
2566
  }
2143
- /** @deprecated Use {@link TrackByFavorite}. */
2144
- trackByFavorite(_index, item) {
2145
- return this.TrackByFavorite(_index, item);
2567
+ /**
2568
+ * Shows `dashboard` (or the overview for null). Home keeps the object it was given for the same dashboard: the
2569
+ * editor follows the dashboard cache itself after a save, so a new copy of the same dashboard is not pushed to it.
2570
+ */
2571
+ setCurrentDashboard(dashboard, startInEditMode) {
2572
+ if (UUIDsEqual(dashboard?.ID, this.CurrentDashboardId))
2573
+ return;
2574
+ this.CurrentDashboard = dashboard;
2575
+ this.CurrentDashboardId = dashboard?.ID ?? null;
2576
+ this.DashboardStartsInEditMode = dashboard !== null && startInEditMode;
2577
+ this.IsDashboardEditing = false;
2578
+ this.focusTitleOnLoad = null;
2579
+ this.urlShownDashboardId = null;
2580
+ this.EditingPinId = null;
2581
+ this.SidebarOpen = false;
2582
+ this.HidePinMenu();
2583
+ this.publishAgentContext();
2584
+ this.cdr.markForCheck();
2585
+ }
2586
+ /** A Config dashboard the user can open, by id (any letter case), or null. */
2587
+ findHomeDashboard(dashboardId) {
2588
+ const dashboard = FindDashboard(this.accessibleDashboards(), dashboardId);
2589
+ return dashboard && CanShowInHome(dashboard) ? dashboard : null;
2590
+ }
2591
+ /** True while the open dashboard is in edit mode with changes the editor has not saved. */
2592
+ hasUnsavedDashboardChanges() {
2593
+ return this.IsDashboardEditing && (this.dashboardEditor?.HasUnsavedChanges ?? false);
2146
2594
  }
2147
2595
  /**
2148
- * Remove duplicate recent items (same entity + recordId). Keeps the first occurrence.
2596
+ * True when Home may leave the open dashboard: it is not being edited, its changes are saved, or the user chose to
2597
+ * discard them (the editor then cancels its edit). False when the user keeps editing.
2149
2598
  */
2150
- deduplicateRecents(items) {
2151
- const seen = new Set();
2152
- return items.filter(item => {
2153
- const key = `${item.entityName}-${item.recordId}`;
2154
- if (seen.has(key)) {
2155
- return false;
2156
- }
2157
- seen.add(key);
2599
+ async confirmLeaveDashboard() {
2600
+ const editor = this.dashboardEditor;
2601
+ if (!editor || !this.IsDashboardEditing)
2158
2602
  return true;
2603
+ if (editor.HasUnsavedChanges && !(await this.confirmDiscardDashboardChanges()))
2604
+ return false;
2605
+ editor.CancelEdit();
2606
+ return true;
2607
+ }
2608
+ /**
2609
+ * Asks whether to discard the open dashboard's unsaved changes. Resolves true for Discard changes, false for Keep
2610
+ * editing.
2611
+ */
2612
+ confirmDiscardDashboardChanges() {
2613
+ return this.confirmService.Confirm({
2614
+ title: 'Discard changes?',
2615
+ message: `Leave "${this.CurrentDashboardName}" without saving?`,
2616
+ detail: 'Your changes to this dashboard will be lost.',
2617
+ type: 'warning',
2618
+ confirmText: 'Discard changes',
2619
+ cancelText: 'Keep editing',
2159
2620
  });
2160
2621
  }
2161
2622
  /**
2162
- * Track function for recent items
2623
+ * Follows a switcher pick, then moves focus to what shows: a dashboard Home switched to gets focus on its title once
2624
+ * the editor has shown it; otherwise focus goes to the open dashboard's title, or to the Pinned header.
2163
2625
  */
2164
- TrackByRecent(_index, item) {
2165
- return `${item.entityName}-${item.recordId}`;
2626
+ async followSwitcherPick(dashboardId) {
2627
+ const switching = dashboardId !== null && !UUIDsEqual(dashboardId, this.CurrentDashboardId);
2628
+ const moved = dashboardId ? await this.OpenDashboardInHome(dashboardId) : await this.GoHome();
2629
+ if (moved && switching) {
2630
+ this.focusTitleOnLoad = this.CurrentDashboardId;
2631
+ }
2632
+ else {
2633
+ this.focusShownView();
2634
+ }
2166
2635
  }
2167
- /** @deprecated Use {@link TrackByRecent}. */
2168
- trackByRecent(_index, item) {
2169
- return this.TrackByRecent(_index, item);
2636
+ /** Runs an agent's change of Home's view, then moves focus when the change removed it (see refocusIfRemoved). */
2637
+ async switchViewForAgent(switchView) {
2638
+ const focused = this.focusedElementInHome();
2639
+ const switched = await switchView();
2640
+ this.refocusIfRemoved(focused);
2641
+ return switched;
2642
+ }
2643
+ /** The element in Home that has focus, or null when focus is outside Home. */
2644
+ focusedElementInHome() {
2645
+ const focused = document.activeElement;
2646
+ return focused instanceof HTMLElement && this.hostElement.nativeElement.contains(focused) ? focused : null;
2170
2647
  }
2171
2648
  /**
2172
- * Track function for notifications
2649
+ * After an agent changed Home's view: renders Home, and when `focused` is gone (the change removed the part of Home it
2650
+ * was in), moves focus as a switcher pick does, to the title of the dashboard Home shows once the editor has shown it,
2651
+ * or on the overview to the Pinned header. Focus that is still on the page stays where it is.
2173
2652
  */
2174
- TrackByNotification(_index, item) {
2175
- return item.ID;
2653
+ refocusIfRemoved(focused) {
2654
+ if (!focused)
2655
+ return;
2656
+ SafeDetectChanges(this.cdr);
2657
+ if (focused.isConnected)
2658
+ return;
2659
+ if (this.CurrentDashboardId) {
2660
+ this.focusTitleOnLoad = this.CurrentDashboardId;
2661
+ }
2662
+ else {
2663
+ this.focusShownView();
2664
+ }
2176
2665
  }
2177
- /** @deprecated Use {@link TrackByNotification}. */
2178
- trackByNotification(_index, item) {
2179
- return this.TrackByNotification(_index, item);
2666
+ /**
2667
+ * Moves focus to the open dashboard's title, or on the overview to the Pinned header: its Dashboards button, or Done
2668
+ * while the pins are in edit mode.
2669
+ */
2670
+ focusShownView() {
2671
+ if (this.CurrentDashboardId) {
2672
+ this.focusInHome(DASHBOARD_TITLE_SELECTOR);
2673
+ }
2674
+ else {
2675
+ this.focusInHome(this.EditMode ? '.pinned-actions > button' : '.pinned-actions .switcher-button');
2676
+ }
2677
+ }
2678
+ /**
2679
+ * Renders Home, then focuses the first element in it that matches `selector`, and returns that element. Returns null,
2680
+ * and focuses nothing, when none shows.
2681
+ */
2682
+ focusInHome(selector) {
2683
+ SafeDetectChanges(this.cdr);
2684
+ const element = this.hostElement.nativeElement.querySelector(selector);
2685
+ element?.focus();
2686
+ return element;
2180
2687
  }
2181
2688
  // =============================================
2182
2689
  // PIN NAME RESOLUTION
@@ -2189,7 +2696,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2189
2696
  // Find pins that need name resolution: records with raw ID titles,
2190
2697
  // or any pin whose DisplayName contains "ID|" (raw composite key)
2191
2698
  const pinsNeedingNames = this.PinnedItems.filter(pin => {
2192
- const rt = this.resolveStoredResourceType(pin);
2699
+ const rt = ResolvePinResourceType(pin);
2193
2700
  if (rt !== 'Records')
2194
2701
  return false;
2195
2702
  // Check if the name looks like a raw ID format
@@ -2232,7 +2739,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2232
2739
  * Resolve missing icons for Custom (app nav item) pins by looking up nav items.
2233
2740
  */
2234
2741
  async resolveCustomPinIcons() {
2235
- const pinsNeedingIcons = this.PinnedItems.filter(pin => this.resolveStoredResourceType(pin) === 'Custom' && !pin.Icon);
2742
+ const pinsNeedingIcons = this.PinnedItems.filter(pin => ResolvePinResourceType(pin) === 'Custom' && !pin.Icon);
2236
2743
  if (pinsNeedingIcons.length === 0)
2237
2744
  return;
2238
2745
  for (const pin of pinsNeedingIcons) {
@@ -2254,145 +2761,144 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2254
2761
  // PIN MANAGEMENT
2255
2762
  // =============================================
2256
2763
  /**
2257
- * Navigate to a pinned resource
2764
+ * Opens a pinned resource. A click in edit mode does nothing. A dashboard the click shows in Home gets focus on its
2765
+ * title once the editor has shown it.
2258
2766
  */
2259
2767
  OnPinClick(pin) {
2768
+ void this.openPinForUser(pin);
2769
+ }
2770
+ /** Opens a pin the user clicked. When it shows a dashboard in Home, that dashboard's title gets focus once the editor has shown it. */
2771
+ async openPinForUser(pin) {
2772
+ const shown = this.CurrentDashboardId;
2773
+ if ((await this.openPin(pin)) && this.CurrentDashboardId && !UUIDsEqual(this.CurrentDashboardId, shown)) {
2774
+ this.focusTitleOnLoad = this.CurrentDashboardId;
2775
+ }
2776
+ }
2777
+ /**
2778
+ * Opens a pin: a dashboard pin as openDashboardPin describes, other pins as Home always has. Returns false when
2779
+ * nothing opened: in edit mode, for a broken pin, or when the user kept editing the open dashboard.
2780
+ */
2781
+ async openPin(pin) {
2260
2782
  if (this.EditMode)
2261
- return;
2783
+ return false;
2784
+ const resourceType = ResolvePinResourceType(pin);
2785
+ return resourceType === 'Dashboards' ? this.openDashboardPin(pin) : this.openResourcePin(pin, resourceType);
2786
+ }
2787
+ /**
2788
+ * Opens a dashboard pin: a Config dashboard the user can open shows inside Home; a Code dashboard, or one the cache
2789
+ * does not have, opens in a tab under the name the pin shows. Returns false when nothing opened.
2790
+ */
2791
+ async openDashboardPin(pin) {
2792
+ const dashboardId = DashboardIdOfPin(pin);
2793
+ if (!dashboardId) {
2794
+ console.warn('[Pin Click] Dashboards pin missing dashboardId and recordId', pin.Configuration);
2795
+ return false;
2796
+ }
2797
+ if (this.findHomeDashboard(dashboardId)) {
2798
+ return this.OpenDashboardInHome(dashboardId);
2799
+ }
2800
+ this.openDashboard(dashboardId, this.PinName(pin));
2801
+ return true;
2802
+ }
2803
+ /**
2804
+ * Opens a pin that is not a dashboard pin: a view, a query, a record, an app page or an action. Returns false when
2805
+ * the pin is broken and nothing opened.
2806
+ */
2807
+ openResourcePin(pin, resourceType) {
2262
2808
  const config = pin.Configuration;
2263
- const rt = this.resolveStoredResourceType(pin);
2264
- // For Dashboards, Views, Queries — route through Data Explorer if available
2265
- const deApp = this.HasDataExplorerApp
2266
- ? this.appManager.GetAllApps().find(a => a.Name === 'Data Explorer')
2267
- : null;
2268
- switch (rt) {
2269
- case 'Dashboards': {
2270
- const dashboardId = config['dashboardId'];
2271
- if (!dashboardId)
2272
- break;
2273
- if (deApp) {
2274
- void this.navigationService.SwitchToApp(deApp.ID, 'Dashboards', { dashboard: dashboardId });
2275
- }
2276
- else {
2277
- this.navigationService.OpenDashboard(dashboardId, pin.DisplayName);
2278
- }
2279
- break;
2280
- }
2281
- case 'User Views':
2809
+ switch (resourceType) {
2810
+ case 'User Views': {
2282
2811
  if (config['isDynamic']) {
2283
- this.navigationService.OpenDynamicView((config['Entity'] || config['entity']), config['extraFilter']);
2284
- }
2285
- else {
2286
- const viewId = config['viewId'];
2287
- if (viewId) {
2288
- this.navigationService.OpenView(viewId, pin.DisplayName);
2812
+ const entityName = (config['Entity'] || config['entity']);
2813
+ if (!entityName) {
2814
+ console.warn('[Pin Click] Dynamic view pin missing Entity', config);
2815
+ return false;
2289
2816
  }
2817
+ this.navigationService.OpenDynamicView(entityName, config['extraFilter']);
2818
+ return true;
2290
2819
  }
2291
- break;
2820
+ const viewId = config['viewId'];
2821
+ if (!viewId)
2822
+ return false;
2823
+ this.navigationService.OpenView(viewId, pin.DisplayName);
2824
+ return true;
2825
+ }
2292
2826
  case 'Queries': {
2293
2827
  const queryId = config['queryId'];
2294
2828
  if (!queryId)
2295
- break;
2829
+ return false;
2830
+ // Opens in Data Explorer's Queries nav item once the Add Pin panel has found that app
2831
+ const deApp = this.HasDataExplorerApp
2832
+ ? this.appManager.GetAllApps().find(a => a.Name === 'Data Explorer')
2833
+ : null;
2296
2834
  if (deApp) {
2297
2835
  void this.navigationService.SwitchToApp(deApp.ID, 'Queries', { queryId: queryId });
2298
2836
  }
2299
2837
  else {
2300
2838
  this.navigationService.OpenQuery(queryId, pin.DisplayName);
2301
2839
  }
2302
- break;
2840
+ return true;
2303
2841
  }
2304
2842
  case 'Records': {
2305
2843
  const entityName = (config['Entity'] || config['entity']);
2306
2844
  const recordId = config['recordId'];
2307
- if (entityName && recordId) {
2308
- const compositeKey = this.buildCompositeKeyForRecord(entityName, recordId);
2309
- if (compositeKey) {
2310
- this.navigationService.OpenEntityRecord(entityName, compositeKey);
2311
- }
2312
- }
2313
- else {
2845
+ if (!entityName || !recordId) {
2314
2846
  console.warn('[Pin Click] Records pin missing Entity or recordId', config);
2847
+ return false;
2315
2848
  }
2316
- break;
2317
- }
2318
- case 'Custom': {
2319
- // Custom resources are nav items within apps — always use app name, never ID
2320
- const navItemName = config['navItemName'];
2321
- const appName = config['appName'];
2322
- const queryParams = config['queryParams'];
2323
- if (appName) {
2324
- const app = this.appManager.GetAllApps().find(a => a.Name === appName);
2325
- if (app) {
2326
- // Pass query params INTO SwitchToApp so they're applied synchronously when the
2327
- // target tab activates — before a cached resource component reattaches. The old
2328
- // post-hoc UpdateActiveTabQueryParams() in a .then() raced the cache reattach and
2329
- // lost: e.g. two conversation pins both landed on whatever chat was already open.
2330
- void this.navigationService.SwitchToApp(app.ID, navItemName, queryParams);
2331
- }
2332
- else {
2333
- console.warn(`[Pin Click] Custom pin: app "${appName}" not found`, config);
2334
- }
2335
- }
2336
- else {
2337
- console.warn('[Pin Click] Custom pin missing appName', config);
2338
- }
2339
- break;
2849
+ const compositeKey = this.buildCompositeKeyForRecord(entityName, recordId);
2850
+ if (!compositeKey)
2851
+ return false;
2852
+ this.navigationService.OpenEntityRecord(entityName, compositeKey);
2853
+ return true;
2340
2854
  }
2855
+ case 'Custom':
2856
+ return this.openAppPagePin(config);
2341
2857
  case 'Actions': {
2342
2858
  const actionId = config['actionId'];
2343
2859
  if (!actionId) {
2344
2860
  console.warn('[Pin Click] Action pin missing actionId', config);
2345
- break;
2861
+ return false;
2346
2862
  }
2347
2863
  this.ActionRunnerPin = pin;
2348
2864
  this.ActionRunnerDialogVisible = true;
2349
2865
  this.cdr.markForCheck();
2350
- break;
2866
+ return true;
2351
2867
  }
2352
2868
  default:
2353
- console.warn('[Pin Click] Unrecognized resource type', rt, 'for pin', pin.DisplayName, config);
2354
- break;
2869
+ console.warn('[Pin Click] Unrecognized resource type', resourceType, 'for pin', pin.DisplayName, config);
2870
+ return false;
2871
+ }
2872
+ }
2873
+ /** Opens an app page pin (a Custom pin): a nav item of an app, found by the app's name. Returns false when the pin is broken. */
2874
+ openAppPagePin(config) {
2875
+ // Custom resources are nav items within apps — always use app name, never ID
2876
+ const navItemName = config['navItemName'];
2877
+ const appName = config['appName'];
2878
+ const queryParams = config['queryParams'];
2879
+ if (!appName) {
2880
+ console.warn('[Pin Click] Custom pin missing appName', config);
2881
+ return false;
2882
+ }
2883
+ const app = this.appManager.GetAllApps().find(a => a.Name === appName);
2884
+ if (!app) {
2885
+ console.warn(`[Pin Click] Custom pin: app "${appName}" not found`, config);
2886
+ return false;
2355
2887
  }
2888
+ // SwitchToApp gets the query params, so the target tab has them when it activates, before a cached resource
2889
+ // component reattaches: the page opens on the state the pin names.
2890
+ void this.navigationService.SwitchToApp(app.ID, navItemName, queryParams);
2891
+ return true;
2356
2892
  }
2357
2893
  /**
2358
- * Resolve a pin's resource type from its stored ResourceType and config keys.
2359
- * Handles legacy pins that may have stored a UUID resourceTypeId or
2360
- * a raw config.resourceType string instead of the canonical type names.
2361
- */
2362
- resolveStoredResourceType(pin) {
2363
- const rt = pin.ResourceType;
2364
- const config = pin.Configuration;
2365
- // Already a known canonical type
2366
- const knownTypes = ['Dashboards', 'User Views', 'Queries', 'Reports', 'Records', 'Custom', 'Actions'];
2367
- if (knownTypes.includes(rt))
2368
- return rt;
2369
- // Check the config's own resourceType field
2370
- const configRt = config['resourceType'];
2371
- if (configRt && knownTypes.includes(configRt))
2372
- return configRt;
2373
- // Fall back to detecting by config keys
2374
- if (config['dashboardId'])
2375
- return 'Dashboards';
2376
- if (config['viewId'])
2377
- return 'User Views';
2378
- if (config['queryId'])
2379
- return 'Queries';
2380
- if (config['reportId'])
2381
- return 'Reports';
2382
- if ((config['Entity'] || config['entity']) && config['recordId'])
2383
- return 'Records';
2384
- if (config['actionId'])
2385
- return 'Actions';
2386
- if (config['navItemName'])
2387
- return 'Custom';
2388
- return rt; // Give up and return whatever was stored
2389
- }
2390
- /**
2391
- * Toggle edit mode for pins
2894
+ * Toggle edit mode for pins. Entering edit mode opens a collapsed Pinned section.
2392
2895
  */
2393
2896
  ToggleEditMode() {
2394
2897
  this.EditMode = !this.EditMode;
2395
- if (!this.EditMode) {
2898
+ if (this.EditMode) {
2899
+ this.openPinnedSection();
2900
+ }
2901
+ else {
2396
2902
  this.EditingPinId = null;
2397
2903
  this.EditingGroupName = null;
2398
2904
  }
@@ -2407,6 +2913,27 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2407
2913
  UserInfoEngine.Instance.SetSettingDebounced('HomeApp.HidePinEmptyState', 'true');
2408
2914
  this.cdr.markForCheck();
2409
2915
  }
2916
+ /** Opens or collapses the Pinned section, saves the choice for the user and reports it to the agent. */
2917
+ OnPinnedExpandedChange(expanded) {
2918
+ this.PinnedExpanded = expanded;
2919
+ this.sectionStateChanged(PINNED_COLLAPSED_SETTING, expanded);
2920
+ }
2921
+ /** Reads whether the Pinned section is open. 'true' means collapsed; a missing setting means open. */
2922
+ loadSectionStates() {
2923
+ this.PinnedExpanded = UserInfoEngine.Instance.GetSetting(PINNED_COLLAPSED_SETTING) !== 'true';
2924
+ }
2925
+ /** Saves a section's state for the user ('true' when collapsed), reports it to the agent and renders. */
2926
+ sectionStateChanged(settingKey, expanded) {
2927
+ UserInfoEngine.Instance.SetSettingDebounced(settingKey, expanded ? 'false' : 'true');
2928
+ this.publishAgentContext();
2929
+ this.cdr.markForCheck();
2930
+ }
2931
+ /** Opens the Pinned section when it is collapsed, so edit mode or a new pin shows. */
2932
+ openPinnedSection() {
2933
+ if (!this.PinnedExpanded) {
2934
+ this.OnPinnedExpandedChange(true);
2935
+ }
2936
+ }
2410
2937
  /**
2411
2938
  * Remove a pin
2412
2939
  */
@@ -2414,22 +2941,96 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2414
2941
  this.pinService.RemovePin(pinId);
2415
2942
  }
2416
2943
  /**
2417
- * Start inline editing of a pin's display name
2944
+ * Starts renaming a pin: shows its rename box, with focus in it and the name selected. A dashboard pin is renamed
2945
+ * only by a user who can edit its dashboard; other users are told why not.
2418
2946
  */
2419
2947
  StartEditingPin(pinId, event) {
2420
2948
  event.stopPropagation();
2949
+ const pin = this.PinnedItems.find(p => p.Id === pinId);
2950
+ if (pin && !this.canRenamePin(pin)) {
2951
+ this.notifyCannotRename(pin);
2952
+ return;
2953
+ }
2421
2954
  this.EditingPinId = pinId;
2422
- this.cdr.markForCheck();
2955
+ this.focusPinNameInput();
2423
2956
  }
2424
2957
  /**
2425
- * Save edited pin name
2958
+ * Saves the name typed in a pin's rename box and closes the box. A dashboard pin renames its dashboard, since it
2959
+ * shows the dashboard's name; other pins rename only the pin. An empty or unchanged name changes nothing. A call
2960
+ * after the rename has ended does nothing: the browser can blur the box as it goes away.
2426
2961
  */
2427
2962
  SavePinName(pinId, newName) {
2428
- if (newName.trim()) {
2429
- this.pinService.UpdatePin(pinId, { DisplayName: newName.trim() });
2430
- }
2963
+ if (this.EditingPinId !== pinId)
2964
+ return;
2431
2965
  this.EditingPinId = null;
2432
2966
  this.cdr.markForCheck();
2967
+ const pin = this.PinnedItems.find(p => p.Id === pinId);
2968
+ const name = newName.trim();
2969
+ if (!pin || !name || name === this.PinName(pin))
2970
+ return;
2971
+ const dashboard = this.pinDashboard(pin);
2972
+ if (dashboard) {
2973
+ void this.renameDashboard(dashboard, pin, name);
2974
+ return;
2975
+ }
2976
+ this.pinService.UpdatePin(pinId, { DisplayName: name });
2977
+ }
2978
+ /** Enter in a pin's rename box: saves the name, then moves focus to Done, since the box goes away. */
2979
+ OnPinNameEnter(pinId, event) {
2980
+ this.SavePinName(pinId, this.GetInputValue(event));
2981
+ this.focusShownView();
2982
+ }
2983
+ /** Renders Home, then puts focus in the open rename box and selects the name, so typing replaces it. */
2984
+ focusPinNameInput() {
2985
+ this.focusInHome('.pin-card .pin-name-input')?.select();
2986
+ }
2987
+ /** The dashboard a dashboard pin shows, from the dashboard cache. Null for other pins, and when the cache lacks it. */
2988
+ pinDashboard(pin) {
2989
+ return FindDashboard(this.accessibleDashboards(), DashboardIdOfPin(pin));
2990
+ }
2991
+ /** True when the user may rename the pin: a pin that shows no cached dashboard, or a dashboard pin whose dashboard the user can edit. */
2992
+ canRenamePin(pin) {
2993
+ const dashboard = this.pinDashboard(pin);
2994
+ return !dashboard || DashboardEngine.Instance.CanUserEditDashboard(dashboard.ID, this.ProviderToUse.CurrentUser.ID);
2995
+ }
2996
+ /** Tells the user that only people who can edit the pin's dashboard can rename the pin. */
2997
+ notifyCannotRename(pin) {
2998
+ MJNotificationService.Instance.CreateSimpleNotification(`Only people who can edit "${this.PinName(pin)}" can rename it`, 'info', 3000);
2999
+ }
3000
+ /**
3001
+ * Renames the dashboard a pin shows, and keeps the pin's stored name in step: the name the pin shows when the cache
3002
+ * lacks the dashboard. It renames the cache's own dashboard object, so the switcher, the pin names and an editor that
3003
+ * shows the dashboard have the new name at once. While a save of that object runs (an editor's Save, for example),
3004
+ * it renames nothing and tells the user: its own save would join the running one and write nothing. A failed save
3005
+ * puts the old name back and tells the user.
3006
+ */
3007
+ async renameDashboard(dashboard, pin, name) {
3008
+ if (dashboard.IsSaving) {
3009
+ MJNotificationService.Instance.CreateSimpleNotification(`"${dashboard.Name}" is being saved. Rename it again in a moment.`, 'info', 3000);
3010
+ return;
3011
+ }
3012
+ const previous = dashboard.Name;
3013
+ dashboard.Name = name;
3014
+ this.refreshPinnedDashboards();
3015
+ const failure = await this.saveRenamedDashboard(dashboard);
3016
+ if (failure !== null) {
3017
+ dashboard.Name = previous;
3018
+ this.refreshPinnedDashboards();
3019
+ LogError(`Home: could not rename the dashboard "${previous}": ${failure}`);
3020
+ MJNotificationService.Instance.CreateSimpleNotification(`Could not rename "${previous}"`, 'error', 3000);
3021
+ return;
3022
+ }
3023
+ this.pinService.UpdatePin(pin.Id, { DisplayName: name });
3024
+ MJNotificationService.Instance.CreateSimpleNotification(`Renamed the dashboard to "${name}"`, 'success', 2000);
3025
+ }
3026
+ /** Saves a renamed dashboard. Returns null when it saved, else why not. Never throws. */
3027
+ async saveRenamedDashboard(dashboard) {
3028
+ try {
3029
+ return (await dashboard.Save()) ? null : dashboard.LatestResult?.CompleteMessage ?? 'unknown error';
3030
+ }
3031
+ catch (error) {
3032
+ return errorMessage(error);
3033
+ }
2433
3034
  }
2434
3035
  /**
2435
3036
  * Extract input value from a DOM event (strict template helper)
@@ -2472,6 +3073,10 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2472
3073
  GetPinsInGroup(groupName) {
2473
3074
  return this.pinService.GetPinsInGroup(groupName);
2474
3075
  }
3076
+ /** The name a pin shows: a dashboard pin shows its dashboard's name from the cache; other pins show their own. */
3077
+ PinName(pin) {
3078
+ return this.pinDashboardNames.get(pin.Id) ?? pin.DisplayName;
3079
+ }
2475
3080
  /**
2476
3081
  * Get icon for a pin based on resource type and metadata
2477
3082
  */
@@ -2549,32 +3154,89 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2549
3154
  // PIN CONTEXT MENU (ELLIPSIS)
2550
3155
  // =============================================
2551
3156
  /**
2552
- * Show the pin context menu (triggered by ellipsis button)
3157
+ * Opens the pin options menu under the pin's ellipsis button, right-aligned and inside the viewport, and moves
3158
+ * focus to its first row. A click elsewhere, Escape or Tab closes it.
2553
3159
  */
2554
3160
  ShowPinMenu(event, pin) {
2555
3161
  event.stopPropagation();
2556
3162
  event.preventDefault();
3163
+ const trigger = event.currentTarget;
3164
+ if (!(trigger instanceof HTMLElement)) {
3165
+ return;
3166
+ }
3167
+ const anchor = MenuAnchorOf(trigger);
3168
+ this.pinMenuTrigger = trigger;
2557
3169
  this.PinMenuPin = pin;
2558
- this.PinMenuX = event.clientX;
2559
- this.PinMenuY = event.clientY;
2560
3170
  this.PinMenuVisible = true;
2561
- this.cdr.markForCheck();
2562
- // Close on click outside or Escape
3171
+ this.placePinMenu(anchor, 0);
3172
+ // Render the menu with no max height to measure its full height, then place it again with that height
3173
+ this.PinMenuMaxHeight = null;
3174
+ this.cdr.detectChanges();
3175
+ this.placePinMenu(anchor, this.pinMenuEl?.nativeElement.offsetHeight ?? 0);
3176
+ this.cdr.detectChanges();
3177
+ this.pinMenuRows()[0]?.focus({ preventScroll: true });
3178
+ this.watchPinMenuDismiss();
3179
+ }
3180
+ /**
3181
+ * Keys in the pin options menu: ArrowDown, ArrowUp, Home and End move between the rows. Escape closes the menu
3182
+ * and puts focus back on its button. Tab closes it too, and the browser moves focus on from the button.
3183
+ */
3184
+ OnPinMenuKeydown(event) {
3185
+ if (event.key === 'Escape') {
3186
+ event.preventDefault();
3187
+ this.closePinMenuToTrigger();
3188
+ }
3189
+ else if (event.key === 'Tab') {
3190
+ this.closePinMenuToTrigger();
3191
+ }
3192
+ else {
3193
+ this.focusPinMenuRow(event);
3194
+ }
3195
+ }
3196
+ /** Moves focus to the menu row that ArrowDown, ArrowUp, Home or End picks. Other keys do nothing. */
3197
+ focusPinMenuRow(event) {
3198
+ const rows = this.pinMenuRows();
3199
+ const next = NextMenuFocusIndex(event.key, rows.findIndex(row => row === document.activeElement), rows.length);
3200
+ if (next !== null) {
3201
+ event.preventDefault();
3202
+ rows[next].focus();
3203
+ }
3204
+ }
3205
+ /** The menu's rows, in order: its menuitem buttons. */
3206
+ pinMenuRows() {
3207
+ return Array.from(this.pinMenuEl?.nativeElement.querySelectorAll('[role="menuitem"]') ?? []);
3208
+ }
3209
+ /** Closes the pin options menu and puts focus back on the button that opened it. */
3210
+ closePinMenuToTrigger() {
3211
+ const trigger = this.pinMenuTrigger;
3212
+ this.HidePinMenu();
3213
+ trigger?.focus();
3214
+ }
3215
+ /**
3216
+ * Places the pin options menu next to its button and limits its height to the room on that side. A height of 0
3217
+ * places it below the button.
3218
+ */
3219
+ placePinMenu(anchor, height) {
3220
+ const place = PlaceMenu(anchor, PIN_MENU_WIDTH, height, 'right', { Width: window.innerWidth, Height: window.innerHeight });
3221
+ this.PinMenuX = place.Left;
3222
+ this.PinMenuY = place.Top;
3223
+ this.PinMenuMaxHeight = place.MaxHeight;
3224
+ }
3225
+ /** Closes the pin options menu on the next click anywhere or on Escape. */
3226
+ watchPinMenuDismiss() {
2563
3227
  setTimeout(() => {
2564
- const clickHandler = () => {
3228
+ const close = () => {
2565
3229
  this.HidePinMenu();
2566
- document.removeEventListener('click', clickHandler);
2567
- document.removeEventListener('keydown', keyHandler);
3230
+ document.removeEventListener('click', close);
3231
+ document.removeEventListener('keydown', onKeydown);
2568
3232
  };
2569
- const keyHandler = (e) => {
2570
- if (e.key === 'Escape') {
2571
- this.HidePinMenu();
2572
- document.removeEventListener('click', clickHandler);
2573
- document.removeEventListener('keydown', keyHandler);
3233
+ const onKeydown = (event) => {
3234
+ if (event.key === 'Escape') {
3235
+ close();
2574
3236
  }
2575
3237
  };
2576
- document.addEventListener('click', clickHandler);
2577
- document.addEventListener('keydown', keyHandler);
3238
+ document.addEventListener('click', close);
3239
+ document.addEventListener('keydown', onKeydown);
2578
3240
  }, 0);
2579
3241
  }
2580
3242
  /**
@@ -2583,18 +3245,30 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2583
3245
  HidePinMenu() {
2584
3246
  this.PinMenuVisible = false;
2585
3247
  this.PinMenuPin = null;
3248
+ this.pinMenuTrigger = null;
2586
3249
  this.cdr.markForCheck();
2587
3250
  }
2588
3251
  /**
2589
- * Edit a pin (enters edit mode focused on this pin)
3252
+ * Edit in a pin's menu: closes the menu, puts the pins in edit mode (opening a collapsed Pinned section) and starts
3253
+ * renaming the pin, with focus in its rename box. For a dashboard pin the user cannot rename, it says why and moves
3254
+ * focus to Done instead.
2590
3255
  */
2591
3256
  OnPinMenuEdit() {
2592
- if (this.PinMenuPin) {
2593
- this.EditMode = true;
2594
- this.EditingPinId = this.PinMenuPin.Id;
2595
- this.cdr.markForCheck();
2596
- }
3257
+ const pin = this.PinMenuPin;
2597
3258
  this.HidePinMenu();
3259
+ if (!pin)
3260
+ return;
3261
+ this.EditMode = true;
3262
+ this.openPinnedSection();
3263
+ if (this.canRenamePin(pin)) {
3264
+ this.EditingPinId = pin.Id;
3265
+ this.focusPinNameInput();
3266
+ }
3267
+ else {
3268
+ this.EditingPinId = null;
3269
+ this.notifyCannotRename(pin);
3270
+ this.focusShownView();
3271
+ }
2598
3272
  }
2599
3273
  /**
2600
3274
  * Move a pin to a different group
@@ -2739,8 +3413,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2739
3413
  }));
2740
3414
  // Load apps with their nav items
2741
3415
  await this.loadAvailableApps();
2742
- // Check if Data Explorer is available — if so, dashboards/queries/views
2743
- // are accessible through its nav items, no need for standalone sections
3416
+ // Query pins open in Data Explorer when the user has that app (see OnPinClick)
2744
3417
  this.HasDataExplorerApp = this.AvailableApps.some(a => a.appName === 'Data Explorer');
2745
3418
  }
2746
3419
  /**
@@ -2811,6 +3484,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2811
3484
  };
2812
3485
  });
2813
3486
  MJNotificationService.Instance.CreateSimpleNotification(`"${navItemLabel}" pinned to Home`, 'success', 3000);
3487
+ this.openPinnedSection();
2814
3488
  this.cdr.markForCheck();
2815
3489
  }
2816
3490
  }
@@ -2843,6 +3517,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2843
3517
  if (added) {
2844
3518
  this.updatePanelPinnedState(resourceType, id, true);
2845
3519
  MJNotificationService.Instance.CreateSimpleNotification(`"${name}" pinned to Home`, 'success', 3000);
3520
+ this.openPinnedSection();
2846
3521
  }
2847
3522
  }
2848
3523
  // =============================================
@@ -2886,6 +3561,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2886
3561
  const added = this.pinService.AddPin(input);
2887
3562
  if (added) {
2888
3563
  MJNotificationService.Instance.CreateSimpleNotification(`"${p.DisplayName}" pinned to Home`, 'success', 3000);
3564
+ this.openPinnedSection();
2889
3565
  }
2890
3566
  else {
2891
3567
  MJNotificationService.Instance.CreateSimpleNotification('A pin with the same title and config already exists.', 'warning', 3000);
@@ -2936,63 +3612,62 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2936
3612
  }
2937
3613
  static ɵfac = function HomeDashboardComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || HomeDashboardComponent)(i0.ɵɵdirectiveInject(i1.ApplicationManager), i0.ɵɵdirectiveInject(i2.RecentAccessService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
2938
3614
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: HomeDashboardComponent, selectors: [["mj-home-dashboard"]], viewQuery: function HomeDashboardComponent_Query(rf, ctx) { if (rf & 1) {
2939
- i0.ɵɵviewQuery(_c0, 5);
3615
+ i0.ɵɵviewQuery(_c0, 5)(_c1, 5)(_c2, 5);
2940
3616
  } if (rf & 2) {
2941
3617
  let _t;
2942
3618
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.AppConfigDialog = _t.first);
2943
- } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 19, vars: 19, consts: [["appConfigDialog", ""], [1, "home-dashboard"], [1, "main-content"], [1, "home-header"], [1, "greeting-section"], [1, "date"], [1, "pinned-section"], [1, "pin-context-menu", 3, "left", "top"], [3, "Result", "Visible", "ActionID", "ActionName", "ActionDescription"], [3, "Result", "Visible", "Pin"], [1, "loading-container"], [1, "apps-section"], [1, "quick-access-sidebar"], ["title", "Quick Access", 1, "sidebar-fab-toggle"], [3, "ShowDialogChange", "ConfigSaved", "ShowDialog"], [1, "pinned-header"], [1, "section-title"], [1, "fa-solid", "fa-thumbtack"], [1, "pinned-actions"], [1, "pin-action-btn", "done"], [1, "edit-mode-banner"], [1, "pin-empty-state"], [1, "pin-grid"], [1, "pin-action-btn", "done", 3, "click"], [1, "fa-solid", "fa-check"], [1, "pin-action-btn", "primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "pin-action-btn"], [1, "pin-action-btn", 3, "click"], [1, "fa-solid", "fa-pen"], [1, "fa-solid", "fa-arrows-up-down-left-right"], ["type", "button", "title", "Hide this", 1, "pin-empty-close"], ["Icon", "fa-solid fa-thumbtack", "Title", "No pinned items yet", "Message", "Pin your favorite dashboards, views, queries, and reports for quick access."], ["actions", "", "mjButton", "", "variant", "primary", 3, "click"], ["actions", "", "mjButton", "", "variant", "flat"], ["type", "button", "title", "Hide this", 1, "pin-empty-close", 3, "click"], [1, "fa-solid", "fa-xmark"], ["actions", "", "mjButton", "", "variant", "flat", 3, "click"], [1, "pin-card", 3, "edit-mode", "dragging", "drag-over", "draggable"], [1, "add-pin-card"], [1, "pin-card", 3, "dragstart", "dragover", "dragleave", "drop", "dragend", "click", "draggable"], [1, "edit-controls"], [1, "pin-thumbnail"], [1, "pin-thumbnail", "action-mode", 3, "background"], [1, "pin-thumbnail", "icon-mode", 3, "--pin-icon-color"], [1, "pin-info"], [1, "pin-name-input", 3, "value"], [1, "pin-name"], [1, "pin-meta"], [1, "pin-app-badge"], [1, "drag-handle"], [1, "fa-solid", "fa-grip-vertical"], [1, "edit-card-actions"], ["aria-label", "Remove pin", "title", "Remove pin", 1, "edit-card-btn", "delete", 3, "click"], [3, "src", "alt"], [1, "pin-overlay"], [1, "open-btn", 3, "click"], [1, "pin-thumbnail", "action-mode"], [1, "pin-thumbnail", "icon-mode"], [1, "pin-name-input", 3, "blur", "keydown.enter", "click", "value"], [1, "pin-name", 3, "click"], ["aria-label", "Pin options", "title", "Pin options", 1, "more-btn"], ["aria-label", "Pin options", "title", "Pin options", 1, "more-btn", 3, "click"], [1, "fa-solid", "fa-ellipsis"], [1, "group-header"], [1, "group-name-input", 3, "value"], [1, "group-name"], [1, "group-line"], [1, "group-count"], [1, "group-edit-controls"], [1, "group-name-input", 3, "blur", "keydown.enter", "value"], [1, "group-name", 3, "click"], [1, "group-edit-btn", "danger", 3, "click"], [1, "fa-solid", "fa-folder-minus"], [1, "add-pin-card", 3, "click"], [1, "pin-context-menu"], [1, "pin-context-item", 3, "click"], [1, "pin-context-divider"], [1, "pin-context-submenu"], [1, "pin-context-item", "submenu-header"], [1, "fa-solid", "fa-folder"], [1, "pin-context-item", "submenu-item"], [1, "pin-context-item", "danger", 3, "click"], [1, "fa-solid", "fa-thumbtack-slash"], [1, "pin-context-item", "submenu-item", 3, "click"], [1, "slide-panel-backdrop", 3, "click"], [1, "slide-panel"], [1, "slide-panel-header"], [1, "slide-panel-close", 3, "click"], [1, "search-box"], [1, "search-input-wrapper"], [1, "fa-solid", "fa-magnifying-glass"], ["type", "text", "placeholder", "Search apps, dashboards, views, queries...", 3, "ngModelChange", "ngModel"], [1, "group-selector"], [3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], ["value", "__new__"], [1, "new-group-row"], [1, "panel-results"], [1, "panel-loading"], ["type", "text", "placeholder", "Enter new group name...", 1, "new-group-input", 3, "ngModelChange", "ngModel"], ["text", "Loading resources...", "size", "small"], ["Size", "sm", 1, "panel-section", 3, "FlushBody", "Expanded"], ["Size", "sm", 1, "panel-section", 3, "ExpandedChange", "FlushBody", "Expanded"], ["mjAccordionTitle", ""], ["mjAccordionBody", ""], [1, "fa-solid", "fa-grid-2"], [1, "mj-accordion-badge", "mj-accordion-badge--right"], [1, "panel-app-header"], [1, "panel-app-icon"], [1, "panel-app-name"], [1, "panel-item", "panel-nav-item"], [1, "panel-item-icon"], [1, "panel-item-info"], [1, "panel-item-name"], [1, "panel-item-action"], [1, "pinned-badge"], [1, "pin-btn"], [1, "pin-btn", 3, "click"], [1, "fa-solid", "fa-gauge-high"], [1, "panel-item"], [1, "panel-item-icon", 2, "background", "color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))"], [1, "fa-solid", "fa-gauge-high", 2, "color", "var(--mj-brand-primary)"], [1, "fa-solid", "fa-table-list"], [1, "fa-solid", "fa-table-list", 2, "color", "var(--mj-brand-primary)"], [1, "panel-item-sub"], [1, "fa-solid", "fa-database"], [1, "fa-solid", "fa-database", 2, "color", "var(--mj-brand-primary)"], [1, "fa-solid", "fa-bolt"], [1, "fa-solid", "fa-bolt", 2, "color", "var(--mj-brand-primary)"], [1, "fa-solid", "fa-sliders"], ["text", "Loading your applications...", "size", "large"], [1, "apps-grid"], [1, "app-card", 3, "mjClickable", "testId", "--app-color"], ["Icon", "fa-solid fa-folder-open", "Title", "No Applications Available", "Message", "You don't have any applications configured yet.", "ActionText", "Configure Applications", "ActionIcon", "fa-solid fa-gear"], [1, "app-card", 3, "click", "mjClickable", "testId"], [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"], ["Icon", "fa-solid fa-folder-open", "Title", "No Applications Available", "Message", "You don't have any applications configured yet.", "ActionText", "Configure Applications", "ActionIcon", "fa-solid fa-gear", 3, "Action"], [1, "sidebar-header"], ["title", "Close panel", 1, "sidebar-close-btn", 3, "click"], [1, "sidebar-content"], [1, "sidebar-section", "notifications-section"], [1, "sidebar-section", "favorites-section"], [1, "sidebar-section", "recents-section"], ["Size", "compact", "Icon", "fa-solid fa-inbox", "Title", "No quick access items", 1, "sidebar-empty"], [1, "sidebar-section-title"], [1, "fa-solid", "fa-bell"], [1, "section-badge"], [1, "sidebar-items"], ["testId", "notification-item", 1, "sidebar-item", "notification-item", 3, "mjClickable"], ["testId", "notification-item", 1, "sidebar-item", "notification-item", 3, "click", "mjClickable"], [1, "sidebar-item-info"], [1, "sidebar-item-title"], [1, "sidebar-item-subtitle"], [1, "fa-solid", "fa-star"], [1, "sidebar-loading"], ["testId", "favorite-item", 1, "sidebar-item", "favorite-item", 3, "mjClickable"], ["testId", "favorite-item", 1, "sidebar-item", "favorite-item", 3, "click", "mjClickable"], [1, "sidebar-item-icon"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-clock-rotate-left"], ["testId", "recent-item", 1, "sidebar-item", "recent-item", 3, "mjClickable"], ["testId", "recent-item", 1, "sidebar-item", "recent-item", 3, "click", "mjClickable"], ["title", "Quick Access", 1, "sidebar-fab-toggle", 3, "click"], [1, "fab-badge"]], template: function HomeDashboardComponent_Template(rf, ctx) { if (rf & 1) {
3619
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.pinMenuEl = _t.first);
3620
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.dashboardEditor = _t.first);
3621
+ } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 16, vars: 19, consts: [["homeDashboardTitle", ""], ["appConfigDialog", ""], ["dashboardEditor", ""], ["pinMenu", ""], [1, "home-dashboard"], [1, "main-content"], [1, "home-overview"], ["BodyStyle", "card", 1, "home-dashboard-view", 3, "Provider", "DashboardId", "StartInEditMode", "TitleTemplate", "ShowOpenInDashboards"], ["role", "menu", 1, "pin-context-menu", 3, "left", "top", "max-height"], [3, "Result", "Visible", "ActionID", "ActionName", "ActionDescription"], [3, "Result", "Visible", "Pin"], [3, "Confirmed", "Cancelled", "Visible", "MaxLength", "Processing"], [1, "loading-container"], [1, "quick-access-sidebar"], ["title", "Quick Access", 1, "sidebar-fab-toggle"], [3, "ShowDialogChange", "ConfigSaved", "ShowDialog"], [1, "home-header"], [1, "greeting-section"], [1, "date"], [1, "pinned-section", 3, "ExpandedChange", "Bare", "TitleIconMuted", "HeadingLevel", "FlushBody", "Expanded"], ["mjAccordionTitle", ""], ["mjAccordionActions", ""], ["mjAccordionBody", ""], [1, "apps-section"], [1, "section-title"], [1, "apps-grid"], [1, "app-card", 3, "mjClickable", "TestId", "--app-color"], ["Icon", "fa-solid fa-folder-open", "Title", "No Applications Available", "Message", "You don't have any applications configured yet.", "ActionText", "Configure Applications", "ActionIcon", "fa-solid fa-gear"], [1, "pinned-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-thumbtack"], [1, "pinned-actions"], ["type", "button", "mjButton", "", "Variant", "success", "Size", "sm"], ["type", "button", "mjButton", "", "Variant", "success", "Size", "sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-check"], [1, "pin-action-label"], ["type", "button", "mjButton", "", "Variant", "primary", "Size", "sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], ["Look", "button", "Align", "right", "Label", "Dashboards", 3, "Pick", "New", "ManagePins", "Dashboards", "CurrentId"], ["type", "button", "mjButton", "", "Variant", "secondary", "Size", "sm"], ["type", "button", "mjButton", "", "Variant", "secondary", "Size", "sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-pen"], [1, "pinned-body"], [1, "edit-mode-banner"], [1, "pin-empty-state"], [1, "pin-grid"], [1, "fa-solid", "fa-arrows-up-down-left-right"], ["type", "button", "title", "Hide this", 1, "pin-empty-close"], ["Icon", "fa-solid fa-thumbtack", "Title", "No pinned items yet", "Message", "Pin your favorite dashboards, views, queries, and reports for quick access."], ["actions", "", "mjButton", "", "variant", "primary", 3, "click"], [1, "fa-solid", "fa-plus"], ["actions", "", "mjButton", "", "variant", "flat"], ["type", "button", "title", "Hide this", 1, "pin-empty-close", 3, "click"], [1, "fa-solid", "fa-xmark"], ["actions", "", "mjButton", "", "variant", "flat", 3, "click"], [1, "add-pin-card"], [1, "group-header"], [1, "pin-card", 3, "edit-mode", "dragging", "drag-over", "menu-open", "draggable"], [1, "group-name-input", 3, "value"], [1, "group-name"], [1, "group-line"], [1, "group-count"], [1, "group-edit-controls"], [1, "group-name-input", 3, "blur", "keydown.enter", "value"], [1, "group-name", 3, "click"], ["type", "button", 1, "group-edit-btn", "danger", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-folder-minus"], [1, "pin-card", 3, "dragstart", "dragover", "dragleave", "drop", "dragend", "click", "draggable"], [1, "edit-controls"], [1, "pin-thumbnail"], [1, "pin-thumbnail", "action-mode", 3, "background"], [1, "pin-thumbnail", "icon-mode"], [1, "pin-info"], [1, "pin-name-input", 3, "value"], [1, "pin-name"], [1, "pin-meta"], ["aria-hidden", "true", 1, "fa-solid", "fa-gauge-high"], [1, "pin-kind"], [1, "drag-handle"], ["aria-hidden", "true", 1, "fa-solid", "fa-grip-vertical"], [1, "edit-card-actions"], ["type", "button", "aria-label", "Remove pin", "title", "Remove pin", 1, "edit-card-btn", "delete", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], [3, "src", "alt"], [1, "pin-overlay"], [1, "pin-thumbnail", "action-mode"], ["aria-hidden", "true"], [1, "pin-name-input", 3, "blur", "keydown.enter", "click", "value"], [1, "pin-name", 3, "click"], [1, "pin-name-text"], ["type", "button", "title", "Pin options", "aria-haspopup", "menu", 1, "more-btn"], ["type", "button", "title", "Pin options", "aria-haspopup", "menu", 1, "more-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-ellipsis"], [1, "add-pin-card", 3, "click"], [1, "app-card", 3, "click", "mjClickable", "TestId"], ["aria-hidden", "true", 1, "app-icon"], [1, "app-info"], [1, "app-name"], [1, "app-description"], ["Icon", "fa-solid fa-folder-open", "Title", "No Applications Available", "Message", "You don't have any applications configured yet.", "ActionText", "Configure Applications", "ActionIcon", "fa-solid fa-gear", 3, "Action"], ["BodyStyle", "card", 1, "home-dashboard-view", 3, "StartInEditModeChange", "Loaded", "EditingChange", "NameChanged", "Saved", "LoadFailed", "OpenInDashboardsRequested", "NavigationRequested", "Provider", "DashboardId", "StartInEditMode", "TitleTemplate", "ShowOpenInDashboards"], [1, "dashboard-title"], ["aria-label", "Breadcrumb", 1, "dashboard-crumb"], ["type", "button", 1, "crumb-home", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-house"], ["Look", "title", "Align", "left", 3, "Pick", "New", "ManagePins", "HeadingLevel", "Label", "Dashboards", "CurrentId"], ["role", "menu", 1, "pin-context-menu", 3, "keydown"], ["type", "button", "role", "menuitem", 1, "pin-context-item", 3, "click"], ["role", "separator", 1, "pin-context-divider"], ["role", "group"], [1, "pin-context-item", "submenu-header", 3, "id"], ["aria-hidden", "true", 1, "fa-solid", "fa-folder"], ["type", "button", "role", "menuitem", 1, "pin-context-item", "submenu-item"], ["type", "button", "role", "menuitem", 1, "pin-context-item", "danger", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-thumbtack-slash"], ["type", "button", "role", "menuitem", 1, "pin-context-item", "submenu-item", 3, "click"], [1, "slide-panel-backdrop", 3, "click"], [1, "slide-panel"], [1, "slide-panel-header"], [1, "fa-solid", "fa-thumbtack"], [1, "slide-panel-close", 3, "click"], [1, "search-box"], [1, "search-input-wrapper"], [1, "fa-solid", "fa-magnifying-glass"], ["type", "text", "placeholder", "Search apps, dashboards, views, queries...", 3, "ngModelChange", "ngModel"], [1, "group-selector"], [1, "fa-solid", "fa-folder"], [3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], ["value", "__new__"], [1, "new-group-row"], [1, "panel-results"], [1, "panel-loading"], ["type", "text", "placeholder", "Enter new group name...", 1, "new-group-input", 3, "ngModelChange", "ngModel"], ["text", "Loading resources...", "size", "small"], ["Size", "sm", 1, "panel-section", 3, "FlushBody", "Expanded"], ["Size", "sm", 1, "panel-section", 3, "ExpandedChange", "FlushBody", "Expanded"], [1, "fa-solid", "fa-grid-2"], [1, "mj-accordion-badge", "mj-accordion-badge--right"], [1, "panel-app-header"], [1, "panel-app-icon"], [1, "panel-app-name"], [1, "panel-item", "panel-nav-item"], [1, "panel-item-icon"], [1, "panel-item-info"], [1, "panel-item-name"], [1, "panel-item-action"], [1, "pinned-badge"], [1, "pin-btn"], [1, "fa-solid", "fa-check"], [1, "pin-btn", 3, "click"], [1, "fa-solid", "fa-gauge-high"], [1, "panel-item"], [1, "panel-item-icon", 2, "background", "color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))"], [1, "fa-solid", "fa-gauge-high", 2, "color", "var(--mj-brand-primary)"], [1, "fa-solid", "fa-table-list"], [1, "fa-solid", "fa-table-list", 2, "color", "var(--mj-brand-primary)"], [1, "panel-item-sub"], [1, "fa-solid", "fa-database"], [1, "fa-solid", "fa-database", 2, "color", "var(--mj-brand-primary)"], [1, "fa-solid", "fa-bolt"], [1, "fa-solid", "fa-bolt", 2, "color", "var(--mj-brand-primary)"], [1, "fa-solid", "fa-sliders"], ["text", "Loading your applications...", "size", "large"], [1, "sidebar-header"], ["title", "Close panel", 1, "sidebar-close-btn", 3, "click"], [1, "sidebar-content"], [1, "sidebar-section", "notifications-section"], [1, "sidebar-section", "favorites-section"], [1, "sidebar-section", "recents-section"], ["Size", "compact", "Icon", "fa-solid fa-inbox", "Title", "No quick access items", 1, "sidebar-empty"], [1, "sidebar-section-title"], [1, "fa-solid", "fa-bell"], [1, "section-badge"], [1, "sidebar-items"], ["testId", "notification-item", 1, "sidebar-item", "notification-item", 3, "mjClickable"], ["testId", "notification-item", 1, "sidebar-item", "notification-item", 3, "click", "mjClickable"], [1, "sidebar-item-info"], [1, "sidebar-item-title"], [1, "sidebar-item-subtitle"], [1, "fa-solid", "fa-star"], [1, "sidebar-loading"], ["testId", "favorite-item", 1, "sidebar-item", "favorite-item", 3, "mjClickable"], ["testId", "favorite-item", 1, "sidebar-item", "favorite-item", 3, "click", "mjClickable"], [1, "sidebar-item-icon"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-clock-rotate-left"], ["testId", "recent-item", 1, "sidebar-item", "recent-item", 3, "mjClickable"], ["testId", "recent-item", 1, "sidebar-item", "recent-item", 3, "click", "mjClickable"], ["title", "Quick Access", 1, "sidebar-fab-toggle", 3, "click"], [1, "fab-badge"]], template: function HomeDashboardComponent_Template(rf, ctx) { if (rf & 1) {
2944
3622
  const _r1 = i0.ɵɵgetCurrentView();
2945
- i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "div", 3)(3, "div", 4)(4, "h1");
2946
- i0.ɵɵtext(5);
3623
+ i0.ɵɵelementStart(0, "div", 4)(1, "div", 5);
3624
+ i0.ɵɵconditionalCreate(2, HomeDashboardComponent_Conditional_2_Template, 18, 9, "div", 6);
3625
+ i0.ɵɵconditionalCreate(3, HomeDashboardComponent_Conditional_3_Template, 2, 5, "mj-dashboard-editor", 7);
3626
+ i0.ɵɵtemplate(4, HomeDashboardComponent_ng_template_4_Template, 10, 4, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
3627
+ i0.ɵɵconditionalCreate(6, HomeDashboardComponent_Conditional_6_Template, 20, 10, "div", 8);
3628
+ i0.ɵɵconditionalCreate(7, HomeDashboardComponent_Conditional_7_Template, 27, 4);
3629
+ i0.ɵɵelementStart(8, "mj-action-pin-config-dialog", 9);
3630
+ i0.ɵɵlistener("Result", function HomeDashboardComponent_Template_mj_action_pin_config_dialog_Result_8_listener($event) { return ctx.OnActionConfigResult($event); });
2947
3631
  i0.ɵɵelementEnd();
2948
- i0.ɵɵelementStart(6, "p", 5);
2949
- i0.ɵɵtext(7);
2950
- i0.ɵɵelementEnd()()();
2951
- i0.ɵɵconditionalCreate(8, HomeDashboardComponent_Conditional_8_Template, 11, 4, "div", 6);
2952
- i0.ɵɵconditionalCreate(9, HomeDashboardComponent_Conditional_9_Template, 19, 5, "div", 7);
2953
- i0.ɵɵconditionalCreate(10, HomeDashboardComponent_Conditional_10_Template, 27, 4);
2954
- i0.ɵɵelementStart(11, "mj-action-pin-config-dialog", 8);
2955
- i0.ɵɵlistener("Result", function HomeDashboardComponent_Template_mj_action_pin_config_dialog_Result_11_listener($event) { return ctx.OnActionConfigResult($event); });
3632
+ i0.ɵɵelementStart(9, "mj-action-pin-runner-dialog", 10);
3633
+ i0.ɵɵlistener("Result", function HomeDashboardComponent_Template_mj_action_pin_runner_dialog_Result_9_listener($event) { return ctx.OnActionRunnerResult($event); });
2956
3634
  i0.ɵɵelementEnd();
2957
- i0.ɵɵelementStart(12, "mj-action-pin-runner-dialog", 9);
2958
- i0.ɵɵlistener("Result", function HomeDashboardComponent_Template_mj_action_pin_runner_dialog_Result_12_listener($event) { return ctx.OnActionRunnerResult($event); });
3635
+ i0.ɵɵelementStart(10, "mj-dashboard-name-dialog", 11);
3636
+ i0.ɵɵlistener("Confirmed", function HomeDashboardComponent_Template_mj_dashboard_name_dialog_Confirmed_10_listener($event) { return ctx.OnNewDashboardNamed($event); })("Cancelled", function HomeDashboardComponent_Template_mj_dashboard_name_dialog_Cancelled_10_listener() { return ctx.OnNewDashboardCancelled(); });
2959
3637
  i0.ɵɵelementEnd();
2960
- i0.ɵɵconditionalCreate(13, HomeDashboardComponent_Conditional_13_Template, 2, 0, "div", 10);
2961
- i0.ɵɵconditionalCreate(14, HomeDashboardComponent_Conditional_14_Template, 8, 1, "div", 11);
3638
+ i0.ɵɵconditionalCreate(11, HomeDashboardComponent_Conditional_11_Template, 2, 0, "div", 12);
2962
3639
  i0.ɵɵelementEnd();
2963
- i0.ɵɵconditionalCreate(15, HomeDashboardComponent_Conditional_15_Template, 12, 4, "div", 12);
2964
- i0.ɵɵconditionalCreate(16, HomeDashboardComponent_Conditional_16_Template, 3, 1, "button", 13);
2965
- i0.ɵɵelementStart(17, "mj-user-app-config", 14, 0);
2966
- i0.ɵɵtwoWayListener("ShowDialogChange", function HomeDashboardComponent_Template_mj_user_app_config_ShowDialogChange_17_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.showConfigDialog, $event) || (ctx.showConfigDialog = $event); return i0.ɵɵresetView($event); });
2967
- i0.ɵɵlistener("ConfigSaved", function HomeDashboardComponent_Template_mj_user_app_config_ConfigSaved_17_listener() { return ctx.onConfigSaved(); });
3640
+ i0.ɵɵconditionalCreate(12, HomeDashboardComponent_Conditional_12_Template, 12, 4, "div", 13);
3641
+ i0.ɵɵconditionalCreate(13, HomeDashboardComponent_Conditional_13_Template, 3, 1, "button", 14);
3642
+ i0.ɵɵelementStart(14, "mj-user-app-config", 15, 1);
3643
+ i0.ɵɵtwoWayListener("ShowDialogChange", function HomeDashboardComponent_Template_mj_user_app_config_ShowDialogChange_14_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.showConfigDialog, $event) || (ctx.showConfigDialog = $event); return i0.ɵɵresetView($event); });
3644
+ i0.ɵɵlistener("ConfigSaved", function HomeDashboardComponent_Template_mj_user_app_config_ConfigSaved_14_listener() { return ctx.onConfigSaved(); });
2968
3645
  i0.ɵɵelementEnd()();
2969
3646
  } if (rf & 2) {
2970
- i0.ɵɵclassProp("sidebar-open", ctx.sidebarOpen && ctx.hasSidebarContent);
2971
- i0.ɵɵadvance(5);
2972
- i0.ɵɵtextInterpolate2("", ctx.greeting, ", ", ctx.currentUser == null ? null : ctx.currentUser.Name);
3647
+ i0.ɵɵclassProp("sidebar-open", ctx.SidebarOpen && ctx.ShowQuickAccess);
2973
3648
  i0.ɵɵadvance(2);
2974
- i0.ɵɵtextInterpolate(ctx.formattedDate);
2975
- i0.ɵɵadvance();
2976
- i0.ɵɵconditional(!ctx.isLoading ? 8 : -1);
3649
+ i0.ɵɵconditional(ctx.ShowOverview ? 2 : -1);
2977
3650
  i0.ɵɵadvance();
2978
- i0.ɵɵconditional(ctx.PinMenuVisible && ctx.PinMenuPin ? 9 : -1);
3651
+ i0.ɵɵconditional(ctx.ShowDashboardView && ctx.CurrentDashboardId ? 3 : -1);
3652
+ i0.ɵɵadvance(3);
3653
+ i0.ɵɵconditional(ctx.PinMenuVisible && ctx.PinMenuPin ? 6 : -1);
2979
3654
  i0.ɵɵadvance();
2980
- i0.ɵɵconditional(ctx.AddPanelOpen ? 10 : -1);
3655
+ i0.ɵɵconditional(ctx.AddPanelOpen ? 7 : -1);
2981
3656
  i0.ɵɵadvance();
2982
3657
  i0.ɵɵproperty("Visible", ctx.ActionConfigDialogVisible)("ActionID", ctx.ActionConfigActionId)("ActionName", ctx.ActionConfigActionName)("ActionDescription", ctx.ActionConfigActionDescription);
2983
3658
  i0.ɵɵadvance();
2984
3659
  i0.ɵɵproperty("Visible", ctx.ActionRunnerDialogVisible)("Pin", ctx.ActionRunnerPin);
2985
3660
  i0.ɵɵadvance();
2986
- i0.ɵɵconditional(ctx.isLoading ? 13 : -1);
3661
+ i0.ɵɵproperty("Visible", ctx.ShowNewDashboardDialog)("MaxLength", ctx.NewDashboardNameMaxLength)("Processing", ctx.IsCreatingDashboard);
2987
3662
  i0.ɵɵadvance();
2988
- i0.ɵɵconditional(!ctx.isLoading ? 14 : -1);
3663
+ i0.ɵɵconditional(ctx.isLoading ? 11 : -1);
2989
3664
  i0.ɵɵadvance();
2990
- i0.ɵɵconditional(ctx.hasSidebarContent ? 15 : -1);
3665
+ i0.ɵɵconditional(ctx.ShowQuickAccess ? 12 : -1);
2991
3666
  i0.ɵɵadvance();
2992
- i0.ɵɵconditional(ctx.hasSidebarContent && !ctx.sidebarOpen ? 16 : -1);
3667
+ i0.ɵɵconditional(ctx.ShowQuickAccess && !ctx.SidebarOpen ? 13 : -1);
2993
3668
  i0.ɵɵadvance();
2994
3669
  i0.ɵɵtwoWayProperty("ShowDialog", ctx.showConfigDialog);
2995
- } }, dependencies: [i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.DefaultValueAccessor, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.MJButtonDirective, i4.MJClickableDirective, i4.MJEmptyStateComponent, i4.MJAccordionPanelComponent, i4.MJAccordionTitleDirective, i4.MJAccordionBodyDirective, i5.LoadingComponent, i6.UserAppConfigComponent, i7.ActionPinConfigDialogComponent, i8.ActionPinRunnerDialogComponent, i9.SlicePipe], styles: [".home-dashboard[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n background: var(--mj-bg-page);\n overflow: hidden;\n position: relative;\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 var(--mj-transition-slow);\n}\n\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 320px;\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: var(--mj-text-4xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-base);\n color: var(--mj-text-muted);\n}\n\n\n.sidebar-fab-toggle[_ngcontent-%COMP%] {\n position: absolute;\n top: 20px;\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xl);\n cursor: pointer;\n box-shadow: var(--mj-shadow-brand-md);\n transition: all var(--mj-transition-base);\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: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\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: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\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: var(--mj-text-muted);\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n color: var(--mj-brand-primary);\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: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\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.app-card[_ngcontent-%COMP%] {\n --app-color: var(--mj-text-muted);\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\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: var(--mj-shadow-lg);\n transform: translateY(-3px);\n}\n\n.app-card[_ngcontent-%COMP%]:hover::before {\n opacity: 1;\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: var(--mj-radius-lg);\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: var(--mj-text-xl);\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: var(--mj-text-inverse);\n transform: scale(1.1);\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: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.app-description[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n line-height: var(--mj-leading-snug);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\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: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n}\n\n.nav-item-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-muted);\n}\n\n.more-items[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-style: italic;\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: var(--mj-text-base);\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\n.quick-access-sidebar[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform var(--mj-transition-slow);\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\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 var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\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: var(--mj-brand-primary);\n font-size: var(--mj-text-sm);\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\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: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n}\n\n.notifications-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-600);\n}\n\n.favorites-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.recents-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.section-badge[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n padding: 2px 6px;\n border-radius: var(--mj-radius-md);\n margin-left: auto;\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: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n transform: translateX(4px);\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\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: var(--mj-text-sm);\n color: var(--mj-text-muted);\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-600);\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-500);\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-info-50);\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\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: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\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: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n padding: 8px 0;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\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: var(--mj-text-disabled);\n}\n\n.sidebar-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n margin-bottom: 12px;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n\n.pinned-section[_ngcontent-%COMP%] {\n margin-bottom: 32px;\n}\n\n.pinned-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.pinned-header[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] {\n margin: 0;\n}\n\n.pinned-actions[_ngcontent-%COMP%] {\n margin-left: auto;\n display: flex;\n gap: 8px;\n}\n\n.pin-action-btn[_ngcontent-%COMP%] {\n padding: 6px 14px;\n border-radius: var(--mj-radius-md);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all var(--mj-transition-base);\n}\n\n.pin-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pin-action-btn.done[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n border-color: var(--mj-status-success);\n}\n\n\n.edit-mode-banner[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n border-radius: var(--mj-radius-lg);\n padding: 12px 20px;\n margin-bottom: 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.edit-mode-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-base);\n}\n\n.edit-mode-banner[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n.pin-empty-state[_ngcontent-%COMP%] {\n position: relative;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n}\n\n.pin-empty-close[_ngcontent-%COMP%] {\n position: absolute;\n top: 10px;\n right: 10px;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: var(--mj-text-sm);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.pin-empty-close[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n\n.pin-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 12px;\n}\n\n\n.group-header[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 0 4px 0;\n margin-top: 8px;\n}\n\n.group-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.group-line[_ngcontent-%COMP%] {\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.group-count[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n background: var(--mj-bg-surface-card);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.group-name-input[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 8px;\n background: var(--mj-bg-surface);\n outline: none;\n width: 160px;\n}\n\n.group-edit-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.group-edit-btn[_ngcontent-%COMP%] {\n background: none;\n border: 1px solid transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n padding: 2px 8px;\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all var(--mj-transition-base);\n}\n\n.group-edit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.group-edit-btn.danger[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n\n.pin-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n}\n\n.pin-card[_ngcontent-%COMP%]:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, var(--mj-border-default));\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.pin-card.edit-mode[_ngcontent-%COMP%] {\n cursor: grab;\n}\n\n.pin-card.edit-mode[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.pin-card.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-lg);\n transform: rotate(2deg);\n}\n\n.pin-card.drag-over[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n border-style: dashed;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n\n.edit-controls[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n left: 8px;\n right: 8px;\n display: flex;\n justify-content: space-between;\n z-index: 10;\n pointer-events: none;\n}\n\n.edit-controls[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] {\n pointer-events: auto;\n}\n\n.drag-handle[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: grab;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.drag-handle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.edit-card-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.edit-card-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-btn.delete[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n\n\n.pin-thumbnail[_ngcontent-%COMP%] {\n width: 100%;\n aspect-ratio: 16 / 10;\n overflow: hidden;\n position: relative;\n}\n\n.pin-thumbnail[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.pin-thumbnail.icon-mode[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--pin-icon-color, var(--mj-text-muted)) 10%, var(--mj-bg-surface-card));\n}\n\n.pin-thumbnail.icon-mode[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--pin-icon-color, var(--mj-text-muted));\n opacity: 0.7;\n}\n\n\n.pin-thumbnail.action-mode[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse, white);\n background: var(--mj-brand-primary);\n}\n\n.pin-thumbnail.action-mode[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--mj-text-inverse, white);\n}\n\n\n.pin-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n background: rgba(0,0,0,0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.pin-card[_ngcontent-%COMP%]:hover .pin-overlay[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n}\n\n.open-btn[_ngcontent-%COMP%] {\n padding: 8px 20px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: none;\n border-radius: var(--mj-radius-md);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n}\n\n\n.pin-info[_ngcontent-%COMP%] {\n padding: 10px 12px;\n}\n\n.pin-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-bottom: 4px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%] {\n margin-left: auto;\n opacity: 0;\n transition: opacity var(--mj-transition-base);\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 2px 4px;\n border-radius: 4px;\n font-size: 14px;\n}\n\n\n\n\n.pin-card[_ngcontent-%COMP%]:hover .pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%], \n.pin-card[_ngcontent-%COMP%]:focus-within .pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-name-input[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 6px;\n width: 100%;\n outline: none;\n background: var(--mj-bg-surface);\n}\n\n.pin-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.pin-meta[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.pin-app-badge[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n\n.add-pin-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 2px dashed var(--mj-border-default);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 180px;\n cursor: pointer;\n transition: all var(--mj-transition-base);\n gap: 8px;\n color: var(--mj-text-muted);\n}\n\n.add-pin-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-pin-card[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n}\n\n.add-pin-card[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n}\n\n\n\n\n.pin-context-menu[_ngcontent-%COMP%] {\n position: fixed;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10001;\n overflow: hidden;\n animation: _ngcontent-%COMP%_pinMenuIn 0.15s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinMenuIn {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.pin-context-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 14px;\n cursor: pointer;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.pin-context-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-context-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 16px;\n text-align: center;\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-item.danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n.pin-context-item.submenu-header[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-medium);\n cursor: default;\n font-size: 12px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n padding: 6px 14px;\n}\n\n.pin-context-item.submenu-header[_ngcontent-%COMP%]:hover {\n background: transparent;\n}\n\n.pin-context-item.submenu-item[_ngcontent-%COMP%] {\n padding-left: 30px;\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n\n\n\n.slide-panel-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 2000;\n}\n\n.slide-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 400px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-xl);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideIn 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.slide-panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.slide-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n}\n\n.slide-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.slide-panel-close[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.slide-panel-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n\n.search-box[_ngcontent-%COMP%] {\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 8px 12px;\n transition: all var(--mj-transition-base);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: none;\n outline: none;\n background: transparent;\n font-size: 14px;\n color: var(--mj-text-primary);\n flex: 1;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n\n.group-selector[_ngcontent-%COMP%] {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.group-selector[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-medium);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.group-selector[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.new-group-input[_ngcontent-%COMP%] {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n\n.panel-results[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.panel-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n\n\n\n\n\n\n.panel-app-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px 6px 12px;\n margin-top: 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-app-header[_ngcontent-%COMP%]:first-child {\n margin-top: 0;\n}\n\n.panel-app-icon[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--panel-app-color);\n}\n\n.panel-app-name[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%] {\n padding: 10px 12px 10px 32px;\n margin-left: 12px;\n border-left: 2px solid var(--mj-border-subtle);\n}\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%]:last-of-type {\n border-left-color: transparent;\n}\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%]:hover {\n border-left-color: var(--mj-brand-primary);\n}\n\n\n.new-group-row[_ngcontent-%COMP%] {\n padding: 0 20px 12px 20px;\n}\n\n.new-group-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n.panel-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: var(--mj-radius-md);\n transition: all var(--mj-transition-base);\n cursor: pointer;\n}\n\n.panel-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.panel-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.panel-item-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.panel-item-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-item-sub[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.panel-item-action[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.panel-item-action[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n padding: 4px 12px;\n border-radius: var(--mj-radius-sm);\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.pin-btn[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.pin-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pinned-badge[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-status-success);\n border: 1px solid var(--mj-status-success);\n cursor: default !important;\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@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: var(--mj-text-3xl);\n }\n\n \n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 0;\n }\n\n \n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 320px;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n }\n}\n\n\n@media (max-width: 768px) {\n \n\n\n\n .main-content[_ngcontent-%COMP%] {\n padding: 20px;\n padding-bottom: 100px; \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: var(--mj-text-2xl);\n }\n\n \n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 10000;\n border-left: none;\n border-top: none;\n }\n\n \n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::before {\n display: none;\n }\n\n \n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n display: none;\n }\n\n .pin-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: 12px;\n }\n\n .slide-panel[_ngcontent-%COMP%] {\n width: 100%;\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: var(--mj-text-lg);\n }\n\n .app-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n }\n\n .nav-preview[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n position: fixed;\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: var(--mj-text-lg);\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: var(--mj-text-xl);\n }\n\n .greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n }\n\n .section-title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\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: var(--mj-text-base);\n }\n}"], changeDetection: 0 });
3670
+ } }, dependencies: [i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.DefaultValueAccessor, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.MJButtonDirective, i4.MJClickableDirective, i4.MJEmptyStateComponent, i4.MJAccordionPanelComponent, i4.MJAccordionTitleDirective, i4.MJAccordionActionsDirective, i4.MJAccordionBodyDirective, i5.LoadingComponent, i6.UserAppConfigComponent, i7.DashboardNameDialogComponent, i8.HomeDashboardSwitcherComponent, i9.ActionPinConfigDialogComponent, i10.ActionPinRunnerDialogComponent, i11.DashboardEditorComponent, i12.SlicePipe], styles: [".home-dashboard[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n background: var(--mj-bg-page);\n overflow: hidden;\n position: relative;\n}\n\n\n.main-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-width: 0;\n overflow-y: auto;\n transition: margin-right var(--mj-transition-slow);\n}\n\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 320px;\n}\n\n\n.home-overview[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 1180px;\n margin: 0 auto;\n padding: var(--mj-space-7) var(--mj-space-8) var(--mj-space-10);\n}\n\n\n.home-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-end;\n gap: var(--mj-space-4);\n margin-bottom: var(--mj-space-6);\n}\n\n.greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-2xl);\n font-weight: var(--mj-font-bold);\n letter-spacing: var(--mj-tracking-tight);\n line-height: var(--mj-leading-tight);\n color: var(--mj-text-primary);\n}\n\n.greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n margin: var(--mj-space-1) 0 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-muted);\n}\n\n\n\n\n\n\n.home-dashboard-view[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n min-height: 520px;\n}\n\n\n.dashboard-title[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.dashboard-crumb[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.crumb-home[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-link);\n cursor: pointer;\n}\n\n.crumb-home[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-link-hover);\n}\n\n.crumb-home[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n border-radius: var(--mj-radius-sm);\n box-shadow: var(--mj-focus-ring);\n}\n\n\n.sidebar-fab-toggle[_ngcontent-%COMP%] {\n position: absolute;\n top: 20px;\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xl);\n cursor: pointer;\n box-shadow: var(--mj-shadow-brand-md);\n transition: all var(--mj-transition-base);\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: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\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: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\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: var(--mj-text-muted);\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n color: var(--mj-brand-primary);\n}\n\n\n.apps-section[_ngcontent-%COMP%] {\n margin-bottom: var(--mj-space-8);\n}\n\n.section-title[_ngcontent-%COMP%] {\n margin: 0 0 var(--mj-space-3);\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-bold);\n color: var(--mj-text-primary);\n}\n\n.apps-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));\n gap: var(--mj-space-3);\n}\n\n\n.app-card[_ngcontent-%COMP%] {\n --app-color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n padding: var(--mj-space-4);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition:\n border-color var(--mj-transition-fast),\n box-shadow var(--mj-transition-fast),\n transform var(--mj-transition-fast);\n}\n\n.app-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.app-card[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n box-shadow: var(--mj-focus-ring);\n}\n\n.app-icon[_ngcontent-%COMP%] {\n flex: 0 0 36px;\n display: grid;\n place-items: center;\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n color: var(--app-color);\n font-size: 16px;\n}\n\n.app-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.app-name[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.app-description[_ngcontent-%COMP%] {\n margin: 2px 0 0;\n font-size: var(--mj-text-xs);\n line-height: var(--mj-leading-snug);\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n\n\n\n.quick-access-sidebar[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform var(--mj-transition-slow);\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\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 var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\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: var(--mj-brand-primary);\n font-size: var(--mj-text-sm);\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\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: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n}\n\n.notifications-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-600);\n}\n\n.favorites-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.recents-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.section-badge[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n padding: 2px 6px;\n border-radius: var(--mj-radius-md);\n margin-left: auto;\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: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n transform: translateX(4px);\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\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: var(--mj-text-sm);\n color: var(--mj-text-muted);\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-600);\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-500);\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-info-50);\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\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: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\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: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n padding: 8px 0;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\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: var(--mj-text-disabled);\n}\n\n.sidebar-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n margin-bottom: 12px;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n\n\n.pinned-section[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: var(--mj-space-8);\n}\n\n\n.pinned-title[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-bold);\n}\n\n.pinned-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n}\n\n\n.pinned-body[_ngcontent-%COMP%] {\n padding-top: var(--mj-space-3);\n}\n\n\n.edit-mode-banner[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n border-radius: var(--mj-radius-lg);\n padding: 12px 20px;\n margin-bottom: 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.edit-mode-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-base);\n}\n\n.edit-mode-banner[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n.pin-empty-state[_ngcontent-%COMP%] {\n position: relative;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n}\n\n.pin-empty-close[_ngcontent-%COMP%] {\n position: absolute;\n top: 10px;\n right: 10px;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: var(--mj-text-sm);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.pin-empty-close[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n\n.pin-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: var(--mj-space-4);\n margin-bottom: var(--mj-space-3);\n}\n\n\n.group-header[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 0 4px 0;\n margin-top: 8px;\n}\n\n.group-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.group-line[_ngcontent-%COMP%] {\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.group-count[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n background: var(--mj-bg-surface-card);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.group-name-input[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 8px;\n background: var(--mj-bg-surface);\n outline: none;\n width: 160px;\n}\n\n.group-edit-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.group-edit-btn[_ngcontent-%COMP%] {\n background: none;\n border: 1px solid transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n padding: 2px 8px;\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all var(--mj-transition-base);\n}\n\n.group-edit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.group-edit-btn.danger[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n\n.pin-card[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n cursor: pointer;\n transition:\n border-color var(--mj-transition-fast),\n box-shadow var(--mj-transition-fast),\n transform var(--mj-transition-fast);\n}\n\n.pin-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.pin-card.edit-mode[_ngcontent-%COMP%] {\n cursor: grab;\n}\n\n.pin-card.edit-mode[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.pin-card.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-lg);\n transform: rotate(2deg);\n}\n\n.pin-card.drag-over[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n border-style: dashed;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n\n.edit-controls[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n left: 8px;\n right: 8px;\n display: flex;\n justify-content: space-between;\n z-index: 10;\n pointer-events: none;\n}\n\n.edit-controls[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] {\n pointer-events: auto;\n}\n\n.drag-handle[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: grab;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.drag-handle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.edit-card-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.edit-card-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-btn.delete[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n\n\n.pin-thumbnail[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n aspect-ratio: 16 / 10;\n overflow: hidden;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.pin-thumbnail[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n\n.pin-thumbnail.icon-mode[_ngcontent-%COMP%] {\n display: grid;\n place-items: center;\n}\n\n.pin-thumbnail.icon-mode[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n display: grid;\n place-items: center;\n width: 52px;\n height: 52px;\n border-radius: var(--mj-radius-md);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 22px;\n}\n\n\n.pin-thumbnail.action-mode[_ngcontent-%COMP%] {\n display: grid;\n place-items: center;\n background: var(--mj-brand-primary);\n}\n\n.pin-thumbnail.action-mode[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--mj-text-inverse, white);\n}\n\n\n.pin-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n display: grid;\n place-items: center;\n background: var(--mj-bg-overlay);\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--mj-transition-fast);\n}\n\n.pin-card[_ngcontent-%COMP%]:hover .pin-overlay[_ngcontent-%COMP%], \n.pin-card[_ngcontent-%COMP%]:focus-within .pin-overlay[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n}\n\n\n.pin-info[_ngcontent-%COMP%] {\n padding: var(--mj-space-3);\n}\n\n.pin-name[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.pin-name-text[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%] {\n flex: none;\n display: inline-grid;\n place-items: center;\n width: 24px;\n height: 24px;\n margin: -4px -4px -4px 0;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-sm);\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: pointer;\n opacity: 0;\n transition:\n opacity var(--mj-transition-fast),\n background-color var(--mj-transition-fast),\n color var(--mj-transition-fast);\n}\n\n\n.pin-card[_ngcontent-%COMP%]:hover .more-btn[_ngcontent-%COMP%], \n.pin-card[_ngcontent-%COMP%]:focus-within .more-btn[_ngcontent-%COMP%], \n.pin-card.menu-open[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%]:hover, \n.pin-card.menu-open[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n box-shadow: var(--mj-focus-ring);\n}\n\n.pin-name-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 2px 6px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n outline: none;\n background: var(--mj-bg-surface);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n\n.pin-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n min-width: 0;\n margin-top: 2px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.pin-meta[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.pin-kind[_ngcontent-%COMP%] {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pin-card[_ngcontent-%COMP%], \n .app-card[_ngcontent-%COMP%] {\n transition: none;\n }\n .pin-card[_ngcontent-%COMP%]:hover, \n .app-card[_ngcontent-%COMP%]:hover {\n transform: none;\n }\n}\n\n\n.add-pin-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 2px dashed var(--mj-border-default);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 180px;\n cursor: pointer;\n transition: all var(--mj-transition-base);\n gap: 8px;\n color: var(--mj-text-muted);\n}\n\n.add-pin-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-pin-card[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n}\n\n.add-pin-card[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n}\n\n\n\n\n\n.pin-context-menu[_ngcontent-%COMP%] {\n position: fixed;\n z-index: 10001;\n width: 220px;\n overflow-y: auto;\n padding: 6px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n animation: _ngcontent-%COMP%_pinMenuIn var(--mj-transition-fast);\n}\n\n@keyframes _ngcontent-%COMP%_pinMenuIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.pin-context-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n width: 100%;\n padding: 8px 10px;\n border: 0;\n border-radius: var(--mj-radius-sm);\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n text-align: left;\n cursor: pointer;\n}\n\n.pin-context-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n.pin-context-item[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n background: var(--mj-bg-surface-hover);\n box-shadow: inset 0 0 0 var(--mj-ring-width) var(--mj-focus-ring-color);\n}\n\n.pin-context-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 14px;\n text-align: center;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.pin-context-item.danger[_ngcontent-%COMP%], \n.pin-context-item.danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.submenu-header[_ngcontent-%COMP%] {\n padding-bottom: 4px;\n cursor: default;\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n}\n\n.pin-context-item.submenu-header[_ngcontent-%COMP%]:hover {\n background: transparent;\n}\n\n.pin-context-item.submenu-item[_ngcontent-%COMP%] {\n padding-left: 34px;\n}\n\n.pin-context-divider[_ngcontent-%COMP%] {\n height: 1px;\n margin: 6px 4px;\n background: var(--mj-border-default);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pin-context-menu[_ngcontent-%COMP%] { animation: none; }\n}\n\n\n\n\n.slide-panel-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 2000;\n}\n\n.slide-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 400px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-xl);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideIn 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.slide-panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.slide-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n}\n\n.slide-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.slide-panel-close[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.slide-panel-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n\n.search-box[_ngcontent-%COMP%] {\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 8px 12px;\n transition: all var(--mj-transition-base);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: none;\n outline: none;\n background: transparent;\n font-size: 14px;\n color: var(--mj-text-primary);\n flex: 1;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n\n.group-selector[_ngcontent-%COMP%] {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.group-selector[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-medium);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.group-selector[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.new-group-input[_ngcontent-%COMP%] {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n\n.panel-results[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.panel-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n\n\n\n\n\n\n.panel-app-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px 6px 12px;\n margin-top: 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-app-header[_ngcontent-%COMP%]:first-child {\n margin-top: 0;\n}\n\n.panel-app-icon[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--panel-app-color);\n}\n\n.panel-app-name[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%] {\n padding: 10px 12px 10px 32px;\n margin-left: 12px;\n border-left: 2px solid var(--mj-border-subtle);\n}\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%]:last-of-type {\n border-left-color: transparent;\n}\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%]:hover {\n border-left-color: var(--mj-brand-primary);\n}\n\n\n.new-group-row[_ngcontent-%COMP%] {\n padding: 0 20px 12px 20px;\n}\n\n.new-group-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n.panel-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: var(--mj-radius-md);\n transition: all var(--mj-transition-base);\n cursor: pointer;\n}\n\n.panel-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.panel-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.panel-item-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.panel-item-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-item-sub[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.panel-item-action[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.panel-item-action[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n padding: 4px 12px;\n border-radius: var(--mj-radius-sm);\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.pin-btn[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.pin-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pinned-badge[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-status-success);\n border: 1px solid var(--mj-status-success);\n cursor: default !important;\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\n\n@media (max-width: 992px) {\n \n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 0;\n }\n\n \n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 320px;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n }\n}\n\n\n@media (max-width: 900px) {\n .home-overview[_ngcontent-%COMP%] {\n padding: var(--mj-space-5) var(--mj-space-4);\n }\n}\n\n\n@media (max-width: 768px) {\n .home-overview[_ngcontent-%COMP%] {\n padding-bottom: 100px; \n }\n\n \n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 10000;\n border-left: none;\n border-top: none;\n }\n\n \n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::before {\n display: none;\n }\n\n \n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n display: none;\n }\n\n .pin-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: var(--mj-space-3);\n }\n\n .slide-panel[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n \n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n position: fixed;\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: var(--mj-text-lg);\n }\n}\n\n@media (max-width: 480px) {\n .home-overview[_ngcontent-%COMP%] {\n padding-bottom: 80px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xl);\n }\n\n .greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n }\n\n \n\n .pinned-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n display: none;\n }\n\n .pinned-actions[_ngcontent-%COMP%] .pin-action-label[_ngcontent-%COMP%] {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: var(--mj-text-base);\n }\n}"], changeDetection: 0 });
2996
3671
  };
2997
3672
  HomeDashboardComponent = __decorate([
2998
3673
  RegisterClass(BaseResourceComponent, 'HomeDashboard')
@@ -3000,10 +3675,23 @@ HomeDashboardComponent = __decorate([
3000
3675
  export { HomeDashboardComponent };
3001
3676
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HomeDashboardComponent, [{
3002
3677
  type: Component,
3003
- 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 <!-- Pinned Section -->\n @if (!isLoading) {\n <div class=\"pinned-section\">\n <div class=\"pinned-header\">\n <h2 class=\"section-title\">\n <i class=\"fa-solid fa-thumbtack\"></i>\n Pinned\n </h2>\n <div class=\"pinned-actions\">\n @if (EditMode) {\n <button class=\"pin-action-btn done\" (click)=\"ToggleEditMode()\">\n <i class=\"fa-solid fa-check\"></i> Done\n </button>\n } @else {\n <button class=\"pin-action-btn primary\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\"></i> Add Pin\n </button>\n @if (PinnedItems.length > 0) {\n <button class=\"pin-action-btn\" (click)=\"ToggleEditMode()\">\n <i class=\"fa-solid fa-pen\"></i> Edit\n </button>\n }\n }\n </div>\n </div>\n\n @if (EditMode) {\n <div class=\"edit-mode-banner\">\n <i class=\"fa-solid fa-arrows-up-down-left-right\"></i>\n <span><strong>Edit mode</strong> \u2014 Drag cards to reorder. Click names to rename.</span>\n </div>\n }\n\n <!-- Empty State -->\n @if (PinnedItems.length === 0 && (EditMode || !HidePinEmptyState)) {\n <div class=\"pin-empty-state\">\n @if (!EditMode) {\n <button type=\"button\" class=\"pin-empty-close\" (click)=\"DismissPinEmptyState()\" title=\"Hide this\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n <mj-empty-state Icon=\"fa-solid fa-thumbtack\"\n Title=\"No pinned items yet\"\n Message=\"Pin your favorite dashboards, views, queries, and reports for quick access.\">\n <button actions mjButton variant=\"primary\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\"></i> Add your first pin\n </button>\n @if (!EditMode && !HidePinEmptyState) {\n <button actions mjButton variant=\"flat\" (click)=\"DismissPinEmptyState()\">\n Don't show this again\n </button>\n }\n </mj-empty-state>\n </div>\n }\n\n <!-- Pin Grid -->\n @if (PinnedItems.length > 0) {\n <div class=\"pin-grid\">\n <!-- Ungrouped Pins -->\n @for (pin of UngroupedPins; track trackByPin($index, pin)) {\n <div class=\"pin-card\"\n [class.edit-mode]=\"EditMode\"\n [class.dragging]=\"DraggingPinId === pin.Id\"\n [class.drag-over]=\"DragOverPinId === pin.Id\"\n [draggable]=\"EditMode\"\n (dragstart)=\"OnDragStart($event, pin)\"\n (dragover)=\"OnDragOver($event, pin)\"\n (dragleave)=\"OnDragLeave()\"\n (drop)=\"OnDrop($event, pin)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OnPinClick(pin)\">\n\n <!-- Edit mode controls -->\n @if (EditMode) {\n <div class=\"edit-controls\">\n <div class=\"drag-handle\"><i class=\"fa-solid fa-grip-vertical\"></i></div>\n <div class=\"edit-card-actions\">\n <button class=\"edit-card-btn delete\" aria-label=\"Remove pin\" title=\"Remove pin\" (click)=\"RemovePin(pin.Id); $event.stopPropagation()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Thumbnail / Icon -->\n @if (pin.Thumbnail) {\n <div class=\"pin-thumbnail\">\n <img [src]=\"pin.Thumbnail\" [alt]=\"pin.DisplayName\" />\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n } @else if (pin.ResourceType === 'Actions') {\n <div class=\"pin-thumbnail action-mode\"\n [style.background]=\"'linear-gradient(135deg, ' + GetPinAccentColor(pin) + ' 0%, ' + GetPinAccentColor(pin) + 'cc 100%)'\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Run</button>\n </div>\n }\n </div>\n } @else {\n <div class=\"pin-thumbnail icon-mode\" [style.--pin-icon-color]=\"pin.Color || 'var(--mj-text-muted)'\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n }\n\n <!-- Pin Info -->\n <div class=\"pin-info\">\n @if (EditMode && EditingPinId === pin.Id) {\n <input class=\"pin-name-input\"\n [value]=\"pin.DisplayName\"\n (blur)=\"SavePinName(pin.Id, GetInputValue($event))\"\n (keydown.enter)=\"SavePinName(pin.Id, GetInputValue($event))\"\n (click)=\"$event.stopPropagation()\" />\n } @else {\n <div class=\"pin-name\" (click)=\"EditMode ? StartEditingPin(pin.Id, $event) : null\">\n {{ pin.DisplayName }}\n @if (!EditMode) {\n <button class=\"more-btn\" aria-label=\"Pin options\" title=\"Pin options\" (click)=\"ShowPinMenu($event, pin)\">\n <i class=\"fa-solid fa-ellipsis\"></i>\n </button>\n }\n </div>\n }\n <div class=\"pin-meta\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n {{ GetResourceTypeLabel(pin) }}\n @if (pin.ApplicationName && pin.ResourceType !== 'Custom') {\n <span class=\"pin-app-badge\">{{ pin.ApplicationName }}</span>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Grouped Pins -->\n @for (group of PinGroups; track trackByGroup($index, group)) {\n <!-- Group Header -->\n <div class=\"group-header\">\n @if (EditMode && EditingGroupName === group) {\n <input class=\"group-name-input\"\n [value]=\"group\"\n (blur)=\"SaveGroupName(group, GetInputValue($event))\"\n (keydown.enter)=\"SaveGroupName(group, GetInputValue($event))\" />\n } @else {\n <span class=\"group-name\" (click)=\"EditMode ? StartEditingGroup(group) : null\">{{ group }}</span>\n }\n <div class=\"group-line\"></div>\n <span class=\"group-count\">{{ GetPinsInGroup(group).length }} pins</span>\n @if (EditMode) {\n <div class=\"group-edit-controls\">\n <button class=\"group-edit-btn danger\" (click)=\"RemoveGroup(group)\">\n <i class=\"fa-solid fa-folder-minus\"></i> Remove Group\n </button>\n </div>\n }\n </div>\n\n <!-- Pins in Group -->\n @for (pin of GetPinsInGroup(group); track trackByPin($index, pin)) {\n <div class=\"pin-card\"\n [class.edit-mode]=\"EditMode\"\n [class.dragging]=\"DraggingPinId === pin.Id\"\n [class.drag-over]=\"DragOverPinId === pin.Id\"\n [draggable]=\"EditMode\"\n (dragstart)=\"OnDragStart($event, pin)\"\n (dragover)=\"OnDragOver($event, pin)\"\n (dragleave)=\"OnDragLeave()\"\n (drop)=\"OnDrop($event, pin)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OnPinClick(pin)\">\n\n @if (EditMode) {\n <div class=\"edit-controls\">\n <div class=\"drag-handle\"><i class=\"fa-solid fa-grip-vertical\"></i></div>\n <div class=\"edit-card-actions\">\n <button class=\"edit-card-btn delete\" aria-label=\"Remove pin\" title=\"Remove pin\" (click)=\"RemovePin(pin.Id); $event.stopPropagation()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n }\n\n @if (pin.Thumbnail) {\n <div class=\"pin-thumbnail\">\n <img [src]=\"pin.Thumbnail\" [alt]=\"pin.DisplayName\" />\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n } @else if (pin.ResourceType === 'Actions') {\n <div class=\"pin-thumbnail action-mode\"\n [style.background]=\"'linear-gradient(135deg, ' + GetPinAccentColor(pin) + ' 0%, ' + GetPinAccentColor(pin) + 'cc 100%)'\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Run</button>\n </div>\n }\n </div>\n } @else {\n <div class=\"pin-thumbnail icon-mode\" [style.--pin-icon-color]=\"pin.Color || 'var(--mj-text-muted)'\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n }\n\n <div class=\"pin-info\">\n @if (EditMode && EditingPinId === pin.Id) {\n <input class=\"pin-name-input\"\n [value]=\"pin.DisplayName\"\n (blur)=\"SavePinName(pin.Id, $event.target.value)\"\n (keydown.enter)=\"SavePinName(pin.Id, $event.target.value)\"\n (click)=\"$event.stopPropagation()\" />\n } @else {\n <div class=\"pin-name\" (click)=\"EditMode ? StartEditingPin(pin.Id, $event) : null\">\n {{ pin.DisplayName }}\n @if (!EditMode) {\n <button class=\"more-btn\" aria-label=\"Pin options\" title=\"Pin options\" (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-ellipsis\"></i>\n </button>\n }\n </div>\n }\n <div class=\"pin-meta\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n {{ GetResourceTypeLabel(pin) }}\n @if (pin.ApplicationName) {\n <span class=\"pin-app-badge\">{{ pin.ApplicationName }}</span>\n }\n </div>\n </div>\n </div>\n }\n }\n\n <!-- Add Pin card (edit mode) -->\n @if (EditMode) {\n <div class=\"add-pin-card\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Pin</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Pin Context Menu (ellipsis) -->\n @if (PinMenuVisible && PinMenuPin) {\n <div class=\"pin-context-menu\"\n [style.left.px]=\"PinMenuX\"\n [style.top.px]=\"PinMenuY\">\n <div class=\"pin-context-item\" (click)=\"OnPinMenuEdit()\">\n <i class=\"fa-solid fa-pen\"></i>\n <span>Edit</span>\n </div>\n <div class=\"pin-context-divider\"></div>\n <div class=\"pin-context-submenu\">\n <div class=\"pin-context-item submenu-header\">\n <i class=\"fa-solid fa-folder\"></i>\n <span>Move to Group</span>\n </div>\n @if (PinMenuPin.Group) {\n <div class=\"pin-context-item submenu-item\" (click)=\"OnPinMenuMoveToGroup(undefined)\">\n <span>(No group)</span>\n </div>\n }\n @for (group of PinGroups; track group) {\n @if (group !== PinMenuPin.Group) {\n <div class=\"pin-context-item submenu-item\" (click)=\"OnPinMenuMoveToGroup(group)\">\n <span>{{ group }}</span>\n </div>\n }\n }\n </div>\n <div class=\"pin-context-divider\"></div>\n <div class=\"pin-context-item danger\" (click)=\"OnPinMenuUnpin()\">\n <i class=\"fa-solid fa-thumbtack-slash\"></i>\n <span>Unpin</span>\n </div>\n </div>\n }\n\n <!-- Add Pin Slide-In Panel -->\n @if (AddPanelOpen) {\n <div class=\"slide-panel-backdrop\" (click)=\"CloseAddPinPanel()\"></div>\n <div class=\"slide-panel\">\n <div class=\"slide-panel-header\">\n <h3><i class=\"fa-solid fa-thumbtack\"></i> Add Pin</h3>\n <button class=\"slide-panel-close\" (click)=\"CloseAddPinPanel()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <div class=\"search-box\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <input type=\"text\"\n placeholder=\"Search apps, dashboards, views, queries...\"\n [(ngModel)]=\"AddPanelSearchQuery\" />\n </div>\n </div>\n\n <div class=\"group-selector\">\n <label><i class=\"fa-solid fa-folder\"></i> Add to group:</label>\n <select [(ngModel)]=\"AddPanelSelectedGroup\">\n <option value=\"\">(No group)</option>\n @for (group of PinGroups; track group) {\n <option [value]=\"group\">{{ group }}</option>\n }\n <option value=\"__new__\">+ New group...</option>\n </select>\n </div>\n @if (AddPanelSelectedGroup === '__new__') {\n <div class=\"new-group-row\">\n <input class=\"new-group-input\"\n type=\"text\"\n placeholder=\"Enter new group name...\"\n [(ngModel)]=\"AddPanelNewGroupName\" />\n </div>\n }\n\n <div class=\"panel-results\">\n @if (AddPanelLoading) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading resources...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <!-- Apps with Nav Items -->\n @if (FilterApps().length > 0) {\n <mj-accordion-panel class=\"panel-section\" Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!PanelSectionCollapsed['apps']\"\n (ExpandedChange)=\"OnPanelSectionExpandedChange('apps', $event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-grid-2\"></i> Applications\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ FilterApps().length }}</span>\n </ng-template>\n <ng-template mjAccordionBody>\n @for (app of FilterApps(); track app.appId) {\n <div class=\"panel-app-header\" [style.--panel-app-color]=\"app.color\">\n <div class=\"panel-app-icon\">\n <i [class]=\"app.icon\"></i>\n </div>\n <span class=\"panel-app-name\">{{ app.appName }}</span>\n </div>\n @for (ni of app.navItems; track ni.label) {\n <div class=\"panel-item panel-nav-item\">\n <div class=\"panel-item-icon\" [style.background]=\"'color-mix(in srgb, ' + app.color + ' 10%, var(--mj-bg-surface-card))'\">\n <i [class]=\"ni.icon\" [style.color]=\"app.color\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ ni.label }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (ni.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinAppNavItem(app.appName, app.icon, app.color, ni.label, ni.icon)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n }\n </ng-template>\n </mj-accordion-panel>\n }\n\n <!-- Dashboards (metadata-driven Config type only) -->\n @if (FilterPanelItems(AvailableDashboards).length > 0) {\n <mj-accordion-panel class=\"panel-section\" Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!PanelSectionCollapsed['dashboards']\"\n (ExpandedChange)=\"OnPanelSectionExpandedChange('dashboards', $event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-gauge-high\"></i> Dashboards\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ FilterPanelItems(AvailableDashboards).length }}</span>\n </ng-template>\n <ng-template mjAccordionBody>\n @for (item of FilterPanelItems(AvailableDashboards); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-gauge-high\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('Dashboards', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n </ng-template>\n </mj-accordion-panel>\n }\n\n <!-- Views -->\n @if (FilterPanelItems(AvailableViews).length > 0) {\n <mj-accordion-panel class=\"panel-section\" Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!PanelSectionCollapsed['views']\"\n (ExpandedChange)=\"OnPanelSectionExpandedChange('views', $event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-table-list\"></i> Views\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ FilterPanelItems(AvailableViews).length }}</span>\n </ng-template>\n <ng-template mjAccordionBody>\n @for (item of FilterPanelItems(AvailableViews); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-table-list\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n <div class=\"panel-item-sub\">{{ item.entityName }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('User Views', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n </ng-template>\n </mj-accordion-panel>\n }\n\n <!-- Queries -->\n @if (FilterPanelItems(AvailableQueries).length > 0) {\n <mj-accordion-panel class=\"panel-section\" Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!PanelSectionCollapsed['queries']\"\n (ExpandedChange)=\"OnPanelSectionExpandedChange('queries', $event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-database\"></i> Queries\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ FilterPanelItems(AvailableQueries).length }}</span>\n </ng-template>\n <ng-template mjAccordionBody>\n @for (item of FilterPanelItems(AvailableQueries); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-database\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('Queries', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n </ng-template>\n </mj-accordion-panel>\n }\n\n <!-- Quick Actions -->\n @if (FilterPanelItems(AvailableActions).length > 0) {\n <mj-accordion-panel class=\"panel-section\" Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!PanelSectionCollapsed['actions']\"\n (ExpandedChange)=\"OnPanelSectionExpandedChange('actions', $event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-bolt\"></i> Quick Actions\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ FilterPanelItems(AvailableActions).length }}</span>\n </ng-template>\n <ng-template mjAccordionBody>\n @for (item of FilterPanelItems(AvailableActions); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-bolt\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n @if (item.description) {\n <div class=\"panel-item-sub\">{{ item.description }}</div>\n }\n </div>\n <div class=\"panel-item-action\">\n <button class=\"pin-btn\" (click)=\"OpenActionPinConfig(item.id, item.name, item.description)\">\n <i class=\"fa-solid fa-sliders\"></i> Configure\n </button>\n </div>\n </div>\n }\n </ng-template>\n </mj-accordion-panel>\n }\n }\n </div>\n </div>\n }\n\n <!-- Action Pin Dialogs -->\n <mj-action-pin-config-dialog\n [Visible]=\"ActionConfigDialogVisible\"\n [ActionID]=\"ActionConfigActionId\"\n [ActionName]=\"ActionConfigActionName\"\n [ActionDescription]=\"ActionConfigActionDescription\"\n (Result)=\"OnActionConfigResult($event)\">\n </mj-action-pin-config-dialog>\n\n <mj-action-pin-runner-dialog\n [Visible]=\"ActionRunnerDialogVisible\"\n [Pin]=\"ActionRunnerPin\"\n (Result)=\"OnActionRunnerResult($event)\">\n </mj-action-pin-runner-dialog>\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 My Applications\n </h2>\n <div class=\"apps-grid\">\n @for (appData of appsDisplayData; track trackByApp($index, appData)) {\n <div\n class=\"app-card\"\n [mjClickable]=\"appData.app.Name\"\n [testId]=\"'app-tile-' + appData.app.Name\"\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 <mj-empty-state Icon=\"fa-solid fa-folder-open\"\n Title=\"No Applications Available\"\n Message=\"You don't have any applications configured yet.\"\n ActionText=\"Configure Applications\"\n ActionIcon=\"fa-solid fa-gear\"\n (Action)=\"openConfigDialog()\" />\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 [mjClickable]=\"notification.Title\"\n testId=\"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 [mjClickable]=\"getFavoriteDisplayName(favorite)\"\n testId=\"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 [mjClickable]=\"item.recordName || item.recordId\"\n testId=\"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 <mj-empty-state class=\"sidebar-empty\" Size=\"compact\"\n Icon=\"fa-solid fa-inbox\"\n Title=\"No quick access items\" />\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: var(--mj-bg-page);\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 var(--mj-transition-slow);\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: var(--mj-text-4xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.greeting-section .date {\n margin: 0;\n font-size: var(--mj-text-base);\n color: var(--mj-text-muted);\n}\n\n/* FAB Toggle Button for Quick Access - top-right on desktop */\n.sidebar-fab-toggle {\n position: absolute;\n top: 20px;\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xl);\n cursor: pointer;\n box-shadow: var(--mj-shadow-brand-md);\n transition: all var(--mj-transition-base);\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle:hover {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\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: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\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: var(--mj-text-muted);\n}\n\n.loading-spinner {\n font-size: var(--mj-text-4xl);\n color: var(--mj-brand-primary);\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: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.section-title i {\n color: var(--mj-text-muted);\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: var(--mj-text-muted);\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\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: var(--mj-shadow-lg);\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: var(--mj-radius-lg);\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: var(--mj-text-xl);\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: var(--mj-text-inverse);\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: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.app-description {\n margin: 0 0 10px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n line-height: var(--mj-leading-snug);\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: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n}\n\n.nav-item-chip i {\n font-size: 9px;\n color: var(--mj-text-muted);\n}\n\n.more-items {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\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: var(--mj-text-base);\n}\n\n.app-card:hover .app-arrow {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\n}\n\n/* ========================================\n RIGHT SIDEBAR\n ======================================== */\n.quick-access-sidebar {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform var(--mj-transition-slow);\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\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 var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.sidebar-header h3 {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header h3 i {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-sm);\n}\n\n.sidebar-close-btn {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\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: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title i {\n font-size: var(--mj-text-xs);\n}\n\n.notifications-section .sidebar-section-title i {\n color: var(--mj-color-warning-600);\n}\n\n.favorites-section .sidebar-section-title i {\n color: var(--mj-status-warning);\n}\n\n.recents-section .sidebar-section-title i {\n color: var(--mj-brand-primary);\n}\n\n.section-badge {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n padding: 2px 6px;\n border-radius: var(--mj-radius-md);\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: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-item:hover {\n background: var(--mj-bg-surface-hover);\n transform: translateX(4px);\n}\n\n.sidebar-item-icon {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\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: var(--mj-text-sm);\n color: var(--mj-text-muted);\n}\n\n.notification-item .sidebar-item-icon {\n background: var(--mj-color-warning-50);\n}\n\n.notification-item .sidebar-item-icon i {\n color: var(--mj-color-warning-600);\n}\n\n.favorite-item .sidebar-item-icon {\n background: var(--mj-color-warning-50);\n}\n\n.favorite-item .sidebar-item-icon i {\n color: var(--mj-color-warning-500);\n}\n\n.recent-item .sidebar-item-icon {\n background: var(--mj-color-info-50);\n}\n\n.recent-item .sidebar-item-icon i {\n color: var(--mj-brand-primary);\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: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\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: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n padding: 8px 0;\n}\n\n.sidebar-loading i {\n color: var(--mj-brand-primary);\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: var(--mj-text-disabled);\n}\n\n.sidebar-empty i {\n font-size: var(--mj-text-4xl);\n margin-bottom: 12px;\n}\n\n.sidebar-empty p {\n margin: 0;\n font-size: var(--mj-text-sm);\n}\n\n\n/* ========================================\n PINNED SECTION\n ======================================== */\n.pinned-section {\n margin-bottom: 32px;\n}\n\n.pinned-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.pinned-header .section-title {\n margin: 0;\n}\n\n.pinned-actions {\n margin-left: auto;\n display: flex;\n gap: 8px;\n}\n\n.pin-action-btn {\n padding: 6px 14px;\n border-radius: var(--mj-radius-md);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all var(--mj-transition-base);\n}\n\n.pin-action-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pin-action-btn.done {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n border-color: var(--mj-status-success);\n}\n\n/* Edit Mode Banner */\n.edit-mode-banner {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n border-radius: var(--mj-radius-lg);\n padding: 12px 20px;\n margin-bottom: 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.edit-mode-banner i {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-base);\n}\n\n.edit-mode-banner strong {\n color: var(--mj-brand-primary);\n}\n\n/* Pin Empty State */\n.pin-empty-state {\n position: relative;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n}\n\n.pin-empty-close {\n position: absolute;\n top: 10px;\n right: 10px;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: var(--mj-text-sm);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.pin-empty-close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n/* Pin Grid */\n.pin-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 12px;\n}\n\n/* Group Header */\n.group-header {\n grid-column: 1 / -1;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 0 4px 0;\n margin-top: 8px;\n}\n\n.group-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.group-line {\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.group-count {\n font-size: 11px;\n color: var(--mj-text-disabled);\n background: var(--mj-bg-surface-card);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.group-name-input {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 8px;\n background: var(--mj-bg-surface);\n outline: none;\n width: 160px;\n}\n\n.group-edit-controls {\n display: flex;\n gap: 6px;\n}\n\n.group-edit-btn {\n background: none;\n border: 1px solid transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n padding: 2px 8px;\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all var(--mj-transition-base);\n}\n\n.group-edit-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.group-edit-btn.danger:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n/* Pin Card */\n.pin-card {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n}\n\n.pin-card:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, var(--mj-border-default));\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.pin-card.edit-mode {\n cursor: grab;\n}\n\n.pin-card.edit-mode:active {\n cursor: grabbing;\n}\n\n.pin-card.dragging {\n opacity: 0.5;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-lg);\n transform: rotate(2deg);\n}\n\n.pin-card.drag-over {\n border-color: var(--mj-brand-primary);\n border-style: dashed;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n/* Edit controls overlay */\n.edit-controls {\n position: absolute;\n top: 8px;\n left: 8px;\n right: 8px;\n display: flex;\n justify-content: space-between;\n z-index: 10;\n pointer-events: none;\n}\n\n.edit-controls > * {\n pointer-events: auto;\n}\n\n.drag-handle {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: grab;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.drag-handle:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-actions {\n display: flex;\n gap: 4px;\n}\n\n.edit-card-btn {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.edit-card-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-btn.delete:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n\n/* Pin Thumbnail */\n.pin-thumbnail {\n width: 100%;\n aspect-ratio: 16 / 10;\n overflow: hidden;\n position: relative;\n}\n\n.pin-thumbnail img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.pin-thumbnail.icon-mode {\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--pin-icon-color, var(--mj-text-muted)) 10%, var(--mj-bg-surface-card));\n}\n\n.pin-thumbnail.icon-mode > i {\n font-size: 36px;\n color: var(--pin-icon-color, var(--mj-text-muted));\n opacity: 0.7;\n}\n\n/* Action-pin card: colored gradient background with white icon/SVG */\n.pin-thumbnail.action-mode {\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse, white);\n background: var(--mj-brand-primary);\n}\n\n.pin-thumbnail.action-mode > i {\n font-size: 36px;\n color: var(--mj-text-inverse, white);\n}\n\n/* Hover overlay */\n.pin-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n background: rgba(0,0,0,0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.pin-card:hover .pin-overlay {\n opacity: 1;\n pointer-events: auto;\n}\n\n.open-btn {\n padding: 8px 20px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: none;\n border-radius: var(--mj-radius-md);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n}\n\n/* Pin Info */\n.pin-info {\n padding: 10px 12px;\n}\n\n.pin-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-bottom: 4px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.pin-name .more-btn {\n margin-left: auto;\n opacity: 0;\n transition: opacity var(--mj-transition-base);\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 2px 4px;\n border-radius: 4px;\n font-size: 14px;\n}\n\n/* Also reveal on keyboard focus \u2014 the pin's overflow menu is the only route to\n rename/remove/configure, and at opacity 0 it was pointer-only: invisible to a\n tabbing keyboard user and unreachable without a hover. */\n.pin-card:hover .pin-name .more-btn,\n.pin-card:focus-within .pin-name .more-btn {\n opacity: 1;\n}\n\n.pin-name .more-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-name-input {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 6px;\n width: 100%;\n outline: none;\n background: var(--mj-bg-surface);\n}\n\n.pin-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.pin-meta > i {\n font-size: 10px;\n}\n\n.pin-app-badge {\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n/* Add Pin Card */\n.add-pin-card {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 2px dashed var(--mj-border-default);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 180px;\n cursor: pointer;\n transition: all var(--mj-transition-base);\n gap: 8px;\n color: var(--mj-text-muted);\n}\n\n.add-pin-card:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-pin-card i {\n font-size: 28px;\n}\n\n.add-pin-card span {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n}\n\n/* ========================================\n PIN CONTEXT MENU (ELLIPSIS)\n ======================================== */\n.pin-context-menu {\n position: fixed;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10001;\n overflow: hidden;\n animation: pinMenuIn 0.15s ease;\n}\n\n@keyframes pinMenuIn {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.pin-context-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 14px;\n cursor: pointer;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.pin-context-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-context-item i {\n width: 16px;\n text-align: center;\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-item.danger {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger i {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n.pin-context-item.submenu-header {\n font-weight: var(--mj-font-medium);\n cursor: default;\n font-size: 12px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n padding: 6px 14px;\n}\n\n.pin-context-item.submenu-header:hover {\n background: transparent;\n}\n\n.pin-context-item.submenu-item {\n padding-left: 30px;\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n/* ========================================\n SLIDE-IN PANEL (Add Pin)\n ======================================== */\n.slide-panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 2000;\n}\n\n.slide-panel {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 400px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-xl);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.3s ease;\n}\n\n@keyframes slideIn {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.slide-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.slide-panel-header h3 {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n}\n\n.slide-panel-header h3 i {\n color: var(--mj-brand-primary);\n}\n\n.slide-panel-close {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.slide-panel-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Search box */\n.search-box {\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-input-wrapper {\n display: flex;\n align-items: center;\n gap: 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 8px 12px;\n transition: all var(--mj-transition-base);\n}\n\n.search-input-wrapper:focus-within {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-input-wrapper i {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.search-input-wrapper input {\n border: none;\n outline: none;\n background: transparent;\n font-size: 14px;\n color: var(--mj-text-primary);\n flex: 1;\n}\n\n.search-input-wrapper input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Group selector */\n.group-selector {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.group-selector label {\n font-weight: var(--mj-font-medium);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.group-selector select {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.new-group-input {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n/* Panel results */\n.panel-results {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.panel-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-section {\n margin-bottom: 20px;\n}\n\n/* Section header (title row + chevron) now owned by <mj-accordion-panel>. */\n\n/* Section count pill migrated to <mj-accordion-badge mj-accordion-badge--right>;\n bespoke .panel-count rule removed. */\n\n/* App hierarchy in panel */\n.panel-app-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px 6px 12px;\n margin-top: 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-app-header:first-child {\n margin-top: 0;\n}\n\n.panel-app-icon {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-app-icon i {\n font-size: 14px;\n color: var(--panel-app-color);\n}\n\n.panel-app-name {\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* Nav items under app \u2014 indented with left border accent */\n.panel-item.panel-nav-item {\n padding: 10px 12px 10px 32px;\n margin-left: 12px;\n border-left: 2px solid var(--mj-border-subtle);\n}\n\n.panel-item.panel-nav-item:last-of-type {\n border-left-color: transparent;\n}\n\n.panel-item.panel-nav-item:hover {\n border-left-color: var(--mj-brand-primary);\n}\n\n/* New group row */\n.new-group-row {\n padding: 0 20px 12px 20px;\n}\n\n.new-group-input {\n width: 100%;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n.panel-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: var(--mj-radius-md);\n transition: all var(--mj-transition-base);\n cursor: pointer;\n}\n\n.panel-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.panel-item-icon {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-item-icon i {\n font-size: 14px;\n}\n\n.panel-item-info {\n flex: 1;\n min-width: 0;\n}\n\n.panel-item-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-item-sub {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.panel-item-action {\n flex-shrink: 0;\n}\n\n.panel-item-action button {\n padding: 4px 12px;\n border-radius: var(--mj-radius-sm);\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.pin-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.pin-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pinned-badge {\n background: transparent;\n color: var(--mj-status-success);\n border: 1px solid var(--mj-status-success);\n cursor: default !important;\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: var(--mj-text-3xl);\n }\n\n /* Make sidebar an overlay on tablet */\n .quick-access-sidebar {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\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: absolute;\n top: 0;\n left: 0;\n right: 320px;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n }\n}\n\n/* Mobile */\n@media (max-width: 768px) {\n /* Keep the fixed-height + scroll contract on mobile (matches desktop and the\n shared <mj-page-layout>/<mj-page-body> primitives). Overriding to\n height:auto / overflow:visible breaks .main-content's flex:1 scroll inside\n the fixed-height shell, leaving the page non-scrollable. */\n .main-content {\n padding: 20px;\n padding-bottom: 100px; /* Space for FAB button */\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: var(--mj-text-2xl);\n }\n\n /* Full-width sidebar on mobile \u2014 fixed overlay covering full viewport */\n .quick-access-sidebar {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 10000;\n border-left: none;\n border-top: none;\n }\n\n /* No separate backdrop needed on mobile \u2014 sidebar covers full screen */\n .home-dashboard.sidebar-open::before {\n display: none;\n }\n\n /* No ::after backdrop needed on mobile */\n .home-dashboard.sidebar-open::after {\n display: none;\n }\n\n .pin-grid {\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: 12px;\n }\n\n .slide-panel {\n width: 100%;\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: var(--mj-text-lg);\n }\n\n .app-name {\n font-size: var(--mj-text-sm);\n }\n\n .nav-preview {\n display: none;\n }\n\n /* Move FAB to bottom-right on mobile \u2014 fixed so it stays visible while scrolling */\n .sidebar-fab-toggle {\n position: fixed;\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: var(--mj-text-lg);\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: var(--mj-text-xl);\n }\n\n .greeting-section .date {\n font-size: var(--mj-text-sm);\n }\n\n .section-title {\n font-size: var(--mj-text-base);\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: var(--mj-text-base);\n }\n}\n"] }]
3678
+ args: [{ standalone: false, selector: 'mj-home-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"home-dashboard\" [class.sidebar-open]=\"SidebarOpen && ShowQuickAccess\">\n <!-- Main Content Area -->\n <div class=\"main-content\">\n <!-- Overview: the greeting, Pinned and My applications in one centered column -->\n @if (ShowOverview) {\n <div class=\"home-overview\">\n <!-- Header Section -->\n <div class=\"home-header\">\n <div class=\"greeting-section\">\n <h1>{{ Greeting }}, {{ GreetingName }}</h1>\n <p class=\"date\">{{ FormattedDate }}</p>\n </div>\n </div>\n\n <!-- Pinned Section: collapses to its header (title, Add Pin / Dashboards / Edit, or Done) -->\n <mj-accordion-panel class=\"pinned-section\" [Bare]=\"true\" [TitleIconMuted]=\"true\" [HeadingLevel]=\"2\" [FlushBody]=\"true\"\n [Expanded]=\"PinnedExpanded\" (ExpandedChange)=\"OnPinnedExpandedChange($event)\">\n <ng-template mjAccordionTitle>\n <span class=\"pinned-title\"><i class=\"fa-solid fa-thumbtack\" aria-hidden=\"true\"></i> Pinned</span>\n </ng-template>\n <ng-template mjAccordionActions>\n <div class=\"pinned-actions\">\n @if (EditMode) {\n <button type=\"button\" mjButton Variant=\"success\" Size=\"sm\" (click)=\"ToggleEditMode()\">\n <i class=\"fa-solid fa-check\" aria-hidden=\"true\"></i> <span class=\"pin-action-label\">Done</span>\n </button>\n } @else {\n <button type=\"button\" mjButton Variant=\"primary\" Size=\"sm\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i> <span class=\"pin-action-label\">Add Pin</span>\n </button>\n <mj-home-dashboard-switcher Look=\"button\" Align=\"right\" Label=\"Dashboards\"\n [Dashboards]=\"PinnedDashboards\" [CurrentId]=\"null\"\n (Pick)=\"OnSwitcherPick($event)\" (New)=\"OpenNewDashboardDialog()\" (ManagePins)=\"ManagePins()\">\n </mj-home-dashboard-switcher>\n @if (PinnedItems.length > 0) {\n <button type=\"button\" mjButton Variant=\"secondary\" Size=\"sm\" (click)=\"ToggleEditMode()\">\n <i class=\"fa-solid fa-pen\" aria-hidden=\"true\"></i> <span class=\"pin-action-label\">Edit</span>\n </button>\n }\n }\n </div>\n </ng-template>\n <ng-template mjAccordionBody>\n <div class=\"pinned-body\">\n @if (EditMode) {\n <div class=\"edit-mode-banner\">\n <i class=\"fa-solid fa-arrows-up-down-left-right\"></i>\n <span><strong>Edit mode</strong> \u2014 Drag cards to reorder. Click names to rename.</span>\n </div>\n }\n\n <!-- Empty State -->\n @if (PinnedItems.length === 0 && (EditMode || !HidePinEmptyState)) {\n <div class=\"pin-empty-state\">\n @if (!EditMode) {\n <button type=\"button\" class=\"pin-empty-close\" (click)=\"DismissPinEmptyState()\" title=\"Hide this\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n <mj-empty-state Icon=\"fa-solid fa-thumbtack\"\n Title=\"No pinned items yet\"\n Message=\"Pin your favorite dashboards, views, queries, and reports for quick access.\">\n <button actions mjButton variant=\"primary\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\"></i> Add your first pin\n </button>\n @if (!EditMode && !HidePinEmptyState) {\n <button actions mjButton variant=\"flat\" (click)=\"DismissPinEmptyState()\">\n Don't show this again\n </button>\n }\n </mj-empty-state>\n </div>\n }\n\n <!-- Pin Grid: the ungrouped pins, then each group under its header, from one card markup -->\n @if (PinnedItems.length > 0) {\n <div class=\"pin-grid\">\n @for (section of PinSections; track section.Key) {\n @if (section.Group !== null) {\n <div class=\"group-header\">\n @if (EditMode && EditingGroupName === section.Group) {\n <input class=\"group-name-input\" [value]=\"section.Group\"\n (blur)=\"SaveGroupName(section.Group, GetInputValue($event))\"\n (keydown.enter)=\"SaveGroupName(section.Group, GetInputValue($event))\" />\n } @else {\n <span class=\"group-name\" (click)=\"EditMode ? StartEditingGroup(section.Group) : null\">{{ section.Group }}</span>\n }\n <div class=\"group-line\"></div>\n <span class=\"group-count\">{{ section.Pins.length }} pins</span>\n @if (EditMode) {\n <div class=\"group-edit-controls\">\n <button type=\"button\" class=\"group-edit-btn danger\" (click)=\"RemoveGroup(section.Group)\">\n <i class=\"fa-solid fa-folder-minus\" aria-hidden=\"true\"></i> Remove Group\n </button>\n </div>\n }\n </div>\n }\n @for (pin of section.Pins; track pin.Id) {\n <div class=\"pin-card\"\n [class.edit-mode]=\"EditMode\"\n [class.dragging]=\"DraggingPinId === pin.Id\"\n [class.drag-over]=\"DragOverPinId === pin.Id\"\n [class.menu-open]=\"PinMenuPin?.Id === pin.Id\"\n [draggable]=\"EditMode\"\n (dragstart)=\"OnDragStart($event, pin)\" (dragover)=\"OnDragOver($event, pin)\" (dragleave)=\"OnDragLeave()\"\n (drop)=\"OnDrop($event, pin)\" (dragend)=\"OnDragEnd()\"\n (click)=\"OnPinClick(pin)\">\n\n <!-- Edit mode controls -->\n @if (EditMode) {\n <div class=\"edit-controls\">\n <div class=\"drag-handle\"><i class=\"fa-solid fa-grip-vertical\" aria-hidden=\"true\"></i></div>\n <div class=\"edit-card-actions\">\n <button type=\"button\" class=\"edit-card-btn delete\" aria-label=\"Remove pin\" title=\"Remove pin\"\n (click)=\"RemovePin(pin.Id); $event.stopPropagation()\"><i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i></button>\n </div>\n </div>\n }\n\n <!-- Thumbnail: the pin's image, the action accent, or the brand icon tile -->\n @if (pin.Thumbnail) {\n <div class=\"pin-thumbnail\">\n <img [src]=\"pin.Thumbnail\" [alt]=\"PinName(pin)\" />\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button type=\"button\" mjButton Variant=\"secondary\" Size=\"sm\" [attr.aria-label]=\"'Open ' + PinName(pin)\"\n (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n } @else if (pin.ResourceType === 'Actions') {\n <div class=\"pin-thumbnail action-mode\"\n [style.background]=\"'linear-gradient(135deg, ' + GetPinAccentColor(pin) + ' 0%, ' + GetPinAccentColor(pin) + 'cc 100%)'\">\n <i [class]=\"GetPinIcon(pin)\" aria-hidden=\"true\"></i>\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button type=\"button\" mjButton Variant=\"secondary\" Size=\"sm\" [attr.aria-label]=\"'Run ' + PinName(pin)\"\n (click)=\"OnPinClick(pin); $event.stopPropagation()\">Run</button>\n </div>\n }\n </div>\n } @else {\n <div class=\"pin-thumbnail icon-mode\">\n <i [class]=\"GetPinIcon(pin)\" aria-hidden=\"true\"></i>\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button type=\"button\" mjButton Variant=\"secondary\" Size=\"sm\" [attr.aria-label]=\"'Open ' + PinName(pin)\"\n (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n }\n\n <!-- Pin Info: the name with the pin options button, and the kind line -->\n <div class=\"pin-info\">\n @if (EditMode && EditingPinId === pin.Id) {\n <input class=\"pin-name-input\" [value]=\"PinName(pin)\" [attr.aria-label]=\"'Name of ' + PinName(pin)\"\n (blur)=\"SavePinName(pin.Id, GetInputValue($event))\"\n (keydown.enter)=\"OnPinNameEnter(pin.Id, $event)\"\n (click)=\"$event.stopPropagation()\" />\n } @else {\n <div class=\"pin-name\" (click)=\"EditMode ? StartEditingPin(pin.Id, $event) : null\">\n <span class=\"pin-name-text\">{{ PinName(pin) }}</span>\n @if (!EditMode) {\n <button type=\"button\" class=\"more-btn\" [attr.aria-label]=\"'Pin options for ' + PinName(pin)\" title=\"Pin options\" aria-haspopup=\"menu\"\n [attr.aria-expanded]=\"PinMenuPin?.Id === pin.Id\" (click)=\"ShowPinMenu($event, pin)\">\n <i class=\"fa-solid fa-ellipsis\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n <div class=\"pin-meta\">\n @if (pin.ResourceType === 'Dashboards') {\n <i class=\"fa-solid fa-gauge-high\" aria-hidden=\"true\"></i>\n }\n <span class=\"pin-kind\">{{ GetResourceTypeLabel(pin) }}</span>\n </div>\n </div>\n </div>\n }\n }\n\n <!-- Add Pin card (edit mode) -->\n @if (EditMode) {\n <div class=\"add-pin-card\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n <span>Add Pin</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </mj-accordion-panel>\n\n <!-- My applications -->\n <section class=\"apps-section\">\n <h2 class=\"section-title\">My applications</h2>\n <div class=\"apps-grid\">\n @for (appData of AppsDisplayData; track TrackByApp($index, appData)) {\n <div class=\"app-card\" [mjClickable]=\"appData.app.Name\" [TestId]=\"'app-tile-' + appData.app.Name\"\n [style.--app-color]=\"appData.color\" (click)=\"OnAppClick(appData.app)\">\n <div class=\"app-icon\" aria-hidden=\"true\"><i [class]=\"appData.icon\"></i></div>\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 </div>\n </div>\n }\n </div>\n <!-- Empty State -->\n @if (Apps.length === 0) {\n <mj-empty-state Icon=\"fa-solid fa-folder-open\"\n Title=\"No Applications Available\"\n Message=\"You don't have any applications configured yet.\"\n ActionText=\"Configure Applications\"\n ActionIcon=\"fa-solid fa-gear\"\n (Action)=\"OpenConfigDialog()\" />\n }\n </section>\n </div>\n }\n\n <!-- Dashboard view: a pinned dashboard at full size in place of the overview, in the shared dashboard editor -->\n @if (ShowDashboardView && CurrentDashboardId) {\n <mj-dashboard-editor #dashboardEditor class=\"home-dashboard-view\"\n [Provider]=\"Provider\" [DashboardId]=\"CurrentDashboardId\"\n [(StartInEditMode)]=\"DashboardStartsInEditMode\"\n [TitleTemplate]=\"homeDashboardTitle\" [ShowOpenInDashboards]=\"true\" BodyStyle=\"card\"\n (Loaded)=\"OnDashboardViewLoaded($event)\"\n (EditingChange)=\"OnDashboardEditingChange($event)\" (NameChanged)=\"OnDashboardSaved()\" (Saved)=\"OnDashboardSaved()\"\n (LoadFailed)=\"OnDashboardViewLoadFailed()\"\n (OpenInDashboardsRequested)=\"OpenDashboardInDashboardsApp($event)\"\n (NavigationRequested)=\"OnDashboardNavigationRequested($event)\">\n </mj-dashboard-editor>\n }\n\n <!-- The dashboard view's title in view mode: the breadcrumb over the Dashboards switcher, whose trigger is the view's heading -->\n <ng-template #homeDashboardTitle let-dashboard>\n <div class=\"dashboard-title\">\n <nav class=\"dashboard-crumb\" aria-label=\"Breadcrumb\">\n <button type=\"button\" class=\"crumb-home\" (click)=\"OnSwitcherPick(null)\"><i class=\"fa-solid fa-house\" aria-hidden=\"true\"></i> Home</button>\n <span aria-hidden=\"true\">/</span>\n <span>Pinned dashboards</span>\n </nav>\n <mj-home-dashboard-switcher Look=\"title\" Align=\"left\" [HeadingLevel]=\"1\" [Label]=\"dashboard.Name\"\n [Dashboards]=\"PinnedDashboards\" [CurrentId]=\"dashboard.ID\"\n (Pick)=\"OnSwitcherPick($event)\" (New)=\"OpenNewDashboardDialog()\" (ManagePins)=\"ManagePins()\">\n </mj-home-dashboard-switcher>\n </div>\n </ng-template>\n\n <!-- Pin options menu (ellipsis): fixed next to its button (below it, or above it when there is no room below), outside the cards so it stacks above them -->\n @if (PinMenuVisible && PinMenuPin) {\n <div #pinMenu class=\"pin-context-menu\" role=\"menu\" [attr.aria-label]=\"'Options for ' + PinName(PinMenuPin)\"\n [style.left.px]=\"PinMenuX\" [style.top.px]=\"PinMenuY\" [style.max-height.px]=\"PinMenuMaxHeight\" (keydown)=\"OnPinMenuKeydown($event)\">\n <button type=\"button\" role=\"menuitem\" class=\"pin-context-item\" (click)=\"OnPinMenuEdit()\">\n <i class=\"fa-solid fa-pen\" aria-hidden=\"true\"></i><span>Edit</span>\n </button>\n <div class=\"pin-context-divider\" role=\"separator\"></div>\n <div role=\"group\" [attr.aria-labelledby]=\"PinMenuGroupLabelId\">\n <div class=\"pin-context-item submenu-header\" [id]=\"PinMenuGroupLabelId\"><i class=\"fa-solid fa-folder\" aria-hidden=\"true\"></i><span>Move to Group</span></div>\n @if (PinMenuPin.Group) {\n <button type=\"button\" role=\"menuitem\" class=\"pin-context-item submenu-item\" (click)=\"OnPinMenuMoveToGroup(undefined)\"><span>(No group)</span></button>\n }\n @for (group of PinGroups; track group) {\n @if (group !== PinMenuPin.Group) {\n <button type=\"button\" role=\"menuitem\" class=\"pin-context-item submenu-item\" (click)=\"OnPinMenuMoveToGroup(group)\"><span>{{ group }}</span></button>\n }\n }\n </div>\n <div class=\"pin-context-divider\" role=\"separator\"></div>\n <button type=\"button\" role=\"menuitem\" class=\"pin-context-item danger\" (click)=\"OnPinMenuUnpin()\">\n <i class=\"fa-solid fa-thumbtack-slash\" aria-hidden=\"true\"></i><span>Unpin</span>\n </button>\n </div>\n }\n\n <!-- Add Pin Slide-In Panel -->\n @if (AddPanelOpen) {\n <div class=\"slide-panel-backdrop\" (click)=\"CloseAddPinPanel()\"></div>\n <div class=\"slide-panel\">\n <div class=\"slide-panel-header\">\n <h3><i class=\"fa-solid fa-thumbtack\"></i> Add Pin</h3>\n <button class=\"slide-panel-close\" (click)=\"CloseAddPinPanel()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <div class=\"search-box\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <input type=\"text\"\n placeholder=\"Search apps, dashboards, views, queries...\"\n [(ngModel)]=\"AddPanelSearchQuery\" />\n </div>\n </div>\n\n <div class=\"group-selector\">\n <label><i class=\"fa-solid fa-folder\"></i> Add to group:</label>\n <select [(ngModel)]=\"AddPanelSelectedGroup\">\n <option value=\"\">(No group)</option>\n @for (group of PinGroups; track group) {\n <option [value]=\"group\">{{ group }}</option>\n }\n <option value=\"__new__\">+ New group...</option>\n </select>\n </div>\n @if (AddPanelSelectedGroup === '__new__') {\n <div class=\"new-group-row\">\n <input class=\"new-group-input\"\n type=\"text\"\n placeholder=\"Enter new group name...\"\n [(ngModel)]=\"AddPanelNewGroupName\" />\n </div>\n }\n\n <div class=\"panel-results\">\n @if (AddPanelLoading) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading resources...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <!-- Apps with Nav Items -->\n @if (FilterApps().length > 0) {\n <mj-accordion-panel class=\"panel-section\" Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!PanelSectionCollapsed['apps']\"\n (ExpandedChange)=\"OnPanelSectionExpandedChange('apps', $event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-grid-2\"></i> Applications\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ FilterApps().length }}</span>\n </ng-template>\n <ng-template mjAccordionBody>\n @for (app of FilterApps(); track app.appId) {\n <div class=\"panel-app-header\" [style.--panel-app-color]=\"app.color\">\n <div class=\"panel-app-icon\">\n <i [class]=\"app.icon\"></i>\n </div>\n <span class=\"panel-app-name\">{{ app.appName }}</span>\n </div>\n @for (ni of app.navItems; track ni.label) {\n <div class=\"panel-item panel-nav-item\">\n <div class=\"panel-item-icon\" [style.background]=\"'color-mix(in srgb, ' + app.color + ' 10%, var(--mj-bg-surface-card))'\">\n <i [class]=\"ni.icon\" [style.color]=\"app.color\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ ni.label }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (ni.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinAppNavItem(app.appName, app.icon, app.color, ni.label, ni.icon)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n }\n </ng-template>\n </mj-accordion-panel>\n }\n\n <!-- Dashboards (metadata-driven Config type only) -->\n @if (FilterPanelItems(AvailableDashboards).length > 0) {\n <mj-accordion-panel class=\"panel-section\" Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!PanelSectionCollapsed['dashboards']\"\n (ExpandedChange)=\"OnPanelSectionExpandedChange('dashboards', $event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-gauge-high\"></i> Dashboards\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ FilterPanelItems(AvailableDashboards).length }}</span>\n </ng-template>\n <ng-template mjAccordionBody>\n @for (item of FilterPanelItems(AvailableDashboards); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-gauge-high\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('Dashboards', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n </ng-template>\n </mj-accordion-panel>\n }\n\n <!-- Views -->\n @if (FilterPanelItems(AvailableViews).length > 0) {\n <mj-accordion-panel class=\"panel-section\" Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!PanelSectionCollapsed['views']\"\n (ExpandedChange)=\"OnPanelSectionExpandedChange('views', $event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-table-list\"></i> Views\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ FilterPanelItems(AvailableViews).length }}</span>\n </ng-template>\n <ng-template mjAccordionBody>\n @for (item of FilterPanelItems(AvailableViews); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-table-list\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n <div class=\"panel-item-sub\">{{ item.entityName }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('User Views', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n </ng-template>\n </mj-accordion-panel>\n }\n\n <!-- Queries -->\n @if (FilterPanelItems(AvailableQueries).length > 0) {\n <mj-accordion-panel class=\"panel-section\" Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!PanelSectionCollapsed['queries']\"\n (ExpandedChange)=\"OnPanelSectionExpandedChange('queries', $event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-database\"></i> Queries\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ FilterPanelItems(AvailableQueries).length }}</span>\n </ng-template>\n <ng-template mjAccordionBody>\n @for (item of FilterPanelItems(AvailableQueries); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-database\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('Queries', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n </ng-template>\n </mj-accordion-panel>\n }\n\n <!-- Quick Actions -->\n @if (FilterPanelItems(AvailableActions).length > 0) {\n <mj-accordion-panel class=\"panel-section\" Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!PanelSectionCollapsed['actions']\"\n (ExpandedChange)=\"OnPanelSectionExpandedChange('actions', $event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-bolt\"></i> Quick Actions\n <span class=\"mj-accordion-badge mj-accordion-badge--right\">{{ FilterPanelItems(AvailableActions).length }}</span>\n </ng-template>\n <ng-template mjAccordionBody>\n @for (item of FilterPanelItems(AvailableActions); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-bolt\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n @if (item.description) {\n <div class=\"panel-item-sub\">{{ item.description }}</div>\n }\n </div>\n <div class=\"panel-item-action\">\n <button class=\"pin-btn\" (click)=\"OpenActionPinConfig(item.id, item.name, item.description)\">\n <i class=\"fa-solid fa-sliders\"></i> Configure\n </button>\n </div>\n </div>\n }\n </ng-template>\n </mj-accordion-panel>\n }\n }\n </div>\n </div>\n }\n\n <!-- Action Pin Dialogs -->\n <mj-action-pin-config-dialog\n [Visible]=\"ActionConfigDialogVisible\"\n [ActionID]=\"ActionConfigActionId\"\n [ActionName]=\"ActionConfigActionName\"\n [ActionDescription]=\"ActionConfigActionDescription\"\n (Result)=\"OnActionConfigResult($event)\">\n </mj-action-pin-config-dialog>\n\n <mj-action-pin-runner-dialog\n [Visible]=\"ActionRunnerDialogVisible\"\n [Pin]=\"ActionRunnerPin\"\n (Result)=\"OnActionRunnerResult($event)\">\n </mj-action-pin-runner-dialog>\n\n <!-- New dashboard: asks for the name; Cancel creates nothing -->\n <mj-dashboard-name-dialog [Visible]=\"ShowNewDashboardDialog\" [MaxLength]=\"NewDashboardNameMaxLength\"\n [Processing]=\"IsCreatingDashboard\" (Confirmed)=\"OnNewDashboardNamed($event)\" (Cancelled)=\"OnNewDashboardCancelled()\">\n </mj-dashboard-name-dialog>\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 </div>\n\n <!-- Collapsible Right Sidebar (the overview only) -->\n @if (ShowQuickAccess) {\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 [mjClickable]=\"notification.Title\"\n testId=\"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 [mjClickable]=\"getFavoriteDisplayName(favorite)\"\n testId=\"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 [mjClickable]=\"item.recordName || item.recordId\"\n testId=\"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 <mj-empty-state class=\"sidebar-empty\" Size=\"compact\"\n Icon=\"fa-solid fa-inbox\"\n Title=\"No quick access items\" />\n }\n </div>\n </div>\n }\n\n <!-- Quick Access FAB Toggle (Fixed Button; the overview only) -->\n @if (ShowQuickAccess && !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: var(--mj-bg-page);\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 min-width: 0;\n overflow-y: auto;\n transition: margin-right var(--mj-transition-slow);\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/* The overview column: greeting, Pinned and My applications */\n.home-overview {\n width: 100%;\n max-width: 1180px;\n margin: 0 auto;\n padding: var(--mj-space-7) var(--mj-space-8) var(--mj-space-10);\n}\n\n/* Header: greeting */\n.home-header {\n display: flex;\n align-items: flex-end;\n gap: var(--mj-space-4);\n margin-bottom: var(--mj-space-6);\n}\n\n.greeting-section h1 {\n margin: 0;\n font-size: var(--mj-text-2xl);\n font-weight: var(--mj-font-bold);\n letter-spacing: var(--mj-tracking-tight);\n line-height: var(--mj-leading-tight);\n color: var(--mj-text-primary);\n}\n\n.greeting-section .date {\n margin: var(--mj-space-1) 0 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-muted);\n}\n\n/* ========================================\n DASHBOARD VIEW\n ======================================== */\n\n/* The dashboard view fills the page; the editor lays out its header and body. */\n.home-dashboard-view {\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n min-height: 520px;\n}\n\n/* View-mode title: breadcrumb over the title switcher */\n.dashboard-title {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.dashboard-crumb {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.crumb-home {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-link);\n cursor: pointer;\n}\n\n.crumb-home:hover {\n color: var(--mj-text-link-hover);\n}\n\n.crumb-home:focus-visible {\n outline: none;\n border-radius: var(--mj-radius-sm);\n box-shadow: var(--mj-focus-ring);\n}\n\n/* FAB Toggle Button for Quick Access - top-right on desktop */\n.sidebar-fab-toggle {\n position: absolute;\n top: 20px;\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xl);\n cursor: pointer;\n box-shadow: var(--mj-shadow-brand-md);\n transition: all var(--mj-transition-base);\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle:hover {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\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: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\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: var(--mj-text-muted);\n}\n\n.loading-spinner {\n font-size: var(--mj-text-4xl);\n color: var(--mj-brand-primary);\n}\n\n/* My applications */\n.apps-section {\n margin-bottom: var(--mj-space-8);\n}\n\n.section-title {\n margin: 0 0 var(--mj-space-3);\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-bold);\n color: var(--mj-text-primary);\n}\n\n.apps-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));\n gap: var(--mj-space-3);\n}\n\n/* App Card: an icon tile in the app's color, then the name and description */\n.app-card {\n --app-color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n padding: var(--mj-space-4);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition:\n border-color var(--mj-transition-fast),\n box-shadow var(--mj-transition-fast),\n transform var(--mj-transition-fast);\n}\n\n.app-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.app-card:focus-visible {\n outline: none;\n box-shadow: var(--mj-focus-ring);\n}\n\n.app-icon {\n flex: 0 0 36px;\n display: grid;\n place-items: center;\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n color: var(--app-color);\n font-size: 16px;\n}\n\n.app-info {\n flex: 1;\n min-width: 0;\n}\n\n.app-name {\n margin: 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.app-description {\n margin: 2px 0 0;\n font-size: var(--mj-text-xs);\n line-height: var(--mj-leading-snug);\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* ========================================\n RIGHT SIDEBAR\n ======================================== */\n.quick-access-sidebar {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform var(--mj-transition-slow);\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\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 var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.sidebar-header h3 {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header h3 i {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-sm);\n}\n\n.sidebar-close-btn {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\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: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title i {\n font-size: var(--mj-text-xs);\n}\n\n.notifications-section .sidebar-section-title i {\n color: var(--mj-color-warning-600);\n}\n\n.favorites-section .sidebar-section-title i {\n color: var(--mj-status-warning);\n}\n\n.recents-section .sidebar-section-title i {\n color: var(--mj-brand-primary);\n}\n\n.section-badge {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n padding: 2px 6px;\n border-radius: var(--mj-radius-md);\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: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-item:hover {\n background: var(--mj-bg-surface-hover);\n transform: translateX(4px);\n}\n\n.sidebar-item-icon {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\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: var(--mj-text-sm);\n color: var(--mj-text-muted);\n}\n\n.notification-item .sidebar-item-icon {\n background: var(--mj-color-warning-50);\n}\n\n.notification-item .sidebar-item-icon i {\n color: var(--mj-color-warning-600);\n}\n\n.favorite-item .sidebar-item-icon {\n background: var(--mj-color-warning-50);\n}\n\n.favorite-item .sidebar-item-icon i {\n color: var(--mj-color-warning-500);\n}\n\n.recent-item .sidebar-item-icon {\n background: var(--mj-color-info-50);\n}\n\n.recent-item .sidebar-item-icon i {\n color: var(--mj-brand-primary);\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: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\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: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n padding: 8px 0;\n}\n\n.sidebar-loading i {\n color: var(--mj-brand-primary);\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: var(--mj-text-disabled);\n}\n\n.sidebar-empty i {\n font-size: var(--mj-text-4xl);\n margin-bottom: 12px;\n}\n\n.sidebar-empty p {\n margin: 0;\n font-size: var(--mj-text-sm);\n}\n\n\n/* ========================================\n PINNED SECTION\n ======================================== */\n/* The section's accordion panel. The panel's header row holds the title, the actions and the chevron. */\n.pinned-section {\n display: block;\n margin-bottom: var(--mj-space-8);\n}\n\n/* Section title in the panel's toggle. It takes the toggle's text color, so the hover cue shows. */\n.pinned-title {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-bold);\n}\n\n.pinned-actions {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n}\n\n/* The accordion body is flush (FlushBody); the grid gets its top gap here */\n.pinned-body {\n padding-top: var(--mj-space-3);\n}\n\n/* Edit Mode Banner */\n.edit-mode-banner {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n border-radius: var(--mj-radius-lg);\n padding: 12px 20px;\n margin-bottom: 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.edit-mode-banner i {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-base);\n}\n\n.edit-mode-banner strong {\n color: var(--mj-brand-primary);\n}\n\n/* Pin Empty State */\n.pin-empty-state {\n position: relative;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n}\n\n.pin-empty-close {\n position: absolute;\n top: 10px;\n right: 10px;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: var(--mj-text-sm);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.pin-empty-close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n/* Pin Grid */\n.pin-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: var(--mj-space-4);\n margin-bottom: var(--mj-space-3);\n}\n\n/* Group Header */\n.group-header {\n grid-column: 1 / -1;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 0 4px 0;\n margin-top: 8px;\n}\n\n.group-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.group-line {\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.group-count {\n font-size: 11px;\n color: var(--mj-text-disabled);\n background: var(--mj-bg-surface-card);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.group-name-input {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 8px;\n background: var(--mj-bg-surface);\n outline: none;\n width: 160px;\n}\n\n.group-edit-controls {\n display: flex;\n gap: 6px;\n}\n\n.group-edit-btn {\n background: none;\n border: 1px solid transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n padding: 2px 8px;\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all var(--mj-transition-base);\n}\n\n.group-edit-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.group-edit-btn.danger:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n/* Pin Card */\n.pin-card {\n position: relative;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n cursor: pointer;\n transition:\n border-color var(--mj-transition-fast),\n box-shadow var(--mj-transition-fast),\n transform var(--mj-transition-fast);\n}\n\n.pin-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.pin-card.edit-mode {\n cursor: grab;\n}\n\n.pin-card.edit-mode:active {\n cursor: grabbing;\n}\n\n.pin-card.dragging {\n opacity: 0.5;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-lg);\n transform: rotate(2deg);\n}\n\n.pin-card.drag-over {\n border-color: var(--mj-brand-primary);\n border-style: dashed;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n/* Edit controls overlay */\n.edit-controls {\n position: absolute;\n top: 8px;\n left: 8px;\n right: 8px;\n display: flex;\n justify-content: space-between;\n z-index: 10;\n pointer-events: none;\n}\n\n.edit-controls > * {\n pointer-events: auto;\n}\n\n.drag-handle {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: grab;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.drag-handle:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-actions {\n display: flex;\n gap: 4px;\n}\n\n.edit-card-btn {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.edit-card-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-btn.delete:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n\n/* Pin Thumbnail */\n.pin-thumbnail {\n position: relative;\n width: 100%;\n aspect-ratio: 16 / 10;\n overflow: hidden;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.pin-thumbnail img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n/* Every pin but an action pin shows its icon on a brand-tinted tile */\n.pin-thumbnail.icon-mode {\n display: grid;\n place-items: center;\n}\n\n.pin-thumbnail.icon-mode > i {\n display: grid;\n place-items: center;\n width: 52px;\n height: 52px;\n border-radius: var(--mj-radius-md);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 22px;\n}\n\n/* Action pins keep their accent gradient (inline style) and white icon */\n.pin-thumbnail.action-mode {\n display: grid;\n place-items: center;\n background: var(--mj-brand-primary);\n}\n\n.pin-thumbnail.action-mode > i {\n font-size: 36px;\n color: var(--mj-text-inverse, white);\n}\n\n/* Hover overlay with the Open (or Run) button */\n.pin-overlay {\n position: absolute;\n inset: 0;\n display: grid;\n place-items: center;\n background: var(--mj-bg-overlay);\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--mj-transition-fast);\n}\n\n.pin-card:hover .pin-overlay,\n.pin-card:focus-within .pin-overlay {\n opacity: 1;\n pointer-events: auto;\n}\n\n/* Pin Info */\n.pin-info {\n padding: var(--mj-space-3);\n}\n\n.pin-name {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.pin-name-text {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.pin-name .more-btn {\n flex: none;\n display: inline-grid;\n place-items: center;\n width: 24px;\n height: 24px;\n margin: -4px -4px -4px 0;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-sm);\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: pointer;\n opacity: 0;\n transition:\n opacity var(--mj-transition-fast),\n background-color var(--mj-transition-fast),\n color var(--mj-transition-fast);\n}\n\n/* Shown on hover, on keyboard focus, and while its menu is open */\n.pin-card:hover .more-btn,\n.pin-card:focus-within .more-btn,\n.pin-card.menu-open .more-btn {\n opacity: 1;\n}\n\n.pin-name .more-btn:hover,\n.pin-card.menu-open .more-btn {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-name .more-btn:focus-visible {\n outline: none;\n box-shadow: var(--mj-focus-ring);\n}\n\n.pin-name-input {\n width: 100%;\n padding: 2px 6px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n outline: none;\n background: var(--mj-bg-surface);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n/* Kind line */\n.pin-meta {\n display: flex;\n align-items: center;\n gap: 5px;\n min-width: 0;\n margin-top: 2px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.pin-meta > i {\n font-size: 11px;\n}\n\n.pin-kind {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pin-card,\n .app-card {\n transition: none;\n }\n .pin-card:hover,\n .app-card:hover {\n transform: none;\n }\n}\n\n/* Add Pin Card */\n.add-pin-card {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 2px dashed var(--mj-border-default);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 180px;\n cursor: pointer;\n transition: all var(--mj-transition-base);\n gap: 8px;\n color: var(--mj-text-muted);\n}\n\n.add-pin-card:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-pin-card i {\n font-size: 28px;\n}\n\n.add-pin-card span {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n}\n\n/* ========================================\n PIN CONTEXT MENU (ELLIPSIS)\n ======================================== */\n/* Fixed next to its button and above the page chrome; the component limits its height to the room on that side */\n.pin-context-menu {\n position: fixed;\n z-index: 10001;\n width: 220px;\n overflow-y: auto;\n padding: 6px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n animation: pinMenuIn var(--mj-transition-fast);\n}\n\n@keyframes pinMenuIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.pin-context-item {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n width: 100%;\n padding: 8px 10px;\n border: 0;\n border-radius: var(--mj-radius-sm);\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n text-align: left;\n cursor: pointer;\n}\n\n.pin-context-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Keyboard focus: a ring drawn inside the row */\n.pin-context-item:focus-visible {\n outline: none;\n background: var(--mj-bg-surface-hover);\n box-shadow: inset 0 0 0 var(--mj-ring-width) var(--mj-focus-ring-color);\n}\n\n.pin-context-item i {\n width: 14px;\n text-align: center;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.pin-context-item.danger,\n.pin-context-item.danger i {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.submenu-header {\n padding-bottom: 4px;\n cursor: default;\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n}\n\n.pin-context-item.submenu-header:hover {\n background: transparent;\n}\n\n.pin-context-item.submenu-item {\n padding-left: 34px;\n}\n\n.pin-context-divider {\n height: 1px;\n margin: 6px 4px;\n background: var(--mj-border-default);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pin-context-menu { animation: none; }\n}\n\n/* ========================================\n SLIDE-IN PANEL (Add Pin)\n ======================================== */\n.slide-panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 2000;\n}\n\n.slide-panel {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 400px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-xl);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.3s ease;\n}\n\n@keyframes slideIn {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.slide-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.slide-panel-header h3 {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n}\n\n.slide-panel-header h3 i {\n color: var(--mj-brand-primary);\n}\n\n.slide-panel-close {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.slide-panel-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Search box */\n.search-box {\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-input-wrapper {\n display: flex;\n align-items: center;\n gap: 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 8px 12px;\n transition: all var(--mj-transition-base);\n}\n\n.search-input-wrapper:focus-within {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-input-wrapper i {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.search-input-wrapper input {\n border: none;\n outline: none;\n background: transparent;\n font-size: 14px;\n color: var(--mj-text-primary);\n flex: 1;\n}\n\n.search-input-wrapper input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Group selector */\n.group-selector {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.group-selector label {\n font-weight: var(--mj-font-medium);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.group-selector select {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.new-group-input {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n/* Panel results */\n.panel-results {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.panel-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-section {\n margin-bottom: 20px;\n}\n\n/* Section header (title row + chevron) now owned by <mj-accordion-panel>. */\n\n/* Section count pill migrated to <mj-accordion-badge mj-accordion-badge--right>;\n bespoke .panel-count rule removed. */\n\n/* App hierarchy in panel */\n.panel-app-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px 6px 12px;\n margin-top: 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-app-header:first-child {\n margin-top: 0;\n}\n\n.panel-app-icon {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-app-icon i {\n font-size: 14px;\n color: var(--panel-app-color);\n}\n\n.panel-app-name {\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* Nav items under app \u2014 indented with left border accent */\n.panel-item.panel-nav-item {\n padding: 10px 12px 10px 32px;\n margin-left: 12px;\n border-left: 2px solid var(--mj-border-subtle);\n}\n\n.panel-item.panel-nav-item:last-of-type {\n border-left-color: transparent;\n}\n\n.panel-item.panel-nav-item:hover {\n border-left-color: var(--mj-brand-primary);\n}\n\n/* New group row */\n.new-group-row {\n padding: 0 20px 12px 20px;\n}\n\n.new-group-input {\n width: 100%;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n.panel-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: var(--mj-radius-md);\n transition: all var(--mj-transition-base);\n cursor: pointer;\n}\n\n.panel-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.panel-item-icon {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-item-icon i {\n font-size: 14px;\n}\n\n.panel-item-info {\n flex: 1;\n min-width: 0;\n}\n\n.panel-item-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-item-sub {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.panel-item-action {\n flex-shrink: 0;\n}\n\n.panel-item-action button {\n padding: 4px 12px;\n border-radius: var(--mj-radius-sm);\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.pin-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.pin-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pinned-badge {\n background: transparent;\n color: var(--mj-status-success);\n border: 1px solid var(--mj-status-success);\n cursor: default !important;\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\n/* Tablet */\n@media (max-width: 992px) {\n /* Make sidebar an overlay on tablet */\n .quick-access-sidebar {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\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: absolute;\n top: 0;\n left: 0;\n right: 320px;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n }\n}\n\n/* Narrow screens: less page padding. The pin and app grids reflow on their own. */\n@media (max-width: 900px) {\n .home-overview {\n padding: var(--mj-space-5) var(--mj-space-4);\n }\n}\n\n/* Mobile */\n@media (max-width: 768px) {\n .home-overview {\n padding-bottom: 100px; /* Space for FAB button */\n }\n\n /* Full-width sidebar on mobile \u2014 fixed overlay covering full viewport */\n .quick-access-sidebar {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 10000;\n border-left: none;\n border-top: none;\n }\n\n /* No separate backdrop needed on mobile \u2014 sidebar covers full screen */\n .home-dashboard.sidebar-open::before {\n display: none;\n }\n\n /* No ::after backdrop needed on mobile */\n .home-dashboard.sidebar-open::after {\n display: none;\n }\n\n .pin-grid {\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: var(--mj-space-3);\n }\n\n .slide-panel {\n width: 100%;\n }\n\n /* Move FAB to bottom-right on mobile \u2014 fixed so it stays visible while scrolling */\n .sidebar-fab-toggle {\n position: fixed;\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: var(--mj-text-lg);\n }\n}\n\n@media (max-width: 480px) {\n .home-overview {\n padding-bottom: 80px;\n }\n\n .greeting-section h1 {\n font-size: var(--mj-text-xl);\n }\n\n .greeting-section .date {\n font-size: var(--mj-text-sm);\n }\n\n /* Pinned header: the title without its icon, and icon-only actions, so it fits on one row.\n The action labels stay in the accessibility tree, so each button keeps its name. */\n .pinned-title i {\n display: none;\n }\n\n .pinned-actions .pin-action-label {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n\n .sidebar-fab-toggle {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: var(--mj-text-base);\n }\n}\n"] }]
3004
3679
  }], () => [{ type: i1.ApplicationManager }, { type: i2.RecentAccessService }, { type: i0.ChangeDetectorRef }], { AppConfigDialog: [{
3005
3680
  type: ViewChild,
3006
3681
  args: ['appConfigDialog']
3682
+ }], pinMenuEl: [{
3683
+ type: ViewChild,
3684
+ args: ['pinMenu']
3685
+ }], dashboardEditor: [{
3686
+ type: ViewChild,
3687
+ args: ['dashboardEditor']
3007
3688
  }] }); })();
3008
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(HomeDashboardComponent, { className: "HomeDashboardComponent", filePath: "src/Home/home-dashboard.component.ts", lineNumber: 46 }); })();
3689
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(HomeDashboardComponent, { className: "HomeDashboardComponent", filePath: "src/Home/home-dashboard.component.ts", lineNumber: 98 }); })();
3690
+ function errorMessage(error) {
3691
+ return error instanceof Error ? error.message : String(error);
3692
+ }
3693
+ /** What a Home agent tool for a part of the overview says while a dashboard shows: the part shows on the overview only. */
3694
+ function overviewOnlyError(part) {
3695
+ return `${part} shows on the ${HOME_OVERVIEW_NAME} overview only. Use SwitchHomeDashboard with "${HOME_OVERVIEW_NAME}" first.`;
3696
+ }
3009
3697
  //# sourceMappingURL=home-dashboard.component.js.map