diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectForm.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectForm.tsx index 0f30a88b6..d23690fc3 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectForm.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectForm.tsx @@ -1,6 +1,8 @@ +import { useState } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import styled from '@emotion/styled'; import { DropResult } from '@hello-pangea/dnd'; +import { Key } from 'ts-key-enum'; import { IconPlus } from 'twenty-ui'; import { z } from 'zod'; @@ -19,6 +21,8 @@ import { CardContent } from '@/ui/layout/card/components/CardContent'; import { CardFooter } from '@/ui/layout/card/components/CardFooter'; import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem'; import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList'; +import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; +import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope'; import { FieldMetadataType } from '~/generated-metadata/graphql'; import { moveArrayItem } from '~/utils/array/moveArrayItem'; import { toSpliced } from '~/utils/array/toSpliced'; @@ -78,6 +82,7 @@ const StyledButton = styled(LightButton)` export const SettingsDataModelFieldSelectForm = ({ fieldMetadataItem, }: SettingsDataModelFieldSelectFormProps) => { + const [focusedOptionId, setFocusedOptionId] = useState(''); const { initialDefaultValue, initialOptions } = useSelectSettingsFormInitialValues({ fieldMetadataItem }); @@ -167,6 +172,37 @@ export const SettingsDataModelFieldSelectForm = ({ } }; + const getOptionsWithNewOption = () => { + const currentOptions = getValues('options'); + + const newOptions = [ + ...currentOptions, + generateNewSelectOption(currentOptions), + ]; + + return newOptions; + }; + + const handleAddOption = () => { + const newOptions = getOptionsWithNewOption(); + + setFormValue('options', newOptions); + }; + + useScopedHotkeys( + Key.Enter, + () => { + const newOptions = getOptionsWithNewOption(); + + setFormValue('options', newOptions); + + const lastOptionId = newOptions[newOptions.length - 1].id; + + setFocusedOptionId(lastOptionId); + }, + AppHotkeyScope.App, + ); + return ( <> { const nextOptions = toSpliced( options, @@ -245,9 +282,7 @@ export const SettingsDataModelFieldSelectForm = ({ - onChange([...options, generateNewSelectOption(options)]) - } + onClick={handleAddOption} /> diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectFormOptionRow.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectFormOptionRow.tsx index fdc99c137..c8f4174fb 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectFormOptionRow.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectFormOptionRow.tsx @@ -1,4 +1,4 @@ -import { useMemo } from 'react'; +import { useEffect, useMemo, useRef } from 'react'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { @@ -31,6 +31,7 @@ type SettingsDataModelFieldSelectFormOptionRowProps = { onSetAsDefault?: () => void; onRemoveAsDefault?: () => void; option: FieldMetadataItemOption; + focused?: boolean; }; const StyledRow = styled.div` @@ -63,12 +64,18 @@ export const SettingsDataModelFieldSelectFormOptionRow = ({ onSetAsDefault, onRemoveAsDefault, option, + focused, }: SettingsDataModelFieldSelectFormOptionRowProps) => { + const inputRef = useRef(null); + const theme = useTheme(); const dropdownIds = useMemo(() => { const baseScopeId = `select-field-option-row-${v4()}`; - return { color: `${baseScopeId}-color`, actions: `${baseScopeId}-actions` }; + return { + color: `${baseScopeId}-color`, + actions: `${baseScopeId}-actions`, + }; }, []); const { closeDropdown: closeColorDropdown } = useDropdown(dropdownIds.color); @@ -76,6 +83,12 @@ export const SettingsDataModelFieldSelectFormOptionRow = ({ dropdownIds.actions, ); + useEffect(() => { + if (focused === true) { + inputRef.current?.focus(); + } + }, [focused]); + return ( - onChange({ ...option, label, value: getOptionValueFromLabel(label) }) + onChange({ + ...option, + label, + value: getOptionValueFromLabel(label), + }) } RightIcon={isDefault ? IconCheck : undefined} />