Files
KnowStreaming/km-console/packages/layout-clusters-fe/src/components/SingleChartHeader/IndicatorDrawer.tsx
2022-08-23 19:01:53 +08:00

324 lines
9.3 KiB
TypeScript

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
className="indicator-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={{
showHeader: false,
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;