From 4fc0a806f1a84bac5ee3d734f1fcdb9b52029dbe Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Mon, 4 Mar 2024 12:56:17 +0100 Subject: [PATCH] Insights dashboard refactor (#6404) - reorganized dashboard components - added share link - health chart aggregated data - refactored chart placeholders --- .../common/ProjectSelect/ProjectSelect.tsx | 4 +- .../executiveDashboard/ExecutiveDashboard.tsx | 353 ++++++++---------- .../FlagsProjectChart/FlagsProjectChart.tsx | 27 -- .../ProjectHealthChart/ProjectHealthChart.tsx | 27 -- .../DashboardHeader/DashboardHeader.tsx | 33 +- .../DashboardHeader/ShareLink/ShareLink.tsx | 41 ++ .../{ => components}/Gauge/Gauge.tsx | 0 .../HorizontalDistributionChart.tsx | 0 .../LineChart/ChartTooltip/ChartTooltip.tsx | 0 .../{ => components}/LineChart/LineChart.tsx | 0 .../LineChart/LineChartComponent.tsx | 6 +- .../LineChart/createChartOptions.ts | 5 +- .../LineChart/createTooltip.ts | 0 .../LineChart/legendOptions.ts | 3 +- .../{ => components}/Widget/Widget.tsx | 12 +- .../FlagsChart/FlagsChart.tsx | 30 +- .../FlagsProjectChart/FlagsProjectChart.tsx | 38 ++ .../MetricsChartTooltip.tsx | 2 +- .../MetricsSummaryChart.tsx | 5 +- .../HealthChartTooltip/HealthChartTooltip.tsx | 4 +- .../ProjectHealthChart/ProjectHealthChart.tsx | 103 +++++ .../TimeToProductionChart.tsx | 5 +- .../UsersChart/UsersChart.tsx | 26 +- .../UsersPerProjectChart.tsx | 38 ++ .../FlagStats/FlagStats.tsx | 59 ++- .../HealthStats/HealthStats.tsx | 2 +- .../TimeToProduction/TimeToProduction.tsx | 2 +- .../UserStats/UserDistributionInfo.tsx | 0 .../UserStats/UserStats.tsx | 8 +- .../hooks/useFilteredFlagsSummary.test.ts | 34 +- .../hooks/useFilteredFlagsSummary.ts | 10 +- .../{ => hooks}/useMetricsSummary.ts | 2 +- .../hooks/usePlaceholderData.ts | 64 ++++ .../{ => hooks}/useProjectChartData.ts | 4 +- .../applicationOverviewIssuesSchemaType.ts | 17 - frontend/src/openapi/models/index.ts | 1 + 36 files changed, 564 insertions(+), 401 deletions(-) delete mode 100644 frontend/src/component/executiveDashboard/FlagsProjectChart/FlagsProjectChart.tsx delete mode 100644 frontend/src/component/executiveDashboard/ProjectHealthChart/ProjectHealthChart.tsx rename frontend/src/component/executiveDashboard/{ => components}/DashboardHeader/DashboardHeader.tsx (61%) create mode 100644 frontend/src/component/executiveDashboard/components/DashboardHeader/ShareLink/ShareLink.tsx rename frontend/src/component/executiveDashboard/{ => components}/Gauge/Gauge.tsx (100%) rename frontend/src/component/executiveDashboard/{ => components}/HorizontalDistributionChart/HorizontalDistributionChart.tsx (100%) rename frontend/src/component/executiveDashboard/{ => components}/LineChart/ChartTooltip/ChartTooltip.tsx (100%) rename frontend/src/component/executiveDashboard/{ => components}/LineChart/LineChart.tsx (100%) rename frontend/src/component/executiveDashboard/{ => components}/LineChart/LineChartComponent.tsx (96%) rename frontend/src/component/executiveDashboard/{ => components}/LineChart/createChartOptions.ts (94%) rename frontend/src/component/executiveDashboard/{ => components}/LineChart/createTooltip.ts (100%) rename frontend/src/component/executiveDashboard/{ => components}/LineChart/legendOptions.ts (95%) rename frontend/src/component/executiveDashboard/{ => components}/Widget/Widget.tsx (83%) rename frontend/src/component/executiveDashboard/{ => componentsChart}/FlagsChart/FlagsChart.tsx (57%) create mode 100644 frontend/src/component/executiveDashboard/componentsChart/FlagsProjectChart/FlagsProjectChart.tsx rename frontend/src/component/executiveDashboard/{ => componentsChart}/MetricsSummaryChart/MetricsChartTooltip/MetricsChartTooltip.tsx (98%) rename frontend/src/component/executiveDashboard/{ => componentsChart}/MetricsSummaryChart/MetricsSummaryChart.tsx (84%) rename frontend/src/component/executiveDashboard/{ => componentsChart}/ProjectHealthChart/HealthChartTooltip/HealthChartTooltip.tsx (96%) create mode 100644 frontend/src/component/executiveDashboard/componentsChart/ProjectHealthChart/ProjectHealthChart.tsx rename frontend/src/component/executiveDashboard/{ => componentsChart}/TimeToProductionChart/TimeToProductionChart.tsx (83%) rename frontend/src/component/executiveDashboard/{ => componentsChart}/UsersChart/UsersChart.tsx (74%) create mode 100644 frontend/src/component/executiveDashboard/componentsChart/UsersPerProjectChart/UsersPerProjectChart.tsx rename frontend/src/component/executiveDashboard/{ => componentsStat}/FlagStats/FlagStats.tsx (63%) rename frontend/src/component/executiveDashboard/{ => componentsStat}/HealthStats/HealthStats.tsx (99%) rename frontend/src/component/executiveDashboard/{ => componentsStat}/TimeToProduction/TimeToProduction.tsx (98%) rename frontend/src/component/executiveDashboard/{ => componentsStat}/UserStats/UserDistributionInfo.tsx (100%) rename frontend/src/component/executiveDashboard/{ => componentsStat}/UserStats/UserStats.tsx (92%) rename frontend/src/component/executiveDashboard/{ => hooks}/useMetricsSummary.ts (95%) create mode 100644 frontend/src/component/executiveDashboard/hooks/usePlaceholderData.ts rename frontend/src/component/executiveDashboard/{ => hooks}/useProjectChartData.ts (93%) delete mode 100644 frontend/src/openapi/models/applicationOverviewIssuesSchemaType.ts diff --git a/frontend/src/component/common/ProjectSelect/ProjectSelect.tsx b/frontend/src/component/common/ProjectSelect/ProjectSelect.tsx index d54171d0ce..1c2673168e 100644 --- a/frontend/src/component/common/ProjectSelect/ProjectSelect.tsx +++ b/frontend/src/component/common/ProjectSelect/ProjectSelect.tsx @@ -12,7 +12,9 @@ export const allOption = { label: 'ALL', id: '*' }; interface IProjectSelectProps { selectedProjects: string[]; - onChange: Dispatch>; + onChange: + | Dispatch> + | ((projects: string[]) => void); dataTestId?: string; sx?: SxProps; disabled?: boolean; diff --git a/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx b/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx index 9140820e17..06111b5dce 100644 --- a/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx +++ b/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx @@ -1,236 +1,195 @@ -import { useMemo, useState, VFC } from 'react'; +import { VFC } from 'react'; +import { Box, styled } from '@mui/material'; +import { ArrayParam, withDefault } from 'use-query-params'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import { usePersistentTableState } from 'hooks/usePersistentTableState'; import { - Box, - styled, - Typography, - useMediaQuery, - useTheme, -} from '@mui/material'; -import { UsersChart } from './UsersChart/UsersChart'; -import { FlagsChart } from './FlagsChart/FlagsChart'; -import { useExecutiveDashboard } from 'hooks/api/getters/useExecutiveSummary/useExecutiveSummary'; -import { UserStats } from './UserStats/UserStats'; -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'; -import { TimeToProduction } from './TimeToProduction/TimeToProduction'; -import { - ProjectSelect, allOption, -} from '../common/ProjectSelect/ProjectSelect'; -import { MetricsSummaryChart } from './MetricsSummaryChart/MetricsSummaryChart'; -import { - ExecutiveSummarySchemaMetricsSummaryTrendsItem, - ExecutiveSummarySchemaProjectFlagTrendsItem, -} from 'openapi'; -import { HealthStats } from './HealthStats/HealthStats'; -import { DashboardHeader } from './DashboardHeader/DashboardHeader'; + ProjectSelect, +} from 'component/common/ProjectSelect/ProjectSelect'; +import { useExecutiveDashboard } from 'hooks/api/getters/useExecutiveSummary/useExecutiveSummary'; + +import { useFilteredFlagsSummary } from './hooks/useFilteredFlagsSummary'; +import { useFilteredTrends } from './hooks/useFilteredTrends'; + +import { Widget } from './components/Widget/Widget'; +import { DashboardHeader } from './components/DashboardHeader/DashboardHeader'; + +import { UserStats } from './componentsStat/UserStats/UserStats'; +import { FlagStats } from './componentsStat/FlagStats/FlagStats'; +import { HealthStats } from './componentsStat/HealthStats/HealthStats'; +import { TimeToProduction } from './componentsStat/TimeToProduction/TimeToProduction'; + +import { UsersChart } from './componentsChart/UsersChart/UsersChart'; +import { FlagsChart } from './componentsChart/FlagsChart/FlagsChart'; +import { FlagsProjectChart } from './componentsChart/FlagsProjectChart/FlagsProjectChart'; +import { ProjectHealthChart } from './componentsChart/ProjectHealthChart/ProjectHealthChart'; +import { TimeToProductionChart } from './componentsChart/TimeToProductionChart/TimeToProductionChart'; +import { MetricsSummaryChart } from './componentsChart/MetricsSummaryChart/MetricsSummaryChart'; +import { UsersPerProjectChart } from './componentsChart/UsersPerProjectChart/UsersPerProjectChart'; const StyledGrid = styled(Box)(({ theme }) => ({ display: 'grid', - gridTemplateColumns: `300px 1fr`, + gridTemplateColumns: `repeat(2, 1fr)`, gridAutoRows: 'auto', gap: theme.spacing(2), -})); - -const StyledBox = styled(Box)(({ theme }) => ({ - marginBottom: theme.spacing(4), - marginTop: theme.spacing(4), - [theme.breakpoints.down('lg')]: { - width: '100%', - marginLeft: 0, + paddingBottom: theme.spacing(2), + [theme.breakpoints.up('md')]: { + gridTemplateColumns: `300px 1fr`, }, - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', })); -const useDashboardGrid = () => { - const theme = useTheme(); - const isMediumScreen = useMediaQuery(theme.breakpoints.down('lg')); - const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); - - if (isSmallScreen) { - return { - gridTemplateColumns: `1fr`, - chartSpan: 1, - userTrendsOrder: 3, - flagStatsOrder: 2, - largeChartSpan: 1, - }; - } - - if (isMediumScreen) { - return { - gridTemplateColumns: `1fr 1fr`, - chartSpan: 2, - userTrendsOrder: 3, - flagStatsOrder: 2, - largeChartSpan: 2, - }; - } - - return { - gridTemplateColumns: `300px auto`, - chartSpan: 1, - userTrendsOrder: 2, - flagStatsOrder: 3, - largeChartSpan: 2, - }; -}; - -interface FilteredProjectData { - filteredProjectFlagTrends: ExecutiveSummarySchemaProjectFlagTrendsItem[]; - filteredMetricsSummaryTrends: ExecutiveSummarySchemaMetricsSummaryTrendsItem[]; -} +const ChartWidget = styled(Widget)(({ theme }) => ({ + [theme.breakpoints.down('md')]: { + gridColumnStart: 'span 2', + order: 2, + }, +})); export const ExecutiveDashboard: VFC = () => { const { executiveDashboardData, loading, error } = useExecutiveDashboard(); - const [projects, setProjects] = useState([allOption.id]); + const stateConfig = { + projects: withDefault(ArrayParam, [allOption.id]), + }; + const [state, setState] = usePersistentTableState(`insights`, stateConfig); + const setProjects = (projects: string[]) => { + setState({ projects }); + }; + const projects = state.projects + ? (state.projects.filter(Boolean) as string[]) + : []; + const showAllProjects = projects[0] === allOption.id; + const projectsData = useFilteredTrends( + executiveDashboardData.projectFlagTrends, + projects, + ); + const metricsData = useFilteredTrends( + executiveDashboardData.metricsSummaryTrends, + projects, + ); + const { users } = executiveDashboardData; - const flagPerUsers = useMemo(() => { - if ( - executiveDashboardData.users.total === 0 || - executiveDashboardData.flags.total === 0 - ) - return '0'; - - return ( - executiveDashboardData.flags.total / - executiveDashboardData.users.total - ).toFixed(1); - }, [executiveDashboardData]); - - const { filteredProjectFlagTrends, filteredMetricsSummaryTrends } = - useMemo(() => { - if (projects[0] === allOption.id) { - return { - filteredProjectFlagTrends: - executiveDashboardData.projectFlagTrends, - filteredMetricsSummaryTrends: - executiveDashboardData.metricsSummaryTrends, - }; - } - - 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 { - gridTemplateColumns, - chartSpan, - userTrendsOrder, - flagStatsOrder, - largeChartSpan, - } = useDashboardGrid(); + const summary = useFilteredFlagsSummary(projectsData); + const isOneProjectSelected = projects.length === 1; return ( <> ({ paddingBottom: theme.spacing(4) })}> - + + } + /> - - - - - - - + + + + + } + elseShow={ + + + + } + /> + + + + } + elseShow={ + + + + } + /> - - - - - - - Insights per project - - + + + } + elseShow={ + + + + } /> - - - - - - + - - - - - - - - + + {/* - - - + + + */} + + + ); }; diff --git a/frontend/src/component/executiveDashboard/FlagsProjectChart/FlagsProjectChart.tsx b/frontend/src/component/executiveDashboard/FlagsProjectChart/FlagsProjectChart.tsx deleted file mode 100644 index db578052ed..0000000000 --- a/frontend/src/component/executiveDashboard/FlagsProjectChart/FlagsProjectChart.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { type VFC } from 'react'; -import 'chartjs-adapter-date-fns'; -import { ExecutiveSummarySchema } from 'openapi'; -import { LineChart } from '../LineChart/LineChart'; -import { useProjectChartData } from '../useProjectChartData'; - -interface IFlagsProjectChartProps { - projectFlagTrends: ExecutiveSummarySchema['projectFlagTrends']; -} - -export const FlagsProjectChart: VFC = ({ - projectFlagTrends, -}) => { - const data = useProjectChartData(projectFlagTrends); - return ( - - ); -}; diff --git a/frontend/src/component/executiveDashboard/ProjectHealthChart/ProjectHealthChart.tsx b/frontend/src/component/executiveDashboard/ProjectHealthChart/ProjectHealthChart.tsx deleted file mode 100644 index aa265f5234..0000000000 --- a/frontend/src/component/executiveDashboard/ProjectHealthChart/ProjectHealthChart.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import 'chartjs-adapter-date-fns'; -import { type VFC } from 'react'; -import { type ExecutiveSummarySchema } from 'openapi'; -import { HealthTooltip } from './HealthChartTooltip/HealthChartTooltip'; -import { LineChart } from '../LineChart/LineChart'; -import { useProjectChartData } from '../useProjectChartData'; - -interface IFlagsProjectChartProps { - projectFlagTrends: ExecutiveSummarySchema['projectFlagTrends']; -} - -export const ProjectHealthChart: VFC = ({ - projectFlagTrends, -}) => { - const data = useProjectChartData(projectFlagTrends); - - return ( - - ); -}; diff --git a/frontend/src/component/executiveDashboard/DashboardHeader/DashboardHeader.tsx b/frontend/src/component/executiveDashboard/components/DashboardHeader/DashboardHeader.tsx similarity index 61% rename from frontend/src/component/executiveDashboard/DashboardHeader/DashboardHeader.tsx rename to frontend/src/component/executiveDashboard/components/DashboardHeader/DashboardHeader.tsx index ed8336664b..857e9f24d2 100644 --- a/frontend/src/component/executiveDashboard/DashboardHeader/DashboardHeader.tsx +++ b/frontend/src/component/executiveDashboard/components/DashboardHeader/DashboardHeader.tsx @@ -1,11 +1,17 @@ -import { VFC } from 'react'; +import { ReactNode, VFC } from 'react'; import { useUiFlag } from 'hooks/useUiFlag'; import { useFeedback } from 'component/feedbackNew/useFeedback'; import { ReviewsOutlined } from '@mui/icons-material'; -import { Badge, Button, Typography } from '@mui/material'; +import { Button, Typography } from '@mui/material'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; +import { Badge } from 'component/common/Badge/Badge'; +import { ShareLink } from './ShareLink/ShareLink'; -export const DashboardHeader: VFC = () => { +type DashboardHeaderProps = { + actions?: ReactNode; +}; + +export const DashboardHeader: VFC = ({ actions }) => { const showInactiveUsers = useUiFlag('showInactiveUsers'); const { openFeedback } = useFeedback( @@ -34,18 +40,21 @@ export const DashboardHeader: VFC = () => { gap: theme.spacing(1), })} > - Insights Beta + Insights Beta } actions={ - + <> + {actions} + + + } /> ); diff --git a/frontend/src/component/executiveDashboard/components/DashboardHeader/ShareLink/ShareLink.tsx b/frontend/src/component/executiveDashboard/components/DashboardHeader/ShareLink/ShareLink.tsx new file mode 100644 index 0000000000..b161287cf4 --- /dev/null +++ b/frontend/src/component/executiveDashboard/components/DashboardHeader/ShareLink/ShareLink.tsx @@ -0,0 +1,41 @@ +import { VFC, useState } from 'react'; +import { Share } from '@mui/icons-material'; +import { Box, Button, Typography } from '@mui/material'; +import { Dialogue } from 'component/common/Dialogue/Dialogue'; +import { LinkField } from 'component/admin/users/LinkField/LinkField'; + +export const ShareLink: VFC = () => { + const [isOpen, setIsOpen] = useState(false); + const url = new URL(window.location.href); + url.searchParams.set('share', 'true'); + + return ( + <> + + setIsOpen(false)} + primaryButtonText='Close' + title='Share insights' + > + + + Link below will lead to insights dashboard with + currently selected filter. + + + + + + ); +}; diff --git a/frontend/src/component/executiveDashboard/Gauge/Gauge.tsx b/frontend/src/component/executiveDashboard/components/Gauge/Gauge.tsx similarity index 100% rename from frontend/src/component/executiveDashboard/Gauge/Gauge.tsx rename to frontend/src/component/executiveDashboard/components/Gauge/Gauge.tsx diff --git a/frontend/src/component/executiveDashboard/HorizontalDistributionChart/HorizontalDistributionChart.tsx b/frontend/src/component/executiveDashboard/components/HorizontalDistributionChart/HorizontalDistributionChart.tsx similarity index 100% rename from frontend/src/component/executiveDashboard/HorizontalDistributionChart/HorizontalDistributionChart.tsx rename to frontend/src/component/executiveDashboard/components/HorizontalDistributionChart/HorizontalDistributionChart.tsx diff --git a/frontend/src/component/executiveDashboard/LineChart/ChartTooltip/ChartTooltip.tsx b/frontend/src/component/executiveDashboard/components/LineChart/ChartTooltip/ChartTooltip.tsx similarity index 100% rename from frontend/src/component/executiveDashboard/LineChart/ChartTooltip/ChartTooltip.tsx rename to frontend/src/component/executiveDashboard/components/LineChart/ChartTooltip/ChartTooltip.tsx diff --git a/frontend/src/component/executiveDashboard/LineChart/LineChart.tsx b/frontend/src/component/executiveDashboard/components/LineChart/LineChart.tsx similarity index 100% rename from frontend/src/component/executiveDashboard/LineChart/LineChart.tsx rename to frontend/src/component/executiveDashboard/components/LineChart/LineChart.tsx diff --git a/frontend/src/component/executiveDashboard/LineChart/LineChartComponent.tsx b/frontend/src/component/executiveDashboard/components/LineChart/LineChartComponent.tsx similarity index 96% rename from frontend/src/component/executiveDashboard/LineChart/LineChartComponent.tsx rename to frontend/src/component/executiveDashboard/components/LineChart/LineChartComponent.tsx index 46d1c7b318..3f23d02819 100644 --- a/frontend/src/component/executiveDashboard/LineChart/LineChartComponent.tsx +++ b/frontend/src/component/executiveDashboard/components/LineChart/LineChartComponent.tsx @@ -92,7 +92,7 @@ const LineChartComponent: VFC<{ }: { tooltip: TooltipState | null }) => ReturnType; }> = ({ data, - aspectRatio, + aspectRatio = 2.5, cover, isLocalTooltip, overrideOptions, @@ -122,8 +122,8 @@ const LineChartComponent: VFC<{ options={options} data={data} plugins={[customHighlightPlugin]} - height={aspectRatio ? 100 : undefined} - width={aspectRatio ? 100 * aspectRatio : undefined} + height={100} + width={100 * aspectRatio} /> { const style = meta.controller.getStyle( usePointStyle ? 0 : undefined, ); return { text: datasets[meta.index].label, - fillStyle: style.backgroundColor, + fillStyle: style.borderColor, fontColor: color, hidden: !meta.visible, lineWidth: 0, diff --git a/frontend/src/component/executiveDashboard/Widget/Widget.tsx b/frontend/src/component/executiveDashboard/components/Widget/Widget.tsx similarity index 83% rename from frontend/src/component/executiveDashboard/Widget/Widget.tsx rename to frontend/src/component/executiveDashboard/components/Widget/Widget.tsx index d39c8a9c54..ca2c4b599c 100644 --- a/frontend/src/component/executiveDashboard/Widget/Widget.tsx +++ b/frontend/src/component/executiveDashboard/components/Widget/Widget.tsx @@ -12,17 +12,9 @@ const StyledPaper = styled(Paper)(({ theme }) => ({ export const Widget: FC<{ title: ReactNode; - order?: number; - span?: number; tooltip?: ReactNode; -}> = ({ title, order, children, span = 1, tooltip }) => ( - +}> = ({ title, children, tooltip, ...rest }) => ( + ({ diff --git a/frontend/src/component/executiveDashboard/FlagsChart/FlagsChart.tsx b/frontend/src/component/executiveDashboard/componentsChart/FlagsChart/FlagsChart.tsx similarity index 57% rename from frontend/src/component/executiveDashboard/FlagsChart/FlagsChart.tsx rename to frontend/src/component/executiveDashboard/componentsChart/FlagsChart/FlagsChart.tsx index 900e4318a2..254ce2ee4e 100644 --- a/frontend/src/component/executiveDashboard/FlagsChart/FlagsChart.tsx +++ b/frontend/src/component/executiveDashboard/componentsChart/FlagsChart/FlagsChart.tsx @@ -2,7 +2,8 @@ import { useMemo, type VFC } from 'react'; import 'chartjs-adapter-date-fns'; import { useTheme } from '@mui/material'; import { ExecutiveSummarySchema } from 'openapi'; -import { LineChart, NotEnoughData } from '../LineChart/LineChart'; +import { LineChart, NotEnoughData } from '../../components/LineChart/LineChart'; +import { usePlaceholderData } from 'component/executiveDashboard/hooks/usePlaceholderData'; interface IFlagsChartProps { flagTrends: ExecutiveSummarySchema['flagTrends']; @@ -15,32 +16,7 @@ export const FlagsChart: VFC = ({ }) => { const theme = useTheme(); const notEnoughData = flagTrends.length < 2; - const placeholderData = useMemo( - () => ({ - labels: Array.from({ length: 15 }, (_, i) => i + 1).map( - (i) => - new Date(Date.now() - (15 - i) * 7 * 24 * 60 * 60 * 1000), - ), - datasets: [ - { - label: 'Total flags', - data: [ - 43, 66, 55, 65, 62, 72, 75, 73, 80, 65, 62, 61, 69, 70, - 77, - ], - borderColor: theme.palette.primary.light, - backgroundColor: theme.palette.primary.light, - }, - { - label: 'Stale', - data: [3, 5, 4, 6, 2, 7, 5, 3, 8, 3, 5, 11, 8, 4, 3], - borderColor: theme.palette.warning.border, - backgroundColor: theme.palette.warning.border, - }, - ], - }), - [theme], - ); + const placeholderData = usePlaceholderData({ fill: true, type: 'double' }); const data = useMemo( () => ({ diff --git a/frontend/src/component/executiveDashboard/componentsChart/FlagsProjectChart/FlagsProjectChart.tsx b/frontend/src/component/executiveDashboard/componentsChart/FlagsProjectChart/FlagsProjectChart.tsx new file mode 100644 index 0000000000..f54a4bdab1 --- /dev/null +++ b/frontend/src/component/executiveDashboard/componentsChart/FlagsProjectChart/FlagsProjectChart.tsx @@ -0,0 +1,38 @@ +import { useMemo, type VFC } from 'react'; +import 'chartjs-adapter-date-fns'; +import { ExecutiveSummarySchema } from 'openapi'; +import { LineChart, NotEnoughData } from '../../components/LineChart/LineChart'; +import { useProjectChartData } from 'component/executiveDashboard/hooks/useProjectChartData'; +import { usePlaceholderData } from 'component/executiveDashboard/hooks/usePlaceholderData'; + +interface IFlagsProjectChartProps { + projectFlagTrends: ExecutiveSummarySchema['projectFlagTrends']; +} + +export const FlagsProjectChart: VFC = ({ + projectFlagTrends, +}) => { + const placeholderData = usePlaceholderData({ + type: 'constant', + }); + + const data = useProjectChartData(projectFlagTrends); + const notEnoughData = useMemo( + () => (data.datasets.some((d) => d.data.length > 1) ? false : true), + [data], + ); + + return ( + : false} + /> + ); +}; diff --git a/frontend/src/component/executiveDashboard/MetricsSummaryChart/MetricsChartTooltip/MetricsChartTooltip.tsx b/frontend/src/component/executiveDashboard/componentsChart/MetricsSummaryChart/MetricsChartTooltip/MetricsChartTooltip.tsx similarity index 98% rename from frontend/src/component/executiveDashboard/MetricsSummaryChart/MetricsChartTooltip/MetricsChartTooltip.tsx rename to frontend/src/component/executiveDashboard/componentsChart/MetricsSummaryChart/MetricsChartTooltip/MetricsChartTooltip.tsx index 862c745e45..eeaf108500 100644 --- a/frontend/src/component/executiveDashboard/MetricsSummaryChart/MetricsChartTooltip/MetricsChartTooltip.tsx +++ b/frontend/src/component/executiveDashboard/componentsChart/MetricsSummaryChart/MetricsChartTooltip/MetricsChartTooltip.tsx @@ -1,7 +1,7 @@ import { type VFC } from 'react'; import { ExecutiveSummarySchemaMetricsSummaryTrendsItem } from 'openapi'; import { Box, Divider, Paper, styled, Typography } from '@mui/material'; -import { TooltipState } from '../../LineChart/ChartTooltip/ChartTooltip'; +import { TooltipState } from '../../../components/LineChart/ChartTooltip/ChartTooltip'; const StyledTooltipItemContainer = styled(Paper)(({ theme }) => ({ padding: theme.spacing(2), diff --git a/frontend/src/component/executiveDashboard/MetricsSummaryChart/MetricsSummaryChart.tsx b/frontend/src/component/executiveDashboard/componentsChart/MetricsSummaryChart/MetricsSummaryChart.tsx similarity index 84% rename from frontend/src/component/executiveDashboard/MetricsSummaryChart/MetricsSummaryChart.tsx rename to frontend/src/component/executiveDashboard/componentsChart/MetricsSummaryChart/MetricsSummaryChart.tsx index 4d72ce2ab4..60a57cb0b5 100644 --- a/frontend/src/component/executiveDashboard/MetricsSummaryChart/MetricsSummaryChart.tsx +++ b/frontend/src/component/executiveDashboard/componentsChart/MetricsSummaryChart/MetricsSummaryChart.tsx @@ -1,9 +1,9 @@ import { type VFC } from 'react'; import 'chartjs-adapter-date-fns'; import { ExecutiveSummarySchema } from 'openapi'; -import { LineChart } from '../LineChart/LineChart'; -import { useMetricsSummary } from '../useMetricsSummary'; +import { LineChart } from '../../components/LineChart/LineChart'; import { MetricsSummaryTooltip } from './MetricsChartTooltip/MetricsChartTooltip'; +import { useMetricsSummary } from '../../hooks/useMetricsSummary'; interface IMetricsSummaryChartProps { metricsSummaryTrends: ExecutiveSummarySchema['metricsSummaryTrends']; @@ -13,6 +13,7 @@ export const MetricsSummaryChart: VFC = ({ metricsSummaryTrends, }) => { const data = useMetricsSummary(metricsSummaryTrends); + return ( ({ diff --git a/frontend/src/component/executiveDashboard/componentsChart/ProjectHealthChart/ProjectHealthChart.tsx b/frontend/src/component/executiveDashboard/componentsChart/ProjectHealthChart/ProjectHealthChart.tsx new file mode 100644 index 0000000000..52943a07c7 --- /dev/null +++ b/frontend/src/component/executiveDashboard/componentsChart/ProjectHealthChart/ProjectHealthChart.tsx @@ -0,0 +1,103 @@ +import 'chartjs-adapter-date-fns'; +import { useMemo, type VFC } from 'react'; +import { type ExecutiveSummarySchema } from 'openapi'; +import { HealthTooltip } from './HealthChartTooltip/HealthChartTooltip'; +import { useProjectChartData } from 'component/executiveDashboard/hooks/useProjectChartData'; +import { + LineChart, + NotEnoughData, +} from 'component/executiveDashboard/components/LineChart/LineChart'; +import { useTheme } from '@mui/material'; + +interface IFlagsProjectChartProps { + projectFlagTrends: ExecutiveSummarySchema['projectFlagTrends']; + isAggregate?: boolean; +} + +export const ProjectHealthChart: VFC = ({ + projectFlagTrends, + isAggregate, +}) => { + const projectsData = useProjectChartData(projectFlagTrends); + const theme = useTheme(); + + const aggregateHealthData = useMemo(() => { + const labels = Array.from( + new Set( + projectsData.datasets.flatMap((d) => + d.data.map((item) => item.week), + ), + ), + ); + + const weeks = labels + .map((label) => { + return projectsData.datasets + .map((d) => d.data.find((item) => item.week === label)) + .reduce( + (acc, item) => { + if (item) { + acc.total += item.total; + acc.stale += item.stale + item.potentiallyStale; + } + if (!acc.date) { + acc.date = item?.date; + } + return acc; + }, + { + total: 0, + stale: 0, + week: label, + } as { + total: number; + stale: number; + week: string; + date?: string; + }, + ); + }) + .sort((a, b) => (a.week > b.week ? 1 : -1)); + + return { + datasets: [ + { + label: 'Health', + data: weeks.map((item) => ({ + health: item.total + ? ((item.total - item.stale) / item.total) * 100 + : undefined, + date: item.date, + })), + borderColor: theme.palette.primary.light, + fill: false, + order: 3, + }, + ], + }; + }, [projectsData, theme]); + + const data = isAggregate ? aggregateHealthData : projectsData; + const notEnoughData = useMemo( + () => + projectsData.datasets.some((d) => d.data.length > 1) ? false : true, + [projectsData], + ); + + return ( + : false} + /> + ); +}; diff --git a/frontend/src/component/executiveDashboard/TimeToProductionChart/TimeToProductionChart.tsx b/frontend/src/component/executiveDashboard/componentsChart/TimeToProductionChart/TimeToProductionChart.tsx similarity index 83% rename from frontend/src/component/executiveDashboard/TimeToProductionChart/TimeToProductionChart.tsx rename to frontend/src/component/executiveDashboard/componentsChart/TimeToProductionChart/TimeToProductionChart.tsx index a8140e921d..69ff748170 100644 --- a/frontend/src/component/executiveDashboard/TimeToProductionChart/TimeToProductionChart.tsx +++ b/frontend/src/component/executiveDashboard/componentsChart/TimeToProductionChart/TimeToProductionChart.tsx @@ -1,8 +1,8 @@ import { type VFC } from 'react'; import 'chartjs-adapter-date-fns'; import { ExecutiveSummarySchema } from 'openapi'; -import { LineChart } from '../LineChart/LineChart'; -import { useProjectChartData } from '../useProjectChartData'; +import { LineChart } from '../../components/LineChart/LineChart'; +import { useProjectChartData } from '../../hooks/useProjectChartData'; interface IFlagsProjectChartProps { projectFlagTrends: ExecutiveSummarySchema['projectFlagTrends']; @@ -12,7 +12,6 @@ export const TimeToProductionChart: VFC = ({ projectFlagTrends, }) => { const data = useProjectChartData(projectFlagTrends); - return ( = ({ const showInactiveUsers = useUiFlag('showInactiveUsers'); const theme = useTheme(); const notEnoughData = userTrends.length < 2; - const placeholderData = useMemo( - () => ({ - labels: Array.from({ length: 15 }, (_, i) => i + 1).map( - (i) => - new Date(Date.now() - (15 - i) * 7 * 24 * 60 * 60 * 1000), - ), - datasets: [ - { - label: 'Total users', - data: [ - 3, 5, 15, 17, 25, 40, 47, 48, 55, 65, 62, 72, 75, 73, - 80, - ], - borderColor: theme.palette.primary.light, - backgroundColor: fillGradientPrimary, - fill: true, - order: 3, - }, - ], - }), - [theme], - ); + const placeholderData = usePlaceholderData({ fill: true, type: 'rising' }); const data = useMemo( () => ({ labels: userTrends.map((item) => item.date), diff --git a/frontend/src/component/executiveDashboard/componentsChart/UsersPerProjectChart/UsersPerProjectChart.tsx b/frontend/src/component/executiveDashboard/componentsChart/UsersPerProjectChart/UsersPerProjectChart.tsx new file mode 100644 index 0000000000..ab6b46d2ba --- /dev/null +++ b/frontend/src/component/executiveDashboard/componentsChart/UsersPerProjectChart/UsersPerProjectChart.tsx @@ -0,0 +1,38 @@ +import { useMemo, type VFC } from 'react'; +import 'chartjs-adapter-date-fns'; +import { ExecutiveSummarySchema } from 'openapi'; +import { LineChart, NotEnoughData } from '../../components/LineChart/LineChart'; +import { useProjectChartData } from 'component/executiveDashboard/hooks/useProjectChartData'; +import { usePlaceholderData } from 'component/executiveDashboard/hooks/usePlaceholderData'; + +interface IUsersPerProjectChartProps { + projectFlagTrends: ExecutiveSummarySchema['projectFlagTrends']; +} + +export const UsersPerProjectChart: VFC = ({ + projectFlagTrends, +}) => { + const placeholderData = usePlaceholderData({ + type: 'constant', + }); + + const data = useProjectChartData(projectFlagTrends); + const notEnoughData = useMemo( + () => (data.datasets.some((d) => d.data.length > 1) ? false : true), + [data], + ); + + return ( + : false} + /> + ); +}; diff --git a/frontend/src/component/executiveDashboard/FlagStats/FlagStats.tsx b/frontend/src/component/executiveDashboard/componentsStat/FlagStats/FlagStats.tsx similarity index 63% rename from frontend/src/component/executiveDashboard/FlagStats/FlagStats.tsx rename to frontend/src/component/executiveDashboard/componentsStat/FlagStats/FlagStats.tsx index de21263c78..ca5f398823 100644 --- a/frontend/src/component/executiveDashboard/FlagStats/FlagStats.tsx +++ b/frontend/src/component/executiveDashboard/componentsStat/FlagStats/FlagStats.tsx @@ -1,20 +1,6 @@ import { Settings } from '@mui/icons-material'; import { Box, Typography, styled } from '@mui/material'; - -const StyledContent = styled(Box)(({ theme }) => ({ - borderRadius: `${theme.shape.borderRadiusLarge}px`, - backgroundColor: theme.palette.background.paper, - maxWidth: 300, - padding: theme.spacing(3), -})); - -const StyledHeader = styled(Typography)(({ theme }) => ({ - marginBottom: theme.spacing(3), - fontSize: theme.fontSizes.bodySize, - fontWeight: 'bold', - display: 'flex', - alignItems: 'center', -})); +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const StyledRingContainer = styled(Box)(({ theme }) => ({ display: 'flex', @@ -79,7 +65,7 @@ const StyledSettingsIcon = styled(Settings)(({ theme }) => ({ interface IFlagStatsProps { count: number; - flagsPerUser: string; + flagsPerUser?: string; } export const FlagStats: React.FC = ({ @@ -94,22 +80,31 @@ export const FlagStats: React.FC = ({ - - - - - - Insights - - - Flags per user - - {flagsPerUser} - + + + + + + Insights + + + + Flags per user + + + + {flagsPerUser} + + + } + /> ); }; diff --git a/frontend/src/component/executiveDashboard/HealthStats/HealthStats.tsx b/frontend/src/component/executiveDashboard/componentsStat/HealthStats/HealthStats.tsx similarity index 99% rename from frontend/src/component/executiveDashboard/HealthStats/HealthStats.tsx rename to frontend/src/component/executiveDashboard/componentsStat/HealthStats/HealthStats.tsx index 5817fcdccd..c2f7b5a672 100644 --- a/frontend/src/component/executiveDashboard/HealthStats/HealthStats.tsx +++ b/frontend/src/component/executiveDashboard/componentsStat/HealthStats/HealthStats.tsx @@ -3,7 +3,7 @@ import { useThemeMode } from 'hooks/useThemeMode'; import { useTheme } from '@mui/material'; interface IHealthStatsProps { - value: number; + value?: string | number; healthy: number; stale: number; potentiallyStale: number; diff --git a/frontend/src/component/executiveDashboard/TimeToProduction/TimeToProduction.tsx b/frontend/src/component/executiveDashboard/componentsStat/TimeToProduction/TimeToProduction.tsx similarity index 98% rename from frontend/src/component/executiveDashboard/TimeToProduction/TimeToProduction.tsx rename to frontend/src/component/executiveDashboard/componentsStat/TimeToProduction/TimeToProduction.tsx index d8a5a55b35..77172306b3 100644 --- a/frontend/src/component/executiveDashboard/TimeToProduction/TimeToProduction.tsx +++ b/frontend/src/component/executiveDashboard/componentsStat/TimeToProduction/TimeToProduction.tsx @@ -1,6 +1,6 @@ import { VFC } from 'react'; import { Typography, styled } from '@mui/material'; -import { Gauge } from '../Gauge/Gauge'; +import { Gauge } from '../../components/Gauge/Gauge'; const StyledContainer = styled('div')(({ theme }) => ({ display: 'flex', diff --git a/frontend/src/component/executiveDashboard/UserStats/UserDistributionInfo.tsx b/frontend/src/component/executiveDashboard/componentsStat/UserStats/UserDistributionInfo.tsx similarity index 100% rename from frontend/src/component/executiveDashboard/UserStats/UserDistributionInfo.tsx rename to frontend/src/component/executiveDashboard/componentsStat/UserStats/UserDistributionInfo.tsx diff --git a/frontend/src/component/executiveDashboard/UserStats/UserStats.tsx b/frontend/src/component/executiveDashboard/componentsStat/UserStats/UserStats.tsx similarity index 92% rename from frontend/src/component/executiveDashboard/UserStats/UserStats.tsx rename to frontend/src/component/executiveDashboard/componentsStat/UserStats/UserStats.tsx index 1c22ffa0c9..c716108186 100644 --- a/frontend/src/component/executiveDashboard/UserStats/UserStats.tsx +++ b/frontend/src/component/executiveDashboard/componentsStat/UserStats/UserStats.tsx @@ -4,7 +4,7 @@ import { Box, Typography, styled } from '@mui/material'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useUiFlag } from 'hooks/useUiFlag'; import { Link } from 'react-router-dom'; -import { HorizontalDistributionChart } from '../HorizontalDistributionChart/HorizontalDistributionChart'; +import { HorizontalDistributionChart } from '../../components/HorizontalDistributionChart/HorizontalDistributionChart'; import { UserDistributionInfo } from './UserDistributionInfo'; const StyledUserContainer = styled(Box)(({ theme }) => ({ @@ -81,7 +81,11 @@ export const UserStats: FC = ({ count, active, inactive }) => { <> - {count} + + {parseInt(`${count}`, 10) === count + ? count + : count.toFixed(2)} + diff --git a/frontend/src/component/executiveDashboard/hooks/useFilteredFlagsSummary.test.ts b/frontend/src/component/executiveDashboard/hooks/useFilteredFlagsSummary.test.ts index 9b9ba85ead..e65f9c0e9a 100644 --- a/frontend/src/component/executiveDashboard/hooks/useFilteredFlagsSummary.test.ts +++ b/frontend/src/component/executiveDashboard/hooks/useFilteredFlagsSummary.test.ts @@ -53,7 +53,7 @@ describe('useFilteredFlagTrends', () => { active: 11, stale: 2, potentiallyStale: 1, - averageUsers: '2.00', + averageUsers: 2, averageHealth: '79', }); }); @@ -79,7 +79,7 @@ describe('useFilteredFlagTrends', () => { active: 5, stale: 0, potentiallyStale: 0, - averageUsers: '0.00', + averageUsers: 0, averageHealth: '100', }); }); @@ -104,7 +104,7 @@ describe('useFilteredFlagTrends', () => { active: 5, stale: 0, potentiallyStale: 0, - users: 2, + users: 3, date: '', }, ]), @@ -115,8 +115,34 @@ describe('useFilteredFlagTrends', () => { active: 10, stale: 0, potentiallyStale: 0, - averageUsers: '1.00', + averageUsers: 1.5, averageHealth: '100', }); }); + + it('should set health of a project without feature toggles to undefined', () => { + const { result } = renderHook(() => + useFilteredFlagsSummary([ + { + week: '2024-01', + project: 'project1', + total: 0, + active: 0, + stale: 0, + potentiallyStale: 0, + users: 0, + date: '', + }, + ]), + ); + + expect(result.current).toEqual({ + total: 0, + active: 0, + stale: 0, + potentiallyStale: 0, + averageUsers: 0, + averageHealth: undefined, + }); + }); }); diff --git a/frontend/src/component/executiveDashboard/hooks/useFilteredFlagsSummary.ts b/frontend/src/component/executiveDashboard/hooks/useFilteredFlagsSummary.ts index 10676ac9d4..dbe7afd398 100644 --- a/frontend/src/component/executiveDashboard/hooks/useFilteredFlagsSummary.ts +++ b/frontend/src/component/executiveDashboard/hooks/useFilteredFlagsSummary.ts @@ -1,6 +1,7 @@ import { useMemo } from 'react'; import { ExecutiveSummarySchemaProjectFlagTrendsItem } from 'openapi'; +// NOTE: should we move project filtering to the backend? export const useFilteredFlagsSummary = ( filteredProjectFlagTrends: ExecutiveSummarySchemaProjectFlagTrendsItem[], ) => @@ -14,12 +15,11 @@ export const useFilteredFlagsSummary = ( (summary) => summary.week === lastWeekId, ); - const averageUsers = ( + const averageUsers = lastWeekSummary.reduce( (acc, current) => acc + (current.users || 0), 0, - ) / lastWeekSummary.length - ).toFixed(2); + ) / lastWeekSummary.length || 0; const sum = lastWeekSummary.reduce( (acc, current) => ({ @@ -41,6 +41,8 @@ export const useFilteredFlagsSummary = ( return { ...sum, averageUsers, - averageHealth: ((sum.active / (sum.total || 1)) * 100).toFixed(0), + averageHealth: sum.total + ? ((sum.active / (sum.total || 1)) * 100).toFixed(0) + : undefined, }; }, [filteredProjectFlagTrends]); diff --git a/frontend/src/component/executiveDashboard/useMetricsSummary.ts b/frontend/src/component/executiveDashboard/hooks/useMetricsSummary.ts similarity index 95% rename from frontend/src/component/executiveDashboard/useMetricsSummary.ts rename to frontend/src/component/executiveDashboard/hooks/useMetricsSummary.ts index 706279fc0a..9d4dc5ddf3 100644 --- a/frontend/src/component/executiveDashboard/useMetricsSummary.ts +++ b/frontend/src/component/executiveDashboard/hooks/useMetricsSummary.ts @@ -4,7 +4,7 @@ import { ExecutiveSummarySchema, ExecutiveSummarySchemaMetricsSummaryTrendsItem, } from 'openapi'; -import { getProjectColor } from './executive-dashboard-utils'; +import { getProjectColor } from '../executive-dashboard-utils'; type MetricsSummaryTrends = ExecutiveSummarySchema['metricsSummaryTrends']; diff --git a/frontend/src/component/executiveDashboard/hooks/usePlaceholderData.ts b/frontend/src/component/executiveDashboard/hooks/usePlaceholderData.ts new file mode 100644 index 0000000000..6ba372feb0 --- /dev/null +++ b/frontend/src/component/executiveDashboard/hooks/usePlaceholderData.ts @@ -0,0 +1,64 @@ +import { useTheme } from '@mui/material'; +import { useMemo } from 'react'; +import { fillGradientPrimary } from '../components/LineChart/LineChart'; + +export const usePlaceholderData = ({ + fill = false, + type = 'constant', +}: { + fill?: boolean; + type?: 'rising' | 'constant' | 'double'; +}) => { + const theme = useTheme(); + + return useMemo( + () => ({ + labels: Array.from({ length: 15 }, (_, i) => i + 1).map( + (i) => + new Date(Date.now() - (15 - i) * 7 * 24 * 60 * 60 * 1000), + ), + datasets: + type === 'double' + ? [ + { + label: 'Total flags', + data: [ + 43, 66, 55, 65, 62, 72, 75, 73, 80, 65, 62, + 61, 69, 70, 77, + ], + borderColor: theme.palette.primary.light, + backgroundColor: theme.palette.primary.light, + }, + { + label: 'Stale', + data: [ + 3, 5, 4, 6, 2, 7, 5, 3, 8, 3, 5, 11, 8, 4, 3, + ], + borderColor: theme.palette.warning.border, + backgroundColor: theme.palette.warning.border, + }, + ] + : [ + { + label: '', + data: + type === 'rising' + ? [ + 3, 5, 15, 17, 25, 40, 47, 48, 55, + 65, 62, 72, 75, 73, 80, + ] + : [ + 54, 52, 53, 49, 54, 50, 47, 46, + 51, 51, 50, 51, 49, 49, 51, + ], + borderColor: theme.palette.primary.light, + backgroundColor: fill + ? fillGradientPrimary + : theme.palette.primary.light, + fill, + }, + ], + }), + [theme, fill], + ); +}; diff --git a/frontend/src/component/executiveDashboard/useProjectChartData.ts b/frontend/src/component/executiveDashboard/hooks/useProjectChartData.ts similarity index 93% rename from frontend/src/component/executiveDashboard/useProjectChartData.ts rename to frontend/src/component/executiveDashboard/hooks/useProjectChartData.ts index 08354f0999..595018203e 100644 --- a/frontend/src/component/executiveDashboard/useProjectChartData.ts +++ b/frontend/src/component/executiveDashboard/hooks/useProjectChartData.ts @@ -2,8 +2,8 @@ import { useMemo } from 'react'; import { ExecutiveSummarySchema, ExecutiveSummarySchemaProjectFlagTrendsItem, -} from '../../openapi'; -import { getProjectColor } from './executive-dashboard-utils'; +} from '../../../openapi'; +import { getProjectColor } from '../executive-dashboard-utils'; import { useTheme } from '@mui/material'; type ProjectFlagTrends = ExecutiveSummarySchema['projectFlagTrends']; diff --git a/frontend/src/openapi/models/applicationOverviewIssuesSchemaType.ts b/frontend/src/openapi/models/applicationOverviewIssuesSchemaType.ts deleted file mode 100644 index 60dd7739d7..0000000000 --- a/frontend/src/openapi/models/applicationOverviewIssuesSchemaType.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Generated by Orval - * Do not edit manually. - * See `gen:api` script in package.json - */ - -/** - * The name of this action. - */ -export type ApplicationOverviewIssuesSchemaType = - (typeof ApplicationOverviewIssuesSchemaType)[keyof typeof ApplicationOverviewIssuesSchemaType]; - -// eslint-disable-next-line @typescript-eslint/no-redeclare -export const ApplicationOverviewIssuesSchemaType = { - missingFeatures: 'missingFeatures', - missingStrategies: 'missingStrategies', -} as const; diff --git a/frontend/src/openapi/models/index.ts b/frontend/src/openapi/models/index.ts index 2fea49a0a6..70d33954a3 100644 --- a/frontend/src/openapi/models/index.ts +++ b/frontend/src/openapi/models/index.ts @@ -575,6 +575,7 @@ export * from './getAllToggles403'; export * from './getApiTokensByName401'; export * from './getApiTokensByName403'; export * from './getApplication404'; +export * from './getApplicationEnvironmentInstances404'; export * from './getApplicationOverview404'; export * from './getApplicationsParams'; export * from './getArchivedFeatures401';