From a183f006579ace8f310e7ad5fed95c0b2d8963a4 Mon Sep 17 00:00:00 2001 From: Hagernesh Date: Fri, 28 Aug 2026 12:10:44 +0000 Subject: [PATCH] fix(container-returns): dedupe company names in the return picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit freight.companies allows duplicate names, and Mantine v9 throws on duplicate Autocomplete option values, taking down the whole Container Returns page with a render error. Dedupes the option list by trimmed name. resolveId now returns an id only when exactly one company carries the name — an ambiguous name resolves to nothing, so the return keeps the typed company name rather than silently attaching to whichever duplicate happened to come first. Co-Authored-By: Claude Opus 5 (1M context) --- .../warehouses/useCompanyOptions.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/edr-freight-web/backoffice/src/components/warehouses/useCompanyOptions.ts b/apps/edr-freight-web/backoffice/src/components/warehouses/useCompanyOptions.ts index ce8286454..2c80535b7 100644 --- a/apps/edr-freight-web/backoffice/src/components/warehouses/useCompanyOptions.ts +++ b/apps/edr-freight-web/backoffice/src/components/warehouses/useCompanyOptions.ts @@ -16,11 +16,22 @@ export function useCompanyOptions() { const companies = data?.items ?? []; + // Company names are not unique — Mantine throws on duplicate option values, + // so the list is deduped by the trimmed name. + const names = [...new Set(companies.map((c) => c.name.trim()).filter(Boolean))]; + return { loading: isLoading, - names: companies.map((c) => c.name), - /** Exact (case-insensitive) name match → company id, else undefined. */ - resolveId: (name: string): string | undefined => - companies.find((c) => c.name.trim().toLowerCase() === name.trim().toLowerCase())?.id, + names, + /** + * Name → company id, only when exactly one company carries that name. An + * ambiguous name resolves to nothing rather than to an arbitrary company: + * the container keeps the typed name and no wrong customer is attached. + */ + resolveId: (name: string): string | undefined => { + const key = name.trim().toLowerCase(); + const matches = companies.filter((c) => c.name.trim().toLowerCase() === key); + return matches.length === 1 ? matches[0].id : undefined; + }, }; }