From 747d1914123e8e64ead014c4b0d50623cb04925f Mon Sep 17 00:00:00 2001 From: Takeshi Kimata <117462761+kimatata@users.noreply.github.com> Date: Sat, 4 May 2024 12:19:53 +0900 Subject: [PATCH] Include locale on all links and routers --- frontend/src/app/[locale]/LangSwitch.tsx | 2 +- frontend/src/app/[locale]/layout.tsx | 11 --------- .../app/[locale]/projects/ProjectsPage.tsx | 4 +++- .../app/[locale]/projects/ProjectsTable.tsx | 8 ++++--- .../[projectId]/{sidebar.tsx => Sidebar.tsx} | 23 +++++++++---------- .../[projectId]/folders/FoldersPane.tsx | 15 ++++++++---- .../folders/[folderId]/cases/CasesPane.tsx | 4 +++- .../[folderId]/cases/TestCaseTable.tsx | 8 ++++--- .../[folderId]/cases/[caseId]/CaseEditor.tsx | 12 +++++++--- .../[folderId]/cases/[caseId]/page.tsx | 8 ++++++- .../folders/[folderId]/cases/page.tsx | 8 +++++-- .../projects/[projectId]/folders/layout.tsx | 4 ++-- .../[locale]/projects/[projectId]/layout.tsx | 6 +++-- .../projects/[projectId]/runs/RunsPage.tsx | 4 +++- .../projects/[projectId]/runs/RunsTable.tsx | 14 +++++++---- .../[projectId]/runs/[runId]/RunEditor.tsx | 9 +++++--- .../[projectId]/runs/[runId]/page.tsx | 10 ++++++-- .../projects/[projectId]/runs/page.tsx | 8 +++++-- frontend/src/app/[locale]/projects/page.tsx | 4 ++-- frontend/src/navigation.ts | 3 +++ 20 files changed, 104 insertions(+), 61 deletions(-) rename frontend/src/app/[locale]/projects/[projectId]/{sidebar.tsx => Sidebar.tsx} (79%) diff --git a/frontend/src/app/[locale]/LangSwitch.tsx b/frontend/src/app/[locale]/LangSwitch.tsx index 68932c1..48a093c 100644 --- a/frontend/src/app/[locale]/LangSwitch.tsx +++ b/frontend/src/app/[locale]/LangSwitch.tsx @@ -21,7 +21,7 @@ export default function LangSwitch(params: { locale: string }) { async function changeLocale(nextLocale: string) { let newPathname; - if (params.locale.length < 4) { + if (pathname.length < 4) { // when root path router.push("/", { locale: nextLocale }); } else { diff --git a/frontend/src/app/[locale]/layout.tsx b/frontend/src/app/[locale]/layout.tsx index 97a35ff..18990c0 100644 --- a/frontend/src/app/[locale]/layout.tsx +++ b/frontend/src/app/[locale]/layout.tsx @@ -43,17 +43,6 @@ export default function RootLayout({
{children}
- {/* */}
diff --git a/frontend/src/app/[locale]/projects/ProjectsPage.tsx b/frontend/src/app/[locale]/projects/ProjectsPage.tsx index 401033e..b2cc51c 100644 --- a/frontend/src/app/[locale]/projects/ProjectsPage.tsx +++ b/frontend/src/app/[locale]/projects/ProjectsPage.tsx @@ -14,9 +14,10 @@ import { export type Props = { messages: ProjectsMessages; + locale: string; }; -export default function ProjectsPage({ messages }: Props) { +export default function ProjectsPage({ messages, locale }: Props) { const [projects, setProjects] = useState([]); useEffect(() => { @@ -101,6 +102,7 @@ export default function ProjectsPage({ messages }: Props) { onEditProject={onEditClick} onDeleteProject={onDeleteClick} messages={messages} + locale={locale} /> void; onDeleteProject: (projectId: number) => void; messages: ProjectsMessages; + locale: string; }; export default function ProjectsTable({ @@ -30,6 +31,7 @@ export default function ProjectsTable({ onEditProject, onDeleteProject, messages, + locale, }: Props) { const headerColumns = [ { name: messages.id, uid: "id", sortable: true }, @@ -67,9 +69,9 @@ export default function ProjectsTable({ case "name": return ( {cellValue} diff --git a/frontend/src/app/[locale]/projects/[projectId]/sidebar.tsx b/frontend/src/app/[locale]/projects/[projectId]/Sidebar.tsx similarity index 79% rename from frontend/src/app/[locale]/projects/[projectId]/sidebar.tsx rename to frontend/src/app/[locale]/projects/[projectId]/Sidebar.tsx index ad6a943..c2f3a0e 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/sidebar.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/Sidebar.tsx @@ -2,10 +2,14 @@ import { useState, useEffect } from "react"; import { Listbox, ListboxItem } from "@nextui-org/react"; import { Home, Files, FlaskConical } from "lucide-react"; -import { useRouter, usePathname } from "next/navigation"; +import { usePathname, useRouter } from "@/src/navigation"; import useGetCurrentIds from "@/utils/useGetCurrentIds"; -export default function Sidebar() { +export type Props = { + locale: string; +}; + +export default function Sidebar({ locale }: Props) { const { projectId } = useGetCurrentIds(); const router = useRouter(); const pathname = usePathname(); @@ -16,11 +20,11 @@ export default function Sidebar() { const handleTabClick = (key: string) => { if (key === "home") { - router.push(`/projects/${projectId}/home`); + router.push(`/projects/${projectId}/home`, { locale: locale }); } else if (key === "cases") { - router.push(`/projects/${projectId}/folders`); + router.push(`/projects/${projectId}/folders`, { locale: locale }); } else if (key === "runs") { - router.push(`/projects/${projectId}/runs`); + router.push(`/projects/${projectId}/runs`, { locale: locale }); } }; @@ -58,13 +62,8 @@ export default function Sidebar() { return (
- router.push(`/projects/${projectId}/home`)} - > - {tabItems.map((itr, index) => ( + + {tabItems.map((itr) => ( { await deleteFolder(folderId); - router.push(`/projects/${projectId}/folders`); + router.push(`/projects/${projectId}/folders`, { locale: locale }); }; useEffect(() => { @@ -86,7 +87,8 @@ export default function FoldersPane({ projectId }: Props) { if (pathname === `/projects/${projectId}/folders`) { const smallestFolderId = Math.min(...data.map((folder) => folder.id)); router.push( - `/projects/${projectId}/folders/${smallestFolderId}/cases` + `/projects/${projectId}/folders/${smallestFolderId}/cases`, + { locale: locale } ); } } catch (error: any) { @@ -117,7 +119,10 @@ export default function FoldersPane({ projectId }: Props) { - router.push(`/projects/${projectId}/folders/${folder.id}/cases`) + router.push( + `/projects/${projectId}/folders/${folder.id}/cases`, + { locale: locale } + ) } startContent={} className={ diff --git a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/CasesPane.tsx b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/CasesPane.tsx index c77f7c2..c68ba6d 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/CasesPane.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/CasesPane.tsx @@ -6,9 +6,10 @@ import { fetchCases, createCase, deleteCase, deleteCases } from "./caseControl"; type Props = { projectId: string; folderId: string; + locale: string; }; -export default function CasesPane({ projectId, folderId }: Props) { +export default function CasesPane({ projectId, folderId, locale }: Props) { const [cases, setCases] = useState([]); useEffect(() => { async function fetchDataEffect() { @@ -50,6 +51,7 @@ export default function CasesPane({ projectId, folderId }: Props) { onCreateCase={() => handleCreateCase(folderId)} onDeleteCase={handleDeleteCase} onDeleteCases={handleDeleteCases} + locale={locale} /> ); diff --git a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/TestCaseTable.tsx b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/TestCaseTable.tsx index c239c4d..ec0bab1 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/TestCaseTable.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/TestCaseTable.tsx @@ -13,8 +13,8 @@ import { DropdownItem, Selection, SortDescriptor, - Link, } from "@nextui-org/react"; +import { Link, NextUiLinkClasses } from "@/src/navigation"; import { Plus, MoreVertical, Trash, Circle } from "lucide-react"; const headerColumns = [ @@ -48,6 +48,7 @@ type Props = { onCreateCase: () => void; onDeleteCase: (caseId: number) => void; onDeleteCases: (selectedCases: string[]) => void; + locale: string; }; export default function TestCaseTable({ @@ -56,6 +57,7 @@ export default function TestCaseTable({ onCreateCase, onDeleteCase, onDeleteCases, + locale, }: Props) { const [selectedKeys, setSelectedKeys] = useState(new Set([])); const [sortDescriptor, setSortDescriptor] = useState({ @@ -81,9 +83,9 @@ export default function TestCaseTable({ case "title": return ( {cellValue} diff --git a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseEditor.tsx b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseEditor.tsx index e01cca5..51d156d 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseEditor.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/CaseEditor.tsx @@ -9,7 +9,7 @@ import { Divider, Tooltip, } from "@nextui-org/react"; -import { useRouter } from "next/navigation"; +import { useRouter } from "@/src/navigation"; import { Save, Plus, ArrowLeft, ArrowUpFromLine, Circle } from "lucide-react"; import { priorities, testTypes, templates } from "@/config/selection"; import CaseStepsEditor from "./CaseStepsEditor"; @@ -40,7 +40,12 @@ const defaultTestCase = { export default function CaseEditor({ params, }: { - params: { projectId: string; folderId: string; caseId: string }; + params: { + projectId: string; + folderId: string; + caseId: string; + locale: string; + }; }) { const [testCase, setTestCase] = useState(defaultTestCase); const [isTitleInvalid, setIsTitleInvalid] = useState(false); @@ -171,7 +176,8 @@ export default function CaseEditor({ className="rounded-full bg-neutral-50 dark:bg-neutral-600" onPress={() => router.push( - `/projects/${params.projectId}/folders/${params.folderId}/cases` + `/projects/${params.projectId}/folders/${params.folderId}/cases`, + { locale: params.locale } ) } > diff --git a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/page.tsx b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/page.tsx index eadbb71..a465505 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/page.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/[caseId]/page.tsx @@ -3,7 +3,12 @@ import CaseEditor from "./CaseEditor"; export default function Page({ params, }: { - params: { projectId: string; folderId: string; caseId: string }; + params: { + projectId: string; + folderId: string; + caseId: string; + locale: string; + }; }) { return ( ); diff --git a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/page.tsx b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/page.tsx index 660850b..35d594e 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/page.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/folders/[folderId]/cases/page.tsx @@ -3,11 +3,15 @@ import CasesPane from "./CasesPane"; export default function Page({ params, }: { - params: { projectId: string; folderId: string }; + params: { projectId: string; folderId: string; locale: string }; }) { return ( <> - + ); } diff --git a/frontend/src/app/[locale]/projects/[projectId]/folders/layout.tsx b/frontend/src/app/[locale]/projects/[projectId]/folders/layout.tsx index 9214761..8fa2098 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/folders/layout.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/folders/layout.tsx @@ -5,11 +5,11 @@ export default function FoldersLayout({ params, }: { children: React.ReactNode; - params: { projectId: string }; + params: { projectId: string; locale: string }; }) { return (
- +
{children}
); diff --git a/frontend/src/app/[locale]/projects/[projectId]/layout.tsx b/frontend/src/app/[locale]/projects/[projectId]/layout.tsx index bbf61b7..681f3e1 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/layout.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/layout.tsx @@ -1,14 +1,16 @@ -import Sidebar from "./sidebar"; +import Sidebar from "./Sidebar"; export default function SidebarLayout({ children, + params: { locale }, }: { children: React.ReactNode; + params: { locale: string }; }) { return ( <>
- +
{children}
diff --git a/frontend/src/app/[locale]/projects/[projectId]/runs/RunsPage.tsx b/frontend/src/app/[locale]/projects/[projectId]/runs/RunsPage.tsx index 2c81636..ca761fe 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/runs/RunsPage.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/runs/RunsPage.tsx @@ -7,9 +7,10 @@ import { fetchRuns, createRun, deleteRun } from "./runsControl"; type Props = { projectId: string; + locale: string; }; -export default function RunsPage({ projectId }: Props) { +export default function RunsPage({ projectId, locale }: Props) { const [runs, setRuns] = useState([]); useEffect(() => { @@ -66,6 +67,7 @@ export default function RunsPage({ projectId }: Props) { projectId={projectId} runs={runs} onDeleteRun={onDeleteClick} + locale={locale} />
); diff --git a/frontend/src/app/[locale]/projects/[projectId]/runs/RunsTable.tsx b/frontend/src/app/[locale]/projects/[projectId]/runs/RunsTable.tsx index 49895ee..9dca473 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/runs/RunsTable.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/runs/RunsTable.tsx @@ -12,8 +12,8 @@ import { DropdownMenu, DropdownItem, SortDescriptor, - Link, } from "@nextui-org/react"; +import { Link, NextUiLinkClasses } from "@/src/navigation"; import { MoreVertical } from "lucide-react"; import { RunType } from "@/types/run"; import dayjs from "dayjs"; @@ -30,9 +30,15 @@ type Props = { projectId: string; runs: RunType[]; onDeleteRun: (runId: number) => void; + locale: string; }; -export default function RunsTable({ projectId, runs, onDeleteRun }: Props) { +export default function RunsTable({ + projectId, + runs, + onDeleteRun, + locale, +}: Props) { const [sortDescriptor, setSortDescriptor] = useState({ column: "id", direction: "ascending", @@ -61,9 +67,9 @@ export default function RunsTable({ projectId, runs, onDeleteRun }: Props) { case "name": return ( {cellValue} diff --git a/frontend/src/app/[locale]/projects/[projectId]/runs/[runId]/RunEditor.tsx b/frontend/src/app/[locale]/projects/[projectId]/runs/[runId]/RunEditor.tsx index 674f4de..969e291 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/runs/[runId]/RunEditor.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/runs/[runId]/RunEditor.tsx @@ -1,7 +1,7 @@ "use client"; import React from "react"; import { useState, useEffect } from "react"; -import { useRouter } from "next/navigation"; +import { useRouter } from "@/src/navigation"; import { Button, Input, @@ -63,9 +63,10 @@ const defaultTestRun = { type Props = { projectId: string; runId: string; + locale: string; }; -export default function RunEditor({ projectId, runId }: Props) { +export default function RunEditor({ projectId, runId, locale }: Props) { const [testRun, setTestRun] = useState(defaultTestRun); const [folders, setFolders] = useState([]); const [runCases, setRunCases] = useState([]); @@ -220,7 +221,9 @@ export default function RunEditor({ projectId, runId }: Props) { isIconOnly size="sm" className="rounded-full bg-neutral-50 dark:bg-neutral-600" - onPress={() => router.push(`/projects/${projectId}/runs`)} + onPress={() => + router.push(`/projects/${projectId}/runs`, { locale: locale }) + } > diff --git a/frontend/src/app/[locale]/projects/[projectId]/runs/[runId]/page.tsx b/frontend/src/app/[locale]/projects/[projectId]/runs/[runId]/page.tsx index bc8c2bb..7eea5f2 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/runs/[runId]/page.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/runs/[runId]/page.tsx @@ -3,7 +3,13 @@ import RunEditor from "./RunEditor"; export default function Page({ params, }: { - params: { projectId: string; runId: string }; + params: { projectId: string; runId: string; locale: string }; }) { - return ; + return ( + + ); } diff --git a/frontend/src/app/[locale]/projects/[projectId]/runs/page.tsx b/frontend/src/app/[locale]/projects/[projectId]/runs/page.tsx index 2ac2a97..856d0b9 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/runs/page.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/runs/page.tsx @@ -1,9 +1,13 @@ import RunsPage from "./RunsPage"; -export default function Page({ params }: { params: { projectId: string } }) { +export default function Page({ + params, +}: { + params: { projectId: string; locale: string }; +}) { return ( <> - + ); } diff --git a/frontend/src/app/[locale]/projects/page.tsx b/frontend/src/app/[locale]/projects/page.tsx index 380d83f..144604d 100644 --- a/frontend/src/app/[locale]/projects/page.tsx +++ b/frontend/src/app/[locale]/projects/page.tsx @@ -1,7 +1,7 @@ import ProjectsPage from "./ProjectsPage"; import { useTranslations } from "next-intl"; -export default function Page() { +export default function Page(params: { locale }) { const t = useTranslations("Projects"); const messages = { projects: t("projects"), @@ -23,7 +23,7 @@ export default function Page() { }; return ( <> - + ); } diff --git a/frontend/src/navigation.ts b/frontend/src/navigation.ts index 5c5256b..2aabacf 100644 --- a/frontend/src/navigation.ts +++ b/frontend/src/navigation.ts @@ -5,3 +5,6 @@ export const localePrefix = "always"; export const { Link, redirect, usePathname, useRouter } = createSharedPathnamesNavigation({ locales, localePrefix }); + +export const NextUiLinkClasses = + "data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 text-medium text-primary hover:underline hover:opacity-80 active:opacity-disabled transition-opacity underline-offset-4 dark:text-white";