diff --git a/src/containers/Tenant/Diagnostics/TenantOverview/TenantDashboard/TenantDashboard.tsx b/src/containers/Tenant/Diagnostics/TenantOverview/TenantDashboard/TenantDashboard.tsx index a28c1024d2..a5dda73abc 100644 --- a/src/containers/Tenant/Diagnostics/TenantOverview/TenantDashboard/TenantDashboard.tsx +++ b/src/containers/Tenant/Diagnostics/TenantOverview/TenantDashboard/TenantDashboard.tsx @@ -6,6 +6,7 @@ import type { ChartOptions, MetricDescription, } from '../../../../../components/MetricChart'; +import {useGraphShardExists} from '../../../../../store/reducers/capabilities/hooks'; import {cn} from '../../../../../utils/cn'; import {useAutoRefreshInterval} from '../../../../../utils/hooks'; @@ -28,7 +29,14 @@ interface TenantDashboardProps { } export const TenantDashboard = ({database, charts}: TenantDashboardProps) => { - const [isDashboardHidden, setIsDashboardHidden] = React.useState(true); + const graphShardExists = useGraphShardExists(); + + const [hasSuccessfulChart, setHasSuccessfulChart] = React.useState(false); + + const isDashboardHidden = React.useMemo(() => { + return !graphShardExists && !hasSuccessfulChart; + }, [graphShardExists, hasSuccessfulChart]); + const [autoRefreshInterval] = useAutoRefreshInterval(); // Refetch data only if dashboard successfully loaded @@ -40,12 +48,14 @@ export const TenantDashboard = ({database, charts}: TenantDashboardProps) => { * 2. ydb version does not have /viewer/json/render endpoint (400, 404, CORS error, etc.) * * If at least one chart successfully loaded, dashboard should be shown + * This fallback behavior is only used when GraphShardExists capability is not available or false * @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 = (chartStatus: ChartDataStatus) => { + // Always track successful chart loads for fallback behavior if (chartStatus === 'success') { - setIsDashboardHidden(false); + setHasSuccessfulChart(true); } }; diff --git a/src/store/reducers/capabilities/capabilities.ts b/src/store/reducers/capabilities/capabilities.ts index 4c60366d4e..fa4abc341d 100644 --- a/src/store/reducers/capabilities/capabilities.ts +++ b/src/store/reducers/capabilities/capabilities.ts @@ -65,6 +65,13 @@ export const selectSecuritySetting = createSelector( selectDatabaseCapabilities(state, database).data?.Settings?.Security?.[setting], ); +export const selectGraphShardExists = createSelector( + (state: RootState) => state, + (_state: RootState, database?: string) => database, + (state, database) => + selectDatabaseCapabilities(state, database).data?.Settings?.Database?.GraphShardExists, +); + export async function queryCapability( capability: Capability, database: string | undefined, diff --git a/src/store/reducers/capabilities/hooks.ts b/src/store/reducers/capabilities/hooks.ts index 24232e419a..6f03517ee3 100644 --- a/src/store/reducers/capabilities/hooks.ts +++ b/src/store/reducers/capabilities/hooks.ts @@ -6,6 +6,7 @@ import { capabilitiesApi, selectCapabilityVersion, selectDatabaseCapabilities, + selectGraphShardExists, selectMetaCapabilities, selectMetaCapabilityVersion, selectSecuritySetting, @@ -98,6 +99,12 @@ const useGetSecuritySetting = (feature: SecuritySetting) => { return useTypedSelector((state) => selectSecuritySetting(state, feature, database)); }; +export const useGraphShardExists = () => { + const database = useDatabaseFromQuery(); + + return useTypedSelector((state) => selectGraphShardExists(state, database)); +}; + export const useClusterWithoutAuthInUI = () => { return useGetSecuritySetting('UseLoginProvider') === false; }; diff --git a/src/types/api/capabilities.ts b/src/types/api/capabilities.ts index 0a20d28786..c2bc53f9a8 100644 --- a/src/types/api/capabilities.ts +++ b/src/types/api/capabilities.ts @@ -5,6 +5,9 @@ export interface CapabilitiesResponse { Capabilities: Record, number>; Settings?: { Security?: Record, boolean>; + Database?: { + GraphShardExists?: boolean; + }; }; }