diff --git a/front/src/modules/activities/components/ActivityAssigneePicker.tsx b/front/src/modules/activities/components/ActivityAssigneePicker.tsx index 8fcf436b3..c2bdc8ee0 100644 --- a/front/src/modules/activities/components/ActivityAssigneePicker.tsx +++ b/front/src/modules/activities/components/ActivityAssigneePicker.tsx @@ -39,8 +39,17 @@ export function ActivityAssigneePicker({ const users = useFilteredSearchEntityQuery({ queryHook: useSearchUserQuery, - selectedIds: activity?.accountOwner?.id ? [activity?.accountOwner?.id] : [], - searchFilter: relationPickerSearchFilter, + filters: [ + { + fieldName: 'firstName', + filter: relationPickerSearchFilter, + }, + { + fieldName: 'lastName', + filter: relationPickerSearchFilter, + }, + ], + orderByField: 'firstName', mappingFunction: (user) => ({ entityType: Entity.User, id: user.id, @@ -50,8 +59,7 @@ export function ActivityAssigneePicker({ avatarType: 'rounded', avatarUrl: user.avatarUrl ?? '', }), - orderByField: 'firstName', - searchOnFields: ['firstName', 'lastName'], + selectedIds: activity?.accountOwner?.id ? [activity?.accountOwner?.id] : [], }); const client = useApolloClient(); diff --git a/front/src/modules/companies/hooks/useFilteredSearchCompanyQuery.ts b/front/src/modules/companies/hooks/useFilteredSearchCompanyQuery.ts index fd082445c..10797d15f 100644 --- a/front/src/modules/companies/hooks/useFilteredSearchCompanyQuery.ts +++ b/front/src/modules/companies/hooks/useFilteredSearchCompanyQuery.ts @@ -14,9 +14,13 @@ export function useFilteredSearchCompanyQuery({ }) { return useFilteredSearchEntityQuery({ queryHook: useSearchCompanyQuery, - searchOnFields: ['name'], + filters: [ + { + fieldName: 'name', + filter: searchFilter, + }, + ], orderByField: 'name', - selectedIds: selectedIds, mappingFunction: (company) => ({ id: company.id, entityType: ActivityTargetableEntityType.Company, @@ -25,7 +29,7 @@ export function useFilteredSearchCompanyQuery({ domainName: company.domainName, avatarType: 'squared', }), - searchFilter, + selectedIds: selectedIds, limit, }); } diff --git a/front/src/modules/people/components/PeoplePicker.tsx b/front/src/modules/people/components/PeoplePicker.tsx index eb8778f8e..ebf199aa2 100644 --- a/front/src/modules/people/components/PeoplePicker.tsx +++ b/front/src/modules/people/components/PeoplePicker.tsx @@ -34,8 +34,16 @@ export function PeoplePicker({ const people = useFilteredSearchEntityQuery({ queryHook: useSearchPeopleQuery, selectedIds: [personId ?? ''], - searchFilter: relationPickerSearchFilter, - filterByFields: [{ companyId: companyId ?? '' }], + filters: [ + { + fieldName: 'firstName', + filter: relationPickerSearchFilter, + }, + { + fieldName: 'lastName', + filter: relationPickerSearchFilter, + }, + ], mappingFunction: (person) => ({ entityType: Entity.Person, id: person.id, @@ -44,8 +52,7 @@ export function PeoplePicker({ avatarUrl: person.avatarUrl ?? '', }), orderByField: 'firstName', - searchOnFields: ['firstName', 'lastName'], - excludePersonIds, + excludeEntityIds: excludePersonIds, }); async function handleEntitySelected( diff --git a/front/src/modules/people/hooks/useFilteredSearchPeopleQuery.ts b/front/src/modules/people/hooks/useFilteredSearchPeopleQuery.ts index 5dcf041b0..07f132a81 100644 --- a/front/src/modules/people/hooks/useFilteredSearchPeopleQuery.ts +++ b/front/src/modules/people/hooks/useFilteredSearchPeopleQuery.ts @@ -14,7 +14,16 @@ export function useFilteredSearchPeopleQuery({ }) { return useFilteredSearchEntityQuery({ queryHook: useSearchPeopleQuery, - searchOnFields: ['firstName', 'lastName'], + filters: [ + { + fieldName: 'firstName', + filter: searchFilter, + }, + { + fieldName: 'lastName', + filter: searchFilter, + }, + ], orderByField: 'lastName', selectedIds: selectedIds, mappingFunction: (entity) => @@ -25,7 +34,6 @@ export function useFilteredSearchPeopleQuery({ avatarUrl: entity.avatarUrl, avatarType: 'rounded', } as ActivityTargetableEntityForSelect), - searchFilter, limit, }); } diff --git a/front/src/modules/search/hooks/useFilteredSearchEntityQuery.ts b/front/src/modules/search/hooks/useFilteredSearchEntityQuery.ts index 0123dbee4..012e2fb55 100644 --- a/front/src/modules/search/hooks/useFilteredSearchEntityQuery.ts +++ b/front/src/modules/search/hooks/useFilteredSearchEntityQuery.ts @@ -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 { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect'; @@ -26,6 +26,8 @@ type ExtractEntityTypeFromQueryResponse = T extends { ? U : never; +type SearchFilter = { fieldName: string; filter: string | number }; + 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 @@ -36,7 +38,6 @@ export function useFilteredSearchEntityQuery< }, EntityStringField extends SelectStringKeys, OrderByField extends EntityStringField, - SearchOnField extends EntityStringField, QueryResponseForExtract, QueryResponse extends { searchResults: EntityType[]; @@ -53,31 +54,24 @@ export function useFilteredSearchEntityQuery< CustomEntityForSelect extends EntityForSelect, >({ queryHook, - searchOnFields, - filterByFields, orderByField, + filters, sortOrder = SortOrder.Asc, selectedIds, mappingFunction, limit, - searchFilter, // TODO: put in a scoped recoil state - excludePersonIds = [], + excludeEntityIds = [], }: { queryHook: ( - queryOptions?: Apollo.QueryHookOptions< - QueryResponseForExtract, - QueryVariables - >, - ) => Apollo.QueryResult; - searchOnFields: SearchOnField[]; - filterByFields?: Record[]; + queryOptions?: QueryHookOptions, + ) => QueryResult; orderByField: OrderByField; + filters: SearchFilter[]; sortOrder?: SortOrder; selectedIds: string[]; mappingFunction: (entity: EntityType) => CustomEntityForSelect; limit?: number; - searchFilter: string; - excludePersonIds?: string[]; + excludeEntityIds?: string[]; }): EntitiesForMultipleEntitySelect { const { loading: selectedEntitiesLoading, data: selectedEntitiesData } = queryHook({ @@ -93,9 +87,9 @@ export function useFilteredSearchEntityQuery< } as QueryVariables, }); - const searchFilterByField = searchOnFields.map((field) => ({ - [field]: { - contains: `%${searchFilter}%`, + const searchFilterByField = filters.map(({ fieldName, filter }) => ({ + [fieldName]: { + contains: `%${filter}%`, mode: QueryMode.Insensitive, }, })); @@ -150,7 +144,7 @@ export function useFilteredSearchEntityQuery< }, { id: { - notIn: [...selectedIds, ...excludePersonIds], + notIn: [...selectedIds, ...excludeEntityIds], }, }, ], diff --git a/front/src/modules/users/components/FilterDropdownUserSearchSelect.tsx b/front/src/modules/users/components/FilterDropdownUserSearchSelect.tsx index 23115069f..dc70f46f2 100644 --- a/front/src/modules/users/components/FilterDropdownUserSearchSelect.tsx +++ b/front/src/modules/users/components/FilterDropdownUserSearchSelect.tsx @@ -26,11 +26,17 @@ export function FilterDropdownUserSearchSelect({ const usersForSelect = useFilteredSearchEntityQuery({ queryHook: useSearchUserQuery, - searchOnFields: ['firstName', 'lastName'], + filters: [ + { + fieldName: 'firstName', + filter: filterDropdownSearchInput, + }, + { + fieldName: 'lastName', + filter: filterDropdownSearchInput, + }, + ], orderByField: 'lastName', - selectedIds: filterDropdownSelectedEntityId - ? [filterDropdownSelectedEntityId] - : [], mappingFunction: (entity) => ({ id: entity.id, entityType: Entity.User, @@ -38,7 +44,9 @@ export function FilterDropdownUserSearchSelect({ avatarType: 'rounded', avatarUrl: entity.avatarUrl ?? '', }), - searchFilter: filterDropdownSearchInput, + selectedIds: filterDropdownSelectedEntityId + ? [filterDropdownSelectedEntityId] + : [], }); return ( diff --git a/front/src/modules/users/components/UserPicker.tsx b/front/src/modules/users/components/UserPicker.tsx index 9890848ff..7fe652287 100644 --- a/front/src/modules/users/components/UserPicker.tsx +++ b/front/src/modules/users/components/UserPicker.tsx @@ -29,8 +29,17 @@ export function UserPicker({ const users = useFilteredSearchEntityQuery({ queryHook: useSearchUserQuery, - selectedIds: userId ? [userId] : [], - searchFilter: relationPickerSearchFilter, + filters: [ + { + fieldName: 'firstName', + filter: relationPickerSearchFilter, + }, + { + fieldName: 'lastName', + filter: relationPickerSearchFilter, + }, + ], + orderByField: 'firstName', mappingFunction: (user) => ({ entityType: Entity.User, id: user.id, @@ -38,8 +47,7 @@ export function UserPicker({ avatarType: 'rounded', avatarUrl: user.avatarUrl ?? '', }), - orderByField: 'firstName', - searchOnFields: ['firstName', 'lastName'], + selectedIds: userId ? [userId] : [], }); async function handleEntitySelected(