import { AppContainer, Divider, Form, IconFont, Input, List, message, Modal, Progress, Spin, Tooltip, Utils } from 'knowdesign'; import moment from 'moment'; import React, { useEffect, useMemo, useState, useReducer } from 'react'; import InfiniteScroll from 'react-infinite-scroll-component'; import { Link, useHistory } from 'react-router-dom'; import { timeFormat } from '../../constants/common'; import { IMetricPoint, linesMetric } from './config'; import { useIntl } from 'react-intl'; import api, { MetricType } from '../../api'; import { getHealthClassName, getHealthProcessColor, getHealthText } from '../SingleClusterDetail/config'; import { ClustersPermissionMap } from '../CommonConfig'; import { getUnit, getDataNumberUnit } from '@src/constants/chartConfig'; import SmallChart from '@src/components/SmallChart'; const ListScroll = (props: { loadMoreData: any; list: any; pagination: any; getPhyClusterState: any }) => { const history = useHistory(); const [global] = AppContainer.useGlobalValue(); const [form] = Form.useForm(); const [list, setList] = useState<[]>(props.list || []); const [loading, setLoading] = useState(false); const [visible, setVisible] = useState(false); const [clusterInfo, setClusterInfo] = useState({} as any); const [pagination, setPagination] = useState( props.pagination || { pageNo: 1, pageSize: 10, total: 0, } ); const intl = useIntl(); useEffect(() => { setList(props.list || []); setPagination(props.pagination || {}); }, [props.list, props.pagination]); useEffect(() => { if (visible) { form.resetFields(); } }, [visible]); const loadMoreData = async () => { if (loading) { return; } setLoading(true); const res = await props.loadMoreData(pagination.pageNo + 1, pagination.pageSize); const _data = list.concat(res.bizData || []) as any; setList(_data); setPagination(res.pagination); setLoading(false); }; const RenderItem = (itemData: any) => { itemData = itemData || {}; const metrics = linesMetric; const metricPoints = [] as IMetricPoint[]; metrics.forEach((item) => { const line = { metricName: item, value: itemData.latestMetrics?.metrics?.[item] || 0, unit: (global.getMetricDefine && global.getMetricDefine(MetricType.Cluster, item).unit) || '', metricLines: { name: item, data: itemData.metricLines .find((metric: any) => metric.metricName === item) ?.metricPoints.map((point: IMetricPoint) => [point.timeStamp, point.value]), }, } as IMetricPoint; // 如果单位是 字节 ,进行单位换算 if (line.unit.toLowerCase().includes('byte')) { const [unit, size] = getUnit(line.value); line.value = Number((line.value / size).toFixed(2)); line.unit = line.unit.toLowerCase().replace('byte', unit); } // Messages 指标值特殊处理 if (line.metricName === 'LeaderMessages') { const [unit, size] = getDataNumberUnit(line.value); line.value = Number((line.value / size).toFixed(2)); line.unit = unit + line.unit; } metricPoints.push(line); }); const { Brokers: brokers, Zookeepers: zks, HealthCheckPassed: healthCheckPassed, HealthCheckTotal: healthCheckTotal, HealthScore: healthScore, ZookeepersAvailable: zookeepersAvailable, LoadReBalanceCpu: loadReBalanceCpu, LoadReBalanceDisk: loadReBalanceDisk, LoadReBalanceEnable: loadReBalanceEnable, LoadReBalanceNwIn: loadReBalanceNwIn, LoadReBalanceNwOut: loadReBalanceNwOut, } = itemData.latestMetrics?.metrics || {}; return ( { history.push(`/cluster/${itemData.id}/cluster`); }} >
= 90 ? 'success' : 'normal'} strokeWidth={4} // className={healthScore > 90 ? 'green-circle' : ''} className={+itemData.alive <= 0 ? 'red-circle' : +healthScore < 90 ? 'blue-circle' : 'green-circle'} strokeColor={getHealthProcessColor(healthScore, itemData.alive)} percent={itemData.alive ? healthScore : 100} format={() => (
{getHealthText(healthScore, itemData?.alive)}
)} width={70} />
通过 {healthCheckPassed}/{healthCheckTotal}
{itemData.name ?? '-'}
{itemData.kafkaVersion ?? '-'} {loadReBalanceEnable !== undefined && (
{ e.preventDefault(); e.stopPropagation(); }} > {[ ['BytesIn', loadReBalanceNwIn === 1], ['BytesOut', loadReBalanceNwOut === 1], ['Disk', loadReBalanceDisk === 1], ].map(([name, isBalanced]) => { return isBalanced ? (
{name} 已均衡
) : loadReBalanceEnable ? (
{name} 未均衡
) : ( 尚未开启 {name} 均衡策略, 前往开启 } >
{name} 未均衡
); })}
)}
{moment(itemData.createTime).format(timeFormat)}
Brokers
{brokers}
ZK
{zookeepersAvailable === -1 ? '-' : zks}
{metricPoints.map((row, index) => { return (
{row.metricName === 'TotalLogSize' ? 'MessageSize' : row.metricName}
{row.value} {row.unit}
); })}
{global.hasPermission && global.hasPermission(ClustersPermissionMap.CLUSTER_DEL) ? (
onClickDeleteBtn(event, itemData)}>
) : ( <> )}
); }; const onFinish = () => { form.validateFields().then((formData) => { Utils.delete(api.phyCluster, { params: { clusterPhyId: clusterInfo.id, }, }).then((res) => { message.success('删除成功'); setVisible(false); props?.getPhyClusterState(); const fliterList: any = list.filter((item: any) => { return item?.id !== clusterInfo.id; }); setList(fliterList || []); }); }); }; const onClickDeleteBtn = (event: any, clusterInfo: any) => { event.stopPropagation(); setClusterInfo(clusterInfo); setVisible(true); }; return ( <> {useMemo( () => ( } endMessage={ !pagination.total ? ( '' ) : ( 加载完成 共{pagination.total}条 ) } scrollableTarget="scrollableDiv" > ), [list, pagination, loading] )} setVisible(false)} okButtonProps={{ style: { width: 56, }, danger: true, size: 'small', }} cancelButtonProps={{ style: { width: 56, }, size: 'small', }} >
{intl.formatMessage({ id: 'delete.cluster.confirm.tip', })}
{clusterInfo.name} { value = value || ''; if (!value.trim() || value.trim() !== clusterInfo.name) return Promise.reject( intl.formatMessage({ id: 'delete.cluster.confirm.cluster', }) ); return Promise.resolve(); }, }, ]} >
); }; export default ListScroll;