From 026e13b347b7e24cf3909af52b0e70b41b3131e3 Mon Sep 17 00:00:00 2001
From: Siri-Ray <109605599+Siri-Ray@users.noreply.github.com>
Date: Wed, 13 May 2026 14:57:25 +0800
Subject: [PATCH] fix(web): restore release header layout (#1519)
* fix(web): restore release header layout
* fix(web): disambiguate entry settings button
Generated-By: looper 0.7.4 (runner=fixer, agent=codex)
---
apps/web/src/components/EntryView.tsx | 20 ++--
apps/web/src/components/ProjectView.tsx | 95 -----------------
apps/web/src/index.css | 134 +-----------------------
e2e/ui/entry-chrome-flows.test.ts | 25 +++--
4 files changed, 24 insertions(+), 250 deletions(-)
diff --git a/apps/web/src/components/EntryView.tsx b/apps/web/src/components/EntryView.tsx
index 6b69b1532..7df4b80ee 100644
--- a/apps/web/src/components/EntryView.tsx
+++ b/apps/web/src/components/EntryView.tsx
@@ -39,6 +39,7 @@ import { PetRail } from './pet/PetRail';
import { PromptTemplatePreviewModal } from './PromptTemplatePreviewModal';
import { PromptTemplatesTab } from './PromptTemplatesTab';
import { apiProtocolLabel } from '../utils/apiProtocol';
+import { AppChromeHeader, SettingsIconButton } from './AppChromeHeader';
type TopTab = 'designs' | 'templates' | 'design-systems' | 'image-templates' | 'video-templates';
@@ -473,6 +474,15 @@ export function EntryView({
return (
+
onOpenSettings()}
+ title={t('settings.title')}
+ ariaLabel={t('settings.title')}
+ />
+ )}
+ />
{
test('pet pill toggle hides and shows the pet rail', async ({ page }) => {
await page.goto('/');
await expect(page.getByTestId('new-project-panel')).toBeVisible();
- await expect(page.locator('.entry-brand')).toBeVisible();
- await expect(page.locator('.entry-brand .entry-brand-title')).toHaveText('Open Design');
- await expect(page.locator('.app-chrome-header')).toHaveCount(0);
+ await expect(page.locator('.app-chrome-header')).toBeVisible();
+ await expect(page.locator('.app-chrome-header .app-chrome-name')).toHaveText('Open Design');
+ await expect(page.locator('.entry-brand')).toHaveCount(0);
await expect(page.locator('.pet-rail')).toBeVisible();
const hideToggle = page.locator('.pet-pill-toggle');
@@ -82,18 +82,17 @@ test('entry chrome avoids horizontal overflow on compact desktop width', async (
await page.setViewportSize({ width: 820, height: 900 });
await page.goto('/');
await expect(page.getByTestId('new-project-panel')).toBeVisible();
- await expect(page.locator('.entry-brand')).toBeVisible();
+ await expect(page.locator('.app-chrome-header')).toBeVisible();
- // The brand row replaced the old global chrome header; if it overflows
- // horizontally on a compact desktop, the logo/title/settings cog will
- // wrap or push the layout sideways. Keep it pinned to no-overflow.
- const brandOverflow = await page.evaluate(() => {
- const brand = document.querySelector('.entry-brand');
- if (!(brand instanceof HTMLElement)) return null;
- return Math.max(0, brand.scrollWidth - brand.clientWidth);
+ // The shared app chrome header should stay one row and avoid pushing
+ // the entry layout sideways on compact desktop widths.
+ const headerOverflow = await page.evaluate(() => {
+ const header = document.querySelector('.app-chrome-header');
+ if (!(header instanceof HTMLElement)) return null;
+ return Math.max(0, header.scrollWidth - header.clientWidth);
});
- expect(brandOverflow).not.toBeNull();
- expect(brandOverflow!).toBeLessThanOrEqual(2);
+ expect(headerOverflow).not.toBeNull();
+ expect(headerOverflow!).toBeLessThanOrEqual(2);
const pageOverflow = await page.evaluate(() =>
Math.max(0, document.documentElement.scrollWidth - document.documentElement.clientWidth),