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 { buildIndexTablePageURL } from '@/object-record/record-table/utils/buildIndexTableURL';
import { useQueryVariablesFromActiveFieldsOfViewOrDefaultView } from '@/views/hooks/useQueryVariablesFromActiveFieldsOfViewOrDefaultView'; import { useQueryVariablesFromActiveFieldsOfViewOrDefaultView } from '@/views/hooks/useQueryVariablesFromActiveFieldsOfViewOrDefaultView';
import { isNonEmptyString } from '@sniptt/guards'; import { isNonEmptyString } from '@sniptt/guards';
import { useEffect, useState } from 'react'; import { useState } from 'react';
import { capitalize } from '~/utils/string/capitalize'; import { capitalize } from '~/utils/string/capitalize';
export const useRecordShowPagePagination = ( export const useRecordShowPagePagination = (
@ -60,55 +60,47 @@ export const useRecordShowPagePagination = (
const cursorFromRequest = currentRecordsPageInfo?.endCursor; const cursorFromRequest = currentRecordsPageInfo?.endCursor;
const { const [totalCount, setTotalCount] = useState<number>(0);
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 { const { loading: loadingRecordBefore, records: recordsBefore } =
loading: loadingRecordAfter, useFindManyRecords({
records: recordsAfter, skip: loadingCursor,
totalCount: totalCountAfter, fetchPolicy: 'network-only',
} = useFindManyRecords({ filter,
skip: loadingCursor, orderBy,
filter, cursorFilter: isNonEmptyString(cursorFromRequest)
fetchPolicy: 'network-only', ? {
orderBy, cursorDirection: 'before',
cursorFilter: cursorFromRequest cursor: cursorFromRequest,
? { limit: 1,
cursorDirection: 'after', }
cursor: cursorFromRequest, : undefined,
limit: 1, objectNameSingular,
} recordGqlFields,
: undefined, onCompleted: (_, pagination) => {
objectNameSingular, setTotalCount(pagination?.totalCount ?? 0);
recordGqlFields, },
}); });
const [totalCount, setTotalCount] = useState( const { loading: loadingRecordAfter, records: recordsAfter } =
Math.max(totalCountBefore ?? 0, totalCountAfter ?? 0), useFindManyRecords({
); skip: loadingCursor,
filter,
useEffect(() => { fetchPolicy: 'network-only',
if (totalCountBefore !== undefined || totalCountAfter !== undefined) { orderBy,
setTotalCount(Math.max(totalCountBefore ?? 0, totalCountAfter ?? 0)); cursorFilter: cursorFromRequest
} ? {
}, [totalCountBefore, totalCountAfter]); cursorDirection: 'after',
cursor: cursorFromRequest,
limit: 1,
}
: undefined,
objectNameSingular,
recordGqlFields,
onCompleted: (_, pagination) => {
setTotalCount(pagination?.totalCount ?? 0);
},
});
const loading = loadingRecordAfter || loadingRecordBefore || loadingCursor; 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 { TimelineActivityContext } from '@/activities/timelineActivities/contexts/TimelineActivityContext';
import { RecordShowContainer } from '@/object-record/record-show/components/RecordShowContainer'; import { RecordShowContainer } from '@/object-record/record-show/components/RecordShowContainer';
import { useRecordShowPage } from '@/object-record/record-show/hooks/useRecordShowPage'; 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 { RecordValueSetterEffect } from '@/object-record/record-store/components/RecordValueSetterEffect';
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
import { PageBody } from '@/ui/layout/page/PageBody'; import { PageBody } from '@/ui/layout/page/PageBody';
import { PageContainer } from '@/ui/layout/page/PageContainer'; import { PageContainer } from '@/ui/layout/page/PageContainer';
import { PageFavoriteButton } from '@/ui/layout/page/PageFavoriteButton'; import { PageFavoriteButton } from '@/ui/layout/page/PageFavoriteButton';
import { PageHeader } from '@/ui/layout/page/PageHeader';
import { ShowPageAddButton } from '@/ui/layout/show-page/components/ShowPageAddButton'; import { ShowPageAddButton } from '@/ui/layout/show-page/components/ShowPageAddButton';
import { ShowPageMoreButton } from '@/ui/layout/show-page/components/ShowPageMoreButton'; import { ShowPageMoreButton } from '@/ui/layout/show-page/components/ShowPageMoreButton';
import { PageTitle } from '@/ui/utilities/page-title/PageTitle'; import { PageTitle } from '@/ui/utilities/page-title/PageTitle';
import { RecordShowPageHeader } from '~/pages/object-record/RecordShowPageHeader';
export const RecordShowPage = () => { export const RecordShowPage = () => {
const parameters = useParams<{ const parameters = useParams<{
@ -36,33 +35,15 @@ export const RecordShowPage = () => {
parameters.objectRecordId ?? '', parameters.objectRecordId ?? '',
); );
const {
viewName,
hasPreviousRecord,
hasNextRecord,
navigateToPreviousRecord,
navigateToNextRecord,
navigateToIndexView,
} = useRecordShowPagePagination(
parameters.objectNameSingular ?? '',
parameters.objectRecordId ?? '',
);
return ( return (
<RecordFieldValueSelectorContextProvider> <RecordFieldValueSelectorContextProvider>
<RecordValueSetterEffect recordId={objectRecordId} /> <RecordValueSetterEffect recordId={objectRecordId} />
<PageContainer> <PageContainer>
<PageTitle title={pageTitle} /> <PageTitle title={pageTitle} />
<PageHeader <RecordShowPageHeader
title={viewName} objectNameSingular={objectNameSingular}
hasPaginationButtons objectRecordId={objectRecordId}
hasClosePageButton headerIcon={headerIcon}
onClosePage={navigateToIndexView}
hasPreviousRecord={hasPreviousRecord}
navigateToPreviousRecord={navigateToPreviousRecord}
hasNextRecord={hasNextRecord}
navigateToNextRecord={navigateToNextRecord}
Icon={headerIcon}
> >
<> <>
<PageFavoriteButton <PageFavoriteButton
@ -82,7 +63,7 @@ export const RecordShowPage = () => {
objectNameSingular={objectNameSingular} objectNameSingular={objectNameSingular}
/> />
</> </>
</PageHeader> </RecordShowPageHeader>
<PageBody> <PageBody>
<TimelineActivityContext.Provider <TimelineActivityContext.Provider
value={{ 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>
);
};