@memberjunction/ng-dashboards 5.22.0 → 5.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/README.md +51 -0
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js +364 -362
  4. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  5. package/dist/AI/components/agents/agent-editor.component.js +2 -2
  6. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +947 -64
  7. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  8. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +7645 -430
  9. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  10. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +285 -6
  11. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  12. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +2454 -277
  13. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  14. package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
  15. package/dist/AI/components/execution-monitoring.component.js +191 -197
  16. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  17. package/dist/AI/components/models/model-management.component.js +9 -8
  18. package/dist/AI/components/models/model-management.component.js.map +1 -1
  19. package/dist/AI/components/prompts/prompt-management.component.js +305 -299
  20. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  21. package/dist/AI/components/system/system-configuration.component.js +319 -313
  22. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  23. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +20 -2
  24. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  25. package/dist/AI/components/vectors/vector-management-resource.component.js +419 -232
  26. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  27. package/dist/APIKeys/api-applications-panel.component.js +10 -12
  28. package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
  29. package/dist/APIKeys/api-key-create-dialog.component.js +13 -19
  30. package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
  31. package/dist/APIKeys/api-key-edit-panel.component.js +12 -14
  32. package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
  33. package/dist/APIKeys/api-scopes-panel.component.js +61 -68
  34. package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
  35. package/dist/APIKeys/api-usage-panel.component.js +10 -11
  36. package/dist/APIKeys/api-usage-panel.component.js.map +1 -1
  37. package/dist/Actions/components/actions-list-view.component.js +82 -96
  38. package/dist/Actions/components/actions-list-view.component.js.map +1 -1
  39. package/dist/Actions/components/actions-overview.component.js +130 -134
  40. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  41. package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
  42. package/dist/Actions/components/categories-list-view.component.js +40 -46
  43. package/dist/Actions/components/categories-list-view.component.js.map +1 -1
  44. package/dist/Actions/components/code-management.component.js +2 -2
  45. package/dist/Actions/components/code-management.component.js.map +1 -1
  46. package/dist/Actions/components/entity-integration.component.js +2 -2
  47. package/dist/Actions/components/entity-integration.component.js.map +1 -1
  48. package/dist/Actions/components/execution-monitoring.component.js +127 -132
  49. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  50. package/dist/Actions/components/executions-list-view.component.js +2 -2
  51. package/dist/Actions/components/executions-list-view.component.js.map +1 -1
  52. package/dist/Actions/components/explorer/action-card.component.js +11 -17
  53. package/dist/Actions/components/explorer/action-card.component.js.map +1 -1
  54. package/dist/Actions/components/explorer/action-explorer.component.js +5 -11
  55. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  56. package/dist/Actions/components/explorer/action-list-item.component.js +8 -10
  57. package/dist/Actions/components/explorer/action-list-item.component.js.map +1 -1
  58. package/dist/Actions/components/explorer/action-toolbar.component.js +112 -133
  59. package/dist/Actions/components/explorer/action-toolbar.component.js.map +1 -1
  60. package/dist/Actions/components/explorer/action-tree-panel.component.js +63 -83
  61. package/dist/Actions/components/explorer/action-tree-panel.component.js.map +1 -1
  62. package/dist/Actions/components/explorer/new-action-panel.component.js +17 -21
  63. package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
  64. package/dist/Actions/components/explorer/new-category-panel.component.js +17 -21
  65. package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
  66. package/dist/Actions/components/scheduled-actions.component.js +2 -2
  67. package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
  68. package/dist/Actions/components/security-permissions.component.js +2 -2
  69. package/dist/Actions/components/security-permissions.component.js.map +1 -1
  70. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +13 -5
  71. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  72. package/dist/ComponentStudio/component-studio-dashboard.component.js +168 -145
  73. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  74. package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts +4 -5
  75. package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
  76. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +197 -200
  77. package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
  78. package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts +5 -7
  79. package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
  80. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +142 -148
  81. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
  82. package/dist/ComponentStudio/components/browser/component-browser.component.js +153 -166
  83. package/dist/ComponentStudio/components/browser/component-browser.component.js.map +1 -1
  84. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +15 -20
  85. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
  86. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +16 -21
  87. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
  88. package/dist/ComponentStudio/components/editors/requirements-editor.component.js +18 -23
  89. package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
  90. package/dist/ComponentStudio/components/editors/spec-editor.component.js +25 -30
  91. package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
  92. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +10 -11
  93. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js.map +1 -1
  94. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.d.ts.map +1 -1
  95. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +24 -35
  96. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
  97. package/dist/ComponentStudio/components/text-import-dialog.component.js +15 -17
  98. package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
  99. package/dist/Credentials/components/credentials-categories-resource.component.js +7 -6
  100. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  101. package/dist/Credentials/components/credentials-list-resource.component.js +6 -5
  102. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  103. package/dist/Credentials/components/credentials-types-resource.component.js +7 -6
  104. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  105. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +9 -9
  106. package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
  107. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  108. package/dist/DataExplorer/data-explorer-dashboard.component.js +17 -17
  109. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  110. package/dist/Home/home-dashboard.component.js +4 -4
  111. package/dist/Home/home-dashboard.component.js.map +1 -1
  112. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  113. package/dist/Integration/components/activity/activity.component.js +1 -0
  114. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  115. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  116. package/dist/Integration/components/connections/connections.component.js +5 -4
  117. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  118. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
  119. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +247 -259
  120. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  121. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  122. package/dist/Integration/components/overview/overview.component.js +1 -0
  123. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  124. package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
  125. package/dist/Integration/components/pipelines/pipelines.component.js +1 -0
  126. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  127. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  128. package/dist/Integration/components/schedules/schedules.component.js +1 -0
  129. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  130. package/dist/Integration/components/widgets/integration-card.component.js +7 -9
  131. package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
  132. package/dist/Integration/integration.module.d.ts +6 -10
  133. package/dist/Integration/integration.module.d.ts.map +1 -1
  134. package/dist/Integration/integration.module.js +12 -20
  135. package/dist/Integration/integration.module.js.map +1 -1
  136. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +411 -0
  137. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -0
  138. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +4266 -0
  139. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -0
  140. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +140 -0
  141. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -0
  142. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +780 -0
  143. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -0
  144. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +8 -2
  145. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
  146. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +246 -195
  147. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  148. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +75 -0
  149. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -0
  150. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +601 -0
  151. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -0
  152. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +93 -12
  153. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +1 -1
  154. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +637 -107
  155. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +1 -1
  156. package/dist/KnowledgeHub/index.d.ts +3 -0
  157. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  158. package/dist/KnowledgeHub/index.js +3 -0
  159. package/dist/KnowledgeHub/index.js.map +1 -1
  160. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  161. package/dist/Lists/components/lists-browse-resource.component.js +9 -7
  162. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  163. package/dist/Lists/components/lists-my-lists-resource.component.js +5 -4
  164. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  165. package/dist/Lists/components/lists-operations-resource.component.js +10 -9
  166. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  167. package/dist/MCP/components/mcp-connection-dialog.component.js +141 -132
  168. package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
  169. package/dist/MCP/components/mcp-log-detail-panel.component.js +4 -4
  170. package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
  171. package/dist/MCP/components/mcp-server-dialog.component.js +141 -128
  172. package/dist/MCP/components/mcp-server-dialog.component.js.map +1 -1
  173. package/dist/MCP/components/mcp-test-tool-dialog.component.js +210 -218
  174. package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
  175. package/dist/MCP/mcp-dashboard.component.js +2 -2
  176. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  177. package/dist/MCP/mcp.module.d.ts +6 -9
  178. package/dist/MCP/mcp.module.d.ts.map +1 -1
  179. package/dist/MCP/mcp.module.js +20 -22
  180. package/dist/MCP/mcp.module.js.map +1 -1
  181. package/dist/Scheduling/components/scheduling-activity.component.js +5 -4
  182. package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
  183. package/dist/Scheduling/components/scheduling-jobs.component.js +6 -5
  184. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  185. package/dist/Scheduling/components/scheduling-overview.component.js +93 -92
  186. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  187. package/dist/Testing/testing-dashboard.component.js +9 -10
  188. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  189. package/dist/__tests__/analytics-resource.test.d.ts +2 -0
  190. package/dist/__tests__/analytics-resource.test.d.ts.map +1 -0
  191. package/dist/__tests__/analytics-resource.test.js +181 -0
  192. package/dist/__tests__/analytics-resource.test.js.map +1 -0
  193. package/dist/__tests__/scheduling.test.d.ts +2 -0
  194. package/dist/__tests__/scheduling.test.d.ts.map +1 -0
  195. package/dist/__tests__/scheduling.test.js +205 -0
  196. package/dist/__tests__/scheduling.test.js.map +1 -0
  197. package/dist/actions-dashboards.module.d.ts +8 -13
  198. package/dist/actions-dashboards.module.d.ts.map +1 -1
  199. package/dist/actions-dashboards.module.js +6 -27
  200. package/dist/actions-dashboards.module.js.map +1 -1
  201. package/dist/ai-dashboards.module.d.ts +20 -20
  202. package/dist/ai-dashboards.module.d.ts.map +1 -1
  203. package/dist/ai-dashboards.module.js +43 -44
  204. package/dist/ai-dashboards.module.js.map +1 -1
  205. package/dist/communication-dashboards.module.d.ts +4 -8
  206. package/dist/communication-dashboards.module.d.ts.map +1 -1
  207. package/dist/communication-dashboards.module.js +0 -19
  208. package/dist/communication-dashboards.module.js.map +1 -1
  209. package/dist/component-studio-dashboards.module.d.ts +7 -11
  210. package/dist/component-studio-dashboards.module.d.ts.map +1 -1
  211. package/dist/component-studio-dashboards.module.js +22 -34
  212. package/dist/component-studio-dashboards.module.js.map +1 -1
  213. package/dist/core-dashboards.module.d.ts +12 -18
  214. package/dist/core-dashboards.module.d.ts.map +1 -1
  215. package/dist/core-dashboards.module.js +15 -31
  216. package/dist/core-dashboards.module.js.map +1 -1
  217. package/dist/credentials-dashboards.module.d.ts +5 -8
  218. package/dist/credentials-dashboards.module.d.ts.map +1 -1
  219. package/dist/credentials-dashboards.module.js +3 -19
  220. package/dist/credentials-dashboards.module.js.map +1 -1
  221. package/dist/data-explorer-dashboards.module.d.ts +7 -13
  222. package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
  223. package/dist/data-explorer-dashboards.module.js +0 -27
  224. package/dist/data-explorer-dashboards.module.js.map +1 -1
  225. package/dist/lists-dashboards.module.d.ts +5 -8
  226. package/dist/lists-dashboards.module.d.ts.map +1 -1
  227. package/dist/lists-dashboards.module.js +3 -19
  228. package/dist/lists-dashboards.module.js.map +1 -1
  229. package/dist/public-api.d.ts +2 -0
  230. package/dist/public-api.d.ts.map +1 -1
  231. package/dist/public-api.js +2 -0
  232. package/dist/public-api.js.map +1 -1
  233. package/dist/scheduling-dashboards.module.d.ts +6 -10
  234. package/dist/scheduling-dashboards.module.d.ts.map +1 -1
  235. package/dist/scheduling-dashboards.module.js +3 -23
  236. package/dist/scheduling-dashboards.module.js.map +1 -1
  237. package/dist/shared/entity-field-display.d.ts +44 -0
  238. package/dist/shared/entity-field-display.d.ts.map +1 -0
  239. package/dist/shared/entity-field-display.js +118 -0
  240. package/dist/shared/entity-field-display.js.map +1 -0
  241. package/dist/testing-dashboards.module.d.ts +7 -13
  242. package/dist/testing-dashboards.module.d.ts.map +1 -1
  243. package/dist/testing-dashboards.module.js +0 -27
  244. package/dist/testing-dashboards.module.js.map +1 -1
  245. package/package.json +48 -55
@@ -0,0 +1,601 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ /**
8
+ * @fileoverview Knowledge Hub Scheduled Pipelines Dashboard Tab
9
+ *
10
+ * Full-page resource component for managing scheduled pipelines within the
11
+ * Knowledge Hub application. Displays job cards in a compact grid, recent
12
+ * activity table, and provides create/edit via the reusable
13
+ * ScheduledJobDialogComponent from @memberjunction/ng-scheduling.
14
+ *
15
+ * Registered as BaseResourceComponent for the Knowledge Hub application.
16
+ */
17
+ import { Component, ChangeDetectorRef, inject } from '@angular/core';
18
+ import { Subject } from 'rxjs';
19
+ import { Metadata, RunView } from '@memberjunction/core';
20
+ import { RegisterClass } from '@memberjunction/global';
21
+ import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
22
+ import { MJNotificationService } from '@memberjunction/ng-notifications';
23
+ import { ScheduledJobService } from '@memberjunction/ng-scheduling';
24
+ import * as i0 from "@angular/core";
25
+ import * as i1 from "@angular/forms";
26
+ import * as i2 from "@memberjunction/ng-shared-generic";
27
+ import * as i3 from "@memberjunction/ng-scheduling";
28
+ const _forTrack0 = ($index, $item) => $item.ID;
29
+ function SchedulingResourceComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
30
+ i0.ɵɵelementStart(0, "div", 0);
31
+ i0.ɵɵelement(1, "mj-loading", 1);
32
+ i0.ɵɵelementEnd();
33
+ } }
34
+ function SchedulingResourceComponent_Conditional_1_Conditional_18_Template(rf, ctx) { if (rf & 1) {
35
+ i0.ɵɵelementStart(0, "strong");
36
+ i0.ɵɵtext(1);
37
+ i0.ɵɵelementEnd();
38
+ i0.ɵɵtext(2, " active ");
39
+ } if (rf & 2) {
40
+ const ctx_r1 = i0.ɵɵnextContext(2);
41
+ i0.ɵɵadvance();
42
+ i0.ɵɵtextInterpolate(ctx_r1.ActiveCount);
43
+ } }
44
+ function SchedulingResourceComponent_Conditional_1_Conditional_19_Template(rf, ctx) { if (rf & 1) {
45
+ i0.ɵɵtext(0, " \u00B7 ");
46
+ i0.ɵɵelementStart(1, "strong");
47
+ i0.ɵɵtext(2);
48
+ i0.ɵɵelementEnd();
49
+ i0.ɵɵtext(3, " paused ");
50
+ } if (rf & 2) {
51
+ const ctx_r1 = i0.ɵɵnextContext(2);
52
+ i0.ɵɵadvance(2);
53
+ i0.ɵɵtextInterpolate(ctx_r1.PausedCount);
54
+ } }
55
+ function SchedulingResourceComponent_Conditional_1_Conditional_20_For_2_For_11_Template(rf, ctx) { if (rf & 1) {
56
+ i0.ɵɵelement(0, "span", 36);
57
+ } if (rf & 2) {
58
+ const dotClass_r5 = ctx.$implicit;
59
+ i0.ɵɵclassMap(dotClass_r5);
60
+ } }
61
+ function SchedulingResourceComponent_Conditional_1_Conditional_20_For_2_Template(rf, ctx) { if (rf & 1) {
62
+ const _r3 = i0.ɵɵgetCurrentView();
63
+ i0.ɵɵelementStart(0, "div", 22);
64
+ i0.ɵɵlistener("click", function SchedulingResourceComponent_Conditional_1_Conditional_20_For_2_Template_div_click_0_listener() { const job_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnEditJob(job_r4)); });
65
+ i0.ɵɵelementStart(1, "div", 23);
66
+ i0.ɵɵelement(2, "span", 24);
67
+ i0.ɵɵelementStart(3, "div", 25)(4, "div", 26);
68
+ i0.ɵɵtext(5);
69
+ i0.ɵɵelementEnd();
70
+ i0.ɵɵelementStart(6, "div", 27);
71
+ i0.ɵɵelement(7, "i", 28);
72
+ i0.ɵɵtext(8);
73
+ i0.ɵɵelementEnd()()();
74
+ i0.ɵɵelementStart(9, "div", 29);
75
+ i0.ɵɵrepeaterCreate(10, SchedulingResourceComponent_Conditional_1_Conditional_20_For_2_For_11_Template, 1, 2, "span", 30, i0.ɵɵrepeaterTrackByIndex);
76
+ i0.ɵɵelementStart(12, "span", 31);
77
+ i0.ɵɵtext(13, "last 7 runs");
78
+ i0.ɵɵelementEnd()();
79
+ i0.ɵɵelementStart(14, "div", 32)(15, "span", 33);
80
+ i0.ɵɵelement(16, "i", 28);
81
+ i0.ɵɵtext(17, " Last: ");
82
+ i0.ɵɵelementStart(18, "strong");
83
+ i0.ɵɵtext(19);
84
+ i0.ɵɵelementEnd()();
85
+ i0.ɵɵelementStart(20, "span", 33);
86
+ i0.ɵɵelement(21, "i", 34);
87
+ i0.ɵɵelementStart(22, "strong");
88
+ i0.ɵɵtext(23);
89
+ i0.ɵɵelementEnd()();
90
+ i0.ɵɵelementStart(24, "span", 33);
91
+ i0.ɵɵelement(25, "i", 35);
92
+ i0.ɵɵtext(26, " Next: ");
93
+ i0.ɵɵelementStart(27, "strong");
94
+ i0.ɵɵtext(28);
95
+ i0.ɵɵelementEnd()()()();
96
+ } if (rf & 2) {
97
+ const job_r4 = ctx.$implicit;
98
+ const ctx_r1 = i0.ɵɵnextContext(3);
99
+ i0.ɵɵclassProp("paused", job_r4.Status === "Paused")("disabled", job_r4.Status === "Disabled");
100
+ i0.ɵɵadvance(2);
101
+ i0.ɵɵclassProp("dot-active", job_r4.Status === "Active")("dot-paused", job_r4.Status === "Paused")("dot-disabled", job_r4.Status === "Disabled");
102
+ i0.ɵɵadvance(3);
103
+ i0.ɵɵtextInterpolate(job_r4.Name);
104
+ i0.ɵɵadvance(3);
105
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.GetCronDescription(job_r4.CronExpression), " ");
106
+ i0.ɵɵadvance(2);
107
+ i0.ɵɵrepeater(ctx_r1.GetSparkline(job_r4.ID));
108
+ i0.ɵɵadvance(9);
109
+ i0.ɵɵtextInterpolate(ctx_r1.GetTimeAgo(job_r4.LastRunAt));
110
+ i0.ɵɵadvance(4);
111
+ i0.ɵɵtextInterpolate(ctx_r1.GetSuccessRate(job_r4));
112
+ i0.ɵɵadvance(5);
113
+ i0.ɵɵtextInterpolate(ctx_r1.GetTimeUntil(job_r4.NextRunAt));
114
+ } }
115
+ function SchedulingResourceComponent_Conditional_1_Conditional_20_Template(rf, ctx) { if (rf & 1) {
116
+ i0.ɵɵelementStart(0, "div", 14);
117
+ i0.ɵɵrepeaterCreate(1, SchedulingResourceComponent_Conditional_1_Conditional_20_For_2_Template, 29, 15, "div", 21, _forTrack0);
118
+ i0.ɵɵelementEnd();
119
+ } if (rf & 2) {
120
+ const ctx_r1 = i0.ɵɵnextContext(2);
121
+ i0.ɵɵadvance();
122
+ i0.ɵɵrepeater(ctx_r1.FilteredJobs);
123
+ } }
124
+ function SchedulingResourceComponent_Conditional_1_Conditional_21_Template(rf, ctx) { if (rf & 1) {
125
+ i0.ɵɵelementStart(0, "div", 15);
126
+ i0.ɵɵelement(1, "i", 37);
127
+ i0.ɵɵelementStart(2, "p");
128
+ i0.ɵɵtext(3, "No Knowledge Hub schedules found");
129
+ i0.ɵɵelementEnd();
130
+ i0.ɵɵelementStart(4, "span");
131
+ i0.ɵɵtext(5, "Create a new schedule to automate classification and vector sync");
132
+ i0.ɵɵelementEnd()();
133
+ } }
134
+ function SchedulingResourceComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
135
+ const _r1 = i0.ɵɵgetCurrentView();
136
+ i0.ɵɵelementStart(0, "div", 2)(1, "button", 3);
137
+ i0.ɵɵlistener("click", function SchedulingResourceComponent_Conditional_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNewSchedule()); });
138
+ i0.ɵɵelement(2, "i", 4);
139
+ i0.ɵɵtext(3, " New Schedule ");
140
+ i0.ɵɵelementEnd();
141
+ i0.ɵɵelementStart(4, "select", 5);
142
+ i0.ɵɵtwoWayListener("ngModelChange", function SchedulingResourceComponent_Conditional_1_Template_select_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.StatusFilter, $event) || (ctx_r1.StatusFilter = $event); return i0.ɵɵresetView($event); });
143
+ i0.ɵɵlistener("ngModelChange", function SchedulingResourceComponent_Conditional_1_Template_select_ngModelChange_4_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnFilterChanged()); });
144
+ i0.ɵɵelementStart(5, "option", 6);
145
+ i0.ɵɵtext(6, "All Statuses");
146
+ i0.ɵɵelementEnd();
147
+ i0.ɵɵelementStart(7, "option", 7);
148
+ i0.ɵɵtext(8, "Active");
149
+ i0.ɵɵelementEnd();
150
+ i0.ɵɵelementStart(9, "option", 8);
151
+ i0.ɵɵtext(10, "Paused");
152
+ i0.ɵɵelementEnd();
153
+ i0.ɵɵelementStart(11, "option", 9);
154
+ i0.ɵɵtext(12, "Disabled");
155
+ i0.ɵɵelementEnd();
156
+ i0.ɵɵelementStart(13, "option", 10);
157
+ i0.ɵɵtext(14, "Pending");
158
+ i0.ɵɵelementEnd()();
159
+ i0.ɵɵelementStart(15, "input", 11);
160
+ i0.ɵɵtwoWayListener("ngModelChange", function SchedulingResourceComponent_Conditional_1_Template_input_ngModelChange_15_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.SearchQuery, $event) || (ctx_r1.SearchQuery = $event); return i0.ɵɵresetView($event); });
161
+ i0.ɵɵlistener("ngModelChange", function SchedulingResourceComponent_Conditional_1_Template_input_ngModelChange_15_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSearchChanged()); });
162
+ i0.ɵɵelementEnd();
163
+ i0.ɵɵelement(16, "div", 12);
164
+ i0.ɵɵelementStart(17, "span", 13);
165
+ i0.ɵɵconditionalCreate(18, SchedulingResourceComponent_Conditional_1_Conditional_18_Template, 3, 1);
166
+ i0.ɵɵconditionalCreate(19, SchedulingResourceComponent_Conditional_1_Conditional_19_Template, 4, 1);
167
+ i0.ɵɵelementEnd()();
168
+ i0.ɵɵconditionalCreate(20, SchedulingResourceComponent_Conditional_1_Conditional_20_Template, 3, 0, "div", 14)(21, SchedulingResourceComponent_Conditional_1_Conditional_21_Template, 6, 0, "div", 15);
169
+ i0.ɵɵelementStart(22, "div", 16)(23, "button", 17);
170
+ i0.ɵɵlistener("click", function SchedulingResourceComponent_Conditional_1_Template_button_click_23_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.GoToSchedulingApp()); });
171
+ i0.ɵɵelement(24, "i", 18);
172
+ i0.ɵɵtext(25, " Open Scheduling App ");
173
+ i0.ɵɵelementEnd();
174
+ i0.ɵɵelementStart(26, "span", 19);
175
+ i0.ɵɵtext(27, "Manage all scheduled jobs across the system");
176
+ i0.ɵɵelementEnd()();
177
+ i0.ɵɵelementStart(28, "mj-scheduled-job-dialog", 20);
178
+ i0.ɵɵlistener("Close", function SchedulingResourceComponent_Conditional_1_Template_mj_scheduled_job_dialog_Close_28_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDialogClosed($event)); });
179
+ i0.ɵɵelementEnd();
180
+ } if (rf & 2) {
181
+ const ctx_r1 = i0.ɵɵnextContext();
182
+ i0.ɵɵadvance(4);
183
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.StatusFilter);
184
+ i0.ɵɵadvance(11);
185
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SearchQuery);
186
+ i0.ɵɵadvance(3);
187
+ i0.ɵɵconditional(ctx_r1.ActiveCount > 0 ? 18 : -1);
188
+ i0.ɵɵadvance();
189
+ i0.ɵɵconditional(ctx_r1.PausedCount > 0 ? 19 : -1);
190
+ i0.ɵɵadvance();
191
+ i0.ɵɵconditional(ctx_r1.FilteredJobs.length > 0 ? 20 : 21);
192
+ i0.ɵɵadvance(8);
193
+ i0.ɵɵproperty("Visible", ctx_r1.ShowEditDialog)("ScheduledJobID", ctx_r1.EditingJobID);
194
+ } }
195
+ let SchedulingResourceComponent = class SchedulingResourceComponent extends BaseResourceComponent {
196
+ cdr = inject(ChangeDetectorRef);
197
+ navigationService = inject(NavigationService);
198
+ scheduledJobService = inject(ScheduledJobService);
199
+ destroy$ = new Subject();
200
+ // ================================================================
201
+ // Resource overrides
202
+ // ================================================================
203
+ async GetResourceDisplayName(_data) {
204
+ return 'Schedules';
205
+ }
206
+ async GetResourceIconClass(_data) {
207
+ return 'fa-solid fa-clock';
208
+ }
209
+ // ================================================================
210
+ // State
211
+ // ================================================================
212
+ IsLoading = true;
213
+ AllJobs = [];
214
+ FilteredJobs = [];
215
+ RecentRuns = [];
216
+ StatusFilter = '';
217
+ SearchQuery = '';
218
+ /** Map of jobID -> last 7 run statuses for sparkline display */
219
+ sparklineCache = new Map();
220
+ // Edit dialog
221
+ ShowEditDialog = false;
222
+ EditingJobID = null;
223
+ // ================================================================
224
+ // Computed
225
+ // ================================================================
226
+ get ActiveCount() {
227
+ return this.AllJobs.filter(j => j.Status === 'Active').length;
228
+ }
229
+ get PausedCount() {
230
+ return this.AllJobs.filter(j => j.Status === 'Paused').length;
231
+ }
232
+ get DisabledCount() {
233
+ return this.AllJobs.filter(j => j.Status === 'Disabled').length;
234
+ }
235
+ // ================================================================
236
+ // Lifecycle
237
+ // ================================================================
238
+ async ngAfterViewInit() {
239
+ await this.loadData();
240
+ this.NotifyLoadComplete();
241
+ }
242
+ ngOnDestroy() {
243
+ this.destroy$.next();
244
+ this.destroy$.complete();
245
+ }
246
+ // ================================================================
247
+ // Public Methods — Toolbar
248
+ // ================================================================
249
+ OnNewSchedule() {
250
+ this.EditingJobID = null;
251
+ this.ShowEditDialog = true;
252
+ this.cdr.detectChanges();
253
+ }
254
+ OnFilterChanged() {
255
+ this.applyFilters();
256
+ this.cdr.detectChanges();
257
+ }
258
+ OnSearchChanged() {
259
+ this.applyFilters();
260
+ this.cdr.detectChanges();
261
+ }
262
+ // ================================================================
263
+ // Public Methods — Card Actions
264
+ // ================================================================
265
+ OnEditJob(job) {
266
+ this.EditingJobID = job.ID;
267
+ this.ShowEditDialog = true;
268
+ this.cdr.detectChanges();
269
+ }
270
+ async OnRunNow(job) {
271
+ MJNotificationService.Instance.CreateSimpleNotification(`Triggering "${job.Name}" — this feature requires server-side support.`, 'info', 4000);
272
+ }
273
+ // ================================================================
274
+ // Public Methods — Dialog
275
+ // ================================================================
276
+ async OnDialogClosed(result) {
277
+ this.ShowEditDialog = false;
278
+ this.EditingJobID = null;
279
+ if (result.Saved || result.Deleted) {
280
+ await this.loadData();
281
+ }
282
+ this.cdr.detectChanges();
283
+ }
284
+ /** Navigate to the full Scheduling application */
285
+ GoToSchedulingApp() {
286
+ const md = new Metadata();
287
+ const schedulingApp = md.Applications.find(a => a.Name === 'Scheduling');
288
+ if (schedulingApp) {
289
+ this.navigationService.SwitchToApp(schedulingApp.ID);
290
+ }
291
+ else {
292
+ MJNotificationService.Instance.CreateSimpleNotification('Scheduling app not found. Check application configuration.', 'warning', 3000);
293
+ }
294
+ }
295
+ // ================================================================
296
+ // Public Methods — Card Display Helpers
297
+ // ================================================================
298
+ GetStatusDotClass(job) {
299
+ return (job.Status ?? 'pending').toLowerCase();
300
+ }
301
+ GetCronDescription(cron) {
302
+ if (!cron)
303
+ return 'No schedule';
304
+ const parts = this.parseCron(cron);
305
+ if (!parts)
306
+ return cron;
307
+ return this.cronToHuman(parts);
308
+ }
309
+ GetSparkline(jobID) {
310
+ return this.sparklineCache.get(jobID) ?? [];
311
+ }
312
+ GetTimeAgo(date) {
313
+ if (!date)
314
+ return 'Never';
315
+ const now = new Date();
316
+ const d = new Date(date);
317
+ const diffMs = now.getTime() - d.getTime();
318
+ return this.formatDuration(diffMs);
319
+ }
320
+ GetTimeUntil(date) {
321
+ if (!date)
322
+ return '--';
323
+ const now = new Date();
324
+ const d = new Date(date);
325
+ const diffMs = d.getTime() - now.getTime();
326
+ if (diffMs <= 0)
327
+ return 'Due';
328
+ return this.formatDuration(diffMs);
329
+ }
330
+ GetSuccessRate(job) {
331
+ if (job.RunCount === 0)
332
+ return 'N/A';
333
+ return Math.round((job.SuccessCount / job.RunCount) * 100) + '%';
334
+ }
335
+ GetSuccessRateClass(job) {
336
+ if (job.RunCount === 0)
337
+ return '';
338
+ const rate = job.SuccessCount / job.RunCount;
339
+ if (rate >= 0.95)
340
+ return 'high';
341
+ if (rate >= 0.80)
342
+ return 'mid';
343
+ return '';
344
+ }
345
+ GetDuration(run) {
346
+ if (!run.StartedAt || !run.CompletedAt)
347
+ return '--';
348
+ const start = new Date(run.StartedAt).getTime();
349
+ const end = new Date(run.CompletedAt).getTime();
350
+ const diffMs = end - start;
351
+ return this.formatDurationShort(diffMs);
352
+ }
353
+ GetItemsProcessed(run) {
354
+ if (!run.Details)
355
+ return '--';
356
+ try {
357
+ const details = JSON.parse(run.Details);
358
+ if (details['ItemsProcessed'] != null) {
359
+ const total = details['TotalItems'];
360
+ const processed = details['ItemsProcessed'];
361
+ if (run.Status === 'Failed' && total != null) {
362
+ return `${this.formatNumber(processed)} / ${this.formatNumber(total)}`;
363
+ }
364
+ return this.formatNumber(processed);
365
+ }
366
+ }
367
+ catch {
368
+ // details not parseable
369
+ }
370
+ return '--';
371
+ }
372
+ // ================================================================
373
+ // Private Methods
374
+ // ================================================================
375
+ async loadData() {
376
+ this.IsLoading = true;
377
+ this.cdr.detectChanges();
378
+ try {
379
+ const rv = new RunView();
380
+ const [jobsResult, runsResult] = await rv.RunViews([
381
+ {
382
+ EntityName: 'MJ: Scheduled Jobs',
383
+ ExtraFilter: `Name LIKE '%Autotag%' OR Name LIKE '%Vector%' OR Name LIKE '%Content%' OR Name LIKE '%Knowledge%' OR Name LIKE '%Tag%'`,
384
+ OrderBy: 'Name',
385
+ ResultType: 'entity_object',
386
+ },
387
+ {
388
+ EntityName: 'MJ: Scheduled Job Runs',
389
+ ExtraFilter: '',
390
+ OrderBy: 'StartedAt DESC',
391
+ MaxRows: 100,
392
+ ResultType: 'entity_object',
393
+ },
394
+ ]);
395
+ if (jobsResult.Success) {
396
+ this.AllJobs = jobsResult.Results;
397
+ }
398
+ else {
399
+ this.AllJobs = [];
400
+ }
401
+ const allRuns = runsResult.Success
402
+ ? runsResult.Results
403
+ : [];
404
+ this.RecentRuns = allRuns.slice(0, 10);
405
+ this.buildSparklineCache(allRuns);
406
+ this.applyFilters();
407
+ }
408
+ catch (error) {
409
+ console.error('[SchedulingResource] Error loading data:', error);
410
+ this.AllJobs = [];
411
+ this.FilteredJobs = [];
412
+ this.RecentRuns = [];
413
+ }
414
+ finally {
415
+ this.IsLoading = false;
416
+ this.cdr.detectChanges();
417
+ }
418
+ }
419
+ applyFilters() {
420
+ let jobs = this.AllJobs;
421
+ if (this.StatusFilter) {
422
+ jobs = jobs.filter(j => j.Status === this.StatusFilter);
423
+ }
424
+ if (this.SearchQuery.trim()) {
425
+ const query = this.SearchQuery.trim().toLowerCase();
426
+ jobs = jobs.filter(j => j.Name.toLowerCase().includes(query) ||
427
+ (j.Description ?? '').toLowerCase().includes(query));
428
+ }
429
+ this.FilteredJobs = jobs;
430
+ }
431
+ /**
432
+ * Build sparkline data for each job from the last 7 runs.
433
+ * Each dot is 'ok', 'fail', or 'skip'.
434
+ */
435
+ buildSparklineCache(allRuns) {
436
+ this.sparklineCache.clear();
437
+ // Group runs by job ID
438
+ const runsByJob = new Map();
439
+ for (const run of allRuns) {
440
+ const jobID = run.ScheduledJobID;
441
+ if (!runsByJob.has(jobID)) {
442
+ runsByJob.set(jobID, []);
443
+ }
444
+ runsByJob.get(jobID).push(run);
445
+ }
446
+ // Build sparkline for each job (up to 7 most recent runs)
447
+ for (const job of this.AllJobs) {
448
+ const runs = runsByJob.get(job.ID) ?? [];
449
+ const last7 = runs.slice(0, 7);
450
+ const dots = last7.map(r => this.runStatusToDot(r));
451
+ // Pad to 7 with 'skip' dots if fewer runs
452
+ while (dots.length < 7) {
453
+ dots.push('skip');
454
+ }
455
+ this.sparklineCache.set(job.ID, dots);
456
+ }
457
+ }
458
+ runStatusToDot(run) {
459
+ if (run.Status === 'Completed' && run.Success)
460
+ return 'ok';
461
+ if (run.Status === 'Failed' || (run.Status === 'Completed' && !run.Success))
462
+ return 'fail';
463
+ if (run.Status === 'Running')
464
+ return 'ok'; // treat in-progress as OK
465
+ return 'skip';
466
+ }
467
+ // ================================================================
468
+ // Cron Parsing
469
+ // ================================================================
470
+ parseCron(cron) {
471
+ const parts = cron.trim().split(/\s+/);
472
+ // Support 5-part (no seconds) and 6-part (with seconds) cron
473
+ if (parts.length === 5) {
474
+ return {
475
+ Second: '0',
476
+ Minute: parts[0],
477
+ Hour: parts[1],
478
+ DayOfMonth: parts[2],
479
+ Month: parts[3],
480
+ DayOfWeek: parts[4],
481
+ };
482
+ }
483
+ if (parts.length === 6) {
484
+ return {
485
+ Second: parts[0],
486
+ Minute: parts[1],
487
+ Hour: parts[2],
488
+ DayOfMonth: parts[3],
489
+ Month: parts[4],
490
+ DayOfWeek: parts[5],
491
+ };
492
+ }
493
+ return null;
494
+ }
495
+ cronToHuman(p) {
496
+ // Every N minutes: */N * * * *
497
+ if (p.Minute.startsWith('*/') && p.Hour === '*' && p.DayOfMonth === '*' && p.Month === '*' && p.DayOfWeek === '*') {
498
+ const interval = parseInt(p.Minute.slice(2), 10);
499
+ if (interval === 1)
500
+ return 'Every minute';
501
+ return `Every ${interval} minutes`;
502
+ }
503
+ // Every N hours: 0 */N * * *
504
+ if (p.Minute !== '*' && !p.Minute.includes('/') && p.Hour.startsWith('*/') && p.DayOfMonth === '*') {
505
+ const interval = parseInt(p.Hour.slice(2), 10);
506
+ if (interval === 1)
507
+ return 'Every hour';
508
+ return `Every ${interval} hours`;
509
+ }
510
+ // Specific hour with specific or wildcard day fields
511
+ if (!p.Minute.includes('*') && !p.Minute.includes('/') &&
512
+ !p.Hour.includes('*') && !p.Hour.includes('/') &&
513
+ p.Month === '*') {
514
+ const hour = parseInt(p.Hour, 10);
515
+ const minute = parseInt(p.Minute, 10);
516
+ const timeStr = this.formatTime(hour, minute);
517
+ // Weekly: specific day of week
518
+ if (p.DayOfWeek !== '*' && p.DayOfMonth === '*') {
519
+ const dayName = this.dayOfWeekName(p.DayOfWeek);
520
+ return `Weekly on ${dayName} at ${timeStr}`;
521
+ }
522
+ // Monthly: specific day of month
523
+ if (p.DayOfMonth !== '*' && p.DayOfWeek === '*') {
524
+ return `Monthly on day ${p.DayOfMonth} at ${timeStr}`;
525
+ }
526
+ // Daily
527
+ if (p.DayOfMonth === '*' && p.DayOfWeek === '*') {
528
+ return `Daily at ${timeStr}`;
529
+ }
530
+ }
531
+ // Fallback: return the raw cron expression
532
+ return `${p.Minute} ${p.Hour} ${p.DayOfMonth} ${p.Month} ${p.DayOfWeek}`;
533
+ }
534
+ formatTime(hour, minute) {
535
+ const ampm = hour >= 12 ? 'PM' : 'AM';
536
+ const h = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
537
+ const m = minute.toString().padStart(2, '0');
538
+ return `${h}:${m} ${ampm}`;
539
+ }
540
+ dayOfWeekName(dow) {
541
+ const names = {
542
+ '0': 'Sunday', '1': 'Monday', '2': 'Tuesday',
543
+ '3': 'Wednesday', '4': 'Thursday', '5': 'Friday',
544
+ '6': 'Saturday', '7': 'Sunday',
545
+ 'SUN': 'Sunday', 'MON': 'Monday', 'TUE': 'Tuesday',
546
+ 'WED': 'Wednesday', 'THU': 'Thursday', 'FRI': 'Friday',
547
+ 'SAT': 'Saturday',
548
+ };
549
+ return names[dow.toUpperCase()] ?? dow;
550
+ }
551
+ // ================================================================
552
+ // Formatting Helpers
553
+ // ================================================================
554
+ formatDuration(ms) {
555
+ const seconds = Math.floor(ms / 1000);
556
+ const minutes = Math.floor(seconds / 60);
557
+ const hours = Math.floor(minutes / 60);
558
+ const days = Math.floor(hours / 24);
559
+ if (days > 0)
560
+ return `${days}d ago`;
561
+ if (hours > 0)
562
+ return `${hours}h ago`;
563
+ if (minutes > 0)
564
+ return `${minutes}m ago`;
565
+ return 'Just now';
566
+ }
567
+ formatDurationShort(ms) {
568
+ const totalSeconds = Math.floor(ms / 1000);
569
+ const minutes = Math.floor(totalSeconds / 60);
570
+ const seconds = totalSeconds % 60;
571
+ if (minutes >= 60) {
572
+ const hours = Math.floor(minutes / 60);
573
+ const remainMinutes = minutes % 60;
574
+ return `${hours}h ${remainMinutes}m`;
575
+ }
576
+ return `${minutes}m ${seconds.toString().padStart(2, '0')}s`;
577
+ }
578
+ formatNumber(n) {
579
+ return n.toLocaleString();
580
+ }
581
+ static ɵfac = /*@__PURE__*/ (() => { let ɵSchedulingResourceComponent_BaseFactory; return function SchedulingResourceComponent_Factory(__ngFactoryType__) { return (ɵSchedulingResourceComponent_BaseFactory || (ɵSchedulingResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(SchedulingResourceComponent)))(__ngFactoryType__ || SchedulingResourceComponent); }; })();
582
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingResourceComponent, selectors: [["app-scheduling-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "loading-container"], ["text", "Loading scheduled pipelines..."], [1, "toolbar"], [1, "btn-primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "filter-select", 3, "ngModelChange", "ngModel"], ["value", ""], ["value", "Active"], ["value", "Paused"], ["value", "Disabled"], ["value", "Pending"], ["type", "text", "placeholder", "Search pipelines...", 1, "search-input", 3, "ngModelChange", "ngModel"], [1, "toolbar-spacer"], [1, "toolbar-stat"], [1, "cards-grid"], [1, "empty-state"], [1, "scheduling-app-link"], [1, "btn-secondary", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "link-hint"], [3, "Close", "Visible", "ScheduledJobID"], [1, "job-card", 3, "paused", "disabled"], [1, "job-card", 3, "click"], [1, "card-top"], [1, "status-dot"], [1, "card-title-area"], [1, "card-name"], [1, "card-cron"], [1, "fa-regular", "fa-clock"], [1, "sparkline"], [1, "spark-dot", 3, "class"], [1, "sparkline-label"], [1, "card-stats"], [1, "stat"], [1, "fa-solid", "fa-chart-simple"], [1, "fa-regular", "fa-calendar"], [1, "spark-dot"], [1, "fa-regular", "fa-calendar-xmark"]], template: function SchedulingResourceComponent_Template(rf, ctx) { if (rf & 1) {
583
+ i0.ɵɵconditionalCreate(0, SchedulingResourceComponent_Conditional_0_Template, 2, 0, "div", 0)(1, SchedulingResourceComponent_Conditional_1_Template, 29, 7);
584
+ } if (rf & 2) {
585
+ i0.ɵɵconditional(ctx.IsLoading ? 0 : 1);
586
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.LoadingComponent, i3.ScheduledJobDialogComponent], styles: ["\n\n[_nghost-%COMP%] {\n display: block;\n padding: 28px 32px 40px;\n max-width: 1200px;\n min-width: 0;\n}\n\n\n\n.page-header[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n.page-header[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n.page-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n\n\n.toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n}\n.btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: var(--mj-radius-sm, 6px);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s;\n white-space: nowrap;\n}\n.btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n.filter-select[_ngcontent-%COMP%] {\n padding: 7px 32px 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm, 6px);\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%2394a3b8'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 10px center;\n cursor: pointer;\n}\n.search-input[_ngcontent-%COMP%] {\n padding: 7px 12px 7px 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm, 6px);\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n width: 220px;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='%2394a3b8'%3E%3Cpath d='M10 6.5a3.5 3.5 0 11-7 0 3.5 3.5 0 017 0zm-.3 3.9a5.5 5.5 0 111.1-1.1l3.1 3.1a.75.75 0 01-1.1 1.1L9.7 10.4z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: 10px center;\n}\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n.toolbar-spacer[_ngcontent-%COMP%] {\n flex: 1;\n}\n.toolbar-stat[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n.toolbar-stat[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-weight: 600;\n}\n\n\n\n.card-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 14px;\n margin-bottom: 32px;\n}\n@media (max-width: 1024px) {\n .card-grid[_ngcontent-%COMP%] { grid-template-columns: repeat(2, 1fr); }\n}\n@media (max-width: 640px) {\n .card-grid[_ngcontent-%COMP%] { grid-template-columns: 1fr; }\n}\n\n\n\n.job-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n padding: 14px 16px;\n box-shadow: var(--mj-shadow-card, 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04));\n position: relative;\n cursor: pointer;\n transition: box-shadow 0.2s, border-color 0.2s;\n height: 132px;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n}\n.job-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-card-hover, 0 4px 12px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.04));\n border-color: var(--mj-border-strong);\n}\n.job-card[_ngcontent-%COMP%]:hover .card-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n.job-card.disabled-card[_ngcontent-%COMP%] {\n opacity: 0.65;\n}\n\n.card-top[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n.status-dot[_ngcontent-%COMP%] {\n width: 9px;\n height: 9px;\n border-radius: 50%;\n flex-shrink: 0;\n margin-top: 4px;\n}\n.status-dot.active[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-success) 18%, transparent);\n}\n.status-dot.paused[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-warning) 18%, transparent);\n}\n.status-dot.disabled[_ngcontent-%COMP%], \n.status-dot.pending[_ngcontent-%COMP%], \n.status-dot.expired[_ngcontent-%COMP%] {\n background: var(--mj-border-strong);\n}\n\n.card-title-area[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n.card-title[_ngcontent-%COMP%] {\n font-size: 13.5px;\n font-weight: 650;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n line-height: 1.3;\n}\n.card-cron[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 1px;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.card-cron[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n\n\n.card-stats[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n font-size: 11.5px;\n color: var(--mj-text-muted);\n}\n.card-stat[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.card-stat[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n.card-stat[_ngcontent-%COMP%] .value[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-weight: 600;\n}\n.success-rate[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n.success-rate.high[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n.success-rate.mid[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n\n\n.sparkline[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 3px;\n margin-top: 8px;\n}\n.spark-dot[_ngcontent-%COMP%] {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n}\n.spark-dot.ok[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 65%, transparent);\n}\n.spark-dot.fail[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 65%, transparent);\n}\n.spark-dot.skip[_ngcontent-%COMP%] {\n background: var(--mj-border-default);\n}\n.sparkline-label[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n margin-left: 4px;\n}\n\n\n\n.card-actions[_ngcontent-%COMP%] {\n position: absolute;\n top: 10px;\n right: 10px;\n display: flex;\n gap: 6px;\n opacity: 0;\n transition: opacity 0.15s;\n}\n.card-action-btn[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 600;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.12s;\n box-shadow: 0 1px 2px rgba(0,0,0,0.06);\n}\n.card-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n.card-action-btn.run-now[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n}\n.card-action-btn.run-now[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n}\n\n\n\n.card-status-label[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 11.5px;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.card-status-label.paused[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n.card-status-label.disabled[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 14px;\n}\n.section-header[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 650;\n color: var(--mj-text-primary);\n}\n.section-header[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n\n\n.activity-table[_ngcontent-%COMP%] {\n width: 100%;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n box-shadow: var(--mj-shadow-card, 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04));\n overflow: hidden;\n}\n.activity-table[_ngcontent-%COMP%] table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n.activity-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n padding: 10px 14px;\n text-align: left;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 11.5px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.activity-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 9px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n}\n.activity-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n.activity-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n.activity-table[_ngcontent-%COMP%] .job-name-cell[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.activity-table[_ngcontent-%COMP%] .time-cell[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 12.5px;\n}\n.items-cell[_ngcontent-%COMP%] {\n text-align: right;\n font-weight: 600;\n}\n.items-cell.failed[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 10px;\n border-radius: 10px;\n font-size: 11.5px;\n font-weight: 600;\n}\n.status-badge.success[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n.status-badge.failed[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n.status-badge.running[_ngcontent-%COMP%] {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info);\n}\n.status-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 60px;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 40px;\n margin-bottom: 12px;\n}\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n margin-bottom: 4px;\n}\n.empty-state[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.scheduling-app-link[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-top: 20px;\n padding-top: 16px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.link-hint[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}"] });
587
+ };
588
+ SchedulingResourceComponent = __decorate([
589
+ RegisterClass(BaseResourceComponent, 'SchedulingResource')
590
+ ], SchedulingResourceComponent);
591
+ export { SchedulingResourceComponent };
592
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SchedulingResourceComponent, [{
593
+ type: Component,
594
+ args: [{ standalone: false, selector: 'app-scheduling-resource', template: "@if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading scheduled pipelines...\"></mj-loading>\n </div>\n} @else {\n <!-- Toolbar -->\n <div class=\"toolbar\">\n <button class=\"btn-primary\" (click)=\"OnNewSchedule()\">\n <i class=\"fa-solid fa-plus\"></i> New Schedule\n </button>\n <select class=\"filter-select\" [(ngModel)]=\"StatusFilter\" (ngModelChange)=\"OnFilterChanged()\">\n <option value=\"\">All Statuses</option>\n <option value=\"Active\">Active</option>\n <option value=\"Paused\">Paused</option>\n <option value=\"Disabled\">Disabled</option>\n <option value=\"Pending\">Pending</option>\n </select>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Search pipelines...\"\n [(ngModel)]=\"SearchQuery\"\n (ngModelChange)=\"OnSearchChanged()\" />\n <div class=\"toolbar-spacer\"></div>\n <span class=\"toolbar-stat\">\n @if (ActiveCount > 0) { <strong>{{ ActiveCount }}</strong> active }\n @if (PausedCount > 0) { &middot; <strong>{{ PausedCount }}</strong> paused }\n </span>\n </div>\n\n <!-- Job Cards Grid -->\n @if (FilteredJobs.length > 0) {\n <div class=\"cards-grid\">\n @for (job of FilteredJobs; track job.ID) {\n <div class=\"job-card\"\n [class.paused]=\"job.Status === 'Paused'\"\n [class.disabled]=\"job.Status === 'Disabled'\"\n (click)=\"OnEditJob(job)\">\n <div class=\"card-top\">\n <span class=\"status-dot\"\n [class.dot-active]=\"job.Status === 'Active'\"\n [class.dot-paused]=\"job.Status === 'Paused'\"\n [class.dot-disabled]=\"job.Status === 'Disabled'\"></span>\n <div class=\"card-title-area\">\n <div class=\"card-name\">{{ job.Name }}</div>\n <div class=\"card-cron\">\n <i class=\"fa-regular fa-clock\"></i>\n {{ GetCronDescription(job.CronExpression) }}\n </div>\n </div>\n </div>\n <div class=\"sparkline\">\n @for (dotClass of GetSparkline(job.ID); track $index) {\n <span class=\"spark-dot\" [class]=\"dotClass\"></span>\n }\n <span class=\"sparkline-label\">last 7 runs</span>\n </div>\n <div class=\"card-stats\">\n <span class=\"stat\">\n <i class=\"fa-regular fa-clock\"></i>\n Last: <strong>{{ GetTimeAgo(job.LastRunAt) }}</strong>\n </span>\n <span class=\"stat\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <strong>{{ GetSuccessRate(job) }}</strong>\n </span>\n <span class=\"stat\">\n <i class=\"fa-regular fa-calendar\"></i>\n Next: <strong>{{ GetTimeUntil(job.NextRunAt) }}</strong>\n </span>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-regular fa-calendar-xmark\"></i>\n <p>No Knowledge Hub schedules found</p>\n <span>Create a new schedule to automate classification and vector sync</span>\n </div>\n }\n\n <!-- Link to full Scheduling App -->\n <div class=\"scheduling-app-link\">\n <button class=\"btn-secondary\" (click)=\"GoToSchedulingApp()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i> Open Scheduling App\n </button>\n <span class=\"link-hint\">Manage all scheduled jobs across the system</span>\n </div>\n\n <!-- Edit Dialog -->\n <mj-scheduled-job-dialog\n [Visible]=\"ShowEditDialog\"\n [ScheduledJobID]=\"EditingJobID\"\n (Close)=\"OnDialogClosed($event)\">\n </mj-scheduled-job-dialog>\n}\n", styles: ["/* \u2500\u2500 Host \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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:host {\n display: block;\n padding: 28px 32px 40px;\n max-width: 1200px;\n min-width: 0;\n}\n\n/* \u2500\u2500 Page Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.page-header {\n margin-bottom: 24px;\n}\n.page-header h1 {\n font-size: 22px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n.page-header p {\n font-size: 13px;\n color: var(--mj-text-secondary);\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\u2500\u2500\u2500\u2500\u2500 */\n.toolbar {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n}\n.btn-primary {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: var(--mj-radius-sm, 6px);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s;\n white-space: nowrap;\n}\n.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n.filter-select {\n padding: 7px 32px 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm, 6px);\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%2394a3b8'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 10px center;\n cursor: pointer;\n}\n.search-input {\n padding: 7px 12px 7px 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm, 6px);\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n width: 220px;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='%2394a3b8'%3E%3Cpath d='M10 6.5a3.5 3.5 0 11-7 0 3.5 3.5 0 017 0zm-.3 3.9a5.5 5.5 0 111.1-1.1l3.1 3.1a.75.75 0 01-1.1 1.1L9.7 10.4z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: 10px center;\n}\n.search-input::placeholder {\n color: var(--mj-text-muted);\n}\n.toolbar-spacer {\n flex: 1;\n}\n.toolbar-stat {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n.toolbar-stat strong {\n color: var(--mj-text-secondary);\n font-weight: 600;\n}\n\n/* \u2500\u2500 Card 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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.card-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 14px;\n margin-bottom: 32px;\n}\n@media (max-width: 1024px) {\n .card-grid { grid-template-columns: repeat(2, 1fr); }\n}\n@media (max-width: 640px) {\n .card-grid { grid-template-columns: 1fr; }\n}\n\n/* \u2500\u2500 Job Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.job-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n padding: 14px 16px;\n box-shadow: var(--mj-shadow-card, 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04));\n position: relative;\n cursor: pointer;\n transition: box-shadow 0.2s, border-color 0.2s;\n height: 132px;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n}\n.job-card:hover {\n box-shadow: var(--mj-shadow-card-hover, 0 4px 12px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.04));\n border-color: var(--mj-border-strong);\n}\n.job-card:hover .card-actions {\n opacity: 1;\n}\n.job-card.disabled-card {\n opacity: 0.65;\n}\n\n.card-top {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n.status-dot {\n width: 9px;\n height: 9px;\n border-radius: 50%;\n flex-shrink: 0;\n margin-top: 4px;\n}\n.status-dot.active {\n background: var(--mj-status-success);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-success) 18%, transparent);\n}\n.status-dot.paused {\n background: var(--mj-status-warning);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-warning) 18%, transparent);\n}\n.status-dot.disabled,\n.status-dot.pending,\n.status-dot.expired {\n background: var(--mj-border-strong);\n}\n\n.card-title-area {\n flex: 1;\n min-width: 0;\n}\n.card-title {\n font-size: 13.5px;\n font-weight: 650;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n line-height: 1.3;\n}\n.card-cron {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 1px;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.card-cron i {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n/* Stats row */\n.card-stats {\n display: flex;\n align-items: center;\n gap: 16px;\n font-size: 11.5px;\n color: var(--mj-text-muted);\n}\n.card-stat {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.card-stat i {\n font-size: 10px;\n}\n.card-stat .value {\n color: var(--mj-text-secondary);\n font-weight: 600;\n}\n.success-rate {\n font-weight: 700;\n}\n.success-rate.high {\n color: var(--mj-status-success);\n}\n.success-rate.mid {\n color: var(--mj-status-warning);\n}\n\n/* Sparkline */\n.sparkline {\n display: flex;\n align-items: center;\n gap: 3px;\n margin-top: 8px;\n}\n.spark-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n}\n.spark-dot.ok {\n background: color-mix(in srgb, var(--mj-status-success) 65%, transparent);\n}\n.spark-dot.fail {\n background: color-mix(in srgb, var(--mj-status-error) 65%, transparent);\n}\n.spark-dot.skip {\n background: var(--mj-border-default);\n}\n.sparkline-label {\n font-size: 10px;\n color: var(--mj-text-muted);\n margin-left: 4px;\n}\n\n/* Hover actions */\n.card-actions {\n position: absolute;\n top: 10px;\n right: 10px;\n display: flex;\n gap: 6px;\n opacity: 0;\n transition: opacity 0.15s;\n}\n.card-action-btn {\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 600;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.12s;\n box-shadow: 0 1px 2px rgba(0,0,0,0.06);\n}\n.card-action-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n.card-action-btn.run-now {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n}\n.card-action-btn.run-now:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n}\n\n/* Paused/disabled status on card */\n.card-status-label {\n font-weight: 600;\n font-size: 11.5px;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.card-status-label.paused {\n color: var(--mj-status-warning);\n}\n.card-status-label.disabled {\n color: var(--mj-text-muted);\n}\n\n/* \u2500\u2500 Section Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 14px;\n}\n.section-header h2 {\n font-size: 15px;\n font-weight: 650;\n color: var(--mj-text-primary);\n}\n.section-header .badge {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n/* \u2500\u2500 Activity Table \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.activity-table {\n width: 100%;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n box-shadow: var(--mj-shadow-card, 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04));\n overflow: hidden;\n}\n.activity-table table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n.activity-table thead th {\n background: var(--mj-bg-surface-card);\n padding: 10px 14px;\n text-align: left;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 11.5px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.activity-table tbody td {\n padding: 9px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n}\n.activity-table tbody tr:last-child td {\n border-bottom: none;\n}\n.activity-table tbody tr:hover {\n background: var(--mj-bg-surface-hover);\n}\n.activity-table .job-name-cell {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.activity-table .time-cell {\n color: var(--mj-text-secondary);\n font-size: 12.5px;\n}\n.items-cell {\n text-align: right;\n font-weight: 600;\n}\n.items-cell.failed {\n color: var(--mj-status-error);\n}\n\n/* Status badges */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 10px;\n border-radius: 10px;\n font-size: 11.5px;\n font-weight: 600;\n}\n.status-badge.success {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n.status-badge.failed {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n.status-badge.running {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info);\n}\n.status-badge i {\n font-size: 9px;\n}\n\n/* \u2500\u2500 Loading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 padding: 60px;\n}\n\n/* \u2500\u2500 Empty state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n.empty-state i {\n font-size: 40px;\n margin-bottom: 12px;\n}\n.empty-state p {\n font-size: 14px;\n margin-bottom: 4px;\n}\n.empty-state span {\n font-size: 12px;\n}\n\n/* Scheduling App Link */\n.scheduling-app-link {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-top: 20px;\n padding-top: 16px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.btn-secondary {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-secondary:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.link-hint {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n"] }]
595
+ }], null, null); })();
596
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SchedulingResourceComponent, { className: "SchedulingResourceComponent", filePath: "src/KnowledgeHub/components/scheduling/scheduling-resource.component.ts", lineNumber: 38 }); })();
597
+ /** Tree-shaking prevention */
598
+ export function LoadSchedulingResource() {
599
+ // Prevents tree-shaking of the component
600
+ }
601
+ //# sourceMappingURL=scheduling-resource.component.js.map