@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
|
@@ -20,7 +20,7 @@ function SchedulingJobsComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
|
20
20
|
const content_r1 = i0.ɵɵreference(3);
|
|
21
21
|
i0.ɵɵproperty("ngTemplateOutlet", content_r1);
|
|
22
22
|
} }
|
|
23
|
-
function
|
|
23
|
+
function SchedulingJobsComponent_Conditional_1_ng_container_15_Template(rf, ctx) { if (rf & 1) {
|
|
24
24
|
i0.ɵɵelementContainer(0);
|
|
25
25
|
} }
|
|
26
26
|
function SchedulingJobsComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -28,42 +28,43 @@ function SchedulingJobsComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
|
28
28
|
i0.ɵɵelementStart(0, "mj-page-layout")(1, "mj-page-header", 2)(2, "div", 3);
|
|
29
29
|
i0.ɵɵelement(3, "mj-stat-badge", 4);
|
|
30
30
|
i0.ɵɵelementEnd();
|
|
31
|
-
i0.ɵɵelementStart(4, "div", 5)(5, "mj-
|
|
32
|
-
i0.ɵɵlistener("
|
|
33
|
-
i0.ɵɵelementStart(6, "mj-filter-panel", 7);
|
|
34
|
-
i0.ɵɵlistener("ValuesChange", function SchedulingJobsComponent_Conditional_1_Template_mj_filter_panel_ValuesChange_6_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFilterValuesChange($event)); })("Reset", function SchedulingJobsComponent_Conditional_1_Template_mj_filter_panel_Reset_6_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ResetFilters()); });
|
|
35
|
-
i0.ɵɵelementEnd()();
|
|
36
|
-
i0.ɵɵelementStart(7, "mj-refresh-button", 8);
|
|
37
|
-
i0.ɵɵlistener("Clicked", function SchedulingJobsComponent_Conditional_1_Template_mj_refresh_button_Clicked_7_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.Refresh()); });
|
|
31
|
+
i0.ɵɵelementStart(4, "div", 5)(5, "mj-refresh-button", 6);
|
|
32
|
+
i0.ɵɵlistener("Clicked", function SchedulingJobsComponent_Conditional_1_Template_mj_refresh_button_Clicked_5_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.Refresh()); });
|
|
38
33
|
i0.ɵɵelementEnd();
|
|
39
|
-
i0.ɵɵelementStart(
|
|
40
|
-
i0.ɵɵlistener("click", function
|
|
41
|
-
i0.ɵɵelement(
|
|
42
|
-
i0.ɵɵ
|
|
43
|
-
i0.ɵɵ
|
|
44
|
-
i0.ɵɵelementStart(11, "div", 11)(12, "mj-page-search", 12);
|
|
45
|
-
i0.ɵɵlistener("ValueChange", function SchedulingJobsComponent_Conditional_1_Template_mj_page_search_ValueChange_12_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnSearchChange($event)); });
|
|
34
|
+
i0.ɵɵelementStart(6, "button", 7);
|
|
35
|
+
i0.ɵɵlistener("click", function SchedulingJobsComponent_Conditional_1_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenCreateSlideout()); });
|
|
36
|
+
i0.ɵɵelement(7, "i", 8);
|
|
37
|
+
i0.ɵɵelementStart(8, "span", 9);
|
|
38
|
+
i0.ɵɵtext(9, "New Job");
|
|
46
39
|
i0.ɵɵelementEnd()()();
|
|
47
|
-
i0.ɵɵelementStart(
|
|
48
|
-
i0.ɵɵ
|
|
40
|
+
i0.ɵɵelementStart(10, "div", 10)(11, "mj-page-search", 11);
|
|
41
|
+
i0.ɵɵlistener("ValueChange", function SchedulingJobsComponent_Conditional_1_Template_mj_page_search_ValueChange_11_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnSearchChange($event)); });
|
|
42
|
+
i0.ɵɵelementEnd();
|
|
43
|
+
i0.ɵɵelementStart(12, "mj-filter-popover", 12);
|
|
44
|
+
i0.ɵɵlistener("ClearAllRequested", function SchedulingJobsComponent_Conditional_1_Template_mj_filter_popover_ClearAllRequested_12_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ResetFilters()); });
|
|
45
|
+
i0.ɵɵelementStart(13, "mj-filter-panel", 13);
|
|
46
|
+
i0.ɵɵlistener("ValuesChange", function SchedulingJobsComponent_Conditional_1_Template_mj_filter_panel_ValuesChange_13_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFilterValuesChange($event)); })("Reset", function SchedulingJobsComponent_Conditional_1_Template_mj_filter_panel_Reset_13_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ResetFilters()); });
|
|
47
|
+
i0.ɵɵelementEnd()()()();
|
|
48
|
+
i0.ɵɵelementStart(14, "mj-page-body");
|
|
49
|
+
i0.ɵɵtemplate(15, SchedulingJobsComponent_Conditional_1_ng_container_15_Template, 1, 0, "ng-container", 1);
|
|
49
50
|
i0.ɵɵelementEnd()();
|
|
50
51
|
} if (rf & 2) {
|
|
51
52
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
52
53
|
const content_r1 = i0.ɵɵreference(3);
|
|
53
54
|
i0.ɵɵadvance(3);
|
|
54
55
|
i0.ɵɵproperty("Count", ctx_r2.FilteredJobs.length)("Total", ctx_r2.Jobs.length);
|
|
55
|
-
i0.ɵɵadvance(
|
|
56
|
+
i0.ɵɵadvance(8);
|
|
57
|
+
i0.ɵɵproperty("Value", ctx_r2.SearchTerm);
|
|
58
|
+
i0.ɵɵadvance();
|
|
56
59
|
i0.ɵɵproperty("ActiveCount", ctx_r2.ActiveFilterCount)("ShowClearAll", ctx_r2.ActiveFilterCount > 0);
|
|
57
60
|
i0.ɵɵadvance();
|
|
58
61
|
i0.ɵɵproperty("Fields", ctx_r2.JobsFilterFields)("Values", ctx_r2.JobsFilterValues);
|
|
59
|
-
i0.ɵɵadvance(6);
|
|
60
|
-
i0.ɵɵproperty("Value", ctx_r2.SearchTerm);
|
|
61
62
|
i0.ɵɵadvance(2);
|
|
62
63
|
i0.ɵɵproperty("ngTemplateOutlet", content_r1);
|
|
63
64
|
} }
|
|
64
65
|
function SchedulingJobsComponent_ng_template_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
65
|
-
i0.ɵɵelementStart(0, "div",
|
|
66
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
66
|
+
i0.ɵɵelementStart(0, "div", 15);
|
|
67
|
+
i0.ɵɵelement(1, "mj-loading", 19);
|
|
67
68
|
i0.ɵɵelementEnd();
|
|
68
69
|
} }
|
|
69
70
|
function SchedulingJobsComponent_ng_template_2_Conditional_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -78,22 +79,22 @@ function SchedulingJobsComponent_ng_template_2_Conditional_2_Conditional_6_Templ
|
|
|
78
79
|
} }
|
|
79
80
|
function SchedulingJobsComponent_ng_template_2_Conditional_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
80
81
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
81
|
-
i0.ɵɵelementStart(0, "button",
|
|
82
|
+
i0.ɵɵelementStart(0, "button", 23);
|
|
82
83
|
i0.ɵɵlistener("click", function SchedulingJobsComponent_ng_template_2_Conditional_2_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenCreateSlideout()); });
|
|
83
|
-
i0.ɵɵelement(1, "i",
|
|
84
|
+
i0.ɵɵelement(1, "i", 8);
|
|
84
85
|
i0.ɵɵtext(2, " Create Job ");
|
|
85
86
|
i0.ɵɵelementEnd();
|
|
86
87
|
} }
|
|
87
88
|
function SchedulingJobsComponent_ng_template_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
88
|
-
i0.ɵɵelementStart(0, "div",
|
|
89
|
-
i0.ɵɵelement(2, "i",
|
|
89
|
+
i0.ɵɵelementStart(0, "div", 16)(1, "div", 20);
|
|
90
|
+
i0.ɵɵelement(2, "i", 21);
|
|
90
91
|
i0.ɵɵelementEnd();
|
|
91
92
|
i0.ɵɵelementStart(3, "h3");
|
|
92
93
|
i0.ɵɵtext(4, "No jobs found");
|
|
93
94
|
i0.ɵɵelementEnd();
|
|
94
95
|
i0.ɵɵconditionalCreate(5, SchedulingJobsComponent_ng_template_2_Conditional_2_Conditional_5_Template, 2, 0, "p");
|
|
95
96
|
i0.ɵɵconditionalCreate(6, SchedulingJobsComponent_ng_template_2_Conditional_2_Conditional_6_Template, 2, 0, "p");
|
|
96
|
-
i0.ɵɵconditionalCreate(7, SchedulingJobsComponent_ng_template_2_Conditional_2_Conditional_7_Template, 3, 0, "button",
|
|
97
|
+
i0.ɵɵconditionalCreate(7, SchedulingJobsComponent_ng_template_2_Conditional_2_Conditional_7_Template, 3, 0, "button", 22);
|
|
97
98
|
i0.ɵɵelementEnd();
|
|
98
99
|
} if (rf & 2) {
|
|
99
100
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
@@ -105,7 +106,7 @@ function SchedulingJobsComponent_ng_template_2_Conditional_2_Template(rf, ctx) {
|
|
|
105
106
|
i0.ɵɵconditional(!ctx_r2.SearchTerm && !ctx_r2.StatusFilter && !ctx_r2.TypeFilter ? 7 : -1);
|
|
106
107
|
} }
|
|
107
108
|
function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
108
|
-
i0.ɵɵelementStart(0, "div",
|
|
109
|
+
i0.ɵɵelementStart(0, "div", 32);
|
|
109
110
|
i0.ɵɵtext(1);
|
|
110
111
|
i0.ɵɵelementEnd();
|
|
111
112
|
} if (rf & 2) {
|
|
@@ -114,7 +115,7 @@ function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_9
|
|
|
114
115
|
i0.ɵɵtextInterpolate(job_r7.description);
|
|
115
116
|
} }
|
|
116
117
|
function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_48_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
117
|
-
i0.ɵɵelement(0, "i",
|
|
118
|
+
i0.ɵɵelement(0, "i", 63);
|
|
118
119
|
i0.ɵɵtext(1, " Deleting... ");
|
|
119
120
|
} }
|
|
120
121
|
function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_48_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -122,18 +123,18 @@ function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_4
|
|
|
122
123
|
} }
|
|
123
124
|
function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_48_Template(rf, ctx) { if (rf & 1) {
|
|
124
125
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
125
|
-
i0.ɵɵelementStart(0, "div",
|
|
126
|
+
i0.ɵɵelementStart(0, "div", 56);
|
|
126
127
|
i0.ɵɵlistener("click", function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_48_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r8); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
127
|
-
i0.ɵɵelementStart(1, "div",
|
|
128
|
-
i0.ɵɵelement(2, "i",
|
|
129
|
-
i0.ɵɵelementStart(3, "span",
|
|
128
|
+
i0.ɵɵelementStart(1, "div", 57);
|
|
129
|
+
i0.ɵɵelement(2, "i", 58);
|
|
130
|
+
i0.ɵɵelementStart(3, "span", 59);
|
|
130
131
|
i0.ɵɵtext(4, "Delete this scheduled job?");
|
|
131
132
|
i0.ɵɵelementEnd();
|
|
132
|
-
i0.ɵɵelementStart(5, "div",
|
|
133
|
+
i0.ɵɵelementStart(5, "div", 60)(6, "button", 61);
|
|
133
134
|
i0.ɵɵlistener("click", function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_48_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(_r8); const job_r7 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.ConfirmDelete(job_r7.jobId, $event)); });
|
|
134
135
|
i0.ɵɵconditionalCreate(7, SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_48_Conditional_7_Template, 2, 0)(8, SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_48_Conditional_8_Template, 1, 0);
|
|
135
136
|
i0.ɵɵelementEnd();
|
|
136
|
-
i0.ɵɵelementStart(9, "button",
|
|
137
|
+
i0.ɵɵelementStart(9, "button", 62);
|
|
137
138
|
i0.ɵɵlistener("click", function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_48_Template_button_click_9_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.CancelDelete($event)); });
|
|
138
139
|
i0.ɵɵtext(10, "Cancel");
|
|
139
140
|
i0.ɵɵelementEnd()()()();
|
|
@@ -146,76 +147,76 @@ function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_4
|
|
|
146
147
|
} }
|
|
147
148
|
function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
148
149
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
149
|
-
i0.ɵɵelementStart(0, "div",
|
|
150
|
+
i0.ɵɵelementStart(0, "div", 25);
|
|
150
151
|
i0.ɵɵlistener("click", function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Template_div_click_0_listener() { const job_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenEditSlideout(job_r7)); });
|
|
151
|
-
i0.ɵɵelementStart(1, "div",
|
|
152
|
-
i0.ɵɵelement(3, "i",
|
|
153
|
-
i0.ɵɵelementStart(4, "span",
|
|
152
|
+
i0.ɵɵelementStart(1, "div", 26)(2, "div", 27);
|
|
153
|
+
i0.ɵɵelement(3, "i", 28);
|
|
154
|
+
i0.ɵɵelementStart(4, "span", 29);
|
|
154
155
|
i0.ɵɵtext(5);
|
|
155
156
|
i0.ɵɵelementEnd()();
|
|
156
|
-
i0.ɵɵelementStart(6, "span",
|
|
157
|
+
i0.ɵɵelementStart(6, "span", 30);
|
|
157
158
|
i0.ɵɵtext(7);
|
|
158
159
|
i0.ɵɵelementEnd()();
|
|
159
|
-
i0.ɵɵelementStart(8, "div",
|
|
160
|
-
i0.ɵɵconditionalCreate(9, SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_9_Template, 2, 1, "div",
|
|
161
|
-
i0.ɵɵelementStart(10, "div",
|
|
160
|
+
i0.ɵɵelementStart(8, "div", 31);
|
|
161
|
+
i0.ɵɵconditionalCreate(9, SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_9_Template, 2, 1, "div", 32);
|
|
162
|
+
i0.ɵɵelementStart(10, "div", 33)(11, "div", 34)(12, "span", 35);
|
|
162
163
|
i0.ɵɵtext(13, "Type");
|
|
163
164
|
i0.ɵɵelementEnd();
|
|
164
|
-
i0.ɵɵelementStart(14, "span",
|
|
165
|
+
i0.ɵɵelementStart(14, "span", 36);
|
|
165
166
|
i0.ɵɵtext(15);
|
|
166
167
|
i0.ɵɵelementEnd()();
|
|
167
|
-
i0.ɵɵelementStart(16, "div",
|
|
168
|
+
i0.ɵɵelementStart(16, "div", 34)(17, "span", 35);
|
|
168
169
|
i0.ɵɵtext(18, "Schedule");
|
|
169
170
|
i0.ɵɵelementEnd();
|
|
170
|
-
i0.ɵɵelementStart(19, "span",
|
|
171
|
+
i0.ɵɵelementStart(19, "span", 37);
|
|
171
172
|
i0.ɵɵtext(20);
|
|
172
173
|
i0.ɵɵelementEnd()();
|
|
173
|
-
i0.ɵɵelementStart(21, "div",
|
|
174
|
+
i0.ɵɵelementStart(21, "div", 34)(22, "span", 35);
|
|
174
175
|
i0.ɵɵtext(23, "Last Run");
|
|
175
176
|
i0.ɵɵelementEnd();
|
|
176
|
-
i0.ɵɵelementStart(24, "span",
|
|
177
|
+
i0.ɵɵelementStart(24, "span", 36);
|
|
177
178
|
i0.ɵɵtext(25);
|
|
178
179
|
i0.ɵɵelementEnd()();
|
|
179
|
-
i0.ɵɵelementStart(26, "div",
|
|
180
|
+
i0.ɵɵelementStart(26, "div", 34)(27, "span", 35);
|
|
180
181
|
i0.ɵɵtext(28, "Next Run");
|
|
181
182
|
i0.ɵɵelementEnd();
|
|
182
|
-
i0.ɵɵelementStart(29, "span",
|
|
183
|
+
i0.ɵɵelementStart(29, "span", 36);
|
|
183
184
|
i0.ɵɵtext(30);
|
|
184
185
|
i0.ɵɵelementEnd()()();
|
|
185
|
-
i0.ɵɵelementStart(31, "div",
|
|
186
|
+
i0.ɵɵelementStart(31, "div", 38)(32, "div", 39)(33, "span", 40);
|
|
186
187
|
i0.ɵɵtext(34, "Success Rate");
|
|
187
188
|
i0.ɵɵelementEnd();
|
|
188
|
-
i0.ɵɵelementStart(35, "span",
|
|
189
|
+
i0.ɵɵelementStart(35, "span", 41);
|
|
189
190
|
i0.ɵɵtext(36);
|
|
190
191
|
i0.ɵɵelementEnd()();
|
|
191
|
-
i0.ɵɵelementStart(37, "div",
|
|
192
|
-
i0.ɵɵelement(38, "div",
|
|
192
|
+
i0.ɵɵelementStart(37, "div", 42);
|
|
193
|
+
i0.ɵɵelement(38, "div", 43);
|
|
193
194
|
i0.ɵɵelementEnd();
|
|
194
|
-
i0.ɵɵelementStart(39, "div",
|
|
195
|
-
i0.ɵɵelement(41, "i",
|
|
195
|
+
i0.ɵɵelementStart(39, "div", 44)(40, "span", 45);
|
|
196
|
+
i0.ɵɵelement(41, "i", 46);
|
|
196
197
|
i0.ɵɵtext(42);
|
|
197
198
|
i0.ɵɵelementEnd();
|
|
198
|
-
i0.ɵɵelementStart(43, "span",
|
|
199
|
-
i0.ɵɵelement(44, "i",
|
|
199
|
+
i0.ɵɵelementStart(43, "span", 47);
|
|
200
|
+
i0.ɵɵelement(44, "i", 48);
|
|
200
201
|
i0.ɵɵtext(45);
|
|
201
202
|
i0.ɵɵelementEnd();
|
|
202
|
-
i0.ɵɵelementStart(46, "span",
|
|
203
|
+
i0.ɵɵelementStart(46, "span", 49);
|
|
203
204
|
i0.ɵɵtext(47);
|
|
204
205
|
i0.ɵɵelementEnd()()()();
|
|
205
|
-
i0.ɵɵconditionalCreate(48, SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_48_Template, 11, 2, "div",
|
|
206
|
-
i0.ɵɵelementStart(49, "div",
|
|
206
|
+
i0.ɵɵconditionalCreate(48, SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Conditional_48_Template, 11, 2, "div", 50);
|
|
207
|
+
i0.ɵɵelementStart(49, "div", 51)(50, "button", 52);
|
|
207
208
|
i0.ɵɵlistener("click", function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Template_button_click_50_listener($event) { const job_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.ToggleJobStatus(job_r7, $event)); });
|
|
208
209
|
i0.ɵɵelement(51, "i");
|
|
209
210
|
i0.ɵɵtext(52);
|
|
210
211
|
i0.ɵɵelementEnd();
|
|
211
|
-
i0.ɵɵelementStart(53, "button",
|
|
212
|
+
i0.ɵɵelementStart(53, "button", 52);
|
|
212
213
|
i0.ɵɵlistener("click", function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Template_button_click_53_listener($event) { const job_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.OpenEntityRecord(job_r7); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
213
|
-
i0.ɵɵelement(54, "i",
|
|
214
|
+
i0.ɵɵelement(54, "i", 53);
|
|
214
215
|
i0.ɵɵtext(55, " Full Details ");
|
|
215
216
|
i0.ɵɵelementEnd();
|
|
216
|
-
i0.ɵɵelementStart(56, "button",
|
|
217
|
+
i0.ɵɵelementStart(56, "button", 54);
|
|
217
218
|
i0.ɵɵlistener("click", function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Template_button_click_56_listener($event) { const job_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.ShowDeleteConfirm(job_r7, $event)); });
|
|
218
|
-
i0.ɵɵelement(57, "i",
|
|
219
|
+
i0.ɵɵelement(57, "i", 55);
|
|
219
220
|
i0.ɵɵtext(58, " Delete ");
|
|
220
221
|
i0.ɵɵelementEnd()()();
|
|
221
222
|
} if (rf & 2) {
|
|
@@ -259,8 +260,8 @@ function SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Template(rf,
|
|
|
259
260
|
i0.ɵɵtextInterpolate1(" ", job_r7.status === "Active" ? "Pause" : "Resume", " ");
|
|
260
261
|
} }
|
|
261
262
|
function SchedulingJobsComponent_ng_template_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
262
|
-
i0.ɵɵelementStart(0, "div",
|
|
263
|
-
i0.ɵɵrepeaterCreate(1, SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Template, 59, 24, "div",
|
|
263
|
+
i0.ɵɵelementStart(0, "div", 17);
|
|
264
|
+
i0.ɵɵrepeaterCreate(1, SchedulingJobsComponent_ng_template_2_Conditional_3_For_2_Template, 59, 24, "div", 24, i0.ɵɵrepeaterTrackByIdentity);
|
|
264
265
|
i0.ɵɵelementEnd();
|
|
265
266
|
} if (rf & 2) {
|
|
266
267
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
@@ -269,11 +270,11 @@ function SchedulingJobsComponent_ng_template_2_Conditional_3_Template(rf, ctx) {
|
|
|
269
270
|
} }
|
|
270
271
|
function SchedulingJobsComponent_ng_template_2_Template(rf, ctx) { if (rf & 1) {
|
|
271
272
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
272
|
-
i0.ɵɵelementStart(0, "div",
|
|
273
|
-
i0.ɵɵconditionalCreate(1, SchedulingJobsComponent_ng_template_2_Conditional_1_Template, 2, 0, "div",
|
|
274
|
-
i0.ɵɵconditionalCreate(2, SchedulingJobsComponent_ng_template_2_Conditional_2_Template, 8, 3, "div",
|
|
275
|
-
i0.ɵɵconditionalCreate(3, SchedulingJobsComponent_ng_template_2_Conditional_3_Template, 3, 0, "div",
|
|
276
|
-
i0.ɵɵelementStart(4, "mj-scheduled-job-slide-panel",
|
|
273
|
+
i0.ɵɵelementStart(0, "div", 14);
|
|
274
|
+
i0.ɵɵconditionalCreate(1, SchedulingJobsComponent_ng_template_2_Conditional_1_Template, 2, 0, "div", 15);
|
|
275
|
+
i0.ɵɵconditionalCreate(2, SchedulingJobsComponent_ng_template_2_Conditional_2_Template, 8, 3, "div", 16);
|
|
276
|
+
i0.ɵɵconditionalCreate(3, SchedulingJobsComponent_ng_template_2_Conditional_3_Template, 3, 0, "div", 17);
|
|
277
|
+
i0.ɵɵelementStart(4, "mj-scheduled-job-slide-panel", 18);
|
|
277
278
|
i0.ɵɵlistener("Close", function SchedulingJobsComponent_ng_template_2_Template_mj_scheduled_job_slide_panel_Close_4_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseSlideout()); })("Saved", function SchedulingJobsComponent_ng_template_2_Template_mj_scheduled_job_slide_panel_Saved_4_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnSlideoutSaved()); })("Deleted", function SchedulingJobsComponent_ng_template_2_Template_mj_scheduled_job_slide_panel_Deleted_4_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnSlideoutSaved()); });
|
|
278
279
|
i0.ɵɵelementEnd()();
|
|
279
280
|
} if (rf & 2) {
|
|
@@ -605,8 +606,8 @@ export class SchedulingJobsComponent {
|
|
|
605
606
|
this.settingsPersistSubject.next();
|
|
606
607
|
}
|
|
607
608
|
static ɵfac = function SchedulingJobsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SchedulingJobsComponent)(i0.ɵɵdirectiveInject(i1.SchedulingInstrumentationService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
608
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingJobsComponent, selectors: [["app-scheduling-jobs"]], inputs: { initialState: "initialState", HideToolbar: "HideToolbar" }, outputs: { stateChange: "stateChange" }, standalone: false, decls: 4, vars: 1, consts: [["content", ""], [4, "ngTemplateOutlet"], ["Title", "Scheduled Jobs", "Icon", "fa-solid fa-calendar-check", "Subtitle", "Configure and manage scheduled jobs"], ["meta", ""], ["Label", "jobs", 3, "Count", "Total"], ["actions", ""], [3, "
|
|
609
|
-
i0.ɵɵconditionalCreate(0, SchedulingJobsComponent_Conditional_0_Template, 1, 1, "ng-container")(1, SchedulingJobsComponent_Conditional_1_Template,
|
|
609
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingJobsComponent, selectors: [["app-scheduling-jobs"]], inputs: { initialState: "initialState", HideToolbar: "HideToolbar" }, outputs: { stateChange: "stateChange" }, standalone: false, decls: 4, vars: 1, consts: [["content", ""], [4, "ngTemplateOutlet"], ["Title", "Scheduled Jobs", "Icon", "fa-solid fa-calendar-check", "Subtitle", "Configure and manage scheduled jobs"], ["meta", ""], ["Label", "jobs", 3, "Count", "Total"], ["actions", ""], [3, "Clicked"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "action-btn-label"], ["toolbar", ""], ["Placeholder", "Search jobs...", 3, "ValueChange", "Value"], [3, "ClearAllRequested", "ActiveCount", "ShowClearAll"], [3, "ValuesChange", "Reset", "Fields", "Values"], [1, "jobs-container"], [1, "loading-container"], [1, "empty-state"], [1, "jobs-grid"], [3, "Close", "Saved", "Deleted", "IsOpen", "ScheduledJobID"], ["text", "Loading jobs...", "size", "medium"], [1, "empty-icon"], [1, "fa-solid", "fa-calendar-xmark"], [1, "primary-btn"], [1, "primary-btn", 3, "click"], [1, "job-card"], [1, "job-card", 3, "click"], [1, "job-card-header"], [1, "job-card-title"], [1, "type-icon"], [1, "job-name"], [1, "status-chip", 3, "ngClass"], [1, "job-card-body"], [1, "job-description"], [1, "job-meta-grid"], [1, "meta-item"], [1, "meta-label"], [1, "meta-value"], [1, "meta-value", "mono"], [1, "success-section"], [1, "success-header"], [1, "success-label"], [1, "success-value"], [1, "success-bar-track"], [1, "success-bar-fill"], [1, "run-stats"], [1, "stat-success"], [1, "fa-solid", "fa-check"], [1, "stat-failure"], [1, "fa-solid", "fa-xmark"], [1, "stat-total"], [1, "delete-confirm-overlay"], [1, "job-card-footer"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click"], [1, "fa-solid", "fa-up-right-from-square"], ["mjButton", "", "variant", "danger", "size", "sm", 3, "click"], [1, "fa-solid", "fa-trash-can"], [1, "delete-confirm-overlay", 3, "click"], [1, "delete-confirm-content"], [1, "fa-solid", "fa-triangle-exclamation", "delete-warn-icon"], [1, "delete-confirm-text"], [1, "delete-confirm-actions"], [1, "delete-confirm-btn", 3, "click", "disabled"], [1, "delete-cancel-btn", 3, "click"], [1, "fa-solid", "fa-spinner", "fa-spin"]], template: function SchedulingJobsComponent_Template(rf, ctx) { if (rf & 1) {
|
|
610
|
+
i0.ɵɵconditionalCreate(0, SchedulingJobsComponent_Conditional_0_Template, 1, 1, "ng-container")(1, SchedulingJobsComponent_Conditional_1_Template, 16, 8, "mj-page-layout");
|
|
610
611
|
i0.ɵɵtemplate(2, SchedulingJobsComponent_ng_template_2_Template, 5, 5, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
|
|
611
612
|
} if (rf & 2) {
|
|
612
613
|
i0.ɵɵconditional(ctx.HideToolbar ? 0 : 1);
|
|
@@ -614,7 +615,7 @@ export class SchedulingJobsComponent {
|
|
|
614
615
|
}
|
|
615
616
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SchedulingJobsComponent, [{
|
|
616
617
|
type: Component,
|
|
617
|
-
args: [{ standalone: false, selector: 'app-scheduling-jobs', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (HideToolbar) {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n} @else {\n <mj-page-layout>\n <mj-page-header\n Title=\"Scheduled Jobs\"\n Icon=\"fa-solid fa-calendar-check\"\n Subtitle=\"Configure and manage scheduled jobs\">\n <div meta>\n <mj-stat-badge [Count]=\"FilteredJobs.length\" [Total]=\"Jobs.length\" Label=\"jobs\"></mj-stat-badge>\n </div>\n <div actions>\n <mj-filter-popover\n [ActiveCount]=\"ActiveFilterCount\"\n [ShowClearAll]=\"ActiveFilterCount > 0\"\n (ClearAllRequested)=\"ResetFilters()\">\n <mj-filter-panel\n [Fields]=\"JobsFilterFields\"\n [Values]=\"JobsFilterValues\"\n (ValuesChange)=\"OnFilterValuesChange($event)\"\n (Reset)=\"ResetFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n <mj-refresh-button (Clicked)=\"Refresh()\"></mj-refresh-button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> New Job\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search jobs...\"\n [Value]=\"SearchTerm\"\n (ValueChange)=\"OnSearchChange($event)\">\n </mj-page-search>\n </div>\n </mj-page-header>\n <mj-page-body>\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </mj-page-body>\n </mj-page-layout>\n}\n\n<ng-template #content>\n<div class=\"jobs-container\">\n\n <!-- Loading -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading jobs...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Empty State -->\n @if (!IsLoading && FilteredJobs.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-calendar-xmark\"></i>\n </div>\n <h3>No jobs found</h3>\n @if (SearchTerm || StatusFilter || TypeFilter) {\n <p>Try adjusting your filters</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <p>Create your first scheduled job to get started</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <button class=\"primary-btn\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> Create Job\n </button>\n }\n </div>\n }\n\n <!-- Job Cards Grid -->\n @if (!IsLoading && FilteredJobs.length > 0) {\n <div class=\"jobs-grid\">\n @for (job of FilteredJobs; track job) {\n <div\n class=\"job-card\"\n (click)=\"OpenEditSlideout(job)\">\n <!-- Card Header -->\n <div class=\"job-card-header\">\n <div class=\"job-card-title\">\n <i [class]=\"GetTypeIcon(job.jobType)\" class=\"type-icon\"></i>\n <span class=\"job-name\">{{job.jobName}}</span>\n </div>\n <span class=\"status-chip\" [ngClass]=\"GetStatusClass(job.status)\">{{job.status}}</span>\n </div>\n <!-- Card Body -->\n <div class=\"job-card-body\">\n @if (job.description) {\n <div class=\"job-description\">{{job.description}}</div>\n }\n <div class=\"job-meta-grid\">\n <div class=\"meta-item\">\n <span class=\"meta-label\">Type</span>\n <span class=\"meta-value\">{{job.jobType}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Schedule</span>\n <span class=\"meta-value mono\">{{job.cronExpression}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Last Run</span>\n <span class=\"meta-value\">{{FormatDate(job.lastRunAt)}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Next Run</span>\n <span class=\"meta-value\">{{FormatDate(job.nextRunAt)}}</span>\n </div>\n </div>\n <!-- Success Rate Bar -->\n <div class=\"success-section\">\n <div class=\"success-header\">\n <span class=\"success-label\">Success Rate</span>\n <span class=\"success-value\" [style.color]=\"GetSuccessRateColor(job.successRate)\">\n {{FormatPercentage(job.successRate)}}\n </span>\n </div>\n <div class=\"success-bar-track\">\n <div class=\"success-bar-fill\"\n [style.width]=\"(job.successRate * 100) + '%'\"\n [style.background]=\"GetSuccessRateColor(job.successRate)\">\n </div>\n </div>\n <div class=\"run-stats\">\n <span class=\"stat-success\"><i class=\"fa-solid fa-check\"></i> {{job.successCount}}</span>\n <span class=\"stat-failure\"><i class=\"fa-solid fa-xmark\"></i> {{job.failureCount}}</span>\n <span class=\"stat-total\">{{job.totalRuns}} total</span>\n </div>\n </div>\n </div>\n <!-- Delete confirmation overlay -->\n @if (IsDeleteConfirming(job.jobId)) {\n <div class=\"delete-confirm-overlay\" (click)=\"$event.stopPropagation()\">\n <div class=\"delete-confirm-content\">\n <i class=\"fa-solid fa-triangle-exclamation delete-warn-icon\"></i>\n <span class=\"delete-confirm-text\">Delete this scheduled job?</span>\n <div class=\"delete-confirm-actions\">\n <button class=\"delete-confirm-btn\" [disabled]=\"IsDeleting\" (click)=\"ConfirmDelete(job.jobId, $event)\">\n @if (IsDeleting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Deleting...\n } @else {\n Delete\n }\n </button>\n <button class=\"delete-cancel-btn\" (click)=\"CancelDelete($event)\">Cancel</button>\n </div>\n </div>\n </div>\n }\n <!-- Card Footer -->\n <div class=\"job-card-footer\">\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"ToggleJobStatus(job, $event)\">\n <i [class]=\"job.status === 'Active' ? 'fa-solid fa-pause' : 'fa-solid fa-play'\"></i>\n {{job.status === 'Active' ? 'Pause' : 'Resume'}}\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OpenEntityRecord(job); $event.stopPropagation()\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n Full Details\n </button>\n <button mjButton variant=\"danger\" size=\"sm\" (click)=\"ShowDeleteConfirm(job, $event)\">\n <i class=\"fa-solid fa-trash-can\"></i>\n Delete\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Slideout Panel -->\n <mj-scheduled-job-slide-panel\n [IsOpen]=\"SlideoutOpen\"\n [ScheduledJobID]=\"SelectedJob?.jobId ?? null\"\n (Close)=\"CloseSlideout()\"\n (Saved)=\"OnSlideoutSaved()\"\n (Deleted)=\"OnSlideoutSaved()\">\n </mj-scheduled-job-slide-panel>\n</div>\n</ng-template>\n", styles: [".jobs-container {\n display: flex;\n flex-direction: column;\n gap: 20px;\n position: relative;\n}\n\n/* \u2500\u2500 Toolbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.jobs-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.toolbar-left {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.toolbar-right {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.search-box {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n min-width: 240px;\n transition: border-color 0.2s;\n}\n\n.search-box:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.search-box i {\n color: var(--mj-text-muted);\n font-size: 0.85rem;\n}\n\n.search-box input {\n border: none;\n outline: none;\n background: transparent;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n width: 100%;\n}\n\n.filter-select {\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n cursor: pointer;\n outline: none;\n transition: border-color 0.2s;\n}\n\n.filter-select:focus {\n border-color: var(--mj-brand-primary);\n}\n\n.result-count {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.control-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.control-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.primary-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 600;\n transition: all 0.2s ease;\n}\n\n.primary-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n/* \u2500\u2500 Loading & Empty \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 64px 24px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 2rem;\n color: var(--mj-text-muted);\n}\n\n.empty-state h3 {\n font-size: 1.1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px;\n}\n\n.empty-state p {\n color: var(--mj-text-secondary);\n margin: 0 0 16px;\n font-size: 0.9rem;\n}\n\n/* \u2500\u2500 Job Cards Grid \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.jobs-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));\n gap: 16px;\n}\n\n.job-card {\n position: relative;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.job-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--mj-shadow-lg);\n border-color: var(--mj-brand-primary);\n}\n\n/* Card Header */\n.job-card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.job-card-title {\n display: flex;\n align-items: center;\n gap: 10px;\n flex: 1;\n min-width: 0;\n}\n\n.type-icon {\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.job-name {\n font-weight: 700;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.3;\n}\n\n.status-chip {\n font-size: 0.7rem;\n font-weight: 700;\n padding: 3px 10px;\n border-radius: 12px;\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n.status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-paused { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-disabled { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.status-pending { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-expired { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n/* Card Body */\n.job-card-body {\n padding: 16px 20px;\n flex: 1;\n}\n\n.job-description {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n}\n\n.job-meta-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.meta-label {\n font-size: 0.65rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.meta-value {\n font-size: 0.8rem;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.meta-value.mono {\n font-family: 'SFMono-Regular', Consolas, monospace;\n font-size: 0.75rem;\n}\n\n/* Success Rate */\n.success-section {\n padding-top: 12px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.success-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n\n.success-label {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.success-value {\n font-size: 0.85rem;\n font-weight: 800;\n}\n\n.success-bar-track {\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.success-bar-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.5s ease;\n}\n\n.run-stats {\n display: flex;\n gap: 12px;\n margin-top: 8px;\n font-size: 0.75rem;\n}\n\n.stat-success { color: var(--mj-status-success); font-weight: 600; }\n.stat-failure { color: var(--mj-status-error); font-weight: 600; }\n.stat-total { color: var(--mj-text-muted); margin-left: auto; }\n\n/* Card Footer */\n.job-card-footer {\n display: flex;\n gap: 8px;\n padding: 12px 20px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n background: var(--mj-bg-surface-sunken);\n}\n\n.action-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s;\n}\n\n.action-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n/* \u2500\u2500 Slideout Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.slideout-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n animation: fadeInBackdrop 0.2s ease;\n}\n\n@keyframes fadeInBackdrop {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.slideout-panel {\n position: fixed;\n top: 0;\n right: -100%;\n height: 100vh;\n background: var(--mj-bg-surface-card);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slideout-panel.open {\n right: 0;\n}\n\n.slideout-resize-handle {\n position: absolute;\n inset: 0;\n background: rgba(255, 255, 255, 0.95);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n border-radius: 16px;\n backdrop-filter: blur(4px);\n}\n\n.slideout-resize-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.slideout-resize-handle:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n/* \u2500\u2500 Delete Confirmation Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.delete-confirm-overlay {\n position: absolute;\n inset: 0;\n background: rgba(255, 255, 255, 0.95);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n border-radius: 16px;\n backdrop-filter: blur(4px);\n}\n\n.delete-confirm-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 24px;\n text-align: center;\n}\n\n.delete-warn-icon {\n font-size: 1.5rem;\n color: var(--mj-status-error);\n}\n\n.delete-confirm-text {\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.delete-confirm-actions {\n display: flex;\n gap: 8px;\n margin-top: 4px;\n}\n\n.delete-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 600;\n transition: background 0.2s;\n}\n\n.delete-confirm-btn:hover:not(:disabled) {\n background: var(--mj-status-error-text);\n}\n\n.delete-confirm-btn:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n}\n\n.delete-cancel-btn {\n padding: 6px 16px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.delete-cancel-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n/* \u2500\u2500 Danger Action Button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.action-btn-danger {\n margin-left: auto;\n color: var(--mj-status-error);\n border-color: var(--mj-status-error-border);\n}\n\n.action-btn-danger:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n color: var(--mj-status-error-text);\n}\n\n/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 1024px) {\n .jobs-grid {\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n }\n}\n\n@media (max-width: 768px) {\n .jobs-toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n .toolbar-right {\n justify-content: space-between;\n }\n .jobs-grid {\n grid-template-columns: 1fr;\n }\n .search-box {\n min-width: auto;\n flex: 1;\n }\n}\n"] }]
|
|
618
|
+
args: [{ standalone: false, selector: 'app-scheduling-jobs', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (HideToolbar) {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n} @else {\n <mj-page-layout>\n <mj-page-header\n Title=\"Scheduled Jobs\"\n Icon=\"fa-solid fa-calendar-check\"\n Subtitle=\"Configure and manage scheduled jobs\">\n <div meta>\n <mj-stat-badge [Count]=\"FilteredJobs.length\" [Total]=\"Jobs.length\" Label=\"jobs\"></mj-stat-badge>\n </div>\n <div actions>\n <mj-refresh-button (Clicked)=\"Refresh()\"></mj-refresh-button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"action-btn-label\">New Job</span>\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search jobs...\"\n [Value]=\"SearchTerm\"\n (ValueChange)=\"OnSearchChange($event)\">\n </mj-page-search>\n <mj-filter-popover\n [ActiveCount]=\"ActiveFilterCount\"\n [ShowClearAll]=\"ActiveFilterCount > 0\"\n (ClearAllRequested)=\"ResetFilters()\">\n <mj-filter-panel\n [Fields]=\"JobsFilterFields\"\n [Values]=\"JobsFilterValues\"\n (ValuesChange)=\"OnFilterValuesChange($event)\"\n (Reset)=\"ResetFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n </mj-page-header>\n <mj-page-body>\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </mj-page-body>\n </mj-page-layout>\n}\n\n<ng-template #content>\n<div class=\"jobs-container\">\n\n <!-- Loading -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading jobs...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Empty State -->\n @if (!IsLoading && FilteredJobs.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-calendar-xmark\"></i>\n </div>\n <h3>No jobs found</h3>\n @if (SearchTerm || StatusFilter || TypeFilter) {\n <p>Try adjusting your filters</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <p>Create your first scheduled job to get started</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <button class=\"primary-btn\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> Create Job\n </button>\n }\n </div>\n }\n\n <!-- Job Cards Grid -->\n @if (!IsLoading && FilteredJobs.length > 0) {\n <div class=\"jobs-grid\">\n @for (job of FilteredJobs; track job) {\n <div\n class=\"job-card\"\n (click)=\"OpenEditSlideout(job)\">\n <!-- Card Header -->\n <div class=\"job-card-header\">\n <div class=\"job-card-title\">\n <i [class]=\"GetTypeIcon(job.jobType)\" class=\"type-icon\"></i>\n <span class=\"job-name\">{{job.jobName}}</span>\n </div>\n <span class=\"status-chip\" [ngClass]=\"GetStatusClass(job.status)\">{{job.status}}</span>\n </div>\n <!-- Card Body -->\n <div class=\"job-card-body\">\n @if (job.description) {\n <div class=\"job-description\">{{job.description}}</div>\n }\n <div class=\"job-meta-grid\">\n <div class=\"meta-item\">\n <span class=\"meta-label\">Type</span>\n <span class=\"meta-value\">{{job.jobType}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Schedule</span>\n <span class=\"meta-value mono\">{{job.cronExpression}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Last Run</span>\n <span class=\"meta-value\">{{FormatDate(job.lastRunAt)}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Next Run</span>\n <span class=\"meta-value\">{{FormatDate(job.nextRunAt)}}</span>\n </div>\n </div>\n <!-- Success Rate Bar -->\n <div class=\"success-section\">\n <div class=\"success-header\">\n <span class=\"success-label\">Success Rate</span>\n <span class=\"success-value\" [style.color]=\"GetSuccessRateColor(job.successRate)\">\n {{FormatPercentage(job.successRate)}}\n </span>\n </div>\n <div class=\"success-bar-track\">\n <div class=\"success-bar-fill\"\n [style.width]=\"(job.successRate * 100) + '%'\"\n [style.background]=\"GetSuccessRateColor(job.successRate)\">\n </div>\n </div>\n <div class=\"run-stats\">\n <span class=\"stat-success\"><i class=\"fa-solid fa-check\"></i> {{job.successCount}}</span>\n <span class=\"stat-failure\"><i class=\"fa-solid fa-xmark\"></i> {{job.failureCount}}</span>\n <span class=\"stat-total\">{{job.totalRuns}} total</span>\n </div>\n </div>\n </div>\n <!-- Delete confirmation overlay -->\n @if (IsDeleteConfirming(job.jobId)) {\n <div class=\"delete-confirm-overlay\" (click)=\"$event.stopPropagation()\">\n <div class=\"delete-confirm-content\">\n <i class=\"fa-solid fa-triangle-exclamation delete-warn-icon\"></i>\n <span class=\"delete-confirm-text\">Delete this scheduled job?</span>\n <div class=\"delete-confirm-actions\">\n <button class=\"delete-confirm-btn\" [disabled]=\"IsDeleting\" (click)=\"ConfirmDelete(job.jobId, $event)\">\n @if (IsDeleting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Deleting...\n } @else {\n Delete\n }\n </button>\n <button class=\"delete-cancel-btn\" (click)=\"CancelDelete($event)\">Cancel</button>\n </div>\n </div>\n </div>\n }\n <!-- Card Footer -->\n <div class=\"job-card-footer\">\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"ToggleJobStatus(job, $event)\">\n <i [class]=\"job.status === 'Active' ? 'fa-solid fa-pause' : 'fa-solid fa-play'\"></i>\n {{job.status === 'Active' ? 'Pause' : 'Resume'}}\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OpenEntityRecord(job); $event.stopPropagation()\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n Full Details\n </button>\n <button mjButton variant=\"danger\" size=\"sm\" (click)=\"ShowDeleteConfirm(job, $event)\">\n <i class=\"fa-solid fa-trash-can\"></i>\n Delete\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Slideout Panel -->\n <mj-scheduled-job-slide-panel\n [IsOpen]=\"SlideoutOpen\"\n [ScheduledJobID]=\"SelectedJob?.jobId ?? null\"\n (Close)=\"CloseSlideout()\"\n (Saved)=\"OnSlideoutSaved()\"\n (Deleted)=\"OnSlideoutSaved()\">\n </mj-scheduled-job-slide-panel>\n</div>\n</ng-template>\n", styles: [".jobs-container {\n display: flex;\n flex-direction: column;\n gap: 20px;\n position: relative;\n}\n\n/* \u2500\u2500 Toolbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.jobs-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.toolbar-left {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.toolbar-right {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.search-box {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n min-width: 240px;\n transition: border-color 0.2s;\n}\n\n.search-box:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.search-box i {\n color: var(--mj-text-muted);\n font-size: 0.85rem;\n}\n\n.search-box input {\n border: none;\n outline: none;\n background: transparent;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n width: 100%;\n}\n\n.filter-select {\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n cursor: pointer;\n outline: none;\n transition: border-color 0.2s;\n}\n\n.filter-select:focus {\n border-color: var(--mj-brand-primary);\n}\n\n.result-count {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.control-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.control-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.primary-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 600;\n transition: all 0.2s ease;\n}\n\n.primary-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n/* \u2500\u2500 Loading & Empty \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 64px 24px;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 2rem;\n color: var(--mj-text-muted);\n}\n\n.empty-state h3 {\n font-size: 1.1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px;\n}\n\n.empty-state p {\n color: var(--mj-text-secondary);\n margin: 0 0 16px;\n font-size: 0.9rem;\n}\n\n/* \u2500\u2500 Job Cards Grid \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.jobs-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));\n gap: 16px;\n}\n\n.job-card {\n position: relative;\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.job-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--mj-shadow-lg);\n border-color: var(--mj-brand-primary);\n}\n\n/* Card Header */\n.job-card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.job-card-title {\n display: flex;\n align-items: center;\n gap: 10px;\n flex: 1;\n min-width: 0;\n}\n\n.type-icon {\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.job-name {\n font-weight: 700;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.3;\n}\n\n.status-chip {\n font-size: 0.7rem;\n font-weight: 700;\n padding: 3px 10px;\n border-radius: 12px;\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n.status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-paused { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-disabled { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.status-pending { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-expired { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n/* Card Body */\n.job-card-body {\n padding: 16px 20px;\n flex: 1;\n}\n\n.job-description {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n}\n\n.job-meta-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.meta-label {\n font-size: 0.65rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.meta-value {\n font-size: 0.8rem;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.meta-value.mono {\n font-family: 'SFMono-Regular', Consolas, monospace;\n font-size: 0.75rem;\n}\n\n/* Success Rate */\n.success-section {\n padding-top: 12px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.success-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n\n.success-label {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.success-value {\n font-size: 0.85rem;\n font-weight: 800;\n}\n\n.success-bar-track {\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.success-bar-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.5s ease;\n}\n\n.run-stats {\n display: flex;\n gap: 12px;\n margin-top: 8px;\n font-size: 0.75rem;\n}\n\n.stat-success { color: var(--mj-status-success); font-weight: 600; }\n.stat-failure { color: var(--mj-status-error); font-weight: 600; }\n.stat-total { color: var(--mj-text-muted); margin-left: auto; }\n\n/* Card Footer */\n.job-card-footer {\n display: flex;\n gap: 8px;\n padding: 12px 20px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n background: var(--mj-bg-surface-sunken);\n}\n\n.action-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s;\n}\n\n.action-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n/* \u2500\u2500 Slideout Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.slideout-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n animation: fadeInBackdrop 0.2s ease;\n}\n\n@keyframes fadeInBackdrop {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.slideout-panel {\n position: fixed;\n top: 0;\n right: -100%;\n height: 100vh;\n background: var(--mj-bg-surface-card);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slideout-panel.open {\n right: 0;\n}\n\n.slideout-resize-handle {\n position: absolute;\n inset: 0;\n background: rgba(255, 255, 255, 0.95);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n border-radius: 16px;\n backdrop-filter: blur(4px);\n}\n\n.slideout-resize-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.slideout-resize-handle:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n/* \u2500\u2500 Delete Confirmation Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.delete-confirm-overlay {\n position: absolute;\n inset: 0;\n background: rgba(255, 255, 255, 0.95);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n border-radius: 16px;\n backdrop-filter: blur(4px);\n}\n\n.delete-confirm-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 24px;\n text-align: center;\n}\n\n.delete-warn-icon {\n font-size: 1.5rem;\n color: var(--mj-status-error);\n}\n\n.delete-confirm-text {\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.delete-confirm-actions {\n display: flex;\n gap: 8px;\n margin-top: 4px;\n}\n\n.delete-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 600;\n transition: background 0.2s;\n}\n\n.delete-confirm-btn:hover:not(:disabled) {\n background: var(--mj-status-error-text);\n}\n\n.delete-confirm-btn:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n}\n\n.delete-cancel-btn {\n padding: 6px 16px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.delete-cancel-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n/* \u2500\u2500 Danger Action Button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.action-btn-danger {\n margin-left: auto;\n color: var(--mj-status-error);\n border-color: var(--mj-status-error-border);\n}\n\n.action-btn-danger:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n color: var(--mj-status-error-text);\n}\n\n/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 1024px) {\n .jobs-grid {\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n }\n}\n\n@media (max-width: 768px) {\n .jobs-toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n .toolbar-right {\n justify-content: space-between;\n }\n .jobs-grid {\n grid-template-columns: 1fr;\n }\n .search-box {\n min-width: auto;\n flex: 1;\n }\n}\n"] }]
|
|
618
619
|
}], () => [{ type: i1.SchedulingInstrumentationService }, { type: i0.ChangeDetectorRef }], { initialState: [{
|
|
619
620
|
type: Input
|
|
620
621
|
}], HideToolbar: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduling-jobs.component.js","sourceRoot":"","sources":["../../../src/Scheduling/components/scheduling-jobs.component.ts","../../../src/Scheduling/components/scheduling-jobs.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { Subscription, BehaviorSubject, Subject, combineLatest } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';\nimport { CompositeKey } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport {\n SchedulingInstrumentationService,\n JobStatistics,\n JobTypeStatistics\n} from '../services/scheduling-instrumentation.service';\n\n@Component({\n standalone: false,\n selector: 'app-scheduling-jobs',\n templateUrl: './scheduling-jobs.component.html',\n styleUrls: ['./scheduling-jobs.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SchedulingJobsComponent implements OnInit, OnDestroy {\n @Input() initialState: Record<string, unknown> = {};\n /** When true, the inner toolbar is hidden — the parent shell is rendering it in `<mj-page-header>` instead. */\n @Input() HideToolbar = false;\n @Output() stateChange = new EventEmitter<Record<string, unknown>>();\n\n public Jobs: JobStatistics[] = [];\n public FilteredJobs: JobStatistics[] = [];\n public JobTypes: JobTypeStatistics[] = [];\n public IsLoading = true;\n\n // Slideout state\n public SlideoutOpen = false;\n public SelectedJob: JobStatistics | null = null;\n\n // Delete confirmation state\n public DeleteConfirmJobId: string | null = null;\n public IsDeleting = false;\n\n // Filters\n public SearchTerm = '';\n public StatusFilter = '';\n public TypeFilter = '';\n\n public StatusOptions = ['', 'Active', 'Paused', 'Disabled', 'Pending', 'Expired'];\n public TypeOptions: string[] = [''];\n\n // Settings keys\n private static readonly SEARCH_STATE_KEY = 'Scheduling.JobsSearchState';\n\n private searchSubject = new BehaviorSubject<string>('');\n private statusSubject = new BehaviorSubject<string>('');\n private typeSubject = new BehaviorSubject<string>('');\n private settingsPersistSubject = new Subject<void>();\n private destroy$ = new Subject<void>();\n private subscriptions: Subscription[] = [];\n private settingsLoaded = false;\n\n constructor(\n private schedulingService: SchedulingInstrumentationService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit(): void {\n this.loadUserSettings();\n this.restoreState();\n this.setupFilters();\n this.setupSettingsPersistence();\n\n this.subscriptions.push(\n this.schedulingService.jobStatistics$.subscribe(jobs => {\n this.Jobs = jobs;\n this.IsLoading = false;\n this.updateTypeOptions();\n this.applyFilters();\n this.cdr.markForCheck();\n }),\n this.schedulingService.jobTypes$.subscribe(types => {\n this.JobTypes = types;\n this.cdr.markForCheck();\n })\n );\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n this.subscriptions.forEach(s => s.unsubscribe());\n }\n\n private loadUserSettings(): void {\n try {\n const stateStr = UserInfoEngine.Instance.GetSetting(SchedulingJobsComponent.SEARCH_STATE_KEY);\n if (stateStr) {\n const state = JSON.parse(stateStr) as Record<string, string>;\n if (state.searchTerm) this.SearchTerm = state.searchTerm;\n if (state.statusFilter) this.StatusFilter = state.statusFilter;\n if (state.typeFilter) this.TypeFilter = state.typeFilter;\n }\n } catch (error) {\n console.warn('[SchedulingJobs] Failed to load user settings:', error);\n } finally {\n this.settingsLoaded = true;\n }\n }\n\n private setupSettingsPersistence(): void {\n this.settingsPersistSubject.pipe(\n debounceTime(500),\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.persistSearchState();\n });\n }\n\n private persistSearchState(): void {\n if (!this.settingsLoaded) return;\n try {\n const state = {\n searchTerm: this.SearchTerm,\n statusFilter: this.StatusFilter,\n typeFilter: this.TypeFilter\n };\n UserInfoEngine.Instance.SetSettingDebounced(\n SchedulingJobsComponent.SEARCH_STATE_KEY,\n JSON.stringify(state)\n );\n } catch (error) {\n console.warn('[SchedulingJobs] Failed to persist search state:', error);\n }\n }\n\n private restoreState(): void {\n if (this.initialState) {\n if (this.initialState['searchTerm']) this.SearchTerm = this.initialState['searchTerm'] as string;\n if (this.initialState['statusFilter']) this.StatusFilter = this.initialState['statusFilter'] as string;\n if (this.initialState['typeFilter']) this.TypeFilter = this.initialState['typeFilter'] as string;\n }\n }\n\n private setupFilters(): void {\n this.subscriptions.push(\n combineLatest([\n this.searchSubject.pipe(debounceTime(300), distinctUntilChanged()),\n this.statusSubject.pipe(distinctUntilChanged()),\n this.typeSubject.pipe(distinctUntilChanged())\n ]).subscribe(() => {\n this.applyFilters();\n this.emitState();\n this.cdr.markForCheck();\n })\n );\n\n this.searchSubject.next(this.SearchTerm);\n this.statusSubject.next(this.StatusFilter);\n this.typeSubject.next(this.TypeFilter);\n }\n\n public OnSearchChange(term: string): void {\n this.SearchTerm = term;\n this.searchSubject.next(term);\n }\n\n public OnStatusFilterChange(status: string): void {\n this.StatusFilter = status;\n this.statusSubject.next(status);\n }\n\n public OnTypeFilterChange(type: string): void {\n this.TypeFilter = type;\n this.typeSubject.next(type);\n }\n\n public get JobsFilterFields(): FilterFieldConfig[] {\n const statusOptions = this.StatusOptions.map(s => ({\n text: s === '' ? 'All Statuses' : s,\n value: s\n }));\n const typeOptions = this.TypeOptions.map(t => ({\n text: t === '' ? 'All Types' : t,\n value: t\n }));\n return [\n {\n key: 'statusFilter',\n type: 'dropdown',\n label: 'Status',\n icon: 'fa-solid fa-circle-info',\n placeholder: 'All Statuses',\n options: statusOptions\n },\n {\n key: 'typeFilter',\n type: 'dropdown',\n label: 'Type',\n icon: 'fa-solid fa-shapes',\n placeholder: 'All Types',\n options: typeOptions\n }\n ];\n }\n\n public get JobsFilterValues(): Record<string, unknown> {\n return {\n statusFilter: this.StatusFilter,\n typeFilter: this.TypeFilter\n };\n }\n\n public get ActiveFilterCount(): number {\n let count = 0;\n if (this.StatusFilter) count++;\n if (this.TypeFilter) count++;\n return count;\n }\n\n public OnFilterValuesChange(values: Record<string, unknown>): void {\n const next = (values ?? {}) as { statusFilter?: string; typeFilter?: string };\n if ((next.statusFilter ?? '') !== this.StatusFilter) {\n this.OnStatusFilterChange(next.statusFilter ?? '');\n }\n if ((next.typeFilter ?? '') !== this.TypeFilter) {\n this.OnTypeFilterChange(next.typeFilter ?? '');\n }\n }\n\n public ResetFilters(): void {\n if (this.StatusFilter) this.OnStatusFilterChange('');\n if (this.TypeFilter) this.OnTypeFilterChange('');\n }\n\n public Refresh(): void {\n this.schedulingService.refresh();\n }\n\n public OpenCreateSlideout(): void {\n this.SelectedJob = null;\n this.SlideoutOpen = true;\n this.cdr.markForCheck();\n }\n\n public OpenEditSlideout(job: JobStatistics): void {\n this.SelectedJob = job;\n this.SlideoutOpen = true;\n this.cdr.markForCheck();\n }\n\n public CloseSlideout(): void {\n this.SlideoutOpen = false;\n this.SelectedJob = null;\n this.cdr.markForCheck();\n }\n\n public OnSlideoutSaved(): void {\n this.CloseSlideout();\n this.schedulingService.refresh();\n }\n\n public async ToggleJobStatus(job: JobStatistics, event: MouseEvent): Promise<void> {\n event.stopPropagation();\n const newStatus = job.status === 'Active' ? 'Paused' : 'Active';\n await this.schedulingService.updateJobStatus(job.jobId, newStatus as 'Active' | 'Paused');\n }\n\n public ShowDeleteConfirm(job: JobStatistics, event: MouseEvent): void {\n event.stopPropagation();\n this.DeleteConfirmJobId = job.jobId;\n this.cdr.markForCheck();\n }\n\n public CancelDelete(event: MouseEvent): void {\n event.stopPropagation();\n this.DeleteConfirmJobId = null;\n this.cdr.markForCheck();\n }\n\n public async ConfirmDelete(jobId: string, event: MouseEvent): Promise<void> {\n event.stopPropagation();\n this.IsDeleting = true;\n this.cdr.markForCheck();\n try {\n const result = await this.schedulingService.deleteJob(jobId);\n if (result) {\n this.DeleteConfirmJobId = null;\n }\n } catch (err) {\n console.error('[SchedulingJobs] Delete error:', err);\n } finally {\n this.IsDeleting = false;\n this.cdr.markForCheck();\n }\n }\n\n public IsDeleteConfirming(jobId: string): boolean {\n return this.DeleteConfirmJobId === jobId;\n }\n\n public OpenEntityRecord(job: JobStatistics): void {\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromSingleKeyValuePair('ID', job.jobId);\n SharedService.Instance.OpenEntityRecord('MJ: Scheduled Jobs', compositeKey);\n }\n\n public GetStatusClass(status: string): string {\n switch (status) {\n case 'Active': return 'status-active';\n case 'Paused': return 'status-paused';\n case 'Disabled': return 'status-disabled';\n case 'Pending': return 'status-pending';\n case 'Expired': return 'status-expired';\n default: return '';\n }\n }\n\n public GetSuccessRateColor(rate: number): string {\n if (rate >= 0.9) return '#10b981';\n if (rate >= 0.7) return '#f59e0b';\n return '#ef4444';\n }\n\n public GetTypeIcon(typeName: string): string {\n const lower = typeName.toLowerCase();\n if (lower.includes('agent')) return 'fa-solid fa-robot';\n if (lower.includes('action')) return 'fa-solid fa-bolt';\n return 'fa-solid fa-gear';\n }\n\n public FormatDate(date: Date | undefined): string {\n if (!date) return '-';\n return date.toLocaleString(undefined, {\n month: 'numeric', day: 'numeric', year: '2-digit',\n hour: 'numeric', minute: '2-digit', hour12: true\n });\n }\n\n public FormatPercentage(value: number): string {\n return `${(value * 100).toFixed(1)}%`;\n }\n\n private applyFilters(): void {\n let filtered = [...this.Jobs];\n\n if (this.SearchTerm) {\n const term = this.SearchTerm.toLowerCase();\n filtered = filtered.filter(j =>\n j.jobName.toLowerCase().includes(term) ||\n j.jobType.toLowerCase().includes(term) ||\n (j.description && j.description.toLowerCase().includes(term))\n );\n }\n\n if (this.StatusFilter) {\n filtered = filtered.filter(j => j.status === this.StatusFilter);\n }\n\n if (this.TypeFilter) {\n filtered = filtered.filter(j => j.jobType === this.TypeFilter);\n }\n\n this.FilteredJobs = filtered;\n }\n\n private updateTypeOptions(): void {\n const types = new Set(this.Jobs.map(j => j.jobType));\n this.TypeOptions = ['', ...Array.from(types).sort()];\n }\n\n private emitState(): void {\n this.stateChange.emit({\n searchTerm: this.SearchTerm,\n statusFilter: this.StatusFilter,\n typeFilter: this.TypeFilter\n });\n this.settingsPersistSubject.next();\n }\n}\n","@if (HideToolbar) {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n} @else {\n <mj-page-layout>\n <mj-page-header\n Title=\"Scheduled Jobs\"\n Icon=\"fa-solid fa-calendar-check\"\n Subtitle=\"Configure and manage scheduled jobs\">\n <div meta>\n <mj-stat-badge [Count]=\"FilteredJobs.length\" [Total]=\"Jobs.length\" Label=\"jobs\"></mj-stat-badge>\n </div>\n <div actions>\n <mj-filter-popover\n [ActiveCount]=\"ActiveFilterCount\"\n [ShowClearAll]=\"ActiveFilterCount > 0\"\n (ClearAllRequested)=\"ResetFilters()\">\n <mj-filter-panel\n [Fields]=\"JobsFilterFields\"\n [Values]=\"JobsFilterValues\"\n (ValuesChange)=\"OnFilterValuesChange($event)\"\n (Reset)=\"ResetFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n <mj-refresh-button (Clicked)=\"Refresh()\"></mj-refresh-button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> New Job\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search jobs...\"\n [Value]=\"SearchTerm\"\n (ValueChange)=\"OnSearchChange($event)\">\n </mj-page-search>\n </div>\n </mj-page-header>\n <mj-page-body>\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </mj-page-body>\n </mj-page-layout>\n}\n\n<ng-template #content>\n<div class=\"jobs-container\">\n\n <!-- Loading -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading jobs...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Empty State -->\n @if (!IsLoading && FilteredJobs.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-calendar-xmark\"></i>\n </div>\n <h3>No jobs found</h3>\n @if (SearchTerm || StatusFilter || TypeFilter) {\n <p>Try adjusting your filters</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <p>Create your first scheduled job to get started</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <button class=\"primary-btn\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> Create Job\n </button>\n }\n </div>\n }\n\n <!-- Job Cards Grid -->\n @if (!IsLoading && FilteredJobs.length > 0) {\n <div class=\"jobs-grid\">\n @for (job of FilteredJobs; track job) {\n <div\n class=\"job-card\"\n (click)=\"OpenEditSlideout(job)\">\n <!-- Card Header -->\n <div class=\"job-card-header\">\n <div class=\"job-card-title\">\n <i [class]=\"GetTypeIcon(job.jobType)\" class=\"type-icon\"></i>\n <span class=\"job-name\">{{job.jobName}}</span>\n </div>\n <span class=\"status-chip\" [ngClass]=\"GetStatusClass(job.status)\">{{job.status}}</span>\n </div>\n <!-- Card Body -->\n <div class=\"job-card-body\">\n @if (job.description) {\n <div class=\"job-description\">{{job.description}}</div>\n }\n <div class=\"job-meta-grid\">\n <div class=\"meta-item\">\n <span class=\"meta-label\">Type</span>\n <span class=\"meta-value\">{{job.jobType}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Schedule</span>\n <span class=\"meta-value mono\">{{job.cronExpression}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Last Run</span>\n <span class=\"meta-value\">{{FormatDate(job.lastRunAt)}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Next Run</span>\n <span class=\"meta-value\">{{FormatDate(job.nextRunAt)}}</span>\n </div>\n </div>\n <!-- Success Rate Bar -->\n <div class=\"success-section\">\n <div class=\"success-header\">\n <span class=\"success-label\">Success Rate</span>\n <span class=\"success-value\" [style.color]=\"GetSuccessRateColor(job.successRate)\">\n {{FormatPercentage(job.successRate)}}\n </span>\n </div>\n <div class=\"success-bar-track\">\n <div class=\"success-bar-fill\"\n [style.width]=\"(job.successRate * 100) + '%'\"\n [style.background]=\"GetSuccessRateColor(job.successRate)\">\n </div>\n </div>\n <div class=\"run-stats\">\n <span class=\"stat-success\"><i class=\"fa-solid fa-check\"></i> {{job.successCount}}</span>\n <span class=\"stat-failure\"><i class=\"fa-solid fa-xmark\"></i> {{job.failureCount}}</span>\n <span class=\"stat-total\">{{job.totalRuns}} total</span>\n </div>\n </div>\n </div>\n <!-- Delete confirmation overlay -->\n @if (IsDeleteConfirming(job.jobId)) {\n <div class=\"delete-confirm-overlay\" (click)=\"$event.stopPropagation()\">\n <div class=\"delete-confirm-content\">\n <i class=\"fa-solid fa-triangle-exclamation delete-warn-icon\"></i>\n <span class=\"delete-confirm-text\">Delete this scheduled job?</span>\n <div class=\"delete-confirm-actions\">\n <button class=\"delete-confirm-btn\" [disabled]=\"IsDeleting\" (click)=\"ConfirmDelete(job.jobId, $event)\">\n @if (IsDeleting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Deleting...\n } @else {\n Delete\n }\n </button>\n <button class=\"delete-cancel-btn\" (click)=\"CancelDelete($event)\">Cancel</button>\n </div>\n </div>\n </div>\n }\n <!-- Card Footer -->\n <div class=\"job-card-footer\">\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"ToggleJobStatus(job, $event)\">\n <i [class]=\"job.status === 'Active' ? 'fa-solid fa-pause' : 'fa-solid fa-play'\"></i>\n {{job.status === 'Active' ? 'Pause' : 'Resume'}}\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OpenEntityRecord(job); $event.stopPropagation()\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n Full Details\n </button>\n <button mjButton variant=\"danger\" size=\"sm\" (click)=\"ShowDeleteConfirm(job, $event)\">\n <i class=\"fa-solid fa-trash-can\"></i>\n Delete\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Slideout Panel -->\n <mj-scheduled-job-slide-panel\n [IsOpen]=\"SlideoutOpen\"\n [ScheduledJobID]=\"SelectedJob?.jobId ?? null\"\n (Close)=\"CloseSlideout()\"\n (Saved)=\"OnSlideoutSaved()\"\n (Deleted)=\"OnSlideoutSaved()\">\n </mj-scheduled-job-slide-panel>\n</div>\n</ng-template>\n"]}
|
|
1
|
+
{"version":3,"file":"scheduling-jobs.component.js","sourceRoot":"","sources":["../../../src/Scheduling/components/scheduling-jobs.component.ts","../../../src/Scheduling/components/scheduling-jobs.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { Subscription, BehaviorSubject, Subject, combineLatest } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';\nimport { CompositeKey } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport {\n SchedulingInstrumentationService,\n JobStatistics,\n JobTypeStatistics\n} from '../services/scheduling-instrumentation.service';\n\n@Component({\n standalone: false,\n selector: 'app-scheduling-jobs',\n templateUrl: './scheduling-jobs.component.html',\n styleUrls: ['./scheduling-jobs.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SchedulingJobsComponent implements OnInit, OnDestroy {\n @Input() initialState: Record<string, unknown> = {};\n /** When true, the inner toolbar is hidden — the parent shell is rendering it in `<mj-page-header>` instead. */\n @Input() HideToolbar = false;\n @Output() stateChange = new EventEmitter<Record<string, unknown>>();\n\n public Jobs: JobStatistics[] = [];\n public FilteredJobs: JobStatistics[] = [];\n public JobTypes: JobTypeStatistics[] = [];\n public IsLoading = true;\n\n // Slideout state\n public SlideoutOpen = false;\n public SelectedJob: JobStatistics | null = null;\n\n // Delete confirmation state\n public DeleteConfirmJobId: string | null = null;\n public IsDeleting = false;\n\n // Filters\n public SearchTerm = '';\n public StatusFilter = '';\n public TypeFilter = '';\n\n public StatusOptions = ['', 'Active', 'Paused', 'Disabled', 'Pending', 'Expired'];\n public TypeOptions: string[] = [''];\n\n // Settings keys\n private static readonly SEARCH_STATE_KEY = 'Scheduling.JobsSearchState';\n\n private searchSubject = new BehaviorSubject<string>('');\n private statusSubject = new BehaviorSubject<string>('');\n private typeSubject = new BehaviorSubject<string>('');\n private settingsPersistSubject = new Subject<void>();\n private destroy$ = new Subject<void>();\n private subscriptions: Subscription[] = [];\n private settingsLoaded = false;\n\n constructor(\n private schedulingService: SchedulingInstrumentationService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit(): void {\n this.loadUserSettings();\n this.restoreState();\n this.setupFilters();\n this.setupSettingsPersistence();\n\n this.subscriptions.push(\n this.schedulingService.jobStatistics$.subscribe(jobs => {\n this.Jobs = jobs;\n this.IsLoading = false;\n this.updateTypeOptions();\n this.applyFilters();\n this.cdr.markForCheck();\n }),\n this.schedulingService.jobTypes$.subscribe(types => {\n this.JobTypes = types;\n this.cdr.markForCheck();\n })\n );\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n this.subscriptions.forEach(s => s.unsubscribe());\n }\n\n private loadUserSettings(): void {\n try {\n const stateStr = UserInfoEngine.Instance.GetSetting(SchedulingJobsComponent.SEARCH_STATE_KEY);\n if (stateStr) {\n const state = JSON.parse(stateStr) as Record<string, string>;\n if (state.searchTerm) this.SearchTerm = state.searchTerm;\n if (state.statusFilter) this.StatusFilter = state.statusFilter;\n if (state.typeFilter) this.TypeFilter = state.typeFilter;\n }\n } catch (error) {\n console.warn('[SchedulingJobs] Failed to load user settings:', error);\n } finally {\n this.settingsLoaded = true;\n }\n }\n\n private setupSettingsPersistence(): void {\n this.settingsPersistSubject.pipe(\n debounceTime(500),\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.persistSearchState();\n });\n }\n\n private persistSearchState(): void {\n if (!this.settingsLoaded) return;\n try {\n const state = {\n searchTerm: this.SearchTerm,\n statusFilter: this.StatusFilter,\n typeFilter: this.TypeFilter\n };\n UserInfoEngine.Instance.SetSettingDebounced(\n SchedulingJobsComponent.SEARCH_STATE_KEY,\n JSON.stringify(state)\n );\n } catch (error) {\n console.warn('[SchedulingJobs] Failed to persist search state:', error);\n }\n }\n\n private restoreState(): void {\n if (this.initialState) {\n if (this.initialState['searchTerm']) this.SearchTerm = this.initialState['searchTerm'] as string;\n if (this.initialState['statusFilter']) this.StatusFilter = this.initialState['statusFilter'] as string;\n if (this.initialState['typeFilter']) this.TypeFilter = this.initialState['typeFilter'] as string;\n }\n }\n\n private setupFilters(): void {\n this.subscriptions.push(\n combineLatest([\n this.searchSubject.pipe(debounceTime(300), distinctUntilChanged()),\n this.statusSubject.pipe(distinctUntilChanged()),\n this.typeSubject.pipe(distinctUntilChanged())\n ]).subscribe(() => {\n this.applyFilters();\n this.emitState();\n this.cdr.markForCheck();\n })\n );\n\n this.searchSubject.next(this.SearchTerm);\n this.statusSubject.next(this.StatusFilter);\n this.typeSubject.next(this.TypeFilter);\n }\n\n public OnSearchChange(term: string): void {\n this.SearchTerm = term;\n this.searchSubject.next(term);\n }\n\n public OnStatusFilterChange(status: string): void {\n this.StatusFilter = status;\n this.statusSubject.next(status);\n }\n\n public OnTypeFilterChange(type: string): void {\n this.TypeFilter = type;\n this.typeSubject.next(type);\n }\n\n public get JobsFilterFields(): FilterFieldConfig[] {\n const statusOptions = this.StatusOptions.map(s => ({\n text: s === '' ? 'All Statuses' : s,\n value: s\n }));\n const typeOptions = this.TypeOptions.map(t => ({\n text: t === '' ? 'All Types' : t,\n value: t\n }));\n return [\n {\n key: 'statusFilter',\n type: 'dropdown',\n label: 'Status',\n icon: 'fa-solid fa-circle-info',\n placeholder: 'All Statuses',\n options: statusOptions\n },\n {\n key: 'typeFilter',\n type: 'dropdown',\n label: 'Type',\n icon: 'fa-solid fa-shapes',\n placeholder: 'All Types',\n options: typeOptions\n }\n ];\n }\n\n public get JobsFilterValues(): Record<string, unknown> {\n return {\n statusFilter: this.StatusFilter,\n typeFilter: this.TypeFilter\n };\n }\n\n public get ActiveFilterCount(): number {\n let count = 0;\n if (this.StatusFilter) count++;\n if (this.TypeFilter) count++;\n return count;\n }\n\n public OnFilterValuesChange(values: Record<string, unknown>): void {\n const next = (values ?? {}) as { statusFilter?: string; typeFilter?: string };\n if ((next.statusFilter ?? '') !== this.StatusFilter) {\n this.OnStatusFilterChange(next.statusFilter ?? '');\n }\n if ((next.typeFilter ?? '') !== this.TypeFilter) {\n this.OnTypeFilterChange(next.typeFilter ?? '');\n }\n }\n\n public ResetFilters(): void {\n if (this.StatusFilter) this.OnStatusFilterChange('');\n if (this.TypeFilter) this.OnTypeFilterChange('');\n }\n\n public Refresh(): void {\n this.schedulingService.refresh();\n }\n\n public OpenCreateSlideout(): void {\n this.SelectedJob = null;\n this.SlideoutOpen = true;\n this.cdr.markForCheck();\n }\n\n public OpenEditSlideout(job: JobStatistics): void {\n this.SelectedJob = job;\n this.SlideoutOpen = true;\n this.cdr.markForCheck();\n }\n\n public CloseSlideout(): void {\n this.SlideoutOpen = false;\n this.SelectedJob = null;\n this.cdr.markForCheck();\n }\n\n public OnSlideoutSaved(): void {\n this.CloseSlideout();\n this.schedulingService.refresh();\n }\n\n public async ToggleJobStatus(job: JobStatistics, event: MouseEvent): Promise<void> {\n event.stopPropagation();\n const newStatus = job.status === 'Active' ? 'Paused' : 'Active';\n await this.schedulingService.updateJobStatus(job.jobId, newStatus as 'Active' | 'Paused');\n }\n\n public ShowDeleteConfirm(job: JobStatistics, event: MouseEvent): void {\n event.stopPropagation();\n this.DeleteConfirmJobId = job.jobId;\n this.cdr.markForCheck();\n }\n\n public CancelDelete(event: MouseEvent): void {\n event.stopPropagation();\n this.DeleteConfirmJobId = null;\n this.cdr.markForCheck();\n }\n\n public async ConfirmDelete(jobId: string, event: MouseEvent): Promise<void> {\n event.stopPropagation();\n this.IsDeleting = true;\n this.cdr.markForCheck();\n try {\n const result = await this.schedulingService.deleteJob(jobId);\n if (result) {\n this.DeleteConfirmJobId = null;\n }\n } catch (err) {\n console.error('[SchedulingJobs] Delete error:', err);\n } finally {\n this.IsDeleting = false;\n this.cdr.markForCheck();\n }\n }\n\n public IsDeleteConfirming(jobId: string): boolean {\n return this.DeleteConfirmJobId === jobId;\n }\n\n public OpenEntityRecord(job: JobStatistics): void {\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromSingleKeyValuePair('ID', job.jobId);\n SharedService.Instance.OpenEntityRecord('MJ: Scheduled Jobs', compositeKey);\n }\n\n public GetStatusClass(status: string): string {\n switch (status) {\n case 'Active': return 'status-active';\n case 'Paused': return 'status-paused';\n case 'Disabled': return 'status-disabled';\n case 'Pending': return 'status-pending';\n case 'Expired': return 'status-expired';\n default: return '';\n }\n }\n\n public GetSuccessRateColor(rate: number): string {\n if (rate >= 0.9) return '#10b981';\n if (rate >= 0.7) return '#f59e0b';\n return '#ef4444';\n }\n\n public GetTypeIcon(typeName: string): string {\n const lower = typeName.toLowerCase();\n if (lower.includes('agent')) return 'fa-solid fa-robot';\n if (lower.includes('action')) return 'fa-solid fa-bolt';\n return 'fa-solid fa-gear';\n }\n\n public FormatDate(date: Date | undefined): string {\n if (!date) return '-';\n return date.toLocaleString(undefined, {\n month: 'numeric', day: 'numeric', year: '2-digit',\n hour: 'numeric', minute: '2-digit', hour12: true\n });\n }\n\n public FormatPercentage(value: number): string {\n return `${(value * 100).toFixed(1)}%`;\n }\n\n private applyFilters(): void {\n let filtered = [...this.Jobs];\n\n if (this.SearchTerm) {\n const term = this.SearchTerm.toLowerCase();\n filtered = filtered.filter(j =>\n j.jobName.toLowerCase().includes(term) ||\n j.jobType.toLowerCase().includes(term) ||\n (j.description && j.description.toLowerCase().includes(term))\n );\n }\n\n if (this.StatusFilter) {\n filtered = filtered.filter(j => j.status === this.StatusFilter);\n }\n\n if (this.TypeFilter) {\n filtered = filtered.filter(j => j.jobType === this.TypeFilter);\n }\n\n this.FilteredJobs = filtered;\n }\n\n private updateTypeOptions(): void {\n const types = new Set(this.Jobs.map(j => j.jobType));\n this.TypeOptions = ['', ...Array.from(types).sort()];\n }\n\n private emitState(): void {\n this.stateChange.emit({\n searchTerm: this.SearchTerm,\n statusFilter: this.StatusFilter,\n typeFilter: this.TypeFilter\n });\n this.settingsPersistSubject.next();\n }\n}\n","@if (HideToolbar) {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n} @else {\n <mj-page-layout>\n <mj-page-header\n Title=\"Scheduled Jobs\"\n Icon=\"fa-solid fa-calendar-check\"\n Subtitle=\"Configure and manage scheduled jobs\">\n <div meta>\n <mj-stat-badge [Count]=\"FilteredJobs.length\" [Total]=\"Jobs.length\" Label=\"jobs\"></mj-stat-badge>\n </div>\n <div actions>\n <mj-refresh-button (Clicked)=\"Refresh()\"></mj-refresh-button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"action-btn-label\">New Job</span>\n </button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search jobs...\"\n [Value]=\"SearchTerm\"\n (ValueChange)=\"OnSearchChange($event)\">\n </mj-page-search>\n <mj-filter-popover\n [ActiveCount]=\"ActiveFilterCount\"\n [ShowClearAll]=\"ActiveFilterCount > 0\"\n (ClearAllRequested)=\"ResetFilters()\">\n <mj-filter-panel\n [Fields]=\"JobsFilterFields\"\n [Values]=\"JobsFilterValues\"\n (ValuesChange)=\"OnFilterValuesChange($event)\"\n (Reset)=\"ResetFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n </mj-page-header>\n <mj-page-body>\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </mj-page-body>\n </mj-page-layout>\n}\n\n<ng-template #content>\n<div class=\"jobs-container\">\n\n <!-- Loading -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading jobs...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Empty State -->\n @if (!IsLoading && FilteredJobs.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-calendar-xmark\"></i>\n </div>\n <h3>No jobs found</h3>\n @if (SearchTerm || StatusFilter || TypeFilter) {\n <p>Try adjusting your filters</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <p>Create your first scheduled job to get started</p>\n }\n @if (!SearchTerm && !StatusFilter && !TypeFilter) {\n <button class=\"primary-btn\" (click)=\"OpenCreateSlideout()\">\n <i class=\"fa-solid fa-plus\"></i> Create Job\n </button>\n }\n </div>\n }\n\n <!-- Job Cards Grid -->\n @if (!IsLoading && FilteredJobs.length > 0) {\n <div class=\"jobs-grid\">\n @for (job of FilteredJobs; track job) {\n <div\n class=\"job-card\"\n (click)=\"OpenEditSlideout(job)\">\n <!-- Card Header -->\n <div class=\"job-card-header\">\n <div class=\"job-card-title\">\n <i [class]=\"GetTypeIcon(job.jobType)\" class=\"type-icon\"></i>\n <span class=\"job-name\">{{job.jobName}}</span>\n </div>\n <span class=\"status-chip\" [ngClass]=\"GetStatusClass(job.status)\">{{job.status}}</span>\n </div>\n <!-- Card Body -->\n <div class=\"job-card-body\">\n @if (job.description) {\n <div class=\"job-description\">{{job.description}}</div>\n }\n <div class=\"job-meta-grid\">\n <div class=\"meta-item\">\n <span class=\"meta-label\">Type</span>\n <span class=\"meta-value\">{{job.jobType}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Schedule</span>\n <span class=\"meta-value mono\">{{job.cronExpression}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Last Run</span>\n <span class=\"meta-value\">{{FormatDate(job.lastRunAt)}}</span>\n </div>\n <div class=\"meta-item\">\n <span class=\"meta-label\">Next Run</span>\n <span class=\"meta-value\">{{FormatDate(job.nextRunAt)}}</span>\n </div>\n </div>\n <!-- Success Rate Bar -->\n <div class=\"success-section\">\n <div class=\"success-header\">\n <span class=\"success-label\">Success Rate</span>\n <span class=\"success-value\" [style.color]=\"GetSuccessRateColor(job.successRate)\">\n {{FormatPercentage(job.successRate)}}\n </span>\n </div>\n <div class=\"success-bar-track\">\n <div class=\"success-bar-fill\"\n [style.width]=\"(job.successRate * 100) + '%'\"\n [style.background]=\"GetSuccessRateColor(job.successRate)\">\n </div>\n </div>\n <div class=\"run-stats\">\n <span class=\"stat-success\"><i class=\"fa-solid fa-check\"></i> {{job.successCount}}</span>\n <span class=\"stat-failure\"><i class=\"fa-solid fa-xmark\"></i> {{job.failureCount}}</span>\n <span class=\"stat-total\">{{job.totalRuns}} total</span>\n </div>\n </div>\n </div>\n <!-- Delete confirmation overlay -->\n @if (IsDeleteConfirming(job.jobId)) {\n <div class=\"delete-confirm-overlay\" (click)=\"$event.stopPropagation()\">\n <div class=\"delete-confirm-content\">\n <i class=\"fa-solid fa-triangle-exclamation delete-warn-icon\"></i>\n <span class=\"delete-confirm-text\">Delete this scheduled job?</span>\n <div class=\"delete-confirm-actions\">\n <button class=\"delete-confirm-btn\" [disabled]=\"IsDeleting\" (click)=\"ConfirmDelete(job.jobId, $event)\">\n @if (IsDeleting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Deleting...\n } @else {\n Delete\n }\n </button>\n <button class=\"delete-cancel-btn\" (click)=\"CancelDelete($event)\">Cancel</button>\n </div>\n </div>\n </div>\n }\n <!-- Card Footer -->\n <div class=\"job-card-footer\">\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"ToggleJobStatus(job, $event)\">\n <i [class]=\"job.status === 'Active' ? 'fa-solid fa-pause' : 'fa-solid fa-play'\"></i>\n {{job.status === 'Active' ? 'Pause' : 'Resume'}}\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OpenEntityRecord(job); $event.stopPropagation()\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n Full Details\n </button>\n <button mjButton variant=\"danger\" size=\"sm\" (click)=\"ShowDeleteConfirm(job, $event)\">\n <i class=\"fa-solid fa-trash-can\"></i>\n Delete\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Slideout Panel -->\n <mj-scheduled-job-slide-panel\n [IsOpen]=\"SlideoutOpen\"\n [ScheduledJobID]=\"SelectedJob?.jobId ?? null\"\n (Close)=\"CloseSlideout()\"\n (Saved)=\"OnSlideoutSaved()\"\n (Deleted)=\"OnSlideoutSaved()\">\n </mj-scheduled-job-slide-panel>\n</div>\n</ng-template>\n"]}
|