Skip to content

Commit fbeea1a

Browse files
feat: add view to schema (#834)
1 parent efccf2e commit fbeea1a

File tree

16 files changed

+91
-47
lines changed

16 files changed

+91
-47
lines changed

package-lock.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"url": "^0.11.3",
4949
"use-query-params": "^2.2.1",
5050
"web-vitals": "^1.1.2",
51-
"ydb-ui-components": "^4.0.0"
51+
"ydb-ui-components": "^4.1.0"
5252
},
5353
"scripts": {
5454
"analyze": "source-map-explorer 'build/static/js/*.js'",

src/containers/Tenant/Diagnostics/DiagnosticsPages.ts

+4
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ export const TOPIC_PAGES = [overview, consumers, partitions, nodes, describe];
9292
export const EXTERNAL_DATA_SOURCE_PAGES = [overview, describe];
9393
export const EXTERNAL_TABLE_PAGES = [overview, describe];
9494

95+
export const VIEW_PAGES = [overview, describe];
96+
9597
// verbose mapping to guarantee correct tabs for new path types
9698
// TS will error when a new type is added but not mapped here
9799
const pathTypeToPages: Record<EPathType, Page[] | undefined> = {
@@ -113,6 +115,8 @@ const pathTypeToPages: Record<EPathType, Page[] | undefined> = {
113115

114116
[EPathType.EPathTypeExternalDataSource]: EXTERNAL_DATA_SOURCE_PAGES,
115117
[EPathType.EPathTypeExternalTable]: EXTERNAL_TABLE_PAGES,
118+
119+
[EPathType.EPathTypeView]: VIEW_PAGES,
116120
};
117121

118122
export const getPagesByType = (type?: EPathType) => (type && pathTypeToPages[type]) || DIR_PAGES;

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

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ function Overview({type, tenantName}: OverviewProps) {
9090
[EPathType.EPathTypePersQueueGroup]: () => <TopicInfo data={data} />,
9191
[EPathType.EPathTypeExternalTable]: () => <ExternalTableInfo data={data} />,
9292
[EPathType.EPathTypeExternalDataSource]: () => <ExternalDataSourceInfo data={data} />,
93+
[EPathType.EPathTypeView]: undefined,
9394
};
9495

9596
return (

src/containers/Tenant/ObjectSummary/ObjectSummary.tsx

+7-4
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import {
4444
PaneVisibilityToggleButtons,
4545
paneVisibilityToggleReducerCreator,
4646
} from '../utils/paneVisibilityToggleHelpers';
47-
import {isIndexTable, isTableType} from '../utils/schema';
47+
import {isIndexTableType, isTableType, isViewType} from '../utils/schema';
4848

4949
import './ObjectSummary.scss';
5050

@@ -103,15 +103,17 @@ export function ObjectSummary({
103103
const currentSchemaData = currentObjectData?.PathDescription?.Self;
104104

105105
React.useEffect(() => {
106-
const isTable = isTableType(type);
106+
// TODO: enable schema tab for view when supported
107+
const isTable = isTableType(type) && !isViewType(type);
107108

108109
if (type && !isTable && !TENANT_INFO_TABS.find((el) => el.id === summaryTab)) {
109110
dispatch(setSummaryTab(TENANT_SUMMARY_TABS_IDS.overview));
110111
}
111112
}, [dispatch, type, summaryTab]);
112113

113114
const renderTabs = () => {
114-
const isTable = isTableType(type);
115+
// TODO: enable schema tab for view when supported
116+
const isTable = isTableType(type) && !isViewType(type);
115117
const tabsItems = isTable ? [...TENANT_INFO_TABS, ...TENANT_SCHEMA_TAB] : TENANT_INFO_TABS;
116118

117119
return (
@@ -160,6 +162,7 @@ export function ObjectSummary({
160162
[EPathType.EPathTypeExternalDataSource]: () => (
161163
<ExternalDataSourceSummary data={currentObjectData} />
162164
),
165+
[EPathType.EPathTypeView]: undefined,
163166
};
164167

165168
let component =
@@ -239,7 +242,7 @@ export function ObjectSummary({
239242
};
240243

241244
const renderCommonInfoControls = () => {
242-
const showPreview = isTableType(type) && !isIndexTable(subType);
245+
const showPreview = isTableType(type) && !isIndexTableType(subType);
243246
return (
244247
<React.Fragment>
245248
{showPreview && (

src/containers/Tenant/Query/Preview/Preview.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type {EPathType} from '../../../../types/api/schema';
1010
import {cn} from '../../../../utils/cn';
1111
import {useTypedDispatch, useTypedSelector} from '../../../../utils/hooks';
1212
import {prepareQueryError} from '../../../../utils/query';
13-
import {isExternalTable, isTableType} from '../../utils/schema';
13+
import {isExternalTableType, isTableType} from '../../utils/schema';
1414
import i18n from '../i18n';
1515

1616
import './Preview.scss';
@@ -32,7 +32,7 @@ export const Preview = ({database, type}: PreviewProps) => {
3232

3333
const query = `--!syntax_v1\nselect * from \`${currentSchemaPath}\` limit 32`;
3434
const {currentData, isFetching, error} = previewApi.useSendQueryQuery(
35-
{database, query, action: isExternalTable(type) ? 'execute-query' : 'execute-scan'},
35+
{database, query, action: isExternalTableType(type) ? 'execute-query' : 'execute-scan'},
3636
{pollingInterval: autorefresh, skip: !isPreviewAvailable},
3737
);
3838
const loading = isFetching && currentData === undefined;

src/containers/Tenant/Schema/SchemaViewer/helpers.tsx

+9-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import type {
1111
TFamilyDescription,
1212
} from '../../../../types/api/schema';
1313
import {EColumnCodec} from '../../../../types/api/schema';
14-
import {isColumnEntityType, isExternalTable, isRowTable, isTableType} from '../../utils/schema';
14+
import {
15+
isColumnEntityType,
16+
isExternalTableType,
17+
isRowTableType,
18+
isTableType,
19+
} from '../../utils/schema';
1520

1621
export const SchemaViewerColumns = {
1722
id: 'Id',
@@ -69,7 +74,7 @@ export function prepareColumnDescriptions(
6974
const columnTableSchema = prepareOlapTableSchema(description);
7075
keyColumnIds = columnTableSchema.KeyColumnIds ?? [];
7176
columns = columnTableSchema.Columns ?? [];
72-
} else if (isExternalTable(type)) {
77+
} else if (isExternalTableType(type)) {
7378
columns = scheme?.PathDescription?.ExternalTableDescription?.Columns ?? [];
7479
} else {
7580
keyColumnIds = scheme?.PathDescription?.Table?.KeyColumnIds ?? [];
@@ -120,7 +125,7 @@ export function prepareSchemaTableColumns(options: {
120125
},
121126
];
122127

123-
if (!isExternalTable(options.type)) {
128+
if (!isExternalTableType(options.type)) {
124129
// External tables don't have key columns
125130
columns.push({
126131
name: SchemaViewerColumns.key,
@@ -164,7 +169,7 @@ export function prepareSchemaTableColumns(options: {
164169
},
165170
);
166171

167-
if (options.withFamilies && isRowTable(options.type)) {
172+
if (options.withFamilies && isRowTableType(options.type)) {
168173
columns.push(
169174
{
170175
name: SchemaViewerColumns.familyName,

src/containers/Tenant/i18n/en.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@
1010

1111
"actions.copied": "The path is copied to the clipboard",
1212
"actions.notCopied": "Couldn’t copy the path",
13-
"actions.externalTableSelectUnavailable": "Select query for external tables available only with 'YQL - QueryService' query mode. You need to turn in additional query modes in settings to enable it",
1413

1514
"actions.copyPath": "Copy path",
1615
"actions.openPreview": "Open preview",
1716
"actions.createTable": "Create table...",
1817
"actions.createExternalTable": "Create external table...",
1918
"actions.createTopic": "Create topic...",
19+
"actions.createView": "Create view...",
2020
"actions.dropTable": "Drop table...",
2121
"actions.dropTopic": "Drop topic...",
22+
"actions.dropView": "Drop view...",
2223
"actions.alterTable": "Alter table...",
2324
"actions.alterTopic": "Alter topic...",
2425
"actions.selectQuery": "Select query...",

src/containers/Tenant/i18n/index.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import {registerKeysets} from '../../../utils/i18n';
22

33
import en from './en.json';
4-
import ru from './ru.json';
54

65
const COMPONENT = 'ydb-tenant';
76

8-
export default registerKeysets(COMPONENT, {en, ru});
7+
export default registerKeysets(COMPONENT, {en});

src/containers/Tenant/i18n/ru.json

-26
This file was deleted.

src/containers/Tenant/utils/queryTemplates.ts

+8
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,11 @@ ALTER TOPIC \`${path}\`
111111
export const dropTopicTemplate = (path: string) => {
112112
return `DROP TOPIC \`${path}\`;`;
113113
};
114+
115+
export const createViewTemplate = (path: string) => {
116+
return `CREATE VIEW \`${path}/my_view\` WITH (security_invoker = TRUE) AS SELECT 1;`;
117+
};
118+
119+
export const dropViewTemplate = (path: string) => {
120+
return `DROP VIEW \`${path}\`;`;
121+
};

src/containers/Tenant/utils/schema.ts

+24-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ const pathTypeToNodeType: Record<EPathType, NavigationTreeNodeType | undefined>
3535

3636
[EPathType.EPathTypeExternalDataSource]: 'external_data_source',
3737
[EPathType.EPathTypeExternalTable]: 'external_table',
38+
39+
[EPathType.EPathTypeView]: 'view',
3840
};
3941

4042
export const mapPathTypeToNavigationTreeType = (
@@ -67,8 +69,11 @@ const pathTypeToEntityName: Record<EPathType, string | undefined> = {
6769
[EPathType.EPathTypeColumnTable]: 'Columntable',
6870
[EPathType.EPathTypeCdcStream]: 'Changefeed',
6971
[EPathType.EPathTypePersQueueGroup]: 'Topic',
72+
7073
[EPathType.EPathTypeExternalDataSource]: 'External Data Source',
7174
[EPathType.EPathTypeExternalTable]: 'External Table',
75+
76+
[EPathType.EPathTypeView]: 'View',
7277
};
7378

7479
export const mapPathTypeToEntityName = (
@@ -97,6 +102,8 @@ const pathTypeToIsTable: Record<EPathType, boolean> = {
97102

98103
[EPathType.EPathTypeExternalTable]: true,
99104

105+
[EPathType.EPathTypeView]: true,
106+
100107
[EPathType.EPathTypeInvalid]: false,
101108
[EPathType.EPathTypeDir]: false,
102109
[EPathType.EPathTypeSubDomain]: false,
@@ -121,7 +128,7 @@ const pathSubTypeToIsIndexImpl: Record<EPathSubType, boolean> = {
121128
[EPathSubType.EPathSubTypeEmpty]: false,
122129
};
123130

124-
export const isIndexTable = (subType?: EPathSubType) =>
131+
export const isIndexTableType = (subType?: EPathSubType) =>
125132
(subType && pathSubTypeToIsIndexImpl[subType]) ?? false;
126133

127134
// ====================
@@ -138,8 +145,11 @@ const pathTypeToIsColumn: Record<EPathType, boolean> = {
138145
[EPathType.EPathTypeExtSubDomain]: false,
139146
[EPathType.EPathTypeCdcStream]: false,
140147
[EPathType.EPathTypePersQueueGroup]: false,
148+
141149
[EPathType.EPathTypeExternalDataSource]: false,
142150
[EPathType.EPathTypeExternalTable]: false,
151+
152+
[EPathType.EPathTypeView]: false,
143153
};
144154

145155
export const isColumnEntityType = (type?: EPathType) => (type && pathTypeToIsColumn[type]) ?? false;
@@ -158,8 +168,11 @@ const pathTypeToIsDatabase: Record<EPathType, boolean> = {
158168
[EPathType.EPathTypeTableIndex]: false,
159169
[EPathType.EPathTypeCdcStream]: false,
160170
[EPathType.EPathTypePersQueueGroup]: false,
171+
161172
[EPathType.EPathTypeExternalDataSource]: false,
162173
[EPathType.EPathTypeExternalTable]: false,
174+
175+
[EPathType.EPathTypeView]: false,
163176
};
164177

165178
export const isDatabaseEntityType = (type?: EPathType) =>
@@ -183,8 +196,11 @@ const pathTypeToEntityWithMergedImplementation: Record<EPathType, boolean> = {
183196
[EPathType.EPathTypeSubDomain]: false,
184197
[EPathType.EPathTypeTableIndex]: false,
185198
[EPathType.EPathTypeExtSubDomain]: false,
199+
186200
[EPathType.EPathTypeExternalDataSource]: false,
187201
[EPathType.EPathTypeExternalTable]: false,
202+
203+
[EPathType.EPathTypeView]: false,
188204
};
189205

190206
export const isEntityWithMergedImplementation = (type?: EPathType) =>
@@ -207,6 +223,8 @@ const pathTypeToChildless: Record<EPathType, boolean> = {
207223
[EPathType.EPathTypeExternalDataSource]: true,
208224
[EPathType.EPathTypeExternalTable]: true,
209225

226+
[EPathType.EPathTypeView]: true,
227+
210228
[EPathType.EPathTypeInvalid]: false,
211229
[EPathType.EPathTypeColumnStore]: false,
212230
[EPathType.EPathTypeColumnTable]: false,
@@ -237,12 +255,15 @@ const mapPathTypeToIsWithTopic: Record<EPathType, boolean> = {
237255

238256
[EPathType.EPathTypeExternalDataSource]: false,
239257
[EPathType.EPathTypeExternalTable]: false,
258+
259+
[EPathType.EPathTypeView]: false,
240260
};
241261

242262
export const isPathTypeWithTopic = (type?: EPathType) =>
243263
(type && mapPathTypeToIsWithTopic[type]) ?? false;
244264

245265
// ====================
246266

247-
export const isExternalTable = (type?: EPathType) => type === EPathType.EPathTypeExternalTable;
248-
export const isRowTable = (type?: EPathType) => type === EPathType.EPathTypeTable;
267+
export const isExternalTableType = (type?: EPathType) => type === EPathType.EPathTypeExternalTable;
268+
export const isRowTableType = (type?: EPathType) => type === EPathType.EPathTypeTable;
269+
export const isViewType = (type?: EPathType) => type === EPathType.EPathTypeView;

src/containers/Tenant/utils/schemaActions.ts

+13
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import {
1414
createExternalTableTemplate,
1515
createTableTemplate,
1616
createTopicTemplate,
17+
createViewTemplate,
1718
dropExternalTableTemplate,
1819
dropTopicTemplate,
20+
dropViewTemplate,
1921
selectQueryTemplate,
2022
upsertQueryTemplate,
2123
} from './queryTemplates';
@@ -54,6 +56,8 @@ const bindActions = (
5456
createTopic: inputQuery(createTopicTemplate, 'script'),
5557
alterTopic: inputQuery(alterTopicTemplate, 'script'),
5658
dropTopic: inputQuery(dropTopicTemplate, 'script'),
59+
createView: inputQuery(createViewTemplate, 'script'),
60+
dropView: inputQuery(dropViewTemplate, 'script'),
5761
copyPath: () => {
5862
try {
5963
copy(path);
@@ -86,6 +90,7 @@ export const getActions =
8690
[
8791
{text: i18n('actions.createTable'), action: actions.createTable},
8892
{text: i18n('actions.createTopic'), action: actions.createTopic},
93+
{text: i18n('actions.createView'), action: actions.createView},
8994
],
9095
];
9196
const TABLE_SET: ActionsSet = [
@@ -121,6 +126,12 @@ export const getActions =
121126
[{text: i18n('actions.createExternalTable'), action: actions.createExternalTable}],
122127
];
123128

129+
const VIEW_SET = [
130+
[copyItem],
131+
[{text: i18n('actions.selectQuery'), action: actions.selectQuery}],
132+
[{text: i18n('actions.dropView'), action: actions.dropView}],
133+
];
134+
124135
const JUST_COPY: ActionsSet = [copyItem];
125136

126137
// verbose mapping to guarantee a correct actions set for new node types
@@ -140,6 +151,8 @@ export const getActions =
140151

141152
external_table: EXTERNAL_TABLE_SET,
142153
external_data_source: EXTERNAL_DATA_SOURCE_SET,
154+
155+
view: VIEW_SET,
143156
};
144157

145158
return nodeTypeToActions[type];

src/containers/Tenant/utils/schemaControls.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ export const getControls =
6060

6161
external_table: openPreview,
6262
external_data_source: undefined,
63+
64+
view: openPreview,
6365
};
6466

6567
return nodeTypeToControls[type];

0 commit comments

Comments
 (0)