From 14f1939d53e31bf0a356466c810b7f6728c4a68a Mon Sep 17 00:00:00 2001 From: Wolfgang Kozian Date: Sun, 6 Sep 2026 03:51:06 +0200 Subject: [PATCH 1/4] build(deps): react-router-dom -> react-router@8.3.0 Co-Authored-By: Claude Opus 5 --- frontend/package-lock.json | 56 +++++++++----------------------------- frontend/package.json | 2 +- 2 files changed, 14 insertions(+), 44 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 23b5cf2..48a3375 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -35,7 +35,7 @@ "react-dom": "^19.0.0", "react-grid-layout": "^2.2.3", "react-i18next": "^17.0.9", - "react-router-dom": "^7.18.1", + "react-router": "^8.3.1", "recharts": "^3.9.2", "tailwind-merge": "^3.6.0", "zustand": "^5.0.14" @@ -2295,18 +2295,11 @@ "node": ">= 0.8" } }, - "node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } + "node_modules/cookie-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-3.1.1.tgz", + "integrity": "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==", + "license": "MIT" }, "node_modules/csstype": { "version": "3.2.3", @@ -3654,20 +3647,19 @@ } }, "node_modules/react-router": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.1.tgz", - "integrity": "sha512-GDLgg3i3uM0aeJO3Fm+TCS+sDQ7gu12T6x0qdTEzcwqEfleci7JwugVNIF3U//0FWKnJT7ptG+20B2jfDqnZAg==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-8.3.1.tgz", + "integrity": "sha512-TEOpiO2g0TJHEOJeRVv4amUFun9v1npCKszvcquNvzETUtJ8udV86ah5eFoHT7g26bsBvT6EiIhqulR8eDF++A==", "license": "MIT", "dependencies": { - "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0" + "cookie-es": "^3.1.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.22.0" }, "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" + "react": ">=19.2.7", + "react-dom": ">=19.2.7" }, "peerDependenciesMeta": { "react-dom": { @@ -3675,22 +3667,6 @@ } } }, - "node_modules/react-router-dom": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.1.tgz", - "integrity": "sha512-KaZh+X/6UtEp28x51AUYZDMg9NGoz2ja3dNHa+ta/tk40vCzKhQ/RypCWBMLbmDr6//E24Vv5uPsrqXFozdkAg==", - "license": "MIT", - "dependencies": { - "react-router": "7.18.1" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, "node_modules/react-style-singleton": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", @@ -3816,12 +3792,6 @@ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, - "node_modules/set-cookie-parser": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", - "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", - "license": "MIT" - }, "node_modules/side-channel": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index f989ffa..8766a9d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -41,7 +41,7 @@ "react-dom": "^19.0.0", "react-grid-layout": "^2.2.3", "react-i18next": "^17.0.9", - "react-router-dom": "^7.18.1", + "react-router": "^8.3.1", "recharts": "^3.9.2", "tailwind-merge": "^3.6.0", "zustand": "^5.0.14" From cd4c826b292e2b29f35fb2479034b4de9caa890d Mon Sep 17 00:00:00 2001 From: Wolfgang Kozian Date: Sun, 6 Sep 2026 03:51:51 +0200 Subject: [PATCH 2/4] refactor: migrate react-router-dom imports to react-router (v8) Co-Authored-By: Claude Opus 5 --- frontend/src/app/router.tsx | 2 +- frontend/src/components/dashboard/IssueListWidget.tsx | 2 +- frontend/src/components/issue/IssueDetailContent.tsx | 2 +- frontend/src/components/issue/IssueDialog.tsx | 2 +- frontend/src/components/issue/IssueDialogHost.tsx | 2 +- frontend/src/components/nav/NavItem.tsx | 2 +- frontend/src/components/notifications/NotificationBell.tsx | 2 +- frontend/src/hooks/useOpenIssue.ts | 2 +- frontend/src/layouts/AppLayout.tsx | 2 +- frontend/src/layouts/AuthLayout.tsx | 2 +- frontend/src/layouts/SettingsLayout.tsx | 2 +- frontend/src/main.tsx | 2 +- frontend/src/pages/admin/AdminAutomationPage.tsx | 2 +- frontend/src/pages/auth/LoginPage.tsx | 2 +- frontend/src/pages/auth/RegisterPage.tsx | 2 +- frontend/src/pages/automation/AutomationPage.tsx | 2 +- frontend/src/pages/automation/AutomationRuleEditorPage.tsx | 2 +- frontend/src/pages/backlog/BacklogPage.tsx | 2 +- frontend/src/pages/board/BoardPage.tsx | 2 +- frontend/src/pages/dashboard/DashboardPage.tsx | 2 +- frontend/src/pages/issues/IssueDetailPage.tsx | 2 +- frontend/src/pages/issues/IssueListPage.tsx | 2 +- frontend/src/pages/orgs/OrgSettingsPage.tsx | 2 +- frontend/src/pages/orgs/OrgsPage.tsx | 2 +- frontend/src/pages/project-dashboard/ProjectDashboardPage.tsx | 2 +- frontend/src/pages/projects/ProjectCreatePage.tsx | 2 +- .../src/pages/projects/servicedesk/IncidentDashboardPage.tsx | 2 +- frontend/src/pages/projects/servicedesk/ServiceDeskPage.tsx | 2 +- frontend/src/pages/projects/settings/CustomFieldsPage.tsx | 2 +- frontend/src/pages/projects/settings/LabelsPage.tsx | 2 +- frontend/src/pages/projects/settings/MembersPage.tsx | 2 +- .../src/pages/projects/settings/OrganizationSettingsPage.tsx | 2 +- frontend/src/pages/projects/settings/ProjectAuditPage.tsx | 2 +- frontend/src/pages/projects/settings/VersionsPage.tsx | 2 +- frontend/src/pages/reports/ReportsPage.tsx | 2 +- frontend/src/pages/settings/AccountSettingsPage.tsx | 2 +- frontend/src/pages/settings/ApiKeysPage.tsx | 2 +- frontend/src/pages/settings/IntegrationsPage.tsx | 2 +- frontend/src/pages/settings/SecurityPage.tsx | 2 +- frontend/src/pages/settings/WebhooksPage.tsx | 2 +- frontend/src/pages/settings/WorkflowEditorPage.tsx | 2 +- frontend/src/pages/sprints/SprintsPage.tsx | 2 +- 42 files changed, 42 insertions(+), 42 deletions(-) diff --git a/frontend/src/app/router.tsx b/frontend/src/app/router.tsx index 7337c79..6daecd3 100644 --- a/frontend/src/app/router.tsx +++ b/frontend/src/app/router.tsx @@ -1,4 +1,4 @@ -import { createBrowserRouter, Navigate } from 'react-router-dom' +import { createBrowserRouter, Navigate } from 'react-router' import { AuthLayout } from '@/layouts/AuthLayout' import { AppLayout } from '@/layouts/AppLayout' import { LoginPage } from '@/pages/auth/LoginPage' diff --git a/frontend/src/components/dashboard/IssueListWidget.tsx b/frontend/src/components/dashboard/IssueListWidget.tsx index ab53190..e5e01b2 100644 --- a/frontend/src/components/dashboard/IssueListWidget.tsx +++ b/frontend/src/components/dashboard/IssueListWidget.tsx @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query' import { apiClient } from '@/api/client' -import { Link } from 'react-router-dom' +import { Link } from 'react-router' import type { Issue, Page } from '@/types' import { useTranslation } from 'react-i18next' diff --git a/frontend/src/components/issue/IssueDetailContent.tsx b/frontend/src/components/issue/IssueDetailContent.tsx index bd18ae8..75dfbc0 100644 --- a/frontend/src/components/issue/IssueDetailContent.tsx +++ b/frontend/src/components/issue/IssueDetailContent.tsx @@ -1,4 +1,4 @@ -import { useNavigate } from 'react-router-dom' +import { useNavigate } from 'react-router' import { useTranslation } from 'react-i18next' import { useIssue, useUpdateIssue } from '@/hooks/useIssues' import { useMe } from '@/hooks/useAuth' diff --git a/frontend/src/components/issue/IssueDialog.tsx b/frontend/src/components/issue/IssueDialog.tsx index 8f4e4fd..f0c2348 100644 --- a/frontend/src/components/issue/IssueDialog.tsx +++ b/frontend/src/components/issue/IssueDialog.tsx @@ -1,7 +1,7 @@ import { useEffect, useRef } from 'react' import { createPortal } from 'react-dom' import { useTranslation } from 'react-i18next' -import { Link } from 'react-router-dom' +import { Link } from 'react-router' import { IssueDetailContent } from '@/components/issue/IssueDetailContent' interface Props { diff --git a/frontend/src/components/issue/IssueDialogHost.tsx b/frontend/src/components/issue/IssueDialogHost.tsx index 5562237..a01567c 100644 --- a/frontend/src/components/issue/IssueDialogHost.tsx +++ b/frontend/src/components/issue/IssueDialogHost.tsx @@ -1,5 +1,5 @@ import { useCallback } from 'react' -import { useSearchParams, useMatch } from 'react-router-dom' +import { useSearchParams, useMatch } from 'react-router' import { IssueDialog } from '@/components/issue/IssueDialog' interface Props { projectKey: string } diff --git a/frontend/src/components/nav/NavItem.tsx b/frontend/src/components/nav/NavItem.tsx index b6362e2..2e34eeb 100644 --- a/frontend/src/components/nav/NavItem.tsx +++ b/frontend/src/components/nav/NavItem.tsx @@ -1,4 +1,4 @@ -import { NavLink } from 'react-router-dom' +import { NavLink } from 'react-router' import type { LucideIcon } from 'lucide-react' export interface NavItemProps { diff --git a/frontend/src/components/notifications/NotificationBell.tsx b/frontend/src/components/notifications/NotificationBell.tsx index b4fce0d..86bde5e 100644 --- a/frontend/src/components/notifications/NotificationBell.tsx +++ b/frontend/src/components/notifications/NotificationBell.tsx @@ -1,4 +1,4 @@ -import { useNavigate } from 'react-router-dom' +import { useNavigate } from 'react-router' import { useUnreadCount } from '@/hooks/useNotifications' import { useTranslation } from 'react-i18next' diff --git a/frontend/src/hooks/useOpenIssue.ts b/frontend/src/hooks/useOpenIssue.ts index 0c6c37d..8fe3ec4 100644 --- a/frontend/src/hooks/useOpenIssue.ts +++ b/frontend/src/hooks/useOpenIssue.ts @@ -1,5 +1,5 @@ import { useCallback } from 'react' -import { useSearchParams } from 'react-router-dom' +import { useSearchParams } from 'react-router' /** Öffnet ein Issue als Modal, indem `?issue=KEY` gesetzt wird (übrige Query-Parameter bleiben erhalten). */ export function useOpenIssue() { diff --git a/frontend/src/layouts/AppLayout.tsx b/frontend/src/layouts/AppLayout.tsx index 5aefadf..b2f0b37 100644 --- a/frontend/src/layouts/AppLayout.tsx +++ b/frontend/src/layouts/AppLayout.tsx @@ -1,4 +1,4 @@ -import { Outlet, Link, useNavigate, useMatch } from 'react-router-dom' +import { Outlet, Link, useNavigate, useMatch } from 'react-router' import { useQuery } from '@tanstack/react-query' import { useTranslation } from 'react-i18next' import { diff --git a/frontend/src/layouts/AuthLayout.tsx b/frontend/src/layouts/AuthLayout.tsx index a1bdfa5..79a2d57 100644 --- a/frontend/src/layouts/AuthLayout.tsx +++ b/frontend/src/layouts/AuthLayout.tsx @@ -1,4 +1,4 @@ -import { Outlet } from 'react-router-dom' +import { Outlet } from 'react-router' import { VersionTag } from '@/components/VersionTag' export function AuthLayout() { diff --git a/frontend/src/layouts/SettingsLayout.tsx b/frontend/src/layouts/SettingsLayout.tsx index 0166fe7..15d8e90 100644 --- a/frontend/src/layouts/SettingsLayout.tsx +++ b/frontend/src/layouts/SettingsLayout.tsx @@ -1,4 +1,4 @@ -import { Outlet, NavLink } from 'react-router-dom' +import { Outlet, NavLink } from 'react-router' import { useTranslation } from 'react-i18next' import { User, Shield, Bell, KeyRound, UserX } from 'lucide-react' diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 82fbb06..1e3de6e 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -1,7 +1,7 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import { QueryClientProvider } from '@tanstack/react-query' -import { RouterProvider } from 'react-router-dom' +import { RouterProvider } from 'react-router/dom' import { queryClient } from './app/queryClient' import { router } from './app/router' import './index.css' diff --git a/frontend/src/pages/admin/AdminAutomationPage.tsx b/frontend/src/pages/admin/AdminAutomationPage.tsx index 6853329..c8c1bc6 100644 --- a/frontend/src/pages/admin/AdminAutomationPage.tsx +++ b/frontend/src/pages/admin/AdminAutomationPage.tsx @@ -1,4 +1,4 @@ -import { useNavigate } from 'react-router-dom' +import { useNavigate } from 'react-router' import { useSystemRules, useToggleSystemRule } from '../../hooks/useAutomation' import { useTranslation } from 'react-i18next' diff --git a/frontend/src/pages/auth/LoginPage.tsx b/frontend/src/pages/auth/LoginPage.tsx index 31d40bb..da388e8 100644 --- a/frontend/src/pages/auth/LoginPage.tsx +++ b/frontend/src/pages/auth/LoginPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useNavigate, Link } from 'react-router-dom' +import { useNavigate, Link } from 'react-router' import { useQuery } from '@tanstack/react-query' import { useTranslation } from 'react-i18next' import { authApi } from '@/api/auth' diff --git a/frontend/src/pages/auth/RegisterPage.tsx b/frontend/src/pages/auth/RegisterPage.tsx index ff8a7ec..cdaf817 100644 --- a/frontend/src/pages/auth/RegisterPage.tsx +++ b/frontend/src/pages/auth/RegisterPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useNavigate, Link } from 'react-router-dom' +import { useNavigate, Link } from 'react-router' import { useTranslation } from 'react-i18next' import { authApi } from '@/api/auth' diff --git a/frontend/src/pages/automation/AutomationPage.tsx b/frontend/src/pages/automation/AutomationPage.tsx index dd9243d..d0d9f60 100644 --- a/frontend/src/pages/automation/AutomationPage.tsx +++ b/frontend/src/pages/automation/AutomationPage.tsx @@ -1,4 +1,4 @@ -import { useParams, useNavigate } from 'react-router-dom' +import { useParams, useNavigate } from 'react-router' import { useAutomationRules, useToggleRule, useDeleteRule } from '../../hooks/useAutomation' import { useTranslation } from 'react-i18next' diff --git a/frontend/src/pages/automation/AutomationRuleEditorPage.tsx b/frontend/src/pages/automation/AutomationRuleEditorPage.tsx index aadc41f..e3f1546 100644 --- a/frontend/src/pages/automation/AutomationRuleEditorPage.tsx +++ b/frontend/src/pages/automation/AutomationRuleEditorPage.tsx @@ -1,4 +1,4 @@ -import { useParams, useNavigate } from 'react-router-dom' +import { useParams, useNavigate } from 'react-router' import { useCreateRule } from '../../hooks/useAutomation' import { RuleEditor } from '../../components/automation/RuleEditor' import type { TriggerType, RuleConditionGroup, RuleAction } from '../../types' diff --git a/frontend/src/pages/backlog/BacklogPage.tsx b/frontend/src/pages/backlog/BacklogPage.tsx index 5f3b83e..b168a60 100644 --- a/frontend/src/pages/backlog/BacklogPage.tsx +++ b/frontend/src/pages/backlog/BacklogPage.tsx @@ -1,6 +1,6 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useBacklog } from '@/hooks/useBoard' import { useStartSprint, useAssignIssue, useUnassignIssue } from '@/hooks/useSprints' import { useProjectSocket } from '@/hooks/useProjectSocket' diff --git a/frontend/src/pages/board/BoardPage.tsx b/frontend/src/pages/board/BoardPage.tsx index 90c83b7..3a63fed 100644 --- a/frontend/src/pages/board/BoardPage.tsx +++ b/frontend/src/pages/board/BoardPage.tsx @@ -1,6 +1,6 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' -import { useParams, Link } from 'react-router-dom' +import { useParams, Link } from 'react-router' import { DndContext, DragEndEvent, PointerSensor, useSensor, useSensors } from '@dnd-kit/core' import { useBoard, useMoveIssue } from '@/hooks/useBoard' import { useCompleteSprint } from '@/hooks/useSprints' diff --git a/frontend/src/pages/dashboard/DashboardPage.tsx b/frontend/src/pages/dashboard/DashboardPage.tsx index dfb2765..c165768 100644 --- a/frontend/src/pages/dashboard/DashboardPage.tsx +++ b/frontend/src/pages/dashboard/DashboardPage.tsx @@ -1,4 +1,4 @@ -import { Link } from 'react-router-dom' +import { Link } from 'react-router' import { useProjects } from '@/hooks/useProjects' import { useTranslation } from 'react-i18next' diff --git a/frontend/src/pages/issues/IssueDetailPage.tsx b/frontend/src/pages/issues/IssueDetailPage.tsx index 28ac55d..4117eed 100644 --- a/frontend/src/pages/issues/IssueDetailPage.tsx +++ b/frontend/src/pages/issues/IssueDetailPage.tsx @@ -1,4 +1,4 @@ -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { IssueDetailContent } from '@/components/issue/IssueDetailContent' export function IssueDetailPage() { diff --git a/frontend/src/pages/issues/IssueListPage.tsx b/frontend/src/pages/issues/IssueListPage.tsx index 326df45..bd82434 100644 --- a/frontend/src/pages/issues/IssueListPage.tsx +++ b/frontend/src/pages/issues/IssueListPage.tsx @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react' -import { useParams, useSearchParams } from 'react-router-dom' +import { useParams, useSearchParams } from 'react-router' import { useTranslation } from 'react-i18next' import { useIssues, useCreateIssue } from '@/hooks/useIssues' import { useLabels } from '@/hooks/useLabels' diff --git a/frontend/src/pages/orgs/OrgSettingsPage.tsx b/frontend/src/pages/orgs/OrgSettingsPage.tsx index 6c743e9..24dfc58 100644 --- a/frontend/src/pages/orgs/OrgSettingsPage.tsx +++ b/frontend/src/pages/orgs/OrgSettingsPage.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useQuery } from '@tanstack/react-query' import { organizationsApi } from '@/api/organizations' import { useOrgMembers, useAddOrgMember, useChangeOrgMemberRole, useRemoveOrgMember } from '@/hooks/useOrganizations' diff --git a/frontend/src/pages/orgs/OrgsPage.tsx b/frontend/src/pages/orgs/OrgsPage.tsx index 96b1810..3b04df6 100644 --- a/frontend/src/pages/orgs/OrgsPage.tsx +++ b/frontend/src/pages/orgs/OrgsPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { Link } from 'react-router-dom' +import { Link } from 'react-router' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { organizationsApi, CreateOrganizationRequest, Organization } from '@/api/organizations' import { useMe } from '@/hooks/useAuth' diff --git a/frontend/src/pages/project-dashboard/ProjectDashboardPage.tsx b/frontend/src/pages/project-dashboard/ProjectDashboardPage.tsx index 3debd1b..fccf3c8 100644 --- a/frontend/src/pages/project-dashboard/ProjectDashboardPage.tsx +++ b/frontend/src/pages/project-dashboard/ProjectDashboardPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useProjectDashboard, useSaveDashboardLayout, useAddWidget, useRemoveWidget } from '@/hooks/useProjectDashboard' import type { WidgetData } from '@/hooks/useProjectDashboard' import { DashboardCanvas } from '@/components/dashboard/DashboardCanvas' diff --git a/frontend/src/pages/projects/ProjectCreatePage.tsx b/frontend/src/pages/projects/ProjectCreatePage.tsx index 315a222..373d691 100644 --- a/frontend/src/pages/projects/ProjectCreatePage.tsx +++ b/frontend/src/pages/projects/ProjectCreatePage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useNavigate } from 'react-router-dom' +import { useNavigate } from 'react-router' import { useCreateProject } from '@/hooks/useProjects' import { useTranslation } from 'react-i18next' diff --git a/frontend/src/pages/projects/servicedesk/IncidentDashboardPage.tsx b/frontend/src/pages/projects/servicedesk/IncidentDashboardPage.tsx index 6538899..fda2ac5 100644 --- a/frontend/src/pages/projects/servicedesk/IncidentDashboardPage.tsx +++ b/frontend/src/pages/projects/servicedesk/IncidentDashboardPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { serviceDeskApi } from '@/api/servicedesk' import { useTranslation } from 'react-i18next' diff --git a/frontend/src/pages/projects/servicedesk/ServiceDeskPage.tsx b/frontend/src/pages/projects/servicedesk/ServiceDeskPage.tsx index 9b847a7..d45a4f1 100644 --- a/frontend/src/pages/projects/servicedesk/ServiceDeskPage.tsx +++ b/frontend/src/pages/projects/servicedesk/ServiceDeskPage.tsx @@ -1,4 +1,4 @@ -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useQuery } from '@tanstack/react-query' import { serviceDeskApi } from '@/api/servicedesk' import { useTranslation } from 'react-i18next' diff --git a/frontend/src/pages/projects/settings/CustomFieldsPage.tsx b/frontend/src/pages/projects/settings/CustomFieldsPage.tsx index 5153d21..bd048c8 100644 --- a/frontend/src/pages/projects/settings/CustomFieldsPage.tsx +++ b/frontend/src/pages/projects/settings/CustomFieldsPage.tsx @@ -1,6 +1,6 @@ // frontend/src/pages/projects/settings/CustomFieldsPage.tsx import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { DndContext, closestCenter, DragEndEvent } from '@dnd-kit/core' import { SortableContext, verticalListSortingStrategy, arrayMove, useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' diff --git a/frontend/src/pages/projects/settings/LabelsPage.tsx b/frontend/src/pages/projects/settings/LabelsPage.tsx index 3875618..b57a7c0 100644 --- a/frontend/src/pages/projects/settings/LabelsPage.tsx +++ b/frontend/src/pages/projects/settings/LabelsPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useLabels, useCreateLabel, useUpdateLabel, useDeleteLabel } from '@/hooks/useLabels' import { useProjectRole } from '@/hooks/useProjectRole' import { LabelChip } from '@/components/issue/LabelChip' diff --git a/frontend/src/pages/projects/settings/MembersPage.tsx b/frontend/src/pages/projects/settings/MembersPage.tsx index 2603bb7..2036a41 100644 --- a/frontend/src/pages/projects/settings/MembersPage.tsx +++ b/frontend/src/pages/projects/settings/MembersPage.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useQuery } from '@tanstack/react-query' import { useProject } from '@/hooks/useProjects' import { diff --git a/frontend/src/pages/projects/settings/OrganizationSettingsPage.tsx b/frontend/src/pages/projects/settings/OrganizationSettingsPage.tsx index 01c0156..b39deee 100644 --- a/frontend/src/pages/projects/settings/OrganizationSettingsPage.tsx +++ b/frontend/src/pages/projects/settings/OrganizationSettingsPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { useProject } from '@/hooks/useProjects' import { organizationsApi } from '@/api/organizations' diff --git a/frontend/src/pages/projects/settings/ProjectAuditPage.tsx b/frontend/src/pages/projects/settings/ProjectAuditPage.tsx index 2954af4..8cd55d8 100644 --- a/frontend/src/pages/projects/settings/ProjectAuditPage.tsx +++ b/frontend/src/pages/projects/settings/ProjectAuditPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useQuery } from '@tanstack/react-query' import { useTranslation } from 'react-i18next' import { auditApi, AuditEvent } from '../../../api/audit' diff --git a/frontend/src/pages/projects/settings/VersionsPage.tsx b/frontend/src/pages/projects/settings/VersionsPage.tsx index 9b7e205..a1788fd 100644 --- a/frontend/src/pages/projects/settings/VersionsPage.tsx +++ b/frontend/src/pages/projects/settings/VersionsPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useVersions, useCreateVersion, useUpdateVersion, useDeleteVersion } from '@/hooks/useVersions' import { useProjectRole } from '@/hooks/useProjectRole' import type { Version } from '@/types' diff --git a/frontend/src/pages/reports/ReportsPage.tsx b/frontend/src/pages/reports/ReportsPage.tsx index d5307cb..3a25f60 100644 --- a/frontend/src/pages/reports/ReportsPage.tsx +++ b/frontend/src/pages/reports/ReportsPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useSprints } from '@/hooks/useSprints' import { useBurndown, useVelocity } from '@/hooks/useReports' import { diff --git a/frontend/src/pages/settings/AccountSettingsPage.tsx b/frontend/src/pages/settings/AccountSettingsPage.tsx index 68a466d..0ee0c3d 100644 --- a/frontend/src/pages/settings/AccountSettingsPage.tsx +++ b/frontend/src/pages/settings/AccountSettingsPage.tsx @@ -1,6 +1,6 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' +import { useNavigate } from 'react-router' import { useDeleteAccount } from '@/hooks/useAccount' export function AccountSettingsPage() { diff --git a/frontend/src/pages/settings/ApiKeysPage.tsx b/frontend/src/pages/settings/ApiKeysPage.tsx index 6f73b63..780842d 100644 --- a/frontend/src/pages/settings/ApiKeysPage.tsx +++ b/frontend/src/pages/settings/ApiKeysPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useApiKeys, useCreateApiKey, useRevokeApiKey } from '@/hooks/useApiKeys' import type { CreateApiKeyResponse } from '@/hooks/useApiKeys' import { DataTable, type Column } from '@/components/table/DataTable' diff --git a/frontend/src/pages/settings/IntegrationsPage.tsx b/frontend/src/pages/settings/IntegrationsPage.tsx index 657420c..3732aa8 100644 --- a/frontend/src/pages/settings/IntegrationsPage.tsx +++ b/frontend/src/pages/settings/IntegrationsPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useProjectIntegrations, useCreateIntegration, useDeleteIntegration } from '@/hooks/useProjectIntegrations' diff --git a/frontend/src/pages/settings/SecurityPage.tsx b/frontend/src/pages/settings/SecurityPage.tsx index 1dffcd1..0133d01 100644 --- a/frontend/src/pages/settings/SecurityPage.tsx +++ b/frontend/src/pages/settings/SecurityPage.tsx @@ -1,6 +1,6 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' +import { useNavigate } from 'react-router' import { useChangePassword } from '@/hooks/useMe' export function SecurityPage() { diff --git a/frontend/src/pages/settings/WebhooksPage.tsx b/frontend/src/pages/settings/WebhooksPage.tsx index a3fd2e6..9492b4b 100644 --- a/frontend/src/pages/settings/WebhooksPage.tsx +++ b/frontend/src/pages/settings/WebhooksPage.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useWebhooks, useCreateWebhook, useDeleteWebhook, useWebhookDeliveries, useTestPing, ALL_WEBHOOK_EVENTS, diff --git a/frontend/src/pages/settings/WorkflowEditorPage.tsx b/frontend/src/pages/settings/WorkflowEditorPage.tsx index a5d18de..9390fc7 100644 --- a/frontend/src/pages/settings/WorkflowEditorPage.tsx +++ b/frontend/src/pages/settings/WorkflowEditorPage.tsx @@ -1,4 +1,4 @@ -import { useParams } from 'react-router-dom' +import { useParams } from 'react-router' import { useWorkflowEditor, useCreateStatus, useCreateTransition, useUpdateGuards, useDeleteTransition, useSaveLayout } from '../../hooks/useWorkflowEditor' import { WorkflowCanvas } from '../../components/workflow/WorkflowCanvas' import { useState } from 'react' diff --git a/frontend/src/pages/sprints/SprintsPage.tsx b/frontend/src/pages/sprints/SprintsPage.tsx index 4815a62..d9d328f 100644 --- a/frontend/src/pages/sprints/SprintsPage.tsx +++ b/frontend/src/pages/sprints/SprintsPage.tsx @@ -1,4 +1,4 @@ -import { useParams, useNavigate } from 'react-router-dom' +import { useParams, useNavigate } from 'react-router' import { useSprints } from '@/hooks/useSprints' import { useTranslation } from 'react-i18next' import { SprintCard } from '@/components/sprint/SprintCard' From a26ae2d04d190803b4b57d4685103b84852fd4ae Mon Sep 17 00:00:00 2001 From: Wolfgang Kozian Date: Sun, 6 Sep 2026 03:52:17 +0200 Subject: [PATCH 3/4] ci: bump setup-node 20 -> 22 for react-router v8 (Node >=22.22) Co-Authored-By: Claude Opus 5 --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e6f42e1..00b0018 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,8 @@ jobs: - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: '20' + # react-router v8 requires Node >= 22.22 at build time. + node-version: '22' cache: 'npm' cache-dependency-path: frontend/package-lock.json From 532e59ec03029b3c82ed439faf983c08ad388ee8 Mon Sep 17 00:00:00 2001 From: Wolfgang Kozian Date: Sun, 6 Sep 2026 03:53:16 +0200 Subject: [PATCH 4/4] revert(security): drop react-router CVE suppressions - fixed by v8 upgrade Co-Authored-By: Claude Opus 5 --- .github/scripts/audit-gate.mjs | 5 +---- .trivyignore | 7 ------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/scripts/audit-gate.mjs b/.github/scripts/audit-gate.mjs index d7e7c3d..5fe3611 100644 --- a/.github/scripts/audit-gate.mjs +++ b/.github/scripts/audit-gate.mjs @@ -11,10 +11,7 @@ import { execSync } from 'node:child_process'; // Begründete Ausnahmen: GHSA-ID -> Grund + Datum. Jede Zeile muss auch in .trivyignore // gespiegelt sein (Trivy-Gate) und via Dependabot-Alert-Dismiss abgedeckt werden. -const ALLOWLIST = { - 'GHSA-QWWW-VCR4-C8H2': - 'react-router RSC-only CSRF (CWE-352); TaskWolf ist Client-SPA (createBrowserRouter, kein RSC/SSR) -> nicht ausnutzbar. Fix nur in react-router 8.3.0 (Major); v8-Migration geplant, 2026-07-29', -}; +const ALLOWLIST = {}; const BLOCK = new Set(['high', 'critical']); const GHSA_RE = /GHSA-[a-z0-9]{4,}-[a-z0-9]{4,}-[a-z0-9]{4,}/i; diff --git a/.trivyignore b/.trivyignore index d69447d..2357007 100644 --- a/.trivyignore +++ b/.trivyignore @@ -1,9 +1,2 @@ # Begründete Ausnahmen. Format pro Zeile: CVE-ID # Grund + Datum # z.B.: CVE-2024-12345 # nicht ausnutzbar (Komponente ungenutzt), 2026-06-28 - -# react-router GHSA-qwww-vcr4-c8h2 (CSRF, CWE-352, CVSS 7.1): betrifft AUSSCHLIESSLICH -# den unstable RSC-Modus (React Server Components). TaskWolf-Frontend ist eine reine -# Client-SPA (createBrowserRouter, kein SSR/RSC, keine unstable_ APIs) -> Code-Pfad -# ungenutzt, nicht ausnutzbar. Fix nur in react-router 8.3.0 (Major, react-router-dom -# in v8 aufgelöst). Auflösung geplant via v8-Migration -> docs/superpowers/plans/2026-07-29-react-router-v8-migration.md -GHSA-qwww-vcr4-c8h2 # RSC-only CSRF, Client-SPA nicht betroffen, 2026-07-29