9018 fix batch delete (#9149)

Closes #9018
This commit is contained in:
Raphaël Bosi
2024-12-20 10:46:24 +01:00
committed by GitHub
parent a0b5720831
commit 925294675c
22 changed files with 413 additions and 50 deletions

View File

@ -1,6 +1,7 @@
import { useApolloClient } from '@apollo/client';
import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect';
import { triggerUpdateRecordOptimisticEffectByBatch } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffectByBatch';
import { apiConfigState } from '@/client-config/states/apiConfigState';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
@ -8,6 +9,7 @@ import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordF
import { getRecordNodeFromRecord } from '@/object-record/cache/utils/getRecordNodeFromRecord';
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
import { DEFAULT_MUTATION_BATCH_SIZE } from '@/object-record/constants/DefaultMutationBatchSize';
import { RecordGqlNode } from '@/object-record/graphql/types/RecordGqlNode';
import { useDeleteManyRecordsMutation } from '@/object-record/hooks/useDeleteManyRecordsMutation';
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
@ -80,6 +82,9 @@ export const useDeleteManyRecords = ({
.map((idToDelete) => getRecordFromCache(idToDelete, apolloClient.cache))
.filter(isDefined);
const cachedRecordsWithConnection: RecordGqlNode[] = [];
const optimisticRecordsWithConnection: RecordGqlNode[] = [];
if (!options?.skipOptimisticEffect) {
cachedRecords.forEach((cachedRecord) => {
if (!cachedRecord || !cachedRecord.id) {
@ -112,20 +117,23 @@ export const useDeleteManyRecords = ({
return null;
}
cachedRecordsWithConnection.push(cachedRecordWithConnection);
optimisticRecordsWithConnection.push(optimisticRecordWithConnection);
updateRecordFromCache({
objectMetadataItems,
objectMetadataItem,
cache: apolloClient.cache,
record: computedOptimisticRecord,
});
});
triggerUpdateRecordOptimisticEffect({
cache: apolloClient.cache,
objectMetadataItem,
currentRecord: cachedRecordWithConnection,
updatedRecord: optimisticRecordWithConnection,
objectMetadataItems,
});
triggerUpdateRecordOptimisticEffectByBatch({
cache: apolloClient.cache,
objectMetadataItem,
currentRecords: cachedRecordsWithConnection,
updatedRecords: optimisticRecordsWithConnection,
objectMetadataItems,
});
}

View File

@ -7,6 +7,8 @@ import { GRAY_SCALE } from 'twenty-ui';
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
import { isRecordBoardFetchingRecordsByColumnFamilyState } from '@/object-record/record-board/states/isRecordBoardFetchingRecordsByColumnFamilyState';
import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
import { isRecordIndexLoadMoreLockedComponentState } from '@/object-record/record-index/states/isRecordIndexLoadMoreLockedComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentFamilyStateV2';
const StyledText = styled.div`
@ -31,11 +33,23 @@ export const RecordBoardColumnFetchMoreLoader = () => {
columnDefinition.id,
);
const isLoadMoreLocked = useRecoilComponentValueV2(
isRecordIndexLoadMoreLockedComponentState,
);
const { ref, inView } = useInView();
useEffect(() => {
if (isLoadMoreLocked) {
return;
}
setShouldFetchMore(inView);
}, [setShouldFetchMore, inView]);
}, [setShouldFetchMore, inView, isLoadMoreLocked]);
if (isLoadMoreLocked) {
return null;
}
return (
<div ref={ref}>

View File

@ -230,6 +230,7 @@ export const RecordIndexContainer = () => {
objectNamePlural={objectNamePlural}
viewBarId={recordIndexId}
/>
<RecordIndexTableContainerEffect />
</SpreadsheetImportProvider>
<RecordIndexFiltersToContextStoreEffect />
{recordIndexViewType === ViewType.Table && (
@ -255,7 +256,9 @@ export const RecordIndexContainer = () => {
<RecordIndexBoardDataLoaderEffect recordBoardId={recordIndexId} />
</StyledContainerWithPadding>
)}
{!isPageHeaderV2Enabled && <RecordIndexActionMenu />}
{!isPageHeaderV2Enabled && (
<RecordIndexActionMenu indexId={recordIndexId} />
)}
</RecordFieldValueSelectorContextProvider>
</StyledContainer>
</>

View File

@ -29,6 +29,8 @@ export const RecordIndexPageHeader = () => {
const recordIndexViewType = useRecoilValue(recordIndexViewTypeState);
const { recordIndexId } = useRecordIndexContextOrThrow();
const numberOfSelectedRecords = useRecoilComponentValueV2(
contextStoreNumberOfSelectedRecordsComponentState,
);
@ -64,7 +66,7 @@ export const RecordIndexPageHeader = () => {
{isPageHeaderV2Enabled && (
<>
<RecordIndexActionMenu />
<RecordIndexActionMenu indexId={recordIndexId} />
<PageHeaderOpenCommandMenuButton />
</>
)}

View File

@ -0,0 +1,9 @@
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const isRecordIndexLoadMoreLockedComponentState =
createComponentStateV2<boolean>({
key: 'isRecordIndexLoadMoreLockedComponentState',
componentInstanceContext: ViewComponentInstanceContext,
defaultValue: false,
});

View File

@ -4,6 +4,7 @@ import { useInView } from 'react-intersection-observer';
import { useRecoilCallback } from 'recoil';
import { GRAY_SCALE } from 'twenty-ui';
import { isRecordIndexLoadMoreLockedComponentState } from '@/object-record/record-index/states/isRecordIndexLoadMoreLockedComponentState';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { hasRecordTableFetchedAllRecordsComponentStateV2 } from '@/object-record/record-table/states/hasRecordTableFetchedAllRecordsComponentStateV2';
import { RecordTableWithWrappersScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts';
@ -22,11 +23,19 @@ const StyledText = styled.div`
export const RecordTableBodyFetchMoreLoader = () => {
const { setRecordTableLastRowVisible } = useRecordTable();
const isRecordTableLoadMoreLocked = useRecoilComponentValueV2(
isRecordIndexLoadMoreLockedComponentState,
);
const onLastRowVisible = useRecoilCallback(
() => async (inView: boolean) => {
if (isRecordTableLoadMoreLocked) {
return;
}
setRecordTableLastRowVisible(inView);
},
[setRecordTableLastRowVisible],
[setRecordTableLastRowVisible, isRecordTableLoadMoreLocked],
);
const scrollWrapperRef = useContext(
@ -37,7 +46,8 @@ export const RecordTableBodyFetchMoreLoader = () => {
hasRecordTableFetchedAllRecordsComponentStateV2,
);
const showLoadingMoreRow = !hasRecordTableFetchedAllRecordsComponents;
const showLoadingMoreRow =
!hasRecordTableFetchedAllRecordsComponents && !isRecordTableLoadMoreLocked;
const { ref: tbodyRef } = useInView({
onChange: onLastRowVisible,

View File

@ -1,5 +1,6 @@
import { useCurrentRecordGroupId } from '@/object-record/record-group/hooks/useCurrentRecordGroupId';
import { useLazyLoadRecordIndexTable } from '@/object-record/record-index/hooks/useLazyLoadRecordIndexTable';
import { isRecordIndexLoadMoreLockedComponentState } from '@/object-record/record-index/states/isRecordIndexLoadMoreLockedComponentState';
import { recordIndexHasFetchedAllRecordsByGroupComponentState } from '@/object-record/record-index/states/recordIndexHasFetchedAllRecordsByGroupComponentState';
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
@ -20,6 +21,10 @@ export const RecordTableRecordGroupSectionLoadMore = () => {
currentRecordGroupId,
);
const isLoadMoreLocked = useRecoilComponentValueV2(
isRecordIndexLoadMoreLockedComponentState,
);
const recordIds = useRecoilComponentValueV2(
recordIndexAllRecordIdsComponentSelector,
);
@ -28,7 +33,7 @@ export const RecordTableRecordGroupSectionLoadMore = () => {
fetchMoreRecords();
};
if (hasFetchedAllRecords) {
if (hasFetchedAllRecords || isLoadMoreLocked) {
return null;
}