feat: Workspace StatusBar (#1362)

* Move component and prep

* Make WorkspaceSection more reusable

* Lay out elements

* Layout tweaks

* Add outdated to Workspace type

* Fill out status bar component

* Format

* Add transition to types

* Add api handlers for build toggle

* Format

* Parallelize machine

* Lay out basics of build submachine

* Pipe start and stop events through - needs status

* Attempt at a machine

It's so big, but collapsing start and stop made it hard to distinguish retry from toggle

* Update mock

* Render status and buttons

* Fix type error on template page

* Move Settings

* Format

* Keep refreshed workspace

* Make it switch workspaces

* Lint

* Fix relative api path

* Test

* Fix polling

* Add loading workspace state

* Format

* Add stub settings page

* Format

* Lint

* Get rid of let

* Add update

* Make start use version id

Important for update

* Fix imports

* Add polling for outdated

* Rely on context instead of finite state for status

* Handle canceling

* Fix tests

* Format

* Display errors so users know when button presses didn't work

* Fix api typo, remove logging

* Lint

* Simplify type

Co-authored-by: G r e y <grey@coder.com>

* Add type, extract helper

Co-authored-by: G r e y <grey@coder.com>
This commit is contained in:
Presley Pizzo
2022-05-16 12:34:22 -04:00
committed by GitHub
parent e990a9ac28
commit b06ef0ae6e
17 changed files with 726 additions and 126 deletions

View File

@ -1,31 +1,51 @@
import Box from "@material-ui/core/Box"
import Paper from "@material-ui/core/Paper"
import { makeStyles } from "@material-ui/core/styles"
import Typography from "@material-ui/core/Typography"
import CloudCircleIcon from "@material-ui/icons/CloudCircle"
import React from "react"
import { Link } from "react-router-dom"
import * as TypesGen from "../../api/typesGenerated"
import { WorkspaceStatus } from "../../pages/WorkspacePage/WorkspacePage"
import { WorkspaceSchedule } from "../WorkspaceSchedule/WorkspaceSchedule"
import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"
import * as Constants from "./constants"
import { WorkspaceStatusBar } from "../WorkspaceStatusBar/WorkspaceStatusBar"
export interface WorkspaceProps {
organization: TypesGen.Organization
organization?: TypesGen.Organization
workspace: TypesGen.Workspace
template: TypesGen.Template
template?: TypesGen.Template
handleStart: () => void
handleStop: () => void
handleRetry: () => void
handleUpdate: () => void
workspaceStatus: WorkspaceStatus
}
/**
* Workspace is the top-level component for viewing an individual workspace
*/
export const Workspace: React.FC<WorkspaceProps> = ({ organization, template, workspace }) => {
export const Workspace: React.FC<WorkspaceProps> = ({
organization,
template,
workspace,
handleStart,
handleStop,
handleRetry,
handleUpdate,
workspaceStatus,
}) => {
const styles = useStyles()
return (
<div className={styles.root}>
<div className={styles.vertical}>
<WorkspaceHeader organization={organization} template={template} workspace={workspace} />
<WorkspaceStatusBar
organization={organization}
template={template}
workspace={workspace}
handleStart={handleStart}
handleStop={handleStop}
handleRetry={handleRetry}
handleUpdate={handleUpdate}
workspaceStatus={workspaceStatus}
/>
<div className={styles.horizontal}>
<div className={styles.sidebarContainer}>
<WorkspaceSection title="Applications">
@ -55,40 +75,6 @@ export const Workspace: React.FC<WorkspaceProps> = ({ organization, template, wo
)
}
/**
* Component for the header at the top of the workspace page
*/
export const WorkspaceHeader: React.FC<WorkspaceProps> = ({ organization, template, workspace }) => {
const styles = useStyles()
const templateLink = `/templates/${organization.name}/${template.name}`
return (
<Paper elevation={0} className={styles.section}>
<div className={styles.horizontal}>
<WorkspaceHeroIcon />
<div className={styles.vertical}>
<Typography variant="h4">{workspace.name}</Typography>
<Typography variant="body2" color="textSecondary">
<Link to={templateLink}>{template.name}</Link>
</Typography>
</div>
</div>
</Paper>
)
}
/**
* Component to render the 'Hero Icon' in the header of a workspace
*/
export const WorkspaceHeroIcon: React.FC = () => {
return (
<Box mr="1em">
<CloudCircleIcon width={Constants.TitleIconSize} height={Constants.TitleIconSize} />
</Box>
)
}
/**
* Temporary placeholder component until we have the sections implemented
* Can be removed once the Workspace page has all the necessary sections
@ -101,7 +87,7 @@ const Placeholder: React.FC = () => {
)
}
export const useStyles = makeStyles((theme) => {
export const useStyles = makeStyles(() => {
return {
root: {
display: "flex",
@ -115,12 +101,6 @@ export const useStyles = makeStyles((theme) => {
display: "flex",
flexDirection: "column",
},
section: {
border: `1px solid ${theme.palette.divider}`,
borderRadius: Constants.CardRadius,
padding: Constants.CardPadding,
margin: theme.spacing(1),
},
sidebarContainer: {
display: "flex",
flexDirection: "column",
@ -129,9 +109,5 @@ export const useStyles = makeStyles((theme) => {
timelineContainer: {
flex: 1,
},
icon: {
width: Constants.TitleIconSize,
height: Constants.TitleIconSize,
},
}
})