ydb-embedded-ui 1.5.1 → 1.6.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.
Files changed (74) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/assets/icons/circle-exclamation.svg +1 -0
  3. package/dist/assets/icons/circle-info.svg +1 -0
  4. package/dist/assets/icons/circle-xmark.svg +1 -0
  5. package/dist/assets/icons/triangle-exclamation.svg +1 -0
  6. package/dist/components/AsideNavigation/Settings/Settings.scss +4 -4
  7. package/dist/components/Breadcrumbs/Breadcrumbs.scss +1 -1
  8. package/dist/components/Collapse/Collapse.scss +8 -8
  9. package/dist/components/EmptyState/EmptyState.scss +6 -6
  10. package/dist/components/EntityStatus/EntityStatus.scss +6 -6
  11. package/dist/components/FullNodeViewer/FullNodeViewer.scss +7 -7
  12. package/dist/components/GroupViewer/GroupViewer.scss +1 -1
  13. package/dist/components/InfoViewer/InfoViewer.scss +4 -4
  14. package/dist/components/PDiskViewer/PDiskViewer.scss +1 -1
  15. package/dist/components/PoolUsage/PoolUsage.scss +5 -5
  16. package/dist/components/ProgressViewer/ProgressViewer.scss +9 -9
  17. package/dist/components/ShortyString/ShortyString.scss +7 -0
  18. package/dist/components/ShortyString/ShortyString.tsx +53 -0
  19. package/dist/components/TableSkeleton/TableSkeleton.scss +1 -1
  20. package/dist/components/TabletsViewer/TabletsViewer.scss +2 -2
  21. package/dist/containers/App/App.js +2 -1
  22. package/dist/containers/App/App.scss +6 -0
  23. package/dist/containers/App/TipPopup/TipPopup.js +1 -1
  24. package/dist/containers/AsideNavigation/AsideNavigation.scss +1 -1
  25. package/dist/containers/Authentication/Authentication.scss +2 -2
  26. package/dist/containers/Header/Header.scss +2 -2
  27. package/dist/containers/Header/Host/Host.scss +6 -6
  28. package/dist/containers/Heatmap/Heatmap.js +1 -2
  29. package/dist/containers/Heatmap/Heatmap.scss +2 -2
  30. package/dist/containers/Node/Node.scss +0 -1
  31. package/dist/containers/Node/Node.tsx +1 -0
  32. package/dist/containers/Node/NodeStructure/NodeStructure.scss +3 -3
  33. package/dist/containers/Node/NodeStructure/Pdisk.tsx +6 -6
  34. package/dist/containers/Pdisk/Pdisk.scss +2 -2
  35. package/dist/containers/Pool/Pool.scss +3 -3
  36. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.scss +2 -2
  37. package/dist/containers/Storage/Storage.scss +3 -3
  38. package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +4 -4
  39. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +4 -4
  40. package/dist/containers/Tablet/Tablet.scss +4 -4
  41. package/dist/containers/Tablets/Tablets.js +1 -2
  42. package/dist/containers/TabletsFilters/TabletsFilters.js +1 -2
  43. package/dist/containers/TabletsFilters/TabletsFilters.scss +2 -2
  44. package/dist/containers/Tenant/Acl/Acl.scss +2 -2
  45. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +15 -21
  46. package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +3 -2
  47. package/dist/containers/Tenant/Diagnostics/Network/Network.scss +6 -6
  48. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.scss +4 -4
  49. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +5 -4
  50. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +2 -2
  51. package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +8 -7
  52. package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.scss +7 -8
  53. package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +2 -12
  54. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +5 -8
  55. package/dist/containers/Tenant/Preview/Preview.js +2 -2
  56. package/dist/containers/Tenant/QueryEditor/Issues/Issues.scss +124 -0
  57. package/dist/containers/Tenant/QueryEditor/Issues/Issues.tsx +171 -0
  58. package/dist/containers/Tenant/QueryEditor/Issues/models.ts +27 -0
  59. package/dist/containers/Tenant/QueryEditor/QueryEditor.js +38 -52
  60. package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +4 -1
  61. package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.js +32 -5
  62. package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.scss +1 -1
  63. package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +1 -3
  64. package/dist/containers/Tenant/Tenant.scss +2 -2
  65. package/dist/containers/Tenant/utils/schemaActions.ts +3 -18
  66. package/dist/containers/Vdisk/Vdisk.scss +2 -2
  67. package/dist/containers/VdiskPdiskNode/VdiskPdiskNode.scss +2 -2
  68. package/dist/store/reducers/tenant.js +30 -0
  69. package/dist/store/state-url-mapping.js +6 -0
  70. package/dist/store/utils.js +1 -1
  71. package/dist/styles/mixins.scss +13 -13
  72. package/dist/utils/getNodesColumns.js +2 -3
  73. package/dist/utils/index.js +4 -0
  74. package/package.json +6 -7
@@ -0,0 +1,124 @@
1
+ .kv-result-issues {
2
+ overflow: auto;
3
+
4
+ height: 100%;
5
+ padding: 0 10px;
6
+ &__error-message {
7
+ position: sticky;
8
+ z-index: 2;
9
+ top: 0;
10
+ left: 0;
11
+
12
+ display: flex;
13
+ align-items: center;
14
+
15
+ padding: 10px 0;
16
+
17
+ background-color: var(--yc-color-base-background);
18
+ }
19
+ &__error-message-text {
20
+ margin: 0 10px;
21
+ }
22
+ }
23
+
24
+ .kv-issues {
25
+ position: relative;
26
+ }
27
+
28
+ .kv-issue {
29
+ &_leaf {
30
+ margin-left: 31px;
31
+ }
32
+
33
+ &__issues {
34
+ padding-left: 24px;
35
+ }
36
+
37
+ &__line {
38
+ display: flex;
39
+ align-items: flex-start;
40
+
41
+ margin: 0 0 10px;
42
+ padding: 0 10px 0 0;
43
+ }
44
+
45
+ &__place-text {
46
+ display: inline-block;
47
+
48
+ padding-right: 10px;
49
+
50
+ text-align: left;
51
+
52
+ color: var(--yc-color-text-secondary);
53
+ }
54
+
55
+ &__message {
56
+ display: flex;
57
+
58
+ margin-right: auto;
59
+ margin-left: 10px;
60
+
61
+ font-family: var(--yc-font-family-monospace);
62
+ font-size: var(--yc-text-code-2-font-size);
63
+ line-height: var(--yc-text-header-2-line-height);
64
+ }
65
+
66
+ &__message-text {
67
+ flex: 1 1 auto;
68
+
69
+ min-width: 240px;
70
+
71
+ white-space: pre-wrap;
72
+ word-break: break-word;
73
+ }
74
+
75
+ &__code {
76
+ flex: 0 0 auto;
77
+
78
+ margin-left: 1.5em;
79
+ padding: 3px 0;
80
+
81
+ font-size: 12px;
82
+
83
+ color: var(--yc-color-text-complementary);
84
+ }
85
+
86
+ &__arrow-toggle {
87
+ margin-right: 5px;
88
+ .yc-button__text {
89
+ margin: 0 5px;
90
+ }
91
+ }
92
+ }
93
+
94
+ .yql-issue-severity {
95
+ display: flex;
96
+ align-items: center;
97
+
98
+ line-height: 28px;
99
+ white-space: nowrap;
100
+
101
+ &_severity_fatal &__icon {
102
+ color: var(--yc-color-text-danger);
103
+ }
104
+
105
+ &_severity_error &__icon {
106
+ color: var(--yc-color-text-danger);
107
+ }
108
+
109
+ &_severity_warning &__icon {
110
+ color: var(--yc-color-text-warning-medium);
111
+ }
112
+
113
+ &_severity_info &__icon {
114
+ color: var(--yc-color-text-info);
115
+ }
116
+
117
+ &__title {
118
+ margin-left: 4px;
119
+
120
+ text-transform: capitalize;
121
+
122
+ color: var(--yc-color-text-complementary);
123
+ }
124
+ }
@@ -0,0 +1,171 @@
1
+ import * as React from 'react';
2
+ import cn from 'bem-cn-lite';
3
+
4
+ import {Button, Icon, ArrowToggle} from '@yandex-cloud/uikit';
5
+ import ShortyString from '../../../../components/ShortyString/ShortyString';
6
+
7
+ import {IssueType, SEVERITY, getSeverity} from './models';
8
+
9
+ import fatalIcon from '../../../../assets/icons/circle-xmark.svg';
10
+ import errorIcon from '../../../../assets/icons/triangle-exclamation.svg';
11
+ import warningIcon from '../../../../assets/icons/circle-exclamation.svg';
12
+ import infoIcon from '../../../../assets/icons/circle-info.svg';
13
+
14
+ import './Issues.scss';
15
+
16
+ const blockWrapper = cn('kv-result-issues');
17
+ const blockIssues = cn('kv-issues');
18
+ const blockIssue = cn('kv-issue');
19
+
20
+ type DataIssues = {
21
+ error: IssueType;
22
+ issues?: IssueType[];
23
+ };
24
+
25
+ interface ResultIssuesProps {
26
+ data: DataIssues | string;
27
+ className: string;
28
+ }
29
+
30
+ export default function ResultIssues({data, className}: ResultIssuesProps) {
31
+ const [showIssues, setShowIssues] = React.useState(false);
32
+
33
+ const hasIssues = typeof data === 'string' ? false : Array.isArray(data?.issues);
34
+
35
+ const renderTitle = () => {
36
+ let content;
37
+ if (typeof data === 'string') {
38
+ content = data;
39
+ } else {
40
+ const severity = getSeverity(data?.error?.severity);
41
+ content = (
42
+ <React.Fragment>
43
+ <IssueSeverity severity={severity} />{' '}
44
+ <span className={blockWrapper('error-message-text')}>
45
+ {data?.error?.message}
46
+ </span>
47
+ </React.Fragment>
48
+ );
49
+ }
50
+
51
+ return content;
52
+ };
53
+
54
+ return (
55
+ <div className={blockWrapper()}>
56
+ <div className={blockWrapper('error-message')}>
57
+ {renderTitle()}
58
+ {hasIssues && (
59
+ <Button view="normal" onClick={() => setShowIssues(!showIssues)}>
60
+ {showIssues ? 'Hide details' : 'Show details'}
61
+ </Button>
62
+ )}
63
+ </div>
64
+ {hasIssues && showIssues && (
65
+ <Issues issues={(data as DataIssues).issues!} className={className} />
66
+ )}
67
+ </div>
68
+ );
69
+ }
70
+
71
+ interface IssuesProps {
72
+ className?: string;
73
+ issues: IssueType[];
74
+ }
75
+ export function Issues({issues, className}: IssuesProps) {
76
+ const mostSevereIssue = issues.reduce((result, issue) => {
77
+ const severity = issue.severity ?? 10;
78
+ return Math.min(result, severity);
79
+ }, 10);
80
+ return (
81
+ <div className={blockIssues(null, className)}>
82
+ {issues.map((issue, index) => (
83
+ <Issue key={index} issue={issue} expanded={issue === mostSevereIssue} />
84
+ ))}
85
+ </div>
86
+ );
87
+ }
88
+
89
+ function Issue({issue, level = 0}: {issue: IssueType; expanded?: boolean; level?: number}) {
90
+ const [isExpand, setIsExpand] = React.useState(true);
91
+ const severity = getSeverity(issue.severity);
92
+ const hasIssues = Array.isArray(issue.issues) && issue.issues.length > 0;
93
+ const position = getIssuePosition(issue);
94
+
95
+ const arrowDirection = isExpand ? 'bottom' : 'right';
96
+
97
+ return (
98
+ <div
99
+ className={blockIssue({
100
+ leaf: !hasIssues,
101
+ 'has-issues': hasIssues,
102
+ })}
103
+ >
104
+ <div className={blockIssue('line')}>
105
+ {hasIssues && (
106
+ <Button
107
+ view="flat-secondary"
108
+ onClick={() => setIsExpand(!isExpand)}
109
+ className={blockIssue('arrow-toggle')}
110
+ >
111
+ <ArrowToggle direction={arrowDirection} size={16} />
112
+ </Button>
113
+ )}
114
+ <IssueSeverity severity={severity} />
115
+
116
+ <span className={blockIssue('message')}>
117
+ {position && (
118
+ <span className={blockIssue('place-text')} title="Position">
119
+ {position}
120
+ </span>
121
+ )}
122
+ <div className={blockIssue('message-text')}>
123
+ <ShortyString value={issue.message} expandLabel={'Show full message'} />
124
+ </div>
125
+ </span>
126
+ {issue.code ? <span className={blockIssue('code')}>Code: {issue.code}</span> : null}
127
+ </div>
128
+ {hasIssues && isExpand && (
129
+ <div className={blockIssue('issues')}>
130
+ <IssueList issues={issue.issues!} level={level + 1} expanded={isExpand} />
131
+ </div>
132
+ )}
133
+ </div>
134
+ );
135
+ }
136
+
137
+ function IssueList(props: {issues: IssueType[]; expanded: boolean; level: number}) {
138
+ const {issues, level, expanded} = props;
139
+ return (
140
+ <div className={blockIssue('list')}>
141
+ {issues.map((issue, index) => (
142
+ <Issue key={index} issue={issue} level={level} expanded={expanded} />
143
+ ))}
144
+ </div>
145
+ );
146
+ }
147
+
148
+ const severityIcons: Record<SEVERITY, any> = {
149
+ S_INFO: infoIcon,
150
+ S_WARNING: warningIcon,
151
+ S_ERROR: errorIcon,
152
+ S_FATAL: fatalIcon,
153
+ };
154
+ const blockIssueSeverity = cn('yql-issue-severity');
155
+ function IssueSeverity({severity}: {severity: SEVERITY}) {
156
+ const shortenSeverity = severity.slice(2).toLowerCase();
157
+ return (
158
+ <span className={blockIssueSeverity({severity: shortenSeverity})}>
159
+ <Icon className={blockIssueSeverity('icon')} data={severityIcons[severity]} size={16} />
160
+ <span className={blockIssueSeverity('title')}>{shortenSeverity}</span>
161
+ </span>
162
+ );
163
+ }
164
+
165
+ function getIssuePosition(issue: IssueType) {
166
+ const {file, position} = issue;
167
+ if (!position) {
168
+ return false;
169
+ }
170
+ return `${file ? 'file:' : ''}${position.row}:${position.column}`;
171
+ }
@@ -0,0 +1,27 @@
1
+ export interface IssueType {
2
+ file?: string;
3
+ position?: {row: number; column: number};
4
+ // eslint-disable-next-line camelcase
5
+ end_position?: {row: number; column: number};
6
+ message?: string;
7
+ code?: number;
8
+ severity?: number;
9
+ issues?: IssueType[];
10
+ }
11
+
12
+ export const SEVERITY_LIST = ['S_FATAL', 'S_ERROR', 'S_WARNING', 'S_INFO'] as const;
13
+
14
+ export type SEVERITY = typeof SEVERITY_LIST[number];
15
+
16
+ // Severity values from ydb/library/yql/public/issue/protos/issue_severity.proto
17
+ // FATAL = 0;
18
+ // ERROR = 1;
19
+ // WARNING = 2;
20
+ // INFO = 3;
21
+ export function isSeverity(value: number | undefined) {
22
+ return value ? SEVERITY_LIST[value] !== undefined : false;
23
+ }
24
+
25
+ export function getSeverity(value: number | undefined) {
26
+ return isSeverity(value) ? SEVERITY_LIST[value!] : 'S_INFO';
27
+ }
@@ -307,58 +307,56 @@ function QueryEditor(props) {
307
307
  executeQuery: {data, error, stats},
308
308
  showTooltip,
309
309
  } = props;
310
- const result = getExecuteResult();
311
- const shouldRenderAnswer = result.length || error;
312
310
 
313
- if (!shouldRenderAnswer) {
314
- return null;
315
- }
316
-
317
- let columns = [];
318
- if (data && data.length > 0) {
319
- columns = Object.keys(data[0]).map((key) => ({
320
- name: key,
321
- render: ({value}) => {
322
- return (
323
- <span
324
- className={b('cell')}
325
- onClick={(e) => showTooltip(e.target, value, 'cell')}
326
- >
327
- {value}
328
- </span>
329
- );
330
- },
331
- }));
311
+ let content;
312
+ if (data) {
313
+ let columns = [];
314
+ if (data.length > 0) {
315
+ columns = Object.keys(data[0]).map((key) => ({
316
+ name: key,
317
+ render: ({value}) => {
318
+ return (
319
+ <span
320
+ className={b('cell')}
321
+ onClick={(e) => showTooltip(e.target, value, 'cell')}
322
+ >
323
+ {value}
324
+ </span>
325
+ );
326
+ },
327
+ }));
328
+ const preparedData = prepareQueryResponse(data);
329
+
330
+ content = columns.length ? (
331
+ <DataTable
332
+ columns={columns}
333
+ data={preparedData}
334
+ settings={TABLE_SETTINGS}
335
+ theme="yandex-cloud"
336
+ rowKey={(_, index) => index}
337
+ />
338
+ ) : (
339
+ <div>{data}</div>
340
+ );
341
+ }
332
342
  }
343
+ const textResults = getPreparedResult();
344
+ const disabled = !textResults.length || resultType !== RESULT_TYPES.EXECUTE;
333
345
 
334
- const preparedData = prepareQueryResponse(data);
335
-
336
- const content = columns.length ? (
337
- <DataTable
338
- columns={columns}
339
- data={preparedData}
340
- settings={TABLE_SETTINGS}
341
- theme="yandex-cloud"
342
- rowKey={(_, index) => index}
343
- />
344
- ) : (
345
- <div>{result}</div>
346
- );
347
- const results = getPreparedResult();
348
- const disabled = !results.length || resultType !== RESULT_TYPES.EXECUTE;
349
- return (
346
+ return data || error ? (
350
347
  <QueryResult
351
348
  result={content}
352
349
  stats={stats}
353
- error={Boolean(error)}
354
- textResults={results}
350
+ error={error}
351
+ textResults={textResults}
355
352
  copyDisabled={disabled}
356
353
  isResultsCollapsed={resultVisibilityState.collapsed}
357
354
  onExpandResults={onExpandResultHandler}
358
355
  onCollapseResults={onCollapseResultHandler}
359
356
  />
360
- );
357
+ ) : null;
361
358
  };
359
+
362
360
  const renderExplainQuery = () => {
363
361
  const {
364
362
  explainQuery: {data, dataAst, error, loading, loadingAst},
@@ -463,18 +461,6 @@ function QueryEditor(props) {
463
461
  );
464
462
  };
465
463
 
466
- const getExecuteResult = () => {
467
- const {data = [], error} = props.executeQuery;
468
-
469
- if (error) {
470
- return error.data || error;
471
- } else if (data.length > 0) {
472
- return data;
473
- } else {
474
- return '';
475
- }
476
- };
477
-
478
464
  const getPreparedResult = () => {
479
465
  const {
480
466
  executeQuery: {data},
@@ -234,7 +234,10 @@ function QueryExplain(props) {
234
234
  }
235
235
 
236
236
  if (error) {
237
- return error.data ? error.data : error;
237
+ if (error.data) {
238
+ return typeof error.data === 'string' ? error.data : error.data.error?.message;
239
+ }
240
+ return error;
238
241
  }
239
242
 
240
243
  switch (activeOption) {
@@ -13,6 +13,7 @@ import './QueryResult.scss';
13
13
  import {PaneVisibilityToggleButtons} from '../../utils/paneVisibilityToggleHelpers';
14
14
  import QueryExecutionStatus from '../../../../components/QueryExecutionStatus/QueryExecutionStatus';
15
15
  import EnableFullscreenButton from '../../../../components/EnableFullscreenButton/EnableFullscreenButton';
16
+ import ResultIssues from '../Issues/Issues';
16
17
 
17
18
  const b = cn('kv-query-result');
18
19
 
@@ -27,7 +28,9 @@ const resultOptions = [
27
28
  ];
28
29
 
29
30
  function QueryResult(props) {
30
- const [activeSection, setActiveSection] = useState(resultOptionsIds.result);
31
+ const [activeSection, setActiveSection] = useState(
32
+ props.result ? resultOptionsIds.result : resultOptionsIds.stats,
33
+ );
31
34
  const isFullscreen = useSelector((state) => state.fullscreen);
32
35
  const dispatch = useDispatch();
33
36
 
@@ -83,11 +86,34 @@ function QueryResult(props) {
83
86
  return (
84
87
  <React.Fragment>
85
88
  {result}
86
- {isFullscreen && <Fullscreen><div className={b('result', {fullscreen: true})}>{result}</div></Fullscreen>}
89
+ {isFullscreen && (
90
+ <Fullscreen>
91
+ <div className={b('result', {fullscreen: true})}>{result}</div>
92
+ </Fullscreen>
93
+ )}
87
94
  </React.Fragment>
88
95
  );
89
96
  };
90
97
 
98
+ const renderIssues = () => {
99
+ const error = props.error?.data;
100
+
101
+ const hasIssues = error?.issues && Array.isArray(error.issues);
102
+
103
+ return hasIssues ? (
104
+ <React.Fragment>
105
+ <ResultIssues data={error} />
106
+ {isFullscreen && (
107
+ <Fullscreen>
108
+ <div className={b('result', {fullscreen: true})}>
109
+ <ResultIssues data={error} />
110
+ </div>
111
+ </Fullscreen>
112
+ )}
113
+ </React.Fragment>
114
+ ) : null;
115
+ };
116
+
91
117
  return (
92
118
  <React.Fragment>
93
119
  <div className={b('controls')}>
@@ -107,7 +133,7 @@ function QueryResult(props) {
107
133
  </div>
108
134
  <div className={b('controls-left')}>
109
135
  {renderClipboardButton()}
110
- <EnableFullscreenButton disabled={Boolean(props.error)}/>
136
+ <EnableFullscreenButton />
111
137
  <PaneVisibilityToggleButtons
112
138
  onCollapse={props.onCollapseResults}
113
139
  onExpand={props.onExpandResults}
@@ -117,8 +143,9 @@ function QueryResult(props) {
117
143
  </div>
118
144
  </div>
119
145
  <div className={b('result')}>
120
- {activeSection === resultOptionsIds.result && renderResult()}
121
- {activeSection === resultOptionsIds.stats && renderStats()}
146
+ {activeSection === resultOptionsIds.result && !props.error && renderResult()}
147
+ {activeSection === resultOptionsIds.stats && !props.error && renderStats()}
148
+ {renderIssues()}
122
149
  </div>
123
150
  </React.Fragment>
124
151
  );
@@ -4,7 +4,7 @@
4
4
  align-items: flex-start;
5
5
 
6
6
  & + & {
7
- margin-top: var(--yc-text-body-line-height);
7
+ margin-top: var(--yc-text-body-1-line-height);
8
8
  }
9
9
  }
10
10
  &__field-title {
@@ -1,5 +1,4 @@
1
1
  import {useDispatch} from 'react-redux';
2
- import {useHistory} from 'react-router';
3
2
 
4
3
  import {NavigationTree} from 'ydb-ui-components';
5
4
 
@@ -26,7 +25,6 @@ export function SchemaTree(props: SchemaTreeProps) {
26
25
  } = props;
27
26
 
28
27
  const dispatch = useDispatch();
29
- const history = useHistory();
30
28
 
31
29
  const fetchPath = (path: string) => window.api.getSchema(
32
30
  {path},
@@ -55,7 +53,7 @@ export function SchemaTree(props: SchemaTreeProps) {
55
53
  collapsed: false,
56
54
  }}
57
55
  fetchPath={fetchPath}
58
- getActions={getActions(dispatch, history, handleActivePathUpdate)}
56
+ getActions={getActions(dispatch, handleActivePathUpdate)}
59
57
  activePath={currentPath}
60
58
  onActivePathUpdate={handleActivePathUpdate}
61
59
  cache={false}
@@ -3,8 +3,8 @@
3
3
  .tenant-page {
4
4
  overflow: hidden;
5
5
 
6
- font-size: var(--yc-text-body2-font-size);
7
- line-height: var(--yc-text-body2-line-height);
6
+ font-size: var(--yc-text-body-2-font-size);
7
+ line-height: var(--yc-text-body-2-line-height);
8
8
  @include flex-container();
9
9
 
10
10
  .yc-tabs {
@@ -1,13 +1,11 @@
1
- import qs from 'qs';
2
1
  import {Dispatch} from 'react';
3
- import {History} from 'history';
4
2
  import type {NavigationTreeNodeType} from 'ydb-ui-components';
5
3
 
6
- import routes, {createHref} from '../../../routes';
7
4
  import {changeUserInput} from '../../../store/reducers/executeQuery';
8
5
  import {setShowPreview} from '../../../store/reducers/schema';
6
+ import {setTopLevelTab} from '../../../store/reducers/tenant';
9
7
  import createToast from '../../../utils/createToast';
10
- import {TenantGeneralTabsIds, TenantTabsGroups} from '../TenantPages';
8
+ import {TenantGeneralTabsIds} from '../TenantPages';
11
9
 
12
10
  const createTableTemplate = (path: string) => {
13
11
  return `CREATE TABLE \`${path}/my_table\`
@@ -36,29 +34,16 @@ VALUES ( );`;
36
34
 
37
35
  export const getActions = (
38
36
  dispatch: Dispatch<any>,
39
- history: History<unknown>,
40
37
  setActivePath: (path: string) => void,
41
38
  ) =>
42
39
  (path: string, type: NavigationTreeNodeType) => {
43
- const queryParams = qs.parse(location.search, {
44
- ignoreQueryPrefix: true,
45
- });
46
-
47
40
  const switchTabToQuery = () => {
48
- history.push(
49
- createHref(routes.tenant, undefined, {
50
- ...queryParams,
51
- [TenantTabsGroups.general]: TenantGeneralTabsIds.query,
52
- }),
53
- );
41
+ dispatch(setTopLevelTab(TenantGeneralTabsIds.query));
54
42
  };
55
43
 
56
44
  const onCreateTableClick = () => {
57
45
  dispatch(changeUserInput({input: createTableTemplate(path)}));
58
46
  switchTabToQuery();
59
- // here and in the other handlers this should be called after switching tab:
60
- // redux-location-state catches the history.push event from the tab switching
61
- // before active path updates in url, preventing its update at all
62
47
  setActivePath(path);
63
48
  };
64
49
 
@@ -20,9 +20,9 @@
20
20
  &__title {
21
21
  margin-right: 16px;
22
22
 
23
- font-size: var(--yc-text-body2-font-size);
23
+ font-size: var(--yc-text-body-2-font-size);
24
24
  font-weight: 500;
25
- line-height: var(--yc-text-body2-line-height);
25
+ line-height: var(--yc-text-body-2-line-height);
26
26
  text-transform: uppercase;
27
27
  }
28
28
 
@@ -27,9 +27,9 @@
27
27
  &__title {
28
28
  margin-right: 16px;
29
29
 
30
- font-size: var(--yc-text-body2-font-size);
30
+ font-size: var(--yc-text-body-2-font-size);
31
31
  font-weight: 500;
32
- line-height: var(--yc-text-body2-line-height);
32
+ line-height: var(--yc-text-body-2-line-height);
33
33
  text-transform: uppercase;
34
34
  }
35
35