交付行被裁掉:策划面不再参与 flex 压缩
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / Backend tests (pull_request) Failing after 9s
Project CI / Frontend tests (pull_request) Successful in 5m54s
Project CI / Native shell tests (pull_request) Successful in 18m0s

批准后 GUI 里看不到路径和「查看 GDD 正文」「打开文件」两个按钮。不是没渲染,是被
切了:`.plan-gdd-surface` 为了画圆角带 `overflow: hidden`,而工作台那条又给它
`flex: 0 1 auto` + `min-height: 0`。聊天列纵向吃紧时 flex 把这个面压到内容高度以
下,裁掉的正是最底下那行。标题和轮次在上面,所以还看得见——症状就是「那一栏太小」。

批准前 strip 只有两行、从不需要压缩,所以直到加了第三行才暴露。

它也不需要可压缩:标题栏是固定几行,审批卡自己有 max-height 和内滚,高度天然有界。
改成 `flex: 0 0 auto`。另外「标题栏定高 + 正文占余下」的两行轨道只在审批卡在场时
成立,批准后面里只剩标题栏,把它挪到 `--with-card` 修饰类下。

补一条 A/B 过的断言(改回可压缩即红):这个面必须 `flex: 0 0 auto` 且不带
grid-template-rows,两行轨道只出现在 `--with-card` 上。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-24 13:28:05 +00:00
parent e5fa6438ca
commit 9e4b2b1dc1
2 changed files with 33 additions and 16 deletions
+9 -1
View File
@@ -7088,8 +7088,16 @@ iframe.preview-frame {
/* 审批卡是这一列里唯一没有天花板的成员:Fast GDD 的决定项越多它越高,能把消息列表和运行
时面板一起挤出可视区。和 `.agent-runtime-status` 一样给它自己的上限加内部滚动,而不是
让它去挤别人。 */
/* 这个面不参与 flex 压缩。它自己不会长高:标题栏是固定几行,审批卡下面有自己的
max-height 和内滚,所以高度天然有界。让它可压缩的话,`overflow: hidden`(画圆角
要的)会把底部切掉——批准后交付行正好在那儿,表现是路径和两个按钮凭空消失。 */
.game-workbench-chat .plan-gdd-surface {
flex: 0 1 auto;
flex: 0 0 auto;
}
/* 只有审批卡在场时才需要「标题栏定高 + 正文占余下」的两行轨道。批准后卡片收掉,
面里只剩标题栏,这条声明会给它套上一个不存在的第二行。 */
.game-workbench-chat .plan-gdd-surface--with-card {
min-height: 0;
grid-template-rows: auto minmax(0, 1fr);
}
@@ -816,7 +816,9 @@ export function registerProjectWorkbenchFoundationTests() {
'workbench-art-viewport-memory',
'美术资源视口记忆',
);
const codeTask = manifest.tasks.find((task) => task.id === 'code-prototype');
const codeTask = manifest.tasks.find(
(task) => task.id === 'code-prototype',
);
expect(codeTask).toBeDefined();
codeTask!.status = 'completed';
manifest.assets = [
@@ -1114,7 +1116,9 @@ export function registerProjectWorkbenchFoundationTests() {
).not.toBeNull();
fireEvent.click(within(outline).getByRole('button', { name: /设计文档/ }));
dispatchPageWheel(screen.getByRole('button', { name: /下一页\s*美术资源/ }));
dispatchPageWheel(
screen.getByRole('button', { name: /下一页\s*美术资源/ }),
);
expect(
screen.getByRole('region', { name: '美术资源资源画布' }),
).not.toBeNull();
@@ -1177,9 +1181,7 @@ export function registerProjectWorkbenchFoundationTests() {
name: /打开资源详情:设计文档 section\.md/,
}),
);
expect(
screen.getByRole('dialog', { name: 'section.md' }),
).not.toBeNull();
expect(screen.getByRole('dialog', { name: 'section.md' })).not.toBeNull();
dispatchPageWheel(dependencyCanvas);
expect(
screen.getByRole('region', { name: '美术资源资源画布' }),
@@ -1321,9 +1323,7 @@ export function registerProjectWorkbenchFoundationTests() {
}),
);
});
fireEvent.click(
within(outline).getByRole('button', { name: /项目版本/ }),
);
fireEvent.click(within(outline).getByRole('button', { name: /项目版本/ }));
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 220));
});
@@ -1331,9 +1331,7 @@ export function registerProjectWorkbenchFoundationTests() {
screen.getByRole('region', { name: '项目版本资源画布' }),
).not.toBeNull();
fireEvent.click(
within(outline).getByRole('button', { name: /设计文档/ }),
);
fireEvent.click(within(outline).getByRole('button', { name: /设计文档/ }));
act(() => {
dependencyCanvas.dispatchEvent(
new WheelEvent('wheel', {
@@ -3747,10 +3745,7 @@ export function registerProjectWorkbenchFoundationTests() {
'[data-resource-viewport]',
);
const viewportScale = Number(
viewportElement
?.getAttribute('data-resource-viewport')
?.split(',')
.at(2),
viewportElement?.getAttribute('data-resource-viewport')?.split(',').at(2),
);
expect(viewportScale).toBeGreaterThan(0);
const expectedX = Math.round(12 + (-100 - 20) / viewportScale);
@@ -4191,6 +4186,20 @@ export function registerProjectWorkbenchFoundationTests() {
expect(styles).toMatch(
/\.game-workbench-chat \.planning-lane-runtime-strip\s*\{[^}]*max-height:\s*clamp\([^)]*\)/s,
);
// 策划面画圆角要 `overflow: hidden`,所以它绝不能参与 flex 压缩:一旦可压缩,被压到
// 内容高度以下时裁掉的正是最底下那行——批准后的交付出口(路径 + 两个按钮)就这么
// 凭空消失过一次。它也不需要可压缩,审批卡自己有上限和内滚,高度天然有界。
const planGddSurfaceRule = styles.match(
/\.game-workbench-chat \.plan-gdd-surface\s*\{[^}]*\}/s,
);
expect(planGddSurfaceRule).not.toBeNull();
expect(planGddSurfaceRule?.[0]).toMatch(/flex:\s*0 0 auto/);
// 「标题栏定高 + 正文占余下」的两行轨道只在审批卡在场时成立;批准后面里只剩标题栏,
// 套上不存在的第二行只会让它错位。
expect(planGddSurfaceRule?.[0]).not.toMatch(/grid-template-rows/);
expect(styles).toMatch(
/\.game-workbench-chat \.plan-gdd-surface--with-card\s*\{[^}]*grid-template-rows:\s*auto minmax\(0, 1fr\)/s,
);
expect(styles).toMatch(
/\.game-workbench-chat \.project-runtime-summary\s*\{[^}]*position:\s*sticky[^}]*top:\s*-10px/s,
);