@memberjunction/ng-dashboards 4.0.0 → 4.2.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 (242) hide show
  1. package/README.md +102 -339
  2. package/dist/AI/components/agents/agent-configuration.component.js +1 -1
  3. package/dist/AI/components/agents/agent-editor.component.js +1 -1
  4. package/dist/AI/components/agents/agent-filter-panel.component.js +1 -1
  5. package/dist/AI/components/charts/performance-heatmap.component.js +1 -1
  6. package/dist/AI/components/charts/time-series-chart.component.js +1 -1
  7. package/dist/AI/components/execution-monitoring.component.js +1 -1
  8. package/dist/AI/components/models/model-management.component.js +1 -1
  9. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +1 -1
  10. package/dist/AI/components/prompts/prompt-filter-panel.component.js +1 -1
  11. package/dist/AI/components/prompts/prompt-management.component.js +1 -1
  12. package/dist/AI/components/prompts/prompt-version-control.component.js +1 -1
  13. package/dist/AI/components/system/system-config-filter-panel.component.js +1 -1
  14. package/dist/AI/components/system/system-configuration.component.js +1 -1
  15. package/dist/AI/components/widgets/kpi-card.component.js +1 -1
  16. package/dist/AI/components/widgets/live-execution-widget.component.js +1 -1
  17. package/dist/APIKeys/api-applications-panel.component.js +1 -1
  18. package/dist/APIKeys/api-key-create-dialog.component.js +1 -1
  19. package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
  20. package/dist/APIKeys/api-key-list.component.js +1 -1
  21. package/dist/APIKeys/api-keys-resource.component.js +1 -1
  22. package/dist/APIKeys/api-scopes-panel.component.js +1 -1
  23. package/dist/APIKeys/api-usage-panel.component.js +1 -1
  24. package/dist/Actions/components/actions-list-view.component.js +1 -1
  25. package/dist/Actions/components/actions-overview.component.js +1 -1
  26. package/dist/Actions/components/categories-list-view.component.js +1 -1
  27. package/dist/Actions/components/code-management.component.js +1 -1
  28. package/dist/Actions/components/entity-integration.component.js +1 -1
  29. package/dist/Actions/components/execution-monitoring.component.js +1 -1
  30. package/dist/Actions/components/executions-list-view.component.js +1 -1
  31. package/dist/Actions/components/explorer/action-breadcrumb.component.js +1 -1
  32. package/dist/Actions/components/explorer/action-card.component.js +1 -1
  33. package/dist/Actions/components/explorer/action-explorer.component.js +1 -1
  34. package/dist/Actions/components/explorer/action-list-item.component.js +1 -1
  35. package/dist/Actions/components/explorer/action-toolbar.component.js +1 -1
  36. package/dist/Actions/components/explorer/action-tree-panel.component.js +1 -1
  37. package/dist/Actions/components/explorer/new-action-panel.component.js +1 -1
  38. package/dist/Actions/components/explorer/new-category-panel.component.js +1 -1
  39. package/dist/Actions/components/scheduled-actions.component.js +1 -1
  40. package/dist/Actions/components/security-permissions.component.js +1 -1
  41. package/dist/Communication/communication-dashboard.component.js +1 -1
  42. package/dist/Communication/communication-logs-resource.component.js +1 -1
  43. package/dist/Communication/communication-monitor-resource.component.js +1 -1
  44. package/dist/Communication/communication-providers-resource.component.js +1 -1
  45. package/dist/Communication/communication-runs-resource.component.js +1 -1
  46. package/dist/Communication/communication-templates-resource.component.js +1 -1
  47. package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -1
  48. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +1 -1
  49. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -1
  50. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +1 -1
  51. package/dist/ComponentStudio/components/browser/component-browser.component.js +1 -1
  52. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +1 -1
  53. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +1 -1
  54. package/dist/ComponentStudio/components/editors/requirements-editor.component.js +1 -1
  55. package/dist/ComponentStudio/components/editors/spec-editor.component.js +1 -1
  56. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +1 -1
  57. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +1 -1
  58. package/dist/ComponentStudio/components/text-import-dialog.component.js +1 -1
  59. package/dist/ComponentStudio/components/workspace/component-preview.component.js +1 -1
  60. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +1 -1
  61. package/dist/Credentials/components/credentials-audit-resource.component.js +1 -1
  62. package/dist/Credentials/components/credentials-categories-resource.component.js +1 -1
  63. package/dist/Credentials/components/credentials-list-resource.component.js +1 -1
  64. package/dist/Credentials/components/credentials-overview-resource.component.js +1 -1
  65. package/dist/Credentials/components/credentials-types-resource.component.js +1 -1
  66. package/dist/Credentials/credentials-dashboard.component.js +1 -1
  67. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +1 -1
  68. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +1 -1
  69. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +1 -1
  70. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +1 -1
  71. package/dist/DataExplorer/components/view-selector/view-selector.component.js +1 -1
  72. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +2 -0
  73. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  74. package/dist/DataExplorer/data-explorer-dashboard.component.js +35 -11
  75. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  76. package/dist/DataExplorer/data-explorer-resource.component.js +1 -1
  77. package/dist/EntityAdmin/entity-admin-dashboard.component.js +1 -1
  78. package/dist/Home/home-application.d.ts +109 -22
  79. package/dist/Home/home-application.d.ts.map +1 -1
  80. package/dist/Home/home-application.js +351 -66
  81. package/dist/Home/home-application.js.map +1 -1
  82. package/dist/Home/home-dashboard.component.d.ts +48 -8
  83. package/dist/Home/home-dashboard.component.d.ts.map +1 -1
  84. package/dist/Home/home-dashboard.component.js +140 -62
  85. package/dist/Home/home-dashboard.component.js.map +1 -1
  86. package/dist/Lists/components/lists-browse-resource.component.js +1 -1
  87. package/dist/Lists/components/lists-categories-resource.component.js +1 -1
  88. package/dist/Lists/components/lists-my-lists-resource.component.js +1 -1
  89. package/dist/Lists/components/lists-operations-resource.component.js +1 -1
  90. package/dist/Lists/components/venn-diagram/venn-diagram.component.js +1 -1
  91. package/dist/MCP/components/mcp-connection-dialog.component.js +1 -1
  92. package/dist/MCP/components/mcp-log-detail-panel.component.js +1 -1
  93. package/dist/MCP/components/mcp-server-dialog.component.js +1 -1
  94. package/dist/MCP/components/mcp-test-tool-dialog.component.js +1 -1
  95. package/dist/MCP/mcp-dashboard.component.js +1 -1
  96. package/dist/MCP/mcp-filter-panel.component.js +1 -1
  97. package/dist/MCP/mcp-resource.component.js +1 -1
  98. package/dist/QueryBrowser/query-browser-resource.component.js +1 -1
  99. package/dist/Scheduling/components/job-slideout.component.js +1 -1
  100. package/dist/Scheduling/components/scheduling-activity-resource.component.js +1 -1
  101. package/dist/Scheduling/components/scheduling-activity.component.js +1 -1
  102. package/dist/Scheduling/components/scheduling-jobs-resource.component.js +1 -1
  103. package/dist/Scheduling/components/scheduling-jobs.component.js +1 -1
  104. package/dist/Scheduling/components/scheduling-overview-resource.component.js +1 -1
  105. package/dist/Scheduling/components/scheduling-overview.component.js +1 -1
  106. package/dist/Scheduling/scheduling-dashboard.component.js +1 -1
  107. package/dist/SystemDiagnostics/system-diagnostics.component.js +1 -1
  108. package/dist/Testing/components/testing-analytics-resource.component.js +1 -1
  109. package/dist/Testing/components/testing-analytics.component.js +1 -1
  110. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
  111. package/dist/Testing/components/testing-dashboard-tab.component.js +1 -1
  112. package/dist/Testing/components/testing-explorer-resource.component.js +1 -1
  113. package/dist/Testing/components/testing-explorer.component.js +1 -1
  114. package/dist/Testing/components/testing-review-resource.component.js +1 -1
  115. package/dist/Testing/components/testing-review.component.js +1 -1
  116. package/dist/Testing/components/testing-runs-resource.component.js +1 -1
  117. package/dist/Testing/components/testing-runs.component.js +1 -1
  118. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +1 -1
  119. package/dist/Testing/components/widgets/suite-tree.component.js +2 -2
  120. package/dist/Testing/components/widgets/test-run-detail-panel.component.js +1 -1
  121. package/dist/Testing/testing-dashboard.component.js +1 -1
  122. package/dist/VersionHistory/components/diff-resource.component.js +1 -1
  123. package/dist/VersionHistory/components/graph-resource.component.js +1 -1
  124. package/dist/VersionHistory/components/labels-resource.component.js +1 -1
  125. package/dist/VersionHistory/components/restore-resource.component.js +1 -1
  126. package/package.json +38 -38
  127. package/dist/AI/ai-dashboard.component.d.ts +0 -62
  128. package/dist/AI/ai-dashboard.component.d.ts.map +0 -1
  129. package/dist/AI/ai-dashboard.component.js +0 -338
  130. package/dist/AI/ai-dashboard.component.js.map +0 -1
  131. package/dist/AI/components/models/model-management-v2.component.d.ts +0 -96
  132. package/dist/AI/components/models/model-management-v2.component.d.ts.map +0 -1
  133. package/dist/AI/components/models/model-management-v2.component.js +0 -981
  134. package/dist/AI/components/models/model-management-v2.component.js.map +0 -1
  135. package/dist/AI/components/prompts/prompt-management-v2.component.d.ts +0 -97
  136. package/dist/AI/components/prompts/prompt-management-v2.component.d.ts.map +0 -1
  137. package/dist/AI/components/prompts/prompt-management-v2.component.js +0 -811
  138. package/dist/AI/components/prompts/prompt-management-v2.component.js.map +0 -1
  139. package/dist/Actions/actions-management-dashboard.component.d.ts +0 -52
  140. package/dist/Actions/actions-management-dashboard.component.d.ts.map +0 -1
  141. package/dist/Actions/actions-management-dashboard.component.js +0 -308
  142. package/dist/Actions/actions-management-dashboard.component.js.map +0 -1
  143. package/dist/Credentials/components/credential-category-edit-panel.component.d.ts +0 -44
  144. package/dist/Credentials/components/credential-category-edit-panel.component.d.ts.map +0 -1
  145. package/dist/Credentials/components/credential-category-edit-panel.component.js +0 -456
  146. package/dist/Credentials/components/credential-category-edit-panel.component.js.map +0 -1
  147. package/dist/Credentials/components/credential-edit-panel.component.d.ts +0 -70
  148. package/dist/Credentials/components/credential-edit-panel.component.d.ts.map +0 -1
  149. package/dist/Credentials/components/credential-edit-panel.component.js +0 -694
  150. package/dist/Credentials/components/credential-edit-panel.component.js.map +0 -1
  151. package/dist/Credentials/components/credential-type-edit-panel.component.d.ts +0 -56
  152. package/dist/Credentials/components/credential-type-edit-panel.component.d.ts.map +0 -1
  153. package/dist/Credentials/components/credential-type-edit-panel.component.js +0 -563
  154. package/dist/Credentials/components/credential-type-edit-panel.component.js.map +0 -1
  155. package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.d.ts +0 -245
  156. package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.d.ts.map +0 -1
  157. package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.js +0 -1143
  158. package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.js.map +0 -1
  159. package/dist/EntityAdmin/components/entity-details.component.d.ts +0 -50
  160. package/dist/EntityAdmin/components/entity-details.component.d.ts.map +0 -1
  161. package/dist/EntityAdmin/components/entity-details.component.js +0 -680
  162. package/dist/EntityAdmin/components/entity-details.component.js.map +0 -1
  163. package/dist/EntityAdmin/components/entity-filter-panel.component.d.ts +0 -31
  164. package/dist/EntityAdmin/components/entity-filter-panel.component.d.ts.map +0 -1
  165. package/dist/EntityAdmin/components/entity-filter-panel.component.js +0 -160
  166. package/dist/EntityAdmin/components/entity-filter-panel.component.js.map +0 -1
  167. package/dist/EntityAdmin/components/erd-composite.component.d.ts +0 -73
  168. package/dist/EntityAdmin/components/erd-composite.component.d.ts.map +0 -1
  169. package/dist/EntityAdmin/components/erd-composite.component.js +0 -271
  170. package/dist/EntityAdmin/components/erd-composite.component.js.map +0 -1
  171. package/dist/EntityAdmin/components/erd-diagram.component.d.ts +0 -47
  172. package/dist/EntityAdmin/components/erd-diagram.component.d.ts.map +0 -1
  173. package/dist/EntityAdmin/components/erd-diagram.component.js +0 -618
  174. package/dist/EntityAdmin/components/erd-diagram.component.js.map +0 -1
  175. package/dist/Scheduling/components/scheduling-health-resource.component.d.ts +0 -20
  176. package/dist/Scheduling/components/scheduling-health-resource.component.d.ts.map +0 -1
  177. package/dist/Scheduling/components/scheduling-health-resource.component.js +0 -55
  178. package/dist/Scheduling/components/scheduling-health-resource.component.js.map +0 -1
  179. package/dist/Scheduling/components/scheduling-health.component.d.ts +0 -30
  180. package/dist/Scheduling/components/scheduling-health.component.d.ts.map +0 -1
  181. package/dist/Scheduling/components/scheduling-health.component.js +0 -315
  182. package/dist/Scheduling/components/scheduling-health.component.js.map +0 -1
  183. package/dist/Scheduling/components/scheduling-history-resource.component.d.ts +0 -20
  184. package/dist/Scheduling/components/scheduling-history-resource.component.d.ts.map +0 -1
  185. package/dist/Scheduling/components/scheduling-history-resource.component.js +0 -55
  186. package/dist/Scheduling/components/scheduling-history-resource.component.js.map +0 -1
  187. package/dist/Scheduling/components/scheduling-history.component.d.ts +0 -48
  188. package/dist/Scheduling/components/scheduling-history.component.d.ts.map +0 -1
  189. package/dist/Scheduling/components/scheduling-history.component.js +0 -377
  190. package/dist/Scheduling/components/scheduling-history.component.js.map +0 -1
  191. package/dist/Scheduling/components/scheduling-monitor-resource.component.d.ts +0 -20
  192. package/dist/Scheduling/components/scheduling-monitor-resource.component.d.ts.map +0 -1
  193. package/dist/Scheduling/components/scheduling-monitor-resource.component.js +0 -55
  194. package/dist/Scheduling/components/scheduling-monitor-resource.component.js.map +0 -1
  195. package/dist/Scheduling/components/scheduling-monitoring.component.d.ts +0 -37
  196. package/dist/Scheduling/components/scheduling-monitoring.component.d.ts.map +0 -1
  197. package/dist/Scheduling/components/scheduling-monitoring.component.js +0 -488
  198. package/dist/Scheduling/components/scheduling-monitoring.component.js.map +0 -1
  199. package/dist/Scheduling/components/scheduling-types-resource.component.d.ts +0 -20
  200. package/dist/Scheduling/components/scheduling-types-resource.component.d.ts.map +0 -1
  201. package/dist/Scheduling/components/scheduling-types-resource.component.js +0 -55
  202. package/dist/Scheduling/components/scheduling-types-resource.component.js.map +0 -1
  203. package/dist/Scheduling/components/scheduling-types.component.d.ts +0 -22
  204. package/dist/Scheduling/components/scheduling-types.component.d.ts.map +0 -1
  205. package/dist/Scheduling/components/scheduling-types.component.js +0 -165
  206. package/dist/Scheduling/components/scheduling-types.component.js.map +0 -1
  207. package/dist/Testing/components/testing-execution-resource.component.d.ts +0 -20
  208. package/dist/Testing/components/testing-execution-resource.component.d.ts.map +0 -1
  209. package/dist/Testing/components/testing-execution-resource.component.js +0 -55
  210. package/dist/Testing/components/testing-execution-resource.component.js.map +0 -1
  211. package/dist/Testing/components/testing-execution.component.d.ts +0 -71
  212. package/dist/Testing/components/testing-execution.component.d.ts.map +0 -1
  213. package/dist/Testing/components/testing-execution.component.js +0 -845
  214. package/dist/Testing/components/testing-execution.component.js.map +0 -1
  215. package/dist/Testing/components/testing-feedback-resource.component.d.ts +0 -20
  216. package/dist/Testing/components/testing-feedback-resource.component.d.ts.map +0 -1
  217. package/dist/Testing/components/testing-feedback-resource.component.js +0 -55
  218. package/dist/Testing/components/testing-feedback-resource.component.js.map +0 -1
  219. package/dist/Testing/components/testing-feedback.component.d.ts +0 -111
  220. package/dist/Testing/components/testing-feedback.component.d.ts.map +0 -1
  221. package/dist/Testing/components/testing-feedback.component.js +0 -1486
  222. package/dist/Testing/components/testing-feedback.component.js.map +0 -1
  223. package/dist/Testing/components/testing-overview-resource.component.d.ts +0 -20
  224. package/dist/Testing/components/testing-overview-resource.component.d.ts.map +0 -1
  225. package/dist/Testing/components/testing-overview-resource.component.js +0 -55
  226. package/dist/Testing/components/testing-overview-resource.component.js.map +0 -1
  227. package/dist/Testing/components/testing-overview.component.d.ts +0 -30
  228. package/dist/Testing/components/testing-overview.component.d.ts.map +0 -1
  229. package/dist/Testing/components/testing-overview.component.js +0 -361
  230. package/dist/Testing/components/testing-overview.component.js.map +0 -1
  231. package/dist/Testing/components/testing-version-comparison.component.d.ts +0 -62
  232. package/dist/Testing/components/testing-version-comparison.component.d.ts.map +0 -1
  233. package/dist/Testing/components/testing-version-comparison.component.js +0 -815
  234. package/dist/Testing/components/testing-version-comparison.component.js.map +0 -1
  235. package/dist/Testing/components/testing-version-resource.component.d.ts +0 -20
  236. package/dist/Testing/components/testing-version-resource.component.d.ts.map +0 -1
  237. package/dist/Testing/components/testing-version-resource.component.js +0 -55
  238. package/dist/Testing/components/testing-version-resource.component.js.map +0 -1
  239. package/dist/generic/base-dashboard.d.ts +0 -65
  240. package/dist/generic/base-dashboard.d.ts.map +0 -1
  241. package/dist/generic/base-dashboard.js +0 -74
  242. package/dist/generic/base-dashboard.js.map +0 -1
@@ -45,5 +45,5 @@ export { TestingAnalyticsResourceComponent };
45
45
  </div>
46
46
  `, styles: ["\n .resource-container {\n width: 100%;\n height: 100%;\n overflow: auto;\n }\n "] }]
47
47
  }], null, null); })();
48
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingAnalyticsResourceComponent, { className: "TestingAnalyticsResourceComponent", filePath: "src/testing/components/testing-analytics-resource.component.ts", lineNumber: 26 }); })();
48
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingAnalyticsResourceComponent, { className: "TestingAnalyticsResourceComponent", filePath: "src/Testing/components/testing-analytics-resource.component.ts", lineNumber: 26 }); })();
49
49
  //# sourceMappingURL=testing-analytics-resource.component.js.map
@@ -1196,5 +1196,5 @@ export class TestingAnalyticsComponent {
1196
1196
  }], stateChange: [{
1197
1197
  type: Output
1198
1198
  }] }); })();
1199
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingAnalyticsComponent, { className: "TestingAnalyticsComponent", filePath: "src/testing/components/testing-analytics.component.ts", lineNumber: 779 }); })();
1199
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingAnalyticsComponent, { className: "TestingAnalyticsComponent", filePath: "src/Testing/components/testing-analytics.component.ts", lineNumber: 779 }); })();
1200
1200
  //# sourceMappingURL=testing-analytics.component.js.map
@@ -43,5 +43,5 @@ export { TestingDashboardTabResourceComponent };
43
43
  </div>
44
44
  `, styles: ["\n .resource-container {\n width: 100%;\n height: 100%;\n overflow: auto;\n }\n "] }]
45
45
  }], null, null); })();
46
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingDashboardTabResourceComponent, { className: "TestingDashboardTabResourceComponent", filePath: "src/testing/components/testing-dashboard-tab-resource.component.ts", lineNumber: 26 }); })();
46
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingDashboardTabResourceComponent, { className: "TestingDashboardTabResourceComponent", filePath: "src/Testing/components/testing-dashboard-tab-resource.component.ts", lineNumber: 26 }); })();
47
47
  //# sourceMappingURL=testing-dashboard-tab-resource.component.js.map
@@ -645,5 +645,5 @@ export class TestingDashboardTabComponent {
645
645
  }], stateChange: [{
646
646
  type: Output
647
647
  }] }); })();
648
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingDashboardTabComponent, { className: "TestingDashboardTabComponent", filePath: "src/testing/components/testing-dashboard-tab.component.ts", lineNumber: 567 }); })();
648
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingDashboardTabComponent, { className: "TestingDashboardTabComponent", filePath: "src/Testing/components/testing-dashboard-tab.component.ts", lineNumber: 567 }); })();
649
649
  //# sourceMappingURL=testing-dashboard-tab.component.js.map
@@ -43,5 +43,5 @@ export { TestingExplorerResourceComponent };
43
43
  </div>
44
44
  `, styles: ["\n .resource-container {\n width: 100%;\n height: 100%;\n overflow: auto;\n }\n "] }]
45
45
  }], null, null); })();
46
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingExplorerResourceComponent, { className: "TestingExplorerResourceComponent", filePath: "src/testing/components/testing-explorer-resource.component.ts", lineNumber: 26 }); })();
46
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingExplorerResourceComponent, { className: "TestingExplorerResourceComponent", filePath: "src/Testing/components/testing-explorer-resource.component.ts", lineNumber: 26 }); })();
47
47
  //# sourceMappingURL=testing-explorer-resource.component.js.map
@@ -2215,5 +2215,5 @@ export class TestingExplorerComponent {
2215
2215
  </div>
2216
2216
  `, styles: ["\n /* ==========================================\n Testing Explorer Component\n ========================================== */\n\n :host {\n display: block;\n height: 100%;\n width: 100%;\n }\n\n /* Loading */\n .explorer-loading {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n min-height: 400px;\n background: #f5f6fa;\n }\n\n /* Layout */\n .explorer-layout {\n display: flex;\n height: 100%;\n background: #f5f6fa;\n overflow: hidden;\n }\n\n /* ==========================================\n Sidebar\n ========================================== */\n .sidebar {\n width: 280px;\n min-width: 280px;\n background: #fff;\n border-right: 1px solid #e8ecef;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transition: width 0.2s ease, min-width 0.2s ease;\n }\n\n .sidebar.collapsed {\n width: 48px;\n min-width: 48px;\n }\n\n .sidebar-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid #e8ecef;\n }\n\n .sidebar-header h3 {\n margin: 0;\n font-size: 15px;\n font-weight: 700;\n color: #2d3436;\n }\n\n .sidebar.collapsed .sidebar-header h3 {\n display: none;\n }\n\n .sidebar-toggle {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid #e8ecef;\n border-radius: 6px;\n color: #636e72;\n cursor: pointer;\n font-size: 11px;\n transition: all 0.15s ease;\n }\n\n .sidebar-toggle:hover {\n background: #f5f6fa;\n color: #2d3436;\n }\n\n .sidebar-content {\n flex: 1;\n overflow-y: auto;\n padding: 8px 0;\n }\n\n .sidebar-section {\n margin-bottom: 8px;\n }\n\n .sidebar-section-title {\n padding: 8px 16px 4px;\n font-size: 10px;\n font-weight: 700;\n color: #b2bec3;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n }\n\n .sidebar-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n font-size: 13px;\n color: #636e72;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n overflow: hidden;\n }\n\n .sidebar-item:hover {\n background: #f5f6fa;\n color: #2d3436;\n }\n\n .sidebar-item.active {\n background: #e0f2f1;\n color: #00897b;\n font-weight: 600;\n }\n\n .sidebar-item i {\n font-size: 12px;\n width: 16px;\n text-align: center;\n flex-shrink: 0;\n }\n\n .sidebar-item span:not(.sidebar-count) {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .sidebar-count {\n font-size: 11px;\n color: #b2bec3;\n font-weight: 500;\n flex-shrink: 0;\n }\n\n .sidebar-item.active .sidebar-count {\n color: #00897b;\n }\n\n .sidebar-empty {\n padding: 8px 16px;\n font-size: 12px;\n color: #b2bec3;\n font-style: italic;\n }\n\n /* Tree nodes */\n .suite-tree-item {\n gap: 6px;\n }\n\n .tree-toggle {\n width: 18px;\n height: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n color: #b2bec3;\n cursor: pointer;\n font-size: 9px;\n flex-shrink: 0;\n border-radius: 4px;\n padding: 0;\n }\n\n .tree-toggle:hover {\n background: #e8ecef;\n color: #636e72;\n }\n\n .tree-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n /* ==========================================\n Main Content\n ========================================== */\n .main-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n /* Toolbar */\n .toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n padding: 16px 24px;\n background: #fff;\n border-bottom: 1px solid #e8ecef;\n flex-shrink: 0;\n }\n\n .toolbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n }\n\n .toolbar-search-box {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: #f5f6fa;\n border: 1px solid #e8ecef;\n border-radius: 6px;\n min-width: 240px;\n max-width: 360px;\n flex: 1;\n transition: border-color 0.2s ease;\n }\n\n .toolbar-search-box:focus-within {\n border-color: #00897b;\n background: #fff;\n }\n\n .toolbar-search-box i {\n color: #b2bec3;\n font-size: 13px;\n }\n\n .toolbar-search-box input {\n flex: 1;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: #2d3436;\n }\n\n .toolbar-search-box input::placeholder {\n color: #b2bec3;\n }\n\n .clear-search {\n border: none;\n background: transparent;\n color: #b2bec3;\n cursor: pointer;\n padding: 2px 4px;\n border-radius: 4px;\n }\n\n .clear-search:hover {\n color: #636e72;\n background: #e8ecef;\n }\n\n .status-chips {\n display: flex;\n gap: 6px;\n }\n\n .chip {\n display: inline-flex;\n align-items: center;\n padding: 6px 14px;\n background: #f5f6fa;\n border: 1px solid transparent;\n border-radius: 16px;\n font-size: 12px;\n font-weight: 600;\n color: #636e72;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .chip:hover {\n background: #e8ecef;\n }\n\n .chip.active {\n color: #fff;\n }\n\n .chip.active[data-status=\"active\"] {\n background: #2e7d32;\n border-color: #2e7d32;\n }\n\n .chip.active[data-status=\"pending\"] {\n background: #e65100;\n border-color: #e65100;\n }\n\n .chip.active[data-status=\"disabled\"] {\n background: #636e72;\n border-color: #636e72;\n }\n\n .toolbar-right {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n }\n\n .result-count {\n font-size: 12px;\n color: #b2bec3;\n font-weight: 500;\n white-space: nowrap;\n }\n\n .view-toggle {\n display: flex;\n border: 1px solid #e8ecef;\n border-radius: 6px;\n overflow: hidden;\n }\n\n .view-btn {\n width: 34px;\n height: 34px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #fff;\n border: none;\n color: #b2bec3;\n cursor: pointer;\n font-size: 13px;\n transition: all 0.15s ease;\n }\n\n .view-btn:not(:last-child) {\n border-right: 1px solid #e8ecef;\n }\n\n .view-btn:hover {\n background: #f5f6fa;\n color: #636e72;\n }\n\n .view-btn.active {\n background: #00897b;\n color: #fff;\n }\n\n /* Buttons */\n .btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 9px 16px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n }\n\n .btn-primary {\n background: #00897b;\n color: #fff;\n }\n\n .btn-primary:hover {\n background: #00796b;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 137, 123, 0.3);\n }\n\n .btn-secondary {\n background: #fff;\n color: #636e72;\n border: 1px solid #e8ecef;\n }\n\n .btn-secondary:hover {\n background: #f5f6fa;\n }\n\n .btn-sm {\n padding: 6px 12px;\n font-size: 12px;\n }\n\n /* Toggle Bar */\n .toggle-bar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 24px;\n background: #fafafa;\n border-bottom: 1px solid #e8ecef;\n flex-shrink: 0;\n }\n\n .toggle-group {\n display: flex;\n border: 1px solid #e8ecef;\n border-radius: 6px;\n overflow: hidden;\n }\n\n .toggle-btn {\n padding: 6px 16px;\n background: #fff;\n border: none;\n font-size: 12px;\n font-weight: 600;\n color: #636e72;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .toggle-btn:not(:last-child) {\n border-right: 1px solid #e8ecef;\n }\n\n .toggle-btn.active {\n background: #00897b;\n color: #fff;\n }\n\n .toggle-btn:hover:not(.active) {\n background: #f5f6fa;\n }\n\n .sort-indicator {\n display: flex;\n align-items: center;\n }\n\n .sort-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid #e8ecef;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n color: #636e72;\n cursor: pointer;\n }\n\n .sort-btn:hover {\n background: #f5f6fa;\n }\n\n .sort-btn i {\n font-size: 11px;\n }\n\n /* Content Area */\n .content-area {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n }\n\n .content-section {\n margin-bottom: 32px;\n }\n\n .section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 700;\n color: #2d3436;\n }\n\n .section-title i {\n color: #00897b;\n font-size: 14px;\n }\n\n .section-count {\n font-size: 12px;\n font-weight: 600;\n color: #b2bec3;\n background: #f5f6fa;\n padding: 2px 8px;\n border-radius: 10px;\n }\n\n /* Card Grid */\n .card-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));\n gap: 16px;\n }\n\n /* Suite Card */\n .suite-card,\n .test-card {\n background: #fff;\n border: 1px solid #e8ecef;\n border-radius: 10px;\n overflow: hidden;\n transition: all 0.2s ease;\n }\n\n .suite-card:hover,\n .test-card:hover {\n border-color: #b2dfdb;\n box-shadow: 0 4px 16px rgba(0, 137, 123, 0.1);\n }\n\n .card-header {\n padding: 16px 16px 12px;\n }\n\n .card-title-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n }\n\n .card-icon {\n font-size: 14px;\n flex-shrink: 0;\n }\n\n .suite-icon {\n color: #00897b;\n }\n\n .test-icon {\n color: #6366f1;\n }\n\n .card-name {\n flex: 1;\n font-size: 14px;\n font-weight: 700;\n color: #2d3436;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .status-badge {\n font-size: 10px;\n font-weight: 700;\n padding: 3px 8px;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n flex-shrink: 0;\n }\n\n .status-badge[data-status=\"active\"] {\n background: #e8f5e9;\n color: #2e7d32;\n }\n\n .status-badge[data-status=\"pending\"] {\n background: #fff3e0;\n color: #e65100;\n }\n\n .status-badge[data-status=\"disabled\"] {\n background: #f5f6fa;\n color: #636e72;\n }\n\n .card-subtitle {\n font-size: 12px;\n color: #636e72;\n margin-bottom: 6px;\n }\n\n .dot-sep {\n display: inline-block;\n width: 3px;\n height: 3px;\n background: #b2bec3;\n border-radius: 50%;\n vertical-align: middle;\n margin: 0 6px;\n }\n\n .card-description {\n margin: 0;\n font-size: 12px;\n color: #636e72;\n line-height: 1.5;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .card-meta-row {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n margin-top: 8px;\n }\n\n .meta-item {\n font-size: 11px;\n color: #636e72;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .meta-item i {\n font-size: 10px;\n color: #b2bec3;\n }\n\n .card-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-top: 8px;\n }\n\n .tag {\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n background: #f5f6fa;\n color: #636e72;\n border-radius: 4px;\n }\n\n .tag-more {\n background: #e8ecef;\n color: #b2bec3;\n }\n\n /* Card Stats */\n .card-stats {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 1px;\n background: #e8ecef;\n border-top: 1px solid #e8ecef;\n }\n\n .stat {\n background: #fafafa;\n padding: 10px 12px;\n text-align: center;\n }\n\n .stat-label {\n display: block;\n font-size: 10px;\n font-weight: 600;\n color: #b2bec3;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 2px;\n }\n\n .stat-value {\n font-size: 14px;\n font-weight: 700;\n color: #2d3436;\n }\n\n .stat-value.good { color: #2e7d32; }\n .stat-value.warn { color: #e65100; }\n .stat-value.bad { color: #c62828; }\n\n .status-text[data-status=\"passed\"] { color: #2e7d32; }\n .status-text[data-status=\"failed\"] { color: #c62828; }\n .status-text[data-status=\"error\"] { color: #e65100; }\n .status-text[data-status=\"running\"] { color: #1565c0; }\n .status-text[data-status=\"pending\"] { color: #e65100; }\n .status-text[data-status=\"skipped\"] { color: #636e72; }\n\n /* Suite Tests Preview */\n .card-tests-preview {\n padding: 10px 16px;\n border-top: 1px solid #e8ecef;\n }\n\n .preview-test-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n font-size: 12px;\n }\n\n .preview-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .preview-dot[data-status=\"passed\"] { background: #2e7d32; }\n .preview-dot[data-status=\"failed\"] { background: #c62828; }\n .preview-dot[data-status=\"error\"] { background: #e65100; }\n .preview-dot[data-status=\"running\"] { background: #1565c0; }\n .preview-dot[data-status=\"\"] { background: #b2bec3; }\n\n .preview-test-name {\n flex: 1;\n color: #2d3436;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .preview-score {\n font-weight: 600;\n font-size: 11px;\n min-width: 32px;\n text-align: right;\n }\n\n .preview-score.good { color: #2e7d32; }\n .preview-score.warn { color: #e65100; }\n .preview-score.bad { color: #c62828; }\n\n .preview-bar {\n width: 48px;\n height: 4px;\n background: #e8ecef;\n border-radius: 2px;\n overflow: hidden;\n flex-shrink: 0;\n }\n\n .preview-bar-fill {\n height: 100%;\n border-radius: 2px;\n transition: width 0.3s ease;\n }\n\n .good-bg { background: #2e7d32; }\n .warn-bg { background: #e65100; }\n .bad-bg { background: #c62828; }\n\n .preview-status {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n min-width: 44px;\n text-align: right;\n }\n\n .preview-status[data-status=\"passed\"] { color: #2e7d32; }\n .preview-status[data-status=\"failed\"] { color: #c62828; }\n .preview-status[data-status=\"error\"] { color: #e65100; }\n .preview-status[data-status=\"\"] { color: #b2bec3; }\n\n .preview-more {\n padding: 4px 0 0;\n font-size: 11px;\n color: #b2bec3;\n font-style: italic;\n }\n\n /* Card Actions */\n .card-actions {\n display: flex;\n gap: 8px;\n padding: 12px 16px;\n border-top: 1px solid #e8ecef;\n background: #fafafa;\n }\n\n /* Empty State */\n .empty-state {\n padding: 80px 40px;\n text-align: center;\n }\n\n .empty-state i {\n font-size: 48px;\n color: #b2bec3;\n margin-bottom: 16px;\n }\n\n .empty-state p {\n font-size: 16px;\n color: #636e72;\n margin: 0 0 8px 0;\n }\n\n .empty-hint {\n font-size: 13px;\n color: #b2bec3;\n }\n\n /* ==========================================\n Slideout Panel\n ========================================== */\n .slideout-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 999;\n animation: fadeInBackdrop 0.2s ease;\n }\n\n @keyframes fadeInBackdrop {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n .slideout-panel {\n position: fixed;\n top: 0;\n right: -100%;\n height: 100vh;\n background: #fff;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);\n z-index: 1000;\n transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .slideout-panel.open {\n right: 0;\n }\n\n .slideout-resize-handle {\n position: absolute;\n top: 0;\n left: 0;\n width: 5px;\n height: 100%;\n cursor: col-resize;\n background: transparent;\n z-index: 10;\n transition: background 0.2s;\n }\n\n .slideout-resize-handle:hover {\n background: rgba(0, 137, 123, 0.3);\n }\n\n .slideout-resize-handle:active {\n background: rgba(0, 137, 123, 0.5);\n }\n\n .slideout-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n }\n\n .slideout-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid #e8ecef;\n flex-shrink: 0;\n }\n\n .slideout-title-row {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .slideout-title-icon {\n font-size: 18px;\n color: #00897b;\n }\n\n .slideout-title-text {\n font-size: 18px;\n font-weight: 700;\n color: #2d3436;\n }\n\n .slideout-close-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid #e8ecef;\n border-radius: 6px;\n color: #636e72;\n cursor: pointer;\n font-size: 14px;\n transition: all 0.15s ease;\n }\n\n .slideout-close-btn:hover {\n background: #f5f6fa;\n color: #2d3436;\n border-color: #ccc;\n }\n\n /* Type Toggle */\n .slideout-type-toggle {\n display: flex;\n gap: 0;\n padding: 16px 24px;\n border-bottom: 1px solid #e8ecef;\n flex-shrink: 0;\n }\n\n .type-toggle-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n background: #f5f6fa;\n border: 1px solid #e8ecef;\n font-size: 13px;\n font-weight: 600;\n color: #636e72;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .type-toggle-btn:first-child {\n border-radius: 8px 0 0 8px;\n border-right: none;\n }\n\n .type-toggle-btn:last-child {\n border-radius: 0 8px 8px 0;\n }\n\n .type-toggle-btn.active {\n background: #00897b;\n border-color: #00897b;\n color: #fff;\n }\n\n .type-toggle-btn:hover:not(.active) {\n background: #e8ecef;\n }\n\n /* Error Banner */\n .slideout-error {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 16px 24px 0;\n padding: 12px 16px;\n background: #fff5f5;\n border: 1px solid #fed7d7;\n border-radius: 8px;\n color: #c53030;\n font-size: 13px;\n flex-shrink: 0;\n }\n\n .slideout-error i {\n font-size: 14px;\n flex-shrink: 0;\n }\n\n /* Slideout Body */\n .slideout-body {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n }\n\n .form-section {\n margin-bottom: 24px;\n }\n\n .form-section-title {\n font-size: 12px;\n font-weight: 700;\n color: #b2bec3;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n margin-bottom: 14px;\n padding-bottom: 8px;\n border-bottom: 1px solid #f0f0f0;\n }\n\n .form-group {\n margin-bottom: 16px;\n }\n\n .form-label {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: #2d3436;\n margin-bottom: 6px;\n }\n\n .form-required {\n color: #e53e3e;\n }\n\n .form-input,\n .form-textarea {\n width: 100%;\n padding: 10px 14px;\n background: #fff;\n border: 1px solid #e8ecef;\n border-radius: 8px;\n font-size: 13px;\n color: #2d3436;\n transition: border-color 0.2s ease;\n outline: none;\n box-sizing: border-box;\n font-family: inherit;\n }\n\n .form-input:focus,\n .form-textarea:focus {\n border-color: #00897b;\n box-shadow: 0 0 0 3px rgba(0, 137, 123, 0.1);\n }\n\n .form-input::placeholder,\n .form-textarea::placeholder {\n color: #b2bec3;\n }\n\n .form-textarea {\n resize: vertical;\n min-height: 80px;\n }\n\n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n }\n\n .form-hint {\n display: block;\n font-size: 11px;\n color: #b2bec3;\n margin-top: 4px;\n }\n\n /* Slideout Footer */\n .slideout-footer {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding: 16px 24px;\n border-top: 1px solid #e8ecef;\n background: #fafafa;\n flex-shrink: 0;\n }\n\n .slideout-footer .btn {\n min-width: 100px;\n justify-content: center;\n }\n\n .slideout-footer .btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n box-shadow: none;\n }\n\n /* Search Highlight */\n ::ng-deep mark.search-highlight {\n background: #fff9c4;\n color: inherit;\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: 700;\n }\n\n /* ==========================================\n Responsive\n ========================================== */\n @media (max-width: 1200px) {\n .card-grid {\n grid-template-columns: 1fr;\n }\n }\n\n @media (max-width: 900px) {\n .sidebar {\n display: none;\n }\n\n .toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .toolbar-left, .toolbar-right {\n flex-wrap: wrap;\n justify-content: center;\n }\n }\n\n @media (max-width: 600px) {\n .content-area {\n padding: 16px;\n }\n\n .card-stats {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .slideout-panel {\n width: 100% !important;\n }\n\n .slideout-resize-handle {\n display: none;\n }\n\n .form-row {\n grid-template-columns: 1fr;\n }\n }\n "] }]
2217
2217
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i0.ViewContainerRef }, { type: i1.TestingDialogService }, { type: i2.TestingInstrumentationService }], null); })();
2218
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingExplorerComponent, { className: "TestingExplorerComponent", filePath: "src/testing/components/testing-explorer.component.ts", lineNumber: 1804 }); })();
2218
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingExplorerComponent, { className: "TestingExplorerComponent", filePath: "src/Testing/components/testing-explorer.component.ts", lineNumber: 1804 }); })();
2219
2219
  //# sourceMappingURL=testing-explorer.component.js.map
@@ -43,5 +43,5 @@ export { TestingReviewResourceComponent };
43
43
  </div>
44
44
  `, styles: ["\n .resource-container {\n width: 100%;\n height: 100%;\n overflow: auto;\n }\n "] }]
45
45
  }], null, null); })();
46
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingReviewResourceComponent, { className: "TestingReviewResourceComponent", filePath: "src/testing/components/testing-review-resource.component.ts", lineNumber: 26 }); })();
46
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingReviewResourceComponent, { className: "TestingReviewResourceComponent", filePath: "src/Testing/components/testing-review-resource.component.ts", lineNumber: 26 }); })();
47
47
  //# sourceMappingURL=testing-review-resource.component.js.map
@@ -981,5 +981,5 @@ export class TestingReviewComponent {
981
981
  }], stateChange: [{
982
982
  type: Output
983
983
  }] }); })();
984
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingReviewComponent, { className: "TestingReviewComponent", filePath: "src/testing/components/testing-review.component.ts", lineNumber: 1188 }); })();
984
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingReviewComponent, { className: "TestingReviewComponent", filePath: "src/Testing/components/testing-review.component.ts", lineNumber: 1188 }); })();
985
985
  //# sourceMappingURL=testing-review.component.js.map
@@ -43,5 +43,5 @@ export { TestingRunsResourceComponent };
43
43
  </div>
44
44
  `, styles: ["\n .resource-container {\n width: 100%;\n height: 100%;\n overflow: auto;\n }\n "] }]
45
45
  }], null, null); })();
46
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingRunsResourceComponent, { className: "TestingRunsResourceComponent", filePath: "src/testing/components/testing-runs-resource.component.ts", lineNumber: 26 }); })();
46
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingRunsResourceComponent, { className: "TestingRunsResourceComponent", filePath: "src/Testing/components/testing-runs-resource.component.ts", lineNumber: 26 }); })();
47
47
  //# sourceMappingURL=testing-runs-resource.component.js.map
@@ -1063,5 +1063,5 @@ export class TestingRunsComponent {
1063
1063
  type: HostListener,
1064
1064
  args: ['document:keydown.escape']
1065
1065
  }] }); })();
1066
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingRunsComponent, { className: "TestingRunsComponent", filePath: "src/testing/components/testing-runs.component.ts", lineNumber: 1103 }); })();
1066
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingRunsComponent, { className: "TestingRunsComponent", filePath: "src/Testing/components/testing-runs.component.ts", lineNumber: 1103 }); })();
1067
1067
  //# sourceMappingURL=testing-runs.component.js.map
@@ -286,5 +286,5 @@ export class OracleBreakdownTableComponent {
286
286
  }], null, { results: [{
287
287
  type: Input
288
288
  }] }); })();
289
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(OracleBreakdownTableComponent, { className: "OracleBreakdownTableComponent", filePath: "src/testing/components/widgets/oracle-breakdown-table.component.ts", lineNumber: 327 }); })();
289
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(OracleBreakdownTableComponent, { className: "OracleBreakdownTableComponent", filePath: "src/Testing/components/widgets/oracle-breakdown-table.component.ts", lineNumber: 327 }); })();
290
290
  //# sourceMappingURL=oracle-breakdown-table.component.js.map
@@ -150,7 +150,7 @@ export class SuiteTreeComponent {
150
150
  }], suiteSelect: [{
151
151
  type: Output
152
152
  }] }); })();
153
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SuiteTreeComponent, { className: "SuiteTreeComponent", filePath: "src/testing/components/widgets/suite-tree.component.ts", lineNumber: 132 }); })();
153
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SuiteTreeComponent, { className: "SuiteTreeComponent", filePath: "src/Testing/components/widgets/suite-tree.component.ts", lineNumber: 132 }); })();
154
154
  export class SuiteTreeNodeComponent {
155
155
  node;
156
156
  level = 0;
@@ -274,5 +274,5 @@ export class SuiteTreeNodeComponent {
274
274
  }], toggleExpand: [{
275
275
  type: Output
276
276
  }] }); })();
277
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SuiteTreeNodeComponent, { className: "SuiteTreeNodeComponent", filePath: "src/testing/components/widgets/suite-tree.component.ts", lineNumber: 323 }); })();
277
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SuiteTreeNodeComponent, { className: "SuiteTreeNodeComponent", filePath: "src/Testing/components/widgets/suite-tree.component.ts", lineNumber: 323 }); })();
278
278
  //# sourceMappingURL=suite-tree.component.js.map
@@ -376,5 +376,5 @@ export class TestRunDetailPanelComponent {
376
376
  }], submitFeedback: [{
377
377
  type: Output
378
378
  }] }); })();
379
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestRunDetailPanelComponent, { className: "TestRunDetailPanelComponent", filePath: "src/testing/components/widgets/test-run-detail-panel.component.ts", lineNumber: 391 }); })();
379
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestRunDetailPanelComponent, { className: "TestRunDetailPanelComponent", filePath: "src/Testing/components/widgets/test-run-detail-panel.component.ts", lineNumber: 391 }); })();
380
380
  //# sourceMappingURL=test-run-detail-panel.component.js.map
@@ -250,5 +250,5 @@ export { TestingDashboardComponent };
250
250
  type: Component,
251
251
  args: [{ standalone: false, selector: 'mj-testing-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"testing-dashboard-container\" kendoDialogContainer>\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading Testing Dashboard...\" size=\"large\"></mj-loading>\n </div>\n }\n\n @if (!isLoading) {\n <div class=\"dashboard-content-wrapper\">\n <div class=\"testing-dashboard-nav\">\n @for (navItem of navigationConfig; track $index) {\n <div\n class=\"nav-item\"\n [class.active]=\"navItem.selected\"\n (click)=\"onTabChange(navigationItems[$index])\"\n >\n <i [class]=\"navItem.icon\"></i>\n <span>{{ navItem.text }}</span>\n </div>\n }\n <div class=\"nav-spacer\"></div>\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n </div>\n\n <div class=\"dashboard-content\">\n @if (activeTab === 'dashboard' && hasVisited('dashboard')) {\n <app-testing-dashboard-tab\n [initialState]=\"dashboardState\"\n (stateChange)=\"onDashboardStateChange($event)\"\n ></app-testing-dashboard-tab>\n }\n\n @if (activeTab === 'runs' && hasVisited('runs')) {\n <app-testing-runs\n [initialState]=\"runsState\"\n (stateChange)=\"onRunsStateChange($event)\"\n ></app-testing-runs>\n }\n\n @if (activeTab === 'analytics' && hasVisited('analytics')) {\n <app-testing-analytics\n [initialState]=\"analyticsState\"\n (stateChange)=\"onAnalyticsStateChange($event)\"\n ></app-testing-analytics>\n }\n\n @if (activeTab === 'review' && hasVisited('review')) {\n <app-testing-review\n [initialState]=\"reviewState\"\n (stateChange)=\"onReviewStateChange($event)\"\n ></app-testing-review>\n }\n </div>\n </div>\n }\n</div>\n", styles: ["/* ============================================\n Testing Dashboard - Premium Design System\n Based on AI Dashboard patterns\n ============================================ */\n\n.testing-dashboard-container {\n height: 100%;\n background: linear-gradient(135deg, #f5f7fa 0%, #e8eef5 100%);\n position: relative;\n overflow: hidden;\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(8px);\n}\n\n.loading-content {\n text-align: center;\n}\n\n.loading-spinner {\n display: inline-block;\n position: relative;\n width: 80px;\n height: 80px;\n}\n\n.spinner-ring {\n box-sizing: border-box;\n display: block;\n position: absolute;\n width: 64px;\n height: 64px;\n margin: 8px;\n border: 8px solid #6366f1;\n border-radius: 50%;\n animation: spinner-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n border-color: #6366f1 transparent transparent transparent;\n}\n\n.spinner-ring:nth-child(1) {\n animation-delay: -0.45s;\n}\n\n.spinner-ring:nth-child(2) {\n animation-delay: -0.3s;\n}\n\n.spinner-ring:nth-child(3) {\n animation-delay: -0.15s;\n}\n\n@keyframes spinner-ring {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n.loading-text {\n margin-top: 20px;\n font-size: 16px;\n color: #64748b;\n font-weight: 500;\n}\n\n/* Dashboard Layout */\n.dashboard-content-wrapper {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n.dashboard-content {\n flex: 1;\n overflow: hidden;\n}\n\n/* Premium Navigation Tabs */\n.testing-dashboard-nav {\n display: flex;\n justify-content: flex-start;\n gap: 2px;\n background: linear-gradient(180deg, #ffffff 0%, #fafbff 100%);\n border-bottom: 1px solid rgba(99, 102, 241, 0.1);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.06);\n padding: 0 16px;\n position: relative;\n z-index: 10;\n}\n\n.nav-item {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n gap: 10px;\n padding: 16px 24px;\n cursor: pointer;\n color: #64748b;\n transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n border-bottom: 3px solid transparent;\n white-space: nowrap;\n position: relative;\n font-weight: 500;\n}\n\n.nav-item::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 3px;\n background: transparent;\n transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n border-radius: 8px 8px 0 0;\n}\n\n.nav-item:hover {\n color: #6366f1;\n}\n\n.nav-item:hover::before {\n background: linear-gradient(180deg, rgba(99, 102, 241, 0.08) 0%, rgba(139, 92, 246, 0.04) 100%);\n}\n\n.nav-item.active {\n color: #6366f1;\n border-bottom-color: #6366f1;\n}\n\n.nav-item.active::before {\n background: linear-gradient(180deg, rgba(99, 102, 241, 0.1) 0%, rgba(139, 92, 246, 0.05) 100%);\n}\n\n.nav-item i {\n font-size: 16px;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n position: relative;\n z-index: 1;\n}\n\n.nav-item:hover i {\n transform: scale(1.1);\n}\n\n.nav-item span {\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0.2px;\n position: relative;\n z-index: 1;\n}\n\n/* Spacer for flex layout */\n.nav-spacer {\n flex: 1;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .testing-dashboard-nav {\n padding: 0 8px;\n overflow-x: auto;\n }\n\n .nav-item {\n padding: 12px 16px;\n gap: 8px;\n }\n\n .nav-item span {\n font-size: 11px;\n }\n\n .nav-item i {\n font-size: 18px;\n }\n}\n"] }]
252
252
  }], () => [{ type: i0.ChangeDetectorRef }], null); })();
253
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingDashboardComponent, { className: "TestingDashboardComponent", filePath: "src/testing/testing-dashboard.component.ts", lineNumber: 24 }); })();
253
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingDashboardComponent, { className: "TestingDashboardComponent", filePath: "src/Testing/testing-dashboard.component.ts", lineNumber: 24 }); })();
254
254
  //# sourceMappingURL=testing-dashboard.component.js.map
@@ -1158,5 +1158,5 @@ export { VersionHistoryDiffResourceComponent };
1158
1158
  type: Component,
1159
1159
  args: [{ standalone: false, selector: 'mj-version-history-diff-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"diff-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading diff viewer...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Diff Viewer</h2>\n <p class=\"page-subtitle\">Compare states between version labels or against current data</p>\n </div>\n </div>\n <!-- Diff Configuration Panel -->\n <div class=\"config-panel\">\n <!-- Mode Selector -->\n <div class=\"mode-selector\">\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-current'\"\n (click)=\"OnDiffModeChange('label-to-current')\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Label vs Current\n </button>\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-label'\"\n (click)=\"OnDiffModeChange('label-to-label')\">\n <i class=\"fa-solid fa-code-compare\"></i>\n Label vs Label\n </button>\n </div>\n <!-- Label Selectors -->\n <div class=\"label-selectors\">\n <div class=\"selector-group\">\n <label class=\"selector-label\">\n {{DiffMode === 'label-to-current' ? 'Compare label' : 'From label'}}\n </label>\n <select class=\"selector-input\"\n [(ngModel)]=\"FromLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredFromLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-arrow\">\n <button class=\"swap-btn\" (click)=\"SwapLabels()\" title=\"Swap direction\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n </div>\n }\n @if (DiffMode === 'label-to-current') {\n <div class=\"selector-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n <span class=\"current-state-badge\">Current State</span>\n </div>\n }\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-group\">\n <label class=\"selector-label\">To label</label>\n <select class=\"selector-input\"\n [(ngModel)]=\"ToLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredToLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n }\n </div>\n <!-- Run Button -->\n <button class=\"btn-primary\"\n [disabled]=\"!CanRunDiff || IsDiffLoading\"\n (click)=\"RunDiff()\">\n @if (!IsDiffLoading) {\n <i class=\"fa-solid fa-play\"></i>\n }\n @if (IsDiffLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n <span>{{IsDiffLoading ? 'Comparing...' : 'Compare'}}</span>\n </button>\n </div>\n <!-- Diff Results -->\n @if (HasDiffResult) {\n <!-- Summary Stats -->\n <div class=\"diff-summary\">\n <div class=\"diff-stat change-added\">\n <i class=\"fa-solid fa-plus\"></i>\n <span class=\"diff-stat-value\">{{TotalAdded}}</span>\n <span class=\"diff-stat-label\">Added</span>\n </div>\n <div class=\"diff-stat change-removed\">\n <i class=\"fa-solid fa-minus\"></i>\n <span class=\"diff-stat-value\">{{TotalRemoved}}</span>\n <span class=\"diff-stat-label\">Removed</span>\n </div>\n <div class=\"diff-stat change-modified\">\n <i class=\"fa-solid fa-pen\"></i>\n <span class=\"diff-stat-value\">{{TotalModified}}</span>\n <span class=\"diff-stat-label\">Modified</span>\n </div>\n <div class=\"diff-stat change-unchanged\">\n <i class=\"fa-solid fa-equals\"></i>\n <span class=\"diff-stat-value\">{{TotalUnchanged}}</span>\n <span class=\"diff-stat-label\">Unchanged</span>\n </div>\n </div>\n <!-- Results toolbar -->\n @if (EntityGroups.length > 0) {\n <div class=\"diff-toolbar\">\n <div class=\"diff-search\">\n <i class=\"fa-solid fa-search diff-search-icon\"></i>\n <input type=\"text\" class=\"diff-search-input\"\n placeholder=\"Search by entity or record...\"\n [ngModel]=\"DiffSearch\"\n (ngModelChange)=\"OnDiffSearchChange($event)\" />\n </div>\n <div class=\"diff-filter-pills\">\n <button class=\"filter-pill\" [class.active]=\"DiffFilterType === 'all'\"\n (click)=\"OnDiffFilterChange('all')\">All</button>\n <button class=\"filter-pill change-added\" [class.active]=\"DiffFilterType === 'added'\"\n (click)=\"OnDiffFilterChange('added')\">Added</button>\n <button class=\"filter-pill change-removed\" [class.active]=\"DiffFilterType === 'removed'\"\n (click)=\"OnDiffFilterChange('removed')\">Removed</button>\n <button class=\"filter-pill change-modified\" [class.active]=\"DiffFilterType === 'modified'\"\n (click)=\"OnDiffFilterChange('modified')\">Modified</button>\n </div>\n <div class=\"diff-toolbar-right\">\n <button class=\"toolbar-action-btn\" (click)=\"ExpandAllGroups()\" title=\"Expand all\">\n <i class=\"fa-solid fa-angles-down\"></i>\n </button>\n <button class=\"toolbar-action-btn\" (click)=\"CollapseAllGroups()\" title=\"Collapse all\">\n <i class=\"fa-solid fa-angles-up\"></i>\n </button>\n <div class=\"diff-sort-toggle\">\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'name'\"\n (click)=\"OnDiffSortChange('name')\" title=\"Sort by name\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'name' && DiffSortDir === 'desc' ? 'fa-arrow-up-z-a' : 'fa-arrow-down-a-z'\"></i>\n </button>\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'count'\"\n (click)=\"OnDiffSortChange('count')\" title=\"Sort by count\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'count' && DiffSortDir === 'asc' ? 'fa-arrow-up-1-9' : 'fa-arrow-down-9-1'\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n <!-- Entity Groups -->\n @if (FilteredEntityGroups.length > 0) {\n <div class=\"entity-groups\">\n @for (group of FilteredEntityGroups; track group) {\n <div class=\"entity-group\">\n <div class=\"entity-group-header\" (click)=\"ToggleEntityGroup(group)\">\n <div class=\"entity-group-left\">\n <i class=\"fa-solid fa-chevron-right entity-chevron\"\n [class.expanded]=\"group.IsExpanded\">\n </i>\n <i [class]=\"group.EntityIcon\" class=\"entity-icon\"></i>\n <span class=\"entity-group-name\">{{group.EntityName}}</span>\n </div>\n <div class=\"entity-group-badges\">\n @if (group.AddedCount > 0) {\n <span class=\"badge change-added\">\n +{{group.AddedCount}}\n </span>\n }\n @if (group.RemovedCount > 0) {\n <span class=\"badge change-removed\">\n -{{group.RemovedCount}}\n </span>\n }\n @if (group.ModifiedCount > 0) {\n <span class=\"badge change-modified\">\n ~{{group.ModifiedCount}}\n </span>\n }\n </div>\n </div>\n @if (group.IsExpanded) {\n <div class=\"entity-group-items\">\n @for (item of group.Items; track item) {\n <div class=\"diff-item-wrapper\">\n <div class=\"diff-item\" [ngClass]=\"GetChangeTypeClass(item.ChangeType)\"\n [class.clickable]=\"item.ChangeType === 'Modified'\"\n (click)=\"ToggleItem(item)\">\n <i [class]=\"GetChangeTypeIcon(item.ChangeType)\" class=\"diff-item-icon\"></i>\n <span class=\"diff-item-record\">\n {{FormatRecordID(item.RecordID)}}\n @if (item.DisplayName) {\n <span class=\"diff-item-display-name\"> ({{item.DisplayName}})</span>\n }\n </span>\n <span class=\"diff-item-type\">{{item.ChangeType}}</span>\n <button class=\"diff-item-open-btn\" (click)=\"OnOpenRecord(item); $event.stopPropagation()\"\n title=\"Open record\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n @if (item.ChangeType === 'Modified') {\n <i class=\"fa-solid fa-chevron-right diff-item-chevron\"\n [class.expanded]=\"item.IsExpanded\"\n ></i>\n }\n </div>\n <!-- Field-level changes -->\n @if (item.IsExpanded && item.ChangeType === 'Modified') {\n <div class=\"diff-fields\">\n @if (item.IsLoadingFields) {\n <mj-loading text=\"Loading changes...\" size=\"small\"></mj-loading>\n }\n @if (!item.IsLoadingFields && item.FieldChanges.length > 0) {\n @for (field of item.FieldChanges; track field) {\n <div class=\"diff-field\"\n [ngClass]=\"GetChangeTypeClass(field.ChangeType)\">\n <span class=\"diff-field-name\">{{field.FieldName}}</span>\n <span class=\"diff-field-values\">\n @if (field.OldValue) {\n <span class=\"diff-field-old\">{{field.OldValue | slice:0:60}}</span>\n }\n @if (field.OldValue && field.NewValue) {\n <i class=\"fa-solid fa-arrow-right diff-field-arrow\"></i>\n }\n @if (field.NewValue) {\n <span class=\"diff-field-new\">{{field.NewValue | slice:0:60}}</span>\n }\n </span>\n </div>\n }\n }\n @if (!item.IsLoadingFields && item.FieldsLoaded && item.FieldChanges.length === 0) {\n <div class=\"diff-fields-empty\">\n <span>No field-level changes available</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- No changes -->\n @if (FilteredEntityGroups.length === 0 && TotalChanges === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-check-circle empty-icon\" style=\"color: #10b981;\"></i>\n <h3>No differences found</h3>\n <p>The compared states are identical.</p>\n </div>\n }\n }\n <!-- No results yet -->\n @if (!HasDiffResult && !IsDiffLoading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-code-compare empty-icon\"></i>\n <h3>Select labels to compare</h3>\n <p>Choose a diff mode and select labels above, then click Compare.</p>\n </div>\n }\n }\n</div>\n", styles: [".diff-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n/* Header */\n.page-header {\n margin-bottom: 24px;\n}\n\n.page-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n/* Config Panel */\n.config-panel {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n padding: 24px;\n margin-bottom: 24px;\n}\n\n.mode-selector {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 18px;\n background: var(--hover-background, #f3f4f6);\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n transition: all 0.2s ease;\n}\n\n.mode-btn:hover {\n background: #e5e7eb;\n}\n\n.mode-btn.active {\n background: rgba(99, 102, 241, 0.08);\n border-color: #6366f1;\n color: #6366f1;\n font-weight: 600;\n}\n\n/* Label Selectors */\n.label-selectors {\n display: flex;\n align-items: flex-end;\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.selector-group {\n flex: 1;\n}\n\n.selector-label {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--text-secondary, #6b7280);\n margin-bottom: 6px;\n}\n\n.selector-input {\n width: 100%;\n padding: 10px 12px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n outline: none;\n box-sizing: border-box;\n}\n\n.selector-input:focus {\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.selector-arrow {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding-bottom: 8px;\n color: var(--text-secondary, #6b7280);\n font-size: 16px;\n}\n\n.current-state-badge {\n font-size: 11px;\n font-weight: 600;\n color: #6366f1;\n background: rgba(99, 102, 241, 0.1);\n padding: 2px 8px;\n border-radius: 8px;\n white-space: nowrap;\n}\n\n/* Run Button */\n.btn-primary {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 24px;\n background: #6366f1;\n border: none;\n border-radius: 8px;\n color: #ffffff;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover:not(:disabled) {\n background: #4f46e5;\n}\n\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Diff Summary */\n.diff-summary {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 24px;\n}\n\n.diff-stat {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n border-radius: 10px;\n border: 1px solid var(--border-color, #e5e7eb);\n}\n\n.diff-stat i {\n font-size: 16px;\n}\n\n.diff-stat-value {\n font-size: 22px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.diff-stat-label {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Change type colors */\n.change-added {\n background: rgba(16, 185, 129, 0.06);\n border-color: rgba(16, 185, 129, 0.2);\n color: #059669;\n}\n\n.change-removed {\n background: rgba(239, 68, 68, 0.06);\n border-color: rgba(239, 68, 68, 0.2);\n color: #dc2626;\n}\n\n.change-modified {\n background: rgba(245, 158, 11, 0.06);\n border-color: rgba(245, 158, 11, 0.2);\n color: #d97706;\n}\n\n.change-unchanged {\n background: rgba(107, 114, 128, 0.06);\n border-color: rgba(107, 114, 128, 0.2);\n color: #6b7280;\n}\n\n/* Entity Groups */\n.entity-groups {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.entity-group {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.entity-group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.entity-group-header:hover {\n background: var(--hover-background, #f9fafb);\n}\n\n.entity-group-left {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.entity-group-left i:first-child {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n width: 16px;\n}\n\n.entity-icon {\n color: #6366f1;\n font-size: 14px;\n}\n\n.entity-group-name {\n font-size: 15px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n}\n\n.entity-group-badges {\n display: flex;\n gap: 6px;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n border: none;\n}\n\n/* Entity chevron animation */\n.entity-chevron {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n width: 14px;\n text-align: center;\n transition: transform 0.2s ease;\n}\n\n.entity-chevron.expanded {\n transform: rotate(90deg);\n}\n\n/* Entity group items */\n.entity-group-items {\n border-top: 1px solid var(--border-color, #e5e7eb);\n padding: 8px 16px;\n}\n\n.diff-item-wrapper {\n margin-bottom: 2px;\n}\n\n.diff-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n border-radius: 6px;\n}\n\n.diff-item.clickable {\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.diff-item.clickable:hover {\n filter: brightness(0.97);\n}\n\n.diff-item-icon {\n font-size: 12px;\n width: 20px;\n text-align: center;\n}\n\n.diff-item-record {\n font-size: 13px;\n font-family: 'SF Mono', 'Fira Code', monospace;\n color: var(--text-primary, #1f2937);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-item-display-name {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n color: var(--text-secondary, #6b7280);\n font-weight: 500;\n}\n\n.diff-item-open-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--text-tertiary, #9ca3af);\n font-size: 11px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.diff-item-open-btn:hover {\n border-color: #6366f1;\n color: #6366f1;\n background: rgba(99, 102, 241, 0.06);\n}\n\n.diff-item-type {\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.diff-item-chevron {\n font-size: 10px;\n color: var(--text-tertiary, #9ca3af);\n transition: transform 0.2s ease;\n}\n\n.diff-item-chevron.expanded {\n transform: rotate(90deg);\n}\n\n/* Field-level diff changes */\n.diff-fields {\n margin-left: 42px;\n margin-bottom: 8px;\n padding: 8px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.diff-field {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.diff-field.change-added {\n background: rgba(16, 185, 129, 0.06);\n}\n\n.diff-field.change-modified {\n background: rgba(245, 158, 11, 0.06);\n}\n\n.diff-field.change-removed {\n background: rgba(239, 68, 68, 0.06);\n}\n\n.diff-field-name {\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n min-width: 120px;\n flex-shrink: 0;\n}\n\n.diff-field-values {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex: 1;\n}\n\n.diff-field-old {\n color: #ef4444;\n text-decoration: line-through;\n opacity: 0.8;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-field-arrow {\n color: var(--text-tertiary, #9ca3af);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.diff-field-new {\n color: #10b981;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-fields-empty {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n font-style: italic;\n}\n\n/* Toolbar actions */\n.diff-toolbar-right {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.toolbar-action-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n background: var(--card-background, #ffffff);\n color: var(--text-tertiary, #9ca3af);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toolbar-action-btn:hover {\n border-color: #6366f1;\n color: #6366f1;\n background: rgba(99, 102, 241, 0.06);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--text-tertiary, #9ca3af);\n margin-bottom: 16px;\n}\n\n.empty-state h3 {\n font-size: 18px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.empty-state p {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n max-width: 400px;\n}\n\n/* Swap Button */\n.swap-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 50%;\n background: var(--card-background, #ffffff);\n color: #6366f1;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.swap-btn:hover {\n background: rgba(99, 102, 241, 0.1);\n border-color: #6366f1;\n transform: rotate(180deg);\n}\n\n/* Diff Results Toolbar */\n.diff-toolbar {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n}\n\n.diff-search {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n.diff-search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--text-tertiary, #9ca3af);\n font-size: 13px;\n}\n\n.diff-search-input {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 13px;\n background: var(--card-background, #ffffff);\n color: var(--text-primary, #1f2937);\n box-sizing: border-box;\n}\n\n.diff-search-input:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.diff-filter-pills {\n display: flex;\n gap: 4px;\n}\n\n.filter-pill {\n padding: 6px 14px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 16px;\n background: var(--card-background, #ffffff);\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.filter-pill:hover {\n border-color: #6366f1;\n color: #6366f1;\n}\n\n.filter-pill.active {\n background: #6366f1;\n border-color: #6366f1;\n color: #ffffff;\n}\n\n.filter-pill.change-added.active {\n background: #059669;\n border-color: #059669;\n}\n\n.filter-pill.change-removed.active {\n background: #dc2626;\n border-color: #dc2626;\n}\n\n.filter-pill.change-modified.active {\n background: #d97706;\n border-color: #d97706;\n}\n\n.diff-sort-toggle {\n display: flex;\n gap: 2px;\n}\n\n.toggle-btn-sm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n background: var(--card-background, #ffffff);\n color: var(--text-tertiary, #9ca3af);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toggle-btn-sm:hover {\n border-color: #6366f1;\n color: #6366f1;\n}\n\n.toggle-btn-sm.active {\n background: rgba(99, 102, 241, 0.1);\n border-color: #6366f1;\n color: #6366f1;\n}\n\n@media (max-width: 768px) {\n .diff-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .label-selectors {\n flex-direction: column;\n }\n}\n"] }]
1160
1160
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.NavigationService }], null); })();
1161
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryDiffResourceComponent, { className: "VersionHistoryDiffResourceComponent", filePath: "src/versionhistory/components/diff-resource.component.ts", lineNumber: 59 }); })();
1161
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryDiffResourceComponent, { className: "VersionHistoryDiffResourceComponent", filePath: "src/VersionHistory/components/diff-resource.component.ts", lineNumber: 59 }); })();
1162
1162
  //# sourceMappingURL=diff-resource.component.js.map
@@ -517,5 +517,5 @@ export { VersionHistoryGraphResourceComponent };
517
517
  type: Component,
518
518
  args: [{ standalone: false, selector: 'mj-version-history-graph-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"graph-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading dependency graph...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Entity Dependency Graph</h2>\n <p class=\"page-subtitle\">Explore entity relationships used by the version history system</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-icon\" (click)=\"Refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n <!-- Stats Row -->\n <div class=\"stats-row\">\n <div class=\"stat-badge\">\n <i class=\"fa-solid fa-table\"></i>\n <span>{{TotalEntities}} Entities</span>\n </div>\n <div class=\"stat-badge\">\n <i class=\"fa-solid fa-diagram-project\"></i>\n <span>{{EntitiesWithDependents}} with Dependents</span>\n </div>\n <div class=\"stat-badge\">\n <i class=\"fa-solid fa-arrow-right-arrow-left\"></i>\n <span>{{TotalRelationships}} Relationships</span>\n </div>\n </div>\n <!-- Main Layout: Entity List + Detail -->\n <div class=\"graph-layout\">\n <!-- Entity List -->\n <div class=\"entity-list-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">Entities</h3>\n </div>\n <div class=\"search-bar\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Filter entities...\"\n [ngModel]=\"SearchText\"\n (ngModelChange)=\"OnSearchChange($event)\" />\n </div>\n <!-- Schema Filter Chips -->\n @if (AvailableSchemas.length > 1) {\n <div class=\"schema-chips\">\n @for (schema of AvailableSchemas; track schema) {\n <button class=\"schema-chip\"\n [class.active]=\"SchemaFilter === schema\"\n (click)=\"OnSchemaFilterChange(schema)\">\n {{schema}}\n <span class=\"schema-chip-count\">{{GetSchemaEntityCount(schema)}}</span>\n </button>\n }\n </div>\n }\n <div class=\"entity-scroll-list\">\n @for (entity of FilteredEntities; track entity) {\n <div class=\"entity-list-item\"\n [class.selected]=\"entity.IsSelected\"\n (click)=\"SelectEntity(entity)\">\n <div class=\"entity-list-name\">{{entity.Name}}</div>\n <div class=\"entity-list-badges\">\n @if (entity.ReferencedByCount > 0) {\n <span class=\"dep-badge\"\n [ngClass]=\"GetDependencyLevel(entity.ReferencedByCount)\"\n title=\"Referenced by (entities with FKs to this)\">\n {{entity.ReferencedByCount}} <i class=\"fa-solid fa-arrow-down\"></i>\n </span>\n }\n @if (entity.DependsOnCount > 0) {\n <span class=\"dep-badge level-depends-on\"\n title=\"Depends on (entities this has FKs to)\">\n {{entity.DependsOnCount}} <i class=\"fa-solid fa-arrow-up\"></i>\n </span>\n }\n </div>\n </div>\n }\n @if (FilteredEntities.length === 0) {\n <div class=\"empty-list\">\n <p>No entities match your search.</p>\n </div>\n }\n </div>\n </div>\n <!-- Detail Panel -->\n <div class=\"entity-detail-panel\">\n @if (SelectedEntity) {\n <div class=\"detail-header\">\n <i class=\"fa-solid fa-table detail-icon\"></i>\n <div class=\"detail-header-text\">\n <h3 class=\"detail-title\">{{SelectedEntity.Name}}</h3>\n <span class=\"detail-schema\">{{SelectedEntity.SchemaName}}</span>\n </div>\n </div>\n <!-- Referenced By (entities that have FKs pointing to this entity) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-down section-icon referenced-by-icon\"></i>\n <h4>Referenced By</h4>\n <span class=\"section-count\">{{ReferencedByEntities.length}}</span>\n </div>\n <p class=\"section-hint\">Entities that have foreign keys pointing to <strong>{{SelectedEntity.Name}}</strong></p>\n @if (ReferencedByEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of ReferencedByEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.ToEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.ToEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (ReferencedByEntities.length === 0) {\n <div class=\"empty-relationships\">\n <p>No entities reference this entity.</p>\n </div>\n }\n </div>\n <!-- Depends On (entities this entity has FKs to) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-up section-icon depends-on-icon\"></i>\n <h4>Depends On</h4>\n <span class=\"section-count\">{{DependsOnEntities.length}}</span>\n </div>\n <p class=\"section-hint\"><strong>{{SelectedEntity.Name}}</strong> has foreign keys pointing to these entities</p>\n @if (DependsOnEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of DependsOnEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.FromEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.FromEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (DependsOnEntities.length === 0) {\n <div class=\"empty-relationships\">\n <p>This entity has no foreign key dependencies.</p>\n </div>\n }\n </div>\n } @else {\n <div class=\"no-selection\">\n <i class=\"fa-solid fa-diagram-project no-selection-icon\"></i>\n <h3>Select an Entity</h3>\n <p>Choose an entity from the list to explore its dependency relationships.</p>\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: [".graph-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n/* Header */\n.page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.header-left { flex: 1; }\n\n.page-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions { display: flex; gap: 12px; }\n\n.btn-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--text-secondary, #6b7280);\n}\n\n.btn-icon:hover {\n background: var(--hover-background, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n/* Stats Row */\n.stats-row {\n display: flex;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.stat-badge {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 20px;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n.stat-badge i {\n color: #6366f1;\n}\n\n/* Main Layout */\n.graph-layout {\n display: grid;\n grid-template-columns: 340px 1fr;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n/* Entity List Panel */\n.entity-list-panel {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n}\n\n.panel-header {\n padding: 16px 20px 0;\n}\n\n.panel-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.search-bar {\n position: relative;\n padding: 12px 16px 8px;\n}\n\n.search-icon {\n position: absolute;\n left: 28px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--text-secondary, #6b7280);\n font-size: 13px;\n}\n\n.search-input {\n width: 100%;\n padding: 8px 12px 8px 34px;\n background: var(--hover-background, #f3f4f6);\n border: 1px solid transparent;\n border-radius: 8px;\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n outline: none;\n box-sizing: border-box;\n}\n\n.search-input:focus {\n background: var(--card-background, #ffffff);\n border-color: #6366f1;\n}\n\n/* Schema Filter Chips */\n.schema-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 0 16px 10px;\n}\n\n.schema-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--hover-background, #f3f4f6);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 14px;\n font-size: 11px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.schema-chip:hover {\n background: rgba(99, 102, 241, 0.06);\n border-color: rgba(99, 102, 241, 0.3);\n}\n\n.schema-chip.active {\n background: rgba(99, 102, 241, 0.1);\n border-color: #6366f1;\n color: #6366f1;\n}\n\n.schema-chip-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n background: rgba(0, 0, 0, 0.06);\n border-radius: 9px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.schema-chip.active .schema-chip-count {\n background: rgba(99, 102, 241, 0.15);\n}\n\n.entity-scroll-list {\n flex: 1;\n overflow-y: auto;\n padding: 0 8px 8px;\n}\n\n.entity-list-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.entity-list-item:hover {\n background: var(--hover-background, #f3f4f6);\n}\n\n.entity-list-item.selected {\n background: rgba(99, 102, 241, 0.08);\n border-left: 3px solid #6366f1;\n}\n\n.entity-list-name {\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n}\n\n.entity-list-badges {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.dep-badge {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.dep-badge i { font-size: 9px; }\n\n.level-none { display: none; }\n\n.level-low {\n background: rgba(16, 185, 129, 0.1);\n color: #059669;\n}\n\n.level-medium {\n background: rgba(245, 158, 11, 0.1);\n color: #d97706;\n}\n\n.level-high {\n background: rgba(239, 68, 68, 0.1);\n color: #dc2626;\n}\n\n.level-depends-on {\n background: rgba(99, 102, 241, 0.1);\n color: #6366f1;\n}\n\n.empty-list {\n padding: 20px;\n text-align: center;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Detail Panel */\n.entity-detail-panel {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n padding: 24px;\n overflow-y: auto;\n max-height: calc(100vh - 280px);\n}\n\n.detail-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 28px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.detail-header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-icon {\n font-size: 20px;\n color: #6366f1;\n}\n\n.detail-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.detail-schema {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Relationship Sections */\n.relationship-section {\n margin-bottom: 28px;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.section-header h4 {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0;\n flex: 1;\n}\n\n.section-hint {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n margin: 0 0 12px 0;\n}\n\n.section-hint strong {\n color: var(--text-secondary, #6b7280);\n}\n\n.section-icon {\n font-size: 14px;\n}\n\n.referenced-by-icon { color: #10b981; }\n.depends-on-icon { color: #6366f1; }\n\n.section-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 8px;\n background: var(--hover-background, #f3f4f6);\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--text-secondary, #6b7280);\n}\n\n.relationship-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.relationship-item {\n border-radius: 8px;\n transition: background 0.15s ease;\n}\n\n.relationship-item:hover {\n background: var(--hover-background, #f3f4f6);\n}\n\n.rel-main {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n}\n\n.rel-icon {\n font-size: 12px;\n color: #6366f1;\n opacity: 0.7;\n flex-shrink: 0;\n}\n\n.rel-entity-name {\n font-size: 14px;\n color: #6366f1;\n font-weight: 500;\n}\n\n.rel-entity-name:hover {\n text-decoration: underline;\n}\n\n.rel-join-field {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n font-family: 'SF Mono', 'Fira Code', monospace;\n margin-left: 4px;\n padding: 2px 8px;\n background: var(--hover-background, #f3f4f6);\n border-radius: 4px;\n}\n\n.rel-join-field i {\n font-size: 9px;\n opacity: 0.5;\n}\n\n.empty-relationships {\n padding: 12px;\n text-align: center;\n font-size: 13px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* No Selection */\n.no-selection {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n height: 100%;\n}\n\n.no-selection-icon {\n font-size: 48px;\n color: var(--text-tertiary, #9ca3af);\n margin-bottom: 16px;\n}\n\n.no-selection h3 {\n font-size: 18px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.no-selection p {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n max-width: 300px;\n}\n"] }]
519
519
  }], () => [{ type: i0.ChangeDetectorRef }], null); })();
520
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryGraphResourceComponent, { className: "VersionHistoryGraphResourceComponent", filePath: "src/versionhistory/components/graph-resource.component.ts", lineNumber: 35 }); })();
520
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryGraphResourceComponent, { className: "VersionHistoryGraphResourceComponent", filePath: "src/VersionHistory/components/graph-resource.component.ts", lineNumber: 35 }); })();
521
521
  //# sourceMappingURL=graph-resource.component.js.map
@@ -964,5 +964,5 @@ export { VersionHistoryLabelsResourceComponent };
964
964
  type: Component,
965
965
  args: [{ standalone: false, selector: 'mj-version-history-labels-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"labels-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading version labels...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Version Labels</h2>\n <p class=\"page-subtitle\">Manage versioning snapshots across your system</p>\n </div>\n <div class=\"header-actions\">\n <div class=\"view-toggle\">\n <button class=\"toggle-btn\" [class.active]=\"ViewMode === 'card'\" (click)=\"SetViewMode('card')\" title=\"Card view\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n <button class=\"toggle-btn\" [class.active]=\"ViewMode === 'list'\" (click)=\"SetViewMode('list')\" title=\"List view\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n </div>\n <button class=\"btn-primary\" (click)=\"OpenCreateDialog()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Create Label</span>\n </button>\n <button class=\"btn-icon\" (click)=\"Refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n <!-- KPI Cards -->\n <div class=\"kpi-row\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\" style=\"background: rgba(99, 102, 241, 0.1); color: #6366f1;\">\n <i class=\"fa-solid fa-tags\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{FormatNumber(TotalLabels)}}</div>\n <div class=\"kpi-label\">Total Labels</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\" style=\"background: rgba(16, 185, 129, 0.1); color: #10b981;\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{FormatNumber(ActiveLabels)}}</div>\n <div class=\"kpi-label\">Active</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\" style=\"background: rgba(107, 114, 128, 0.1); color: #6b7280;\">\n <i class=\"fa-solid fa-box-archive\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{FormatNumber(ArchivedLabels)}}</div>\n <div class=\"kpi-label\">Archived</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\" style=\"background: rgba(245, 158, 11, 0.1); color: #f59e0b;\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{FormatNumber(RestoredLabels)}}</div>\n <div class=\"kpi-label\">Restored</div>\n </div>\n </div>\n </div>\n <!-- Scope breakdown -->\n <div class=\"scope-chips\">\n @for (stat of ScopeStats; track stat) {\n <button class=\"scope-chip\"\n [class.active]=\"ScopeFilter === stat.Scope\"\n (click)=\"OnScopeFilterChange(stat.Scope)\">\n <i [class]=\"stat.Icon\"></i>\n <span>{{stat.Scope}}</span>\n <span class=\"chip-count\">{{stat.Count}}</span>\n </button>\n }\n @for (stat of StatusStats; track stat) {\n <button class=\"scope-chip\"\n [class.active]=\"StatusFilter === stat.Status\"\n [ngClass]=\"GetStatusClass(stat.Status)\"\n (click)=\"OnStatusFilterChange(stat.Status)\">\n <span>{{stat.Status}}</span>\n <span class=\"chip-count\">{{stat.Count}}</span>\n </button>\n }\n </div>\n <!-- Search -->\n <div class=\"search-bar\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Search labels by name, description, or entity...\"\n [ngModel]=\"SearchText\"\n (ngModelChange)=\"OnSearchChange($event)\" />\n @if (SearchText) {\n <button class=\"btn-clear\" (click)=\"OnSearchChange('')\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n <!-- Labels Card View -->\n @if (FilteredLabels.length > 0 && ViewMode === 'card') {\n <div class=\"labels-list\">\n @for (label of FilteredLabels; track label) {\n <div class=\"label-card clickable\"\n [class.group-parent]=\"IsGroupParent(label)\"\n (click)=\"OnLabelClick(label)\">\n <div class=\"label-header\">\n <div class=\"label-title-row\">\n <i [class]=\"GetScopeIcon(label.Scope)\" class=\"label-scope-icon\"></i>\n <h3 class=\"label-name\">{{label.Name}}</h3>\n @if (IsGroupParent(label)) {\n <span class=\"group-badge\">\n <i class=\"fa-solid fa-layer-group\"></i>\n {{GetChildLabels(label.ID).length}} records\n </span>\n }\n <span class=\"label-status\" [ngClass]=\"GetStatusClass(label.Status)\">\n {{label.Status}}\n </span>\n </div>\n <div class=\"label-meta\">\n <span class=\"meta-item\" title=\"Scope\">\n <i class=\"fa-solid fa-layer-group\"></i> {{label.Scope}}\n </span>\n @if (label.Entity || label.EntityID) {\n <span class=\"meta-item\" title=\"Entity\">\n <i class=\"fa-solid fa-table\"></i> {{label.Entity ?? ResolveEntityName(label.EntityID)}}\n </span>\n }\n @if (label.RecordID) {\n <span class=\"meta-item\" title=\"Record ID\">\n <i class=\"fa-solid fa-fingerprint\"></i> {{label.RecordID | slice:0:12}}...\n </span>\n }\n @if (label.ItemCount) {\n <span class=\"meta-item\" title=\"Items captured\">\n <i class=\"fa-solid fa-camera\"></i> {{label.ItemCount}} items\n </span>\n }\n @if (!label.ItemCount) {\n <span class=\"meta-item\" title=\"Items captured\">\n <i class=\"fa-solid fa-camera\"></i> {{GetItemCount(label.ID)}} items\n </span>\n }\n @if (label.CreationDurationMS) {\n <span class=\"meta-item\" title=\"Creation time\">\n <i class=\"fa-solid fa-stopwatch\"></i> {{FormatDuration(label.CreationDurationMS)}}\n </span>\n }\n @if (label.CreatedByUser) {\n <span class=\"meta-item\" title=\"Created by\">\n <i class=\"fa-solid fa-user\"></i> {{label.CreatedByUser}}\n </span>\n }\n <span class=\"meta-item\" title=\"Created\">\n <i class=\"fa-regular fa-clock\"></i> {{FormatDate(label.__mj_CreatedAt)}}\n </span>\n </div>\n </div>\n @if (label.Description) {\n <p class=\"label-description\">{{label.Description}}</p>\n }\n <!-- Child labels for group parents -->\n @if (IsGroupParent(label) && GetChildLabels(label.ID).length > 0) {\n <div class=\"child-labels\">\n @for (child of GetChildLabels(label.ID); track child) {\n <div class=\"child-label\">\n <i class=\"fa-solid fa-tag child-icon\"></i>\n <span class=\"child-name\">{{child.Name}}</span>\n @if (child.RecordID) {\n <span class=\"child-record\">{{child.RecordID | slice:0:12}}...</span>\n }\n @if (child.ItemCount) {\n <span class=\"child-items\">{{child.ItemCount}} items</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- Labels List View -->\n @if (FilteredLabels.length > 0 && ViewMode === 'list') {\n <div class=\"labels-table\">\n <div class=\"list-header-row\">\n <span class=\"list-col-icon\"></span>\n <span class=\"list-col-name sortable-header\" (click)=\"OnSortChange('Name')\">\n Name <i [class]=\"GetSortIcon('Name')\" class=\"sort-icon\"></i>\n </span>\n <span class=\"list-col-entity\">Entity</span>\n <span class=\"list-col-status sortable-header\" (click)=\"OnSortChange('Status')\">\n Status <i [class]=\"GetSortIcon('Status')\" class=\"sort-icon\"></i>\n </span>\n <span class=\"list-col-items sortable-header\" (click)=\"OnSortChange('Items')\">\n Items <i [class]=\"GetSortIcon('Items')\" class=\"sort-icon\"></i>\n </span>\n <span class=\"list-col-date sortable-header\" (click)=\"OnSortChange('Date')\">\n Created <i [class]=\"GetSortIcon('Date')\" class=\"sort-icon\"></i>\n </span>\n <span class=\"list-col-arrow\"></span>\n </div>\n @for (label of FilteredLabels; track label) {\n <div class=\"list-row clickable\"\n (click)=\"OnLabelClick(label)\">\n <span class=\"list-col-icon\">\n <i [class]=\"GetScopeIcon(label.Scope)\" class=\"list-scope-icon\"></i>\n </span>\n <span class=\"list-col-name\">\n <span class=\"list-label-name\">{{label.Name}}</span>\n @if (IsGroupParent(label)) {\n <span class=\"list-group-badge\">\n <i class=\"fa-solid fa-layer-group\"></i> {{GetChildLabels(label.ID).length}}\n </span>\n }\n </span>\n <span class=\"list-col-entity\">{{label.Entity ?? ResolveEntityName(label.EntityID)}}</span>\n <span class=\"list-col-status\">\n <span class=\"label-status small\" [ngClass]=\"GetStatusClass(label.Status)\">{{label.Status}}</span>\n </span>\n <span class=\"list-col-items\">{{label.ItemCount || GetItemCount(label.ID)}}</span>\n <span class=\"list-col-date\">{{FormatDate(label.__mj_CreatedAt)}}</span>\n <span class=\"list-col-arrow\">\n <i class=\"fa-solid fa-chevron-right list-arrow\"></i>\n </span>\n </div>\n }\n </div>\n }\n <!-- Empty state -->\n @if (FilteredLabels.length === 0 && !IsLoading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-tags empty-icon\"></i>\n <h3>No labels found</h3>\n @if (SearchText || ScopeFilter || StatusFilter) {\n <p>\n Try adjusting your filters or search criteria.\n </p>\n }\n @if (!SearchText && !ScopeFilter && !StatusFilter) {\n <p>\n No version labels have been created yet.\n </p>\n }\n @if (!SearchText && !ScopeFilter && !StatusFilter) {\n <button class=\"btn-primary empty-cta\"\n (click)=\"OpenCreateDialog()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Create Your First Label</span>\n </button>\n }\n </div>\n }\n }\n\n <!-- Create Label Wizard -->\n @if (ShowCreateWizard) {\n <div class=\"create-wizard-overlay\" (click)=\"OnCreateWizardCancel()\">\n <div class=\"create-wizard-container\" (click)=\"$event.stopPropagation()\">\n <div class=\"create-wizard-header\">\n <h3 class=\"create-wizard-title\">\n <i class=\"fa-solid fa-tag\"></i>\n Create Version Label\n </h3>\n <button class=\"create-wizard-close\" (click)=\"OnCreateWizardCancel()\" title=\"Close\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"create-wizard-body\">\n <mj-label-create\n (Created)=\"OnLabelCreated($event)\"\n (Cancel)=\"OnCreateWizardCancel()\">\n </mj-label-create>\n </div>\n </div>\n </div>\n }\n\n <!-- Detail panel -->\n @if (ShowDetailPanel && SelectedLabel) {\n <mj-label-detail-panel\n [Label]=\"SelectedLabel\"\n [AllLabels]=\"Labels\"\n [ItemCountMap]=\"ItemCountMap\"\n (Close)=\"OnDetailPanelClose()\"\n (LabelUpdated)=\"OnLabelUpdated()\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\">\n </mj-label-detail-panel>\n }\n</div>\n", styles: [".labels-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n/* Header */\n.page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left { flex: 1; }\n\n.page-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions {\n display: flex;\n gap: 12px;\n align-items: center;\n}\n\n.btn-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--text-secondary, #6b7280);\n}\n\n.btn-icon:hover {\n background: var(--hover-background, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n.btn-primary {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: #6366f1;\n color: #ffffff;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover {\n background: #4f46e5;\n}\n\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-secondary {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: var(--card-background, #ffffff);\n color: var(--text-secondary, #6b7280);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-secondary:hover {\n background: var(--hover-background, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n/* KPI Row */\n.kpi-row {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n}\n\n.kpi-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n border-radius: 12px;\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.kpi-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n line-height: 1;\n}\n\n.kpi-label {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n margin-top: 4px;\n}\n\n/* Scope Chips */\n.scope-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.scope-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 20px;\n cursor: pointer;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n transition: all 0.2s ease;\n}\n\n.scope-chip:hover {\n background: var(--hover-background, #f3f4f6);\n border-color: var(--border-hover, #d1d5db);\n}\n\n.scope-chip.active {\n background: #6366f1;\n border-color: #6366f1;\n color: #ffffff;\n}\n\n.scope-chip.active .chip-count {\n background: rgba(255, 255, 255, 0.2);\n color: #ffffff;\n}\n\n.chip-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--hover-background, #f3f4f6);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n/* Search Bar */\n.search-bar {\n position: relative;\n margin-bottom: 20px;\n}\n\n.search-icon {\n position: absolute;\n left: 14px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--text-secondary, #6b7280);\n font-size: 14px;\n}\n\n.search-input {\n width: 100%;\n padding: 10px 40px 10px 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n outline: none;\n transition: border-color 0.2s ease;\n box-sizing: border-box;\n}\n\n.search-input:focus {\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.search-input::placeholder {\n color: var(--text-tertiary, #9ca3af);\n}\n\n.btn-clear {\n position: absolute;\n right: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n border-radius: 4px;\n}\n\n.btn-clear:hover {\n color: var(--text-primary, #1f2937);\n background: var(--hover-background, #f3f4f6);\n}\n\n/* Labels List */\n.labels-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.label-card {\n padding: 20px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n transition: all 0.2s ease;\n}\n\n.label-card:hover {\n border-color: var(--border-hover, #d1d5db);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n}\n\n.label-card.group-parent {\n border-left: 3px solid #6366f1;\n}\n\n.label-header {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.label-title-row {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.label-scope-icon {\n color: #6366f1;\n font-size: 16px;\n}\n\n.label-name {\n font-size: 16px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0;\n flex: 1;\n}\n\n.group-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 10px;\n background: rgba(99, 102, 241, 0.1);\n color: #6366f1;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.label-status {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-active {\n background: rgba(16, 185, 129, 0.1);\n color: #059669;\n}\n\n.status-archived {\n background: rgba(107, 114, 128, 0.1);\n color: #6b7280;\n}\n\n.status-restored {\n background: rgba(245, 158, 11, 0.1);\n color: #d97706;\n}\n\n.label-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 16px;\n margin-top: 4px;\n}\n\n.meta-item {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n.meta-item i {\n font-size: 12px;\n opacity: 0.7;\n}\n\n.label-description {\n margin: 10px 0 0 0;\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n line-height: 1.5;\n}\n\n/* Child labels */\n.child-labels {\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--border-color, #e5e7eb);\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.child-label {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.child-label:hover {\n background: var(--hover-background, #f3f4f6);\n}\n\n.child-icon {\n color: var(--text-tertiary, #9ca3af);\n font-size: 11px;\n}\n\n.child-name {\n flex: 1;\n color: var(--text-primary, #1f2937);\n}\n\n.child-record {\n color: var(--text-tertiary, #9ca3af);\n font-size: 12px;\n font-family: monospace;\n}\n\n.child-items {\n color: var(--text-secondary, #6b7280);\n font-size: 12px;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--text-tertiary, #9ca3af);\n margin-bottom: 16px;\n}\n\n.empty-state h3 {\n font-size: 18px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.empty-state p {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n max-width: 400px;\n}\n\n.empty-cta {\n margin-top: 20px;\n}\n\n/* ==================================================================== */\n/* Create Label Dialog */\n/* ==================================================================== */\n\n/* Step Indicator */\n.step-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0;\n margin-bottom: 24px;\n padding: 0 20px;\n}\n\n.step {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.step-number {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n font-size: 13px;\n font-weight: 700;\n background: var(--hover-background, #f3f4f6);\n color: var(--text-tertiary, #9ca3af);\n transition: all 0.2s ease;\n}\n\n.step.active .step-number {\n background: #6366f1;\n color: #ffffff;\n}\n\n.step.completed .step-number {\n background: #10b981;\n color: #ffffff;\n}\n\n.step-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.step.active .step-label {\n color: var(--text-primary, #1f2937);\n font-weight: 600;\n}\n\n.step.completed .step-label {\n color: #10b981;\n}\n\n.step-connector {\n width: 40px;\n height: 2px;\n background: var(--border-color, #e5e7eb);\n margin: 0 8px;\n transition: background 0.2s ease;\n}\n\n.step-connector.active {\n background: #10b981;\n}\n\n/* Dialog Step Content */\n.dialog-step {\n display: flex;\n flex-direction: column;\n gap: 16px;\n min-height: 300px;\n}\n\n.step-description {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.step-header-row {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.btn-back {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: none;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.btn-back:hover {\n background: var(--hover-background, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n/* Dialog Search */\n.dialog-search {\n position: relative;\n}\n\n.dialog-search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--text-tertiary, #9ca3af);\n font-size: 13px;\n}\n\n.dialog-search-input {\n width: 100%;\n padding: 9px 12px 9px 36px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n outline: none;\n box-sizing: border-box;\n transition: border-color 0.15s ease;\n}\n\n.dialog-search-input:focus {\n border-color: #6366f1;\n}\n\n.dialog-search-input::placeholder {\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* Entity List */\n.entity-list {\n flex: 1;\n overflow-y: auto;\n max-height: 320px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n}\n\n.entity-option {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.15s ease;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.entity-option:last-child {\n border-bottom: none;\n}\n\n.entity-option:hover {\n background: var(--hover-background, #f3f4f6);\n}\n\n.entity-option-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.entity-option-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--text-primary, #1f2937);\n}\n\n.entity-option-desc {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.entity-option-arrow {\n color: var(--text-tertiary, #9ca3af);\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.entity-list-empty {\n padding: 40px 20px;\n text-align: center;\n color: var(--text-tertiary, #9ca3af);\n font-size: 14px;\n}\n\n/* Records */\n.records-toolbar {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.selection-actions {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.btn-text {\n padding: 6px 12px;\n background: none;\n border: none;\n font-size: 13px;\n font-weight: 500;\n color: #6366f1;\n cursor: pointer;\n border-radius: 6px;\n transition: background 0.15s ease;\n}\n\n.btn-text:hover {\n background: rgba(99, 102, 241, 0.1);\n}\n\n.record-list {\n flex: 1;\n overflow-y: auto;\n max-height: 280px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n}\n\n.record-option {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 16px;\n cursor: pointer;\n transition: background 0.15s ease;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.record-option:last-child {\n border-bottom: none;\n}\n\n.record-option:hover {\n background: var(--hover-background, #f3f4f6);\n}\n\n.record-option.selected {\n background: rgba(99, 102, 241, 0.05);\n}\n\n.record-checkbox {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border: 2px solid var(--border-color, #d1d5db);\n border-radius: 4px;\n font-size: 11px;\n color: transparent;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.record-option.selected .record-checkbox {\n background: #6366f1;\n border-color: #6366f1;\n color: #ffffff;\n}\n\n.record-name {\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.records-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding-top: 8px;\n}\n\n.selection-count {\n font-size: 13px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Details step */\n.details-summary {\n display: flex;\n flex-wrap: wrap;\n gap: 16px;\n padding: 14px 16px;\n background: var(--hover-background, #f3f4f6);\n border-radius: 10px;\n}\n\n.summary-item {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n.summary-item i {\n color: #6366f1;\n font-size: 13px;\n}\n\n.form-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.form-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n}\n\n.form-input {\n padding: 10px 14px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n outline: none;\n transition: border-color 0.15s ease;\n}\n\n.form-input:focus {\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.form-input::placeholder {\n color: var(--text-tertiary, #9ca3af);\n}\n\n.form-textarea {\n padding: 10px 14px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n outline: none;\n resize: vertical;\n font-family: inherit;\n transition: border-color 0.15s ease;\n}\n\n.form-textarea:focus {\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.form-textarea::placeholder {\n color: var(--text-tertiary, #9ca3af);\n}\n\n.details-footer {\n display: flex;\n gap: 12px;\n padding-top: 8px;\n}\n\n/* Creating state */\n.creating-step {\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 40px 20px;\n}\n\n.creating-animation {\n margin-bottom: 16px;\n}\n\n.creating-icon {\n font-size: 40px;\n color: #6366f1;\n}\n\n.creating-title {\n font-size: 18px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.creating-progress {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n/* Progress bar */\n.progress-container {\n width: 100%;\n max-width: 420px;\n margin: 16px auto 0;\n text-align: left;\n}\n\n.progress-bar-track {\n width: 100%;\n height: 8px;\n background: var(--hover-background, #e5e7eb);\n border-radius: 4px;\n overflow: hidden;\n}\n\n.progress-bar-fill {\n height: 100%;\n background: linear-gradient(90deg, #6366f1, #818cf8);\n border-radius: 4px;\n transition: width 0.3s ease;\n}\n\n.progress-details {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-top: 8px;\n}\n\n.progress-message {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n margin-right: 12px;\n}\n\n.progress-pct {\n font-size: 13px;\n font-weight: 600;\n color: #6366f1;\n white-space: nowrap;\n}\n\n.progress-stats {\n display: flex;\n gap: 16px;\n margin-top: 6px;\n}\n\n.progress-stat {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n.progress-stat i {\n font-size: 11px;\n}\n\n/* Done state */\n.done-step {\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 40px 20px;\n}\n\n.done-icon-wrap {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 56px;\n border-radius: 50%;\n font-size: 24px;\n margin-bottom: 16px;\n}\n\n.done-icon-wrap.success {\n background: rgba(16, 185, 129, 0.1);\n color: #10b981;\n}\n\n.done-icon-wrap.error {\n background: rgba(239, 68, 68, 0.1);\n color: #ef4444;\n}\n\n.done-title {\n font-size: 18px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.done-message {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0 0 20px 0;\n}\n\n.error-text {\n color: #ef4444;\n}\n\n/* View Toggle */\n.view-toggle {\n display: flex;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.toggle-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--text-tertiary, #9ca3af);\n transition: all 0.15s ease;\n font-size: 14px;\n}\n\n.toggle-btn:hover {\n color: var(--text-primary, #1f2937);\n background: var(--hover-background, #f3f4f6);\n}\n\n.toggle-btn.active {\n color: #6366f1;\n background: rgba(99, 102, 241, 0.08);\n}\n\n.toggle-btn + .toggle-btn {\n border-left: 1px solid var(--border-color, #e5e7eb);\n}\n\n/* Clickable cards/rows */\n.clickable {\n cursor: pointer;\n}\n\n.label-card.clickable:hover {\n border-color: #6366f1;\n box-shadow: 0 2px 12px rgba(99, 102, 241, 0.1);\n transform: translateY(-1px);\n}\n\n/* Labels Table (List View) */\n.labels-table {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.list-header-row {\n display: grid;\n grid-template-columns: 40px 1fr 160px 90px 60px 100px 32px;\n align-items: center;\n padding: 10px 16px;\n background: var(--hover-background, #f9fafb);\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n font-size: 12px;\n font-weight: 600;\n color: var(--text-tertiary, #9ca3af);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n.list-row {\n display: grid;\n grid-template-columns: 40px 1fr 160px 90px 60px 100px 32px;\n align-items: center;\n padding: 12px 16px;\n border-bottom: 1px solid var(--border-color, #f3f4f6);\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n transition: all 0.15s ease;\n}\n\n.list-row:last-child {\n border-bottom: none;\n}\n\n.list-row:hover {\n background: rgba(99, 102, 241, 0.04);\n}\n\n.list-scope-icon {\n color: #6366f1;\n font-size: 15px;\n}\n\n.list-col-name {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n.list-label-name {\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.list-group-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: rgba(99, 102, 241, 0.1);\n color: #6366f1;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n flex-shrink: 0;\n}\n\n.list-col-entity {\n color: var(--text-secondary, #6b7280);\n font-size: 13px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.list-col-items {\n text-align: center;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n.list-col-date {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n.list-col-arrow {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.list-arrow {\n color: var(--text-tertiary, #d1d5db);\n font-size: 12px;\n transition: transform 0.15s ease, color 0.15s ease;\n}\n\n.list-row:hover .list-arrow {\n color: #6366f1;\n transform: translateX(2px);\n}\n\n.label-status.small {\n padding: 2px 8px;\n font-size: 11px;\n}\n\n/* Sortable headers */\n.sortable-header {\n cursor: pointer;\n user-select: none;\n display: flex;\n align-items: center;\n gap: 4px;\n transition: color 0.15s ease;\n}\n\n.sortable-header:hover {\n color: #6366f1;\n}\n\n.sort-icon {\n font-size: 10px;\n opacity: 0.4;\n transition: opacity 0.15s ease;\n}\n\n.sortable-header:hover .sort-icon {\n opacity: 0.8;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .kpi-row {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .list-header-row,\n .list-row {\n grid-template-columns: 36px 1fr 80px 60px 32px;\n }\n\n .list-col-entity,\n .list-col-date {\n display: none;\n }\n}\n\n/* ================================================================= */\n/* CREATE WIZARD OVERLAY */\n/* ================================================================= */\n\n.create-wizard-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: fadeIn 0.15s ease;\n}\n\n.create-wizard-container {\n background: white;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n width: 90%;\n max-width: 600px;\n max-height: 85vh;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.create-wizard-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n flex-shrink: 0;\n}\n\n.create-wizard-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.create-wizard-title i {\n color: #6366f1;\n font-size: 15px;\n}\n\n.create-wizard-close {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: none;\n border: none;\n border-radius: 8px;\n color: var(--text-tertiary, #9ca3af);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.create-wizard-close:hover {\n background: var(--hover-background, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n.create-wizard-body {\n padding: 24px;\n overflow-y: auto;\n flex: 1;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n"] }]
966
966
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.NavigationService }], null); })();
967
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryLabelsResourceComponent, { className: "VersionHistoryLabelsResourceComponent", filePath: "src/versionhistory/components/labels-resource.component.ts", lineNumber: 40 }); })();
967
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryLabelsResourceComponent, { className: "VersionHistoryLabelsResourceComponent", filePath: "src/VersionHistory/components/labels-resource.component.ts", lineNumber: 40 }); })();
968
968
  //# sourceMappingURL=labels-resource.component.js.map
@@ -468,5 +468,5 @@ export { VersionHistoryRestoreResourceComponent };
468
468
  type: Component,
469
469
  args: [{ standalone: false, selector: 'mj-version-history-restore-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"restore-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading restore history...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Restore History</h2>\n <p class=\"page-subtitle\">Track all restore operations and their outcomes</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-icon\" (click)=\"Refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n <!-- KPI Cards -->\n <div class=\"kpi-row\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\" style=\"background: rgba(99, 102, 241, 0.1); color: #6366f1;\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{TotalRestores}}</div>\n <div class=\"kpi-label\">Total Restores</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\" style=\"background: rgba(16, 185, 129, 0.1); color: #10b981;\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{SuccessfulRestores}}</div>\n <div class=\"kpi-label\">Successful</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\" style=\"background: rgba(239, 68, 68, 0.1); color: #ef4444;\">\n <i class=\"fa-solid fa-circle-xmark\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{FailedRestores}}</div>\n <div class=\"kpi-label\">Failed</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\" style=\"background: rgba(245, 158, 11, 0.1); color: #f59e0b;\">\n <i class=\"fa-solid fa-circle-half-stroke\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{PartialRestores}}</div>\n <div class=\"kpi-label\">Partial</div>\n </div>\n </div>\n </div>\n <!-- Filters -->\n <div class=\"filter-row\">\n <button class=\"filter-chip\"\n [class.active]=\"StatusFilter === 'Complete'\"\n (click)=\"OnStatusFilterChange('Complete')\">\n <i class=\"fa-solid fa-circle-check\"></i> Complete\n </button>\n <button class=\"filter-chip\"\n [class.active]=\"StatusFilter === 'Error'\"\n (click)=\"OnStatusFilterChange('Error')\">\n <i class=\"fa-solid fa-circle-xmark\"></i> Error\n </button>\n <button class=\"filter-chip\"\n [class.active]=\"StatusFilter === 'Partial'\"\n (click)=\"OnStatusFilterChange('Partial')\">\n <i class=\"fa-solid fa-circle-half-stroke\"></i> Partial\n </button>\n </div>\n <!-- Restore List -->\n @if (FilteredRestores.length > 0) {\n <div class=\"restore-list\">\n @for (restore of FilteredRestores; track restore) {\n <div class=\"restore-card\"\n [ngClass]=\"{'expanded': IsExpanded(restore.ID)}\">\n <div class=\"restore-header\" (click)=\"ToggleExpand(restore.ID)\">\n <div class=\"restore-header-left\">\n <i [class]=\"GetStatusIcon(restore.Status)\"\n [ngClass]=\"GetStatusClass(restore.Status)\"\n class=\"status-icon\"></i>\n <div class=\"restore-info\">\n <div class=\"restore-label-name\">\n {{restore.VersionLabel}}\n </div>\n @if (restore.StartedAt) {\n <div class=\"restore-date\">{{FormatDate(restore.StartedAt)}}</div>\n }\n </div>\n </div>\n <div class=\"restore-header-right\">\n <div class=\"restore-progress-bar\">\n <div class=\"progress-fill\"\n [ngClass]=\"GetStatusClass(restore.Status)\"\n [style.width.%]=\"GetProgressPercent(restore)\">\n </div>\n </div>\n <span class=\"restore-count\">\n {{restore.CompletedItems ?? 0}} / {{restore.TotalItems ?? 0}} items\n </span>\n <i class=\"fa-solid\"\n [ngClass]=\"IsExpanded(restore.ID) ? 'fa-chevron-up' : 'fa-chevron-down'\"\n class=\"expand-icon\">\n </i>\n </div>\n </div>\n <!-- Expanded Details -->\n @if (IsExpanded(restore.ID)) {\n <div class=\"restore-details\">\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Status</span>\n <span class=\"detail-value\" [ngClass]=\"GetStatusClass(restore.Status)\">\n {{restore.Status}}\n </span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Items Completed</span>\n <span class=\"detail-value\">{{restore.CompletedItems ?? 0}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Items Failed</span>\n <span class=\"detail-value\" [class.text-error]=\"(restore.FailedItems ?? 0) > 0\">\n {{restore.FailedItems ?? 0}}\n </span>\n </div>\n @if (restore.User) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Restored By</span>\n <span class=\"detail-value\">{{restore.User}}</span>\n </div>\n }\n @if (restore.PreRestoreLabelID) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Pre-Restore Label</span>\n @if (restore.PreRestoreLabel) {\n <span class=\"detail-value detail-mono\">\n {{restore.PreRestoreLabel}}\n </span>\n }\n @if (!restore.PreRestoreLabel) {\n <span class=\"detail-value detail-mono\">\n {{restore.PreRestoreLabelID | slice:0:20}}...\n </span>\n }\n </div>\n }\n </div>\n @if (restore.ErrorLog) {\n <div class=\"error-log\">\n <div class=\"error-log-header\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n Error Log\n </div>\n <pre class=\"error-log-content\">{{restore.ErrorLog}}</pre>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (FilteredRestores.length === 0 && !IsLoading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-clock-rotate-left empty-icon\"></i>\n <h3>No restore operations found</h3>\n @if (StatusFilter) {\n <p>\n Try adjusting your filters.\n </p>\n }\n @if (!StatusFilter) {\n <p>\n No restores have been performed yet. Use the VersionHistoryEngine to restore records to a labeled state.\n </p>\n }\n </div>\n }\n }\n</div>\n", styles: [".restore-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n/* Header */\n.page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left { flex: 1; }\n\n.page-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions { display: flex; gap: 12px; }\n\n.btn-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--text-secondary, #6b7280);\n}\n\n.btn-icon:hover {\n background: var(--hover-background, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n/* KPI Row */\n.kpi-row {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n}\n\n.kpi-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n border-radius: 12px;\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.kpi-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n line-height: 1;\n}\n\n.kpi-label {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n margin-top: 4px;\n}\n\n/* Filter Row */\n.filter-row {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.filter-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 20px;\n cursor: pointer;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n transition: all 0.2s ease;\n}\n\n.filter-chip:hover {\n background: var(--hover-background, #f3f4f6);\n}\n\n.filter-chip.active {\n background: #6366f1;\n border-color: #6366f1;\n color: #ffffff;\n}\n\n/* Restore List */\n.restore-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.restore-card {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.2s ease;\n}\n\n.restore-card:hover {\n border-color: var(--border-hover, #d1d5db);\n}\n\n.restore-card.expanded {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n}\n\n.restore-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n cursor: pointer;\n}\n\n.restore-header-left {\n display: flex;\n align-items: center;\n gap: 14px;\n}\n\n.status-icon {\n font-size: 20px;\n}\n\n.status-success { color: #10b981; }\n.status-failed { color: #ef4444; }\n.status-progress { color: #6366f1; }\n.status-pending { color: #f59e0b; }\n\n.restore-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.restore-label-name {\n font-size: 15px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.dry-run-badge {\n font-size: 10px;\n font-weight: 700;\n padding: 2px 8px;\n background: rgba(245, 158, 11, 0.1);\n color: #d97706;\n border-radius: 8px;\n letter-spacing: 0.5px;\n}\n\n.restore-date {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n.restore-header-right {\n display: flex;\n align-items: center;\n gap: 14px;\n}\n\n.restore-progress-bar {\n width: 80px;\n height: 6px;\n background: var(--hover-background, #f3f4f6);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.progress-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.3s ease;\n}\n\n.progress-fill.status-success { background: #10b981; }\n.progress-fill.status-failed { background: #ef4444; }\n.progress-fill.status-progress { background: #6366f1; }\n.progress-fill.status-pending { background: #f59e0b; }\n\n.restore-count {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n white-space: nowrap;\n}\n\n.expand-icon {\n color: var(--text-tertiary, #9ca3af);\n font-size: 12px;\n}\n\n/* Expanded Details */\n.restore-details {\n padding: 0 20px 20px;\n border-top: 1px solid var(--border-color, #e5e7eb);\n}\n\n.detail-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 16px;\n padding-top: 16px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.detail-label {\n font-size: 12px;\n font-weight: 600;\n color: var(--text-secondary, #6b7280);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.detail-value {\n font-size: 15px;\n color: var(--text-primary, #1f2937);\n font-weight: 500;\n}\n\n.detail-mono {\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 13px;\n}\n\n.text-error {\n color: #ef4444;\n}\n\n/* Error Log */\n.error-log {\n margin-top: 16px;\n border: 1px solid rgba(239, 68, 68, 0.2);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.error-log-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: rgba(239, 68, 68, 0.06);\n color: #dc2626;\n font-size: 13px;\n font-weight: 600;\n}\n\n.error-log-content {\n margin: 0;\n padding: 12px 14px;\n font-size: 12px;\n font-family: 'SF Mono', 'Fira Code', monospace;\n color: var(--text-primary, #1f2937);\n background: var(--card-background, #ffffff);\n overflow-x: auto;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--text-tertiary, #9ca3af);\n margin-bottom: 16px;\n}\n\n.empty-state h3 {\n font-size: 18px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.empty-state p {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n max-width: 400px;\n}\n\n@media (max-width: 768px) {\n .kpi-row { grid-template-columns: repeat(2, 1fr); }\n}\n"] }]
470
470
  }], () => [{ type: i0.ChangeDetectorRef }], null); })();
471
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryRestoreResourceComponent, { className: "VersionHistoryRestoreResourceComponent", filePath: "src/versionhistory/components/restore-resource.component.ts", lineNumber: 19 }); })();
471
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryRestoreResourceComponent, { className: "VersionHistoryRestoreResourceComponent", filePath: "src/VersionHistory/components/restore-resource.component.ts", lineNumber: 19 }); })();
472
472
  //# sourceMappingURL=restore-resource.component.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-dashboards",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "description": "MemberJunction Dashboards",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -33,43 +33,43 @@
33
33
  "@codemirror/merge": "^6.11.2",
34
34
  "@codemirror/state": "^6.5.4",
35
35
  "@codemirror/view": "^6.39.12",
36
- "@memberjunction/actions-base": "4.0.0",
37
- "@memberjunction/ai-engine-base": "4.0.0",
38
- "@memberjunction/api-keys-base": "4.0.0",
39
- "@memberjunction/ai-core-plus": "4.0.0",
40
- "@memberjunction/core": "4.0.0",
41
- "@memberjunction/export-engine": "4.0.0",
42
- "@memberjunction/ng-entity-relationship-diagram": "4.0.0",
43
- "@memberjunction/core-entities": "4.0.0",
44
- "@memberjunction/global": "4.0.0",
45
- "@memberjunction/graphql-dataprovider": "4.0.0",
46
- "@memberjunction/interactive-component-types": "4.0.0",
47
- "@memberjunction/ng-action-gallery": "4.0.0",
48
- "@memberjunction/ng-actions": "4.0.0",
49
- "@memberjunction/ng-agents": "4.0.0",
50
- "@memberjunction/ng-ai-test-harness": "4.0.0",
51
- "@memberjunction/ng-base-application": "4.0.0",
52
- "@memberjunction/ng-code-editor": "4.0.0",
53
- "@memberjunction/ng-container-directives": "4.0.0",
54
- "@memberjunction/ng-core-entity-forms": "4.0.0",
55
- "@memberjunction/ng-credentials": "4.0.0",
56
- "@memberjunction/ng-dashboard-viewer": "4.0.0",
57
- "@memberjunction/ng-entity-viewer": "4.0.0",
58
- "@memberjunction/ng-export-service": "4.0.0",
59
- "@memberjunction/ng-filter-builder": "4.0.0",
60
- "@memberjunction/ng-list-management": "4.0.0",
61
- "@memberjunction/ng-explorer-settings": "4.0.0",
62
- "@memberjunction/ng-notifications": "4.0.0",
63
- "@memberjunction/ng-query-viewer": "4.0.0",
64
- "@memberjunction/ng-react": "4.0.0",
65
- "@memberjunction/ng-shared": "4.0.0",
66
- "@memberjunction/ng-shared-generic": "4.0.0",
67
- "@memberjunction/ng-versions": "4.0.0",
68
- "@memberjunction/ng-testing": "4.0.0",
69
- "@memberjunction/skip-types": "4.0.0",
70
- "@memberjunction/templates-base-types": "4.0.0",
71
- "@memberjunction/testing-engine-base": "4.0.0",
72
- "@memberjunction/ng-markdown": "4.0.0",
36
+ "@memberjunction/actions-base": "4.2.0",
37
+ "@memberjunction/ai-engine-base": "4.2.0",
38
+ "@memberjunction/api-keys-base": "4.2.0",
39
+ "@memberjunction/ai-core-plus": "4.2.0",
40
+ "@memberjunction/core": "4.2.0",
41
+ "@memberjunction/export-engine": "4.2.0",
42
+ "@memberjunction/ng-entity-relationship-diagram": "4.2.0",
43
+ "@memberjunction/core-entities": "4.2.0",
44
+ "@memberjunction/global": "4.2.0",
45
+ "@memberjunction/graphql-dataprovider": "4.2.0",
46
+ "@memberjunction/interactive-component-types": "4.2.0",
47
+ "@memberjunction/ng-action-gallery": "4.2.0",
48
+ "@memberjunction/ng-actions": "4.2.0",
49
+ "@memberjunction/ng-agents": "4.2.0",
50
+ "@memberjunction/ng-ai-test-harness": "4.2.0",
51
+ "@memberjunction/ng-base-application": "4.2.0",
52
+ "@memberjunction/ng-code-editor": "4.2.0",
53
+ "@memberjunction/ng-container-directives": "4.2.0",
54
+ "@memberjunction/ng-core-entity-forms": "4.2.0",
55
+ "@memberjunction/ng-credentials": "4.2.0",
56
+ "@memberjunction/ng-dashboard-viewer": "4.2.0",
57
+ "@memberjunction/ng-entity-viewer": "4.2.0",
58
+ "@memberjunction/ng-export-service": "4.2.0",
59
+ "@memberjunction/ng-filter-builder": "4.2.0",
60
+ "@memberjunction/ng-list-management": "4.2.0",
61
+ "@memberjunction/ng-explorer-settings": "4.2.0",
62
+ "@memberjunction/ng-notifications": "4.2.0",
63
+ "@memberjunction/ng-query-viewer": "4.2.0",
64
+ "@memberjunction/ng-react": "4.2.0",
65
+ "@memberjunction/ng-shared": "4.2.0",
66
+ "@memberjunction/ng-shared-generic": "4.2.0",
67
+ "@memberjunction/ng-versions": "4.2.0",
68
+ "@memberjunction/ng-testing": "4.2.0",
69
+ "@memberjunction/skip-types": "4.2.0",
70
+ "@memberjunction/templates-base-types": "4.2.0",
71
+ "@memberjunction/testing-engine-base": "4.2.0",
72
+ "@memberjunction/ng-markdown": "4.2.0",
73
73
  "@progress/kendo-angular-buttons": "22.0.1",
74
74
  "@progress/kendo-angular-dateinputs": "22.0.1",
75
75
  "@progress/kendo-angular-dialog": "22.0.1",