import React from 'react'; import {Flex, Tab, TabList, TabProvider} from '@gravity-ui/uikit'; import {skipToken} from '@reduxjs/toolkit/query'; import {Helmet} from 'react-helmet-async'; import {useParams} from 'react-router-dom'; import {useQueryParams} from 'use-query-params'; import {z} from 'zod'; import {StickyAutoRefreshControl} from '../../components/AutoRefreshControl/StickyAutoRefreshControl'; import {EmptyStateWrapper} from '../../components/EmptyState'; import {EntityPageTitle} from '../../components/EntityPageTitle/EntityPageTitle'; import {ResponseError} from '../../components/Errors/ResponseError'; import {InternalLink} from '../../components/InternalLink'; import {LoaderWrapper} from '../../components/LoaderWrapper/LoaderWrapper'; import {PageMeta} from '../../components/PageMeta/PageMeta'; import {tabletPageQueryParams, useTabletPagePath} from '../../routes'; import {useTabletDevUiSecurePath} from '../../store/reducers/capabilities/hooks'; import {setHeaderBreadcrumbs} from '../../store/reducers/header/header'; import {tabletApi} from '../../store/reducers/tablet'; import {EFlag} from '../../types/api/enums'; import type {TTabletStateInfo} from '../../types/api/tablet'; import type {ITabletPreparedHistoryItem} from '../../types/store/tablet'; import {cn} from '../../utils/cn'; import {CLUSTER_DEFAULT_TITLE} from '../../utils/constants'; import {useAutoRefreshInterval, useTypedDispatch} from '../../utils/hooks'; import {useIsUserAllowedToMakeChanges} from '../../utils/hooks/useIsUserAllowedToMakeChanges'; import {TabletControls} from './components/TabletControls'; import {TabletInfo} from './components/TabletInfo'; import {TabletStorageInfo} from './components/TabletStorageInfo/TabletStorageInfo'; import {TabletTable} from './components/TabletTable'; import i18n from './i18n'; import {getTabletObjectKind, hasHive} from './utils'; import './Tablet.scss'; const b = cn('ydb-tablet-page'); const TABLET_TABS_IDS = { history: 'history', channels: 'channels', } as const; const TABLET_PAGE_TABS = [ { id: TABLET_TABS_IDS.history, get title() { return i18n('label_tablet-history'); }, }, { id: TABLET_TABS_IDS.channels, get title() { return i18n('label_tablet-channels'); }, isAdvanced: true, }, ]; const tabletTabSchema = z.nativeEnum(TABLET_TABS_IDS).catch(TABLET_TABS_IDS.history); export function Tablet() { const dispatch = useTypedDispatch(); const {id} = useParams<{id: string}>(); const [{database: queryDatabase, clusterName: queryClusterName, followerId: queryFollowerId}] = useQueryParams(tabletPageQueryParams); const database = queryDatabase?.toString(); const [autoRefreshInterval] = useAutoRefreshInterval(); const {currentData, isFetching, error} = tabletApi.useGetTabletQuery( {id, database, followerId: queryFollowerId ?? undefined}, {pollingInterval: autoRefreshInterval}, ); const loading = isFetching && currentData === undefined; const {data: tablet = {}, history = []} = currentData || {}; const {currentData: databaseFullPath} = tabletApi.useGetTabletDescribeQuery( tablet.TenantId ? {tenantId: tablet.TenantId, database} : skipToken, ); const tabletType = tablet.Type; React.useEffect(() => { dispatch( setHeaderBreadcrumbs('tablet', { database, tabletId: id, tabletType, databaseName: databaseFullPath, }), ); }, [dispatch, database, id, tabletType, databaseFullPath]); const {Leader} = tablet; const metaItems: string[] = []; if (databaseFullPath) { metaItems.push(`${i18n('tablet.meta-database')}: ${databaseFullPath}`); } // Add "Tablet" instead of tablet type to metadata metaItems.push(i18n('tablet.header')); if (Leader === false) { metaItems.push(i18n('tablet.meta-follower').toUpperCase()); } return (