Skip to content

Commit 3123f4f

Browse files
refactor: move ClusterInfo utils
1 parent c673abc commit 3123f4f

File tree

4 files changed

+157
-154
lines changed

4 files changed

+157
-154
lines changed

src/containers/Cluster/ClusterInfo/ClusterInfo.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import type {VersionToColorMap} from '../../../types/versions';
1010
import i18n from '../i18n';
1111

1212
import {b} from './shared';
13-
import {getInfo, useClusterLinks} from './utils';
13+
import {useClusterLinks} from './utils/useClusterLinks';
14+
import {getInfo} from './utils/utils';
1415

1516
import './ClusterInfo.scss';
1617

src/containers/Cluster/ClusterInfo/utils.tsx

Lines changed: 0 additions & 153 deletions
This file was deleted.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import React from 'react';
2+
3+
import {useClusterBaseInfo} from '../../../../store/reducers/cluster/cluster';
4+
import type {ClusterLink} from '../../../../types/additionalProps';
5+
import {parseJson} from '../../../../utils/utils';
6+
import i18n from '../../i18n';
7+
8+
/**
9+
* parses stringified json in format {url: "href"}
10+
*/
11+
function prepareClusterCoresLink(rawCoresString?: string) {
12+
try {
13+
const linkObject = parseJson(rawCoresString) as unknown;
14+
15+
if (
16+
linkObject &&
17+
typeof linkObject === 'object' &&
18+
'url' in linkObject &&
19+
typeof linkObject.url === 'string'
20+
) {
21+
return linkObject.url;
22+
}
23+
} catch {}
24+
25+
return undefined;
26+
}
27+
28+
/**
29+
* parses stringified json in format {url: "href", slo_logs_url: "href"}
30+
*/
31+
function prepareClusterLoggingLinks(rawLoggingString?: string) {
32+
try {
33+
const linkObject = parseJson(rawLoggingString) as unknown;
34+
35+
if (linkObject && typeof linkObject === 'object') {
36+
const logsUrl =
37+
'url' in linkObject && typeof linkObject.url === 'string'
38+
? linkObject.url
39+
: undefined;
40+
const sloLogsUrl =
41+
'slo_logs_url' in linkObject && typeof linkObject.slo_logs_url === 'string'
42+
? linkObject.slo_logs_url
43+
: undefined;
44+
return {logsUrl, sloLogsUrl};
45+
}
46+
} catch {}
47+
48+
return {};
49+
}
50+
51+
export function useClusterLinks() {
52+
const {cores, logging} = useClusterBaseInfo();
53+
54+
return React.useMemo(() => {
55+
const result: ClusterLink[] = [];
56+
57+
const coresUrl = prepareClusterCoresLink(cores);
58+
const {logsUrl, sloLogsUrl} = prepareClusterLoggingLinks(logging);
59+
60+
if (coresUrl) {
61+
result.push({
62+
title: i18n('link_cores'),
63+
url: coresUrl,
64+
});
65+
}
66+
67+
if (logsUrl) {
68+
result.push({
69+
title: i18n('link_logging'),
70+
url: logsUrl,
71+
});
72+
}
73+
74+
if (sloLogsUrl) {
75+
result.push({
76+
title: i18n('link_slo-logs'),
77+
url: sloLogsUrl,
78+
});
79+
}
80+
81+
return result;
82+
}, [cores, logging]);
83+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import React from 'react';
2+
3+
import {Flex} from '@gravity-ui/uikit';
4+
5+
import {ProgressViewer} from '../../../../components/ProgressViewer/ProgressViewer';
6+
import {Tags} from '../../../../components/Tags';
7+
import {isClusterInfoV2} from '../../../../types/api/cluster';
8+
import type {TClusterInfo} from '../../../../types/api/cluster';
9+
import type {EFlag} from '../../../../types/api/enums';
10+
import type {InfoItem} from '../../../../types/components';
11+
import {formatNumber} from '../../../../utils/dataFormatters/dataFormatters';
12+
import i18n from '../../i18n';
13+
import {NodesState} from '../components/NodesState/NodesState';
14+
import {b} from '../shared';
15+
16+
const COLORS_PRIORITY: Record<EFlag, number> = {
17+
Green: 5,
18+
Blue: 4,
19+
Yellow: 3,
20+
Orange: 2,
21+
Red: 1,
22+
Grey: 0,
23+
};
24+
25+
const getDCInfo = (cluster: TClusterInfo) => {
26+
if (isClusterInfoV2(cluster) && cluster.MapDataCenters) {
27+
return Object.entries(cluster.MapDataCenters).map(([dc, count]) => (
28+
<React.Fragment key={dc}>
29+
{dc}: {formatNumber(count)}
30+
</React.Fragment>
31+
));
32+
}
33+
return undefined;
34+
};
35+
36+
export const getInfo = (cluster: TClusterInfo, additionalInfo: InfoItem[]) => {
37+
const info: InfoItem[] = [];
38+
39+
if (isClusterInfoV2(cluster) && cluster.MapNodeStates) {
40+
const arrayNodesStates = Object.entries(cluster.MapNodeStates) as [EFlag, number][];
41+
// sort stack to achieve order "green, orange, yellow, red, blue, grey"
42+
arrayNodesStates.sort((a, b) => COLORS_PRIORITY[b[0]] - COLORS_PRIORITY[a[0]]);
43+
const nodesStates = arrayNodesStates.map(([state, count]) => {
44+
return (
45+
<NodesState state={state as EFlag} key={state}>
46+
{formatNumber(count)}
47+
</NodesState>
48+
);
49+
});
50+
info.push({
51+
label: i18n('label_nodes-state'),
52+
value: <Flex gap={2}>{nodesStates}</Flex>,
53+
});
54+
}
55+
56+
const dataCenters = getDCInfo(cluster);
57+
if (dataCenters?.length) {
58+
info.push({
59+
label: i18n('label_dc'),
60+
value: <Tags tags={dataCenters} gap={2} className={b('dc')} />,
61+
});
62+
}
63+
64+
info.push({
65+
label: i18n('label_load'),
66+
value: <ProgressViewer value={cluster?.LoadAverage} capacity={cluster?.NumberOfCpus} />,
67+
});
68+
69+
info.push(...additionalInfo);
70+
71+
return info;
72+
};

0 commit comments

Comments
 (0)