-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Data Skeleton Loading on Indexes #5828
Changes from 3 commits
ffd3ed2
aa4966b
8b5ac3f
1c7f966
61611e9
f931621
b11dbc2
61b6d70
5b6d6b1
aabf6b5
7d90a77
a39181a
3614b81
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; | ||
import { useTheme } from '@emotion/react'; | ||
import styled from '@emotion/styled'; | ||
|
||
import { | ||
StyledBoardCardBody, | ||
StyledBoardCardHeader, | ||
} from '@/object-record/record-board/record-board-card/components/RecordBoardCard'; | ||
|
||
const StyledSkeletonIconAndText = styled.div` | ||
display: flex; | ||
gap: ${({ theme }) => theme.spacing(1)}; | ||
`; | ||
|
||
const StyledSkeletonTitle = styled.div` | ||
padding-left: ${({ theme }) => theme.spacing(2)}; | ||
`; | ||
|
||
const StyledSeparator = styled.div` | ||
height: ${({ theme }) => theme.spacing(2)}; | ||
`; | ||
|
||
export const RecordBoardColumnCardContainerSkeletonLoader = ({ | ||
titleSkeletonWidth, | ||
isCompactModeActive, | ||
}: { | ||
titleSkeletonWidth: number; | ||
isCompactModeActive: boolean; | ||
}) => { | ||
const theme = useTheme(); | ||
const skeletonItems = Array.from({ length: 6 }).map((_, index) => ({ | ||
id: `skeleton-item-${index}`, | ||
})); | ||
return ( | ||
<SkeletonTheme | ||
baseColor={theme.background.tertiary} | ||
highlightColor={theme.background.transparent.lighter} | ||
borderRadius={4} | ||
> | ||
<StyledBoardCardHeader showCompactView={isCompactModeActive}> | ||
<StyledSkeletonTitle> | ||
<Skeleton width={titleSkeletonWidth} height={16} /> | ||
</StyledSkeletonTitle> | ||
</StyledBoardCardHeader> | ||
<StyledSeparator /> | ||
{!isCompactModeActive && | ||
skeletonItems.map(({ id }) => ( | ||
<StyledBoardCardBody key={id}> | ||
<StyledSkeletonIconAndText> | ||
<Skeleton width={16} height={16} /> | ||
<Skeleton width={151} height={16} /> | ||
</StyledSkeletonIconAndText> | ||
</StyledBoardCardBody> | ||
))} | ||
</SkeletonTheme> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,15 @@ | ||
import React, { ReactElement, useContext, useEffect, useState } from 'react'; | ||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; | ||
import { useTheme } from '@emotion/react'; | ||
import styled from '@emotion/styled'; | ||
import { clsx } from 'clsx'; | ||
import { useRecoilValue } from 'recoil'; | ||
|
||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; | ||
import { useFieldFocus } from '@/object-record/record-field/hooks/useFieldFocus'; | ||
import { RecordTableContext } from '@/object-record/record-table/contexts/RecordTableContext'; | ||
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext'; | ||
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; | ||
import { RecordTableCellSoftFocusMode } from '@/object-record/record-table/record-table-cell/components/RecordTableCellSoftFocusMode'; | ||
import { useCurrentTableCellPosition } from '@/object-record/record-table/record-table-cell/hooks/useCurrentCellPosition'; | ||
import { useOpenRecordTableCellFromCell } from '@/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellFromCell'; | ||
|
@@ -18,6 +23,28 @@ import { RecordTableCellEditMode } from './RecordTableCellEditMode'; | |
|
||
import styles from './RecordTableCellContainer.module.css'; | ||
|
||
const StyledSkeletonContainer = styled.div` | ||
padding-left: ${({ theme }) => theme.spacing(2)}; | ||
padding-right: ${({ theme }) => theme.spacing(1)}; | ||
`; | ||
|
||
const StyledRecordTableCellContainerLoader = ({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you extract all of this logic outside of RecordTableCellContainer ? Because RecordTableCellContainer is a very optimized component used for displaying FieldDisplay component fast. Here we just want to fill a table with skeletons, so we might as well put this logic in another RecordTableCellLoading and use it directly in the new RecordTableBodyLoading that should also be extracted. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking into this @lucasbordeau |
||
skeletonWidth = 132, | ||
}: { | ||
skeletonWidth?: number; | ||
}) => { | ||
const theme = useTheme(); | ||
return ( | ||
<SkeletonTheme | ||
baseColor={theme.background.tertiary} | ||
highlightColor={theme.background.transparent.lighter} | ||
borderRadius={4} | ||
> | ||
<Skeleton width={skeletonWidth} height={16} /> | ||
</SkeletonTheme> | ||
); | ||
}; | ||
|
||
export type RecordTableCellContainerProps = { | ||
editModeContent: ReactElement; | ||
nonEditModeContent: ReactElement; | ||
|
@@ -26,6 +53,7 @@ export type RecordTableCellContainerProps = { | |
maxContentWidth?: number; | ||
onSubmit?: () => void; | ||
onCancel?: () => void; | ||
skeletonWidth?: number; | ||
}; | ||
|
||
const DEFAULT_CELL_SCOPE: HotkeyScope = { | ||
|
@@ -36,9 +64,11 @@ export const RecordTableCellContainer = ({ | |
editModeContent, | ||
nonEditModeContent, | ||
editHotkeyScope, | ||
skeletonWidth, | ||
}: RecordTableCellContainerProps) => { | ||
const { setIsFocused } = useFieldFocus(); | ||
const { openTableCell } = useOpenRecordTableCellFromCell(); | ||
const { isRecordTableInitialLoadingState } = useRecordTableStates(); | ||
|
||
const { isSelected, recordId, isPendingRow } = useContext( | ||
RecordTableRowContext, | ||
|
@@ -53,7 +83,9 @@ export const RecordTableCellContainer = ({ | |
const [isInEditMode, setIsInEditMode] = useState(shouldBeInitiallyInEditMode); | ||
|
||
const cellPosition = useCurrentTableCellPosition(); | ||
|
||
const isRecordTableInitialLoading = useRecoilValue( | ||
isRecordTableInitialLoadingState, | ||
); | ||
const handleContextMenu = (event: React.MouseEvent) => { | ||
onContextMenu(event, recordId); | ||
}; | ||
|
@@ -151,7 +183,13 @@ export const RecordTableCellContainer = ({ | |
[styles.cellBaseContainerSoftFocus]: hasSoftFocus, | ||
})} | ||
> | ||
{isInEditMode ? ( | ||
{isRecordTableInitialLoading ? ( | ||
<StyledSkeletonContainer> | ||
<StyledRecordTableCellContainerLoader | ||
skeletonWidth={skeletonWidth} | ||
/> | ||
</StyledSkeletonContainer> | ||
) : isInEditMode ? ( | ||
<RecordTableCellEditMode>{editModeContent}</RecordTableCellEditMode> | ||
) : hasSoftFocus ? ( | ||
<> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState'; | ||
|
||
export const isRecordIndexLoadingFamilyState = createFamilyState< | ||
boolean, | ||
string | undefined | ||
>({ | ||
key: 'isRecordIndexLoadingFamilyState', | ||
defaultValue: false, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure loading state is updated based on
loading
andrecords.length
.