import { Lightbulb, ChevronsUpDown } from 'lucide-react' import { useEffect, useState } from 'react' import dynamic from 'next/dynamic' import { formatSql } from 'lib/formatSql' import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button, cn } from 'ui' import { QueryPanelContainer, QueryPanelSection } from './QueryPanel' import { QUERY_PERFORMANCE_COLUMNS, QUERY_PERFORMANCE_REPORT_TYPES, } from './QueryPerformance.constants' import { formatDuration } from './QueryPerformance.utils' interface QueryDetailProps { reportType: QUERY_PERFORMANCE_REPORT_TYPES selectedRow: any onClickViewSuggestion: () => void } // Load SqlMonacoBlock (monaco editor) client-side only (does not behave well server-side) const SqlMonacoBlock = dynamic( () => import('./SqlMonacoBlock').then(({ SqlMonacoBlock }) => SqlMonacoBlock), { ssr: false, } ) export const QueryDetail = ({ selectedRow, onClickViewSuggestion }: QueryDetailProps) => { // [Joshen] TODO implement this logic once the linter rules are in const isLinterWarning = false const report = QUERY_PERFORMANCE_COLUMNS const [query, setQuery] = useState(selectedRow?.['query']) useEffect(() => { if (selectedRow !== undefined) { const formattedQuery = formatSql(selectedRow['query']) setQuery(formattedQuery) } }, [selectedRow]) const [isExpanded, setIsExpanded] = useState(false) return (

Query pattern

{isLinterWarning && ( Suggested optimization: Add an index Adding an index will help this query execute faster )}

Metadata

    {report .filter((x) => x.id !== 'query') .map((x) => { const rawValue = selectedRow?.[x.id] const isTime = x.name.includes('time') const formattedValue = isTime ? typeof rawValue === 'number' && !isNaN(rawValue) && isFinite(rawValue) ? `${Math.round(rawValue).toLocaleString()}ms` : 'n/a' : rawValue != null ? String(rawValue) : 'n/a' if (x.id === 'prop_total_time') { const percentage = selectedRow?.prop_total_time || 0 const totalTime = selectedRow?.total_time || 0 return (
  • {x.name}

    {percentage && totalTime ? (

    {percentage.toFixed(1)}% {' '} /{' '} {formatDuration(totalTime)}

    ) : (

    )}
  • ) } if (x.id == 'rows_read') { return (
  • {x.name}

    {typeof rawValue === 'number' && !isNaN(rawValue) && isFinite(rawValue) ? (

    {rawValue.toLocaleString()}

    ) : (

    )}
  • ) } const cacheHitRateToNumber = (value: number | string) => { if (typeof value === 'number') return value return parseFloat(value.toString().replace('%', '')) || 0 } if (x.id === 'cache_hit_rate') { return (
  • {x.name}

    {typeof rawValue === 'string' || typeof rawValue === 'number' ? (

    {cacheHitRateToNumber(rawValue).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2, })} %

    ) : (

    )}
  • ) } return (
  • {x.name}

    {formattedValue}

  • ) })}
) }