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:
@ -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;
|
||||
|
||||
|
||||
@ -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={{
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user