Skip to content

Dashboard: statistics, charts and a customizable widget layout - #257

Merged
windischb merged 4 commits into
developfrom
claude/dashboard-stats-diagrams-2aca2f
Oct 10, 2026
Merged

windischb merged 4 commits into
developfrom
claude/dashboard-stats-diagrams-2aca2f

Conversation

@windischb

Copy link
Copy Markdown
Contributor

The dashboard becomes a catalog of widgets on a 12-column grid, with statistics and charts, and an arrangement each user can change.

What it does

  • Statistics and charts. Sign-ins per day (successful / failed, 30 days), sign-in methods, security events by severity with the most frequent warnings and errors, counts for the directory and the application surface, four headline numbers. The charts are plain SVG components on the design-system tokens — no chart dependency.
  • Three layers of arrangement. A user's own layout, else the realm default an admin set, else the layout built into the app. Widgets can be reordered, resized, removed and added in an edit mode; realm-settings:write can save or remove the realm default.
  • Per-widget settings. A placement can carry options: which counts the directory and applications widgets show, how many rows the list widgets show.
  • Personal widgets for every signed-in user: account security, own sessions, "My apps" (the clients the account holds a valid authorization with), "My passkeys".

Backend

  • GET /api/dashboard/stats — counts plus per-day series, aggregated in SQL and bucketed by the viewer's calendar day. Each block is computed only when the caller holds the permission guarding the matching list surface, and is omitted otherwise.
  • GET /api/dashboard/my-apps — strictly the caller's own valid authorizations, one row per client.
  • GET/PUT/DELETE /api/dashboard/layout for the caller's own arrangement; PUT/DELETE /api/admin/dashboard/default-layout (realm-settings:write) for the realm default. A layout is shape-checked only and grants nothing: the widget catalog lives in the frontend, and a widget the viewer may not see drops out at render time.
  • A permanent erase drops the user's arrangement.

Fixed along the way

The old "failed attempts, 24h" tile read a Level field the security-log endpoint never returned. The number now comes from the statistics endpoint.

Verification

  • 15 integration tests in DashboardEndpointsTests (day buckets in the viewer's zone, failure streaks, withheld blocks without permission, per-user layout, realm default gating, options, my-apps).
  • Frontend type check; walked through in the browser against a dev database (display, tooltip, dark mode, narrow width, save / reset / realm default, widget settings).
  • Not verified: reordering by dragging with a real mouse (only with synthetic drag events; the arrow buttons do the same), and the rendering of "My apps" / "My passkeys" in a browser. The full backend suite was not run locally.

Not in this PR

  • The realm default layout is not part of the realm manifest (export / import).
  • No documentation page for the dashboard yet.

🤖 Generated with Claude Code

windischb and others added 4 commits October 10, 2026 10:55
… realm default

The dashboard becomes a catalog of widgets on a 12-column grid. Which widgets
show, in which order and how wide resolves in three layers: the user's own
arrangement, the realm default an admin set, the layout built into the app.

Backend
- GET /api/dashboard/stats: counts plus per-day login and security-event
  series, aggregated in SQL and bucketed by the viewer's calendar day. Each
  block is computed only when the caller holds the permission guarding the
  matching list surface and is omitted otherwise.
- GET/PUT/DELETE /api/dashboard/layout for the caller's own arrangement;
  PUT/DELETE /api/admin/dashboard/default-layout (realm-settings:write) for
  the realm default. A layout is shape-checked only and grants nothing.
- A permanent erase drops the user's arrangement.

Frontend
- TrendChart (line/area with crosshair tooltip) and DonutChart as plain SVG
  components on the design-system tokens, no chart dependency.
- Thirteen widgets; an edit mode to reorder, resize, remove and add them, and
  for realm-settings:write to save or remove the realm default.

The old "failed attempts, 24h" tile read a Level field the security-log
endpoint never returned; the number now comes from the statistics endpoint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…egend drops below the ring when narrow

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dgets

- A placement can carry options (option key -> chosen values). In edit mode a
  gear opens the widget's settings: which counts the directory and
  applications widgets show, how many rows the list widgets show.
- Counts for positions (behind the PositionTerminals feature), OAuth APIs and
  OAuth scopes, each behind the permission of its list.
- GET /api/dashboard/my-apps: the clients the caller holds a valid
  authorization with, one row per client.
- New personal widgets "My apps" and "My passkeys".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@windischb
windischb enabled auto-merge (squash) October 10, 2026 14:10
@windischb
windischb merged commit 4451067 into develop Oct 10, 2026
8 checks passed
@windischb
windischb deleted the claude/dashboard-stats-diagrams-2aca2f branch October 10, 2026 14:44
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