diff --git a/front/src/modules/ui/data/data-table/table-cell/components/TableCellSoftFocusMode.tsx b/front/src/modules/ui/data/data-table/table-cell/components/TableCellSoftFocusMode.tsx index 1a2acbb59..424e46429 100644 --- a/front/src/modules/ui/data/data-table/table-cell/components/TableCellSoftFocusMode.tsx +++ b/front/src/modules/ui/data/data-table/table-cell/components/TableCellSoftFocusMode.tsx @@ -1,6 +1,7 @@ import { PropsWithChildren, useEffect, useRef } from 'react'; import { useIsFieldInputOnly } from '@/ui/data/field/hooks/useIsFieldInputOnly'; +import { useToggleEditOnlyInput } from '@/ui/data/field/hooks/useToggleEditOnlyInput'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { isNonTextWritingKey } from '@/ui/utilities/hotkey/utils/isNonTextWritingKey'; @@ -17,7 +18,7 @@ export const TableCellSoftFocusMode = ({ const { openTableCell } = useTableCell(); const isFieldInputOnly = useIsFieldInputOnly(); - + const toggleEditOnlyInput = useToggleEditOnlyInput(); const scrollRef = useRef(null); useEffect(() => { @@ -27,34 +28,36 @@ export const TableCellSoftFocusMode = ({ useScopedHotkeys( 'enter', () => { - openTableCell(); + if (!isFieldInputOnly) { + openTableCell(); + } else { + toggleEditOnlyInput(); + } }, TableHotkeyScope.TableSoftFocus, [openTableCell], - { - enabled: !isFieldInputOnly, - }, ); useScopedHotkeys( '*', (keyboardEvent) => { - const isWritingText = - !isNonTextWritingKey(keyboardEvent.key) && - !keyboardEvent.ctrlKey && - !keyboardEvent.metaKey; + if (!isFieldInputOnly) { + const isWritingText = + !isNonTextWritingKey(keyboardEvent.key) && + !keyboardEvent.ctrlKey && + !keyboardEvent.metaKey; - if (!isWritingText) { - return; + if (!isWritingText) { + return; + } + + openTableCell(); } - - openTableCell(); }, TableHotkeyScope.TableSoftFocus, [openTableCell], { preventDefault: false, - enabled: !isFieldInputOnly, }, ); diff --git a/front/src/modules/ui/data/field/hooks/useToggleEditOnlyInput.ts b/front/src/modules/ui/data/field/hooks/useToggleEditOnlyInput.ts new file mode 100644 index 000000000..58653555e --- /dev/null +++ b/front/src/modules/ui/data/field/hooks/useToggleEditOnlyInput.ts @@ -0,0 +1,48 @@ +import { useContext } from 'react'; +import { useRecoilCallback } from 'recoil'; + +import { FieldContext } from '../contexts/FieldContext'; +import { entityFieldsFamilySelector } from '../states/selectors/entityFieldsFamilySelector'; +import { isFieldBoolean } from '../types/guards/isFieldBoolean'; + +export const useToggleEditOnlyInput = () => { + const { entityId, fieldDefinition, useUpdateEntityMutation } = + useContext(FieldContext); + + const [updateEntity] = useUpdateEntityMutation(); + + const toggleField = useRecoilCallback( + ({ set, snapshot }) => + () => { + const fieldIsBoolean = isFieldBoolean(fieldDefinition); + + if (fieldIsBoolean) { + const fieldName = fieldDefinition.metadata.fieldName; + const oldValue = snapshot + .getLoadable(entityFieldsFamilySelector({ entityId, fieldName })) + .valueOrThrow(); + const valueToPersist = !oldValue; + set( + entityFieldsFamilySelector({ entityId, fieldName }), + valueToPersist, + ); + + updateEntity({ + variables: { + where: { id: entityId }, + data: { + [fieldName]: valueToPersist, + }, + }, + }); + } else { + throw new Error( + `Invalid value to toggle for type : ${fieldDefinition.type}, type may not be implemented in useToggleEditOnlyInput.`, + ); + } + }, + [entityId, fieldDefinition, updateEntity], + ); + + return toggleField; +};