|
|
|
@ -1,27 +1,38 @@ |
|
|
|
|
// eslint-disable-next-line no-use-before-define
|
|
|
|
|
import React, { useEffect, useRef, useState } from 'react' |
|
|
|
|
import { FormattedMessage, useIntl } from 'react-intl' |
|
|
|
|
import React, {useEffect, useRef, useState} from 'react' |
|
|
|
|
import {FormattedMessage, useIntl} from 'react-intl' |
|
|
|
|
import * as remixLib from '@remix-project/remix-lib' |
|
|
|
|
import { ContractGUIProps } from '../types' |
|
|
|
|
import { CopyToClipboard } from '@remix-ui/clipboard' |
|
|
|
|
import { CustomTooltip, ProxyAddressToggle, ProxyDropdownMenu, shortenDate, shortenProxyAddress, unavailableProxyLayoutMsg, upgradeReportMsg } from '@remix-ui/helper' |
|
|
|
|
import { Dropdown } from 'react-bootstrap' |
|
|
|
|
import {ContractGUIProps} from '../types' |
|
|
|
|
import {CopyToClipboard} from '@remix-ui/clipboard' |
|
|
|
|
import { |
|
|
|
|
CustomTooltip, |
|
|
|
|
ProxyAddressToggle, |
|
|
|
|
ProxyDropdownMenu, |
|
|
|
|
shortenDate, |
|
|
|
|
shortenProxyAddress, |
|
|
|
|
unavailableProxyLayoutMsg, |
|
|
|
|
upgradeReportMsg |
|
|
|
|
} from '@remix-ui/helper' |
|
|
|
|
import {Dropdown} from 'react-bootstrap' |
|
|
|
|
|
|
|
|
|
const txFormat = remixLib.execution.txFormat |
|
|
|
|
const txHelper = remixLib.execution.txHelper |
|
|
|
|
export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
export function ContractGUI(props: ContractGUIProps) { |
|
|
|
|
const [title, setTitle] = useState<string>('') |
|
|
|
|
const [basicInput, setBasicInput] = useState<string>('') |
|
|
|
|
const [toggleContainer, setToggleContainer] = useState<boolean>(false) |
|
|
|
|
const [buttonOptions, setButtonOptions] = useState<{ |
|
|
|
|
title: string, |
|
|
|
|
content: string, |
|
|
|
|
classList: string, |
|
|
|
|
title: string |
|
|
|
|
content: string |
|
|
|
|
classList: string |
|
|
|
|
dataId: string |
|
|
|
|
}>({ title: '', content: '', classList: '', dataId: '' }) |
|
|
|
|
}>({title: '', content: '', classList: '', dataId: ''}) |
|
|
|
|
const [toggleDeployProxy, setToggleDeployProxy] = useState<boolean>(false) |
|
|
|
|
const [toggleUpgradeImp, setToggleUpgradeImp] = useState<boolean>(false) |
|
|
|
|
const [deployState, setDeployState] = useState<{ deploy: boolean, upgrade: boolean }>({ deploy: false, upgrade: false }) |
|
|
|
|
const [deployState, setDeployState] = useState<{ |
|
|
|
|
deploy: boolean |
|
|
|
|
upgrade: boolean |
|
|
|
|
}>({deploy: false, upgrade: false}) |
|
|
|
|
const [proxyAddress, setProxyAddress] = useState<string>('') |
|
|
|
|
const [proxyAddressError, setProxyAddressError] = useState<string>('') |
|
|
|
|
const [showDropdown, setShowDropdown] = useState<boolean>(false) |
|
|
|
@ -32,8 +43,18 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
if (props.deployOption && Array.isArray(props.deployOption)) { |
|
|
|
|
if (props.deployOption[0] && props.deployOption[0].title === 'Deploy with Proxy' && props.deployOption[0].active) handleDeployProxySelect(true) |
|
|
|
|
else if (props.deployOption[1] && props.deployOption[1].title === 'Upgrade with Proxy' && props.deployOption[1].active) handleUpgradeImpSelect(true) |
|
|
|
|
if ( |
|
|
|
|
props.deployOption[0] && |
|
|
|
|
props.deployOption[0].title === 'Deploy with Proxy' && |
|
|
|
|
props.deployOption[0].active |
|
|
|
|
) |
|
|
|
|
handleDeployProxySelect(true) |
|
|
|
|
else if ( |
|
|
|
|
props.deployOption[1] && |
|
|
|
|
props.deployOption[1].title === 'Upgrade with Proxy' && |
|
|
|
|
props.deployOption[1].active |
|
|
|
|
) |
|
|
|
|
handleUpgradeImpSelect(true) |
|
|
|
|
} |
|
|
|
|
}, [props.deployOption]) |
|
|
|
|
|
|
|
|
@ -48,21 +69,26 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
setBasicInput('') |
|
|
|
|
// we have the reset the fields before reseting the previous references.
|
|
|
|
|
basicInputRef.current.value = '' |
|
|
|
|
multiFields.current.filter((el) => el !== null && el !== undefined).forEach((el) => el.value = '') |
|
|
|
|
multiFields.current |
|
|
|
|
.filter((el) => el !== null && el !== undefined) |
|
|
|
|
.forEach((el) => (el.value = '')) |
|
|
|
|
multiFields.current = [] |
|
|
|
|
}, [props.title, props.funcABI]) |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
if (props.lookupOnly) { |
|
|
|
|
// // call. stateMutability is either pure or view
|
|
|
|
|
// // call. stateMutability is either pure or view
|
|
|
|
|
setButtonOptions({ |
|
|
|
|
title: title + ' - call', |
|
|
|
|
content: 'call', |
|
|
|
|
classList: 'btn-info', |
|
|
|
|
dataId: title + ' - call' |
|
|
|
|
}) |
|
|
|
|
} else if (props.funcABI.stateMutability === 'payable' || props.funcABI.payable) { |
|
|
|
|
// // transact. stateMutability = payable
|
|
|
|
|
} else if ( |
|
|
|
|
props.funcABI.stateMutability === 'payable' || |
|
|
|
|
props.funcABI.payable |
|
|
|
|
) { |
|
|
|
|
// // transact. stateMutability = payable
|
|
|
|
|
setButtonOptions({ |
|
|
|
|
title: title + ' - transact (payable)', |
|
|
|
|
content: 'transact', |
|
|
|
@ -70,7 +96,7 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
dataId: title + ' - transact (payable)' |
|
|
|
|
}) |
|
|
|
|
} else { |
|
|
|
|
// // transact. stateMutability = nonpayable
|
|
|
|
|
// // transact. stateMutability = nonpayable
|
|
|
|
|
setButtonOptions({ |
|
|
|
|
title: title + ' - transact (not payable)', |
|
|
|
|
content: 'transact', |
|
|
|
@ -91,7 +117,8 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
const encodeObj = txFormat.encodeData( |
|
|
|
|
props.funcABI, |
|
|
|
|
multiJSON, |
|
|
|
|
props.funcABI.type === 'constructor' ? props.evmBC : null) |
|
|
|
|
props.funcABI.type === 'constructor' ? props.evmBC : null |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if (encodeObj.error) { |
|
|
|
|
console.error(encodeObj.error) |
|
|
|
@ -138,7 +165,10 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
|
|
|
|
|
valArrayTest.push(elVal) |
|
|
|
|
elVal = elVal.replace(/(^|,\s+|,)(\d+)(\s+,|,|$)/g, '$1"$2"$3') // replace non quoted number by quoted number
|
|
|
|
|
elVal = elVal.replace(/(^|,\s+|,)(0[xX][0-9a-fA-F]+)(\s+,|,|$)/g, '$1"$2"$3') // replace non quoted hex string by quoted hex string
|
|
|
|
|
elVal = elVal.replace( |
|
|
|
|
/(^|,\s+|,)(0[xX][0-9a-fA-F]+)(\s+,|,|$)/g, |
|
|
|
|
'$1"$2"$3' |
|
|
|
|
) // replace non quoted hex string by quoted hex string
|
|
|
|
|
if (elVal) { |
|
|
|
|
try { |
|
|
|
|
JSON.parse(elVal) |
|
|
|
@ -161,7 +191,8 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
const inputString = basicInput |
|
|
|
|
|
|
|
|
|
if (inputString) { |
|
|
|
|
const inputJSON = remixLib.execution.txFormat.parseFunctionParams(inputString) |
|
|
|
|
const inputJSON = |
|
|
|
|
remixLib.execution.txFormat.parseFunctionParams(inputString) |
|
|
|
|
const multiInputs = multiFields.current |
|
|
|
|
|
|
|
|
|
for (let k = 0; k < multiInputs.length; k++) { |
|
|
|
@ -175,26 +206,61 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
const handleActionClick = async () => { |
|
|
|
|
if (deployState.deploy) { |
|
|
|
|
const proxyInitializeString = getMultiValsString(initializeFields.current) |
|
|
|
|
props.clickCallBack(props.initializerOptions.inputs.inputs, proxyInitializeString, ['Deploy with Proxy']) |
|
|
|
|
props.clickCallBack( |
|
|
|
|
props.initializerOptions.inputs.inputs, |
|
|
|
|
proxyInitializeString, |
|
|
|
|
['Deploy with Proxy'] |
|
|
|
|
) |
|
|
|
|
} else if (deployState.upgrade) { |
|
|
|
|
if (proxyAddress === '') { |
|
|
|
|
setProxyAddressError('proxy address cannot be empty') |
|
|
|
|
} else { |
|
|
|
|
const isValidProxyAddress = await props.isValidProxyAddress(proxyAddress) |
|
|
|
|
const isValidProxyAddress = await props.isValidProxyAddress( |
|
|
|
|
proxyAddress |
|
|
|
|
) |
|
|
|
|
if (isValidProxyAddress) { |
|
|
|
|
setProxyAddressError('') |
|
|
|
|
const upgradeReport: any = await props.isValidProxyUpgrade(proxyAddress) |
|
|
|
|
const upgradeReport: any = await props.isValidProxyUpgrade( |
|
|
|
|
proxyAddress |
|
|
|
|
) |
|
|
|
|
if (upgradeReport.ok) { |
|
|
|
|
!proxyAddressError && props.clickCallBack(props.funcABI.inputs, proxyAddress, ['Upgrade with Proxy']) |
|
|
|
|
!proxyAddressError && |
|
|
|
|
props.clickCallBack(props.funcABI.inputs, proxyAddress, [ |
|
|
|
|
'Upgrade with Proxy' |
|
|
|
|
]) |
|
|
|
|
} else { |
|
|
|
|
if (upgradeReport.warning) { |
|
|
|
|
props.modal('Proxy Upgrade Warning', unavailableProxyLayoutMsg(), 'Proceed', () => { |
|
|
|
|
!proxyAddressError && props.clickCallBack(props.funcABI.inputs, proxyAddress, ['Upgrade with Proxy']) |
|
|
|
|
}, 'Cancel', () => {}, 'btn-warning', 'btn-secondary') |
|
|
|
|
props.modal( |
|
|
|
|
'Proxy Upgrade Warning', |
|
|
|
|
unavailableProxyLayoutMsg(), |
|
|
|
|
'Proceed', |
|
|
|
|
() => { |
|
|
|
|
!proxyAddressError && |
|
|
|
|
props.clickCallBack(props.funcABI.inputs, proxyAddress, [ |
|
|
|
|
'Upgrade with Proxy' |
|
|
|
|
]) |
|
|
|
|
}, |
|
|
|
|
'Cancel', |
|
|
|
|
() => {}, |
|
|
|
|
'btn-warning', |
|
|
|
|
'btn-secondary' |
|
|
|
|
) |
|
|
|
|
} else { |
|
|
|
|
props.modal('Proxy Upgrade Error', upgradeReportMsg(upgradeReport), 'Continue anyway ', () => { |
|
|
|
|
!proxyAddressError && props.clickCallBack(props.funcABI.inputs, proxyAddress, ['Upgrade with Proxy']) |
|
|
|
|
}, 'Cancel', () => {}, 'btn-warning', 'btn-secondary') |
|
|
|
|
props.modal( |
|
|
|
|
'Proxy Upgrade Error', |
|
|
|
|
upgradeReportMsg(upgradeReport), |
|
|
|
|
'Continue anyway ', |
|
|
|
|
() => { |
|
|
|
|
!proxyAddressError && |
|
|
|
|
props.clickCallBack(props.funcABI.inputs, proxyAddress, [ |
|
|
|
|
'Upgrade with Proxy' |
|
|
|
|
]) |
|
|
|
|
}, |
|
|
|
|
'Cancel', |
|
|
|
|
() => {}, |
|
|
|
|
'btn-warning', |
|
|
|
|
'btn-secondary' |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
@ -229,7 +295,7 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
const handleDeployProxySelect = (value: boolean) => { |
|
|
|
|
if (value) setToggleUpgradeImp(false) |
|
|
|
|
setToggleDeployProxy(value) |
|
|
|
|
setDeployState({ upgrade: false, deploy: value }) |
|
|
|
|
setDeployState({upgrade: false, deploy: value}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const handleToggleUpgradeImp = () => { |
|
|
|
@ -241,7 +307,7 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
if (value) { |
|
|
|
|
setToggleDeployProxy(false) |
|
|
|
|
} |
|
|
|
|
setDeployState({ deploy: false, upgrade: value }) |
|
|
|
|
setDeployState({deploy: false, upgrade: value}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const switchProxyAddress = (address: string) => { |
|
|
|
@ -262,50 +328,58 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
<div |
|
|
|
|
className={`udapp_contractProperty ${ |
|
|
|
|
(props.funcABI.inputs && props.funcABI.inputs.length > 0) || |
|
|
|
|
props.funcABI.type === "fallback" || |
|
|
|
|
props.funcABI.type === "receive" |
|
|
|
|
? "udapp_hasArgs" |
|
|
|
|
: "" |
|
|
|
|
props.funcABI.type === 'fallback' || |
|
|
|
|
props.funcABI.type === 'receive' |
|
|
|
|
? 'udapp_hasArgs' |
|
|
|
|
: '' |
|
|
|
|
}`}
|
|
|
|
|
> |
|
|
|
|
<div |
|
|
|
|
className="udapp_contractActionsContainerSingle pt-2" |
|
|
|
|
style={{ display: toggleContainer ? "none" : "flex" }} |
|
|
|
|
>
|
|
|
|
|
<div |
|
|
|
|
className='d-flex' |
|
|
|
|
onClick={handleActionClick} |
|
|
|
|
style={{display: toggleContainer ? 'none' : 'flex'}} |
|
|
|
|
> |
|
|
|
|
<CustomTooltip |
|
|
|
|
delay={0} |
|
|
|
|
placement={'right'} |
|
|
|
|
tooltipClasses="text-wrap" |
|
|
|
|
tooltipId="remixUdappInstanceButtonTooltip" |
|
|
|
|
tooltipText={ |
|
|
|
|
toggleUpgradeImp && !proxyAddress |
|
|
|
|
? 'Proxy address cannot be empty' |
|
|
|
|
: props.inputs !== '' && basicInput === '' |
|
|
|
|
? 'Input required' |
|
|
|
|
: buttonOptions.title |
|
|
|
|
} |
|
|
|
|
> |
|
|
|
|
<button |
|
|
|
|
className={`udapp_instanceButton text-nowrap overflow-hidden text-truncate ${props.widthClass} btn btn-sm ${buttonOptions.classList}`} |
|
|
|
|
data-id={buttonOptions.dataId} |
|
|
|
|
data-title={buttonOptions.title} |
|
|
|
|
disabled={(toggleUpgradeImp && !proxyAddress) || props.disabled || (props.inputs !=='' && basicInput === '')} |
|
|
|
|
> |
|
|
|
|
<CustomTooltip |
|
|
|
|
delay={0} |
|
|
|
|
placement={"right"} |
|
|
|
|
tooltipClasses="text-wrap" |
|
|
|
|
tooltipId="remixUdappInstanceButtonTooltip" |
|
|
|
|
tooltipText={toggleUpgradeImp && !proxyAddress ? 'Proxy address cannot be empty' : (props.inputs !=='' && basicInput === '') ? 'Input required' : buttonOptions.title} |
|
|
|
|
<div className="d-flex" onClick={handleActionClick}> |
|
|
|
|
<button |
|
|
|
|
className={`udapp_instanceButton text-nowrap overflow-hidden text-truncate ${props.widthClass} btn btn-sm ${buttonOptions.classList}`} |
|
|
|
|
data-id={buttonOptions.dataId} |
|
|
|
|
data-title={buttonOptions.title} |
|
|
|
|
disabled={ |
|
|
|
|
(toggleUpgradeImp && !proxyAddress) || |
|
|
|
|
props.disabled || |
|
|
|
|
(props.inputs !== '' && basicInput === '') |
|
|
|
|
} |
|
|
|
|
style={{pointerEvents: 'none'}} |
|
|
|
|
> |
|
|
|
|
<div>{title}</div> |
|
|
|
|
</CustomTooltip> |
|
|
|
|
</button> |
|
|
|
|
</div> |
|
|
|
|
{title} |
|
|
|
|
</button> |
|
|
|
|
</div> |
|
|
|
|
</CustomTooltip> |
|
|
|
|
<input |
|
|
|
|
className="form-control" |
|
|
|
|
data-id={ |
|
|
|
|
props.funcABI.type === "fallback" || |
|
|
|
|
props.funcABI.type === "receive" |
|
|
|
|
props.funcABI.type === 'fallback' || |
|
|
|
|
props.funcABI.type === 'receive' |
|
|
|
|
? `'(${props.funcABI.type}')` |
|
|
|
|
: "multiParamManagerBasicInputField" |
|
|
|
|
: 'multiParamManagerBasicInputField' |
|
|
|
|
} |
|
|
|
|
placeholder={props.inputs} |
|
|
|
|
onChange={handleBasicInput} |
|
|
|
|
data-title={ |
|
|
|
|
props.funcABI.type === "fallback" || |
|
|
|
|
props.funcABI.type === "receive" |
|
|
|
|
props.funcABI.type === 'fallback' || |
|
|
|
|
props.funcABI.type === 'receive' |
|
|
|
|
? `'(${props.funcABI.type}')` |
|
|
|
|
: props.inputs |
|
|
|
|
} |
|
|
|
@ -314,11 +388,11 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
height: '2rem', |
|
|
|
|
visibility: !( |
|
|
|
|
(props.funcABI.inputs && props.funcABI.inputs.length > 0) || |
|
|
|
|
props.funcABI.type === "fallback" || |
|
|
|
|
props.funcABI.type === "receive" |
|
|
|
|
props.funcABI.type === 'fallback' || |
|
|
|
|
props.funcABI.type === 'receive' |
|
|
|
|
) |
|
|
|
|
? "hidden" |
|
|
|
|
: "visible", |
|
|
|
|
? 'hidden' |
|
|
|
|
: 'visible' |
|
|
|
|
}} |
|
|
|
|
/> |
|
|
|
|
<i |
|
|
|
@ -328,14 +402,14 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
visibility: !( |
|
|
|
|
props.funcABI.inputs && props.funcABI.inputs.length > 0 |
|
|
|
|
) |
|
|
|
|
? "hidden" |
|
|
|
|
: "visible", |
|
|
|
|
? 'hidden' |
|
|
|
|
: 'visible' |
|
|
|
|
}} |
|
|
|
|
></i> |
|
|
|
|
</div> |
|
|
|
|
<div |
|
|
|
|
className="udapp_contractActionsContainerMulti" |
|
|
|
|
style={{ display: toggleContainer ? "flex" : "none" }} |
|
|
|
|
style={{display: toggleContainer ? 'flex' : 'none'}} |
|
|
|
|
> |
|
|
|
|
<div className="udapp_contractActionsContainerMultiInner text-dark"> |
|
|
|
|
<div onClick={switchMethodViewOff} className="udapp_multiHeader"> |
|
|
|
@ -357,7 +431,7 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
> |
|
|
|
|
<input |
|
|
|
|
ref={(el) => { |
|
|
|
|
multiFields.current[index] = el; |
|
|
|
|
multiFields.current[index] = el |
|
|
|
|
}} |
|
|
|
|
className="form-control" |
|
|
|
|
placeholder={inp.type} |
|
|
|
@ -366,14 +440,14 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
/> |
|
|
|
|
</CustomTooltip> |
|
|
|
|
</div> |
|
|
|
|
); |
|
|
|
|
) |
|
|
|
|
})} |
|
|
|
|
</div> |
|
|
|
|
<div className="d-flex udapp_group udapp_multiArg"> |
|
|
|
|
<CopyToClipboard |
|
|
|
|
tip={intl.formatMessage({ id: 'udapp.copyCalldata' })} |
|
|
|
|
tip={intl.formatMessage({id: 'udapp.copyCalldata'})} |
|
|
|
|
icon="fa-clipboard" |
|
|
|
|
direction={"bottom"} |
|
|
|
|
direction={'bottom'} |
|
|
|
|
getContent={getEncodedCall} |
|
|
|
|
> |
|
|
|
|
<button className="btn remixui_copyButton"> |
|
|
|
@ -386,9 +460,9 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
</button> |
|
|
|
|
</CopyToClipboard> |
|
|
|
|
<CopyToClipboard |
|
|
|
|
tip={intl.formatMessage({ id: 'udapp.copyParameters' })} |
|
|
|
|
tip={intl.formatMessage({id: 'udapp.copyParameters'})} |
|
|
|
|
icon="fa-clipboard" |
|
|
|
|
direction={"bottom"} |
|
|
|
|
direction={'bottom'} |
|
|
|
|
getContent={getEncodedParams} |
|
|
|
|
> |
|
|
|
|
<button className="btn remixui_copyButton"> |
|
|
|
@ -397,23 +471,25 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
className="m-0 remixui_copyIcon far fa-copy" |
|
|
|
|
aria-hidden="true" |
|
|
|
|
></i> |
|
|
|
|
<label htmlFor="copyParameters"><FormattedMessage id='udapp.parameters' /></label> |
|
|
|
|
<label htmlFor="copyParameters"> |
|
|
|
|
<FormattedMessage id="udapp.parameters" /> |
|
|
|
|
</label> |
|
|
|
|
</button> |
|
|
|
|
</CopyToClipboard> |
|
|
|
|
<CustomTooltip |
|
|
|
|
placement={"right"} |
|
|
|
|
placement={'right'} |
|
|
|
|
tooltipClasses="text-nowrap" |
|
|
|
|
tooltipId="remixUdappInstanceButtonTooltip" |
|
|
|
|
tooltipText={buttonOptions.title} |
|
|
|
|
> |
|
|
|
|
<div |
|
|
|
|
onClick={handleExpandMultiClick} |
|
|
|
|
> |
|
|
|
|
<div onClick={handleExpandMultiClick}> |
|
|
|
|
<button |
|
|
|
|
type="button" |
|
|
|
|
data-id={buttonOptions.dataId} |
|
|
|
|
className={`udapp_instanceButton btn ${buttonOptions.classList}`} |
|
|
|
|
disabled={props.disabled || (props.inputs !=='' && basicInput === '')} |
|
|
|
|
disabled={ |
|
|
|
|
props.disabled || (props.inputs !== '' && basicInput === '') |
|
|
|
|
} |
|
|
|
|
> |
|
|
|
|
{buttonOptions.content} |
|
|
|
|
</button> |
|
|
|
@ -439,14 +515,19 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
data-id="contractGUIDeployWithProxyLabel" |
|
|
|
|
className="m-0 form-check-label w-100 custom-control-label udapp_checkboxAlign" |
|
|
|
|
> |
|
|
|
|
<FormattedMessage id='udapp.deployWithProxy' /> |
|
|
|
|
<FormattedMessage id="udapp.deployWithProxy" /> |
|
|
|
|
</label> |
|
|
|
|
</div> |
|
|
|
|
<div> |
|
|
|
|
{props.initializerOptions && |
|
|
|
|
props.initializerOptions.initializeInputs ? ( |
|
|
|
|
<span onClick={handleToggleDeployProxy}> |
|
|
|
|
<i className={!toggleDeployProxy ? "fas fa-angle-right pt-2" : "fas fa-angle-down"} |
|
|
|
|
<i |
|
|
|
|
className={ |
|
|
|
|
!toggleDeployProxy |
|
|
|
|
? 'fas fa-angle-right pt-2' |
|
|
|
|
: 'fas fa-angle-down' |
|
|
|
|
} |
|
|
|
|
aria-hidden="true" |
|
|
|
|
></i> |
|
|
|
|
</span> |
|
|
|
@ -457,7 +538,7 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
props.initializerOptions.initializeInputs ? ( |
|
|
|
|
<div |
|
|
|
|
className={`pl-4 flex-column ${ |
|
|
|
|
toggleDeployProxy ? "d-flex" : "d-none" |
|
|
|
|
toggleDeployProxy ? 'd-flex' : 'd-none' |
|
|
|
|
}`}
|
|
|
|
|
> |
|
|
|
|
<div className={`flex-column 'd-flex'}`}> |
|
|
|
@ -468,19 +549,19 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
className="mt-2 text-left d-block" |
|
|
|
|
htmlFor={inp.name} |
|
|
|
|
> |
|
|
|
|
{" "} |
|
|
|
|
{inp.name}:{" "} |
|
|
|
|
{' '} |
|
|
|
|
{inp.name}:{' '} |
|
|
|
|
</label> |
|
|
|
|
<input |
|
|
|
|
ref={(el) => { |
|
|
|
|
initializeFields.current[index] = el; |
|
|
|
|
initializeFields.current[index] = el |
|
|
|
|
}} |
|
|
|
|
style={{ height: 32 }} |
|
|
|
|
style={{height: 32}} |
|
|
|
|
className="form-control udapp_input" |
|
|
|
|
placeholder={inp.type} |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
); |
|
|
|
|
) |
|
|
|
|
})} |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
@ -500,15 +581,15 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
data-id="contractGUIUpgradeImplementationLabel" |
|
|
|
|
className="m-0 form-check-label custom-control-label udapp_checkboxAlign" |
|
|
|
|
> |
|
|
|
|
<FormattedMessage id='udapp.upgradeWithProxy' /> |
|
|
|
|
<FormattedMessage id="udapp.upgradeWithProxy" /> |
|
|
|
|
</label> |
|
|
|
|
</div> |
|
|
|
|
<span onClick={handleToggleUpgradeImp}> |
|
|
|
|
<i |
|
|
|
|
className={ |
|
|
|
|
!toggleUpgradeImp |
|
|
|
|
? "fas fa-angle-right pt-2" |
|
|
|
|
: "fas fa-angle-down" |
|
|
|
|
? 'fas fa-angle-right pt-2' |
|
|
|
|
: 'fas fa-angle-down' |
|
|
|
|
} |
|
|
|
|
aria-hidden="true" |
|
|
|
|
></i> |
|
|
|
@ -516,50 +597,79 @@ export function ContractGUI (props: ContractGUIProps) { |
|
|
|
|
</div> |
|
|
|
|
<div |
|
|
|
|
className={`pl-4 flex-column ${ |
|
|
|
|
toggleUpgradeImp ? "d-flex" : "d-none" |
|
|
|
|
toggleUpgradeImp ? 'd-flex' : 'd-none' |
|
|
|
|
}`}
|
|
|
|
|
> |
|
|
|
|
<div data-id="proxy-dropdown-items"> |
|
|
|
|
<Dropdown onToggle={toggleDropdown} show={showDropdown}> |
|
|
|
|
<Dropdown.Toggle id="dropdown-custom-components" as={ProxyAddressToggle} address={proxyAddress} onChange={handleAddressChange} className="d-inline-block border border-dark bg-dark" /> |
|
|
|
|
|
|
|
|
|
{ props.proxy.deployments.length > 0 && |
|
|
|
|
<Dropdown.Menu as={ProxyDropdownMenu} className='w-100 custom-dropdown-items' style={{ overflow: 'hidden' }}> |
|
|
|
|
{ |
|
|
|
|
props.proxy.deployments.map((deployment, index) => ( |
|
|
|
|
<CustomTooltip |
|
|
|
|
placement={"right"} |
|
|
|
|
tooltipClasses="text-nowrap" |
|
|
|
|
tooltipId={`proxyAddressTooltip${index}`} |
|
|
|
|
tooltipText={'Deployed ' + shortenDate(deployment.date)} |
|
|
|
|
<Dropdown.Toggle |
|
|
|
|
id="dropdown-custom-components" |
|
|
|
|
as={ProxyAddressToggle} |
|
|
|
|
address={proxyAddress} |
|
|
|
|
onChange={handleAddressChange} |
|
|
|
|
className="d-inline-block border border-dark bg-dark" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
{props.proxy.deployments.length > 0 && ( |
|
|
|
|
<Dropdown.Menu |
|
|
|
|
as={ProxyDropdownMenu} |
|
|
|
|
className="w-100 custom-dropdown-items" |
|
|
|
|
style={{overflow: 'hidden'}} |
|
|
|
|
> |
|
|
|
|
{props.proxy.deployments.map((deployment, index) => ( |
|
|
|
|
<CustomTooltip |
|
|
|
|
placement={'right'} |
|
|
|
|
tooltipClasses="text-nowrap" |
|
|
|
|
tooltipId={`proxyAddressTooltip${index}`} |
|
|
|
|
tooltipText={'Deployed ' + shortenDate(deployment.date)} |
|
|
|
|
key={index} |
|
|
|
|
> |
|
|
|
|
<Dropdown.Item |
|
|
|
|
key={index} |
|
|
|
|
onClick={() => { |
|
|
|
|
switchProxyAddress(deployment.address) |
|
|
|
|
}} |
|
|
|
|
data-id={`proxyAddress${index}`} |
|
|
|
|
> |
|
|
|
|
<Dropdown.Item |
|
|
|
|
key={index} |
|
|
|
|
onClick={() => { switchProxyAddress(deployment.address) }} |
|
|
|
|
data-id={`proxyAddress${index}`} |
|
|
|
|
> |
|
|
|
|
<span> |
|
|
|
|
{ proxyAddress === deployment.address ? |
|
|
|
|
<span>✓ { deployment.contractName + ' ' + shortenProxyAddress(deployment.address) } </span> |
|
|
|
|
: <span className="pl-3">{ deployment.contractName + ' ' + shortenProxyAddress(deployment.address) }</span> } |
|
|
|
|
</span> |
|
|
|
|
</Dropdown.Item> |
|
|
|
|
</CustomTooltip> |
|
|
|
|
)) |
|
|
|
|
} |
|
|
|
|
<span> |
|
|
|
|
{proxyAddress === deployment.address ? ( |
|
|
|
|
<span> |
|
|
|
|
✓{' '} |
|
|
|
|
{deployment.contractName + |
|
|
|
|
' ' + |
|
|
|
|
shortenProxyAddress(deployment.address)}{' '} |
|
|
|
|
</span> |
|
|
|
|
) : ( |
|
|
|
|
<span className="pl-3"> |
|
|
|
|
{deployment.contractName + |
|
|
|
|
' ' + |
|
|
|
|
shortenProxyAddress(deployment.address)} |
|
|
|
|
</span> |
|
|
|
|
)} |
|
|
|
|
</span> |
|
|
|
|
</Dropdown.Item> |
|
|
|
|
</CustomTooltip> |
|
|
|
|
))} |
|
|
|
|
</Dropdown.Menu> |
|
|
|
|
} |
|
|
|
|
)} |
|
|
|
|
</Dropdown> |
|
|
|
|
</div> |
|
|
|
|
<div className='d-flex'> |
|
|
|
|
<div className="d-flex"> |
|
|
|
|
<div className="mb-2"> |
|
|
|
|
{ proxyAddressError && <span className='text-lowercase text-danger' data-id="errorMsgProxyAddress" style={{ fontSize: '.8em' }}>{ proxyAddressError }</span> } |
|
|
|
|
{proxyAddressError && ( |
|
|
|
|
<span |
|
|
|
|
className="text-lowercase text-danger" |
|
|
|
|
data-id="errorMsgProxyAddress" |
|
|
|
|
style={{fontSize: '.8em'}} |
|
|
|
|
> |
|
|
|
|
{proxyAddressError} |
|
|
|
|
</span> |
|
|
|
|
)} |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</>
|
|
|
|
|
</> |
|
|
|
|
) : null} |
|
|
|
|
</div> |
|
|
|
|
); |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|