feat(site/src/pages/TemplateBuilder): auto-fill customization fields from base template - #27272
Merged
jeremyruppel merged 1 commit intoJul 22, 2026
Conversation
…from base template Seed the customizations step (ID, display name, description, icon) with defaults derived from the selected base template, keeping every field editable. Defaults are re-seeded when the base changes and preserved on back-navigation and same-base re-selection. Implements DEVEX-586.
jeremyruppel
marked this pull request as ready for review
July 15, 2026 18:13
aqandrew
approved these changes
Jul 21, 2026
jeremyruppel
deleted the
jeremy/devex-586-auto-fill-customization-fields-from-selected-base-template
branch
July 22, 2026 20:09
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes DEVEX-586.
The Template Builder wizard's final Customizations step rendered empty inputs for ID, Display name, Description, and Icon. This seeds those fields with sensible defaults derived from the selected base template, while keeping every field editable.
Changes
All frontend, in
site/src/pages/TemplateBuilder/wizardState.ts:SelectedBaseMetanow carriesdescription, mapped intoSelectedBaseMeta.baseCustomizationDefaults(base)maps the base to{ name: base.id, displayName: base.name, description, icon }.SET_BASEseeds the four customization fields when the base changes (still clearing base variable values). Re-selecting the same base preserves user edits.initWizardStateseeds the same defaults for the?base=deeplink entry path.RESET_CUSTOMIZATIONS(fired on back-navigation) now resets only organization/provisioner state, so auto-filled values survive stepping back and forth.No change was needed in
TemplateCustomizationsStep.tsx; it already binds to these state fields, so seeded values render and stay editable. Existing placeholders remain as the fallback when a base value is empty (e.g.scratch).Default mapping
namebase.iddisplayNamebase.namedescriptionbase.descriptioniconbase.iconbase.idis used for the ID field because base ids are already valid template slugs (docker,aws-linux, ...). Icon values are already served asset paths (/icon/*,/emojis/*), so no lookup map is needed.Testing
wizardState.test.ts: 27 passing, including new coverage for seeding, base-change re-seed, same-base edit preservation,RESET_CUSTOMIZATIONS,initWizardState,toSelectedBaseMeta, andbaseCustomizationDefaults.biome checkclean;tsc --noEmitclean.Implementation plan
DEVEX-586: Auto-fill customization fields from selected base template
Goal
In the Template Builder wizard, the final Customizations step currently renders empty inputs for Display name, Description, ID, and Icon. Pre-populate these with sensible defaults derived from the selected base template, while keeping every field editable. Organization is already auto-selected when a single org is available, so it is out of scope beyond leaving it untouched.
Source: Linear DEVEX-586 (Ben Potter): "Would love if all these options ... were auto-filled and generated and can be edited versus the user manually filling it out." Fields called out: display name, description, ID, and icon.
Current behavior (findings)
Frontend lives in
site/src/pages/TemplateBuilder/.TemplateCustomizationsStep.tsxrenders the four fields bound tostate.displayName,state.description,state.name(the "ID" field), andstate.icon. All start empty (initialWizardState).wizardState.tsholds the state, thewizardReducer, and theSelectedBaseMetaUI type.SelectedBaseMetadid not carrydescription.toSelectedBaseMeta(base)maps the APITemplateBuilderBaseintoSelectedBaseMeta.SET_BASEset the base and clearedbaseVariableValuesonly when the base id changed; customization fields were left empty.RESET_CUSTOMIZATIONS(dispatched byhandleBack) blanked org/provisioner plusname,displayName,description,icon.initWizardState(preselectedBase)seededbaseTemplateIdandselectedBasefor deeplinks but left customization fields empty.TemplateBuilderBaseexposesid,name,description,icon,os,variables,prerequisites.coderd/templatebuilder_handler.go) builds each base from the built-inTemplateExample:id = ex.ID,name = ex.Name,description = ex.Description,icon = ex.Icon.docker,kubernetes,aws-linux,aws-windows,gcp-linux,gcp-windows,azure-linux,digitalocean-linux,scratch.Default mapping
namebase.iddisplayNamebase.namedescriptionbase.descriptioniconbase.iconUrl(base.icon)organizationIdRationale for
name = base.id: base ids are guaranteed valid template slugs, whereas slugifying the human display name is lossy and can collide. The field stays editable.Icon default: confirmed, no map needed
The API already returns normalized, served asset paths in
base.icon(e.g./icon/docker.png,/icon/aws.svg,/emojis/1f4e6.pngforscratch), the same valuesCreateTemplatePageassigns when creating from a built-in example.IconFieldaccepts any URL/path, so every base renders correctly. A base-id-to-icon map is unnecessary.Implementation
Frontend-only, in
wizardState.ts:description?: stringtoSelectedBaseMeta; map it intoSelectedBaseMeta.baseCustomizationDefaults(base)returning{ name, displayName, description, icon }.SET_BASE: on base change, spread the defaults alongside thebaseVariableValues: {}reset; on same-base re-selection, preserve existing values.initWizardState(preselectedBase): spread defaults into the returned state.RESET_CUSTOMIZATIONSto reset onlyorganizationIdandhasProvisioners.toCreateTemplateRequestalready sends the fields, so no payload change.Tests
Reducer unit tests in
wizardState.test.tsfor seeding, base-change re-seed, same-base edit preservation,RESET_CUSTOMIZATIONS,initWizardState,toSelectedBaseMeta(description carried), andbaseCustomizationDefaults.Scope / non-goals
Opened by Coder Agents on behalf of @jeremyruppel.