"use client" import { getUserTaskList } from "@/components/label/api/task" import { Task } from "@/components/label/api/task/typing" import { useBackUrlStore, usePermissionStore, } from "@/components/label/store/auth" import { TaskStatusEnum } from "@/components/label/utils/constants" import { Badge, Button, Group, Modal, Stack, Text, TextInput, UnstyledButton, } from "@mantine/core" import { notifications } from "@mantine/notifications" import { IconRefresh } from "@tabler/icons-react" import { DataTable, DataTableColumn } from "mantine-datatable" import { useCallback, useEffect, useMemo, useState } from "react" function getStatusColor(status?: number | null) { switch (status) { case 2: return "blue" case 4: return "yellow" case 6: return "orange" case 7: return "green" case 8: return "red" default: return "gray" } } const DEFAULT_RECORDS_PER_PAGE_OPTIONS = [10, 15, 20, 50] 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(50) const [recordsPerPageOptions, setRecordsPerPageOptions] = useState( () => [...DEFAULT_RECORDS_PER_PAGE_OPTIONS] ) const [customPageSizeInput, setCustomPageSizeInput] = useState("") const [customPageSizeModalOpened, setCustomPageSizeModalOpened] = useState(false) const [totalItems, setTotalItems] = useState(0) const [records, setRecords] = useState([]) const [loading, setLoading] = useState(false) 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, }) setRecords(res?.simple_task_list ?? []) setTotalItems(res?.total_items ?? 0) } finally { setLoading(false) } }, [page, pageSize, 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(0) const openCustomPageSizeModal = useCallback(() => { setCustomPageSizeModalOpened(true) }, []) const closeCustomPageSizeModal = useCallback(() => { setCustomPageSizeModalOpened(false) setCustomPageSizeInput("") }, []) const handleAddCustomPageSize = useCallback(() => { const rawValue = customPageSizeInput.trim() if (!rawValue) return const size = Number(rawValue) if (!Number.isInteger(size) || size <= 0) { notifications.show({ color: "red", title: "输入无效", message: "请填写大于 0 的整数条数", }) return } if (recordsPerPageOptions.includes(size)) { notifications.show({ color: "blue", title: "已存在", message: `每页 ${size} 条已在可选项中`, }) return } setRecordsPerPageOptions((prev) => [...prev, size].sort((a, b) => a - b)) closeCustomPageSizeModal() notifications.show({ color: "green", title: "添加成功", message: `已新增每页 ${size} 条`, }) }, [closeCustomPageSizeModal, customPageSizeInput, recordsPerPageOptions]) const handleCustomPageSizeEnter = useCallback( (event: React.KeyboardEvent) => { if (event.key !== "Enter") return event.preventDefault() handleAddCustomPageSize() }, [handleAddCustomPageSize] ) const originColumn = useMemo(() => { let column: DataTableColumn[] = [ { accessor: "project_name", title: "项目名称", width: 160, render: (record: Task.SimpleTaskItem) => { return ( {record.project_name ?? "-"} ) }, }, { accessor: "id", title: "任务ID", width: 150, render: (record: Task.SimpleTaskItem) => { return ( { setCurrentRowId(record.id) if ([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 { // 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} ) }, }, { accessor: "label_object_size.object_size", title: "对象数", width: 80, render: (record: Task.SimpleTaskItem) => { return <>{record.label_object_size?.object_size || "-"} }, }, { accessor: "label_status", title: "状态", width: 80, render: (record: Task.SimpleTaskItem) => { return ( {TaskStatusEnum.get(record.label_status)} ) }, }, { accessor: "label_username", title: "标注员", width: 80, }, { accessor: "review1_username", title: "审核员", width: 80, }, { accessor: "review2_username", title: "复审员", width: 80, }, ] return column }, [setBackProps]) return ( 我的任务 width="100%" style={{ width: "100%" }} styles={{ header: { color: "var(--mantine-color-grey-text)", backgroundColor: "var(--mantine-datatable-striped-color)", }, }} withTableBorder withRowBorders pinFirstColumn pinLastColumn rowBackgroundColor={({ id }) => { if (id === currentRowId) return "var(--mantine-datatable-highlight-on-hover-color-light, var(--mantine-datatable-highlight-on-hover-color))" }} scrollAreaProps={{ type: "auto" }} records={records} onRecordsPerPageChange={setPageSize} recordsPerPageOptions={recordsPerPageOptions} columns={originColumn} totalRecords={totalItems} recordsPerPage={pageSize} page={page} onPageChange={setPage} noRecordsText="暂无数据" recordsPerPageLabel="当前页数" renderPagination={({ Controls }) => ( )} /> setCustomPageSizeInput(event.currentTarget.value) } onKeyDown={handleCustomPageSizeEnter} /> ) }