DocSpace-buildtools/packages/asc-web-components/table-container/TableHeader.js

189 lines
5.6 KiB
JavaScript

import React from "react";
import PropTypes from "prop-types";
import throttle from "lodash.throttle";
import Text from "../text";
import globalColors from "../utils/globalColors";
import { StyledTableHeader, StyledTableRow } from "./StyledTableContainer";
import Checkbox from "../checkbox";
import TableSettings from "./TableSettings";
const TABLE_SIZE = "tableSize";
class TableHeader extends React.Component {
constructor(props) {
super(props);
this.state = { columnIndex: null };
this.headerRef = React.createRef();
this.throttledResize = throttle(this.onResize, 0);
}
componentDidMount() {
this.onResize();
window.addEventListener("resize", this.throttledResize);
}
componentWillUnmount() {
window.removeEventListener("resize", this.throttledResize);
}
getSubstring = (str) => str.substring(0, str.length - 2);
onMouseMove = (e) => {
const { columnIndex } = this.state;
const { containerRef } = this.props;
if (!columnIndex) return;
const column = document.getElementById("column_" + columnIndex);
const columnSize = column.getBoundingClientRect();
const newWidth = e.clientX - columnSize.left;
const tableContainer = containerRef.current.style.gridTemplateColumns;
const widths = tableContainer.split(" ");
//getSubstring(widths[+columnIndex])
if (newWidth <= 150) {
widths[+columnIndex] = widths[+columnIndex];
} else {
const offset = +this.getSubstring(widths[+columnIndex]) - newWidth;
const column2Width = +this.getSubstring(widths[+columnIndex + 1]);
//getSubstring(widths[+columnIndex])
if (column2Width + offset >= 150) {
widths[+columnIndex] = newWidth + "px";
widths[+columnIndex + 1] = column2Width + offset + "px";
}
}
containerRef.current.style.gridTemplateColumns = widths.join(" ");
this.headerRef.current.style.gridTemplateColumns = widths.join(" ");
};
onMouseUp = () => {
localStorage.setItem(
TABLE_SIZE,
this.props.containerRef.current.style.gridTemplateColumns
);
window.removeEventListener("mousemove", this.onMouseMove);
window.removeEventListener("mouseup", this.onMouseUp);
};
onMouseDown = (event) => {
this.setState({ columnIndex: event.target.dataset.column });
window.addEventListener("mousemove", this.onMouseMove);
window.addEventListener("mouseup", this.onMouseUp);
};
onResize = () => {
const { containerRef } = this.props;
const container = containerRef.current
? containerRef.current
: document.getElementById("table-container");
const storageSize = localStorage.getItem(TABLE_SIZE);
const tableContainer = storageSize
? storageSize.split(" ")
: container.style.gridTemplateColumns.split(" ");
const containerWidth = +container.clientWidth;
const newContainerWidth = containerWidth - 32 - 80 - 24;
let str = "";
if (tableContainer.length > 1) {
const gridTemplateColumns = [];
const oldWidth = tableContainer
.map((column) => +this.getSubstring(column))
.reduce((x, y) => x + y);
for (let index in tableContainer) {
const item = tableContainer[index];
if (item !== "24px" && item !== "32px" && item !== "80px") {
const percent = (+this.getSubstring(item) / oldWidth) * 100;
const newItemWidth = (containerWidth * percent) / 100 + "px";
gridTemplateColumns.push(newItemWidth);
} else {
gridTemplateColumns.push(item);
}
str = gridTemplateColumns.join(" ");
}
} else {
const column = (newContainerWidth * 40) / 100 + "px";
const otherColumns = (newContainerWidth * 20) / 100 + "px";
str = `32px ${column} ${otherColumns} ${otherColumns} ${otherColumns} 80px 24px`;
}
container.style.gridTemplateColumns = str;
this.headerRef.current.style.gridTemplateColumns = str;
this.headerRef.current.style.width = containerWidth + "px";
localStorage.setItem(TABLE_SIZE, str);
};
onChange = (checked) => {
this.props.setSelected(checked ? "all" : "none");
};
render() {
const { columns, ...rest } = this.props;
return (
<StyledTableHeader
className="table-container_header"
ref={this.headerRef}
{...rest}
>
<StyledTableRow>
<Checkbox onChange={this.onChange} checked={false} />
{columns.map((column, index) => {
return (
<div
className="table-container_header-cell"
id={`column_${index + 1}`}
key={column.key}
>
<div style={{ display: "flex", userSelect: "none" }}>
<Text
fontWeight={600}
color={globalColors.gray}
className="header-container"
>
{column.title}
</Text>
{column.resizable && (
<div
data-column={`${index + 1}`}
className="resize-handle not-selectable"
onMouseDown={this.onMouseDown}
/>
)}
</div>
</div>
);
})}
<div className="table-container_header-cell">
<TableSettings columns={columns} />
</div>
</StyledTableRow>
</StyledTableHeader>
);
}
}
TableHeader.propTypes = {
containerRef: PropTypes.shape({ current: PropTypes.any }),
columns: PropTypes.array.isRequired,
setSelected: PropTypes.func,
};
export default TableHeader;