Fix infinite loop on new table (#15111)

https://github.com/user-attachments/assets/7002cd6c-08d9-4ad7-833f-21bc23d5eea2
This commit is contained in:
Charles Bochet
2025-10-16 10:30:17 +02:00
committed by GitHub
parent 20fdb66bd3
commit 5586728105
2 changed files with 49 additions and 35 deletions
@@ -1,12 +1,10 @@
import { useSetRecoilState } from 'recoil';
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { getRecordsFromRecordConnection } from '@/object-record/cache/utils/getRecordsFromRecordConnection';
import { type RecordGqlOperationFindManyResult } from '@/object-record/graphql/types/RecordGqlOperationFindManyResult';
import { cursorFamilyState } from '@/object-record/states/cursorFamilyState';
import { hasNextPageFamilyState } from '@/object-record/states/hasNextPageFamilyState';
import { type OnFindManyRecordsCompleted } from '@/object-record/types/OnFindManyRecordsCompleted';
import { useCallback } from 'react';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
export const useHandleFindManyRecordsCompleted = <T>({
@@ -18,35 +16,29 @@ export const useHandleFindManyRecordsCompleted = <T>({
objectMetadataItem: ObjectMetadataItem;
onCompleted?: OnFindManyRecordsCompleted<T>;
}) => {
const setLastCursor = useSetRecoilState(cursorFamilyState(queryIdentifier));
const handleFindManyRecordsCompleted = useRecoilCallback(
({ set }) =>
(data: RecordGqlOperationFindManyResult) => {
const pageInfo = data?.[objectMetadataItem.namePlural]?.pageInfo;
const setHasNextPage = useSetRecoilState(
hasNextPageFamilyState(queryIdentifier),
);
const records = getRecordsFromRecordConnection({
recordConnection: data?.[objectMetadataItem.namePlural],
}) as T[];
const handleFindManyRecordsCompleted = useCallback(
(data: RecordGqlOperationFindManyResult) => {
if (!isDefined(data)) {
onCompleted?.([]);
}
onCompleted?.(records, {
pageInfo,
totalCount: data?.[objectMetadataItem.namePlural]?.totalCount,
});
const pageInfo = data?.[objectMetadataItem.namePlural]?.pageInfo;
const records = getRecordsFromRecordConnection({
recordConnection: data?.[objectMetadataItem.namePlural],
}) as T[];
onCompleted?.(records, {
pageInfo,
totalCount: data?.[objectMetadataItem.namePlural]?.totalCount,
});
if (isDefined(data?.[objectMetadataItem.namePlural])) {
setLastCursor(pageInfo.endCursor ?? '');
setHasNextPage(pageInfo.hasNextPage ?? false);
}
},
[onCompleted, objectMetadataItem.namePlural, setLastCursor, setHasNextPage],
if (isDefined(data?.[objectMetadataItem.namePlural])) {
set(cursorFamilyState(queryIdentifier), pageInfo.endCursor ?? '');
set(
hasNextPageFamilyState(queryIdentifier),
pageInfo.hasNextPage ?? false,
);
}
},
[objectMetadataItem.namePlural, onCompleted, queryIdentifier],
);
return {
@@ -7,7 +7,6 @@ import { getRecordsFromRecordConnection } from '@/object-record/cache/utils/getR
import { type RecordGqlOperationFindManyResult } from '@/object-record/graphql/types/RecordGqlOperationFindManyResult';
import { type UseFindManyRecordsParams } from '@/object-record/hooks/useFindManyRecords';
import { useFindManyRecordsQuery } from '@/object-record/hooks/useFindManyRecordsQuery';
import { useHandleFindManyRecordsCompleted } from '@/object-record/hooks/useHandleFindManyRecordsCompleted';
import { useHandleFindManyRecordsError } from '@/object-record/hooks/useHandleFindManyRecordsError';
import { useLazyFetchMoreRecordsWithPagination } from '@/object-record/hooks/useLazyFetchMoreRecordsWithPagination';
import { useObjectPermissionsForObject } from '@/object-record/hooks/useObjectPermissionsForObject';
@@ -16,6 +15,7 @@ import { hasNextPageFamilyState } from '@/object-record/states/hasNextPageFamily
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { getQueryIdentifier } from '@/object-record/utils/getQueryIdentifier';
import { QUERY_DEFAULT_LIMIT_RECORDS } from 'twenty-shared/constants';
import { isDefined } from 'twenty-shared/utils';
type UseLazyFindManyRecordsParams<T> = Omit<
UseFindManyRecordsParams<T>,
@@ -52,17 +52,39 @@ export const useLazyFindManyRecords = <T extends ObjectRecord = ObjectRecord>({
limit,
});
const { handleFindManyRecordsCompleted } = useHandleFindManyRecordsCompleted({
objectMetadataItem,
queryIdentifier,
});
const objectPermissions = useObjectPermissionsForObject(
objectMetadataItem.id,
);
const hasReadPermission = objectPermissions.canReadObjectRecords;
const handleFindManyRecordsCompleted = useRecoilCallback(
({ set, snapshot }) =>
(data: RecordGqlOperationFindManyResult) => {
const pageInfo = data?.[objectMetadataItem.namePlural]?.pageInfo;
const existingCursor = snapshot
.getLoadable(cursorFamilyState(queryIdentifier))
.getValue();
const existingHasNextPage = snapshot
.getLoadable(hasNextPageFamilyState(queryIdentifier))
.getValue();
if (isDefined(data?.[objectMetadataItem.namePlural])) {
if (existingCursor !== pageInfo.endCursor) {
set(cursorFamilyState(queryIdentifier), pageInfo.endCursor ?? '');
}
if (existingHasNextPage !== pageInfo.hasNextPage) {
set(
hasNextPageFamilyState(queryIdentifier),
pageInfo.hasNextPage ?? false,
);
}
}
},
[objectMetadataItem.namePlural, queryIdentifier],
);
const [findManyRecords, { data, error, fetchMore }] =
useLazyQuery<RecordGqlOperationFindManyResult>(findManyRecordsQuery, {
variables: {