22541 add bundled case breadcrumb state resolver

This commit is contained in:
2026-04-09 09:28:54 +01:00
parent 59d3ed287c
commit f447aa19ea
4 changed files with 97 additions and 26 deletions
+10 -25
View File
@@ -12,10 +12,7 @@ import {
setRepresentationCapacity,
setRepresentationSubmit
} from "../store/currentView/action";
import {
resolveSearchResultsHref,
resolveSearchBreadcrumbLabel
} from "../lib/routing/routeState";
import { resolveCaseBreadcrumbState } from "../lib/routing/routeState";
const Breadcrumbs = (props) => {
const {
currentView,
@@ -95,27 +92,15 @@ const Breadcrumbs = (props) => {
return labelsByKey[viewKey] || null;
};
const breadcrumbHref = resolveSearchResultsHref({
query: router.query,
hasSession: Boolean(session),
includeViewAll: true,
fallbackToMyPortalWhenNoFlags: true
});
const caseResultsHref = resolveSearchResultsHref({
query: router.query,
hasSession: Boolean(session),
includeViewAll: false,
fallbackToMyPortalWhenNoFlags: false
});
const breadcrumbLabel = resolveSearchBreadcrumbLabel({
query: router.query,
getViewAllLabel,
advancedLabel: t("common:breadcrumb-advanced-search-results"),
addressLabel: t("common:breadcrumb-address-search-results"),
defaultLabel: t("common:breadcrumb-search-results")
});
const { breadcrumbHref, caseResultsHref, breadcrumbLabel } =
resolveCaseBreadcrumbState({
query: router.query,
hasSession: Boolean(session),
getViewAllLabel,
advancedLabel: t("common:breadcrumb-advanced-search-results"),
addressLabel: t("common:breadcrumb-address-search-results"),
defaultLabel: t("common:breadcrumb-search-results")
});
return (
<>
<nav
+31
View File
@@ -92,3 +92,34 @@ export const isDnsRoutePath = (pathname = "") => {
pathname.startsWith("/myportal/dns/")
);
};
export const resolveCaseBreadcrumbState = ({
query = {},
hasSession = false,
getViewAllLabel = () => null,
advancedLabel = "",
addressLabel = "",
defaultLabel = ""
} = {}) => {
return {
breadcrumbHref: resolveSearchResultsHref({
query,
hasSession,
includeViewAll: true,
fallbackToMyPortalWhenNoFlags: true
}),
caseResultsHref: resolveSearchResultsHref({
query,
hasSession,
includeViewAll: false,
fallbackToMyPortalWhenNoFlags: false
}),
breadcrumbLabel: resolveSearchBreadcrumbLabel({
query,
getViewAllLabel,
advancedLabel,
addressLabel,
defaultLabel
})
};
};
+29
View File
@@ -83,6 +83,35 @@ Follow-ups:
- Next breadcrumbs slice can target incremental decomposition of large pathname branch rendering blocks in `components/breadcrumbs.js` into grouped render helpers with behavior parity.
### CL-22541-C: breadcrumb case-state bundling helper (single-call resolver)
date: 2026-04-09
author: Cline
scope: `lib/routing/routeState.js`, `components/breadcrumbs.js`, `tests/phase22/route-state-helper.test.cjs`
type: change
rationale: Continue Priority 3 breadcrumbs refactor by bundling repeatedly paired breadcrumb href/label resolution into one pure helper so component call sites stay thinner and less drift-prone.
impact: Refactor-only centralization of existing route-state composition logic; no intended auth/session/API/i18n behavior change.
status: completed
Summary:
- Added `resolveCaseBreadcrumbState(...)` in `lib/routing/routeState.js` to return:
- `breadcrumbHref`
- `caseResultsHref`
- `breadcrumbLabel`
- Updated `components/breadcrumbs.js` to replace three separate helper invocations with one resolver call.
- Extended `tests/phase22/route-state-helper.test.cjs` with bundled case-state resolver coverage.
Validation:
- `npx eslint lib/routing/routeState.js components/breadcrumbs.js tests/phase22/route-state-helper.test.cjs` -> pass.
- `node tests/phase22/route-state-helper.test.cjs` -> pass (8/8).
- `node tests/phase22/index.test.cjs` -> pass (combined suite).
Follow-ups:
- Next bounded slice can extract grouped pathname render blocks from `components/breadcrumbs.js` (data-driven map or small render helpers) while preserving route parity.
### CL-00X: 22500 `components/elements/index.js` Phase 1 helper extraction
date: 2026-04-07
+27 -1
View File
@@ -11,7 +11,7 @@ const loadRouteStateModule = () => {
source = source.replace(/export const\s+/g, "const ");
source +=
"\nmodule.exports = { normalizeRouteStateQuery, resolveSearchResultsHref, resolveSearchBreadcrumbLabel, isDnsRoutePath };\n";
"\nmodule.exports = { normalizeRouteStateQuery, resolveSearchResultsHref, resolveSearchBreadcrumbLabel, isDnsRoutePath, resolveCaseBreadcrumbState };\n";
const context = {
module: { exports: {} },
@@ -158,6 +158,32 @@ test("routing/routeState identifies dns and myportal dns route prefixes", async
assert.strictEqual(mod.isDnsRoutePath("/case/123"), false);
});
test("routing/routeState resolves bundled case breadcrumb state", async () => {
const mod = loadRouteStateModule();
const getViewAllLabel = (key) => ({ myCases: "My Cases" })[key] || null;
const state = mod.resolveCaseBreadcrumbState({
query: { va: "true", key: "myCases" },
hasSession: true,
getViewAllLabel,
advancedLabel: "Advanced",
addressLabel: "Address",
defaultLabel: "Search"
});
assert.deepStrictEqual(JSON.parse(JSON.stringify(state)), {
breadcrumbHref: {
pathname: "/myportal/viewall",
query: { key: "myCases" }
},
caseResultsHref: {
pathname: "/myportal/searchresults",
query: { va: "true", key: "myCases" }
},
breadcrumbLabel: "My Cases"
});
});
const run = async () => {
let passed = 0;