ydb-embedded-ui 4.10.0 → 4.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/components/InfoViewer/formatters/schema.ts +3 -1
  3. package/dist/components/QueryResultTable/Cell/Cell.tsx +8 -8
  4. package/dist/components/QueryResultTable/i18n/en.json +1 -1
  5. package/dist/components/QueryResultTable/i18n/ru.json +1 -1
  6. package/dist/components/ShortyString/ShortyString.tsx +3 -6
  7. package/dist/components/ShortyString/i18n/en.json +8 -8
  8. package/dist/components/ShortyString/i18n/ru.json +8 -8
  9. package/dist/components/SpeedMultiMeter/i18n/index.ts +0 -2
  10. package/dist/components/Stack/Stack.tsx +16 -16
  11. package/dist/components/TableSkeleton/TableSkeleton.tsx +3 -3
  12. package/dist/components/TableWithControlsLayout/TableWithControlsLayout.scss +32 -0
  13. package/dist/components/TableWithControlsLayout/TableWithControlsLayout.tsx +43 -0
  14. package/dist/containers/AsideNavigation/AsideNavigation.tsx +2 -2
  15. package/dist/containers/Cluster/Cluster.scss +4 -5
  16. package/dist/containers/Cluster/Cluster.tsx +3 -22
  17. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.scss +4 -0
  18. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.tsx +14 -3
  19. package/dist/containers/Cluster/ClusterInfoSkeleton/ClusterInfoSkeleton.tsx +1 -1
  20. package/dist/containers/Cluster/utils.tsx +0 -11
  21. package/dist/containers/Header/Header.scss +1 -5
  22. package/dist/containers/Header/Header.tsx +2 -2
  23. package/dist/containers/Header/breadcrumbs.ts +2 -1
  24. package/dist/containers/Heatmap/Heatmap.tsx +4 -3
  25. package/dist/containers/Node/NodeStructure/PDiskTitleBadge.tsx +2 -8
  26. package/dist/containers/Nodes/Nodes.scss +1 -24
  27. package/dist/containers/Nodes/Nodes.tsx +29 -39
  28. package/dist/containers/Storage/EmptyFilter/i18n/en.json +2 -2
  29. package/dist/containers/Storage/EmptyFilter/i18n/ru.json +2 -2
  30. package/dist/containers/Storage/Storage.scss +1 -14
  31. package/dist/containers/Storage/Storage.tsx +15 -18
  32. package/dist/containers/Storage/StorageGroups/i18n/en.json +5 -5
  33. package/dist/containers/Storage/StorageGroups/i18n/ru.json +5 -5
  34. package/dist/containers/Storage/StorageTypeFilter/StorageTypeFilter.tsx +3 -1
  35. package/dist/containers/Storage/{StorageVisibleEntityFilter/StorageVisibleEntityFilter.tsx → StorageVisibleEntitiesFilter/StorageVisibleEntitiesFilter.tsx} +4 -2
  36. package/dist/containers/Storage/UsageFilter/i18n/en.json +3 -8
  37. package/dist/containers/Storage/UsageFilter/i18n/ru.json +3 -8
  38. package/dist/containers/Tablet/Tablet.tsx +2 -2
  39. package/dist/containers/Tenant/Acl/Acl.scss +1 -9
  40. package/dist/containers/Tenant/Acl/Acl.tsx +137 -0
  41. package/dist/containers/Tenant/Diagnostics/Describe/Describe.tsx +2 -2
  42. package/dist/containers/Tenant/Diagnostics/Diagnostics.scss +6 -2
  43. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +6 -0
  44. package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +3 -3
  45. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +2 -0
  46. package/dist/containers/Tenant/Diagnostics/Overview/utils/prepareTopicSchemaInfo.ts +2 -3
  47. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.scss +3 -18
  48. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +95 -88
  49. package/dist/containers/Tenant/Query/Issues/Issues.tsx +27 -23
  50. package/dist/containers/Tenant/Query/Issues/models.ts +0 -11
  51. package/dist/containers/Tenant/Query/Preview/Preview.tsx +3 -3
  52. package/dist/containers/Tenant/Query/i18n/en.json +1 -1
  53. package/dist/containers/Tenant/Query/i18n/ru.json +1 -1
  54. package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +2 -2
  55. package/dist/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx +99 -0
  56. package/dist/containers/Tenant/Tenant.tsx +1 -5
  57. package/dist/containers/Tenant/TenantPages.tsx +9 -14
  58. package/dist/containers/Tenant/i18n/en.json +11 -0
  59. package/dist/containers/Tenant/i18n/index.ts +11 -0
  60. package/dist/containers/Tenant/i18n/ru.json +11 -0
  61. package/dist/containers/Tenant/utils/schema.ts +24 -0
  62. package/dist/containers/Tenant/utils/schemaActions.ts +28 -24
  63. package/dist/containers/Tenants/Tenants.scss +1 -13
  64. package/dist/containers/Tenants/Tenants.tsx +18 -28
  65. package/dist/services/api.ts +6 -7
  66. package/dist/store/index.js +1 -1
  67. package/dist/store/reducers/nodes/nodes.ts +12 -111
  68. package/dist/store/reducers/nodes/selectors.ts +74 -0
  69. package/dist/store/reducers/nodes/types.ts +22 -3
  70. package/dist/store/reducers/nodes/utils.ts +59 -0
  71. package/dist/store/reducers/preview.ts +6 -4
  72. package/dist/store/reducers/schemaAcl/schemaAcl.ts +17 -0
  73. package/dist/store/reducers/schemaAcl/types.ts +9 -7
  74. package/dist/store/reducers/storage/selectors.ts +1 -1
  75. package/dist/store/reducers/tenant/constants.ts +6 -0
  76. package/dist/store/reducers/tenant/tenant.ts +15 -0
  77. package/dist/store/reducers/tenant/types.ts +18 -3
  78. package/dist/store/state-url-mapping.js +3 -0
  79. package/dist/types/api/cluster.ts +1 -1
  80. package/dist/types/api/compute.ts +27 -2
  81. package/dist/types/api/error.ts +2 -2
  82. package/dist/types/api/netInfo.ts +3 -3
  83. package/dist/types/api/nodes.ts +13 -1
  84. package/dist/types/api/query.ts +1 -1
  85. package/dist/types/api/schema/cdcStream.ts +32 -0
  86. package/dist/types/api/schema/columnEntity.ts +138 -0
  87. package/dist/types/api/schema/externalDataSource.ts +24 -0
  88. package/dist/types/api/schema/externalTable.ts +14 -0
  89. package/dist/types/api/schema/index.ts +10 -0
  90. package/dist/types/api/schema/persQueueGroup.ts +191 -0
  91. package/dist/types/api/schema/schema.ts +302 -0
  92. package/dist/types/api/schema/shared.ts +42 -0
  93. package/dist/types/api/schema/table.ts +616 -0
  94. package/dist/types/api/schema/tableIndex.ts +33 -0
  95. package/dist/types/api/storage.ts +1 -1
  96. package/dist/types/assets.d.ts +1 -2
  97. package/dist/types/store/executeQuery.ts +2 -3
  98. package/dist/types/store/executeTopQueries.ts +8 -5
  99. package/dist/types/store/explainQuery.ts +4 -4
  100. package/dist/types/store/query.ts +4 -3
  101. package/dist/types/store/shardsWorkload.ts +8 -5
  102. package/dist/utils/constants.ts +4 -1
  103. package/dist/utils/error.ts +2 -3
  104. package/dist/utils/query.ts +3 -9
  105. package/dist/utils/tests/providers.tsx +6 -9
  106. package/package.json +6 -2
  107. package/dist/assets/icons/versions.svg +0 -3
  108. package/dist/containers/Tenant/Acl/Acl.js +0 -153
  109. package/dist/containers/Tenant/Schema/SchemaViewer/SchemaViewer.js +0 -94
  110. package/dist/types/api/schema.ts +0 -1326
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.11.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.10.1...v4.11.0) (2023-07-27)
4
+
5
+
6
+ ### Features
7
+
8
+ * support external objects in schema tree ([#485](https://github.com/ydb-platform/ydb-embedded-ui/issues/485)) ([cf96f9a](https://github.com/ydb-platform/ydb-embedded-ui/commit/cf96f9af02db1352f3990f21f8a84c1282229517))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **ClusterInfo:** change cluster default name ([#478](https://github.com/ydb-platform/ydb-embedded-ui/issues/478)) ([398df6e](https://github.com/ydb-platform/ydb-embedded-ui/commit/398df6e3a5778c245653f61b41ba2e1bd0ea3a51))
14
+ * fix copy schema action ([#483](https://github.com/ydb-platform/ydb-embedded-ui/issues/483)) ([f6b01c3](https://github.com/ydb-platform/ydb-embedded-ui/commit/f6b01c3cc2808337d5597f990f65ff3e7c010b05))
15
+ * **Nodes:** support v2 compute ([#476](https://github.com/ydb-platform/ydb-embedded-ui/issues/476)) ([696d43a](https://github.com/ydb-platform/ydb-embedded-ui/commit/696d43a04109c7fc68986e036e66767593af8d00))
16
+ * **ObjectSummary:** fix issue on object change with active schema tab ([#482](https://github.com/ydb-platform/ydb-embedded-ui/issues/482)) ([b50db5f](https://github.com/ydb-platform/ydb-embedded-ui/commit/b50db5ff742c5c7fc27e292309831b937e5d40bd))
17
+ * **ObjectSummary:** fix wrong tree alignment bug ([#486](https://github.com/ydb-platform/ydb-embedded-ui/issues/486)) ([e8bfe99](https://github.com/ydb-platform/ydb-embedded-ui/commit/e8bfe99657870c735a41d24febaa907ac1383479))
18
+ * **Query:** process null issues error ([#480](https://github.com/ydb-platform/ydb-embedded-ui/issues/480)) ([4c4e684](https://github.com/ydb-platform/ydb-embedded-ui/commit/4c4e6845e539296ecbdefa930bc63d3321f277dc))
19
+
20
+ ## [4.10.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.10.0...v4.10.1) (2023-07-14)
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * apply design fixes ([#475](https://github.com/ydb-platform/ydb-embedded-ui/issues/475)) ([5e7c9ca](https://github.com/ydb-platform/ydb-embedded-ui/commit/5e7c9caa9f54094a3eb6448d92d43242d3e738dd))
26
+ * **AsideNavigation:** replace query icon ([#466](https://github.com/ydb-platform/ydb-embedded-ui/issues/466)) ([4495eb2](https://github.com/ydb-platform/ydb-embedded-ui/commit/4495eb2634e48feda677c03591b92393ad28981e))
27
+ * **ClusterInfo:** add Databases field ([#474](https://github.com/ydb-platform/ydb-embedded-ui/issues/474)) ([28a9936](https://github.com/ydb-platform/ydb-embedded-ui/commit/28a99364bf5e916381a54a59d4d3f979b35f6eff))
28
+ * **Cluster:** make global scroll ([#470](https://github.com/ydb-platform/ydb-embedded-ui/issues/470)) ([30f8bc5](https://github.com/ydb-platform/ydb-embedded-ui/commit/30f8bc5ce52fceda076d278b1464d413e899ae21))
29
+ * **Cluster:** remove tabs icons and numbers ([#473](https://github.com/ydb-platform/ydb-embedded-ui/issues/473)) ([d2e43d4](https://github.com/ydb-platform/ydb-embedded-ui/commit/d2e43d41759b085f34b7f29f52f3aba60cd0588f))
30
+ * **Query:** rename New Query tab to Query ([#467](https://github.com/ydb-platform/ydb-embedded-ui/issues/467)) ([c3f5585](https://github.com/ydb-platform/ydb-embedded-ui/commit/c3f5585562a204ef0831d0c45766b17c3dc72f82))
31
+ * **TableIndexInfo:** format DataSize ([#468](https://github.com/ydb-platform/ydb-embedded-ui/issues/468)) ([a189b8c](https://github.com/ydb-platform/ydb-embedded-ui/commit/a189b8cf9610f6b1b7b5f4c01896eda5f8347ebf))
32
+
3
33
  ## [4.10.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.9.0...v4.10.0) (2023-07-07)
4
34
 
5
35
 
@@ -1,4 +1,5 @@
1
- import {TIndexDescription} from '../../../types/api/schema';
1
+ import type {TIndexDescription} from '../../../types/api/schema';
2
+ import {toFormattedSize} from '../../FormattedBytes/utils';
2
3
 
3
4
  import {createInfoFormatter} from '../utils';
4
5
 
@@ -8,6 +9,7 @@ export const formatTableIndexItem = createInfoFormatter<TIndexDescription>({
8
9
  State: (value) => value?.substring(11), // trims EIndexState prefix
9
10
  KeyColumnNames: (value) => value?.join(', '),
10
11
  DataColumnNames: (value) => value?.join(', '),
12
+ DataSize: toFormattedSize,
11
13
  },
12
14
  labels: {
13
15
  KeyColumnNames: 'Columns',
@@ -11,16 +11,16 @@ interface CellProps {
11
11
  }
12
12
 
13
13
  export const Cell = React.memo(function Cell(props: CellProps) {
14
- const {
15
- className,
16
- value,
17
- } = props;
14
+ const {className, value} = props;
18
15
 
19
16
  const dispatch = useDispatch();
20
17
 
21
- useEffect(() => () => {
22
- dispatch(hideTooltip());
23
- }, [dispatch]);
18
+ useEffect(
19
+ () => () => {
20
+ dispatch(hideTooltip());
21
+ },
22
+ [dispatch],
23
+ );
24
24
 
25
25
  return (
26
26
  <span
@@ -29,5 +29,5 @@ export const Cell = React.memo(function Cell(props: CellProps) {
29
29
  >
30
30
  {value}
31
31
  </span>
32
- )
32
+ );
33
33
  });
@@ -1,3 +1,3 @@
1
1
  {
2
- "empty": "Table is empty"
2
+ "empty": "Table is empty"
3
3
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "empty": "Таблица пустая"
2
+ "empty": "Таблица пустая"
3
3
  }
@@ -33,18 +33,15 @@ export default function ShortyString({
33
33
  const [expanded, setExpanded] = React.useState(false);
34
34
 
35
35
  const toggleLabelAction = expanded ? collapseLabel : expandLabel;
36
- const toggleLabelSymbolsCount = displayLength && !expanded
37
- ? i18n('chars_count', {count: value.length})
38
- : '';
36
+ const toggleLabelSymbolsCount =
37
+ displayLength && !expanded ? i18n('chars_count', {count: value.length}) : '';
39
38
  const toggleLabel = toggleLabelAction + toggleLabelSymbolsCount;
40
39
 
41
40
  // showing toogle button with a label that is longer than the hidden part is pointless,
42
41
  // hence compare to limit + length in the not-strict mode
43
42
  const hasToggle = value.length > limit + (strict ? 0 : toggleLabel.length);
44
43
 
45
- const text = expanded || !hasToggle
46
- ? value
47
- : value.slice(0, limit - 4) + '\u00a0...';
44
+ const text = expanded || !hasToggle ? value : value.slice(0, limit - 4) + '\u00a0...';
48
45
 
49
46
  return (
50
47
  <div className={block()}>
@@ -1,10 +1,10 @@
1
1
  {
2
- "default_collapse_label": "Show less",
3
- "default_expand_label": "Show more",
4
- "chars_count": [
5
- " ({{count}} symbol)",
6
- " ({{count}} symbols)",
7
- " ({{count}} symbols)",
8
- " ({{count}} symbols)"
9
- ]
2
+ "default_collapse_label": "Show less",
3
+ "default_expand_label": "Show more",
4
+ "chars_count": [
5
+ " ({{count}} symbol)",
6
+ " ({{count}} symbols)",
7
+ " ({{count}} symbols)",
8
+ " ({{count}} symbols)"
9
+ ]
10
10
  }
@@ -1,10 +1,10 @@
1
1
  {
2
- "default_collapse_label": "Показать меньше",
3
- "default_expand_label": "Показать ещё",
4
- "chars_count": [
5
- " ({{count}} символ)",
6
- " ({{count}} символа)",
7
- " ({{count}} символов)",
8
- " ({{count}} символов)"
9
- ]
2
+ "default_collapse_label": "Показать меньше",
3
+ "default_expand_label": "Показать ещё",
4
+ "chars_count": [
5
+ " ({{count}} символ)",
6
+ " ({{count}} символа)",
7
+ " ({{count}} символов)",
8
+ " ({{count}} символов)"
9
+ ]
10
10
  }
@@ -9,5 +9,3 @@ i18n.registerKeyset(Lang.En, COMPONENT, en);
9
9
  i18n.registerKeyset(Lang.Ru, COMPONENT, ru);
10
10
 
11
11
  export default i18n.keyset(COMPONENT);
12
-
13
-
@@ -13,23 +13,23 @@ const b = cn('stack');
13
13
 
14
14
  export const Stack: React.FC<StackProps> = ({children, className}) => (
15
15
  <div className={b(null, className)}>
16
- {
17
- React.Children.map(children, (child, index) => {
18
- if (!React.isValidElement(child)) {
19
- return null;
20
- }
16
+ {React.Children.map(children, (child, index) => {
17
+ if (!React.isValidElement(child)) {
18
+ return null;
19
+ }
21
20
 
22
- return (
23
- <div
24
- className={b('layer')}
25
- style={{
21
+ return (
22
+ <div
23
+ className={b('layer')}
24
+ style={
25
+ {
26
26
  [LAYER_CSS_VAR]: index,
27
- } as React.CSSProperties}
28
- >
29
- {child}
30
- </div>
31
- );
32
- })
33
- }
27
+ } as React.CSSProperties
28
+ }
29
+ >
30
+ {child}
31
+ </div>
32
+ );
33
+ })}
34
34
  </div>
35
35
  );
@@ -1,6 +1,6 @@
1
- import { FC } from 'react';
1
+ import {FC} from 'react';
2
2
  import block from 'bem-cn-lite';
3
- import { Skeleton } from '@gravity-ui/uikit';
3
+ import {Skeleton} from '@gravity-ui/uikit';
4
4
 
5
5
  import './TableSkeleton.scss';
6
6
 
@@ -11,7 +11,7 @@ interface TableSkeletonProps {
11
11
  rows?: number;
12
12
  }
13
13
 
14
- export const TableSkeleton: FC<TableSkeletonProps> = ({ rows = 2, className }) => (
14
+ export const TableSkeleton: FC<TableSkeletonProps> = ({rows = 2, className}) => (
15
15
  <div className={b(null, className)}>
16
16
  <div className={b('row')}>
17
17
  <Skeleton className={b('col-1')} />
@@ -0,0 +1,32 @@
1
+ @import '../../styles/mixins.scss';
2
+
3
+ .ydb-table-with-controls-layout {
4
+ display: inline-block;
5
+
6
+ box-sizing: border-box;
7
+ min-width: 100%;
8
+
9
+ &__controls-wrapper {
10
+ z-index: 3;
11
+
12
+ box-sizing: border-box;
13
+ width: 100%;
14
+
15
+ @include sticky-top();
16
+ }
17
+
18
+ &__controls {
19
+ z-index: 3;
20
+
21
+ width: max-content;
22
+ height: 62px;
23
+
24
+ @include controls();
25
+ @include sticky-top();
26
+ }
27
+
28
+ .data-table__sticky_moving {
29
+ // Place table head right after controls
30
+ top: 62px !important;
31
+ }
32
+ }
@@ -0,0 +1,43 @@
1
+ import type {ReactNode} from 'react';
2
+ import block from 'bem-cn-lite';
3
+
4
+ import {TableSkeleton} from '../TableSkeleton/TableSkeleton';
5
+
6
+ import './TableWithControlsLayout.scss';
7
+
8
+ const b = block('ydb-table-with-controls-layout');
9
+
10
+ interface TableWithControlsLayoutItemProps {
11
+ children: ReactNode;
12
+ className?: string;
13
+ }
14
+
15
+ interface TableProps extends TableWithControlsLayoutItemProps {
16
+ loading?: boolean;
17
+ }
18
+
19
+ export const TableWithControlsLayout = ({
20
+ children,
21
+ className,
22
+ }: TableWithControlsLayoutItemProps) => {
23
+ return <div className={b(null, className)}>{children}</div>;
24
+ };
25
+
26
+ TableWithControlsLayout.Controls = function TableControls({
27
+ children,
28
+ className,
29
+ }: TableWithControlsLayoutItemProps) {
30
+ return (
31
+ <div className={b('controls-wrapper')}>
32
+ <div className={b('controls', className)}>{children}</div>
33
+ </div>
34
+ );
35
+ };
36
+
37
+ TableWithControlsLayout.Table = function Table({children, loading, className}: TableProps) {
38
+ if (loading) {
39
+ return <TableSkeleton className={b('loader')} />;
40
+ }
41
+
42
+ return <div className={b('table', className)}>{children}</div>;
43
+ };
@@ -7,7 +7,7 @@ import cn from 'bem-cn-lite';
7
7
  import {Icon, Button} from '@gravity-ui/uikit';
8
8
  import {AsideHeader, MenuItem as AsideHeaderMenuItem, FooterItem} from '@gravity-ui/navigation';
9
9
 
10
- import squareChartBarIcon from '@gravity-ui/icons/svgs/square-chart-bar.svg';
10
+ import terminalIcon from '@gravity-ui/icons/svgs/terminal.svg';
11
11
  import pulseIcon from '@gravity-ui/icons/svgs/pulse.svg';
12
12
 
13
13
  import signOutIcon from '../../assets/icons/signOut.svg';
@@ -141,7 +141,7 @@ export const useGetLeftNavigationItems = () => {
141
141
  {
142
142
  id: TENANT_PAGES_IDS.query,
143
143
  title: 'Query',
144
- icon: squareChartBarIcon,
144
+ icon: terminalIcon,
145
145
  iconSize: 20,
146
146
  location: getTenantPath({
147
147
  ...queryParams,
@@ -5,13 +5,12 @@
5
5
  flex-grow: 1;
6
6
 
7
7
  height: 100%;
8
- padding: 20px 20px 0px;
8
+ padding: 0 20px;
9
9
 
10
10
  @include flex-container();
11
11
 
12
- &__content {
13
- overflow: auto;
14
-
15
- height: 100%;
12
+ &__tabs {
13
+ position: sticky;
14
+ left: 0;
16
15
  }
17
16
  }
@@ -118,20 +118,6 @@ function Cluster({
118
118
  }
119
119
  };
120
120
 
121
- const getTabEntityCount = (tabId: ClusterTab) => {
122
- switch (tabId) {
123
- case clusterTabsIds.tenants: {
124
- return cluster?.Tenants ? Number(cluster.Tenants) : undefined;
125
- }
126
- case clusterTabsIds.nodes: {
127
- return cluster?.NodesTotal ? Number(cluster.NodesTotal) : undefined;
128
- }
129
- default: {
130
- return undefined;
131
- }
132
- }
133
- };
134
-
135
121
  return (
136
122
  <div className={b()}>
137
123
  <ClusterInfo
@@ -142,17 +128,12 @@ function Cluster({
142
128
  additionalClusterProps={additionalClusterProps}
143
129
  />
144
130
 
145
- <div>
131
+ <div className={b('tabs')}>
146
132
  <Tabs
147
133
  size="l"
148
134
  allowNotSelected={true}
149
135
  activeTab={activeTab as string}
150
- items={clusterTabs.map((item) => {
151
- return {
152
- ...item,
153
- counter: getTabEntityCount(item.id),
154
- };
155
- })}
136
+ items={clusterTabs}
156
137
  wrapTo={({id}, node) => {
157
138
  const path = getClusterPath(id as ClusterTab, queryParams);
158
139
  return (
@@ -164,7 +145,7 @@ function Cluster({
164
145
  />
165
146
  </div>
166
147
 
167
- <div className={b('content')}>{renderTab()}</div>
148
+ <div>{renderTab()}</div>
168
149
  </div>
169
150
  );
170
151
  }
@@ -1,7 +1,11 @@
1
1
  @import '../../../styles/mixins';
2
2
 
3
3
  .cluster-info {
4
+ position: sticky;
5
+ left: 0;
6
+
4
7
  width: 100%;
8
+ padding-top: 20px;
5
9
 
6
10
  &__header {
7
11
  display: flex;
@@ -18,7 +18,11 @@ import type {TClusterInfo} from '../../../types/api/cluster';
18
18
  import {backend, customBackend} from '../../../store';
19
19
  import {formatStorageValues} from '../../../utils';
20
20
  import {useSetting, useTypedSelector} from '../../../utils/hooks';
21
- import {CLUSTER_INFO_HIDDEN_KEY, DEVELOPER_UI} from '../../../utils/constants';
21
+ import {
22
+ CLUSTER_DEFAULT_TITLE,
23
+ CLUSTER_INFO_HIDDEN_KEY,
24
+ DEVELOPER_UI_TITLE,
25
+ } from '../../../utils/constants';
22
26
 
23
27
  import {VersionsBar} from '../VersionsBar/VersionsBar';
24
28
  import {ClusterInfoSkeleton} from '../ClusterInfoSkeleton/ClusterInfoSkeleton';
@@ -57,6 +61,13 @@ const getInfo = (
57
61
  });
58
62
  }
59
63
 
64
+ if (cluster.Tenants) {
65
+ info.push({
66
+ label: 'Databases',
67
+ value: cluster.Tenants,
68
+ });
69
+ }
70
+
60
71
  info.push(
61
72
  {
62
73
  label: 'Nodes',
@@ -141,7 +152,7 @@ export const ClusterInfo = ({
141
152
  const {info = [], links = []} = additionalClusterProps;
142
153
 
143
154
  const clusterInfo = getInfo(cluster, versionsValues, info, [
144
- {title: DEVELOPER_UI, url: internalLink},
155
+ {title: DEVELOPER_UI_TITLE, url: internalLink},
145
156
  ...links,
146
157
  ]);
147
158
 
@@ -166,7 +177,7 @@ export const ClusterInfo = ({
166
177
  <EntityStatus
167
178
  size="m"
168
179
  status={cluster?.Overall}
169
- name={cluster?.Name ?? 'Unknown cluster'}
180
+ name={cluster?.Name ?? CLUSTER_DEFAULT_TITLE}
170
181
  className={b('title')}
171
182
  />
172
183
  );
@@ -18,7 +18,7 @@ interface ClusterInfoSkeletonProps {
18
18
  rows?: number;
19
19
  }
20
20
 
21
- export const ClusterInfoSkeleton = ({rows = 6, className}: ClusterInfoSkeletonProps) => (
21
+ export const ClusterInfoSkeleton = ({rows = 7, className}: ClusterInfoSkeletonProps) => (
22
22
  <div className={b(null, className)}>
23
23
  {[...new Array(rows)].map((_, index) => (
24
24
  <div className={b('row')} key={`skeleton-row-${index}`}>
@@ -1,10 +1,3 @@
1
- import {Icon} from '@gravity-ui/uikit';
2
- import cubes3Icon from '@gravity-ui/icons/svgs/cubes-3.svg';
3
- import databasesIcon from '@gravity-ui/icons/svgs/databases.svg';
4
- import hardDriveIcon from '@gravity-ui/icons/svgs/hard-drive.svg';
5
-
6
- import versionsIcon from '../../assets/icons/versions.svg';
7
-
8
1
  import type {ValueOf} from '../../types/common';
9
2
  import routes, {createHref} from '../../routes';
10
3
 
@@ -20,22 +13,18 @@ export type ClusterTab = ValueOf<typeof clusterTabsIds>;
20
13
  const tenants = {
21
14
  id: clusterTabsIds.tenants,
22
15
  title: 'Databases',
23
- icon: <Icon data={databasesIcon} />,
24
16
  };
25
17
  const nodes = {
26
18
  id: clusterTabsIds.nodes,
27
19
  title: 'Nodes',
28
- icon: <Icon data={cubes3Icon} />,
29
20
  };
30
21
  const storage = {
31
22
  id: clusterTabsIds.storage,
32
23
  title: 'Storage',
33
- icon: <Icon data={hardDriveIcon} />,
34
24
  };
35
25
  const versions = {
36
26
  id: clusterTabsIds.versions,
37
27
  title: 'Versions',
38
- icon: <Icon data={versionsIcon} />,
39
28
  };
40
29
 
41
30
  export const clusterTabs = [tenants, nodes, storage, versions];
@@ -6,14 +6,10 @@
6
6
  justify-content: space-between;
7
7
  align-items: center;
8
8
 
9
- padding: 0 20px 0 18px;
10
-
11
- font-weight: 600;
9
+ padding: 0 20px 0 12px;
12
10
 
13
11
  border-bottom: 1px solid var(--yc-color-line-generic);
14
12
 
15
- @include body2-typography;
16
-
17
13
  &__breadcrumb {
18
14
  display: flex;
19
15
  align-items: center;
@@ -10,7 +10,7 @@ import {ExternalLinkWithIcon} from '../../components/ExternalLinkWithIcon/Extern
10
10
  import {backend, customBackend} from '../../store';
11
11
  import {getClusterInfo} from '../../store/reducers/cluster/cluster';
12
12
  import {useTypedSelector} from '../../utils/hooks';
13
- import {DEVELOPER_UI} from '../../utils/constants';
13
+ import {DEVELOPER_UI_TITLE} from '../../utils/constants';
14
14
  import {parseQuery} from '../../routes';
15
15
 
16
16
  import {RawBreadcrumbItem, getBreadcrumbs} from './breadcrumbs';
@@ -105,7 +105,7 @@ function Header({mainPage}: HeaderProps) {
105
105
  </div>
106
106
 
107
107
  <ExternalLinkWithIcon
108
- title={DEVELOPER_UI}
108
+ title={DEVELOPER_UI_TITLE}
109
109
  url={getInternalLink(singleClusterMode)}
110
110
  />
111
111
  </header>
@@ -16,6 +16,7 @@ import {
16
16
  TENANT_PAGES_IDS,
17
17
  } from '../../store/reducers/tenant/constants';
18
18
  import routes, {createHref} from '../../routes';
19
+ import {CLUSTER_DEFAULT_TITLE} from '../../utils/constants';
19
20
 
20
21
  import {getClusterPath} from '../Cluster/utils';
21
22
  import {TenantTabsGroups, getTenantPath} from '../Tenant/TenantPages';
@@ -39,7 +40,7 @@ const getClusterBreadcrumbs = (
39
40
 
40
41
  return [
41
42
  {
42
- text: clusterName || 'Cluster',
43
+ text: clusterName || CLUSTER_DEFAULT_TITLE,
43
44
  link: getClusterPath(clusterTab, query),
44
45
  icon: nodesRightIcon,
45
46
  },
@@ -4,13 +4,14 @@ import cn from 'bem-cn-lite';
4
4
 
5
5
  import {Checkbox, Select} from '@gravity-ui/uikit';
6
6
 
7
+ import type {IHeatmapMetricValue} from '../../types/store/heatmap';
7
8
  import {getTabletsInfo, setHeatmapOptions} from '../../store/reducers/heatmap';
8
9
  import {showTooltip, hideTooltip} from '../../store/reducers/tooltip';
9
10
  import {formatNumber} from '../../utils';
10
- import {prepareQueryError} from '../../utils/query';
11
11
  import {useAutofetcher, useTypedSelector} from '../../utils/hooks';
12
+
12
13
  import {Loader} from '../../components/Loader';
13
- import type {IHeatmapMetricValue} from '../../types/store/heatmap';
14
+ import {ResponseError} from '../../components/Errors/ResponseError';
14
15
 
15
16
  import {COLORS_RANGE_SIZE, getColorRange, getColorIndex, getCurrentMetricLimits} from './util';
16
17
  import {HeatmapCanvas} from './HeatmapCanvas/HeatmapCanvas';
@@ -196,7 +197,7 @@ export const Heatmap = ({path}: HeatmapProps) => {
196
197
  }
197
198
 
198
199
  if (error) {
199
- return <div>{prepareQueryError(error)}</div>;
200
+ return <ResponseError error={error} />;
200
201
  }
201
202
 
202
203
  return renderContent();
@@ -12,14 +12,8 @@ interface PDiskTitleBadgeProps {
12
12
  export function PDiskTitleBadge({label, value, className}: PDiskTitleBadgeProps) {
13
13
  return (
14
14
  <span className={b('pdisk-title-item', className)}>
15
- {label && (
16
- <span className={b('pdisk-title-item-label')}>
17
- {label}:
18
- </span>
19
- )}
20
- <span className={b('pdisk-title-item-value')}>
21
- {value}
22
- </span>
15
+ {label && <span className={b('pdisk-title-item-label')}>{label}:</span>}
16
+ <span className={b('pdisk-title-item-value')}>{value}</span>
23
17
  </span>
24
18
  );
25
19
  }
@@ -1,21 +1,10 @@
1
1
  @import '../../styles/mixins.scss';
2
2
 
3
3
  .ydb-nodes {
4
- overflow: auto;
5
- flex-grow: 1;
6
-
7
- height: 100%;
8
-
9
- @include flex-container();
10
-
11
4
  &__search {
12
5
  @include search();
13
6
  }
14
7
 
15
- &__controls {
16
- @include controls();
17
- }
18
-
19
8
  &__show-all-wrapper {
20
9
  position: sticky;
21
10
  left: 0;
@@ -23,19 +12,7 @@
23
12
  margin-bottom: 15px;
24
13
  }
25
14
 
26
- &__table-wrapper {
27
- overflow: auto;
28
- @include flex-container();
29
- }
30
-
31
- &__table-content {
32
- overflow: auto;
33
-
34
- height: 100%;
35
-
36
- @include freeze-nth-column(1);
37
- @include freeze-nth-column(2, 80px);
38
-
15
+ &__table {
39
16
  @include table-styles;
40
17
  @include table-sticky-styles;
41
18
  }