From 658e7f100f4a9a332b7f9ef9c4c8ce42e59af356 Mon Sep 17 00:00:00 2001 From: mesalogo Date: Sun, 4 Oct 2026 14:25:27 +0800 Subject: [PATCH] fix(workspace): open project menu with all projects --- src/renderer/src/ProjectSwitcher.test.tsx | 2 +- src/renderer/src/WorkspaceMenu.test.tsx | 32 ++++++++++++++++++----- src/renderer/src/WorkspaceMenu.tsx | 2 +- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/renderer/src/ProjectSwitcher.test.tsx b/src/renderer/src/ProjectSwitcher.test.tsx index eb941ff6..a910cbc6 100644 --- a/src/renderer/src/ProjectSwitcher.test.tsx +++ b/src/renderer/src/ProjectSwitcher.test.tsx @@ -331,7 +331,7 @@ describe('ProjectSwitcher project activity integration', () => { expect(trigger).toHaveTextContent('Local project') expect(trigger).toHaveAccessibleDescription('暂无活动') fireEvent.click(within(trigger).getByText('暂无活动')) - expect(screen.getByRole('region', { name: project.name })).toBeVisible() + expect(screen.getByRole('region', { name: '全部项目' })).toBeVisible() fireEvent.keyDown(screen.getByRole('dialog', { name: '项目与活动' }), { key: 'Escape' }) expect(trigger).toHaveFocus() expect(trigger).toHaveAttribute('aria-expanded', 'false') diff --git a/src/renderer/src/WorkspaceMenu.test.tsx b/src/renderer/src/WorkspaceMenu.test.tsx index d6d6ce00..a8117531 100644 --- a/src/renderer/src/WorkspaceMenu.test.tsx +++ b/src/renderer/src/WorkspaceMenu.test.tsx @@ -30,6 +30,26 @@ function setup({ projects = [local, other], conversations = [conversation('Local afterEach(async () => { cleanup(); vi.restoreAllMocks(); await i18n.changeLanguage('zh-CN') }) describe('production workspace menu', () => { + it('opens with all projects and clears the previous preview when reopened', async () => { + await i18n.changeLanguage('en-US') + const { actions } = setup() + const trigger = screen.getByRole('button', { name: 'Current project' }) + fireEvent.click(trigger) + const assertAllProjects = (): void => { + const region = screen.getByRole('region', { name: 'All projects' }) + expect(within(region).getByRole('button', { name: /^Local chat/ })).toBeVisible() + expect(within(region).getByRole('button', { name: /^Other chat/ })).toBeVisible() + expect(document.querySelector('[data-preview="true"]')).toBeNull() + } + assertAllProjects() + fireEvent.pointerOver(screen.getByRole('menuitemradio', { name: /Other workspace/ }), { pointerType: 'mouse' }) + expect(screen.getByRole('region', { name: other.name })).toBeVisible() + fireEvent.keyDown(screen.getByRole('dialog'), { key: 'Escape' }) + fireEvent.click(trigger) + assertAllProjects() + expect(actions.onSelect).not.toHaveBeenCalled() + }) + it('puts All Projects first in a fixed tab row and filters categories only when activated', async () => { await i18n.changeLanguage('en-US') const remote: AssistantProject = { ...other, id: 'remote', name: 'Remote workspace', rootPath: '/srv/workspace', @@ -144,7 +164,7 @@ describe('production workspace menu', () => { } }) - it('opens current-project activity from the unified button and offers all projects inside', async () => { + it('opens all-project activity from the unified button', async () => { await i18n.changeLanguage('en-US') const conversations = Array.from({ length: 12 }, (_, i) => conversation(`Finished ${i}`, local.id, 100 - i)) const activities: ConversationActivity[] = conversations.map((row) => ({ conversationId: row.id, projectId: local.id, @@ -158,14 +178,12 @@ describe('production workspace menu', () => { const menu = screen.getByRole('dialog', { name: 'Projects and activity' }) expect(trigger).toHaveAttribute('aria-controls', menu.id) expect(trigger).toHaveAttribute('aria-expanded', 'true') - expect(screen.getByRole('region', { name: local.name })).toBeVisible() + expect(screen.getByRole('region', { name: 'All projects' })).toBeVisible() const all = screen.getByRole('tab', { name: 'All projects' }) expect(all).toHaveAttribute('aria-selected', 'true') expect(screen.getAllByRole('tab')[0]).toBe(all) const list = screen.getByRole('list', { name: 'Conversations' }) - expect(within(list).getAllByRole('button')).toHaveLength(10) - expect(within(list).queryByText('Running chat')).not.toBeInTheDocument() - fireEvent.click(all) + expect(within(list).getByText('Running chat')).toBeVisible() expect(within(list).getAllByRole('button')).toHaveLength(11) expect(within(list).getAllByText(local.name)).toHaveLength(10) fireEvent.click(within(screen.getByRole('group', { name: 'Filter conversation status' })).getByRole('button', { name: 'Completed' })) @@ -174,8 +192,8 @@ describe('production workspace menu', () => { expect(actions.onOpenConversation).toHaveBeenCalledExactlyOnceWith('Finished 0') rerender( row.conversationId !== 'Finished 0')} />) fireEvent.click(screen.getByRole('button', { name: 'Current project' })) - expect(within(screen.getByRole('list', { name: 'Conversations' })).getByRole('button', { name: 'Finished 0' })).toBeInTheDocument() - expect(screen.getByRole('region', { name: local.name })).toBeVisible() + expect(within(screen.getByRole('list', { name: 'Conversations' })).getByRole('button', { name: /^Finished 0 / })).toBeInTheDocument() + expect(screen.getByRole('region', { name: 'All projects' })).toBeVisible() }) it('searches across categories, creates in preview scope, and explains channel restrictions', async () => { diff --git a/src/renderer/src/WorkspaceMenu.tsx b/src/renderer/src/WorkspaceMenu.tsx index b7507396..5b1b7aa1 100644 --- a/src/renderer/src/WorkspaceMenu.tsx +++ b/src/renderer/src/WorkspaceMenu.tsx @@ -50,7 +50,7 @@ export function WorkspaceMenu({ const categoriesRef = useRef(null) const [category, setCategory] = useState('allProjects') if (category === 'remote' && !remoteProjectsEnabled) setCategory('allProjects') - const [scope, setScope] = useState(activeProjectId) + const [scope, setScope] = useState(null) const [filter, setFilter] = useState('all') const [query, setQuery] = useState('') const [collapsed, setCollapsed] = useState>(() => new Set())