fix(workspace): open project menu with all projects
This commit is contained in:
@@ -331,7 +331,7 @@ describe('ProjectSwitcher project activity integration', () => {
|
|||||||
expect(trigger).toHaveTextContent('Local project')
|
expect(trigger).toHaveTextContent('Local project')
|
||||||
expect(trigger).toHaveAccessibleDescription('暂无活动')
|
expect(trigger).toHaveAccessibleDescription('暂无活动')
|
||||||
fireEvent.click(within(trigger).getByText('暂无活动'))
|
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' })
|
fireEvent.keyDown(screen.getByRole('dialog', { name: '项目与活动' }), { key: 'Escape' })
|
||||||
expect(trigger).toHaveFocus()
|
expect(trigger).toHaveFocus()
|
||||||
expect(trigger).toHaveAttribute('aria-expanded', 'false')
|
expect(trigger).toHaveAttribute('aria-expanded', 'false')
|
||||||
|
|||||||
@@ -30,6 +30,26 @@ function setup({ projects = [local, other], conversations = [conversation('Local
|
|||||||
afterEach(async () => { cleanup(); vi.restoreAllMocks(); await i18n.changeLanguage('zh-CN') })
|
afterEach(async () => { cleanup(); vi.restoreAllMocks(); await i18n.changeLanguage('zh-CN') })
|
||||||
|
|
||||||
describe('production workspace menu', () => {
|
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 () => {
|
it('puts All Projects first in a fixed tab row and filters categories only when activated', async () => {
|
||||||
await i18n.changeLanguage('en-US')
|
await i18n.changeLanguage('en-US')
|
||||||
const remote: AssistantProject = { ...other, id: 'remote', name: 'Remote workspace', rootPath: '/srv/workspace',
|
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')
|
await i18n.changeLanguage('en-US')
|
||||||
const conversations = Array.from({ length: 12 }, (_, i) => conversation(`Finished ${i}`, local.id, 100 - i))
|
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,
|
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' })
|
const menu = screen.getByRole('dialog', { name: 'Projects and activity' })
|
||||||
expect(trigger).toHaveAttribute('aria-controls', menu.id)
|
expect(trigger).toHaveAttribute('aria-controls', menu.id)
|
||||||
expect(trigger).toHaveAttribute('aria-expanded', 'true')
|
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' })
|
const all = screen.getByRole('tab', { name: 'All projects' })
|
||||||
expect(all).toHaveAttribute('aria-selected', 'true')
|
expect(all).toHaveAttribute('aria-selected', 'true')
|
||||||
expect(screen.getAllByRole('tab')[0]).toBe(all)
|
expect(screen.getAllByRole('tab')[0]).toBe(all)
|
||||||
const list = screen.getByRole('list', { name: 'Conversations' })
|
const list = screen.getByRole('list', { name: 'Conversations' })
|
||||||
expect(within(list).getAllByRole('button')).toHaveLength(10)
|
expect(within(list).getByText('Running chat')).toBeVisible()
|
||||||
expect(within(list).queryByText('Running chat')).not.toBeInTheDocument()
|
|
||||||
fireEvent.click(all)
|
|
||||||
expect(within(list).getAllByRole('button')).toHaveLength(11)
|
expect(within(list).getAllByRole('button')).toHaveLength(11)
|
||||||
expect(within(list).getAllByText(local.name)).toHaveLength(10)
|
expect(within(list).getAllByText(local.name)).toHaveLength(10)
|
||||||
fireEvent.click(within(screen.getByRole('group', { name: 'Filter conversation status' })).getByRole('button', { name: 'Completed' }))
|
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')
|
expect(actions.onOpenConversation).toHaveBeenCalledExactlyOnceWith('Finished 0')
|
||||||
rerender(<ProjectSwitcher {...props} activities={activities.filter((row) => row.conversationId !== 'Finished 0')} />)
|
rerender(<ProjectSwitcher {...props} activities={activities.filter((row) => row.conversationId !== 'Finished 0')} />)
|
||||||
fireEvent.click(screen.getByRole('button', { name: 'Current project' }))
|
fireEvent.click(screen.getByRole('button', { name: 'Current project' }))
|
||||||
expect(within(screen.getByRole('list', { name: 'Conversations' })).getByRole('button', { name: 'Finished 0' })).toBeInTheDocument()
|
expect(within(screen.getByRole('list', { name: 'Conversations' })).getByRole('button', { name: /^Finished 0 / })).toBeInTheDocument()
|
||||||
expect(screen.getByRole('region', { name: local.name })).toBeVisible()
|
expect(screen.getByRole('region', { name: 'All projects' })).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('searches across categories, creates in preview scope, and explains channel restrictions', async () => {
|
it('searches across categories, creates in preview scope, and explains channel restrictions', async () => {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export function WorkspaceMenu({
|
|||||||
const categoriesRef = useRef<HTMLDivElement>(null)
|
const categoriesRef = useRef<HTMLDivElement>(null)
|
||||||
const [category, setCategory] = useState<ProjectCategory>('allProjects')
|
const [category, setCategory] = useState<ProjectCategory>('allProjects')
|
||||||
if (category === 'remote' && !remoteProjectsEnabled) setCategory('allProjects')
|
if (category === 'remote' && !remoteProjectsEnabled) setCategory('allProjects')
|
||||||
const [scope, setScope] = useState<string | null>(activeProjectId)
|
const [scope, setScope] = useState<string | null>(null)
|
||||||
const [filter, setFilter] = useState<WorkspaceFilter>('all')
|
const [filter, setFilter] = useState<WorkspaceFilter>('all')
|
||||||
const [query, setQuery] = useState('')
|
const [query, setQuery] = useState('')
|
||||||
const [collapsed, setCollapsed] = useState<ReadonlySet<string>>(() => new Set())
|
const [collapsed, setCollapsed] = useState<ReadonlySet<string>>(() => new Set())
|
||||||
|
|||||||
Reference in New Issue
Block a user