@memberjunction/ng-dashboards 5.22.0 → 5.24.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 (245) hide show
  1. package/README.md +51 -0
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js +364 -362
  4. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  5. package/dist/AI/components/agents/agent-editor.component.js +2 -2
  6. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +947 -64
  7. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  8. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +7645 -430
  9. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  10. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +285 -6
  11. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  12. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +2454 -277
  13. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  14. package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
  15. package/dist/AI/components/execution-monitoring.component.js +191 -197
  16. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  17. package/dist/AI/components/models/model-management.component.js +9 -8
  18. package/dist/AI/components/models/model-management.component.js.map +1 -1
  19. package/dist/AI/components/prompts/prompt-management.component.js +305 -299
  20. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  21. package/dist/AI/components/system/system-configuration.component.js +319 -313
  22. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  23. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +20 -2
  24. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  25. package/dist/AI/components/vectors/vector-management-resource.component.js +419 -232
  26. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  27. package/dist/APIKeys/api-applications-panel.component.js +10 -12
  28. package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
  29. package/dist/APIKeys/api-key-create-dialog.component.js +13 -19
  30. package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
  31. package/dist/APIKeys/api-key-edit-panel.component.js +12 -14
  32. package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
  33. package/dist/APIKeys/api-scopes-panel.component.js +61 -68
  34. package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
  35. package/dist/APIKeys/api-usage-panel.component.js +10 -11
  36. package/dist/APIKeys/api-usage-panel.component.js.map +1 -1
  37. package/dist/Actions/components/actions-list-view.component.js +82 -96
  38. package/dist/Actions/components/actions-list-view.component.js.map +1 -1
  39. package/dist/Actions/components/actions-overview.component.js +130 -134
  40. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  41. package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
  42. package/dist/Actions/components/categories-list-view.component.js +40 -46
  43. package/dist/Actions/components/categories-list-view.component.js.map +1 -1
  44. package/dist/Actions/components/code-management.component.js +2 -2
  45. package/dist/Actions/components/code-management.component.js.map +1 -1
  46. package/dist/Actions/components/entity-integration.component.js +2 -2
  47. package/dist/Actions/components/entity-integration.component.js.map +1 -1
  48. package/dist/Actions/components/execution-monitoring.component.js +127 -132
  49. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  50. package/dist/Actions/components/executions-list-view.component.js +2 -2
  51. package/dist/Actions/components/executions-list-view.component.js.map +1 -1
  52. package/dist/Actions/components/explorer/action-card.component.js +11 -17
  53. package/dist/Actions/components/explorer/action-card.component.js.map +1 -1
  54. package/dist/Actions/components/explorer/action-explorer.component.js +5 -11
  55. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  56. package/dist/Actions/components/explorer/action-list-item.component.js +8 -10
  57. package/dist/Actions/components/explorer/action-list-item.component.js.map +1 -1
  58. package/dist/Actions/components/explorer/action-toolbar.component.js +112 -133
  59. package/dist/Actions/components/explorer/action-toolbar.component.js.map +1 -1
  60. package/dist/Actions/components/explorer/action-tree-panel.component.js +63 -83
  61. package/dist/Actions/components/explorer/action-tree-panel.component.js.map +1 -1
  62. package/dist/Actions/components/explorer/new-action-panel.component.js +17 -21
  63. package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
  64. package/dist/Actions/components/explorer/new-category-panel.component.js +17 -21
  65. package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
  66. package/dist/Actions/components/scheduled-actions.component.js +2 -2
  67. package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
  68. package/dist/Actions/components/security-permissions.component.js +2 -2
  69. package/dist/Actions/components/security-permissions.component.js.map +1 -1
  70. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +13 -5
  71. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  72. package/dist/ComponentStudio/component-studio-dashboard.component.js +168 -145
  73. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  74. package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts +4 -5
  75. package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
  76. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +197 -200
  77. package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
  78. package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts +5 -7
  79. package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
  80. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +142 -148
  81. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
  82. package/dist/ComponentStudio/components/browser/component-browser.component.js +153 -166
  83. package/dist/ComponentStudio/components/browser/component-browser.component.js.map +1 -1
  84. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +15 -20
  85. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
  86. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +16 -21
  87. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
  88. package/dist/ComponentStudio/components/editors/requirements-editor.component.js +18 -23
  89. package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
  90. package/dist/ComponentStudio/components/editors/spec-editor.component.js +25 -30
  91. package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
  92. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +10 -11
  93. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js.map +1 -1
  94. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.d.ts.map +1 -1
  95. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +24 -35
  96. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
  97. package/dist/ComponentStudio/components/text-import-dialog.component.js +15 -17
  98. package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
  99. package/dist/Credentials/components/credentials-categories-resource.component.js +7 -6
  100. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  101. package/dist/Credentials/components/credentials-list-resource.component.js +6 -5
  102. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  103. package/dist/Credentials/components/credentials-types-resource.component.js +7 -6
  104. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  105. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +9 -9
  106. package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
  107. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  108. package/dist/DataExplorer/data-explorer-dashboard.component.js +17 -17
  109. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  110. package/dist/Home/home-dashboard.component.js +4 -4
  111. package/dist/Home/home-dashboard.component.js.map +1 -1
  112. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  113. package/dist/Integration/components/activity/activity.component.js +1 -0
  114. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  115. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  116. package/dist/Integration/components/connections/connections.component.js +5 -4
  117. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  118. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
  119. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +247 -259
  120. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  121. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  122. package/dist/Integration/components/overview/overview.component.js +1 -0
  123. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  124. package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
  125. package/dist/Integration/components/pipelines/pipelines.component.js +1 -0
  126. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  127. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  128. package/dist/Integration/components/schedules/schedules.component.js +1 -0
  129. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  130. package/dist/Integration/components/widgets/integration-card.component.js +7 -9
  131. package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
  132. package/dist/Integration/integration.module.d.ts +6 -10
  133. package/dist/Integration/integration.module.d.ts.map +1 -1
  134. package/dist/Integration/integration.module.js +12 -20
  135. package/dist/Integration/integration.module.js.map +1 -1
  136. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +411 -0
  137. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -0
  138. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +4266 -0
  139. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -0
  140. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +140 -0
  141. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -0
  142. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +780 -0
  143. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -0
  144. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +8 -2
  145. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
  146. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +246 -195
  147. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  148. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +75 -0
  149. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -0
  150. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +601 -0
  151. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -0
  152. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +93 -12
  153. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +1 -1
  154. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +637 -107
  155. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +1 -1
  156. package/dist/KnowledgeHub/index.d.ts +3 -0
  157. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  158. package/dist/KnowledgeHub/index.js +3 -0
  159. package/dist/KnowledgeHub/index.js.map +1 -1
  160. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  161. package/dist/Lists/components/lists-browse-resource.component.js +9 -7
  162. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  163. package/dist/Lists/components/lists-my-lists-resource.component.js +5 -4
  164. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  165. package/dist/Lists/components/lists-operations-resource.component.js +10 -9
  166. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  167. package/dist/MCP/components/mcp-connection-dialog.component.js +141 -132
  168. package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
  169. package/dist/MCP/components/mcp-log-detail-panel.component.js +4 -4
  170. package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
  171. package/dist/MCP/components/mcp-server-dialog.component.js +141 -128
  172. package/dist/MCP/components/mcp-server-dialog.component.js.map +1 -1
  173. package/dist/MCP/components/mcp-test-tool-dialog.component.js +210 -218
  174. package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
  175. package/dist/MCP/mcp-dashboard.component.js +2 -2
  176. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  177. package/dist/MCP/mcp.module.d.ts +6 -9
  178. package/dist/MCP/mcp.module.d.ts.map +1 -1
  179. package/dist/MCP/mcp.module.js +20 -22
  180. package/dist/MCP/mcp.module.js.map +1 -1
  181. package/dist/Scheduling/components/scheduling-activity.component.js +5 -4
  182. package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
  183. package/dist/Scheduling/components/scheduling-jobs.component.js +6 -5
  184. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  185. package/dist/Scheduling/components/scheduling-overview.component.js +93 -92
  186. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  187. package/dist/Testing/testing-dashboard.component.js +9 -10
  188. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  189. package/dist/__tests__/analytics-resource.test.d.ts +2 -0
  190. package/dist/__tests__/analytics-resource.test.d.ts.map +1 -0
  191. package/dist/__tests__/analytics-resource.test.js +181 -0
  192. package/dist/__tests__/analytics-resource.test.js.map +1 -0
  193. package/dist/__tests__/scheduling.test.d.ts +2 -0
  194. package/dist/__tests__/scheduling.test.d.ts.map +1 -0
  195. package/dist/__tests__/scheduling.test.js +205 -0
  196. package/dist/__tests__/scheduling.test.js.map +1 -0
  197. package/dist/actions-dashboards.module.d.ts +8 -13
  198. package/dist/actions-dashboards.module.d.ts.map +1 -1
  199. package/dist/actions-dashboards.module.js +6 -27
  200. package/dist/actions-dashboards.module.js.map +1 -1
  201. package/dist/ai-dashboards.module.d.ts +20 -20
  202. package/dist/ai-dashboards.module.d.ts.map +1 -1
  203. package/dist/ai-dashboards.module.js +43 -44
  204. package/dist/ai-dashboards.module.js.map +1 -1
  205. package/dist/communication-dashboards.module.d.ts +4 -8
  206. package/dist/communication-dashboards.module.d.ts.map +1 -1
  207. package/dist/communication-dashboards.module.js +0 -19
  208. package/dist/communication-dashboards.module.js.map +1 -1
  209. package/dist/component-studio-dashboards.module.d.ts +7 -11
  210. package/dist/component-studio-dashboards.module.d.ts.map +1 -1
  211. package/dist/component-studio-dashboards.module.js +22 -34
  212. package/dist/component-studio-dashboards.module.js.map +1 -1
  213. package/dist/core-dashboards.module.d.ts +12 -18
  214. package/dist/core-dashboards.module.d.ts.map +1 -1
  215. package/dist/core-dashboards.module.js +15 -31
  216. package/dist/core-dashboards.module.js.map +1 -1
  217. package/dist/credentials-dashboards.module.d.ts +5 -8
  218. package/dist/credentials-dashboards.module.d.ts.map +1 -1
  219. package/dist/credentials-dashboards.module.js +3 -19
  220. package/dist/credentials-dashboards.module.js.map +1 -1
  221. package/dist/data-explorer-dashboards.module.d.ts +7 -13
  222. package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
  223. package/dist/data-explorer-dashboards.module.js +0 -27
  224. package/dist/data-explorer-dashboards.module.js.map +1 -1
  225. package/dist/lists-dashboards.module.d.ts +5 -8
  226. package/dist/lists-dashboards.module.d.ts.map +1 -1
  227. package/dist/lists-dashboards.module.js +3 -19
  228. package/dist/lists-dashboards.module.js.map +1 -1
  229. package/dist/public-api.d.ts +2 -0
  230. package/dist/public-api.d.ts.map +1 -1
  231. package/dist/public-api.js +2 -0
  232. package/dist/public-api.js.map +1 -1
  233. package/dist/scheduling-dashboards.module.d.ts +6 -10
  234. package/dist/scheduling-dashboards.module.d.ts.map +1 -1
  235. package/dist/scheduling-dashboards.module.js +3 -23
  236. package/dist/scheduling-dashboards.module.js.map +1 -1
  237. package/dist/shared/entity-field-display.d.ts +44 -0
  238. package/dist/shared/entity-field-display.d.ts.map +1 -0
  239. package/dist/shared/entity-field-display.js +118 -0
  240. package/dist/shared/entity-field-display.js.map +1 -0
  241. package/dist/testing-dashboards.module.d.ts +7 -13
  242. package/dist/testing-dashboards.module.d.ts.map +1 -1
  243. package/dist/testing-dashboards.module.js +0 -27
  244. package/dist/testing-dashboards.module.js.map +1 -1
  245. package/package.json +48 -55
@@ -3,30 +3,31 @@ import { interval } from 'rxjs';
3
3
  import * as i0 from "@angular/core";
4
4
  import * as i1 from "../services/scheduling-instrumentation.service";
5
5
  import * as i2 from "@angular/common";
6
- import * as i3 from "@memberjunction/ng-shared-generic";
6
+ import * as i3 from "@memberjunction/ng-ui-components";
7
+ import * as i4 from "@memberjunction/ng-shared-generic";
7
8
  function SchedulingOverviewComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
8
- i0.ɵɵelementStart(0, "div", 6);
9
- i0.ɵɵelement(1, "mj-loading", 8);
9
+ i0.ɵɵelementStart(0, "div", 7);
10
+ i0.ɵɵelement(1, "mj-loading", 9);
10
11
  i0.ɵɵelementEnd();
11
12
  } }
12
13
  function SchedulingOverviewComponent_Conditional_10_Conditional_65_Template(rf, ctx) { if (rf & 1) {
13
- i0.ɵɵelementStart(0, "div", 42);
14
- i0.ɵɵelement(1, "i", 53);
14
+ i0.ɵɵelementStart(0, "div", 43);
15
+ i0.ɵɵelement(1, "i", 54);
15
16
  i0.ɵɵelementStart(2, "span");
16
17
  i0.ɵɵtext(3, "No recent executions");
17
18
  i0.ɵɵelementEnd()();
18
19
  } }
19
20
  function SchedulingOverviewComponent_Conditional_10_For_67_Template(rf, ctx) { if (rf & 1) {
20
- i0.ɵɵelementStart(0, "div", 43)(1, "div", 54);
21
- i0.ɵɵelement(2, "i", 55);
21
+ i0.ɵɵelementStart(0, "div", 44)(1, "div", 55);
22
+ i0.ɵɵelement(2, "i", 56);
22
23
  i0.ɵɵelementEnd();
23
- i0.ɵɵelementStart(3, "div", 56)(4, "div", 57);
24
+ i0.ɵɵelementStart(3, "div", 57)(4, "div", 58);
24
25
  i0.ɵɵtext(5);
25
26
  i0.ɵɵelementEnd();
26
- i0.ɵɵelementStart(6, "div", 58);
27
+ i0.ɵɵelementStart(6, "div", 59);
27
28
  i0.ɵɵtext(7);
28
29
  i0.ɵɵelementEnd()();
29
- i0.ɵɵelementStart(8, "div", 59);
30
+ i0.ɵɵelementStart(8, "div", 60);
30
31
  i0.ɵɵtext(9);
31
32
  i0.ɵɵelementEnd()();
32
33
  } if (rf & 2) {
@@ -45,7 +46,7 @@ function SchedulingOverviewComponent_Conditional_10_For_67_Template(rf, ctx) { i
45
46
  i0.ɵɵtextInterpolate1(" ", exec_r1.status, " ");
46
47
  } }
47
48
  function SchedulingOverviewComponent_Conditional_10_Conditional_74_Template(rf, ctx) { if (rf & 1) {
48
- i0.ɵɵelementStart(0, "span", 46);
49
+ i0.ɵɵelementStart(0, "span", 47);
49
50
  i0.ɵɵtext(1);
50
51
  i0.ɵɵelementEnd();
51
52
  } if (rf & 2) {
@@ -54,34 +55,34 @@ function SchedulingOverviewComponent_Conditional_10_Conditional_74_Template(rf,
54
55
  i0.ɵɵtextInterpolate(ctx_r1.Alerts.length);
55
56
  } }
56
57
  function SchedulingOverviewComponent_Conditional_10_Conditional_75_Template(rf, ctx) { if (rf & 1) {
57
- i0.ɵɵelementStart(0, "span", 47);
58
+ i0.ɵɵelementStart(0, "span", 48);
58
59
  i0.ɵɵtext(1, "0");
59
60
  i0.ɵɵelementEnd();
60
61
  } }
61
62
  function SchedulingOverviewComponent_Conditional_10_Conditional_77_Template(rf, ctx) { if (rf & 1) {
62
- i0.ɵɵelementStart(0, "div", 48);
63
- i0.ɵɵelement(1, "i", 60);
63
+ i0.ɵɵelementStart(0, "div", 49);
64
+ i0.ɵɵelement(1, "i", 61);
64
65
  i0.ɵɵelementStart(2, "span");
65
66
  i0.ɵɵtext(3, "No active alerts");
66
67
  i0.ɵɵelementEnd()();
67
68
  } }
68
69
  function SchedulingOverviewComponent_Conditional_10_For_79_Conditional_7_Template(rf, ctx) { if (rf & 1) {
69
70
  const _r3 = i0.ɵɵgetCurrentView();
70
- i0.ɵɵelementStart(0, "button", 66);
71
+ i0.ɵɵelementStart(0, "button", 67);
71
72
  i0.ɵɵlistener("click", function SchedulingOverviewComponent_Conditional_10_For_79_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const alert_r4 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ReleaseLock(alert_r4.jobId)); });
72
73
  i0.ɵɵtext(1, " Release ");
73
74
  i0.ɵɵelementEnd();
74
75
  } }
75
76
  function SchedulingOverviewComponent_Conditional_10_For_79_Template(rf, ctx) { if (rf & 1) {
76
- i0.ɵɵelementStart(0, "div", 49);
77
- i0.ɵɵelement(1, "i", 61);
78
- i0.ɵɵelementStart(2, "div", 62)(3, "div", 63);
77
+ i0.ɵɵelementStart(0, "div", 50);
78
+ i0.ɵɵelement(1, "i", 62);
79
+ i0.ɵɵelementStart(2, "div", 63)(3, "div", 64);
79
80
  i0.ɵɵtext(4);
80
81
  i0.ɵɵelementEnd();
81
- i0.ɵɵelementStart(5, "div", 64);
82
+ i0.ɵɵelementStart(5, "div", 65);
82
83
  i0.ɵɵtext(6);
83
84
  i0.ɵɵelementEnd()();
84
- i0.ɵɵconditionalCreate(7, SchedulingOverviewComponent_Conditional_10_For_79_Conditional_7_Template, 2, 0, "button", 65);
85
+ i0.ɵɵconditionalCreate(7, SchedulingOverviewComponent_Conditional_10_For_79_Conditional_7_Template, 2, 0, "button", 66);
85
86
  i0.ɵɵelementEnd();
86
87
  } if (rf & 2) {
87
88
  const alert_r4 = ctx.$implicit;
@@ -97,22 +98,22 @@ function SchedulingOverviewComponent_Conditional_10_For_79_Template(rf, ctx) { i
97
98
  i0.ɵɵconditional(alert_r4.type === "stale-lock" && alert_r4.jobId ? 7 : -1);
98
99
  } }
99
100
  function SchedulingOverviewComponent_Conditional_10_Conditional_88_Template(rf, ctx) { if (rf & 1) {
100
- i0.ɵɵelementStart(0, "div", 42);
101
- i0.ɵɵelement(1, "i", 67);
101
+ i0.ɵɵelementStart(0, "div", 43);
102
+ i0.ɵɵelement(1, "i", 68);
102
103
  i0.ɵɵelementStart(2, "span");
103
104
  i0.ɵɵtext(3, "No upcoming executions");
104
105
  i0.ɵɵelementEnd()();
105
106
  } }
106
107
  function SchedulingOverviewComponent_Conditional_10_For_90_Template(rf, ctx) { if (rf & 1) {
107
- i0.ɵɵelementStart(0, "div", 51)(1, "div", 68)(2, "div", 69);
108
+ i0.ɵɵelementStart(0, "div", 52)(1, "div", 69)(2, "div", 70);
108
109
  i0.ɵɵtext(3);
109
110
  i0.ɵɵelementEnd();
110
- i0.ɵɵelementStart(4, "div", 70);
111
+ i0.ɵɵelementStart(4, "div", 71);
111
112
  i0.ɵɵtext(5);
112
- i0.ɵɵelementStart(6, "span", 71);
113
+ i0.ɵɵelementStart(6, "span", 72);
113
114
  i0.ɵɵtext(7);
114
115
  i0.ɵɵelementEnd()()();
115
- i0.ɵɵelementStart(8, "div", 72);
116
+ i0.ɵɵelementStart(8, "div", 73);
116
117
  i0.ɵɵtext(9);
117
118
  i0.ɵɵelementEnd()();
118
119
  } if (rf & 2) {
@@ -131,30 +132,30 @@ function SchedulingOverviewComponent_Conditional_10_For_90_Template(rf, ctx) { i
131
132
  } }
132
133
  function SchedulingOverviewComponent_Conditional_10_Conditional_91_For_24_Conditional_13_Template(rf, ctx) { if (rf & 1) {
133
134
  const _r6 = i0.ɵɵgetCurrentView();
134
- i0.ɵɵelementStart(0, "button", 80);
135
+ i0.ɵɵelementStart(0, "button", 81);
135
136
  i0.ɵɵlistener("click", function SchedulingOverviewComponent_Conditional_10_Conditional_91_For_24_Conditional_13_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const lock_r7 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ReleaseLock(lock_r7.jobId)); });
136
- i0.ɵɵelement(1, "i", 81);
137
+ i0.ɵɵelement(1, "i", 82);
137
138
  i0.ɵɵtext(2, " Release ");
138
139
  i0.ɵɵelementEnd();
139
140
  } }
140
141
  function SchedulingOverviewComponent_Conditional_10_Conditional_91_For_24_Template(rf, ctx) { if (rf & 1) {
141
- i0.ɵɵelementStart(0, "tr")(1, "td", 76);
142
+ i0.ɵɵelementStart(0, "tr")(1, "td", 77);
142
143
  i0.ɵɵtext(2);
143
144
  i0.ɵɵelementEnd();
144
- i0.ɵɵelementStart(3, "td", 77);
145
+ i0.ɵɵelementStart(3, "td", 78);
145
146
  i0.ɵɵtext(4);
146
147
  i0.ɵɵelementEnd();
147
- i0.ɵɵelementStart(5, "td", 77);
148
+ i0.ɵɵelementStart(5, "td", 78);
148
149
  i0.ɵɵtext(6);
149
150
  i0.ɵɵelementEnd();
150
- i0.ɵɵelementStart(7, "td", 77);
151
+ i0.ɵɵelementStart(7, "td", 78);
151
152
  i0.ɵɵtext(8);
152
153
  i0.ɵɵelementEnd();
153
- i0.ɵɵelementStart(9, "td")(10, "span", 78);
154
+ i0.ɵɵelementStart(9, "td")(10, "span", 79);
154
155
  i0.ɵɵtext(11);
155
156
  i0.ɵɵelementEnd()();
156
157
  i0.ɵɵelementStart(12, "td");
157
- i0.ɵɵconditionalCreate(13, SchedulingOverviewComponent_Conditional_10_Conditional_91_For_24_Conditional_13_Template, 3, 0, "button", 79);
158
+ i0.ɵɵconditionalCreate(13, SchedulingOverviewComponent_Conditional_10_Conditional_91_For_24_Conditional_13_Template, 3, 0, "button", 80);
158
159
  i0.ɵɵelementEnd()();
159
160
  } if (rf & 2) {
160
161
  const lock_r7 = ctx.$implicit;
@@ -176,14 +177,14 @@ function SchedulingOverviewComponent_Conditional_10_Conditional_91_For_24_Templa
176
177
  i0.ɵɵconditional(lock_r7.isStale ? 13 : -1);
177
178
  } }
178
179
  function SchedulingOverviewComponent_Conditional_10_Conditional_91_Template(rf, ctx) { if (rf & 1) {
179
- i0.ɵɵelementStart(0, "div", 52)(1, "div", 37)(2, "div", 38);
180
- i0.ɵɵelement(3, "i", 73);
180
+ i0.ɵɵelementStart(0, "div", 53)(1, "div", 38)(2, "div", 39);
181
+ i0.ɵɵelement(3, "i", 74);
181
182
  i0.ɵɵtext(4, " Active Locks ");
182
183
  i0.ɵɵelementEnd();
183
- i0.ɵɵelementStart(5, "span", 40);
184
+ i0.ɵɵelementStart(5, "span", 41);
184
185
  i0.ɵɵtext(6);
185
186
  i0.ɵɵelementEnd()();
186
- i0.ɵɵelementStart(7, "div", 41)(8, "table", 74)(9, "thead")(10, "tr")(11, "th");
187
+ i0.ɵɵelementStart(7, "div", 42)(8, "table", 75)(9, "thead")(10, "tr")(11, "th");
187
188
  i0.ɵɵtext(12, "Job");
188
189
  i0.ɵɵelementEnd();
189
190
  i0.ɵɵelementStart(13, "th");
@@ -201,7 +202,7 @@ function SchedulingOverviewComponent_Conditional_10_Conditional_91_Template(rf,
201
202
  i0.ɵɵelement(21, "th");
202
203
  i0.ɵɵelementEnd()();
203
204
  i0.ɵɵelementStart(22, "tbody");
204
- i0.ɵɵrepeaterCreate(23, SchedulingOverviewComponent_Conditional_10_Conditional_91_For_24_Template, 14, 10, "tr", 75, i0.ɵɵrepeaterTrackByIdentity);
205
+ i0.ɵɵrepeaterCreate(23, SchedulingOverviewComponent_Conditional_10_Conditional_91_For_24_Template, 14, 10, "tr", 76, i0.ɵɵrepeaterTrackByIdentity);
205
206
  i0.ɵɵelementEnd()()()();
206
207
  } if (rf & 2) {
207
208
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -211,103 +212,103 @@ function SchedulingOverviewComponent_Conditional_10_Conditional_91_Template(rf,
211
212
  i0.ɵɵrepeater(ctx_r1.Locks);
212
213
  } }
213
214
  function SchedulingOverviewComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
214
- i0.ɵɵelementStart(0, "div", 7)(1, "div", 9)(2, "div", 10);
215
+ i0.ɵɵelementStart(0, "div", 8)(1, "div", 10)(2, "div", 11);
215
216
  i0.ɵɵnamespaceSVG();
216
- i0.ɵɵelementStart(3, "svg", 11);
217
- i0.ɵɵelement(4, "circle", 12)(5, "circle", 13);
217
+ i0.ɵɵelementStart(3, "svg", 12);
218
+ i0.ɵɵelement(4, "circle", 13)(5, "circle", 14);
218
219
  i0.ɵɵelementEnd();
219
220
  i0.ɵɵnamespaceHTML();
220
- i0.ɵɵelementStart(6, "div", 14);
221
+ i0.ɵɵelementStart(6, "div", 15);
221
222
  i0.ɵɵtext(7);
222
223
  i0.ɵɵelementEnd()();
223
- i0.ɵɵelementStart(8, "div", 15)(9, "div", 16);
224
+ i0.ɵɵelementStart(8, "div", 16)(9, "div", 17);
224
225
  i0.ɵɵtext(10, "System Health");
225
226
  i0.ɵɵelementEnd();
226
- i0.ɵɵelementStart(11, "div", 17)(12, "span");
227
- i0.ɵɵelement(13, "i", 18);
227
+ i0.ɵɵelementStart(11, "div", 18)(12, "span");
228
+ i0.ɵɵelement(13, "i", 19);
228
229
  i0.ɵɵtext(14);
229
230
  i0.ɵɵelementEnd();
230
231
  i0.ɵɵelementStart(15, "span");
231
- i0.ɵɵelement(16, "i", 19);
232
+ i0.ɵɵelement(16, "i", 20);
232
233
  i0.ɵɵtext(17);
233
234
  i0.ɵɵelementEnd();
234
235
  i0.ɵɵelementStart(18, "span");
235
- i0.ɵɵelement(19, "i", 20);
236
+ i0.ɵɵelement(19, "i", 21);
236
237
  i0.ɵɵtext(20);
237
238
  i0.ɵɵelementEnd()()()();
238
- i0.ɵɵelementStart(21, "div", 21)(22, "div", 22)(23, "div", 23);
239
- i0.ɵɵelement(24, "i", 24);
239
+ i0.ɵɵelementStart(21, "div", 22)(22, "div", 23)(23, "div", 24);
240
+ i0.ɵɵelement(24, "i", 25);
240
241
  i0.ɵɵelementEnd();
241
- i0.ɵɵelementStart(25, "div", 25)(26, "div", 26);
242
+ i0.ɵɵelementStart(25, "div", 26)(26, "div", 27);
242
243
  i0.ɵɵtext(27);
243
244
  i0.ɵɵelementEnd();
244
- i0.ɵɵelementStart(28, "div", 27);
245
+ i0.ɵɵelementStart(28, "div", 28);
245
246
  i0.ɵɵtext(29, "Active Jobs");
246
247
  i0.ɵɵelementEnd()()();
247
- i0.ɵɵelementStart(30, "div", 22)(31, "div", 28);
248
- i0.ɵɵelement(32, "i", 29);
248
+ i0.ɵɵelementStart(30, "div", 23)(31, "div", 29);
249
+ i0.ɵɵelement(32, "i", 30);
249
250
  i0.ɵɵelementEnd();
250
- i0.ɵɵelementStart(33, "div", 25)(34, "div", 26);
251
+ i0.ɵɵelementStart(33, "div", 26)(34, "div", 27);
251
252
  i0.ɵɵtext(35);
252
253
  i0.ɵɵelementEnd();
253
- i0.ɵɵelementStart(36, "div", 27);
254
+ i0.ɵɵelementStart(36, "div", 28);
254
255
  i0.ɵɵtext(37, "Due Next Hour");
255
256
  i0.ɵɵelementEnd()()();
256
- i0.ɵɵelementStart(38, "div", 22)(39, "div", 30);
257
- i0.ɵɵelement(40, "i", 31);
257
+ i0.ɵɵelementStart(38, "div", 23)(39, "div", 31);
258
+ i0.ɵɵelement(40, "i", 32);
258
259
  i0.ɵɵelementEnd();
259
- i0.ɵɵelementStart(41, "div", 25)(42, "div", 26);
260
+ i0.ɵɵelementStart(41, "div", 26)(42, "div", 27);
260
261
  i0.ɵɵtext(43);
261
262
  i0.ɵɵelementEnd();
262
- i0.ɵɵelementStart(44, "div", 27);
263
+ i0.ɵɵelementStart(44, "div", 28);
263
264
  i0.ɵɵtext(45, "Runs (24h)");
264
265
  i0.ɵɵelementEnd();
265
- i0.ɵɵelementStart(46, "div", 32);
266
+ i0.ɵɵelementStart(46, "div", 33);
266
267
  i0.ɵɵtext(47);
267
268
  i0.ɵɵelementEnd()()();
268
- i0.ɵɵelementStart(48, "div", 22)(49, "div", 33);
269
- i0.ɵɵelement(50, "i", 34);
269
+ i0.ɵɵelementStart(48, "div", 23)(49, "div", 34);
270
+ i0.ɵɵelement(50, "i", 35);
270
271
  i0.ɵɵelementEnd();
271
- i0.ɵɵelementStart(51, "div", 25)(52, "div", 26);
272
+ i0.ɵɵelementStart(51, "div", 26)(52, "div", 27);
272
273
  i0.ɵɵtext(53);
273
274
  i0.ɵɵelementEnd();
274
- i0.ɵɵelementStart(54, "div", 27);
275
+ i0.ɵɵelementStart(54, "div", 28);
275
276
  i0.ɵɵtext(55, "Running Now");
276
277
  i0.ɵɵelementEnd()()()();
277
- i0.ɵɵelementStart(56, "div", 35)(57, "div", 36)(58, "div", 37)(59, "div", 38);
278
- i0.ɵɵelement(60, "i", 39);
278
+ i0.ɵɵelementStart(56, "div", 36)(57, "div", 37)(58, "div", 38)(59, "div", 39);
279
+ i0.ɵɵelement(60, "i", 40);
279
280
  i0.ɵɵtext(61, " Live Executions ");
280
281
  i0.ɵɵelementEnd();
281
- i0.ɵɵelementStart(62, "span", 40);
282
+ i0.ɵɵelementStart(62, "span", 41);
282
283
  i0.ɵɵtext(63);
283
284
  i0.ɵɵelementEnd()();
284
- i0.ɵɵelementStart(64, "div", 41);
285
- i0.ɵɵconditionalCreate(65, SchedulingOverviewComponent_Conditional_10_Conditional_65_Template, 4, 0, "div", 42);
286
- i0.ɵɵrepeaterCreate(66, SchedulingOverviewComponent_Conditional_10_For_67_Template, 10, 8, "div", 43, i0.ɵɵrepeaterTrackByIdentity);
285
+ i0.ɵɵelementStart(64, "div", 42);
286
+ i0.ɵɵconditionalCreate(65, SchedulingOverviewComponent_Conditional_10_Conditional_65_Template, 4, 0, "div", 43);
287
+ i0.ɵɵrepeaterCreate(66, SchedulingOverviewComponent_Conditional_10_For_67_Template, 10, 8, "div", 44, i0.ɵɵrepeaterTrackByIdentity);
287
288
  i0.ɵɵelementEnd()();
288
- i0.ɵɵelementStart(68, "div", 44)(69, "div", 36)(70, "div", 45)(71, "div", 38);
289
+ i0.ɵɵelementStart(68, "div", 45)(69, "div", 37)(70, "div", 46)(71, "div", 39);
289
290
  i0.ɵɵelement(72, "i");
290
291
  i0.ɵɵtext(73);
291
292
  i0.ɵɵelementEnd();
292
- i0.ɵɵconditionalCreate(74, SchedulingOverviewComponent_Conditional_10_Conditional_74_Template, 2, 1, "span", 46);
293
- i0.ɵɵconditionalCreate(75, SchedulingOverviewComponent_Conditional_10_Conditional_75_Template, 2, 0, "span", 47);
293
+ i0.ɵɵconditionalCreate(74, SchedulingOverviewComponent_Conditional_10_Conditional_74_Template, 2, 1, "span", 47);
294
+ i0.ɵɵconditionalCreate(75, SchedulingOverviewComponent_Conditional_10_Conditional_75_Template, 2, 0, "span", 48);
294
295
  i0.ɵɵelementEnd();
295
- i0.ɵɵelementStart(76, "div", 41);
296
- i0.ɵɵconditionalCreate(77, SchedulingOverviewComponent_Conditional_10_Conditional_77_Template, 4, 0, "div", 48);
297
- i0.ɵɵrepeaterCreate(78, SchedulingOverviewComponent_Conditional_10_For_79_Template, 8, 6, "div", 49, i0.ɵɵrepeaterTrackByIdentity);
296
+ i0.ɵɵelementStart(76, "div", 42);
297
+ i0.ɵɵconditionalCreate(77, SchedulingOverviewComponent_Conditional_10_Conditional_77_Template, 4, 0, "div", 49);
298
+ i0.ɵɵrepeaterCreate(78, SchedulingOverviewComponent_Conditional_10_For_79_Template, 8, 6, "div", 50, i0.ɵɵrepeaterTrackByIdentity);
298
299
  i0.ɵɵelementEnd()();
299
- i0.ɵɵelementStart(80, "div", 36)(81, "div", 37)(82, "div", 38);
300
- i0.ɵɵelement(83, "i", 50);
300
+ i0.ɵɵelementStart(80, "div", 37)(81, "div", 38)(82, "div", 39);
301
+ i0.ɵɵelement(83, "i", 51);
301
302
  i0.ɵɵtext(84, " Upcoming (24h) ");
302
303
  i0.ɵɵelementEnd();
303
- i0.ɵɵelementStart(85, "span", 40);
304
+ i0.ɵɵelementStart(85, "span", 41);
304
305
  i0.ɵɵtext(86);
305
306
  i0.ɵɵelementEnd()();
306
- i0.ɵɵelementStart(87, "div", 41);
307
- i0.ɵɵconditionalCreate(88, SchedulingOverviewComponent_Conditional_10_Conditional_88_Template, 4, 0, "div", 42);
308
- i0.ɵɵrepeaterCreate(89, SchedulingOverviewComponent_Conditional_10_For_90_Template, 10, 6, "div", 51, i0.ɵɵrepeaterTrackByIdentity);
307
+ i0.ɵɵelementStart(87, "div", 42);
308
+ i0.ɵɵconditionalCreate(88, SchedulingOverviewComponent_Conditional_10_Conditional_88_Template, 4, 0, "div", 43);
309
+ i0.ɵɵrepeaterCreate(89, SchedulingOverviewComponent_Conditional_10_For_90_Template, 10, 6, "div", 52, i0.ɵɵrepeaterTrackByIdentity);
309
310
  i0.ɵɵelementEnd()()()();
310
- i0.ɵɵconditionalCreate(91, SchedulingOverviewComponent_Conditional_10_Conditional_91_Template, 25, 1, "div", 52);
311
+ i0.ɵɵconditionalCreate(91, SchedulingOverviewComponent_Conditional_10_Conditional_91_Template, 25, 1, "div", 53);
311
312
  i0.ɵɵelementEnd();
312
313
  } if (rf & 2) {
313
314
  const ctx_r1 = i0.ɵɵnextContext();
@@ -563,34 +564,34 @@ export class SchedulingOverviewComponent {
563
564
  });
564
565
  }
565
566
  static ɵfac = function SchedulingOverviewComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SchedulingOverviewComponent)(i0.ɵɵdirectiveInject(i1.SchedulingInstrumentationService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
566
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingOverviewComponent, selectors: [["app-scheduling-overview"]], inputs: { initialState: "initialState" }, outputs: { stateChange: "stateChange" }, standalone: false, decls: 11, vars: 5, consts: [[1, "overview-container"], [1, "overview-header"], [1, "header-controls"], [1, "control-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], [1, "fa-solid", "fa-rotate"], [1, "loading-container"], [1, "overview-content"], ["text", "Loading dashboard...", "size", "medium"], [1, "health-banner"], [1, "health-ring"], ["viewBox", "0 0 80 80", 1, "health-svg"], ["cx", "40", "cy", "40", "r", "36", "fill", "none", "stroke-width", "6", 1, "health-ring-track"], ["cx", "40", "cy", "40", "r", "36", "fill", "none", "stroke-width", "6", "stroke-linecap", "round", "transform", "rotate(-90 40 40)"], [1, "health-score"], [1, "health-details"], [1, "health-title"], [1, "health-stats"], [1, "fa-solid", "fa-check-circle", "status-success"], [1, "fa-solid", "fa-lock", "status-warning"], [1, "fa-solid", "fa-xmark-circle", "status-error"], [1, "kpi-grid"], [1, "kpi-card"], [1, "kpi-icon", "blue"], [1, "fa-solid", "fa-calendar-check"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "amber"], [1, "fa-solid", "fa-clock"], [1, "kpi-icon", "purple"], [1, "fa-solid", "fa-chart-bar"], [1, "kpi-sub"], [1, "kpi-icon", "green"], [1, "fa-solid", "fa-play"], [1, "panels-grid"], [1, "panel"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-bolt"], [1, "panel-badge"], [1, "panel-body"], [1, "empty-state-small"], [1, "execution-item"], [1, "right-column"], [1, "panel-header", 3, "ngClass"], [1, "panel-badge", "error"], [1, "panel-badge", "clear"], [1, "empty-state-small", "all-clear"], [1, "alert-item", 3, "ngClass"], [1, "fa-solid", "fa-calendar-day"], [1, "upcoming-item"], [1, "panel", 2, "margin-top", "20px"], [1, "fa-solid", "fa-inbox"], [1, "exec-status"], [3, "ngClass"], [1, "exec-details"], [1, "exec-name"], [1, "exec-meta"], [1, "exec-status-badge", 3, "ngClass"], [1, "fa-solid", "fa-circle-check"], [1, "alert-icon"], [1, "alert-content"], [1, "alert-title"], [1, "alert-message"], [1, "alert-action-btn"], [1, "alert-action-btn", 3, "click"], [1, "fa-solid", "fa-calendar-xmark"], [1, "upcoming-info"], [1, "upcoming-name"], [1, "upcoming-meta"], [1, "upcoming-type"], [1, "upcoming-countdown"], [1, "fa-solid", "fa-lock"], [1, "data-table"], [3, "stale-row"], [1, "cell-name"], [1, "cell-meta"], [1, "lock-status-badge"], [1, "release-btn"], [1, "release-btn", 3, "click"], [1, "fa-solid", "fa-lock-open"]], template: function SchedulingOverviewComponent_Template(rf, ctx) { if (rf & 1) {
567
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingOverviewComponent, selectors: [["app-scheduling-overview"]], inputs: { initialState: "initialState" }, outputs: { stateChange: "stateChange" }, standalone: false, decls: 11, vars: 4, consts: [[1, "overview-container"], [1, "overview-header"], [1, "header-controls"], ["mjButton", "", "variant", "secondary", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], ["mjButton", "", 3, "click", "variant"], [1, "fa-solid", "fa-rotate"], [1, "loading-container"], [1, "overview-content"], ["text", "Loading dashboard...", "size", "medium"], [1, "health-banner"], [1, "health-ring"], ["viewBox", "0 0 80 80", 1, "health-svg"], ["cx", "40", "cy", "40", "r", "36", "fill", "none", "stroke-width", "6", 1, "health-ring-track"], ["cx", "40", "cy", "40", "r", "36", "fill", "none", "stroke-width", "6", "stroke-linecap", "round", "transform", "rotate(-90 40 40)"], [1, "health-score"], [1, "health-details"], [1, "health-title"], [1, "health-stats"], [1, "fa-solid", "fa-check-circle", "status-success"], [1, "fa-solid", "fa-lock", "status-warning"], [1, "fa-solid", "fa-xmark-circle", "status-error"], [1, "kpi-grid"], [1, "kpi-card"], [1, "kpi-icon", "blue"], [1, "fa-solid", "fa-calendar-check"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "amber"], [1, "fa-solid", "fa-clock"], [1, "kpi-icon", "purple"], [1, "fa-solid", "fa-chart-bar"], [1, "kpi-sub"], [1, "kpi-icon", "green"], [1, "fa-solid", "fa-play"], [1, "panels-grid"], [1, "panel"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-bolt"], [1, "panel-badge"], [1, "panel-body"], [1, "empty-state-small"], [1, "execution-item"], [1, "right-column"], [1, "panel-header", 3, "ngClass"], [1, "panel-badge", "error"], [1, "panel-badge", "clear"], [1, "empty-state-small", "all-clear"], [1, "alert-item", 3, "ngClass"], [1, "fa-solid", "fa-calendar-day"], [1, "upcoming-item"], [1, "panel", 2, "margin-top", "20px"], [1, "fa-solid", "fa-inbox"], [1, "exec-status"], [3, "ngClass"], [1, "exec-details"], [1, "exec-name"], [1, "exec-meta"], [1, "exec-status-badge", 3, "ngClass"], [1, "fa-solid", "fa-circle-check"], [1, "alert-icon"], [1, "alert-content"], [1, "alert-title"], [1, "alert-message"], [1, "alert-action-btn"], [1, "alert-action-btn", 3, "click"], [1, "fa-solid", "fa-calendar-xmark"], [1, "upcoming-info"], [1, "upcoming-name"], [1, "upcoming-meta"], [1, "upcoming-type"], [1, "upcoming-countdown"], [1, "fa-solid", "fa-lock"], [1, "data-table"], [3, "stale-row"], [1, "cell-name"], [1, "cell-meta"], [1, "lock-status-badge"], [1, "release-btn"], [1, "release-btn", 3, "click"], [1, "fa-solid", "fa-lock-open"]], template: function SchedulingOverviewComponent_Template(rf, ctx) { if (rf & 1) {
567
568
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "button", 3);
568
569
  i0.ɵɵlistener("click", function SchedulingOverviewComponent_Template_button_click_3_listener() { return ctx.Refresh(); });
569
570
  i0.ɵɵelement(4, "i", 4);
570
571
  i0.ɵɵtext(5, " Refresh ");
571
572
  i0.ɵɵelementEnd();
572
- i0.ɵɵelementStart(6, "button", 3);
573
+ i0.ɵɵelementStart(6, "button", 5);
573
574
  i0.ɵɵlistener("click", function SchedulingOverviewComponent_Template_button_click_6_listener() { return ctx.ToggleAutoRefresh(); });
574
- i0.ɵɵelement(7, "i", 5);
575
+ i0.ɵɵelement(7, "i", 6);
575
576
  i0.ɵɵtext(8);
576
577
  i0.ɵɵelementEnd()()();
577
- i0.ɵɵconditionalCreate(9, SchedulingOverviewComponent_Conditional_9_Template, 2, 0, "div", 6);
578
- i0.ɵɵconditionalCreate(10, SchedulingOverviewComponent_Conditional_10_Template, 92, 29, "div", 7);
578
+ i0.ɵɵconditionalCreate(9, SchedulingOverviewComponent_Conditional_9_Template, 2, 0, "div", 7);
579
+ i0.ɵɵconditionalCreate(10, SchedulingOverviewComponent_Conditional_10_Template, 92, 29, "div", 8);
579
580
  i0.ɵɵelementEnd();
580
581
  } if (rf & 2) {
581
582
  i0.ɵɵadvance(6);
582
- i0.ɵɵclassProp("active", ctx.AutoRefreshEnabled);
583
+ i0.ɵɵproperty("variant", ctx.AutoRefreshEnabled ? "primary" : "secondary");
583
584
  i0.ɵɵadvance(2);
584
585
  i0.ɵɵtextInterpolate1(" Auto-Refresh: ", ctx.AutoRefreshEnabled ? "ON" : "OFF", " ");
585
586
  i0.ɵɵadvance();
586
587
  i0.ɵɵconditional(ctx.IsLoading ? 9 : -1);
587
588
  i0.ɵɵadvance();
588
589
  i0.ɵɵconditional(!ctx.IsLoading && ctx.Kpis ? 10 : -1);
589
- } }, dependencies: [i2.NgClass, i3.LoadingComponent], styles: [".overview-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n height: 100%;\n}\n\n.overview-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n\n\n.overview-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n}\n\n.header-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.control-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.control-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.control-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n\n\n.health-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 24px;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n border-left: 4px solid var(--mj-status-success);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.health-ring[_ngcontent-%COMP%] {\n position: relative;\n width: 80px;\n height: 80px;\n flex-shrink: 0;\n}\n\n.health-svg[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n}\n\n.health-ring-track[_ngcontent-%COMP%] {\n stroke: var(--mj-border-default);\n}\n\n.health-score[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 1.5rem;\n font-weight: 800;\n}\n\n.health-details[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.health-title[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n}\n\n.health-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 20px;\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n}\n\n.health-stats[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n\n\n.kpi-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n}\n\n.kpi-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--mj-shadow-lg);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.kpi-icon.blue[_ngcontent-%COMP%] { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n.kpi-icon.amber[_ngcontent-%COMP%] { background: var(--mj-status-warning); color: var(--mj-text-inverse); }\n.kpi-icon.purple[_ngcontent-%COMP%] { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n.kpi-icon.green[_ngcontent-%COMP%] { background: var(--mj-status-success); color: var(--mj-text-inverse); }\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n font-weight: 800;\n color: var(--mj-text-primary);\n line-height: 1;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n}\n\n.kpi-sub[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n margin-top: 2px;\n}\n\n\n\n.panels-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n flex: 1;\n min-height: 300px;\n}\n\n.right-column[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-header.alert-header[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-bottom-color: var(--mj-status-error);\n}\n\n.panel-header.clear-header[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border-bottom-color: var(--mj-status-success);\n}\n\n.clear-header[_ngcontent-%COMP%] .panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.panel-badge.clear[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.all-clear[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success) !important;\n}\n\n.all-clear[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n font-weight: 500;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n font-size: 0.95rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.alert-header[_ngcontent-%COMP%] .panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.panel-badge[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 700;\n padding: 2px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.panel-badge.error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.panel-body[_ngcontent-%COMP%] {\n padding: 12px 20px;\n overflow-y: auto;\n flex: 1;\n min-height: 0;\n}\n\n\n\n.execution-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.execution-item[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.exec-status[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n}\n\n.exec-details[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.exec-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n}\n\n.exec-meta[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.exec-status-badge[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n}\n\n\n\n.status-running[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n.status-success[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.status-error[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.status-warning[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n\n.exec-status-badge.status-running[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.exec-status-badge.status-success[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.exec-status-badge.status-error[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.exec-status-badge.status-warning[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n\n\n.alert-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px;\n border-radius: 10px;\n margin-bottom: 8px;\n}\n\n.alert-item[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.alert-item.alert-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.alert-item.alert-warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n}\n\n.alert-icon[_ngcontent-%COMP%] {\n font-size: 1rem;\n margin-top: 2px;\n}\n\n.alert-error[_ngcontent-%COMP%] .alert-icon[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.alert-warning[_ngcontent-%COMP%] .alert-icon[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n\n.alert-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.alert-title[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n}\n\n.alert-message[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.alert-action-btn[_ngcontent-%COMP%] {\n padding: 4px 12px;\n font-size: 0.75rem;\n font-weight: 600;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.2s;\n}\n\n.alert-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n}\n\n\n\n.upcoming-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.upcoming-item[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.upcoming-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n}\n\n.upcoming-meta[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.upcoming-type[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 1px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 0.65rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-left: 6px;\n}\n\n.upcoming-countdown[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n font-weight: 700;\n color: var(--mj-brand-primary);\n}\n\n.upcoming-countdown.soon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n\n\n.empty-state-small[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n}\n\n.empty-state-small[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2rem;\n color: var(--mj-border-strong);\n}\n\n.empty-state-small[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n}\n\n\n\n.data-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.data-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 0.85rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.cell-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.cell-meta[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.stale-row[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.lock-status-badge[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.lock-status-badge.stale[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.release-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n font-size: 0.75rem;\n font-weight: 600;\n background: transparent;\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.release-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border-color: var(--mj-status-error);\n}\n\n\n\n@media (max-width: 1024px) {\n .panels-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .kpi-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .kpi-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .health-banner[_ngcontent-%COMP%] {\n flex-direction: column;\n text-align: center;\n }\n .health-stats[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 8px;\n align-items: center;\n }\n .data-table[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n }\n}"], changeDetection: 0 });
590
+ } }, dependencies: [i2.NgClass, i3.MJButtonDirective, i4.LoadingComponent], styles: [".overview-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n height: 100%;\n}\n\n.overview-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n\n\n.overview-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n}\n\n.header-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.control-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.control-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.control-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n\n\n.health-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 24px;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n border-left: 4px solid var(--mj-status-success);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.health-ring[_ngcontent-%COMP%] {\n position: relative;\n width: 80px;\n height: 80px;\n flex-shrink: 0;\n}\n\n.health-svg[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n}\n\n.health-ring-track[_ngcontent-%COMP%] {\n stroke: var(--mj-border-default);\n}\n\n.health-score[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 1.5rem;\n font-weight: 800;\n}\n\n.health-details[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.health-title[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n}\n\n.health-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 20px;\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n}\n\n.health-stats[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n\n\n.kpi-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n}\n\n.kpi-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--mj-shadow-lg);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.kpi-icon.blue[_ngcontent-%COMP%] { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n.kpi-icon.amber[_ngcontent-%COMP%] { background: var(--mj-status-warning); color: var(--mj-text-inverse); }\n.kpi-icon.purple[_ngcontent-%COMP%] { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n.kpi-icon.green[_ngcontent-%COMP%] { background: var(--mj-status-success); color: var(--mj-text-inverse); }\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n font-weight: 800;\n color: var(--mj-text-primary);\n line-height: 1;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n}\n\n.kpi-sub[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n margin-top: 2px;\n}\n\n\n\n.panels-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n flex: 1;\n min-height: 300px;\n}\n\n.right-column[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-header.alert-header[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-bottom-color: var(--mj-status-error);\n}\n\n.panel-header.clear-header[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border-bottom-color: var(--mj-status-success);\n}\n\n.clear-header[_ngcontent-%COMP%] .panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.panel-badge.clear[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.all-clear[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success) !important;\n}\n\n.all-clear[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n font-weight: 500;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n font-size: 0.95rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.alert-header[_ngcontent-%COMP%] .panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.panel-badge[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 700;\n padding: 2px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.panel-badge.error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.panel-body[_ngcontent-%COMP%] {\n padding: 12px 20px;\n overflow-y: auto;\n flex: 1;\n min-height: 0;\n}\n\n\n\n.execution-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.execution-item[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.exec-status[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n}\n\n.exec-details[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.exec-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n}\n\n.exec-meta[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.exec-status-badge[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n}\n\n\n\n.status-running[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n.status-success[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.status-error[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.status-warning[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n\n.exec-status-badge.status-running[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.exec-status-badge.status-success[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.exec-status-badge.status-error[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.exec-status-badge.status-warning[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n\n\n.alert-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px;\n border-radius: 10px;\n margin-bottom: 8px;\n}\n\n.alert-item[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.alert-item.alert-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.alert-item.alert-warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n}\n\n.alert-icon[_ngcontent-%COMP%] {\n font-size: 1rem;\n margin-top: 2px;\n}\n\n.alert-error[_ngcontent-%COMP%] .alert-icon[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.alert-warning[_ngcontent-%COMP%] .alert-icon[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n\n.alert-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.alert-title[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n}\n\n.alert-message[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.alert-action-btn[_ngcontent-%COMP%] {\n padding: 4px 12px;\n font-size: 0.75rem;\n font-weight: 600;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.2s;\n}\n\n.alert-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n}\n\n\n\n.upcoming-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.upcoming-item[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.upcoming-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n}\n\n.upcoming-meta[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.upcoming-type[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 1px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 0.65rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-left: 6px;\n}\n\n.upcoming-countdown[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n font-weight: 700;\n color: var(--mj-brand-primary);\n}\n\n.upcoming-countdown.soon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n\n\n.empty-state-small[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n}\n\n.empty-state-small[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2rem;\n color: var(--mj-border-strong);\n}\n\n.empty-state-small[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n}\n\n\n\n.data-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.data-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 0.85rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.cell-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.cell-meta[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.stale-row[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.lock-status-badge[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.lock-status-badge.stale[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.release-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n font-size: 0.75rem;\n font-weight: 600;\n background: transparent;\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.release-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border-color: var(--mj-status-error);\n}\n\n\n\n@media (max-width: 1024px) {\n .panels-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .kpi-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .kpi-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .health-banner[_ngcontent-%COMP%] {\n flex-direction: column;\n text-align: center;\n }\n .health-stats[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 8px;\n align-items: center;\n }\n .data-table[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n }\n}"], changeDetection: 0 });
590
591
  }
591
592
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SchedulingOverviewComponent, [{
592
593
  type: Component,
593
- args: [{ standalone: false, selector: 'app-scheduling-overview', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"overview-container\">\n <!-- Header Controls -->\n <div class=\"overview-header\">\n <div class=\"header-controls\">\n <button class=\"control-btn\" (click)=\"Refresh()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n <button class=\"control-btn\" [class.active]=\"AutoRefreshEnabled\" (click)=\"ToggleAutoRefresh()\">\n <i class=\"fa-solid fa-rotate\"></i>\n Auto-Refresh: {{AutoRefreshEnabled ? 'ON' : 'OFF'}}\n </button>\n </div>\n </div>\n\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading dashboard...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n @if (!IsLoading && Kpis) {\n <div class=\"overview-content\">\n <!-- Health Banner -->\n <div class=\"health-banner\" [style.border-color]=\"GetHealthColor()\">\n <div class=\"health-ring\">\n <svg viewBox=\"0 0 80 80\" class=\"health-svg\">\n <circle cx=\"40\" cy=\"40\" r=\"36\" fill=\"none\" class=\"health-ring-track\" stroke-width=\"6\"/>\n <circle cx=\"40\" cy=\"40\" r=\"36\" fill=\"none\"\n [attr.stroke]=\"GetHealthColor()\"\n stroke-width=\"6\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"GetHealthStrokeDasharray()\"\n transform=\"rotate(-90 40 40)\"/>\n </svg>\n <div class=\"health-score\" [style.color]=\"GetHealthColor()\">{{GetHealthScore()}}</div>\n </div>\n <div class=\"health-details\">\n <div class=\"health-title\">System Health</div>\n <div class=\"health-stats\">\n <span><i class=\"fa-solid fa-check-circle status-success\"></i> {{Kpis.totalActiveJobs}} active</span>\n <span><i class=\"fa-solid fa-lock status-warning\"></i> {{Kpis.lockedJobs}} locked</span>\n <span><i class=\"fa-solid fa-xmark-circle status-error\"></i> {{Kpis.totalFailures7d}} failures (7d)</span>\n </div>\n </div>\n </div>\n <!-- KPI Cards -->\n <div class=\"kpi-grid\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon blue\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{Kpis.totalActiveJobs}}</div>\n <div class=\"kpi-label\">Active Jobs</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon amber\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{Kpis.jobsDueInNextHour}}</div>\n <div class=\"kpi-label\">Due Next Hour</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon purple\">\n <i class=\"fa-solid fa-chart-bar\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{Kpis.recentExecutions24h}}</div>\n <div class=\"kpi-label\">Runs (24h)</div>\n <div class=\"kpi-sub\" [style.color]=\"GetSuccessRateColor(Kpis.successRate24h)\">\n {{FormatPercentage(Kpis.successRate24h)}} success\n </div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon green\">\n <i class=\"fa-solid fa-play\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{Kpis.currentlyRunning}}</div>\n <div class=\"kpi-label\">Running Now</div>\n </div>\n </div>\n </div>\n <!-- Two-Column Layout: Live Executions + Alerts/Upcoming -->\n <div class=\"panels-grid\">\n <!-- Live Executions -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-bolt\"></i> Live Executions\n </div>\n <span class=\"panel-badge\">{{LiveExecutions.length}}</span>\n </div>\n <div class=\"panel-body\">\n @if (LiveExecutions.length === 0) {\n <div class=\"empty-state-small\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No recent executions</span>\n </div>\n }\n @for (exec of LiveExecutions; track exec) {\n <div class=\"execution-item\">\n <div class=\"exec-status\">\n <i [class]=\"GetStatusIcon(exec.status)\" [ngClass]=\"GetStatusClass(exec.status)\"></i>\n </div>\n <div class=\"exec-details\">\n <div class=\"exec-name\">{{exec.jobName}}</div>\n <div class=\"exec-meta\">{{FormatTimeAgo(exec.startedAt)}} &middot; {{FormatDuration(exec.duration)}}</div>\n </div>\n <div class=\"exec-status-badge\" [ngClass]=\"GetStatusClass(exec.status)\">\n {{exec.status}}\n </div>\n </div>\n }\n </div>\n </div>\n <!-- Right Column: Alerts + Upcoming -->\n <div class=\"right-column\">\n <!-- Alerts -->\n <div class=\"panel\">\n <div class=\"panel-header\" [ngClass]=\"Alerts.length > 0 ? 'alert-header' : 'clear-header'\">\n <div class=\"panel-title\">\n <i [class]=\"Alerts.length > 0 ? 'fa-solid fa-triangle-exclamation' : 'fa-solid fa-shield-check'\"></i>\n {{Alerts.length > 0 ? 'Alerts' : 'All Clear'}}\n </div>\n @if (Alerts.length > 0) {\n <span class=\"panel-badge error\">{{Alerts.length}}</span>\n }\n @if (Alerts.length === 0) {\n <span class=\"panel-badge clear\">0</span>\n }\n </div>\n <div class=\"panel-body\">\n @if (Alerts.length === 0) {\n <div class=\"empty-state-small all-clear\">\n <i class=\"fa-solid fa-circle-check\"></i>\n <span>No active alerts</span>\n </div>\n }\n @for (alert of Alerts; track alert) {\n <div class=\"alert-item\" [ngClass]=\"'alert-' + alert.severity\">\n <i [class]=\"GetAlertIcon(alert.severity)\" class=\"alert-icon\"></i>\n <div class=\"alert-content\">\n <div class=\"alert-title\">{{alert.title}}</div>\n <div class=\"alert-message\">{{alert.message}}</div>\n </div>\n @if (alert.type === 'stale-lock' && alert.jobId) {\n <button\n class=\"alert-action-btn\"\n (click)=\"ReleaseLock(alert.jobId!)\">\n Release\n </button>\n }\n </div>\n }\n </div>\n </div>\n <!-- Upcoming -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-calendar-day\"></i> Upcoming (24h)\n </div>\n <span class=\"panel-badge\">{{UpcomingExecutions.length}}</span>\n </div>\n <div class=\"panel-body\">\n @if (UpcomingExecutions.length === 0) {\n <div class=\"empty-state-small\">\n <i class=\"fa-solid fa-calendar-xmark\"></i>\n <span>No upcoming executions</span>\n </div>\n }\n @for (upcoming of UpcomingExecutions; track upcoming) {\n <div class=\"upcoming-item\">\n <div class=\"upcoming-info\">\n <div class=\"upcoming-name\">{{upcoming.jobName}}</div>\n <div class=\"upcoming-meta\">\n {{FormatDateTime(upcoming.nextRunAt)}}\n <span class=\"upcoming-type\">{{upcoming.jobType}}</span>\n </div>\n </div>\n <div class=\"upcoming-countdown\" [class.soon]=\"FormatTimeUntil(upcoming.nextRunAt).includes('m') && !FormatTimeUntil(upcoming.nextRunAt).includes('h')\">\n {{FormatTimeUntil(upcoming.nextRunAt)}}\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n <!-- Locks Section -->\n @if (Locks.length > 0) {\n <div class=\"panel\" style=\"margin-top: 20px;\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-lock\"></i> Active Locks\n </div>\n <span class=\"panel-badge\">{{Locks.length}}</span>\n </div>\n <div class=\"panel-body\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Job</th>\n <th>Locked By</th>\n <th>Locked At</th>\n <th>Expected Completion</th>\n <th>Status</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (lock of Locks; track lock) {\n <tr [class.stale-row]=\"lock.isStale\">\n <td class=\"cell-name\">{{lock.jobName}}</td>\n <td class=\"cell-meta\">{{lock.lockedBy}}</td>\n <td class=\"cell-meta\">{{FormatTimeAgo(lock.lockedAt)}}</td>\n <td class=\"cell-meta\">{{FormatDateTime(lock.expectedCompletion)}}</td>\n <td>\n <span class=\"lock-status-badge\" [class.stale]=\"lock.isStale\">\n {{lock.isStale ? 'Stale' : 'Active'}}\n </span>\n </td>\n <td>\n @if (lock.isStale) {\n <button class=\"release-btn\" (click)=\"ReleaseLock(lock.jobId)\">\n <i class=\"fa-solid fa-lock-open\"></i> Release\n </button>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".overview-container {\n display: flex;\n flex-direction: column;\n gap: 20px;\n height: 100%;\n}\n\n.overview-content {\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.overview-header {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n}\n\n.header-controls {\n display: flex;\n gap: 8px;\n}\n\n.control-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.control-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.control-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n/* \u2500\u2500 Health Banner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.health-banner {\n display: flex;\n align-items: center;\n gap: 24px;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n border-left: 4px solid var(--mj-status-success);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.health-ring {\n position: relative;\n width: 80px;\n height: 80px;\n flex-shrink: 0;\n}\n\n.health-svg {\n width: 100%;\n height: 100%;\n}\n\n.health-ring-track {\n stroke: var(--mj-border-default);\n}\n\n.health-score {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 1.5rem;\n font-weight: 800;\n}\n\n.health-details {\n flex: 1;\n}\n\n.health-title {\n font-size: 1.1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n}\n\n.health-stats {\n display: flex;\n gap: 20px;\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n}\n\n.health-stats span {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* \u2500\u2500 KPI Cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.kpi-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--mj-shadow-lg);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.kpi-icon.blue { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n.kpi-icon.amber { background: var(--mj-status-warning); color: var(--mj-text-inverse); }\n.kpi-icon.purple { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n.kpi-icon.green { background: var(--mj-status-success); color: var(--mj-text-inverse); }\n\n.kpi-content {\n flex: 1;\n}\n\n.kpi-value {\n font-size: 1.75rem;\n font-weight: 800;\n color: var(--mj-text-primary);\n line-height: 1;\n}\n\n.kpi-label {\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n}\n\n.kpi-sub {\n font-size: 0.75rem;\n font-weight: 600;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Panels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.panels-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n flex: 1;\n min-height: 300px;\n}\n\n.right-column {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.panel {\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-header.alert-header {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-bottom-color: var(--mj-status-error);\n}\n\n.panel-header.clear-header {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border-bottom-color: var(--mj-status-success);\n}\n\n.clear-header .panel-title i {\n color: var(--mj-status-success);\n}\n\n.panel-badge.clear {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.all-clear i {\n color: var(--mj-status-success) !important;\n}\n\n.all-clear span {\n color: var(--mj-status-success);\n font-weight: 500;\n}\n\n.panel-title {\n font-size: 0.95rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title i {\n color: var(--mj-brand-primary);\n}\n\n.alert-header .panel-title i {\n color: var(--mj-status-error);\n}\n\n.panel-badge {\n font-size: 0.7rem;\n font-weight: 700;\n padding: 2px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.panel-badge.error {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.panel-body {\n padding: 12px 20px;\n overflow-y: auto;\n flex: 1;\n min-height: 0;\n}\n\n/* \u2500\u2500 Execution Items \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.execution-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.execution-item:last-child {\n border-bottom: none;\n}\n\n.exec-status i {\n font-size: 1.1rem;\n}\n\n.exec-details {\n flex: 1;\n}\n\n.exec-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n}\n\n.exec-meta {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.exec-status-badge {\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n}\n\n/* Status Colors */\n.status-running { color: var(--mj-brand-primary); }\n.status-success { color: var(--mj-status-success); }\n.status-error { color: var(--mj-status-error); }\n.status-warning { color: var(--mj-status-warning); }\n\n.exec-status-badge.status-running { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.exec-status-badge.status-success { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.exec-status-badge.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.exec-status-badge.status-warning { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n/* \u2500\u2500 Alert Items \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.alert-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px;\n border-radius: 10px;\n margin-bottom: 8px;\n}\n\n.alert-item:last-child {\n margin-bottom: 0;\n}\n\n.alert-item.alert-error {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.alert-item.alert-warning {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n}\n\n.alert-icon {\n font-size: 1rem;\n margin-top: 2px;\n}\n\n.alert-error .alert-icon { color: var(--mj-status-error); }\n.alert-warning .alert-icon { color: var(--mj-status-warning); }\n\n.alert-content {\n flex: 1;\n}\n\n.alert-title {\n font-weight: 600;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n}\n\n.alert-message {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.alert-action-btn {\n padding: 4px 12px;\n font-size: 0.75rem;\n font-weight: 600;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.2s;\n}\n\n.alert-action-btn:hover {\n background: var(--mj-status-error);\n}\n\n/* \u2500\u2500 Upcoming Items \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.upcoming-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.upcoming-item:last-child {\n border-bottom: none;\n}\n\n.upcoming-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n}\n\n.upcoming-meta {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.upcoming-type {\n display: inline-flex;\n padding: 1px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 0.65rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-left: 6px;\n}\n\n.upcoming-countdown {\n font-size: 0.85rem;\n font-weight: 700;\n color: var(--mj-brand-primary);\n}\n\n.upcoming-countdown.soon {\n color: var(--mj-status-warning);\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.empty-state-small {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n}\n\n.empty-state-small i {\n font-size: 2rem;\n color: var(--mj-border-strong);\n}\n\n.empty-state-small span {\n font-size: 0.85rem;\n}\n\n/* \u2500\u2500 Data Table \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.data-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table th {\n text-align: left;\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.data-table td {\n padding: 10px 12px;\n font-size: 0.85rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.cell-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.cell-meta {\n color: var(--mj-text-secondary);\n}\n\n.stale-row {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.lock-status-badge {\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.lock-status-badge.stale {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.release-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n font-size: 0.75rem;\n font-weight: 600;\n background: transparent;\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.release-btn:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border-color: var(--mj-status-error);\n}\n\n/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 1024px) {\n .panels-grid {\n grid-template-columns: 1fr;\n }\n .kpi-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .kpi-grid {\n grid-template-columns: 1fr;\n }\n .health-banner {\n flex-direction: column;\n text-align: center;\n }\n .health-stats {\n flex-direction: column;\n gap: 8px;\n align-items: center;\n }\n .data-table {\n font-size: 0.8rem;\n }\n}\n"] }]
594
+ args: [{ standalone: false, selector: 'app-scheduling-overview', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"overview-container\">\n <!-- Header Controls -->\n <div class=\"overview-header\">\n <div class=\"header-controls\">\n <button mjButton variant=\"secondary\" (click)=\"Refresh()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n <button mjButton [variant]=\"AutoRefreshEnabled ? 'primary' : 'secondary'\" (click)=\"ToggleAutoRefresh()\">\n <i class=\"fa-solid fa-rotate\"></i>\n Auto-Refresh: {{AutoRefreshEnabled ? 'ON' : 'OFF'}}\n </button>\n </div>\n </div>\n\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading dashboard...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n @if (!IsLoading && Kpis) {\n <div class=\"overview-content\">\n <!-- Health Banner -->\n <div class=\"health-banner\" [style.border-color]=\"GetHealthColor()\">\n <div class=\"health-ring\">\n <svg viewBox=\"0 0 80 80\" class=\"health-svg\">\n <circle cx=\"40\" cy=\"40\" r=\"36\" fill=\"none\" class=\"health-ring-track\" stroke-width=\"6\"/>\n <circle cx=\"40\" cy=\"40\" r=\"36\" fill=\"none\"\n [attr.stroke]=\"GetHealthColor()\"\n stroke-width=\"6\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"GetHealthStrokeDasharray()\"\n transform=\"rotate(-90 40 40)\"/>\n </svg>\n <div class=\"health-score\" [style.color]=\"GetHealthColor()\">{{GetHealthScore()}}</div>\n </div>\n <div class=\"health-details\">\n <div class=\"health-title\">System Health</div>\n <div class=\"health-stats\">\n <span><i class=\"fa-solid fa-check-circle status-success\"></i> {{Kpis.totalActiveJobs}} active</span>\n <span><i class=\"fa-solid fa-lock status-warning\"></i> {{Kpis.lockedJobs}} locked</span>\n <span><i class=\"fa-solid fa-xmark-circle status-error\"></i> {{Kpis.totalFailures7d}} failures (7d)</span>\n </div>\n </div>\n </div>\n <!-- KPI Cards -->\n <div class=\"kpi-grid\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon blue\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{Kpis.totalActiveJobs}}</div>\n <div class=\"kpi-label\">Active Jobs</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon amber\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{Kpis.jobsDueInNextHour}}</div>\n <div class=\"kpi-label\">Due Next Hour</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon purple\">\n <i class=\"fa-solid fa-chart-bar\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{Kpis.recentExecutions24h}}</div>\n <div class=\"kpi-label\">Runs (24h)</div>\n <div class=\"kpi-sub\" [style.color]=\"GetSuccessRateColor(Kpis.successRate24h)\">\n {{FormatPercentage(Kpis.successRate24h)}} success\n </div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon green\">\n <i class=\"fa-solid fa-play\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{Kpis.currentlyRunning}}</div>\n <div class=\"kpi-label\">Running Now</div>\n </div>\n </div>\n </div>\n <!-- Two-Column Layout: Live Executions + Alerts/Upcoming -->\n <div class=\"panels-grid\">\n <!-- Live Executions -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-bolt\"></i> Live Executions\n </div>\n <span class=\"panel-badge\">{{LiveExecutions.length}}</span>\n </div>\n <div class=\"panel-body\">\n @if (LiveExecutions.length === 0) {\n <div class=\"empty-state-small\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No recent executions</span>\n </div>\n }\n @for (exec of LiveExecutions; track exec) {\n <div class=\"execution-item\">\n <div class=\"exec-status\">\n <i [class]=\"GetStatusIcon(exec.status)\" [ngClass]=\"GetStatusClass(exec.status)\"></i>\n </div>\n <div class=\"exec-details\">\n <div class=\"exec-name\">{{exec.jobName}}</div>\n <div class=\"exec-meta\">{{FormatTimeAgo(exec.startedAt)}} &middot; {{FormatDuration(exec.duration)}}</div>\n </div>\n <div class=\"exec-status-badge\" [ngClass]=\"GetStatusClass(exec.status)\">\n {{exec.status}}\n </div>\n </div>\n }\n </div>\n </div>\n <!-- Right Column: Alerts + Upcoming -->\n <div class=\"right-column\">\n <!-- Alerts -->\n <div class=\"panel\">\n <div class=\"panel-header\" [ngClass]=\"Alerts.length > 0 ? 'alert-header' : 'clear-header'\">\n <div class=\"panel-title\">\n <i [class]=\"Alerts.length > 0 ? 'fa-solid fa-triangle-exclamation' : 'fa-solid fa-shield-check'\"></i>\n {{Alerts.length > 0 ? 'Alerts' : 'All Clear'}}\n </div>\n @if (Alerts.length > 0) {\n <span class=\"panel-badge error\">{{Alerts.length}}</span>\n }\n @if (Alerts.length === 0) {\n <span class=\"panel-badge clear\">0</span>\n }\n </div>\n <div class=\"panel-body\">\n @if (Alerts.length === 0) {\n <div class=\"empty-state-small all-clear\">\n <i class=\"fa-solid fa-circle-check\"></i>\n <span>No active alerts</span>\n </div>\n }\n @for (alert of Alerts; track alert) {\n <div class=\"alert-item\" [ngClass]=\"'alert-' + alert.severity\">\n <i [class]=\"GetAlertIcon(alert.severity)\" class=\"alert-icon\"></i>\n <div class=\"alert-content\">\n <div class=\"alert-title\">{{alert.title}}</div>\n <div class=\"alert-message\">{{alert.message}}</div>\n </div>\n @if (alert.type === 'stale-lock' && alert.jobId) {\n <button\n class=\"alert-action-btn\"\n (click)=\"ReleaseLock(alert.jobId!)\">\n Release\n </button>\n }\n </div>\n }\n </div>\n </div>\n <!-- Upcoming -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-calendar-day\"></i> Upcoming (24h)\n </div>\n <span class=\"panel-badge\">{{UpcomingExecutions.length}}</span>\n </div>\n <div class=\"panel-body\">\n @if (UpcomingExecutions.length === 0) {\n <div class=\"empty-state-small\">\n <i class=\"fa-solid fa-calendar-xmark\"></i>\n <span>No upcoming executions</span>\n </div>\n }\n @for (upcoming of UpcomingExecutions; track upcoming) {\n <div class=\"upcoming-item\">\n <div class=\"upcoming-info\">\n <div class=\"upcoming-name\">{{upcoming.jobName}}</div>\n <div class=\"upcoming-meta\">\n {{FormatDateTime(upcoming.nextRunAt)}}\n <span class=\"upcoming-type\">{{upcoming.jobType}}</span>\n </div>\n </div>\n <div class=\"upcoming-countdown\" [class.soon]=\"FormatTimeUntil(upcoming.nextRunAt).includes('m') && !FormatTimeUntil(upcoming.nextRunAt).includes('h')\">\n {{FormatTimeUntil(upcoming.nextRunAt)}}\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n <!-- Locks Section -->\n @if (Locks.length > 0) {\n <div class=\"panel\" style=\"margin-top: 20px;\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-lock\"></i> Active Locks\n </div>\n <span class=\"panel-badge\">{{Locks.length}}</span>\n </div>\n <div class=\"panel-body\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Job</th>\n <th>Locked By</th>\n <th>Locked At</th>\n <th>Expected Completion</th>\n <th>Status</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (lock of Locks; track lock) {\n <tr [class.stale-row]=\"lock.isStale\">\n <td class=\"cell-name\">{{lock.jobName}}</td>\n <td class=\"cell-meta\">{{lock.lockedBy}}</td>\n <td class=\"cell-meta\">{{FormatTimeAgo(lock.lockedAt)}}</td>\n <td class=\"cell-meta\">{{FormatDateTime(lock.expectedCompletion)}}</td>\n <td>\n <span class=\"lock-status-badge\" [class.stale]=\"lock.isStale\">\n {{lock.isStale ? 'Stale' : 'Active'}}\n </span>\n </td>\n <td>\n @if (lock.isStale) {\n <button class=\"release-btn\" (click)=\"ReleaseLock(lock.jobId)\">\n <i class=\"fa-solid fa-lock-open\"></i> Release\n </button>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".overview-container {\n display: flex;\n flex-direction: column;\n gap: 20px;\n height: 100%;\n}\n\n.overview-content {\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.overview-header {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n}\n\n.header-controls {\n display: flex;\n gap: 8px;\n}\n\n.control-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.control-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.control-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n/* \u2500\u2500 Health Banner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.health-banner {\n display: flex;\n align-items: center;\n gap: 24px;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n border-left: 4px solid var(--mj-status-success);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.health-ring {\n position: relative;\n width: 80px;\n height: 80px;\n flex-shrink: 0;\n}\n\n.health-svg {\n width: 100%;\n height: 100%;\n}\n\n.health-ring-track {\n stroke: var(--mj-border-default);\n}\n\n.health-score {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 1.5rem;\n font-weight: 800;\n}\n\n.health-details {\n flex: 1;\n}\n\n.health-title {\n font-size: 1.1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n}\n\n.health-stats {\n display: flex;\n gap: 20px;\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n}\n\n.health-stats span {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* \u2500\u2500 KPI Cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.kpi-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--mj-shadow-lg);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.kpi-icon.blue { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n.kpi-icon.amber { background: var(--mj-status-warning); color: var(--mj-text-inverse); }\n.kpi-icon.purple { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n.kpi-icon.green { background: var(--mj-status-success); color: var(--mj-text-inverse); }\n\n.kpi-content {\n flex: 1;\n}\n\n.kpi-value {\n font-size: 1.75rem;\n font-weight: 800;\n color: var(--mj-text-primary);\n line-height: 1;\n}\n\n.kpi-label {\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n}\n\n.kpi-sub {\n font-size: 0.75rem;\n font-weight: 600;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Panels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.panels-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n flex: 1;\n min-height: 300px;\n}\n\n.right-column {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.panel {\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-header.alert-header {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-bottom-color: var(--mj-status-error);\n}\n\n.panel-header.clear-header {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border-bottom-color: var(--mj-status-success);\n}\n\n.clear-header .panel-title i {\n color: var(--mj-status-success);\n}\n\n.panel-badge.clear {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.all-clear i {\n color: var(--mj-status-success) !important;\n}\n\n.all-clear span {\n color: var(--mj-status-success);\n font-weight: 500;\n}\n\n.panel-title {\n font-size: 0.95rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title i {\n color: var(--mj-brand-primary);\n}\n\n.alert-header .panel-title i {\n color: var(--mj-status-error);\n}\n\n.panel-badge {\n font-size: 0.7rem;\n font-weight: 700;\n padding: 2px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.panel-badge.error {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.panel-body {\n padding: 12px 20px;\n overflow-y: auto;\n flex: 1;\n min-height: 0;\n}\n\n/* \u2500\u2500 Execution Items \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.execution-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.execution-item:last-child {\n border-bottom: none;\n}\n\n.exec-status i {\n font-size: 1.1rem;\n}\n\n.exec-details {\n flex: 1;\n}\n\n.exec-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n}\n\n.exec-meta {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.exec-status-badge {\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n}\n\n/* Status Colors */\n.status-running { color: var(--mj-brand-primary); }\n.status-success { color: var(--mj-status-success); }\n.status-error { color: var(--mj-status-error); }\n.status-warning { color: var(--mj-status-warning); }\n\n.exec-status-badge.status-running { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.exec-status-badge.status-success { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.exec-status-badge.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.exec-status-badge.status-warning { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n/* \u2500\u2500 Alert Items \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.alert-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px;\n border-radius: 10px;\n margin-bottom: 8px;\n}\n\n.alert-item:last-child {\n margin-bottom: 0;\n}\n\n.alert-item.alert-error {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.alert-item.alert-warning {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n}\n\n.alert-icon {\n font-size: 1rem;\n margin-top: 2px;\n}\n\n.alert-error .alert-icon { color: var(--mj-status-error); }\n.alert-warning .alert-icon { color: var(--mj-status-warning); }\n\n.alert-content {\n flex: 1;\n}\n\n.alert-title {\n font-weight: 600;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n}\n\n.alert-message {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.alert-action-btn {\n padding: 4px 12px;\n font-size: 0.75rem;\n font-weight: 600;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.2s;\n}\n\n.alert-action-btn:hover {\n background: var(--mj-status-error);\n}\n\n/* \u2500\u2500 Upcoming Items \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.upcoming-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.upcoming-item:last-child {\n border-bottom: none;\n}\n\n.upcoming-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n}\n\n.upcoming-meta {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.upcoming-type {\n display: inline-flex;\n padding: 1px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 0.65rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-left: 6px;\n}\n\n.upcoming-countdown {\n font-size: 0.85rem;\n font-weight: 700;\n color: var(--mj-brand-primary);\n}\n\n.upcoming-countdown.soon {\n color: var(--mj-status-warning);\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.empty-state-small {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n}\n\n.empty-state-small i {\n font-size: 2rem;\n color: var(--mj-border-strong);\n}\n\n.empty-state-small span {\n font-size: 0.85rem;\n}\n\n/* \u2500\u2500 Data Table \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.data-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table th {\n text-align: left;\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.data-table td {\n padding: 10px 12px;\n font-size: 0.85rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.cell-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.cell-meta {\n color: var(--mj-text-secondary);\n}\n\n.stale-row {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.lock-status-badge {\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.lock-status-badge.stale {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.release-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n font-size: 0.75rem;\n font-weight: 600;\n background: transparent;\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.release-btn:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border-color: var(--mj-status-error);\n}\n\n/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 1024px) {\n .panels-grid {\n grid-template-columns: 1fr;\n }\n .kpi-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .kpi-grid {\n grid-template-columns: 1fr;\n }\n .health-banner {\n flex-direction: column;\n text-align: center;\n }\n .health-stats {\n flex-direction: column;\n gap: 8px;\n align-items: center;\n }\n .data-table {\n font-size: 0.8rem;\n }\n}\n"] }]
594
595
  }], () => [{ type: i1.SchedulingInstrumentationService }, { type: i0.ChangeDetectorRef }], { initialState: [{
595
596
  type: Input
596
597
  }], stateChange: [{