Skip to content

Commit 96e32d6

Browse files
authored
chore(site): add preset combobox to dynamic parameters page (#19100)
## Description This PR updates the `CreateWorkspacePageViewExperimental` page to use the `Combobox` React component for preset selection. This aligns it with the implementation used in the standard `CreateWorkspacePageView`, ensuring consistency in UI behavior and component usage across both pages. <img width="2084" height="792" alt="Screenshot 2025-07-30 at 13 58 23" src="/api/flow.js?q=https%3A%2F%2Fgithub.com%2Fcoder%2Fcoder%2Fcommit%2F%253Ca%2520href%3D"https://github.com/user-attachments/assets/b8e4ed37-9c59-499f-b4e3-7aaca847eaa1">https://github.com/user-attachments/assets/b8e4ed37-9c59-499f-b4e3-7aaca847eaa1" /> Related to `CreateWorkspacePageView` changes: #19063
1 parent 998fbdf commit 96e32d6

File tree

1 file changed

+33
-41
lines changed

1 file changed

+33
-41
lines changed

site/src/pages/CreateWorkspacePage/CreateWorkspacePageViewExperimental.tsx

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,10 @@ import { ErrorAlert } from "components/Alert/ErrorAlert";
55
import { Avatar } from "components/Avatar/Avatar";
66
import { Badge } from "components/Badge/Badge";
77
import { Button } from "components/Button/Button";
8+
import { Combobox } from "components/Combobox/Combobox";
89
import { Input } from "components/Input/Input";
910
import { Label } from "components/Label/Label";
1011
import { Link } from "components/Link/Link";
11-
import {
12-
Select,
13-
SelectContent,
14-
SelectItem,
15-
SelectTrigger,
16-
SelectValue,
17-
} from "components/Select/Select";
1812
import { Spinner } from "components/Spinner/Spinner";
1913
import { Switch } from "components/Switch/Switch";
2014
import {
@@ -186,30 +180,31 @@ export const CreateWorkspacePageViewExperimental: FC<
186180
}, [form.submitCount, form.errors]);
187181

188182
const [presetOptions, setPresetOptions] = useState([
189-
{ label: "None", value: "None" },
183+
{ displayName: "None", value: "undefined", icon: "", description: "" },
190184
]);
185+
const [selectedPresetIndex, setSelectedPresetIndex] = useState(0);
186+
// Build options and keep default label/value in sync
191187
useEffect(() => {
192-
setPresetOptions([
193-
{ label: "None", value: "None" },
188+
const options = [
189+
{ displayName: "None", value: "undefined", icon: "", description: "" },
194190
...presets.map((preset) => ({
195-
label: preset.Default ? `${preset.Name} (Default)` : preset.Name,
191+
displayName: preset.Default ? `${preset.Name} (Default)` : preset.Name,
196192
value: preset.ID,
193+
icon: preset.Icon,
194+
description: preset.Description,
197195
})),
198-
]);
199-
}, [presets]);
200-
201-
const [selectedPresetIndex, setSelectedPresetIndex] = useState(0);
202-
203-
// Set default preset when presets are loaded
204-
useEffect(() => {
205-
const defaultPreset = presets.find((preset) => preset.Default);
196+
];
197+
setPresetOptions(options);
198+
const defaultPreset = presets.find((p) => p.Default);
206199
if (defaultPreset) {
207-
// +1 because "None" is at index 0
208-
const defaultIndex =
209-
presets.findIndex((preset) => preset.ID === defaultPreset.ID) + 1;
210-
setSelectedPresetIndex(defaultIndex);
200+
const idx = presets.indexOf(defaultPreset) + 1; // +1 for "None"
201+
setSelectedPresetIndex(idx);
202+
form.setFieldValue("template_version_preset_id", defaultPreset.ID);
203+
} else {
204+
setSelectedPresetIndex(0); // Explicitly set to "None"
205+
form.setFieldValue("template_version_preset_id", undefined);
211206
}
212-
}, [presets]);
207+
}, [presets, form.setFieldValue]);
213208

214209
const [presetParameterNames, setPresetParameterNames] = useState<string[]>(
215210
[],
@@ -572,33 +567,30 @@ export const CreateWorkspacePageViewExperimental: FC<
572567
</div>
573568
<div className="flex flex-col gap-4">
574569
<div className="max-w-lg">
575-
<Select
576-
value={presetOptions[selectedPresetIndex]?.value}
577-
onValueChange={(option) => {
570+
<Combobox
571+
value={
572+
presetOptions[selectedPresetIndex]?.displayName || ""
573+
}
574+
options={presetOptions}
575+
placeholder="Select a preset"
576+
onSelect={(value) => {
578577
const index = presetOptions.findIndex(
579-
(preset) => preset.value === option,
578+
(preset) => preset.value === value,
580579
);
581580
if (index === -1) {
582581
return;
583582
}
584583
setSelectedPresetIndex(index);
585584
form.setFieldValue(
586585
"template_version_preset_id",
587-
index === 0 ? undefined : option,
586+
// "undefined" string is equivalent to using None option
587+
// Combobox requires a value in order to correctly highlight the None option
588+
presetOptions[index].value === "undefined"
589+
? undefined
590+
: presetOptions[index].value,
588591
);
589592
}}
590-
>
591-
<SelectTrigger>
592-
<SelectValue placeholder={"Select a preset"} />
593-
</SelectTrigger>
594-
<SelectContent>
595-
{presetOptions.map((option) => (
596-
<SelectItem key={option.value} value={option.value}>
597-
{option.label}
598-
</SelectItem>
599-
))}
600-
</SelectContent>
601-
</Select>
593+
/>
602594
</div>
603595
{/* Only show the preset parameter visibility toggle if preset parameters are actually being modified, otherwise it is ineffectual */}
604596
{presetParameterNames.length > 0 && (

0 commit comments

Comments
 (0)