fix(server): dashboard query (#15195)

#### PR Dependency Tree


* **PR #15195** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Admin dashboard storage history now returns a continuous day-by-day
trend, carrying forward the last known workspace and blob storage values
for days without samples.
* Active member counts for workspace analytics were corrected to reflect
active workspace members.
* **New Features**
* Admin workspace member roles are now returned via a dedicated role
enum, serialized as enum name strings (e.g., `Owner`).
* **UI Improvements**
* Renamed key labels to “Active Members” and “Members and Invitations”;
member roles use pill badges and non-accepted statuses are shown.
* **Tests**
* Added E2E coverage for role enum serialization and strengthened
storage history assertions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-07-05 03:04:05 +08:00
committed by GitHub
parent 7cfedbd49d
commit 296a4c2f81
10 changed files with 451 additions and 149 deletions
@@ -102,14 +102,14 @@ export const useColumns = () => {
},
{
accessorKey: 'members',
header: () => <div className="text-xs font-medium">Members</div>,
header: () => <div className="text-xs font-medium">Active Members</div>,
cell: ({ row }) => {
const ws = row.original;
return (
<div className="flex flex-col text-xs gap-1">
<div className="flex gap-2">
<span className="font-medium">{ws.memberCount}</span>
<span className="text-muted-foreground">members</span>
<span className="text-muted-foreground">active members</span>
</div>
<div className="flex gap-2">
<span className="font-medium">{ws.publicPageCount}</span>
@@ -235,7 +235,10 @@ function WorkspacePanelContent({
value={formatBytes(workspace.blobSize)}
/>
<MetricCard label="Blob Count" value={`${workspace.blobCount}`} />
<MetricCard label="Members" value={`${workspace.memberCount}`} />
<MetricCard
label="Active Members"
value={`${workspace.memberCount}`}
/>
<MetricCard
label="Shared Pages"
value={`${workspace.publicPageCount}`}
@@ -243,12 +246,14 @@ function WorkspacePanelContent({
</div>
<div className="rounded-xl border border-border/60 bg-card shadow-sm">
<div className="px-3 py-2 text-sm font-medium">Members</div>
<div className="px-3 py-2 text-sm font-medium">
Members and Invitations
</div>
<Separator />
<div className="flex flex-col divide-y">
{memberList.length === 0 ? (
<div className="px-3 py-3 text-xs text-muted-foreground">
No members.
No members or invitations.
</div>
) : (
memberList.map(member => (
@@ -270,8 +275,15 @@ function WorkspacePanelContent({
{member.email}
</div>
</div>
<div className="ml-auto text-xs px-2 py-1 rounded border">
{member.role}
<div className="ml-auto flex flex-col items-end gap-1 text-xs">
<div className="rounded border px-2 py-1">
{member.role}
</div>
{member.status !== 'Accepted' ? (
<div className="text-muted-foreground">
{member.status}
</div>
) : null}
</div>
</div>
))