diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx index 02ca43184..410379b4a 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx @@ -1,3 +1,5 @@ +import styled from '@emotion/styled'; +import { useRecoilValue } from 'recoil'; import { IconChevronDown, useIcons } from 'twenty-ui'; import { OBJECT_SORT_DROPDOWN_ID } from '@/object-record/object-sort-dropdown/constants/ObjectSortDropdownId'; @@ -7,12 +9,35 @@ import { LightButton } from '@/ui/input/button/components/LightButton'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; -import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { SORT_DIRECTIONS } from '../types/SortDirection'; +export const StyledInput = styled.input` + background: ${({ theme }) => theme.background.secondary}; + border: none; + border-top: 1px solid ${({ theme }) => theme.border.color.light}; + border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; + border-radius: 0; + color: ${({ theme }) => theme.font.color.primary}; + margin: 0; + outline: none; + padding: ${({ theme }) => theme.spacing(2)}; + height: 20px; + font-family: inherit; + font-size: ${({ theme }) => theme.font.size.sm}; + + font-weight: inherit; + max-width: 100%; + overflow: hidden; + text-decoration: none; + + &::placeholder { + color: ${({ theme }) => theme.font.color.light}; + } +`; + export type ObjectSortDropdownButtonProps = { sortDropdownId: string; hotkeyScope: HotkeyScope; @@ -32,6 +57,9 @@ export const ObjectSortDropdownButton = ({ isSortSelected, availableSortDefinitions, handleAddSort, + objectSortDropdownSearchInputState, + setObjectSortDropdownSearchInput, + resetSearchInput, } = useObjectSortDropdown(); const handleButtonClick = () => { @@ -39,9 +67,14 @@ export const ObjectSortDropdownButton = ({ }; const handleDropdownButtonClose = () => { + resetSearchInput(); resetState(); }; + const objectSortDropdownSearchInput = useRecoilValue( + objectSortDropdownSearchInputState, + ); + const { getIcon } = useIcons(); return ( @@ -80,15 +113,32 @@ export const ObjectSortDropdownButton = ({ > {selectedSortDirection === 'asc' ? 'Ascending' : 'Descending'} - + + setObjectSortDropdownSearchInput(event.target.value) + } + /> {[...availableSortDefinitions] .sort((a, b) => a.label.localeCompare(b.label)) + .filter((item) => + item.label + .toLocaleLowerCase() + .includes( + objectSortDropdownSearchInput.toLocaleLowerCase(), + ), + ) .map((availableSortDefinition, index) => ( handleAddSort(availableSortDefinition)} + onClick={() => { + setObjectSortDropdownSearchInput(''); + handleAddSort(availableSortDefinition); + }} LeftIcon={getIcon(availableSortDefinition.iconName)} text={availableSortDefinition.label} /> diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useObjectSortDropdown.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useObjectSortDropdown.ts index 85322c628..4a797a259 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useObjectSortDropdown.ts +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useObjectSortDropdown.ts @@ -44,6 +44,9 @@ export const useObjectSortDropdown = () => { availableSortDefinitionsState, onSortSelectState, isSortSelectedState, + objectSortDropdownSearchInputState, + setObjectSortDropdownSearchInput, + resetSearchInput, } = useSortDropdown({ sortDropdownId: VIEW_SORT_DROPDOWN_ID, }); @@ -71,6 +74,9 @@ export const useObjectSortDropdown = () => { toggleSortDropdown, resetState, isSortSelected, + objectSortDropdownSearchInputState, + setObjectSortDropdownSearchInput, + resetSearchInput, availableSortDefinitions, handleAddSort, }; diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdown.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdown.ts index aee777aa1..44373f1fa 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdown.ts +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdown.ts @@ -1,3 +1,5 @@ +import { useRecoilCallback, useSetRecoilState } from 'recoil'; + import { useSortDropdownStates } from '@/object-record/object-sort-dropdown/hooks/useSortDropdownStates'; import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; @@ -16,12 +18,28 @@ export const useSortDropdown = (props?: UseSortProps) => { availableSortDefinitionsState, isSortSelectedState, onSortSelectState, + objectSortDropdownSearchInputState, } = useSortDropdownStates(scopeId); + const setObjectSortDropdownSearchInput = useSetRecoilState( + objectSortDropdownSearchInputState, + ); + + const resetSearchInput = useRecoilCallback( + ({ set }) => + () => { + set(objectSortDropdownSearchInputState, ''); + }, + [objectSortDropdownSearchInputState], + ); + return { scopeId, availableSortDefinitionsState, isSortSelectedState, onSortSelectState, + objectSortDropdownSearchInputState, + setObjectSortDropdownSearchInput, + resetSearchInput, }; }; diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdownStates.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdownStates.ts index 74c6bdb54..b36788076 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdownStates.ts +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useSortDropdownStates.ts @@ -1,4 +1,5 @@ import { isSortSelectedComponentState } from '@/object-record/object-sort-dropdown/states/isSortSelectedScopedState'; +import { objectSortDropdownSearchInputComponentState } from '@/object-record/object-sort-dropdown/states/objectSortDropdownSearchInputComponentState'; import { onSortSelectComponentState } from '@/object-record/object-sort-dropdown/states/onSortSelectScopedState'; import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; import { availableSortDefinitionsComponentState } from '@/views/states/availableSortDefinitionsComponentState'; @@ -19,9 +20,15 @@ export const useSortDropdownStates = (scopeId: string) => { scopeId, ); + const objectSortDropdownSearchInputState = extractComponentState( + objectSortDropdownSearchInputComponentState, + scopeId, + ); + return { availableSortDefinitionsState, isSortSelectedState, onSortSelectState, + objectSortDropdownSearchInputState, }; }; diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/objectSortDropdownSearchInputComponentState.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/objectSortDropdownSearchInputComponentState.ts new file mode 100644 index 000000000..216161938 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/states/objectSortDropdownSearchInputComponentState.ts @@ -0,0 +1,7 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const objectSortDropdownSearchInputComponentState = + createComponentState({ + key: 'objectSortDropdownSearchInputComponentState', + defaultValue: '', + });