more tooltips

pull/2904/head
Joseph Izang 2 years ago
parent 33a84c27fe
commit 820b3ab304
  1. 2
      apps/remix-ide-e2e/src/commands/addAtAddressInstance.ts
  2. 300
      libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx
  3. 163
      libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx

@ -23,7 +23,7 @@ function addInstance (browser: NightwatchBrowser, address: string, isValidFormat
else if (isAbi) {
browser.useXpath()
.click('//button[@id="runAndDeployAtAdressButton"]')
.waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]')
.waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]', 5000)
.execute(function () {
const modal = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any

@ -234,78 +234,179 @@ export function ContractGUI (props: ContractGUIProps) {
}
return (
<div className={`udapp_contractProperty ${(props.funcABI.inputs && props.funcABI.inputs.length > 0) || (props.funcABI.type === 'fallback') || (props.funcABI.type === 'receive') ? 'udapp_hasArgs' : ''}`}>
<div className="udapp_contractActionsContainerSingle pt-2" style={{ display: toggleContainer ? 'none' : 'flex' }}>
<OverlayTrigger placement={'right'} overlay={
<Tooltip className="text-nowrap" id="remixUdappInstanceButtonTooltip">
<span>{buttonOptions.title}</span>
</Tooltip>
}>
<button onClick={handleActionClick} className={`udapp_instanceButton ${props.widthClass} btn btn-sm ${buttonOptions.classList}`} data-id={buttonOptions.dataId} data-title={buttonOptions.title}>{title}</button>
<div
className={`udapp_contractProperty ${
(props.funcABI.inputs && props.funcABI.inputs.length > 0) ||
props.funcABI.type === "fallback" ||
props.funcABI.type === "receive"
? "udapp_hasArgs"
: ""
}`}
>
<div
className="udapp_contractActionsContainerSingle pt-2"
style={{ display: toggleContainer ? "none" : "flex" }}
>
<OverlayTrigger
placement={"right"}
overlay={
<Tooltip
className="text-nowrap"
id="remixUdappInstanceButtonTooltip"
>
<span>{buttonOptions.title}</span>
</Tooltip>
}
>
<button
onClick={handleActionClick}
className={`udapp_instanceButton ${props.widthClass} btn btn-sm ${buttonOptions.classList}`}
data-id={buttonOptions.dataId}
data-title={buttonOptions.title}
>
{title}
</button>
</OverlayTrigger>
<OverlayTrigger placement={'right'} overlay={
<Tooltip className="text-nowrap" id="remixContractGuiTooltip">
<span>{props.funcABI.type === 'fallback' || props.funcABI.type === 'receive' ? `'(${props.funcABI.type}')` : props.inputs}</span>
</Tooltip>
}>
<input
className="form-control"
data-id={props.funcABI.type === 'fallback' || props.funcABI.type === 'receive' ? `'(${props.funcABI.type}')` : 'multiParamManagerBasicInputField'}
placeholder={props.inputs}
onChange={handleBasicInput}
data-title={props.funcABI.type === 'fallback' || props.funcABI.type === 'receive' ? `'(${props.funcABI.type}')` : props.inputs}
ref={basicInputRef}
style={{ visibility: !((props.funcABI.inputs && props.funcABI.inputs.length > 0) || (props.funcABI.type === 'fallback') || (props.funcABI.type === 'receive')) ? 'hidden' : 'visible' }} />
<OverlayTrigger
placement={"right"}
overlay={
<Tooltip className="text-nowrap" id="remixContractGuiTooltip">
<span>
{props.funcABI.type === "fallback" ||
props.funcABI.type === "receive"
? `'(${props.funcABI.type}')`
: props.inputs}
</span>
</Tooltip>
}
>
<input
className="form-control"
data-id={
props.funcABI.type === "fallback" ||
props.funcABI.type === "receive"
? `'(${props.funcABI.type}')`
: "multiParamManagerBasicInputField"
}
placeholder={props.inputs}
onChange={handleBasicInput}
data-title={
props.funcABI.type === "fallback" ||
props.funcABI.type === "receive"
? `'(${props.funcABI.type}')`
: props.inputs
}
ref={basicInputRef}
style={{
visibility: !(
(props.funcABI.inputs && props.funcABI.inputs.length > 0) ||
props.funcABI.type === "fallback" ||
props.funcABI.type === "receive"
)
? "hidden"
: "visible",
}}
/>
</OverlayTrigger>
<i
className="fas fa-angle-down udapp_methCaret"
onClick={switchMethodViewOn}
title={title}
style={{ visibility: !(props.funcABI.inputs && props.funcABI.inputs.length > 0) ? 'hidden' : 'visible' }}></i>
style={{
visibility: !(
props.funcABI.inputs && props.funcABI.inputs.length > 0
)
? "hidden"
: "visible",
}}
></i>
</div>
<div className="udapp_contractActionsContainerMulti" style={{ display: toggleContainer ? 'flex' : 'none' }}>
<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 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>)
<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="d-flex udapp_group udapp_multiArg">
<CopyToClipboard tip='Copy calldata to clipboard' icon='fa-clipboard' direction={'bottom'} getContent={getEncodedCall} >
<CopyToClipboard
tip="Copy calldata to clipboard"
icon="fa-clipboard"
direction={"bottom"}
getContent={getEncodedCall}
>
<button className="btn remixui_copyButton">
<i id="copyCalldata" className="m-0 remixui_copyIcon far fa-copy" aria-hidden="true"></i>
<i
id="copyCalldata"
className="m-0 remixui_copyIcon far fa-copy"
aria-hidden="true"
></i>
<label htmlFor="copyCalldata">Calldata</label>
</button>
</CopyToClipboard>
<CopyToClipboard tip='Copy encoded input parameters to clipboard' icon='fa-clipboard' direction={'bottom'} getContent={getEncodedParams} >
<CopyToClipboard
tip="Copy encoded input parameters to clipboard"
icon="fa-clipboard"
direction={"bottom"}
getContent={getEncodedParams}
>
<button className="btn remixui_copyButton">
<i id="copyParameters" className="m-0 remixui_copyIcon far fa-copy" aria-hidden="true"></i>
<i
id="copyParameters"
className="m-0 remixui_copyIcon far fa-copy"
aria-hidden="true"
></i>
<label htmlFor="copyParameters">Parameters</label>
</button>
</CopyToClipboard>
<button
type="button"
onClick={handleExpandMultiClick}
title={buttonOptions.title}
data-id={buttonOptions.dataId}
className={`udapp_instanceButton ${buttonOptions.classList}`}
<OverlayTrigger
placement={"right"}
overlay={
<Tooltip
className="text-nowrap"
id="remixUdappInstanceButtonTooltip"
>
<span>{buttonOptions.title}</span>
</Tooltip>
}
>
{ buttonOptions.content }
</button>
<button
type="button"
onClick={handleExpandMultiClick}
data-id={buttonOptions.dataId}
className={`udapp_instanceButton ${buttonOptions.classList}`}
>
{buttonOptions.content}
</button>
</OverlayTrigger>
</div>
</div>
</div>
{ props.deployOption && (props.deployOption || []).length > 0 ?
{props.deployOption && (props.deployOption || []).length > 0 ? (
<>
<div className='d-flex justify-content-between'>
<div className="d-flex justify-content-between">
<div className="d-flex py-1 align-items-center custom-control custom-checkbox">
<input
id="deployWithProxy"
@ -325,30 +426,55 @@ export function ContractGUI (props: ContractGUIProps) {
</label>
</div>
<div>
{
props.initializerOptions && props.initializerOptions.initializeInputs ?
{props.initializerOptions &&
props.initializerOptions.initializeInputs ? (
<span onClick={handleToggleDeployProxy}>
<i className={!toggleDeployProxy ? 'fas fa-angle-right pt-2' : 'fas fa-angle-down'} aria-hidden="true"></i>
</span> : null
}
<i
className={
!toggleDeployProxy
? "fas fa-angle-right pt-2"
: "fas fa-angle-down"
}
aria-hidden="true"
></i>
</span>
) : null}
</div>
</div>
{
props.initializerOptions && props.initializerOptions.initializeInputs ?
<div className={`pl-4 flex-column ${toggleDeployProxy ? "d-flex" : "d-none"}`}>
<div className={`flex-column 'd-flex'}`}>{
props.initializerOptions.inputs.inputs.map((inp, index) => {
return (
<div className="mb-2" key={index}>
<label className='mt-2 text-left d-block' htmlFor={inp.name}> {inp.name}: </label>
<input ref={el => { initializeFields.current[index] = el }} style={{ height: 32 }} className="form-control udapp_input" placeholder={inp.type} title={inp.name} />
</div>
)})
}
</div>
</div> : null
}
<div className='d-flex justify-content-between'>
{props.initializerOptions &&
props.initializerOptions.initializeInputs ? (
<div
className={`pl-4 flex-column ${
toggleDeployProxy ? "d-flex" : "d-none"
}`}
>
<div className={`flex-column 'd-flex'}`}>
{props.initializerOptions.inputs.inputs.map((inp, index) => {
return (
<div className="mb-2" key={index}>
<label
className="mt-2 text-left d-block"
htmlFor={inp.name}
>
{" "}
{inp.name}:{" "}
</label>
<input
ref={(el) => {
initializeFields.current[index] = el;
}}
style={{ height: 32 }}
className="form-control udapp_input"
placeholder={inp.type}
title={inp.name}
/>
</div>
);
})}
</div>
</div>
) : null}
<div className="d-flex justify-content-between">
<div className="d-flex py-1 align-items-center custom-control custom-checkbox">
<input
id="upgradeImplementation"
@ -368,10 +494,21 @@ export function ContractGUI (props: ContractGUIProps) {
</label>
</div>
<span onClick={handleToggleUpgradeImp}>
<i className={!toggleUpgradeImp ? 'fas fa-angle-right pt-2' : 'fas fa-angle-down'} aria-hidden="true"></i>
<i
className={
!toggleUpgradeImp
? "fas fa-angle-right pt-2"
: "fas fa-angle-down"
}
aria-hidden="true"
></i>
</span>
</div>
<div className={`pl-4 flex-column ${toggleUpgradeImp ? "d-flex" : "d-none"}`}>
<div
className={`pl-4 flex-column ${
toggleUpgradeImp ? "d-flex" : "d-none"
}`}
>
<div className={`flex-column 'd-flex'}`}>
<div className="d-flex py-1 align-items-center custom-control custom-checkbox">
<input
@ -392,18 +529,33 @@ export function ContractGUI (props: ContractGUIProps) {
Use last deployed ERC1967 contract
</label>
</div>
{
!useLastProxy ?
{!useLastProxy ? (
<div className="mb-2">
<label className='mt-2 text-left d-block'>Proxy Address: </label>
<input style={{ height: 32 }} className="form-control udapp_input" data-id="ERC1967AddressInput" placeholder='proxy address' title='Enter previously deployed proxy address on the selected network' onChange={handleSetProxyAddress} />
</div> :
<span className='text-capitalize' data-id="lastDeployedERC1967Address" style={{ fontSize: '.8em' }}>{ proxyAddress || 'No proxy address available' }</span>
}
<label className="mt-2 text-left d-block">
Proxy Address:{" "}
</label>
<input
style={{ height: 32 }}
className="form-control udapp_input"
data-id="ERC1967AddressInput"
placeholder="proxy address"
title="Enter previously deployed proxy address on the selected network"
onChange={handleSetProxyAddress}
/>
</div>
) : (
<span
className="text-capitalize"
data-id="lastDeployedERC1967Address"
style={{ fontSize: ".8em" }}
>
{proxyAddress || "No proxy address available"}
</span>
)}
</div>
</div>
</> : null
}
</>
) : null}
</div>
)
);
}

@ -7,6 +7,7 @@ import * as remixLib from '@remix-project/remix-lib'
import * as ethJSUtil from 'ethereumjs-util'
import { ContractGUI } from './contractGUI'
import { TreeView, TreeViewItem } from '@remix-ui/tree-view'
import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line
import { BN } from 'ethereumjs-util'
import { is0XPrefixed, isHexadecimal, isNumeric, shortenAddress } from '@remix-ui/helper'
@ -210,19 +211,37 @@ export function UniversalDappUI (props: UdappProps) {
}
return (
<div className={`instance udapp_instance udapp_run-instance border-dark ${toggleExpander ? 'udapp_hidesub' : 'bg-light'}`} id={`instance${address}`} data-shared="universalDappUiInstance">
<div
className={`instance udapp_instance udapp_run-instance border-dark ${
toggleExpander ? "udapp_hidesub" : "bg-light"
}`}
id={`instance${address}`}
data-shared="universalDappUiInstance"
>
<div className="udapp_title pb-0 alert alert-secondary">
<span data-id={`universalDappUiTitleExpander${props.index}`} className="btn udapp_titleExpander" onClick={toggleClass}>
<i className={`fas ${toggleExpander ? 'fa-angle-right' : 'fa-angle-down'}`} aria-hidden="true"></i>
<span
data-id={`universalDappUiTitleExpander${props.index}`}
className="btn udapp_titleExpander"
onClick={toggleClass}
>
<i
className={`fas ${
toggleExpander ? "fa-angle-right" : "fa-angle-down"
}`}
aria-hidden="true"
></i>
</span>
<div className="input-group udapp_nameNbuts">
<div className="udapp_titleText input-group-prepend">
<span className="input-group-text udapp_spanTitleText">
{props.instance.name} at {shortenAddress(address)} ({props.context})
{props.instance.name} at {shortenAddress(address)} (
{props.context})
</span>
</div>
<div className="btn-group">
<button className="btn p-1 btn-secondary"><CopyToClipboard content={address} direction={'top'} /></button>
<button className="btn p-1 btn-secondary">
<CopyToClipboard content={address} direction={"top"} />
</button>
</div>
</div>
<button
@ -234,64 +253,106 @@ export function UniversalDappUI (props: UdappProps) {
<i className="udapp_closeIcon fas fa-times" aria-hidden="true"></i>
</button>
</div>
<div className="udapp_cActionsWrapper" data-id="universalDappUiContractActionWrapper">
<div
className="udapp_cActionsWrapper"
data-id="universalDappUiContractActionWrapper"
>
<div className="udapp_contractActionsContainer">
<div className="d-flex" data-id="instanceContractBal">
<label>Balance: {instanceBalance} ETH</label>
</div>
{
contractABI && contractABI.map((funcABI, index) => {
if (funcABI.type !== 'function') return null
const isConstant = funcABI.constant !== undefined ? funcABI.constant : false
const lookupOnly = funcABI.stateMutability === 'view' || funcABI.stateMutability === 'pure' || isConstant
const inputs = props.getFuncABIInputs(funcABI)
<div className="d-flex" data-id="instanceContractBal">
<label>Balance: {instanceBalance} ETH</label>
</div>
{contractABI &&
contractABI.map((funcABI, index) => {
if (funcABI.type !== "function") return null;
const isConstant =
funcABI.constant !== undefined ? funcABI.constant : false;
const lookupOnly =
funcABI.stateMutability === "view" ||
funcABI.stateMutability === "pure" ||
isConstant;
const inputs = props.getFuncABIInputs(funcABI);
return <div key={index}>
<ContractGUI
funcABI={funcABI}
clickCallBack={(valArray: { name: string, type: string }[], inputsValues: string) => {
runTransaction(lookupOnly, funcABI, valArray, inputsValues, index)
}}
inputs={inputs}
evmBC={evmBC}
lookupOnly={lookupOnly}
key={index}
/>
<div className="udapp_value" data-id="udapp_value">
<TreeView id="treeView">
{
Object.keys(props.instance.decodedResponse || {}).map((key) => {
const funcIndex = index.toString()
const response = props.instance.decodedResponse[key]
return (
<div key={index}>
<ContractGUI
funcABI={funcABI}
clickCallBack={(
valArray: { name: string; type: string }[],
inputsValues: string
) => {
runTransaction(
lookupOnly,
funcABI,
valArray,
inputsValues,
index
);
}}
inputs={inputs}
evmBC={evmBC}
lookupOnly={lookupOnly}
key={index}
/>
<div className="udapp_value" data-id="udapp_value">
<TreeView id="treeView">
{Object.keys(props.instance.decodedResponse || {}).map(
(key) => {
const funcIndex = index.toString();
const response = props.instance.decodedResponse[key];
return key === funcIndex ? Object.keys(response || {}).map((innerkey, index) => {
return renderData(props.instance.decodedResponse[key][innerkey], response, innerkey, innerkey)
}) : null
})
}
</TreeView>
return key === funcIndex
? Object.keys(response || {}).map(
(innerkey, index) => {
return renderData(
props.instance.decodedResponse[key][
innerkey
],
response,
innerkey,
innerkey
);
}
)
: null;
}
)}
</TreeView>
</div>
</div>
</div>
})
}
);
})}
</div>
<div className="d-flex flex-column">
<div className="d-flex flex-row justify-content-between mt-2">
<div className="py-2 border-top d-flex justify-content-start flex-grow-1">
Low level interactions
</div>
<a
href="https://solidity.readthedocs.io/en/v0.6.2/contracts.html#receive-ether-function"
title="check out docs for using 'receive'/'fallback'"
target="_blank" rel="noreferrer"
<OverlayTrigger
placement={"bottom-end"}
overlay={
<Tooltip className="text-wrap" id="receiveEthDocstoolTip">
<span>{"check out docs for using 'receive'/'fallback'"}</span>
</Tooltip>
}
>
<i aria-hidden="true" className="fas fa-info my-2 mr-1"></i>
</a>
<a
href="https://solidity.readthedocs.io/en/v0.6.2/contracts.html#receive-ether-function"
target="_blank"
rel="noreferrer"
>
<i aria-hidden="true" className="fas fa-info my-2 mr-1"></i>
</a>
</OverlayTrigger>
</div>
<div className="d-flex flex-column align-items-start">
<label className="">CALLDATA</label>
<div className="d-flex justify-content-end w-100 align-items-center">
<input id="deployAndRunLLTxCalldata" onChange={handleCalldataChange} className="udapp_calldataInput form-control" title="The Calldata to send to fallback function of the contract." />
<input
id="deployAndRunLLTxCalldata"
onChange={handleCalldataChange}
className="udapp_calldataInput form-control"
title="The Calldata to send to fallback function of the contract."
/>
<button
id="deployAndRunLLTxSendTransaction"
data-id="pluginManagerSettingsDeployAndRunLLTxSendTransaction"
@ -304,10 +365,12 @@ export function UniversalDappUI (props: UdappProps) {
</div>
</div>
<div>
<label id="deployAndRunLLTxError" className="text-danger my-2">{ llIError }</label>
<label id="deployAndRunLLTxError" className="text-danger my-2">
{llIError}
</label>
</div>
</div>
</div>
</div>
)
);
}

Loading…
Cancel
Save