feat(p): link only OEM codes with a cross-reference match
Every OEM code was a link → unmatched codes (the majority — fasteners, clips, body parts TecDoc doesn't carry) opened an empty "no equivalents" page. Now the schema page batch-checks its codes against the snapshot (POST /p/matched, one indexed query) and links ONLY the matched ones; unmatched codes render as plain text. Copy stays for all. No more dead-end empty pages from the parts panel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,34 @@ export function PartsPanel({
|
||||
const viewedKeyRef = useRef<string | null>(null);
|
||||
const [copiedId, setCopiedId] = useState<string | null>(null);
|
||||
const [resolvingCode, setResolvingCode] = useState<string | null>(null);
|
||||
// OEM codes that resolve to a non-empty cross-reference page. Only these are
|
||||
// rendered as links — unmatched codes stay plain text so a click never lands
|
||||
// on an empty "no equivalents" page. One batch lookup per parts list.
|
||||
const [matchedOemCodes, setMatchedOemCodes] = useState<Set<string>>(new Set());
|
||||
|
||||
const oemCodes = useMemo(
|
||||
() => [...new Set(parts.map((p) => p.oemCode).filter((c) => c && c !== "N/A"))],
|
||||
[parts],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (oemCodes.length === 0) {
|
||||
setMatchedOemCodes(new Set());
|
||||
return;
|
||||
}
|
||||
let cancelled = false;
|
||||
api
|
||||
.post<{ matched: string[] }>("/p/matched", { codes: oemCodes })
|
||||
.then((res) => {
|
||||
if (!cancelled) setMatchedOemCodes(new Set(res?.matched ?? []));
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) setMatchedOemCodes(new Set());
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [oemCodes]);
|
||||
|
||||
// PL24 "bk. tablo:NNN-NNN" cross-reference jump. Resolved at load → open the
|
||||
// target illustration directly. Unresolved (target branch not seeded yet) →
|
||||
@@ -365,11 +393,13 @@ export function PartsPanel({
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
{part.oemCode && part.oemCode !== "N/A" ? (
|
||||
// Click → OEM detail page (P cross-reference) in a
|
||||
// new tab so the catalog/schema context stays put. Plain
|
||||
// anchor (not router Link) — a fresh load resolves the
|
||||
// route and keeps this cell router-context-free.
|
||||
{part.oemCode &&
|
||||
part.oemCode !== "N/A" &&
|
||||
matchedOemCodes.has(part.oemCode) ? (
|
||||
// Link ONLY codes with a real cross-reference (new tab,
|
||||
// keeps catalog/schema context). Plain anchor, not router
|
||||
// Link — fresh load resolves the route, no router context
|
||||
// needed here. Unmatched codes fall through to plain text.
|
||||
<a
|
||||
href={`/dashboard/oem/${encodeURIComponent(part.oemCode)}`}
|
||||
target="_blank"
|
||||
|
||||
Reference in New Issue
Block a user