@memberjunction/ng-dashboards 2.47.0 → 2.49.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 +105 -2
- package/dist/AI/ai-dashboard.component.d.ts +2 -0
- package/dist/AI/ai-dashboard.component.d.ts.map +1 -1
- package/dist/AI/ai-dashboard.component.js +66 -43
- package/dist/AI/ai-dashboard.component.js.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +45 -58
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.d.ts +6 -1
- package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +368 -366
- package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.js +83 -85
- package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.d.ts +66 -0
- package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -0
- package/dist/AI/components/charts/performance-heatmap.component.js +428 -0
- package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -0
- package/dist/AI/components/charts/time-series-chart.component.d.ts +66 -0
- package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -0
- package/dist/AI/components/charts/time-series-chart.component.js +547 -0
- package/dist/AI/components/charts/time-series-chart.component.js.map +1 -0
- package/dist/AI/components/execution-monitoring.component.d.ts +157 -5
- package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +2032 -20
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +211 -237
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +208 -226
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-filter-panel.component.js +97 -99
- package/dist/AI/components/prompts/prompt-filter-panel.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +381 -424
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +173 -191
- package/dist/AI/components/prompts/prompt-version-control.component.js.map +1 -1
- package/dist/AI/components/system/system-config-filter-panel.component.js +85 -87
- package/dist/AI/components/system/system-config-filter-panel.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +86 -99
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/widgets/kpi-card.component.d.ts +25 -0
- package/dist/AI/components/widgets/kpi-card.component.d.ts.map +1 -0
- package/dist/AI/components/widgets/kpi-card.component.js +163 -0
- package/dist/AI/components/widgets/kpi-card.component.js.map +1 -0
- package/dist/AI/components/widgets/live-execution-widget.component.d.ts +25 -0
- package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -0
- package/dist/AI/components/widgets/live-execution-widget.component.js +298 -0
- package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -0
- package/dist/AI/index.d.ts +7 -0
- package/dist/AI/index.d.ts.map +1 -0
- package/dist/AI/index.js +9 -0
- package/dist/AI/index.js.map +1 -0
- package/dist/AI/services/ai-instrumentation.service.d.ts +109 -0
- package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -0
- package/dist/AI/services/ai-instrumentation.service.js +490 -0
- package/dist/AI/services/ai-instrumentation.service.js.map +1 -0
- package/dist/Actions/actions-management-dashboard.component.js +40 -41
- package/dist/Actions/actions-management-dashboard.component.js.map +1 -1
- package/dist/Actions/components/actions-list-view.component.js +117 -134
- package/dist/Actions/components/actions-list-view.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +274 -296
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +12 -14
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/Actions/components/code-management.component.js +12 -14
- package/dist/Actions/components/code-management.component.js.map +1 -1
- package/dist/Actions/components/entity-integration.component.js +12 -14
- package/dist/Actions/components/entity-integration.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +238 -256
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/executions-list-view.component.js +12 -14
- package/dist/Actions/components/executions-list-view.component.js.map +1 -1
- package/dist/Actions/components/scheduled-actions.component.js +12 -14
- package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
- package/dist/Actions/components/security-permissions.component.js +12 -14
- package/dist/Actions/components/security-permissions.component.js.map +1 -1
- package/dist/EntityAdmin/components/entity-details.component.js +105 -107
- package/dist/EntityAdmin/components/entity-details.component.js.map +1 -1
- package/dist/EntityAdmin/components/entity-filter-panel.component.js +100 -102
- package/dist/EntityAdmin/components/entity-filter-panel.component.js.map +1 -1
- package/dist/EntityAdmin/components/erd-composite.component.js +84 -100
- package/dist/EntityAdmin/components/erd-composite.component.js.map +1 -1
- package/dist/EntityAdmin/components/erd-diagram.component.js +50 -50
- package/dist/EntityAdmin/components/erd-diagram.component.js.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +45 -49
- package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
- package/dist/generic/base-dashboard.js +28 -40
- package/dist/generic/base-dashboard.js.map +1 -1
- package/dist/module.d.ts +16 -12
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +36 -15
- package/dist/module.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { Component, Output, EventEmitter } from '@angular/core';
|
|
11
2
|
import { RunView, LogError } from '@memberjunction/core';
|
|
12
3
|
import { Subject, BehaviorSubject, combineLatest } from 'rxjs';
|
|
@@ -143,45 +134,44 @@ function ExecutionMonitoringComponent_Conditional_87_Template(rf, ctx) { if (rf
|
|
|
143
134
|
i0.ɵɵproperty("themeColor", "primary");
|
|
144
135
|
} }
|
|
145
136
|
export class ExecutionMonitoringComponent {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
137
|
+
openEntityRecord = new EventEmitter();
|
|
138
|
+
showExecutionsListView = new EventEmitter();
|
|
139
|
+
isLoading = true;
|
|
140
|
+
executions = [];
|
|
141
|
+
filteredExecutions = [];
|
|
142
|
+
actions = new Map();
|
|
143
|
+
metrics = {
|
|
144
|
+
totalExecutions: 0,
|
|
145
|
+
successfulExecutions: 0,
|
|
146
|
+
failedExecutions: 0,
|
|
147
|
+
averageDuration: 0,
|
|
148
|
+
executionsToday: 0,
|
|
149
|
+
executionsThisWeek: 0,
|
|
150
|
+
currentlyRunning: 0
|
|
151
|
+
};
|
|
152
|
+
executionTrends = [];
|
|
153
|
+
searchTerm$ = new BehaviorSubject('');
|
|
154
|
+
selectedResult$ = new BehaviorSubject('all');
|
|
155
|
+
selectedTimeRange$ = new BehaviorSubject('7days');
|
|
156
|
+
selectedAction$ = new BehaviorSubject('all');
|
|
157
|
+
timeRangeOptions = [
|
|
158
|
+
{ text: 'Last 24 Hours', value: '24hours' },
|
|
159
|
+
{ text: 'Last 7 Days', value: '7days' },
|
|
160
|
+
{ text: 'Last 30 Days', value: '30days' },
|
|
161
|
+
{ text: 'Last 90 Days', value: '90days' }
|
|
162
|
+
];
|
|
163
|
+
resultOptions = [
|
|
164
|
+
{ text: 'All Results', value: 'all' },
|
|
165
|
+
{ text: 'Success', value: 'Success' },
|
|
166
|
+
{ text: 'Failed', value: 'Failed' },
|
|
167
|
+
{ text: 'Error', value: 'Error' },
|
|
168
|
+
{ text: 'Running', value: 'Running' }
|
|
169
|
+
];
|
|
170
|
+
actionOptions = [
|
|
171
|
+
{ text: 'All Actions', value: 'all' }
|
|
172
|
+
];
|
|
173
|
+
destroy$ = new Subject();
|
|
174
|
+
constructor() { }
|
|
185
175
|
ngOnInit() {
|
|
186
176
|
this.setupFilters();
|
|
187
177
|
this.loadData();
|
|
@@ -200,66 +190,60 @@ export class ExecutionMonitoringComponent {
|
|
|
200
190
|
this.applyFilters();
|
|
201
191
|
});
|
|
202
192
|
}
|
|
203
|
-
loadData() {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
});
|
|
193
|
+
async loadData() {
|
|
194
|
+
try {
|
|
195
|
+
this.isLoading = true;
|
|
196
|
+
const [executions, actions] = await Promise.all([
|
|
197
|
+
this.loadExecutions(),
|
|
198
|
+
this.loadActions()
|
|
199
|
+
]);
|
|
200
|
+
this.executions = executions;
|
|
201
|
+
this.populateActionsMap(actions);
|
|
202
|
+
this.buildActionOptions(actions);
|
|
203
|
+
this.calculateMetrics();
|
|
204
|
+
this.generateExecutionTrends();
|
|
205
|
+
this.applyFilters();
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
LogError('Failed to load execution monitoring data', undefined, error);
|
|
209
|
+
}
|
|
210
|
+
finally {
|
|
211
|
+
this.isLoading = false;
|
|
212
|
+
}
|
|
225
213
|
}
|
|
226
|
-
loadExecutions() {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
MaxRows: 5000
|
|
236
|
-
});
|
|
237
|
-
if (result && result.Success && result.Results) {
|
|
238
|
-
return result.Results;
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
throw new Error('Failed to load action execution logs');
|
|
242
|
-
}
|
|
214
|
+
async loadExecutions() {
|
|
215
|
+
const rv = new RunView();
|
|
216
|
+
const result = await rv.RunView({
|
|
217
|
+
EntityName: 'Action Execution Logs',
|
|
218
|
+
ExtraFilter: '',
|
|
219
|
+
OrderBy: 'StartedAt DESC',
|
|
220
|
+
UserSearchString: '',
|
|
221
|
+
IgnoreMaxRows: false,
|
|
222
|
+
MaxRows: 5000
|
|
243
223
|
});
|
|
224
|
+
if (result && result.Success && result.Results) {
|
|
225
|
+
return result.Results;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
throw new Error('Failed to load action execution logs');
|
|
229
|
+
}
|
|
244
230
|
}
|
|
245
|
-
loadActions() {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
MaxRows: 1000
|
|
255
|
-
});
|
|
256
|
-
if (result && result.Success && result.Results) {
|
|
257
|
-
return result.Results;
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
260
|
-
throw new Error('Failed to load actions');
|
|
261
|
-
}
|
|
231
|
+
async loadActions() {
|
|
232
|
+
const rv = new RunView();
|
|
233
|
+
const result = await rv.RunView({
|
|
234
|
+
EntityName: 'Actions',
|
|
235
|
+
ExtraFilter: '',
|
|
236
|
+
OrderBy: 'Name',
|
|
237
|
+
UserSearchString: '',
|
|
238
|
+
IgnoreMaxRows: false,
|
|
239
|
+
MaxRows: 1000
|
|
262
240
|
});
|
|
241
|
+
if (result && result.Success && result.Results) {
|
|
242
|
+
return result.Results;
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
throw new Error('Failed to load actions');
|
|
246
|
+
}
|
|
263
247
|
}
|
|
264
248
|
populateActionsMap(actions) {
|
|
265
249
|
this.actions.clear();
|
|
@@ -362,11 +346,10 @@ export class ExecutionMonitoringComponent {
|
|
|
362
346
|
const searchTerm = this.searchTerm$.value.toLowerCase();
|
|
363
347
|
if (searchTerm) {
|
|
364
348
|
filtered = filtered.filter(e => {
|
|
365
|
-
var _a, _b;
|
|
366
349
|
const action = this.actions.get(e.ActionID);
|
|
367
|
-
return (
|
|
368
|
-
|
|
369
|
-
|
|
350
|
+
return (action?.Name.toLowerCase().includes(searchTerm) ||
|
|
351
|
+
e.ResultCode?.toLowerCase().includes(searchTerm) ||
|
|
352
|
+
e.UserID?.toLowerCase().includes(searchTerm));
|
|
370
353
|
});
|
|
371
354
|
}
|
|
372
355
|
this.filteredExecutions = filtered;
|
|
@@ -411,8 +394,7 @@ export class ExecutionMonitoringComponent {
|
|
|
411
394
|
});
|
|
412
395
|
}
|
|
413
396
|
getActionName(actionId) {
|
|
414
|
-
|
|
415
|
-
return ((_a = this.actions.get(actionId)) === null || _a === void 0 ? void 0 : _a.Name) || `Action ${actionId}`;
|
|
397
|
+
return this.actions.get(actionId)?.Name || `Action ${actionId}`;
|
|
416
398
|
}
|
|
417
399
|
getResultColor(resultCode) {
|
|
418
400
|
if (!resultCode)
|
|
@@ -470,153 +452,153 @@ export class ExecutionMonitoringComponent {
|
|
|
470
452
|
onRunningExecutionsClick() {
|
|
471
453
|
this.selectedResult$.next('Running');
|
|
472
454
|
}
|
|
455
|
+
static ɵfac = function ExecutionMonitoringComponent_Factory(t) { return new (t || ExecutionMonitoringComponent)(); };
|
|
456
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ExecutionMonitoringComponent, selectors: [["mj-execution-monitoring"]], outputs: { openEntityRecord: "openEntityRecord", showExecutionsListView: "showExecutionsListView" }, decls: 88, vars: 22, consts: [["mjFillContainer", "", 1, "execution-monitoring"], [1, "monitoring-header"], [1, "header-title"], [1, "fa-solid", "fa-chart-line"], ["kendoButton", "", 1, "refresh-btn", 3, "click", "primary", "icon"], [1, "filters-row"], [1, "search-container"], ["placeholder", "Search executions...", 3, "valueChange", "value"], ["kendoTextBoxPrefixTemplate", ""], [1, "filter-group"], ["textField", "text", "valueField", "value", 3, "valueChange", "data", "value"], [1, "metrics-summary"], [1, "metric-card", "total", "clickable", 3, "click"], [1, "metric-icon"], [1, "fa-solid", "fa-play-circle"], [1, "metric-content"], [1, "metric-value"], [1, "metric-label"], [1, "metric-card", "success", "clickable", 3, "click"], [1, "fa-solid", "fa-check-circle"], [1, "metric-detail"], [1, "metric-card", "error", "clickable", 3, "click"], [1, "fa-solid", "fa-exclamation-circle"], [1, "metric-card", "duration"], [1, "fa-solid", "fa-clock"], [1, "metric-card", "activity"], [1, "fa-solid", "fa-calendar-day"], [1, "metric-card", "running", "clickable", 3, "click"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "trends-section"], [1, "section-header"], [1, "fa-solid", "fa-chart-area"], [1, "trends-chart"], [1, "empty-chart"], [1, "executions-section"], [1, "fa-solid", "fa-list"], [1, "results-count"], [1, "executions-list"], [1, "empty-state"], [1, "loading-overlay"], [1, "fa-solid", "fa-search"], [1, "trend-bars"], [1, "trend-bar"], [1, "chart-legend"], [1, "legend-item"], [1, "legend-color", "success"], [1, "legend-color", "failed"], [1, "bar-container"], [1, "bar-success"], [1, "bar-failed"], [1, "bar-label"], [1, "bar-total"], [1, "execution-item"], [1, "execution-item", 3, "click"], [1, "execution-status"], [1, "execution-main"], [1, "execution-action", 3, "click"], [1, "execution-details"], [1, "execution-time"], [1, "execution-user"], [1, "execution-duration"], [1, "execution-result"], [3, "themeColor", "size"], [1, "execution-actions"], ["kendoButton", "", 3, "click", "fillMode", "icon"], ["type", "converging-spinner", 3, "themeColor"]], template: function ExecutionMonitoringComponent_Template(rf, ctx) { if (rf & 1) {
|
|
457
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "h3");
|
|
458
|
+
i0.ɵɵelement(4, "i", 3);
|
|
459
|
+
i0.ɵɵtext(5, " Execution Monitoring");
|
|
460
|
+
i0.ɵɵelementEnd();
|
|
461
|
+
i0.ɵɵelementStart(6, "button", 4);
|
|
462
|
+
i0.ɵɵlistener("click", function ExecutionMonitoringComponent_Template_button_click_6_listener() { return ctx.refreshData(); });
|
|
463
|
+
i0.ɵɵtext(7, " Refresh ");
|
|
464
|
+
i0.ɵɵelementEnd()();
|
|
465
|
+
i0.ɵɵelementStart(8, "div", 5)(9, "div", 6)(10, "kendo-textbox", 7);
|
|
466
|
+
i0.ɵɵlistener("valueChange", function ExecutionMonitoringComponent_Template_kendo_textbox_valueChange_10_listener($event) { return ctx.onSearchChange($event); });
|
|
467
|
+
i0.ɵɵtemplate(11, ExecutionMonitoringComponent_ng_template_11_Template, 1, 0, "ng-template", 8);
|
|
468
|
+
i0.ɵɵelementEnd()();
|
|
469
|
+
i0.ɵɵelementStart(12, "div", 9)(13, "kendo-dropdownlist", 10);
|
|
470
|
+
i0.ɵɵlistener("valueChange", function ExecutionMonitoringComponent_Template_kendo_dropdownlist_valueChange_13_listener($event) { return ctx.onTimeRangeChange($event); });
|
|
471
|
+
i0.ɵɵelementEnd();
|
|
472
|
+
i0.ɵɵelementStart(14, "kendo-dropdownlist", 10);
|
|
473
|
+
i0.ɵɵlistener("valueChange", function ExecutionMonitoringComponent_Template_kendo_dropdownlist_valueChange_14_listener($event) { return ctx.onResultFilterChange($event); });
|
|
474
|
+
i0.ɵɵelementEnd();
|
|
475
|
+
i0.ɵɵelementStart(15, "kendo-dropdownlist", 10);
|
|
476
|
+
i0.ɵɵlistener("valueChange", function ExecutionMonitoringComponent_Template_kendo_dropdownlist_valueChange_15_listener($event) { return ctx.onActionFilterChange($event); });
|
|
477
|
+
i0.ɵɵelementEnd()()()();
|
|
478
|
+
i0.ɵɵelementStart(16, "div", 11)(17, "div", 12);
|
|
479
|
+
i0.ɵɵlistener("click", function ExecutionMonitoringComponent_Template_div_click_17_listener() { return ctx.onTotalExecutionsClick(); });
|
|
480
|
+
i0.ɵɵelementStart(18, "div", 13);
|
|
481
|
+
i0.ɵɵelement(19, "i", 14);
|
|
482
|
+
i0.ɵɵelementEnd();
|
|
483
|
+
i0.ɵɵelementStart(20, "div", 15)(21, "div", 16);
|
|
484
|
+
i0.ɵɵtext(22);
|
|
485
|
+
i0.ɵɵelementEnd();
|
|
486
|
+
i0.ɵɵelementStart(23, "div", 17);
|
|
487
|
+
i0.ɵɵtext(24, "Total Executions");
|
|
488
|
+
i0.ɵɵelementEnd()()();
|
|
489
|
+
i0.ɵɵelementStart(25, "div", 18);
|
|
490
|
+
i0.ɵɵlistener("click", function ExecutionMonitoringComponent_Template_div_click_25_listener() { return ctx.onSuccessRateClick(); });
|
|
491
|
+
i0.ɵɵelementStart(26, "div", 13);
|
|
492
|
+
i0.ɵɵelement(27, "i", 19);
|
|
493
|
+
i0.ɵɵelementEnd();
|
|
494
|
+
i0.ɵɵelementStart(28, "div", 15)(29, "div", 16);
|
|
495
|
+
i0.ɵɵtext(30);
|
|
496
|
+
i0.ɵɵelementEnd();
|
|
497
|
+
i0.ɵɵelementStart(31, "div", 17);
|
|
498
|
+
i0.ɵɵtext(32, "Success Rate");
|
|
499
|
+
i0.ɵɵelementEnd();
|
|
500
|
+
i0.ɵɵelementStart(33, "div", 20);
|
|
501
|
+
i0.ɵɵtext(34);
|
|
502
|
+
i0.ɵɵelementEnd()()();
|
|
503
|
+
i0.ɵɵelementStart(35, "div", 21);
|
|
504
|
+
i0.ɵɵlistener("click", function ExecutionMonitoringComponent_Template_div_click_35_listener() { return ctx.onFailedExecutionsClick(); });
|
|
505
|
+
i0.ɵɵelementStart(36, "div", 13);
|
|
506
|
+
i0.ɵɵelement(37, "i", 22);
|
|
507
|
+
i0.ɵɵelementEnd();
|
|
508
|
+
i0.ɵɵelementStart(38, "div", 15)(39, "div", 16);
|
|
509
|
+
i0.ɵɵtext(40);
|
|
510
|
+
i0.ɵɵelementEnd();
|
|
511
|
+
i0.ɵɵelementStart(41, "div", 17);
|
|
512
|
+
i0.ɵɵtext(42, "Failed Executions");
|
|
513
|
+
i0.ɵɵelementEnd()()();
|
|
514
|
+
i0.ɵɵelementStart(43, "div", 23)(44, "div", 13);
|
|
515
|
+
i0.ɵɵelement(45, "i", 24);
|
|
516
|
+
i0.ɵɵelementEnd();
|
|
517
|
+
i0.ɵɵelementStart(46, "div", 15)(47, "div", 16);
|
|
518
|
+
i0.ɵɵtext(48);
|
|
519
|
+
i0.ɵɵelementEnd();
|
|
520
|
+
i0.ɵɵelementStart(49, "div", 17);
|
|
521
|
+
i0.ɵɵtext(50, "Avg Duration");
|
|
522
|
+
i0.ɵɵelementEnd()()();
|
|
523
|
+
i0.ɵɵelementStart(51, "div", 25)(52, "div", 13);
|
|
524
|
+
i0.ɵɵelement(53, "i", 26);
|
|
525
|
+
i0.ɵɵelementEnd();
|
|
526
|
+
i0.ɵɵelementStart(54, "div", 15)(55, "div", 16);
|
|
527
|
+
i0.ɵɵtext(56);
|
|
528
|
+
i0.ɵɵelementEnd();
|
|
529
|
+
i0.ɵɵelementStart(57, "div", 17);
|
|
530
|
+
i0.ɵɵtext(58, "Today");
|
|
531
|
+
i0.ɵɵelementEnd();
|
|
532
|
+
i0.ɵɵelementStart(59, "div", 20);
|
|
533
|
+
i0.ɵɵtext(60);
|
|
534
|
+
i0.ɵɵelementEnd()()();
|
|
535
|
+
i0.ɵɵelementStart(61, "div", 27);
|
|
536
|
+
i0.ɵɵlistener("click", function ExecutionMonitoringComponent_Template_div_click_61_listener() { return ctx.onRunningExecutionsClick(); });
|
|
537
|
+
i0.ɵɵelementStart(62, "div", 13);
|
|
538
|
+
i0.ɵɵelement(63, "i", 28);
|
|
539
|
+
i0.ɵɵelementEnd();
|
|
540
|
+
i0.ɵɵelementStart(64, "div", 15)(65, "div", 16);
|
|
541
|
+
i0.ɵɵtext(66);
|
|
542
|
+
i0.ɵɵelementEnd();
|
|
543
|
+
i0.ɵɵelementStart(67, "div", 17);
|
|
544
|
+
i0.ɵɵtext(68, "Currently Running");
|
|
545
|
+
i0.ɵɵelementEnd()()()();
|
|
546
|
+
i0.ɵɵelementStart(69, "div", 29)(70, "div", 30)(71, "h4");
|
|
547
|
+
i0.ɵɵelement(72, "i", 31);
|
|
548
|
+
i0.ɵɵtext(73, " 7-Day Execution Trends");
|
|
549
|
+
i0.ɵɵelementEnd()();
|
|
550
|
+
i0.ɵɵelementStart(74, "div", 32);
|
|
551
|
+
i0.ɵɵtemplate(75, ExecutionMonitoringComponent_Conditional_75_Template, 12, 0)(76, ExecutionMonitoringComponent_Conditional_76_Template, 4, 0, "div", 33);
|
|
552
|
+
i0.ɵɵelementEnd()();
|
|
553
|
+
i0.ɵɵelementStart(77, "div", 34)(78, "div", 30)(79, "h4");
|
|
554
|
+
i0.ɵɵelement(80, "i", 35);
|
|
555
|
+
i0.ɵɵtext(81, " Recent Executions");
|
|
556
|
+
i0.ɵɵelementEnd();
|
|
557
|
+
i0.ɵɵelementStart(82, "div", 36);
|
|
558
|
+
i0.ɵɵtext(83);
|
|
559
|
+
i0.ɵɵelementEnd()();
|
|
560
|
+
i0.ɵɵelementStart(84, "div", 37);
|
|
561
|
+
i0.ɵɵtemplate(85, ExecutionMonitoringComponent_Conditional_85_Template, 2, 0)(86, ExecutionMonitoringComponent_Conditional_86_Template, 6, 0, "div", 38);
|
|
562
|
+
i0.ɵɵelementEnd()();
|
|
563
|
+
i0.ɵɵtemplate(87, ExecutionMonitoringComponent_Conditional_87_Template, 2, 1, "div", 39);
|
|
564
|
+
i0.ɵɵelementEnd();
|
|
565
|
+
} if (rf & 2) {
|
|
566
|
+
i0.ɵɵadvance(6);
|
|
567
|
+
i0.ɵɵproperty("primary", true)("icon", "refresh");
|
|
568
|
+
i0.ɵɵadvance(4);
|
|
569
|
+
i0.ɵɵproperty("value", ctx.searchTerm$.value);
|
|
570
|
+
i0.ɵɵadvance(3);
|
|
571
|
+
i0.ɵɵproperty("data", ctx.timeRangeOptions)("value", ctx.selectedTimeRange$.value);
|
|
572
|
+
i0.ɵɵadvance();
|
|
573
|
+
i0.ɵɵproperty("data", ctx.resultOptions)("value", ctx.selectedResult$.value);
|
|
574
|
+
i0.ɵɵadvance();
|
|
575
|
+
i0.ɵɵproperty("data", ctx.actionOptions)("value", ctx.selectedAction$.value);
|
|
576
|
+
i0.ɵɵadvance(7);
|
|
577
|
+
i0.ɵɵtextInterpolate(ctx.metrics.totalExecutions);
|
|
578
|
+
i0.ɵɵadvance(8);
|
|
579
|
+
i0.ɵɵtextInterpolate1("", ctx.getSuccessRate(), "%");
|
|
580
|
+
i0.ɵɵadvance(4);
|
|
581
|
+
i0.ɵɵtextInterpolate2("", ctx.metrics.successfulExecutions, "/", ctx.metrics.totalExecutions, "");
|
|
582
|
+
i0.ɵɵadvance(6);
|
|
583
|
+
i0.ɵɵtextInterpolate(ctx.metrics.failedExecutions);
|
|
584
|
+
i0.ɵɵadvance(8);
|
|
585
|
+
i0.ɵɵtextInterpolate1("", ctx.metrics.averageDuration, "s");
|
|
586
|
+
i0.ɵɵadvance(8);
|
|
587
|
+
i0.ɵɵtextInterpolate(ctx.metrics.executionsToday);
|
|
588
|
+
i0.ɵɵadvance(4);
|
|
589
|
+
i0.ɵɵtextInterpolate1("", ctx.metrics.executionsThisWeek, " this week");
|
|
590
|
+
i0.ɵɵadvance(6);
|
|
591
|
+
i0.ɵɵtextInterpolate(ctx.metrics.currentlyRunning);
|
|
592
|
+
i0.ɵɵadvance(9);
|
|
593
|
+
i0.ɵɵconditional(ctx.executionTrends.length > 0 ? 75 : 76);
|
|
594
|
+
i0.ɵɵadvance(8);
|
|
595
|
+
i0.ɵɵtextInterpolate1("", ctx.filteredExecutions.length, " executions");
|
|
596
|
+
i0.ɵɵadvance(2);
|
|
597
|
+
i0.ɵɵconditional(ctx.filteredExecutions.length > 0 ? 85 : 86);
|
|
598
|
+
i0.ɵɵadvance(2);
|
|
599
|
+
i0.ɵɵconditional(ctx.isLoading ? 87 : -1);
|
|
600
|
+
} }, dependencies: [i1.LoaderComponent, i2.DropDownListComponent, i3.TextBoxComponent, i3.TextBoxPrefixTemplateDirective, i4.FillContainer, i5.ButtonComponent, i5.ChipComponent, i6.DatePipe], styles: [".execution-monitoring[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n padding: 1.5rem;\n height: 100%;\n overflow-y: auto;\n\n .monitoring-header {\n .header-title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 1rem;\n\n h3 {\n margin: 0;\n font-size: 1.25rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n i {\n color: var(--kendo-color-primary);\n }\n }\n\n .refresh-btn {\n gap: 0.5rem;\n }\n }\n\n .filters-row {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex-wrap: wrap;\n\n .search-container {\n flex: 1;\n min-width: 200px;\n\n kendo-textbox {\n width: 100%;\n }\n }\n\n .filter-group {\n display: flex;\n gap: 0.75rem;\n \n kendo-dropdownlist {\n min-width: 140px;\n }\n }\n }\n }\n\n .metrics-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;\n\n .metric-card {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1.25rem;\n border-radius: 0.75rem;\n background: var(--kendo-color-surface);\n border: 1px solid var(--kendo-color-border);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n transition: all 0.2s ease;\n\n &.clickable {\n cursor: pointer;\n \n &:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);\n }\n }\n\n .metric-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n border-radius: 0.5rem;\n font-size: 1rem;\n\n i {\n color: white;\n }\n }\n\n .metric-content {\n flex: 1;\n\n .metric-value {\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n margin-bottom: 0.25rem;\n }\n\n .metric-label {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--kendo-color-subtle);\n margin-bottom: 0.125rem;\n }\n\n .metric-detail {\n font-size: 0.625rem;\n color: var(--kendo-color-subtle);\n }\n }\n\n &.total .metric-icon { background: var(--kendo-color-primary); }\n &.success .metric-icon { background: var(--kendo-color-success); }\n &.error .metric-icon { background: var(--kendo-color-error); }\n &.duration .metric-icon { background: var(--kendo-color-info); }\n &.activity .metric-icon { background: var(--kendo-color-warning); }\n &.running .metric-icon { background: var(--kendo-color-secondary); }\n }\n }\n\n .trends-section {\n background: var(--kendo-color-surface);\n border: 1px solid var(--kendo-color-border);\n border-radius: 0.75rem;\n padding: 1.5rem;\n\n .section-header {\n margin-bottom: 1.5rem;\n\n h4 {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n i {\n color: var(--kendo-color-primary);\n }\n }\n }\n\n .trends-chart {\n .trend-bars {\n display: flex;\n align-items: end;\n gap: 1rem;\n height: 120px;\n margin-bottom: 1rem;\n\n .trend-bar {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n\n .bar-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-height: 80px;\n border-radius: 0.25rem;\n overflow: hidden;\n background: var(--kendo-color-border);\n position: relative;\n\n .bar-success {\n background: var(--kendo-color-success);\n width: 100%;\n min-height: 2px;\n transition: height 0.3s ease;\n }\n\n .bar-failed {\n background: var(--kendo-color-error);\n width: 100%;\n min-height: 2px;\n transition: height 0.3s ease;\n }\n }\n\n .bar-label {\n font-size: 0.625rem;\n color: var(--kendo-color-subtle);\n font-weight: 600;\n }\n\n .bar-total {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--kendo-color-on-app-surface);\n }\n }\n }\n\n .chart-legend {\n display: flex;\n justify-content: center;\n gap: 1.5rem;\n\n .legend-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.75rem;\n\n .legend-color {\n width: 12px;\n height: 12px;\n border-radius: 2px;\n\n &.success { background: var(--kendo-color-success); }\n &.failed { background: var(--kendo-color-error); }\n }\n }\n }\n\n .empty-chart {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 120px;\n color: var(--kendo-color-subtle);\n\n i {\n font-size: 2rem;\n margin-bottom: 0.5rem;\n opacity: 0.5;\n }\n\n p {\n margin: 0;\n font-size: 0.875rem;\n }\n }\n }\n }\n\n .executions-section {\n flex: 1;\n min-height: 0;\n background: var(--kendo-color-surface);\n border: 1px solid var(--kendo-color-border);\n border-radius: 0.75rem;\n display: flex;\n flex-direction: column;\n\n .section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1.5rem 1.5rem 0;\n margin-bottom: 1rem;\n\n h4 {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n i {\n color: var(--kendo-color-primary);\n }\n }\n\n .results-count {\n font-size: 0.75rem;\n color: var(--kendo-color-subtle);\n font-weight: 600;\n }\n }\n\n .executions-list {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 0 1.5rem 1.5rem;\n\n .execution-item {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n border: 1px solid var(--kendo-color-border);\n border-radius: 0.5rem;\n margin-bottom: 0.75rem;\n cursor: pointer;\n transition: all 0.2s ease;\n\n &:hover {\n background: var(--kendo-color-base-hover);\n border-color: var(--kendo-color-primary);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n }\n\n .execution-status {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n\n i {\n font-size: 1rem;\n\n &.fa-check-circle { color: var(--kendo-color-success); }\n &.fa-exclamation-circle { color: var(--kendo-color-error); }\n &.fa-spinner { color: var(--kendo-color-warning); }\n &.fa-info-circle,\n &.fa-question { color: var(--kendo-color-info); }\n }\n }\n\n .execution-main {\n flex: 1;\n\n .execution-action {\n font-weight: 600;\n margin-bottom: 0.25rem;\n color: var(--kendo-color-primary);\n cursor: pointer;\n transition: color 0.2s ease;\n\n &:hover {\n color: var(--kendo-color-primary-darker);\n text-decoration: underline;\n }\n }\n\n .execution-details {\n display: flex;\n gap: 1rem;\n font-size: 0.75rem;\n color: var(--kendo-color-subtle);\n\n .execution-time {\n font-weight: 600;\n }\n\n .execution-user {\n color: var(--kendo-color-info);\n }\n\n .execution-duration {\n font-weight: 600;\n }\n }\n }\n\n .execution-result {\n flex-shrink: 0;\n }\n\n .execution-actions {\n flex-shrink: 0;\n\n button {\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n }\n\n &:hover .execution-actions button {\n opacity: 1;\n }\n }\n\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 3rem 2rem;\n text-align: center;\n color: var(--kendo-color-subtle);\n\n i {\n font-size: 3rem;\n margin-bottom: 1rem;\n opacity: 0.5;\n }\n\n h5 {\n margin: 0 0 0.5rem 0;\n font-size: 1rem;\n font-weight: 600;\n }\n\n p {\n margin: 0;\n font-size: 0.875rem;\n }\n }\n }\n }\n\n .loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n }\n}\n\n//[_ngcontent-%COMP%] Responsive[_ngcontent-%COMP%] design\n@media[_ngcontent-%COMP%] (max-width[_ngcontent-%COMP%]: 1200px)[_ngcontent-%COMP%] {\n .execution-monitoring {\n .metrics-summary {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .monitoring-header .filters-row {\n .filter-group {\n flex-wrap: wrap;\n }\n }\n }\n}\n\n@media (max-width: 768px) {\n .execution-monitoring[_ngcontent-%COMP%] {\n padding: 1rem;\n gap: 1rem;\n\n .metrics-summary {\n grid-template-columns: repeat(2, 1fr);\n gap: 0.75rem;\n\n .metric-card {\n padding: 1rem;\n\n .metric-content .metric-value {\n font-size: 1.25rem;\n }\n }\n }\n\n .monitoring-header {\n .header-title {\n flex-direction: column;\n align-items: stretch;\n gap: 1rem;\n }\n\n .filters-row {\n flex-direction: column;\n align-items: stretch;\n\n .search-container,\n .filter-group {\n min-width: unset;\n }\n\n .filter-group {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 0.5rem;\n }\n }\n }\n\n .trends-section .trends-chart .trend-bars {\n gap: 0.5rem;\n }\n }\n}"] });
|
|
473
601
|
}
|
|
474
|
-
ExecutionMonitoringComponent.ɵfac = function ExecutionMonitoringComponent_Factory(t) { return new (t || ExecutionMonitoringComponent)(); };
|
|
475
|
-
ExecutionMonitoringComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ExecutionMonitoringComponent, selectors: [["mj-execution-monitoring"]], outputs: { openEntityRecord: "openEntityRecord", showExecutionsListView: "showExecutionsListView" }, decls: 88, vars: 22, consts: [["mjFillContainer", "", 1, "execution-monitoring"], [1, "monitoring-header"], [1, "header-title"], [1, "fa-solid", "fa-chart-line"], ["kendoButton", "", 1, "refresh-btn", 3, "click", "primary", "icon"], [1, "filters-row"], [1, "search-container"], ["placeholder", "Search executions...", 3, "valueChange", "value"], ["kendoTextBoxPrefixTemplate", ""], [1, "filter-group"], ["textField", "text", "valueField", "value", 3, "valueChange", "data", "value"], [1, "metrics-summary"], [1, "metric-card", "total", "clickable", 3, "click"], [1, "metric-icon"], [1, "fa-solid", "fa-play-circle"], [1, "metric-content"], [1, "metric-value"], [1, "metric-label"], [1, "metric-card", "success", "clickable", 3, "click"], [1, "fa-solid", "fa-check-circle"], [1, "metric-detail"], [1, "metric-card", "error", "clickable", 3, "click"], [1, "fa-solid", "fa-exclamation-circle"], [1, "metric-card", "duration"], [1, "fa-solid", "fa-clock"], [1, "metric-card", "activity"], [1, "fa-solid", "fa-calendar-day"], [1, "metric-card", "running", "clickable", 3, "click"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "trends-section"], [1, "section-header"], [1, "fa-solid", "fa-chart-area"], [1, "trends-chart"], [1, "empty-chart"], [1, "executions-section"], [1, "fa-solid", "fa-list"], [1, "results-count"], [1, "executions-list"], [1, "empty-state"], [1, "loading-overlay"], [1, "fa-solid", "fa-search"], [1, "trend-bars"], [1, "trend-bar"], [1, "chart-legend"], [1, "legend-item"], [1, "legend-color", "success"], [1, "legend-color", "failed"], [1, "bar-container"], [1, "bar-success"], [1, "bar-failed"], [1, "bar-label"], [1, "bar-total"], [1, "execution-item"], [1, "execution-item", 3, "click"], [1, "execution-status"], [1, "execution-main"], [1, "execution-action", 3, "click"], [1, "execution-details"], [1, "execution-time"], [1, "execution-user"], [1, "execution-duration"], [1, "execution-result"], [3, "themeColor", "size"], [1, "execution-actions"], ["kendoButton", "", 3, "click", "fillMode", "icon"], ["type", "converging-spinner", 3, "themeColor"]], template: function ExecutionMonitoringComponent_Template(rf, ctx) { if (rf & 1) {
|
|
476
|
-
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "h3");
|
|
477
|
-
i0.ɵɵelement(4, "i", 3);
|
|
478
|
-
i0.ɵɵtext(5, " Execution Monitoring");
|
|
479
|
-
i0.ɵɵelementEnd();
|
|
480
|
-
i0.ɵɵelementStart(6, "button", 4);
|
|
481
|
-
i0.ɵɵlistener("click", function ExecutionMonitoringComponent_Template_button_click_6_listener() { return ctx.refreshData(); });
|
|
482
|
-
i0.ɵɵtext(7, " Refresh ");
|
|
483
|
-
i0.ɵɵelementEnd()();
|
|
484
|
-
i0.ɵɵelementStart(8, "div", 5)(9, "div", 6)(10, "kendo-textbox", 7);
|
|
485
|
-
i0.ɵɵlistener("valueChange", function ExecutionMonitoringComponent_Template_kendo_textbox_valueChange_10_listener($event) { return ctx.onSearchChange($event); });
|
|
486
|
-
i0.ɵɵtemplate(11, ExecutionMonitoringComponent_ng_template_11_Template, 1, 0, "ng-template", 8);
|
|
487
|
-
i0.ɵɵelementEnd()();
|
|
488
|
-
i0.ɵɵelementStart(12, "div", 9)(13, "kendo-dropdownlist", 10);
|
|
489
|
-
i0.ɵɵlistener("valueChange", function ExecutionMonitoringComponent_Template_kendo_dropdownlist_valueChange_13_listener($event) { return ctx.onTimeRangeChange($event); });
|
|
490
|
-
i0.ɵɵelementEnd();
|
|
491
|
-
i0.ɵɵelementStart(14, "kendo-dropdownlist", 10);
|
|
492
|
-
i0.ɵɵlistener("valueChange", function ExecutionMonitoringComponent_Template_kendo_dropdownlist_valueChange_14_listener($event) { return ctx.onResultFilterChange($event); });
|
|
493
|
-
i0.ɵɵelementEnd();
|
|
494
|
-
i0.ɵɵelementStart(15, "kendo-dropdownlist", 10);
|
|
495
|
-
i0.ɵɵlistener("valueChange", function ExecutionMonitoringComponent_Template_kendo_dropdownlist_valueChange_15_listener($event) { return ctx.onActionFilterChange($event); });
|
|
496
|
-
i0.ɵɵelementEnd()()()();
|
|
497
|
-
i0.ɵɵelementStart(16, "div", 11)(17, "div", 12);
|
|
498
|
-
i0.ɵɵlistener("click", function ExecutionMonitoringComponent_Template_div_click_17_listener() { return ctx.onTotalExecutionsClick(); });
|
|
499
|
-
i0.ɵɵelementStart(18, "div", 13);
|
|
500
|
-
i0.ɵɵelement(19, "i", 14);
|
|
501
|
-
i0.ɵɵelementEnd();
|
|
502
|
-
i0.ɵɵelementStart(20, "div", 15)(21, "div", 16);
|
|
503
|
-
i0.ɵɵtext(22);
|
|
504
|
-
i0.ɵɵelementEnd();
|
|
505
|
-
i0.ɵɵelementStart(23, "div", 17);
|
|
506
|
-
i0.ɵɵtext(24, "Total Executions");
|
|
507
|
-
i0.ɵɵelementEnd()()();
|
|
508
|
-
i0.ɵɵelementStart(25, "div", 18);
|
|
509
|
-
i0.ɵɵlistener("click", function ExecutionMonitoringComponent_Template_div_click_25_listener() { return ctx.onSuccessRateClick(); });
|
|
510
|
-
i0.ɵɵelementStart(26, "div", 13);
|
|
511
|
-
i0.ɵɵelement(27, "i", 19);
|
|
512
|
-
i0.ɵɵelementEnd();
|
|
513
|
-
i0.ɵɵelementStart(28, "div", 15)(29, "div", 16);
|
|
514
|
-
i0.ɵɵtext(30);
|
|
515
|
-
i0.ɵɵelementEnd();
|
|
516
|
-
i0.ɵɵelementStart(31, "div", 17);
|
|
517
|
-
i0.ɵɵtext(32, "Success Rate");
|
|
518
|
-
i0.ɵɵelementEnd();
|
|
519
|
-
i0.ɵɵelementStart(33, "div", 20);
|
|
520
|
-
i0.ɵɵtext(34);
|
|
521
|
-
i0.ɵɵelementEnd()()();
|
|
522
|
-
i0.ɵɵelementStart(35, "div", 21);
|
|
523
|
-
i0.ɵɵlistener("click", function ExecutionMonitoringComponent_Template_div_click_35_listener() { return ctx.onFailedExecutionsClick(); });
|
|
524
|
-
i0.ɵɵelementStart(36, "div", 13);
|
|
525
|
-
i0.ɵɵelement(37, "i", 22);
|
|
526
|
-
i0.ɵɵelementEnd();
|
|
527
|
-
i0.ɵɵelementStart(38, "div", 15)(39, "div", 16);
|
|
528
|
-
i0.ɵɵtext(40);
|
|
529
|
-
i0.ɵɵelementEnd();
|
|
530
|
-
i0.ɵɵelementStart(41, "div", 17);
|
|
531
|
-
i0.ɵɵtext(42, "Failed Executions");
|
|
532
|
-
i0.ɵɵelementEnd()()();
|
|
533
|
-
i0.ɵɵelementStart(43, "div", 23)(44, "div", 13);
|
|
534
|
-
i0.ɵɵelement(45, "i", 24);
|
|
535
|
-
i0.ɵɵelementEnd();
|
|
536
|
-
i0.ɵɵelementStart(46, "div", 15)(47, "div", 16);
|
|
537
|
-
i0.ɵɵtext(48);
|
|
538
|
-
i0.ɵɵelementEnd();
|
|
539
|
-
i0.ɵɵelementStart(49, "div", 17);
|
|
540
|
-
i0.ɵɵtext(50, "Avg Duration");
|
|
541
|
-
i0.ɵɵelementEnd()()();
|
|
542
|
-
i0.ɵɵelementStart(51, "div", 25)(52, "div", 13);
|
|
543
|
-
i0.ɵɵelement(53, "i", 26);
|
|
544
|
-
i0.ɵɵelementEnd();
|
|
545
|
-
i0.ɵɵelementStart(54, "div", 15)(55, "div", 16);
|
|
546
|
-
i0.ɵɵtext(56);
|
|
547
|
-
i0.ɵɵelementEnd();
|
|
548
|
-
i0.ɵɵelementStart(57, "div", 17);
|
|
549
|
-
i0.ɵɵtext(58, "Today");
|
|
550
|
-
i0.ɵɵelementEnd();
|
|
551
|
-
i0.ɵɵelementStart(59, "div", 20);
|
|
552
|
-
i0.ɵɵtext(60);
|
|
553
|
-
i0.ɵɵelementEnd()()();
|
|
554
|
-
i0.ɵɵelementStart(61, "div", 27);
|
|
555
|
-
i0.ɵɵlistener("click", function ExecutionMonitoringComponent_Template_div_click_61_listener() { return ctx.onRunningExecutionsClick(); });
|
|
556
|
-
i0.ɵɵelementStart(62, "div", 13);
|
|
557
|
-
i0.ɵɵelement(63, "i", 28);
|
|
558
|
-
i0.ɵɵelementEnd();
|
|
559
|
-
i0.ɵɵelementStart(64, "div", 15)(65, "div", 16);
|
|
560
|
-
i0.ɵɵtext(66);
|
|
561
|
-
i0.ɵɵelementEnd();
|
|
562
|
-
i0.ɵɵelementStart(67, "div", 17);
|
|
563
|
-
i0.ɵɵtext(68, "Currently Running");
|
|
564
|
-
i0.ɵɵelementEnd()()()();
|
|
565
|
-
i0.ɵɵelementStart(69, "div", 29)(70, "div", 30)(71, "h4");
|
|
566
|
-
i0.ɵɵelement(72, "i", 31);
|
|
567
|
-
i0.ɵɵtext(73, " 7-Day Execution Trends");
|
|
568
|
-
i0.ɵɵelementEnd()();
|
|
569
|
-
i0.ɵɵelementStart(74, "div", 32);
|
|
570
|
-
i0.ɵɵtemplate(75, ExecutionMonitoringComponent_Conditional_75_Template, 12, 0)(76, ExecutionMonitoringComponent_Conditional_76_Template, 4, 0, "div", 33);
|
|
571
|
-
i0.ɵɵelementEnd()();
|
|
572
|
-
i0.ɵɵelementStart(77, "div", 34)(78, "div", 30)(79, "h4");
|
|
573
|
-
i0.ɵɵelement(80, "i", 35);
|
|
574
|
-
i0.ɵɵtext(81, " Recent Executions");
|
|
575
|
-
i0.ɵɵelementEnd();
|
|
576
|
-
i0.ɵɵelementStart(82, "div", 36);
|
|
577
|
-
i0.ɵɵtext(83);
|
|
578
|
-
i0.ɵɵelementEnd()();
|
|
579
|
-
i0.ɵɵelementStart(84, "div", 37);
|
|
580
|
-
i0.ɵɵtemplate(85, ExecutionMonitoringComponent_Conditional_85_Template, 2, 0)(86, ExecutionMonitoringComponent_Conditional_86_Template, 6, 0, "div", 38);
|
|
581
|
-
i0.ɵɵelementEnd()();
|
|
582
|
-
i0.ɵɵtemplate(87, ExecutionMonitoringComponent_Conditional_87_Template, 2, 1, "div", 39);
|
|
583
|
-
i0.ɵɵelementEnd();
|
|
584
|
-
} if (rf & 2) {
|
|
585
|
-
i0.ɵɵadvance(6);
|
|
586
|
-
i0.ɵɵproperty("primary", true)("icon", "refresh");
|
|
587
|
-
i0.ɵɵadvance(4);
|
|
588
|
-
i0.ɵɵproperty("value", ctx.searchTerm$.value);
|
|
589
|
-
i0.ɵɵadvance(3);
|
|
590
|
-
i0.ɵɵproperty("data", ctx.timeRangeOptions)("value", ctx.selectedTimeRange$.value);
|
|
591
|
-
i0.ɵɵadvance();
|
|
592
|
-
i0.ɵɵproperty("data", ctx.resultOptions)("value", ctx.selectedResult$.value);
|
|
593
|
-
i0.ɵɵadvance();
|
|
594
|
-
i0.ɵɵproperty("data", ctx.actionOptions)("value", ctx.selectedAction$.value);
|
|
595
|
-
i0.ɵɵadvance(7);
|
|
596
|
-
i0.ɵɵtextInterpolate(ctx.metrics.totalExecutions);
|
|
597
|
-
i0.ɵɵadvance(8);
|
|
598
|
-
i0.ɵɵtextInterpolate1("", ctx.getSuccessRate(), "%");
|
|
599
|
-
i0.ɵɵadvance(4);
|
|
600
|
-
i0.ɵɵtextInterpolate2("", ctx.metrics.successfulExecutions, "/", ctx.metrics.totalExecutions, "");
|
|
601
|
-
i0.ɵɵadvance(6);
|
|
602
|
-
i0.ɵɵtextInterpolate(ctx.metrics.failedExecutions);
|
|
603
|
-
i0.ɵɵadvance(8);
|
|
604
|
-
i0.ɵɵtextInterpolate1("", ctx.metrics.averageDuration, "s");
|
|
605
|
-
i0.ɵɵadvance(8);
|
|
606
|
-
i0.ɵɵtextInterpolate(ctx.metrics.executionsToday);
|
|
607
|
-
i0.ɵɵadvance(4);
|
|
608
|
-
i0.ɵɵtextInterpolate1("", ctx.metrics.executionsThisWeek, " this week");
|
|
609
|
-
i0.ɵɵadvance(6);
|
|
610
|
-
i0.ɵɵtextInterpolate(ctx.metrics.currentlyRunning);
|
|
611
|
-
i0.ɵɵadvance(9);
|
|
612
|
-
i0.ɵɵconditional(ctx.executionTrends.length > 0 ? 75 : 76);
|
|
613
|
-
i0.ɵɵadvance(8);
|
|
614
|
-
i0.ɵɵtextInterpolate1("", ctx.filteredExecutions.length, " executions");
|
|
615
|
-
i0.ɵɵadvance(2);
|
|
616
|
-
i0.ɵɵconditional(ctx.filteredExecutions.length > 0 ? 85 : 86);
|
|
617
|
-
i0.ɵɵadvance(2);
|
|
618
|
-
i0.ɵɵconditional(ctx.isLoading ? 87 : -1);
|
|
619
|
-
} }, dependencies: [i1.LoaderComponent, i2.DropDownListComponent, i3.TextBoxComponent, i3.TextBoxPrefixTemplateDirective, i4.FillContainer, i5.ButtonComponent, i5.ChipComponent, i6.DatePipe], styles: [".execution-monitoring[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n padding: 1.5rem;\n height: 100%;\n overflow-y: auto;\n\n .monitoring-header {\n .header-title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 1rem;\n\n h3 {\n margin: 0;\n font-size: 1.25rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n i {\n color: var(--kendo-color-primary);\n }\n }\n\n .refresh-btn {\n gap: 0.5rem;\n }\n }\n\n .filters-row {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex-wrap: wrap;\n\n .search-container {\n flex: 1;\n min-width: 200px;\n\n kendo-textbox {\n width: 100%;\n }\n }\n\n .filter-group {\n display: flex;\n gap: 0.75rem;\n \n kendo-dropdownlist {\n min-width: 140px;\n }\n }\n }\n }\n\n .metrics-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;\n\n .metric-card {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1.25rem;\n border-radius: 0.75rem;\n background: var(--kendo-color-surface);\n border: 1px solid var(--kendo-color-border);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n transition: all 0.2s ease;\n\n &.clickable {\n cursor: pointer;\n \n &:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);\n }\n }\n\n .metric-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n border-radius: 0.5rem;\n font-size: 1rem;\n\n i {\n color: white;\n }\n }\n\n .metric-content {\n flex: 1;\n\n .metric-value {\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n margin-bottom: 0.25rem;\n }\n\n .metric-label {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--kendo-color-subtle);\n margin-bottom: 0.125rem;\n }\n\n .metric-detail {\n font-size: 0.625rem;\n color: var(--kendo-color-subtle);\n }\n }\n\n &.total .metric-icon { background: var(--kendo-color-primary); }\n &.success .metric-icon { background: var(--kendo-color-success); }\n &.error .metric-icon { background: var(--kendo-color-error); }\n &.duration .metric-icon { background: var(--kendo-color-info); }\n &.activity .metric-icon { background: var(--kendo-color-warning); }\n &.running .metric-icon { background: var(--kendo-color-secondary); }\n }\n }\n\n .trends-section {\n background: var(--kendo-color-surface);\n border: 1px solid var(--kendo-color-border);\n border-radius: 0.75rem;\n padding: 1.5rem;\n\n .section-header {\n margin-bottom: 1.5rem;\n\n h4 {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n i {\n color: var(--kendo-color-primary);\n }\n }\n }\n\n .trends-chart {\n .trend-bars {\n display: flex;\n align-items: end;\n gap: 1rem;\n height: 120px;\n margin-bottom: 1rem;\n\n .trend-bar {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n\n .bar-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-height: 80px;\n border-radius: 0.25rem;\n overflow: hidden;\n background: var(--kendo-color-border);\n position: relative;\n\n .bar-success {\n background: var(--kendo-color-success);\n width: 100%;\n min-height: 2px;\n transition: height 0.3s ease;\n }\n\n .bar-failed {\n background: var(--kendo-color-error);\n width: 100%;\n min-height: 2px;\n transition: height 0.3s ease;\n }\n }\n\n .bar-label {\n font-size: 0.625rem;\n color: var(--kendo-color-subtle);\n font-weight: 600;\n }\n\n .bar-total {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--kendo-color-on-app-surface);\n }\n }\n }\n\n .chart-legend {\n display: flex;\n justify-content: center;\n gap: 1.5rem;\n\n .legend-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.75rem;\n\n .legend-color {\n width: 12px;\n height: 12px;\n border-radius: 2px;\n\n &.success { background: var(--kendo-color-success); }\n &.failed { background: var(--kendo-color-error); }\n }\n }\n }\n\n .empty-chart {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 120px;\n color: var(--kendo-color-subtle);\n\n i {\n font-size: 2rem;\n margin-bottom: 0.5rem;\n opacity: 0.5;\n }\n\n p {\n margin: 0;\n font-size: 0.875rem;\n }\n }\n }\n }\n\n .executions-section {\n flex: 1;\n min-height: 0;\n background: var(--kendo-color-surface);\n border: 1px solid var(--kendo-color-border);\n border-radius: 0.75rem;\n display: flex;\n flex-direction: column;\n\n .section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1.5rem 1.5rem 0;\n margin-bottom: 1rem;\n\n h4 {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n i {\n color: var(--kendo-color-primary);\n }\n }\n\n .results-count {\n font-size: 0.75rem;\n color: var(--kendo-color-subtle);\n font-weight: 600;\n }\n }\n\n .executions-list {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 0 1.5rem 1.5rem;\n\n .execution-item {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n border: 1px solid var(--kendo-color-border);\n border-radius: 0.5rem;\n margin-bottom: 0.75rem;\n cursor: pointer;\n transition: all 0.2s ease;\n\n &:hover {\n background: var(--kendo-color-base-hover);\n border-color: var(--kendo-color-primary);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n }\n\n .execution-status {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n\n i {\n font-size: 1rem;\n\n &.fa-check-circle { color: var(--kendo-color-success); }\n &.fa-exclamation-circle { color: var(--kendo-color-error); }\n &.fa-spinner { color: var(--kendo-color-warning); }\n &.fa-info-circle,\n &.fa-question { color: var(--kendo-color-info); }\n }\n }\n\n .execution-main {\n flex: 1;\n\n .execution-action {\n font-weight: 600;\n margin-bottom: 0.25rem;\n color: var(--kendo-color-primary);\n cursor: pointer;\n transition: color 0.2s ease;\n\n &:hover {\n color: var(--kendo-color-primary-darker);\n text-decoration: underline;\n }\n }\n\n .execution-details {\n display: flex;\n gap: 1rem;\n font-size: 0.75rem;\n color: var(--kendo-color-subtle);\n\n .execution-time {\n font-weight: 600;\n }\n\n .execution-user {\n color: var(--kendo-color-info);\n }\n\n .execution-duration {\n font-weight: 600;\n }\n }\n }\n\n .execution-result {\n flex-shrink: 0;\n }\n\n .execution-actions {\n flex-shrink: 0;\n\n button {\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n }\n\n &:hover .execution-actions button {\n opacity: 1;\n }\n }\n\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 3rem 2rem;\n text-align: center;\n color: var(--kendo-color-subtle);\n\n i {\n font-size: 3rem;\n margin-bottom: 1rem;\n opacity: 0.5;\n }\n\n h5 {\n margin: 0 0 0.5rem 0;\n font-size: 1rem;\n font-weight: 600;\n }\n\n p {\n margin: 0;\n font-size: 0.875rem;\n }\n }\n }\n }\n\n .loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n }\n}\n\n//[_ngcontent-%COMP%] Responsive[_ngcontent-%COMP%] design\n@media[_ngcontent-%COMP%] (max-width[_ngcontent-%COMP%]: 1200px)[_ngcontent-%COMP%] {\n .execution-monitoring {\n .metrics-summary {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .monitoring-header .filters-row {\n .filter-group {\n flex-wrap: wrap;\n }\n }\n }\n}\n\n@media (max-width: 768px) {\n .execution-monitoring[_ngcontent-%COMP%] {\n padding: 1rem;\n gap: 1rem;\n\n .metrics-summary {\n grid-template-columns: repeat(2, 1fr);\n gap: 0.75rem;\n\n .metric-card {\n padding: 1rem;\n\n .metric-content .metric-value {\n font-size: 1.25rem;\n }\n }\n }\n\n .monitoring-header {\n .header-title {\n flex-direction: column;\n align-items: stretch;\n gap: 1rem;\n }\n\n .filters-row {\n flex-direction: column;\n align-items: stretch;\n\n .search-container,\n .filter-group {\n min-width: unset;\n }\n\n .filter-group {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 0.5rem;\n }\n }\n }\n\n .trends-section .trends-chart .trend-bars {\n gap: 0.5rem;\n }\n }\n}"] });
|
|
620
602
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ExecutionMonitoringComponent, [{
|
|
621
603
|
type: Component,
|
|
622
604
|
args: [{ selector: 'mj-execution-monitoring', template: "<div class=\"execution-monitoring\" mjFillContainer>\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 [value]=\"selectedTimeRange$.value\"\n (valueChange)=\"onTimeRangeChange($event)\">\n </kendo-dropdownlist>\n \n <kendo-dropdownlist \n [data]=\"resultOptions\"\n textField=\"text\"\n valueField=\"value\"\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 [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 <kendo-loader type=\"converging-spinner\" [themeColor]=\"'primary'\"></kendo-loader>\n </div>\n }\n</div>", styles: [".execution-monitoring {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n padding: 1.5rem;\n height: 100%;\n overflow-y: auto;\n\n .monitoring-header {\n .header-title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 1rem;\n\n h3 {\n margin: 0;\n font-size: 1.25rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n i {\n color: var(--kendo-color-primary);\n }\n }\n\n .refresh-btn {\n gap: 0.5rem;\n }\n }\n\n .filters-row {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex-wrap: wrap;\n\n .search-container {\n flex: 1;\n min-width: 200px;\n\n kendo-textbox {\n width: 100%;\n }\n }\n\n .filter-group {\n display: flex;\n gap: 0.75rem;\n \n kendo-dropdownlist {\n min-width: 140px;\n }\n }\n }\n }\n\n .metrics-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;\n\n .metric-card {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1.25rem;\n border-radius: 0.75rem;\n background: var(--kendo-color-surface);\n border: 1px solid var(--kendo-color-border);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n transition: all 0.2s ease;\n\n &.clickable {\n cursor: pointer;\n \n &:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);\n }\n }\n\n .metric-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n border-radius: 0.5rem;\n font-size: 1rem;\n\n i {\n color: white;\n }\n }\n\n .metric-content {\n flex: 1;\n\n .metric-value {\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n margin-bottom: 0.25rem;\n }\n\n .metric-label {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--kendo-color-subtle);\n margin-bottom: 0.125rem;\n }\n\n .metric-detail {\n font-size: 0.625rem;\n color: var(--kendo-color-subtle);\n }\n }\n\n &.total .metric-icon { background: var(--kendo-color-primary); }\n &.success .metric-icon { background: var(--kendo-color-success); }\n &.error .metric-icon { background: var(--kendo-color-error); }\n &.duration .metric-icon { background: var(--kendo-color-info); }\n &.activity .metric-icon { background: var(--kendo-color-warning); }\n &.running .metric-icon { background: var(--kendo-color-secondary); }\n }\n }\n\n .trends-section {\n background: var(--kendo-color-surface);\n border: 1px solid var(--kendo-color-border);\n border-radius: 0.75rem;\n padding: 1.5rem;\n\n .section-header {\n margin-bottom: 1.5rem;\n\n h4 {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n i {\n color: var(--kendo-color-primary);\n }\n }\n }\n\n .trends-chart {\n .trend-bars {\n display: flex;\n align-items: end;\n gap: 1rem;\n height: 120px;\n margin-bottom: 1rem;\n\n .trend-bar {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n\n .bar-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-height: 80px;\n border-radius: 0.25rem;\n overflow: hidden;\n background: var(--kendo-color-border);\n position: relative;\n\n .bar-success {\n background: var(--kendo-color-success);\n width: 100%;\n min-height: 2px;\n transition: height 0.3s ease;\n }\n\n .bar-failed {\n background: var(--kendo-color-error);\n width: 100%;\n min-height: 2px;\n transition: height 0.3s ease;\n }\n }\n\n .bar-label {\n font-size: 0.625rem;\n color: var(--kendo-color-subtle);\n font-weight: 600;\n }\n\n .bar-total {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--kendo-color-on-app-surface);\n }\n }\n }\n\n .chart-legend {\n display: flex;\n justify-content: center;\n gap: 1.5rem;\n\n .legend-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.75rem;\n\n .legend-color {\n width: 12px;\n height: 12px;\n border-radius: 2px;\n\n &.success { background: var(--kendo-color-success); }\n &.failed { background: var(--kendo-color-error); }\n }\n }\n }\n\n .empty-chart {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 120px;\n color: var(--kendo-color-subtle);\n\n i {\n font-size: 2rem;\n margin-bottom: 0.5rem;\n opacity: 0.5;\n }\n\n p {\n margin: 0;\n font-size: 0.875rem;\n }\n }\n }\n }\n\n .executions-section {\n flex: 1;\n min-height: 0;\n background: var(--kendo-color-surface);\n border: 1px solid var(--kendo-color-border);\n border-radius: 0.75rem;\n display: flex;\n flex-direction: column;\n\n .section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1.5rem 1.5rem 0;\n margin-bottom: 1rem;\n\n h4 {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n i {\n color: var(--kendo-color-primary);\n }\n }\n\n .results-count {\n font-size: 0.75rem;\n color: var(--kendo-color-subtle);\n font-weight: 600;\n }\n }\n\n .executions-list {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 0 1.5rem 1.5rem;\n\n .execution-item {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n border: 1px solid var(--kendo-color-border);\n border-radius: 0.5rem;\n margin-bottom: 0.75rem;\n cursor: pointer;\n transition: all 0.2s ease;\n\n &:hover {\n background: var(--kendo-color-base-hover);\n border-color: var(--kendo-color-primary);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n }\n\n .execution-status {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n\n i {\n font-size: 1rem;\n\n &.fa-check-circle { color: var(--kendo-color-success); }\n &.fa-exclamation-circle { color: var(--kendo-color-error); }\n &.fa-spinner { color: var(--kendo-color-warning); }\n &.fa-info-circle,\n &.fa-question { color: var(--kendo-color-info); }\n }\n }\n\n .execution-main {\n flex: 1;\n\n .execution-action {\n font-weight: 600;\n margin-bottom: 0.25rem;\n color: var(--kendo-color-primary);\n cursor: pointer;\n transition: color 0.2s ease;\n\n &:hover {\n color: var(--kendo-color-primary-darker);\n text-decoration: underline;\n }\n }\n\n .execution-details {\n display: flex;\n gap: 1rem;\n font-size: 0.75rem;\n color: var(--kendo-color-subtle);\n\n .execution-time {\n font-weight: 600;\n }\n\n .execution-user {\n color: var(--kendo-color-info);\n }\n\n .execution-duration {\n font-weight: 600;\n }\n }\n }\n\n .execution-result {\n flex-shrink: 0;\n }\n\n .execution-actions {\n flex-shrink: 0;\n\n button {\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n }\n\n &:hover .execution-actions button {\n opacity: 1;\n }\n }\n\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 3rem 2rem;\n text-align: center;\n color: var(--kendo-color-subtle);\n\n i {\n font-size: 3rem;\n margin-bottom: 1rem;\n opacity: 0.5;\n }\n\n h5 {\n margin: 0 0 0.5rem 0;\n font-size: 1rem;\n font-weight: 600;\n }\n\n p {\n margin: 0;\n font-size: 0.875rem;\n }\n }\n }\n }\n\n .loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n }\n}\n\n// Responsive design\n@media (max-width: 1200px) {\n .execution-monitoring {\n .metrics-summary {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .monitoring-header .filters-row {\n .filter-group {\n flex-wrap: wrap;\n }\n }\n }\n}\n\n@media (max-width: 768px) {\n .execution-monitoring {\n padding: 1rem;\n gap: 1rem;\n\n .metrics-summary {\n grid-template-columns: repeat(2, 1fr);\n gap: 0.75rem;\n\n .metric-card {\n padding: 1rem;\n\n .metric-content .metric-value {\n font-size: 1.25rem;\n }\n }\n }\n\n .monitoring-header {\n .header-title {\n flex-direction: column;\n align-items: stretch;\n gap: 1rem;\n }\n\n .filters-row {\n flex-direction: column;\n align-items: stretch;\n\n .search-container,\n .filter-group {\n min-width: unset;\n }\n\n .filter-group {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 0.5rem;\n }\n }\n }\n\n .trends-section .trends-chart .trend-bars {\n gap: 0.5rem;\n }\n }\n}"] }]
|