Skip to content

react-router migration batch 3: Inventory and Setting screens#384

Closed
blaipr wants to merge 3 commits into
ctrliq:mainfrom
blaipr:feature/react-router-batch-3
Closed

react-router migration batch 3: Inventory and Setting screens#384
blaipr wants to merge 3 commits into
ctrliq:mainfrom
blaipr:feature/react-router-batch-3

Conversation

@blaipr

@blaipr blaipr commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

📋 Merge instructions — all 13 open PRs, any order, zero conflicts

Every pair of open PRs has been verified conflict-free with git merge-tree (0 conflicts across all 78 pairs), and the union of all 13 was integration-tested green (Python suite 3477 passed, Jest 2873 passed, lint, build, licenses). Merge in any order you like. Two recommendations, not requirements:

The full queue:

  1. Merge PR Upgrade twisted, kubernetes, pyyaml, Cython and Django to latest allowed versions #374 - Upgrade twisted, kubernetes, pyyaml, Cython and Django to latest allowed versions
  2. Merge PR Upgrade django-oauth-toolkit 1.7.1 to 3.3.0 #376 - Upgrade django-oauth-toolkit 1.7.1 to 3.3.0
  3. Merge PR Upgrade styled-components from 5 to 6 #380 - Upgrade styled-components from 5 to 6
  4. Merge PR Begin react-router 5 → 6 migration via react-router-dom-v5-compat #381 - Begin react-router 5 → 6 migration via react-router-dom-v5-compat
  5. Merge PR react-router migration batch 1: shared components, contexts and hooks #382 - react-router migration batch 1: shared components, contexts and hooks
  6. Merge PR react-router migration batch 2: screen directories (all except Inventory and Setting) #383 - react-router migration batch 2: screen directories (all except Inventory and Setting)
  7. Merge PR react-router migration batch 3: Inventory and Setting screens #384 - react-router migration batch 3: Inventory and Setting screens ⬅️ this PR
  8. Merge PR Add React Testing Library migration infrastructure and first conversions #385 - Add React Testing Library migration infrastructure and first conversions
  9. Merge PR Remove EOL msrestazure, msrest and adal dependencies #386 - Remove EOL msrestazure, msrest and adal dependencies
  10. Merge PR Fix cross-test mock leak behind the flaky parallel test failures #388 - Fix cross-test mock leak behind the flaky parallel test failures
  11. Merge PR Build Activity Stream links for inventory source sync schedules #389 - Build Activity Stream links for inventory source sync schedules
  12. Merge PR Surface an error when the webhook credential type lookup returns nothing #390 - Surface an error when the webhook credential type lookup returns nothing
  13. Merge PR Modernize the frontend toolchain: Lingui 6, ESLint 9 and @dagrejs/dagre #391 - Modernize the frontend toolchain: Lingui 6, ESLint 9 and @dagrejs/dagre

SUMMARY

Third batch of the incremental react-router 5 → 6 migration: the two largest screen directories, Inventory and Setting (74 files), using the established recipe (useHistoryuseNavigate, history.locationuseLocation(), params-only useRouteMatchuseParams(), conditional RedirectNavigate; route trees stay on v5 for the final phase).

Two findings worth reviewer attention:

  1. navigate() from the compat package is not referentially stable (its identity changes with the location), unlike v5's history object. Redirect-on-result effects that listed history in their deps would refire after unrelated navigations if mechanically converted to navigate. The five affected useEffects (SmartInventoryAdd/Edit, InventorySourceAdd/Edit, SubscriptionEdit) drop navigate from deps with an explanatory eslint-disable, preserving exact v5 behavior. This was caught by an existing test — the post-submit redirect effect refired and overrode the cancel navigation.
  2. v6 navigation drops custom location fields. UIEdit passed a custom hardReload flag on the v5 location object; it now travels in navigation state (navigate(..., { state: { hardReload: true } })) and UIDetail reads location.state?.hardReload. history.go() becomes navigate(0).

Test changes: the ConstructedInventoryDetail RTL suite mounts with a bare v5 Router and gains the controlled v6 Router layer; UIEdit assertions read location.state.

Stacked on #381; parallel to #382 and #383 (disjoint files, any merge order once the bridge lands). Remaining after this: the route-tree phase (Switch/Route/match.path, prefix-match useRouteMatch, root Switch in App.js), then the v6 flip.

ISSUE TYPE

  • New or Enhanced Feature

COMPONENT NAME

  • UI

ASCENDER VERSION

awx: 25.4.1.dev5+gcda0899.d20260610

ADDITIONAL INFORMATION

All UI gates run against this branch state:

npm --prefix awx/ui run lint     # clean
npm --prefix awx/ui run test     # 544 suites passed (1 skipped), 2869 tests passed (5 skipped)
npm --prefix awx/ui run build    # production build succeeds

Heads-up: the same navigate-in-deps pattern exists at three sites in #382/#383 (AddResourceRole, CredentialAdd, CredentialEdit); fix commits are being pushed to those branches.

blaipr added 2 commits June 11, 2026 10:26
Stage 2 of the React stack modernization. react-router-dom 6/7 removed
Switch, useHistory, useRouteMatch, Redirect and withRouter, which 243
files here still use, so the migration has to be incremental. This sets
up the official bridge and migrates the first screen:

- Add react-router-dom-v5-compat (ships router v6 alongside v5) and
  mount CompatRouter inside the app's HashRouter, so v5 and v6 routing
  contexts coexist and components can be migrated file by file.
- Wire the v6 context into testUtils/enzymeHelpers: the v5 Router keeps
  its history subscription and drives re-renders, while a fully
  controlled nested v6 Router (location from v5 context, navigator =
  the shared history) provides the v6 context without a second
  subscription - no act() warnings, and shallow rendering still works.
- Migrate screens/Login as the demonstration slice: Redirect becomes
  Navigate (from the compat package), and the withRouter wrapper is
  dropped (the component never used the injected props).
- Remove a test.only in Login.test.js that had silenced the other 14
  Login tests since the initial import, and fix the two assertions that
  had rotted while dark (the custom login screen has no LoginMainHeader;
  branding-fetch errors fall back to the default logo without a modal).
  The suite now runs 2869 tests, 14 more than before.

Migration recipe for follow-up PRs, per component:
  useHistory().push(x)  -> useNavigate(); navigate(x)
  useRouteMatch().params -> useParams()
  <Redirect to={x} />    -> <Navigate to={x} />
  withRouter(C)          -> hooks (or delete if props unused)
importing from 'react-router-dom-v5-compat'; the root Switch in App.js
migrates last, then react-router-dom flips to v6 and the compat package
is removed.
Migrates the two largest screen directories (74 files) to the
react-router-dom-v5-compat APIs using the established recipe
(useHistory -> useNavigate, history.location -> useLocation, params-only
useRouteMatch -> useParams, conditional Redirect -> Navigate; route
trees stay on v5 for the final phase).

Two findings specific to this batch:

- navigate() from the compat package is not referentially stable (it
  depends on the current location), so redirect-on-result effects that
  previously listed the stable v5 history object in their deps would
  refire after unrelated navigations. The five affected useEffects
  (SmartInventoryAdd/Edit, InventorySourceAdd/Edit, SubscriptionEdit)
  drop navigate from their deps with an explanatory eslint-disable,
  preserving the exact v5 behavior. Caught by the SmartInventoryAdd
  cancel test: the post-submit redirect effect refired and overrode the
  cancel navigation.

- UIEdit passed a custom hardReload field on the v5 location object;
  v6 navigation only carries pathname/search/hash/state, so it moves to
  navigation state (navigate(..., { state: { hardReload: true } })) and
  UIDetail reads location.state.hardReload. history.go() with no
  argument becomes navigate(0).

The ConstructedInventoryDetail RTL suite mounts with a bare v5 Router
and now needs the v6 context; its wrapper gains the controlled v6
Router layer.
test_licenses requires every package.json dependency to have a matching
file in licenses/ui (caught by an integration run of the full Python
suite over all open PRs combined).

(cherry picked from commit c8103b1)
@blaipr

blaipr commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #392, which unifies the v5-compat bridge and all three migration batches into a single PR (one squashed commit, identical content, full gates green). Done as part of making the whole queue conflict-free and mergeable in any order.

@blaipr blaipr closed this Jun 11, 2026
@blaipr blaipr deleted the feature/react-router-batch-3 branch June 11, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant