fix: fit the story graph to the window and scroll each column on its own

This commit is contained in:
mesalogo
2026-10-02 22:22:03 +08:00
parent 0fd2f7e3c8
commit 9d8477b728
5 changed files with 109 additions and 1 deletions
@@ -824,6 +824,38 @@ app
await settle()
await writeFile(join(artifacts, `dense-bottom-${width}.png`), (await win.webContents.capturePage()).toPNG())
}
// The graph row fills the window down to a steady bottom margin; each column scrolls on its own.
for (const [width, height] of [[1440, 900], [1440, 700], [1024, 800]]) {
win.setContentSize(width, height)
await settle()
const fill = await js(`(() => {
const shell = document.querySelector('.page-shell');
shell.scrollTop = 0;
const layout = document.querySelector('.supervisor-workspace__graph-layout');
const shellBox = shell.getBoundingClientRect(), box = layout.getBoundingClientRect();
const columns = [...layout.children].map(column => {
const scroller = column.matches('.supervisor-workspace__graph-list') ? column.querySelector('[role=tabpanel]') : column;
const r = column.getBoundingClientRect();
return { name: column.className.split(' ')[0], top: r.top, bottom: r.bottom, scrolls: getComputedStyle(scroller).overflowY,
clientHeight: scroller.clientHeight, scrollHeight: scroller.scrollHeight };
});
// Bottom of the first grid row (the side-by-side columns), measured from the window bottom.
const rowBottom = Math.max(...columns.filter(column => Math.abs(column.top - columns[0].top) < 1).map(column => column.bottom));
return { bottomGap: shellBox.bottom - rowBottom, wrapped: columns.length - columns.filter(column => Math.abs(column.top - columns[0].top) < 1).length,
height: box.height, pageScroll: shell.scrollHeight - shell.clientHeight, columns };
})()`)
reports.push({ fill: { width, height, ...fill } })
await writeFile(join(artifacts, `fill-${width}x${height}.json`), JSON.stringify({ width, height, bottomGap: Math.round(fill.bottomGap), wrapped: fill.wrapped, pageScroll: fill.pageScroll, rowHeight: Math.round(fill.columns[0].bottom - fill.columns[0].top) }))
assert(fill.bottomGap >= 20 && fill.bottomGap <= 40, `Graph must stop above the window bottom: ${JSON.stringify(fill)}`)
// Three columns fit the window with no page scroll; at two columns only the wrapped detail extends the page.
if (!fill.wrapped) assert(fill.pageScroll <= 1, `Page must not scroll at three columns: ${JSON.stringify(fill)}`)
const sideBySide = fill.columns.filter(column => Math.abs(column.top - fill.columns[0].top) < 1)
for (const column of sideBySide) {
assert(Math.abs(column.bottom - sideBySide[0].bottom) < 1, `Columns must share the row height: ${JSON.stringify(fill)}`)
assert(['auto', 'scroll'].includes(column.scrolls), `Column must scroll on its own: ${JSON.stringify(column)}`)
}
await writeFile(join(artifacts, `fill-${width}x${height}.png`), (await win.webContents.capturePage()).toPNG())
}
win.setContentSize(1440, 1100)
await js(
'document.querySelectorAll(".supervisor-workspace__graph-list [role=tab]")[2].click()'