mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
* feat: Improve navbar to be more compact The navbar was unnecessarily large before, which made the UI feel a bit bloaty from my perspective. * Attempt to remove overrides * Update theme * Add text field * Update theme to dark! * Fix import ordering * Fix page location * Fix requested changes * Add storybook for workspaces page view * Add empty view * Add tests for empty view * Remove templates page * Fix local port * Remove templates from nav * Fix e2e test * Remove time.ts * Remove dep * Add background color to margins * Merge status checking from workspace page * Fix requested changes * Fix workspace status tests
146 lines
4.1 KiB
TypeScript
146 lines
4.1 KiB
TypeScript
import Box from "@material-ui/core/Box"
|
|
import Button from "@material-ui/core/Button"
|
|
import { makeStyles } from "@material-ui/core/styles"
|
|
import Typography from "@material-ui/core/Typography"
|
|
import React from "react"
|
|
import { Link } from "react-router-dom"
|
|
import * as TypesGen from "../../api/typesGenerated"
|
|
import { TitleIconSize } from "../../theme/constants"
|
|
import { combineClasses } from "../../util/combineClasses"
|
|
import { WorkspaceStatus } from "../../util/workspace"
|
|
import { Stack } from "../Stack/Stack"
|
|
import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"
|
|
|
|
export const Language = {
|
|
stop: "Stop",
|
|
start: "Start",
|
|
retry: "Retry",
|
|
update: "Update",
|
|
settings: "Settings",
|
|
started: "Running",
|
|
stopped: "Stopped",
|
|
starting: "Building",
|
|
stopping: "Stopping",
|
|
canceled: "Canceled",
|
|
queued: "Queued",
|
|
error: "Build Failed",
|
|
loading: "Loading Status",
|
|
deleting: "Deleting",
|
|
deleted: "Deleted",
|
|
// "Canceling" would be misleading because it refers to a build, not the workspace.
|
|
// So just stall. When it is canceled it will appear as the error workspaceStatus.
|
|
canceling: "Loading Status",
|
|
}
|
|
|
|
export interface WorkspaceStatusBarProps {
|
|
organization?: TypesGen.Organization
|
|
workspace: TypesGen.Workspace
|
|
template?: TypesGen.Template
|
|
handleStart: () => void
|
|
handleStop: () => void
|
|
handleRetry: () => void
|
|
handleUpdate: () => void
|
|
workspaceStatus: WorkspaceStatus
|
|
}
|
|
|
|
/**
|
|
* Jobs submitted while another job is in progress will be discarded,
|
|
* so check whether workspace job status has reached completion (whether successful or not).
|
|
*/
|
|
const canAcceptJobs = (workspaceStatus: WorkspaceStatus) =>
|
|
["started", "stopped", "deleted", "error", "canceled"].includes(workspaceStatus)
|
|
|
|
/**
|
|
* Component for the header at the top of the workspace page
|
|
*/
|
|
export const WorkspaceStatusBar: React.FC<WorkspaceStatusBarProps> = ({
|
|
workspace,
|
|
handleStart,
|
|
handleStop,
|
|
handleRetry,
|
|
handleUpdate,
|
|
workspaceStatus,
|
|
}) => {
|
|
const styles = useStyles()
|
|
|
|
const settingsLink = "edit"
|
|
|
|
return (
|
|
<WorkspaceSection>
|
|
<Stack spacing={1}>
|
|
<div className={combineClasses([styles.horizontal, styles.reverse])}>
|
|
<div className={styles.horizontal}>
|
|
<Link className={styles.link} to={settingsLink}>
|
|
{Language.settings}
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
|
|
<div className={styles.horizontal}>
|
|
<div className={styles.horizontal}>
|
|
<Typography variant="h4">{workspace.name}</Typography>
|
|
<Box className={styles.statusChip} role="status">
|
|
{Language[workspaceStatus]}
|
|
</Box>
|
|
</div>
|
|
|
|
<div className={styles.horizontal}>
|
|
{workspaceStatus === "started" && (
|
|
<Button onClick={handleStop} color="primary">
|
|
{Language.stop}
|
|
</Button>
|
|
)}
|
|
{workspaceStatus === "stopped" && (
|
|
<Button onClick={handleStart} color="primary">
|
|
{Language.start}
|
|
</Button>
|
|
)}
|
|
{workspaceStatus === "error" && (
|
|
<Button onClick={handleRetry} color="primary">
|
|
{Language.retry}
|
|
</Button>
|
|
)}
|
|
|
|
{workspace.outdated && canAcceptJobs(workspaceStatus) && (
|
|
<Button onClick={handleUpdate} color="primary">
|
|
{Language.update}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</Stack>
|
|
</WorkspaceSection>
|
|
)
|
|
}
|
|
|
|
const useStyles = makeStyles((theme) => {
|
|
return {
|
|
link: {
|
|
textDecoration: "none",
|
|
color: theme.palette.text.primary,
|
|
},
|
|
icon: {
|
|
width: TitleIconSize,
|
|
height: TitleIconSize,
|
|
},
|
|
horizontal: {
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
gap: theme.spacing(2),
|
|
},
|
|
reverse: {
|
|
flexDirection: "row-reverse",
|
|
},
|
|
statusChip: {
|
|
border: `solid 1px ${theme.palette.text.hint}`,
|
|
borderRadius: theme.shape.borderRadius,
|
|
padding: theme.spacing(1),
|
|
},
|
|
vertical: {
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
},
|
|
}
|
|
})
|