V2 settings: rebuild the Stats tab to match the classic profile stats page - #1397
Merged
Paul Lizer (paullizer) merged 2 commits intoSep 3, 2026
Merged
Conversation
… page The V2 Stats tab was a placeholder: four hand-rolled SVG sparklines, a 7/30/90 selector, and no totals. The classic profile page's stats tab has considerably more, and all of it is already served by /api/user/activity-trends and /api/user/settings, so this is entirely a client change. Stats now covers lifetime totals with the stamp that qualifies them, a custom start-end range alongside the presets, sign-in and token line charts, created- versus-deleted bars for conversations and documents, a storage ring, a CSV export matching the classic one column for column, and the account card. Charts are drawn with the Chart.js already vendored under public/vendor/ and loaded on demand. The loader moves to lib/chartRuntime.ts and is shared with the inline chat charts, so whichever draws first pays for the script. Nothing is added to the main bundle and nothing is fetched from outside the application. The account menu's Profile entry is removed. It was a second destination for personal settings that existed because the classic profile page held the stats; with those rebuilt it leads nowhere V2 does not already cover. The classic deep links inside the Groups and Public tabs stay, since those tabs are unbuilt. Verified by rendering the built bundle against stubbed endpoints: all five charts draw in both themes, a reversed custom range is refused client-side, a valid one relabels from the server, and the export downloads a correct CSV. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Three conflicts, all from the base branch renumbering under this one. The conversation export and admin appearance parity PRs landed while this was open and took 0.261.039 and 0.261.040, so the version bump here moves to 0.261.041 and the release notes entries move to a new section above both. The other two were additive on both sides: the test table in REACT_V2_UI.md keeps the conversation export row alongside the two stats rows, and the release notes keep every section. Nothing in the merge disturbs the shared Chart.js loader. The base's changes to InlineChart.tsx did not touch it, and it added no second loader of its own, so lib/chartRuntime.ts remains the only one. Verified after merging: typecheck and build clean, 19 functional test files pass including the base branch's own conversation export and admin appearance tests, and the Stats tab still renders all five charts in both themes against the rebuilt bundle. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
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.
What this does
Rebuilds the Stats tab on the V2 Settings page so it covers what the classic profile page's stats tab covers, and removes the account menu's Profile entry now that it leads nowhere V2 does not already reach.
Why
The V2 Stats tab was a placeholder — four hand-rolled SVG sparklines, a 7/30/90 selector, no totals. The classic page had considerably more, and the account menu offered Profile as the way to get to it. Keeping both entries asked the user to choose between two destinations for personal settings without the information to make the choice, so the placeholder had to become the real thing before the second entry could go.
What the tab gained
The four totals are lifetime cached figures, and the tab now says when they were last worked out. That distinction is the classic page's and the placeholder had lost it — without the stamp, the cards read as figures for the period on screen.
No backend change
GET /api/user/activity-trendsandGET /api/user/settingsalready returned everything, including customstart_date/end_datewindows and the cachedmetricsblock. The whole change is in the SPA. The CSV is assembled in the browser from those same two responses, the way the classic page does it; an export endpoint would be a second implementation of totals that are on screen at the time.Charts
Drawn with the Chart.js already vendored at
application/v2_ui/public/vendor/chartjs-4.5.1/, loaded on demand. The loader moves out ofInlineChart.tsxintolib/chartRuntime.tsand is shared, so whichever of the two draws first fetches and evaluates the script and the other reuses it.It is not an npm dependency, so the main bundle is unchanged, and the bytes are served from the app's own origin —
default-src 'self'is untouched. The previous "plain SVG is enough" note inStatsTab.tsxargued against adding a charting package topackage.json; that is still true and still enforced by the test, but it never applied to a library the repository already ships.Account menu
Profileis removed; Settings is the single destination. The/profile?tab=groupsand/profile?tab=public-workspaceslinks inside the Groups and Public tabs stay — those are the "open in the classic UI" fallback for tabs V2 has not rebuilt, not profile navigation, and removing them would leave those capabilities unreachable.Verification
Beyond typecheck, build and the test suite, the built bundle was rendered in headless Chromium against stubbed endpoints, asserting behaviour rather than source:
window.labelThe full V2 and docs suite passes — 12/12 files, including
test_docs_app_surface_coverage.pyandtest_docs_site_quality.py.test_v2_stats_parity.pypins names: every trend field, query parameter and metrics key the tab reads is checked to exist server-side, each classic surface is checked to have a counterpart, and both chart consumers are checked to share the vendored runtime.test_v2_stats_logic.mjsexecutesuserStats.tsdirectly under Node against the cases that render perfectly while being wrong — a window sent as the wrong pair of parameters, a sparse series drawn against the wrong dates, the token series read by the wrong key, an export whose columns have slipped by one.Two judgment calls worth a look
0–3.0axis beside a47,188,095total, which reads as a contradiction. (The classic chart is worse here: itsprecision: 0ticks collapse every sub-million day to zero.)Documentation and version
docs/explanation/features/V2_STATS_TAB_PARITY.mddocs/explanation/features/REACT_V2_UI.mdupdated: personal settings, the vendored library table, the shared loader, the account menu, and the test tablev0.261.041config.py→0.261.041. Nothing underdeployers/, sodeployers/version.txtis untouchedOut of scope
The Preferences tab, deliberately — this change is scoped to Stats.
Rebased onto a moved base
The conversation export (#1395) and admin appearance parity (#1396) PRs landed while this was open and took
0.261.039and0.261.040.origin/paullizer-react-v2-uihas been merged in and this change renumbered to 0.261.041, with its release-notes entries moved to a new section above both.The three conflicts were all version-related. The other two were additive on both sides — the test table in
REACT_V2_UI.mdkeeps the conversation export row alongside the two stats rows, and the release notes keep every section.Worth noting for review: the base's changes to
InlineChart.tsxdid not touch the Chart.js loader and introduced no second loader of its own, solib/chartRuntime.tsremains the only one after the merge. Re-verified post-merge — typecheck and build clean, 19 functional test files pass including the base's own conversation export and admin appearance tests, and the Stats tab still renders all five charts in both themes.