From c8f274c7d1c667eb21792f77c1159657e1f1bf60 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Sun, 29 Mar 2026 19:18:41 +0200 Subject: [PATCH] build(web)!: upgrade to react-router v7 replace react-router-dom v6 with react-router v7, updating all imports from "react-router-dom" to "react-router" Co-Authored-By: Claude Opus 4.6 (1M context) --- webui2/package.json | 2 +- webui2/pnpm-lock.yaml | 54 +++++++++++------------ webui2/src/App.tsx | 2 +- webui2/src/__generated__/graphql.ts | 8 +++- webui2/src/components/bugs/BugRow.tsx | 2 +- webui2/src/components/bugs/Timeline.tsx | 2 +- webui2/src/components/code/CommitList.tsx | 2 +- webui2/src/components/code/FileTree.tsx | 2 +- webui2/src/components/layout/Header.tsx | 2 +- webui2/src/components/layout/Shell.tsx | 2 +- webui2/src/lib/repo.tsx | 2 +- webui2/src/pages/BugDetailPage.tsx | 2 +- webui2/src/pages/CodePage.tsx | 2 +- webui2/src/pages/CommitPage.tsx | 2 +- webui2/src/pages/ErrorPage.tsx | 2 +- webui2/src/pages/NewBugPage.tsx | 2 +- webui2/src/pages/RepoPickerPage.tsx | 2 +- webui2/src/pages/UserProfilePage.tsx | 2 +- 18 files changed, 49 insertions(+), 45 deletions(-) diff --git a/webui2/package.json b/webui2/package.json index 2a87b39f7c30dabc91c073bb2bf46526bde14ddc..3edeb7ce98917354848efe8c79daea6cea8ff714 100644 --- a/webui2/package.json +++ b/webui2/package.json @@ -30,7 +30,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "react-markdown": "^10.1.0", - "react-router-dom": "^6.28.0", + "react-router": "^7.13.2", "rehype-autolink-headings": "^7.1.0", "rehype-external-links": "^3.0.0", "rehype-raw": "^7.0.0", diff --git a/webui2/pnpm-lock.yaml b/webui2/pnpm-lock.yaml index 668285cd80a6c84fda12183a6de52eb597f31fff..44abe53a1a6021474248606dee61e8205c83895b 100644 --- a/webui2/pnpm-lock.yaml +++ b/webui2/pnpm-lock.yaml @@ -53,9 +53,9 @@ importers: react-markdown: specifier: ^10.1.0 version: 10.1.0(@types/react@19.2.14)(react@19.2.4) - react-router-dom: - specifier: ^6.28.0 - version: 6.30.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-router: + specifier: ^7.13.2 + version: 7.13.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) rehype-autolink-headings: specifier: ^7.1.0 version: 7.1.0 @@ -1275,10 +1275,6 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - '@remix-run/router@1.23.2': - resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==} - engines: {node: '>=14.0.0'} - '@repeaterjs/repeater@3.0.6': resolution: {integrity: sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==} @@ -1665,6 +1661,10 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + cosmiconfig@8.3.6: resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} engines: {node: '>=14'} @@ -2626,18 +2626,15 @@ packages: '@types/react': optional: true - react-router-dom@6.30.3: - resolution: {integrity: sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' - - react-router@6.30.3: - resolution: {integrity: sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==} - engines: {node: '>=14.0.0'} + react-router@7.13.2: + resolution: {integrity: sha512-tX1Aee+ArlKQP+NIUd7SE6Li+CiGKwQtbS+FfRxPX6Pe4vHOo6nr9d++u5cwg+Z8K/x8tP+7qLmujDtfrAoUJA==} + engines: {node: '>=20.0.0'} peerDependencies: - react: '>=16.8' + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true react-style-singleton@2.2.3: resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} @@ -2760,6 +2757,9 @@ packages: sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + shell-quote@1.8.3: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} @@ -4279,8 +4279,6 @@ snapshots: '@radix-ui/rect@1.1.1': {} - '@remix-run/router@1.23.2': {} - '@repeaterjs/repeater@3.0.6': {} '@rolldown/binding-android-arm64@1.0.0-rc.12': @@ -4620,6 +4618,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie@1.1.1: {} + cosmiconfig@8.3.6(typescript@6.0.2): dependencies: import-fresh: 3.3.1 @@ -5787,17 +5787,13 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 - react-router-dom@6.30.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + react-router@7.13.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - '@remix-run/router': 1.23.2 + cookie: 1.1.1 react: 19.2.4 + set-cookie-parser: 2.7.2 + optionalDependencies: react-dom: 19.2.4(react@19.2.4) - react-router: 6.30.3(react@19.2.4) - - react-router@6.30.3(react@19.2.4): - dependencies: - '@remix-run/router': 1.23.2 - react: 19.2.4 react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.4): dependencies: @@ -5968,6 +5964,8 @@ snapshots: tslib: 2.8.1 upper-case-first: 2.0.2 + set-cookie-parser@2.7.2: {} + shell-quote@1.8.3: {} signal-exit@4.1.0: {} diff --git a/webui2/src/App.tsx b/webui2/src/App.tsx index bc94c95ec9b81ad0ff255ea782ab6e052796e9fe..46d5242c2ca42453dcfdda837410b22543b1644f 100644 --- a/webui2/src/App.tsx +++ b/webui2/src/App.tsx @@ -1,4 +1,4 @@ -import { createBrowserRouter, RouterProvider } from "react-router-dom"; +import { createBrowserRouter, RouterProvider } from "react-router"; import { Shell } from "@/components/layout/Shell"; import { RepoShell } from "@/lib/repo"; diff --git a/webui2/src/__generated__/graphql.ts b/webui2/src/__generated__/graphql.ts index 7027302d7fdd32b03f75c0ee591556d15ac64d99..ea4662f9d761bf217e34c9308f5456b9502edbe3 100644 --- a/webui2/src/__generated__/graphql.ts +++ b/webui2/src/__generated__/graphql.ts @@ -1174,7 +1174,13 @@ export type BugDetailQueryVariables = Exact<{ }>; -export type BugDetailQuery = { __typename?: 'Query', repository?: { __typename?: 'Repository', bug?: { __typename?: 'Bug', id: string, humanId: string, status: Status, title: string, createdAt: string, lastEdit: string, labels: Array<{ __typename?: 'Label', name: string, color: { __typename?: 'Color', R: number, G: number, B: number } }>, author: { __typename?: 'Identity', id: string, humanId: string, displayName: string, avatarUrl?: string | null }, participants: { __typename?: 'IdentityConnection', nodes: Array<{ __typename?: 'Identity', id: string, humanId: string, displayName: string, avatarUrl?: string | null }> }, timeline: { __typename?: 'BugTimelineItemConnection', nodes: Array<{ __typename: 'BugAddCommentTimelineItem', message: string, createdAt: string, lastEdit: string, edited: boolean, id: string, author: { __typename?: 'Identity', id: string, humanId: string, displayName: string, avatarUrl?: string | null } } | { __typename: 'BugCreateTimelineItem', message: string, createdAt: string, lastEdit: string, edited: boolean, id: string, author: { __typename?: 'Identity', id: string, humanId: string, displayName: string, avatarUrl?: string | null } } | { __typename: 'BugLabelChangeTimelineItem', date: string, id: string, author: { __typename?: 'Identity', humanId: string, displayName: string }, added: Array<{ __typename?: 'Label', name: string, color: { __typename?: 'Color', R: number, G: number, B: number } }>, removed: Array<{ __typename?: 'Label', name: string, color: { __typename?: 'Color', R: number, G: number, B: number } }> } | { __typename: 'BugSetStatusTimelineItem', date: string, status: Status, id: string, author: { __typename?: 'Identity', humanId: string, displayName: string } } | { __typename: 'BugSetTitleTimelineItem', date: string, title: string, was: string, id: string, author: { __typename?: 'Identity', humanId: string, displayName: string } }> } } | null } | null }; +export type BugDetailQuery = { __typename?: 'Query', repository?: { __typename?: 'Repository', bug?: { __typename?: 'Bug', id: string, humanId: string, status: Status, title: string, createdAt: string, lastEdit: string, labels: Array<{ __typename?: 'Label', name: string, color: { __typename?: 'Color', R: number, G: number, B: number } }>, author: { __typename?: 'Identity', id: string, humanId: string, displayName: string, avatarUrl?: string | null }, participants: { __typename?: 'IdentityConnection', nodes: Array<{ __typename?: 'Identity', id: string, humanId: string, displayName: string, avatarUrl?: string | null }> }, timeline: { __typename?: 'BugTimelineItemConnection', nodes: Array< + | { __typename: 'BugAddCommentTimelineItem', message: string, createdAt: string, lastEdit: string, edited: boolean, id: string, author: { __typename?: 'Identity', id: string, humanId: string, displayName: string, avatarUrl?: string | null } } + | { __typename: 'BugCreateTimelineItem', message: string, createdAt: string, lastEdit: string, edited: boolean, id: string, author: { __typename?: 'Identity', id: string, humanId: string, displayName: string, avatarUrl?: string | null } } + | { __typename: 'BugLabelChangeTimelineItem', date: string, id: string, author: { __typename?: 'Identity', humanId: string, displayName: string }, added: Array<{ __typename?: 'Label', name: string, color: { __typename?: 'Color', R: number, G: number, B: number } }>, removed: Array<{ __typename?: 'Label', name: string, color: { __typename?: 'Color', R: number, G: number, B: number } }> } + | { __typename: 'BugSetStatusTimelineItem', date: string, status: Status, id: string, author: { __typename?: 'Identity', humanId: string, displayName: string } } + | { __typename: 'BugSetTitleTimelineItem', date: string, title: string, was: string, id: string, author: { __typename?: 'Identity', humanId: string, displayName: string } } + > } } | null } | null }; export type BugListQueryVariables = Exact<{ ref?: InputMaybe; diff --git a/webui2/src/components/bugs/BugRow.tsx b/webui2/src/components/bugs/BugRow.tsx index e73afd58338f6c312aded50e15856396085b35d3..eaa9582fd1e7c3afcbb5ca89f1e5c1e9e92f1fda 100644 --- a/webui2/src/components/bugs/BugRow.tsx +++ b/webui2/src/components/bugs/BugRow.tsx @@ -1,6 +1,6 @@ import { formatDistanceToNow } from "date-fns"; import { MessageSquare, CircleDot, CircleCheck } from "lucide-react"; -import { Link } from "react-router-dom"; +import { Link } from "react-router"; import { Status } from "@/__generated__/graphql"; diff --git a/webui2/src/components/bugs/Timeline.tsx b/webui2/src/components/bugs/Timeline.tsx index 6cff6a89ce8090d9c19b0d64a874b11b0c4ae5b8..769930093c927d28528017899e6c800b612bcb06 100644 --- a/webui2/src/components/bugs/Timeline.tsx +++ b/webui2/src/components/bugs/Timeline.tsx @@ -1,7 +1,7 @@ import { formatDistanceToNow } from "date-fns"; import { Tag, GitPullRequestClosed, Pencil, CircleDot } from "lucide-react"; import { useState } from "react"; -import { Link } from "react-router-dom"; +import { Link } from "react-router"; import { Status, diff --git a/webui2/src/components/code/CommitList.tsx b/webui2/src/components/code/CommitList.tsx index 916bd841e50da4e203405217cb181adcc2a67acc..b54f1ad12c5284b23e9366a6f4fae4c79c8ba6fd 100644 --- a/webui2/src/components/code/CommitList.tsx +++ b/webui2/src/components/code/CommitList.tsx @@ -5,7 +5,7 @@ import { gql, useQuery } from "@apollo/client"; import { formatDistanceToNow } from "date-fns"; import { GitCommit } from "lucide-react"; import { useState } from "react"; -import { Link } from "react-router-dom"; +import { Link } from "react-router"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; diff --git a/webui2/src/components/code/FileTree.tsx b/webui2/src/components/code/FileTree.tsx index 5d1090ecefcdcb7dd20b14f37980853263503fda..742c705729c3a8b90bb7a9e86820ce2af0ee612d 100644 --- a/webui2/src/components/code/FileTree.tsx +++ b/webui2/src/components/code/FileTree.tsx @@ -1,6 +1,6 @@ import { formatDistanceToNow } from "date-fns"; import { Folder, File } from "lucide-react"; -import { Link } from "react-router-dom"; +import { Link } from "react-router"; import type { GitTreeEntry } from "@/__generated__/graphql"; import { Skeleton } from "@/components/ui/skeleton"; diff --git a/webui2/src/components/layout/Header.tsx b/webui2/src/components/layout/Header.tsx index e0de44737547c1cf4ebbba7768c949fbbd53e3a5..eed8fbdd447d4ba98a8091d187f02dee6045ebe4 100644 --- a/webui2/src/components/layout/Header.tsx +++ b/webui2/src/components/layout/Header.tsx @@ -7,7 +7,7 @@ // action when logged in. import { Bug, Plus, Sun, Moon, LogIn, LogOut } from "lucide-react"; -import { Link, useMatch, NavLink } from "react-router-dom"; +import { Link, useMatch, NavLink } from "react-router"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; diff --git a/webui2/src/components/layout/Shell.tsx b/webui2/src/components/layout/Shell.tsx index 39cfc54cc9e681a3ceacdfc3f2672147e9a60475..9f30e4569c0468c1dc2ef6530538ecd971485a90 100644 --- a/webui2/src/components/layout/Shell.tsx +++ b/webui2/src/components/layout/Shell.tsx @@ -1,4 +1,4 @@ -import { Outlet } from "react-router-dom"; +import { Outlet } from "react-router"; import { Header } from "./Header"; diff --git a/webui2/src/lib/repo.tsx b/webui2/src/lib/repo.tsx index 766f16e1a6f3555e67bc9497f8a5ff529be8dbf0..49de30c9697e45bcbef9425d2453c8dfa0a2fd66 100644 --- a/webui2/src/lib/repo.tsx +++ b/webui2/src/lib/repo.tsx @@ -7,7 +7,7 @@ // - Pass the slug as `ref` to all GraphQL repository queries. import { createContext, useContext } from "react"; -import { useParams, Outlet } from "react-router-dom"; +import { useParams, Outlet } from "react-router"; const RepoContext = createContext(null); diff --git a/webui2/src/pages/BugDetailPage.tsx b/webui2/src/pages/BugDetailPage.tsx index cd5059df8f562918405be30be662cbe36a4d2748..add1aa2dfd562d838d831e10e19e4f31057412fc 100644 --- a/webui2/src/pages/BugDetailPage.tsx +++ b/webui2/src/pages/BugDetailPage.tsx @@ -1,6 +1,6 @@ import { formatDistanceToNow } from "date-fns"; import { ArrowLeft } from "lucide-react"; -import { useParams, Link } from "react-router-dom"; +import { useParams, Link } from "react-router"; import { useBugDetailQuery } from "@/__generated__/graphql"; import { CommentBox } from "@/components/bugs/CommentBox"; diff --git a/webui2/src/pages/CodePage.tsx b/webui2/src/pages/CodePage.tsx index e76aa3f0af5d0eda479ea949e575619e2db7d48e..4c4284810b33d8a319880245fbd706f6bc20b388 100644 --- a/webui2/src/pages/CodePage.tsx +++ b/webui2/src/pages/CodePage.tsx @@ -4,7 +4,7 @@ import { gql, useQuery } from "@apollo/client"; import { AlertCircle, GitCommit } from "lucide-react"; import { useEffect } from "react"; -import { useSearchParams } from "react-router-dom"; +import { useSearchParams } from "react-router"; import type { GitRef, GitTreeEntry, GitBlob, GitLastCommit } from "@/__generated__/graphql"; import { CodeBreadcrumb } from "@/components/code/CodeBreadcrumb"; diff --git a/webui2/src/pages/CommitPage.tsx b/webui2/src/pages/CommitPage.tsx index 1ad5f8aa8f190a07b1c034d1c9f0b2796318bd03..9d2729e48721edcdac36820233e536d56cd228eb 100644 --- a/webui2/src/pages/CommitPage.tsx +++ b/webui2/src/pages/CommitPage.tsx @@ -4,7 +4,7 @@ import { gql, useQuery } from "@apollo/client"; import { format } from "date-fns"; import { ArrowLeft, GitCommit } from "lucide-react"; -import { Link, useParams, useNavigate } from "react-router-dom"; +import { Link, useParams, useNavigate } from "react-router"; import { FileDiffView } from "@/components/code/FileDiffView"; import { Skeleton } from "@/components/ui/skeleton"; diff --git a/webui2/src/pages/ErrorPage.tsx b/webui2/src/pages/ErrorPage.tsx index c5dd663f7ec3818e9959c4d4b465be73ad40519a..f4342cf16c4e2cfb57b7d62fa37029edabf0bdbc 100644 --- a/webui2/src/pages/ErrorPage.tsx +++ b/webui2/src/pages/ErrorPage.tsx @@ -3,7 +3,7 @@ // Application Error!" screen. import { AlertTriangle } from "lucide-react"; -import { useRouteError, isRouteErrorResponse, Link } from "react-router-dom"; +import { useRouteError, isRouteErrorResponse, Link } from "react-router"; import { Button } from "@/components/ui/button"; diff --git a/webui2/src/pages/NewBugPage.tsx b/webui2/src/pages/NewBugPage.tsx index 3e880b8c0adaaaf1661437a960d9102475a36c58..f858cfa6c611b65a6bcdf403ca92f81a68ecc251 100644 --- a/webui2/src/pages/NewBugPage.tsx +++ b/webui2/src/pages/NewBugPage.tsx @@ -1,6 +1,6 @@ import { ArrowLeft } from "lucide-react"; import { useState } from "react"; -import { useNavigate, Link } from "react-router-dom"; +import { useNavigate, Link } from "react-router"; import { useBugCreateMutation } from "@/__generated__/graphql"; import { Markdown } from "@/components/content/Markdown"; diff --git a/webui2/src/pages/RepoPickerPage.tsx b/webui2/src/pages/RepoPickerPage.tsx index 8d6407c8ee4bd98cb04b0fed58a9f7cc8a76f0e7..d0b74268995781a1bc8e60efb8c13840e9f3b9cc 100644 --- a/webui2/src/pages/RepoPickerPage.tsx +++ b/webui2/src/pages/RepoPickerPage.tsx @@ -3,7 +3,7 @@ import { GitFork, FolderOpen, AlertCircle } from "lucide-react"; import { useEffect } from "react"; -import { Link, useNavigate } from "react-router-dom"; +import { Link, useNavigate } from "react-router"; import { useRepositoriesQuery } from "@/__generated__/graphql"; import { Skeleton } from "@/components/ui/skeleton"; diff --git a/webui2/src/pages/UserProfilePage.tsx b/webui2/src/pages/UserProfilePage.tsx index 7f18d8723de23a6f63cc37427e68e64d07a7f27b..9f2057fb1f7fdc7e5b61bac21d9fb6abc089b459 100644 --- a/webui2/src/pages/UserProfilePage.tsx +++ b/webui2/src/pages/UserProfilePage.tsx @@ -17,7 +17,7 @@ import { ChevronRight, } from "lucide-react"; import { useState } from "react"; -import { useParams, Link } from "react-router-dom"; +import { useParams, Link } from "react-router"; import { Status, useUserProfileQuery } from "@/__generated__/graphql"; import { LabelBadge } from "@/components/bugs/LabelBadge";