diff --git a/site/src/components/RichParameterInput/RichParameterInput.stories.tsx b/site/src/components/RichParameterInput/RichParameterInput.stories.tsx index 3ec838272e7c6..80ed2c9c8111e 100644 --- a/site/src/components/RichParameterInput/RichParameterInput.stories.tsx +++ b/site/src/components/RichParameterInput/RichParameterInput.stories.tsx @@ -374,3 +374,44 @@ export const SmallBasicWithDisplayName: Story = { size: "small", }, }; + +export const WithPreset: Story = { + args: { + value: "preset-value", + id: "project_name", + parameter: createTemplateVersionParameter({ + name: "project_name", + description: + "Customize the name of a Google Cloud project that will be created!", + }), + isPreset: true, + }, +}; + +export const WithPresetAndImmutable: Story = { + args: { + value: "preset-value", + id: "project_name", + parameter: createTemplateVersionParameter({ + name: "project_name", + description: + "Customize the name of a Google Cloud project that will be created!", + mutable: false, + }), + isPreset: true, + }, +}; + +export const WithPresetAndOptional: Story = { + args: { + value: "preset-value", + id: "project_name", + parameter: createTemplateVersionParameter({ + name: "project_name", + description: + "Customize the name of a Google Cloud project that will be created!", + required: false, + }), + isPreset: true, + }, +}; diff --git a/site/src/components/RichParameterInput/RichParameterInput.tsx b/site/src/components/RichParameterInput/RichParameterInput.tsx index 9919fca44b592..beaff8ca2772e 100644 --- a/site/src/components/RichParameterInput/RichParameterInput.tsx +++ b/site/src/components/RichParameterInput/RichParameterInput.tsx @@ -1,5 +1,6 @@ import type { Interpolation, Theme } from "@emotion/react"; import ErrorOutline from "@mui/icons-material/ErrorOutline"; +import SettingsIcon from "@mui/icons-material/Settings"; import Button from "@mui/material/Button"; import FormControlLabel from "@mui/material/FormControlLabel"; import FormHelperText from "@mui/material/FormHelperText"; @@ -122,9 +123,10 @@ const styles = { export interface ParameterLabelProps { parameter: TemplateVersionParameter; + isPreset?: boolean; } -const ParameterLabel: FC = ({ parameter }) => { +const ParameterLabel: FC = ({ parameter, isPreset }) => { const hasDescription = parameter.description && parameter.description !== ""; const displayName = parameter.display_name ? parameter.display_name @@ -146,6 +148,13 @@ const ParameterLabel: FC = ({ parameter }) => { )} + {isPreset && ( + + }> + Preset + + + )} ); @@ -187,6 +196,7 @@ export type RichParameterInputProps = Omit< parameterAutofill?: AutofillBuildParameter; onChange: (value: string) => void; size?: Size; + isPreset?: boolean; }; const autofillDescription: Partial> = { @@ -198,6 +208,7 @@ export const RichParameterInput: FC = ({ parameter, parameterAutofill, onChange, + isPreset, ...fieldProps }) => { const autofillSource = parameterAutofill?.source; @@ -211,7 +222,7 @@ export const RichParameterInput: FC = ({ className={size} data-testid={`parameter-field-${parameter.name}`} > - +
{ + const canvas = within(canvasElement); + // Select a preset + await userEvent.click(canvas.getByLabelText("Preset")); + await userEvent.click(canvas.getByText("Preset 1")); + }, +}; + +export const PresetSelectedWithVisibleParameters: Story = { + args: PresetsButNoneSelected.args, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + // Select a preset + await userEvent.click(canvas.getByLabelText("Preset")); + await userEvent.click(canvas.getByText("Preset 1")); + // Toggle off the show preset parameters switch + await userEvent.click(canvas.getByLabelText("Show preset parameters")); + }, +}; + export const PresetReselected: Story = { args: PresetsButNoneSelected.args, play: async ({ canvasElement }) => { diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx index 34917fe14b058..6dab8de306a10 100644 --- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx +++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx @@ -1,4 +1,5 @@ import type { Interpolation, Theme } from "@emotion/react"; +import FormControlLabel from "@mui/material/FormControlLabel"; import FormHelperText from "@mui/material/FormHelperText"; import TextField from "@mui/material/TextField"; import type * as TypesGen from "api/typesGenerated"; @@ -24,6 +25,7 @@ import { Pill } from "components/Pill/Pill"; import { RichParameterInput } from "components/RichParameterInput/RichParameterInput"; import { Spinner } from "components/Spinner/Spinner"; import { Stack } from "components/Stack/Stack"; +import { Switch } from "components/Switch/Switch"; import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete"; import { type FormikContextType, useFormik } from "formik"; import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName"; @@ -101,6 +103,7 @@ export const CreateWorkspacePageView: FC = ({ const [suggestedName, setSuggestedName] = useState(() => generateWorkspaceName(), ); + const [showPresetParameters, setShowPresetParameters] = useState(false); const rerollSuggestedName = useCallback(() => { setSuggestedName(() => generateWorkspaceName()); @@ -273,33 +276,6 @@ export const CreateWorkspacePageView: FC = ({ )} - {presets.length > 0 && ( - - - - Select a preset to get started - - - - - { - const index = presetOptions.findIndex( - (preset) => preset.value === option?.value, - ); - if (index === -1) { - return; - } - setSelectedPresetIndex(index); - }} - placeholder="Select a preset" - selectedOption={presetOptions[selectedPresetIndex]} - /> - - - )}
= ({ hence they require additional vertical spacing for better readability and user experience. */} + {presets.length > 0 && ( + + + + Select a preset to get started + + + + + + { + const index = presetOptions.findIndex( + (preset) => preset.value === option?.value, + ); + if (index === -1) { + return; + } + setSelectedPresetIndex(index); + }} + placeholder="Select a preset" + selectedOption={presetOptions[selectedPresetIndex]} + /> + +
+ + +
+
+
+ )} + {parameters.map((parameter, index) => { const parameterField = `rich_parameter_values.${index}`; const parameterInputName = `${parameterField}.value`; + const isPresetParameter = presetParameterNames.includes( + parameter.name, + ); const isDisabled = disabledParams?.includes( parameter.name.toLowerCase().replace(/ /g, "_"), ) || creatingWorkspace || - presetParameterNames.includes(parameter.name); + isPresetParameter; + + // Hide preset parameters if showPresetParameters is false + if (!showPresetParameters && isPresetParameter) { + return null; + } return ( - { - await form.setFieldValue(parameterField, { - name: parameter.name, - value, - }); - }} - key={parameter.name} - parameter={parameter} - parameterAutofill={autofillByName[parameter.name]} - disabled={isDisabled} - /> +
+ { + await form.setFieldValue(parameterField, { + name: parameter.name, + value, + }); + }} + parameter={parameter} + parameterAutofill={autofillByName[parameter.name]} + disabled={isDisabled} + isPreset={isPresetParameter} + /> +
); })}
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