fix(label): fix task tool
This commit is contained in:
@@ -25,6 +25,7 @@ import {
|
||||
import { useRouter } from "next/navigation"
|
||||
import { useCallback, useEffect, useMemo, useState } from "react"
|
||||
import { Project } from "../api/project/typing"
|
||||
import { Task } from "../api/task/typing"
|
||||
import { getTaskList } from "../api/task"
|
||||
import { useObjectStore } from "../store"
|
||||
import type { Option } from "../store/auth"
|
||||
@@ -38,11 +39,54 @@ interface RightTaskToolsComponentProps {
|
||||
task_id: number
|
||||
}
|
||||
|
||||
interface FilterOption {
|
||||
label: string
|
||||
value: string
|
||||
}
|
||||
|
||||
interface FilterOptions {
|
||||
all_user: Option[]
|
||||
label_user: Option[]
|
||||
review_user1: Option[]
|
||||
review_user2: Option[]
|
||||
all_user: FilterOption[]
|
||||
label_user: FilterOption[]
|
||||
review_user1: FilterOption[]
|
||||
review_user2: FilterOption[]
|
||||
}
|
||||
|
||||
interface FilterFormValues {
|
||||
label_status: string[]
|
||||
current_uid: string[]
|
||||
label_user: string[]
|
||||
review_user1: string[]
|
||||
review_user2: string[]
|
||||
rejected: string | null
|
||||
id: string
|
||||
}
|
||||
|
||||
type TaskListFilterParams = Partial<
|
||||
Pick<
|
||||
Task.ListRequest,
|
||||
| "label_status"
|
||||
| "current_uid"
|
||||
| "label_user"
|
||||
| "review_user1"
|
||||
| "review_user2"
|
||||
| "rejected"
|
||||
| "id"
|
||||
>
|
||||
>
|
||||
|
||||
const normalizeFilterOption = (option: Option): FilterOption | null => {
|
||||
if (option.value === null || option.value === undefined) return null
|
||||
|
||||
return {
|
||||
label: option.label,
|
||||
value: String(option.value),
|
||||
}
|
||||
}
|
||||
|
||||
const pushUniqueOption = (options: FilterOption[], option: FilterOption) => {
|
||||
if (!options.some((item) => item.value === option.value)) {
|
||||
options.push(option)
|
||||
}
|
||||
}
|
||||
|
||||
const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
@@ -57,11 +101,12 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
|
||||
const { userOpts } = useAllUserStore()
|
||||
|
||||
const [taskList, setTaskList] = useState<any[]>([])
|
||||
const [taskList, setTaskList] = useState<Task.DataProps[]>([])
|
||||
const [activePage, setPage] = useState(1)
|
||||
const [pageSize, setPageSize] = useState(20)
|
||||
const [filterOpened, setFilterOpened] = useState(false)
|
||||
|
||||
const filterForm = useForm({
|
||||
const filterForm = useForm<FilterFormValues>({
|
||||
initialValues: {
|
||||
label_status: [],
|
||||
current_uid: [],
|
||||
@@ -72,32 +117,25 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
id: "",
|
||||
},
|
||||
})
|
||||
const [filterParams, setFilterParams] = useState<any>({})
|
||||
const isParamsEmpty: boolean = JSON.stringify(filterParams) === "{}"
|
||||
const [filterParams, setFilterParams] = useState<TaskListFilterParams>({})
|
||||
const isParamsEmpty = Object.keys(filterParams).length === 0
|
||||
|
||||
const getListData = useCallback(async () => {
|
||||
let pg_num = 0,
|
||||
pg_size = 1000
|
||||
let total = 0
|
||||
let tasksCount = 1000000
|
||||
let finalData: any[] = []
|
||||
let tasksCount = Number.POSITIVE_INFINITY
|
||||
let finalData: Task.DataProps[] = []
|
||||
|
||||
while (total < tasksCount) {
|
||||
pg_num += 1
|
||||
const params = filterParams
|
||||
? {
|
||||
project_id: [projectId],
|
||||
get_data: true,
|
||||
page_number: pg_num,
|
||||
page_size: pg_size,
|
||||
...filterParams,
|
||||
}
|
||||
: {
|
||||
project_id: [projectId],
|
||||
get_data: true,
|
||||
page_number: pg_num,
|
||||
page_size: pg_size,
|
||||
}
|
||||
const params: Task.ListRequest = {
|
||||
project_id: [projectId],
|
||||
get_data: true,
|
||||
page_number: pg_num,
|
||||
page_size: pg_size,
|
||||
...filterParams,
|
||||
}
|
||||
const res = await getTaskList(params)
|
||||
const { total_items, task_list } = res
|
||||
finalData = [...finalData, ...task_list]
|
||||
@@ -112,6 +150,18 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
queueMicrotask(() => getListData())
|
||||
}, [getListData])
|
||||
|
||||
const normalizedUserOpts = useMemo(() => {
|
||||
return userOpts.reduce<FilterOption[]>((result, item) => {
|
||||
const normalizedOption = normalizeFilterOption(item)
|
||||
|
||||
if (normalizedOption) {
|
||||
result.push(normalizedOption)
|
||||
}
|
||||
|
||||
return result
|
||||
}, [])
|
||||
}, [userOpts])
|
||||
|
||||
const filterUserOpts = useMemo(() => {
|
||||
const opts: FilterOptions = {
|
||||
all_user: [],
|
||||
@@ -121,29 +171,33 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
}
|
||||
|
||||
if (!projectDetail) return opts
|
||||
const steps = projectDetail.label_process.step_detail
|
||||
const normalizedUserMap = new Map(
|
||||
normalizedUserOpts.map((item) => [item.value, item])
|
||||
)
|
||||
const steps = projectDetail.label_process.step_detail ?? []
|
||||
steps.forEach(({ action, user_list }) => {
|
||||
let users: any[] = []
|
||||
user_list.forEach((v) => {
|
||||
userOpts.forEach((item) => {
|
||||
if (item.value === v) {
|
||||
users.push(item)
|
||||
const flag = opts.all_user.find((u) => u.value === v)
|
||||
if (!flag) opts.all_user.push(item)
|
||||
}
|
||||
})
|
||||
const users: FilterOption[] = []
|
||||
|
||||
user_list.forEach((userId) => {
|
||||
const matchedUser = normalizedUserMap.get(String(userId))
|
||||
|
||||
if (!matchedUser) return
|
||||
|
||||
pushUniqueOption(users, matchedUser)
|
||||
pushUniqueOption(opts.all_user, matchedUser)
|
||||
})
|
||||
|
||||
if (action === 1) {
|
||||
opts.label_user.push(...users)
|
||||
users.forEach((user) => pushUniqueOption(opts.label_user, user))
|
||||
} else if (action === 2) {
|
||||
opts.review_user1.push(...users)
|
||||
users.forEach((user) => pushUniqueOption(opts.review_user1, user))
|
||||
} else if (action === 3) {
|
||||
opts.review_user2.push(...users)
|
||||
users.forEach((user) => pushUniqueOption(opts.review_user2, user))
|
||||
}
|
||||
})
|
||||
|
||||
return opts
|
||||
}, [projectDetail, userOpts])
|
||||
}, [normalizedUserOpts, projectDetail])
|
||||
|
||||
const handleTurnPrevious = () => {
|
||||
const index = taskList.findIndex((task) => task.id === taskId)
|
||||
@@ -185,12 +239,14 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
label: value,
|
||||
value: key,
|
||||
}))}
|
||||
comboboxProps={{ withinPortal: false }}
|
||||
{...filterForm.getInputProps("label_status")}
|
||||
clearable
|
||||
/>
|
||||
<MultiSelect
|
||||
label="当前负责人"
|
||||
data={filterUserOpts.all_user}
|
||||
comboboxProps={{ withinPortal: false }}
|
||||
{...filterForm.getInputProps("current_uid")}
|
||||
searchable
|
||||
clearable
|
||||
@@ -198,6 +254,7 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
<MultiSelect
|
||||
label="标注员"
|
||||
data={filterUserOpts.label_user}
|
||||
comboboxProps={{ withinPortal: false }}
|
||||
{...filterForm.getInputProps("label_user")}
|
||||
searchable
|
||||
clearable
|
||||
@@ -205,6 +262,7 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
<MultiSelect
|
||||
label="审核员"
|
||||
data={filterUserOpts.review_user1}
|
||||
comboboxProps={{ withinPortal: false }}
|
||||
{...filterForm.getInputProps("review_user1")}
|
||||
searchable
|
||||
clearable
|
||||
@@ -212,6 +270,7 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
<MultiSelect
|
||||
label="复审员"
|
||||
data={filterUserOpts.review_user2}
|
||||
comboboxProps={{ withinPortal: false }}
|
||||
{...filterForm.getInputProps("review_user2")}
|
||||
searchable
|
||||
clearable
|
||||
@@ -222,6 +281,7 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
{ label: "是", value: "1" },
|
||||
{ label: "否", value: "0" },
|
||||
]}
|
||||
comboboxProps={{ withinPortal: false }}
|
||||
{...filterForm.getInputProps("rejected")}
|
||||
clearable
|
||||
/>
|
||||
@@ -237,23 +297,36 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
filterForm.reset()
|
||||
setFilterParams({})
|
||||
setPage(1)
|
||||
setFilterOpened(false)
|
||||
}}>
|
||||
重置
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
const obj = filterForm.values
|
||||
const params: any = {}
|
||||
const params: TaskListFilterParams = {}
|
||||
if (obj.label_status?.length)
|
||||
params.label_status = obj.label_status.map(Number)
|
||||
if (obj.current_uid?.length) params.current_uid = obj.current_uid
|
||||
if (obj.label_user?.length) params.label_user = obj.label_user
|
||||
if (obj.review_user1?.length) params.review_user1 = obj.review_user1
|
||||
if (obj.review_user2?.length) params.review_user2 = obj.review_user2
|
||||
if (obj.rejected) params.rejected = Number(obj.rejected)
|
||||
if (obj.id) params.id = obj.id.trim()
|
||||
if (obj.current_uid?.length)
|
||||
params.current_uid = obj.current_uid.map(Number)
|
||||
if (obj.label_user?.length)
|
||||
params.label_user = obj.label_user.map(Number)
|
||||
if (obj.review_user1?.length)
|
||||
params.review_user1 = obj.review_user1.map(Number)
|
||||
if (obj.review_user2?.length)
|
||||
params.review_user2 = obj.review_user2.map(Number)
|
||||
if (obj.rejected !== null)
|
||||
params.rejected = Number(obj.rejected) === 1
|
||||
if (obj.id.trim()) {
|
||||
const taskId = Number(obj.id.trim())
|
||||
|
||||
if (Number.isFinite(taskId)) {
|
||||
params.id = [taskId]
|
||||
}
|
||||
}
|
||||
setFilterParams(params)
|
||||
setPage(1)
|
||||
setFilterOpened(false)
|
||||
}}>
|
||||
确定
|
||||
</Button>
|
||||
@@ -276,12 +349,18 @@ const RightTaskTools: React.FC<RightTaskToolsComponentProps> = (props) => {
|
||||
<IconChevronRight size={16} />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
<Popover position="bottom-end" withArrow shadow="md">
|
||||
<Popover
|
||||
position="bottom-end"
|
||||
withArrow
|
||||
shadow="md"
|
||||
opened={filterOpened}
|
||||
onChange={setFilterOpened}>
|
||||
<Popover.Target>
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
size="sm"
|
||||
color={!isParamsEmpty ? "blue" : "gray"}>
|
||||
color={!isParamsEmpty ? "blue" : "gray"}
|
||||
onClick={() => setFilterOpened((opened) => !opened)}>
|
||||
<IconFilter size={16} />
|
||||
</ActionIcon>
|
||||
</Popover.Target>
|
||||
|
||||
Reference in New Issue
Block a user