Add Filters on Table views (#95)
* Add filter search logic WIP Filter search Implement filters test: fix sorts tests test: fix filter test feature: search person and display firstname in results feature: fix test for filter component test: mock search filters refactor: create a useSearch hook refactor: move debounce in useSearch and reset status of filter selection feature: debounce set filters refactor: remove useless setSorts feature: add where variable to people query feature: strongly type Filters feature: update WhereTemplate method feature: implement filtering on full name feature: type the useSearch hook feature: use where reducer refactor: create a type for readability feature: use query and mapper from filters feature: implement filter by company feature: search filter results on filter select feature: add loading and results to search results in filters refactor: move render search results in a function feature: display a LOADING when it loads feature: split search input and search filter for different debounce refactor: remove some warnings refactor: remove some warnings * Write test 1 * Write test 2 * test: useSearch is tested * test: update names of default people data * test: add a filter search * Test 3 * Fix tests --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
105
front/src/services/search/search.ts
Normal file
105
front/src/services/search/search.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { People_Bool_Exp } from '../../generated/graphql';
|
||||
import {} from '../../interfaces/company.interface';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { FilterType } from '../../components/table/table-header/interface';
|
||||
|
||||
export const SEARCH_PEOPLE_QUERY = gql`
|
||||
query SearchQuery($where: people_bool_exp, $limit: Int) {
|
||||
searchResults: people(where: $where, limit: $limit) {
|
||||
id
|
||||
phone
|
||||
email
|
||||
city
|
||||
firstname
|
||||
lastname
|
||||
created_at
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const EMPTY_QUERY = gql`
|
||||
query EmptyQuery {
|
||||
_
|
||||
}
|
||||
`;
|
||||
|
||||
export const SEARCH_COMPANY_QUERY = gql`
|
||||
query SearchQuery($where: companies_bool_exp, $limit: Int) {
|
||||
searchResults: companies(where: $where, limit: $limit) {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const debounce = <FuncArgs extends any[]>(
|
||||
func: (...args: FuncArgs) => void,
|
||||
delay: number,
|
||||
) => {
|
||||
let timeoutId: ReturnType<typeof setTimeout>;
|
||||
return (...args: FuncArgs) => {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => {
|
||||
func(...args);
|
||||
}, delay);
|
||||
};
|
||||
};
|
||||
|
||||
export const useSearch = (): [
|
||||
{ results: { displayValue: string; value: any }[]; loading: boolean },
|
||||
React.Dispatch<React.SetStateAction<string>>,
|
||||
React.Dispatch<React.SetStateAction<FilterType<People_Bool_Exp> | null>>,
|
||||
] => {
|
||||
const [filter, setFilter] = useState<FilterType<People_Bool_Exp> | null>(
|
||||
null,
|
||||
);
|
||||
const [searchInput, setSearchInput] = useState<string>('');
|
||||
|
||||
const debouncedsetSearchInput = useMemo(
|
||||
() => debounce(setSearchInput, 500),
|
||||
[],
|
||||
);
|
||||
|
||||
const where = useMemo(() => {
|
||||
return (
|
||||
filter && filter.searchTemplate && filter.searchTemplate(searchInput)
|
||||
);
|
||||
}, [filter, searchInput]);
|
||||
|
||||
const searchFilterQueryResults = useQuery(
|
||||
filter?.searchQuery || EMPTY_QUERY,
|
||||
{
|
||||
variables: {
|
||||
where,
|
||||
},
|
||||
skip: !filter,
|
||||
},
|
||||
);
|
||||
|
||||
const searchFilterResults = useMemo<{
|
||||
results: { displayValue: string; value: any }[];
|
||||
loading: boolean;
|
||||
}>(() => {
|
||||
if (filter == null) {
|
||||
return {
|
||||
loading: false,
|
||||
results: [],
|
||||
};
|
||||
}
|
||||
if (searchFilterQueryResults.loading) {
|
||||
return {
|
||||
loading: true,
|
||||
results: [],
|
||||
};
|
||||
}
|
||||
return {
|
||||
loading: false,
|
||||
results: searchFilterQueryResults.data.searchResults.map(
|
||||
filter.searchResultMapper,
|
||||
),
|
||||
};
|
||||
}, [filter, searchFilterQueryResults]);
|
||||
|
||||
return [searchFilterResults, debouncedsetSearchInput, setFilter];
|
||||
};
|
||||
Reference in New Issue
Block a user