ydb-embedded-ui 1.14.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +42 -0
- package/dist/assets/illustrations/dark/thumbsUp.svg +15 -0
- package/dist/assets/illustrations/light/thumbsUp.svg +15 -0
- package/dist/components/AsideNavigation/AsideHeader.tsx +1 -1
- package/dist/components/AsideNavigation/AsideHeaderFooterItem/AsideHeaderFooterItem.tsx +1 -1
- package/dist/components/AsideNavigation/AsideHeaderTooltip/AsideHeaderTooltip.tsx +1 -1
- package/dist/components/AsideNavigation/CompositeBar/CompositeBar.tsx +1 -1
- package/dist/components/AsideNavigation/Logo/Logo.tsx +1 -1
- package/dist/components/AsideNavigation/Settings/Settings.tsx +1 -1
- package/dist/components/AsideNavigation/Settings/SettingsMenu/SettingsMenu.tsx +1 -1
- package/dist/components/AsideNavigation/Settings/SettingsSearch/SettingsSearch.tsx +1 -1
- package/dist/components/AsideNavigation/Settings/collect-settings.ts +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.js +1 -1
- package/dist/components/ClusterInfo/ClusterInfo.tsx +1 -1
- package/dist/components/Collapse/Collapse.js +1 -1
- package/dist/components/CopyToClipboard/CopyToClipboard.tsx +1 -1
- package/dist/components/CriticalActionDialog/CriticalActionDialog.js +1 -1
- package/dist/components/EmptyState/EmptyState.scss +0 -1
- package/dist/components/EnableFullscreenButton/EnableFullscreenButton.tsx +1 -1
- package/dist/components/EntityStatus/EntityStatus.js +28 -3
- package/dist/components/EntityStatus/EntityStatus.scss +22 -1
- package/dist/components/Fullscreen/Fullscreen.tsx +1 -1
- package/dist/components/Icon/Icon.js +1 -1
- package/dist/components/Illustration/Illustration.tsx +3 -1
- package/dist/components/Loader/Loader.tsx +1 -1
- package/dist/components/NodesViewer/NodesViewer.js +5 -2
- package/dist/components/Pagination/Pagination.js +1 -1
- package/dist/components/ProblemFilter/ProblemFilter.js +1 -1
- package/dist/components/ShortyString/ShortyString.tsx +1 -1
- package/dist/components/TableSkeleton/TableSkeleton.tsx +1 -1
- package/dist/components/TabletsOverall/TabletsOverall.tsx +1 -1
- package/dist/containers/App/App.js +1 -1
- package/dist/containers/App/App.scss +0 -10
- package/dist/containers/App/Content.js +1 -1
- package/dist/containers/App/TipPopup/TipPopup.js +1 -1
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +1 -1
- package/dist/containers/Authentication/Authentication.tsx +1 -1
- package/dist/containers/Group/Group.js +1 -1
- package/dist/containers/Header/Header.tsx +1 -1
- package/dist/containers/Header/Host/Host.js +1 -1
- package/dist/containers/Heatmap/Heatmap.js +1 -1
- package/dist/containers/Node/Node.tsx +1 -1
- package/dist/containers/Node/NodeStructure/Pdisk.tsx +1 -1
- package/dist/containers/Nodes/Nodes.js +4 -2
- package/dist/containers/Pdisk/Pdisk.js +1 -1
- package/dist/containers/Pool/Pool.js +3 -2
- package/dist/containers/ReduxTooltip/ReduxTooltip.js +1 -1
- package/dist/containers/Storage/EmptyFilter/EmptyFilter.tsx +34 -0
- package/dist/containers/Storage/EmptyFilter/i18n/en.json +4 -0
- package/dist/containers/Storage/EmptyFilter/i18n/index.ts +11 -0
- package/dist/containers/Storage/EmptyFilter/i18n/ru.json +4 -0
- package/dist/containers/Storage/Pdisk/Pdisk.tsx +1 -1
- package/dist/containers/Storage/Storage.js +3 -1
- package/dist/containers/Storage/StorageFilter/StorageFilter.tsx +2 -1
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +27 -6
- package/dist/containers/Storage/StorageGroups/i18n/en.json +6 -0
- package/dist/containers/Storage/StorageGroups/i18n/index.ts +11 -0
- package/dist/containers/Storage/StorageGroups/i18n/ru.json +6 -0
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +24 -7
- package/dist/containers/Storage/StorageNodes/i18n/en.json +6 -0
- package/dist/containers/Storage/StorageNodes/i18n/index.ts +11 -0
- package/dist/containers/Storage/StorageNodes/i18n/ru.json +6 -0
- package/dist/containers/Storage/UsageFilter/UsageFilter.tsx +1 -1
- package/dist/containers/Storage/Vdisk/Vdisk.js +1 -1
- package/dist/containers/Tablet/Tablet.js +1 -1
- package/dist/containers/Tablets/Tablets.js +1 -1
- package/dist/containers/TabletsFilters/TabletsFilters.js +1 -1
- package/dist/containers/Tenant/Acl/Acl.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Compute/Compute.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Describe/Describe.js +1 -1
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +3 -4
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +1 -1
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.scss +7 -1
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.tsx +86 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuePreview/IssuePreview.tsx +34 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuePreview/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesList/IssuesList.tsx +69 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/IssuesList/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Preview/Preview.tsx +80 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Preview/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/i18n/en.json +11 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/i18n/index.ts +11 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/i18n/ru.json +11 -0
- package/dist/containers/Tenant/Diagnostics/Healthcheck/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Network/Network.js +3 -2
- package/dist/containers/Tenant/Diagnostics/Network/Network.scss +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +17 -35
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +1 -1
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +3 -3
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +3 -3
- package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +1 -1
- package/dist/containers/Tenant/ObjectGeneralTabs/ObjectGeneralTabs.tsx +1 -1
- package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +1 -1
- package/dist/containers/Tenant/Preview/Preview.js +1 -1
- package/dist/containers/Tenant/QueryEditor/Issues/Issues.scss +2 -3
- package/dist/containers/Tenant/QueryEditor/Issues/Issues.tsx +1 -1
- package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.tsx +1 -1
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +2 -2
- package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +63 -45
- package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.scss +8 -4
- package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.js +1 -1
- package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.scss +1 -0
- package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.js +1 -1
- package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.js +1 -1
- package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.scss +2 -2
- package/dist/containers/Tenant/utils/paneVisibilityToggleHelpers.tsx +1 -1
- package/dist/containers/Tenants/Tenants.js +4 -2
- package/dist/containers/UserSettings/UserSettings.tsx +2 -2
- package/dist/containers/Vdisk/Vdisk.js +1 -1
- package/dist/containers/VdiskPdiskNode/VdiskPdiskNode.js +1 -1
- package/dist/index.js +1 -1
- package/dist/services/api.d.ts +9 -0
- package/dist/setupTests.js +1 -1
- package/dist/store/reducers/executeTopQueries.js +6 -9
- package/dist/store/reducers/explainQuery.js +27 -36
- package/dist/store/reducers/olapStats.js +6 -8
- package/dist/store/reducers/shardsWorkload.js +6 -8
- package/dist/types/api/healthcheck.ts +91 -0
- package/dist/types/api/query.ts +32 -21
- package/dist/types/assets.d.ts +1 -1
- package/dist/types/store/healthcheck.ts +3 -0
- package/dist/types/store/query.ts +1 -1
- package/dist/utils/createToast.tsx +1 -1
- package/dist/utils/getNodesColumns.js +1 -1
- package/dist/utils/hooks/index.ts +1 -0
- package/dist/utils/hooks/useAutofetcher.ts +29 -0
- package/dist/utils/i18n/i18n.ts +1 -1
- package/dist/utils/prepareQueryExplain.ts +0 -4
- package/dist/utils/query.test.ts +59 -1
- package/dist/utils/query.ts +38 -4
- package/package.json +9 -11
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.js +0 -195
@@ -1,7 +1,7 @@
|
|
1
|
-
import React, {useEffect, useState} from 'react';
|
1
|
+
import React, {useEffect, useRef, useState} from 'react';
|
2
2
|
import cn from 'bem-cn-lite';
|
3
3
|
import MonacoEditor from 'react-monaco-editor';
|
4
|
-
import {Loader, RadioButton} from '@
|
4
|
+
import {Loader, RadioButton} from '@gravity-ui/uikit';
|
5
5
|
import JSONTree from 'react-json-inspector';
|
6
6
|
import {LANGUAGE_S_EXPRESSION_ID} from '../../../../utils/monaco';
|
7
7
|
import {
|
@@ -62,18 +62,25 @@ const explainOptions = [
|
|
62
62
|
];
|
63
63
|
|
64
64
|
function GraphRoot(props) {
|
65
|
-
|
66
|
-
|
65
|
+
const paranoid = useRef();
|
66
|
+
|
67
|
+
const render = () => {
|
67
68
|
const {data, opts, shapes, version} = props;
|
69
|
+
|
68
70
|
if (version === explainVersions.v2) {
|
69
|
-
paranoid = getTopology('graphRoot',
|
70
|
-
paranoid.render();
|
71
|
+
paranoid.current = getTopology('graphRoot', data, opts, shapes);
|
72
|
+
paranoid.current.render();
|
71
73
|
} else if (version === explainVersions.v1) {
|
72
|
-
paranoid = getCompactTopology('graphRoot', data, opts);
|
73
|
-
paranoid.renderCompactTopology();
|
74
|
+
paranoid.current = getCompactTopology('graphRoot', data, opts);
|
75
|
+
paranoid.current.renderCompactTopology();
|
74
76
|
}
|
77
|
+
}
|
78
|
+
|
79
|
+
useEffect(() => {
|
80
|
+
render();
|
81
|
+
|
75
82
|
return () => {
|
76
|
-
paranoid = undefined;
|
83
|
+
paranoid.current = undefined;
|
77
84
|
};
|
78
85
|
}, []);
|
79
86
|
|
@@ -86,13 +93,11 @@ function GraphRoot(props) {
|
|
86
93
|
|
87
94
|
graphRoot.innerHTML = '';
|
88
95
|
|
89
|
-
|
90
|
-
paranoid = getCompactTopology('graphRoot', data, opts);
|
91
|
-
paranoid.renderCompactTopology();
|
96
|
+
render();
|
92
97
|
}, [props.opts.colors]);
|
93
98
|
|
94
99
|
useEffect(() => {
|
95
|
-
paranoid?.updateData(props.data);
|
100
|
+
paranoid.current?.updateData?.(props.data);
|
96
101
|
}, [props.data]);
|
97
102
|
|
98
103
|
return <div id="graphRoot" style={{height: '100vh'}} />;
|
@@ -110,9 +115,6 @@ function QueryExplain(props) {
|
|
110
115
|
};
|
111
116
|
}, []);
|
112
117
|
|
113
|
-
const {explain = {}, theme} = props;
|
114
|
-
const {links, nodes, version, graphDepth} = explain;
|
115
|
-
|
116
118
|
useEffect(() => {
|
117
119
|
if (!props.ast && activeOption === ExplainOptionIds.ast) {
|
118
120
|
props.astQuery();
|
@@ -132,14 +134,24 @@ function QueryExplain(props) {
|
|
132
134
|
};
|
133
135
|
|
134
136
|
const renderStub = () => {
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
137
|
+
return (
|
138
|
+
<div className={b('text-message')}>
|
139
|
+
There is no explanation for the request
|
140
|
+
</div>
|
141
|
+
);
|
142
|
+
};
|
143
|
+
|
144
|
+
const hasContent = () => {
|
145
|
+
switch (activeOption) {
|
146
|
+
case ExplainOptionIds.schema:
|
147
|
+
return Boolean(props.explain?.nodes?.length);
|
148
|
+
case ExplainOptionIds.json:
|
149
|
+
return Boolean(props.explain);
|
150
|
+
case ExplainOptionIds.ast:
|
151
|
+
return Boolean(props.ast);
|
152
|
+
default:
|
153
|
+
return false;
|
141
154
|
}
|
142
|
-
return null;
|
143
155
|
};
|
144
156
|
|
145
157
|
const renderTextExplain = () => {
|
@@ -153,23 +165,16 @@ function QueryExplain(props) {
|
|
153
165
|
}}
|
154
166
|
/>
|
155
167
|
);
|
168
|
+
|
156
169
|
return (
|
157
170
|
<React.Fragment>
|
158
171
|
{content}
|
159
|
-
{
|
160
|
-
{isFullscreen && (
|
161
|
-
<Fullscreen>
|
162
|
-
<div className={b('inspector', {fullscreen: true})}>{content}</div>
|
163
|
-
</Fullscreen>
|
164
|
-
)}
|
172
|
+
{isFullscreen && <Fullscreen>{content}</Fullscreen>}
|
165
173
|
</React.Fragment>
|
166
174
|
);
|
167
175
|
};
|
168
176
|
|
169
177
|
const renderAstExplain = () => {
|
170
|
-
if (!props.ast) {
|
171
|
-
return 'There is no AST explanation for the request';
|
172
|
-
}
|
173
178
|
const content = (
|
174
179
|
<div className={b('ast')}>
|
175
180
|
<MonacoEditor
|
@@ -189,19 +194,14 @@ function QueryExplain(props) {
|
|
189
194
|
};
|
190
195
|
|
191
196
|
const renderGraph = () => {
|
192
|
-
const
|
193
|
-
|
197
|
+
const {explain = {}, theme} = props;
|
198
|
+
const {links, nodes, version} = explain;
|
194
199
|
const content =
|
195
200
|
links && nodes && nodes.length ? (
|
196
201
|
<div
|
197
202
|
className={b('explain-canvas-container', {
|
198
203
|
hidden: activeOption !== ExplainOptionIds.schema,
|
199
204
|
})}
|
200
|
-
style={{
|
201
|
-
height: isFullscreen ? '100%' : graphHeight,
|
202
|
-
minHeight: graphHeight,
|
203
|
-
width: '100%',
|
204
|
-
}}
|
205
205
|
>
|
206
206
|
<GraphRoot
|
207
207
|
version={version}
|
@@ -222,11 +222,28 @@ function QueryExplain(props) {
|
|
222
222
|
<React.Fragment>
|
223
223
|
{!isFullscreen && content}
|
224
224
|
{isFullscreen && <Fullscreen>{content}</Fullscreen>}
|
225
|
-
{renderStub()}
|
226
225
|
</React.Fragment>
|
227
226
|
);
|
228
227
|
};
|
229
228
|
|
229
|
+
const renderError = () => {
|
230
|
+
const {error} = props;
|
231
|
+
|
232
|
+
let message;
|
233
|
+
|
234
|
+
if (error.data) {
|
235
|
+
message = typeof error.data === 'string' ? error.data : error.data.error?.message;
|
236
|
+
} else {
|
237
|
+
message = error;
|
238
|
+
}
|
239
|
+
|
240
|
+
return (
|
241
|
+
<div className={b('text-message')}>
|
242
|
+
{message}
|
243
|
+
</div>
|
244
|
+
);
|
245
|
+
};
|
246
|
+
|
230
247
|
const renderContent = () => {
|
231
248
|
const {error, loading, loadingAst} = props;
|
232
249
|
if (loading || loadingAst) {
|
@@ -234,10 +251,11 @@ function QueryExplain(props) {
|
|
234
251
|
}
|
235
252
|
|
236
253
|
if (error) {
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
254
|
+
return renderError();
|
255
|
+
}
|
256
|
+
|
257
|
+
if (!hasContent()) {
|
258
|
+
return renderStub();
|
241
259
|
}
|
242
260
|
|
243
261
|
switch (activeOption) {
|
@@ -274,7 +292,7 @@ function QueryExplain(props) {
|
|
274
292
|
)}
|
275
293
|
</div>
|
276
294
|
<div className={b('controls-left')}>
|
277
|
-
<EnableFullscreenButton disabled={Boolean(props.error)} />
|
295
|
+
<EnableFullscreenButton disabled={Boolean(props.error) || !hasContent()} />
|
278
296
|
<PaneVisibilityToggleButtons
|
279
297
|
onCollapse={props.onCollapseResults}
|
280
298
|
onExpand={props.onExpandResults}
|
@@ -6,8 +6,9 @@
|
|
6
6
|
overflow: auto;
|
7
7
|
flex-grow: 1;
|
8
8
|
flex-direction: column;
|
9
|
-
|
10
|
-
|
9
|
+
}
|
10
|
+
&__text-message {
|
11
|
+
padding: 15px 20px;
|
11
12
|
}
|
12
13
|
&__controls {
|
13
14
|
position: sticky;
|
@@ -40,7 +41,8 @@
|
|
40
41
|
&__explain-canvas-container {
|
41
42
|
overflow-y: auto;
|
42
43
|
|
43
|
-
|
44
|
+
width: 100%;
|
45
|
+
height: 100%;
|
44
46
|
&_hidden {
|
45
47
|
display: none;
|
46
48
|
}
|
@@ -49,6 +51,7 @@
|
|
49
51
|
overflow-y: auto;
|
50
52
|
|
51
53
|
width: 100%;
|
54
|
+
padding: 15px 20px;
|
52
55
|
@include json-tree-styles();
|
53
56
|
&
|
54
57
|
.json-inspector__leaf.json-inspector__leaf_root.json-inspector__leaf_expanded.json-inspector__leaf_composite {
|
@@ -61,9 +64,10 @@
|
|
61
64
|
}
|
62
65
|
|
63
66
|
&__ast {
|
67
|
+
overflow: hidden;
|
68
|
+
|
64
69
|
width: 100%;
|
65
70
|
height: 100%;
|
66
|
-
margin: 20px 0;
|
67
71
|
|
68
72
|
white-space: pre-wrap;
|
69
73
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React, {useEffect, useState} from 'react';
|
2
2
|
import {useDispatch, useSelector} from 'react-redux';
|
3
3
|
import cn from 'bem-cn-lite';
|
4
|
-
import {RadioButton} from '@
|
4
|
+
import {RadioButton} from '@gravity-ui/uikit';
|
5
5
|
import JSONTree from 'react-json-inspector';
|
6
6
|
|
7
7
|
import CopyToClipboard from '../../../../components/CopyToClipboard/CopyToClipboard';
|
@@ -2,7 +2,7 @@ import React, {useState} from 'react';
|
|
2
2
|
import _ from 'lodash';
|
3
3
|
import cn from 'bem-cn-lite';
|
4
4
|
import {useDispatch, useSelector} from 'react-redux';
|
5
|
-
import {Dialog, DropdownMenu, TextInput, Button} from '@
|
5
|
+
import {Dialog, DropdownMenu, TextInput, Button} from '@gravity-ui/uikit';
|
6
6
|
|
7
7
|
import {setQueryNameToEdit} from '../../../../store/reducers/saveQuery';
|
8
8
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React, {useRef, useState} from 'react';
|
2
2
|
import _ from 'lodash';
|
3
3
|
import cn from 'bem-cn-lite';
|
4
|
-
import {Dialog, Popup, Button} from '@
|
4
|
+
import {Dialog, Popup, Button} from '@gravity-ui/uikit';
|
5
5
|
|
6
6
|
import TruncatedQuery from '../../../../components/TruncatedQuery/TruncatedQuery';
|
7
7
|
import Icon from '../../../../components/Icon/Icon';
|
@@ -5,12 +5,13 @@ import {connect} from 'react-redux';
|
|
5
5
|
import _ from 'lodash';
|
6
6
|
|
7
7
|
import DataTable from '@yandex-cloud/react-data-table';
|
8
|
-
import {Loader, TextInput, Button} from '@
|
8
|
+
import {Loader, TextInput, Button} from '@gravity-ui/uikit';
|
9
9
|
|
10
10
|
import EntityStatus from '../../components/EntityStatus/EntityStatus';
|
11
11
|
import PoolsGraph from '../../components/PoolsGraph/PoolsGraph';
|
12
12
|
import TabletsStatistic from '../../components/TabletsStatistic/TabletsStatistic';
|
13
13
|
import ProblemFilter, {problemFilterType} from '../../components/ProblemFilter/ProblemFilter';
|
14
|
+
import {Illustration} from '../../components/Illustration';
|
14
15
|
import {AutoFetcher} from '../../utils/autofetcher';
|
15
16
|
|
16
17
|
import routes, {CLUSTER_PAGES, createHref} from '../../routes';
|
@@ -97,6 +98,7 @@ class Tenants extends React.Component {
|
|
97
98
|
text={searchQuery}
|
98
99
|
onUpdate={handleSearchQuery}
|
99
100
|
hasClear
|
101
|
+
autoFocus
|
100
102
|
/>
|
101
103
|
<ProblemFilter value={filter} onChange={changeFilter} />
|
102
104
|
</div>
|
@@ -309,7 +311,7 @@ class Tenants extends React.Component {
|
|
309
311
|
];
|
310
312
|
|
311
313
|
if (filteredTenants.length === 0 && filter !== ALL) {
|
312
|
-
return <
|
314
|
+
return <Illustration name="thumbsUp" width="200" />;
|
313
315
|
}
|
314
316
|
|
315
317
|
return (
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import {connect} from 'react-redux';
|
2
2
|
|
3
|
-
import {RadioButton, Switch} from '@
|
3
|
+
import {RadioButton, Switch} from '@gravity-ui/uikit';
|
4
4
|
import {Settings} from '../../components/AsideNavigation/Settings';
|
5
5
|
import favoriteFilledIcon from '../../assets/icons/star.svg';
|
6
6
|
import flaskIcon from '../../assets/icons/flask.svg';
|
@@ -21,7 +21,7 @@ function UserSettings(props: any) {
|
|
21
21
|
};
|
22
22
|
|
23
23
|
const _onInvertedDisksChangeHandler = (value: boolean) => {
|
24
|
-
props.setSettingValue(INVERTED_DISKS_KEY, value);
|
24
|
+
props.setSettingValue(INVERTED_DISKS_KEY, String(value));
|
25
25
|
};
|
26
26
|
|
27
27
|
return (
|
@@ -4,7 +4,7 @@ import cn from 'bem-cn-lite';
|
|
4
4
|
import {connect} from 'react-redux';
|
5
5
|
|
6
6
|
import {Link} from 'react-router-dom';
|
7
|
-
import {Loader} from '@
|
7
|
+
import {Loader} from '@gravity-ui/uikit';
|
8
8
|
|
9
9
|
import InfoViewer from '../../components/InfoViewer/InfoViewer';
|
10
10
|
import EntityStatus from '../../components/EntityStatus/EntityStatus';
|
@@ -5,7 +5,7 @@ import {connect} from 'react-redux';
|
|
5
5
|
import _ from 'lodash';
|
6
6
|
|
7
7
|
import {Link} from 'react-router-dom';
|
8
|
-
import {Loader} from '@
|
8
|
+
import {Loader} from '@gravity-ui/uikit';
|
9
9
|
|
10
10
|
import InfoViewer from '../../components/InfoViewer/InfoViewer';
|
11
11
|
import EntityStatus from '../../components/EntityStatus/EntityStatus';
|
package/dist/index.js
CHANGED
@@ -5,7 +5,7 @@ import App from './containers/App/App';
|
|
5
5
|
import {Provider} from 'react-redux';
|
6
6
|
import configureStore from './store';
|
7
7
|
import reportWebVitals from './reportWebVitals';
|
8
|
-
import '@
|
8
|
+
import '@gravity-ui/uikit/styles/styles.scss';
|
9
9
|
import HistoryContext from './contexts/HistoryContext';
|
10
10
|
|
11
11
|
const {store, history} = configureStore();
|
package/dist/services/api.d.ts
CHANGED
@@ -30,6 +30,15 @@ interface Window {
|
|
30
30
|
},
|
31
31
|
axiosOptions?: AxiosOptions,
|
32
32
|
) => Promise<import('../types/api/query').QueryAPIResponse<Action, Schema>>;
|
33
|
+
getExplainQuery: (
|
34
|
+
query: string,
|
35
|
+
database: string,
|
36
|
+
) => Promise<import('../types/api/query').QueryAPIExplainResponse<'explain'>>;
|
37
|
+
getExplainQueryAst: (
|
38
|
+
query: string,
|
39
|
+
database: string,
|
40
|
+
) => Promise<import('../types/api/query').QueryAPIExplainResponse<'explain-ast'>>;
|
41
|
+
getHealthcheckInfo: (database: string) => Promise<import('../types/api/healthcheck').HealthCheckAPIResponse>,
|
33
42
|
[method: string]: Function;
|
34
43
|
};
|
35
44
|
}
|
package/dist/setupTests.js
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
// learn more: https://github.com/testing-library/jest-dom
|
5
5
|
import '@testing-library/jest-dom';
|
6
6
|
|
7
|
-
import {configure as configureUiKit} from '@
|
7
|
+
import {configure as configureUiKit} from '@gravity-ui/uikit';
|
8
8
|
import {configure as configureYdbUiComponents} from 'ydb-ui-components';
|
9
9
|
import {i18n, Lang} from '../src/utils/i18n';
|
10
10
|
|
@@ -1,6 +1,9 @@
|
|
1
|
-
import {createRequestActionTypes, createApiRequest} from '../utils';
|
2
1
|
import '../../services/api';
|
3
2
|
|
3
|
+
import {parseQueryAPIExecuteResponse} from '../../utils/query';
|
4
|
+
|
5
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
6
|
+
|
4
7
|
const SEND_QUERY = createRequestActionTypes('top-queries', 'SEND_QUERY');
|
5
8
|
const SET_QUERY_OPTIONS = createRequestActionTypes('top-queries', 'SET_QUERY_OPTIONS');
|
6
9
|
|
@@ -47,15 +50,9 @@ const executeTopQueries = (state = initialState, action) => {
|
|
47
50
|
|
48
51
|
export const sendQuery = ({query, database, action}) => {
|
49
52
|
return createApiRequest({
|
50
|
-
request: window.api.sendQuery({query, database, action}),
|
53
|
+
request: window.api.sendQuery({schema: 'modern', query, database, action}),
|
51
54
|
actions: SEND_QUERY,
|
52
|
-
dataHandler:
|
53
|
-
if (result && typeof result === 'string') {
|
54
|
-
throw 'Unexpected token in JSON.';
|
55
|
-
}
|
56
|
-
|
57
|
-
return result;
|
58
|
-
},
|
55
|
+
dataHandler: parseQueryAPIExecuteResponse,
|
59
56
|
});
|
60
57
|
};
|
61
58
|
|
@@ -1,8 +1,12 @@
|
|
1
|
-
import {createRequestActionTypes, createApiRequest} from '../utils';
|
2
|
-
import '../../services/api';
|
3
1
|
import _ from 'lodash';
|
2
|
+
|
3
|
+
import '../../services/api';
|
4
|
+
|
4
5
|
import {getExplainNodeId, getMetaForExplainNode} from '../../utils';
|
5
6
|
import {preparePlan} from '../../utils/prepareQueryExplain';
|
7
|
+
import {parseQueryAPIExplainResponse} from '../../utils/query';
|
8
|
+
|
9
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
6
10
|
|
7
11
|
const GET_EXPLAIN_QUERY = createRequestActionTypes('query', 'GET_EXPLAIN_QUERY');
|
8
12
|
const GET_EXPLAIN_QUERY_AST = createRequestActionTypes('query', 'GET_EXPLAIN_QUERY_AST');
|
@@ -26,7 +30,8 @@ const explainQuery = (state = initialState, action) => {
|
|
26
30
|
case GET_EXPLAIN_QUERY.SUCCESS: {
|
27
31
|
return {
|
28
32
|
...state,
|
29
|
-
data: action.data,
|
33
|
+
data: action.data.plan,
|
34
|
+
dataAst: action.data.ast,
|
30
35
|
loading: false,
|
31
36
|
error: undefined,
|
32
37
|
};
|
@@ -50,7 +55,7 @@ const explainQuery = (state = initialState, action) => {
|
|
50
55
|
case GET_EXPLAIN_QUERY_AST.SUCCESS: {
|
51
56
|
return {
|
52
57
|
...state,
|
53
|
-
dataAst: action.data,
|
58
|
+
dataAst: action.data.ast,
|
54
59
|
loadingAst: false,
|
55
60
|
error: undefined,
|
56
61
|
};
|
@@ -72,9 +77,7 @@ export const getExplainQueryAst = ({query, database}) => {
|
|
72
77
|
return createApiRequest({
|
73
78
|
request: window.api.getExplainQueryAst(query, database),
|
74
79
|
actions: GET_EXPLAIN_QUERY_AST,
|
75
|
-
dataHandler:
|
76
|
-
return result && result.ast ? result.ast : result;
|
77
|
-
},
|
80
|
+
dataHandler: parseQueryAPIExplainResponse,
|
78
81
|
});
|
79
82
|
};
|
80
83
|
|
@@ -89,11 +92,15 @@ export const getExplainQuery = ({query, database}) => {
|
|
89
92
|
return createApiRequest({
|
90
93
|
request: window.api.getExplainQuery(query, database),
|
91
94
|
actions: GET_EXPLAIN_QUERY,
|
92
|
-
dataHandler: (
|
93
|
-
|
95
|
+
dataHandler: (response) => {
|
96
|
+
const {plan: result, ast} = parseQueryAPIExplainResponse(response);
|
97
|
+
|
98
|
+
if (!result) {
|
99
|
+
return {ast};
|
100
|
+
}
|
101
|
+
|
94
102
|
let links = [];
|
95
103
|
let nodes = [];
|
96
|
-
let graphDepth;
|
97
104
|
const {tables, meta, Plan} = result;
|
98
105
|
|
99
106
|
if (supportedExplainQueryVersions.indexOf(meta.version) === -1) {
|
@@ -106,9 +113,7 @@ export const getExplainQuery = ({query, database}) => {
|
|
106
113
|
const preparedPlan = preparePlan(Plan);
|
107
114
|
links = preparedPlan.links;
|
108
115
|
nodes = preparedPlan.nodes;
|
109
|
-
graphDepth = preparedPlan.graphDepth;
|
110
116
|
} else {
|
111
|
-
graphDepth = tables.length;
|
112
117
|
_.forEach(tables, (table) => {
|
113
118
|
nodes.push({
|
114
119
|
name: table.name,
|
@@ -117,7 +122,7 @@ export const getExplainQuery = ({query, database}) => {
|
|
117
122
|
const tableTypes = {};
|
118
123
|
|
119
124
|
const {reads = [], writes = []} = table;
|
120
|
-
let
|
125
|
+
let prevNodeId = table.name;
|
121
126
|
|
122
127
|
_.forEach([...reads, ...writes], (node) => {
|
123
128
|
if (tableTypes[node.type]) {
|
@@ -132,22 +137,6 @@ export const getExplainQuery = ({query, database}) => {
|
|
132
137
|
tableTypes[node.type],
|
133
138
|
);
|
134
139
|
|
135
|
-
let prevNodeId = table.name;
|
136
|
-
if (prevEl) {
|
137
|
-
prevNodeId =
|
138
|
-
node.type === prevEl.type
|
139
|
-
? getExplainNodeId(
|
140
|
-
table.name,
|
141
|
-
prevEl.type,
|
142
|
-
tableTypes[prevEl.type] - 1,
|
143
|
-
)
|
144
|
-
: getExplainNodeId(
|
145
|
-
table.name,
|
146
|
-
prevEl.type,
|
147
|
-
tableTypes[prevEl.type],
|
148
|
-
);
|
149
|
-
}
|
150
|
-
|
151
140
|
links.push({
|
152
141
|
from: prevNodeId,
|
153
142
|
to: nodeId,
|
@@ -158,18 +147,20 @@ export const getExplainQuery = ({query, database}) => {
|
|
158
147
|
id: nodeId,
|
159
148
|
});
|
160
149
|
|
161
|
-
|
150
|
+
prevNodeId = nodeId;
|
162
151
|
});
|
163
152
|
});
|
164
153
|
}
|
165
154
|
|
166
155
|
return {
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
156
|
+
plan: {
|
157
|
+
links,
|
158
|
+
nodes,
|
159
|
+
tables,
|
160
|
+
version: meta.version,
|
161
|
+
pristine: result,
|
162
|
+
},
|
163
|
+
ast,
|
173
164
|
};
|
174
165
|
},
|
175
166
|
});
|
@@ -1,6 +1,9 @@
|
|
1
|
-
import {createRequestActionTypes, createApiRequest} from '../utils';
|
2
1
|
import '../../services/api';
|
3
2
|
|
3
|
+
import {parseQueryAPIExecuteResponse} from '../../utils/query';
|
4
|
+
|
5
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
6
|
+
|
4
7
|
const FETCH_OLAP_STATS = createRequestActionTypes('query', 'SEND_OLAP_STATS_QUERY');
|
5
8
|
const SET_OLAP_STATS_OPTIONS = createRequestActionTypes('query', 'SET_OLAP_STATS_OPTIONS');
|
6
9
|
|
@@ -53,18 +56,13 @@ const olapStats = (state = initialState, action) => {
|
|
53
56
|
export const getOlapStats = ({path = ''}) => {
|
54
57
|
return createApiRequest({
|
55
58
|
request: window.api.sendQuery({
|
59
|
+
schema: 'modern',
|
56
60
|
query: createOlatStatsQuery(path),
|
57
61
|
database: path,
|
58
62
|
action: queryAction,
|
59
63
|
}),
|
60
64
|
actions: FETCH_OLAP_STATS,
|
61
|
-
dataHandler:
|
62
|
-
if (result && typeof result === 'string') {
|
63
|
-
throw 'Unexpected token in JSON.';
|
64
|
-
}
|
65
|
-
|
66
|
-
return result;
|
67
|
-
},
|
65
|
+
dataHandler: parseQueryAPIExecuteResponse,
|
68
66
|
});
|
69
67
|
};
|
70
68
|
|
@@ -1,6 +1,9 @@
|
|
1
|
-
import {createRequestActionTypes, createApiRequest} from '../utils';
|
2
1
|
import '../../services/api';
|
3
2
|
|
3
|
+
import {parseQueryAPIExecuteResponse} from '../../utils/query';
|
4
|
+
|
5
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
6
|
+
|
4
7
|
const SEND_SHARD_QUERY = createRequestActionTypes('query', 'SEND_SHARD_QUERY');
|
5
8
|
const SET_SHARD_QUERY_OPTIONS = 'query/SET_SHARD_QUERY_OPTIONS';
|
6
9
|
|
@@ -76,6 +79,7 @@ const shardsWorkload = (state = initialState, action) => {
|
|
76
79
|
export const sendShardQuery = ({database, path = '', sortOrder}) => {
|
77
80
|
return createApiRequest({
|
78
81
|
request: window.api.sendQuery({
|
82
|
+
schema: 'modern',
|
79
83
|
query: createShardQuery(path, sortOrder, database),
|
80
84
|
database,
|
81
85
|
action: queryAction,
|
@@ -83,13 +87,7 @@ export const sendShardQuery = ({database, path = '', sortOrder}) => {
|
|
83
87
|
concurrentId: 'topShards',
|
84
88
|
}),
|
85
89
|
actions: SEND_SHARD_QUERY,
|
86
|
-
dataHandler:
|
87
|
-
if (result && typeof result === 'string') {
|
88
|
-
throw 'Unexpected token in JSON.';
|
89
|
-
}
|
90
|
-
|
91
|
-
return result;
|
92
|
-
},
|
90
|
+
dataHandler: parseQueryAPIExecuteResponse,
|
93
91
|
});
|
94
92
|
};
|
95
93
|
|