@memberjunction/ng-dashboards 5.38.0 → 5.40.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.
- package/README.md +14 -7
- package/dist/AI/components/agents/agent-configuration.component.js +199 -198
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/ai-analytics-resource.component.js +20 -17
- package/dist/AI/components/analytics/ai-analytics-resource.component.js.map +1 -1
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts +15 -0
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.js +166 -58
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.js.map +1 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.js +2 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.js.map +1 -1
- package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts +1 -0
- package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/model-performance/model-performance.component.js +55 -36
- package/dist/AI/components/analytics/model-performance/model-performance.component.js.map +1 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts +9 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js +158 -117
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js.map +1 -1
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts +1 -0
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js +22 -8
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +217 -860
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +1717 -7802
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts +56 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js +423 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts +70 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.js +308 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts +29 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js +186 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts +69 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js +278 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts +73 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js +393 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts +122 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js +908 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts +87 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js +475 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts +29 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js +208 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts +21 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js +70 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts +333 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +2125 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts +61 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.js +78 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.js.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.format.d.ts +58 -0
- package/dist/AI/components/autotagging/shared/classify.format.d.ts.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.format.js +260 -0
- package/dist/AI/components/autotagging/shared/classify.format.js.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.types.d.ts +319 -0
- package/dist/AI/components/autotagging/shared/classify.types.d.ts.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.types.js +6 -0
- package/dist/AI/components/autotagging/shared/classify.types.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts +103 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.js +571 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts +77 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.js +519 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts +107 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.js +719 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts +131 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js +813 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts +177 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.js +1465 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts +78 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.js +492 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts +397 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js +3490 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts +56 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.js +271 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.js.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +3 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +306 -290
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +1 -1
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +209 -208
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +130 -128
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/requests/agent-requests-resource.component.js +61 -61
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +17 -17
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +1 -0
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.js +578 -538
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +3 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +331 -303
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.d.ts +5 -0
- package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.js +14 -2
- package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
- package/dist/AI/services/cache-metrics.d.ts +50 -0
- package/dist/AI/services/cache-metrics.d.ts.map +1 -0
- package/dist/AI/services/cache-metrics.js +43 -0
- package/dist/AI/services/cache-metrics.js.map +1 -0
- package/dist/APIKeys/api-applications-panel.component.js +2 -2
- package/dist/APIKeys/api-key-create-dialog.component.js +2 -2
- package/dist/APIKeys/api-key-edit-panel.component.js +2 -2
- package/dist/APIKeys/api-keys-resource.component.js +132 -131
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +141 -141
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +15 -15
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.d.ts +0 -5
- package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +139 -212
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Admin/admin-data-schema.component.js +2 -2
- package/dist/Admin/admin-data-schema.component.js.map +1 -1
- package/dist/Admin/admin-dev-tools-resource.component.js +2 -2
- package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -1
- package/dist/Admin/admin-identity-access.component.js +2 -2
- package/dist/Admin/admin-identity-access.component.js.map +1 -1
- package/dist/Admin/admin-monitoring.component.js +2 -2
- package/dist/Admin/admin-monitoring.component.js.map +1 -1
- package/dist/ApplicationRoles/application-roles-resource.component.js +54 -49
- package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
- package/dist/Communication/communication-logs-resource.component.d.ts +6 -0
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +72 -50
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +103 -102
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +52 -51
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +39 -38
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.d.ts +6 -0
- package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +92 -89
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +136 -135
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +155 -152
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +119 -118
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +129 -128
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +107 -106
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +31 -340
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +468 -1958
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +10 -0
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +1 -1
- package/dist/DatabaseDesigner/components/entity-list.component.js +115 -114
- package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -1
- package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +5 -6
- package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -1
- package/dist/DatabaseDesigner/database-designer-dashboards.module.js +4 -5
- package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -1
- package/dist/DevTools/app-state-inspector.component.js +18 -17
- package/dist/DevTools/app-state-inspector.component.js.map +1 -1
- package/dist/DevTools/class-registry.component.js +88 -85
- package/dist/DevTools/class-registry.component.js.map +1 -1
- package/dist/DevTools/event-monitor.component.js +155 -150
- package/dist/DevTools/event-monitor.component.js.map +1 -1
- package/dist/DevTools/graphql-console.component.js +245 -243
- package/dist/DevTools/graphql-console.component.js.map +1 -1
- package/dist/DevTools/layout-inspector.component.js +18 -17
- package/dist/DevTools/layout-inspector.component.js.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +20 -19
- package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +2 -2
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +236 -229
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +390 -389
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +2 -2
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +14 -11
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +27 -2
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +244 -119
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +293 -291
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +62 -61
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts +65 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js +176 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js.map +1 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts +81 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js +308 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js.map +1 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts +85 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js +362 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/index.d.ts +3 -0
- package/dist/KnowledgeHub/index.d.ts.map +1 -1
- package/dist/KnowledgeHub/index.js +3 -0
- package/dist/KnowledgeHub/index.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts +6 -2
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +525 -566
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +135 -134
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +199 -198
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
- package/dist/MCP/mcp-dashboard.component.js +443 -438
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +146 -147
- package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +76 -75
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +97 -96
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +24 -22
- package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +2 -0
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.js +1 -0
- package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts +14 -4
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +436 -427
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.js +1 -1
- package/dist/Testing/components/testing-runs.component.js +116 -115
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +6 -7
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/VersionHistory/components/labels-resource.component.js +173 -172
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.d.ts +6 -0
- package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +116 -92
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +57 -35
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +80 -1
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/communication-dashboards.module.d.ts +1 -1
- package/dist/communication-dashboards.module.d.ts.map +1 -1
- package/dist/communication-dashboards.module.js +7 -1
- package/dist/communication-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +12 -14
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +5 -14
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +3 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -1
- package/dist/testing-dashboards.module.d.ts +4 -5
- package/dist/testing-dashboards.module.d.ts.map +1 -1
- package/dist/testing-dashboards.module.js +7 -5
- package/dist/testing-dashboards.module.js.map +1 -1
- package/package.json +57 -54
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts +0 -79
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts.map +0 -1
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +0 -195
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js.map +0 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts +0 -226
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +0 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +0 -861
- package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +0 -1
|
@@ -40,7 +40,7 @@ function SchedulingResourceComponent_Conditional_0_Conditional_4_Template(rf, ct
|
|
|
40
40
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
41
41
|
i0.ɵɵproperty("Count", ctx_r1.PausedCount);
|
|
42
42
|
} }
|
|
43
|
-
function
|
|
43
|
+
function SchedulingResourceComponent_Conditional_0_ng_container_24_Template(rf, ctx) { if (rf & 1) {
|
|
44
44
|
i0.ɵɵelementContainer(0);
|
|
45
45
|
} }
|
|
46
46
|
function SchedulingResourceComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -52,31 +52,32 @@ function SchedulingResourceComponent_Conditional_0_Template(rf, ctx) { if (rf &
|
|
|
52
52
|
i0.ɵɵelementStart(5, "div", 5)(6, "button", 6);
|
|
53
53
|
i0.ɵɵlistener("click", function SchedulingResourceComponent_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNewSchedule()); });
|
|
54
54
|
i0.ɵɵelement(7, "i", 7);
|
|
55
|
-
i0.ɵɵ
|
|
56
|
-
i0.ɵɵ
|
|
57
|
-
i0.ɵɵ
|
|
58
|
-
i0.ɵɵ
|
|
55
|
+
i0.ɵɵelementStart(8, "span", 8);
|
|
56
|
+
i0.ɵɵtext(9, "New Schedule");
|
|
57
|
+
i0.ɵɵelementEnd()()();
|
|
58
|
+
i0.ɵɵelementStart(10, "div", 9)(11, "mj-page-search", 10);
|
|
59
|
+
i0.ɵɵlistener("ValueChange", function SchedulingResourceComponent_Conditional_0_Template_mj_page_search_ValueChange_11_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.SearchQuery = $event; return i0.ɵɵresetView(ctx_r1.OnSearchChanged()); });
|
|
59
60
|
i0.ɵɵelementEnd();
|
|
60
|
-
i0.ɵɵelementStart(
|
|
61
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
62
|
-
i0.ɵɵlistener("ngModelChange", function
|
|
63
|
-
i0.ɵɵelementStart(
|
|
64
|
-
i0.ɵɵtext(
|
|
61
|
+
i0.ɵɵelementStart(12, "select", 11);
|
|
62
|
+
i0.ɵɵtwoWayListener("ngModelChange", function SchedulingResourceComponent_Conditional_0_Template_select_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.StatusFilter, $event) || (ctx_r1.StatusFilter = $event); return i0.ɵɵresetView($event); });
|
|
63
|
+
i0.ɵɵlistener("ngModelChange", function SchedulingResourceComponent_Conditional_0_Template_select_ngModelChange_12_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnFilterChanged()); });
|
|
64
|
+
i0.ɵɵelementStart(13, "option", 12);
|
|
65
|
+
i0.ɵɵtext(14, "All Statuses");
|
|
65
66
|
i0.ɵɵelementEnd();
|
|
66
|
-
i0.ɵɵelementStart(
|
|
67
|
-
i0.ɵɵtext(
|
|
67
|
+
i0.ɵɵelementStart(15, "option", 13);
|
|
68
|
+
i0.ɵɵtext(16, "Active");
|
|
68
69
|
i0.ɵɵelementEnd();
|
|
69
|
-
i0.ɵɵelementStart(
|
|
70
|
-
i0.ɵɵtext(
|
|
70
|
+
i0.ɵɵelementStart(17, "option", 14);
|
|
71
|
+
i0.ɵɵtext(18, "Paused");
|
|
71
72
|
i0.ɵɵelementEnd();
|
|
72
|
-
i0.ɵɵelementStart(
|
|
73
|
-
i0.ɵɵtext(
|
|
73
|
+
i0.ɵɵelementStart(19, "option", 15);
|
|
74
|
+
i0.ɵɵtext(20, "Disabled");
|
|
74
75
|
i0.ɵɵelementEnd();
|
|
75
|
-
i0.ɵɵelementStart(
|
|
76
|
-
i0.ɵɵtext(
|
|
76
|
+
i0.ɵɵelementStart(21, "option", 16);
|
|
77
|
+
i0.ɵɵtext(22, "Pending");
|
|
77
78
|
i0.ɵɵelementEnd()()()();
|
|
78
|
-
i0.ɵɵelementStart(
|
|
79
|
-
i0.ɵɵtemplate(
|
|
79
|
+
i0.ɵɵelementStart(23, "mj-page-body");
|
|
80
|
+
i0.ɵɵtemplate(24, SchedulingResourceComponent_Conditional_0_ng_container_24_Template, 1, 0, "ng-container", 17);
|
|
80
81
|
i0.ɵɵelementEnd()();
|
|
81
82
|
} if (rf & 2) {
|
|
82
83
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -85,7 +86,7 @@ function SchedulingResourceComponent_Conditional_0_Template(rf, ctx) { if (rf &
|
|
|
85
86
|
i0.ɵɵconditional(ctx_r1.ActiveCount > 0 ? 3 : -1);
|
|
86
87
|
i0.ɵɵadvance();
|
|
87
88
|
i0.ɵɵconditional(ctx_r1.PausedCount > 0 ? 4 : -1);
|
|
88
|
-
i0.ɵɵadvance(
|
|
89
|
+
i0.ɵɵadvance(7);
|
|
89
90
|
i0.ɵɵproperty("Value", ctx_r1.SearchQuery);
|
|
90
91
|
i0.ɵɵadvance();
|
|
91
92
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.StatusFilter);
|
|
@@ -97,35 +98,35 @@ function SchedulingResourceComponent_Conditional_1_ng_container_17_Template(rf,
|
|
|
97
98
|
} }
|
|
98
99
|
function SchedulingResourceComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
99
100
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
100
|
-
i0.ɵɵelementStart(0, "div",
|
|
101
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "input", 19);
|
|
101
102
|
i0.ɵɵtwoWayListener("ngModelChange", function SchedulingResourceComponent_Conditional_1_Template_input_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.SearchQuery, $event) || (ctx_r1.SearchQuery = $event); return i0.ɵɵresetView($event); });
|
|
102
103
|
i0.ɵɵlistener("ngModelChange", function SchedulingResourceComponent_Conditional_1_Template_input_ngModelChange_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSearchChanged()); });
|
|
103
104
|
i0.ɵɵelementEnd();
|
|
104
|
-
i0.ɵɵelementStart(2, "select",
|
|
105
|
+
i0.ɵɵelementStart(2, "select", 11);
|
|
105
106
|
i0.ɵɵtwoWayListener("ngModelChange", function SchedulingResourceComponent_Conditional_1_Template_select_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.StatusFilter, $event) || (ctx_r1.StatusFilter = $event); return i0.ɵɵresetView($event); });
|
|
106
107
|
i0.ɵɵlistener("ngModelChange", function SchedulingResourceComponent_Conditional_1_Template_select_ngModelChange_2_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnFilterChanged()); });
|
|
107
|
-
i0.ɵɵelementStart(3, "option",
|
|
108
|
+
i0.ɵɵelementStart(3, "option", 12);
|
|
108
109
|
i0.ɵɵtext(4, "All Statuses");
|
|
109
110
|
i0.ɵɵelementEnd();
|
|
110
|
-
i0.ɵɵelementStart(5, "option",
|
|
111
|
+
i0.ɵɵelementStart(5, "option", 13);
|
|
111
112
|
i0.ɵɵtext(6, "Active");
|
|
112
113
|
i0.ɵɵelementEnd();
|
|
113
|
-
i0.ɵɵelementStart(7, "option",
|
|
114
|
+
i0.ɵɵelementStart(7, "option", 14);
|
|
114
115
|
i0.ɵɵtext(8, "Paused");
|
|
115
116
|
i0.ɵɵelementEnd();
|
|
116
|
-
i0.ɵɵelementStart(9, "option",
|
|
117
|
+
i0.ɵɵelementStart(9, "option", 15);
|
|
117
118
|
i0.ɵɵtext(10, "Disabled");
|
|
118
119
|
i0.ɵɵelementEnd();
|
|
119
|
-
i0.ɵɵelementStart(11, "option",
|
|
120
|
+
i0.ɵɵelementStart(11, "option", 16);
|
|
120
121
|
i0.ɵɵtext(12, "Pending");
|
|
121
122
|
i0.ɵɵelementEnd()();
|
|
122
|
-
i0.ɵɵelement(13, "span",
|
|
123
|
+
i0.ɵɵelement(13, "span", 20);
|
|
123
124
|
i0.ɵɵelementStart(14, "button", 6);
|
|
124
125
|
i0.ɵɵlistener("click", function SchedulingResourceComponent_Conditional_1_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNewSchedule()); });
|
|
125
126
|
i0.ɵɵelement(15, "i", 7);
|
|
126
127
|
i0.ɵɵtext(16, " New Schedule ");
|
|
127
128
|
i0.ɵɵelementEnd()();
|
|
128
|
-
i0.ɵɵtemplate(17, SchedulingResourceComponent_Conditional_1_ng_container_17_Template, 1, 0, "ng-container",
|
|
129
|
+
i0.ɵɵtemplate(17, SchedulingResourceComponent_Conditional_1_ng_container_17_Template, 1, 0, "ng-container", 17);
|
|
129
130
|
} if (rf & 2) {
|
|
130
131
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
131
132
|
const schedulingBody_r3 = i0.ɵɵreference(3);
|
|
@@ -137,47 +138,47 @@ function SchedulingResourceComponent_Conditional_1_Template(rf, ctx) { if (rf &
|
|
|
137
138
|
i0.ɵɵproperty("ngTemplateOutlet", schedulingBody_r3);
|
|
138
139
|
} }
|
|
139
140
|
function SchedulingResourceComponent_ng_template_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
140
|
-
i0.ɵɵelementStart(0, "div",
|
|
141
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
141
|
+
i0.ɵɵelementStart(0, "div", 21);
|
|
142
|
+
i0.ɵɵelement(1, "mj-loading", 22);
|
|
142
143
|
i0.ɵɵelementEnd();
|
|
143
144
|
} }
|
|
144
145
|
function SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_For_2_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
145
|
-
i0.ɵɵelement(0, "span",
|
|
146
|
+
i0.ɵɵelement(0, "span", 45);
|
|
146
147
|
} if (rf & 2) {
|
|
147
148
|
const dotClass_r8 = ctx.$implicit;
|
|
148
149
|
i0.ɵɵclassMap(dotClass_r8);
|
|
149
150
|
} }
|
|
150
151
|
function SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
151
152
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
152
|
-
i0.ɵɵelementStart(0, "div",
|
|
153
|
+
i0.ɵɵelementStart(0, "div", 31);
|
|
153
154
|
i0.ɵɵlistener("click", function SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_For_2_Template_div_click_0_listener() { const job_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnEditJob(job_r7)); });
|
|
154
|
-
i0.ɵɵelementStart(1, "div",
|
|
155
|
-
i0.ɵɵelement(2, "span",
|
|
156
|
-
i0.ɵɵelementStart(3, "div",
|
|
155
|
+
i0.ɵɵelementStart(1, "div", 32);
|
|
156
|
+
i0.ɵɵelement(2, "span", 33);
|
|
157
|
+
i0.ɵɵelementStart(3, "div", 34)(4, "div", 35);
|
|
157
158
|
i0.ɵɵtext(5);
|
|
158
159
|
i0.ɵɵelementEnd();
|
|
159
|
-
i0.ɵɵelementStart(6, "div",
|
|
160
|
-
i0.ɵɵelement(7, "i",
|
|
160
|
+
i0.ɵɵelementStart(6, "div", 36);
|
|
161
|
+
i0.ɵɵelement(7, "i", 37);
|
|
161
162
|
i0.ɵɵtext(8);
|
|
162
163
|
i0.ɵɵelementEnd()()();
|
|
163
|
-
i0.ɵɵelementStart(9, "div",
|
|
164
|
-
i0.ɵɵrepeaterCreate(10, SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_For_2_For_11_Template, 1, 2, "span",
|
|
165
|
-
i0.ɵɵelementStart(12, "span",
|
|
164
|
+
i0.ɵɵelementStart(9, "div", 38);
|
|
165
|
+
i0.ɵɵrepeaterCreate(10, SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_For_2_For_11_Template, 1, 2, "span", 39, i0.ɵɵrepeaterTrackByIndex);
|
|
166
|
+
i0.ɵɵelementStart(12, "span", 40);
|
|
166
167
|
i0.ɵɵtext(13, "last 7 runs");
|
|
167
168
|
i0.ɵɵelementEnd()();
|
|
168
|
-
i0.ɵɵelementStart(14, "div",
|
|
169
|
-
i0.ɵɵelement(16, "i",
|
|
169
|
+
i0.ɵɵelementStart(14, "div", 41)(15, "span", 42);
|
|
170
|
+
i0.ɵɵelement(16, "i", 37);
|
|
170
171
|
i0.ɵɵtext(17, " Last: ");
|
|
171
172
|
i0.ɵɵelementStart(18, "strong");
|
|
172
173
|
i0.ɵɵtext(19);
|
|
173
174
|
i0.ɵɵelementEnd()();
|
|
174
|
-
i0.ɵɵelementStart(20, "span",
|
|
175
|
-
i0.ɵɵelement(21, "i",
|
|
175
|
+
i0.ɵɵelementStart(20, "span", 42);
|
|
176
|
+
i0.ɵɵelement(21, "i", 43);
|
|
176
177
|
i0.ɵɵelementStart(22, "strong");
|
|
177
178
|
i0.ɵɵtext(23);
|
|
178
179
|
i0.ɵɵelementEnd()();
|
|
179
|
-
i0.ɵɵelementStart(24, "span",
|
|
180
|
-
i0.ɵɵelement(25, "i",
|
|
180
|
+
i0.ɵɵelementStart(24, "span", 42);
|
|
181
|
+
i0.ɵɵelement(25, "i", 44);
|
|
181
182
|
i0.ɵɵtext(26, " Next: ");
|
|
182
183
|
i0.ɵɵelementStart(27, "strong");
|
|
183
184
|
i0.ɵɵtext(28);
|
|
@@ -202,8 +203,8 @@ function SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_F
|
|
|
202
203
|
i0.ɵɵtextInterpolate(ctx_r1.GetTimeUntil(job_r7.NextRunAt));
|
|
203
204
|
} }
|
|
204
205
|
function SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
205
|
-
i0.ɵɵelementStart(0, "div",
|
|
206
|
-
i0.ɵɵrepeaterCreate(1, SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_For_2_Template, 29, 15, "div",
|
|
206
|
+
i0.ɵɵelementStart(0, "div", 23);
|
|
207
|
+
i0.ɵɵrepeaterCreate(1, SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_For_2_Template, 29, 15, "div", 30, _forTrack0);
|
|
207
208
|
i0.ɵɵelementEnd();
|
|
208
209
|
} if (rf & 2) {
|
|
209
210
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -211,8 +212,8 @@ function SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_T
|
|
|
211
212
|
i0.ɵɵrepeater(ctx_r1.FilteredJobs);
|
|
212
213
|
} }
|
|
213
214
|
function SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
214
|
-
i0.ɵɵelementStart(0, "div",
|
|
215
|
-
i0.ɵɵelement(1, "i",
|
|
215
|
+
i0.ɵɵelementStart(0, "div", 24);
|
|
216
|
+
i0.ɵɵelement(1, "i", 46);
|
|
216
217
|
i0.ɵɵelementStart(2, "p");
|
|
217
218
|
i0.ɵɵtext(3, "No Knowledge Hub schedules found");
|
|
218
219
|
i0.ɵɵelementEnd();
|
|
@@ -222,16 +223,16 @@ function SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_1_T
|
|
|
222
223
|
} }
|
|
223
224
|
function SchedulingResourceComponent_ng_template_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
224
225
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
225
|
-
i0.ɵɵconditionalCreate(0, SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_Template, 3, 0, "div",
|
|
226
|
-
i0.ɵɵelementStart(2, "div",
|
|
226
|
+
i0.ɵɵconditionalCreate(0, SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_0_Template, 3, 0, "div", 23)(1, SchedulingResourceComponent_ng_template_2_Conditional_1_Conditional_1_Template, 6, 0, "div", 24);
|
|
227
|
+
i0.ɵɵelementStart(2, "div", 25)(3, "button", 26);
|
|
227
228
|
i0.ɵɵlistener("click", function SchedulingResourceComponent_ng_template_2_Conditional_1_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.GoToSchedulingApp()); });
|
|
228
|
-
i0.ɵɵelement(4, "i",
|
|
229
|
+
i0.ɵɵelement(4, "i", 27);
|
|
229
230
|
i0.ɵɵtext(5, " Open Scheduling App ");
|
|
230
231
|
i0.ɵɵelementEnd();
|
|
231
|
-
i0.ɵɵelementStart(6, "span",
|
|
232
|
+
i0.ɵɵelementStart(6, "span", 28);
|
|
232
233
|
i0.ɵɵtext(7, "Manage all scheduled jobs across the system");
|
|
233
234
|
i0.ɵɵelementEnd()();
|
|
234
|
-
i0.ɵɵelementStart(8, "mj-scheduled-job-dialog",
|
|
235
|
+
i0.ɵɵelementStart(8, "mj-scheduled-job-dialog", 29);
|
|
235
236
|
i0.ɵɵlistener("Close", function SchedulingResourceComponent_ng_template_2_Conditional_1_Template_mj_scheduled_job_dialog_Close_8_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDialogClosed($event)); });
|
|
236
237
|
i0.ɵɵelementEnd();
|
|
237
238
|
} if (rf & 2) {
|
|
@@ -241,7 +242,7 @@ function SchedulingResourceComponent_ng_template_2_Conditional_1_Template(rf, ct
|
|
|
241
242
|
i0.ɵɵproperty("Visible", ctx_r1.ShowEditDialog)("ScheduledJobID", ctx_r1.EditingJobID);
|
|
242
243
|
} }
|
|
243
244
|
function SchedulingResourceComponent_ng_template_2_Template(rf, ctx) { if (rf & 1) {
|
|
244
|
-
i0.ɵɵconditionalCreate(0, SchedulingResourceComponent_ng_template_2_Conditional_0_Template, 2, 0, "div",
|
|
245
|
+
i0.ɵɵconditionalCreate(0, SchedulingResourceComponent_ng_template_2_Conditional_0_Template, 2, 0, "div", 21)(1, SchedulingResourceComponent_ng_template_2_Conditional_1_Template, 9, 3);
|
|
245
246
|
} if (rf & 2) {
|
|
246
247
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
247
248
|
i0.ɵɵconditional(ctx_r1.IsLoading ? 0 : 1);
|
|
@@ -645,8 +646,8 @@ let SchedulingResourceComponent = class SchedulingResourceComponent extends Base
|
|
|
645
646
|
return n.toLocaleString();
|
|
646
647
|
}
|
|
647
648
|
static ɵfac = /*@__PURE__*/ (() => { let ɵSchedulingResourceComponent_BaseFactory; return function SchedulingResourceComponent_Factory(__ngFactoryType__) { return (ɵSchedulingResourceComponent_BaseFactory || (ɵSchedulingResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(SchedulingResourceComponent)))(__ngFactoryType__ || SchedulingResourceComponent); }; })();
|
|
648
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingResourceComponent, selectors: [["app-scheduling-resource"]], inputs: { HideToolbar: "HideToolbar" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["schedulingBody", ""], ["Title", "Knowledge Pipelines", "Icon", "fa-solid fa-calendar-check", "Subtitle", "Scheduled knowledge ingestion, autotagging, and embedding pipelines"], ["meta", ""], ["Label", "active", "Variant", "success", 3, "Count"], ["Label", "paused", "Variant", "warning", 3, "Count"], ["actions", ""], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-plus"], ["toolbar", ""], ["Placeholder", "Search pipelines...", 3, "ValueChange", "Value"], [1, "mj-input", "kh-toolbar-select", 3, "ngModelChange", "ngModel"], ["value", ""], ["value", "Active"], ["value", "Paused"], ["value", "Disabled"], ["value", "Pending"], [4, "ngTemplateOutlet"], [1, "embedded-controls"], ["type", "text", "placeholder", "Search pipelines...", 1, "mj-input", "embedded-search", 3, "ngModelChange", "ngModel"], [1, "embedded-spacer"], [1, "loading-container"], ["text", "Loading scheduled pipelines..."], [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) {
|
|
649
|
-
i0.ɵɵconditionalCreate(0, SchedulingResourceComponent_Conditional_0_Template,
|
|
649
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingResourceComponent, selectors: [["app-scheduling-resource"]], inputs: { HideToolbar: "HideToolbar" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["schedulingBody", ""], ["Title", "Knowledge Pipelines", "Icon", "fa-solid fa-calendar-check", "Subtitle", "Scheduled knowledge ingestion, autotagging, and embedding pipelines"], ["meta", ""], ["Label", "active", "Variant", "success", 3, "Count"], ["Label", "paused", "Variant", "warning", 3, "Count"], ["actions", ""], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "action-btn-label"], ["toolbar", ""], ["Placeholder", "Search pipelines...", 3, "ValueChange", "Value"], [1, "mj-input", "kh-toolbar-select", 3, "ngModelChange", "ngModel"], ["value", ""], ["value", "Active"], ["value", "Paused"], ["value", "Disabled"], ["value", "Pending"], [4, "ngTemplateOutlet"], [1, "embedded-controls"], ["type", "text", "placeholder", "Search pipelines...", 1, "mj-input", "embedded-search", 3, "ngModelChange", "ngModel"], [1, "embedded-spacer"], [1, "loading-container"], ["text", "Loading scheduled pipelines..."], [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) {
|
|
650
|
+
i0.ɵɵconditionalCreate(0, SchedulingResourceComponent_Conditional_0_Template, 25, 5, "mj-page-layout");
|
|
650
651
|
i0.ɵɵconditionalCreate(1, SchedulingResourceComponent_Conditional_1_Template, 18, 3);
|
|
651
652
|
i0.ɵɵtemplate(2, SchedulingResourceComponent_ng_template_2_Template, 2, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
|
|
652
653
|
} if (rf & 2) {
|
|
@@ -661,7 +662,7 @@ SchedulingResourceComponent = __decorate([
|
|
|
661
662
|
export { SchedulingResourceComponent };
|
|
662
663
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SchedulingResourceComponent, [{
|
|
663
664
|
type: Component,
|
|
664
|
-
args: [{ standalone: false, selector: 'app-scheduling-resource', template: "@if (!HideToolbar) {\n<mj-page-layout>\n <mj-page-header\n Title=\"Knowledge Pipelines\"\n Icon=\"fa-solid fa-calendar-check\"\n Subtitle=\"Scheduled knowledge ingestion, autotagging, and embedding pipelines\">\n <div meta>\n @if (ActiveCount > 0) {\n <mj-stat-badge [Count]=\"ActiveCount\" Label=\"active\" Variant=\"success\"></mj-stat-badge>\n }\n @if (PausedCount > 0) {\n <mj-stat-badge [Count]=\"PausedCount\" Label=\"paused\" Variant=\"warning\"></mj-stat-badge>\n }\n </div>\n <div actions>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewSchedule()\">\n <i class=\"fa-solid fa-plus\"></i> New Schedule\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search pipelines...\"\n [Value]=\"SearchQuery\"\n (ValueChange)=\"SearchQuery = $event; OnSearchChanged()\">\n </mj-page-search>\n <select class=\"mj-input kh-toolbar-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 </div>\n </mj-page-header>\n\n <mj-page-body>\n <ng-container *ngTemplateOutlet=\"schedulingBody\"></ng-container>\n </mj-page-body>\n</mj-page-layout>\n}\n@if (HideToolbar) {\n <div class=\"embedded-controls\">\n <input\n type=\"text\"\n class=\"mj-input embedded-search\"\n placeholder=\"Search pipelines...\"\n [(ngModel)]=\"SearchQuery\"\n (ngModelChange)=\"OnSearchChanged()\" />\n <select class=\"mj-input kh-toolbar-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 <span class=\"embedded-spacer\"></span>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewSchedule()\">\n <i class=\"fa-solid fa-plus\"></i> New Schedule\n </button>\n </div>\n <ng-container *ngTemplateOutlet=\"schedulingBody\"></ng-container>\n}\n\n<ng-template #schedulingBody>\n@if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading scheduled pipelines...\"></mj-loading>\n </div>\n} @else {\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</ng-template>\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: flex;\n flex-direction: column;\n height: 100%;\n min-width: 0;\n}\n\n/* Embedded mode: inline controls row instead of <mj-page-header>. */\n.embedded-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.embedded-search {\n flex: 1;\n max-width: 320px;\n}\n\n.embedded-spacer {\n flex: 1;\n}\n\n/* Status select used in the [toolbar] slot. */\n.kh-toolbar-select {\n width: auto;\n min-width: 140px;\n min-height: 32px;\n padding: 4px 28px 4px 12px;\n font-size: 0.8125rem;\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"] }]
|
|
665
|
+
args: [{ standalone: false, selector: 'app-scheduling-resource', template: "@if (!HideToolbar) {\n<mj-page-layout>\n <mj-page-header\n Title=\"Knowledge Pipelines\"\n Icon=\"fa-solid fa-calendar-check\"\n Subtitle=\"Scheduled knowledge ingestion, autotagging, and embedding pipelines\">\n <div meta>\n @if (ActiveCount > 0) {\n <mj-stat-badge [Count]=\"ActiveCount\" Label=\"active\" Variant=\"success\"></mj-stat-badge>\n }\n @if (PausedCount > 0) {\n <mj-stat-badge [Count]=\"PausedCount\" Label=\"paused\" Variant=\"warning\"></mj-stat-badge>\n }\n </div>\n <div actions>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewSchedule()\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"action-btn-label\">New Schedule</span>\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search pipelines...\"\n [Value]=\"SearchQuery\"\n (ValueChange)=\"SearchQuery = $event; OnSearchChanged()\">\n </mj-page-search>\n <select class=\"mj-input kh-toolbar-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 </div>\n </mj-page-header>\n\n <mj-page-body>\n <ng-container *ngTemplateOutlet=\"schedulingBody\"></ng-container>\n </mj-page-body>\n</mj-page-layout>\n}\n@if (HideToolbar) {\n <div class=\"embedded-controls\">\n <input\n type=\"text\"\n class=\"mj-input embedded-search\"\n placeholder=\"Search pipelines...\"\n [(ngModel)]=\"SearchQuery\"\n (ngModelChange)=\"OnSearchChanged()\" />\n <select class=\"mj-input kh-toolbar-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 <span class=\"embedded-spacer\"></span>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewSchedule()\">\n <i class=\"fa-solid fa-plus\"></i> New Schedule\n </button>\n </div>\n <ng-container *ngTemplateOutlet=\"schedulingBody\"></ng-container>\n}\n\n<ng-template #schedulingBody>\n@if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading scheduled pipelines...\"></mj-loading>\n </div>\n} @else {\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</ng-template>\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: flex;\n flex-direction: column;\n height: 100%;\n min-width: 0;\n}\n\n/* Embedded mode: inline controls row instead of <mj-page-header>. */\n.embedded-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.embedded-search {\n flex: 1;\n max-width: 320px;\n}\n\n.embedded-spacer {\n flex: 1;\n}\n\n/* Status select used in the [toolbar] slot. */\n.kh-toolbar-select {\n width: auto;\n min-width: 140px;\n min-height: 32px;\n padding: 4px 28px 4px 12px;\n font-size: 0.8125rem;\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"] }]
|
|
665
666
|
}], null, { HideToolbar: [{
|
|
666
667
|
type: Input
|
|
667
668
|
}] }); })();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduling-resource.component.js","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/scheduling/scheduling-resource.component.ts","../../../../src/KnowledgeHub/components/scheduling/scheduling-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Knowledge Hub Scheduled Pipelines Dashboard Tab\n *\n * Full-page resource component for managing scheduled pipelines within the\n * Knowledge Hub application. Displays job cards in a compact grid, recent\n * activity table, and provides create/edit via the reusable\n * ScheduledJobDialogComponent from @memberjunction/ng-scheduling.\n *\n * Registered as BaseResourceComponent for the Knowledge Hub application.\n */\n\nimport { Component, Input, ChangeDetectorRef, OnDestroy, AfterViewInit, inject } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { Metadata, RunView } from '@memberjunction/core';\nimport { ResourceData, MJScheduledJobEntity, MJScheduledJobRunEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { ScheduledJobService, ScheduledJobDialogResult } from '@memberjunction/ng-scheduling';\n\n/** Simple cron-to-English mapping for common patterns */\ninterface CronParts {\n Second: string;\n Minute: string;\n Hour: string;\n DayOfMonth: string;\n Month: string;\n DayOfWeek: string;\n}\n\n@RegisterClass(BaseResourceComponent, 'SchedulingResource')\n@Component({\n standalone: false,\n selector: 'app-scheduling-resource',\n templateUrl: './scheduling-resource.component.html',\n styleUrls: ['./scheduling-resource.component.css'],\n})\nexport class SchedulingResourceComponent extends BaseResourceComponent implements AfterViewInit, OnDestroy {\n /**\n * When true, renders only the body content (no <mj-page-layout> + <mj-page-header>\n * chrome). Used when embedded inside another resource page (e.g. KH Configuration's\n * Scheduling section) so we don't get nested page-layouts that trap click events.\n *\n * Named `HideToolbar` for cross-section consistency with Scheduling/Testing inner\n * components — see plans/explorer-chrome-conventions.md Section 5. The name is\n * narrower than its actual behavior (suppresses entire chrome, not just the toolbar)\n * but matches the documented convention.\n */\n @Input() HideToolbar = false;\n\n private cdr = inject(ChangeDetectorRef);\n protected override navigationService = inject(NavigationService);\n private scheduledJobService = inject(ScheduledJobService);\n protected override destroy$ = new Subject<void>();\n\n // ================================================================\n // Resource overrides\n // ================================================================\n\n async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'Schedules';\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-clock';\n }\n\n // ================================================================\n // State\n // ================================================================\n\n public IsLoading = true;\n public AllJobs: MJScheduledJobEntity[] = [];\n public FilteredJobs: MJScheduledJobEntity[] = [];\n public RecentRuns: MJScheduledJobRunEntity[] = [];\n public StatusFilter = '';\n public SearchQuery = '';\n\n /** Map of jobID -> last 7 run statuses for sparkline display */\n private sparklineCache = new Map<string, string[]>();\n\n // Edit dialog\n public ShowEditDialog = false;\n public EditingJobID: string | null = null;\n\n // ================================================================\n // Computed\n // ================================================================\n\n public get ActiveCount(): number {\n return this.AllJobs.filter(j => j.Status === 'Active').length;\n }\n\n public get PausedCount(): number {\n return this.AllJobs.filter(j => j.Status === 'Paused').length;\n }\n\n public get DisabledCount(): number {\n return this.AllJobs.filter(j => j.Status === 'Disabled').length;\n }\n\n // ================================================================\n // Lifecycle\n // ================================================================\n\n async ngAfterViewInit(): Promise<void> {\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ================================================================\n // Public Methods — Toolbar\n // ================================================================\n\n public OnNewSchedule(): void {\n this.EditingJobID = null;\n this.ShowEditDialog = true;\n this.cdr.detectChanges();\n }\n\n public OnFilterChanged(): void {\n this.applyFilters();\n this.cdr.detectChanges();\n }\n\n public OnSearchChanged(): void {\n this.applyFilters();\n this.cdr.detectChanges();\n }\n\n // ================================================================\n // Public Methods — Card Actions\n // ================================================================\n\n public OnEditJob(job: MJScheduledJobEntity): void {\n this.EditingJobID = job.ID;\n this.ShowEditDialog = true;\n this.cdr.detectChanges();\n }\n\n public async OnRunNow(job: MJScheduledJobEntity): Promise<void> {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Triggering \"${job.Name}\" — this feature requires server-side support.`,\n 'info', 4000\n );\n }\n\n // ================================================================\n // Public Methods — Dialog\n // ================================================================\n\n public async OnDialogClosed(result: ScheduledJobDialogResult): Promise<void> {\n this.ShowEditDialog = false;\n this.EditingJobID = null;\n\n if (result.Saved || result.Deleted) {\n await this.loadData();\n }\n\n this.cdr.detectChanges();\n }\n\n /** Navigate to the full Scheduling application */\n public GoToSchedulingApp(): void {\n const md = this.ProviderToUse;\n const schedulingApp = md.Applications.find(a => a.Name === 'Scheduling');\n if (schedulingApp) {\n this.navigationService.SwitchToApp(schedulingApp.ID);\n } else {\n MJNotificationService.Instance.CreateSimpleNotification(\n 'Scheduling app not found. Check application configuration.',\n 'warning', 3000\n );\n }\n }\n\n // ================================================================\n // Public Methods — Card Display Helpers\n // ================================================================\n\n public GetStatusDotClass(job: MJScheduledJobEntity): string {\n return (job.Status ?? 'pending').toLowerCase();\n }\n\n public GetCronDescription(cron: string): string {\n if (!cron) return 'No schedule';\n const parts = this.parseCron(cron);\n if (!parts) return cron;\n return this.cronToHuman(parts);\n }\n\n public GetSparkline(jobID: string): string[] {\n return this.sparklineCache.get(jobID) ?? [];\n }\n\n public GetTimeAgo(date: Date | null): string {\n if (!date) return 'Never';\n const now = new Date();\n const d = new Date(date);\n const diffMs = now.getTime() - d.getTime();\n return this.formatDuration(diffMs);\n }\n\n public GetTimeUntil(date: Date | null): string {\n if (!date) return '--';\n const now = new Date();\n const d = new Date(date);\n const diffMs = d.getTime() - now.getTime();\n if (diffMs <= 0) return 'Due';\n return this.formatDuration(diffMs);\n }\n\n public GetSuccessRate(job: MJScheduledJobEntity): string {\n if (job.RunCount === 0) return 'N/A';\n return Math.round((job.SuccessCount / job.RunCount) * 100) + '%';\n }\n\n public GetSuccessRateClass(job: MJScheduledJobEntity): string {\n if (job.RunCount === 0) return '';\n const rate = job.SuccessCount / job.RunCount;\n if (rate >= 0.95) return 'high';\n if (rate >= 0.80) return 'mid';\n return '';\n }\n\n public GetDuration(run: MJScheduledJobRunEntity): string {\n if (!run.StartedAt || !run.CompletedAt) return '--';\n const start = new Date(run.StartedAt).getTime();\n const end = new Date(run.CompletedAt).getTime();\n const diffMs = end - start;\n return this.formatDurationShort(diffMs);\n }\n\n public GetItemsProcessed(run: MJScheduledJobRunEntity): string {\n if (!run.Details) return '--';\n try {\n const details = JSON.parse(run.Details) as Record<string, unknown>;\n if (details['ItemsProcessed'] != null) {\n const total = details['TotalItems'] as number | undefined;\n const processed = details['ItemsProcessed'] as number;\n if (run.Status === 'Failed' && total != null) {\n return `${this.formatNumber(processed)} / ${this.formatNumber(total)}`;\n }\n return this.formatNumber(processed);\n }\n } catch {\n // details not parseable\n }\n return '--';\n }\n\n // ================================================================\n // Private Methods\n // ================================================================\n\n private async loadData(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const [jobsResult, runsResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Scheduled Jobs',\n ExtraFilter: `Name LIKE '%Autotag%' OR Name LIKE '%Vector%' OR Name LIKE '%Content%' OR Name LIKE '%Knowledge%' OR Name LIKE '%Tag%'`,\n OrderBy: 'Name',\n ResultType: 'entity_object',\n },\n {\n EntityName: 'MJ: Scheduled Job Runs',\n ExtraFilter: '',\n OrderBy: 'StartedAt DESC',\n MaxRows: 100,\n ResultType: 'entity_object',\n },\n ]);\n\n if (jobsResult.Success) {\n this.AllJobs = jobsResult.Results as MJScheduledJobEntity[];\n } else {\n this.AllJobs = [];\n }\n\n const allRuns = runsResult.Success\n ? (runsResult.Results as MJScheduledJobRunEntity[])\n : [];\n\n this.RecentRuns = allRuns.slice(0, 10);\n this.buildSparklineCache(allRuns);\n this.applyFilters();\n } catch (error) {\n console.error('[SchedulingResource] Error loading data:', error);\n this.AllJobs = [];\n this.FilteredJobs = [];\n this.RecentRuns = [];\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private applyFilters(): void {\n let jobs = this.AllJobs;\n\n if (this.StatusFilter) {\n jobs = jobs.filter(j => j.Status === this.StatusFilter);\n }\n\n if (this.SearchQuery.trim()) {\n const query = this.SearchQuery.trim().toLowerCase();\n jobs = jobs.filter(j =>\n j.Name.toLowerCase().includes(query) ||\n (j.Description ?? '').toLowerCase().includes(query)\n );\n }\n\n this.FilteredJobs = jobs;\n }\n\n /**\n * Build sparkline data for each job from the last 7 runs.\n * Each dot is 'ok', 'fail', or 'skip'.\n */\n private buildSparklineCache(allRuns: MJScheduledJobRunEntity[]): void {\n this.sparklineCache.clear();\n\n // Group runs by job ID\n const runsByJob = new Map<string, MJScheduledJobRunEntity[]>();\n for (const run of allRuns) {\n const jobID = run.ScheduledJobID;\n if (!runsByJob.has(jobID)) {\n runsByJob.set(jobID, []);\n }\n runsByJob.get(jobID)!.push(run);\n }\n\n // Build sparkline for each job (up to 7 most recent runs)\n for (const job of this.AllJobs) {\n const runs = runsByJob.get(job.ID) ?? [];\n const last7 = runs.slice(0, 7);\n const dots: string[] = last7.map(r => this.runStatusToDot(r));\n\n // Pad to 7 with 'skip' dots if fewer runs\n while (dots.length < 7) {\n dots.push('skip');\n }\n\n this.sparklineCache.set(job.ID, dots);\n }\n }\n\n private runStatusToDot(run: MJScheduledJobRunEntity): string {\n if (run.Status === 'Completed' && run.Success) return 'ok';\n if (run.Status === 'Failed' || (run.Status === 'Completed' && !run.Success)) return 'fail';\n if (run.Status === 'Running') return 'ok'; // treat in-progress as OK\n return 'skip';\n }\n\n // ================================================================\n // Cron Parsing\n // ================================================================\n\n private parseCron(cron: string): CronParts | null {\n const parts = cron.trim().split(/\\s+/);\n // Support 5-part (no seconds) and 6-part (with seconds) cron\n if (parts.length === 5) {\n return {\n Second: '0',\n Minute: parts[0],\n Hour: parts[1],\n DayOfMonth: parts[2],\n Month: parts[3],\n DayOfWeek: parts[4],\n };\n }\n if (parts.length === 6) {\n return {\n Second: parts[0],\n Minute: parts[1],\n Hour: parts[2],\n DayOfMonth: parts[3],\n Month: parts[4],\n DayOfWeek: parts[5],\n };\n }\n return null;\n }\n\n private cronToHuman(p: CronParts): string {\n // Every N minutes: */N * * * *\n if (p.Minute.startsWith('*/') && p.Hour === '*' && p.DayOfMonth === '*' && p.Month === '*' && p.DayOfWeek === '*') {\n const interval = parseInt(p.Minute.slice(2), 10);\n if (interval === 1) return 'Every minute';\n return `Every ${interval} minutes`;\n }\n\n // Every N hours: 0 */N * * *\n if (p.Minute !== '*' && !p.Minute.includes('/') && p.Hour.startsWith('*/') && p.DayOfMonth === '*') {\n const interval = parseInt(p.Hour.slice(2), 10);\n if (interval === 1) return 'Every hour';\n return `Every ${interval} hours`;\n }\n\n // Specific hour with specific or wildcard day fields\n if (!p.Minute.includes('*') && !p.Minute.includes('/') &&\n !p.Hour.includes('*') && !p.Hour.includes('/') &&\n p.Month === '*') {\n\n const hour = parseInt(p.Hour, 10);\n const minute = parseInt(p.Minute, 10);\n const timeStr = this.formatTime(hour, minute);\n\n // Weekly: specific day of week\n if (p.DayOfWeek !== '*' && p.DayOfMonth === '*') {\n const dayName = this.dayOfWeekName(p.DayOfWeek);\n return `Weekly on ${dayName} at ${timeStr}`;\n }\n\n // Monthly: specific day of month\n if (p.DayOfMonth !== '*' && p.DayOfWeek === '*') {\n return `Monthly on day ${p.DayOfMonth} at ${timeStr}`;\n }\n\n // Daily\n if (p.DayOfMonth === '*' && p.DayOfWeek === '*') {\n return `Daily at ${timeStr}`;\n }\n }\n\n // Fallback: return the raw cron expression\n return `${p.Minute} ${p.Hour} ${p.DayOfMonth} ${p.Month} ${p.DayOfWeek}`;\n }\n\n private formatTime(hour: number, minute: number): string {\n const ampm = hour >= 12 ? 'PM' : 'AM';\n const h = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;\n const m = minute.toString().padStart(2, '0');\n return `${h}:${m} ${ampm}`;\n }\n\n private dayOfWeekName(dow: string): string {\n const names: Record<string, string> = {\n '0': 'Sunday', '1': 'Monday', '2': 'Tuesday',\n '3': 'Wednesday', '4': 'Thursday', '5': 'Friday',\n '6': 'Saturday', '7': 'Sunday',\n 'SUN': 'Sunday', 'MON': 'Monday', 'TUE': 'Tuesday',\n 'WED': 'Wednesday', 'THU': 'Thursday', 'FRI': 'Friday',\n 'SAT': 'Saturday',\n };\n return names[dow.toUpperCase()] ?? dow;\n }\n\n // ================================================================\n // Formatting Helpers\n // ================================================================\n\n private formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 0) return `${days}d ago`;\n if (hours > 0) return `${hours}h ago`;\n if (minutes > 0) return `${minutes}m ago`;\n return 'Just now';\n }\n\n private formatDurationShort(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n\n if (minutes >= 60) {\n const hours = Math.floor(minutes / 60);\n const remainMinutes = minutes % 60;\n return `${hours}h ${remainMinutes}m`;\n }\n return `${minutes}m ${seconds.toString().padStart(2, '0')}s`;\n }\n\n private formatNumber(n: number): string {\n return n.toLocaleString();\n }\n}\n\n/** Tree-shaking prevention */\nexport function LoadSchedulingResource(): void {\n // Prevents tree-shaking of the component\n}\n","@if (!HideToolbar) {\n<mj-page-layout>\n <mj-page-header\n Title=\"Knowledge Pipelines\"\n Icon=\"fa-solid fa-calendar-check\"\n Subtitle=\"Scheduled knowledge ingestion, autotagging, and embedding pipelines\">\n <div meta>\n @if (ActiveCount > 0) {\n <mj-stat-badge [Count]=\"ActiveCount\" Label=\"active\" Variant=\"success\"></mj-stat-badge>\n }\n @if (PausedCount > 0) {\n <mj-stat-badge [Count]=\"PausedCount\" Label=\"paused\" Variant=\"warning\"></mj-stat-badge>\n }\n </div>\n <div actions>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewSchedule()\">\n <i class=\"fa-solid fa-plus\"></i> New Schedule\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search pipelines...\"\n [Value]=\"SearchQuery\"\n (ValueChange)=\"SearchQuery = $event; OnSearchChanged()\">\n </mj-page-search>\n <select class=\"mj-input kh-toolbar-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 </div>\n </mj-page-header>\n\n <mj-page-body>\n <ng-container *ngTemplateOutlet=\"schedulingBody\"></ng-container>\n </mj-page-body>\n</mj-page-layout>\n}\n@if (HideToolbar) {\n <div class=\"embedded-controls\">\n <input\n type=\"text\"\n class=\"mj-input embedded-search\"\n placeholder=\"Search pipelines...\"\n [(ngModel)]=\"SearchQuery\"\n (ngModelChange)=\"OnSearchChanged()\" />\n <select class=\"mj-input kh-toolbar-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 <span class=\"embedded-spacer\"></span>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewSchedule()\">\n <i class=\"fa-solid fa-plus\"></i> New Schedule\n </button>\n </div>\n <ng-container *ngTemplateOutlet=\"schedulingBody\"></ng-container>\n}\n\n<ng-template #schedulingBody>\n@if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading scheduled pipelines...\"></mj-loading>\n </div>\n} @else {\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</ng-template>\n"]}
|
|
1
|
+
{"version":3,"file":"scheduling-resource.component.js","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/scheduling/scheduling-resource.component.ts","../../../../src/KnowledgeHub/components/scheduling/scheduling-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Knowledge Hub Scheduled Pipelines Dashboard Tab\n *\n * Full-page resource component for managing scheduled pipelines within the\n * Knowledge Hub application. Displays job cards in a compact grid, recent\n * activity table, and provides create/edit via the reusable\n * ScheduledJobDialogComponent from @memberjunction/ng-scheduling.\n *\n * Registered as BaseResourceComponent for the Knowledge Hub application.\n */\n\nimport { Component, Input, ChangeDetectorRef, OnDestroy, AfterViewInit, inject } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { Metadata, RunView } from '@memberjunction/core';\nimport { ResourceData, MJScheduledJobEntity, MJScheduledJobRunEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { ScheduledJobService, ScheduledJobDialogResult } from '@memberjunction/ng-scheduling';\n\n/** Simple cron-to-English mapping for common patterns */\ninterface CronParts {\n Second: string;\n Minute: string;\n Hour: string;\n DayOfMonth: string;\n Month: string;\n DayOfWeek: string;\n}\n\n@RegisterClass(BaseResourceComponent, 'SchedulingResource')\n@Component({\n standalone: false,\n selector: 'app-scheduling-resource',\n templateUrl: './scheduling-resource.component.html',\n styleUrls: ['./scheduling-resource.component.css'],\n})\nexport class SchedulingResourceComponent extends BaseResourceComponent implements AfterViewInit, OnDestroy {\n /**\n * When true, renders only the body content (no <mj-page-layout> + <mj-page-header>\n * chrome). Used when embedded inside another resource page (e.g. KH Configuration's\n * Scheduling section) so we don't get nested page-layouts that trap click events.\n *\n * Named `HideToolbar` for cross-section consistency with Scheduling/Testing inner\n * components — see plans/explorer-chrome-conventions.md Section 5. The name is\n * narrower than its actual behavior (suppresses entire chrome, not just the toolbar)\n * but matches the documented convention.\n */\n @Input() HideToolbar = false;\n\n private cdr = inject(ChangeDetectorRef);\n protected override navigationService = inject(NavigationService);\n private scheduledJobService = inject(ScheduledJobService);\n protected override destroy$ = new Subject<void>();\n\n // ================================================================\n // Resource overrides\n // ================================================================\n\n async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'Schedules';\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-clock';\n }\n\n // ================================================================\n // State\n // ================================================================\n\n public IsLoading = true;\n public AllJobs: MJScheduledJobEntity[] = [];\n public FilteredJobs: MJScheduledJobEntity[] = [];\n public RecentRuns: MJScheduledJobRunEntity[] = [];\n public StatusFilter = '';\n public SearchQuery = '';\n\n /** Map of jobID -> last 7 run statuses for sparkline display */\n private sparklineCache = new Map<string, string[]>();\n\n // Edit dialog\n public ShowEditDialog = false;\n public EditingJobID: string | null = null;\n\n // ================================================================\n // Computed\n // ================================================================\n\n public get ActiveCount(): number {\n return this.AllJobs.filter(j => j.Status === 'Active').length;\n }\n\n public get PausedCount(): number {\n return this.AllJobs.filter(j => j.Status === 'Paused').length;\n }\n\n public get DisabledCount(): number {\n return this.AllJobs.filter(j => j.Status === 'Disabled').length;\n }\n\n // ================================================================\n // Lifecycle\n // ================================================================\n\n async ngAfterViewInit(): Promise<void> {\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ================================================================\n // Public Methods — Toolbar\n // ================================================================\n\n public OnNewSchedule(): void {\n this.EditingJobID = null;\n this.ShowEditDialog = true;\n this.cdr.detectChanges();\n }\n\n public OnFilterChanged(): void {\n this.applyFilters();\n this.cdr.detectChanges();\n }\n\n public OnSearchChanged(): void {\n this.applyFilters();\n this.cdr.detectChanges();\n }\n\n // ================================================================\n // Public Methods — Card Actions\n // ================================================================\n\n public OnEditJob(job: MJScheduledJobEntity): void {\n this.EditingJobID = job.ID;\n this.ShowEditDialog = true;\n this.cdr.detectChanges();\n }\n\n public async OnRunNow(job: MJScheduledJobEntity): Promise<void> {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Triggering \"${job.Name}\" — this feature requires server-side support.`,\n 'info', 4000\n );\n }\n\n // ================================================================\n // Public Methods — Dialog\n // ================================================================\n\n public async OnDialogClosed(result: ScheduledJobDialogResult): Promise<void> {\n this.ShowEditDialog = false;\n this.EditingJobID = null;\n\n if (result.Saved || result.Deleted) {\n await this.loadData();\n }\n\n this.cdr.detectChanges();\n }\n\n /** Navigate to the full Scheduling application */\n public GoToSchedulingApp(): void {\n const md = this.ProviderToUse;\n const schedulingApp = md.Applications.find(a => a.Name === 'Scheduling');\n if (schedulingApp) {\n this.navigationService.SwitchToApp(schedulingApp.ID);\n } else {\n MJNotificationService.Instance.CreateSimpleNotification(\n 'Scheduling app not found. Check application configuration.',\n 'warning', 3000\n );\n }\n }\n\n // ================================================================\n // Public Methods — Card Display Helpers\n // ================================================================\n\n public GetStatusDotClass(job: MJScheduledJobEntity): string {\n return (job.Status ?? 'pending').toLowerCase();\n }\n\n public GetCronDescription(cron: string): string {\n if (!cron) return 'No schedule';\n const parts = this.parseCron(cron);\n if (!parts) return cron;\n return this.cronToHuman(parts);\n }\n\n public GetSparkline(jobID: string): string[] {\n return this.sparklineCache.get(jobID) ?? [];\n }\n\n public GetTimeAgo(date: Date | null): string {\n if (!date) return 'Never';\n const now = new Date();\n const d = new Date(date);\n const diffMs = now.getTime() - d.getTime();\n return this.formatDuration(diffMs);\n }\n\n public GetTimeUntil(date: Date | null): string {\n if (!date) return '--';\n const now = new Date();\n const d = new Date(date);\n const diffMs = d.getTime() - now.getTime();\n if (diffMs <= 0) return 'Due';\n return this.formatDuration(diffMs);\n }\n\n public GetSuccessRate(job: MJScheduledJobEntity): string {\n if (job.RunCount === 0) return 'N/A';\n return Math.round((job.SuccessCount / job.RunCount) * 100) + '%';\n }\n\n public GetSuccessRateClass(job: MJScheduledJobEntity): string {\n if (job.RunCount === 0) return '';\n const rate = job.SuccessCount / job.RunCount;\n if (rate >= 0.95) return 'high';\n if (rate >= 0.80) return 'mid';\n return '';\n }\n\n public GetDuration(run: MJScheduledJobRunEntity): string {\n if (!run.StartedAt || !run.CompletedAt) return '--';\n const start = new Date(run.StartedAt).getTime();\n const end = new Date(run.CompletedAt).getTime();\n const diffMs = end - start;\n return this.formatDurationShort(diffMs);\n }\n\n public GetItemsProcessed(run: MJScheduledJobRunEntity): string {\n if (!run.Details) return '--';\n try {\n const details = JSON.parse(run.Details) as Record<string, unknown>;\n if (details['ItemsProcessed'] != null) {\n const total = details['TotalItems'] as number | undefined;\n const processed = details['ItemsProcessed'] as number;\n if (run.Status === 'Failed' && total != null) {\n return `${this.formatNumber(processed)} / ${this.formatNumber(total)}`;\n }\n return this.formatNumber(processed);\n }\n } catch {\n // details not parseable\n }\n return '--';\n }\n\n // ================================================================\n // Private Methods\n // ================================================================\n\n private async loadData(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const [jobsResult, runsResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Scheduled Jobs',\n ExtraFilter: `Name LIKE '%Autotag%' OR Name LIKE '%Vector%' OR Name LIKE '%Content%' OR Name LIKE '%Knowledge%' OR Name LIKE '%Tag%'`,\n OrderBy: 'Name',\n ResultType: 'entity_object',\n },\n {\n EntityName: 'MJ: Scheduled Job Runs',\n ExtraFilter: '',\n OrderBy: 'StartedAt DESC',\n MaxRows: 100,\n ResultType: 'entity_object',\n },\n ]);\n\n if (jobsResult.Success) {\n this.AllJobs = jobsResult.Results as MJScheduledJobEntity[];\n } else {\n this.AllJobs = [];\n }\n\n const allRuns = runsResult.Success\n ? (runsResult.Results as MJScheduledJobRunEntity[])\n : [];\n\n this.RecentRuns = allRuns.slice(0, 10);\n this.buildSparklineCache(allRuns);\n this.applyFilters();\n } catch (error) {\n console.error('[SchedulingResource] Error loading data:', error);\n this.AllJobs = [];\n this.FilteredJobs = [];\n this.RecentRuns = [];\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private applyFilters(): void {\n let jobs = this.AllJobs;\n\n if (this.StatusFilter) {\n jobs = jobs.filter(j => j.Status === this.StatusFilter);\n }\n\n if (this.SearchQuery.trim()) {\n const query = this.SearchQuery.trim().toLowerCase();\n jobs = jobs.filter(j =>\n j.Name.toLowerCase().includes(query) ||\n (j.Description ?? '').toLowerCase().includes(query)\n );\n }\n\n this.FilteredJobs = jobs;\n }\n\n /**\n * Build sparkline data for each job from the last 7 runs.\n * Each dot is 'ok', 'fail', or 'skip'.\n */\n private buildSparklineCache(allRuns: MJScheduledJobRunEntity[]): void {\n this.sparklineCache.clear();\n\n // Group runs by job ID\n const runsByJob = new Map<string, MJScheduledJobRunEntity[]>();\n for (const run of allRuns) {\n const jobID = run.ScheduledJobID;\n if (!runsByJob.has(jobID)) {\n runsByJob.set(jobID, []);\n }\n runsByJob.get(jobID)!.push(run);\n }\n\n // Build sparkline for each job (up to 7 most recent runs)\n for (const job of this.AllJobs) {\n const runs = runsByJob.get(job.ID) ?? [];\n const last7 = runs.slice(0, 7);\n const dots: string[] = last7.map(r => this.runStatusToDot(r));\n\n // Pad to 7 with 'skip' dots if fewer runs\n while (dots.length < 7) {\n dots.push('skip');\n }\n\n this.sparklineCache.set(job.ID, dots);\n }\n }\n\n private runStatusToDot(run: MJScheduledJobRunEntity): string {\n if (run.Status === 'Completed' && run.Success) return 'ok';\n if (run.Status === 'Failed' || (run.Status === 'Completed' && !run.Success)) return 'fail';\n if (run.Status === 'Running') return 'ok'; // treat in-progress as OK\n return 'skip';\n }\n\n // ================================================================\n // Cron Parsing\n // ================================================================\n\n private parseCron(cron: string): CronParts | null {\n const parts = cron.trim().split(/\\s+/);\n // Support 5-part (no seconds) and 6-part (with seconds) cron\n if (parts.length === 5) {\n return {\n Second: '0',\n Minute: parts[0],\n Hour: parts[1],\n DayOfMonth: parts[2],\n Month: parts[3],\n DayOfWeek: parts[4],\n };\n }\n if (parts.length === 6) {\n return {\n Second: parts[0],\n Minute: parts[1],\n Hour: parts[2],\n DayOfMonth: parts[3],\n Month: parts[4],\n DayOfWeek: parts[5],\n };\n }\n return null;\n }\n\n private cronToHuman(p: CronParts): string {\n // Every N minutes: */N * * * *\n if (p.Minute.startsWith('*/') && p.Hour === '*' && p.DayOfMonth === '*' && p.Month === '*' && p.DayOfWeek === '*') {\n const interval = parseInt(p.Minute.slice(2), 10);\n if (interval === 1) return 'Every minute';\n return `Every ${interval} minutes`;\n }\n\n // Every N hours: 0 */N * * *\n if (p.Minute !== '*' && !p.Minute.includes('/') && p.Hour.startsWith('*/') && p.DayOfMonth === '*') {\n const interval = parseInt(p.Hour.slice(2), 10);\n if (interval === 1) return 'Every hour';\n return `Every ${interval} hours`;\n }\n\n // Specific hour with specific or wildcard day fields\n if (!p.Minute.includes('*') && !p.Minute.includes('/') &&\n !p.Hour.includes('*') && !p.Hour.includes('/') &&\n p.Month === '*') {\n\n const hour = parseInt(p.Hour, 10);\n const minute = parseInt(p.Minute, 10);\n const timeStr = this.formatTime(hour, minute);\n\n // Weekly: specific day of week\n if (p.DayOfWeek !== '*' && p.DayOfMonth === '*') {\n const dayName = this.dayOfWeekName(p.DayOfWeek);\n return `Weekly on ${dayName} at ${timeStr}`;\n }\n\n // Monthly: specific day of month\n if (p.DayOfMonth !== '*' && p.DayOfWeek === '*') {\n return `Monthly on day ${p.DayOfMonth} at ${timeStr}`;\n }\n\n // Daily\n if (p.DayOfMonth === '*' && p.DayOfWeek === '*') {\n return `Daily at ${timeStr}`;\n }\n }\n\n // Fallback: return the raw cron expression\n return `${p.Minute} ${p.Hour} ${p.DayOfMonth} ${p.Month} ${p.DayOfWeek}`;\n }\n\n private formatTime(hour: number, minute: number): string {\n const ampm = hour >= 12 ? 'PM' : 'AM';\n const h = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;\n const m = minute.toString().padStart(2, '0');\n return `${h}:${m} ${ampm}`;\n }\n\n private dayOfWeekName(dow: string): string {\n const names: Record<string, string> = {\n '0': 'Sunday', '1': 'Monday', '2': 'Tuesday',\n '3': 'Wednesday', '4': 'Thursday', '5': 'Friday',\n '6': 'Saturday', '7': 'Sunday',\n 'SUN': 'Sunday', 'MON': 'Monday', 'TUE': 'Tuesday',\n 'WED': 'Wednesday', 'THU': 'Thursday', 'FRI': 'Friday',\n 'SAT': 'Saturday',\n };\n return names[dow.toUpperCase()] ?? dow;\n }\n\n // ================================================================\n // Formatting Helpers\n // ================================================================\n\n private formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 0) return `${days}d ago`;\n if (hours > 0) return `${hours}h ago`;\n if (minutes > 0) return `${minutes}m ago`;\n return 'Just now';\n }\n\n private formatDurationShort(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n\n if (minutes >= 60) {\n const hours = Math.floor(minutes / 60);\n const remainMinutes = minutes % 60;\n return `${hours}h ${remainMinutes}m`;\n }\n return `${minutes}m ${seconds.toString().padStart(2, '0')}s`;\n }\n\n private formatNumber(n: number): string {\n return n.toLocaleString();\n }\n}\n\n/** Tree-shaking prevention */\nexport function LoadSchedulingResource(): void {\n // Prevents tree-shaking of the component\n}\n","@if (!HideToolbar) {\n<mj-page-layout>\n <mj-page-header\n Title=\"Knowledge Pipelines\"\n Icon=\"fa-solid fa-calendar-check\"\n Subtitle=\"Scheduled knowledge ingestion, autotagging, and embedding pipelines\">\n <div meta>\n @if (ActiveCount > 0) {\n <mj-stat-badge [Count]=\"ActiveCount\" Label=\"active\" Variant=\"success\"></mj-stat-badge>\n }\n @if (PausedCount > 0) {\n <mj-stat-badge [Count]=\"PausedCount\" Label=\"paused\" Variant=\"warning\"></mj-stat-badge>\n }\n </div>\n <div actions>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewSchedule()\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"action-btn-label\">New Schedule</span>\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search pipelines...\"\n [Value]=\"SearchQuery\"\n (ValueChange)=\"SearchQuery = $event; OnSearchChanged()\">\n </mj-page-search>\n <select class=\"mj-input kh-toolbar-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 </div>\n </mj-page-header>\n\n <mj-page-body>\n <ng-container *ngTemplateOutlet=\"schedulingBody\"></ng-container>\n </mj-page-body>\n</mj-page-layout>\n}\n@if (HideToolbar) {\n <div class=\"embedded-controls\">\n <input\n type=\"text\"\n class=\"mj-input embedded-search\"\n placeholder=\"Search pipelines...\"\n [(ngModel)]=\"SearchQuery\"\n (ngModelChange)=\"OnSearchChanged()\" />\n <select class=\"mj-input kh-toolbar-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 <span class=\"embedded-spacer\"></span>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewSchedule()\">\n <i class=\"fa-solid fa-plus\"></i> New Schedule\n </button>\n </div>\n <ng-container *ngTemplateOutlet=\"schedulingBody\"></ng-container>\n}\n\n<ng-template #schedulingBody>\n@if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading scheduled pipelines...\"></mj-loading>\n </div>\n} @else {\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</ng-template>\n"]}
|