diff --git a/packages/twenty-front/src/modules/page-layout/widgets/field/components/FieldWidgetTextEditor.tsx b/packages/twenty-front/src/modules/page-layout/widgets/field/components/FieldWidgetTextEditor.tsx index 68c0274e72..ddd59415cf 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/field/components/FieldWidgetTextEditor.tsx +++ b/packages/twenty-front/src/modules/page-layout/widgets/field/components/FieldWidgetTextEditor.tsx @@ -7,7 +7,7 @@ import { recordStoreFamilySelector } from '@/object-record/record-store/states/s import { TextArea } from '@/ui/input/components/TextArea'; import { useAtomFamilySelectorState } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorState'; import { styled } from '@linaria/react'; -import { useCallback, useEffect } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { themeCssVariables } from 'twenty-ui/theme-constants'; import { useDebouncedCallback } from 'use-debounce'; @@ -46,6 +46,11 @@ export const FieldWidgetTextEditor = ({ }); const textAreaId = `field-widget-text-editor-${recordId}-${fieldName}`; + const fieldTextValue = isFieldTextValue(fieldValue) ? fieldValue : ''; + + const [draftText, setDraftText] = useState(fieldTextValue); + const [isFocused, setIsFocused] = useState(false); + const [isDraftDirty, setIsDraftDirty] = useState(false); const persistTextDebounced = useDebouncedCallback((text: string) => { if (isRecordFieldReadOnly === true) { @@ -63,12 +68,28 @@ export const FieldWidgetTextEditor = ({ useEffect(() => () => persistTextDebounced.flush(), [persistTextDebounced]); + useEffect(() => { + if (isFocused) { + return; + } + + setDraftText(fieldTextValue); + setIsDraftDirty(false); + }, [fieldTextValue, isFocused]); + + const handleFocus = useCallback(() => { + setIsFocused(true); + setIsDraftDirty(false); + }, []); + const handleChange = useCallback( (text: string) => { if (isRecordFieldReadOnly === true) { return; } + setDraftText(text); + setIsDraftDirty(true); setFieldValue(text); persistTextDebounced(text); @@ -77,18 +98,29 @@ export const FieldWidgetTextEditor = ({ ); const handleBlur = useCallback(() => { - persistTextDebounced.flush(); - }, [persistTextDebounced]); + setIsFocused(false); - const fieldTextValue = isFieldTextValue(fieldValue) ? fieldValue : ''; + if (isDraftDirty && isRecordFieldReadOnly !== true) { + setFieldValue(draftText); + } + + persistTextDebounced.flush(); + }, [ + draftText, + isDraftDirty, + isRecordFieldReadOnly, + persistTextDebounced, + setFieldValue, + ]); return (