diff --git a/src/modules/manager/workflowTemplates/components/CapabilityEditors/TaskCoreEditor.tsx b/src/modules/manager/workflowTemplates/components/CapabilityEditors/TaskCoreEditor.tsx index e2dcfb0..501edad 100644 --- a/src/modules/manager/workflowTemplates/components/CapabilityEditors/TaskCoreEditor.tsx +++ b/src/modules/manager/workflowTemplates/components/CapabilityEditors/TaskCoreEditor.tsx @@ -16,6 +16,7 @@ interface TaskCoreEditorProps { allowedTasks: TaskMetadata[]; onChange: (updated: TaskDefinition) => void; onValidate: (result: TaskValidationResult) => void; + shouldAssignDefaults: boolean; } export const TaskCoreEditor: React.FC = ({ @@ -24,11 +25,11 @@ export const TaskCoreEditor: React.FC = ({ allowedTasks, onChange, onValidate, + shouldAssignDefaults, }) => { const { t: tTaskType } = useTranslation(Namespaces.TaskTypes); const [fieldErrors, setFieldErrors] = useState>({}); const prevErrorsRef = useRef>({}); - const hasAssignedDefaultName = useRef(false); // Generate a unique default name const nameExists = (tasks: TaskDefinition[], candidate: string): boolean => { @@ -59,42 +60,50 @@ export const TaskCoreEditor: React.FC = ({ [allowedTasks, task.type, tTaskType], ); - useEffect(() => { - // Reset the guard when a new task is loaded - hasAssignedDefaultName.current = false; - }, [task.config.guid]); + const assignDefaults = ( + newConfig: Record, + task: TaskDefinition, + allTasks: TaskDefinition[], + allowedTasks: TaskMetadata[], + formatNewTaskName: (tasks: TaskDefinition[]) => string, + ) => { + const displayName = allowedTasks.find( + (t) => t.taskType === task.type, + )?.displayName; - useEffect(() => { - if (!hasAssignedDefaultName.current && !task.config.name) { - hasAssignedDefaultName.current = true; - - const displayName = allowedTasks.find( - (t) => t.taskType === task.type, - )?.displayName; - - const newConfig = { ...task.config }; - - // Assign default name - if (displayName) { - newConfig.name = formatNewTaskName(allTasks); - } - - // Assign default predecessor (the task immediately before this one) - const index = allTasks.findIndex( - (t) => t.config.guid === task.config.guid, - ); - - if (index > 0) { - const previousTask = allTasks[index - 1]; - newConfig.predecessors = [previousTask.config.guid as string]; - } - - onChange({ - ...task, - config: newConfig, - }); + // Assign default name + if (displayName) { + newConfig.name = formatNewTaskName(allTasks); } - }, [allTasks, allowedTasks, formatNewTaskName, onChange, task]); + + // Assign default predecessor (the task immediately before this one) + const index = allTasks.findIndex((t) => t.config.guid === task.config.guid); + + if (index > 0) { + const previousTask = allTasks[index - 1]; + newConfig.predecessors = [previousTask.config.guid as string]; + } + }; + + useEffect(() => { + if (!shouldAssignDefaults) return; + + const newConfig = { ...task.config }; + + assignDefaults(newConfig, task, allTasks, allowedTasks, formatNewTaskName); + + onChange({ + ...task, + config: newConfig, + }); + }, [ + shouldAssignDefaults, + task, + allTasks, + allowedTasks, + formatNewTaskName, + onChange, + ]); const runValidation = useCallback(() => { const errors: Record = {}; diff --git a/src/modules/manager/workflowTemplates/components/TasksEditor.tsx b/src/modules/manager/workflowTemplates/components/TasksEditor.tsx index e02dab3..31432a1 100644 --- a/src/modules/manager/workflowTemplates/components/TasksEditor.tsx +++ b/src/modules/manager/workflowTemplates/components/TasksEditor.tsx @@ -25,6 +25,30 @@ export const TaskEditor: React.FC = ({ onChange, onValidate, }) => { + //region assign defaults + const hasAssignedDefaultsRef = useRef(false); + const [shouldAssignDefaults, setShouldAssignDefaults] = useState(false); + + // Reset guard when a new task is loaded + useEffect(() => { + hasAssignedDefaultsRef.current = false; + setShouldAssignDefaults(false); + }, [task.config.guid]); + + // Decide when to trigger initial defaults (current rule: no name yet) + useEffect(() => { + if (!hasAssignedDefaultsRef.current && !task.config.name) { + hasAssignedDefaultsRef.current = true; + setShouldAssignDefaults(true); + } else { + // ensure we only pulse true once + setShouldAssignDefaults(false); + } + }, [task.config.name]); + + //end region assign defaults + + //region Validation // eslint-disable-next-line @typescript-eslint/no-unused-vars const [validationMap, setValidationMap] = useState< Record @@ -52,6 +76,8 @@ export const TaskEditor: React.FC = ({ } }, [validationMap, task.config.guid, onValidate]); + //End region validation + return ( <> = ({ allTasks={allTasks} onChange={onChange} onValidate={(result) => onCapabilityValidate("core", result)} + shouldAssignDefaults={shouldAssignDefaults} /> );