parent
2ce18276cb
commit
d50881e797
@ -1,4 +1,3 @@ |
||||
import Slider from './lib/slider' |
||||
import * as debuggerUI from './lib/debugger-ui' |
||||
import StepManager from './lib/step-manager/step-manager' |
||||
|
||||
export { Slider, debuggerUI } |
||||
export { StepManager } |
||||
|
@ -0,0 +1,22 @@ |
||||
.buttons { |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
} |
||||
.stepButtons { |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
} |
||||
.stepButton { |
||||
} |
||||
.jumpButtons { |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
} |
||||
.jumpButton { |
||||
} |
||||
.navigator { |
||||
} |
||||
.navigator:hover { |
||||
} |
@ -0,0 +1,11 @@ |
||||
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(); |
||||
}); |
||||
}); |
@ -0,0 +1,78 @@ |
||||
import React, { useState, useEffect } from 'react' |
||||
import './button-navigator.css' |
||||
|
||||
export const ButtonNavigation = ({ stepManager, revertedReason, stepState, jumpOutDisabled }) => { |
||||
const [state, setState] = useState({ |
||||
intoBackDisabled: true, |
||||
overBackDisabled: true, |
||||
intoForwardDisabled: true, |
||||
overForwardDisabled: true, |
||||
jumpOutDisabled: true, |
||||
jumpNextBreakpointDisabled: true, |
||||
jumpPreviousBreakpointDisabled: true |
||||
}) |
||||
|
||||
useEffect(() => { |
||||
stepChanged(stepState, jumpOutDisabled) |
||||
}, [stepState, jumpOutDisabled]) |
||||
|
||||
const reset = () => { |
||||
setState(() => { |
||||
return { |
||||
intoBackDisabled: true, |
||||
overBackDisabled: true, |
||||
intoForwardDisabled: true, |
||||
overForwardDisabled: true, |
||||
jumpOutDisabled: true, |
||||
jumpNextBreakpointDisabled: true, |
||||
jumpPreviousBreakpointDisabled: true |
||||
} |
||||
}) |
||||
} |
||||
|
||||
const stepChanged = (stepState, jumpOutDisabled) => { |
||||
if (stepState === 'invalid') { |
||||
// TODO: probably not necessary, already implicit done in the next steps
|
||||
reset() |
||||
return |
||||
} |
||||
|
||||
setState(() => { |
||||
return { |
||||
intoBackDisabled: stepState === 'initial', |
||||
overBackDisabled: stepState === 'initial', |
||||
jumpPreviousBreakpointDisabled: stepState === 'initial', |
||||
intoForwardDisabled: stepState === 'end', |
||||
overForwardDisabled: stepState === 'end', |
||||
jumpNextBreakpointDisabled: jumpOutDisabled, |
||||
jumpOutDisabled |
||||
} |
||||
}) |
||||
} |
||||
|
||||
return ( |
||||
<div className="buttons"> |
||||
<div className="stepButtons btn-group py-1"> |
||||
<button id='overback' className='btn btn-primary btn-sm navigator stepButton fas fa-reply' title='Step over back' onClick={() => { stepManager.stepOverBack() }} disabled={state.overBackDisabled} ></button> |
||||
<button id='intoback' data-id="buttonNavigatorIntoBack" className='btn btn-primary btn-sm navigator stepButton fas fa-level-up-alt' title='Step back' onClick={() => { stepManager.stepIntoBack() }} disabled={state.intoBackDisabled}></button> |
||||
<button id='intoforward' data-id="buttonNavigatorIntoForward" className='btn btn-primary btn-sm navigator stepButton fas fa-level-down-alt' title='Step into' onClick={() => { stepManager.stepIntoForward() }} disabled={state.intoForwardDisabled}></button> |
||||
<button id='overforward' className='btn btn-primary btn-sm navigator stepButton fas fa-share' title='Step over forward' onClick={() => { stepManager.stepOverForward() }} disabled={state.overForwardDisabled}></button> |
||||
</div> |
||||
|
||||
<div className="jumpButtons btn-group py-1"> |
||||
<button className='btn btn-primary btn-sm navigator jumpButton fas fa-step-backward' id='jumppreviousbreakpoint' data-id="buttonNavigatorJumpPreviousBreakpoint" title='Jump to the previous breakpoint' onClick={() => { stepManager.jumpPreviousBreakpoint() }} disabled={state.jumpPreviousBreakpointDisabled}></button> |
||||
<button className='btn btn-primary btn-sm navigator jumpButton fas fa-eject' id='jumpout' title='Jump out' onClick={() => { stepManager.jumpOut() }} disabled={state.jumpOutDisabled}></button> |
||||
<button className='btn btn-primary btn-sm navigator jumpButton fas fa-step-forward' id='jumpnextbreakpoint' data-id="buttonNavigatorJumpNextBreakpoint" title='Jump to the next breakpoint' onClick={() => { stepManager.jumpNextBreakpoint() }} disabled={state.jumpNextBreakpointDisabled}></button> |
||||
</div> |
||||
<div id='reverted' style={{ display: revertedReason === '' ? 'none' : 'block' }}> |
||||
<button id='jumptoexception' title='Jump to exception' className='btn btn-danger btn-sm navigator button fas fa-exclamation-triangle' onClick={() => { stepManager.jumpToException() }} disabled={state.jumpOutDisabled}> |
||||
</button> |
||||
<span>State changes made during this call will be reverted.</span> |
||||
<span id='outofgas' style={{ display: revertedReason === 'outofgas' ? 'inline' : 'none' }}>This call will run out of gas.</span> |
||||
<span id='parenthasthrown' style={{ display: revertedReason === 'parenthasthrown' ? 'inline' : 'none' }}>The parent call will throw an exception</span> |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default ButtonNavigation |
@ -1,65 +0,0 @@ |
||||
import React, { useState, useRef } from 'react' |
||||
|
||||
const Slider = ({ event }) => { |
||||
const [state, setState] = useState({ |
||||
max: null, |
||||
disabled: true, |
||||
previousValue: null, |
||||
currentValue: null |
||||
}) |
||||
const sliderRef = useRef(null) |
||||
|
||||
const setSliderLength = (length) => { |
||||
sliderRef.current.setAttribute('max', length - 1) |
||||
setState({ |
||||
...state, |
||||
max: length - 1, |
||||
disabled: (length === 0) |
||||
}) |
||||
|
||||
if (state.disabled) { |
||||
sliderRef.current.setAttribute('disabled', true) |
||||
} else { |
||||
sliderRef.current.removeAttribute('disabled') |
||||
} |
||||
|
||||
setValue(0) |
||||
} |
||||
|
||||
const setValue = (value) => { |
||||
setState({ |
||||
...state, |
||||
currentValue: value |
||||
}) |
||||
} |
||||
|
||||
const handleChange = (e) => { |
||||
const value = parseInt(e.target.value) |
||||
|
||||
if (value === state.previousValue) return |
||||
setState({ |
||||
...state, |
||||
previousValue: value, |
||||
currentValue: value |
||||
}) |
||||
event.trigger('sliderMoved', [value]) |
||||
} |
||||
|
||||
return ( |
||||
<div> |
||||
<input id='slider' |
||||
data-id="slider" |
||||
className='w-100 my-0' |
||||
type='range' |
||||
min={0} |
||||
max={state.max} |
||||
value={state.currentValue} |
||||
onChange={handleChange} |
||||
disabled={state.disabled} |
||||
ref={sliderRef} |
||||
/> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default Slider |
@ -0,0 +1,11 @@ |
||||
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(); |
||||
}); |
||||
}); |
@ -0,0 +1,67 @@ |
||||
import React, { useState, useEffect } from 'react' |
||||
|
||||
export const Slider = ({ stepManager, sliderLength, sliderValue }) => { |
||||
const [state, setState] = useState({ |
||||
max: null, |
||||
disabled: true, |
||||
previousValue: null, |
||||
currentValue: null |
||||
}) |
||||
|
||||
useEffect(() => { |
||||
setState(prevState => { |
||||
return { |
||||
...prevState, |
||||
max: sliderLength - 1, |
||||
disabled: (sliderLength === 0) |
||||
} |
||||
}) |
||||
|
||||
setValue(0) |
||||
}, [sliderLength]) |
||||
|
||||
useEffect(() => { |
||||
setValue(sliderValue) |
||||
}, [sliderValue]) |
||||
|
||||
const setValue = (value) => { |
||||
setState(prevState => { |
||||
return { |
||||
...prevState, |
||||
currentValue: value |
||||
} |
||||
}) |
||||
} |
||||
|
||||
const handleChange = (e) => { |
||||
console.log('e.target: ', e.target) |
||||
const value = parseInt(e.target.value) |
||||
|
||||
if (value === state.previousValue) return |
||||
setState(prevState => { |
||||
return { |
||||
...prevState, |
||||
previousValue: value, |
||||
currentValue: value |
||||
} |
||||
}) |
||||
stepManager.jumpTo(value) |
||||
} |
||||
|
||||
return ( |
||||
<div> |
||||
<input id='slider' |
||||
data-id="slider" |
||||
className='w-100 my-0' |
||||
type='range' |
||||
min={0} |
||||
max={state.max} |
||||
value={state.currentValue} |
||||
onChange={handleChange} |
||||
disabled={state.disabled} |
||||
/> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default Slider |
@ -0,0 +1,11 @@ |
||||
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(); |
||||
}); |
||||
}); |
@ -0,0 +1,60 @@ |
||||
import React, { useState, useEffect } from 'react' |
||||
import './step-manager.css' |
||||
import Slider from '../slider/slider' |
||||
import ButtonNavigator from '../button-navigator/button-navigator' |
||||
|
||||
export const StepManager = ({ stepManager }) => { |
||||
const [state, setState] = useState({ |
||||
sliderLength: null, |
||||
sliderValue: 0, |
||||
revertWarning: '', |
||||
stepState: '', |
||||
jumpOutDisabled: true |
||||
}) |
||||
|
||||
useEffect(() => { |
||||
stepManager.event.register('traceLengthChanged', setSliderLength) |
||||
stepManager.event.register('revertWarning', setRevertWarning) |
||||
stepManager.event.register('stepChanged', updateStep) |
||||
}, []) |
||||
|
||||
const setSliderLength = (length) => { |
||||
setState(prevState => { |
||||
return { |
||||
...prevState, |
||||
sliderLength: length |
||||
} |
||||
}) |
||||
} |
||||
|
||||
const setRevertWarning = (warning) => { |
||||
setState(prevState => { |
||||
return { |
||||
...prevState, |
||||
revertWarning: warning |
||||
} |
||||
}) |
||||
} |
||||
|
||||
const updateStep = (step, stepState, jumpOutDisabled) => { |
||||
setState(prevState => { |
||||
return { |
||||
...prevState, |
||||
sliderValue: step, |
||||
stepState, |
||||
jumpOutDisabled |
||||
} |
||||
}) |
||||
} |
||||
|
||||
const { sliderLength, sliderValue, revertWarning, stepState, jumpOutDisabled } = state |
||||
|
||||
return ( |
||||
<div className="py-1"> |
||||
<Slider stepManager={stepManager} sliderLength={sliderLength} sliderValue={sliderValue} /> |
||||
<ButtonNavigator stepManager={stepManager} revertedReason={revertWarning} stepState={stepState} jumpOutDisabled={jumpOutDisabled} /> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default StepManager |
Loading…
Reference in new issue