@memberjunction/ng-dashboards 5.10.1 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts +34 -2
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js +586 -223
  4. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  5. package/dist/AI/components/agents/agent-editor.component.js +2 -2
  6. package/dist/AI/components/agents/agent-filter-panel.component.d.ts +8 -0
  7. package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
  8. package/dist/AI/components/agents/agent-filter-panel.component.js +85 -52
  9. package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
  10. package/dist/AI/components/charts/performance-heatmap.component.d.ts +1 -0
  11. package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -1
  12. package/dist/AI/components/charts/performance-heatmap.component.js +27 -5
  13. package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
  14. package/dist/AI/components/charts/time-series-chart.component.d.ts +5 -0
  15. package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -1
  16. package/dist/AI/components/charts/time-series-chart.component.js +23 -8
  17. package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
  18. package/dist/AI/components/execution-monitoring.component.js +2 -2
  19. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  20. package/dist/AI/components/models/model-management.component.js +2 -2
  21. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +2 -2
  22. package/dist/AI/components/prompts/prompt-filter-panel.component.js +2 -2
  23. package/dist/AI/components/prompts/prompt-management.component.js +3 -3
  24. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  25. package/dist/AI/components/prompts/prompt-version-control.component.js +2 -2
  26. package/dist/AI/components/requests/agent-requests-resource.component.d.ts +83 -0
  27. package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -0
  28. package/dist/AI/components/requests/agent-requests-resource.component.js +547 -0
  29. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -0
  30. package/dist/AI/components/system/system-config-filter-panel.component.js +2 -2
  31. package/dist/AI/components/system/system-configuration.component.js +2 -2
  32. package/dist/AI/components/widgets/kpi-card.component.js +7 -7
  33. package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
  34. package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -1
  35. package/dist/AI/components/widgets/live-execution-widget.component.js +6 -6
  36. package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
  37. package/dist/AI/index.d.ts +1 -0
  38. package/dist/AI/index.d.ts.map +1 -1
  39. package/dist/AI/index.js +2 -0
  40. package/dist/AI/index.js.map +1 -1
  41. package/dist/APIKeys/api-applications-panel.component.js +3 -3
  42. package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
  43. package/dist/APIKeys/api-key-create-dialog.component.js +3 -3
  44. package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
  45. package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
  46. package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
  47. package/dist/APIKeys/api-key-list.component.js +3 -3
  48. package/dist/APIKeys/api-key-list.component.js.map +1 -1
  49. package/dist/APIKeys/api-keys-resource.component.js +1 -1
  50. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  51. package/dist/APIKeys/api-scopes-panel.component.js +2 -2
  52. package/dist/APIKeys/api-usage-panel.component.js +2 -2
  53. package/dist/Actions/components/actions-overview.component.js +2 -2
  54. package/dist/Actions/components/execution-monitoring.component.js +2 -2
  55. package/dist/Actions/components/explorer/action-breadcrumb.component.js +2 -2
  56. package/dist/Actions/components/explorer/action-card.component.js +2 -2
  57. package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
  58. package/dist/Actions/components/explorer/action-list-item.component.js +2 -2
  59. package/dist/Actions/components/explorer/action-toolbar.component.js +2 -2
  60. package/dist/Actions/components/explorer/action-tree-panel.component.js +2 -2
  61. package/dist/Actions/components/explorer/new-action-panel.component.js +2 -2
  62. package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
  63. package/dist/Actions/components/explorer/new-category-panel.component.js +2 -2
  64. package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
  65. package/dist/Communication/communication-dashboard.component.js +2 -2
  66. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  67. package/dist/Communication/communication-logs-resource.component.js +3 -3
  68. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  69. package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
  70. package/dist/Communication/communication-monitor-resource.component.js +5 -5
  71. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  72. package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
  73. package/dist/Communication/communication-providers-resource.component.js +3 -3
  74. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  75. package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
  76. package/dist/Communication/communication-runs-resource.component.js +3 -3
  77. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  78. package/dist/Communication/communication-templates-resource.component.js +2 -2
  79. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  80. package/dist/ComponentStudio/component-studio-dashboard.component.js +2 -2
  81. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +2 -2
  82. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +2 -2
  83. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +2 -2
  84. package/dist/ComponentStudio/components/browser/component-browser.component.js +2 -2
  85. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +2 -2
  86. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
  87. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +2 -2
  88. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
  89. package/dist/ComponentStudio/components/editors/requirements-editor.component.js +2 -2
  90. package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
  91. package/dist/ComponentStudio/components/editors/spec-editor.component.js +2 -2
  92. package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
  93. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +2 -2
  94. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +2 -2
  95. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
  96. package/dist/ComponentStudio/components/text-import-dialog.component.js +2 -2
  97. package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
  98. package/dist/ComponentStudio/components/workspace/component-preview.component.js +2 -2
  99. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +2 -2
  100. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
  101. package/dist/Credentials/components/credentials-audit-resource.component.js +9 -9
  102. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  103. package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
  104. package/dist/Credentials/components/credentials-categories-resource.component.js +11 -3
  105. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  106. package/dist/Credentials/components/credentials-list-resource.component.js +2 -2
  107. package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
  108. package/dist/Credentials/components/credentials-overview-resource.component.js +12 -11
  109. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  110. package/dist/Credentials/components/credentials-types-resource.component.js +9 -9
  111. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  112. package/dist/Credentials/credentials-dashboard.component.js +2 -2
  113. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +2 -2
  114. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +2 -2
  115. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
  116. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +2 -2
  117. package/dist/DataExplorer/components/view-selector/view-selector.component.js +2 -2
  118. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +6 -2
  119. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  120. package/dist/DataExplorer/data-explorer-dashboard.component.js +26 -8
  121. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  122. package/dist/Home/home-dashboard.component.js +2 -2
  123. package/dist/Integration/components/activity/activity.component.d.ts +1 -1
  124. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  125. package/dist/Integration/components/activity/activity.component.js +5 -5
  126. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  127. package/dist/Integration/components/connections/connections.component.d.ts +31 -2
  128. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  129. package/dist/Integration/components/connections/connections.component.js +753 -412
  130. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  131. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +3 -3
  132. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  133. package/dist/Integration/components/overview/overview.component.d.ts +0 -1
  134. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  135. package/dist/Integration/components/overview/overview.component.js +3 -6
  136. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  137. package/dist/Integration/components/pipelines/pipelines.component.js +3 -3
  138. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  139. package/dist/Integration/components/schedules/schedules.component.d.ts +20 -0
  140. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  141. package/dist/Integration/components/schedules/schedules.component.js +97 -5
  142. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  143. package/dist/Integration/components/visual-editor/visual-editor.component.js +2 -2
  144. package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -1
  145. package/dist/Integration/components/widgets/integration-card.component.js +5 -1
  146. package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
  147. package/dist/Integration/components/widgets/run-history-panel.component.js +2 -2
  148. package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
  149. package/dist/Integration/integration.module.d.ts +2 -1
  150. package/dist/Integration/integration.module.d.ts.map +1 -1
  151. package/dist/Integration/integration.module.js +7 -3
  152. package/dist/Integration/integration.module.js.map +1 -1
  153. package/dist/Integration/services/integration-data.service.d.ts +27 -2
  154. package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
  155. package/dist/Integration/services/integration-data.service.js +107 -4
  156. package/dist/Integration/services/integration-data.service.js.map +1 -1
  157. package/dist/Lists/components/lists-browse-resource.component.js +2 -2
  158. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  159. package/dist/Lists/components/lists-categories-resource.component.js +2 -2
  160. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  161. package/dist/Lists/components/lists-my-lists-resource.component.js +2 -2
  162. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  163. package/dist/Lists/components/lists-operations-resource.component.js +2 -2
  164. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  165. package/dist/Lists/components/venn-diagram/venn-diagram.component.js +3 -3
  166. package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
  167. package/dist/MCP/components/mcp-connection-dialog.component.js +2 -2
  168. package/dist/MCP/components/mcp-log-detail-panel.component.js +2 -2
  169. package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
  170. package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
  171. package/dist/MCP/components/mcp-test-tool-dialog.component.js +2 -2
  172. package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
  173. package/dist/MCP/mcp-dashboard.component.js +2 -2
  174. package/dist/MCP/mcp-filter-panel.component.js +2 -2
  175. package/dist/QueryBrowser/query-browser-resource.component.d.ts +55 -1
  176. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  177. package/dist/QueryBrowser/query-browser-resource.component.js +664 -199
  178. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  179. package/dist/Scheduling/components/index.d.ts +0 -1
  180. package/dist/Scheduling/components/index.d.ts.map +1 -1
  181. package/dist/Scheduling/components/index.js +0 -1
  182. package/dist/Scheduling/components/index.js.map +1 -1
  183. package/dist/Scheduling/components/scheduling-activity.component.js +2 -2
  184. package/dist/Scheduling/components/scheduling-jobs.component.d.ts +6 -9
  185. package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
  186. package/dist/Scheduling/components/scheduling-jobs.component.js +118 -110
  187. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  188. package/dist/Scheduling/components/scheduling-overview.component.js +3 -3
  189. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  190. package/dist/Scheduling/scheduling-dashboard.component.js +2 -2
  191. package/dist/SystemDiagnostics/system-diagnostics.component.js +4 -4
  192. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  193. package/dist/Testing/components/testing-analytics.component.js +2 -2
  194. package/dist/Testing/components/testing-analytics.component.js.map +1 -1
  195. package/dist/Testing/components/testing-dashboard-tab.component.js +4 -4
  196. package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
  197. package/dist/Testing/components/testing-explorer.component.js +2 -2
  198. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  199. package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
  200. package/dist/Testing/components/testing-review.component.js +5 -5
  201. package/dist/Testing/components/testing-review.component.js.map +1 -1
  202. package/dist/Testing/components/testing-runs.component.js +2 -2
  203. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  204. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +2 -2
  205. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
  206. package/dist/Testing/components/widgets/suite-tree.component.js +4 -4
  207. package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
  208. package/dist/Testing/components/widgets/test-run-detail-panel.component.js +2 -2
  209. package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
  210. package/dist/Testing/testing-dashboard.component.js +2 -2
  211. package/dist/VersionHistory/components/diff-resource.component.js +2 -2
  212. package/dist/VersionHistory/components/graph-resource.component.js +2 -2
  213. package/dist/VersionHistory/components/labels-resource.component.js +3 -3
  214. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  215. package/dist/VersionHistory/components/restore-resource.component.js +3 -3
  216. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  217. package/dist/__tests__/integration-data-service.test.js +1 -0
  218. package/dist/__tests__/integration-data-service.test.js.map +1 -1
  219. package/dist/module.d.ts +52 -49
  220. package/dist/module.d.ts.map +1 -1
  221. package/dist/module.js +25 -6
  222. package/dist/module.js.map +1 -1
  223. package/dist/public-api.d.ts +1 -1
  224. package/dist/public-api.d.ts.map +1 -1
  225. package/dist/public-api.js +1 -1
  226. package/dist/public-api.js.map +1 -1
  227. package/package.json +42 -40
  228. package/dist/Scheduling/components/job-slideout.component.d.ts +0 -45
  229. package/dist/Scheduling/components/job-slideout.component.d.ts.map +0 -1
  230. package/dist/Scheduling/components/job-slideout.component.js +0 -459
  231. package/dist/Scheduling/components/job-slideout.component.js.map +0 -1
@@ -535,11 +535,11 @@ export class DashboardShareDialogComponent {
535
535
  i0.ɵɵconditionalCreate(0, DashboardShareDialogComponent_Conditional_0_Template, 37, 17, "kendo-window", 0);
536
536
  } if (rf & 2) {
537
537
  i0.ɵɵconditional(ctx.Visible ? 0 : -1);
538
- } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.WindowComponent, i2.WindowTitleBarComponent, i2.WindowContainerDirective], styles: ["/* Dashboard Share Dialog - Compact Design */\n\n/* Window Styling - use specific class to override Kendo defaults */\n.mj-share-dialog-window.k-window {\n border-radius: 12px !important;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2) !important;\n overflow: hidden !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar {\n background: #3f51b5 !important;\n border: none !important;\n padding: 16px 20px !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-title {\n display: none !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-actions .k-button {\n background: rgba(255, 255, 255, 0.15) !important;\n border: none !important;\n color: #fff !important;\n border-radius: 4px !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-actions .k-button:hover {\n background: rgba(255, 255, 255, 0.25) !important;\n}\n\n.mj-share-dialog-window .k-window-content {\n padding: 0 !important;\n background: #fff !important;\n}\n\n/* Header */\n.share-dialog-header {\n display: flex;\n align-items: center;\n gap: 10px;\n color: #fff;\n font-size: 16px;\n font-weight: 500;\n}\n\n.share-dialog-header i {\n font-size: 18px;\n opacity: 0.9;\n}\n\n/* Body */\n.share-dialog-body {\n padding: 0;\n}\n\n/* Alert */\n.share-alert {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 20px;\n font-size: 13px;\n}\n\n.share-alert-error {\n background: #ffebee;\n color: #c62828;\n border-bottom: 1px solid #ffcdd2;\n}\n\n/* Sections */\n.share-section {\n padding: 16px 20px;\n}\n\n.share-section:not(:last-child) {\n border-bottom: 1px solid #e0e0e0;\n}\n\n.share-section-label {\n font-size: 11px;\n font-weight: 600;\n color: #757575;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n}\n\n/* Search Box */\n.share-search-box {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: #f5f5f5;\n border-radius: 8px;\n border: 1px solid transparent;\n transition: all 0.15s;\n}\n\n.share-search-box:focus-within {\n background: #fff;\n border-color: #3f51b5;\n box-shadow: 0 0 0 3px rgba(63, 81, 181, 0.1);\n}\n\n.share-search-box i {\n color: #9e9e9e;\n font-size: 14px;\n}\n\n.share-search-box input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n outline: none;\n}\n\n.share-search-box input::placeholder {\n color: #9e9e9e;\n}\n\n/* User Dropdown */\n.share-user-dropdown {\n margin-top: 8px;\n max-height: 180px;\n overflow-y: auto;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n background: #fafafa;\n}\n\n.share-user-option {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 12px;\n border: none;\n background: transparent;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.share-user-option:hover {\n background: rgba(63, 81, 181, 0.08);\n}\n\n.share-user-option:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-user-option .share-user-name {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: #212121;\n}\n\n.share-user-option .share-user-email {\n font-size: 12px;\n color: #757575;\n margin-right: auto;\n}\n\n.share-user-option i.fa-plus {\n color: #3f51b5;\n font-size: 12px;\n opacity: 0;\n transition: opacity 0.1s;\n}\n\n.share-user-option:hover i.fa-plus {\n opacity: 1;\n}\n\n.share-no-results {\n padding: 16px;\n text-align: center;\n color: #757575;\n font-size: 13px;\n}\n\n/* Avatar */\n.share-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(135deg, #5c6bc0, #3f51b5);\n color: #fff;\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.share-avatar-owner {\n background: linear-gradient(135deg, #ffc107, #ff9800);\n font-size: 14px;\n}\n\n.share-avatar-removed {\n background: #bdbdbd;\n}\n\n/* Person Row */\n.share-person {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n\n.share-person:not(:last-child) {\n border-bottom: 1px solid #f0f0f0;\n}\n\n.share-person-new {\n background: rgba(76, 175, 80, 0.05);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-modified {\n background: rgba(33, 150, 243, 0.05);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-info {\n flex: 1;\n min-width: 0;\n}\n\n.share-person-name {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #212121;\n}\n\n.share-person-email {\n font-size: 12px;\n color: #757575;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.share-person-role {\n font-size: 12px;\n color: #ff9800;\n font-weight: 500;\n}\n\n.share-badge-new {\n padding: 2px 6px;\n background: #4caf50;\n color: #fff;\n font-size: 10px;\n font-weight: 600;\n border-radius: 4px;\n}\n\n/* Permissions */\n.share-permissions {\n display: flex;\n gap: 4px;\n}\n\n.share-perm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.1s;\n position: relative;\n}\n\n.share-perm input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n}\n\n.share-perm i {\n font-size: 12px;\n color: #bdbdbd;\n transition: color 0.1s;\n}\n\n.share-perm:hover {\n background: #f0f0f0;\n}\n\n.share-perm input:checked + i {\n color: #3f51b5;\n}\n\n.share-perm input:disabled + i {\n color: #3f51b5;\n opacity: 0.7;\n}\n\n/* Remove Button */\n.share-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: #bdbdbd;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.1s;\n}\n\n.share-remove-btn:hover {\n background: #ffebee;\n color: #f44336;\n}\n\n/* Empty State */\n.share-empty {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 20px;\n color: #9e9e9e;\n font-size: 13px;\n background: #fafafa;\n border-radius: 8px;\n justify-content: center;\n}\n\n.share-empty i {\n font-size: 16px;\n}\n\n/* Removed Section */\n.share-removed-section {\n margin-top: 12px;\n padding: 12px;\n background: #fff3e0;\n border-radius: 8px;\n border: 1px solid #ffe0b2;\n}\n\n.share-removed-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n}\n\n.share-removed-name {\n flex: 1;\n font-size: 13px;\n color: #757575;\n text-decoration: line-through;\n}\n\n.share-undo-btn {\n padding: 4px 10px;\n border: none;\n background: transparent;\n color: #f57c00;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.share-undo-btn:hover {\n text-decoration: underline;\n}\n\n/* Footer */\n.share-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: #fafafa;\n border-top: 1px solid #e0e0e0;\n}\n\n.share-changes-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: #3f51b5;\n}\n\n.share-changes-hint i {\n font-size: 6px;\n}\n\n.share-footer-actions {\n display: flex;\n gap: 10px;\n margin-left: auto;\n}\n\n.share-btn {\n padding: 8px 18px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.share-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-btn-secondary {\n background: #fff;\n border: 1px solid #d0d0d0;\n color: #666;\n}\n\n.share-btn-secondary:hover:not(:disabled) {\n background: #f5f5f5;\n border-color: #bdbdbd;\n}\n\n.share-btn-primary {\n background: #3f51b5;\n border: none;\n color: #fff;\n}\n\n.share-btn-primary:hover:not(:disabled) {\n background: #303f9f;\n box-shadow: 0 2px 8px rgba(63, 81, 181, 0.3);\n}\n\n/* Owner row specific styling */\n.share-owner {\n background: linear-gradient(135deg, #fff8e1, #ffecb3);\n margin: 0 -20px;\n padding: 10px 20px;\n border-radius: 0;\n}\n"], encapsulation: 2 });
538
+ } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.WindowComponent, i2.WindowTitleBarComponent, i2.WindowContainerDirective], styles: ["/* Dashboard Share Dialog - Compact Design */\n\n/* Window Styling - use specific class to override Kendo defaults */\n.mj-share-dialog-window.k-window {\n border-radius: 12px !important;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2) !important;\n overflow: hidden !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar {\n background: var(--mj-brand-primary) !important;\n border: none !important;\n padding: 16px 20px !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-title {\n display: none !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-actions .k-button {\n background: color-mix(in srgb, var(--mj-bg-surface) 15%, transparent) !important;\n border: none !important;\n color: var(--mj-text-inverse) !important;\n border-radius: 4px !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-actions .k-button:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 25%, transparent) !important;\n}\n\n.mj-share-dialog-window .k-window-content {\n padding: 0 !important;\n background: var(--mj-bg-surface) !important;\n}\n\n/* Header */\n.share-dialog-header {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n font-weight: 500;\n}\n\n.share-dialog-header i {\n font-size: 18px;\n opacity: 0.9;\n}\n\n/* Body */\n.share-dialog-body {\n padding: 0;\n}\n\n/* Alert */\n.share-alert {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 20px;\n font-size: 13px;\n}\n\n.share-alert-error {\n background: var(--mj-bg-error);\n color: var(--mj-status-error);\n border-bottom: 1px solid var(--mj-border-error);\n}\n\n/* Sections */\n.share-section {\n padding: 16px 20px;\n}\n\n.share-section:not(:last-child) {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.share-section-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n}\n\n/* Search Box */\n.share-search-box {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid transparent;\n transition: all 0.15s;\n}\n\n.share-search-box:focus-within {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.share-search-box i {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.share-search-box input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n outline: none;\n}\n\n.share-search-box input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* User Dropdown */\n.share-user-dropdown {\n margin-top: 8px;\n max-height: 180px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n}\n\n/* User Option */\n.share-user-option {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 12px;\n border: none;\n background: transparent;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.share-user-option:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.share-user-option:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-user-option .share-user-name {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-user-option .share-user-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-right: auto;\n}\n\n.share-user-option i.fa-plus {\n color: var(--mj-brand-primary);\n font-size: 12px;\n opacity: 0;\n transition: opacity 0.1s;\n}\n\n.share-user-option:hover i.fa-plus {\n opacity: 1;\n}\n\n.share-no-results {\n padding: 16px;\n text-align: center;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n/* Avatar */\n.share-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.share-avatar-owner {\n background: var(--mj-status-warning);\n font-size: 14px;\n}\n\n.share-avatar-removed {\n background: var(--mj-border-strong);\n}\n\n/* Person Row */\n.share-person {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n\n.share-person:not(:last-child) {\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.share-person-new {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-modified {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-info {\n flex: 1;\n min-width: 0;\n}\n\n.share-person-name {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-person-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.share-person-role {\n font-size: 12px;\n color: var(--mj-status-warning);\n font-weight: 500;\n}\n\n.share-badge-new {\n padding: 2px 6px;\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 4px;\n}\n\n/* Permissions */\n.share-permissions {\n display: flex;\n gap: 4px;\n}\n\n.share-perm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.1s;\n position: relative;\n}\n\n.share-perm input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n}\n\n.share-perm i {\n font-size: 12px;\n color: var(--mj-border-strong);\n transition: color 0.1s;\n}\n\n.share-perm:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.share-perm input:checked + i {\n color: var(--mj-brand-primary);\n}\n\n.share-perm input:disabled + i {\n color: var(--mj-brand-primary);\n opacity: 0.7;\n}\n\n/* Remove Button */\n.share-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.1s;\n}\n\n.share-remove-btn:hover {\n background: var(--mj-bg-error);\n color: var(--mj-status-error);\n}\n\n/* Empty State */\n.share-empty {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 20px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n justify-content: center;\n}\n\n.share-empty i {\n font-size: 16px;\n}\n\n/* Removed Section */\n.share-removed-section {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-warning);\n border-radius: 8px;\n border: 1px solid var(--mj-border-warning);\n}\n\n.share-removed-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n}\n\n.share-removed-name {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n text-decoration: line-through;\n}\n\n.share-undo-btn {\n padding: 4px 10px;\n border: none;\n background: transparent;\n color: var(--mj-status-warning);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.share-undo-btn:hover {\n text-decoration: underline;\n}\n\n/* Footer */\n.share-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.share-changes-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-brand-primary);\n}\n\n.share-changes-hint i {\n font-size: 6px;\n}\n\n.share-footer-actions {\n display: flex;\n gap: 10px;\n margin-left: auto;\n}\n\n.share-btn {\n padding: 8px 18px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.share-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-btn-secondary {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.share-btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n.share-btn-primary {\n background: var(--mj-brand-primary);\n border: none;\n color: var(--mj-text-inverse);\n}\n\n.share-btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Owner row specific styling */\n.share-owner {\n background: var(--mj-bg-warning);\n margin: 0 -20px;\n padding: 10px 20px;\n border-radius: 0;\n}\n"], encapsulation: 2 });
539
539
  }
540
540
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DashboardShareDialogComponent, [{
541
541
  type: Component,
542
- args: [{ standalone: false, selector: 'mj-dashboard-share-dialog', encapsulation: ViewEncapsulation.None, template: "@if (Visible) {\n <kendo-window\n [width]=\"560\"\n [minHeight]=\"200\"\n [resizable]=\"false\"\n [draggable]=\"true\"\n [keepContent]=\"true\"\n (close)=\"onCancel()\"\n class=\"mj-share-dialog-window\"\n kendoWindowContainer>\n <kendo-window-titlebar>\n <div class=\"share-dialog-header\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n <span>Share \"{{ Dashboard?.Name }}\"</span>\n </div>\n </kendo-window-titlebar>\n <div class=\"share-dialog-body\">\n <!-- Error Alert -->\n @if (Error) {\n <div class=\"share-alert share-alert-error\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ Error }}</span>\n </div>\n }\n <!-- Add Users Section -->\n <div class=\"share-section\">\n <div class=\"share-search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Add people by name or email...\"\n [(ngModel)]=\"UserSearchFilter\"\n [disabled]=\"IsLoading\">\n </div>\n <!-- Available Users Dropdown -->\n @if (FilteredAvailableUsers.length > 0) {\n <div class=\"share-user-dropdown\">\n @for (user of FilteredAvailableUsers; track user.ID) {\n <button type=\"button\" class=\"share-user-option\" (click)=\"addUserShare(user)\" [disabled]=\"IsLoading\">\n <span class=\"share-avatar\">{{ getUserInitials(user) }}</span>\n <span class=\"share-user-name\">{{ user.Name }}</span>\n @if (user.Email) {\n <span class=\"share-user-email\">{{ user.Email }}</span>\n }\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n </div>\n }\n @if (UserSearchFilter && FilteredAvailableUsers.length === 0) {\n <div class=\"share-no-results\">\n No users found matching \"{{ UserSearchFilter }}\"\n </div>\n }\n </div>\n <!-- People with Access -->\n <div class=\"share-section\">\n <div class=\"share-section-label\">People with access</div>\n <!-- Owner -->\n <div class=\"share-person share-owner\">\n <span class=\"share-avatar share-avatar-owner\">\n <i class=\"fa-solid fa-crown\"></i>\n </span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">{{ Dashboard?.User || 'You' }}</span>\n <span class=\"share-person-role\">Owner</span>\n </div>\n </div>\n <!-- Shared Users -->\n @for (share of ActiveShares; track share.User.ID) {\n <div class=\"share-person\" [class.share-person-new]=\"share.IsNew\" [class.share-person-modified]=\"share.Permission.Dirty\">\n <span class=\"share-avatar\">{{ getUserInitials(share.User) }}</span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">\n {{ share.User.Name }}\n @if (share.IsNew) {\n <span class=\"share-badge-new\">New</span>\n }\n </span>\n @if (share.User.Email) {\n <span class=\"share-person-email\">{{ share.User.Email }}</span>\n }\n </div>\n <div class=\"share-permissions\">\n <label class=\"share-perm\" title=\"Can view\">\n <input type=\"checkbox\" [checked]=\"share.Permission.CanRead\" disabled>\n <i class=\"fa-solid fa-eye\"></i>\n </label>\n <label class=\"share-perm\" title=\"Can edit\">\n <input type=\"checkbox\" [checked]=\"share.Permission.CanEdit\" (change)=\"toggleCanEdit(share)\">\n <i class=\"fa-solid fa-edit\"></i>\n </label>\n <label class=\"share-perm\" title=\"Can delete\">\n <input type=\"checkbox\" [checked]=\"share.Permission.CanDelete\" (change)=\"toggleCanDelete(share)\">\n <i class=\"fa-solid fa-trash\"></i>\n </label>\n <label class=\"share-perm\" title=\"Can share\">\n <input type=\"checkbox\" [checked]=\"share.Permission.CanShare\" (change)=\"toggleCanShare(share)\">\n <i class=\"fa-solid fa-share\"></i>\n </label>\n </div>\n <button type=\"button\" class=\"share-remove-btn\" (click)=\"removeUserShare(share)\" title=\"Remove\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n @if (ActiveShares.length === 0) {\n <div class=\"share-empty\">\n <i class=\"fa-solid fa-user-lock\"></i>\n <span>Not shared with anyone yet</span>\n </div>\n }\n <!-- Pending Removals -->\n @if (RemovedShares.length > 0) {\n <div class=\"share-removed-section\">\n @for (share of RemovedShares; track share.User.ID) {\n <div class=\"share-removed-item\">\n <span class=\"share-avatar share-avatar-removed\">{{ getUserInitials(share.User) }}</span>\n <span class=\"share-removed-name\">{{ share.User.Name }}</span>\n <button type=\"button\" class=\"share-undo-btn\" (click)=\"undoRemove(share)\">\n <i class=\"fa-solid fa-undo\"></i> Undo\n </button>\n </div>\n }\n </div>\n }\n </div>\n <!-- Footer -->\n <div class=\"share-footer\">\n @if (HasChanges) {\n <span class=\"share-changes-hint\">\n <i class=\"fa-solid fa-circle\"></i> Unsaved changes\n </span>\n }\n <div class=\"share-footer-actions\">\n <button type=\"button\" class=\"share-btn share-btn-secondary\" (click)=\"onCancel()\">\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"share-btn share-btn-primary\"\n (click)=\"onSave()\"\n [disabled]=\"!HasChanges || IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n Save\n }\n </button>\n </div>\n </div>\n </div>\n </kendo-window>\n}\n", styles: ["/* Dashboard Share Dialog - Compact Design */\n\n/* Window Styling - use specific class to override Kendo defaults */\n.mj-share-dialog-window.k-window {\n border-radius: 12px !important;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2) !important;\n overflow: hidden !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar {\n background: #3f51b5 !important;\n border: none !important;\n padding: 16px 20px !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-title {\n display: none !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-actions .k-button {\n background: rgba(255, 255, 255, 0.15) !important;\n border: none !important;\n color: #fff !important;\n border-radius: 4px !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-actions .k-button:hover {\n background: rgba(255, 255, 255, 0.25) !important;\n}\n\n.mj-share-dialog-window .k-window-content {\n padding: 0 !important;\n background: #fff !important;\n}\n\n/* Header */\n.share-dialog-header {\n display: flex;\n align-items: center;\n gap: 10px;\n color: #fff;\n font-size: 16px;\n font-weight: 500;\n}\n\n.share-dialog-header i {\n font-size: 18px;\n opacity: 0.9;\n}\n\n/* Body */\n.share-dialog-body {\n padding: 0;\n}\n\n/* Alert */\n.share-alert {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 20px;\n font-size: 13px;\n}\n\n.share-alert-error {\n background: #ffebee;\n color: #c62828;\n border-bottom: 1px solid #ffcdd2;\n}\n\n/* Sections */\n.share-section {\n padding: 16px 20px;\n}\n\n.share-section:not(:last-child) {\n border-bottom: 1px solid #e0e0e0;\n}\n\n.share-section-label {\n font-size: 11px;\n font-weight: 600;\n color: #757575;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n}\n\n/* Search Box */\n.share-search-box {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: #f5f5f5;\n border-radius: 8px;\n border: 1px solid transparent;\n transition: all 0.15s;\n}\n\n.share-search-box:focus-within {\n background: #fff;\n border-color: #3f51b5;\n box-shadow: 0 0 0 3px rgba(63, 81, 181, 0.1);\n}\n\n.share-search-box i {\n color: #9e9e9e;\n font-size: 14px;\n}\n\n.share-search-box input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n outline: none;\n}\n\n.share-search-box input::placeholder {\n color: #9e9e9e;\n}\n\n/* User Dropdown */\n.share-user-dropdown {\n margin-top: 8px;\n max-height: 180px;\n overflow-y: auto;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n background: #fafafa;\n}\n\n.share-user-option {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 12px;\n border: none;\n background: transparent;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.share-user-option:hover {\n background: rgba(63, 81, 181, 0.08);\n}\n\n.share-user-option:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-user-option .share-user-name {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: #212121;\n}\n\n.share-user-option .share-user-email {\n font-size: 12px;\n color: #757575;\n margin-right: auto;\n}\n\n.share-user-option i.fa-plus {\n color: #3f51b5;\n font-size: 12px;\n opacity: 0;\n transition: opacity 0.1s;\n}\n\n.share-user-option:hover i.fa-plus {\n opacity: 1;\n}\n\n.share-no-results {\n padding: 16px;\n text-align: center;\n color: #757575;\n font-size: 13px;\n}\n\n/* Avatar */\n.share-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(135deg, #5c6bc0, #3f51b5);\n color: #fff;\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.share-avatar-owner {\n background: linear-gradient(135deg, #ffc107, #ff9800);\n font-size: 14px;\n}\n\n.share-avatar-removed {\n background: #bdbdbd;\n}\n\n/* Person Row */\n.share-person {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n\n.share-person:not(:last-child) {\n border-bottom: 1px solid #f0f0f0;\n}\n\n.share-person-new {\n background: rgba(76, 175, 80, 0.05);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-modified {\n background: rgba(33, 150, 243, 0.05);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-info {\n flex: 1;\n min-width: 0;\n}\n\n.share-person-name {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #212121;\n}\n\n.share-person-email {\n font-size: 12px;\n color: #757575;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.share-person-role {\n font-size: 12px;\n color: #ff9800;\n font-weight: 500;\n}\n\n.share-badge-new {\n padding: 2px 6px;\n background: #4caf50;\n color: #fff;\n font-size: 10px;\n font-weight: 600;\n border-radius: 4px;\n}\n\n/* Permissions */\n.share-permissions {\n display: flex;\n gap: 4px;\n}\n\n.share-perm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.1s;\n position: relative;\n}\n\n.share-perm input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n}\n\n.share-perm i {\n font-size: 12px;\n color: #bdbdbd;\n transition: color 0.1s;\n}\n\n.share-perm:hover {\n background: #f0f0f0;\n}\n\n.share-perm input:checked + i {\n color: #3f51b5;\n}\n\n.share-perm input:disabled + i {\n color: #3f51b5;\n opacity: 0.7;\n}\n\n/* Remove Button */\n.share-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: #bdbdbd;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.1s;\n}\n\n.share-remove-btn:hover {\n background: #ffebee;\n color: #f44336;\n}\n\n/* Empty State */\n.share-empty {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 20px;\n color: #9e9e9e;\n font-size: 13px;\n background: #fafafa;\n border-radius: 8px;\n justify-content: center;\n}\n\n.share-empty i {\n font-size: 16px;\n}\n\n/* Removed Section */\n.share-removed-section {\n margin-top: 12px;\n padding: 12px;\n background: #fff3e0;\n border-radius: 8px;\n border: 1px solid #ffe0b2;\n}\n\n.share-removed-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n}\n\n.share-removed-name {\n flex: 1;\n font-size: 13px;\n color: #757575;\n text-decoration: line-through;\n}\n\n.share-undo-btn {\n padding: 4px 10px;\n border: none;\n background: transparent;\n color: #f57c00;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.share-undo-btn:hover {\n text-decoration: underline;\n}\n\n/* Footer */\n.share-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: #fafafa;\n border-top: 1px solid #e0e0e0;\n}\n\n.share-changes-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: #3f51b5;\n}\n\n.share-changes-hint i {\n font-size: 6px;\n}\n\n.share-footer-actions {\n display: flex;\n gap: 10px;\n margin-left: auto;\n}\n\n.share-btn {\n padding: 8px 18px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.share-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-btn-secondary {\n background: #fff;\n border: 1px solid #d0d0d0;\n color: #666;\n}\n\n.share-btn-secondary:hover:not(:disabled) {\n background: #f5f5f5;\n border-color: #bdbdbd;\n}\n\n.share-btn-primary {\n background: #3f51b5;\n border: none;\n color: #fff;\n}\n\n.share-btn-primary:hover:not(:disabled) {\n background: #303f9f;\n box-shadow: 0 2px 8px rgba(63, 81, 181, 0.3);\n}\n\n/* Owner row specific styling */\n.share-owner {\n background: linear-gradient(135deg, #fff8e1, #ffecb3);\n margin: 0 -20px;\n padding: 10px 20px;\n border-radius: 0;\n}\n"] }]
542
+ args: [{ standalone: false, selector: 'mj-dashboard-share-dialog', encapsulation: ViewEncapsulation.None, template: "@if (Visible) {\n <kendo-window\n [width]=\"560\"\n [minHeight]=\"200\"\n [resizable]=\"false\"\n [draggable]=\"true\"\n [keepContent]=\"true\"\n (close)=\"onCancel()\"\n class=\"mj-share-dialog-window\"\n kendoWindowContainer>\n <kendo-window-titlebar>\n <div class=\"share-dialog-header\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n <span>Share \"{{ Dashboard?.Name }}\"</span>\n </div>\n </kendo-window-titlebar>\n <div class=\"share-dialog-body\">\n <!-- Error Alert -->\n @if (Error) {\n <div class=\"share-alert share-alert-error\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ Error }}</span>\n </div>\n }\n <!-- Add Users Section -->\n <div class=\"share-section\">\n <div class=\"share-search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Add people by name or email...\"\n [(ngModel)]=\"UserSearchFilter\"\n [disabled]=\"IsLoading\">\n </div>\n <!-- Available Users Dropdown -->\n @if (FilteredAvailableUsers.length > 0) {\n <div class=\"share-user-dropdown\">\n @for (user of FilteredAvailableUsers; track user.ID) {\n <button type=\"button\" class=\"share-user-option\" (click)=\"addUserShare(user)\" [disabled]=\"IsLoading\">\n <span class=\"share-avatar\">{{ getUserInitials(user) }}</span>\n <span class=\"share-user-name\">{{ user.Name }}</span>\n @if (user.Email) {\n <span class=\"share-user-email\">{{ user.Email }}</span>\n }\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n }\n </div>\n }\n @if (UserSearchFilter && FilteredAvailableUsers.length === 0) {\n <div class=\"share-no-results\">\n No users found matching \"{{ UserSearchFilter }}\"\n </div>\n }\n </div>\n <!-- People with Access -->\n <div class=\"share-section\">\n <div class=\"share-section-label\">People with access</div>\n <!-- Owner -->\n <div class=\"share-person share-owner\">\n <span class=\"share-avatar share-avatar-owner\">\n <i class=\"fa-solid fa-crown\"></i>\n </span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">{{ Dashboard?.User || 'You' }}</span>\n <span class=\"share-person-role\">Owner</span>\n </div>\n </div>\n <!-- Shared Users -->\n @for (share of ActiveShares; track share.User.ID) {\n <div class=\"share-person\" [class.share-person-new]=\"share.IsNew\" [class.share-person-modified]=\"share.Permission.Dirty\">\n <span class=\"share-avatar\">{{ getUserInitials(share.User) }}</span>\n <div class=\"share-person-info\">\n <span class=\"share-person-name\">\n {{ share.User.Name }}\n @if (share.IsNew) {\n <span class=\"share-badge-new\">New</span>\n }\n </span>\n @if (share.User.Email) {\n <span class=\"share-person-email\">{{ share.User.Email }}</span>\n }\n </div>\n <div class=\"share-permissions\">\n <label class=\"share-perm\" title=\"Can view\">\n <input type=\"checkbox\" [checked]=\"share.Permission.CanRead\" disabled>\n <i class=\"fa-solid fa-eye\"></i>\n </label>\n <label class=\"share-perm\" title=\"Can edit\">\n <input type=\"checkbox\" [checked]=\"share.Permission.CanEdit\" (change)=\"toggleCanEdit(share)\">\n <i class=\"fa-solid fa-edit\"></i>\n </label>\n <label class=\"share-perm\" title=\"Can delete\">\n <input type=\"checkbox\" [checked]=\"share.Permission.CanDelete\" (change)=\"toggleCanDelete(share)\">\n <i class=\"fa-solid fa-trash\"></i>\n </label>\n <label class=\"share-perm\" title=\"Can share\">\n <input type=\"checkbox\" [checked]=\"share.Permission.CanShare\" (change)=\"toggleCanShare(share)\">\n <i class=\"fa-solid fa-share\"></i>\n </label>\n </div>\n <button type=\"button\" class=\"share-remove-btn\" (click)=\"removeUserShare(share)\" title=\"Remove\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n @if (ActiveShares.length === 0) {\n <div class=\"share-empty\">\n <i class=\"fa-solid fa-user-lock\"></i>\n <span>Not shared with anyone yet</span>\n </div>\n }\n <!-- Pending Removals -->\n @if (RemovedShares.length > 0) {\n <div class=\"share-removed-section\">\n @for (share of RemovedShares; track share.User.ID) {\n <div class=\"share-removed-item\">\n <span class=\"share-avatar share-avatar-removed\">{{ getUserInitials(share.User) }}</span>\n <span class=\"share-removed-name\">{{ share.User.Name }}</span>\n <button type=\"button\" class=\"share-undo-btn\" (click)=\"undoRemove(share)\">\n <i class=\"fa-solid fa-undo\"></i> Undo\n </button>\n </div>\n }\n </div>\n }\n </div>\n <!-- Footer -->\n <div class=\"share-footer\">\n @if (HasChanges) {\n <span class=\"share-changes-hint\">\n <i class=\"fa-solid fa-circle\"></i> Unsaved changes\n </span>\n }\n <div class=\"share-footer-actions\">\n <button type=\"button\" class=\"share-btn share-btn-secondary\" (click)=\"onCancel()\">\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"share-btn share-btn-primary\"\n (click)=\"onSave()\"\n [disabled]=\"!HasChanges || IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n Save\n }\n </button>\n </div>\n </div>\n </div>\n </kendo-window>\n}\n", styles: ["/* Dashboard Share Dialog - Compact Design */\n\n/* Window Styling - use specific class to override Kendo defaults */\n.mj-share-dialog-window.k-window {\n border-radius: 12px !important;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2) !important;\n overflow: hidden !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar {\n background: var(--mj-brand-primary) !important;\n border: none !important;\n padding: 16px 20px !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-title {\n display: none !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-actions .k-button {\n background: color-mix(in srgb, var(--mj-bg-surface) 15%, transparent) !important;\n border: none !important;\n color: var(--mj-text-inverse) !important;\n border-radius: 4px !important;\n}\n\n.mj-share-dialog-window .k-window-titlebar .k-window-actions .k-button:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 25%, transparent) !important;\n}\n\n.mj-share-dialog-window .k-window-content {\n padding: 0 !important;\n background: var(--mj-bg-surface) !important;\n}\n\n/* Header */\n.share-dialog-header {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n font-weight: 500;\n}\n\n.share-dialog-header i {\n font-size: 18px;\n opacity: 0.9;\n}\n\n/* Body */\n.share-dialog-body {\n padding: 0;\n}\n\n/* Alert */\n.share-alert {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 20px;\n font-size: 13px;\n}\n\n.share-alert-error {\n background: var(--mj-bg-error);\n color: var(--mj-status-error);\n border-bottom: 1px solid var(--mj-border-error);\n}\n\n/* Sections */\n.share-section {\n padding: 16px 20px;\n}\n\n.share-section:not(:last-child) {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.share-section-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n}\n\n/* Search Box */\n.share-search-box {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid transparent;\n transition: all 0.15s;\n}\n\n.share-search-box:focus-within {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.share-search-box i {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.share-search-box input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n outline: none;\n}\n\n.share-search-box input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* User Dropdown */\n.share-user-dropdown {\n margin-top: 8px;\n max-height: 180px;\n overflow-y: auto;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n}\n\n/* User Option */\n.share-user-option {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 12px;\n border: none;\n background: transparent;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.share-user-option:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.share-user-option:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-user-option .share-user-name {\n flex: 1;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-user-option .share-user-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-right: auto;\n}\n\n.share-user-option i.fa-plus {\n color: var(--mj-brand-primary);\n font-size: 12px;\n opacity: 0;\n transition: opacity 0.1s;\n}\n\n.share-user-option:hover i.fa-plus {\n opacity: 1;\n}\n\n.share-no-results {\n padding: 16px;\n text-align: center;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n/* Avatar */\n.share-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.share-avatar-owner {\n background: var(--mj-status-warning);\n font-size: 14px;\n}\n\n.share-avatar-removed {\n background: var(--mj-border-strong);\n}\n\n/* Person Row */\n.share-person {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 0;\n}\n\n.share-person:not(:last-child) {\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.share-person-new {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-modified {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n margin: 0 -20px;\n padding: 10px 20px;\n}\n\n.share-person-info {\n flex: 1;\n min-width: 0;\n}\n\n.share-person-name {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-person-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.share-person-role {\n font-size: 12px;\n color: var(--mj-status-warning);\n font-weight: 500;\n}\n\n.share-badge-new {\n padding: 2px 6px;\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 4px;\n}\n\n/* Permissions */\n.share-permissions {\n display: flex;\n gap: 4px;\n}\n\n.share-perm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.1s;\n position: relative;\n}\n\n.share-perm input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n}\n\n.share-perm i {\n font-size: 12px;\n color: var(--mj-border-strong);\n transition: color 0.1s;\n}\n\n.share-perm:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.share-perm input:checked + i {\n color: var(--mj-brand-primary);\n}\n\n.share-perm input:disabled + i {\n color: var(--mj-brand-primary);\n opacity: 0.7;\n}\n\n/* Remove Button */\n.share-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.1s;\n}\n\n.share-remove-btn:hover {\n background: var(--mj-bg-error);\n color: var(--mj-status-error);\n}\n\n/* Empty State */\n.share-empty {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 20px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n justify-content: center;\n}\n\n.share-empty i {\n font-size: 16px;\n}\n\n/* Removed Section */\n.share-removed-section {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-warning);\n border-radius: 8px;\n border: 1px solid var(--mj-border-warning);\n}\n\n.share-removed-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n}\n\n.share-removed-name {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n text-decoration: line-through;\n}\n\n.share-undo-btn {\n padding: 4px 10px;\n border: none;\n background: transparent;\n color: var(--mj-status-warning);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.share-undo-btn:hover {\n text-decoration: underline;\n}\n\n/* Footer */\n.share-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.share-changes-hint {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-brand-primary);\n}\n\n.share-changes-hint i {\n font-size: 6px;\n}\n\n.share-footer-actions {\n display: flex;\n gap: 10px;\n margin-left: auto;\n}\n\n.share-btn {\n padding: 8px 18px;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.share-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.share-btn-secondary {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.share-btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n.share-btn-primary {\n background: var(--mj-brand-primary);\n border: none;\n color: var(--mj-text-inverse);\n}\n\n.share-btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Owner row specific styling */\n.share-owner {\n background: var(--mj-bg-warning);\n margin: 0 -20px;\n padding: 10px 20px;\n border-radius: 0;\n}\n"] }]
543
543
  }], () => [{ type: i0.ChangeDetectorRef }], { Visible: [{
544
544
  type: Input
545
545
  }], Dashboard: [{
@@ -170,11 +170,11 @@ export class FilterDialogComponent {
170
170
  i0.ɵɵconditionalCreate(0, FilterDialogComponent_Conditional_0_Template, 22, 9);
171
171
  } if (rf & 2) {
172
172
  i0.ɵɵconditional(ctx.isOpen ? 0 : -1);
173
- } }, dependencies: [i1.FilterBuilderComponent], styles: ["\n\n.dialog-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease;\n}\n\n\n\n.filter-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 90%;\n max-width: 800px;\n max-height: 85vh;\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from {\n opacity: 0;\n transform: translate(-50%, -48%);\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%);\n }\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n}\n\n.filter-badge[_ngcontent-%COMP%] {\n background: #1976d2;\n color: white;\n font-size: 12px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #999;\n font-size: 16px;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n color: #333;\n}\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n min-height: 200px;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-top: 1px solid #e8e8e8;\n background: #fafafa;\n border-radius: 0 0 12px 12px;\n flex-shrink: 0;\n}\n\n.footer-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 10px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.clear-btn[_ngcontent-%COMP%] {\n background: transparent;\n color: #c62828;\n border: 1px solid #e0e0e0;\n}\n\n.clear-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #ffebee;\n border-color: #c62828;\n}\n\n.cancel-btn[_ngcontent-%COMP%] {\n background: #f5f5f5;\n color: #666;\n}\n\n.cancel-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #e8e8e8;\n color: #333;\n}\n\n.apply-btn[_ngcontent-%COMP%] {\n background: #1976d2;\n color: white;\n}\n\n.apply-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #1565c0;\n}\n\n\n\n@media (max-width: 600px) {\n .filter-dialog[_ngcontent-%COMP%] {\n width: 95%;\n max-height: 90vh;\n border-radius: 8px;\n }\n\n .dialog-header[_ngcontent-%COMP%] {\n padding: 14px 16px;\n }\n\n .header-title[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .dialog-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .dialog-footer[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 12px;\n padding: 14px 16px;\n }\n\n .footer-right[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .footer-btn[_ngcontent-%COMP%] {\n flex: 1;\n justify-content: center;\n }\n\n .clear-btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}"] });
173
+ } }, dependencies: [i1.FilterBuilderComponent], styles: ["\n\n.dialog-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: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease;\n}\n\n\n\n.filter-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 90%;\n max-width: 800px;\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from {\n opacity: 0;\n transform: translate(-50%, -48%);\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%);\n }\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.filter-badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 16px;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n}\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n min-height: 200px;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n border-radius: 0 0 12px 12px;\n flex-shrink: 0;\n}\n\n.footer-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 10px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.clear-btn[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-status-error);\n border: 1px solid var(--mj-border-default);\n}\n\n.clear-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n}\n\n.cancel-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n}\n\n.cancel-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.apply-btn[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.apply-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n\n\n@media (max-width: 600px) {\n .filter-dialog[_ngcontent-%COMP%] {\n width: 95%;\n max-height: 90vh;\n border-radius: 8px;\n }\n\n .dialog-header[_ngcontent-%COMP%] {\n padding: 14px 16px;\n }\n\n .header-title[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .dialog-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .dialog-footer[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 12px;\n padding: 14px 16px;\n }\n\n .footer-right[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .footer-btn[_ngcontent-%COMP%] {\n flex: 1;\n justify-content: center;\n }\n\n .clear-btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}"] });
174
174
  }
175
175
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FilterDialogComponent, [{
176
176
  type: Component,
177
- args: [{ standalone: false, selector: 'mj-filter-dialog', template: "@if (isOpen) {\n <!-- Backdrop -->\n <div class=\"dialog-backdrop\" (click)=\"onCancel()\"></div>\n\n <!-- Dialog -->\n <div class=\"filter-dialog\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-filter\"></i>\n <span>Edit Filters</span>\n @if (getFilterCount() > 0) {\n <span class=\"filter-badge\">{{ getFilterCount() }}</span>\n }\n </div>\n <button class=\"close-btn\" (click)=\"onCancel()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <mj-filter-builder\n [fields]=\"fields\"\n [filter]=\"workingFilter\"\n [disabled]=\"disabled\"\n [showSummary]=\"true\"\n [config]=\"{ showClearButton: false, applyOnChange: true }\"\n (filterChange)=\"onFilterChange($event)\">\n </mj-filter-builder>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <button class=\"footer-btn clear-btn\" (click)=\"onClear()\" [disabled]=\"disabled || getFilterCount() === 0\">\n <i class=\"fa-solid fa-eraser\"></i>\n Clear All\n </button>\n <div class=\"footer-right\">\n <button class=\"footer-btn cancel-btn\" (click)=\"onCancel()\">\n Cancel\n </button>\n <button class=\"footer-btn apply-btn\" (click)=\"onApply()\" [disabled]=\"disabled\">\n <i class=\"fa-solid fa-check\"></i>\n Apply Filters\n </button>\n </div>\n </div>\n </div>\n}\n", styles: ["/* Backdrop */\n.dialog-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 1000;\n animation: fadeIn 0.15s ease;\n}\n\n/* Dialog */\n.filter-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 90%;\n max-width: 800px;\n max-height: 85vh;\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translate(-50%, -48%);\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%);\n }\n}\n\n/* Header */\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n}\n\n.header-title i {\n color: #1976d2;\n}\n\n.filter-badge {\n background: #1976d2;\n color: white;\n font-size: 12px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.close-btn {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #999;\n font-size: 16px;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn:hover {\n background: #f5f5f5;\n color: #333;\n}\n\n/* Content */\n.dialog-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n min-height: 200px;\n}\n\n/* Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-top: 1px solid #e8e8e8;\n background: #fafafa;\n border-radius: 0 0 12px 12px;\n flex-shrink: 0;\n}\n\n.footer-right {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 10px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn i {\n font-size: 12px;\n}\n\n.clear-btn {\n background: transparent;\n color: #c62828;\n border: 1px solid #e0e0e0;\n}\n\n.clear-btn:hover:not(:disabled) {\n background: #ffebee;\n border-color: #c62828;\n}\n\n.cancel-btn {\n background: #f5f5f5;\n color: #666;\n}\n\n.cancel-btn:hover:not(:disabled) {\n background: #e8e8e8;\n color: #333;\n}\n\n.apply-btn {\n background: #1976d2;\n color: white;\n}\n\n.apply-btn:hover:not(:disabled) {\n background: #1565c0;\n}\n\n/* Responsive */\n@media (max-width: 600px) {\n .filter-dialog {\n width: 95%;\n max-height: 90vh;\n border-radius: 8px;\n }\n\n .dialog-header {\n padding: 14px 16px;\n }\n\n .header-title {\n font-size: 16px;\n }\n\n .dialog-content {\n padding: 16px;\n }\n\n .dialog-footer {\n flex-direction: column;\n gap: 12px;\n padding: 14px 16px;\n }\n\n .footer-right {\n width: 100%;\n justify-content: stretch;\n }\n\n .footer-btn {\n flex: 1;\n justify-content: center;\n }\n\n .clear-btn {\n width: 100%;\n justify-content: center;\n }\n}\n"] }]
177
+ args: [{ standalone: false, selector: 'mj-filter-dialog', template: "@if (isOpen) {\n <!-- Backdrop -->\n <div class=\"dialog-backdrop\" (click)=\"onCancel()\"></div>\n\n <!-- Dialog -->\n <div class=\"filter-dialog\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-filter\"></i>\n <span>Edit Filters</span>\n @if (getFilterCount() > 0) {\n <span class=\"filter-badge\">{{ getFilterCount() }}</span>\n }\n </div>\n <button class=\"close-btn\" (click)=\"onCancel()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <mj-filter-builder\n [fields]=\"fields\"\n [filter]=\"workingFilter\"\n [disabled]=\"disabled\"\n [showSummary]=\"true\"\n [config]=\"{ showClearButton: false, applyOnChange: true }\"\n (filterChange)=\"onFilterChange($event)\">\n </mj-filter-builder>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <button class=\"footer-btn clear-btn\" (click)=\"onClear()\" [disabled]=\"disabled || getFilterCount() === 0\">\n <i class=\"fa-solid fa-eraser\"></i>\n Clear All\n </button>\n <div class=\"footer-right\">\n <button class=\"footer-btn cancel-btn\" (click)=\"onCancel()\">\n Cancel\n </button>\n <button class=\"footer-btn apply-btn\" (click)=\"onApply()\" [disabled]=\"disabled\">\n <i class=\"fa-solid fa-check\"></i>\n Apply Filters\n </button>\n </div>\n </div>\n </div>\n}\n", styles: ["/* Backdrop */\n.dialog-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: 1000;\n animation: fadeIn 0.15s ease;\n}\n\n/* Dialog */\n.filter-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 90%;\n max-width: 800px;\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translate(-50%, -48%);\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%);\n }\n}\n\n/* Header */\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title i {\n color: var(--mj-brand-primary);\n}\n\n.filter-badge {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.close-btn {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 16px;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n}\n\n/* Content */\n.dialog-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n min-height: 200px;\n}\n\n/* Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n border-radius: 0 0 12px 12px;\n flex-shrink: 0;\n}\n\n.footer-right {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 10px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn i {\n font-size: 12px;\n}\n\n.clear-btn {\n background: transparent;\n color: var(--mj-status-error);\n border: 1px solid var(--mj-border-default);\n}\n\n.clear-btn:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n}\n\n.cancel-btn {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n}\n\n.cancel-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.apply-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.apply-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n/* Responsive */\n@media (max-width: 600px) {\n .filter-dialog {\n width: 95%;\n max-height: 90vh;\n border-radius: 8px;\n }\n\n .dialog-header {\n padding: 14px 16px;\n }\n\n .header-title {\n font-size: 16px;\n }\n\n .dialog-content {\n padding: 16px;\n }\n\n .dialog-footer {\n flex-direction: column;\n gap: 12px;\n padding: 14px 16px;\n }\n\n .footer-right {\n width: 100%;\n justify-content: stretch;\n }\n\n .footer-btn {\n flex: 1;\n justify-content: center;\n }\n\n .clear-btn {\n width: 100%;\n justify-content: center;\n }\n}\n"] }]
178
178
  }], null, { isOpen: [{
179
179
  type: Input
180
180
  }], fields: [{
@@ -631,11 +631,11 @@ export class NavigationPanelComponent {
631
631
  i0.ɵɵclassProp("fa-chevron-right", ctx.collapsed)("fa-chevron-left", !ctx.collapsed);
632
632
  i0.ɵɵadvance();
633
633
  i0.ɵɵconditional(!ctx.collapsed ? 3 : 4);
634
- } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel], styles: [".navigation-panel-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0; \n\n position: relative;\n background: white;\n box-shadow: 1px 0 3px rgba(0, 0, 0, 0.05);\n}\n.navigation-panel-container.collapsed[_ngcontent-%COMP%] {\n align-items: center;\n padding-top: 48px;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.collapse-toggle[_ngcontent-%COMP%] {\n position: absolute;\n top: 12px;\n right: 12px;\n width: 28px;\n height: 28px;\n border: none;\n background: #f5f5f5;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n z-index: 10;\n}\n.collapse-toggle[_ngcontent-%COMP%]:hover {\n background: #e8e8e8;\n color: #333;\n}\n.collapsed[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%] {\n right: auto;\n left: 50%;\n transform: translateX(-50%);\n background: transparent;\n}\n.collapsed[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n}\n\n.panel-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n padding-top: 48px;\n min-height: 0; \n\n}\n\n.section[_ngcontent-%COMP%] {\n flex-shrink: 0;\n border-bottom: 1px solid #f0f0f0;\n}\n\n\n\n.section.favorites-section[_ngcontent-%COMP%], \n.section.recent-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-height: 0;\n max-height: 200px; \n\n}\n\n.section.entities-section[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n border-bottom: none;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 14px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n background: #fafafa;\n}\n.section-header[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n}\n\n.section-icon[_ngcontent-%COMP%] {\n width: 20px;\n font-size: 13px;\n color: #666;\n margin-right: 10px;\n}\n\n.section-title[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: #555;\n}\n\n.section-count[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #999;\n margin-right: 8px;\n font-weight: 500;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #999;\n transition: transform 0.15s ease;\n}\n\n.section-content[_ngcontent-%COMP%] {\n padding: 8px 12px 12px 12px;\n background: white;\n}\n\n\n\n.section-content.scrollable-section[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n\n.scrollable-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n padding-right: 4px;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: #ddd;\n border-radius: 3px;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: #ccc;\n}\n\n.scrollable-list-inner[_ngcontent-%COMP%] {\n \n\n}\n\n.entities-section[_ngcontent-%COMP%] .section-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0; \n\n overflow: hidden;\n}\n\n.empty-section[_ngcontent-%COMP%] {\n padding: 20px 16px;\n text-align: center;\n color: #aaa;\n font-size: 12px;\n font-style: italic;\n}\n\n.nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n gap: 10px;\n margin-bottom: 2px;\n}\n.nav-item[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n}\n.nav-item.selected[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);\n color: #1565c0;\n box-shadow: 0 1px 3px rgba(21, 101, 192, 0.15);\n}\n.nav-item.selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1565c0;\n}\n.nav-item.selected[_ngcontent-%COMP%] .nav-item-label[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n.nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 18px;\n font-size: 14px;\n color: #666;\n flex-shrink: 0;\n text-align: center;\n}\n\n.nav-item-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.nav-item-label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.nav-item-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #999;\n}\n\n.entity-search[_ngcontent-%COMP%] {\n position: relative;\n margin-bottom: 12px;\n flex-shrink: 0;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 12px;\n color: #999;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 36px 10px 36px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n font-size: 13px;\n background: #fafafa;\n transition: all 0.15s ease;\n}\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #1976d2;\n background: white;\n box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);\n}\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: #aaa;\n}\n\n.clear-search[_ngcontent-%COMP%] {\n position: absolute;\n right: 6px;\n top: 50%;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #999;\n}\n.clear-search[_ngcontent-%COMP%]:hover {\n background: #e0e0e0;\n color: #555;\n}\n\n.entity-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n padding-right: 4px;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: #ddd;\n border-radius: 3px;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: #ccc;\n}\n\n.entity-list-inner[_ngcontent-%COMP%] {\n \n\n \n\n}\n\n.entity-item[_ngcontent-%COMP%] .nav-item-label[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n\n\n\n\n\n.nav-app-group[_ngcontent-%COMP%] {\n margin-bottom: 2px;\n}\n\n.nav-app-group-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.12s;\n user-select: none;\n}\n\n.nav-app-group-header[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n}\n\n.nav-app-group-icon[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6b7280;\n width: 16px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.nav-app-group-name[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #6b7280;\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.nav-app-group-count[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #9ca3af;\n background: #f5f7fa;\n padding: 1px 6px;\n border-radius: 8px;\n}\n\n.nav-app-group-chevron[_ngcontent-%COMP%] {\n font-size: 9px;\n color: #9ca3af;\n transition: transform 0.15s;\n}\n\n.nav-app-group-chevron.expanded[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n.nav-app-group-entities[_ngcontent-%COMP%] {\n padding-left: 8px;\n}\n\n.nav-app-group-entities[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%] {\n padding: 8px 10px 8px 16px;\n}\n\n.collapsed-icons[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding-top: 16px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n position: relative;\n}\n.icon-btn[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n color: #1976d2;\n}\n.icon-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.collapsed-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: 2px;\n right: 2px;\n min-width: 16px;\n height: 16px;\n font-size: 10px;\n font-weight: 600;\n color: white;\n background: #1976d2;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n}"] });
634
+ } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel], styles: [".navigation-panel-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0; \n\n position: relative;\n background: var(--mj-bg-surface);\n box-shadow: 1px 0 3px rgba(0, 0, 0, 0.05);\n}\n.navigation-panel-container.collapsed[_ngcontent-%COMP%] {\n align-items: center;\n padding-top: 48px;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.collapse-toggle[_ngcontent-%COMP%] {\n position: absolute;\n top: 12px;\n right: 12px;\n width: 28px;\n height: 28px;\n border: none;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n z-index: 10;\n}\n.collapse-toggle[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.collapsed[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%] {\n right: auto;\n left: 50%;\n transform: translateX(-50%);\n background: transparent;\n}\n.collapsed[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.panel-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n padding-top: 48px;\n min-height: 0; \n\n}\n\n.section[_ngcontent-%COMP%] {\n flex-shrink: 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n\n\n.section.favorites-section[_ngcontent-%COMP%], \n.section.recent-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-height: 0;\n max-height: 200px; \n\n}\n\n.section.entities-section[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n border-bottom: none;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 14px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n background: var(--mj-bg-surface-card);\n}\n.section-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.section-icon[_ngcontent-%COMP%] {\n width: 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin-right: 10px;\n}\n\n.section-title[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: var(--mj-text-muted);\n}\n\n.section-count[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-right: 8px;\n font-weight: 500;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.15s ease;\n}\n\n.section-content[_ngcontent-%COMP%] {\n padding: 8px 12px 12px 12px;\n background: var(--mj-bg-surface);\n}\n\n\n\n.section-content.scrollable-section[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n\n.scrollable-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n padding-right: 4px;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n.scrollable-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n.scrollable-list-inner[_ngcontent-%COMP%] {\n \n\n}\n\n.entities-section[_ngcontent-%COMP%] .section-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0; \n\n overflow: hidden;\n}\n\n.empty-section[_ngcontent-%COMP%] {\n padding: 20px 16px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n font-style: italic;\n}\n\n.nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n gap: 10px;\n margin-bottom: 2px;\n}\n.nav-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n.nav-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.nav-item.selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.nav-item.selected[_ngcontent-%COMP%] .nav-item-label[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n.nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 18px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n text-align: center;\n}\n\n.nav-item-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.nav-item-label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.nav-item-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.entity-search[_ngcontent-%COMP%] {\n position: relative;\n margin-bottom: 12px;\n flex-shrink: 0;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 36px 10px 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface-card);\n transition: all 0.15s ease;\n}\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n\n.clear-search[_ngcontent-%COMP%] {\n position: absolute;\n right: 6px;\n top: 50%;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n}\n.clear-search[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n.entity-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n padding-right: 4px;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n.entity-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n.entity-list-inner[_ngcontent-%COMP%] {\n \n\n \n\n}\n\n.entity-item[_ngcontent-%COMP%] .nav-item-label[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n\n\n\n\n\n.nav-app-group[_ngcontent-%COMP%] {\n margin-bottom: 2px;\n}\n\n.nav-app-group-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.12s;\n user-select: none;\n}\n\n.nav-app-group-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.nav-app-group-icon[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n width: 16px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.nav-app-group-name[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-secondary);\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.nav-app-group-count[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 8px;\n}\n\n.nav-app-group-chevron[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-muted);\n transition: transform 0.15s;\n}\n\n.nav-app-group-chevron.expanded[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n.nav-app-group-entities[_ngcontent-%COMP%] {\n padding-left: 8px;\n}\n\n.nav-app-group-entities[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%] {\n padding: 8px 10px 8px 16px;\n}\n\n.collapsed-icons[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding-top: 16px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n position: relative;\n}\n.icon-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n.icon-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.collapsed-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: 2px;\n right: 2px;\n min-width: 16px;\n height: 16px;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n}"] });
635
635
  }
636
636
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NavigationPanelComponent, [{
637
637
  type: Component,
638
- args: [{ standalone: false, selector: 'mj-explorer-navigation-panel', template: "<div class=\"navigation-panel-container\" [class.collapsed]=\"collapsed\">\n <!-- Collapse Toggle -->\n <button class=\"collapse-toggle\" (click)=\"onToggleCollapse()\" [title]=\"collapsed ? 'Expand' : 'Collapse'\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"collapsed\" [class.fa-chevron-left]=\"!collapsed\"></i>\n </button>\n\n @if (!collapsed) {\n <div class=\"panel-content\">\n <!-- Favorites Section -->\n <div class=\"section favorites-section\">\n <div class=\"section-header\" (click)=\"onSectionToggle('favorites')\">\n <i class=\"fa-solid fa-star section-icon\"></i>\n <span class=\"section-title\">Favorites</span>\n @if (favoriteRecords.length + favoriteEntities.length > 0) {\n <span class=\"section-count\">({{ favoriteRecords.length + favoriteEntities.length }})</span>\n }\n <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"favoritesSectionExpanded\" [class.fa-chevron-right]=\"!favoritesSectionExpanded\"></i>\n </div>\n\n @if (favoritesSectionExpanded) {\n <div class=\"section-content scrollable-section\">\n @if (favoriteRecords.length + favoriteEntities.length === 0) {\n <div class=\"empty-section\">\n <span>No favorites yet</span>\n </div>\n } @else {\n <div class=\"scrollable-list\">\n <div class=\"scrollable-list-inner\">\n @for (favorite of favoriteEntities; track favorite.displayName) {\n <div class=\"nav-item\" (click)=\"onFavoriteClick(favorite)\" [title]=\"favorite.entityName ? favorite.entityName + ' - ' + favorite.displayName : favorite.displayName\">\n <i [class]=\"getFavoriteIcon(favorite)\"></i>\n <span class=\"nav-item-label\">{{ favorite.displayName }}</span>\n </div>\n }\n @for (favorite of favoriteRecords; track favorite.displayName) {\n <div class=\"nav-item\" (click)=\"onFavoriteClick(favorite)\" [title]=\"favorite.entityName ? favorite.entityName + ' - ' + favorite.displayName : favorite.displayName\">\n <i [class]=\"getFavoriteIcon(favorite)\"></i>\n <span class=\"nav-item-label\">{{ favorite.displayName }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Recent Items Section -->\n <div class=\"section recent-section\">\n <div class=\"section-header\" (click)=\"onSectionToggle('recent')\">\n <i class=\"fa-solid fa-clock section-icon\"></i>\n <span class=\"section-title\">Recent</span>\n @if (filteredRecentItems.length > 0) {\n <span class=\"section-count\">({{ filteredRecentItems.length }})</span>\n }\n <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"recentSectionExpanded\" [class.fa-chevron-right]=\"!recentSectionExpanded\"></i>\n </div>\n\n @if (recentSectionExpanded) {\n <div class=\"section-content scrollable-section\">\n @if (filteredRecentItems.length === 0) {\n <div class=\"empty-section\">\n <span>No recent items</span>\n </div>\n } @else {\n <div class=\"scrollable-list\">\n <div class=\"scrollable-list-inner\">\n @for (item of filteredRecentItems; track item.compositeKeyString) {\n <div class=\"nav-item\" (click)=\"onRecentClick(item)\" [title]=\"item.entityName + ' - ' + item.displayName\">\n <i [class]=\"getRecentItemIcon(item)\"></i>\n <div class=\"nav-item-content\">\n <span class=\"nav-item-label\">{{ item.displayName }}</span>\n <span class=\"nav-item-meta\">{{ formatTimestamp(item.timestamp) }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Entities Section -->\n <div class=\"section entities-section\">\n <div class=\"section-header\" (click)=\"onSectionToggle('entities')\">\n <i class=\"fa-solid fa-database section-icon\"></i>\n <span class=\"section-title\">Entities</span>\n <span class=\"section-count\">({{ entities.length }})</span>\n <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"entitiesSectionExpanded\" [class.fa-chevron-right]=\"!entitiesSectionExpanded\"></i>\n </div>\n\n @if (entitiesSectionExpanded) {\n <div class=\"section-content\">\n <!-- Entity Search -->\n <div class=\"entity-search\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input\n type=\"text\"\n class=\"search-input\"\n placeholder=\"Search entities...\"\n [(ngModel)]=\"entitySearchTerm\"\n />\n @if (entitySearchTerm) {\n <button class=\"clear-search\" (click)=\"entitySearchTerm = ''\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n\n <!-- Entity List (scrollable container) -->\n <div class=\"entity-list\">\n <div class=\"entity-list-inner\">\n @if (hasAppGroups) {\n <!-- Grouped by application -->\n @for (group of filteredNavGroups; track group.applicationId) {\n <div class=\"nav-app-group\">\n <div class=\"nav-app-group-header\" (click)=\"onNavGroupToggle(group.applicationId)\">\n <i [class]=\"group.applicationIcon || 'fa-solid fa-folder'\" class=\"nav-app-group-icon\"\n [style.color]=\"group.applicationColor || null\"></i>\n <span class=\"nav-app-group-name\">{{ group.applicationName }}</span>\n <span class=\"nav-app-group-count\">{{ group.entities.length }}</span>\n <i class=\"fa-solid fa-chevron-right nav-app-group-chevron\"\n [class.expanded]=\"isNavGroupExpanded(group.applicationId)\"></i>\n </div>\n @if (isNavGroupExpanded(group.applicationId)) {\n <div class=\"nav-app-group-entities\">\n @for (entity of group.entities; track entity.ID) {\n <div\n class=\"nav-item entity-item\"\n [class.selected]=\"isEntitySelected(entity)\"\n (click)=\"onEntityClick(entity)\"\n [title]=\"entity.Description || entity.DisplayNameOrName\">\n <i [class]=\"getEntityIcon(entity)\"></i>\n <span class=\"nav-item-label\">{{ entity.DisplayNameOrName }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n } @else {\n <!-- Flat list (no groups available) -->\n @for (entity of filteredEntities; track entity.ID) {\n <div\n class=\"nav-item entity-item\"\n [class.selected]=\"isEntitySelected(entity)\"\n (click)=\"onEntityClick(entity)\"\n [title]=\"entity.Description || entity.DisplayNameOrName\">\n <i [class]=\"getEntityIcon(entity)\"></i>\n <span class=\"nav-item-label\">{{ entity.DisplayNameOrName }}</span>\n </div>\n }\n }\n\n @if (filteredEntities.length === 0 && entitySearchTerm) {\n <div class=\"empty-section\">\n <span>No entities match \"{{ entitySearchTerm }}\"</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n } @else {\n <!-- Collapsed State - Show Icons Only -->\n <div class=\"collapsed-icons\">\n <button class=\"icon-btn\" title=\"Favorites\" (click)=\"onCollapsedIconClick('favorites')\">\n <i class=\"fa-solid fa-star\"></i>\n @if (favoriteRecords.length + favoriteEntities.length > 0) {\n <span class=\"collapsed-badge\">{{ favoriteRecords.length + favoriteEntities.length }}</span>\n }\n </button>\n <button class=\"icon-btn\" title=\"Recent\" (click)=\"onCollapsedIconClick('recent')\">\n <i class=\"fa-solid fa-clock\"></i>\n @if (filteredRecentItems.length > 0) {\n <span class=\"collapsed-badge\">{{ filteredRecentItems.length }}</span>\n }\n </button>\n <button class=\"icon-btn\" title=\"Entities\" (click)=\"onCollapsedIconClick('entities')\">\n <i class=\"fa-solid fa-database\"></i>\n <span class=\"collapsed-badge\">{{ entities.length }}</span>\n </button>\n </div>\n }\n</div>\n", styles: [".navigation-panel-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0; /* Critical for nested flex scrolling */\n position: relative;\n background: white;\n box-shadow: 1px 0 3px rgba(0, 0, 0, 0.05);\n}\n.navigation-panel-container.collapsed {\n align-items: center;\n padding-top: 48px;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.panel-title {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.collapse-toggle {\n position: absolute;\n top: 12px;\n right: 12px;\n width: 28px;\n height: 28px;\n border: none;\n background: #f5f5f5;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n z-index: 10;\n}\n.collapse-toggle:hover {\n background: #e8e8e8;\n color: #333;\n}\n.collapsed .collapse-toggle {\n right: auto;\n left: 50%;\n transform: translateX(-50%);\n background: transparent;\n}\n.collapsed .collapse-toggle:hover {\n background: #f5f5f5;\n}\n\n.panel-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n padding-top: 48px;\n min-height: 0; /* Allow flex children to shrink below content size */\n}\n\n.section {\n flex-shrink: 0;\n border-bottom: 1px solid #f0f0f0;\n}\n\n/* Scrollable sections (Favorites, Recent) - allow them to shrink and scroll */\n.section.favorites-section,\n.section.recent-section {\n display: flex;\n flex-direction: column;\n min-height: 0;\n max-height: 200px; /* Limit height so entities section has room */\n}\n\n.section.entities-section {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n border-bottom: none;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n padding: 14px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n background: #fafafa;\n}\n.section-header:hover {\n background: #f0f0f0;\n}\n\n.section-icon {\n width: 20px;\n font-size: 13px;\n color: #666;\n margin-right: 10px;\n}\n\n.section-title {\n flex: 1;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: #555;\n}\n\n.section-count {\n font-size: 11px;\n color: #999;\n margin-right: 8px;\n font-weight: 500;\n}\n\n.expand-icon {\n font-size: 10px;\n color: #999;\n transition: transform 0.15s ease;\n}\n\n.section-content {\n padding: 8px 12px 12px 12px;\n background: white;\n}\n\n/* Scrollable section content for Favorites and Recent */\n.section-content.scrollable-section {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n\n.scrollable-list {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n padding-right: 4px;\n}\n.scrollable-list::-webkit-scrollbar {\n width: 6px;\n}\n.scrollable-list::-webkit-scrollbar-track {\n background: transparent;\n}\n.scrollable-list::-webkit-scrollbar-thumb {\n background: #ddd;\n border-radius: 3px;\n}\n.scrollable-list::-webkit-scrollbar-thumb:hover {\n background: #ccc;\n}\n\n.scrollable-list-inner {\n /* Inner container grows naturally based on content */\n}\n\n.entities-section .section-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0; /* Allow content to shrink */\n overflow: hidden;\n}\n\n.empty-section {\n padding: 20px 16px;\n text-align: center;\n color: #aaa;\n font-size: 12px;\n font-style: italic;\n}\n\n.nav-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n gap: 10px;\n margin-bottom: 2px;\n}\n.nav-item:hover {\n background: #f5f5f5;\n}\n.nav-item.selected {\n background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);\n color: #1565c0;\n box-shadow: 0 1px 3px rgba(21, 101, 192, 0.15);\n}\n.nav-item.selected i {\n color: #1565c0;\n}\n.nav-item.selected .nav-item-label {\n font-weight: 600;\n}\n.nav-item i {\n width: 18px;\n font-size: 14px;\n color: #666;\n flex-shrink: 0;\n text-align: center;\n}\n\n.nav-item-content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.nav-item-label {\n font-size: 13px;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.nav-item-meta {\n font-size: 11px;\n color: #999;\n}\n\n.entity-search {\n position: relative;\n margin-bottom: 12px;\n flex-shrink: 0;\n}\n\n.search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 12px;\n color: #999;\n}\n\n.search-input {\n width: 100%;\n padding: 10px 36px 10px 36px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n font-size: 13px;\n background: #fafafa;\n transition: all 0.15s ease;\n}\n.search-input:focus {\n outline: none;\n border-color: #1976d2;\n background: white;\n box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);\n}\n.search-input::placeholder {\n color: #aaa;\n}\n\n.clear-search {\n position: absolute;\n right: 6px;\n top: 50%;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #999;\n}\n.clear-search:hover {\n background: #e0e0e0;\n color: #555;\n}\n\n.entity-list {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n padding-right: 4px;\n}\n.entity-list::-webkit-scrollbar {\n width: 6px;\n}\n.entity-list::-webkit-scrollbar-track {\n background: transparent;\n}\n.entity-list::-webkit-scrollbar-thumb {\n background: #ddd;\n border-radius: 3px;\n}\n.entity-list::-webkit-scrollbar-thumb:hover {\n background: #ccc;\n}\n\n.entity-list-inner {\n /* Inner container grows naturally based on content */\n /* Does not scroll - parent .entity-list handles scrolling */\n}\n\n.entity-item .nav-item-label {\n flex: 1;\n}\n\n/* ============================================\n NAV PANEL APPLICATION GROUPS\n ============================================ */\n\n.nav-app-group {\n margin-bottom: 2px;\n}\n\n.nav-app-group-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.12s;\n user-select: none;\n}\n\n.nav-app-group-header:hover {\n background: #f5f5f5;\n}\n\n.nav-app-group-icon {\n font-size: 12px;\n color: #6b7280;\n width: 16px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.nav-app-group-name {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #6b7280;\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.nav-app-group-count {\n font-size: 10px;\n color: #9ca3af;\n background: #f5f7fa;\n padding: 1px 6px;\n border-radius: 8px;\n}\n\n.nav-app-group-chevron {\n font-size: 9px;\n color: #9ca3af;\n transition: transform 0.15s;\n}\n\n.nav-app-group-chevron.expanded {\n transform: rotate(90deg);\n}\n\n.nav-app-group-entities {\n padding-left: 8px;\n}\n\n.nav-app-group-entities .nav-item {\n padding: 8px 10px 8px 16px;\n}\n\n.collapsed-icons {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding-top: 16px;\n}\n\n.icon-btn {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n position: relative;\n}\n.icon-btn:hover {\n background: #f0f0f0;\n color: #1976d2;\n}\n.icon-btn i {\n font-size: 16px;\n}\n\n.collapsed-badge {\n position: absolute;\n top: 2px;\n right: 2px;\n min-width: 16px;\n height: 16px;\n font-size: 10px;\n font-weight: 600;\n color: white;\n background: #1976d2;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n}\n"] }]
638
+ args: [{ standalone: false, selector: 'mj-explorer-navigation-panel', template: "<div class=\"navigation-panel-container\" [class.collapsed]=\"collapsed\">\n <!-- Collapse Toggle -->\n <button class=\"collapse-toggle\" (click)=\"onToggleCollapse()\" [title]=\"collapsed ? 'Expand' : 'Collapse'\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"collapsed\" [class.fa-chevron-left]=\"!collapsed\"></i>\n </button>\n\n @if (!collapsed) {\n <div class=\"panel-content\">\n <!-- Favorites Section -->\n <div class=\"section favorites-section\">\n <div class=\"section-header\" (click)=\"onSectionToggle('favorites')\">\n <i class=\"fa-solid fa-star section-icon\"></i>\n <span class=\"section-title\">Favorites</span>\n @if (favoriteRecords.length + favoriteEntities.length > 0) {\n <span class=\"section-count\">({{ favoriteRecords.length + favoriteEntities.length }})</span>\n }\n <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"favoritesSectionExpanded\" [class.fa-chevron-right]=\"!favoritesSectionExpanded\"></i>\n </div>\n\n @if (favoritesSectionExpanded) {\n <div class=\"section-content scrollable-section\">\n @if (favoriteRecords.length + favoriteEntities.length === 0) {\n <div class=\"empty-section\">\n <span>No favorites yet</span>\n </div>\n } @else {\n <div class=\"scrollable-list\">\n <div class=\"scrollable-list-inner\">\n @for (favorite of favoriteEntities; track favorite.displayName) {\n <div class=\"nav-item\" (click)=\"onFavoriteClick(favorite)\" [title]=\"favorite.entityName ? favorite.entityName + ' - ' + favorite.displayName : favorite.displayName\">\n <i [class]=\"getFavoriteIcon(favorite)\"></i>\n <span class=\"nav-item-label\">{{ favorite.displayName }}</span>\n </div>\n }\n @for (favorite of favoriteRecords; track favorite.displayName) {\n <div class=\"nav-item\" (click)=\"onFavoriteClick(favorite)\" [title]=\"favorite.entityName ? favorite.entityName + ' - ' + favorite.displayName : favorite.displayName\">\n <i [class]=\"getFavoriteIcon(favorite)\"></i>\n <span class=\"nav-item-label\">{{ favorite.displayName }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Recent Items Section -->\n <div class=\"section recent-section\">\n <div class=\"section-header\" (click)=\"onSectionToggle('recent')\">\n <i class=\"fa-solid fa-clock section-icon\"></i>\n <span class=\"section-title\">Recent</span>\n @if (filteredRecentItems.length > 0) {\n <span class=\"section-count\">({{ filteredRecentItems.length }})</span>\n }\n <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"recentSectionExpanded\" [class.fa-chevron-right]=\"!recentSectionExpanded\"></i>\n </div>\n\n @if (recentSectionExpanded) {\n <div class=\"section-content scrollable-section\">\n @if (filteredRecentItems.length === 0) {\n <div class=\"empty-section\">\n <span>No recent items</span>\n </div>\n } @else {\n <div class=\"scrollable-list\">\n <div class=\"scrollable-list-inner\">\n @for (item of filteredRecentItems; track item.compositeKeyString) {\n <div class=\"nav-item\" (click)=\"onRecentClick(item)\" [title]=\"item.entityName + ' - ' + item.displayName\">\n <i [class]=\"getRecentItemIcon(item)\"></i>\n <div class=\"nav-item-content\">\n <span class=\"nav-item-label\">{{ item.displayName }}</span>\n <span class=\"nav-item-meta\">{{ formatTimestamp(item.timestamp) }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Entities Section -->\n <div class=\"section entities-section\">\n <div class=\"section-header\" (click)=\"onSectionToggle('entities')\">\n <i class=\"fa-solid fa-database section-icon\"></i>\n <span class=\"section-title\">Entities</span>\n <span class=\"section-count\">({{ entities.length }})</span>\n <i class=\"fa-solid expand-icon\" [class.fa-chevron-down]=\"entitiesSectionExpanded\" [class.fa-chevron-right]=\"!entitiesSectionExpanded\"></i>\n </div>\n\n @if (entitiesSectionExpanded) {\n <div class=\"section-content\">\n <!-- Entity Search -->\n <div class=\"entity-search\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input\n type=\"text\"\n class=\"search-input\"\n placeholder=\"Search entities...\"\n [(ngModel)]=\"entitySearchTerm\"\n />\n @if (entitySearchTerm) {\n <button class=\"clear-search\" (click)=\"entitySearchTerm = ''\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n\n <!-- Entity List (scrollable container) -->\n <div class=\"entity-list\">\n <div class=\"entity-list-inner\">\n @if (hasAppGroups) {\n <!-- Grouped by application -->\n @for (group of filteredNavGroups; track group.applicationId) {\n <div class=\"nav-app-group\">\n <div class=\"nav-app-group-header\" (click)=\"onNavGroupToggle(group.applicationId)\">\n <i [class]=\"group.applicationIcon || 'fa-solid fa-folder'\" class=\"nav-app-group-icon\"\n [style.color]=\"group.applicationColor || null\"></i>\n <span class=\"nav-app-group-name\">{{ group.applicationName }}</span>\n <span class=\"nav-app-group-count\">{{ group.entities.length }}</span>\n <i class=\"fa-solid fa-chevron-right nav-app-group-chevron\"\n [class.expanded]=\"isNavGroupExpanded(group.applicationId)\"></i>\n </div>\n @if (isNavGroupExpanded(group.applicationId)) {\n <div class=\"nav-app-group-entities\">\n @for (entity of group.entities; track entity.ID) {\n <div\n class=\"nav-item entity-item\"\n [class.selected]=\"isEntitySelected(entity)\"\n (click)=\"onEntityClick(entity)\"\n [title]=\"entity.Description || entity.DisplayNameOrName\">\n <i [class]=\"getEntityIcon(entity)\"></i>\n <span class=\"nav-item-label\">{{ entity.DisplayNameOrName }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n } @else {\n <!-- Flat list (no groups available) -->\n @for (entity of filteredEntities; track entity.ID) {\n <div\n class=\"nav-item entity-item\"\n [class.selected]=\"isEntitySelected(entity)\"\n (click)=\"onEntityClick(entity)\"\n [title]=\"entity.Description || entity.DisplayNameOrName\">\n <i [class]=\"getEntityIcon(entity)\"></i>\n <span class=\"nav-item-label\">{{ entity.DisplayNameOrName }}</span>\n </div>\n }\n }\n\n @if (filteredEntities.length === 0 && entitySearchTerm) {\n <div class=\"empty-section\">\n <span>No entities match \"{{ entitySearchTerm }}\"</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n } @else {\n <!-- Collapsed State - Show Icons Only -->\n <div class=\"collapsed-icons\">\n <button class=\"icon-btn\" title=\"Favorites\" (click)=\"onCollapsedIconClick('favorites')\">\n <i class=\"fa-solid fa-star\"></i>\n @if (favoriteRecords.length + favoriteEntities.length > 0) {\n <span class=\"collapsed-badge\">{{ favoriteRecords.length + favoriteEntities.length }}</span>\n }\n </button>\n <button class=\"icon-btn\" title=\"Recent\" (click)=\"onCollapsedIconClick('recent')\">\n <i class=\"fa-solid fa-clock\"></i>\n @if (filteredRecentItems.length > 0) {\n <span class=\"collapsed-badge\">{{ filteredRecentItems.length }}</span>\n }\n </button>\n <button class=\"icon-btn\" title=\"Entities\" (click)=\"onCollapsedIconClick('entities')\">\n <i class=\"fa-solid fa-database\"></i>\n <span class=\"collapsed-badge\">{{ entities.length }}</span>\n </button>\n </div>\n }\n</div>\n", styles: [".navigation-panel-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0; /* Critical for nested flex scrolling */\n position: relative;\n background: var(--mj-bg-surface);\n box-shadow: 1px 0 3px rgba(0, 0, 0, 0.05);\n}\n.navigation-panel-container.collapsed {\n align-items: center;\n padding-top: 48px;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.panel-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.collapse-toggle {\n position: absolute;\n top: 12px;\n right: 12px;\n width: 28px;\n height: 28px;\n border: none;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n z-index: 10;\n}\n.collapse-toggle:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.collapsed .collapse-toggle {\n right: auto;\n left: 50%;\n transform: translateX(-50%);\n background: transparent;\n}\n.collapsed .collapse-toggle:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.panel-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n padding-top: 48px;\n min-height: 0; /* Allow flex children to shrink below content size */\n}\n\n.section {\n flex-shrink: 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n/* Scrollable sections (Favorites, Recent) - allow them to shrink and scroll */\n.section.favorites-section,\n.section.recent-section {\n display: flex;\n flex-direction: column;\n min-height: 0;\n max-height: 200px; /* Limit height so entities section has room */\n}\n\n.section.entities-section {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n border-bottom: none;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n padding: 14px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n background: var(--mj-bg-surface-card);\n}\n.section-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.section-icon {\n width: 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin-right: 10px;\n}\n\n.section-title {\n flex: 1;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: var(--mj-text-muted);\n}\n\n.section-count {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-right: 8px;\n font-weight: 500;\n}\n\n.expand-icon {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.15s ease;\n}\n\n.section-content {\n padding: 8px 12px 12px 12px;\n background: var(--mj-bg-surface);\n}\n\n/* Scrollable section content for Favorites and Recent */\n.section-content.scrollable-section {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n\n.scrollable-list {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n padding-right: 4px;\n}\n.scrollable-list::-webkit-scrollbar {\n width: 6px;\n}\n.scrollable-list::-webkit-scrollbar-track {\n background: transparent;\n}\n.scrollable-list::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n.scrollable-list::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n.scrollable-list-inner {\n /* Inner container grows naturally based on content */\n}\n\n.entities-section .section-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0; /* Allow content to shrink */\n overflow: hidden;\n}\n\n.empty-section {\n padding: 20px 16px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n font-style: italic;\n}\n\n.nav-item {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n gap: 10px;\n margin-bottom: 2px;\n}\n.nav-item:hover {\n background: var(--mj-bg-surface-card);\n}\n.nav-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.nav-item.selected i {\n color: var(--mj-brand-primary);\n}\n.nav-item.selected .nav-item-label {\n font-weight: 600;\n}\n.nav-item i {\n width: 18px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n text-align: center;\n}\n\n.nav-item-content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.nav-item-label {\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.nav-item-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.entity-search {\n position: relative;\n margin-bottom: 12px;\n flex-shrink: 0;\n}\n\n.search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.search-input {\n width: 100%;\n padding: 10px 36px 10px 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface-card);\n transition: all 0.15s ease;\n}\n.search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n.search-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.clear-search {\n position: absolute;\n right: 6px;\n top: 50%;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n}\n.clear-search:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n.entity-list {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n padding-right: 4px;\n}\n.entity-list::-webkit-scrollbar {\n width: 6px;\n}\n.entity-list::-webkit-scrollbar-track {\n background: transparent;\n}\n.entity-list::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n.entity-list::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n.entity-list-inner {\n /* Inner container grows naturally based on content */\n /* Does not scroll - parent .entity-list handles scrolling */\n}\n\n.entity-item .nav-item-label {\n flex: 1;\n}\n\n/* ============================================\n NAV PANEL APPLICATION GROUPS\n ============================================ */\n\n.nav-app-group {\n margin-bottom: 2px;\n}\n\n.nav-app-group-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.12s;\n user-select: none;\n}\n\n.nav-app-group-header:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.nav-app-group-icon {\n font-size: 12px;\n color: var(--mj-text-secondary);\n width: 16px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.nav-app-group-name {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-secondary);\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.nav-app-group-count {\n font-size: 10px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 8px;\n}\n\n.nav-app-group-chevron {\n font-size: 9px;\n color: var(--mj-text-muted);\n transition: transform 0.15s;\n}\n\n.nav-app-group-chevron.expanded {\n transform: rotate(90deg);\n}\n\n.nav-app-group-entities {\n padding-left: 8px;\n}\n\n.nav-app-group-entities .nav-item {\n padding: 8px 10px 8px 16px;\n}\n\n.collapsed-icons {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding-top: 16px;\n}\n\n.icon-btn {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n position: relative;\n}\n.icon-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n.icon-btn i {\n font-size: 16px;\n}\n\n.collapsed-badge {\n position: absolute;\n top: 2px;\n right: 2px;\n min-width: 16px;\n height: 16px;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n}\n"] }]
639
639
  }], null, { entities: [{
640
640
  type: Input
641
641
  }], selectedEntityName: [{
@@ -824,11 +824,11 @@ export class ViewSelectorComponent {
824
824
  i0.ɵɵconditional(ctx.isDropdownOpen ? 9 : -1);
825
825
  i0.ɵɵadvance();
826
826
  i0.ɵɵconditional(ctx.selectedViewId ? 10 : -1);
827
- } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["/* ========================================\n VIEW SELECTOR - All classes prefixed vs-\n to avoid conflicts (ViewEncapsulation.None)\n ======================================== */\n\n/* Container */\n.vs-container {\n display: flex;\n align-items: center;\n gap: 4px;\n position: relative;\n}\n\n/* Backdrop for closing panel */\n.vs-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n background: transparent;\n}\n\n.vs-wrapper {\n position: relative;\n}\n\n/* Main Button */\n.vs-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: var(--background-alt, #f5f5f5);\n border: 1px solid var(--border-color, #e0e0e0);\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--text-primary, #333);\n transition: all 0.15s ease;\n min-width: 140px;\n max-width: 280px;\n}\n\n.vs-button:hover {\n border-color: #5c6bc0;\n background: #f3f4fa;\n}\n\n.vs-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.vs-button.open {\n border-color: #5c6bc0;\n background: #f3f4fa;\n}\n\n.vs-button.modified {\n border-color: #f57c00;\n}\n\n.vs-btn-icon {\n color: #5c6bc0;\n font-size: 12px;\n}\n\n.vs-btn-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: left;\n}\n\n.vs-modified-dot {\n color: #f57c00;\n font-weight: bold;\n font-size: 18px;\n line-height: 1;\n}\n\n.vs-arrow {\n color: #999;\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.vs-arrow.rotated {\n transform: rotate(180deg);\n}\n\n/* ========================================\n RICH VIEW PANEL\n Styles ported directly from prototype\n ======================================== */\n\n/* Reset inherited styles inside panel */\n.vs-panel,\n.vs-panel * {\n box-sizing: border-box;\n line-height: 1.5;\n text-align: left;\n}\n\n.vs-panel {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n width: 400px;\n max-width: calc(100vw - 40px);\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.16);\n z-index: 1000;\n overflow: hidden;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n color: #333;\n}\n\n/* Panel Header */\n.vs-panel-header {\n padding: 16px 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.vs-header-icon {\n color: #5c6bc0;\n font-size: 14px;\n}\n\n.vs-panel-title {\n font-size: 15px;\n font-weight: 600;\n color: #333;\n}\n\n.vs-entity-badge {\n font-size: 11px;\n font-weight: 500;\n background: #e8eaf6;\n color: #5c6bc0;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.vs-close-btn {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: #999;\n font-size: 16px;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.vs-close-btn:hover {\n color: #333;\n}\n\n/* Panel Search */\n.vs-panel-search {\n padding: 12px 20px;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.vs-search-input {\n width: 100%;\n padding: 6px 12px 6px 32px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n font-size: 13px;\n background: #f5f5f5 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='%23999'%3E%3Cpath d='M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208z'/%3E%3C/svg%3E\") no-repeat 10px center;\n background-size: 14px;\n box-sizing: border-box;\n font-family: inherit;\n}\n\n.vs-search-input:focus {\n outline: none;\n border-color: #5c6bc0;\n}\n\n.vs-search-input::placeholder {\n color: #999;\n}\n\n/* Panel Body */\n.vs-panel-body {\n max-height: 400px;\n overflow-y: auto;\n}\n\n/* View Section */\n.vs-section {\n padding: 8px 0;\n}\n\n.vs-section-header {\n padding: 6px 20px;\n font-size: 11px;\n font-weight: 700;\n color: #999;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.vs-section-header i {\n font-size: 10px;\n}\n\n.vs-section-count {\n background: #e0e0e0;\n padding: 0 6px;\n border-radius: 8px;\n font-size: 10px;\n}\n\n/* View Card */\n.vs-card {\n padding: 10px 20px;\n cursor: pointer;\n transition: background 0.1s;\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.vs-card:hover {\n background: #f3f4fa;\n}\n\n.vs-card.active {\n background: #e8eaf6;\n border-left: 3px solid #5c6bc0;\n padding-left: 17px;\n}\n\n/* View Card Icon */\n.vs-card-icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n background: #f5f5f5;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #999;\n font-size: 14px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.vs-card-icon.active {\n background: #5c6bc0;\n color: white;\n}\n\n.vs-card-icon.shared {\n background: #f5f5f5;\n color: #999;\n}\n\n/* View Card Content */\n.vs-card-content {\n flex: 1;\n min-width: 0;\n padding-top: 4px;\n}\n\n.vs-card-name {\n font-size: 13px;\n font-weight: 500;\n color: #333;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.vs-card.active .vs-card-name {\n color: #5c6bc0;\n font-weight: 600;\n}\n\n.vs-default-badge {\n font-size: 9px;\n font-weight: 600;\n background: #e8f5e9;\n color: #43a047;\n padding: 1px 5px;\n border-radius: 6px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.vs-shared-badge {\n font-size: 9px;\n font-weight: 600;\n background: #e8eaf6;\n color: #5c6bc0;\n padding: 1px 5px;\n border-radius: 6px;\n}\n\n.vs-shared-badge.editable {\n background: #e8f5e9;\n color: #43a047;\n}\n\n.vs-card-desc {\n font-size: 12px;\n color: #999;\n margin-top: 2px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.vs-card-meta {\n display: flex;\n gap: 10px;\n margin-top: 4px;\n font-size: 11px;\n color: #999;\n}\n\n.vs-card-meta span {\n display: flex;\n align-items: center;\n gap: 3px;\n}\n\n.vs-card-meta i {\n font-size: 10px;\n}\n\n/* View Card Check */\n.vs-card-check {\n color: #5c6bc0;\n font-size: 12px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* View Card Actions (hover reveal) */\n.vs-card-actions {\n display: flex;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.vs-card:hover .vs-card-actions {\n opacity: 1;\n}\n\n.vs-action-btn {\n width: 26px;\n height: 26px;\n border-radius: 4px;\n border: none;\n background: none;\n cursor: pointer;\n color: #999;\n font-size: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.vs-action-btn:hover {\n background: #f5f5f5;\n color: #333;\n}\n\n/* Empty State */\n.vs-empty-message {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px;\n color: #999;\n font-size: 13px;\n}\n\n.vs-empty-message i {\n font-size: 16px;\n opacity: 0.5;\n}\n\n.vs-empty-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.vs-empty-text strong {\n color: #666;\n font-size: 13px;\n}\n\n.vs-empty-text span {\n font-size: 12px;\n}\n\n/* Loading */\n.vs-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: #999;\n font-size: 13px;\n text-align: center;\n}\n\n/* Panel Footer */\n.vs-panel-footer {\n padding: 12px 20px;\n border-top: 1px solid #f0f0f0;\n display: flex;\n gap: 8px;\n}\n\n.vs-panel-btn {\n flex: 1;\n padding: 8px 12px;\n border-radius: 4px;\n border: 1px solid #e0e0e0;\n background: #fff;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: #666;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.15s;\n font-family: inherit;\n text-align: center;\n}\n\n.vs-panel-btn:hover {\n border-color: #5c6bc0;\n color: #5c6bc0;\n}\n\n.vs-panel-btn.primary {\n background: #5c6bc0;\n color: white;\n border-color: #5c6bc0;\n}\n\n.vs-panel-btn.primary:hover {\n background: #4a59b0;\n}\n\n.vs-panel-btn i {\n font-size: 11px;\n}\n\n/* ========================================\n ICON BUTTONS (outside panel)\n ======================================== */\n\n.vs-icon-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: var(--background-alt, #f5f5f5);\n border: 1px solid var(--border-color, #e0e0e0);\n border-radius: 6px;\n cursor: pointer;\n color: var(--text-secondary, #666);\n transition: all 0.15s ease;\n}\n\n.vs-icon-btn:hover {\n background: var(--background-hover, #e8e8e8);\n border-color: var(--border-color-hover, #ccc);\n color: #5c6bc0;\n}\n\n.vs-icon-btn i {\n font-size: 12px;\n}\n\n.vs-export-btn:hover {\n color: #217346;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .vs-button {\n min-width: 100px;\n max-width: 180px;\n padding: 6px 10px;\n }\n\n .vs-panel {\n width: calc(100vw - 32px);\n max-width: 400px;\n }\n}\n"], encapsulation: 2 });
827
+ } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["/* ========================================\n VIEW SELECTOR - All classes prefixed vs-\n to avoid conflicts (ViewEncapsulation.None)\n ======================================== */\n\n/* Container */\n.vs-container {\n display: flex;\n align-items: center;\n gap: 4px;\n position: relative;\n}\n\n/* Backdrop for closing panel */\n.vs-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n background: transparent;\n}\n\n.vs-wrapper {\n position: relative;\n}\n\n/* Main Button */\n.vs-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n transition: all 0.15s ease;\n min-width: 140px;\n max-width: 280px;\n}\n\n.vs-button:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.vs-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.vs-button.open {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.vs-button.modified {\n border-color: var(--mj-status-warning);\n}\n\n.vs-btn-icon {\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n.vs-btn-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: left;\n}\n\n.vs-modified-dot {\n color: var(--mj-status-warning);\n font-weight: bold;\n font-size: 18px;\n line-height: 1;\n}\n\n.vs-arrow {\n color: var(--mj-text-muted);\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.vs-arrow.rotated {\n transform: rotate(180deg);\n}\n\n/* ========================================\n RICH VIEW PANEL\n Styles ported directly from prototype\n ======================================== */\n\n/* Reset inherited styles inside panel */\n.vs-panel,\n.vs-panel * {\n box-sizing: border-box;\n line-height: 1.5;\n text-align: left;\n}\n\n.vs-panel {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n width: 400px;\n max-width: calc(100vw - 40px);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.16);\n z-index: 1000;\n overflow: hidden;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n/* Panel Header */\n.vs-panel-header {\n padding: 16px 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.vs-header-icon {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.vs-panel-title {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.vs-entity-badge {\n font-size: 11px;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.vs-close-btn {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 16px;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.vs-close-btn:hover {\n color: var(--mj-text-primary);\n}\n\n/* Panel Search */\n.vs-panel-search {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.vs-search-input {\n width: 100%;\n padding: 6px 12px 6px 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n font-size: 13px;\n background: var(--mj-bg-surface-card) url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='%23999'%3E%3Cpath d='M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208z'/%3E%3C/svg%3E\") no-repeat 10px center;\n background-size: 14px;\n box-sizing: border-box;\n font-family: inherit;\n}\n\n.vs-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.vs-search-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n/* Panel Body */\n.vs-panel-body {\n max-height: 400px;\n overflow-y: auto;\n}\n\n/* View Section */\n.vs-section {\n padding: 8px 0;\n}\n\n.vs-section-header {\n padding: 6px 20px;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.vs-section-header i {\n font-size: 10px;\n}\n\n.vs-section-count {\n background: var(--mj-border-default);\n padding: 0 6px;\n border-radius: 8px;\n font-size: 10px;\n}\n\n/* View Card */\n.vs-card {\n padding: 10px 20px;\n cursor: pointer;\n transition: background 0.1s;\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.vs-card:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.vs-card.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n padding-left: 17px;\n}\n\n/* View Card Icon */\n.vs-card-icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.vs-card-icon.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.vs-card-icon.shared {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n}\n\n/* View Card Content */\n.vs-card-content {\n flex: 1;\n min-width: 0;\n padding-top: 4px;\n}\n\n.vs-card-name {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.vs-card.active .vs-card-name {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.vs-default-badge {\n font-size: 9px;\n font-weight: 600;\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n padding: 1px 5px;\n border-radius: 6px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.vs-shared-badge {\n font-size: 9px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n padding: 1px 5px;\n border-radius: 6px;\n}\n\n.vs-shared-badge.editable {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.vs-card-desc {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.vs-card-meta {\n display: flex;\n gap: 10px;\n margin-top: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.vs-card-meta span {\n display: flex;\n align-items: center;\n gap: 3px;\n}\n\n.vs-card-meta i {\n font-size: 10px;\n}\n\n/* View Card Check */\n.vs-card-check {\n color: var(--mj-brand-primary);\n font-size: 12px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* View Card Actions (hover reveal) */\n.vs-card-actions {\n display: flex;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.vs-card:hover .vs-card-actions {\n opacity: 1;\n}\n\n.vs-action-btn {\n width: 26px;\n height: 26px;\n border-radius: 4px;\n border: none;\n background: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.vs-action-btn:hover {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n}\n\n/* Empty State */\n.vs-empty-message {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.vs-empty-message i {\n font-size: 16px;\n opacity: 0.5;\n}\n\n.vs-empty-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.vs-empty-text strong {\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.vs-empty-text span {\n font-size: 12px;\n}\n\n/* Loading */\n.vs-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: var(--mj-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n/* Panel Footer */\n.vs-panel-footer {\n padding: 12px 20px;\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n gap: 8px;\n}\n\n.vs-panel-btn {\n flex: 1;\n padding: 8px 12px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.15s;\n font-family: inherit;\n text-align: center;\n}\n\n.vs-panel-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.vs-panel-btn.primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.vs-panel-btn.primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.vs-panel-btn i {\n font-size: 11px;\n}\n\n/* ========================================\n ICON BUTTONS (outside panel)\n ======================================== */\n\n.vs-icon-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.vs-icon-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-brand-primary);\n}\n\n.vs-icon-btn i {\n font-size: 12px;\n}\n\n.vs-export-btn:hover {\n color: var(--mj-status-success);\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .vs-button {\n min-width: 100px;\n max-width: 180px;\n padding: 6px 10px;\n }\n\n .vs-panel {\n width: calc(100vw - 32px);\n max-width: 400px;\n }\n}\n"], encapsulation: 2 });
828
828
  }
829
829
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewSelectorComponent, [{
830
830
  type: Component,
831
- args: [{ standalone: false, selector: 'mj-view-selector', encapsulation: ViewEncapsulation.None, template: "<div class=\"vs-container\">\n <!-- Backdrop for closing panel -->\n @if (isDropdownOpen) {\n <div class=\"vs-backdrop\" (click)=\"closeDropdown()\"></div>\n }\n\n <!-- Main View Selector Button -->\n <div class=\"vs-wrapper\">\n <button\n class=\"vs-button\"\n [class.modified]=\"viewModified\"\n [class.open]=\"isDropdownOpen\"\n (click)=\"toggleDropdown()\"\n [disabled]=\"isLoading\"\n title=\"Select a saved view\">\n <i class=\"fa-solid fa-layer-group vs-btn-icon\"></i>\n <span class=\"vs-btn-name\">{{ displayName }}</span>\n @if (viewModified) {\n <span class=\"vs-modified-dot\" title=\"View has unsaved changes\">\u2022</span>\n }\n <i class=\"fa-solid fa-chevron-down vs-arrow\" [class.rotated]=\"isDropdownOpen\"></i>\n </button>\n\n <!-- Rich View Panel -->\n @if (isDropdownOpen) {\n <div class=\"vs-panel\">\n <!-- Panel Header -->\n <div class=\"vs-panel-header\">\n <i class=\"fa-solid fa-table-list vs-header-icon\"></i>\n <span class=\"vs-panel-title\">Views</span>\n @if (entity) {\n <span class=\"vs-entity-badge\">{{ entity.DisplayNameOrName }}</span>\n }\n <button class=\"vs-close-btn\" (click)=\"closeDropdown()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Search -->\n <div class=\"vs-panel-search\">\n <input\n type=\"text\"\n class=\"vs-search-input\"\n placeholder=\"Search views...\"\n [(ngModel)]=\"searchText\"\n (keydown.escape)=\"searchText = ''\"\n />\n </div>\n\n <!-- Panel Body -->\n <div class=\"vs-panel-body\">\n <!-- Default Option -->\n <div class=\"vs-section\">\n <div\n class=\"vs-card\"\n [class.active]=\"!selectedViewId\"\n (click)=\"selectDefault()\">\n <div class=\"vs-card-icon\" [class.active]=\"!selectedViewId\">\n <i class=\"fa-solid fa-table\"></i>\n </div>\n <div class=\"vs-card-content\">\n <div class=\"vs-card-name\">(Default)</div>\n </div>\n @if (!selectedViewId) {\n <i class=\"fa-solid fa-check vs-card-check\"></i>\n }\n </div>\n </div>\n\n <!-- My Views Section -->\n @if (filteredMyViews.length > 0) {\n <div class=\"vs-section\">\n <div class=\"vs-section-header\">\n <i class=\"fa-solid fa-user\"></i>\n <span>My Views</span>\n <span class=\"vs-section-count\">{{ filteredMyViews.length }}</span>\n </div>\n @for (view of filteredMyViews; track view.id) {\n <div\n class=\"vs-card\"\n [class.active]=\"selectedViewId === view.id\"\n (click)=\"selectView(view)\">\n <div class=\"vs-card-icon\" [class.active]=\"selectedViewId === view.id\">\n <i class=\"fa-solid fa-table-list\"></i>\n </div>\n <div class=\"vs-card-content\">\n <div class=\"vs-card-name\">\n {{ view.name }}\n @if (view.isDefault) {\n <span class=\"vs-default-badge\">Default</span>\n }\n </div>\n @if (view.entity.Description) {\n <div class=\"vs-card-desc\">{{ view.entity.Description }}</div>\n }\n @if (getViewFilterCount(view) > 0 || getViewColumnCount(view) > 0 || getViewSortInfo(view)) {\n <div class=\"vs-card-meta\">\n @if (getViewFilterCount(view) > 0) {\n <span><i class=\"fa-solid fa-filter\"></i> {{ getViewFilterCount(view) }} filter{{ getViewFilterCount(view) !== 1 ? 's' : '' }}</span>\n }\n @if (getViewColumnCount(view) > 0) {\n <span><i class=\"fa-solid fa-table-columns\"></i> {{ getViewColumnCount(view) }} col{{ getViewColumnCount(view) !== 1 ? 's' : '' }}</span>\n }\n @if (getViewSortInfo(view)) {\n <span><i class=\"fa-solid fa-arrow-down-short-wide\"></i> {{ getViewSortInfo(view) }}</span>\n }\n </div>\n }\n </div>\n <div class=\"vs-card-actions\">\n <button\n class=\"vs-action-btn\"\n (click)=\"onDuplicateView(view.id, $event)\"\n title=\"Duplicate\">\n <i class=\"fa-regular fa-copy\"></i>\n </button>\n <button\n class=\"vs-action-btn\"\n (click)=\"onConfigureViewById(view.id, $event)\"\n title=\"Configure\">\n <i class=\"fa-solid fa-sliders\"></i>\n </button>\n <button\n class=\"vs-action-btn\"\n (click)=\"onOpenViewInTab(view.id, $event)\"\n title=\"Open in Tab\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n </button>\n </div>\n @if (selectedViewId === view.id) {\n <i class=\"fa-solid fa-check vs-card-check\"></i>\n }\n </div>\n }\n </div>\n }\n\n <!-- Shared Views Section -->\n @if (filteredSharedViews.length > 0) {\n <div class=\"vs-section\">\n <div class=\"vs-section-header\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n <span>Shared With Me</span>\n <span class=\"vs-section-count\">{{ filteredSharedViews.length }}</span>\n </div>\n @for (view of filteredSharedViews; track view.id) {\n <div\n class=\"vs-card\"\n [class.active]=\"selectedViewId === view.id\"\n (click)=\"selectView(view)\">\n <div class=\"vs-card-icon shared\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <div class=\"vs-card-content\">\n <div class=\"vs-card-name\">\n {{ view.name }}\n @if (!view.userCanEdit) {\n <span class=\"vs-shared-badge\">View Only</span>\n } @else {\n <span class=\"vs-shared-badge editable\">Can Edit</span>\n }\n </div>\n @if (view.entity.Description) {\n <div class=\"vs-card-desc\">{{ view.entity.Description }}</div>\n }\n @if (getViewFilterCount(view) > 0 || getViewColumnCount(view) > 0) {\n <div class=\"vs-card-meta\">\n @if (getViewFilterCount(view) > 0) {\n <span><i class=\"fa-solid fa-filter\"></i> {{ getViewFilterCount(view) }} filter{{ getViewFilterCount(view) !== 1 ? 's' : '' }}</span>\n }\n @if (getViewColumnCount(view) > 0) {\n <span><i class=\"fa-solid fa-table-columns\"></i> {{ getViewColumnCount(view) }} col{{ getViewColumnCount(view) !== 1 ? 's' : '' }}</span>\n }\n </div>\n }\n </div>\n <div class=\"vs-card-actions\">\n <button\n class=\"vs-action-btn\"\n (click)=\"onDuplicateView(view.id, $event)\"\n title=\"Duplicate as My View\">\n <i class=\"fa-regular fa-copy\"></i>\n </button>\n @if (view.userCanEdit) {\n <button\n class=\"vs-action-btn\"\n (click)=\"onConfigureViewById(view.id, $event)\"\n title=\"Configure\">\n <i class=\"fa-solid fa-sliders\"></i>\n </button>\n }\n </div>\n @if (selectedViewId === view.id) {\n <i class=\"fa-solid fa-check vs-card-check\"></i>\n }\n </div>\n }\n </div>\n }\n\n <!-- No Views Message -->\n @if (!hasViews && !isLoading) {\n <div class=\"vs-empty-message\">\n <i class=\"fa-solid fa-bookmark\"></i>\n <div class=\"vs-empty-text\">\n <strong>No saved views yet</strong>\n <span>Save your current configuration as a view</span>\n </div>\n </div>\n }\n\n <!-- No Search Results -->\n @if (hasViews && filteredMyViews.length === 0 && filteredSharedViews.length === 0 && searchText) {\n <div class=\"vs-empty-message\">\n <i class=\"fa-solid fa-search\"></i>\n <span>No views match \"{{ searchText }}\"</span>\n </div>\n }\n\n <!-- Loading Indicator -->\n @if (isLoading) {\n <div class=\"vs-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading views...</span>\n </div>\n }\n </div>\n\n <!-- Panel Footer -->\n <div class=\"vs-panel-footer\">\n <button\n class=\"vs-panel-btn primary\"\n (click)=\"onQuickSave()\"\n title=\"Save current view configuration\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New View</span>\n </button>\n <button\n class=\"vs-panel-btn\"\n (click)=\"onResetToDefault()\"\n title=\"Reset to default view\">\n <i class=\"fa-solid fa-arrow-rotate-left\"></i>\n <span>Reset to Default</span>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Open in Tab Button (only visible when a view is selected) -->\n @if (selectedViewId) {\n <button\n class=\"vs-icon-btn\"\n (click)=\"onOpenInTab()\"\n title=\"Open this view in a new tab\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n </button>\n }\n\n <!-- Configure View Button -->\n <button\n class=\"vs-icon-btn\"\n (click)=\"onConfigureView()\"\n title=\"Configure view settings (columns, filters, sorting)\">\n <i class=\"fa-solid fa-sliders-h\"></i>\n </button>\n\n <!-- Create New Record Button -->\n <button\n class=\"vs-icon-btn\"\n (click)=\"onCreateNewRecord()\"\n title=\"Create new record\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n\n <!-- Export Button -->\n <button\n class=\"vs-icon-btn vs-export-btn\"\n (click)=\"onExport()\"\n title=\"Export to Excel\">\n <i class=\"fa-solid fa-file-excel\"></i>\n </button>\n</div>\n", styles: ["/* ========================================\n VIEW SELECTOR - All classes prefixed vs-\n to avoid conflicts (ViewEncapsulation.None)\n ======================================== */\n\n/* Container */\n.vs-container {\n display: flex;\n align-items: center;\n gap: 4px;\n position: relative;\n}\n\n/* Backdrop for closing panel */\n.vs-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n background: transparent;\n}\n\n.vs-wrapper {\n position: relative;\n}\n\n/* Main Button */\n.vs-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: var(--background-alt, #f5f5f5);\n border: 1px solid var(--border-color, #e0e0e0);\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--text-primary, #333);\n transition: all 0.15s ease;\n min-width: 140px;\n max-width: 280px;\n}\n\n.vs-button:hover {\n border-color: #5c6bc0;\n background: #f3f4fa;\n}\n\n.vs-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.vs-button.open {\n border-color: #5c6bc0;\n background: #f3f4fa;\n}\n\n.vs-button.modified {\n border-color: #f57c00;\n}\n\n.vs-btn-icon {\n color: #5c6bc0;\n font-size: 12px;\n}\n\n.vs-btn-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: left;\n}\n\n.vs-modified-dot {\n color: #f57c00;\n font-weight: bold;\n font-size: 18px;\n line-height: 1;\n}\n\n.vs-arrow {\n color: #999;\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.vs-arrow.rotated {\n transform: rotate(180deg);\n}\n\n/* ========================================\n RICH VIEW PANEL\n Styles ported directly from prototype\n ======================================== */\n\n/* Reset inherited styles inside panel */\n.vs-panel,\n.vs-panel * {\n box-sizing: border-box;\n line-height: 1.5;\n text-align: left;\n}\n\n.vs-panel {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n width: 400px;\n max-width: calc(100vw - 40px);\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.16);\n z-index: 1000;\n overflow: hidden;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n color: #333;\n}\n\n/* Panel Header */\n.vs-panel-header {\n padding: 16px 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.vs-header-icon {\n color: #5c6bc0;\n font-size: 14px;\n}\n\n.vs-panel-title {\n font-size: 15px;\n font-weight: 600;\n color: #333;\n}\n\n.vs-entity-badge {\n font-size: 11px;\n font-weight: 500;\n background: #e8eaf6;\n color: #5c6bc0;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.vs-close-btn {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: #999;\n font-size: 16px;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.vs-close-btn:hover {\n color: #333;\n}\n\n/* Panel Search */\n.vs-panel-search {\n padding: 12px 20px;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.vs-search-input {\n width: 100%;\n padding: 6px 12px 6px 32px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n font-size: 13px;\n background: #f5f5f5 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='%23999'%3E%3Cpath d='M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208z'/%3E%3C/svg%3E\") no-repeat 10px center;\n background-size: 14px;\n box-sizing: border-box;\n font-family: inherit;\n}\n\n.vs-search-input:focus {\n outline: none;\n border-color: #5c6bc0;\n}\n\n.vs-search-input::placeholder {\n color: #999;\n}\n\n/* Panel Body */\n.vs-panel-body {\n max-height: 400px;\n overflow-y: auto;\n}\n\n/* View Section */\n.vs-section {\n padding: 8px 0;\n}\n\n.vs-section-header {\n padding: 6px 20px;\n font-size: 11px;\n font-weight: 700;\n color: #999;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.vs-section-header i {\n font-size: 10px;\n}\n\n.vs-section-count {\n background: #e0e0e0;\n padding: 0 6px;\n border-radius: 8px;\n font-size: 10px;\n}\n\n/* View Card */\n.vs-card {\n padding: 10px 20px;\n cursor: pointer;\n transition: background 0.1s;\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.vs-card:hover {\n background: #f3f4fa;\n}\n\n.vs-card.active {\n background: #e8eaf6;\n border-left: 3px solid #5c6bc0;\n padding-left: 17px;\n}\n\n/* View Card Icon */\n.vs-card-icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n background: #f5f5f5;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #999;\n font-size: 14px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.vs-card-icon.active {\n background: #5c6bc0;\n color: white;\n}\n\n.vs-card-icon.shared {\n background: #f5f5f5;\n color: #999;\n}\n\n/* View Card Content */\n.vs-card-content {\n flex: 1;\n min-width: 0;\n padding-top: 4px;\n}\n\n.vs-card-name {\n font-size: 13px;\n font-weight: 500;\n color: #333;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.vs-card.active .vs-card-name {\n color: #5c6bc0;\n font-weight: 600;\n}\n\n.vs-default-badge {\n font-size: 9px;\n font-weight: 600;\n background: #e8f5e9;\n color: #43a047;\n padding: 1px 5px;\n border-radius: 6px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.vs-shared-badge {\n font-size: 9px;\n font-weight: 600;\n background: #e8eaf6;\n color: #5c6bc0;\n padding: 1px 5px;\n border-radius: 6px;\n}\n\n.vs-shared-badge.editable {\n background: #e8f5e9;\n color: #43a047;\n}\n\n.vs-card-desc {\n font-size: 12px;\n color: #999;\n margin-top: 2px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.vs-card-meta {\n display: flex;\n gap: 10px;\n margin-top: 4px;\n font-size: 11px;\n color: #999;\n}\n\n.vs-card-meta span {\n display: flex;\n align-items: center;\n gap: 3px;\n}\n\n.vs-card-meta i {\n font-size: 10px;\n}\n\n/* View Card Check */\n.vs-card-check {\n color: #5c6bc0;\n font-size: 12px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* View Card Actions (hover reveal) */\n.vs-card-actions {\n display: flex;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.vs-card:hover .vs-card-actions {\n opacity: 1;\n}\n\n.vs-action-btn {\n width: 26px;\n height: 26px;\n border-radius: 4px;\n border: none;\n background: none;\n cursor: pointer;\n color: #999;\n font-size: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.vs-action-btn:hover {\n background: #f5f5f5;\n color: #333;\n}\n\n/* Empty State */\n.vs-empty-message {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px;\n color: #999;\n font-size: 13px;\n}\n\n.vs-empty-message i {\n font-size: 16px;\n opacity: 0.5;\n}\n\n.vs-empty-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.vs-empty-text strong {\n color: #666;\n font-size: 13px;\n}\n\n.vs-empty-text span {\n font-size: 12px;\n}\n\n/* Loading */\n.vs-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: #999;\n font-size: 13px;\n text-align: center;\n}\n\n/* Panel Footer */\n.vs-panel-footer {\n padding: 12px 20px;\n border-top: 1px solid #f0f0f0;\n display: flex;\n gap: 8px;\n}\n\n.vs-panel-btn {\n flex: 1;\n padding: 8px 12px;\n border-radius: 4px;\n border: 1px solid #e0e0e0;\n background: #fff;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: #666;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.15s;\n font-family: inherit;\n text-align: center;\n}\n\n.vs-panel-btn:hover {\n border-color: #5c6bc0;\n color: #5c6bc0;\n}\n\n.vs-panel-btn.primary {\n background: #5c6bc0;\n color: white;\n border-color: #5c6bc0;\n}\n\n.vs-panel-btn.primary:hover {\n background: #4a59b0;\n}\n\n.vs-panel-btn i {\n font-size: 11px;\n}\n\n/* ========================================\n ICON BUTTONS (outside panel)\n ======================================== */\n\n.vs-icon-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: var(--background-alt, #f5f5f5);\n border: 1px solid var(--border-color, #e0e0e0);\n border-radius: 6px;\n cursor: pointer;\n color: var(--text-secondary, #666);\n transition: all 0.15s ease;\n}\n\n.vs-icon-btn:hover {\n background: var(--background-hover, #e8e8e8);\n border-color: var(--border-color-hover, #ccc);\n color: #5c6bc0;\n}\n\n.vs-icon-btn i {\n font-size: 12px;\n}\n\n.vs-export-btn:hover {\n color: #217346;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .vs-button {\n min-width: 100px;\n max-width: 180px;\n padding: 6px 10px;\n }\n\n .vs-panel {\n width: calc(100vw - 32px);\n max-width: 400px;\n }\n}\n"] }]
831
+ args: [{ standalone: false, selector: 'mj-view-selector', encapsulation: ViewEncapsulation.None, template: "<div class=\"vs-container\">\n <!-- Backdrop for closing panel -->\n @if (isDropdownOpen) {\n <div class=\"vs-backdrop\" (click)=\"closeDropdown()\"></div>\n }\n\n <!-- Main View Selector Button -->\n <div class=\"vs-wrapper\">\n <button\n class=\"vs-button\"\n [class.modified]=\"viewModified\"\n [class.open]=\"isDropdownOpen\"\n (click)=\"toggleDropdown()\"\n [disabled]=\"isLoading\"\n title=\"Select a saved view\">\n <i class=\"fa-solid fa-layer-group vs-btn-icon\"></i>\n <span class=\"vs-btn-name\">{{ displayName }}</span>\n @if (viewModified) {\n <span class=\"vs-modified-dot\" title=\"View has unsaved changes\">\u2022</span>\n }\n <i class=\"fa-solid fa-chevron-down vs-arrow\" [class.rotated]=\"isDropdownOpen\"></i>\n </button>\n\n <!-- Rich View Panel -->\n @if (isDropdownOpen) {\n <div class=\"vs-panel\">\n <!-- Panel Header -->\n <div class=\"vs-panel-header\">\n <i class=\"fa-solid fa-table-list vs-header-icon\"></i>\n <span class=\"vs-panel-title\">Views</span>\n @if (entity) {\n <span class=\"vs-entity-badge\">{{ entity.DisplayNameOrName }}</span>\n }\n <button class=\"vs-close-btn\" (click)=\"closeDropdown()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Search -->\n <div class=\"vs-panel-search\">\n <input\n type=\"text\"\n class=\"vs-search-input\"\n placeholder=\"Search views...\"\n [(ngModel)]=\"searchText\"\n (keydown.escape)=\"searchText = ''\"\n />\n </div>\n\n <!-- Panel Body -->\n <div class=\"vs-panel-body\">\n <!-- Default Option -->\n <div class=\"vs-section\">\n <div\n class=\"vs-card\"\n [class.active]=\"!selectedViewId\"\n (click)=\"selectDefault()\">\n <div class=\"vs-card-icon\" [class.active]=\"!selectedViewId\">\n <i class=\"fa-solid fa-table\"></i>\n </div>\n <div class=\"vs-card-content\">\n <div class=\"vs-card-name\">(Default)</div>\n </div>\n @if (!selectedViewId) {\n <i class=\"fa-solid fa-check vs-card-check\"></i>\n }\n </div>\n </div>\n\n <!-- My Views Section -->\n @if (filteredMyViews.length > 0) {\n <div class=\"vs-section\">\n <div class=\"vs-section-header\">\n <i class=\"fa-solid fa-user\"></i>\n <span>My Views</span>\n <span class=\"vs-section-count\">{{ filteredMyViews.length }}</span>\n </div>\n @for (view of filteredMyViews; track view.id) {\n <div\n class=\"vs-card\"\n [class.active]=\"selectedViewId === view.id\"\n (click)=\"selectView(view)\">\n <div class=\"vs-card-icon\" [class.active]=\"selectedViewId === view.id\">\n <i class=\"fa-solid fa-table-list\"></i>\n </div>\n <div class=\"vs-card-content\">\n <div class=\"vs-card-name\">\n {{ view.name }}\n @if (view.isDefault) {\n <span class=\"vs-default-badge\">Default</span>\n }\n </div>\n @if (view.entity.Description) {\n <div class=\"vs-card-desc\">{{ view.entity.Description }}</div>\n }\n @if (getViewFilterCount(view) > 0 || getViewColumnCount(view) > 0 || getViewSortInfo(view)) {\n <div class=\"vs-card-meta\">\n @if (getViewFilterCount(view) > 0) {\n <span><i class=\"fa-solid fa-filter\"></i> {{ getViewFilterCount(view) }} filter{{ getViewFilterCount(view) !== 1 ? 's' : '' }}</span>\n }\n @if (getViewColumnCount(view) > 0) {\n <span><i class=\"fa-solid fa-table-columns\"></i> {{ getViewColumnCount(view) }} col{{ getViewColumnCount(view) !== 1 ? 's' : '' }}</span>\n }\n @if (getViewSortInfo(view)) {\n <span><i class=\"fa-solid fa-arrow-down-short-wide\"></i> {{ getViewSortInfo(view) }}</span>\n }\n </div>\n }\n </div>\n <div class=\"vs-card-actions\">\n <button\n class=\"vs-action-btn\"\n (click)=\"onDuplicateView(view.id, $event)\"\n title=\"Duplicate\">\n <i class=\"fa-regular fa-copy\"></i>\n </button>\n <button\n class=\"vs-action-btn\"\n (click)=\"onConfigureViewById(view.id, $event)\"\n title=\"Configure\">\n <i class=\"fa-solid fa-sliders\"></i>\n </button>\n <button\n class=\"vs-action-btn\"\n (click)=\"onOpenViewInTab(view.id, $event)\"\n title=\"Open in Tab\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n </button>\n </div>\n @if (selectedViewId === view.id) {\n <i class=\"fa-solid fa-check vs-card-check\"></i>\n }\n </div>\n }\n </div>\n }\n\n <!-- Shared Views Section -->\n @if (filteredSharedViews.length > 0) {\n <div class=\"vs-section\">\n <div class=\"vs-section-header\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n <span>Shared With Me</span>\n <span class=\"vs-section-count\">{{ filteredSharedViews.length }}</span>\n </div>\n @for (view of filteredSharedViews; track view.id) {\n <div\n class=\"vs-card\"\n [class.active]=\"selectedViewId === view.id\"\n (click)=\"selectView(view)\">\n <div class=\"vs-card-icon shared\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <div class=\"vs-card-content\">\n <div class=\"vs-card-name\">\n {{ view.name }}\n @if (!view.userCanEdit) {\n <span class=\"vs-shared-badge\">View Only</span>\n } @else {\n <span class=\"vs-shared-badge editable\">Can Edit</span>\n }\n </div>\n @if (view.entity.Description) {\n <div class=\"vs-card-desc\">{{ view.entity.Description }}</div>\n }\n @if (getViewFilterCount(view) > 0 || getViewColumnCount(view) > 0) {\n <div class=\"vs-card-meta\">\n @if (getViewFilterCount(view) > 0) {\n <span><i class=\"fa-solid fa-filter\"></i> {{ getViewFilterCount(view) }} filter{{ getViewFilterCount(view) !== 1 ? 's' : '' }}</span>\n }\n @if (getViewColumnCount(view) > 0) {\n <span><i class=\"fa-solid fa-table-columns\"></i> {{ getViewColumnCount(view) }} col{{ getViewColumnCount(view) !== 1 ? 's' : '' }}</span>\n }\n </div>\n }\n </div>\n <div class=\"vs-card-actions\">\n <button\n class=\"vs-action-btn\"\n (click)=\"onDuplicateView(view.id, $event)\"\n title=\"Duplicate as My View\">\n <i class=\"fa-regular fa-copy\"></i>\n </button>\n @if (view.userCanEdit) {\n <button\n class=\"vs-action-btn\"\n (click)=\"onConfigureViewById(view.id, $event)\"\n title=\"Configure\">\n <i class=\"fa-solid fa-sliders\"></i>\n </button>\n }\n </div>\n @if (selectedViewId === view.id) {\n <i class=\"fa-solid fa-check vs-card-check\"></i>\n }\n </div>\n }\n </div>\n }\n\n <!-- No Views Message -->\n @if (!hasViews && !isLoading) {\n <div class=\"vs-empty-message\">\n <i class=\"fa-solid fa-bookmark\"></i>\n <div class=\"vs-empty-text\">\n <strong>No saved views yet</strong>\n <span>Save your current configuration as a view</span>\n </div>\n </div>\n }\n\n <!-- No Search Results -->\n @if (hasViews && filteredMyViews.length === 0 && filteredSharedViews.length === 0 && searchText) {\n <div class=\"vs-empty-message\">\n <i class=\"fa-solid fa-search\"></i>\n <span>No views match \"{{ searchText }}\"</span>\n </div>\n }\n\n <!-- Loading Indicator -->\n @if (isLoading) {\n <div class=\"vs-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading views...</span>\n </div>\n }\n </div>\n\n <!-- Panel Footer -->\n <div class=\"vs-panel-footer\">\n <button\n class=\"vs-panel-btn primary\"\n (click)=\"onQuickSave()\"\n title=\"Save current view configuration\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>New View</span>\n </button>\n <button\n class=\"vs-panel-btn\"\n (click)=\"onResetToDefault()\"\n title=\"Reset to default view\">\n <i class=\"fa-solid fa-arrow-rotate-left\"></i>\n <span>Reset to Default</span>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Open in Tab Button (only visible when a view is selected) -->\n @if (selectedViewId) {\n <button\n class=\"vs-icon-btn\"\n (click)=\"onOpenInTab()\"\n title=\"Open this view in a new tab\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n </button>\n }\n\n <!-- Configure View Button -->\n <button\n class=\"vs-icon-btn\"\n (click)=\"onConfigureView()\"\n title=\"Configure view settings (columns, filters, sorting)\">\n <i class=\"fa-solid fa-sliders-h\"></i>\n </button>\n\n <!-- Create New Record Button -->\n <button\n class=\"vs-icon-btn\"\n (click)=\"onCreateNewRecord()\"\n title=\"Create new record\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n\n <!-- Export Button -->\n <button\n class=\"vs-icon-btn vs-export-btn\"\n (click)=\"onExport()\"\n title=\"Export to Excel\">\n <i class=\"fa-solid fa-file-excel\"></i>\n </button>\n</div>\n", styles: ["/* ========================================\n VIEW SELECTOR - All classes prefixed vs-\n to avoid conflicts (ViewEncapsulation.None)\n ======================================== */\n\n/* Container */\n.vs-container {\n display: flex;\n align-items: center;\n gap: 4px;\n position: relative;\n}\n\n/* Backdrop for closing panel */\n.vs-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n background: transparent;\n}\n\n.vs-wrapper {\n position: relative;\n}\n\n/* Main Button */\n.vs-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n transition: all 0.15s ease;\n min-width: 140px;\n max-width: 280px;\n}\n\n.vs-button:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.vs-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.vs-button.open {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.vs-button.modified {\n border-color: var(--mj-status-warning);\n}\n\n.vs-btn-icon {\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n.vs-btn-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: left;\n}\n\n.vs-modified-dot {\n color: var(--mj-status-warning);\n font-weight: bold;\n font-size: 18px;\n line-height: 1;\n}\n\n.vs-arrow {\n color: var(--mj-text-muted);\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.vs-arrow.rotated {\n transform: rotate(180deg);\n}\n\n/* ========================================\n RICH VIEW PANEL\n Styles ported directly from prototype\n ======================================== */\n\n/* Reset inherited styles inside panel */\n.vs-panel,\n.vs-panel * {\n box-sizing: border-box;\n line-height: 1.5;\n text-align: left;\n}\n\n.vs-panel {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n width: 400px;\n max-width: calc(100vw - 40px);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.16);\n z-index: 1000;\n overflow: hidden;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n/* Panel Header */\n.vs-panel-header {\n padding: 16px 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.vs-header-icon {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.vs-panel-title {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.vs-entity-badge {\n font-size: 11px;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.vs-close-btn {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 16px;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.vs-close-btn:hover {\n color: var(--mj-text-primary);\n}\n\n/* Panel Search */\n.vs-panel-search {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.vs-search-input {\n width: 100%;\n padding: 6px 12px 6px 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n font-size: 13px;\n background: var(--mj-bg-surface-card) url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='%23999'%3E%3Cpath d='M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208z'/%3E%3C/svg%3E\") no-repeat 10px center;\n background-size: 14px;\n box-sizing: border-box;\n font-family: inherit;\n}\n\n.vs-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.vs-search-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n/* Panel Body */\n.vs-panel-body {\n max-height: 400px;\n overflow-y: auto;\n}\n\n/* View Section */\n.vs-section {\n padding: 8px 0;\n}\n\n.vs-section-header {\n padding: 6px 20px;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.vs-section-header i {\n font-size: 10px;\n}\n\n.vs-section-count {\n background: var(--mj-border-default);\n padding: 0 6px;\n border-radius: 8px;\n font-size: 10px;\n}\n\n/* View Card */\n.vs-card {\n padding: 10px 20px;\n cursor: pointer;\n transition: background 0.1s;\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.vs-card:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.vs-card.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n padding-left: 17px;\n}\n\n/* View Card Icon */\n.vs-card-icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.vs-card-icon.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.vs-card-icon.shared {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n}\n\n/* View Card Content */\n.vs-card-content {\n flex: 1;\n min-width: 0;\n padding-top: 4px;\n}\n\n.vs-card-name {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.vs-card.active .vs-card-name {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.vs-default-badge {\n font-size: 9px;\n font-weight: 600;\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n padding: 1px 5px;\n border-radius: 6px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.vs-shared-badge {\n font-size: 9px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n padding: 1px 5px;\n border-radius: 6px;\n}\n\n.vs-shared-badge.editable {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.vs-card-desc {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.vs-card-meta {\n display: flex;\n gap: 10px;\n margin-top: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.vs-card-meta span {\n display: flex;\n align-items: center;\n gap: 3px;\n}\n\n.vs-card-meta i {\n font-size: 10px;\n}\n\n/* View Card Check */\n.vs-card-check {\n color: var(--mj-brand-primary);\n font-size: 12px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* View Card Actions (hover reveal) */\n.vs-card-actions {\n display: flex;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.vs-card:hover .vs-card-actions {\n opacity: 1;\n}\n\n.vs-action-btn {\n width: 26px;\n height: 26px;\n border-radius: 4px;\n border: none;\n background: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.vs-action-btn:hover {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n}\n\n/* Empty State */\n.vs-empty-message {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.vs-empty-message i {\n font-size: 16px;\n opacity: 0.5;\n}\n\n.vs-empty-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.vs-empty-text strong {\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.vs-empty-text span {\n font-size: 12px;\n}\n\n/* Loading */\n.vs-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: var(--mj-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n/* Panel Footer */\n.vs-panel-footer {\n padding: 12px 20px;\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n gap: 8px;\n}\n\n.vs-panel-btn {\n flex: 1;\n padding: 8px 12px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.15s;\n font-family: inherit;\n text-align: center;\n}\n\n.vs-panel-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.vs-panel-btn.primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.vs-panel-btn.primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.vs-panel-btn i {\n font-size: 11px;\n}\n\n/* ========================================\n ICON BUTTONS (outside panel)\n ======================================== */\n\n.vs-icon-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.vs-icon-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-brand-primary);\n}\n\n.vs-icon-btn i {\n font-size: 12px;\n}\n\n.vs-export-btn:hover {\n color: var(--mj-status-success);\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .vs-button {\n min-width: 100px;\n max-width: 180px;\n padding: 6px 10px;\n }\n\n .vs-panel {\n width: calc(100vw - 32px);\n max-width: 400px;\n }\n}\n"] }]
832
832
  }], () => [{ type: i0.ChangeDetectorRef }], { entity: [{
833
833
  type: Input
834
834
  }], selectedViewId: [{
@@ -4,7 +4,7 @@ import { BaseDashboard, NavigationService } from '@memberjunction/ng-shared';
4
4
  import { RecentAccessService } from '@memberjunction/ng-shared-generic';
5
5
  import { EntityInfo } from '@memberjunction/core';
6
6
  import { ResourceData } from '@memberjunction/core-entities';
7
- import { RecordSelectedEvent, RecordOpenedEvent, DataLoadedEvent, FilteredCountChangedEvent, EntityViewerConfig, EntityViewMode, NavigateToRelatedEvent, EntityViewerComponent, ViewGridState, GridStateChangedEvent, ViewSaveEvent, ViewConfigPanelComponent, ViewConfigSummary, QuickSaveEvent, DuplicateViewEvent, SharedViewAction } from '@memberjunction/ng-entity-viewer';
7
+ import { RecordSelectedEvent, RecordOpenedEvent, DataLoadedEvent, FilteredCountChangedEvent, EntityViewerConfig, EntityViewMode, NavigateToRelatedEvent, EntityViewerComponent, ViewGridState, GridStateChangedEvent, ViewSaveEvent, ViewConfigPanelComponent, ViewConfigSummary, QuickSaveEvent, QuickSaveAdvancedEvent, DuplicateViewEvent, SharedViewAction } from '@memberjunction/ng-entity-viewer';
8
8
  import { ViewSelectedEvent, SaveViewRequestedEvent, ViewSelectorComponent } from './components/view-selector/view-selector.component';
9
9
  import { CompositeFilterDescriptor, FilterFieldInfo } from '@memberjunction/ng-filter-builder';
10
10
  import { MJUserViewEntityExtended } from '@memberjunction/core-entities';
@@ -93,6 +93,9 @@ export declare class DataExplorerDashboardComponent extends BaseDashboard implem
93
93
  selectedRecords: Record<string, unknown>[];
94
94
  showQuickSaveDialog: boolean;
95
95
  quickSaveSummary: ViewConfigSummary | null;
96
+ pendingNewViewName: string;
97
+ pendingNewViewDescription: string;
98
+ pendingNewViewIsShared: boolean;
96
99
  showDuplicateDialog: boolean;
97
100
  duplicateSourceViewName: string;
98
101
  duplicateSummary: ViewConfigSummary | null;
@@ -330,6 +333,7 @@ export declare class DataExplorerDashboardComponent extends BaseDashboard implem
330
333
  * Close the view configuration panel
331
334
  */
332
335
  onCloseViewConfigPanel(): void;
336
+ private clearPendingNewViewState;
333
337
  /**
334
338
  * Handle request to open filter dialog from view config panel
335
339
  * The dialog is rendered at dashboard level to allow full viewport width
@@ -409,7 +413,7 @@ export declare class DataExplorerDashboardComponent extends BaseDashboard implem
409
413
  /**
410
414
  * Handle quick save "Open Advanced" - close dialog and open full config panel
411
415
  */
412
- onQuickSaveOpenAdvanced(): void;
416
+ onQuickSaveOpenAdvanced(event: QuickSaveAdvancedEvent): void;
413
417
  /**
414
418
  * Handle duplicate view request (F-005)
415
419
  * Opens the Duplicate View Dialog so user can choose a name for the copy