diff --git a/src/components/Dashboard/common/ObjectForm.jsx b/src/components/Dashboard/common/ObjectForm.jsx index 9dce603..bf908a4 100644 --- a/src/components/Dashboard/common/ObjectForm.jsx +++ b/src/components/Dashboard/common/ObjectForm.jsx @@ -30,13 +30,15 @@ import { getModelByName } from '../../../database/ObjectModels' const ObjectForm = forwardRef( ({ id, type, style, children, onEdit, onStateChange }, ref) => { const [objectData, setObjectData] = useState(null) - const [serverObjectData, setServerObjectData] = useState(null) + const serverObjectData = useRef(null) + const onStateChangeRef = useRef(onStateChange) const [fetchLoading, setFetchLoading] = useState(true) const [editLoading, setEditLoading] = useState(false) const [lock, setLock] = useState({}) const [initialized, setInitialized] = useState(false) const [isEditing, setIsEditing] = useState(false) const [formValid, setFormValid] = useState(false) + const [form] = Form.useForm() const formUpdateValues = Form.useWatch([], form) const [messageApi, contextHolder] = message.useMessage() @@ -141,26 +143,32 @@ const ObjectForm = forwardRef( // Validate form on change (debounced to avoid heavy work on every keystroke) useEffect(() => { const timeoutId = setTimeout(() => { + const currentFormValues = form.getFieldsValue() + const mergedObjectData = { + ...serverObjectData.current, + ...currentFormValues + } + form .validateFields({ validateOnly: true }) .then(() => { setFormValid(true) - onStateChange({ + onStateChangeRef.current({ formValid: true, - objectData: { ...serverObjectData, ...form.getFieldsValue() } + objectData: mergedObjectData }) }) .catch(() => { setFormValid(false) - onStateChange({ + onStateChangeRef.current({ formValid: false, - objectData: { ...serverObjectData, ...form.getFieldsValue() } + objectData: mergedObjectData }) }) }, 150) return () => clearTimeout(timeoutId) - }, [form, formUpdateValues, onStateChange, serverObjectData]) + }, [form, formUpdateValues]) // Cleanup on unmount useEffect(() => { @@ -185,13 +193,13 @@ const ObjectForm = forwardRef( const handleFetchObject = useCallback(async () => { try { setFetchLoading(true) - onStateChange({ loading: true }) + onStateChangeRef.current({ loading: true }) const data = await fetchObject(id, type) const lockEvent = await fetchObjectLock(id, type) setLock(lockEvent) - onStateChange({ lock: lockEvent }) + onStateChangeRef.current({ lock: lockEvent }) setObjectData(data) - setServerObjectData(data) + serverObjectData.current = data // Calculate and set computed values on initial load const computedValues = calculateComputedValues(data, model) @@ -199,7 +207,7 @@ const ObjectForm = forwardRef( form.setFieldsValue(initialFormData) setFetchLoading(false) - onStateChange({ loading: false }) + onStateChangeRef.current({ loading: false }) } catch (err) { console.error(err) messageApi.error('Failed to fetch object info') @@ -218,7 +226,7 @@ const ObjectForm = forwardRef( // Update event handler const updateLockEventHandler = useCallback((value) => { setLock((prev) => { - onStateChange({ lock: { ...prev, ...value } }) + onStateChangeRef.current({ lock: { ...prev, ...value } }) return { ...prev, ...value } }) }, []) @@ -260,29 +268,31 @@ const ObjectForm = forwardRef( // Debounce objectData updates sent to parent to limit re-renders useEffect(() => { const timeoutId = setTimeout(() => { - onStateChange({ objectData }) + onStateChangeRef.current({ objectData }) }, 150) - return () => clearTimeout(timeoutId) - }, [objectData, onStateChange]) + }, [objectData]) const startEditing = () => { setIsEditing(true) - onStateChange({ isEditing: true }) + onStateChangeRef.current({ isEditing: true }) lockObject(id, type) } const cancelEditing = () => { - if (serverObjectData) { + if (serverObjectData.current) { // Recalculate computed values when canceling - const computedValues = calculateComputedValues(serverObjectData, model) - const resetFormData = { ...serverObjectData, ...computedValues } + const computedValues = calculateComputedValues( + serverObjectData.current, + model + ) + const resetFormData = { ...serverObjectData.current, ...computedValues } form.setFieldsValue(resetFormData) setObjectData(resetFormData) } setIsEditing(false) - onStateChange({ isEditing: false }) + onStateChangeRef.current({ isEditing: false }) unlockObject(id, type) } @@ -290,11 +300,11 @@ const ObjectForm = forwardRef( try { const value = await form.validateFields() setEditLoading(true) - onStateChange({ editLoading: true }) + onStateChangeRef.current({ editLoading: true }) await updateObject(id, type, value) setObjectData({ ...objectData, ...value }) setIsEditing(false) - onStateChange({ isEditing: false }) + onStateChangeRef.current({ isEditing: false }) messageApi.success('Information updated successfully') } catch (err) { console.error(err) @@ -309,7 +319,7 @@ const ObjectForm = forwardRef( } finally { handleFetchObject() setEditLoading(false) - onStateChange({ editLoading: false }) + onStateChangeRef.current({ editLoading: false }) } }