mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
feat: use template/module config variable's default value as its field placeholder if present
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
TemplateBuilderTitle,
|
||||
} from "#/pages/TemplateBuilder/TemplateBuilderHeader";
|
||||
import type { ConfigurationFieldDefinition } from "./ConfigurationField";
|
||||
import { defaultPlaceholder } from "./defaultPlaceholder";
|
||||
import { TemplateConfiguration } from "./TemplateConfiguration";
|
||||
|
||||
interface BaseTemplateParametersStepProps {
|
||||
@@ -53,7 +54,9 @@ function variableToField(
|
||||
label: variable.name,
|
||||
description: variable.description || undefined,
|
||||
required: variable.required,
|
||||
placeholder: variable.required ? "Required" : "Optional",
|
||||
placeholder:
|
||||
defaultPlaceholder(variable.default) ??
|
||||
(variable.required ? "Required" : "Optional"),
|
||||
field: {
|
||||
name: variable.name,
|
||||
id,
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
TemplateBuilderTitle,
|
||||
} from "#/pages/TemplateBuilder/TemplateBuilderHeader";
|
||||
import type { ConfigurationFieldDefinition } from "./ConfigurationField";
|
||||
import { defaultPlaceholder } from "./defaultPlaceholder";
|
||||
import { ModuleConfiguration } from "./ModuleConfiguration";
|
||||
|
||||
interface ModuleSettingsStepProps {
|
||||
@@ -51,7 +52,9 @@ function variableToField(
|
||||
label: variable.name,
|
||||
description: variable.description || undefined,
|
||||
required: variable.required,
|
||||
placeholder: variable.required ? "Required" : "Optional",
|
||||
placeholder:
|
||||
defaultPlaceholder(variable.default) ??
|
||||
(variable.required ? "Required" : "Optional"),
|
||||
field: {
|
||||
name: variable.name,
|
||||
id,
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { defaultPlaceholder } from "./defaultPlaceholder";
|
||||
|
||||
describe("defaultPlaceholder", () => {
|
||||
it("formats numeric defaults, including zero", () => {
|
||||
expect(defaultPlaceholder(13337)).toBe("13337");
|
||||
expect(defaultPlaceholder(0)).toBe("0");
|
||||
});
|
||||
|
||||
it("formats boolean defaults", () => {
|
||||
expect(defaultPlaceholder(false)).toBe("false");
|
||||
expect(defaultPlaceholder(true)).toBe("true");
|
||||
});
|
||||
|
||||
it("returns non-empty string defaults unchanged", () => {
|
||||
expect(defaultPlaceholder("v0.10.0")).toBe("v0.10.0");
|
||||
});
|
||||
|
||||
it("returns undefined for empty or absent defaults", () => {
|
||||
expect(defaultPlaceholder("")).toBeUndefined();
|
||||
expect(defaultPlaceholder(undefined)).toBeUndefined();
|
||||
expect(defaultPlaceholder(null)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns undefined for object and array defaults", () => {
|
||||
expect(defaultPlaceholder({ key: "value" })).toBeUndefined();
|
||||
expect(defaultPlaceholder(["a", "b"])).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Coerces a module variable's `default` into placeholder text.
|
||||
*
|
||||
* `TemplateBuilderModuleVariable.default` is generated as
|
||||
* `Record<string, string>` because every `json.RawMessage` field maps to that
|
||||
* type, but the actual wire value is a JSON scalar (string, number, or
|
||||
* boolean). The parameter is typed `unknown` so the generated value is accepted
|
||||
* without a cast.
|
||||
*
|
||||
* An empty-string default returns `undefined` so callers fall back to their
|
||||
* existing Required/Optional hint. Object or array defaults also return
|
||||
* `undefined` since they have no meaningful placeholder representation.
|
||||
*/
|
||||
export function defaultPlaceholder(value: unknown): string | undefined {
|
||||
if (typeof value === "number" || typeof value === "boolean") {
|
||||
return String(value);
|
||||
}
|
||||
if (typeof value === "string" && value !== "") {
|
||||
return value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
Reference in New Issue
Block a user