mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-23 00:22:19 +01:00
fix: do not show flagsPerUser when calculation results to NaN (#6639)
What it says on the tin Closes # [1-2209](https://linear.app/unleash/issue/1-2209/total-flag-widget-says-nan-when-no-data) --------- Signed-off-by: andreas-unleash <andreas@getunleash.ai> Co-authored-by: Thomas Heartman <thomas@getunleash.io>
This commit is contained in:
parent
3241d14a05
commit
bce25bf0f1
@ -39,6 +39,7 @@ interface IChartsProps {
|
|||||||
potentiallyStale: number;
|
potentiallyStale: number;
|
||||||
averageUsers: number;
|
averageUsers: number;
|
||||||
averageHealth?: string;
|
averageHealth?: string;
|
||||||
|
flagsPerUser?: string;
|
||||||
};
|
};
|
||||||
avgDaysToProduction: number;
|
avgDaysToProduction: number;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
@ -124,9 +125,7 @@ export const Charts: VFC<IChartsProps> = ({
|
|||||||
<FlagStats
|
<FlagStats
|
||||||
count={summary.total}
|
count={summary.total}
|
||||||
flagsPerUser={
|
flagsPerUser={
|
||||||
showAllProjects
|
showAllProjects ? summary.flagsPerUser : ''
|
||||||
? (summary.total / users.total).toFixed(2)
|
|
||||||
: ''
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
@ -22,7 +22,10 @@ export const useDashboardData = (
|
|||||||
);
|
);
|
||||||
const groupedMetricsData = useGroupedProjectTrends(metricsData);
|
const groupedMetricsData = useGroupedProjectTrends(metricsData);
|
||||||
|
|
||||||
const summary = useFilteredFlagsSummary(projectsData);
|
const summary = useFilteredFlagsSummary(
|
||||||
|
projectsData,
|
||||||
|
executiveDashboardData.users,
|
||||||
|
);
|
||||||
|
|
||||||
const avgDaysToProduction = useAvgTimeToProduction(groupedProjectsData);
|
const avgDaysToProduction = useAvgTimeToProduction(groupedProjectsData);
|
||||||
|
|
||||||
|
@ -1,51 +1,55 @@
|
|||||||
import { renderHook } from '@testing-library/react-hooks';
|
import { renderHook } from '@testing-library/react-hooks';
|
||||||
import { useFilteredFlagsSummary } from './useFilteredFlagsSummary';
|
import { useFilteredFlagsSummary } from './useFilteredFlagsSummary';
|
||||||
|
import type { ExecutiveSummarySchemaUsers } from '../../../openapi';
|
||||||
|
|
||||||
describe('useFilteredFlagTrends', () => {
|
describe('useFilteredFlagTrends', () => {
|
||||||
it('should summarize only last week of project flag trends', () => {
|
it('should summarize only last week of project flag trends', () => {
|
||||||
const { result } = renderHook(() =>
|
const { result } = renderHook(() =>
|
||||||
useFilteredFlagsSummary([
|
useFilteredFlagsSummary(
|
||||||
{
|
[
|
||||||
week: '2024-01',
|
{
|
||||||
project: 'project1',
|
week: '2024-01',
|
||||||
total: 1,
|
project: 'project1',
|
||||||
active: 1,
|
total: 1,
|
||||||
stale: 0,
|
active: 1,
|
||||||
potentiallyStale: 0,
|
stale: 0,
|
||||||
users: 1,
|
potentiallyStale: 0,
|
||||||
date: '',
|
users: 1,
|
||||||
},
|
date: '',
|
||||||
{
|
},
|
||||||
week: '2024-01',
|
{
|
||||||
project: 'project2',
|
week: '2024-01',
|
||||||
total: 2,
|
project: 'project2',
|
||||||
active: 2,
|
total: 2,
|
||||||
stale: 0,
|
active: 2,
|
||||||
potentiallyStale: 0,
|
stale: 0,
|
||||||
users: 2,
|
potentiallyStale: 0,
|
||||||
date: '',
|
users: 2,
|
||||||
},
|
date: '',
|
||||||
{
|
},
|
||||||
week: '2024-02',
|
{
|
||||||
project: 'project1',
|
week: '2024-02',
|
||||||
total: 4,
|
project: 'project1',
|
||||||
active: 3,
|
total: 4,
|
||||||
stale: 0,
|
active: 3,
|
||||||
potentiallyStale: 1,
|
stale: 0,
|
||||||
users: 1,
|
potentiallyStale: 1,
|
||||||
date: '',
|
users: 1,
|
||||||
},
|
date: '',
|
||||||
{
|
},
|
||||||
week: '2024-02',
|
{
|
||||||
project: 'project3',
|
week: '2024-02',
|
||||||
total: 10,
|
project: 'project3',
|
||||||
active: 8,
|
total: 10,
|
||||||
stale: 2,
|
active: 8,
|
||||||
potentiallyStale: 0,
|
stale: 2,
|
||||||
users: 3,
|
potentiallyStale: 0,
|
||||||
date: '',
|
users: 3,
|
||||||
},
|
date: '',
|
||||||
]),
|
},
|
||||||
|
],
|
||||||
|
{ total: 1 } as unknown as ExecutiveSummarySchemaUsers,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result.current).toEqual({
|
expect(result.current).toEqual({
|
||||||
@ -55,23 +59,27 @@ describe('useFilteredFlagTrends', () => {
|
|||||||
potentiallyStale: 1,
|
potentiallyStale: 1,
|
||||||
averageUsers: 2,
|
averageUsers: 2,
|
||||||
averageHealth: '79',
|
averageHealth: '79',
|
||||||
|
flagsPerUser: '14.00',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with project with zero users', () => {
|
it('should work with project with zero users', () => {
|
||||||
const { result, rerender } = renderHook(() =>
|
const { result, rerender } = renderHook(() =>
|
||||||
useFilteredFlagsSummary([
|
useFilteredFlagsSummary(
|
||||||
{
|
[
|
||||||
week: '2024-01',
|
{
|
||||||
project: 'project1',
|
week: '2024-01',
|
||||||
total: 5,
|
project: 'project1',
|
||||||
active: 5,
|
total: 5,
|
||||||
stale: 0,
|
active: 5,
|
||||||
potentiallyStale: 0,
|
stale: 0,
|
||||||
users: 0,
|
potentiallyStale: 0,
|
||||||
date: '',
|
users: 0,
|
||||||
},
|
date: '',
|
||||||
]),
|
},
|
||||||
|
],
|
||||||
|
{ total: 1 } as unknown as ExecutiveSummarySchemaUsers,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result.current).toEqual({
|
expect(result.current).toEqual({
|
||||||
@ -81,33 +89,37 @@ describe('useFilteredFlagTrends', () => {
|
|||||||
potentiallyStale: 0,
|
potentiallyStale: 0,
|
||||||
averageUsers: 0,
|
averageUsers: 0,
|
||||||
averageHealth: '100',
|
averageHealth: '100',
|
||||||
|
flagsPerUser: '5.00',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with projects where some have with zero users', () => {
|
it('should work with projects where some have with zero users', () => {
|
||||||
const { result } = renderHook(() =>
|
const { result } = renderHook(() =>
|
||||||
useFilteredFlagsSummary([
|
useFilteredFlagsSummary(
|
||||||
{
|
[
|
||||||
week: '2024-01',
|
{
|
||||||
project: 'project1',
|
week: '2024-01',
|
||||||
total: 5,
|
project: 'project1',
|
||||||
active: 5,
|
total: 5,
|
||||||
stale: 0,
|
active: 5,
|
||||||
potentiallyStale: 0,
|
stale: 0,
|
||||||
users: 0,
|
potentiallyStale: 0,
|
||||||
date: '',
|
users: 0,
|
||||||
},
|
date: '',
|
||||||
{
|
},
|
||||||
week: '2024-01',
|
{
|
||||||
project: 'project2',
|
week: '2024-01',
|
||||||
total: 5,
|
project: 'project2',
|
||||||
active: 5,
|
total: 5,
|
||||||
stale: 0,
|
active: 5,
|
||||||
potentiallyStale: 0,
|
stale: 0,
|
||||||
users: 3,
|
potentiallyStale: 0,
|
||||||
date: '',
|
users: 3,
|
||||||
},
|
date: '',
|
||||||
]),
|
},
|
||||||
|
],
|
||||||
|
{ total: 1 } as unknown as ExecutiveSummarySchemaUsers,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result.current).toEqual({
|
expect(result.current).toEqual({
|
||||||
@ -117,23 +129,27 @@ describe('useFilteredFlagTrends', () => {
|
|||||||
potentiallyStale: 0,
|
potentiallyStale: 0,
|
||||||
averageUsers: 1.5,
|
averageUsers: 1.5,
|
||||||
averageHealth: '100',
|
averageHealth: '100',
|
||||||
|
flagsPerUser: '10.00',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set health of a project without feature toggles to undefined', () => {
|
it('should set health of a project without feature toggles to undefined', () => {
|
||||||
const { result } = renderHook(() =>
|
const { result } = renderHook(() =>
|
||||||
useFilteredFlagsSummary([
|
useFilteredFlagsSummary(
|
||||||
{
|
[
|
||||||
week: '2024-01',
|
{
|
||||||
project: 'project1',
|
week: '2024-01',
|
||||||
total: 0,
|
project: 'project1',
|
||||||
active: 0,
|
total: 0,
|
||||||
stale: 0,
|
active: 0,
|
||||||
potentiallyStale: 0,
|
stale: 0,
|
||||||
users: 0,
|
potentiallyStale: 0,
|
||||||
date: '',
|
users: 0,
|
||||||
},
|
date: '',
|
||||||
]),
|
},
|
||||||
|
],
|
||||||
|
{ total: 1 } as unknown as ExecutiveSummarySchemaUsers,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result.current).toEqual({
|
expect(result.current).toEqual({
|
||||||
@ -143,6 +159,7 @@ describe('useFilteredFlagTrends', () => {
|
|||||||
potentiallyStale: 0,
|
potentiallyStale: 0,
|
||||||
averageUsers: 0,
|
averageUsers: 0,
|
||||||
averageHealth: undefined,
|
averageHealth: undefined,
|
||||||
|
flagsPerUser: '0.00',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import type { ExecutiveSummarySchemaProjectFlagTrendsItem } from 'openapi';
|
import type {
|
||||||
|
ExecutiveSummarySchemaProjectFlagTrendsItem,
|
||||||
|
ExecutiveSummarySchemaUsers,
|
||||||
|
} from 'openapi';
|
||||||
|
|
||||||
// NOTE: should we move project filtering to the backend?
|
// NOTE: should we move project filtering to the backend?
|
||||||
export const useFilteredFlagsSummary = (
|
export const useFilteredFlagsSummary = (
|
||||||
filteredProjectFlagTrends: ExecutiveSummarySchemaProjectFlagTrendsItem[],
|
filteredProjectFlagTrends: ExecutiveSummarySchemaProjectFlagTrendsItem[],
|
||||||
|
users: ExecutiveSummarySchemaUsers,
|
||||||
) =>
|
) =>
|
||||||
useMemo(() => {
|
useMemo(() => {
|
||||||
const lastWeekId = filteredProjectFlagTrends.reduce((prev, current) => {
|
const lastWeekId = filteredProjectFlagTrends.reduce((prev, current) => {
|
||||||
@ -38,8 +42,14 @@ export const useFilteredFlagsSummary = (
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const flagsPerUserCalculation = sum.total / users.total;
|
||||||
|
const flagsPerUser = Number.isNaN(flagsPerUserCalculation)
|
||||||
|
? 'N/A'
|
||||||
|
: flagsPerUserCalculation.toFixed(2);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...sum,
|
...sum,
|
||||||
|
flagsPerUser,
|
||||||
averageUsers,
|
averageUsers,
|
||||||
averageHealth: sum.total
|
averageHealth: sum.total
|
||||||
? ((sum.active / (sum.total || 1)) * 100).toFixed(0)
|
? ((sum.active / (sum.total || 1)) * 100).toFixed(0)
|
||||||
|
Loading…
Reference in New Issue
Block a user