From fe4946a26986d46993492facb0b59214f63c67ea Mon Sep 17 00:00:00 2001 From: Parteek malik <64765095+parteekmalik@users.noreply.github.com> Date: Tue, 15 Jul 2025 02:09:07 +0530 Subject: [PATCH] fix: added custom filter for time select (#21717) * added custom filter * handling spaces --- .../schedules/components/Schedule.tsx | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/packages/features/schedules/components/Schedule.tsx b/packages/features/schedules/components/Schedule.tsx index 6d41f6aab7..388de8f32d 100644 --- a/packages/features/schedules/components/Schedule.tsx +++ b/packages/features/schedules/components/Schedule.tsx @@ -1,4 +1,4 @@ -import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react"; +import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react"; import type { ArrayPath, Control, @@ -10,7 +10,7 @@ import type { UseFieldArrayRemove, } from "react-hook-form"; import { Controller, useFieldArray, useFormContext } from "react-hook-form"; -import type { GroupBase, Props } from "react-select"; +import { createFilter, type GroupBase, type Props } from "react-select"; import type { scheduleClassNames } from "@calcom/atoms/availability/types"; import type { ConfigType } from "@calcom/dayjs"; @@ -20,6 +20,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale"; import { weekdayNames } from "@calcom/lib/weekday"; import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery"; import type { TimeRange } from "@calcom/types/schedule"; + import cn from "@calcom/ui/classNames"; import { Button } from "@calcom/ui/components/button"; import { Dropdown, DropdownMenuContent, DropdownMenuTrigger } from "@calcom/ui/components/dropdown"; @@ -396,9 +397,36 @@ const LazySelect = ({ filter({ current: value }); }, [filter, value]); + const [inputValue, setInputValue] = React.useState(""); + const defaultFilter = React.useMemo(() => createFilter(), []); + const filteredOptions = React.useMemo(() => { + const regex = /^(\d{1,2})(a|p|am|pm)$/i; + const match = inputValue.replaceAll(" ", "").match(regex); + if (!match) { + return options.filter((option) => + defaultFilter({ ...option, data: option.label, value: option.label }, inputValue) + ); + } + + const [, numberPart, periodPart] = match; + const periodLower = periodPart.toLowerCase(); + const scoredOptions = options + .filter((option) => option.label && option.label.toLowerCase().includes(periodLower)) + .map((option) => { + const labelLower = option.label.toLowerCase(); + const index = labelLower.indexOf(numberPart); + const score = index >= 0 ? index + labelLower.length : Infinity; + return { score, option }; + }) + .sort((a, b) => a.score - b.score); + + const maxScore = scoredOptions[0]?.score; + return scoredOptions.filter((item) => item.score === maxScore).map((item) => item.option); + }, [inputValue, options, defaultFilter]); + return (