Skip to content

Commit 39ad943

Browse files
feat(QueryEditor): add explain query modes
1 parent 7c96120 commit 39ad943

19 files changed

+398
-162
lines changed

src/containers/Tenant/QueryEditor/QueryEditor.js

Lines changed: 58 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,36 @@ import {connect} from 'react-redux';
44
import cn from 'bem-cn-lite';
55
import _ from 'lodash';
66
import MonacoEditor from 'react-monaco-editor';
7-
import {Button, DropdownMenu} from '@gravity-ui/uikit';
87

98
import SplitPane from '../../../components/SplitPane';
109
import {QueryResultTable} from '../../../components/QueryResultTable';
1110

12-
import SaveQuery from './SaveQuery/SaveQuery';
1311
import SavedQueries from './SavedQueries/SavedQueries';
14-
import {Icon} from '../../../components/Icon';
1512
import QueryResult from './QueryResult/QueryResult';
1613
import QueryExplain from './QueryExplain/QueryExplain';
14+
import {QueryEditorControls} from './QueryEditorControls/QueryEditorControls';
15+
import {OldQueryEditorControls} from './QueryEditorControls/OldQueryEditorControls';
1716

1817
import {
19-
sendQuery,
18+
sendExecuteQuery,
2019
changeUserInput,
2120
saveQueryToHistory,
2221
goToPreviousQuery,
2322
goToNextQuery,
24-
selectRunAction,
25-
RUN_ACTIONS_VALUES,
2623
MONACO_HOT_KEY_ACTIONS,
2724
setMonacoHotKey,
2825
} from '../../../store/reducers/executeQuery';
2926
import {getExplainQuery, getExplainQueryAst} from '../../../store/reducers/explainQuery';
30-
import {getSettingValue, setSettingValue} from '../../../store/reducers/settings';
27+
import {getParsedSettingValue, setSettingValue} from '../../../store/reducers/settings';
3128
import {
3229
DEFAULT_IS_QUERY_RESULT_COLLAPSED,
3330
DEFAULT_SIZE_RESULT_PANE_KEY,
3431
SAVED_QUERIES_KEY,
35-
QUERY_INITIAL_RUN_ACTION_KEY,
32+
QUERY_INITIAL_MODE_KEY,
33+
ENABLE_QUERY_MODES_FOR_EXPLAIN,
3634
} from '../../../utils/constants';
3735

38-
import {parseJson} from '../../../utils/utils';
39-
4036
import './QueryEditor.scss';
41-
import Divider from '../../../components/Divider/Divider';
4237
import QueriesHistory from './QueriesHistory/QueriesHistory';
4338
import {
4439
PaneVisibilityActionTypes,
@@ -47,11 +42,6 @@ import {
4742
import Preview from '../Preview/Preview';
4843
import {setShowPreview} from '../../../store/reducers/schema';
4944

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-
5545
const TABLE_SETTINGS = {
5646
sortable: false,
5747
};
@@ -73,14 +63,15 @@ const RESULT_TYPES = {
7363
const b = cn('query-editor');
7464

7565
const propTypes = {
76-
sendQuery: PropTypes.func,
66+
sendExecuteQuery: PropTypes.func,
7767
path: PropTypes.string,
7868
response: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
7969
executeQuery: PropTypes.object,
8070
explainQuery: PropTypes.object,
8171
setMonacoHotKey: PropTypes.func,
8272
theme: PropTypes.string,
8373
type: PropTypes.string,
74+
initialQueryMode: PropTypes.string,
8475
};
8576

8677
const initialTenantCommonInfoState = {
@@ -92,6 +83,7 @@ function QueryEditor(props) {
9283
const [resultType, setResultType] = useState(RESULT_TYPES.EXECUTE);
9384

9485
const [isResultLoaded, setIsResultLoaded] = useState(false);
86+
const [queryMode, setQueryMode] = useState(props.initialQueryMode);
9587

9688
const [resultVisibilityState, dispatchResultVisibilityState] = useReducer(
9789
paneVisibilityToggleReducerCreator(DEFAULT_IS_QUERY_RESULT_COLLAPSED),
@@ -155,7 +147,7 @@ function QueryEditor(props) {
155147
setMonacoHotKey(null);
156148
switch (monacoHotKey) {
157149
case MONACO_HOT_KEY_ACTIONS.sendQuery: {
158-
return handleSendClick();
150+
return handleSendExecuteClick(queryMode);
159151
}
160152
case MONACO_HOT_KEY_ACTIONS.goPrev: {
161153
return handlePreviousHistoryClick();
@@ -246,17 +238,17 @@ function QueryEditor(props) {
246238
props.changeUserInput({input: newValue});
247239
};
248240

249-
const handleSendClick = () => {
241+
const handleSendExecuteClick = (mode) => {
250242
const {
251243
path,
252-
executeQuery: {input, history, runAction},
253-
sendQuery,
244+
executeQuery: {input, history},
245+
sendExecuteQuery,
254246
saveQueryToHistory,
255247
setShowPreview,
256248
} = props;
257249

258250
setResultType(RESULT_TYPES.EXECUTE);
259-
sendQuery({query: input, database: path, action: runAction});
251+
sendExecuteQuery({query: input, database: path, mode});
260252
setIsResultLoaded(true);
261253
setShowPreview(false);
262254

@@ -267,15 +259,20 @@ function QueryEditor(props) {
267259
dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerExpand);
268260
};
269261

270-
const handleGetExplainQueryClick = () => {
262+
const handleGetExplainQueryClick = (mode) => {
271263
const {
272264
path,
273265
executeQuery: {input},
274266
getExplainQuery,
275267
setShowPreview,
276268
} = props;
269+
277270
setResultType(RESULT_TYPES.EXPLAIN);
278-
getExplainQuery({query: input, database: path});
271+
getExplainQuery({
272+
query: input,
273+
database: path,
274+
mode: mode,
275+
});
279276
setIsResultLoaded(true);
280277
setShowPreview(false);
281278
dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerExpand);
@@ -513,65 +510,42 @@ function QueryEditor(props) {
513510
setSettingValue(SAVED_QUERIES_KEY, JSON.stringify(newSavedQueries));
514511
};
515512

516-
const renderControls = () => {
517-
const {executeQuery, explainQuery, savedQueries, selectRunAction, setSettingValue} = props;
518-
const {runAction} = executeQuery;
519-
const runIsDisabled = !executeQuery.input || executeQuery.loading;
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+
};
531517

532-
return (
533-
<div className={b('controls')}>
534-
<div className={b('control-run')}>
535-
<Button
536-
onClick={handleSendClick}
537-
view="action"
538-
pin="round-brick"
539-
disabled={runIsDisabled}
540-
loading={executeQuery.loading}
541-
>
542-
<Icon name="startPlay" viewBox="0 0 16 16" width={16} height={16} />
543-
{runText}
544-
</Button>
545-
<DropdownMenu
546-
items={menuItems}
547-
popupClassName={b('select-query-action-popup')}
548-
switcher={
549-
<Button
550-
view="action"
551-
pin="brick-round"
552-
disabled={runIsDisabled}
553-
loading={executeQuery.loading}
554-
className={b('select-query-action')}
555-
>
556-
<Icon name="chevron-down" width={16} height={16} />
557-
</Button>
558-
}
559-
/>
560-
</div>
561-
<Button
562-
onClick={handleGetExplainQueryClick}
563-
disabled={!executeQuery.input}
564-
loading={explainQuery.loading}
565-
>
566-
Explain
567-
</Button>
568-
<Divider />
569-
<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}
570529
savedQueries={savedQueries}
571-
onSaveQuery={onSaveQueryHandler}
572-
saveButtonDisabled={runIsDisabled}
530+
disabled={!executeQuery.input}
531+
onUpdateQueryMode={onUpdateQueryMode}
532+
queryMode={queryMode}
573533
/>
574-
</div>
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+
/>
575549
);
576550
};
577551

@@ -632,23 +606,24 @@ const mapStateToProps = (state) => {
632606
return {
633607
executeQuery: state.executeQuery,
634608
explainQuery: state.explainQuery,
635-
savedQueries: parseJson(getSettingValue(state, SAVED_QUERIES_KEY)),
609+
savedQueries: getParsedSettingValue(state, SAVED_QUERIES_KEY),
610+
initialQueryMode: getParsedSettingValue(state, QUERY_INITIAL_MODE_KEY),
611+
enableQueryModesForExplain: getParsedSettingValue(state, ENABLE_QUERY_MODES_FOR_EXPLAIN),
636612
showPreview: state.schema.showPreview,
637613
currentSchema: state.schema.currentSchema,
638614
monacoHotKey: state.executeQuery?.monacoHotKey,
639615
};
640616
};
641617

642618
const mapDispatchToProps = {
643-
sendQuery,
619+
sendExecuteQuery,
644620
changeUserInput,
645621
saveQueryToHistory,
646622
goToPreviousQuery,
647623
goToNextQuery,
648624
getExplainQuery,
649625
getExplainQueryAst,
650626
setSettingValue,
651-
selectRunAction,
652627
setShowPreview,
653628
setMonacoHotKey,
654629
};

src/containers/Tenant/QueryEditor/QueryEditor.scss

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -54,35 +54,6 @@
5454
align-items: center;
5555
}
5656

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-
8657
&__history-controls {
8758
display: flex;
8859
align-items: center;
@@ -93,8 +64,4 @@
9364

9465
color: var(--yc-color-text-secondary);
9566
}
96-
97-
&__select-query-action {
98-
margin-left: 2px;
99-
}
10067
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import {Button, DropdownMenu} from '@gravity-ui/uikit';
2+
import {useMemo} from 'react';
3+
4+
import {QueryModes} from '../../../../types/store/query';
5+
import {Icon} from '../../../../components/Icon';
6+
7+
import SaveQuery from '../SaveQuery/SaveQuery';
8+
9+
import {b, QueryEditorControlsProps, QueryModeSelectorTitles} from './shared';
10+
11+
import './QueryEditorControls.scss';
12+
13+
export const OldQueryEditorControls = ({
14+
onRunButtonClick,
15+
runIsLoading,
16+
onExplainButtonClick,
17+
explainIsLoading,
18+
onSaveQueryClick,
19+
savedQueries,
20+
disabled,
21+
onUpdateQueryMode,
22+
queryMode,
23+
}: QueryEditorControlsProps) => {
24+
const runModeSelectorMenuItems = useMemo(() => {
25+
return Object.entries(QueryModeSelectorTitles).map(([mode, title]) => {
26+
return {
27+
text: `Run ${title}`,
28+
action: () => {
29+
onUpdateQueryMode(mode as QueryModes);
30+
},
31+
};
32+
});
33+
}, [onUpdateQueryMode]);
34+
35+
return (
36+
<div className={b()}>
37+
<div className={b('left')}>
38+
<div className={b('run')}>
39+
<Button
40+
onClick={() => onRunButtonClick(queryMode)}
41+
view="action"
42+
pin="round-brick"
43+
disabled={disabled}
44+
loading={runIsLoading}
45+
>
46+
<Icon name="startPlay" viewBox="0 0 16 16" width={16} height={16} />
47+
{`Run ${QueryModeSelectorTitles[queryMode]}`}
48+
</Button>
49+
<DropdownMenu
50+
items={runModeSelectorMenuItems}
51+
popupClassName={b('select-query-action-popup')}
52+
switcher={
53+
<Button
54+
view="action"
55+
pin="brick-round"
56+
disabled={disabled}
57+
loading={runIsLoading}
58+
className={b('select-query-action')}
59+
>
60+
<Icon name="chevron-down" width={16} height={16} />
61+
</Button>
62+
}
63+
/>
64+
</div>
65+
<Button
66+
onClick={() => {
67+
// Without defined query mode it sends 'explain' action
68+
onExplainButtonClick();
69+
}}
70+
disabled={disabled}
71+
loading={explainIsLoading}
72+
>
73+
Explain
74+
</Button>
75+
</div>
76+
<SaveQuery
77+
savedQueries={savedQueries}
78+
onSaveQuery={onSaveQueryClick}
79+
saveButtonDisabled={disabled}
80+
/>
81+
</div>
82+
);
83+
};

0 commit comments

Comments
 (0)