Files
weave-scope/client/app/scripts/components/node-details/node-details-generic-table.js
Filip Barl d3466b5454 Refactored the table component/model and wrote the tests
Backward-compatibility fix
2017-01-16 17:05:36 +01:00

112 lines
3.4 KiB
JavaScript

import React from 'react';
import sortBy from 'lodash/sortBy';
import { Map as makeMap } from 'immutable';
import { NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT } from '../../constants/limits';
import {
isNumber,
getTableColumnsStyles,
genericTableEntryKey
} from '../../utils/node-details-utils';
import NodeDetailsTableHeaders from './node-details-table-headers';
import MatchedText from '../matched-text';
import ShowMore from '../show-more';
function sortedRows(rows, columns, sortedBy, sortedDesc) {
const column = columns.find(c => c.id === sortedBy);
const sorted = sortBy(rows, (row) => {
let value = row.entries[sortedBy];
if (isNumber(column)) {
value = parseFloat(value);
}
return value;
});
if (sortedDesc) {
sorted.reverse();
}
return sorted;
}
export default class NodeDetailsGenericTable extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
limit: NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT,
sortedBy: props.columns && props.columns[0].id,
sortedDesc: true
};
this.handleLimitClick = this.handleLimitClick.bind(this);
this.updateSorted = this.updateSorted.bind(this);
}
updateSorted(sortedBy, sortedDesc) {
this.setState({ sortedBy, sortedDesc });
}
handleLimitClick() {
this.setState({
limit: this.state.limit ? 0 : NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT
});
}
render() {
const { sortedBy, sortedDesc } = this.state;
const { columns, matches = makeMap() } = this.props;
const expanded = this.state.limit === 0;
let rows = this.props.rows || [];
let notShown = 0;
// If there are rows that would be hidden behind 'show more', keep them
// expanded if any of them match the search query; otherwise hide them.
if (this.state.limit > 0 && rows.length > this.state.limit) {
const hasHiddenMatch = rows.slice(this.state.limit).some(row =>
columns.some(column => matches.has(genericTableEntryKey(row, column)))
);
if (!hasHiddenMatch) {
notShown = rows.length - NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT;
rows = rows.slice(0, this.state.limit);
}
}
const styles = getTableColumnsStyles(columns);
return (
<div className="node-details-generic-table">
<table>
<thead>
<NodeDetailsTableHeaders
headers={columns}
sortedBy={sortedBy}
sortedDesc={sortedDesc}
onClick={this.updateSorted}
/>
</thead>
<tbody>
{sortedRows(rows, columns, sortedBy, sortedDesc).map(row => (
<tr className="node-details-generic-table-row" key={row.id}>
{columns.map((column, index) => {
const match = matches.get(genericTableEntryKey(row, column));
const value = row.entries[column.id];
return (
<td
className="node-details-generic-table-value truncate"
title={value} key={column.id} style={styles[index]}>
<MatchedText text={value} match={match} />
</td>
);
})}
</tr>
))}
</tbody>
</table>
<ShowMore
handleClick={this.handleLimitClick} collection={this.props.rows}
expanded={expanded} notShown={notShown}
/>
</div>
);
}
}