307 lines
9.4 KiB
TypeScript
307 lines
9.4 KiB
TypeScript
"use client"
|
|
|
|
import { getUserTaskList } from "@/components/label/api/task"
|
|
import { Task } from "@/components/label/api/task/typing"
|
|
import TaskStatusTag from "@/components/label/components/TaskStatusTag"
|
|
import {
|
|
useBackUrlStore,
|
|
usePermissionStore,
|
|
} from "@/components/label/store/auth"
|
|
import {
|
|
SettingCustomPageSizeControl,
|
|
SettingDataTable,
|
|
SettingHeaderActions,
|
|
SettingListHeader,
|
|
usePersistentPageSizeOptions,
|
|
} from "@/components/setting/PageSurface"
|
|
import {
|
|
getPersistedPageSizeOptions,
|
|
resolvePageSizeWithinOptions,
|
|
} from "@/components/setting/pageSize"
|
|
import {
|
|
Button,
|
|
Group,
|
|
Select,
|
|
Stack,
|
|
Text,
|
|
UnstyledButton,
|
|
} from "@mantine/core"
|
|
import { IconRefresh } from "@tabler/icons-react"
|
|
import { DataTableColumn } from "mantine-datatable"
|
|
import { useCallback, useEffect, useMemo, useState } from "react"
|
|
import classes from "../page.module.css"
|
|
|
|
const DEFAULT_RECORDS_PER_PAGE_OPTIONS = [10, 15, 20, 50]
|
|
const REJECTED_FILTER_OPTIONS = [
|
|
{ value: "all", label: "全部" },
|
|
{ value: "true", label: "是" },
|
|
{ value: "false", label: "否" },
|
|
] as const
|
|
|
|
type RejectedFilterValue = (typeof REJECTED_FILTER_OPTIONS)[number]["value"]
|
|
|
|
export default function PersonalTaskTable() {
|
|
const user_name = usePermissionStore((s) => s.user_name)
|
|
const setBackProps = useBackUrlStore((s) => s.setBackProps)
|
|
|
|
const [page, setPage] = useState(1)
|
|
const [pageSize, setPageSize] = useState(() =>
|
|
resolvePageSizeWithinOptions(
|
|
10,
|
|
getPersistedPageSizeOptions(DEFAULT_RECORDS_PER_PAGE_OPTIONS),
|
|
10
|
|
)
|
|
)
|
|
const {
|
|
recordsPerPageOptions,
|
|
addCustomPageSize,
|
|
clearCustomPageSizeCache,
|
|
hasCustomPageSizeCache,
|
|
} = usePersistentPageSizeOptions(DEFAULT_RECORDS_PER_PAGE_OPTIONS, pageSize)
|
|
const [totalItems, setTotalItems] = useState(0)
|
|
const [records, setRecords] = useState<Task.SimpleTaskItem[]>([])
|
|
const [loading, setLoading] = useState(false)
|
|
const [rejectedFilter, setRejectedFilter] =
|
|
useState<RejectedFilterValue>("all")
|
|
|
|
const totalPages = useMemo(() => {
|
|
return Math.max(1, Math.ceil(totalItems / pageSize))
|
|
}, [pageSize, totalItems])
|
|
|
|
const load = useCallback(async () => {
|
|
if (!user_name) return
|
|
setLoading(true)
|
|
try {
|
|
const res = await getUserTaskList({
|
|
page_number: page,
|
|
page_size: pageSize,
|
|
rejected:
|
|
rejectedFilter === "all" ? undefined : rejectedFilter === "true",
|
|
})
|
|
setRecords(res?.simple_task_list ?? [])
|
|
setTotalItems(res?.total_items ?? 0)
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}, [page, pageSize, rejectedFilter, user_name])
|
|
|
|
useEffect(() => {
|
|
load()
|
|
}, [load])
|
|
|
|
useEffect(() => {
|
|
if (page > totalPages) setPage(totalPages)
|
|
}, [page, totalPages])
|
|
|
|
const resetData = () => {
|
|
if (page === 1) load()
|
|
else setPage(1)
|
|
}
|
|
|
|
const [currentRowId, setCurrentRowId] = useState<number>(0)
|
|
|
|
const originColumn = useMemo(() => {
|
|
let column: DataTableColumn<Task.SimpleTaskItem>[] = [
|
|
{
|
|
accessor: "project_name",
|
|
title: "项目名称",
|
|
width: 160,
|
|
render: (record: Task.SimpleTaskItem) => {
|
|
return (
|
|
<Text
|
|
title={record.project_name ?? "-"}
|
|
className={classes.ellipsisText}>
|
|
{record.project_name ?? "-"}
|
|
</Text>
|
|
)
|
|
},
|
|
},
|
|
{
|
|
accessor: "id",
|
|
title: "任务ID",
|
|
width: 150,
|
|
render: (record: Task.SimpleTaskItem) => {
|
|
return (
|
|
<UnstyledButton
|
|
onClick={async () => {
|
|
setCurrentRowId(record.id)
|
|
if ([1, 2, 4, 5, 6, 7].includes(record.label_type)) {
|
|
setBackProps(`/person/dashboard`)
|
|
if ([4, 5, 6].includes(record.label_type)) {
|
|
// router.replace(
|
|
// `/image/label?project_id=${record.project_id}&task_id=${record.id}`
|
|
// )
|
|
window.location.href = `/image/label?project_id=${record.project_id}&task_id=${record.id}`
|
|
} else if ([7].includes(record.label_type)) {
|
|
// router.replace(
|
|
// `/video/label?project_id=${record.project_id}&task_id=${record.id}`
|
|
// )
|
|
window.location.href = `/video/label?project_id=${record.project_id}&task_id=${record.id}`
|
|
} else if ([1, 2].includes(record.label_type)) {
|
|
window.location.href = `/lidar/lidar-point?project_id=${record.project_id}&task_id=${record.id}`
|
|
}
|
|
} else {
|
|
// await runCommand(
|
|
// record.id.toString(),
|
|
// user_name,
|
|
// user_password
|
|
// )
|
|
}
|
|
}}
|
|
title={record.id.toString()}
|
|
className={classes.tableLink}>
|
|
{record.id}
|
|
</UnstyledButton>
|
|
)
|
|
},
|
|
},
|
|
{
|
|
accessor: "label_object_size.object_size",
|
|
title: "对象数",
|
|
width: 80,
|
|
render: (record: Task.SimpleTaskItem) => {
|
|
return (
|
|
<Text className={classes.tableCellText}>
|
|
{record.label_object_size?.object_size || "-"}
|
|
</Text>
|
|
)
|
|
},
|
|
},
|
|
{
|
|
accessor: "label_status",
|
|
title: "状态",
|
|
width: 160,
|
|
render: (record) => (
|
|
<TaskStatusTag
|
|
status={record.label_status}
|
|
rejected={record.rejected}
|
|
/>
|
|
),
|
|
},
|
|
{
|
|
accessor: "label_username",
|
|
title: "标注员",
|
|
width: 80,
|
|
render: (record: Task.SimpleTaskItem) => (
|
|
<Text className={classes.tableCellText}>
|
|
{record.label_username || "-"}
|
|
</Text>
|
|
),
|
|
},
|
|
{
|
|
accessor: "review1_username",
|
|
title: "审核员",
|
|
width: 80,
|
|
render: (record: Task.SimpleTaskItem) => (
|
|
<Text className={classes.tableCellText}>
|
|
{record.review1_username || "-"}
|
|
</Text>
|
|
),
|
|
},
|
|
{
|
|
accessor: "review2_username",
|
|
title: "复审员",
|
|
width: 80,
|
|
render: (record: Task.SimpleTaskItem) => (
|
|
<Text className={classes.tableCellText}>
|
|
{record.review2_username || "-"}
|
|
</Text>
|
|
),
|
|
},
|
|
]
|
|
return column
|
|
}, [setBackProps])
|
|
|
|
return (
|
|
<Stack className={classes.dashboardSection}>
|
|
<SettingListHeader
|
|
title="我的任务"
|
|
count={
|
|
<Group gap="sm" align="center" wrap="wrap">
|
|
<Text span inherit>
|
|
共 {totalItems} 条记录
|
|
</Text>
|
|
<Group gap={6} align="center" wrap="wrap">
|
|
<Text span inherit>
|
|
是否返工
|
|
</Text>
|
|
<Select
|
|
data={REJECTED_FILTER_OPTIONS}
|
|
value={rejectedFilter}
|
|
onChange={(value) => {
|
|
if (!value) return
|
|
setRejectedFilter(value as RejectedFilterValue)
|
|
setPage(1)
|
|
}}
|
|
allowDeselect={false}
|
|
checkIconPosition="right"
|
|
size="xs"
|
|
w={112}
|
|
className={classes.dashboardHeaderSelect}
|
|
/>
|
|
</Group>
|
|
</Group>
|
|
}
|
|
actions={
|
|
<SettingHeaderActions>
|
|
<Button
|
|
variant="default"
|
|
onClick={resetData}
|
|
disabled={loading}
|
|
leftSection={<IconRefresh size={16} />}>
|
|
刷新
|
|
</Button>
|
|
</SettingHeaderActions>
|
|
}
|
|
/>
|
|
<div className={classes.dashboardTableArea}>
|
|
<SettingDataTable<Task.SimpleTaskItem>
|
|
width="100%"
|
|
minHeight={0}
|
|
style={{ width: "100%", flex: 1 }}
|
|
pinFirstColumn
|
|
fetching={loading}
|
|
rowBackgroundColor={({ id }) => {
|
|
if (id === currentRowId) return "#F7FBFF"
|
|
}}
|
|
scrollAreaProps={{ type: "auto" }}
|
|
records={records}
|
|
onRecordsPerPageChange={setPageSize}
|
|
recordsPerPageOptions={recordsPerPageOptions}
|
|
columns={originColumn}
|
|
totalRecords={totalItems}
|
|
recordsPerPage={pageSize}
|
|
page={page}
|
|
onPageChange={setPage}
|
|
noRecordsText="暂无数据"
|
|
recordsPerPageLabel="每页条数"
|
|
paginationText={({ from, to, totalRecords }) =>
|
|
`显示 ${from}-${to} 条,共 ${totalRecords} 条记录`
|
|
}
|
|
renderPagination={({ Controls }) => (
|
|
<Group
|
|
justify="space-between"
|
|
align="center"
|
|
w="100%"
|
|
gap="sm"
|
|
wrap="wrap">
|
|
<Group gap="xs" align="center" wrap="wrap">
|
|
<Controls.Text />
|
|
<Controls.PageSizeSelector />
|
|
<SettingCustomPageSizeControl
|
|
addCustomPageSize={addCustomPageSize}
|
|
clearCustomPageSizeCache={clearCustomPageSizeCache}
|
|
hasCustomPageSizeCache={hasCustomPageSizeCache}
|
|
triggerButtonProps={{ variant: "default", size: "sm" }}
|
|
confirmButtonProps={{ color: "#1874ff" }}
|
|
/>
|
|
</Group>
|
|
<Controls.Pagination />
|
|
</Group>
|
|
)}
|
|
/>
|
|
</div>
|
|
</Stack>
|
|
)
|
|
}
|