Skip to content

refactor(site): Improve workspaces filtering #7681

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 25 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactor filter
  • Loading branch information
BrunoQuaresma committed May 23, 2023
commit 858ee93670467ba946e2263261bc0ace6f6896ed
4 changes: 2 additions & 2 deletions site/src/components/BuildsTable/BuildAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PlayArrowOutlined from "@mui/icons-material/PlayArrowOutlined"
import PauseOutlined from "@mui/icons-material/PauseOutlined"
import DeleteOutlined from "@mui/icons-material/DeleteOutlined"
import { WorkspaceBuild, WorkspaceTransition } from "api/typesGenerated"
import { getDisplayJobStatus } from "utils/workspace"
import { getDisplayWorkspaceBuildStatus } from "utils/workspace"
import { Avatar, AvatarProps } from "components/Avatar/Avatar"
import { PaletteIndex } from "theme/theme"
import { Theme } from "@mui/material/styles"
Expand Down Expand Up @@ -39,7 +39,7 @@ const iconByTransition: Record<WorkspaceTransition, JSX.Element> = {

export const BuildAvatar: FC<BuildAvatarProps> = ({ build, size }) => {
const theme = useTheme<Theme>()
const displayBuildStatus = getDisplayJobStatus(theme, build.job.status)
const displayBuildStatus = getDisplayWorkspaceBuildStatus(theme, build)

return (
<StyledBadge
Expand Down
4 changes: 2 additions & 2 deletions site/src/components/DeploymentBanner/DeploymentBannerView.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { DeploymentStats, WorkspaceStatus } from "api/typesGenerated"
import { FC, useMemo, useEffect, useState } from "react"
import prettyBytes from "pretty-bytes"
import { getStatus } from "components/WorkspaceStatusBadge/WorkspaceStatusBadge"
import BuildingIcon from "@mui/icons-material/Build"
import { makeStyles } from "@mui/styles"
import { RocketIcon } from "components/Icons/RocketIcon"
Expand All @@ -19,6 +18,7 @@ import dayjs from "dayjs"
import CollectedIcon from "@mui/icons-material/Compare"
import RefreshIcon from "@mui/icons-material/Refresh"
import Button from "@mui/material/Button"
import { getDisplayWorkspaceStatus } from "utils/workspace"

export const bannerHeight = 36

Expand Down Expand Up @@ -218,7 +218,7 @@ const WorkspaceBuildValue: FC<{
count?: number
}> = ({ status, count }) => {
const styles = useStyles()
const displayStatus = getStatus(status)
const displayStatus = getDisplayWorkspaceStatus(status)
let statusText = displayStatus.text
let icon = displayStatus.icon
if (status === "starting") {
Expand Down
93 changes: 8 additions & 85 deletions site/src/components/WorkspaceStatusBadge/WorkspaceStatusBadge.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import CircularProgress from "@mui/material/CircularProgress"
import ErrorIcon from "@mui/icons-material/ErrorOutline"
import StopIcon from "@mui/icons-material/StopOutlined"
import PlayIcon from "@mui/icons-material/PlayArrowOutlined"
import QueuedIcon from "@mui/icons-material/HourglassEmpty"
import { Workspace, WorkspaceBuild } from "api/typesGenerated"
import { Workspace } from "api/typesGenerated"
import { Pill } from "components/Pill/Pill"
import i18next from "i18next"
import { FC, PropsWithChildren } from "react"
import { makeStyles } from "@mui/styles"
import { combineClasses } from "utils/combineClasses"
Expand All @@ -14,82 +8,7 @@ import {
ImpendingDeletionBadge,
ImpendingDeletionText,
} from "components/WorkspaceDeletion"

const LoadingIcon: FC = () => {
return <CircularProgress size={10} style={{ color: "#FFF" }} />
}

export const getStatus = (buildStatus: WorkspaceBuild["status"]) => {
const { t } = i18next

switch (buildStatus) {
case undefined:
return {
text: t("workspaceStatus.loading", { ns: "common" }),
icon: <LoadingIcon />,
} as const
case "running":
return {
type: "success",
text: t("workspaceStatus.running", { ns: "common" }),
icon: <PlayIcon />,
} as const
case "starting":
return {
type: "success",
text: t("workspaceStatus.starting", { ns: "common" }),
icon: <LoadingIcon />,
} as const
case "stopping":
return {
type: "warning",
text: t("workspaceStatus.stopping", { ns: "common" }),
icon: <LoadingIcon />,
} as const
case "stopped":
return {
type: "warning",
text: t("workspaceStatus.stopped", { ns: "common" }),
icon: <StopIcon />,
} as const
case "deleting":
return {
type: "warning",
text: t("workspaceStatus.deleting", { ns: "common" }),
icon: <LoadingIcon />,
} as const
case "deleted":
return {
type: "error",
text: t("workspaceStatus.deleted", { ns: "common" }),
icon: <ErrorIcon />,
} as const
case "canceling":
return {
type: "warning",
text: t("workspaceStatus.canceling", { ns: "common" }),
icon: <LoadingIcon />,
} as const
case "canceled":
return {
type: "warning",
text: t("workspaceStatus.canceled", { ns: "common" }),
icon: <ErrorIcon />,
} as const
case "failed":
return {
type: "error",
text: t("workspaceStatus.failed", { ns: "common" }),
icon: <ErrorIcon />,
} as const
case "pending":
return {
type: "info",
text: t("workspaceStatus.pending", { ns: "common" }),
icon: <QueuedIcon />,
} as const
}
}
import { getDisplayWorkspaceStatus } from "utils/workspace"

export type WorkspaceStatusBadgeProps = {
workspace: Workspace
Expand All @@ -99,7 +18,9 @@ export type WorkspaceStatusBadgeProps = {
export const WorkspaceStatusBadge: FC<
PropsWithChildren<WorkspaceStatusBadgeProps>
> = ({ workspace, className }) => {
const { text, icon, type } = getStatus(workspace.latest_build.status)
const { text, icon, type } = getDisplayWorkspaceStatus(
workspace.latest_build.status,
)
return (
<ChooseOne>
{/* <ImpendingDeletionBadge/> determines its own visibility */}
Expand All @@ -117,7 +38,9 @@ export const WorkspaceStatusText: FC<
PropsWithChildren<WorkspaceStatusBadgeProps>
> = ({ workspace, className }) => {
const styles = useStyles()
const { text, type } = getStatus(workspace.latest_build.status)
const { text, type } = getDisplayWorkspaceStatus(
workspace.latest_build.status,
)

return (
<ChooseOne>
Expand Down
76 changes: 18 additions & 58 deletions site/src/pages/WorkspacesPage/WorkspacesPageView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Link from "@mui/material/Link"
import { ProvisionerJobStatus, Workspace } from "api/typesGenerated"
import { Workspace, WorkspaceStatuses } from "api/typesGenerated"
import { Maybe } from "components/Conditionals/Maybe"
import { PaginationWidgetBase } from "components/PaginationWidget/PaginationWidgetBase"
import { FC, forwardRef, useRef, useState } from "react"
Expand All @@ -22,8 +22,6 @@ import TextField from "@mui/material/TextField"
import { MockTemplate, MockUser, MockUser2 } from "testHelpers/entities"
import { UserAvatar } from "components/UserAvatar/UserAvatar"
import KeyboardArrowDown from "@mui/icons-material/KeyboardArrowDown"
import { getDisplayJobStatus, jobStatuses } from "utils/workspace"
import { useTheme } from "@mui/styles"
import Button, { ButtonProps } from "@mui/material/Button"
import Menu from "@mui/material/Menu"
import MenuItem from "@mui/material/MenuItem"
Expand All @@ -35,6 +33,7 @@ import { Palette, PaletteColor } from "@mui/material/styles"
import IconButton from "@mui/material/IconButton"
import Tooltip from "@mui/material/Tooltip"
import CloseOutlined from "@mui/icons-material/CloseOutlined"
import { getDisplayWorkspaceStatus } from "utils/workspace"

export const Language = {
pageTitle: "Workspaces",
Expand Down Expand Up @@ -274,21 +273,8 @@ const OwnerFilter: FC<{

return (
<div>
<MenuButton
ref={buttonRef}
startIcon={
selectedOption ? (
<UserAvatar
username={selectedOption.label}
avatarURL={selectedOption.avatarUrl}
sx={{ width: 16, height: 16, fontSize: "8px !important" }}
/>
) : undefined
}
onClick={() => setIsMenuOpen(true)}
sx={{ width: 220 }}
>
{selectedOption ? selectedOption.label : "All users"}
<MenuButton ref={buttonRef} onClick={() => setIsMenuOpen(true)}>
User
</MenuButton>
<Menu
id="user-filter-menu"
Expand Down Expand Up @@ -392,21 +378,8 @@ const TemplateFilter: FC<{

return (
<div>
<MenuButton
ref={buttonRef}
startIcon={
selectedOption ? (
<TemplateAvatar
sx={{ width: 14, height: 14, fontSize: 8 }}
templateName={selectedOption.label}
icon={selectedOption.icon}
/>
) : undefined
}
onClick={() => setIsMenuOpen(true)}
sx={{ width: 220 }}
>
{selectedOption ? selectedOption.label : "All templates"}
<MenuButton ref={buttonRef} onClick={() => setIsMenuOpen(true)}>
Template
</MenuButton>
<Menu
id="template-filter-menu"
Expand Down Expand Up @@ -500,19 +473,18 @@ const StatusFilter: FC<{
value: FilterValue["status"]
onChange: (value: FilterValue["status"]) => void
}> = ({ value, onChange }) => {
const theme = useTheme()
const buttonRef = useRef<HTMLButtonElement>(null)
const [isMenuOpen, setIsMenuOpen] = useState(false)
const workspaceStatusOptions: WorkspaceStatusOption[] = Object.keys(
jobStatuses,
).map((status) => {
const display = getDisplayJobStatus(theme, status as ProvisionerJobStatus)
return {
label: display.status,
value: status,
color: display.type,
}
})
const workspaceStatusOptions: WorkspaceStatusOption[] = WorkspaceStatuses.map(
(status) => {
const display = getDisplayWorkspaceStatus(status)
return {
label: display.text,
value: status,
color: display.type ?? "warning",
}
},
)
const selectedOption = workspaceStatusOptions.find(
(option) => option.value === value,
)
Expand All @@ -523,24 +495,14 @@ const StatusFilter: FC<{

return (
<div>
<MenuButton
ref={buttonRef}
startIcon={
selectedOption ? (
<StatusIndicator option={selectedOption} />
) : undefined
}
onClick={() => setIsMenuOpen(true)}
sx={{ width: 140 }}
>
{selectedOption ? selectedOption.label : "All statuses"}
<MenuButton ref={buttonRef} onClick={() => setIsMenuOpen(true)}>
Status
</MenuButton>
<Menu
id="status-filter-menu"
anchorEl={buttonRef.current}
open={isMenuOpen}
onClose={handleClose}
sx={{ "& .MuiPaper-root": { width: 140 } }}
>
{workspaceStatusOptions.map((option) => (
<MenuItem
Expand Down Expand Up @@ -594,8 +556,6 @@ const MenuButton = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
{...props}
sx={{
borderRadius: "6px",
lineHeight: 0,
"& .MuiButton-endIcon": { marginLeft: "auto" },
...props.sx,
}}
/>
Expand Down
Loading