From 392896dfb1e1646b3dafb7d1518eaac38c741b6b Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Tue, 15 Jul 2025 14:09:05 +0300 Subject: [PATCH] fix: query activities banner visibility --- .../QueriesActivityBar/QueriesActivityBar.tsx | 34 ++++++++++++++++--- .../QueriesActivityCharts.tsx | 31 ++++++++++------- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/components/QueriesActivityBar/QueriesActivityBar.tsx b/src/components/QueriesActivityBar/QueriesActivityBar.tsx index 52a8c9fa7e..acfe89deab 100644 --- a/src/components/QueriesActivityBar/QueriesActivityBar.tsx +++ b/src/components/QueriesActivityBar/QueriesActivityBar.tsx @@ -13,6 +13,7 @@ import {cn} from '../../utils/cn'; import {useAutoRefreshInterval} from '../../utils/hooks'; import type {TimeFrame} from '../../utils/timeframes'; import {chartApi} from '../MetricChart/reducer'; +import type {ChartDataStatus} from '../MetricChart/types'; import {QueriesActivityCharts} from './QueriesActivityCharts'; import i18n from './i18n'; @@ -33,6 +34,25 @@ export function QueriesActivityBar({tenantName}: QueriesActivityBarProps) { const [expanded, setExpanded] = React.useState(false); const [queriesTimeFrame] = React.useState('1h'); const [latenciesTimeFrame] = React.useState('1h'); + const [isActivityBarHidden, setIsActivityBarHidden] = React.useState(true); + + // Refetch data only if activity bar successfully loaded + const shouldRefresh = isActivityBarHidden ? 0 : autoRefreshInterval; + + /** + * Activity bar should be hidden, if charts are not enabled: + * 1. GraphShard is not enabled + * 2. ydb version does not have /viewer/json/render endpoint (400, 404, CORS error, etc.) + * + * If at least one chart successfully loaded, activity bar should be shown + * @link https://github.com/ydb-platform/ydb-embedded-ui/issues/659 + * @todo disable only for specific errors ('GraphShard is not enabled') after ydb-stable-24 is generally used + */ + const handleChartDataStatusChange = React.useCallback((chartStatus: ChartDataStatus) => { + if (chartStatus === 'success') { + setIsActivityBarHidden(false); + } + }, []); // Fetch running queries const {data: runningQueriesData} = topQueriesApi.useGetRunningQueriesQuery( @@ -40,7 +60,7 @@ export function QueriesActivityBar({tenantName}: QueriesActivityBarProps) { database: tenantName, filters: {}, }, - {pollingInterval: autoRefreshInterval}, + {pollingInterval: shouldRefresh}, ); // Fetch queries per second data for header metrics @@ -51,7 +71,7 @@ export function QueriesActivityBar({tenantName}: QueriesActivityBarProps) { timeFrame: queriesTimeFrame, maxDataPoints: 30, }, - {pollingInterval: autoRefreshInterval}, + {pollingInterval: shouldRefresh}, ); // Fetch latency data for header metrics @@ -62,7 +82,7 @@ export function QueriesActivityBar({tenantName}: QueriesActivityBarProps) { timeFrame: latenciesTimeFrame, maxDataPoints: 30, }, - {pollingInterval: autoRefreshInterval}, + {pollingInterval: shouldRefresh}, ); const runningQueriesCount = runningQueriesData?.resultSets?.[0]?.result?.length || 0; @@ -109,7 +129,7 @@ export function QueriesActivityBar({tenantName}: QueriesActivityBarProps) { }; return ( -
+
{(props) => ( @@ -204,7 +224,11 @@ export function QueriesActivityBar({tenantName}: QueriesActivityBarProps) {
) : null} - +
); } diff --git a/src/components/QueriesActivityBar/QueriesActivityCharts.tsx b/src/components/QueriesActivityBar/QueriesActivityCharts.tsx index 52a59a6b0d..c943fee847 100644 --- a/src/components/QueriesActivityBar/QueriesActivityCharts.tsx +++ b/src/components/QueriesActivityBar/QueriesActivityCharts.tsx @@ -15,11 +15,16 @@ const b = cn('queries-activity-bar'); interface QueriesActivityChartsProps { tenantName: string; expanded: boolean; + onChartDataStatusChange?: (status: ChartDataStatus) => void; } const ACTIVITY_CHART_HEIGHT = 292; -export function QueriesActivityCharts({tenantName, expanded}: QueriesActivityChartsProps) { +export function QueriesActivityCharts({ + tenantName, + expanded, + onChartDataStatusChange, +}: QueriesActivityChartsProps) { const [autoRefreshInterval] = useAutoRefreshInterval(); const [queriesTimeFrame, setQueriesTimeFrame] = React.useState('1h'); const [latenciesTimeFrame, setLatenciesTimeFrame] = React.useState('1h'); @@ -44,11 +49,16 @@ export function QueriesActivityCharts({tenantName, expanded}: QueriesActivityCha // Refetch data only if charts have successfully loaded at least once const shouldRefresh = hasChartsLoaded ? autoRefreshInterval : 0; - const handleChartDataStatusChange = React.useCallback((status: ChartDataStatus) => { - if (status === 'success') { - setHasChartsLoaded(true); - } - }, []); + const handleChartDataStatusChange = React.useCallback( + (status: ChartDataStatus) => { + if (status === 'success') { + setHasChartsLoaded(true); + } + // Also call parent callback if provided + onChartDataStatusChange?.(status); + }, + [onChartDataStatusChange], + ); const handleQueriesTimeFrameChange = React.useCallback((newTimeFrame: TimeFrame) => { setQueriesTimeFrame(newTimeFrame); @@ -92,12 +102,9 @@ export function QueriesActivityCharts({tenantName, expanded}: QueriesActivityCha // fails when the chart is not immediately visible during mounting. // TODO: Remove this workaround once the upstream issue is fixed - if (!expanded) { - return null; - } return ( -
+