From e1fe1837a220664be359c74af4c477e4bdc7de1c Mon Sep 17 00:00:00 2001 From: kdletters <61648117+kdletters@users.noreply.github.com> Date: Mon, 28 Sep 2026 14:16:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E5=8F=B0=E6=A8=A1=E6=9D=BF=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E5=BC=B9=E7=AA=97=E8=A1=A8=E5=A4=B4=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=8E=E4=BB=93=E5=BA=93=E5=8D=AB=E7=94=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminAgcTemplatesPage 的上传弹窗把 TableHeader(thead)当列头使用,生成出 th > tr > thead 的非法层级;修正为 TableHeader > TableRow > TableHead,并补列头角色与层级回归。 - .gitignore 补 /server-rs/crates/*/server-rs/.data/:api-server 的相对 outbox 默认路径在嵌套 cwd 下会在仓库内生成内嵌数据目录,避免其被误提交。 --- .gitignore | 3 ++ .../src/pages/AdminAgcTemplatesPage.test.tsx | 31 +++++++++++++++++++ .../src/pages/AdminAgcTemplatesPage.tsx | 20 ++++++------ 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index c278ff3fa..e5662c91e 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,9 @@ temp*build*/ /apps/preview-deployer-web/node_modules/ /server-rs/.spacetimedb/ /server-rs/.data/ +# api-server 的 tracking / wallet-refund outbox 默认目录相对仓库根(server-rs/.data/…); +# 从 server-rs/crates/ 目录运行测试或二进制时,会在仓库内生成嵌套副本,不能提交。 +/server-rs/crates/*/server-rs/.data/ /public/generated-animations /public/generated-character-drafts /public/generated-characters diff --git a/apps/admin-web/src/pages/AdminAgcTemplatesPage.test.tsx b/apps/admin-web/src/pages/AdminAgcTemplatesPage.test.tsx index 11c3f5493..7365cb71d 100644 --- a/apps/admin-web/src/pages/AdminAgcTemplatesPage.test.tsx +++ b/apps/admin-web/src/pages/AdminAgcTemplatesPage.test.tsx @@ -542,6 +542,37 @@ function pickUploadFiles(dialog: HTMLElement, accept: string, files: File[]) { fireEvent.change(input, { target: { files } }); } +test('批量上传:表头是真实列头单元格,不是嵌套 thead', async () => { + render(); + const dialog = await openUploadDialog(); + pickUploadFiles(dialog, '.zip,application/zip', [uploadZipFile('alpha.zip')]); + + const table = Array.from(dialog.querySelectorAll('table')).find((candidate) => + candidate.textContent?.includes('alpha.zip'), + ); + expect(table).toBeTruthy(); + + // 每一列表头都必须是 `th`:把 ``(渲染 ``)当单元格用会产出 + // ``,列头语义与样式一起丢失。 + expect( + within(table as HTMLElement) + .getAllByRole('columnheader') + .map((cell) => cell.textContent), + ).toEqual([ + '模板包', + 'ID', + '名称', + '版本', + '运行时', + 'entry', + '封面', + '操作', + ]); + expect(table?.querySelectorAll('thead thead')).toHaveLength(0); + expect(table?.querySelectorAll('thead > tr > th')).toHaveLength(8); + expect(table?.querySelectorAll('thead > th')).toHaveLength(0); +}); + test('批量上传:多选 ZIP 生成行,封面匹配齐了才能提交', async () => { render(); const dialog = await openUploadDialog(); diff --git a/apps/admin-web/src/pages/AdminAgcTemplatesPage.tsx b/apps/admin-web/src/pages/AdminAgcTemplatesPage.tsx index f5cd5fb16..37c3d8809 100644 --- a/apps/admin-web/src/pages/AdminAgcTemplatesPage.tsx +++ b/apps/admin-web/src/pages/AdminAgcTemplatesPage.tsx @@ -880,18 +880,18 @@ function TemplateUploadDialog({ ) : (
- + - 模板包 - ID - 名称 - 版本 - 运行时 - entry - 封面 - 操作 + 模板包 + ID + 名称 + 版本 + 运行时 + entry + 封面 + 操作 - + {state.rows.map((row) => { const rowError = state.errors[row.key];