Dropdown panel refactor

pull/5370/head
ioedeveloper 4 years ago
parent d50881e797
commit b59895c966
  1. 10
      apps/remix-ide/src/app/tabs/debugger/debuggerUI.js
  2. 11
      libs/debugger-ui/src/lib/button-navigator/button-navigator.spec.tsx
  3. 0
      libs/debugger-ui/src/lib/slider/slider.css
  4. 11
      libs/debugger-ui/src/lib/slider/slider.spec.tsx
  5. 0
      libs/debugger-ui/src/lib/step-manager/step-manager.css
  6. 11
      libs/debugger-ui/src/lib/step-manager/step-manager.spec.tsx
  7. 1
      libs/debugger-ui/src/lib/step-manager/step-manager.tsx
  8. 24
      libs/debugger-ui/src/lib/tx-browser/tx-browser.css
  9. 82
      libs/debugger-ui/src/lib/tx-browser/tx-browser.tsx
  10. 21
      libs/debugger-ui/src/lib/vm-debugger/code-list-view.tsx
  11. 178
      libs/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx
  12. 4
      libs/debugger-ui/src/lib/vm-debugger/styles/code-list-view.css
  13. 44
      libs/debugger-ui/src/lib/vm-debugger/styles/dropdown-panel.css
  14. 16
      libs/debugger-ui/src/lib/vm-debugger/vm-debugger.tsx

@ -2,7 +2,7 @@ import React from 'react';
import ReactDOM from 'react-dom'
import { StepManager } from '@remix-project/debugger-ui'
var TxBrowser = require('./debuggerUI/TxBrowser')
var StepManagerUI = require('./debuggerUI/StepManager')
// var StepManagerUI = require('./debuggerUI/StepManager')
var VmDebugger = require('./debuggerUI/VmDebugger')
var toaster = require('../../ui/tooltip')
@ -61,7 +61,7 @@ class DebuggerUI {
this.sourceHighlighter = new SourceHighlighter()
this.startTxBrowser()
this.stepManager = null
// this.stepManager = null
this.statusMessage = ''
this.currentReceipt
@ -187,7 +187,7 @@ class DebuggerUI {
this.listenToEvents()
this.debugger.debug(blockNumber, txNumber, tx, () => {
this.stepManager = new StepManagerUI(this.debugger.step_manager)
// this.stepManager = new StepManagerUI(this.debugger.step_manager)
this.vmDebugger = new VmDebugger(this.debugger.vmDebuggerLogic)
this.txBrowser.setState({ blockNumber, txNumber, debugging: true })
this.renderDebugger()
@ -259,10 +259,10 @@ class DebuggerUI {
yo.update(this.debuggerPanelsView, yo`<div></div>`)
yo.update(this.stepManagerView, yo`<div></div>`)
if (this.vmDebugger) this.vmDebugger.remove()
if (this.stepManager) this.stepManager.remove()
// if (this.stepManager) this.stepManager.remove()
if (this.txBrowser) this.txBrowser.setState({debugging: false})
this.vmDebugger = null
this.stepManager = null
// this.stepManager = null
if (this.debugger) delete this.debugger
this.event.trigger('traceUnloaded')
}

@ -1,11 +0,0 @@
import React from 'react';
import { render } from '@testing-library/react';
import ButtonNavigation from './button-navigator';
describe(' ButtonNavigation', () => {
it('should render successfully', () => {
const { baseElement } = render(<ButtonNavigation />);
expect(baseElement).toBeTruthy();
});
});

@ -1,11 +0,0 @@
import React from 'react';
import { render } from '@testing-library/react';
import Slider from './slider';
describe(' Slider', () => {
it('should render successfully', () => {
const { baseElement } = render(<Slider />);
expect(baseElement).toBeTruthy();
});
});

@ -1,11 +0,0 @@
import React from 'react';
import { render } from '@testing-library/react';
import StepManager from './step-manager';
describe(' StepManager', () => {
it('should render successfully', () => {
const { baseElement } = render(<StepManager />);
expect(baseElement).toBeTruthy();
});
});

@ -1,5 +1,4 @@
import React, { useState, useEffect } from 'react'
import './step-manager.css'
import Slider from '../slider/slider'
import ButtonNavigator from '../button-navigator/button-navigator'

@ -0,0 +1,24 @@
.container {
display: flex;
flex-direction: column;
}
.txContainer {
display: flex;
flex-direction: column;
}
.txinput {
width: inherit;
font-size: small;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.txbutton {
width: inherit;
}
.txbutton:hover {
}
.vmargin {
margin-top: 10px;
margin-bottom: 10px;
}

@ -0,0 +1,82 @@
import React, { useState } from 'react'
import './tx-browser.css'
import EventManager from '../../../../../apps/remix-ide/src/lib/events'
export const TxBrowser = () => {
const event = new EventManager()
const [state, setState] = useState({
txNumber: undefined,
debugging: false
})
const handleSubmit = () => {
if (state.debugging) {
unload()
} else {
event.trigger('requestDebug', [undefined, state.txNumber])
}
}
const unload = () => {
event.trigger('unloadRequested', [])
}
const updateTxN = (ev) => {
setState(prevState => {
return {
...prevState,
txNumber: ev.target.value
}
})
}
const txInputChanged = (e) => {
// todo check validation of txnumber in the input element, use
// required
// oninvalid="setCustomValidity('Please provide a valid transaction number, must start with 0x and have length of 22')"
// pattern="^0[x,X]+[0-9a-fA-F]{22}"
// this.state.txNumberInput.setCustomValidity('')
setState(prevState => {
return {
...prevState,
txNumber: e.target.value
}
})
}
return (
<div className="container">
<div className="txContainer">
<div className="py-1 d-flex justify-content-center w-100 input-group">
<input
value={state.txNumber || ''}
className="form-control m-0 css.txinput"
id='txinput'
onKeyUp={updateTxN}
type='text'
onInput={txInputChanged}
placeholder={'Transaction hash, should start with 0x'}
data-id="debuggerTransactionInput"
disabled={state.debugging}
/>
</div>
<div className="d-flex justify-content-center w-100 btn-group py-1">
<button
className="btn btn-primary btn-sm txbutton"
id="load"
title={state.debugging ? 'Stop debugging' : 'Start debugging'}
onClick={handleSubmit}
data-id="debuggerTransactionStartButton"
disabled={!state.txNumber ? true : !state.debugging ? false : true }
>
{ state.debugging ? 'Stop' : 'Start' } debugging
</button>
</div>
</div>
<span id='error'></span>
</div>
)
}
export default TxBrowser

@ -0,0 +1,21 @@
import React, { useState } from 'react'
import './styles/code-list-view.css'
import EventManager from '../../../../../apps/remix-ide/src/lib/events'
export const VmDebugger = ({ vmDebuggerLogic }) => {
const event = new EventManager()
const [state, setState] = useState({
code: '',
address: '',
itemSelected: null,
})
return (
<div>
<h1>Welcome to vmDebugger!</h1>
</div>
)
}
export default VmDebugger

@ -0,0 +1,178 @@
import React, { useState, useRef } from 'react'
import './styles/dropdown-panel.css'
import EventManager from '../../../../../apps/remix-ide/src/lib/events'
import TreeView from '../../../../../apps/remix-ide/src/app/ui/TreeView'
import copyToClipboard from '../../../../../apps/remix-ide/src/app/ui/copy-to-clipboard'
export const DropdownPanel = ({ name, opts, node }) => {
const event = new EventManager()
const treeView = new TreeView(opts)
const [state, setState] = useState({
header: '',
json: opts.json,
displayContentOnly: opts.displayContentOnly,
toggleDropdown: false,
message: {
innerText: '',
display: 'none'
},
dropdownContent: {
innerText: '',
display: 'none'
},
dropdownRawContent: {
innerText: '',
display: 'none'
},
title: {
innerText: '',
display: 'none'
},
showRefreshIcon: false
})
const dropdownRawEl = useRef(null)
const handleToggle = () => {
setState(prevState => {
if (prevState.toggleDropdown) event.trigger('hide', [])
else event.trigger('show', [])
return {
...prevState,
toggleDropdown: !prevState.toggleDropdown
}
})
}
const copyClipboard = () => {
return dropdownRawEl.current.innerText ? dropdownRawEl.current.innerText : dropdownRawEl.current.textContent
}
const message = (message) => {
setState(state => {
return {
...state,
message: {
innerText: message,
display: message ? 'block' : ''
},
dropdownRawContent: {
...state.dropdownRawContent,
display: 'none'
},
dropdownContent: {
...state.dropdownContent,
display: 'none'
},
showRefreshIcon: false
}
})
}
const setLoading = () => {
setState(prevState => {
return {
...prevState,
message: {
innerText: '',
display: 'none'
},
dropdownRawContent: {
...prevState.dropdownRawContent,
display: 'none'
},
dropdownContent: {
...prevState.dropdownContent,
display: 'none'
},
showRefreshIcon: true
}
})
}
const update = function (data, header) {
setState(prevState => {
return {
...prevState,
showRefreshIcon: false,
dropdownContent: {
...prevState.dropdownContent,
display: 'none'
},
dropdownRawContent: {
innerText: JSON.stringify(data, null, '\t'),
display: 'block'
}
}
})
if (!this.displayContentOnly) {
// this.view.querySelector('.title i.fa-copy').style.display = 'block'
setState(prevState => {
return {
...prevState,
title: {
innerText: header || '',
display: 'block'
}
}
})
}
message('')
if (state.json) {
treeView.update(data)
}
}
const hide = () => {
setState(prevState => {
return {
...prevState,
toggleDropdown: false
}
})
event.trigger('hide', [])
}
const show = () => {
setState(prevState => {
return {
...prevState,
toggleDropdown: true
}
})
event.trigger('show', [])
}
let content = <div>Empty</div>
if (state.json) {
content = treeView.render({}, null)
}
const title = !state.displayContentOnly ?
<div className="py-0 px-1 title">
<div className={state.toggleDropdown ? 'icon fas fa-caret-down' : 'icon fas fa-caret-right'} onClick={handleToggle}></div>
<div className="name" onClick={handleToggle}>{name}</div><span className="nameDetail" onClick={handleToggle}></span>
{copyToClipboard(() => copyClipboard())}
</div> : <div></div>
if (state.displayContentOnly) {
setState(prevState => {
return {
...prevState,
toggleDropdown: true
}
})
}
return (
<div className="border rounded px-1 mt-1 bg-light">
{ title }
<div className='dropdownpanel' style={{ display: state.toggleDropdown ? 'block' : 'none' }}>
<i className="refresh fas fa-sync" style={{ display: state.showRefreshIcon ? 'inline-block' : 'none' }} aria-hidden="true"></i>
<div className='dropdowncontent' style={{ display: state.dropdownContent.display }}>{node || content }</div>
<div className='dropdownrawcontent' style={{ display: state.dropdownRawContent.display }} ref={ dropdownRawEl }></div>
<div className='message' style={{ display: state.message.display }}></div>
</div>
</div>
)
}
export default DropdownPanel

@ -0,0 +1,4 @@
.instructions {
overflow-y: scroll;
max-height: 130px;
}

@ -0,0 +1,44 @@
.title {
display: flex;
align-items: center;
}
.name {
font-weight: bold;
}
.nameDetail {
font-weight: bold;
margin-left: 3px;
}
.icon {
margin-right: 5%;
}
.eyeButton {
margin: 3px;
}
.dropdownpanel {
width: 100%;
word-break: break-word;
}
.dropdownrawcontent {
padding: 2px;
word-break: break-word;
}
.message {
padding: 2px;
word-break: break-word;
}
.refresh {
display: none;
margin-left: 4px;
margin-top: 4px;
animation: spin 2s linear infinite;
}
@-moz-keyframes spin {
to { -moz-transform: rotate(359deg); }
}
@-webkit-keyframes spin {
to { -webkit-transform: rotate(359deg); }
}
@keyframes spin {
to {transform:rotate(359deg);}
}

@ -0,0 +1,16 @@
import React, { useState } from 'react';
import './vm-debugger.css';
export const VmDebugger = ({ vmDebuggerLogic }) => {
const [state, setState] = useState({
asmCode
})
return (
<div>
<h1>Welcome to vmDebugger!</h1>
</div>
);
};
export default VmDebugger;
Loading…
Cancel
Save