Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make no data look like no data #8396

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 29 additions & 36 deletions frontend/src/component/personalDashboard/FlagMetricsChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import annotationPlugin from 'chartjs-plugin-annotation';
import { Bar } from 'react-chartjs-2';
import useTheme from '@mui/material/styles/useTheme';
import { type FC, useEffect, useMemo, useState } from 'react';
import { Box, styled, Typography } from '@mui/material';
import { Box, styled } from '@mui/material';
import { FeatureMetricsHours } from '../feature/FeatureView/FeatureMetrics/FeatureMetricsHours/FeatureMetricsHours';
import GeneralSelect from '../common/GeneralSelect/GeneralSelect';
import { useFeatureMetricsRaw } from 'hooks/api/getters/useFeatureMetricsRaw/useFeatureMetricsRaw';
Expand All @@ -24,39 +24,24 @@ import {
} from './createChartOptions';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';

const defaultYes = [
45_000_000, 28_000_000, 28_000_000, 25_000_000, 50_000_000, 27_000_000,
26_000_000, 50_000_000, 32_000_000, 12_000_000, 13_000_000, 31_000_000,
12_000_000, 47_000_000, 29_000_000, 46_000_000, 45_000_000, 28_000_000,
28_000_000, 25_000_000, 50_000_000, 27_000_000, 26_000_000, 50_000_000,
32_000_000, 12_000_000, 13_000_000, 31_000_000, 12_000_000, 47_000_000,
];
const defaultNo = [
5_000_000, 8_000_000, 3_000_000, 2_000_000, 2_000_000, 5_000_000, 9_000_000,
3_000_000, 7_000_000, 2_000_000, 5_000_000, 8_000_000, 3_000_000, 2_000_000,
2_000_000, 5_000_000, 1_000_000, 3_000_000, 12_000_000, 2_000_000,
1_000_000, 1_000_000, 3_000_000, 2_000_000, 2_000_000, 5_000_000, 1_000_000,
3_000_000, 8_000_000, 2_000_000,
];
const defaultYes = [0, 14, 28, 21, 33, 31, 31, 22, 26, 37, 31, 14, 21, 14, 0];

const placeholderData = {
labels: Array.from({ length: 30 }, (_, i) => i + 1),
labels: Array.from({ length: 15 }, (_, i) => i + 1),
datasets: [
{
data: defaultYes,
label: 'yes',
backgroundColor: '#BEBEBE',
hoverBackgroundColor: '#BEBEBE',
},
{
data: defaultNo,
label: 'no',
backgroundColor: '#9A9A9A',
hoverBackgroundColor: '#9A9A9A',
backgroundColor: '#EAEAED',
hoverBackgroundColor: '#EAEAED',
label: 'No metrics for this feature flag in the selected environment and time period',
},
],
};

const ChartWrapper = styled('div')({
width: '90%',
});

export const PlaceholderFlagMetricsChart = () => {
const theme = useTheme();

Expand All @@ -65,14 +50,13 @@ export const PlaceholderFlagMetricsChart = () => {
}, [theme]);

return (
<>
<Typography sx={{ mb: 4 }}>No feature flag metrics data</Typography>
<ChartWrapper>
<Bar
data={placeholderData}
options={options}
aria-label='A placeholder bar chart with a single feature flag exposure metrics'
/>
</>
</ChartWrapper>
);
};

Expand Down Expand Up @@ -160,7 +144,14 @@ const MetricsSelectors = styled(Box)(({ theme }) => ({
display: 'flex',
justifyContent: 'flex-end',
gap: theme.spacing(2),
mb: theme.spacing(6),
width: '100%',
}));

const ChartContainer = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(3),
alignItems: 'center',
}));

export const FlagMetricsChart: FC<{
Expand All @@ -176,7 +167,7 @@ export const FlagMetricsChart: FC<{
const noData = data.datasets[0].data.length === 0;

return (
<>
<ChartContainer>
<MetricsSelectors>
{environment ? (
<EnvironmentSelect
Expand All @@ -194,13 +185,15 @@ export const FlagMetricsChart: FC<{
{noData ? (
<PlaceholderFlagMetricsChart />
) : (
<Bar
data={data}
options={options}
aria-label='A bar chart with a single feature flag exposure metrics'
/>
<ChartWrapper>
<Bar
data={data}
options={options}
aria-label='A bar chart with a single feature flag exposure metrics'
/>
</ChartWrapper>
)}
</>
</ChartContainer>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ test('Render personal dashboard for a long running project', async () => {
await screen.findByText('13 feature flags'); // stale flags
await screen.findByText('14 feature flags'); // potentially stale flags
await screen.findByText('myFlag');
await screen.findByText('No feature flag metrics data');
await screen.findByText('production');
await screen.findByText('Last 48 hours');
});
Expand All @@ -166,6 +165,4 @@ test('Render personal dashboard for a new project', async () => {
await screen.findByText(
'You have not created or favorited any feature flags. Once you do, they will show up here.',
);

await screen.findByText('No feature flag metrics data');
});
28 changes: 19 additions & 9 deletions frontend/src/component/personalDashboard/createChartOptions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { Theme } from '@mui/material/styles/createTheme';
import type { ChartOptions } from 'chart.js';
import { formatTickValue } from '../common/Chart/formatTickValue';
import type { ILocationSettings } from '../../hooks/useLocationSettings';
import type { IPoint } from '../feature/FeatureView/FeatureMetrics/FeatureMetricsChart/createChartData';
import {
Expand All @@ -24,16 +23,17 @@ export const createPlaceholderBarChartOptions = (
): ChartOptions<'bar'> => ({
plugins: {
legend: {
position: 'bottom',
position: 'top',
labels: {
color: theme.palette.text.primary,
pointStyle: 'circle',
usePointStyle: true,
boxHeight: 6,
pointStyle: 'none',
boxHeight: 0,
padding: 15,
boxPadding: 5,
},
},

tooltip: {
enabled: false,
},
Expand All @@ -43,7 +43,7 @@ export const createPlaceholderBarChartOptions = (
x: {
stacked: true,
ticks: {
color: theme.palette.text.secondary,
display: false,
},
grid: {
display: false,
Expand All @@ -52,9 +52,8 @@ export const createPlaceholderBarChartOptions = (
y: {
stacked: true,
ticks: {
color: theme.palette.text.secondary,
maxTicksLimit: 5,
callback: formatTickValue,
display: false,
},
grid: {
drawBorder: false,
Expand All @@ -77,11 +76,22 @@ export const createBarChartOptions = (
hoursBack: number,
locationSettings: ILocationSettings,
): ChartOptions<'bar'> => {
const { plugins, responsive, elements, interaction, scales } =
const { responsive, elements, interaction, scales } =
createPlaceholderBarChartOptions(theme);
return {
plugins: {
legend: plugins?.legend,
legend: {
position: 'bottom',
labels: {
color: theme.palette.text.primary,
pointStyle: 'circle',
usePointStyle: true,
boxHeight: 6,
padding: 15,
boxPadding: 5,
},
},

// required to avoid the highlight plugin highlighting empty annotation
annotation: {
clip: false,
Expand Down
Loading