From a6ec22559879a20e718184bac0ab1f22c296550f Mon Sep 17 00:00:00 2001 From: cesnimda Date: Wed, 11 Nov 2026 07:05:29 +0100 Subject: [PATCH] feat(discovery): move mobile filters into accessible drawer --- .../DISCOVERY_MOBILE_FILTERS.md | 9 + .../discovery-mobile-filters/LINT.txt | 0 .../evidence/discovery-mobile-filters/RED.txt | 1127 +++++++++++++++++ .../discovery-mobile-filters/TESTS.txt | 9 + .../discovery-mobile-filters/TYPES.txt | 4 + job-tracker-ui/src/job-discovery.test.tsx | 78 +- job-tracker-ui/src/views/JobDiscoveryPage.tsx | 44 +- 7 files changed, 1268 insertions(+), 3 deletions(-) create mode 100644 docs/ui-modernisation/visual-correction/DISCOVERY_MOBILE_FILTERS.md create mode 100644 docs/ui-modernisation/visual-correction/evidence/discovery-mobile-filters/LINT.txt create mode 100644 docs/ui-modernisation/visual-correction/evidence/discovery-mobile-filters/RED.txt create mode 100644 docs/ui-modernisation/visual-correction/evidence/discovery-mobile-filters/TESTS.txt create mode 100644 docs/ui-modernisation/visual-correction/evidence/discovery-mobile-filters/TYPES.txt diff --git a/docs/ui-modernisation/visual-correction/DISCOVERY_MOBILE_FILTERS.md b/docs/ui-modernisation/visual-correction/DISCOVERY_MOBILE_FILTERS.md new file mode 100644 index 00000000..c2b1721c --- /dev/null +++ b/docs/ui-modernisation/visual-correction/DISCOVERY_MOBILE_FILTERS.md @@ -0,0 +1,9 @@ +# Discovery mobile filters + +The approved A3 refinement calls for a mobile filter drawer while retaining the desktop search rail. This package starts from locale-sort checkpoint `b29c78e86d256f0c4e29f104bcd0c45572116635` on isolated branch `codex/a3-discovery-mobile-filters`. + +At widths up to 1000 px, the existing municipality, source disclosure and saved-search controls open from a named Filters button. Wider layouts retain the permanent rail. Search drafts and saved-search definitions remain in their existing state owner. The municipality control and drawer submit button target the original search form. Search and Jump to results close the drawer and move focus to results. Escape/Close return focus to the trigger. Crossing to the desktop rail closes the modal and focuses the query. Failed saved-search writes remain visible inside the drawer with their draft. + +The initial mobile regression failed three cases against the previous page. The final 28 discovery cases passed, including EN/NB draft/submit/focus, breakpoint transitions, saved-write failure and existing permission, ordering and tracker behaviour. Type-check and scoped lint passed. Raw logs are in `evidence/discovery-mobile-filters/`. + +This package uses the current NAV search contract. New geography, taxonomy, map, providers and data persistence retain their roadmap dependencies. Exported browser, visual and accessibility validation is pending integration. Native-device and final owner acceptance remain open. diff --git a/docs/ui-modernisation/visual-correction/evidence/discovery-mobile-filters/LINT.txt b/docs/ui-modernisation/visual-correction/evidence/discovery-mobile-filters/LINT.txt new file mode 100644 index 00000000..e69de29b diff --git a/docs/ui-modernisation/visual-correction/evidence/discovery-mobile-filters/RED.txt b/docs/ui-modernisation/visual-correction/evidence/discovery-mobile-filters/RED.txt new file mode 100644 index 00000000..67e7417f --- /dev/null +++ b/docs/ui-modernisation/visual-correction/evidence/discovery-mobile-filters/RED.txt @@ -0,0 +1,1127 @@ + +> job-tracker-ui@0.1.0 test +> jest --runInBand job-discovery.test.tsx -t mobile filters|filter breakpoint + + console.error + An update to JobDiscoveryPage inside a test was not wrapped in act(...). + + When testing, code that causes React state updates should be wrapped into act(...): + + act(() => { + /* fire events that update state */ + }); + /* assert on the output */ + + This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act + + 81 | throw new Error("Invalid saved-search response"); + 82 | } + > 83 | if (active) { setSavedSearches(rows); setSavedSearchState("loaded"); } + | ^ + 84 | }) + 85 | .catch(() => { if (active) setSavedSearchState("error"); }); + 86 | return () => { active = false; }; + + at ../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18758:19 + at runWithFiberInDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:874:13) + at warnIfUpdatesNotWrappedWithActDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18757:9) + at scheduleUpdateOnFiber (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:16409:11) + at dispatchSetStateInternal (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9170:13) + at dispatchSetState (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9127:7) + at setSavedSearches (src/views/JobDiscoveryPage.tsx:83:23) + + console.error + An update to JobDiscoveryPage inside a test was not wrapped in act(...). + + When testing, code that causes React state updates should be wrapped into act(...): + + act(() => { + /* fire events that update state */ + }); + /* assert on the output */ + + This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act + + 81 | throw new Error("Invalid saved-search response"); + 82 | } + > 83 | if (active) { setSavedSearches(rows); setSavedSearchState("loaded"); } + | ^ + 84 | }) + 85 | .catch(() => { if (active) setSavedSearchState("error"); }); + 86 | return () => { active = false; }; + + at ../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18758:19 + at runWithFiberInDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:874:13) + at warnIfUpdatesNotWrappedWithActDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18757:9) + at scheduleUpdateOnFiber (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:16409:11) + at dispatchSetStateInternal (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9170:13) + at dispatchSetState (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9127:7) + at setSavedSearchState (src/views/JobDiscoveryPage.tsx:83:47) + + console.error + An update to JobDiscoveryPage inside a test was not wrapped in act(...). + + When testing, code that causes React state updates should be wrapped into act(...): + + act(() => { + /* fire events that update state */ + }); + /* assert on the output */ + + This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act + + 81 | throw new Error("Invalid saved-search response"); + 82 | } + > 83 | if (active) { setSavedSearches(rows); setSavedSearchState("loaded"); } + | ^ + 84 | }) + 85 | .catch(() => { if (active) setSavedSearchState("error"); }); + 86 | return () => { active = false; }; + + at ../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18758:19 + at runWithFiberInDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:874:13) + at warnIfUpdatesNotWrappedWithActDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18757:9) + at scheduleUpdateOnFiber (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:16409:11) + at dispatchSetStateInternal (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9170:13) + at dispatchSetState (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9127:7) + at setSavedSearches (src/views/JobDiscoveryPage.tsx:83:23) + + console.error + An update to JobDiscoveryPage inside a test was not wrapped in act(...). + + When testing, code that causes React state updates should be wrapped into act(...): + + act(() => { + /* fire events that update state */ + }); + /* assert on the output */ + + This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act + + 81 | throw new Error("Invalid saved-search response"); + 82 | } + > 83 | if (active) { setSavedSearches(rows); setSavedSearchState("loaded"); } + | ^ + 84 | }) + 85 | .catch(() => { if (active) setSavedSearchState("error"); }); + 86 | return () => { active = false; }; + + at ../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18758:19 + at runWithFiberInDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:874:13) + at warnIfUpdatesNotWrappedWithActDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18757:9) + at scheduleUpdateOnFiber (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:16409:11) + at dispatchSetStateInternal (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9170:13) + at dispatchSetState (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9127:7) + at setSavedSearchState (src/views/JobDiscoveryPage.tsx:83:47) + + console.error + An update to JobDiscoveryPage inside a test was not wrapped in act(...). + + When testing, code that causes React state updates should be wrapped into act(...): + + act(() => { + /* fire events that update state */ + }); + /* assert on the output */ + + This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act + + 81 | throw new Error("Invalid saved-search response"); + 82 | } + > 83 | if (active) { setSavedSearches(rows); setSavedSearchState("loaded"); } + | ^ + 84 | }) + 85 | .catch(() => { if (active) setSavedSearchState("error"); }); + 86 | return () => { active = false; }; + + at ../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18758:19 + at runWithFiberInDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:874:13) + at warnIfUpdatesNotWrappedWithActDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18757:9) + at scheduleUpdateOnFiber (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:16409:11) + at dispatchSetStateInternal (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9170:13) + at dispatchSetState (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9127:7) + at setSavedSearches (src/views/JobDiscoveryPage.tsx:83:23) + + console.error + An update to JobDiscoveryPage inside a test was not wrapped in act(...). + + When testing, code that causes React state updates should be wrapped into act(...): + + act(() => { + /* fire events that update state */ + }); + /* assert on the output */ + + This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act + + 81 | throw new Error("Invalid saved-search response"); + 82 | } + > 83 | if (active) { setSavedSearches(rows); setSavedSearchState("loaded"); } + | ^ + 84 | }) + 85 | .catch(() => { if (active) setSavedSearchState("error"); }); + 86 | return () => { active = false; }; + + at ../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18758:19 + at runWithFiberInDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:874:13) + at warnIfUpdatesNotWrappedWithActDEV (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:18757:9) + at scheduleUpdateOnFiber (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:16409:11) + at dispatchSetStateInternal (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9170:13) + at dispatchSetState (../../../direct-roadmap-integration/Job tracker/job-tracker-ui/node_modules/react-dom/cjs/react-dom-client.development.js:9127:7) + at setSavedSearchState (src/views/JobDiscoveryPage.tsx:83:47) + +FAIL src/job-discovery.test.tsx + ● en mobile filters retain drafts, restore focus and submit the existing search + + TestingLibraryElementError: Unable to find an accessible element with the role "button" and name "Search filters" + + Here are the accessible roles: + + form: + + Name "Search NAV": +
+ + -------------------------------------------------- + textbox: + + Name "Role or company": + + + Name "Municipality": + + + Name "Search name": + + + -------------------------------------------------- + button: + + Name "Search NAV": + +
+
+