Skip to content

Commit 022e400

Browse files
committed
Finish design
1 parent ba975a9 commit 022e400

File tree

3 files changed

+194
-38
lines changed

3 files changed

+194
-38
lines changed

site/src/components/HorizontalForm/HorizontalForm.tsx

Lines changed: 77 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,84 @@ import {
44
FormFooter as BaseFormFooter,
55
} from "components/FormFooter/FormFooter"
66
import { Stack } from "components/Stack/Stack"
7-
import { FC, HTMLProps, PropsWithChildren } from "react"
7+
import {
8+
createContext,
9+
FC,
10+
HTMLProps,
11+
PropsWithChildren,
12+
useContext,
13+
} from "react"
814
import { combineClasses } from "util/combineClasses"
915

10-
export const HorizontalForm: FC<
11-
PropsWithChildren & HTMLProps<HTMLFormElement>
12-
> = ({ children, ...formProps }) => {
16+
type FormContextValue = { direction?: "horizontal" | "vertical" }
17+
18+
const FormContext = createContext<FormContextValue>({
19+
direction: "horizontal",
20+
})
21+
22+
type FormProps = HTMLProps<HTMLFormElement> & {
23+
direction?: FormContextValue["direction"]
24+
}
25+
26+
export const Form: FC<FormProps> = ({ direction, className, ...formProps }) => {
1327
const styles = useStyles()
1428

1529
return (
16-
<form {...formProps}>
17-
<Stack direction="column" spacing={10} className={styles.formSections}>
18-
{children}
19-
</Stack>
20-
</form>
30+
<FormContext.Provider value={{ direction }}>
31+
<form
32+
{...formProps}
33+
className={combineClasses([styles.form, className])}
34+
/>
35+
</FormContext.Provider>
36+
)
37+
}
38+
39+
export const HorizontalForm: FC<HTMLProps<HTMLFormElement>> = ({
40+
children,
41+
...formProps
42+
}) => {
43+
return (
44+
<Form direction="horizontal" {...formProps}>
45+
{children}
46+
</Form>
47+
)
48+
}
49+
50+
export const VerticalForm: FC<HTMLProps<HTMLFormElement>> = ({
51+
children,
52+
...formProps
53+
}) => {
54+
return (
55+
<Form direction="vertical" {...formProps}>
56+
{children}
57+
</Form>
2158
)
2259
}
2360

2461
export const FormSection: FC<
2562
PropsWithChildren & {
26-
title: string
63+
title: string | JSX.Element
2764
description: string | JSX.Element
28-
className?: string
65+
classes?: {
66+
root?: string
67+
infoTitle?: string
68+
}
2969
}
30-
> = ({ children, title, description, className }) => {
31-
const styles = useStyles()
70+
> = ({ children, title, description, classes = {} }) => {
71+
const formContext = useContext(FormContext)
72+
const styles = useStyles(formContext)
3273

3374
return (
34-
<div className={combineClasses([styles.formSection, className])}>
75+
<div className={combineClasses([styles.formSection, classes.root])}>
3576
<div className={styles.formSectionInfo}>
36-
<h2 className={styles.formSectionInfoTitle}>{title}</h2>
77+
<h2
78+
className={combineClasses([
79+
styles.formSectionInfoTitle,
80+
classes.infoTitle,
81+
])}
82+
>
83+
{title}
84+
</h2>
3785
<div className={styles.formSectionInfoDescription}>{description}</div>
3886
</div>
3987

@@ -62,7 +110,12 @@ export const FormFooter: FC<BaseFormFooterProps> = (props) => {
62110
}
63111

64112
const useStyles = makeStyles((theme) => ({
65-
formSections: {
113+
form: {
114+
display: "flex",
115+
flexDirection: "column",
116+
gap: ({ direction }: FormContextValue = {}) =>
117+
direction === "horizontal" ? theme.spacing(10) : theme.spacing(5),
118+
66119
[theme.breakpoints.down("sm")]: {
67120
gap: theme.spacing(8),
68121
},
@@ -71,7 +124,10 @@ const useStyles = makeStyles((theme) => ({
71124
formSection: {
72125
display: "flex",
73126
alignItems: "flex-start",
74-
gap: theme.spacing(15),
127+
gap: ({ direction }: FormContextValue = {}) =>
128+
direction === "horizontal" ? theme.spacing(15) : theme.spacing(3),
129+
flexDirection: ({ direction }: FormContextValue = {}) =>
130+
direction === "horizontal" ? "row" : "column",
75131

76132
[theme.breakpoints.down("sm")]: {
77133
flexDirection: "column",
@@ -80,9 +136,11 @@ const useStyles = makeStyles((theme) => ({
80136
},
81137

82138
formSectionInfo: {
83-
width: 312,
139+
maxWidth: ({ direction }: FormContextValue = {}) =>
140+
direction === "horizontal" ? 312 : undefined,
84141
flexShrink: 0,
85-
position: "sticky",
142+
position: ({ direction }: FormContextValue = {}) =>
143+
direction === "horizontal" ? "sticky" : undefined,
86144
top: theme.spacing(3),
87145

88146
[theme.breakpoints.down("sm")]: {

site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ export const CreateWorkspacePageView: FC<
338338
props.templateParameters.filter((p) => !p.mutable).length > 0 && (
339339
<FormSection
340340
title="Immutable parameters"
341-
className={styles.warningSection}
341+
classes={{ root: styles.warningSection }}
342342
description={
343343
<>
344344
Those values are also parameters provided from your Terraform

site/src/pages/WorkspacePage/UpdateBuildParametersDialog.tsx

Lines changed: 116 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,23 @@ import { FC } from "react"
88
import { getFormHelpers } from "util/formUtils"
99
import {
1010
FormFields,
11-
FormFooter,
11+
FormSection,
12+
VerticalForm,
1213
} from "components/HorizontalForm/HorizontalForm"
1314
import {
1415
TemplateVersionParameter,
1516
WorkspaceBuildParameter,
1617
} from "api/typesGenerated"
1718
import { RichParameterInput } from "components/RichParameterInput/RichParameterInput"
18-
import { Stack } from "components/Stack/Stack"
1919
import { useFormik } from "formik"
2020
import {
2121
selectInitialRichParametersValues,
2222
ValidationSchemaForRichParameters,
2323
} from "util/richParameters"
2424
import * as Yup from "yup"
25+
import DialogActions from "@material-ui/core/DialogActions"
26+
import Button from "@material-ui/core/Button"
27+
import InfoOutlined from "@material-ui/icons/InfoOutlined"
2528

2629
export type UpdateBuildParametersDialogProps = DialogProps & {
2730
onClose: () => void
@@ -50,23 +53,75 @@ export const UpdateBuildParametersDialog: FC<
5053
const getFieldHelpers = getFormHelpers(form)
5154

5255
return (
53-
<Dialog {...dialogProps} aria-labelledby="update-build-parameters-title">
56+
<Dialog
57+
{...dialogProps}
58+
scroll="body"
59+
aria-labelledby="update-build-parameters-title"
60+
maxWidth="xs"
61+
>
5462
<DialogTitle
5563
id="update-build-parameters-title"
5664
classes={{ root: styles.title }}
5765
>
58-
Missing workspace parameters
66+
Workspace parameters
5967
</DialogTitle>
6068
<DialogContent className={styles.content}>
61-
<DialogContentText className={styles.contentText}>
69+
<DialogContentText className={styles.info}>
6270
It looks like the new version has some mandatory parameters that need
6371
to be filled in to update the workspace.
6472
</DialogContentText>
65-
<form className={styles.form} onSubmit={form.handleSubmit}>
66-
<Stack spacing={5}>
73+
<VerticalForm
74+
className={styles.form}
75+
onSubmit={form.handleSubmit}
76+
id="updateParameters"
77+
>
78+
{parameters && parameters.filter((p) => p.mutable).length > 0 && (
6779
<FormFields>
68-
{parameters &&
69-
parameters.map((parameter, index) => {
80+
{parameters.map((parameter, index) => {
81+
if (!parameter.mutable) {
82+
return <></>
83+
}
84+
85+
return (
86+
<RichParameterInput
87+
{...getFieldHelpers(
88+
"rich_parameter_values[" + index + "].value",
89+
)}
90+
key={parameter.name}
91+
parameter={parameter}
92+
initialValue=""
93+
index={index}
94+
onChange={async (value) => {
95+
await form.setFieldValue(
96+
"rich_parameter_values." + index,
97+
{
98+
name: parameter.name,
99+
value: value,
100+
},
101+
)
102+
}}
103+
/>
104+
)
105+
})}
106+
</FormFields>
107+
)}
108+
{parameters && parameters.filter((p) => !p.mutable).length > 0 && (
109+
<FormSection
110+
title={
111+
<>
112+
<InfoOutlined className={styles.warningIcon} />
113+
Immutable parameters
114+
</>
115+
}
116+
classes={{ infoTitle: styles.infoTitle }}
117+
description="These parameters values are immutable and cannot be changed after the update."
118+
>
119+
<FormFields>
120+
{parameters.map((parameter, index) => {
121+
if (parameter.mutable) {
122+
return <></>
123+
}
124+
70125
return (
71126
<RichParameterInput
72127
{...getFieldHelpers(
@@ -88,18 +143,31 @@ export const UpdateBuildParametersDialog: FC<
88143
/>
89144
)
90145
})}
91-
</FormFields>
92-
<FormFooter onCancel={dialogProps.onClose} isLoading={false} />
93-
</Stack>
94-
</form>
146+
</FormFields>
147+
</FormSection>
148+
)}
149+
</VerticalForm>
95150
</DialogContent>
151+
<DialogActions disableSpacing className={styles.dialogActions}>
152+
<Button
153+
fullWidth
154+
type="button"
155+
variant="outlined"
156+
onClick={dialogProps.onClose}
157+
>
158+
Cancel
159+
</Button>
160+
<Button color="primary" fullWidth type="submit" form="updateParameters">
161+
Update
162+
</Button>
163+
</DialogActions>
96164
</Dialog>
97165
)
98166
}
99167

100168
const useStyles = makeStyles((theme) => ({
101169
title: {
102-
padding: theme.spacing(5, 5, 2, 5),
170+
padding: theme.spacing(3, 5),
103171

104172
"& h2": {
105173
fontSize: theme.spacing(2.5),
@@ -108,15 +176,45 @@ const useStyles = makeStyles((theme) => ({
108176
},
109177

110178
content: {
111-
padding: theme.spacing(0, 5, 5, 5),
179+
padding: theme.spacing(0, 5, 0, 5),
112180
},
113181

114-
contentText: {
115-
fontSize: theme.spacing(2),
182+
info: {
183+
fontSize: theme.spacing(1.75),
116184
lineHeight: "160%",
185+
backgroundColor: theme.palette.info.dark,
186+
color: theme.palette.text.primary,
187+
border: `1px solid ${theme.palette.info.light}`,
188+
borderRight: 0,
189+
borderLeft: 0,
190+
padding: theme.spacing(3, 5),
191+
margin: theme.spacing(0, -5),
117192
},
118193

119194
form: {
120-
marginTop: theme.spacing(4),
195+
paddingTop: theme.spacing(5),
196+
},
197+
198+
infoTitle: {
199+
fontSize: theme.spacing(2),
200+
fontWeight: 600,
201+
display: "flex",
202+
alignItems: "center",
203+
gap: theme.spacing(1),
204+
},
205+
206+
warningIcon: {
207+
color: theme.palette.warning.light,
208+
fontSize: theme.spacing(1.5),
209+
},
210+
211+
formFooter: {
212+
flexDirection: "column",
213+
},
214+
215+
dialogActions: {
216+
padding: theme.spacing(5),
217+
flexDirection: "column",
218+
gap: theme.spacing(1),
121219
},
122220
}))

0 commit comments

Comments
 (0)