Skip to content

Commit 4209d7d

Browse files
committed
feat: setup autofill for dynamic parameters
1 parent 3011eca commit 4209d7d

File tree

2 files changed

+91
-14
lines changed

2 files changed

+91
-14
lines changed

site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,27 @@ import {
3232
TooltipProvider,
3333
TooltipTrigger,
3434
} from "components/Tooltip/Tooltip";
35-
import { Info, Settings, TriangleAlert } from "lucide-react";
35+
import { Info, Link, Settings, TriangleAlert } from "lucide-react";
3636
import { type FC, useEffect, useId, useState } from "react";
3737
import type { AutofillBuildParameter } from "utils/richParameters";
3838
import * as Yup from "yup";
3939

4040
export interface DynamicParameterProps {
4141
parameter: PreviewParameter;
42+
value?: string;
4243
onChange: (value: string) => void;
4344
disabled?: boolean;
4445
isPreset?: boolean;
46+
autofill?: AutofillBuildParameter;
4547
}
4648

4749
export const DynamicParameter: FC<DynamicParameterProps> = ({
4850
parameter,
51+
value,
4952
onChange,
5053
disabled,
5154
isPreset,
55+
autofill,
5256
}) => {
5357
const id = useId();
5458

@@ -57,13 +61,18 @@ export const DynamicParameter: FC<DynamicParameterProps> = ({
5761
className="flex flex-col gap-2"
5862
data-testid={`parameter-field-${parameter.name}`}
5963
>
60-
<ParameterLabel parameter={parameter} isPreset={isPreset} />
64+
<ParameterLabel
65+
parameter={parameter}
66+
isPreset={isPreset}
67+
autofill={autofill}
68+
/>
6169
<div className="max-w-lg">
6270
<ParameterField
71+
id={id}
6372
parameter={parameter}
73+
value={value}
6474
onChange={onChange}
6575
disabled={disabled}
66-
id={id}
6776
/>
6877
</div>
6978
{parameter.diagnostics.length > 0 && (
@@ -76,9 +85,14 @@ export const DynamicParameter: FC<DynamicParameterProps> = ({
7685
interface ParameterLabelProps {
7786
parameter: PreviewParameter;
7887
isPreset?: boolean;
88+
autofill?: AutofillBuildParameter;
7989
}
8090

81-
const ParameterLabel: FC<ParameterLabelProps> = ({ parameter, isPreset }) => {
91+
const ParameterLabel: FC<ParameterLabelProps> = ({
92+
parameter,
93+
isPreset,
94+
autofill,
95+
}) => {
8296
const hasDescription = parameter.description && parameter.description !== "";
8397
const displayName = parameter.display_name
8498
? parameter.display_name
@@ -137,6 +151,23 @@ const ParameterLabel: FC<ParameterLabelProps> = ({ parameter, isPreset }) => {
137151
</Tooltip>
138152
</TooltipProvider>
139153
)}
154+
{autofill && (
155+
<TooltipProvider delayDuration={100}>
156+
<Tooltip>
157+
<TooltipTrigger asChild>
158+
<span className="flex items-center">
159+
<Badge size="sm">
160+
<Link />
161+
URL Autofill
162+
</Badge>
163+
</span>
164+
</TooltipTrigger>
165+
<TooltipContent className="max-w-xs">
166+
Autofilled from the URL
167+
</TooltipContent>
168+
</Tooltip>
169+
</TooltipProvider>
170+
)}
140171
</Label>
141172

142173
{hasDescription && (
@@ -153,22 +184,27 @@ const ParameterLabel: FC<ParameterLabelProps> = ({ parameter, isPreset }) => {
153184

154185
interface ParameterFieldProps {
155186
parameter: PreviewParameter;
187+
value?: string;
156188
onChange: (value: string) => void;
157189
disabled?: boolean;
158190
id: string;
159191
}
160192

161193
const ParameterField: FC<ParameterFieldProps> = ({
162194
parameter,
195+
value,
163196
onChange,
164197
disabled,
165198
id,
166199
}) => {
167-
const value = validValue(parameter.value);
168-
const [localValue, setLocalValue] = useState(value);
200+
const initialValue =
201+
value !== undefined ? value : validValue(parameter.value);
202+
const [localValue, setLocalValue] = useState(initialValue);
169203

170204
useEffect(() => {
171-
setLocalValue(value);
205+
if (value !== undefined) {
206+
setLocalValue(value);
207+
}
172208
}, [value]);
173209

174210
switch (parameter.form_type) {
@@ -469,14 +505,14 @@ export const getInitialParameterValues = (
469505
({ name }) => name === parameter.name,
470506
);
471507

508+
const useAutofill =
509+
autofillParam &&
510+
isValidParameterOption(parameter, autofillParam) &&
511+
autofillParam.value;
512+
472513
return {
473514
name: parameter.name,
474-
value:
475-
autofillParam &&
476-
isValidParameterOption(parameter, autofillParam) &&
477-
autofillParam.value
478-
? autofillParam.value
479-
: validValue(parameter.value),
515+
value: useAutofill ? autofillParam.value : validValue(parameter.value),
480516
};
481517
});
482518
};
@@ -489,14 +525,41 @@ const isValidParameterOption = (
489525
previewParam: PreviewParameter,
490526
buildParam: WorkspaceBuildParameter,
491527
) => {
528+
if (previewParam.form_type === "multi-select") {
529+
console.log("buildParam.value", buildParam.value);
530+
let values: string[] = [];
531+
try {
532+
const parsed = JSON.parse(buildParam.value);
533+
if (Array.isArray(parsed)) {
534+
values = parsed;
535+
}
536+
} catch (e) {
537+
console.error(
538+
"Error parsing parameter value with form_type multi-select",
539+
e,
540+
);
541+
return false;
542+
}
543+
544+
// If options exist, validate each value
545+
if (previewParam.options.length > 0) {
546+
const validValues = previewParam.options.map(
547+
(option) => option.value.value,
548+
);
549+
return values.every((value) => validValues.includes(value));
550+
}
551+
return false;
552+
}
553+
// For parameters with options (dropdown, radio, etc.)
492554
if (previewParam.options.length > 0) {
493555
const validValues = previewParam.options.map(
494556
(option) => option.value.value,
495557
);
496558
return validValues.includes(buildParam.value);
497559
}
498560

499-
return false;
561+
// For parameters without options (input, textarea, etc.)
562+
return true;
500563
};
501564

502565
export const useValidationSchemaForDynamicParameters = (

site/src/pages/CreateWorkspacePage/CreateWorkspacePageViewExperimental.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
useContext,
3434
useEffect,
3535
useId,
36+
useMemo,
3637
useRef,
3738
useState,
3839
} from "react";
@@ -141,6 +142,14 @@ export const CreateWorkspacePageViewExperimental: FC<
141142
},
142143
});
143144

145+
const autofillByName = useMemo(
146+
() =>
147+
Object.fromEntries(
148+
autofillParameters.map((param) => [param.name, param]),
149+
),
150+
[autofillParameters],
151+
);
152+
144153
useEffect(() => {
145154
if (error) {
146155
window.scrollTo(0, 0);
@@ -509,6 +518,9 @@ export const CreateWorkspacePageViewExperimental: FC<
509518
return null;
510519
}
511520

521+
const formValue =
522+
form.values?.rich_parameter_values?.[index]?.value || "";
523+
512524
return (
513525
<DynamicParameter
514526
key={parameter.name}
@@ -518,6 +530,8 @@ export const CreateWorkspacePageViewExperimental: FC<
518530
}
519531
disabled={isDisabled}
520532
isPreset={isPresetParameter}
533+
autofill={autofillByName[parameter.name]}
534+
value={formValue}
521535
/>
522536
);
523537
})}

0 commit comments

Comments
 (0)