Let a paused flow be stepped from the dock
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H7LwYgJfpkbLCTeiAf8U4A
This commit is contained in:
@@ -9,13 +9,7 @@ import { cn } from "@/lib/utils"
|
|||||||
import "./dashboard.css"
|
import "./dashboard.css"
|
||||||
import { WidgetBody, WidgetFrame, widgetIssue } from "./widgets"
|
import { WidgetBody, WidgetFrame, widgetIssue } from "./widgets"
|
||||||
|
|
||||||
/**
|
export type Dashboard = DashboardDef_Output
|
||||||
* A dashboard, plus the settings the generated client does not carry yet.
|
|
||||||
*
|
|
||||||
* `columns` is stored by the backend but the SDK is regenerated on its own
|
|
||||||
* schedule, so it is widened here rather than waited for.
|
|
||||||
*/
|
|
||||||
export type Dashboard = DashboardDef_Output & { columns?: number }
|
|
||||||
|
|
||||||
/** How many columns a wall panel is cut into, if the document does not say. */
|
/** How many columns a wall panel is cut into, if the document does not say. */
|
||||||
export const DEFAULT_COLUMNS = 12
|
export const DEFAULT_COLUMNS = 12
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
Play,
|
Play,
|
||||||
PlayCircle,
|
PlayCircle,
|
||||||
Plus,
|
Plus,
|
||||||
|
StepForward,
|
||||||
WifiOff,
|
WifiOff,
|
||||||
ZoomIn,
|
ZoomIn,
|
||||||
ZoomOut,
|
ZoomOut,
|
||||||
@@ -62,6 +63,8 @@ export function FlowDock({
|
|||||||
onAddNode,
|
onAddNode,
|
||||||
onRun,
|
onRun,
|
||||||
onTogglePause,
|
onTogglePause,
|
||||||
|
onStep,
|
||||||
|
stepping,
|
||||||
onFocusNode,
|
onFocusNode,
|
||||||
onEditFlow,
|
onEditFlow,
|
||||||
onPublish,
|
onPublish,
|
||||||
@@ -79,6 +82,8 @@ export function FlowDock({
|
|||||||
onAddNode: () => void
|
onAddNode: () => void
|
||||||
onRun: () => void
|
onRun: () => void
|
||||||
onTogglePause: () => void
|
onTogglePause: () => void
|
||||||
|
onStep: () => void
|
||||||
|
stepping: boolean
|
||||||
onFocusNode: (nodeId: string) => void
|
onFocusNode: (nodeId: string) => void
|
||||||
onEditFlow: () => void
|
onEditFlow: () => void
|
||||||
onPublish: () => void
|
onPublish: () => void
|
||||||
@@ -214,6 +219,25 @@ export function FlowDock({
|
|||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
|
{paused && enabled ? (
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
className="size-11 text-muted-foreground md:size-8"
|
||||||
|
onClick={onStep}
|
||||||
|
disabled={stepping}
|
||||||
|
aria-label="Step the flow"
|
||||||
|
data-testid="step-flow"
|
||||||
|
>
|
||||||
|
<StepForward />
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>Let one held-back item through</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ function FlowEditorInner({
|
|||||||
}) {
|
}) {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const { showErrorToast } = useCustomToast()
|
const { showErrorToast, showSuccessToast } = useCustomToast()
|
||||||
const { screenToFlowPosition, fitView } = useReactFlow()
|
const { screenToFlowPosition, fitView } = useReactFlow()
|
||||||
const updateNodeInternals = useUpdateNodeInternals()
|
const updateNodeInternals = useUpdateNodeInternals()
|
||||||
|
|
||||||
@@ -507,6 +507,13 @@ function FlowEditorInner({
|
|||||||
onError: () => showErrorToast("The flow could not be paused."),
|
onError: () => showErrorToast("The flow could not be paused."),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const stepMutation = useMutation({
|
||||||
|
mutationFn: () => FlowsService.stepFlow({ name: flowName }),
|
||||||
|
// Says which node ran, or that nothing was held back — both are answers.
|
||||||
|
onSuccess: (result) => showSuccessToast(result.message),
|
||||||
|
onError: () => showErrorToast("The flow could not be stepped."),
|
||||||
|
})
|
||||||
|
|
||||||
const deleteMutation = useMutation({
|
const deleteMutation = useMutation({
|
||||||
mutationFn: () => FlowsService.deleteFlow({ name: flowName }),
|
mutationFn: () => FlowsService.deleteFlow({ name: flowName }),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
@@ -970,6 +977,8 @@ function FlowEditorInner({
|
|||||||
runMutation.mutate()
|
runMutation.mutate()
|
||||||
}}
|
}}
|
||||||
onTogglePause={() => pauseMutation.mutate(!paused)}
|
onTogglePause={() => pauseMutation.mutate(!paused)}
|
||||||
|
onStep={() => stepMutation.mutate()}
|
||||||
|
stepping={stepMutation.isPending}
|
||||||
onFocusNode={focusNode}
|
onFocusNode={focusNode}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user