Use search instead of findMany in relation pickers (#7798)

First step of #https://github.com/twentyhq/twenty/issues/3298.
Here we update the search endpoint to allow for a filter argument, which
we currently use in the relation pickers to restrict or exclude ids from
search.
In a future PR we will try to simplify the search logic in the FE
This commit is contained in:
Marie
2024-10-18 14:50:04 +02:00
committed by GitHub
parent 8cadcdf577
commit 6fef125965
15 changed files with 123 additions and 125 deletions

View File

@ -80,13 +80,11 @@ describe('useFilteredSearchEntityQuery', () => {
setMetadataItems(generatedMockObjectMetadataItems);
return useFilteredSearchEntityQuery({
orderByField: 'name',
filters: [{ fieldNames: ['name'], filter: 'Entity' }],
sortOrder: 'AscNullsLast',
selectedIds: ['1'],
limit: 10,
excludeRecordIds: ['2'],
objectNameSingular: 'person',
searchFilter: 'Entity',
});
},
{ wrapper: Wrapper },

View File

@ -1,39 +1,26 @@
import { isNonEmptyString } from '@sniptt/guards';
import { useMapToObjectRecordIdentifier } from '@/object-metadata/hooks/useMapToObjectRecordIdentifier';
import { DEFAULT_SEARCH_REQUEST_LIMIT } from '@/object-record/constants/DefaultSearchRequestLimit';
import { RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { useSearchRecords } from '@/object-record/hooks/useSearchRecords';
import { EntitiesForMultipleEntitySelect } from '@/object-record/relation-picker/types/EntitiesForMultipleEntitySelect';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { makeAndFilterVariables } from '@/object-record/utils/makeAndFilterVariables';
import { makeOrFilterVariables } from '@/object-record/utils/makeOrFilterVariables';
import { OrderBy } from '@/types/OrderBy';
import { generateILikeFiltersForCompositeFields } from '~/utils/array/generateILikeFiltersForCompositeFields';
import { isDefined } from '~/utils/isDefined';
type SearchFilter = { fieldNames: string[]; filter: string | number };
// TODO: use this for all search queries, because we need selectedEntities and entitiesToSelect each time we want to search
// Filtered entities to select are
export const useFilteredSearchEntityQuery = ({
orderByField,
filters,
sortOrder = 'AscNullsLast',
selectedIds,
limit,
excludeRecordIds = [],
objectNameSingular,
searchFilter,
}: {
orderByField: string;
filters: SearchFilter[];
sortOrder?: OrderBy;
selectedIds: string[];
limit?: number;
excludeRecordIds?: string[];
objectNameSingular: string;
searchFilter?: string;
}): EntitiesForMultipleEntitySelect<EntityForSelect> => {
const { mapToObjectRecordIdentifier } = useMapToObjectRecordIdentifier({
objectNameSingular,
@ -46,55 +33,21 @@ export const useFilteredSearchEntityQuery = ({
const selectedIdsFilter = { id: { in: selectedIds } };
const { loading: selectedRecordsLoading, records: selectedRecords } =
useFindManyRecords({
useSearchRecords({
objectNameSingular,
filter: selectedIdsFilter,
orderBy: [{ [orderByField]: sortOrder }],
skip: !selectedIds.length,
searchInput: searchFilter,
});
const searchFilters = filters.map(({ fieldNames, filter }) => {
if (!isNonEmptyString(filter)) {
return undefined;
}
const formattedFilters = fieldNames.reduce(
(previousValue: RecordGqlOperationFilter[], fieldName) => {
const [parentFieldName, subFieldName] = fieldName.split('.');
if (isNonEmptyString(subFieldName)) {
// Composite field
return [
...previousValue,
...generateILikeFiltersForCompositeFields(filter, parentFieldName, [
subFieldName,
]),
];
}
return [
...previousValue,
{
[fieldName]: {
ilike: `%${filter}%`,
},
},
];
},
[],
);
return makeOrFilterVariables(formattedFilters);
});
const {
loading: filteredSelectedRecordsLoading,
records: filteredSelectedRecords,
} = useFindManyRecords({
} = useSearchRecords({
objectNameSingular,
filter: makeAndFilterVariables([...searchFilters, selectedIdsFilter]),
orderBy: [{ [orderByField]: sortOrder }],
filter: selectedIdsFilter,
skip: !selectedIds.length,
searchInput: searchFilter,
});
const notFilterIds = [...selectedIds, ...excludeRecordIds];
@ -102,11 +55,11 @@ export const useFilteredSearchEntityQuery = ({
? { not: { id: { in: notFilterIds } } }
: undefined;
const { loading: recordsToSelectLoading, records: recordsToSelect } =
useFindManyRecords({
useSearchRecords({
objectNameSingular,
filter: makeAndFilterVariables([...searchFilters, notFilter]),
filter: notFilter,
limit: limit ?? DEFAULT_SEARCH_REQUEST_LIMIT,
orderBy: [{ [orderByField]: sortOrder }],
searchInput: searchFilter,
});
return {