: null}
- {preparedDescribeData ? (
+ {currentData ? (
}
search
diff --git a/src/containers/Tenant/Diagnostics/Diagnostics.tsx b/src/containers/Tenant/Diagnostics/Diagnostics.tsx
index 18f5dbfb2a..71667817bf 100644
--- a/src/containers/Tenant/Diagnostics/Diagnostics.tsx
+++ b/src/containers/Tenant/Diagnostics/Diagnostics.tsx
@@ -13,7 +13,7 @@ import {
import {TENANT_DIAGNOSTICS_TABS_IDS} from '../../../store/reducers/tenant/constants';
import {setDiagnosticsTab} from '../../../store/reducers/tenant/tenant';
import type {AdditionalNodesProps, AdditionalTenantsProps} from '../../../types/additionalProps';
-import type {EPathType} from '../../../types/api/schema';
+import type {EPathSubType, EPathType} from '../../../types/api/schema';
import {cn} from '../../../utils/cn';
import {useTypedDispatch, useTypedSelector} from '../../../utils/hooks';
import {Heatmap} from '../../Heatmap';
@@ -40,6 +40,7 @@ import './Diagnostics.scss';
interface DiagnosticsProps {
type?: EPathType;
+ subType?: EPathSubType;
tenantName: string;
path: string;
additionalTenantProps?: AdditionalTenantsProps;
@@ -62,7 +63,7 @@ function Diagnostics(props: DiagnosticsProps) {
const hasFeatureFlags = useFeatureFlagsAvailable();
const hasTopicData = useTopicDataAvailable();
- const pages = getPagesByType(props.type, {
+ const pages = getPagesByType(props.type, props.subType, {
hasFeatureFlags,
hasTopicData,
isTopLevel: props.path === props.tenantName,
@@ -129,7 +130,7 @@ function Diagnostics(props: DiagnosticsProps) {
);
}
case TENANT_DIAGNOSTICS_TABS_IDS.describe: {
- return
;
+ return
;
}
case TENANT_DIAGNOSTICS_TABS_IDS.hotKeys: {
return
;
diff --git a/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts b/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts
index e58181d776..64ea644caa 100644
--- a/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts
+++ b/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts
@@ -4,7 +4,7 @@ import {StringParam, useQueryParams} from 'use-query-params';
import {TENANT_DIAGNOSTICS_TABS_IDS} from '../../../store/reducers/tenant/constants';
import type {TenantDiagnosticsTab} from '../../../store/reducers/tenant/types';
-import {EPathType} from '../../../types/api/schema';
+import {EPathSubType, EPathType} from '../../../types/api/schema';
import type {TenantQuery} from '../TenantPages';
import {TenantTabsGroups, getTenantPath} from '../TenantPages';
import {isDatabaseEntityType, isTopicEntityType} from '../utils/schema';
@@ -113,7 +113,8 @@ const COLUMN_TABLE_PAGES = [overview, schema, topShards, nodes, tablets, describ
const DIR_PAGES = [overview, topShards, nodes, describe];
-const CDC_STREAM_PAGES = [overview, consumers, partitions, nodes, tablets, describe];
+const CDC_STREAM_PAGES = [overview, consumers, partitions, nodes, describe];
+const CDC_STREAM_IMPL_PAGES = [overview, nodes, tablets, describe];
const TOPIC_PAGES = [overview, consumers, partitions, topicData, nodes, tablets, describe];
const EXTERNAL_DATA_SOURCE_PAGES = [overview, describe];
@@ -149,15 +150,23 @@ const pathTypeToPages: Record
= {
[EPathType.EPathTypeTransfer]: TRANSFER_PAGES,
[EPathType.EPathTypeResourcePool]: DIR_PAGES,
};
+const pathSubTypeToPages: Record = {
+ [EPathSubType.EPathSubTypeStreamImpl]: CDC_STREAM_IMPL_PAGES,
+
+ [EPathSubType.EPathSubTypeSyncIndexImplTable]: undefined,
+ [EPathSubType.EPathSubTypeAsyncIndexImplTable]: undefined,
+ [EPathSubType.EPathSubTypeEmpty]: undefined,
+};
export const getPagesByType = (
type?: EPathType,
+ subType?: EPathSubType,
options?: {hasFeatureFlags?: boolean; hasTopicData?: boolean; isTopLevel?: boolean},
) => {
- if (!type || !pathTypeToPages[type]) {
- return DIR_PAGES;
- }
- let pages = pathTypeToPages[type];
+ const subTypePages = subType ? pathSubTypeToPages[subType] : undefined;
+ const typePages = type ? pathTypeToPages[type] : undefined;
+ let pages = subTypePages || typePages || DIR_PAGES;
+
if (isTopicEntityType(type) && !options?.hasTopicData) {
return pages?.filter((item) => item.id !== TENANT_DIAGNOSTICS_TABS_IDS.topicData);
}
diff --git a/src/containers/Tenant/Diagnostics/Overview/ChangefeedInfo/ChangefeedInfo.tsx b/src/containers/Tenant/Diagnostics/Overview/ChangefeedInfo/ChangefeedInfo.tsx
index 18104e061e..d4d984ec4a 100644
--- a/src/containers/Tenant/Diagnostics/Overview/ChangefeedInfo/ChangefeedInfo.tsx
+++ b/src/containers/Tenant/Diagnostics/Overview/ChangefeedInfo/ChangefeedInfo.tsx
@@ -7,13 +7,9 @@ import {
import type {TEvDescribeSchemeResult} from '../../../../../types/api/schema';
import {getEntityName} from '../../../utils';
import {TopicStats} from '../TopicStats';
-import {prepareTopicSchemaInfo} from '../utils';
-const prepareChangefeedInfo = (
- changefeedData?: TEvDescribeSchemeResult,
- topicData?: TEvDescribeSchemeResult,
-): Array => {
- if (!changefeedData && !topicData) {
+const prepareChangefeedInfo = (changefeedData?: TEvDescribeSchemeResult): Array => {
+ if (!changefeedData) {
return [];
}
@@ -25,17 +21,14 @@ const prepareChangefeedInfo = (
Mode,
Format,
});
- const topicInfo = prepareTopicSchemaInfo(topicData);
-
- const info = [...changefeedInfo, ...topicInfo];
const createStep = changefeedData?.PathDescription?.Self?.CreateStep;
if (Number(createStep)) {
- info.unshift(formatCommonItem('CreateStep', createStep));
+ changefeedInfo.unshift(formatCommonItem('CreateStep', createStep));
}
- return info;
+ return changefeedInfo;
};
interface ChangefeedProps {
@@ -46,16 +39,16 @@ interface ChangefeedProps {
}
/** Displays overview for CDCStream EPathType */
-export const ChangefeedInfo = ({path, database, data, topic}: ChangefeedProps) => {
+export const ChangefeedInfo = ({path, database, data}: ChangefeedProps) => {
const entityName = getEntityName(data?.PathDescription);
- if (!data || !topic) {
+ if (!data) {
return No {entityName} data
;
}
return (
-
+
);
diff --git a/src/containers/Tenant/Diagnostics/Overview/Overview.tsx b/src/containers/Tenant/Diagnostics/Overview/Overview.tsx
index 6e67378901..57c6169762 100644
--- a/src/containers/Tenant/Diagnostics/Overview/Overview.tsx
+++ b/src/containers/Tenant/Diagnostics/Overview/Overview.tsx
@@ -1,20 +1,14 @@
import React from 'react';
-import {shallowEqual} from 'react-redux';
-
import {ResponseError} from '../../../../components/Errors/ResponseError';
import {TableIndexInfo} from '../../../../components/InfoViewer/schemaInfo';
import {Loader} from '../../../../components/Loader';
-import {
- selectSchemaMergedChildrenPaths,
- useGetMultiOverviewQuery,
-} from '../../../../store/reducers/overview/overview';
+import {overviewApi} from '../../../../store/reducers/overview/overview';
import {EPathType} from '../../../../types/api/schema';
-import {useAutoRefreshInterval, useTypedSelector} from '../../../../utils/hooks';
+import {useAutoRefreshInterval} from '../../../../utils/hooks';
import {ExternalDataSourceInfo} from '../../Info/ExternalDataSource/ExternalDataSource';
import {ExternalTableInfo} from '../../Info/ExternalTable/ExternalTable';
import {ViewInfo} from '../../Info/View/View';
-import {isEntityWithMergedImplementation} from '../../utils/schema';
import {AsyncReplicationInfo} from './AsyncReplicationInfo';
import {ChangefeedInfo} from './ChangefeedInfo';
@@ -31,37 +25,15 @@ interface OverviewProps {
function Overview({type, path, database}: OverviewProps) {
const [autoRefreshInterval] = useAutoRefreshInterval();
- const isEntityWithMergedImpl = isEntityWithMergedImplementation(type);
-
- // shallowEqual prevents rerenders when new schema data is loaded
- const mergedChildrenPaths = useTypedSelector(
- (state) => selectSchemaMergedChildrenPaths(state, path, type, database),
- shallowEqual,
+ const {currentData, isFetching, error} = overviewApi.useGetOverviewQuery(
+ {path, database},
+ {pollingInterval: autoRefreshInterval},
);
- let paths: string[] = [];
- if (!isEntityWithMergedImpl) {
- paths = [path];
- } else if (mergedChildrenPaths) {
- paths = [path, ...mergedChildrenPaths];
- }
-
- const {
- mergedDescribe,
- loading: entityLoading,
- error,
- } = useGetMultiOverviewQuery({
- paths,
- database,
- autoRefreshInterval,
- });
-
- const rawData = mergedDescribe[path];
-
- const entityNotReady = isEntityWithMergedImpl && !mergedChildrenPaths;
+ const loading = isFetching && currentData === undefined;
const renderContent = () => {
- const data = rawData ?? undefined;
+ const data = currentData ?? undefined;
// verbose mapping to guarantee a correct render for new path types
// TS will error when a new type is added but not mapped here
const pathTypeToComponent: Record React.ReactNode) | undefined> = {
@@ -74,20 +46,9 @@ function Overview({type, path, database}: OverviewProps) {
[EPathType.EPathTypeExtSubDomain]: undefined,
[EPathType.EPathTypeColumnStore]: undefined,
[EPathType.EPathTypeColumnTable]: undefined,
- [EPathType.EPathTypeCdcStream]: () => {
- const topicPath = mergedChildrenPaths?.[0];
- if (topicPath) {
- return (
-
- );
- }
- return undefined;
- },
+ [EPathType.EPathTypeCdcStream]: () => (
+
+ ),
[EPathType.EPathTypePersQueueGroup]: () => (
),
@@ -103,14 +64,14 @@ function Overview({type, path, database}: OverviewProps) {
return (type && pathTypeToComponent[type]?.()) || ;
};
- if (entityLoading || entityNotReady) {
+ if (loading) {
return ;
}
return (
{error ? : null}
- {error && !rawData ? null : renderContent()}
+ {error && !currentData ? null : renderContent()}
);
}
diff --git a/src/containers/Tenant/Diagnostics/Overview/TopicInfo/TopicInfo.tsx b/src/containers/Tenant/Diagnostics/Overview/TopicInfo/TopicInfo.tsx
index ac4a82ef5c..314ca4f606 100644
--- a/src/containers/Tenant/Diagnostics/Overview/TopicInfo/TopicInfo.tsx
+++ b/src/containers/Tenant/Diagnostics/Overview/TopicInfo/TopicInfo.tsx
@@ -1,4 +1,5 @@
import {InfoViewer} from '../../../../../components/InfoViewer';
+import {EPathSubType} from '../../../../../types/api/schema';
import type {TEvDescribeSchemeResult} from '../../../../../types/api/schema';
import {getEntityName} from '../../../utils';
import {TopicStats} from '../TopicStats';
@@ -18,10 +19,19 @@ export const TopicInfo = ({data, path, database}: TopicInfoProps) => {
return No {entityName} data
;
}
+ const renderStats = () => {
+ // In case of stream impl we display stats in CDC info tab instead
+ if (data.PathDescription?.Self?.PathSubType === EPathSubType.EPathSubTypeStreamImpl) {
+ return null;
+ }
+
+ return ;
+ };
+
return (
-
+ {renderStats()}
);
};
diff --git a/src/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx b/src/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx
index ed8a6e15b2..6bde55a1db 100644
--- a/src/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx
+++ b/src/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx
@@ -2,7 +2,7 @@ import {useThemeValue} from '@gravity-ui/uikit';
import {TENANT_PAGES_IDS} from '../../../store/reducers/tenant/constants';
import type {AdditionalNodesProps, AdditionalTenantsProps} from '../../../types/additionalProps';
-import type {EPathType} from '../../../types/api/schema';
+import type {EPathSubType, EPathType} from '../../../types/api/schema';
import {cn} from '../../../utils/cn';
import {useTypedSelector} from '../../../utils/hooks';
import Diagnostics from '../Diagnostics/Diagnostics';
@@ -15,6 +15,7 @@ const b = cn('object-general');
interface ObjectGeneralProps {
type?: EPathType;
+ subType?: EPathSubType;
tenantName: string;
path: string;
additionalTenantProps?: AdditionalTenantsProps;
@@ -27,7 +28,8 @@ function ObjectGeneral(props: ObjectGeneralProps) {
const {tenantPage} = useTypedSelector((state) => state.tenant);
const renderPageContent = () => {
- const {type, additionalTenantProps, additionalNodesProps, tenantName, path} = props;
+ const {type, subType, additionalTenantProps, additionalNodesProps, tenantName, path} =
+ props;
switch (tenantPage) {
case TENANT_PAGES_IDS.query: {
return ;
@@ -36,6 +38,7 @@ function ObjectGeneral(props: ObjectGeneralProps) {
return (
type === EPathType.EPathT
// ====================
-const pathTypeToEntityWithMergedImplementation: Record = {
- [EPathType.EPathTypeCdcStream]: true,
-
- [EPathType.EPathTypePersQueueGroup]: false,
- [EPathType.EPathTypeInvalid]: false,
- [EPathType.EPathTypeColumnStore]: false,
- [EPathType.EPathTypeColumnTable]: false,
- [EPathType.EPathTypeDir]: false,
- [EPathType.EPathTypeTable]: false,
- [EPathType.EPathTypeSubDomain]: false,
- [EPathType.EPathTypeTableIndex]: false,
- [EPathType.EPathTypeExtSubDomain]: false,
-
- [EPathType.EPathTypeExternalDataSource]: false,
- [EPathType.EPathTypeExternalTable]: false,
-
- [EPathType.EPathTypeView]: false,
-
- [EPathType.EPathTypeReplication]: false,
- [EPathType.EPathTypeTransfer]: false,
- [EPathType.EPathTypeResourcePool]: false,
-};
-
-export const isEntityWithMergedImplementation = (type?: EPathType) =>
- (type && pathTypeToEntityWithMergedImplementation[type]) ?? false;
-
-// ====================
-
const pathSubTypeToChildless: Record = {
[EPathSubType.EPathSubTypeSyncIndexImplTable]: true,
[EPathSubType.EPathSubTypeAsyncIndexImplTable]: true,
+ [EPathSubType.EPathSubTypeStreamImpl]: true,
- [EPathSubType.EPathSubTypeStreamImpl]: false,
[EPathSubType.EPathSubTypeEmpty]: false,
};
const pathTypeToChildless: Record = {
- [EPathType.EPathTypeCdcStream]: true,
+ [EPathType.EPathTypeCdcStream]: false,
[EPathType.EPathTypePersQueueGroup]: true,
[EPathType.EPathTypeExternalDataSource]: true,
diff --git a/src/store/reducers/overview/overview.ts b/src/store/reducers/overview/overview.ts
index 9c1676c432..2beb11b2f5 100644
--- a/src/store/reducers/overview/overview.ts
+++ b/src/store/reducers/overview/overview.ts
@@ -1,36 +1,7 @@
-import {createSelector} from '@reduxjs/toolkit';
-import {skipToken} from '@reduxjs/toolkit/query';
-
-import {isEntityWithMergedImplementation} from '../../../containers/Tenant/utils/schema';
-import type {EPathType} from '../../../types/api/schema';
-import type {IDescribeData} from '../../../types/store/describe';
-import type {RootState} from '../../defaultStore';
import {api} from '../api';
export const overviewApi = api.injectEndpoints({
endpoints: (build) => ({
- getMultiOverview: build.query({
- queryFn: async ({paths, database}: {paths: string[]; database: string}, {signal}) => {
- try {
- const data = await Promise.all(
- paths.map((p) =>
- window.api.viewer.getDescribe(
- {
- path: p,
- database,
- },
- {signal},
- ),
- ),
- );
- return {data};
- } catch (error) {
- return {error};
- }
- },
- keepUnusedDataFor: 0,
- providesTags: ['All'],
- }),
getOverview: build.query({
queryFn: async (
{path, database, timeout}: {path: string; database: string; timeout?: number},
@@ -59,86 +30,3 @@ export const overviewApi = api.injectEndpoints({
}),
}),
});
-
-const getOverviewSelector = createSelector(
- (path: string) => path,
- (_path: string, database: string) => database,
- (path, database) => overviewApi.endpoints.getOverview.select({path, database}),
-);
-
-const selectGetOverview = createSelector(
- (state: RootState) => state,
- (_state: RootState, path: string, database: string) => getOverviewSelector(path, database),
- (state, selectOverview) => selectOverview(state).data,
-);
-
-const selectOverviewChildren = (state: RootState, path: string, database: string) =>
- selectGetOverview(state, path, database)?.PathDescription?.Children;
-
-export const selectSchemaMergedChildrenPaths = createSelector(
- [
- (_, path: string) => path,
- (_, _path, type: EPathType | undefined) => type,
- (state, path, _type, database: string) => selectOverviewChildren(state, path, database),
- ],
- (path, type, children) => {
- return isEntityWithMergedImplementation(type)
- ? children?.map(({Name}) => path + '/' + Name)
- : undefined;
- },
-);
-
-//this hook is done not to refetch mainPath describe for entities with merged implementation
-export function useGetMultiOverviewQuery({
- paths,
- database,
- autoRefreshInterval,
-}: {
- paths: string[];
- database: string;
- autoRefreshInterval?: number;
-}) {
- const [mainPath, ...additionalPaths] = paths;
-
- const {
- currentData: mainDescribe,
- isFetching: mainDescribeIsFetching,
- error: mainDescribeError,
- } = overviewApi.useGetOverviewQuery(
- {
- path: mainPath,
- database,
- },
- {
- pollingInterval: autoRefreshInterval,
- },
- );
-
- const {
- currentData: currentChindrenDescribe,
- isFetching: childrenDescribeIsFetching,
- error: childrenDescribeError,
- } = overviewApi.useGetMultiOverviewQuery(
- additionalPaths.length ? {paths: additionalPaths, database} : skipToken,
- {
- pollingInterval: autoRefreshInterval,
- },
- );
-
- const childrenDescribeLoading =
- childrenDescribeIsFetching && currentChindrenDescribe === undefined;
- const mainDescribeLoading = mainDescribeIsFetching && mainDescribe === undefined;
-
- const loading = mainDescribeLoading || childrenDescribeLoading;
-
- const describe = [mainDescribe, ...(currentChindrenDescribe ?? [])];
-
- const mergedDescribe = describe.reduce((acc, item) => {
- if (item?.Path) {
- acc[item.Path] = item;
- }
- return acc;
- }, {});
-
- return {loading, error: mainDescribeError || childrenDescribeError, mergedDescribe};
-}