feat: support attendee name and email filter on /bookings (#19565)

* feat: support attendee name and email filter on /bookings

* remove console log

* change label
This commit is contained in:
Eunjae Lee
2025-02-26 18:48:36 +01:00
committed by GitHub
parent 3c367dd2c8
commit 7a797490c8
6 changed files with 74 additions and 9 deletions
@@ -19,6 +19,7 @@ import {
useFilterValue,
ZMultiSelectFilterValue,
ZDateRangeFilterValue,
ZTextFilterValue,
} from "@calcom/features/data-table";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { RouterOutputs } from "@calcom/trpc/react";
@@ -114,6 +115,8 @@ function BookingsContent({ status }: BookingsProps) {
const teamIds = useFilterValue("teamId", ZMultiSelectFilterValue)?.data as number[] | undefined;
const userIds = useFilterValue("userId", ZMultiSelectFilterValue)?.data as number[] | undefined;
const dateRange = useFilterValue("dateRange", ZDateRangeFilterValue)?.data;
const attendeeName = useFilterValue("attendeeName", ZTextFilterValue);
const attendeeEmail = useFilterValue("attendeeEmail", ZTextFilterValue);
const query = trpc.viewer.bookings.get.useInfiniteQuery(
{
@@ -123,6 +126,8 @@ function BookingsContent({ status }: BookingsProps) {
eventTypeIds,
teamIds,
userIds,
attendeeName,
attendeeEmail,
afterStartDate: dateRange?.startDate ?? undefined,
beforeEndDate: dateRange?.endDate ?? undefined,
},
@@ -164,7 +169,7 @@ function BookingsContent({ status }: BookingsProps) {
}),
columnHelper.accessor((row) => row.type === "data" && row.booking.user?.id, {
id: "userId",
header: t("people"),
header: t("member"),
enableColumnFilter: true,
enableSorting: false,
cell: () => null,
@@ -175,6 +180,32 @@ function BookingsContent({ status }: BookingsProps) {
},
},
}),
columnHelper.accessor((row) => row, {
id: "attendeeName",
header: t("attendee_name"),
enableColumnFilter: true,
enableSorting: false,
cell: () => null,
filterFn: () => true,
meta: {
filter: {
type: ColumnFilterType.TEXT,
},
},
}),
columnHelper.accessor((row) => row, {
id: "attendeeEmail",
header: t("attendee_email_variable"),
enableColumnFilter: true,
enableSorting: false,
cell: () => null,
filterFn: () => true,
meta: {
filter: {
type: ColumnFilterType.TEXT,
},
},
}),
columnHelper.accessor((row) => row, {
id: "dateRange",
header: t("date_range"),
@@ -314,6 +345,8 @@ function BookingsContent({ status }: BookingsProps) {
eventTypeId: false,
teamId: false,
userId: false,
attendeeName: false,
attendeeEmail: false,
dateRange: false,
},
},
@@ -65,7 +65,7 @@ export function TextFilterOptions({ column }: TextFilterOptionsProps) {
)}
/>
<div className="bg-subtle -mx-3 mb-2 h-px" role="separator" />
<div className="bg-subtle -mx-3 my-2 h-px" role="separator" />
<div className="flex items-center justify-between">
<Button
@@ -54,7 +54,7 @@ export const useInsightsColumns = ({
}),
columnHelper.accessor("bookingUserId", {
id: "bookingUserId",
header: t("user"),
header: t("member"),
enableColumnFilter: true,
enableSorting: false,
meta: {
+3 -2
View File
@@ -1,3 +1,4 @@
import type { TextFilterValue } from "@calcom/features/data-table/lib/types";
import type { PrismaClient } from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { BookingStatus } from "@calcom/prisma/enums";
@@ -23,8 +24,8 @@ type GetOptions = {
teamIds?: number[] | undefined;
userIds?: number[] | undefined;
eventTypeIds?: number[] | undefined;
attendeeEmail?: string;
attendeeName?: string;
attendeeEmail?: string | TextFilterValue;
attendeeName?: string | TextFilterValue;
};
sort?: SortOptions;
};
@@ -1,6 +1,8 @@
import { Prisma as PrismaClientType } from "@prisma/client";
import dayjs from "@calcom/dayjs";
import { makeWhereClause } from "@calcom/features/data-table/lib/server";
import { isTextFilterValue } from "@calcom/features/data-table/lib/utils";
import { parseRecurringEvent, parseEventTypeColor } from "@calcom/lib";
import getAllUserBookings from "@calcom/lib/bookings/getAllUserBookings";
import logger from "@calcom/lib/logger";
@@ -266,20 +268,47 @@ export async function getBookings({
},
]
: []),
...(filters?.attendeeEmail
...(typeof filters?.attendeeEmail === "string"
? [
{
attendees: { some: { email: filters.attendeeEmail.trim() } },
},
]
: []),
...(filters?.attendeeName
...(isTextFilterValue(filters?.attendeeEmail)
? [
{
attendees: {
some: makeWhereClause({
columnName: "email",
filterValue: filters.attendeeEmail,
}),
},
},
]
: []),
...(typeof filters?.attendeeName === "string"
? [
{
attendees: { some: { name: filters.attendeeName.trim() } },
},
]
: []),
...(isTextFilterValue(filters?.attendeeName)
? [
{
attendees: {
some: makeWhereClause({
columnName: "name",
filterValue: filters.attendeeName,
}),
},
},
]
: []),
...(filters?.afterStartDate
? [
{
@@ -1,13 +1,15 @@
import { z } from "zod";
import { ZTextFilterValue } from "@calcom/features/data-table/lib/types";
export const ZGetInputSchema = z.object({
filters: z.object({
teamIds: z.number().array().optional(),
userIds: z.number().array().optional(),
status: z.enum(["upcoming", "recurring", "past", "cancelled", "unconfirmed"]).optional(),
eventTypeIds: z.number().array().optional(),
attendeeEmail: z.string().optional(),
attendeeName: z.string().optional(),
attendeeEmail: z.union([z.string(), ZTextFilterValue]).optional(),
attendeeName: z.union([z.string(), ZTextFilterValue]).optional(),
afterStartDate: z.string().optional(),
beforeEndDate: z.string().optional(),
afterUpdatedDate: z.string().optional(),