diff --git a/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx b/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx
index 1098adad9004..77010e448e14 100644
--- a/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx
+++ b/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx
@@ -15,6 +15,7 @@ import { FlagStats } from './FlagStats/FlagStats';
import { Widget } from './Widget/Widget';
import { FlagsProjectChart } from './FlagsProjectChart/FlagsProjectChart';
import { ProjectHealthChart } from './ProjectHealthChart/ProjectHealthChart';
+import { TimeToProductionChart } from './TimeToProductionChart/TimeToProductionChart';
const StyledGrid = styled(Box)(({ theme }) => ({
display: 'grid',
@@ -138,6 +139,17 @@ export const ExecutiveDashboard: VFC = () => {
}
/>
+
+
+
>
);
diff --git a/frontend/src/component/executiveDashboard/FlagsProjectChart/FlagsProjectChart.tsx b/frontend/src/component/executiveDashboard/FlagsProjectChart/FlagsProjectChart.tsx
index 176ea1086f0b..c7a3977d9b02 100644
--- a/frontend/src/component/executiveDashboard/FlagsProjectChart/FlagsProjectChart.tsx
+++ b/frontend/src/component/executiveDashboard/FlagsProjectChart/FlagsProjectChart.tsx
@@ -7,6 +7,7 @@ import {
} from 'openapi';
import { LineChart } from '../LineChart/LineChart';
import { getRandomColor } from '../executive-dashboard-utils';
+import { useProjectChartData } from '../useProjectChartData';
interface IFlagsProjectChartProps {
projectFlagTrends: ExecutiveSummarySchema['projectFlagTrends'];
@@ -15,38 +16,7 @@ interface IFlagsProjectChartProps {
export const FlagsProjectChart: VFC = ({
projectFlagTrends,
}) => {
- const theme = useTheme();
- const data = useMemo(() => {
- const groupedFlagTrends = projectFlagTrends.reduce<
- Record
- >((groups, item) => {
- if (!groups[item.project]) {
- groups[item.project] = [];
- }
- groups[item.project].push(item);
- return groups;
- }, {});
-
- const datasets = Object.entries(groupedFlagTrends).map(
- ([project, trends]) => {
- const color = getRandomColor();
- return {
- label: project,
- data: trends.map((item) => item.total),
- borderColor: color,
- backgroundColor: color,
- fill: true,
- };
- },
- );
-
- const objectKeys = Object.keys(groupedFlagTrends);
-
- return {
- labels: groupedFlagTrends[objectKeys[0]].map((item) => item.date),
- datasets,
- };
- }, [theme, projectFlagTrends]);
+ const data = useProjectChartData(projectFlagTrends, 'total');
return ;
};
diff --git a/frontend/src/component/executiveDashboard/ProjectHealthChart/ProjectHealthChart.tsx b/frontend/src/component/executiveDashboard/ProjectHealthChart/ProjectHealthChart.tsx
index da5b0e0e6b6f..08acf7f21002 100644
--- a/frontend/src/component/executiveDashboard/ProjectHealthChart/ProjectHealthChart.tsx
+++ b/frontend/src/component/executiveDashboard/ProjectHealthChart/ProjectHealthChart.tsx
@@ -7,6 +7,7 @@ import {
} from 'openapi';
import { LineChart } from '../LineChart/LineChart';
import { getRandomColor } from '../executive-dashboard-utils';
+import { useProjectChartData } from '../useProjectChartData';
interface IFlagsProjectChartProps {
projectFlagTrends: ExecutiveSummarySchema['projectFlagTrends'];
@@ -15,39 +16,7 @@ interface IFlagsProjectChartProps {
export const ProjectHealthChart: VFC = ({
projectFlagTrends,
}) => {
- const theme = useTheme();
-
- const data = useMemo(() => {
- const groupedFlagTrends = projectFlagTrends.reduce<
- Record
- >((groups, item) => {
- if (!groups[item.project]) {
- groups[item.project] = [];
- }
- groups[item.project].push(item);
- return groups;
- }, {});
-
- const datasets = Object.entries(groupedFlagTrends).map(
- ([project, trends]) => {
- const color = getRandomColor();
- return {
- label: project,
- data: trends.map((item) => item.health || 0),
- borderColor: color,
- backgroundColor: color,
- fill: true,
- };
- },
- );
-
- const objectKeys = Object.keys(groupedFlagTrends);
-
- return {
- labels: groupedFlagTrends[objectKeys[0]].map((item) => item.date),
- datasets,
- };
- }, [theme, projectFlagTrends]);
+ const data = useProjectChartData(projectFlagTrends, 'health');
return ;
};
diff --git a/frontend/src/component/executiveDashboard/TimeToProductionChart/TimeToProductionChart.tsx b/frontend/src/component/executiveDashboard/TimeToProductionChart/TimeToProductionChart.tsx
new file mode 100644
index 000000000000..f1f33be090cd
--- /dev/null
+++ b/frontend/src/component/executiveDashboard/TimeToProductionChart/TimeToProductionChart.tsx
@@ -0,0 +1,22 @@
+import { useMemo, type VFC } from 'react';
+import 'chartjs-adapter-date-fns';
+import { useTheme } from '@mui/material';
+import {
+ ExecutiveSummarySchema,
+ ExecutiveSummarySchemaProjectFlagTrendsItem,
+} from 'openapi';
+import { LineChart } from '../LineChart/LineChart';
+import { getRandomColor } from '../executive-dashboard-utils';
+import { useProjectChartData } from '../useProjectChartData';
+
+interface IFlagsProjectChartProps {
+ projectFlagTrends: ExecutiveSummarySchema['projectFlagTrends'];
+}
+
+export const TimeToProductionChart: VFC = ({
+ projectFlagTrends,
+}) => {
+ const data = useProjectChartData(projectFlagTrends, 'timeToProduction');
+
+ return ;
+};
diff --git a/frontend/src/component/executiveDashboard/useProjectChartData.ts b/frontend/src/component/executiveDashboard/useProjectChartData.ts
new file mode 100644
index 000000000000..15633c58b4f1
--- /dev/null
+++ b/frontend/src/component/executiveDashboard/useProjectChartData.ts
@@ -0,0 +1,55 @@
+import { useMemo } from 'react';
+import {
+ ExecutiveSummarySchema,
+ ExecutiveSummarySchemaProjectFlagTrendsItem,
+} from '../../openapi';
+import { getRandomColor } from './executive-dashboard-utils';
+import { useTheme } from '@mui/material';
+
+type ProjectFlagTrends = ExecutiveSummarySchema['projectFlagTrends'];
+
+export const useProjectChartData = (
+ projectFlagTrends: ProjectFlagTrends,
+ field: 'timeToProduction' | 'total' | 'health',
+) => {
+ const theme = useTheme();
+
+ const data = useMemo(() => {
+ const groupedFlagTrends = projectFlagTrends.reduce<
+ Record
+ >((groups, item) => {
+ if (!groups[item.project]) {
+ groups[item.project] = [];
+ }
+ groups[item.project].push(item);
+ return groups;
+ }, {});
+
+ const datasets = Object.entries(groupedFlagTrends).map(
+ ([project, trends]) => {
+ const color = getRandomColor();
+ return {
+ label: project,
+ data: trends.map((item) => {
+ return item[field] || 0;
+ }),
+ borderColor: color,
+ backgroundColor: color,
+ fill: true,
+ };
+ },
+ );
+
+ const objectKeys = Object.keys(groupedFlagTrends);
+
+ const firstElementTrends = groupedFlagTrends[objectKeys[0]] || [];
+ const firstElementsDates = firstElementTrends.map((item) => item.date);
+
+ return {
+ labels: firstElementsDates,
+ datasets,
+ };
+ }, [theme, projectFlagTrends]);
+
+ return data;
+};