diff --git a/frontend/src/component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx b/frontend/src/component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx index 69e44ed196..200ef8d87d 100644 --- a/frontend/src/component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx +++ b/frontend/src/component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx @@ -19,6 +19,10 @@ interface IPrettifyLargeNumberProps { * @default 2 */ precision?: number; + /** + * Data attribute for loading state + */ + 'data-loading'?: string; } export const prettifyLargeNumber = @@ -34,12 +38,15 @@ export const PrettifyLargeNumber: FC = ({ value, threshold = 1_000_000, precision = 2, + 'data-loading': dataLoading, }) => { const prettyValue = prettifyLargeNumber(threshold, precision)(value); const showTooltip = value > threshold; const valueSpan = ( - {prettyValue} + + {prettyValue} + ); return ( diff --git a/frontend/src/component/insights/sections/InsightsSection.tsx b/frontend/src/component/insights/sections/InsightsSection.tsx index 392144284c..32d0e3da39 100644 --- a/frontend/src/component/insights/sections/InsightsSection.tsx +++ b/frontend/src/component/insights/sections/InsightsSection.tsx @@ -1,5 +1,5 @@ import { styled } from '@mui/material'; -import type { FC, PropsWithChildren, ReactNode } from 'react'; +import { forwardRef, type PropsWithChildren, type ReactNode } from 'react'; const StyledSection = styled('section')(({ theme }) => ({ display: 'flex', @@ -21,14 +21,15 @@ const SectionTitleRow = styled('div')(({ theme }) => ({ rowGap: theme.spacing(2), })); -export const InsightsSection: FC< +export const InsightsSection = forwardRef< + HTMLElement, PropsWithChildren<{ title: string; filters?: ReactNode }> -> = ({ title, children, filters: HeaderActions }) => ( - +>(({ title, children, filters: HeaderActions }, ref) => ( +

{title}

{HeaderActions}
{children}
-); +)); diff --git a/frontend/src/component/insights/sections/LifecycleInsights.tsx b/frontend/src/component/insights/sections/LifecycleInsights.tsx index 29244dd51a..ee9b5f1c33 100644 --- a/frontend/src/component/insights/sections/LifecycleInsights.tsx +++ b/frontend/src/component/insights/sections/LifecycleInsights.tsx @@ -13,6 +13,7 @@ import { } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx'; import { FeatureLifecycleStageIcon } from 'component/common/FeatureLifecycle/FeatureLifecycleStageIcon.tsx'; import { normalizeDays } from './normalize-days.ts'; +import useLoading from 'hooks/useLoading.ts'; type LifecycleTrend = { totalFlags: number; @@ -128,14 +129,17 @@ export const LifecycleInsights: FC = () => { stateConfig, ); - // todo: use data from the actual endpoint when we have something useful to return + const loadingLabel = 'lifecycle-trend-charts'; + // todo (lifecycleMetrics): use data from the actual endpoint when we have something useful to return const projects = state[`${statePrefix}project`]?.values ?? [allOption.id]; const { insights, loading } = useInsights(); + const loadingRef = useLoading(loading, `[data-loading="${loadingLabel}"]`); const { lifecycleTrends } = insights; return ( { {
Median time for flags currently in stage
-
+
{normalizeDays( data.averageTimeInStageDays, )} @@ -186,7 +191,7 @@ export const LifecycleInsights: FC = () => { Historical median time for flags in stage -
+
{normalizeDays( data.averageTimeInStageDays, )} @@ -247,9 +252,6 @@ const Chart: React.FC<{ stage: string; data: LifecycleTrend }> = ({ labels: { value: { formatter: (value, context) => { - // todo (lifecycleMetrics): use a nice - // formatter here, so that 1,000,000 - // flags are instead formatted as 1M if ( context.chart.legend ?.legendItems?.[1].hidden