From fdef6b0489795b4b7f2f3482cadb1437d5c1ddc4 Mon Sep 17 00:00:00 2001 From: Ephraim Atta-Duncan Date: Wed, 13 Aug 2025 11:00:44 +0000 Subject: [PATCH] fix: documents and users count in the table --- .../tables/organisation-insights-table.tsx | 22 ++++++++---------- .../admin+/organisation-insights.$id.tsx | 23 +++++++++++-------- .../get-organisation-detailed-insights.ts | 16 ++++++++++--- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/apps/remix/app/components/tables/organisation-insights-table.tsx b/apps/remix/app/components/tables/organisation-insights-table.tsx index 4fe627b24..de2cdfb41 100644 --- a/apps/remix/app/components/tables/organisation-insights-table.tsx +++ b/apps/remix/app/components/tables/organisation-insights-table.tsx @@ -59,12 +59,12 @@ export const OrganisationInsightsTable = ({ { header: _(msg`Members`), accessorKey: 'memberCount', - cell: ({ row }) => row.getValue('memberCount'), + cell: ({ row }) => Number(row.getValue('memberCount')), }, { header: _(msg`Documents`), accessorKey: 'documentCount', - cell: ({ row }) => row.getValue('documentCount'), + cell: ({ row }) => Number(row.getValue('documentCount')), }, { header: _(msg`Created`), @@ -87,12 +87,12 @@ export const OrganisationInsightsTable = ({ { header: _(msg`Documents Created`), accessorKey: 'documentCount', - cell: ({ row }) => row.getValue('documentCount'), + cell: ({ row }) => Number(row.getValue('documentCount')), }, { header: _(msg`Documents Signed`), accessorKey: 'signedDocumentCount', - cell: ({ row }) => row.getValue('signedDocumentCount'), + cell: ({ row }) => Number(row.getValue('signedDocumentCount')), }, { header: _(msg`Joined`), @@ -170,14 +170,12 @@ export const OrganisationInsightsTable = ({ value: number; subtitle?: string; }) => ( -
-
- -
-

{title}

-

{value}

- {subtitle &&

{subtitle}

} -
+
+ +
+

{title}

+

{value}

+ {subtitle &&

{subtitle}

}
); diff --git a/apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx b/apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx index 3a70f7c81..24272e842 100644 --- a/apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx +++ b/apps/remix/app/routes/_authenticated+/admin+/organisation-insights.$id.tsx @@ -1,6 +1,7 @@ import { Trans } from '@lingui/react/macro'; import { getOrganisationDetailedInsights } from '@documenso/lib/server-only/admin/get-organisation-detailed-insights'; +import { getAdminOrganisation } from '@documenso/trpc/server/admin-router/get-admin-organisation'; import { OrganisationInsightsTable } from '~/components/tables/organisation-insights-table'; @@ -19,16 +20,20 @@ export async function loader({ params, request }: Route.LoaderArgs) { | 'allTime'; const view = (url.searchParams.get('view') || 'teams') as 'teams' | 'users' | 'documents'; - const insights = await getOrganisationDetailedInsights({ - organisationId: id, - page, - perPage, - dateRange, - view, - }); + const [insights, organisation] = await Promise.all([ + getOrganisationDetailedInsights({ + organisationId: id, + page, + perPage, + dateRange, + view, + }), + getAdminOrganisation({ organisationId: id }), + ]); return { organisationId: id, + organisationName: organisation.name, insights, page, perPage, @@ -38,13 +43,13 @@ export async function loader({ params, request }: Route.LoaderArgs) { } export default function OrganisationInsights({ loaderData }: Route.ComponentProps) { - const { organisationId, insights, page, perPage, dateRange, view } = loaderData; + const { insights, page, perPage, dateRange, view, organisationName } = loaderData; return (

- Organisation Insights + {organisationName}

diff --git a/packages/lib/server-only/admin/get-organisation-detailed-insights.ts b/packages/lib/server-only/admin/get-organisation-detailed-insights.ts index 9f401fc20..4232ac63c 100644 --- a/packages/lib/server-only/admin/get-organisation-detailed-insights.ts +++ b/packages/lib/server-only/admin/get-organisation-detailed-insights.ts @@ -122,12 +122,16 @@ async function getTeamInsights( .leftJoin('Document as d', (join) => join.onRef('t.id', '=', 'd.teamId').on('d.deletedAt', 'is', null), ) + .leftJoin('TeamGroup as tg', 'tg.teamId', 't.id') + .leftJoin('OrganisationGroup as og', 'og.id', 'tg.organisationGroupId') + .leftJoin('OrganisationGroupMember as ogm', 'ogm.groupId', 'og.id') + .leftJoin('OrganisationMember as om', 'om.id', 'ogm.organisationMemberId') .where('t.organisationId', '=', organisationId) .select([ 't.id as id', 't.name as name', 't.createdAt as createdAt', - sql`0`.as('memberCount'), + sql`COUNT(DISTINCT om."userId")`.as('memberCount'), sql`COUNT(DISTINCT CASE WHEN d.id IS NOT NULL ${dateFilter} THEN d.id END)`.as( 'documentCount', ), @@ -163,14 +167,20 @@ async function getUserInsights( const usersQuery = kyselyPrisma.$kysely .selectFrom('OrganisationMember as om') .innerJoin('User as u', 'u.id', 'om.userId') + .leftJoin('Document as d', (join) => + join.onRef('d.userId', '=', 'u.id').on('d.deletedAt', 'is', null), + ) + .leftJoin('Recipient as r', (join) => + join.onRef('r.email', '=', 'u.email').on('r.signedAt', 'is not', null), + ) .where('om.organisationId', '=', organisationId) .select([ 'u.id as id', 'u.name as name', 'u.email as email', 'u.createdAt as createdAt', - sql`0`.as('documentCount'), - sql`0`.as('signedDocumentCount'), + sql`COUNT(DISTINCT d.id)`.as('documentCount'), + sql`COUNT(DISTINCT r.id)`.as('signedDocumentCount'), ]) .groupBy(['u.id', 'u.name', 'u.email', 'u.createdAt']) .orderBy('u.createdAt', 'desc')