Add Skeleton loading for side panel (#7394)
This PR was created by [GitStart](https://gitstart.com/) to address the requirements from this ticket: [TWNTY-7112](https://clients.gitstart.com/twenty/5449/tickets/TWNTY-7112). --- ### Description - To test you can use `await new Promise(r => setTimeout(r, 5000));` line 74 of \`openCreateActivityDrawer.ts\` - We added a recoil state to define the loading status - Design points to note: 1 - We did not change the chip component styles because would be unrelated to the issue can you confirm if you still need this change?  2- In Figma, the loading state shows the Chip rendering an initial name before showing the loaded name, currently, we are rendering the correct name while loading, the change that makes this possible is below  if we set it as null, the initial name would appear, but also the previous data in the state would affect the UI, passing the `activityObjectNameSingular` data allows us to clear the previous data, and make the Chip instantly updated, let us know if this behavior is fine, or if you still want an initial name to be rendered while is loading. 3 - Currently, the loading state of the tabs does not affect the selected tab (auto-defined by the component) should we change this logic for all Tabs used in the app, or make this behavior optional by using props?  ### Demo <https://www.loom.com/share/590df738a8ec41e6b64232bde237c01f?sid=7f8f4e40-ec82-4282-a43d-452a1cf27f4a> ### Refs #7112 --------- Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com> Co-authored-by: gitstart-twenty <140154534+gitstart-twenty@users.noreply.github.com> Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
This commit is contained in:
committed by
GitHub
parent
97eff774bd
commit
8afa504b65
@ -1,7 +1,8 @@
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import {
|
||||
StyledBoardCardBody,
|
||||
StyledBoardCardHeader,
|
||||
@ -43,7 +44,10 @@ export const RecordBoardColumnCardContainerSkeletonLoader = ({
|
||||
>
|
||||
<StyledBoardCardHeader showCompactView={isCompactModeActive}>
|
||||
<StyledSkeletonTitle>
|
||||
<Skeleton width={titleSkeletonWidth} height={16} />
|
||||
<Skeleton
|
||||
width={titleSkeletonWidth}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
</StyledSkeletonTitle>
|
||||
</StyledBoardCardHeader>
|
||||
<StyledSeparator />
|
||||
@ -51,8 +55,14 @@ export const RecordBoardColumnCardContainerSkeletonLoader = ({
|
||||
skeletonItems.map(({ id }) => (
|
||||
<StyledBoardCardBody key={id}>
|
||||
<StyledSkeletonIconAndText>
|
||||
<Skeleton width={16} height={16} />
|
||||
<Skeleton width={151} height={16} />
|
||||
<Skeleton
|
||||
width={16}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
<Skeleton
|
||||
width={151}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
</StyledSkeletonIconAndText>
|
||||
</StyledBoardCardBody>
|
||||
))}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { StyledSkeletonDiv } from './RecordInlineCellContainer';
|
||||
|
||||
export const RecordInlineCellSkeletonLoader = () => {
|
||||
@ -13,7 +14,10 @@ export const RecordInlineCellSkeletonLoader = () => {
|
||||
borderRadius={4}
|
||||
>
|
||||
<StyledSkeletonDiv>
|
||||
<Skeleton width={154} height={16} />
|
||||
<Skeleton
|
||||
width={154}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
</StyledSkeletonDiv>
|
||||
</SkeletonTheme>
|
||||
);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
|
||||
const StyledSkeletonDiv = styled.div`
|
||||
align-items: center;
|
||||
@ -22,8 +23,14 @@ export const PropertyBoxSkeletonLoader = () => {
|
||||
>
|
||||
{skeletonItems.map(({ id }) => (
|
||||
<StyledSkeletonDiv key={id}>
|
||||
<Skeleton width={92} height={16} />
|
||||
<Skeleton width={154} height={16} />
|
||||
<Skeleton
|
||||
width={92}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
<Skeleton
|
||||
width={154}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
</StyledSkeletonDiv>
|
||||
))}
|
||||
</SkeletonTheme>
|
||||
|
||||
@ -19,15 +19,6 @@ export const RightDrawerRecord = () => {
|
||||
viewableRecordNameSingularState,
|
||||
);
|
||||
const viewableRecordId = useRecoilValue(viewableRecordIdState);
|
||||
|
||||
if (!viewableRecordNameSingular) {
|
||||
throw new Error(`Object name is not defined`);
|
||||
}
|
||||
|
||||
if (!viewableRecordId) {
|
||||
throw new Error(`Record id is not defined`);
|
||||
}
|
||||
|
||||
const { objectNameSingular, objectRecordId } = useRecordShowPage(
|
||||
viewableRecordNameSingular ?? '',
|
||||
viewableRecordId ?? '',
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
|
||||
export const isNewViewableRecordLoadingState = createState<boolean>({
|
||||
key: 'activities/is-new-viewable-record-loading',
|
||||
defaultValue: false,
|
||||
});
|
||||
@ -21,6 +21,7 @@ import { RecordInlineCell } from '@/object-record/record-inline-cell/components/
|
||||
import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox';
|
||||
import { PropertyBoxSkeletonLoader } from '@/object-record/record-inline-cell/property-box/components/PropertyBoxSkeletonLoader';
|
||||
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
|
||||
import { isNewViewableRecordLoadingState } from '@/object-record/record-right-drawer/states/isNewViewableRecordLoading';
|
||||
import { RecordDetailDuplicatesSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailDuplicatesSection';
|
||||
import { RecordDetailRelationSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationSection';
|
||||
import { recordLoadingFamilyState } from '@/object-record/record-store/states/recordLoadingFamilyState';
|
||||
@ -33,6 +34,7 @@ import { ShowPageContainer } from '@/ui/layout/page/ShowPageContainer';
|
||||
import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer';
|
||||
import { ShowPageRightContainer } from '@/ui/layout/show-page/components/ShowPageRightContainer';
|
||||
import { ShowPageSummaryCard } from '@/ui/layout/show-page/components/ShowPageSummaryCard';
|
||||
import { ShowPageSummaryCardSkeletonLoader } from '@/ui/layout/show-page/components/ShowPageSummaryCardSkeletonLoader';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import {
|
||||
FieldMetadataType,
|
||||
@ -80,7 +82,9 @@ export const RecordShowContainer = ({
|
||||
recordId: objectRecordId,
|
||||
}),
|
||||
);
|
||||
|
||||
const isNewViewableRecordLoading = useRecoilValue(
|
||||
isNewViewableRecordLoadingState,
|
||||
);
|
||||
const [uploadImage] = useUploadImageMutation();
|
||||
const { updateOneRecord } = useUpdateOneRecord({ objectNameSingular });
|
||||
|
||||
@ -162,53 +166,56 @@ export const RecordShowContainer = ({
|
||||
const isReadOnly = objectMetadataItem.isRemote;
|
||||
const isMobile = useIsMobile() || isInRightDrawer;
|
||||
const isPrefetchLoading = useIsPrefetchLoading();
|
||||
const isNewRightDrawerItemLoading =
|
||||
isInRightDrawer && isNewViewableRecordLoading;
|
||||
|
||||
const summaryCard = isDefined(recordFromStore) ? (
|
||||
<ShowPageSummaryCard
|
||||
isMobile={isMobile}
|
||||
id={objectRecordId}
|
||||
logoOrAvatar={recordIdentifier?.avatarUrl ?? ''}
|
||||
icon={Icon}
|
||||
iconColor={IconColor}
|
||||
avatarPlaceholder={recordIdentifier?.name ?? ''}
|
||||
date={recordFromStore.createdAt ?? ''}
|
||||
loading={isPrefetchLoading || loading || recordLoading}
|
||||
title={
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
recordId: objectRecordId,
|
||||
recoilScopeId:
|
||||
objectRecordId + labelIdentifierFieldMetadataItem?.id,
|
||||
isLabelIdentifier: false,
|
||||
fieldDefinition: {
|
||||
type:
|
||||
labelIdentifierFieldMetadataItem?.type ||
|
||||
FieldMetadataType.Text,
|
||||
iconName: '',
|
||||
fieldMetadataId: labelIdentifierFieldMetadataItem?.id ?? '',
|
||||
label: labelIdentifierFieldMetadataItem?.label || '',
|
||||
metadata: {
|
||||
fieldName: labelIdentifierFieldMetadataItem?.name || '',
|
||||
objectMetadataNameSingular: objectNameSingular,
|
||||
const summaryCard =
|
||||
!isNewRightDrawerItemLoading && isDefined(recordFromStore) ? (
|
||||
<ShowPageSummaryCard
|
||||
isMobile={isMobile}
|
||||
id={objectRecordId}
|
||||
logoOrAvatar={recordIdentifier?.avatarUrl ?? ''}
|
||||
icon={Icon}
|
||||
iconColor={IconColor}
|
||||
avatarPlaceholder={recordIdentifier?.name ?? ''}
|
||||
date={recordFromStore.createdAt ?? ''}
|
||||
loading={isPrefetchLoading || loading || recordLoading}
|
||||
title={
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
recordId: objectRecordId,
|
||||
recoilScopeId:
|
||||
objectRecordId + labelIdentifierFieldMetadataItem?.id,
|
||||
isLabelIdentifier: false,
|
||||
fieldDefinition: {
|
||||
type:
|
||||
labelIdentifierFieldMetadataItem?.type ||
|
||||
FieldMetadataType.Text,
|
||||
iconName: '',
|
||||
fieldMetadataId: labelIdentifierFieldMetadataItem?.id ?? '',
|
||||
label: labelIdentifierFieldMetadataItem?.label || '',
|
||||
metadata: {
|
||||
fieldName: labelIdentifierFieldMetadataItem?.name || '',
|
||||
objectMetadataNameSingular: objectNameSingular,
|
||||
},
|
||||
defaultValue: labelIdentifierFieldMetadataItem?.defaultValue,
|
||||
},
|
||||
defaultValue: labelIdentifierFieldMetadataItem?.defaultValue,
|
||||
},
|
||||
useUpdateRecord: useUpdateOneObjectRecordMutation,
|
||||
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
||||
isCentered: true,
|
||||
}}
|
||||
>
|
||||
<RecordInlineCell readonly={isReadOnly} isCentered={true} />
|
||||
</FieldContext.Provider>
|
||||
}
|
||||
avatarType={recordIdentifier?.avatarType ?? 'rounded'}
|
||||
onUploadPicture={
|
||||
objectNameSingular === 'person' ? onUploadPicture : undefined
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
useUpdateRecord: useUpdateOneObjectRecordMutation,
|
||||
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
||||
isCentered: true,
|
||||
}}
|
||||
>
|
||||
<RecordInlineCell readonly={isReadOnly} isCentered={true} />
|
||||
</FieldContext.Provider>
|
||||
}
|
||||
avatarType={recordIdentifier?.avatarType ?? 'rounded'}
|
||||
onUploadPicture={
|
||||
objectNameSingular === 'person' ? onUploadPicture : undefined
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<ShowPageSummaryCardSkeletonLoader />
|
||||
);
|
||||
|
||||
const fieldsBox = (
|
||||
<>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
|
||||
const StyledSkeletonContainer = styled.div`
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
@ -15,7 +16,10 @@ const StyledRecordTableCellLoader = ({ width }: { width?: number }) => {
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
borderRadius={4}
|
||||
>
|
||||
<Skeleton width={width} height={16} />
|
||||
<Skeleton
|
||||
width={width}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
</SkeletonTheme>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user