diff --git a/src/components/common/useForm.ts b/src/components/common/useForm.ts index 47f8892..c8bb7ca 100644 --- a/src/components/common/useForm.ts +++ b/src/components/common/useForm.ts @@ -1,4 +1,4 @@ -import { useState, useCallback, useRef, useEffect } from "react"; +import { useState, useCallback, useRef, useEffect, useMemo } from "react"; import Joi from "joi"; import { GeneralIdRef } from "../../utils/GeneralIdRef"; import { @@ -12,6 +12,7 @@ import { Glossary, } from "../../modules/manager/glossary/services/glossaryService"; import { InputType } from "./Input"; +import { TaskDefinition } from "../../modules/manager/workflowTemplates/services/WorkflowTemplateService"; export interface FormError { [key: string]: string; @@ -24,6 +25,7 @@ export interface FormData { | boolean | CustomFieldValue[] | GeneralIdRef + | TaskDefinition | CustomField[] | bigint | Glossary @@ -623,44 +625,85 @@ export const useForm = (initialState: FormState): UseFormReturn => { }, [setupNavigationGuard]); useEffect(() => { - if (!wasLoadedRef.current && state.loaded) { + const becameLoaded = !wasLoadedRef.current && state.loaded; + + if (becameLoaded) { + // Snapshot initial data initialDataRef.current = JSON.parse(JSON.stringify(state.data)); + + // Trigger validation immediately after load + Promise.resolve().then(() => { + const errors = validate(state.data); + setState({ errors }); + }); } wasLoadedRef.current = state.loaded; - }, [state.loaded, state.data]); + }, [state.loaded, state.data, validate, setState]); + + const api = useMemo( + () => ({ + state, + schema: schemaRef.current, + validate, + GetCustomFieldValues, + CustomFieldValues, + setCustomFieldValues, + getCustomFieldType, + handleSubmit, + handleGeneralError, + handleChange, + handleTextAreaChange, + handleCustomFieldChange, + handleTemplateEditorChange, + handleSelectChange, + handlePickerChange, + handleDomainPickerChange, + handleGlossaryPickerChange, + handleTemplateFormPickerChange, + handleUserPickerChange, + handleSsoProviderPickerChange, + handleToggleChange, + handleTasksChange, + setState, + hasUnsavedChanges, + markAsSaved, + setupNavigationGuard, + enableReactRouterGuard, + disableReactRouterGuard, + routerGuardEnabledRef, + }), + [ + state, + validate, + GetCustomFieldValues, + CustomFieldValues, + setCustomFieldValues, + getCustomFieldType, + handleSubmit, + handleGeneralError, + handleChange, + handleTextAreaChange, + handleCustomFieldChange, + handleTemplateEditorChange, + handleSelectChange, + handlePickerChange, + handleDomainPickerChange, + handleGlossaryPickerChange, + handleTemplateFormPickerChange, + handleUserPickerChange, + handleSsoProviderPickerChange, + handleToggleChange, + handleTasksChange, + setState, + hasUnsavedChanges, + markAsSaved, + setupNavigationGuard, + enableReactRouterGuard, + disableReactRouterGuard, + ], + ); - const api: any = { - state, - schema: schemaRef.current, - validate, - GetCustomFieldValues, - CustomFieldValues, - setCustomFieldValues, - getCustomFieldType, - handleSubmit, - handleGeneralError, - handleChange, - handleTextAreaChange, - handleCustomFieldChange, - handleTemplateEditorChange, - handleSelectChange, - handlePickerChange, - handleDomainPickerChange, - handleGlossaryPickerChange, - handleTemplateFormPickerChange, - handleUserPickerChange, - handleSsoProviderPickerChange, - handleToggleChange, - handleTasksChange, - setState, - hasUnsavedChanges, - markAsSaved, - setupNavigationGuard, - enableReactRouterGuard, - disableReactRouterGuard, - routerGuardEnabledRef, - }; Object.defineProperty(api, "schema", { get: () => schemaRef.current, set: (value: joiSchema) => {