Capability editors now validate when the task is loaded.

This commit is contained in:
Colin Dawson 2026-02-14 12:46:47 +00:00
parent 324bce3fc0
commit 319d5165a5
4 changed files with 24 additions and 11 deletions

View File

@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from "react"; import { useCallback, useEffect, useRef, useState } from "react";
import { InputType } from "../../../../../components/common/Input"; import { InputType } from "../../../../../components/common/Input";
import { TaskDefinition } from "../../services/WorkflowTemplateService"; import { TaskDefinition } from "../../services/WorkflowTemplateService";
import { renderTaskField } from "../taskEditorHelpers"; import { renderTaskField } from "../taskEditorHelpers";
@ -20,17 +20,31 @@ export const TaskCoreEditor: React.FC<TaskCoreEditorProps> = ({
const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({}); const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});
const prevErrorsRef = useRef<Record<string, string>>({}); const prevErrorsRef = useRef<Record<string, string>>({});
useEffect(() => { const runValidation = useCallback(() => {
const errors: Record<string, string> = {}; const errors: Record<string, string> = {};
// Validation rules if (!task.config.description) {
if (task.config.description === "") {
errors["description"] = "Description cannot be empty"; errors["description"] = "Description cannot be empty";
} }
const isValid = Object.keys(errors).length === 0; const isValid = Object.keys(errors).length === 0;
return { errors, isValid };
}, [task.config.description]);
//Validate when task changes.
useEffect(() => {
const { errors, isValid } = runValidation();
setFieldErrors(errors);
prevErrorsRef.current = errors;
onValidate({ isValid, errors });
}, [onValidate, runValidation, task.config.guid]);
//Validate when fields change
useEffect(() => {
const { errors, isValid } = runValidation();
// Compare with previous errors
const prevErrors = prevErrorsRef.current; const prevErrors = prevErrorsRef.current;
const errorsChanged = const errorsChanged =
Object.keys(prevErrors).length !== Object.keys(errors).length || Object.keys(prevErrors).length !== Object.keys(errors).length ||
@ -41,7 +55,7 @@ export const TaskCoreEditor: React.FC<TaskCoreEditorProps> = ({
onValidate({ isValid, errors }); onValidate({ isValid, errors });
prevErrorsRef.current = errors; prevErrorsRef.current = errors;
} }
}, [task.config.description, task.config.name, onValidate]); }, [task.config.description, task.config.name, onValidate, runValidation]);
return ( return (
<div> <div>

View File

@ -48,9 +48,9 @@ const TaskList: React.FC<TaskListProps> = ({
}, },
}; };
if (tasks.length === 0) { //if (tasks.length === 0) {
onSelectTask(newTask); onSelectTask(newTask);
} //}
onChange([...tasks, newTask]); onChange([...tasks, newTask]);
}; };

View File

@ -1,4 +1,4 @@
import { useState } from "react"; import { useEffect, useState } from "react";
import { TaskDefinition } from "../services/WorkflowTemplateService"; import { TaskDefinition } from "../services/WorkflowTemplateService";
import { TaskCoreEditor } from "./CapabilityEditors/TaskCoreEditor"; import { TaskCoreEditor } from "./CapabilityEditors/TaskCoreEditor";

View File

@ -50,7 +50,6 @@ const TasksTab: React.FC<TasksTabProps> = ({
} }
if (!selectedTask) { if (!selectedTask) {
setSelectedTask(tasks[0]);
return; return;
} }