Skip to content

feat(overview): merge the matrix footer into one bar and dim stale data in flight / 合并矩阵页脚为单栏并在加载中淡化旧数据 - #744

Merged
edwingao28 merged 2 commits into
chun/inferencex-app_overviewfrom
wenyaogao/pr719-ui-polish
Aug 14, 2026
Merged

feat(overview): merge the matrix footer into one bar and dim stale data in flight / 合并矩阵页脚为单栏并在加载中淡化旧数据#744
edwingao28 merged 2 commits into
chun/inferencex-app_overviewfrom
wenyaogao/pr719-ui-polish

Conversation

@edwingao28

@edwingao28 edwingao28 commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #719 — UI/UX polish only, no behavior change to its features.

Summary

  • One footer bar instead of three stacked link rows. The methodology notes keep the card's left edge and the two scope filters ride the right as chips with count badges ("Hide blanks ④" / "Show inactive"). The full counted sentences stay on the accessible name and hover title. The card ends on a single rule, returning ~90px to the matrix on a laptop viewport.
  • Balanced control strip. The on-page strip now uses the same three-column skeleton as the presenting toolbar: view tabs stay centred on the matrix, and Present — now carrying an expand glyph, Exit a collapse glyph — anchors the right edge as an action instead of trailing the tabs like a third view.
  • Page and presentation states share one chip style. The footer chips are the same control the deck toolbar already showed, so entering Present no longer restyles the filters (the badge is dropped there, where it would be noise at projection size).
  • In-flight feedback. OverviewNavigationProvider exposes pending; a fetch still unresolved after 150ms dims the stale matrix to 60% opacity. Cache hits and fast responses stay under the delay and never flicker. The URL-driven server filtering, hover prefetch and client cache are untouched.

Test plan

中文说明

基于 #719 的增量 PR——仅打磨 UI/UX,不改变其功能行为。

  • 底部三条堆叠链接行合并为单条页脚栏。 方法学注释保持左侧,两个范围过滤器以带计数徽标的 chip 形式靠右("隐藏空行 ④"/"显示停用模型")。带计数的完整句子保留在无障碍名称与悬停提示中。卡片以单条分隔线收尾,在笔记本视口上为矩阵让出约 90px。
  • 控制条重新配平。 页面态控制条改用与演示态工具栏相同的三栏骨架:视图标签相对矩阵居中,Present(新增展开图标,Exit 为收起图标)右对齐为动作按钮,不再像第三个视图标签。
  • 页面态与演示态共用同一 chip 样式。 页脚 chip 即演示工具栏原有控件,进入演示不再改变过滤器外观(演示态省略徽标,投影尺寸下是噪声)。
  • 加载中反馈。 OverviewNavigationProvider 暴露 pending;请求超过 150ms 未返回时旧矩阵淡化至 60% 不透明度,缓存命中与快速响应不闪烁。URL 驱动的服务端过滤、悬停预取与客户端缓存均未改动。

Note

Low Risk
Client-side overview navigation and presentation UI only; no API or data-model changes, with tests for pending state and existing navigation race handling.

Overview
Overview UI polish on top of #719: layout and loading feedback, not new filtering behavior.

The matrix card footer is one bar—methodology notes on the left, row/model scope controls as chips with count badges on the right (full counted sentences on aria-label/title). Scope toggles use the same chip style in the footer and presentation toolbar; presentation drops the badge.

The control strip matches the presenting toolbar’s three-column layout: view tabs centered, Present (expand/collapse icons) anchored on the right.

OverviewNavigationProvider exposes pending; the matrix card dims to 60% opacity after a 150ms delay while a selector fetch is in flight, and clears on success or failure. Unit tests cover pending lifecycle; Cypress zh locale asserts the short chip label plus full aria-label.

Reviewed by Cursor Bugbot for commit 0385d4b. Bugbot is set up for automated code reviews on this repo. Configure here.

@edwingao28
edwingao28 requested a review from adibarra as a code owner August 14, 2026 21:01
@vercel

vercel Bot commented Aug 14, 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 14, 2026 9:42pm

Request Review

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edwingao28's task in 5m 21s —— View job


Review: overview footer merge & in-flight dimming

🟢 LGTM — no blocking issues found.

  • Read the full diff against origin/chun/inferencex-app_overview
  • Static review of all 5 changed files
  • Runtime verification via Playwright
  • Checked CI status

I reviewed the code statically and verified it at runtime against the dev server.

Static review

  • overview-navigation.tsx — the new pending flag is correctly gated by navigationIdRef: a stale response that loses the navigationId race returns early in both .then and .catch, so it never clears pending for a newer navigation, and the latest navigation always settles it. No stuck-true path (the [initialData, initialHref] effect also resets it). pending is properly added to the useMemo deps.
  • overview-page.tsx / overview-scorecard.tsx — footer merge into a single bordered bar looks right; the border-t moved cleanly from each child <nav>/methodology block to the shared container. ScopeChipCount renders only for variant === 'section', so the badge is correctly dropped in the presenting toolbar. aria-label/title now carry the full counted sentence in both variants (matches the updated overview.cy.ts assertion).
  • The 150ms-delay opacity approach (delay-150 on the pending branch only) achieves the "no flicker under the threshold" intent purely in CSS.

Runtime verification (/overview?models=all&compare=30d)

  • ✅ Single footer bar: methodology left, Hide unchanged ⑨ + Hide inactive chips right.
  • ✅ Present mode: chips keep the same style and drop the count badge (Hide unchanged / Hide inactive, no 9); expand/collapse glyph on the toggle.
  • ✅ In-flight dimming: switching tiers sets data-pending="true" on the matrix card during the fetch and flips back to false + opacity-100 on resolve.
  • ✅ 0 console errors (the 2 left-pattern-full.svg preload warnings are pre-existing and unrelated).

CI: Claude (route), Vercel pass; tests-*/lint not yet reported at review time — assume the merge gate covers them.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 63cca8f8ce

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/app/src/components/overview/overview-page.tsx
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edwingao28's task in 1m 34s —— View job


Re-review: overview footer merge & in-flight dimming

🟢 LGTM — no blocking issues found. New commit 0385d4b resolves the one open review thread.

  • Read full diff vs origin/chun/inferencex-app_overview
  • Focus on new commit 0385d4b (pending lifecycle tests)
  • Static review of changed files
  • Runtime verification via Playwright
  • Check CI status

This re-review covers the delta since the prior LGTM on 63cca8f — i.e. commit 0385d4b, which adds the pending-lifecycle tests that address Codex's P1 (missing coverage for the dimming state).

New test commit (0385d4b)

  • overview-navigation.test.tsx — the two added cases correctly exercise the lifecycle the P1 asked for: a held-open fetch asserts pending flips true in flight, then clears on resolution (case 1) and on rejection (case 2 — the permanently-dimmed regression). The failure case also asserts data/tier stays on the prior selection (50), so the matrix isn't left dimmed over data it still shows. Solid coverage.
  • I agree with the author's reply that unit is the right layer here: the 150 ms threshold is a CSS delay-150, not JS state, so the timing itself isn't meaningfully assertable from Cypress any more precisely than from jsdom. What matters — the pending flag never sticking true — is what these tests pin.

Static review of the rest — consistent with the prior pass; nothing new to flag. The pending flag is still correctly guarded by the navigationId race in both .then/.catch (a stale response returns early and never clears a newer navigation's pending), and the [initialData, initialHref] effect resets it. pending is in the useMemo deps.

Runtime verification (/overview?models=all&compare=30d)

  • ✅ Single footer bar: border-t container with methodology left, scope chips right (overview-methodology and both toggles share one flex … border-t parent — no per-child rules).
  • ✅ Row-scope chip: Hide unchanged + badge 9, full sentence Hide 9 rows with no 30-day change on aria-label.
  • ✅ Model-scope chip: Hide inactive, full sentence Hide deprecated & maintenance-mode models on aria-label/title (matches the updated overview.cy.ts / zh assertion).
  • ✅ Matrix card: data-pending="false"opacity-100, transition-opacity duration-200 present for the dimming path.
  • ✅ 0 console errors (the SVG preload warnings are pre-existing and unrelated).

CI: typecheck/lint/test:unit and fixtures-e2e are covered by the dedicated tests-*/lint workflows (not re-run here). The only runs surfaced against this head are the Claude jobs; assume the merge gate covers the rest.

@edwingao28
edwingao28 merged commit a64befc into chun/inferencex-app_overview Aug 14, 2026
10 checks passed
@edwingao28
edwingao28 deleted the wenyaogao/pr719-ui-polish branch August 14, 2026 22:32
edwingao28 added a commit that referenced this pull request Aug 17, 2026
…en / 一屏信息总览与全屏演示 (#719)

* feat(overview): fit the matrix on one screen and present it full screen

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下不能一屏放下所有信息的局限。方法:全屏显示

* fix(overview): keep the dormant row scope on the URL

`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 #719.

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

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

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

* fix(overview): update /api/v1/overview route digest after merge

The api-route-catalog guardrail (added on master) pins a SHA-256 of each
route's source. This PR added 4 lines to the overview route, so its stored
digest was stale once master was merged in. Update it to match the current
source; no classification/documentation change is needed.

中文:master 引入的 api-route-catalog 守卫会对每个路由源码计算 SHA-256 摘要。
本 PR 为 overview 路由新增了 4 行,合并 master 后其存储的摘要已过期。此处将摘要
更新为与当前源码一致,无需改动分类或文档。

Co-authored-by: Alec Ibarra <93070681+adibarra@users.noreply.github.com>

* chore(api): re-register the overview route digest after the row-scope params

#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.

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

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

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

* test(overview): assert the DOM this branch actually renders

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>

* fix(overview): key the client data cache on the row scopes

The row filters moved the address bar and left every row on screen. #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.

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

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

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

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

* feat(overview): merge the matrix footer into one bar and dim stale data in flight / 合并矩阵页脚为单栏并在加载中淡化旧数据 (#744)

* feat(overview): merge the matrix footer into one bar and dim stale data in flight

* test(overview): cover the pending lifecycle across success and failure

* test(overview): assert the flipped row-filter chip by its accessible name

* fix(overview): page one view per arrow press while presenting

* fix(overview): render the window menu in place while presenting

* fix(overview): name the active window in the row-filter copy

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Alec Ibarra <93070681+adibarra@users.noreply.github.com>
Co-authored-by: Wenyao Gao <105094497+edwingao28@users.noreply.github.com>
Co-authored-by: Wenyao Gao <wgao11@u.rochester.edu>
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.

1 participant