padding and format

pull/749/head
LianaHus 4 years ago committed by ioedeveloper
parent 7f4d4734c8
commit 8860c2842e
  1. 372
      libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx

@ -6,206 +6,206 @@ import { initialState, reducer } from '../../reducers/calldata'
import './styles/dropdown-panel.css' import './styles/dropdown-panel.css'
export const DropdownPanel = (props: DropdownPanelProps) => { export const DropdownPanel = (props: DropdownPanelProps) => {
const [calldataObj, dispatch] = useReducer(reducer, initialState) const [calldataObj, dispatch] = useReducer(reducer, initialState)
const { dropdownName, dropdownMessage, calldata, header, loading, extractFunc, formatSelfFunc, registerEvent, triggerEvent, loadMoreEvent, loadMoreCompletedEvent } = props const { dropdownName, dropdownMessage, calldata, header, loading, extractFunc, formatSelfFunc, registerEvent, triggerEvent, loadMoreEvent, loadMoreCompletedEvent } = props
const extractDataDefault: ExtractFunc = (item, parent?) => { const extractDataDefault: ExtractFunc = (item, parent?) => {
const ret: ExtractData = {} const ret: ExtractData = {}
if (item instanceof Array) { if (item instanceof Array) {
ret.children = item.map((item, index) => { ret.children = item.map((item, index) => {
return {key: index, value: item} return { key: index, value: item }
}) })
ret.self = 'Array' ret.self = 'Array'
ret.isNode = true ret.isNode = true
ret.isLeaf = false ret.isLeaf = false
} else if (item instanceof Object) { } else if (item instanceof Object) {
ret.children = Object.keys(item).map((key) => { ret.children = Object.keys(item).map((key) => {
return {key: key, value: item[key]} return { key: key, value: item[key] }
}) })
ret.self = 'Object' ret.self = 'Object'
ret.isNode = true ret.isNode = true
ret.isLeaf = false ret.isLeaf = false
} else { } else {
ret.self = item ret.self = item
ret.children = null ret.children = null
ret.isNode = false ret.isNode = false
ret.isLeaf = true ret.isLeaf = true
}
return ret
} }
const formatSelfDefault = (key: string | number, data: ExtractData) => { return ret
return ( }
<div className="d-flex mb-1 flex-row label_item"> const formatSelfDefault = (key: string | number, data: ExtractData) => {
<label className="small font-weight-bold pr-1 label_key">{key}:</label> return (
<label className="m-0 label_value">{data.self}</label> <div className="d-flex mb-1 flex-row label_item">
</div> <label className="small font-weight-bold pr-1 label_key">{key}:</label>
) <label className="m-0 label_value">{data.self}</label>
</div>
)
}
const [state, setState] = useState({
header: '',
toggleDropdown: false,
message: {
innerText: 'No data available.',
display: 'block'
},
dropdownContent: {
innerText: '',
display: 'none'
},
title: {
innerText: '',
display: 'none'
},
copiableContent: '',
updating: false,
expandPath: [],
data: null
})
useEffect(() => {
registerEvent && registerEvent(loadMoreCompletedEvent, (updatedCalldata) => {
dispatch({ type: 'UPDATE_CALLDATA_SUCCESS', payload: updatedCalldata })
})
}, [])
useEffect(() => {
dispatch({ type: 'FETCH_CALLDATA_SUCCESS', payload: calldata })
}, [calldata])
useEffect(() => {
update(calldata)
}, [calldataObj.calldata])
useEffect(() => {
message(dropdownMessage)
}, [dropdownMessage])
useEffect(() => {
if (loading && !state.updating) setLoading()
}, [loading])
const handleToggle = () => {
setState(prevState => {
return {
...prevState,
toggleDropdown: !prevState.toggleDropdown
}
})
}
const handleExpand = (keyPath) => {
if (!state.expandPath.includes(keyPath)) {
state.expandPath.push(keyPath)
} else {
state.expandPath = state.expandPath.filter(path => !path.startsWith(keyPath))
} }
const [state, setState] = useState({ }
header: '',
toggleDropdown: false, const message = (message) => {
if (message === state.message.innerText) return
setState(prevState => {
return {
...prevState,
message: { message: {
innerText: 'No data available.', innerText: message,
display: 'block' display: message ? 'block' : ''
}, },
dropdownContent: { updating: false
innerText: '', }
display: 'none' })
}
const setLoading = () => {
setState(prevState => {
return {
...prevState,
message: {
innerText: '',
display: 'none'
}, },
title: { dropdownContent: {
innerText: '', ...prevState.dropdownContent,
display: 'none' display: 'none'
}, },
copiableContent: '', copiableContent: '',
updating: false, updating: true
expandPath: [], }
data: null
}) })
}
useEffect(() => { const update = function (calldata) {
registerEvent && registerEvent(loadMoreCompletedEvent, (updatedCalldata) => { let isEmpty = !calldata ? true : false
dispatch({ type: 'UPDATE_CALLDATA_SUCCESS', payload: updatedCalldata })
})
}, [])
useEffect(() => {
dispatch({ type: 'FETCH_CALLDATA_SUCCESS', payload: calldata })
}, [calldata])
useEffect(() => {
update(calldata)
}, [calldataObj.calldata])
useEffect(() => {
message(dropdownMessage)
}, [dropdownMessage])
useEffect(() => {
if (loading && !state.updating) setLoading()
}, [loading])
const handleToggle = () => {
setState(prevState => {
return {
...prevState,
toggleDropdown: !prevState.toggleDropdown
}
})
}
const handleExpand = (keyPath) => {
if (!state.expandPath.includes(keyPath)) {
state.expandPath.push(keyPath)
} else {
state.expandPath = state.expandPath.filter(path => !path.startsWith(keyPath))
}
}
const message = (message) => {
if (message === state.message.innerText) return
setState(prevState => {
return {
...prevState,
message: {
innerText: message,
display: message ? 'block' : ''
},
updating: false
}
})
}
const setLoading = () => { if (calldata && Array.isArray(calldata) && calldata.length === 0) isEmpty = true
setState(prevState => { else if (calldata && Object.keys(calldata).length === 0 && calldata.constructor === Object) isEmpty = true
return {
...prevState,
message: {
innerText: '',
display: 'none'
},
dropdownContent: {
...prevState.dropdownContent,
display: 'none'
},
copiableContent: '',
updating: true
}
})
}
const update = function (calldata) { setState(prevState => {
let isEmpty = !calldata ? true : false return {
...prevState,
if(calldata && Array.isArray(calldata) && calldata.length === 0) isEmpty = true dropdownContent: {
else if(calldata && Object.keys(calldata).length === 0 && calldata.constructor === Object) isEmpty = true ...prevState.dropdownContent,
display: 'block'
setState(prevState => { },
return { copiableContent: JSON.stringify(calldata, null, '\t'),
...prevState, message: {
dropdownContent: { innerText: isEmpty ? 'No data available' : '',
...prevState.dropdownContent, display: isEmpty ? 'block' : 'none'
display: 'block' },
}, updating: false,
copiableContent: JSON.stringify(calldata, null, '\t'), toggleDropdown: !isEmpty,
message: { data: calldata
innerText: isEmpty ? 'No data available' : '', }
display: isEmpty ? 'block' : 'none' })
}, }
updating: false,
toggleDropdown: !isEmpty, const renderData = (item: ExtractData, parent, key: string | number, keyPath: string) => {
data: calldata const data = extractFunc ? extractFunc(item, parent) : extractDataDefault(item, parent)
} const children = (data.children || []).map((child) => {
}) return (
} renderData(child.value, data, child.key, keyPath + '/' + child.key)
)
})
const renderData = (item: ExtractData, parent, key: string | number, keyPath: string) => { if (children && children.length > 0) {
const data = extractFunc ? extractFunc(item, parent) : extractDataDefault(item, parent) return (
const children = (data.children || []).map((child) => { <TreeViewItem id={`treeViewItem${key}`} key={keyPath} label={formatSelfFunc ? formatSelfFunc(key, data) : formatSelfDefault(key, data)} onClick={() => handleExpand(keyPath)} expand={state.expandPath.includes(keyPath)}>
return ( <TreeView id={`treeView${key}`} key={keyPath}>
renderData(child.value, data, child.key, keyPath + '/' + child.key) {children}
) {data.hasNext && <TreeViewItem id={`treeViewLoadMore`} data-id={`treeViewLoadMore`} className="cursor_pointer" label="Load more" onClick={() => { triggerEvent(loadMoreEvent, [data.cursor]) }} />}
}) </TreeView>
</TreeViewItem>
if (children && children.length > 0 ) { )
return ( } else {
<TreeViewItem id={`treeViewItem${key}`} key={keyPath} label={ formatSelfFunc ? formatSelfFunc(key, data) : formatSelfDefault(key, data) } onClick={() => handleExpand(keyPath)} expand={state.expandPath.includes(keyPath)}> return <TreeViewItem id={key.toString()} key={keyPath} label={formatSelfFunc ? formatSelfFunc(key, data) : formatSelfDefault(key, data)} onClick={() => handleExpand(keyPath)} expand={state.expandPath.includes(keyPath)} />
<TreeView id={`treeView${key}`} key={keyPath}>
{ children }
{ data.hasNext && <TreeViewItem id={`treeViewLoadMore`} data-id={`treeViewLoadMore`} className="cursor_pointer" label="Load more" onClick={() => { triggerEvent(loadMoreEvent, [data.cursor]) }} /> }
</TreeView>
</TreeViewItem>
)
} else {
return <TreeViewItem id={key.toString()} key={keyPath} label={ formatSelfFunc ? formatSelfFunc(key, data) : formatSelfDefault(key, data) } onClick={() => handleExpand(keyPath)} expand={state.expandPath.includes(keyPath)} />
}
} }
}
const uniquePanelName = dropdownName.split(' ').join('')
const uniquePanelName = dropdownName.split(' ').join('')
return (
<div className="border rounded px-1 mt-1 bg-light"> return (
<div className="py-0 px-1 title"> <div className="border rounded px-1 mt-1 bg-light">
<div className={state.toggleDropdown ? 'icon fas fa-caret-down' : 'icon fas fa-caret-right'} onClick={handleToggle}></div> <div className="py-0 px-1 title">
<div className="name" data-id={`dropdownPanel${uniquePanelName}`} onClick={handleToggle}>{dropdownName}</div><span className="nameDetail" onClick={handleToggle}>{ header }</span> <div className={state.toggleDropdown ? 'icon fas fa-caret-down' : 'icon fas fa-caret-right'} onClick={handleToggle}></div>
<CopyToClipboard content={state.copiableContent} data-id={`dropdownPanelCopyToClipboard${uniquePanelName}`} /> <div className="name" data-id={`dropdownPanel${uniquePanelName}`} onClick={handleToggle}>{dropdownName}</div><span className="nameDetail" onClick={handleToggle}>{header}</span>
</div> <CopyToClipboard content={state.copiableContent} data-id={`dropdownPanelCopyToClipboard${uniquePanelName}`} />
<div className='dropdownpanel' style={{ display: state.toggleDropdown ? 'block' : 'none' }}> </div>
<i className="refresh fas fa-sync" style={{ display: state.updating ? 'inline-block' : 'none' }} aria-hidden="true"></i> <div className='dropdownpanel' style={{ display: state.toggleDropdown ? 'block' : 'none' }}>
<div className='dropdowncontent' style={{ display: state.dropdownContent.display }}> <i className="refresh fas fa-sync" style={{ display: state.updating ? 'inline-block' : 'none' }} aria-hidden="true"></i>
{ <div className='dropdowncontent' style={{ display: state.dropdownContent.display }}>
state.data && {
<TreeView id="treeView"> state.data &&
{ <TreeView id="treeView">
Object.keys(state.data).map((innerkey) => renderData(state.data[innerkey], state.data, innerkey, innerkey)) {
} Object.keys(state.data).map((innerkey) => renderData(state.data[innerkey], state.data, innerkey, innerkey))
</TreeView> }
} </TreeView>
</div> }
<div className='dropdownrawcontent' hidden={true}>{ state.copiableContent }</div>
<div className='message' style={{ display: state.message.display }}>{ state.message.innerText }</div>
</div>
</div> </div>
) <div className='dropdownrawcontent' hidden={true}>{state.copiableContent}</div>
<div className='message' style={{ display: state.message.display }}>{state.message.innerText}</div>
</div>
</div>
)
} }
export default DropdownPanel export default DropdownPanel
Loading…
Cancel
Save