Altered the default assignment code so that it is scalable.

This commit is contained in:
Colin Dawson 2026-02-14 22:56:34 +00:00
parent f45f9f0b25
commit e7a084c301
2 changed files with 71 additions and 35 deletions

View File

@ -16,6 +16,7 @@ interface TaskCoreEditorProps {
allowedTasks: TaskMetadata[];
onChange: (updated: TaskDefinition) => void;
onValidate: (result: TaskValidationResult) => void;
shouldAssignDefaults: boolean;
}
export const TaskCoreEditor: React.FC<TaskCoreEditorProps> = ({
@ -24,11 +25,11 @@ export const TaskCoreEditor: React.FC<TaskCoreEditorProps> = ({
allowedTasks,
onChange,
onValidate,
shouldAssignDefaults,
}) => {
const { t: tTaskType } = useTranslation(Namespaces.TaskTypes);
const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});
const prevErrorsRef = useRef<Record<string, string>>({});
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<TaskCoreEditorProps> = ({
[allowedTasks, task.type, tTaskType],
);
useEffect(() => {
// Reset the guard when a new task is loaded
hasAssignedDefaultName.current = false;
}, [task.config.guid]);
useEffect(() => {
if (!hasAssignedDefaultName.current && !task.config.name) {
hasAssignedDefaultName.current = true;
const assignDefaults = (
newConfig: Record<string, unknown>,
task: TaskDefinition,
allTasks: TaskDefinition[],
allowedTasks: TaskMetadata[],
formatNewTaskName: (tasks: TaskDefinition[]) => string,
) => {
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,
);
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,
});
}
}, [allTasks, allowedTasks, formatNewTaskName, onChange, task]);
}, [
shouldAssignDefaults,
task,
allTasks,
allowedTasks,
formatNewTaskName,
onChange,
]);
const runValidation = useCallback(() => {
const errors: Record<string, string> = {};

View File

@ -25,6 +25,30 @@ export const TaskEditor: React.FC<TaskEditorProps> = ({
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<string, TaskValidationResult>
@ -52,6 +76,8 @@ export const TaskEditor: React.FC<TaskEditorProps> = ({
}
}, [validationMap, task.config.guid, onValidate]);
//End region validation
return (
<>
<TaskCoreEditor
@ -60,6 +86,7 @@ export const TaskEditor: React.FC<TaskEditorProps> = ({
allTasks={allTasks}
onChange={onChange}
onValidate={(result) => onCapabilityValidate("core", result)}
shouldAssignDefaults={shouldAssignDefaults}
/>
</>
);