ydb-embedded-ui 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
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