feat: complete project workspace tags and notes UI

This commit is contained in:
2026-07-21 00:46:09 +08:00
parent 54958382f1
commit c613d4c997
28 changed files with 1621 additions and 284 deletions

View File

@@ -5,13 +5,14 @@ const requiredFiles = [
'src/pages/login.tsx',
'src/pages/workspace-body.tsx',
'src/pages/workspace-home.tsx',
'src/pages/workspace-inbox.tsx',
'src/pages/workspace-explore.tsx',
'src/pages/projects/project-overview.tsx',
'src/pages/projects/project-channel-page.tsx',
'src/pages/projects/project-tasks.tsx',
'src/pages/projects/project-ai.tsx',
'src/pages/projects/project-notes.tsx',
'src/pages/projects/project-cron.tsx',
'src/pages/projects/project-new-channel.tsx',
'src/pages/projects/project-rail.tsx',
'src/pages/projects/project-sidebar.tsx',
'src/pages/projects/project-topbar.tsx',

View File

@@ -38,7 +38,7 @@ const collectMetrics = async () => page.evaluate(() => {
const workspaceActions = [...document.querySelectorAll('.workspace-page .overview-head .arco-btn')]
.map((button) => button.textContent?.trim())
const dashboard = document.querySelector('.dashboard-button')
const workspaceInbox = document.querySelector('.dashboard-button[title="Inbox"]')
const workspaceExplore = document.querySelector('.dashboard-button[title="探索"]')
const project = document.querySelector('.project-button')
const create = document.querySelector('.create-project')
const firstBadge = document.querySelector('.project-badge .arco-badge-number')
@@ -84,8 +84,8 @@ const collectMetrics = async () => page.evaluate(() => {
workspaceActions,
dashboardButton: rect(dashboard),
dashboardButtonActive: dashboard?.classList.contains('active') ?? false,
workspaceInboxButton: rect(workspaceInbox),
workspaceInboxButtonActive: workspaceInbox?.classList.contains('active') ?? false,
workspaceExploreButton: rect(workspaceExplore),
workspaceExploreButtonActive: workspaceExplore?.classList.contains('active') ?? false,
projectButton: rect(project),
projectButtonActive: project?.classList.contains('active') ?? false,
createProjectButton: rect(create),
@@ -111,10 +111,10 @@ await page.waitForTimeout(700)
await page.screenshot({ path: 'test-results/workbench-react-acro-light.png', fullPage: true })
const workspaceMetrics = await collectMetrics()
await page.locator('.dashboard-button[title="Inbox"]').click()
await page.locator('.dashboard-button[title="探索"]').click()
await page.waitForTimeout(500)
await page.screenshot({ path: 'test-results/workspace-inbox-react-acro-light.png', fullPage: true })
const workspaceInboxMetrics = await collectMetrics()
await page.screenshot({ path: 'test-results/workspace-explore-react-acro-light.png', fullPage: true })
const workspaceExploreMetrics = await collectMetrics()
await page.locator('.project-button').first().click()
await page.waitForTimeout(500)
@@ -133,7 +133,8 @@ for (const channel of [
{ label: '工作计划', pageClass: 'project-tasks-page', expectedHeading: '工作计划' },
{ label: 'AI 会话', pageClass: 'project-ai-page', expectedHeading: 'AI 会话' },
{ label: '笔记资料', pageClass: 'project-notes-page', expectedHeading: '笔记资料' },
{ label: 'Cron 计划任务', pageClass: 'project-cron-page', expectedHeading: 'Cron 计划任务' },
{ label: '计划任务', pageClass: 'project-cron-page', expectedHeading: '计划任务' },
{ label: '新建频道', pageClass: 'project-new-channel-page', expectedHeading: '新建频道' },
]) {
await page.locator('.channel-button', { hasText: channel.label }).click()
await page.waitForTimeout(250)
@@ -158,7 +159,7 @@ await server.close()
console.log(JSON.stringify({
workspaceMetrics,
workspaceInboxMetrics,
workspaceExploreMetrics,
projectMetrics,
channelSidebarHoverMetrics,
stageHoverMetrics,
@@ -180,8 +181,8 @@ if (metrics.overflowX) failures.push('expected no horizontal overflow')
if (!metrics.workbenchMain) failures.push('missing workbench main')
if (!metrics.hasWorkspacePage) failures.push('expected login to land on workspace page')
if (!metrics.dashboardButtonActive) failures.push('expected dashboard button to be active after login')
if (!metrics.workspaceInboxButton) failures.push('expected fixed workspace inbox button to render in project rail')
if (metrics.workspaceInboxButtonActive) failures.push('expected fixed workspace inbox button not to be active after login')
if (!metrics.workspaceExploreButton) failures.push('expected fixed workspace explore button to render in project rail')
if (metrics.workspaceExploreButtonActive) failures.push('expected fixed workspace explore button not to be active after login')
if (metrics.projectButtonActive) failures.push('expected first project button not to be active on workspace landing page')
if (metrics.channelSidebar) failures.push(`expected workspace to hide channel sidebar, got ${JSON.stringify(metrics.channelSidebar)}`)
if (metrics.inspector) failures.push(`expected workspace to hide inspector, got ${JSON.stringify(metrics.inspector)}`)
@@ -231,11 +232,11 @@ if (
failures.push(`dashboard button size ${JSON.stringify(metrics.dashboardButton)} does not match project button ${JSON.stringify(metrics.projectButton)}`)
}
if (
!metrics.workspaceInboxButton ||
metrics.workspaceInboxButton.width !== metrics.projectButton?.width ||
metrics.workspaceInboxButton.height !== metrics.projectButton?.height
!metrics.workspaceExploreButton ||
metrics.workspaceExploreButton.width !== metrics.projectButton?.width ||
metrics.workspaceExploreButton.height !== metrics.projectButton?.height
) {
failures.push(`workspace inbox button size ${JSON.stringify(metrics.workspaceInboxButton)} does not match project button ${JSON.stringify(metrics.projectButton)}`)
failures.push(`workspace explore button size ${JSON.stringify(metrics.workspaceExploreButton)} does not match project button ${JSON.stringify(metrics.projectButton)}`)
}
if (
!metrics.createProjectButton ||
@@ -245,14 +246,14 @@ if (
failures.push(`create project button size ${JSON.stringify(metrics.createProjectButton)} does not match project button ${JSON.stringify(metrics.projectButton)}`)
}
if (!workspaceInboxMetrics.workspaceInboxButtonActive) failures.push('expected fixed workspace inbox button to become active when selected')
if (workspaceInboxMetrics.dashboardButtonActive) failures.push('expected dashboard button not to be active on workspace inbox page')
if (workspaceInboxMetrics.channelSidebar) failures.push(`expected workspace inbox to hide channel sidebar, got ${JSON.stringify(workspaceInboxMetrics.channelSidebar)}`)
if (workspaceInboxMetrics.inspector) failures.push(`expected workspace inbox to hide inspector, got ${JSON.stringify(workspaceInboxMetrics.inspector)}`)
if (!workspaceInboxMetrics.stage || !workspaceInboxMetrics.projectRail) {
failures.push(`missing workspace inbox layout regions: rail=${JSON.stringify(workspaceInboxMetrics.projectRail)}, stage=${JSON.stringify(workspaceInboxMetrics.stage)}`)
} else if (Math.abs(workspaceInboxMetrics.stage.left - workspaceInboxMetrics.projectRail.right) > 1) {
failures.push(`expected workspace inbox stage to start after project rail, got stage.left=${workspaceInboxMetrics.stage.left}, rail.right=${workspaceInboxMetrics.projectRail.right}`)
if (!workspaceExploreMetrics.workspaceExploreButtonActive) failures.push('expected fixed workspace explore button to become active when selected')
if (workspaceExploreMetrics.dashboardButtonActive) failures.push('expected dashboard button not to be active on workspace explore page')
if (workspaceExploreMetrics.channelSidebar) failures.push(`expected workspace explore to hide channel sidebar, got ${JSON.stringify(workspaceExploreMetrics.channelSidebar)}`)
if (workspaceExploreMetrics.inspector) failures.push(`expected workspace explore to hide inspector, got ${JSON.stringify(workspaceExploreMetrics.inspector)}`)
if (!workspaceExploreMetrics.stage || !workspaceExploreMetrics.projectRail) {
failures.push(`missing workspace explore layout regions: rail=${JSON.stringify(workspaceExploreMetrics.projectRail)}, stage=${JSON.stringify(workspaceExploreMetrics.stage)}`)
} else if (Math.abs(workspaceExploreMetrics.stage.left - workspaceExploreMetrics.projectRail.right) > 1) {
failures.push(`expected workspace explore stage to start after project rail, got stage.left=${workspaceExploreMetrics.stage.left}, rail.right=${workspaceExploreMetrics.projectRail.right}`)
}
if (!projectMetrics.hasProjectOverview) failures.push('expected first project click to show project overview page')