import { ArrowDown, ArrowUp, TextSearch, X } from 'lucide-react' import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import DataGrid, { Column } from 'react-data-grid' import { useParams } from 'common' import { DbQueryHook } from 'hooks/analytics/useDbQuery' import { Button, ResizableHandle, ResizablePanel, ResizablePanelGroup, TabsContent_Shadcn_, TabsList_Shadcn_, TabsTrigger_Shadcn_, Tabs_Shadcn_, cn, } from 'ui' import { GenericSkeletonLoader } from 'ui-patterns' import { QueryPerformanceSort } from '../Reports/Reports.queries' import { IndexSuggestion } from './IndexSuggestion' import { QueryDetail } from './QueryDetail' import { QUERY_PERFORMANCE_REPORTS, QUERY_PERFORMANCE_REPORT_TYPES, } from './QueryPerformance.constants' interface QueryPerformanceGridProps { queryPerformanceQuery: DbQueryHook } export const QueryPerformanceGrid = ({ queryPerformanceQuery }: QueryPerformanceGridProps) => { // [Joshen] This will come in another PR to integrate index advisor const showIndexSuggestions = false const router = useRouter() const { preset } = useParams() const { isLoading } = queryPerformanceQuery const defaultSortValue = router.query.sort ? ({ column: router.query.sort, order: router.query.order } as QueryPerformanceSort) : undefined const [view, setView] = useState<'details' | 'suggestion'>('details') const [sort, setSort] = useState(defaultSortValue) const [selectedRow, setSelectedRow] = useState() const reportType = (preset as QUERY_PERFORMANCE_REPORT_TYPES) ?? QUERY_PERFORMANCE_REPORT_TYPES.MOST_TIME_CONSUMING const columns = QUERY_PERFORMANCE_REPORTS[reportType].map((col) => { const result: Column = { key: col.id, name: col.name, resizable: true, minWidth: col.minWidth ?? 120, headerCellClass: 'first:pl-6 cursor-pointer', renderHeaderCell: () => { return (
onSortChange(col.id)} >

{col.name}

{col.description &&

{col.description}

}
{sort?.column === col.id && ( <>{sort.order === 'desc' ? : } )}
) }, renderCell: (props) => { const value = props.row?.[col.id] const isTime = col.name.includes('time') const formattedValue = isTime ? `${value.toFixed(2)}ms` : String(value) return (

{formattedValue}

{isTime &&

{(value / 1000).toFixed(2)}s

}
) }, } return result }) const onSortChange = (column: string) => { let updatedSort = undefined if (sort?.column === column) { if (sort.order === 'desc') { updatedSort = { column, order: 'asc' } } else { updatedSort = undefined } } else { updatedSort = { column, order: 'desc' } } setSort(updatedSort as QueryPerformanceSort) if (updatedSort === undefined) { const { sort, order, ...otherParams } = router.query router.push({ ...router, query: otherParams }) } else { router.push({ ...router, query: { ...router.query, sort: updatedSort.column, order: updatedSort.order }, }) } } useEffect(() => { setSelectedRow(undefined) }, [preset]) return ( { const { rowIdx } = props if (rowIdx >= 0) setSelectedRow(rowIdx) }} columns={columns} rows={queryPerformanceQuery?.data ?? []} rowClass={(_, idx) => { const isSelected = idx === selectedRow return [ `${isSelected ? 'bg-surface-300 dark:bg-surface-300' : 'bg-200'} cursor-pointer`, `${isSelected ? '[&>div:first-child]:border-l-4 border-l-secondary [&>div]:border-l-foreground' : ''}`, '[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-none [&>.rdg-cell]:shadow-none', '[&>.rdg-cell:first-child>div]:ml-4', ].join(' ') }} renderers={{ noRowsFallback: isLoading ? (
) : (

No queries detected yet

There are no queries actively running that meet the criteria

), }} />
{selectedRow !== undefined && ( <>