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:
@@ -49,7 +49,7 @@ import {
|
||||
secretsQueryOptions,
|
||||
useParamSuggestions,
|
||||
} from "./queries"
|
||||
import { PANEL_SECTION, PanelTitle, SidePanel } from "./SidePanel"
|
||||
import { InfoTip, PANEL_SECTION, PanelTitle, SidePanel } from "./SidePanel"
|
||||
|
||||
const NodeEditor = lazy(() => import("./NodeEditor"))
|
||||
|
||||
@@ -368,8 +368,8 @@ function PortList({
|
||||
aria-label="Streaming output"
|
||||
aria-pressed={spec.stream ?? false}
|
||||
title={
|
||||
"Published repeatedly while the node runs — a curve rather " +
|
||||
"than a result. A run keeps every value it takes."
|
||||
"Published repeatedly while the node runs: a curve rather than " +
|
||||
"a result. A run keeps every value it takes."
|
||||
}
|
||||
className={cn(
|
||||
"shrink-0",
|
||||
@@ -613,15 +613,15 @@ function CronHelp({
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Five fields —{" "}
|
||||
<InfoTip label="Cron">
|
||||
Five fields:{" "}
|
||||
<span className="font-mono">
|
||||
minute hour day-of-month month weekday
|
||||
</span>
|
||||
. <span className="font-mono">*</span> is every,{" "}
|
||||
<span className="font-mono">*/5</span> every fifth,{" "}
|
||||
<span className="font-mono">1-5</span> a range.
|
||||
</p>
|
||||
</InfoTip>
|
||||
{derivable && derived && params.cron !== derived ? (
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -886,9 +886,17 @@ function ResourcesSection({
|
||||
|
||||
return (
|
||||
<div className="grid gap-1.5">
|
||||
<Label htmlFor="node-resources" className={SECTION}>
|
||||
Resources
|
||||
</Label>
|
||||
<div className="flex items-center gap-1">
|
||||
<Label htmlFor="node-resources" className={SECTION}>
|
||||
Resources
|
||||
</Label>
|
||||
<InfoTip label="Resources">
|
||||
What is held for the whole execution, and what the node's own
|
||||
libraries are told they may use. The duration is a planning figure,
|
||||
not a limit. Held nothing, the node shares the pool with every other
|
||||
node that asks for nothing.
|
||||
</InfoTip>
|
||||
</div>
|
||||
<Select value={choice} onValueChange={pick}>
|
||||
<SelectTrigger id="node-resources" className="h-8 text-sm">
|
||||
<SelectValue />
|
||||
@@ -946,7 +954,7 @@ function ResourcesSection({
|
||||
{resources ? (
|
||||
<Input
|
||||
className="h-8 text-sm"
|
||||
placeholder="expected duration — 30m, 2h"
|
||||
placeholder="expected duration, e.g. 30m or 2h"
|
||||
defaultValue={formatDuration(resources.duration_s)}
|
||||
key={`${choice}-${resources.duration_s ?? ""}`}
|
||||
onBlur={(event) => {
|
||||
@@ -962,12 +970,6 @@ function ResourcesSection({
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{resources
|
||||
? "Held for the whole execution, and what the node's own libraries are told they may use. The duration is a planning fact, not a limit."
|
||||
: "Nothing held: the node shares the pool with every other node that says nothing."}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1047,10 +1049,13 @@ function SharingSection({
|
||||
|
||||
return (
|
||||
<div className="grid gap-3">
|
||||
<span className={SECTION}>Reuse</span>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Move this node's code to the library so other flows can run it too.
|
||||
</p>
|
||||
<div className="flex items-center gap-1">
|
||||
<span className={SECTION}>Reuse</span>
|
||||
<InfoTip label="Reuse">
|
||||
Moves this node's code to the library so other flows can run it too.
|
||||
Editing a shared node changes it everywhere at once.
|
||||
</InfoTip>
|
||||
</div>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Input
|
||||
value={name}
|
||||
@@ -1325,9 +1330,16 @@ function PanelBody({
|
||||
) : null}
|
||||
{hasSource ? (
|
||||
<div className="grid gap-1.5">
|
||||
<Label htmlFor="node-timeout" className={SECTION}>
|
||||
Timeout
|
||||
</Label>
|
||||
<div className="flex items-center gap-1">
|
||||
<Label htmlFor="node-timeout" className={SECTION}>
|
||||
Timeout
|
||||
</Label>
|
||||
<InfoTip label="Timeout">
|
||||
Seconds this code may stay silent before it is stopped. A yield
|
||||
or an emit resets the clock. 0 disables the limit; empty uses
|
||||
the engine default.
|
||||
</InfoTip>
|
||||
</div>
|
||||
<Input
|
||||
id="node-timeout"
|
||||
type="number"
|
||||
@@ -1346,11 +1358,6 @@ function PanelBody({
|
||||
})
|
||||
}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Seconds this code may be silent before it is stopped — a yield or
|
||||
an emit resets the clock. 0 disables the limit; empty uses the
|
||||
engine default.
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
{hasSource ? (
|
||||
@@ -1394,8 +1401,8 @@ function PanelBody({
|
||||
data-testid="node-source-generated"
|
||||
>
|
||||
Generated by <span className="font-mono">fluksio sync</span> from{" "}
|
||||
<span className="font-mono">{origin.repo || "a repository"}</span>{" "}
|
||||
— edit it there and sync again.
|
||||
<span className="font-mono">{origin.repo || "a repository"}</span>
|
||||
. Edit it there and sync again.
|
||||
</p>
|
||||
) : null}
|
||||
<div className="min-h-0 flex-1 overflow-hidden rounded-md border border-border">
|
||||
|
||||
Reference in New Issue
Block a user