ydb-embedded-ui 4.5.1 → 4.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.
- package/CHANGELOG.md +20 -0
- package/dist/components/FullNodeViewer/FullNodeViewer.js +1 -1
- package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +1 -1
- package/dist/components/PoolUsage/PoolUsage.scss +1 -1
- package/dist/components/PoolUsage/PoolUsage.tsx +50 -0
- package/dist/containers/App/Content.js +3 -2
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +4 -50
- package/dist/containers/Cluster/Cluster.scss +7 -48
- package/dist/containers/Cluster/Cluster.tsx +136 -20
- package/dist/containers/Cluster/ClusterInfo/ClusterInfo.scss +34 -17
- package/dist/containers/Cluster/ClusterInfo/ClusterInfo.tsx +57 -91
- package/dist/containers/Cluster/ClusterInfoSkeleton/ClusterInfoSkeleton.scss +48 -0
- package/dist/containers/Cluster/ClusterInfoSkeleton/ClusterInfoSkeleton.tsx +34 -0
- package/dist/containers/Cluster/utils.ts +34 -0
- package/dist/containers/Header/Header.scss +0 -24
- package/dist/containers/Header/Header.tsx +14 -44
- package/dist/containers/Node/Node.tsx +23 -21
- package/dist/containers/Node/NodeStructure/NodeStructure.tsx +19 -17
- package/dist/containers/Nodes/Nodes.tsx +0 -16
- package/dist/containers/Nodes/getNodesColumns.tsx +1 -1
- package/dist/containers/Storage/Storage.js +1 -11
- package/dist/containers/Tablet/Tablet.tsx +28 -0
- package/dist/containers/TabletsFilters/TabletsFilters.js +16 -1
- package/dist/containers/Tenant/Diagnostics/Describe/Describe.tsx +1 -1
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +3 -0
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +3 -3
- package/dist/containers/Tenant/Diagnostics/Network/Network.js +2 -2
- package/dist/containers/Tenant/Diagnostics/Overview/ChangefeedInfo/ChangefeedInfo.tsx +4 -6
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +56 -53
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +1 -1
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.tsx +1 -1
- package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +1 -1
- package/dist/containers/Tenant/Preview/Preview.js +1 -1
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +26 -22
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/OldQueryEditorControls.tsx +10 -3
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.tsx +8 -1
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/shared.ts +1 -6
- package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +1 -1
- package/dist/containers/Tenant/Tenant.tsx +8 -13
- package/dist/containers/Tenant/utils/schemaActions.ts +1 -1
- package/dist/containers/Tenants/Tenants.js +18 -28
- package/dist/containers/Tenants/Tenants.scss +2 -4
- package/dist/containers/UserSettings/i18n/en.json +2 -2
- package/dist/containers/UserSettings/i18n/ru.json +2 -2
- package/dist/containers/UserSettings/settings.ts +4 -4
- package/dist/containers/Versions/GroupedNodesTree/GroupedNodesTree.scss +1 -0
- package/dist/containers/Versions/NodesTable/NodesTable.tsx +2 -3
- package/dist/containers/Versions/Versions.scss +0 -4
- package/dist/containers/Versions/Versions.tsx +74 -66
- package/dist/routes.ts +0 -7
- package/dist/services/api.ts +8 -4
- package/dist/store/reducers/clusterNodes/clusterNodes.tsx +4 -0
- package/dist/store/reducers/index.ts +6 -4
- package/dist/store/reducers/{network.js → network/network.ts} +11 -8
- package/dist/store/reducers/network/types.ts +16 -0
- package/dist/store/reducers/node/node.ts +102 -0
- package/dist/store/reducers/node/selectors.ts +59 -0
- package/dist/store/reducers/node/types.ts +44 -0
- package/dist/store/reducers/overview/overview.ts +109 -0
- package/dist/store/reducers/overview/types.ts +24 -0
- package/dist/store/reducers/{schema.ts → schema/schema.ts} +24 -50
- package/dist/{types/store/schema.ts → store/reducers/schema/types.ts} +16 -15
- package/dist/store/reducers/{schemaAcl.js → schemaAcl/schemaAcl.ts} +20 -9
- package/dist/store/reducers/schemaAcl/types.ts +15 -0
- package/dist/store/reducers/settings/settings.ts +5 -3
- package/dist/types/api/acl.ts +1 -1
- package/dist/types/api/query.ts +78 -44
- package/dist/types/store/explainQuery.ts +2 -2
- package/dist/types/store/query.ts +4 -2
- package/dist/utils/constants.ts +3 -1
- package/dist/utils/nodes.ts +1 -1
- package/dist/utils/query.ts +3 -3
- package/package.json +1 -1
- package/dist/components/PoolUsage/PoolUsage.js +0 -54
- package/dist/store/reducers/node.js +0 -141
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [4.6.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.5.2...v4.6.0) (2023-06-13)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* **QueryEditor:** add data and query modes ([#422](https://github.com/ydb-platform/ydb-embedded-ui/issues/422)) ([c142f03](https://github.com/ydb-platform/ydb-embedded-ui/commit/c142f03e9caeab4dcf1d34b3988e949a94213932))
|
9
|
+
* rework navigation, update breadcrumbs ([#418](https://github.com/ydb-platform/ydb-embedded-ui/issues/418)) ([2d807d6](https://github.com/ydb-platform/ydb-embedded-ui/commit/2d807d6a52e13edcf2a7e1591672224339d91949))
|
10
|
+
|
11
|
+
|
12
|
+
### Bug Fixes
|
13
|
+
|
14
|
+
* **Diagnostics:** remove unneded tenantInfo fetch ([#420](https://github.com/ydb-platform/ydb-embedded-ui/issues/420)) ([ccaafe4](https://github.com/ydb-platform/ydb-embedded-ui/commit/ccaafe4ec9346ee1ec2ebd2a62600274f2175bfb))
|
15
|
+
|
16
|
+
## [4.5.2](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.5.1...v4.5.2) (2023-06-06)
|
17
|
+
|
18
|
+
|
19
|
+
### Bug Fixes
|
20
|
+
|
21
|
+
* **Versions:** enable table dynamic render ([#416](https://github.com/ydb-platform/ydb-embedded-ui/issues/416)) ([3c877ea](https://github.com/ydb-platform/ydb-embedded-ui/commit/3c877ea88a0c4036213b38099676f473cf3ac2d6))
|
22
|
+
|
3
23
|
## [4.5.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.5.0...v4.5.1) (2023-06-02)
|
4
24
|
|
5
25
|
|
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
|
4
4
|
|
5
5
|
import InfoViewer from '../InfoViewer/InfoViewer';
|
6
6
|
import ProgressViewer from '../ProgressViewer/ProgressViewer';
|
7
|
-
import PoolUsage from '../PoolUsage/PoolUsage';
|
7
|
+
import {PoolUsage} from '../PoolUsage/PoolUsage';
|
8
8
|
|
9
9
|
import {LOAD_AVERAGE_TIME_INTERVALS} from '../../utils/constants';
|
10
10
|
import {calcUptime} from '../../utils';
|
@@ -16,7 +16,7 @@ const b = block('ydb-node-host-wrapper');
|
|
16
16
|
|
17
17
|
interface NodeHostWrapperProps {
|
18
18
|
node: INodesPreparedEntity;
|
19
|
-
getNodeRef?: (node?: NodeAddress) => string;
|
19
|
+
getNodeRef?: (node?: NodeAddress) => string | null;
|
20
20
|
}
|
21
21
|
|
22
22
|
export const NodeHostWrapper = ({node, getNodeRef}: NodeHostWrapperProps) => {
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import block from 'bem-cn-lite';
|
2
|
+
|
3
|
+
import type {TPoolStats} from '../../types/api/nodes';
|
4
|
+
|
5
|
+
import './PoolUsage.scss';
|
6
|
+
|
7
|
+
const b = block('ydb-pool-usage');
|
8
|
+
|
9
|
+
const getLineType = (fillWidth: number) => {
|
10
|
+
let fillColor = 'green';
|
11
|
+
if (fillWidth > 60 && fillWidth <= 80) {
|
12
|
+
fillColor = 'yellow';
|
13
|
+
} else if (fillWidth > 80) {
|
14
|
+
fillColor = 'red';
|
15
|
+
}
|
16
|
+
|
17
|
+
return fillColor;
|
18
|
+
};
|
19
|
+
|
20
|
+
interface PoolUsageProps {
|
21
|
+
data?: TPoolStats;
|
22
|
+
}
|
23
|
+
|
24
|
+
export const PoolUsage = ({data: pool = {}}: PoolUsageProps) => {
|
25
|
+
const {Threads, Name = 'Unknown', Usage = 0} = pool;
|
26
|
+
const dataExist = Usage && Threads;
|
27
|
+
|
28
|
+
const value = Math.floor(Usage * 100);
|
29
|
+
const fillWidth = value > 100 ? 100 : value;
|
30
|
+
|
31
|
+
return (
|
32
|
+
<div className={b()}>
|
33
|
+
<div className={b('info')}>
|
34
|
+
<div className={b('pool-name')}>{Name}</div>
|
35
|
+
{dataExist && (
|
36
|
+
<div className={b('value')}>
|
37
|
+
<div className={b('percents')}>{value < 1 ? '<1' : value}%</div>
|
38
|
+
<div className={b('threads')}>(×{Threads})</div>
|
39
|
+
</div>
|
40
|
+
)}
|
41
|
+
</div>
|
42
|
+
<div className={b('visual')}>
|
43
|
+
<div
|
44
|
+
className={b('usage-line', {type: getLineType(fillWidth)})}
|
45
|
+
style={{width: `${fillWidth}%`}}
|
46
|
+
/>
|
47
|
+
</div>
|
48
|
+
</div>
|
49
|
+
);
|
50
|
+
};
|
@@ -5,7 +5,7 @@ import {connect} from 'react-redux';
|
|
5
5
|
|
6
6
|
import {ThemeProvider} from '@gravity-ui/uikit';
|
7
7
|
|
8
|
-
import routes, {createHref
|
8
|
+
import routes, {createHref} from '../../routes';
|
9
9
|
|
10
10
|
import Cluster from '../Cluster/Cluster';
|
11
11
|
import Tenant from '../Tenant/Tenant';
|
@@ -23,6 +23,7 @@ import './App.scss';
|
|
23
23
|
import PropTypes from 'prop-types';
|
24
24
|
import HistoryContext from '../../contexts/HistoryContext';
|
25
25
|
import Authentication from '../Authentication/Authentication';
|
26
|
+
import {clusterTabsIds} from '../Cluster/utils';
|
26
27
|
|
27
28
|
const b = cn('app');
|
28
29
|
|
@@ -44,7 +45,7 @@ export function Content(props) {
|
|
44
45
|
<Route path={routes.tabletsFilters} component={TabletsFilters} />
|
45
46
|
<Redirect
|
46
47
|
to={createHref(routes.cluster, {
|
47
|
-
activeTab:
|
48
|
+
activeTab: clusterTabsIds.tenants,
|
48
49
|
})}
|
49
50
|
/>
|
50
51
|
</Switch>
|
@@ -9,11 +9,7 @@ import {AsideHeader, MenuItem as AsideHeaderMenuItem, FooterItem} from '@gravity
|
|
9
9
|
|
10
10
|
import signOutIcon from '../../assets/icons/signOut.svg';
|
11
11
|
import signInIcon from '../../assets/icons/signIn.svg';
|
12
|
-
import databaseIcon from '../../assets/icons/server.svg';
|
13
|
-
import storageIcon from '../../assets/icons/storage.svg';
|
14
|
-
import clusterIcon from '../../assets/icons/cluster.svg';
|
15
12
|
import ydbLogoIcon from '../../assets/icons/ydb.svg';
|
16
|
-
import databasesIcon from '../../assets/icons/databases.svg';
|
17
13
|
import userSecret from '../../assets/icons/user-secret.svg';
|
18
14
|
import userChecked from '../../assets/icons/user-check.svg';
|
19
15
|
import settingsIcon from '../../assets/icons/settings.svg';
|
@@ -21,7 +17,7 @@ import supportIcon from '../../assets/icons/support.svg';
|
|
21
17
|
|
22
18
|
import {UserSettings} from '../UserSettings/UserSettings';
|
23
19
|
|
24
|
-
import routes, {createHref
|
20
|
+
import routes, {createHref} from '../../routes';
|
25
21
|
|
26
22
|
import {logout} from '../../store/reducers/authentication';
|
27
23
|
import {getParsedSettingValue, setSettingValue} from '../../store/reducers/settings/settings';
|
@@ -115,46 +111,8 @@ interface AsideNavigationProps {
|
|
115
111
|
setSettingValue: (name: string, value: string) => void;
|
116
112
|
}
|
117
113
|
|
118
|
-
|
119
|
-
|
120
|
-
id: CLUSTER_PAGES.tenants.id,
|
121
|
-
title: 'Databases',
|
122
|
-
icon: databasesIcon,
|
123
|
-
iconSize: 20,
|
124
|
-
location: createHref(routes.cluster, {
|
125
|
-
activeTab: CLUSTER_PAGES.tenants.id,
|
126
|
-
}),
|
127
|
-
locationKeys: ['/tenant'],
|
128
|
-
},
|
129
|
-
{
|
130
|
-
id: CLUSTER_PAGES.nodes.id,
|
131
|
-
title: 'Nodes',
|
132
|
-
icon: databaseIcon,
|
133
|
-
iconSize: 20,
|
134
|
-
location: createHref(routes.cluster, {activeTab: CLUSTER_PAGES.nodes.id}),
|
135
|
-
locationKeys: ['/node'],
|
136
|
-
},
|
137
|
-
{
|
138
|
-
id: CLUSTER_PAGES.storage.id,
|
139
|
-
title: 'Storage',
|
140
|
-
icon: storageIcon,
|
141
|
-
iconSize: 20,
|
142
|
-
location: createHref(routes.cluster, {
|
143
|
-
activeTab: CLUSTER_PAGES.storage.id,
|
144
|
-
}),
|
145
|
-
locationKeys: ['/storage'],
|
146
|
-
},
|
147
|
-
{
|
148
|
-
id: CLUSTER_PAGES.cluster.id,
|
149
|
-
title: 'Cluster',
|
150
|
-
icon: clusterIcon,
|
151
|
-
iconSize: 20,
|
152
|
-
location: createHref(routes.cluster, {
|
153
|
-
activeTab: CLUSTER_PAGES.cluster.id,
|
154
|
-
}),
|
155
|
-
locationKeys: ['/cluster/cluster'],
|
156
|
-
},
|
157
|
-
];
|
114
|
+
// FIXME: add items or delete
|
115
|
+
const items: MenuItem[] = [];
|
158
116
|
|
159
117
|
enum Panel {
|
160
118
|
UserSettings = 'UserSettings',
|
@@ -172,17 +130,13 @@ function AsideNavigation(props: AsideNavigationProps) {
|
|
172
130
|
|
173
131
|
const menuItems: AsideHeaderMenuItem[] = React.useMemo(() => {
|
174
132
|
const {pathname} = location;
|
175
|
-
const isClusterPage = pathname === '/cluster';
|
176
133
|
const menuItems: AsideHeaderMenuItem[] = items.map((item) => {
|
177
134
|
const locationKeysCoincidence = item.locationKeys?.filter((key) =>
|
178
135
|
pathname.startsWith(key),
|
179
136
|
);
|
180
|
-
|
137
|
+
const current =
|
181
138
|
(locationKeysCoincidence && locationKeysCoincidence.length > 0) ||
|
182
139
|
item.location.startsWith(pathname);
|
183
|
-
if (isClusterPage && item.id !== CLUSTER_PAGES.tenants.id) {
|
184
|
-
current = false;
|
185
|
-
}
|
186
140
|
return {
|
187
141
|
id: item.id,
|
188
142
|
title: item.title,
|
@@ -2,57 +2,16 @@
|
|
2
2
|
|
3
3
|
.cluster {
|
4
4
|
overflow: auto;
|
5
|
+
flex-grow: 1;
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
&_tab_cluster {
|
10
|
-
padding: 0px;
|
11
|
-
}
|
12
|
-
|
13
|
-
&__tab {
|
14
|
-
text-decoration: none;
|
15
|
-
|
16
|
-
&:first-letter {
|
17
|
-
text-transform: uppercase;
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
&__format-label {
|
22
|
-
margin-right: 15px;
|
23
|
-
}
|
24
|
-
|
25
|
-
&__title {
|
26
|
-
text-align: center;
|
27
|
-
}
|
7
|
+
height: 100%;
|
8
|
+
padding: 20px 20px 0px;
|
28
9
|
|
29
|
-
|
30
|
-
animation: none !important;
|
31
|
-
}
|
32
|
-
|
33
|
-
&__search {
|
34
|
-
width: 255px;
|
35
|
-
margin: 0 15px 0 0;
|
36
|
-
}
|
37
|
-
|
38
|
-
&__tablets {
|
39
|
-
padding: 0 !important;
|
40
|
-
|
41
|
-
.tablets-viewer__grid {
|
42
|
-
grid-template-columns: 125px;
|
43
|
-
}
|
44
|
-
}
|
45
|
-
|
46
|
-
&__controls {
|
47
|
-
display: flex;
|
48
|
-
justify-content: space-between;
|
10
|
+
@include flex-container();
|
49
11
|
|
50
|
-
|
51
|
-
|
12
|
+
&__content {
|
13
|
+
overflow: auto;
|
52
14
|
|
53
|
-
|
54
|
-
display: flex;
|
55
|
-
flex: 1 1 auto;
|
56
|
-
flex-direction: column;
|
15
|
+
height: 100%;
|
57
16
|
}
|
58
17
|
}
|
@@ -1,51 +1,133 @@
|
|
1
|
-
import {
|
1
|
+
import {useEffect, useMemo} from 'react';
|
2
|
+
import {useLocation, useRouteMatch} from 'react-router';
|
3
|
+
import {useDispatch} from 'react-redux';
|
2
4
|
import cn from 'bem-cn-lite';
|
5
|
+
import qs from 'qs';
|
6
|
+
|
7
|
+
import {Tabs} from '@gravity-ui/uikit';
|
3
8
|
|
4
9
|
import type {AdditionalClusterProps, AdditionalVersionsProps} from '../../types/additionalProps';
|
5
|
-
import
|
10
|
+
import type {AdditionalNodesInfo} from '../../utils/nodes';
|
11
|
+
import routes from '../../routes';
|
6
12
|
|
7
|
-
import {
|
13
|
+
import {setHeader} from '../../store/reducers/header';
|
14
|
+
import {getClusterInfo} from '../../store/reducers/cluster/cluster';
|
15
|
+
import {getClusterNodes} from '../../store/reducers/clusterNodes/clusterNodes';
|
16
|
+
import {parseNodesToVersionsValues, parseVersionsToVersionToColorMap} from '../../utils/versions';
|
17
|
+
import {useAutofetcher, useTypedSelector} from '../../utils/hooks';
|
18
|
+
|
19
|
+
import {InternalLink} from '../../components/InternalLink';
|
8
20
|
import Tenants from '../Tenants/Tenants';
|
9
21
|
import {Nodes} from '../Nodes/Nodes';
|
10
22
|
import Storage from '../Storage/Storage';
|
23
|
+
import {Versions} from '../Versions/Versions';
|
24
|
+
|
25
|
+
import {ClusterInfo} from './ClusterInfo/ClusterInfo';
|
26
|
+
import {ClusterTab, clusterTabs, clusterTabsIds, getClusterPath} from './utils';
|
11
27
|
|
12
28
|
import './Cluster.scss';
|
13
29
|
|
14
30
|
const b = cn('cluster');
|
15
31
|
|
16
32
|
interface ClusterProps {
|
17
|
-
additionalTenantsInfo?:
|
18
|
-
additionalNodesInfo?:
|
33
|
+
additionalTenantsInfo?: unknown;
|
34
|
+
additionalNodesInfo?: AdditionalNodesInfo;
|
19
35
|
additionalClusterProps?: AdditionalClusterProps;
|
20
36
|
additionalVersionsProps?: AdditionalVersionsProps;
|
21
37
|
}
|
22
38
|
|
23
39
|
function Cluster({
|
40
|
+
additionalClusterProps,
|
24
41
|
additionalTenantsInfo,
|
25
42
|
additionalNodesInfo,
|
26
|
-
additionalClusterProps,
|
27
43
|
additionalVersionsProps,
|
28
44
|
}: ClusterProps) {
|
29
|
-
const
|
30
|
-
|
31
|
-
const
|
45
|
+
const dispatch = useDispatch();
|
46
|
+
|
47
|
+
const match = useRouteMatch<{activeTab: string}>(routes.cluster);
|
48
|
+
const {activeTab = clusterTabsIds.tenants} = match?.params || {};
|
49
|
+
|
50
|
+
const location = useLocation();
|
51
|
+
const queryParams = qs.parse(location.search, {
|
52
|
+
ignoreQueryPrefix: true,
|
53
|
+
});
|
54
|
+
const {clusterName} = queryParams;
|
55
|
+
|
56
|
+
const {
|
57
|
+
data: cluster = {},
|
58
|
+
loading: clusterLoading,
|
59
|
+
wasLoaded: clusterWasLoaded,
|
60
|
+
error: clusterError,
|
61
|
+
} = useTypedSelector((state) => state.cluster);
|
62
|
+
const {
|
63
|
+
nodes,
|
64
|
+
loading: nodesLoading,
|
65
|
+
wasLoaded: nodesWasLoaded,
|
66
|
+
} = useTypedSelector((state) => state.clusterNodes);
|
67
|
+
|
68
|
+
const {Name} = cluster;
|
69
|
+
|
70
|
+
const infoLoading = (clusterLoading && !clusterWasLoaded) || (nodesLoading && !nodesWasLoaded);
|
71
|
+
|
72
|
+
useEffect(() => {
|
73
|
+
dispatch(getClusterNodes());
|
74
|
+
}, [dispatch]);
|
75
|
+
|
76
|
+
useAutofetcher(
|
77
|
+
() => dispatch(getClusterInfo(clusterName ? String(clusterName) : undefined)),
|
78
|
+
[dispatch, clusterName],
|
79
|
+
true,
|
80
|
+
);
|
81
|
+
|
82
|
+
useEffect(() => {
|
83
|
+
dispatch(
|
84
|
+
setHeader([
|
85
|
+
{
|
86
|
+
text: Name || 'Cluster',
|
87
|
+
link: getClusterPath(),
|
88
|
+
},
|
89
|
+
]),
|
90
|
+
);
|
91
|
+
}, [dispatch, Name]);
|
92
|
+
|
93
|
+
const versionToColor = useMemo(() => {
|
94
|
+
if (additionalVersionsProps?.getVersionToColorMap) {
|
95
|
+
return additionalVersionsProps?.getVersionToColorMap();
|
96
|
+
}
|
97
|
+
return parseVersionsToVersionToColorMap(cluster?.Versions);
|
98
|
+
}, [additionalVersionsProps, cluster]);
|
99
|
+
|
100
|
+
const versionsValues = useMemo(() => {
|
101
|
+
return parseNodesToVersionsValues(nodes, versionToColor);
|
102
|
+
}, [nodes, versionToColor]);
|
103
|
+
|
104
|
+
const renderTab = () => {
|
32
105
|
switch (activeTab) {
|
33
|
-
case
|
106
|
+
case clusterTabsIds.tenants: {
|
34
107
|
return <Tenants additionalTenantsInfo={additionalTenantsInfo} />;
|
35
108
|
}
|
36
|
-
case
|
109
|
+
case clusterTabsIds.nodes: {
|
37
110
|
return <Nodes additionalNodesInfo={additionalNodesInfo} />;
|
38
111
|
}
|
39
|
-
case
|
112
|
+
case clusterTabsIds.storage: {
|
40
113
|
return <Storage additionalNodesInfo={additionalNodesInfo} />;
|
41
114
|
}
|
42
|
-
case
|
43
|
-
return
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
115
|
+
case clusterTabsIds.versions: {
|
116
|
+
return <Versions versionToColor={versionToColor} />;
|
117
|
+
}
|
118
|
+
default: {
|
119
|
+
return null;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
};
|
123
|
+
|
124
|
+
const getTabEntityCount = (tabId: ClusterTab) => {
|
125
|
+
switch (tabId) {
|
126
|
+
case clusterTabsIds.tenants: {
|
127
|
+
return cluster?.Tenants;
|
128
|
+
}
|
129
|
+
case clusterTabsIds.nodes: {
|
130
|
+
return cluster?.NodesTotal;
|
49
131
|
}
|
50
132
|
default: {
|
51
133
|
return null;
|
@@ -53,7 +135,41 @@ function Cluster({
|
|
53
135
|
}
|
54
136
|
};
|
55
137
|
|
56
|
-
return
|
138
|
+
return (
|
139
|
+
<div className={b()}>
|
140
|
+
<ClusterInfo
|
141
|
+
cluster={cluster}
|
142
|
+
versionsValues={versionsValues}
|
143
|
+
loading={infoLoading}
|
144
|
+
error={clusterError}
|
145
|
+
additionalClusterProps={additionalClusterProps}
|
146
|
+
/>
|
147
|
+
|
148
|
+
<div>
|
149
|
+
<Tabs
|
150
|
+
size="l"
|
151
|
+
allowNotSelected={true}
|
152
|
+
activeTab={activeTab as string}
|
153
|
+
items={clusterTabs.map((item) => {
|
154
|
+
return {
|
155
|
+
...item,
|
156
|
+
title: `${item.title} ${getTabEntityCount(item.id) || ''}`,
|
157
|
+
};
|
158
|
+
})}
|
159
|
+
wrapTo={({id}, node) => {
|
160
|
+
const path = getClusterPath(id as ClusterTab, queryParams);
|
161
|
+
return (
|
162
|
+
<InternalLink to={path} key={id}>
|
163
|
+
{node}
|
164
|
+
</InternalLink>
|
165
|
+
);
|
166
|
+
}}
|
167
|
+
/>
|
168
|
+
</div>
|
169
|
+
|
170
|
+
<div className={b('content')}>{renderTab()}</div>
|
171
|
+
</div>
|
172
|
+
);
|
57
173
|
}
|
58
174
|
|
59
175
|
export default Cluster;
|
@@ -1,31 +1,48 @@
|
|
1
1
|
@import '../../../styles/mixins';
|
2
2
|
|
3
3
|
.cluster-info {
|
4
|
-
|
5
|
-
$progress_width: 100%;
|
4
|
+
width: 100%;
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
flex-direction: column;
|
6
|
+
&__header {
|
7
|
+
display: flex;
|
10
8
|
|
11
|
-
|
9
|
+
width: fit-content;
|
10
|
+
margin-bottom: 20px;
|
12
11
|
|
13
|
-
|
14
|
-
line-height: var(--yc-text-body-2-line-height);
|
12
|
+
cursor: pointer;
|
15
13
|
|
16
|
-
|
17
|
-
|
14
|
+
&__expand-button {
|
15
|
+
margin-left: 6px;
|
18
16
|
|
19
|
-
|
20
|
-
|
17
|
+
&_rotate {
|
18
|
+
transform: rotate(180deg);
|
19
|
+
}
|
20
|
+
}
|
21
21
|
}
|
22
22
|
|
23
|
-
&__title {
|
24
|
-
|
25
|
-
|
23
|
+
&__title .entity-status__name {
|
24
|
+
font-size: var(--yc-text-header-1-font-size);
|
25
|
+
font-weight: var(--yc-text-header-font-weight);
|
26
|
+
line-height: var(--yc-text-header-1-line-height);
|
27
|
+
}
|
28
|
+
|
29
|
+
&__title-skeleton {
|
30
|
+
width: 20%;
|
31
|
+
min-width: 200px;
|
32
|
+
height: var(--yc-text-header-1-line-height);
|
33
|
+
}
|
26
34
|
|
27
|
-
|
35
|
+
&__error {
|
36
|
+
font-size: var(--yc-text-body-2-font-size);
|
37
|
+
line-height: var(--yc-text-body-2-line-height);
|
38
|
+
}
|
39
|
+
|
40
|
+
&__info {
|
28
41
|
margin-bottom: 20px;
|
42
|
+
|
43
|
+
&_hidden {
|
44
|
+
display: none;
|
45
|
+
}
|
29
46
|
}
|
30
47
|
|
31
48
|
&__metric-field {
|
@@ -38,7 +55,7 @@
|
|
38
55
|
align-items: center;
|
39
56
|
|
40
57
|
& .tablet {
|
41
|
-
margin-
|
58
|
+
margin-top: 2px;
|
42
59
|
}
|
43
60
|
}
|
44
61
|
|