移除模板分类编辑来源字段

- 删除编辑模板弹窗中分类编辑态的旧 category 来源文本框,避免显示未分类、批量导入或模板名等干扰信息。

- 保留分类名称编辑、颜色、maskid 和拖拽层级能力,旧 category 元数据仅作为兼容数据继续随记录保留。

- 为模板分类编辑补充回归测试,确保点击分类后不再暴露旧 category 来源字段。

- 更新 AGENTS、需求冻结、设计冻结和测试计划文档,明确编辑弹窗不展示或编辑 category 来源元信息。
This commit is contained in:
2026-05-03 18:04:02 +08:00
parent cadacef04d
commit d559cda2cb
6 changed files with 37 additions and 24 deletions

View File

@@ -216,6 +216,28 @@ describe('TemplateRegistry', () => {
expect(await screen.findAllByText('新模板')).toHaveLength(2);
});
it('does not expose legacy category metadata while editing template classes', async () => {
apiMock.getTemplates.mockResolvedValueOnce([
{
id: 't1',
name: '模板',
description: 'desc',
classes: [{ id: 'c1', name: '胆囊', color: '#ff0000', zIndex: 10, category: '器官' }],
rules: [],
color: '#06b6d4',
z_index: 3,
},
]);
render(<TemplateRegistry />);
fireEvent.click(await screen.findByRole('button', { name: '编辑模板 模板' }));
fireEvent.click(screen.getAllByText('胆囊').at(-1)!);
expect(screen.getByDisplayValue('胆囊')).toBeInTheDocument();
expect(screen.queryByDisplayValue('器官')).not.toBeInTheDocument();
expect(screen.queryByPlaceholderText('类别')).not.toBeInTheDocument();
});
it('shows the semantic tree title and opens the add-class modal from the detail view', async () => {
apiMock.getTemplates.mockResolvedValueOnce([
{

View File

@@ -685,25 +685,16 @@ export function TemplateRegistry() {
className="w-8 h-8 rounded bg-transparent border-0 cursor-pointer shrink-0 disabled:cursor-not-allowed disabled:opacity-50"
/>
{editingClassId === cls.id ? (
<>
<input
type="text"
value={cls.name}
onChange={(e) => updateClass(cls.id, { name: e.target.value })}
onBlur={() => setEditingClassId(null)}
onKeyDown={(e) => e.key === 'Enter' && setEditingClassId(null)}
autoFocus
readOnly={isReservedUnclassifiedClass(cls)}
className="flex-1 bg-[#1a1a1a] border border-white/10 rounded px-2 py-1 text-sm text-white"
/>
<input
type="text"
value={cls.category || ''}
onChange={(e) => updateClass(cls.id, { category: e.target.value })}
placeholder="类别"
className="w-24 bg-[#1a1a1a] border border-white/10 rounded px-2 py-1 text-sm text-white"
/>
</>
<input
type="text"
value={cls.name}
onChange={(e) => updateClass(cls.id, { name: e.target.value })}
onBlur={() => setEditingClassId(null)}
onKeyDown={(e) => e.key === 'Enter' && setEditingClassId(null)}
autoFocus
readOnly={isReservedUnclassifiedClass(cls)}
className="flex-1 bg-[#1a1a1a] border border-white/10 rounded px-2 py-1 text-sm text-white"
/>
) : (
<>
<span