move components
This commit is contained in:
parent
2018d77045
commit
dfc2df4db3
|
@ -23,3 +23,4 @@ yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
src/logs/
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
const lineByLine = require('n-readlines');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
|
||||||
|
const liner = new lineByLine('./raw_logs.json');
|
||||||
|
|
||||||
|
let DB = {};
|
||||||
|
let line;
|
||||||
|
|
||||||
|
while (_line = liner.next()) {
|
||||||
|
if (_line.length === 0) continue;
|
||||||
|
let line = _line.toString('ascii')
|
||||||
|
let data = JSON.parse(line)
|
||||||
|
|
||||||
|
let id = data.id
|
||||||
|
if (DB[id]) {
|
||||||
|
DB[id] = {...DB[id], ...data}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DB[id] = data
|
||||||
|
}
|
||||||
|
|
||||||
|
console.dir("wrote " + Object.keys(DB).length + " keys");
|
||||||
|
fs.writeJSONSync("./log.json", DB);
|
||||||
|
console.dir("done");
|
|
@ -9,7 +9,9 @@
|
||||||
"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",
|
||||||
|
"fs-extra": "^8.1.0",
|
||||||
"jquery": "^3.4.1",
|
"jquery": "^3.4.1",
|
||||||
|
"n-readlines": "^1.0.0",
|
||||||
"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-bootstrap-slider": "^2.2.2",
|
||||||
|
|
211
src/App.js
211
src/App.js
|
@ -1,18 +1,13 @@
|
||||||
import React, {useState} from 'react';
|
import React from 'react';
|
||||||
import { SearchState, SortingState, IntegratedSorting, TreeDataState, CustomTreeData, FilteringState, IntegratedFiltering, TableColumnVisibility, DataTypeProvider } from '@devexpress/dx-react-grid';
|
|
||||||
import { Grid, Table, TableHeaderRow, TableTreeColumn, TableFilterRow, SearchPanel, Toolbar, ColumnChooser, TableColumnResizing, DragDropProvider, TableColumnReordering } from '@devexpress/dx-react-grid-bootstrap4';
|
|
||||||
import Convert from 'ansi-to-html';
|
|
||||||
import stripAnsi from 'strip-ansi';
|
|
||||||
import ReactJson from 'react-json-view';
|
|
||||||
import './App.css';
|
import './App.css';
|
||||||
import Logs from './Logs.js';
|
import DetailModal from './DetailModal.js';
|
||||||
import {Button, Card, Collapse, Navbar, Nav, Container, Modal} from 'react-bootstrap';
|
import ObjectSection from './ObjectSection.js';
|
||||||
import ReactBootstrapSlider from 'react-bootstrap-slider';
|
import ConsoleSection from './ConsoleSection.js';
|
||||||
|
import LogsSection from './LogsSection.js';
|
||||||
import all_data from './log_embark_run.json'
|
import DebugBar from './DebugBar.js';
|
||||||
|
|
||||||
let convert = new Convert();
|
|
||||||
|
|
||||||
|
// import all_data from './logs/log_embark_run.json'
|
||||||
|
import all_data from './logs/log.json'
|
||||||
let all_data_ordered = Object.values(all_data).sort((x) => x.timestamp)
|
let all_data_ordered = Object.values(all_data).sort((x) => x.timestamp)
|
||||||
|
|
||||||
let session_object = Object.values(all_data).find((x) => x.session === x.id)
|
let session_object = Object.values(all_data).find((x) => x.session === x.id)
|
||||||
|
@ -20,116 +15,6 @@ let session_object = Object.values(all_data).find((x) => x.session === x.id)
|
||||||
|
|
||||||
let data = [session_object];
|
let data = [session_object];
|
||||||
|
|
||||||
const ImportFromFileBodyComponent = () => {
|
|
||||||
let fileReader;
|
|
||||||
|
|
||||||
const handleFileRead = (e) => {
|
|
||||||
const content = fileReader.result;
|
|
||||||
console.log(content);
|
|
||||||
// … do something with the 'content' …
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFileChosen = (file) => {
|
|
||||||
if (!file) return;
|
|
||||||
fileReader = new FileReader();
|
|
||||||
fileReader.onloadend = handleFileRead;
|
|
||||||
fileReader.readAsText(file);
|
|
||||||
};
|
|
||||||
|
|
||||||
return <div className='upload-expense'>
|
|
||||||
<input type='file'
|
|
||||||
id='file'
|
|
||||||
className='input-file'
|
|
||||||
accept='.csv'
|
|
||||||
onChange={e => handleFileChosen(e.target.files[0])}
|
|
||||||
/>
|
|
||||||
</div>;
|
|
||||||
};
|
|
||||||
|
|
||||||
function DetailModal({show, setShow, title, content}) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
size="xl"
|
|
||||||
show={show}
|
|
||||||
onHide={() => setShow(false)}
|
|
||||||
// dialogClassName="modal-90w"
|
|
||||||
aria-labelledby="example-custom-modal-styling-title"
|
|
||||||
>
|
|
||||||
<Modal.Header closeButton>
|
|
||||||
<Modal.Title id="example-custom-modal-styling-title">
|
|
||||||
{title}
|
|
||||||
</Modal.Title>
|
|
||||||
</Modal.Header>
|
|
||||||
<Modal.Body>
|
|
||||||
<ReactJson src={content} theme="monokai" groupArraysAfterLength={10} name={false} collapsed={3} />
|
|
||||||
</Modal.Body>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function Section({title, children, defaultOpen}) {
|
|
||||||
const [open, setOpen] = useState(defaultOpen);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Card>
|
|
||||||
<Card.Header onClick={() => setOpen(!open)} style={{"cursor": "pointer"}}>
|
|
||||||
{title}
|
|
||||||
</Card.Header>
|
|
||||||
|
|
||||||
<Collapse in={open}>
|
|
||||||
<Card.Body>
|
|
||||||
{children}
|
|
||||||
</Card.Body>
|
|
||||||
</Collapse>
|
|
||||||
</Card>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const LogFormatter = ({ onClick }) => {
|
|
||||||
return (props) => {
|
|
||||||
return (
|
|
||||||
<span onClick={onClick(props)}>
|
|
||||||
{stripAnsi(props.value)}
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const LogTypeProvider = (props) => {
|
|
||||||
console.dir(props)
|
|
||||||
return (
|
|
||||||
<DataTypeProvider
|
|
||||||
formatterComponent={LogFormatter(props)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const StepFormatter = ({onClick}) => {
|
|
||||||
return (props) => {
|
|
||||||
return (
|
|
||||||
<span onClick={onClick(props)}>
|
|
||||||
{stripAnsi(props.value)}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const StepTypeProvider = (props) => {
|
|
||||||
return (
|
|
||||||
<DataTypeProvider
|
|
||||||
formatterComponent={StepFormatter(props)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class App extends React.PureComponent {
|
class App extends React.PureComponent {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -152,8 +37,8 @@ class App extends React.PureComponent {
|
||||||
// { name: 'inputs', title: 'Inputs' },
|
// { name: 'inputs', title: 'Inputs' },
|
||||||
{ name: 'msg', title: 'Error' },
|
{ name: 'msg', title: 'Error' },
|
||||||
],
|
],
|
||||||
rows: [session_object],
|
// rows: [session_object],
|
||||||
tableColumnExtensions: [{ columnName: 'name', width: 300, align: 'left' }],
|
rows: data,
|
||||||
// defaultExpandedRowIds: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27]
|
// defaultExpandedRowIds: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27]
|
||||||
defaultExpandedRowIds: [],
|
defaultExpandedRowIds: [],
|
||||||
defaultHiddenColumnNames: ['session', 'parent_id', 'id', 'error'],
|
defaultHiddenColumnNames: ['session', 'parent_id', 'id', 'error'],
|
||||||
|
@ -173,14 +58,6 @@ class App extends React.PureComponent {
|
||||||
{ columnName: 'msg', width: 200 },
|
{ columnName: 'msg', width: 200 },
|
||||||
],
|
],
|
||||||
defaultOrder: ['session', 'parent_id', 'id', 'step', 'name', 'type', 'timestamp', 'msg'],
|
defaultOrder: ['session', 'parent_id', 'id', 'step', 'name', 'type', 'timestamp', 'msg'],
|
||||||
numberFilterOperations: [
|
|
||||||
'equal',
|
|
||||||
'notEqual',
|
|
||||||
'greaterThan',
|
|
||||||
'greaterThanOrEqual',
|
|
||||||
'lessThan',
|
|
||||||
'lessThanOrEqual',
|
|
||||||
],
|
|
||||||
shouldShowModal: false,
|
shouldShowModal: false,
|
||||||
modalTitle: "",
|
modalTitle: "",
|
||||||
modalContent: {}
|
modalContent: {}
|
||||||
|
@ -243,6 +120,7 @@ class App extends React.PureComponent {
|
||||||
|
|
||||||
for (let i=0; i<diff; i++) {
|
for (let i=0; i<diff; i++) {
|
||||||
let newItem = all_data_ordered[this.state.current_index - diff - 1]
|
let newItem = all_data_ordered[this.state.current_index - diff - 1]
|
||||||
|
if (!newItem) break;
|
||||||
data.pop();
|
data.pop();
|
||||||
nextLogs.pop()
|
nextLogs.pop()
|
||||||
newItem.step = this.state.current_index - diff - 1
|
newItem.step = this.state.current_index - diff - 1
|
||||||
|
@ -272,7 +150,7 @@ class App extends React.PureComponent {
|
||||||
|
|
||||||
let newItem = all_data_ordered[current_step]
|
let newItem = all_data_ordered[current_step]
|
||||||
if (!newItem) break;
|
if (!newItem) break;
|
||||||
if (newItem.type.indexOf("log_") === 0) {
|
if (newItem.type && newItem.type.indexOf("log_") === 0) {
|
||||||
nextLogs.push(current_step + ". " + newItem.name)
|
nextLogs.push(current_step + ". " + newItem.name)
|
||||||
} else {
|
} else {
|
||||||
nextLogs.push("") // easier to slice it after...
|
nextLogs.push("") // easier to slice it after...
|
||||||
|
@ -336,62 +214,21 @@ class App extends React.PureComponent {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<DetailModal show={this.state.shouldShowModal} setShow={this.setShow} title={this.state.modalTitle} content={this.state.modalContent} />
|
<DetailModal show={this.state.shouldShowModal} setShow={this.setShow} title={this.state.modalTitle} content={this.state.modalContent} />
|
||||||
<Navbar fixed="top" style={{"background-color": "white", "border-bottom": "1px solid black"}}>
|
<DebugBar currentStep={this.state.current_index} maxStep={this.state.max_index} currentId={this.state.current_index} goBack={this.previousLog} goForward={this.nextLog} changeStep={this.changeValue} goToStep={this.goToStep} />
|
||||||
{/* <ImportFromFileBodyComponent /> */}
|
|
||||||
<Button onClick={() => { this.setState({shouldShowModal: true})}}>show</Button>
|
|
||||||
<Navbar.Brand href="#">StructLog</Navbar.Brand>
|
|
||||||
<Nav className="mr-auto">
|
|
||||||
step: {this.state.current_index} / {this.state.max_index} id: {this.state.current_id}
|
|
||||||
</Nav>
|
|
||||||
< inline>
|
|
||||||
<button onClick={() => { this.goToStep(1) }}>First</button>
|
|
||||||
<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>
|
|
||||||
<button onClick={() => { this.goToStep(this.state.max_index) }}>Last</button>
|
|
||||||
</inline>
|
|
||||||
</Navbar>
|
|
||||||
<div style={{"margin-top": "55px"}}>
|
<div style={{"margin-top": "55px"}}>
|
||||||
<Section title="Current" defaultOpen={true}>
|
<ObjectSection log={this.state.current} open={true} />
|
||||||
<ReactJson src={this.state.current} theme="monokai" groupArraysAfterLength={5} name={false} collapsed={2} />
|
<ConsoleSection logs={this.state.logs} open={true} />
|
||||||
</Section>
|
<LogsSection
|
||||||
<Section title="Console Output" defaultOpen={true}>
|
open={true}
|
||||||
<Logs>
|
rows={this.state.rows}
|
||||||
{this.state.logs.map((item, i) => {
|
columns={this.state.columns}
|
||||||
return (
|
viewRow={this.viewRow}
|
||||||
<div key={`message-${i}`}>
|
getChildRows={this.getChildRows}
|
||||||
<p dangerouslySetInnerHTML={{ __html: (convert.toHtml(item || "")) }} />
|
defaultColumnWidths={this.state.defaultColumnWidths}
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Logs>
|
|
||||||
</Section>
|
|
||||||
<Section title="Logs" defaultOpen={true}>
|
|
||||||
<Grid rows={this.state.rows} columns={this.state.columns} >
|
|
||||||
<LogTypeProvider for={["name"]} onClick={this.viewRow} />
|
|
||||||
<StepTypeProvider for={["step"]} onClick={this.viewRow} availableFilterOperations={this.state.numberFilterOperations} />
|
|
||||||
<TreeDataState defaultExpandedRowIds={this.state.defaultExpandedRowIds} />
|
|
||||||
<CustomTreeData getChildRows={this.getChildRows} />
|
|
||||||
<FilteringState defaultFilters={[]} />
|
|
||||||
<SearchState defaultValue="" />
|
|
||||||
<IntegratedFiltering />
|
|
||||||
<SortingState defaultSorting={[{ columnName: 'Timestamp', direction: 'asc' }]} />
|
|
||||||
<IntegratedSorting />
|
|
||||||
<DragDropProvider />
|
|
||||||
<Table columnExtensions={this.state.tableColumnExtensions} />
|
|
||||||
<TableColumnResizing defaultColumnWidths={this.state.defaultColumnWidths} />
|
|
||||||
<TableHeaderRow showSortingControls />
|
|
||||||
<TableColumnVisibility
|
|
||||||
defaultHiddenColumnNames={this.state.defaultHiddenColumnNames}
|
defaultHiddenColumnNames={this.state.defaultHiddenColumnNames}
|
||||||
|
defaultOrder={this.state.defaultOrder}
|
||||||
/>
|
/>
|
||||||
<TableColumnReordering defaultOrder={this.state.defaultOrder} />
|
|
||||||
<Toolbar />
|
|
||||||
<SearchPanel />
|
|
||||||
<TableFilterRow showFilterSelector={true} />
|
|
||||||
<TableTreeColumn for="name" />
|
|
||||||
<ColumnChooser />
|
|
||||||
</Grid>
|
|
||||||
</Section>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import React from 'react';
|
||||||
|
import Convert from 'ansi-to-html';
|
||||||
|
import Section from './Section.js';
|
||||||
|
import Logs from './Logs.js';
|
||||||
|
|
||||||
|
let convert = new Convert();
|
||||||
|
|
||||||
|
function ConsoleSection({logs, open}) {
|
||||||
|
return (
|
||||||
|
<Section title="Console Output" defaultOpen={open}>
|
||||||
|
<Logs>
|
||||||
|
{logs.map((item, i) => {
|
||||||
|
return (
|
||||||
|
<div key={`message-${i}`}>
|
||||||
|
<p dangerouslySetInnerHTML={{ __html: (convert.toHtml(item || "")) }} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Logs>
|
||||||
|
</Section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ConsoleSection;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {Navbar, Nav} from 'react-bootstrap';
|
||||||
|
import ReactBootstrapSlider from 'react-bootstrap-slider';
|
||||||
|
|
||||||
|
function DebugBar({currentStep, maxStep, currentId, goBack, goForward, changeStep, goToStep}) {
|
||||||
|
return (
|
||||||
|
<Navbar fixed="top" style={{ "background-color": "white", "border-bottom": "1px solid black" }}>
|
||||||
|
<Navbar.Brand href="#">StructLog</Navbar.Brand>
|
||||||
|
<Nav className="mr-auto">
|
||||||
|
step: {currentStep} / {maxStep} id: {currentId}
|
||||||
|
</Nav>
|
||||||
|
< inline>
|
||||||
|
<button onClick={() => { goToStep(1) }}>First</button>
|
||||||
|
<button onClick={goBack}>Previous</button>
|
||||||
|
<ReactBootstrapSlider min={0} max={maxStep} change={changeStep} value={currentStep} />
|
||||||
|
<button onClick={goForward}>Next</button>
|
||||||
|
<button onClick={() => { goToStep(maxStep) }}>Last</button>
|
||||||
|
</inline>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DebugBar;
|
|
@ -0,0 +1,28 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {Modal} from 'react-bootstrap';
|
||||||
|
import ReactJson from 'react-json-view';
|
||||||
|
|
||||||
|
function DetailModal({show, setShow, title, content}) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Modal
|
||||||
|
size="xl"
|
||||||
|
show={show}
|
||||||
|
onHide={() => setShow(false)}
|
||||||
|
// dialogClassName="modal-90w"
|
||||||
|
aria-labelledby="example-custom-modal-styling-title"
|
||||||
|
>
|
||||||
|
<Modal.Header closeButton>
|
||||||
|
<Modal.Title id="example-custom-modal-styling-title">
|
||||||
|
{title}
|
||||||
|
</Modal.Title>
|
||||||
|
</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
<ReactJson src={content} theme="monokai" groupArraysAfterLength={10} name={false} collapsed={3} />
|
||||||
|
</Modal.Body>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DetailModal;
|
|
@ -0,0 +1,49 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { DataTypeProvider } from '@devexpress/dx-react-grid';
|
||||||
|
import stripAnsi from 'strip-ansi';
|
||||||
|
|
||||||
|
const LogFormatter = ({ onClick }) => {
|
||||||
|
return (props) => {
|
||||||
|
return (
|
||||||
|
<span onClick={onClick(props)}>
|
||||||
|
{stripAnsi(props.value)}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const LogTypeProvider = (props) => {
|
||||||
|
console.dir(props)
|
||||||
|
return (
|
||||||
|
<DataTypeProvider
|
||||||
|
formatterComponent={LogFormatter(props)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const StepFormatter = ({onClick}) => {
|
||||||
|
return (props) => {
|
||||||
|
return (
|
||||||
|
<span onClick={onClick(props)}>
|
||||||
|
{stripAnsi(props.value)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const StepTypeProvider = (props) => {
|
||||||
|
return (
|
||||||
|
<DataTypeProvider
|
||||||
|
formatterComponent={StepFormatter(props)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
LogFormatter,
|
||||||
|
LogTypeProvider,
|
||||||
|
StepFormatter,
|
||||||
|
StepTypeProvider
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
import React 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, TableColumnResizing, DragDropProvider, TableColumnReordering } from '@devexpress/dx-react-grid-bootstrap4';
|
||||||
|
import {LogTypeProvider, StepTypeProvider} from './Formatters.js';
|
||||||
|
|
||||||
|
import Section from './Section.js';
|
||||||
|
|
||||||
|
let numberFilterOperations = [
|
||||||
|
'equal',
|
||||||
|
'notEqual',
|
||||||
|
'greaterThan',
|
||||||
|
'greaterThanOrEqual',
|
||||||
|
'lessThan',
|
||||||
|
'lessThanOrEqual',
|
||||||
|
];
|
||||||
|
|
||||||
|
let tableColumnExtensions = [{ columnName: 'name', width: 300, align: 'left' }];
|
||||||
|
|
||||||
|
function LogsSection({open, rows, columns, viewRow, getChildRows, defaultColumnWidths, defaultHiddenColumnNames, defaultOrder}) {
|
||||||
|
return (
|
||||||
|
<Section title="Logs" defaultOpen={open}>
|
||||||
|
<Grid rows={rows} columns={columns} >
|
||||||
|
<LogTypeProvider for={["name"]} onClick={viewRow} />
|
||||||
|
<StepTypeProvider for={["step"]} onClick={viewRow} availableFilterOperations={numberFilterOperations} />
|
||||||
|
<TreeDataState defaultExpandedRowIds={[]} />
|
||||||
|
<CustomTreeData getChildRows={getChildRows} />
|
||||||
|
<FilteringState defaultFilters={[]} />
|
||||||
|
<SearchState defaultValue="" />
|
||||||
|
<IntegratedFiltering />
|
||||||
|
<SortingState defaultSorting={[{ columnName: 'Timestamp', direction: 'asc' }]} />
|
||||||
|
<IntegratedSorting />
|
||||||
|
<DragDropProvider />
|
||||||
|
<Table columnExtensions={tableColumnExtensions} />
|
||||||
|
<TableColumnResizing defaultColumnWidths={defaultColumnWidths} />
|
||||||
|
<TableHeaderRow showSortingControls />
|
||||||
|
<TableColumnVisibility defaultHiddenColumnNames={defaultHiddenColumnNames} />
|
||||||
|
<TableColumnReordering defaultOrder={defaultOrder} />
|
||||||
|
<Toolbar />
|
||||||
|
<SearchPanel />
|
||||||
|
<TableFilterRow showFilterSelector={true} />
|
||||||
|
<TableTreeColumn for="name" />
|
||||||
|
<ColumnChooser />
|
||||||
|
</Grid>
|
||||||
|
</Section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LogsSection;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ReactJson from 'react-json-view';
|
||||||
|
import Section from './Section.js';
|
||||||
|
|
||||||
|
function ObjectSection({log, open}) {
|
||||||
|
return (
|
||||||
|
<Section title="Current" defaultOpen={open}>
|
||||||
|
<ReactJson src={log} theme="monokai" groupArraysAfterLength={5} name={false} collapsed={2} />
|
||||||
|
</Section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ObjectSection;
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import React, {useState} from 'react';
|
||||||
|
import {Card, Collapse} from 'react-bootstrap';
|
||||||
|
|
||||||
|
function Section({title, children, defaultOpen}) {
|
||||||
|
const [open, setOpen] = useState(defaultOpen);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Card>
|
||||||
|
<Card.Header onClick={() => setOpen(!open)} style={{"cursor": "pointer"}}>
|
||||||
|
{title}
|
||||||
|
</Card.Header>
|
||||||
|
|
||||||
|
<Collapse in={open}>
|
||||||
|
<Card.Body>
|
||||||
|
{children}
|
||||||
|
</Card.Body>
|
||||||
|
</Collapse>
|
||||||
|
</Card>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Section;
|
File diff suppressed because one or more lines are too long
|
@ -6488,6 +6488,11 @@ mute-stream@0.0.7:
|
||||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
||||||
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
|
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
|
||||||
|
|
||||||
|
n-readlines@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/n-readlines/-/n-readlines-1.0.0.tgz#c353797f216c253fdfef7e91da4e8b17c29a91a6"
|
||||||
|
integrity sha512-ISDqGcspVu6U3VKqtJZG1uR55SmNNF9uK0EMq1IvNVVZOui6MW6VR0+pIZhqz85ORAGp+4zW+5fJ/SE7bwEibA==
|
||||||
|
|
||||||
nan@^2.12.1:
|
nan@^2.12.1:
|
||||||
version "2.14.0"
|
version "2.14.0"
|
||||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
|
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
|
||||||
|
|
Loading…
Reference in New Issue