Added a search box in sort menu (#5045)

Closes #4368

---------

Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
Vinod Rathod 2024-04-25 19:01:41 +05:30 committed by GitHub
parent 806666d909
commit 4af2c5f298
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 91 additions and 3 deletions

View File

@ -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'}
</DropdownMenuHeader>
<DropdownMenuSeparator />
<StyledInput
autoFocus
value={objectSortDropdownSearchInput}
placeholder="Search fields"
onChange={(event) =>
setObjectSortDropdownSearchInput(event.target.value)
}
/>
<DropdownMenuItemsContainer>
{[...availableSortDefinitions]
.sort((a, b) => a.label.localeCompare(b.label))
.filter((item) =>
item.label
.toLocaleLowerCase()
.includes(
objectSortDropdownSearchInput.toLocaleLowerCase(),
),
)
.map((availableSortDefinition, index) => (
<MenuItem
testId={`select-sort-${index}`}
key={index}
onClick={() => handleAddSort(availableSortDefinition)}
onClick={() => {
setObjectSortDropdownSearchInput('');
handleAddSort(availableSortDefinition);
}}
LeftIcon={getIcon(availableSortDefinition.iconName)}
text={availableSortDefinition.label}
/>

View File

@ -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,
};

View File

@ -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,
};
};

View File

@ -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,
};
};

View File

@ -0,0 +1,7 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export const objectSortDropdownSearchInputComponentState =
createComponentState<string>({
key: 'objectSortDropdownSearchInputComponentState',
defaultValue: '',
});