176 lines
5.3 KiB
TypeScript
176 lines
5.3 KiB
TypeScript
"use client"
|
||
|
||
import { projectConfig } from "@/components/label/api/project"
|
||
import { ProjectDetail } from "@/components/label/api/project/typing"
|
||
import { useAllUserStore } from "@/components/label/store/auth"
|
||
import { Button, Group, Paper, Stack, Switch, Text } from "@mantine/core"
|
||
import { notifications } from "@mantine/notifications"
|
||
import { JSX, useMemo, useState } from "react"
|
||
import AdminUserModal from "./components/AdminUserModal"
|
||
import LabelSchemeContainer from "./components/LabelSchemeContainer"
|
||
import NoteRulesTable from "./components/NoteRulesTable"
|
||
import SamplingPlanContainer from "./components/SamplingPlanContainer"
|
||
import TaskStageTabsContainer from "./components/TaskStageTabsContainer"
|
||
|
||
export default function InfoSettingContainer(props: {
|
||
info: ProjectDetail.DataProps | undefined
|
||
menuAction?: () => JSX.Element
|
||
userEnums: {
|
||
allEnum: Map<any, any>
|
||
labelEnum: Map<any, any>
|
||
review1Enum: Map<any, any>
|
||
review2Enum: Map<any, any>
|
||
}
|
||
updateAction: () => void
|
||
}) {
|
||
const { info, menuAction, userEnums, updateAction } = props
|
||
const projectId = info?.id ?? -1
|
||
|
||
const { userOpts } = useAllUserStore()
|
||
const userOptions = useMemo(() => {
|
||
return userOpts.map((o) => ({ label: o.label, value: String(o.value) }))
|
||
}, [userOpts])
|
||
|
||
const [adminModalOpen, setAdminModalOpen] = useState(false)
|
||
const [lockingValue, setLockingValue] = useState<boolean>(
|
||
!!info?.is_lock_object
|
||
)
|
||
const [savingLock, setSavingLock] = useState(false)
|
||
|
||
const adminText = useMemo(() => {
|
||
const adminUids = info?.admin_user ?? []
|
||
const names = adminUids.map((uid) => {
|
||
const opt = userOpts.find((o) => o.value === uid)
|
||
return opt?.label ?? String(uid)
|
||
})
|
||
return names.length ? names.join("、") : "-"
|
||
}, [info?.admin_user, userOpts])
|
||
|
||
const saveLock = async () => {
|
||
if (projectId === -1) return
|
||
setSavingLock(true)
|
||
try {
|
||
await projectConfig({
|
||
project_id: projectId,
|
||
is_lock_object: lockingValue,
|
||
})
|
||
notifications.show({
|
||
color: "green",
|
||
title: "操作成功",
|
||
message: "已保存配置",
|
||
})
|
||
updateAction()
|
||
} catch (e) {
|
||
notifications.show({
|
||
color: "red",
|
||
title: "操作失败",
|
||
message: e instanceof Error ? e.message : "请求失败",
|
||
})
|
||
} finally {
|
||
setSavingLock(false)
|
||
}
|
||
}
|
||
|
||
return (
|
||
<>
|
||
<Stack gap="md" style={{ flex: 1, minHeight: 0 }}>
|
||
<Paper
|
||
withBorder
|
||
p="sm"
|
||
radius="md"
|
||
style={{ borderColor: "rgba(0,0,0,0.06)" }}>
|
||
<Stack gap="sm">
|
||
{menuAction ? <div>{menuAction()}</div> : null}
|
||
<Group justify="space-between" wrap="wrap">
|
||
<Text fw={700}>基础配置</Text>
|
||
<Button size="xs" variant="default" onClick={updateAction}>
|
||
刷新项目详情
|
||
</Button>
|
||
</Group>
|
||
|
||
<Group justify="space-between" wrap="wrap">
|
||
<Stack gap={2}>
|
||
<Text size="sm" fw={600}>
|
||
项目管理员
|
||
</Text>
|
||
<Text size="sm" c="dimmed">
|
||
{adminText}
|
||
</Text>
|
||
</Stack>
|
||
<Button
|
||
size="xs"
|
||
variant="default"
|
||
onClick={() => setAdminModalOpen(true)}>
|
||
编辑
|
||
</Button>
|
||
</Group>
|
||
|
||
<Group justify="space-between" wrap="wrap">
|
||
<Stack gap={2}>
|
||
<Text size="sm" fw={600}>
|
||
图片对象锁定
|
||
</Text>
|
||
<Text size="sm" c="dimmed">
|
||
开启后对象可被锁定,避免多人同时标注冲突
|
||
</Text>
|
||
</Stack>
|
||
<Group gap="sm">
|
||
<Switch
|
||
checked={lockingValue}
|
||
onChange={(e) => setLockingValue(e.currentTarget.checked)}
|
||
/>
|
||
<Button size="xs" loading={savingLock} onClick={saveLock}>
|
||
保存
|
||
</Button>
|
||
</Group>
|
||
</Group>
|
||
</Stack>
|
||
</Paper>
|
||
|
||
<TaskStageTabsContainer
|
||
projectId={projectId}
|
||
info={info}
|
||
userOptions={userOptions}
|
||
userEnums={userEnums}
|
||
onUpdatedAction={updateAction}
|
||
/>
|
||
|
||
<SamplingPlanContainer
|
||
projectId={projectId}
|
||
info={info}
|
||
onUpdated={updateAction}
|
||
/>
|
||
|
||
<LabelSchemeContainer info={info} />
|
||
|
||
<NoteRulesTable info={info} />
|
||
</Stack>
|
||
|
||
<AdminUserModal
|
||
opened={adminModalOpen}
|
||
value={info?.admin_user ?? []}
|
||
options={userOptions}
|
||
onCloseAction={async (next) => {
|
||
setAdminModalOpen(false)
|
||
if (!next || projectId === -1) return
|
||
try {
|
||
await projectConfig({ project_id: projectId, admin_user: next })
|
||
notifications.show({
|
||
color: "green",
|
||
title: "操作成功",
|
||
message: "已保存项目管理员",
|
||
})
|
||
updateAction()
|
||
} catch (e) {
|
||
notifications.show({
|
||
color: "red",
|
||
title: "操作失败",
|
||
message: e instanceof Error ? e.message : "请求失败",
|
||
})
|
||
}
|
||
}}
|
||
/>
|
||
</>
|
||
)
|
||
}
|