Improve RecordShowPage Header performances (#6440)

In this PR, I am:
- removing a useEffect (we use the onCompleted prop of useFindManyQuery
hook)
- moving this logic into a RecordShowPageHeader to avoid re-renders of
the whole tree
This commit is contained in:
Charles Bochet
2024-07-29 18:11:41 +02:00
committed by GitHub
parent 0fd3c8b264
commit d2fe31061e
3 changed files with 87 additions and 73 deletions

View File

@ -11,7 +11,7 @@ import { buildShowPageURL } from '@/object-record/record-show/utils/buildShowPag
import { buildIndexTablePageURL } from '@/object-record/record-table/utils/buildIndexTableURL';
import { useQueryVariablesFromActiveFieldsOfViewOrDefaultView } from '@/views/hooks/useQueryVariablesFromActiveFieldsOfViewOrDefaultView';
import { isNonEmptyString } from '@sniptt/guards';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { capitalize } from '~/utils/string/capitalize';
export const useRecordShowPagePagination = (
@ -60,55 +60,47 @@ export const useRecordShowPagePagination = (
const cursorFromRequest = currentRecordsPageInfo?.endCursor;
const {
loading: loadingRecordBefore,
records: recordsBefore,
totalCount: totalCountBefore,
} = useFindManyRecords({
skip: loadingCursor,
fetchPolicy: 'network-only',
filter,
orderBy,
cursorFilter: isNonEmptyString(cursorFromRequest)
? {
cursorDirection: 'before',
cursor: cursorFromRequest,
limit: 1,
}
: undefined,
objectNameSingular,
recordGqlFields,
});
const [totalCount, setTotalCount] = useState<number>(0);
const {
loading: loadingRecordAfter,
records: recordsAfter,
totalCount: totalCountAfter,
} = useFindManyRecords({
skip: loadingCursor,
filter,
fetchPolicy: 'network-only',
orderBy,
cursorFilter: cursorFromRequest
? {
cursorDirection: 'after',
cursor: cursorFromRequest,
limit: 1,
}
: undefined,
objectNameSingular,
recordGqlFields,
});
const { loading: loadingRecordBefore, records: recordsBefore } =
useFindManyRecords({
skip: loadingCursor,
fetchPolicy: 'network-only',
filter,
orderBy,
cursorFilter: isNonEmptyString(cursorFromRequest)
? {
cursorDirection: 'before',
cursor: cursorFromRequest,
limit: 1,
}
: undefined,
objectNameSingular,
recordGqlFields,
onCompleted: (_, pagination) => {
setTotalCount(pagination?.totalCount ?? 0);
},
});
const [totalCount, setTotalCount] = useState(
Math.max(totalCountBefore ?? 0, totalCountAfter ?? 0),
);
useEffect(() => {
if (totalCountBefore !== undefined || totalCountAfter !== undefined) {
setTotalCount(Math.max(totalCountBefore ?? 0, totalCountAfter ?? 0));
}
}, [totalCountBefore, totalCountAfter]);
const { loading: loadingRecordAfter, records: recordsAfter } =
useFindManyRecords({
skip: loadingCursor,
filter,
fetchPolicy: 'network-only',
orderBy,
cursorFilter: cursorFromRequest
? {
cursorDirection: 'after',
cursor: cursorFromRequest,
limit: 1,
}
: undefined,
objectNameSingular,
recordGqlFields,
onCompleted: (_, pagination) => {
setTotalCount(pagination?.totalCount ?? 0);
},
});
const loading = loadingRecordAfter || loadingRecordBefore || loadingCursor;

View File

@ -3,16 +3,15 @@ import { useParams } from 'react-router-dom';
import { TimelineActivityContext } from '@/activities/timelineActivities/contexts/TimelineActivityContext';
import { RecordShowContainer } from '@/object-record/record-show/components/RecordShowContainer';
import { useRecordShowPage } from '@/object-record/record-show/hooks/useRecordShowPage';
import { useRecordShowPagePagination } from '@/object-record/record-show/hooks/useRecordShowPagePagination';
import { RecordValueSetterEffect } from '@/object-record/record-store/components/RecordValueSetterEffect';
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
import { PageBody } from '@/ui/layout/page/PageBody';
import { PageContainer } from '@/ui/layout/page/PageContainer';
import { PageFavoriteButton } from '@/ui/layout/page/PageFavoriteButton';
import { PageHeader } from '@/ui/layout/page/PageHeader';
import { ShowPageAddButton } from '@/ui/layout/show-page/components/ShowPageAddButton';
import { ShowPageMoreButton } from '@/ui/layout/show-page/components/ShowPageMoreButton';
import { PageTitle } from '@/ui/utilities/page-title/PageTitle';
import { RecordShowPageHeader } from '~/pages/object-record/RecordShowPageHeader';
export const RecordShowPage = () => {
const parameters = useParams<{
@ -36,33 +35,15 @@ export const RecordShowPage = () => {
parameters.objectRecordId ?? '',
);
const {
viewName,
hasPreviousRecord,
hasNextRecord,
navigateToPreviousRecord,
navigateToNextRecord,
navigateToIndexView,
} = useRecordShowPagePagination(
parameters.objectNameSingular ?? '',
parameters.objectRecordId ?? '',
);
return (
<RecordFieldValueSelectorContextProvider>
<RecordValueSetterEffect recordId={objectRecordId} />
<PageContainer>
<PageTitle title={pageTitle} />
<PageHeader
title={viewName}
hasPaginationButtons
hasClosePageButton
onClosePage={navigateToIndexView}
hasPreviousRecord={hasPreviousRecord}
navigateToPreviousRecord={navigateToPreviousRecord}
hasNextRecord={hasNextRecord}
navigateToNextRecord={navigateToNextRecord}
Icon={headerIcon}
<RecordShowPageHeader
objectNameSingular={objectNameSingular}
objectRecordId={objectRecordId}
headerIcon={headerIcon}
>
<>
<PageFavoriteButton
@ -82,7 +63,7 @@ export const RecordShowPage = () => {
objectNameSingular={objectNameSingular}
/>
</>
</PageHeader>
</RecordShowPageHeader>
<PageBody>
<TimelineActivityContext.Provider
value={{

View File

@ -0,0 +1,41 @@
import { useRecordShowPage } from '@/object-record/record-show/hooks/useRecordShowPage';
import { useRecordShowPagePagination } from '@/object-record/record-show/hooks/useRecordShowPagePagination';
import { PageHeader } from '@/ui/layout/page/PageHeader';
export const RecordShowPageHeader = ({
objectNameSingular,
objectRecordId,
children,
}: {
objectNameSingular: string;
objectRecordId: string;
headerIcon: React.ComponentType;
children?: React.ReactNode;
}) => {
const {
viewName,
hasPreviousRecord,
hasNextRecord,
navigateToPreviousRecord,
navigateToNextRecord,
navigateToIndexView,
} = useRecordShowPagePagination(objectNameSingular, objectRecordId);
const { headerIcon } = useRecordShowPage(objectNameSingular, objectRecordId);
return (
<PageHeader
title={viewName}
hasPaginationButtons
hasClosePageButton
onClosePage={navigateToIndexView}
hasPreviousRecord={hasPreviousRecord}
navigateToPreviousRecord={navigateToPreviousRecord}
hasNextRecord={hasNextRecord}
navigateToNextRecord={navigateToNextRecord}
Icon={headerIcon}
>
{children}
</PageHeader>
);
};