// REQ-USR-003: KPI 合并网格(D5:CSS Grid gridRow span 复刻原型 kpi-body 合并)。
// 「导航类型」整列一格跨全部行;「角色」「子流程」按 roleSpan/subSpan 合并;空数据 → Empty。
import { Empty } from 'antd';
import type { KpiRow } from './dashboardData';
import { KPI_HEADERS } from './dashboardData';
import styles from './HomePage.module.css';
interface KpiBoardProps {
rows: KpiRow[];
/** KPI 待处理事项/描述为纯展示(蓝色链接样式),点击不跳转;保留占位以示意无导航。 */
onNavigate?: (target: string) => void;
}
export default function KpiBoard({ rows }: KpiBoardProps) {
if (!rows.length) {
return (
);
}
const total = rows.length;
// 表头行 = 第 1 行;数据行从第 2 行起
const cells: React.ReactNode[] = [];
// 表头 7 列
KPI_HEADERS.forEach((h, i) => {
cells.push(
{h}
,
);
});
// 导航类型:整列一格,跨全部数据行(复刻原型 navCell '按角色')
cells.push(
按角色
,
);
rows.forEach((row, idx) => {
const curRow = idx + 2;
const alt = idx % 2 === 1 ? styles.kpiRowAlt : '';
// 角色(带 rowSpan)
if (row.role) {
const span = row.roleSpan ?? 1;
cells.push(
{row.role}
,
);
}
// KPI 待处理事项(蓝色链接样式,纯展示)
cells.push(
{row.item}
,
);
// KPI 内容描述(蓝色链接样式,纯展示)
cells.push(
{row.desc}
,
);
// 今日未处理
cells.push(
{row.today}
,
);
// 未清总数
cells.push(
{row.total}
,
);
// 子流程(带 rowSpan)
if (row.sub && row.subSpan) {
cells.push(
{row.sub}
,
);
}
});
return (
{cells}
);
}