@memberjunction/ng-dashboards 5.21.0 → 5.23.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 +51 -0
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +364 -362
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +2 -2
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +313 -0
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +2792 -0
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +382 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +2683 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -0
- package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +191 -197
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +9 -8
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +305 -299
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +319 -313
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +240 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -0
- package/dist/AI/components/vectors/vector-management-resource.component.js +1767 -0
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -0
- package/dist/AI/index.d.ts +3 -0
- package/dist/AI/index.d.ts.map +1 -1
- package/dist/AI/index.js +6 -0
- package/dist/AI/index.js.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.d.ts +50 -7
- package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.js +161 -193
- package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +10 -12
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +13 -19
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +12 -14
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +61 -68
- package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
- package/dist/APIKeys/api-usage-panel.component.js +10 -11
- package/dist/APIKeys/api-usage-panel.component.js.map +1 -1
- package/dist/Actions/components/actions-list-view.component.js +82 -96
- package/dist/Actions/components/actions-list-view.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +130 -134
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +40 -46
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/Actions/components/code-management.component.js +2 -2
- package/dist/Actions/components/code-management.component.js.map +1 -1
- package/dist/Actions/components/entity-integration.component.js +2 -2
- package/dist/Actions/components/entity-integration.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +127 -132
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/executions-list-view.component.js +2 -2
- package/dist/Actions/components/executions-list-view.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-card.component.js +11 -17
- package/dist/Actions/components/explorer/action-card.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +5 -11
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-list-item.component.js +8 -10
- package/dist/Actions/components/explorer/action-list-item.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-toolbar.component.js +112 -133
- package/dist/Actions/components/explorer/action-toolbar.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-tree-panel.component.js +63 -83
- package/dist/Actions/components/explorer/action-tree-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.js +17 -21
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +17 -21
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Actions/components/scheduled-actions.component.js +2 -2
- package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
- package/dist/Actions/components/security-permissions.component.js +2 -2
- package/dist/Actions/components/security-permissions.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +13 -5
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +168 -145
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts +4 -5
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +197 -200
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts +5 -7
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +142 -148
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/browser/component-browser.component.js +153 -166
- package/dist/ComponentStudio/components/browser/component-browser.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +15 -20
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +16 -21
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +18 -23
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +25 -30
- package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +10 -11
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +24 -35
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +15 -17
- package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +7 -6
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +6 -5
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +7 -6
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +11 -0
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +57 -0
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +9 -9
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +10 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +35 -11
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts +1 -0
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +8 -4
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.d.ts +181 -1
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +1704 -182
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +4 -4
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +246 -259
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/widgets/integration-card.component.js +7 -9
- package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
- package/dist/Integration/integration.module.d.ts +6 -10
- package/dist/Integration/integration.module.d.ts.map +1 -1
- package/dist/Integration/integration.module.js +12 -20
- package/dist/Integration/integration.module.js.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +106 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +607 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +126 -0
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +1086 -0
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.d.ts +56 -0
- package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.js +291 -0
- package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.js.map +1 -0
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +85 -0
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +461 -0
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/index.d.ts +5 -0
- package/dist/KnowledgeHub/index.d.ts.map +1 -0
- package/dist/KnowledgeHub/index.js +6 -0
- package/dist/KnowledgeHub/index.js.map +1 -0
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +9 -7
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +5 -4
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +10 -9
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +141 -132
- package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-log-detail-panel.component.js +4 -4
- package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +141 -128
- package/dist/MCP/components/mcp-server-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +210 -218
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +2 -2
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/MCP/mcp.module.d.ts +6 -9
- package/dist/MCP/mcp.module.d.ts.map +1 -1
- package/dist/MCP/mcp.module.js +20 -22
- package/dist/MCP/mcp.module.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +5 -1
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +5 -4
- package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +6 -5
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +93 -92
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.js +1 -0
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts +7 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +63 -8
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.d.ts +9 -1
- package/dist/Testing/components/testing-dashboard-tab.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.js +109 -62
- package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts +2 -1
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +241 -200
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.d.ts +7 -1
- package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.js +63 -8
- package/dist/Testing/components/testing-runs-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-runs.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-runs.component.js +7 -5
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.d.ts +9 -1
- package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +122 -54
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/actions-dashboards.module.d.ts +8 -13
- package/dist/actions-dashboards.module.d.ts.map +1 -1
- package/dist/actions-dashboards.module.js +6 -27
- package/dist/actions-dashboards.module.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +14 -11
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +58 -44
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/communication-dashboards.module.d.ts +4 -8
- package/dist/communication-dashboards.module.d.ts.map +1 -1
- package/dist/communication-dashboards.module.js +0 -19
- package/dist/communication-dashboards.module.js.map +1 -1
- package/dist/component-studio-dashboards.module.d.ts +7 -11
- package/dist/component-studio-dashboards.module.d.ts.map +1 -1
- package/dist/component-studio-dashboards.module.js +22 -34
- package/dist/component-studio-dashboards.module.js.map +1 -1
- package/dist/core-dashboards.module.d.ts +13 -18
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +18 -31
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/credentials-dashboards.module.d.ts +5 -8
- package/dist/credentials-dashboards.module.d.ts.map +1 -1
- package/dist/credentials-dashboards.module.js +3 -19
- package/dist/credentials-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +7 -13
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +0 -27
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/lists-dashboards.module.d.ts +5 -8
- package/dist/lists-dashboards.module.d.ts.map +1 -1
- package/dist/lists-dashboards.module.js +3 -19
- package/dist/lists-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +5 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +6 -1
- package/dist/public-api.js.map +1 -1
- package/dist/scheduling-dashboards.module.d.ts +6 -10
- package/dist/scheduling-dashboards.module.d.ts.map +1 -1
- package/dist/scheduling-dashboards.module.js +3 -23
- package/dist/scheduling-dashboards.module.js.map +1 -1
- package/dist/testing-dashboards.module.d.ts +7 -12
- package/dist/testing-dashboards.module.d.ts.map +1 -1
- package/dist/testing-dashboards.module.js +4 -27
- package/dist/testing-dashboards.module.js.map +1 -1
- package/package.json +47 -53
|
@@ -8,7 +8,8 @@ import * as i0 from "@angular/core";
|
|
|
8
8
|
import * as i1 from "../services/scheduling-instrumentation.service";
|
|
9
9
|
import * as i2 from "@angular/common";
|
|
10
10
|
import * as i3 from "@angular/forms";
|
|
11
|
-
import * as i4 from "@memberjunction/ng-
|
|
11
|
+
import * as i4 from "@memberjunction/ng-ui-components";
|
|
12
|
+
import * as i5 from "@memberjunction/ng-shared-generic";
|
|
12
13
|
function SchedulingActivityComponent_For_10_Template(rf, ctx) { if (rf & 1) {
|
|
13
14
|
i0.ɵɵelementStart(0, "option", 8);
|
|
14
15
|
i0.ɵɵtext(1);
|
|
@@ -652,7 +653,7 @@ export class SchedulingActivityComponent {
|
|
|
652
653
|
this.settingsPersistSubject.next();
|
|
653
654
|
}
|
|
654
655
|
static ɵfac = function SchedulingActivityComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SchedulingActivityComponent)(i0.ɵɵdirectiveInject(i1.SchedulingInstrumentationService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
655
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingActivityComponent, selectors: [["app-scheduling-activity"]], inputs: { initialState: "initialState" }, outputs: { stateChange: "stateChange" }, standalone: false, decls: 25, vars: 5, consts: [[1, "activity-container"], [1, "activity-toolbar"], [1, "toolbar-left"], [1, "search-box"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search executions...", 3, "input", "value"], [1, "filter-select", 3, "change", "value"], ["value", ""], [3, "value"], [1, "toolbar-right"], [1, "time-range-group"], [1, "range-btn", 3, "active"], [
|
|
656
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SchedulingActivityComponent, selectors: [["app-scheduling-activity"]], inputs: { initialState: "initialState" }, outputs: { stateChange: "stateChange" }, standalone: false, decls: 25, vars: 5, consts: [[1, "activity-container"], [1, "activity-toolbar"], [1, "toolbar-left"], [1, "search-box"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search executions...", 3, "input", "value"], [1, "filter-select", 3, "change", "value"], ["value", ""], [3, "value"], [1, "toolbar-right"], [1, "time-range-group"], [1, "range-btn", 3, "active"], ["mjButton", "", "variant", "secondary", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], [1, "loading-container"], [1, "activity-content"], [1, "range-btn", 3, "click"], ["text", "Loading activity...", "size", "medium"], [1, "type-cards-row"], [1, "panel"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "result-count"], [1, "panel-body", "table-container"], [1, "empty-state-small"], [1, "data-table"], [1, "type-card"], [1, "type-card-icon"], [1, "type-card-info"], [1, "type-card-name"], [1, "type-card-stats"], [1, "dot"], [1, "type-card-bar"], [1, "type-bar-fill"], [1, "fa-solid", "fa-chart-bar"], [1, "panel-body", "chart-container"], [1, "trend-chart"], [1, "chart-column"], [1, "chart-legend"], [1, "legend-item"], [1, "legend-dot", "success"], [1, "legend-dot", "failure"], [1, "bars-wrapper"], [1, "bar", "success-bar", 3, "title"], [1, "bar", "failure-bar", 3, "height", "title"], [1, "chart-label"], [1, "bar", "failure-bar", 3, "title"], [1, "fa-solid", "fa-inbox"], [1, "col-expand"], [1, "exec-row", 3, "click"], [1, "fa-solid", "fa-chevron-right", "expand-icon"], [1, "exec-status-badge", 3, "ngClass"], [1, "cell-name"], [1, "cell-meta"], [1, "cell-error"], [1, "exec-detail-row"], [1, "exec-detail-content"], [1, "exec-detail-grid"], [1, "detail-item"], [1, "detail-label"], [1, "detail-value"], [1, "exec-detail-actions"], [1, "detail-action-btn", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "detail-action-btn", "secondary", 3, "click"], [1, "fa-solid", "fa-briefcase"], [1, "detail-value", "error-text"]], template: function SchedulingActivityComponent_Template(rf, ctx) { if (rf & 1) {
|
|
656
657
|
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3);
|
|
657
658
|
i0.ɵɵelement(4, "i", 4);
|
|
658
659
|
i0.ɵɵelementStart(5, "input", 5);
|
|
@@ -700,11 +701,11 @@ export class SchedulingActivityComponent {
|
|
|
700
701
|
i0.ɵɵconditional(ctx.IsLoading ? 23 : -1);
|
|
701
702
|
i0.ɵɵadvance();
|
|
702
703
|
i0.ɵɵconditional(!ctx.IsLoading ? 24 : -1);
|
|
703
|
-
} }, dependencies: [i2.NgClass, i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i4.LoadingComponent], styles: [".activity-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n\n\n.activity-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.search-box[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n min-width: 220px;\n transition: border-color 0.2s;\n}\n\n.search-box[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.search-box[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-size: 0.85rem; }\n\n.search-box[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: none; outline: none; background: transparent;\n font-size: 0.85rem; color: var(--mj-text-primary); width: 100%;\n}\n\n.filter-select[_ngcontent-%COMP%] {\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n cursor: pointer;\n outline: none;\n}\n\n.time-range-group[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.range-btn[_ngcontent-%COMP%] {\n padding: 8px 14px;\n border: none;\n background: transparent;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.range-btn[_ngcontent-%COMP%]:last-child { border-right: none; }\n\n.range-btn[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-sunken); }\n\n.range-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.control-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.control-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.result-count[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n\n\n.type-cards-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.type-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-radius: 14px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n flex: 1;\n min-width: 240px;\n transition: all 0.2s ease;\n}\n\n.type-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.type-card-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: 12px;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.type-card-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.type-card-name[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.type-card-stats[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.type-card-stats[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%] {\n margin: 0 4px;\n}\n\n.type-card-bar[_ngcontent-%COMP%] {\n width: 60px;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.type-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 3px;\n transition: width 0.5s;\n}\n\n\n\n.panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n font-size: 0.95rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n.panel-body[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.chart-container[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.table-container[_ngcontent-%COMP%] {\n padding: 0;\n max-height: 600px;\n overflow-y: auto;\n}\n\n\n\n.trend-chart[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n height: 220px;\n align-items: flex-end;\n padding-bottom: 50px;\n overflow-x: auto;\n}\n\n.chart-column[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n flex: 1;\n min-width: 24px;\n max-width: 40px;\n height: 100%;\n}\n\n.bars-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1px;\n flex: 1;\n justify-content: flex-end;\n width: 100%;\n}\n\n.bar[_ngcontent-%COMP%] {\n width: 100%;\n border-radius: 3px 3px 0 0;\n min-height: 2px;\n transition: height 0.3s;\n}\n\n.success-bar[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n}\n\n.failure-bar[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n border-radius: 0;\n}\n\n.chart-label[_ngcontent-%COMP%] {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n margin-top: 6px;\n white-space: nowrap;\n text-align: center;\n transform: rotate(-45deg);\n transform-origin: top center;\n height: 40px;\n overflow: visible;\n}\n\n.chart-label.hidden-label[_ngcontent-%COMP%] {\n visibility: hidden;\n}\n\n.chart-legend[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n gap: 20px;\n margin-top: 12px;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.legend-dot[_ngcontent-%COMP%] {\n width: 10px;\n height: 10px;\n border-radius: 3px;\n}\n\n.legend-dot.success[_ngcontent-%COMP%] { background: var(--mj-status-success); }\n.legend-dot.failure[_ngcontent-%COMP%] { background: var(--mj-status-error); }\n\n\n\n.data-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-sunken);\n z-index: 1;\n}\n\n.data-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 16px;\n font-size: 0.85rem;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.data-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.cell-name[_ngcontent-%COMP%] { font-weight: 600; color: var(--mj-text-primary); }\n.cell-meta[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.cell-error[_ngcontent-%COMP%] { color: var(--mj-status-error); font-size: 0.8rem; max-width: 300px; }\n\n.exec-status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n white-space: nowrap;\n}\n\n.exec-status-badge.status-running[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.exec-status-badge.status-success[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.exec-status-badge.status-error[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.exec-status-badge.status-warning[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n\n\n.col-expand[_ngcontent-%COMP%] {\n width: 32px;\n text-align: center;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n.expand-icon.rotated[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n.exec-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.exec-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.exec-row.expanded[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-bottom-color: transparent;\n}\n\n.exec-detail-row[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 0 !important;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.exec-detail-content[_ngcontent-%COMP%] {\n padding: 16px 20px 16px 48px;\n background: var(--mj-bg-surface-sunken);\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.exec-detail-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 12px 24px;\n margin-bottom: 14px;\n}\n\n.detail-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n}\n\n.detail-value.error-text[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-size: 0.8rem;\n word-break: break-word;\n}\n\n.exec-detail-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding-top: 10px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.detail-action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-size: 0.8rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.detail-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.detail-action-btn.secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n.detail-action-btn.secondary[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.empty-state-small[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 48px 16px;\n color: var(--mj-text-muted);\n}\n\n.empty-state-small[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 2rem; color: var(--mj-border-strong); }\n.empty-state-small[_ngcontent-%COMP%] span[_ngcontent-%COMP%] { font-size: 0.85rem; }\n\n\n\n@media (max-width: 1024px) {\n .type-cards-row[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n .type-card[_ngcontent-%COMP%] {\n min-width: auto;\n }\n}\n\n@media (max-width: 768px) {\n .activity-toolbar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n .toolbar-right[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n justify-content: space-between;\n }\n .search-box[_ngcontent-%COMP%] {\n min-width: auto;\n flex: 1;\n }\n .trend-chart[_ngcontent-%COMP%] {\n height: 120px;\n }\n .data-table[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n }\n}"], changeDetection: 0 });
|
|
704
|
+
} }, dependencies: [i2.NgClass, i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i4.MJButtonDirective, i5.LoadingComponent], styles: [".activity-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n\n\n.activity-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.search-box[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n min-width: 220px;\n transition: border-color 0.2s;\n}\n\n.search-box[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.search-box[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-size: 0.85rem; }\n\n.search-box[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: none; outline: none; background: transparent;\n font-size: 0.85rem; color: var(--mj-text-primary); width: 100%;\n}\n\n.filter-select[_ngcontent-%COMP%] {\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n cursor: pointer;\n outline: none;\n}\n\n.time-range-group[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.range-btn[_ngcontent-%COMP%] {\n padding: 8px 14px;\n border: none;\n background: transparent;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.range-btn[_ngcontent-%COMP%]:last-child { border-right: none; }\n\n.range-btn[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-sunken); }\n\n.range-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.control-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.control-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.result-count[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n\n\n.type-cards-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.type-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-radius: 14px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n flex: 1;\n min-width: 240px;\n transition: all 0.2s ease;\n}\n\n.type-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.type-card-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: 12px;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.type-card-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.type-card-name[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.type-card-stats[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.type-card-stats[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%] {\n margin: 0 4px;\n}\n\n.type-card-bar[_ngcontent-%COMP%] {\n width: 60px;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.type-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 3px;\n transition: width 0.5s;\n}\n\n\n\n.panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n font-size: 0.95rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n.panel-body[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.chart-container[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.table-container[_ngcontent-%COMP%] {\n padding: 0;\n max-height: 600px;\n overflow-y: auto;\n}\n\n\n\n.trend-chart[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n height: 220px;\n align-items: flex-end;\n padding-bottom: 50px;\n overflow-x: auto;\n}\n\n.chart-column[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n flex: 1;\n min-width: 24px;\n max-width: 40px;\n height: 100%;\n}\n\n.bars-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1px;\n flex: 1;\n justify-content: flex-end;\n width: 100%;\n}\n\n.bar[_ngcontent-%COMP%] {\n width: 100%;\n border-radius: 3px 3px 0 0;\n min-height: 2px;\n transition: height 0.3s;\n}\n\n.success-bar[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n}\n\n.failure-bar[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n border-radius: 0;\n}\n\n.chart-label[_ngcontent-%COMP%] {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n margin-top: 6px;\n white-space: nowrap;\n text-align: center;\n transform: rotate(-45deg);\n transform-origin: top center;\n height: 40px;\n overflow: visible;\n}\n\n.chart-label.hidden-label[_ngcontent-%COMP%] {\n visibility: hidden;\n}\n\n.chart-legend[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n gap: 20px;\n margin-top: 12px;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.legend-dot[_ngcontent-%COMP%] {\n width: 10px;\n height: 10px;\n border-radius: 3px;\n}\n\n.legend-dot.success[_ngcontent-%COMP%] { background: var(--mj-status-success); }\n.legend-dot.failure[_ngcontent-%COMP%] { background: var(--mj-status-error); }\n\n\n\n.data-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-sunken);\n z-index: 1;\n}\n\n.data-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 16px;\n font-size: 0.85rem;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.data-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.cell-name[_ngcontent-%COMP%] { font-weight: 600; color: var(--mj-text-primary); }\n.cell-meta[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.cell-error[_ngcontent-%COMP%] { color: var(--mj-status-error); font-size: 0.8rem; max-width: 300px; }\n\n.exec-status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n white-space: nowrap;\n}\n\n.exec-status-badge.status-running[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.exec-status-badge.status-success[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.exec-status-badge.status-error[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.exec-status-badge.status-warning[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n\n\n.col-expand[_ngcontent-%COMP%] {\n width: 32px;\n text-align: center;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n.expand-icon.rotated[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n.exec-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.exec-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.exec-row.expanded[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-bottom-color: transparent;\n}\n\n.exec-detail-row[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 0 !important;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.exec-detail-content[_ngcontent-%COMP%] {\n padding: 16px 20px 16px 48px;\n background: var(--mj-bg-surface-sunken);\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.exec-detail-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 12px 24px;\n margin-bottom: 14px;\n}\n\n.detail-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n}\n\n.detail-value.error-text[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-size: 0.8rem;\n word-break: break-word;\n}\n\n.exec-detail-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding-top: 10px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.detail-action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-size: 0.8rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.detail-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.detail-action-btn.secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n.detail-action-btn.secondary[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.empty-state-small[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 48px 16px;\n color: var(--mj-text-muted);\n}\n\n.empty-state-small[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 2rem; color: var(--mj-border-strong); }\n.empty-state-small[_ngcontent-%COMP%] span[_ngcontent-%COMP%] { font-size: 0.85rem; }\n\n\n\n@media (max-width: 1024px) {\n .type-cards-row[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n .type-card[_ngcontent-%COMP%] {\n min-width: auto;\n }\n}\n\n@media (max-width: 768px) {\n .activity-toolbar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n .toolbar-right[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n justify-content: space-between;\n }\n .search-box[_ngcontent-%COMP%] {\n min-width: auto;\n flex: 1;\n }\n .trend-chart[_ngcontent-%COMP%] {\n height: 120px;\n }\n .data-table[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n }\n}"], changeDetection: 0 });
|
|
704
705
|
}
|
|
705
706
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SchedulingActivityComponent, [{
|
|
706
707
|
type: Component,
|
|
707
|
-
args: [{ standalone: false, selector: 'app-scheduling-activity', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"activity-container\">\n <!-- Toolbar -->\n <div class=\"activity-toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\" placeholder=\"Search executions...\"\n [value]=\"SearchTerm\"\n (input)=\"OnSearchChange($any($event.target).value)\" />\n </div>\n <select class=\"filter-select\" [value]=\"StatusFilter\" (change)=\"OnStatusFilterChange($any($event.target).value)\">\n <option value=\"\">All Statuses</option>\n @for (s of StatusOptions.slice(1); track s) {\n <option [value]=\"s\">{{s}}</option>\n }\n </select>\n <select class=\"filter-select\" [value]=\"JobNameFilter\" (change)=\"OnJobNameFilterChange($any($event.target).value)\">\n <option value=\"\">All Jobs</option>\n @for (name of UniqueJobNames; track name) {\n <option [value]=\"name\">{{name}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <div class=\"time-range-group\">\n @for (range of TimeRanges; track range) {\n <button\n class=\"range-btn\"\n [class.active]=\"SelectedTimeRange === range.value\"\n (click)=\"OnTimeRangeChange(range.value)\">\n {{range.label}}\n </button>\n }\n </div>\n <button class=\"control-btn\" (click)=\"Refresh()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n </div>\n </div>\n\n <!-- Loading -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading activity...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n @if (!IsLoading) {\n <div class=\"activity-content\">\n <!-- Job Type Summary Cards -->\n @if (JobTypes.length > 0) {\n <div class=\"type-cards-row\">\n @for (type of JobTypes; track type) {\n <div class=\"type-card\">\n <div class=\"type-card-icon\">\n <i [class]=\"GetTypeIcon(type.typeName)\"></i>\n </div>\n <div class=\"type-card-info\">\n <div class=\"type-card-name\">{{type.typeName}}</div>\n <div class=\"type-card-stats\">\n <span>{{type.activeJobsCount}} active</span>\n <span class=\"dot\">·</span>\n <span>{{type.totalRuns}} runs</span>\n <span class=\"dot\">·</span>\n <span [style.color]=\"GetSuccessRateColor(type.successRate)\">\n {{FormatPercentage(type.successRate)}}\n </span>\n </div>\n </div>\n <div class=\"type-card-bar\">\n <div class=\"type-bar-fill\"\n [style.width]=\"(type.successRate * 100) + '%'\"\n [style.background]=\"GetSuccessRateColor(type.successRate)\">\n </div>\n </div>\n </div>\n }\n </div>\n }\n <!-- Execution Trends Chart -->\n @if (Trends.length > 0) {\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-chart-bar\"></i> Execution Trends\n </div>\n <span class=\"result-count\">{{FilteredExecutions.length}} executions</span>\n </div>\n <div class=\"panel-body chart-container\">\n <div class=\"trend-chart\">\n @for (trend of Trends; track trend; let i = $index) {\n <div class=\"chart-column\">\n <div class=\"bars-wrapper\">\n <div class=\"bar success-bar\"\n [style.height]=\"GetBarHeight(trend.successes)\"\n [title]=\"trend.successes + ' successful'\">\n </div>\n @if (trend.failures > 0) {\n <div class=\"bar failure-bar\"\n [style.height]=\"GetBarHeight(trend.failures)\"\n [title]=\"trend.failures + ' failed'\">\n </div>\n }\n </div>\n <div class=\"chart-label\" [class.hidden-label]=\"!ShouldShowLabel(i)\" >{{FormatChartLabel(trend.timestamp)}}</div>\n </div>\n }\n </div>\n <div class=\"chart-legend\">\n <span class=\"legend-item\"><span class=\"legend-dot success\"></span> Successful</span>\n <span class=\"legend-item\"><span class=\"legend-dot failure\"></span> Failed</span>\n </div>\n </div>\n </div>\n }\n <!-- Execution History Table -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i> Execution History\n </div>\n <span class=\"result-count\">{{FilteredExecutions.length}} of {{Executions.length}}</span>\n </div>\n <div class=\"panel-body table-container\">\n @if (FilteredExecutions.length === 0) {\n <div class=\"empty-state-small\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No executions found for this time range</span>\n </div>\n }\n @if (FilteredExecutions.length > 0) {\n <table class=\"data-table\">\n <thead>\n <tr>\n <th class=\"col-expand\"></th>\n <th>Status</th>\n <th>Job Name</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Error</th>\n </tr>\n </thead>\n <tbody>\n @for (exec of FilteredExecutions; track exec) {\n <tr class=\"exec-row\" [class.expanded]=\"IsExpanded(exec)\" (click)=\"ToggleExpand(exec)\">\n <td class=\"col-expand\">\n <i class=\"fa-solid fa-chevron-right expand-icon\"\n [class.rotated]=\"IsExpanded(exec)\"></i>\n </td>\n <td>\n <span class=\"exec-status-badge\" [ngClass]=\"GetStatusClass(exec.status)\">\n <i [class]=\"GetStatusIcon(exec.status)\"></i>\n {{exec.status}}\n </span>\n </td>\n <td class=\"cell-name\">{{exec.jobName}}</td>\n <td class=\"cell-meta\">{{FormatDateTime(exec.startedAt)}}</td>\n <td class=\"cell-meta\">{{FormatDuration(exec.duration)}}</td>\n <td class=\"cell-error\">{{TruncateError(exec.errorMessage)}}</td>\n </tr>\n @if (IsExpanded(exec)) {\n <tr class=\"exec-detail-row\">\n <td [attr.colspan]=\"6\">\n <div class=\"exec-detail-content\">\n <div class=\"exec-detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Job Name</span>\n <span class=\"detail-value\">{{exec.jobName}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Started</span>\n <span class=\"detail-value\">{{FormatDateTime(exec.startedAt)}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Completed</span>\n <span class=\"detail-value\">{{exec.completedAt ? FormatDateTime(exec.completedAt) : '-'}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Duration</span>\n <span class=\"detail-value\">{{FormatDuration(exec.duration)}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Status</span>\n <span class=\"detail-value\">\n <span class=\"exec-status-badge\" [ngClass]=\"GetStatusClass(exec.status)\">\n <i [class]=\"GetStatusIcon(exec.status)\"></i>\n {{exec.status}}\n </span>\n </span>\n </div>\n @if (exec.errorMessage) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Error</span>\n <span class=\"detail-value error-text\">{{exec.errorMessage}}</span>\n </div>\n }\n </div>\n <div class=\"exec-detail-actions\">\n <button class=\"detail-action-btn\" (click)=\"OpenExecutionRecord(exec, $event)\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i> Open Run Record\n </button>\n <button class=\"detail-action-btn secondary\" (click)=\"OpenJobRecord(exec, $event)\">\n <i class=\"fa-solid fa-briefcase\"></i> Open Job\n </button>\n </div>\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n }\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".activity-container {\n display: flex;\n flex-direction: column;\n gap: 20px;\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.activity-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: 220px;\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 { color: var(--mj-text-muted); font-size: 0.85rem; }\n\n.search-box input {\n border: none; outline: none; background: transparent;\n font-size: 0.85rem; color: var(--mj-text-primary); 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}\n\n.time-range-group {\n display: flex;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.range-btn {\n padding: 8px 14px;\n border: none;\n background: transparent;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.range-btn:last-child { border-right: none; }\n\n.range-btn:hover { background: var(--mj-bg-surface-sunken); }\n\n.range-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\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.result-count {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n/* \u2500\u2500 Type Summary Cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.type-cards-row {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.type-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-radius: 14px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n flex: 1;\n min-width: 240px;\n transition: all 0.2s ease;\n}\n\n.type-card:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.type-card-icon {\n width: 44px;\n height: 44px;\n border-radius: 12px;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.type-card-info {\n flex: 1;\n}\n\n.type-card-name {\n font-weight: 700;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.type-card-stats {\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.type-card-stats .dot {\n margin: 0 4px;\n}\n\n.type-card-bar {\n width: 60px;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.type-bar-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.5s;\n}\n\n/* \u2500\u2500 Panels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.panel {\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n}\n\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-title {\n font-size: 0.95rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title i { color: var(--mj-brand-primary); }\n\n.panel-body {\n padding: 20px;\n}\n\n.chart-container {\n padding: 20px;\n}\n\n.table-container {\n padding: 0;\n max-height: 600px;\n overflow-y: auto;\n}\n\n/* \u2500\u2500 Trend Chart \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.trend-chart {\n display: flex;\n gap: 4px;\n height: 220px;\n align-items: flex-end;\n padding-bottom: 50px;\n overflow-x: auto;\n}\n\n.chart-column {\n display: flex;\n flex-direction: column;\n align-items: center;\n flex: 1;\n min-width: 24px;\n max-width: 40px;\n height: 100%;\n}\n\n.bars-wrapper {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1px;\n flex: 1;\n justify-content: flex-end;\n width: 100%;\n}\n\n.bar {\n width: 100%;\n border-radius: 3px 3px 0 0;\n min-height: 2px;\n transition: height 0.3s;\n}\n\n.success-bar {\n background: var(--mj-status-success);\n}\n\n.failure-bar {\n background: var(--mj-status-error);\n border-radius: 0;\n}\n\n.chart-label {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n margin-top: 6px;\n white-space: nowrap;\n text-align: center;\n transform: rotate(-45deg);\n transform-origin: top center;\n height: 40px;\n overflow: visible;\n}\n\n.chart-label.hidden-label {\n visibility: hidden;\n}\n\n.chart-legend {\n display: flex;\n justify-content: center;\n gap: 20px;\n margin-top: 12px;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.legend-dot {\n width: 10px;\n height: 10px;\n border-radius: 3px;\n}\n\n.legend-dot.success { background: var(--mj-status-success); }\n.legend-dot.failure { background: var(--mj-status-error); }\n\n/* \u2500\u2500 Data Table \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.data-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table th {\n text-align: left;\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-sunken);\n z-index: 1;\n}\n\n.data-table td {\n padding: 10px 16px;\n font-size: 0.85rem;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.data-table tbody tr:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.cell-name { font-weight: 600; color: var(--mj-text-primary); }\n.cell-meta { color: var(--mj-text-secondary); }\n.cell-error { color: var(--mj-status-error); font-size: 0.8rem; max-width: 300px; }\n\n.exec-status-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n white-space: nowrap;\n}\n\n.exec-status-badge.status-running { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.exec-status-badge.status-success { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.exec-status-badge.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.exec-status-badge.status-warning { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n/* \u2500\u2500 Expandable Rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.col-expand {\n width: 32px;\n text-align: center;\n}\n\n.expand-icon {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n.expand-icon.rotated {\n transform: rotate(90deg);\n}\n\n.exec-row {\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.exec-row:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.exec-row.expanded {\n background: var(--mj-bg-surface-sunken);\n border-bottom-color: transparent;\n}\n\n.exec-detail-row td {\n padding: 0 !important;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.exec-detail-content {\n padding: 16px 20px 16px 48px;\n background: var(--mj-bg-surface-sunken);\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.exec-detail-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 12px 24px;\n margin-bottom: 14px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-label {\n font-size: 0.7rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.detail-value {\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n}\n\n.detail-value.error-text {\n color: var(--mj-status-error);\n font-size: 0.8rem;\n word-break: break-word;\n}\n\n.exec-detail-actions {\n display: flex;\n gap: 8px;\n padding-top: 10px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.detail-action-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-size: 0.8rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.detail-action-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.detail-action-btn.secondary {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n.detail-action-btn.secondary:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.empty-state-small {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 48px 16px;\n color: var(--mj-text-muted);\n}\n\n.empty-state-small i { font-size: 2rem; color: var(--mj-border-strong); }\n.empty-state-small span { font-size: 0.85rem; }\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 .type-cards-row {\n flex-direction: column;\n }\n .type-card {\n min-width: auto;\n }\n}\n\n@media (max-width: 768px) {\n .activity-toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n .toolbar-right {\n flex-wrap: wrap;\n justify-content: space-between;\n }\n .search-box {\n min-width: auto;\n flex: 1;\n }\n .trend-chart {\n height: 120px;\n }\n .data-table {\n font-size: 0.8rem;\n }\n}\n"] }]
|
|
708
|
+
args: [{ standalone: false, selector: 'app-scheduling-activity', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"activity-container\">\n <!-- Toolbar -->\n <div class=\"activity-toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\" placeholder=\"Search executions...\"\n [value]=\"SearchTerm\"\n (input)=\"OnSearchChange($any($event.target).value)\" />\n </div>\n <select class=\"filter-select\" [value]=\"StatusFilter\" (change)=\"OnStatusFilterChange($any($event.target).value)\">\n <option value=\"\">All Statuses</option>\n @for (s of StatusOptions.slice(1); track s) {\n <option [value]=\"s\">{{s}}</option>\n }\n </select>\n <select class=\"filter-select\" [value]=\"JobNameFilter\" (change)=\"OnJobNameFilterChange($any($event.target).value)\">\n <option value=\"\">All Jobs</option>\n @for (name of UniqueJobNames; track name) {\n <option [value]=\"name\">{{name}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <div class=\"time-range-group\">\n @for (range of TimeRanges; track range) {\n <button\n class=\"range-btn\"\n [class.active]=\"SelectedTimeRange === range.value\"\n (click)=\"OnTimeRangeChange(range.value)\">\n {{range.label}}\n </button>\n }\n </div>\n <button mjButton variant=\"secondary\" (click)=\"Refresh()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n </div>\n </div>\n\n <!-- Loading -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading activity...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n @if (!IsLoading) {\n <div class=\"activity-content\">\n <!-- Job Type Summary Cards -->\n @if (JobTypes.length > 0) {\n <div class=\"type-cards-row\">\n @for (type of JobTypes; track type) {\n <div class=\"type-card\">\n <div class=\"type-card-icon\">\n <i [class]=\"GetTypeIcon(type.typeName)\"></i>\n </div>\n <div class=\"type-card-info\">\n <div class=\"type-card-name\">{{type.typeName}}</div>\n <div class=\"type-card-stats\">\n <span>{{type.activeJobsCount}} active</span>\n <span class=\"dot\">·</span>\n <span>{{type.totalRuns}} runs</span>\n <span class=\"dot\">·</span>\n <span [style.color]=\"GetSuccessRateColor(type.successRate)\">\n {{FormatPercentage(type.successRate)}}\n </span>\n </div>\n </div>\n <div class=\"type-card-bar\">\n <div class=\"type-bar-fill\"\n [style.width]=\"(type.successRate * 100) + '%'\"\n [style.background]=\"GetSuccessRateColor(type.successRate)\">\n </div>\n </div>\n </div>\n }\n </div>\n }\n <!-- Execution Trends Chart -->\n @if (Trends.length > 0) {\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-chart-bar\"></i> Execution Trends\n </div>\n <span class=\"result-count\">{{FilteredExecutions.length}} executions</span>\n </div>\n <div class=\"panel-body chart-container\">\n <div class=\"trend-chart\">\n @for (trend of Trends; track trend; let i = $index) {\n <div class=\"chart-column\">\n <div class=\"bars-wrapper\">\n <div class=\"bar success-bar\"\n [style.height]=\"GetBarHeight(trend.successes)\"\n [title]=\"trend.successes + ' successful'\">\n </div>\n @if (trend.failures > 0) {\n <div class=\"bar failure-bar\"\n [style.height]=\"GetBarHeight(trend.failures)\"\n [title]=\"trend.failures + ' failed'\">\n </div>\n }\n </div>\n <div class=\"chart-label\" [class.hidden-label]=\"!ShouldShowLabel(i)\" >{{FormatChartLabel(trend.timestamp)}}</div>\n </div>\n }\n </div>\n <div class=\"chart-legend\">\n <span class=\"legend-item\"><span class=\"legend-dot success\"></span> Successful</span>\n <span class=\"legend-item\"><span class=\"legend-dot failure\"></span> Failed</span>\n </div>\n </div>\n </div>\n }\n <!-- Execution History Table -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i> Execution History\n </div>\n <span class=\"result-count\">{{FilteredExecutions.length}} of {{Executions.length}}</span>\n </div>\n <div class=\"panel-body table-container\">\n @if (FilteredExecutions.length === 0) {\n <div class=\"empty-state-small\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No executions found for this time range</span>\n </div>\n }\n @if (FilteredExecutions.length > 0) {\n <table class=\"data-table\">\n <thead>\n <tr>\n <th class=\"col-expand\"></th>\n <th>Status</th>\n <th>Job Name</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Error</th>\n </tr>\n </thead>\n <tbody>\n @for (exec of FilteredExecutions; track exec) {\n <tr class=\"exec-row\" [class.expanded]=\"IsExpanded(exec)\" (click)=\"ToggleExpand(exec)\">\n <td class=\"col-expand\">\n <i class=\"fa-solid fa-chevron-right expand-icon\"\n [class.rotated]=\"IsExpanded(exec)\"></i>\n </td>\n <td>\n <span class=\"exec-status-badge\" [ngClass]=\"GetStatusClass(exec.status)\">\n <i [class]=\"GetStatusIcon(exec.status)\"></i>\n {{exec.status}}\n </span>\n </td>\n <td class=\"cell-name\">{{exec.jobName}}</td>\n <td class=\"cell-meta\">{{FormatDateTime(exec.startedAt)}}</td>\n <td class=\"cell-meta\">{{FormatDuration(exec.duration)}}</td>\n <td class=\"cell-error\">{{TruncateError(exec.errorMessage)}}</td>\n </tr>\n @if (IsExpanded(exec)) {\n <tr class=\"exec-detail-row\">\n <td [attr.colspan]=\"6\">\n <div class=\"exec-detail-content\">\n <div class=\"exec-detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Job Name</span>\n <span class=\"detail-value\">{{exec.jobName}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Started</span>\n <span class=\"detail-value\">{{FormatDateTime(exec.startedAt)}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Completed</span>\n <span class=\"detail-value\">{{exec.completedAt ? FormatDateTime(exec.completedAt) : '-'}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Duration</span>\n <span class=\"detail-value\">{{FormatDuration(exec.duration)}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Status</span>\n <span class=\"detail-value\">\n <span class=\"exec-status-badge\" [ngClass]=\"GetStatusClass(exec.status)\">\n <i [class]=\"GetStatusIcon(exec.status)\"></i>\n {{exec.status}}\n </span>\n </span>\n </div>\n @if (exec.errorMessage) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Error</span>\n <span class=\"detail-value error-text\">{{exec.errorMessage}}</span>\n </div>\n }\n </div>\n <div class=\"exec-detail-actions\">\n <button class=\"detail-action-btn\" (click)=\"OpenExecutionRecord(exec, $event)\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i> Open Run Record\n </button>\n <button class=\"detail-action-btn secondary\" (click)=\"OpenJobRecord(exec, $event)\">\n <i class=\"fa-solid fa-briefcase\"></i> Open Job\n </button>\n </div>\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n }\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".activity-container {\n display: flex;\n flex-direction: column;\n gap: 20px;\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.activity-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: 220px;\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 { color: var(--mj-text-muted); font-size: 0.85rem; }\n\n.search-box input {\n border: none; outline: none; background: transparent;\n font-size: 0.85rem; color: var(--mj-text-primary); 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}\n\n.time-range-group {\n display: flex;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.range-btn {\n padding: 8px 14px;\n border: none;\n background: transparent;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.range-btn:last-child { border-right: none; }\n\n.range-btn:hover { background: var(--mj-bg-surface-sunken); }\n\n.range-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\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.result-count {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 300px;\n}\n\n/* \u2500\u2500 Type Summary Cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.type-cards-row {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.type-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-card);\n border-radius: 14px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n flex: 1;\n min-width: 240px;\n transition: all 0.2s ease;\n}\n\n.type-card:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.type-card-icon {\n width: 44px;\n height: 44px;\n border-radius: 12px;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.type-card-info {\n flex: 1;\n}\n\n.type-card-name {\n font-weight: 700;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.type-card-stats {\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n}\n\n.type-card-stats .dot {\n margin: 0 4px;\n}\n\n.type-card-bar {\n width: 60px;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.type-bar-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.5s;\n}\n\n/* \u2500\u2500 Panels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.panel {\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n}\n\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-title {\n font-size: 0.95rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title i { color: var(--mj-brand-primary); }\n\n.panel-body {\n padding: 20px;\n}\n\n.chart-container {\n padding: 20px;\n}\n\n.table-container {\n padding: 0;\n max-height: 600px;\n overflow-y: auto;\n}\n\n/* \u2500\u2500 Trend Chart \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.trend-chart {\n display: flex;\n gap: 4px;\n height: 220px;\n align-items: flex-end;\n padding-bottom: 50px;\n overflow-x: auto;\n}\n\n.chart-column {\n display: flex;\n flex-direction: column;\n align-items: center;\n flex: 1;\n min-width: 24px;\n max-width: 40px;\n height: 100%;\n}\n\n.bars-wrapper {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1px;\n flex: 1;\n justify-content: flex-end;\n width: 100%;\n}\n\n.bar {\n width: 100%;\n border-radius: 3px 3px 0 0;\n min-height: 2px;\n transition: height 0.3s;\n}\n\n.success-bar {\n background: var(--mj-status-success);\n}\n\n.failure-bar {\n background: var(--mj-status-error);\n border-radius: 0;\n}\n\n.chart-label {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n margin-top: 6px;\n white-space: nowrap;\n text-align: center;\n transform: rotate(-45deg);\n transform-origin: top center;\n height: 40px;\n overflow: visible;\n}\n\n.chart-label.hidden-label {\n visibility: hidden;\n}\n\n.chart-legend {\n display: flex;\n justify-content: center;\n gap: 20px;\n margin-top: 12px;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.legend-dot {\n width: 10px;\n height: 10px;\n border-radius: 3px;\n}\n\n.legend-dot.success { background: var(--mj-status-success); }\n.legend-dot.failure { background: var(--mj-status-error); }\n\n/* \u2500\u2500 Data Table \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.data-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table th {\n text-align: left;\n font-size: 0.7rem;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-sunken);\n z-index: 1;\n}\n\n.data-table td {\n padding: 10px 16px;\n font-size: 0.85rem;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.data-table tbody tr:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.cell-name { font-weight: 600; color: var(--mj-text-primary); }\n.cell-meta { color: var(--mj-text-secondary); }\n.cell-error { color: var(--mj-status-error); font-size: 0.8rem; max-width: 300px; }\n\n.exec-status-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n font-size: 0.7rem;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 12px;\n white-space: nowrap;\n}\n\n.exec-status-badge.status-running { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.exec-status-badge.status-success { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.exec-status-badge.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.exec-status-badge.status-warning { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n/* \u2500\u2500 Expandable Rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.col-expand {\n width: 32px;\n text-align: center;\n}\n\n.expand-icon {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n.expand-icon.rotated {\n transform: rotate(90deg);\n}\n\n.exec-row {\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.exec-row:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.exec-row.expanded {\n background: var(--mj-bg-surface-sunken);\n border-bottom-color: transparent;\n}\n\n.exec-detail-row td {\n padding: 0 !important;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.exec-detail-content {\n padding: 16px 20px 16px 48px;\n background: var(--mj-bg-surface-sunken);\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.exec-detail-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 12px 24px;\n margin-bottom: 14px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-label {\n font-size: 0.7rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.detail-value {\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n}\n\n.detail-value.error-text {\n color: var(--mj-status-error);\n font-size: 0.8rem;\n word-break: break-word;\n}\n\n.exec-detail-actions {\n display: flex;\n gap: 8px;\n padding-top: 10px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.detail-action-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-size: 0.8rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.detail-action-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.detail-action-btn.secondary {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n.detail-action-btn.secondary:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.empty-state-small {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 48px 16px;\n color: var(--mj-text-muted);\n}\n\n.empty-state-small i { font-size: 2rem; color: var(--mj-border-strong); }\n.empty-state-small span { font-size: 0.85rem; }\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 .type-cards-row {\n flex-direction: column;\n }\n .type-card {\n min-width: auto;\n }\n}\n\n@media (max-width: 768px) {\n .activity-toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n .toolbar-right {\n flex-wrap: wrap;\n justify-content: space-between;\n }\n .search-box {\n min-width: auto;\n flex: 1;\n }\n .trend-chart {\n height: 120px;\n }\n .data-table {\n font-size: 0.8rem;\n }\n}\n"] }]
|
|
708
709
|
}], () => [{ type: i1.SchedulingInstrumentationService }, { type: i0.ChangeDetectorRef }], { initialState: [{
|
|
709
710
|
type: Input
|
|
710
711
|
}], stateChange: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduling-activity.component.js","sourceRoot":"","sources":["../../../src/Scheduling/components/scheduling-activity.component.ts","../../../src/Scheduling/components/scheduling-activity.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 {\n SchedulingInstrumentationService,\n JobExecution,\n ExecutionTrendData,\n JobTypeStatistics\n} from '../services/scheduling-instrumentation.service';\n\ntype TimeRange = '24h' | '7d' | '30d' | '90d';\n\n@Component({\n standalone: false,\n selector: 'app-scheduling-activity',\n templateUrl: './scheduling-activity.component.html',\n styleUrls: ['./scheduling-activity.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SchedulingActivityComponent implements OnInit, OnDestroy {\n @Input() initialState: Record<string, unknown> = {};\n @Output() stateChange = new EventEmitter<Record<string, unknown>>();\n\n public Executions: JobExecution[] = [];\n public FilteredExecutions: JobExecution[] = [];\n public Trends: ExecutionTrendData[] = [];\n public JobTypes: JobTypeStatistics[] = [];\n public IsLoading = true;\n\n public SearchTerm = '';\n public StatusFilter = '';\n public JobNameFilter = '';\n public SelectedTimeRange: TimeRange = '7d';\n public StatusOptions = ['', 'Running', 'Completed', 'Failed', 'Cancelled', 'Timeout'];\n public UniqueJobNames: string[] = [];\n public ExpandedExecutionIds = new Set<string>();\n public TimeRanges: { value: TimeRange; label: string }[] = [\n { value: '24h', label: '24 Hours' },\n { value: '7d', label: '7 Days' },\n { value: '30d', label: '30 Days' },\n { value: '90d', label: '90 Days' }\n ];\n\n private static readonly SEARCH_STATE_KEY = 'Scheduling.ActivitySearchState';\n\n private searchSubject = new BehaviorSubject<string>('');\n private statusSubject = new BehaviorSubject<string>('');\n private jobNameSubject = 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.applyTimeRange();\n this.setupFilters();\n this.setupSettingsPersistence();\n\n this.subscriptions.push(\n this.schedulingService.executionHistory$.subscribe(execs => {\n this.Executions = execs;\n this.IsLoading = false;\n this.applyFilters();\n this.cdr.markForCheck();\n }),\n this.schedulingService.executionTrends$.subscribe(trends => {\n this.Trends = trends;\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(SchedulingActivityComponent.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.jobNameFilter) this.JobNameFilter = state.jobNameFilter;\n if (state.timeRange) this.SelectedTimeRange = state.timeRange as TimeRange;\n }\n } catch (error) {\n console.warn('[SchedulingActivity] Failed to load user settings:', error);\n } finally {\n this.settingsLoaded = true;\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['jobNameFilter']) this.JobNameFilter = this.initialState['jobNameFilter'] as string;\n if (this.initialState['timeRange']) this.SelectedTimeRange = this.initialState['timeRange'] as TimeRange;\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 jobNameFilter: this.JobNameFilter,\n timeRange: this.SelectedTimeRange\n };\n UserInfoEngine.Instance.SetSettingDebounced(\n SchedulingActivityComponent.SEARCH_STATE_KEY,\n JSON.stringify(state)\n );\n } catch (error) {\n console.warn('[SchedulingActivity] Failed to persist search state:', error);\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.jobNameSubject.pipe(distinctUntilChanged())\n ]).subscribe(() => {\n this.applyFilters();\n this.emitState();\n this.cdr.markForCheck();\n })\n );\n this.searchSubject.next(this.SearchTerm);\n this.statusSubject.next(this.StatusFilter);\n this.jobNameSubject.next(this.JobNameFilter);\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 OnJobNameFilterChange(name: string): void {\n this.JobNameFilter = name;\n this.jobNameSubject.next(name);\n }\n\n public ShouldShowLabel(index: number): boolean {\n const total = this.Trends.length;\n if (total <= 10) return true;\n const step = Math.ceil(total / 8);\n return index % step === 0 || index === total - 1;\n }\n\n public OnTimeRangeChange(range: TimeRange): void {\n this.SelectedTimeRange = range;\n this.applyTimeRange();\n this.emitState();\n }\n\n public Refresh(): void {\n this.schedulingService.refresh();\n }\n\n public ToggleExpand(exec: JobExecution): void {\n if (this.ExpandedExecutionIds.has(exec.id)) {\n this.ExpandedExecutionIds.delete(exec.id);\n } else {\n this.ExpandedExecutionIds.add(exec.id);\n }\n this.cdr.markForCheck();\n }\n\n public IsExpanded(exec: JobExecution): boolean {\n return this.ExpandedExecutionIds.has(exec.id);\n }\n\n public OpenExecutionRecord(exec: JobExecution, event: MouseEvent): void {\n event.stopPropagation();\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromSingleKeyValuePair('ID', exec.id);\n SharedService.Instance.OpenEntityRecord('MJ: Scheduled Job Runs', compositeKey);\n }\n\n public OpenJobRecord(exec: JobExecution, event: MouseEvent): void {\n event.stopPropagation();\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromSingleKeyValuePair('ID', exec.jobId);\n SharedService.Instance.OpenEntityRecord('MJ: Scheduled Jobs', compositeKey);\n }\n\n public GetStatusIcon(status: string): string {\n switch (status) {\n case 'Running': return 'fa-solid fa-spinner fa-spin';\n case 'Completed': return 'fa-solid fa-circle-check';\n case 'Failed': return 'fa-solid fa-circle-xmark';\n case 'Cancelled': return 'fa-solid fa-ban';\n case 'Timeout': return 'fa-solid fa-clock';\n default: return 'fa-solid fa-circle-question';\n }\n }\n\n public GetStatusClass(status: string): string {\n switch (status) {\n case 'Running': return 'status-running';\n case 'Completed': return 'status-success';\n case 'Failed': return 'status-error';\n case 'Cancelled': return 'status-warning';\n case 'Timeout': return 'status-warning';\n default: return '';\n }\n }\n\n public GetTypeIcon(name: string): string {\n const lower = name.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 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 FormatDuration(ms: number | undefined): string {\n if (ms == null) return '-';\n const seconds = Math.floor(ms / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ${minutes % 60}m`;\n }\n\n public FormatDateTime(date: Date): string {\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 FormatChartLabel(date: Date): string {\n const hours = (this.schedulingService.CurrentDateRange.end.getTime() -\n this.schedulingService.CurrentDateRange.start.getTime()) / (1000 * 60 * 60);\n if (hours <= 24) {\n return date.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit', hour12: true });\n }\n return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n }\n\n public GetMaxTrendValue(): number {\n if (this.Trends.length === 0) return 1;\n return Math.max(...this.Trends.map(t => t.executions), 1);\n }\n\n public GetBarHeight(count: number): string {\n const max = this.GetMaxTrendValue();\n return `${Math.max((count / max) * 100, 2)}%`;\n }\n\n public FormatPercentage(value: number): string {\n return `${(value * 100).toFixed(1)}%`;\n }\n\n public TruncateError(msg: string | undefined): string {\n if (!msg) return '-';\n return msg.length > 60 ? msg.substring(0, 60) + '...' : msg;\n }\n\n private applyTimeRange(): void {\n const now = new Date();\n let start: Date;\n switch (this.SelectedTimeRange) {\n case '24h': start = new Date(now.getTime() - 24 * 60 * 60 * 1000); break;\n case '7d': start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); break;\n case '30d': start = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000); break;\n case '90d': start = new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000); break;\n }\n this.schedulingService.setDateRange(start, now);\n }\n\n private applyFilters(): void {\n this.buildUniqueJobNames();\n let filtered = [...this.Executions];\n\n if (this.SearchTerm) {\n const term = this.SearchTerm.toLowerCase();\n filtered = filtered.filter(e =>\n e.jobName.toLowerCase().includes(term) ||\n (e.errorMessage && e.errorMessage.toLowerCase().includes(term))\n );\n }\n\n if (this.StatusFilter) {\n filtered = filtered.filter(e => e.status === this.StatusFilter);\n }\n\n if (this.JobNameFilter) {\n filtered = filtered.filter(e => e.jobName === this.JobNameFilter);\n }\n\n this.FilteredExecutions = filtered;\n }\n\n private buildUniqueJobNames(): void {\n const names = new Set<string>();\n for (const exec of this.Executions) {\n names.add(exec.jobName);\n }\n this.UniqueJobNames = Array.from(names).sort();\n }\n\n private emitState(): void {\n this.stateChange.emit({\n searchTerm: this.SearchTerm,\n statusFilter: this.StatusFilter,\n jobNameFilter: this.JobNameFilter,\n timeRange: this.SelectedTimeRange\n });\n this.settingsPersistSubject.next();\n }\n}\n","<div class=\"activity-container\">\n <!-- Toolbar -->\n <div class=\"activity-toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\" placeholder=\"Search executions...\"\n [value]=\"SearchTerm\"\n (input)=\"OnSearchChange($any($event.target).value)\" />\n </div>\n <select class=\"filter-select\" [value]=\"StatusFilter\" (change)=\"OnStatusFilterChange($any($event.target).value)\">\n <option value=\"\">All Statuses</option>\n @for (s of StatusOptions.slice(1); track s) {\n <option [value]=\"s\">{{s}}</option>\n }\n </select>\n <select class=\"filter-select\" [value]=\"JobNameFilter\" (change)=\"OnJobNameFilterChange($any($event.target).value)\">\n <option value=\"\">All Jobs</option>\n @for (name of UniqueJobNames; track name) {\n <option [value]=\"name\">{{name}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <div class=\"time-range-group\">\n @for (range of TimeRanges; track range) {\n <button\n class=\"range-btn\"\n [class.active]=\"SelectedTimeRange === range.value\"\n (click)=\"OnTimeRangeChange(range.value)\">\n {{range.label}}\n </button>\n }\n </div>\n <button class=\"control-btn\" (click)=\"Refresh()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n </div>\n </div>\n\n <!-- Loading -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading activity...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n @if (!IsLoading) {\n <div class=\"activity-content\">\n <!-- Job Type Summary Cards -->\n @if (JobTypes.length > 0) {\n <div class=\"type-cards-row\">\n @for (type of JobTypes; track type) {\n <div class=\"type-card\">\n <div class=\"type-card-icon\">\n <i [class]=\"GetTypeIcon(type.typeName)\"></i>\n </div>\n <div class=\"type-card-info\">\n <div class=\"type-card-name\">{{type.typeName}}</div>\n <div class=\"type-card-stats\">\n <span>{{type.activeJobsCount}} active</span>\n <span class=\"dot\">·</span>\n <span>{{type.totalRuns}} runs</span>\n <span class=\"dot\">·</span>\n <span [style.color]=\"GetSuccessRateColor(type.successRate)\">\n {{FormatPercentage(type.successRate)}}\n </span>\n </div>\n </div>\n <div class=\"type-card-bar\">\n <div class=\"type-bar-fill\"\n [style.width]=\"(type.successRate * 100) + '%'\"\n [style.background]=\"GetSuccessRateColor(type.successRate)\">\n </div>\n </div>\n </div>\n }\n </div>\n }\n <!-- Execution Trends Chart -->\n @if (Trends.length > 0) {\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-chart-bar\"></i> Execution Trends\n </div>\n <span class=\"result-count\">{{FilteredExecutions.length}} executions</span>\n </div>\n <div class=\"panel-body chart-container\">\n <div class=\"trend-chart\">\n @for (trend of Trends; track trend; let i = $index) {\n <div class=\"chart-column\">\n <div class=\"bars-wrapper\">\n <div class=\"bar success-bar\"\n [style.height]=\"GetBarHeight(trend.successes)\"\n [title]=\"trend.successes + ' successful'\">\n </div>\n @if (trend.failures > 0) {\n <div class=\"bar failure-bar\"\n [style.height]=\"GetBarHeight(trend.failures)\"\n [title]=\"trend.failures + ' failed'\">\n </div>\n }\n </div>\n <div class=\"chart-label\" [class.hidden-label]=\"!ShouldShowLabel(i)\" >{{FormatChartLabel(trend.timestamp)}}</div>\n </div>\n }\n </div>\n <div class=\"chart-legend\">\n <span class=\"legend-item\"><span class=\"legend-dot success\"></span> Successful</span>\n <span class=\"legend-item\"><span class=\"legend-dot failure\"></span> Failed</span>\n </div>\n </div>\n </div>\n }\n <!-- Execution History Table -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i> Execution History\n </div>\n <span class=\"result-count\">{{FilteredExecutions.length}} of {{Executions.length}}</span>\n </div>\n <div class=\"panel-body table-container\">\n @if (FilteredExecutions.length === 0) {\n <div class=\"empty-state-small\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No executions found for this time range</span>\n </div>\n }\n @if (FilteredExecutions.length > 0) {\n <table class=\"data-table\">\n <thead>\n <tr>\n <th class=\"col-expand\"></th>\n <th>Status</th>\n <th>Job Name</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Error</th>\n </tr>\n </thead>\n <tbody>\n @for (exec of FilteredExecutions; track exec) {\n <tr class=\"exec-row\" [class.expanded]=\"IsExpanded(exec)\" (click)=\"ToggleExpand(exec)\">\n <td class=\"col-expand\">\n <i class=\"fa-solid fa-chevron-right expand-icon\"\n [class.rotated]=\"IsExpanded(exec)\"></i>\n </td>\n <td>\n <span class=\"exec-status-badge\" [ngClass]=\"GetStatusClass(exec.status)\">\n <i [class]=\"GetStatusIcon(exec.status)\"></i>\n {{exec.status}}\n </span>\n </td>\n <td class=\"cell-name\">{{exec.jobName}}</td>\n <td class=\"cell-meta\">{{FormatDateTime(exec.startedAt)}}</td>\n <td class=\"cell-meta\">{{FormatDuration(exec.duration)}}</td>\n <td class=\"cell-error\">{{TruncateError(exec.errorMessage)}}</td>\n </tr>\n @if (IsExpanded(exec)) {\n <tr class=\"exec-detail-row\">\n <td [attr.colspan]=\"6\">\n <div class=\"exec-detail-content\">\n <div class=\"exec-detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Job Name</span>\n <span class=\"detail-value\">{{exec.jobName}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Started</span>\n <span class=\"detail-value\">{{FormatDateTime(exec.startedAt)}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Completed</span>\n <span class=\"detail-value\">{{exec.completedAt ? FormatDateTime(exec.completedAt) : '-'}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Duration</span>\n <span class=\"detail-value\">{{FormatDuration(exec.duration)}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Status</span>\n <span class=\"detail-value\">\n <span class=\"exec-status-badge\" [ngClass]=\"GetStatusClass(exec.status)\">\n <i [class]=\"GetStatusIcon(exec.status)\"></i>\n {{exec.status}}\n </span>\n </span>\n </div>\n @if (exec.errorMessage) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Error</span>\n <span class=\"detail-value error-text\">{{exec.errorMessage}}</span>\n </div>\n }\n </div>\n <div class=\"exec-detail-actions\">\n <button class=\"detail-action-btn\" (click)=\"OpenExecutionRecord(exec, $event)\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i> Open Run Record\n </button>\n <button class=\"detail-action-btn secondary\" (click)=\"OpenJobRecord(exec, $event)\">\n <i class=\"fa-solid fa-briefcase\"></i> Open Job\n </button>\n </div>\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n }\n </div>\n </div>\n </div>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"scheduling-activity.component.js","sourceRoot":"","sources":["../../../src/Scheduling/components/scheduling-activity.component.ts","../../../src/Scheduling/components/scheduling-activity.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 {\n SchedulingInstrumentationService,\n JobExecution,\n ExecutionTrendData,\n JobTypeStatistics\n} from '../services/scheduling-instrumentation.service';\n\ntype TimeRange = '24h' | '7d' | '30d' | '90d';\n\n@Component({\n standalone: false,\n selector: 'app-scheduling-activity',\n templateUrl: './scheduling-activity.component.html',\n styleUrls: ['./scheduling-activity.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SchedulingActivityComponent implements OnInit, OnDestroy {\n @Input() initialState: Record<string, unknown> = {};\n @Output() stateChange = new EventEmitter<Record<string, unknown>>();\n\n public Executions: JobExecution[] = [];\n public FilteredExecutions: JobExecution[] = [];\n public Trends: ExecutionTrendData[] = [];\n public JobTypes: JobTypeStatistics[] = [];\n public IsLoading = true;\n\n public SearchTerm = '';\n public StatusFilter = '';\n public JobNameFilter = '';\n public SelectedTimeRange: TimeRange = '7d';\n public StatusOptions = ['', 'Running', 'Completed', 'Failed', 'Cancelled', 'Timeout'];\n public UniqueJobNames: string[] = [];\n public ExpandedExecutionIds = new Set<string>();\n public TimeRanges: { value: TimeRange; label: string }[] = [\n { value: '24h', label: '24 Hours' },\n { value: '7d', label: '7 Days' },\n { value: '30d', label: '30 Days' },\n { value: '90d', label: '90 Days' }\n ];\n\n private static readonly SEARCH_STATE_KEY = 'Scheduling.ActivitySearchState';\n\n private searchSubject = new BehaviorSubject<string>('');\n private statusSubject = new BehaviorSubject<string>('');\n private jobNameSubject = 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.applyTimeRange();\n this.setupFilters();\n this.setupSettingsPersistence();\n\n this.subscriptions.push(\n this.schedulingService.executionHistory$.subscribe(execs => {\n this.Executions = execs;\n this.IsLoading = false;\n this.applyFilters();\n this.cdr.markForCheck();\n }),\n this.schedulingService.executionTrends$.subscribe(trends => {\n this.Trends = trends;\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(SchedulingActivityComponent.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.jobNameFilter) this.JobNameFilter = state.jobNameFilter;\n if (state.timeRange) this.SelectedTimeRange = state.timeRange as TimeRange;\n }\n } catch (error) {\n console.warn('[SchedulingActivity] Failed to load user settings:', error);\n } finally {\n this.settingsLoaded = true;\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['jobNameFilter']) this.JobNameFilter = this.initialState['jobNameFilter'] as string;\n if (this.initialState['timeRange']) this.SelectedTimeRange = this.initialState['timeRange'] as TimeRange;\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 jobNameFilter: this.JobNameFilter,\n timeRange: this.SelectedTimeRange\n };\n UserInfoEngine.Instance.SetSettingDebounced(\n SchedulingActivityComponent.SEARCH_STATE_KEY,\n JSON.stringify(state)\n );\n } catch (error) {\n console.warn('[SchedulingActivity] Failed to persist search state:', error);\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.jobNameSubject.pipe(distinctUntilChanged())\n ]).subscribe(() => {\n this.applyFilters();\n this.emitState();\n this.cdr.markForCheck();\n })\n );\n this.searchSubject.next(this.SearchTerm);\n this.statusSubject.next(this.StatusFilter);\n this.jobNameSubject.next(this.JobNameFilter);\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 OnJobNameFilterChange(name: string): void {\n this.JobNameFilter = name;\n this.jobNameSubject.next(name);\n }\n\n public ShouldShowLabel(index: number): boolean {\n const total = this.Trends.length;\n if (total <= 10) return true;\n const step = Math.ceil(total / 8);\n return index % step === 0 || index === total - 1;\n }\n\n public OnTimeRangeChange(range: TimeRange): void {\n this.SelectedTimeRange = range;\n this.applyTimeRange();\n this.emitState();\n }\n\n public Refresh(): void {\n this.schedulingService.refresh();\n }\n\n public ToggleExpand(exec: JobExecution): void {\n if (this.ExpandedExecutionIds.has(exec.id)) {\n this.ExpandedExecutionIds.delete(exec.id);\n } else {\n this.ExpandedExecutionIds.add(exec.id);\n }\n this.cdr.markForCheck();\n }\n\n public IsExpanded(exec: JobExecution): boolean {\n return this.ExpandedExecutionIds.has(exec.id);\n }\n\n public OpenExecutionRecord(exec: JobExecution, event: MouseEvent): void {\n event.stopPropagation();\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromSingleKeyValuePair('ID', exec.id);\n SharedService.Instance.OpenEntityRecord('MJ: Scheduled Job Runs', compositeKey);\n }\n\n public OpenJobRecord(exec: JobExecution, event: MouseEvent): void {\n event.stopPropagation();\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromSingleKeyValuePair('ID', exec.jobId);\n SharedService.Instance.OpenEntityRecord('MJ: Scheduled Jobs', compositeKey);\n }\n\n public GetStatusIcon(status: string): string {\n switch (status) {\n case 'Running': return 'fa-solid fa-spinner fa-spin';\n case 'Completed': return 'fa-solid fa-circle-check';\n case 'Failed': return 'fa-solid fa-circle-xmark';\n case 'Cancelled': return 'fa-solid fa-ban';\n case 'Timeout': return 'fa-solid fa-clock';\n default: return 'fa-solid fa-circle-question';\n }\n }\n\n public GetStatusClass(status: string): string {\n switch (status) {\n case 'Running': return 'status-running';\n case 'Completed': return 'status-success';\n case 'Failed': return 'status-error';\n case 'Cancelled': return 'status-warning';\n case 'Timeout': return 'status-warning';\n default: return '';\n }\n }\n\n public GetTypeIcon(name: string): string {\n const lower = name.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 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 FormatDuration(ms: number | undefined): string {\n if (ms == null) return '-';\n const seconds = Math.floor(ms / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ${minutes % 60}m`;\n }\n\n public FormatDateTime(date: Date): string {\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 FormatChartLabel(date: Date): string {\n const hours = (this.schedulingService.CurrentDateRange.end.getTime() -\n this.schedulingService.CurrentDateRange.start.getTime()) / (1000 * 60 * 60);\n if (hours <= 24) {\n return date.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit', hour12: true });\n }\n return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n }\n\n public GetMaxTrendValue(): number {\n if (this.Trends.length === 0) return 1;\n return Math.max(...this.Trends.map(t => t.executions), 1);\n }\n\n public GetBarHeight(count: number): string {\n const max = this.GetMaxTrendValue();\n return `${Math.max((count / max) * 100, 2)}%`;\n }\n\n public FormatPercentage(value: number): string {\n return `${(value * 100).toFixed(1)}%`;\n }\n\n public TruncateError(msg: string | undefined): string {\n if (!msg) return '-';\n return msg.length > 60 ? msg.substring(0, 60) + '...' : msg;\n }\n\n private applyTimeRange(): void {\n const now = new Date();\n let start: Date;\n switch (this.SelectedTimeRange) {\n case '24h': start = new Date(now.getTime() - 24 * 60 * 60 * 1000); break;\n case '7d': start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); break;\n case '30d': start = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000); break;\n case '90d': start = new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000); break;\n }\n this.schedulingService.setDateRange(start, now);\n }\n\n private applyFilters(): void {\n this.buildUniqueJobNames();\n let filtered = [...this.Executions];\n\n if (this.SearchTerm) {\n const term = this.SearchTerm.toLowerCase();\n filtered = filtered.filter(e =>\n e.jobName.toLowerCase().includes(term) ||\n (e.errorMessage && e.errorMessage.toLowerCase().includes(term))\n );\n }\n\n if (this.StatusFilter) {\n filtered = filtered.filter(e => e.status === this.StatusFilter);\n }\n\n if (this.JobNameFilter) {\n filtered = filtered.filter(e => e.jobName === this.JobNameFilter);\n }\n\n this.FilteredExecutions = filtered;\n }\n\n private buildUniqueJobNames(): void {\n const names = new Set<string>();\n for (const exec of this.Executions) {\n names.add(exec.jobName);\n }\n this.UniqueJobNames = Array.from(names).sort();\n }\n\n private emitState(): void {\n this.stateChange.emit({\n searchTerm: this.SearchTerm,\n statusFilter: this.StatusFilter,\n jobNameFilter: this.JobNameFilter,\n timeRange: this.SelectedTimeRange\n });\n this.settingsPersistSubject.next();\n }\n}\n","<div class=\"activity-container\">\n <!-- Toolbar -->\n <div class=\"activity-toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\" placeholder=\"Search executions...\"\n [value]=\"SearchTerm\"\n (input)=\"OnSearchChange($any($event.target).value)\" />\n </div>\n <select class=\"filter-select\" [value]=\"StatusFilter\" (change)=\"OnStatusFilterChange($any($event.target).value)\">\n <option value=\"\">All Statuses</option>\n @for (s of StatusOptions.slice(1); track s) {\n <option [value]=\"s\">{{s}}</option>\n }\n </select>\n <select class=\"filter-select\" [value]=\"JobNameFilter\" (change)=\"OnJobNameFilterChange($any($event.target).value)\">\n <option value=\"\">All Jobs</option>\n @for (name of UniqueJobNames; track name) {\n <option [value]=\"name\">{{name}}</option>\n }\n </select>\n </div>\n <div class=\"toolbar-right\">\n <div class=\"time-range-group\">\n @for (range of TimeRanges; track range) {\n <button\n class=\"range-btn\"\n [class.active]=\"SelectedTimeRange === range.value\"\n (click)=\"OnTimeRangeChange(range.value)\">\n {{range.label}}\n </button>\n }\n </div>\n <button mjButton variant=\"secondary\" (click)=\"Refresh()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n </div>\n </div>\n\n <!-- Loading -->\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading activity...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n @if (!IsLoading) {\n <div class=\"activity-content\">\n <!-- Job Type Summary Cards -->\n @if (JobTypes.length > 0) {\n <div class=\"type-cards-row\">\n @for (type of JobTypes; track type) {\n <div class=\"type-card\">\n <div class=\"type-card-icon\">\n <i [class]=\"GetTypeIcon(type.typeName)\"></i>\n </div>\n <div class=\"type-card-info\">\n <div class=\"type-card-name\">{{type.typeName}}</div>\n <div class=\"type-card-stats\">\n <span>{{type.activeJobsCount}} active</span>\n <span class=\"dot\">·</span>\n <span>{{type.totalRuns}} runs</span>\n <span class=\"dot\">·</span>\n <span [style.color]=\"GetSuccessRateColor(type.successRate)\">\n {{FormatPercentage(type.successRate)}}\n </span>\n </div>\n </div>\n <div class=\"type-card-bar\">\n <div class=\"type-bar-fill\"\n [style.width]=\"(type.successRate * 100) + '%'\"\n [style.background]=\"GetSuccessRateColor(type.successRate)\">\n </div>\n </div>\n </div>\n }\n </div>\n }\n <!-- Execution Trends Chart -->\n @if (Trends.length > 0) {\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-chart-bar\"></i> Execution Trends\n </div>\n <span class=\"result-count\">{{FilteredExecutions.length}} executions</span>\n </div>\n <div class=\"panel-body chart-container\">\n <div class=\"trend-chart\">\n @for (trend of Trends; track trend; let i = $index) {\n <div class=\"chart-column\">\n <div class=\"bars-wrapper\">\n <div class=\"bar success-bar\"\n [style.height]=\"GetBarHeight(trend.successes)\"\n [title]=\"trend.successes + ' successful'\">\n </div>\n @if (trend.failures > 0) {\n <div class=\"bar failure-bar\"\n [style.height]=\"GetBarHeight(trend.failures)\"\n [title]=\"trend.failures + ' failed'\">\n </div>\n }\n </div>\n <div class=\"chart-label\" [class.hidden-label]=\"!ShouldShowLabel(i)\" >{{FormatChartLabel(trend.timestamp)}}</div>\n </div>\n }\n </div>\n <div class=\"chart-legend\">\n <span class=\"legend-item\"><span class=\"legend-dot success\"></span> Successful</span>\n <span class=\"legend-item\"><span class=\"legend-dot failure\"></span> Failed</span>\n </div>\n </div>\n </div>\n }\n <!-- Execution History Table -->\n <div class=\"panel\">\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i> Execution History\n </div>\n <span class=\"result-count\">{{FilteredExecutions.length}} of {{Executions.length}}</span>\n </div>\n <div class=\"panel-body table-container\">\n @if (FilteredExecutions.length === 0) {\n <div class=\"empty-state-small\">\n <i class=\"fa-solid fa-inbox\"></i>\n <span>No executions found for this time range</span>\n </div>\n }\n @if (FilteredExecutions.length > 0) {\n <table class=\"data-table\">\n <thead>\n <tr>\n <th class=\"col-expand\"></th>\n <th>Status</th>\n <th>Job Name</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Error</th>\n </tr>\n </thead>\n <tbody>\n @for (exec of FilteredExecutions; track exec) {\n <tr class=\"exec-row\" [class.expanded]=\"IsExpanded(exec)\" (click)=\"ToggleExpand(exec)\">\n <td class=\"col-expand\">\n <i class=\"fa-solid fa-chevron-right expand-icon\"\n [class.rotated]=\"IsExpanded(exec)\"></i>\n </td>\n <td>\n <span class=\"exec-status-badge\" [ngClass]=\"GetStatusClass(exec.status)\">\n <i [class]=\"GetStatusIcon(exec.status)\"></i>\n {{exec.status}}\n </span>\n </td>\n <td class=\"cell-name\">{{exec.jobName}}</td>\n <td class=\"cell-meta\">{{FormatDateTime(exec.startedAt)}}</td>\n <td class=\"cell-meta\">{{FormatDuration(exec.duration)}}</td>\n <td class=\"cell-error\">{{TruncateError(exec.errorMessage)}}</td>\n </tr>\n @if (IsExpanded(exec)) {\n <tr class=\"exec-detail-row\">\n <td [attr.colspan]=\"6\">\n <div class=\"exec-detail-content\">\n <div class=\"exec-detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Job Name</span>\n <span class=\"detail-value\">{{exec.jobName}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Started</span>\n <span class=\"detail-value\">{{FormatDateTime(exec.startedAt)}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Completed</span>\n <span class=\"detail-value\">{{exec.completedAt ? FormatDateTime(exec.completedAt) : '-'}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Duration</span>\n <span class=\"detail-value\">{{FormatDuration(exec.duration)}}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Status</span>\n <span class=\"detail-value\">\n <span class=\"exec-status-badge\" [ngClass]=\"GetStatusClass(exec.status)\">\n <i [class]=\"GetStatusIcon(exec.status)\"></i>\n {{exec.status}}\n </span>\n </span>\n </div>\n @if (exec.errorMessage) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Error</span>\n <span class=\"detail-value error-text\">{{exec.errorMessage}}</span>\n </div>\n }\n </div>\n <div class=\"exec-detail-actions\">\n <button class=\"detail-action-btn\" (click)=\"OpenExecutionRecord(exec, $event)\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i> Open Run Record\n </button>\n <button class=\"detail-action-btn secondary\" (click)=\"OpenJobRecord(exec, $event)\">\n <i class=\"fa-solid fa-briefcase\"></i> Open Job\n </button>\n </div>\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n }\n </div>\n </div>\n </div>\n }\n</div>\n"]}
|