mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor(site): Add skeletons for table loading state (#6626)
This commit is contained in:
@@ -23,7 +23,12 @@ export const AvatarData: FC<PropsWithChildren<AvatarDataProps>> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack spacing={1.5} direction="row" alignItems="center">
|
||||
<Stack
|
||||
spacing={1.5}
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
className={styles.root}
|
||||
>
|
||||
{avatar}
|
||||
|
||||
<Stack spacing={0}>
|
||||
@@ -35,6 +40,10 @@ export const AvatarData: FC<PropsWithChildren<AvatarDataProps>> = ({
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
minHeight: theme.spacing(5), // Make it predictable for the skeleton
|
||||
},
|
||||
|
||||
title: {
|
||||
color: theme.palette.text.primary,
|
||||
fontWeight: 600,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { FC } from "react"
|
||||
import { Stack } from "components/Stack/Stack"
|
||||
import { Skeleton } from "@material-ui/lab"
|
||||
|
||||
export const AvatarDataSkeleton: FC = () => {
|
||||
return (
|
||||
<Stack spacing={1.5} direction="row" alignItems="center">
|
||||
<Skeleton variant="circle" width={36} height={36} />
|
||||
|
||||
<Stack spacing={0}>
|
||||
<Skeleton variant="text" width={100} />
|
||||
<Skeleton variant="text" width={60} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import TableCell from "@material-ui/core/TableCell"
|
||||
import TableRow from "@material-ui/core/TableRow"
|
||||
import Skeleton from "@material-ui/lab/Skeleton"
|
||||
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton"
|
||||
import { FC } from "react"
|
||||
import { Loader } from "../Loader/Loader"
|
||||
|
||||
@@ -22,3 +24,36 @@ const useStyles = makeStyles((theme) => ({
|
||||
height: theme.spacing(20),
|
||||
},
|
||||
}))
|
||||
|
||||
export const TableLoaderSkeleton: FC<{
|
||||
columns: number
|
||||
rows?: number
|
||||
useAvatarData?: boolean
|
||||
}> = ({ columns, rows = 4, useAvatarData = false }) => {
|
||||
const placeholderColumns = Array(columns).fill(undefined)
|
||||
const placeholderRows = Array(rows).fill(undefined)
|
||||
|
||||
return (
|
||||
<>
|
||||
{placeholderRows.map((_, rowIndex) => (
|
||||
<TableRow key={rowIndex} role="progressbar" data-testid="loader">
|
||||
{placeholderColumns.map((_, columnIndex) => {
|
||||
if (useAvatarData && columnIndex === 0) {
|
||||
return (
|
||||
<TableCell key={columnIndex}>
|
||||
<AvatarDataSkeleton />
|
||||
</TableCell>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<TableCell key={columnIndex}>
|
||||
<Skeleton variant="text" width="25%" />
|
||||
</TableCell>
|
||||
)
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as TypesGen from "../../api/typesGenerated"
|
||||
import { combineClasses } from "../../util/combineClasses"
|
||||
import { AvatarData } from "../AvatarData/AvatarData"
|
||||
import { EmptyState } from "../EmptyState/EmptyState"
|
||||
import { TableLoader } from "../TableLoader/TableLoader"
|
||||
import { TableLoaderSkeleton } from "../TableLoader/TableLoader"
|
||||
import { TableRowMenu } from "../TableRowMenu/TableRowMenu"
|
||||
import { EditRolesButton } from "components/EditRolesButton/EditRolesButton"
|
||||
import { Stack } from "components/Stack/Stack"
|
||||
@@ -70,7 +70,7 @@ export const UsersTableBody: FC<
|
||||
return (
|
||||
<ChooseOne>
|
||||
<Cond condition={Boolean(isLoading)}>
|
||||
<TableLoader />
|
||||
<TableLoaderSkeleton columns={4} useAvatarData />
|
||||
</Cond>
|
||||
<Cond condition={!users || users.length === 0}>
|
||||
<ChooseOne>
|
||||
|
||||
@@ -8,7 +8,7 @@ import { TableEmpty } from "components/TableEmpty/TableEmpty"
|
||||
import { FC } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { Link as RouterLink } from "react-router-dom"
|
||||
import { TableLoader } from "../TableLoader/TableLoader"
|
||||
import { TableLoaderSkeleton } from "../TableLoader/TableLoader"
|
||||
import { WorkspacesRow } from "./WorkspacesRow"
|
||||
|
||||
interface TableBodyProps {
|
||||
@@ -29,7 +29,7 @@ export const WorkspacesTableBody: FC<
|
||||
}
|
||||
|
||||
if (!workspaces) {
|
||||
return <TableLoader />
|
||||
return <TableLoaderSkeleton columns={4} useAvatarData />
|
||||
}
|
||||
|
||||
if (workspaces.length === 0) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { AvatarData } from "components/AvatarData/AvatarData"
|
||||
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"
|
||||
import { EmptyState } from "components/EmptyState/EmptyState"
|
||||
import { Stack } from "components/Stack/Stack"
|
||||
import { TableLoader } from "components/TableLoader/TableLoader"
|
||||
import { TableLoaderSkeleton } from "components/TableLoader/TableLoader"
|
||||
import { UserAvatar } from "components/UserAvatar/UserAvatar"
|
||||
import { FC } from "react"
|
||||
import { Link as RouterLink, useNavigate } from "react-router-dom"
|
||||
@@ -83,7 +83,7 @@ export const GroupsPageView: FC<GroupsPageViewProps> = ({
|
||||
<TableBody>
|
||||
<ChooseOne>
|
||||
<Cond condition={isLoading}>
|
||||
<TableLoader />
|
||||
<TableLoaderSkeleton columns={2} useAvatarData />
|
||||
</Cond>
|
||||
|
||||
<Cond condition={isEmpty}>
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
PageHeaderTitle,
|
||||
} from "../../components/PageHeader/PageHeader"
|
||||
import { Stack } from "../../components/Stack/Stack"
|
||||
import { TableLoader } from "../../components/TableLoader/TableLoader"
|
||||
import { TableLoaderSkeleton } from "../../components/TableLoader/TableLoader"
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipLink,
|
||||
@@ -210,7 +210,7 @@ export const TemplatesPageView: FC<
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<Maybe condition={isLoading}>
|
||||
<TableLoader />
|
||||
<TableLoaderSkeleton columns={4} useAvatarData />
|
||||
</Maybe>
|
||||
|
||||
<ChooseOne>
|
||||
|
||||
@@ -41,4 +41,7 @@ export const props = {
|
||||
MuiPaper: {
|
||||
elevation: 0,
|
||||
},
|
||||
MuiSkeleton: {
|
||||
animation: "wave",
|
||||
},
|
||||
} as ComponentsProps
|
||||
|
||||
Reference in New Issue
Block a user