From ab2117485dad660672a673620ad197b68361762e Mon Sep 17 00:00:00 2001 From: testikun Date: Thu, 27 Aug 2026 14:28:11 +0800 Subject: [PATCH 1/2] fix(desktop): keep Agent Graph heading visible Make the Agent Graph heading sticky within the bounded panel so status and controls remain available while operators scroll. Add a Desktop layout regression for the sticky heading, overflow, opaque surface, and collapsed-state contract. Fixes #3967 Generated-by: OpenAI Codex --- apps/desktop/e2e/agent-graph-layout.spec.ts | 83 +++++++++++++++++++ .../src/renderer/styles/agent-graph.css | 4 + 2 files changed, 87 insertions(+) create mode 100644 apps/desktop/e2e/agent-graph-layout.spec.ts diff --git a/apps/desktop/e2e/agent-graph-layout.spec.ts b/apps/desktop/e2e/agent-graph-layout.spec.ts new file mode 100644 index 0000000000..631f1f7bf3 --- /dev/null +++ b/apps/desktop/e2e/agent-graph-layout.spec.ts @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { expect, test } from './fixtures'; + +test('Agent Graph keeps its heading fixed while the content scrolls', async ({ window: page }) => { + const geometry = await page.evaluate(() => { + const panel = document.createElement('section'); + panel.className = 'maka-agent-graph-panel'; + + const heading = document.createElement('header'); + heading.className = 'maka-agent-graph-heading'; + heading.textContent = 'Agent Graph'; + + const content = document.createElement('div'); + content.className = 'maka-agent-graph-content'; + + const operators = document.createElement('ul'); + operators.className = 'maka-agent-graph-operators'; + for (let index = 0; index < 24; index += 1) { + const operator = document.createElement('li'); + operator.textContent = `operator-${index + 1}`; + operators.append(operator); + } + content.append(operators); + panel.append(heading, content); + // Give the fixture the bounded viewport production gets from max-height. + // The explicit height keeps the overflow contract deterministic when the + // surrounding E2E shell has an unconstrained body height. + panel.style.height = '295px'; + document.body.append(panel); + + const panelStyle = getComputedStyle(panel); + const panelOverflow = panelStyle.overflow; + const headingStyle = getComputedStyle(heading); + const panelMaxHeight = panelStyle.maxHeight; + const panelRectBefore = panel.getBoundingClientRect(); + const headingRectBefore = heading.getBoundingClientRect(); + panel.scrollTop = panel.scrollHeight; + const panelRectAfter = panel.getBoundingClientRect(); + const headingRectAfter = heading.getBoundingClientRect(); + const beforeOffset = headingRectBefore.top - panelRectBefore.top; + const afterOffset = headingRectAfter.top - panelRectAfter.top; + panel.dataset.collapsed = 'true'; + const collapsedStyle = getComputedStyle(panel); + + return { + panelOverflow, + panelMaxHeight, + headingPosition: headingStyle.position, + headingBackground: headingStyle.backgroundColor, + panelScrollHeight: panel.scrollHeight, + panelClientHeight: panel.clientHeight, + headingOffsetBefore: beforeOffset, + headingOffsetAfter: afterOffset, + collapsedOverflow: collapsedStyle.overflow, + collapsedMaxHeight: collapsedStyle.maxHeight, + }; + }); + expect(geometry.panelOverflow).toBe('auto'); + expect(geometry.headingPosition).toBe('sticky'); + expect(geometry.headingBackground).not.toBe('rgba(0, 0, 0, 0)'); + expect(geometry.panelScrollHeight).toBeGreaterThan(geometry.panelClientHeight); + expect(Math.abs(geometry.headingOffsetAfter - geometry.headingOffsetBefore)).toBeLessThanOrEqual(1); + expect(geometry.collapsedOverflow).toBe('visible'); + expect(geometry.collapsedMaxHeight).toBe('none'); +}); diff --git a/apps/desktop/src/renderer/styles/agent-graph.css b/apps/desktop/src/renderer/styles/agent-graph.css index dc9a4474d0..51fdd474c2 100644 --- a/apps/desktop/src/renderer/styles/agent-graph.css +++ b/apps/desktop/src/renderer/styles/agent-graph.css @@ -44,7 +44,11 @@ } .maka-agent-graph-heading { + position: sticky; + top: 0; + z-index: 1; justify-content: space-between; + background: var(--surface-raised); } .maka-agent-graph-heading-copy { From 72d439b4152e1a853831e835435816ed585956c1 Mon Sep 17 00:00:00 2001 From: testikun Date: Thu, 27 Aug 2026 14:39:14 +0800 Subject: [PATCH 2/2] fix(desktop): clarify sticky Agent Graph heading --- apps/desktop/e2e/agent-graph-layout.spec.ts | 4 ++++ apps/desktop/src/renderer/styles/agent-graph.css | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/desktop/e2e/agent-graph-layout.spec.ts b/apps/desktop/e2e/agent-graph-layout.spec.ts index 631f1f7bf3..be48fd33f2 100644 --- a/apps/desktop/e2e/agent-graph-layout.spec.ts +++ b/apps/desktop/e2e/agent-graph-layout.spec.ts @@ -64,7 +64,9 @@ test('Agent Graph keeps its heading fixed while the content scrolls', async ({ w panelOverflow, panelMaxHeight, headingPosition: headingStyle.position, + headingZIndex: headingStyle.zIndex, headingBackground: headingStyle.backgroundColor, + headingBoxShadow: headingStyle.boxShadow, panelScrollHeight: panel.scrollHeight, panelClientHeight: panel.clientHeight, headingOffsetBefore: beforeOffset, @@ -75,7 +77,9 @@ test('Agent Graph keeps its heading fixed while the content scrolls', async ({ w }); expect(geometry.panelOverflow).toBe('auto'); expect(geometry.headingPosition).toBe('sticky'); + expect(geometry.headingZIndex).toBe('20'); expect(geometry.headingBackground).not.toBe('rgba(0, 0, 0, 0)'); + expect(geometry.headingBoxShadow).not.toBe('none'); expect(geometry.panelScrollHeight).toBeGreaterThan(geometry.panelClientHeight); expect(Math.abs(geometry.headingOffsetAfter - geometry.headingOffsetBefore)).toBeLessThanOrEqual(1); expect(geometry.collapsedOverflow).toBe('visible'); diff --git a/apps/desktop/src/renderer/styles/agent-graph.css b/apps/desktop/src/renderer/styles/agent-graph.css index 51fdd474c2..1ad1e0041a 100644 --- a/apps/desktop/src/renderer/styles/agent-graph.css +++ b/apps/desktop/src/renderer/styles/agent-graph.css @@ -46,9 +46,10 @@ .maka-agent-graph-heading { position: sticky; top: 0; - z-index: 1; + z-index: var(--z-sticky); justify-content: space-between; background: var(--surface-raised); + box-shadow: 0 var(--border-width-hairline) 0 var(--border-soft); } .maka-agent-graph-heading-copy {