Skip to content

Commit

Permalink
Fix: insights loading (#6834)
Browse files Browse the repository at this point in the history
Loading state for
- charts (placeholder data, animation)
- user stats - loading skeleton animation
- empty flags stats
- kept other "stat" widgets as-is, usually not visible
  • Loading branch information
Tymek committed Apr 15, 2024
1 parent 1f4febb commit e10ad72
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 33 deletions.
20 changes: 15 additions & 5 deletions frontend/src/component/insights/InsightsCharts.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { ConditionallyRender } from '../common/ConditionallyRender/ConditionallyRender';
import type { VFC } from 'react';
import { Box, styled } from '@mui/material';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { Widget } from './components/Widget/Widget';
import { UserStats } from './componentsStat/UserStats/UserStats';
import { UsersChart } from './componentsChart/UsersChart/UsersChart';
Expand All @@ -18,9 +20,7 @@ import type {
InstanceInsightsSchemaUsers,
} from 'openapi';
import type { GroupedDataByProject } from './hooks/useGroupedProjectTrends';
import { Box, styled } from '@mui/material';
import { allOption } from '../common/ProjectSelect/ProjectSelect';
import type { VFC } from 'react';
import { allOption } from 'component/common/ProjectSelect/ProjectSelect';
import { chartInfo } from './chart-info';

interface IChartsProps {
Expand Down Expand Up @@ -107,6 +107,7 @@ export const InsightsCharts: VFC<IChartsProps> = ({
count={users.total}
active={users.active}
inactive={users.inactive}
isLoading={loading}
/>
</Widget>
}
Expand All @@ -116,7 +117,10 @@ export const InsightsCharts: VFC<IChartsProps> = ({
? chartInfo.usersInProject
: chartInfo.avgUsersPerProject)}
>
<UserStats count={summary.averageUsers} />
<UserStats
count={summary.averageUsers}
isLoading={loading}
/>
</Widget>
}
/>
Expand All @@ -134,6 +138,7 @@ export const InsightsCharts: VFC<IChartsProps> = ({
<ChartWidget {...chartInfo.usersPerProject}>
<UsersPerProjectChart
projectFlagTrends={groupedProjectsData}
isLoading={loading}
/>
</ChartWidget>
}
Expand All @@ -144,6 +149,7 @@ export const InsightsCharts: VFC<IChartsProps> = ({
flagsPerUser={
showAllProjects ? getFlagsPerUser(flags, users) : ''
}
isLoading={loading}
/>
</Widget>
<ConditionallyRender
Expand All @@ -160,6 +166,7 @@ export const InsightsCharts: VFC<IChartsProps> = ({
<ChartWidget {...chartInfo.flagsPerProject}>
<FlagsProjectChart
projectFlagTrends={groupedProjectsData}
isLoading={loading}
/>
</ChartWidget>
}
Expand All @@ -180,6 +187,7 @@ export const InsightsCharts: VFC<IChartsProps> = ({
<ProjectHealthChart
projectFlagTrends={groupedProjectsData}
isAggregate={showAllProjects}
isLoading={loading}
/>
</ChartWidget>
<Widget {...chartInfo.medianTimeToProduction}>
Expand All @@ -195,6 +203,7 @@ export const InsightsCharts: VFC<IChartsProps> = ({
<TimeToProductionChart
projectFlagTrends={groupedProjectsData}
isAggregate={showAllProjects}
isLoading={loading}
/>
</ChartWidget>
</StyledGrid>
Expand All @@ -207,6 +216,7 @@ export const InsightsCharts: VFC<IChartsProps> = ({
metricsSummaryTrends={groupedMetricsData}
allDatapointsSorted={allMetricsDatapoints}
isAggregate={showAllProjects}
isLoading={loading}
/>
</Widget>
<Widget
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const LineChartComponent: VFC<{
return (
<StyledContainer>
<Line
key={cover ? 'cover' : 'chart'}
options={options}
data={data}
plugins={[customHighlightPlugin]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const FlagsChart: VFC<IFlagsChartProps> = ({
isLoading,
}) => {
const theme = useTheme();
const notEnoughData = flagTrends.length < 2;
const notEnoughData = !isLoading && flagTrends.length < 2;
const placeholderData = usePlaceholderData({ fill: true, type: 'double' });

const data = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,35 @@ interface IFlagsProjectChartProps {
projectFlagTrends: GroupedDataByProject<
InstanceInsightsSchema['projectFlagTrends']
>;
isLoading?: boolean;
}

export const FlagsProjectChart: VFC<IFlagsProjectChartProps> = ({
projectFlagTrends,
isLoading,
}) => {
const placeholderData = usePlaceholderData({
type: 'constant',
});

const data = useProjectChartData(projectFlagTrends);
const notEnoughData = useMemo(
() => (data.datasets.some((d) => d.data.length > 1) ? false : true),
[data],
() =>
!isLoading &&
(data.datasets.some((d) => d.data.length > 1) ? false : true),
[data, isLoading],
);

return (
<LineChart
data={notEnoughData ? placeholderData : data}
data={notEnoughData || isLoading ? placeholderData : data}
overrideOptions={{
parsing: {
yAxisKey: 'total',
xAxisKey: 'date',
},
}}
cover={notEnoughData ? <NotEnoughData /> : false}
cover={notEnoughData ? <NotEnoughData /> : isLoading}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,25 @@ interface IMetricsSummaryChartProps {
>;
isAggregate?: boolean;
allDatapointsSorted: string[];
isLoading?: boolean;
}

export const MetricsSummaryChart: VFC<IMetricsSummaryChartProps> = ({
metricsSummaryTrends,
isAggregate,
allDatapointsSorted,
isLoading,
}) => {
const theme = useTheme();
const metricsSummary = useFilledMetricsSummary(
metricsSummaryTrends,
allDatapointsSorted,
);
const notEnoughData = useMemo(
() => !metricsSummary.datasets.some((d) => d.data.length > 1),
[metricsSummary],
() =>
!isLoading &&
!metricsSummary.datasets.some((d) => d.data.length > 1),
[metricsSummary, isLoading],
);
const placeholderData = usePlaceholderData();

Expand Down Expand Up @@ -67,7 +71,7 @@ export const MetricsSummaryChart: VFC<IMetricsSummaryChartProps> = ({

return (
<LineChart
data={notEnoughData ? placeholderData : data}
data={notEnoughData || isLoading ? placeholderData : data}
TooltipComponent={MetricsSummaryTooltip}
overrideOptions={
notEnoughData
Expand All @@ -79,7 +83,7 @@ export const MetricsSummaryChart: VFC<IMetricsSummaryChartProps> = ({
},
}
}
cover={notEnoughData ? <NotEnoughData /> : false}
cover={notEnoughData ? <NotEnoughData /> : isLoading}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,24 @@ import {
} from 'component/insights/components/LineChart/LineChart';
import { useTheme } from '@mui/material';
import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends';
import { usePlaceholderData } from 'component/insights/hooks/usePlaceholderData';

interface IProjectHealthChartProps {
projectFlagTrends: GroupedDataByProject<
InstanceInsightsSchema['projectFlagTrends']
>;
isAggregate?: boolean;
isLoading?: boolean;
}

export const ProjectHealthChart: VFC<IProjectHealthChartProps> = ({
projectFlagTrends,
isAggregate,
isLoading,
}) => {
const projectsData = useProjectChartData(projectFlagTrends);
const theme = useTheme();
const placeholderData = usePlaceholderData();

const aggregateHealthData = useMemo(() => {
const labels = Array.from(
Expand Down Expand Up @@ -85,12 +89,19 @@ export const ProjectHealthChart: VFC<IProjectHealthChartProps> = ({
};
}, [projectsData, theme]);

const data = isAggregate ? aggregateHealthData : projectsData;
const aggregateOrProjectData = isAggregate
? aggregateHealthData
: projectsData;
const notEnoughData = useMemo(
() =>
projectsData.datasets.some((d) => d.data.length > 1) ? false : true,
[projectsData],
!isLoading &&
(projectsData.datasets.some((d) => d.data.length > 1)
? false
: true),
[projectsData, isLoading],
);
const data =
notEnoughData || isLoading ? placeholderData : aggregateOrProjectData;

return (
<LineChart
Expand All @@ -104,7 +115,7 @@ export const ProjectHealthChart: VFC<IProjectHealthChartProps> = ({
parsing: { yAxisKey: 'health', xAxisKey: 'date' },
}
}
cover={notEnoughData ? <NotEnoughData /> : false}
cover={notEnoughData ? <NotEnoughData /> : isLoading}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,21 @@ interface ITimeToProductionChartProps {
InstanceInsightsSchema['projectFlagTrends']
>;
isAggregate?: boolean;
isLoading?: boolean;
}

export const TimeToProductionChart: VFC<ITimeToProductionChartProps> = ({
projectFlagTrends,
isAggregate,
isLoading,
}) => {
const theme = useTheme();
const projectsDatasets = useProjectChartData(projectFlagTrends);
const notEnoughData = useMemo(
() => !projectsDatasets.datasets.some((d) => d.data.length > 1),
[projectsDatasets],
() =>
!isLoading &&
!projectsDatasets.datasets.some((d) => d.data.length > 1),
[projectsDatasets, isLoading],
);

const aggregatedPerDay = useMemo(() => {
Expand Down Expand Up @@ -62,7 +66,7 @@ export const TimeToProductionChart: VFC<ITimeToProductionChartProps> = ({
const placeholderData = usePlaceholderData();
return (
<LineChart
data={notEnoughData ? placeholderData : data}
data={notEnoughData || isLoading ? placeholderData : data}
TooltipComponent={TimeToProductionTooltip}
overrideOptions={
notEnoughData
Expand All @@ -74,7 +78,7 @@ export const TimeToProductionChart: VFC<ITimeToProductionChartProps> = ({
},
}
}
cover={notEnoughData ? <NotEnoughData /> : false}
cover={notEnoughData ? <NotEnoughData /> : isLoading}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const UpdatesPerEnvironmentTypeChart: VFC<
> = ({ environmentTypeTrends, isLoading }) => {
const theme = useTheme();
const getEnvironmentTypeColor = useEnvironmentTypeColor();
const notEnoughData = environmentTypeTrends?.length < 2;
const notEnoughData = !isLoading && environmentTypeTrends?.length < 2;
const placeholderData = usePlaceholderData({ fill: true, type: 'double' });

const data = useMemo(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const UsersChart: VFC<IUsersChartProps> = ({
}) => {
const showInactiveUsers = useUiFlag('showInactiveUsers');
const theme = useTheme();
const notEnoughData = userTrends.length < 2;
const notEnoughData = !isLoading && userTrends.length < 2;
const placeholderData = usePlaceholderData({ fill: true, type: 'rising' });
const data = useMemo(
() => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,35 @@ interface IUsersPerProjectChartProps {
projectFlagTrends: GroupedDataByProject<
InstanceInsightsSchema['projectFlagTrends']
>;
isLoading?: boolean;
}

export const UsersPerProjectChart: VFC<IUsersPerProjectChartProps> = ({
projectFlagTrends,
isLoading,
}) => {
const placeholderData = usePlaceholderData({
type: 'constant',
});

const data = useProjectChartData(projectFlagTrends);
const notEnoughData = useMemo(
() => (data.datasets.some((d) => d.data.length > 1) ? false : true),
[data],
() =>
!isLoading &&
(data.datasets.some((d) => d.data.length > 1) ? false : true),
[data, isLoading],
);

return (
<LineChart
data={notEnoughData ? placeholderData : data}
data={notEnoughData || isLoading ? placeholderData : data}
overrideOptions={{
parsing: {
yAxisKey: 'users',
xAxisKey: 'date',
},
}}
cover={notEnoughData ? <NotEnoughData /> : false}
cover={notEnoughData ? <NotEnoughData /> : isLoading}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,21 @@ const StyledIcon = styled(Icon)(({ theme }) => ({
interface IFlagStatsProps {
count: number;
flagsPerUser?: string;
isLoading?: boolean;
}

export const FlagStats: React.FC<IFlagStatsProps> = ({
count,
flagsPerUser,
isLoading,
}) => {
return (
<>
<StyledRingContainer>
<StyledRing>
<StyledRingContent>{count}</StyledRingContent>
<StyledRingContent>
{isLoading ? '' : count}
</StyledRingContent>
</StyledRing>
</StyledRingContainer>

Expand Down

0 comments on commit e10ad72

Please sign in to comment.