Files
KnowStreaming/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/LeftSider.tsx
2022-09-13 14:46:29 +08:00

254 lines
9.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { AppContainer, Divider, IconFont, Progress, Tooltip, Utils } from 'knowdesign';
import React, { useEffect, useState } from 'react';
import AccessClusters from '../MutliClusterPage/AccessCluster';
import './index.less';
import API from '../../api';
import HealthySetting from './HealthySetting';
import CheckDetail from './CheckDetail';
import { Link, useHistory, useParams } from 'react-router-dom';
import { getHealthClassName, getHealthProcessColor, getHealthState, getHealthText, renderToolTipValue } from './config';
import { ClustersPermissionMap } from '../CommonConfig';
const LeftSider = () => {
const [global] = AppContainer.useGlobalValue();
const history = useHistory();
const [kafkaVersion, setKafkaVersion] = useState({});
const [clusterInfo, setClusterInfo] = useState({} as any);
const [loading, setLoading] = React.useState(false);
const [clusterMetrics, setClusterMetrics] = useState({} as any);
const [brokerState, setBrokerState] = useState({} as any);
const detailDrawerRef: any = React.createRef();
const healthyDrawerRef: any = React.createRef();
const { clusterId } = useParams<{ clusterId: string }>();
const [visible, setVisible] = React.useState(false);
const getSupportKafkaVersion = () => {
Utils.request(API.supportKafkaVersion).then((res) => {
setKafkaVersion(res || {});
});
};
const getBrokerState = () => {
return Utils.request(API.getBrokersState(clusterId)).then((res) => {
setBrokerState(res);
});
};
const getPhyClusterMetrics = () => {
return Utils.post(
API.getPhyClusterMetrics(+clusterId),
[
'HealthScore',
'HealthCheckPassed',
'HealthCheckTotal',
'Topics',
'PartitionURP',
'PartitionNoLeader', // > 0 error
'PartitionMinISR_S', // > 0 error
'Groups',
'GroupDeads',
'Alive',
].concat(process.env.BUSINESS_VERSION ? ['LoadReBalanceEnable', 'LoadReBalanceNwIn', 'LoadReBalanceNwOut', 'LoadReBalanceDisk'] : [])
).then((res: any) => {
setClusterMetrics(res?.metrics || {});
});
};
const getPhyClusterInfo = () => {
setLoading(true);
Utils.request(API.getPhyClusterBasic(+clusterId))
.then((res: any) => {
let jmxProperties = null;
try {
jmxProperties = JSON.parse(res?.jmxProperties);
} catch (err) {
console.error(err);
}
// 转化值对应成表单值
if (jmxProperties?.openSSL) {
jmxProperties.security = 'Password';
}
if (jmxProperties) {
res = Object.assign({}, res || {}, jmxProperties);
}
setClusterInfo(res);
setLoading(false);
})
.catch((err) => {
setLoading(false);
});
};
useEffect(() => {
getBrokerState();
getPhyClusterMetrics();
getSupportKafkaVersion();
getPhyClusterInfo();
}, []);
const renderIcon = (type: string) => {
return (
<span className={`icon`}>
<IconFont type={type === 'green' ? 'icon-zhengchang' : type === 'warning' ? 'icon-yichang' : 'icon-warning'} />
</span>
);
};
return (
<>
<div className="left-sider">
<div className="state-card">
<Progress
type="circle"
status="active"
strokeWidth={4}
strokeColor={getHealthProcessColor(clusterMetrics?.HealthScore, clusterMetrics?.Alive)}
percent={clusterMetrics?.HealthScore ?? '-'}
className={+clusterMetrics.Alive <= 0 ? 'red-circle' : +clusterMetrics?.HealthScore < 90 ? 'blue-circle' : 'green-circle'}
format={() => (
<div className={`healthy-percent ${getHealthClassName(clusterMetrics?.HealthScore, clusterMetrics?.Alive)}`}>
{getHealthText(clusterMetrics?.HealthScore, clusterMetrics?.Alive)}
</div>
)}
width={75}
/>
<div className="healthy-state">
<div className="healthy-state-status">
<span>{getHealthState(clusterMetrics?.HealthScore, clusterMetrics?.Alive)}</span>
{/* 健康分设置 */}
{global.hasPermission && global.hasPermission(ClustersPermissionMap.CLUSTER_CHANGE_HEALTHY) ? (
<span
className="icon"
onClick={() => {
healthyDrawerRef.current.getHealthconfig().then(() => {
healthyDrawerRef.current.setVisible(true);
});
}}
>
<IconFont type="icon-shezhi" size={13} />
</span>
) : (
<></>
)}
</div>
<div>
<span className="healthy-state-num">
{clusterMetrics?.HealthCheckPassed}/{clusterMetrics?.HealthCheckTotal}
</span>
{/* 健康度详情 */}
<span
className="healthy-state-btn"
onClick={() => {
detailDrawerRef.current.setVisible(true);
}}
>
</span>
</div>
</div>
</div>
<Divider />
<div className="title">
<div className="name">{renderToolTipValue(clusterInfo?.name, 35)}</div>
{!loading && global.hasPermission && global.hasPermission(ClustersPermissionMap.CLUSTER_CHANGE_INFO) ? (
<div className="edit-icon-box" onClick={() => setVisible(true)}>
<IconFont className="edit-icon" type="icon-bianji2" />
</div>
) : (
<></>
)}
</div>
<div className="tag-panel">
<div className="tag default">{clusterInfo?.kafkaVersion ?? '-'}</div>
{clusterMetrics?.LoadReBalanceEnable !== undefined &&
[
['BytesIn', clusterMetrics?.LoadReBalanceNwIn === 1],
['BytesOut', clusterMetrics?.LoadReBalanceNwOut === 1],
['Disk', clusterMetrics?.LoadReBalanceDisk === 1],
].map(([name, isBalanced]) => {
return isBalanced ? (
<div className="tag balanced">{name} </div>
) : clusterMetrics?.LoadReBalanceEnable ? (
<div className="tag unbalanced">{name} </div>
) : (
<Tooltip
title={
<span>
{name}
<Link to={`/cluster/${clusterId}/cluster/balance`}></Link>
</span>
}
>
<div className="tag unbalanced">{name} </div>
</Tooltip>
);
})}
</div>
<div className="desc">{renderToolTipValue(clusterInfo?.description, 35)}</div>
<div className="card-panel">
<div className="card-item" onClick={() => history.push(`/cluster/${clusterId}/broker`)}>
<div className="title">Brokers总数</div>
<div className="count">
<span className="num">{brokerState?.brokerCount ?? '-'}</span>
<span className="unit"></span>
</div>
<div className="metric">
<span className="type">Controller</span>
{renderIcon(brokerState?.kafkaControllerAlive ? 'green' : 'red')}
</div>
<div className="metric">
<span className="type">Similar Config</span>
{renderIcon(brokerState?.configSimilar ? 'green' : 'warning')}
</div>
</div>
<div className="card-item" onClick={() => history.push(`/cluster/${clusterId}/topic`)}>
<div className="title">Topics总数</div>
<div className="count">
<span className="num">{clusterMetrics?.Topics ?? '-'}</span>
<span className="unit"></span>
</div>
<div className="metric">
<span className="type">No leader</span>
{renderIcon(clusterMetrics?.PartitionNoLeader === 0 ? 'green' : 'red')}
</div>
<div className="metric">
<span className="type">{'< Min ISR'}</span>
{renderIcon(clusterMetrics?.PartitionMinISR_S === 0 ? 'green' : 'red')}
</div>
<div className="metric">
<span className="type">URP</span>
{renderIcon(clusterMetrics?.PartitionURP === 0 ? 'green' : 'red')}
</div>
</div>
<div className="card-item" onClick={() => history.push(`/cluster/${clusterId}/consumers`)}>
<div className="title">ConsumerGroup总数</div>
<div className="count">
<span className="num">{clusterMetrics?.Groups ?? '-'}</span>
<span className="unit"></span>
</div>
<div className="metric">
<span className="type">Dead</span>
{renderIcon(clusterMetrics?.GroupDeads === 0 ? 'green' : 'red')}
</div>
</div>
</div>
</div>
<AccessClusters
visible={visible}
setVisible={setVisible}
title="edit.cluster"
afterSubmitSuccess={getPhyClusterInfo}
clusterInfo={clusterInfo}
kafkaVersion={Object.keys(kafkaVersion)}
/>
<HealthySetting ref={healthyDrawerRef} />
<CheckDetail ref={detailDrawerRef} />
</>
);
};
export default LeftSider;