2018-10-17 07:58:04 -05:00
|
|
|
import _ from 'lodash';
|
2018-04-26 04:58:42 -05:00
|
|
|
import React, { PureComponent } from 'react';
|
2019-07-30 08:49:32 -05:00
|
|
|
import ReactTable, { RowInfo } from 'react-table';
|
2018-10-17 07:58:04 -05:00
|
|
|
|
2018-08-03 03:20:13 -05:00
|
|
|
import TableModel from 'app/core/table_model';
|
2018-04-26 04:58:42 -05:00
|
|
|
|
2018-08-03 03:20:13 -05:00
|
|
|
const EMPTY_TABLE = new TableModel();
|
2018-10-19 08:29:58 -05:00
|
|
|
// Identify columns that contain values
|
|
|
|
const VALUE_REGEX = /^[Vv]alue #\d+/;
|
2018-04-26 04:58:42 -05:00
|
|
|
|
2018-08-03 03:20:13 -05:00
|
|
|
interface TableProps {
|
|
|
|
data: TableModel;
|
2018-08-04 04:07:48 -05:00
|
|
|
loading: boolean;
|
2018-08-03 03:20:13 -05:00
|
|
|
onClickCell?: (columnKey: string, rowValue: string) => void;
|
|
|
|
}
|
|
|
|
|
2019-07-30 08:49:32 -05:00
|
|
|
function prepareRows(rows: any[], columnNames: string[]) {
|
2018-10-17 07:58:04 -05:00
|
|
|
return rows.map(cells => _.zipObject(columnNames, cells));
|
2018-08-03 03:20:13 -05:00
|
|
|
}
|
|
|
|
|
2018-10-18 03:42:25 -05:00
|
|
|
export default class Table extends PureComponent<TableProps> {
|
2019-07-30 08:49:32 -05:00
|
|
|
getCellProps = (state: any, rowInfo: RowInfo, column: any) => {
|
2018-10-17 07:58:04 -05:00
|
|
|
return {
|
2018-10-29 10:44:50 -05:00
|
|
|
onClick: (e: React.SyntheticEvent) => {
|
|
|
|
// Only handle click on link, not the cell
|
|
|
|
if (e.target) {
|
|
|
|
const link = e.target as HTMLElement;
|
|
|
|
if (link.className === 'link') {
|
2019-05-15 04:43:27 -05:00
|
|
|
const columnKey = column.Header().props.title;
|
2018-10-29 10:44:50 -05:00
|
|
|
const rowValue = rowInfo.row[columnKey];
|
2019-11-26 03:01:32 -06:00
|
|
|
this.props.onClickCell?.(columnKey, rowValue);
|
2018-10-29 10:44:50 -05:00
|
|
|
}
|
|
|
|
}
|
2018-10-17 07:58:04 -05:00
|
|
|
},
|
2018-08-03 03:20:13 -05:00
|
|
|
};
|
2018-10-17 07:58:04 -05:00
|
|
|
};
|
2018-08-03 03:20:13 -05:00
|
|
|
|
2018-04-26 04:58:42 -05:00
|
|
|
render() {
|
2018-10-17 07:58:04 -05:00
|
|
|
const { data, loading } = this.props;
|
2018-08-26 10:14:40 -05:00
|
|
|
const tableModel = data || EMPTY_TABLE;
|
2018-10-17 07:58:04 -05:00
|
|
|
const columnNames = tableModel.columns.map(({ text }) => text);
|
|
|
|
const columns = tableModel.columns.map(({ filterable, text }) => ({
|
2019-03-15 08:11:40 -05:00
|
|
|
Header: () => <span title={text}>{text}</span>,
|
2018-10-17 07:58:04 -05:00
|
|
|
accessor: text,
|
2018-10-19 08:29:58 -05:00
|
|
|
className: VALUE_REGEX.test(text) ? 'text-right' : '',
|
2018-10-17 07:58:04 -05:00
|
|
|
show: text !== 'Time',
|
2019-07-30 08:49:32 -05:00
|
|
|
Cell: (row: any) => (
|
2019-03-15 08:11:40 -05:00
|
|
|
<span className={filterable ? 'link' : ''} title={text + ': ' + row.value}>
|
2019-09-04 03:49:09 -05:00
|
|
|
{typeof row.value === 'string' ? row.value : JSON.stringify(row.value)}
|
2019-03-15 08:11:40 -05:00
|
|
|
</span>
|
|
|
|
),
|
2018-10-17 07:58:04 -05:00
|
|
|
}));
|
2018-10-18 03:42:25 -05:00
|
|
|
const noDataText = data ? 'The queries returned no data for a table.' : '';
|
2018-10-17 07:58:04 -05:00
|
|
|
|
2018-04-26 04:58:42 -05:00
|
|
|
return (
|
2018-10-17 07:58:04 -05:00
|
|
|
<ReactTable
|
|
|
|
columns={columns}
|
|
|
|
data={tableModel.rows}
|
|
|
|
getTdProps={this.getCellProps}
|
|
|
|
loading={loading}
|
|
|
|
minRows={0}
|
2018-10-18 03:42:25 -05:00
|
|
|
noDataText={noDataText}
|
2018-10-17 07:58:04 -05:00
|
|
|
resolveData={data => prepareRows(data, columnNames)}
|
2018-10-22 10:51:42 -05:00
|
|
|
showPagination={Boolean(data)}
|
2018-10-17 07:58:04 -05:00
|
|
|
/>
|
2018-04-26 04:58:42 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|