ydb-embedded-ui 4.21.0 → 4.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/components/NodeHostWrapper/NodeHostWrapper.scss +2 -1
- package/dist/components/QueryResultTable/QueryResultTable.tsx +7 -3
- package/dist/components/VirtualTable/TableChunk.tsx +2 -1
- package/dist/components/VirtualTable/VirtualTable.tsx +1 -1
- package/dist/containers/Node/Node.tsx +9 -17
- package/dist/containers/Node/NodeStructure/NodeStructure.tsx +8 -30
- package/dist/containers/Node/NodeStructure/Pdisk.tsx +32 -18
- package/dist/containers/Node/i18n/en.json +4 -0
- package/dist/containers/Node/i18n/index.ts +11 -0
- package/dist/containers/Node/i18n/ru.json +4 -0
- package/dist/containers/Nodes/Nodes.tsx +5 -10
- package/dist/containers/Nodes/getNodesColumns.tsx +57 -13
- package/dist/containers/Tablets/Tablets.tsx +3 -8
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +0 -1
- package/dist/containers/Tenant/Diagnostics/Network/Network.js +5 -10
- package/dist/containers/Tenant/Diagnostics/Network/utils.ts +6 -0
- package/dist/containers/Tenant/Query/ExecuteResult/ExecuteResult.scss +13 -5
- package/dist/containers/Tenant/Query/ExecuteResult/ExecuteResult.tsx +72 -18
- package/dist/containers/Tenant/Query/ExplainResult/ExplainResult.js +2 -1
- package/dist/containers/Tenant/Query/ExplainResult/utils.ts +6 -0
- package/dist/containers/Tenant/Query/QueryEditor/QueryEditor.js +11 -24
- package/dist/containers/Tenant/Query/utils/getPreparedResult.ts +4 -5
- package/dist/containers/UserSettings/i18n/en.json +5 -2
- package/dist/containers/UserSettings/i18n/ru.json +5 -2
- package/dist/containers/UserSettings/settings.ts +12 -6
- package/dist/store/reducers/executeQuery.ts +4 -3
- package/dist/store/reducers/nodes/nodes.ts +2 -2
- package/dist/store/reducers/nodes/types.ts +12 -1
- package/dist/store/reducers/nodes/utils.ts +6 -0
- package/dist/store/reducers/settings/settings.ts +5 -3
- package/dist/types/api/netInfo.ts +1 -1
- package/dist/types/api/nodes.ts +24 -0
- package/dist/types/api/query.ts +23 -8
- package/dist/types/store/query.ts +6 -0
- package/dist/utils/constants.ts +3 -0
- package/dist/utils/developerUI/__test__/developerUI.test.ts +50 -0
- package/dist/utils/developerUI/developerUI.ts +42 -0
- package/dist/utils/diagnostics.ts +1 -0
- package/dist/utils/query.ts +68 -13
- package/package.json +1 -1
- package/dist/utils/index.js +0 -9
- /package/dist/{components/VirtualTable/utils.ts → utils/index.ts} +0 -0
@@ -0,0 +1,6 @@
|
|
1
|
+
import type {TNetNodePeerInfo} from '../../../../types/api/netInfo';
|
2
|
+
|
3
|
+
// determine how many nodes have status Connected "true"
|
4
|
+
export const getConnectedNodesCount = (peers: TNetNodePeerInfo[] | undefined) => {
|
5
|
+
return peers?.reduce((acc, item) => (item.Connected ? acc + 1 : acc), 0);
|
6
|
+
};
|
@@ -13,11 +13,19 @@
|
|
13
13
|
& .data-table__table-wrapper {
|
14
14
|
padding-bottom: 0;
|
15
15
|
}
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
}
|
17
|
+
|
18
|
+
&__result-fullscreen-wrapper {
|
19
|
+
display: flex;
|
20
|
+
flex-direction: column;
|
21
|
+
|
22
|
+
width: 100%;
|
23
|
+
margin-top: 10px;
|
24
|
+
padding: 0 10px 10px;
|
25
|
+
}
|
26
|
+
|
27
|
+
&__result-tabs {
|
28
|
+
padding-left: 10px;
|
21
29
|
}
|
22
30
|
|
23
31
|
&__error {
|
@@ -1,26 +1,30 @@
|
|
1
|
-
import React, {
|
1
|
+
import React, {useEffect, useState} from 'react';
|
2
2
|
import {useDispatch} from 'react-redux';
|
3
3
|
import cn from 'bem-cn-lite';
|
4
4
|
import JSONTree from 'react-json-inspector';
|
5
5
|
|
6
|
-
import {RadioButton} from '@gravity-ui/uikit';
|
6
|
+
import {RadioButton, Tabs} from '@gravity-ui/uikit';
|
7
7
|
|
8
8
|
import CopyToClipboard from '../../../../components/CopyToClipboard/CopyToClipboard';
|
9
9
|
import Divider from '../../../../components/Divider/Divider';
|
10
10
|
import EnableFullscreenButton from '../../../../components/EnableFullscreenButton/EnableFullscreenButton';
|
11
11
|
import Fullscreen from '../../../../components/Fullscreen/Fullscreen';
|
12
12
|
import {QueryExecutionStatus} from '../../../../components/QueryExecutionStatus';
|
13
|
+
import {QueryResultTable} from '../../../../components/QueryResultTable/QueryResultTable';
|
13
14
|
|
14
15
|
import type {ValueOf} from '../../../../types/common';
|
15
16
|
import type {IQueryResult, QueryErrorResponse} from '../../../../types/store/query';
|
17
|
+
import type {ColumnType, KeyValueRow} from '../../../../types/api/query';
|
16
18
|
import {disableFullscreen} from '../../../../store/reducers/fullscreen';
|
17
19
|
import {prepareQueryError} from '../../../../utils/query';
|
18
20
|
import {useTypedSelector} from '../../../../utils/hooks';
|
21
|
+
import {getArray} from '../../../../utils';
|
19
22
|
|
20
23
|
import {PaneVisibilityToggleButtons} from '../../utils/paneVisibilityToggleHelpers';
|
21
24
|
|
22
25
|
import {ResultIssues} from '../Issues/Issues';
|
23
26
|
import {QueryDuration} from '../QueryDuration/QueryDuration';
|
27
|
+
import {getPreparedResult} from '../utils/getPreparedResult';
|
24
28
|
|
25
29
|
import './ExecuteResult.scss';
|
26
30
|
|
@@ -39,30 +43,35 @@ const resultOptions = [
|
|
39
43
|
];
|
40
44
|
|
41
45
|
interface ExecuteResultProps {
|
42
|
-
|
43
|
-
result: ReactNode;
|
46
|
+
data: IQueryResult | undefined;
|
44
47
|
stats: IQueryResult['stats'] | undefined;
|
45
48
|
error: string | QueryErrorResponse | undefined;
|
46
|
-
copyDisabled?: boolean;
|
47
49
|
isResultsCollapsed?: boolean;
|
48
50
|
onCollapseResults: VoidFunction;
|
49
51
|
onExpandResults: VoidFunction;
|
50
52
|
}
|
51
53
|
|
52
54
|
export function ExecuteResult({
|
53
|
-
|
54
|
-
result,
|
55
|
+
data,
|
55
56
|
stats,
|
56
57
|
error,
|
57
|
-
copyDisabled,
|
58
58
|
isResultsCollapsed,
|
59
59
|
onCollapseResults,
|
60
60
|
onExpandResults,
|
61
61
|
}: ExecuteResultProps) {
|
62
|
+
const [selectedResultSet, setSelectedResultSet] = useState(0);
|
62
63
|
const [activeSection, setActiveSection] = useState<SectionID>(resultOptionsIds.result);
|
64
|
+
|
63
65
|
const isFullscreen = useTypedSelector((state) => state.fullscreen);
|
64
66
|
const dispatch = useDispatch();
|
65
67
|
|
68
|
+
const resultsSetsCount = data?.resultSets?.length;
|
69
|
+
const isMulti = resultsSetsCount && resultsSetsCount > 0;
|
70
|
+
const currentResult = isMulti ? data?.resultSets?.[selectedResultSet].result : data?.result;
|
71
|
+
const currentColumns = isMulti ? data?.resultSets?.[selectedResultSet].columns : data?.columns;
|
72
|
+
const textResults = getPreparedResult(currentResult);
|
73
|
+
const copyDisabled = !textResults.length;
|
74
|
+
|
66
75
|
useEffect(() => {
|
67
76
|
return () => {
|
68
77
|
dispatch(disableFullscreen());
|
@@ -73,6 +82,37 @@ export function ExecuteResult({
|
|
73
82
|
setActiveSection(value as SectionID);
|
74
83
|
};
|
75
84
|
|
85
|
+
const renderResultTable = (
|
86
|
+
result: KeyValueRow[] | undefined,
|
87
|
+
columns: ColumnType[] | undefined,
|
88
|
+
) => {
|
89
|
+
return <QueryResultTable data={result} columns={columns} settings={{sortable: false}} />;
|
90
|
+
};
|
91
|
+
|
92
|
+
const renderContent = () => {
|
93
|
+
return (
|
94
|
+
<>
|
95
|
+
{isMulti && resultsSetsCount > 1 && (
|
96
|
+
<div>
|
97
|
+
<Tabs
|
98
|
+
className={b('result-tabs')}
|
99
|
+
size="l"
|
100
|
+
items={getArray(resultsSetsCount).map((item) => ({
|
101
|
+
id: String(item),
|
102
|
+
title: `Result #${item + 1}`,
|
103
|
+
}))}
|
104
|
+
activeTab={String(selectedResultSet)}
|
105
|
+
onSelectTab={(tabId) => setSelectedResultSet(Number(tabId))}
|
106
|
+
/>
|
107
|
+
</div>
|
108
|
+
)}
|
109
|
+
<div className={b('result')}>
|
110
|
+
{renderResultTable(currentResult, currentColumns)}
|
111
|
+
</div>
|
112
|
+
</>
|
113
|
+
);
|
114
|
+
};
|
115
|
+
|
76
116
|
const renderClipboardButton = () => {
|
77
117
|
return (
|
78
118
|
<CopyToClipboard
|
@@ -108,12 +148,14 @@ export function ExecuteResult({
|
|
108
148
|
};
|
109
149
|
|
110
150
|
const renderResult = () => {
|
151
|
+
const content = renderContent();
|
152
|
+
|
111
153
|
return (
|
112
154
|
<React.Fragment>
|
113
|
-
{
|
155
|
+
{content}
|
114
156
|
{isFullscreen && (
|
115
157
|
<Fullscreen>
|
116
|
-
<div className={b('result'
|
158
|
+
<div className={b('result-fullscreen-wrapper')}>{content}</div>
|
117
159
|
</Fullscreen>
|
118
160
|
)}
|
119
161
|
</React.Fragment>
|
@@ -126,13 +168,15 @@ export function ExecuteResult({
|
|
126
168
|
}
|
127
169
|
|
128
170
|
if (typeof error === 'object' && error.data?.issues && Array.isArray(error.data.issues)) {
|
171
|
+
const content = <ResultIssues data={error.data} />;
|
172
|
+
|
129
173
|
return (
|
130
174
|
<React.Fragment>
|
131
|
-
|
175
|
+
{content}
|
132
176
|
{isFullscreen && (
|
133
177
|
<Fullscreen>
|
134
|
-
<div className={b('result',
|
135
|
-
|
178
|
+
<div className={b('result-fullscreen-wrapper', b('result'))}>
|
179
|
+
{content}
|
136
180
|
</div>
|
137
181
|
</Fullscreen>
|
138
182
|
)}
|
@@ -145,6 +189,19 @@ export function ExecuteResult({
|
|
145
189
|
return <div className={b('error')}>{parsedError}</div>;
|
146
190
|
};
|
147
191
|
|
192
|
+
const renderResultSection = () => {
|
193
|
+
if (activeSection === resultOptionsIds.result && !error) {
|
194
|
+
return renderResult();
|
195
|
+
}
|
196
|
+
|
197
|
+
return (
|
198
|
+
<div className={b('result')}>
|
199
|
+
{activeSection === resultOptionsIds.stats && !error && renderStats()}
|
200
|
+
{renderIssues()}
|
201
|
+
</div>
|
202
|
+
);
|
203
|
+
};
|
204
|
+
|
148
205
|
return (
|
149
206
|
<React.Fragment>
|
150
207
|
<div className={b('controls')}>
|
@@ -174,11 +231,8 @@ export function ExecuteResult({
|
|
174
231
|
/>
|
175
232
|
</div>
|
176
233
|
</div>
|
177
|
-
|
178
|
-
|
179
|
-
{activeSection === resultOptionsIds.stats && !error && renderStats()}
|
180
|
-
{renderIssues()}
|
181
|
-
</div>
|
234
|
+
|
235
|
+
{renderResultSection()}
|
182
236
|
</React.Fragment>
|
183
237
|
);
|
184
238
|
}
|
@@ -16,11 +16,12 @@ import {QueryExecutionStatus} from '../../../../components/QueryExecutionStatus'
|
|
16
16
|
import {explainVersions} from '../../../../store/reducers/explainQuery';
|
17
17
|
import {disableFullscreen} from '../../../../store/reducers/fullscreen';
|
18
18
|
|
19
|
-
import {renderExplainNode} from '../../../../utils';
|
20
19
|
import {LANGUAGE_S_EXPRESSION_ID} from '../../../../utils/monaco';
|
21
20
|
|
22
21
|
import {PaneVisibilityToggleButtons} from '../../utils/paneVisibilityToggleHelpers';
|
23
22
|
|
23
|
+
import {renderExplainNode} from './utils';
|
24
|
+
|
24
25
|
import './ExplainResult.scss';
|
25
26
|
|
26
27
|
const b = cn('ydb-query-explain-result');
|
@@ -6,7 +6,6 @@ import _ from 'lodash';
|
|
6
6
|
import MonacoEditor from 'react-monaco-editor';
|
7
7
|
|
8
8
|
import SplitPane from '../../../../components/SplitPane';
|
9
|
-
import {QueryResultTable} from '../../../../components/QueryResultTable';
|
10
9
|
|
11
10
|
import {
|
12
11
|
sendExecuteQuery,
|
@@ -26,6 +25,7 @@ import {
|
|
26
25
|
SAVED_QUERIES_KEY,
|
27
26
|
ENABLE_ADDITIONAL_QUERY_MODES,
|
28
27
|
LAST_USED_QUERY_ACTION_KEY,
|
28
|
+
QUERY_USE_MULTI_SCHEMA_KEY,
|
29
29
|
} from '../../../../utils/constants';
|
30
30
|
import {useSetting, useQueryModes} from '../../../../utils/hooks';
|
31
31
|
import {QUERY_ACTIONS, QUERY_MODES, isNewQueryMode} from '../../../../utils/query';
|
@@ -40,14 +40,8 @@ import {ExecuteResult} from '../ExecuteResult/ExecuteResult';
|
|
40
40
|
import {ExplainResult} from '../ExplainResult/ExplainResult';
|
41
41
|
import {QueryEditorControls} from '../QueryEditorControls/QueryEditorControls';
|
42
42
|
|
43
|
-
import {getPreparedResult} from '../utils/getPreparedResult';
|
44
|
-
|
45
43
|
import './QueryEditor.scss';
|
46
44
|
|
47
|
-
const TABLE_SETTINGS = {
|
48
|
-
sortable: false,
|
49
|
-
};
|
50
|
-
|
51
45
|
const EDITOR_OPTIONS = {
|
52
46
|
automaticLayout: true,
|
53
47
|
selectOnLineNumbers: true,
|
@@ -92,6 +86,7 @@ function QueryEditor(props) {
|
|
92
86
|
const [isResultLoaded, setIsResultLoaded] = useState(false);
|
93
87
|
const [queryMode, setQueryMode] = useQueryModes();
|
94
88
|
const [enableAdditionalQueryModes] = useSetting(ENABLE_ADDITIONAL_QUERY_MODES);
|
89
|
+
const [useMultiSchema] = useSetting(QUERY_USE_MULTI_SCHEMA_KEY);
|
95
90
|
const [lastUsedQueryAction, setLastUsedQueryAction] = useSetting(LAST_USED_QUERY_ACTION_KEY);
|
96
91
|
|
97
92
|
useEffect(() => {
|
@@ -256,9 +251,16 @@ function QueryEditor(props) {
|
|
256
251
|
setShowPreview,
|
257
252
|
} = props;
|
258
253
|
|
254
|
+
const schema = useMultiSchema ? 'multi' : 'modern';
|
255
|
+
|
259
256
|
setLastUsedQueryAction(QUERY_ACTIONS.execute);
|
260
257
|
setResultType(RESULT_TYPES.EXECUTE);
|
261
|
-
sendExecuteQuery({
|
258
|
+
sendExecuteQuery({
|
259
|
+
query: input,
|
260
|
+
database: path,
|
261
|
+
mode,
|
262
|
+
schema,
|
263
|
+
});
|
262
264
|
setIsResultLoaded(true);
|
263
265
|
setShowPreview(false);
|
264
266
|
|
@@ -314,26 +316,11 @@ function QueryEditor(props) {
|
|
314
316
|
executeQuery: {data, error, stats},
|
315
317
|
} = props;
|
316
318
|
|
317
|
-
let content;
|
318
|
-
if (data) {
|
319
|
-
content = (
|
320
|
-
<QueryResultTable
|
321
|
-
data={data.result}
|
322
|
-
columns={data.columns}
|
323
|
-
settings={TABLE_SETTINGS}
|
324
|
-
/>
|
325
|
-
);
|
326
|
-
}
|
327
|
-
const textResults = getPreparedResult(data);
|
328
|
-
const disabled = !textResults.length || resultType !== RESULT_TYPES.EXECUTE;
|
329
|
-
|
330
319
|
return data || error ? (
|
331
320
|
<ExecuteResult
|
332
|
-
|
321
|
+
data={data}
|
333
322
|
stats={stats}
|
334
323
|
error={error}
|
335
|
-
textResults={textResults}
|
336
|
-
copyDisabled={disabled}
|
337
324
|
isResultsCollapsed={resultVisibilityState.collapsed}
|
338
325
|
onExpandResults={onExpandResultHandler}
|
339
326
|
onCollapseResults={onCollapseResultHandler}
|
@@ -1,16 +1,15 @@
|
|
1
1
|
import type {KeyValueRow} from '../../../../types/api/query';
|
2
|
-
import type {IQueryResult} from '../../../../types/store/query';
|
3
2
|
|
4
|
-
export const getPreparedResult = (data:
|
3
|
+
export const getPreparedResult = (data: KeyValueRow[] | undefined) => {
|
5
4
|
const columnDivider = '\t';
|
6
5
|
const rowDivider = '\n';
|
7
6
|
|
8
|
-
if (!data?.
|
7
|
+
if (!data?.length) {
|
9
8
|
return '';
|
10
9
|
}
|
11
10
|
|
12
|
-
const columnHeaders = Object.keys(data
|
13
|
-
const rows = Array<string[] | KeyValueRow[]>(columnHeaders).concat(data
|
11
|
+
const columnHeaders = Object.keys(data[0]);
|
12
|
+
const rows = Array<string[] | KeyValueRow[]>(columnHeaders).concat(data);
|
14
13
|
|
15
14
|
return rows
|
16
15
|
.map((item) => {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"page.general": "General",
|
3
|
-
"section.
|
3
|
+
"section.appearance": "Appearance",
|
4
4
|
|
5
5
|
"page.experiments": "Experiments",
|
6
6
|
"section.experiments": "Experiments",
|
@@ -17,7 +17,7 @@
|
|
17
17
|
"settings.invertedDisks.title": "Inverted disks space indicators",
|
18
18
|
|
19
19
|
"settings.useNodesEndpoint.title": "Break the Nodes tab in Diagnostics",
|
20
|
-
"settings.useNodesEndpoint.popover": "Use /viewer/json/nodes endpoint for Nodes Tab in diagnostics. It
|
20
|
+
"settings.useNodesEndpoint.popover": "Use /viewer/json/nodes endpoint for Nodes Tab in diagnostics. It could return incorrect data on some versions",
|
21
21
|
|
22
22
|
"settings.useBackendParamsForTables.title": "Use virtual table for cluster Nodes tab",
|
23
23
|
"settings.useBackendParamsForTables.popover": "Use table with data load on scroll. It will increase performance, but could work unstable",
|
@@ -25,6 +25,9 @@
|
|
25
25
|
"settings.enableAdditionalQueryModes.title": "Enable additional query modes",
|
26
26
|
"settings.enableAdditionalQueryModes.popover": "Adds 'Data', 'YQL - QueryService' and 'PostgreSQL' modes. May not work on some versions",
|
27
27
|
|
28
|
+
"settings.queryUseMultiSchema.title": "Allow queries with multiple result sets",
|
29
|
+
"settings.queryUseMultiSchema.popover": "Use 'multi' schema for queries that enables queries with multiple result sets. Returns nothing on versions 23-3 and older",
|
30
|
+
|
28
31
|
"settings.tenantDiagnostics.title": "Display metrics cards for database diagnostics",
|
29
32
|
"settings.tenantDiagnostics.popover": "Adds indicators of database resources usage. Incomplete data may be displayed for some databases"
|
30
33
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"page.general": "Общие",
|
3
|
-
"section.
|
3
|
+
"section.appearance": "Внешний вид",
|
4
4
|
|
5
5
|
"page.experiments": "Эксперименты",
|
6
6
|
"section.experiments": "Эксперименты",
|
@@ -17,7 +17,7 @@
|
|
17
17
|
"settings.invertedDisks.title": "Инвертированные индикаторы места на дисках",
|
18
18
|
|
19
19
|
"settings.useNodesEndpoint.title": "Сломать вкладку Nodes в диагностике",
|
20
|
-
"settings.useNodesEndpoint.popover": "Использовать эндпоинт /viewer/json/nodes для вкладки Nodes в диагностике. Может возвращать некорректные данные на версиях
|
20
|
+
"settings.useNodesEndpoint.popover": "Использовать эндпоинт /viewer/json/nodes для вкладки Nodes в диагностике. Может возвращать некорректные данные на некоторых версиях",
|
21
21
|
|
22
22
|
"settings.useBackendParamsForTables.title": "Использовать виртуализированную таблицу для вкладки Nodes кластера",
|
23
23
|
"settings.useBackendParamsForTables.popover": "Использовать таблицу с загрузкой данных по скроллу. Это улучшит производительность, но может работать нестабильно",
|
@@ -25,6 +25,9 @@
|
|
25
25
|
"settings.enableAdditionalQueryModes.title": "Включить дополнительные режимы выполнения запросов",
|
26
26
|
"settings.enableAdditionalQueryModes.popover": "Добавляет режимы 'Data', 'YQL - QueryService' и 'PostgreSQL'. Может работать некорректно на некоторых версиях",
|
27
27
|
|
28
|
+
"settings.queryUseMultiSchema.title": "Разрешить запросы с несколькими результатами",
|
29
|
+
"settings.queryUseMultiSchema.popover": "Использовать для запросов схему 'multi', которая позволяет выполнять запросы с несколькими результатами. На версиях 23-3 и старше результат не возвращается вообще",
|
30
|
+
|
28
31
|
"settings.tenantDiagnostics.title": "Показывать карточки с метриками в диагностике базы данных",
|
29
32
|
"settings.tenantDiagnostics.popover": "Добавляет индикаторы использования ресурсов базы данных. Для некоторых баз могут отображаться неполные данные"
|
30
33
|
}
|
@@ -11,6 +11,7 @@ import {
|
|
11
11
|
THEME_KEY,
|
12
12
|
USE_BACKEND_PARAMS_FOR_TABLES_KEY,
|
13
13
|
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
|
14
|
+
QUERY_USE_MULTI_SCHEMA_KEY,
|
14
15
|
} from '../../utils/constants';
|
15
16
|
import {Lang, defaultLang} from '../../utils/i18n';
|
16
17
|
|
@@ -95,25 +96,30 @@ export const enableQueryModesForExplainSetting: SettingProps = {
|
|
95
96
|
title: i18n('settings.enableAdditionalQueryModes.title'),
|
96
97
|
helpPopoverContent: i18n('settings.enableAdditionalQueryModes.popover'),
|
97
98
|
};
|
99
|
+
export const queryUseMultiSchemaSetting: SettingProps = {
|
100
|
+
settingKey: QUERY_USE_MULTI_SCHEMA_KEY,
|
101
|
+
title: i18n('settings.queryUseMultiSchema.title'),
|
102
|
+
helpPopoverContent: i18n('settings.queryUseMultiSchema.popover'),
|
103
|
+
};
|
98
104
|
export const enableNewTenantDiagnosticsDesign: SettingProps = {
|
99
105
|
settingKey: DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS,
|
100
106
|
title: i18n('settings.tenantDiagnostics.title'),
|
101
107
|
helpPopoverContent: i18n('settings.tenantDiagnostics.popover'),
|
102
108
|
};
|
103
109
|
|
104
|
-
export const
|
105
|
-
id: '
|
106
|
-
title: i18n('section.
|
107
|
-
settings: [themeSetting],
|
110
|
+
export const appearanceSection: SettingsSection = {
|
111
|
+
id: 'appearanceSection',
|
112
|
+
title: i18n('section.appearance'),
|
113
|
+
settings: [themeSetting, invertedDisksSetting],
|
108
114
|
};
|
109
115
|
export const experimentsSection: SettingsSection = {
|
110
116
|
id: 'experimentsSection',
|
111
117
|
title: i18n('section.experiments'),
|
112
118
|
settings: [
|
113
|
-
invertedDisksSetting,
|
114
119
|
useNodesEndpointSetting,
|
115
120
|
useBackendParamsForTables,
|
116
121
|
enableQueryModesForExplainSetting,
|
122
|
+
queryUseMultiSchemaSetting,
|
117
123
|
enableNewTenantDiagnosticsDesign,
|
118
124
|
],
|
119
125
|
};
|
@@ -122,7 +128,7 @@ export const generalPage: SettingsPage = {
|
|
122
128
|
id: 'generalPage',
|
123
129
|
title: i18n('page.general'),
|
124
130
|
icon: {data: favoriteFilledIcon, height: 14, width: 14},
|
125
|
-
sections: [
|
131
|
+
sections: [appearanceSection],
|
126
132
|
};
|
127
133
|
export const experimentsPage: SettingsPage = {
|
128
134
|
id: 'experimentsPage',
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import type {Reducer} from 'redux';
|
2
2
|
|
3
|
-
import type {ExecuteActions} from '../../types/api/query';
|
3
|
+
import type {ExecuteActions, Schemas} from '../../types/api/query';
|
4
4
|
import type {
|
5
5
|
ExecuteQueryAction,
|
6
6
|
ExecuteQueryState,
|
@@ -154,9 +154,10 @@ const executeQuery: Reducer<ExecuteQueryState, ExecuteQueryAction> = (
|
|
154
154
|
|
155
155
|
interface SendQueryParams extends QueryRequestParams {
|
156
156
|
mode?: QueryMode;
|
157
|
+
schema?: Schemas;
|
157
158
|
}
|
158
159
|
|
159
|
-
export const sendExecuteQuery = ({query, database, mode}: SendQueryParams) => {
|
160
|
+
export const sendExecuteQuery = ({query, database, mode, schema = 'modern'}: SendQueryParams) => {
|
160
161
|
let action: ExecuteActions = 'execute';
|
161
162
|
let syntax: QuerySyntax = QUERY_SYNTAX.yql;
|
162
163
|
|
@@ -169,7 +170,7 @@ export const sendExecuteQuery = ({query, database, mode}: SendQueryParams) => {
|
|
169
170
|
|
170
171
|
return createApiRequest({
|
171
172
|
request: window.api.sendQuery({
|
172
|
-
schema
|
173
|
+
schema,
|
173
174
|
query,
|
174
175
|
database,
|
175
176
|
action,
|
@@ -99,9 +99,9 @@ const nodes: Reducer<NodesState, NodesAction> = (state = initialState, action) =
|
|
99
99
|
};
|
100
100
|
const concurrentId = 'getNodes';
|
101
101
|
|
102
|
-
export function getNodes({type = 'any', ...params}: NodesApiRequestParams) {
|
102
|
+
export function getNodes({type = 'any', storage = false, ...params}: NodesApiRequestParams) {
|
103
103
|
return createApiRequest({
|
104
|
-
request: window.api.getNodes({type, ...params}, {concurrentId}),
|
104
|
+
request: window.api.getNodes({type, storage, ...params}, {concurrentId}),
|
105
105
|
actions: FETCH_NODES,
|
106
106
|
dataHandler: prepareNodesData,
|
107
107
|
});
|
@@ -30,15 +30,25 @@ export interface NodesPreparedEntity {
|
|
30
30
|
DataCenter?: string;
|
31
31
|
Rack?: string;
|
32
32
|
Version?: string;
|
33
|
+
TenantName?: string;
|
34
|
+
|
33
35
|
StartTime?: string;
|
34
36
|
Uptime: string;
|
37
|
+
DisconnectTime?: string;
|
38
|
+
|
35
39
|
MemoryUsed?: string;
|
40
|
+
MemoryUsedInAlloc?: string;
|
36
41
|
MemoryLimit?: string;
|
42
|
+
|
43
|
+
SharedCacheUsed?: string;
|
44
|
+
SharedCacheLimit?: string | number;
|
45
|
+
|
37
46
|
PoolStats?: TPoolStats[];
|
38
47
|
LoadAverage?: number[];
|
39
48
|
Tablets?: TFullTabletStateInfo[] | TComputeTabletStateInfo[];
|
40
|
-
TenantName?: string;
|
41
49
|
Endpoints?: TEndpoint[];
|
50
|
+
|
51
|
+
TotalSessions?: number;
|
42
52
|
}
|
43
53
|
|
44
54
|
export interface NodesState {
|
@@ -70,6 +80,7 @@ export interface NodesGeneralRequestParams extends NodesSortParams {
|
|
70
80
|
}
|
71
81
|
|
72
82
|
export interface NodesApiRequestParams extends NodesGeneralRequestParams {
|
83
|
+
path?: string;
|
73
84
|
tenant?: string;
|
74
85
|
type?: NodeType;
|
75
86
|
visibleEntities?: VisibleEntities; // "with" param
|
@@ -50,12 +50,18 @@ export const prepareNodesData = (data: TNodesInfo): NodesHandledResponse => {
|
|
50
50
|
const rawNodes = data.Nodes || [];
|
51
51
|
|
52
52
|
const preparedNodes = rawNodes.map((node) => {
|
53
|
+
// 0 limit means that limit is not set, so it should be undefined
|
54
|
+
const sharedCacheLimit = Number(node.SystemState.SharedCacheStats?.LimitBytes) || undefined;
|
55
|
+
|
53
56
|
return {
|
54
57
|
...node.SystemState,
|
55
58
|
Tablets: node.Tablets,
|
56
59
|
NodeId: node.NodeId,
|
57
60
|
Uptime: calcUptime(node.SystemState?.StartTime),
|
58
61
|
TenantName: node.SystemState?.Tenants?.[0],
|
62
|
+
|
63
|
+
SharedCacheUsed: node.SystemState.SharedCacheStats?.UsedBytes,
|
64
|
+
SharedCacheLimit: sharedCacheLimit,
|
59
65
|
};
|
60
66
|
});
|
61
67
|
|
@@ -16,6 +16,7 @@ import {
|
|
16
16
|
USE_BACKEND_PARAMS_FOR_TABLES_KEY,
|
17
17
|
LANGUAGE_KEY,
|
18
18
|
DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS,
|
19
|
+
QUERY_USE_MULTI_SCHEMA_KEY,
|
19
20
|
} from '../../../utils/constants';
|
20
21
|
import '../../../services/api';
|
21
22
|
import {parseJson} from '../../../utils/utils';
|
@@ -50,15 +51,16 @@ export const initialState = {
|
|
50
51
|
[INVERTED_DISKS_KEY]: readSavedSettingsValue(INVERTED_DISKS_KEY, 'false'),
|
51
52
|
[USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY]: readSavedSettingsValue(
|
52
53
|
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
|
53
|
-
'
|
54
|
+
'false',
|
54
55
|
),
|
55
56
|
[ENABLE_ADDITIONAL_QUERY_MODES]: readSavedSettingsValue(
|
56
57
|
ENABLE_ADDITIONAL_QUERY_MODES,
|
57
|
-
'
|
58
|
+
'true',
|
58
59
|
),
|
60
|
+
[QUERY_USE_MULTI_SCHEMA_KEY]: readSavedSettingsValue(QUERY_USE_MULTI_SCHEMA_KEY, 'false'),
|
59
61
|
[DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS]: readSavedSettingsValue(
|
60
62
|
DISPLAY_METRICS_CARDS_FOR_TENANT_DIAGNOSTICS,
|
61
|
-
'
|
63
|
+
'true',
|
62
64
|
),
|
63
65
|
[SAVED_QUERIES_KEY]: readSavedSettingsValue(SAVED_QUERIES_KEY, '[]'),
|
64
66
|
[TENANT_INITIAL_PAGE_KEY]: readSavedSettingsValue(
|
package/dist/types/api/nodes.ts
CHANGED
@@ -26,6 +26,9 @@ export interface TNodeInfo {
|
|
26
26
|
Tablets?: TTabletStateInfo[];
|
27
27
|
}
|
28
28
|
|
29
|
+
/**
|
30
|
+
* source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/node_whiteboard.proto
|
31
|
+
*/
|
29
32
|
export interface TSystemStateInfo {
|
30
33
|
/** uint64 */
|
31
34
|
StartTime?: string;
|
@@ -62,6 +65,20 @@ export interface TSystemStateInfo {
|
|
62
65
|
/** double */
|
63
66
|
MaxDiskUsage?: number;
|
64
67
|
Location?: TNodeLocation;
|
68
|
+
|
69
|
+
/**
|
70
|
+
* int64
|
71
|
+
*
|
72
|
+
* a positive value means the peer is ahead in time; a negative value means it's behind
|
73
|
+
*/
|
74
|
+
MaxClockSkewWithPeerUs?: string;
|
75
|
+
MaxClockSkewPeerId?: number;
|
76
|
+
|
77
|
+
/** uint64 */
|
78
|
+
DisconnectTime?: string;
|
79
|
+
|
80
|
+
SharedCacheStats?: TNodeSharedCache;
|
81
|
+
TotalSessions?: number;
|
65
82
|
}
|
66
83
|
|
67
84
|
export interface TPoolStats {
|
@@ -97,6 +114,13 @@ interface TNodeLocation {
|
|
97
114
|
Unit?: string;
|
98
115
|
}
|
99
116
|
|
117
|
+
interface TNodeSharedCache {
|
118
|
+
/** uint64 */
|
119
|
+
UsedBytes: string;
|
120
|
+
/** uint64 */
|
121
|
+
LimitBytes: string;
|
122
|
+
}
|
123
|
+
|
100
124
|
enum EConfigState {
|
101
125
|
'Consistent' = 'Consistent',
|
102
126
|
'Outdated' = 'Outdated',
|