From e685dc54e1681a2b66303a7f6ab6c1ef105ac591 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Wed, 3 Jun 2026 14:00:59 -0700 Subject: [PATCH] feat(dashboard): select a custom workflow when creating a task New-task modal and the quick-add card (expanded) now expose a workflow picker; the chosen workflow is applied to the new task via selectTaskWorkflow right after creation, non-blocking on failure. --- .../app/components/InlineCreateCard.tsx | 28 ++++++++++++++++++- .../dashboard/app/components/NewTaskModal.tsx | 27 ++++++++++++++++-- .../__tests__/NewTaskModal.test.tsx | 7 +++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/packages/dashboard/app/components/InlineCreateCard.tsx b/packages/dashboard/app/components/InlineCreateCard.tsx index 2190faf3ee..60a7914f64 100644 --- a/packages/dashboard/app/components/InlineCreateCard.tsx +++ b/packages/dashboard/app/components/InlineCreateCard.tsx @@ -5,7 +5,7 @@ import { Brain, Link, Lightbulb, ListTree, Zap, ChevronDown, ChevronUp, Bot, Max import { DEFAULT_TASK_PRIORITY, TASK_PRIORITIES, type Task, type TaskPriority, type Settings } from "@fusion/core"; import { getErrorMessage } from "@fusion/core"; import type { ToastType } from "../hooks/useToast"; -import { checkDuplicateTasks, fetchModels, uploadAttachment, fetchSettings, updateGlobalSettings, fetchAgents, DuplicateCandidatesError } from "../api"; +import { checkDuplicateTasks, fetchModels, uploadAttachment, fetchSettings, updateGlobalSettings, fetchAgents, selectTaskWorkflow, DuplicateCandidatesError } from "../api"; import type { CreateTaskInput, ModelInfo, Agent, NodeInfo, DuplicateMatch } from "../api"; import { useNodes } from "../hooks/useNodes"; import { ModelSelectionModal } from "./ModelSelectionModal"; @@ -13,6 +13,7 @@ import { NodeHealthDot } from "./NodeHealthDot"; import { DuplicateWarningModal } from "./DuplicateWarningModal"; import { applyPresetToSelection } from "../utils/modelPresets"; import { getScopedItem, removeScopedItem, setScopedItem } from "../utils/projectStorage"; +import { WorkflowSelector } from "./WorkflowSelector"; const ALLOWED_IMAGE_TYPES = ["image/png", "image/jpeg", "image/gif", "image/webp"]; const STORAGE_KEY = "kb-inline-create-text"; @@ -114,6 +115,7 @@ export function InlineCreateCard({ const [favoriteModels, setFavoriteModels] = useState([]); const [submitting, setSubmitting] = useState(false); const [pendingImages, setPendingImages] = useState([]); + const [selectedWorkflowId, setSelectedWorkflowId] = useState(null); const [isExpanded, setIsExpanded] = useState(false); // isDescriptionExpanded controls fullscreen description editing mode const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false); @@ -338,6 +340,19 @@ export function InlineCreateCard({ try { const task = await onSubmit(input); + // Apply custom workflow if selected (non-blocking — task already exists) + if (selectedWorkflowId) { + try { + await selectTaskWorkflow(task.id, selectedWorkflowId, projectId); + } catch (err) { + if (addToast) { + addToast(getErrorMessage(err) || "Failed to apply workflow", "error"); + } else { + console.warn("Failed to apply workflow:", getErrorMessage(err)); + } + } + } + // Upload pending images as attachments if (pendingImages.length > 0) { const failures: string[] = []; @@ -376,6 +391,7 @@ export function InlineCreateCard({ setShowAgentPicker(false); setIsModelModalOpen(false); setShowPresets(false); + setSelectedWorkflowId(null); addToast(`Created ${task.id}`, "success"); // Collapse and clear localStorage after successful task creation @@ -400,6 +416,7 @@ export function InlineCreateCard({ onSubmit, addToast, projectId, + selectedWorkflowId, ]); const handleSubmit = useCallback(async () => { @@ -1008,6 +1025,15 @@ export function InlineCreateCard({ {browserVerification ? "Browser Verify ✓" : "Browser Verify"} + setSelectedWorkflowId(id)} + projectId={projectId} + addToast={addToast} + label="Workflow" + disabled={submitting} + /> +