ydb-embedded-ui 0.1.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +3 -3
  4. package/dist/assets/icons/cluster.svg +1 -0
  5. package/dist/assets/icons/hide.svg +1 -0
  6. package/dist/assets/icons/show.svg +1 -0
  7. package/dist/assets/icons/user-check.svg +1 -1
  8. package/dist/assets/icons/user-secret.svg +1 -1
  9. package/dist/components/AsideNavigation/AsideHeader.scss +1 -2
  10. package/dist/components/AsideNavigation/AsideHeaderFooterItem/AsideHeaderFooterItem.scss +7 -7
  11. package/dist/components/AsideNavigation/AsideHeaderTooltip/AsideHeaderTooltip.scss +2 -2
  12. package/dist/components/AsideNavigation/CompositeBar/CompositeBar.scss +6 -6
  13. package/dist/components/AsideNavigation/Drawer/Drawer.scss +5 -5
  14. package/dist/components/AsideNavigation/Logo/Logo.scss +3 -4
  15. package/dist/components/AsideNavigation/Settings/Settings.scss +27 -12
  16. package/dist/components/AsideNavigation/Settings/SettingsMenu/SettingsMenu.scss +14 -6
  17. package/dist/components/Breadcrumbs/Breadcrumbs.scss +2 -1
  18. package/dist/components/ClusterInfo/ClusterInfo.scss +19 -12
  19. package/dist/components/ClusterInfo/ClusterInfo.tsx +110 -10
  20. package/dist/components/CopyToClipboard/CopyToClipboard.tsx +39 -0
  21. package/dist/components/CriticalActionDialog/CriticalActionDialog.scss +5 -4
  22. package/dist/components/Divider/Divider.scss +7 -0
  23. package/dist/components/Divider/Divider.tsx +11 -0
  24. package/dist/components/EmptyState/EmptyState.scss +14 -10
  25. package/dist/components/EnableFullscreenButton/EnableFullscreenButton.tsx +22 -0
  26. package/dist/components/EntityStatus/EntityStatus.js +5 -3
  27. package/dist/components/EntityStatus/EntityStatus.scss +35 -13
  28. package/dist/components/FullGroupViewer/FullGroupViewer.js +2 -4
  29. package/dist/components/FullGroupViewer/FullGroupViewer.scss +6 -3
  30. package/dist/components/FullNodeViewer/FullNodeViewer.scss +19 -11
  31. package/dist/components/Fullscreen/Fullscreen.scss +28 -0
  32. package/dist/components/Fullscreen/Fullscreen.tsx +81 -0
  33. package/dist/components/GroupTreeViewer/GroupTreeViewer.scss +1 -0
  34. package/dist/components/GroupViewer/GroupViewer.scss +8 -4
  35. package/dist/components/Icon/Icon.js +2 -0
  36. package/dist/components/InfoViewer/InfoViewer.scss +22 -16
  37. package/dist/components/NodesViewer/NodesViewer.js +25 -35
  38. package/dist/components/NodesViewer/NodesViewer.scss +15 -11
  39. package/dist/components/PDiskViewer/PDiskViewer.scss +10 -4
  40. package/dist/components/Pagination/Pagination.scss +6 -3
  41. package/dist/components/PoolBar/PoolBar.scss +14 -10
  42. package/dist/components/PoolUsage/PoolUsage.scss +17 -9
  43. package/dist/components/ProgressViewer/ProgressViewer.js +1 -1
  44. package/dist/components/ProgressViewer/ProgressViewer.scss +28 -18
  45. package/dist/components/QueryExecutionStatus/QueryExecutionStatus.scss +14 -0
  46. package/dist/components/QueryExecutionStatus/QueryExecutionStatus.tsx +29 -0
  47. package/dist/components/SplitPane/SplitPane.scss +33 -40
  48. package/dist/components/SplitPane/SplitPane.tsx +94 -0
  49. package/dist/components/Tablet/Tablet.scss +9 -6
  50. package/dist/components/TabletsOverall/TabletsOverall.scss +19 -0
  51. package/dist/components/TabletsOverall/TabletsOverall.tsx +105 -0
  52. package/dist/components/TabletsStatistic/TabletsStatistic.scss +24 -18
  53. package/dist/components/TabletsViewer/TabletsViewer.scss +12 -9
  54. package/dist/components/Tag/Tag.scss +6 -4
  55. package/dist/components/Tags/Tags.scss +1 -1
  56. package/dist/components/TreeView/TreeView.js +1 -1
  57. package/dist/components/TreeView/TreeView.scss +9 -0
  58. package/dist/components/TruncatedQuery/TruncatedQuery.scss +4 -3
  59. package/dist/containers/App/App.js +1 -0
  60. package/dist/containers/App/App.scss +50 -31
  61. package/dist/containers/App/Content.js +2 -2
  62. package/dist/containers/App/NodesTable.scss +25 -0
  63. package/dist/containers/App/TipPopup/TipPopup.scss +10 -6
  64. package/dist/containers/AppIcons/AppIcons.js +46 -22
  65. package/dist/containers/AsideNavigation/AsideNavigation.scss +1 -1
  66. package/dist/containers/AsideNavigation/AsideNavigation.tsx +12 -5
  67. package/dist/containers/Authentication/Authentication.scss +63 -14
  68. package/dist/containers/Authentication/Authentication.tsx +42 -9
  69. package/dist/containers/Cluster/Cluster.scss +5 -3
  70. package/dist/containers/Cluster/Cluster.tsx +49 -0
  71. package/dist/containers/Group/Group.scss +1 -1
  72. package/dist/containers/Header/Header.scss +15 -59
  73. package/dist/containers/Header/Header.tsx +75 -0
  74. package/dist/containers/Header/Host/Host.scss +10 -3
  75. package/dist/containers/Heatmap/Heatmap.js +1 -1
  76. package/dist/containers/Heatmap/Heatmap.scss +16 -7
  77. package/dist/containers/Heatmap/HeatmapCanvas/HeatmapCanvas.js +3 -3
  78. package/dist/containers/Heatmap/Histogram/Histogram.scss +21 -9
  79. package/dist/containers/Node/Node.js +1 -1
  80. package/dist/containers/Node/Node.scss +6 -4
  81. package/dist/containers/Nodes/Nodes.js +28 -27
  82. package/dist/containers/Nodes/Nodes.scss +5 -17
  83. package/dist/containers/Pdisk/Pdisk.scss +6 -4
  84. package/dist/containers/Pool/Pool.scss +7 -4
  85. package/dist/containers/ReduxTooltip/ReduxTooltip.scss +5 -1
  86. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.scss +77 -0
  87. package/dist/containers/{StorageV2 → Storage}/DiskStateProgressBar/DiskStateProgressBar.tsx +1 -1
  88. package/dist/containers/{StorageV2 → Storage}/Pdisk/Pdisk.scss +6 -4
  89. package/dist/containers/{StorageV2 → Storage}/Pdisk/Pdisk.tsx +1 -2
  90. package/dist/containers/{StorageV2 → Storage}/Storage.js +72 -34
  91. package/dist/containers/{StorageV2 → Storage}/Storage.scss +12 -14
  92. package/dist/containers/{StorageV2 → Storage}/StorageFilter/StorageFilter.js +1 -9
  93. package/dist/containers/{StorageV2 → Storage}/StorageGroups/StorageGroups.scss +2 -0
  94. package/dist/containers/{StorageV2 → Storage}/StorageGroups/StorageGroups.tsx +1 -1
  95. package/dist/containers/{StorageV2 → Storage}/StorageNodes/StorageNodes.scss +2 -0
  96. package/dist/containers/{StorageV2 → Storage}/StorageNodes/StorageNodes.tsx +1 -1
  97. package/dist/containers/{StorageV2 → Storage}/Vdisk/Vdisk.js +0 -0
  98. package/dist/containers/{StorageV2 → Storage}/Vdisk/Vdisk.scss +6 -4
  99. package/dist/containers/Tablet/Tablet.scss +13 -9
  100. package/dist/containers/Tablets/Tablets.js +21 -90
  101. package/dist/containers/Tablets/Tablets.scss +9 -35
  102. package/dist/containers/TabletsFilters/TabletsFilters.js +2 -75
  103. package/dist/containers/TabletsFilters/TabletsFilters.scss +15 -35
  104. package/dist/containers/Tenant/Acl/Acl.js +54 -47
  105. package/dist/containers/Tenant/Acl/Acl.scss +15 -4
  106. package/dist/containers/Tenant/{Compute → Diagnostics/Compute}/Compute.js +35 -12
  107. package/dist/containers/Tenant/Diagnostics/Compute/Compute.scss +14 -0
  108. package/dist/containers/Tenant/{Describe → Diagnostics/Describe}/Describe.js +50 -1
  109. package/dist/containers/Tenant/{Describe → Diagnostics/Describe}/Describe.scss +5 -3
  110. package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +27 -0
  111. package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +88 -0
  112. package/dist/containers/Tenant/Diagnostics/Diagnostics.scss +50 -0
  113. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +208 -0
  114. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +75 -0
  115. package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.js +191 -0
  116. package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.scss +79 -0
  117. package/dist/containers/Tenant/{Healthcheck → Diagnostics/Healthcheck}/IssuesViewer/IssueViewer.scss +25 -13
  118. package/dist/containers/Tenant/{Healthcheck → Diagnostics/Healthcheck}/IssuesViewer/IssuesViewer.js +2 -2
  119. package/dist/containers/Tenant/{Schema → Diagnostics}/HotKeys/HotKeys.js +14 -8
  120. package/dist/containers/Tenant/{Schema → Diagnostics}/HotKeys/HotKeys.scss +7 -5
  121. package/dist/containers/Tenant/{Network → Diagnostics/Network}/Network.js +39 -9
  122. package/dist/containers/Tenant/{Network → Diagnostics/Network}/Network.scss +35 -36
  123. package/dist/containers/Tenant/{Network → Diagnostics/Network}/NodeNetwork/NodeNetwork.js +0 -0
  124. package/dist/containers/Tenant/{Network → Diagnostics/Network}/NodeNetwork/NodeNetwork.scss +11 -9
  125. package/dist/containers/Tenant/Diagnostics/Overview/Overview.scss +13 -0
  126. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +123 -0
  127. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +200 -0
  128. package/dist/{components → containers/Tenant/Diagnostics}/TenantOverview/TenantOverview.scss +24 -17
  129. package/dist/containers/Tenant/{TopQueries → Diagnostics/TopQueries}/TopQueries.js +32 -30
  130. package/dist/containers/Tenant/{TopQueries → Diagnostics/TopQueries}/TopQueries.scss +10 -9
  131. package/dist/containers/Tenant/{TopShards → Diagnostics/TopShards}/TopShards.js +25 -29
  132. package/dist/containers/Tenant/{TopShards → Diagnostics/TopShards}/TopShards.scss +1 -13
  133. package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.scss +38 -0
  134. package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +104 -0
  135. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.scss +175 -0
  136. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +319 -0
  137. package/dist/containers/Tenant/Preview/Preview.js +50 -12
  138. package/dist/containers/Tenant/Preview/Preview.scss +45 -3
  139. package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.scss +85 -0
  140. package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.tsx +95 -0
  141. package/dist/containers/Tenant/QueryEditor/QueryEditor.js +319 -268
  142. package/dist/containers/Tenant/QueryEditor/QueryEditor.scss +47 -18
  143. package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +190 -75
  144. package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.scss +47 -11
  145. package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.js +89 -20
  146. package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.scss +60 -6
  147. package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.js +10 -23
  148. package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.scss +15 -7
  149. package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.js +7 -3
  150. package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.scss +28 -17
  151. package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.js +7 -7
  152. package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.scss +1 -11
  153. package/dist/containers/Tenant/Schema/SchemaNode/SchemaNode.js +37 -17
  154. package/dist/containers/Tenant/Schema/SchemaNode/SchemaNode.scss +33 -12
  155. package/dist/containers/Tenant/Schema/SchemaNodeActions/SchemaNodeActions.scss +17 -0
  156. package/dist/containers/Tenant/Schema/SchemaNodeActions/SchemaNodeActions.tsx +125 -0
  157. package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.js +5 -4
  158. package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.scss +6 -2
  159. package/dist/containers/Tenant/Schema/SchemaViewer/SchemaViewer.js +53 -34
  160. package/dist/containers/Tenant/Schema/SchemaViewer/SchemaViewer.scss +1 -22
  161. package/dist/containers/Tenant/Tenant.scss +3 -32
  162. package/dist/containers/Tenant/Tenant.tsx +161 -0
  163. package/dist/containers/Tenant/TenantPages.tsx +48 -0
  164. package/dist/containers/Tenant/utils/ToggleButton.scss +26 -0
  165. package/dist/containers/Tenant/utils/paneVisibilityToggleHelpers.tsx +126 -0
  166. package/dist/containers/Tenants/Tenants.js +41 -55
  167. package/dist/containers/Tenants/Tenants.scss +4 -17
  168. package/dist/containers/UserSettings/UserSettings.tsx +0 -2
  169. package/dist/containers/Vdisk/Vdisk.scss +6 -4
  170. package/dist/containers/VdiskPdiskNode/VdiskPdiskNode.js +1 -1
  171. package/dist/containers/VdiskPdiskNode/VdiskPdiskNode.scss +5 -5
  172. package/dist/{routes.js → routes.ts} +14 -4
  173. package/dist/store/reducers/clusterNodes.js +1 -1
  174. package/dist/store/reducers/executeQuery.js +36 -2
  175. package/dist/store/reducers/fullscreen.ts +31 -0
  176. package/dist/store/reducers/header.ts +23 -0
  177. package/dist/store/reducers/hotKeys.js +1 -1
  178. package/dist/store/reducers/index.js +6 -0
  179. package/dist/store/reducers/saveQuery.ts +33 -0
  180. package/dist/store/reducers/schema.js +14 -0
  181. package/dist/store/reducers/shardsWorkload.js +1 -1
  182. package/dist/store/state-url-mapping.js +1 -1
  183. package/dist/store/utils.js +2 -6
  184. package/dist/styles/mixins.scss +49 -34
  185. package/dist/utils/autofetcher.ts +51 -0
  186. package/dist/utils/constants.js +26 -7
  187. package/dist/utils/createToast.tsx +23 -0
  188. package/dist/utils/getNodesColumns.js +25 -28
  189. package/dist/utils/index.js +6 -2
  190. package/package.json +8 -4
  191. package/dist/components/SplitPane/SplitPane.js +0 -368
  192. package/dist/components/TenantOverview/TenantOverview.js +0 -148
  193. package/dist/containers/Cluster/Cluster.js +0 -168
  194. package/dist/containers/Header/Header.js +0 -88
  195. package/dist/containers/StorageV2/DiskStateProgressBar/DiskStateProgressBar.scss +0 -81
  196. package/dist/containers/Tenant/Compute/Compute.scss +0 -6
  197. package/dist/containers/Tenant/Healthcheck/Healthcheck.js +0 -116
  198. package/dist/containers/Tenant/Healthcheck/Healthcheck.scss +0 -64
  199. package/dist/containers/Tenant/Schema/Info/Info.js +0 -84
  200. package/dist/containers/Tenant/Schema/Info/Info.scss +0 -3
  201. package/dist/containers/Tenant/Schema/SchemaMain/SchemaMain.js +0 -439
  202. package/dist/containers/Tenant/Schema/SchemaMain/SchemaMain.scss +0 -90
  203. package/dist/containers/Tenant/Schema/SchemaPages.js +0 -56
  204. package/dist/containers/Tenant/Tenant.js +0 -199
  205. package/dist/containers/Tenant/TenantPages.js +0 -35
@@ -1,16 +1,16 @@
1
- import React from 'react';
1
+ import {useEffect, useReducer, useRef, useState} from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  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
7
  import DataTable from '@yandex-cloud/react-data-table';
8
- import {Button, Toaster, CopyToClipboard} from '@yandex-cloud/uikit';
8
+ import {Button} from '@yandex-cloud/uikit';
9
9
  import {Select} from '@yandex-cloud/uikit/build/esm/components/unstable/Select';
10
10
  import SplitPane from '../../../components/SplitPane';
11
11
 
12
- import Pagination from '../../../components/Pagination/Pagination';
13
12
  import SaveQuery from './SaveQuery/SaveQuery';
13
+ import SavedQueries from './SavedQueries/SavedQueries';
14
14
  import Icon from '../../../components/Icon/Icon';
15
15
  import QueryResult from './QueryResult/QueryResult';
16
16
  import QueryExplain from './QueryExplain/QueryExplain';
@@ -23,18 +23,31 @@ import {
23
23
  goToNextQuery,
24
24
  selectRunAction,
25
25
  RUN_ACTIONS_VALUES,
26
+ MONACO_HOT_KEY_ACTIONS,
27
+ setMonacoHotKey,
26
28
  } from '../../../store/reducers/executeQuery';
27
29
  import {getExplainQuery, getExplainQueryAst} from '../../../store/reducers/explainQuery';
28
30
  import {showTooltip} from '../../../store/reducers/tooltip';
29
31
  import {getSettingValue, setSettingValue} from '../../../store/reducers/settings';
30
- import {THEME_KEY, DEFAULT_SIZE_RESULT_PANE_KEY, SAVED_QUERIES_KEY} from '../../../utils/constants';
32
+ import {
33
+ DEFAULT_IS_QUERY_RESULT_COLLAPSED,
34
+ DEFAULT_SIZE_RESULT_PANE_KEY,
35
+ DEFAULT_TABLE_SETTINGS,
36
+ SAVED_QUERIES_KEY,
37
+ } from '../../../utils/constants';
31
38
  import {prepareQueryResponse} from '../../../utils/index';
32
39
 
33
40
  import {parseJson} from '../../../utils/utils';
34
41
 
35
42
  import './QueryEditor.scss';
36
-
37
- const toaster = new Toaster();
43
+ import Divider from '../../../components/Divider/Divider';
44
+ import QueriesHistory from './QueriesHistory/QueriesHistory';
45
+ import {
46
+ PaneVisibilityActionTypes,
47
+ paneVisibilityToggleReducerCreator,
48
+ } from '../utils/paneVisibilityToggleHelpers';
49
+ import Preview from '../Preview/Preview';
50
+ import {setShowPreview} from '../../../store/reducers/schema';
38
51
 
39
52
  export const RUN_ACTIONS = [
40
53
  {value: RUN_ACTIONS_VALUES.script, content: 'Run Script'},
@@ -42,11 +55,13 @@ export const RUN_ACTIONS = [
42
55
  ];
43
56
 
44
57
  const TABLE_SETTINGS = {
45
- displayIndices: false,
46
- syncHeadOnResize: true,
47
- stickyHead: DataTable.MOVING,
58
+ ...DEFAULT_TABLE_SETTINGS,
48
59
  sortable: false,
60
+ dynamicItemSizeGetter: () => 40,
61
+ dynamicRenderType: 'variable',
62
+ stripedRows: true,
49
63
  };
64
+
50
65
  const EDITOR_OPTIONS = {
51
66
  automaticLayout: true,
52
67
  selectOnLineNumbers: true,
@@ -63,66 +78,116 @@ const RESULT_TYPES = {
63
78
 
64
79
  const b = cn('query-editor');
65
80
 
66
- class QueryEditor extends React.Component {
67
- static propTypes = {
68
- sendQuery: PropTypes.func,
69
- path: PropTypes.string,
70
- response: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
71
- executeQuery: PropTypes.object,
72
- explainQuery: PropTypes.object,
73
- showTooltip: PropTypes.func,
74
- theme: PropTypes.string,
75
- };
81
+ const propTypes = {
82
+ sendQuery: PropTypes.func,
83
+ path: PropTypes.string,
84
+ response: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
85
+ executeQuery: PropTypes.object,
86
+ explainQuery: PropTypes.object,
87
+ showTooltip: PropTypes.func,
88
+ setMonacoHotKey: PropTypes.func,
89
+ theme: PropTypes.string,
90
+ type: PropTypes.string,
91
+ };
76
92
 
77
- state = {
78
- resultType: RESULT_TYPES.EXECUTE,
79
- runAction: RUN_ACTIONS[0].value,
80
- };
93
+ const initialTenantCommonInfoState = {
94
+ triggerExpand: false,
95
+ triggerCollapse: false,
96
+ collapsed: true,
97
+ };
98
+ function QueryEditor(props) {
99
+ const [resultType, setResultType] = useState(RESULT_TYPES.EXECUTE);
81
100
 
82
- editorRef = null;
101
+ const [resultVisibilityState, dispatchResultVisibilityState] = useReducer(
102
+ paneVisibilityToggleReducerCreator(DEFAULT_IS_QUERY_RESULT_COLLAPSED),
103
+ initialTenantCommonInfoState,
104
+ );
83
105
 
84
- componentDidMount() {
85
- this.updateEditor();
106
+ const editorRef = useRef(null);
86
107
 
87
- window.addEventListener('resize', this.onChangeWindow);
88
- window.addEventListener('storage', this.storageEventHandler);
89
- }
108
+ useEffect(() => {
109
+ updateEditor();
90
110
 
91
- checkIfHasUnsavedInput(e) {
92
- e.preventDefault();
93
- // Chrome requires returnValue to be set
94
- e.returnValue = '';
95
- }
111
+ window.addEventListener('resize', onChangeWindow);
112
+ window.addEventListener('storage', storageEventHandler);
96
113
 
97
- componentWillUnmount() {
98
- window.removeEventListener('resize', this.onChangeWindow);
99
- window.removeEventListener('storage', this.storageEventHandler);
100
- window.onbeforeunload = undefined;
101
- }
114
+ return () => {
115
+ window.removeEventListener('resize', onChangeWindow);
116
+ window.removeEventListener('storage', storageEventHandler);
117
+ window.onbeforeunload = undefined;
118
+ props.setMonacoHotKey(null);
119
+ };
120
+ }, []);
121
+
122
+ useEffect(() => {
123
+ dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerCollapse);
124
+ }, []);
125
+
126
+ useEffect(() => {
127
+ const {showPreview} = props;
128
+ if (showPreview && resultVisibilityState.collapsed) {
129
+ dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerExpand);
130
+ }
131
+ }, [props.showPreview, resultVisibilityState.collapsed]);
102
132
 
103
- componentDidUpdate() {
133
+ useEffect(() => {
104
134
  const {
105
135
  explainQuery: {data},
106
136
  executeQuery: {input, history},
107
- } = this.props;
137
+ } = props;
108
138
 
109
139
  const hasUnsavedInput = input
110
140
  ? input !== history.queries[history.queries?.length - 1]
111
141
  : false;
112
142
 
113
143
  if (hasUnsavedInput) {
114
- window.onbeforeunload = this.checkIfHasUnsavedInput;
144
+ window.onbeforeunload = checkIfHasUnsavedInput;
115
145
  } else {
116
146
  window.onbeforeunload = undefined;
117
147
  }
118
148
 
119
- if (!data || this.state.resultType !== RESULT_TYPES.EXPLAIN) {
149
+ if (!data || resultType !== RESULT_TYPES.EXPLAIN) {
120
150
  return;
121
151
  }
122
- }
152
+ }, [props.executeQuery, props.executeQuery]);
153
+
154
+ useEffect(() => {
155
+ const {monacoHotKey, setMonacoHotKey} = props;
156
+ if (monacoHotKey === null) {
157
+ return
158
+ }
159
+ setMonacoHotKey(null);
160
+ switch (monacoHotKey) {
161
+ case MONACO_HOT_KEY_ACTIONS.sendQuery: {
162
+ return handleSendClick();
163
+ }
164
+ case MONACO_HOT_KEY_ACTIONS.goPrev: {
165
+ return handlePreviousHistoryClick();
166
+ }
167
+ case MONACO_HOT_KEY_ACTIONS.goNext: {
168
+ return handleNextHistoryClick();
169
+ }
170
+ case MONACO_HOT_KEY_ACTIONS.getExplain: {
171
+ return handleGetExplainQueryClick();
172
+ }
173
+ default: {
174
+ return;
175
+ }
176
+ }
177
+ }, [props.monacoHotKey]);
178
+
179
+ const checkIfHasUnsavedInput = (e) => {
180
+ e.preventDefault();
181
+ // Chrome requires returnValue to be set
182
+ e.returnValue = '';
183
+ };
184
+
185
+ const handleKeyBinding = (value) => {
186
+ return () => props.setMonacoHotKey(value);
187
+ };
123
188
 
124
- editorDidMount = (editor, monaco) => {
125
- this.editorRef = editor;
189
+ const editorDidMount = (editor, monaco) => {
190
+ editorRef.current = editor;
126
191
  editor.focus();
127
192
  editor.addAction({
128
193
  id: 'run',
@@ -139,9 +204,7 @@ class QueryEditor extends React.Component {
139
204
  contextMenuOrder: 1,
140
205
  // Method that will be executed when the action is triggered.
141
206
  // @param editor The editor instance is passed in as a convinience
142
- run: () => {
143
- this.handleSendClick();
144
- },
207
+ run: handleKeyBinding(MONACO_HOT_KEY_ACTIONS.sendQuery),
145
208
  });
146
209
 
147
210
  editor.addAction({
@@ -153,9 +216,7 @@ class QueryEditor extends React.Component {
153
216
  ],
154
217
  contextMenuGroupId: CONTEXT_MENU_GROUP_ID,
155
218
  contextMenuOrder: 2,
156
- run: () => {
157
- this.handlePreviousHistoryClick();
158
- },
219
+ run: handleKeyBinding(MONACO_HOT_KEY_ACTIONS.goPrev),
159
220
  });
160
221
  editor.addAction({
161
222
  id: 'next-query',
@@ -166,9 +227,7 @@ class QueryEditor extends React.Component {
166
227
  ],
167
228
  contextMenuGroupId: CONTEXT_MENU_GROUP_ID,
168
229
  contextMenuOrder: 3,
169
- run: () => {
170
- this.handleNextHistoryClick();
171
- },
230
+ run: handleKeyBinding(MONACO_HOT_KEY_ACTIONS.goNext),
172
231
  });
173
232
 
174
233
  editor.addAction({
@@ -184,63 +243,72 @@ class QueryEditor extends React.Component {
184
243
  keybindingContext: null,
185
244
  contextMenuGroupId: CONTEXT_MENU_GROUP_ID,
186
245
  contextMenuOrder: 4,
187
- run: () => {
188
- this.handleGetExplainQueryClick();
189
- },
246
+ run: handleKeyBinding(MONACO_HOT_KEY_ACTIONS.getExplain),
190
247
  });
191
248
  };
192
- onChange = (newValue) => {
193
- this.props.changeUserInput({input: newValue});
249
+ const onChange = (newValue) => {
250
+ props.changeUserInput({input: newValue});
194
251
  };
195
252
 
196
- handleSendClick = () => {
253
+ const handleSendClick = () => {
197
254
  const {
198
255
  path,
199
256
  executeQuery: {input, history, runAction},
200
257
  sendQuery,
201
258
  saveQueryToHistory,
202
- } = this.props;
259
+ setShowPreview,
260
+ } = props;
203
261
 
204
- this.setState({resultType: RESULT_TYPES.EXECUTE});
262
+ setResultType(RESULT_TYPES.EXECUTE);
205
263
  sendQuery({query: input, database: path, action: runAction});
264
+ setShowPreview(false);
206
265
 
207
266
  const {queries, currentIndex} = history;
208
267
  if (input !== queries[currentIndex]) {
209
268
  saveQueryToHistory(input);
210
269
  }
270
+ dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerExpand);
211
271
  };
212
272
 
213
- handleCancelClick = () => {
214
- this.props.cancelQuery();
215
- };
216
-
217
- handleGetExplainQueryClick = () => {
273
+ const handleGetExplainQueryClick = () => {
218
274
  const {
219
275
  path,
220
276
  executeQuery: {input},
221
277
  getExplainQuery,
222
- } = this.props;
223
-
224
- this.setState({resultType: RESULT_TYPES.EXPLAIN}, () => {
225
- getExplainQuery({query: input, database: path});
226
- });
278
+ setShowPreview,
279
+ } = props;
280
+ setResultType(RESULT_TYPES.EXPLAIN);
281
+ getExplainQuery({query: input, database: path});
282
+ setShowPreview(false);
283
+ dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerExpand);
227
284
  };
228
285
 
229
- handleAstQuery = () => {
286
+ const handleAstQuery = () => {
230
287
  const {
231
288
  path,
232
289
  executeQuery: {input},
233
290
  getExplainQueryAst,
234
- } = this.props;
291
+ } = props;
235
292
  getExplainQueryAst({query: input, database: path});
236
293
  };
237
294
 
238
- renderExecuteQuery = () => {
295
+ const onCollapseResultHandler = () => {
296
+ dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerCollapse);
297
+ };
298
+ const onExpandResultHandler = () => {
299
+ dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerExpand);
300
+ };
301
+
302
+ const onSplitStartDrugAdditional = () => {
303
+ dispatchResultVisibilityState(PaneVisibilityActionTypes.clear);
304
+ };
305
+
306
+ const renderExecuteQuery = () => {
239
307
  const {
240
308
  executeQuery: {data, error, stats},
241
309
  showTooltip,
242
- } = this.props;
243
- const result = this.getExecuteResult();
310
+ } = props;
311
+ const result = getExecuteResult();
244
312
  const shouldRenderAnswer = result.length || error;
245
313
 
246
314
  if (!shouldRenderAnswer) {
@@ -265,56 +333,62 @@ class QueryEditor extends React.Component {
265
333
  }
266
334
 
267
335
  const preparedData = prepareQueryResponse(data);
336
+
268
337
  const content = columns.length ? (
269
338
  <DataTable
270
339
  columns={columns}
271
340
  data={preparedData}
272
341
  settings={TABLE_SETTINGS}
273
- theme="common"
342
+ theme="yandex-cloud"
274
343
  />
275
344
  ) : (
276
345
  <div>{result}</div>
277
346
  );
278
- return <QueryResult result={content} stats={stats} />;
347
+ const results = getPreparedResult();
348
+ const disabled = !results.length || resultType !== RESULT_TYPES.EXECUTE;
349
+ return (
350
+ <QueryResult
351
+ result={content}
352
+ stats={stats}
353
+ error={Boolean(error)}
354
+ textResults={results}
355
+ copyDisabled={disabled}
356
+ isResultsCollapsed={resultVisibilityState.collapsed}
357
+ onExpandResults={onExpandResultHandler}
358
+ onCollapseResults={onCollapseResultHandler}
359
+ />
360
+ );
279
361
  };
280
-
281
- renderExplainQuery = () => {
362
+ const renderExplainQuery = () => {
282
363
  const {
283
364
  explainQuery: {data, dataAst, error, loading, loadingAst},
284
365
  theme,
285
- } = this.props;
286
-
287
- if (error) {
288
- return error.data ? error.data : error;
289
- } else if (!data && !loading) {
290
- return 'Explain of query is empty';
291
- } else if (!data) {
292
- return null;
293
- } else if (!data.nodes.length) {
294
- return 'There is no explanation for the request';
295
- }
366
+ } = props;
296
367
 
297
368
  return (
298
369
  <QueryExplain
370
+ error={error}
299
371
  explain={data}
300
- astQuery={this.handleAstQuery}
372
+ astQuery={handleAstQuery}
301
373
  ast={dataAst?.ast}
374
+ loading={loading}
302
375
  loadingAst={loadingAst}
303
376
  theme={theme}
377
+ isResultsCollapsed={resultVisibilityState.collapsed}
378
+ onExpandResults={onExpandResultHandler}
379
+ onCollapseResults={onCollapseResultHandler}
304
380
  />
305
381
  );
306
382
  };
307
383
 
308
- renderResult = () => {
309
- const {resultType} = this.state;
310
-
384
+ const renderResult = () => {
311
385
  let result;
312
386
  switch (resultType) {
313
387
  case RESULT_TYPES.EXECUTE:
314
- result = this.renderExecuteQuery();
388
+ result = renderExecuteQuery();
315
389
  break;
316
390
  case RESULT_TYPES.EXPLAIN:
317
- result = this.renderExplainQuery();
391
+ result = renderExplainQuery();
318
392
  break;
319
393
  default:
320
394
  result = null;
@@ -323,15 +397,24 @@ class QueryEditor extends React.Component {
323
397
  return result;
324
398
  };
325
399
 
326
- handlePreviousHistoryClick = () => {
400
+ const renderPreview = () => {
401
+ const {path, type, currentSchema = {}} = props;
402
+ const partCount = currentSchema?.PathDescription?.TableStats?.PartCount;
403
+ // onExpandResultHandler();
404
+ return (
405
+ <Preview database={path} table={currentSchema.Path} type={type} partCount={partCount} />
406
+ );
407
+ };
408
+
409
+ const handlePreviousHistoryClick = () => {
327
410
  const {
328
411
  changeUserInput,
329
412
  executeQuery: {history},
330
413
  goToPreviousQuery,
331
- } = this.props;
414
+ } = props;
332
415
  const {queries, currentIndex} = history;
333
416
 
334
- if (this.previousButtonIsDisabled()) {
417
+ if (previousButtonIsDisabled()) {
335
418
  return;
336
419
  }
337
420
 
@@ -339,15 +422,15 @@ class QueryEditor extends React.Component {
339
422
  changeUserInput({input: queries[currentIndex - 1]});
340
423
  };
341
424
 
342
- handleNextHistoryClick = () => {
425
+ const handleNextHistoryClick = () => {
343
426
  const {
344
427
  changeUserInput,
345
428
  executeQuery: {history},
346
429
  goToNextQuery,
347
- } = this.props;
430
+ } = props;
348
431
  const {queries, currentIndex} = history;
349
432
 
350
- if (this.nextButtonIsDisabled()) {
433
+ if (nextButtonIsDisabled()) {
351
434
  return;
352
435
  }
353
436
 
@@ -355,55 +438,38 @@ class QueryEditor extends React.Component {
355
438
  changeUserInput({input: queries[currentIndex + 1]});
356
439
  };
357
440
 
358
- previousButtonIsDisabled = () => {
441
+ const previousButtonIsDisabled = () => {
359
442
  const {
360
443
  history: {currentIndex},
361
- } = this.props.executeQuery;
444
+ } = props.executeQuery;
362
445
 
363
446
  return currentIndex <= 0;
364
447
  };
365
448
 
366
- nextButtonIsDisabled = () => {
449
+ const nextButtonIsDisabled = () => {
367
450
  const {
368
451
  history: {queries, currentIndex},
369
- } = this.props.executeQuery;
452
+ } = props.executeQuery;
370
453
 
371
454
  return queries.length - 1 === currentIndex;
372
455
  };
373
456
 
374
- renderHistoryNavigation = () => {
457
+ const renderHistoryNavigation = () => {
458
+ const {changeUserInput} = props;
375
459
  return (
376
460
  <div className={b('history-controls')}>
377
- <span className={b('history-label')}>History:</span>
378
- <Pagination
379
- previous={{
380
- handler: this.handlePreviousHistoryClick,
381
- hotkeyHandler: this.handlePreviousHistoryClick,
382
- hotkeyScope: 'all',
383
- hotkey: 'ctrl+up, command+up',
384
- tooltip: 'Previous query [ctrl+↑]',
385
- disabled: this.previousButtonIsDisabled(),
386
- }}
387
- next={{
388
- handler: this.handleNextHistoryClick,
389
- hotkeyHandler: this.handleNextHistoryClick,
390
- hotkeyScope: 'all',
391
- hotkey: 'ctrl+down, command+down',
392
- tooltip: 'Next query [ctrl+↓]',
393
- disabled: this.nextButtonIsDisabled(),
394
- }}
395
- />
461
+ <QueriesHistory changeUserInput={changeUserInput} />
396
462
  </div>
397
463
  );
398
464
  };
399
465
 
400
- getExecuteResult = () => {
466
+ const getExecuteResult = () => {
401
467
  const {
402
468
  data = [],
403
469
  error,
404
470
  loading,
405
471
  history: {queries},
406
- } = this.props.executeQuery;
472
+ } = props.executeQuery;
407
473
 
408
474
  if (error) {
409
475
  return error.data || error;
@@ -416,10 +482,10 @@ class QueryEditor extends React.Component {
416
482
  }
417
483
  };
418
484
 
419
- getPreparedResult = () => {
485
+ const getPreparedResult = () => {
420
486
  const {
421
487
  executeQuery: {data},
422
- } = this.props;
488
+ } = props;
423
489
  const columnDivider = '\t';
424
490
  const rowDivider = '\n';
425
491
 
@@ -447,68 +513,28 @@ class QueryEditor extends React.Component {
447
513
  .join(rowDivider);
448
514
  };
449
515
 
450
- renderClipboardButton = () => {
451
- const results = this.getPreparedResult();
452
- const {resultType} = this.state;
453
- const disabled = !results.length || resultType !== RESULT_TYPES.EXECUTE;
454
-
455
- return (
456
- <CopyToClipboard text={results} timeout={1000}>
457
- {(state) => {
458
- if (state === 'success') {
459
- toaster.createToast({
460
- name: 'Copied',
461
- title: 'Results were copied to clipboard successfully',
462
- type: state,
463
- });
464
- }
465
-
466
- return (
467
- <Button onClick={() => {}} disabled={disabled}>
468
- Copy results
469
- </Button>
470
- );
471
- }}
472
- </CopyToClipboard>
473
- );
474
- };
475
-
476
- onChangeWindow = _.throttle(() => {
477
- this.updateEditor();
516
+ const onChangeWindow = _.throttle(() => {
517
+ updateEditor();
478
518
  }, 100);
479
519
 
480
- storageEventHandler = (event) => {
520
+ const storageEventHandler = (event) => {
481
521
  if (event.key === SAVED_QUERIES_KEY) {
482
- this.props.setSettingValue(SAVED_QUERIES_KEY, event.newValue);
522
+ props.setSettingValue(SAVED_QUERIES_KEY, event.newValue);
483
523
  }
484
524
  };
485
525
 
486
- updateEditor = () => {
487
- if (this.editorRef) {
488
- this.editorRef.layout();
526
+ const updateEditor = () => {
527
+ if (editorRef.current) {
528
+ editorRef.current.layout();
489
529
  }
490
530
  };
491
531
 
492
- onChangeSplit = (size) => {
493
- this.setDefaultSizeResultPane(size);
494
- this.updateEditor();
495
- };
496
- setDefaultSizeResultPane = (size) => {
497
- localStorage.setItem(DEFAULT_SIZE_RESULT_PANE_KEY, size);
498
- };
499
- getDefaultSizeResultPane = () => {
500
- let size = parseInt(localStorage.getItem(DEFAULT_SIZE_RESULT_PANE_KEY), 10) || 250;
501
- size = `${size}px`;
502
-
503
- return size;
504
- };
505
-
506
- onSaveQueryHandler = (queryName) => {
532
+ const onSaveQueryHandler = (queryName) => {
507
533
  const {
508
534
  executeQuery: {input},
509
535
  savedQueries = [],
510
536
  setSettingValue,
511
- } = this.props;
537
+ } = props;
512
538
 
513
539
  const queryIndex = savedQueries.findIndex(
514
540
  (el) => el.name.toLowerCase() === queryName.toLowerCase(),
@@ -524,112 +550,133 @@ class QueryEditor extends React.Component {
524
550
  setSettingValue(SAVED_QUERIES_KEY, JSON.stringify(newSavedQueries));
525
551
  };
526
552
 
527
- onDeleteQueryHandler = (queryName) => {
528
- const {savedQueries = [], setSettingValue} = this.props;
553
+ const onDeleteQueryHandler = (queryName) => {
554
+ const {savedQueries = [], setSettingValue} = props;
529
555
  const newSavedQueries = savedQueries.filter(
530
556
  (el) => el.name.toLowerCase() !== queryName.toLowerCase(),
531
557
  );
532
558
  setSettingValue(SAVED_QUERIES_KEY, JSON.stringify(newSavedQueries));
533
559
  };
534
560
 
535
- render() {
536
- const {executeQuery, explainQuery, theme, savedQueries, changeUserInput} = this.props;
561
+ const renderControls = () => {
562
+ const {executeQuery, explainQuery, savedQueries} = props;
537
563
  const {runAction} = executeQuery;
538
564
  const runIsDisabled = !executeQuery.input || executeQuery.loading;
539
- const runText = _.find(RUN_ACTIONS, {value: runAction}).title;
540
- const loadingResult = executeQuery.loading || explainQuery.loading;
541
- const result = this.renderResult();
542
- const showSecondPane = Boolean(result) || loadingResult;
543
- const defaultSizeResultPane = this.getDefaultSizeResultPane();
544
-
565
+ const runText = _.find(RUN_ACTIONS, {value: runAction}).content;
545
566
  return (
546
- <div className={b()}>
547
- <SplitPane
548
- split="horizontal"
549
- primary="second"
550
- minSize={100}
551
- maxSize={-57}
552
- defaultSize={defaultSizeResultPane}
553
- hidePane={!showSecondPane}
554
- pane1Style={{minHeight: '50px'}}
555
- onChange={this.onChangeSplit}
567
+ <div className={b('controls')}>
568
+ <div className={b('control-run')}>
569
+ <Button
570
+ onClick={handleSendClick}
571
+ view="action"
572
+ pin="round-brick"
573
+ disabled={runIsDisabled}
574
+ loading={executeQuery.loading}
575
+ >
576
+ <Icon name="startPlay" viewBox="0 0 16 16" width={16} height={16} />
577
+ {runText}
578
+ </Button>
579
+ <Select
580
+ view="action"
581
+ options={RUN_ACTIONS}
582
+ value={undefined}
583
+ disabled={runIsDisabled}
584
+ pin="brick-round"
585
+ // renderSwitcher={() => (
586
+ // <div className={b('run-switcher')}>
587
+ // <Button
588
+ // view="action"
589
+ // pin="brick-round"
590
+ // disabled={runIsDisabled}
591
+ // loading={executeQuery.loading}
592
+ // >
593
+ // <Icon name="chevron-down" width={16} height={16} />
594
+ // </Button>
595
+ // </div>
596
+ // )}
597
+ onUpdate={(value) => {
598
+ props.selectRunAction(value[0]);
599
+ }}
600
+ />
601
+ </div>
602
+ <Button
603
+ onClick={handleGetExplainQueryClick}
604
+ disabled={!executeQuery.input}
605
+ loading={explainQuery.loading}
556
606
  >
557
- <div className={b('pane-wrapper')}>
558
- <div className={b('monaco-wrapper')}>
559
- <div className={b('monaco')}>
560
- <MonacoEditor
561
- language="sql"
562
- value={executeQuery.input}
563
- options={EDITOR_OPTIONS}
564
- onChange={this.onChange}
565
- editorDidMount={this.editorDidMount}
566
- theme={`vs-${theme}`}
567
- />
568
- </div>
569
- </div>
570
- <div className={b('controls')}>
571
- <div className={b('control-run')}>
572
- <Button
573
- onClick={this.handleSendClick}
574
- view="action"
575
- pin="round-brick"
576
- disabled={runIsDisabled}
577
- loading={executeQuery.loading}
578
- >
579
- {runText}
580
- </Button>
581
- <Select
582
- options={RUN_ACTIONS}
583
- value={runAction}
584
- disabled={runIsDisabled}
585
- renderSwitcher={() => (
586
- <div className={b('run-switcher')}>
587
- <Button
588
- view="action"
589
- pin="brick-round"
590
- disabled={runIsDisabled}
591
- loading={executeQuery.loading}
592
- >
593
- <Icon name="chevron-down" width={16} height={16} />
594
- </Button>
595
- </div>
596
- )}
597
- onUpdate={(value) => {
598
- this.props.selectRunAction(value);
599
- }}
600
- />
601
- </div>
602
- <Button
603
- onClick={this.handleGetExplainQueryClick}
604
- disabled={!executeQuery.input}
605
- loading={explainQuery.loading}
606
- >
607
- Explain
608
- </Button>
609
- {this.renderHistoryNavigation()}
610
- {this.renderClipboardButton()}
611
- <SaveQuery
612
- savedQueries={savedQueries}
613
- onSaveQuery={this.onSaveQueryHandler}
614
- saveButtonDisabled={runIsDisabled}
615
- changeUserInput={changeUserInput}
616
- onDeleteQuery={this.onDeleteQueryHandler}
607
+ Explain
608
+ </Button>
609
+ <Divider />
610
+ <SaveQuery
611
+ savedQueries={savedQueries}
612
+ onSaveQuery={onSaveQueryHandler}
613
+ saveButtonDisabled={runIsDisabled}
614
+ />
615
+ </div>
616
+ );
617
+ };
618
+
619
+ const renderUpperControls = () => {
620
+ const {savedQueries, changeUserInput} = props;
621
+
622
+ return (
623
+ <div className={b('upper-controls')}>
624
+ {renderHistoryNavigation()}
625
+ <SavedQueries
626
+ savedQueries={savedQueries}
627
+ changeUserInput={changeUserInput}
628
+ onDeleteQuery={onDeleteQueryHandler}
629
+ />
630
+ </div>
631
+ );
632
+ };
633
+
634
+ const {executeQuery, theme} = props;
635
+ const result = renderResult();
636
+
637
+ return (
638
+ <div className={b()}>
639
+ <SplitPane
640
+ direction="vertical"
641
+ defaultSizePaneKey={DEFAULT_SIZE_RESULT_PANE_KEY}
642
+ triggerCollapse={resultVisibilityState.triggerCollapse}
643
+ triggerExpand={resultVisibilityState.triggerExpand}
644
+ minSize={[0, 52]}
645
+ collapsedSizes={[100, 0]}
646
+ onSplitStartDrugAdditional={onSplitStartDrugAdditional}
647
+ >
648
+ <div className={b('pane-wrapper')}>
649
+ <div className={b('monaco-wrapper')}>
650
+ <div className={b('monaco')}>
651
+ <MonacoEditor
652
+ language="sql"
653
+ value={executeQuery.input}
654
+ options={EDITOR_OPTIONS}
655
+ onChange={onChange}
656
+ editorDidMount={editorDidMount}
657
+ theme={`vs-${theme}`}
617
658
  />
618
659
  </div>
619
660
  </div>
620
- {showSecondPane && <div className={b('pane-wrapper')}>{result}</div>}
621
- </SplitPane>
622
- </div>
623
- );
624
- }
661
+ {renderControls()}
662
+ {renderUpperControls()}
663
+ </div>
664
+ <div className={b('pane-wrapper')}>
665
+ {props.showPreview ? renderPreview() : result}
666
+ </div>
667
+ </SplitPane>
668
+ </div>
669
+ );
625
670
  }
626
671
 
627
672
  const mapStateToProps = (state) => {
628
673
  return {
629
674
  executeQuery: state.executeQuery,
630
675
  explainQuery: state.explainQuery,
631
- theme: getSettingValue(state, THEME_KEY),
632
676
  savedQueries: parseJson(getSettingValue(state, SAVED_QUERIES_KEY)),
677
+ showPreview: state.schema.showPreview,
678
+ currentSchema: state.schema.currentSchema,
679
+ monacoHotKey: state.executeQuery?.monacoHotKey,
633
680
  };
634
681
  };
635
682
 
@@ -644,6 +691,10 @@ const mapDispatchToProps = {
644
691
  getExplainQueryAst,
645
692
  setSettingValue,
646
693
  selectRunAction,
694
+ setShowPreview,
695
+ setMonacoHotKey,
647
696
  };
648
697
 
698
+ QueryEditor.propTypes = propTypes;
699
+
649
700
  export default connect(mapStateToProps, mapDispatchToProps)(QueryEditor);