diff --git a/src/components/renderer/form/form-renderer.component.tsx b/src/components/renderer/form/form-renderer.component.tsx index acfe203c0..cb5063e5e 100644 --- a/src/components/renderer/form/form-renderer.component.tsx +++ b/src/components/renderer/form/form-renderer.component.tsx @@ -18,10 +18,15 @@ export type FormRendererProps = { export const FormRenderer = ({ processorContext, initialValues, setIsLoadingFormDependencies }: FormRendererProps) => { const { evaluatedFields, evaluatedFormJson } = useEvaluateFormFieldExpressions(initialValues, processorContext); - const { registerForm, workspaceLayout } = useFormFactory(); + const { registerForm, setIsFormDirty, workspaceLayout } = useFormFactory(); const methods = useForm({ defaultValues: initialValues, }); + + const { + formState: { isDirty }, + } = methods; + const [{ formFields, invalidFields, formJson }, dispatch] = useReducer(formStateReducer, { ...initialState, formFields: evaluatedFields, @@ -62,6 +67,10 @@ export const FormRenderer = ({ processorContext, initialValues, setIsLoadingForm registerForm(formJson.name, context); }, [formJson.name, context]); + useEffect(() => { + setIsFormDirty(isDirty); + }, [isDirty]); + return ( {formJson.pages.map((page) => { diff --git a/src/form-engine.component.tsx b/src/form-engine.component.tsx index 034e0ba9e..edb940e20 100644 --- a/src/form-engine.component.tsx +++ b/src/form-engine.component.tsx @@ -30,6 +30,7 @@ interface FormEngineProps { onCancel?: () => void; handleClose?: () => void; handleConfirmQuestionDeletion?: (question: Readonly) => Promise; + markFormAsDirty?: (isDirty: boolean) => void; } // TODOs: @@ -48,6 +49,7 @@ const FormEngine = ({ onCancel, handleClose, handleConfirmQuestionDeletion, + markFormAsDirty, }: FormEngineProps) => { const { t } = useTranslation(); const session = useSession(); @@ -60,6 +62,7 @@ const FormEngine = ({ const [isLoadingDependencies, setIsLoadingDependencies] = useState(false); const [showSidebar, setShowSidebar] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); + const [isFormDirty, setIsFormDirty] = useState(false); // TODO: Updating this prop triggers a rerender of the entire form. This means whenever we scroll into a new page, the form is rerendered. // Figure out a way to avoid this. Maybe use a ref with an observer instead of a state? const [currentPage, setCurrentPage] = useState(''); @@ -89,6 +92,10 @@ const FormEngine = ({ }; }, []); + useEffect(() => { + markFormAsDirty?.(isFormDirty); + }, [isFormDirty]); + const handleSubmit = useCallback((e: React.FormEvent) => { e.preventDefault(); setIsSubmitting(true); @@ -116,6 +123,7 @@ const FormEngine = ({ onError: () => {}, handleClose: () => {}, }} + setIsFormDirty={setIsFormDirty} setCurrentPage={setCurrentPage}>
{isLoadingDependencies && ( diff --git a/src/provider/form-factory-provider.tsx b/src/provider/form-factory-provider.tsx index 404d580d6..cba1b6c1a 100644 --- a/src/provider/form-factory-provider.tsx +++ b/src/provider/form-factory-provider.tsx @@ -30,6 +30,7 @@ interface FormFactoryProviderContextProps { registerForm: (formId: string, context: FormContextProps) => void; setCurrentPage: (page: string) => void; handleConfirmQuestionDeletion?: (question: Readonly) => Promise; + setIsFormDirty: (isFormDirty: boolean) => void; } interface FormFactoryProviderProps { @@ -51,6 +52,7 @@ interface FormFactoryProviderProps { }; setCurrentPage: (page: string) => void; handleConfirmQuestionDeletion?: (question: Readonly) => Promise; + setIsFormDirty: (isFormDirty: boolean) => void; } const FormFactoryProviderContext = createContext(undefined); @@ -68,6 +70,7 @@ export const FormFactoryProvider: React.FC = ({ formSubmissionProps, setCurrentPage, handleConfirmQuestionDeletion, + setIsFormDirty, }) => { const { t } = useTranslation(); const rootForm = useRef(); @@ -154,6 +157,7 @@ export const FormFactoryProvider: React.FC = ({ registerForm, setCurrentPage, handleConfirmQuestionDeletion, + setIsFormDirty, }}> {formProcessors.current && children} diff --git a/yarn.lock b/yarn.lock index c22c9c744..bd046bb41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3316,8 +3316,8 @@ __metadata: linkType: hard "@openmrs/esm-patient-common-lib@npm:next": - version: 8.0.1-pre.4537 - resolution: "@openmrs/esm-patient-common-lib@npm:8.0.1-pre.4537" + version: 8.1.1-pre.5183 + resolution: "@openmrs/esm-patient-common-lib@npm:8.1.1-pre.5183" dependencies: "@carbon/react": "npm:^1.12.0" lodash-es: "npm:^4.17.21" @@ -3326,7 +3326,7 @@ __metadata: "@openmrs/esm-framework": 5.x react: 18.x single-spa: 6.x - checksum: 10/2c8e7348732d3baf37876e983ff523bb8c0cc2c0e676fca96a4459e2c524e05b97b350244964ee96137af9b2f4e94988518ef4fb0b3727833bff4d1f9a2f3cca + checksum: 10/b6d1a4ecf05e06447dbab30068af204157bb67f6e6c207ad568a01599974e5afd2e9a106621d5ed5db3d1d6c129baa13ecd1c615cec58fb6e9bf70287dc7a463 languageName: node linkType: hard