Files
KnowStreaming/km-console/packages/layout-clusters-fe/src/pages/ConsumerGroup/Detail.tsx
erge ac4ea13be9 修复一些前端问题 (#1199)
请不要在没有先创建Issue的情况下创建Pull Request。

## 变更的目的是什么

XXXXX

## 简短的更新日志

- [Bugfix]修复重置offset接口调用过多问题
- [Bugfix]修复消费组Offset重置后,提示重置成功,但是前端不刷新数据,Offset无变化的问题
- [Optimize]消费组详情控制数据实时刷新

## 验证这一变化

XXXX

请遵循此清单,以帮助我们快速轻松地整合您的贡献:

* [ ] 一个 PR(Pull Request的简写)只解决一个问题,禁止一个 PR 解决多个问题;
* [ ] 确保 PR 有对应的 Issue(通常在您开始处理之前创建),除非是书写错误之类的琐碎更改不需要 Issue ;
* [ ] 格式化 PR 及 Commit-Log 的标题及内容,例如 #861 。PS:Commit-Log 需要在 Git Commit
代码时进行填写,在 GitHub 上修改不了;
* [ ] 编写足够详细的 PR 描述,以了解 PR 的作用、方式和原因;
* [ ] 编写必要的单元测试来验证您的逻辑更正。如果提交了新功能或重大更改,请记住在 test 模块中添加 integration-test;
* [ ] 确保编译通过,集成测试通过;
2023-11-30 21:44:06 +08:00

283 lines
9.0 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 React, { useState, useEffect } from 'react';
import { useParams, useHistory } from 'react-router-dom';
import { Button, Space, Divider, Drawer, ProTable, Utils, notification } from 'knowdesign';
import { IconFont } from '@knowdesign/icons';
import API from '@src/api/index';
import { defaultPagination, hashDataParse } from '@src/constants/common';
import { getGtoupTopicColumns } from './config';
import { ExpandedRow } from './ExpandedRow';
import ResetOffsetDrawer from './ResetOffsetDrawer';
import { useForceRefresh } from '@src/components/utils';
const { request } = Utils;
export interface MetricLine {
createTime?: number;
metricPoints: Array<{
aggType: string;
createTime: number;
timeStamp: number;
unit: string;
updateTime: number;
value: number;
}>;
name: string;
updateTime?: number;
}
export interface MetricData {
metricLines?: Array<MetricLine>;
metricLine?: MetricLine;
metricName: string;
}
export interface HashData {
groupName: string;
topicName: string;
}
const metricConsts = ['LogEndOffset', 'OffsetConsumed', 'Lag'];
const metricWithType = [
{ metricName: 'LogEndOffset', metricType: 104 },
{ metricName: 'OffsetConsumed', metricType: 102 },
{ metricName: 'Lag', metricType: 102 },
];
const GroupDetail = (props: any) => {
const { scene } = props;
const urlParams = useParams<{
clusterId: string;
}>();
const now = Date.now();
const history = useHistory();
const [hashData, setHashData] = useState<HashData>({ groupName: '', topicName: '' });
const [visible, setVisible] = useState(false);
const [topicData, setTopicData] = useState([]);
const [loading, setLoading] = useState(true);
const [pagination, setPagination] = useState<any>(defaultPagination);
const [expandedData, setExpandedData] = useState([]);
const [chartData, setChartData] = useState<Array<MetricData>>([]);
const [loadingObj, setLoadingObj] = useState<any>({});
const [timeRange, setTimeRange] = useState([now - 24 * 60 * 60 * 1000, now]);
const [curPartition, setCurPartition] = useState<string>('');
const [groupMetricsData, setGroupMetricsData] = useState<Array<MetricData>>([]);
const [openKeys, setOpenKeys] = useState();
const [resetOffsetVisible, setResetOffsetVisible] = useState(false);
const [resetOffsetArg, setResetOffsetArg] = useState({});
const [refreshKey, forceRefresh] = useForceRefresh();
const genData = async ({ pageNo, pageSize, groupName }: any) => {
if (urlParams?.clusterId === undefined) return;
setLoading(true);
const params = {
// searchKeywords: '',
pageNo,
pageSize,
};
request(API.getGroupTopicList(+urlParams?.clusterId, groupName), { params })
.then((res: any) => {
setVisible(true);
setPagination({
current: res.pagination?.pageNo,
pageSize: res.pagination?.pageSize,
total: res.pagination?.total,
});
const newTopicListData = res?.bizData.map((item: any) => {
return {
...item,
key: item.topicName,
};
});
setTopicData(newTopicListData || []);
setLoading(false);
})
.catch((err) => {
setLoading(false);
});
};
const onClose = () => {
setVisible(false);
// clean hash'
scene === 'topicDetail' && history.goBack();
scene !== 'topicDetail' && window.history.pushState('', '', location.pathname);
};
const resetOffset = (record: any) => {
setResetOffsetVisible(true);
setResetOffsetArg({
topicName: record?.topicName,
groupName: record?.groupName,
});
};
// 删除消费组Topic
const deleteOffset = (record: any) => {
const params = {
clusterPhyId: +urlParams?.clusterId,
deleteType: 1, // 0:group纬度1Topic纬度2Partition纬度
groupName: record.groupName,
topicName: record.topicName,
};
Utils.delete(API.deleteGroupOffset(), { data: params }).then((data: any) => {
if (data === null) {
notification.success({
message: '删除Topic成功!',
});
genData({ pageNo: 1, pageSize: pagination.pageSize, groupName: hashData.groupName });
}
});
};
const onTableChange = (pagination: any, filters: any, sorter: any) => {
genData({ pageNo: pagination.current, pageSize: pagination.pageSize, filters, sorter, groupName: hashData.groupName });
};
const onClickExpand = (expanded: any, record: any) => {
const key = record?.key;
// 之前展开过
if (expandedData[key]?.length) return;
// 第一次展开
setOpenKeys(key);
// const loading = { ...loadingObj };
// loading[key] = true;
// setLoadingObj(loading);
// expanded && queryExpandedData(record, key);
};
useEffect(() => {
const hashData = hashDataParse(location.hash);
if (!hashData.groupName) {
setVisible(false);
}
setHashData(hashData);
// 获取分区列表 为图表模式做准备
hashData.groupName && genData({ pageNo: 1, pageSize: pagination.pageSize, groupName: hashData.groupName });
// getConsumersMetadata(hashData).then((res: any) => {
// if (res.exist) {
// setVisible(false);
// history.push(`/cluster/${params?.clusterId}/consumers`);
// return;
// }
// setVisible(true);
// getTopicGroupPartitionsHistory(hashData)
// .then((data: any) => {
// if (data.length > 0) {
// setCurPartition(data[0].partition);
// }
// setPartitionList(data);
// return data;
// })
// .then((data) => {
// getTopicGroupMetricHistory(data, hashData);
// })
// .catch((e) => {
// history.push(`/cluster/${params?.clusterId}/consumers`);
// setVisible(false);
// });
// // 获取Consumer列表 表格模式
// getTopicGroupMetric(hashData);
// });
}, [hashDataParse(location.hash).groupName, refreshKey]);
return (
<Drawer
push={false}
title="Consumer Group详情"
width={1080}
placement="right"
onClose={onClose}
visible={visible}
className="consumer-group-detail-drawer"
maskClosable={false}
destroyOnClose
// extra={
// <Space>
// {global.hasPermission &&
// global.hasPermission(
// scene === 'topicDetail' ? ClustersPermissionMap.TOPIC_RESET_OFFSET : ClustersPermissionMap.CONSUMERS_RESET_OFFSET
// ) && <ResetOffsetDrawer record={hashData}></ResetOffsetDrawer>}
// <Divider type="vertical" />
// </Space>
// }
extra={
<Space>
<span style={{ display: 'inline-block', fontSize: '15px' }} onClick={forceRefresh as () => void}>
<i className="iconfont icon-shuaxin1" style={{ cursor: 'pointer' }} />
</span>
<Divider type="vertical" />
</Space>
}
>
<ProTable
showQueryForm={false}
tableProps={{
showHeader: false,
rowKey: 'key',
loading: loading,
columns: getGtoupTopicColumns({ resetOffset, deleteOffset }),
dataSource: topicData,
paginationProps: { ...pagination },
// noPagination: true,
attrs: {
className: 'consumer-group-detail-drawer-table',
bordered: false,
onChange: onTableChange,
tableLayout: 'auto',
scroll: { x: 'max-content' },
expandable: {
expandedRowRender: (record: any, index: number, indent: any, expanded: boolean) => (
<ExpandedRow
record={record}
openKeys={openKeys}
expanded={expanded}
tableData={expandedData}
chartData={chartData}
groupName={hashDataParse(location.hash).groupName}
loading={loadingObj}
refreshKey={refreshKey}
/>
),
// expandedRowRender,
onExpand: onClickExpand,
columnWidth: '20px',
fixed: 'left',
expandIcon: ({ expanded, onExpand, record }: any) => {
return expanded ? (
<IconFont
style={{ fontSize: '16px' }}
type="icon-xia"
onClick={(e: any) => {
onExpand(record, e);
}}
/>
) : (
<IconFont
style={{ fontSize: '16px' }}
type="icon-jiantou_1"
onClick={(e: any) => {
onExpand(record, e);
}}
/>
);
},
},
style: {
width: '1032px',
},
},
}}
/>
<ResetOffsetDrawer
visible={resetOffsetVisible}
setVisible={setResetOffsetVisible}
record={resetOffsetArg}
resetOffsetFn={forceRefresh}
></ResetOffsetDrawer>
</Drawer>
);
};
export default GroupDetail;