@lostgradient/cinder 0.9.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/components.json +82 -4
- package/dist/components/access-gate/index.js +381 -239
- package/dist/components/chat/builders.d.ts +17 -8
- package/dist/components/chat/conversation-model.d.ts +1 -1
- package/dist/components/chat/index.d.ts +1 -1
- package/dist/components/chat/index.js +300 -17
- package/dist/components/chat/utilities/conversation.d.ts +6 -6
- package/dist/components/chat-conversation-header/index.js +19 -6
- package/dist/components/chat-conversation-list/index.js +19 -6
- package/dist/components/code-block/code-block.css +15 -9
- package/dist/components/code-block/code-block.variables.js +8 -2
- package/dist/components/confirm-dialog/confirm-dialog.css +2 -0
- package/dist/components/confirm-dialog/confirm-dialog.schema.js +10 -1
- package/dist/components/confirm-dialog/confirm-dialog.types.d.ts +7 -0
- package/dist/components/confirm-dialog/index.js +478 -106
- package/dist/components/connection-indicator/connection-indicator.css +136 -0
- package/dist/components/connection-indicator/connection-indicator.css.d.ts +1 -0
- package/dist/components/connection-indicator/connection-indicator.schema.d.ts +3 -0
- package/dist/components/connection-indicator/connection-indicator.schema.js +89 -0
- package/dist/components/connection-indicator/connection-indicator.svelte.d.ts +21 -0
- package/dist/components/connection-indicator/connection-indicator.types.d.ts +46 -0
- package/dist/components/connection-indicator/connection-indicator.variables.d.ts +2 -0
- package/dist/components/connection-indicator/connection-indicator.variables.js +61 -0
- package/dist/components/connection-indicator/index.d.ts +5 -0
- package/dist/components/connection-indicator/index.js +409 -0
- package/dist/components/container/container.schema.js +4 -4
- package/dist/components/faceted-filter-bar/faceted-filter-bar.schema.js +5 -1
- package/dist/components/faceted-filter-bar/faceted-filter-bar.types.d.ts +2 -0
- package/dist/components/faceted-filter-bar/index.js +40 -31
- package/dist/components/invocation-rule-builder/index.d.ts +1 -1
- package/dist/components/invocation-rule-builder/index.js +305 -150
- package/dist/components/invocation-rule-builder/invocation-rule-builder.css +28 -0
- package/dist/components/invocation-rule-builder/invocation-rule-builder.schema.js +89 -5
- package/dist/components/invocation-rule-builder/invocation-rule-builder.svelte.d.ts +2 -1
- package/dist/components/invocation-rule-builder/invocation-rule-builder.types.d.ts +114 -16
- package/dist/components/navigation-bar/index.js +11 -17
- package/dist/components/run-step-timeline/index.d.ts +1 -1
- package/dist/components/run-step-timeline/index.js +1052 -560
- package/dist/components/run-step-timeline/run-step-branch-disclosure.svelte.d.ts +17 -0
- package/dist/components/run-step-timeline/run-step-timeline.css +124 -0
- package/dist/components/run-step-timeline/run-step-timeline.schema.js +873 -350
- package/dist/components/run-step-timeline/run-step-timeline.svelte.d.ts +1 -15
- package/dist/components/run-step-timeline/run-step-timeline.types.d.ts +182 -5
- package/dist/components/run-step-timeline/run-step-timeline.utilities.d.ts +60 -0
- package/dist/components/schedule-builder/index.d.ts +5 -0
- package/dist/components/schedule-builder/index.js +3176 -0
- package/dist/components/schedule-builder/schedule-builder.css +121 -0
- package/dist/components/schedule-builder/schedule-builder.css.d.ts +1 -0
- package/dist/components/schedule-builder/schedule-builder.schema.d.ts +3 -0
- package/dist/components/schedule-builder/schedule-builder.schema.js +141 -0
- package/dist/components/schedule-builder/schedule-builder.svelte.d.ts +22 -0
- package/dist/components/schedule-builder/schedule-builder.types.d.ts +130 -0
- package/dist/components/schedule-builder/schedule-builder.utilities.d.ts +78 -0
- package/dist/components/schedule-builder/schedule-builder.variables.d.ts +2 -0
- package/dist/components/schedule-builder/schedule-builder.variables.js +61 -0
- package/dist/components/tag-input/index.js +22 -4
- package/dist/components/tag-input/tag-input.schema.js +5 -1
- package/dist/components/tag-input/tag-input.types.d.ts +4 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +23069 -20833
- package/dist/server/components/access-gate/index.js +2 -1
- package/dist/server/components/chat/index.js +4 -4
- package/dist/server/components/chat-conversation-header/index.js +5 -5
- package/dist/server/components/chat-conversation-list/index.js +3 -3
- package/dist/server/components/color-field/index.js +2 -2
- package/dist/server/components/confirm-dialog/index.js +7 -2
- package/dist/server/components/connection-indicator/index.js +16 -0
- package/dist/server/components/data-table/index.js +3 -3
- package/dist/server/components/diff-viewer/index.js +4 -3
- package/dist/server/components/faceted-filter-bar/index.js +1 -1
- package/dist/server/components/invocation-rule-builder/index.js +1 -1
- package/dist/server/components/json-schema-editor/index.js +4 -3
- package/dist/server/components/navigation-bar/index.js +1 -1
- package/dist/server/components/review-editor/index.js +4 -3
- package/dist/server/components/run-step-timeline/index.js +1 -1
- package/dist/server/components/schedule-builder/index.js +30 -0
- package/dist/server/components/side-navigation/index.js +2 -2
- package/dist/server/components/table/index.js +3 -3
- package/dist/server/components/tag-input/index.js +1 -1
- package/dist/server/components/time-field/index.js +5 -3
- package/dist/server/index.js +105 -92
- package/dist/server/index.server-0sx92swg.js +9 -0
- package/dist/server/{index.server-mzzb7dnm.js → index.server-2bbwajb2.js} +1 -1
- package/dist/server/{index.server-q7w4jw89.js → index.server-2s5h1d05.js} +2 -2
- package/dist/server/{index.server-dg83ke3k.js → index.server-2zdbz3rj.js} +1 -1
- package/dist/server/{index.server-0jhra85x.js → index.server-3w72dxz7.js} +4 -4
- package/dist/server/{index.server-5tf22d6e.js → index.server-4wx0qven.js} +3 -3
- package/dist/server/{index.server-qh9qzd5t.js → index.server-4x4hgvqe.js} +283 -13
- package/dist/server/{index.server-c6pe4kaf.js → index.server-5gzyqv78.js} +1 -1
- package/dist/server/{index.server-mqt1ngqw.js → index.server-6hnfzc7f.js} +19 -6
- package/dist/server/{index.server-894t97kv.js → index.server-7yvpb6z7.js} +4 -4
- package/dist/server/index.server-be9bpqeh.js +93 -0
- package/dist/server/{index.server-f3z7tpxr.js → index.server-c42b462p.js} +2 -4
- package/dist/server/{index.server-7vyzen5x.js → index.server-c5qv3p61.js} +171 -63
- package/dist/server/index.server-cch0eed5.js +144 -0
- package/dist/server/{index.server-btgb3d56.js → index.server-d5a5ccz7.js} +18 -12
- package/dist/server/index.server-g5jgq3jp.js +793 -0
- package/dist/server/index.server-gmh5ar16.js +2 -0
- package/dist/server/{index.server-0atyznp7.js → index.server-h89zk5ev.js} +7 -7
- package/dist/server/{index.server-jxg42jpz.js → index.server-jdcq5zza.js} +7 -7
- package/dist/server/{index.server-2dga5yzr.js → index.server-jfrssta6.js} +1 -1
- package/dist/server/{index.server-fy068yne.js → index.server-jj76374p.js} +1 -1
- package/dist/server/{index.server-39ne5cd1.js → index.server-pxq277t5.js} +32 -1
- package/dist/server/index.server-qbkxz7r2.js +750 -0
- package/dist/server/{index.server-marjz8ps.js → index.server-tcay903b.js} +3 -2
- package/dist/server/{index.server-yz4k36cw.js → index.server-z7hxtqs1.js} +1 -1
- package/package.json +87 -97
- package/src/components/chat/builders.ts +445 -14
- package/src/components/chat/conversation-model.ts +1 -0
- package/src/components/chat/index.ts +1 -0
- package/src/components/chat/utilities/conversation.ts +33 -15
- package/src/components/code-block/code-block.css +15 -9
- package/src/components/code-block/code-block.variables.json +7 -1
- package/src/components/code-block/code-block.variables.ts +7 -1
- package/src/components/confirm-dialog/confirm-dialog.css +2 -0
- package/src/components/confirm-dialog/confirm-dialog.schema.json +8 -0
- package/src/components/confirm-dialog/confirm-dialog.schema.ts +10 -0
- package/src/components/confirm-dialog/confirm-dialog.svelte +31 -3
- package/src/components/confirm-dialog/confirm-dialog.types.ts +7 -0
- package/src/components/connection-indicator/connection-indicator.css +136 -0
- package/src/components/connection-indicator/connection-indicator.examples.json +31 -0
- package/src/components/connection-indicator/connection-indicator.schema.json +29 -0
- package/src/components/connection-indicator/connection-indicator.schema.ts +36 -0
- package/src/components/connection-indicator/connection-indicator.svelte +63 -0
- package/src/components/connection-indicator/connection-indicator.types.ts +58 -0
- package/src/components/connection-indicator/connection-indicator.variables.json +1 -0
- package/src/components/connection-indicator/connection-indicator.variables.ts +3 -0
- package/src/components/connection-indicator/index.ts +10 -0
- package/src/components/container/container.schema.json +3 -3
- package/src/components/container/container.schema.ts +3 -3
- package/src/components/faceted-filter-bar/faceted-filter-bar.schema.json +4 -0
- package/src/components/faceted-filter-bar/faceted-filter-bar.schema.ts +4 -0
- package/src/components/faceted-filter-bar/faceted-filter-bar.svelte +13 -11
- package/src/components/faceted-filter-bar/faceted-filter-bar.types.ts +2 -0
- package/src/components/invocation-rule-builder/index.ts +4 -0
- package/src/components/invocation-rule-builder/invocation-rule-builder.css +28 -0
- package/src/components/invocation-rule-builder/invocation-rule-builder.examples.json +6 -0
- package/src/components/invocation-rule-builder/invocation-rule-builder.schema.json +76 -3
- package/src/components/invocation-rule-builder/invocation-rule-builder.schema.ts +83 -3
- package/src/components/invocation-rule-builder/invocation-rule-builder.svelte +326 -113
- package/src/components/invocation-rule-builder/invocation-rule-builder.types.ts +157 -43
- package/src/components/navigation-bar/navigation-bar.svelte +2 -2
- package/src/components/run-step-timeline/index.ts +8 -0
- package/src/components/run-step-timeline/run-step-branch-disclosure.svelte +16 -0
- package/src/components/run-step-timeline/run-step-timeline.css +124 -0
- package/src/components/run-step-timeline/run-step-timeline.examples.json +18 -0
- package/src/components/run-step-timeline/run-step-timeline.schema.json +872 -349
- package/src/components/run-step-timeline/run-step-timeline.schema.ts +931 -349
- package/src/components/run-step-timeline/run-step-timeline.svelte +388 -269
- package/src/components/run-step-timeline/run-step-timeline.types.ts +192 -5
- package/src/components/run-step-timeline/run-step-timeline.utilities.ts +310 -0
- package/src/components/schedule-builder/index.ts +14 -0
- package/src/components/schedule-builder/schedule-builder.css +121 -0
- package/src/components/schedule-builder/schedule-builder.examples.json +31 -0
- package/src/components/schedule-builder/schedule-builder.schema.json +78 -0
- package/src/components/schedule-builder/schedule-builder.schema.ts +86 -0
- package/src/components/schedule-builder/schedule-builder.svelte +629 -0
- package/src/components/schedule-builder/schedule-builder.types.ts +137 -0
- package/src/components/schedule-builder/schedule-builder.utilities.ts +344 -0
- package/src/components/schedule-builder/schedule-builder.variables.json +1 -0
- package/src/components/schedule-builder/schedule-builder.variables.ts +3 -0
- package/src/components/tag-input/tag-input.schema.json +4 -0
- package/src/components/tag-input/tag-input.schema.ts +4 -0
- package/src/components/tag-input/tag-input.svelte +20 -3
- package/src/components/tag-input/tag-input.types.ts +4 -0
- package/src/index.ts +23 -0
- package/src/styles/components.css +2 -0
- package/dist/server/index.server-qk1h0n02.js +0 -393
|
@@ -6,157 +6,175 @@ export {};
|
|
|
6
6
|
import { classNames } from '../../utilities/class-names.ts';
|
|
7
7
|
import Badge from '../badge/badge.svelte';
|
|
8
8
|
import Collapsible from '../collapsible/collapsible.svelte';
|
|
9
|
+
import RunStepBranchDisclosure from './run-step-branch-disclosure.svelte';
|
|
9
10
|
import Link from '../link/link.svelte';
|
|
10
11
|
import Progress from '../progress/progress.svelte';
|
|
11
12
|
import StatusDot from '../status-dot/status-dot.svelte';
|
|
13
|
+
import { actionsCountLabel, badgeVariant, branchGroupHasCurrentStep, branchOutcomeSummary, branchStartsCollapsed, hasProgress, hiddenNestedStepLabel, isCurrent, isTerminal, laneOutcomeBadgeVariant, laneOutcomeLabel, metadataItems, relocateCompensationEntries, relocateCompensationSteps, safeStepLinkHref, statusDotStatus, statusLabel, } from './run-step-timeline.utilities.ts';
|
|
12
14
|
const MAX_NESTED_STEP_DEPTH = 3;
|
|
13
15
|
let { steps, label, class: className, children, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, ...rest } = $props();
|
|
14
16
|
const resolvedAriaLabel = $derived(ariaLabelledby === undefined && ariaLabel === undefined ? label : ariaLabel);
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
switch (status) {
|
|
19
|
-
case 'succeeded':
|
|
20
|
-
return 'success';
|
|
21
|
-
case 'failed':
|
|
22
|
-
return 'danger';
|
|
23
|
-
case 'running':
|
|
24
|
-
return 'online';
|
|
25
|
-
case 'retrying':
|
|
26
|
-
return 'warning';
|
|
27
|
-
case 'waiting_approval':
|
|
28
|
-
return 'accent';
|
|
29
|
-
case 'cancelled':
|
|
30
|
-
return 'offline';
|
|
31
|
-
case 'skipped':
|
|
32
|
-
return 'neutral';
|
|
33
|
-
case 'pending':
|
|
34
|
-
return 'pending';
|
|
35
|
-
}
|
|
17
|
+
const renderedEntries = $derived(flattenEntries(relocateCompensationEntries(steps)));
|
|
18
|
+
function isBranchGroup(entry) {
|
|
19
|
+
return 'kind' in entry && entry.kind === 'branch';
|
|
36
20
|
}
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
21
|
+
// Flatten the top-level entries, keeping contiguous runs of steps together so
|
|
22
|
+
// the connector rail spans them, and emitting a standalone row for each
|
|
23
|
+
// branch group (which renders its own parallel sub-lanes).
|
|
24
|
+
function flattenEntries(entries) {
|
|
25
|
+
const result = [];
|
|
26
|
+
let stepRun = [];
|
|
27
|
+
const flushRun = () => {
|
|
28
|
+
if (stepRun.length === 0)
|
|
29
|
+
return;
|
|
30
|
+
result.push(...flattenSteps(stepRun, ''));
|
|
31
|
+
stepRun = [];
|
|
32
|
+
};
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
if (isBranchGroup(entry)) {
|
|
35
|
+
flushRun();
|
|
36
|
+
result.push({
|
|
37
|
+
kind: 'branch',
|
|
38
|
+
group: entry,
|
|
39
|
+
// A raw `%` can never appear in an escaped step-path segment
|
|
40
|
+
// (escapeStepPathSegment turns `%` into `%25`), so this branch key
|
|
41
|
+
// cannot collide with any step's path key.
|
|
42
|
+
pathKey: `%branch/${escapeStepPathSegment(entry.id)}`,
|
|
43
|
+
connectorAfter: 'hidden',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
stepRun.push(entry);
|
|
48
|
+
}
|
|
56
49
|
}
|
|
50
|
+
flushRun();
|
|
51
|
+
// `flattenSteps` computes `aria-current` within each contiguous run; on the
|
|
52
|
+
// outer rail, keep a SINGLE deepest current row across the whole timeline so
|
|
53
|
+
// a branch group between two active runs doesn't produce two current rows.
|
|
54
|
+
// `applyGlobalRailConnectors` then reconnects the rail across run/branch
|
|
55
|
+
// boundaries — each run is flattened in isolation, so its last row and the
|
|
56
|
+
// branch rows would otherwise both hide their connector and split one
|
|
57
|
+
// ordered run (step → branch → step) into disconnected rails.
|
|
58
|
+
// `applyGlobalTopLevelCompensates` likewise resolves `compensates` for
|
|
59
|
+
// top-level steps across the whole rail, since a compensating step can be
|
|
60
|
+
// separated from its forward sibling by a branch group (different run).
|
|
61
|
+
return applyGlobalRailConnectors(applyGlobalTopLevelCompensates(applyGlobalRailAriaCurrent(result)));
|
|
57
62
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return 'neutral';
|
|
72
|
-
case 'skipped':
|
|
73
|
-
return 'neutral';
|
|
74
|
-
case 'pending':
|
|
75
|
-
return 'neutral';
|
|
63
|
+
// Resolve `compensates` for TOP-LEVEL steps across the entire outer rail. Each
|
|
64
|
+
// contiguous run is flattened in isolation, so a compensating top-level step
|
|
65
|
+
// separated from its forward sibling by a branch group (e.g. `charge → branch
|
|
66
|
+
// → refund` where refund compensates charge) would never find it in its own
|
|
67
|
+
// run's label map. Nested steps are unaffected: a branch group never nests
|
|
68
|
+
// inside a step's children, so nested siblings always share a run and are
|
|
69
|
+
// already resolved correctly by `flattenSteps`.
|
|
70
|
+
function applyGlobalTopLevelCompensates(rows) {
|
|
71
|
+
const topLevelLabelByPathKey = new Map();
|
|
72
|
+
for (const row of rows) {
|
|
73
|
+
if (row.kind === 'step' && row.depth === 0) {
|
|
74
|
+
topLevelLabelByPathKey.set(row.pathKey, row.step.label);
|
|
75
|
+
}
|
|
76
76
|
}
|
|
77
|
+
return rows.map((row) => {
|
|
78
|
+
if (row.kind !== 'step' || row.depth !== 0 || row.step.compensates === undefined)
|
|
79
|
+
return row;
|
|
80
|
+
return {
|
|
81
|
+
...row,
|
|
82
|
+
compensatesLabel: resolveSiblingCompensatesLabel(row, topLevelLabelByPathKey),
|
|
83
|
+
};
|
|
84
|
+
});
|
|
77
85
|
}
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
status === 'cancelled' ||
|
|
83
|
-
status === 'skipped');
|
|
84
|
-
}
|
|
85
|
-
function isCurrent(status) {
|
|
86
|
-
return status === 'running' || status === 'retrying' || status === 'waiting_approval';
|
|
87
|
-
}
|
|
88
|
-
// Whether this step has a progress bar to show.
|
|
89
|
-
function hasProgress(step) {
|
|
90
|
-
return step.progress !== undefined && isCurrent(step.status);
|
|
86
|
+
// A rail row's effective depth for connector purposes. Branch groups always
|
|
87
|
+
// render at the top level, so they sit at depth 0.
|
|
88
|
+
function railRowDepth(row) {
|
|
89
|
+
return row.kind === 'branch' ? 0 : row.depth;
|
|
91
90
|
}
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
if (step.attemptCount !== undefined && step.attemptCount > 1) {
|
|
105
|
-
items.push({ term: 'Attempts', definition: String(step.attemptCount) });
|
|
106
|
-
}
|
|
107
|
-
return items;
|
|
108
|
-
}
|
|
109
|
-
function actionsCountLabel(actionsCount) {
|
|
110
|
-
return actionsCount === 1 ? '1 action' : `${actionsCount} actions`;
|
|
91
|
+
// Recompute each top-level row's downward connector against the ACTUAL next
|
|
92
|
+
// rendered row (including branch rows), rather than the per-run view that
|
|
93
|
+
// `flattenSteps` sees. A connector shows unless the row is last or the next
|
|
94
|
+
// row dedents to a shallower level — so a depth-0 step followed by a branch,
|
|
95
|
+
// and a branch followed by another run, both stay linked.
|
|
96
|
+
function applyGlobalRailConnectors(rows) {
|
|
97
|
+
return rows.map((row, index) => {
|
|
98
|
+
const next = rows[index + 1];
|
|
99
|
+
const connectorAfter = next === undefined || railRowDepth(next) < railRowDepth(row) ? 'hidden' : 'visible';
|
|
100
|
+
return { ...row, connectorAfter };
|
|
101
|
+
});
|
|
111
102
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
103
|
+
// The "current depth" of a rail row: deeper is more current. A depth-limit row
|
|
104
|
+
// that hides a current descendant counts one level below its own depth.
|
|
105
|
+
function rowCurrentDepth(row) {
|
|
106
|
+
if (row.kind === 'depth-limit')
|
|
107
|
+
return row.hiddenCurrent ? row.depth + 1 : -1;
|
|
108
|
+
if (row.kind === 'step')
|
|
109
|
+
return isCurrent(row.step.status) ? row.depth : -1;
|
|
110
|
+
return -1;
|
|
116
111
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return undefined;
|
|
128
|
-
if (/^[A-Za-z][A-Za-z\d+.-]*:/.test(trimmedHref)) {
|
|
129
|
-
try {
|
|
130
|
-
const parsedUrl = new URL(trimmedHref);
|
|
131
|
-
return parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:'
|
|
132
|
-
? trimmedHref
|
|
133
|
-
: undefined;
|
|
134
|
-
}
|
|
135
|
-
catch {
|
|
136
|
-
return undefined;
|
|
112
|
+
// Reduce the rail to a single `aria-current="step"` row: the deepest current
|
|
113
|
+
// step across all top-level runs. Branch groups do not participate.
|
|
114
|
+
function applyGlobalRailAriaCurrent(rows) {
|
|
115
|
+
let deepestRow;
|
|
116
|
+
let deepestDepth = -1;
|
|
117
|
+
for (const row of rows) {
|
|
118
|
+
const depth = rowCurrentDepth(row);
|
|
119
|
+
if (depth > deepestDepth) {
|
|
120
|
+
deepestDepth = depth;
|
|
121
|
+
deepestRow = row;
|
|
137
122
|
}
|
|
138
123
|
}
|
|
139
|
-
return
|
|
124
|
+
return rows.map((row) => row.kind === 'branch' ? row : { ...row, ariaCurrent: row === deepestRow });
|
|
140
125
|
}
|
|
141
|
-
|
|
126
|
+
// Flatten a RunStep[] (with nested children) into rendered rows, computing the
|
|
127
|
+
// connector rail, the single deepest `aria-current` row, and resolved
|
|
128
|
+
// compensation labels. Reused for the main rail and for each branch lane.
|
|
129
|
+
function flattenSteps(list, pathPrefix) {
|
|
142
130
|
const rows = [];
|
|
143
|
-
appendRunStepRows(rows,
|
|
131
|
+
appendRunStepRows(rows, relocateCompensationSteps(list), 0, pathPrefix);
|
|
144
132
|
const currentRowIndex = deepestCurrentStepIndex(rows);
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
133
|
+
// Index every step row by its unique path key (built from the escaped id
|
|
134
|
+
// chain). A `compensates` id then resolves to a true SIBLING — a step under
|
|
135
|
+
// the same parent — rather than any same-id descendant elsewhere in the run
|
|
136
|
+
// or lane. Iterating the already-bounded, depth-capped rows also avoids
|
|
137
|
+
// recursing the full step tree, which could overflow the stack.
|
|
138
|
+
const labelByPathKey = new Map();
|
|
139
|
+
for (const row of rows) {
|
|
140
|
+
if (row.kind === 'step')
|
|
141
|
+
labelByPathKey.set(row.pathKey, row.step.label);
|
|
142
|
+
}
|
|
143
|
+
return rows.map((row, index) => {
|
|
144
|
+
const next = rows[index + 1];
|
|
145
|
+
const connectorAfter = next === undefined || next.depth < row.depth ? 'hidden' : 'visible';
|
|
146
|
+
const ariaCurrent = index === currentRowIndex;
|
|
147
|
+
if (row.kind === 'depth-limit') {
|
|
148
|
+
return { ...row, connectorAfter, ariaCurrent };
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
...row,
|
|
152
|
+
connectorAfter,
|
|
153
|
+
ariaCurrent,
|
|
154
|
+
compensatesLabel: resolveSiblingCompensatesLabel(row, labelByPathKey),
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// Resolve a step's `compensates` id to the label of a sibling step (one under
|
|
159
|
+
// the same parent), or `undefined` when there is no such sibling. Never
|
|
160
|
+
// resolves to the step itself.
|
|
161
|
+
function resolveSiblingCompensatesLabel(row, labelByPathKey) {
|
|
162
|
+
if (row.step.compensates === undefined)
|
|
163
|
+
return undefined;
|
|
164
|
+
const lastSeparator = row.pathKey.lastIndexOf('/');
|
|
165
|
+
const parentPrefix = lastSeparator === -1 ? '' : row.pathKey.slice(0, lastSeparator);
|
|
166
|
+
const siblingPathKey = nestedStepPathKey(parentPrefix, row.step.compensates);
|
|
167
|
+
if (siblingPathKey === row.pathKey)
|
|
168
|
+
return undefined;
|
|
169
|
+
return labelByPathKey.get(siblingPathKey);
|
|
152
170
|
}
|
|
153
|
-
function appendRunStepRows(rows,
|
|
154
|
-
for (const step of
|
|
171
|
+
function appendRunStepRows(rows, list, depth, pathPrefix) {
|
|
172
|
+
for (const step of list) {
|
|
155
173
|
const pathKey = nestedStepPathKey(pathPrefix, step.id);
|
|
156
174
|
rows.push({ kind: 'step', step, depth, pathKey });
|
|
157
175
|
if (step.children && step.children.length > 0) {
|
|
158
176
|
if (depth < MAX_NESTED_STEP_DEPTH) {
|
|
159
|
-
appendRunStepRows(rows, step.children, depth + 1, pathKey);
|
|
177
|
+
appendRunStepRows(rows, relocateCompensationSteps(step.children), depth + 1, pathKey);
|
|
160
178
|
}
|
|
161
179
|
else {
|
|
162
180
|
const hiddenSummary = summarizeNestedRunSteps(step.children);
|
|
@@ -178,10 +196,10 @@ function nestedStepPathKey(pathPrefix, stepId) {
|
|
|
178
196
|
function escapeStepPathSegment(stepId) {
|
|
179
197
|
return stepId.replaceAll('%', '%25').replaceAll('/', '%2F');
|
|
180
198
|
}
|
|
181
|
-
function summarizeNestedRunSteps(
|
|
199
|
+
function summarizeNestedRunSteps(list) {
|
|
182
200
|
let count = 0;
|
|
183
201
|
let hasCurrent = false;
|
|
184
|
-
const stack = [...
|
|
202
|
+
const stack = [...list];
|
|
185
203
|
while (stack.length > 0) {
|
|
186
204
|
const step = stack.pop();
|
|
187
205
|
if (step === undefined)
|
|
@@ -189,10 +207,10 @@ function summarizeNestedRunSteps(steps) {
|
|
|
189
207
|
count += 1;
|
|
190
208
|
if (isCurrent(step.status))
|
|
191
209
|
hasCurrent = true;
|
|
192
|
-
const
|
|
193
|
-
if (
|
|
194
|
-
for (let index =
|
|
195
|
-
const child =
|
|
210
|
+
const stepChildren = step.children;
|
|
211
|
+
if (stepChildren) {
|
|
212
|
+
for (let index = stepChildren.length - 1; index >= 0; index -= 1) {
|
|
213
|
+
const child = stepChildren[index];
|
|
196
214
|
if (child)
|
|
197
215
|
stack.push(child);
|
|
198
216
|
}
|
|
@@ -216,162 +234,263 @@ function deepestCurrentStepIndex(rows) {
|
|
|
216
234
|
});
|
|
217
235
|
return currentIndex;
|
|
218
236
|
}
|
|
237
|
+
function laneRows(lane) {
|
|
238
|
+
return flattenSteps(lane.steps, '');
|
|
239
|
+
}
|
|
240
|
+
function laneStateLabel(lane) {
|
|
241
|
+
return lane.outcome === undefined ? 'racing' : laneOutcomeLabel(lane.outcome).toLowerCase();
|
|
242
|
+
}
|
|
219
243
|
</script>
|
|
220
244
|
|
|
245
|
+
{#snippet stepItem(row: RenderedStepRow)}
|
|
246
|
+
{@const step = row.step}
|
|
247
|
+
{@const terminal = isTerminal(step.status)}
|
|
248
|
+
{@const metadata = metadataItems(step)}
|
|
249
|
+
<li
|
|
250
|
+
class="cinder-run-step-timeline__item"
|
|
251
|
+
data-cinder-status={step.status}
|
|
252
|
+
data-cinder-depth={row.depth}
|
|
253
|
+
data-cinder-path={row.pathKey}
|
|
254
|
+
data-cinder-terminal={terminal ? '' : undefined}
|
|
255
|
+
data-cinder-rewound={step.rewound ? '' : undefined}
|
|
256
|
+
data-cinder-compensation={row.compensatesLabel !== undefined ? '' : undefined}
|
|
257
|
+
data-cinder-connector-after={row.connectorAfter}
|
|
258
|
+
aria-current={row.ariaCurrent ? 'step' : undefined}
|
|
259
|
+
style:--_cinder-rst-depth={row.depth}
|
|
260
|
+
>
|
|
261
|
+
<div class="cinder-run-step-timeline__event">
|
|
262
|
+
<span class="cinder-run-step-timeline__marker" aria-hidden="true" inert>
|
|
263
|
+
<StatusDot
|
|
264
|
+
status={statusDotStatus(step.status)}
|
|
265
|
+
label={statusLabel(step.status)}
|
|
266
|
+
showLabel={false}
|
|
267
|
+
size="md"
|
|
268
|
+
/>
|
|
269
|
+
</span>
|
|
270
|
+
|
|
271
|
+
<div class="cinder-run-step-timeline__content">
|
|
272
|
+
<div class="cinder-run-step-timeline__header">
|
|
273
|
+
<span class="cinder-run-step-timeline__label">{step.label}</span>
|
|
274
|
+
{#if step.link}
|
|
275
|
+
{@const safeLinkHref = safeStepLinkHref(step.link.href)}
|
|
276
|
+
{#if safeLinkHref}
|
|
277
|
+
<Link href={safeLinkHref} class="cinder-run-step-timeline__link">
|
|
278
|
+
{step.link.label}
|
|
279
|
+
</Link>
|
|
280
|
+
{:else}
|
|
281
|
+
<span class="cinder-run-step-timeline__link cinder-run-step-timeline__link--unsafe">
|
|
282
|
+
{step.link.label}
|
|
283
|
+
</span>
|
|
284
|
+
{/if}
|
|
285
|
+
{/if}
|
|
286
|
+
<Badge
|
|
287
|
+
class="cinder-run-step-timeline__status"
|
|
288
|
+
variant={badgeVariant(step.status)}
|
|
289
|
+
size="xs"
|
|
290
|
+
aria-label={`Status: ${statusLabel(step.status)}`}
|
|
291
|
+
>
|
|
292
|
+
{statusLabel(step.status)}
|
|
293
|
+
</Badge>
|
|
294
|
+
{#if step.rewound}
|
|
295
|
+
<Badge
|
|
296
|
+
class="cinder-run-step-timeline__flag"
|
|
297
|
+
variant="neutral"
|
|
298
|
+
size="xs"
|
|
299
|
+
aria-label="State: rewound — speculatively executed, then unwound"
|
|
300
|
+
>
|
|
301
|
+
Rewound
|
|
302
|
+
</Badge>
|
|
303
|
+
{/if}
|
|
304
|
+
{#if row.compensatesLabel !== undefined}
|
|
305
|
+
<Badge
|
|
306
|
+
class="cinder-run-step-timeline__flag"
|
|
307
|
+
variant="warning"
|
|
308
|
+
size="xs"
|
|
309
|
+
aria-label={`Compensates ${row.compensatesLabel} — reverses the forward step`}
|
|
310
|
+
>
|
|
311
|
+
Compensates {row.compensatesLabel}
|
|
312
|
+
</Badge>
|
|
313
|
+
{/if}
|
|
314
|
+
{#if step.attemptCount !== undefined && step.attemptCount > 1}
|
|
315
|
+
<Badge variant="neutral" size="xs" mono>attempt {step.attemptCount}</Badge>
|
|
316
|
+
{/if}
|
|
317
|
+
{#if step.actionsCount !== undefined && step.actionsCount > 0}
|
|
318
|
+
<Badge variant="neutral" size="xs" mono>{actionsCountLabel(step.actionsCount)}</Badge>
|
|
319
|
+
{/if}
|
|
320
|
+
</div>
|
|
321
|
+
|
|
322
|
+
{#if hasProgress(step)}
|
|
323
|
+
<div class="cinder-run-step-timeline__progress">
|
|
324
|
+
<Progress
|
|
325
|
+
value={step.progress ?? 0}
|
|
326
|
+
max={step.progressMax ?? 100}
|
|
327
|
+
size="sm"
|
|
328
|
+
ariaLabel={`${step.label} progress`}
|
|
329
|
+
/>
|
|
330
|
+
</div>
|
|
331
|
+
{/if}
|
|
332
|
+
|
|
333
|
+
{#if metadata.length > 0}
|
|
334
|
+
<dl class="cinder-run-step-timeline__meta">
|
|
335
|
+
{#each metadata as item (item.term)}
|
|
336
|
+
<div class="cinder-run-step-timeline__meta-row">
|
|
337
|
+
<dt class="cinder-run-step-timeline__meta-term">{item.term}</dt>
|
|
338
|
+
<dd class="cinder-run-step-timeline__meta-definition">{item.definition}</dd>
|
|
339
|
+
</div>
|
|
340
|
+
{/each}
|
|
341
|
+
</dl>
|
|
342
|
+
{/if}
|
|
343
|
+
|
|
344
|
+
{#if step.details && step.details.length > 0}
|
|
345
|
+
<div class="cinder-run-step-timeline__details">
|
|
346
|
+
{#each step.details as detail (detail.id)}
|
|
347
|
+
<Collapsible trigger={detail.label}>
|
|
348
|
+
<pre class="cinder-run-step-timeline__detail-content">{detail.content}</pre>
|
|
349
|
+
</Collapsible>
|
|
350
|
+
{/each}
|
|
351
|
+
</div>
|
|
352
|
+
{/if}
|
|
353
|
+
|
|
354
|
+
{#if children}
|
|
355
|
+
<div class="cinder-run-step-timeline__body">
|
|
356
|
+
{@render children(step)}
|
|
357
|
+
</div>
|
|
358
|
+
{/if}
|
|
359
|
+
</div>
|
|
360
|
+
</div>
|
|
361
|
+
</li>
|
|
362
|
+
{/snippet}
|
|
363
|
+
|
|
364
|
+
{#snippet depthLimitItem(row: RenderedDepthLimitRow)}
|
|
365
|
+
<li
|
|
366
|
+
class="cinder-run-step-timeline__item"
|
|
367
|
+
data-cinder-status="depth-limit"
|
|
368
|
+
data-cinder-depth={row.depth}
|
|
369
|
+
data-cinder-path={row.pathKey}
|
|
370
|
+
data-cinder-connector-after={row.connectorAfter}
|
|
371
|
+
data-cinder-depth-limit
|
|
372
|
+
aria-current={row.ariaCurrent ? 'step' : undefined}
|
|
373
|
+
style:--_cinder-rst-depth={row.depth}
|
|
374
|
+
>
|
|
375
|
+
<div class="cinder-run-step-timeline__event">
|
|
376
|
+
<span class="cinder-run-step-timeline__marker" aria-hidden="true" inert>
|
|
377
|
+
<StatusDot status="neutral" label="Nested steps hidden" showLabel={false} size="md" />
|
|
378
|
+
</span>
|
|
379
|
+
|
|
380
|
+
<div class="cinder-run-step-timeline__content">
|
|
381
|
+
<div class="cinder-run-step-timeline__header">
|
|
382
|
+
<span class="cinder-run-step-timeline__label">
|
|
383
|
+
{hiddenNestedStepLabel(row.hiddenStepCount)}
|
|
384
|
+
</span>
|
|
385
|
+
<Badge
|
|
386
|
+
class="cinder-run-step-timeline__status"
|
|
387
|
+
variant="neutral"
|
|
388
|
+
size="xs"
|
|
389
|
+
aria-label="Status: Nested child steps hidden"
|
|
390
|
+
>
|
|
391
|
+
Depth cap
|
|
392
|
+
</Badge>
|
|
393
|
+
</div>
|
|
394
|
+
<p class="cinder-run-step-timeline__body">
|
|
395
|
+
Additional child-workflow steps are hidden because the timeline depth cap was reached.
|
|
396
|
+
</p>
|
|
397
|
+
</div>
|
|
398
|
+
</div>
|
|
399
|
+
</li>
|
|
400
|
+
{/snippet}
|
|
401
|
+
|
|
402
|
+
{#snippet stepRail(rows: RenderedStepLike[])}
|
|
403
|
+
{#each rows as row (row.pathKey)}
|
|
404
|
+
{#if row.kind === 'depth-limit'}
|
|
405
|
+
{@render depthLimitItem(row)}
|
|
406
|
+
{:else}
|
|
407
|
+
{@render stepItem(row)}
|
|
408
|
+
{/if}
|
|
409
|
+
{/each}
|
|
410
|
+
{/snippet}
|
|
411
|
+
|
|
221
412
|
<ol
|
|
222
413
|
{...rest}
|
|
223
414
|
class={classNames('cinder-run-step-timeline', className)}
|
|
224
415
|
aria-label={resolvedAriaLabel}
|
|
225
416
|
aria-labelledby={ariaLabelledby}
|
|
226
417
|
>
|
|
227
|
-
{#each
|
|
228
|
-
{#if
|
|
418
|
+
{#each renderedEntries as entry (entry.pathKey)}
|
|
419
|
+
{#if entry.kind === 'branch'}
|
|
420
|
+
{@const group = entry.group}
|
|
421
|
+
{@const summary = branchOutcomeSummary(group.lanes)}
|
|
422
|
+
{@const initialOpen =
|
|
423
|
+
!branchStartsCollapsed(group.lanes.length, group.collapseThreshold, group.collapsed) ||
|
|
424
|
+
(group.collapsed === undefined && branchGroupHasCurrentStep(group))}
|
|
229
425
|
<li
|
|
230
|
-
class="cinder-run-step-timeline__item"
|
|
231
|
-
data-cinder-status="
|
|
232
|
-
data-cinder-depth=
|
|
233
|
-
data-cinder-path={
|
|
234
|
-
data-cinder-connector-after={
|
|
235
|
-
data-cinder-depth-limit
|
|
236
|
-
aria-current={row.ariaCurrent ? 'step' : undefined}
|
|
237
|
-
style:--_cinder-rst-depth={row.depth}
|
|
426
|
+
class="cinder-run-step-timeline__item cinder-run-step-timeline__item--branch"
|
|
427
|
+
data-cinder-status="branch"
|
|
428
|
+
data-cinder-depth="0"
|
|
429
|
+
data-cinder-path={entry.pathKey}
|
|
430
|
+
data-cinder-connector-after={entry.connectorAfter}
|
|
238
431
|
>
|
|
239
432
|
<div class="cinder-run-step-timeline__event">
|
|
240
433
|
<span class="cinder-run-step-timeline__marker" aria-hidden="true" inert>
|
|
241
|
-
<StatusDot status="
|
|
434
|
+
<StatusDot status="accent" label="Branch group" showLabel={false} size="md" />
|
|
242
435
|
</span>
|
|
243
436
|
|
|
244
|
-
<div class="cinder-run-step-timeline__content">
|
|
245
|
-
<
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
<p class="cinder-run-step-timeline__body">
|
|
259
|
-
Additional child-workflow steps are hidden because the timeline depth cap was reached.
|
|
260
|
-
</p>
|
|
261
|
-
</div>
|
|
262
|
-
</div>
|
|
263
|
-
</li>
|
|
264
|
-
{:else}
|
|
265
|
-
{@const step = row.step}
|
|
266
|
-
{@const terminal = isTerminal(step.status)}
|
|
267
|
-
{@const metadata = metadataItems(step)}
|
|
268
|
-
<li
|
|
269
|
-
class="cinder-run-step-timeline__item"
|
|
270
|
-
data-cinder-status={step.status}
|
|
271
|
-
data-cinder-depth={row.depth}
|
|
272
|
-
data-cinder-path={row.pathKey}
|
|
273
|
-
data-cinder-terminal={terminal ? '' : undefined}
|
|
274
|
-
data-cinder-connector-after={row.connectorAfter}
|
|
275
|
-
aria-current={row.ariaCurrent ? 'step' : undefined}
|
|
276
|
-
style:--_cinder-rst-depth={row.depth}
|
|
277
|
-
>
|
|
278
|
-
<div class="cinder-run-step-timeline__event">
|
|
279
|
-
<!-- Marker: StatusDot on the rail -->
|
|
280
|
-
<span class="cinder-run-step-timeline__marker" aria-hidden="true" inert>
|
|
281
|
-
<StatusDot
|
|
282
|
-
status={statusDotStatus(step.status)}
|
|
283
|
-
label={statusLabel(step.status)}
|
|
284
|
-
showLabel={false}
|
|
285
|
-
size="md"
|
|
286
|
-
/>
|
|
287
|
-
</span>
|
|
437
|
+
<div class="cinder-run-step-timeline__content cinder-run-step-timeline__branch">
|
|
438
|
+
<RunStepBranchDisclosure
|
|
439
|
+
{initialOpen}
|
|
440
|
+
class="cinder-run-step-timeline__branch-disclosure"
|
|
441
|
+
triggerAriaLabel={`Branch group: ${group.label}. ${summary}.`}
|
|
442
|
+
>
|
|
443
|
+
{#snippet trigger()}
|
|
444
|
+
<span class="cinder-run-step-timeline__branch-heading">
|
|
445
|
+
<span class="cinder-run-step-timeline__label">{group.label}</span>
|
|
446
|
+
<Badge variant="accent" size="xs" aria-label={`Branch group outcome: ${summary}`}>
|
|
447
|
+
{summary}
|
|
448
|
+
</Badge>
|
|
449
|
+
</span>
|
|
450
|
+
{/snippet}
|
|
288
451
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
{@const safeLinkHref = safeStepLinkHref(step.link.href)}
|
|
296
|
-
{#if safeLinkHref}
|
|
297
|
-
<Link href={safeLinkHref} class="cinder-run-step-timeline__link">
|
|
298
|
-
{step.link.label}
|
|
299
|
-
</Link>
|
|
300
|
-
{:else}
|
|
301
|
-
<span
|
|
302
|
-
class="cinder-run-step-timeline__link cinder-run-step-timeline__link--unsafe"
|
|
452
|
+
<ul class="cinder-run-step-timeline__lanes" aria-label={`${group.label} branches`}>
|
|
453
|
+
{#each group.lanes as lane (lane.id)}
|
|
454
|
+
<li
|
|
455
|
+
class="cinder-run-step-timeline__lane"
|
|
456
|
+
data-cinder-outcome={lane.outcome ?? 'racing'}
|
|
457
|
+
aria-label={`Branch ${lane.label ?? lane.id}: ${laneStateLabel(lane)}`}
|
|
303
458
|
>
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
<Progress
|
|
330
|
-
value={step.progress ?? 0}
|
|
331
|
-
max={step.progressMax ?? 100}
|
|
332
|
-
size="sm"
|
|
333
|
-
ariaLabel={`${step.label} progress`}
|
|
334
|
-
/>
|
|
335
|
-
</div>
|
|
336
|
-
{/if}
|
|
337
|
-
|
|
338
|
-
<!-- Metadata: start/end/duration/attempts -->
|
|
339
|
-
{#if metadata.length > 0}
|
|
340
|
-
<dl class="cinder-run-step-timeline__meta">
|
|
341
|
-
{#each metadata as item (item.term)}
|
|
342
|
-
<div class="cinder-run-step-timeline__meta-row">
|
|
343
|
-
<dt class="cinder-run-step-timeline__meta-term">{item.term}</dt>
|
|
344
|
-
<dd class="cinder-run-step-timeline__meta-definition">{item.definition}</dd>
|
|
345
|
-
</div>
|
|
459
|
+
<div class="cinder-run-step-timeline__lane-header">
|
|
460
|
+
<span class="cinder-run-step-timeline__lane-label">
|
|
461
|
+
{lane.label ?? lane.id}
|
|
462
|
+
</span>
|
|
463
|
+
{#if lane.outcome !== undefined}
|
|
464
|
+
<Badge
|
|
465
|
+
variant={laneOutcomeBadgeVariant(lane.outcome)}
|
|
466
|
+
size="xs"
|
|
467
|
+
aria-label={`Outcome: ${laneOutcomeLabel(lane.outcome)}`}
|
|
468
|
+
>
|
|
469
|
+
{laneOutcomeLabel(lane.outcome)}
|
|
470
|
+
</Badge>
|
|
471
|
+
{:else}
|
|
472
|
+
<Badge variant="info" size="xs" aria-label="Outcome: still racing">
|
|
473
|
+
Racing
|
|
474
|
+
</Badge>
|
|
475
|
+
{/if}
|
|
476
|
+
</div>
|
|
477
|
+
<ol
|
|
478
|
+
class="cinder-run-step-timeline cinder-run-step-timeline__lane-steps"
|
|
479
|
+
aria-label={`${lane.label ?? lane.id} steps`}
|
|
480
|
+
>
|
|
481
|
+
{@render stepRail(laneRows(lane))}
|
|
482
|
+
</ol>
|
|
483
|
+
</li>
|
|
346
484
|
{/each}
|
|
347
|
-
</
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
<!-- Expandable details (logs, payloads, errors) -->
|
|
351
|
-
{#if step.details && step.details.length > 0}
|
|
352
|
-
<div class="cinder-run-step-timeline__details">
|
|
353
|
-
<!-- No idBase: let each Collapsible mint its own collision-free
|
|
354
|
-
id via $props.id(). Passing detail.id here would reuse a
|
|
355
|
-
consumer-supplied value that is only unique within a step, so
|
|
356
|
-
two steps with a detail id like "logs" would produce duplicate
|
|
357
|
-
DOM ids and cross-wired aria-controls. -->
|
|
358
|
-
{#each step.details as detail (detail.id)}
|
|
359
|
-
<Collapsible trigger={detail.label}>
|
|
360
|
-
<pre class="cinder-run-step-timeline__detail-content">{detail.content}</pre>
|
|
361
|
-
</Collapsible>
|
|
362
|
-
{/each}
|
|
363
|
-
</div>
|
|
364
|
-
{/if}
|
|
365
|
-
|
|
366
|
-
<!-- Optional per-step body slot -->
|
|
367
|
-
{#if children}
|
|
368
|
-
<div class="cinder-run-step-timeline__body">
|
|
369
|
-
{@render children(step)}
|
|
370
|
-
</div>
|
|
371
|
-
{/if}
|
|
485
|
+
</ul>
|
|
486
|
+
</RunStepBranchDisclosure>
|
|
372
487
|
</div>
|
|
373
488
|
</div>
|
|
374
489
|
</li>
|
|
490
|
+
{:else if entry.kind === 'depth-limit'}
|
|
491
|
+
{@render depthLimitItem(entry)}
|
|
492
|
+
{:else}
|
|
493
|
+
{@render stepItem(entry)}
|
|
375
494
|
{/if}
|
|
376
495
|
{/each}
|
|
377
496
|
</ol>
|