Skip to content

Long-term metrics chart legend blinks on data refetch and tooltip shows wrong... #1067

@eve-scality

Description

@eve-scality

Identified by automated analysis of ARTESCA-17128
Confidence: high

What needs to change

File: @artesca/ui/src/components/system-health-monitoring/overview/long-term-metrics/LongTermCapacityChart.tsx
Fix 1 — Blinking Legend (in scality/artesca):

Add keepPreviousData: true (React Query v3) or placeholderData: keepPreviousData (React Query v5) to both useGetPrometheusQueryRange and useGetPrometheusQuery hooks. This ensures that when the query key changes (e.g., endTimestamp updates), the previous data remains available during the refetch, preventing isSuccess from transitioning to false and series from becoming [].

In useGetPrometheusQueryRange.ts:

return useQuery<PrometheusQueryResult>({
    queryKey: [query, startTimestamp, endTimestamp, step],
    queryFn: async () => { ... },
    keepPreviousData: true,  // ADD THIS
    ...
});

In useGetPrometheusQuery.ts:

return useQuery<PrometheusQueryResult>({
    queryKey: ['prometheus-instant', query, timestamp],
    queryFn: async () => { ... },
    keepPreviousData: true,  // ADD THIS
    ...
});

Additionally, in LongTermCapacityChart.tsx, the series useMemo guard should be relaxed to also keep the previous series data while loading:

const series = useMemo(() => {
    if (!isSuccessAggregatedData && !aggregatedData.length) {  // Change || to &&
      return [];
    }
    // ... rest of the series building logic
}, [...]);

Fix 2 — Tooltip Cursor (in scality/core-ui):

In src/lib/components/iconhelper/IconHelper.tsx, change cursor: pointer to cursor: default in the HelpButton styled component:

const HelpButton = styled.button`
  ...
  cursor: default;  // Was: cursor: pointer
  ...
`;

Root Cause

Two related bugs exist in the long-term metrics chart:

Bug 1 — Blinking Legend: In LongTermCapacityChart.tsx, the series useMemo (line 96-98) returns an empty array [] when !isSuccessAggregatedData || !aggregatedData.length. When the component remounts (e.g., navigating away and back, or any parent re-render causing remount), a new endTimestamp is computed via Math.floor(new Date().getTime() / 1000) (line 47). This creates a new React Query cache key [query, startTimestamp, endTimestamp, step] in useGetPrometheusQueryRange, causing React Query to treat it as a fresh query — transitioning isSuccess from true to false momentarily. During this transition, series becomes [], which causes the useChartData hook in core-ui to switch from real data lines (key: "Net capacity-0") to empty placeholder lines (key: "empty-Net capacity"), forcing Recharts to unmount/remount <Line> components — producing the visible blink. The root issue is that keepPreviousData is not used in the React Query hooks, so stale data is discarded during refetches.

Bug 2 — Wrong cursor on tooltip icon: The helpText prop on LineTimeSerieChart renders an IconHelp component from @scality/core-ui. The HelpButton styled component in IconHelper.tsx (line 26) sets cursor: pointer, giving the informational tooltip icon an "action" cursor. Since this icon only shows a tooltip and is not clickable/actionable, it should use cursor: default or cursor: help.

Evidence

@artesca/ui/src/components/system-health-monitoring/overview/long-term-metrics/LongTermCapacityChart.tsx
├── L96: const series = useMemo(() => { ...  — When isSuccessAggregatedData transitions to false during a refetch (new query key), series becomes []. This empties the chart legend and forces Recharts to unmount/remount Line components, causing the visible blink.
└── L46: const timestamps = useMemo(() => { ...  — endTimestamp is computed from Date.now() inside useMemo. On component remount, a new endTimestamp value is generated, which changes the React Query cache key and triggers a fresh fetch (losing cached data).
@artesca/ui/src/hooks/prometheus/useGetPrometheusQueryRange.ts
└── L22: return useQuery<PrometheusQueryResult>({ ...  — The queryKey includes endTimestamp. A new endTimestamp creates a new cache key, causing React Query to start a fresh fetch. Without keepPreviousData, the previous data is discarded and isSuccess becomes false during the fetch.
@artesca/ui/src/hooks/long-terms-metrics/useAggregatedPrometheusData.ts
└── L101: return { ...  — isSuccess is directly tied to the range query's success state. When a new query key triggers a fresh fetch, isSuccessRange becomes false, propagating up to LongTermCapacityChart where it causes series to return [].
@artesca/ui/src/hooks/prometheus/useGetPrometheusQuery.ts
└── L15: return useQuery<PrometheusQueryResult>({ ...  — The instant query also includes the timestamp (endTimestamp) in its query key, so it also triggers a fresh fetch when endTimestamp changes, contributing to the loading state flash.

Upstream Impact

Medium severity. The blinking chart legend is a visual regression that affects the user experience on the main overview/dashboard page. Every time a user navigates to or revisits the System Health Monitoring overview, the chart legend may flash/blink momentarily. The incorrect cursor on the tooltip icon is a minor UI polish issue but contributes to a perception of inconsistency. Both bugs affect all users viewing the long-term metrics chart.

Metadata

Metadata

Assignees

No one assigned

    Labels

    cerebro-analyzedIssue created by Cerebro automated analysis

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions