Skip to content

Commit f76e7b1

Browse files
refactor: Refactor create workspace page (#4862)
1 parent 86fc3e0 commit f76e7b1

File tree

12 files changed

+382
-135
lines changed

12 files changed

+382
-135
lines changed

site/src/components/FormCloseButton/FormCloseButton.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ const useStyles = makeStyles((theme) => ({
4747
"&:hover": {
4848
opacity: 1,
4949
},
50+
51+
[theme.breakpoints.down("sm")]: {
52+
top: theme.spacing(1),
53+
right: theme.spacing(1),
54+
},
5055
},
5156
label: {
5257
position: "absolute",
Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Button from "@material-ui/core/Button"
22
import { makeStyles } from "@material-ui/core/styles"
3+
import { ClassNameMap } from "@material-ui/core/styles/withStyles"
34
import { FC } from "react"
45
import { LoadingButton } from "../LoadingButton/LoadingButton"
56

@@ -8,36 +9,22 @@ export const Language = {
89
defaultSubmitLabel: "Submit",
910
}
1011

12+
type FormFooterStyles = ClassNameMap<"footer" | "button">
1113
export interface FormFooterProps {
1214
onCancel: () => void
1315
isLoading: boolean
16+
styles?: FormFooterStyles
1417
submitLabel?: string
1518
submitDisabled?: boolean
1619
}
1720

18-
const useStyles = makeStyles((theme) => ({
19-
footer: {
20-
display: "flex",
21-
flex: "0",
22-
// The first button is the submit so it is the first element to be focused
23-
// on tab so we use row-reverse to display it on the right
24-
flexDirection: "row-reverse",
25-
gap: theme.spacing(1.5),
26-
alignItems: "center",
27-
marginTop: theme.spacing(3),
28-
},
29-
button: {
30-
width: "100%",
31-
},
32-
}))
33-
34-
export const FormFooter: FC<React.PropsWithChildren<FormFooterProps>> = ({
21+
export const FormFooter: FC<FormFooterProps> = ({
3522
onCancel,
3623
isLoading,
37-
submitLabel = Language.defaultSubmitLabel,
3824
submitDisabled,
25+
submitLabel = Language.defaultSubmitLabel,
26+
styles = defaultStyles(),
3927
}) => {
40-
const styles = useStyles()
4128
return (
4229
<div className={styles.footer}>
4330
<LoadingButton
@@ -63,3 +50,19 @@ export const FormFooter: FC<React.PropsWithChildren<FormFooterProps>> = ({
6350
</div>
6451
)
6552
}
53+
54+
const defaultStyles = makeStyles((theme) => ({
55+
footer: {
56+
display: "flex",
57+
flex: "0",
58+
// The first button is the submit so it is the first element to be focused
59+
// on tab so we use row-reverse to display it on the right
60+
flexDirection: "row-reverse",
61+
gap: theme.spacing(1.5),
62+
alignItems: "center",
63+
marginTop: theme.spacing(3),
64+
},
65+
button: {
66+
width: "100%",
67+
},
68+
}))
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { FormCloseButton } from "../FormCloseButton/FormCloseButton"
2+
import { makeStyles } from "@material-ui/core/styles"
3+
import Typography from "@material-ui/core/Typography"
4+
import { Margins } from "components/Margins/Margins"
5+
import { FC, ReactNode } from "react"
6+
7+
export interface FormTitleProps {
8+
title: string
9+
detail?: ReactNode
10+
}
11+
12+
export interface FullPageHorizontalFormProps {
13+
title: string
14+
detail?: ReactNode
15+
onCancel: () => void
16+
}
17+
18+
export const FullPageHorizontalForm: FC<
19+
React.PropsWithChildren<FullPageHorizontalFormProps>
20+
> = ({ title, detail, onCancel, children }) => {
21+
const styles = useStyles()
22+
23+
return (
24+
<>
25+
<header className={styles.title}>
26+
<Margins size="medium">
27+
<Typography variant="h3">{title}</Typography>
28+
{detail && <Typography variant="caption">{detail}</Typography>}
29+
</Margins>
30+
</header>
31+
32+
<FormCloseButton onClose={onCancel} />
33+
34+
<main className={styles.main}>
35+
<Margins size="medium">{children}</Margins>
36+
</main>
37+
</>
38+
)
39+
}
40+
41+
const useStyles = makeStyles((theme) => ({
42+
title: {
43+
paddingTop: theme.spacing(6),
44+
paddingBottom: theme.spacing(8),
45+
46+
[theme.breakpoints.down("sm")]: {
47+
paddingTop: theme.spacing(4),
48+
paddingBottom: theme.spacing(4),
49+
},
50+
},
51+
52+
main: {
53+
paddingBottom: theme.spacing(10),
54+
},
55+
}))

site/src/components/Margins/Margins.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { makeStyles } from "@material-ui/core/styles"
22
import { FC } from "react"
3-
import { containerWidth, sidePadding } from "../../theme/constants"
3+
import {
4+
containerWidth,
5+
containerWidthMedium,
6+
sidePadding,
7+
} from "../../theme/constants"
48

59
type Size = "regular" | "medium" | "small"
610

711
const widthBySize: Record<Size, number> = {
812
regular: containerWidth,
9-
medium: containerWidth / 2,
13+
medium: containerWidthMedium,
1014
small: containerWidth / 3,
1115
}
1216

site/src/components/ParameterInput/ParameterInput.tsx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import TextField from "@material-ui/core/TextField"
77
import { Stack } from "components/Stack/Stack"
88
import { FC } from "react"
99
import { ParameterSchema } from "../../api/typesGenerated"
10-
import { MONOSPACE_FONT_FAMILY } from "../../theme/constants"
1110

1211
const isBoolean = (schema: ParameterSchema) => {
1312
return schema.validation_value_type === "bool"
@@ -16,12 +15,18 @@ const isBoolean = (schema: ParameterSchema) => {
1615
const ParameterLabel: React.FC<{ schema: ParameterSchema }> = ({ schema }) => {
1716
const styles = useStyles()
1817

19-
return (
20-
<label className={styles.label} htmlFor={schema.name}>
21-
<strong>var.{schema.name}</strong>
22-
{schema.description && (
18+
if (schema.name && schema.description) {
19+
return (
20+
<label htmlFor={schema.name}>
21+
<span className={styles.labelName}>var.{schema.name}</span>
2322
<span className={styles.labelDescription}>{schema.description}</span>
24-
)}
23+
</label>
24+
)
25+
}
26+
27+
return (
28+
<label htmlFor={schema.name}>
29+
<span className={styles.labelDescription}>var.{schema.name}</span>
2530
</label>
2631
)
2732
}
@@ -38,7 +43,7 @@ export const ParameterInput: FC<
3843
const styles = useStyles()
3944

4045
return (
41-
<Stack direction="column" className={styles.root}>
46+
<Stack direction="column" spacing={0.75}>
4247
<ParameterLabel schema={schema} />
4348
<div className={styles.input}>
4449
<ParameterField
@@ -119,19 +124,17 @@ const ParameterField: React.FC<
119124
}
120125

121126
const useStyles = makeStyles((theme) => ({
122-
root: {
123-
fontFamily: MONOSPACE_FONT_FAMILY,
124-
paddingTop: theme.spacing(2),
125-
paddingBottom: theme.spacing(2),
126-
},
127-
label: {
128-
display: "flex",
129-
flexDirection: "column",
130-
fontSize: 21,
127+
labelName: {
128+
fontSize: 14,
129+
color: theme.palette.text.secondary,
130+
display: "block",
131+
marginBottom: theme.spacing(0.5),
131132
},
132133
labelDescription: {
133-
fontSize: 14,
134-
marginTop: theme.spacing(1),
134+
fontSize: 16,
135+
color: theme.palette.text.primary,
136+
display: "block",
137+
fontWeight: 600,
135138
},
136139
input: {
137140
display: "flex",

site/src/components/WorkspaceQuota/WorkspaceQuota.tsx

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { AlertBanner } from "components/AlertBanner/AlertBanner"
66
import { Stack } from "components/Stack/Stack"
77
import { FC } from "react"
88
import * as TypesGen from "../../api/typesGenerated"
9-
import { MONOSPACE_FONT_FAMILY } from "../../theme/constants"
109

1110
export const Language = {
1211
of: "of",
@@ -27,7 +26,7 @@ export const WorkspaceQuota: FC<WorkspaceQuotaProps> = ({ quota, error }) => {
2726
return (
2827
<Box>
2928
<Stack spacing={1} className={styles.stack}>
30-
<span className={styles.title}>Workspace Quota</span>
29+
<span className={styles.title}>Usage Quota</span>
3130
<AlertBanner severity="error" error={error} />
3231
</Stack>
3332
</Box>
@@ -39,7 +38,7 @@ export const WorkspaceQuota: FC<WorkspaceQuotaProps> = ({ quota, error }) => {
3938
return (
4039
<Box>
4140
<Stack spacing={1} className={styles.stack}>
42-
<span className={styles.title}>Workspace Quota</span>
41+
<span className={styles.title}>Usage quota</span>
4342
<LinearProgress color="primary" />
4443
<div className={styles.label}>
4544
<Skeleton className={styles.skeleton} />
@@ -64,8 +63,23 @@ export const WorkspaceQuota: FC<WorkspaceQuotaProps> = ({ quota, error }) => {
6463

6564
return (
6665
<Box>
67-
<Stack spacing={1} className={styles.stack}>
68-
<span className={styles.title}>Workspace Quota</span>
66+
<Stack spacing={1.5} className={styles.stack}>
67+
<Stack direction="row" justifyContent="space-between">
68+
<span className={styles.title}>Usage Quota</span>
69+
<div className={styles.label}>
70+
<span className={styles.labelHighlight}>
71+
{quota.user_workspace_count}
72+
</span>{" "}
73+
{Language.of}{" "}
74+
<span className={styles.labelHighlight}>
75+
{quota.user_workspace_limit}
76+
</span>{" "}
77+
{quota.user_workspace_limit === 1
78+
? Language.workspace
79+
: Language.workspaces}
80+
{" used"}
81+
</div>
82+
</Stack>
6983
<LinearProgress
7084
className={
7185
quota.user_workspace_count >= quota.user_workspace_limit
@@ -75,14 +89,6 @@ export const WorkspaceQuota: FC<WorkspaceQuotaProps> = ({ quota, error }) => {
7589
value={value}
7690
variant="determinate"
7791
/>
78-
<div className={styles.label}>
79-
{quota.user_workspace_count} {Language.of}{" "}
80-
{quota.user_workspace_limit}{" "}
81-
{quota.user_workspace_limit === 1
82-
? Language.workspace
83-
: Language.workspaces}
84-
{" used"}
85-
</div>
8692
</Stack>
8793
</Box>
8894
)
@@ -101,18 +107,16 @@ const useStyles = makeStyles((theme) => ({
101107
},
102108
},
103109
title: {
104-
fontFamily: MONOSPACE_FONT_FAMILY,
105-
fontSize: 21,
106-
paddingBottom: "8px",
110+
fontSize: 16,
107111
},
108112
label: {
109-
fontFamily: MONOSPACE_FONT_FAMILY,
110-
fontSize: 12,
111-
textTransform: "uppercase",
113+
fontSize: 14,
112114
display: "block",
113-
fontWeight: 600,
114115
color: theme.palette.text.secondary,
115116
},
117+
labelHighlight: {
118+
color: theme.palette.text.primary,
119+
},
116120
skeleton: {
117121
minWidth: "150px",
118122
},
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"templateLabel": "Template",
3-
"nameLabel": "Name",
4-
"ownerLabel": "Workspace Owner"
3+
"nameLabel": "Workspace Name",
4+
"ownerLabel": "Owner",
5+
"createWorkspace": "Create workspace"
56
}

site/src/pages/CreateWorkspacePage/CreateWorkspacePage.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import { fireEvent, screen, waitFor } from "@testing-library/react"
33
import userEvent from "@testing-library/user-event"
44
import * as API from "api/api"
5-
import { Language as FooterLanguage } from "components/FormFooter/FormFooter"
65
import i18next from "i18next"
76
import {
87
MockTemplate,
@@ -17,6 +16,7 @@ import CreateWorkspacePage from "./CreateWorkspacePage"
1716
const { t } = i18next
1817

1918
const nameLabelText = t("nameLabel", { ns: "createWorkspacePage" })
19+
const createWorkspaceText = t("createWorkspace", { ns: "createWorkspacePage" })
2020

2121
const renderCreateWorkspacePage = () => {
2222
return renderWithAuth(<CreateWorkspacePage />, {
@@ -48,7 +48,7 @@ describe("CreateWorkspacePage", () => {
4848
target: { value: "test" },
4949
})
5050

51-
const submitButton = screen.getByText(FooterLanguage.defaultSubmitLabel)
51+
const submitButton = screen.getByText(createWorkspaceText)
5252
userEvent.click(submitButton)
5353

5454
await waitFor(() =>

site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ const CreateWorkspacePage: FC = () => {
2525
shallowEqual,
2626
)
2727
const workspaceQuotaEnabled = featureVisibility[FeatureNames.WorkspaceQuota]
28-
2928
const [authState] = useActor(xServices.authXService)
3029
const { me } = authState.context
3130
const [createWorkspaceState, send] = useMachine(createWorkspaceMachine, {
@@ -89,7 +88,8 @@ const CreateWorkspacePage: FC = () => {
8988
})
9089
}}
9190
onCancel={() => {
92-
navigate("/templates")
91+
// Go back
92+
navigate(-1)
9393
}}
9494
onSubmit={(request) => {
9595
send({

0 commit comments

Comments
 (0)