diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index f72653a1ee..6e6b6dfed0 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -240,8 +240,6 @@ These values are sent with the Planning Mode create-task request as `branchSelec When inline quick-create, Planning Mode, or Subtask Breakdown is opened from a workflow-filtered board/list lane, the create request also carries that active workflow selection. Quick-created tasks appear on the selected workflow lane immediately while board-workflows metadata refreshes, and planning saves, planning breakdown saves, and subtask-breakdown saves create their tasks directly on the selected workflow lane instead of briefly landing on the default board. -The **New Task** dialog's workflow selector also defaults to the current or last selected Board/List workflow lane for the current project. If no valid lane has been selected, or the remembered lane was deleted, the selector falls back to the project default workflow and task creation omits an explicit `workflowId`. - Completed single-task planning sessions remain in the Planning Mode history after you create the task, and selecting one restores the completed summary instead of restarting the composer. History rows are deduplicated by session id even if the initial load and live session updates arrive out of order, and deleting a history entry now waits for the server delete to persist (failures keep the row visible and surface an error instead of silently disappearing until refresh). ## New Task Modal Branch Strategy diff --git a/packages/dashboard/app/components/Board.tsx b/packages/dashboard/app/components/Board.tsx index a361d6c2ad..fa4d9745d0 100644 --- a/packages/dashboard/app/components/Board.tsx +++ b/packages/dashboard/app/components/Board.tsx @@ -16,7 +16,6 @@ import { getBoardCanDropTaskRejection } from "./boardCanDropTask"; import { WorkflowSwitcher } from "./WorkflowSwitcher"; import { computeWorkflowStatusCounts } from "./workflowStatusCounts"; import { readBoardWorkflowsCache, writeBoardWorkflowsCache } from "../utils/boardWorkflowsCache"; -import { writeLastSelectedWorkflowId } from "../utils/lastSelectedWorkflow"; interface BoardProps { tasks: Task[]; @@ -484,15 +483,6 @@ export function Board({ tasks, projectId, maxConcurrent, onMoveTask, onPauseTask } }, [selectedWorkflow, selectedWorkflowId, workflowMode]); - /** - * FNXC:WorkflowDefaults 2026-06-22-00:00: - * Persist explicit board-lane picks per project so the New Task dialog opens on the same current or last selected workflow lane without changing board filtering semantics. - */ - const handleSelectedWorkflowChange = useCallback((id: string) => { - setSelectedWorkflowId(id); - writeLastSelectedWorkflowId(projectId, id); - }, [projectId]); - const selectedWorkflowTasks = useMemo(() => { if (!workflowMode || !boardWorkflows || !selectedWorkflow) return []; return tasks.filter((task) => { @@ -622,7 +612,7 @@ export function Board({ tasks, projectId, maxConcurrent, onMoveTask, onPauseTask onChangeView("command-center"), + }, { id: "board", label: t("nav.board", "Board"), @@ -297,15 +310,6 @@ export function LeftSidebarNav({ onSelect: () => onChangeView("list"), }, ...(graphPluginEntry ? [mapPluginEntry(graphPluginEntry)] : []), - { - id: "command-center", - label: t("nav.commandCenter", "Command Center"), - view: "command-center", - isActive: view === "command-center", - icon: Gauge, - testId: "sidebar-nav-command-center", - onSelect: () => onChangeView("command-center"), - }, ...(showAgentsTab ? [ { diff --git a/packages/dashboard/app/components/ListView.tsx b/packages/dashboard/app/components/ListView.tsx index de02011146..5568c9c5aa 100644 --- a/packages/dashboard/app/components/ListView.tsx +++ b/packages/dashboard/app/components/ListView.tsx @@ -25,7 +25,6 @@ import { subscribeSse } from "../sse-bus"; import { WorkflowSwitcher } from "./WorkflowSwitcher"; import { computeWorkflowStatusCounts } from "./workflowStatusCounts"; import { readBoardWorkflowsCache, writeBoardWorkflowsCache } from "../utils/boardWorkflowsCache"; -import { writeLastSelectedWorkflowId } from "../utils/lastSelectedWorkflow"; const COLUMN_COLOR_MAP: Record = { triage: "var(--triage)", @@ -630,15 +629,6 @@ export function ListView({ } }, [selectedWorkflow, selectedWorkflowId, workflowMode]); - /** - * FNXC:WorkflowDefaults 2026-06-22-00:00: - * Persist explicit list-view workflow-lane picks per project so New Task inherits the user's current board context without changing list filtering or default resolution. - */ - const handleSelectedWorkflowChange = useCallback((id: string) => { - setSelectedWorkflowId(id); - writeLastSelectedWorkflowId(projectId, id); - }, [projectId]); - useEffect(() => { setSelectedColumn(null); }, [selectedWorkflowId]); @@ -1672,7 +1662,7 @@ export function ListView({ (undefined); - const initialWorkflowIdRef = useRef(undefined); // Optional workflow steps the user opted into; TaskForm fetches + seeds these // from the selected workflow's defaultOn and lifts the enabled set up here. const [enabledWorkflowSteps, setEnabledWorkflowSteps] = useState([]); @@ -99,23 +96,13 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask, /** * FNXC:SelectionComment 2026-06-16-23:58: * Selection comments open the normal New Task dialog with a prefilled description; seed only on the closed→open transition so rerenders do not overwrite user edits. - * - * FNXC:WorkflowDefaults 2026-06-22-00:00: - * Seed New Task's workflow selector from the project's last selected board lane only when that lane still exists in the board-workflows cache. Store the seed as the pristine baseline so opening on a remembered lane does not trigger discard-changes confirmation, and reset returns to that same baseline. */ useEffect(() => { if (isOpen && !wasOpenRef.current) { setDescription(initialDescription); - const persistedWorkflowId = readLastSelectedWorkflowId(projectId); - const cachedWorkflows = readBoardWorkflowsCache(projectId); - const initialWorkflowId = persistedWorkflowId && cachedWorkflows?.workflows.some((workflow) => workflow.id === persistedWorkflowId) - ? persistedWorkflowId - : undefined; - initialWorkflowIdRef.current = initialWorkflowId; - setSelectedWorkflowId(initialWorkflowId); } wasOpenRef.current = isOpen; - }, [initialDescription, isOpen, projectId]); + }, [initialDescription, isOpen]); // Load agents for agent picker const loadAgents = useCallback(() => { @@ -184,7 +171,7 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask, description.trim() !== "" || dependencies.length > 0 || pendingImages.length > 0 || - selectedWorkflowId !== initialWorkflowIdRef.current || + selectedWorkflowId !== undefined || // Optional workflow steps the user toggled count as unsaved work. (Workflows // whose steps are defaultOn:false — today's only shipped step — seed an empty // set, so this stays false until the user actually opts a step in.) @@ -220,7 +207,7 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask, setThinkingLevel(""); setSelectedPresetId(""); setPresetMode("default"); - setSelectedWorkflowId(initialWorkflowIdRef.current); + setSelectedWorkflowId(undefined); setEnabledWorkflowSteps([]); setSelectedAgentId(null); setShowAgentPicker(false); @@ -348,7 +335,7 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask, setThinkingLevel(""); setSelectedPresetId(""); setPresetMode("default"); - setSelectedWorkflowId(initialWorkflowIdRef.current); + setSelectedWorkflowId(undefined); setEnabledWorkflowSteps([]); setSelectedAgentId(null); setShowAgentPicker(false); diff --git a/packages/dashboard/app/components/WorkflowSwitcher.tsx b/packages/dashboard/app/components/WorkflowSwitcher.tsx index 17c54e31c9..7d6309b254 100644 --- a/packages/dashboard/app/components/WorkflowSwitcher.tsx +++ b/packages/dashboard/app/components/WorkflowSwitcher.tsx @@ -387,7 +387,7 @@ export function WorkflowSwitcher({ workflows, value, onChange, counts, onOpen, l {isOpen ? renderCountBadges(selectedCounts, "trigger") : null} {isOpen ? renderAccessibleCounts(selectedCounts) : null} -