diff --git a/src/containers/Tenant/Diagnostics/Describe/Describe.tsx b/src/containers/Tenant/Diagnostics/Describe/Describe.tsx index 235c2b76df..ceb3d30508 100644 --- a/src/containers/Tenant/Diagnostics/Describe/Describe.tsx +++ b/src/containers/Tenant/Diagnostics/Describe/Describe.tsx @@ -5,9 +5,10 @@ import {shallowEqual} from 'react-redux'; import {ResponseError} from '../../../../components/Errors/ResponseError'; import {Loader} from '../../../../components/Loader'; -import {describeApi} from '../../../../store/reducers/describe'; +import {overviewApi} from '../../../../store/reducers/overview/overview'; import {selectSchemaMergedChildrenPaths} from '../../../../store/reducers/schema/schema'; import type {EPathType} from '../../../../types/api/schema'; +import type {IDescribeData} from '../../../../types/store/describe'; import {cn} from '../../../../utils/cn'; import {useAutoRefreshInterval, useTypedSelector} from '../../../../utils/hooks'; import {isEntityWithMergedImplementation} from '../../utils/schema'; @@ -25,6 +26,8 @@ interface IDescribeProps { type?: EPathType; } +const emptyObject: IDescribeData = {}; + const Describe = ({path, database, type}: IDescribeProps) => { const [autoRefreshInterval] = useAutoRefreshInterval(); @@ -41,14 +44,29 @@ const Describe = ({path, database, type}: IDescribeProps) => { } else if (mergedChildrenPaths) { paths = [path, ...mergedChildrenPaths]; } - const {currentData, isFetching, error} = describeApi.useGetDescribeQuery( + const {currentDescribe, currentData, isFetching, error} = overviewApi.useGetOverviewQuery( paths.length ? {paths, database} : skipToken, { pollingInterval: autoRefreshInterval, + selectFromResult: (props) => { + const {currentData} = props; + if (!currentData) { + return {currentDescribe: emptyObject, ...props}; + } + + const mergedData = [currentData.data, ...currentData.additionalData]; + + const data = mergedData.reduce((acc, item) => { + if (item?.Path) { + acc[item.Path] = item; + } + return acc; + }, {}); + return {currentDescribe: data, ...props}; + }, }, ); const loading = isFetching && currentData === undefined; - const currentDescribe = currentData; let preparedDescribeData: Object | undefined; if (currentDescribe) { diff --git a/src/containers/Tenant/Diagnostics/HotKeys/HotKeys.tsx b/src/containers/Tenant/Diagnostics/HotKeys/HotKeys.tsx index 33a33f9491..afd4f82520 100644 --- a/src/containers/Tenant/Diagnostics/HotKeys/HotKeys.tsx +++ b/src/containers/Tenant/Diagnostics/HotKeys/HotKeys.tsx @@ -8,11 +8,11 @@ import {Button, Card, Icon} from '@gravity-ui/uikit'; import {ResponseError} from '../../../../components/Errors/ResponseError'; import {ResizeableDataTable} from '../../../../components/ResizeableDataTable/ResizeableDataTable'; import {hotKeysApi} from '../../../../store/reducers/hotKeys/hotKeys'; -import {useGetSchemaQuery} from '../../../../store/reducers/schema/schema'; +import {overviewApi} from '../../../../store/reducers/overview/overview'; import type {HotKey} from '../../../../types/api/hotkeys'; import {cn} from '../../../../utils/cn'; import {DEFAULT_TABLE_SETTINGS, IS_HOTKEYS_HELP_HIDDEN_KEY} from '../../../../utils/constants'; -import {useSetting} from '../../../../utils/hooks'; +import {useAutoRefreshInterval, useSetting} from '../../../../utils/hooks'; import i18n from './i18n'; @@ -61,9 +61,17 @@ interface HotKeysProps { export function HotKeys({path, database}: HotKeysProps) { const {currentData: data, isFetching, error} = hotKeysApi.useGetHotKeysQuery({path, database}); const loading = isFetching && data === undefined; - - const {data: schemaData, isLoading: schemaLoading} = useGetSchemaQuery({path, database}); - + const [autoRefreshInterval] = useAutoRefreshInterval(); + const {currentData, isLoading: schemaLoading} = overviewApi.useGetOverviewQuery( + { + paths: [path], + database, + }, + { + pollingInterval: autoRefreshInterval, + }, + ); + const {data: schemaData} = currentData ?? {}; const keyColumnsIds = schemaData?.PathDescription?.Table?.KeyColumnNames; const tableColumns = React.useMemo(() => { diff --git a/src/containers/Tenant/Diagnostics/Overview/Overview.tsx b/src/containers/Tenant/Diagnostics/Overview/Overview.tsx index 857ea6747e..b4aaf55a96 100644 --- a/src/containers/Tenant/Diagnostics/Overview/Overview.tsx +++ b/src/containers/Tenant/Diagnostics/Overview/Overview.tsx @@ -7,10 +7,7 @@ import {ResponseError} from '../../../../components/Errors/ResponseError'; import {TableIndexInfo} from '../../../../components/InfoViewer/schemaInfo'; import {Loader} from '../../../../components/Loader'; import {overviewApi} from '../../../../store/reducers/overview/overview'; -import { - selectSchemaMergedChildrenPaths, - useGetSchemaQuery, -} from '../../../../store/reducers/schema/schema'; +import {selectSchemaMergedChildrenPaths} from '../../../../store/reducers/schema/schema'; import {EPathType} from '../../../../types/api/schema'; import {useAutoRefreshInterval, useTypedSelector} from '../../../../utils/hooks'; import {ExternalDataSourceInfo} from '../../Info/ExternalDataSource/ExternalDataSource'; @@ -57,8 +54,6 @@ function Overview({type, path, database}: OverviewProps) { const overviewLoading = isFetching && currentData === undefined; const {data: rawData, additionalData} = currentData || {}; - const {error: schemaError} = useGetSchemaQuery({path, database}); - const entityLoading = overviewLoading; const entityNotReady = isEntityWithMergedImpl && !mergedChildrenPaths; @@ -101,7 +96,6 @@ function Overview({type, path, database}: OverviewProps) { return ( - {schemaError ? : null} {overviewError ? : null} {overviewError && !rawData ? null : renderContent()} diff --git a/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx b/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx index de2032bbe9..b2f73c7294 100644 --- a/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx +++ b/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx @@ -1,7 +1,7 @@ import {Loader} from '@gravity-ui/uikit'; import {EntityStatus} from '../../../../components/EntityStatus/EntityStatus'; -import {useGetSchemaQuery} from '../../../../store/reducers/schema/schema'; +import {overviewApi} from '../../../../store/reducers/overview/overview'; import {TENANT_METRICS_TABS_IDS} from '../../../../store/reducers/tenant/constants'; import {tenantApi} from '../../../../store/reducers/tenant/tenant'; import {calculateTenantMetrics} from '../../../../store/reducers/tenants/utils'; @@ -44,9 +44,17 @@ export function TenantOverview({ const {Name, Type, Overall} = tenant || {}; const tenantType = mapDatabaseTypeToDBName(Type); - // FIXME: remove after correct data is added to tenantInfo - const {data: tenantSchemaData} = useGetSchemaQuery({path: tenantName, database: tenantName}); + const {currentData} = overviewApi.useGetOverviewQuery( + { + paths: [tenantName], + database: tenantName, + }, + { + pollingInterval: autoRefreshInterval, + }, + ); + const {data: tenantSchemaData} = currentData ?? {}; const {Tables, Topics} = tenantSchemaData?.PathDescription?.DomainDescription?.DiskSpaceUsage || {}; diff --git a/src/containers/Tenant/ObjectSummary/ObjectSummary.tsx b/src/containers/Tenant/ObjectSummary/ObjectSummary.tsx index 9f6fe3a491..09d709532a 100644 --- a/src/containers/Tenant/ObjectSummary/ObjectSummary.tsx +++ b/src/containers/Tenant/ObjectSummary/ObjectSummary.tsx @@ -14,7 +14,7 @@ import type {InfoViewerItem} from '../../../components/InfoViewer/InfoViewer'; import {LinkWithIcon} from '../../../components/LinkWithIcon/LinkWithIcon'; import SplitPane from '../../../components/SplitPane'; import routes, {createExternalUILink, createHref} from '../../../routes'; -import {useGetSchemaQuery} from '../../../store/reducers/schema/schema'; +import {overviewApi} from '../../../store/reducers/overview/overview'; import {TENANT_SUMMARY_TABS_IDS} from '../../../store/reducers/tenant/constants'; import {setSummaryTab} from '../../../store/reducers/tenant/tenant'; import {EPathSubType, EPathType} from '../../../types/api/schema'; @@ -27,7 +27,7 @@ import { formatNumber, formatSecondsToHours, } from '../../../utils/dataFormatters/dataFormatters'; -import {useTypedDispatch, useTypedSelector} from '../../../utils/hooks'; +import {useAutoRefreshInterval, useTypedDispatch, useTypedSelector} from '../../../utils/hooks'; import {Acl} from '../Acl/Acl'; import {EntityTitle} from '../EntityTitle/EntityTitle'; import {SchemaViewer} from '../Schema/SchemaViewer/SchemaViewer'; @@ -77,6 +77,7 @@ export function ObjectSummary({ onExpandSummary, isCollapsed, }: ObjectSummaryProps) { + const [autoRefreshInterval] = useAutoRefreshInterval(); const dispatch = useTypedDispatch(); const [, setCurrentPath] = useQueryParam('schema', StringParam); const [commonInfoVisibilityState, dispatchCommonInfoVisibilityState] = React.useReducer( @@ -94,7 +95,16 @@ export function ObjectSummary({ ignoreQueryPrefix: true, }); - const {data: currentObjectData} = useGetSchemaQuery({path, database: tenantName}); + const {currentData} = overviewApi.useGetOverviewQuery( + { + paths: [path], + database: tenantName, + }, + { + pollingInterval: autoRefreshInterval, + }, + ); + const {data: currentObjectData} = currentData ?? {}; const currentSchemaData = currentObjectData?.PathDescription?.Self; React.useEffect(() => { diff --git a/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx b/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx index 6691d86117..794d0af5ad 100644 --- a/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx +++ b/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx @@ -4,10 +4,11 @@ import {skipToken} from '@reduxjs/toolkit/query'; import {ResizeableDataTable} from '../../../../components/ResizeableDataTable/ResizeableDataTable'; import {TableSkeleton} from '../../../../components/TableSkeleton/TableSkeleton'; -import {useGetSchemaQuery} from '../../../../store/reducers/schema/schema'; +import {overviewApi} from '../../../../store/reducers/overview/overview'; import {viewSchemaApi} from '../../../../store/reducers/viewSchema/viewSchema'; import type {EPathType} from '../../../../types/api/schema'; import {DEFAULT_TABLE_SETTINGS} from '../../../../utils/constants'; +import {useAutoRefreshInterval} from '../../../../utils/hooks'; import { isColumnEntityType, isExternalTableType, @@ -36,7 +37,18 @@ interface SchemaViewerProps { } export const SchemaViewer = ({type, path, tenantName, extended = false}: SchemaViewerProps) => { - const {data: schemaData, isLoading: loading} = useGetSchemaQuery({path, database: tenantName}); + const [autoRefreshInterval] = useAutoRefreshInterval(); + const {currentData, isLoading: loading} = overviewApi.useGetOverviewQuery( + { + paths: [path], + database: tenantName, + }, + { + pollingInterval: autoRefreshInterval, + }, + ); + + const {data: schemaData} = currentData ?? {}; const viewSchemaRequestParams = isViewType(type) ? {path, database: tenantName} : skipToken; diff --git a/src/containers/Tenant/Schema/SchemaViewer/prepareData.ts b/src/containers/Tenant/Schema/SchemaViewer/prepareData.ts index 128313ac68..97a43dacee 100644 --- a/src/containers/Tenant/Schema/SchemaViewer/prepareData.ts +++ b/src/containers/Tenant/Schema/SchemaViewer/prepareData.ts @@ -8,6 +8,7 @@ import type { TTableDescription, } from '../../../../types/api/schema'; import {EColumnCodec} from '../../../../types/api/schema'; +import type {Nullable} from '../../../../utils/typecheckers'; import {isColumnEntityType, isExternalTableType, isRowTableType} from '../../utils/schema'; import type {SchemaData} from './types'; @@ -123,7 +124,7 @@ function prepareColumnTableSchema(data: TColumnTableDescription = {}): SchemaDat export function prepareSchemaData( type?: EPathType, - schema?: TEvDescribeSchemeResult, + schema?: Nullable, ): SchemaData[] { const {Table, ColumnTableDescription, ExternalTableDescription} = schema?.PathDescription || {}; diff --git a/src/containers/Tenant/Tenant.tsx b/src/containers/Tenant/Tenant.tsx index 217f7939a0..c346a300bb 100644 --- a/src/containers/Tenant/Tenant.tsx +++ b/src/containers/Tenant/Tenant.tsx @@ -7,11 +7,11 @@ import {PageError, isAccessError} from '../../components/Errors/PageError/PageEr import {LoaderWrapper} from '../../components/LoaderWrapper/LoaderWrapper'; import SplitPane from '../../components/SplitPane'; import {setHeaderBreadcrumbs} from '../../store/reducers/header/header'; -import {useGetSchemaQuery} from '../../store/reducers/schema/schema'; +import {overviewApi} from '../../store/reducers/overview/overview'; import type {AdditionalNodesProps, AdditionalTenantsProps} from '../../types/additionalProps'; import {cn} from '../../utils/cn'; import {DEFAULT_IS_TENANT_SUMMARY_COLLAPSED, DEFAULT_SIZE_TENANT_KEY} from '../../utils/constants'; -import {useTypedDispatch} from '../../utils/hooks'; +import {useAutoRefreshInterval, useTypedDispatch} from '../../utils/hooks'; import ObjectGeneral from './ObjectGeneral/ObjectGeneral'; import {ObjectSummary} from './ObjectSummary/ObjectSummary'; @@ -41,6 +41,7 @@ interface TenantProps { } export function Tenant(props: TenantProps) { + const [autoRefreshInterval] = useAutoRefreshInterval(); const [summaryVisibilityState, dispatchSummaryVisibilityAction] = React.useReducer( paneVisibilityToggleReducerCreator(DEFAULT_IS_TENANT_SUMMARY_COLLAPSED), undefined, @@ -74,7 +75,13 @@ export function Tenant(props: TenantProps) { const path = schema ?? tenantName; - const {data: currentItem, error, isLoading} = useGetSchemaQuery({path, database: tenantName}); + const {currentData, error, isLoading} = overviewApi.useGetOverviewQuery( + {paths: [path], database: tenantName}, + { + pollingInterval: autoRefreshInterval, + }, + ); + const {data: currentItem} = currentData ?? {}; const {PathType: currentPathType, PathSubType: currentPathSubType} = currentItem?.PathDescription?.Self || {}; diff --git a/src/services/api.ts b/src/services/api.ts index 6b18ec3044..1a2ec82f16 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -365,9 +365,9 @@ export class YdbEmbeddedAPI extends AxiosWrapper { enums: true, backup: false, private: true, - partition_config: true, - partition_stats: true, - partitioning_info: true, + partition_config: false, + partition_stats: false, + partitioning_info: false, subs: 1, }, {concurrentId, requestConfig: {signal}}, diff --git a/src/store/reducers/describe.ts b/src/store/reducers/describe.ts deleted file mode 100644 index 135391c3a2..0000000000 --- a/src/store/reducers/describe.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type {IDescribeData} from '../../types/store/describe'; - -import {api} from './api'; - -export const describeApi = api.injectEndpoints({ - endpoints: (build) => ({ - getDescribe: build.query({ - queryFn: async ({paths, database}: {paths: string[]; database: string}, {signal}) => { - try { - const response = await Promise.all( - paths.map((p) => window.api.getDescribe({path: p, database}, {signal})), - ); - const data = response.reduce((acc, item) => { - if (item?.Path) { - acc[item.Path] = item; - } - return acc; - }, {}); - return {data}; - } catch (error) { - return {error}; - } - }, - providesTags: ['All'], - }), - }), - overrideExisting: 'throw', -}); diff --git a/src/store/reducers/overview/overview.ts b/src/store/reducers/overview/overview.ts index 60e7ed7c8e..070e1b175e 100644 --- a/src/store/reducers/overview/overview.ts +++ b/src/store/reducers/overview/overview.ts @@ -6,13 +6,22 @@ export const overviewApi = api.injectEndpoints({ queryFn: async ({paths, database}: {paths: string[]; database: string}, {signal}) => { try { const [data, ...additionalData] = await Promise.all( - paths.map((p) => window.api.getDescribe({path: p, database}, {signal})), + paths.map((p) => + window.api.getDescribe( + { + path: p, + database, + }, + {signal}, + ), + ), ); return {data: {data, additionalData}}; } catch (error) { return {error}; } }, + keepUnusedDataFor: 0, providesTags: ['All'], }), }),