Modify UI for multifield and single fields

pull/2260/head
David Disu 3 years ago
parent 998eedc1b7
commit beba1ba95d
  1. 10
      libs/remix-ui/run-tab/src/lib/actions/deploy.ts
  2. 158
      libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx
  3. 1
      libs/remix-ui/run-tab/src/lib/css/run-tab.css
  4. 2
      libs/remix-ui/run-tab/src/lib/types/index.ts

@ -157,11 +157,6 @@ export const createInstance = async (
} else { } else {
_paq.push(['trackEvent', 'udapp', 'DeployOnly', plugin.REACT_API.networkName]) _paq.push(['trackEvent', 'udapp', 'DeployOnly', plugin.REACT_API.networkName])
} }
deployMode.forEach(async (mode) => {
const owner = plugin.REACT_API.accounts.selectedAccount
if (mode === 'Deploy with Proxy') await plugin.call('openzeppelin-proxy', 'execute', address, owner)
})
} }
let contractMetadata let contractMetadata
@ -173,10 +168,11 @@ export const createInstance = async (
const compilerContracts = getCompilerContracts(plugin) const compilerContracts = getCompilerContracts(plugin)
const confirmationCb = getConfirmationCb(plugin, dispatch, mainnetPrompt) const confirmationCb = getConfirmationCb(plugin, dispatch, mainnetPrompt)
const isProxyDeployment = (deployMode || []).find(mode => mode === 'Deploy with Proxy')
if (selectedContract.isOverSizeLimit()) { if (selectedContract.isOverSizeLimit()) {
return dispatch(displayNotification('Contract code size over limit', isOverSizePrompt(), 'Force Send', 'Cancel', () => { return dispatch(displayNotification('Contract code size over limit', isOverSizePrompt(), 'Force Send', 'Cancel', () => {
deployContract(plugin, selectedContract, args, contractMetadata, compilerContracts, { deployContract(plugin, selectedContract, !isProxyDeployment ? args : '', contractMetadata, compilerContracts, {
continueCb: (error, continueTxExecution, cancelCb) => { continueCb: (error, continueTxExecution, cancelCb) => {
continueHandler(dispatch, gasEstimationPrompt, error, continueTxExecution, cancelCb) continueHandler(dispatch, gasEstimationPrompt, error, continueTxExecution, cancelCb)
}, },
@ -192,7 +188,7 @@ export const createInstance = async (
return terminalLogger(plugin, log) return terminalLogger(plugin, log)
})) }))
} }
deployContract(plugin, selectedContract, args, contractMetadata, compilerContracts, { deployContract(plugin, selectedContract, !isProxyDeployment ? args : '', contractMetadata, compilerContracts, {
continueCb: (error, continueTxExecution, cancelCb) => { continueCb: (error, continueTxExecution, cancelCb) => {
continueHandler(dispatch, gasEstimationPrompt, error, continueTxExecution, cancelCb) continueHandler(dispatch, gasEstimationPrompt, error, continueTxExecution, cancelCb)
}, },

@ -9,7 +9,7 @@ const txFormat = remixLib.execution.txFormat
export function ContractGUI (props: ContractGUIProps) { export function ContractGUI (props: ContractGUIProps) {
const [title, setTitle] = useState<string>('') const [title, setTitle] = useState<string>('')
const [basicInput, setBasicInput] = useState<string>('') const [basicInput, setBasicInput] = useState<string>('')
const [toggleContainer, setToggleContainer] = useState<boolean>(false) // const [toggleContainer, setToggleContainer] = useState<boolean>(false)
const [buttonOptions, setButtonOptions] = useState<{ const [buttonOptions, setButtonOptions] = useState<{
title: string, title: string,
content: string, content: string,
@ -19,6 +19,7 @@ export function ContractGUI (props: ContractGUIProps) {
const [selectedDeployIndex, setSelectedDeployIndex] = useState<number[]>([]) const [selectedDeployIndex, setSelectedDeployIndex] = useState<number[]>([])
const [showOptions, setShowOptions] = useState<boolean>(false) const [showOptions, setShowOptions] = useState<boolean>(false)
const [hasArgs, setHasArgs] = useState<boolean>(false) const [hasArgs, setHasArgs] = useState<boolean>(false)
const [isMultiField, setIsMultiField] = useState<boolean>(false)
const multiFields = useRef<Array<HTMLInputElement | null>>([]) const multiFields = useRef<Array<HTMLInputElement | null>>([])
const basicInputRef = useRef<HTMLInputElement>() const basicInputRef = useRef<HTMLInputElement>()
@ -93,15 +94,26 @@ export function ContractGUI (props: ContractGUIProps) {
} }
} }
const switchMethodViewOn = () => { useEffect(() => {
setToggleContainer(true) if (props.initializerOptions) {
makeMultiVal() if (props.initializerOptions.inputs.inputs.length > 1) setIsMultiField(true)
} else setIsMultiField(false)
} else if (props.funcABI) {
if (props.funcABI.inputs.length > 1) setIsMultiField(true)
else setIsMultiField(false)
} else setIsMultiField(false)
}, [props.initializerOptions, props.funcABI])
const switchMethodViewOff = () => { // const switchMethodViewOn = () => {
setToggleContainer(false) // setToggleContainer(true)
const multiValString = getMultiValsString() // makeMultiVal()
// }
const switchMethodViewOff = () => {
// setToggleContainer(false)
let multiValString = getMultiValsString()
multiValString = multiValString.replace(/["]+/g, '')
if (multiValString) setBasicInput(multiValString) if (multiValString) setBasicInput(multiValString)
} }
@ -141,7 +153,9 @@ export function ContractGUI (props: ContractGUIProps) {
if (inputString) { if (inputString) {
inputString = inputString.replace(/(^|,\s+|,)(\d+)(\s+,|,|$)/g, '$1"$2"$3') // replace non quoted number by quoted number inputString = inputString.replace(/(^|,\s+|,)(\d+)(\s+,|,|$)/g, '$1"$2"$3') // replace non quoted number by quoted number
inputString = inputString.replace(/(^|,\s+|,)(0[xX][0-9a-fA-F]+)(\s+,|,|$)/g, '$1"$2"$3') // replace non quoted hex string by quoted hex string inputString = inputString.replace(/(^|,\s+|,)(0[xX][0-9a-fA-F]+)(\s+,|,|$)/g, '$1"$2"$3') // replace non quoted hex string by quoted hex string
const inputJSON = JSON.parse('[' + inputString + ']') inputString = JSON.stringify([inputString])
const inputJSON = JSON.parse(inputString)
const multiInputs = multiFields.current const multiInputs = multiFields.current
for (let k = 0; k < multiInputs.length; k++) { for (let k = 0; k < multiInputs.length; k++) {
@ -164,7 +178,7 @@ export function ContractGUI (props: ContractGUIProps) {
setBasicInput(value) setBasicInput(value)
} }
const handleExpandMultiClick = () => { const handleMultiValsSubmit = () => {
const valsString = getMultiValsString() const valsString = getMultiValsString()
if (valsString) { if (valsString) {
@ -189,37 +203,44 @@ export function ContractGUI (props: ContractGUIProps) {
return ( return (
<div className={`udapp_contractProperty ${hasArgs ? 'udapp_hasArgs' : ''}`}> <div className={`udapp_contractProperty ${hasArgs ? 'udapp_hasArgs' : ''}`}>
<div className="udapp_contractActionsContainerSingle pt-2" style={{ display: toggleContainer ? 'none' : 'flex' }}> <div className="udapp_contractActionsContainerSingle pt-2" style={{ display: 'flex' }}>
{ {
props.isDeploy && (props.deployOption || []).length > 0 ? props.isDeploy && !isMultiField && (props.deployOption || []).length > 0 &&
<Dropdown as={ButtonGroup} show={showOptions}> <Dropdown as={ButtonGroup} show={showOptions}>
<button onClick={handleActionClick} title={buttonOptions.title} className={`udapp_instanceButton ${props.widthClass} btn btn-sm ${buttonOptions.classList}`} data-id={buttonOptions.dataId}>Deploy</button> <button onClick={handleActionClick} title={buttonOptions.title} className={`udapp_instanceButton ${props.widthClass} btn btn-sm ${buttonOptions.classList}`} data-id={buttonOptions.dataId}>Deploy</button>
<Dropdown.Toggle split id="dropdown-split-basic" className={`btn btn-sm dropdown-toggle dropdown-toggle-split ${buttonOptions.classList}`} style={{ maxWidth: 25, minWidth: 0, height: 32 }} onClick={toggleOptions} /> <Dropdown.Toggle split id="dropdown-split-basic" className={`btn btn-sm dropdown-toggle dropdown-toggle-split ${buttonOptions.classList}`} style={{ maxWidth: 25, minWidth: 0, height: 32 }} onClick={toggleOptions} />
<Dropdown.Menu className="deploy-items border-0"> <Dropdown.Menu className="deploy-items border-0">
{ {
(props.deployOption).map(({ title, active }, index) => <Dropdown.Item onClick={() => setSelectedDeploy(index)}> { selectedDeployIndex.includes(index) ? <span>&#10003; {title} </span> : <span className="pl-3">{title}</span> }</Dropdown.Item>) (props.deployOption).map(({ title, active }, index) => <Dropdown.Item onClick={() => setSelectedDeploy(index)} key={index}> { selectedDeployIndex.includes(index) ? <span>&#10003; {title} </span> : <span className="pl-3">{title}</span> }</Dropdown.Item>)
} }
</Dropdown.Menu> </Dropdown.Menu>
</Dropdown> : <button onClick={handleActionClick} title={buttonOptions.title} className={`udapp_instanceButton ${props.widthClass} btn btn-sm ${buttonOptions.classList}`} data-id={buttonOptions.dataId}>{title}</button> </Dropdown>
} }
{ {
props.isDeploy && props.initializerOptions && (props.initializerOptions.inputs.inputs.length > 0) ? props.isDeploy && !isMultiField && !props.deployOption &&
<> <button onClick={handleActionClick} title={buttonOptions.title} className={`udapp_instanceButton ${props.widthClass} btn btn-sm ${buttonOptions.classList}`} data-id={buttonOptions.dataId}>{title}</button>
<input }
className="form-control" {
data-id={props.initializerOptions.inputs.type === 'fallback' || props.initializerOptions.inputs.type === 'receive' ? `'(${props.initializerOptions.inputs.type}')` : 'multiParamManagerBasicInputField'} props.isDeploy && !isMultiField && props.initializerOptions &&
placeholder={props.initializerOptions.initializeInputs} <>
title={props.initializerOptions.inputs.type === 'fallback' || props.initializerOptions.inputs.type === 'receive' ? `'(${props.initializerOptions.inputs.type}')` : props.initializerOptions.initializeInputs} <input
onChange={handleBasicInput} className="form-control"
ref={basicInputRef} data-id={props.initializerOptions.inputs.type === 'fallback' || props.initializerOptions.inputs.type === 'receive' ? `'(${props.initializerOptions.inputs.type}')` : 'multiParamManagerBasicInputField'}
style={{ visibility: !((props.initializerOptions.inputs.inputs && props.initializerOptions.inputs.inputs.length > 0) || (props.initializerOptions.inputs.type === 'fallback') || (props.initializerOptions.inputs.type === 'receive')) ? 'hidden' : 'visible' }} /> placeholder={props.initializerOptions.initializeInputs}
<i title={props.initializerOptions.inputs.type === 'fallback' || props.initializerOptions.inputs.type === 'receive' ? `'(${props.initializerOptions.inputs.type}')` : props.initializerOptions.initializeInputs}
className="fas fa-angle-down udapp_methCaret" onChange={handleBasicInput}
onClick={switchMethodViewOn} ref={basicInputRef}
title={title} style={{ visibility: !((props.initializerOptions.inputs.inputs && props.initializerOptions.inputs.inputs.length > 0) || (props.initializerOptions.inputs.type === 'fallback') || (props.initializerOptions.inputs.type === 'receive')) ? 'hidden' : 'visible' }} />
style={{ visibility: !(props.initializerOptions.inputs.inputs && props.initializerOptions.inputs.inputs.length > 0) ? 'hidden' : 'visible' }}> {/* <i
</i> className="fas fa-angle-down udapp_methCaret"
</> : onClick={switchMethodViewOn}
title={title}
style={{ visibility: !(props.initializerOptions.inputs.inputs && props.initializerOptions.inputs.inputs.length > 0) ? 'hidden' : 'visible' }}>
</i> */}
</>
}
{
props.isDeploy && !isMultiField && props.funcABI &&
<> <>
<input <input
className="form-control" className="form-control"
@ -229,25 +250,58 @@ export function ContractGUI (props: ContractGUIProps) {
onChange={handleBasicInput} onChange={handleBasicInput}
ref={basicInputRef} ref={basicInputRef}
style={{ visibility: !((props.funcABI.inputs && props.funcABI.inputs.length > 0) || (props.funcABI.type === 'fallback') || (props.funcABI.type === 'receive')) ? 'hidden' : 'visible' }} /> style={{ visibility: !((props.funcABI.inputs && props.funcABI.inputs.length > 0) || (props.funcABI.type === 'fallback') || (props.funcABI.type === 'receive')) ? 'hidden' : 'visible' }} />
<i {/* <i
className="fas fa-angle-down udapp_methCaret" className="fas fa-angle-down udapp_methCaret"
onClick={switchMethodViewOn} onClick={switchMethodViewOn}
title={title} title={title}
style={{ visibility: !(props.funcABI.inputs && props.funcABI.inputs.length > 0) ? 'hidden' : 'visible' }}> style={{ visibility: !(props.funcABI.inputs && props.funcABI.inputs.length > 0) ? 'hidden' : 'visible' }}>
</i> </i> */}
</> </>
} }
</div> </div>
{ { isMultiField ?
props.isDeploy && props.initializerOptions && (props.initializerOptions.inputs.inputs.length > 0) ? props.isDeploy && props.initializerOptions ?
<div className="udapp_contractActionsContainerMulti" style={{ display: toggleContainer ? 'flex' : 'none' }}> <div className="udapp_contractActionsContainerMulti" style={{ display: 'flex' }}>
<div className="udapp_contractActionsContainerMultiInner text-dark">
{/* <div onClick={switchMethodViewOff} className="udapp_multiHeader">
<div className="udapp_multiTitle run-instance-multi-title">{title}</div>
<i className='fas fa-angle-up udapp_methCaret'></i>
</div> */}
<div>
{props.initializerOptions.inputs.inputs.map((inp, index) => {
return (
<div className="udapp_multiArg" key={index}>
<label htmlFor={inp.name}> {inp.name}: </label>
<input ref={el => { multiFields.current[index] = el }} className="form-control" placeholder={inp.type} title={inp.name} data-id={`multiParamManagerInput${inp.name}`} />
</div>)
})}
</div>
<div className="udapp_group udapp_multiArg">
{/* <CopyToClipboard tip='Encode values of input fields & copy to clipboard' icon='fa-clipboard' direction={'left'} getContent={getContentOnCTC} /> */}
{
(props.deployOption || []).length > 0 ?
<Dropdown as={ButtonGroup} show={showOptions}>
<button onClick={handleMultiValsSubmit} title={buttonOptions.title} className={`udapp_instanceButton ${props.widthClass} btn btn-sm ${buttonOptions.classList}`} data-id={buttonOptions.dataId}>Deploy</button>
<Dropdown.Toggle split id="dropdown-split-basic" className={`btn btn-sm dropdown-toggle dropdown-toggle-split ${buttonOptions.classList}`} style={{ maxWidth: 25, minWidth: 0, height: 32 }} onClick={toggleOptions} />
<Dropdown.Menu className="deploy-items border-0">
{
(props.deployOption).map(({ title, active }, index) => <Dropdown.Item onClick={() => setSelectedDeploy(index)} key={index}> { selectedDeployIndex.includes(index) ? <span>&#10003; {title} </span> : <span className="pl-3">{title}</span> }</Dropdown.Item>)
}
</Dropdown.Menu>
</Dropdown> :
<button onClick={handleMultiValsSubmit} title={buttonOptions.title} data-id={buttonOptions.dataId} className={`udapp_instanceButton ${buttonOptions.classList}`}>{ title }</button>
}
</div>
</div>
</div> :
<div className="udapp_contractActionsContainerMulti" style={{ display: 'flex' }}>
<div className="udapp_contractActionsContainerMultiInner text-dark"> <div className="udapp_contractActionsContainerMultiInner text-dark">
<div onClick={switchMethodViewOff} className="udapp_multiHeader"> {/* <div onClick={switchMethodViewOff} className="udapp_multiHeader">
<div className="udapp_multiTitle run-instance-multi-title">{title}</div> <div className="udapp_multiTitle run-instance-multi-title">{title}</div>
<i className='fas fa-angle-up udapp_methCaret'></i> <i className='fas fa-angle-up udapp_methCaret'></i>
</div> </div> */}
<div> <div>
{props.initializerOptions.inputs.inputs.map((inp, index) => { {props.funcABI.inputs.map((inp, index) => {
return ( return (
<div className="udapp_multiArg" key={index}> <div className="udapp_multiArg" key={index}>
<label htmlFor={inp.name}> {inp.name}: </label> <label htmlFor={inp.name}> {inp.name}: </label>
@ -256,32 +310,12 @@ export function ContractGUI (props: ContractGUIProps) {
})} })}
</div> </div>
<div className="udapp_group udapp_multiArg"> <div className="udapp_group udapp_multiArg">
{/* <CopyToClipboard tip='Encode values of input fields & copy to clipboard' icon='fa-clipboard' direction={'left'} getContent={getContentOnCTC} /> */} <CopyToClipboard tip='Encode values of input fields & copy to clipboard' icon='fa-clipboard' direction={'left'} getContent={getContentOnCTC} />
<button onClick={handleExpandMultiClick} title={buttonOptions.title} data-id={buttonOptions.dataId} className={`udapp_instanceButton ${buttonOptions.classList}`}>{ buttonOptions.content }</button> <button onClick={handleMultiValsSubmit} title={buttonOptions.title} data-id={buttonOptions.dataId} className={`udapp_instanceButton ${buttonOptions.classList}`}>{ buttonOptions.content }</button>
</div> </div>
</div> </div>
</div> :
<div className="udapp_contractActionsContainerMulti" style={{ display: toggleContainer ? 'flex' : 'none' }}>
<div className="udapp_contractActionsContainerMultiInner text-dark">
<div onClick={switchMethodViewOff} className="udapp_multiHeader">
<div className="udapp_multiTitle run-instance-multi-title">{title}</div>
<i className='fas fa-angle-up udapp_methCaret'></i>
</div>
<div>
{props.funcABI.inputs.map((inp, index) => {
return (
<div className="udapp_multiArg" key={index}>
<label htmlFor={inp.name}> {inp.name}: </label>
<input ref={el => { multiFields.current[index] = el }} className="form-control" placeholder={inp.type} title={inp.name} data-id={`multiParamManagerInput${inp.name}`} />
</div>)
})}
</div>
<div className="udapp_group udapp_multiArg">
<CopyToClipboard tip='Encode values of input fields & copy to clipboard' icon='fa-clipboard' direction={'left'} getContent={getContentOnCTC} />
<button onClick={handleExpandMultiClick} title={buttonOptions.title} data-id={buttonOptions.dataId} className={`udapp_instanceButton ${buttonOptions.classList}`}>{ buttonOptions.content }</button>
</div>
</div> </div>
</div> : null
} }
</div> </div>
) )

@ -401,7 +401,6 @@
} }
.udapp_contractActionsContainerMultiInner { .udapp_contractActionsContainerMultiInner {
width: 100%; width: 100%;
padding: 16px 8px 16px 14px;
border-radius: 3px; border-radius: 3px;
margin-bottom: 8px; margin-bottom: 8px;
} }

@ -259,7 +259,7 @@ export interface ContractGUIProps {
disabled?: boolean, disabled?: boolean,
isDeploy?: boolean, isDeploy?: boolean,
deployOption?: { title: DeployMode, active: boolean }[], deployOption?: { title: DeployMode, active: boolean }[],
initializerOptions: DeployOption initializerOptions?: DeployOption
} }
export interface MainnetProps { export interface MainnetProps {
network: Network, network: Network,

Loading…
Cancel
Save