ydb-embedded-ui 4.4.2 → 4.5.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 +7 -0
- package/dist/components/ContentWithPopup/ContentWithPopup.tsx +51 -0
- package/dist/components/ExternalLinkWithIcon/ExternalLinkWithIcon.scss +7 -0
- package/dist/components/ExternalLinkWithIcon/ExternalLinkWithIcon.tsx +24 -0
- package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +2 -2
- package/dist/components/PoolBar/PoolBar.scss +6 -1
- package/dist/components/PoolBar/PoolBar.tsx +39 -0
- package/dist/components/PoolsGraph/PoolsGraph.scss +1 -1
- package/dist/components/PoolsGraph/PoolsGraph.tsx +23 -0
- package/dist/components/Tablet/Tablet.scss +4 -1
- package/dist/components/Tablet/Tablet.tsx +11 -35
- package/dist/components/{Tooltips/NodeEndpointsTooltip/NodeEndpointsTooltip.scss → TooltipsContent/NodeEndpointsTooltipContent/NodeEndpointsTooltipContent.scss} +1 -1
- package/dist/components/{Tooltips/NodeEndpointsTooltip/NodeEndpointsTooltip.tsx → TooltipsContent/NodeEndpointsTooltipContent/NodeEndpointsTooltipContent.tsx} +3 -3
- package/dist/components/TooltipsContent/PoolTooltipContent/PoolTooltipContent.tsx +24 -0
- package/dist/components/TooltipsContent/TabletTooltipContent/TabletTooltipContent.tsx +34 -0
- package/dist/components/TooltipsContent/index.ts +3 -0
- package/dist/containers/Cluster/Cluster.tsx +14 -10
- package/dist/containers/{ClusterInfo → Cluster/ClusterInfo}/ClusterInfo.scss +8 -40
- package/dist/containers/Cluster/ClusterInfo/ClusterInfo.tsx +223 -0
- package/dist/containers/{ClusterInfo → Cluster/ClusterInfo}/utils.ts +1 -1
- package/dist/containers/Cluster/VersionsBar/VersionsBar.scss +27 -0
- package/dist/containers/Cluster/VersionsBar/VersionsBar.tsx +33 -0
- package/dist/containers/Header/Header.tsx +3 -6
- package/dist/containers/Nodes/Nodes.tsx +0 -11
- package/dist/containers/Nodes/getNodesColumns.tsx +3 -20
- package/dist/containers/Tablets/Tablets.tsx +1 -17
- package/dist/containers/TabletsFilters/TabletsFilters.js +2 -14
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +2 -12
- package/dist/containers/Tenants/Tenants.js +3 -17
- package/dist/containers/Versions/NodesTable/NodesTable.tsx +4 -34
- package/dist/types/additionalProps.ts +11 -0
- package/dist/utils/tooltip.js +8 -80
- package/package.json +1 -1
- package/dist/components/PoolBar/PoolBar.js +0 -52
- package/dist/components/PoolsGraph/PoolsGraph.js +0 -33
- package/dist/containers/ClusterInfo/ClusterInfo.tsx +0 -207
package/dist/utils/tooltip.js
CHANGED
@@ -1,83 +1,11 @@
|
|
1
1
|
import cn from 'bem-cn-lite';
|
2
|
-
import {calcUptime} from '.';
|
3
2
|
import JSONTree from 'react-json-inspector';
|
4
3
|
|
5
|
-
import {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
const {data} = props;
|
11
|
-
const usage = (data.Usage * 100).toFixed(2);
|
12
|
-
return (
|
13
|
-
data && (
|
14
|
-
<div className={poolB()}>
|
15
|
-
<table>
|
16
|
-
<tbody>
|
17
|
-
<tr>
|
18
|
-
<td className={poolB('label')}>Pool</td>
|
19
|
-
<td>{data.Name}</td>
|
20
|
-
</tr>
|
21
|
-
<tr>
|
22
|
-
<td className={poolB('label')}>Usage</td>
|
23
|
-
<td>{usage} %</td>
|
24
|
-
</tr>
|
25
|
-
<tr>
|
26
|
-
<td className={poolB('label')}>Threads</td>
|
27
|
-
<td>{data.Threads}</td>
|
28
|
-
</tr>
|
29
|
-
</tbody>
|
30
|
-
</table>
|
31
|
-
</div>
|
32
|
-
)
|
33
|
-
);
|
34
|
-
};
|
35
|
-
|
36
|
-
const tabletB = cn('tablet-tooltip');
|
37
|
-
|
38
|
-
const TabletTooltip = (props) => {
|
39
|
-
const {data, additionalData} = props;
|
40
|
-
return (
|
41
|
-
data && (
|
42
|
-
<div className={tabletB()}>
|
43
|
-
<table>
|
44
|
-
<tbody>
|
45
|
-
<tr>
|
46
|
-
<td className={tabletB('label')}>Tablet</td>
|
47
|
-
<td className={tabletB('value')}>{data.TabletId}</td>
|
48
|
-
</tr>
|
49
|
-
<tr>
|
50
|
-
<td className={tabletB('label')}>NodeID</td>
|
51
|
-
<td className={tabletB('value')}>{data.NodeId}</td>
|
52
|
-
</tr>
|
53
|
-
<tr>
|
54
|
-
<td className={tabletB('label')}>State</td>
|
55
|
-
<td className={tabletB('value')}>{data.State}</td>
|
56
|
-
</tr>
|
57
|
-
<tr>
|
58
|
-
<td className={tabletB('label')}>Type</td>
|
59
|
-
<td className={tabletB('value')}>{data.Type}</td>
|
60
|
-
</tr>
|
61
|
-
<tr>
|
62
|
-
<td className={tabletB('label')}>Uptime</td>
|
63
|
-
<td className={tabletB('value')}>{calcUptime(data.ChangeTime)}</td>
|
64
|
-
</tr>
|
65
|
-
<tr>
|
66
|
-
<td className={tabletB('label')}>Generation</td>
|
67
|
-
<td className={tabletB('value')}>{data.Generation}</td>
|
68
|
-
</tr>
|
69
|
-
{additionalData && (
|
70
|
-
<tr>
|
71
|
-
<td className={tabletB('label')}>{additionalData.name}</td>
|
72
|
-
<td className={tabletB('value')}>{additionalData.value}</td>
|
73
|
-
</tr>
|
74
|
-
)}
|
75
|
-
</tbody>
|
76
|
-
</table>
|
77
|
-
</div>
|
78
|
-
)
|
79
|
-
);
|
80
|
-
};
|
4
|
+
import {
|
5
|
+
NodeEndpointsTooltipContent,
|
6
|
+
TabletTooltipContent,
|
7
|
+
PoolTooltipContent,
|
8
|
+
} from '../components/TooltipsContent';
|
81
9
|
|
82
10
|
const nodeB = cn('node-tootltip');
|
83
11
|
|
@@ -172,12 +100,12 @@ const jsonB = cn('json-tooltip');
|
|
172
100
|
|
173
101
|
export const tooltipTemplates = {
|
174
102
|
// eslint-disable-next-line react/display-name
|
175
|
-
pool: (data) => <
|
103
|
+
pool: (data) => <PoolTooltipContent data={data} />,
|
176
104
|
// eslint-disable-next-line react/display-name
|
177
|
-
tablet: (data
|
105
|
+
tablet: (data) => <TabletTooltipContent data={data} />,
|
178
106
|
// eslint-disable-next-line react/display-name
|
179
107
|
node: (data) => <NodeTooltip data={data} />,
|
180
|
-
nodeEndpoints: (data) => <
|
108
|
+
nodeEndpoints: (data) => <NodeEndpointsTooltipContent data={data} />,
|
181
109
|
// eslint-disable-next-line react/display-name
|
182
110
|
tabletsOverall: (data) => <TabletsOverallTooltip data={data} />,
|
183
111
|
// eslint-disable-next-line react/display-name
|
package/package.json
CHANGED
@@ -1,52 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import cn from 'bem-cn-lite';
|
3
|
-
import PropTypes from 'prop-types';
|
4
|
-
|
5
|
-
import './PoolBar.scss';
|
6
|
-
|
7
|
-
const b = cn('pool-bar');
|
8
|
-
|
9
|
-
const getBarType = (usage) => {
|
10
|
-
if (usage >= 75) {
|
11
|
-
return 'danger';
|
12
|
-
} else if (usage >= 50 && usage < 75) {
|
13
|
-
return 'warning';
|
14
|
-
} else {
|
15
|
-
return 'normal';
|
16
|
-
}
|
17
|
-
};
|
18
|
-
|
19
|
-
class PoolBar extends React.Component {
|
20
|
-
static propTypes = {
|
21
|
-
data: PropTypes.object,
|
22
|
-
onMouseEnter: PropTypes.func,
|
23
|
-
onMouseLeave: PropTypes.func,
|
24
|
-
};
|
25
|
-
|
26
|
-
bar = React.createRef();
|
27
|
-
|
28
|
-
_onBarHover = () => {
|
29
|
-
this.props.onMouseEnter(this.bar.current, this.props.data, 'pool');
|
30
|
-
};
|
31
|
-
_onBarLeave = () => {
|
32
|
-
this.props.onMouseLeave();
|
33
|
-
};
|
34
|
-
render() {
|
35
|
-
const {Usage: usage = 0} = this.props.data;
|
36
|
-
const usagePercents = Math.min(usage * 100, 100);
|
37
|
-
const type = getBarType(usagePercents);
|
38
|
-
|
39
|
-
return (
|
40
|
-
<div
|
41
|
-
ref={this.bar}
|
42
|
-
className={b({type})}
|
43
|
-
onMouseEnter={this._onBarHover}
|
44
|
-
onMouseLeave={this._onBarLeave}
|
45
|
-
>
|
46
|
-
<div style={{height: `${usagePercents}%`}} className={b('value', {type})} />
|
47
|
-
</div>
|
48
|
-
);
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
export default PoolBar;
|
@@ -1,33 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import PropTypes from 'prop-types';
|
3
|
-
import cn from 'bem-cn-lite';
|
4
|
-
|
5
|
-
import PoolBar from '../PoolBar/PoolBar';
|
6
|
-
|
7
|
-
import './PoolsGraph.scss';
|
8
|
-
|
9
|
-
const b = cn('pools-graph');
|
10
|
-
|
11
|
-
class PoolsGraph extends React.Component {
|
12
|
-
static propTypes = {
|
13
|
-
pools: PropTypes.arrayOf(PropTypes.object).isRequired,
|
14
|
-
onMouseLeave: PropTypes.func,
|
15
|
-
onMouseEnter: PropTypes.func,
|
16
|
-
};
|
17
|
-
static defaultProps = {
|
18
|
-
pools: [],
|
19
|
-
};
|
20
|
-
render() {
|
21
|
-
const {pools} = this.props;
|
22
|
-
|
23
|
-
return (
|
24
|
-
<div className={b()}>
|
25
|
-
{pools.map((item, index) => (
|
26
|
-
<PoolBar key={index} data={item} {...this.props} />
|
27
|
-
))}
|
28
|
-
</div>
|
29
|
-
);
|
30
|
-
}
|
31
|
-
}
|
32
|
-
|
33
|
-
export default PoolsGraph;
|
@@ -1,207 +0,0 @@
|
|
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 {Link, Progress} from '@gravity-ui/uikit';
|
8
|
-
|
9
|
-
import EntityStatus from '../../components/EntityStatus/EntityStatus';
|
10
|
-
import ProgressViewer from '../../components/ProgressViewer/ProgressViewer';
|
11
|
-
import InfoViewer, {InfoViewerItem} from '../../components/InfoViewer/InfoViewer';
|
12
|
-
import {Tags} from '../../components/Tags';
|
13
|
-
import {Tablet} from '../../components/Tablet';
|
14
|
-
import {Icon} from '../../components/Icon';
|
15
|
-
import {Loader} from '../../components/Loader';
|
16
|
-
import {ResponseError} from '../../components/Errors/ResponseError';
|
17
|
-
|
18
|
-
import type {AdditionalVersionsProps} from '../../types/additionalProps';
|
19
|
-
import {hideTooltip, showTooltip} from '../../store/reducers/tooltip';
|
20
|
-
import {getClusterInfo} from '../../store/reducers/cluster/cluster';
|
21
|
-
import {getClusterNodes} from '../../store/reducers/clusterNodes/clusterNodes';
|
22
|
-
import {backend, customBackend} from '../../store';
|
23
|
-
import {setHeader} from '../../store/reducers/header';
|
24
|
-
import {formatStorageValues} from '../../utils';
|
25
|
-
import {useAutofetcher, useTypedSelector} from '../../utils/hooks';
|
26
|
-
import {parseVersionsToVersionToColorMap, parseNodesToVersionsValues} from '../../utils/versions';
|
27
|
-
import routes, {CLUSTER_PAGES, createHref} from '../../routes';
|
28
|
-
|
29
|
-
import {Versions} from '../Versions/Versions';
|
30
|
-
|
31
|
-
import {compareTablets} from './utils';
|
32
|
-
|
33
|
-
import './ClusterInfo.scss';
|
34
|
-
|
35
|
-
const b = block('cluster-info');
|
36
|
-
|
37
|
-
interface ClusterInfoProps {
|
38
|
-
clusterTitle?: string;
|
39
|
-
additionalClusterInfo?: InfoViewerItem[];
|
40
|
-
additionalVersionsProps?: AdditionalVersionsProps;
|
41
|
-
}
|
42
|
-
|
43
|
-
export const ClusterInfo = ({
|
44
|
-
clusterTitle,
|
45
|
-
additionalClusterInfo = [],
|
46
|
-
additionalVersionsProps,
|
47
|
-
}: ClusterInfoProps) => {
|
48
|
-
const dispatch = useDispatch();
|
49
|
-
const location = useLocation();
|
50
|
-
|
51
|
-
const queryParams = qs.parse(location.search, {
|
52
|
-
ignoreQueryPrefix: true,
|
53
|
-
});
|
54
|
-
const {clusterName} = queryParams;
|
55
|
-
|
56
|
-
const {data: cluster, loading, wasLoaded, error} = useTypedSelector((state) => state.cluster);
|
57
|
-
const {
|
58
|
-
nodes,
|
59
|
-
loading: nodesLoading,
|
60
|
-
wasLoaded: nodesWasLoaded,
|
61
|
-
error: nodesError,
|
62
|
-
} = useTypedSelector((state) => state.clusterNodes);
|
63
|
-
const singleClusterMode = useTypedSelector((state) => state.singleClusterMode);
|
64
|
-
|
65
|
-
useEffect(() => {
|
66
|
-
dispatch(
|
67
|
-
setHeader([
|
68
|
-
{
|
69
|
-
text: CLUSTER_PAGES.cluster.title,
|
70
|
-
link: createHref(routes.cluster, {activeTab: CLUSTER_PAGES.cluster.id}),
|
71
|
-
},
|
72
|
-
]),
|
73
|
-
);
|
74
|
-
}, [dispatch]);
|
75
|
-
|
76
|
-
const fetchData = useCallback(() => {
|
77
|
-
dispatch(getClusterInfo(clusterName ? String(clusterName) : undefined));
|
78
|
-
dispatch(getClusterNodes());
|
79
|
-
}, [dispatch, clusterName]);
|
80
|
-
|
81
|
-
useAutofetcher(fetchData, [fetchData], true);
|
82
|
-
|
83
|
-
const versionToColor = useMemo(() => {
|
84
|
-
if (additionalVersionsProps?.getVersionToColorMap) {
|
85
|
-
return additionalVersionsProps?.getVersionToColorMap();
|
86
|
-
}
|
87
|
-
return parseVersionsToVersionToColorMap(cluster?.Versions);
|
88
|
-
}, [additionalVersionsProps, cluster]);
|
89
|
-
|
90
|
-
const versionsValues = useMemo(() => {
|
91
|
-
return parseNodesToVersionsValues(nodes, versionToColor);
|
92
|
-
}, [nodes, versionToColor]);
|
93
|
-
|
94
|
-
const onShowTooltip = (...args: Parameters<typeof showTooltip>) => {
|
95
|
-
dispatch(showTooltip(...args));
|
96
|
-
};
|
97
|
-
|
98
|
-
const onHideTooltip = () => {
|
99
|
-
dispatch(hideTooltip());
|
100
|
-
};
|
101
|
-
|
102
|
-
const getInfo = () => {
|
103
|
-
let link = backend + '/internal';
|
104
|
-
|
105
|
-
if (singleClusterMode && !customBackend) {
|
106
|
-
link = `/internal`;
|
107
|
-
}
|
108
|
-
|
109
|
-
const info: InfoViewerItem[] = [
|
110
|
-
{
|
111
|
-
label: 'Nodes',
|
112
|
-
value: (
|
113
|
-
<ProgressViewer
|
114
|
-
className={b('metric-field')}
|
115
|
-
value={cluster?.NodesAlive}
|
116
|
-
capacity={cluster?.NodesTotal}
|
117
|
-
/>
|
118
|
-
),
|
119
|
-
},
|
120
|
-
{
|
121
|
-
label: 'Load',
|
122
|
-
value: (
|
123
|
-
<ProgressViewer
|
124
|
-
className={b('metric-field')}
|
125
|
-
value={cluster?.LoadAverage}
|
126
|
-
capacity={cluster?.NumberOfCpus}
|
127
|
-
/>
|
128
|
-
),
|
129
|
-
},
|
130
|
-
{
|
131
|
-
label: 'Storage',
|
132
|
-
value: (
|
133
|
-
<ProgressViewer
|
134
|
-
className={b('metric-field')}
|
135
|
-
value={cluster?.StorageUsed}
|
136
|
-
capacity={cluster?.StorageTotal}
|
137
|
-
formatValues={formatStorageValues}
|
138
|
-
/>
|
139
|
-
),
|
140
|
-
},
|
141
|
-
{
|
142
|
-
label: 'Versions',
|
143
|
-
value: <div>{cluster?.Versions?.join(', ')}</div>,
|
144
|
-
},
|
145
|
-
...additionalClusterInfo,
|
146
|
-
{
|
147
|
-
label: 'Internal viewer',
|
148
|
-
value: (
|
149
|
-
<Link href={link} target="_blank">
|
150
|
-
<Icon name="external" viewBox={'0 0 16 16'} width={16} height={16} />
|
151
|
-
</Link>
|
152
|
-
),
|
153
|
-
},
|
154
|
-
];
|
155
|
-
|
156
|
-
return info;
|
157
|
-
};
|
158
|
-
|
159
|
-
if ((loading && !wasLoaded) || (nodesLoading && !nodesWasLoaded)) {
|
160
|
-
return <Loader size="l" />;
|
161
|
-
}
|
162
|
-
|
163
|
-
if (error || nodesError) {
|
164
|
-
return <ResponseError error={error || nodesError} />;
|
165
|
-
}
|
166
|
-
|
167
|
-
return (
|
168
|
-
<div className={b()}>
|
169
|
-
<div className={b('header')}>
|
170
|
-
<div className="info">
|
171
|
-
<div className={b('common')}>
|
172
|
-
<div className={b('url')}>
|
173
|
-
<EntityStatus
|
174
|
-
size="m"
|
175
|
-
status={cluster?.Overall}
|
176
|
-
name={clusterTitle ?? cluster?.Name ?? 'Unknown cluster'}
|
177
|
-
/>
|
178
|
-
</div>
|
179
|
-
|
180
|
-
{cluster?.DataCenters && <Tags tags={cluster?.DataCenters} />}
|
181
|
-
|
182
|
-
<div className={b('system-tablets')}>
|
183
|
-
{cluster?.SystemTablets &&
|
184
|
-
cluster.SystemTablets.sort(compareTablets).map(
|
185
|
-
(tablet, tabletIndex) => (
|
186
|
-
<Tablet
|
187
|
-
onMouseEnter={onShowTooltip}
|
188
|
-
onMouseLeave={onHideTooltip}
|
189
|
-
key={tabletIndex}
|
190
|
-
tablet={tablet}
|
191
|
-
/>
|
192
|
-
),
|
193
|
-
)}
|
194
|
-
</div>
|
195
|
-
</div>
|
196
|
-
<InfoViewer dots={true} info={getInfo()} />
|
197
|
-
</div>
|
198
|
-
<div className={b('version-progress')}>
|
199
|
-
<h3 className={b('progress-label')}>Versions</h3>
|
200
|
-
<Progress value={100} stack={versionsValues} />
|
201
|
-
</div>
|
202
|
-
</div>
|
203
|
-
|
204
|
-
<Versions nodes={nodes} versionToColor={versionToColor} />
|
205
|
-
</div>
|
206
|
-
);
|
207
|
-
};
|