mirror of
https://github.com/documenso/documenso.git
synced 2026-09-29 16:24:30 +10:00
feat(admin): show team count in organisation stats
This commit is contained in:
@@ -12,7 +12,7 @@ import { ChevronDownIcon, ChevronsUpDownIcon, ChevronUpIcon } from 'lucide-react
|
||||
import { useMemo } from 'react';
|
||||
import { Link, useSearchParams } from 'react-router';
|
||||
|
||||
type OrderByColumn = 'documentCount' | 'emailCount' | 'apiCount' | 'emailReports' | 'totalCount';
|
||||
type OrderByColumn = 'documentCount' | 'emailCount' | 'apiCount' | 'emailReports' | 'teamCount' | 'totalCount';
|
||||
type OrderByDirection = 'asc' | 'desc';
|
||||
|
||||
const parseOrderByColumn = (value: string | undefined): OrderByColumn | undefined => {
|
||||
@@ -21,6 +21,7 @@ const parseOrderByColumn = (value: string | undefined): OrderByColumn | undefine
|
||||
value === 'emailCount' ||
|
||||
value === 'apiCount' ||
|
||||
value === 'emailReports' ||
|
||||
value === 'teamCount' ||
|
||||
value === 'totalCount'
|
||||
) {
|
||||
return value;
|
||||
@@ -178,6 +179,11 @@ export const AdminOrganisationStatsTable = ({ displayMode = 'usage' }: AdminOrga
|
||||
accessorKey: 'originalClaimId',
|
||||
cell: ({ row }) => <span className="text-muted-foreground text-sm">{row.original.originalClaimId ?? '—'}</span>,
|
||||
},
|
||||
{
|
||||
header: () => sortableHeader(t`Teams`, 'teamCount'),
|
||||
accessorKey: 'teamCount',
|
||||
cell: ({ row }) => row.original.teamCount,
|
||||
},
|
||||
{
|
||||
header: t`Period`,
|
||||
accessorKey: 'period',
|
||||
@@ -240,6 +246,9 @@ export const AdminOrganisationStatsTable = ({ displayMode = 'usage' }: AdminOrga
|
||||
<TableCell>
|
||||
<Skeleton className="h-4 w-24 rounded-full" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4 w-10 rounded-full" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4 w-16 rounded-full" />
|
||||
</TableCell>
|
||||
|
||||
@@ -32,7 +32,7 @@ type FindOrganisationStatsOptions = {
|
||||
claimId?: string;
|
||||
page?: number;
|
||||
perPage?: number;
|
||||
orderByColumn?: 'documentCount' | 'emailCount' | 'apiCount' | 'emailReports' | 'totalCount';
|
||||
orderByColumn?: 'documentCount' | 'emailCount' | 'apiCount' | 'emailReports' | 'teamCount' | 'totalCount';
|
||||
orderByDirection?: 'asc' | 'desc';
|
||||
};
|
||||
|
||||
@@ -95,6 +95,12 @@ export const findOrganisationStats = async ({
|
||||
'OrganisationClaim.documentQuota as documentQuota',
|
||||
'OrganisationClaim.emailQuota as emailQuota',
|
||||
'OrganisationClaim.apiQuota as apiQuota',
|
||||
// Teams have no monthly history, so this is the current count for every period.
|
||||
eb
|
||||
.selectFrom('Team')
|
||||
.whereRef('Team.organisationId', '=', 'Organisation.id')
|
||||
.select(sql<number>`count("Team"."id")`.as('count'))
|
||||
.as('teamCount'),
|
||||
totalCountExpression.as('totalCount'),
|
||||
eb.fn.countAll().over().as('totalRows'),
|
||||
])
|
||||
@@ -104,6 +110,7 @@ export const findOrganisationStats = async ({
|
||||
.with('emailCount', () => qb.orderBy('OrganisationMonthlyStat.emailCount', orderByDirection))
|
||||
.with('apiCount', () => qb.orderBy('OrganisationMonthlyStat.apiCount', orderByDirection))
|
||||
.with('emailReports', () => qb.orderBy('OrganisationMonthlyStat.emailReports', orderByDirection))
|
||||
.with('teamCount', () => qb.orderBy('teamCount', orderByDirection))
|
||||
.with('totalCount', () => qb.orderBy(totalCountExpression, orderByDirection))
|
||||
.with(undefined, () =>
|
||||
// Default ordering mirrors the desired SQL: email, api, document descending.
|
||||
@@ -132,6 +139,7 @@ export const findOrganisationStats = async ({
|
||||
emailCount: Number(row.emailCount),
|
||||
apiCount: Number(row.apiCount),
|
||||
emailReports: Number(row.emailReports),
|
||||
teamCount: Number(row.teamCount),
|
||||
documentQuota: row.documentQuota === null ? null : Number(row.documentQuota),
|
||||
emailQuota: row.emailQuota === null ? null : Number(row.emailQuota),
|
||||
apiQuota: row.apiQuota === null ? null : Number(row.apiQuota),
|
||||
|
||||
@@ -9,7 +9,7 @@ export const ZFindOrganisationStatsRequestSchema = ZFindSearchParamsSchema.exten
|
||||
.optional(),
|
||||
claimId: z.string().describe('Filter stats by the original subscription claim ID.').optional(),
|
||||
orderByColumn: z
|
||||
.enum(['documentCount', 'emailCount', 'apiCount', 'emailReports', 'totalCount'])
|
||||
.enum(['documentCount', 'emailCount', 'apiCount', 'emailReports', 'teamCount', 'totalCount'])
|
||||
.describe('The column to sort by.')
|
||||
.optional(),
|
||||
orderByDirection: z.enum(['asc', 'desc']).describe('Sort direction.').default('desc'),
|
||||
@@ -27,6 +27,7 @@ export const ZFindOrganisationStatsResponseSchema = ZFindResultResponse.extend({
|
||||
emailCount: z.number(),
|
||||
apiCount: z.number(),
|
||||
emailReports: z.number(),
|
||||
teamCount: z.number(),
|
||||
documentQuota: z.number().nullable(),
|
||||
emailQuota: z.number().nullable(),
|
||||
apiQuota: z.number().nullable(),
|
||||
|
||||
Reference in New Issue
Block a user