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",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
"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": {
|
"lodash._baseassign": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
|
||||||
|
@ -7443,6 +7448,14 @@
|
||||||
"prop-types": "15.5.10"
|
"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": {
|
"react-data-grid": {
|
||||||
"version": "2.0.58",
|
"version": "2.0.58",
|
||||||
"resolved": "https://registry.npmjs.org/react-data-grid/-/react-data-grid-2.0.58.tgz",
|
"resolved": "https://registry.npmjs.org/react-data-grid/-/react-data-grid-2.0.58.tgz",
|
||||||
|
@ -7572,6 +7585,19 @@
|
||||||
"warning": "3.0.0"
|
"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": {
|
"react-router": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.2.0.tgz",
|
"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": {
|
"regenerate": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz",
|
||||||
|
@ -8570,6 +8607,11 @@
|
||||||
"whet.extend": "0.9.9"
|
"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": {
|
"table": {
|
||||||
"version": "3.8.3",
|
"version": "3.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
|
||||||
|
|
|
@ -69,14 +69,16 @@
|
||||||
"react": "^15.6.1",
|
"react": "^15.6.1",
|
||||||
"react-bootstrap": "^0.31.2",
|
"react-bootstrap": "^0.31.2",
|
||||||
"react-copy-to-clipboard": "^5.0.0",
|
"react-copy-to-clipboard": "^5.0.0",
|
||||||
|
"react-data-components": "^1.1.1",
|
||||||
"react-data-grid": "^2.0.58",
|
"react-data-grid": "^2.0.58",
|
||||||
"react-data-grid-addons": "^2.0.58",
|
"react-data-grid-addons": "^2.0.58",
|
||||||
"react-dom": "^15.6.1",
|
"react-dom": "^15.6.1",
|
||||||
"react-fa": "^4.2.0",
|
"react-fa": "^4.2.0",
|
||||||
"react-graph-vis": "^0.1.3",
|
"react-graph-vis": "^0.1.3",
|
||||||
"react-json-tree": "^0.10.9",
|
"react-json-tree": "^0.10.9",
|
||||||
"react-json-view": "^1.12.1",
|
|
||||||
"react-jsonschema-form": "^0.49.0",
|
"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';
|
import FullLogsPage from 'components/pages/FullLogsPage';
|
||||||
|
|
||||||
require('normalize.css/normalize.css');
|
require('normalize.css/normalize.css');
|
||||||
|
require('react-data-components/css/table-twbs.css');
|
||||||
require('styles/App.css');
|
require('styles/App.css');
|
||||||
|
|
||||||
let logoImage = require('../images/monkey-logo.png');
|
let logoImage = require('../images/monkey-logo.png');
|
||||||
|
|
|
@ -1,143 +1,45 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Col} from 'react-bootstrap';
|
import {Col} from 'react-bootstrap';
|
||||||
import ReactJson from 'react-json-view'
|
|
||||||
import JSONTree from 'react-json-tree'
|
import JSONTree from 'react-json-tree'
|
||||||
import ReactDataGrid, {Row} from 'react-data-grid';
|
import {DataTable} from 'react-data-components';
|
||||||
import {Icon} from "react-fa";
|
|
||||||
const { Toolbar, Data: { Selectors } } = require('react-data-grid-addons');
|
|
||||||
|
|
||||||
// Custom Formatter component
|
const renderJson = (val, row) => <JSONTree data={val} level={1} theme="eighties" invertTheme={true} />;
|
||||||
const JsonCellFormatter = React.createClass({
|
const renderTime = (val, row) => val.split('.')[0];
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<ReactJson src={this.props.value} collapsed={true} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const RowRenderer = React.createClass({
|
const columns = [
|
||||||
render() {
|
{ title: 'Type', prop: 'telem_type' },
|
||||||
return (
|
{ title: 'Monkey ID', prop: 'monkey_guid' },
|
||||||
<Row ref={ node => this.row = node } {...this.props}/>
|
{ title: 'Time', prop: 'timestamp', render: renderTime},
|
||||||
);
|
{ title: 'More Info', prop: 'data', render: renderJson, width: '40%' }
|
||||||
}
|
];
|
||||||
// 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>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
|
|
||||||
class FullLogsPageComponent extends React.Component {
|
class FullLogsPageComponent extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
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 = () => {
|
componentDidMount = () => {
|
||||||
this.dataGrid.setState({canFilter: true}, () => this.hideFilterButton());
|
|
||||||
fetch('/api/telemetry')
|
fetch('/api/telemetry')
|
||||||
.then(res => res.json())
|
.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() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Col xs={12}>
|
<Col xs={12}>
|
||||||
<h1 className="page-title">Full Logs</h1>
|
<h1 className="page-title">Full Logs</h1>
|
||||||
<div>
|
<div className="data-table-container">
|
||||||
<ReactDataGrid
|
<DataTable
|
||||||
ref={(grid) => { this.dataGrid = grid; }}
|
keys="name"
|
||||||
rowRenderer={RowRenderer}
|
columns={columns}
|
||||||
rowHeight={50}
|
initialData={this.state.data}
|
||||||
minHeight={500}
|
initialPageLength={20}
|
||||||
columns={this._columns}
|
initialSortBy={{ prop: 'timestamp', order: 'descending' }}
|
||||||
toolbar={<Toolbar enableFilter={true}/>}
|
pageLengthOptions={[ 20, 50, 100 ]}
|
||||||
rowGetter={this.rowGetter}
|
/>
|
||||||
rowsCount={this.getSize()}
|
|
||||||
onGridSort={this.handleGridSort}
|
|
||||||
onAddFilter={this.handleFilterChange}
|
|
||||||
onClearFilters={this.onClearFilters} />
|
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
|
|
|
@ -154,28 +154,32 @@ body {
|
||||||
* Map Preview Pane
|
* Map Preview Pane
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.preview.well {
|
.preview-pane {
|
||||||
padding: 1em;
|
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;
|
margin: 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
.preview h3 small {
|
.preview-pane h3 small {
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.preview h3 .fa {
|
.preview-pane h3 .fa {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
.preview h4 {
|
.preview-pane h4 {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: #999;
|
color: #999;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
.preview p, .preview .timeline {
|
.preview-pane p, .preview-pane .timeline {
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,3 +221,35 @@ body {
|
||||||
.timeline .bullet.bad {
|
.timeline .bullet.bad {
|
||||||
background: #d30d09;
|
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