From 1436389790ca7e2c79d739cf6707cf8b80cde8cc Mon Sep 17 00:00:00 2001 From: ciregenz Date: Thu, 21 May 2026 22:39:22 -0700 Subject: [PATCH] =?UTF-8?q?[eric]=20workflows:=20PreviewView=20=E2=80=94?= =?UTF-8?q?=20step=20list=20+=20Schedule=20prompt=20card=20(Image=20#7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/Workflows/WorkflowCardSubviews.tsx | 110 ++++++++++++------ 1 file changed, 72 insertions(+), 38 deletions(-) diff --git a/frontend/src/app/pages/Workflows/WorkflowCardSubviews.tsx b/frontend/src/app/pages/Workflows/WorkflowCardSubviews.tsx index 7eba9da7..f115a125 100644 --- a/frontend/src/app/pages/Workflows/WorkflowCardSubviews.tsx +++ b/frontend/src/app/pages/Workflows/WorkflowCardSubviews.tsx @@ -119,24 +119,6 @@ export function PreviewView({ workflowId, steps, sourceSessionId, initialDraft, const [editedSteps, setEditedSteps] = useState(null); const liveSteps = editedSteps || steps; - const onSave = useCallback(async () => { - if (busy) return; - setBusy(true); - try { - const result = await dispatch(createWorkflow({ - title, - description, - steps: liveSteps.map((s) => ({ id: s.id, text: s.text })), - source_session_id: sourceSessionId, - use_synced_prompt: true, - } as Partial)); - const wf = (result as unknown as { payload: Workflow }).payload; - if (wf?.id) onSaved(wf); - } finally { - setBusy(false); - } - }, [busy, dispatch, title, description, liveSteps, sourceSessionId, onSaved]); - const onDiscard = useCallback(() => { dispatch(closeWorkflowCard(workflowId)); dispatch(removeWorkflowCard(workflowId)); @@ -153,31 +135,83 @@ export function PreviewView({ workflowId, steps, sourceSessionId, initialDraft, setEditedSteps(next); }, [liveSteps]); + // The Save flow auto-creates the workflow, then prompts the user to schedule it + // (Image #7). Ignore = save without schedule. Schedule = open the scheduling + // composer (slice 3 wires this to the natural-language input). + const onSaveThenSchedule = useCallback(async () => { + if (busy) return; + setBusy(true); + try { + const result = await dispatch(createWorkflow({ + title, + description, + steps: liveSteps.map((s) => ({ id: s.id, text: s.text })), + source_session_id: sourceSessionId, + use_synced_prompt: true, + } as Partial)); + const wf = (result as unknown as { payload: Workflow }).payload; + if (wf?.id) { + onSaved(wf); + dispatch(updateWorkflowCard({ workflowId: wf.id, patch: { view: 'edit', editFacet: 'Schedule' } })); + } + } finally { + setBusy(false); + } + }, [busy, dispatch, title, description, liveSteps, sourceSessionId, onSaved]); + + void onChangeDescription; return ( - // PreviewView visually matches SavedView (target image #107): same - // Scheduled / Permissions prose, same framed step boxes. Title + - // description come from the AI gen at save time; the user doesn't - // type a description here. Discard/Save sits in the bottom-right. - - - Scheduled: - Not scheduled + + + {/* Schedule prompt card. Soft accent tint + calendar icon, matching Image #7. */} + + + - - Permissions: - Notify me in Open Swarm + + + Schedule this workflow? + + + You can have workflows run on a recurring basis, automatically. + - {description && ( - - {description} - - )} - - - - + + + Ignore + + + Schedule Workflow + );