From 6d171ccaa706ff99ec4e1bac00f377620c4ec0b9 Mon Sep 17 00:00:00 2001 From: kemal Date: Mon, 11 Aug 2025 18:19:52 +0100 Subject: [PATCH] chore: removing unused code AI generates stuff we dont need so removing it all. --- .../QueryInsights/QueryInsights.tsx | 6 +- .../interfaces/QueryInsights/QueryList.tsx | 418 ++++++++++++++++++ .../components/MetricToggleButtons.tsx | 7 +- .../QueryInsights/components/MetricsChart.tsx | 9 +- .../QueryInsights/components/QueryList.tsx | 2 +- .../QueryInsights/hooks/useChartConfig.ts | 51 +-- 6 files changed, 429 insertions(+), 64 deletions(-) create mode 100644 apps/studio/components/interfaces/QueryInsights/QueryList.tsx diff --git a/apps/studio/components/interfaces/QueryInsights/QueryInsights.tsx b/apps/studio/components/interfaces/QueryInsights/QueryInsights.tsx index 0705033c998..96c7d037a95 100644 --- a/apps/studio/components/interfaces/QueryInsights/QueryInsights.tsx +++ b/apps/studio/components/interfaces/QueryInsights/QueryInsights.tsx @@ -15,7 +15,7 @@ import { } from 'data/query-insights/query-insights-query' import { useDatabaseSelectorStateSnapshot } from 'state/database-selector' import { useReadReplicasQuery } from 'data/read-replicas/replicas-query' -import { formatMetricValue } from './QueryInsights.utils' + export type MetricType = 'rows_read' | 'query_latency' | 'calls' | 'cache_hits' | 'issues' @@ -141,7 +141,7 @@ export const QueryInsights = () => { errorCount: errorCount }) - const selectedDatabase = databases?.find((db) => db.identifier === state.selectedDatabaseId) + // Define metrics with dynamic descriptions const METRICS: { id: MetricType; label: string; description: string; tooltip: string }[] = [ @@ -387,6 +387,4 @@ export const QueryInsights = () => { /> ) - - console.log('🚀 [QueryInsights] Component rendered - END') } diff --git a/apps/studio/components/interfaces/QueryInsights/QueryList.tsx b/apps/studio/components/interfaces/QueryInsights/QueryList.tsx new file mode 100644 index 00000000000..7ccb2f571ed --- /dev/null +++ b/apps/studio/components/interfaces/QueryInsights/QueryList.tsx @@ -0,0 +1,418 @@ +import { useRouter } from 'next/router' +import { useRef, useState, useEffect } from 'react' +import DataGrid, { Column, DataGridHandle, Row } from 'react-data-grid' +import { QueryInsightsQuery } from 'data/query-insights/query-insights-query' +import dayjs from 'dayjs' +import { cn, CodeBlock, Tooltip, TooltipContent, TooltipTrigger } from 'ui' +import { TextSearch } from 'lucide-react' +import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' + +interface QueryListProps { + queries: QueryInsightsQuery[] + isLoading: boolean + onQuerySelect?: (query: QueryInsightsQuery | null) => void + onQueryHover?: (query: QueryInsightsQuery | null) => void + selectedQuery?: QueryInsightsQuery | null + hoveredQuery?: QueryInsightsQuery | null +} + +export const QueryList = ({ + queries, + isLoading, + onQuerySelect, + onQueryHover, + selectedQuery, + hoveredQuery, +}: QueryListProps) => { + const router = useRouter() + const gridRef = useRef(null) + const [selectedRow, setSelectedRow] = useState() + const [hoveredRow, setHoveredRow] = useState() + + const normalizeWhitespace = (sql: string) => { + return sql.replace(/\s+/g, ' ').trim() + } + + // Update selected row when selectedQuery changes from parent + useEffect(() => { + if (selectedQuery) { + const idx = queries.findIndex((q) => q.query_id === selectedQuery.query_id) + if (idx !== -1) { + setSelectedRow(idx) + } + } else { + setSelectedRow(undefined) + } + }, [selectedQuery, queries]) + + // Handler for row click + const handleRowClick = (idx: number) => { + if (isNaN(idx) || idx < 0 || idx >= queries.length) return + + const query = queries[idx] + const isAlreadySelected = selectedQuery?.query_id === query.query_id + + // If the query is already selected, deselect it + if (isAlreadySelected) { + setSelectedRow(undefined) + onQuerySelect?.(null) + } else { + // Otherwise, select the new query + setSelectedRow(idx) + onQuerySelect?.(query) + } + + // Scroll to keep the row in view + gridRef.current?.scrollToCell({ idx: 0, rowIdx: idx }) + } + + // Handler for row hover + const handleRowMouseEnter = (idx: number) => { + if (isNaN(idx) || idx < 0 || idx >= queries.length) return + if (selectedQuery) return // Don't trigger hover when a query is already selected + + const query = queries[idx] + setHoveredRow(idx) + onQueryHover?.(query) + } + + const handleRowMouseLeave = () => { + if (selectedQuery) return // Don't clear hover when a query is already selected + + setHoveredRow(undefined) + onQueryHover?.(null) + } + + const rowClassRender = (row: QueryInsightsQuery) => { + const isSelected = selectedQuery?.query_id === row.query_id + const isHovered = hoveredQuery?.query_id === row.query_id && !selectedQuery + + return cn( + 'cursor-pointer transition-colors', + isSelected ? 'bg-surface-300' : isHovered ? 'bg-surface-200' : '' + ) + } + + const columns: Column[] = [ + { + key: 'query', + name: 'Query', + resizable: true, + minWidth: 400, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Query

+
+ ), + renderCell: (props) => ( +
+ + {normalizeWhitespace(props.row.query)} + +
+ ), + }, + { + key: 'calls', + name: 'Calls', + resizable: true, + minWidth: 100, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Calls

+
+ ), + renderCell: (props) => ( +
+ {props.row.calls.toLocaleString()} +
+ ), + }, + { + key: 'total_time', + name: 'Total Time', + resizable: true, + minWidth: 120, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Total Time

+
+ ), + renderCell: (props) => ( +
+

{props.row.total_time.toFixed(0)}ms

+

{(props.row.total_time / 1000).toFixed(2)}s

+
+ ), + }, + { + key: 'mean_exec_time', + name: 'Mean Time', + resizable: true, + minWidth: 120, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Mean Time

+
+ ), + renderCell: (props) => ( +
+

{props.row.mean_exec_time.toFixed(0)}ms

+

{(props.row.mean_exec_time / 1000).toFixed(2)}s

+
+ ), + }, + { + key: 'rows_read', + name: 'Rows Read', + resizable: true, + minWidth: 100, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Rows Read

+
+ ), + renderCell: (props) => ( +
+ {((props.row.rows_read ?? 0) > 0 ? props.row.rows_read : 0).toLocaleString()} +
+ ), + }, + { + key: 'rows_insert', + name: 'Rows Insert', + resizable: true, + minWidth: 100, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Rows Insert

+
+ ), + renderCell: (props) => ( +
+ {((props.row.rows_insert ?? 0) > 0 ? props.row.rows_insert : 0).toLocaleString()} +
+ ), + }, + { + key: 'rows_update', + name: 'Rows Update', + resizable: true, + minWidth: 100, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Rows Update

+
+ ), + renderCell: (props) => ( +
+ {((props.row.rows_update ?? 0) > 0 ? props.row.rows_update : 0).toLocaleString()} +
+ ), + }, + { + key: 'rows_delete', + name: 'Rows Delete', + resizable: true, + minWidth: 100, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Rows Delete

+
+ ), + renderCell: (props) => ( +
+ {((props.row.rows_delete ?? 0) > 0 ? props.row.rows_delete : 0).toLocaleString()} +
+ ), + }, + { + key: 'application_name', + name: 'Application', + resizable: true, + minWidth: 120, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Application

+
+ ), + renderCell: (props) => ( +
+ {props.row.application_name || 'Unknown'} +
+ ), + }, + { + key: 'badness_score', + name: 'Badness Score', + resizable: true, + minWidth: 120, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Badness Score

+
+ ), + renderCell: (props) => ( +
+ {(props.row.badness_score ?? 0).toFixed(2)} +
+ ), + }, + { + key: 'index_recommendations', + name: 'Index Recommendations', + resizable: true, + minWidth: 160, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Index Recommendations

+
+ ), + renderCell: (props) => { + const indexStatements = props.row.index_statements + const hasRecommendations = + indexStatements !== undefined && + Array.isArray(indexStatements) && + indexStatements.length > 0 + + return ( +
+ {hasRecommendations ? ( + + {indexStatements.length} suggestions + + ) : props.row.query.toLowerCase().startsWith('select') ? ( + + Optimized + + ) : ( + N/A + )} +
+ ) + }, + }, + { + key: 'errors', + name: 'Slow Queries', + resizable: true, + minWidth: 120, + headerCellClass: '', + renderHeaderCell: () => ( +
+

Slow Queries

+
+ ), + renderCell: (props) => { + const errorCount = props.row.error_count || 0 + + if (errorCount === 0) { + return ( +
+ + No issues + +
+ ) + } + + return ( +
+ + {errorCount} slow query{errorCount !== 1 ? 's' : ''} + +
+ ) + }, + }, + ] + + return ( +
+ { + // Use the query_id for comparison instead of row index + const isSelected = selectedQuery?.query_id === row.query_id + return [ + rowClassRender(row), + `${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={{ + renderRow: (rowIdx, props) => { + const idx = typeof rowIdx === 'number' ? rowIdx : Number(rowIdx) + return ( + handleRowClick(idx)} + onMouseEnter={() => handleRowMouseEnter(idx)} + onMouseLeave={handleRowMouseLeave} + /> + ) + }, + noRowsFallback: isLoading ? ( +
+ +
+ ) : ( +
+ +
+

No queries detected

+

+ There are no actively running queries that match the criteria +

+
+
+ ), + }} + /> +
+ ) +} \ No newline at end of file diff --git a/apps/studio/components/interfaces/QueryInsights/components/MetricToggleButtons.tsx b/apps/studio/components/interfaces/QueryInsights/components/MetricToggleButtons.tsx index 5211cdfa563..66db2eab180 100644 --- a/apps/studio/components/interfaces/QueryInsights/components/MetricToggleButtons.tsx +++ b/apps/studio/components/interfaces/QueryInsights/components/MetricToggleButtons.tsx @@ -144,12 +144,7 @@ export const MetricToggleButtons = ({ isActive={visibleMetrics[keyMappings[key] || key]} onClick={() => { const targetKey = keyMappings[key] || key - console.log(`[MetricToggleButtons] Toggle clicked for ${key}:`, { - targetKey, - currentValue: visibleMetrics[targetKey], - keyMappings: keyMappings, - allVisibleMetrics: visibleMetrics - }) + setVisibleMetrics((prev) => ({ ...prev, [targetKey]: !prev[targetKey], diff --git a/apps/studio/components/interfaces/QueryInsights/components/MetricsChart.tsx b/apps/studio/components/interfaces/QueryInsights/components/MetricsChart.tsx index 051cf5f920e..24998bfdde0 100644 --- a/apps/studio/components/interfaces/QueryInsights/components/MetricsChart.tsx +++ b/apps/studio/components/interfaces/QueryInsights/components/MetricsChart.tsx @@ -229,14 +229,7 @@ export function MetricsChart(props: MetricsChartProps) { // Map the key to the corresponding visibleMetrics key const visibleMetricsKey = (keyMappings as Record)[key] || key - // Debug logging for toggle button troubleshooting - console.log(`[MetricsChart] Rendering series ${key}:`, { - visibleMetricsKey, - visibleMetricsValue: visibleMetrics[visibleMetricsKey], - directValue: visibleMetrics[key], - shouldRender: visibleMetrics[visibleMetricsKey] || visibleMetrics[key], - keyMappings: keyMappings, - }) + // Skip series not enabled in visible metrics // If we have keyMappings, only check the mapped key diff --git a/apps/studio/components/interfaces/QueryInsights/components/QueryList.tsx b/apps/studio/components/interfaces/QueryInsights/components/QueryList.tsx index 243a93e7620..4d325e80c9d 100644 --- a/apps/studio/components/interfaces/QueryInsights/components/QueryList.tsx +++ b/apps/studio/components/interfaces/QueryInsights/components/QueryList.tsx @@ -3,7 +3,7 @@ import { useRef, useState, useEffect } from 'react' import DataGrid, { Column, DataGridHandle, Row } from 'react-data-grid' import { QueryInsightsQuery } from 'data/query-insights/query-insights-query' import dayjs from 'dayjs' -import { cn, CodeBlock, Tooltip, TooltipContent, TooltipTrigger } from 'ui' +import { cn, CodeBlock } from 'ui' import { TextSearch } from 'lucide-react' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' diff --git a/apps/studio/components/interfaces/QueryInsights/hooks/useChartConfig.ts b/apps/studio/components/interfaces/QueryInsights/hooks/useChartConfig.ts index f66a602cc84..a9757b7f610 100644 --- a/apps/studio/components/interfaces/QueryInsights/hooks/useChartConfig.ts +++ b/apps/studio/components/interfaces/QueryInsights/hooks/useChartConfig.ts @@ -63,12 +63,7 @@ export function useQueryLatencyChart({ const { ref } = useParams() const isActive = metric === 'query_latency' - console.log( - '[useQueryLatencyChart] selectedQuery:', - selectedQuery?.query_id, - 'hoveredQuery:', - hoveredQuery?.query_id - ) + // Fetch single query latency data const { data: queryLatencyData } = useSingleQueryLatency( @@ -104,11 +99,7 @@ export function useQueryLatencyChart({ queryLatencyPoints.length : 0 - console.log('[useQueryLatencyChart] Calculating metric badge:', { - avgLatency, - pointsWithLatency: queryLatencyPoints.length, - totalPoints: chartData.length, - }) + return [ { @@ -148,12 +139,7 @@ export function useRowsReadChart({ const { ref } = useParams() const isActive = metric === 'rows_read' - console.log( - '[useRowsReadChart] selectedQuery:', - selectedQuery?.query_id, - 'hoveredQuery:', - hoveredQuery?.query_id - ) + // Fetch single query rows data const { data: queryRowsData } = useSingleQueryRows( @@ -167,7 +153,7 @@ export function useRowsReadChart({ } ) - console.log('[useRowsReadChart] queryRowsData:', queryRowsData) + // Generate chart configuration const chartConfig = useMemo(() => { @@ -175,26 +161,13 @@ export function useRowsReadChart({ return null } const config = getRowsReadConfig(data, queryRowsData) - console.log('[useRowsReadChart] chartConfig result:', { - chartDataLength: config.chartData.length, - hasQueryRows: config.chartData.some((point) => point.query_rows > 0), - firstFewPoints: config.chartData.slice(0, 3), - queryRowsPoints: config.chartData.filter((point) => point.query_rows > 0), - }) + return config }, [data, queryRowsData, isActive]) // Get metrics for the selected query badge const metricBadges = useMemo(() => { - console.log('🔍 [useRowsReadChart] metricBadges useMemo triggered, isActive:', isActive, 'selectedQuery:', selectedQuery?.query_id, 'chartConfig:', !!chartConfig) - console.log('🔍 [useRowsReadChart] Conditions check:', { - isActive, - hasSelectedQuery: !!selectedQuery, - hasChartConfig: !!chartConfig, - willReturnEarly: !isActive || !selectedQuery || !chartConfig - }) if (!isActive || !selectedQuery || !chartConfig) { - console.log('🔍 [useRowsReadChart] Returning early due to conditions not met') return [] } @@ -203,15 +176,8 @@ export function useRowsReadChart({ // Calculate total rows for display - sum across all data points const totalQueryRows = chartData.reduce((sum, point) => sum + (point.query_rows ?? 0), 0) - console.log('🏷️ [useRowsReadChart] PILL metric badge calculation:', { - totalQueryRows, - chartDataPoints: chartData.length, - hasQueryRows: chartData.some((point) => point.query_rows > 0), - }) - // Show the total rows rather than just the latest point const formattedValue = formatMetricValue(totalQueryRows) - console.log('🏷️ [useRowsReadChart] PILL Final formatted value:', formattedValue, typeof formattedValue) return [ { @@ -245,12 +211,7 @@ export function useCallsChart({ const { ref } = useParams() const isActive = metric === 'calls' - console.log( - '[useCallsChart] selectedQuery:', - selectedQuery?.query_id, - 'hoveredQuery:', - hoveredQuery?.query_id - ) + // Fetch single query calls data const { data: queryCallsData } = useSingleQueryCalls(