From 7c477619f0ac9bc680772e9362806d101068d7a9 Mon Sep 17 00:00:00 2001 From: Awen Saunders Date: Fri, 20 Sep 2024 18:00:31 +0100 Subject: [PATCH 1/3] Make calculated fields work everywhere This still needs some refactoring as eslint doesn't like where the code currently lives. --- .../components/record-form/form/record-form.jsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/app/javascript/components/record-form/form/record-form.jsx b/app/javascript/components/record-form/form/record-form.jsx index 83757c45db..896c8e1518 100644 --- a/app/javascript/components/record-form/form/record-form.jsx +++ b/app/javascript/components/record-form/form/record-form.jsx @@ -18,6 +18,7 @@ import { AUDIO_FIELD, DOCUMENT_FIELD, PHOTO_FIELD } from "../constants"; import { LEGITIMATE_BASIS } from "../../record-creation-flow/components/consent-prompt/constants"; import renderFormSections from "../components/render-form-sections"; import { useApp } from "../../application"; +import { parseExpression } from "../../../libs/expressions"; import { RECORD_FORM_NAME } from "./constants"; import { fieldValidations } from "./validations"; @@ -188,6 +189,8 @@ function RecordForm({ formikValues.current = values; }; + const calculatedFields = forms.flatMap(fs => fs.fields.filter(field => field.calculation?.expression)); + if (!isEmpty(initialValues) && !isEmpty(forms)) { const validationSchema = buildValidationSchema(forms); const handleOnSubmit = values => { @@ -207,11 +210,23 @@ function RecordForm({ > {props => { // eslint-disable-next-line react/prop-types - const { submitForm, values } = props; + const { submitForm, values, setFieldValue } = props; bindSubmitForm(submitForm); setFormikValuesForNav(values); + useEffect(() => { + if (values) { + calculatedFields.forEach(field => { + const result = parseExpression(field.calculation.expression).evaluate(values); + + if (values[field.name] !== result) { + setFieldValue(field.name, result, false); + } + }); + } + }, [values]); + return ( Date: Fri, 20 Sep 2024 19:08:29 +0100 Subject: [PATCH 2/3] Use bindRecalculateFields to pass a closure This gets around the issue that eslint was complaining about as the react hook is now at the top level, and we pass a closure into it. --- .../record-form/form/record-form.jsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/app/javascript/components/record-form/form/record-form.jsx b/app/javascript/components/record-form/form/record-form.jsx index 896c8e1518..dc0c82a085 100644 --- a/app/javascript/components/record-form/form/record-form.jsx +++ b/app/javascript/components/record-form/form/record-form.jsx @@ -55,6 +55,7 @@ function RecordForm({ const formikValues = useRef(); const bindedSetValues = useRef(null); const bindedResetForm = useRef(null); + const bindedRecalculateFields = useRef(null); const bindSetValues = setValues => { bindedSetValues.current = setValues; @@ -64,6 +65,10 @@ function RecordForm({ bindedResetForm.current = resetForm; }; + const bindRecalculateFields = recalculateFields => { + bindedRecalculateFields.current = recalculateFields; + } + const buildValidationSchema = formSections => { const schema = formSections.reduce((obj, item) => { return Object.assign( @@ -175,6 +180,14 @@ function RecordForm({ } }, [mode.isNew, dataProtectionInitialValues]); + const calculatedFields = forms.flatMap(fs => fs.fields.filter(field => field.calculation?.expression)); + + useEffect(() => { + if (typeof bindedRecalculateFields.current === "function") { + bindedRecalculateFields.current(); + } + }) + const handleConfirm = onConfirm => { onConfirm(); if (incidentFromCase?.size) { @@ -189,7 +202,6 @@ function RecordForm({ formikValues.current = values; }; - const calculatedFields = forms.flatMap(fs => fs.fields.filter(field => field.calculation?.expression)); if (!isEmpty(initialValues) && !isEmpty(forms)) { const validationSchema = buildValidationSchema(forms); @@ -215,17 +227,16 @@ function RecordForm({ bindSubmitForm(submitForm); setFormikValuesForNav(values); - useEffect(() => { + bindRecalculateFields(() => { if (values) { calculatedFields.forEach(field => { const result = parseExpression(field.calculation.expression).evaluate(values); - if (values[field.name] !== result) { setFieldValue(field.name, result, false); } }); } - }, [values]); + }); return ( Date: Tue, 24 Sep 2024 13:26:24 +0100 Subject: [PATCH 3/3] Fix linting issue on record-form --- app/javascript/components/record-form/form/record-form.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/javascript/components/record-form/form/record-form.jsx b/app/javascript/components/record-form/form/record-form.jsx index dc0c82a085..26ffbeda6a 100644 --- a/app/javascript/components/record-form/form/record-form.jsx +++ b/app/javascript/components/record-form/form/record-form.jsx @@ -67,7 +67,7 @@ function RecordForm({ const bindRecalculateFields = recalculateFields => { bindedRecalculateFields.current = recalculateFields; - } + }; const buildValidationSchema = formSections => { const schema = formSections.reduce((obj, item) => { @@ -186,7 +186,7 @@ function RecordForm({ if (typeof bindedRecalculateFields.current === "function") { bindedRecalculateFields.current(); } - }) + }); const handleConfirm = onConfirm => { onConfirm(); @@ -202,7 +202,6 @@ function RecordForm({ formikValues.current = values; }; - if (!isEmpty(initialValues) && !isEmpty(forms)) { const validationSchema = buildValidationSchema(forms); const handleOnSubmit = values => { @@ -231,6 +230,7 @@ function RecordForm({ if (values) { calculatedFields.forEach(field => { const result = parseExpression(field.calculation.expression).evaluate(values); + if (values[field.name] !== result) { setFieldValue(field.name, result, false); }