Files
labelimage/app/project/detail/components/DispatchModal.tsx
2026-04-15 18:36:28 +08:00

185 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { taskDispatch } from "@/components/label/api/task"
import { Task } from "@/components/label/api/task/typing"
import { usePermissionStore } from "@/components/label/store/auth"
import { Badge, Button, Group, Modal, Select, Stack, Text } from "@mantine/core"
import { useForm } from "@mantine/form"
import { notifications } from "@mantine/notifications"
import { useEffect } from "react"
import { selectedDataProps } from "../TaskTableContainer"
import { dispatchOpts } from "./config"
export default function DispatchModal(props: {
opened: boolean
dispatchData?: selectedDataProps
task_ids: Task.DataProps[]
userOptions: Array<{ label: string; value: string }>
onCloseAction: (refresh?: boolean) => void
}) {
const { opened, dispatchData, task_ids, userOptions, onCloseAction } = props
const operation_uid = usePermissionStore((s) => s.user_id)
const form = useForm({
initialValues: {
task_status_dst: "",
uid_dst: "",
},
validate: {
task_status_dst: (value) => (!value ? "必填" : null),
},
})
const resetFormState = () => {
form.setValues({
task_status_dst: "",
uid_dst: "",
})
form.clearErrors()
form.resetDirty()
}
useEffect(() => {
if (opened) {
resetFormState()
return
}
resetFormState()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [opened])
const taskStatusSrc = dispatchData?.status ?? 0
const taskStatusSrcLabel = dispatchOpts[taskStatusSrc]?.label ?? "-"
const taskRejected = Boolean(dispatchData?.reject)
const dstOptions =
dispatchOpts[taskStatusSrc]?.opts?.map((o) => ({
label: o.label,
value: String(o.value),
})) ?? []
return (
<Modal
opened={opened}
onClose={() => {
resetFormState()
onCloseAction()
}}
title="调度任务"
centered
size={520}>
<form
onSubmit={form.onSubmit(async (values) => {
const opUid =
typeof operation_uid === "number"
? operation_uid
: Number(operation_uid ?? 0)
console.log(dispatchData, operation_uid)
if (!values?.uid_dst || !opUid) {
notifications.show({
color: "red",
title: "操作失败",
message: "缺少必要参数",
})
return
}
const taskStatusDst = Number(values.task_status_dst)
if (!Number.isFinite(taskStatusDst)) {
notifications.show({
color: "red",
title: "校验失败",
message: "请选择目标状态",
})
return
}
const uidDst = values.uid_dst ? Number(values.uid_dst) : null
if (values.uid_dst && !Number.isFinite(uidDst)) {
notifications.show({
color: "red",
title: "校验失败",
message: "请选择目标人员",
})
return
}
try {
await taskDispatch({
operation_uid: opUid,
reject: taskRejected,
task_ids: task_ids.map((item) => item.id),
task_status_src: taskStatusSrc,
task_status_dst: taskStatusDst,
uid_src: dispatchData?.uid ?? null,
uid_dst: uidDst,
})
notifications.show({
color: "green",
title: "操作成功",
message: "已调度任务",
})
resetFormState()
onCloseAction(true)
} catch (e) {
notifications.show({
color: "red",
title: "操作失败",
message: e instanceof Error ? e.message : "请求失败",
})
}
})}>
<Stack gap="sm">
<Text size="sm" c="dimmed">
{task_ids.map((item) => item.project_name).join("、") ?? "-"}
</Text>
<Group gap={6}>
<Text size="sm" c="dimmed">
{taskStatusSrcLabel}
</Text>
{taskRejected ? (
<Badge variant="outline" color="yellow" size="sm">
</Badge>
) : null}
</Group>
<Select
label="目标状态"
placeholder="请选择目标状态"
data={dstOptions}
searchable
clearable
withAsterisk
value={form.values.task_status_dst || null}
onChange={(v) => form.setFieldValue("task_status_dst", v ?? "")}
error={form.errors.task_status_dst}
/>
<Select
label="目标人员"
data={userOptions}
searchable
clearable
value={form.values.uid_dst || null}
onChange={(v) => form.setFieldValue("uid_dst", v ?? "")}
/>
<Group justify="flex-end" gap="sm">
<Button
variant="default"
onClick={() => {
resetFormState()
onCloseAction()
}}>
</Button>
<Button type="submit"></Button>
</Group>
</Stack>
</form>
</Modal>
)
}