feat: filter bookings by event type (#9011)

* filter bookings by event type

* fix: hide event-types sections not having atleast 1 event-type

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
mohammed hussam 2023-05-26 13:19:13 +05:30 committed by GitHub
parent e4a16a86a4
commit 781e0e361d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 34 deletions

View File

@ -1,12 +1,14 @@
import { useSession } from "next-auth/react";
import { Fragment, useState, useEffect } from "react";
import { Fragment, useState } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import { AnimatedPopover } from "@calcom/ui";
import { Checkbox } from "@calcom/ui";
import { groupBy } from "../groupBy";
import { useFilterQuery } from "../lib/useFilterQuery";
export type IEventTypesFilters = RouterOutputs["viewer"]["eventTypes"]["listWithTeam"];
export type IEventTypeFilter = IEventTypesFilters[0];
@ -27,24 +29,32 @@ type GroupedEventTypeState = Record<
export const EventTypeFilter = () => {
const { t } = useLocale();
const { data: user } = useSession();
const eventTypes = trpc.viewer.eventTypes.listWithTeam.useQuery();
const { data: query, pushItemToKey, removeItemByKeyAndValue } = useFilterQuery();
const [groupedEventTypes, setGroupedEventTypes] = useState<GroupedEventTypeState>();
// Will be handled up the tree to redirect
useEffect(() => {
if (!eventTypes.data) return;
// Group event types by team
const grouped = groupBy<IEventTypeFilter>(
eventTypes.data.filter((el) => el.team),
(item) => item?.team?.name || ""
); // Add the team name
const individualEvents = eventTypes.data.filter((el) => !el.team);
// push indivdual events to the start of grouped array
setGroupedEventTypes({ user_own_event_types: individualEvents, ...grouped });
}, [eventTypes.data, user]);
if (!user) return null;
const eventTypes = trpc.viewer.eventTypes.listWithTeam.useQuery(undefined, {
onSuccess: (data) => {
// Will be handled up the tree to redirect
// Group event types by team
const grouped = groupBy<IEventTypeFilter>(
data.filter((el) => el.team),
(item) => item?.team?.name || ""
); // Add the team name
const individualEvents = data.filter((el) => !el.team);
// push indivdual events to the start of grouped array
setGroupedEventTypes(
individualEvents.length > 0 ? { user_own_event_types: individualEvents, ...grouped } : grouped
);
},
enabled: !!user,
});
return (
if (!eventTypes.data) return null;
const isNotEmpty = eventTypes.data.length > 0;
return eventTypes.status === "success" && isNotEmpty ? (
<AnimatedPopover text={t("event_type")}>
<div className="">
{groupedEventTypes &&
@ -54,25 +64,23 @@ export const EventTypeFilter = () => {
{teamName === "user_own_event_types" ? t("individual") : teamName}
</div>
{groupedEventTypes[teamName].map((eventType) => (
<Fragment key={eventType.id}>
<div className="item-center flex px-4 py-[6px]">
<p className="text-default block self-center truncate text-sm font-medium">
{eventType.title}
</p>
<div className="ml-auto">
<input
type="checkbox"
name=""
id=""
className="text-primary-600 focus:ring-primary-500 border-default h-4 w-4 rounded ltr:mr-2 rtl:ml-2 "
/>
</div>
</div>
</Fragment>
<div key={eventType.id} className="item-center flex px-4 py-1.5">
<Checkbox
checked={query.eventTypeIds?.includes(eventType.id)}
onChange={(e) => {
if (e.target.checked) {
pushItemToKey("eventTypeIds", eventType.id);
} else if (!e.target.checked) {
removeItemByKeyAndValue("eventTypeIds", eventType.id);
}
}}
description={eventType.title}
/>
</div>
))}
</Fragment>
))}
</div>
</AnimatedPopover>
);
) : null;
};

View File

@ -1,9 +1,11 @@
import { Fragment, ReactNode } from "react";
import type { ReactNode } from "react";
import { Fragment } from "react";
import { EventTypeFilter } from "./EventTypeFilter";
import { PeopleFilter } from "./PeopleFilter";
import { TeamsMemberFilter } from "./TeamFilter";
type FilterTypes = "teams" | "people";
type FilterTypes = "teams" | "people" | "eventType";
type Filter = {
name: FilterTypes;
@ -25,6 +27,12 @@ const filters: Filter[] = [
controllingQueryParams: ["usersId"],
showByDefault: true,
},
{
name: "eventType",
component: <EventTypeFilter />,
controllingQueryParams: ["eventTypeId"],
showByDefault: true,
},
];
export function FiltersContainer() {

View File

@ -102,6 +102,15 @@ export const getHandler = async ({ ctx, input }: GetOptions) => {
},
],
},
eventTypeIds: {
AND: [
{
eventTypeId: {
in: input.filters?.eventTypeIds,
},
},
],
},
};
const filtersCombined: Prisma.BookingWhereInput[] =