diff --git a/packages/features/insights/components/RoutingFormResponsesTable.tsx b/packages/features/insights/components/RoutingFormResponsesTable.tsx index be7db2fffb..d1b2b0ed71 100644 --- a/packages/features/insights/components/RoutingFormResponsesTable.tsx +++ b/packages/features/insights/components/RoutingFormResponsesTable.tsx @@ -28,6 +28,7 @@ import { dataTableFilter, useDataTable, ZDateRangeFilterValue, + ZMultiSelectFilterValue, ZSingleSelectFilterValue, DateRangeFilter, type FilterableColumn, @@ -280,7 +281,9 @@ export function RoutingFormResponsesTableContent() { const teamId = orgTeamsType === "team" ? selectedTeamId : undefined; const userId = orgTeamsType === "yours" ? session.data?.user.id : undefined; - const memberUserId = useFilterValue("bookingUserId", ZSingleSelectFilterValue)?.data as number | undefined; + const memberUserIds = useFilterValue("bookingUserId", ZMultiSelectFilterValue)?.data as + | number[] + | undefined; const routingFormId = useFilterValue("formId", ZSingleSelectFilterValue)?.data as string | undefined; const createdAtRange = useFilterValue("createdAt", ZDateRangeFilterValue)?.data; const startDate = createdAtRange?.startDate ?? dayjs().subtract(1, "week").startOf("day").toISOString(); @@ -317,7 +320,7 @@ export function RoutingFormResponsesTableContent() { startDate, endDate, userId, - memberUserId, + memberUserIds, isAll, routingFormId, columnFilters, @@ -361,7 +364,7 @@ export function RoutingFormResponsesTableContent() { enableColumnFilter: true, enableSorting: false, meta: { - filter: { type: "single_select" }, + filter: { type: "multi_select" }, }, cell: () => null, }), @@ -619,8 +622,8 @@ export function RoutingFormResponsesTableContent() { endDate={endDate} teamId={teamId} userId={userId} - isAll={isAll ?? false} - memberUserId={memberUserId} + isAll={isAll} + memberUserIds={memberUserIds} routingFormId={routingFormId} columnFilters={columnFilters} sorting={sorting} diff --git a/packages/features/insights/filters/Download/RoutingFormResponsesDownload.tsx b/packages/features/insights/filters/Download/RoutingFormResponsesDownload.tsx index 6026dc98cf..042f45414a 100644 --- a/packages/features/insights/filters/Download/RoutingFormResponsesDownload.tsx +++ b/packages/features/insights/filters/Download/RoutingFormResponsesDownload.tsx @@ -14,7 +14,7 @@ type RoutingData = RouterOutputs["viewer"]["insights"]["routingFormResponsesForD type Props = { teamId: number | undefined; userId: number | undefined; - memberUserId: number | undefined; + memberUserIds: number[] | undefined; routingFormId: string | undefined; isAll: boolean; startDate: string; @@ -31,7 +31,7 @@ type Batch = { export const RoutingFormResponsesDownload = ({ teamId, userId, - memberUserId, + memberUserIds, routingFormId, isAll, startDate, @@ -55,8 +55,8 @@ export const RoutingFormResponsesDownload = ({ startDate, endDate, userId, - memberUserId, - isAll: isAll ?? false, + memberUserIds, + isAll: isAll, routingFormId, columnFilters, sorting, diff --git a/packages/features/insights/server/raw-data.schema.ts b/packages/features/insights/server/raw-data.schema.ts index 8f63073da8..80ae6e8447 100644 --- a/packages/features/insights/server/raw-data.schema.ts +++ b/packages/features/insights/server/raw-data.schema.ts @@ -1,6 +1,8 @@ import z from "zod"; -const rawDataInputSchema = z.object({ +import { ZColumnFilter, ZSorting } from "@calcom/features/data-table"; + +export const rawDataInputSchema = z.object({ startDate: z.string(), endDate: z.string(), teamId: z.coerce.number().optional().nullable(), @@ -12,4 +14,18 @@ const rawDataInputSchema = z.object({ export type RawDataInput = z.infer; -export { rawDataInputSchema }; +export const routingFormResponsesInputSchema = z.object({ + startDate: z.string(), + endDate: z.string(), + teamId: z.coerce.number().optional(), + userId: z.coerce.number().optional(), + memberUserIds: z.number().array().optional(), + isAll: z.coerce.boolean(), + routingFormId: z.string().optional(), + cursor: z.number().optional(), + limit: z.number().optional(), + columnFilters: z.array(ZColumnFilter), + sorting: z.array(ZSorting), +}); + +export type RoutingFormResponsesInput = z.infer; diff --git a/packages/features/insights/server/routing-events.ts b/packages/features/insights/server/routing-events.ts index 014f908082..8bd351f675 100644 --- a/packages/features/insights/server/routing-events.ts +++ b/packages/features/insights/server/routing-events.ts @@ -9,13 +9,9 @@ import { routingFormResponseInDbSchema, } from "@calcom/app-store/routing-forms/zod"; import dayjs from "@calcom/dayjs"; -import type { - ColumnFilter, - TypedColumnFilter, - ColumnFilterType, - SortingState, -} from "@calcom/features/data-table"; +import type { ColumnFilter, TypedColumnFilter, ColumnFilterType } from "@calcom/features/data-table"; import { makeWhereClause, makeOrderBy } from "@calcom/features/data-table/lib/server"; +import type { RoutingFormResponsesInput } from "@calcom/features/insights/server/raw-data.schema"; import { readonlyPrisma as prisma } from "@calcom/prisma"; import type { BookingStatus } from "@calcom/prisma/enums"; @@ -42,6 +38,10 @@ type RoutingFormInsightsFilter = RoutingFormInsightsTeamFilter & { columnFilters: ColumnFilter[]; }; +type RoutingFormResponsesFilter = RoutingFormResponsesInput & { + organizationId: number | null; +}; + type WhereForTeamOrAllTeams = Pick; class RoutingEventsInsights { @@ -222,14 +222,10 @@ class RoutingEventsInsights { cursor, limit, userId, - memberUserId, + memberUserIds, columnFilters, sorting, - }: Omit & { - sorting: SortingState; - cursor?: number; - limit?: number; - }) { + }: RoutingFormResponsesFilter) { const formsTeamWhereCondition = await this.getWhereForTeamOrAllTeams({ userId, teamId, @@ -286,7 +282,7 @@ class RoutingEventsInsights { })), // memberUserId - ...(memberUserId && { bookingUserId: memberUserId }), + ...(memberUserIds && memberUserIds.length > 0 && { bookingUserId: { in: memberUserIds } }), // createdAt ...(startDate && @@ -369,14 +365,10 @@ class RoutingEventsInsights { cursor, limit, userId, - memberUserId, + memberUserIds, columnFilters, sorting, - }: Omit & { - sorting: SortingState; - cursor?: number; - limit?: number; - }) { + }: RoutingFormResponsesFilter) { const headersPromise = this.getRoutingFormHeaders({ userId, teamId, @@ -393,7 +385,7 @@ class RoutingEventsInsights { routingFormId, cursor, userId, - memberUserId, + memberUserIds, limit, columnFilters, sorting, diff --git a/packages/features/insights/server/trpc-router.ts b/packages/features/insights/server/trpc-router.ts index 5be1a133e5..f0da4df6d5 100644 --- a/packages/features/insights/server/trpc-router.ts +++ b/packages/features/insights/server/trpc-router.ts @@ -3,8 +3,10 @@ import md5 from "md5"; import { z } from "zod"; import dayjs from "@calcom/dayjs"; -import { ZColumnFilter, ZSorting } from "@calcom/features/data-table"; -import { rawDataInputSchema } from "@calcom/features/insights/server/raw-data.schema"; +import { + rawDataInputSchema, + routingFormResponsesInputSchema, +} from "@calcom/features/insights/server/raw-data.schema"; import { randomString } from "@calcom/lib/random"; import type { readonlyPrisma } from "@calcom/prisma"; import { BookingStatus } from "@calcom/prisma/enums"; @@ -1588,53 +1590,36 @@ export const insightsRouter = router({ return stats; }), routingFormResponses: userBelongsToTeamProcedure - .input( - rawDataInputSchema.extend({ - routingFormId: z.string().optional(), - cursor: z.number().optional(), - limit: z.number().optional(), - columnFilters: z.array(ZColumnFilter), - sorting: z.array(ZSorting), - }) - ) + .input(routingFormResponsesInputSchema) .query(async ({ ctx, input }) => { - const { startDate, endDate } = input; return await RoutingEventsInsights.getRoutingFormPaginatedResponses({ - teamId: input.teamId ?? null, - startDate, - endDate, - isAll: input.isAll ?? false, + teamId: input.teamId, + startDate: input.startDate, + endDate: input.endDate, + isAll: input.isAll, organizationId: ctx.user.organizationId ?? null, - routingFormId: input.routingFormId ?? null, + routingFormId: input.routingFormId, cursor: input.cursor, - userId: input.userId ?? null, - memberUserId: input.memberUserId ?? null, + userId: input.userId, + memberUserIds: input.memberUserIds, limit: input.limit, columnFilters: input.columnFilters, sorting: input.sorting, }); }), routingFormResponsesForDownload: userBelongsToTeamProcedure - .input( - rawDataInputSchema.extend({ - routingFormId: z.string().optional(), - cursor: z.number().optional(), - limit: z.number().optional(), - columnFilters: z.array(ZColumnFilter), - sorting: z.array(ZSorting), - }) - ) + .input(routingFormResponsesInputSchema) .query(async ({ ctx, input }) => { return await RoutingEventsInsights.getRoutingFormPaginatedResponsesForDownload({ - teamId: input.teamId ?? null, + teamId: input.teamId, startDate: input.startDate, endDate: input.endDate, - isAll: input.isAll ?? false, + isAll: input.isAll, organizationId: ctx.user.organizationId ?? null, - routingFormId: input.routingFormId ?? null, + routingFormId: input.routingFormId, cursor: input.cursor, - userId: input.userId ?? null, - memberUserId: input.memberUserId ?? null, + userId: input.userId, + memberUserIds: input.memberUserIds, limit: input.limit ?? BATCH_SIZE, columnFilters: input.columnFilters, sorting: input.sorting,