fix(canvas): align workspace headers
This commit is contained in:
@@ -4,7 +4,6 @@ import {
|
||||
Loader2,
|
||||
MessageSquareText,
|
||||
Send,
|
||||
Sparkles,
|
||||
} from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
import { Button } from '@/components/ui/button';
|
||||
@@ -121,16 +120,6 @@ export function DesignConversationPane({
|
||||
data-testid="image-workspace-conversation"
|
||||
className="flex min-h-0 flex-1 flex-col bg-surface-subtle/45"
|
||||
>
|
||||
<header className="border-b border-border/70 bg-background px-5 py-3.5">
|
||||
<div className="flex items-center gap-2">
|
||||
<Sparkles className="h-4 w-4 text-brand" />
|
||||
<h2 className="text-sm font-semibold text-foreground">和 AI 一起完善创作</h2>
|
||||
</div>
|
||||
<p className="mt-1 text-xs leading-5 text-muted-foreground">
|
||||
前面的对话会逐步整理成下方可编辑的创作提示词。
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div className="min-h-0 flex-1 overflow-y-auto px-4 py-5 sm:px-6">
|
||||
{workspace.turns.length === 0
|
||||
&& pendingChatMessages.length === 0 && (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Clock3, Images } from 'lucide-react';
|
||||
import { Images } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { DesignWorkspace } from '../../../shared/image-workspace';
|
||||
import { DesignPlanHistory } from './DesignPlanHistory';
|
||||
@@ -14,30 +14,26 @@ export function DesignHistoryRail({ workspace }: { workspace: DesignWorkspace |
|
||||
aria-label="历史作品"
|
||||
className="flex h-full min-h-0 w-[320px] shrink-0 flex-col border-l border-border/70 bg-background font-sans xl:w-[340px]"
|
||||
>
|
||||
<header className={cn(
|
||||
'flex shrink-0 justify-between gap-3 border-b border-border/70 px-4',
|
||||
platform === 'darwin' || platform === 'win32'
|
||||
? 'min-h-[104px] items-end pb-3 pt-10'
|
||||
: 'min-h-16 items-center',
|
||||
)}>
|
||||
<header
|
||||
data-testid="image-workspace-history-header"
|
||||
className={cn(
|
||||
'flex h-16 shrink-0 items-center border-b border-border/70 px-4',
|
||||
platform === 'darwin' && 'pr-[116px]',
|
||||
platform === 'win32' && 'items-end pb-1.5 pr-[156px]',
|
||||
)}
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<Images className="h-4 w-4 shrink-0 text-brand" aria-hidden="true" />
|
||||
<h2 className="truncate text-sm font-semibold text-foreground">历史作品</h2>
|
||||
</div>
|
||||
<p className="mt-1 text-[11px] tabular-nums text-muted-foreground">
|
||||
<p className={cn(
|
||||
'mt-1 truncate text-[11px] tabular-nums text-muted-foreground',
|
||||
platform === 'win32' && 'hidden',
|
||||
)}>
|
||||
{taskCount > 0 ? `${taskCount} 次制作 · ${resultCount} 个结果` : '当前设计项目的制作记录'}
|
||||
</p>
|
||||
</div>
|
||||
{workspace?.tasks.some((task) => task.status === 'queued' || task.status === 'running') ? (
|
||||
<span
|
||||
role="status"
|
||||
className="inline-flex shrink-0 items-center gap-1.5 rounded-lg bg-brand/[0.06] px-2 py-1 text-[11px] font-medium text-brand"
|
||||
>
|
||||
<Clock3 className="h-3.5 w-3.5 animate-pulse" aria-hidden="true" />
|
||||
制作中
|
||||
</span>
|
||||
) : null}
|
||||
</header>
|
||||
|
||||
<div data-testid="image-workspace-history-scroll" className="min-h-0 flex-1 overflow-y-auto overscroll-contain p-3">
|
||||
|
||||
@@ -178,8 +178,8 @@ export function ImageCanvas() {
|
||||
return (
|
||||
<div data-testid="image-workspace" className="flex h-full min-h-0 overflow-hidden bg-background font-sans">
|
||||
<div className="flex min-w-0 flex-1 flex-col">
|
||||
<header className={cn(
|
||||
'flex min-h-16 shrink-0 items-center gap-4 border-b border-border/70 bg-background py-3',
|
||||
<header data-testid="image-workspace-header" className={cn(
|
||||
'flex h-16 shrink-0 items-center gap-4 border-b border-border/70 bg-background py-2',
|
||||
platform === 'darwin'
|
||||
? 'pl-4 pr-[116px] sm:pl-5'
|
||||
: platform === 'win32'
|
||||
|
||||
@@ -355,7 +355,7 @@ test.describe('AI Design V2 workspace', () => {
|
||||
await expect(page.getByTestId('sidebar-image-workspace')).toBeVisible();
|
||||
await expect(page.getByTestId('image-workspace-history-rail')).toBeVisible();
|
||||
await expect(page.getByTestId('image-workspace-works-rail')).toHaveCount(0);
|
||||
await expect(page.getByRole('heading', { name: '和 AI 一起完善创作' })).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: '和 AI 一起完善创作' })).toHaveCount(0);
|
||||
await expect(page.getByRole('heading', { name: '制作方案' })).toBeVisible();
|
||||
await expect(page.getByRole('textbox', { name: '创作提示词' })).toHaveValue(
|
||||
'把便携咖啡机呈现为城市通勤中的精密工具',
|
||||
@@ -373,7 +373,11 @@ test.describe('AI Design V2 workspace', () => {
|
||||
?.getBoundingClientRect();
|
||||
const historyRail = document.querySelector('[data-testid="image-workspace-history-rail"]')
|
||||
?.getBoundingClientRect();
|
||||
return conversation && projectSidebar && workspace && historyRail
|
||||
const workspaceHeader = document.querySelector('[data-testid="image-workspace-header"]')
|
||||
?.getBoundingClientRect();
|
||||
const historyHeader = document.querySelector('[data-testid="image-workspace-history-header"]')
|
||||
?.getBoundingClientRect();
|
||||
return conversation && projectSidebar && workspace && historyRail && workspaceHeader && historyHeader
|
||||
? {
|
||||
conversationHeight: conversation.height,
|
||||
conversationWidth: conversation.width,
|
||||
@@ -384,6 +388,10 @@ test.describe('AI Design V2 workspace', () => {
|
||||
historyTopGap: Math.abs(workspace.top - historyRail.top),
|
||||
historyBottomGap: Math.abs(workspace.bottom - historyRail.bottom),
|
||||
historyHorizontalGap: Math.abs(conversation.right - historyRail.left),
|
||||
workspaceHeaderHeight: workspaceHeader.height,
|
||||
historyHeaderHeight: historyHeader.height,
|
||||
headerTopGap: Math.abs(workspaceHeader.top - historyHeader.top),
|
||||
headerBottomGap: Math.abs(workspaceHeader.bottom - historyHeader.bottom),
|
||||
}
|
||||
: null;
|
||||
});
|
||||
@@ -396,6 +404,10 @@ test.describe('AI Design V2 workspace', () => {
|
||||
expect(layout!.historyTopGap).toBeLessThanOrEqual(1);
|
||||
expect(layout!.historyBottomGap).toBeLessThanOrEqual(1);
|
||||
expect(layout!.historyHorizontalGap).toBeLessThanOrEqual(1);
|
||||
expect(layout!.workspaceHeaderHeight).toBe(64);
|
||||
expect(layout!.historyHeaderHeight).toBe(64);
|
||||
expect(layout!.headerTopGap).toBeLessThanOrEqual(1);
|
||||
expect(layout!.headerBottomGap).toBeLessThanOrEqual(1);
|
||||
expect(layout!.conversationWidth).toBeGreaterThan(600);
|
||||
|
||||
const desktopViewport = page.viewportSize();
|
||||
|
||||
@@ -115,7 +115,7 @@ describe('AI Design Canvas page', () => {
|
||||
render(<ImageCanvas />);
|
||||
|
||||
const conversation = screen.getByTestId('image-workspace-conversation');
|
||||
expect(within(conversation).getByRole('heading', { name: '和 AI 一起完善创作' })).toBeInTheDocument();
|
||||
expect(within(conversation).queryByRole('heading', { name: '和 AI 一起完善创作' })).not.toBeInTheDocument();
|
||||
expect(within(conversation).getByRole('heading', { name: '制作方案' })).toBeInTheDocument();
|
||||
expect(within(conversation).getByRole('textbox', { name: '创作提示词' })).toHaveValue(
|
||||
'把便携咖啡机呈现为城市通勤中的精密工具',
|
||||
@@ -132,6 +132,8 @@ describe('AI Design Canvas page', () => {
|
||||
|
||||
const historyRail = screen.getByTestId('image-workspace-history-rail');
|
||||
expect(historyRail).toHaveClass('h-full', 'border-l');
|
||||
expect(screen.getByTestId('image-workspace-header')).toHaveClass('h-16');
|
||||
expect(screen.getByTestId('image-workspace-history-header')).toHaveClass('h-16');
|
||||
expect(within(historyRail).getByRole('heading', { name: '历史作品' })).toBeInTheDocument();
|
||||
expect(within(historyRail).getByText('还没有历史作品')).toBeInTheDocument();
|
||||
expect(screen.queryByTestId('image-workspace-works-rail')).not.toBeInTheDocument();
|
||||
|
||||
Reference in New Issue
Block a user