diff --git a/src/containers/Tenant/Diagnostics/Diagnostics.scss b/src/containers/Tenant/Diagnostics/Diagnostics.scss index 94c229d652..d5e26309c4 100644 --- a/src/containers/Tenant/Diagnostics/Diagnostics.scss +++ b/src/containers/Tenant/Diagnostics/Diagnostics.scss @@ -45,4 +45,8 @@ // This prevents inheritance issues with percentage-based calculations container-type: size; } + + &__new-label { + margin-left: 8px; + } } diff --git a/src/containers/Tenant/Diagnostics/Diagnostics.tsx b/src/containers/Tenant/Diagnostics/Diagnostics.tsx index 86f5fec76e..4784aafa6b 100644 --- a/src/containers/Tenant/Diagnostics/Diagnostics.tsx +++ b/src/containers/Tenant/Diagnostics/Diagnostics.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {Tab, TabList, TabProvider} from '@gravity-ui/uikit'; +import {Label, Tab, TabList, TabProvider} from '@gravity-ui/uikit'; import {Helmet} from 'react-helmet-async'; import {AutoRefreshControl} from '../../../components/AutoRefreshControl/AutoRefreshControl'; @@ -33,6 +33,7 @@ import Describe from './Describe/Describe'; import DetailedOverview from './DetailedOverview/DetailedOverview'; import {getPagesByType, useDiagnosticsPageLinkGetter} from './DiagnosticsPages'; import {HotKeys} from './HotKeys/HotKeys'; +import {Monitoring} from './Monitoring/Monitoring'; import {NetworkWrapper} from './Network/NetworkWrapper'; import {Partitions} from './Partitions/Partitions'; import {TopQueries} from './TopQueries'; @@ -98,6 +99,15 @@ function Diagnostics({additionalTenantProps}: DiagnosticsProps) { /> ); } + case TENANT_DIAGNOSTICS_TABS_IDS.monitoring: { + const monitoringUrl = additionalTenantProps?.getMonitoringLink?.( + database, + databaseType, + ); + return ( + + ); + } case TENANT_DIAGNOSTICS_TABS_IDS.schema: { return ( { + // Date when the Monitoring tab was added (Oct 22, 2025) + const MONITORING_TAB_LAUNCH_DATE = new Date('2025-10-22'); + const FOURTEEN_DAYS_MS = 14 * 24 * 60 * 60 * 1000; + const now = new Date(); + const showNewLabel = + now.getTime() - MONITORING_TAB_LAUNCH_DATE.getTime() < FOURTEEN_DAYS_MS; + return (
@@ -227,10 +244,21 @@ function Diagnostics({additionalTenantProps}: DiagnosticsProps) { {pages.map(({id, title}) => { const linkPath = getDiagnosticsPageLink(id); + const isMonitoringTab = + id === TENANT_DIAGNOSTICS_TABS_IDS.monitoring; return ( {title} + {isMonitoringTab && showNewLabel && ( + + )} ); diff --git a/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts b/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts index c6c81b8d34..973302b30b 100644 --- a/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts +++ b/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts @@ -29,6 +29,11 @@ const overview = { title: 'Info', }; +const monitoring = { + id: TENANT_DIAGNOSTICS_TABS_IDS.monitoring, + title: 'Monitoring', +}; + const schema = { id: TENANT_DIAGNOSTICS_TABS_IDS.schema, title: 'Schema', @@ -115,6 +120,7 @@ const TRANSFER_PAGES = [overview, tablets, describe, access]; const DATABASE_PAGES = [ overview, + monitoring, topQueries, topShards, nodes, @@ -130,6 +136,7 @@ const DATABASE_PAGES = [ const SERVERLESS_DATABASE_PAGES = [ overview, + monitoring, topQueries, topShards, tablets, diff --git a/src/containers/Tenant/Diagnostics/Monitoring/Monitoring.scss b/src/containers/Tenant/Diagnostics/Monitoring/Monitoring.scss new file mode 100644 index 0000000000..fa3e31f031 --- /dev/null +++ b/src/containers/Tenant/Diagnostics/Monitoring/Monitoring.scss @@ -0,0 +1,28 @@ +@use '../../../../styles/mixins'; + +.ydb-monitoring { + width: 100%; + height: 100%; + + &__iframe { + width: 100%; + height: 100%; + + border: none; + } + + &__empty { + display: flex; + justify-content: center; + align-items: center; + + width: 100%; + height: 100%; + } + + &__empty-text { + font-size: 16px; + + color: var(--g-color-text-secondary); + } +} diff --git a/src/containers/Tenant/Diagnostics/Monitoring/Monitoring.tsx b/src/containers/Tenant/Diagnostics/Monitoring/Monitoring.tsx new file mode 100644 index 0000000000..54e6cf6570 --- /dev/null +++ b/src/containers/Tenant/Diagnostics/Monitoring/Monitoring.tsx @@ -0,0 +1,33 @@ +import {cn} from '../../../../utils/cn'; + +import i18n from './i18n'; + +import './Monitoring.scss'; + +const b = cn('ydb-monitoring'); + +interface MonitoringProps { + database: string; + monitoringUrl?: string; +} + +export function Monitoring({monitoringUrl}: MonitoringProps) { + if (!monitoringUrl) { + return ( +
+
{i18n('message_not-available')}
+
+ ); + } + + return ( +
+