From 906edec1b6a40a79f739264af485d8a815638b82 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Thu, 18 Jul 2024 10:24:58 +0200 Subject: [PATCH] feat: show info on healthy flags in health tooltip (#7611) This PR updates the tooltips for the health chart to also include information on how healthy flags there are. The user could make this calculation themselves before, but it'd require them to subtract the sum of stale and potentially stale flags from the total. This makes it so that they don't have to do the calculation. I've also included a bar for the healthy flags in the overview, so that it's easier to see how large a portion it is compared to the others. Also: clean up some uses of the now-deprecated VFC. ![image](https://github.com/user-attachments/assets/fa33b5ec-b5aa-472d-8ee3-329c5ed0d0c6) --- .../LineChart/LineChartComponent.tsx | 6 +- .../HealthChartTooltip/HealthChartTooltip.tsx | 113 ++++++++++-------- .../ProjectHealthChart/ProjectHealthChart.tsx | 38 +++--- .../HealthStats/HealthStats.tsx | 4 +- 4 files changed, 92 insertions(+), 69 deletions(-) diff --git a/frontend/src/component/insights/components/LineChart/LineChartComponent.tsx b/frontend/src/component/insights/components/LineChart/LineChartComponent.tsx index c8c94cb4cc..bf0d46090b 100644 --- a/frontend/src/component/insights/components/LineChart/LineChartComponent.tsx +++ b/frontend/src/component/insights/components/LineChart/LineChartComponent.tsx @@ -1,4 +1,4 @@ -import { type ReactNode, useMemo, useState, type VFC } from 'react'; +import { type ReactNode, useMemo, useState, type FC } from 'react'; import { CategoryScale, LinearScale, @@ -81,14 +81,14 @@ const customHighlightPlugin = { }, }; -const LineChartComponent: VFC<{ +const LineChartComponent: FC<{ data: ChartData<'line', unknown>; aspectRatio?: number; cover?: ReactNode; overrideOptions?: ChartOptions<'line'>; TooltipComponent?: ({ tooltip, - }: { tooltip: TooltipState | null }) => ReturnType; + }: { tooltip: TooltipState | null }) => ReturnType; }> = ({ data, aspectRatio = 2.5, diff --git a/frontend/src/component/insights/componentsChart/ProjectHealthChart/HealthChartTooltip/HealthChartTooltip.tsx b/frontend/src/component/insights/componentsChart/ProjectHealthChart/HealthChartTooltip/HealthChartTooltip.tsx index 2dd3a99c8f..96f35ba764 100644 --- a/frontend/src/component/insights/componentsChart/ProjectHealthChart/HealthChartTooltip/HealthChartTooltip.tsx +++ b/frontend/src/component/insights/componentsChart/ProjectHealthChart/HealthChartTooltip/HealthChartTooltip.tsx @@ -1,4 +1,4 @@ -import type { VFC } from 'react'; +import type { FC } from 'react'; import type { InstanceInsightsSchemaProjectFlagTrendsItem } from 'openapi'; import { Box, Divider, Paper, Typography, styled } from '@mui/material'; import { Badge } from 'component/common/Badge/Badge'; @@ -33,55 +33,70 @@ const getHealthBadgeColor = (health?: number | null) => { return 'error'; }; -const Distribution = ({ stale = 0, potentiallyStale = 0, total = 0 }) => ( - <> - - - ({ marginTop: theme.spacing(0.5) })} - > - ({ - color: theme.palette.error.border, - })} - > - {'● '} - - Stale flags: {stale} - - - ({ - color: theme.palette.warning.border, - })} - > - {'● '} - - Potentially stale flags: {potentiallyStale} - - -); +const Distribution = ({ stale = 0, potentiallyStale = 0, total = 0 }) => { + const healthyFlagCount = total - stale - potentiallyStale; -export const HealthTooltip: VFC<{ tooltip: TooltipState | null }> = ({ + return ( + <> + + ({ marginTop: theme.spacing(0.5) })} + > + ({ + color: theme.palette.error.border, + })} + > + {'● '} + + Stale flags: {stale} + + + ({ + color: theme.palette.warning.border, + })} + > + {'● '} + + Potentially stale flags: {potentiallyStale} + + + ({ + color: theme.palette.success.border, + })} + > + {'● '} + + Healthy flags: {healthyFlagCount} + + + ); +}; + +export const HealthTooltip: FC<{ tooltip: TooltipState | null }> = ({ tooltip, }) => { const data = tooltip?.dataPoints.map((point) => { diff --git a/frontend/src/component/insights/componentsChart/ProjectHealthChart/ProjectHealthChart.tsx b/frontend/src/component/insights/componentsChart/ProjectHealthChart/ProjectHealthChart.tsx index bc811db9c4..04ee11def0 100644 --- a/frontend/src/component/insights/componentsChart/ProjectHealthChart/ProjectHealthChart.tsx +++ b/frontend/src/component/insights/componentsChart/ProjectHealthChart/ProjectHealthChart.tsx @@ -1,5 +1,5 @@ import 'chartjs-adapter-date-fns'; -import { useMemo, type VFC } from 'react'; +import { type FC, useMemo } from 'react'; import type { InstanceInsightsSchema } from 'openapi'; import { HealthTooltip } from './HealthChartTooltip/HealthChartTooltip'; import { useProjectChartData } from 'component/insights/hooks/useProjectChartData'; @@ -20,7 +20,21 @@ interface IProjectHealthChartProps { isLoading?: boolean; } -export const ProjectHealthChart: VFC = ({ +type WeekData = { + total: number; + stale: number; + potentiallyStale: number; + week: string; + date?: string; +}; + +const calculateHealth = (item: WeekData) => + ( + ((item.total - item.stale - item.potentiallyStale) / item.total) * + 100 + ).toFixed(2); + +export const ProjectHealthChart: FC = ({ projectFlagTrends, isAggregate, isLoading, @@ -46,7 +60,8 @@ export const ProjectHealthChart: VFC = ({ (acc, item) => { if (item) { acc.total += item.total; - acc.stale += item.stale + item.potentiallyStale; + acc.stale += item.stale; + acc.potentiallyStale += item.potentiallyStale; } if (!acc.date) { acc.date = item?.date; @@ -56,13 +71,9 @@ export const ProjectHealthChart: VFC = ({ { total: 0, stale: 0, + potentiallyStale: 0, week: label, - } as { - total: number; - stale: number; - week: string; - date?: string; - }, + } as WeekData, ); }) .sort((a, b) => (a.week > b.week ? 1 : -1)); @@ -71,14 +82,11 @@ export const ProjectHealthChart: VFC = ({ { label: 'Health', data: weeks.map((item) => ({ - health: item.total - ? ( - ((item.total - item.stale) / item.total) * - 100 - ).toFixed(2) - : undefined, + health: item.total ? calculateHealth(item) : undefined, date: item.date, total: item.total, + stale: item.stale, + potentiallyStale: item.potentiallyStale, })), borderColor: theme.palette.primary.light, backgroundColor: fillGradientPrimary, diff --git a/frontend/src/component/insights/componentsStat/HealthStats/HealthStats.tsx b/frontend/src/component/insights/componentsStat/HealthStats/HealthStats.tsx index b0e092c79a..6be9e790b9 100644 --- a/frontend/src/component/insights/componentsStat/HealthStats/HealthStats.tsx +++ b/frontend/src/component/insights/componentsStat/HealthStats/HealthStats.tsx @@ -1,4 +1,4 @@ -import type { VFC } from 'react'; +import type { FC } from 'react'; import { useThemeMode } from 'hooks/useThemeMode'; import { useTheme } from '@mui/material'; @@ -9,7 +9,7 @@ interface IHealthStatsProps { potentiallyStale: number; } -export const HealthStats: VFC = ({ +export const HealthStats: FC = ({ value, healthy, stale,