From 78d62c541f4438b18cf0b9cb72fe68c91e0a525b Mon Sep 17 00:00:00 2001 From: robbond Date: Thu, 9 Apr 2026 10:21:09 +0100 Subject: [PATCH] 22541 consolidate breadcrumb mapped route maps into grouped constants --- components/breadcrumbs.js | 220 ++++++++---------- memory-bank/change-log.md | 33 +++ .../breadcrumbs-route-map-structure.test.cjs | 14 ++ 3 files changed, 148 insertions(+), 119 deletions(-) diff --git a/components/breadcrumbs.js b/components/breadcrumbs.js index f0e3b552..90c2a391 100644 --- a/components/breadcrumbs.js +++ b/components/breadcrumbs.js @@ -113,132 +113,114 @@ const Breadcrumbs = (props) => { return staticTextCrumbByPath[path] || null; }; - const getSimpleRouteRenderer = (path) => { - const simpleRouteRenderersByPath = { - "/myportal": () => renderTextCrumb(t("myportal:page-title")), - "/searchresults": () => - renderTextCrumb(t("common:breadcrumb-search-results")), - "/advancedsearch": () => - renderTextCrumb(t("common:breadcrumb-advanced-search")), - "/addresssearch": () => - renderTextCrumb(t("common:breadcrumb-address-search")), - "/contactus": () => - renderTextCrumb(t("common:footer-contact-us-link-label")), - "/viewall": () => - renderMyPortalSectionCrumbs(t("common:breadcrumb-your-cases")), - "/myportal/dnsapplications": () => - renderMyPortalSectionCrumbs(t("dnsCommon:service-name")) - }; - - return simpleRouteRenderersByPath[path] || null; + const simpleRouteRenderersByPath = { + "/myportal": () => renderTextCrumb(t("myportal:page-title")), + "/searchresults": () => + renderTextCrumb(t("common:breadcrumb-search-results")), + "/advancedsearch": () => + renderTextCrumb(t("common:breadcrumb-advanced-search")), + "/addresssearch": () => + renderTextCrumb(t("common:breadcrumb-address-search")), + "/contactus": () => + renderTextCrumb(t("common:footer-contact-us-link-label")), + "/viewall": () => + renderMyPortalSectionCrumbs(t("common:breadcrumb-your-cases")), + "/myportal/dnsapplications": () => + renderMyPortalSectionCrumbs(t("dnsCommon:service-name")) }; - const getSimpleLinkTextPairRenderer = (path) => { - const simpleLinkTextPairRenderersByPath = { - "/addresssearchresults": () => ( - <> - {renderLinkCrumb( - isWelsh - ? router.locale + "/chwiliadcyfeiriadau" - : "/addresssearch", - t("common:breadcrumb-address-search") - )} - {renderTextCrumb( - t("common:breadcrumb-address-search-results") - )} - - ), - "/advancedsearchresults": () => ( - <> - {renderLinkCrumb( - isWelsh - ? router.locale + "/advancedsearch" - : "/advancedsearch", - t("common:breadcrumb-advanced-search") - )} - {renderTextCrumb( - t("common:breadcrumb-advanced-search-results") - )} - - ) - }; - - return simpleLinkTextPairRenderersByPath[path] || null; - }; - - const getSimpleMyPortalRouteRenderer = (path) => { - const simpleMyPortalRouteRenderersByPath = { - "/myportal/searchresults": () => ( - <> - {renderAnchorCrumb( - myPortalHref, - t("common:breadcrumb-my-portal") - )} - {renderTextCrumb(t("common:breadcrumb-search-results"))} - - ), - "/myportal/addresssearch": () => - renderMyPortalSectionCrumbs( + const simpleLinkTextPairRenderersByPath = { + "/addresssearchresults": () => ( + <> + {renderLinkCrumb( + isWelsh + ? router.locale + "/chwiliadcyfeiriadau" + : "/addresssearch", t("common:breadcrumb-address-search") - ), - "/myportal/advancedsearch": () => - renderMyPortalSectionCrumbs( + )} + {renderTextCrumb(t("common:breadcrumb-address-search-results"))} + + ), + "/advancedsearchresults": () => ( + <> + {renderLinkCrumb( + isWelsh + ? router.locale + "/advancedsearch" + : "/advancedsearch", t("common:breadcrumb-advanced-search") - ), - "/myportal/contactus": () => - renderMyPortalSectionCrumbs( - t("common:footer-contact-us-link-label") - ), - "/myportal/viewall": () => - renderMyPortalSectionCrumbs( - getViewAllLabel( - currentViewState.viewKey || router.query.key - ) - ), - "/myportal/advancedsearchresults": () => ( - <> - {renderMyPortalCrumb()} - {renderLinkCrumb( - isWelsh - ? router.locale + "/myportal/advancedsearch" - : "/myportal/advancedsearch", - t("common:breadcrumb-advanced-search") - )} - {renderTextCrumb( - t("common:breadcrumb-advanced-search-results") - )} - - ), - "/myportal/addresssearchresults": () => ( - <> - {renderMyPortalCrumb()} - {renderLinkCrumb( - isWelsh - ? "/" + - router.locale + - "/fymhorth/chwiliadcyfeiriadau" - : "/myportal/addresssearch", - t("common:breadcrumb-address-search") - )} - {renderTextCrumb( - t("common:breadcrumb-address-search-results") - )} - - ) - }; - - return simpleMyPortalRouteRenderersByPath[path] || null; + )} + {renderTextCrumb( + t("common:breadcrumb-advanced-search-results") + )} + + ) }; + const simpleMyPortalRouteRenderersByPath = { + "/myportal/searchresults": () => ( + <> + {renderAnchorCrumb( + myPortalHref, + t("common:breadcrumb-my-portal") + )} + {renderTextCrumb(t("common:breadcrumb-search-results"))} + + ), + "/myportal/addresssearch": () => + renderMyPortalSectionCrumbs(t("common:breadcrumb-address-search")), + "/myportal/advancedsearch": () => + renderMyPortalSectionCrumbs(t("common:breadcrumb-advanced-search")), + "/myportal/contactus": () => + renderMyPortalSectionCrumbs( + t("common:footer-contact-us-link-label") + ), + "/myportal/viewall": () => + renderMyPortalSectionCrumbs( + getViewAllLabel(currentViewState.viewKey || router.query.key) + ), + "/myportal/advancedsearchresults": () => ( + <> + {renderMyPortalCrumb()} + {renderLinkCrumb( + isWelsh + ? router.locale + "/myportal/advancedsearch" + : "/myportal/advancedsearch", + t("common:breadcrumb-advanced-search") + )} + {renderTextCrumb( + t("common:breadcrumb-advanced-search-results") + )} + + ), + "/myportal/addresssearchresults": () => ( + <> + {renderMyPortalCrumb()} + {renderLinkCrumb( + isWelsh + ? "/" + router.locale + "/fymhorth/chwiliadcyfeiriadau" + : "/myportal/addresssearch", + t("common:breadcrumb-address-search") + )} + {renderTextCrumb(t("common:breadcrumb-address-search-results"))} + + ) + }; + + const mappedRouteRendererMaps = [ + simpleRouteRenderersByPath, + simpleLinkTextPairRenderersByPath, + simpleMyPortalRouteRenderersByPath + ]; + + const getMappedRendererByPath = (path, routeRendererMap) => + routeRendererMap[path] || null; + const resolveMappedRouteRenderer = (path) => { - const mappedResolvers = [ - getSimpleRouteRenderer, - getSimpleLinkTextPairRenderer, - getSimpleMyPortalRouteRenderer - ]; - - for (const resolveRenderer of mappedResolvers) { - const routeRenderer = resolveRenderer(path); + for (const routeRendererMap of mappedRouteRendererMaps) { + const routeRenderer = getMappedRendererByPath( + path, + routeRendererMap + ); if (routeRenderer) { return routeRenderer; } diff --git a/memory-bank/change-log.md b/memory-bank/change-log.md index a1706c71..f2e0d2c0 100644 --- a/memory-bank/change-log.md +++ b/memory-bank/change-log.md @@ -459,6 +459,39 @@ Follow-ups: - Next wider slice candidate: split map resolver sections into clearly named grouped constants (simple/public/myportal) near one composition point, then optionally move map-only route renderers to a local pure helper module if continued growth impacts scanability. +### CL-22541-P: breadcrumbs grouped route-map constants + unified map composition point + +date: 2026-04-09 +author: Cline +scope: `components/breadcrumbs.js`, `tests/phase22/breadcrumbs-route-map-structure.test.cjs` +type: change +rationale: Execute the next wider slice by replacing per-group resolver functions with grouped route-map constants and a single composition array to further improve scanability while preserving route precedence semantics. +impact: Refactor-only structural readability improvement; no intended route/auth/session/API/EN-CY/a11y behavior change. +status: completed + +Summary: + +- Replaced function-based map accessors with grouped route-map constants in `components/breadcrumbs.js`: + - `simpleRouteRenderersByPath` + - `simpleLinkTextPairRenderersByPath` + - `simpleMyPortalRouteRenderersByPath` +- Added unified map composition point: + - `mappedRouteRendererMaps` (ordered array preserving precedence) + - `getMappedRendererByPath(path, routeRendererMap)` helper +- Updated `resolveMappedRouteRenderer(path)` to iterate the composed map list while retaining previous resolution order and behavior. +- Kept dynamic/callback branches explicit and unchanged outside map-driven paths. +- Expanded structure tests to assert grouped map composition contracts (`mappedRouteRendererMaps`, `getMappedRendererByPath`) in addition to existing resolver and invocation guardrails. + +Validation: + +- `npx eslint components/breadcrumbs.js tests/phase22/breadcrumbs-route-map-structure.test.cjs tests/phase22/index.test.cjs` -> pass. +- `node tests/phase22/index.test.cjs` -> pass (combined suite; breadcrumbs-route-map tests 3/3). + +Follow-ups: + +- Next slice option A (larger): extract map constants + resolver helpers into a local `lib/routing/breadcrumbRouteMaps.js` pure module with focused tests, keeping callback/stateful branch rendering in component. +- Next slice option B (smaller): expand structure tests to assert explicit map ordering invariants so future reordering regressions are caught early. + ### CL-00X: 22500 `components/elements/index.js` Phase 1 helper extraction date: 2026-04-07 diff --git a/tests/phase22/breadcrumbs-route-map-structure.test.cjs b/tests/phase22/breadcrumbs-route-map-structure.test.cjs index 65613f6b..77c0e4a7 100644 --- a/tests/phase22/breadcrumbs-route-map-structure.test.cjs +++ b/tests/phase22/breadcrumbs-route-map-structure.test.cjs @@ -59,6 +59,20 @@ test("breadcrumbs/simple-link-text map includes address and advanced search resu test("breadcrumbs/merged resolver renders mapped routes through single helper invocation", async () => { const source = loadBreadcrumbSource(); + assert.strictEqual( + source.includes("const mappedRouteRendererMaps = ["), + true, + "Expected grouped mapped route renderer map composition to exist" + ); + + assert.strictEqual( + source.includes( + "const getMappedRendererByPath = (path, routeRendererMap) =>" + ), + true, + "Expected shared mapped renderer lookup helper to exist" + ); + assert.strictEqual( source.includes("const resolveMappedRouteRenderer = (path) =>"), true,