Skip to content

Commit f80c381

Browse files
committed
fix(Tenant): ensure correct behavior for new schema node types
1 parent 6aa326f commit f80c381

File tree

5 files changed

+162
-94
lines changed

5 files changed

+162
-94
lines changed

src/containers/Tenant/Diagnostics/DiagnosticsPages.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ export enum GeneralPagesIds {
1313
'graph' = 'graph',
1414
}
1515

16+
type Page = {
17+
id: GeneralPagesIds,
18+
title: string,
19+
};
20+
1621
const overview = {
1722
id: GeneralPagesIds.overview,
1823
title: 'Overview',
@@ -76,17 +81,22 @@ export const TABLE_PAGES = [overview, topShards, graph, tablets, hotKeys, descri
7681

7782
export const DIR_PAGES = [overview, topShards, describe];
7883

79-
export const getPagesByType = (type?: EPathType) => {
80-
switch (type) {
81-
case EPathType.EPathTypeColumnStore:
82-
case EPathType.EPathTypeSubDomain:
83-
return DATABASE_PAGES;
84-
case EPathType.EPathTypeColumnTable:
85-
case EPathType.EPathTypeTable:
86-
return TABLE_PAGES;
87-
case EPathType.EPathTypeDir:
88-
case EPathType.EPathTypeTableIndex:
89-
default:
90-
return DIR_PAGES;
91-
}
92-
}
84+
// verbose mapping to guarantee correct tabs for new path types
85+
// TS will error when a new type is added but not mapped here
86+
const pathTypeToPages: Record<EPathType, Page[] | undefined> = {
87+
[EPathType.EPathTypeInvalid]: undefined,
88+
89+
[EPathType.EPathTypeSubDomain]: DATABASE_PAGES,
90+
[EPathType.EPathTypeExtSubDomain]: DATABASE_PAGES,
91+
[EPathType.EPathTypeColumnStore]: DATABASE_PAGES,
92+
93+
[EPathType.EPathTypeTable]: TABLE_PAGES,
94+
[EPathType.EPathTypeColumnTable]: TABLE_PAGES,
95+
96+
[EPathType.EPathTypeDir]: DIR_PAGES,
97+
[EPathType.EPathTypeTableIndex]: DIR_PAGES,
98+
[EPathType.EPathTypeCdcStream]: DIR_PAGES,
99+
};
100+
101+
export const getPagesByType = (type?: EPathType) =>
102+
(type && pathTypeToPages[type]) || DIR_PAGES;

src/containers/Tenant/Diagnostics/HotKeys/HotKeys.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import Icon from '../../../../components/Icon/Icon';
88

99
import {AutoFetcher} from '../../../../utils/autofetcher';
1010
import {getHotKeys, setHotKeysOptions} from '../../../../store/reducers/hotKeys';
11-
import {EPathType} from '../../../../types/api/schema';
1211
import {prepareQueryError} from '../../../../utils';
1312

13+
import {isColumnEntityType, isTableType} from '../../utils/schema';
14+
1415
import './HotKeys.scss';
1516

1617
const b = cn('hot-keys');
@@ -42,8 +43,7 @@ function HotKeys({
4243
type,
4344
}) {
4445
const fetchData = () => {
45-
// ColumnTables excluded intentionally
46-
if (type === EPathType.EPathTypeTable) {
46+
if (isTableType(type) && !isColumnEntityType(type)) {
4747
getHotKeys(currentSchemaPath);
4848
}
4949
};

src/containers/Tenant/Diagnostics/Overview/Overview.tsx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {useEffect, useMemo} from 'react';
1+
import {ReactNode, useEffect, useMemo} from 'react';
22
import {useDispatch, useSelector} from 'react-redux';
33
import cn from 'bem-cn-lite';
44

@@ -8,8 +8,8 @@ import {Loader} from '@yandex-cloud/uikit';
88
import SchemaInfoViewer from '../../Schema/SchemaInfoViewer/SchemaInfoViewer';
99
import {IndexInfoViewer} from '../../../../components/IndexInfoViewer/IndexInfoViewer';
1010

11-
import type {EPathType} from '../../../../types/api/schema';
12-
import {isColumnEntityType, isTableType, mapPathTypeToNavigationTreeType} from '../../utils/schema';
11+
import {EPathType} from '../../../../types/api/schema';
12+
import {isColumnEntityType, isTableType} from '../../utils/schema';
1313
import {AutoFetcher} from '../../../../utils/autofetcher';
1414
//@ts-ignore
1515
import {getSchema} from '../../../../store/reducers/schema';
@@ -114,16 +114,23 @@ function Overview(props: OverviewProps) {
114114
};
115115

116116
const renderContent = () => {
117-
switch (mapPathTypeToNavigationTreeType(props.type)) {
118-
case 'index':
119-
return (
120-
<IndexInfoViewer data={schemaData} />
121-
);
122-
default:
123-
return (
124-
<SchemaInfoViewer fullPath={currentItem.Path} data={schemaData} />
125-
);
126-
}
117+
// verbose mapping to guarantee a correct render for new path types
118+
// TS will error when a new type is added but not mapped here
119+
const pathTypeToComponent: Record<EPathType, (() => ReactNode) | undefined> = {
120+
[EPathType.EPathTypeInvalid]: undefined,
121+
[EPathType.EPathTypeDir]: undefined,
122+
[EPathType.EPathTypeTable]: undefined,
123+
[EPathType.EPathTypeSubDomain]: undefined,
124+
[EPathType.EPathTypeTableIndex]: () => <IndexInfoViewer data={schemaData} />,
125+
[EPathType.EPathTypeExtSubDomain]: undefined,
126+
[EPathType.EPathTypeColumnStore]: undefined,
127+
[EPathType.EPathTypeColumnTable]: undefined,
128+
[EPathType.EPathTypeCdcStream]: undefined,
129+
};
130+
131+
return (props.type && pathTypeToComponent[props.type]?.()) || (
132+
<SchemaInfoViewer fullPath={currentItem.Path} data={schemaData} />
133+
);
127134
}
128135

129136
return loading && !wasLoaded ? (
Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,88 @@
11
import type {NavigationTreeNodeType} from 'ydb-ui-components';
22
import {EPathSubType, EPathType} from '../../../types/api/schema';
33

4-
const mapTablePathSubTypeToNavigationTreeType = (subType?: EPathSubType) => {
5-
switch (subType) {
6-
case EPathSubType.EPathSubTypeSyncIndexImplTable:
7-
case EPathSubType.EPathSubTypeAsyncIndexImplTable:
8-
return 'index_table';
9-
default:
10-
return 'table';
11-
}
4+
// this file contains verbose mappings that are typed in a way that ensures
5+
// correctness when a new node type or a new path type is added
6+
// TS will error if a new entity is added but not mapped here
7+
8+
const pathSubTypeToNodeType: Record<EPathSubType, NavigationTreeNodeType | undefined> = {
9+
[EPathSubType.EPathSubTypeSyncIndexImplTable]: 'index_table',
10+
[EPathSubType.EPathSubTypeAsyncIndexImplTable]: 'index_table',
11+
12+
[EPathSubType.EPathSubTypeStreamImpl]: undefined,
13+
[EPathSubType.EPathSubTypeEmpty]: undefined,
14+
};
15+
16+
const pathTypeToNodeType: Record<EPathType, NavigationTreeNodeType | undefined> = {
17+
[EPathType.EPathTypeInvalid]: undefined,
18+
19+
[EPathType.EPathTypeSubDomain]: 'database',
20+
[EPathType.EPathTypeExtSubDomain]: 'database',
21+
22+
[EPathType.EPathTypeDir]: 'directory',
23+
[EPathType.EPathTypeColumnStore]: 'directory',
24+
25+
[EPathType.EPathTypeTable]: 'table',
26+
27+
[EPathType.EPathTypeTableIndex]: 'index',
28+
29+
[EPathType.EPathTypeColumnTable]: 'column_table',
30+
31+
[EPathType.EPathTypeCdcStream]: 'topic',
1232
};
1333

1434
export const mapPathTypeToNavigationTreeType = (
1535
type: EPathType = EPathType.EPathTypeDir,
1636
subType?: EPathSubType,
1737
defaultType: NavigationTreeNodeType = 'directory'
18-
): NavigationTreeNodeType => {
19-
switch (type) {
20-
case EPathType.EPathTypeSubDomain:
21-
case EPathType.EPathTypeExtSubDomain:
22-
return 'database';
23-
case EPathType.EPathTypeTable:
24-
return mapTablePathSubTypeToNavigationTreeType(subType);
25-
case EPathType.EPathTypeColumnTable:
26-
return 'column_table';
27-
case EPathType.EPathTypeDir:
28-
case EPathType.EPathTypeColumnStore:
29-
return 'directory';
30-
case EPathType.EPathTypeTableIndex:
31-
return 'index';
32-
case EPathType.EPathTypeCdcStream:
33-
return 'topic';
34-
default:
35-
return defaultType;
36-
}
38+
): NavigationTreeNodeType =>
39+
(subType && pathSubTypeToNodeType[subType]) || pathTypeToNodeType[type] || defaultType;
40+
41+
// ====================
42+
43+
const pathTypeToIsTable: Record<EPathType, boolean> = {
44+
[EPathType.EPathTypeTable]: true,
45+
[EPathType.EPathTypeColumnTable]: true,
46+
47+
[EPathType.EPathTypeInvalid]: false,
48+
[EPathType.EPathTypeDir]: false,
49+
[EPathType.EPathTypeSubDomain]: false,
50+
[EPathType.EPathTypeTableIndex]: false,
51+
[EPathType.EPathTypeExtSubDomain]: false,
52+
[EPathType.EPathTypeColumnStore]: false,
53+
[EPathType.EPathTypeCdcStream]: false,
3754
};
3855

39-
export const isTableType = (type?: EPathType) =>
40-
mapPathTypeToNavigationTreeType(type) === 'table';
56+
export const isTableType = (pathType?: EPathType) =>
57+
(pathType && pathTypeToIsTable[pathType]) ?? false;
58+
59+
// ====================
60+
61+
const pathSubTypeToIsIndexImpl: Record<EPathSubType, boolean> = {
62+
[EPathSubType.EPathSubTypeSyncIndexImplTable]: true,
63+
[EPathSubType.EPathSubTypeAsyncIndexImplTable]: true,
64+
65+
[EPathSubType.EPathSubTypeStreamImpl]: false,
66+
[EPathSubType.EPathSubTypeEmpty]: false,
67+
};
4168

4269
export const isIndexTable = (subType?: EPathSubType) =>
43-
mapTablePathSubTypeToNavigationTreeType(subType) === 'index_table';
70+
(subType && pathSubTypeToIsIndexImpl[subType]) ?? false;
71+
72+
// ====================
73+
74+
const pathTypeToIsColumn: Record<EPathType, boolean> = {
75+
[EPathType.EPathTypeColumnStore]: true,
76+
[EPathType.EPathTypeColumnTable]: true,
77+
78+
[EPathType.EPathTypeInvalid]: false,
79+
[EPathType.EPathTypeDir]: false,
80+
[EPathType.EPathTypeTable]: false,
81+
[EPathType.EPathTypeSubDomain]: false,
82+
[EPathType.EPathTypeTableIndex]: false,
83+
[EPathType.EPathTypeExtSubDomain]: false,
84+
[EPathType.EPathTypeCdcStream]: false,
85+
};
4486

4587
export const isColumnEntityType = (type?: EPathType) =>
46-
type === EPathType.EPathTypeColumnStore ||
47-
type === EPathType.EPathTypeColumnTable;
88+
(type && pathTypeToIsColumn[type]) ?? false;

src/containers/Tenant/utils/schemaActions.ts

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Dispatch} from 'react';
2-
import type {NavigationTreeNodeType} from 'ydb-ui-components';
2+
import type {NavigationTreeNodeType, NavigationTreeProps} from 'ydb-ui-components';
33

44
import {changeUserInput} from '../../../store/reducers/executeQuery';
55
import {setShowPreview} from '../../../store/reducers/schema';
@@ -73,6 +73,8 @@ const bindActions = (
7373
};
7474
};
7575

76+
type ActionsSet = ReturnType<Required<NavigationTreeProps>['getActions']>;
77+
7678
export const getActions = (
7779
dispatch: Dispatch<any>,
7880
setActivePath: (path: string) => void,
@@ -81,35 +83,43 @@ export const getActions = (
8183
const actions = bindActions(path, dispatch, setActivePath);
8284
const copyItem = {text: 'Copy path', action: actions.copyPath};
8385

84-
switch (type) {
85-
case 'database':
86-
case 'directory':
87-
return [
88-
[
89-
copyItem,
90-
],
91-
[
92-
{text: 'Create table...', action: actions.createTable},
93-
],
94-
];
95-
case 'table':
96-
return [
97-
[
98-
{text: 'Open preview', action: actions.openPreview},
99-
copyItem,
100-
],
101-
[
102-
{text: 'Alter table...', action: actions.alterTable},
103-
{text: 'Select query...', action: actions.selectQuery},
104-
{text: 'Upsert query...', action: actions.upsertQuery},
105-
],
106-
];
107-
case 'index_table':
108-
return [
109-
copyItem,
110-
];
111-
case 'index':
112-
default:
113-
return [];
114-
}
86+
const DIR_SET: ActionsSet = [
87+
[
88+
copyItem,
89+
],
90+
[
91+
{text: 'Create table...', action: actions.createTable},
92+
],
93+
];
94+
const TABLE_SET: ActionsSet = [
95+
[
96+
{text: 'Open preview', action: actions.openPreview},
97+
copyItem,
98+
],
99+
[
100+
{text: 'Alter table...', action: actions.alterTable},
101+
{text: 'Select query...', action: actions.selectQuery},
102+
{text: 'Upsert query...', action: actions.upsertQuery},
103+
],
104+
];
105+
106+
const JUST_COPY: ActionsSet = [
107+
copyItem,
108+
];
109+
110+
const EMPTY_SET: ActionsSet = [];
111+
112+
// verbose mapping to guarantee a correct actions set for new node types
113+
// TS will error when a new type is added in the lib but is not mapped here
114+
const nodeTypeToActions: Record<NavigationTreeNodeType, ActionsSet> = {
115+
database: DIR_SET,
116+
directory: DIR_SET,
117+
table: TABLE_SET,
118+
column_table: TABLE_SET,
119+
index_table: JUST_COPY,
120+
index: EMPTY_SET,
121+
topic: DIR_SET,
122+
};
123+
124+
return nodeTypeToActions[type];
115125
};

0 commit comments

Comments
 (0)