1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-10-27 11:02:16 +01:00

fix: show average ratio for the period of collected data (#10735)

Instead of showing the current ratio of archived to created flags, we
show you the average ratio for the selected period.

Before:
<img width="1153" height="391" alt="image"
src="https://github.com/user-attachments/assets/efe87982-544e-485a-aa4d-04faa7d552fc"
/>

After:
<img width="1143" height="385" alt="image"
src="https://github.com/user-attachments/assets/25f8ee4d-3eaa-4e01-a793-2cc0321a55ed"
/>
This commit is contained in:
Thomas Heartman 2025-10-06 13:05:21 +02:00 committed by GitHub
parent b1f4ebd5eb
commit 236addbe23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 156 additions and 34 deletions

View File

@ -7,36 +7,7 @@ import { StatsExplanation } from 'component/insights/InsightsCharts.styles';
import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends'; import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends';
import type { InstanceInsightsSchema } from 'openapi'; import type { InstanceInsightsSchema } from 'openapi';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { calculateRatio } from 'component/insights/calculate-ratio/calculate-ratio'; import { calculateArchiveRatio } from './calculateArchiveRatio.ts';
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 calculateRatio(totalArchived, totalCreated);
}
const StyledRatioContainer = styled(Box)(({ theme }) => ({ const StyledRatioContainer = styled(Box)(({ theme }) => ({
backgroundColor: theme.palette.background.elevation1, backgroundColor: theme.palette.background.elevation1,
@ -83,20 +54,20 @@ export const CreationArchiveStats: FC<CreationArchiveStatsProps> = ({
groupedCreationArchiveData, groupedCreationArchiveData,
isLoading, isLoading,
}) => { }) => {
const currentRatio = getCurrentArchiveRatio(groupedCreationArchiveData); const averageRatio = calculateArchiveRatio(groupedCreationArchiveData);
return ( return (
<> <>
<StyledRatioContainer> <StyledRatioContainer>
<StyledPercentageRow> <StyledPercentageRow>
<StyledRatioTypography> <StyledRatioTypography>
{isLoading ? '...' : currentRatio} {isLoading ? '...' : averageRatio}
</StyledRatioTypography> </StyledRatioTypography>
<HelpIcon tooltip='Ratio of archived flags to created flags'> <HelpIcon tooltip='Ratio of archived flags to created flags in the selected period'>
<StyledInfoIcon /> <StyledInfoIcon />
</HelpIcon> </HelpIcon>
</StyledPercentageRow> </StyledPercentageRow>
<Typography variant='body2'>Current ratio</Typography> <Typography variant='body2'>Average ratio</Typography>
</StyledRatioContainer> </StyledRatioContainer>
<StatsExplanation> <StatsExplanation>
<Lightbulb color='primary' /> <Lightbulb color='primary' />

View File

@ -0,0 +1,114 @@
import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends.ts';
import { calculateArchiveRatio } from './calculateArchiveRatio.ts';
import type { InstanceInsightsSchema } from 'openapi/index.ts';
describe('calculateArchiveRatio', () => {
it('should return "N/A" when the data is empty', () => {
expect(calculateArchiveRatio({})).toBe('N/A');
});
it('should return "N/A" when no flags have been created', () => {
const result = calculateArchiveRatio({
a: [
{
week: '2024-53',
date: '2025-01-05T01:00:00.000Z',
project: 'a',
createdFlags: {
release: 0,
},
archivedFlags: 10,
},
],
});
expect(result).toBe('N/A');
});
it('should count missing `createdFlags` and `archivedFlags` properties as 0', () => {
const result = calculateArchiveRatio({
project: [
// @ts-expect-error: the type requires `createdFlags` to be present
{
week: '2024-53',
date: '2025-01-05T01:00:00.000Z',
project: 'a',
archivedFlags: 1,
},
// @ts-expect-error: the type requires `archivedFlags` to be present
{
week: '2024-53',
date: '2025-01-05T01:00:00.000Z',
project: 'a',
createdFlags: {
release: 1,
},
},
],
});
expect(result).toBe('100%');
});
it('should count all flag types listed under createdFlags', () => {
const input: GroupedDataByProject<
InstanceInsightsSchema['creationArchiveTrends']
> = {
projectA: [
{
week: '2025-40',
date: '2025-10-05T00:21:42.617Z',
project: 'projectA',
createdFlags: {
release: 1,
killswitch: 1,
experiment: 1,
operational: 1,
bogus: 1,
},
archivedFlags: 5,
},
],
};
expect(calculateArchiveRatio(input)).toBe('100%');
});
it('should take the average of all data points', () => {
const input: GroupedDataByProject<
InstanceInsightsSchema['creationArchiveTrends']
> = {
projectA: [
{
week: '2025-40',
date: '2025-10-05T00:21:42.617Z',
project: 'projectA',
createdFlags: {
release: 1,
},
archivedFlags: 2,
},
{
week: '2025-38',
date: '2025-09-22T10:36:58.612Z',
project: 'projectA',
createdFlags: {
killswitch: 6,
},
archivedFlags: 7,
},
],
projectB: [
{
week: '2025-03',
date: '2025-01-19T01:00:00.000Z',
project: 'projectB',
createdFlags: {
release: 0,
},
archivedFlags: 5,
},
],
};
expect(calculateArchiveRatio(input)).toBe('200%');
});
});

View File

@ -0,0 +1,37 @@
import { calculateRatio } from 'component/insights/calculate-ratio/calculate-ratio';
import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends';
import type { InstanceInsightsSchema } from 'openapi';
export const calculateArchiveRatio = (
groupedCreationArchiveData: GroupedDataByProject<
InstanceInsightsSchema['creationArchiveTrends']
>,
): string => {
const { totalCreated, totalArchived } = Object.values(
groupedCreationArchiveData,
).reduce(
(totalAcc, totalCurr) => {
const { created, archived } = totalCurr.reduce(
(acc, curr) => {
const createdSum = curr.createdFlags
? Object.values(curr.createdFlags).reduce(
(sum, count) => sum + count,
0,
)
: 0;
return {
created: acc.created + createdSum,
archived: acc.archived + (curr.archivedFlags ?? 0),
};
},
{ created: 0, archived: 0 },
);
return {
totalCreated: totalAcc.totalCreated + created,
totalArchived: totalAcc.totalArchived + archived,
};
},
{ totalCreated: 0, totalArchived: 0 },
);
return calculateRatio(totalArchived, totalCreated);
};