mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
feat: show the metrics summary chart (#6297)
Creates the impressions summary chart <img width="1358" alt="Screenshot 2024-02-21 at 13 25 05" src="https://github.com/Unleash/unleash/assets/104830839/ddf15637-34de-4883-9ef7-517e37eab331"> Closes # [1-2060](https://linear.app/unleash/issue/1-2060/impressions-summary-widget-frontend) --------- Signed-off-by: andreas-unleash <andreas@getunleash.ai> Co-authored-by: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com>
This commit is contained in:
parent
153c60d335
commit
bae195add9
@ -18,6 +18,11 @@ import { ProjectHealthChart } from './ProjectHealthChart/ProjectHealthChart';
|
||||
import { TimeToProductionChart } from './TimeToProductionChart/TimeToProductionChart';
|
||||
import { TimeToProduction } from './TimeToProduction/TimeToProduction';
|
||||
import { ProjectSelect, allOption } from './ProjectSelect/ProjectSelect';
|
||||
import { MetricsSummaryChart } from './MetricsSummaryChart/MetricsSummaryChart';
|
||||
import {
|
||||
ExecutiveSummarySchemaMetricsSummaryTrendsItem,
|
||||
ExecutiveSummarySchemaProjectFlagTrendsItem,
|
||||
} from '../../openapi';
|
||||
import { HealthStats } from './HealthStats/HealthStats';
|
||||
|
||||
const StyledGrid = styled(Box)(({ theme }) => ({
|
||||
@ -61,6 +66,11 @@ const useDashboardGrid = () => {
|
||||
};
|
||||
};
|
||||
|
||||
interface FilteredProjectData {
|
||||
filteredProjectFlagTrends: ExecutiveSummarySchemaProjectFlagTrendsItem[];
|
||||
filteredMetricsSummaryTrends: ExecutiveSummarySchemaMetricsSummaryTrendsItem[];
|
||||
}
|
||||
|
||||
export const ExecutiveDashboard: VFC = () => {
|
||||
const { executiveDashboardData, loading, error } = useExecutiveDashboard();
|
||||
const [projects, setProjects] = useState([allOption.id]);
|
||||
@ -78,14 +88,31 @@ export const ExecutiveDashboard: VFC = () => {
|
||||
).toFixed(1);
|
||||
}, [executiveDashboardData]);
|
||||
|
||||
const filteredProjectFlagTrends = useMemo(() => {
|
||||
const { filteredProjectFlagTrends, filteredMetricsSummaryTrends } =
|
||||
useMemo<FilteredProjectData>(() => {
|
||||
if (projects[0] === allOption.id) {
|
||||
return executiveDashboardData.projectFlagTrends;
|
||||
return {
|
||||
filteredProjectFlagTrends:
|
||||
executiveDashboardData.projectFlagTrends,
|
||||
filteredMetricsSummaryTrends:
|
||||
executiveDashboardData.metricsSummaryTrends,
|
||||
};
|
||||
}
|
||||
|
||||
return executiveDashboardData.projectFlagTrends.filter((trend) =>
|
||||
const filteredProjectFlagTrends =
|
||||
executiveDashboardData.projectFlagTrends.filter((trend) =>
|
||||
projects.includes(trend.project),
|
||||
);
|
||||
) as ExecutiveSummarySchemaProjectFlagTrendsItem[];
|
||||
|
||||
const filteredImpressionsSummary =
|
||||
executiveDashboardData.metricsSummaryTrends.filter((summary) =>
|
||||
projects.includes(summary.project),
|
||||
) as ExecutiveSummarySchemaMetricsSummaryTrendsItem[];
|
||||
|
||||
return {
|
||||
filteredProjectFlagTrends,
|
||||
filteredMetricsSummaryTrends: filteredImpressionsSummary,
|
||||
};
|
||||
}, [executiveDashboardData, projects]);
|
||||
|
||||
const {
|
||||
@ -159,13 +186,23 @@ export const ExecutiveDashboard: VFC = () => {
|
||||
projectFlagTrends={filteredProjectFlagTrends}
|
||||
/>
|
||||
</Widget>
|
||||
<Widget title='Average time to production' order={8}>
|
||||
<Widget
|
||||
title='Metrics over time per project'
|
||||
order={8}
|
||||
span={largeChartSpan}
|
||||
>
|
||||
<MetricsSummaryChart
|
||||
metricsSummaryTrends={filteredMetricsSummaryTrends}
|
||||
/>
|
||||
</Widget>
|
||||
|
||||
<Widget title='Average time to production' order={9}>
|
||||
<TimeToProduction
|
||||
//FIXME: data from API
|
||||
daysToProduction={12}
|
||||
/>
|
||||
</Widget>
|
||||
<Widget title='Time to production' order={9} span={chartSpan}>
|
||||
<Widget title='Time to production' order={10} span={chartSpan}>
|
||||
<TimeToProductionChart
|
||||
projectFlagTrends={filteredProjectFlagTrends}
|
||||
/>
|
||||
|
@ -0,0 +1,17 @@
|
||||
import { type VFC } from 'react';
|
||||
import 'chartjs-adapter-date-fns';
|
||||
import { ExecutiveSummarySchema } from 'openapi';
|
||||
import { LineChart } from '../LineChart/LineChart';
|
||||
import { useMetricsSummary } from '../useMetricsSummary';
|
||||
|
||||
interface IMetricsSummaryChartProps {
|
||||
metricsSummaryTrends: ExecutiveSummarySchema['metricsSummaryTrends'];
|
||||
}
|
||||
|
||||
export const MetricsSummaryChart: VFC<IMetricsSummaryChartProps> = ({
|
||||
metricsSummaryTrends,
|
||||
}) => {
|
||||
const data = useMetricsSummary(metricsSummaryTrends, 'total');
|
||||
|
||||
return <LineChart data={data} />;
|
||||
};
|
@ -0,0 +1,58 @@
|
||||
import { useMemo } from 'react';
|
||||
import { getProjectColor } from './executive-dashboard-utils';
|
||||
import { useTheme } from '@mui/material';
|
||||
import {
|
||||
ExecutiveSummarySchema,
|
||||
ExecutiveSummarySchemaMetricsSummaryTrendsItem,
|
||||
} from '../../openapi';
|
||||
|
||||
type MetricsSummaryTrends = ExecutiveSummarySchema['metricsSummaryTrends'];
|
||||
|
||||
export const useMetricsSummary = (
|
||||
metricsSummaryTrends: MetricsSummaryTrends,
|
||||
field: 'total' | 'totalYes' | 'totalNo' | 'totalApps',
|
||||
) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const data = useMemo(() => {
|
||||
const groupedFlagTrends = metricsSummaryTrends.reduce<
|
||||
Record<string, ExecutiveSummarySchemaMetricsSummaryTrendsItem[]>
|
||||
>((groups, item) => {
|
||||
if (!groups[item.project]) {
|
||||
groups[item.project] = [];
|
||||
}
|
||||
groups[item.project].push(item);
|
||||
return groups;
|
||||
}, {});
|
||||
|
||||
const datasets = Object.entries(groupedFlagTrends).map(
|
||||
([project, metricsSummaryTrends]) => {
|
||||
const color = getProjectColor(project);
|
||||
return {
|
||||
label: project,
|
||||
data: metricsSummaryTrends.map((item) => {
|
||||
if (field !== 'total') {
|
||||
return item[field] || 0;
|
||||
}
|
||||
return item.totalYes + item.totalNo || 0;
|
||||
}),
|
||||
borderColor: color,
|
||||
backgroundColor: color,
|
||||
fill: false,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
const objectKeys = Object.keys(groupedFlagTrends);
|
||||
|
||||
const firstElementSummary = groupedFlagTrends[objectKeys[0]] || [];
|
||||
const firstElementsDates = firstElementSummary.map((item) => item.date);
|
||||
|
||||
return {
|
||||
labels: firstElementsDates,
|
||||
datasets,
|
||||
};
|
||||
}, [theme, metricsSummaryTrends]);
|
||||
|
||||
return data;
|
||||
};
|
@ -33,7 +33,7 @@ export const useExecutiveDashboard = (
|
||||
userTrends: [],
|
||||
flagTrends: [],
|
||||
projectFlagTrends: [],
|
||||
impressionsSummary: [],
|
||||
metricsSummaryTrends: [],
|
||||
},
|
||||
refetchExecutiveDashboard,
|
||||
loading: !error && !data,
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
import type { ExecutiveSummarySchemaFlags } from './executiveSummarySchemaFlags';
|
||||
import type { ExecutiveSummarySchemaFlagTrendsItem } from './executiveSummarySchemaFlagTrendsItem';
|
||||
import type { ExecutiveSummarySchemaImpressionsSummaryItem } from './executiveSummarySchemaImpressionsSummaryItem';
|
||||
import type { ExecutiveSummarySchemaMetricsSummaryTrendsItem } from './executiveSummarySchemaMetricsSummaryTrendsItem';
|
||||
import type { ExecutiveSummarySchemaProjectFlagTrendsItem } from './executiveSummarySchemaProjectFlagTrendsItem';
|
||||
import type { ExecutiveSummarySchemaUsers } from './executiveSummarySchemaUsers';
|
||||
import type { ExecutiveSummarySchemaUserTrendsItem } from './executiveSummarySchemaUserTrendsItem';
|
||||
@ -18,8 +18,8 @@ export interface ExecutiveSummarySchema {
|
||||
flags: ExecutiveSummarySchemaFlags;
|
||||
/** How number of flags changed over time */
|
||||
flagTrends: ExecutiveSummarySchemaFlagTrendsItem[];
|
||||
/** How impression data per project changed over time */
|
||||
impressionsSummary: ExecutiveSummarySchemaImpressionsSummaryItem[];
|
||||
/** How metrics data per project changed over time */
|
||||
metricsSummaryTrends: ExecutiveSummarySchemaMetricsSummaryTrendsItem[];
|
||||
/** How number of flags per project changed over time */
|
||||
projectFlagTrends: ExecutiveSummarySchemaProjectFlagTrendsItem[];
|
||||
/** High level user count statistics */
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See `gen:api` script in package.json
|
||||
*/
|
||||
|
||||
export type ExecutiveSummarySchemaImpressionsSummaryItem = {
|
||||
export type ExecutiveSummarySchemaMetricsSummaryTrendsItem = {
|
||||
/** Date the impressions summary were calculated */
|
||||
date: string;
|
||||
/** Project id of the project the impressions summary belong to */
|
@ -512,7 +512,7 @@ export * from './eventsSchemaVersion';
|
||||
export * from './executiveSummarySchema';
|
||||
export * from './executiveSummarySchemaFlagTrendsItem';
|
||||
export * from './executiveSummarySchemaFlags';
|
||||
export * from './executiveSummarySchemaImpressionsSummaryItem';
|
||||
export * from './executiveSummarySchemaMetricsSummaryTrendsItem';
|
||||
export * from './executiveSummarySchemaProjectFlagTrendsItem';
|
||||
export * from './executiveSummarySchemaUserTrendsItem';
|
||||
export * from './executiveSummarySchemaUsers';
|
||||
|
Loading…
Reference in New Issue
Block a user