@memberjunction/ng-dashboards 5.11.0 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts +34 -2
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js +586 -223
  4. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  5. package/dist/AI/components/agents/agent-editor.component.js +2 -2
  6. package/dist/AI/components/agents/agent-filter-panel.component.d.ts +8 -0
  7. package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
  8. package/dist/AI/components/agents/agent-filter-panel.component.js +85 -52
  9. package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
  10. package/dist/AI/components/charts/performance-heatmap.component.d.ts +1 -0
  11. package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -1
  12. package/dist/AI/components/charts/performance-heatmap.component.js +27 -5
  13. package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
  14. package/dist/AI/components/charts/time-series-chart.component.d.ts +5 -0
  15. package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -1
  16. package/dist/AI/components/charts/time-series-chart.component.js +23 -8
  17. package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
  18. package/dist/AI/components/execution-monitoring.component.js +2 -2
  19. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  20. package/dist/AI/components/models/model-management.component.js +2 -2
  21. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +2 -2
  22. package/dist/AI/components/prompts/prompt-filter-panel.component.js +2 -2
  23. package/dist/AI/components/prompts/prompt-management.component.js +3 -3
  24. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  25. package/dist/AI/components/prompts/prompt-version-control.component.js +2 -2
  26. package/dist/AI/components/requests/agent-requests-resource.component.d.ts +83 -0
  27. package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -0
  28. package/dist/AI/components/requests/agent-requests-resource.component.js +547 -0
  29. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -0
  30. package/dist/AI/components/system/system-config-filter-panel.component.js +2 -2
  31. package/dist/AI/components/system/system-configuration.component.js +2 -2
  32. package/dist/AI/components/widgets/kpi-card.component.js +7 -7
  33. package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
  34. package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -1
  35. package/dist/AI/components/widgets/live-execution-widget.component.js +6 -6
  36. package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
  37. package/dist/AI/index.d.ts +1 -0
  38. package/dist/AI/index.d.ts.map +1 -1
  39. package/dist/AI/index.js +2 -0
  40. package/dist/AI/index.js.map +1 -1
  41. package/dist/APIKeys/api-applications-panel.component.js +3 -3
  42. package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
  43. package/dist/APIKeys/api-key-create-dialog.component.js +3 -3
  44. package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
  45. package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
  46. package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
  47. package/dist/APIKeys/api-key-list.component.js +3 -3
  48. package/dist/APIKeys/api-key-list.component.js.map +1 -1
  49. package/dist/APIKeys/api-keys-resource.component.js +1 -1
  50. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  51. package/dist/APIKeys/api-scopes-panel.component.js +2 -2
  52. package/dist/APIKeys/api-usage-panel.component.js +2 -2
  53. package/dist/Actions/components/actions-overview.component.js +2 -2
  54. package/dist/Actions/components/execution-monitoring.component.js +2 -2
  55. package/dist/Actions/components/explorer/action-breadcrumb.component.js +2 -2
  56. package/dist/Actions/components/explorer/action-card.component.js +2 -2
  57. package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
  58. package/dist/Actions/components/explorer/action-list-item.component.js +2 -2
  59. package/dist/Actions/components/explorer/action-toolbar.component.js +2 -2
  60. package/dist/Actions/components/explorer/action-tree-panel.component.js +2 -2
  61. package/dist/Actions/components/explorer/new-action-panel.component.js +2 -2
  62. package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
  63. package/dist/Actions/components/explorer/new-category-panel.component.js +2 -2
  64. package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
  65. package/dist/Communication/communication-dashboard.component.js +2 -2
  66. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  67. package/dist/Communication/communication-logs-resource.component.js +3 -3
  68. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  69. package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
  70. package/dist/Communication/communication-monitor-resource.component.js +5 -5
  71. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  72. package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
  73. package/dist/Communication/communication-providers-resource.component.js +3 -3
  74. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  75. package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
  76. package/dist/Communication/communication-runs-resource.component.js +3 -3
  77. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  78. package/dist/Communication/communication-templates-resource.component.js +2 -2
  79. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  80. package/dist/ComponentStudio/component-studio-dashboard.component.js +2 -2
  81. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +2 -2
  82. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +2 -2
  83. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +2 -2
  84. package/dist/ComponentStudio/components/browser/component-browser.component.js +2 -2
  85. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +2 -2
  86. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
  87. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +2 -2
  88. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
  89. package/dist/ComponentStudio/components/editors/requirements-editor.component.js +2 -2
  90. package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
  91. package/dist/ComponentStudio/components/editors/spec-editor.component.js +2 -2
  92. package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
  93. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +2 -2
  94. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +2 -2
  95. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
  96. package/dist/ComponentStudio/components/text-import-dialog.component.js +2 -2
  97. package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
  98. package/dist/ComponentStudio/components/workspace/component-preview.component.js +2 -2
  99. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +2 -2
  100. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
  101. package/dist/Credentials/components/credentials-audit-resource.component.js +9 -9
  102. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  103. package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
  104. package/dist/Credentials/components/credentials-categories-resource.component.js +11 -3
  105. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  106. package/dist/Credentials/components/credentials-list-resource.component.js +2 -2
  107. package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
  108. package/dist/Credentials/components/credentials-overview-resource.component.js +12 -11
  109. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  110. package/dist/Credentials/components/credentials-types-resource.component.js +9 -9
  111. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  112. package/dist/Credentials/credentials-dashboard.component.js +2 -2
  113. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +2 -2
  114. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +2 -2
  115. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
  116. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +2 -2
  117. package/dist/DataExplorer/components/view-selector/view-selector.component.js +2 -2
  118. package/dist/DataExplorer/data-explorer-dashboard.component.js +4 -4
  119. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  120. package/dist/Home/home-dashboard.component.js +2 -2
  121. package/dist/Integration/components/activity/activity.component.d.ts +1 -1
  122. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  123. package/dist/Integration/components/activity/activity.component.js +5 -5
  124. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  125. package/dist/Integration/components/connections/connections.component.d.ts +31 -2
  126. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  127. package/dist/Integration/components/connections/connections.component.js +753 -412
  128. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  129. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +3 -3
  130. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  131. package/dist/Integration/components/overview/overview.component.d.ts +0 -1
  132. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  133. package/dist/Integration/components/overview/overview.component.js +3 -6
  134. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  135. package/dist/Integration/components/pipelines/pipelines.component.js +3 -3
  136. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  137. package/dist/Integration/components/schedules/schedules.component.d.ts +20 -0
  138. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  139. package/dist/Integration/components/schedules/schedules.component.js +97 -5
  140. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  141. package/dist/Integration/components/visual-editor/visual-editor.component.js +2 -2
  142. package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -1
  143. package/dist/Integration/components/widgets/integration-card.component.js +5 -1
  144. package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
  145. package/dist/Integration/components/widgets/run-history-panel.component.js +2 -2
  146. package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
  147. package/dist/Integration/integration.module.d.ts +2 -1
  148. package/dist/Integration/integration.module.d.ts.map +1 -1
  149. package/dist/Integration/integration.module.js +7 -3
  150. package/dist/Integration/integration.module.js.map +1 -1
  151. package/dist/Integration/services/integration-data.service.d.ts +27 -2
  152. package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
  153. package/dist/Integration/services/integration-data.service.js +107 -4
  154. package/dist/Integration/services/integration-data.service.js.map +1 -1
  155. package/dist/Lists/components/lists-browse-resource.component.js +2 -2
  156. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  157. package/dist/Lists/components/lists-categories-resource.component.js +2 -2
  158. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  159. package/dist/Lists/components/lists-my-lists-resource.component.js +2 -2
  160. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  161. package/dist/Lists/components/lists-operations-resource.component.js +2 -2
  162. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  163. package/dist/Lists/components/venn-diagram/venn-diagram.component.js +3 -3
  164. package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
  165. package/dist/MCP/components/mcp-connection-dialog.component.js +2 -2
  166. package/dist/MCP/components/mcp-log-detail-panel.component.js +2 -2
  167. package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
  168. package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
  169. package/dist/MCP/components/mcp-test-tool-dialog.component.js +2 -2
  170. package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
  171. package/dist/MCP/mcp-dashboard.component.js +2 -2
  172. package/dist/MCP/mcp-filter-panel.component.js +2 -2
  173. package/dist/QueryBrowser/query-browser-resource.component.js +7 -7
  174. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  175. package/dist/Scheduling/components/index.d.ts +0 -1
  176. package/dist/Scheduling/components/index.d.ts.map +1 -1
  177. package/dist/Scheduling/components/index.js +0 -1
  178. package/dist/Scheduling/components/index.js.map +1 -1
  179. package/dist/Scheduling/components/scheduling-activity.component.js +2 -2
  180. package/dist/Scheduling/components/scheduling-jobs.component.d.ts +6 -9
  181. package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
  182. package/dist/Scheduling/components/scheduling-jobs.component.js +118 -110
  183. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  184. package/dist/Scheduling/components/scheduling-overview.component.js +3 -3
  185. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  186. package/dist/Scheduling/scheduling-dashboard.component.js +2 -2
  187. package/dist/SystemDiagnostics/system-diagnostics.component.js +4 -4
  188. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  189. package/dist/Testing/components/testing-analytics.component.js +2 -2
  190. package/dist/Testing/components/testing-analytics.component.js.map +1 -1
  191. package/dist/Testing/components/testing-dashboard-tab.component.js +4 -4
  192. package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
  193. package/dist/Testing/components/testing-explorer.component.js +2 -2
  194. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  195. package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
  196. package/dist/Testing/components/testing-review.component.js +5 -5
  197. package/dist/Testing/components/testing-review.component.js.map +1 -1
  198. package/dist/Testing/components/testing-runs.component.js +2 -2
  199. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  200. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +2 -2
  201. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
  202. package/dist/Testing/components/widgets/suite-tree.component.js +4 -4
  203. package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
  204. package/dist/Testing/components/widgets/test-run-detail-panel.component.js +2 -2
  205. package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
  206. package/dist/Testing/testing-dashboard.component.js +2 -2
  207. package/dist/VersionHistory/components/diff-resource.component.js +2 -2
  208. package/dist/VersionHistory/components/graph-resource.component.js +2 -2
  209. package/dist/VersionHistory/components/labels-resource.component.js +3 -3
  210. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  211. package/dist/VersionHistory/components/restore-resource.component.js +3 -3
  212. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  213. package/dist/__tests__/integration-data-service.test.js +1 -0
  214. package/dist/__tests__/integration-data-service.test.js.map +1 -1
  215. package/dist/module.d.ts +52 -49
  216. package/dist/module.d.ts.map +1 -1
  217. package/dist/module.js +25 -6
  218. package/dist/module.js.map +1 -1
  219. package/dist/public-api.d.ts +1 -1
  220. package/dist/public-api.d.ts.map +1 -1
  221. package/dist/public-api.js +1 -1
  222. package/dist/public-api.js.map +1 -1
  223. package/package.json +42 -40
  224. package/dist/Scheduling/components/job-slideout.component.d.ts +0 -45
  225. package/dist/Scheduling/components/job-slideout.component.d.ts.map +0 -1
  226. package/dist/Scheduling/components/job-slideout.component.js +0 -459
  227. package/dist/Scheduling/components/job-slideout.component.js.map +0 -1
@@ -9,7 +9,7 @@ import * as i1 from "../services/scheduling-instrumentation.service";
9
9
  import * as i2 from "@angular/common";
10
10
  import * as i3 from "@angular/forms";
11
11
  import * as i4 from "@memberjunction/ng-shared-generic";
12
- import * as i5 from "./job-slideout.component";
12
+ import * as i5 from "@memberjunction/ng-scheduling";
13
13
  function SchedulingJobsComponent_For_10_Template(rf, ctx) { if (rf & 1) {
14
14
  i0.ɵɵelementStart(0, "option", 8);
15
15
  i0.ɵɵtext(1);
@@ -32,7 +32,7 @@ function SchedulingJobsComponent_For_15_Template(rf, ctx) { if (rf & 1) {
32
32
  } }
33
33
  function SchedulingJobsComponent_Conditional_25_Template(rf, ctx) { if (rf & 1) {
34
34
  i0.ɵɵelementStart(0, "div", 15);
35
- i0.ɵɵelement(1, "mj-loading", 22);
35
+ i0.ɵɵelement(1, "mj-loading", 19);
36
36
  i0.ɵɵelementEnd();
37
37
  } }
38
38
  function SchedulingJobsComponent_Conditional_26_Conditional_5_Template(rf, ctx) { if (rf & 1) {
@@ -54,15 +54,15 @@ function SchedulingJobsComponent_Conditional_26_Conditional_7_Template(rf, ctx)
54
54
  i0.ɵɵelementEnd();
55
55
  } }
56
56
  function SchedulingJobsComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
57
- i0.ɵɵelementStart(0, "div", 16)(1, "div", 23);
58
- i0.ɵɵelement(2, "i", 24);
57
+ i0.ɵɵelementStart(0, "div", 16)(1, "div", 20);
58
+ i0.ɵɵelement(2, "i", 21);
59
59
  i0.ɵɵelementEnd();
60
60
  i0.ɵɵelementStart(3, "h3");
61
61
  i0.ɵɵtext(4, "No jobs found");
62
62
  i0.ɵɵelementEnd();
63
63
  i0.ɵɵconditionalCreate(5, SchedulingJobsComponent_Conditional_26_Conditional_5_Template, 2, 0, "p");
64
64
  i0.ɵɵconditionalCreate(6, SchedulingJobsComponent_Conditional_26_Conditional_6_Template, 2, 0, "p");
65
- i0.ɵɵconditionalCreate(7, SchedulingJobsComponent_Conditional_26_Conditional_7_Template, 3, 0, "button", 25);
65
+ i0.ɵɵconditionalCreate(7, SchedulingJobsComponent_Conditional_26_Conditional_7_Template, 3, 0, "button", 22);
66
66
  i0.ɵɵelementEnd();
67
67
  } if (rf & 2) {
68
68
  const ctx_r3 = i0.ɵɵnextContext();
@@ -74,7 +74,7 @@ function SchedulingJobsComponent_Conditional_26_Template(rf, ctx) { if (rf & 1)
74
74
  i0.ɵɵconditional(!ctx_r3.SearchTerm && !ctx_r3.StatusFilter && !ctx_r3.TypeFilter ? 7 : -1);
75
75
  } }
76
76
  function SchedulingJobsComponent_Conditional_27_For_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
77
- i0.ɵɵelementStart(0, "div", 34);
77
+ i0.ɵɵelementStart(0, "div", 31);
78
78
  i0.ɵɵtext(1);
79
79
  i0.ɵɵelementEnd();
80
80
  } if (rf & 2) {
@@ -82,73 +82,110 @@ function SchedulingJobsComponent_Conditional_27_For_2_Conditional_9_Template(rf,
82
82
  i0.ɵɵadvance();
83
83
  i0.ɵɵtextInterpolate(job_r6.description);
84
84
  } }
85
+ function SchedulingJobsComponent_Conditional_27_For_2_Conditional_48_Conditional_7_Template(rf, ctx) { if (rf & 1) {
86
+ i0.ɵɵelement(0, "i", 62);
87
+ i0.ɵɵtext(1, " Deleting... ");
88
+ } }
89
+ function SchedulingJobsComponent_Conditional_27_For_2_Conditional_48_Conditional_8_Template(rf, ctx) { if (rf & 1) {
90
+ i0.ɵɵtext(0, " Delete ");
91
+ } }
92
+ function SchedulingJobsComponent_Conditional_27_For_2_Conditional_48_Template(rf, ctx) { if (rf & 1) {
93
+ const _r7 = i0.ɵɵgetCurrentView();
94
+ i0.ɵɵelementStart(0, "div", 55);
95
+ i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_27_For_2_Conditional_48_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r7); return i0.ɵɵresetView($event.stopPropagation()); });
96
+ i0.ɵɵelementStart(1, "div", 56);
97
+ i0.ɵɵelement(2, "i", 57);
98
+ i0.ɵɵelementStart(3, "span", 58);
99
+ i0.ɵɵtext(4, "Delete this scheduled job?");
100
+ i0.ɵɵelementEnd();
101
+ i0.ɵɵelementStart(5, "div", 59)(6, "button", 60);
102
+ i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_27_For_2_Conditional_48_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(_r7); const job_r6 = i0.ɵɵnextContext().$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.ConfirmDelete(job_r6.jobId, $event)); });
103
+ i0.ɵɵconditionalCreate(7, SchedulingJobsComponent_Conditional_27_For_2_Conditional_48_Conditional_7_Template, 2, 0)(8, SchedulingJobsComponent_Conditional_27_For_2_Conditional_48_Conditional_8_Template, 1, 0);
104
+ i0.ɵɵelementEnd();
105
+ i0.ɵɵelementStart(9, "button", 61);
106
+ i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_27_For_2_Conditional_48_Template_button_click_9_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r3 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r3.CancelDelete($event)); });
107
+ i0.ɵɵtext(10, "Cancel");
108
+ i0.ɵɵelementEnd()()()();
109
+ } if (rf & 2) {
110
+ const ctx_r3 = i0.ɵɵnextContext(3);
111
+ i0.ɵɵadvance(6);
112
+ i0.ɵɵproperty("disabled", ctx_r3.IsDeleting);
113
+ i0.ɵɵadvance();
114
+ i0.ɵɵconditional(ctx_r3.IsDeleting ? 7 : 8);
115
+ } }
85
116
  function SchedulingJobsComponent_Conditional_27_For_2_Template(rf, ctx) { if (rf & 1) {
86
117
  const _r5 = i0.ɵɵgetCurrentView();
87
- i0.ɵɵelementStart(0, "div", 27);
118
+ i0.ɵɵelementStart(0, "div", 24);
88
119
  i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_27_For_2_Template_div_click_0_listener() { const job_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.OpenEditSlideout(job_r6)); });
89
- i0.ɵɵelementStart(1, "div", 28)(2, "div", 29);
90
- i0.ɵɵelement(3, "i", 30);
91
- i0.ɵɵelementStart(4, "span", 31);
120
+ i0.ɵɵelementStart(1, "div", 25)(2, "div", 26);
121
+ i0.ɵɵelement(3, "i", 27);
122
+ i0.ɵɵelementStart(4, "span", 28);
92
123
  i0.ɵɵtext(5);
93
124
  i0.ɵɵelementEnd()();
94
- i0.ɵɵelementStart(6, "span", 32);
125
+ i0.ɵɵelementStart(6, "span", 29);
95
126
  i0.ɵɵtext(7);
96
127
  i0.ɵɵelementEnd()();
97
- i0.ɵɵelementStart(8, "div", 33);
98
- i0.ɵɵconditionalCreate(9, SchedulingJobsComponent_Conditional_27_For_2_Conditional_9_Template, 2, 1, "div", 34);
99
- i0.ɵɵelementStart(10, "div", 35)(11, "div", 36)(12, "span", 37);
128
+ i0.ɵɵelementStart(8, "div", 30);
129
+ i0.ɵɵconditionalCreate(9, SchedulingJobsComponent_Conditional_27_For_2_Conditional_9_Template, 2, 1, "div", 31);
130
+ i0.ɵɵelementStart(10, "div", 32)(11, "div", 33)(12, "span", 34);
100
131
  i0.ɵɵtext(13, "Type");
101
132
  i0.ɵɵelementEnd();
102
- i0.ɵɵelementStart(14, "span", 38);
133
+ i0.ɵɵelementStart(14, "span", 35);
103
134
  i0.ɵɵtext(15);
104
135
  i0.ɵɵelementEnd()();
105
- i0.ɵɵelementStart(16, "div", 36)(17, "span", 37);
136
+ i0.ɵɵelementStart(16, "div", 33)(17, "span", 34);
106
137
  i0.ɵɵtext(18, "Schedule");
107
138
  i0.ɵɵelementEnd();
108
- i0.ɵɵelementStart(19, "span", 39);
139
+ i0.ɵɵelementStart(19, "span", 36);
109
140
  i0.ɵɵtext(20);
110
141
  i0.ɵɵelementEnd()();
111
- i0.ɵɵelementStart(21, "div", 36)(22, "span", 37);
142
+ i0.ɵɵelementStart(21, "div", 33)(22, "span", 34);
112
143
  i0.ɵɵtext(23, "Last Run");
113
144
  i0.ɵɵelementEnd();
114
- i0.ɵɵelementStart(24, "span", 38);
145
+ i0.ɵɵelementStart(24, "span", 35);
115
146
  i0.ɵɵtext(25);
116
147
  i0.ɵɵelementEnd()();
117
- i0.ɵɵelementStart(26, "div", 36)(27, "span", 37);
148
+ i0.ɵɵelementStart(26, "div", 33)(27, "span", 34);
118
149
  i0.ɵɵtext(28, "Next Run");
119
150
  i0.ɵɵelementEnd();
120
- i0.ɵɵelementStart(29, "span", 38);
151
+ i0.ɵɵelementStart(29, "span", 35);
121
152
  i0.ɵɵtext(30);
122
153
  i0.ɵɵelementEnd()()();
123
- i0.ɵɵelementStart(31, "div", 40)(32, "div", 41)(33, "span", 42);
154
+ i0.ɵɵelementStart(31, "div", 37)(32, "div", 38)(33, "span", 39);
124
155
  i0.ɵɵtext(34, "Success Rate");
125
156
  i0.ɵɵelementEnd();
126
- i0.ɵɵelementStart(35, "span", 43);
157
+ i0.ɵɵelementStart(35, "span", 40);
127
158
  i0.ɵɵtext(36);
128
159
  i0.ɵɵelementEnd()();
129
- i0.ɵɵelementStart(37, "div", 44);
130
- i0.ɵɵelement(38, "div", 45);
160
+ i0.ɵɵelementStart(37, "div", 41);
161
+ i0.ɵɵelement(38, "div", 42);
131
162
  i0.ɵɵelementEnd();
132
- i0.ɵɵelementStart(39, "div", 46)(40, "span", 47);
133
- i0.ɵɵelement(41, "i", 48);
163
+ i0.ɵɵelementStart(39, "div", 43)(40, "span", 44);
164
+ i0.ɵɵelement(41, "i", 45);
134
165
  i0.ɵɵtext(42);
135
166
  i0.ɵɵelementEnd();
136
- i0.ɵɵelementStart(43, "span", 49);
137
- i0.ɵɵelement(44, "i", 50);
167
+ i0.ɵɵelementStart(43, "span", 46);
168
+ i0.ɵɵelement(44, "i", 47);
138
169
  i0.ɵɵtext(45);
139
170
  i0.ɵɵelementEnd();
140
- i0.ɵɵelementStart(46, "span", 51);
171
+ i0.ɵɵelementStart(46, "span", 48);
141
172
  i0.ɵɵtext(47);
142
173
  i0.ɵɵelementEnd()()()();
143
- i0.ɵɵelementStart(48, "div", 52)(49, "button", 53);
144
- i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_27_For_2_Template_button_click_49_listener($event) { const job_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.ToggleJobStatus(job_r6, $event)); });
145
- i0.ɵɵelement(50, "i");
146
- i0.ɵɵtext(51);
174
+ i0.ɵɵconditionalCreate(48, SchedulingJobsComponent_Conditional_27_For_2_Conditional_48_Template, 11, 2, "div", 49);
175
+ i0.ɵɵelementStart(49, "div", 50)(50, "button", 51);
176
+ i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_27_For_2_Template_button_click_50_listener($event) { const job_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.ToggleJobStatus(job_r6, $event)); });
177
+ i0.ɵɵelement(51, "i");
178
+ i0.ɵɵtext(52);
147
179
  i0.ɵɵelementEnd();
148
- i0.ɵɵelementStart(52, "button", 53);
149
- i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_27_For_2_Template_button_click_52_listener($event) { const job_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); ctx_r3.OpenEntityRecord(job_r6); return i0.ɵɵresetView($event.stopPropagation()); });
150
- i0.ɵɵelement(53, "i", 54);
151
- i0.ɵɵtext(54, " Full Details ");
180
+ i0.ɵɵelementStart(53, "button", 51);
181
+ i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_27_For_2_Template_button_click_53_listener($event) { const job_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); ctx_r3.OpenEntityRecord(job_r6); return i0.ɵɵresetView($event.stopPropagation()); });
182
+ i0.ɵɵelement(54, "i", 52);
183
+ i0.ɵɵtext(55, " Full Details ");
184
+ i0.ɵɵelementEnd();
185
+ i0.ɵɵelementStart(56, "button", 53);
186
+ i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_27_For_2_Template_button_click_56_listener($event) { const job_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.ShowDeleteConfirm(job_r6, $event)); });
187
+ i0.ɵɵelement(57, "i", 54);
188
+ i0.ɵɵtext(58, " Delete ");
152
189
  i0.ɵɵelementEnd()()();
153
190
  } if (rf & 2) {
154
191
  const job_r6 = ctx.$implicit;
@@ -183,6 +220,8 @@ function SchedulingJobsComponent_Conditional_27_For_2_Template(rf, ctx) { if (rf
183
220
  i0.ɵɵtextInterpolate1(" ", job_r6.failureCount);
184
221
  i0.ɵɵadvance(2);
185
222
  i0.ɵɵtextInterpolate1("", job_r6.totalRuns, " total");
223
+ i0.ɵɵadvance();
224
+ i0.ɵɵconditional(ctx_r3.IsDeleteConfirming(job_r6.jobId) ? 48 : -1);
186
225
  i0.ɵɵadvance(3);
187
226
  i0.ɵɵclassMap(job_r6.status === "Active" ? "fa-solid fa-pause" : "fa-solid fa-play");
188
227
  i0.ɵɵadvance();
@@ -190,28 +229,13 @@ function SchedulingJobsComponent_Conditional_27_For_2_Template(rf, ctx) { if (rf
190
229
  } }
191
230
  function SchedulingJobsComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
192
231
  i0.ɵɵelementStart(0, "div", 17);
193
- i0.ɵɵrepeaterCreate(1, SchedulingJobsComponent_Conditional_27_For_2_Template, 55, 23, "div", 26, i0.ɵɵrepeaterTrackByIdentity);
232
+ i0.ɵɵrepeaterCreate(1, SchedulingJobsComponent_Conditional_27_For_2_Template, 59, 24, "div", 23, i0.ɵɵrepeaterTrackByIdentity);
194
233
  i0.ɵɵelementEnd();
195
234
  } if (rf & 2) {
196
235
  const ctx_r3 = i0.ɵɵnextContext();
197
236
  i0.ɵɵadvance();
198
237
  i0.ɵɵrepeater(ctx_r3.FilteredJobs);
199
238
  } }
200
- function SchedulingJobsComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
201
- const _r7 = i0.ɵɵgetCurrentView();
202
- i0.ɵɵelementStart(0, "div", 55);
203
- i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_28_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.CloseSlideout()); });
204
- i0.ɵɵelementEnd();
205
- } }
206
- function SchedulingJobsComponent_Conditional_31_Template(rf, ctx) { if (rf & 1) {
207
- const _r8 = i0.ɵɵgetCurrentView();
208
- i0.ɵɵelementStart(0, "app-job-slideout", 56);
209
- i0.ɵɵlistener("Close", function SchedulingJobsComponent_Conditional_31_Template_app_job_slideout_Close_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.CloseSlideout()); })("Saved", function SchedulingJobsComponent_Conditional_31_Template_app_job_slideout_Saved_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.OnSlideoutSaved()); });
210
- i0.ɵɵelementEnd();
211
- } if (rf & 2) {
212
- const ctx_r3 = i0.ɵɵnextContext();
213
- i0.ɵɵproperty("Mode", ctx_r3.SlideoutMode)("Job", ctx_r3.SelectedJob);
214
- } }
215
239
  export class SchedulingJobsComponent {
216
240
  schedulingService;
217
241
  cdr;
@@ -223,13 +247,10 @@ export class SchedulingJobsComponent {
223
247
  IsLoading = true;
224
248
  // Slideout state
225
249
  SlideoutOpen = false;
226
- SlideoutMode = 'create';
227
250
  SelectedJob = null;
228
- SlideoutWidth = 620;
229
- // Resize state
230
- resizeStartX = 0;
231
- resizeStartWidth = 0;
232
- isResizing = false;
251
+ // Delete confirmation state
252
+ DeleteConfirmJobId = null;
253
+ IsDeleting = false;
233
254
  // Filters
234
255
  SearchTerm = '';
235
256
  StatusFilter = '';
@@ -237,7 +258,6 @@ export class SchedulingJobsComponent {
237
258
  StatusOptions = ['', 'Active', 'Paused', 'Disabled', 'Pending', 'Expired'];
238
259
  TypeOptions = [''];
239
260
  // Settings keys
240
- static PANEL_WIDTH_KEY = 'Scheduling.SlideoutPanelWidth';
241
261
  static SEARCH_STATE_KEY = 'Scheduling.JobsSearchState';
242
262
  searchSubject = new BehaviorSubject('');
243
263
  statusSubject = new BehaviorSubject('');
@@ -270,18 +290,9 @@ export class SchedulingJobsComponent {
270
290
  this.destroy$.next();
271
291
  this.destroy$.complete();
272
292
  this.subscriptions.forEach(s => s.unsubscribe());
273
- document.removeEventListener('mousemove', this.onResizeMove);
274
- document.removeEventListener('mouseup', this.onResizeEnd);
275
293
  }
276
294
  loadUserSettings() {
277
295
  try {
278
- const widthStr = UserInfoEngine.Instance.GetSetting(SchedulingJobsComponent.PANEL_WIDTH_KEY);
279
- if (widthStr) {
280
- const width = parseInt(widthStr, 10);
281
- if (!isNaN(width) && width >= 400 && width <= 900) {
282
- this.SlideoutWidth = width;
283
- }
284
- }
285
296
  const stateStr = UserInfoEngine.Instance.GetSetting(SchedulingJobsComponent.SEARCH_STATE_KEY);
286
297
  if (stateStr) {
287
298
  const state = JSON.parse(stateStr);
@@ -359,39 +370,13 @@ export class SchedulingJobsComponent {
359
370
  Refresh() {
360
371
  this.schedulingService.refresh();
361
372
  }
362
- // ── Resize ──────────────────────────────────────────────
363
- OnResizeStart(event) {
364
- event.preventDefault();
365
- this.isResizing = true;
366
- this.resizeStartX = event.clientX;
367
- this.resizeStartWidth = this.SlideoutWidth;
368
- document.addEventListener('mousemove', this.onResizeMove);
369
- document.addEventListener('mouseup', this.onResizeEnd);
370
- document.body.style.cursor = 'col-resize';
371
- document.body.style.userSelect = 'none';
372
- }
373
- onResizeMove = (event) => {
374
- const delta = this.resizeStartX - event.clientX;
375
- this.SlideoutWidth = Math.max(400, Math.min(900, this.resizeStartWidth + delta));
376
- this.cdr.detectChanges();
377
- };
378
- onResizeEnd = () => {
379
- this.isResizing = false;
380
- document.removeEventListener('mousemove', this.onResizeMove);
381
- document.removeEventListener('mouseup', this.onResizeEnd);
382
- document.body.style.cursor = '';
383
- document.body.style.userSelect = '';
384
- UserInfoEngine.Instance.SetSettingDebounced(SchedulingJobsComponent.PANEL_WIDTH_KEY, String(this.SlideoutWidth));
385
- };
386
373
  OpenCreateSlideout() {
387
374
  this.SelectedJob = null;
388
- this.SlideoutMode = 'create';
389
375
  this.SlideoutOpen = true;
390
376
  this.cdr.markForCheck();
391
377
  }
392
378
  OpenEditSlideout(job) {
393
379
  this.SelectedJob = job;
394
- this.SlideoutMode = 'edit';
395
380
  this.SlideoutOpen = true;
396
381
  this.cdr.markForCheck();
397
382
  }
@@ -409,6 +394,37 @@ export class SchedulingJobsComponent {
409
394
  const newStatus = job.status === 'Active' ? 'Paused' : 'Active';
410
395
  await this.schedulingService.updateJobStatus(job.jobId, newStatus);
411
396
  }
397
+ ShowDeleteConfirm(job, event) {
398
+ event.stopPropagation();
399
+ this.DeleteConfirmJobId = job.jobId;
400
+ this.cdr.markForCheck();
401
+ }
402
+ CancelDelete(event) {
403
+ event.stopPropagation();
404
+ this.DeleteConfirmJobId = null;
405
+ this.cdr.markForCheck();
406
+ }
407
+ async ConfirmDelete(jobId, event) {
408
+ event.stopPropagation();
409
+ this.IsDeleting = true;
410
+ this.cdr.markForCheck();
411
+ try {
412
+ const result = await this.schedulingService.deleteJob(jobId);
413
+ if (result) {
414
+ this.DeleteConfirmJobId = null;
415
+ }
416
+ }
417
+ catch (err) {
418
+ console.error('[SchedulingJobs] Delete error:', err);
419
+ }
420
+ finally {
421
+ this.IsDeleting = false;
422
+ this.cdr.markForCheck();
423
+ }
424
+ }
425
+ IsDeleteConfirming(jobId) {
426
+ return this.DeleteConfirmJobId === jobId;
427
+ }
412
428
  OpenEntityRecord(job) {
413
429
  const compositeKey = new CompositeKey();
414
430
  compositeKey.LoadFromSingleKeyValuePair('ID', job.jobId);
@@ -479,7 +495,7 @@ export class SchedulingJobsComponent {
479
495
  this.settingsPersistSubject.next();
480
496
  }
481
497
  static ɵfac = function SchedulingJobsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SchedulingJobsComponent)(i0.ɵɵdirectiveInject(i1.SchedulingInstrumentationService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
482
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingJobsComponent, selectors: [["app-scheduling-jobs"]], inputs: { initialState: "initialState" }, outputs: { stateChange: "stateChange" }, standalone: false, decls: 32, vars: 14, consts: [[1, "jobs-container"], [1, "jobs-toolbar"], [1, "toolbar-left"], [1, "search-box"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search jobs...", 3, "input", "value"], [1, "filter-select", 3, "change", "value"], ["value", ""], [3, "value"], [1, "toolbar-right"], [1, "result-count"], [1, "control-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], [1, "primary-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "loading-container"], [1, "empty-state"], [1, "jobs-grid"], [1, "slideout-backdrop"], [1, "slideout-panel"], [1, "slideout-resize-handle", 3, "mousedown"], [3, "Mode", "Job"], ["text", "Loading jobs...", "size", "medium"], [1, "empty-icon"], [1, "fa-solid", "fa-calendar-xmark"], [1, "primary-btn"], [1, "job-card"], [1, "job-card", 3, "click"], [1, "job-card-header"], [1, "job-card-title"], [1, "type-icon"], [1, "job-name"], [1, "status-chip", 3, "ngClass"], [1, "job-card-body"], [1, "job-description"], [1, "job-meta-grid"], [1, "meta-item"], [1, "meta-label"], [1, "meta-value"], [1, "meta-value", "mono"], [1, "success-section"], [1, "success-header"], [1, "success-label"], [1, "success-value"], [1, "success-bar-track"], [1, "success-bar-fill"], [1, "run-stats"], [1, "stat-success"], [1, "fa-solid", "fa-check"], [1, "stat-failure"], [1, "fa-solid", "fa-xmark"], [1, "stat-total"], [1, "job-card-footer"], [1, "action-btn", 3, "click"], [1, "fa-solid", "fa-up-right-from-square"], [1, "slideout-backdrop", 3, "click"], [3, "Close", "Saved", "Mode", "Job"]], template: function SchedulingJobsComponent_Template(rf, ctx) { if (rf & 1) {
498
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingJobsComponent, selectors: [["app-scheduling-jobs"]], inputs: { initialState: "initialState" }, outputs: { stateChange: "stateChange" }, standalone: false, decls: 29, vars: 10, consts: [[1, "jobs-container"], [1, "jobs-toolbar"], [1, "toolbar-left"], [1, "search-box"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search jobs...", 3, "input", "value"], [1, "filter-select", 3, "change", "value"], ["value", ""], [3, "value"], [1, "toolbar-right"], [1, "result-count"], [1, "control-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], [1, "primary-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "loading-container"], [1, "empty-state"], [1, "jobs-grid"], [3, "Close", "Saved", "Deleted", "IsOpen", "ScheduledJobID"], ["text", "Loading jobs...", "size", "medium"], [1, "empty-icon"], [1, "fa-solid", "fa-calendar-xmark"], [1, "primary-btn"], [1, "job-card"], [1, "job-card", 3, "click"], [1, "job-card-header"], [1, "job-card-title"], [1, "type-icon"], [1, "job-name"], [1, "status-chip", 3, "ngClass"], [1, "job-card-body"], [1, "job-description"], [1, "job-meta-grid"], [1, "meta-item"], [1, "meta-label"], [1, "meta-value"], [1, "meta-value", "mono"], [1, "success-section"], [1, "success-header"], [1, "success-label"], [1, "success-value"], [1, "success-bar-track"], [1, "success-bar-fill"], [1, "run-stats"], [1, "stat-success"], [1, "fa-solid", "fa-check"], [1, "stat-failure"], [1, "fa-solid", "fa-xmark"], [1, "stat-total"], [1, "delete-confirm-overlay"], [1, "job-card-footer"], [1, "action-btn", 3, "click"], [1, "fa-solid", "fa-up-right-from-square"], [1, "action-btn", "action-btn-danger", 3, "click"], [1, "fa-solid", "fa-trash-can"], [1, "delete-confirm-overlay", 3, "click"], [1, "delete-confirm-content"], [1, "fa-solid", "fa-triangle-exclamation", "delete-warn-icon"], [1, "delete-confirm-text"], [1, "delete-confirm-actions"], [1, "delete-confirm-btn", 3, "click", "disabled"], [1, "delete-cancel-btn", 3, "click"], [1, "fa-solid", "fa-spinner", "fa-spin"]], template: function SchedulingJobsComponent_Template(rf, ctx) { if (rf & 1) {
483
499
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3);
484
500
  i0.ɵɵelement(4, "i", 4);
485
501
  i0.ɵɵelementStart(5, "input", 5);
@@ -515,11 +531,8 @@ export class SchedulingJobsComponent {
515
531
  i0.ɵɵconditionalCreate(25, SchedulingJobsComponent_Conditional_25_Template, 2, 0, "div", 15);
516
532
  i0.ɵɵconditionalCreate(26, SchedulingJobsComponent_Conditional_26_Template, 8, 3, "div", 16);
517
533
  i0.ɵɵconditionalCreate(27, SchedulingJobsComponent_Conditional_27_Template, 3, 0, "div", 17);
518
- i0.ɵɵconditionalCreate(28, SchedulingJobsComponent_Conditional_28_Template, 1, 0, "div", 18);
519
- i0.ɵɵelementStart(29, "div", 19)(30, "div", 20);
520
- i0.ɵɵlistener("mousedown", function SchedulingJobsComponent_Template_div_mousedown_30_listener($event) { return ctx.OnResizeStart($event); });
521
- i0.ɵɵelementEnd();
522
- i0.ɵɵconditionalCreate(31, SchedulingJobsComponent_Conditional_31_Template, 1, 2, "app-job-slideout", 21);
534
+ i0.ɵɵelementStart(28, "mj-scheduled-job-slide-panel", 18);
535
+ i0.ɵɵlistener("Close", function SchedulingJobsComponent_Template_mj_scheduled_job_slide_panel_Close_28_listener() { return ctx.CloseSlideout(); })("Saved", function SchedulingJobsComponent_Template_mj_scheduled_job_slide_panel_Saved_28_listener() { return ctx.OnSlideoutSaved(); })("Deleted", function SchedulingJobsComponent_Template_mj_scheduled_job_slide_panel_Deleted_28_listener() { return ctx.OnSlideoutSaved(); });
523
536
  i0.ɵɵelementEnd()();
524
537
  } if (rf & 2) {
525
538
  i0.ɵɵadvance(5);
@@ -541,17 +554,12 @@ export class SchedulingJobsComponent {
541
554
  i0.ɵɵadvance();
542
555
  i0.ɵɵconditional(!ctx.IsLoading && ctx.FilteredJobs.length > 0 ? 27 : -1);
543
556
  i0.ɵɵadvance();
544
- i0.ɵɵconditional(ctx.SlideoutOpen ? 28 : -1);
545
- i0.ɵɵadvance();
546
- i0.ɵɵstyleProp("width", ctx.SlideoutWidth, "px");
547
- i0.ɵɵclassProp("open", ctx.SlideoutOpen);
548
- i0.ɵɵadvance(2);
549
- i0.ɵɵconditional(ctx.SlideoutOpen ? 31 : -1);
550
- } }, dependencies: [i2.NgClass, i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i4.LoadingComponent, i5.JobSlideoutComponent], styles: [".jobs-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n position: relative;\n}\n\n\n\n.jobs-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.search-box[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n min-width: 240px;\n transition: border-color 0.2s;\n}\n\n.search-box[_ngcontent-%COMP%]:focus-within {\n border-color: #0076b6;\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.1);\n}\n\n.search-box[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #94a3b8;\n font-size: 0.85rem;\n}\n\n.search-box[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: none;\n outline: none;\n background: transparent;\n font-size: 0.85rem;\n color: #0f172a;\n width: 100%;\n}\n\n.filter-select[_ngcontent-%COMP%] {\n padding: 8px 14px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n font-size: 0.85rem;\n color: #475569;\n cursor: pointer;\n outline: none;\n transition: border-color 0.2s;\n}\n\n.filter-select[_ngcontent-%COMP%]:focus {\n border-color: #0076b6;\n}\n\n.result-count[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: #94a3b8;\n white-space: nowrap;\n}\n\n.control-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n color: #475569;\n transition: all 0.2s ease;\n}\n\n.control-btn[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n border-color: #999;\n}\n\n.primary-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 20px;\n background: linear-gradient(135deg, #0076b6 0%, #005a8c 100%);\n color: white;\n border: none;\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 600;\n transition: all 0.2s ease;\n}\n\n.primary-btn[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(0, 118, 182, 0.4);\n}\n\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.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 64px 24px;\n background: white;\n border-radius: 16px;\n border: 2px dashed #dee2e6;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: #f8f9fa;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2rem;\n color: #adb5bd;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n font-weight: 700;\n color: #334155;\n margin: 0 0 8px;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: #64748b;\n margin: 0 0 16px;\n font-size: 0.9rem;\n}\n\n\n\n.jobs-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));\n gap: 16px;\n}\n\n.job-card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 16px;\n border: 1px solid #e2e8f0;\n box-shadow: 0 1px 3px rgba(0,0,0,0.05);\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.job-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 25px -5px rgba(0,0,0,0.1);\n border-color: #0076b6;\n}\n\n\n\n.job-card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #f1f5f9;\n}\n\n.job-card-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex: 1;\n min-width: 0;\n}\n\n.type-icon[_ngcontent-%COMP%] {\n color: #0076b6;\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.job-name[_ngcontent-%COMP%] {\n font-weight: 700;\n color: #0f172a;\n font-size: 0.9rem;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.3;\n}\n\n.status-chip[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 700;\n padding: 3px 10px;\n border-radius: 12px;\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n.status-active[_ngcontent-%COMP%] { background: #dcfce7; color: #166534; }\n.status-paused[_ngcontent-%COMP%] { background: #fef3c7; color: #92400e; }\n.status-disabled[_ngcontent-%COMP%] { background: #f1f5f9; color: #64748b; }\n.status-pending[_ngcontent-%COMP%] { background: #dbeafe; color: #1e40af; }\n.status-expired[_ngcontent-%COMP%] { background: #fee2e2; color: #991b1b; }\n\n\n\n.job-card-body[_ngcontent-%COMP%] {\n padding: 16px 20px;\n flex: 1;\n}\n\n.job-description[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: #64748b;\n margin-bottom: 12px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n}\n\n.job-meta-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.meta-label[_ngcontent-%COMP%] {\n font-size: 0.65rem;\n font-weight: 700;\n color: #94a3b8;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.meta-value[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: #334155;\n font-weight: 500;\n}\n\n.meta-value.mono[_ngcontent-%COMP%] {\n font-family: 'SFMono-Regular', Consolas, monospace;\n font-size: 0.75rem;\n}\n\n\n\n.success-section[_ngcontent-%COMP%] {\n padding-top: 12px;\n border-top: 1px solid #f1f5f9;\n}\n\n.success-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n\n.success-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n color: #64748b;\n}\n\n.success-value[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n font-weight: 800;\n}\n\n.success-bar-track[_ngcontent-%COMP%] {\n height: 6px;\n background: #f1f5f9;\n border-radius: 3px;\n overflow: hidden;\n}\n\n.success-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 3px;\n transition: width 0.5s ease;\n}\n\n.run-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n margin-top: 8px;\n font-size: 0.75rem;\n}\n\n.stat-success[_ngcontent-%COMP%] { color: #10b981; font-weight: 600; }\n.stat-failure[_ngcontent-%COMP%] { color: #ef4444; font-weight: 600; }\n.stat-total[_ngcontent-%COMP%] { color: #94a3b8; margin-left: auto; }\n\n\n\n.job-card-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding: 12px 20px;\n border-top: 1px solid #f1f5f9;\n background: #fafbfc;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.75rem;\n font-weight: 500;\n color: #475569;\n transition: all 0.2s;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n border-color: #999;\n}\n\n\n\n.slideout-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 999;\n animation: _ngcontent-%COMP%_fadeInBackdrop 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeInBackdrop {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.slideout-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: -100%;\n height: 100vh;\n background: white;\n box-shadow: -4px 0 20px rgba(0,0,0,0.15);\n z-index: 1000;\n transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slideout-panel.open[_ngcontent-%COMP%] {\n right: 0;\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n width: 5px;\n height: 100%;\n cursor: col-resize;\n background: transparent;\n z-index: 10;\n transition: background 0.2s;\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%]:hover {\n background: rgba(0, 118, 182, 0.3);\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%]:active {\n background: rgba(0, 118, 182, 0.5);\n}\n\n\n\n@media (max-width: 1024px) {\n .jobs-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n }\n}\n\n@media (max-width: 768px) {\n .jobs-toolbar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n .toolbar-right[_ngcontent-%COMP%] {\n justify-content: space-between;\n }\n .jobs-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .search-box[_ngcontent-%COMP%] {\n min-width: auto;\n flex: 1;\n }\n .slideout-panel[_ngcontent-%COMP%] {\n width: 100% !important;\n }\n .slideout-resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n}"], changeDetection: 0 });
557
+ i0.ɵɵproperty("IsOpen", ctx.SlideoutOpen)("ScheduledJobID", (ctx.SelectedJob == null ? null : ctx.SelectedJob.jobId) ?? null);
558
+ } }, dependencies: [i2.NgClass, i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i4.LoadingComponent, i5.ScheduledJobSlidePanelComponent], styles: [".jobs-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n position: relative;\n}\n\n\n\n.jobs-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.search-box[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n min-width: 240px;\n transition: border-color 0.2s;\n}\n\n.search-box[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.search-box[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.85rem;\n}\n\n.search-box[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: none;\n outline: none;\n background: transparent;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n width: 100%;\n}\n\n.filter-select[_ngcontent-%COMP%] {\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n cursor: pointer;\n outline: none;\n transition: border-color 0.2s;\n}\n\n.filter-select[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n}\n\n.result-count[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.control-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\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.primary-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 600;\n transition: all 0.2s ease;\n}\n\n.primary-btn[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\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.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 64px 24px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2rem;\n color: var(--mj-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n margin: 0 0 16px;\n font-size: 0.9rem;\n}\n\n\n\n.jobs-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));\n gap: 16px;\n}\n\n.job-card[_ngcontent-%COMP%] {\n position: relative;\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 cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.job-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--mj-shadow-lg);\n border-color: var(--mj-brand-primary);\n}\n\n\n\n.job-card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.job-card-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex: 1;\n min-width: 0;\n}\n\n.type-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.job-name[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.3;\n}\n\n.status-chip[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 700;\n padding: 3px 10px;\n border-radius: 12px;\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n.status-active[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-paused[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-disabled[_ngcontent-%COMP%] { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.status-pending[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-expired[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n\n\n.job-card-body[_ngcontent-%COMP%] {\n padding: 16px 20px;\n flex: 1;\n}\n\n.job-description[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n}\n\n.job-meta-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.meta-label[_ngcontent-%COMP%] {\n font-size: 0.65rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.meta-value[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.meta-value.mono[_ngcontent-%COMP%] {\n font-family: 'SFMono-Regular', Consolas, monospace;\n font-size: 0.75rem;\n}\n\n\n\n.success-section[_ngcontent-%COMP%] {\n padding-top: 12px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.success-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n\n.success-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.success-value[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n font-weight: 800;\n}\n\n.success-bar-track[_ngcontent-%COMP%] {\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.success-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 3px;\n transition: width 0.5s ease;\n}\n\n.run-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n margin-top: 8px;\n font-size: 0.75rem;\n}\n\n.stat-success[_ngcontent-%COMP%] { color: var(--mj-status-success); font-weight: 600; }\n.stat-failure[_ngcontent-%COMP%] { color: var(--mj-status-error); font-weight: 600; }\n.stat-total[_ngcontent-%COMP%] { color: var(--mj-text-muted); margin-left: auto; }\n\n\n\n.job-card-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding: 12px 20px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n background: var(--mj-bg-surface-sunken);\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n\n\n.slideout-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n animation: _ngcontent-%COMP%_fadeInBackdrop 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeInBackdrop {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.slideout-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: -100%;\n height: 100vh;\n background: var(--mj-bg-surface-card);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slideout-panel.open[_ngcontent-%COMP%] {\n right: 0;\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: rgba(255, 255, 255, 0.95);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n border-radius: 16px;\n backdrop-filter: blur(4px);\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n\n\n.delete-confirm-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: rgba(255, 255, 255, 0.95);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n border-radius: 16px;\n backdrop-filter: blur(4px);\n}\n\n.delete-confirm-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 24px;\n text-align: center;\n}\n\n.delete-warn-icon[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n color: var(--mj-status-error);\n}\n\n.delete-confirm-text[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.delete-confirm-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-top: 4px;\n}\n\n.delete-confirm-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 600;\n transition: background 0.2s;\n}\n\n.delete-confirm-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error-text);\n}\n\n.delete-confirm-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n}\n\n.delete-cancel-btn[_ngcontent-%COMP%] {\n padding: 6px 16px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.delete-cancel-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n\n\n.action-btn-danger[_ngcontent-%COMP%] {\n margin-left: auto;\n color: var(--mj-status-error);\n border-color: var(--mj-status-error-border);\n}\n\n.action-btn-danger[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n color: var(--mj-status-error-text);\n}\n\n\n\n@media (max-width: 1024px) {\n .jobs-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n }\n}\n\n@media (max-width: 768px) {\n .jobs-toolbar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n .toolbar-right[_ngcontent-%COMP%] {\n justify-content: space-between;\n }\n .jobs-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .search-box[_ngcontent-%COMP%] {\n min-width: auto;\n flex: 1;\n }\n}"], changeDetection: 0 });
551
559
  }
552
560
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SchedulingJobsComponent, [{
553
561
  type: Component,
554
- args: [{ standalone: false, selector: 'app-scheduling-jobs', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"jobs-container\">\n <!-- Toolbar -->\n <div class=\"jobs-toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Search jobs...\"\n [value]=\"SearchTerm\"\n (input)=\"OnSearchChange($any($event.target).value)\" />\n </div>\n <select class=\"filter-select\" [value]=\"StatusFilter\" (change)=\"OnStatusFilterChange($any($event.target).value)\">\n <option value=\"\">All Statuses</option>\n @for (s of StatusOptions.slice(1); track s) {\n <option [value]=\"s\">{{s}}</option>\n }\n </select>\n <select class=\"filter-select\" [value]=\"TypeFilter\" (change)=\"OnTypeFilterChange($any($event.target).value)\">\n <option value=\"\">All Types</option>\n @for (t of TypeOptions.slice(1); track t) {\n <option [value]=\"t\">{{t}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <span class=\"result-count\">{{FilteredJobs.length}} of {{Jobs.length}} jobs</span>\n <button class=\"control-btn\" (click)=\"Refresh()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n <button class=\"primary-btn\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> New Job\n </button>\n </div>\n </div>\n\n <!-- Loading -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading jobs...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Empty State -->\n @if (!IsLoading && FilteredJobs.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-calendar-xmark\"></i>\n </div>\n <h3>No jobs found</h3>\n @if (SearchTerm || StatusFilter || TypeFilter) {\n <p>Try adjusting your filters</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <p>Create your first scheduled job to get started</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <button class=\"primary-btn\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> Create Job\n </button>\n }\n </div>\n }\n\n <!-- Job Cards Grid -->\n @if (!IsLoading && FilteredJobs.length > 0) {\n <div class=\"jobs-grid\">\n @for (job of FilteredJobs; track job) {\n <div\n class=\"job-card\"\n (click)=\"OpenEditSlideout(job)\">\n <!-- Card Header -->\n <div class=\"job-card-header\">\n <div class=\"job-card-title\">\n <i [class]=\"GetTypeIcon(job.jobType)\" class=\"type-icon\"></i>\n <span class=\"job-name\">{{job.jobName}}</span>\n </div>\n <span class=\"status-chip\" [ngClass]=\"GetStatusClass(job.status)\">{{job.status}}</span>\n </div>\n <!-- Card Body -->\n <div class=\"job-card-body\">\n @if (job.description) {\n <div class=\"job-description\">{{job.description}}</div>\n }\n <div class=\"job-meta-grid\">\n <div class=\"meta-item\">\n <span class=\"meta-label\">Type</span>\n <span class=\"meta-value\">{{job.jobType}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Schedule</span>\n <span class=\"meta-value mono\">{{job.cronExpression}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Last Run</span>\n <span class=\"meta-value\">{{FormatDate(job.lastRunAt)}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Next Run</span>\n <span class=\"meta-value\">{{FormatDate(job.nextRunAt)}}</span>\n </div>\n </div>\n <!-- Success Rate Bar -->\n <div class=\"success-section\">\n <div class=\"success-header\">\n <span class=\"success-label\">Success Rate</span>\n <span class=\"success-value\" [style.color]=\"GetSuccessRateColor(job.successRate)\">\n {{FormatPercentage(job.successRate)}}\n </span>\n </div>\n <div class=\"success-bar-track\">\n <div class=\"success-bar-fill\"\n [style.width]=\"(job.successRate * 100) + '%'\"\n [style.background]=\"GetSuccessRateColor(job.successRate)\">\n </div>\n </div>\n <div class=\"run-stats\">\n <span class=\"stat-success\"><i class=\"fa-solid fa-check\"></i> {{job.successCount}}</span>\n <span class=\"stat-failure\"><i class=\"fa-solid fa-xmark\"></i> {{job.failureCount}}</span>\n <span class=\"stat-total\">{{job.totalRuns}} total</span>\n </div>\n </div>\n </div>\n <!-- Card Footer -->\n <div class=\"job-card-footer\">\n <button class=\"action-btn\" (click)=\"ToggleJobStatus(job, $event)\">\n <i [class]=\"job.status === 'Active' ? 'fa-solid fa-pause' : 'fa-solid fa-play'\"></i>\n {{job.status === 'Active' ? 'Pause' : 'Resume'}}\n </button>\n <button class=\"action-btn\" (click)=\"OpenEntityRecord(job); $event.stopPropagation()\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n Full Details\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Slideout Panel -->\n @if (SlideoutOpen) {\n <div class=\"slideout-backdrop\" (click)=\"CloseSlideout()\"></div>\n }\n <div class=\"slideout-panel\" [class.open]=\"SlideoutOpen\" [style.width.px]=\"SlideoutWidth\">\n <div class=\"slideout-resize-handle\" (mousedown)=\"OnResizeStart($event)\"></div>\n @if (SlideoutOpen) {\n <app-job-slideout\n [Mode]=\"SlideoutMode\"\n [Job]=\"SelectedJob\"\n (Close)=\"CloseSlideout()\"\n (Saved)=\"OnSlideoutSaved()\">\n </app-job-slideout>\n }\n </div>\n</div>\n", styles: [".jobs-container {\n display: flex;\n flex-direction: column;\n gap: 20px;\n position: relative;\n}\n\n/* \u2500\u2500 Toolbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.jobs-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.toolbar-left {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.toolbar-right {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.search-box {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n min-width: 240px;\n transition: border-color 0.2s;\n}\n\n.search-box:focus-within {\n border-color: #0076b6;\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.1);\n}\n\n.search-box i {\n color: #94a3b8;\n font-size: 0.85rem;\n}\n\n.search-box input {\n border: none;\n outline: none;\n background: transparent;\n font-size: 0.85rem;\n color: #0f172a;\n width: 100%;\n}\n\n.filter-select {\n padding: 8px 14px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n font-size: 0.85rem;\n color: #475569;\n cursor: pointer;\n outline: none;\n transition: border-color 0.2s;\n}\n\n.filter-select:focus {\n border-color: #0076b6;\n}\n\n.result-count {\n font-size: 0.8rem;\n color: #94a3b8;\n white-space: nowrap;\n}\n\n.control-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n color: #475569;\n transition: all 0.2s ease;\n}\n\n.control-btn:hover {\n background: #f3f4f6;\n border-color: #999;\n}\n\n.primary-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 20px;\n background: linear-gradient(135deg, #0076b6 0%, #005a8c 100%);\n color: white;\n border: none;\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 600;\n transition: all 0.2s ease;\n}\n\n.primary-btn:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(0, 118, 182, 0.4);\n}\n\n/* \u2500\u2500 Loading & Empty \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 64px 24px;\n background: white;\n border-radius: 16px;\n border: 2px dashed #dee2e6;\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: #f8f9fa;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 2rem;\n color: #adb5bd;\n}\n\n.empty-state h3 {\n font-size: 1.1rem;\n font-weight: 700;\n color: #334155;\n margin: 0 0 8px;\n}\n\n.empty-state p {\n color: #64748b;\n margin: 0 0 16px;\n font-size: 0.9rem;\n}\n\n/* \u2500\u2500 Job Cards Grid \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.jobs-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));\n gap: 16px;\n}\n\n.job-card {\n background: white;\n border-radius: 16px;\n border: 1px solid #e2e8f0;\n box-shadow: 0 1px 3px rgba(0,0,0,0.05);\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.job-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 25px -5px rgba(0,0,0,0.1);\n border-color: #0076b6;\n}\n\n/* Card Header */\n.job-card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #f1f5f9;\n}\n\n.job-card-title {\n display: flex;\n align-items: center;\n gap: 10px;\n flex: 1;\n min-width: 0;\n}\n\n.type-icon {\n color: #0076b6;\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.job-name {\n font-weight: 700;\n color: #0f172a;\n font-size: 0.9rem;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.3;\n}\n\n.status-chip {\n font-size: 0.7rem;\n font-weight: 700;\n padding: 3px 10px;\n border-radius: 12px;\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n.status-active { background: #dcfce7; color: #166534; }\n.status-paused { background: #fef3c7; color: #92400e; }\n.status-disabled { background: #f1f5f9; color: #64748b; }\n.status-pending { background: #dbeafe; color: #1e40af; }\n.status-expired { background: #fee2e2; color: #991b1b; }\n\n/* Card Body */\n.job-card-body {\n padding: 16px 20px;\n flex: 1;\n}\n\n.job-description {\n font-size: 0.8rem;\n color: #64748b;\n margin-bottom: 12px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n}\n\n.job-meta-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.meta-label {\n font-size: 0.65rem;\n font-weight: 700;\n color: #94a3b8;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.meta-value {\n font-size: 0.8rem;\n color: #334155;\n font-weight: 500;\n}\n\n.meta-value.mono {\n font-family: 'SFMono-Regular', Consolas, monospace;\n font-size: 0.75rem;\n}\n\n/* Success Rate */\n.success-section {\n padding-top: 12px;\n border-top: 1px solid #f1f5f9;\n}\n\n.success-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n\n.success-label {\n font-size: 0.75rem;\n font-weight: 600;\n color: #64748b;\n}\n\n.success-value {\n font-size: 0.85rem;\n font-weight: 800;\n}\n\n.success-bar-track {\n height: 6px;\n background: #f1f5f9;\n border-radius: 3px;\n overflow: hidden;\n}\n\n.success-bar-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.5s ease;\n}\n\n.run-stats {\n display: flex;\n gap: 12px;\n margin-top: 8px;\n font-size: 0.75rem;\n}\n\n.stat-success { color: #10b981; font-weight: 600; }\n.stat-failure { color: #ef4444; font-weight: 600; }\n.stat-total { color: #94a3b8; margin-left: auto; }\n\n/* Card Footer */\n.job-card-footer {\n display: flex;\n gap: 8px;\n padding: 12px 20px;\n border-top: 1px solid #f1f5f9;\n background: #fafbfc;\n}\n\n.action-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.75rem;\n font-weight: 500;\n color: #475569;\n transition: all 0.2s;\n}\n\n.action-btn:hover {\n background: #f3f4f6;\n border-color: #999;\n}\n\n/* \u2500\u2500 Slideout Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.slideout-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 999;\n animation: fadeInBackdrop 0.2s ease;\n}\n\n@keyframes fadeInBackdrop {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.slideout-panel {\n position: fixed;\n top: 0;\n right: -100%;\n height: 100vh;\n background: white;\n box-shadow: -4px 0 20px rgba(0,0,0,0.15);\n z-index: 1000;\n transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slideout-panel.open {\n right: 0;\n}\n\n.slideout-resize-handle {\n position: absolute;\n top: 0;\n left: 0;\n width: 5px;\n height: 100%;\n cursor: col-resize;\n background: transparent;\n z-index: 10;\n transition: background 0.2s;\n}\n\n.slideout-resize-handle:hover {\n background: rgba(0, 118, 182, 0.3);\n}\n\n.slideout-resize-handle:active {\n background: rgba(0, 118, 182, 0.5);\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 .jobs-grid {\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n }\n}\n\n@media (max-width: 768px) {\n .jobs-toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n .toolbar-right {\n justify-content: space-between;\n }\n .jobs-grid {\n grid-template-columns: 1fr;\n }\n .search-box {\n min-width: auto;\n flex: 1;\n }\n .slideout-panel {\n width: 100% !important;\n }\n .slideout-resize-handle {\n display: none;\n }\n}\n"] }]
562
+ args: [{ standalone: false, selector: 'app-scheduling-jobs', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"jobs-container\">\n <!-- Toolbar -->\n <div class=\"jobs-toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Search jobs...\"\n [value]=\"SearchTerm\"\n (input)=\"OnSearchChange($any($event.target).value)\" />\n </div>\n <select class=\"filter-select\" [value]=\"StatusFilter\" (change)=\"OnStatusFilterChange($any($event.target).value)\">\n <option value=\"\">All Statuses</option>\n @for (s of StatusOptions.slice(1); track s) {\n <option [value]=\"s\">{{s}}</option>\n }\n </select>\n <select class=\"filter-select\" [value]=\"TypeFilter\" (change)=\"OnTypeFilterChange($any($event.target).value)\">\n <option value=\"\">All Types</option>\n @for (t of TypeOptions.slice(1); track t) {\n <option [value]=\"t\">{{t}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <span class=\"result-count\">{{FilteredJobs.length}} of {{Jobs.length}} jobs</span>\n <button class=\"control-btn\" (click)=\"Refresh()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n <button class=\"primary-btn\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> New Job\n </button>\n </div>\n </div>\n\n <!-- Loading -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading jobs...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Empty State -->\n @if (!IsLoading && FilteredJobs.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-calendar-xmark\"></i>\n </div>\n <h3>No jobs found</h3>\n @if (SearchTerm || StatusFilter || TypeFilter) {\n <p>Try adjusting your filters</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <p>Create your first scheduled job to get started</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <button class=\"primary-btn\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> Create Job\n </button>\n }\n </div>\n }\n\n <!-- Job Cards Grid -->\n @if (!IsLoading && FilteredJobs.length > 0) {\n <div class=\"jobs-grid\">\n @for (job of FilteredJobs; track job) {\n <div\n class=\"job-card\"\n (click)=\"OpenEditSlideout(job)\">\n <!-- Card Header -->\n <div class=\"job-card-header\">\n <div class=\"job-card-title\">\n <i [class]=\"GetTypeIcon(job.jobType)\" class=\"type-icon\"></i>\n <span class=\"job-name\">{{job.jobName}}</span>\n </div>\n <span class=\"status-chip\" [ngClass]=\"GetStatusClass(job.status)\">{{job.status}}</span>\n </div>\n <!-- Card Body -->\n <div class=\"job-card-body\">\n @if (job.description) {\n <div class=\"job-description\">{{job.description}}</div>\n }\n <div class=\"job-meta-grid\">\n <div class=\"meta-item\">\n <span class=\"meta-label\">Type</span>\n <span class=\"meta-value\">{{job.jobType}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Schedule</span>\n <span class=\"meta-value mono\">{{job.cronExpression}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Last Run</span>\n <span class=\"meta-value\">{{FormatDate(job.lastRunAt)}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Next Run</span>\n <span class=\"meta-value\">{{FormatDate(job.nextRunAt)}}</span>\n </div>\n </div>\n <!-- Success Rate Bar -->\n <div class=\"success-section\">\n <div class=\"success-header\">\n <span class=\"success-label\">Success Rate</span>\n <span class=\"success-value\" [style.color]=\"GetSuccessRateColor(job.successRate)\">\n {{FormatPercentage(job.successRate)}}\n </span>\n </div>\n <div class=\"success-bar-track\">\n <div class=\"success-bar-fill\"\n [style.width]=\"(job.successRate * 100) + '%'\"\n [style.background]=\"GetSuccessRateColor(job.successRate)\">\n </div>\n </div>\n <div class=\"run-stats\">\n <span class=\"stat-success\"><i class=\"fa-solid fa-check\"></i> {{job.successCount}}</span>\n <span class=\"stat-failure\"><i class=\"fa-solid fa-xmark\"></i> {{job.failureCount}}</span>\n <span class=\"stat-total\">{{job.totalRuns}} total</span>\n </div>\n </div>\n </div>\n <!-- Delete confirmation overlay -->\n @if (IsDeleteConfirming(job.jobId)) {\n <div class=\"delete-confirm-overlay\" (click)=\"$event.stopPropagation()\">\n <div class=\"delete-confirm-content\">\n <i class=\"fa-solid fa-triangle-exclamation delete-warn-icon\"></i>\n <span class=\"delete-confirm-text\">Delete this scheduled job?</span>\n <div class=\"delete-confirm-actions\">\n <button class=\"delete-confirm-btn\" [disabled]=\"IsDeleting\" (click)=\"ConfirmDelete(job.jobId, $event)\">\n @if (IsDeleting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Deleting...\n } @else {\n Delete\n }\n </button>\n <button class=\"delete-cancel-btn\" (click)=\"CancelDelete($event)\">Cancel</button>\n </div>\n </div>\n </div>\n }\n <!-- Card Footer -->\n <div class=\"job-card-footer\">\n <button class=\"action-btn\" (click)=\"ToggleJobStatus(job, $event)\">\n <i [class]=\"job.status === 'Active' ? 'fa-solid fa-pause' : 'fa-solid fa-play'\"></i>\n {{job.status === 'Active' ? 'Pause' : 'Resume'}}\n </button>\n <button class=\"action-btn\" (click)=\"OpenEntityRecord(job); $event.stopPropagation()\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n Full Details\n </button>\n <button class=\"action-btn action-btn-danger\" (click)=\"ShowDeleteConfirm(job, $event)\">\n <i class=\"fa-solid fa-trash-can\"></i>\n Delete\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Slideout Panel -->\n <mj-scheduled-job-slide-panel\n [IsOpen]=\"SlideoutOpen\"\n [ScheduledJobID]=\"SelectedJob?.jobId ?? null\"\n (Close)=\"CloseSlideout()\"\n (Saved)=\"OnSlideoutSaved()\"\n (Deleted)=\"OnSlideoutSaved()\">\n </mj-scheduled-job-slide-panel>\n</div>\n", styles: [".jobs-container {\n display: flex;\n flex-direction: column;\n gap: 20px;\n position: relative;\n}\n\n/* \u2500\u2500 Toolbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.jobs-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.toolbar-left {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.toolbar-right {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.search-box {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n min-width: 240px;\n transition: border-color 0.2s;\n}\n\n.search-box:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.search-box i {\n color: var(--mj-text-muted);\n font-size: 0.85rem;\n}\n\n.search-box input {\n border: none;\n outline: none;\n background: transparent;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n width: 100%;\n}\n\n.filter-select {\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n cursor: pointer;\n outline: none;\n transition: border-color 0.2s;\n}\n\n.filter-select:focus {\n border-color: var(--mj-brand-primary);\n}\n\n.result-count {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.control-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\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.primary-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 600;\n transition: all 0.2s ease;\n}\n\n.primary-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n/* \u2500\u2500 Loading & Empty \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 64px 24px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 2rem;\n color: var(--mj-text-muted);\n}\n\n.empty-state h3 {\n font-size: 1.1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px;\n}\n\n.empty-state p {\n color: var(--mj-text-secondary);\n margin: 0 0 16px;\n font-size: 0.9rem;\n}\n\n/* \u2500\u2500 Job Cards Grid \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.jobs-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));\n gap: 16px;\n}\n\n.job-card {\n position: relative;\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 cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.job-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--mj-shadow-lg);\n border-color: var(--mj-brand-primary);\n}\n\n/* Card Header */\n.job-card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.job-card-title {\n display: flex;\n align-items: center;\n gap: 10px;\n flex: 1;\n min-width: 0;\n}\n\n.type-icon {\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.job-name {\n font-weight: 700;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.3;\n}\n\n.status-chip {\n font-size: 0.7rem;\n font-weight: 700;\n padding: 3px 10px;\n border-radius: 12px;\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n.status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-paused { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-disabled { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.status-pending { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-expired { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n/* Card Body */\n.job-card-body {\n padding: 16px 20px;\n flex: 1;\n}\n\n.job-description {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n}\n\n.job-meta-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.meta-label {\n font-size: 0.65rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.meta-value {\n font-size: 0.8rem;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.meta-value.mono {\n font-family: 'SFMono-Regular', Consolas, monospace;\n font-size: 0.75rem;\n}\n\n/* Success Rate */\n.success-section {\n padding-top: 12px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.success-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n\n.success-label {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.success-value {\n font-size: 0.85rem;\n font-weight: 800;\n}\n\n.success-bar-track {\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.success-bar-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.5s ease;\n}\n\n.run-stats {\n display: flex;\n gap: 12px;\n margin-top: 8px;\n font-size: 0.75rem;\n}\n\n.stat-success { color: var(--mj-status-success); font-weight: 600; }\n.stat-failure { color: var(--mj-status-error); font-weight: 600; }\n.stat-total { color: var(--mj-text-muted); margin-left: auto; }\n\n/* Card Footer */\n.job-card-footer {\n display: flex;\n gap: 8px;\n padding: 12px 20px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n background: var(--mj-bg-surface-sunken);\n}\n\n.action-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s;\n}\n\n.action-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n/* \u2500\u2500 Slideout Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.slideout-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n animation: fadeInBackdrop 0.2s ease;\n}\n\n@keyframes fadeInBackdrop {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.slideout-panel {\n position: fixed;\n top: 0;\n right: -100%;\n height: 100vh;\n background: var(--mj-bg-surface-card);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slideout-panel.open {\n right: 0;\n}\n\n.slideout-resize-handle {\n position: absolute;\n inset: 0;\n background: rgba(255, 255, 255, 0.95);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n border-radius: 16px;\n backdrop-filter: blur(4px);\n}\n\n.slideout-resize-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.slideout-resize-handle:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n/* \u2500\u2500 Delete Confirmation Overlay \u2500\u2500\u2500\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.delete-confirm-overlay {\n position: absolute;\n inset: 0;\n background: rgba(255, 255, 255, 0.95);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n border-radius: 16px;\n backdrop-filter: blur(4px);\n}\n\n.delete-confirm-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 24px;\n text-align: center;\n}\n\n.delete-warn-icon {\n font-size: 1.5rem;\n color: var(--mj-status-error);\n}\n\n.delete-confirm-text {\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.delete-confirm-actions {\n display: flex;\n gap: 8px;\n margin-top: 4px;\n}\n\n.delete-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 600;\n transition: background 0.2s;\n}\n\n.delete-confirm-btn:hover:not(:disabled) {\n background: var(--mj-status-error-text);\n}\n\n.delete-confirm-btn:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n}\n\n.delete-cancel-btn {\n padding: 6px 16px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.delete-cancel-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n/* \u2500\u2500 Danger Action Button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.action-btn-danger {\n margin-left: auto;\n color: var(--mj-status-error);\n border-color: var(--mj-status-error-border);\n}\n\n.action-btn-danger:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n color: var(--mj-status-error-text);\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 .jobs-grid {\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n }\n}\n\n@media (max-width: 768px) {\n .jobs-toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n .toolbar-right {\n justify-content: space-between;\n }\n .jobs-grid {\n grid-template-columns: 1fr;\n }\n .search-box {\n min-width: auto;\n flex: 1;\n }\n}\n"] }]
555
563
  }], () => [{ type: i1.SchedulingInstrumentationService }, { type: i0.ChangeDetectorRef }], { initialState: [{
556
564
  type: Input
557
565
  }], stateChange: [{