diff --git a/apps/etherscan/src/app/views/VerifyView.tsx b/apps/etherscan/src/app/views/VerifyView.tsx index ca70dba74cd..f41e9203afd 100644 --- a/apps/etherscan/src/app/views/VerifyView.tsx +++ b/apps/etherscan/src/app/views/VerifyView.tsx @@ -211,7 +211,7 @@ export const VerifyView = ({apiKey, client, contracts, onVerifiedContract, netwo type="button" className="mr-2 mb-2 py-1 px-2 btn btn-secondary btn-block" onClick={async () => { - etherscanScripts(client) + etherscanScripts({}, client) }} > Generate Verification Scripts diff --git a/apps/remix-ide-e2e/src/tests/ballot.test.ts b/apps/remix-ide-e2e/src/tests/ballot.test.ts index dbdef20903e..c9fb7c27bcf 100644 --- a/apps/remix-ide-e2e/src/tests/ballot.test.ts +++ b/apps/remix-ide-e2e/src/tests/ballot.test.ts @@ -97,12 +97,12 @@ module.exports = { .clickLaunchIcon('filePanel') .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-remixDefault"]') + .scrollAndClick('*[data-id="create-remixDefault"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - // eslint-disable-next-line dot-notation - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_remix_default' }) - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_remix_default') + .modalFooterOKClick('TemplatesSelection') .pause(1000) .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .addFile('contracts/lib/storage/src/Storage.sol', { content: storageContract}) diff --git a/apps/remix-ide-e2e/src/tests/circom.test.ts b/apps/remix-ide-e2e/src/tests/circom.test.ts index a5f6e2a1efb..ac14415ea97 100644 --- a/apps/remix-ide-e2e/src/tests/circom.test.ts +++ b/apps/remix-ide-e2e/src/tests/circom.test.ts @@ -13,13 +13,9 @@ module.exports = { .clickLaunchIcon('filePanel') .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') - .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=semaphore]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .pause(100) + .waitForElementPresent('*[data-id="create-semaphore"]') + .scrollAndClick('*[data-id="create-semaphore"]') + .modalFooterOKClick('TemplatesSelection') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits/semaphore.circom"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemscripts"]') @@ -155,12 +151,9 @@ module.exports = { .clickLaunchIcon('filePanel') .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') - .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=hashchecker]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .waitForElementPresent('*[data-id="create-hashchecker"]') + .scrollAndClick('*[data-id="create-hashchecker"]') + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits/calculate_hash.circom"]') diff --git a/apps/remix-ide-e2e/src/tests/erc721.test.ts b/apps/remix-ide-e2e/src/tests/erc721.test.ts index 373477f064a..890a5e7fc3b 100644 --- a/apps/remix-ide-e2e/src/tests/erc721.test.ts +++ b/apps/remix-ide-e2e/src/tests/erc721.test.ts @@ -17,14 +17,12 @@ module.exports = { .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') // create contract + .waitForElementPresent('*[data-id="create-hashchecker"]') + .scrollAndClick('*[data-id="create-ozerc721"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - // eslint-disable-next-line dot-notation - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc721' }) - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=ozerc721]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_erc721') + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]') diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts index c96f7023398..91ef7d6a4f1 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts @@ -180,16 +180,17 @@ module.exports = { // creating a new workspace .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-remixDefault"]') + .scrollAndClick('*[data-id="create-remixDefault"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .click('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]') - .setValue('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_new') + .click('input[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_new') .pause(2000) - .getValue('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]', (result) => { + .getValue('input[data-id="modalDialogCustomPromptTextCreate"]', (result) => { console.log(result) browser.assert.equal(result.value, 'workspace_new') }) - .waitForElementVisible('*[data-id="fileSystem-modal-footer-ok-react"]') - .click('*[data-id="fileSystem-modal-footer-ok-react"]') + .modalFooterOKClick('TemplatesSelection') .pause(3000) .currentWorkspaceIs('workspace_new') .waitForElementVisible('li[data-id="treeViewLitreeViewItem.deps/remix-tests/remix_tests.sol"]') diff --git a/apps/remix-ide-e2e/src/tests/workspace.test.ts b/apps/remix-ide-e2e/src/tests/workspace.test.ts index d351b05ce18..094b35a080f 100644 --- a/apps/remix-ide-e2e/src/tests/workspace.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace.test.ts @@ -38,12 +38,12 @@ module.exports = { .clickLaunchIcon('filePanel') .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-remixDefault"]') + .scrollAndClick('*[data-id="create-remixDefault"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - // eslint-disable-next-line dot-notation - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_remix_default' }) - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_remix_default') + .modalFooterOKClick('TemplatesSelection') .pause(1000) .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') @@ -110,14 +110,12 @@ module.exports = { browser .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-blank"]') + .scrollAndClick('*[data-id="create-blank"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - // eslint-disable-next-line dot-notation - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_blank' }) - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=blank]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_blank') + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementPresent('*[data-id="treeViewUltreeViewMenu"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItem.prettierrc.json"]') @@ -133,14 +131,12 @@ module.exports = { browser .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-ozerc20"]') + .scrollAndClick('*[data-id="create-ozerc20"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - // eslint-disable-next-line dot-notation - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc20' }) - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=ozerc20]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_erc20') + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]') @@ -194,14 +190,12 @@ module.exports = { browser .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-ozerc721"]') + .scrollAndClick('*[data-id="create-ozerc721"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - // eslint-disable-next-line dot-notation - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc721' }) - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=ozerc721]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_erc721') + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]') @@ -255,14 +249,12 @@ module.exports = { browser .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-ozerc1155"]') + .scrollAndClick('*[data-id="create-ozerc1155"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - // eslint-disable-next-line dot-notation - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc1155' }) - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=ozerc1155]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_erc1155') + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]') @@ -316,17 +308,10 @@ module.exports = { browser .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent(`*[data-id='create-ozerc1155{"upgradeable":"uups","mintable":true,"burnable":true,"pausable":true}']`) + .scrollAndClick(`*[data-id='create-ozerc1155{"upgradeable":"uups","mintable":true,"burnable":true,"pausable":true}']`) .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=ozerc1155]') - .waitForElementPresent('*[data-id="ozCustomization"]') - .click('*[data-id="featureTypeMintable"]') - .click('*[data-id="featureTypeBurnable"]') - .click('*[data-id="featureTypePausable"]') - .click('*[data-id="upgradeTypeUups"]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]') @@ -386,12 +371,10 @@ module.exports = { browser .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-hashchecker"]') + .scrollAndClick('*[data-id="create-hashchecker"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=hashchecker]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcircuits/calculate_hash.circom"]') @@ -424,11 +407,12 @@ module.exports = { browser .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-remixDefault"]') + .scrollAndClick('*[data-id="create-remixDefault"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .click('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]') - .setValue('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_name') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .click('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .click('input[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_name') + .modalFooterOKClick('TemplatesSelection') .waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]') .addFile('test.sol', { content: 'test' }) .waitForElementVisible('*[data-id="treeViewLitreeViewItemtest.sol"]') @@ -438,11 +422,12 @@ module.exports = { }) .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-remixDefault"]') + .scrollAndClick('*[data-id="create-remixDefault"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .click('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]') - .setValue('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_name_1') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .click('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .click('input[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_name_1') + .modalFooterOKClick('TemplatesSelection') .waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]') .waitForElementNotPresent('*[data-id="treeViewLitreeViewItemtest.sol"]') .switchWorkspace('workspace_name') @@ -494,13 +479,12 @@ module.exports = { .clickLaunchIcon('filePanel') .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-ozerc1155"]') + .scrollAndClick('*[data-id="create-ozerc1155"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=ozerc1155]') - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'sometestworkspace' }) - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'sometestworkspace') + .modalFooterOKClick('TemplatesSelection') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItem.prettierrc.json"]') @@ -521,14 +505,12 @@ module.exports = { browser .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-ozerc1155"]') + .scrollAndClick('*[data-id="create-ozerc1155"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - // eslint-disable-next-line dot-notation - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=ozerc1155]') - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_db_test' }) - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_db_test') + .modalFooterOKClick('TemplatesSelection') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItem.prettierrc.json"]') @@ -551,14 +533,12 @@ module.exports = { .clickLaunchIcon('filePanel') .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-uniswapV4HookBookMultiSigSwapHook"]') + .scrollAndClick('*[data-id="create-uniswapV4HookBookMultiSigSwapHook"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=uniswapV4HookBookMultiSigSwapHook]') - // eslint-disable-next-line dot-notation - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'multisig cookbook' }) - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'multisig cookbook') + .modalFooterOKClick('TemplatesSelection') .waitForElementVisible('[data-id="PermissionHandler-modal-footer-ok-react"]', 300000) .click('[data-id="PermissionHandler-modal-footer-ok-react"]') // click on lib to close it diff --git a/apps/remix-ide-e2e/src/tests/workspace_git.test.ts b/apps/remix-ide-e2e/src/tests/workspace_git.test.ts index fdde711a8fd..0661eb31ee4 100644 --- a/apps/remix-ide-e2e/src/tests/workspace_git.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace_git.test.ts @@ -13,8 +13,9 @@ module.exports = { .clickLaunchIcon('filePanel') .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-remixDefault"]') + .scrollAndClick('*[data-id="create-remixDefault"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') .waitForElementVisible({ selector: "//*[@class='text-warning' and contains(.,'add username and email')]", locateStrategy: 'xpath' @@ -23,10 +24,10 @@ module.exports = { selector: '//*[@data-id="initGitRepository"][@disabled]', locateStrategy: 'xpath' }) - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_blank' }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_blank') .click('[data-id="initGitRepositoryLabel"]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementNotPresent('*[data-id="treeViewLitreeViewItem.git"]') @@ -47,15 +48,13 @@ module.exports = { .waitForElementNotVisible('[data-id="workspaceGitPanel"]') .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-blank"]') + .scrollAndClick('*[data-id="create-blank"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - // eslint-disable-next-line dot-notation - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_blank' }) - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=blank]') + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_blank') .click('[data-id="initGitRepositoryLabel"]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementVisible('[data-id="workspaceGitPanel"]') .waitForElementContainsText('[data-id="workspaceGitBranchesDropdown"]', 'main') @@ -391,12 +390,10 @@ module.exports = { browser .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-uniswapV4Template"]') + .scrollAndClick('*[data-id="create-uniswapV4Template"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=uniswapV4Template]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .modalFooterOKClick('TemplatesSelection') .pause(100) .waitForElementVisible('*[data-id="treeViewLitreeViewItemsrc"]') .openFile('src') @@ -413,14 +410,12 @@ module.exports = { .clickLaunchIcon('filePanel') .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-ozerc20"]') + .scrollAndClick('*[data-id="create-ozerc20"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - // eslint-disable-next-line dot-notation - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=ozerc20]') - .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'new_workspace' }) - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .scrollAndClick('*[data-id="modalDialogCustomPromptTextCreate"]') + .setValue('*[data-id="modalDialogCustomPromptTextCreate"]', 'new_workspace') + .modalFooterOKClick('TemplatesSelection') .waitForElementVisible('*[data-id="treeViewDivDraggableItemtests/MyToken_test.sol"]') }, 'Update settings for git #group5': function (browser: NightwatchBrowser) { @@ -468,13 +463,11 @@ module.exports = { .clickLaunchIcon('filePanel') .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') + .waitForElementPresent('*[data-id="create-uniswapV4Template"]') + .scrollAndClick('*[data-id="create-uniswapV4Template"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') - .click('select[id="wstemplate"]') - .click('select[id="wstemplate"] option[value=uniswapV4Template]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .pause(100) + .modalFooterOKClick('TemplatesSelection') + .pause(100) .waitForElementVisible('*[data-id="treeViewLitreeViewItemsrc"]') .openFile('src') .openFile('src/Counter.sol') diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 2dafcd7efec..a3722c75728 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -61,6 +61,8 @@ import { Matomo } from './app/plugins/matomo' import {SolCoder} from './app/plugins/solcoderAI' +import { TemplatesSelectionPlugin } from './app/plugins/templates-selection/templates-selection-plugin' + const isElectron = require('is-electron') const remixLib = require('@remix-project/remix-lib') @@ -315,6 +317,8 @@ class AppComponent { // ----------------- run script after each compilation results ----------- const pluginStateLogger = new PluginStateLogger() + const templateSelection = new TemplatesSelectionPlugin() + this.engine.register([ permissionHandler, this.layout, @@ -366,7 +370,8 @@ class AppComponent { solcoder, git, pluginStateLogger, - matomo + matomo, + templateSelection ]) //---- fs plugin diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 02d233d5bb8..b6ff0405132 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -195,7 +195,7 @@ module.exports = class Filepanel extends ViewPlugin { if (err) reject(err) else resolve(data || true) }) - }) + }, false) } renameWorkspace(oldName, workspaceName) { diff --git a/apps/remix-ide/src/app/plugins/remixGuide.tsx b/apps/remix-ide/src/app/plugins/remixGuide.tsx index d08d350b0b9..96d6adcf2fa 100644 --- a/apps/remix-ide/src/app/plugins/remixGuide.tsx +++ b/apps/remix-ide/src/app/plugins/remixGuide.tsx @@ -123,6 +123,7 @@ export class RemixGuidePlugin extends ViewPlugin { expandViewEl={ cell.expandViewElement } + key={cell.title} id={cell.title} handleExpand={() => { this.showVideo = true diff --git a/apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.css b/apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.css new file mode 100644 index 00000000000..f6e9f504f1c --- /dev/null +++ b/apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.css @@ -0,0 +1,12 @@ +.TSCellStyle { + min-height: 8.5rem; + max-width: 13rem; + min-width: 13rem; + max-height: 8.5rem; +} + +.badgeForCell { + max-width: fit-content; + padding-right: 0.5rem; + font-size: smaller; +} diff --git a/apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.tsx b/apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.tsx new file mode 100644 index 00000000000..6df97e60b6d --- /dev/null +++ b/apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.tsx @@ -0,0 +1,269 @@ + +import React from 'react' +import { FormattedMessage, useIntl } from 'react-intl' +import { CustomTooltip } from "@remix-ui/helper" +import { AppModal } from '@remix-ui/app' +import { ViewPlugin } from '@remixproject/engine-web' +import { PluginViewWrapper } from '@remix-ui/helper' +import { RemixUIGridView } from '@remix-ui/remix-ui-grid-view' +import { RemixUIGridSection } from '@remix-ui/remix-ui-grid-section' +import { RemixUIGridCell } from '@remix-ui/remix-ui-grid-cell' +import isElectron from 'is-electron' +import type { TemplateGroup } from '@remix-ui/workspace' +import './templates-selection-plugin.css' +import { templates } from './templates' + +//@ts-ignore +const _paq = (window._paq = window._paq || []) + +const profile = { + name: 'templateSelection', + displayName: 'Template Selection', + description: 'templateSelection', + location: 'mainPanel', + methods: [], + events: [], + maintainedBy: 'Remix', +} + +export class TemplatesSelectionPlugin extends ViewPlugin { + templates: Array + dispatch: React.Dispatch = () => { } + constructor() { + super(profile) + } + + async onActivation() { + this.handleThemeChange() + await this.call('tabs', 'focus', 'templateSelection') + this.renderComponent() + _paq.push(['trackEvent', 'plugin', 'activated', 'remixGuide']) + } + + onDeactivation(): void { + } + + private handleThemeChange() { + this.on('theme', 'themeChanged', (theme: any) => { + this.renderComponent() + }) + } + + setDispatch(dispatch: React.Dispatch): void { + this.dispatch = dispatch + this.renderComponent() + } + + render() { + return ( +
+ +
+ ) + } + + renderComponent() { + this.dispatch({ + ...this, + }) + } + + updateComponent() { + /* + This represents the different options available from the openzeppelin library. + const opts = { + // @ts-ignore: Object is possibly 'null'. + mintable: mintableCheckboxRef.current.checked, + // @ts-ignore: Object is possibly 'null'. + burnable: burnableCheckboxRef.current.checked, + // @ts-ignore: Object is possibly 'null'. + pausable: pausableCheckboxRef.current.checked, + // @ts-ignore: Object is possibly 'null'. + upgradeable: transparentRadioRef.current.checked ? transparentRadioRef.current.value : uupsRadioRef.current.checked ? uupsRadioRef.current.value : false + } + */ + const createWorkspace = async (item) => { + const defaultName = await this.call('filePanel', 'getAvailableWorkspaceName', item.displayName) + + const username = await this.call('settings', 'get', 'settings/github-user-name') + const email = await this.call('settings', 'get', 'settings/github-email') + const gitNotSet = !username || !email + let workspaceName = defaultName + let initGit = false + const modal: AppModal = { + id: 'TemplatesSelection', + title: window._intl.formatMessage({ id: !isElectron() ? 'filePanel.workspace.create': 'filePanel.workspace.create.desktop' }), + message: await createModalMessage(defaultName, gitNotSet, (value) => workspaceName = value, (value) => initGit = !!value), + okLabel: window._intl.formatMessage({ id: !isElectron() ? 'filePanel.ok':'filePanel.selectFolder' }), + } + const modalResult = await this.call('notification', 'modal', modal) + if (!modalResult) return + this.emit('createWorkspaceReducerEvent', workspaceName, item.value, item.opts, false, async (e, data) => { + if (e) { + const modal: AppModal = { + id: 'TemplatesSelection', + title: window._intl.formatMessage({ id: !isElectron() ? 'filePanel.workspace.create': 'filePanel.workspace.create.desktop' }), + message: e.message, + okLabel: window._intl.formatMessage({ id: 'filePanel.ok' }), + cancelLabel: window._intl.formatMessage({ id: 'filePanel.cancel' }) + } + await this.call('notification', 'modal', modal) + console.error(e) + } + + }, initGit) + } + + const addToCurrentWorkspace = async (item) => { + this.emit('addTemplateToWorkspaceReducerEvent', item.value, item.opts, false, async (e, data) => { + if (e) { + const modal: AppModal = { + id: 'TemplatesSelection', + title: window._intl.formatMessage({ id: !isElectron() ? 'filePanel.workspace.create': 'filePanel.workspace.create.desktop' }), + message: e.message, + okLabel: window._intl.formatMessage({ id: 'filePanel.ok' }), + cancelLabel: window._intl.formatMessage({ id: 'filePanel.cancel' }) + } + await this.call('notification', 'modal', modal) + console.error(e) + } else { + this.call('notification', 'toast', 'Files Added.') + } + }) + } + + return ( + + { + templates(window._intl).map(template => { + return + {template.items.map(item => { + return +
+
+
+ {item.description && {item.description}} +
+
+ {(item.opts && item.opts.upgradeable && item.opts.upgradeable === 'uupds') && Upgradeable-UUPS} + {(item.opts && item.opts.mintable) && mintable} + {(item.opts && item.opts.burnable) && burnable} + {(item.opts && item.opts.pausable) && pausable} +
+
+
+ {(!template.IsArtefact || !item.isArtefact) && + createWorkspace(item)} + className="btn btn-sm mr-2 border border-primary" + > + Create + + } + + addToCurrentWorkspace(item)} + className="btn btn-sm border" + > + Add to current + + +
+
+
+ })} +
+ })} +
+ ) + } +} + +const createModalMessage = async ( + defaultName: string, + gitConfigNotSet: boolean, + onChangeTemplateName: (name: string) => void, + onChangeInitGit: (name: string) => void) => { + + return ( + <> + + onChangeTemplateName(e.target.value)} + onInput={(e) => onChangeTemplateName((e.target as any).value)} + /> +
+ onChangeInitGit(e.target.value)} + onInput={(e) => onChangeInitGit((e.target as any).value)} + /> + +
+ {gitConfigNotSet ? ( +
+ +
+ ) : ( + <> + )} + + ) +} + diff --git a/apps/remix-ide/src/app/plugins/templates-selection/templates.ts b/apps/remix-ide/src/app/plugins/templates-selection/templates.ts new file mode 100644 index 00000000000..a42524a2851 --- /dev/null +++ b/apps/remix-ide/src/app/plugins/templates-selection/templates.ts @@ -0,0 +1,357 @@ + +export const templates = (intl) => { + return [ + { + name: "Generic", + items: [ + { value: "remixDefault", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.basic' }), description: 'A default project' }, + { value: "blank", displayName: intl.formatMessage({ id: 'filePanel.blank' }), IsArtefact: true, description: 'A blank project' } + ] + }, + { + name: "OpenZeppelin", + items: [ + { + value: "ozerc20", + displayName: "ERC20", + tagList: ["ERC20", "Solidity"], + description: 'A simple ERC20 project' + }, + { + value: "ozerc721", + displayName: "ERC721 (NFT)", + tagList: ["ERC721", "Solidity"], + description: 'A simple ERC721 (aka NFT) project' + }, + { + value: "ozerc1155", + tagList: ["Solidity"], + displayName: "ERC1155", + description: 'A simple ERC1155 (multi token) project' + }, + { + value: "ozerc20", + displayName: "ERC20", + description: "A standard interface for fungible tokens", + tagList: ["Solidity"], + opts: { + mintable: true + } + }, + { + value: "ozerc721", + displayName: "ERC721 (NFT)", + description: "Non-fungible Token Standard", + tagList: ["Solidity", "ERC721"], + opts: { + mintable: true + } + }, + { + value: "ozerc1155", + displayName: "ERC1155", + tagList: ["Solidity"], + description: "A standard interface for contracts that manage multiple token types", + opts: { + mintable: true + } + }, + { + value: "ozerc20", + displayName: "ERC20", + description: "A standard interface for fungible tokens", + tagList: ["Solidity", "ERC20"], + opts: { + mintable: true, + burnable: true + }, + }, + { + value: "ozerc721", + displayName: "ERC721 (NFT)", + description: "Non-fungible Token Standard", + opts: { + mintable: true, + burnable: true + }, + tagList: ["ERC721", "Solidity"] + }, + { + value: "ozerc1155", + displayName: "ERC1155", + description: "A standard interface for contracts that manage multiple token types", + opts: { + mintable: true, + burnable: true + }, + tagList: ["ERC1155", "Solidity"] + }, + { + value: "ozerc20", + displayName: "ERC20", + description: "A standard interface for fungible tokens", + opts: { + mintable: true, + pausable: true + }, + tagList: ["ERC20", "Solidity"] + }, + { + value: "ozerc721", + displayName: "ERC721 (NFT)", + description: "Non-fungible Token Standard", + opts: { + mintable: true, + pausable: true + }, + tagList: ["ERC721", "Solidity"] + }, + { + value: "ozerc1155", + displayName: "ERC1155", + description: "A standard interface for contracts that manage multiple token types", + tagList: ["ERC20"], + opts: { + mintable: true, + pausable: true + } + } + ] + }, + { + name: "OpenZeppelin Proxy", + items: [ + { + value: "ozerc20", + displayName: "ERC20", + description: "A standard interface for fungible tokens", + opts: { + upgradeable: 'uups' + }, + tagList: ["ERC20", "Solidity"] + }, + { + value: "ozerc721", + displayName: "ERC721 (NFT)", + description: "Non-fungible Token Standard", + opts: { + upgradeable: 'uups' + }, + tagList: ["ERC721", "Solidity"] + }, + { + value: "ozerc1155", + displayName: "ERC1155", + description: "A standard interface for contracts that manage multiple token types", + opts: { + upgradeable: 'uups' + }, + tagList: ["ERC1155", "Solidity"] + }, + { + value: "ozerc20", + displayName: "ERC20", + description: "A standard interface for fungible tokens", + opts: { + upgradeable: 'uups', + mintable: true + }, + tagList: ["ERC20", "Solidity"] + }, + { + value: "ozerc721", + displayName: "ERC721 (NFT)", + description: "Non-fungible Token Standard", + opts: { + upgradeable: 'uups', + mintable: true + }, + tagList: ["ERC721", "Solidity"] + }, + { + value: "ozerc1155", + displayName: "ERC1155", + description: "A standard interface for contracts that manage multiple token types", + opts: { + upgradeable: 'uups', + mintable: true + }, + tagList: ["ERC1155", "Solidity"] + }, + { + value: "ozerc20", + displayName: "ERC20", + description: "A standard interface for fungible tokens", + opts: { + upgradeable: 'uups', + mintable: true, + burnable: true + }, + tagList: ["ERC20", "Solidity"] + }, + { + value: "ozerc721", + displayName: "ERC721 (NFT)", + description: "Non-fungible Token Standard", + opts: { + upgradeable: 'uups', + mintable: true, + burnable: true + }, + tagList: ["ERC721", "Solidity"] + }, + { + value: "ozerc1155", + displayName: "ERC1155", + description: "A standard interface for contracts that manage multiple token types", + opts: { + upgradeable: 'uups', + mintable: true, + burnable: true + }, + tagList: ["ERC1155", "Solidity"] + }, + { + value: "ozerc20", + displayName: "ERC20", + description: "A standard interface for fungible tokens", + opts: { + upgradeable: 'uups', + mintable: true, + pausable: true + }, + tagList: ["ERC20", "Solidity"] + }, + { + value: "ozerc721", + displayName: "ERC721 (NFT)", + description: "Non-fungible Token Standard", + opts: { + upgradeable: 'uups', + mintable: true, + pausable: true + }, + tagList: ["ERC721", "Solidity"] + }, + { + value: "ozerc1155", + displayName: "ERC1155", + description: "A standard interface for contracts that manage multiple token types", + opts: { + upgradeable: 'uups', + mintable: true, + pausable: true + }, + tagList: ["ERC1155", "Solidity"] + }, + { + value: "ozerc1155", + displayName: "ERC1155", + description: "A standard interface for contracts that manage multiple token types", + opts: { + upgradeable: 'uups', + mintable: true, + burnable: true, + pausable: true + }, + tagList: ["ERC1155", "Solidity"] + } + ] + }, + { + name: "OxProject", + items: [ + { value: "zeroxErc20", displayName: "ERC20", tagList: ["ERC20", "Solidity"], description: "A standard interface for fungible tokens by 0xProject" } + ] + }, + { + name: "Gnosis Safe", + items: [ + { value: "gnosisSafeMultisig", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.multiSigWallet' }), description: 'Deploy or Customize the Gnosis Safe.' } + ] + }, + { + name: "Circom ZKP", + items: [ + { value: "semaphore", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.semaphore' }), description: 'Run a ZK Semaphore circom circuit.' }, + { value: "hashchecker", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.hashchecker' }), description: 'Run a ZK Hash checker circom circuit.' }, + { value: "rln", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.rln' }), description: 'Run a Rate Limiting Nullifier circom circuit.' } + ] + }, + { + name: "Generic ZKP", + items: [ + { + value: "sindriScripts", + tagList: ["ZKP"], + displayName: intl.formatMessage({ id: 'filePanel.addscriptsindri' }), + description: 'Use the Sindri API to compile and generate proof.' + }, + ], + }, + { + name: "Uniswap V4", + items: [ + { value: "uniswapV4Template", + displayName: intl.formatMessage({ id: 'filePanel.uniswapV4Template' }), + description: 'Use an Uniswap hook' + }, + { + value: "breakthroughLabsUniswapv4Hooks", + displayName: intl.formatMessage({ id: 'filePanel.breakthroughLabsUniswapv4Hooks' }), + description: 'Use an Uniswap hook developed by Breakthrough Labs' + }, + { + value: "uniswapV4HookBookMultiSigSwapHook", + displayName: intl.formatMessage({ id: 'filePanel.uniswapV4HookBookMultiSigSwapHook' }), + description: 'Use a MultiSigSwapHook developed by Breakthrough Labs' + } + ] + }, + { + name: "Solidity CREATE2", + items: [ + { + value: "contractCreate2Factory", + tagList: ["Solidity"], + displayName: intl.formatMessage({ id: 'filePanel.addcreate2solidityfactory' }), + description: 'Factory for deploying a Contract using the CREATE2 opcode.' + }, + { + value: "contractDeployerScripts", + displayName: intl.formatMessage({ id: 'filePanel.addscriptdeployer' }), + description: 'Script for deploying a Contract using the CREATE2 opcode.' + } + ] + }, + { + name: "Contract Verification", + items: [ + { + value: "etherscanScripts", + displayName: intl.formatMessage({ id: 'filePanel.addscriptetherscan' }), + description: 'Script for verifying a Contract in Etherscan.' + }, + ], + }, + { + name: 'Github Actions', + items: [ + { value: "runJsTestAction", + displayName: intl.formatMessage({ id: 'filePanel.tssoltestghaction' }), + description: 'A Mocha Chai Test Workflow in a GitHub CI.' + }, + { value: "runSolidityUnittestingAction", + displayName: intl.formatMessage({ id: 'filePanel.solghaction' }), + description: 'Run a Solidity Unittest Workflow in a GitHub CI.' + }, + { + value: "runSlitherAction", + displayName: intl.formatMessage({ id: 'filePanel.slitherghaction' }), + description: 'Run a Slither Security Analysis in a GitHub CI.' + } + ], + IsArtefact: true + } + ] +} \ No newline at end of file diff --git a/apps/remix-ide/src/app/providers/environment-explorer.tsx b/apps/remix-ide/src/app/providers/environment-explorer.tsx index b7919086505..8e5fe870116 100644 --- a/apps/remix-ide/src/app/providers/environment-explorer.tsx +++ b/apps/remix-ide/src/app/providers/environment-explorer.tsx @@ -108,8 +108,9 @@ export class EnvironmentExplorer extends ViewPlugin { title={provider.displayName} logos={provider.logos} classList='EECellStyle' - payload={provider.description} + searchKeywords={['Injected', provider.name, provider.displayName, provider.title, provider.description]} pinned={this.pinnedProviders.includes(provider.name)} + key={provider.name} id={provider.name} pinStateCallback={async (pinned: boolean) => { if (pinned) { @@ -142,8 +143,9 @@ export class EnvironmentExplorer extends ViewPlugin { title={provider.displayName} logos={provider.logos} classList='EECellStyle' - payload={provider.description} + searchKeywords={['Remix VMs', provider.name, provider.displayName, provider.title, provider.description]} pinned={this.pinnedProviders.includes(provider.name)} + key={provider.name} id={provider.name} pinStateCallback={async (pinned: boolean) => { if (pinned) { @@ -174,9 +176,10 @@ export class EnvironmentExplorer extends ViewPlugin { plugin={this} title={provider.displayName} logos={provider.logos} - payload={provider.description} classList='EECellStyle' + searchKeywords={['Externals', provider.name, provider.displayName, provider.title, provider.description]} pinned={this.pinnedProviders.includes(provider.name)} + key={provider.name} id={provider.name} pinStateCallback={async (pinned: boolean) => { if (pinned) { diff --git a/apps/remix-ide/src/app/providers/style/environment-explorer.css b/apps/remix-ide/src/app/providers/style/environment-explorer.css index ca19edbc987..b5770fba423 100644 --- a/apps/remix-ide/src/app/providers/style/environment-explorer.css +++ b/apps/remix-ide/src/app/providers/style/environment-explorer.css @@ -1,5 +1,5 @@ .EECellStyle { - min-height: 4rem; - max-width: 10rem; - min-width: 9rem; + min-height: 6rem; + max-width: 12rem; + min-width: 10rem; } diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index a42ae836f17..f512e93f2d2 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -82,6 +82,8 @@ let requiredModules = [ // services + layout views + system views 'pinnedPanel', 'pluginStateLogger', 'remixGuide', + 'environmentExplorer', + 'templateSelection', 'matomo', 'walletconnect' ] @@ -133,6 +135,8 @@ export function isNative(name) { 'compilationDetails', 'vyperCompilationDetails', //'remixGuide', + 'environmentExplorer', + 'templateSelection', 'walletconnect' ] return nativePlugins.includes(name) || requiredModules.includes(name) || isInjectedProvider(name) || isVM(name) diff --git a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css index d9618242762..760a85e1d66 100644 --- a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css +++ b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css @@ -28,8 +28,8 @@ width: 1rem; height: 1rem; position: relative; - right: 1.4rem; - top: -0.8rem; + right: 0.9rem; + top: -0.7rem; background: transparent; } @@ -41,8 +41,8 @@ .remixui_grid_cell_tags_no_pin { position: relative; - right: 0rem; - top: -6.5rem; + right: 0.45rem; + top: 1px } .remixui_grid_cell_tag { diff --git a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx index 698646d51a9..3055d0d4e71 100644 --- a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx +++ b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx @@ -18,7 +18,7 @@ interface RemixUIGridCellProps { logo?: string logos?: string[] title: string - payload?: string + hideTitle?: boolean tagList?: string[] // max 8, others will be ignored classList?: string styleList?: any @@ -26,6 +26,7 @@ interface RemixUIGridCellProps { expandViewEl?: any handleExpand?: any id: string + searchKeywords?: string[] } export const RemixUIGridCell = (props: RemixUIGridCellProps) => { @@ -35,16 +36,20 @@ export const RemixUIGridCell = (props: RemixUIGridCellProps) => { const [pinned, setPinned] = useState(props.pinned) useEffect(() => { - if (props.tagList) setAnyEnabled(props.tagList.some((key) => filterCon.keyValueMap[key]?.enabled)) - else setAnyEnabled(filterCon?.keyValueMap['no tag']?.enabled) - if (!props.tagList || props.tagList.length == 0) setAnyEnabled(true) - setAnyEnabled(anyEnabled && - ( - props.title.toLowerCase().includes(filterCon.filter) || - props.title.includes(filterCon.filter)) || - props?.payload?.toLowerCase().includes(filterCon.filter) || - props?.payload?.includes(filterCon.filter) - ) + let enabled = false + // check for tags + if (props.tagList && props.tagList.length != 0) { + enabled = props.tagList.some((key) => filterCon.keyValueMap[key]?.enabled) + } else if (filterCon?.keyValueMap['no tag']?.enabled || !Object.keys(filterCon?.keyValueMap).length) { + enabled = true + } + + // check for filter + if (filterCon.filter != '') + enabled = (props.title?.toLowerCase().includes(filterCon.filter?.toLowerCase()) || + props.searchKeywords?.map(keyword => keyword.toLowerCase()).some(searchKeyword => searchKeyword.toLowerCase().includes(filterCon.filter.toLocaleLowerCase()))) + + setAnyEnabled(enabled) }, [filterCon, props.tagList]) /*const listenOnExpand = (key) => { @@ -67,26 +72,32 @@ export const RemixUIGridCell = (props: RemixUIGridCellProps) => { props.handleExpand(!expand) else return }}> - { anyEnabled &&
+ { anyEnabled &&
-
-
-
+
+
+ { !props.hideTitle &&
{ props.logo && } { props.logos && props.logos.map((logo) => )} - { props.title && } -
+ { props.title && + + + + } +
} { props.children }
{ filterCon.showPin && } { props.tagList &&
{ Object.keys(props.tagList).map((key) => ( - filterCon.keyValueMap[props.tagList[key]].enabled && ( + filterCon.keyValueMap[props.tagList[key]]?.enabled && ( { )) }
} { !props.tagList && + className={'px-1 remixui_grid_cell_tags'}> }
{ expand &&
diff --git a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-section.tsx b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-section.tsx index 07e4eea279b..a3cb8b15c01 100644 --- a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-section.tsx +++ b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-section.tsx @@ -29,14 +29,11 @@ const hasChildCell = (children: ReactNode): boolean => { } const traverse = (child: ReactNode) => { - console.log('found ', children) - if (found) return if (isElement(child)) { - if (child.props.classList === 'EECellStyle') { + if (child.props.classList === 'remixui_grid_cell_container') { found = true - console.log('found ', child.props.className) return } 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 2215b6942da..24df154cf11 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx @@ -25,7 +25,7 @@ type WorkspaceTemplate = { workspaceTitle: string description: string projectLogo: string - templateName: string + templateName?: string } const workspaceTemplates: WorkspaceTemplate[] = [ @@ -70,7 +70,7 @@ const workspaceTemplates: WorkspaceTemplate[] = [ description: 'Create a new MultiSig wallet using this template.', projectLogo: 'assets/img/gnosissafeLogo.png', templateName: 'gnosisSafeMultisig', - }, + } ] function HomeTabGetStarted({ plugin }: HomeTabGetStartedProps) { @@ -163,9 +163,14 @@ function HomeTabGetStarted({ plugin }: HomeTabGetStartedProps) {