diff --git a/apps/remix-ide-e2e/src/commands/addAtAddressInstance.ts b/apps/remix-ide-e2e/src/commands/addAtAddressInstance.ts index 86624a900d..48270c6b9b 100644 --- a/apps/remix-ide-e2e/src/commands/addAtAddressInstance.ts +++ b/apps/remix-ide-e2e/src/commands/addAtAddressInstance.ts @@ -21,15 +21,22 @@ function addInstance (browser: NightwatchBrowser, address: string, isValidFormat .setValue('.ataddressinput', address, function () { if (!isValidFormat || !isValidChecksum) browser.assert.elementPresent('button[id^="runAndDeployAtAdressButton"]:disabled') else if (isAbi) { - browser.click('button[id^="runAndDeployAtAdressButton"]') - .waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]') + browser + .click({ + selector: '//*[@id="runAndDeployAtAdressButtonContainer"]', + locateStrategy: 'xpath' + }) + .waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]', 5000) .execute(function () { const modal = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any modal.click() }) } else { - browser.click('button[id^="runAndDeployAtAdressButton"]') + browser.click({ + selector: '//*[@id="runAndDeployAtAdressButtonContainer"]', + locateStrategy: 'xpath' + }) } callback() }) diff --git a/apps/remix-ide-e2e/src/commands/clickFunction.ts b/apps/remix-ide-e2e/src/commands/clickFunction.ts index e84be6a0d0..9ae4b3c330 100644 --- a/apps/remix-ide-e2e/src/commands/clickFunction.ts +++ b/apps/remix-ide-e2e/src/commands/clickFunction.ts @@ -3,18 +3,18 @@ import EventEmitter from 'events' class ClickFunction extends EventEmitter { command (this: NightwatchBrowser, fnFullName: string, expectedInput?: NightwatchClickFunctionExpectedInput): NightwatchBrowser { - this.api.waitForElementPresent('.instance button[title="' + fnFullName + '"]') + this.api.waitForElementPresent('.instance button[data-title="' + fnFullName + '"]') .perform(function (client, done) { client.execute(function () { document.querySelector('#runTabView').scrollTop = document.querySelector('#runTabView').scrollHeight }, [], function () { if (expectedInput) { - client.setValue('#runTabView input[title="' + expectedInput.types + '"]', expectedInput.values, _ => _) + client.setValue('#runTabView input[data-title="' + expectedInput.types + '"]', expectedInput.values, _ => _) } done() }) }) - .scrollAndClick('.instance button[title="' + fnFullName + '"]') + .scrollAndClick('.instance button[data-title="' + fnFullName + '"]') .pause(2000) .perform(() => { this.emit('complete') diff --git a/apps/remix-ide-e2e/src/commands/testConstantFunction.ts b/apps/remix-ide-e2e/src/commands/testConstantFunction.ts index 00f9512814..3216bc39ed 100644 --- a/apps/remix-ide-e2e/src/commands/testConstantFunction.ts +++ b/apps/remix-ide-e2e/src/commands/testConstantFunction.ts @@ -15,18 +15,18 @@ class TestConstantFunction extends EventEmitter { } function testConstantFunction (browser: NightwatchBrowser, address: string, fnFullName: string, expectedInput: NightwatchTestConstantFunctionExpectedInput, expectedOutput: string, cb: VoidFunction) { - browser.waitForElementPresent('.instance button[title="' + fnFullName + '"]').perform(function (client, done) { + browser.waitForElementPresent('.instance button[data-title="' + fnFullName + '"]').perform(function (client, done) { client.execute(function () { document.querySelector('#runTabView').scrollTop = document.querySelector('#runTabView').scrollHeight }, [], function () { if (expectedInput) { - client.waitForElementPresent('#runTabView input[title="' + expectedInput.types + '"]') - .setValue('#runTabView input[title="' + expectedInput.types + '"]', expectedInput.values) + client.waitForElementPresent('#runTabView input[data-title="' + expectedInput.types + '"]') + .setValue('#runTabView input[data-title="' + expectedInput.types + '"]', expectedInput.values) } done() }) }) - .click(`#instance${address} button[title="${fnFullName}"]`) + .click(`#instance${address} button[data-title="${fnFullName}"]`) .pause(1000) .waitForElementPresent('#instance' + address + ' .udapp_contractActionsContainer .udapp_value') .scrollInto('#instance' + address + ' .udapp_contractActionsContainer .udapp_value') diff --git a/apps/remix-ide-e2e/src/tests/debugger.test.ts b/apps/remix-ide-e2e/src/tests/debugger.test.ts index b9602b4b57..56965e31a9 100644 --- a/apps/remix-ide-e2e/src/tests/debugger.test.ts +++ b/apps/remix-ide-e2e/src/tests/debugger.test.ts @@ -19,8 +19,8 @@ module.exports = { .clickLaunchIcon('solidity').click('*[data-id="compilerContainerCompileBtn"]') .pause(4000) .clickLaunchIcon('udapp') - .waitForElementPresent('*[title="Deploy - transact (not payable)"]', 60000) - .click('*[title="Deploy - transact (not payable)"]') + .waitForElementPresent('*[data-title="Deploy - transact (not payable)"]', 60000) + .click('*[data-title="Deploy - transact (not payable)"]') .debugTransaction(0) .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .clearConsole() @@ -30,8 +30,8 @@ module.exports = { browser.waitForElementVisible('*[data-id="verticalIconsKindudapp"]') .clickLaunchIcon('udapp') .clickInstance(0) - .scrollAndClick('*[title="string name, uint256 goal"]') - .setValue('*[title="string name, uint256 goal"]', '"toast", 999') + .scrollAndClick('*[data-title="string name, uint256 goal"]') + .setValue('*[data-title="string name, uint256 goal"]', '"toast", 999') .click('*[data-id="createProject - transact (not payable)"]') .debugTransaction(0) .pause(2000) @@ -88,7 +88,7 @@ module.exports = { .clickLaunchIcon('solidity') .testContracts('externalImport.sol', sources[1]['externalImport.sol'], ['ERC20']) .clickLaunchIcon('udapp') - .waitForElementPresent('*[title="Deploy - transact (not payable)"]', 35000) + .waitForElementPresent('*[data-title="Deploy - transact (not payable)"]', 35000) .selectContract('ERC20') .createContract('"tokenName", "symbol"') .debugTransaction(0) @@ -159,7 +159,7 @@ module.exports = { .clickLaunchIcon('solidity') .testContracts('locals.sol', sources[3]['locals.sol'], ['testLocals']) .clickLaunchIcon('udapp') - .waitForElementPresent('*[title="Deploy - transact (not payable)"]', 40000) + .waitForElementPresent('*[data-title="Deploy - transact (not payable)"]', 40000) .createContract('') .pause(2000) .clearConsole() @@ -266,7 +266,7 @@ const sources = [ 'blah.sol': { content: ` pragma solidity >=0.7.0 <0.9.0; - + contract Kickstarter { enum State { Started, Completed } @@ -276,9 +276,9 @@ const sources = [ string name; uint goal; State state; - } + } - Project[] public projects; + Project[] public projects; constructor() { @@ -291,7 +291,7 @@ const sources = [ project.state = State.Started; project.goal = goal; } - } + } ` } }, @@ -309,12 +309,12 @@ const sources = [ function test1 (bytes calldata userData) external returns (bytes memory, bytes32, bytes32, uint) { bytes32 idAsk = abi.decode(userData[:33], (bytes32)); bytes32 idOffer = abi.decode(userData[32:64], (bytes32)); - + bytes memory ro = abi.encodePacked(msg.sender, msg.sender, idAsk, idOffer); return (ro, idAsk, idOffer, userData.length); } - - + + function testgp (bytes calldata userData) external returns (bytes4) { return abi.decode(userData[:4], (bytes4)); } @@ -341,9 +341,9 @@ const sources = [ 'withGeneratedSources.sol': { content: ` // SPDX-License-Identifier: GPL-3.0 - pragma experimental ABIEncoderV2; - contract A { - function f(uint[] memory) public returns (uint256) { } + pragma experimental ABIEncoderV2; + contract A { + function f(uint[] memory) public returns (uint256) { } } ` } @@ -372,7 +372,7 @@ const sources = [ } /** - * @dev Return value + * @dev Return value * @return value of 'number' */ function retrieve() public view returns (uint256){ @@ -393,14 +393,14 @@ const sources = [ function callA() public { p = 123; try b.callB() { - + } catch (bytes memory reason) { - + } } } - + contract B { C c; uint p; @@ -413,7 +413,7 @@ const sources = [ c.callC(); } } - + contract C { uint p; function callC() public { @@ -498,7 +498,7 @@ const jsGetTrace = `(async () => { } })()` -const jsDebug = `(async () => { +const jsDebug = `(async () => { try { const result = await remix.call('debugger', 'debug', '0x65f0813753462414f9a91f0aabea946188327995f54b893b63a8d7ff186cfca3') console.log('result ', result) diff --git a/libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx b/libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx index f298eba01d..9418051754 100644 --- a/libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx @@ -2,15 +2,24 @@ import React from 'react' const CustomNavButtons = ({ next, previous, goToSlide, ...rest }) => { - const { carouselState: { currentSlide, totalItems } } = rest + const { carouselState: { currentSlide, totalItems, itemWidth, containerWidth } } = rest return (
- -
diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx index 8741d7779f..18798c3f4f 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx @@ -18,7 +18,7 @@ function HomeTabFeatured() {
- + } arrows={false} @@ -40,26 +40,31 @@ function HomeTabFeatured() { dotListClass="position-relative mt-2" >
- -
+ +
JUMP INTO WEB3
- The Remix Project is a rich toolset which can be used for the entire journey of contract development by users of any knowledge level, and as a learning lab for teaching and experimenting with Ethereum. +

The Remix Project is a rich toolset which can be used for the entire journey of contract development by users of any knowledge level, and as a learning lab for teaching and experimenting with Ethereum.

+ More
-
+
REMIX REWARDS
-

NFTs for our users!

- Remix Project rewards contributors, beta testers, and UX research participants with NFTs deployed on Optimism. Remix Reward holders are able to mint a second “Remixer” user NFT badge to give to any other user of their choice +

NFTs for our users!

+

+ Remix Project rewards contributors, beta testers, and UX research participants with NFTs deployed on Optimism. Remix Reward holders are able to mint a second “Remixer” user NFT badge to give to any other user of their choice. +

+ More
-
+
BETA TESTING
-

Our community supports us.

- You can join Beta Testing before each release of Remix IDE. Help us test now and get a handle on new features! +

Our community supports us.

+

You can join Beta Testing before each release of Remix IDE. Help us test now and get a handle on new features!

+ More
diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx index a0913e4469..1741d6bb32 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx @@ -1,18 +1,18 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import React, { useEffect, useState, useRef, useContext } from 'react' +import React, { useEffect, useRef, useContext } from 'react' import { FormattedMessage } from 'react-intl' import PluginButton from './pluginButton' -import { ThemeContext, themes } from '../themeContext' +import { ThemeContext } from '../themeContext' import Carousel from 'react-multi-carousel' import 'react-multi-carousel/lib/styles.css' import CustomNavButtons from './customNavButtons' +const itemsToShow = 5 declare global { interface Window { _paq: any } } const _paq = window._paq = window._paq || [] //eslint-disable-line - interface HomeTabFeaturedPluginsProps { plugin: any } @@ -21,16 +21,40 @@ function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) { const themeFilter = useContext(ThemeContext) const carouselRef = useRef(null) + const carouselRefDiv = useRef(null) - // Todo doesn't work useEffect(() => { - window.addEventListener("scroll", handleScroll) + document.addEventListener("wheel", handleScroll) return () => { - window.removeEventListener("scroll", handleScroll) + document.removeEventListener("wheel", handleScroll) } }, []) + function isDescendant(parent, child) { + let node = child.parentNode; + while (node != null) { + if (node === parent) { + return true; + } + node = node.parentNode; + } + return false; + } + const handleScroll = (e) => { + if (isDescendant(carouselRefDiv.current, e.target)) { + e.stopPropagation() + let nextSlide = 0 + if (e.wheelDelta < 0) { + nextSlide = carouselRef.current.state.currentSlide + 1; + if ((carouselRef.current.state.totalItems - carouselRef.current.state.currentSlide) * carouselRef.current.state.itemWidth + 5 < carouselRef.current.state.containerWidth) return // 5 is approx margins + carouselRef.current.goToSlide(nextSlide) + } else { + nextSlide = carouselRef.current.state.currentSlide - 1; + if (nextSlide < 0) nextSlide = 0 + carouselRef.current.goToSlide(nextSlide) + } + } } const startSolidity = async () => { @@ -62,17 +86,30 @@ function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) { return (
-
+
} + focusOnSelect={true} + customButtonGroup={ + + } arrows={false} swipeable={false} draggable={true} showDots={false} - responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 5} }} + responsive={ + { + superLargeDesktop: { + breakpoint: { max: 4000, min: 3000 }, + items: itemsToShow + }, + desktop: { + breakpoint: { max: 3000, min: 1024 }, + items: itemsToShow + } + } + } renderButtonGroupOutside={true} ssr={true} // means to render carousel on server-side. keyBoardControl={true} diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx index f27f489198..bea7384767 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import React, { useEffect, useState, useRef, useContext } from 'react' -import { ThemeContext, themes } from '../themeContext' +import React, { useEffect, useRef, useContext } from 'react' +import { ThemeContext} from '../themeContext' import Carousel from 'react-multi-carousel' import WorkspaceTemplate from './workspaceTemplate' import 'react-multi-carousel/lib/styles.css' @@ -11,13 +11,48 @@ declare global { } } const _paq = window._paq = window._paq || [] //eslint-disable-line - interface HomeTabGetStartedProps { plugin: any } function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) { const themeFilter = useContext(ThemeContext) + const carouselRef = useRef(null) + const carouselRefDiv = useRef(null) + + useEffect(() => { + document.addEventListener("wheel", handleScroll) + return () => { + document.removeEventListener("wheel", handleScroll) + } + }, []) + + function isDescendant(parent, child) { + let node = child.parentNode; + while (node != null) { + if (node === parent) { + return true; + } + node = node.parentNode; + } + return false; + } + + const handleScroll = (e) => { + if (isDescendant(carouselRefDiv.current, e.target)) { + e.stopPropagation() + let nextSlide = 0 + if (e.wheelDelta < 0) { + nextSlide = carouselRef.current.state.currentSlide + 1; + if ((carouselRef.current.state.totalItems - carouselRef.current.state.currentSlide) * carouselRef.current.state.itemWidth + 5 < carouselRef.current.state.containerWidth) return // 5 is approx margins + carouselRef.current.goToSlide(nextSlide) + } else { + nextSlide = carouselRef.current.state.currentSlide - 1; + if (nextSlide < 0) nextSlide = 0 + carouselRef.current.goToSlide(nextSlide) + } + } + } const createWorkspace = async (templateName) => { await plugin.appManager.activatePlugin('filePanel') @@ -36,16 +71,31 @@ function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) { - Project Templates -
+
- } + + } arrows={false} swipeable={false} draggable={true} showDots={false} - responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 5} }} + responsive={ + { + superLargeDesktop: { + breakpoint: { max: 4000, min: 3000 }, + items: 5 + }, + desktop: { + breakpoint: { max: 3000, min: 1024 }, + items: 5, + partialVisibilityGutter: 0 + } + } + } renderButtonGroupOutside={true} ssr={true} // means to render carousel on server-side. keyBoardControl={true} diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx index 0fdc6ab5ff..e9d1a345b3 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx @@ -50,20 +50,20 @@ function HomeTabLearn ({plugin}: HomeTabLearnProps) {
}
}
} diff --git a/libs/remix-ui/home-tab/src/lib/components/pluginButton.tsx b/libs/remix-ui/home-tab/src/lib/components/pluginButton.tsx index 803c9f7ec4..8a8470304d 100644 --- a/libs/remix-ui/home-tab/src/lib/components/pluginButton.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/pluginButton.tsx @@ -23,7 +23,7 @@ function PluginButton ({ imgPath, envID, envText, callback, l2, description, rem onClick={() => callback()} > -
+
{description}
diff --git a/libs/remix-ui/home-tab/src/lib/components/workspaceTemplate.tsx b/libs/remix-ui/home-tab/src/lib/components/workspaceTemplate.tsx index ad079053a8..4610236f79 100644 --- a/libs/remix-ui/home-tab/src/lib/components/workspaceTemplate.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/workspaceTemplate.tsx @@ -16,7 +16,7 @@ function WorkspaceTemplate ({ gsID, workspaceTitle, description, callback }: Wor data-id={'landingPageStart' + gsID} onClick={() => callback()} > -
+
{description}
diff --git a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.css b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.css index d6ced30e67..011a179161 100644 --- a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.css +++ b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.css @@ -1,11 +1,9 @@ .remixui_home_text { - cursor: pointer; font-size: 0.8rem; font-weight: normal; max-width: 300px; } .remixui_home_text:hover { - cursor: pointer; text-decoration: underline; } .remixui_home_homeContainer { diff --git a/libs/remix-ui/run-tab/src/lib/components/account.tsx b/libs/remix-ui/run-tab/src/lib/components/account.tsx index 0a36eef8b5..21d0d90a6f 100644 --- a/libs/remix-ui/run-tab/src/lib/components/account.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/account.tsx @@ -4,6 +4,7 @@ import { FormattedMessage, useIntl } from 'react-intl' import { CopyToClipboard } from '@remix-ui/clipboard' import { AccountProps } from '../types' import { PassphrasePrompt } from './passphrase' +import { OverlayTrigger, Tooltip } from 'react-bootstrap' export function AccountUI (props: AccountProps) { const { selectedAccount, loadedAccounts } = props.accounts @@ -153,9 +154,15 @@ export function AccountUI (props: AccountProps) {
- + + {"Sign a message using this account"} + + }> + +
) diff --git a/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx b/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx index 9862dad59c..c4e3801bd8 100644 --- a/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx @@ -3,10 +3,10 @@ import React, { useEffect, useRef, useState } from 'react' import { FormattedMessage, useIntl } from 'react-intl' import { ContractDropdownProps, DeployMode } from '../types' import { ContractData, FuncABI } from '@remix-project/core-plugin' +import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line import * as ethJSUtil from 'ethereumjs-util' import { ContractGUI } from './contractGUI' import { deployWithProxyMsg, upgradeWithProxyMsg } from '@remix-ui/helper' -import { OverlayTrigger, Tooltip } from 'react-bootstrap' const _paq = window._paq = window._paq || [] export function ContractDropdownUI (props: ContractDropdownProps) { @@ -279,13 +279,25 @@ export function ContractDropdownUI (props: ContractDropdownProps) { : null}
- {(contractList[currentFile] || []).map((contract, index) => { return })} + {abiLabel.content}
@@ -314,14 +326,19 @@ export function ContractDropdownUI (props: ContractDropdownProps) { onChange={handleCheckedIPFS} checked={props.ipfsCheckedState} /> - + + Publishing the source code and metadata to IPFS facilitates source code verification
using Sourcify and will greatly foster contract adoption (auditing, debugging, calling it, etc...)
+ + }> + +
: '' } @@ -329,17 +346,30 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
-
- - +
+ + {atAddressOptions.title} + + }> +
+ +
+
+ + {"address of contract"} + + }> + +
diff --git a/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx b/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx index ad5716f45c..cccbbbbb2e 100644 --- a/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx @@ -3,6 +3,7 @@ import React, { useEffect, useRef, useState } from 'react' import * as remixLib from '@remix-project/remix-lib' import { ContractGUIProps } from '../types' import { CopyToClipboard } from '@remix-ui/clipboard' +import { OverlayTrigger, Tooltip } from 'react-bootstrap' const txFormat = remixLib.execution.txFormat const txHelper = remixLib.execution.txHelper @@ -233,66 +234,187 @@ export function ContractGUI (props: ContractGUIProps) { } return ( -
0) || (props.funcABI.type === 'fallback') || (props.funcABI.type === 'receive') ? 'udapp_hasArgs' : ''}`}> -
- - 0) || (props.funcABI.type === 'fallback') || (props.funcABI.type === 'receive')) ? 'hidden' : 'visible' }} /> +
0) || + props.funcABI.type === "fallback" || + props.funcABI.type === "receive" + ? "udapp_hasArgs" + : "" + }`} + > +
+ + {buttonOptions.title} + + } + > + + + + + {props.funcABI.type === "fallback" || + props.funcABI.type === "receive" + ? `'(${props.funcABI.type}')` + : props.inputs} + + + } + > + 0) || + props.funcABI.type === "fallback" || + props.funcABI.type === "receive" + ) + ? "hidden" + : "visible", + }} + /> + 0) ? 'hidden' : 'visible' }}> + style={{ + visibility: !( + props.funcABI.inputs && props.funcABI.inputs.length > 0 + ) + ? "hidden" + : "visible", + }} + >
-
+
-
{title}
- +
+ {title} +
+
{props.funcABI.inputs.map((inp, index) => { return (
- { multiFields.current[index] = el }} className="form-control" placeholder={inp.type} title={inp.name} data-id={`multiParamManagerInput${inp.name}`} /> -
) + + {inp.name} + + } + > + { + multiFields.current[index] = el; + }} + className="form-control" + placeholder={inp.type} + data-id={`multiParamManagerInput${inp.name}`} + /> + +
+ ); })}
- + - + - + +
- { props.deployOption && (props.deployOption || []).length > 0 ? + {props.deployOption && (props.deployOption || []).length > 0 ? ( <> -
+
- { - props.initializerOptions && props.initializerOptions.initializeInputs ? + {props.initializerOptions && + props.initializerOptions.initializeInputs ? ( - - : null - } + + + ) : null}
- { - props.initializerOptions && props.initializerOptions.initializeInputs ? -
-
{ - props.initializerOptions.inputs.inputs.map((inp, index) => { - return ( -
- - { initializeFields.current[index] = el }} style={{ height: 32 }} className="form-control udapp_input" placeholder={inp.type} title={inp.name} /> -
- )}) - } -
-
: null - } -
+ {props.initializerOptions && + props.initializerOptions.initializeInputs ? ( +
+
+ {props.initializerOptions.inputs.inputs.map((inp, index) => { + return ( +
+ + { + initializeFields.current[index] = el; + }} + style={{ height: 32 }} + className="form-control udapp_input" + placeholder={inp.type} + title={inp.name} + /> +
+ ); + })} +
+
+ ) : null} +
- +
-
+
- { - !useLastProxy ? + {!useLastProxy ? (
- - -
: - { proxyAddress || 'No proxy address available' } - } + + +
+ ) : ( + + {proxyAddress || "No proxy address available"} + + )}
- : null - } + + ) : null}
- ) + ); } diff --git a/libs/remix-ui/run-tab/src/lib/components/deployButton.tsx b/libs/remix-ui/run-tab/src/lib/components/deployButton.tsx index 5cc3f69b97..98cdb72262 100644 --- a/libs/remix-ui/run-tab/src/lib/components/deployButton.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/deployButton.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react' import { FormattedMessage } from 'react-intl' import { DeployButtonProps } from '../types' -import { ButtonGroup, Dropdown } from 'react-bootstrap' +import { ButtonGroup, Dropdown, OverlayTrigger, Tooltip } from 'react-bootstrap' export function DeployButton (props: DeployButtonProps) { const [showOptions, setShowOptions] = useState(false) @@ -25,9 +25,18 @@ export function DeployButton (props: DeployButtonProps) { } : - + + {props.buttonOptions.title} + + } + > + + } ) diff --git a/libs/remix-ui/run-tab/src/lib/components/deployInput.tsx b/libs/remix-ui/run-tab/src/lib/components/deployInput.tsx index 26fcf2a164..c5dc153e42 100644 --- a/libs/remix-ui/run-tab/src/lib/components/deployInput.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/deployInput.tsx @@ -1,4 +1,5 @@ import React from 'react' +import { OverlayTrigger, Tooltip } from 'react-bootstrap' import { DeployInputProps } from '../types' import { DeployButton } from './deployButton' @@ -6,15 +7,24 @@ export function DeployInput (props: DeployInputProps) { return (
- + + {props.funcABI.type === 'fallback' || props.funcABI.type === 'receive' ? `'(${props.funcABI.type}')` : props.inputs} + + } + > + +
) } diff --git a/libs/remix-ui/run-tab/src/lib/components/environment.tsx b/libs/remix-ui/run-tab/src/lib/components/environment.tsx index 04315d6d8b..2d99734d96 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -1,12 +1,13 @@ // eslint-disable-next-line no-use-before-define import React from 'react' -import { FormattedMessage, useIntl } from 'react-intl' +import { FormattedMessage } from 'react-intl' import { EnvironmentProps } from '../types' import { Dropdown } from 'react-bootstrap' import { CustomMenu, CustomToggle } from '@remix-ui/helper' import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line export function EnvironmentUI (props: EnvironmentProps) { + const handleChangeExEnv = (env: string) => { const provider = props.providers.providerList.find(exEnv => exEnv.value === env) const fork = provider.fork // can be undefined if connected to an external source (External Http Provider / injected) @@ -17,8 +18,6 @@ export function EnvironmentUI (props: EnvironmentProps) { props.setExecutionContext({ context, fork }) } - const intl = useIntl() - const currentProvider = props.providers.providerList.find(exEnv => exEnv.value === props.selectedEnv) const bridges = { 'Optimism Provider': 'https://www.optimism.io/apps/bridges', @@ -68,12 +67,13 @@ export function EnvironmentUI (props: EnvironmentProps) { } - - - + + + + }> + +
) diff --git a/libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx b/libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx index 3b46a72627..77350e9099 100644 --- a/libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx @@ -1,6 +1,7 @@ // eslint-disable-next-line no-use-before-define import React from 'react' import { FormattedMessage } from 'react-intl' +import { OverlayTrigger, Tooltip } from 'react-bootstrap' import { GasPriceProps } from '../types' export function GasPriceUI (props: GasPriceProps) { @@ -11,7 +12,13 @@ export function GasPriceUI (props: GasPriceProps) { return (
- + + {"The default gas limit is 3M. Adjust as needed."} + + }> + +
) } diff --git a/libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx b/libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx index e96bc6f07f..d5123be03f 100644 --- a/libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx @@ -1,6 +1,7 @@ // eslint-disable-next-line no-use-before-define import React from 'react' import { FormattedMessage, useIntl } from 'react-intl' +import { OverlayTrigger, Tooltip } from 'react-bootstrap' import { InstanceContainerProps } from '../types' import { UniversalDappUI } from './universalDappUI' @@ -15,15 +16,35 @@ export function InstanceContainerUI (props: InstanceContainerProps) { return (
-
diff --git a/libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx b/libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx index 9b3a99ae6f..554c75d29f 100644 --- a/libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx @@ -34,7 +34,13 @@ export function RecorderUI (props: RecorderProps) { -
{props.count}
+ + {'The number of recorded transactions'} + + }> +
{props.count}
+
Save transactions (deployed contracts and function executions) and replay them in another environment.
e.g Transactions created in Remix VM can be replayed in the Injected Provider. @@ -62,19 +68,33 @@ export function RecorderUI (props: RecorderProps) {
- - Save {props.count} transaction{props.count === 1 ? '' : 's'} as scenario file + + + { + props.count === 0 ? 'No transactions to save' + : props.count === 1 ? `Save ${props.count} transaction as scenario file` + : `Save ${props.count} transactions as scenario file` + } + }> - + + + Run transaction(s) from the current scenario file }> - + + +
diff --git a/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx b/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx index 4c2deaebcb..b9bdfa82ed 100644 --- a/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx @@ -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,104 +211,190 @@ export function UniversalDappUI (props: UdappProps) { } return ( -
+
- - + +
- {props.instance.name} at {shortenAddress(address)} ({props.context}) + {props.instance.name} at {shortenAddress(address)} ( + {props.context})
- +
- + +
-
+
-
- -
- { - 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) +
+ +
+ {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
- { - runTransaction(lookupOnly, funcABI, valArray, inputsValues, index) - }} - inputs={inputs} - evmBC={evmBC} - lookupOnly={lookupOnly} - key={index} - /> -
- - { - Object.keys(props.instance.decodedResponse || {}).map((key) => { - const funcIndex = index.toString() - const response = props.instance.decodedResponse[key] + return ( +
+ { + runTransaction( + lookupOnly, + funcABI, + valArray, + inputsValues, + index + ); + }} + inputs={inputs} + evmBC={evmBC} + lookupOnly={lookupOnly} + key={index} + /> +
+ + {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 - }) - } - + return key === funcIndex + ? Object.keys(response || {}).map( + (innerkey, index) => { + return renderData( + props.instance.decodedResponse[key][ + innerkey + ], + response, + innerkey, + innerkey + ); + } + ) + : null; + } + )} + +
-
- }) - } + ); + })}
- - + +
- +
- ) + ); } diff --git a/libs/remix-ui/run-tab/src/lib/components/value.tsx b/libs/remix-ui/run-tab/src/lib/components/value.tsx index 81935ae8d2..2090f59ab3 100644 --- a/libs/remix-ui/run-tab/src/lib/components/value.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/value.tsx @@ -4,6 +4,7 @@ import { FormattedMessage } from 'react-intl' import { BN } from 'ethereumjs-util' import { isNumeric } from '@remix-ui/helper' import { ValueProps } from '../types' +import { OverlayTrigger, Tooltip } from 'react-bootstrap' export function ValueUI (props: ValueProps) { const [sendValue, setSendValue] = useState(props.sendValue) @@ -50,6 +51,11 @@ export function ValueUI (props: ValueProps) {
+ + {"Enter an amount and choose its unit"} + + }> +