@@ -6,7 +6,7 @@ import { type ReactNode, useMemo, useRef, useState } from "react";
66
77import { DataTableSkeleton } from "@calcom/features/data-table" ;
88import { downloadAsCsv } from "@calcom/lib/csvUtils" ;
9- import { useInViewObserver } from "@calcom/lib/hooks/useInViewObserver " ;
9+ import { useDebounce } from "@calcom/lib/hooks/useDebounce " ;
1010import { useLocale } from "@calcom/lib/hooks/useLocale" ;
1111import { trpc } from "@calcom/trpc" ;
1212import type { RouterOutputs } from "@calcom/trpc/react" ;
@@ -26,46 +26,26 @@ import {
2626} from "@calcom/ui/components/table" ;
2727import { Tooltip } from "@calcom/ui/components/tooltip" ;
2828
29- import { useInsightsParameters } from "../../hooks/useInsightsParameters " ;
29+ import { useInsightsRoutingParameters } from "../../hooks/useInsightsRoutingParameters " ;
3030import { ChartCard } from "../ChartCard" ;
3131
3232interface DownloadButtonProps {
33- teamId ?: number ;
34- userId ?: number ;
35- isAll ?: boolean ;
36- routingFormId ?: string ;
37- startDate : string ;
38- endDate : string ;
39- selectedPeriod : string ;
33+ selectedPeriod : "perDay" | "perWeek" | "perMonth" ;
4034 searchQuery ?: string ;
4135}
4236
43- function DownloadButton ( {
44- userId,
45- teamId,
46- isAll,
47- routingFormId,
48- startDate,
49- endDate,
50- selectedPeriod,
51- searchQuery,
52- } : DownloadButtonProps ) {
37+ function DownloadButton ( { selectedPeriod, searchQuery } : DownloadButtonProps ) {
5338 const [ isDownloading , setIsDownloading ] = useState ( false ) ;
39+ const routingParams = useInsightsRoutingParameters ( ) ;
5440 const utils = trpc . useContext ( ) ;
55- const { t } = useLocale ( ) ;
5641
5742 const handleDownload = async ( e : React . MouseEvent ) => {
5843 e . preventDefault ( ) ; // Prevent default form submission
5944
6045 try {
6146 const result = await utils . viewer . insights . routedToPerPeriodCsv . fetch ( {
62- userId,
63- teamId,
64- startDate,
65- endDate,
66- period : selectedPeriod as "perDay" | "perWeek" | "perMonth" ,
67- isAll,
68- routingFormId,
47+ ...routingParams ,
48+ period : selectedPeriod ,
6949 searchQuery : searchQuery || undefined ,
7050 } ) ;
7151
@@ -94,32 +74,14 @@ function DownloadButton({
9474}
9575
9676interface FormCardProps {
97- selectedPeriod : string ;
98- onPeriodChange : ( value : string ) => void ;
77+ selectedPeriod : "perDay" | "perWeek" | "perMonth" ;
78+ onPeriodChange : ( value : "perDay" | "perWeek" | "perMonth" ) => void ;
9979 searchQuery : string ;
10080 onSearchChange : ( value : string ) => void ;
10181 children : ReactNode ;
102- teamId ?: number ;
103- userId ?: number ;
104- isAll ?: boolean ;
105- routingFormId ?: string ;
106- startDate : string ;
107- endDate : string ;
10882}
10983
110- function FormCard ( {
111- selectedPeriod,
112- onPeriodChange,
113- searchQuery,
114- onSearchChange,
115- children,
116- teamId,
117- userId,
118- isAll,
119- routingFormId,
120- startDate,
121- endDate,
122- } : FormCardProps ) {
84+ function FormCard ( { selectedPeriod, onPeriodChange, searchQuery, onSearchChange, children } : FormCardProps ) {
12385 const { t } = useLocale ( ) ;
12486
12587 return (
@@ -135,7 +97,7 @@ function FormCard({
13597 ] }
13698 className = "w-fit"
13799 value = { selectedPeriod }
138- onValueChange = { ( value ) => value && onPeriodChange ( value ) }
100+ onValueChange = { ( value ) => value && onPeriodChange ( value as "perDay" | "perWeek" | "perMonth" ) }
139101 />
140102 < div className = "flex gap-2" >
141103 < div className = "w-64" >
@@ -147,16 +109,7 @@ function FormCard({
147109 className = "w-full"
148110 />
149111 </ div >
150- < DownloadButton
151- userId = { userId }
152- teamId = { teamId }
153- isAll = { isAll }
154- routingFormId = { routingFormId }
155- startDate = { startDate }
156- endDate = { endDate }
157- selectedPeriod = { selectedPeriod }
158- searchQuery = { searchQuery }
159- />
112+ < DownloadButton selectedPeriod = { selectedPeriod } searchQuery = { searchQuery } />
160113 </ div >
161114 </ div >
162115 { children }
@@ -215,87 +168,56 @@ const getPerformanceBadge = (performance: RoutedToTableRow["performance"], t: TF
215168
216169export function RoutedToPerPeriod ( ) {
217170 const { t } = useLocale ( ) ;
218- const { userId, teamId, startDate, endDate, isAll, routingFormId } = useInsightsParameters ( ) ;
219- const [ selectedPeriod , setSelectedPeriod ] = useQueryState ( "selectedPeriod" , {
220- defaultValue : "perWeek" ,
221- } ) ;
171+ const routingParams = useInsightsRoutingParameters ( ) ;
172+ const [ selectedPeriod , setSelectedPeriod ] = useState < "perDay" | "perWeek" | "perMonth" > ( "perWeek" ) ;
222173 const [ searchQuery , setSearchQuery ] = useQueryState ( "search" , {
223174 defaultValue : "" ,
224175 } ) ;
225176
226- const { ref : loadMoreRef } = useInViewObserver ( ( ) => {
227- if ( hasNextPage && ! isFetchingNextPage ) {
228- fetchNextPage ( ) ;
229- }
230- } ) ;
231-
232177 const tableContainerRef = useRef < HTMLDivElement > ( null ) ;
233-
234- const { data , fetchNextPage , isFetchingNextPage , hasNextPage , isLoading } =
235- trpc . viewer . insights . routedToPerPeriod . useInfiniteQuery (
236- {
237- userId ,
238- teamId ,
239- startDate ,
240- endDate ,
241- period : selectedPeriod as "perDay" | "perWeek" | "perMonth" ,
242- isAll ,
243- routingFormId ,
244- searchQuery : searchQuery || undefined ,
245- limit : 10 ,
178+ const debouncedSearchQuery = useDebounce ( searchQuery , 500 ) ;
179+
180+ const { data , isLoading } = trpc . viewer . insights . routedToPerPeriod . useQuery (
181+ {
182+ ... routingParams ,
183+ period : selectedPeriod ,
184+ searchQuery : debouncedSearchQuery || undefined ,
185+ } ,
186+ {
187+ staleTime : 30000 ,
188+ refetchOnWindowFocus : false ,
189+ trpc : {
190+ context : { skipBatch : true } ,
246191 } ,
247- {
248- getNextPageParam : ( lastPage ) => {
249- if ( ! lastPage . users . nextCursor && ! lastPage . periodStats . nextCursor ) {
250- return undefined ;
251- }
252-
253- return {
254- userCursor : lastPage . users . nextCursor ,
255- periodCursor : lastPage . periodStats . nextCursor ,
256- } ;
257- } ,
258- }
259- ) ;
192+ }
193+ ) ;
260194
261195 const flattenedUsers = useMemo ( ( ) => {
262- const userMap = new Map ( ) ;
263- data ?. pages . forEach ( ( page ) => {
264- page . users . data . forEach ( ( user ) => {
265- if ( ! userMap . has ( user . id ) ) {
266- userMap . set ( user . id , user ) ;
267- }
268- } ) ;
269- } ) ;
270- return Array . from ( userMap . values ( ) ) ;
271- } , [ data ?. pages ] ) ;
196+ return data ?. users . data || [ ] ;
197+ } , [ data ?. users . data ] ) ;
272198
273199 const uniquePeriods = useMemo ( ( ) => {
274- if ( ! data ?. pages ) return [ ] ;
200+ if ( ! data ?. periodStats . data ) return [ ] ;
275201
276- // Get all unique periods from all pages
202+ // Get all unique periods
277203 const periods = new Set < string > ( ) ;
278- data . pages . forEach ( ( page ) => {
279- page . periodStats . data . forEach ( ( stat ) => {
280- periods . add ( stat . period_start . toISOString ( ) ) ;
281- } ) ;
204+ data . periodStats . data . forEach ( ( stat ) => {
205+ periods . add ( stat . period_start . toISOString ( ) ) ;
282206 } ) ;
283207
284208 return Array . from ( periods )
285209 . map ( ( dateStr ) => new Date ( dateStr ) )
286210 . sort ( ( a , b ) => a . getTime ( ) - b . getTime ( ) ) ;
287- } , [ data ?. pages ] ) ;
211+ } , [ data ?. periodStats . data ] ) ;
288212
289213 const processedData = useMemo ( ( ) => {
290- if ( ! data ?. pages ) return [ ] ;
214+ if ( ! data ?. periodStats . data ) return [ ] ;
291215
292216 // Create a map for quick lookup of stats
293217 const statsMap = new Map < string , number > ( ) ;
294- data . pages . forEach ( ( page ) => {
295- page . periodStats . data . forEach ( ( stat ) => {
296- const key = `${ stat . userId } -${ stat . period_start . toISOString ( ) } ` ;
297- statsMap . set ( key , stat . total ) ;
298- } ) ;
218+ data . periodStats . data . forEach ( ( stat ) => {
219+ const key = `${ stat . userId } -${ stat . period_start . toISOString ( ) } ` ;
220+ statsMap . set ( key , stat . total ) ;
299221 } ) ;
300222
301223 return flattenedUsers . map ( ( user ) => {
@@ -314,7 +236,7 @@ export function RoutedToPerPeriod() {
314236 totalBookings : user . totalBookings ,
315237 } ;
316238 } ) ;
317- } , [ data ?. pages , flattenedUsers , uniquePeriods ] ) ;
239+ } , [ data ?. periodStats . data , flattenedUsers , uniquePeriods ] ) ;
318240
319241 if ( isLoading ) {
320242 return (
@@ -327,13 +249,7 @@ export function RoutedToPerPeriod() {
327249 selectedPeriod = { selectedPeriod }
328250 onPeriodChange = { setSelectedPeriod }
329251 searchQuery = { searchQuery }
330- onSearchChange = { setSearchQuery }
331- userId = { userId }
332- teamId = { teamId }
333- isAll = { isAll }
334- routingFormId = { routingFormId }
335- startDate = { startDate }
336- endDate = { endDate } >
252+ onSearchChange = { setSearchQuery } >
337253 < div className = "mt-6" >
338254 < DataTableSkeleton columns = { 5 } columnWidths = { [ 200 , 120 , 120 , 120 , 120 ] } />
339255 </ div >
@@ -368,13 +284,7 @@ export function RoutedToPerPeriod() {
368284 selectedPeriod = { selectedPeriod }
369285 onPeriodChange = { setSelectedPeriod }
370286 searchQuery = { searchQuery }
371- onSearchChange = { setSearchQuery }
372- userId = { userId }
373- teamId = { teamId }
374- isAll = { isAll }
375- routingFormId = { routingFormId }
376- startDate = { startDate }
377- endDate = { endDate } >
287+ onSearchChange = { setSearchQuery } >
378288 < div className = "mt-6" >
379289 < div
380290 className = "scrollbar-thin border-subtle relative overflow-auto rounded-md border"
@@ -405,10 +315,7 @@ export function RoutedToPerPeriod() {
405315 < TableBody className = "relative" >
406316 { processedData . map ( ( row , index ) => {
407317 return (
408- < TableRow
409- key = { row . id }
410- ref = { index === processedData . length - 1 ? loadMoreRef : undefined }
411- className = "divide-muted divide-x" >
318+ < TableRow key = { row . id } className = "divide-muted divide-x" >
412319 < TableCell className = "bg-default w-[200px]" >
413320 < HoverCard >
414321 < HoverCardTrigger asChild >
0 commit comments