fix(ui): restore data-label coverage and colspan parity in the admin models table - #162
Merged
Merged
Conversation
…models table `renderAdminModels()` was the only one of the seven table renderers that violated the interface conventions documented in `ui/README.md`, in two ways at once (both introduced by the same commit that created the table, 98a7a9b): 1. `data-label` coverage was 1 of 8 cells. Under `@media (max-width:560px)` the thead is hidden and each row is rendered as a card via `td::before { content: attr(data-label) }`, so seven of the eight fields were displayed without any label. The other six renderers are complete (mk-body 7/7, share-body 8/8, api-keys 6/6, emp-body 7/7, dept-body 7/7, ops-body 4/4). Added the seven missing labels as literal strings, matching the existing convention used by the other renderers (they are all literal rather than i18n-driven). 2. The empty and error rows used `colspan=7` against an eight-column table (the 读图 column has existed since the table was created), so the cell under-covered the table: measured in Chrome at 1400px the cell was 984px of a 1044px table, leaving a 60px gap. Both rows now use `colspan=8`. Bumped the asset cache-bust to 20260911-7. Verified in a headless Chrome A/B harness, with both the baseline and the fixed tree produced by the same generator (baseline rebuilt from git HEAD): card mode @<=560px goes from 1/8 to 8/8 labelled cells over the same seven identity-keyed cells, while desktop keeps the thead rendered; the desktop error row goes from 94.3% to 100% of the table width. Mobile card mode is unaffected by the colspan change (thead hidden -> block layout).
7 tasks
argszero
added a commit
that referenced
this pull request
Sep 13, 2026
ui/ writes each table's column count by hand in several places — the <thead>, the empty-state emptyRow(N, …) colspan, the load-failure loadErrorRow(N, …) colspan, and the number of <td> in the row template. Nothing fails at runtime when they disagree: a short colspan just paints the row narrow, a long one is silently clipped, and the empty/error row is only visible when the list is empty or the request failed. That is how #97 happened (adding an 8th column to the admin models table left the empty state at colspan=7); #162 only fixed the symptom by hand. src/table_gate.rs is a test-only gate in the same shape as catalog_gate.rs and i18n_pack.rs (#[cfg(test)] in main.rs, zero new dependencies, no regex, no JS execution, no browser). It reads ui/index.html and ui/js/app.js as text and asserts, for every <tbody> table: - positive control: exactly the seven registered tables are found, each with its true <thead> column count (a scanner bug that returns an empty set fails here instead of letting the set assertions pass vacuously); - emptyRow(N) colspan == the table's column count; - loadErrorRow(N) colspan == the table's column count; - the row template has exactly one <td> per column, with whole-row colspan cells (the marketplace detail row) excluded; - the only literal colspan is that detail row, and index.html contains none; - the transactions table derives its colspan from columns.length instead of hard-coding a number; - <tbody> containers receive <tr>-shaped rows (loadErrorRow) and never a bare <div> — the browser hoists a bare <div> out of the table and the retry button then loses setLiveError's container-level delegation. The assertions are split per dimension so a single failure names the dimension that drifted. Site-to-container attribution is positional (the nearest preceding $("#id").innerHTML assignment / setLiveError($("#id"), …)), not a JS parse. Tests: 9 new; cargo test 226 -> 235, fmt and clippy clean. A/B: six mutations, each applied alone and restored byte-identically (md5 verified), produce five distinct red sets — empty colspan, thead column count, row-template cell count, error-row colspan, and the literal/dynamic colspan pair. An 8th thead column and an unregistered new table both trip the positive control (same assertion, different inputs — recorded honestly). The unmutated tree is green on all six legs, as a live control.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
renderAdminModels()(admin 模型管理 table,#model-body) was the only one of the seven table renderers that broke the interface conventions documented inui/README.md— and it broke two of them at once. Both were introduced by the same commit that created the table (98a7a9b), i.e. the table has shipped this way since birth.1.
data-labelcoverage was 1 of 8 cells.The README states the convention twice (所有表格 td 必须带
data-label, enforced bytd::before { content: attr(data-label) }under@media (max-width:560px)). Under 560px the thead is hidden and every row is rendered as a card, so seven of the eight fields appeared with no label at all. The other six renderers are complete:mk-body7/7,share-body8/8,api-keys6/6,emp-body7/7,dept-body7/7,ops-body4/4. The seven missing labels (厂商 / 模型 / 输入价 / 输出价 / 上下文 / 最大输出 / 读图) were added as literal strings, matching the existing convention — the other renderers' ~30 labels are all literals, not i18n-driven, so a literal set is the minimal consistent change.2. Empty/error rows used
colspan=7against an eight-column table.The 读图 column has been present since the table was created, so
loadErrorRow(7, …)/emptyRow(7, …)under-covered the table. The other six renderers' colspan arguments all match their own column counts exactly (7/8/6/7/7/4).Bumped the asset cache-bust
20260911-6→20260911-7(5 refs inui/index.html).Related Issue
Changes
ui/js/app.js— add the 7 missingdata-labelattributes inrenderAdminModels(); changeloadErrorRow(7,…)andemptyRow(7,…)to8.ui/index.html— cache-bust-6→-7(CSS + 4 scripts).Tests
cargo test全部通过 — 148 passed; 0 failed.cargo fmt --check通过.cargo clippy --all-targets -- -D warnings通过(无新增 warning).Measured before/after evidence (headless Chrome, both trees produced by the same generator; baseline rebuilt from git
HEAD, matched by identity key = cell text):matchMediatrue, theaddisplay:none)table-header-group, 8 cellsGate:
node --check×4 OK; i18n key-set parity 762 == 762, 0 unresolved static keys.Checklist
fix/admin-models-data-label-colspan)fix(ui): …)