ydb-embedded-ui 4.6.0 → 4.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/assets/icons/versions.svg +3 -0
  3. package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +6 -1
  4. package/dist/components/Tablet/Tablet.tsx +17 -3
  5. package/dist/components/TabletsStatistic/TabletsStatistic.tsx +23 -16
  6. package/dist/containers/App/Content.js +5 -2
  7. package/dist/containers/AsideNavigation/AsideNavigation.tsx +50 -18
  8. package/dist/containers/Cluster/Cluster.tsx +6 -13
  9. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.tsx +3 -3
  10. package/dist/containers/Cluster/{utils.ts → utils.tsx} +11 -0
  11. package/dist/containers/Header/Header.scss +9 -0
  12. package/dist/containers/Header/Header.tsx +70 -14
  13. package/dist/containers/Header/breadcrumbs.ts +146 -0
  14. package/dist/containers/Node/Node.tsx +21 -27
  15. package/dist/containers/Node/NodePages.ts +10 -6
  16. package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +11 -3
  17. package/dist/containers/Tablet/Tablet.tsx +35 -27
  18. package/dist/containers/Tablet/TabletInfo/TabletInfo.tsx +2 -2
  19. package/dist/containers/TabletsFilters/TabletsFilters.js +13 -15
  20. package/dist/containers/Tenant/Diagnostics/Consumers/columns/columns.tsx +1 -1
  21. package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +5 -1
  22. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +4 -14
  23. package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.scss +5 -3
  24. package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.tsx +1 -1
  25. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +2 -1
  26. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +9 -16
  27. package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +11 -11
  28. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +7 -3
  29. package/dist/containers/Tenant/{QueryEditor/QueryResult/QueryResult.js → Query/ExecuteResult/ExecuteResult.js} +3 -5
  30. package/dist/containers/Tenant/{QueryEditor/QueryResult/QueryResult.scss → Query/ExecuteResult/ExecuteResult.scss} +1 -1
  31. package/dist/containers/Tenant/{QueryEditor/QueryExplain/QueryExplain.js → Query/ExplainResult/ExplainResult.js} +3 -5
  32. package/dist/containers/Tenant/{QueryEditor/QueryExplain/QueryExplain.scss → Query/ExplainResult/ExplainResult.scss} +1 -1
  33. package/dist/containers/Tenant/Query/QueriesHistory/QueriesHistory.scss +20 -0
  34. package/dist/containers/Tenant/Query/QueriesHistory/QueriesHistory.tsx +60 -0
  35. package/dist/containers/Tenant/Query/Query.scss +16 -0
  36. package/dist/containers/Tenant/Query/Query.tsx +73 -0
  37. package/dist/containers/Tenant/{QueryEditor → Query/QueryEditor}/QueryEditor.js +39 -88
  38. package/dist/containers/Tenant/{QueryEditor → Query/QueryEditor}/QueryEditor.scss +7 -23
  39. package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/QueryEditorControls.scss +1 -4
  40. package/dist/containers/Tenant/Query/QueryTabs/QueryTabs.tsx +59 -0
  41. package/dist/containers/Tenant/{QueryEditor → Query}/SaveQuery/SaveQuery.js +5 -5
  42. package/dist/containers/Tenant/Query/SavedQueries/SavedQueries.scss +55 -0
  43. package/dist/containers/Tenant/Query/SavedQueries/SavedQueries.tsx +150 -0
  44. package/dist/containers/Tenant/Query/i18n/en.json +12 -0
  45. package/dist/containers/Tenant/Query/i18n/ru.json +12 -0
  46. package/dist/containers/Tenant/Query/utils/getPreparedResult.ts +30 -0
  47. package/dist/containers/Tenant/Tenant.scss +0 -8
  48. package/dist/containers/Tenant/Tenant.tsx +24 -46
  49. package/dist/containers/Tenant/TenantPages.tsx +7 -16
  50. package/dist/containers/Tenant/utils/constants.ts +10 -0
  51. package/dist/containers/Tenant/utils/schemaActions.ts +9 -4
  52. package/dist/containers/Tenants/Tenants.js +26 -13
  53. package/dist/routes.ts +21 -7
  54. package/dist/services/api.ts +9 -5
  55. package/dist/store/reducers/executeQuery.ts +18 -4
  56. package/dist/store/reducers/header/header.ts +31 -0
  57. package/dist/store/reducers/header/types.ts +54 -0
  58. package/dist/store/reducers/index.ts +1 -1
  59. package/dist/store/reducers/node/types.ts +2 -0
  60. package/dist/store/reducers/settings/settings.ts +8 -3
  61. package/dist/store/reducers/tablet.ts +18 -1
  62. package/dist/store/reducers/tenant/constants.ts +9 -1
  63. package/dist/store/reducers/tenant/tenant.ts +23 -4
  64. package/dist/store/reducers/tenant/types.ts +9 -5
  65. package/dist/store/reducers/topic.ts +1 -1
  66. package/dist/store/state-url-mapping.js +6 -3
  67. package/dist/types/store/executeQuery.ts +4 -1
  68. package/dist/types/store/query.ts +5 -0
  69. package/dist/types/store/tablet.ts +7 -4
  70. package/dist/utils/constants.ts +5 -1
  71. package/package.json +2 -1
  72. package/dist/containers/Tenant/ObjectGeneralTabs/ObjectGeneralTabs.scss +0 -9
  73. package/dist/containers/Tenant/ObjectGeneralTabs/ObjectGeneralTabs.tsx +0 -68
  74. package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.scss +0 -85
  75. package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.tsx +0 -95
  76. package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.js +0 -161
  77. package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.scss +0 -93
  78. package/dist/containers/Tenant/QueryEditor/i18n/en.json +0 -3
  79. package/dist/containers/Tenant/QueryEditor/i18n/ru.json +0 -3
  80. package/dist/store/reducers/header.ts +0 -26
  81. /package/dist/containers/Tenant/{QueryEditor → Query}/Issues/Issues.scss +0 -0
  82. /package/dist/containers/Tenant/{QueryEditor → Query}/Issues/Issues.tsx +0 -0
  83. /package/dist/containers/Tenant/{QueryEditor → Query}/Issues/models.ts +0 -0
  84. /package/dist/containers/Tenant/{QueryEditor → Query}/QueryDuration/QueryDuration.scss +0 -0
  85. /package/dist/containers/Tenant/{QueryEditor → Query}/QueryDuration/QueryDuration.tsx +0 -0
  86. /package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/OldQueryEditorControls.tsx +0 -0
  87. /package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/QueryEditorControls.tsx +0 -0
  88. /package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/shared.ts +0 -0
  89. /package/dist/containers/Tenant/{QueryEditor → Query}/SaveQuery/SaveQuery.scss +0 -0
  90. /package/dist/containers/Tenant/{QueryEditor → Query}/i18n/index.ts +0 -0
@@ -4,7 +4,7 @@ import {useHistory, useLocation} from 'react-router';
4
4
  import qs from 'qs';
5
5
  import cn from 'bem-cn-lite';
6
6
 
7
- import DataTable, {Column, Settings} from '@gravity-ui/react-data-table';
7
+ import DataTable, {Column} from '@gravity-ui/react-data-table';
8
8
  import {Loader} from '@gravity-ui/uikit';
9
9
 
10
10
  import {DateRange, DateRangeValues} from '../../../../components/DateRange';
@@ -22,29 +22,22 @@ import type {KeyValueRow} from '../../../../types/api/query';
22
22
  import type {EPathType} from '../../../../types/api/schema';
23
23
  import type {ITopQueriesFilters} from '../../../../types/store/executeTopQueries';
24
24
  import type {IQueryResult} from '../../../../types/store/query';
25
- import type {TenantGeneralTab} from '../../../../store/reducers/tenant/types';
26
25
 
27
- import {TENANT_GENERAL_TABS_IDS} from '../../../../store/reducers/tenant/constants';
26
+ import {TENANT_PAGE, TENANT_PAGES_IDS, TENANT_QUERY_TABS_ID} from '../../../../store/reducers/tenant/constants';
28
27
  import {formatDateTime, formatNumber} from '../../../../utils';
29
- import {DEFAULT_TABLE_SETTINGS, HOUR_IN_SECONDS} from '../../../../utils/constants';
28
+ import {HOUR_IN_SECONDS} from '../../../../utils/constants';
30
29
  import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
31
30
  import {prepareQueryError} from '../../../../utils/query';
32
- import routes, {createHref} from '../../../../routes';
33
31
 
32
+ import {MAX_QUERY_HEIGHT, QUERY_TABLE_SETTINGS} from '../../utils/constants';
34
33
  import {isColumnEntityType} from '../../utils/schema';
35
- import {TenantTabsGroups} from '../../TenantPages';
34
+ import {TenantTabsGroups, getTenantPath} from '../../TenantPages';
36
35
 
37
36
  import i18n from './i18n';
38
37
  import './TopQueries.scss';
39
38
 
40
39
  const b = cn('kv-top-queries');
41
40
 
42
- const TABLE_SETTINGS: Settings = {
43
- ...DEFAULT_TABLE_SETTINGS,
44
- dynamicRenderType: 'variable',
45
- };
46
-
47
- const MAX_QUERY_HEIGHT = 10;
48
41
  const COLUMNS: Column<KeyValueRow>[] = [
49
42
  {
50
43
  name: 'CPUTimeUs',
@@ -88,7 +81,6 @@ const COLUMNS: Column<KeyValueRow>[] = [
88
81
 
89
82
  interface TopQueriesProps {
90
83
  path: string;
91
- changeSchemaTab: (tab: TenantGeneralTab) => void;
92
84
  type?: EPathType;
93
85
  }
94
86
 
@@ -178,9 +170,10 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
178
170
  ignoreQueryPrefix: true,
179
171
  });
180
172
 
181
- const queryPath = createHref(routes.tenant, undefined, {
173
+ const queryPath = getTenantPath({
182
174
  ...queryParams,
183
- [TenantTabsGroups.general]: TENANT_GENERAL_TABS_IDS.query,
175
+ [TENANT_PAGE]: TENANT_PAGES_IDS.query,
176
+ [TenantTabsGroups.queryTab]: TENANT_QUERY_TABS_ID.newQuery,
184
177
  });
185
178
 
186
179
  history.push(queryPath);
@@ -222,7 +215,7 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
222
215
  <DataTable
223
216
  columns={COLUMNS}
224
217
  data={data}
225
- settings={TABLE_SETTINGS}
218
+ settings={QUERY_TABLE_SETTINGS}
226
219
  onRowClick={handleRowClick}
227
220
  theme="yandex-cloud"
228
221
  />
@@ -1,13 +1,15 @@
1
- import qs from 'qs';
2
1
  import {useLocation} from 'react-router';
3
2
  import cn from 'bem-cn-lite';
4
3
 
5
4
  import {useThemeValue} from '@gravity-ui/uikit';
6
5
 
7
6
  import type {EPathType} from '../../../types/api/schema';
8
- import {TENANT_GENERAL_TABS_IDS} from '../../../store/reducers/tenant/constants';
7
+ import {TENANT_PAGES_IDS} from '../../../store/reducers/tenant/constants';
8
+ import {useSetting} from '../../../utils/hooks';
9
+ import {TENANT_INITIAL_PAGE_KEY} from '../../../utils/constants';
10
+ import {parseQuery} from '../../../routes';
9
11
 
10
- import QueryEditor from '../QueryEditor/QueryEditor';
12
+ import {Query} from '../Query/Query';
11
13
  import Diagnostics from '../Diagnostics/Diagnostics';
12
14
 
13
15
  import './ObjectGeneral.scss';
@@ -22,20 +24,18 @@ interface ObjectGeneralProps {
22
24
 
23
25
  function ObjectGeneral(props: ObjectGeneralProps) {
24
26
  const location = useLocation();
25
-
26
27
  const theme = useThemeValue();
27
28
 
28
- const queryParams = qs.parse(location.search, {
29
- ignoreQueryPrefix: true,
30
- });
29
+ const [initialPage] = useSetting<string>(TENANT_INITIAL_PAGE_KEY);
31
30
 
32
- const {name: tenantName, general: generalTab} = queryParams;
31
+ const queryParams = parseQuery(location);
32
+ const {name: tenantName, tenantPage = initialPage} = queryParams;
33
33
 
34
34
  const renderTabContent = () => {
35
35
  const {type, additionalTenantInfo, additionalNodesInfo} = props;
36
- switch (generalTab) {
37
- case TENANT_GENERAL_TABS_IDS.query: {
38
- return <QueryEditor path={tenantName as string} theme={theme} type={type} />;
36
+ switch (tenantPage) {
37
+ case TENANT_PAGES_IDS.query: {
38
+ return <Query path={tenantName as string} theme={theme} type={type} />;
39
39
  }
40
40
  default: {
41
41
  return (
@@ -47,8 +47,11 @@ import {
47
47
  PaneVisibilityToggleButtons,
48
48
  } from '../utils/paneVisibilityToggleHelpers';
49
49
  import {setShowPreview} from '../../../store/reducers/schema/schema';
50
- import {setTopLevelTab} from '../../../store/reducers/tenant/tenant';
51
- import {TENANT_GENERAL_TABS_IDS} from '../../../store/reducers/tenant/constants';
50
+ import {setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant';
51
+ import {
52
+ TENANT_PAGES_IDS,
53
+ TENANT_QUERY_TABS_ID,
54
+ } from '../../../store/reducers/tenant/constants';
52
55
 
53
56
  import './ObjectSummary.scss';
54
57
 
@@ -275,7 +278,8 @@ function ObjectSummary(props: ObjectSummaryProps) {
275
278
 
276
279
  const onOpenPreview = () => {
277
280
  dispatch(setShowPreview(true));
278
- dispatch(setTopLevelTab(TENANT_GENERAL_TABS_IDS.query));
281
+ dispatch(setTenantPage(TENANT_PAGES_IDS.query));
282
+ dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
279
283
  };
280
284
 
281
285
  const renderCommonInfoControls = () => {
@@ -20,9 +20,9 @@ import {PaneVisibilityToggleButtons} from '../../utils/paneVisibilityToggleHelpe
20
20
  import ResultIssues from '../Issues/Issues';
21
21
  import {QueryDuration} from '../QueryDuration/QueryDuration';
22
22
 
23
- import './QueryResult.scss';
23
+ import './ExecuteResult.scss';
24
24
 
25
- const b = cn('kv-query-result');
25
+ const b = cn('ydb-query-execute-result');
26
26
 
27
27
  const resultOptionsIds = {
28
28
  result: 'result',
@@ -34,7 +34,7 @@ const resultOptions = [
34
34
  {value: resultOptionsIds.stats, content: 'Stats'},
35
35
  ];
36
36
 
37
- function QueryResult(props) {
37
+ export function ExecuteResult(props) {
38
38
  const [activeSection, setActiveSection] = useState(resultOptionsIds.result);
39
39
  const isFullscreen = useSelector((state) => state.fullscreen);
40
40
  const dispatch = useDispatch();
@@ -162,5 +162,3 @@ function QueryResult(props) {
162
162
  </React.Fragment>
163
163
  );
164
164
  }
165
-
166
- export default QueryResult;
@@ -1,6 +1,6 @@
1
1
  @import '../../../../styles/mixins.scss';
2
2
 
3
- .kv-query-result {
3
+ .ydb-query-execute-result {
4
4
  &__result {
5
5
  display: flex;
6
6
  overflow: auto;
@@ -21,9 +21,9 @@ import {LANGUAGE_S_EXPRESSION_ID} from '../../../../utils/monaco';
21
21
 
22
22
  import {PaneVisibilityToggleButtons} from '../../utils/paneVisibilityToggleHelpers';
23
23
 
24
- import './QueryExplain.scss';
24
+ import './ExplainResult.scss';
25
25
 
26
- const b = cn('kv-query-explain');
26
+ const b = cn('ydb-query-explain-result');
27
27
 
28
28
  const EDITOR_OPTIONS = {
29
29
  automaticLayout: true,
@@ -90,7 +90,7 @@ function GraphRoot(props) {
90
90
  return <div id="graphRoot" style={{height: '100vh'}} />;
91
91
  }
92
92
 
93
- function QueryExplain(props) {
93
+ export function ExplainResult(props) {
94
94
  const dispatch = useDispatch();
95
95
  const [activeOption, setActiveOption] = useState(ExplainOptionIds.schema);
96
96
 
@@ -287,5 +287,3 @@ function QueryExplain(props) {
287
287
  </React.Fragment>
288
288
  );
289
289
  }
290
-
291
- export default QueryExplain;
@@ -1,6 +1,6 @@
1
1
  @import '../../../../styles/mixins.scss';
2
2
 
3
- .kv-query-explain {
3
+ .ydb-query-explain-result {
4
4
  &__result {
5
5
  display: flex;
6
6
  overflow: auto;
@@ -0,0 +1,20 @@
1
+ @import '../../../../styles/mixins.scss';
2
+
3
+ .ydb-queries-history {
4
+ overflow: auto;
5
+
6
+ height: 100%;
7
+ padding: 0 16px;
8
+
9
+ @include flex-container();
10
+ @include table-styles;
11
+
12
+ &__query {
13
+ overflow: hidden;
14
+ flex-grow: 1;
15
+
16
+ cursor: pointer;
17
+ white-space: pre;
18
+ text-overflow: ellipsis;
19
+ }
20
+ }
@@ -0,0 +1,60 @@
1
+ import {useDispatch} from 'react-redux';
2
+ import block from 'bem-cn-lite';
3
+
4
+ import DataTable, {Column} from '@gravity-ui/react-data-table';
5
+
6
+ import TruncatedQuery from '../../../../components/TruncatedQuery/TruncatedQuery';
7
+ import {setQueryTab} from '../../../../store/reducers/tenant/tenant';
8
+ import {TENANT_QUERY_TABS_ID} from '../../../../store/reducers/tenant/constants';
9
+ import {useTypedSelector} from '../../../../utils/hooks';
10
+ import {MAX_QUERY_HEIGHT, QUERY_TABLE_SETTINGS} from '../../utils/constants';
11
+
12
+ import i18n from '../i18n';
13
+
14
+ import './QueriesHistory.scss';
15
+
16
+ const b = block('ydb-queries-history');
17
+
18
+ interface QueriesHistoryProps {
19
+ changeUserInput: (value: {input: string}) => void;
20
+ }
21
+
22
+ function QueriesHistory({changeUserInput}: QueriesHistoryProps) {
23
+ const dispatch = useDispatch();
24
+
25
+ const queriesHistory = useTypedSelector((state) => state.executeQuery.history.queries) ?? [];
26
+ const reversedHistory = [...queriesHistory].reverse();
27
+
28
+ const onQueryClick = (queryText: string) => {
29
+ changeUserInput({input: queryText});
30
+ dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
31
+ };
32
+
33
+ const columns: Column<string>[] = [
34
+ {
35
+ name: 'queryText',
36
+ header: 'Query Text',
37
+ render: ({row: query}) => (
38
+ <div className={b('query')}>
39
+ <TruncatedQuery value={query} maxQueryHeight={MAX_QUERY_HEIGHT} />
40
+ </div>
41
+ ),
42
+ sortable: false,
43
+ },
44
+ ];
45
+
46
+ return (
47
+ <div className={b()}>
48
+ <DataTable
49
+ theme="yandex-cloud"
50
+ columns={columns}
51
+ data={reversedHistory}
52
+ settings={QUERY_TABLE_SETTINGS}
53
+ emptyDataMessage={i18n('history.empty')}
54
+ onRowClick={(row) => onQueryClick(row)}
55
+ />
56
+ </div>
57
+ );
58
+ }
59
+
60
+ export default QueriesHistory;
@@ -0,0 +1,16 @@
1
+ @import '../../../styles/mixins.scss';
2
+
3
+ .ydb-query {
4
+ max-height: 100%;
5
+ @include flex-container();
6
+
7
+ &__tabs {
8
+ padding: 13px 20px 16px;
9
+ }
10
+
11
+ &__content {
12
+ overflow: hidden;
13
+
14
+ height: 100%;
15
+ }
16
+ }
@@ -0,0 +1,73 @@
1
+ import {useDispatch} from 'react-redux';
2
+ import block from 'bem-cn-lite';
3
+
4
+ import type {EPathType} from '../../../types/api/schema';
5
+ import type {SavedQuery} from '../../../types/store/query';
6
+ import {changeUserInput} from '../../../store/reducers/executeQuery';
7
+ import {TENANT_QUERY_TABS_ID} from '../../../store/reducers/tenant/constants';
8
+ import {useSetting, useTypedSelector} from '../../../utils/hooks';
9
+ import {SAVED_QUERIES_KEY} from '../../../utils/constants';
10
+
11
+ import {QueryTabs} from './QueryTabs/QueryTabs';
12
+ import {SavedQueries} from './SavedQueries/SavedQueries';
13
+ import QueriesHistory from './QueriesHistory/QueriesHistory';
14
+ import QueryEditor from './QueryEditor/QueryEditor';
15
+
16
+ import './Query.scss';
17
+
18
+ const b = block('ydb-query');
19
+
20
+ interface QueryProps {
21
+ theme: string;
22
+ path?: string;
23
+ type?: EPathType;
24
+ }
25
+
26
+ export const Query = (props: QueryProps) => {
27
+ const dispatch = useDispatch();
28
+
29
+ const {queryTab = TENANT_QUERY_TABS_ID.newQuery} = useTypedSelector((state) => state.tenant);
30
+
31
+ const [savedQueries, setSavedQueries] = useSetting<SavedQuery[]>(SAVED_QUERIES_KEY, []);
32
+
33
+ const handleDeleteQuery = (queryName: string) => {
34
+ const newSavedQueries = savedQueries.filter(
35
+ (el) => el.name.toLowerCase() !== queryName.toLowerCase(),
36
+ );
37
+ setSavedQueries(newSavedQueries);
38
+ };
39
+
40
+ const handleUserInputChange = (value: {input: string}) => {
41
+ dispatch(changeUserInput(value));
42
+ };
43
+
44
+ const renderContent = () => {
45
+ switch (queryTab) {
46
+ case TENANT_QUERY_TABS_ID.newQuery: {
47
+ return <QueryEditor changeUserInput={handleUserInputChange} {...props} />;
48
+ }
49
+ case TENANT_QUERY_TABS_ID.history: {
50
+ return <QueriesHistory changeUserInput={handleUserInputChange} />;
51
+ }
52
+ case TENANT_QUERY_TABS_ID.saved: {
53
+ return (
54
+ <SavedQueries
55
+ changeUserInput={handleUserInputChange}
56
+ savedQueries={savedQueries}
57
+ onDeleteQuery={handleDeleteQuery}
58
+ />
59
+ );
60
+ }
61
+ default: {
62
+ return null;
63
+ }
64
+ }
65
+ };
66
+
67
+ return (
68
+ <div className={b()}>
69
+ <QueryTabs className={b('tabs')} activeTab={queryTab} />
70
+ <div className={b('content')}>{renderContent()}</div>
71
+ </div>
72
+ );
73
+ };
@@ -5,43 +5,43 @@ import cn from 'bem-cn-lite';
5
5
  import _ from 'lodash';
6
6
  import MonacoEditor from 'react-monaco-editor';
7
7
 
8
- import SplitPane from '../../../components/SplitPane';
9
- import {QueryResultTable} from '../../../components/QueryResultTable';
8
+ import SplitPane from '../../../../components/SplitPane';
9
+ import {QueryResultTable} from '../../../../components/QueryResultTable';
10
10
 
11
11
  import {
12
12
  sendExecuteQuery,
13
- changeUserInput,
14
13
  saveQueryToHistory,
15
14
  goToPreviousQuery,
16
15
  goToNextQuery,
17
16
  MONACO_HOT_KEY_ACTIONS,
18
17
  setMonacoHotKey,
19
- } from '../../../store/reducers/executeQuery';
20
- import {getExplainQuery, getExplainQueryAst} from '../../../store/reducers/explainQuery';
21
- import {getParsedSettingValue, setSettingValue} from '../../../store/reducers/settings/settings';
22
- import {setShowPreview} from '../../../store/reducers/schema/schema';
18
+ setTenantPath,
19
+ } from '../../../../store/reducers/executeQuery';
20
+ import {getExplainQuery, getExplainQueryAst} from '../../../../store/reducers/explainQuery';
21
+ import {getParsedSettingValue, setSettingValue} from '../../../../store/reducers/settings/settings';
22
+ import {setShowPreview} from '../../../../store/reducers/schema/schema';
23
23
  import {
24
24
  DEFAULT_IS_QUERY_RESULT_COLLAPSED,
25
25
  DEFAULT_SIZE_RESULT_PANE_KEY,
26
26
  SAVED_QUERIES_KEY,
27
27
  QUERY_INITIAL_MODE_KEY,
28
28
  ENABLE_ADDITIONAL_QUERY_MODES,
29
- } from '../../../utils/constants';
30
- import {useSetting} from '../../../utils/hooks';
31
- import {QueryModes} from '../../../types/store/query';
29
+ } from '../../../../utils/constants';
30
+ import {useSetting} from '../../../../utils/hooks';
31
+ import {QueryModes} from '../../../../types/store/query';
32
32
 
33
33
  import {
34
34
  PaneVisibilityActionTypes,
35
35
  paneVisibilityToggleReducerCreator,
36
- } from '../utils/paneVisibilityToggleHelpers';
37
- import Preview from '../Preview/Preview';
36
+ } from '../../utils/paneVisibilityToggleHelpers';
37
+ import Preview from '../../Preview/Preview';
38
38
 
39
- import SavedQueries from './SavedQueries/SavedQueries';
40
- import QueryResult from './QueryResult/QueryResult';
41
- import QueryExplain from './QueryExplain/QueryExplain';
42
- import {QueryEditorControls} from './QueryEditorControls/QueryEditorControls';
43
- import {OldQueryEditorControls} from './QueryEditorControls/OldQueryEditorControls';
44
- import QueriesHistory from './QueriesHistory/QueriesHistory';
39
+ import {ExecuteResult} from '../ExecuteResult/ExecuteResult';
40
+ import {ExplainResult} from '../ExplainResult/ExplainResult';
41
+ import {QueryEditorControls} from '../QueryEditorControls/QueryEditorControls';
42
+ import {OldQueryEditorControls} from '../QueryEditorControls/OldQueryEditorControls';
43
+
44
+ import {getPreparedResult} from '../utils/getPreparedResult';
45
45
 
46
46
  import './QueryEditor.scss';
47
47
 
@@ -67,6 +67,7 @@ const b = cn('query-editor');
67
67
 
68
68
  const propTypes = {
69
69
  sendExecuteQuery: PropTypes.func,
70
+ changeUserInput: PropTypes.func,
70
71
  path: PropTypes.string,
71
72
  response: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
72
73
  executeQuery: PropTypes.object,
@@ -75,6 +76,7 @@ const propTypes = {
75
76
  theme: PropTypes.string,
76
77
  type: PropTypes.string,
77
78
  initialQueryMode: PropTypes.string,
79
+ setTenantPath: PropTypes.func,
78
80
  };
79
81
 
80
82
  const initialTenantCommonInfoState = {
@@ -83,6 +85,9 @@ const initialTenantCommonInfoState = {
83
85
  collapsed: true,
84
86
  };
85
87
  function QueryEditor(props) {
88
+ const {path, executeQuery, theme, setTenantPath, changeUserInput} = props;
89
+ const {tenantPath: savedPath} = executeQuery;
90
+
86
91
  const [resultType, setResultType] = useState(RESULT_TYPES.EXECUTE);
87
92
 
88
93
  const [isResultLoaded, setIsResultLoaded] = useState(false);
@@ -96,6 +101,13 @@ function QueryEditor(props) {
96
101
  }
97
102
  }, [enableAdditionalQueryModes, queryMode, setQueryMode]);
98
103
 
104
+ useEffect(() => {
105
+ if (savedPath !== path) {
106
+ setTenantPath(path);
107
+ changeUserInput({input: ''});
108
+ }
109
+ }, [changeUserInput, setTenantPath, path, savedPath]);
110
+
99
111
  const [resultVisibilityState, dispatchResultVisibilityState] = useReducer(
100
112
  paneVisibilityToggleReducerCreator(DEFAULT_IS_QUERY_RESULT_COLLAPSED),
101
113
  initialTenantCommonInfoState,
@@ -324,11 +336,11 @@ function QueryEditor(props) {
324
336
  />
325
337
  );
326
338
  }
327
- const textResults = getPreparedResult();
339
+ const textResults = getPreparedResult(data);
328
340
  const disabled = !textResults.length || resultType !== RESULT_TYPES.EXECUTE;
329
341
 
330
342
  return data || error ? (
331
- <QueryResult
343
+ <ExecuteResult
332
344
  result={content}
333
345
  stats={stats}
334
346
  error={error}
@@ -348,7 +360,7 @@ function QueryEditor(props) {
348
360
  } = props;
349
361
 
350
362
  return (
351
- <QueryExplain
363
+ <ExplainResult
352
364
  error={error}
353
365
  explain={data}
354
366
  astQuery={handleAstQuery}
@@ -436,46 +448,6 @@ function QueryEditor(props) {
436
448
  return queries.length - 1 === currentIndex;
437
449
  };
438
450
 
439
- const renderHistoryNavigation = () => {
440
- const {changeUserInput} = props;
441
- return (
442
- <div className={b('history-controls')}>
443
- <QueriesHistory changeUserInput={changeUserInput} />
444
- </div>
445
- );
446
- };
447
-
448
- const getPreparedResult = () => {
449
- const {
450
- executeQuery: {data},
451
- } = props;
452
- const columnDivider = '\t';
453
- const rowDivider = '\n';
454
-
455
- if (!data?.result?.length) {
456
- return '';
457
- }
458
-
459
- const columnHeaders = Object.keys(data.result[0]);
460
- const rows = [columnHeaders].concat(data.result);
461
-
462
- return rows
463
- .map((item) => {
464
- const row = [];
465
-
466
- for (const field in item) {
467
- if (typeof item[field] === 'object' || Array.isArray(item[field])) {
468
- row.push(JSON.stringify(item[field]));
469
- } else {
470
- row.push(item[field]);
471
- }
472
- }
473
-
474
- return row.join(columnDivider);
475
- })
476
- .join(rowDivider);
477
- };
478
-
479
451
  const onChangeWindow = _.throttle(() => {
480
452
  updateEditor();
481
453
  }, 100);
@@ -513,14 +485,6 @@ function QueryEditor(props) {
513
485
  setSettingValue(SAVED_QUERIES_KEY, JSON.stringify(newSavedQueries));
514
486
  };
515
487
 
516
- const onDeleteQueryHandler = (queryName) => {
517
- const {savedQueries = [], setSettingValue} = props;
518
- const newSavedQueries = savedQueries.filter(
519
- (el) => el.name.toLowerCase() !== queryName.toLowerCase(),
520
- );
521
- setSettingValue(SAVED_QUERIES_KEY, JSON.stringify(newSavedQueries));
522
- };
523
-
524
488
  const renderControls = () => {
525
489
  const {executeQuery, explainQuery, savedQueries} = props;
526
490
 
@@ -555,22 +519,6 @@ function QueryEditor(props) {
555
519
  );
556
520
  };
557
521
 
558
- const renderUpperControls = () => {
559
- const {savedQueries, changeUserInput} = props;
560
-
561
- return (
562
- <div className={b('upper-controls')}>
563
- {renderHistoryNavigation()}
564
- <SavedQueries
565
- savedQueries={savedQueries}
566
- changeUserInput={changeUserInput}
567
- onDeleteQuery={onDeleteQueryHandler}
568
- />
569
- </div>
570
- );
571
- };
572
-
573
- const {executeQuery, theme} = props;
574
522
  const result = renderResult();
575
523
 
576
524
  return (
@@ -584,7 +532,11 @@ function QueryEditor(props) {
584
532
  collapsedSizes={[100, 0]}
585
533
  onSplitStartDragAdditional={onSplitStartDragAdditional}
586
534
  >
587
- <div className={b('pane-wrapper')}>
535
+ <div
536
+ className={b('pane-wrapper', {
537
+ top: true,
538
+ })}
539
+ >
588
540
  <div className={b('monaco-wrapper')}>
589
541
  <div className={b('monaco')}>
590
542
  <MonacoEditor
@@ -598,7 +550,6 @@ function QueryEditor(props) {
598
550
  </div>
599
551
  </div>
600
552
  {renderControls()}
601
- {renderUpperControls()}
602
553
  </div>
603
554
  <div className={b('pane-wrapper')}>
604
555
  {props.showPreview ? renderPreview() : result}
@@ -621,7 +572,6 @@ const mapStateToProps = (state) => {
621
572
 
622
573
  const mapDispatchToProps = {
623
574
  sendExecuteQuery,
624
- changeUserInput,
625
575
  saveQueryToHistory,
626
576
  goToPreviousQuery,
627
577
  goToNextQuery,
@@ -630,6 +580,7 @@ const mapDispatchToProps = {
630
580
  setSettingValue,
631
581
  setShowPreview,
632
582
  setMonacoHotKey,
583
+ setTenantPath,
633
584
  };
634
585
 
635
586
  QueryEditor.propTypes = propTypes;
@@ -1,4 +1,4 @@
1
- @import '../../../styles/mixins.scss';
1
+ @import '../../../../styles/mixins.scss';
2
2
 
3
3
  .query-editor {
4
4
  position: relative;
@@ -24,7 +24,8 @@
24
24
 
25
25
  width: 100%;
26
26
  height: 100%;
27
- padding-top: 9px;
27
+
28
+ border: 1px solid var(--yc-color-line-generic);
28
29
  }
29
30
 
30
31
  &__monaco-wrapper {
@@ -40,28 +41,11 @@
40
41
  flex-direction: column;
41
42
 
42
43
  background-color: var(--yc-color-base-background);
43
- }
44
-
45
- &__upper-controls {
46
- position: absolute;
47
- top: -38px;
48
- right: 20px;
49
-
50
- display: flex;
51
- gap: 12px;
52
-
53
- justify-content: flex-end;
54
- align-items: center;
55
- }
56
-
57
- &__history-controls {
58
- display: flex;
59
- align-items: center;
60
- }
61
44
 
62
- &__history-label {
63
- margin-right: 8px;
45
+ &_top {
46
+ padding: 0 16px;
64
47
 
65
- color: var(--yc-color-text-secondary);
48
+ border-bottom: 1px solid var(--yc-color-line-generic);
49
+ }
66
50
  }
67
51
  }