FN-5717: add per-task auto-merge override in new task form
Add a New Task form option to override auto-merge behavior per task and wire it through task creation APIs. - add TaskForm UI state/prop support for enabling or disabling per-task auto-merge override - pass override values through NewTaskModal and legacy task creation API payloads - persist and validate settings.autoMerge overrides in task workflow route handling - add dashboard and route tests covering override defaults and explicit true/false behavior - document per-task auto-merge override behavior in dashboard and settings docs Files changed: docs/dashboard-guide.md | 1 + docs/settings-reference.md | 2 +- packages/dashboard/app/api/legacy.ts | 2 + packages/dashboard/app/components/NewTaskModal.tsx | 11 ++++- packages/dashboard/app/components/TaskForm.tsx | 27 ++++++++++++ .../app/components/__tests__/NewTaskModal.test.tsx | 51 ++++++++++++++++++++++ .../dashboard/src/__tests__/routes-tasks.test.ts | 33 ++++++++++++++ .../src/routes/register-task-workflow-routes.ts | 6 +++ 8 files changed, 130 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-5717 Fusion-Task-Lineage: 3bdbb561-9c6d-4f64-ad4b-ae723e73223e
This commit is contained in:
@@ -56,6 +56,7 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask,
|
||||
const [selectedWorkflowSteps, setSelectedWorkflowSteps] = useState<string[]>([]);
|
||||
const [workflowStepsExplicitlySet, setWorkflowStepsExplicitlySet] = useState(false);
|
||||
const [reviewLevel, setReviewLevel] = useState<number | undefined>(undefined);
|
||||
const [autoMerge, setAutoMerge] = useState<boolean | undefined>(undefined);
|
||||
const [priority, setPriority] = useState<TaskPriority>(DEFAULT_TASK_PRIORITY);
|
||||
const [nodeId, setNodeId] = useState<string | undefined>(undefined);
|
||||
const [githubTrackingEnabled, setGithubTrackingEnabled] = useState(false);
|
||||
@@ -161,6 +162,7 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask,
|
||||
selectedWorkflowSteps.length > 0 ||
|
||||
selectedAgentId !== null ||
|
||||
reviewLevel !== undefined ||
|
||||
autoMerge !== undefined ||
|
||||
priority !== DEFAULT_TASK_PRIORITY ||
|
||||
nodeId !== undefined ||
|
||||
branchMode !== "project-default" ||
|
||||
@@ -169,7 +171,7 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask,
|
||||
githubTrackingEnabled ||
|
||||
githubRepoOverrideTrimmed !== "";
|
||||
setHasDirtyState(isDirty);
|
||||
}, [description, dependencies, pendingImages, executorModel, validatorModel, planningModel, thinkingLevel, selectedWorkflowSteps, selectedAgentId, reviewLevel, priority, nodeId, branchMode, branch, baseBranch, githubTrackingEnabled, githubRepoOverrideTrimmed]);
|
||||
}, [description, dependencies, pendingImages, executorModel, validatorModel, planningModel, thinkingLevel, selectedWorkflowSteps, selectedAgentId, reviewLevel, autoMerge, priority, nodeId, branchMode, branch, baseBranch, githubTrackingEnabled, githubRepoOverrideTrimmed]);
|
||||
|
||||
const handleClose = useCallback(async () => {
|
||||
if (hasDirtyState) {
|
||||
@@ -197,6 +199,7 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask,
|
||||
setSelectedAgentId(null);
|
||||
setShowAgentPicker(false);
|
||||
setReviewLevel(undefined);
|
||||
setAutoMerge(undefined);
|
||||
setPriority(DEFAULT_TASK_PRIORITY);
|
||||
setNodeId(undefined);
|
||||
setBranchMode("project-default");
|
||||
@@ -242,6 +245,7 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask,
|
||||
planningModelId: planningModel && planningSlashIdx !== -1 ? planningModel.slice(planningSlashIdx + 1) : undefined,
|
||||
thinkingLevel: thinkingLevel !== "" ? thinkingLevel as "minimal" | "low" | "medium" | "high" : undefined,
|
||||
reviewLevel,
|
||||
...(autoMerge !== undefined ? { autoMerge } : {}),
|
||||
priority,
|
||||
nodeId,
|
||||
branchSelection: {
|
||||
@@ -292,6 +296,7 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask,
|
||||
setSelectedAgentId(null);
|
||||
setShowAgentPicker(false);
|
||||
setReviewLevel(undefined);
|
||||
setAutoMerge(undefined);
|
||||
setPriority(DEFAULT_TASK_PRIORITY);
|
||||
setNodeId(undefined);
|
||||
setBranchMode("project-default");
|
||||
@@ -305,7 +310,7 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask,
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}, [description, dependencies, pendingImages, executorModel, validatorModel, planningModel, thinkingLevel, isSubmitting, githubRepoOverrideInvalid, hasInvalidBranchSelection, onCreateTask, addToast, onClose, projectId, presetMode, selectedPresetId, selectedWorkflowSteps, workflowStepsExplicitlySet, selectedAgentId, reviewLevel, priority, nodeId, branchMode, isBranchNameRequired, branch, baseBranch, githubTrackingEnabled, githubRepoOverrideTrimmed]);
|
||||
}, [description, dependencies, pendingImages, executorModel, validatorModel, planningModel, thinkingLevel, isSubmitting, githubRepoOverrideInvalid, hasInvalidBranchSelection, onCreateTask, addToast, onClose, projectId, presetMode, selectedPresetId, selectedWorkflowSteps, workflowStepsExplicitlySet, selectedAgentId, reviewLevel, autoMerge, priority, nodeId, branchMode, isBranchNameRequired, branch, baseBranch, githubTrackingEnabled, githubRepoOverrideTrimmed]);
|
||||
|
||||
// Handle keyboard shortcuts
|
||||
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
|
||||
@@ -505,6 +510,8 @@ export function NewTaskModal({ isOpen, onClose, projectId, tasks, onCreateTask,
|
||||
onThinkingLevelChange={setThinkingLevel}
|
||||
reviewLevel={reviewLevel}
|
||||
onReviewLevelChange={setReviewLevel}
|
||||
autoMerge={autoMerge}
|
||||
onAutoMergeChange={setAutoMerge}
|
||||
priority={priority}
|
||||
onPriorityChange={setPriority}
|
||||
branch={branch}
|
||||
|
||||
Reference in New Issue
Block a user