Show the streaming dash on dashboard edges and without motion

This commit is contained in:
2026-08-20 13:28:40 +02:00
parent f719816992
commit 32cc23fa6b
3 changed files with 15 additions and 5 deletions
-2
View File
@@ -32,8 +32,6 @@ should reopen it.
- FEAT/UI/MOBILE: a rank of many nodes — a connector feeding eight dashboard tiles — is thousands of pixels wide however the graph is turned, so on a phone the fit shrinks it past reading. The layout is right and the flow is simply too big for the screen; a "one rank at a time" reading mode, or wrapping a wide rank, is what would make it legible. - FEAT/UI/MOBILE: a rank of many nodes — a connector feeding eight dashboard tiles — is thousands of pixels wide however the graph is turned, so on a phone the fit shrinks it past reading. The layout is right and the flow is simply too big for the screen; a "one rank at a time" reading mode, or wrapping a wide rank, is what would make it legible.
- CHORE/UI: an edge's value chip sits at the bezier midpoint while the layout reserves its room at dagre's label rank. The two agree closely enough today; if chips ever pile up, take the position from the layout instead. - CHORE/UI: an edge's value chip sits at the bezier midpoint while the layout reserves its room at dagre's label rank. The two agree closely enough today; if chips ever pile up, take the position from the layout instead.
- CHORE/UI: the bar widget's nested fill is `--chart-5` against a `--primary` outer fill, which measures 2.53:1 in light mode — under the 3:1 guideline for non-text. The `inset-y-1` gutter supplies the edge, and every other slot of the ramp collapses in dark mode instead. - CHORE/UI: the bar widget's nested fill is `--chart-5` against a `--primary` outer fill, which measures 2.53:1 in light mode — under the 3:1 guideline for non-text. The `inset-y-1` gutter supplies the edge, and every other slot of the ramp collapses in dark mode instead.
- CHORE/UI: a streaming edge's dashes sit inside the `prefers-reduced-motion: no-preference` guard, so a reduced-motion user gets no streaming indicator at all. Lifting `stroke-dasharray` alone out of the guard keeps the static signal without the motion.
- CHORE/UI: only node-to-node edges carry the streaming dash. `endpoints.ts` builds a dashboard endpoint's edges without the producing port's `stream` flag, so a training loss feeding a chart — the case the march was drawn for — is still a plain line.
- CHORE/UI: the Home flow-activity table's name cell is `max-w-0` with nothing setting a floor, so `demo_training` reads as "demo⋯" at 1440px while the row has slack to spare. The cap is what keeps the table from widening the page; it wants a minimum beside it. - CHORE/UI: the Home flow-activity table's name cell is `max-w-0` with nothing setting a floor, so `demo_training` reads as "demo⋯" at 1440px while the row has slack to spare. The cap is what keeps the table from widening the page; it wants a minimum beside it.
- FEAT/UI (deferred until MCP lands): add a "bot" icon button to the home view (graph panel) which opens a chat window (reuse general concept of a side panel like in flows/nodes to make it a chat panel which can open on any screen (stacks below any other existing panel -> introduce stacking) to give support on errors/write code, generate dashboards etc) to explain the error(s) - FEAT/UI (deferred until MCP lands): add a "bot" icon button to the home view (graph panel) which opens a chat window (reuse general concept of a side panel like in flows/nodes to make it a chat panel which can open on any screen (stacks below any other existing panel -> introduce stacking) to give support on errors/write code, generate dashboards etc) to explain the error(s)
- FEAT/UI make the header (Fluksio - YEAR) and the logo in the sidebar link to the main page (fluksio.com) - FEAT/UI make the header (Fluksio - YEAR) and the logo in the sidebar link to the main page (fluksio.com)
+6 -2
View File
@@ -51,7 +51,10 @@ export function deriveEndpoints(
// Which node consumes or produces each message, so a label can sit beside it. // Which node consumes or produces each message, so a label can sit beside it.
const consumers = new Map<string, { node: string; port: string }[]>() const consumers = new Map<string, { node: string; port: string }[]>()
const producers = new Map<string, { node: string; port: string }[]>() const producers = new Map<
string,
{ node: string; port: string; stream?: boolean }[]
>()
for (const node of definitions) { for (const node of definitions) {
for (const spec of node.requires ?? []) { for (const spec of node.requires ?? []) {
const message = qualify(flow, spec.name ?? "") const message = qualify(flow, spec.name ?? "")
@@ -66,7 +69,7 @@ export function deriveEndpoints(
if (!message) continue if (!message) continue
producers.set(message, [ producers.set(message, [
...(producers.get(message) ?? []), ...(producers.get(message) ?? []),
{ node: node.id, port: portOf(spec) }, { node: node.id, port: portOf(spec), stream: spec.stream },
]) ])
} }
} }
@@ -127,6 +130,7 @@ export function deriveEndpoints(
message, message,
flow, flow,
producerId: `${flow}.${producer.node}`, producerId: `${flow}.${producer.node}`,
stream: producer.stream,
} satisfies FlowEdgeData, } satisfies FlowEdgeData,
}) })
} }
+9 -1
View File
@@ -49,6 +49,15 @@
--edge-rest: var(--primary); --edge-rest: var(--primary);
} }
/*
* The dashes are the signal, the march below is only its motion: the pattern
* is declared outside the guard so a reduced-motion reader still sees which
* edges stream.
*/
.react-flow__edge-path.edge-stream {
stroke-dasharray: 6 4;
}
/* A message arriving lights its edge, then decays back to rest. */ /* A message arriving lights its edge, then decays back to rest. */
@media (prefers-reduced-motion: no-preference) { @media (prefers-reduced-motion: no-preference) {
.react-flow__edge-path.edge-live { .react-flow__edge-path.edge-live {
@@ -80,7 +89,6 @@
* the literal is one dash period per step, slow enough to read as direction. * the literal is one dash period per step, slow enough to read as direction.
*/ */
.react-flow__edge-path.edge-stream { .react-flow__edge-path.edge-stream {
stroke-dasharray: 6 4;
animation: edge-march 700ms linear infinite; animation: edge-march 700ms linear infinite;
} }