import React, { useEffect, useRef, useState } from 'react'; import { Slider, Input, Select, Checkbox, Button, Utils, Spin, AppContainer, Tooltip } from 'knowdesign'; import { IconFont } from '@knowdesign/icons'; import API from '@src/api'; import TourGuide, { MultiPageSteps } from '@src/components/TourGuide'; import { healthSorceList, sliderValueMap, sortFieldList, sortTypes, statusFilters } from './config'; import ClusterList from './List'; import AccessClusters from './AccessCluster'; import AccessCluster from './AccessClusterConfig'; import CustomCheckGroup from './CustomCheckGroup'; import { ClustersPermissionMap } from '../CommonConfig'; import './index.less'; const CheckboxGroup = Checkbox.Group; const { Option } = Select; interface ClustersState { liveCount: number; downCount: number; total: number; } interface ClustersHealthState { deadCount: number; goodCount: number; mediumCount: number; poorCount: number; total: number; unknownCount: number; } export interface SearchParams { healthState?: number[]; checkedKafkaVersions?: string[]; sortInfo?: { sortField: string; sortType: string; }; keywords?: string; clusterStatus?: number[]; isReloadAll?: boolean; } // 未接入集群默认页 const DefaultPage = (props: { setVisible: (visible: boolean) => void }) => { return (
Kafka 多集群管理
); }; // 加载状态 const LoadingState = () => { return (
); }; const MultiClusterPage = () => { const [global] = AppContainer.useGlobalValue(); const [pageLoading, setPageLoading] = useState(true); const [accessClusterVisible, setAccessClusterVisible] = React.useState(false); const [curClusterInfo, setCurClusterInfo] = useState({}); const [kafkaVersions, setKafkaVersions] = React.useState([]); const [existKafkaVersion, setExistKafkaVersion] = React.useState([]); const [stateInfo, setStateInfo] = React.useState({ downCount: 0, liveCount: 0, total: 0, }); const [clustersHealthState, setClustersHealthState] = React.useState(); const [sliderInfo, setSliderInfo] = React.useState<{ value: [number, number]; desc: string; }>({ value: [0, 5], desc: '', }); // TODO: 首次进入因 searchParams 状态变化导致获取两次列表数据的问题 const [searchParams, setSearchParams] = React.useState({ keywords: '', checkedKafkaVersions: [], sortInfo: { sortField: 'HealthState', sortType: 'asc', }, clusterStatus: [0, 1], healthState: [-1, 0, 1, 2, 3], // 是否拉取当前所有数据 isReloadAll: false, }); const searchKeyword = useRef(''); const isReload = useRef(false); const getPhyClusterHealthState = () => { Utils.request(API.phyClusterHealthState).then((res: ClustersHealthState) => { setClustersHealthState(res || undefined); const result: string[] = []; for (let i = 0; i < sliderInfo.value[1] - sliderInfo.value[0]; i++) { const val = sliderValueMap[(sliderInfo.value[1] - i) as keyof typeof sliderValueMap]; result.push(`${val.name}: ${res?.[val.key as keyof ClustersHealthState]}`); } setSliderInfo((cur) => ({ ...cur, desc: result.reverse().join(', '), })); }); }; // 获取集群状态 const getPhyClusterState = () => { getPhyClusterHealthState(); Utils.request(API.phyClusterState) .then((res: ClustersState) => { setStateInfo(res); }) .finally(() => { setPageLoading(false); }); }; // 获取 kafka 全部版本 const getSupportKafkaVersion = () => { Utils.request(API.supportKafkaVersion).then((res) => { setKafkaVersions(Object.keys(res || {})); }); }; const updateSearchParams = (params: SearchParams) => { setSearchParams((curParams) => ({ ...curParams, isReloadAll: false, ...params })); getPhyClusterHealthState(); }; const searchParamsChangeFunc = { // 健康分改变 onSilderChange: (value: number[]) => updateSearchParams({ healthState: value, }), // 排序信息改变 onSortInfoChange: (type: string, value: string) => updateSearchParams({ sortInfo: { ...searchParams.sortInfo, [type]: value, }, }), // Live / Down 筛选 onClusterStatusChange: (list: number[]) => updateSearchParams({ clusterStatus: list, }), // 集群名称搜索项改变 onInputChange: () => updateSearchParams({ keywords: searchKeyword.current, }), // 集群版本筛选 onChangeCheckGroup: (list: string[]) => { updateSearchParams({ checkedKafkaVersions: list, isReloadAll: isReload.current, }); isReload.current = false; }, }; // 获取当前接入集群的 kafka 版本 const getExistKafkaVersion = (isReloadAll = false) => { isReload.current = isReloadAll; Utils.request(API.getClustersVersion).then((versions: string[]) => { if (!Array.isArray(versions)) { versions = []; } setExistKafkaVersion(versions.sort().reverse() || []); }); }; // 接入/编辑集群 const showAccessCluster = (clusterInfo: any = {}) => { setCurClusterInfo(clusterInfo); setAccessClusterVisible(true); }; // 接入/编辑集群回调 const afterAccessCluster = () => { getPhyClusterState(); getExistKafkaVersion(true); }; useEffect(() => { getPhyClusterState(); getSupportKafkaVersion(); getExistKafkaVersion(); }, []); return ( <> {pageLoading ? ( ) : !stateInfo?.total ? ( ) : ( <>
Clusters 总数
{stateInfo.total}
live {stateInfo.liveCount}
down {stateInfo.downCount}
(searchKeyword.current = e.target.value)} allowClear bordered={false} placeholder="请输入ClusterName进行搜索" suffix={} />
{global.hasPermission && global.hasPermission(ClustersPermissionMap.CLUSTER_ADD) ? ( <>
) : ( <> )}

版本分布

{existKafkaVersion.length ? ( ) : null}

健康状态

{ if (value[0] !== value[1]) { const result = []; for (let i = 0; i < value[1] - value[0]; i++) { const val = sliderValueMap[(value[1] - i) as keyof typeof sliderValueMap]; result.push(`${val.name}: ${clustersHealthState?.[val.key as keyof ClustersHealthState]}`); } setSliderInfo({ value, desc: result.reverse().join(', '), }); } }} onAfterChange={(value: [number, number]) => { const result = []; for (let i = 0; i < value[1] - value[0]; i++) { const val = sliderValueMap[(value[1] - i) as keyof typeof sliderValueMap]; result.push(val.code); } searchParamsChangeFunc.onSilderChange(result); }} />
{/* 引导页 */} )} ); }; export default MultiClusterPage;