full logs page - replace grid component

This commit is contained in:
Barak Argaman 2017-09-05 00:46:24 +03:00
parent c143987138
commit 9858f99fe8
5 changed files with 110 additions and 127 deletions

View File

@ -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",

View File

@ -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"
} }
} }

View File

@ -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');

View File

@ -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>
); );

View File

@ -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;
}