Skip to content

Commit 0ba035a

Browse files
refactor(site): improve parameters field (#11802)
1 parent 4c71ccc commit 0ba035a

File tree

6 files changed

+141
-175
lines changed

6 files changed

+141
-175
lines changed

site/src/components/RichParameterInput/RichParameterInput.stories.tsx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const createTemplateVersionParameter = (
1919
name: "first_parameter",
2020
description: "This is first parameter.",
2121
type: "string",
22-
mutable: false,
22+
mutable: true,
2323
default_value: "default string",
2424
icon: "/icon/folder.svg",
2525
options: [],
@@ -47,6 +47,46 @@ export const Basic: Story = {
4747
},
4848
};
4949

50+
export const Optional: Story = {
51+
args: {
52+
value: "initial-value",
53+
id: "project_name",
54+
parameter: createTemplateVersionParameter({
55+
required: false,
56+
name: "project_name",
57+
description:
58+
"Customize the name of a Google Cloud project that will be created!",
59+
}),
60+
},
61+
};
62+
63+
export const Immutable: Story = {
64+
args: {
65+
value: "initial-value",
66+
id: "project_name",
67+
parameter: createTemplateVersionParameter({
68+
mutable: false,
69+
name: "project_name",
70+
description:
71+
"Customize the name of a Google Cloud project that will be created!",
72+
}),
73+
},
74+
};
75+
76+
export const WithError: Story = {
77+
args: {
78+
id: "number_parameter",
79+
parameter: createTemplateVersionParameter({
80+
name: "number_parameter",
81+
type: "number",
82+
description: "Numeric parameter",
83+
default_value: "",
84+
}),
85+
error: true,
86+
helperText: "Number must be greater than 5",
87+
},
88+
};
89+
5090
export const NumberType: Story = {
5191
args: {
5292
value: "4",

site/src/components/RichParameterInput/RichParameterInput.tsx

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { MemoizedMarkdown } from "components/Markdown/Markdown";
1010
import { Stack } from "components/Stack/Stack";
1111
import { MultiTextField } from "./MultiTextField";
1212
import { ExternalImage } from "components/ExternalImage/ExternalImage";
13+
import { Pill } from "components/Pill/Pill";
14+
import ErrorOutline from "@mui/icons-material/ErrorOutline";
1315

1416
const isBoolean = (parameter: TemplateVersionParameter) => {
1517
return parameter.type === "bool";
@@ -31,7 +33,11 @@ const styles = {
3133
labelPrimary: (theme) => ({
3234
fontSize: 16,
3335
color: theme.palette.text.primary,
34-
fontWeight: 600,
36+
fontWeight: 500,
37+
display: "flex",
38+
alignItems: "center",
39+
flexWrap: "wrap",
40+
gap: 8,
3541

3642
"& p": {
3743
margin: 0,
@@ -42,6 +48,11 @@ const styles = {
4248
fontSize: 14,
4349
},
4450
}),
51+
optionalLabel: (theme) => ({
52+
fontSize: 14,
53+
color: theme.palette.text.disabled,
54+
fontWeight: 500,
55+
}),
4556
textField: {
4657
".small & .MuiInputBase-root": {
4758
height: 36,
@@ -102,6 +113,25 @@ const ParameterLabel: FC<ParameterLabelProps> = ({ parameter }) => {
102113
? parameter.display_name
103114
: parameter.name;
104115

116+
const labelPrimary = (
117+
<span css={styles.labelPrimary}>
118+
{displayName}
119+
120+
{!parameter.required && (
121+
<Tooltip title="If no value is specified, the system will default to the value set by the administrator.">
122+
<span css={styles.optionalLabel}>(optional)</span>
123+
</Tooltip>
124+
)}
125+
{!parameter.mutable && (
126+
<Tooltip title="This value cannot be modified after the workspace has been created.">
127+
<Pill type="warning" icon={<ErrorOutline />}>
128+
Immutable
129+
</Pill>
130+
</Tooltip>
131+
)}
132+
</span>
133+
);
134+
105135
return (
106136
<label htmlFor={parameter.name}>
107137
<Stack direction="row" alignItems="center">
@@ -117,13 +147,13 @@ const ParameterLabel: FC<ParameterLabelProps> = ({ parameter }) => {
117147

118148
{hasDescription ? (
119149
<Stack spacing={0}>
120-
<span css={styles.labelPrimary}>{displayName}</span>
150+
{labelPrimary}
121151
<MemoizedMarkdown css={styles.labelCaption}>
122152
{parameter.description}
123153
</MemoizedMarkdown>
124154
</Stack>
125155
) : (
126-
<span css={styles.labelPrimary}>{displayName}</span>
156+
labelPrimary
127157
)}
128158
</Stack>
129159
</label>

site/src/components/TemplateParameters/TemplateParameters.tsx

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ export type TemplateParametersSectionProps = {
1414
) => Omit<RichParameterInputProps, "parameter" | "index">;
1515
} & Pick<ComponentProps<typeof FormSection>, "classes">;
1616

17-
export const MutableTemplateParametersSection: FC<
18-
TemplateParametersSectionProps
19-
> = ({ templateParameters, getInputProps, ...formSectionProps }) => {
17+
export const TemplateParametersSection: FC<TemplateParametersSectionProps> = ({
18+
templateParameters,
19+
getInputProps,
20+
...formSectionProps
21+
}) => {
2022
const hasMutableParameters =
2123
templateParameters.filter((p) => p.mutable).length > 0;
2224

@@ -45,40 +47,3 @@ export const MutableTemplateParametersSection: FC<
4547
</>
4648
);
4749
};
48-
49-
export const ImmutableTemplateParametersSection: FC<
50-
TemplateParametersSectionProps
51-
> = ({ templateParameters, getInputProps, ...formSectionProps }) => {
52-
const hasImmutableParameters =
53-
templateParameters.filter((p) => !p.mutable).length > 0;
54-
55-
return (
56-
<>
57-
{hasImmutableParameters && (
58-
<FormSection
59-
{...formSectionProps}
60-
title="Immutable parameters"
61-
description={
62-
<>
63-
These settings <strong>cannot be changed</strong> after creating
64-
the workspace.
65-
</>
66-
}
67-
>
68-
<FormFields>
69-
{templateParameters.map(
70-
(parameter, index) =>
71-
!parameter.mutable && (
72-
<RichParameterInput
73-
{...getInputProps(parameter, index)}
74-
key={parameter.name}
75-
parameter={parameter}
76-
/>
77-
),
78-
)}
79-
</FormFields>
80-
</FormSection>
81-
)}
82-
</>
83-
);
84-
};

site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx

Lines changed: 36 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { css } from "@emotion/css";
2-
import { useTheme, type Interpolation, type Theme } from "@emotion/react";
1+
import { type Interpolation, type Theme } from "@emotion/react";
32
import TextField from "@mui/material/TextField";
43
import type * as TypesGen from "api/typesGenerated";
54
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
@@ -21,10 +20,6 @@ import {
2120
getInitialRichParameterValues,
2221
useValidationSchemaForRichParameters,
2322
} from "utils/richParameters";
24-
import {
25-
ImmutableTemplateParametersSection,
26-
MutableTemplateParametersSection,
27-
} from "components/TemplateParameters/TemplateParameters";
2823
import { ErrorAlert } from "components/Alert/ErrorAlert";
2924
import { Stack } from "components/Stack/Stack";
3025
import {
@@ -44,6 +39,7 @@ import {
4439
PageHeaderSubtitle,
4540
} from "components/PageHeader/PageHeader";
4641
import { Pill } from "components/Pill/Pill";
42+
import { RichParameterInput } from "components/RichParameterInput/RichParameterInput";
4743

4844
export const Language = {
4945
duplicationWarning:
@@ -90,7 +86,6 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
9086
onSubmit,
9187
onCancel,
9288
}) => {
93-
const theme = useTheme();
9489
const [owner, setOwner] = useState(defaultOwner);
9590
const [searchParams] = useSearchParams();
9691
const disabledParamsList = searchParams?.get("disable_params")?.split(",");
@@ -222,65 +217,41 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
222217
</FormFields>
223218
</FormSection>
224219

225-
{parameters && (
226-
<>
227-
<MutableTemplateParametersSection
228-
templateParameters={parameters}
229-
getInputProps={(parameter, index) => {
230-
return {
231-
...getFieldHelpers(
232-
"rich_parameter_values[" + index + "].value",
233-
),
234-
onChange: async (value) => {
235-
await form.setFieldValue(
236-
"rich_parameter_values." + index,
237-
{
238-
name: parameter.name,
239-
value: value,
240-
},
241-
);
242-
},
243-
disabled:
244-
disabledParamsList?.includes(
245-
parameter.name.toLowerCase().replace(/ /g, "_"),
246-
) || creatingWorkspace,
247-
};
248-
}}
249-
/>
250-
<ImmutableTemplateParametersSection
251-
templateParameters={parameters}
252-
classes={{
253-
root: css`
254-
border: 1px solid ${theme.palette.warning.light};
255-
border-radius: 8px;
256-
background-color: ${theme.palette.background.paper};
257-
padding: 80px;
258-
margin-left: -80px;
259-
margin-right: -80px;
260-
`,
261-
}}
262-
getInputProps={(parameter, index) => {
263-
return {
264-
...getFieldHelpers(
265-
"rich_parameter_values[" + index + "].value",
266-
),
267-
onChange: async (value) => {
268-
await form.setFieldValue(
269-
"rich_parameter_values." + index,
270-
{
220+
{parameters.length > 0 && (
221+
<FormSection
222+
title="Parameters"
223+
description="These are the settings used by your template. Please note that immutable parameters cannot be modified once the workspace is created."
224+
>
225+
{/*
226+
Opted not to use FormFields in order to increase spacing.
227+
This decision was made because rich parameter inputs are more visually dense than standard text fields.
228+
*/}
229+
<div css={{ display: "flex", flexDirection: "column", gap: 36 }}>
230+
{parameters.map((parameter, index) => {
231+
const parameterField = `rich_parameter_values.${index}`;
232+
const parameterInputName = `${parameterField}.value`;
233+
const isDisabled =
234+
disabledParamsList?.includes(
235+
parameter.name.toLowerCase().replace(/ /g, "_"),
236+
) || creatingWorkspace;
237+
238+
return (
239+
<RichParameterInput
240+
{...getFieldHelpers(parameterInputName)}
241+
onChange={async (value) => {
242+
await form.setFieldValue(parameterField, {
271243
name: parameter.name,
272-
value: value,
273-
},
274-
);
275-
},
276-
disabled:
277-
disabledParamsList?.includes(
278-
parameter.name.toLowerCase().replace(/ /g, "_"),
279-
) || creatingWorkspace,
280-
};
281-
}}
282-
/>
283-
</>
244+
value,
245+
});
246+
}}
247+
key={parameter.name}
248+
parameter={parameter}
249+
disabled={isDisabled}
250+
/>
251+
);
252+
})}
253+
</div>
254+
</FormSection>
284255
)}
285256

286257
<FormFooter

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