fix(/management/person/dashboard): component change
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
|||||||
Select,
|
Select,
|
||||||
Table,
|
Table,
|
||||||
} from "@mantine/core"
|
} from "@mantine/core"
|
||||||
|
|
||||||
import { IconRefresh } from "@tabler/icons-react"
|
import { IconRefresh } from "@tabler/icons-react"
|
||||||
import dayjs from "dayjs"
|
import dayjs from "dayjs"
|
||||||
import duration from "dayjs/plugin/duration"
|
import duration from "dayjs/plugin/duration"
|
||||||
@@ -73,7 +74,10 @@ export default function PersonalProjectTable() {
|
|||||||
style={{ flexDirection: "column" }}>
|
style={{ flexDirection: "column" }}>
|
||||||
<Group justify="flex-end">
|
<Group justify="flex-end">
|
||||||
<Button
|
<Button
|
||||||
variant="filled"
|
size={"xs"}
|
||||||
|
fz={"sm"}
|
||||||
|
fw={500}
|
||||||
|
radius="sm"
|
||||||
onClick={load}
|
onClick={load}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
leftSection={<IconRefresh size={16} />}>
|
leftSection={<IconRefresh size={16} />}>
|
||||||
|
|||||||
@@ -1,27 +1,18 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { getUserTaskList } from "@/components/label/api/task"
|
import { getUserTaskList } from "@/components/label/api/task"
|
||||||
|
import { Task } from "@/components/label/api/task/typing"
|
||||||
import {
|
import {
|
||||||
useBackUrlStore,
|
useBackUrlStore,
|
||||||
usePermissionStore,
|
usePermissionStore,
|
||||||
} from "@/components/label/store/auth"
|
} from "@/components/label/store/auth"
|
||||||
import { TaskStatusEnum } from "@/components/label/utils/constants"
|
import { TaskStatusEnum } from "@/components/label/utils/constants"
|
||||||
import {
|
import { Badge, Button, Group, Text, UnstyledButton } from "@mantine/core"
|
||||||
Anchor,
|
|
||||||
Badge,
|
|
||||||
Button,
|
|
||||||
Group,
|
|
||||||
Pagination,
|
|
||||||
ScrollArea,
|
|
||||||
Select,
|
|
||||||
Table,
|
|
||||||
Text,
|
|
||||||
} from "@mantine/core"
|
|
||||||
import { IconRefresh } from "@tabler/icons-react"
|
import { IconRefresh } from "@tabler/icons-react"
|
||||||
|
import { DataTable, DataTableColumn } from "mantine-datatable"
|
||||||
import { useRouter } from "next/navigation"
|
import { useRouter } from "next/navigation"
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react"
|
import { useCallback, useEffect, useMemo, useState } from "react"
|
||||||
|
import { runCommand } from "./util"
|
||||||
const pageSizeOptions = [50, 100, 200]
|
|
||||||
|
|
||||||
function getStatusColor(status?: number | null) {
|
function getStatusColor(status?: number | null) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@@ -49,7 +40,7 @@ export default function PersonalTaskTable() {
|
|||||||
const [page, setPage] = useState(1)
|
const [page, setPage] = useState(1)
|
||||||
const [pageSize, setPageSize] = useState(50)
|
const [pageSize, setPageSize] = useState(50)
|
||||||
const [totalItems, setTotalItems] = useState(0)
|
const [totalItems, setTotalItems] = useState(0)
|
||||||
const [records, setRecords] = useState<any[]>([])
|
const [records, setRecords] = useState<Task.SimpleTaskItem[]>([])
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
|
|
||||||
const totalPages = useMemo(() => {
|
const totalPages = useMemo(() => {
|
||||||
@@ -84,6 +75,92 @@ export default function PersonalTaskTable() {
|
|||||||
else setPage(1)
|
else setPage(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [currentRowId, setCurrentRowId] = useState<number>(0)
|
||||||
|
|
||||||
|
const originColumn = useMemo(() => {
|
||||||
|
let column: DataTableColumn<Task.SimpleTaskItem>[] = [
|
||||||
|
{
|
||||||
|
accessor: "project_name",
|
||||||
|
title: "项目名称",
|
||||||
|
width: 150,
|
||||||
|
render: (record: Task.SimpleTaskItem) => {
|
||||||
|
return <Text>{record.project_name}</Text>
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: "id",
|
||||||
|
title: "任务ID",
|
||||||
|
width: 150,
|
||||||
|
render: (record: Task.SimpleTaskItem) => {
|
||||||
|
return (
|
||||||
|
<UnstyledButton
|
||||||
|
px={6}
|
||||||
|
variant="transparent"
|
||||||
|
onClick={async () => {
|
||||||
|
setCurrentRowId(record.id)
|
||||||
|
if ([4, 5, 6].includes(record.label_type)) {
|
||||||
|
setBackProps(`/project/person`)
|
||||||
|
router.push(
|
||||||
|
`/label?project_id=${record.project_id}&task_id=${record.id}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
await runCommand(
|
||||||
|
record.id.toString(),
|
||||||
|
user_name,
|
||||||
|
user_password
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
title={record.id.toString()}
|
||||||
|
c={"brand"}
|
||||||
|
style={{
|
||||||
|
fontSize: "14px",
|
||||||
|
maxWidth: "100%",
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
}}>
|
||||||
|
{record.id}
|
||||||
|
</UnstyledButton>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: "label_status",
|
||||||
|
title: "状态",
|
||||||
|
width: 80,
|
||||||
|
render: (record: Task.SimpleTaskItem) => {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
color={getStatusColor(record.label_status)}
|
||||||
|
style={{
|
||||||
|
fontSize: "12px",
|
||||||
|
padding: "2px 6px",
|
||||||
|
}}>
|
||||||
|
{TaskStatusEnum.get(record.label_status)}
|
||||||
|
</Badge>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: "label_username",
|
||||||
|
title: "标注员",
|
||||||
|
width: 80,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: "review1_username",
|
||||||
|
title: "审核员",
|
||||||
|
width: 80,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: "review2_username",
|
||||||
|
title: "复审员",
|
||||||
|
width: 80,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
return column
|
||||||
|
}, [router, setBackProps, user_name, user_password])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group
|
<Group
|
||||||
gap="sm"
|
gap="sm"
|
||||||
@@ -92,89 +169,49 @@ export default function PersonalTaskTable() {
|
|||||||
style={{ flexDirection: "column" }}>
|
style={{ flexDirection: "column" }}>
|
||||||
<Group justify="flex-end">
|
<Group justify="flex-end">
|
||||||
<Button
|
<Button
|
||||||
variant="filled"
|
size={"xs"}
|
||||||
|
fz={"sm"}
|
||||||
|
fw={500}
|
||||||
|
radius="sm"
|
||||||
onClick={resetData}
|
onClick={resetData}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
leftSection={<IconRefresh size={16} />}>
|
leftSection={<IconRefresh size={16} />}>
|
||||||
更新
|
更新
|
||||||
</Button>
|
</Button>
|
||||||
</Group>
|
</Group>
|
||||||
<Group gap={0} align="stretch" style={{ flex: 1, minHeight: 0 }}>
|
<Group
|
||||||
<ScrollArea style={{ flex: 1 }}>
|
gap={0}
|
||||||
<Table withTableBorder withColumnBorders striped highlightOnHover>
|
align="stretch"
|
||||||
<Table.Thead>
|
style={{ flex: 1, minHeight: 0, width: "100%" }}>
|
||||||
<Table.Tr>
|
<DataTable<Task.SimpleTaskItem>
|
||||||
<Table.Th style={{ width: 260 }}>项目名称</Table.Th>
|
width="100%"
|
||||||
<Table.Th style={{ width: 110 }}>任务ID</Table.Th>
|
style={{ width: "100%" }}
|
||||||
<Table.Th style={{ width: 160 }}>状态</Table.Th>
|
styles={{
|
||||||
<Table.Th style={{ width: 90 }}>标注员</Table.Th>
|
header: {
|
||||||
<Table.Th style={{ width: 90 }}>审核员</Table.Th>
|
color: "var(--mantine-color-grey-text)",
|
||||||
<Table.Th style={{ width: 90 }}>复审员</Table.Th>
|
backgroundColor: "var(--mantine-datatable-striped-color)",
|
||||||
</Table.Tr>
|
},
|
||||||
</Table.Thead>
|
}}
|
||||||
<Table.Tbody>
|
withTableBorder
|
||||||
{records.map((record) => (
|
withRowBorders
|
||||||
<Table.Tr key={record.id}>
|
pinFirstColumn
|
||||||
<Table.Td>
|
pinLastColumn
|
||||||
<Text lineClamp={1}>{record.project_name ?? "-"}</Text>
|
rowBackgroundColor={({ id }) => {
|
||||||
</Table.Td>
|
if (id === currentRowId)
|
||||||
<Table.Td>
|
return "var(--mantine-datatable-highlight-on-hover-color-light, var(--mantine-datatable-highlight-on-hover-color))"
|
||||||
<Anchor
|
}}
|
||||||
onClick={async (e) => {
|
scrollAreaProps={{ type: "auto" }}
|
||||||
e.preventDefault()
|
records={records}
|
||||||
const labelType = record.label_type
|
onRecordsPerPageChange={setPageSize}
|
||||||
if ([4, 5, 6].includes(labelType)) {
|
recordsPerPageOptions={[10, 15, 20]}
|
||||||
setBackProps("/management/person/dashboard")
|
columns={originColumn}
|
||||||
router.push(
|
totalRecords={totalItems}
|
||||||
`/label?project_id=${record.project_id}&task_id=${record.id}`
|
recordsPerPage={pageSize}
|
||||||
)
|
page={page}
|
||||||
return
|
onPageChange={setPage}
|
||||||
}
|
noRecordsText="暂无数据"
|
||||||
if (user_name && user_password) {
|
recordsPerPageLabel="当前页数"
|
||||||
setBackProps("/management/person/dashboard")
|
/>
|
||||||
router.push(
|
|
||||||
`/label?project_id=${record.project_id}&task_id=${record.id}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
style={{ cursor: "pointer" }}>
|
|
||||||
{record.id ?? "-"}
|
|
||||||
</Anchor>
|
|
||||||
</Table.Td>
|
|
||||||
<Table.Td>
|
|
||||||
<Badge
|
|
||||||
color={getStatusColor(record.label_status)}
|
|
||||||
variant="light">
|
|
||||||
{`${TaskStatusEnum.get(record.label_status) ?? "-"}${
|
|
||||||
record.rejected ? "返工" : ""
|
|
||||||
}`}
|
|
||||||
</Badge>
|
|
||||||
</Table.Td>
|
|
||||||
<Table.Td>{record.label_username ?? "-"}</Table.Td>
|
|
||||||
<Table.Td>{record.review1_username ?? "-"}</Table.Td>
|
|
||||||
<Table.Td>{record.review2_username ?? "-"}</Table.Td>
|
|
||||||
</Table.Tr>
|
|
||||||
))}
|
|
||||||
</Table.Tbody>
|
|
||||||
</Table>
|
|
||||||
</ScrollArea>
|
|
||||||
</Group>
|
|
||||||
<Group justify="space-between">
|
|
||||||
<Group gap="xs">
|
|
||||||
<Select
|
|
||||||
w={120}
|
|
||||||
value={String(pageSize)}
|
|
||||||
data={pageSizeOptions.map((v) => String(v))}
|
|
||||||
allowDeselect={false}
|
|
||||||
onChange={(value) => {
|
|
||||||
const next = Number(value)
|
|
||||||
if (!Number.isFinite(next)) return
|
|
||||||
setPageSize(next)
|
|
||||||
setPage(1)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Group>
|
|
||||||
<Pagination value={page} onChange={setPage} total={totalPages} />
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
)
|
)
|
||||||
|
|||||||
41
app/management/person/dashboard/components/util.ts
Normal file
41
app/management/person/dashboard/components/util.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { platform } from "@tauri-apps/plugin-os"
|
||||||
|
import { Command } from "@tauri-apps/plugin-shell"
|
||||||
|
|
||||||
|
export const runCommand = async (
|
||||||
|
taskId: string,
|
||||||
|
name: string,
|
||||||
|
password: string
|
||||||
|
) => {
|
||||||
|
const platformName = platform()
|
||||||
|
const cmdStr = /^win/i.test(platformName)
|
||||||
|
? "labeltool_windows"
|
||||||
|
: "labeltool_linux"
|
||||||
|
|
||||||
|
let dStr = process.env.NEXT_PUBLIC_URL || ""
|
||||||
|
|
||||||
|
const command = Command.create(cmdStr, [
|
||||||
|
"--t",
|
||||||
|
taskId,
|
||||||
|
"--u",
|
||||||
|
name,
|
||||||
|
"--p",
|
||||||
|
password,
|
||||||
|
"--d",
|
||||||
|
dStr,
|
||||||
|
])
|
||||||
|
// command.on("close", (data) => {
|
||||||
|
// console.log(
|
||||||
|
// `command finished with code ${data.code} and signal ${data.signal}`
|
||||||
|
// );
|
||||||
|
// });
|
||||||
|
// command.on("error", (error) => console.error(`command error: "${error}"`));
|
||||||
|
// command.stdout.on("data", (line) =>
|
||||||
|
// console.log(`command stdout: "${line}"`)
|
||||||
|
// );
|
||||||
|
// command.stderr.on("data", (line) =>
|
||||||
|
// console.log(`command stderr: "${line}"`)
|
||||||
|
// );
|
||||||
|
|
||||||
|
await command.execute()
|
||||||
|
// console.log("pid:", child);
|
||||||
|
}
|
||||||
@@ -98,7 +98,7 @@ export const getUserTaskList = (params: {
|
|||||||
page_size: number
|
page_size: number
|
||||||
page_number: number
|
page_number: number
|
||||||
}) => {
|
}) => {
|
||||||
return httpFetch<{ simple_task_list: any[]; total_items: number }>({
|
return httpFetch<Task.ResGetUserTaskList>({
|
||||||
url: BASE_LABEL_API + `/api/v1/label_server/task/list_by_user`,
|
url: BASE_LABEL_API + `/api/v1/label_server/task/list_by_user`,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
data: params,
|
data: params,
|
||||||
|
|||||||
@@ -156,4 +156,22 @@ export namespace Task {
|
|||||||
work_time: number
|
work_time: number
|
||||||
comment_question_size?: number
|
comment_question_size?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ResGetUserTaskList {
|
||||||
|
simple_task_list: SimpleTaskItem[]
|
||||||
|
total_items: number
|
||||||
|
total_pages: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SimpleTaskItem {
|
||||||
|
id: number
|
||||||
|
label_status: number
|
||||||
|
label_type: number
|
||||||
|
label_username?: string
|
||||||
|
project_id: number
|
||||||
|
project_name: string
|
||||||
|
rejected: boolean
|
||||||
|
review1_username?: string
|
||||||
|
review2_username?: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
"@monaco-editor/react": "^4.7.0",
|
"@monaco-editor/react": "^4.7.0",
|
||||||
"@tabler/icons-react": "^3.35.0",
|
"@tabler/icons-react": "^3.35.0",
|
||||||
"@tauri-apps/api": "^2.9.1",
|
"@tauri-apps/api": "^2.9.1",
|
||||||
|
"@tauri-apps/plugin-os": "^2.3.2",
|
||||||
|
"@tauri-apps/plugin-shell": "^2.3.4",
|
||||||
"@tiptap/extension-image": "^3.15.3",
|
"@tiptap/extension-image": "^3.15.3",
|
||||||
"@tiptap/extension-link": "^3.15.3",
|
"@tiptap/extension-link": "^3.15.3",
|
||||||
"@tiptap/extension-placeholder": "^3.15.3",
|
"@tiptap/extension-placeholder": "^3.15.3",
|
||||||
|
|||||||
Reference in New Issue
Block a user