all scrollbar

This commit is contained in:
Iuri Matias 2019-11-02 15:52:35 -04:00
parent 399d559ec5
commit 54c48b3cf9
4 changed files with 105 additions and 37 deletions

View File

@ -9,8 +9,10 @@
"ansi-to-html": "^0.6.12",
"autoscroll-react": "^3.2.0",
"bootstrap": "^4.3.1",
"jquery": "^3.4.1",
"react": "^16.11.0",
"react-bootstrap": "^1.0.0-beta.14",
"react-bootstrap-slider": "^2.2.2",
"react-dom": "^16.11.0",
"react-json-view": "^1.19.1",
"react-scripts": "3.2.0",

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, {useState} from 'react';
import { SearchState, SortingState, IntegratedSorting, TreeDataState, CustomTreeData, FilteringState, IntegratedFiltering, TableColumnVisibility } from '@devexpress/dx-react-grid';
import { Grid, Table, TableHeaderRow, TableTreeColumn, TableFilterRow, SearchPanel, Toolbar, ColumnChooser } from '@devexpress/dx-react-grid-bootstrap4';
import Convert from 'ansi-to-html';
@ -6,6 +6,8 @@ import stripAnsi from 'strip-ansi';
import ReactJson from 'react-json-view';
import './App.css';
import Logs from './Logs.js';
import {Button, Card, Collapse} from 'react-bootstrap';
import ReactBootstrapSlider from 'react-bootstrap-slider';
import all_data from './log.json'
@ -18,6 +20,26 @@ let session_object = Object.values(all_data).find((x) => x.session === x.id)
let data = [session_object];
function Section({title, children}) {
const [open, setOpen] = useState(false);
return (
<>
<Card>
<Card.Header onClick={() => setOpen(!open)} style={{"cursor": "pointer"}}>
{title}
</Card.Header>
<Collapse in={open}>
<Card.Body>
{children}
</Card.Body>
</Collapse>
</Card>
</>
);
}
class App extends React.PureComponent {
constructor(props) {
@ -25,6 +47,7 @@ class App extends React.PureComponent {
this.state = {
current_index: 0,
max_index: all_data_ordered.length,
logs: [],
current: session_object,
columns: [
@ -52,9 +75,7 @@ class App extends React.PureComponent {
const nextLogs = this.state.logs.slice();
let newItem = all_data_ordered[this.state.current_index - 1]
data.pop();
if (newItem.type.indexOf("log_") === 0) {
nextLogs.pop()
}
nextLogs.pop()
this.setState({
rows: nextRows,
current_index: (this.state.current_index - 1),
@ -68,10 +89,10 @@ class App extends React.PureComponent {
const nextLogs = this.state.logs.slice();
if (!all_data_ordered[this.state.current_index]) return
let newItem = all_data_ordered[this.state.current_index]
// let convert = new Convert()
// newItem.name = convert.toHtml(newItem.name)
if (newItem.type.indexOf("log_") === 0) {
nextLogs.push(newItem.name)
} else {
nextLogs.push("") // easier to slice it after...
}
newItem.name = stripAnsi(newItem.name)
data.push(newItem)
@ -88,42 +109,69 @@ class App extends React.PureComponent {
if (row && !row.id) return []; // prevents invalid records from crashing app
return (row ? data.filter((x) => { return x.parent_id === row.id }) : rootRows)
}
this.changeValue = ({target}) => {
let value = target.value;
if (value === this.state.current_index) return;
if (value < this.state.current_index) {
let diff = this.state.current_index - value;
for (let i=0; i<diff; i++) {
this.previousLog();
}
}
if (value > this.state.current_index) {
let diff = value - this.state.current_index;
for (let i=0; i<diff; i++) {
this.nextLog();
}
}
}
}
render() {
return (
<div className="card">
<div>
step: {this.state.current_index} id: {this.state.current_id}
<button onClick={this.previousLog}>Previous</button> <button onClick={this.nextLog}>Next</button>
<ReactJson src={this.state.current} />
<Logs>
{this.state.logs.map((item, i) => {
return (
<div key={`message-${i}`}>
<p dangerouslySetInnerHTML={{ __html: (convert.toHtml(item || "")) }} />
</div>
);
})}
</Logs>
<Grid rows={this.state.rows} columns={this.state.columns} >
<TreeDataState defaultExpandedRowIds={this.state.defaultExpandedRowIds} />
<CustomTreeData getChildRows={this.getChildRows} />
<FilteringState defaultFilters={[]} />
<SearchState defaultValue="" />
<IntegratedFiltering />
<SortingState defaultSorting={[{ columnName: 'Timestamp', direction: 'asc' }]} />
<IntegratedSorting />
<Table columnExtensions={this.state.tableColumnExtensions} />
<TableHeaderRow showSortingControls />
<TableColumnVisibility
defaultHiddenColumnNames={this.state.defaultHiddenColumnNames}
/>
<Toolbar />
<SearchPanel />
<TableFilterRow showFilterSelector={true} />
<TableTreeColumn for="name" />
<ColumnChooser />
</Grid>
<button onClick={this.previousLog}>Previous</button>
<ReactBootstrapSlider min={0} max={this.state.max_index} change={this.changeValue} value={this.state.current_index} />
<button onClick={this.nextLog}>Next</button>
<div className="card">
<ReactJson src={this.state.current} theme="monokai" groupArraysAfterLength={5} name={false} />
</div>
<Section title="Console Output">
<Logs>
{this.state.logs.map((item, i) => {
return (
<div key={`message-${i}`}>
<p dangerouslySetInnerHTML={{ __html: (convert.toHtml(item || "")) }} />
</div>
);
})}
</Logs>
</Section>
<Section title="Logs">
<Grid rows={this.state.rows} columns={this.state.columns} >
<TreeDataState defaultExpandedRowIds={this.state.defaultExpandedRowIds} />
<CustomTreeData getChildRows={this.getChildRows} />
<FilteringState defaultFilters={[]} />
<SearchState defaultValue="" />
<IntegratedFiltering />
<SortingState defaultSorting={[{ columnName: 'Timestamp', direction: 'asc' }]} />
<IntegratedSorting />
<Table columnExtensions={this.state.tableColumnExtensions} />
<TableHeaderRow showSortingControls />
<TableColumnVisibility
defaultHiddenColumnNames={this.state.defaultHiddenColumnNames}
/>
<Toolbar />
<SearchPanel />
<TableFilterRow showFilterSelector={true} />
<TableTreeColumn for="name" />
<ColumnChooser />
</Grid>
</Section>
</div>
);
}

View File

@ -4,6 +4,7 @@ import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.min.css';
import "bootstrap-slider/dist/css/bootstrap-slider.css"
import '@devexpress/dx-react-grid-bootstrap4/dist/dx-react-grid-bootstrap4.css';
ReactDOM.render(<App />, document.getElementById('root'));

View File

@ -2153,6 +2153,11 @@ boolbase@^1.0.0, boolbase@~1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
bootstrap-slider@^10.6.1:
version "10.6.2"
resolved "https://registry.yarnpkg.com/bootstrap-slider/-/bootstrap-slider-10.6.2.tgz#7341f468c012bdaa6a1d8625d989fdeb8ed7dd38"
integrity sha512-8JTPZB9QVOdrGzYF3YgC3YW6ssfPeBvBwZnXffiZ7YH/zz1D0EKlZvmQsm/w3N0XjVNYQEoQ0ax+jHrErV4K1Q==
bootstrap@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.3.1.tgz#280ca8f610504d99d7b6b4bfc4b68cec601704ac"
@ -5750,6 +5755,11 @@ jest@24.9.0:
import-local "^2.0.0"
jest-cli "^24.9.0"
jquery@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2"
integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==
js-levenshtein@^1.1.3:
version "1.1.6"
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
@ -8201,6 +8211,13 @@ react-base16-styling@^0.6.0:
lodash.flow "^3.3.0"
pure-color "^1.2.0"
react-bootstrap-slider@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/react-bootstrap-slider/-/react-bootstrap-slider-2.2.2.tgz#e56bd570fa16b19661762022dd76419a0ef7d726"
integrity sha512-4j69ruXFiOCRL97+eO3otgIeHmBaNPelf2wgK6UljjD8EfpLL3yOmLHulWogEQFeXHm0i2wr42qXdTyKClYoKA==
dependencies:
bootstrap-slider "^10.6.1"
react-bootstrap@^1.0.0-beta.14:
version "1.0.0-beta.14"
resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-1.0.0-beta.14.tgz#30330df61edbed1f0405f75363ef72d77c1fed57"