2
0

TaskTable.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import { useEffect, useState } from "react";
  2. import type { IProject, ITaskData } from "../../api/task";
  3. import "../article/article.css";
  4. import TaskTableCell from "./TaskTableCell";
  5. interface ITaskHeading {
  6. id: string;
  7. title: string;
  8. children: number;
  9. }
  10. interface IWidget {
  11. tasks?: ITaskData[];
  12. onChange?: (treeData: ITaskData[]) => void;
  13. }
  14. const TaskTable = ({ tasks, onChange }: IWidget) => {
  15. const [tasksTitle, setTasksTitle] = useState<ITaskHeading[][]>();
  16. const [dataHeading, setDataHeading] = useState<string[]>();
  17. const [projects, setProjects] = useState<IProject[]>();
  18. useEffect(() => {
  19. const projectsId = new Map<string, number>();
  20. const projectMap = new Map<string, IProject>();
  21. tasks?.forEach((task) => {
  22. if (task.project_id && task.project) {
  23. if (projectsId.has(task.project_id)) {
  24. projectsId.set(task.project_id, projectsId.get(task.project_id)! + 1);
  25. } else {
  26. projectsId.set(task.project_id, 1);
  27. projectMap.set(task.project_id, task.project);
  28. }
  29. }
  30. });
  31. setProjects(Array.from(projectMap.values()));
  32. const getNodeChildren = (task: ITaskData): number => {
  33. const children = tasks?.filter((value) => value.parent_id === task.id);
  34. if (children && children.length > 0) {
  35. return children.reduce((acc, cur) => {
  36. return acc + getNodeChildren(cur);
  37. }, children.length);
  38. } else {
  39. return 0;
  40. }
  41. };
  42. //列表头
  43. const titles1: ITaskHeading[] = [];
  44. let titles2: ITaskHeading[] = [];
  45. let titles3: string[] = [];
  46. const tRoot = new Map<string, ITaskData>();
  47. tasks
  48. ?.filter((value: ITaskData) => !value.parent_id)
  49. .forEach((task) => {
  50. tRoot.set(task.title, task);
  51. });
  52. console.debug("tasks", tasks);
  53. tRoot.forEach((task) => {
  54. const children = tasks
  55. ?.filter((value1) => value1.parent_id === task.id)
  56. .map((task1) => {
  57. const child: ITaskHeading = {
  58. id: task1.id,
  59. title: task1.title ?? "",
  60. children: 0,
  61. };
  62. return child;
  63. });
  64. console.debug("task children", task.title, children);
  65. if (children) {
  66. titles2 = [...titles2, ...children];
  67. }
  68. titles1.push({
  69. title: task.title ?? "",
  70. id: task.id,
  71. children: getNodeChildren(task),
  72. });
  73. if (children && children.length > 0) {
  74. titles3 = [...titles3, ...children.map((item) => item.title)];
  75. } else {
  76. titles3.push(task.title);
  77. }
  78. });
  79. const heading = [titles1, titles2];
  80. console.log("heading", heading);
  81. setTasksTitle(heading);
  82. setDataHeading(titles3);
  83. }, [tasks]);
  84. return (
  85. <div className="pcd_article">
  86. <table>
  87. <thead>
  88. {tasksTitle?.map((row, level) => {
  89. return (
  90. <tr>
  91. {level === 0 ? (
  92. <>
  93. <th rowSpan={2}>project</th>
  94. <th>weight</th>
  95. </>
  96. ) : undefined}
  97. {row.map((task, index) => {
  98. return (
  99. <th
  100. key={index}
  101. colSpan={task.children === 0 ? undefined : task.children}
  102. rowSpan={task.children === 0 ? 2 : undefined}
  103. >
  104. {task.title}
  105. </th>
  106. );
  107. })}
  108. </tr>
  109. );
  110. })}
  111. </thead>
  112. <tbody>
  113. {projects
  114. ?.sort((a, b) => a.sn - b.sn)
  115. .map((row, index) => (
  116. <tr key={index}>
  117. <td key={"title"}>{row.title}</td>
  118. <td key={"weight"}>{row.weight}</td>
  119. {dataHeading?.map((task, id) => {
  120. const taskData = tasks?.find(
  121. (value: ITaskData) =>
  122. value.title === task && value.project_id === row.id
  123. );
  124. return (
  125. <td key={id}>
  126. <TaskTableCell task={taskData} onChange={onChange} />
  127. </td>
  128. );
  129. })}
  130. </tr>
  131. ))}
  132. </tbody>
  133. </table>
  134. </div>
  135. );
  136. };
  137. export default TaskTable;