mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
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="https://github.com/user-attachments/assets/b8e4ed37-9c59-499f-b4e3-7aaca847eaa1" /> Related to `CreateWorkspacePageView` changes: https://github.com/coder/coder/pull/19063
This commit is contained in:
@@ -5,16 +5,10 @@ import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import { Avatar } from "components/Avatar/Avatar";
|
||||
import { Badge } from "components/Badge/Badge";
|
||||
import { Button } from "components/Button/Button";
|
||||
import { Combobox } from "components/Combobox/Combobox";
|
||||
import { Input } from "components/Input/Input";
|
||||
import { Label } from "components/Label/Label";
|
||||
import { Link } from "components/Link/Link";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "components/Select/Select";
|
||||
import { Spinner } from "components/Spinner/Spinner";
|
||||
import { Switch } from "components/Switch/Switch";
|
||||
import {
|
||||
@@ -186,30 +180,31 @@ export const CreateWorkspacePageViewExperimental: FC<
|
||||
}, [form.submitCount, form.errors]);
|
||||
|
||||
const [presetOptions, setPresetOptions] = useState([
|
||||
{ label: "None", value: "None" },
|
||||
{ displayName: "None", value: "undefined", icon: "", description: "" },
|
||||
]);
|
||||
useEffect(() => {
|
||||
setPresetOptions([
|
||||
{ label: "None", value: "None" },
|
||||
...presets.map((preset) => ({
|
||||
label: preset.Default ? `${preset.Name} (Default)` : preset.Name,
|
||||
value: preset.ID,
|
||||
})),
|
||||
]);
|
||||
}, [presets]);
|
||||
|
||||
const [selectedPresetIndex, setSelectedPresetIndex] = useState(0);
|
||||
|
||||
// Set default preset when presets are loaded
|
||||
// Build options and keep default label/value in sync
|
||||
useEffect(() => {
|
||||
const defaultPreset = presets.find((preset) => preset.Default);
|
||||
const options = [
|
||||
{ displayName: "None", value: "undefined", icon: "", description: "" },
|
||||
...presets.map((preset) => ({
|
||||
displayName: preset.Default ? `${preset.Name} (Default)` : preset.Name,
|
||||
value: preset.ID,
|
||||
icon: preset.Icon,
|
||||
description: preset.Description,
|
||||
})),
|
||||
];
|
||||
setPresetOptions(options);
|
||||
const defaultPreset = presets.find((p) => p.Default);
|
||||
if (defaultPreset) {
|
||||
// +1 because "None" is at index 0
|
||||
const defaultIndex =
|
||||
presets.findIndex((preset) => preset.ID === defaultPreset.ID) + 1;
|
||||
setSelectedPresetIndex(defaultIndex);
|
||||
const idx = presets.indexOf(defaultPreset) + 1; // +1 for "None"
|
||||
setSelectedPresetIndex(idx);
|
||||
form.setFieldValue("template_version_preset_id", defaultPreset.ID);
|
||||
} else {
|
||||
setSelectedPresetIndex(0); // Explicitly set to "None"
|
||||
form.setFieldValue("template_version_preset_id", undefined);
|
||||
}
|
||||
}, [presets]);
|
||||
}, [presets, form.setFieldValue]);
|
||||
|
||||
const [presetParameterNames, setPresetParameterNames] = useState<string[]>(
|
||||
[],
|
||||
@@ -572,11 +567,15 @@ export const CreateWorkspacePageViewExperimental: FC<
|
||||
</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="max-w-lg">
|
||||
<Select
|
||||
value={presetOptions[selectedPresetIndex]?.value}
|
||||
onValueChange={(option) => {
|
||||
<Combobox
|
||||
value={
|
||||
presetOptions[selectedPresetIndex]?.displayName || ""
|
||||
}
|
||||
options={presetOptions}
|
||||
placeholder="Select a preset"
|
||||
onSelect={(value) => {
|
||||
const index = presetOptions.findIndex(
|
||||
(preset) => preset.value === option,
|
||||
(preset) => preset.value === value,
|
||||
);
|
||||
if (index === -1) {
|
||||
return;
|
||||
@@ -584,21 +583,14 @@ export const CreateWorkspacePageViewExperimental: FC<
|
||||
setSelectedPresetIndex(index);
|
||||
form.setFieldValue(
|
||||
"template_version_preset_id",
|
||||
index === 0 ? undefined : option,
|
||||
// "undefined" string is equivalent to using None option
|
||||
// Combobox requires a value in order to correctly highlight the None option
|
||||
presetOptions[index].value === "undefined"
|
||||
? undefined
|
||||
: presetOptions[index].value,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={"Select a preset"} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{presetOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
/>
|
||||
</div>
|
||||
{/* Only show the preset parameter visibility toggle if preset parameters are actually being modified, otherwise it is ineffectual */}
|
||||
{presetParameterNames.length > 0 && (
|
||||
|
||||
Reference in New Issue
Block a user