From 2766dcf17a356ccec1766f4111f13a849b5ed054 Mon Sep 17 00:00:00 2001 From: Devin Foley Date: Thu, 30 Jul 2026 13:12:49 -0700 Subject: [PATCH] fix(ui): reset stale error panels when the new-company name changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new-company name is part of both the preview and import payloads, so editing it also supersedes a failed request. Reset the mutation state on name changes — without discarding the rendered preview, since name overrides are typed against it — and cover the behavior in the component tests. --- ui/src/pages/CompanyImport.test.tsx | 14 ++++++++++++++ ui/src/pages/CompanyImport.tsx | 20 ++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/ui/src/pages/CompanyImport.test.tsx b/ui/src/pages/CompanyImport.test.tsx index b1baabe5296..7843b14fe15 100644 --- a/ui/src/pages/CompanyImport.test.tsx +++ b/ui/src/pages/CompanyImport.test.tsx @@ -389,6 +389,20 @@ describe("CompanyImport", () => { expect(container.textContent).toContain("check the target company before retrying."); expect(mockPushToast).toHaveBeenCalledWith(expect.objectContaining({ tone: "error" })); + // The new-company name feeds the request payload too: editing it clears + // the stale error panel without discarding the rendered preview. + const nameInput = container.querySelector('input[placeholder="Imported Company"]'); + expect(nameInput).toBeTruthy(); + await act(async () => { + const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")!.set!; + setter.call(nameInput!, "Renamed Import"); + nameInput!.dispatchEvent(new Event("input", { bubbles: true })); + }); + await flushReact(); + + expect(container.textContent).not.toContain("Import failed:"); + expect(findButton((text) => text.startsWith("Import 3 file"))).toBeTruthy(); + // Changing the package supersedes the failed import: previewing a fresh // package must not resurface the stale import error panel. await enterGithubUrl("https://github.com/acme/other-starter/tree/main/company"); diff --git a/ui/src/pages/CompanyImport.tsx b/ui/src/pages/CompanyImport.tsx index bb2f9d9c5d3..133c05c3ab5 100644 --- a/ui/src/pages/CompanyImport.tsx +++ b/ui/src/pages/CompanyImport.tsx @@ -927,15 +927,20 @@ export function CompanyImport() { }, }); - // Any change to the package or import configuration supersedes the last - // preview and any settled mutation state, so the persistent progress/error - // panels never keep describing a request that no longer applies. - function resetImportFlowState() { - setImportPreview(null); + // Any change to the import configuration supersedes the request the last + // progress/error panel describes, so it resets both mutations. The + // new-company name is typed against a rendered preview, so it resets only + // the panels; structural changes also discard the preview itself. + function resetMutationState() { previewMutation.reset(); importMutation.reset(); } + function resetImportFlowState() { + setImportPreview(null); + resetMutationState(); + } + async function handleChooseLocalPackage(e: ChangeEvent) { const fileList = e.target.files; if (!fileList || fileList.length === 0) return; @@ -1419,7 +1424,10 @@ export function CompanyImport() { className="w-full rounded-md border border-border bg-transparent px-2.5 py-1.5 text-sm outline-none" type="text" value={newCompanyName} - onChange={(e) => setNewCompanyName(e.target.value)} + onChange={(e) => { + setNewCompanyName(e.target.value); + resetMutationState(); + }} placeholder="Imported Company" />