Convert Project route tree to react-router v6 Routes - #424
Conversation
The shared Schedules/Schedule components are mounted at several different base paths (templates, projects, inventory sources, management jobs), so they can't hardcode an absolute base. Schedule.js already derived its base from the location (pathRoot = pathname up to 'schedules'); apply the same technique to Schedules.js and convert both from v5 <Switch>/<Redirect> to v6 <Routes>/<Navigate>. - Schedules.js: drop useRouteMatch; compute the base from useLocation and use it for the list/add/:scheduleId routes (the schedule detail delegates with /*). - Schedule.js: <Switch> -> <Routes>; the exact <Redirect> becomes a <Route> Navigate to details; edit/details kept on their computed pathRoot paths; not-found kept as path="*". Because the routes are computed-absolute, they resolve whether the parent screen is still on v5 <Switch> or already migrated to v6 - so this decouples the shared-component conversion from the Template / Project / ManagementJob / InventorySource / WorkflowJobTemplate screens, which can now be migrated independently afterward. Verified: components/Schedule (13 suites) and all five parent screens that mount <Schedules> pass unchanged.
Migrate the Project list and detail route trees from the react-router v5 <Switch>/<Route>/<Redirect> API to v6 <Routes>/<Route> via react-router-dom-v5-compat. Now unblocked by the shared Schedule component conversion. - Projects.js: <Switch> -> <Routes>; the detail route uses /projects/:id/* so the nested <Project> tree matches. - Project.js: <Switch> -> <Routes> with relative child paths (details, edit, access, notifications, job_templates, schedules/*); the exact <Redirect> becomes an index route that <Navigate>s to details; the schedules tab delegates with schedules/* to the shared <Schedules>; not-found kept as path="*". - Tests: mount Project under the real /projects/:id/* route (drop the react-router-dom useRouteMatch/useParams mocks) and stub the list in Projects.test.js; mock RootAPI.readAssetVariables for the brand-name hook the resolved detail route now mounts. Depends on the shared Schedule component conversion (PR ctrliq#422), included in this branch until that PR merges.
There was a problem hiding this comment.
Pull request overview
Continues the incremental react-router v5 → v6 migration by converting the Project screen’s route trees (and the shared Schedule subtree included from the dependent PR) to the v6 <Routes>/<Route> API via react-router-dom-v5-compat.
Changes:
- Migrated
Projects(list) andProject(detail) route trees from v5Switch/Redirectto v6Routes/Navigate, using nested route patterns (/projects/:id/*,schedules/*). - Updated Project screen tests to mount under the real
/projects/:id/*route (removing route hook mocks) and stub/mocks needed for newly mounted dependencies. - Migrated shared Schedule components’ routing to v6-compatible
<Routes>with base-path derivation fromlocation.pathname.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| awx/ui/src/screens/Project/Projects.js | Converts Projects list routing to v6 <Routes> and nests Project under /projects/:id/*. |
| awx/ui/src/screens/Project/Project.js | Converts Project detail routing to v6 <Routes>, adds index redirect and schedule subtree delegation. |
| awx/ui/src/screens/Project/Projects.test.js | Updates test to provide router history and stubs list component for route resolution. |
| awx/ui/src/screens/Project/Project.test.js | Updates tests to mount under /projects/:id/* and mocks brand-name asset variables dependency. |
| awx/ui/src/components/Schedule/Schedules.js | Converts shared Schedules routing to v6 <Routes> using base URL derived from location. |
| awx/ui/src/components/Schedule/Schedule.js | Converts shared Schedule routing to v6 <Routes>/<Navigate>. |
- Schedule.js: import useParams/useLocation from react-router-dom-v5-compat (not v5) so scheduleId resolves under the v6 parent route. - Schedule.js: the edit route used :id while the component reads scheduleId; use :scheduleId consistently. - Schedules.js: derive baseUrl with substring and handle the 'schedules'- absent case explicitly so it never collapses to a relative path. - Drop the doubled '/* /*' nested-route comment in both files. (cherry picked from commit 4b0b609)
Add a test that mounting at the bare /projects/:id resolves to the details tab (the index <Route> -> <Navigate> replacing the old v5 Redirect).
|
Thanks for the review. Addressed in |
|
Project > Schedules page seems to be broken (blank) but may be a part of the larger Schedules issue that is going on. |
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)
cigamit reported the Sync button looked/behaved wrong. ProjectSyncButton used v5 useRouteMatch(), which resolves to url '/' under the compat router (no v5 route ancestor), so the isDetailsView check was always false. Derive it from useLocation().pathname instead.
The Sync button only shows its 'Sync' label on the details view, which ProjectSyncButton now derives from useLocation; mount the test there.
cigamit
left a comment
There was a problem hiding this comment.
Everything on Projects is working now.

SUMMARY
Continues the react-router v5 → v6 route-tree migration. Converts the Project screen's route trees from the v5
<Switch>/<Route>/<Redirect>API to v6<Routes>/<Route>viareact-router-dom-v5-compat.UI (no behavior change - same URLs, same panels):
Projects.js(list router):<Switch>→<Routes>; the detail route is/projects/:id/*so the nested<Project>tree matches.Project.js(detail router):<Switch>→<Routes>with relative child paths (details,edit,access,notifications,job_templates,schedules/*); the exact<Redirect>becomes an index route that<Navigate>s todetails; the schedules tab delegates withschedules/*to the shared<Schedules>; not-found stayspath="*".Projectunder the real/projects/:id/*route (dropping thereact-router-domuseRouteMatch/useParamsmocks), stub the list inProjects.test.js, and mockRootAPI.readAssetVariablesfor the brand-name hook the now-resolved detail route mounts.ISSUE TYPE
COMPONENT NAME
ADDITIONAL INFORMATION
screens/Projectdirectory passes (11 suites / 66 tests).npm --prefix awx/ui run lintclean on the changed source.