ydb-embedded-ui 3.4.5 → 4.0.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 +41 -0
- package/dist/components/InfoViewer/formatters/table.ts +6 -0
- package/dist/components/TruncatedQuery/TruncatedQuery.js +1 -1
- package/dist/components/TruncatedQuery/TruncatedQuery.scss +7 -3
- package/dist/containers/Node/{NodePages.js → NodePages.ts} +1 -1
- package/dist/containers/Tablet/TabletControls/TabletControls.tsx +2 -2
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +11 -43
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/TableInfo.tsx +19 -17
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo.ts +192 -37
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +20 -14
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +49 -12
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.tsx +37 -18
- package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.tsx +3 -3
- package/dist/containers/Tenant/QueryEditor/QueryDuration/QueryDuration.scss +8 -0
- package/dist/containers/Tenant/QueryEditor/QueryDuration/QueryDuration.tsx +21 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +58 -82
- package/dist/containers/Tenant/QueryEditor/QueryEditor.scss +0 -33
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/OldQueryEditorControls.tsx +83 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.scss +57 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.tsx +84 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/shared.ts +23 -0
- package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +12 -23
- package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.js +4 -6
- package/dist/containers/Tenant/QueryEditor/i18n/en.json +3 -0
- package/dist/containers/Tenant/QueryEditor/i18n/index.ts +11 -0
- package/dist/containers/Tenant/QueryEditor/i18n/ru.json +3 -0
- package/dist/containers/UserSettings/UserSettings.tsx +30 -1
- package/dist/routes.ts +1 -1
- package/dist/services/api.d.ts +4 -3
- package/dist/services/api.js +5 -5
- package/dist/store/reducers/{executeQuery.js → executeQuery.ts} +48 -43
- package/dist/store/reducers/executeTopQueries.ts +5 -1
- package/dist/store/reducers/{explainQuery.js → explainQuery.ts} +44 -59
- package/dist/store/reducers/{olapStats.js → olapStats.ts} +8 -18
- package/dist/store/reducers/settings.js +19 -4
- package/dist/store/reducers/storage.js +5 -7
- package/dist/types/api/error.ts +14 -0
- package/dist/types/api/query.ts +227 -115
- package/dist/types/api/schema.ts +523 -3
- package/dist/types/common.ts +1 -0
- package/dist/types/store/executeQuery.ts +38 -0
- package/dist/types/store/explainQuery.ts +38 -0
- package/dist/types/store/olapStats.ts +14 -0
- package/dist/types/store/query.ts +23 -3
- package/dist/utils/constants.ts +2 -1
- package/dist/utils/error.ts +25 -0
- package/dist/utils/index.js +0 -49
- package/dist/utils/prepareQueryExplain.ts +7 -24
- package/dist/utils/query.test.ts +148 -213
- package/dist/utils/query.ts +68 -90
- package/dist/utils/timeParsers/formatDuration.ts +30 -12
- package/dist/utils/timeParsers/i18n/en.json +9 -5
- package/dist/utils/timeParsers/i18n/ru.json +9 -5
- package/dist/utils/timeParsers/parsers.ts +9 -0
- package/dist/utils/utils.js +1 -2
- package/package.json +1 -1
@@ -1,5 +1,7 @@
|
|
1
1
|
import {useCallback, useEffect, useRef, useState} from 'react';
|
2
2
|
import {useDispatch} from 'react-redux';
|
3
|
+
import {useHistory, useLocation} from 'react-router';
|
4
|
+
import qs from 'qs';
|
3
5
|
import cn from 'bem-cn-lite';
|
4
6
|
|
5
7
|
import DataTable, {Column, Settings} from '@gravity-ui/react-data-table';
|
@@ -21,13 +23,14 @@ import type {EPathType} from '../../../../types/api/schema';
|
|
21
23
|
import type {ITopQueriesFilters} from '../../../../types/store/executeTopQueries';
|
22
24
|
import type {IQueryResult} from '../../../../types/store/query';
|
23
25
|
|
24
|
-
import {formatDateTime} from '../../../../utils';
|
26
|
+
import {formatDateTime, formatNumber} from '../../../../utils';
|
25
27
|
import {DEFAULT_TABLE_SETTINGS, HOUR_IN_SECONDS} from '../../../../utils/constants';
|
26
28
|
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
|
27
29
|
import {prepareQueryError} from '../../../../utils/query';
|
30
|
+
import routes, {createHref} from '../../../../routes';
|
28
31
|
|
29
32
|
import {isColumnEntityType} from '../../utils/schema';
|
30
|
-
import {TenantGeneralTabsIds} from '../../TenantPages';
|
33
|
+
import {TenantGeneralTabsIds, TenantTabsGroups} from '../../TenantPages';
|
31
34
|
|
32
35
|
import i18n from './i18n';
|
33
36
|
import './TopQueries.scss';
|
@@ -43,19 +46,41 @@ const MAX_QUERY_HEIGHT = 10;
|
|
43
46
|
const COLUMNS: Column<KeyValueRow>[] = [
|
44
47
|
{
|
45
48
|
name: 'CPUTimeUs',
|
46
|
-
|
47
|
-
|
49
|
+
sortAccessor: (row) => Number(row.CPUTimeUs),
|
50
|
+
align: DataTable.RIGHT,
|
48
51
|
},
|
49
52
|
{
|
50
53
|
name: 'QueryText',
|
51
54
|
width: 500,
|
52
55
|
sortable: false,
|
53
|
-
render: ({
|
56
|
+
render: ({row}) => (
|
57
|
+
<div className={b('query')}>
|
58
|
+
<TruncatedQuery value={row.QueryText} maxQueryHeight={MAX_QUERY_HEIGHT} />
|
59
|
+
</div>
|
60
|
+
),
|
61
|
+
},
|
62
|
+
{
|
63
|
+
name: 'EndTime',
|
64
|
+
render: ({row}) => formatDateTime(new Date(row.EndTime as string).getTime()),
|
65
|
+
align: DataTable.RIGHT,
|
66
|
+
},
|
67
|
+
{
|
68
|
+
name: 'ReadRows',
|
69
|
+
render: ({row}) => formatNumber(row.ReadRows),
|
70
|
+
sortAccessor: (row) => Number(row.ReadRows),
|
71
|
+
align: DataTable.RIGHT,
|
72
|
+
},
|
73
|
+
{
|
74
|
+
name: 'ReadBytes',
|
75
|
+
render: ({row}) => formatNumber(row.ReadBytes),
|
76
|
+
sortAccessor: (row) => Number(row.ReadBytes),
|
77
|
+
align: DataTable.RIGHT,
|
54
78
|
},
|
55
79
|
{
|
56
|
-
name: '
|
57
|
-
|
58
|
-
|
80
|
+
name: 'UserSID',
|
81
|
+
render: ({row}) => <div className={b('user-sid')}>{row.UserSID || '–'}</div>,
|
82
|
+
sortAccessor: (row) => String(row.UserSID),
|
83
|
+
align: DataTable.LEFT,
|
59
84
|
},
|
60
85
|
];
|
61
86
|
|
@@ -65,8 +90,10 @@ interface TopQueriesProps {
|
|
65
90
|
type?: EPathType;
|
66
91
|
}
|
67
92
|
|
68
|
-
export const TopQueries = ({path, type
|
93
|
+
export const TopQueries = ({path, type}: TopQueriesProps) => {
|
69
94
|
const dispatch = useDispatch();
|
95
|
+
const location = useLocation();
|
96
|
+
const history = useHistory();
|
70
97
|
|
71
98
|
const {autorefresh} = useTypedSelector((state) => state.schema);
|
72
99
|
|
@@ -144,9 +171,19 @@ export const TopQueries = ({path, type, changeSchemaTab}: TopQueriesProps) => {
|
|
144
171
|
const {QueryText: input} = row;
|
145
172
|
|
146
173
|
dispatch(changeUserInput({input}));
|
147
|
-
|
174
|
+
|
175
|
+
const queryParams = qs.parse(location.search, {
|
176
|
+
ignoreQueryPrefix: true,
|
177
|
+
});
|
178
|
+
|
179
|
+
const queryPath = createHref(routes.tenant, undefined, {
|
180
|
+
...queryParams,
|
181
|
+
[TenantTabsGroups.general]: TenantGeneralTabsIds.query,
|
182
|
+
});
|
183
|
+
|
184
|
+
history.push(queryPath);
|
148
185
|
},
|
149
|
-
[
|
186
|
+
[dispatch, history, location],
|
150
187
|
);
|
151
188
|
|
152
189
|
const handleTextSearchUpdate = (text: string) => {
|
@@ -179,7 +216,7 @@ export const TopQueries = ({path, type, changeSchemaTab}: TopQueriesProps) => {
|
|
179
216
|
}
|
180
217
|
|
181
218
|
return (
|
182
|
-
<div className={b('
|
219
|
+
<div className={b('table')}>
|
183
220
|
<DataTable
|
184
221
|
columns={COLUMNS}
|
185
222
|
data={data}
|
@@ -20,6 +20,7 @@ import {setCurrentSchemaPath, getSchema} from '../../../../store/reducers/schema
|
|
20
20
|
import {EShardsWorkloadMode, IShardsWorkloadFilters} from '../../../../types/store/shardsWorkload';
|
21
21
|
|
22
22
|
import type {EPathType} from '../../../../types/api/schema';
|
23
|
+
import type {CellValue, KeyValueRow} from '../../../../types/api/query';
|
23
24
|
|
24
25
|
import {formatDateTime, formatNumber} from '../../../../utils';
|
25
26
|
import {DEFAULT_TABLE_SETTINGS, HOUR_IN_SECONDS} from '../../../../utils/constants';
|
@@ -57,10 +58,17 @@ const tableColumnsNames = {
|
|
57
58
|
IntervalEnd: 'IntervalEnd',
|
58
59
|
};
|
59
60
|
|
60
|
-
function prepareCPUWorkloadValue(value: string) {
|
61
|
+
function prepareCPUWorkloadValue(value: string | number) {
|
61
62
|
return `${(Number(value) * 100).toFixed(2)}%`;
|
62
63
|
}
|
63
64
|
|
65
|
+
function prepareDateTimeValue(value: CellValue) {
|
66
|
+
if (!value) {
|
67
|
+
return '–';
|
68
|
+
}
|
69
|
+
return formatDateTime(new Date(value).getTime());
|
70
|
+
}
|
71
|
+
|
64
72
|
function stringToDataTableSortOrder(value: string): SortOrder[] | undefined {
|
65
73
|
return value
|
66
74
|
? value.split(',').map((columnId) => ({
|
@@ -190,16 +198,17 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
190
198
|
};
|
191
199
|
};
|
192
200
|
|
193
|
-
const columns: Column<
|
201
|
+
const columns: Column<KeyValueRow>[] = [
|
194
202
|
{
|
195
203
|
name: tableColumnsNames.Path,
|
196
|
-
render: ({
|
204
|
+
render: ({row}) => {
|
205
|
+
// row.Path - relative schema path
|
197
206
|
return (
|
198
207
|
<span
|
199
|
-
onClick={onSchemaClick(tenantPath +
|
208
|
+
onClick={onSchemaClick(tenantPath + row.Path)}
|
200
209
|
className={bLink({view: 'normal'})}
|
201
210
|
>
|
202
|
-
{
|
211
|
+
{row.Path}
|
203
212
|
</span>
|
204
213
|
);
|
205
214
|
},
|
@@ -207,25 +216,28 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
207
216
|
},
|
208
217
|
{
|
209
218
|
name: tableColumnsNames.CPUCores,
|
210
|
-
render: ({
|
211
|
-
return prepareCPUWorkloadValue(
|
219
|
+
render: ({row}) => {
|
220
|
+
return prepareCPUWorkloadValue(row.CPUCores || 0);
|
212
221
|
},
|
213
222
|
align: DataTable.RIGHT,
|
214
223
|
},
|
215
224
|
{
|
216
225
|
name: tableColumnsNames.DataSize,
|
217
226
|
header: 'DataSize (B)',
|
218
|
-
render: ({
|
219
|
-
return formatNumber(
|
227
|
+
render: ({row}) => {
|
228
|
+
return formatNumber(row.DataSize);
|
220
229
|
},
|
221
230
|
align: DataTable.RIGHT,
|
222
231
|
},
|
223
232
|
{
|
224
233
|
name: tableColumnsNames.TabletId,
|
225
|
-
render: ({
|
234
|
+
render: ({row}) => {
|
235
|
+
if (!row.TabletId) {
|
236
|
+
return '–';
|
237
|
+
}
|
226
238
|
return (
|
227
|
-
<InternalLink to={createHref(routes.tablet, {id:
|
228
|
-
{
|
239
|
+
<InternalLink to={createHref(routes.tablet, {id: row.TabletId})}>
|
240
|
+
{row.TabletId}
|
229
241
|
</InternalLink>
|
230
242
|
);
|
231
243
|
},
|
@@ -233,10 +245,13 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
233
245
|
},
|
234
246
|
{
|
235
247
|
name: tableColumnsNames.NodeId,
|
236
|
-
render: ({
|
248
|
+
render: ({row}) => {
|
249
|
+
if (!row.NodeId) {
|
250
|
+
return '–';
|
251
|
+
}
|
237
252
|
return (
|
238
|
-
<InternalLink to={getDefaultNodePath(
|
239
|
-
{
|
253
|
+
<InternalLink to={getDefaultNodePath(row.NodeId)}>
|
254
|
+
{row.NodeId}
|
240
255
|
</InternalLink>
|
241
256
|
);
|
242
257
|
},
|
@@ -245,7 +260,7 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
245
260
|
},
|
246
261
|
{
|
247
262
|
name: tableColumnsNames.InFlightTxCount,
|
248
|
-
render: ({
|
263
|
+
render: ({row}) => formatNumber(row.InFlightTxCount),
|
249
264
|
align: DataTable.RIGHT,
|
250
265
|
sortable: false,
|
251
266
|
},
|
@@ -255,12 +270,16 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
255
270
|
// after NodeId
|
256
271
|
columns.splice(5, 0, {
|
257
272
|
name: tableColumnsNames.PeakTime,
|
258
|
-
render: ({
|
273
|
+
render: ({row}) => {
|
274
|
+
return prepareDateTimeValue(row.PeakTime);
|
275
|
+
},
|
259
276
|
sortable: false,
|
260
277
|
});
|
261
278
|
columns.push({
|
262
279
|
name: tableColumnsNames.IntervalEnd,
|
263
|
-
render: ({
|
280
|
+
render: ({row}) => {
|
281
|
+
return prepareDateTimeValue(row.IntervalEnd);
|
282
|
+
},
|
264
283
|
});
|
265
284
|
}
|
266
285
|
|
@@ -2,8 +2,9 @@ import React, {useRef, useState} from 'react';
|
|
2
2
|
import cn from 'bem-cn-lite';
|
3
3
|
import _ from 'lodash';
|
4
4
|
import {Button, Popup} from '@gravity-ui/uikit';
|
5
|
+
|
5
6
|
import TruncatedQuery from '../../../../components/TruncatedQuery/TruncatedQuery';
|
6
|
-
import {
|
7
|
+
import {useTypedSelector} from '../../../../utils/hooks';
|
7
8
|
|
8
9
|
import './QueriesHistory.scss';
|
9
10
|
|
@@ -17,8 +18,7 @@ interface QueriesHistoryProps {
|
|
17
18
|
|
18
19
|
function QueriesHistory(props: QueriesHistoryProps) {
|
19
20
|
const [isHistoryVisible, setIsHistoryVisible] = useState(false);
|
20
|
-
const history
|
21
|
-
useSelector((state: any) => state.executeQuery.history?.queries) ?? [];
|
21
|
+
const history = useTypedSelector((state) => state.executeQuery.history.queries) ?? [];
|
22
22
|
const anchor = useRef(null);
|
23
23
|
|
24
24
|
const onShowHistoryClick = () => {
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import block from 'bem-cn-lite';
|
2
|
+
|
3
|
+
import {formatDurationToShortTimeFormat, parseUsToMs} from '../../../../utils/timeParsers';
|
4
|
+
|
5
|
+
import './QueryDuration.scss';
|
6
|
+
|
7
|
+
interface QueryDurationProps {
|
8
|
+
duration?: string;
|
9
|
+
}
|
10
|
+
|
11
|
+
const b = block('ydb-query-duration');
|
12
|
+
|
13
|
+
export const QueryDuration = ({duration}: QueryDurationProps) => {
|
14
|
+
if (!duration) {
|
15
|
+
return null;
|
16
|
+
}
|
17
|
+
|
18
|
+
const parsedDuration = formatDurationToShortTimeFormat(parseUsToMs(duration), 1);
|
19
|
+
|
20
|
+
return <span className={b()}>{parsedDuration}</span>;
|
21
|
+
};
|
@@ -4,41 +4,36 @@ import {connect} from 'react-redux';
|
|
4
4
|
import cn from 'bem-cn-lite';
|
5
5
|
import _ from 'lodash';
|
6
6
|
import MonacoEditor from 'react-monaco-editor';
|
7
|
-
import {Button, DropdownMenu} from '@gravity-ui/uikit';
|
8
7
|
|
9
8
|
import SplitPane from '../../../components/SplitPane';
|
10
9
|
import {QueryResultTable} from '../../../components/QueryResultTable';
|
11
10
|
|
12
|
-
import SaveQuery from './SaveQuery/SaveQuery';
|
13
11
|
import SavedQueries from './SavedQueries/SavedQueries';
|
14
|
-
import {Icon} from '../../../components/Icon';
|
15
12
|
import QueryResult from './QueryResult/QueryResult';
|
16
13
|
import QueryExplain from './QueryExplain/QueryExplain';
|
14
|
+
import {QueryEditorControls} from './QueryEditorControls/QueryEditorControls';
|
15
|
+
import {OldQueryEditorControls} from './QueryEditorControls/OldQueryEditorControls';
|
17
16
|
|
18
17
|
import {
|
19
|
-
|
18
|
+
sendExecuteQuery,
|
20
19
|
changeUserInput,
|
21
20
|
saveQueryToHistory,
|
22
21
|
goToPreviousQuery,
|
23
22
|
goToNextQuery,
|
24
|
-
selectRunAction,
|
25
|
-
RUN_ACTIONS_VALUES,
|
26
23
|
MONACO_HOT_KEY_ACTIONS,
|
27
24
|
setMonacoHotKey,
|
28
25
|
} from '../../../store/reducers/executeQuery';
|
29
26
|
import {getExplainQuery, getExplainQueryAst} from '../../../store/reducers/explainQuery';
|
30
|
-
import {
|
27
|
+
import {getParsedSettingValue, setSettingValue} from '../../../store/reducers/settings';
|
31
28
|
import {
|
32
29
|
DEFAULT_IS_QUERY_RESULT_COLLAPSED,
|
33
30
|
DEFAULT_SIZE_RESULT_PANE_KEY,
|
34
31
|
SAVED_QUERIES_KEY,
|
35
|
-
|
32
|
+
QUERY_INITIAL_MODE_KEY,
|
33
|
+
ENABLE_QUERY_MODES_FOR_EXPLAIN,
|
36
34
|
} from '../../../utils/constants';
|
37
35
|
|
38
|
-
import {parseJson} from '../../../utils/utils';
|
39
|
-
|
40
36
|
import './QueryEditor.scss';
|
41
|
-
import Divider from '../../../components/Divider/Divider';
|
42
37
|
import QueriesHistory from './QueriesHistory/QueriesHistory';
|
43
38
|
import {
|
44
39
|
PaneVisibilityActionTypes,
|
@@ -47,11 +42,6 @@ import {
|
|
47
42
|
import Preview from '../Preview/Preview';
|
48
43
|
import {setShowPreview} from '../../../store/reducers/schema';
|
49
44
|
|
50
|
-
export const RUN_ACTIONS = [
|
51
|
-
{value: RUN_ACTIONS_VALUES.script, content: 'Run Script'},
|
52
|
-
{value: RUN_ACTIONS_VALUES.scan, content: 'Run Scan'},
|
53
|
-
];
|
54
|
-
|
55
45
|
const TABLE_SETTINGS = {
|
56
46
|
sortable: false,
|
57
47
|
};
|
@@ -73,7 +63,7 @@ const RESULT_TYPES = {
|
|
73
63
|
const b = cn('query-editor');
|
74
64
|
|
75
65
|
const propTypes = {
|
76
|
-
|
66
|
+
sendExecuteQuery: PropTypes.func,
|
77
67
|
path: PropTypes.string,
|
78
68
|
response: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
|
79
69
|
executeQuery: PropTypes.object,
|
@@ -81,6 +71,7 @@ const propTypes = {
|
|
81
71
|
setMonacoHotKey: PropTypes.func,
|
82
72
|
theme: PropTypes.string,
|
83
73
|
type: PropTypes.string,
|
74
|
+
initialQueryMode: PropTypes.string,
|
84
75
|
};
|
85
76
|
|
86
77
|
const initialTenantCommonInfoState = {
|
@@ -92,6 +83,7 @@ function QueryEditor(props) {
|
|
92
83
|
const [resultType, setResultType] = useState(RESULT_TYPES.EXECUTE);
|
93
84
|
|
94
85
|
const [isResultLoaded, setIsResultLoaded] = useState(false);
|
86
|
+
const [queryMode, setQueryMode] = useState(props.initialQueryMode);
|
95
87
|
|
96
88
|
const [resultVisibilityState, dispatchResultVisibilityState] = useReducer(
|
97
89
|
paneVisibilityToggleReducerCreator(DEFAULT_IS_QUERY_RESULT_COLLAPSED),
|
@@ -155,7 +147,7 @@ function QueryEditor(props) {
|
|
155
147
|
setMonacoHotKey(null);
|
156
148
|
switch (monacoHotKey) {
|
157
149
|
case MONACO_HOT_KEY_ACTIONS.sendQuery: {
|
158
|
-
return
|
150
|
+
return handleSendExecuteClick(queryMode);
|
159
151
|
}
|
160
152
|
case MONACO_HOT_KEY_ACTIONS.goPrev: {
|
161
153
|
return handlePreviousHistoryClick();
|
@@ -246,17 +238,17 @@ function QueryEditor(props) {
|
|
246
238
|
props.changeUserInput({input: newValue});
|
247
239
|
};
|
248
240
|
|
249
|
-
const
|
241
|
+
const handleSendExecuteClick = (mode) => {
|
250
242
|
const {
|
251
243
|
path,
|
252
|
-
executeQuery: {input, history
|
253
|
-
|
244
|
+
executeQuery: {input, history},
|
245
|
+
sendExecuteQuery,
|
254
246
|
saveQueryToHistory,
|
255
247
|
setShowPreview,
|
256
248
|
} = props;
|
257
249
|
|
258
250
|
setResultType(RESULT_TYPES.EXECUTE);
|
259
|
-
|
251
|
+
sendExecuteQuery({query: input, database: path, mode});
|
260
252
|
setIsResultLoaded(true);
|
261
253
|
setShowPreview(false);
|
262
254
|
|
@@ -267,15 +259,20 @@ function QueryEditor(props) {
|
|
267
259
|
dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerExpand);
|
268
260
|
};
|
269
261
|
|
270
|
-
const handleGetExplainQueryClick = () => {
|
262
|
+
const handleGetExplainQueryClick = (mode) => {
|
271
263
|
const {
|
272
264
|
path,
|
273
265
|
executeQuery: {input},
|
274
266
|
getExplainQuery,
|
275
267
|
setShowPreview,
|
276
268
|
} = props;
|
269
|
+
|
277
270
|
setResultType(RESULT_TYPES.EXPLAIN);
|
278
|
-
getExplainQuery({
|
271
|
+
getExplainQuery({
|
272
|
+
query: input,
|
273
|
+
database: path,
|
274
|
+
mode: mode,
|
275
|
+
});
|
279
276
|
setIsResultLoaded(true);
|
280
277
|
setShowPreview(false);
|
281
278
|
dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerExpand);
|
@@ -513,64 +510,42 @@ function QueryEditor(props) {
|
|
513
510
|
setSettingValue(SAVED_QUERIES_KEY, JSON.stringify(newSavedQueries));
|
514
511
|
};
|
515
512
|
|
516
|
-
const
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
const runText = _.find(RUN_ACTIONS, {value: runAction}).content;
|
521
|
-
|
522
|
-
const menuItems = RUN_ACTIONS.map((action) => {
|
523
|
-
return {
|
524
|
-
text: action.content,
|
525
|
-
action: () => {
|
526
|
-
selectRunAction(action.value);
|
527
|
-
setSettingValue(QUERY_INITIAL_RUN_ACTION_KEY, action.value);
|
528
|
-
},
|
529
|
-
};
|
530
|
-
});
|
513
|
+
const onUpdateQueryMode = (mode) => {
|
514
|
+
setQueryMode(mode);
|
515
|
+
props.setSettingValue(QUERY_INITIAL_MODE_KEY, mode);
|
516
|
+
};
|
531
517
|
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
{runText}
|
544
|
-
</Button>
|
545
|
-
<DropdownMenu
|
546
|
-
items={menuItems}
|
547
|
-
switcher={
|
548
|
-
<Button
|
549
|
-
view="action"
|
550
|
-
pin="brick-round"
|
551
|
-
disabled={runIsDisabled}
|
552
|
-
loading={executeQuery.loading}
|
553
|
-
className={b('select-query-action')}
|
554
|
-
>
|
555
|
-
<Icon name="chevron-down" width={16} height={16} />
|
556
|
-
</Button>
|
557
|
-
}
|
558
|
-
/>
|
559
|
-
</div>
|
560
|
-
<Button
|
561
|
-
onClick={handleGetExplainQueryClick}
|
562
|
-
disabled={!executeQuery.input}
|
563
|
-
loading={explainQuery.loading}
|
564
|
-
>
|
565
|
-
Explain
|
566
|
-
</Button>
|
567
|
-
<Divider />
|
568
|
-
<SaveQuery
|
518
|
+
const renderControls = () => {
|
519
|
+
const {executeQuery, explainQuery, savedQueries, enableQueryModesForExplain} = props;
|
520
|
+
|
521
|
+
if (enableQueryModesForExplain) {
|
522
|
+
return (
|
523
|
+
<QueryEditorControls
|
524
|
+
onRunButtonClick={handleSendExecuteClick}
|
525
|
+
runIsLoading={executeQuery.loading}
|
526
|
+
onExplainButtonClick={handleGetExplainQueryClick}
|
527
|
+
explainIsLoading={explainQuery.loading}
|
528
|
+
onSaveQueryClick={onSaveQueryHandler}
|
569
529
|
savedQueries={savedQueries}
|
570
|
-
|
571
|
-
|
530
|
+
disabled={!executeQuery.input}
|
531
|
+
onUpdateQueryMode={onUpdateQueryMode}
|
532
|
+
queryMode={queryMode}
|
572
533
|
/>
|
573
|
-
|
534
|
+
);
|
535
|
+
}
|
536
|
+
|
537
|
+
return (
|
538
|
+
<OldQueryEditorControls
|
539
|
+
onRunButtonClick={handleSendExecuteClick}
|
540
|
+
runIsLoading={executeQuery.loading}
|
541
|
+
onExplainButtonClick={handleGetExplainQueryClick}
|
542
|
+
explainIsLoading={explainQuery.loading}
|
543
|
+
onSaveQueryClick={onSaveQueryHandler}
|
544
|
+
savedQueries={savedQueries}
|
545
|
+
disabled={!executeQuery.input}
|
546
|
+
onUpdateQueryMode={onUpdateQueryMode}
|
547
|
+
queryMode={queryMode}
|
548
|
+
/>
|
574
549
|
);
|
575
550
|
};
|
576
551
|
|
@@ -631,7 +606,9 @@ const mapStateToProps = (state) => {
|
|
631
606
|
return {
|
632
607
|
executeQuery: state.executeQuery,
|
633
608
|
explainQuery: state.explainQuery,
|
634
|
-
savedQueries:
|
609
|
+
savedQueries: getParsedSettingValue(state, SAVED_QUERIES_KEY),
|
610
|
+
initialQueryMode: getParsedSettingValue(state, QUERY_INITIAL_MODE_KEY),
|
611
|
+
enableQueryModesForExplain: getParsedSettingValue(state, ENABLE_QUERY_MODES_FOR_EXPLAIN),
|
635
612
|
showPreview: state.schema.showPreview,
|
636
613
|
currentSchema: state.schema.currentSchema,
|
637
614
|
monacoHotKey: state.executeQuery?.monacoHotKey,
|
@@ -639,7 +616,7 @@ const mapStateToProps = (state) => {
|
|
639
616
|
};
|
640
617
|
|
641
618
|
const mapDispatchToProps = {
|
642
|
-
|
619
|
+
sendExecuteQuery,
|
643
620
|
changeUserInput,
|
644
621
|
saveQueryToHistory,
|
645
622
|
goToPreviousQuery,
|
@@ -647,7 +624,6 @@ const mapDispatchToProps = {
|
|
647
624
|
getExplainQuery,
|
648
625
|
getExplainQueryAst,
|
649
626
|
setSettingValue,
|
650
|
-
selectRunAction,
|
651
627
|
setShowPreview,
|
652
628
|
setMonacoHotKey,
|
653
629
|
};
|
@@ -54,35 +54,6 @@
|
|
54
54
|
align-items: center;
|
55
55
|
}
|
56
56
|
|
57
|
-
&__controls {
|
58
|
-
display: flex;
|
59
|
-
flex: 0 0 40px;
|
60
|
-
align-items: flex-end;
|
61
|
-
|
62
|
-
min-height: 40px;
|
63
|
-
padding: 5px 20px;
|
64
|
-
|
65
|
-
border-top: 1px solid var(--yc-color-line-generic);
|
66
|
-
border-bottom: 1px solid var(--yc-color-line-generic);
|
67
|
-
background-color: var(--yc-color-base-background);
|
68
|
-
gap: 12px;
|
69
|
-
}
|
70
|
-
|
71
|
-
&__control-run {
|
72
|
-
display: flex;
|
73
|
-
align-items: center;
|
74
|
-
.yc-select__option-text {
|
75
|
-
display: none;
|
76
|
-
}
|
77
|
-
|
78
|
-
.yc-button__text {
|
79
|
-
display: flex;
|
80
|
-
justify-content: center;
|
81
|
-
align-items: center;
|
82
|
-
gap: 8px;
|
83
|
-
}
|
84
|
-
}
|
85
|
-
|
86
57
|
&__history-controls {
|
87
58
|
display: flex;
|
88
59
|
align-items: center;
|
@@ -93,8 +64,4 @@
|
|
93
64
|
|
94
65
|
color: var(--yc-color-text-secondary);
|
95
66
|
}
|
96
|
-
|
97
|
-
&__select-query-action {
|
98
|
-
margin-left: 2px;
|
99
|
-
}
|
100
67
|
}
|