fix: update org stats table ui (#2924)

This commit is contained in:
David Nguyen
2026-06-03 16:48:20 +10:00
committed by GitHub
parent 0a21598fec
commit 7f796ed74e
2 changed files with 37 additions and 19 deletions
@@ -57,11 +57,13 @@ const getPeriodDivisor = (period: string): number => {
return new Date(Date.UTC(year, month, 0)).getUTCDate();
};
export type OrganisationStatsDisplayMode = 'usage' | 'quotas' | 'averages';
type AdminOrganisationStatsTableProps = {
showDailyAverages?: boolean;
displayMode?: OrganisationStatsDisplayMode;
};
export const AdminOrganisationStatsTable = ({ showDailyAverages = true }: AdminOrganisationStatsTableProps) => {
export const AdminOrganisationStatsTable = ({ displayMode = 'usage' }: AdminOrganisationStatsTableProps) => {
const { t } = useLingui();
const [searchParams, setSearchParams] = useSearchParams();
@@ -127,15 +129,19 @@ export const AdminOrganisationStatsTable = ({ showDailyAverages = true }: AdminO
};
const renderUsageCell = (used: number, quota: number | null) => {
if (showDailyAverages) {
return <span>~{formatPerDay(used)}/day</span>;
if (displayMode === 'averages') {
return formatPerDay(used);
}
return (
<span>
{used} / {quota === null ? '∞' : quota}
</span>
);
if (displayMode === 'quotas') {
return (
<span>
{used}/{quota === null ? '∞' : quota}
</span>
);
}
return <span>{used}</span>;
};
const sortableHeader = (label: string, column: OrderByColumn) => (
@@ -162,7 +168,7 @@ export const AdminOrganisationStatsTable = ({ showDailyAverages = true }: AdminO
header: t`Organisation`,
accessorKey: 'organisationName',
cell: ({ row }) => (
<Link to={`/admin/organisations/${row.original.organisationId}`} className="text-xs hover:underline">
<Link to={`/admin/organisations/${row.original.organisationId}`} className="text-sm hover:underline">
{row.original.organisationName}
</Link>
),
@@ -170,12 +176,12 @@ export const AdminOrganisationStatsTable = ({ showDailyAverages = true }: AdminO
{
header: t`Claim`,
accessorKey: 'originalClaimId',
cell: ({ row }) => <span className="text-muted-foreground text-xs">{row.original.originalClaimId ?? '—'}</span>,
cell: ({ row }) => <span className="text-muted-foreground text-sm">{row.original.originalClaimId ?? '—'}</span>,
},
{
header: t`Period`,
accessorKey: 'period',
cell: ({ row }) => <span className="text-xs">{row.original.period}</span>,
cell: ({ row }) => <span className="text-sm">{row.original.period}</span>,
},
{
header: () => sortableHeader(t`Documents`, 'documentCount'),
@@ -208,14 +214,14 @@ export const AdminOrganisationStatsTable = ({ showDailyAverages = true }: AdminO
// Without this, changing a filter (e.g. claimId) wouldn't refresh the memoised handler,
// and sorting would merge onto stale params and drop the active filter.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [t, orderByColumn, orderByDirection, period, showDailyAverages, searchParams]);
}, [t, orderByColumn, orderByDirection, period, displayMode, searchParams]);
return (
<div>
<DataTable
columns={columns}
data={results.data}
rowClassName="text-xs"
rowClassName="text-sm"
perPage={results.perPage}
currentPage={results.currentPage}
totalPages={results.totalPages}
@@ -10,7 +10,10 @@ import { useEffect, useMemo, useState } from 'react';
import { useLocation, useSearchParams } from 'react-router';
import { SettingsHeader } from '~/components/general/settings-header';
import { AdminOrganisationStatsTable } from '~/components/tables/admin-organisation-stats-table';
import {
AdminOrganisationStatsTable,
type OrganisationStatsDisplayMode,
} from '~/components/tables/admin-organisation-stats-table';
const ALL_CLAIMS_VALUE = 'all';
@@ -53,7 +56,7 @@ export default function OrganisationStats() {
const [searchQuery, setSearchQuery] = useState(() => searchParams?.get('query') ?? '');
const [displayMode, setDisplayMode] = useState<'quotas' | 'averages'>('quotas');
const [displayMode, setDisplayMode] = useState<OrganisationStatsDisplayMode>('usage');
const debouncedSearchQuery = useDebouncedValue(searchQuery, 500);
@@ -160,18 +163,27 @@ export default function OrganisationStats() {
</div>
<div className="mt-4">
<AdminOrganisationStatsTable showDailyAverages={displayMode === 'averages'} />
<AdminOrganisationStatsTable displayMode={displayMode} />
</div>
<RadioGroup
value={displayMode}
onValueChange={(value) => setDisplayMode(value === 'averages' ? 'averages' : 'quotas')}
onValueChange={(value) =>
setDisplayMode(value === 'quotas' ? 'quotas' : value === 'averages' ? 'averages' : 'usage')
}
className="mt-4 flex flex-col gap-3 rounded-lg border border-border p-4"
>
<div className="flex items-center gap-2">
<RadioGroupItem id="display-usage" value="usage" />
<label htmlFor="display-usage" className="text-muted-foreground text-sm">
<Trans>Show usage</Trans>
</label>
</div>
<div className="flex items-center gap-2">
<RadioGroupItem id="display-quotas" value="quotas" />
<label htmlFor="display-quotas" className="text-muted-foreground text-sm">
<Trans>Show quotas for documents, emails and API usages</Trans>
<Trans>Show usage with quotas</Trans>
</label>
</div>