diff --git a/frontend/src/pages/DataAnnotation/components/TemplateConfigurationTreeEditor.tsx b/frontend/src/pages/DataAnnotation/components/TemplateConfigurationTreeEditor.tsx index 99f5099..79bb4c4 100644 --- a/frontend/src/pages/DataAnnotation/components/TemplateConfigurationTreeEditor.tsx +++ b/frontend/src/pages/DataAnnotation/components/TemplateConfigurationTreeEditor.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { Alert, Button, @@ -204,9 +204,20 @@ const isDescendant = (node: XmlNode, targetId: string): boolean => { return node.children.some((child) => isDescendant(child, targetId)); }; -const getNodeLabel = (node: XmlNode) => { - const name = node.attrs.name || node.attrs.value; - return name ? `${node.tag} (${name})` : node.tag; +const COMMON_TAG_DISPLAY_NAMES: Record = { + View: "容器", + Header: "标题", + Style: "样式", + Label: "标签项", + Choice: "选项", + Relation: "关系", + Relations: "关系组", + Item: "列表项", + Path: "路径", + Channel: "通道", + Collapse: "折叠面板", + Filter: "过滤器", + Shortcut: "快捷键", }; const getDefaultName = (tag: string) => { @@ -478,7 +489,10 @@ const TemplateConfigurationTreeEditor = ({ .map(([tag]) => ({ value: tag, label: getControlDisplayName(tag) })); const layout = Object.entries(config.controls) .filter(([, item]) => item.category === "layout") - .map(([tag]) => ({ value: tag, label: tag })); + .map(([tag]) => ({ + value: tag, + label: COMMON_TAG_DISPLAY_NAMES[tag] || tag, + })); return { labeling, layout }; }, [config]); @@ -497,7 +511,7 @@ const TemplateConfigurationTreeEditor = ({ }[]; options.push({ label: "容器", - options: [{ value: "View", label: "View" }], + options: [{ value: "View", label: COMMON_TAG_DISPLAY_NAMES.View }], }); if (objectOptions.length > 0) { options.push({ label: "数据对象", options: objectOptions }); @@ -510,11 +524,23 @@ const TemplateConfigurationTreeEditor = ({ } options.push({ label: "子标签", - options: CHILD_TAGS.map((tag) => ({ value: tag, label: tag })), + options: CHILD_TAGS.map((tag) => ({ + value: tag, + label: COMMON_TAG_DISPLAY_NAMES[tag] || tag, + })), }); return options; }, [objectOptions, controlOptions]); + const getTagDisplayName = useCallback( + (tag: string) => { + if (config?.objects?.[tag]) return getObjectDisplayName(tag); + if (config?.controls?.[tag]) return getControlDisplayName(tag); + return COMMON_TAG_DISPLAY_NAMES[tag] || tag; + }, + [config] + ); + const handleAddNode = (tag: string, mode: "child" | "sibling") => { if (isStructureLocked) return; const newNode = createNode(tag, config || null, objectNames); @@ -630,12 +656,16 @@ const TemplateConfigurationTreeEditor = ({ const issue = validationIssues[node.id]; const hasError = issue?.errors?.length > 0; const hasWarning = issue?.warnings?.length > 0; + const name = node.attrs.name || node.attrs.value; + const title = name + ? `${getTagDisplayName(node.tag)} (${name})` + : getTagDisplayName(node.tag); return { key: node.id, title: ( - {getNodeLabel(node)} + {title} {hasError && 错误} {!hasError && hasWarning && 提示} @@ -646,7 +676,7 @@ const TemplateConfigurationTreeEditor = ({ }; }; return [build(tree)]; - }, [tree, validationIssues, isStructureLocked]); + }, [tree, validationIssues, isStructureLocked, getTagDisplayName]); const onDrop: TreeProps["onDrop"] = (info) => { if (isStructureLocked) return;