import { styled, useTheme, Typography } from '@mui/material';
import { Link } from 'react-router-dom';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { useProjectStatus } from 'hooks/api/getters/useProjectStatus/useProjectStatus';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { HealthGridTile } from './ProjectHealthGrid.styles';
import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber';
import { getTechnicalDebtColor } from 'utils/getTechnicalDebtColor.ts';
import { useUiFlag } from 'hooks/useUiFlag';
const ChartRadius = 40;
const ChartStrokeWidth = 13;
const ChartTotalWidth = ChartRadius * 2 + ChartStrokeWidth;
const ChartContainerWidth = 100;
const TextContainer = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(1),
}));
const ChartRow = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
gap: theme.spacing(2),
}));
const SVGWrapper = styled('div')(({ theme }) => ({
flex: 'none',
height: 85,
width: ChartContainerWidth,
position: 'relative',
}));
const StyledSVG = styled('svg')({
position: 'absolute',
});
const BigText = styled('span')(({ theme }) => ({
fontSize: theme.typography.h1.fontSize,
}));
const UnhealthyStatContainer = styled('div')(({ theme }) => ({
flex: 'none',
display: 'grid',
placeItems: 'center',
width: ChartContainerWidth,
}));
const UnhealthyStatText = styled('p')(({ theme }) => ({
fontSize: theme.typography.body2.fontSize,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '50%',
backgroundColor:
theme.mode === 'light'
? theme.palette.background.elevation2
: '#302E42', // in dark mode, elevation2 and elevation1 are the same color. This is an alternative
width: ChartTotalWidth,
height: ChartTotalWidth,
overflow: 'hidden',
}));
const UnhealthyFlagBox = ({ flagCount }: { flagCount: number }) => {
const flagWord = flagCount === 1 ? 'flag' : 'flags';
return (
unhealthy
{flagWord}
);
};
const useHealthColor = (healthRating: number) => {
const theme = useTheme();
if (healthRating <= 24) {
return theme.palette.error.main;
}
if (healthRating <= 74) {
return theme.palette.warning.border;
}
return theme.palette.success.border;
};
const useTechnicalDebtColor = (techicalDebt: number) => {
const theme = useTheme();
switch (getTechnicalDebtColor(techicalDebt)) {
case 'error':
return theme.palette.error.main;
case 'warning':
return theme.palette.warning.border;
default:
return theme.palette.success.border;
}
};
const Wrapper = styled(HealthGridTile)(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-around',
gap: theme.spacing(2),
}));
export const ProjectHealth = () => {
const projectId = useRequiredPathParam('projectId');
const {
data: { health, technicalDebt, staleFlags },
} = useProjectStatus(projectId);
const { isOss } = useUiConfig();
const theme = useTheme();
const healthToDebtEnabled = useUiFlag('healthToTechDebt');
const circumference = 2 * Math.PI * ChartRadius;
const healthRating = health.current;
const gapLength = 0.3;
const filledLength = 1 - gapLength;
const offset = 0.75 - gapLength / 2;
const healthLength = (healthRating / 100) * circumference * 0.7;
const technicalDebtLength =
((technicalDebt.current || 0) / 100) * circumference * 0.7;
const healthColor = useHealthColor(healthRating);
const technicalDebtColor = useTechnicalDebtColor(
technicalDebt.current || 0,
);
return (
{healthToDebtEnabled
? technicalDebt.current || 0
: healthRating}
%
{healthToDebtEnabled ? (
<>
Your current technical debt rating is{' '}
{technicalDebt.current}%.
>
) : (
<>
Your current project health rating is{' '}
{healthRating}%.
>
)}
{!isOss() && (
{healthToDebtEnabled
? 'View technical debt over time'
: 'View health over time'}
)}
To keep your project healthy, archive stale feature
flags and remove code from your code base to reduce
technical debt.
View unhealthy flags
);
};