Record Page Navigation Arrows Cause Unnecessary skeleton loading (#6367)
@Bonapara Issue #6325 - Desired Behavior The navigation should always be visible. Clicking on a Next/Previous arrow should immediately increment the number without switching to the skeleton loading step. **Done** Please let me know what do you think about this approach. Thanks :) https://github.com/user-attachments/assets/bda3608f-87e3-45bd-a7c8-4a6b48391cf2 Co-authored-by: Weiko <corentin@twenty.com> Co-authored-by: martmull <martmull@hotmail.fr>
This commit is contained in:
@ -11,6 +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 { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
|
|
||||||
export const useRecordShowPagePagination = (
|
export const useRecordShowPagePagination = (
|
||||||
@ -99,7 +100,15 @@ export const useRecordShowPagePagination = (
|
|||||||
recordGqlFields,
|
recordGqlFields,
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalCount = Math.max(totalCountBefore ?? 0, totalCountAfter ?? 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 || loadingRecordBefore || loadingCursor;
|
const loading = loadingRecordAfter || loadingRecordBefore || loadingCursor;
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { ComponentProps, ReactNode } from 'react';
|
|
||||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { ComponentProps, ReactNode } from 'react';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import {
|
import {
|
||||||
IconChevronDown,
|
IconChevronDown,
|
||||||
@ -77,19 +76,6 @@ const StyledTopBarButtonContainer = styled.div`
|
|||||||
margin-right: ${({ theme }) => theme.spacing(1)};
|
margin-right: ${({ theme }) => theme.spacing(1)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledSkeletonLoader = () => {
|
|
||||||
const theme = useTheme();
|
|
||||||
return (
|
|
||||||
<SkeletonTheme
|
|
||||||
baseColor={theme.background.quaternary}
|
|
||||||
highlightColor={theme.background.transparent.light}
|
|
||||||
borderRadius={50}
|
|
||||||
>
|
|
||||||
<Skeleton height={24} width={108} />
|
|
||||||
</SkeletonTheme>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
type PageHeaderProps = ComponentProps<'div'> & {
|
type PageHeaderProps = ComponentProps<'div'> & {
|
||||||
title: string;
|
title: string;
|
||||||
hasClosePageButton?: boolean;
|
hasClosePageButton?: boolean;
|
||||||
@ -101,7 +87,6 @@ type PageHeaderProps = ComponentProps<'div'> & {
|
|||||||
navigateToNextRecord?: () => void;
|
navigateToNextRecord?: () => void;
|
||||||
Icon: IconComponent;
|
Icon: IconComponent;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
loading?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PageHeader = ({
|
export const PageHeader = ({
|
||||||
@ -115,7 +100,6 @@ export const PageHeader = ({
|
|||||||
navigateToNextRecord,
|
navigateToNextRecord,
|
||||||
Icon,
|
Icon,
|
||||||
children,
|
children,
|
||||||
loading,
|
|
||||||
}: PageHeaderProps) => {
|
}: PageHeaderProps) => {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@ -137,34 +121,31 @@ export const PageHeader = ({
|
|||||||
onClick={() => onClosePage?.()}
|
onClick={() => onClosePage?.()}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{loading ? (
|
|
||||||
<StyledSkeletonLoader />
|
<StyledTopBarIconStyledTitleContainer>
|
||||||
) : (
|
{hasPaginationButtons && (
|
||||||
<StyledTopBarIconStyledTitleContainer>
|
<>
|
||||||
{hasPaginationButtons && (
|
<IconButton
|
||||||
<>
|
Icon={IconChevronUp}
|
||||||
<IconButton
|
size="small"
|
||||||
Icon={IconChevronUp}
|
variant="secondary"
|
||||||
size="small"
|
disabled={!hasPreviousRecord}
|
||||||
variant="secondary"
|
onClick={() => navigateToPreviousRecord?.()}
|
||||||
disabled={!hasPreviousRecord}
|
/>
|
||||||
onClick={() => navigateToPreviousRecord?.()}
|
<IconButton
|
||||||
/>
|
Icon={IconChevronDown}
|
||||||
<IconButton
|
size="small"
|
||||||
Icon={IconChevronDown}
|
variant="secondary"
|
||||||
size="small"
|
disabled={!hasNextRecord}
|
||||||
variant="secondary"
|
onClick={() => navigateToNextRecord?.()}
|
||||||
disabled={!hasNextRecord}
|
/>
|
||||||
onClick={() => navigateToNextRecord?.()}
|
</>
|
||||||
/>
|
)}
|
||||||
</>
|
{Icon && <Icon size={theme.icon.size.md} />}
|
||||||
)}
|
<StyledTitleContainer data-testid="top-bar-title">
|
||||||
{Icon && <Icon size={theme.icon.size.md} />}
|
<OverflowingTextWithTooltip text={title} />
|
||||||
<StyledTitleContainer data-testid="top-bar-title">
|
</StyledTitleContainer>
|
||||||
<OverflowingTextWithTooltip text={title} />
|
</StyledTopBarIconStyledTitleContainer>
|
||||||
</StyledTitleContainer>
|
|
||||||
</StyledTopBarIconStyledTitleContainer>
|
|
||||||
)}
|
|
||||||
</StyledLeftContainer>
|
</StyledLeftContainer>
|
||||||
<StyledPageActionContainer>{children}</StyledPageActionContainer>
|
<StyledPageActionContainer>{children}</StyledPageActionContainer>
|
||||||
</StyledTopBarContainer>
|
</StyledTopBarContainer>
|
||||||
|
|||||||
@ -43,7 +43,6 @@ export const RecordShowPage = () => {
|
|||||||
navigateToPreviousRecord,
|
navigateToPreviousRecord,
|
||||||
navigateToNextRecord,
|
navigateToNextRecord,
|
||||||
navigateToIndexView,
|
navigateToIndexView,
|
||||||
isLoadingPagination,
|
|
||||||
} = useRecordShowPagePagination(
|
} = useRecordShowPagePagination(
|
||||||
parameters.objectNameSingular ?? '',
|
parameters.objectNameSingular ?? '',
|
||||||
parameters.objectRecordId ?? '',
|
parameters.objectRecordId ?? '',
|
||||||
@ -64,7 +63,6 @@ export const RecordShowPage = () => {
|
|||||||
hasNextRecord={hasNextRecord}
|
hasNextRecord={hasNextRecord}
|
||||||
navigateToNextRecord={navigateToNextRecord}
|
navigateToNextRecord={navigateToNextRecord}
|
||||||
Icon={headerIcon}
|
Icon={headerIcon}
|
||||||
loading={loading || isLoadingPagination}
|
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<PageFavoriteButton
|
<PageFavoriteButton
|
||||||
|
|||||||
Reference in New Issue
Block a user