Skip to content

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components - #1252

Merged
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle
Jul 19, 2026
Merged

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components#1252
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle

Conversation

@jackwener

Copy link
Copy Markdown
Member

User verdict: 显示明细这部分的 UI 丑得要死,需要打磨和深度重构. Delivered both.

Restyle (drift → convergence)

  • White-pill active tab (Segmented misuse) → house underline TabsList + live count pills (请求 22 · 供应商 3 · 模型 5 · 工具 14 · 定价 0) — same primitive as skills/MCP.
  • Floating range+refresh → aligned toolbar (range cluster left, refresh trailing, shared centerline).
  • Bare header + bare 暂无 line → EmptyState primitive; tables get real structure: hairline separators, muted weight-medium headers, right-aligned tabular-nums numerics, one grow column absorbs slack (no more even-distribution gaps), scoped th headers.
  • StatTile tiles verified already-primitive; kept.

Deep refactor

One monolithic switch component → orchestrator + 5 per-tab components (Requests/Providers/Models/Tools/Pricing panels) funneling one shared typed UsageStatsTable (columns carry numeric/grow; single-table-consumer decision documented).

Coverage

New deterministic usage fixture seed (3 providers / 5 models / 6 tools / ~22 requests incl. an error row, fixed-clock literals); settings-usage added to the alignment auditor FIXTURES. settings-usage-contract fully re-pinned (all behavioral pins carried). CDP light+dark × all 5 tabs accepted by maintainer.

Known follow-up (out of renderer territory, reported not changed): settingsStore.usageStats aggregates byTool per-session so 工具统计 repeats tool names — data-layer fix queued.

Gates (merged tree incl. R6): desktop 2744 · ui 196 · typecheck · check-dead-css · knip ×2 = 0 · a11y/copy/console 0 · auditor all fixtures clean incl. settings-usage. Implemented by an opus worktree agent.

…structured tables
- Replace the activeTab Segmented (white-pill toggle) with the house
underline TabsList + count pills (skills / MCP language).
- Left-align the range segmented as one time cluster; push the refresh
to the row's trailing edge (space-between) so it stops floating.
- Split the five tab panels into per-tab components funneling through
one shared UsageStatsTable: hairline separators, muted+medium header
row, numeric columns right-aligned with tabular-nums, a grow column
that absorbs slack so numbers size to content.
- Empty tabs (定价配置 + any empty stats tab) render the EmptyState
primitive instead of a bare line under a bare header row.
…ture
Scope assertions to the new orchestrator / per-tab panel / shared table
blocks: underline TabsList with count pills, per-column alignment recipe,
EmptyState-backed empty tabs. Behavioral pins (optimistic draft, refresh
guard, request-filter scoping, label helpers) carried over unchanged.
… the auditor
- Add usageStatsSessions: 3 providers, 5 models, 6 tools (2 failing),
~22 request-log rows, gated to the settings-usage scenario so no other
capture shifts.
- Default the settings-usage fixture to 全部 + details-on: the seed uses
the fixed visual-smoke clock, which sits outside the store's real-time
24h/7天/30天 windows, so the populated tables only render deterministically
under 全部.
- Add settings-usage to the alignment auditor's fixture list.
@jackwener
jackwener merged commit 545b77a into mainJul 19, 2026
3 checks passed
jackwener added a commit that referenced this pull request Jul 20, 2026
…itive, dense health/permission rows, dialect cleanup (#1274)
* feat(ui): extract DataTable primitive from usage stats table
Promote the #1252 hairline table recipe out of usage-settings-page into a
shared DataTable primitive (@maka/ui) now that it has health + permission
consumers. The primitive owns the table markup: muted+medium scoped col
headers, first-cell-as-scoped-row-header, hairline row separators,
right-aligned tabular-nums numeric columns, and one grow column that absorbs
slack while the rest size to content on one line.
UsageStatsTable becomes a thin wrapper: it keeps the usage-local empty-tab
routing (EmptyState icon+copy) that a table primitive deliberately omits, and
delegates the non-empty branch to <DataTable>. Rendering is pixel-identical —
every utility class and the settingsUsageTable pin class are preserved.
Re-pin: the moved table markup is now guarded by packages/ui data-table.test
(renderToStaticMarkup); settings-usage-contract's stats-table assertions follow
the split — keep the wrapper's typed-column + EmptyState signature, assert
delegation to <DataTable>, and forbid a hand-rolled <table>.
* refactor(settings): kill the .settingsAboutPrivacy blue-header dialect
The uppercase brand-blue h3 + brand-deep tinted card was a fourth section-
header voice, used by 关于's privacy card AND (confusingly) 数据's 配置导入
导出 header — the reason 数据's export section wore a blue header.
Converge both onto the sanctioned language:
- 关于 privacy → SectionHeader (as=h3) + Alert variant=passive holding the
privacy points (a quiet 'just so you know' callout; matches the passive
Alert language already on the data page's backup notice).
- 数据 config → SectionHeader (as=h3, configHelp as subtitle) over the form
controls, no card chrome (it's a form, not a callout).
Widen SectionHeader's `as` to accept h3 (a section under a page h2). Delete
the .settingsAboutPrivacy CSS block (incl. the green ::marker) for neutral
gap containers. Re-pin radius-converge (drop the stale selector) and
settings-app-info (name now scopes at the section) contracts.
* polish(ui): converge search pre-search hint + fix gateway 5-tile grid
- search-modal: route the pre-search guidance line through the shared
EmptyState inline primitive instead of a bare <p>, so the 'start typing'
hint uses the sanctioned empty-state language (keeps the placeholder pin
class so layout is unchanged).
- open-gateway: the posture strip has five metric tiles but reused the
four-column .settingsUsageSummary grid, orphaning the fifth on a second
row. Give it .settingsGatewaySummary — 5-up on wide, clean 3-up (3 + 2)
wrap when the pane narrows.
* polish(permissions): drop the OS-row status stripe (#651)
Each OS-permission row already shows its state as a Badge; the left-edge
status stripe (amber on 等待授权, red on 已拒绝) was a redundant second status
channel, and the amber stripe read as a standing alarm on an expected waiting
state. Remove both stripe rules and the now-orphaned position:relative anchor;
the row's Chip/text is the single state signal (the denied icon tint stays as
the one exception accent).
* refactor(providers): converge .providerRootHeader onto SectionHeader
The 已连接 and 添加新连接 section titles were a bespoke flex header (bold h3
+ muted help + far-right count) — a fourth section-header dialect. Converge
both onto the shared SectionHeader primitive: title + subtitle, and the
connection count rides SectionHeader's count slot (tabular-nums baked in).
Extend SectionHeader with an optional titleId so the catalog section keeps
its aria-labelledby link. Delete the .providerRootHeader CSS family. Re-pin:
tabular-nums-converge (drop the removed selector, add a SectionHeader
primitive pin) and provider-navigation (catalog title now on SectionHeader
via titleId).
* polish(settings): converge health/permission onto dense shared-language rows
Polish wave (wave 2) — kill the bordered-block dialect on the Health and
Permission Center pages and the redundant gray intro banners.
- Item 2 (健康): HealthSignalRow bordered blocks -> shared Item row
primitive inside one hairline card; prose message + detail keep stacked
secondary lines, status is a squared Chip (exception-only color via its
tone scale), send/capability blockers are exception Chips. Meta on one
tabular-nums line. Deleted the bespoke .settingsHealthSignalRow* CSS.
- Item 3 (权限): CapabilityRow bordered blocks -> dense hairline-divided
rows in one card matching the OS permission list above; the nested gray
boxed .settingsCapabilityLayers dl becomes structured secondary lines
(no nested surface). readiness Badge -> Chip. Kept the dl + aria-label
and the diagnostics collapse.
- Item 5: the second gray-banner PageHeader on each page
(.settingsHealthIntro / .settingsPermissionIntro) restating the page
title -> SectionHeader; unique subtitle kept, badge/timestamp/refresh
moved into the action slot, banner chrome dropped.
Re-pins: radius-converge SELECTOR_TIER drops the retired
.settingsHealthIntro/.settingsPermissionIntro/.settingsCapabilityRow radius
entries and adds the new .settingsCapabilityList/.settingsHealthSignalList
card entries. roadmap-cleanup + capability-audit contracts unchanged.
Verified light+dark via direct CDP over settings-health / settings-permissions.
Gates: desktop main + @maka/ui suites, full typecheck, check-dead-css,
audit-alignment (settings-permissions clean) all green.
* test(gateway): re-pin summary-strip aria assertions to settingsGatewaySummary
Wave 1 renamed the tile strip class (fixing the 4+1 orphan grid) and kept
role=group + aria-label, but the network-gateway contract's regexes pinned
the old settingsUsageSummary class name — the one re-pin the wave missed.
Also corrects the earlier triage: the failure was branch-caused, not
pre-existing on main.
Sign up for freeto 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

@jackwener
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components by jackwener · Pull Request #1252 · apache/maka · GitHub
Skip to content

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components - #1252

Merged
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle
Jul 19, 2026
Merged

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components#1252
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle

Conversation

@jackwener

Copy link
Copy Markdown
Member

User verdict: 显示明细这部分的 UI 丑得要死,需要打磨和深度重构. Delivered both.

Restyle (drift → convergence)

  • White-pill active tab (Segmented misuse) → house underline TabsList + live count pills (请求 22 · 供应商 3 · 模型 5 · 工具 14 · 定价 0) — same primitive as skills/MCP.
  • Floating range+refresh → aligned toolbar (range cluster left, refresh trailing, shared centerline).
  • Bare header + bare 暂无 line → EmptyState primitive; tables get real structure: hairline separators, muted weight-medium headers, right-aligned tabular-nums numerics, one grow column absorbs slack (no more even-distribution gaps), scoped th headers.
  • StatTile tiles verified already-primitive; kept.

Deep refactor

One monolithic switch component → orchestrator + 5 per-tab components (Requests/Providers/Models/Tools/Pricing panels) funneling one shared typed UsageStatsTable (columns carry numeric/grow; single-table-consumer decision documented).

Coverage

New deterministic usage fixture seed (3 providers / 5 models / 6 tools / ~22 requests incl. an error row, fixed-clock literals); settings-usage added to the alignment auditor FIXTURES. settings-usage-contract fully re-pinned (all behavioral pins carried). CDP light+dark × all 5 tabs accepted by maintainer.

Known follow-up (out of renderer territory, reported not changed): settingsStore.usageStats aggregates byTool per-session so 工具统计 repeats tool names — data-layer fix queued.

Gates (merged tree incl. R6): desktop 2744 · ui 196 · typecheck · check-dead-css · knip ×2 = 0 · a11y/copy/console 0 · auditor all fixtures clean incl. settings-usage. Implemented by an opus worktree agent.

…structured tables
- Replace the activeTab Segmented (white-pill toggle) with the house
underline TabsList + count pills (skills / MCP language).
- Left-align the range segmented as one time cluster; push the refresh
to the row's trailing edge (space-between) so it stops floating.
- Split the five tab panels into per-tab components funneling through
one shared UsageStatsTable: hairline separators, muted+medium header
row, numeric columns right-aligned with tabular-nums, a grow column
that absorbs slack so numbers size to content.
- Empty tabs (定价配置 + any empty stats tab) render the EmptyState
primitive instead of a bare line under a bare header row.
…ture
Scope assertions to the new orchestrator / per-tab panel / shared table
blocks: underline TabsList with count pills, per-column alignment recipe,
EmptyState-backed empty tabs. Behavioral pins (optimistic draft, refresh
guard, request-filter scoping, label helpers) carried over unchanged.
… the auditor
- Add usageStatsSessions: 3 providers, 5 models, 6 tools (2 failing),
~22 request-log rows, gated to the settings-usage scenario so no other
capture shifts.
- Default the settings-usage fixture to 全部 + details-on: the seed uses
the fixed visual-smoke clock, which sits outside the store's real-time
24h/7天/30天 windows, so the populated tables only render deterministically
under 全部.
- Add settings-usage to the alignment auditor's fixture list.
@jackwener
jackwener merged commit 545b77a into mainJul 19, 2026
3 checks passed
jackwener added a commit that referenced this pull request Jul 20, 2026
…itive, dense health/permission rows, dialect cleanup (#1274)
* feat(ui): extract DataTable primitive from usage stats table
Promote the #1252 hairline table recipe out of usage-settings-page into a
shared DataTable primitive (@maka/ui) now that it has health + permission
consumers. The primitive owns the table markup: muted+medium scoped col
headers, first-cell-as-scoped-row-header, hairline row separators,
right-aligned tabular-nums numeric columns, and one grow column that absorbs
slack while the rest size to content on one line.
UsageStatsTable becomes a thin wrapper: it keeps the usage-local empty-tab
routing (EmptyState icon+copy) that a table primitive deliberately omits, and
delegates the non-empty branch to <DataTable>. Rendering is pixel-identical —
every utility class and the settingsUsageTable pin class are preserved.
Re-pin: the moved table markup is now guarded by packages/ui data-table.test
(renderToStaticMarkup); settings-usage-contract's stats-table assertions follow
the split — keep the wrapper's typed-column + EmptyState signature, assert
delegation to <DataTable>, and forbid a hand-rolled <table>.
* refactor(settings): kill the .settingsAboutPrivacy blue-header dialect
The uppercase brand-blue h3 + brand-deep tinted card was a fourth section-
header voice, used by 关于's privacy card AND (confusingly) 数据's 配置导入
导出 header — the reason 数据's export section wore a blue header.
Converge both onto the sanctioned language:
- 关于 privacy → SectionHeader (as=h3) + Alert variant=passive holding the
privacy points (a quiet 'just so you know' callout; matches the passive
Alert language already on the data page's backup notice).
- 数据 config → SectionHeader (as=h3, configHelp as subtitle) over the form
controls, no card chrome (it's a form, not a callout).
Widen SectionHeader's `as` to accept h3 (a section under a page h2). Delete
the .settingsAboutPrivacy CSS block (incl. the green ::marker) for neutral
gap containers. Re-pin radius-converge (drop the stale selector) and
settings-app-info (name now scopes at the section) contracts.
* polish(ui): converge search pre-search hint + fix gateway 5-tile grid
- search-modal: route the pre-search guidance line through the shared
EmptyState inline primitive instead of a bare <p>, so the 'start typing'
hint uses the sanctioned empty-state language (keeps the placeholder pin
class so layout is unchanged).
- open-gateway: the posture strip has five metric tiles but reused the
four-column .settingsUsageSummary grid, orphaning the fifth on a second
row. Give it .settingsGatewaySummary — 5-up on wide, clean 3-up (3 + 2)
wrap when the pane narrows.
* polish(permissions): drop the OS-row status stripe (#651)
Each OS-permission row already shows its state as a Badge; the left-edge
status stripe (amber on 等待授权, red on 已拒绝) was a redundant second status
channel, and the amber stripe read as a standing alarm on an expected waiting
state. Remove both stripe rules and the now-orphaned position:relative anchor;
the row's Chip/text is the single state signal (the denied icon tint stays as
the one exception accent).
* refactor(providers): converge .providerRootHeader onto SectionHeader
The 已连接 and 添加新连接 section titles were a bespoke flex header (bold h3
+ muted help + far-right count) — a fourth section-header dialect. Converge
both onto the shared SectionHeader primitive: title + subtitle, and the
connection count rides SectionHeader's count slot (tabular-nums baked in).
Extend SectionHeader with an optional titleId so the catalog section keeps
its aria-labelledby link. Delete the .providerRootHeader CSS family. Re-pin:
tabular-nums-converge (drop the removed selector, add a SectionHeader
primitive pin) and provider-navigation (catalog title now on SectionHeader
via titleId).
* polish(settings): converge health/permission onto dense shared-language rows
Polish wave (wave 2) — kill the bordered-block dialect on the Health and
Permission Center pages and the redundant gray intro banners.
- Item 2 (健康): HealthSignalRow bordered blocks -> shared Item row
primitive inside one hairline card; prose message + detail keep stacked
secondary lines, status is a squared Chip (exception-only color via its
tone scale), send/capability blockers are exception Chips. Meta on one
tabular-nums line. Deleted the bespoke .settingsHealthSignalRow* CSS.
- Item 3 (权限): CapabilityRow bordered blocks -> dense hairline-divided
rows in one card matching the OS permission list above; the nested gray
boxed .settingsCapabilityLayers dl becomes structured secondary lines
(no nested surface). readiness Badge -> Chip. Kept the dl + aria-label
and the diagnostics collapse.
- Item 5: the second gray-banner PageHeader on each page
(.settingsHealthIntro / .settingsPermissionIntro) restating the page
title -> SectionHeader; unique subtitle kept, badge/timestamp/refresh
moved into the action slot, banner chrome dropped.
Re-pins: radius-converge SELECTOR_TIER drops the retired
.settingsHealthIntro/.settingsPermissionIntro/.settingsCapabilityRow radius
entries and adds the new .settingsCapabilityList/.settingsHealthSignalList
card entries. roadmap-cleanup + capability-audit contracts unchanged.
Verified light+dark via direct CDP over settings-health / settings-permissions.
Gates: desktop main + @maka/ui suites, full typecheck, check-dead-css,
audit-alignment (settings-permissions clean) all green.
* test(gateway): re-pin summary-strip aria assertions to settingsGatewaySummary
Wave 1 renamed the tile strip class (fixing the 4+1 orphan grid) and kept
role=group + aria-label, but the network-gateway contract's regexes pinned
the old settingsUsageSummary class name — the one re-pin the wave missed.
Also corrects the earlier triage: the failure was branch-caused, not
pre-existing on main.
Sign up for freeto 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

@jackwener
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components by jackwener · Pull Request #1252 · apache/maka · GitHub
Skip to content

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components - #1252

Merged
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle
Jul 19, 2026
Merged

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components#1252
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle

Conversation

@jackwener

Copy link
Copy Markdown
Member

User verdict: 显示明细这部分的 UI 丑得要死,需要打磨和深度重构. Delivered both.

Restyle (drift → convergence)

  • White-pill active tab (Segmented misuse) → house underline TabsList + live count pills (请求 22 · 供应商 3 · 模型 5 · 工具 14 · 定价 0) — same primitive as skills/MCP.
  • Floating range+refresh → aligned toolbar (range cluster left, refresh trailing, shared centerline).
  • Bare header + bare 暂无 line → EmptyState primitive; tables get real structure: hairline separators, muted weight-medium headers, right-aligned tabular-nums numerics, one grow column absorbs slack (no more even-distribution gaps), scoped th headers.
  • StatTile tiles verified already-primitive; kept.

Deep refactor

One monolithic switch component → orchestrator + 5 per-tab components (Requests/Providers/Models/Tools/Pricing panels) funneling one shared typed UsageStatsTable (columns carry numeric/grow; single-table-consumer decision documented).

Coverage

New deterministic usage fixture seed (3 providers / 5 models / 6 tools / ~22 requests incl. an error row, fixed-clock literals); settings-usage added to the alignment auditor FIXTURES. settings-usage-contract fully re-pinned (all behavioral pins carried). CDP light+dark × all 5 tabs accepted by maintainer.

Known follow-up (out of renderer territory, reported not changed): settingsStore.usageStats aggregates byTool per-session so 工具统计 repeats tool names — data-layer fix queued.

Gates (merged tree incl. R6): desktop 2744 · ui 196 · typecheck · check-dead-css · knip ×2 = 0 · a11y/copy/console 0 · auditor all fixtures clean incl. settings-usage. Implemented by an opus worktree agent.

…structured tables
- Replace the activeTab Segmented (white-pill toggle) with the house
underline TabsList + count pills (skills / MCP language).
- Left-align the range segmented as one time cluster; push the refresh
to the row's trailing edge (space-between) so it stops floating.
- Split the five tab panels into per-tab components funneling through
one shared UsageStatsTable: hairline separators, muted+medium header
row, numeric columns right-aligned with tabular-nums, a grow column
that absorbs slack so numbers size to content.
- Empty tabs (定价配置 + any empty stats tab) render the EmptyState
primitive instead of a bare line under a bare header row.
…ture
Scope assertions to the new orchestrator / per-tab panel / shared table
blocks: underline TabsList with count pills, per-column alignment recipe,
EmptyState-backed empty tabs. Behavioral pins (optimistic draft, refresh
guard, request-filter scoping, label helpers) carried over unchanged.
… the auditor
- Add usageStatsSessions: 3 providers, 5 models, 6 tools (2 failing),
~22 request-log rows, gated to the settings-usage scenario so no other
capture shifts.
- Default the settings-usage fixture to 全部 + details-on: the seed uses
the fixed visual-smoke clock, which sits outside the store's real-time
24h/7天/30天 windows, so the populated tables only render deterministically
under 全部.
- Add settings-usage to the alignment auditor's fixture list.
@jackwener
jackwener merged commit 545b77a into mainJul 19, 2026
3 checks passed
jackwener added a commit that referenced this pull request Jul 20, 2026
…itive, dense health/permission rows, dialect cleanup (#1274)
* feat(ui): extract DataTable primitive from usage stats table
Promote the #1252 hairline table recipe out of usage-settings-page into a
shared DataTable primitive (@maka/ui) now that it has health + permission
consumers. The primitive owns the table markup: muted+medium scoped col
headers, first-cell-as-scoped-row-header, hairline row separators,
right-aligned tabular-nums numeric columns, and one grow column that absorbs
slack while the rest size to content on one line.
UsageStatsTable becomes a thin wrapper: it keeps the usage-local empty-tab
routing (EmptyState icon+copy) that a table primitive deliberately omits, and
delegates the non-empty branch to <DataTable>. Rendering is pixel-identical —
every utility class and the settingsUsageTable pin class are preserved.
Re-pin: the moved table markup is now guarded by packages/ui data-table.test
(renderToStaticMarkup); settings-usage-contract's stats-table assertions follow
the split — keep the wrapper's typed-column + EmptyState signature, assert
delegation to <DataTable>, and forbid a hand-rolled <table>.
* refactor(settings): kill the .settingsAboutPrivacy blue-header dialect
The uppercase brand-blue h3 + brand-deep tinted card was a fourth section-
header voice, used by 关于's privacy card AND (confusingly) 数据's 配置导入
导出 header — the reason 数据's export section wore a blue header.
Converge both onto the sanctioned language:
- 关于 privacy → SectionHeader (as=h3) + Alert variant=passive holding the
privacy points (a quiet 'just so you know' callout; matches the passive
Alert language already on the data page's backup notice).
- 数据 config → SectionHeader (as=h3, configHelp as subtitle) over the form
controls, no card chrome (it's a form, not a callout).
Widen SectionHeader's `as` to accept h3 (a section under a page h2). Delete
the .settingsAboutPrivacy CSS block (incl. the green ::marker) for neutral
gap containers. Re-pin radius-converge (drop the stale selector) and
settings-app-info (name now scopes at the section) contracts.
* polish(ui): converge search pre-search hint + fix gateway 5-tile grid
- search-modal: route the pre-search guidance line through the shared
EmptyState inline primitive instead of a bare <p>, so the 'start typing'
hint uses the sanctioned empty-state language (keeps the placeholder pin
class so layout is unchanged).
- open-gateway: the posture strip has five metric tiles but reused the
four-column .settingsUsageSummary grid, orphaning the fifth on a second
row. Give it .settingsGatewaySummary — 5-up on wide, clean 3-up (3 + 2)
wrap when the pane narrows.
* polish(permissions): drop the OS-row status stripe (#651)
Each OS-permission row already shows its state as a Badge; the left-edge
status stripe (amber on 等待授权, red on 已拒绝) was a redundant second status
channel, and the amber stripe read as a standing alarm on an expected waiting
state. Remove both stripe rules and the now-orphaned position:relative anchor;
the row's Chip/text is the single state signal (the denied icon tint stays as
the one exception accent).
* refactor(providers): converge .providerRootHeader onto SectionHeader
The 已连接 and 添加新连接 section titles were a bespoke flex header (bold h3
+ muted help + far-right count) — a fourth section-header dialect. Converge
both onto the shared SectionHeader primitive: title + subtitle, and the
connection count rides SectionHeader's count slot (tabular-nums baked in).
Extend SectionHeader with an optional titleId so the catalog section keeps
its aria-labelledby link. Delete the .providerRootHeader CSS family. Re-pin:
tabular-nums-converge (drop the removed selector, add a SectionHeader
primitive pin) and provider-navigation (catalog title now on SectionHeader
via titleId).
* polish(settings): converge health/permission onto dense shared-language rows
Polish wave (wave 2) — kill the bordered-block dialect on the Health and
Permission Center pages and the redundant gray intro banners.
- Item 2 (健康): HealthSignalRow bordered blocks -> shared Item row
primitive inside one hairline card; prose message + detail keep stacked
secondary lines, status is a squared Chip (exception-only color via its
tone scale), send/capability blockers are exception Chips. Meta on one
tabular-nums line. Deleted the bespoke .settingsHealthSignalRow* CSS.
- Item 3 (权限): CapabilityRow bordered blocks -> dense hairline-divided
rows in one card matching the OS permission list above; the nested gray
boxed .settingsCapabilityLayers dl becomes structured secondary lines
(no nested surface). readiness Badge -> Chip. Kept the dl + aria-label
and the diagnostics collapse.
- Item 5: the second gray-banner PageHeader on each page
(.settingsHealthIntro / .settingsPermissionIntro) restating the page
title -> SectionHeader; unique subtitle kept, badge/timestamp/refresh
moved into the action slot, banner chrome dropped.
Re-pins: radius-converge SELECTOR_TIER drops the retired
.settingsHealthIntro/.settingsPermissionIntro/.settingsCapabilityRow radius
entries and adds the new .settingsCapabilityList/.settingsHealthSignalList
card entries. roadmap-cleanup + capability-audit contracts unchanged.
Verified light+dark via direct CDP over settings-health / settings-permissions.
Gates: desktop main + @maka/ui suites, full typecheck, check-dead-css,
audit-alignment (settings-permissions clean) all green.
* test(gateway): re-pin summary-strip aria assertions to settingsGatewaySummary
Wave 1 renamed the tile strip class (fixing the 4+1 orphan grid) and kept
role=group + aria-label, but the network-gateway contract's regexes pinned
the old settingsUsageSummary class name — the one re-pin the wave missed.
Also corrects the earlier triage: the failure was branch-caused, not
pre-existing on main.
Sign up for freeto 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

@jackwener
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components by jackwener · Pull Request #1252 · apache/maka · GitHub
Skip to content

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components - #1252

Merged
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle
Jul 19, 2026
Merged

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components#1252
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle

Conversation

@jackwener

Copy link
Copy Markdown
Member

User verdict: 显示明细这部分的 UI 丑得要死,需要打磨和深度重构. Delivered both.

Restyle (drift → convergence)

  • White-pill active tab (Segmented misuse) → house underline TabsList + live count pills (请求 22 · 供应商 3 · 模型 5 · 工具 14 · 定价 0) — same primitive as skills/MCP.
  • Floating range+refresh → aligned toolbar (range cluster left, refresh trailing, shared centerline).
  • Bare header + bare 暂无 line → EmptyState primitive; tables get real structure: hairline separators, muted weight-medium headers, right-aligned tabular-nums numerics, one grow column absorbs slack (no more even-distribution gaps), scoped th headers.
  • StatTile tiles verified already-primitive; kept.

Deep refactor

One monolithic switch component → orchestrator + 5 per-tab components (Requests/Providers/Models/Tools/Pricing panels) funneling one shared typed UsageStatsTable (columns carry numeric/grow; single-table-consumer decision documented).

Coverage

New deterministic usage fixture seed (3 providers / 5 models / 6 tools / ~22 requests incl. an error row, fixed-clock literals); settings-usage added to the alignment auditor FIXTURES. settings-usage-contract fully re-pinned (all behavioral pins carried). CDP light+dark × all 5 tabs accepted by maintainer.

Known follow-up (out of renderer territory, reported not changed): settingsStore.usageStats aggregates byTool per-session so 工具统计 repeats tool names — data-layer fix queued.

Gates (merged tree incl. R6): desktop 2744 · ui 196 · typecheck · check-dead-css · knip ×2 = 0 · a11y/copy/console 0 · auditor all fixtures clean incl. settings-usage. Implemented by an opus worktree agent.

…structured tables
- Replace the activeTab Segmented (white-pill toggle) with the house
underline TabsList + count pills (skills / MCP language).
- Left-align the range segmented as one time cluster; push the refresh
to the row's trailing edge (space-between) so it stops floating.
- Split the five tab panels into per-tab components funneling through
one shared UsageStatsTable: hairline separators, muted+medium header
row, numeric columns right-aligned with tabular-nums, a grow column
that absorbs slack so numbers size to content.
- Empty tabs (定价配置 + any empty stats tab) render the EmptyState
primitive instead of a bare line under a bare header row.
…ture
Scope assertions to the new orchestrator / per-tab panel / shared table
blocks: underline TabsList with count pills, per-column alignment recipe,
EmptyState-backed empty tabs. Behavioral pins (optimistic draft, refresh
guard, request-filter scoping, label helpers) carried over unchanged.
… the auditor
- Add usageStatsSessions: 3 providers, 5 models, 6 tools (2 failing),
~22 request-log rows, gated to the settings-usage scenario so no other
capture shifts.
- Default the settings-usage fixture to 全部 + details-on: the seed uses
the fixed visual-smoke clock, which sits outside the store's real-time
24h/7天/30天 windows, so the populated tables only render deterministically
under 全部.
- Add settings-usage to the alignment auditor's fixture list.
@jackwener
jackwener merged commit 545b77a into mainJul 19, 2026
3 checks passed
jackwener added a commit that referenced this pull request Jul 20, 2026
…itive, dense health/permission rows, dialect cleanup (#1274)
* feat(ui): extract DataTable primitive from usage stats table
Promote the #1252 hairline table recipe out of usage-settings-page into a
shared DataTable primitive (@maka/ui) now that it has health + permission
consumers. The primitive owns the table markup: muted+medium scoped col
headers, first-cell-as-scoped-row-header, hairline row separators,
right-aligned tabular-nums numeric columns, and one grow column that absorbs
slack while the rest size to content on one line.
UsageStatsTable becomes a thin wrapper: it keeps the usage-local empty-tab
routing (EmptyState icon+copy) that a table primitive deliberately omits, and
delegates the non-empty branch to <DataTable>. Rendering is pixel-identical —
every utility class and the settingsUsageTable pin class are preserved.
Re-pin: the moved table markup is now guarded by packages/ui data-table.test
(renderToStaticMarkup); settings-usage-contract's stats-table assertions follow
the split — keep the wrapper's typed-column + EmptyState signature, assert
delegation to <DataTable>, and forbid a hand-rolled <table>.
* refactor(settings): kill the .settingsAboutPrivacy blue-header dialect
The uppercase brand-blue h3 + brand-deep tinted card was a fourth section-
header voice, used by 关于's privacy card AND (confusingly) 数据's 配置导入
导出 header — the reason 数据's export section wore a blue header.
Converge both onto the sanctioned language:
- 关于 privacy → SectionHeader (as=h3) + Alert variant=passive holding the
privacy points (a quiet 'just so you know' callout; matches the passive
Alert language already on the data page's backup notice).
- 数据 config → SectionHeader (as=h3, configHelp as subtitle) over the form
controls, no card chrome (it's a form, not a callout).
Widen SectionHeader's `as` to accept h3 (a section under a page h2). Delete
the .settingsAboutPrivacy CSS block (incl. the green ::marker) for neutral
gap containers. Re-pin radius-converge (drop the stale selector) and
settings-app-info (name now scopes at the section) contracts.
* polish(ui): converge search pre-search hint + fix gateway 5-tile grid
- search-modal: route the pre-search guidance line through the shared
EmptyState inline primitive instead of a bare <p>, so the 'start typing'
hint uses the sanctioned empty-state language (keeps the placeholder pin
class so layout is unchanged).
- open-gateway: the posture strip has five metric tiles but reused the
four-column .settingsUsageSummary grid, orphaning the fifth on a second
row. Give it .settingsGatewaySummary — 5-up on wide, clean 3-up (3 + 2)
wrap when the pane narrows.
* polish(permissions): drop the OS-row status stripe (#651)
Each OS-permission row already shows its state as a Badge; the left-edge
status stripe (amber on 等待授权, red on 已拒绝) was a redundant second status
channel, and the amber stripe read as a standing alarm on an expected waiting
state. Remove both stripe rules and the now-orphaned position:relative anchor;
the row's Chip/text is the single state signal (the denied icon tint stays as
the one exception accent).
* refactor(providers): converge .providerRootHeader onto SectionHeader
The 已连接 and 添加新连接 section titles were a bespoke flex header (bold h3
+ muted help + far-right count) — a fourth section-header dialect. Converge
both onto the shared SectionHeader primitive: title + subtitle, and the
connection count rides SectionHeader's count slot (tabular-nums baked in).
Extend SectionHeader with an optional titleId so the catalog section keeps
its aria-labelledby link. Delete the .providerRootHeader CSS family. Re-pin:
tabular-nums-converge (drop the removed selector, add a SectionHeader
primitive pin) and provider-navigation (catalog title now on SectionHeader
via titleId).
* polish(settings): converge health/permission onto dense shared-language rows
Polish wave (wave 2) — kill the bordered-block dialect on the Health and
Permission Center pages and the redundant gray intro banners.
- Item 2 (健康): HealthSignalRow bordered blocks -> shared Item row
primitive inside one hairline card; prose message + detail keep stacked
secondary lines, status is a squared Chip (exception-only color via its
tone scale), send/capability blockers are exception Chips. Meta on one
tabular-nums line. Deleted the bespoke .settingsHealthSignalRow* CSS.
- Item 3 (权限): CapabilityRow bordered blocks -> dense hairline-divided
rows in one card matching the OS permission list above; the nested gray
boxed .settingsCapabilityLayers dl becomes structured secondary lines
(no nested surface). readiness Badge -> Chip. Kept the dl + aria-label
and the diagnostics collapse.
- Item 5: the second gray-banner PageHeader on each page
(.settingsHealthIntro / .settingsPermissionIntro) restating the page
title -> SectionHeader; unique subtitle kept, badge/timestamp/refresh
moved into the action slot, banner chrome dropped.
Re-pins: radius-converge SELECTOR_TIER drops the retired
.settingsHealthIntro/.settingsPermissionIntro/.settingsCapabilityRow radius
entries and adds the new .settingsCapabilityList/.settingsHealthSignalList
card entries. roadmap-cleanup + capability-audit contracts unchanged.
Verified light+dark via direct CDP over settings-health / settings-permissions.
Gates: desktop main + @maka/ui suites, full typecheck, check-dead-css,
audit-alignment (settings-permissions clean) all green.
* test(gateway): re-pin summary-strip aria assertions to settingsGatewaySummary
Wave 1 renamed the tile strip class (fixing the 4+1 orphan grid) and kept
role=group + aria-label, but the network-gateway contract's regexes pinned
the old settingsUsageSummary class name — the one re-pin the wave missed.
Also corrects the earlier triage: the failure was branch-caused, not
pre-existing on main.
Sign up for freeto 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

@jackwener
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components by jackwener · Pull Request #1252 · apache/maka · GitHub
Skip to content

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components - #1252

Merged
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle
Jul 19, 2026
Merged

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components#1252
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle

Conversation

@jackwener

Copy link
Copy Markdown
Member

User verdict: 显示明细这部分的 UI 丑得要死,需要打磨和深度重构. Delivered both.

Restyle (drift → convergence)

  • White-pill active tab (Segmented misuse) → house underline TabsList + live count pills (请求 22 · 供应商 3 · 模型 5 · 工具 14 · 定价 0) — same primitive as skills/MCP.
  • Floating range+refresh → aligned toolbar (range cluster left, refresh trailing, shared centerline).
  • Bare header + bare 暂无 line → EmptyState primitive; tables get real structure: hairline separators, muted weight-medium headers, right-aligned tabular-nums numerics, one grow column absorbs slack (no more even-distribution gaps), scoped th headers.
  • StatTile tiles verified already-primitive; kept.

Deep refactor

One monolithic switch component → orchestrator + 5 per-tab components (Requests/Providers/Models/Tools/Pricing panels) funneling one shared typed UsageStatsTable (columns carry numeric/grow; single-table-consumer decision documented).

Coverage

New deterministic usage fixture seed (3 providers / 5 models / 6 tools / ~22 requests incl. an error row, fixed-clock literals); settings-usage added to the alignment auditor FIXTURES. settings-usage-contract fully re-pinned (all behavioral pins carried). CDP light+dark × all 5 tabs accepted by maintainer.

Known follow-up (out of renderer territory, reported not changed): settingsStore.usageStats aggregates byTool per-session so 工具统计 repeats tool names — data-layer fix queued.

Gates (merged tree incl. R6): desktop 2744 · ui 196 · typecheck · check-dead-css · knip ×2 = 0 · a11y/copy/console 0 · auditor all fixtures clean incl. settings-usage. Implemented by an opus worktree agent.

…structured tables
- Replace the activeTab Segmented (white-pill toggle) with the house
underline TabsList + count pills (skills / MCP language).
- Left-align the range segmented as one time cluster; push the refresh
to the row's trailing edge (space-between) so it stops floating.
- Split the five tab panels into per-tab components funneling through
one shared UsageStatsTable: hairline separators, muted+medium header
row, numeric columns right-aligned with tabular-nums, a grow column
that absorbs slack so numbers size to content.
- Empty tabs (定价配置 + any empty stats tab) render the EmptyState
primitive instead of a bare line under a bare header row.
…ture
Scope assertions to the new orchestrator / per-tab panel / shared table
blocks: underline TabsList with count pills, per-column alignment recipe,
EmptyState-backed empty tabs. Behavioral pins (optimistic draft, refresh
guard, request-filter scoping, label helpers) carried over unchanged.
… the auditor
- Add usageStatsSessions: 3 providers, 5 models, 6 tools (2 failing),
~22 request-log rows, gated to the settings-usage scenario so no other
capture shifts.
- Default the settings-usage fixture to 全部 + details-on: the seed uses
the fixed visual-smoke clock, which sits outside the store's real-time
24h/7天/30天 windows, so the populated tables only render deterministically
under 全部.
- Add settings-usage to the alignment auditor's fixture list.
@jackwener
jackwener merged commit 545b77a into mainJul 19, 2026
3 checks passed
jackwener added a commit that referenced this pull request Jul 20, 2026
…itive, dense health/permission rows, dialect cleanup (#1274)
* feat(ui): extract DataTable primitive from usage stats table
Promote the #1252 hairline table recipe out of usage-settings-page into a
shared DataTable primitive (@maka/ui) now that it has health + permission
consumers. The primitive owns the table markup: muted+medium scoped col
headers, first-cell-as-scoped-row-header, hairline row separators,
right-aligned tabular-nums numeric columns, and one grow column that absorbs
slack while the rest size to content on one line.
UsageStatsTable becomes a thin wrapper: it keeps the usage-local empty-tab
routing (EmptyState icon+copy) that a table primitive deliberately omits, and
delegates the non-empty branch to <DataTable>. Rendering is pixel-identical —
every utility class and the settingsUsageTable pin class are preserved.
Re-pin: the moved table markup is now guarded by packages/ui data-table.test
(renderToStaticMarkup); settings-usage-contract's stats-table assertions follow
the split — keep the wrapper's typed-column + EmptyState signature, assert
delegation to <DataTable>, and forbid a hand-rolled <table>.
* refactor(settings): kill the .settingsAboutPrivacy blue-header dialect
The uppercase brand-blue h3 + brand-deep tinted card was a fourth section-
header voice, used by 关于's privacy card AND (confusingly) 数据's 配置导入
导出 header — the reason 数据's export section wore a blue header.
Converge both onto the sanctioned language:
- 关于 privacy → SectionHeader (as=h3) + Alert variant=passive holding the
privacy points (a quiet 'just so you know' callout; matches the passive
Alert language already on the data page's backup notice).
- 数据 config → SectionHeader (as=h3, configHelp as subtitle) over the form
controls, no card chrome (it's a form, not a callout).
Widen SectionHeader's `as` to accept h3 (a section under a page h2). Delete
the .settingsAboutPrivacy CSS block (incl. the green ::marker) for neutral
gap containers. Re-pin radius-converge (drop the stale selector) and
settings-app-info (name now scopes at the section) contracts.
* polish(ui): converge search pre-search hint + fix gateway 5-tile grid
- search-modal: route the pre-search guidance line through the shared
EmptyState inline primitive instead of a bare <p>, so the 'start typing'
hint uses the sanctioned empty-state language (keeps the placeholder pin
class so layout is unchanged).
- open-gateway: the posture strip has five metric tiles but reused the
four-column .settingsUsageSummary grid, orphaning the fifth on a second
row. Give it .settingsGatewaySummary — 5-up on wide, clean 3-up (3 + 2)
wrap when the pane narrows.
* polish(permissions): drop the OS-row status stripe (#651)
Each OS-permission row already shows its state as a Badge; the left-edge
status stripe (amber on 等待授权, red on 已拒绝) was a redundant second status
channel, and the amber stripe read as a standing alarm on an expected waiting
state. Remove both stripe rules and the now-orphaned position:relative anchor;
the row's Chip/text is the single state signal (the denied icon tint stays as
the one exception accent).
* refactor(providers): converge .providerRootHeader onto SectionHeader
The 已连接 and 添加新连接 section titles were a bespoke flex header (bold h3
+ muted help + far-right count) — a fourth section-header dialect. Converge
both onto the shared SectionHeader primitive: title + subtitle, and the
connection count rides SectionHeader's count slot (tabular-nums baked in).
Extend SectionHeader with an optional titleId so the catalog section keeps
its aria-labelledby link. Delete the .providerRootHeader CSS family. Re-pin:
tabular-nums-converge (drop the removed selector, add a SectionHeader
primitive pin) and provider-navigation (catalog title now on SectionHeader
via titleId).
* polish(settings): converge health/permission onto dense shared-language rows
Polish wave (wave 2) — kill the bordered-block dialect on the Health and
Permission Center pages and the redundant gray intro banners.
- Item 2 (健康): HealthSignalRow bordered blocks -> shared Item row
primitive inside one hairline card; prose message + detail keep stacked
secondary lines, status is a squared Chip (exception-only color via its
tone scale), send/capability blockers are exception Chips. Meta on one
tabular-nums line. Deleted the bespoke .settingsHealthSignalRow* CSS.
- Item 3 (权限): CapabilityRow bordered blocks -> dense hairline-divided
rows in one card matching the OS permission list above; the nested gray
boxed .settingsCapabilityLayers dl becomes structured secondary lines
(no nested surface). readiness Badge -> Chip. Kept the dl + aria-label
and the diagnostics collapse.
- Item 5: the second gray-banner PageHeader on each page
(.settingsHealthIntro / .settingsPermissionIntro) restating the page
title -> SectionHeader; unique subtitle kept, badge/timestamp/refresh
moved into the action slot, banner chrome dropped.
Re-pins: radius-converge SELECTOR_TIER drops the retired
.settingsHealthIntro/.settingsPermissionIntro/.settingsCapabilityRow radius
entries and adds the new .settingsCapabilityList/.settingsHealthSignalList
card entries. roadmap-cleanup + capability-audit contracts unchanged.
Verified light+dark via direct CDP over settings-health / settings-permissions.
Gates: desktop main + @maka/ui suites, full typecheck, check-dead-css,
audit-alignment (settings-permissions clean) all green.
* test(gateway): re-pin summary-strip aria assertions to settingsGatewaySummary
Wave 1 renamed the tile strip class (fixing the 4+1 orphan grid) and kept
role=group + aria-label, but the network-gateway contract's regexes pinned
the old settingsUsageSummary class name — the one re-pin the wave missed.
Also corrects the earlier triage: the failure was branch-caused, not
pre-existing on main.
Sign up for freeto 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

@jackwener
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components by jackwener · Pull Request #1252 · apache/maka · GitHub
Skip to content

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components - #1252

Merged
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle
Jul 19, 2026
Merged

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components#1252
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle

Conversation

@jackwener

Copy link
Copy Markdown
Member

User verdict: 显示明细这部分的 UI 丑得要死,需要打磨和深度重构. Delivered both.

Restyle (drift → convergence)

  • White-pill active tab (Segmented misuse) → house underline TabsList + live count pills (请求 22 · 供应商 3 · 模型 5 · 工具 14 · 定价 0) — same primitive as skills/MCP.
  • Floating range+refresh → aligned toolbar (range cluster left, refresh trailing, shared centerline).
  • Bare header + bare 暂无 line → EmptyState primitive; tables get real structure: hairline separators, muted weight-medium headers, right-aligned tabular-nums numerics, one grow column absorbs slack (no more even-distribution gaps), scoped th headers.
  • StatTile tiles verified already-primitive; kept.

Deep refactor

One monolithic switch component → orchestrator + 5 per-tab components (Requests/Providers/Models/Tools/Pricing panels) funneling one shared typed UsageStatsTable (columns carry numeric/grow; single-table-consumer decision documented).

Coverage

New deterministic usage fixture seed (3 providers / 5 models / 6 tools / ~22 requests incl. an error row, fixed-clock literals); settings-usage added to the alignment auditor FIXTURES. settings-usage-contract fully re-pinned (all behavioral pins carried). CDP light+dark × all 5 tabs accepted by maintainer.

Known follow-up (out of renderer territory, reported not changed): settingsStore.usageStats aggregates byTool per-session so 工具统计 repeats tool names — data-layer fix queued.

Gates (merged tree incl. R6): desktop 2744 · ui 196 · typecheck · check-dead-css · knip ×2 = 0 · a11y/copy/console 0 · auditor all fixtures clean incl. settings-usage. Implemented by an opus worktree agent.

…structured tables
- Replace the activeTab Segmented (white-pill toggle) with the house
underline TabsList + count pills (skills / MCP language).
- Left-align the range segmented as one time cluster; push the refresh
to the row's trailing edge (space-between) so it stops floating.
- Split the five tab panels into per-tab components funneling through
one shared UsageStatsTable: hairline separators, muted+medium header
row, numeric columns right-aligned with tabular-nums, a grow column
that absorbs slack so numbers size to content.
- Empty tabs (定价配置 + any empty stats tab) render the EmptyState
primitive instead of a bare line under a bare header row.
…ture
Scope assertions to the new orchestrator / per-tab panel / shared table
blocks: underline TabsList with count pills, per-column alignment recipe,
EmptyState-backed empty tabs. Behavioral pins (optimistic draft, refresh
guard, request-filter scoping, label helpers) carried over unchanged.
… the auditor
- Add usageStatsSessions: 3 providers, 5 models, 6 tools (2 failing),
~22 request-log rows, gated to the settings-usage scenario so no other
capture shifts.
- Default the settings-usage fixture to 全部 + details-on: the seed uses
the fixed visual-smoke clock, which sits outside the store's real-time
24h/7天/30天 windows, so the populated tables only render deterministically
under 全部.
- Add settings-usage to the alignment auditor's fixture list.
@jackwener
jackwener merged commit 545b77a into mainJul 19, 2026
3 checks passed
jackwener added a commit that referenced this pull request Jul 20, 2026
…itive, dense health/permission rows, dialect cleanup (#1274)
* feat(ui): extract DataTable primitive from usage stats table
Promote the #1252 hairline table recipe out of usage-settings-page into a
shared DataTable primitive (@maka/ui) now that it has health + permission
consumers. The primitive owns the table markup: muted+medium scoped col
headers, first-cell-as-scoped-row-header, hairline row separators,
right-aligned tabular-nums numeric columns, and one grow column that absorbs
slack while the rest size to content on one line.
UsageStatsTable becomes a thin wrapper: it keeps the usage-local empty-tab
routing (EmptyState icon+copy) that a table primitive deliberately omits, and
delegates the non-empty branch to <DataTable>. Rendering is pixel-identical —
every utility class and the settingsUsageTable pin class are preserved.
Re-pin: the moved table markup is now guarded by packages/ui data-table.test
(renderToStaticMarkup); settings-usage-contract's stats-table assertions follow
the split — keep the wrapper's typed-column + EmptyState signature, assert
delegation to <DataTable>, and forbid a hand-rolled <table>.
* refactor(settings): kill the .settingsAboutPrivacy blue-header dialect
The uppercase brand-blue h3 + brand-deep tinted card was a fourth section-
header voice, used by 关于's privacy card AND (confusingly) 数据's 配置导入
导出 header — the reason 数据's export section wore a blue header.
Converge both onto the sanctioned language:
- 关于 privacy → SectionHeader (as=h3) + Alert variant=passive holding the
privacy points (a quiet 'just so you know' callout; matches the passive
Alert language already on the data page's backup notice).
- 数据 config → SectionHeader (as=h3, configHelp as subtitle) over the form
controls, no card chrome (it's a form, not a callout).
Widen SectionHeader's `as` to accept h3 (a section under a page h2). Delete
the .settingsAboutPrivacy CSS block (incl. the green ::marker) for neutral
gap containers. Re-pin radius-converge (drop the stale selector) and
settings-app-info (name now scopes at the section) contracts.
* polish(ui): converge search pre-search hint + fix gateway 5-tile grid
- search-modal: route the pre-search guidance line through the shared
EmptyState inline primitive instead of a bare <p>, so the 'start typing'
hint uses the sanctioned empty-state language (keeps the placeholder pin
class so layout is unchanged).
- open-gateway: the posture strip has five metric tiles but reused the
four-column .settingsUsageSummary grid, orphaning the fifth on a second
row. Give it .settingsGatewaySummary — 5-up on wide, clean 3-up (3 + 2)
wrap when the pane narrows.
* polish(permissions): drop the OS-row status stripe (#651)
Each OS-permission row already shows its state as a Badge; the left-edge
status stripe (amber on 等待授权, red on 已拒绝) was a redundant second status
channel, and the amber stripe read as a standing alarm on an expected waiting
state. Remove both stripe rules and the now-orphaned position:relative anchor;
the row's Chip/text is the single state signal (the denied icon tint stays as
the one exception accent).
* refactor(providers): converge .providerRootHeader onto SectionHeader
The 已连接 and 添加新连接 section titles were a bespoke flex header (bold h3
+ muted help + far-right count) — a fourth section-header dialect. Converge
both onto the shared SectionHeader primitive: title + subtitle, and the
connection count rides SectionHeader's count slot (tabular-nums baked in).
Extend SectionHeader with an optional titleId so the catalog section keeps
its aria-labelledby link. Delete the .providerRootHeader CSS family. Re-pin:
tabular-nums-converge (drop the removed selector, add a SectionHeader
primitive pin) and provider-navigation (catalog title now on SectionHeader
via titleId).
* polish(settings): converge health/permission onto dense shared-language rows
Polish wave (wave 2) — kill the bordered-block dialect on the Health and
Permission Center pages and the redundant gray intro banners.
- Item 2 (健康): HealthSignalRow bordered blocks -> shared Item row
primitive inside one hairline card; prose message + detail keep stacked
secondary lines, status is a squared Chip (exception-only color via its
tone scale), send/capability blockers are exception Chips. Meta on one
tabular-nums line. Deleted the bespoke .settingsHealthSignalRow* CSS.
- Item 3 (权限): CapabilityRow bordered blocks -> dense hairline-divided
rows in one card matching the OS permission list above; the nested gray
boxed .settingsCapabilityLayers dl becomes structured secondary lines
(no nested surface). readiness Badge -> Chip. Kept the dl + aria-label
and the diagnostics collapse.
- Item 5: the second gray-banner PageHeader on each page
(.settingsHealthIntro / .settingsPermissionIntro) restating the page
title -> SectionHeader; unique subtitle kept, badge/timestamp/refresh
moved into the action slot, banner chrome dropped.
Re-pins: radius-converge SELECTOR_TIER drops the retired
.settingsHealthIntro/.settingsPermissionIntro/.settingsCapabilityRow radius
entries and adds the new .settingsCapabilityList/.settingsHealthSignalList
card entries. roadmap-cleanup + capability-audit contracts unchanged.
Verified light+dark via direct CDP over settings-health / settings-permissions.
Gates: desktop main + @maka/ui suites, full typecheck, check-dead-css,
audit-alignment (settings-permissions clean) all green.
* test(gateway): re-pin summary-strip aria assertions to settingsGatewaySummary
Wave 1 renamed the tile strip class (fixing the 4+1 orphan grid) and kept
role=group + aria-label, but the network-gateway contract's regexes pinned
the old settingsUsageSummary class name — the one re-pin the wave missed.
Also corrects the earlier triage: the failure was branch-caused, not
pre-existing on main.
Sign up for freeto 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

@jackwener
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components by jackwener · Pull Request #1252 · apache/maka · GitHub
Skip to content

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components - #1252

Merged
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle
Jul 19, 2026
Merged

fix(usage): deep restyle of 使用统计 detail area — house tabs, real tables, per-tab components#1252
jackwener merged 4 commits into
mainfrom
fix/usage-stats-restyle

Conversation

@jackwener

Copy link
Copy Markdown
Member

User verdict: 显示明细这部分的 UI 丑得要死,需要打磨和深度重构. Delivered both.

Restyle (drift → convergence)

  • White-pill active tab (Segmented misuse) → house underline TabsList + live count pills (请求 22 · 供应商 3 · 模型 5 · 工具 14 · 定价 0) — same primitive as skills/MCP.
  • Floating range+refresh → aligned toolbar (range cluster left, refresh trailing, shared centerline).
  • Bare header + bare 暂无 line → EmptyState primitive; tables get real structure: hairline separators, muted weight-medium headers, right-aligned tabular-nums numerics, one grow column absorbs slack (no more even-distribution gaps), scoped th headers.
  • StatTile tiles verified already-primitive; kept.

Deep refactor

One monolithic switch component → orchestrator + 5 per-tab components (Requests/Providers/Models/Tools/Pricing panels) funneling one shared typed UsageStatsTable (columns carry numeric/grow; single-table-consumer decision documented).

Coverage

New deterministic usage fixture seed (3 providers / 5 models / 6 tools / ~22 requests incl. an error row, fixed-clock literals); settings-usage added to the alignment auditor FIXTURES. settings-usage-contract fully re-pinned (all behavioral pins carried). CDP light+dark × all 5 tabs accepted by maintainer.

Known follow-up (out of renderer territory, reported not changed): settingsStore.usageStats aggregates byTool per-session so 工具统计 repeats tool names — data-layer fix queued.

Gates (merged tree incl. R6): desktop 2744 · ui 196 · typecheck · check-dead-css · knip ×2 = 0 · a11y/copy/console 0 · auditor all fixtures clean incl. settings-usage. Implemented by an opus worktree agent.

…structured tables
- Replace the activeTab Segmented (white-pill toggle) with the house
underline TabsList + count pills (skills / MCP language).
- Left-align the range segmented as one time cluster; push the refresh
to the row's trailing edge (space-between) so it stops floating.
- Split the five tab panels into per-tab components funneling through
one shared UsageStatsTable: hairline separators, muted+medium header
row, numeric columns right-aligned with tabular-nums, a grow column
that absorbs slack so numbers size to content.
- Empty tabs (定价配置 + any empty stats tab) render the EmptyState
primitive instead of a bare line under a bare header row.
…ture
Scope assertions to the new orchestrator / per-tab panel / shared table
blocks: underline TabsList with count pills, per-column alignment recipe,
EmptyState-backed empty tabs. Behavioral pins (optimistic draft, refresh
guard, request-filter scoping, label helpers) carried over unchanged.
… the auditor
- Add usageStatsSessions: 3 providers, 5 models, 6 tools (2 failing),
~22 request-log rows, gated to the settings-usage scenario so no other
capture shifts.
- Default the settings-usage fixture to 全部 + details-on: the seed uses
the fixed visual-smoke clock, which sits outside the store's real-time
24h/7天/30天 windows, so the populated tables only render deterministically
under 全部.
- Add settings-usage to the alignment auditor's fixture list.
@jackwener
jackwener merged commit 545b77a into mainJul 19, 2026
3 checks passed
jackwener added a commit that referenced this pull request Jul 20, 2026
…itive, dense health/permission rows, dialect cleanup (#1274)
* feat(ui): extract DataTable primitive from usage stats table
Promote the #1252 hairline table recipe out of usage-settings-page into a
shared DataTable primitive (@maka/ui) now that it has health + permission
consumers. The primitive owns the table markup: muted+medium scoped col
headers, first-cell-as-scoped-row-header, hairline row separators,
right-aligned tabular-nums numeric columns, and one grow column that absorbs
slack while the rest size to content on one line.
UsageStatsTable becomes a thin wrapper: it keeps the usage-local empty-tab
routing (EmptyState icon+copy) that a table primitive deliberately omits, and
delegates the non-empty branch to <DataTable>. Rendering is pixel-identical —
every utility class and the settingsUsageTable pin class are preserved.
Re-pin: the moved table markup is now guarded by packages/ui data-table.test
(renderToStaticMarkup); settings-usage-contract's stats-table assertions follow
the split — keep the wrapper's typed-column + EmptyState signature, assert
delegation to <DataTable>, and forbid a hand-rolled <table>.
* refactor(settings): kill the .settingsAboutPrivacy blue-header dialect
The uppercase brand-blue h3 + brand-deep tinted card was a fourth section-
header voice, used by 关于's privacy card AND (confusingly) 数据's 配置导入
导出 header — the reason 数据's export section wore a blue header.
Converge both onto the sanctioned language:
- 关于 privacy → SectionHeader (as=h3) + Alert variant=passive holding the
privacy points (a quiet 'just so you know' callout; matches the passive
Alert language already on the data page's backup notice).
- 数据 config → SectionHeader (as=h3, configHelp as subtitle) over the form
controls, no card chrome (it's a form, not a callout).
Widen SectionHeader's `as` to accept h3 (a section under a page h2). Delete
the .settingsAboutPrivacy CSS block (incl. the green ::marker) for neutral
gap containers. Re-pin radius-converge (drop the stale selector) and
settings-app-info (name now scopes at the section) contracts.
* polish(ui): converge search pre-search hint + fix gateway 5-tile grid
- search-modal: route the pre-search guidance line through the shared
EmptyState inline primitive instead of a bare <p>, so the 'start typing'
hint uses the sanctioned empty-state language (keeps the placeholder pin
class so layout is unchanged).
- open-gateway: the posture strip has five metric tiles but reused the
four-column .settingsUsageSummary grid, orphaning the fifth on a second
row. Give it .settingsGatewaySummary — 5-up on wide, clean 3-up (3 + 2)
wrap when the pane narrows.
* polish(permissions): drop the OS-row status stripe (#651)
Each OS-permission row already shows its state as a Badge; the left-edge
status stripe (amber on 等待授权, red on 已拒绝) was a redundant second status
channel, and the amber stripe read as a standing alarm on an expected waiting
state. Remove both stripe rules and the now-orphaned position:relative anchor;
the row's Chip/text is the single state signal (the denied icon tint stays as
the one exception accent).
* refactor(providers): converge .providerRootHeader onto SectionHeader
The 已连接 and 添加新连接 section titles were a bespoke flex header (bold h3
+ muted help + far-right count) — a fourth section-header dialect. Converge
both onto the shared SectionHeader primitive: title + subtitle, and the
connection count rides SectionHeader's count slot (tabular-nums baked in).
Extend SectionHeader with an optional titleId so the catalog section keeps
its aria-labelledby link. Delete the .providerRootHeader CSS family. Re-pin:
tabular-nums-converge (drop the removed selector, add a SectionHeader
primitive pin) and provider-navigation (catalog title now on SectionHeader
via titleId).
* polish(settings): converge health/permission onto dense shared-language rows
Polish wave (wave 2) — kill the bordered-block dialect on the Health and
Permission Center pages and the redundant gray intro banners.
- Item 2 (健康): HealthSignalRow bordered blocks -> shared Item row
primitive inside one hairline card; prose message + detail keep stacked
secondary lines, status is a squared Chip (exception-only color via its
tone scale), send/capability blockers are exception Chips. Meta on one
tabular-nums line. Deleted the bespoke .settingsHealthSignalRow* CSS.
- Item 3 (权限): CapabilityRow bordered blocks -> dense hairline-divided
rows in one card matching the OS permission list above; the nested gray
boxed .settingsCapabilityLayers dl becomes structured secondary lines
(no nested surface). readiness Badge -> Chip. Kept the dl + aria-label
and the diagnostics collapse.
- Item 5: the second gray-banner PageHeader on each page
(.settingsHealthIntro / .settingsPermissionIntro) restating the page
title -> SectionHeader; unique subtitle kept, badge/timestamp/refresh
moved into the action slot, banner chrome dropped.
Re-pins: radius-converge SELECTOR_TIER drops the retired
.settingsHealthIntro/.settingsPermissionIntro/.settingsCapabilityRow radius
entries and adds the new .settingsCapabilityList/.settingsHealthSignalList
card entries. roadmap-cleanup + capability-audit contracts unchanged.
Verified light+dark via direct CDP over settings-health / settings-permissions.
Gates: desktop main + @maka/ui suites, full typecheck, check-dead-css,
audit-alignment (settings-permissions clean) all green.
* test(gateway): re-pin summary-strip aria assertions to settingsGatewaySummary
Wave 1 renamed the tile strip class (fixing the 4+1 orphan grid) and kept
role=group + aria-label, but the network-gateway contract's regexes pinned
the old settingsUsageSummary class name — the one re-pin the wave missed.
Also corrects the earlier triage: the failure was branch-caused, not
pre-existing on main.
Sign up for freeto 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

@jackwener