feat(task): add filters
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import "@mantine/core/styles.css"
|
import "@mantine/core/styles.css"
|
||||||
import "@mantine/core/styles.layer.css"
|
import "@mantine/core/styles.layer.css"
|
||||||
|
import "@mantine/dates/styles.css"
|
||||||
import "@mantine/notifications/styles.css"
|
import "@mantine/notifications/styles.css"
|
||||||
import "mantine-datatable/styles.css"
|
import "mantine-datatable/styles.css"
|
||||||
import Script from "next/script"
|
import Script from "next/script"
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
TextInput,
|
TextInput,
|
||||||
} from "@mantine/core"
|
} from "@mantine/core"
|
||||||
|
import { DatePickerInput, type DatesRangeValue } from "@mantine/dates"
|
||||||
import { modals } from "@mantine/modals"
|
import { modals } from "@mantine/modals"
|
||||||
import { notifications } from "@mantine/notifications"
|
import { notifications } from "@mantine/notifications"
|
||||||
import {
|
import {
|
||||||
@@ -41,8 +42,9 @@ import {
|
|||||||
IconSearch,
|
IconSearch,
|
||||||
} from "@tabler/icons-react"
|
} from "@tabler/icons-react"
|
||||||
import dayjs from "dayjs"
|
import dayjs from "dayjs"
|
||||||
|
import "dayjs/locale/zh-cn"
|
||||||
import duration from "dayjs/plugin/duration"
|
import duration from "dayjs/plugin/duration"
|
||||||
import { DataTableColumn } from "mantine-datatable"
|
import { DataTableColumn, type DataTableSortStatus } from "mantine-datatable"
|
||||||
import { useRouter, useSearchParams } from "next/navigation"
|
import { useRouter, useSearchParams } from "next/navigation"
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react"
|
import { useCallback, useEffect, useMemo, useState } from "react"
|
||||||
import * as XLSX from "xlsx-js-style"
|
import * as XLSX from "xlsx-js-style"
|
||||||
@@ -60,6 +62,8 @@ interface FilterFormRecord {
|
|||||||
label_user: string[]
|
label_user: string[]
|
||||||
review_user1: string[]
|
review_user1: string[]
|
||||||
review_user2: string[]
|
review_user2: string[]
|
||||||
|
first_commit_label_time: DatesRangeValue
|
||||||
|
first_commit_review1_time: DatesRangeValue
|
||||||
}
|
}
|
||||||
|
|
||||||
function createInitialFilters(): FilterFormRecord {
|
function createInitialFilters(): FilterFormRecord {
|
||||||
@@ -71,10 +75,52 @@ function createInitialFilters(): FilterFormRecord {
|
|||||||
label_user: [],
|
label_user: [],
|
||||||
review_user1: [],
|
review_user1: [],
|
||||||
review_user2: [],
|
review_user2: [],
|
||||||
|
first_commit_label_time: [null, null],
|
||||||
|
first_commit_review1_time: [null, null],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_RECORDS_PER_PAGE_OPTIONS = [10, 15, 20]
|
const DEFAULT_RECORDS_PER_PAGE_OPTIONS = [10, 15, 20]
|
||||||
|
const INITIAL_SORT_ACCESSOR = "__initial__"
|
||||||
|
|
||||||
|
type SortableTaskSizeAccessor = keyof Task.SizeProps
|
||||||
|
|
||||||
|
const SORTABLE_TASK_SIZE_COLUMNS: Array<{
|
||||||
|
accessor: SortableTaskSizeAccessor
|
||||||
|
title: string
|
||||||
|
width: number
|
||||||
|
}> = [
|
||||||
|
{ accessor: "object_size", title: "对象总数", width: 110 },
|
||||||
|
{ accessor: "valid_size", title: "有效对象数", width: 120 },
|
||||||
|
{ accessor: "new_size", title: "新增对象数", width: 120 },
|
||||||
|
{ accessor: "key_frame_size", title: "关键帧数", width: 120 },
|
||||||
|
{ accessor: "dynamic_size", title: "动态对象数", width: 120 },
|
||||||
|
{ accessor: "static_size", title: "静态对象数", width: 120 },
|
||||||
|
{ accessor: "prelabel_size", title: "预标注对象数", width: 120 },
|
||||||
|
{ accessor: "prelabel_modify_size", title: "预标注对象修改数", width: 160 },
|
||||||
|
{ accessor: "question_size", title: "问题数", width: 120 },
|
||||||
|
{ accessor: "total_qa_group_size", title: "总问答组数", width: 120 },
|
||||||
|
{ accessor: "single_qa_group_size", title: "单轮问答组数", width: 120 },
|
||||||
|
{ accessor: "multiple_qa_group_size", title: "多轮问答组数", width: 120 },
|
||||||
|
{ accessor: "new_qa_group_size", title: "新增问答组数", width: 120 },
|
||||||
|
{
|
||||||
|
accessor: "new_single_qa_group_size",
|
||||||
|
title: "新增单轮问答组数",
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: "new_multiple_qa_group_size",
|
||||||
|
title: "新增多轮问答组数",
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
{ accessor: "review_question_size", title: "审核问题数", width: 120 },
|
||||||
|
{ accessor: "comment_question_size", title: "首次批注问题数", width: 140 },
|
||||||
|
{ accessor: "review_size", title: "审核对象数", width: 120 },
|
||||||
|
{ accessor: "review_dynamic_size", title: "审核动态对象数", width: 140 },
|
||||||
|
{ accessor: "review_static_size", title: "审核静态对象数", width: 140 },
|
||||||
|
{ accessor: "first_comment_size", title: "批注数(1)", width: 120 },
|
||||||
|
{ accessor: "second_comment_size", title: "批注数(2)", width: 120 },
|
||||||
|
]
|
||||||
|
|
||||||
export interface selectedDataProps {
|
export interface selectedDataProps {
|
||||||
status: number
|
status: number
|
||||||
@@ -167,6 +213,12 @@ export default function TaskTableContainer(props: {
|
|||||||
const [selectedRecords, setSelectedRecords] = useState<Task.DataProps[]>([])
|
const [selectedRecords, setSelectedRecords] = useState<Task.DataProps[]>([])
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [queryTrigger, setQueryTrigger] = useState(0)
|
const [queryTrigger, setQueryTrigger] = useState(0)
|
||||||
|
const [sortStatus, setSortStatus] = useState<
|
||||||
|
DataTableSortStatus<Task.DataProps>
|
||||||
|
>({
|
||||||
|
columnAccessor: INITIAL_SORT_ACCESSOR,
|
||||||
|
direction: "asc",
|
||||||
|
})
|
||||||
|
|
||||||
const [workflowTaskId, setWorkflowTaskId] = useState<number | null>(null)
|
const [workflowTaskId, setWorkflowTaskId] = useState<number | null>(null)
|
||||||
const [dispatchRecordModal, setDispatchModalConfig] = useState<{
|
const [dispatchRecordModal, setDispatchModalConfig] = useState<{
|
||||||
@@ -223,9 +275,33 @@ export default function TaskTableContainer(props: {
|
|||||||
if (form.review_user2?.length) {
|
if (form.review_user2?.length) {
|
||||||
obj.review_user2 = form.review_user2?.map((item) => Number(item))
|
obj.review_user2 = form.review_user2?.map((item) => Number(item))
|
||||||
}
|
}
|
||||||
|
if (form.first_commit_label_time[0] && form.first_commit_label_time[1]) {
|
||||||
|
obj.first_commit_label_time_start = dayjs(
|
||||||
|
form.first_commit_label_time[0]
|
||||||
|
).format("YYYY-MM-DD")
|
||||||
|
obj.first_commit_label_time_end = dayjs(
|
||||||
|
form.first_commit_label_time[1]
|
||||||
|
).format("YYYY-MM-DD")
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
form.first_commit_review1_time[0] &&
|
||||||
|
form.first_commit_review1_time[1]
|
||||||
|
) {
|
||||||
|
obj.first_commit_review1_time_start = dayjs(
|
||||||
|
form.first_commit_review1_time[0]
|
||||||
|
).format("YYYY-MM-DD")
|
||||||
|
obj.first_commit_review1_time_end = dayjs(
|
||||||
|
form.first_commit_review1_time[1]
|
||||||
|
).format("YYYY-MM-DD")
|
||||||
|
}
|
||||||
|
if (sortStatus.columnAccessor !== INITIAL_SORT_ACCESSOR) {
|
||||||
|
obj.order_by = `${sortStatus.columnAccessor} ${sortStatus.direction}`
|
||||||
|
}
|
||||||
return obj
|
return obj
|
||||||
}, [
|
}, [
|
||||||
form.current_uid,
|
form.current_uid,
|
||||||
|
form.first_commit_label_time,
|
||||||
|
form.first_commit_review1_time,
|
||||||
form.label_user,
|
form.label_user,
|
||||||
form.rejected,
|
form.rejected,
|
||||||
form.review_user1,
|
form.review_user1,
|
||||||
@@ -235,6 +311,8 @@ export default function TaskTableContainer(props: {
|
|||||||
pageNumber,
|
pageNumber,
|
||||||
pageSize,
|
pageSize,
|
||||||
projectId,
|
projectId,
|
||||||
|
sortStatus.columnAccessor,
|
||||||
|
sortStatus.direction,
|
||||||
])
|
])
|
||||||
|
|
||||||
const load = useCallback(async () => {
|
const load = useCallback(async () => {
|
||||||
@@ -528,6 +606,22 @@ export default function TaskTableContainer(props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const columns = useMemo(() => {
|
const columns = useMemo(() => {
|
||||||
|
const createSortableSizeColumn = ({
|
||||||
|
accessor,
|
||||||
|
title,
|
||||||
|
width,
|
||||||
|
}: {
|
||||||
|
accessor: SortableTaskSizeAccessor
|
||||||
|
title: string
|
||||||
|
width: number
|
||||||
|
}): DataTableColumn<Task.DataProps> => ({
|
||||||
|
accessor,
|
||||||
|
title,
|
||||||
|
width,
|
||||||
|
sortable: true,
|
||||||
|
render: (record) => record.label_object_size?.[accessor] ?? "-",
|
||||||
|
})
|
||||||
|
|
||||||
const cols: DataTableColumn<Task.DataProps>[] = [
|
const cols: DataTableColumn<Task.DataProps>[] = [
|
||||||
{
|
{
|
||||||
accessor: "id",
|
accessor: "id",
|
||||||
@@ -595,148 +689,7 @@ export default function TaskTableContainer(props: {
|
|||||||
width: 120,
|
width: 120,
|
||||||
render: (record) => record.review2_username ?? "-",
|
render: (record) => record.review2_username ?? "-",
|
||||||
},
|
},
|
||||||
{
|
...SORTABLE_TASK_SIZE_COLUMNS.map(createSortableSizeColumn),
|
||||||
accessor: "label_object_size.object_size",
|
|
||||||
title: "对象总数",
|
|
||||||
width: 110,
|
|
||||||
render: (record) => record.label_object_size?.object_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.valid_size",
|
|
||||||
title: "有效对象数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) => record.label_object_size?.valid_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.new_size",
|
|
||||||
title: "新增对象数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) => record.label_object_size?.new_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.key_frame_size",
|
|
||||||
title: "关键帧数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) => record.label_object_size?.key_frame_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.dynamic_size",
|
|
||||||
title: "动态对象数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) => record.label_object_size?.dynamic_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.static_size",
|
|
||||||
title: "静态对象数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) => record.label_object_size?.static_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.prelabel_size",
|
|
||||||
title: "预标注对象数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) => record.label_object_size?.prelabel_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.prelabel_modify_size",
|
|
||||||
title: "预标注对象修改数",
|
|
||||||
width: 160,
|
|
||||||
render: (record) =>
|
|
||||||
record.label_object_size?.prelabel_modify_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.question_size",
|
|
||||||
title: "问题数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) => record.label_object_size?.question_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.total_qa_group_size",
|
|
||||||
title: "总问答组数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) =>
|
|
||||||
record.label_object_size?.total_qa_group_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.single_qa_group_size",
|
|
||||||
title: "单轮问答组数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) =>
|
|
||||||
record.label_object_size?.single_qa_group_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.multiple_qa_group_size",
|
|
||||||
title: "多轮问答组数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) =>
|
|
||||||
record.label_object_size?.multiple_qa_group_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.new_qa_group_size",
|
|
||||||
title: "新增问答组数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) => record.label_object_size?.new_qa_group_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.new_single_qa_group_size",
|
|
||||||
title: "新增单轮问答组数",
|
|
||||||
width: 160,
|
|
||||||
render: (record) =>
|
|
||||||
record.label_object_size?.new_single_qa_group_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.new_multiple_qa_group_size",
|
|
||||||
title: "新增多轮问答组数",
|
|
||||||
width: 160,
|
|
||||||
render: (record) =>
|
|
||||||
record.label_object_size?.new_multiple_qa_group_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.review_question_size",
|
|
||||||
title: "审核问题数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) =>
|
|
||||||
record.label_object_size?.review_question_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.comment_question_size",
|
|
||||||
title: "首次批注问题数",
|
|
||||||
width: 140,
|
|
||||||
render: (record) =>
|
|
||||||
record.label_object_size?.comment_question_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.review_size",
|
|
||||||
title: "审核对象数",
|
|
||||||
width: 120,
|
|
||||||
render: (record) => record.label_object_size?.review_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.review_dynamic_size",
|
|
||||||
title: "审核动态对象数",
|
|
||||||
width: 140,
|
|
||||||
render: (record) =>
|
|
||||||
record.label_object_size?.review_dynamic_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.review_static_size",
|
|
||||||
title: "审核静态对象数",
|
|
||||||
width: 140,
|
|
||||||
render: (record) => record.label_object_size?.review_static_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.first_comment_size",
|
|
||||||
title: "批注数(1)",
|
|
||||||
width: 120,
|
|
||||||
render: (record) => record.label_object_size?.first_comment_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessor: "label_object_size.second_comment_size",
|
|
||||||
title: "批注数(2)",
|
|
||||||
width: 120,
|
|
||||||
render: (record) =>
|
|
||||||
record.label_object_size?.second_comment_size ?? "-",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
accessor: "first_commit_label_time",
|
accessor: "first_commit_label_time",
|
||||||
title: "标注首次提交时间",
|
title: "标注首次提交时间",
|
||||||
@@ -966,6 +919,36 @@ export default function TaskTableContainer(props: {
|
|||||||
setFilters((s) => ({ ...s, review_user2: v }))
|
setFilters((s) => ({ ...s, review_user2: v }))
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<DatePickerInput
|
||||||
|
type="range"
|
||||||
|
label="标注首次提交时间"
|
||||||
|
placeholder="请选择时间范围"
|
||||||
|
valueFormat="YYYY-MM-DD"
|
||||||
|
locale="zh-cn"
|
||||||
|
clearable
|
||||||
|
value={filters.first_commit_label_time}
|
||||||
|
onChange={(value: DatesRangeValue) =>
|
||||||
|
setFilters((s) => ({
|
||||||
|
...s,
|
||||||
|
first_commit_label_time: value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<DatePickerInput
|
||||||
|
type="range"
|
||||||
|
label="审核首次提交时间"
|
||||||
|
placeholder="请选择时间范围"
|
||||||
|
valueFormat="YYYY-MM-DD"
|
||||||
|
locale="zh-cn"
|
||||||
|
clearable
|
||||||
|
value={filters.first_commit_review1_time}
|
||||||
|
onChange={(value: DatesRangeValue) =>
|
||||||
|
setFilters((s) => ({
|
||||||
|
...s,
|
||||||
|
first_commit_review1_time: value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
/>
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
@@ -1038,6 +1021,13 @@ export default function TaskTableContainer(props: {
|
|||||||
fetching={loading}
|
fetching={loading}
|
||||||
records={records}
|
records={records}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
sortStatus={sortStatus}
|
||||||
|
onSortStatusChange={(
|
||||||
|
nextSortStatus: DataTableSortStatus<Task.DataProps>
|
||||||
|
) => {
|
||||||
|
setPageNumber(1)
|
||||||
|
setSortStatus(nextSortStatus)
|
||||||
|
}}
|
||||||
totalRecords={total}
|
totalRecords={total}
|
||||||
recordsPerPage={pageSize}
|
recordsPerPage={pageSize}
|
||||||
page={pageNumber}
|
page={pageNumber}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export namespace Task {
|
export namespace Task {
|
||||||
export interface DataProps {
|
export interface DataProps {
|
||||||
|
[key: string]: unknown
|
||||||
id: number
|
id: number
|
||||||
create_date: string
|
create_date: string
|
||||||
data_type?: number
|
data_type?: number
|
||||||
@@ -74,6 +75,7 @@ export namespace Task {
|
|||||||
id?: number[]
|
id?: number[]
|
||||||
label_status?: number[]
|
label_status?: number[]
|
||||||
label_user?: number[]
|
label_user?: number[]
|
||||||
|
// sample: object_size asc/object_size desc
|
||||||
order_by?: string
|
order_by?: string
|
||||||
page_number: number
|
page_number: number
|
||||||
page_size: number
|
page_size: number
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"@ffmpeg/util": "^0.12.2",
|
"@ffmpeg/util": "^0.12.2",
|
||||||
"@fingerprintjs/fingerprintjs": "^5.0.1",
|
"@fingerprintjs/fingerprintjs": "^5.0.1",
|
||||||
"@mantine/core": "^8.3.1",
|
"@mantine/core": "^8.3.1",
|
||||||
|
"@mantine/dates": "^8.3.18",
|
||||||
"@mantine/form": "^8.3.1",
|
"@mantine/form": "^8.3.1",
|
||||||
"@mantine/hooks": "^8.3.1",
|
"@mantine/hooks": "^8.3.1",
|
||||||
"@mantine/modals": "^8.3.10",
|
"@mantine/modals": "^8.3.10",
|
||||||
|
|||||||
Reference in New Issue
Block a user