mirror of
https://github.com/didi/KnowStreaming.git
synced 2026-01-08 15:52:15 +08:00
初始化3.0.0版本
This commit is contained in:
@@ -0,0 +1,321 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Drawer, Button, Space, Divider, AppContainer, ProTable, IconFont } from 'knowdesign';
|
||||
import { IindicatorSelectModule } from './index';
|
||||
import './style/indicator-drawer.less';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
interface PropsType extends React.HTMLAttributes<HTMLDivElement> {
|
||||
onClose: () => void;
|
||||
visible: boolean;
|
||||
isGroup?: boolean; // 是否分组
|
||||
indicatorSelectModule: IindicatorSelectModule;
|
||||
}
|
||||
|
||||
interface MetricInfo {
|
||||
name: string;
|
||||
unit: string;
|
||||
desc: string;
|
||||
}
|
||||
|
||||
interface SelectedMetrics {
|
||||
[category: string]: string[];
|
||||
}
|
||||
|
||||
type CategoryData = {
|
||||
category: string;
|
||||
metrics: MetricInfo[];
|
||||
};
|
||||
|
||||
const ExpandedRow = ({ metrics, category, selectedMetrics, selectedMetricChange }: any) => {
|
||||
const innerColumns = [
|
||||
{
|
||||
title: '指标名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
dataIndex: 'unit',
|
||||
key: 'unit',
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'desc',
|
||||
key: 'desc',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
padding: '12px 16px',
|
||||
margin: '0 7px',
|
||||
border: '1px solid #EFF2F7',
|
||||
borderRadius: '8px',
|
||||
backgroundColor: '#ffffff',
|
||||
}}
|
||||
>
|
||||
<ProTable
|
||||
tableProps={{
|
||||
showHeader: false,
|
||||
noPagination: true,
|
||||
rowKey: 'name',
|
||||
columns: innerColumns,
|
||||
dataSource: metrics,
|
||||
attrs: {
|
||||
rowSelection: {
|
||||
hideSelectAll: true,
|
||||
selectedRowKeys: selectedMetrics,
|
||||
onChange: (keys: string[]) => {
|
||||
selectedMetricChange(category, keys);
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const IndicatorDrawer = ({ onClose, visible, indicatorSelectModule }: PropsType) => {
|
||||
const [global] = AppContainer.useGlobalValue();
|
||||
const { pathname } = useLocation();
|
||||
const [confirmLoading, setConfirmLoading] = useState<boolean>(false);
|
||||
const [categoryData, setCategoryData] = useState<CategoryData[]>([]);
|
||||
const [selectedCategories, setSelectedCategories] = useState<string[]>([]);
|
||||
const [childrenSelectedRowKeys, setChildrenSelectedRowKeys] = useState<SelectedMetrics>({});
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: `${pathname.endsWith('/broker') ? 'Broker' : pathname.endsWith('/topic') ? 'Topic' : 'Cluster'} Metrics`,
|
||||
dataIndex: 'category',
|
||||
key: 'category',
|
||||
},
|
||||
];
|
||||
|
||||
const formateTableData = () => {
|
||||
const tableData = indicatorSelectModule.tableData;
|
||||
const categoryData: {
|
||||
[category: string]: MetricInfo[];
|
||||
} = {};
|
||||
|
||||
tableData.forEach(({ name, desc }) => {
|
||||
const metricDefine = global.getMetricDefine(indicatorSelectModule?.metricType, name);
|
||||
const returnData = {
|
||||
name,
|
||||
desc,
|
||||
unit: metricDefine?.unit,
|
||||
};
|
||||
if (metricDefine.category) {
|
||||
if (!categoryData[metricDefine.category]) {
|
||||
categoryData[metricDefine.category] = [returnData];
|
||||
} else {
|
||||
categoryData[metricDefine.category].push(returnData);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const result = Object.entries(categoryData).map(([category, data]) => ({
|
||||
category,
|
||||
metrics: data.sort((a, b) => Number(a.name > b.name) - 0.5),
|
||||
}));
|
||||
setCategoryData(result);
|
||||
};
|
||||
|
||||
const formateSelectedKeys = () => {
|
||||
const newKeys = indicatorSelectModule.selectedRows;
|
||||
const result: SelectedMetrics = {};
|
||||
const selectedCategories: string[] = [];
|
||||
|
||||
newKeys.forEach((name: string) => {
|
||||
const metricDefine = global.getMetricDefine(indicatorSelectModule?.metricType, name);
|
||||
if (metricDefine) {
|
||||
if (!result[metricDefine.category]) {
|
||||
result[metricDefine.category] = [name];
|
||||
} else {
|
||||
result[metricDefine.category].push(name);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Object.entries(result).forEach(([curCategory, metrics]) => {
|
||||
if (metrics.length) {
|
||||
selectedCategories.push(curCategory);
|
||||
}
|
||||
});
|
||||
|
||||
setSelectedCategories(selectedCategories);
|
||||
|
||||
setChildrenSelectedRowKeys((cur) => ({
|
||||
...cur,
|
||||
...result,
|
||||
}));
|
||||
};
|
||||
|
||||
const rowChange = (newCategorys: string[]) => {
|
||||
newCategorys.sort();
|
||||
const prevCategories = selectedCategories;
|
||||
const addCategories: string[] = [];
|
||||
const delCategories: string[] = [];
|
||||
// 需要选中的指标
|
||||
newCategorys.forEach((name) => !prevCategories.includes(name) && addCategories.push(name));
|
||||
// 取消选中的指标
|
||||
prevCategories.forEach((name) => !newCategorys.includes(name) && delCategories.push(name));
|
||||
|
||||
const changedCategories: SelectedMetrics = {};
|
||||
// 1. 选中,即选中所有子项
|
||||
addCategories.forEach((curCategory) => {
|
||||
let childrenData: string[] = [];
|
||||
categoryData.some(({ category, metrics }) => {
|
||||
if (curCategory === category) {
|
||||
childrenData = metrics.map(({ name }) => name);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
changedCategories[curCategory] = childrenData;
|
||||
});
|
||||
// 2. 取消选中,取消选中所有子项
|
||||
delCategories.forEach((curCategory) => {
|
||||
changedCategories[curCategory] = [];
|
||||
});
|
||||
|
||||
setSelectedCategories(newCategorys);
|
||||
setChildrenSelectedRowKeys((cur) => ({
|
||||
...cur,
|
||||
...changedCategories,
|
||||
}));
|
||||
};
|
||||
|
||||
const childrenRowChange = (curCategory: string, keys: string[]) => {
|
||||
// 更新选中的指标项
|
||||
setChildrenSelectedRowKeys((cur) => ({
|
||||
...cur,
|
||||
[curCategory]: keys,
|
||||
}));
|
||||
// 更新父级选中状态
|
||||
if (keys.length === 0) {
|
||||
const i = selectedCategories.indexOf(curCategory);
|
||||
if (i !== -1) {
|
||||
const newCategories = [...selectedCategories];
|
||||
newCategories.splice(i, 1);
|
||||
setSelectedCategories(newCategories);
|
||||
}
|
||||
} else {
|
||||
const curCategoryData = categoryData.find((value) => value.category === curCategory);
|
||||
if (curCategoryData.metrics.length === keys.length) {
|
||||
setSelectedCategories([...selectedCategories, curCategory]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const submitRowKeys = () => {
|
||||
setConfirmLoading(true);
|
||||
|
||||
const allRowKeys: string[] = [];
|
||||
Object.entries(childrenSelectedRowKeys).forEach(([, arr]) => allRowKeys.push(...arr));
|
||||
|
||||
indicatorSelectModule.submitCallback(allRowKeys).then(
|
||||
() => {
|
||||
setConfirmLoading(false);
|
||||
onClose();
|
||||
},
|
||||
() => {
|
||||
setConfirmLoading(false);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const rowSelection = {
|
||||
selectedRowKeys: selectedCategories,
|
||||
onChange: rowChange,
|
||||
// getCheckboxProps: (record: any) => indicatorSelectModule.checkboxProps && indicatorSelectModule.checkboxProps(record),
|
||||
getCheckboxProps: (record: CategoryData) => {
|
||||
const isAllSelected = record.metrics.length === childrenSelectedRowKeys[record.category]?.length;
|
||||
const isNotCheck = !childrenSelectedRowKeys[record.category] || childrenSelectedRowKeys[record.category]?.length === 0;
|
||||
return {
|
||||
indeterminate: !isNotCheck && !isAllSelected,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
useEffect(formateTableData, [indicatorSelectModule.tableData]);
|
||||
|
||||
useEffect(() => {
|
||||
visible && formateSelectedKeys();
|
||||
}, [visible, indicatorSelectModule.selectedRows]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Drawer
|
||||
title={indicatorSelectModule.drawerTitle || '指标筛选'}
|
||||
width="868px"
|
||||
forceRender={true}
|
||||
onClose={onClose}
|
||||
visible={visible}
|
||||
maskClosable={false}
|
||||
extra={
|
||||
<Space>
|
||||
<Button size="small" onClick={onClose}>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
disabled={Object.entries(childrenSelectedRowKeys).every(([, arr]) => !arr.length)}
|
||||
loading={confirmLoading}
|
||||
onClick={submitRowKeys}
|
||||
>
|
||||
确定
|
||||
</Button>
|
||||
<Divider type="vertical" />
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<ProTable
|
||||
tableProps={{
|
||||
rowKey: 'category',
|
||||
columns: columns,
|
||||
dataSource: categoryData,
|
||||
attrs: {
|
||||
rowSelection: rowSelection,
|
||||
expandable: {
|
||||
expandRowByClick: true,
|
||||
expandedRowRender: (record: CategoryData) => (
|
||||
<ExpandedRow
|
||||
metrics={record.metrics}
|
||||
category={record.category}
|
||||
selectedMetrics={childrenSelectedRowKeys[record.category] || []}
|
||||
selectedMetricChange={childrenRowChange}
|
||||
/>
|
||||
),
|
||||
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);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Drawer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default IndicatorDrawer;
|
||||
Reference in New Issue
Block a user