Skip to content

Commit 250ee53

Browse files
committed
chore: update for types from typesGenerated
1 parent 24be8bf commit 250ee53

File tree

2 files changed

+178
-138
lines changed

2 files changed

+178
-138
lines changed

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

Lines changed: 160 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import type { WorkspaceBuildParameter } from "api/typesGenerated";
21
import type {
3-
Parameter,
4-
ParameterOption,
5-
ParameterValidation,
6-
} from "api/typesParameter";
2+
PreviewParameter,
3+
PreviewParameterOption,
4+
WorkspaceBuildParameter,
5+
} from "api/typesGenerated";
76
import { Badge } from "components/Badge/Badge";
87
import { Checkbox } from "components/Checkbox/Checkbox";
98
import { ExternalImage } from "components/ExternalImage/ExternalImage";
@@ -31,10 +30,11 @@ import {
3130
} from "components/Tooltip/Tooltip";
3231
import { Info, Settings, TriangleAlert } from "lucide-react";
3332
import { type FC, useId } from "react";
33+
import type { AutofillBuildParameter } from "utils/richParameters";
3434
import * as Yup from "yup";
3535

3636
export interface DynamicParameterProps {
37-
parameter: Parameter;
37+
parameter: PreviewParameter;
3838
onChange: (value: string) => void;
3939
disabled?: boolean;
4040
isPreset?: boolean;
@@ -68,7 +68,7 @@ export const DynamicParameter: FC<DynamicParameterProps> = ({
6868
};
6969

7070
interface ParameterLabelProps {
71-
parameter: Parameter;
71+
parameter: PreviewParameter;
7272
isPreset?: boolean;
7373
}
7474

@@ -144,7 +144,7 @@ const ParameterLabel: FC<ParameterLabelProps> = ({ parameter, isPreset }) => {
144144
};
145145

146146
interface ParameterFieldProps {
147-
parameter: Parameter;
147+
parameter: PreviewParameter;
148148
onChange: (value: string) => void;
149149
disabled?: boolean;
150150
id: string;
@@ -173,26 +173,35 @@ const ParameterField: FC<ParameterFieldProps> = ({
173173
<SelectValue placeholder="Select option" />
174174
</SelectTrigger>
175175
<SelectContent>
176-
{parameter.options.map((option) => (
177-
<SelectItem key={option.value.value} value={option.value.value}>
178-
<OptionDisplay option={option} />
179-
</SelectItem>
180-
))}
176+
{parameter.options
177+
.filter(
178+
(option): option is NonNullable<typeof option> =>
179+
option !== null,
180+
)
181+
.map((option) => (
182+
<SelectItem key={option.value.value} value={option.value.value}>
183+
<OptionDisplay option={option} />
184+
</SelectItem>
185+
))}
181186
</SelectContent>
182187
</Select>
183188
);
184189

185190
case "multi-select": {
186191
// Map parameter options to MultiSelectCombobox options format
187-
const comboboxOptions: Option[] = parameter.options.map((opt) => ({
188-
value: opt.value.value,
189-
label: opt.name,
190-
disable: false,
191-
}));
192+
const comboboxOptions: Option[] = parameter.options
193+
.filter((opt): opt is NonNullable<typeof opt> => opt !== null)
194+
.map((opt) => ({
195+
value: opt.value.value,
196+
label: opt.name,
197+
disable: false,
198+
}));
192199

193200
const defaultOptions: Option[] = JSON.parse(defaultValue).map(
194201
(val: string) => {
195-
const option = parameter.options.find((o) => o.value.value === val);
202+
const option = parameter.options
203+
.filter((o): o is NonNullable<typeof o> => o !== null)
204+
.find((o) => o.value.value === val);
196205
return {
197206
value: val,
198207
label: option?.name || val,
@@ -242,20 +251,24 @@ const ParameterField: FC<ParameterFieldProps> = ({
242251
disabled={disabled}
243252
defaultValue={defaultValue}
244253
>
245-
{parameter.options.map((option) => (
246-
<div
247-
key={option.value.value}
248-
className="flex items-center space-x-2"
249-
>
250-
<RadioGroupItem
251-
id={option.value.value}
252-
value={option.value.value}
253-
/>
254-
<Label htmlFor={option.value.value} className="cursor-pointer">
255-
<OptionDisplay option={option} />
256-
</Label>
257-
</div>
258-
))}
254+
{parameter.options
255+
.filter(
256+
(option): option is NonNullable<typeof option> => option !== null,
257+
)
258+
.map((option) => (
259+
<div
260+
key={option.value.value}
261+
className="flex items-center space-x-2"
262+
>
263+
<RadioGroupItem
264+
id={option.value.value}
265+
value={option.value.value}
266+
/>
267+
<Label htmlFor={option.value.value} className="cursor-pointer">
268+
<OptionDisplay option={option} />
269+
</Label>
270+
</div>
271+
))}
259272
</RadioGroup>
260273
);
261274

@@ -281,7 +294,10 @@ const ParameterField: FC<ParameterFieldProps> = ({
281294
const inputProps: Record<string, unknown> = {};
282295

283296
if (parameter.type === "number") {
284-
const validations = parameter.validations[0] || {};
297+
const validations =
298+
parameter.validations.filter(
299+
(v): v is NonNullable<typeof v> => v !== null,
300+
)[0] || {};
285301
const { validation_min, validation_max } = validations;
286302

287303
if (validation_min !== null) {
@@ -310,7 +326,7 @@ const ParameterField: FC<ParameterFieldProps> = ({
310326
};
311327

312328
interface OptionDisplayProps {
313-
option: ParameterOption;
329+
option: PreviewParameterOption;
314330
}
315331

316332
const OptionDisplay: FC<OptionDisplayProps> = ({ option }) => {
@@ -341,33 +357,84 @@ const OptionDisplay: FC<OptionDisplayProps> = ({ option }) => {
341357
};
342358

343359
interface ParameterDiagnosticsProps {
344-
diagnostics: Parameter["diagnostics"];
360+
diagnostics: PreviewParameter["diagnostics"];
345361
}
346362

347363
const ParameterDiagnostics: FC<ParameterDiagnosticsProps> = ({
348364
diagnostics,
349365
}) => {
350366
return (
351367
<div className="flex flex-col gap-2">
352-
{diagnostics.map((diagnostic, index) => (
353-
<div
354-
key={`diagnostic-${diagnostic.summary}-${index}`}
355-
className={`text-xs px-1 ${
356-
diagnostic.severity === "error"
357-
? "text-content-destructive"
358-
: "text-content-warning"
359-
}`}
360-
>
361-
<div className="font-medium">{diagnostic.summary}</div>
362-
{diagnostic.detail && <div>{diagnostic.detail}</div>}
363-
</div>
364-
))}
368+
{diagnostics
369+
.filter(
370+
(diagnostic): diagnostic is NonNullable<typeof diagnostic> =>
371+
diagnostic !== null,
372+
)
373+
.map((diagnostic, index) => (
374+
<div
375+
key={`diagnostic-${diagnostic.summary}-${index}`}
376+
className={`text-xs px-1 ${
377+
diagnostic.severity === "error"
378+
? "text-content-destructive"
379+
: "text-content-warning"
380+
}`}
381+
>
382+
<div className="font-medium">{diagnostic.summary}</div>
383+
{diagnostic.detail && <div>{diagnostic.detail}</div>}
384+
</div>
385+
))}
365386
</div>
366387
);
367388
};
368389

390+
export const getInitialParameterValues = (
391+
params: PreviewParameter[],
392+
autofillParams?: AutofillBuildParameter[],
393+
): WorkspaceBuildParameter[] => {
394+
return params.map((parameter) => {
395+
// Short-circuit for ephemeral parameters, which are always reset to
396+
// the template-defined default.
397+
if (parameter.ephemeral) {
398+
return {
399+
name: parameter.name,
400+
value: parameter.default_value.valid
401+
? parameter.default_value.value
402+
: "",
403+
};
404+
}
405+
406+
const autofillParam = autofillParams?.find(
407+
({ name }) => name === parameter.name,
408+
);
409+
410+
return {
411+
name: parameter.name,
412+
value:
413+
autofillParam &&
414+
isValidValue(parameter, autofillParam) &&
415+
autofillParam.value
416+
? autofillParam.value
417+
: "",
418+
};
419+
});
420+
};
421+
422+
const isValidValue = (
423+
previewParam: PreviewParameter,
424+
buildParam: WorkspaceBuildParameter,
425+
) => {
426+
if (previewParam.options.length > 0) {
427+
const validValues = previewParam.options
428+
.filter((option): option is NonNullable<typeof option> => option !== null)
429+
.map((option) => option.value.value);
430+
return validValues.includes(buildParam.value);
431+
}
432+
433+
return true;
434+
};
435+
369436
export const useValidationSchemaForDynamicParameters = (
370-
parameters?: Parameter[],
437+
parameters?: PreviewParameter[],
371438
lastBuildParameters?: WorkspaceBuildParameter[],
372439
): Yup.AnySchema => {
373440
if (!parameters) {
@@ -387,15 +454,16 @@ export const useValidationSchemaForDynamicParameters = (
387454
if (parameter) {
388455
switch (parameter.type) {
389456
case "number": {
390-
const minValidation = parameter.validations.find(
391-
(v) => v.validation_min !== null,
392-
);
393-
const maxValidation = parameter.validations.find(
394-
(v) => v.validation_max !== null,
395-
);
457+
const minValidation = parameter.validations
458+
.filter((v): v is NonNullable<typeof v> => v !== null)
459+
.find((v) => v.validation_min !== null);
460+
const maxValidation = parameter.validations
461+
.filter((v): v is NonNullable<typeof v> => v !== null)
462+
.find((v) => v.validation_max !== null);
396463

397464
if (
398-
minValidation?.validation_min &&
465+
minValidation &&
466+
minValidation.validation_min !== null &&
399467
!maxValidation &&
400468
Number(val) < minValidation.validation_min
401469
) {
@@ -409,7 +477,8 @@ export const useValidationSchemaForDynamicParameters = (
409477

410478
if (
411479
!minValidation &&
412-
maxValidation?.validation_max &&
480+
maxValidation &&
481+
maxValidation.validation_max !== null &&
413482
Number(val) > maxValidation.validation_max
414483
) {
415484
return ctx.createError({
@@ -421,8 +490,10 @@ export const useValidationSchemaForDynamicParameters = (
421490
}
422491

423492
if (
424-
minValidation?.validation_min &&
425-
maxValidation?.validation_max &&
493+
minValidation &&
494+
minValidation.validation_min !== null &&
495+
maxValidation &&
496+
maxValidation.validation_max !== null &&
426497
(Number(val) < minValidation.validation_min ||
427498
Number(val) > maxValidation.validation_max)
428499
) {
@@ -434,18 +505,20 @@ export const useValidationSchemaForDynamicParameters = (
434505
});
435506
}
436507

437-
const monotonicValidation = parameter.validations.find(
438-
(v) => v.validation_monotonic !== null,
439-
);
440-
if (
441-
monotonicValidation?.validation_monotonic &&
442-
lastBuildParameters
443-
) {
508+
const monotonic = parameter.validations
509+
.filter((v): v is NonNullable<typeof v> => v !== null)
510+
.find(
511+
(v) =>
512+
v.validation_monotonic !== null &&
513+
v.validation_monotonic !== "",
514+
);
515+
516+
if (monotonic && lastBuildParameters) {
444517
const lastBuildParameter = lastBuildParameters.find(
445518
(last: { name: string }) => last.name === name,
446519
);
447520
if (lastBuildParameter) {
448-
switch (monotonicValidation.validation_monotonic) {
521+
switch (monotonic.validation_monotonic) {
449522
case "increasing":
450523
if (Number(lastBuildParameter.value) > Number(val)) {
451524
return ctx.createError({
@@ -468,17 +541,18 @@ export const useValidationSchemaForDynamicParameters = (
468541
break;
469542
}
470543
case "string": {
471-
const regexValidation = parameter.validations.find(
472-
(v) => v.validation_regex !== null,
473-
);
474-
if (!regexValidation?.validation_regex) {
544+
const regex = parameter.validations
545+
.filter((v): v is NonNullable<typeof v> => v !== null)
546+
.find(
547+
(v) =>
548+
v.validation_regex !== null &&
549+
v.validation_regex !== "",
550+
);
551+
if (!regex || !regex.validation_regex) {
475552
return true;
476553
}
477554

478-
if (
479-
val &&
480-
!new RegExp(regexValidation.validation_regex).test(val)
481-
) {
555+
if (val && !new RegExp(regex.validation_regex).test(val)) {
482556
return ctx.createError({
483557
path: ctx.path,
484558
message: parameterError(parameter, val),
@@ -496,18 +570,18 @@ export const useValidationSchemaForDynamicParameters = (
496570
};
497571

498572
const parameterError = (
499-
parameter: Parameter,
573+
parameter: PreviewParameter,
500574
value?: string,
501575
): string | undefined => {
502-
const validation_error = parameter.validations.find(
503-
(v) => v.validation_error !== null,
504-
);
505-
const minValidation = parameter.validations.find(
506-
(v) => v.validation_min !== null,
507-
);
508-
const maxValidation = parameter.validations.find(
509-
(v) => v.validation_max !== null,
510-
);
576+
const validation_error = parameter.validations
577+
.filter((v): v is NonNullable<typeof v> => v !== null)
578+
.find((v) => v.validation_error !== null);
579+
const minValidation = parameter.validations
580+
.filter((v): v is NonNullable<typeof v> => v !== null)
581+
.find((v) => v.validation_min !== null);
582+
const maxValidation = parameter.validations
583+
.filter((v): v is NonNullable<typeof v> => v !== null)
584+
.find((v) => v.validation_max !== null);
511585

512586
if (!validation_error || !value) {
513587
return;

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