1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-10-13 11:17:26 +02:00
unleash.unleash/frontend/src/component/insights/componentsStat/CreationArchiveStats/CreationArchiveStats.tsx
Thomas Heartman 709a890bd8
fix: incorrect current calculation of ratio (#10567)
Looks like the sinner was looking at the last entry of each data list,
when they are sorted by most recent first.
2025-08-28 15:53:25 +02:00

113 lines
3.6 KiB
TypeScript

import type { FC } from 'react';
import { Box, Typography, styled } from '@mui/material';
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
import InfoOutlined from '@mui/icons-material/InfoOutlined';
import Lightbulb from '@mui/icons-material/LightbulbOutlined';
import { StatsExplanation } from 'component/insights/InsightsCharts.styles';
import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends';
import type { InstanceInsightsSchema } from 'openapi';
import { Link } from 'react-router-dom';
function getCurrentArchiveRatio(
groupedCreationArchiveData: GroupedDataByProject<
InstanceInsightsSchema['creationArchiveTrends']
>,
) {
if (!groupedCreationArchiveData) {
return 0;
}
let totalArchived = 0;
let totalCreated = 0;
Object.values(groupedCreationArchiveData).forEach((projectData) => {
const latestData = projectData[0];
if (latestData) {
totalArchived += latestData.archivedFlags || 0;
const createdSum = latestData.createdFlags
? Object.values(latestData.createdFlags).reduce(
(sum: number, count: number) => sum + count,
0,
)
: 0;
totalCreated += createdSum;
}
});
return totalCreated > 0
? Math.round((totalArchived / totalCreated) * 100)
: 0;
}
const StyledRatioContainer = styled(Box)(({ theme }) => ({
backgroundColor: theme.palette.background.elevation1,
borderRadius: theme.spacing(2),
padding: theme.spacing(2),
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(0.5),
}));
const StyledPercentageRow = styled(Box)(({ theme }) => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}));
const StyledRatioTypography = styled(Typography)(({ theme }) => ({
color: theme.palette.primary.main,
fontSize: theme.spacing(2.5),
fontWeight: 'bold',
}));
const StyledInfoIcon = styled(InfoOutlined)(({ theme }) => ({
color: theme.palette.text.secondary,
}));
const StyledLink = styled(Link)(({ theme }) => ({
color: theme.palette.primary.main,
textDecoration: 'none',
'&:hover': {
textDecoration: 'underline',
},
fontSize: theme.spacing(1.75),
}));
interface CreationArchiveStatsProps {
groupedCreationArchiveData: GroupedDataByProject<
InstanceInsightsSchema['creationArchiveTrends']
>;
isLoading?: boolean;
}
export const CreationArchiveStats: FC<CreationArchiveStatsProps> = ({
groupedCreationArchiveData,
isLoading,
}) => {
const currentRatio = getCurrentArchiveRatio(groupedCreationArchiveData);
return (
<>
<StyledRatioContainer>
<StyledPercentageRow>
<StyledRatioTypography>
{isLoading ? '...' : `${currentRatio}%`}
</StyledRatioTypography>
<HelpIcon tooltip='Ratio of archived flags to created flags'>
<StyledInfoIcon />
</HelpIcon>
</StyledPercentageRow>
<Typography variant='body2'>Current ratio</Typography>
</StyledRatioContainer>
<StatsExplanation>
<Lightbulb color='primary' />
Do you create more flags than you archive? Or do you have good
process for cleaning up?
</StatsExplanation>
<StyledLink to='/search?lifecycle=IS:completed'>
View flags in cleanup stage
</StyledLink>
</>
);
};