22541 expand breadcrumb route-state helpers for label and dns path reuse
This commit is contained in:
@@ -13,8 +13,8 @@ import {
|
|||||||
setRepresentationSubmit
|
setRepresentationSubmit
|
||||||
} from "../store/currentView/action";
|
} from "../store/currentView/action";
|
||||||
import {
|
import {
|
||||||
normalizeRouteStateQuery,
|
resolveSearchResultsHref,
|
||||||
resolveSearchResultsHref
|
resolveSearchBreadcrumbLabel
|
||||||
} from "../lib/routing/routeState";
|
} from "../lib/routing/routeState";
|
||||||
const Breadcrumbs = (props) => {
|
const Breadcrumbs = (props) => {
|
||||||
const {
|
const {
|
||||||
@@ -73,9 +73,6 @@ const Breadcrumbs = (props) => {
|
|||||||
? 9
|
? 9
|
||||||
: "";
|
: "";
|
||||||
|
|
||||||
const routeState = normalizeRouteStateQuery(router.query);
|
|
||||||
const { viewAll, advanced, address, key } = routeState;
|
|
||||||
|
|
||||||
const hideServiceNamePaths = [
|
const hideServiceNamePaths = [
|
||||||
"/myportal/[appealtypes]",
|
"/myportal/[appealtypes]",
|
||||||
"/newappeal",
|
"/newappeal",
|
||||||
@@ -112,24 +109,13 @@ const Breadcrumbs = (props) => {
|
|||||||
fallbackToMyPortalWhenNoFlags: false
|
fallbackToMyPortalWhenNoFlags: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const breadcrumbLabel = (() => {
|
const breadcrumbLabel = resolveSearchBreadcrumbLabel({
|
||||||
if (viewAll) {
|
query: router.query,
|
||||||
return getViewAllLabel(key);
|
getViewAllLabel,
|
||||||
}
|
advancedLabel: t("common:breadcrumb-advanced-search-results"),
|
||||||
|
addressLabel: t("common:breadcrumb-address-search-results"),
|
||||||
const keyedLabel = getViewAllLabel(key);
|
defaultLabel: t("common:breadcrumb-search-results")
|
||||||
if (keyedLabel) return keyedLabel;
|
});
|
||||||
|
|
||||||
if (advanced) {
|
|
||||||
return t("common:breadcrumb-advanced-search-results");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (address) {
|
|
||||||
return t("common:breadcrumb-address-search-results");
|
|
||||||
}
|
|
||||||
|
|
||||||
return t("common:breadcrumb-search-results");
|
|
||||||
})();
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<nav
|
<nav
|
||||||
|
|||||||
@@ -45,7 +45,10 @@ import {
|
|||||||
showRepsEnded,
|
showRepsEnded,
|
||||||
getBilingualText
|
getBilingualText
|
||||||
} from "./summary/utils/helpers";
|
} from "./summary/utils/helpers";
|
||||||
import { resolveSearchResultsHref } from "../../lib/routing/routeState";
|
import {
|
||||||
|
resolveSearchResultsHref,
|
||||||
|
isDnsRoutePath
|
||||||
|
} from "../../lib/routing/routeState";
|
||||||
|
|
||||||
import CaseNoticeBanner from "./caseNoticeBanner";
|
import CaseNoticeBanner from "./caseNoticeBanner";
|
||||||
import WatchModal from "./watchmodal";
|
import WatchModal from "./watchmodal";
|
||||||
@@ -325,11 +328,7 @@ const CaseSummary = (props) => {
|
|||||||
|
|
||||||
const zoom = isNaN(parseFloat(siteCoords.latitude)) ? 7 : 12;
|
const zoom = isNaN(parseFloat(siteCoords.latitude)) ? 7 : 12;
|
||||||
|
|
||||||
const isDnsRoute =
|
const isDnsRoute = isDnsRoutePath(router.pathname);
|
||||||
router.pathname === "/dns" ||
|
|
||||||
router.pathname.startsWith("/dns/") ||
|
|
||||||
router.pathname === "/myportal/dns" ||
|
|
||||||
router.pathname.startsWith("/myportal/dns/");
|
|
||||||
|
|
||||||
const searchHref = resolveSearchResultsHref({
|
const searchHref = resolveSearchResultsHref({
|
||||||
query: router.query,
|
query: router.query,
|
||||||
|
|||||||
@@ -60,3 +60,35 @@ export const resolveSearchResultsHref = ({
|
|||||||
query
|
query
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const resolveSearchBreadcrumbLabel = ({
|
||||||
|
query = {},
|
||||||
|
getViewAllLabel = () => null,
|
||||||
|
advancedLabel = "",
|
||||||
|
addressLabel = "",
|
||||||
|
defaultLabel = ""
|
||||||
|
} = {}) => {
|
||||||
|
const routeState = normalizeRouteStateQuery(query);
|
||||||
|
const { viewAll, advanced, address, key } = routeState;
|
||||||
|
|
||||||
|
if (viewAll) {
|
||||||
|
return getViewAllLabel(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyedLabel = getViewAllLabel(key);
|
||||||
|
if (keyedLabel) return keyedLabel;
|
||||||
|
|
||||||
|
if (advanced) return advancedLabel;
|
||||||
|
if (address) return addressLabel;
|
||||||
|
|
||||||
|
return defaultLabel;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isDnsRoutePath = (pathname = "") => {
|
||||||
|
return (
|
||||||
|
pathname === "/dns" ||
|
||||||
|
pathname.startsWith("/dns/") ||
|
||||||
|
pathname === "/myportal/dns" ||
|
||||||
|
pathname.startsWith("/myportal/dns/")
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -52,6 +52,37 @@ Follow-ups:
|
|||||||
- If needed, triage/fix the existing phase22 auth redirect test harness failure separately to restore full combined suite execution.
|
- If needed, triage/fix the existing phase22 auth redirect test harness failure separately to restore full combined suite execution.
|
||||||
- Expand helper adoption in future slices to other navigation decision call sites if additional duplication emerges.
|
- Expand helper adoption in future slices to other navigation decision call sites if additional duplication emerges.
|
||||||
|
|
||||||
|
### CL-22541-B: breadcrumb route-state helper expansion (label + DNS path helper)
|
||||||
|
|
||||||
|
date: 2026-04-09
|
||||||
|
author: Cline
|
||||||
|
scope: `lib/routing/routeState.js`, `components/breadcrumbs.js`, `components/case/summary.js`, `tests/phase22/route-state-helper.test.cjs`
|
||||||
|
type: change
|
||||||
|
rationale: Continue Priority 3 breadcrumb refactor in a second bounded commit by extracting remaining repeated breadcrumb label and DNS-route-path decision logic into shared pure helpers.
|
||||||
|
impact: Refactor-only extraction for navigation decision logic; no auth/session/CSP/API changes; no intended EN/CY behavior change beyond internal logic centralization.
|
||||||
|
status: completed
|
||||||
|
|
||||||
|
Summary:
|
||||||
|
|
||||||
|
- Extended `lib/routing/routeState.js` with:
|
||||||
|
- `resolveSearchBreadcrumbLabel(...)`
|
||||||
|
- `isDnsRoutePath(pathname)`
|
||||||
|
- Updated `components/breadcrumbs.js` to use `resolveSearchBreadcrumbLabel(...)` and removed inline label decision IIFE.
|
||||||
|
- Updated `components/case/summary.js` to use `isDnsRoutePath(router.pathname)` and removed inline DNS path checks.
|
||||||
|
- Expanded `tests/phase22/route-state-helper.test.cjs` with coverage for:
|
||||||
|
- breadcrumb label resolution matrix
|
||||||
|
- DNS path detection helper
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
|
||||||
|
- `npx eslint lib/routing/routeState.js components/breadcrumbs.js components/case/summary.js tests/phase22/route-state-helper.test.cjs` -> pass with 1 pre-existing warning in `components/case/summary.js` (`react-hooks/exhaustive-deps`).
|
||||||
|
- `node tests/phase22/route-state-helper.test.cjs` -> pass (7/7).
|
||||||
|
- `node tests/phase22/index.test.cjs` -> pass (combined suite).
|
||||||
|
|
||||||
|
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-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
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const loadRouteStateModule = () => {
|
|||||||
|
|
||||||
source = source.replace(/export const\s+/g, "const ");
|
source = source.replace(/export const\s+/g, "const ");
|
||||||
source +=
|
source +=
|
||||||
"\nmodule.exports = { normalizeRouteStateQuery, resolveSearchResultsHref };\n";
|
"\nmodule.exports = { normalizeRouteStateQuery, resolveSearchResultsHref, resolveSearchBreadcrumbLabel, isDnsRoutePath };\n";
|
||||||
|
|
||||||
const context = {
|
const context = {
|
||||||
module: { exports: {} },
|
module: { exports: {} },
|
||||||
@@ -116,6 +116,48 @@ test("routing/routeState supports DNS route override", async () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("routing/routeState resolves breadcrumb label using key and route flags", async () => {
|
||||||
|
const mod = loadRouteStateModule();
|
||||||
|
const getViewAllLabel = (key) =>
|
||||||
|
({ myCases: "My Cases", watchedCases: "Watched Cases" })[key] || null;
|
||||||
|
|
||||||
|
const fromViewAll = mod.resolveSearchBreadcrumbLabel({
|
||||||
|
query: { va: "true", key: "myCases" },
|
||||||
|
getViewAllLabel,
|
||||||
|
advancedLabel: "Advanced",
|
||||||
|
addressLabel: "Address",
|
||||||
|
defaultLabel: "Search"
|
||||||
|
});
|
||||||
|
const fromAdvanced = mod.resolveSearchBreadcrumbLabel({
|
||||||
|
query: { adv: "true" },
|
||||||
|
getViewAllLabel,
|
||||||
|
advancedLabel: "Advanced",
|
||||||
|
addressLabel: "Address",
|
||||||
|
defaultLabel: "Search"
|
||||||
|
});
|
||||||
|
const fromDefault = mod.resolveSearchBreadcrumbLabel({
|
||||||
|
query: {},
|
||||||
|
getViewAllLabel,
|
||||||
|
advancedLabel: "Advanced",
|
||||||
|
addressLabel: "Address",
|
||||||
|
defaultLabel: "Search"
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(fromViewAll, "My Cases");
|
||||||
|
assert.strictEqual(fromAdvanced, "Advanced");
|
||||||
|
assert.strictEqual(fromDefault, "Search");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("routing/routeState identifies dns and myportal dns route prefixes", async () => {
|
||||||
|
const mod = loadRouteStateModule();
|
||||||
|
|
||||||
|
assert.strictEqual(mod.isDnsRoutePath("/dns"), true);
|
||||||
|
assert.strictEqual(mod.isDnsRoutePath("/dns/development"), true);
|
||||||
|
assert.strictEqual(mod.isDnsRoutePath("/myportal/dns"), true);
|
||||||
|
assert.strictEqual(mod.isDnsRoutePath("/myportal/dns/applications"), true);
|
||||||
|
assert.strictEqual(mod.isDnsRoutePath("/case/123"), false);
|
||||||
|
});
|
||||||
|
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
let passed = 0;
|
let passed = 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user