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

View File

@ -4,6 +4,7 @@ import './index.css';
import App from './App'; import App from './App';
import * as serviceWorker from './serviceWorker'; import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.min.css'; 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'; import '@devexpress/dx-react-grid-bootstrap4/dist/dx-react-grid-bootstrap4.css';
ReactDOM.render(<App />, document.getElementById('root')); 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" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= 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: bootstrap@^4.3.1:
version "4.3.1" version "4.3.1"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.3.1.tgz#280ca8f610504d99d7b6b4bfc4b68cec601704ac" 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" import-local "^2.0.0"
jest-cli "^24.9.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: js-levenshtein@^1.1.3:
version "1.1.6" version "1.1.6"
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" 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" lodash.flow "^3.3.0"
pure-color "^1.2.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: react-bootstrap@^1.0.0-beta.14:
version "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" resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-1.0.0-beta.14.tgz#30330df61edbed1f0405f75363ef72d77c1fed57"