Apply i18n

This commit is contained in:
Takeshi Kimata
2024-05-04 15:03:05 +09:00
parent 772da88e9b
commit 9c390ef305
14 changed files with 201 additions and 34 deletions

View File

@@ -4,12 +4,14 @@ import { Listbox, ListboxItem } from "@nextui-org/react";
import { Home, Files, FlaskConical } from "lucide-react";
import { usePathname, useRouter } from "@/src/navigation";
import useGetCurrentIds from "@/utils/useGetCurrentIds";
import { ProjectMessages } from "@/types/project";
export type Props = {
messages: ProjectMessages;
locale: string;
};
export default function Sidebar({ locale }: Props) {
export default function Sidebar({ messages, locale }: Props) {
const { projectId } = useGetCurrentIds();
const router = useRouter();
const pathname = usePathname();
@@ -45,17 +47,17 @@ export default function Sidebar({ locale }: Props) {
const tabItems = [
{
key: "home",
text: "Home",
text: messages.home,
startContent: <Home strokeWidth={1} size={28} />,
},
{
key: "cases",
text: "Test Cases",
text: messages.testCases,
startContent: <Files strokeWidth={1} size={28} />,
},
{
key: "runs",
text: "Test Runs",
text: messages.testRuns,
startContent: <FlaskConical strokeWidth={1} size={28} />,
},
];

View File

@@ -11,13 +11,14 @@ import {
ModalBody,
ModalFooter,
} from "@nextui-org/react";
import { FolderType } from "@/types/folder";
import { FolderType, FoldersMessages } from "@/types/folder";
type Props = {
isOpen: boolean;
editingFolder: FolderType;
onCancel: () => void;
onSubmit: (name: string, detail: string) => void;
messages: FoldersMessages;
};
export default function FolderDialog({
@@ -25,6 +26,7 @@ export default function FolderDialog({
editingFolder,
onCancel,
onSubmit,
messages,
}: Props) {
const [folderName, setFolderName] = useState({
text: editingFolder ? editingFolder.name : "",
@@ -80,7 +82,7 @@ export default function FolderDialog({
setFolderName({
text: "",
isValid: false,
errorMessage: "Please enter folder name",
errorMessage: messages.pleaseEnter,
});
return;
@@ -98,11 +100,13 @@ export default function FolderDialog({
}}
>
<ModalContent>
<ModalHeader className="flex flex-col gap-1">Folder</ModalHeader>
<ModalHeader className="flex flex-col gap-1">
{messages.folder}
</ModalHeader>
<ModalBody>
<Input
type="text"
label="Folder Name"
label={messages.folderName}
value={folderName.text}
isInvalid={folderName.isValid}
errorMessage={folderName.errorMessage}
@@ -114,7 +118,7 @@ export default function FolderDialog({
}}
/>
<Textarea
label="Folder Detail"
label={messages.folderDetail}
value={folderDetail.text}
isInvalid={folderDetail.isValid}
errorMessage={folderDetail.errorMessage}
@@ -128,10 +132,10 @@ export default function FolderDialog({
</ModalBody>
<ModalFooter>
<Button variant="light" onPress={onCancel}>
Close
{messages.close}
</Button>
<Button color="primary" onPress={validate}>
{editingFolder ? "Update" : "Create"}
{editingFolder ? messages.update : messages.create}
</Button>
</ModalFooter>
</ModalContent>

View File

@@ -6,8 +6,21 @@ import {
DropdownItem,
} from "@nextui-org/react";
import { MoreVertical } from "lucide-react";
import { FolderType, FoldersMessages } from "@/types/folder";
export default function FolderEditMenu({ folder, onEditClick, onDeleteClick }) {
type Props = {
folder: FolderType;
onEditClick: (folder: FolderType) => void;
onDeleteClick: (folder: FolderType) => void;
messages: FoldersMessages;
};
export default function FolderEditMenu({
folder,
onEditClick,
onDeleteClick,
messages,
}: Props) {
return (
<Dropdown>
<DropdownTrigger>
@@ -17,7 +30,7 @@ export default function FolderEditMenu({ folder, onEditClick, onDeleteClick }) {
</DropdownTrigger>
<DropdownMenu aria-label="Static Actions">
<DropdownItem key="edit" onClick={() => onEditClick(folder)}>
Edit folder
{messages.editFolder}
</DropdownItem>
<DropdownItem
key="delete"
@@ -25,7 +38,7 @@ export default function FolderEditMenu({ folder, onEditClick, onDeleteClick }) {
color="danger"
onClick={() => onDeleteClick(folder.id)}
>
Delete folder
{messages.deleteFolder}
</DropdownItem>
</DropdownMenu>
</Dropdown>

View File

@@ -1,6 +1,6 @@
"use client";
import React from "react";
import { FolderType } from "@/types/folder";
import { FolderType, FoldersMessages } from "@/types/folder";
import { useEffect, useState } from "react";
import { Button, Listbox, ListboxItem } from "@nextui-org/react";
import { Folder, Plus } from "lucide-react";
@@ -18,10 +18,11 @@ import {
type Props = {
projectId: string;
messages: FoldersMessages;
locale: string;
};
export default function FoldersPane({ projectId, locale }: Props) {
export default function FoldersPane({ projectId, messages, locale }: Props) {
const router = useRouter();
const pathname = usePathname();
const [folders, setFolders] = useState([]);
@@ -112,7 +113,7 @@ export default function FoldersPane({ projectId, locale }: Props) {
className="m-2"
onClick={openDialogForCreate}
>
New Folder
{messages.newFolder}
</Button>
<Listbox aria-label="Listbox Variants" variant="light">
{folders.map((folder, index) => (
@@ -135,6 +136,7 @@ export default function FoldersPane({ projectId, locale }: Props) {
folder={folder}
onEditClick={onEditClick}
onDeleteClick={onDeleteClick}
messages={messages}
/>
}
>
@@ -149,6 +151,7 @@ export default function FoldersPane({ projectId, locale }: Props) {
editingFolder={editingFolder}
onCancel={closeDialog}
onSubmit={onSubmit}
messages={messages}
/>
</>
);

View File

@@ -2,14 +2,21 @@
import { useEffect, useState } from "react";
import TestCaseTable from "./TestCaseTable";
import { fetchCases, createCase, deleteCase, deleteCases } from "./caseControl";
import { CasesMessages } from "@/types/case";
type Props = {
projectId: string;
folderId: string;
messages: CasesMessages;
locale: string;
};
export default function CasesPane({ projectId, folderId, locale }: Props) {
export default function CasesPane({
projectId,
folderId,
messages,
locale,
}: Props) {
const [cases, setCases] = useState([]);
useEffect(() => {
async function fetchDataEffect() {
@@ -51,6 +58,7 @@ export default function CasesPane({ projectId, folderId, locale }: Props) {
onCreateCase={() => handleCreateCase(folderId)}
onDeleteCase={handleDeleteCase}
onDeleteCases={handleDeleteCases}
messages={messages}
locale={locale}
/>
</>

View File

@@ -16,14 +16,7 @@ import {
} from "@nextui-org/react";
import { Link, NextUiLinkClasses } from "@/src/navigation";
import { Plus, MoreVertical, Trash, Circle } from "lucide-react";
const headerColumns = [
{ name: "ID", uid: "id", sortable: true },
{ name: "Title", uid: "title", sortable: true },
{ name: "Priority", uid: "priority", sortable: true },
{ name: "Actions", uid: "actions" },
];
import { CasesMessages } from "@/types/case";
import { priorities } from "@/config/selection";
type Case = {
@@ -48,6 +41,7 @@ type Props = {
onCreateCase: () => void;
onDeleteCase: (caseId: number) => void;
onDeleteCases: (selectedCases: string[]) => void;
messages: CasesMessages;
locale: string;
};
@@ -57,8 +51,16 @@ export default function TestCaseTable({
onCreateCase,
onDeleteCase,
onDeleteCases,
messages,
locale,
}: Props) {
const headerColumns = [
{ name: messages.id, uid: "id", sortable: true },
{ name: messages.title, uid: "title", sortable: true },
{ name: messages.priority, uid: "priority", sortable: true },
{ name: messages.actions, uid: "actions" },
];
const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set([]));
const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>({
column: "id",
@@ -121,7 +123,7 @@ export default function TestCaseTable({
className="text-danger"
onClick={() => onDeleteCase(testCase.id)}
>
Delete test case
{messages.deleteCase}
</DropdownItem>
</DropdownMenu>
</Dropdown>
@@ -163,7 +165,7 @@ export default function TestCaseTable({
return (
<>
<div className="border-b-1 dark:border-neutral-700 w-full p-3 flex items-center justify-between">
<h3 className="font-bold">Cases</h3>
<h3 className="font-bold">{messages.testCases}</h3>
<div>
{(selectedKeys.size > 0 || selectedKeys === "all") && (
<Button
@@ -173,7 +175,7 @@ export default function TestCaseTable({
className="me-2"
onClick={onDeleteCasesClick}
>
Delete
{messages.delete}
</Button>
)}
<Button
@@ -182,7 +184,7 @@ export default function TestCaseTable({
color="primary"
onClick={onCreateCase}
>
New Test Case
{messages.newTestCase}
</Button>
</div>
</div>

View File

@@ -1,16 +1,40 @@
import CasesPane from "./CasesPane";
import { useTranslations } from "next-intl";
export default function Page({
params,
}: {
params: { projectId: string; folderId: string; locale: string };
}) {
const t = useTranslations("Cases");
const messages = {
testCases: t("test_cases"),
// folder: t("folder"),
// newFolder: t("new_folder"),
// deleteFolder: t("delete_folder"),
id: t("id"),
title: t("title"),
priority: t("priority"),
actions: t("actions"),
deleteCase: t("delete_case"),
delete: t("delete"),
newTestCase: t("new_test_case"),
// projectName: t("folder_name"),
// projectDetail: t("folder_detail"),
// close: t("close"),
// create: t("create"),
// update: t("update"),
// pleaseEnter: t("please_enter"),
};
return (
<>
<CasesPane
projectId={params.projectId}
folderId={params.folderId}
locale={params.locale}
messages={messages}
/>
</>
);

View File

@@ -1,4 +1,5 @@
import FoldersPane from "./FoldersPane";
import { useTranslations } from "next-intl";
export default function FoldersLayout({
children,
@@ -7,9 +8,27 @@ export default function FoldersLayout({
children: React.ReactNode;
params: { projectId: string; locale: string };
}) {
const t = useTranslations("Folders");
const messages = {
folder: t("folder"),
newFolder: t("new_folder"),
editFolder: t("edit_folder"),
deleteFolder: t("delete_folder"),
folderName: t("folder_name"),
folderDetail: t("folder_detail"),
close: t("close"),
create: t("create"),
update: t("update"),
pleaseEnter: t("please_enter"),
};
return (
<div className="flex w-full">
<FoldersPane projectId={params.projectId} locale={params.locale} />
<FoldersPane
projectId={params.projectId}
messages={messages}
locale={params.locale}
/>
<div className="flex-grow w-full">{children}</div>
</div>
);

View File

@@ -1,4 +1,5 @@
import Sidebar from "./Sidebar";
import { useTranslations } from "next-intl";
export default function SidebarLayout({
children,
@@ -7,10 +8,17 @@ export default function SidebarLayout({
children: React.ReactNode;
params: { locale: string };
}) {
const t = useTranslations("Project");
const messages = {
home: t("home"),
testCases: t("test_cases"),
testRuns: t("test_runs"),
};
return (
<>
<div className="flex border-t-1 dark:border-neutral-700 min-h-[calc(100vh-64px)]">
<Sidebar locale={locale} />
<Sidebar messages={messages} locale={locale} />
<div className="flex w-full">
<div className="flex-grow">{children}</div>
</div>