Commit ff67213b by David Kaltschmidt

Explore: Use react-table as table component

- adds react-table as dependency
- replaces custom table component in Explore
- vendors react-table styles and overrides them (currently in
  explore.scss)
parent a825f42a
...@@ -160,6 +160,7 @@ ...@@ -160,6 +160,7 @@
"react-redux": "^5.0.7", "react-redux": "^5.0.7",
"react-select": "2.1.0", "react-select": "2.1.0",
"react-sizeme": "^2.3.6", "react-sizeme": "^2.3.6",
"react-table": "^6.8.6",
"react-transition-group": "^2.2.1", "react-transition-group": "^2.2.1",
"redux": "^4.0.0", "redux": "^4.0.0",
"redux-logger": "^3.0.6", "redux-logger": "^3.0.6",
......
...@@ -644,7 +644,9 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> { ...@@ -644,7 +644,9 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
/> />
)} )}
{supportsTable && showingTable ? ( {supportsTable && showingTable ? (
<div className="panel-container">
<Table className="m-t-3" data={tableResult} loading={loading} onClickCell={this.onClickTableCell} /> <Table className="m-t-3" data={tableResult} loading={loading} onClickCell={this.onClickTableCell} />
</div>
) : null} ) : null}
{supportsLogs && showingLogs ? <Logs data={logsResult} loading={loading} /> : null} {supportsLogs && showingLogs ? <Logs data={logsResult} loading={loading} /> : null}
</main> </main>
......
import _ from 'lodash';
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import ReactTable from 'react-table';
import TableModel from 'app/core/table_model'; import TableModel from 'app/core/table_model';
const EMPTY_TABLE = new TableModel(); const EMPTY_TABLE = new TableModel();
...@@ -10,75 +13,42 @@ interface TableProps { ...@@ -10,75 +13,42 @@ interface TableProps {
onClickCell?: (columnKey: string, rowValue: string) => void; onClickCell?: (columnKey: string, rowValue: string) => void;
} }
interface SFCCellProps { function prepareRows(rows, columnNames) {
columnIndex: number; return rows.map(cells => _.zipObject(columnNames, cells));
onClickCell?: (columnKey: string, rowValue: string, columnIndex: number, rowIndex: number, table: TableModel) => void;
rowIndex: number;
table: TableModel;
value: string;
} }
function Cell(props: SFCCellProps) { export default class Table extends PureComponent<TableProps, {}> {
const { columnIndex, rowIndex, table, value, onClickCell } = props; getCellProps = (state, rowInfo, column) => {
const column = table.columns[columnIndex]; return {
if (column && column.filterable && onClickCell) { onClick: () => {
const onClick = event => { const columnKey = column.Header;
event.preventDefault(); const rowValue = rowInfo.row[columnKey];
onClickCell(column.text, value, columnIndex, rowIndex, table); this.props.onClickCell(columnKey, rowValue);
},
};
}; };
return (
<td>
<a className="link" onClick={onClick}>
{value}
</a>
</td>
);
}
return <td>{value}</td>;
}
export default class Table extends PureComponent<TableProps, {}> {
render() { render() {
const { className = '', data, loading, onClickCell } = this.props; const { data, loading } = this.props;
const tableModel = data || EMPTY_TABLE; const tableModel = data || EMPTY_TABLE;
if (!loading && data && data.rows.length === 0) { const columnNames = tableModel.columns.map(({ text }) => text);
return ( const columns = tableModel.columns.map(({ filterable, text }) => ({
<table className={`${className} filter-table`}> Header: text,
<thead> accessor: text,
<tr> show: text !== 'Time',
<th>Table</th> Cell: row => <span className={filterable ? 'link' : ''}>{row.value}</span>,
</tr> }));
</thead>
<tbody>
<tr>
<td className="muted">The queries returned no data for a table.</td>
</tr>
</tbody>
</table>
);
}
return ( return (
<table className={`${className} filter-table`}> <ReactTable
<thead> columns={columns}
<tr>{tableModel.columns.map(col => <th key={col.text}>{col.text}</th>)}</tr> data={tableModel.rows}
</thead> getTdProps={this.getCellProps}
<tbody> loading={loading}
{tableModel.rows.map((row, i) => ( minRows={0}
<tr key={i}> noDataText="No data returned from query."
{row.map((value, j) => ( resolveData={data => prepareRows(data, columnNames)}
<Cell
key={j}
columnIndex={j}
rowIndex={i}
value={String(value)}
table={data}
onClickCell={onClickCell}
/> />
))}
</tr>
))}
</tbody>
</table>
); );
} }
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
@import '../vendor/css/timepicker.css'; @import '../vendor/css/timepicker.css';
@import '../vendor/css/spectrum.css'; @import '../vendor/css/spectrum.css';
@import '../vendor/css/rc-cascader.scss'; @import '../vendor/css/rc-cascader.scss';
@import '../vendor/css/react-table.css';
// MIXINS // MIXINS
@import 'mixins/mixins'; @import 'mixins/mixins';
......
...@@ -111,6 +111,15 @@ ...@@ -111,6 +111,15 @@
.link { .link {
text-decoration: underline; text-decoration: underline;
} }
// React table
.explore-table-wrapper {
margin-top: 2 * $panel-margin;
}
.rt-tr .rt-td:last-child {
text-align: right;
}
} }
.explore + .explore { .explore + .explore {
...@@ -186,3 +195,55 @@ ...@@ -186,3 +195,55 @@
margin: 0.25em 0.5em 0.5em; margin: 0.25em 0.5em 0.5em;
} }
} }
// ReactTable basic overrides (does not include pivot/groups/filters)
// When integrating ReactTable as new panel plugin, move to _panel_table.scss
.ReactTable {
border: none;
}
.ReactTable .rt-thead.-header {
box-shadow: none;
background: $list-item-bg;
border-top: 2px solid $body-bg;
border-bottom: 2px solid $body-bg;
height: 2em;
}
.ReactTable .rt-thead.-header .rt-th {
text-align: left;
color: $blue;
font-weight: 500;
}
.ReactTable .rt-thead .rt-td,
.ReactTable .rt-thead .rt-th {
padding: 0.45em 0 0.45em 1.1em;
border-right: none;
box-shadow: none;
}
.ReactTable .rt-tbody .rt-td {
padding: 0.45em 0 0.45em 1.1em;
border-bottom: 2px solid $body-bg;
border-right: 2px solid $body-bg;
}
.ReactTable .rt-tbody .rt-td:last-child {
border-right: none;
}
.ReactTable .-pagination .-btn {
color: $blue;
background: $list-item-bg;
}
.ReactTable .-pagination input,
.ReactTable .-pagination select {
color: $input-color;
background-color: $input-bg;
}
.ReactTable .-loading {
background: $input-bg;
}
.ReactTable .-loading.-active {
opacity: 0.8;
}
.ReactTable .-loading > div {
color: $input-color;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment