Move panel explanations into tooltips

The node, flow, widget and dashboard panels explained themselves in
paragraphs under every control. They now carry a caption and an info
tooltip, so a panel reads as a list of settings.

InfoTip, PanelSection and FieldLabel live beside PANEL_SECTION in
SidePanel.tsx, which the panels already share. InfoTip holds its own open
state because a Radix tooltip ignores a touch pointer, and below md the
whole panel is a full-screen sheet — hover-only help would leave a phone
with the caption and nothing else.

Dashboard/panels.tsx drops from 30 helper paragraphs to 5; the ones left
are empty states and status, not explanation. Em-dashes are out of the
user-facing strings, except where one separates the halves of a select
item.
This commit is contained in:
2026-08-31 10:24:26 +02:00
parent 6c8a101d24
commit 4e98bf30bf
6 changed files with 303 additions and 224 deletions
+28 -18
View File
@@ -12,7 +12,7 @@ import {
} from "@/components/ui/dialog"
import { Switch } from "@/components/ui/switch"
import { BoundarySections } from "./FlowBoundary"
import { PANEL_SECTION, PanelTitle, SidePanel } from "./SidePanel"
import { PanelSection, PanelTitle, SidePanel } from "./SidePanel"
/**
* The flow's own settings, in the same panel its nodes use — down to where the
@@ -72,13 +72,14 @@ export function FlowPanel({
}
>
<div className="grid gap-6 p-4">
<div className="grid gap-3">
<span className={PANEL_SECTION}>Running</span>
<PanelSection
title="Running"
className="gap-3"
help="While this is on, the engine keeps the flow's subscriptions, schedules and webhooks live. Off, none of it is subscribed, scheduled or reachable."
>
<div className="flex items-center justify-between gap-3">
<p className="text-sm text-muted-foreground">
{enabled
? "The engine runs this flow: subscriptions, schedules and webhooks are live."
: "Stopped. Nothing of this flow is subscribed, scheduled or reachable."}
{enabled ? "Live" : "Stopped"}
</p>
<Switch
checked={enabled}
@@ -88,7 +89,7 @@ export function FlowPanel({
data-testid="flow-enabled"
/>
</div>
</div>
</PanelSection>
<BoundarySections
flow={definition.name}
@@ -97,25 +98,34 @@ export function FlowPanel({
onChange={onChange}
/>
<div className="grid gap-3">
<span className={PANEL_SECTION}>Contents</span>
<PanelSection
title="Contents"
className="gap-3"
help={
<>
Every message in this flow is named under{" "}
<span className="font-mono">{definition.name}</span>, so two
flows can use the same short name without colliding.
</>
}
>
<p className="text-sm text-muted-foreground">
<span className="font-mono">{definition.name}</span> namespaces
every message in here.{" "}
{nodeCount === 0
? "No nodes yet."
: `${nodeCount} node${nodeCount === 1 ? "" : "s"}.`}
: `${nodeCount} node${nodeCount === 1 ? "" : "s"}`}
</p>
</div>
</PanelSection>
{hasDraft ? (
<div className="grid gap-3">
<span className={PANEL_SECTION}>Unpublished changes</span>
<PanelSection
title="Unpublished changes"
className="gap-3"
help="Edits are kept as a draft until you publish them. The bar below publishes this one, or discards it."
>
<p className="text-sm text-muted-foreground">
The engine is still running the last published version of this
flow. The bar below publishes it, or throws the edit away.
The engine is still running the last published version.
</p>
</div>
</PanelSection>
) : null}
</div>
</SidePanel>