feat(central-ui): FlowGraphView External lane, outbound status pills, async/spawn connectors
Four lanes (LaneCount 4; External sublabel = distinct targets, three then +n); ApiCall/DbCall/Notify nodes carry a status pill (Ok/Pending/Parked/Failed — pending pulses, reduced-motion aware) plus a sync/cached/notify mode; folded lifecycles show '+4.1 s' submit→terminal wall time. Async edges are dashed and routed through the inter-lane strip with a gutter tag; spawn edges use a bolt marker. Predicted async edges (Task 6's PredictedEdge.Async) render the same way. de-DE height pinned at 319.2 = (4×110+16)×0.7. Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
.fg-node.failed .fg-node-box,
|
||||
.fg-node.timed-out .fg-node-box { stroke: var(--bs-danger, #c0392b); }
|
||||
.fg-node.not-traced .fg-node-box { stroke-dasharray: 1 3; }
|
||||
.fg-node.parked .fg-node-box { stroke: var(--warn, var(--bs-warning, #e8920c)); }
|
||||
|
||||
/* Node body: HTML inside a foreignObject so text is measured by the browser. */
|
||||
.fg-body {
|
||||
@@ -77,6 +78,40 @@
|
||||
.fg-node.failed .fg-eyebrow,
|
||||
.fg-node.timed-out .fg-eyebrow { color: var(--bs-danger, #c0392b); }
|
||||
|
||||
/* Outbound nodes (API call / database / notify): the folded outcome as a status pill, then the
|
||||
call mode. Kit status tokens first (dark mode follows via site.css), Bootstrap's as fallback. */
|
||||
.fg-status { margin-top: auto; display: flex; align-items: center; gap: 4px; min-width: 0; }
|
||||
.fg-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
flex-shrink: 0;
|
||||
font-size: 0.6rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.3;
|
||||
padding: 0 6px;
|
||||
border-radius: 999px;
|
||||
white-space: nowrap;
|
||||
color: var(--ink-soft);
|
||||
background: var(--rule);
|
||||
}
|
||||
.fg-pill::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
|
||||
.fg-pill.ok { color: var(--ok, var(--bs-success, #2f9e44)); background: var(--ok-bg, rgba(var(--bs-success-rgb, 25, 135, 84), 0.12)); }
|
||||
.fg-pill.pending { color: var(--warn, var(--bs-warning, #e8920c)); background: var(--warn-bg, rgba(var(--bs-warning-rgb, 255, 193, 7), 0.15)); }
|
||||
.fg-pill.parked { color: var(--warn, var(--bs-warning, #e8920c)); background: var(--warn-bg, rgba(var(--bs-warning-rgb, 255, 193, 7), 0.15)); }
|
||||
.fg-pill.failed { color: var(--bad, var(--bs-danger, #e03131)); background: var(--bad-bg, rgba(var(--bs-danger-rgb, 220, 53, 69), 0.12)); }
|
||||
.fg-mode { color: var(--ink-soft); font-size: 0.66rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
|
||||
/* A pending pill pulses while the page keeps refreshing outcomes after a Live run. */
|
||||
.fg-node.pending .fg-pill { animation: fg-pulse 1.6s ease-in-out infinite; }
|
||||
@keyframes fg-pulse {
|
||||
0%, 100% { opacity: 1; box-shadow: 0 0 0 0 var(--warn-bg, rgba(var(--bs-warning-rgb, 255, 193, 7), 0.15)); }
|
||||
50% { opacity: 0.6; box-shadow: 0 0 0 4px var(--warn-bg, rgba(var(--bs-warning-rgb, 255, 193, 7), 0.15)); }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.fg-node.pending .fg-pill { animation: none; }
|
||||
}
|
||||
|
||||
/* Connectors */
|
||||
.fg-edge {
|
||||
fill: none;
|
||||
@@ -85,6 +120,12 @@
|
||||
}
|
||||
.fg-edge.boundary { stroke: var(--accent); }
|
||||
.fg-edge.external { stroke-dasharray: 5 4; }
|
||||
/* Async branch (cached call / notification): same dash as the echo edge, its own class — the run
|
||||
carried on without waiting. Spawn: solid line ending in the bolt marker (a trigger cascade). */
|
||||
.fg-edge.async { stroke-dasharray: 5 4; }
|
||||
.fg-edge.spawn { stroke: var(--ink-soft); }
|
||||
.fg-edge.predicted { stroke-opacity: 0.5; stroke-dasharray: 3 3; }
|
||||
.fg-arrowhead { fill: var(--ink-faint); }
|
||||
.fg-arrowhead.accent { fill: var(--accent); }
|
||||
.fg-arrowhead.spawn { fill: var(--ink-soft); }
|
||||
.fg-wrap ::deep .fg-edge-tag { fill: var(--ink-faint); font-size: 0.6rem; font-family: var(--mono); }
|
||||
|
||||
Reference in New Issue
Block a user