Skip to content

feat(site): make workspace batch deletion GA #9313

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

Merged
merged 10 commits into from
Aug 30, 2023
Prev Previous commit
Next Next commit
Remove feature checks and improve loading stat
  • Loading branch information
BrunoQuaresma committed Aug 24, 2023
commit b95a64335fe92f3221758e45a51a5ff9b2c1f4e9
50 changes: 20 additions & 30 deletions site/src/components/TableLoader/TableLoader.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { makeStyles } from "@mui/styles"
import TableCell from "@mui/material/TableCell"
import TableRow from "@mui/material/TableRow"
import Skeleton from "@mui/material/Skeleton"
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton"
import { FC } from "react"
import TableRow, { TableRowProps } from "@mui/material/TableRow"
import { FC, ReactNode, cloneElement, isValidElement } from "react"
import { Loader } from "../Loader/Loader"

export const TableLoader: FC = () => {
Expand All @@ -25,35 +23,27 @@ const useStyles = makeStyles((theme) => ({
},
}))

export const TableLoaderSkeleton: FC<{
columns: number
export const TableLoaderSkeleton = ({
rows = 4,
children,
}: {
rows?: number
useAvatarData?: boolean
}> = ({ columns, rows = 4, useAvatarData = false }) => {
const placeholderColumns = Array(columns).fill(undefined)
const placeholderRows = Array(rows).fill(undefined)

children: ReactNode
}) => {
if (!isValidElement(children)) {
throw new Error(
"TableLoaderSkeleton children must be a valid React element",
)
}
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>
))}
{Array.from({ length: rows }, (_, i) =>
cloneElement(children, { key: i }),
)}
</>
)
}

export const TableRowSkeleton = (props: TableRowProps) => {
return <TableRow role="progressbar" data-testid="loader" {...props} />
}
35 changes: 33 additions & 2 deletions site/src/components/UsersTable/UsersTableBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ import * as TypesGen from "../../api/typesGenerated"
import { combineClasses } from "../../utils/combineClasses"
import { AvatarData } from "../AvatarData/AvatarData"
import { EmptyState } from "../EmptyState/EmptyState"
import { TableLoaderSkeleton } from "../TableLoader/TableLoader"
import {
TableLoaderSkeleton,
TableRowSkeleton,
} from "../TableLoader/TableLoader"
import { TableRowMenu } from "../TableRowMenu/TableRowMenu"
import { EditRolesButton } from "components/EditRolesButton/EditRolesButton"
import { Stack } from "components/Stack/Stack"
import { EnterpriseBadge } from "components/DeploySettingsLayout/Badges"
import Skeleton from "@mui/material/Skeleton"
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton"

const isOwnerRole = (role: TypesGen.Role): boolean => {
return role.name === "owner"
Expand Down Expand Up @@ -80,7 +85,7 @@ export const UsersTableBody: FC<
return (
<ChooseOne>
<Cond condition={Boolean(isLoading)}>
<TableLoaderSkeleton columns={5} useAvatarData />
<TableLoader />
</Cond>
<Cond condition={!users || users.length === 0}>
<ChooseOne>
Expand Down Expand Up @@ -252,3 +257,29 @@ const useStyles = makeStyles((theme) => ({
borderColor: theme.palette.info.light,
},
}))

const TableLoader = () => {
return (
<TableLoaderSkeleton>
<TableRowSkeleton>
<TableCell>
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<AvatarDataSkeleton />
</Box>
</TableCell>
<TableCell>
<Skeleton variant="text" width="25%" />
</TableCell>
<TableCell>
<Skeleton variant="text" width="25%" />
</TableCell>
<TableCell>
<Skeleton variant="text" width="25%" />
</TableCell>
<TableCell>
<Skeleton variant="text" width="25%" />
</TableCell>
</TableRowSkeleton>
</TableLoaderSkeleton>
)
}
30 changes: 28 additions & 2 deletions site/src/pages/GroupsPage/GroupsPageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@ 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 { TableLoaderSkeleton } from "components/TableLoader/TableLoader"
import {
TableLoaderSkeleton,
TableRowSkeleton,
} from "components/TableLoader/TableLoader"
import { UserAvatar } from "components/UserAvatar/UserAvatar"
import { FC } from "react"
import { Link as RouterLink, useNavigate } from "react-router-dom"
import { Paywall } from "components/Paywall/Paywall"
import { Group } from "api/typesGenerated"
import { GroupAvatar } from "components/GroupAvatar/GroupAvatar"
import { docs } from "utils/docs"
import Skeleton from "@mui/material/Skeleton"
import { Box } from "@mui/system"
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton"

export type GroupsPageViewProps = {
groups: Group[] | undefined
Expand Down Expand Up @@ -83,7 +89,7 @@ export const GroupsPageView: FC<GroupsPageViewProps> = ({
<TableBody>
<ChooseOne>
<Cond condition={isLoading}>
<TableLoaderSkeleton columns={3} useAvatarData />
<TableLoader />
</Cond>

<Cond condition={isEmpty}>
Expand Down Expand Up @@ -184,6 +190,26 @@ export const GroupsPageView: FC<GroupsPageViewProps> = ({
)
}

const TableLoader = () => {
return (
<TableLoaderSkeleton>
<TableRowSkeleton>
<TableCell>
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<AvatarDataSkeleton />
</Box>
</TableCell>
<TableCell>
<Skeleton variant="text" width="25%" />
</TableCell>
<TableCell>
<Skeleton variant="text" width="25%" />
</TableCell>
</TableRowSkeleton>
</TableLoaderSkeleton>
)
}

const useStyles = makeStyles((theme) => ({
clickableTableRow: {
cursor: "pointer",
Expand Down
36 changes: 34 additions & 2 deletions site/src/pages/TemplatesPage/TemplatesPageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ import {
PageHeaderTitle,
} from "../../components/PageHeader/PageHeader"
import { Stack } from "../../components/Stack/Stack"
import { TableLoaderSkeleton } from "../../components/TableLoader/TableLoader"
import {
TableLoaderSkeleton,
TableRowSkeleton,
} from "../../components/TableLoader/TableLoader"
import {
HelpTooltip,
HelpTooltipLink,
Expand All @@ -42,6 +45,9 @@ import ArrowForwardOutlined from "@mui/icons-material/ArrowForwardOutlined"
import { Avatar } from "components/Avatar/Avatar"
import { ErrorAlert } from "components/Alert/ErrorAlert"
import { docs } from "utils/docs"
import Skeleton from "@mui/material/Skeleton"
import { Box } from "@mui/system"
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton"

export const Language = {
developerCount: (activeCount: number): string => {
Expand Down Expand Up @@ -196,7 +202,7 @@ export const TemplatesPageView: FC<
</TableHead>
<TableBody>
<Maybe condition={isLoading}>
<TableLoaderSkeleton columns={5} useAvatarData />
<TableLoader />
</Maybe>

<ChooseOne>
Expand All @@ -222,6 +228,32 @@ export const TemplatesPageView: FC<
)
}

const TableLoader = () => {
return (
<TableLoaderSkeleton>
<TableRowSkeleton>
<TableCell>
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<AvatarDataSkeleton />
</Box>
</TableCell>
<TableCell>
<Skeleton variant="text" width="25%" />
</TableCell>
<TableCell>
<Skeleton variant="text" width="25%" />
</TableCell>
<TableCell>
<Skeleton variant="text" width="25%" />
</TableCell>
<TableCell>
<Skeleton variant="text" width="25%" />
</TableCell>
</TableRowSkeleton>
</TableLoaderSkeleton>
)
}

const useStyles = makeStyles((theme) => ({
templateIconWrapper: {
// Same size then the avatar component
Expand Down
10 changes: 1 addition & 9 deletions site/src/pages/WorkspacesPage/WorkspacesPage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { usePagination } from "hooks/usePagination"
import { Workspace } from "api/typesGenerated"
import {
useDashboard,
useIsWorkspaceActionsEnabled,
} from "components/Dashboard/DashboardProvider"
import { useIsWorkspaceActionsEnabled } from "components/Dashboard/DashboardProvider"
import { FC, useEffect, useState } from "react"
import { Helmet } from "react-helmet-async"
import { pageTitle } from "utils/page"
Expand Down Expand Up @@ -68,10 +65,6 @@ const WorkspacesPage: FC = () => {
const [checkedWorkspaces, setCheckedWorkspaces] = useState<Workspace[]>([])
const [isDeletingAll, setIsDeletingAll] = useState(false)
const [urlSearchParams] = searchParamsResult
const dashboard = useDashboard()
const isWorkspaceBatchActionsEnabled =
dashboard.experiments.includes("workspaces_batch_actions") ||
process.env.NODE_ENV === "development"

// We want to uncheck the selected workspaces always when the url changes
// because of filtering or pagination
Expand All @@ -86,7 +79,6 @@ const WorkspacesPage: FC = () => {
</Helmet>

<WorkspacesPageView
isWorkspaceBatchActionsEnabled={isWorkspaceBatchActionsEnabled}
checkedWorkspaces={checkedWorkspaces}
onCheckChange={setCheckedWorkspaces}
workspaces={data?.workspaces}
Expand Down
3 changes: 0 additions & 3 deletions site/src/pages/WorkspacesPage/WorkspacesPageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export interface WorkspacesPageViewProps {
filterProps: ComponentProps<typeof WorkspacesFilter>
page: number
limit: number
isWorkspaceBatchActionsEnabled?: boolean
onPageChange: (page: number) => void
onUpdateWorkspace: (workspace: Workspace) => void
onCheckChange: (checkedWorkspaces: Workspace[]) => void
Expand All @@ -64,7 +63,6 @@ export const WorkspacesPageView: FC<
onUpdateWorkspace,
page,
checkedWorkspaces,
isWorkspaceBatchActionsEnabled,
onCheckChange,
onDeleteAll,
}) => {
Expand Down Expand Up @@ -151,7 +149,6 @@ export const WorkspacesPageView: FC<
onUpdateWorkspace={onUpdateWorkspace}
checkedWorkspaces={checkedWorkspaces}
onCheckChange={onCheckChange}
isWorkspaceBatchActionsEnabled={isWorkspaceBatchActionsEnabled}
/>
{count !== undefined && (
<PaginationWidgetBase
Expand Down
Loading