forked from p15670423/monkey
full logs page - replace grid component
This commit is contained in:
parent
c143987138
commit
9858f99fe8
|
@ -5525,6 +5525,11 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
},
|
||||
"lodash-es": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.4.tgz",
|
||||
"integrity": "sha1-3MHXVS4VCgZABzupyzHXDwMpUOc="
|
||||
},
|
||||
"lodash._baseassign": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
|
||||
|
@ -7443,6 +7448,14 @@
|
|||
"prop-types": "15.5.10"
|
||||
}
|
||||
},
|
||||
"react-data-components": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-data-components/-/react-data-components-1.1.1.tgz",
|
||||
"integrity": "sha512-b6gq3tXSQ0hHTH1iNoBQODQw4Y5km5vCpUV4SK7TaS6RZt4TSXxL5vbqoMToccSnImSGZdrjvx1Sp2zju+LyxA==",
|
||||
"requires": {
|
||||
"lodash": "4.17.4"
|
||||
}
|
||||
},
|
||||
"react-data-grid": {
|
||||
"version": "2.0.58",
|
||||
"resolved": "https://registry.npmjs.org/react-data-grid/-/react-data-grid-2.0.58.tgz",
|
||||
|
@ -7572,6 +7585,19 @@
|
|||
"warning": "3.0.0"
|
||||
}
|
||||
},
|
||||
"react-redux": {
|
||||
"version": "5.0.6",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.6.tgz",
|
||||
"integrity": "sha512-8taaaGu+J7PMJQDJrk/xiWEYQmdo3mkXw6wPr3K3LxvXis3Fymiq7c13S+Tpls/AyNUAsoONkU81AP0RA6y6Vw==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "2.3.1",
|
||||
"invariant": "2.2.2",
|
||||
"lodash": "4.17.4",
|
||||
"lodash-es": "4.17.4",
|
||||
"loose-envify": "1.3.1",
|
||||
"prop-types": "15.5.10"
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.2.0.tgz",
|
||||
|
@ -7752,6 +7778,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"redux": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz",
|
||||
"integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==",
|
||||
"requires": {
|
||||
"lodash": "4.17.4",
|
||||
"lodash-es": "4.17.4",
|
||||
"loose-envify": "1.3.1",
|
||||
"symbol-observable": "1.0.4"
|
||||
}
|
||||
},
|
||||
"regenerate": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz",
|
||||
|
@ -8570,6 +8607,11 @@
|
|||
"whet.extend": "0.9.9"
|
||||
}
|
||||
},
|
||||
"symbol-observable": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz",
|
||||
"integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0="
|
||||
},
|
||||
"table": {
|
||||
"version": "3.8.3",
|
||||
"resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
|
||||
|
|
|
@ -69,14 +69,16 @@
|
|||
"react": "^15.6.1",
|
||||
"react-bootstrap": "^0.31.2",
|
||||
"react-copy-to-clipboard": "^5.0.0",
|
||||
"react-data-components": "^1.1.1",
|
||||
"react-data-grid": "^2.0.58",
|
||||
"react-data-grid-addons": "^2.0.58",
|
||||
"react-dom": "^15.6.1",
|
||||
"react-fa": "^4.2.0",
|
||||
"react-graph-vis": "^0.1.3",
|
||||
"react-json-tree": "^0.10.9",
|
||||
"react-json-view": "^1.12.1",
|
||||
"react-jsonschema-form": "^0.49.0",
|
||||
"react-router-dom": "^4.2.2"
|
||||
"react-redux": "^5.0.6",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"redux": "^3.7.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import MapPage from 'components/pages/MapPage';
|
|||
import FullLogsPage from 'components/pages/FullLogsPage';
|
||||
|
||||
require('normalize.css/normalize.css');
|
||||
require('react-data-components/css/table-twbs.css');
|
||||
require('styles/App.css');
|
||||
|
||||
let logoImage = require('../images/monkey-logo.png');
|
||||
|
|
|
@ -1,143 +1,45 @@
|
|||
import React from 'react';
|
||||
import {Col} from 'react-bootstrap';
|
||||
import ReactJson from 'react-json-view'
|
||||
import JSONTree from 'react-json-tree'
|
||||
import ReactDataGrid, {Row} from 'react-data-grid';
|
||||
import {Icon} from "react-fa";
|
||||
const { Toolbar, Data: { Selectors } } = require('react-data-grid-addons');
|
||||
import {DataTable} from 'react-data-components';
|
||||
|
||||
// Custom Formatter component
|
||||
const JsonCellFormatter = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<ReactJson src={this.props.value} collapsed={true} />
|
||||
);
|
||||
}
|
||||
});
|
||||
const renderJson = (val, row) => <JSONTree data={val} level={1} theme="eighties" invertTheme={true} />;
|
||||
const renderTime = (val, row) => val.split('.')[0];
|
||||
|
||||
const RowRenderer = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Row ref={ node => this.row = node } {...this.props}/>
|
||||
);
|
||||
}
|
||||
// height: '50px',
|
||||
//
|
||||
// onClick() {
|
||||
// this.height = '200px';
|
||||
// },
|
||||
//
|
||||
// render() {
|
||||
// return (
|
||||
// <div style={{height: this.height}} onClick={this.onClick}>
|
||||
// <Icon name="expand" className="pull-right"/>
|
||||
// <Row style={{minHeight: '100px'}} ref={ node => this.row = node } {...this.props}/>
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
});
|
||||
const columns = [
|
||||
{ title: 'Type', prop: 'telem_type' },
|
||||
{ title: 'Monkey ID', prop: 'monkey_guid' },
|
||||
{ title: 'Time', prop: 'timestamp', render: renderTime},
|
||||
{ title: 'More Info', prop: 'data', render: renderJson, width: '40%' }
|
||||
];
|
||||
|
||||
class FullLogsPageComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
...this.getInitialState()
|
||||
data: []
|
||||
};
|
||||
}
|
||||
|
||||
getInitialState() {
|
||||
this._columns = [
|
||||
{
|
||||
key: 'telem_type',
|
||||
name: 'Type',
|
||||
width: 200,
|
||||
filterable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: 'monkey_guid',
|
||||
name: 'Monkey ID',
|
||||
filterable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: 'timestamp',
|
||||
name: 'Time',
|
||||
filterable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: 'data',
|
||||
name: 'More Info',
|
||||
formatter: JsonCellFormatter
|
||||
}
|
||||
];
|
||||
|
||||
return { rows: [], filters: {}, sortColumn: null, sortDirection: null };
|
||||
}
|
||||
|
||||
getRandomDate(start, end) {
|
||||
return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toLocaleDateString();
|
||||
}
|
||||
|
||||
getRows() {
|
||||
return Selectors.getRows(this.state);
|
||||
}
|
||||
|
||||
getSize() {
|
||||
return this.getRows().length;
|
||||
}
|
||||
|
||||
rowGetter = (rowIdx) => {
|
||||
const rows = this.getRows();
|
||||
return rows[rowIdx];
|
||||
};
|
||||
|
||||
handleGridSort = (sortColumn, sortDirection) => {
|
||||
this.setState({ sortColumn: sortColumn, sortDirection: sortDirection });
|
||||
};
|
||||
|
||||
handleFilterChange = (filter) => {
|
||||
let newFilters = Object.assign({}, this.state.filters);
|
||||
if (filter.filterTerm) {
|
||||
newFilters[filter.column.key] = filter;
|
||||
} else {
|
||||
delete newFilters[filter.column.key];
|
||||
}
|
||||
|
||||
this.setState({ filters: newFilters });
|
||||
};
|
||||
|
||||
onClearFilters = () => {
|
||||
this.setState({ filters: {} });
|
||||
};
|
||||
|
||||
componentDidMount = () => {
|
||||
this.dataGrid.setState({canFilter: true}, () => this.hideFilterButton());
|
||||
fetch('/api/telemetry')
|
||||
.then(res => res.json())
|
||||
.then(res => this.setState({rows: res.objects}));
|
||||
.then(res => this.setState({data: res.objects}));
|
||||
};
|
||||
|
||||
hideFilterButton = () => document.getElementsByClassName('react-grid-Toolbar')[0].style.display = 'none';
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Col xs={12}>
|
||||
<h1 className="page-title">Full Logs</h1>
|
||||
<div>
|
||||
<ReactDataGrid
|
||||
ref={(grid) => { this.dataGrid = grid; }}
|
||||
rowRenderer={RowRenderer}
|
||||
rowHeight={50}
|
||||
minHeight={500}
|
||||
columns={this._columns}
|
||||
toolbar={<Toolbar enableFilter={true}/>}
|
||||
rowGetter={this.rowGetter}
|
||||
rowsCount={this.getSize()}
|
||||
onGridSort={this.handleGridSort}
|
||||
onAddFilter={this.handleFilterChange}
|
||||
onClearFilters={this.onClearFilters} />
|
||||
<div className="data-table-container">
|
||||
<DataTable
|
||||
keys="name"
|
||||
columns={columns}
|
||||
initialData={this.state.data}
|
||||
initialPageLength={20}
|
||||
initialSortBy={{ prop: 'timestamp', order: 'descending' }}
|
||||
pageLengthOptions={[ 20, 50, 100 ]}
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
);
|
||||
|
|
|
@ -154,28 +154,32 @@ body {
|
|||
* Map Preview Pane
|
||||
*/
|
||||
|
||||
.preview.well {
|
||||
padding: 1em;
|
||||
.preview-pane {
|
||||
background: #f5f5f5;
|
||||
border-left: 1px solid #e8e8e8;
|
||||
border-bottom: 3px solid #e8e8e8;
|
||||
padding: 1.5em 1em;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.preview h3 {
|
||||
.preview-pane h3 {
|
||||
margin: 0;
|
||||
|
||||
}
|
||||
.preview h3 small {
|
||||
.preview-pane h3 small {
|
||||
margin-top: 0.5em;
|
||||
display: block;
|
||||
}
|
||||
.preview h3 .fa {
|
||||
.preview-pane h3 .fa {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.preview h4 {
|
||||
.preview-pane h4 {
|
||||
text-transform: uppercase;
|
||||
color: #999;
|
||||
font-size: 1em;
|
||||
margin-top: 0;
|
||||
}
|
||||
.preview p, .preview .timeline {
|
||||
.preview-pane p, .preview-pane .timeline {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
|
@ -217,3 +221,35 @@ body {
|
|||
.timeline .bullet.bad {
|
||||
background: #d30d09;
|
||||
}
|
||||
|
||||
/*
|
||||
* Full Logs Page
|
||||
*/
|
||||
|
||||
.data-table-container > .container {
|
||||
width: inherit;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.data-table-container > .container th , .data-table-container > .container td {
|
||||
padding: 15px 8px;
|
||||
}
|
||||
|
||||
#search-field , #page-menu {
|
||||
margin-left: 1em;
|
||||
margin-bottom: 1em;
|
||||
height: 34px;
|
||||
padding: 6px 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.42857143;
|
||||
color: #555;
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
|
||||
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue