diff --git a/.github/scripts/audit-gate.mjs b/.github/scripts/audit-gate.mjs index d7e7c3d7..5fe36118 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/.github/workflows/ci.yml b/.github/workflows/ci.yml index e6f42e18..00b00186 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 diff --git a/.trivyignore b/.trivyignore index d69447db..2357007b 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 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 23b5cf24..48a33759 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 f989ffaf..8766a9dd 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" diff --git a/frontend/src/app/router.tsx b/frontend/src/app/router.tsx index 7337c79b..6daecd30 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 ab531907..e5e01b2d 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 bd18ae8a..75dfbc0a 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 8f4e4fd6..f0c23486 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 5562237a..a01567c1 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 b6362e2f..2e34eeb8 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 b4fce0dd..86bde5e3 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 0c6c37d2..8fe3ec40 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 5aefadf7..b2f0b37e 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 a1bdfa5d..79a2d576 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 0166fe79..15d8e90e 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 82fbb066..1e3de6e0 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 68533293..c8c1bc6e 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 31d40bbe..da388e89 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 ff8a7eca..cdaf817e 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 dd9243d9..d0d9f608 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 aadc41fa..e3f1546e 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 5f3b83eb..b168a600 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 90c83b79..3a63fedd 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 dfb27658..c1657688 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 28ac55dc..4117eed9 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 326df451..bd82434d 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 6c743e90..24dfc58e 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 96b18104..3b04df65 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 3debd1b5..fccf3c81 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 315a222d..373d6914 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 65388990..fda2ac56 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 9b847a70..d45a4f18 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 5153d21c..bd048c87 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 38756181..b57a7c00 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 2603bb71..2036a417 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 01c01560..b39deee8 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 2954af47..8cd55d8b 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 9b7e205f..a1788fdd 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 d5307cb6..3a25f604 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 68a466de..0ee0c3de 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 6f73b632..780842d4 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 657420c3..3732aa80 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 1dffcd11..0133d017 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 a3fd2e6f..9492b4b2 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 a5d18deb..9390fc71 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 4815a62c..d9d328f6 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'