22541 unify breadcrumb mapped-route resolver and widen route-map coverage
This commit is contained in:
+57
-48
@@ -166,6 +166,62 @@ const Breadcrumbs = (props) => {
|
|||||||
return simpleLinkTextPairRenderersByPath[path] || null;
|
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(
|
||||||
|
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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
return simpleMyPortalRouteRenderersByPath[path] || null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const resolveMappedRouteRenderer = (path) => {
|
||||||
|
const mappedResolvers = [
|
||||||
|
getSimpleRouteRenderer,
|
||||||
|
getSimpleLinkTextPairRenderer,
|
||||||
|
getSimpleMyPortalRouteRenderer
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const resolveRenderer of mappedResolvers) {
|
||||||
|
const routeRenderer = resolveRenderer(path);
|
||||||
|
if (routeRenderer) {
|
||||||
|
return routeRenderer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderMappedRoute = (path, resolver = resolveMappedRouteRenderer) => {
|
||||||
|
const routeRenderer = resolver(path);
|
||||||
|
return routeRenderer ? routeRenderer() : null;
|
||||||
|
};
|
||||||
|
|
||||||
const renderMyPortalCrumb = () => (
|
const renderMyPortalCrumb = () => (
|
||||||
<li className="govuk-breadcrumbs__list-item">
|
<li className="govuk-breadcrumbs__list-item">
|
||||||
<Link href={myPortalHref} className="govuk-breadcrumbs__link">
|
<Link href={myPortalHref} className="govuk-breadcrumbs__link">
|
||||||
@@ -261,43 +317,7 @@ const Breadcrumbs = (props) => {
|
|||||||
t("common:service-name-breadcrumb")
|
t("common:service-name-breadcrumb")
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{(() => {
|
{renderMappedRoute(pathname)}
|
||||||
const renderSimpleRoute =
|
|
||||||
getSimpleRouteRenderer(pathname);
|
|
||||||
return renderSimpleRoute
|
|
||||||
? renderSimpleRoute()
|
|
||||||
: null;
|
|
||||||
})()}
|
|
||||||
{(() => {
|
|
||||||
const renderSimpleLinkTextPair =
|
|
||||||
getSimpleLinkTextPairRenderer(pathname);
|
|
||||||
return renderSimpleLinkTextPair
|
|
||||||
? renderSimpleLinkTextPair()
|
|
||||||
: null;
|
|
||||||
})()}
|
|
||||||
{isPath("/myportal/searchresults") && (
|
|
||||||
<>
|
|
||||||
{renderAnchorCrumb(
|
|
||||||
myPortalHref,
|
|
||||||
t("common:breadcrumb-my-portal")
|
|
||||||
)}
|
|
||||||
<li className="govuk-breadcrumbs__list-item">
|
|
||||||
{t("common:breadcrumb-search-results")}
|
|
||||||
</li>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{isPath("/myportal/addresssearch") &&
|
|
||||||
renderMyPortalSectionCrumbs(
|
|
||||||
t("common:breadcrumb-address-search")
|
|
||||||
)}
|
|
||||||
{isPath("/myportal/advancedsearch") &&
|
|
||||||
renderMyPortalSectionCrumbs(
|
|
||||||
t("common:breadcrumb-advanced-search")
|
|
||||||
)}
|
|
||||||
{isPath("/myportal/contactus") &&
|
|
||||||
renderMyPortalSectionCrumbs(
|
|
||||||
t("common:footer-contact-us-link-label")
|
|
||||||
)}
|
|
||||||
{isPath("/myportal/advancedsearchresults") && (
|
{isPath("/myportal/advancedsearchresults") && (
|
||||||
<>
|
<>
|
||||||
{renderMyPortalCrumb()}
|
{renderMyPortalCrumb()}
|
||||||
@@ -386,17 +406,6 @@ const Breadcrumbs = (props) => {
|
|||||||
</li>
|
</li>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{isPath("/myportal/viewall") && (
|
|
||||||
<>
|
|
||||||
{renderMyPortalCrumb()}
|
|
||||||
<li className="govuk-breadcrumbs__list-item">
|
|
||||||
{getViewAllLabel(
|
|
||||||
currentViewState.viewKey ||
|
|
||||||
router.query.key
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{isPath("/myportal/case") && (
|
{isPath("/myportal/case") && (
|
||||||
<>
|
<>
|
||||||
{renderLinkCrumb(
|
{renderLinkCrumb(
|
||||||
|
|||||||
@@ -392,6 +392,43 @@ Follow-ups:
|
|||||||
|
|
||||||
- Next slice recommendation: introduce a tiny local `renderMappedRoute(path, resolver)` helper to remove repeated inline IIFE map invocations, then optionally merge simple maps under one top-level resolver while preserving explicit ordering and side-effect-free constraints.
|
- Next slice recommendation: introduce a tiny local `renderMappedRoute(path, resolver)` helper to remove repeated inline IIFE map invocations, then optionally merge simple maps under one top-level resolver while preserving explicit ordering and side-effect-free constraints.
|
||||||
|
|
||||||
|
### CL-22541-N: breadcrumbs unified mapped-route resolver + widened structural guardrails
|
||||||
|
|
||||||
|
date: 2026-04-09
|
||||||
|
author: Cline
|
||||||
|
scope: `components/breadcrumbs.js`, `tests/phase22/breadcrumbs-route-map-structure.test.cjs`
|
||||||
|
type: change
|
||||||
|
rationale: Execute the requested wider next slice by removing duplicated mapped-route invocation patterns, introducing a single top-level mapped resolver with explicit precedence, and migrating an additional safe my-portal route group into map-driven rendering while preserving explicit dynamic/callback branches.
|
||||||
|
impact: Refactor-only structural consolidation/readability improvement with widened mapped-route coverage and stronger structure guardrail tests; no intended route/auth/session/API/EN-CY/a11y behavior change.
|
||||||
|
status: completed
|
||||||
|
|
||||||
|
Summary:
|
||||||
|
|
||||||
|
- Added `getSimpleMyPortalRouteRenderer(path)` in `components/breadcrumbs.js` and migrated additional safe map-friendly routes:
|
||||||
|
- `/myportal/searchresults`
|
||||||
|
- `/myportal/addresssearch`
|
||||||
|
- `/myportal/advancedsearch`
|
||||||
|
- `/myportal/contactus`
|
||||||
|
- `/myportal/viewall`
|
||||||
|
- Added `resolveMappedRouteRenderer(path)` to unify map precedence under one resolver.
|
||||||
|
- Added `renderMappedRoute(path, resolver?)` helper and replaced duplicated inline map IIFE invocations with a single call:
|
||||||
|
- `{renderMappedRoute(pathname)}`
|
||||||
|
- Kept dynamic/stateful callback branches explicit and unchanged, especially `/myportal/case/id/[incident]` (`router.back()`) and other callback/state driven branches.
|
||||||
|
- Expanded `tests/phase22/breadcrumbs-route-map-structure.test.cjs` to assert:
|
||||||
|
- new my-portal route-map entries are present
|
||||||
|
- unified resolver/helper signatures are present
|
||||||
|
- single mapped-route invocation is used in JSX
|
||||||
|
- dynamic callback branch remains explicit.
|
||||||
|
|
||||||
|
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 wider slice candidate: move a second safe myportal results pair group (`/myportal/advancedsearchresults`, `/myportal/addresssearchresults`) into the unified mapped resolver where callback-free, then consider splitting resolver maps into a dedicated local constant section for improved scanability.
|
||||||
|
|
||||||
### CL-00X: 22500 `components/elements/index.js` Phase 1 helper extraction
|
### CL-00X: 22500 `components/elements/index.js` Phase 1 helper extraction
|
||||||
|
|
||||||
date: 2026-04-07
|
date: 2026-04-07
|
||||||
|
|||||||
@@ -30,6 +30,42 @@ test("breadcrumbs/simple-link-text map includes address and advanced search resu
|
|||||||
true,
|
true,
|
||||||
"Expected /advancedsearchresults to be mapped in getSimpleLinkTextPairRenderer"
|
"Expected /advancedsearchresults to be mapped in getSimpleLinkTextPairRenderer"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
source.includes('"/myportal/searchresults": () => ('),
|
||||||
|
true,
|
||||||
|
"Expected /myportal/searchresults to be mapped in getSimpleMyPortalRouteRenderer"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
source.includes('"/myportal/viewall": () =>'),
|
||||||
|
true,
|
||||||
|
"Expected /myportal/viewall to be mapped in getSimpleMyPortalRouteRenderer"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("breadcrumbs/merged resolver renders mapped routes through single helper invocation", async () => {
|
||||||
|
const source = loadBreadcrumbSource();
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
source.includes("const resolveMappedRouteRenderer = (path) =>"),
|
||||||
|
true,
|
||||||
|
"Expected unified mapped route resolver helper to exist"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
source.includes(
|
||||||
|
"const renderMappedRoute = (path, resolver = resolveMappedRouteRenderer) =>"
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
"Expected reusable renderMappedRoute helper to exist"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
source.includes("{renderMappedRoute(pathname)}"),
|
||||||
|
true,
|
||||||
|
"Expected breadcrumb JSX to use single mapped route render invocation"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("breadcrumbs/dynamic callback branch remains explicit for myportal case incident route", async () => {
|
test("breadcrumbs/dynamic callback branch remains explicit for myportal case incident route", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user