@memberjunction/ng-dashboards 6.1.4 → 6.1.5
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/dist/Workflows/components/workflow-run-debug-state.d.ts +7 -0
- package/dist/Workflows/components/workflow-run-debug-state.d.ts.map +1 -1
- package/dist/Workflows/components/workflow-run-debug-state.js +12 -0
- package/dist/Workflows/components/workflow-run-debug-state.js.map +1 -1
- package/dist/Workflows/components/workflow-runs-resource.component.d.ts +4 -0
- package/dist/Workflows/components/workflow-runs-resource.component.d.ts.map +1 -1
- package/dist/Workflows/components/workflow-runs-resource.component.js +106 -85
- package/dist/Workflows/components/workflow-runs-resource.component.js.map +1 -1
- package/package.json +63 -63
|
@@ -14,7 +14,7 @@ import { BaseDashboard, BaseResourceComponent } from '@memberjunction/ng-shared'
|
|
|
14
14
|
import { TaskGraphDebuggerComponent } from '@memberjunction/ng-task-graph-editor';
|
|
15
15
|
import { SortWorkflowRuns } from './workflow-run-sorting';
|
|
16
16
|
import { WorkflowRunLayout } from './workflow-run-layout';
|
|
17
|
-
import { EmptyDebugState, ParseWorkflowRunParentBag, TryParseJsonObject, } from './workflow-run-debug-state';
|
|
17
|
+
import { EmptyDebugState, ParseWorkflowRunParentBag, StepFailureReason, TryParseJsonObject, } from './workflow-run-debug-state';
|
|
18
18
|
import * as i0 from "@angular/core";
|
|
19
19
|
import * as i1 from "@angular/common";
|
|
20
20
|
import * as i2 from "@angular/forms";
|
|
@@ -380,19 +380,30 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
380
380
|
i0.ɵɵadvance(2);
|
|
381
381
|
i0.ɵɵconditional(ctx_r0.SelectedEdgeIsConditional ? 10 : 11);
|
|
382
382
|
} }
|
|
383
|
-
function
|
|
383
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
384
|
+
i0.ɵɵelementStart(0, "div", 94)(1, "span", 89);
|
|
385
|
+
i0.ɵɵtext(2, "Why it failed");
|
|
386
|
+
i0.ɵɵelementEnd();
|
|
387
|
+
i0.ɵɵelementStart(3, "span");
|
|
388
|
+
i0.ɵɵtext(4);
|
|
389
|
+
i0.ɵɵelementEnd()();
|
|
390
|
+
} if (rf & 2) {
|
|
391
|
+
i0.ɵɵadvance(4);
|
|
392
|
+
i0.ɵɵtextInterpolate(ctx);
|
|
393
|
+
} }
|
|
394
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_9_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
384
395
|
i0.ɵɵtext(0);
|
|
385
396
|
} if (rf & 2) {
|
|
386
397
|
const progress_r26 = i0.ɵɵnextContext();
|
|
387
398
|
i0.ɵɵtextInterpolate1(" (", progress_r26.progressPercent, "%) ");
|
|
388
399
|
} }
|
|
389
|
-
function
|
|
400
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
390
401
|
i0.ɵɵelementStart(0, "div", 88)(1, "span", 89);
|
|
391
402
|
i0.ɵɵtext(2, "Doing now");
|
|
392
403
|
i0.ɵɵelementEnd();
|
|
393
404
|
i0.ɵɵelementStart(3, "span");
|
|
394
405
|
i0.ɵɵtext(4);
|
|
395
|
-
i0.ɵɵconditionalCreate(5,
|
|
406
|
+
i0.ɵɵconditionalCreate(5, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_9_Conditional_5_Template, 1, 1);
|
|
396
407
|
i0.ɵɵelementEnd()();
|
|
397
408
|
} if (rf & 2) {
|
|
398
409
|
const progress_r26 = ctx;
|
|
@@ -401,27 +412,27 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
401
412
|
i0.ɵɵadvance();
|
|
402
413
|
i0.ɵɵconditional(progress_r26.progressPercent != null ? 5 : -1);
|
|
403
414
|
} }
|
|
404
|
-
function
|
|
415
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_10_Case_4_Template(rf, ctx) { if (rf & 1) {
|
|
405
416
|
i0.ɵɵtext(0);
|
|
406
417
|
} if (rf & 2) {
|
|
407
418
|
const claim_r27 = i0.ɵɵnextContext();
|
|
408
419
|
i0.ɵɵtextInterpolate1(" ", claim_r27.claimedBy, " \u2014 working ");
|
|
409
420
|
} }
|
|
410
|
-
function
|
|
421
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_10_Case_5_Template(rf, ctx) { if (rf & 1) {
|
|
411
422
|
i0.ɵɵtext(0);
|
|
412
423
|
} if (rf & 2) {
|
|
413
424
|
const claim_r27 = i0.ɵɵnextContext();
|
|
414
425
|
i0.ɵɵtextInterpolate1(" ", claim_r27.claimedBy, " \u2014 lost, will be requeued ");
|
|
415
426
|
} }
|
|
416
|
-
function
|
|
427
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_10_Case_6_Template(rf, ctx) { if (rf & 1) {
|
|
417
428
|
i0.ɵɵtext(0, " requeued by the engine ");
|
|
418
429
|
} }
|
|
419
|
-
function
|
|
430
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
420
431
|
i0.ɵɵelementStart(0, "div", 88)(1, "span", 89);
|
|
421
432
|
i0.ɵɵtext(2, "Worker");
|
|
422
433
|
i0.ɵɵelementEnd();
|
|
423
434
|
i0.ɵɵelementStart(3, "span");
|
|
424
|
-
i0.ɵɵconditionalCreate(4,
|
|
435
|
+
i0.ɵɵconditionalCreate(4, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_10_Case_4_Template, 1, 1)(5, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_10_Case_5_Template, 1, 1)(6, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_10_Case_6_Template, 1, 0);
|
|
425
436
|
i0.ɵɵelementEnd()();
|
|
426
437
|
} if (rf & 2) {
|
|
427
438
|
let tmp_11_0;
|
|
@@ -430,16 +441,16 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
430
441
|
i0.ɵɵadvance(4);
|
|
431
442
|
i0.ɵɵconditional((tmp_11_0 = claim_r27.claimEvent) === "claimed" ? 4 : tmp_11_0 === "heartbeat-lost" ? 5 : tmp_11_0 === "reclaimed" ? 6 : -1);
|
|
432
443
|
} }
|
|
433
|
-
function
|
|
444
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Case_2_Template(rf, ctx) { if (rf & 1) {
|
|
434
445
|
i0.ɵɵtext(0, " Path taken ");
|
|
435
446
|
} }
|
|
436
|
-
function
|
|
447
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Case_3_Template(rf, ctx) { if (rf & 1) {
|
|
437
448
|
i0.ɵɵtext(0, " Path not taken ");
|
|
438
449
|
} }
|
|
439
|
-
function
|
|
450
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Case_4_Template(rf, ctx) { if (rf & 1) {
|
|
440
451
|
i0.ɵɵtext(0, " Path can't be answered ");
|
|
441
452
|
} }
|
|
442
|
-
function
|
|
453
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
443
454
|
i0.ɵɵelementStart(0, "code");
|
|
444
455
|
i0.ɵɵtext(1);
|
|
445
456
|
i0.ɵɵelementEnd();
|
|
@@ -448,19 +459,19 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
448
459
|
i0.ɵɵadvance();
|
|
449
460
|
i0.ɵɵtextInterpolate(verdict_r28.conditionText);
|
|
450
461
|
} }
|
|
451
|
-
function
|
|
462
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
452
463
|
i0.ɵɵtext(0);
|
|
453
464
|
} if (rf & 2) {
|
|
454
465
|
const verdict_r28 = i0.ɵɵnextContext().$implicit;
|
|
455
466
|
i0.ɵɵtextInterpolate1(" \u2014 ", verdict_r28.reason, " ");
|
|
456
467
|
} }
|
|
457
|
-
function
|
|
468
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Template(rf, ctx) { if (rf & 1) {
|
|
458
469
|
i0.ɵɵelementStart(0, "div", 88)(1, "span", 89);
|
|
459
|
-
i0.ɵɵconditionalCreate(2,
|
|
470
|
+
i0.ɵɵconditionalCreate(2, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Case_2_Template, 1, 0)(3, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Case_3_Template, 1, 0)(4, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Case_4_Template, 1, 0);
|
|
460
471
|
i0.ɵɵelementEnd();
|
|
461
472
|
i0.ɵɵelementStart(5, "span");
|
|
462
|
-
i0.ɵɵconditionalCreate(6,
|
|
463
|
-
i0.ɵɵconditionalCreate(7,
|
|
473
|
+
i0.ɵɵconditionalCreate(6, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Conditional_6_Template, 2, 1, "code");
|
|
474
|
+
i0.ɵɵconditionalCreate(7, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Conditional_7_Template, 1, 1);
|
|
464
475
|
i0.ɵɵelementEnd()();
|
|
465
476
|
} if (rf & 2) {
|
|
466
477
|
let tmp_19_0;
|
|
@@ -473,7 +484,7 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
473
484
|
i0.ɵɵadvance();
|
|
474
485
|
i0.ɵɵconditional(verdict_r28.reason ? 7 : -1);
|
|
475
486
|
} }
|
|
476
|
-
function
|
|
487
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
477
488
|
i0.ɵɵelementStart(0, "div", 88)(1, "span", 89);
|
|
478
489
|
i0.ɵɵtext(2, "If this step fails");
|
|
479
490
|
i0.ɵɵelementEnd();
|
|
@@ -485,22 +496,22 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
485
496
|
i0.ɵɵadvance(4);
|
|
486
497
|
i0.ɵɵtextInterpolate2("", whatIf_r29.BlockedCount, " step", whatIf_r29.BlockedCount === 1 ? "" : "s", " can no longer run");
|
|
487
498
|
} }
|
|
488
|
-
function
|
|
499
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
489
500
|
const _r30 = i0.ɵɵgetCurrentView();
|
|
490
|
-
i0.ɵɵelementStart(0, "button",
|
|
491
|
-
i0.ɵɵlistener("click", function
|
|
492
|
-
i0.ɵɵelement(1, "i",
|
|
501
|
+
i0.ɵɵelementStart(0, "button", 104);
|
|
502
|
+
i0.ɵɵlistener("click", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r30); const step_r25 = i0.ɵɵnextContext(2); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.OnSkipStep(step_r25)); });
|
|
503
|
+
i0.ɵɵelement(1, "i", 105);
|
|
493
504
|
i0.ɵɵtext(2, " Skip step ");
|
|
494
505
|
i0.ɵɵelementEnd();
|
|
495
506
|
} if (rf & 2) {
|
|
496
507
|
const ctx_r0 = i0.ɵɵnextContext(7);
|
|
497
508
|
i0.ɵɵproperty("disabled", ctx_r0.ControlBusy);
|
|
498
509
|
} }
|
|
499
|
-
function
|
|
510
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
500
511
|
const _r31 = i0.ɵɵgetCurrentView();
|
|
501
512
|
i0.ɵɵelementStart(0, "button", 59);
|
|
502
|
-
i0.ɵɵlistener("click", function
|
|
503
|
-
i0.ɵɵelement(1, "i",
|
|
513
|
+
i0.ɵɵlistener("click", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r31); const step_r25 = i0.ɵɵnextContext(2); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.OpenEditInput(step_r25)); });
|
|
514
|
+
i0.ɵɵelement(1, "i", 106);
|
|
504
515
|
i0.ɵɵtext(2);
|
|
505
516
|
i0.ɵɵelementEnd();
|
|
506
517
|
} if (rf & 2) {
|
|
@@ -510,34 +521,34 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
510
521
|
i0.ɵɵadvance(2);
|
|
511
522
|
i0.ɵɵtextInterpolate1(" ", step_r25.Status === "Failed" ? "Edit input & retry" : "Edit input", " ");
|
|
512
523
|
} }
|
|
513
|
-
function
|
|
524
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
514
525
|
const _r32 = i0.ɵɵgetCurrentView();
|
|
515
526
|
i0.ɵɵelementStart(0, "button", 59);
|
|
516
|
-
i0.ɵɵlistener("click", function
|
|
517
|
-
i0.ɵɵelement(1, "i",
|
|
527
|
+
i0.ɵɵlistener("click", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r32); const step_r25 = i0.ɵɵnextContext(2); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.OnRetryStep(step_r25)); });
|
|
528
|
+
i0.ɵɵelement(1, "i", 107);
|
|
518
529
|
i0.ɵɵtext(2, " Retry ");
|
|
519
530
|
i0.ɵɵelementEnd();
|
|
520
531
|
} if (rf & 2) {
|
|
521
532
|
const ctx_r0 = i0.ɵɵnextContext(7);
|
|
522
533
|
i0.ɵɵproperty("disabled", ctx_r0.ControlBusy);
|
|
523
534
|
} }
|
|
524
|
-
function
|
|
535
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
525
536
|
const _r33 = i0.ɵɵgetCurrentView();
|
|
526
|
-
i0.ɵɵelementStart(0, "button",
|
|
527
|
-
i0.ɵɵlistener("click", function
|
|
528
|
-
i0.ɵɵelement(1, "i",
|
|
537
|
+
i0.ɵɵelementStart(0, "button", 108);
|
|
538
|
+
i0.ɵɵlistener("click", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r33); const step_r25 = i0.ɵɵnextContext(2); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.OpenForceComplete(step_r25)); });
|
|
539
|
+
i0.ɵɵelement(1, "i", 109);
|
|
529
540
|
i0.ɵɵtext(2, " Force complete ");
|
|
530
541
|
i0.ɵɵelementEnd();
|
|
531
542
|
} if (rf & 2) {
|
|
532
543
|
const ctx_r0 = i0.ɵɵnextContext(7);
|
|
533
544
|
i0.ɵɵproperty("disabled", ctx_r0.ControlBusy);
|
|
534
545
|
} }
|
|
535
|
-
function
|
|
546
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
536
547
|
i0.ɵɵelementStart(0, "div", 90);
|
|
537
|
-
i0.ɵɵconditionalCreate(1,
|
|
538
|
-
i0.ɵɵconditionalCreate(2,
|
|
539
|
-
i0.ɵɵconditionalCreate(3,
|
|
540
|
-
i0.ɵɵconditionalCreate(4,
|
|
548
|
+
i0.ɵɵconditionalCreate(1, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_1_Template, 3, 1, "button", 101);
|
|
549
|
+
i0.ɵɵconditionalCreate(2, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_2_Template, 3, 2, "button", 102);
|
|
550
|
+
i0.ɵɵconditionalCreate(3, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_3_Template, 3, 1, "button", 102);
|
|
551
|
+
i0.ɵɵconditionalCreate(4, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Conditional_4_Template, 3, 1, "button", 103);
|
|
541
552
|
i0.ɵɵelementEnd();
|
|
542
553
|
} if (rf & 2) {
|
|
543
554
|
const step_r25 = i0.ɵɵnextContext();
|
|
@@ -551,8 +562,8 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
551
562
|
i0.ɵɵadvance();
|
|
552
563
|
i0.ɵɵconditional(ctx_r0.CanForceComplete(step_r25) ? 4 : -1);
|
|
553
564
|
} }
|
|
554
|
-
function
|
|
555
|
-
i0.ɵɵelementStart(0, "span",
|
|
565
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_15_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
566
|
+
i0.ɵɵelementStart(0, "span", 111);
|
|
556
567
|
i0.ɵɵtext(1);
|
|
557
568
|
i0.ɵɵelementEnd();
|
|
558
569
|
} if (rf & 2) {
|
|
@@ -560,24 +571,24 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
560
571
|
i0.ɵɵadvance();
|
|
561
572
|
i0.ɵɵtextInterpolate(ctx_r0.EditInputError);
|
|
562
573
|
} }
|
|
563
|
-
function
|
|
574
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
564
575
|
const _r34 = i0.ɵɵgetCurrentView();
|
|
565
|
-
i0.ɵɵelementStart(0, "div",
|
|
576
|
+
i0.ɵɵelementStart(0, "div", 98)(1, "span", 89);
|
|
566
577
|
i0.ɵɵtext(2);
|
|
567
578
|
i0.ɵɵelementEnd();
|
|
568
579
|
i0.ɵɵelementStart(3, "p", 91);
|
|
569
580
|
i0.ɵɵtext(4, "Applies to this run only. Invalid JSON is refused here.");
|
|
570
581
|
i0.ɵɵelementEnd();
|
|
571
|
-
i0.ɵɵelementStart(5, "textarea",
|
|
572
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
582
|
+
i0.ɵɵelementStart(5, "textarea", 110);
|
|
583
|
+
i0.ɵɵtwoWayListener("ngModelChange", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_15_Template_textarea_ngModelChange_5_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(6); i0.ɵɵtwoWayBindingSet(ctx_r0.EditInputJson, $event) || (ctx_r0.EditInputJson = $event); return i0.ɵɵresetView($event); });
|
|
573
584
|
i0.ɵɵelementEnd();
|
|
574
|
-
i0.ɵɵconditionalCreate(6,
|
|
585
|
+
i0.ɵɵconditionalCreate(6, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_15_Conditional_6_Template, 2, 1, "span", 111);
|
|
575
586
|
i0.ɵɵelementStart(7, "div", 90)(8, "button", 58);
|
|
576
|
-
i0.ɵɵlistener("click", function
|
|
587
|
+
i0.ɵɵlistener("click", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_15_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r34); const step_r25 = i0.ɵɵnextContext(); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.SubmitEditInput(step_r25)); });
|
|
577
588
|
i0.ɵɵtext(9);
|
|
578
589
|
i0.ɵɵelementEnd();
|
|
579
590
|
i0.ɵɵelementStart(10, "button", 49);
|
|
580
|
-
i0.ɵɵlistener("click", function
|
|
591
|
+
i0.ɵɵlistener("click", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_15_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(6); return i0.ɵɵresetView(ctx_r0.EditInputOpen = false); });
|
|
581
592
|
i0.ɵɵtext(11, "Cancel");
|
|
582
593
|
i0.ɵɵelementEnd()()();
|
|
583
594
|
} if (rf & 2) {
|
|
@@ -594,8 +605,8 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
594
605
|
i0.ɵɵadvance();
|
|
595
606
|
i0.ɵɵtextInterpolate1(" ", step_r25.Status === "Failed" ? "Apply & retry" : "Apply", " ");
|
|
596
607
|
} }
|
|
597
|
-
function
|
|
598
|
-
i0.ɵɵelementStart(0, "span",
|
|
608
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_16_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
609
|
+
i0.ɵɵelementStart(0, "span", 111);
|
|
599
610
|
i0.ɵɵtext(1);
|
|
600
611
|
i0.ɵɵelementEnd();
|
|
601
612
|
} if (rf & 2) {
|
|
@@ -603,27 +614,27 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
603
614
|
i0.ɵɵadvance();
|
|
604
615
|
i0.ɵɵtextInterpolate(ctx_r0.ForceCompleteError);
|
|
605
616
|
} }
|
|
606
|
-
function
|
|
617
|
+
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
607
618
|
const _r35 = i0.ɵɵgetCurrentView();
|
|
608
|
-
i0.ɵɵelementStart(0, "div",
|
|
619
|
+
i0.ɵɵelementStart(0, "div", 99)(1, "span", 89);
|
|
609
620
|
i0.ɵɵtext(2, "Force complete");
|
|
610
621
|
i0.ɵɵelementEnd();
|
|
611
622
|
i0.ɵɵelementStart(3, "p", 91);
|
|
612
623
|
i0.ɵɵtext(4, "Downstream conditions will evaluate against this output as if the step had produced it. Type the step name to confirm.");
|
|
613
624
|
i0.ɵɵelementEnd();
|
|
614
|
-
i0.ɵɵelementStart(5, "textarea",
|
|
615
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
625
|
+
i0.ɵɵelementStart(5, "textarea", 112);
|
|
626
|
+
i0.ɵɵtwoWayListener("ngModelChange", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_16_Template_textarea_ngModelChange_5_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r0 = i0.ɵɵnextContext(6); i0.ɵɵtwoWayBindingSet(ctx_r0.ForceCompleteJson, $event) || (ctx_r0.ForceCompleteJson = $event); return i0.ɵɵresetView($event); });
|
|
616
627
|
i0.ɵɵelementEnd();
|
|
617
|
-
i0.ɵɵelementStart(6, "input",
|
|
618
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
628
|
+
i0.ɵɵelementStart(6, "input", 113);
|
|
629
|
+
i0.ɵɵtwoWayListener("ngModelChange", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_16_Template_input_ngModelChange_6_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r0 = i0.ɵɵnextContext(6); i0.ɵɵtwoWayBindingSet(ctx_r0.ForceCompleteName, $event) || (ctx_r0.ForceCompleteName = $event); return i0.ɵɵresetView($event); });
|
|
619
630
|
i0.ɵɵelementEnd();
|
|
620
|
-
i0.ɵɵconditionalCreate(7,
|
|
621
|
-
i0.ɵɵelementStart(8, "div", 90)(9, "button",
|
|
622
|
-
i0.ɵɵlistener("click", function
|
|
631
|
+
i0.ɵɵconditionalCreate(7, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_16_Conditional_7_Template, 2, 1, "span", 111);
|
|
632
|
+
i0.ɵɵelementStart(8, "div", 90)(9, "button", 108);
|
|
633
|
+
i0.ɵɵlistener("click", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_16_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r35); const step_r25 = i0.ɵɵnextContext(); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.SubmitForceComplete(step_r25)); });
|
|
623
634
|
i0.ɵɵtext(10, "Force complete");
|
|
624
635
|
i0.ɵɵelementEnd();
|
|
625
636
|
i0.ɵɵelementStart(11, "button", 49);
|
|
626
|
-
i0.ɵɵlistener("click", function
|
|
637
|
+
i0.ɵɵlistener("click", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_16_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r35); const ctx_r0 = i0.ɵɵnextContext(6); return i0.ɵɵresetView(ctx_r0.ForceCompleteOpen = false); });
|
|
627
638
|
i0.ɵɵtext(12, "Cancel");
|
|
628
639
|
i0.ɵɵelementEnd()()();
|
|
629
640
|
} if (rf & 2) {
|
|
@@ -647,23 +658,25 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
647
658
|
i0.ɵɵelementStart(4, "span", 36);
|
|
648
659
|
i0.ɵɵtext(5);
|
|
649
660
|
i0.ɵɵelementEnd()();
|
|
650
|
-
i0.ɵɵ
|
|
651
|
-
i0.ɵɵ
|
|
652
|
-
i0.ɵɵ
|
|
653
|
-
i0.ɵɵ
|
|
654
|
-
i0.ɵɵ
|
|
655
|
-
i0.ɵɵconditionalCreate(9, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_9_Template,
|
|
656
|
-
i0.ɵɵ
|
|
657
|
-
i0.ɵɵ
|
|
658
|
-
i0.ɵɵconditionalCreate(13, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_13_Template, 5,
|
|
659
|
-
i0.ɵɵconditionalCreate(14, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Template,
|
|
660
|
-
i0.ɵɵconditionalCreate(15, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_15_Template,
|
|
661
|
-
i0.ɵɵ
|
|
661
|
+
i0.ɵɵconditionalCreate(6, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_6_Template, 5, 1, "div", 94);
|
|
662
|
+
i0.ɵɵelementStart(7, "button", 95);
|
|
663
|
+
i0.ɵɵlistener("click", function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Template_button_click_7_listener() { const step_r25 = i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.OnBreakpointToggled({ TaskID: step_r25.ID, Enabled: !ctx_r0.HasBreakpoint(step_r25.ID) })); });
|
|
664
|
+
i0.ɵɵelement(8, "i", 96);
|
|
665
|
+
i0.ɵɵelementEnd();
|
|
666
|
+
i0.ɵɵconditionalCreate(9, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_9_Template, 6, 2, "div", 88);
|
|
667
|
+
i0.ɵɵconditionalCreate(10, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_10_Template, 7, 3, "div", 97);
|
|
668
|
+
i0.ɵɵrepeaterCreate(11, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_For_12_Template, 8, 4, "div", 88, _forTrack2);
|
|
669
|
+
i0.ɵɵconditionalCreate(13, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_13_Template, 5, 2, "div", 88);
|
|
670
|
+
i0.ɵɵconditionalCreate(14, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_14_Template, 5, 4, "div", 90);
|
|
671
|
+
i0.ɵɵconditionalCreate(15, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_15_Template, 12, 5, "div", 98);
|
|
672
|
+
i0.ɵɵconditionalCreate(16, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Conditional_16_Template, 13, 5, "div", 99);
|
|
673
|
+
i0.ɵɵelement(17, "mj-task-graph-variables", 100);
|
|
662
674
|
i0.ɵɵelementEnd();
|
|
663
675
|
} if (rf & 2) {
|
|
664
|
-
let
|
|
676
|
+
let tmp_11_0;
|
|
665
677
|
let tmp_18_0;
|
|
666
|
-
let
|
|
678
|
+
let tmp_19_0;
|
|
679
|
+
let tmp_21_0;
|
|
667
680
|
const step_r25 = ctx;
|
|
668
681
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
669
682
|
i0.ɵɵadvance(3);
|
|
@@ -673,25 +686,27 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
673
686
|
i0.ɵɵadvance();
|
|
674
687
|
i0.ɵɵtextInterpolate(step_r25.Status);
|
|
675
688
|
i0.ɵɵadvance();
|
|
689
|
+
i0.ɵɵconditional((tmp_11_0 = ctx_r0.SelectedStepFailureReason) ? 6 : -1, tmp_11_0);
|
|
690
|
+
i0.ɵɵadvance();
|
|
676
691
|
i0.ɵɵclassProp("wfr-bp-on", ctx_r0.HasBreakpoint(step_r25.ID));
|
|
677
692
|
i0.ɵɵproperty("disabled", ctx_r0.ControlBusy)("title", ctx_r0.HasBreakpoint(step_r25.ID) ? "Remove breakpoint" : "Break before this step");
|
|
678
693
|
i0.ɵɵattribute("aria-pressed", ctx_r0.HasBreakpoint(step_r25.ID));
|
|
679
694
|
i0.ɵɵadvance();
|
|
680
695
|
i0.ɵɵclassProp("fa-solid", ctx_r0.HasBreakpoint(step_r25.ID))("fa-regular", !ctx_r0.HasBreakpoint(step_r25.ID));
|
|
681
696
|
i0.ɵɵadvance();
|
|
682
|
-
i0.ɵɵconditional((
|
|
697
|
+
i0.ɵɵconditional((tmp_18_0 = ctx_r0.SelectedStepProgress) ? 9 : -1, tmp_18_0);
|
|
683
698
|
i0.ɵɵadvance();
|
|
684
|
-
i0.ɵɵconditional((
|
|
699
|
+
i0.ɵɵconditional((tmp_19_0 = ctx_r0.SelectedStepClaim) ? 10 : -1, tmp_19_0);
|
|
685
700
|
i0.ɵɵadvance();
|
|
686
701
|
i0.ɵɵrepeater(ctx_r0.SelectedStepVerdicts);
|
|
687
702
|
i0.ɵɵadvance(2);
|
|
688
|
-
i0.ɵɵconditional((
|
|
703
|
+
i0.ɵɵconditional((tmp_21_0 = ctx_r0.SelectedStepWhatIf) ? 13 : -1, tmp_21_0);
|
|
689
704
|
i0.ɵɵadvance();
|
|
690
|
-
i0.ɵɵconditional(step_r25.Status === "Pending" || step_r25.Status === "Failed" || ctx_r0.CanForceComplete(step_r25) ?
|
|
705
|
+
i0.ɵɵconditional(step_r25.Status === "Pending" || step_r25.Status === "Failed" || ctx_r0.CanForceComplete(step_r25) ? 14 : -1);
|
|
691
706
|
i0.ɵɵadvance();
|
|
692
|
-
i0.ɵɵconditional(ctx_r0.EditInputOpen ?
|
|
707
|
+
i0.ɵɵconditional(ctx_r0.EditInputOpen ? 15 : -1);
|
|
693
708
|
i0.ɵɵadvance();
|
|
694
|
-
i0.ɵɵconditional(ctx_r0.ForceCompleteOpen ?
|
|
709
|
+
i0.ɵɵconditional(ctx_r0.ForceCompleteOpen ? 16 : -1);
|
|
695
710
|
i0.ɵɵadvance();
|
|
696
711
|
i0.ɵɵproperty("InputPayload", ctx_r0.StepPayload(step_r25, "InputPayload"))("OutputPayload", ctx_r0.StepPayload(step_r25, "OutputPayload"))("Invocation", ctx_r0.Invocation);
|
|
697
712
|
} }
|
|
@@ -702,7 +717,7 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
702
717
|
i0.ɵɵelementStart(0, "div", 79);
|
|
703
718
|
i0.ɵɵrepeaterCreate(1, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_For_2_Template, 5, 5, "button", 80, _forTrack0);
|
|
704
719
|
i0.ɵɵelementEnd();
|
|
705
|
-
i0.ɵɵconditionalCreate(3, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_3_Template, 12, 5, "div", 81)(4, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Template,
|
|
720
|
+
i0.ɵɵconditionalCreate(3, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_3_Template, 12, 5, "div", 81)(4, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_4_Template, 18, 22, "div", 81)(5, WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_20_Conditional_11_Conditional_5_Template, 1, 0, "mj-empty-state", 82);
|
|
706
721
|
} if (rf & 2) {
|
|
707
722
|
let tmp_7_0;
|
|
708
723
|
const ctx_r0 = i0.ɵɵnextContext(4);
|
|
@@ -747,7 +762,7 @@ function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional
|
|
|
747
762
|
} }
|
|
748
763
|
function WorkflowRunsResourceComponent_Conditional_16_Conditional_22_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
749
764
|
i0.ɵɵelementStart(0, "div", 48);
|
|
750
|
-
i0.ɵɵelement(1, "mj-code-editor",
|
|
765
|
+
i0.ɵɵelement(1, "mj-code-editor", 114);
|
|
751
766
|
i0.ɵɵelementEnd();
|
|
752
767
|
} if (rf & 2) {
|
|
753
768
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -1530,6 +1545,7 @@ let WorkflowRunsResourceComponent = class WorkflowRunsResourceComponent extends
|
|
|
1530
1545
|
StepType: t.StepType,
|
|
1531
1546
|
StartedAt: t.StartedAt,
|
|
1532
1547
|
CompletedAt: t.CompletedAt,
|
|
1548
|
+
ErrorMessage: t.ErrorMessage,
|
|
1533
1549
|
Record: t.GetAll(),
|
|
1534
1550
|
}));
|
|
1535
1551
|
}
|
|
@@ -1565,6 +1581,11 @@ let WorkflowRunsResourceComponent = class WorkflowRunsResourceComponent extends
|
|
|
1565
1581
|
get SelectedStep() {
|
|
1566
1582
|
return this.SelectedSteps.find((s) => UUIDsEqual(s.ID, this.SelectedStepID ?? '')) ?? null;
|
|
1567
1583
|
}
|
|
1584
|
+
/** Why the selected step failed, or `null` — the inspector otherwise shows FAILED with no reason. */
|
|
1585
|
+
get SelectedStepFailureReason() {
|
|
1586
|
+
const step = this.SelectedStep;
|
|
1587
|
+
return step ? StepFailureReason(step.Status, step.ErrorMessage) : null;
|
|
1588
|
+
}
|
|
1568
1589
|
/** The selected step, as formatted JSON for the viewer. */
|
|
1569
1590
|
get SelectedStepJson() {
|
|
1570
1591
|
const step = this.SelectedStep;
|
|
@@ -1775,7 +1796,7 @@ let WorkflowRunsResourceComponent = class WorkflowRunsResourceComponent extends
|
|
|
1775
1796
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.GraphDebug = _t.first);
|
|
1776
1797
|
} }, hostBindings: function WorkflowRunsResourceComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
1777
1798
|
i0.ɵɵlistener("resize", function WorkflowRunsResourceComponent_resize_HostBindingHandler() { return ctx.onViewportResized(); }, i0.ɵɵresolveWindow);
|
|
1778
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 17, vars: 4, consts: [["GraphDebug", ""], ["Title", "Runs", "Icon", "fa-solid fa-timeline", "Subtitle", "Every workflow that has run \u2014 however it was started."], ["meta", ""], ["Label", "runs", 3, "Count", "Total"], ["actions", ""], [3, "Clicked", "Loading"], ["toolbar", ""], ["Placeholder", "Search runs", 3, "ValueChange", "Value"], [1, "wfr-status-filters"], ["type", "button", "mjButton", "", "size", "sm", 3, "variant"], ["text", "Loading runs..."], ["Variant", "error", 3, "Message"], ["Icon", "fa-solid fa-timeline", "Title", "Nothing has run yet", "Message", "When a workflow runs \u2014 started by hand, on a schedule, or by an agent \u2014 it will appear here."], ["Icon", "fa-solid fa-filter", "Title", "No runs match", "Message", "Nothing matches the current filter. Clear it to see everything that has run."], ["direction", "horizontal", "unit", "percent", 1, "wfr-split", 3, "gutterSize", "disabled"], ["type", "button", "mjButton", "", "size", "sm", 3, "click", "variant"], ["direction", "horizontal", "unit", "percent", 1, "wfr-split", 3, "dragEnd", "gutterSize", "disabled"], [3, "size", "minSize"], [1, "wfr-list"], ["role", "row", 1, "wfr-head"], ["type", "button", 1, "wfr-head-cell", "wfr-col-name", 3, "click"], ["aria-hidden", "true", 3, "ngClass"], ["type", "button", 1, "wfr-head-cell", "wfr-col-time", 3, "click"], ["type", "button", 1, "wfr-head-cell", "wfr-col-duration", 3, "click"], ["type", "button", 1, "wfr-head-cell", "wfr-col-status", 3, "click"], ["type", "button", 1, "wfr-row", 3, "wfr-row-selected"], [3, "size", "minSize", "visible"], [1, "wfr-detail"], ["type", "button", 1, "wfr-row", 3, "click"], [1, "wfr-col-name", "wfr-row-name"], [1, "wfr-col-time"], [1, "wfr-col-duration"], [1, "wfr-col-status", "wfr-row-status"], [1, "wfr-detail-head"], [1, "wfr-detail-title"], [1, "wfr-detail-name"], [1, "wfr-row-status"], [1, "wfr-detail-actions"], ["mjButton", "", "variant", "flat", "size", "sm"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "title"], ["mjButton", "", "variant", "flat", "size", "sm", "aria-label", "Close", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], ["role", "tablist", 1, "wfr-detail-tabs"], ["type", "button", 1, "wfr-tab", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-diagram-project"], ["aria-hidden", "true", 1, "fa-solid", "fa-code"], ["role", "status", 1, "wfr-stall"], ["unit", "percent", 1, "wfr-graph-split", 3, "direction", "gutterSize"], [1, "wfr-json-pane"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-up-right-from-square"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid"], [1, "wfr-stall-body"], ["aria-hidden", "true", 1, "fa-solid", "fa-triangle-exclamation"], [1, "wfr-stall-copy"], [1, "wfr-stall-reason"], [1, "wfr-stall-actions"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click", "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], ["unit", "percent", 1, "wfr-graph-split", 3, "dragEnd", "direction", "gutterSize"], [1, "wfr-graph-pane"], ["Height", "100%", 3, "NodeSelected", "ConnectionSelected", "LegendToggled", "Settled", "Frame", "PausedChange", "Provider", "ParentTaskID", "WorkflowName", "LiveUpdates", "ReplayAt", "ShowLegend"], [1, "wfr-replay"], ["aria-label", "Armed breakpoints", 1, "wfr-bp-bar"], ["aria-label", "Engine activity", 1, "wfr-engine"], [1, "wfr-steps-pane"], ["text", "Loading steps..."], ["aria-hidden", "true", 1, "fa-solid", "fa-clock-rotate-left"], ["type", "range", "min", "0", "max", "100", "step", "1", "aria-label", "Replay position", 3, "input", "value"], [1, "wfr-chip", "wfr-chip-paused"], ["type", "button", 1, "wfr-chip", "wfr-chip-break"], ["aria-hidden", "true", 1, "fa-solid", "fa-pause"], ["type", "button", 1, "wfr-chip", "wfr-chip-break", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle"], ["role", "button", "tabindex", "0", "aria-label", "Remove breakpoint", 1, "wfr-chip-x", 3, "click"], [1, "wfr-tick", 3, "wfr-tick-held"], [1, "wfr-tick", "wfr-tick-paused"], [1, "wfr-tick"], [1, "wfr-step-list"], ["type", "button", 1, "wfr-step", 3, "wfr-step-selected"], [1, "wfr-step-json"], ["Size", "compact", "Icon", "fa-solid fa-hand-pointer", "Title", "Select a step", "Message", "Click a step on the canvas or in the list to see everything it recorded."], ["type", "button", 1, "wfr-step", 3, "click"], [1, "wfr-step-name"], [1, "wfr-step-meta"], [1, "wfr-step-json-head"], [1, "wfr-chip", "wfr-chip-forced"], [1, "wfr-insp-card"], [1, "wfr-insp-label"], [1, "wfr-insp-actions"], [1, "wfr-insp-hint"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "disabled"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click", "disabled"], ["type", "button", 1, "wfr-bp", 3, "click", "disabled", "title"], ["aria-hidden", "true", 1, "fa-circle"], [1, "wfr-insp-card", 3, "wfr-insp-bad"], [1, "wfr-editor-card"], [1, "wfr-editor-card", "wfr-editor-danger"], [3, "InputPayload", "OutputPayload", "Invocation"], ["mjButton", "", "variant", "secondary", "size", "sm", "title", "Declare this step not-taken; later steps proceed", 3, "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "disabled"], ["mjButton", "", "variant", "danger", "size", "sm", 3, "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", "title", "Declare this step not-taken; later steps proceed", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-forward"], ["aria-hidden", "true", 1, "fa-solid", "fa-pen-to-square"], ["aria-hidden", "true", 1, "fa-solid", "fa-rotate-right"], ["mjButton", "", "variant", "danger", "size", "sm", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-flag-checkered"], ["rows", "8", "spellcheck", "false", 1, "mj-textarea", "wfr-json-edit", 3, "ngModelChange", "ngModel"], [1, "wfr-editor-error"], ["rows", "6", "spellcheck", "false", 1, "mj-textarea", "wfr-json-edit", 3, "ngModelChange", "ngModel"], ["type", "text", 1, "mj-input", 3, "ngModelChange", "ngModel", "placeholder"], [2, "width", "100%", 3, "ngModel", "language", "readonly"]], template: function WorkflowRunsResourceComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1799
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 17, vars: 4, consts: [["GraphDebug", ""], ["Title", "Runs", "Icon", "fa-solid fa-timeline", "Subtitle", "Every workflow that has run \u2014 however it was started."], ["meta", ""], ["Label", "runs", 3, "Count", "Total"], ["actions", ""], [3, "Clicked", "Loading"], ["toolbar", ""], ["Placeholder", "Search runs", 3, "ValueChange", "Value"], [1, "wfr-status-filters"], ["type", "button", "mjButton", "", "size", "sm", 3, "variant"], ["text", "Loading runs..."], ["Variant", "error", 3, "Message"], ["Icon", "fa-solid fa-timeline", "Title", "Nothing has run yet", "Message", "When a workflow runs \u2014 started by hand, on a schedule, or by an agent \u2014 it will appear here."], ["Icon", "fa-solid fa-filter", "Title", "No runs match", "Message", "Nothing matches the current filter. Clear it to see everything that has run."], ["direction", "horizontal", "unit", "percent", 1, "wfr-split", 3, "gutterSize", "disabled"], ["type", "button", "mjButton", "", "size", "sm", 3, "click", "variant"], ["direction", "horizontal", "unit", "percent", 1, "wfr-split", 3, "dragEnd", "gutterSize", "disabled"], [3, "size", "minSize"], [1, "wfr-list"], ["role", "row", 1, "wfr-head"], ["type", "button", 1, "wfr-head-cell", "wfr-col-name", 3, "click"], ["aria-hidden", "true", 3, "ngClass"], ["type", "button", 1, "wfr-head-cell", "wfr-col-time", 3, "click"], ["type", "button", 1, "wfr-head-cell", "wfr-col-duration", 3, "click"], ["type", "button", 1, "wfr-head-cell", "wfr-col-status", 3, "click"], ["type", "button", 1, "wfr-row", 3, "wfr-row-selected"], [3, "size", "minSize", "visible"], [1, "wfr-detail"], ["type", "button", 1, "wfr-row", 3, "click"], [1, "wfr-col-name", "wfr-row-name"], [1, "wfr-col-time"], [1, "wfr-col-duration"], [1, "wfr-col-status", "wfr-row-status"], [1, "wfr-detail-head"], [1, "wfr-detail-title"], [1, "wfr-detail-name"], [1, "wfr-row-status"], [1, "wfr-detail-actions"], ["mjButton", "", "variant", "flat", "size", "sm"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "title"], ["mjButton", "", "variant", "flat", "size", "sm", "aria-label", "Close", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], ["role", "tablist", 1, "wfr-detail-tabs"], ["type", "button", 1, "wfr-tab", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-diagram-project"], ["aria-hidden", "true", 1, "fa-solid", "fa-code"], ["role", "status", 1, "wfr-stall"], ["unit", "percent", 1, "wfr-graph-split", 3, "direction", "gutterSize"], [1, "wfr-json-pane"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-up-right-from-square"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid"], [1, "wfr-stall-body"], ["aria-hidden", "true", 1, "fa-solid", "fa-triangle-exclamation"], [1, "wfr-stall-copy"], [1, "wfr-stall-reason"], [1, "wfr-stall-actions"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click", "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], ["unit", "percent", 1, "wfr-graph-split", 3, "dragEnd", "direction", "gutterSize"], [1, "wfr-graph-pane"], ["Height", "100%", 3, "NodeSelected", "ConnectionSelected", "LegendToggled", "Settled", "Frame", "PausedChange", "Provider", "ParentTaskID", "WorkflowName", "LiveUpdates", "ReplayAt", "ShowLegend"], [1, "wfr-replay"], ["aria-label", "Armed breakpoints", 1, "wfr-bp-bar"], ["aria-label", "Engine activity", 1, "wfr-engine"], [1, "wfr-steps-pane"], ["text", "Loading steps..."], ["aria-hidden", "true", 1, "fa-solid", "fa-clock-rotate-left"], ["type", "range", "min", "0", "max", "100", "step", "1", "aria-label", "Replay position", 3, "input", "value"], [1, "wfr-chip", "wfr-chip-paused"], ["type", "button", 1, "wfr-chip", "wfr-chip-break"], ["aria-hidden", "true", 1, "fa-solid", "fa-pause"], ["type", "button", 1, "wfr-chip", "wfr-chip-break", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle"], ["role", "button", "tabindex", "0", "aria-label", "Remove breakpoint", 1, "wfr-chip-x", 3, "click"], [1, "wfr-tick", 3, "wfr-tick-held"], [1, "wfr-tick", "wfr-tick-paused"], [1, "wfr-tick"], [1, "wfr-step-list"], ["type", "button", 1, "wfr-step", 3, "wfr-step-selected"], [1, "wfr-step-json"], ["Size", "compact", "Icon", "fa-solid fa-hand-pointer", "Title", "Select a step", "Message", "Click a step on the canvas or in the list to see everything it recorded."], ["type", "button", 1, "wfr-step", 3, "click"], [1, "wfr-step-name"], [1, "wfr-step-meta"], [1, "wfr-step-json-head"], [1, "wfr-chip", "wfr-chip-forced"], [1, "wfr-insp-card"], [1, "wfr-insp-label"], [1, "wfr-insp-actions"], [1, "wfr-insp-hint"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "disabled"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click", "disabled"], ["role", "status", 1, "wfr-insp-card", "wfr-insp-failure"], ["type", "button", 1, "wfr-bp", 3, "click", "disabled", "title"], ["aria-hidden", "true", 1, "fa-circle"], [1, "wfr-insp-card", 3, "wfr-insp-bad"], [1, "wfr-editor-card"], [1, "wfr-editor-card", "wfr-editor-danger"], [3, "InputPayload", "OutputPayload", "Invocation"], ["mjButton", "", "variant", "secondary", "size", "sm", "title", "Declare this step not-taken; later steps proceed", 3, "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "disabled"], ["mjButton", "", "variant", "danger", "size", "sm", 3, "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", "title", "Declare this step not-taken; later steps proceed", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-forward"], ["aria-hidden", "true", 1, "fa-solid", "fa-pen-to-square"], ["aria-hidden", "true", 1, "fa-solid", "fa-rotate-right"], ["mjButton", "", "variant", "danger", "size", "sm", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-flag-checkered"], ["rows", "8", "spellcheck", "false", 1, "mj-textarea", "wfr-json-edit", 3, "ngModelChange", "ngModel"], [1, "wfr-editor-error"], ["rows", "6", "spellcheck", "false", 1, "mj-textarea", "wfr-json-edit", 3, "ngModelChange", "ngModel"], ["type", "text", 1, "mj-input", 3, "ngModelChange", "ngModel", "placeholder"], [2, "width", "100%", 3, "ngModel", "language", "readonly"]], template: function WorkflowRunsResourceComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1779
1800
|
i0.ɵɵelementStart(0, "mj-page-layout")(1, "mj-page-header", 1)(2, "div", 2);
|
|
1780
1801
|
i0.ɵɵconditionalCreate(3, WorkflowRunsResourceComponent_Conditional_3_Template, 1, 2, "mj-stat-badge", 3);
|
|
1781
1802
|
i0.ɵɵelementEnd();
|
|
@@ -1802,7 +1823,7 @@ let WorkflowRunsResourceComponent = class WorkflowRunsResourceComponent extends
|
|
|
1802
1823
|
i0.ɵɵrepeater(ctx.StatusFilters);
|
|
1803
1824
|
i0.ɵɵadvance(3);
|
|
1804
1825
|
i0.ɵɵconditional(ctx.IsLoading ? 12 : ctx.LoadError ? 13 : ctx.Runs.length === 0 ? 14 : ctx.VisibleRuns.length === 0 ? 15 : 16);
|
|
1805
|
-
} }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJAlertComponent, i3.MJButtonDirective, i3.MJEmptyStateComponent, i3.MJPageBodyComponent, i3.MJPageHeaderComponent, i3.MJPageLayoutComponent, i3.MJPageSearchComponent, i3.MJRefreshButtonComponent, i3.MJStatBadgeComponent, i4.LoadingComponent, i5.TaskGraphVariablesComponent, i5.TaskGraphDebuggerComponent, i6.CodeEditorComponent, i7.SplitComponent, i7.SplitAreaComponent, i1.DatePipe], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.wfr-status-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-1);\n align-items: center;\n}\n\n\n\n.wfr-split[_ngcontent-%COMP%] {\n height: 100%;\n min-height: 0;\n}\n\n\n[_nghost-%COMP%] .wfr-split > .as-split-gutter, \n[_nghost-%COMP%] .wfr-graph-split > .as-split-gutter {\n background: transparent !important;\n position: relative;\n}\n\n[_nghost-%COMP%] .wfr-split > .as-split-gutter::after, \n[_nghost-%COMP%] .wfr-graph-split > .as-split-gutter::after {\n content: '';\n position: absolute;\n inset: 0;\n margin: auto;\n background: var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n}\n\n[_nghost-%COMP%] .wfr-split.as-horizontal > .as-split-gutter::after, \n[_nghost-%COMP%] .wfr-graph-split.as-horizontal > .as-split-gutter::after {\n width: 2px;\n}\n\n[_nghost-%COMP%] .wfr-graph-split.as-vertical > .as-split-gutter::after {\n height: 2px;\n}\n\n[_nghost-%COMP%] .wfr-split > .as-split-gutter:hover::after, \n[_nghost-%COMP%] .wfr-graph-split > .as-split-gutter:hover::after {\n background: var(--mj-brand-primary);\n}\n\n\n\n\n.wfr-graph-split[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-height: 0;\n}\n\n.wfr-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n overflow-y: auto;\n min-height: 0;\n}\n\n.wfr-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-2) var(--mj-space-3);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n text-align: left;\n cursor: pointer;\n color: var(--mj-text-primary);\n}\n\n.wfr-row[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.wfr-row[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.wfr-row-selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.wfr-row-main[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.wfr-row-name[_ngcontent-%COMP%] {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wfr-row-when[_ngcontent-%COMP%] {\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n}\n\n.wfr-row-status[_ngcontent-%COMP%] {\n flex: none;\n font-size: var(--mj-font-size-xs);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n padding: 2px var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n\n\n\n.wfr-row-status[data-status='Complete'][_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 40%, transparent);\n}\n\n.wfr-row-status[data-status='Failed'][_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, transparent);\n}\n\n.wfr-row-status[data-status='Running'][_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.wfr-detail[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n \n\n height: 100%;\n min-height: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n}\n\n.wfr-detail-head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-3);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.wfr-detail-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n min-width: 0;\n}\n\n.wfr-detail-name[_ngcontent-%COMP%] {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wfr-detail-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n flex: none;\n}\n\n\n\n\n\n\n\n.wfr-head[_ngcontent-%COMP%], \n.wfr-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 1.3fr) minmax(0, 1.3fr) minmax(0, 0.7fr) minmax(0, 0.9fr);\n gap: var(--mj-space-2);\n align-items: center;\n}\n\n.wfr-head[_ngcontent-%COMP%] {\n position: sticky;\n top: 0;\n z-index: 1;\n padding: 0 var(--mj-space-3) var(--mj-space-1);\n background: var(--mj-bg-page);\n}\n\n.wfr-head-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: none;\n border: none;\n padding: var(--mj-space-1) 0;\n font-size: var(--mj-font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-secondary);\n cursor: pointer;\n text-align: left;\n}\n\n.wfr-head-cell[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.wfr-head-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n opacity: 0.65;\n font-size: 0.85em;\n}\n\n.wfr-col-time[_ngcontent-%COMP%], \n.wfr-col-duration[_ngcontent-%COMP%] {\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.wfr-col-status[_ngcontent-%COMP%] {\n justify-self: start;\n}\n\n\n\n\n.wfr-detail-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-1);\n padding: 0 var(--mj-space-3);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.wfr-tab[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n padding: var(--mj-space-2) var(--mj-space-2);\n font-size: var(--mj-font-size-sm);\n font-weight: 600;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.wfr-tab-active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.wfr-graph-pane[_ngcontent-%COMP%] {\n height: 100%;\n min-height: 12rem;\n}\n\n.wfr-steps-pane[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n border-left: 1px solid var(--mj-border-default);\n overflow: hidden;\n}\n\n\n[_nghost-%COMP%] .as-vertical .wfr-steps-pane {\n border-left: none;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.wfr-step-list[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mj-space-1);\n padding: var(--mj-space-2);\n border-bottom: 1px solid var(--mj-border-default);\n max-height: 8rem;\n overflow-y: auto;\n flex: none;\n}\n\n.wfr-step[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: var(--mj-space-1) var(--mj-space-2);\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-primary);\n font-size: var(--mj-font-size-sm);\n cursor: pointer;\n text-align: left;\n}\n\n.wfr-step[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.wfr-step-selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n\n.wfr-step[data-status='Skipped'][_ngcontent-%COMP%] .wfr-step-name[_ngcontent-%COMP%] {\n text-decoration: line-through;\n color: var(--mj-text-secondary);\n}\n\n.wfr-step-name[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.wfr-step-meta[_ngcontent-%COMP%] {\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-secondary);\n}\n\n.wfr-step-json[_ngcontent-%COMP%], \n.wfr-json-pane[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: auto;\n}\n\n.wfr-step-json-head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n padding: var(--mj-space-1) var(--mj-space-3);\n font-weight: 600;\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n flex: none;\n}\n\n\n\n.wfr-stall[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 8px 12px;\n margin: 0 12px 8px;\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 45%, var(--mj-border-default));\n border-left: 4px solid var(--mj-status-warning);\n border-radius: var(--mj-radius-md);\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n font-size: var(--mj-font-size-sm);\n}\n.wfr-stall-body[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n.wfr-stall[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n.wfr-stall-copy[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.wfr-stall-copy[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n}\n.wfr-stall-reason[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.wfr-stall-actions[_ngcontent-%COMP%] { display: flex; flex-wrap: wrap; gap: 6px; }\n\n.wfr-replay[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n}\n.wfr-replay[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.wfr-replay[_ngcontent-%COMP%] input[type='range'][_ngcontent-%COMP%] { flex: 1; accent-color: var(--mj-brand-primary); }\n\n.wfr-engine[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n overflow-x: auto;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n}\n.wfr-tick[_ngcontent-%COMP%] {\n flex: none;\n padding: 3px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n white-space: nowrap;\n}\n.wfr-tick-held[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-status-warning, #d97706) 45%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-status-warning, #d97706) 8%, var(--mj-bg-surface));\n}\n.wfr-tick-paused[_ngcontent-%COMP%] { color: var(--mj-brand-primary); border-color: var(--mj-border-strong); }\n\n.wfr-insp-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 7px 10px;\n margin: 0 0 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-primary);\n}\n.wfr-insp-card[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n}\n.wfr-insp-label[_ngcontent-%COMP%] {\n font-size: var(--mj-font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-secondary);\n}\n.wfr-insp-card[data-verdict='held'][_ngcontent-%COMP%], \n.wfr-insp-bad[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-status-warning, #d97706) 45%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-status-warning, #d97706) 8%, var(--mj-bg-surface));\n}\n.wfr-insp-card[data-verdict='satisfied'][_ngcontent-%COMP%] .wfr-insp-label[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.wfr-insp-actions[_ngcontent-%COMP%] { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 8px; }\n.wfr-insp-hint[_ngcontent-%COMP%] {\n margin: 0 0 8px;\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-muted);\n}\n\n.wfr-bp-bar[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n}\n.wfr-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 2px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: var(--mj-font-size-xs);\n cursor: pointer;\n}\n.wfr-chip-break[_ngcontent-%COMP%] { color: var(--mj-status-error); border-color: color-mix(in srgb, var(--mj-status-error) 40%, transparent); }\n.wfr-chip-break[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 7px; }\n.wfr-chip-paused[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n cursor: default;\n}\n.wfr-chip-forced[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n border-color: color-mix(in srgb, var(--mj-status-warning) 40%, transparent);\n cursor: default;\n}\n.wfr-chip-x[_ngcontent-%COMP%] {\n font-size: 14px;\n line-height: 1;\n padding: 0 2px;\n}\n.wfr-chip-x[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); }\n\n.wfr-bp[_ngcontent-%COMP%] {\n width: 22px;\n height: 22px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin: 0 0 8px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n}\n.wfr-bp[_ngcontent-%COMP%]:hover { color: var(--mj-status-error); }\n.wfr-bp-on[_ngcontent-%COMP%], \n.wfr-bp-on[_ngcontent-%COMP%]:hover { color: var(--mj-status-error); }\n.wfr-bp[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 10px; }\n.wfr-bp[_ngcontent-%COMP%]:disabled { opacity: 0.45; cursor: default; }\n\n.wfr-editor-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px;\n margin: 0 0 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-card);\n}\n.wfr-editor-danger[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-border-default));\n}\n.wfr-json-edit[_ngcontent-%COMP%] {\n width: 100%;\n min-height: 120px;\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n resize: vertical;\n}\n.wfr-editor-error[_ngcontent-%COMP%] { color: var(--mj-status-error); font-size: var(--mj-font-size-xs); }"], changeDetection: 0 });
|
|
1826
|
+
} }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJAlertComponent, i3.MJButtonDirective, i3.MJEmptyStateComponent, i3.MJPageBodyComponent, i3.MJPageHeaderComponent, i3.MJPageLayoutComponent, i3.MJPageSearchComponent, i3.MJRefreshButtonComponent, i3.MJStatBadgeComponent, i4.LoadingComponent, i5.TaskGraphVariablesComponent, i5.TaskGraphDebuggerComponent, i6.CodeEditorComponent, i7.SplitComponent, i7.SplitAreaComponent, i1.DatePipe], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.wfr-status-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-1);\n align-items: center;\n}\n\n\n\n.wfr-split[_ngcontent-%COMP%] {\n height: 100%;\n min-height: 0;\n}\n\n\n[_nghost-%COMP%] .wfr-split > .as-split-gutter, \n[_nghost-%COMP%] .wfr-graph-split > .as-split-gutter {\n background: transparent !important;\n position: relative;\n}\n\n[_nghost-%COMP%] .wfr-split > .as-split-gutter::after, \n[_nghost-%COMP%] .wfr-graph-split > .as-split-gutter::after {\n content: '';\n position: absolute;\n inset: 0;\n margin: auto;\n background: var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n}\n\n[_nghost-%COMP%] .wfr-split.as-horizontal > .as-split-gutter::after, \n[_nghost-%COMP%] .wfr-graph-split.as-horizontal > .as-split-gutter::after {\n width: 2px;\n}\n\n[_nghost-%COMP%] .wfr-graph-split.as-vertical > .as-split-gutter::after {\n height: 2px;\n}\n\n[_nghost-%COMP%] .wfr-split > .as-split-gutter:hover::after, \n[_nghost-%COMP%] .wfr-graph-split > .as-split-gutter:hover::after {\n background: var(--mj-brand-primary);\n}\n\n\n\n\n.wfr-graph-split[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-height: 0;\n}\n\n.wfr-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n overflow-y: auto;\n min-height: 0;\n}\n\n.wfr-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-2) var(--mj-space-3);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n text-align: left;\n cursor: pointer;\n color: var(--mj-text-primary);\n}\n\n.wfr-row[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.wfr-row[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.wfr-row-selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.wfr-row-main[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.wfr-row-name[_ngcontent-%COMP%] {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wfr-row-when[_ngcontent-%COMP%] {\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n}\n\n.wfr-row-status[_ngcontent-%COMP%] {\n flex: none;\n font-size: var(--mj-font-size-xs);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n padding: 2px var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n\n\n\n.wfr-row-status[data-status='Complete'][_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 40%, transparent);\n}\n\n.wfr-row-status[data-status='Failed'][_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, transparent);\n}\n\n.wfr-row-status[data-status='Running'][_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.wfr-detail[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n \n\n height: 100%;\n min-height: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n}\n\n.wfr-detail-head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-3);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.wfr-detail-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n min-width: 0;\n}\n\n.wfr-detail-name[_ngcontent-%COMP%] {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wfr-detail-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n flex: none;\n}\n\n\n\n\n\n\n\n.wfr-head[_ngcontent-%COMP%], \n.wfr-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 1.3fr) minmax(0, 1.3fr) minmax(0, 0.7fr) minmax(0, 0.9fr);\n gap: var(--mj-space-2);\n align-items: center;\n}\n\n.wfr-head[_ngcontent-%COMP%] {\n position: sticky;\n top: 0;\n z-index: 1;\n padding: 0 var(--mj-space-3) var(--mj-space-1);\n background: var(--mj-bg-page);\n}\n\n.wfr-head-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: none;\n border: none;\n padding: var(--mj-space-1) 0;\n font-size: var(--mj-font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-secondary);\n cursor: pointer;\n text-align: left;\n}\n\n.wfr-head-cell[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.wfr-head-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n opacity: 0.65;\n font-size: 0.85em;\n}\n\n.wfr-col-time[_ngcontent-%COMP%], \n.wfr-col-duration[_ngcontent-%COMP%] {\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.wfr-col-status[_ngcontent-%COMP%] {\n justify-self: start;\n}\n\n\n\n\n.wfr-detail-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-1);\n padding: 0 var(--mj-space-3);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.wfr-tab[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n padding: var(--mj-space-2) var(--mj-space-2);\n font-size: var(--mj-font-size-sm);\n font-weight: 600;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.wfr-tab-active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.wfr-graph-pane[_ngcontent-%COMP%] {\n height: 100%;\n min-height: 12rem;\n}\n\n.wfr-steps-pane[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n border-left: 1px solid var(--mj-border-default);\n overflow: hidden;\n}\n\n\n[_nghost-%COMP%] .as-vertical .wfr-steps-pane {\n border-left: none;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.wfr-step-list[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mj-space-1);\n padding: var(--mj-space-2);\n border-bottom: 1px solid var(--mj-border-default);\n max-height: 8rem;\n overflow-y: auto;\n flex: none;\n}\n\n.wfr-step[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: var(--mj-space-1) var(--mj-space-2);\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-primary);\n font-size: var(--mj-font-size-sm);\n cursor: pointer;\n text-align: left;\n}\n\n.wfr-step[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.wfr-step-selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n\n.wfr-step[data-status='Skipped'][_ngcontent-%COMP%] .wfr-step-name[_ngcontent-%COMP%] {\n text-decoration: line-through;\n color: var(--mj-text-secondary);\n}\n\n.wfr-step-name[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.wfr-step-meta[_ngcontent-%COMP%] {\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-secondary);\n}\n\n.wfr-step-json[_ngcontent-%COMP%], \n.wfr-json-pane[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: auto;\n}\n\n.wfr-step-json-head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n padding: var(--mj-space-1) var(--mj-space-3);\n font-weight: 600;\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n flex: none;\n}\n\n\n\n.wfr-stall[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 8px 12px;\n margin: 0 12px 8px;\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 45%, var(--mj-border-default));\n border-left: 4px solid var(--mj-status-warning);\n border-radius: var(--mj-radius-md);\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n font-size: var(--mj-font-size-sm);\n}\n.wfr-stall-body[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n.wfr-stall[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n.wfr-stall-copy[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.wfr-stall-copy[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n}\n.wfr-stall-reason[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.wfr-stall-actions[_ngcontent-%COMP%] { display: flex; flex-wrap: wrap; gap: 6px; }\n\n.wfr-replay[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n}\n.wfr-replay[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.wfr-replay[_ngcontent-%COMP%] input[type='range'][_ngcontent-%COMP%] { flex: 1; accent-color: var(--mj-brand-primary); }\n\n.wfr-engine[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n overflow-x: auto;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n}\n.wfr-tick[_ngcontent-%COMP%] {\n flex: none;\n padding: 3px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n white-space: nowrap;\n}\n.wfr-tick-held[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-status-warning, #d97706) 45%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-status-warning, #d97706) 8%, var(--mj-bg-surface));\n}\n.wfr-tick-paused[_ngcontent-%COMP%] { color: var(--mj-brand-primary); border-color: var(--mj-border-strong); }\n\n.wfr-insp-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 7px 10px;\n margin: 0 0 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-primary);\n}\n.wfr-insp-card[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n}\n.wfr-insp-label[_ngcontent-%COMP%] {\n font-size: var(--mj-font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-secondary);\n}\n.wfr-insp-card[data-verdict='held'][_ngcontent-%COMP%], \n.wfr-insp-bad[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-status-warning, #d97706) 45%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-status-warning, #d97706) 8%, var(--mj-bg-surface));\n}\n.wfr-insp-card[data-verdict='satisfied'][_ngcontent-%COMP%] .wfr-insp-label[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.wfr-insp-actions[_ngcontent-%COMP%] { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 8px; }\n.wfr-insp-hint[_ngcontent-%COMP%] {\n margin: 0 0 8px;\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-muted);\n}\n\n.wfr-bp-bar[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n}\n.wfr-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 2px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: var(--mj-font-size-xs);\n cursor: pointer;\n}\n.wfr-chip-break[_ngcontent-%COMP%] { color: var(--mj-status-error); border-color: color-mix(in srgb, var(--mj-status-error) 40%, transparent); }\n.wfr-chip-break[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 7px; }\n.wfr-chip-paused[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n cursor: default;\n}\n.wfr-chip-forced[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n border-color: color-mix(in srgb, var(--mj-status-warning) 40%, transparent);\n cursor: default;\n}\n.wfr-chip-x[_ngcontent-%COMP%] {\n font-size: 14px;\n line-height: 1;\n padding: 0 2px;\n}\n.wfr-chip-x[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); }\n\n.wfr-bp[_ngcontent-%COMP%] {\n width: 22px;\n height: 22px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin: 0 0 8px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n}\n.wfr-bp[_ngcontent-%COMP%]:hover { color: var(--mj-status-error); }\n.wfr-bp-on[_ngcontent-%COMP%], \n.wfr-bp-on[_ngcontent-%COMP%]:hover { color: var(--mj-status-error); }\n.wfr-bp[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 10px; }\n.wfr-bp[_ngcontent-%COMP%]:disabled { opacity: 0.45; cursor: default; }\n\n.wfr-editor-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px;\n margin: 0 0 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-card);\n}\n.wfr-editor-danger[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-border-default));\n}\n.wfr-json-edit[_ngcontent-%COMP%] {\n width: 100%;\n min-height: 120px;\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n resize: vertical;\n}\n.wfr-editor-error[_ngcontent-%COMP%] { color: var(--mj-status-error); font-size: var(--mj-font-size-xs); }\n.wfr-insp-failure[_ngcontent-%COMP%] { border-color: var(--mj-status-error); color: var(--mj-status-error); }"], changeDetection: 0 });
|
|
1806
1827
|
};
|
|
1807
1828
|
WorkflowRunsResourceComponent = WorkflowRunsResourceComponent_1 = __decorate([
|
|
1808
1829
|
RegisterClass(BaseResourceComponent, 'WorkflowRunsResource')
|
|
@@ -1810,7 +1831,7 @@ WorkflowRunsResourceComponent = WorkflowRunsResourceComponent_1 = __decorate([
|
|
|
1810
1831
|
export { WorkflowRunsResourceComponent };
|
|
1811
1832
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WorkflowRunsResourceComponent, [{
|
|
1812
1833
|
type: Component,
|
|
1813
|
-
args: [{ standalone: false, selector: 'mj-workflow-runs', changeDetection: ChangeDetectionStrategy.OnPush, template: "<mj-page-layout>\n <mj-page-header\n Title=\"Runs\"\n Icon=\"fa-solid fa-timeline\"\n Subtitle=\"Every workflow that has run \u2014 however it was started.\">\n\n <div meta>\n @if (!IsLoading && Runs.length > 0) {\n <mj-stat-badge\n [Count]=\"VisibleRuns.length\"\n [Total]=\"Runs.length\"\n Label=\"runs\"></mj-stat-badge>\n }\n </div>\n\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"loadData()\"></mj-refresh-button>\n </div>\n\n <div toolbar>\n <mj-page-search\n [Value]=\"SearchText\"\n Placeholder=\"Search runs\"\n (ValueChange)=\"OnSearch($event)\"></mj-page-search>\n\n <div class=\"wfr-status-filters\">\n @for (status of StatusFilters; track status) {\n <button\n type=\"button\"\n mjButton\n [variant]=\"StatusFilter === status ? 'primary' : 'flat'\"\n size=\"sm\"\n (click)=\"OnFilterByStatus(status)\">\n {{ status === 'all' ? 'All' : status }}\n </button>\n }\n </div>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n @if (IsLoading) {\n <mj-loading text=\"Loading runs...\"></mj-loading>\n } @else if (LoadError) {\n <mj-alert Variant=\"error\" [Message]=\"LoadError\"></mj-alert>\n } @else if (Runs.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-timeline\"\n Title=\"Nothing has run yet\"\n Message=\"When a workflow runs \u2014 started by hand, on a schedule, or by an agent \u2014 it will appear here.\">\n </mj-empty-state>\n } @else if (VisibleRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-filter\"\n Title=\"No runs match\"\n Message=\"Nothing matches the current filter. Clear it to see everything that has run.\">\n </mj-empty-state>\n } @else {\n <as-split class=\"wfr-split\" direction=\"horizontal\" unit=\"percent\"\n [gutterSize]=\"8\" [disabled]=\"!SelectedRun\" (dragEnd)=\"OnSplitDragEnd($event.sizes)\">\n <as-split-area [size]=\"SelectedRun ? Layout.SplitSizes[0] : 100\" [minSize]=\"20\">\n <div class=\"wfr-list\">\n <!-- A header row that sorts. Every column a person scans by is sortable, because \"the\n longest run\" and \"the one that failed this morning\" are the two questions this list\n exists to answer and neither is answerable by scrolling. -->\n <div class=\"wfr-head\" role=\"row\">\n <button type=\"button\" class=\"wfr-head-cell wfr-col-name\" (click)=\"OnSort('Name')\">\n Workflow <i [ngClass]=\"SortIcon('Name')\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"wfr-head-cell wfr-col-time\" (click)=\"OnSort('StartedAt')\">\n Started <i [ngClass]=\"SortIcon('StartedAt')\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"wfr-head-cell wfr-col-time\" (click)=\"OnSort('CompletedAt')\">\n Ended <i [ngClass]=\"SortIcon('CompletedAt')\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"wfr-head-cell wfr-col-duration\" (click)=\"OnSort('Duration')\">\n Duration <i [ngClass]=\"SortIcon('Duration')\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"wfr-head-cell wfr-col-status\" (click)=\"OnSort('Status')\">\n Status <i [ngClass]=\"SortIcon('Status')\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n @for (run of VisibleRuns; track run.ID) {\n <button\n type=\"button\"\n class=\"wfr-row\"\n [class.wfr-row-selected]=\"run.ID === SelectedRunID\"\n (click)=\"OnSelectRun(run)\">\n <span class=\"wfr-col-name wfr-row-name\">{{ run.Name }}</span>\n <!-- An em dash, never a fabricated time: a run that has not started has no start, and\n printing one would read as data. -->\n <span class=\"wfr-col-time\">{{ run.StartedAt ? (run.StartedAt | date:'MMM d, h:mm:ss a') : '\u2014' }}</span>\n <span class=\"wfr-col-time\">{{ run.CompletedAt ? (run.CompletedAt | date:'MMM d, h:mm:ss a') : '\u2014' }}</span>\n <span class=\"wfr-col-duration\">{{ run.Duration }}</span>\n <span class=\"wfr-col-status wfr-row-status\" [attr.data-status]=\"run.Status\">{{ run.Status }}</span>\n </button>\n }\n </div>\n </as-split-area>\n\n <as-split-area [size]=\"SelectedRun ? Layout.SplitSizes[1] : 0\" [minSize]=\"25\" [visible]=\"!!SelectedRun\">\n @if (SelectedRun; as selected) {\n <!-- The canvas lives in the RIGHT PANEL on selection, not nested inside the list row.\n A graph needs room to be read; inlining one per row turns a scannable list into a\n stack of diagrams. -->\n <aside class=\"wfr-detail\">\n <header class=\"wfr-detail-head\">\n <div class=\"wfr-detail-title\">\n <span class=\"wfr-detail-name\">{{ selected.Name }}</span>\n <span class=\"wfr-row-status\" [attr.data-status]=\"selected.Status\">{{ selected.Status }}</span>\n </div>\n <div class=\"wfr-detail-actions\">\n @if (selected.AgentRunID) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OnOpenAgentRun(selected)\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\" aria-hidden=\"true\"></i>\n Agent run\n </button>\n }\n @if (DetailTab === 'graph') {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"ToggleStepPanel()\"\n [title]=\"Layout.StepPanelOpen ? 'Hide step details' : 'Show step details'\">\n <i class=\"fa-solid\" [class.fa-square-caret-right]=\"Layout.StepPanelOpen\"\n [class.fa-square-caret-left]=\"!Layout.StepPanelOpen\" aria-hidden=\"true\"></i>\n </button>\n }\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OnSelectRun(selected)\" aria-label=\"Close\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n <div class=\"wfr-detail-tabs\" role=\"tablist\">\n <button type=\"button\" class=\"wfr-tab\" [class.wfr-tab-active]=\"DetailTab === 'graph'\"\n (click)=\"OnDetailTab('graph')\">\n <i class=\"fa-solid fa-diagram-project\" aria-hidden=\"true\"></i> Workflow\n </button>\n <button type=\"button\" class=\"wfr-tab\" [class.wfr-tab-active]=\"DetailTab === 'json'\"\n (click)=\"OnDetailTab('json')\">\n <i class=\"fa-solid fa-code\" aria-hidden=\"true\"></i> JSON\n </button>\n </div>\n\n @if (Stall) {\n <!-- The hardening review's signature failure \u2014 \"the run strands silently\" \u2014 made\n loud. A held path is now something the operator can answer, not just read. -->\n <div class=\"wfr-stall\" role=\"status\" [attr.data-kind]=\"Stall.kind\">\n <div class=\"wfr-stall-body\">\n <i class=\"fa-solid fa-triangle-exclamation\" aria-hidden=\"true\"></i>\n <div class=\"wfr-stall-copy\">\n <span>{{ Stall.message }}</span>\n @if (Stall.conditionText) {\n <code>{{ Stall.conditionText }}</code>\n }\n @if (Stall.reason) {\n <span class=\"wfr-stall-reason\">{{ Stall.reason }}</span>\n }\n </div>\n </div>\n @if (Stall.kind === 'held' && Stall.edgeID) {\n <div class=\"wfr-stall-actions\">\n <button mjButton variant=\"primary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnOverrideEdge(Stall.edgeID!, 'true')\">\n Answer true\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnOverrideEdge(Stall.edgeID!, 'false')\">\n Answer false\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OnDismissStall()\">\n Leave held\n </button>\n </div>\n }\n </div>\n }\n\n @if (DetailTab === 'graph') {\n <!-- Canvas BESIDE the step it opened, not above it. A JSON record in a strip along the\n bottom shows about ten lines, which is not enough of a record to read. -->\n <as-split class=\"wfr-graph-split\" [direction]=\"InnerSplitDirection\" unit=\"percent\"\n [gutterSize]=\"8\" (dragEnd)=\"OnStepSplitDragEnd($event.sizes)\">\n <as-split-area [size]=\"Layout.StepPanelOpen ? Layout.StepSplitSizes[0] : 100\" [minSize]=\"25\">\n <div class=\"wfr-graph-pane\">\n <mj-task-graph-debugger\n #GraphDebug\n [Provider]=\"ProviderToUse\"\n [ParentTaskID]=\"selected.ID\"\n [WorkflowName]=\"selected.Name\"\n [LiveUpdates]=\"selected.Status === 'Running' || selected.Status === 'In Progress'\"\n [ReplayAt]=\"ReplayAt\"\n [ShowLegend]=\"Layout.ShowLegend\"\n Height=\"100%\"\n (NodeSelected)=\"OnGraphNodeSelected($event)\"\n (ConnectionSelected)=\"OnGraphConnectionSelected($event)\"\n (LegendToggled)=\"OnLegendToggled($event)\"\n (Settled)=\"OnCanvasSettled()\"\n (Frame)=\"OnFrame($event)\"\n (PausedChange)=\"DebugPaused = $event\">\n </mj-task-graph-debugger>\n\n @if (CanReplay) {\n <!-- Replay: scrub through the settled run on the same canvas, reconstructed\n from each step's own timestamps. Read-only by construction. -->\n <div class=\"wfr-replay\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n <input type=\"range\" min=\"0\" max=\"100\" step=\"1\"\n [value]=\"ReplayPercent ?? 100\"\n (input)=\"OnReplayScrub($any($event.target).value)\"\n aria-label=\"Replay position\" />\n @if (ReplayPercent !== null) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OnReplayReset()\">Now</button>\n }\n </div>\n }\n\n @if (GraphDebug.Breakpoints.length > 0 || GraphDebug.PausedAtTaskID) {\n <div class=\"wfr-bp-bar\" aria-label=\"Armed breakpoints\">\n @if (GraphDebug.PausedAtTaskID) {\n <span class=\"wfr-chip wfr-chip-paused\">\n <i class=\"fa-solid fa-pause\" aria-hidden=\"true\"></i>\n Paused at {{ StepName(GraphDebug.PausedAtTaskID) }}\n </span>\n }\n @for (id of GraphDebug.Breakpoints; track id) {\n <button type=\"button\" class=\"wfr-chip wfr-chip-break\" (click)=\"OnSelectBreakpoint(id)\">\n <i class=\"fa-solid fa-circle\" aria-hidden=\"true\"></i>\n {{ StepName(id) }}\n <span class=\"wfr-chip-x\" (click)=\"OnRemoveBreakpoint(id); $event.stopPropagation()\"\n role=\"button\" tabindex=\"0\" aria-label=\"Remove breakpoint\">\u00D7</span>\n </button>\n }\n </div>\n }\n\n @if (EngineTicks.length > 0) {\n <!-- The engine strip: one tick per dispatcher pass. A stuck run is a strip\n that keeps ticking with nothing moving \u2014 the honest visual of a stall. -->\n <div class=\"wfr-engine\" aria-label=\"Engine activity\">\n @for (tick of EngineTicks; track tick.passNumber) {\n <span class=\"wfr-tick\" [class.wfr-tick-held]=\"(tick.heldCount ?? 0) > 0\">\n #{{ tick.passNumber }} \u00B7 ready {{ tick.eligibleCount ?? 0 }}\n \u00B7 held {{ tick.heldCount ?? 0 }} \u00B7 took {{ tick.claimedCount ?? 0 }}\n </span>\n }\n @if (GraphDebug.Paused) {\n <span class=\"wfr-tick wfr-tick-paused\">\u23F8 paused \u2014 nothing new starts</span>\n }\n </div>\n }\n </div>\n </as-split-area>\n\n <as-split-area [size]=\"Layout.StepPanelOpen ? Layout.StepSplitSizes[1] : 0\" [minSize]=\"20\"\n [visible]=\"Layout.StepPanelOpen\">\n <div class=\"wfr-steps-pane\">\n @if (StepsLoading) {\n <mj-loading text=\"Loading steps...\"></mj-loading>\n } @else {\n <div class=\"wfr-step-list\">\n @for (step of SelectedSteps; track step.ID) {\n <button type=\"button\" class=\"wfr-step\"\n [class.wfr-step-selected]=\"step.ID === SelectedStepID\"\n [attr.data-status]=\"step.Status\"\n (click)=\"OnSelectStep(step)\">\n <span class=\"wfr-step-name\">{{ step.Name }}</span>\n <span class=\"wfr-step-meta\">{{ step.StepType || 'Step' }}</span>\n </button>\n }\n </div>\n\n @if (InspectorMode === 'edge' && SelectedEdge; as edge) {\n <div class=\"wfr-step-json\">\n <div class=\"wfr-step-json-head\">\n <span>{{ SelectedEdgeFromName }} \u2192 {{ SelectedEdgeToName }}</span>\n @if (SelectedEdgeOverride) {\n <span class=\"wfr-chip wfr-chip-forced\">forced {{ SelectedEdgeOverride }}</span>\n }\n </div>\n <div class=\"wfr-insp-card\">\n <span class=\"wfr-insp-label\">Condition</span>\n @if (edge.Condition?.trim()) {\n <code>{{ edge.Condition }}</code>\n } @else {\n <span>Unconditional \u2014 this path always runs.</span>\n }\n </div>\n @if (SelectedEdgeIsConditional) {\n <div class=\"wfr-insp-actions\">\n <button mjButton variant=\"primary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnOverrideEdge(edge.ID, 'true')\">Answer true</button>\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnOverrideEdge(edge.ID, 'false')\">Answer false</button>\n @if (SelectedEdgeOverride) {\n <button mjButton variant=\"flat\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnOverrideEdge(edge.ID, null)\">Clear override</button>\n }\n </div>\n } @else {\n <p class=\"wfr-insp-hint\">Skip the target step instead of overriding an unconditional path.</p>\n }\n </div>\n } @else if (SelectedStep; as step) {\n <div class=\"wfr-step-json\">\n <div class=\"wfr-step-json-head\">\n <span>{{ step.Name }}</span>\n <span class=\"wfr-row-status\" [attr.data-status]=\"step.Status\">{{ step.Status }}</span>\n </div>\n\n <button type=\"button\" class=\"wfr-bp\"\n [class.wfr-bp-on]=\"HasBreakpoint(step.ID)\"\n [disabled]=\"ControlBusy\"\n (click)=\"OnBreakpointToggled({ TaskID: step.ID, Enabled: !HasBreakpoint(step.ID) })\"\n [attr.aria-pressed]=\"HasBreakpoint(step.ID)\"\n [title]=\"HasBreakpoint(step.ID) ? 'Remove breakpoint' : 'Break before this step'\">\n <i class=\"fa-circle\"\n [class.fa-solid]=\"HasBreakpoint(step.ID)\"\n [class.fa-regular]=\"!HasBreakpoint(step.ID)\"\n aria-hidden=\"true\"></i>\n </button>\n\n <!-- The inspector: live engine facts about this step, from the frame\n stream \u2014 claim, path verdicts, runner progress, what-if. -->\n @if (SelectedStepProgress; as progress) {\n <div class=\"wfr-insp-card\">\n <span class=\"wfr-insp-label\">Doing now</span>\n <span>{{ progress.progressMessage }}\n @if (progress.progressPercent != null) { ({{ progress.progressPercent }}%) }\n </span>\n </div>\n }\n @if (SelectedStepClaim; as claim) {\n <div class=\"wfr-insp-card\" [class.wfr-insp-bad]=\"claim.claimEvent === 'heartbeat-lost'\">\n <span class=\"wfr-insp-label\">Worker</span>\n <span>\n @switch (claim.claimEvent) {\n @case ('claimed') { {{ claim.claimedBy }} \u2014 working }\n @case ('heartbeat-lost') { {{ claim.claimedBy }} \u2014 lost, will be requeued }\n @case ('reclaimed') { requeued by the engine }\n }\n </span>\n </div>\n }\n @for (verdict of SelectedStepVerdicts; track verdict.edgeId) {\n <div class=\"wfr-insp-card\" [attr.data-verdict]=\"verdict.verdict\">\n <span class=\"wfr-insp-label\">\n @switch (verdict.verdict) {\n @case ('satisfied') { Path taken }\n @case ('notTaken') { Path not taken }\n @case ('held') { Path can't be answered }\n }\n </span>\n <span>\n @if (verdict.conditionText) { <code>{{ verdict.conditionText }}</code> }\n @if (verdict.reason) { \u2014 {{ verdict.reason }} }\n </span>\n </div>\n }\n @if (SelectedStepWhatIf; as whatIf) {\n <div class=\"wfr-insp-card\">\n <span class=\"wfr-insp-label\">If this step fails</span>\n <span>{{ whatIf.BlockedCount }} step{{ whatIf.BlockedCount === 1 ? '' : 's' }} can no longer run</span>\n </div>\n }\n @if (step.Status === 'Pending' || step.Status === 'Failed' || CanForceComplete(step)) {\n <div class=\"wfr-insp-actions\">\n @if (step.Status === 'Pending') {\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnSkipStep(step)\"\n title=\"Declare this step not-taken; later steps proceed\">\n <i class=\"fa-solid fa-forward\" aria-hidden=\"true\"></i> Skip step\n </button>\n }\n @if (CanEditInput(step)) {\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OpenEditInput(step)\">\n <i class=\"fa-solid fa-pen-to-square\" aria-hidden=\"true\"></i>\n {{ step.Status === 'Failed' ? 'Edit input & retry' : 'Edit input' }}\n </button>\n }\n @if (step.Status === 'Failed') {\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnRetryStep(step)\">\n <i class=\"fa-solid fa-rotate-right\" aria-hidden=\"true\"></i> Retry\n </button>\n }\n @if (CanForceComplete(step)) {\n <button mjButton variant=\"danger\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OpenForceComplete(step)\">\n <i class=\"fa-solid fa-flag-checkered\" aria-hidden=\"true\"></i> Force complete\n </button>\n }\n </div>\n }\n\n @if (EditInputOpen) {\n <div class=\"wfr-editor-card\">\n <span class=\"wfr-insp-label\">{{ step.Status === 'Failed' ? 'Edit input and retry' : 'Edit input' }}</span>\n <p class=\"wfr-insp-hint\">Applies to this run only. Invalid JSON is refused here.</p>\n <textarea class=\"mj-textarea wfr-json-edit\" [(ngModel)]=\"EditInputJson\"\n rows=\"8\" spellcheck=\"false\"></textarea>\n @if (EditInputError) {\n <span class=\"wfr-editor-error\">{{ EditInputError }}</span>\n }\n <div class=\"wfr-insp-actions\">\n <button mjButton variant=\"primary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"SubmitEditInput(step)\">\n {{ step.Status === 'Failed' ? 'Apply & retry' : 'Apply' }}\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"EditInputOpen = false\">Cancel</button>\n </div>\n </div>\n }\n\n @if (ForceCompleteOpen) {\n <div class=\"wfr-editor-card wfr-editor-danger\">\n <span class=\"wfr-insp-label\">Force complete</span>\n <p class=\"wfr-insp-hint\">Downstream conditions will evaluate against this output as if the step had produced it. Type the step name to confirm.</p>\n <textarea class=\"mj-textarea wfr-json-edit\" [(ngModel)]=\"ForceCompleteJson\"\n rows=\"6\" spellcheck=\"false\"></textarea>\n <input class=\"mj-input\" type=\"text\" [(ngModel)]=\"ForceCompleteName\"\n [placeholder]=\"'Type \u201C' + step.Name + '\u201D to confirm'\" />\n @if (ForceCompleteError) {\n <span class=\"wfr-editor-error\">{{ ForceCompleteError }}</span>\n }\n <div class=\"wfr-insp-actions\">\n <button mjButton variant=\"danger\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"SubmitForceComplete(step)\">Force complete</button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"ForceCompleteOpen = false\">Cancel</button>\n </div>\n </div>\n }\n\n <mj-task-graph-variables\n [InputPayload]=\"StepPayload(step, 'InputPayload')\"\n [OutputPayload]=\"StepPayload(step, 'OutputPayload')\"\n [Invocation]=\"Invocation\">\n </mj-task-graph-variables>\n </div>\n } @else {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-hand-pointer\"\n Title=\"Select a step\"\n Message=\"Click a step on the canvas or in the list to see everything it recorded.\">\n </mj-empty-state>\n }\n }\n </div>\n </as-split-area>\n </as-split>\n } @else {\n <div class=\"wfr-json-pane\">\n <mj-code-editor\n [ngModel]=\"SelectedRunJson\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n style=\"width: 100%;\">\n </mj-code-editor>\n </div>\n }\n </aside>\n }\n </as-split-area>\n </as-split>\n }\n </mj-page-body>\n</mj-page-layout>\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.wfr-status-filters {\n display: flex;\n gap: var(--mj-space-1);\n align-items: center;\n}\n\n/* List alone until something is selected; two resizable panes after. The size is the user's \u2014 see\n the LAYOUT_KEYS note on the component for why it is persisted server-side rather than locally. */\n.wfr-split {\n height: 100%;\n min-height: 0;\n}\n\n/* A gutter you can find. The default is a hairline, which is discoverable only by accident. */\n:host ::ng-deep .wfr-split > .as-split-gutter,\n:host ::ng-deep .wfr-graph-split > .as-split-gutter {\n background: transparent !important;\n position: relative;\n}\n\n:host ::ng-deep .wfr-split > .as-split-gutter::after,\n:host ::ng-deep .wfr-graph-split > .as-split-gutter::after {\n content: '';\n position: absolute;\n inset: 0;\n margin: auto;\n background: var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n}\n\n:host ::ng-deep .wfr-split.as-horizontal > .as-split-gutter::after,\n:host ::ng-deep .wfr-graph-split.as-horizontal > .as-split-gutter::after {\n width: 2px;\n}\n\n:host ::ng-deep .wfr-graph-split.as-vertical > .as-split-gutter::after {\n height: 2px;\n}\n\n:host ::ng-deep .wfr-split > .as-split-gutter:hover::after,\n:host ::ng-deep .wfr-graph-split > .as-split-gutter:hover::after {\n background: var(--mj-brand-primary);\n}\n\n/* The canvas and the step record sit SIDE BY SIDE \u2014 a JSON record in a strip along the bottom shows\n about ten lines. Stacks below the breakpoint, where three columns would leave each too narrow to\n use. */\n.wfr-graph-split {\n flex: 1 1 auto;\n min-height: 0;\n}\n\n.wfr-list {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n overflow-y: auto;\n min-height: 0;\n}\n\n.wfr-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-2) var(--mj-space-3);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n text-align: left;\n cursor: pointer;\n color: var(--mj-text-primary);\n}\n\n.wfr-row:hover {\n border-color: var(--mj-border-strong);\n}\n\n.wfr-row:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.wfr-row-selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.wfr-row-main {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.wfr-row-name {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wfr-row-when {\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n}\n\n.wfr-row-status {\n flex: none;\n font-size: var(--mj-font-size-xs);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n padding: 2px var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n/* Status carries meaning, so it is encoded in colour as well as text \u2014 a failed run should be\n findable without reading every row. Skipped stays grey on purpose: a branch that was not taken\n is a normal outcome, not a warning. */\n.wfr-row-status[data-status='Complete'] {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 40%, transparent);\n}\n\n.wfr-row-status[data-status='Failed'] {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, transparent);\n}\n\n.wfr-row-status[data-status='Running'] {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.wfr-detail {\n display: flex;\n flex-direction: column;\n /* Fills its split area. Without it the column sizes to its CONTENT, so the canvas below \u2014\n `flex: 1 1 auto` of an auto-height parent \u2014 got its intrinsic height and left dead space. */\n height: 100%;\n min-height: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n}\n\n.wfr-detail-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-3);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.wfr-detail-title {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n min-width: 0;\n}\n\n.wfr-detail-name {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wfr-detail-actions {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n flex: none;\n}\n\n/* ============================================================\n The run list as a sortable table\n ============================================================\n A run list is scanned for two things \u2014 the slowest run and the one that failed \u2014 and neither is\n answerable by scrolling. Columns line up so a reader compares down a column rather than reading\n each row; `tabular-nums` keeps the timestamps from jittering as digits change. */\n.wfr-head,\n.wfr-row {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 1.3fr) minmax(0, 1.3fr) minmax(0, 0.7fr) minmax(0, 0.9fr);\n gap: var(--mj-space-2);\n align-items: center;\n}\n\n.wfr-head {\n position: sticky;\n top: 0;\n z-index: 1;\n padding: 0 var(--mj-space-3) var(--mj-space-1);\n background: var(--mj-bg-page);\n}\n\n.wfr-head-cell {\n display: flex;\n align-items: center;\n gap: 6px;\n background: none;\n border: none;\n padding: var(--mj-space-1) 0;\n font-size: var(--mj-font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-secondary);\n cursor: pointer;\n text-align: left;\n}\n\n.wfr-head-cell:hover {\n color: var(--mj-text-primary);\n}\n\n.wfr-head-cell i {\n opacity: 0.65;\n font-size: 0.85em;\n}\n\n.wfr-col-time,\n.wfr-col-duration {\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.wfr-col-status {\n justify-self: start;\n}\n\n/* ============================================================\n Detail panel: canvas + step JSON, or the whole run as JSON\n ============================================================ */\n.wfr-detail-tabs {\n display: flex;\n gap: var(--mj-space-1);\n padding: 0 var(--mj-space-3);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.wfr-tab {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n padding: var(--mj-space-2) var(--mj-space-2);\n font-size: var(--mj-font-size-sm);\n font-weight: 600;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.wfr-tab-active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.wfr-graph-pane {\n height: 100%;\n min-height: 12rem;\n}\n\n.wfr-steps-pane {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n border-left: 1px solid var(--mj-border-default);\n overflow: hidden;\n}\n\n/* Stacked layout puts the divider back on top, where the eye expects it. */\n:host ::ng-deep .as-vertical .wfr-steps-pane {\n border-left: none;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.wfr-step-list {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mj-space-1);\n padding: var(--mj-space-2);\n border-bottom: 1px solid var(--mj-border-default);\n max-height: 8rem;\n overflow-y: auto;\n flex: none;\n}\n\n.wfr-step {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: var(--mj-space-1) var(--mj-space-2);\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-primary);\n font-size: var(--mj-font-size-sm);\n cursor: pointer;\n text-align: left;\n}\n\n.wfr-step:hover {\n border-color: var(--mj-border-strong);\n}\n\n.wfr-step-selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n/* Work that never ran must not read like work that did \u2014 the same rule the run timeline follows. */\n.wfr-step[data-status='Skipped'] .wfr-step-name {\n text-decoration: line-through;\n color: var(--mj-text-secondary);\n}\n\n.wfr-step-name {\n font-weight: 600;\n}\n\n.wfr-step-meta {\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-secondary);\n}\n\n.wfr-step-json,\n.wfr-json-pane {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: auto;\n}\n\n.wfr-step-json-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n padding: var(--mj-space-1) var(--mj-space-3);\n font-weight: 600;\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n flex: none;\n}\n\n/* \u2500\u2500 live console \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.wfr-stall {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 8px 12px;\n margin: 0 12px 8px;\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 45%, var(--mj-border-default));\n border-left: 4px solid var(--mj-status-warning);\n border-radius: var(--mj-radius-md);\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n font-size: var(--mj-font-size-sm);\n}\n.wfr-stall-body {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n.wfr-stall i { color: var(--mj-status-warning); }\n.wfr-stall-copy {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.wfr-stall-copy code {\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n}\n.wfr-stall-reason { color: var(--mj-text-secondary); }\n.wfr-stall-actions { display: flex; flex-wrap: wrap; gap: 6px; }\n\n.wfr-replay {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n}\n.wfr-replay i { color: var(--mj-text-secondary); }\n.wfr-replay input[type='range'] { flex: 1; accent-color: var(--mj-brand-primary); }\n\n.wfr-engine {\n display: flex;\n gap: 8px;\n overflow-x: auto;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n}\n.wfr-tick {\n flex: none;\n padding: 3px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n white-space: nowrap;\n}\n.wfr-tick-held {\n border-color: color-mix(in srgb, var(--mj-status-warning, #d97706) 45%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-status-warning, #d97706) 8%, var(--mj-bg-surface));\n}\n.wfr-tick-paused { color: var(--mj-brand-primary); border-color: var(--mj-border-strong); }\n\n.wfr-insp-card {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 7px 10px;\n margin: 0 0 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-primary);\n}\n.wfr-insp-card code {\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n}\n.wfr-insp-label {\n font-size: var(--mj-font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-secondary);\n}\n.wfr-insp-card[data-verdict='held'],\n.wfr-insp-bad {\n border-color: color-mix(in srgb, var(--mj-status-warning, #d97706) 45%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-status-warning, #d97706) 8%, var(--mj-bg-surface));\n}\n.wfr-insp-card[data-verdict='satisfied'] .wfr-insp-label { color: var(--mj-status-success); }\n.wfr-insp-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 8px; }\n.wfr-insp-hint {\n margin: 0 0 8px;\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-muted);\n}\n\n.wfr-bp-bar {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n}\n.wfr-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 2px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: var(--mj-font-size-xs);\n cursor: pointer;\n}\n.wfr-chip-break { color: var(--mj-status-error); border-color: color-mix(in srgb, var(--mj-status-error) 40%, transparent); }\n.wfr-chip-break i { font-size: 7px; }\n.wfr-chip-paused {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n cursor: default;\n}\n.wfr-chip-forced {\n color: var(--mj-status-warning);\n border-color: color-mix(in srgb, var(--mj-status-warning) 40%, transparent);\n cursor: default;\n}\n.wfr-chip-x {\n font-size: 14px;\n line-height: 1;\n padding: 0 2px;\n}\n.wfr-chip-x:hover { color: var(--mj-text-primary); }\n\n.wfr-bp {\n width: 22px;\n height: 22px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin: 0 0 8px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n}\n.wfr-bp:hover { color: var(--mj-status-error); }\n.wfr-bp-on,\n.wfr-bp-on:hover { color: var(--mj-status-error); }\n.wfr-bp i { font-size: 10px; }\n.wfr-bp:disabled { opacity: 0.45; cursor: default; }\n\n.wfr-editor-card {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px;\n margin: 0 0 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-card);\n}\n.wfr-editor-danger {\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-border-default));\n}\n.wfr-json-edit {\n width: 100%;\n min-height: 120px;\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n resize: vertical;\n}\n.wfr-editor-error { color: var(--mj-status-error); font-size: var(--mj-font-size-xs); }\n"] }]
|
|
1834
|
+
args: [{ standalone: false, selector: 'mj-workflow-runs', changeDetection: ChangeDetectionStrategy.OnPush, template: "<mj-page-layout>\n <mj-page-header\n Title=\"Runs\"\n Icon=\"fa-solid fa-timeline\"\n Subtitle=\"Every workflow that has run \u2014 however it was started.\">\n\n <div meta>\n @if (!IsLoading && Runs.length > 0) {\n <mj-stat-badge\n [Count]=\"VisibleRuns.length\"\n [Total]=\"Runs.length\"\n Label=\"runs\"></mj-stat-badge>\n }\n </div>\n\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"loadData()\"></mj-refresh-button>\n </div>\n\n <div toolbar>\n <mj-page-search\n [Value]=\"SearchText\"\n Placeholder=\"Search runs\"\n (ValueChange)=\"OnSearch($event)\"></mj-page-search>\n\n <div class=\"wfr-status-filters\">\n @for (status of StatusFilters; track status) {\n <button\n type=\"button\"\n mjButton\n [variant]=\"StatusFilter === status ? 'primary' : 'flat'\"\n size=\"sm\"\n (click)=\"OnFilterByStatus(status)\">\n {{ status === 'all' ? 'All' : status }}\n </button>\n }\n </div>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n @if (IsLoading) {\n <mj-loading text=\"Loading runs...\"></mj-loading>\n } @else if (LoadError) {\n <mj-alert Variant=\"error\" [Message]=\"LoadError\"></mj-alert>\n } @else if (Runs.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-timeline\"\n Title=\"Nothing has run yet\"\n Message=\"When a workflow runs \u2014 started by hand, on a schedule, or by an agent \u2014 it will appear here.\">\n </mj-empty-state>\n } @else if (VisibleRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-filter\"\n Title=\"No runs match\"\n Message=\"Nothing matches the current filter. Clear it to see everything that has run.\">\n </mj-empty-state>\n } @else {\n <as-split class=\"wfr-split\" direction=\"horizontal\" unit=\"percent\"\n [gutterSize]=\"8\" [disabled]=\"!SelectedRun\" (dragEnd)=\"OnSplitDragEnd($event.sizes)\">\n <as-split-area [size]=\"SelectedRun ? Layout.SplitSizes[0] : 100\" [minSize]=\"20\">\n <div class=\"wfr-list\">\n <!-- A header row that sorts. Every column a person scans by is sortable, because \"the\n longest run\" and \"the one that failed this morning\" are the two questions this list\n exists to answer and neither is answerable by scrolling. -->\n <div class=\"wfr-head\" role=\"row\">\n <button type=\"button\" class=\"wfr-head-cell wfr-col-name\" (click)=\"OnSort('Name')\">\n Workflow <i [ngClass]=\"SortIcon('Name')\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"wfr-head-cell wfr-col-time\" (click)=\"OnSort('StartedAt')\">\n Started <i [ngClass]=\"SortIcon('StartedAt')\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"wfr-head-cell wfr-col-time\" (click)=\"OnSort('CompletedAt')\">\n Ended <i [ngClass]=\"SortIcon('CompletedAt')\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"wfr-head-cell wfr-col-duration\" (click)=\"OnSort('Duration')\">\n Duration <i [ngClass]=\"SortIcon('Duration')\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"wfr-head-cell wfr-col-status\" (click)=\"OnSort('Status')\">\n Status <i [ngClass]=\"SortIcon('Status')\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n @for (run of VisibleRuns; track run.ID) {\n <button\n type=\"button\"\n class=\"wfr-row\"\n [class.wfr-row-selected]=\"run.ID === SelectedRunID\"\n (click)=\"OnSelectRun(run)\">\n <span class=\"wfr-col-name wfr-row-name\">{{ run.Name }}</span>\n <!-- An em dash, never a fabricated time: a run that has not started has no start, and\n printing one would read as data. -->\n <span class=\"wfr-col-time\">{{ run.StartedAt ? (run.StartedAt | date:'MMM d, h:mm:ss a') : '\u2014' }}</span>\n <span class=\"wfr-col-time\">{{ run.CompletedAt ? (run.CompletedAt | date:'MMM d, h:mm:ss a') : '\u2014' }}</span>\n <span class=\"wfr-col-duration\">{{ run.Duration }}</span>\n <span class=\"wfr-col-status wfr-row-status\" [attr.data-status]=\"run.Status\">{{ run.Status }}</span>\n </button>\n }\n </div>\n </as-split-area>\n\n <as-split-area [size]=\"SelectedRun ? Layout.SplitSizes[1] : 0\" [minSize]=\"25\" [visible]=\"!!SelectedRun\">\n @if (SelectedRun; as selected) {\n <!-- The canvas lives in the RIGHT PANEL on selection, not nested inside the list row.\n A graph needs room to be read; inlining one per row turns a scannable list into a\n stack of diagrams. -->\n <aside class=\"wfr-detail\">\n <header class=\"wfr-detail-head\">\n <div class=\"wfr-detail-title\">\n <span class=\"wfr-detail-name\">{{ selected.Name }}</span>\n <span class=\"wfr-row-status\" [attr.data-status]=\"selected.Status\">{{ selected.Status }}</span>\n </div>\n <div class=\"wfr-detail-actions\">\n @if (selected.AgentRunID) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OnOpenAgentRun(selected)\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\" aria-hidden=\"true\"></i>\n Agent run\n </button>\n }\n @if (DetailTab === 'graph') {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"ToggleStepPanel()\"\n [title]=\"Layout.StepPanelOpen ? 'Hide step details' : 'Show step details'\">\n <i class=\"fa-solid\" [class.fa-square-caret-right]=\"Layout.StepPanelOpen\"\n [class.fa-square-caret-left]=\"!Layout.StepPanelOpen\" aria-hidden=\"true\"></i>\n </button>\n }\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OnSelectRun(selected)\" aria-label=\"Close\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </header>\n\n <div class=\"wfr-detail-tabs\" role=\"tablist\">\n <button type=\"button\" class=\"wfr-tab\" [class.wfr-tab-active]=\"DetailTab === 'graph'\"\n (click)=\"OnDetailTab('graph')\">\n <i class=\"fa-solid fa-diagram-project\" aria-hidden=\"true\"></i> Workflow\n </button>\n <button type=\"button\" class=\"wfr-tab\" [class.wfr-tab-active]=\"DetailTab === 'json'\"\n (click)=\"OnDetailTab('json')\">\n <i class=\"fa-solid fa-code\" aria-hidden=\"true\"></i> JSON\n </button>\n </div>\n\n @if (Stall) {\n <!-- The hardening review's signature failure \u2014 \"the run strands silently\" \u2014 made\n loud. A held path is now something the operator can answer, not just read. -->\n <div class=\"wfr-stall\" role=\"status\" [attr.data-kind]=\"Stall.kind\">\n <div class=\"wfr-stall-body\">\n <i class=\"fa-solid fa-triangle-exclamation\" aria-hidden=\"true\"></i>\n <div class=\"wfr-stall-copy\">\n <span>{{ Stall.message }}</span>\n @if (Stall.conditionText) {\n <code>{{ Stall.conditionText }}</code>\n }\n @if (Stall.reason) {\n <span class=\"wfr-stall-reason\">{{ Stall.reason }}</span>\n }\n </div>\n </div>\n @if (Stall.kind === 'held' && Stall.edgeID) {\n <div class=\"wfr-stall-actions\">\n <button mjButton variant=\"primary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnOverrideEdge(Stall.edgeID!, 'true')\">\n Answer true\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnOverrideEdge(Stall.edgeID!, 'false')\">\n Answer false\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OnDismissStall()\">\n Leave held\n </button>\n </div>\n }\n </div>\n }\n\n @if (DetailTab === 'graph') {\n <!-- Canvas BESIDE the step it opened, not above it. A JSON record in a strip along the\n bottom shows about ten lines, which is not enough of a record to read. -->\n <as-split class=\"wfr-graph-split\" [direction]=\"InnerSplitDirection\" unit=\"percent\"\n [gutterSize]=\"8\" (dragEnd)=\"OnStepSplitDragEnd($event.sizes)\">\n <as-split-area [size]=\"Layout.StepPanelOpen ? Layout.StepSplitSizes[0] : 100\" [minSize]=\"25\">\n <div class=\"wfr-graph-pane\">\n <mj-task-graph-debugger\n #GraphDebug\n [Provider]=\"ProviderToUse\"\n [ParentTaskID]=\"selected.ID\"\n [WorkflowName]=\"selected.Name\"\n [LiveUpdates]=\"selected.Status === 'Running' || selected.Status === 'In Progress'\"\n [ReplayAt]=\"ReplayAt\"\n [ShowLegend]=\"Layout.ShowLegend\"\n Height=\"100%\"\n (NodeSelected)=\"OnGraphNodeSelected($event)\"\n (ConnectionSelected)=\"OnGraphConnectionSelected($event)\"\n (LegendToggled)=\"OnLegendToggled($event)\"\n (Settled)=\"OnCanvasSettled()\"\n (Frame)=\"OnFrame($event)\"\n (PausedChange)=\"DebugPaused = $event\">\n </mj-task-graph-debugger>\n\n @if (CanReplay) {\n <!-- Replay: scrub through the settled run on the same canvas, reconstructed\n from each step's own timestamps. Read-only by construction. -->\n <div class=\"wfr-replay\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n <input type=\"range\" min=\"0\" max=\"100\" step=\"1\"\n [value]=\"ReplayPercent ?? 100\"\n (input)=\"OnReplayScrub($any($event.target).value)\"\n aria-label=\"Replay position\" />\n @if (ReplayPercent !== null) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OnReplayReset()\">Now</button>\n }\n </div>\n }\n\n @if (GraphDebug.Breakpoints.length > 0 || GraphDebug.PausedAtTaskID) {\n <div class=\"wfr-bp-bar\" aria-label=\"Armed breakpoints\">\n @if (GraphDebug.PausedAtTaskID) {\n <span class=\"wfr-chip wfr-chip-paused\">\n <i class=\"fa-solid fa-pause\" aria-hidden=\"true\"></i>\n Paused at {{ StepName(GraphDebug.PausedAtTaskID) }}\n </span>\n }\n @for (id of GraphDebug.Breakpoints; track id) {\n <button type=\"button\" class=\"wfr-chip wfr-chip-break\" (click)=\"OnSelectBreakpoint(id)\">\n <i class=\"fa-solid fa-circle\" aria-hidden=\"true\"></i>\n {{ StepName(id) }}\n <span class=\"wfr-chip-x\" (click)=\"OnRemoveBreakpoint(id); $event.stopPropagation()\"\n role=\"button\" tabindex=\"0\" aria-label=\"Remove breakpoint\">\u00D7</span>\n </button>\n }\n </div>\n }\n\n @if (EngineTicks.length > 0) {\n <!-- The engine strip: one tick per dispatcher pass. A stuck run is a strip\n that keeps ticking with nothing moving \u2014 the honest visual of a stall. -->\n <div class=\"wfr-engine\" aria-label=\"Engine activity\">\n @for (tick of EngineTicks; track tick.passNumber) {\n <span class=\"wfr-tick\" [class.wfr-tick-held]=\"(tick.heldCount ?? 0) > 0\">\n #{{ tick.passNumber }} \u00B7 ready {{ tick.eligibleCount ?? 0 }}\n \u00B7 held {{ tick.heldCount ?? 0 }} \u00B7 took {{ tick.claimedCount ?? 0 }}\n </span>\n }\n @if (GraphDebug.Paused) {\n <span class=\"wfr-tick wfr-tick-paused\">\u23F8 paused \u2014 nothing new starts</span>\n }\n </div>\n }\n </div>\n </as-split-area>\n\n <as-split-area [size]=\"Layout.StepPanelOpen ? Layout.StepSplitSizes[1] : 0\" [minSize]=\"20\"\n [visible]=\"Layout.StepPanelOpen\">\n <div class=\"wfr-steps-pane\">\n @if (StepsLoading) {\n <mj-loading text=\"Loading steps...\"></mj-loading>\n } @else {\n <div class=\"wfr-step-list\">\n @for (step of SelectedSteps; track step.ID) {\n <button type=\"button\" class=\"wfr-step\"\n [class.wfr-step-selected]=\"step.ID === SelectedStepID\"\n [attr.data-status]=\"step.Status\"\n (click)=\"OnSelectStep(step)\">\n <span class=\"wfr-step-name\">{{ step.Name }}</span>\n <span class=\"wfr-step-meta\">{{ step.StepType || 'Step' }}</span>\n </button>\n }\n </div>\n\n @if (InspectorMode === 'edge' && SelectedEdge; as edge) {\n <div class=\"wfr-step-json\">\n <div class=\"wfr-step-json-head\">\n <span>{{ SelectedEdgeFromName }} \u2192 {{ SelectedEdgeToName }}</span>\n @if (SelectedEdgeOverride) {\n <span class=\"wfr-chip wfr-chip-forced\">forced {{ SelectedEdgeOverride }}</span>\n }\n </div>\n <div class=\"wfr-insp-card\">\n <span class=\"wfr-insp-label\">Condition</span>\n @if (edge.Condition?.trim()) {\n <code>{{ edge.Condition }}</code>\n } @else {\n <span>Unconditional \u2014 this path always runs.</span>\n }\n </div>\n @if (SelectedEdgeIsConditional) {\n <div class=\"wfr-insp-actions\">\n <button mjButton variant=\"primary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnOverrideEdge(edge.ID, 'true')\">Answer true</button>\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnOverrideEdge(edge.ID, 'false')\">Answer false</button>\n @if (SelectedEdgeOverride) {\n <button mjButton variant=\"flat\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnOverrideEdge(edge.ID, null)\">Clear override</button>\n }\n </div>\n } @else {\n <p class=\"wfr-insp-hint\">Skip the target step instead of overriding an unconditional path.</p>\n }\n </div>\n } @else if (SelectedStep; as step) {\n <div class=\"wfr-step-json\">\n <div class=\"wfr-step-json-head\">\n <span>{{ step.Name }}</span>\n <span class=\"wfr-row-status\" [attr.data-status]=\"step.Status\">{{ step.Status }}</span>\n </div>\n\n @if (SelectedStepFailureReason; as reason) {\n <div class=\"wfr-insp-card wfr-insp-failure\" role=\"status\">\n <span class=\"wfr-insp-label\">Why it failed</span>\n <span>{{ reason }}</span>\n </div>\n }\n\n <button type=\"button\" class=\"wfr-bp\"\n [class.wfr-bp-on]=\"HasBreakpoint(step.ID)\"\n [disabled]=\"ControlBusy\"\n (click)=\"OnBreakpointToggled({ TaskID: step.ID, Enabled: !HasBreakpoint(step.ID) })\"\n [attr.aria-pressed]=\"HasBreakpoint(step.ID)\"\n [title]=\"HasBreakpoint(step.ID) ? 'Remove breakpoint' : 'Break before this step'\">\n <i class=\"fa-circle\"\n [class.fa-solid]=\"HasBreakpoint(step.ID)\"\n [class.fa-regular]=\"!HasBreakpoint(step.ID)\"\n aria-hidden=\"true\"></i>\n </button>\n\n <!-- The inspector: live engine facts about this step, from the frame\n stream \u2014 claim, path verdicts, runner progress, what-if. -->\n @if (SelectedStepProgress; as progress) {\n <div class=\"wfr-insp-card\">\n <span class=\"wfr-insp-label\">Doing now</span>\n <span>{{ progress.progressMessage }}\n @if (progress.progressPercent != null) { ({{ progress.progressPercent }}%) }\n </span>\n </div>\n }\n @if (SelectedStepClaim; as claim) {\n <div class=\"wfr-insp-card\" [class.wfr-insp-bad]=\"claim.claimEvent === 'heartbeat-lost'\">\n <span class=\"wfr-insp-label\">Worker</span>\n <span>\n @switch (claim.claimEvent) {\n @case ('claimed') { {{ claim.claimedBy }} \u2014 working }\n @case ('heartbeat-lost') { {{ claim.claimedBy }} \u2014 lost, will be requeued }\n @case ('reclaimed') { requeued by the engine }\n }\n </span>\n </div>\n }\n @for (verdict of SelectedStepVerdicts; track verdict.edgeId) {\n <div class=\"wfr-insp-card\" [attr.data-verdict]=\"verdict.verdict\">\n <span class=\"wfr-insp-label\">\n @switch (verdict.verdict) {\n @case ('satisfied') { Path taken }\n @case ('notTaken') { Path not taken }\n @case ('held') { Path can't be answered }\n }\n </span>\n <span>\n @if (verdict.conditionText) { <code>{{ verdict.conditionText }}</code> }\n @if (verdict.reason) { \u2014 {{ verdict.reason }} }\n </span>\n </div>\n }\n @if (SelectedStepWhatIf; as whatIf) {\n <div class=\"wfr-insp-card\">\n <span class=\"wfr-insp-label\">If this step fails</span>\n <span>{{ whatIf.BlockedCount }} step{{ whatIf.BlockedCount === 1 ? '' : 's' }} can no longer run</span>\n </div>\n }\n @if (step.Status === 'Pending' || step.Status === 'Failed' || CanForceComplete(step)) {\n <div class=\"wfr-insp-actions\">\n @if (step.Status === 'Pending') {\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnSkipStep(step)\"\n title=\"Declare this step not-taken; later steps proceed\">\n <i class=\"fa-solid fa-forward\" aria-hidden=\"true\"></i> Skip step\n </button>\n }\n @if (CanEditInput(step)) {\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OpenEditInput(step)\">\n <i class=\"fa-solid fa-pen-to-square\" aria-hidden=\"true\"></i>\n {{ step.Status === 'Failed' ? 'Edit input & retry' : 'Edit input' }}\n </button>\n }\n @if (step.Status === 'Failed') {\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OnRetryStep(step)\">\n <i class=\"fa-solid fa-rotate-right\" aria-hidden=\"true\"></i> Retry\n </button>\n }\n @if (CanForceComplete(step)) {\n <button mjButton variant=\"danger\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"OpenForceComplete(step)\">\n <i class=\"fa-solid fa-flag-checkered\" aria-hidden=\"true\"></i> Force complete\n </button>\n }\n </div>\n }\n\n @if (EditInputOpen) {\n <div class=\"wfr-editor-card\">\n <span class=\"wfr-insp-label\">{{ step.Status === 'Failed' ? 'Edit input and retry' : 'Edit input' }}</span>\n <p class=\"wfr-insp-hint\">Applies to this run only. Invalid JSON is refused here.</p>\n <textarea class=\"mj-textarea wfr-json-edit\" [(ngModel)]=\"EditInputJson\"\n rows=\"8\" spellcheck=\"false\"></textarea>\n @if (EditInputError) {\n <span class=\"wfr-editor-error\">{{ EditInputError }}</span>\n }\n <div class=\"wfr-insp-actions\">\n <button mjButton variant=\"primary\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"SubmitEditInput(step)\">\n {{ step.Status === 'Failed' ? 'Apply & retry' : 'Apply' }}\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"EditInputOpen = false\">Cancel</button>\n </div>\n </div>\n }\n\n @if (ForceCompleteOpen) {\n <div class=\"wfr-editor-card wfr-editor-danger\">\n <span class=\"wfr-insp-label\">Force complete</span>\n <p class=\"wfr-insp-hint\">Downstream conditions will evaluate against this output as if the step had produced it. Type the step name to confirm.</p>\n <textarea class=\"mj-textarea wfr-json-edit\" [(ngModel)]=\"ForceCompleteJson\"\n rows=\"6\" spellcheck=\"false\"></textarea>\n <input class=\"mj-input\" type=\"text\" [(ngModel)]=\"ForceCompleteName\"\n [placeholder]=\"'Type \u201C' + step.Name + '\u201D to confirm'\" />\n @if (ForceCompleteError) {\n <span class=\"wfr-editor-error\">{{ ForceCompleteError }}</span>\n }\n <div class=\"wfr-insp-actions\">\n <button mjButton variant=\"danger\" size=\"sm\" [disabled]=\"ControlBusy\"\n (click)=\"SubmitForceComplete(step)\">Force complete</button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"ForceCompleteOpen = false\">Cancel</button>\n </div>\n </div>\n }\n\n <mj-task-graph-variables\n [InputPayload]=\"StepPayload(step, 'InputPayload')\"\n [OutputPayload]=\"StepPayload(step, 'OutputPayload')\"\n [Invocation]=\"Invocation\">\n </mj-task-graph-variables>\n </div>\n } @else {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-hand-pointer\"\n Title=\"Select a step\"\n Message=\"Click a step on the canvas or in the list to see everything it recorded.\">\n </mj-empty-state>\n }\n }\n </div>\n </as-split-area>\n </as-split>\n } @else {\n <div class=\"wfr-json-pane\">\n <mj-code-editor\n [ngModel]=\"SelectedRunJson\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n style=\"width: 100%;\">\n </mj-code-editor>\n </div>\n }\n </aside>\n }\n </as-split-area>\n </as-split>\n }\n </mj-page-body>\n</mj-page-layout>\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.wfr-status-filters {\n display: flex;\n gap: var(--mj-space-1);\n align-items: center;\n}\n\n/* List alone until something is selected; two resizable panes after. The size is the user's \u2014 see\n the LAYOUT_KEYS note on the component for why it is persisted server-side rather than locally. */\n.wfr-split {\n height: 100%;\n min-height: 0;\n}\n\n/* A gutter you can find. The default is a hairline, which is discoverable only by accident. */\n:host ::ng-deep .wfr-split > .as-split-gutter,\n:host ::ng-deep .wfr-graph-split > .as-split-gutter {\n background: transparent !important;\n position: relative;\n}\n\n:host ::ng-deep .wfr-split > .as-split-gutter::after,\n:host ::ng-deep .wfr-graph-split > .as-split-gutter::after {\n content: '';\n position: absolute;\n inset: 0;\n margin: auto;\n background: var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n}\n\n:host ::ng-deep .wfr-split.as-horizontal > .as-split-gutter::after,\n:host ::ng-deep .wfr-graph-split.as-horizontal > .as-split-gutter::after {\n width: 2px;\n}\n\n:host ::ng-deep .wfr-graph-split.as-vertical > .as-split-gutter::after {\n height: 2px;\n}\n\n:host ::ng-deep .wfr-split > .as-split-gutter:hover::after,\n:host ::ng-deep .wfr-graph-split > .as-split-gutter:hover::after {\n background: var(--mj-brand-primary);\n}\n\n/* The canvas and the step record sit SIDE BY SIDE \u2014 a JSON record in a strip along the bottom shows\n about ten lines. Stacks below the breakpoint, where three columns would leave each too narrow to\n use. */\n.wfr-graph-split {\n flex: 1 1 auto;\n min-height: 0;\n}\n\n.wfr-list {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n overflow-y: auto;\n min-height: 0;\n}\n\n.wfr-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-2) var(--mj-space-3);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n text-align: left;\n cursor: pointer;\n color: var(--mj-text-primary);\n}\n\n.wfr-row:hover {\n border-color: var(--mj-border-strong);\n}\n\n.wfr-row:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.wfr-row-selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.wfr-row-main {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.wfr-row-name {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wfr-row-when {\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n}\n\n.wfr-row-status {\n flex: none;\n font-size: var(--mj-font-size-xs);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n padding: 2px var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n/* Status carries meaning, so it is encoded in colour as well as text \u2014 a failed run should be\n findable without reading every row. Skipped stays grey on purpose: a branch that was not taken\n is a normal outcome, not a warning. */\n.wfr-row-status[data-status='Complete'] {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 40%, transparent);\n}\n\n.wfr-row-status[data-status='Failed'] {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, transparent);\n}\n\n.wfr-row-status[data-status='Running'] {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.wfr-detail {\n display: flex;\n flex-direction: column;\n /* Fills its split area. Without it the column sizes to its CONTENT, so the canvas below \u2014\n `flex: 1 1 auto` of an auto-height parent \u2014 got its intrinsic height and left dead space. */\n height: 100%;\n min-height: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n}\n\n.wfr-detail-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-3);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.wfr-detail-title {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n min-width: 0;\n}\n\n.wfr-detail-name {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wfr-detail-actions {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n flex: none;\n}\n\n/* ============================================================\n The run list as a sortable table\n ============================================================\n A run list is scanned for two things \u2014 the slowest run and the one that failed \u2014 and neither is\n answerable by scrolling. Columns line up so a reader compares down a column rather than reading\n each row; `tabular-nums` keeps the timestamps from jittering as digits change. */\n.wfr-head,\n.wfr-row {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 1.3fr) minmax(0, 1.3fr) minmax(0, 0.7fr) minmax(0, 0.9fr);\n gap: var(--mj-space-2);\n align-items: center;\n}\n\n.wfr-head {\n position: sticky;\n top: 0;\n z-index: 1;\n padding: 0 var(--mj-space-3) var(--mj-space-1);\n background: var(--mj-bg-page);\n}\n\n.wfr-head-cell {\n display: flex;\n align-items: center;\n gap: 6px;\n background: none;\n border: none;\n padding: var(--mj-space-1) 0;\n font-size: var(--mj-font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-secondary);\n cursor: pointer;\n text-align: left;\n}\n\n.wfr-head-cell:hover {\n color: var(--mj-text-primary);\n}\n\n.wfr-head-cell i {\n opacity: 0.65;\n font-size: 0.85em;\n}\n\n.wfr-col-time,\n.wfr-col-duration {\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.wfr-col-status {\n justify-self: start;\n}\n\n/* ============================================================\n Detail panel: canvas + step JSON, or the whole run as JSON\n ============================================================ */\n.wfr-detail-tabs {\n display: flex;\n gap: var(--mj-space-1);\n padding: 0 var(--mj-space-3);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.wfr-tab {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n padding: var(--mj-space-2) var(--mj-space-2);\n font-size: var(--mj-font-size-sm);\n font-weight: 600;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.wfr-tab-active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.wfr-graph-pane {\n height: 100%;\n min-height: 12rem;\n}\n\n.wfr-steps-pane {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n border-left: 1px solid var(--mj-border-default);\n overflow: hidden;\n}\n\n/* Stacked layout puts the divider back on top, where the eye expects it. */\n:host ::ng-deep .as-vertical .wfr-steps-pane {\n border-left: none;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.wfr-step-list {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mj-space-1);\n padding: var(--mj-space-2);\n border-bottom: 1px solid var(--mj-border-default);\n max-height: 8rem;\n overflow-y: auto;\n flex: none;\n}\n\n.wfr-step {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: var(--mj-space-1) var(--mj-space-2);\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-primary);\n font-size: var(--mj-font-size-sm);\n cursor: pointer;\n text-align: left;\n}\n\n.wfr-step:hover {\n border-color: var(--mj-border-strong);\n}\n\n.wfr-step-selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n/* Work that never ran must not read like work that did \u2014 the same rule the run timeline follows. */\n.wfr-step[data-status='Skipped'] .wfr-step-name {\n text-decoration: line-through;\n color: var(--mj-text-secondary);\n}\n\n.wfr-step-name {\n font-weight: 600;\n}\n\n.wfr-step-meta {\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-secondary);\n}\n\n.wfr-step-json,\n.wfr-json-pane {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: auto;\n}\n\n.wfr-step-json-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mj-space-2);\n padding: var(--mj-space-1) var(--mj-space-3);\n font-weight: 600;\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-secondary);\n flex: none;\n}\n\n/* \u2500\u2500 live console \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.wfr-stall {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 8px 12px;\n margin: 0 12px 8px;\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 45%, var(--mj-border-default));\n border-left: 4px solid var(--mj-status-warning);\n border-radius: var(--mj-radius-md);\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n font-size: var(--mj-font-size-sm);\n}\n.wfr-stall-body {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n.wfr-stall i { color: var(--mj-status-warning); }\n.wfr-stall-copy {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.wfr-stall-copy code {\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n}\n.wfr-stall-reason { color: var(--mj-text-secondary); }\n.wfr-stall-actions { display: flex; flex-wrap: wrap; gap: 6px; }\n\n.wfr-replay {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n}\n.wfr-replay i { color: var(--mj-text-secondary); }\n.wfr-replay input[type='range'] { flex: 1; accent-color: var(--mj-brand-primary); }\n\n.wfr-engine {\n display: flex;\n gap: 8px;\n overflow-x: auto;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n}\n.wfr-tick {\n flex: none;\n padding: 3px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n white-space: nowrap;\n}\n.wfr-tick-held {\n border-color: color-mix(in srgb, var(--mj-status-warning, #d97706) 45%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-status-warning, #d97706) 8%, var(--mj-bg-surface));\n}\n.wfr-tick-paused { color: var(--mj-brand-primary); border-color: var(--mj-border-strong); }\n\n.wfr-insp-card {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 7px 10px;\n margin: 0 0 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n font-size: var(--mj-font-size-sm);\n color: var(--mj-text-primary);\n}\n.wfr-insp-card code {\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n}\n.wfr-insp-label {\n font-size: var(--mj-font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-secondary);\n}\n.wfr-insp-card[data-verdict='held'],\n.wfr-insp-bad {\n border-color: color-mix(in srgb, var(--mj-status-warning, #d97706) 45%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-status-warning, #d97706) 8%, var(--mj-bg-surface));\n}\n.wfr-insp-card[data-verdict='satisfied'] .wfr-insp-label { color: var(--mj-status-success); }\n.wfr-insp-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 8px; }\n.wfr-insp-hint {\n margin: 0 0 8px;\n font-size: var(--mj-font-size-xs);\n color: var(--mj-text-muted);\n}\n\n.wfr-bp-bar {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 6px 12px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n}\n.wfr-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 2px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: var(--mj-font-size-xs);\n cursor: pointer;\n}\n.wfr-chip-break { color: var(--mj-status-error); border-color: color-mix(in srgb, var(--mj-status-error) 40%, transparent); }\n.wfr-chip-break i { font-size: 7px; }\n.wfr-chip-paused {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n cursor: default;\n}\n.wfr-chip-forced {\n color: var(--mj-status-warning);\n border-color: color-mix(in srgb, var(--mj-status-warning) 40%, transparent);\n cursor: default;\n}\n.wfr-chip-x {\n font-size: 14px;\n line-height: 1;\n padding: 0 2px;\n}\n.wfr-chip-x:hover { color: var(--mj-text-primary); }\n\n.wfr-bp {\n width: 22px;\n height: 22px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin: 0 0 8px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n}\n.wfr-bp:hover { color: var(--mj-status-error); }\n.wfr-bp-on,\n.wfr-bp-on:hover { color: var(--mj-status-error); }\n.wfr-bp i { font-size: 10px; }\n.wfr-bp:disabled { opacity: 0.45; cursor: default; }\n\n.wfr-editor-card {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px;\n margin: 0 0 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-card);\n}\n.wfr-editor-danger {\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, var(--mj-border-default));\n}\n.wfr-json-edit {\n width: 100%;\n min-height: 120px;\n font-family: var(--mj-font-mono, ui-monospace, monospace);\n font-size: var(--mj-font-size-xs);\n resize: vertical;\n}\n.wfr-editor-error { color: var(--mj-status-error); font-size: var(--mj-font-size-xs); }\n.wfr-insp-failure { border-color: var(--mj-status-error); color: var(--mj-status-error); }\n"] }]
|
|
1814
1835
|
}], () => [{ type: i0.ChangeDetectorRef }], { onViewportResized: [{
|
|
1815
1836
|
type: HostListener,
|
|
1816
1837
|
args: ['window:resize']
|
|
@@ -1818,5 +1839,5 @@ export { WorkflowRunsResourceComponent };
|
|
|
1818
1839
|
type: ViewChild,
|
|
1819
1840
|
args: [TaskGraphDebuggerComponent]
|
|
1820
1841
|
}] }); })();
|
|
1821
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WorkflowRunsResourceComponent, { className: "WorkflowRunsResourceComponent", filePath: "src/Workflows/components/workflow-runs-resource.component.ts", lineNumber:
|
|
1842
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WorkflowRunsResourceComponent, { className: "WorkflowRunsResourceComponent", filePath: "src/Workflows/components/workflow-runs-resource.component.ts", lineNumber: 104 }); })();
|
|
1822
1843
|
//# sourceMappingURL=workflow-runs-resource.component.js.map
|