ydb-embedded-ui 4.4.2 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/components/ContentWithPopup/ContentWithPopup.tsx +51 -0
  3. package/dist/components/ExternalLinkWithIcon/ExternalLinkWithIcon.scss +7 -0
  4. package/dist/components/ExternalLinkWithIcon/ExternalLinkWithIcon.tsx +24 -0
  5. package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +2 -2
  6. package/dist/components/PoolBar/PoolBar.scss +6 -1
  7. package/dist/components/PoolBar/PoolBar.tsx +39 -0
  8. package/dist/components/PoolsGraph/PoolsGraph.scss +1 -1
  9. package/dist/components/PoolsGraph/PoolsGraph.tsx +23 -0
  10. package/dist/components/Tablet/Tablet.scss +4 -1
  11. package/dist/components/Tablet/Tablet.tsx +11 -35
  12. package/dist/components/{Tooltips/NodeEndpointsTooltip/NodeEndpointsTooltip.scss → TooltipsContent/NodeEndpointsTooltipContent/NodeEndpointsTooltipContent.scss} +1 -1
  13. package/dist/components/{Tooltips/NodeEndpointsTooltip/NodeEndpointsTooltip.tsx → TooltipsContent/NodeEndpointsTooltipContent/NodeEndpointsTooltipContent.tsx} +3 -3
  14. package/dist/components/TooltipsContent/PoolTooltipContent/PoolTooltipContent.tsx +24 -0
  15. package/dist/components/TooltipsContent/TabletTooltipContent/TabletTooltipContent.tsx +34 -0
  16. package/dist/components/TooltipsContent/index.ts +3 -0
  17. package/dist/containers/Cluster/Cluster.tsx +14 -10
  18. package/dist/containers/{ClusterInfo → Cluster/ClusterInfo}/ClusterInfo.scss +8 -40
  19. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.tsx +223 -0
  20. package/dist/containers/{ClusterInfo → Cluster/ClusterInfo}/utils.ts +1 -1
  21. package/dist/containers/Cluster/VersionsBar/VersionsBar.scss +27 -0
  22. package/dist/containers/Cluster/VersionsBar/VersionsBar.tsx +33 -0
  23. package/dist/containers/Header/Header.tsx +3 -6
  24. package/dist/containers/Nodes/Nodes.tsx +0 -11
  25. package/dist/containers/Nodes/getNodesColumns.tsx +3 -20
  26. package/dist/containers/Tablets/Tablets.tsx +1 -17
  27. package/dist/containers/TabletsFilters/TabletsFilters.js +2 -14
  28. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +2 -12
  29. package/dist/containers/Tenants/Tenants.js +3 -17
  30. package/dist/containers/Versions/NodesTable/NodesTable.tsx +4 -34
  31. package/dist/types/additionalProps.ts +11 -0
  32. package/dist/utils/tooltip.js +8 -80
  33. package/package.json +1 -1
  34. package/dist/components/PoolBar/PoolBar.js +0 -52
  35. package/dist/components/PoolsGraph/PoolsGraph.js +0 -33
  36. package/dist/containers/ClusterInfo/ClusterInfo.tsx +0 -207
@@ -0,0 +1,223 @@
1
+ import {useCallback, useEffect, useMemo} from 'react';
2
+ import {useDispatch} from 'react-redux';
3
+ import {useLocation} from 'react-router';
4
+ import block from 'bem-cn-lite';
5
+ import qs from 'qs';
6
+
7
+ import EntityStatus from '../../../components/EntityStatus/EntityStatus';
8
+ import ProgressViewer from '../../../components/ProgressViewer/ProgressViewer';
9
+ import InfoViewer, {InfoViewerItem} from '../../../components/InfoViewer/InfoViewer';
10
+ import {Tags} from '../../../components/Tags';
11
+ import {Tablet} from '../../../components/Tablet';
12
+ import {Loader} from '../../../components/Loader';
13
+ import {ResponseError} from '../../../components/Errors/ResponseError';
14
+ import {ExternalLinkWithIcon} from '../../../components/ExternalLinkWithIcon/ExternalLinkWithIcon';
15
+
16
+ import type {
17
+ AdditionalClusterProps,
18
+ AdditionalVersionsProps,
19
+ ClusterLink,
20
+ } from '../../../types/additionalProps';
21
+ import type {VersionValue} from '../../../types/versions';
22
+ import type {TClusterInfo} from '../../../types/api/cluster';
23
+ import {getClusterNodes} from '../../../store/reducers/clusterNodes/clusterNodes';
24
+ import {getClusterInfo} from '../../../store/reducers/cluster/cluster';
25
+ import {backend, customBackend} from '../../../store';
26
+ import {setHeader} from '../../../store/reducers/header';
27
+ import {formatStorageValues} from '../../../utils';
28
+ import {useAutofetcher, useTypedSelector} from '../../../utils/hooks';
29
+ import {
30
+ parseVersionsToVersionToColorMap,
31
+ parseNodesToVersionsValues,
32
+ } from '../../../utils/versions';
33
+ import routes, {CLUSTER_PAGES, createHref} from '../../../routes';
34
+
35
+ import {Versions} from '../../Versions/Versions';
36
+ import {VersionsBar} from '../VersionsBar/VersionsBar';
37
+
38
+ import {compareTablets} from './utils';
39
+
40
+ import './ClusterInfo.scss';
41
+
42
+ const b = block('cluster-info');
43
+
44
+ const getInfo = (
45
+ cluster: TClusterInfo,
46
+ versionsValues: VersionValue[],
47
+ additionalInfo: InfoViewerItem[],
48
+ links: ClusterLink[],
49
+ ) => {
50
+ const info: InfoViewerItem[] = [];
51
+
52
+ if (cluster.DataCenters) {
53
+ info.push({
54
+ label: 'DC',
55
+ value: <Tags tags={cluster.DataCenters} />,
56
+ });
57
+ }
58
+
59
+ if (cluster.SystemTablets) {
60
+ info.push({
61
+ label: 'Tablets',
62
+ value: (
63
+ <div className={b('system-tablets')}>
64
+ {cluster.SystemTablets.sort(compareTablets).map((tablet, tabletIndex) => (
65
+ <Tablet key={tabletIndex} tablet={tablet} />
66
+ ))}
67
+ </div>
68
+ ),
69
+ });
70
+ }
71
+
72
+ info.push(
73
+ {
74
+ label: 'Nodes',
75
+ value: (
76
+ <ProgressViewer
77
+ className={b('metric-field')}
78
+ value={cluster?.NodesAlive}
79
+ capacity={cluster?.NodesTotal}
80
+ />
81
+ ),
82
+ },
83
+ {
84
+ label: 'Load',
85
+ value: (
86
+ <ProgressViewer
87
+ className={b('metric-field')}
88
+ value={cluster?.LoadAverage}
89
+ capacity={cluster?.NumberOfCpus}
90
+ />
91
+ ),
92
+ },
93
+ {
94
+ label: 'Storage',
95
+ value: (
96
+ <ProgressViewer
97
+ className={b('metric-field')}
98
+ value={cluster?.StorageUsed}
99
+ capacity={cluster?.StorageTotal}
100
+ formatValues={formatStorageValues}
101
+ />
102
+ ),
103
+ },
104
+ ...additionalInfo,
105
+ {
106
+ label: 'Links',
107
+ value: (
108
+ <div className={b('links')}>
109
+ {links.map(({title, url}) => (
110
+ <ExternalLinkWithIcon key={title} title={title} url={url} />
111
+ ))}
112
+ </div>
113
+ ),
114
+ },
115
+ {
116
+ label: 'Versions',
117
+ value: <VersionsBar versionsValues={versionsValues} />,
118
+ },
119
+ );
120
+
121
+ return info;
122
+ };
123
+
124
+ interface ClusterInfoProps {
125
+ clusterTitle?: string;
126
+ additionalClusterProps?: AdditionalClusterProps;
127
+ additionalVersionsProps?: AdditionalVersionsProps;
128
+ }
129
+
130
+ export const ClusterInfo = ({
131
+ clusterTitle,
132
+ additionalClusterProps = {},
133
+ additionalVersionsProps = {},
134
+ }: ClusterInfoProps) => {
135
+ const dispatch = useDispatch();
136
+ const location = useLocation();
137
+
138
+ const queryParams = qs.parse(location.search, {
139
+ ignoreQueryPrefix: true,
140
+ });
141
+ const {clusterName} = queryParams;
142
+
143
+ const {
144
+ data: cluster = {},
145
+ loading,
146
+ wasLoaded,
147
+ error,
148
+ } = useTypedSelector((state) => state.cluster);
149
+ const {
150
+ nodes,
151
+ loading: nodesLoading,
152
+ wasLoaded: nodesWasLoaded,
153
+ error: nodesError,
154
+ } = useTypedSelector((state) => state.clusterNodes);
155
+ const singleClusterMode = useTypedSelector((state) => state.singleClusterMode);
156
+
157
+ useEffect(() => {
158
+ dispatch(
159
+ setHeader([
160
+ {
161
+ text: CLUSTER_PAGES.cluster.title,
162
+ link: createHref(routes.cluster, {activeTab: CLUSTER_PAGES.cluster.id}),
163
+ },
164
+ ]),
165
+ );
166
+ }, [dispatch]);
167
+
168
+ const fetchData = useCallback(() => {
169
+ dispatch(getClusterInfo(clusterName ? String(clusterName) : undefined));
170
+ dispatch(getClusterNodes());
171
+ }, [dispatch, clusterName]);
172
+
173
+ useAutofetcher(fetchData, [fetchData], true);
174
+
175
+ const versionToColor = useMemo(() => {
176
+ if (additionalVersionsProps?.getVersionToColorMap) {
177
+ return additionalVersionsProps.getVersionToColorMap();
178
+ }
179
+ return parseVersionsToVersionToColorMap(cluster.Versions);
180
+ }, [additionalVersionsProps, cluster]);
181
+
182
+ const versionsValues = useMemo(() => {
183
+ return parseNodesToVersionsValues(nodes, versionToColor);
184
+ }, [nodes, versionToColor]);
185
+
186
+ if ((loading && !wasLoaded) || (nodesLoading && !nodesWasLoaded)) {
187
+ return <Loader size="l" />;
188
+ }
189
+
190
+ if (error || nodesError) {
191
+ return <ResponseError error={error || nodesError} />;
192
+ }
193
+
194
+ let internalLink = backend + '/internal';
195
+
196
+ if (singleClusterMode && !customBackend) {
197
+ internalLink = `/internal`;
198
+ }
199
+
200
+ const {info = [], links = []} = additionalClusterProps;
201
+
202
+ const clusterInfo = getInfo(cluster, versionsValues, info, [
203
+ {title: 'Internal Viewer', url: internalLink},
204
+ ...links,
205
+ ]);
206
+
207
+ return (
208
+ <div className={b()}>
209
+ <div className={b('header')}>
210
+ <div className={b('title')}>
211
+ <EntityStatus
212
+ size="m"
213
+ status={cluster.Overall}
214
+ name={clusterTitle ?? cluster.Name ?? 'Unknown cluster'}
215
+ />
216
+ </div>
217
+ <InfoViewer dots={true} info={clusterInfo} />
218
+ </div>
219
+
220
+ <Versions nodes={nodes} versionToColor={versionToColor} />
221
+ </div>
222
+ );
223
+ };
@@ -1,4 +1,4 @@
1
- import {TTabletStateInfo, EType} from '../../types/api/tablet';
1
+ import {TTabletStateInfo, EType} from '../../../types/api/tablet';
2
2
 
3
3
  export const compareTablets = (tablet1: TTabletStateInfo, tablet2: TTabletStateInfo) => {
4
4
  if (tablet1.Type === EType.TxAllocator) {
@@ -0,0 +1,27 @@
1
+ .ydb-cluster-versions-bar {
2
+ display: flex;
3
+ flex-direction: column;
4
+
5
+ width: 600px;
6
+
7
+ & .yc-progress {
8
+ width: 100%;
9
+ }
10
+
11
+ &__versions {
12
+ display: flex;
13
+ flex-flow: row wrap;
14
+
15
+ margin-top: 6px;
16
+ }
17
+
18
+ &__version-title {
19
+ margin-left: 3px;
20
+
21
+ white-space: nowrap;
22
+ }
23
+
24
+ & .yc-progress__stack {
25
+ cursor: pointer;
26
+ }
27
+ }
@@ -0,0 +1,33 @@
1
+ import block from 'bem-cn-lite';
2
+
3
+ import {Progress} from '@gravity-ui/uikit';
4
+
5
+ import type {VersionValue} from '../../../types/versions';
6
+
7
+ import './VersionsBar.scss';
8
+
9
+ const b = block('ydb-cluster-versions-bar');
10
+
11
+ interface VersionsBarProps {
12
+ versionsValues?: VersionValue[];
13
+ }
14
+
15
+ export const VersionsBar = ({versionsValues = []}: VersionsBarProps) => {
16
+ return (
17
+ <div className={b()}>
18
+ <Progress value={100} stack={versionsValues} view="thin" />
19
+ <div className={b('versions')}>
20
+ {versionsValues.map((item, index) => (
21
+ <div
22
+ className={b('version-title')}
23
+ style={{color: item.color}}
24
+ key={item.version}
25
+ title={item.version}
26
+ >
27
+ {`${item.version}${index === versionsValues.length - 1 ? '' : ','}`}
28
+ </div>
29
+ ))}
30
+ </div>
31
+ </div>
32
+ );
33
+ };
@@ -2,10 +2,10 @@ import React, {useEffect} from 'react';
2
2
  import {useDispatch} from 'react-redux';
3
3
  import cn from 'bem-cn-lite';
4
4
  import {useHistory} from 'react-router';
5
- import {Breadcrumbs, BreadcrumbsItem, Link} from '@gravity-ui/uikit';
5
+ import {Breadcrumbs, BreadcrumbsItem} from '@gravity-ui/uikit';
6
6
 
7
7
  import Divider from '../../components/Divider/Divider';
8
- import {Icon} from '../../components/Icon';
8
+ import {ExternalLinkWithIcon} from '../../components/ExternalLinkWithIcon/ExternalLinkWithIcon';
9
9
 
10
10
  import {backend, customBackend} from '../../store';
11
11
  import {getHostInfo} from '../../store/reducers/host';
@@ -72,10 +72,7 @@ function Header({clusterName}: HeaderProps) {
72
72
  </div>
73
73
 
74
74
  <div className={b('cluster-name-wrapper')}>
75
- <Link href={link} target="_blank">
76
- Internal viewer{' '}
77
- <Icon name="external" viewBox={'0 0 16 16'} width={16} height={16} />
78
- </Link>
75
+ <ExternalLinkWithIcon title={'Internal Viewer'} url={link} />
79
76
  {clusterNameFinal && (
80
77
  <React.Fragment>
81
78
  <div className={b('divider')}>
@@ -31,7 +31,6 @@ import {
31
31
  getComputeNodes,
32
32
  } from '../../store/reducers/nodes';
33
33
  import {changeFilter, ProblemFilterValues} from '../../store/reducers/settings/settings';
34
- import {hideTooltip, showTooltip} from '../../store/reducers/tooltip';
35
34
 
36
35
  import {isDatabaseEntityType} from '../Tenant/utils/schema';
37
36
 
@@ -129,18 +128,8 @@ export const Nodes = ({path, type, className, additionalNodesInfo = {}}: NodesPr
129
128
  );
130
129
  };
131
130
 
132
- const onShowTooltip = (...args: Parameters<typeof showTooltip>) => {
133
- dispatch(showTooltip(...args));
134
- };
135
-
136
- const onHideTooltip = () => {
137
- dispatch(hideTooltip());
138
- };
139
-
140
131
  const renderTable = () => {
141
132
  const columns = getNodesColumns({
142
- showTooltip: onShowTooltip,
143
- hideTooltip: onHideTooltip,
144
133
  getNodeRef: additionalNodesInfo.getNodeRef,
145
134
  });
146
135
 
@@ -1,7 +1,7 @@
1
1
  import DataTable, {Column} from '@gravity-ui/react-data-table';
2
2
  import {Popover} from '@gravity-ui/uikit';
3
3
 
4
- import PoolsGraph from '../../components/PoolsGraph/PoolsGraph';
4
+ import {PoolsGraph} from '../../components/PoolsGraph/PoolsGraph';
5
5
  import ProgressViewer from '../../components/ProgressViewer/ProgressViewer';
6
6
  import {TabletsStatistic} from '../../components/TabletsStatistic';
7
7
  import {NodeHostWrapper} from '../../components/NodeHostWrapper/NodeHostWrapper';
@@ -10,21 +10,13 @@ import type {NodeAddress} from '../../utils/nodes';
10
10
  import {formatBytesToGigabyte} from '../../utils/index';
11
11
 
12
12
  import type {INodesPreparedEntity} from '../../types/store/nodes';
13
- import {showTooltip as externalShowTooltip} from '../../store/reducers/tooltip';
14
13
 
15
14
  interface GetNodesColumnsProps {
16
- showTooltip: (...args: Parameters<typeof externalShowTooltip>) => void;
17
- hideTooltip: VoidFunction;
18
15
  tabletsPath?: string;
19
16
  getNodeRef?: (node?: NodeAddress) => string;
20
17
  }
21
18
 
22
- export function getNodesColumns({
23
- showTooltip,
24
- hideTooltip,
25
- tabletsPath,
26
- getNodeRef,
27
- }: GetNodesColumnsProps) {
19
+ export function getNodesColumns({tabletsPath, getNodeRef}: GetNodesColumnsProps) {
28
20
  const columns: Column<INodesPreparedEntity>[] = [
29
21
  {
30
22
  name: 'NodeId',
@@ -96,16 +88,7 @@ export function getNodesColumns({
96
88
  }
97
89
  }, 0),
98
90
  defaultOrder: DataTable.DESCENDING,
99
- render: ({row}) =>
100
- row.PoolStats ? (
101
- <PoolsGraph
102
- onMouseEnter={showTooltip}
103
- onMouseLeave={hideTooltip}
104
- pools={row.PoolStats}
105
- />
106
- ) : (
107
- '—'
108
- ),
91
+ render: ({row}) => (row.PoolStats ? <PoolsGraph pools={row.PoolStats} /> : '—'),
109
92
  align: DataTable.LEFT,
110
93
  width: '120px',
111
94
  },
@@ -12,7 +12,6 @@ import {Loader} from '../../components/Loader';
12
12
  import {useAutofetcher, useTypedSelector} from '../../utils/hooks';
13
13
  import {ETabletState, EType, TTabletStateInfo} from '../../types/api/tablet';
14
14
 
15
- import {showTooltip, hideTooltip} from '../../store/reducers/tooltip';
16
15
  import {
17
16
  getTabletsInfo,
18
17
  clearWasLoadingFlag,
@@ -89,23 +88,8 @@ export const Tablets = ({path, nodeId, className}: TabletsProps) => {
89
88
  dispatch(setTypeFilter(value as EType[]));
90
89
  };
91
90
 
92
- const onShowTooltip = (...args: Parameters<typeof showTooltip>) => {
93
- dispatch(showTooltip(...args));
94
- };
95
-
96
- const onHideTooltip = () => {
97
- dispatch(hideTooltip());
98
- };
99
-
100
91
  const renderTablet = (tabletIndex: number) => {
101
- return (
102
- <Tablet
103
- onMouseLeave={onHideTooltip}
104
- onMouseEnter={onShowTooltip}
105
- tablet={tabletsToRender[tabletIndex]}
106
- key={tabletIndex}
107
- />
108
- );
92
+ return <Tablet tablet={tabletsToRender[tabletIndex]} key={tabletIndex} />;
109
93
  };
110
94
 
111
95
  const renderContent = () => {
@@ -12,7 +12,6 @@ import {Tablet} from '../../components/Tablet';
12
12
  import {AccessDenied} from '../../components/Errors/403';
13
13
 
14
14
  import {tabletColorToTabletState, tabletStates} from '../../utils/tablet';
15
- import {showTooltip, hideTooltip} from '../../store/reducers/tooltip';
16
15
  import {
17
16
  getTabletsInfo,
18
17
  clearWasLoadingFlag,
@@ -30,8 +29,6 @@ class TabletsFilters extends React.Component {
30
29
  static propTypes = {
31
30
  wasLoaded: PropTypes.bool,
32
31
  loading: PropTypes.bool,
33
- showTooltip: PropTypes.func,
34
- hideTooltip: PropTypes.func,
35
32
  getTabletsInfo: PropTypes.func,
36
33
  timeoutForRequest: PropTypes.number,
37
34
  path: PropTypes.string,
@@ -141,17 +138,10 @@ class TabletsFilters extends React.Component {
141
138
  };
142
139
 
143
140
  renderTablet = (index, key) => {
144
- const {filteredTablets, hideTooltip, showTooltip, size} = this.props;
141
+ const {filteredTablets, size} = this.props;
145
142
 
146
143
  return (
147
- <Tablet
148
- onMouseLeave={hideTooltip}
149
- onMouseEnter={showTooltip}
150
- tablet={filteredTablets[index]}
151
- key={key}
152
- size={size}
153
- className={b('tablet')}
154
- />
144
+ <Tablet tablet={filteredTablets[index]} key={key} size={size} className={b('tablet')} />
155
145
  );
156
146
  };
157
147
 
@@ -333,8 +323,6 @@ const mapStateToProps = (state) => {
333
323
 
334
324
  const mapDispatchToProps = {
335
325
  getTabletsInfo,
336
- hideTooltip,
337
- showTooltip,
338
326
  clearWasLoadingFlag,
339
327
  setStateFilter,
340
328
  setTypeFilter,
@@ -9,7 +9,6 @@ import InfoViewer from '../../../../components/InfoViewer/InfoViewer';
9
9
  import PoolUsage from '../../../../components/PoolUsage/PoolUsage';
10
10
  import {Tablet} from '../../../../components/Tablet';
11
11
 
12
- import {hideTooltip, showTooltip} from '../../../../store/reducers/tooltip';
13
12
  import {getTenantInfo} from '../../../../store/reducers/tenant';
14
13
 
15
14
  import {formatCPU} from '../../../../utils';
@@ -44,8 +43,6 @@ class TenantOverview extends React.Component {
44
43
  loading: PropTypes.bool,
45
44
  autorefresh: PropTypes.bool,
46
45
  tenant: PropTypes.object,
47
- hideTooltip: PropTypes.func,
48
- showTooltip: PropTypes.func,
49
46
  systemTablets: PropTypes.array,
50
47
  additionalTenantInfo: PropTypes.func,
51
48
  tenantName: PropTypes.string,
@@ -102,7 +99,7 @@ class TenantOverview extends React.Component {
102
99
  };
103
100
 
104
101
  render() {
105
- const {tenant, hideTooltip, showTooltip, loading} = this.props;
102
+ const {tenant, loading} = this.props;
106
103
  const {
107
104
  Metrics = {},
108
105
  PoolStats,
@@ -162,12 +159,7 @@ class TenantOverview extends React.Component {
162
159
  <div className={b('system-tablets')}>
163
160
  {SystemTablets &&
164
161
  SystemTablets.map((tablet, tabletIndex) => (
165
- <Tablet
166
- onMouseEnter={showTooltip}
167
- onMouseLeave={hideTooltip}
168
- key={tabletIndex}
169
- tablet={tablet}
170
- />
162
+ <Tablet key={tabletIndex} tablet={tablet} />
171
163
  ))}
172
164
  </div>
173
165
  <div className={b('common-info')}>
@@ -211,8 +203,6 @@ function mapStateToProps(state) {
211
203
  }
212
204
 
213
205
  const mapDispatchToProps = {
214
- hideTooltip,
215
- showTooltip,
216
206
  getTenantInfo,
217
207
  };
218
208
 
@@ -9,7 +9,7 @@ import DataTable from '@gravity-ui/react-data-table';
9
9
  import {Loader, TextInput, Button} from '@gravity-ui/uikit';
10
10
 
11
11
  import EntityStatus from '../../components/EntityStatus/EntityStatus';
12
- import PoolsGraph from '../../components/PoolsGraph/PoolsGraph';
12
+ import {PoolsGraph} from '../../components/PoolsGraph/PoolsGraph';
13
13
  import {TabletsStatistic} from '../../components/TabletsStatistic';
14
14
  import {ProblemFilter} from '../../components/ProblemFilter';
15
15
  import {Illustration} from '../../components/Illustration';
@@ -17,7 +17,6 @@ import {AutoFetcher} from '../../utils/autofetcher';
17
17
 
18
18
  import routes, {CLUSTER_PAGES, createHref} from '../../routes';
19
19
  import {formatCPU, formatBytesToGigabyte, formatNumber} from '../../utils';
20
- import {hideTooltip, showTooltip} from '../../store/reducers/tooltip';
21
20
  import {withSearch} from '../../HOCS';
22
21
  import {DEFAULT_TABLE_SETTINGS, TENANT_INITIAL_TAB_KEY} from '../../utils/constants';
23
22
  import {getTenantsInfo} from '../../store/reducers/tenants/tenants';
@@ -50,8 +49,6 @@ class Tenants extends React.Component {
50
49
  error: PropTypes.bool,
51
50
  getTenantsInfo: PropTypes.func,
52
51
  tenants: PropTypes.array,
53
- showTooltip: PropTypes.func,
54
- hideTooltip: PropTypes.func,
55
52
  searchQuery: PropTypes.string,
56
53
  handleSearchQuery: PropTypes.func,
57
54
  setHeader: PropTypes.func,
@@ -121,8 +118,6 @@ class Tenants extends React.Component {
121
118
  const {
122
119
  tenants = [],
123
120
  searchQuery,
124
- showTooltip,
125
- hideTooltip,
126
121
  filter,
127
122
  handleSearchQuery,
128
123
  additionalTenantsInfo = {},
@@ -291,15 +286,8 @@ class Tenants extends React.Component {
291
286
  sortAccessor: ({PoolStats = []}) =>
292
287
  PoolStats.reduce((acc, item) => acc + item.Usage, 0),
293
288
  defaultOrder: DataTable.DESCENDING,
294
- align: DataTable.CENTER,
295
- render: ({value}) => (
296
- <PoolsGraph
297
- onMouseEnter={showTooltip}
298
- onMouseLeave={hideTooltip}
299
- rowInfo={value}
300
- pools={value}
301
- />
302
- ),
289
+ align: DataTable.LEFT,
290
+ render: ({value}) => <PoolsGraph rowInfo={value} pools={value} />,
303
291
  },
304
292
  {
305
293
  name: 'Tablets',
@@ -374,8 +362,6 @@ const mapStateToProps = (state) => {
374
362
 
375
363
  const mapDispatchToProps = {
376
364
  getTenantsInfo,
377
- hideTooltip,
378
- showTooltip,
379
365
  changeFilter,
380
366
  setHeader,
381
367
  };
@@ -1,26 +1,15 @@
1
- import {useDispatch} from 'react-redux';
2
-
3
1
  import DataTable, {Column} from '@gravity-ui/react-data-table';
4
2
 
5
3
  import type {PreparedClusterNode} from '../../../store/reducers/clusterNodes/types';
6
- import type {ShowTooltipFunction} from '../../../types/store/tooltip';
7
-
8
- import {hideTooltip, showTooltip} from '../../../store/reducers/tooltip';
9
4
  import {isUnavailableNode} from '../../../utils/nodes';
10
5
  import {formatBytes} from '../../../utils';
11
6
  import {getDefaultNodePath} from '../../Node/NodePages';
12
7
 
13
8
  import ProgressViewer from '../../../components/ProgressViewer/ProgressViewer';
14
- import PoolsGraph from '../../../components/PoolsGraph/PoolsGraph';
9
+ import {PoolsGraph} from '../../../components/PoolsGraph/PoolsGraph';
15
10
  import EntityStatus from '../../../components/EntityStatus/EntityStatus';
16
11
 
17
- const getColumns = ({
18
- onShowTooltip,
19
- onHideTooltip,
20
- }: {
21
- onShowTooltip: (...args: Parameters<ShowTooltipFunction>) => void;
22
- onHideTooltip: VoidFunction;
23
- }): Column<PreparedClusterNode>[] => [
12
+ const columns: Column<PreparedClusterNode>[] = [
24
13
  {
25
14
  name: 'NodeId',
26
15
  header: '#',
@@ -89,16 +78,7 @@ const getColumns = ({
89
78
  PoolStats.reduce((acc, item) => acc + (item.Usage || 0), 0),
90
79
  defaultOrder: DataTable.DESCENDING,
91
80
  width: '120px',
92
- render: ({row}) =>
93
- row.PoolStats ? (
94
- <PoolsGraph
95
- onMouseEnter={onShowTooltip}
96
- onMouseLeave={onHideTooltip}
97
- pools={row.PoolStats}
98
- />
99
- ) : (
100
- '—'
101
- ),
81
+ render: ({row}) => (row.PoolStats ? <PoolsGraph pools={row.PoolStats} /> : '—'),
102
82
  align: DataTable.LEFT,
103
83
  },
104
84
  {
@@ -127,21 +107,11 @@ interface NodesTableProps {
127
107
  }
128
108
 
129
109
  export const NodesTable = ({nodes}: NodesTableProps) => {
130
- const dispatch = useDispatch();
131
-
132
- const onShowTooltip = (...args: Parameters<ShowTooltipFunction>) => {
133
- dispatch(showTooltip(...args));
134
- };
135
-
136
- const onHideTooltip = () => {
137
- dispatch(hideTooltip());
138
- };
139
-
140
110
  return (
141
111
  <DataTable
142
112
  theme="yandex-cloud"
143
113
  data={nodes}
144
- columns={getColumns({onShowTooltip, onHideTooltip})}
114
+ columns={columns}
145
115
  settings={{
146
116
  displayIndices: false,
147
117
  }}
@@ -1,5 +1,16 @@
1
+ import type {InfoViewerItem} from '../components/InfoViewer';
1
2
  import type {VersionToColorMap} from './versions';
2
3
 
3
4
  export interface AdditionalVersionsProps {
4
5
  getVersionToColorMap?: () => VersionToColorMap;
5
6
  }
7
+
8
+ export interface ClusterLink {
9
+ title: string;
10
+ url: string;
11
+ }
12
+
13
+ export interface AdditionalClusterProps {
14
+ info?: InfoViewerItem[];
15
+ links?: ClusterLink[];
16
+ }