mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-07-15 19:54:32 +00:00
## Summary Long team workspace names wrapped onto multiple lines in the user-menu workspace switcher, overflowing the fixed 54px rows and breaking the dropdown layout. Applies the same single-line ellipsis pattern already used by the current-workspace header (`CurrentUserPopoverWorkspace.vue`). ## Changes - **What**: `truncate` on the switcher name span, `max-w-full` on the name row, `shrink-0` on avatar/tier badge/check icon so only the name shrinks (`WorkspaceSwitcherPopover.vue`, 5 lines) - Regression tests: Vitest component test + `@cloud` Playwright e2e measuring single-line render height Fixes [FE-778](https://linear.app/comfyorg/issue/FE-778/bug-team-workspace-names-wrapping-to-multiple-lines-display-poorly-in) ## Red-Green Verification | Commit | CI | Result | |---|---|---| | `30e04e2` test only | [Tests Unit](https://github.com/Comfy-Org/ComfyUI_frontend/actions/runs/27278378157) / [Tests E2E](https://github.com/Comfy-Org/ComfyUI_frontend/actions/runs/27278378213) | 🔴 new unit test + cloud e2e fail (proves tests catch the bug) | | `d8f9a5c` fix | [Tests Unit](https://github.com/Comfy-Org/ComfyUI_frontend/actions/runs/27279508881) / [Tests E2E](https://github.com/Comfy-Org/ComfyUI_frontend/actions/runs/27279508715) | 🟢 same tests pass | ## Screenshots | Before | After | |---|---| | <img width="320" alt="before — name wraps to 4 lines, rows collide" src="https://github.com/user-attachments/assets/90f3286a-5b50-4477-9b5c-9d32d0b026e4" /> | <img width="320" alt="after — single line with ellipsis, row height intact" src="https://github.com/user-attachments/assets/8e47bbb2-b5b1-4945-a008-68491f39dc46" /> | ## Review Focus - Truncation chain: the name span is a flex item, so `truncate` (overflow-hidden) zeroes its automatic min size; `max-w-full` caps the `items-start` row at the container width. Mirrors the header pattern — no new component. - Figma `Team Plan - Workspaces` (Workspaces Menu component, node 2045-14413) specifies compact single-line rows; long-name overflow was undesigned, truncation preserves the spec'd layout.
102 lines
2.9 KiB
TypeScript
102 lines
2.9 KiB
TypeScript
import { expect } from '@playwright/test'
|
|
|
|
import type { RemoteConfig } from '@/platform/remoteConfig/types'
|
|
import type { WorkspaceWithRole } from '@/platform/workspace/api/workspaceApi'
|
|
import type { WorkspaceTokenResponse } from '@/platform/workspace/stores/workspaceAuthStore'
|
|
import { comfyPageFixture } from '@e2e/fixtures/ComfyPage'
|
|
|
|
const PERSONAL_WORKSPACE_NAME = 'Personal Workspace'
|
|
const LONG_WORKSPACE_NAME =
|
|
'Quantum Renaissance Collective for Hyperdimensional Latent Diffusion Research and Experimental Workflow Engineering'
|
|
|
|
// text-sm rows render a single 20px line; a wrapped name is 40px+.
|
|
const SINGLE_LINE_MAX_HEIGHT_PX = 28
|
|
|
|
const mockRemoteConfig: RemoteConfig = { team_workspaces_enabled: true }
|
|
|
|
const mockListWorkspacesResponse: { workspaces: WorkspaceWithRole[] } = {
|
|
workspaces: [
|
|
{
|
|
id: 'ws-personal',
|
|
name: PERSONAL_WORKSPACE_NAME,
|
|
type: 'personal',
|
|
created_at: '2026-01-01T00:00:00Z',
|
|
joined_at: '2026-01-01T00:00:00Z',
|
|
role: 'owner'
|
|
},
|
|
{
|
|
id: 'ws-team-long',
|
|
name: LONG_WORKSPACE_NAME,
|
|
type: 'team',
|
|
created_at: '2026-01-02T00:00:00Z',
|
|
joined_at: '2026-01-02T00:00:00Z',
|
|
role: 'member'
|
|
}
|
|
]
|
|
}
|
|
|
|
const mockTokenResponse: WorkspaceTokenResponse = {
|
|
token: 'mock-workspace-token',
|
|
expires_at: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
|
|
workspace: {
|
|
id: 'ws-personal',
|
|
name: PERSONAL_WORKSPACE_NAME,
|
|
type: 'personal'
|
|
},
|
|
role: 'owner',
|
|
permissions: []
|
|
}
|
|
|
|
const test = comfyPageFixture.extend({
|
|
page: async ({ page }, use) => {
|
|
await page.route('**/api/features', (route) =>
|
|
route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(mockRemoteConfig)
|
|
})
|
|
)
|
|
|
|
await page.route('**/api/workspaces', async (route) => {
|
|
if (route.request().method() !== 'GET') {
|
|
await route.fallback()
|
|
return
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(mockListWorkspacesResponse)
|
|
})
|
|
})
|
|
|
|
await page.route('**/api/auth/token', (route) =>
|
|
route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(mockTokenResponse)
|
|
})
|
|
)
|
|
|
|
await use(page)
|
|
}
|
|
})
|
|
|
|
test.describe('Workspace switcher', { tag: '@cloud' }, () => {
|
|
test('renders a long team workspace name on a single line', async ({
|
|
comfyPage
|
|
}) => {
|
|
const page = comfyPage.page
|
|
|
|
await comfyPage.toast.closeToasts()
|
|
await page.getByRole('button', { name: 'Current user' }).click()
|
|
await page.getByText(PERSONAL_WORKSPACE_NAME).click()
|
|
|
|
const longName = page.getByText(LONG_WORKSPACE_NAME)
|
|
await expect(longName).toBeVisible()
|
|
|
|
const box = await longName.boundingBox()
|
|
expect(box).not.toBeNull()
|
|
expect(box!.height).toBeLessThan(SINGLE_LINE_MAX_HEIGHT_PX)
|
|
})
|
|
})
|