all scrollbar
This commit is contained in:
parent
399d559ec5
commit
54c48b3cf9
|
@ -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",
|
||||||
|
|
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 { 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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'));
|
||||||
|
|
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"
|
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"
|
||||||
|
|
Loading…
Reference in New Issue