validation now runs async, to allow for potential api calls whilst validating (the results of these calls should be cached to help with performance)
This commit is contained in:
parent
4706b78d88
commit
99dfd14ec9
@ -171,14 +171,14 @@ export const AssigneesOfITaskAssigneeEditor: React.FC<CapabilityEditorProps> = (
|
|||||||
const runValidation = (
|
const runValidation = (
|
||||||
task: TaskDefinition,
|
task: TaskDefinition,
|
||||||
tasks: TaskDefinition[],
|
tasks: TaskDefinition[],
|
||||||
): Record<string, string> => {
|
): Promise<Record<string, string>> => {
|
||||||
const errors: Record<string, string> = {};
|
const errors: Record<string, string> = {};
|
||||||
const guid = task.config.guid as string;
|
const guid = task.config.guid as string;
|
||||||
const assignees = task.config.assignees as ITaskAssignee[] | undefined;
|
const assignees = task.config.assignees as ITaskAssignee[] | undefined;
|
||||||
|
|
||||||
if (!assignees || assignees.length === 0) {
|
if (!assignees || assignees.length === 0) {
|
||||||
errors[`${guid}.assignees`] = "At least one assignee is required.";
|
errors[`${guid}.assignees`] = "At least one assignee is required.";
|
||||||
return errors;
|
return Promise.resolve(errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
assignees.forEach((a, i) => {
|
assignees.forEach((a, i) => {
|
||||||
|
|||||||
@ -69,10 +69,10 @@ export const BudgetEditor: React.FC<CapabilityEditorProps> = (props) => {
|
|||||||
const runValidation = (
|
const runValidation = (
|
||||||
task: TaskDefinition,
|
task: TaskDefinition,
|
||||||
tasks: TaskDefinition[],
|
tasks: TaskDefinition[],
|
||||||
): Record<string, string> => {
|
): Promise<Record<string, string>> => {
|
||||||
const errors: Record<string, string> = {};
|
const errors: Record<string, string> = {};
|
||||||
|
|
||||||
return errors;
|
return Promise.resolve(errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function defaultsAssignment(
|
export function defaultsAssignment(
|
||||||
|
|||||||
@ -27,10 +27,10 @@ export const BypassableEditor: React.FC<CapabilityEditorProps> = (props) => {
|
|||||||
const runValidation = (
|
const runValidation = (
|
||||||
task: TaskDefinition,
|
task: TaskDefinition,
|
||||||
tasks: TaskDefinition[],
|
tasks: TaskDefinition[],
|
||||||
): Record<string, string> => {
|
): Promise<Record<string, string>> => {
|
||||||
const errors: Record<string, string> = {};
|
const errors: Record<string, string> = {};
|
||||||
|
|
||||||
return errors;
|
return Promise.resolve(errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function defaultsAssignment(
|
export function defaultsAssignment(
|
||||||
|
|||||||
@ -152,7 +152,7 @@ export const outcomeEditor: React.FC<CapabilityEditorProps> = (props) => {
|
|||||||
const runValidation = (
|
const runValidation = (
|
||||||
task: TaskDefinition,
|
task: TaskDefinition,
|
||||||
tasks: TaskDefinition[],
|
tasks: TaskDefinition[],
|
||||||
): Record<string, string> => {
|
): Promise<Record<string, string>> => {
|
||||||
const errors: Record<string, string> = {};
|
const errors: Record<string, string> = {};
|
||||||
const guid = task.config.guid as string;
|
const guid = task.config.guid as string;
|
||||||
const outcomeActions =
|
const outcomeActions =
|
||||||
@ -160,7 +160,7 @@ const runValidation = (
|
|||||||
|
|
||||||
if (!outcomeActions) {
|
if (!outcomeActions) {
|
||||||
// No outcome actions is valid, it just means there are no outcomes configured
|
// No outcome actions is valid, it just means there are no outcomes configured
|
||||||
return errors;
|
return Promise.resolve(errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Rule 1: Task must be selected ---
|
// --- Rule 1: Task must be selected ---
|
||||||
@ -190,7 +190,7 @@ const runValidation = (
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return errors;
|
return Promise.resolve(errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function defaultsAssignment(
|
export function defaultsAssignment(
|
||||||
|
|||||||
@ -31,7 +31,7 @@ export const StageOfGeneralTaskEditor: React.FC<CapabilityEditorProps> = (
|
|||||||
|
|
||||||
const runDefaults = useCapabilityDefaults(tasksMetadata);
|
const runDefaults = useCapabilityDefaults(tasksMetadata);
|
||||||
|
|
||||||
const handleAddTask = (selectedType: TaskMetadata) => {
|
const handleAddTask = async (selectedType: TaskMetadata) => {
|
||||||
const newTask: TaskDefinition = {
|
const newTask: TaskDefinition = {
|
||||||
type: selectedType.taskType,
|
type: selectedType.taskType,
|
||||||
|
|
||||||
@ -48,14 +48,12 @@ export const StageOfGeneralTaskEditor: React.FC<CapabilityEditorProps> = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
const updatedTasks = [...childTasks, newTask];
|
const updatedTasks = [...childTasks, newTask];
|
||||||
const errors = validateTask(newTask, updatedTasks, tasksMetadata);
|
const errors = await validateTask(newTask, updatedTasks, tasksMetadata);
|
||||||
|
|
||||||
const isValid = Object.keys(errors).length === 0;
|
const isValid = Object.keys(errors).length === 0;
|
||||||
|
|
||||||
task.config.tasks = updatedTasks;
|
task.config.tasks = updatedTasks;
|
||||||
|
|
||||||
onValidate({ errors: errors, isValid: isValid } as TaskValidationResult);
|
|
||||||
|
|
||||||
onChange(task);
|
onChange(task);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,12 +64,28 @@ export const StageOfGeneralTaskEditor: React.FC<CapabilityEditorProps> = (
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const runValidation = (
|
const runValidation = async (
|
||||||
task: TaskDefinition,
|
task: TaskDefinition,
|
||||||
tasks: TaskDefinition[],
|
tasks: TaskDefinition[],
|
||||||
): Record<string, string> => {
|
): Promise<Record<string, string>> => {
|
||||||
const errors: Record<string, string> = {};
|
const errors: Record<string, string> = {};
|
||||||
|
|
||||||
|
const meta = await templateVersionsService.getTaskMetadata("GeneralTask");
|
||||||
|
|
||||||
|
if (task.config.tasks) {
|
||||||
|
for (const childTask of task.config.tasks as TaskDefinition[]) {
|
||||||
|
const childErrors = await validateTask(
|
||||||
|
childTask,
|
||||||
|
task.config.tasks as TaskDefinition[],
|
||||||
|
meta,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (childErrors && Object.keys(childErrors).length > 0) {
|
||||||
|
errors[`${task.config.guid}.tasks`] =
|
||||||
|
`One or more child tasks are invalid.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return errors;
|
return errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -27,10 +27,10 @@ export const TagsEditor: React.FC<CapabilityEditorProps> = (props) => {
|
|||||||
const runValidation = (
|
const runValidation = (
|
||||||
task: TaskDefinition,
|
task: TaskDefinition,
|
||||||
tasks: TaskDefinition[],
|
tasks: TaskDefinition[],
|
||||||
): Record<string, string> => {
|
): Promise<Record<string, string>> => {
|
||||||
const errors: Record<string, string> = {};
|
const errors: Record<string, string> = {};
|
||||||
|
|
||||||
return errors;
|
return Promise.resolve(errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function defaultsAssignment(
|
export function defaultsAssignment(
|
||||||
|
|||||||
@ -120,7 +120,7 @@ export const TaskCoreEditor: React.FC<CapabilityEditorProps> = (props) => {
|
|||||||
const runValidation = (
|
const runValidation = (
|
||||||
task: TaskDefinition,
|
task: TaskDefinition,
|
||||||
tasks: TaskDefinition[],
|
tasks: TaskDefinition[],
|
||||||
): Record<string, string> => {
|
): Promise<Record<string, string>> => {
|
||||||
const errors: Record<string, string> = {};
|
const errors: Record<string, string> = {};
|
||||||
|
|
||||||
if (!(task.config.name as string)?.trim()) {
|
if (!(task.config.name as string)?.trim()) {
|
||||||
@ -156,7 +156,7 @@ const runValidation = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors;
|
return Promise.resolve(errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function defaultsAssignment(
|
export function defaultsAssignment(
|
||||||
|
|||||||
@ -41,12 +41,16 @@ const TaskEditorComponent: React.FC<TaskEditorProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const runValidation = useCallback(
|
const runValidation = useCallback(
|
||||||
(
|
async (
|
||||||
taskToValidate: TaskDefinition,
|
taskToValidate: TaskDefinition,
|
||||||
tasksList: TaskDefinition[],
|
tasksList: TaskDefinition[],
|
||||||
tasksMetadataList: TaskMetadata[],
|
tasksMetadataList: TaskMetadata[],
|
||||||
) => {
|
) => {
|
||||||
const errors = validateTask(taskToValidate, tasksList, tasksMetadataList);
|
const errors = await validateTask(
|
||||||
|
taskToValidate,
|
||||||
|
tasksList,
|
||||||
|
tasksMetadataList,
|
||||||
|
);
|
||||||
setFieldErrors(errors);
|
setFieldErrors(errors);
|
||||||
onValidate(
|
onValidate(
|
||||||
taskToValidate.config.guid as string,
|
taskToValidate.config.guid as string,
|
||||||
|
|||||||
@ -36,14 +36,14 @@ export interface capabilityEditorRegistryEntry {
|
|||||||
task: TaskDefinition,
|
task: TaskDefinition,
|
||||||
tasks: TaskDefinition[],
|
tasks: TaskDefinition[],
|
||||||
tasksMetadata: TaskMetadata[],
|
tasksMetadata: TaskMetadata[],
|
||||||
) => Record<string, string>;
|
) => Promise<Record<string, string>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateTask(
|
export async function validateTask(
|
||||||
task: TaskDefinition,
|
task: TaskDefinition,
|
||||||
tasks: TaskDefinition[],
|
tasks: TaskDefinition[],
|
||||||
tasksMetadata: TaskMetadata[],
|
tasksMetadata: TaskMetadata[],
|
||||||
): Record<string, string> {
|
): Promise<Record<string, string>> {
|
||||||
const taskMeta = tasksMetadata.find((t) => t.taskType === task.type);
|
const taskMeta = tasksMetadata.find((t) => t.taskType === task.type);
|
||||||
|
|
||||||
const errors: Record<string, string> = {};
|
const errors: Record<string, string> = {};
|
||||||
@ -55,7 +55,7 @@ export function validateTask(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const validationErrors = entry.ValidationRunner(task, tasks);
|
const validationErrors = await entry.ValidationRunner(task, tasks);
|
||||||
Object.assign(errors, validationErrors);
|
Object.assign(errors, validationErrors);
|
||||||
}
|
}
|
||||||
return errors;
|
return errors;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user