Introduce prettier

This commit is contained in:
Takeshi Kimata
2024-05-19 21:06:49 +09:00
parent 75eeebefda
commit c5ba3b9a00
52 changed files with 884 additions and 1509 deletions

View File

@@ -1,7 +1,7 @@
"use client";
import React from "react";
import { useState, useEffect } from "react";
import { useRouter } from "@/src/navigation";
'use client';
import React from 'react';
import { useState, useEffect } from 'react';
import { useRouter } from '@/src/navigation';
import {
Button,
Input,
@@ -17,28 +17,14 @@ import {
Dropdown,
DropdownMenu,
DropdownItem,
} from "@nextui-org/react";
import {
Save,
ArrowLeft,
Folder,
ChevronDown,
CopyPlus,
CopyMinus,
RotateCw,
} from "lucide-react";
import RunProgressChart from "./RunPregressDonutChart";
import TestCaseSelector from "./TestCaseSelector";
import { testRunStatus } from "@/config/selection";
import {
RunType,
RunCaseType,
RunCaseInfoType,
RunStatusCountType,
RunMessages,
} from "@/types/run";
import { CaseType } from "@/types/case";
import { FolderType } from "@/types/folder";
} from '@nextui-org/react';
import { Save, ArrowLeft, Folder, ChevronDown, CopyPlus, CopyMinus, RotateCw } from 'lucide-react';
import RunProgressChart from './RunPregressDonutChart';
import TestCaseSelector from './TestCaseSelector';
import { testRunStatus } from '@/config/selection';
import { RunType, RunCaseType, RunCaseInfoType, RunStatusCountType, RunMessages } from '@/types/run';
import { CaseType } from '@/types/case';
import { FolderType } from '@/types/folder';
import {
fetchRun,
updateRun,
@@ -48,16 +34,16 @@ import {
bulkCreateRunCases,
deleteRunCase,
bulkDeleteRunCases,
} from "../runsControl";
import { fetchFolders } from "../../folders/foldersControl";
import { fetchCases } from "../../folders/[folderId]/cases/caseControl";
import { useTheme } from "next-themes";
} from '../runsControl';
import { fetchFolders } from '../../folders/foldersControl';
import { fetchCases } from '../../folders/[folderId]/cases/caseControl';
import { useTheme } from 'next-themes';
const defaultTestRun = {
id: 0,
name: "",
name: '',
configurations: 0,
description: "",
description: '',
state: 0,
projectId: 0,
};
@@ -69,18 +55,12 @@ type Props = {
locale: string;
};
export default function RunEditor({
projectId,
runId,
messages,
locale,
}: Props) {
export default function RunEditor({ projectId, runId, messages, locale }: Props) {
const { theme, setTheme } = useTheme();
const [testRun, setTestRun] = useState<RunType>(defaultTestRun);
const [folders, setFolders] = useState([]);
const [runCases, setRunCases] = useState<RunCaseType[]>([]);
const [runStatusCounts, setRunStatusCounts] =
useState<RunStatusCountType[]>();
const [runStatusCounts, setRunStatusCounts] = useState<RunStatusCountType[]>();
const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set([]));
const [selectedFolder, setSelectedFolder] = useState<FolderType>({});
const [testcases, setTestCases] = useState<CaseType[]>([]);
@@ -102,7 +82,7 @@ export default function RunEditor({
setFolders(foldersData);
setSelectedFolder(foldersData[0]);
} catch (error: any) {
console.error("Error in effect:", error.message);
console.error('Error in effect:', error.message);
}
}
@@ -120,9 +100,7 @@ export default function RunEditor({
// Check if each testCase has an association with testRun
// and add "isIncluded" property
const updatedTestCasesData = testCasesData.map((testCase) => {
const runCase = latestRunCases.find(
(runCase) => runCase.caseId === testCase.id
);
const runCase = latestRunCases.find((runCase) => runCase.caseId === testCase.id);
const isIncluded = runCase ? true : false;
const runStatus = runCase ? runCase.status : 0;
@@ -135,7 +113,7 @@ export default function RunEditor({
setTestCases(updatedTestCasesData);
} catch (error: any) {
console.error("Error fetching cases data:", error.message);
console.error('Error fetching cases data:', error.message);
}
}
}
@@ -155,10 +133,7 @@ export default function RunEditor({
});
};
const handleIncludeExcludeCase = async (
isInclude: boolean,
clickedTestCaseId: number
) => {
const handleIncludeExcludeCase = async (isInclude: boolean, clickedTestCaseId: number) => {
if (isInclude) {
const createdRunCase = await createRunCase(runId, clickedTestCaseId);
setRunCases((prevRunCases) => {
@@ -167,9 +142,7 @@ export default function RunEditor({
} else {
await deleteRunCase(runId, clickedTestCaseId);
setRunCases((prevRunCases) => {
return prevRunCases.filter(
(runCase) => runCase.caseId !== clickedTestCaseId
);
return prevRunCases.filter((runCase) => runCase.caseId !== clickedTestCaseId);
});
}
@@ -185,7 +158,7 @@ export default function RunEditor({
const handleBulkIncludeExcludeCases = async (isInclude: boolean) => {
let keys: number[] = [];
if (selectedKeys === "all") {
if (selectedKeys === 'all') {
keys = testcases.map((item) => item.id);
} else {
keys = Array.from(selectedKeys).map(Number);
@@ -218,7 +191,7 @@ export default function RunEditor({
setSelectedKeys(new Set([]));
};
const baseClass = "";
const baseClass = '';
const selectedClass = `${baseClass} bg-neutral-200 dark:bg-neutral-700`;
return (
@@ -230,9 +203,7 @@ export default function RunEditor({
isIconOnly
size="sm"
className="rounded-full bg-neutral-50 dark:bg-neutral-600"
onPress={() =>
router.push(`/projects/${projectId}/runs`, { locale: locale })
}
onPress={() => router.push(`/projects/${projectId}/runs`, { locale: locale })}
>
<ArrowLeft size={16} />
</Button>
@@ -272,11 +243,7 @@ export default function RunEditor({
</Tooltip>
</div>
<RunProgressChart
statusCounts={runStatusCounts}
messages={messages}
theme={theme}
/>
<RunProgressChart statusCounts={runStatusCounts} messages={messages} theme={theme} />
</div>
</div>
<div className="flex-grow">
@@ -287,7 +254,7 @@ export default function RunEditor({
label={messages.title}
value={testRun.name}
isInvalid={isNameInvalid}
errorMessage={isNameInvalid ? messages.pleaseEnter : ""}
errorMessage={isNameInvalid ? messages.pleaseEnter : ''}
onChange={(e) => {
setTestRun({ ...testRun, name: e.target.value });
}}
@@ -312,9 +279,7 @@ export default function RunEditor({
selectedKeys={[testRunStatus[testRun.state].uid]}
onSelectionChange={(e) => {
const selectedUid = e.anchorKey;
const index = testRunStatus.findIndex(
(template) => template.uid === selectedUid
);
const index = testRunStatus.findIndex((template) => template.uid === selectedUid);
setTestRun({ ...testRun, state: index });
}}
label={messages.status}
@@ -334,14 +299,10 @@ export default function RunEditor({
<div className="flex items-center justify-between">
<h6 className="h-8 font-bold">{messages.selectTestCase}</h6>
<div>
{(selectedKeys.size > 0 || selectedKeys === "all") && (
{(selectedKeys.size > 0 || selectedKeys === 'all') && (
<Dropdown>
<DropdownTrigger>
<Button
size="sm"
color="primary"
endContent={<ChevronDown size={16} />}
>
<Button size="sm" color="primary" endContent={<ChevronDown size={16} />}>
{messages.testCaseSelection}
</Button>
</DropdownTrigger>
@@ -371,14 +332,8 @@ export default function RunEditor({
<ListboxItem
key={index}
onClick={() => setSelectedFolder(folder)}
startContent={
<Folder size={20} color="#F7C24E" fill="#F7C24E" />
}
className={
selectedFolder && folder.id === selectedFolder.id
? selectedClass
: baseClass
}
startContent={<Folder size={20} color="#F7C24E" fill="#F7C24E" />}
className={selectedFolder && folder.id === selectedFolder.id ? selectedClass : baseClass}
>
{folder.name}
</ListboxItem>
@@ -391,12 +346,8 @@ export default function RunEditor({
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}
onStatusChange={handleChangeStatus}
onIncludeCase={(includeTestId) =>
handleIncludeExcludeCase(true, includeTestId)
}
onExcludeCase={(excludeCaseId) =>
handleIncludeExcludeCase(false, excludeCaseId)
}
onIncludeCase={(includeTestId) => handleIncludeExcludeCase(true, includeTestId)}
onExcludeCase={(excludeCaseId) => handleIncludeExcludeCase(false, excludeCaseId)}
messages={messages}
/>
</div>

View File

@@ -1,9 +1,9 @@
import React from "react";
import { useState, useEffect } from "react";
import dynamic from "next/dynamic";
import { testRunCaseStatus } from "@/config/selection";
import { RunStatusCountType, RunMessages } from "@/types/run";
const Chart = dynamic(() => import("react-apexcharts"), { ssr: false });
import React from 'react';
import { useState, useEffect } from 'react';
import dynamic from 'next/dynamic';
import { testRunCaseStatus } from '@/config/selection';
import { RunStatusCountType, RunMessages } from '@/types/run';
const Chart = dynamic(() => import('react-apexcharts'), { ssr: false });
type Props = {
statusCounts: RunStatusCountType[];
@@ -11,11 +11,7 @@ type Props = {
theme: string;
};
export default function RunProgressDounut({
statusCounts,
messages,
theme,
}: Props) {
export default function RunProgressDounut({ statusCounts, messages, theme }: Props) {
const [chartData, setChartData] = useState({
series: [],
options: {
@@ -37,10 +33,10 @@ export default function RunProgressDounut({
const legend = {
labels: {
colors: testRunCaseStatus.map((entry) => {
if (theme === "light") {
return "black";
if (theme === 'light') {
return 'black';
} else {
return "white";
return 'white';
}
}),
},
@@ -56,13 +52,5 @@ export default function RunProgressDounut({
updateChartDate();
}, [statusCounts, theme]);
return (
<Chart
options={chartData.options}
series={chartData.series}
type="donut"
width={"100%"}
height={"100%"}
/>
);
return <Chart options={chartData.options} series={chartData.series} type="donut" width={'100%'} height={'100%'} />;
}

View File

@@ -1,4 +1,4 @@
import { useState, useMemo } from "react";
import { useState, useMemo } from 'react';
import {
Table,
TableHeader,
@@ -13,7 +13,7 @@ import {
DropdownItem,
Selection,
SortDescriptor,
} from "@nextui-org/react";
} from '@nextui-org/react';
import {
ChevronDown,
MoreVertical,
@@ -24,10 +24,10 @@ import {
CircleDashed,
CircleX,
CircleSlash2,
} from "lucide-react";
import { priorities, testRunCaseStatus } from "@/config/selection";
import { CaseType } from "@/types/case";
import { RunsMessages } from "@/types/run";
} from 'lucide-react';
import { priorities, testRunCaseStatus } from '@/config/selection';
import { CaseType } from '@/types/case';
import { RunsMessages } from '@/types/run';
type Props = {
cases: CaseType[];
@@ -49,16 +49,16 @@ export default function TestCaseSelector({
messages,
}: 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.status, uid: "runStatus", sortable: true },
{ name: messages.actions, uid: "actions" },
{ name: messages.id, uid: 'id', sortable: true },
{ name: messages.title, uid: 'title', sortable: true },
{ name: messages.priority, uid: 'priority', sortable: true },
{ name: messages.status, uid: 'runStatus', sortable: true },
{ name: messages.actions, uid: 'actions' },
];
const [sortDescriptor, setSortDescriptor] = useState<SortDescriptor>({
column: "id",
direction: "ascending",
column: 'id',
direction: 'ascending',
});
const sortedItems = useMemo(() => {
@@ -67,23 +67,23 @@ export default function TestCaseSelector({
const second = b[sortDescriptor.column as keyof CaseType] as number;
const cmp = first < second ? -1 : first > second ? 1 : 0;
return sortDescriptor.direction === "descending" ? -cmp : cmp;
return sortDescriptor.direction === 'descending' ? -cmp : cmp;
});
}, [sortDescriptor, cases]);
const notIncludedCaseClass = "text-neutral-200 dark:text-neutral-600";
const chipBaseClass = "flex items-center text-default-600";
const notIncludedCaseClass = 'text-neutral-200 dark:text-neutral-600';
const chipBaseClass = 'flex items-center text-default-600';
const renderStatusIcon = (uid: string) => {
if (uid === "untested") {
if (uid === 'untested') {
return <Circle size={16} color="#d4d4d8" />;
} else if (uid === "passed") {
} else if (uid === 'passed') {
return <CircleCheck size={16} color="#17c964" />;
} else if (uid === "retest") {
} else if (uid === 'retest') {
return <CircleDashed size={16} color="#f5a524" />;
} else if (uid === "failed") {
} else if (uid === 'failed') {
return <CircleX size={16} color="#f31260" />;
} else if (uid === "skipped") {
} else if (uid === 'skipped') {
return <CircleSlash2 size={16} color="#52525b" />;
}
};
@@ -93,22 +93,18 @@ export default function TestCaseSelector({
const isIncluded = testCase.isIncluded;
switch (columnKey) {
case "priority":
case 'priority':
return (
<div
className={
isIncluded ? chipBaseClass : chipBaseClass + notIncludedCaseClass
}
>
<div className={isIncluded ? chipBaseClass : chipBaseClass + notIncludedCaseClass}>
<Circle
size={8}
color={isIncluded ? priorities[cellValue].color : "#d4d4d8"}
fill={isIncluded ? priorities[cellValue].color : "#d4d4d8"}
color={isIncluded ? priorities[cellValue].color : '#d4d4d8'}
fill={isIncluded ? priorities[cellValue].color : '#d4d4d8'}
/>
<div className="ms-3">{messages[priorities[cellValue].uid]}</div>
</div>
);
case "runStatus":
case 'runStatus':
return (
<Dropdown>
<DropdownTrigger>
@@ -116,15 +112,10 @@ export default function TestCaseSelector({
size="sm"
variant="light"
isDisabled={!isIncluded}
startContent={
isIncluded &&
renderStatusIcon(testRunCaseStatus[cellValue].uid)
}
startContent={isIncluded && renderStatusIcon(testRunCaseStatus[cellValue].uid)}
endContent={isIncluded && <ChevronDown size={16} />}
>
<span className="w-12">
{isIncluded && messages[testRunCaseStatus[cellValue].uid]}
</span>
<span className="w-12">{isIncluded && messages[testRunCaseStatus[cellValue].uid]}</span>
</Button>
</DropdownTrigger>
<DropdownMenu aria-label="test case actions">
@@ -140,7 +131,7 @@ export default function TestCaseSelector({
</DropdownMenu>
</Dropdown>
);
case "actions":
case 'actions':
return (
<Dropdown>
<DropdownTrigger>
@@ -173,18 +164,18 @@ export default function TestCaseSelector({
const classNames = useMemo(
() => ({
wrapper: ["min-w-3xl"],
th: ["bg-transparent", "text-default-500", "border-b", "border-divider"],
wrapper: ['min-w-3xl'],
th: ['bg-transparent', 'text-default-500', 'border-b', 'border-divider'],
td: [
// changing the rows border radius
// first
"group-data-[first=true]:first:before:rounded-none",
"group-data-[first=true]:last:before:rounded-none",
'group-data-[first=true]:first:before:rounded-none',
'group-data-[first=true]:last:before:rounded-none',
// middle
"group-data-[middle=true]:before:rounded-none",
'group-data-[middle=true]:before:rounded-none',
// last
"group-data-[last=true]:first:before:rounded-none",
"group-data-[last=true]:last:before:rounded-none",
'group-data-[last=true]:first:before:rounded-none',
'group-data-[last=true]:last:before:rounded-none',
],
}),
[]
@@ -211,7 +202,7 @@ export default function TestCaseSelector({
{(column) => (
<TableColumn
key={column.uid}
align={column.uid === "actions" ? "center" : "start"}
align={column.uid === 'actions' ? 'center' : 'start'}
allowsSorting={column.sortable}
>
{column.name}
@@ -220,13 +211,8 @@ export default function TestCaseSelector({
</TableHeader>
<TableBody emptyContent={messages.noCasesFound} items={sortedItems}>
{(item) => (
<TableRow
key={item.id}
className={!item.isIncluded ? notIncludedCaseClass : ""}
>
{(columnKey) => (
<TableCell>{renderCell(item, columnKey)}</TableCell>
)}
<TableRow key={item.id} className={!item.isIncluded ? notIncludedCaseClass : ''}>
{(columnKey) => <TableCell>{renderCell(item, columnKey)}</TableCell>}
</TableRow>
)}
</TableBody>

View File

@@ -1,53 +1,42 @@
import RunEditor from "./RunEditor";
import { useTranslations } from "next-intl";
import RunEditor from './RunEditor';
import { useTranslations } from 'next-intl';
export default function Page({
params,
}: {
params: { projectId: string; runId: string; locale: string };
}) {
const t = useTranslations("Run");
export default function Page({ params }: { params: { projectId: string; runId: string; locale: string } }) {
const t = useTranslations('Run');
const messages = {
backToRuns: t("back_to_runs"),
updating: t("updating"),
update: t("update"),
progress: t("progress"),
refresh: t("refresh"),
id: t("id"),
title: t("title"),
pleaseEnter: t("please_enter"),
description: t("description"),
new: t("new"),
inProgress: t("inProgress"),
underReview: t("underReview"),
rejected: t("rejected"),
done: t("done"),
closed: t("closed"),
priority: t("priority"),
actions: t("actions"),
status: t("status"),
critical: t("critical"),
high: t("high"),
medium: t("medium"),
low: t("low"),
untested: t("untested"),
passed: t("passed"),
failed: t("failed"),
retest: t("retest"),
skipped: t("skipped"),
selectTestCase: t("select_test_case"),
testCaseSelection: t("test_case_selection"),
includeInRun: t("include_in_run"),
excludeFromRun: t("exclude_from_run"),
noCasesFound: t("no_cases_found"),
backToRuns: t('back_to_runs'),
updating: t('updating'),
update: t('update'),
progress: t('progress'),
refresh: t('refresh'),
id: t('id'),
title: t('title'),
pleaseEnter: t('please_enter'),
description: t('description'),
new: t('new'),
inProgress: t('inProgress'),
underReview: t('underReview'),
rejected: t('rejected'),
done: t('done'),
closed: t('closed'),
priority: t('priority'),
actions: t('actions'),
status: t('status'),
critical: t('critical'),
high: t('high'),
medium: t('medium'),
low: t('low'),
untested: t('untested'),
passed: t('passed'),
failed: t('failed'),
retest: t('retest'),
skipped: t('skipped'),
selectTestCase: t('select_test_case'),
testCaseSelection: t('test_case_selection'),
includeInRun: t('include_in_run'),
excludeFromRun: t('exclude_from_run'),
noCasesFound: t('no_cases_found'),
};
return (
<RunEditor
projectId={params.projectId}
runId={params.runId}
messages={messages}
locale={params.locale}
/>
);
return <RunEditor projectId={params.projectId} runId={params.runId} messages={messages} locale={params.locale} />;
}