QueryInsightsHealth.tsx61 lines · main
1import type { QueryPerformanceRow } from '../../QueryPerformance/QueryPerformance.types'
2import { useQueryInsightsIssues } from '../hooks/useQueryInsightsIssues'
3import { useQueryInsightsMetrics } from '../hooks/useQueryInsightsMetrics'
4import { useQueryInsightsScore } from '../hooks/useQueryInsightsScore'
5import { HEALTH_COLORS, HEALTH_LEVELS } from './QueryInsightsHealth.constants'
6import { QueryInsightsHealthMetric } from './QueryInsightsHealthMetric'
7import { QueryInsightsHealthScore } from './QueryInsightsHealthScore'
8import { QueryInsightsHealthScoreSkeleton } from './QueryInsightsHealthScoreSkeleton'
9
10interface QueryInsightsHealthProps {
11 data: QueryPerformanceRow[]
12 isLoading: boolean
13}
14
15export const QueryInsightsHealth = ({ data, isLoading }: QueryInsightsHealthProps) => {
16 const { errors, indexIssues, slowQueries } = useQueryInsightsIssues(data)
17 const { score, level } = useQueryInsightsScore({ errors, indexIssues, slowQueries })
18 const { avgP95, totalCalls, totalRowsRead, cacheHitRate } = useQueryInsightsMetrics(data)
19
20 const color = HEALTH_COLORS[level]
21 const label = HEALTH_LEVELS[level].label
22
23 return (
24 <div className="w-full border-b flex items-center">
25 <div className="px-6 py-3 flex items-center gap-3">
26 {isLoading ? (
27 <QueryInsightsHealthScoreSkeleton />
28 ) : (
29 <QueryInsightsHealthScore score={score} color={color} label={label} />
30 )}
31 </div>
32 <div className="flex-1 border-l h-full">
33 <div className="grid grid-cols-2">
34 <QueryInsightsHealthMetric
35 label="Average P95"
36 value={`${avgP95}ms`}
37 className="border-b"
38 isLoading={isLoading}
39 />
40 <QueryInsightsHealthMetric
41 label="Total Calls"
42 value={totalCalls.toLocaleString()}
43 className="border-l border-b"
44 isLoading={isLoading}
45 />
46 <QueryInsightsHealthMetric
47 label="Total Rows Read"
48 value={totalRowsRead.toLocaleString()}
49 isLoading={isLoading}
50 />
51 <QueryInsightsHealthMetric
52 label="Cache Hit Rate"
53 value={cacheHitRate}
54 className="border-l"
55 isLoading={isLoading}
56 />
57 </div>
58 </div>
59 </div>
60 )
61}