import 'chartjs-adapter-date-fns'; import { useMemo, type VFC } from 'react'; import type { InstanceInsightsSchema } from 'openapi'; import { HealthTooltip } from './HealthChartTooltip/HealthChartTooltip'; import { useProjectChartData } from 'component/insights/hooks/useProjectChartData'; import { fillGradientPrimary, LineChart, NotEnoughData, } from 'component/insights/components/LineChart/LineChart'; import { useTheme } from '@mui/material'; import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends'; interface IProjectHealthChartProps { projectFlagTrends: GroupedDataByProject< InstanceInsightsSchema['projectFlagTrends'] >; isAggregate?: boolean; } export const ProjectHealthChart: VFC = ({ projectFlagTrends, isAggregate, }) => { const projectsData = useProjectChartData(projectFlagTrends); const theme = useTheme(); const aggregateHealthData = useMemo(() => { const labels = Array.from( new Set( projectsData.datasets.flatMap((d) => d.data.map((item) => item.week), ), ), ); const weeks = labels .map((label) => { return projectsData.datasets .map((d) => d.data.find((item) => item.week === label)) .reduce( (acc, item) => { if (item) { acc.total += item.total; acc.stale += item.stale + item.potentiallyStale; } if (!acc.date) { acc.date = item?.date; } return acc; }, { total: 0, stale: 0, week: label, } as { total: number; stale: number; week: string; date?: string; }, ); }) .sort((a, b) => (a.week > b.week ? 1 : -1)); return { datasets: [ { label: 'Health', data: weeks.map((item) => ({ health: item.total ? ((item.total - item.stale) / item.total) * 100 : undefined, date: item.date, })), borderColor: theme.palette.primary.light, backgroundColor: fillGradientPrimary, fill: true, order: 3, }, ], }; }, [projectsData, theme]); const data = isAggregate ? aggregateHealthData : projectsData; const notEnoughData = useMemo( () => projectsData.datasets.some((d) => d.data.length > 1) ? false : true, [projectsData], ); return ( : false} /> ); };