all scrollbar
This commit is contained in:
parent
399d559ec5
commit
54c48b3cf9
|
@ -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",
|
||||
|
|
122
src/App.js
122
src/App.js
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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'));
|
||||
|
|
17
yarn.lock
17
yarn.lock
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue