"use client" import { projectConfig } from "@/components/label/api/project" import { ProjectDetail } from "@/components/label/api/project/typing" import { usePermissionStore } from "@/components/label/store/auth" import { SettingDataTable } from "@/components/setting/PageSurface" import { ActionIcon, Badge, Button, Group, Modal, Paper, Stack, Text, TextInput, } from "@mantine/core" import { modals } from "@mantine/modals" import { notifications } from "@mantine/notifications" import { IconPlus, IconTrash } from "@tabler/icons-react" import dayjs from "dayjs" import { DataTableColumn } from "mantine-datatable" import { useMemo, useState } from "react" type RulePayload = { text: string create_user: string create_date: string } type RuleRow = RulePayload & { index: number } function normalizeRule(item: unknown): RulePayload { if (typeof item === "string") { return { text: item, create_user: "-", create_date: "-" } } if (item && typeof item === "object") { const rule = item as { text?: unknown create_user?: unknown create_date?: unknown } return { text: String(rule.text ?? ""), create_user: String(rule.create_user ?? "-"), create_date: String(rule.create_date ?? "-"), } } return { text: "", create_user: "-", create_date: "-" } } export default function NoteRulesTable(props: { info: ProjectDetail.DataProps | undefined onUpdated: () => void }) { const { info, onUpdated } = props const projectId = info?.id ?? -1 const userName = usePermissionStore((s) => s.user_name) const [open, setOpen] = useState(false) const [inputText, setInputText] = useState("") const [saving, setSaving] = useState(false) const textRules = useMemo(() => { const rules = (info?.comment_rule as any)?.text_rules return Array.isArray(rules) ? rules.map((r) => String(r ?? "")) : [] }, [info?.comment_rule]) const checkBoxRules = useMemo(() => { const raw = (info?.comment_rule as any)?.check_box_rules const list = Array.isArray(raw) ? raw : [] return list.map((item) => normalizeRule(item)) }, [info?.comment_rule]) const rows = useMemo(() => { return checkBoxRules.map((rule, index) => ({ ...rule, index })) }, [checkBoxRules]) const saveRules = async (nextRules: RulePayload[], successText: string) => { if (projectId === -1) return setSaving(true) try { await projectConfig({ project_id: projectId, comment_rule: { check_box_rules: nextRules, text_rules: textRules, }, }) notifications.show({ color: "green", title: "操作成功", message: successText, }) setOpen(false) setInputText("") onUpdated() } catch (e) { notifications.show({ color: "red", title: "操作失败", message: e instanceof Error ? e.message : "请求失败", }) } finally { setSaving(false) } } const handleAdd = async () => { const value = inputText.trim() if (!value) { notifications.show({ color: "red", title: "新增失败", message: "批注内容不能为空", }) return } const exists = rows.some((row) => row.text.trim() === value) if (exists) { notifications.show({ color: "red", title: "新增失败", message: "批注规则重复,请重新输入", }) return } const next: RulePayload[] = [ ...checkBoxRules, { text: value, create_user: userName ? String(userName) : "-", create_date: dayjs().format("YYYY-MM-DD"), }, ] await saveRules(next, "已添加规则") } const handleDelete = async (row: RuleRow) => { const next = checkBoxRules.filter((_, index) => index !== row.index) await saveRules(next, "已删除规则") } const columns: DataTableColumn[] = [ { accessor: "method", title: "批注方式", width: 90, render: () => 勾选, }, { accessor: "text", title: "内容", }, { accessor: "create_user", title: "添加者", width: 120, }, { accessor: "create_date", title: "添加日期", width: 120, }, { accessor: "operation", title: "操作", width: 90, textAlign: "center", render: (record) => ( { modals.openConfirmModal({ title: "删除规则", centered: true, children: 确定删除该批注规则吗?, labels: { confirm: "确定", cancel: "取消" }, confirmProps: { color: "red" }, onConfirm: () => handleDelete(record), }) }}> ), }, ] return ( <> 批注规则 文本规则 {textRules.length ? textRules.join(";") : "-"} records={rows} columns={columns} noRecordsText="暂无规则" minHeight={200} idAccessor={(record) => `${record.index}_${record.text}_${record.create_user}_${record.create_date}` } /> { if (saving) return setOpen(false) setInputText("") }} title="添加批注规则" centered> 批注方式 勾选 setInputText(e.currentTarget.value)} /> ) }