From b01bdd380ac713d7d5c0e98c921d38baf2fbf8ad Mon Sep 17 00:00:00 2001 From: hunter-dev Date: Wed, 26 Aug 2026 19:21:29 +0800 Subject: [PATCH] =?UTF-8?q?fix(tabs):=20=E5=85=B3=E9=97=AD=E5=85=A8?= =?UTF-8?q?=E9=83=A8=E6=A0=87=E7=AD=BE=E9=A1=B5=E5=90=8E=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E6=9C=AA=E6=B8=85=E7=A9=BA=E2=80=94=E2=80=94closeTab?= =?UTF-8?q?=20=E4=BB=85=E6=B8=85=E7=A9=BA=20tabs/activeId=20=E4=B8=8D?= =?UTF-8?q?=E6=B8=85=20store.currentPath,=20=E5=AF=BC=E8=87=B4=20TiptapEdi?= =?UTF-8?q?tor=20=E4=BB=8D=E6=B8=B2=E6=9F=93=E6=97=A7=E6=96=87=E6=A1=A3.?= =?UTF-8?q?=20TabBar=20useEffect=20=E5=8A=A0=20resetEditor:=20=E5=BD=93=20?= =?UTF-8?q?activeId=20=E4=B8=BA=20null=20=E4=B8=94=20currentPath=20?= =?UTF-8?q?=E9=9D=9E=E7=A9=BA=E6=97=B6=E8=B0=83=E7=94=A8=20store.resetEdit?= =?UTF-8?q?or=20=E6=B8=85=E7=A9=BA=20currentPath/body/meta,=20=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E6=AD=A3=E7=A1=AE=E6=98=BE=E7=A4=BA=E7=A9=BA?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=8F=90=E7=A4=BA;=20=E6=96=B0=E5=A2=9E=20E2?= =?UTF-8?q?E=20=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/renderer/features/tabs/TabBar.tsx | 4 +++- apps/desktop/tests/e2e/button-all.spec.ts | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/apps/desktop/src/renderer/features/tabs/TabBar.tsx b/apps/desktop/src/renderer/features/tabs/TabBar.tsx index d369e3d..570cbe5 100644 --- a/apps/desktop/src/renderer/features/tabs/TabBar.tsx +++ b/apps/desktop/src/renderer/features/tabs/TabBar.tsx @@ -7,10 +7,12 @@ export function TabBar() { const { openDoc, currentPath } = useStore(); const [hoveredTab, setHoveredTab] = useState(null); - // 当 activeId 变化,加载对应标签的文档 + // 当 activeId 变化,加载对应标签的文档;标签全部关闭时清空编辑器 + const resetEditor = useStore(s => s.resetEditor); useEffect(() => { const tab = tabs.find(t => t.id === activeId); if (tab && tab.path !== currentPath) openDoc(tab.path); + else if (!activeId && currentPath) resetEditor(); }, [activeId]); if (tabs.length === 0) return null; diff --git a/apps/desktop/tests/e2e/button-all.spec.ts b/apps/desktop/tests/e2e/button-all.spec.ts index 706567b..1682087 100644 --- a/apps/desktop/tests/e2e/button-all.spec.ts +++ b/apps/desktop/tests/e2e/button-all.spec.ts @@ -321,3 +321,21 @@ test('TabBar: 固定+关闭可用', async () => { await expect(a.page.getByTestId('tabbar').getByText('Tab2', { exact: true })).toHaveCount(0, { timeout: 3000 }); await a.app.close(); }); + +test('TabBar: 关闭全部标签后编辑器应显示空状态', async () => { + const a = await launch(nodePath.join(os.tmpdir(), 'hn-close-all-' + Date.now())); + await setupVault(a, [{ name: 'CloseAllTest', body: '# 关闭全部测试\n正文内容' }]); + // 打开文档 + await a.page.getByTestId('filetree').getByText('CloseAllTest', { exact: true }).click(); + await expect(a.page.getByTestId('tabbar').getByText('CloseAllTest', { exact: true })).toBeVisible(); + // 编辑器应显示文档内容 + await expect(a.page.locator('.ProseMirror')).toContainText('关闭全部测试'); + // 关闭标签页(span 文本 x) + const tab = a.page.getByTestId('tabbar').locator('div').filter({ hasText: 'CloseAllTest' }).first(); + await tab.locator('span').filter({ hasText: 'x' }).click(); + await a.page.waitForTimeout(500); + // 标签栏为空 → 当前文档应重置,编辑器显示空状态提示 + expect(await a.page.evaluate(() => (globalThis as any).__STORE__?.getState?.().currentPath)).toBeNull(); + await expect(a.page.getByText('从左侧选择一篇笔记')).toBeVisible({ timeout: 5000 }); + await a.app.close(); +});