@memberjunction/ng-dashboards 5.22.0 → 5.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +947 -64
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +7645 -430
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +285 -6
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +2454 -277
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- 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 +20 -2
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +419 -232
- package/dist/AI/components/vectors/vector-management-resource.component.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-share-dialog.component.js +9 -9
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +17 -17
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +4 -4
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +1 -0
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +5 -4
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +247 -259
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +1 -0
- package/dist/Integration/components/overview/overview.component.js.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.js +1 -0
- package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.js +1 -0
- package/dist/Integration/components/schedules/schedules.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/analytics/analytics-resource.component.d.ts +411 -0
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +4266 -0
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +140 -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 +780 -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 +8 -2
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +246 -195
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +75 -0
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +601 -0
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +93 -12
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +637 -107
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/index.d.ts +3 -0
- package/dist/KnowledgeHub/index.d.ts.map +1 -1
- package/dist/KnowledgeHub/index.js +3 -0
- package/dist/KnowledgeHub/index.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts.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/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/Testing/testing-dashboard.component.js +9 -10
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/__tests__/analytics-resource.test.d.ts +2 -0
- package/dist/__tests__/analytics-resource.test.d.ts.map +1 -0
- package/dist/__tests__/analytics-resource.test.js +181 -0
- package/dist/__tests__/analytics-resource.test.js.map +1 -0
- package/dist/__tests__/scheduling.test.d.ts +2 -0
- package/dist/__tests__/scheduling.test.d.ts.map +1 -0
- package/dist/__tests__/scheduling.test.js +205 -0
- package/dist/__tests__/scheduling.test.js.map +1 -0
- 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 +20 -20
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +43 -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 +12 -18
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +15 -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 +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -0
- 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/shared/entity-field-display.d.ts +44 -0
- package/dist/shared/entity-field-display.d.ts.map +1 -0
- package/dist/shared/entity-field-display.js +118 -0
- package/dist/shared/entity-field-display.js.map +1 -0
- package/dist/testing-dashboards.module.d.ts +7 -13
- package/dist/testing-dashboards.module.d.ts.map +1 -1
- package/dist/testing-dashboards.module.js +0 -27
- package/dist/testing-dashboards.module.js.map +1 -1
- package/package.json +48 -55
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-monitoring.component.js","sourceRoot":"","sources":["../../../src/Actions/components/execution-monitoring.component.ts","../../../src/Actions/components/execution-monitoring.component.html"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAwC,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEvE,OAAO,EAAE,aAAa,EAAG,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAqB,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;;;;;;;;;;;ICWnE,wBAAkC;;;IA+GhC,AADF,+BAAuB,cACM;IAEzB,AADA,0BAA+G,cACL;IAC5G,iBAAM;IACN,+BAAuB;IAAA,YAA+B;;IAAA,iBAAM;IAC5D,+BAAuB;IAAA,YAAiB;IAC1C,AAD0C,iBAAM,EAC1C;;;IALuB,eAA+E;IAA/E,kGAA+E;IAChF,cAA2E;IAA3E,8FAA2E;IAE9E,eAA+B;IAA/B,kEAA+B;IAC/B,eAAiB;IAAjB,oCAAiB;;;IAR9C,+BAAwB;IACtB,+GASC;IACH,iBAAM;IAEJ,AADF,+BAA0B,cACC;IACvB,0BAAwC;IACxC,4BAAM;IAAA,0BAAU;IAClB,AADkB,iBAAO,EACnB;IACN,+BAAyB;IACvB,0BAAuC;IACvC,6BAAM;IAAA,uBAAM;IAEhB,AADE,AADc,iBAAO,EACf,EACF;;;IApBJ,cASC;IATD,qCASC;;;IAaH,+BAAyB;IACvB,wBAAsC;IACtC,yBAAG;IAAA,6CAA6B;IAClC,AADkC,iBAAI,EAChC;;;;IAeJ,+BAA+D;IAAnC,oOAAS,kCAAwB,KAAC;IAC5D,+BAA8B;IAC5B,oBAAqD;IACvD,iBAAM;IAGJ,AADF,+BAA4B,cACwE;IAApE,oNAAS,wCAA+B,wBAAE,wBAAwB,KAAC;IAC/F,YACF;IAAA,iBAAM;IAEJ,AADF,+BAA+B,eACA;IAAA,YAAkD;;IAAA,iBAAO;IACtF,iCAA6B;IAAA,aAAsB;IAAA,iBAAO;IAC1D,iCAAiC;IAAA,aAA4B;IAEjE,AADE,AAD+D,iBAAO,EAChE,EACF;IAGJ,AADF,gCAA8B,sBAGT;IACjB,aACF;IACF,AADE,iBAAa,EACT;IAGJ,AADF,gCAA+B,kBAIQ;IAAnC,2KAAS,wBAAwB,KAAC;IAGxC,AADE,AADE,iBAAS,EACL,EACF;;;;IA7BC,eAA6C;IAA7C,4DAA6C;IAK9C,eACF;IADE,4EACF;IAE+B,eAAkD;IAAlD,sFAAkD;IAClD,eAAsB;IAAtB,yCAAsB;IAClB,eAA4B;IAA5B,sDAA4B;IAM7D,eAAmD;IACnD,AADA,2EAAmD,iBACnC;IAChB,cACF;IADE,qEACF;IAKE,eAAmB;IACnB,AADA,iCAAmB,yBACK;;;IA5BhC,iHAiCC;;;IAjCD,wCAiCC;;;IAED,+BAAyB;IACvB,wBAAkC;IAClC,0BAAI;IAAA,mCAAmB;IAAA,iBAAK;IAC5B,yBAAG;IAAA,0DAA0C;IAC/C,AAD+C,iBAAI,EAC7C;;;IAMV,+BAA6B;IAC3B,iCAA0D;IAC5D,iBAAM;;IADQ,cAAkB;IAAlB,gCAAkB;;AD3LpC;;GAEG;AAQI,IAAM,4BAA4B,GAAlC,MAAM,4BAA6B,SAAQ,qBAAqB;IA4CjD;IAA8C;IA3C3D,SAAS,GAAG,IAAI,CAAC;IACjB,UAAU,GAAiC,EAAE,CAAC;IAC9C,kBAAkB,GAAiC,EAAE,CAAC;IACtD,OAAO,GAAgC,IAAI,GAAG,EAAE,CAAC;IAEjD,OAAO,GAAqB;QACjC,eAAe,EAAE,CAAC;QAClB,oBAAoB,EAAE,CAAC;QACvB,gBAAgB,EAAE,CAAC;QACnB,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,CAAC;QAClB,kBAAkB,EAAE,CAAC;QACrB,gBAAgB,EAAE,CAAC;KACpB,CAAC;IAEK,eAAe,GAAqB,EAAE,CAAC;IAEvC,WAAW,GAAG,IAAI,eAAe,CAAS,EAAE,CAAC,CAAC;IAC9C,eAAe,GAAG,IAAI,eAAe,CAAS,KAAK,CAAC,CAAC;IACrD,kBAAkB,GAAG,IAAI,eAAe,CAAS,OAAO,CAAC,CAAC;IAC1D,eAAe,GAAG,IAAI,eAAe,CAAS,KAAK,CAAC,CAAC;IAErD,gBAAgB,GAAG;QACxB,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE;QAC3C,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE;QACvC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE;QACzC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE;KAC1C,CAAC;IAEK,aAAa,GAAG;QACrB,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE;QACrC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;QACrC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;QACnC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;QACjC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;KACtC,CAAC;IAEK,aAAa,GAAyC;QAC3D,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE;KACtC,CAAC;IAEM,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAEvC,YAAoB,iBAAoC,EAAU,GAAsB;QACtF,KAAK,EAAE,CAAC;QADU,sBAAiB,GAAjB,iBAAiB,CAAmB;QAAU,QAAG,GAAH,GAAG,CAAmB;IAExF,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED,WAAW;QACT,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;IAEO,YAAY;QAClB,aAAa,CAAC;YACZ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,oBAAoB,EAAE,CAAC;YAChE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACjD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACpD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;SAClD,CAAC,CAAC,IAAI,CACL,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB,CAAC,SAAS,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,QAAQ;QACpB,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YAEtB,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,CAAC,gBAAgB,EAAE,aAAa,CAAC,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC;gBAC1D;oBACE,UAAU,EAAE,2BAA2B;oBACvC,OAAO,EAAE,gBAAgB;iBAC1B;gBACD;oBACE,UAAU,EAAE,aAAa;oBACzB,OAAO,EAAE,MAAM;iBAChB;aACF,CAAC,CAAC;YAEH,IAAI,CAAC,gBAAgB,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;gBACxD,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACzC,CAAC;YAED,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAuC,CAAC;YAC5E,MAAM,OAAO,GAAG,aAAa,CAAC,OAA2B,CAAC;YAE1D,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC7B,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACjC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACjC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY,EAAE,CAAC;QAEtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,0CAA0C,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACzE,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAEO,kBAAkB,CAAC,OAAyB;QAClD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,kBAAkB,CAAC,OAAyB;QAClD,IAAI,CAAC,aAAa,GAAG;YACnB,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE;YACrC,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,KAAK,EAAE,MAAM,CAAC,EAAE;aACjB,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IAEO,gBAAgB;QACtB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACzE,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAEpE,IAAI,CAAC,OAAO,GAAG;YACb,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM;YACvC,oBAAoB,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,MAAM;YACpF,gBAAgB,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC3C,CAAC,CAAC,UAAU,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAC3D,CAAC,MAAM;YACR,eAAe,EAAE,IAAI,CAAC,wBAAwB,EAAE;YAChD,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC1C,IAAI,IAAI,CAAC,CAAC,CAAC,SAAU,CAAC,IAAI,KAAK,CAChC,CAAC,MAAM;YACR,kBAAkB,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC7C,IAAI,IAAI,CAAC,CAAC,CAAC,SAAU,CAAC,IAAI,OAAO,CAClC,CAAC,MAAM;YACR,gBAAgB,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC3C,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,OAAO,CACzC,CAAC,MAAM;SACT,CAAC;IACJ,CAAC;IAEO,wBAAwB;QAC9B,MAAM,mBAAmB,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACrD,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,OAAO,CACzB,CAAC;QAEF,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAE/C,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE;YAClE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAU,CAAC,CAAC,OAAO,EAAE,CAAC;YACvD,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,OAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;YACnD,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;QAC7B,CAAC,EAAE,CAAC,CAAC,CAAC;QAEN,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,mBAAmB,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,qBAAqB;IAC7F,CAAC;IAEO,uBAAuB;QAC7B,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;QACjD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACnD,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAEb,oCAAoC;QACpC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACvB,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE;gBACf,IAAI;gBACJ,UAAU,EAAE,CAAC;gBACb,MAAM,EAAE,CAAC;gBACT,KAAK,EAAE,CAAC;aACT,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,sCAAsC;QACtC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YAClC,IAAI,CAAC,SAAS,CAAC,SAAS;gBAAE,OAAO;YAEjC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACvE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE/B,IAAI,KAAK,EAAE,CAAC;gBACV,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;oBACvC,KAAK,CAAC,UAAU,EAAE,CAAC;gBACrB,CAAC;qBAAM,IAAI,SAAS,CAAC,UAAU,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;oBACtF,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;IAEO,YAAY;QAClB,IAAI,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAEpC,0BAA0B;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC;QAChD,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;YACxB,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;YACtD,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC7B,CAAC,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,UAAU,CACnD,CAAC;QACJ,CAAC;QAED,sBAAsB;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;QAC1C,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACrB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC;YAC5E,CAAC;iBAAM,CAAC;gBACN,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;QAC5C,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;YACvB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,sBAAsB;QACtB,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QACxD,IAAI,UAAU,EAAE,CAAC;YACf,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;gBAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,QAAS,CAAC,CAAC;gBAC7C,OAAO,CACL,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;oBAC/C,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;oBAChD,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAC7C,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC;IACrC,CAAC;IAEO,kBAAkB,CAAC,SAAiB;QAC1C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,SAAS;gBACZ,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YACvD,KAAK,OAAO;gBACV,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAC3D,KAAK,QAAQ;gBACX,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAC5D,KAAK,QAAQ;gBACX,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAC5D;gBACE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAEM,cAAc,CAAC,UAAkB;QACtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAEM,oBAAoB,CAAC,MAAc;QACxC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAEM,iBAAiB,CAAC,SAAiB;QACxC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAEM,oBAAoB,CAAC,QAAgB;QAC1C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAEM,aAAa,CAAC,SAAqC;QACxD,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;IAC5E,CAAC;IAEM,UAAU,CAAC,QAAgB;QAChC,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;IAC9D,CAAC;IAEM,aAAa,CAAC,QAAgB;QACnC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,IAAI,UAAU,QAAQ,EAAE,CAAC;IAClE,CAAC;IAEM,cAAc,CAAC,UAAyB;QAC7C,IAAI,CAAC,UAAU;YAAE,OAAO,MAAM,CAAC;QAC/B,QAAQ,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;YACjC,KAAK,SAAS,CAAC,CAAC,OAAO,SAAS,CAAC;YACjC,KAAK,QAAQ,CAAC;YACd,KAAK,OAAO,CAAC,CAAC,OAAO,OAAO,CAAC;YAC7B,KAAK,SAAS,CAAC,CAAC,OAAO,SAAS,CAAC;YACjC,OAAO,CAAC,CAAC,OAAO,MAAM,CAAC;QACzB,CAAC;IACH,CAAC;IAEM,aAAa,CAAC,UAAyB;QAC5C,IAAI,CAAC,UAAU;YAAE,OAAO,sBAAsB,CAAC;QAC/C,QAAQ,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;YACjC,KAAK,SAAS,CAAC,CAAC,OAAO,0BAA0B,CAAC;YAClD,KAAK,QAAQ,CAAC;YACd,KAAK,OAAO,CAAC,CAAC,OAAO,gCAAgC,CAAC;YACtD,KAAK,SAAS,CAAC,CAAC,OAAO,6BAA6B,CAAC;YACrD,OAAO,CAAC,CAAC,OAAO,yBAAyB,CAAC;QAC5C,CAAC;IACH,CAAC;IAEM,WAAW,CAAC,SAAqC;QACtD,IAAI,CAAC,SAAS,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YAC/C,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACnD,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QAElD,IAAI,QAAQ,GAAG,EAAE;YAAE,OAAO,GAAG,QAAQ,GAAG,CAAC;QACzC,IAAI,QAAQ,GAAG,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC;QAC5D,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC;IAC3C,CAAC;IAEM,cAAc;QACnB,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,GAAG,CAAC,CAAC;IAC9F,CAAC;IAEM,WAAW;QAChB,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED,6BAA6B;IACtB,sBAAsB;QAC3B,uCAAuC;QACvC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAEM,kBAAkB;QACvB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAEM,uBAAuB;QAC5B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAEM,wBAAwB;QAC7B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,IAAkB;QAC7C,OAAO,sBAAsB,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,IAAkB;QAC3C,OAAO,wBAAwB,CAAC;IAClC,CAAC;sHA9WU,4BAA4B;6DAA5B,4BAA4B;YC9BnC,AADF,AADF,AAFF,8BAAmC,aAEF,aACH,SACpB;YAAA,uBAAsC;YAAC,qCAAoB;YAAA,iBAAK;YACpE,iCAAoG;YAA5C,yGAAS,iBAAa,IAAC;YAC7E,yBACF;YACF,AADE,iBAAS,EACL;YAIF,AADF,AADF,8BAAyB,aACO,wBAIa;YAAvC,mIAAe,0BAAsB,IAAC;YACtC,+FAAwC;YAI5C,AADE,iBAAgB,EACZ;YAGJ,AADF,+BAA0B,8BAOoB;YAA1C,wIAAe,6BAAyB,IAAC;YAC3C,iBAAqB;YAErB,+CAM+C;YAA7C,wIAAe,gCAA4B,IAAC;YAC9C,iBAAqB;YAErB,+CAM+C;YAA7C,wIAAe,gCAA4B,IAAC;YAIpD,AADE,AADE,AADE,iBAAqB,EACjB,EACF,EACF;YAIJ,AADF,gCAA6B,eACiD;YAAnC,uGAAS,4BAAwB,IAAC;YACzE,gCAAyB;YACvB,yBAAuC;YACzC,iBAAM;YAEJ,AADF,gCAA4B,eACA;YAAA,aAA6B;YAAA,iBAAM;YAC7D,gCAA0B;YAAA,iCAAgB;YAE9C,AADE,AAD4C,iBAAM,EAC5C,EACF;YAEN,gCAA0E;YAA/B,uGAAS,wBAAoB,IAAC;YACvE,gCAAyB;YACvB,yBAAwC;YAC1C,iBAAM;YAEJ,AADF,gCAA4B,eACA;YAAA,aAAuB;YAAA,iBAAM;YACvD,gCAA0B;YAAA,6BAAY;YAAA,iBAAM;YAC5C,gCAA2B;YAAA,aAAgE;YAE/F,AADE,AAD6F,iBAAM,EAC7F,EACF;YAEN,gCAA6E;YAApC,uGAAS,6BAAyB,IAAC;YAC1E,gCAAyB;YACvB,yBAA8C;YAChD,iBAAM;YAEJ,AADF,gCAA4B,eACA;YAAA,aAA8B;YAAA,iBAAM;YAC9D,gCAA0B;YAAA,kCAAiB;YAE/C,AADE,AAD6C,iBAAM,EAC7C,EACF;YAGJ,AADF,gCAAkC,eACP;YACvB,yBAAiC;YACnC,iBAAM;YAEJ,AADF,gCAA4B,eACA;YAAA,aAA8B;YAAA,iBAAM;YAC9D,gCAA0B;YAAA,6BAAY;YAE1C,AADE,AADwC,iBAAM,EACxC,EACF;YAGJ,AADF,gCAAkC,eACP;YACvB,yBAAwC;YAC1C,iBAAM;YAEJ,AADF,gCAA4B,eACA;YAAA,aAA6B;YAAA,iBAAM;YAC7D,gCAA0B;YAAA,sBAAK;YAAA,iBAAM;YACrC,gCAA2B;YAAA,aAA0C;YAEzE,AADE,AADuE,iBAAM,EACvE,EACF;YAEN,gCAAgF;YAArC,uGAAS,8BAA0B,IAAC;YAC7E,gCAAyB;YACvB,yBAA2C;YAC7C,iBAAM;YAEJ,AADF,gCAA4B,eACA;YAAA,aAA8B;YAAA,iBAAM;YAC9D,gCAA0B;YAAA,kCAAiB;YAGjD,AADE,AADE,AAD6C,iBAAM,EAC7C,EACF,EACF;YAKF,AADF,AADF,gCAA4B,eACE,UACtB;YAAA,yBAAsC;YAAC,wCAAsB;YACnE,AADmE,iBAAK,EAClE;YACN,gCAA0B;YAwBtB,AAvBF,uFAAkC,2EAuBzB;YAOb,AADE,iBAAM,EACF;YAKF,AADF,AADF,gCAAgC,eACF,UACtB;YAAA,yBAAgC;YAAC,mCAAiB;YAAA,iBAAK;YAC3D,gCAA2B;YAAA,aAA0C;YACvE,AADuE,iBAAM,EACvE;YAEN,gCAA6B;YAoCzB,AAnCF,sFAAqC,2EAmC5B;YAQb,AADE,iBAAM,EACF;YAEN,iGAAiB;YAKnB,iBAAM;;YAjNoB,eAAgB;YAAC,AAAjB,8BAAgB,mBAAmB;YASnD,eAA2B;YAA3B,6CAA2B;YAU3B,eAAyB;YAIzB,AADA,AAHA,2CAAyB,wBAGF,uCACW;YAKlC,cAAsB;YAItB,AADA,AAHA,wCAAsB,wBAGC,oCACQ;YAK/B,cAAsB;YAItB,AADA,AAHA,wCAAsB,wBAGC,oCACQ;YAcP,eAA6B;YAA7B,iDAA6B;YAU7B,eAAuB;YAAvB,oDAAuB;YAEtB,eAAgE;YAAhE,6FAAgE;YASjE,eAA8B;YAA9B,kDAA8B;YAU9B,eAA8B;YAA9B,2DAA8B;YAU9B,eAA6B;YAA7B,iDAA6B;YAE5B,eAA0C;YAA1C,uEAA0C;YAS3C,eAA8B;YAA9B,kDAA8B;YAY1D,eA4BC;YA5BD,0DA4BC;YAQ0B,eAA0C;YAA1C,uEAA0C;YAIrE,eAyCC;YAzCD,6DAyCC;YAIL,eAIC;YAJD,yCAIC;;;ADnLU,4BAA4B;IAPxC,aAAa,CAAC,qBAAqB,EAAE,wBAAwB,CAAC;GAOlD,4BAA4B,CA+WxC;;iFA/WY,4BAA4B;cANxC,SAAS;6BACI,KAAK,YACP,yBAAyB;;kFAIxB,4BAA4B","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { CompositeKey, RunView, LogError } from '@memberjunction/core';\nimport { MJActionExecutionLogEntity, MJActionEntity, ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { Subject, BehaviorSubject, combineLatest } from 'rxjs';\nimport { debounceTime, takeUntil, distinctUntilChanged } from 'rxjs/operators';\ninterface ExecutionMetrics {\n totalExecutions: number;\n successfulExecutions: number;\n failedExecutions: number;\n averageDuration: number;\n executionsToday: number;\n executionsThisWeek: number;\n currentlyRunning: number;\n}\n\ninterface ExecutionTrend {\n date: string;\n successful: number;\n failed: number;\n total: number;\n}\n\n/**\n * Execution Monitoring Resource - displays action execution logs and metrics\n */\n@RegisterClass(BaseResourceComponent, 'ActionsMonitorResource')\n@Component({\n standalone: false,\n selector: 'mj-execution-monitoring',\n templateUrl: './execution-monitoring.component.html',\n styleUrls: ['./execution-monitoring.component.css']\n})\nexport class ExecutionMonitoringComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = true;\n public executions: MJActionExecutionLogEntity[] = [];\n public filteredExecutions: MJActionExecutionLogEntity[] = [];\n public actions: Map<string, MJActionEntity> = new Map();\n \n public metrics: ExecutionMetrics = {\n totalExecutions: 0,\n successfulExecutions: 0,\n failedExecutions: 0,\n averageDuration: 0,\n executionsToday: 0,\n executionsThisWeek: 0,\n currentlyRunning: 0\n };\n\n public executionTrends: ExecutionTrend[] = [];\n \n public searchTerm$ = new BehaviorSubject<string>('');\n public selectedResult$ = new BehaviorSubject<string>('all');\n public selectedTimeRange$ = new BehaviorSubject<string>('7days');\n public selectedAction$ = new BehaviorSubject<string>('all');\n\n public timeRangeOptions = [\n { text: 'Last 24 Hours', value: '24hours' },\n { text: 'Last 7 Days', value: '7days' },\n { text: 'Last 30 Days', value: '30days' },\n { text: 'Last 90 Days', value: '90days' }\n ];\n\n public resultOptions = [\n { text: 'All Results', value: 'all' },\n { text: 'Success', value: 'Success' },\n { text: 'Failed', value: 'Failed' },\n { text: 'Error', value: 'Error' },\n { text: 'Running', value: 'Running' }\n ];\n\n public actionOptions: Array<{text: string; value: string}> = [\n { text: 'All Actions', value: 'all' }\n ];\n\n private destroy$ = new Subject<void>();\n\n constructor(private navigationService: NavigationService, private cdr: ChangeDetectorRef) {\n super();\n }\n\n ngOnInit(): void {\n this.setupFilters();\n this.loadData();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private setupFilters(): void {\n combineLatest([\n this.searchTerm$.pipe(debounceTime(300), distinctUntilChanged()),\n this.selectedResult$.pipe(distinctUntilChanged()),\n this.selectedTimeRange$.pipe(distinctUntilChanged()),\n this.selectedAction$.pipe(distinctUntilChanged())\n ]).pipe(\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.applyFilters();\n });\n }\n\n private async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n \n const rv = new RunView();\n const [executionsResult, actionsResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Action Execution Logs', \n OrderBy: 'StartedAt DESC' \n },\n {\n EntityName: 'MJ: Actions', \n OrderBy: 'Name' \n }\n ]);\n \n if (!executionsResult.Success || !actionsResult.Success) {\n throw new Error('Failed to load data');\n }\n \n const executions = executionsResult.Results as MJActionExecutionLogEntity[];\n const actions = actionsResult.Results as MJActionEntity[];\n\n this.executions = executions;\n this.populateActionsMap(actions);\n this.buildActionOptions(actions);\n this.calculateMetrics();\n this.generateExecutionTrends();\n this.applyFilters();\n\n } catch (error) {\n LogError('Failed to load execution monitoring data', undefined, error);\n } finally {\n this.isLoading = false;\n this.NotifyLoadComplete();\n this.cdr.detectChanges();\n }\n }\n\n private populateActionsMap(actions: MJActionEntity[]): void {\n this.actions.clear();\n actions.forEach(action => {\n this.actions.set(action.ID, action);\n });\n }\n\n private buildActionOptions(actions: MJActionEntity[]): void {\n this.actionOptions = [\n { text: 'All Actions', value: 'all' },\n ...actions.map(action => ({\n text: action.Name,\n value: action.ID\n }))\n ];\n }\n\n private calculateMetrics(): void {\n const now = new Date();\n const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);\n\n this.metrics = {\n totalExecutions: this.executions.length,\n successfulExecutions: this.executions.filter(e => e.ResultCode === 'Success').length,\n failedExecutions: this.executions.filter(e => \n e.ResultCode && ['Failed', 'Error'].includes(e.ResultCode)\n ).length,\n averageDuration: this.calculateAverageDuration(),\n executionsToday: this.executions.filter(e => \n new Date(e.StartedAt!) >= today\n ).length,\n executionsThisWeek: this.executions.filter(e => \n new Date(e.StartedAt!) >= weekAgo\n ).length,\n currentlyRunning: this.executions.filter(e => \n e.ResultCode === 'Running' || !e.EndedAt\n ).length\n };\n }\n\n private calculateAverageDuration(): number {\n const completedExecutions = this.executions.filter(e => \n e.StartedAt && e.EndedAt\n );\n \n if (completedExecutions.length === 0) return 0;\n\n const totalDuration = completedExecutions.reduce((sum, execution) => {\n const start = new Date(execution.StartedAt!).getTime();\n const end = new Date(execution.EndedAt!).getTime();\n return sum + (end - start);\n }, 0);\n\n return Math.round(totalDuration / completedExecutions.length / 1000); // Average in seconds\n }\n\n private generateExecutionTrends(): void {\n const trends = new Map<string, ExecutionTrend>();\n const last7Days = Array.from({ length: 7 }, (_, i) => {\n const date = new Date();\n date.setDate(date.getDate() - i);\n return date.toISOString().split('T')[0];\n }).reverse();\n\n // Initialize trends for last 7 days\n last7Days.forEach(date => {\n trends.set(date, {\n date,\n successful: 0,\n failed: 0,\n total: 0\n });\n });\n\n // Populate trends with execution data\n this.executions.forEach(execution => {\n if (!execution.StartedAt) return;\n \n const date = new Date(execution.StartedAt).toISOString().split('T')[0];\n const trend = trends.get(date);\n \n if (trend) {\n trend.total++;\n if (execution.ResultCode === 'Success') {\n trend.successful++;\n } else if (execution.ResultCode && ['Failed', 'Error'].includes(execution.ResultCode)) {\n trend.failed++;\n }\n }\n });\n\n this.executionTrends = Array.from(trends.values());\n }\n\n private applyFilters(): void {\n let filtered = [...this.executions];\n\n // Apply time range filter\n const timeRange = this.selectedTimeRange$.value;\n if (timeRange !== 'all') {\n const cutoffDate = this.getTimeRangeCutoff(timeRange);\n filtered = filtered.filter(e => \n e.StartedAt && new Date(e.StartedAt) >= cutoffDate\n );\n }\n\n // Apply result filter\n const result = this.selectedResult$.value;\n if (result !== 'all') {\n if (result === 'Running') {\n filtered = filtered.filter(e => !e.EndedAt || e.ResultCode === 'Running');\n } else {\n filtered = filtered.filter(e => e.ResultCode === result);\n }\n }\n\n // Apply action filter\n const actionId = this.selectedAction$.value;\n if (actionId !== 'all') {\n filtered = filtered.filter(e => UUIDsEqual(e.ActionID, actionId));\n }\n\n // Apply search filter\n const searchTerm = this.searchTerm$.value.toLowerCase();\n if (searchTerm) {\n filtered = filtered.filter(e => {\n const action = this.actions.get(e.ActionID!);\n return (\n action?.Name.toLowerCase().includes(searchTerm) ||\n e.ResultCode?.toLowerCase().includes(searchTerm) ||\n e.UserID?.toLowerCase().includes(searchTerm)\n );\n });\n }\n\n this.filteredExecutions = filtered;\n }\n\n private getTimeRangeCutoff(timeRange: string): Date {\n const now = new Date();\n switch (timeRange) {\n case '24hours':\n return new Date(now.getTime() - 24 * 60 * 60 * 1000);\n case '7days':\n return new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);\n case '30days':\n return new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);\n case '90days':\n return new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000);\n default:\n return new Date(0);\n }\n }\n\n public onSearchChange(searchTerm: string): void {\n this.searchTerm$.next(searchTerm);\n }\n\n public onResultFilterChange(result: string): void {\n this.selectedResult$.next(result);\n }\n\n public onTimeRangeChange(timeRange: string): void {\n this.selectedTimeRange$.next(timeRange);\n }\n\n public onActionFilterChange(actionId: string): void {\n this.selectedAction$.next(actionId);\n }\n\n public openExecution(execution: MJActionExecutionLogEntity): void {\n const key = new CompositeKey([{ FieldName: 'ID', Value: execution.ID }]);\n this.navigationService.OpenEntityRecord('MJ: Action Execution Logs', key);\n }\n\n public openAction(actionId: string): void {\n const key = new CompositeKey([{ FieldName: 'ID', Value: actionId }]);\n this.navigationService.OpenEntityRecord('MJ: Actions', key);\n }\n\n public getActionName(actionId: string): string {\n return this.actions.get(actionId)?.Name || `Action ${actionId}`;\n }\n\n public getResultColor(resultCode: string | null): 'success' | 'warning' | 'error' | 'info' {\n if (!resultCode) return 'info';\n switch (resultCode.toLowerCase()) {\n case 'success': return 'success';\n case 'failed':\n case 'error': return 'error';\n case 'running': return 'warning';\n default: return 'info';\n }\n }\n\n public getResultIcon(resultCode: string | null): string {\n if (!resultCode) return 'fa-solid fa-question';\n switch (resultCode.toLowerCase()) {\n case 'success': return 'fa-solid fa-check-circle';\n case 'failed':\n case 'error': return 'fa-solid fa-exclamation-circle';\n case 'running': return 'fa-solid fa-spinner fa-spin';\n default: return 'fa-solid fa-info-circle';\n }\n }\n\n public getDuration(execution: MJActionExecutionLogEntity): string {\n if (!execution.StartedAt || !execution.EndedAt) {\n return execution.EndedAt ? 'Unknown' : 'Running';\n }\n\n const start = new Date(execution.StartedAt).getTime();\n const end = new Date(execution.EndedAt).getTime();\n const duration = Math.round((end - start) / 1000);\n\n if (duration < 60) return `${duration}s`;\n if (duration < 3600) return `${Math.round(duration / 60)}m`;\n return `${Math.round(duration / 3600)}h`;\n }\n\n public getSuccessRate(): number {\n if (this.metrics.totalExecutions === 0) return 0;\n return Math.round((this.metrics.successfulExecutions / this.metrics.totalExecutions) * 100);\n }\n\n public refreshData(): void {\n this.loadData();\n }\n\n // Metric card click handlers\n public onTotalExecutionsClick(): void {\n // Reset filters to show all executions\n this.selectedResult$.next('all');\n this.selectedTimeRange$.next('7days');\n this.selectedAction$.next('all');\n }\n\n public onSuccessRateClick(): void {\n this.selectedResult$.next('Success');\n }\n\n public onFailedExecutionsClick(): void {\n this.selectedResult$.next('Failed');\n }\n\n public onRunningExecutionsClick(): void {\n this.selectedResult$.next('Running');\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Execution Monitoring';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-chart-line';\n }\n}","<div class=\"execution-monitoring\" >\n <!-- Header with filters -->\n <div class=\"monitoring-header\">\n <div class=\"header-title\">\n <h3><i class=\"fa-solid fa-chart-line\"></i> Execution Monitoring</h3>\n <button kendoButton [primary]=\"true\" [icon]=\"'refresh'\" (click)=\"refreshData()\" class=\"refresh-btn\">\n Refresh\n </button>\n </div>\n \n <div class=\"filters-row\">\n <div class=\"search-container\">\n <kendo-textbox \n placeholder=\"Search executions...\" \n [value]=\"searchTerm$.value\"\n (valueChange)=\"onSearchChange($event)\">\n <ng-template kendoTextBoxPrefixTemplate>\n <i class=\"fa-solid fa-search\"></i>\n </ng-template>\n </kendo-textbox>\n </div>\n \n <div class=\"filter-group\">\n <kendo-dropdownlist \n [data]=\"timeRangeOptions\"\n textField=\"text\"\n valueField=\"value\"\n [valuePrimitive]=\"true\"\n [value]=\"selectedTimeRange$.value\"\n (valueChange)=\"onTimeRangeChange($event)\">\n </kendo-dropdownlist>\n \n <kendo-dropdownlist \n [data]=\"resultOptions\"\n textField=\"text\"\n valueField=\"value\"\n [valuePrimitive]=\"true\"\n [value]=\"selectedResult$.value\"\n (valueChange)=\"onResultFilterChange($event)\">\n </kendo-dropdownlist>\n \n <kendo-dropdownlist \n [data]=\"actionOptions\"\n textField=\"text\"\n valueField=\"value\"\n [valuePrimitive]=\"true\"\n [value]=\"selectedAction$.value\"\n (valueChange)=\"onActionFilterChange($event)\">\n </kendo-dropdownlist>\n </div>\n </div>\n </div>\n\n <!-- Metrics Summary -->\n <div class=\"metrics-summary\">\n <div class=\"metric-card total clickable\" (click)=\"onTotalExecutionsClick()\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-play-circle\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ metrics.totalExecutions }}</div>\n <div class=\"metric-label\">Total Executions</div>\n </div>\n </div>\n\n <div class=\"metric-card success clickable\" (click)=\"onSuccessRateClick()\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ getSuccessRate() }}%</div>\n <div class=\"metric-label\">Success Rate</div>\n <div class=\"metric-detail\">{{ metrics.successfulExecutions }}/{{ metrics.totalExecutions }}</div>\n </div>\n </div>\n\n <div class=\"metric-card error clickable\" (click)=\"onFailedExecutionsClick()\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ metrics.failedExecutions }}</div>\n <div class=\"metric-label\">Failed Executions</div>\n </div>\n </div>\n\n <div class=\"metric-card duration\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ metrics.averageDuration }}s</div>\n <div class=\"metric-label\">Avg Duration</div>\n </div>\n </div>\n\n <div class=\"metric-card activity\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-calendar-day\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ metrics.executionsToday }}</div>\n <div class=\"metric-label\">Today</div>\n <div class=\"metric-detail\">{{ metrics.executionsThisWeek }} this week</div>\n </div>\n </div>\n\n <div class=\"metric-card running clickable\" (click)=\"onRunningExecutionsClick()\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ metrics.currentlyRunning }}</div>\n <div class=\"metric-label\">Currently Running</div>\n </div>\n </div>\n </div>\n\n <!-- Execution Trends Chart -->\n <div class=\"trends-section\">\n <div class=\"section-header\">\n <h4><i class=\"fa-solid fa-chart-area\"></i> 7-Day Execution Trends</h4>\n </div>\n <div class=\"trends-chart\">\n @if (executionTrends.length > 0) {\n <div class=\"trend-bars\">\n @for (trend of executionTrends; track trend.date) {\n <div class=\"trend-bar\">\n <div class=\"bar-container\">\n <div class=\"bar-success\" [style.height.%]=\"trend.total > 0 ? (trend.successful / trend.total) * 100 : 0\"></div>\n <div class=\"bar-failed\" [style.height.%]=\"trend.total > 0 ? (trend.failed / trend.total) * 100 : 0\"></div>\n </div>\n <div class=\"bar-label\">{{ trend.date | date:'MMM d' }}</div>\n <div class=\"bar-total\">{{ trend.total }}</div>\n </div>\n }\n </div>\n <div class=\"chart-legend\">\n <div class=\"legend-item\">\n <div class=\"legend-color success\"></div>\n <span>Successful</span>\n </div>\n <div class=\"legend-item\">\n <div class=\"legend-color failed\"></div>\n <span>Failed</span>\n </div>\n </div>\n } @else {\n <div class=\"empty-chart\">\n <i class=\"fa-solid fa-chart-area\"></i>\n <p>No execution trends available</p>\n </div>\n }\n </div>\n </div>\n\n <!-- Execution List -->\n <div class=\"executions-section\">\n <div class=\"section-header\">\n <h4><i class=\"fa-solid fa-list\"></i> Recent Executions</h4>\n <div class=\"results-count\">{{ filteredExecutions.length }} executions</div>\n </div>\n \n <div class=\"executions-list\">\n @if (filteredExecutions.length > 0) {\n @for (execution of filteredExecutions; track execution.ID) {\n <div class=\"execution-item\" (click)=\"openExecution(execution)\">\n <div class=\"execution-status\">\n <i [class]=\"getResultIcon(execution.ResultCode)\"></i>\n </div>\n \n <div class=\"execution-main\">\n <div class=\"execution-action\" (click)=\"openAction(execution.ActionID!); $event.stopPropagation()\">\n {{ getActionName(execution.ActionID!) }}\n </div>\n <div class=\"execution-details\">\n <span class=\"execution-time\">{{ execution.StartedAt | date:'MMM d, HH:mm:ss' }}</span>\n <span class=\"execution-user\">{{ execution.UserID }}</span>\n <span class=\"execution-duration\">{{ getDuration(execution) }}</span>\n </div>\n </div>\n \n <div class=\"execution-result\">\n <kendo-chip \n [themeColor]=\"getResultColor(execution.ResultCode)\"\n [size]=\"'small'\">\n {{ execution.ResultCode || 'Unknown' }}\n </kendo-chip>\n </div>\n \n <div class=\"execution-actions\">\n <button kendoButton \n [fillMode]=\"'flat'\" \n [icon]=\"'more-vertical'\"\n (click)=\"$event.stopPropagation()\">\n </button>\n </div>\n </div>\n }\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-search\"></i>\n <h5>No executions found</h5>\n <p>Try adjusting your filters or search terms</p>\n </div>\n }\n </div>\n </div>\n\n @if (isLoading) {\n <div class=\"loading-overlay\">\n <mj-loading [showText]=\"false\" size=\"medium\"></mj-loading>\n </div>\n }\n</div>"]}
|
|
1
|
+
{"version":3,"file":"execution-monitoring.component.js","sourceRoot":"","sources":["../../../src/Actions/components/execution-monitoring.component.ts","../../../src/Actions/components/execution-monitoring.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { CompositeKey, RunView, LogError } from '@memberjunction/core';\nimport { MJActionExecutionLogEntity, MJActionEntity, ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { Subject, BehaviorSubject, combineLatest } from 'rxjs';\nimport { debounceTime, takeUntil, distinctUntilChanged } from 'rxjs/operators';\ninterface ExecutionMetrics {\n totalExecutions: number;\n successfulExecutions: number;\n failedExecutions: number;\n averageDuration: number;\n executionsToday: number;\n executionsThisWeek: number;\n currentlyRunning: number;\n}\n\ninterface ExecutionTrend {\n date: string;\n successful: number;\n failed: number;\n total: number;\n}\n\n/**\n * Execution Monitoring Resource - displays action execution logs and metrics\n */\n@RegisterClass(BaseResourceComponent, 'ActionsMonitorResource')\n@Component({\n standalone: false,\n selector: 'mj-execution-monitoring',\n templateUrl: './execution-monitoring.component.html',\n styleUrls: ['./execution-monitoring.component.css']\n})\nexport class ExecutionMonitoringComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public isLoading = true;\n public executions: MJActionExecutionLogEntity[] = [];\n public filteredExecutions: MJActionExecutionLogEntity[] = [];\n public actions: Map<string, MJActionEntity> = new Map();\n \n public metrics: ExecutionMetrics = {\n totalExecutions: 0,\n successfulExecutions: 0,\n failedExecutions: 0,\n averageDuration: 0,\n executionsToday: 0,\n executionsThisWeek: 0,\n currentlyRunning: 0\n };\n\n public executionTrends: ExecutionTrend[] = [];\n \n public searchTerm$ = new BehaviorSubject<string>('');\n public selectedResult$ = new BehaviorSubject<string>('all');\n public selectedTimeRange$ = new BehaviorSubject<string>('7days');\n public selectedAction$ = new BehaviorSubject<string>('all');\n\n public timeRangeOptions = [\n { text: 'Last 24 Hours', value: '24hours' },\n { text: 'Last 7 Days', value: '7days' },\n { text: 'Last 30 Days', value: '30days' },\n { text: 'Last 90 Days', value: '90days' }\n ];\n\n public resultOptions = [\n { text: 'All Results', value: 'all' },\n { text: 'Success', value: 'Success' },\n { text: 'Failed', value: 'Failed' },\n { text: 'Error', value: 'Error' },\n { text: 'Running', value: 'Running' }\n ];\n\n public actionOptions: Array<{text: string; value: string}> = [\n { text: 'All Actions', value: 'all' }\n ];\n\n private destroy$ = new Subject<void>();\n\n constructor(private navigationService: NavigationService, private cdr: ChangeDetectorRef) {\n super();\n }\n\n ngOnInit(): void {\n this.setupFilters();\n this.loadData();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private setupFilters(): void {\n combineLatest([\n this.searchTerm$.pipe(debounceTime(300), distinctUntilChanged()),\n this.selectedResult$.pipe(distinctUntilChanged()),\n this.selectedTimeRange$.pipe(distinctUntilChanged()),\n this.selectedAction$.pipe(distinctUntilChanged())\n ]).pipe(\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.applyFilters();\n });\n }\n\n private async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n \n const rv = new RunView();\n const [executionsResult, actionsResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Action Execution Logs', \n OrderBy: 'StartedAt DESC' \n },\n {\n EntityName: 'MJ: Actions', \n OrderBy: 'Name' \n }\n ]);\n \n if (!executionsResult.Success || !actionsResult.Success) {\n throw new Error('Failed to load data');\n }\n \n const executions = executionsResult.Results as MJActionExecutionLogEntity[];\n const actions = actionsResult.Results as MJActionEntity[];\n\n this.executions = executions;\n this.populateActionsMap(actions);\n this.buildActionOptions(actions);\n this.calculateMetrics();\n this.generateExecutionTrends();\n this.applyFilters();\n\n } catch (error) {\n LogError('Failed to load execution monitoring data', undefined, error);\n } finally {\n this.isLoading = false;\n this.NotifyLoadComplete();\n this.cdr.detectChanges();\n }\n }\n\n private populateActionsMap(actions: MJActionEntity[]): void {\n this.actions.clear();\n actions.forEach(action => {\n this.actions.set(action.ID, action);\n });\n }\n\n private buildActionOptions(actions: MJActionEntity[]): void {\n this.actionOptions = [\n { text: 'All Actions', value: 'all' },\n ...actions.map(action => ({\n text: action.Name,\n value: action.ID\n }))\n ];\n }\n\n private calculateMetrics(): void {\n const now = new Date();\n const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);\n\n this.metrics = {\n totalExecutions: this.executions.length,\n successfulExecutions: this.executions.filter(e => e.ResultCode === 'Success').length,\n failedExecutions: this.executions.filter(e => \n e.ResultCode && ['Failed', 'Error'].includes(e.ResultCode)\n ).length,\n averageDuration: this.calculateAverageDuration(),\n executionsToday: this.executions.filter(e => \n new Date(e.StartedAt!) >= today\n ).length,\n executionsThisWeek: this.executions.filter(e => \n new Date(e.StartedAt!) >= weekAgo\n ).length,\n currentlyRunning: this.executions.filter(e => \n e.ResultCode === 'Running' || !e.EndedAt\n ).length\n };\n }\n\n private calculateAverageDuration(): number {\n const completedExecutions = this.executions.filter(e => \n e.StartedAt && e.EndedAt\n );\n \n if (completedExecutions.length === 0) return 0;\n\n const totalDuration = completedExecutions.reduce((sum, execution) => {\n const start = new Date(execution.StartedAt!).getTime();\n const end = new Date(execution.EndedAt!).getTime();\n return sum + (end - start);\n }, 0);\n\n return Math.round(totalDuration / completedExecutions.length / 1000); // Average in seconds\n }\n\n private generateExecutionTrends(): void {\n const trends = new Map<string, ExecutionTrend>();\n const last7Days = Array.from({ length: 7 }, (_, i) => {\n const date = new Date();\n date.setDate(date.getDate() - i);\n return date.toISOString().split('T')[0];\n }).reverse();\n\n // Initialize trends for last 7 days\n last7Days.forEach(date => {\n trends.set(date, {\n date,\n successful: 0,\n failed: 0,\n total: 0\n });\n });\n\n // Populate trends with execution data\n this.executions.forEach(execution => {\n if (!execution.StartedAt) return;\n \n const date = new Date(execution.StartedAt).toISOString().split('T')[0];\n const trend = trends.get(date);\n \n if (trend) {\n trend.total++;\n if (execution.ResultCode === 'Success') {\n trend.successful++;\n } else if (execution.ResultCode && ['Failed', 'Error'].includes(execution.ResultCode)) {\n trend.failed++;\n }\n }\n });\n\n this.executionTrends = Array.from(trends.values());\n }\n\n private applyFilters(): void {\n let filtered = [...this.executions];\n\n // Apply time range filter\n const timeRange = this.selectedTimeRange$.value;\n if (timeRange !== 'all') {\n const cutoffDate = this.getTimeRangeCutoff(timeRange);\n filtered = filtered.filter(e => \n e.StartedAt && new Date(e.StartedAt) >= cutoffDate\n );\n }\n\n // Apply result filter\n const result = this.selectedResult$.value;\n if (result !== 'all') {\n if (result === 'Running') {\n filtered = filtered.filter(e => !e.EndedAt || e.ResultCode === 'Running');\n } else {\n filtered = filtered.filter(e => e.ResultCode === result);\n }\n }\n\n // Apply action filter\n const actionId = this.selectedAction$.value;\n if (actionId !== 'all') {\n filtered = filtered.filter(e => UUIDsEqual(e.ActionID, actionId));\n }\n\n // Apply search filter\n const searchTerm = this.searchTerm$.value.toLowerCase();\n if (searchTerm) {\n filtered = filtered.filter(e => {\n const action = this.actions.get(e.ActionID!);\n return (\n action?.Name.toLowerCase().includes(searchTerm) ||\n e.ResultCode?.toLowerCase().includes(searchTerm) ||\n e.UserID?.toLowerCase().includes(searchTerm)\n );\n });\n }\n\n this.filteredExecutions = filtered;\n }\n\n private getTimeRangeCutoff(timeRange: string): Date {\n const now = new Date();\n switch (timeRange) {\n case '24hours':\n return new Date(now.getTime() - 24 * 60 * 60 * 1000);\n case '7days':\n return new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);\n case '30days':\n return new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);\n case '90days':\n return new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000);\n default:\n return new Date(0);\n }\n }\n\n public onSearchChange(searchTerm: string): void {\n this.searchTerm$.next(searchTerm);\n }\n\n public onResultFilterChange(result: string): void {\n this.selectedResult$.next(result);\n }\n\n public onTimeRangeChange(timeRange: string): void {\n this.selectedTimeRange$.next(timeRange);\n }\n\n public onActionFilterChange(actionId: string): void {\n this.selectedAction$.next(actionId);\n }\n\n public openExecution(execution: MJActionExecutionLogEntity): void {\n const key = new CompositeKey([{ FieldName: 'ID', Value: execution.ID }]);\n this.navigationService.OpenEntityRecord('MJ: Action Execution Logs', key);\n }\n\n public openAction(actionId: string): void {\n const key = new CompositeKey([{ FieldName: 'ID', Value: actionId }]);\n this.navigationService.OpenEntityRecord('MJ: Actions', key);\n }\n\n public getActionName(actionId: string): string {\n return this.actions.get(actionId)?.Name || `Action ${actionId}`;\n }\n\n public getResultColor(resultCode: string | null): 'success' | 'warning' | 'error' | 'info' {\n if (!resultCode) return 'info';\n switch (resultCode.toLowerCase()) {\n case 'success': return 'success';\n case 'failed':\n case 'error': return 'error';\n case 'running': return 'warning';\n default: return 'info';\n }\n }\n\n public getResultIcon(resultCode: string | null): string {\n if (!resultCode) return 'fa-solid fa-question';\n switch (resultCode.toLowerCase()) {\n case 'success': return 'fa-solid fa-check-circle';\n case 'failed':\n case 'error': return 'fa-solid fa-exclamation-circle';\n case 'running': return 'fa-solid fa-spinner fa-spin';\n default: return 'fa-solid fa-info-circle';\n }\n }\n\n public getDuration(execution: MJActionExecutionLogEntity): string {\n if (!execution.StartedAt || !execution.EndedAt) {\n return execution.EndedAt ? 'Unknown' : 'Running';\n }\n\n const start = new Date(execution.StartedAt).getTime();\n const end = new Date(execution.EndedAt).getTime();\n const duration = Math.round((end - start) / 1000);\n\n if (duration < 60) return `${duration}s`;\n if (duration < 3600) return `${Math.round(duration / 60)}m`;\n return `${Math.round(duration / 3600)}h`;\n }\n\n public getSuccessRate(): number {\n if (this.metrics.totalExecutions === 0) return 0;\n return Math.round((this.metrics.successfulExecutions / this.metrics.totalExecutions) * 100);\n }\n\n public refreshData(): void {\n this.loadData();\n }\n\n // Metric card click handlers\n public onTotalExecutionsClick(): void {\n // Reset filters to show all executions\n this.selectedResult$.next('all');\n this.selectedTimeRange$.next('7days');\n this.selectedAction$.next('all');\n }\n\n public onSuccessRateClick(): void {\n this.selectedResult$.next('Success');\n }\n\n public onFailedExecutionsClick(): void {\n this.selectedResult$.next('Failed');\n }\n\n public onRunningExecutionsClick(): void {\n this.selectedResult$.next('Running');\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Execution Monitoring';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-chart-line';\n }\n}","<div class=\"execution-monitoring\" >\n <!-- Header with filters -->\n <div class=\"monitoring-header\">\n <div class=\"header-title\">\n <h3><i class=\"fa-solid fa-chart-line\"></i> Execution Monitoring</h3>\n <button mjButton variant=\"primary\" (click)=\"refreshData()\" class=\"refresh-btn\">\n <i class=\"fa-solid fa-refresh\"></i> Refresh\n </button>\n </div>\n \n <div class=\"filters-row\">\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input type=\"text\" class=\"mj-input\"\n placeholder=\"Search executions...\"\n [value]=\"searchTerm$.value\"\n (input)=\"onSearchChange($any($event.target).value)\" />\n </div>\n </div>\n\n <div class=\"filter-group\">\n <mj-dropdown\n [Data]=\"timeRangeOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [ngModel]=\"selectedTimeRange$.value\"\n (ValueChange)=\"onTimeRangeChange($any($event))\">\n </mj-dropdown>\n\n <mj-dropdown\n [Data]=\"resultOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [ngModel]=\"selectedResult$.value\"\n (ValueChange)=\"onResultFilterChange($any($event))\">\n </mj-dropdown>\n\n <mj-dropdown\n [Data]=\"actionOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [ngModel]=\"selectedAction$.value\"\n (ValueChange)=\"onActionFilterChange($any($event))\">\n </mj-dropdown>\n </div>\n </div>\n </div>\n\n <!-- Metrics Summary -->\n <div class=\"metrics-summary\">\n <div class=\"metric-card total clickable\" (click)=\"onTotalExecutionsClick()\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-play-circle\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ metrics.totalExecutions }}</div>\n <div class=\"metric-label\">Total Executions</div>\n </div>\n </div>\n\n <div class=\"metric-card success clickable\" (click)=\"onSuccessRateClick()\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ getSuccessRate() }}%</div>\n <div class=\"metric-label\">Success Rate</div>\n <div class=\"metric-detail\">{{ metrics.successfulExecutions }}/{{ metrics.totalExecutions }}</div>\n </div>\n </div>\n\n <div class=\"metric-card error clickable\" (click)=\"onFailedExecutionsClick()\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ metrics.failedExecutions }}</div>\n <div class=\"metric-label\">Failed Executions</div>\n </div>\n </div>\n\n <div class=\"metric-card duration\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-clock\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ metrics.averageDuration }}s</div>\n <div class=\"metric-label\">Avg Duration</div>\n </div>\n </div>\n\n <div class=\"metric-card activity\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-calendar-day\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ metrics.executionsToday }}</div>\n <div class=\"metric-label\">Today</div>\n <div class=\"metric-detail\">{{ metrics.executionsThisWeek }} this week</div>\n </div>\n </div>\n\n <div class=\"metric-card running clickable\" (click)=\"onRunningExecutionsClick()\">\n <div class=\"metric-icon\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ metrics.currentlyRunning }}</div>\n <div class=\"metric-label\">Currently Running</div>\n </div>\n </div>\n </div>\n\n <!-- Execution Trends Chart -->\n <div class=\"trends-section\">\n <div class=\"section-header\">\n <h4><i class=\"fa-solid fa-chart-area\"></i> 7-Day Execution Trends</h4>\n </div>\n <div class=\"trends-chart\">\n @if (executionTrends.length > 0) {\n <div class=\"trend-bars\">\n @for (trend of executionTrends; track trend.date) {\n <div class=\"trend-bar\">\n <div class=\"bar-container\">\n <div class=\"bar-success\" [style.height.%]=\"trend.total > 0 ? (trend.successful / trend.total) * 100 : 0\"></div>\n <div class=\"bar-failed\" [style.height.%]=\"trend.total > 0 ? (trend.failed / trend.total) * 100 : 0\"></div>\n </div>\n <div class=\"bar-label\">{{ trend.date | date:'MMM d' }}</div>\n <div class=\"bar-total\">{{ trend.total }}</div>\n </div>\n }\n </div>\n <div class=\"chart-legend\">\n <div class=\"legend-item\">\n <div class=\"legend-color success\"></div>\n <span>Successful</span>\n </div>\n <div class=\"legend-item\">\n <div class=\"legend-color failed\"></div>\n <span>Failed</span>\n </div>\n </div>\n } @else {\n <div class=\"empty-chart\">\n <i class=\"fa-solid fa-chart-area\"></i>\n <p>No execution trends available</p>\n </div>\n }\n </div>\n </div>\n\n <!-- Execution List -->\n <div class=\"executions-section\">\n <div class=\"section-header\">\n <h4><i class=\"fa-solid fa-list\"></i> Recent Executions</h4>\n <div class=\"results-count\">{{ filteredExecutions.length }} executions</div>\n </div>\n \n <div class=\"executions-list\">\n @if (filteredExecutions.length > 0) {\n @for (execution of filteredExecutions; track execution.ID) {\n <div class=\"execution-item\" (click)=\"openExecution(execution)\">\n <div class=\"execution-status\">\n <i [class]=\"getResultIcon(execution.ResultCode)\"></i>\n </div>\n \n <div class=\"execution-main\">\n <div class=\"execution-action\" (click)=\"openAction(execution.ActionID!); $event.stopPropagation()\">\n {{ getActionName(execution.ActionID!) }}\n </div>\n <div class=\"execution-details\">\n <span class=\"execution-time\">{{ execution.StartedAt | date:'MMM d, HH:mm:ss' }}</span>\n <span class=\"execution-user\">{{ execution.UserID }}</span>\n <span class=\"execution-duration\">{{ getDuration(execution) }}</span>\n </div>\n </div>\n \n <div class=\"execution-result\">\n <span class=\"status-chip\" [attr.data-color]=\"getResultColor(execution.ResultCode)\">\n {{ execution.ResultCode || 'Unknown' }}\n </span>\n </div>\n \n <div class=\"execution-actions\">\n <button mjButton\n variant=\"flat\"\n (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-ellipsis-vertical\"></i>\n </button>\n </div>\n </div>\n }\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-search\"></i>\n <h5>No executions found</h5>\n <p>Try adjusting your filters or search terms</p>\n </div>\n }\n </div>\n </div>\n\n @if (isLoading) {\n <div class=\"loading-overlay\">\n <mj-loading [showText]=\"false\" size=\"medium\"></mj-loading>\n </div>\n }\n</div>"]}
|
|
@@ -12,7 +12,7 @@ export class ExecutionsListViewComponent {
|
|
|
12
12
|
i0.ɵɵelementStart(5, "p");
|
|
13
13
|
i0.ɵɵtext(6, "Detailed execution history with filtering and sorting coming soon...");
|
|
14
14
|
i0.ɵɵelementEnd()()();
|
|
15
|
-
} }, styles: [".executions-list-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: var(--
|
|
15
|
+
} }, styles: [".executions-list-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: var(--mj-bg-surface);\n \n .placeholder-content {\n text-align: center;\n color: var(--mj-text-muted);\n \n i {\n font-size: 3rem;\n margin-bottom: 1rem;\n opacity: 0.5;\n color: var(--mj-brand-primary);\n }\n \n h3 {\n margin: 0 0 0.5rem 0;\n font-size: 1.25rem;\n font-weight: 600;\n }\n \n p {\n margin: 0;\n font-size: 0.875rem;\n }\n }\n }"] });
|
|
16
16
|
}
|
|
17
17
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ExecutionsListViewComponent, [{
|
|
18
18
|
type: Component,
|
|
@@ -24,7 +24,7 @@ export class ExecutionsListViewComponent {
|
|
|
24
24
|
<p>Detailed execution history with filtering and sorting coming soon...</p>
|
|
25
25
|
</div>
|
|
26
26
|
</div>
|
|
27
|
-
`, styles: ["\n .executions-list-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: var(--
|
|
27
|
+
`, styles: ["\n .executions-list-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: var(--mj-bg-surface);\n \n .placeholder-content {\n text-align: center;\n color: var(--mj-text-muted);\n \n i {\n font-size: 3rem;\n margin-bottom: 1rem;\n opacity: 0.5;\n color: var(--mj-brand-primary);\n }\n \n h3 {\n margin: 0 0 0.5rem 0;\n font-size: 1.25rem;\n font-weight: 600;\n }\n \n p {\n margin: 0;\n font-size: 0.875rem;\n }\n }\n }\n "] }]
|
|
28
28
|
}], null, { openEntityRecord: [{
|
|
29
29
|
type: Output
|
|
30
30
|
}] }); })();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executions-list-view.component.js","sourceRoot":"","sources":["../../../src/Actions/components/executions-list-view.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;;AA+ChE,MAAM,OAAO,2BAA2B;IAC5B,gBAAgB,GAAG,IAAI,YAAY,EAA0C,CAAC;qHAD7E,2BAA2B;6DAA3B,2BAA2B;YAxClC,AADF,8BAA0C,aACP;YAC/B,uBAAgC;YAChC,0BAAI;YAAA,oCAAoB;YAAA,iBAAK;YAC7B,yBAAG;YAAA,oFAAoE;YAE3E,AADE,AADyE,iBAAI,EACvE,EACF;;;iFAmCG,2BAA2B;cA7CvC,SAAS;6BACI,KAAK,YACP,yBAAyB,YACzB;;;;;;;;GAQT;;kBAmCA,MAAM;;kFADI,2BAA2B","sourcesContent":["import { Component, Output, EventEmitter } from '@angular/core';\n\n@Component({\n standalone: false,\n selector: 'mj-executions-list-view',\n template: `\n <div class=\"executions-list-placeholder\" >\n <div class=\"placeholder-content\">\n <i class=\"fa-solid fa-list\"></i>\n <h3>Executions List View</h3>\n <p>Detailed execution history with filtering and sorting coming soon...</p>\n </div>\n </div>\n `,\n styles: [`\n .executions-list-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: var(--
|
|
1
|
+
{"version":3,"file":"executions-list-view.component.js","sourceRoot":"","sources":["../../../src/Actions/components/executions-list-view.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;;AA+ChE,MAAM,OAAO,2BAA2B;IAC5B,gBAAgB,GAAG,IAAI,YAAY,EAA0C,CAAC;qHAD7E,2BAA2B;6DAA3B,2BAA2B;YAxClC,AADF,8BAA0C,aACP;YAC/B,uBAAgC;YAChC,0BAAI;YAAA,oCAAoB;YAAA,iBAAK;YAC7B,yBAAG;YAAA,oFAAoE;YAE3E,AADE,AADyE,iBAAI,EACvE,EACF;;;iFAmCG,2BAA2B;cA7CvC,SAAS;6BACI,KAAK,YACP,yBAAyB,YACzB;;;;;;;;GAQT;;kBAmCA,MAAM;;kFADI,2BAA2B","sourcesContent":["import { Component, Output, EventEmitter } from '@angular/core';\n\n@Component({\n standalone: false,\n selector: 'mj-executions-list-view',\n template: `\n <div class=\"executions-list-placeholder\" >\n <div class=\"placeholder-content\">\n <i class=\"fa-solid fa-list\"></i>\n <h3>Executions List View</h3>\n <p>Detailed execution history with filtering and sorting coming soon...</p>\n </div>\n </div>\n `,\n styles: [`\n .executions-list-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: var(--mj-bg-surface);\n \n .placeholder-content {\n text-align: center;\n color: var(--mj-text-muted);\n \n i {\n font-size: 3rem;\n margin-bottom: 1rem;\n opacity: 0.5;\n color: var(--mj-brand-primary);\n }\n \n h3 {\n margin: 0 0 0.5rem 0;\n font-size: 1.25rem;\n font-weight: 600;\n }\n \n p {\n margin: 0;\n font-size: 0.875rem;\n }\n }\n }\n `]\n})\nexport class ExecutionsListViewComponent {\n @Output() openEntityRecord = new EventEmitter<{entityName: string; recordId: string}>();\n}"]}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
|
|
2
2
|
import { RunView } from '@memberjunction/core';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
|
-
import * as i1 from "@
|
|
4
|
+
import * as i1 from "@memberjunction/ng-ui-components";
|
|
5
5
|
import * as i2 from "@memberjunction/ng-shared-generic";
|
|
6
6
|
const _forTrack0 = ($index, $item) => $item.Name;
|
|
7
7
|
function ActionCardComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
8
|
-
i0.ɵɵelementStart(0, "
|
|
8
|
+
i0.ɵɵelementStart(0, "span", 8);
|
|
9
9
|
i0.ɵɵelement(1, "i", 21);
|
|
10
10
|
i0.ɵɵtext(2, " AI ");
|
|
11
11
|
i0.ɵɵelementEnd();
|
|
12
|
-
} if (rf & 2) {
|
|
13
|
-
i0.ɵɵproperty("size", "small");
|
|
14
12
|
} }
|
|
15
13
|
function ActionCardComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
16
14
|
i0.ɵɵelementStart(0, "span", 13);
|
|
@@ -311,7 +309,7 @@ export class ActionCardComponent {
|
|
|
311
309
|
return date.toLocaleDateString();
|
|
312
310
|
}
|
|
313
311
|
static ɵfac = function ActionCardComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ActionCardComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
314
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ActionCardComponent, selectors: [["mj-action-card"]], inputs: { Action: "Action", Categories: "Categories" }, outputs: { ActionClick: "ActionClick", EditClick: "EditClick", RunClick: "RunClick", CategoryClick: "CategoryClick" }, standalone: false, decls: 29, vars:
|
|
312
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ActionCardComponent, selectors: [["mj-action-card"]], inputs: { Action: "Action", Categories: "Categories" }, outputs: { ActionClick: "ActionClick", EditClick: "EditClick", RunClick: "RunClick", CategoryClick: "CategoryClick" }, standalone: false, decls: 29, vars: 21, consts: [[1, "action-card", 3, "click"], [1, "card-main"], [1, "action-icon"], [1, "action-content"], [1, "action-header"], [1, "action-name", 3, "title"], [1, "action-badges"], [1, "status-chip"], ["data-color", "info", 1, "status-chip"], [1, "action-description", 3, "title"], [1, "action-meta"], [1, "meta-item", "category", 3, "click", "title"], [1, "fa-solid", "fa-folder"], [1, "meta-item"], [1, "action-buttons"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "View Stats", 3, "click"], ["mjButton", "", "variant", "primary", "size", "sm", "title", "Run Action", 3, "click", "disabled"], [1, "fa-solid", "fa-play"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Edit Action", 3, "click"], [1, "fa-solid", "fa-pen"], [1, "card-expanded"], [1, "fa-solid", "fa-robot"], [1, "fa-solid", "fa-clock"], [1, "stats-loading"], ["size", "small", 3, "showText"], [1, "stats-grid"], [1, "stat-item"], [1, "stat-value"], [1, "stat-label"], [1, "stat-item", "params"], [1, "params-preview"], [1, "params-header"], [1, "fa-solid", "fa-sliders"], [1, "params-list"], [1, "param-tag", 3, "required"], [1, "param-more"], [1, "param-tag"], [1, "required-marker"]], template: function ActionCardComponent_Template(rf, ctx) { if (rf & 1) {
|
|
315
313
|
i0.ɵɵelementStart(0, "div", 0);
|
|
316
314
|
i0.ɵɵlistener("click", function ActionCardComponent_Template_div_click_0_listener() { return ctx.onCardClick(); });
|
|
317
315
|
i0.ɵɵelementStart(1, "div", 1)(2, "div", 2);
|
|
@@ -320,10 +318,10 @@ export class ActionCardComponent {
|
|
|
320
318
|
i0.ɵɵelementStart(4, "div", 3)(5, "div", 4)(6, "h3", 5);
|
|
321
319
|
i0.ɵɵtext(7);
|
|
322
320
|
i0.ɵɵelementEnd();
|
|
323
|
-
i0.ɵɵelementStart(8, "div", 6)(9, "
|
|
321
|
+
i0.ɵɵelementStart(8, "div", 6)(9, "span", 7);
|
|
324
322
|
i0.ɵɵtext(10);
|
|
325
323
|
i0.ɵɵelementEnd();
|
|
326
|
-
i0.ɵɵconditionalCreate(11, ActionCardComponent_Conditional_11_Template, 3,
|
|
324
|
+
i0.ɵɵconditionalCreate(11, ActionCardComponent_Conditional_11_Template, 3, 0, "span", 8);
|
|
327
325
|
i0.ɵɵelementEnd()();
|
|
328
326
|
i0.ɵɵelementStart(12, "p", 9);
|
|
329
327
|
i0.ɵɵtext(13);
|
|
@@ -362,7 +360,7 @@ export class ActionCardComponent {
|
|
|
362
360
|
i0.ɵɵadvance();
|
|
363
361
|
i0.ɵɵtextInterpolate(ctx.Action.Name);
|
|
364
362
|
i0.ɵɵadvance(2);
|
|
365
|
-
i0.ɵɵ
|
|
363
|
+
i0.ɵɵattribute("data-color", ctx.getStatusColor());
|
|
366
364
|
i0.ɵɵadvance();
|
|
367
365
|
i0.ɵɵtextInterpolate1(" ", ctx.Action.Status, " ");
|
|
368
366
|
i0.ɵɵadvance();
|
|
@@ -379,21 +377,17 @@ export class ActionCardComponent {
|
|
|
379
377
|
i0.ɵɵconditional(ctx.Action.__mj_UpdatedAt ? 19 : -1);
|
|
380
378
|
i0.ɵɵadvance();
|
|
381
379
|
i0.ɵɵconditional(ctx.Action.Type === "Generated" && ctx.Action.CodeApprovalStatus ? 20 : -1);
|
|
382
|
-
i0.ɵɵadvance(
|
|
383
|
-
i0.ɵɵproperty("fillMode", "flat")("size", "small");
|
|
384
|
-
i0.ɵɵadvance();
|
|
380
|
+
i0.ɵɵadvance(3);
|
|
385
381
|
i0.ɵɵclassMap(ctx.IsExpanded ? "fa-solid fa-chevron-up" : "fa-solid fa-chart-line");
|
|
386
382
|
i0.ɵɵadvance();
|
|
387
|
-
i0.ɵɵproperty("
|
|
388
|
-
i0.ɵɵadvance(
|
|
389
|
-
i0.ɵɵproperty("fillMode", "flat")("size", "small");
|
|
390
|
-
i0.ɵɵadvance(2);
|
|
383
|
+
i0.ɵɵproperty("disabled", ctx.Action.Status !== "Active");
|
|
384
|
+
i0.ɵɵadvance(4);
|
|
391
385
|
i0.ɵɵconditional(ctx.IsExpanded ? 28 : -1);
|
|
392
|
-
} }, dependencies: [i1.
|
|
386
|
+
} }, dependencies: [i1.MJButtonDirective, i2.LoadingComponent], styles: [".action-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.action-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\n\n.action-card.expanded[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n}\n\n.card-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n}\n\n\n\n.action-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n flex-shrink: 0;\n}\n\n.action-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.action-icon.ai-generated[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface)), color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)));\n}\n\n.action-icon.ai-generated[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, var(--mj-status-info), var(--mj-brand-primary));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n}\n\n\n\n.action-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.action-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.action-name[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.action-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.action-description[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.action-meta[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n background: none;\n border: none;\n padding: 0;\n cursor: default;\n}\n\n.meta-item.category[_ngcontent-%COMP%] {\n cursor: pointer;\n padding: 2px 6px;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.meta-item.category[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-brand-primary);\n}\n\n.meta-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.meta-item[data-status=\"Approved\"][_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.meta-item[data-status=\"Pending\"][_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.meta-item[data-status=\"Rejected\"][_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.action-card[_ngcontent-%COMP%]:hover .action-buttons[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.action-buttons[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n padding: 6px;\n}\n\n\n\n.card-expanded[_ngcontent-%COMP%] {\n padding: 0 20px 20px 20px;\n border-top: 1px solid var(--mj-border-default);\n margin-top: -1px;\n padding-top: 16px;\n background: var(--mj-bg-page);\n}\n\n.stats-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 20px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n margin-bottom: 16px;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n text-align: center;\n padding: 12px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.stat-value.success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.stat-value.warning[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.stat-value.error[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.params-preview[_ngcontent-%COMP%] {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n}\n\n.params-header[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.params-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.params-list[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.param-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 14px;\n font-size: 12px;\n color: var(--mj-text-primary);\n}\n\n.param-tag.required[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.required-marker[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-weight: 600;\n}\n\n.param-more[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n\n\n@media (max-width: 640px) {\n .card-main[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .action-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n }\n\n .action-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .action-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .action-buttons[_ngcontent-%COMP%] {\n flex-direction: row;\n opacity: 1;\n width: 100%;\n justify-content: flex-end;\n }\n\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}"], changeDetection: 0 });
|
|
393
387
|
}
|
|
394
388
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ActionCardComponent, [{
|
|
395
389
|
type: Component,
|
|
396
|
-
args: [{ standalone: false, selector: 'mj-action-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"action-card\" [class.expanded]=\"IsExpanded\" (click)=\"onCardClick()\">\n <div class=\"card-main\">\n <!-- Icon -->\n <div class=\"action-icon\" [class.ai-generated]=\"Action.Type === 'Generated'\">\n <i [class]=\"getActionIcon()\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"action-content\">\n <div class=\"action-header\">\n <h3 class=\"action-name\" [title]=\"Action.Name\">{{ Action.Name }}</h3>\n <div class=\"action-badges\">\n <kendo-chip\n [themeColor]=\"getStatusColor()\"\n [size]=\"'small'\">\n {{ Action.Status }}\n </kendo-chip>\n @if (Action.Type === 'Generated') {\n <kendo-chip themeColor=\"info\" [size]=\"'small'\">\n <i class=\"fa-solid fa-robot\"></i> AI\n </kendo-chip>\n }\n </div>\n </div>\n\n <p class=\"action-description\" [title]=\"Action.Description || 'No description'\">\n {{ Action.Description || 'No description available' }}\n </p>\n\n <div class=\"action-meta\">\n <button class=\"meta-item category\" (click)=\"onCategoryClick($event)\" [title]=\"'View category: ' + getCategoryName()\">\n <i class=\"fa-solid fa-folder\"></i>\n <span>{{ getCategoryName() }}</span>\n </button>\n\n @if (Action.__mj_UpdatedAt) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span>{{ formatDate(Action.__mj_UpdatedAt) }}</span>\n </span>\n }\n\n @if (Action.Type === 'Generated' && Action.CodeApprovalStatus) {\n <span class=\"meta-item\" [attr.data-status]=\"Action.CodeApprovalStatus\">\n <i [class]=\"getApprovalStatusIcon()\"></i>\n <span>{{ Action.CodeApprovalStatus }}</span>\n </span>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"action-buttons\">\n <button kendoButton\n [fillMode]=\"'flat'\"\n [size]=\"'small'\"\n title=\"View Stats\"\n (click)=\"toggleExpanded($event)\">\n <i [class]=\"IsExpanded ? 'fa-solid fa-chevron-up' : 'fa-solid fa-chart-line'\"></i>\n </button>\n <button kendoButton\n [fillMode]=\"'flat'\"\n [size]=\"'small'\"\n [themeColor]=\"'primary'\"\n title=\"Run Action\"\n [disabled]=\"Action.Status !== 'Active'\"\n (click)=\"onRunClick($event)\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n <button kendoButton\n [fillMode]=\"'flat'\"\n [size]=\"'small'\"\n title=\"Edit Action\"\n (click)=\"onEditClick($event)\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n </div>\n </div>\n\n <!-- Expanded Stats Section -->\n @if (IsExpanded) {\n <div class=\"card-expanded\">\n @if (ExecutionStats.isLoading) {\n <div class=\"stats-loading\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <span>Loading execution stats...</span>\n </div>\n } @else {\n <div class=\"stats-grid\">\n <div class=\"stat-item\">\n <div class=\"stat-value\">{{ ExecutionStats.totalExecutions }}</div>\n <div class=\"stat-label\">Total Runs</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value\" [class.success]=\"ExecutionStats.successRate >= 90\" [class.warning]=\"ExecutionStats.successRate >= 50 && ExecutionStats.successRate < 90\" [class.error]=\"ExecutionStats.successRate < 50\">\n {{ ExecutionStats.successRate }}%\n </div>\n <div class=\"stat-label\">Success Rate</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value\">{{ formatDate(ExecutionStats.lastExecuted) }}</div>\n <div class=\"stat-label\">Last Run</div>\n </div>\n <div class=\"stat-item params\">\n <div class=\"stat-value\">{{ Action.Params.length || 0 }}</div>\n <div class=\"stat-label\">Parameters</div>\n </div>\n </div>\n\n @if (Action.Params && Action.Params.length > 0) {\n <div class=\"params-preview\">\n <div class=\"params-header\">\n <i class=\"fa-solid fa-sliders\"></i>\n Parameters\n </div>\n <div class=\"params-list\">\n @for (param of Action.Params.slice(0, 4); track param.Name) {\n <span class=\"param-tag\" [class.required]=\"param.IsRequired\">\n {{ param.Name }}\n @if (param.IsRequired) {\n <span class=\"required-marker\">*</span>\n }\n </span>\n }\n @if (Action.Params.length > 4) {\n <span class=\"param-more\">+{{ Action.Params.length - 4 }} more</span>\n }\n </div>\n </div>\n }\n }\n </div>\n }\n</div>\n", styles: [".action-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.action-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\n\n.action-card.expanded {\n border-color: var(--mj-brand-primary);\n}\n\n.card-main {\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n}\n\n/* Icon */\n.action-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n flex-shrink: 0;\n}\n\n.action-icon i {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.action-icon.ai-generated {\n background: linear-gradient(135deg, color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface)), color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)));\n}\n\n.action-icon.ai-generated i {\n background: linear-gradient(135deg, var(--mj-status-info), var(--mj-brand-primary));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n}\n\n/* Content */\n.action-content {\n flex: 1;\n min-width: 0;\n}\n\n.action-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.action-name {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.action-badges {\n display: flex;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.action-badges kendo-chip:has(i) {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.action-badges kendo-chip i {\n font-size: 10px;\n}\n\n.action-description {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.action-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n background: none;\n border: none;\n padding: 0;\n cursor: default;\n}\n\n.meta-item.category {\n cursor: pointer;\n padding: 2px 6px;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.meta-item.category:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-brand-primary);\n}\n\n.meta-item i {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.meta-item[data-status=\"Approved\"] i {\n color: var(--mj-status-success);\n}\n\n.meta-item[data-status=\"Pending\"] i {\n color: var(--mj-status-warning);\n}\n\n.meta-item[data-status=\"Rejected\"] i {\n color: var(--mj-status-error);\n}\n\n/* Action Buttons */\n.action-buttons {\n display: flex;\n flex-direction: column;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.action-card:hover .action-buttons {\n opacity: 1;\n}\n\n.action-buttons button {\n padding: 6px;\n}\n\n/* Expanded Section */\n.card-expanded {\n padding: 0 20px 20px 20px;\n border-top: 1px solid var(--mj-border-default);\n margin-top: -1px;\n padding-top: 16px;\n background: var(--mj-bg-page);\n}\n\n.stats-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 20px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n margin-bottom: 16px;\n}\n\n.stat-item {\n text-align: center;\n padding: 12px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n}\n\n.stat-value {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.stat-value.success {\n color: var(--mj-status-success);\n}\n\n.stat-value.warning {\n color: var(--mj-status-warning);\n}\n\n.stat-value.error {\n color: var(--mj-status-error);\n}\n\n.stat-label {\n font-size: 11px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Params Preview */\n.params-preview {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n}\n\n.params-header {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.params-header i {\n font-size: 12px;\n}\n\n.params-list {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.param-tag {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 14px;\n font-size: 12px;\n color: var(--mj-text-primary);\n}\n\n.param-tag.required {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.required-marker {\n color: var(--mj-status-error);\n font-weight: 600;\n}\n\n.param-more {\n padding: 4px 10px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* Responsive */\n@media (max-width: 640px) {\n .card-main {\n flex-wrap: wrap;\n }\n\n .action-icon {\n width: 40px;\n height: 40px;\n }\n\n .action-icon i {\n font-size: 16px;\n }\n\n .action-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .action-buttons {\n flex-direction: row;\n opacity: 1;\n width: 100%;\n justify-content: flex-end;\n }\n\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n"] }]
|
|
390
|
+
args: [{ standalone: false, selector: 'mj-action-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"action-card\" [class.expanded]=\"IsExpanded\" (click)=\"onCardClick()\">\n <div class=\"card-main\">\n <!-- Icon -->\n <div class=\"action-icon\" [class.ai-generated]=\"Action.Type === 'Generated'\">\n <i [class]=\"getActionIcon()\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"action-content\">\n <div class=\"action-header\">\n <h3 class=\"action-name\" [title]=\"Action.Name\">{{ Action.Name }}</h3>\n <div class=\"action-badges\">\n <span class=\"status-chip\" [attr.data-color]=\"getStatusColor()\">\n {{ Action.Status }}\n </span>\n @if (Action.Type === 'Generated') {\n <span class=\"status-chip\" data-color=\"info\">\n <i class=\"fa-solid fa-robot\"></i> AI\n </span>\n }\n </div>\n </div>\n\n <p class=\"action-description\" [title]=\"Action.Description || 'No description'\">\n {{ Action.Description || 'No description available' }}\n </p>\n\n <div class=\"action-meta\">\n <button class=\"meta-item category\" (click)=\"onCategoryClick($event)\" [title]=\"'View category: ' + getCategoryName()\">\n <i class=\"fa-solid fa-folder\"></i>\n <span>{{ getCategoryName() }}</span>\n </button>\n\n @if (Action.__mj_UpdatedAt) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span>{{ formatDate(Action.__mj_UpdatedAt) }}</span>\n </span>\n }\n\n @if (Action.Type === 'Generated' && Action.CodeApprovalStatus) {\n <span class=\"meta-item\" [attr.data-status]=\"Action.CodeApprovalStatus\">\n <i [class]=\"getApprovalStatusIcon()\"></i>\n <span>{{ Action.CodeApprovalStatus }}</span>\n </span>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"action-buttons\">\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n title=\"View Stats\"\n (click)=\"toggleExpanded($event)\">\n <i [class]=\"IsExpanded ? 'fa-solid fa-chevron-up' : 'fa-solid fa-chart-line'\"></i>\n </button>\n <button mjButton\n variant=\"primary\"\n size=\"sm\"\n title=\"Run Action\"\n [disabled]=\"Action.Status !== 'Active'\"\n (click)=\"onRunClick($event)\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n title=\"Edit Action\"\n (click)=\"onEditClick($event)\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n </div>\n </div>\n\n <!-- Expanded Stats Section -->\n @if (IsExpanded) {\n <div class=\"card-expanded\">\n @if (ExecutionStats.isLoading) {\n <div class=\"stats-loading\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <span>Loading execution stats...</span>\n </div>\n } @else {\n <div class=\"stats-grid\">\n <div class=\"stat-item\">\n <div class=\"stat-value\">{{ ExecutionStats.totalExecutions }}</div>\n <div class=\"stat-label\">Total Runs</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value\" [class.success]=\"ExecutionStats.successRate >= 90\" [class.warning]=\"ExecutionStats.successRate >= 50 && ExecutionStats.successRate < 90\" [class.error]=\"ExecutionStats.successRate < 50\">\n {{ ExecutionStats.successRate }}%\n </div>\n <div class=\"stat-label\">Success Rate</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value\">{{ formatDate(ExecutionStats.lastExecuted) }}</div>\n <div class=\"stat-label\">Last Run</div>\n </div>\n <div class=\"stat-item params\">\n <div class=\"stat-value\">{{ Action.Params.length || 0 }}</div>\n <div class=\"stat-label\">Parameters</div>\n </div>\n </div>\n\n @if (Action.Params && Action.Params.length > 0) {\n <div class=\"params-preview\">\n <div class=\"params-header\">\n <i class=\"fa-solid fa-sliders\"></i>\n Parameters\n </div>\n <div class=\"params-list\">\n @for (param of Action.Params.slice(0, 4); track param.Name) {\n <span class=\"param-tag\" [class.required]=\"param.IsRequired\">\n {{ param.Name }}\n @if (param.IsRequired) {\n <span class=\"required-marker\">*</span>\n }\n </span>\n }\n @if (Action.Params.length > 4) {\n <span class=\"param-more\">+{{ Action.Params.length - 4 }} more</span>\n }\n </div>\n </div>\n }\n }\n </div>\n }\n</div>\n", styles: [".action-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.action-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\n\n.action-card.expanded {\n border-color: var(--mj-brand-primary);\n}\n\n.card-main {\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n}\n\n/* Icon */\n.action-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n flex-shrink: 0;\n}\n\n.action-icon i {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.action-icon.ai-generated {\n background: linear-gradient(135deg, color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface)), color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)));\n}\n\n.action-icon.ai-generated i {\n background: linear-gradient(135deg, var(--mj-status-info), var(--mj-brand-primary));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n}\n\n/* Content */\n.action-content {\n flex: 1;\n min-width: 0;\n}\n\n.action-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.action-name {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.action-badges {\n display: flex;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.action-description {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.action-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n background: none;\n border: none;\n padding: 0;\n cursor: default;\n}\n\n.meta-item.category {\n cursor: pointer;\n padding: 2px 6px;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.meta-item.category:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-brand-primary);\n}\n\n.meta-item i {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.meta-item[data-status=\"Approved\"] i {\n color: var(--mj-status-success);\n}\n\n.meta-item[data-status=\"Pending\"] i {\n color: var(--mj-status-warning);\n}\n\n.meta-item[data-status=\"Rejected\"] i {\n color: var(--mj-status-error);\n}\n\n/* Action Buttons */\n.action-buttons {\n display: flex;\n flex-direction: column;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.action-card:hover .action-buttons {\n opacity: 1;\n}\n\n.action-buttons button {\n padding: 6px;\n}\n\n/* Expanded Section */\n.card-expanded {\n padding: 0 20px 20px 20px;\n border-top: 1px solid var(--mj-border-default);\n margin-top: -1px;\n padding-top: 16px;\n background: var(--mj-bg-page);\n}\n\n.stats-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 20px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n margin-bottom: 16px;\n}\n\n.stat-item {\n text-align: center;\n padding: 12px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n}\n\n.stat-value {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.stat-value.success {\n color: var(--mj-status-success);\n}\n\n.stat-value.warning {\n color: var(--mj-status-warning);\n}\n\n.stat-value.error {\n color: var(--mj-status-error);\n}\n\n.stat-label {\n font-size: 11px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Params Preview */\n.params-preview {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n}\n\n.params-header {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.params-header i {\n font-size: 12px;\n}\n\n.params-list {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.param-tag {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 14px;\n font-size: 12px;\n color: var(--mj-text-primary);\n}\n\n.param-tag.required {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.required-marker {\n color: var(--mj-status-error);\n font-weight: 600;\n}\n\n.param-more {\n padding: 4px 10px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* Responsive */\n@media (max-width: 640px) {\n .card-main {\n flex-wrap: wrap;\n }\n\n .action-icon {\n width: 40px;\n height: 40px;\n }\n\n .action-icon i {\n font-size: 16px;\n }\n\n .action-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .action-buttons {\n flex-direction: row;\n opacity: 1;\n width: 100%;\n justify-content: flex-end;\n }\n\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n"] }]
|
|
397
391
|
}], () => [{ type: i0.ChangeDetectorRef }], { Action: [{
|
|
398
392
|
type: Input
|
|
399
393
|
}], Categories: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-card.component.js","sourceRoot":"","sources":["../../../../src/Actions/components/explorer/action-card.component.ts","../../../../src/Actions/components/explorer/action-card.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n ChangeDetectorRef\n} from '@angular/core';\nimport { MJActionCategoryEntity, MJActionExecutionLogEntity } from '@memberjunction/core-entities';\nimport { MJActionEntityExtended } from '@memberjunction/actions-base';\nimport { RunView } from '@memberjunction/core';\n\nexport interface ActionExecutionStats {\n totalExecutions: number;\n successRate: number;\n lastExecuted: Date | null;\n isLoading: boolean;\n isLoaded: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-action-card',\n templateUrl: './action-card.component.html',\n styleUrls: ['./action-card.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ActionCardComponent {\n @Input() Action!: MJActionEntityExtended;\n @Input() Categories: Map<string, MJActionCategoryEntity> = new Map();\n @Output() ActionClick = new EventEmitter<MJActionEntityExtended>();\n @Output() EditClick = new EventEmitter<MJActionEntityExtended>();\n @Output() RunClick = new EventEmitter<MJActionEntityExtended>();\n @Output() CategoryClick = new EventEmitter<string>();\n\n public IsExpanded = false;\n public ExecutionStats: ActionExecutionStats = {\n totalExecutions: 0,\n successRate: 0,\n lastExecuted: null,\n isLoading: false,\n isLoaded: false\n };\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n public onCardClick(): void {\n this.ActionClick.emit(this.Action);\n }\n\n public onEditClick(event: MouseEvent): void {\n event.stopPropagation();\n this.EditClick.emit(this.Action);\n }\n\n public onRunClick(event: MouseEvent): void {\n event.stopPropagation();\n this.RunClick.emit(this.Action);\n }\n\n public onCategoryClick(event: MouseEvent): void {\n event.stopPropagation();\n if (this.Action.CategoryID) {\n this.CategoryClick.emit(this.Action.CategoryID);\n }\n }\n\n public toggleExpanded(event: MouseEvent): void {\n event.stopPropagation();\n this.IsExpanded = !this.IsExpanded;\n\n if (this.IsExpanded && !this.ExecutionStats.isLoaded && !this.ExecutionStats.isLoading) {\n this.loadExecutionStats();\n }\n }\n\n private async loadExecutionStats(): Promise<void> {\n this.ExecutionStats.isLoading = true;\n this.cdr.markForCheck();\n\n try {\n const rv = new RunView();\n\n // Load both executions and result codes in parallel\n const [executionsResult, resultCodesResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Action Execution Logs',\n ExtraFilter: `ActionID='${this.Action.ID}'`,\n OrderBy: 'StartedAt DESC',\n MaxRows: 100,\n ResultType: 'simple',\n Fields: ['ID', 'ResultCode', 'StartedAt']\n },\n {\n EntityName: 'MJ: Action Result Codes',\n ExtraFilter: `ActionID='${this.Action.ID}'`,\n ResultType: 'simple',\n Fields: ['ResultCode', 'IsSuccess']\n }\n ]);\n\n if (executionsResult.Success && executionsResult.Results) {\n const executions = executionsResult.Results as { ID: string; ResultCode: string; StartedAt: Date }[];\n\n // Build a map of result codes to IsSuccess\n const successMap = new Map<string, boolean>();\n if (resultCodesResult.Success && resultCodesResult.Results) {\n const resultCodes = resultCodesResult.Results as { ResultCode: string; IsSuccess: boolean }[];\n resultCodes.forEach(rc => {\n successMap.set(rc.ResultCode, rc.IsSuccess);\n });\n }\n\n // Count successful executions using result code lookup\n const successful = executions.filter(e => {\n if (!e.ResultCode) return false;\n // Look up the result code in the map\n const isSuccess = successMap.get(e.ResultCode);\n // If result code is defined in the map, use it; otherwise fall back to heuristic\n if (isSuccess !== undefined) {\n return isSuccess;\n }\n // Fallback heuristic for unknown result codes\n const code = e.ResultCode.toLowerCase();\n return code === 'success' || code === 'ok' || code === 'completed';\n }).length;\n\n this.ExecutionStats = {\n totalExecutions: executions.length,\n successRate: executions.length > 0 ? Math.round((successful / executions.length) * 100) : 0,\n lastExecuted: executions.length > 0 ? new Date(executions[0].StartedAt) : null,\n isLoading: false,\n isLoaded: true\n };\n } else {\n this.ExecutionStats.isLoading = false;\n this.ExecutionStats.isLoaded = true;\n }\n } catch (error) {\n console.error('Failed to load execution stats:', error);\n this.ExecutionStats.isLoading = false;\n this.ExecutionStats.isLoaded = true;\n }\n\n this.cdr.markForCheck();\n }\n\n public getCategoryName(): string {\n if (!this.Action.CategoryID) return 'Uncategorized';\n return this.Categories.get(this.Action.CategoryID)?.Name || 'Unknown Category';\n }\n\n public getStatusColor(): 'success' | 'warning' | 'error' | 'info' {\n switch (this.Action.Status) {\n case 'Active': return 'success';\n case 'Pending': return 'warning';\n case 'Disabled': return 'error';\n default: return 'info';\n }\n }\n\n public getActionIcon(): string {\n // Use custom icon if set, otherwise derive from type\n if (this.Action.IconClass) {\n return this.Action.IconClass;\n }\n switch (this.Action.Type) {\n case 'Generated': return 'fa-solid fa-robot';\n case 'Custom': return 'fa-solid fa-code';\n default: return 'fa-solid fa-bolt';\n }\n }\n\n public getTypeLabel(): string {\n return this.Action.Type === 'Generated' ? 'AI Generated' : 'Custom';\n }\n\n public getApprovalStatusIcon(): string {\n switch (this.Action.CodeApprovalStatus) {\n case 'Approved': return 'fa-solid fa-check-circle';\n case 'Pending': return 'fa-solid fa-clock';\n case 'Rejected': return 'fa-solid fa-times-circle';\n default: return 'fa-solid fa-question-circle';\n }\n }\n\n public getApprovalStatusColor(): string {\n switch (this.Action.CodeApprovalStatus) {\n case 'Approved': return 'success';\n case 'Pending': return 'warning';\n case 'Rejected': return 'error';\n default: return 'info';\n }\n }\n\n public formatDate(date: Date | null): string {\n if (!date) return 'Never';\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n const minutes = Math.floor(diff / 60000);\n const hours = Math.floor(diff / 3600000);\n const days = Math.floor(diff / 86400000);\n\n if (minutes < 1) return 'Just now';\n if (minutes < 60) return `${minutes}m ago`;\n if (hours < 24) return `${hours}h ago`;\n if (days < 7) return `${days}d ago`;\n return date.toLocaleDateString();\n }\n}\n","<div class=\"action-card\" [class.expanded]=\"IsExpanded\" (click)=\"onCardClick()\">\n <div class=\"card-main\">\n <!-- Icon -->\n <div class=\"action-icon\" [class.ai-generated]=\"Action.Type === 'Generated'\">\n <i [class]=\"getActionIcon()\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"action-content\">\n <div class=\"action-header\">\n <h3 class=\"action-name\" [title]=\"Action.Name\">{{ Action.Name }}</h3>\n <div class=\"action-badges\">\n <kendo-chip\n [themeColor]=\"getStatusColor()\"\n [size]=\"'small'\">\n {{ Action.Status }}\n </kendo-chip>\n @if (Action.Type === 'Generated') {\n <kendo-chip themeColor=\"info\" [size]=\"'small'\">\n <i class=\"fa-solid fa-robot\"></i> AI\n </kendo-chip>\n }\n </div>\n </div>\n\n <p class=\"action-description\" [title]=\"Action.Description || 'No description'\">\n {{ Action.Description || 'No description available' }}\n </p>\n\n <div class=\"action-meta\">\n <button class=\"meta-item category\" (click)=\"onCategoryClick($event)\" [title]=\"'View category: ' + getCategoryName()\">\n <i class=\"fa-solid fa-folder\"></i>\n <span>{{ getCategoryName() }}</span>\n </button>\n\n @if (Action.__mj_UpdatedAt) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span>{{ formatDate(Action.__mj_UpdatedAt) }}</span>\n </span>\n }\n\n @if (Action.Type === 'Generated' && Action.CodeApprovalStatus) {\n <span class=\"meta-item\" [attr.data-status]=\"Action.CodeApprovalStatus\">\n <i [class]=\"getApprovalStatusIcon()\"></i>\n <span>{{ Action.CodeApprovalStatus }}</span>\n </span>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"action-buttons\">\n <button kendoButton\n [fillMode]=\"'flat'\"\n [size]=\"'small'\"\n title=\"View Stats\"\n (click)=\"toggleExpanded($event)\">\n <i [class]=\"IsExpanded ? 'fa-solid fa-chevron-up' : 'fa-solid fa-chart-line'\"></i>\n </button>\n <button kendoButton\n [fillMode]=\"'flat'\"\n [size]=\"'small'\"\n [themeColor]=\"'primary'\"\n title=\"Run Action\"\n [disabled]=\"Action.Status !== 'Active'\"\n (click)=\"onRunClick($event)\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n <button kendoButton\n [fillMode]=\"'flat'\"\n [size]=\"'small'\"\n title=\"Edit Action\"\n (click)=\"onEditClick($event)\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n </div>\n </div>\n\n <!-- Expanded Stats Section -->\n @if (IsExpanded) {\n <div class=\"card-expanded\">\n @if (ExecutionStats.isLoading) {\n <div class=\"stats-loading\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <span>Loading execution stats...</span>\n </div>\n } @else {\n <div class=\"stats-grid\">\n <div class=\"stat-item\">\n <div class=\"stat-value\">{{ ExecutionStats.totalExecutions }}</div>\n <div class=\"stat-label\">Total Runs</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value\" [class.success]=\"ExecutionStats.successRate >= 90\" [class.warning]=\"ExecutionStats.successRate >= 50 && ExecutionStats.successRate < 90\" [class.error]=\"ExecutionStats.successRate < 50\">\n {{ ExecutionStats.successRate }}%\n </div>\n <div class=\"stat-label\">Success Rate</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value\">{{ formatDate(ExecutionStats.lastExecuted) }}</div>\n <div class=\"stat-label\">Last Run</div>\n </div>\n <div class=\"stat-item params\">\n <div class=\"stat-value\">{{ Action.Params.length || 0 }}</div>\n <div class=\"stat-label\">Parameters</div>\n </div>\n </div>\n\n @if (Action.Params && Action.Params.length > 0) {\n <div class=\"params-preview\">\n <div class=\"params-header\">\n <i class=\"fa-solid fa-sliders\"></i>\n Parameters\n </div>\n <div class=\"params-list\">\n @for (param of Action.Params.slice(0, 4); track param.Name) {\n <span class=\"param-tag\" [class.required]=\"param.IsRequired\">\n {{ param.Name }}\n @if (param.IsRequired) {\n <span class=\"required-marker\">*</span>\n }\n </span>\n }\n @if (Action.Params.length > 4) {\n <span class=\"param-more\">+{{ Action.Params.length - 4 }} more</span>\n }\n </div>\n </div>\n }\n }\n </div>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"action-card.component.js","sourceRoot":"","sources":["../../../../src/Actions/components/explorer/action-card.component.ts","../../../../src/Actions/components/explorer/action-card.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n ChangeDetectorRef\n} from '@angular/core';\nimport { MJActionCategoryEntity, MJActionExecutionLogEntity } from '@memberjunction/core-entities';\nimport { MJActionEntityExtended } from '@memberjunction/actions-base';\nimport { RunView } from '@memberjunction/core';\n\nexport interface ActionExecutionStats {\n totalExecutions: number;\n successRate: number;\n lastExecuted: Date | null;\n isLoading: boolean;\n isLoaded: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-action-card',\n templateUrl: './action-card.component.html',\n styleUrls: ['./action-card.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ActionCardComponent {\n @Input() Action!: MJActionEntityExtended;\n @Input() Categories: Map<string, MJActionCategoryEntity> = new Map();\n @Output() ActionClick = new EventEmitter<MJActionEntityExtended>();\n @Output() EditClick = new EventEmitter<MJActionEntityExtended>();\n @Output() RunClick = new EventEmitter<MJActionEntityExtended>();\n @Output() CategoryClick = new EventEmitter<string>();\n\n public IsExpanded = false;\n public ExecutionStats: ActionExecutionStats = {\n totalExecutions: 0,\n successRate: 0,\n lastExecuted: null,\n isLoading: false,\n isLoaded: false\n };\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n public onCardClick(): void {\n this.ActionClick.emit(this.Action);\n }\n\n public onEditClick(event: MouseEvent): void {\n event.stopPropagation();\n this.EditClick.emit(this.Action);\n }\n\n public onRunClick(event: MouseEvent): void {\n event.stopPropagation();\n this.RunClick.emit(this.Action);\n }\n\n public onCategoryClick(event: MouseEvent): void {\n event.stopPropagation();\n if (this.Action.CategoryID) {\n this.CategoryClick.emit(this.Action.CategoryID);\n }\n }\n\n public toggleExpanded(event: MouseEvent): void {\n event.stopPropagation();\n this.IsExpanded = !this.IsExpanded;\n\n if (this.IsExpanded && !this.ExecutionStats.isLoaded && !this.ExecutionStats.isLoading) {\n this.loadExecutionStats();\n }\n }\n\n private async loadExecutionStats(): Promise<void> {\n this.ExecutionStats.isLoading = true;\n this.cdr.markForCheck();\n\n try {\n const rv = new RunView();\n\n // Load both executions and result codes in parallel\n const [executionsResult, resultCodesResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Action Execution Logs',\n ExtraFilter: `ActionID='${this.Action.ID}'`,\n OrderBy: 'StartedAt DESC',\n MaxRows: 100,\n ResultType: 'simple',\n Fields: ['ID', 'ResultCode', 'StartedAt']\n },\n {\n EntityName: 'MJ: Action Result Codes',\n ExtraFilter: `ActionID='${this.Action.ID}'`,\n ResultType: 'simple',\n Fields: ['ResultCode', 'IsSuccess']\n }\n ]);\n\n if (executionsResult.Success && executionsResult.Results) {\n const executions = executionsResult.Results as { ID: string; ResultCode: string; StartedAt: Date }[];\n\n // Build a map of result codes to IsSuccess\n const successMap = new Map<string, boolean>();\n if (resultCodesResult.Success && resultCodesResult.Results) {\n const resultCodes = resultCodesResult.Results as { ResultCode: string; IsSuccess: boolean }[];\n resultCodes.forEach(rc => {\n successMap.set(rc.ResultCode, rc.IsSuccess);\n });\n }\n\n // Count successful executions using result code lookup\n const successful = executions.filter(e => {\n if (!e.ResultCode) return false;\n // Look up the result code in the map\n const isSuccess = successMap.get(e.ResultCode);\n // If result code is defined in the map, use it; otherwise fall back to heuristic\n if (isSuccess !== undefined) {\n return isSuccess;\n }\n // Fallback heuristic for unknown result codes\n const code = e.ResultCode.toLowerCase();\n return code === 'success' || code === 'ok' || code === 'completed';\n }).length;\n\n this.ExecutionStats = {\n totalExecutions: executions.length,\n successRate: executions.length > 0 ? Math.round((successful / executions.length) * 100) : 0,\n lastExecuted: executions.length > 0 ? new Date(executions[0].StartedAt) : null,\n isLoading: false,\n isLoaded: true\n };\n } else {\n this.ExecutionStats.isLoading = false;\n this.ExecutionStats.isLoaded = true;\n }\n } catch (error) {\n console.error('Failed to load execution stats:', error);\n this.ExecutionStats.isLoading = false;\n this.ExecutionStats.isLoaded = true;\n }\n\n this.cdr.markForCheck();\n }\n\n public getCategoryName(): string {\n if (!this.Action.CategoryID) return 'Uncategorized';\n return this.Categories.get(this.Action.CategoryID)?.Name || 'Unknown Category';\n }\n\n public getStatusColor(): 'success' | 'warning' | 'error' | 'info' {\n switch (this.Action.Status) {\n case 'Active': return 'success';\n case 'Pending': return 'warning';\n case 'Disabled': return 'error';\n default: return 'info';\n }\n }\n\n public getActionIcon(): string {\n // Use custom icon if set, otherwise derive from type\n if (this.Action.IconClass) {\n return this.Action.IconClass;\n }\n switch (this.Action.Type) {\n case 'Generated': return 'fa-solid fa-robot';\n case 'Custom': return 'fa-solid fa-code';\n default: return 'fa-solid fa-bolt';\n }\n }\n\n public getTypeLabel(): string {\n return this.Action.Type === 'Generated' ? 'AI Generated' : 'Custom';\n }\n\n public getApprovalStatusIcon(): string {\n switch (this.Action.CodeApprovalStatus) {\n case 'Approved': return 'fa-solid fa-check-circle';\n case 'Pending': return 'fa-solid fa-clock';\n case 'Rejected': return 'fa-solid fa-times-circle';\n default: return 'fa-solid fa-question-circle';\n }\n }\n\n public getApprovalStatusColor(): string {\n switch (this.Action.CodeApprovalStatus) {\n case 'Approved': return 'success';\n case 'Pending': return 'warning';\n case 'Rejected': return 'error';\n default: return 'info';\n }\n }\n\n public formatDate(date: Date | null): string {\n if (!date) return 'Never';\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n const minutes = Math.floor(diff / 60000);\n const hours = Math.floor(diff / 3600000);\n const days = Math.floor(diff / 86400000);\n\n if (minutes < 1) return 'Just now';\n if (minutes < 60) return `${minutes}m ago`;\n if (hours < 24) return `${hours}h ago`;\n if (days < 7) return `${days}d ago`;\n return date.toLocaleDateString();\n }\n}\n","<div class=\"action-card\" [class.expanded]=\"IsExpanded\" (click)=\"onCardClick()\">\n <div class=\"card-main\">\n <!-- Icon -->\n <div class=\"action-icon\" [class.ai-generated]=\"Action.Type === 'Generated'\">\n <i [class]=\"getActionIcon()\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"action-content\">\n <div class=\"action-header\">\n <h3 class=\"action-name\" [title]=\"Action.Name\">{{ Action.Name }}</h3>\n <div class=\"action-badges\">\n <span class=\"status-chip\" [attr.data-color]=\"getStatusColor()\">\n {{ Action.Status }}\n </span>\n @if (Action.Type === 'Generated') {\n <span class=\"status-chip\" data-color=\"info\">\n <i class=\"fa-solid fa-robot\"></i> AI\n </span>\n }\n </div>\n </div>\n\n <p class=\"action-description\" [title]=\"Action.Description || 'No description'\">\n {{ Action.Description || 'No description available' }}\n </p>\n\n <div class=\"action-meta\">\n <button class=\"meta-item category\" (click)=\"onCategoryClick($event)\" [title]=\"'View category: ' + getCategoryName()\">\n <i class=\"fa-solid fa-folder\"></i>\n <span>{{ getCategoryName() }}</span>\n </button>\n\n @if (Action.__mj_UpdatedAt) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span>{{ formatDate(Action.__mj_UpdatedAt) }}</span>\n </span>\n }\n\n @if (Action.Type === 'Generated' && Action.CodeApprovalStatus) {\n <span class=\"meta-item\" [attr.data-status]=\"Action.CodeApprovalStatus\">\n <i [class]=\"getApprovalStatusIcon()\"></i>\n <span>{{ Action.CodeApprovalStatus }}</span>\n </span>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"action-buttons\">\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n title=\"View Stats\"\n (click)=\"toggleExpanded($event)\">\n <i [class]=\"IsExpanded ? 'fa-solid fa-chevron-up' : 'fa-solid fa-chart-line'\"></i>\n </button>\n <button mjButton\n variant=\"primary\"\n size=\"sm\"\n title=\"Run Action\"\n [disabled]=\"Action.Status !== 'Active'\"\n (click)=\"onRunClick($event)\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n title=\"Edit Action\"\n (click)=\"onEditClick($event)\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n </div>\n </div>\n\n <!-- Expanded Stats Section -->\n @if (IsExpanded) {\n <div class=\"card-expanded\">\n @if (ExecutionStats.isLoading) {\n <div class=\"stats-loading\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <span>Loading execution stats...</span>\n </div>\n } @else {\n <div class=\"stats-grid\">\n <div class=\"stat-item\">\n <div class=\"stat-value\">{{ ExecutionStats.totalExecutions }}</div>\n <div class=\"stat-label\">Total Runs</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value\" [class.success]=\"ExecutionStats.successRate >= 90\" [class.warning]=\"ExecutionStats.successRate >= 50 && ExecutionStats.successRate < 90\" [class.error]=\"ExecutionStats.successRate < 50\">\n {{ ExecutionStats.successRate }}%\n </div>\n <div class=\"stat-label\">Success Rate</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value\">{{ formatDate(ExecutionStats.lastExecuted) }}</div>\n <div class=\"stat-label\">Last Run</div>\n </div>\n <div class=\"stat-item params\">\n <div class=\"stat-value\">{{ Action.Params.length || 0 }}</div>\n <div class=\"stat-label\">Parameters</div>\n </div>\n </div>\n\n @if (Action.Params && Action.Params.length > 0) {\n <div class=\"params-preview\">\n <div class=\"params-header\">\n <i class=\"fa-solid fa-sliders\"></i>\n Parameters\n </div>\n <div class=\"params-list\">\n @for (param of Action.Params.slice(0, 4); track param.Name) {\n <span class=\"param-tag\" [class.required]=\"param.IsRequired\">\n {{ param.Name }}\n @if (param.IsRequired) {\n <span class=\"required-marker\">*</span>\n }\n </span>\n }\n @if (Action.Params.length > 4) {\n <span class=\"param-more\">+{{ Action.Params.length - 4 }} more</span>\n }\n </div>\n </div>\n }\n }\n </div>\n }\n</div>\n"]}
|