From 9033321eb880823108876cd8e47e457c393cae6f Mon Sep 17 00:00:00 2001 From: Dion Low Date: Mon, 27 Apr 2026 18:20:22 -0500 Subject: [PATCH] fix(InstallWizard): include auto-discovered fields on Additional page When an amp.yaml object uses optionalFieldsAuto: all (without an explicit optionalFields list), the auto-discovered customer fields surface via manifest.getCustomerFieldsForObject(objectName).allFields rather than object.optionalFields. Sub-page routing and the Additional checkbox list both ignored that source, so the user landed on an empty Fields page and the Additional page itself was empty. - Update getSubPages() and useSubPageNavigation to treat an object as having optional fields when either the explicit list or auto-discovered customer fields are non-empty. - Merge auto-discovered customer fields into optionalFieldItems on the Additional page, deduping by field name and preferring explicit optionalFields so amp.yaml display names win. Closes #1599 Co-Authored-By: Claude Opus 4.7 (1M context) --- .../ConfigureObjectsStep.tsx | 39 ++++++++++++++----- .../steps/configure-objects/subPageUtils.ts | 13 ++++++- .../configure-objects/useSubPageNavigation.ts | 17 ++++++-- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/components/InstallWizard/steps/configure-objects/ConfigureObjectsStep.tsx b/src/components/InstallWizard/steps/configure-objects/ConfigureObjectsStep.tsx index 03863dac..2e099eef 100644 --- a/src/components/InstallWizard/steps/configure-objects/ConfigureObjectsStep.tsx +++ b/src/components/InstallWizard/steps/configure-objects/ConfigureObjectsStep.tsx @@ -96,16 +96,37 @@ export function ConfigureObjectsStep() { [configHandlers], ); - const optionalFieldItems: CheckboxItem[] = useMemo( - () => - optionalFields.map((field) => ({ - id: getFieldName(field), + // Build the list of optional-field checkboxes shown on the Additional page. + // Merge explicit optionalFields (from amp.yaml) with auto-discovered customer + // fields (e.g. when amp.yaml uses `optionalFieldsAuto: all`). Explicit + // entries win on conflicts so the configured display name is preserved. + const optionalFieldItems: CheckboxItem[] = useMemo(() => { + const items: CheckboxItem[] = []; + const seen = new Set(); + + optionalFields.forEach((field) => { + const fieldName = getFieldName(field); + if (!fieldName || seen.has(fieldName)) return; + seen.add(fieldName); + items.push({ + id: fieldName, label: getFieldDisplayName(field), - isChecked: - configHandlers?.getSelectedField(getFieldName(field)) ?? false, - })), - [optionalFields, configHandlers], - ); + isChecked: configHandlers?.getSelectedField(fieldName) ?? false, + }); + }); + + Object.entries(customerFields).forEach(([fieldName, meta]) => { + if (!fieldName || seen.has(fieldName)) return; + seen.add(fieldName); + items.push({ + id: fieldName, + label: meta.displayName || fieldName, + isChecked: configHandlers?.getSelectedField(fieldName) ?? false, + }); + }); + + return items; + }, [optionalFields, customerFields, configHandlers]); // Check if all required mappings have been filled const requiredMappingsComplete = useMemo( diff --git a/src/components/InstallWizard/steps/configure-objects/subPageUtils.ts b/src/components/InstallWizard/steps/configure-objects/subPageUtils.ts index cd3e19d0..b7599e39 100644 --- a/src/components/InstallWizard/steps/configure-objects/subPageUtils.ts +++ b/src/components/InstallWizard/steps/configure-objects/subPageUtils.ts @@ -60,9 +60,18 @@ export function getSubPages(manifest: Manifest, objectName: string): SubPage[] { (obj.getOptionalMapFields()?.length ?? 0) > 0; if (hasMappings) pages.push("mappings"); - const hasOptionalFields = + // An object has optional fields to show on the "additional" page if it has + // an explicit optionalFields list OR if it has auto-discovered customer + // fields (e.g. from `optionalFieldsAuto: all` in amp.yaml). The latter + // surface via manifest.getCustomerFieldsForObject(...).allFields. + const hasExplicitOptionalFields = (obj.getOptionalFields("no-mappings")?.length ?? 0) > 0; - if (hasOptionalFields) pages.push("additional"); + const hasAutoOptionalFields = + Object.keys(manifest.getCustomerFieldsForObject(objectName).allFields ?? {}) + .length > 0; + if (hasExplicitOptionalFields || hasAutoOptionalFields) { + pages.push("additional"); + } return pages.length > 0 ? pages : ["fields"]; } diff --git a/src/components/InstallWizard/steps/configure-objects/useSubPageNavigation.ts b/src/components/InstallWizard/steps/configure-objects/useSubPageNavigation.ts index 55ee435c..bf671cb9 100644 --- a/src/components/InstallWizard/steps/configure-objects/useSubPageNavigation.ts +++ b/src/components/InstallWizard/steps/configure-objects/useSubPageNavigation.ts @@ -53,11 +53,20 @@ export function useSubPageNavigation() { return required > 0 || optional > 0; }, [currentManifestObject]); + // Mirrors the check in getSubPages(): an object has an "additional" page if + // it has explicit optionalFields OR auto-discovered customer fields (e.g. + // from `optionalFieldsAuto: all`). const hasOptionalFields = useMemo(() => { - return ( - (currentManifestObject?.getOptionalFields("no-mappings")?.length ?? 0) > 0 - ); - }, [currentManifestObject]); + const hasExplicit = + (currentManifestObject?.getOptionalFields("no-mappings")?.length ?? 0) > + 0; + const hasAuto = + !!currentObjectName && + Object.keys( + manifest.getCustomerFieldsForObject(currentObjectName).allFields ?? {}, + ).length > 0; + return hasExplicit || hasAuto; + }, [currentManifestObject, manifest, currentObjectName]); const hasFieldsContent = useMemo(() => { const hasRequiredFields =