Sammy/t 192 aau whan i select does not include it is (#99)
* feature: add operand list to filters * feature: implement not include * feature: add operand on filters * feature: use filters operand instead of defaults * test: adapt test with new operands * refactor: remove useless %% in gql where * test: test fullname filter * test: add test for where rendering of filters
This commit is contained in:
@ -16,11 +16,6 @@ type OwnProps<FilterProperties> = {
|
||||
) => void;
|
||||
};
|
||||
|
||||
const filterOperands: FilterOperandType[] = [
|
||||
{ label: 'Include', id: 'include', keyWord: 'ilike' },
|
||||
{ label: "Doesn't include", id: 'not-include', keyWord: 'not_ilike' },
|
||||
];
|
||||
|
||||
export function FilterDropdownButton<FilterProperties>({
|
||||
availableFilters,
|
||||
filterSearchResults,
|
||||
@ -36,33 +31,37 @@ export function FilterDropdownButton<FilterProperties>({
|
||||
FilterType<FilterProperties> | undefined
|
||||
>(undefined);
|
||||
|
||||
const [selectedFilterOperand, setSelectedFilterOperand] =
|
||||
useState<FilterOperandType>(filterOperands[0]);
|
||||
const [selectedFilterOperand, setSelectedFilterOperand] = useState<
|
||||
FilterOperandType | undefined
|
||||
>(undefined);
|
||||
|
||||
const resetState = useCallback(() => {
|
||||
setIsOptionUnfolded(false);
|
||||
setSelectedFilter(undefined);
|
||||
setSelectedFilterOperand(filterOperands[0]);
|
||||
setSelectedFilterOperand(undefined);
|
||||
onFilterSearch(null, '');
|
||||
}, [onFilterSearch]);
|
||||
|
||||
const renderSelectOptionItems = filterOperands.map((filterOperand, index) => (
|
||||
<DropdownButton.StyledDropdownItem
|
||||
key={`select-filter-operand-${index}`}
|
||||
onClick={() => {
|
||||
setSelectedFilterOperand(filterOperand);
|
||||
setIsOptionUnfolded(false);
|
||||
}}
|
||||
>
|
||||
{filterOperand.label}
|
||||
</DropdownButton.StyledDropdownItem>
|
||||
));
|
||||
const renderSelectOptionItems = selectedFilter?.operands.map(
|
||||
(filterOperand, index) => (
|
||||
<DropdownButton.StyledDropdownItem
|
||||
key={`select-filter-operand-${index}`}
|
||||
onClick={() => {
|
||||
setSelectedFilterOperand(filterOperand);
|
||||
setIsOptionUnfolded(false);
|
||||
}}
|
||||
>
|
||||
{filterOperand.label}
|
||||
</DropdownButton.StyledDropdownItem>
|
||||
),
|
||||
);
|
||||
|
||||
const renderSearchResults = (
|
||||
filterSearchResults: NonNullable<
|
||||
OwnProps<FilterProperties>['filterSearchResults']
|
||||
>,
|
||||
selectedFilter: FilterType<FilterProperties>,
|
||||
selectedFilterOperand: FilterOperandType,
|
||||
) => {
|
||||
if (filterSearchResults.loading) {
|
||||
return (
|
||||
@ -76,6 +75,7 @@ export function FilterDropdownButton<FilterProperties>({
|
||||
key={`fields-value-${index}`}
|
||||
onClick={() => {
|
||||
onFilterSelect({
|
||||
...selectedFilter,
|
||||
key: value.displayValue,
|
||||
operand: selectedFilterOperand,
|
||||
searchQuery: selectedFilter.searchQuery,
|
||||
@ -104,6 +104,7 @@ export function FilterDropdownButton<FilterProperties>({
|
||||
key={`select-filter-${index}`}
|
||||
onClick={() => {
|
||||
setSelectedFilter(filter);
|
||||
setSelectedFilterOperand(filter.operands[0]);
|
||||
onFilterSearch(filter, '');
|
||||
}}
|
||||
>
|
||||
@ -112,7 +113,10 @@ export function FilterDropdownButton<FilterProperties>({
|
||||
</DropdownButton.StyledDropdownItem>
|
||||
));
|
||||
|
||||
function renderFilterDropdown(selectedFilter: FilterType<FilterProperties>) {
|
||||
function renderFilterDropdown(
|
||||
selectedFilter: FilterType<FilterProperties>,
|
||||
selectedFilterOperand: FilterOperandType,
|
||||
) {
|
||||
return (
|
||||
<>
|
||||
<DropdownButton.StyledDropdownTopOption
|
||||
@ -133,7 +137,11 @@ export function FilterDropdownButton<FilterProperties>({
|
||||
/>
|
||||
</DropdownButton.StyledSearchField>
|
||||
{filterSearchResults &&
|
||||
renderSearchResults(filterSearchResults, selectedFilter)}
|
||||
renderSearchResults(
|
||||
filterSearchResults,
|
||||
selectedFilter,
|
||||
selectedFilterOperand,
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -146,10 +154,10 @@ export function FilterDropdownButton<FilterProperties>({
|
||||
setIsUnfolded={setIsUnfolded}
|
||||
resetState={resetState}
|
||||
>
|
||||
{selectedFilter
|
||||
{selectedFilter && selectedFilterOperand
|
||||
? isOptionUnfolded
|
||||
? renderSelectOptionItems
|
||||
: renderFilterDropdown(selectedFilter)
|
||||
: renderFilterDropdown(selectedFilter, selectedFilterOperand)
|
||||
: renderSelectFilterITems}
|
||||
</DropdownButton>
|
||||
);
|
||||
|
||||
@ -100,6 +100,10 @@ const availableFilters = [
|
||||
displayValue: data.firstname + ' ' + data.lastname,
|
||||
value: data.firstname,
|
||||
}),
|
||||
operands: [
|
||||
{ label: 'Equal', id: 'equal', keyWord: 'equal' },
|
||||
{ label: 'Not equal', id: 'not-equal', keyWord: 'not_equal' },
|
||||
],
|
||||
},
|
||||
] satisfies FilterType<People_Bool_Exp>[];
|
||||
|
||||
|
||||
@ -56,6 +56,7 @@ export const RegularSortAndFilterBar = ({ removeFunction }: OwnProps) => {
|
||||
displayValue: 'John Doe',
|
||||
value: data.firstname,
|
||||
}),
|
||||
operands: [],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
@ -28,16 +28,16 @@ it('Checks the default top option is Include', async () => {
|
||||
value: 'Alexandre Prot',
|
||||
label: 'People',
|
||||
operand: {
|
||||
id: 'include',
|
||||
keyWord: 'ilike',
|
||||
label: 'Include',
|
||||
id: 'equal',
|
||||
keyWord: 'equal',
|
||||
label: 'Equal',
|
||||
},
|
||||
icon: <FaUsers />,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('Checks the selection of top option for Doesnot include', async () => {
|
||||
it('Checks the selection of top option for Not Equal', async () => {
|
||||
const setFilters = jest.fn();
|
||||
const { getByText } = render(
|
||||
<RegularFilterDropdownButton setFilter={setFilters} />,
|
||||
@ -49,10 +49,10 @@ it('Checks the selection of top option for Doesnot include', async () => {
|
||||
const filterByPeople = getByText('People');
|
||||
fireEvent.click(filterByPeople);
|
||||
|
||||
const openOperandOptions = getByText('Include');
|
||||
const openOperandOptions = getByText('Equal');
|
||||
fireEvent.click(openOperandOptions);
|
||||
|
||||
const selectOperand = getByText("Doesn't include");
|
||||
const selectOperand = getByText('Not equal');
|
||||
fireEvent.click(selectOperand);
|
||||
|
||||
await waitFor(() => {
|
||||
@ -69,9 +69,9 @@ it('Checks the selection of top option for Doesnot include', async () => {
|
||||
value: 'Alexandre Prot',
|
||||
label: 'People',
|
||||
operand: {
|
||||
id: 'not-include',
|
||||
keyWord: 'not_ilike',
|
||||
label: "Doesn't include",
|
||||
id: 'not-equal',
|
||||
keyWord: 'not_equal',
|
||||
label: 'Not equal',
|
||||
},
|
||||
icon: <FaUsers />,
|
||||
}),
|
||||
@ -122,9 +122,9 @@ it('Calls the filters when typing a new name', async () => {
|
||||
value: 'Jane Doe',
|
||||
label: 'People',
|
||||
operand: {
|
||||
id: 'include',
|
||||
keyWord: 'ilike',
|
||||
label: 'Include',
|
||||
id: 'equal',
|
||||
keyWord: 'equal',
|
||||
label: 'Equal',
|
||||
},
|
||||
icon: <FaUsers />,
|
||||
}),
|
||||
|
||||
@ -16,22 +16,29 @@ export type SelectedSortType<SortField = string> = SortType<SortField> & {
|
||||
order: 'asc' | 'desc';
|
||||
};
|
||||
|
||||
export type FilterType<WhereTemplate, T = Record<string, string>> = {
|
||||
export type FilterType<WhereTemplate, FilterValue = Record<string, any>> = {
|
||||
operands: FilterOperandType[];
|
||||
label: string;
|
||||
key: string;
|
||||
icon: ReactNode;
|
||||
whereTemplate: (operand: FilterOperandType, value: T) => WhereTemplate;
|
||||
whereTemplate: (
|
||||
operand: FilterOperandType,
|
||||
value: FilterValue,
|
||||
) => WhereTemplate;
|
||||
searchQuery: DocumentNode;
|
||||
searchTemplate: (
|
||||
searchInput: string,
|
||||
) => People_Bool_Exp | Companies_Bool_Exp | Users_Bool_Exp;
|
||||
searchResultMapper: (data: any) => { displayValue: string; value: T };
|
||||
searchResultMapper: (data: any) => {
|
||||
displayValue: string;
|
||||
value: FilterValue;
|
||||
};
|
||||
};
|
||||
|
||||
export type FilterOperandType = {
|
||||
label: string;
|
||||
id: string;
|
||||
keyWord: 'ilike' | 'not_ilike';
|
||||
keyWord: 'ilike' | 'not_ilike' | 'equal' | 'not_equal';
|
||||
};
|
||||
|
||||
export type SelectedFilterType<WhereTemplate> = FilterType<WhereTemplate> & {
|
||||
|
||||
Reference in New Issue
Block a user