Refactor useFilteredSearchEntityQuery to accept multiple filters (#1526)
* refactoring useFilteredSearchEntityQuery * refactor with filter addition --------- Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
This commit is contained in:
@ -39,8 +39,17 @@ export function ActivityAssigneePicker({
|
|||||||
|
|
||||||
const users = useFilteredSearchEntityQuery({
|
const users = useFilteredSearchEntityQuery({
|
||||||
queryHook: useSearchUserQuery,
|
queryHook: useSearchUserQuery,
|
||||||
selectedIds: activity?.accountOwner?.id ? [activity?.accountOwner?.id] : [],
|
filters: [
|
||||||
searchFilter: relationPickerSearchFilter,
|
{
|
||||||
|
fieldName: 'firstName',
|
||||||
|
filter: relationPickerSearchFilter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'lastName',
|
||||||
|
filter: relationPickerSearchFilter,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orderByField: 'firstName',
|
||||||
mappingFunction: (user) => ({
|
mappingFunction: (user) => ({
|
||||||
entityType: Entity.User,
|
entityType: Entity.User,
|
||||||
id: user.id,
|
id: user.id,
|
||||||
@ -50,8 +59,7 @@ export function ActivityAssigneePicker({
|
|||||||
avatarType: 'rounded',
|
avatarType: 'rounded',
|
||||||
avatarUrl: user.avatarUrl ?? '',
|
avatarUrl: user.avatarUrl ?? '',
|
||||||
}),
|
}),
|
||||||
orderByField: 'firstName',
|
selectedIds: activity?.accountOwner?.id ? [activity?.accountOwner?.id] : [],
|
||||||
searchOnFields: ['firstName', 'lastName'],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
|
|||||||
@ -14,9 +14,13 @@ export function useFilteredSearchCompanyQuery({
|
|||||||
}) {
|
}) {
|
||||||
return useFilteredSearchEntityQuery({
|
return useFilteredSearchEntityQuery({
|
||||||
queryHook: useSearchCompanyQuery,
|
queryHook: useSearchCompanyQuery,
|
||||||
searchOnFields: ['name'],
|
filters: [
|
||||||
|
{
|
||||||
|
fieldName: 'name',
|
||||||
|
filter: searchFilter,
|
||||||
|
},
|
||||||
|
],
|
||||||
orderByField: 'name',
|
orderByField: 'name',
|
||||||
selectedIds: selectedIds,
|
|
||||||
mappingFunction: (company) => ({
|
mappingFunction: (company) => ({
|
||||||
id: company.id,
|
id: company.id,
|
||||||
entityType: ActivityTargetableEntityType.Company,
|
entityType: ActivityTargetableEntityType.Company,
|
||||||
@ -25,7 +29,7 @@ export function useFilteredSearchCompanyQuery({
|
|||||||
domainName: company.domainName,
|
domainName: company.domainName,
|
||||||
avatarType: 'squared',
|
avatarType: 'squared',
|
||||||
}),
|
}),
|
||||||
searchFilter,
|
selectedIds: selectedIds,
|
||||||
limit,
|
limit,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,8 +34,16 @@ export function PeoplePicker({
|
|||||||
const people = useFilteredSearchEntityQuery({
|
const people = useFilteredSearchEntityQuery({
|
||||||
queryHook: useSearchPeopleQuery,
|
queryHook: useSearchPeopleQuery,
|
||||||
selectedIds: [personId ?? ''],
|
selectedIds: [personId ?? ''],
|
||||||
searchFilter: relationPickerSearchFilter,
|
filters: [
|
||||||
filterByFields: [{ companyId: companyId ?? '' }],
|
{
|
||||||
|
fieldName: 'firstName',
|
||||||
|
filter: relationPickerSearchFilter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'lastName',
|
||||||
|
filter: relationPickerSearchFilter,
|
||||||
|
},
|
||||||
|
],
|
||||||
mappingFunction: (person) => ({
|
mappingFunction: (person) => ({
|
||||||
entityType: Entity.Person,
|
entityType: Entity.Person,
|
||||||
id: person.id,
|
id: person.id,
|
||||||
@ -44,8 +52,7 @@ export function PeoplePicker({
|
|||||||
avatarUrl: person.avatarUrl ?? '',
|
avatarUrl: person.avatarUrl ?? '',
|
||||||
}),
|
}),
|
||||||
orderByField: 'firstName',
|
orderByField: 'firstName',
|
||||||
searchOnFields: ['firstName', 'lastName'],
|
excludeEntityIds: excludePersonIds,
|
||||||
excludePersonIds,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function handleEntitySelected(
|
async function handleEntitySelected(
|
||||||
|
|||||||
@ -14,7 +14,16 @@ export function useFilteredSearchPeopleQuery({
|
|||||||
}) {
|
}) {
|
||||||
return useFilteredSearchEntityQuery({
|
return useFilteredSearchEntityQuery({
|
||||||
queryHook: useSearchPeopleQuery,
|
queryHook: useSearchPeopleQuery,
|
||||||
searchOnFields: ['firstName', 'lastName'],
|
filters: [
|
||||||
|
{
|
||||||
|
fieldName: 'firstName',
|
||||||
|
filter: searchFilter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'lastName',
|
||||||
|
filter: searchFilter,
|
||||||
|
},
|
||||||
|
],
|
||||||
orderByField: 'lastName',
|
orderByField: 'lastName',
|
||||||
selectedIds: selectedIds,
|
selectedIds: selectedIds,
|
||||||
mappingFunction: (entity) =>
|
mappingFunction: (entity) =>
|
||||||
@ -25,7 +34,6 @@ export function useFilteredSearchPeopleQuery({
|
|||||||
avatarUrl: entity.avatarUrl,
|
avatarUrl: entity.avatarUrl,
|
||||||
avatarType: 'rounded',
|
avatarType: 'rounded',
|
||||||
} as ActivityTargetableEntityForSelect),
|
} as ActivityTargetableEntityForSelect),
|
||||||
searchFilter,
|
|
||||||
limit,
|
limit,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import * as Apollo from '@apollo/client';
|
import { QueryHookOptions, QueryResult } from '@apollo/client';
|
||||||
|
|
||||||
import { EntitiesForMultipleEntitySelect } from '@/ui/input/relation-picker/components/MultipleEntitySelect';
|
import { EntitiesForMultipleEntitySelect } from '@/ui/input/relation-picker/components/MultipleEntitySelect';
|
||||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||||
@ -26,6 +26,8 @@ type ExtractEntityTypeFromQueryResponse<T> = T extends {
|
|||||||
? U
|
? U
|
||||||
: never;
|
: never;
|
||||||
|
|
||||||
|
type SearchFilter = { fieldName: string; filter: string | number };
|
||||||
|
|
||||||
const DEFAULT_SEARCH_REQUEST_LIMIT = 10;
|
const DEFAULT_SEARCH_REQUEST_LIMIT = 10;
|
||||||
|
|
||||||
// TODO: use this for all search queries, because we need selectedEntities and entitiesToSelect each time we want to search
|
// TODO: use this for all search queries, because we need selectedEntities and entitiesToSelect each time we want to search
|
||||||
@ -36,7 +38,6 @@ export function useFilteredSearchEntityQuery<
|
|||||||
},
|
},
|
||||||
EntityStringField extends SelectStringKeys<EntityType>,
|
EntityStringField extends SelectStringKeys<EntityType>,
|
||||||
OrderByField extends EntityStringField,
|
OrderByField extends EntityStringField,
|
||||||
SearchOnField extends EntityStringField,
|
|
||||||
QueryResponseForExtract,
|
QueryResponseForExtract,
|
||||||
QueryResponse extends {
|
QueryResponse extends {
|
||||||
searchResults: EntityType[];
|
searchResults: EntityType[];
|
||||||
@ -53,31 +54,24 @@ export function useFilteredSearchEntityQuery<
|
|||||||
CustomEntityForSelect extends EntityForSelect,
|
CustomEntityForSelect extends EntityForSelect,
|
||||||
>({
|
>({
|
||||||
queryHook,
|
queryHook,
|
||||||
searchOnFields,
|
|
||||||
filterByFields,
|
|
||||||
orderByField,
|
orderByField,
|
||||||
|
filters,
|
||||||
sortOrder = SortOrder.Asc,
|
sortOrder = SortOrder.Asc,
|
||||||
selectedIds,
|
selectedIds,
|
||||||
mappingFunction,
|
mappingFunction,
|
||||||
limit,
|
limit,
|
||||||
searchFilter, // TODO: put in a scoped recoil state
|
excludeEntityIds = [],
|
||||||
excludePersonIds = [],
|
|
||||||
}: {
|
}: {
|
||||||
queryHook: (
|
queryHook: (
|
||||||
queryOptions?: Apollo.QueryHookOptions<
|
queryOptions?: QueryHookOptions<QueryResponseForExtract, QueryVariables>,
|
||||||
QueryResponseForExtract,
|
) => QueryResult<QueryResponse, QueryVariables>;
|
||||||
QueryVariables
|
|
||||||
>,
|
|
||||||
) => Apollo.QueryResult<QueryResponse, QueryVariables>;
|
|
||||||
searchOnFields: SearchOnField[];
|
|
||||||
filterByFields?: Record<string, any>[];
|
|
||||||
orderByField: OrderByField;
|
orderByField: OrderByField;
|
||||||
|
filters: SearchFilter[];
|
||||||
sortOrder?: SortOrder;
|
sortOrder?: SortOrder;
|
||||||
selectedIds: string[];
|
selectedIds: string[];
|
||||||
mappingFunction: (entity: EntityType) => CustomEntityForSelect;
|
mappingFunction: (entity: EntityType) => CustomEntityForSelect;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
searchFilter: string;
|
excludeEntityIds?: string[];
|
||||||
excludePersonIds?: string[];
|
|
||||||
}): EntitiesForMultipleEntitySelect<CustomEntityForSelect> {
|
}): EntitiesForMultipleEntitySelect<CustomEntityForSelect> {
|
||||||
const { loading: selectedEntitiesLoading, data: selectedEntitiesData } =
|
const { loading: selectedEntitiesLoading, data: selectedEntitiesData } =
|
||||||
queryHook({
|
queryHook({
|
||||||
@ -93,9 +87,9 @@ export function useFilteredSearchEntityQuery<
|
|||||||
} as QueryVariables,
|
} as QueryVariables,
|
||||||
});
|
});
|
||||||
|
|
||||||
const searchFilterByField = searchOnFields.map((field) => ({
|
const searchFilterByField = filters.map(({ fieldName, filter }) => ({
|
||||||
[field]: {
|
[fieldName]: {
|
||||||
contains: `%${searchFilter}%`,
|
contains: `%${filter}%`,
|
||||||
mode: QueryMode.Insensitive,
|
mode: QueryMode.Insensitive,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
@ -150,7 +144,7 @@ export function useFilteredSearchEntityQuery<
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: {
|
id: {
|
||||||
notIn: [...selectedIds, ...excludePersonIds],
|
notIn: [...selectedIds, ...excludeEntityIds],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@ -26,11 +26,17 @@ export function FilterDropdownUserSearchSelect({
|
|||||||
|
|
||||||
const usersForSelect = useFilteredSearchEntityQuery({
|
const usersForSelect = useFilteredSearchEntityQuery({
|
||||||
queryHook: useSearchUserQuery,
|
queryHook: useSearchUserQuery,
|
||||||
searchOnFields: ['firstName', 'lastName'],
|
filters: [
|
||||||
|
{
|
||||||
|
fieldName: 'firstName',
|
||||||
|
filter: filterDropdownSearchInput,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'lastName',
|
||||||
|
filter: filterDropdownSearchInput,
|
||||||
|
},
|
||||||
|
],
|
||||||
orderByField: 'lastName',
|
orderByField: 'lastName',
|
||||||
selectedIds: filterDropdownSelectedEntityId
|
|
||||||
? [filterDropdownSelectedEntityId]
|
|
||||||
: [],
|
|
||||||
mappingFunction: (entity) => ({
|
mappingFunction: (entity) => ({
|
||||||
id: entity.id,
|
id: entity.id,
|
||||||
entityType: Entity.User,
|
entityType: Entity.User,
|
||||||
@ -38,7 +44,9 @@ export function FilterDropdownUserSearchSelect({
|
|||||||
avatarType: 'rounded',
|
avatarType: 'rounded',
|
||||||
avatarUrl: entity.avatarUrl ?? '',
|
avatarUrl: entity.avatarUrl ?? '',
|
||||||
}),
|
}),
|
||||||
searchFilter: filterDropdownSearchInput,
|
selectedIds: filterDropdownSelectedEntityId
|
||||||
|
? [filterDropdownSelectedEntityId]
|
||||||
|
: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -29,8 +29,17 @@ export function UserPicker({
|
|||||||
|
|
||||||
const users = useFilteredSearchEntityQuery({
|
const users = useFilteredSearchEntityQuery({
|
||||||
queryHook: useSearchUserQuery,
|
queryHook: useSearchUserQuery,
|
||||||
selectedIds: userId ? [userId] : [],
|
filters: [
|
||||||
searchFilter: relationPickerSearchFilter,
|
{
|
||||||
|
fieldName: 'firstName',
|
||||||
|
filter: relationPickerSearchFilter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'lastName',
|
||||||
|
filter: relationPickerSearchFilter,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orderByField: 'firstName',
|
||||||
mappingFunction: (user) => ({
|
mappingFunction: (user) => ({
|
||||||
entityType: Entity.User,
|
entityType: Entity.User,
|
||||||
id: user.id,
|
id: user.id,
|
||||||
@ -38,8 +47,7 @@ export function UserPicker({
|
|||||||
avatarType: 'rounded',
|
avatarType: 'rounded',
|
||||||
avatarUrl: user.avatarUrl ?? '',
|
avatarUrl: user.avatarUrl ?? '',
|
||||||
}),
|
}),
|
||||||
orderByField: 'firstName',
|
selectedIds: userId ? [userId] : [],
|
||||||
searchOnFields: ['firstName', 'lastName'],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function handleEntitySelected(
|
async function handleEntitySelected(
|
||||||
|
|||||||
Reference in New Issue
Block a user