Files
labelimage/app/project/detail/components/LabelSchemeContainer.tsx
2026-04-03 15:12:00 +08:00

222 lines
5.6 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 { ProjectDetail } from "@/components/label/api/project/typing"
import {
labelTypeMap,
selectModeMap,
staticsColor,
} from "@/components/label/utils/constants"
import { SettingDataTable } from "@/components/setting/PageSurface"
import { Badge, Button, Group, Modal, Paper, Stack, Text } from "@mantine/core"
import { DataTableColumn } from "mantine-datatable"
import { useState } from "react"
type DetailRow = ProjectDetail.SubAttributesDescribe
function getColorIndex(color: number[] | undefined) {
if (!Array.isArray(color) || color.length < 3) return undefined
const key = color.slice(0, 3).join("_")
for (const item of staticsColor) {
const [colorKey, colorIndex] = Object.entries(item)[0] ?? []
if (colorKey === key && typeof colorIndex === "number") {
return colorIndex
}
}
return undefined
}
export default function LabelSchemeContainer(props: {
info: ProjectDetail.DataProps | undefined
}) {
const schemas = props.info?.label_schema_list ?? []
const [detailOpen, setDetailOpen] = useState(false)
const [detailRows, setDetailRows] = useState<DetailRow[]>([])
const columns: DataTableColumn<ProjectDetail.LabelSchemaList>[] = [
{
accessor: "label_class",
title: "类别",
width: 120,
},
{
accessor: "super_category",
title: "属性",
width: 120,
render: (record) => record.super_category || "-",
},
{
accessor: "category_id",
title: "ID",
width: 90,
},
{
accessor: "label_type",
title: "标注方式",
width: 140,
render: (record) => (
<Badge variant="light">
{labelTypeMap.get(record.label_type) ??
String(record.label_type ?? "-")}
</Badge>
),
},
{
accessor: "color",
title: "标签颜色",
width: 130,
render: (record) => {
const color = Array.isArray(record.color) ? record.color : []
const idx = getColorIndex(color)
if (color.length < 3) {
return (
<Text size="sm" c="dimmed">
-
</Text>
)
}
return (
<Group gap={8} wrap="nowrap">
<div
style={{
width: 10,
height: 10,
borderRadius: 999,
backgroundColor: `rgb(${color.join(",")})`,
border:
"1px solid light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
}}
/>
<Text size="sm">{idx ?? "-"}</Text>
</Group>
)
},
},
{
accessor: "sub_attributes",
title: "子属性",
width: 180,
render: (record) => {
const attrs = Array.isArray(record.sub_attributes)
? record.sub_attributes
: []
return (
<Text
size="sm"
style={{
maxWidth: 180,
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
}}>
{attrs.length ? attrs.join("、") : "-"}
</Text>
)
},
},
{
accessor: "sub_attributes_describe",
title: "子属性描述",
width: 120,
textAlign: "center",
render: (record) => {
const details = Array.isArray(record.sub_attributes_describe)
? record.sub_attributes_describe
: []
if (!details.length) {
return (
<Text size="sm" c="dimmed">
-
</Text>
)
}
return (
<Button
variant="subtle"
size="compact-xs"
onClick={() => {
setDetailRows(details)
setDetailOpen(true)
}}>
</Button>
)
},
},
]
const detailColumns: DataTableColumn<DetailRow>[] = [
{
accessor: "chinese_name",
title: "子属性",
width: 140,
render: (record) => record.chinese_name || "-",
},
{
accessor: "select_mode",
title: "输入方式",
width: 100,
render: (record) =>
selectModeMap.get(record.select_mode) ??
String(record.select_mode ?? "-"),
},
{
accessor: "isrequired",
title: "是否必填",
width: 90,
render: (record) => (record.isrequired === 1 ? "是" : "否"),
},
{
accessor: "optional_item",
title: "可选属性值",
render: (record) => {
const opts = Array.isArray(record.optional_item)
? record.optional_item
: []
return opts.length ? opts.join("") : "-"
},
},
]
return (
<>
<Paper
withBorder
p="sm"
radius="md"
style={{
borderColor:
"light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
}}>
<Stack gap="sm">
<Text fw={700}></Text>
<SettingDataTable<ProjectDetail.LabelSchemaList>
idAccessor="category_id"
records={schemas}
columns={columns}
minHeight={160}
noRecordsText="暂无数据"
/>
</Stack>
</Paper>
<Modal
opened={detailOpen}
onClose={() => {
setDetailOpen(false)
setDetailRows([])
}}
title="子属性描述"
centered
size="70%">
<SettingDataTable<DetailRow>
records={detailRows}
columns={detailColumns}
noRecordsText="暂无数据"
minHeight={220}
idAccessor="chinese_name"
/>
</Modal>
</>
)
}