Convert the Inventory screen route trees to react-router v6 Routes - #421
Conversation
First batch of the Inventory screen migration to react-router v6. - AdvancedInventoryHost: <Switch> -> <Routes>; useRouteMatch is replaced with useParams (inventoryType, hostId) and an explicit hostBaseUrl; the exact <Redirect> becomes a <Route> that <Navigate>s to details; not-found kept as path="*". - AdvancedInventoryHosts: <Switch> -> <Routes>; the host detail route gets a trailing /* so the nested <AdvancedInventoryHost> tree matches. Both keep absolute /inventories/:inventoryType/:id/hosts paths, so they resolve under the still-v5 Inventory parents; existing tests pass unchanged.
Second batch of the Inventory screen migration: the standard inventory host subtree. - InventoryHosts: <Switch> -> <Routes>; host add/list use element; the host detail route gets /* to delegate to <InventoryHost>. - InventoryHost: <Switch> -> <Routes>; useRouteMatch replaced with useParams (hostId) + an explicit hostBaseUrl; exact <Redirect> becomes a <Route> Navigate to details; the groups tab delegates with groups/*; not-found kept as path="*". - InventoryHostGroups: <Switch> -> <Routes> keeping its absolute /inventories/inventory/:id/hosts/:hostId/groups path. All keep absolute paths, so they resolve under the still-v5 Inventory parents and existing tests pass unchanged.
Third batch of the Inventory screen migration: the inventory group subtree. - InventoryGroups: <Switch> -> <Routes>; group add/list use element; the group detail route gets /* to delegate to <InventoryGroup>. - InventoryGroup: <Switch> -> <Routes>; exact <Redirect> becomes a <Route> Navigate to details (built from the useParams inventoryType/ inventoryId/groupId); the nested_hosts and nested_groups tabs delegate with /*; not-found kept as path="*". - InventoryGroupHosts / InventoryRelatedGroups: <Switch> -> <Routes> keeping their absolute nested_hosts / nested_groups paths. - InventoryGroup.test.js: drop the conflicting hoisted useParams module mocks and mount under the real v6 /inventories/:inventoryType/:id/ groups/:groupId/* route so params resolve from the URL. All keep absolute paths, so they resolve under the still-v5 Inventory parents.
…outes Fourth batch of the Inventory screen migration: the standard inventory detail and its sources subtree. - Inventory.js: <Switch> -> <Routes>; useRouteMatch replaced with useParams (id) + an explicit inventoryBaseUrl; the exact <Redirect> and the kind-mismatch <Redirect> become <Navigate>; the groups/hosts/ sources tabs delegate with /*; details/access/edit/jobs/job_templates use the element prop; not-found kept as path="*". - InventorySources: <Switch> -> <Routes>; the source detail route gets /* to delegate to the (still-v5) <InventorySource> - its v5 Switch matches the absolute location, so it keeps working until it is converted with the shared Schedules cluster. All keep absolute paths.
Final Inventory batch: the smart/constructed/federated inventory detail screens and the top-level Inventories dispatcher. - SmartInventory, ConstructedInventory, FederatedInventory: <Switch> -> <Routes>; useRouteMatch replaced with useParams + an explicit base url; the exact <Redirect> and the kind-mismatch <Redirect> become <Navigate>; the hosts and groups tabs delegate with /*; not-found kept as path="*". - Inventories.js: <Switch> -> <Routes>; the add routes use the element prop; each inventory-type detail route gets /* so its nested <Routes> resolves. - Inventories.test.js: mount at /inventories and stub InventoryList so the list route renders without an API call. Only the InventorySource detail remains on v5 (it renders the shared Schedules component and is handled with the Schedules cluster).
There was a problem hiding this comment.
Pull request overview
Migrates the Inventory screen’s route trees from react-router v5 (<Switch>/<Route>/<Redirect>) to react-router v6-style routing (<Routes>/<Route>/<Navigate>) using react-router-dom-v5-compat, while preserving the existing absolute /inventories/... URL structure and nested route behavior.
Changes:
- Converted Inventory detail screens (Inventory / Smart / Constructed / Federated) to
<Routes>and replaced v5 redirects with<Navigate replace>. - Updated nested Inventory subtrees (hosts, groups, sources, related groups, etc.) to use v6 routing patterns, including
/*where delegation to nested route trees is required. - Updated tests to mount components under real v6-compatible routes and to stub inventory listing where needed.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| awx/ui/src/screens/Inventory/SmartInventory.js | Converts Smart Inventory detail routing to <Routes>/<Navigate> and replaces useRouteMatch with useParams + explicit base URL. |
| awx/ui/src/screens/Inventory/InventorySources/InventorySources.js | Converts sources route tree to <Routes>, adding /* delegation for the nested InventorySource subtree. |
| awx/ui/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroups.js | Converts related-groups subtree routing to <Routes>. |
| awx/ui/src/screens/Inventory/InventoryHosts/InventoryHosts.js | Converts hosts subtree routing to <Routes>, adding /* delegation for nested host detail routes. |
| awx/ui/src/screens/Inventory/InventoryHostGroups/InventoryHostGroups.js | Converts host-groups subtree routing to <Routes>. |
| awx/ui/src/screens/Inventory/InventoryHost/InventoryHost.js | Converts inventory host detail routing to <Routes>/<Navigate> and switches from useRouteMatch to useParams. |
| awx/ui/src/screens/Inventory/InventoryGroups/InventoryGroups.js | Converts groups subtree routing to <Routes>, adding /* delegation for nested group detail routes. |
| awx/ui/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHosts.js | Converts group-hosts subtree routing to <Routes>. |
| awx/ui/src/screens/Inventory/InventoryGroup/InventoryGroup.test.js | Updates tests to mount under a real v6-compatible route so useParams resolves from the URL. |
| awx/ui/src/screens/Inventory/InventoryGroup/InventoryGroup.js | Converts group detail routing to <Routes>/<Navigate> and replaces v5 redirect behavior. |
| awx/ui/src/screens/Inventory/Inventory.js | Converts standard Inventory detail routing to <Routes>/<Navigate> and switches from useRouteMatch to useParams. |
| awx/ui/src/screens/Inventory/Inventories.test.js | Adjusts test mounting to /inventories and stubs the list so the route can render without API calls. |
| awx/ui/src/screens/Inventory/Inventories.js | Converts the top-level Inventories dispatcher routing to <Routes> and adds /* delegation for each inventory detail screen. |
| awx/ui/src/screens/Inventory/FederatedInventory.js | Converts Federated Inventory detail routing to <Routes>/<Navigate> and switches from useRouteMatch to useParams. |
| awx/ui/src/screens/Inventory/ConstructedInventory.js | Converts Constructed Inventory detail routing to <Routes>/<Navigate> and switches from useRouteMatch to useParams. |
| awx/ui/src/screens/Inventory/AdvancedInventoryHosts/AdvancedInventoryHosts.js | Converts advanced-hosts subtree routing to <Routes>, adding /* delegation for nested host detail routes. |
| awx/ui/src/screens/Inventory/AdvancedInventoryHost/AdvancedInventoryHost.js | Converts advanced host detail routing to <Routes>/<Navigate> and replaces useRouteMatch with useParams + explicit base URL. |
The fallback 'View Inventory Details' link built a literal '/inventories/:inventoryType/...' path, which navigates to a non-existent URL. Interpolate inventoryType from useParams() so the link resolves.
|
Thanks for the review. Fixed in |
cigamit reported that clicking an inventory threw 'page not found' on every tab. The dispatcher (Inventories.js) was converted to v6 (path "...:id/*"), which makes each detail screen's <Routes> a descendant whose paths resolve relative to the parent match. The screens used ABSOLUTE paths (/inventories/inventory/:id/details), so nothing matched and everything fell through to the not-found route. - Convert the whole Inventory subtree to relative route paths (matching the merged Application screen), with index routes for the bare-:id redirects. - Route inventory detail through a single /inventories/:inventoryType/:id/* entry so inventoryType is a real route param again (the nested group/host screens read it via useParams to build links); a small type-router picks the right detail screen by kind. - Update the isolated tests to mount each screen under its v6 parent route (they were mounting top-level, which is exactly why the regression slipped through), and add a dispatcher-level test that a detail tab resolves rather than falling through to not-found.
InventorySource is mounted as a descendant of the v6 inventory route tree (Inventory -> InventorySources via sources/* -> InventorySource via :sourceId/*), but it was still a v5 <Switch> with relative path strings, which v5 cannot match. Its tabs and the schedules sub-route fell through to the not-found route. Convert it to v6 <Routes>: read :sourceId via useParams, build URLs from inventory.id, use relative <Route> elements, and mount <Schedules> under schedules/* so its nested route tree resolves.
cigamit reported that opening a schedule's details fails. <Schedules> is mounted by the parent screens via a ".../schedules/*" route, so it is a v6 descendant; it (and <Schedule>) built absolute baseUrl/pathRoot-derived route paths, which do not match in that descendant context, so the add/detail/edit routes never resolved. Use relative route paths (add, :scheduleId/*, index in Schedules; index -> details, details, edit in Schedule). The pathRoot-derived absolute values are kept only for the tab/breadcrumb Links, not the route paths. Mount the Schedules test under its parent route. (cherry picked from commit 4dd8df0)
The Inventory route tree is now v6, but its leaf components (lists, detail, add/edit, list items) still read :id / :inventoryType / :groupId / :hostId through react-router v5 useParams, which returns nothing inside a v6 <Routes> tree. As a result the Hosts, Groups and Sources tabs fetched /api/v2/inventories/undefined/... and rendered a not-found error. Read those params from react-router-dom-v5-compat in all 16 affected components, and drop the now-empty useRouteMatch().url in InventoryList in favor of the fixed /inventories base. Update the tests to mount each component under a real v6 route that supplies the params instead of mocking the router, so they exercise the actual routing.
|
Pushed a fix for the Groups/Hosts/Sources errors you hit (the /api/v2/inventories/undefined/... calls). Root cause: the inventory route tree is v6 now, but its leaf components (the lists, detail, add/edit and list-item components) were still reading :id / :inventoryType / :groupId through react-router v5 useParams, which returns nothing inside a v6 Routes tree. So the id came through as undefined and the API calls 404'd. Changes:
Verified in a local browser against real data: Details, Access, Groups, Hosts, Sources, the inventory list, and the inventory source Schedules list and detail all load correctly now. |


SUMMARY
Continues the react-router v5 → v6 route-tree migration. Converts the Inventory screen - the largest remaining screen family (16 nested route trees) - from the v5
<Switch>/<Route>/<Redirect>API to v6<Routes>/<Route>viareact-router-dom-v5-compat. Done as a single PR with several commits.UI (no behavior change - same URLs, same panels). Each route tree keeps its absolute
/inventories/...paths, so it resolves correctly regardless of conversion order; every route that delegates to a nested screen gets a trailing/*;useRouteMatchis replaced withuseParams+ an explicit base url; exact<Redirect>s (and the inventory-kind mismatch redirects) become<Navigate>.Converted (15 of the 16 trees):
/*)Deferred (1 tree):
Schedulescomponent, so it stays on v5 here and is handled with the shared-Schedulescluster. Its v5<Switch>keeps working under the now-v6InventorySourcesparent because it matches the absolute location.ISSUE TYPE
COMPONENT NAME
ADDITIONAL INFORMATION
screens/Inventorydirectory passes (76 suites / 345 tests). A couple of tests needed updates (drop conflicting hoisteduseParamsmodule mocks and mount under the real v6 route; stub the inventory list / mount at/inventories); the rest pass unchanged because the routes keep absolute paths.npm --prefix awx/ui run lintclean on the changed source.