Skip to content

feat(overview): fit the matrix on one screen and present it full screen / 一屏信息总览与全屏演示 - #719

Open
chunfangamd wants to merge 9 commits into
SemiAnalysisAI:masterfrom
chunfangamd:chun/inferencex-app_overview
Open

feat(overview): fit the matrix on one screen and present it full screen / 一屏信息总览与全屏演示#719
chunfangamd wants to merge 9 commits into
SemiAnalysisAI:masterfrom
chunfangamd:chun/inferencex-app_overview

Conversation

@chunfangamd

Copy link
Copy Markdown

Summary

The overview matrix did not fit a laptop viewport. At the 50 tok/s/user SLO the section measured 1188px against roughly 900px of usable height, so the last rows and the methodology notes were always below the fold. This PR brings it onto one screen and lets it drive a projector.

Row filtering now works in both comparison modes. The 30-day view keeps its existing "hide rows with no change" control, and the hardware views gain a sibling that hides rows with no result on any platform. They are deliberately separate scopes on separate URL keys (rows= and hwrows=), so each mode remembers its own answer across a tab switch and neither leaks into the other's canonical URL. The hardware predicate tests every platform rather than the delta against the current reference, so the hidden count does not swing when the reference changes and no row that still prices something is ever dropped. Both default to showing everything — narrowing is opt-in.

Revealing inactive models resets whichever row filter is active. A deprecated or maintenance-mode model rarely posts a 30-day change and is the most likely to have no result anywhere, so without the reset the link would read as dead: asking for more models would show none.

Density. Row padding drops from py-4 to py-2.5, the header card tightens, and the AgentX scenario name is abbreviated in the row header. The full scenario name stays as the accessible name and the hover title, so nothing is lost for screen readers.

Present mode hands the matrix section to the Fullscreen API and scales it with a single CSS zoom, so type, padding and rules magnify together and the projection cannot drift from the page layout. While presenting, the control strip becomes the only chrome: SLO on the left, the view tabs centred on the matrix, and the row filters next to Exit as chips whose labels name the click ("Hide unchanged" / "Show all rows") and flip with the scope, with the full counted sentence kept on the accessible name. Arrow keys page between the two views. The reference-hardware dropdown renders in place rather than through a portal while presenting, since document.body sits outside both the fullscreen element and the zoom.

Bilingual. The /zh sibling page is updated in the same commit and every new user-visible string ships an en/zh pair in OVERVIEW_STRINGS.

Test plan

  • bun run test:unit — 168 files / 3273 tests pass (Node 24)
  • New overview-presentation.test.tsx (4 tests): fullscreen round trip, Esc bypassing the button, arrow keys gated on presenting, and graceful absence on browsers that refuse fullscreen
  • New unit tests for both row scopes (12) covering resolution, opt-in defaults, cross-mode pass-through, the reference-independence safeguard, and the degenerate "nothing to hide" fallback
  • New link tests (10) covering canonical URL shape, per-mode key emission, and that each mode keeps its own filter across a tab switch
  • bun run typecheck, bun run lint, bun run fmt clean
  • Manual verification in the browser: both locales, both comparison modes, every SLO tier, and Present mode including arrow-key paging and the reference dropdown

中文说明

总览矩阵此前无法在笔记本视口内完整显示。在 50 tok/s/user 的 SLO 下,该区块高约 1188px,而可用高度仅约 900px,导致末尾几行与方法学脚注始终位于首屏之下。本 PR 将其收进一屏,并新增全屏演示能力。

行过滤现已覆盖两种对比模式。 30-day 视图保留原有的"隐藏无变化行"控件,硬件对比视图新增一个同类控件,用于隐藏在所有平台上均无结果的行。两者刻意采用独立的作用域与独立的 URL 参数(rows=hwrows=),因此切换标签页时各自记住自己的状态,也不会污染对方的规范 URL。硬件侧的判定检查所有平台,而非与当前参考硬件的差值,这样隐藏行数不会随参考硬件改变而波动,且任何仍有报价的行都不会被误删。两者默认显示全部,收窄始终是显式选择。

显示非活跃模型时会重置当前生效的行过滤。 已弃用与维护模式的模型很少产生 30 天变化,也最可能在所有平台上都没有结果;若不重置,请求显示更多模型却什么都看不到,该链接会表现得像失效链接。

排版密度。 行内边距由 py-4 收紧至 py-2.5,头部卡片同步收紧,AgentX 场景名在行首以缩写显示。完整场景名仍作为无障碍名称与悬停提示保留,读屏用户不会丢失信息。

演示模式 将矩阵区块交给 Fullscreen API,并以单个 CSS zoom 整体缩放,使字号、内边距与分隔线同比放大,投影效果不会偏离页面布局。演示时控制栏成为唯一的界面元素:左侧为 SLO,中间是与矩阵居中对齐的视图标签,右侧是与 Exit 并排的行过滤按钮——按钮文案描述点击动作("Hide unchanged" / "Show all rows")并随状态翻转,带计数的完整语句保留在无障碍名称中。方向键可在两个视图间切换。演示期间参考硬件下拉框就地渲染而非通过 portal,因为 document.body 位于 fullscreen 元素与 zoom 作用范围之外。

双语。 /zh 对应页面已在同一提交中更新,所有新增的用户可见文案均在 OVERVIEW_STRINGS 中提供了 en/zh 两份。

Made with Cursor

The matrix overflowed a laptop viewport (1188px against ~900px of usable
height). Row padding tightens, the AgentX scenario name is abbreviated in the
row header with the full name kept as the accessible name, and both
comparison modes can now hide uninteresting rows — the 30-day view keeps its
existing control, the hardware views gain one for rows with no result on any
platform. Separate URL keys (rows=, hwrows=) let each mode remember its own
answer across a tab switch; both default to showing everything.

Present mode hands the matrix to the Fullscreen API and scales it with one
CSS zoom, so the projection cannot drift from the page layout. While
presenting, the control strip carries the SLO, the view tabs, and the filters
beside Exit as chips that name the click and flip with the scope. Arrow keys
page between views.

中文:本PR解决此前overview下不能一屏放下所有信息的局限。方法:全屏显示
@chunfangamd
chunfangamd requested a review from adibarra as a code owner August 11, 2026 00:17
@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

@chunfangamd is attempting to deploy a commit to the SemiAnalysisAI Team on Vercel.

A member of the Team first needs to authorize it.

Comment thread packages/app/src/components/overview/overview-scorecard.tsx
Comment thread packages/app/src/components/overview/overview-page.tsx
`overviewHref` emitted only the active mode's row key, and the scope resolvers
cleared the other mode's answer out of the page data. Since every href the page
builds — including the one the client router starts from — comes from that
data, the dormant filter was erased on first load and deleted again by the
models toggle, which merges both keys. Refreshing, or opening a link carrying
both, could not restore the other tab.

Emit each scope whenever it is set regardless of mode, and carry the off-screen
scope through its no-op branch instead of resetting it to `all`. Only the row
count is zeroed there, since that mode has no control to label while it is off
screen. Reported by Bugbot on SemiAnalysisAI#719.

中文:`overviewHref` 只输出当前模式的行过滤 key,而作用域解析函数会把另一模式的
选择从页面数据中清除。页面构建的每个 href 都源自这份数据(包括客户端路由的起始
URL),因此休眠的过滤器在首次加载时即被抹除,并会被同时合并两个 key 的模型开关
再次删除;刷新或打开带两个参数的链接都无法恢复另一个标签页的状态。

现改为:只要作用域非默认就输出,与当前模式无关;跨模式的空操作分支改为透传该作用
域而非重置为 `all`,仅将行计数清零——该模式不在屏幕上时没有控件需要标注。
由 Bugbot 在 SemiAnalysisAI#719 中发现。

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
inferencemax-app Ready Ready Preview Aug 11, 2026 12:56am

Request Review

@adibarra

Copy link
Copy Markdown
Contributor

@claude can you fix the tests and make sure its green

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Claude finished @adibarra's task in 7m 17s —— View job


Tests fixed ✅

Root cause: the only real CI failure was api-route-catalog.test.ts. Master (054a9d3) added an API-route guardrail that pins a SHA-256 of each route's source. This PR added 4 lines to /api/v1/overview/route.ts, so once the branch was merged with master the stored digest no longer matched. It didn't reproduce on the branch head alone because CI tests the PR merged into master, and the branch was behind master (missing the catalog entirely).

The connection.test.ts failures that show up on a local run are unrelated — they only trip when DATABASE_SSL/DATABASE_DRIVER are set in the shell, which isn't the case in CI. They pass on CI and I left them untouched.

Fix:

  • Merged origin/master into the branch (brings in the api-route-catalog guardrail + the other master changes it was behind on). Clean merge, no conflicts.
  • Updated the /api/v1/overview sourceSha256 digest in api-route-catalog.ts from 7c9830…499089… to match the current route source. No classification/documentation change was needed (the route's shape is unchanged; only 4 lines were added).

Verification (all green locally):

  • bun run test:unitall workspaces pass (app 169 files / 3281 tests, db 39/455, mcp 25, constants 2) — exit 0
  • api-route-catalog.test.ts — 7/7 pass
  • bun run typecheck — clean
  • bun run lint — clean
  • bun run fmt — clean

Pushed as 5523298 (merge a02d659 + digest fix). CI will re-run on the update.
• branch chun/inferencex-app_overview

Comment thread packages/app/src/components/overview/overview-page.tsx Outdated
@chunfangamd chunfangamd changed the title feat(overview): fit the matrix on one screen and present it full screen / 总览矩阵收进一屏并支持全屏演示 feat(overview): fit the matrix on one screen and present it full screen / 一屏信息总览与全屏演示 Aug 11, 2026
chunfangamd and others added 3 commits August 11, 2026 01:44
… params

SemiAnalysisAI#718 landed a catalog that stores a SHA-256 of every API route source, so any
edit to a route has to come with a documentation and classification review.
This branch added `rows` and `hwrows` to `GET /api/v1/overview` before that
guard existed, so the merge left the digest stale and unit tests red.

The route stays `page-bff` and excluded from the public reference: the two new
parameters are more overview-UI-coupled projection, not a public contract. The
exclusion reason now names row scoping alongside the tier and comparison
projections it already listed.

中文:SemiAnalysisAI#718 引入了记录每个 API 路由源文件 SHA-256 的目录,任何路由改动都必须
伴随一次文档与分类审查。本分支在该守卫存在之前就为 `GET /api/v1/overview`
新增了 `rows` 与 `hwrows`,合并后摘要过期导致单元测试失败。

该路由仍归类为 `page-bff` 并排除在公开参考之外:新增的两个参数属于与概览界面
耦合的投影,而非公开契约。排除理由中现已在原有的档位与比较投影之外补上行范围。

Co-authored-by: Cursor <cursoragent@cursor.com>
Two overview e2e assertions encoded the pre-branch DOM and failed on both
browsers in shard 3.

The comparison tabs were asserted to be a direct child of the page section.
They now sit inside the surface handed to the Fullscreen API, because a
presentation that dropped its own view tabs would be a worse deck. Asserting
against the surface keeps the "exactly one, centred" guard and adds the
containment that fullscreen depends on.

The scenario cell was asserted by flattened text. Abbreviating AgentX in the
row header leaves the full name in an sr-only node, so that text now reads
"...(AgentX)AgentX". A helper checks the visible acronym and the accessible
full name as the two layers they are, rather than their concatenation.

中文:两条总览 e2e 断言写死了本分支之前的 DOM,在 shard 3 的两个浏览器上都失败。

其一断言对比标签页是页面区块的直接子元素。它现在位于交给 Fullscreen API 的容器
内,因为演示时丢掉自己的视图标签页会是更差的体验。改为针对该容器断言,既保留了
“有且仅有一个、居中”的约束,又补上了全屏所依赖的包含关系。

其二用扁平化文本断言场景单元格。行首缩写 AgentX 后,完整名称保留在 sr-only 节点
中,该文本因而变成“……(AgentX)AgentX”。新增的辅助函数按可见缩写与无障碍全称这两
个层次分别断言,而非断言二者的拼接结果。

Co-authored-by: Cursor <cursoragent@cursor.com>
SemiAnalysisAI#704 rebuilt the overview page under this branch: the navigation context split
into data/reference/controls, the matrix card grew a pending state, and both
surfaces moved behind `useWideViewport` instead of rendering twice. Three files
conflicted.

Resolution: master's structure wins everywhere it touched, with this branch's
changes reapplied on top of it — the row padding on master's per-row
`referenceCost` loop, `portalled={!presenting}` on master's context-derived
reference select, and the presentation surface and control row rebuilt against
`useOverviewData`/`useOverviewReference`. The row scopes join
`OverviewNavControl` so the focus restoration master added covers them too.

That refactor also made a latent bug concrete, which Bugbot reported on f4d5f6b:
presenting drops the phone list, but the matrix was still gated on the `xl`
viewport query, so a projector under 1280px showed an empty card. The deck lays
out at a fixed width and is scaled by `zoom`, so the viewport is the wrong thing
to ask — the matrix now drops the gate while presenting. Verified in a browser
at a 933px viewport in real fullscreen: the eight rows render where they
previously would not have.

中文:SemiAnalysisAI#704 在本分支之下重写了总览页:导航 context 拆分为数据/参考/控件,矩阵卡片
新增加载态,两种surface 改由 `useWideViewport` 择一渲染而非双份渲染。三个文件冲突。

解决方式:master 触及之处一律以其结构为准,再将本分支的改动叠加回去——行内边距叠
到 master 的逐行 `referenceCost` 循环上,`portalled={!presenting}` 叠到 master 由
context 推导的参考硬件选择器上,演示容器与控制栏则改用
`useOverviewData`/`useOverviewReference` 重建。两个行作用域也加入
`OverviewNavControl`,以纳入 master 新增的焦点恢复机制。

该重构同时让一处潜在缺陷显形,即 Bugbot 在 f4d5f6b 上报告的问题:演示时会移除手机
端列表,而矩阵仍受 `xl` 视口查询门控,因此低于 1280px 的投影仪只会看到一张空卡片。
演示画面以固定宽度布局并由 `zoom` 缩放,视口本就不是该问的对象——现在演示时直接去
掉该门控。已在浏览器中于 933px 视口、真实全屏下验证:此前无法显示的八行现已正常渲染。

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread packages/app/src/components/overview/overview-navigation.tsx
chunfangamd and others added 3 commits August 11, 2026 17:41
Pulls in SemiAnalysisAI#720 (Measured Energy axes). No conflicts: that change is confined
to the inference chart components and shares no files with the overview work
on this branch. Full unit suite, typecheck, lint and format are clean on the
merged tree.

Co-authored-by: Cursor <cursoragent@cursor.com>
The row filters moved the address bar and left every row on screen. SemiAnalysisAI#704
introduced `overviewDataKey`, which collapses equivalent URLs onto one cache
and request identity so a `ref` change repaints from the payload in hand. It
rebuilds that key from the params it knows, and this branch's `rows`/`hwrows`
arrived without being added — so a scoped URL keyed to the unfiltered payload
already in the cache, and the click resolved instantly against the full
matrix. The label reads from the response too, so it never flipped either.

Both scopes narrow the rows the server sends, and the dormant one still
reaches the payload that restores the other tab, so neither can be treated as
client-derived the way `ref` deliberately is. The route itself was always
correct: `?rows=changed` returns 2 of 8 rows.

Covered twice, because unit coverage alone is what let this through: the
provider must issue a request for each scope, and the overview e2e now clicks
the control and asserts the matrix actually shrinks.

中文:行过滤器只改动地址栏,矩阵一行不减。SemiAnalysisAI#704 引入的 `overviewDataKey` 把等价
URL 归一为同一个缓存与请求标识,好让切换 `ref` 直接用手头的数据重绘;它按已知
参数重建该 key,而本分支新增的 `rows`/`hwrows` 没有登记进去——于是带作用域的
URL 命中了缓存中未过滤的旧数据,点击瞬间“完成”却仍是完整矩阵。按钮文案同样取自
响应,因此也不会翻转。

两个作用域都会改变服务端返回的行,且休眠的那个仍要随载荷回传以恢复另一个标签页
的状态,所以都不能像 `ref` 那样按客户端自行推导处理。路由本身一直是对的:
`?rows=changed` 会把 8 行返回成 2 行。

补了两层测试,因为只有单测正是这个缺陷得以溜过的原因:provider 必须为每个作用域
发出请求,总览 e2e 则真实点击控件并断言矩阵确实变短。

Co-authored-by: Cursor <cursoragent@cursor.com>
Pulls in SemiAnalysisAI#722 and SemiAnalysisAI#723, two ETL run-override additions that exclude
unsupported AgentX results. No conflicts: they touch only
packages/db/src/etl/run-overrides.ts and share no file with the overview work
on this branch.

Co-authored-by: Cursor <cursoragent@cursor.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 872ef27. Configure here.

data.modelScope,
),
['compare'],
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arrow repeat flips views rapidly

Medium Severity

The present-mode arrow handler treats every keydown as a view page, including browser key-repeat events. With only two views, holding Left or Right oscillates between them and spams comparison fetches instead of advancing once per press.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 872ef27. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants