trust-module-frontend/src/Components/UI/TreeTable.jsx

150 lines
6.5 KiB
JavaScript

import React, { useEffect, useRef, useState } from "react";
import "../../Style/TreeTable.css";
import { statusManager1, statusManager2 } from "../TreeChart/dataUtils";
const TreeTable = ({ data }) => {
const tableRef = useRef(null);
const [fontSize, setFontSize] = useState(16);
const [log, setLog] = useState([]);
const [isLogVisible, setIsLogVisible] = useState(true);
const adjustFontSize = () => {
if (tableRef.current) {
let newSize = 16;
const maxWidth = window.innerWidth;
while (tableRef.current.scrollWidth > maxWidth && newSize > 10) {
newSize -= 1;
tableRef.current.style.fontSize = `${newSize}px`;
}
while (tableRef.current.scrollWidth < maxWidth && newSize < 16) {
newSize += 1;
tableRef.current.style.fontSize = `${newSize}px`;
}
setFontSize(newSize);
}
};
useEffect(() => {
adjustFontSize();
window.addEventListener("resize", adjustFontSize);
return () => window.removeEventListener("resize", adjustFontSize);
}, [data]);
useEffect(() => {
const newLog = [];
const traverse = (items) => {
items.forEach((item) => {
if (["yellow", "orange", "red"].includes(item.status)) {
newLog.push({
title: item.title,
status: item.status,
time: new Date().toLocaleTimeString() // Добавляем время
});
}
if (item.items) {
traverse(item.items);
}
});
};
traverse(data.items);
setLog(newLog);
}, [data]);
const filteredData = data.items.filter((item) => item.title !== "Функциональные задачи");
const renderHeaders = (items) => {
return items.map((item) => {
const colSpan = item.items ? item.items.length : 1;
return (
<th key={item.id} colSpan={colSpan} className="tree-table-header" title={item.title}>
<div className="header-content">
<div className="status-indicator-bar" style={{ backgroundColor: statusManager1.getStatusColor(item.status) }} />
<div className="status-indicator-bar" style={{ backgroundColor: statusManager2.getStatusColor(item.status), marginLeft: "5px" }} />
{item.title}
</div>
</th>
);
});
};
const renderRows = (items) => {
if (!items || items.length === 0) return null;
const hasChildren = items.some((item) => item.items && item.items.length > 0);
if (!hasChildren) return null;
return (
<tr className="tree-table-row">
{items.map((item) => {
if (item.items && item.items.length > 0) {
return (
<React.Fragment key={item.id}>
{item.items.map((child) => (
<td key={child.id} className="tree-table-cell" title={child.title}>
<div className="cell-content">
<div className="status-indicator-bar" style={{ backgroundColor: statusManager1.getStatusColor(child.status) }} />
<div className="status-indicator-bar" style={{ backgroundColor: statusManager2.getStatusColor(child.status), marginLeft: "5px" }} />
{child.title}
</div>
</td>
))}
</React.Fragment>
);
} else {
return (
<td key={item.id} className="tree-table-cell" title={item.title}>
<div className="cell-content">
<div className="status-indicator-bar" style={{ backgroundColor: statusManager1.getStatusColor(item.status) }} />
<div className="status-indicator-bar" style={{ backgroundColor: statusManager2.getStatusColor(item.status), marginLeft: "5px" }} />
{item.title}
</div>
</td>
);
}
})}
</tr>
);
};
return (
<div className="tree-table-container">
<table ref={tableRef} className="tree-table" style={{ fontSize: `${fontSize}px` }}>
<thead>
<tr>
<th
colSpan={filteredData.reduce((acc, item) => acc + (item.items ? item.items.length : 1), 0)}
className="tree-table-header"
title={data.title}
>
<div className="header-content">
<div className="status-indicator-bar" style={{ backgroundColor: statusManager1.getStatusColor(data.status) }} />
<div className="status-indicator-bar" style={{ backgroundColor: statusManager2.getStatusColor(data.status), marginLeft: "5px" }} />
{data.title}
</div>
</th>
</tr>
<tr>{renderHeaders(filteredData)}</tr>
</thead>
<tbody>{renderRows(filteredData)}</tbody>
</table>
<button onClick={() => setIsLogVisible(!isLogVisible)} className="toggle-log-button">
{isLogVisible ? "Скрыть лог" : "Показать лог"}
</button>
{isLogVisible && (
<div className="status-log">
<h3>Лог статусов</h3>
<ul>
{log.map((entry, index) => (
<li key={index} style={{ color: statusManager1.getStatusColor(entry.status) }}>
[{entry.time}] {entry.status}: {entry.title}
</li>
))}
</ul>
</div>
)}
</div>
);
};
export default TreeTable;