From 26850552c17dd2d8cfc9ca3eb47b44952c061ecd Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Fri, 21 Feb 2025 17:01:59 +0100 Subject: [PATCH 1/2] chore: remove filter-related code that is no longer in use --- .../bookings/components/EventTypeFilter.tsx | 113 ------------------ .../bookings/components/FilterToggle.tsx | 35 ------ .../bookings/components/FiltersContainer.tsx | 49 -------- .../bookings/components/PeopleFilter.tsx | 97 --------------- .../filters/components/StartTimeFilters.tsx | 80 ------------- .../viewer/teams/legacyListMembers.handler.ts | 4 - .../viewer/teams/legacyListMembers.schema.ts | 4 +- 7 files changed, 1 insertion(+), 381 deletions(-) delete mode 100644 packages/features/bookings/components/EventTypeFilter.tsx delete mode 100644 packages/features/bookings/components/FilterToggle.tsx delete mode 100644 packages/features/bookings/components/FiltersContainer.tsx delete mode 100644 packages/features/bookings/components/PeopleFilter.tsx delete mode 100644 packages/features/filters/components/StartTimeFilters.tsx diff --git a/packages/features/bookings/components/EventTypeFilter.tsx b/packages/features/bookings/components/EventTypeFilter.tsx deleted file mode 100644 index 105450ed1c5ecc..00000000000000 --- a/packages/features/bookings/components/EventTypeFilter.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { useSession } from "next-auth/react"; -import { Fragment, useMemo, useState } from "react"; - -import { - FilterCheckboxField, - FilterCheckboxFieldsContainer, -} from "@calcom/features/filters/components/TeamsFilter"; -import type { IEventTypeFilter } from "@calcom/features/filters/types/filter"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; -import { trpc } from "@calcom/trpc/react"; -import { FilterSearchField } from "@calcom/ui"; -import { AnimatedPopover, Divider, Icon } from "@calcom/ui"; - -import { groupBy } from "../groupBy"; -import { useFilterQuery } from "../lib/useFilterQuery"; - -type GroupedEventTypeState = Record< - string, - { - team: { - id: number; - name: string; - } | null; - id: number; - title: string; - slug: string; - }[] ->; - -export const EventTypeFilter = () => { - const { t } = useLocale(); - const { data: user } = useSession(); - const { data: query, pushItemToKey, removeItemByKeyAndValue, removeAllQueryParams } = useFilterQuery(); - const [search, setSearch] = useState(""); - - const eventTypes = trpc.viewer.eventTypes.listWithTeam.useQuery(undefined, { - enabled: !!user, - }); - const groupedEventTypes: GroupedEventTypeState | null = useMemo(() => { - const data = eventTypes.data; - if (!data) { - return null; - } - // Will be handled up the tree to redirect - // Group event types by team - const grouped = groupBy( - data.filter((el) => el.team), - (item) => item?.team?.name || "" - ); // Add the team name - const individualEvents = data.filter((el) => !el.team); - // push individual events to the start of grouped array - return individualEvents.length > 0 ? { user_own_event_types: individualEvents, ...grouped } : grouped; - }, [eventTypes.data]); - - if (!eventTypes.data) return null; - const isEmpty = eventTypes.data.length === 0; - - const getTextForPopover = () => { - const eventTypeIds = query.eventTypeIds; - if (eventTypeIds) { - return `${t("number_selected", { count: eventTypeIds.length })}`; - } - return `${t("all")}`; - }; - - return ( - - {!isEmpty ? ( - - setSearch(e.target.value)} - /> - } - checked={!query.eventTypeIds?.length} - onChange={removeAllQueryParams} - label={t("all_event_types_filter_label")} - /> - - {groupedEventTypes && - Object.keys(groupedEventTypes).map((teamName) => ( - -
- {teamName === "user_own_event_types" ? t("individual") : teamName} -
- {groupedEventTypes[teamName] - .filter((eventType) => eventType.title.toLowerCase().includes(search.toLowerCase())) - .map((eventType) => ( - { - if (e.target.checked) { - pushItemToKey("eventTypeIds", eventType.id); - } else if (!e.target.checked) { - removeItemByKeyAndValue("eventTypeIds", eventType.id); - } - }} - label={eventType.title} - /> - ))} -
- ))} -
- ) : ( -

{t("no_options_available")}

- )} -
- ); -}; diff --git a/packages/features/bookings/components/FilterToggle.tsx b/packages/features/bookings/components/FilterToggle.tsx deleted file mode 100644 index b81a500dd0e89d..00000000000000 --- a/packages/features/bookings/components/FilterToggle.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import type { Dispatch, SetStateAction } from "react"; - -import { useFilterQuery } from "@calcom/features/bookings/lib/useFilterQuery"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; -import { Badge, Button, Tooltip } from "@calcom/ui"; - -export interface FilterToggleProps { - setIsFiltersVisible: Dispatch>; -} - -export function FilterToggle({ setIsFiltersVisible }: FilterToggleProps) { - const { - data: { teamIds, userIds, eventTypeIds }, - } = useFilterQuery(); - const { t } = useLocale(); - - function toggleFiltersVisibility() { - setIsFiltersVisible((prev) => !prev); - } - - return ( - - ); -} diff --git a/packages/features/bookings/components/FiltersContainer.tsx b/packages/features/bookings/components/FiltersContainer.tsx deleted file mode 100644 index b0ff226a9982b4..00000000000000 --- a/packages/features/bookings/components/FiltersContainer.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { useAutoAnimate } from "@formkit/auto-animate/react"; -import { useSearchParams } from "next/navigation"; - -import { PeopleFilter } from "@calcom/features/bookings/components/PeopleFilter"; -import { useFilterQuery } from "@calcom/features/bookings/lib/useFilterQuery"; -import { StartTimeFilters } from "@calcom/features/filters/components/StartTimeFilters"; -import { TeamsFilter } from "@calcom/features/filters/components/TeamsFilter"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; -import { Tooltip, Button } from "@calcom/ui"; - -import { EventTypeFilter } from "./EventTypeFilter"; - -export interface FiltersContainerProps { - isFiltersVisible: boolean; -} - -export function FiltersContainer({ isFiltersVisible }: FiltersContainerProps) { - const [animationParentRef] = useAutoAnimate(); - const { removeAllQueryParams } = useFilterQuery(); - const { t } = useLocale(); - const searchParams = useSearchParams(); - - const validFilterKeys = ["userIds", "eventTypeIds", "upIds", "teamIds", "afterStartDate", "beforeEndDate"]; - const hasValidQueryParams = Array.from(searchParams?.keys() ?? []).some((key) => - validFilterKeys.includes(key) - ); - - return ( -
- {isFiltersVisible ? ( -
- - - - - - - -
- ) : null} -
- ); -} diff --git a/packages/features/bookings/components/PeopleFilter.tsx b/packages/features/bookings/components/PeopleFilter.tsx deleted file mode 100644 index 5435ca38a6bf54..00000000000000 --- a/packages/features/bookings/components/PeopleFilter.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import { useState } from "react"; - -import { useFilterQuery } from "@calcom/features/bookings/lib/useFilterQuery"; -import { - FilterCheckboxField, - FilterCheckboxFieldsContainer, -} from "@calcom/features/filters/components/TeamsFilter"; -import { useDebounce } from "@calcom/lib/hooks/useDebounce"; -import { useInViewObserver } from "@calcom/lib/hooks/useInViewObserver"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; -import { trpc } from "@calcom/trpc/react"; -import { AnimatedPopover, Avatar, Divider, FilterSearchField, Icon, Button } from "@calcom/ui"; - -export const PeopleFilter = () => { - const { t } = useLocale(); - - const { data: currentOrg } = trpc.viewer.organizations.listCurrent.useQuery(); - const isAdmin = currentOrg?.user.role === "ADMIN" || currentOrg?.user.role === "OWNER"; - const hasPermToView = !currentOrg?.isPrivate || isAdmin; - - const { data: query, pushItemToKey, removeItemByKeyAndValue, removeAllQueryParams } = useFilterQuery(); - const [searchText, setSearchText] = useState(""); - - const debouncedSearch = useDebounce(searchText, 500); - - const queryMembers = trpc.viewer.teams.legacyListMembers.useInfiniteQuery( - { limit: 10, searchText: debouncedSearch, includeEmail: true }, - { - enabled: true, - getNextPageParam: (lastPage) => lastPage.nextCursor, - } - ); - - const { ref: observerRef } = useInViewObserver(() => { - if (queryMembers.hasNextPage && !queryMembers.isFetching) { - queryMembers.fetchNextPage(); - } - }, document.querySelector('[role="dialog"]')); - - const filteredMembers = queryMembers?.data?.pages.flatMap((page) => page.members); - - const getTextForPopover = () => { - const userIds = query.userIds; - if (userIds) { - return `${t("number_selected", { count: userIds.length })}`; - } - return `${t("all")}`; - }; - - if (!hasPermToView) { - return null; - } - - return ( - - - setSearchText(e.target.value)} placeholder={t("search")} /> - - } - checked={!query.userIds?.length} - onChange={removeAllQueryParams} - label={t("all_users_filter_label")} - /> - - - {filteredMembers?.map((member) => ( - { - if (e.target.checked) { - pushItemToKey("userIds", member.id); - } else if (!e.target.checked) { - removeItemByKeyAndValue("userIds", member.id); - } - }} - icon={} - /> - ))} -
- -
-
-
- ); -}; diff --git a/packages/features/filters/components/StartTimeFilters.tsx b/packages/features/filters/components/StartTimeFilters.tsx deleted file mode 100644 index 514c14b895e051..00000000000000 --- a/packages/features/filters/components/StartTimeFilters.tsx +++ /dev/null @@ -1,80 +0,0 @@ -"use client"; - -import { usePathname, useRouter, useSearchParams } from "next/navigation"; -import { useState, useEffect } from "react"; - -import type { Dayjs } from "@calcom/dayjs"; -import dayjs from "@calcom/dayjs"; -import { useFilterQuery } from "@calcom/features/bookings/lib/useFilterQuery"; -import { DateRangePicker } from "@calcom/ui"; - -export const StartTimeFilters = () => { - const router = useRouter(); - const pathname = usePathname(); - const searchParams = useSearchParams(); - const { data: query } = useFilterQuery(); - - const getQueryDate = (param: string) => - searchParams?.get(param) ? dayjs(searchParams?.get(param)) : undefined; - - const [afterStartDate, setAfterStartDate] = useState(() => - getQueryDate("afterStartDate") - ); - const [beforeEndDate, setBeforeEndDate] = useState(() => getQueryDate("beforeEndDate")); - - const startValue = afterStartDate?.toDate(); - const endValue = beforeEndDate?.toDate(); - - const updateUrlParams = (newStartDate: Dayjs, newEndDate: Dayjs) => { - const search = new URLSearchParams(searchParams?.toString()); - - Object.entries(query).forEach(([key, value]) => { - if (key !== "afterStartDate" && key !== "beforeEndDate") { - search.set(key, String(value)); - } - }); - - if (newStartDate) { - search.set("afterStartDate", newStartDate.startOf("day").format("YYYY-MM-DDTHH:mm:ss")); - } - if (newEndDate) { - search.set("beforeEndDate", newEndDate.endOf("day").format("YYYY-MM-DDTHH:mm:ss")); - } - - router.replace(`${pathname}?${search.toString()}`); - }; - - useEffect(() => { - //if params has date range - if (searchParams?.has("afterStartDate") && searchParams?.has("beforeEndDate")) { - setAfterStartDate(getQueryDate("afterStartDate")); - setBeforeEndDate(getQueryDate("beforeEndDate")); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchParams]); - - useEffect(() => { - if (Object.keys(query).length === 1 && "status" in query && afterStartDate && beforeEndDate) { - setAfterStartDate(undefined); - setBeforeEndDate(undefined); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [query]); - - return ( - { - const newAfterStartDate = values.startDate ? dayjs(values.startDate) : undefined; - const newBeforeEndDate = values.endDate ? dayjs(values.endDate) : undefined; - setAfterStartDate(newAfterStartDate); - setBeforeEndDate(newBeforeEndDate); - - if (newAfterStartDate && newBeforeEndDate) { - updateUrlParams(newAfterStartDate, newBeforeEndDate); - } - }} - /> - ); -}; diff --git a/packages/trpc/server/routers/viewer/teams/legacyListMembers.handler.ts b/packages/trpc/server/routers/viewer/teams/legacyListMembers.handler.ts index 7be2d5cfa91793..ae18dfd4b8c323 100644 --- a/packages/trpc/server/routers/viewer/teams/legacyListMembers.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/legacyListMembers.handler.ts @@ -64,10 +64,6 @@ export const legacyListMembers = async ({ ctx, input }: ListMembersOptions) => { { username: { contains: input.searchText, mode: "insensitive" } }, ]; - if (input.includeEmail) { - searchTextClauses.push({ email: { contains: input.searchText, mode: "insensitive" } }); - } - // Fetch unique users through memberships const memberships = await prisma.membership.findMany({ where: { diff --git a/packages/trpc/server/routers/viewer/teams/legacyListMembers.schema.ts b/packages/trpc/server/routers/viewer/teams/legacyListMembers.schema.ts index 88f8370d208a5d..a6a31373f61c20 100644 --- a/packages/trpc/server/routers/viewer/teams/legacyListMembers.schema.ts +++ b/packages/trpc/server/routers/viewer/teams/legacyListMembers.schema.ts @@ -7,9 +7,7 @@ export const ZListMembersInputSchema = z.object({ cursor: z.number().nullish(), }); -export const ZLegacyListMembersInputSchema = ZListMembersInputSchema.extend({ - includeEmail: z.boolean().optional(), -}); +export const ZLegacyListMembersInputSchema = ZListMembersInputSchema.extend({}); export type TListMembersInputSchema = z.infer; export type TLegacyListMembersInputSchema = z.infer; From bf0536ed3f506ab32ee704b2f8c662677fd4563b Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Fri, 21 Feb 2025 17:18:43 +0100 Subject: [PATCH 2/2] remove groupBy.ts --- packages/features/bookings/groupBy.ts | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 packages/features/bookings/groupBy.ts diff --git a/packages/features/bookings/groupBy.ts b/packages/features/bookings/groupBy.ts deleted file mode 100644 index c0d337af29610d..00000000000000 --- a/packages/features/bookings/groupBy.ts +++ /dev/null @@ -1,18 +0,0 @@ -type KeySelector = (item: T) => string; - -export function groupBy(array: Iterable, keySelector: KeySelector): Record { - return Array.from(array).reduce( - (acc: Record, item: T) => { - const key = keySelector(item); - if (key in acc) { - // found key, push new item into existing array - acc[key].push(item); - } else { - // did not find key, create new array - acc[key] = [item]; - } - return acc; - }, - {} // start with empty object - ); -}