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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy