mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-18 00:19:49 +01:00
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. 
This commit is contained in:
parent
06f5073fce
commit
906edec1b6
@ -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<VFC>;
|
||||
}: { tooltip: TooltipState | null }) => ReturnType<FC>;
|
||||
}> = ({
|
||||
data,
|
||||
aspectRatio = 2.5,
|
||||
|
@ -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 }) => (
|
||||
<>
|
||||
<HorizontalDistributionChart
|
||||
sections={[{ type: 'default', value: 100 }]}
|
||||
size='small'
|
||||
/>
|
||||
<HorizontalDistributionChart
|
||||
sections={[
|
||||
{
|
||||
type: 'error',
|
||||
value: (stale / total) * 100,
|
||||
},
|
||||
{
|
||||
type: 'warning',
|
||||
value: (potentiallyStale / total) * 100,
|
||||
},
|
||||
]}
|
||||
size='small'
|
||||
/>
|
||||
<Typography
|
||||
variant='body2'
|
||||
component='p'
|
||||
sx={(theme) => ({ marginTop: theme.spacing(0.5) })}
|
||||
>
|
||||
<Typography
|
||||
component='span'
|
||||
sx={(theme) => ({
|
||||
color: theme.palette.error.border,
|
||||
})}
|
||||
>
|
||||
{'● '}
|
||||
</Typography>
|
||||
Stale flags: {stale}
|
||||
</Typography>
|
||||
<Typography variant='body2' component='p'>
|
||||
<Typography
|
||||
component='span'
|
||||
sx={(theme) => ({
|
||||
color: theme.palette.warning.border,
|
||||
})}
|
||||
>
|
||||
{'● '}
|
||||
</Typography>
|
||||
Potentially stale flags: {potentiallyStale}
|
||||
</Typography>
|
||||
</>
|
||||
);
|
||||
const Distribution = ({ stale = 0, potentiallyStale = 0, total = 0 }) => {
|
||||
const healthyFlagCount = total - stale - potentiallyStale;
|
||||
|
||||
export const HealthTooltip: VFC<{ tooltip: TooltipState | null }> = ({
|
||||
return (
|
||||
<>
|
||||
<HorizontalDistributionChart
|
||||
sections={[
|
||||
{
|
||||
type: 'error',
|
||||
value: (stale / total) * 100,
|
||||
},
|
||||
{
|
||||
type: 'warning',
|
||||
value: (potentiallyStale / total) * 100,
|
||||
},
|
||||
{
|
||||
type: 'success',
|
||||
value: (healthyFlagCount / total) * 100,
|
||||
},
|
||||
]}
|
||||
size='small'
|
||||
/>
|
||||
<Typography
|
||||
variant='body2'
|
||||
component='p'
|
||||
sx={(theme) => ({ marginTop: theme.spacing(0.5) })}
|
||||
>
|
||||
<Typography
|
||||
component='span'
|
||||
sx={(theme) => ({
|
||||
color: theme.palette.error.border,
|
||||
})}
|
||||
>
|
||||
{'● '}
|
||||
</Typography>
|
||||
Stale flags: {stale}
|
||||
</Typography>
|
||||
<Typography variant='body2' component='p'>
|
||||
<Typography
|
||||
component='span'
|
||||
sx={(theme) => ({
|
||||
color: theme.palette.warning.border,
|
||||
})}
|
||||
>
|
||||
{'● '}
|
||||
</Typography>
|
||||
Potentially stale flags: {potentiallyStale}
|
||||
</Typography>
|
||||
<Typography variant='body2' component='p'>
|
||||
<Typography
|
||||
component='span'
|
||||
sx={(theme) => ({
|
||||
color: theme.palette.success.border,
|
||||
})}
|
||||
>
|
||||
{'● '}
|
||||
</Typography>
|
||||
Healthy flags: {healthyFlagCount}
|
||||
</Typography>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const HealthTooltip: FC<{ tooltip: TooltipState | null }> = ({
|
||||
tooltip,
|
||||
}) => {
|
||||
const data = tooltip?.dataPoints.map((point) => {
|
||||
|
@ -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<IProjectHealthChartProps> = ({
|
||||
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<IProjectHealthChartProps> = ({
|
||||
projectFlagTrends,
|
||||
isAggregate,
|
||||
isLoading,
|
||||
@ -46,7 +60,8 @@ export const ProjectHealthChart: VFC<IProjectHealthChartProps> = ({
|
||||
(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<IProjectHealthChartProps> = ({
|
||||
{
|
||||
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<IProjectHealthChartProps> = ({
|
||||
{
|
||||
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,
|
||||
|
@ -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<IHealthStatsProps> = ({
|
||||
export const HealthStats: FC<IHealthStatsProps> = ({
|
||||
value,
|
||||
healthy,
|
||||
stale,
|
||||
|
Loading…
Reference in New Issue
Block a user