From 937fa20686544ea5bc8a75168177ccdfa5b6e433 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 22 Dec 2023 00:13:52 +0100 Subject: [PATCH] add cookbook template --- .../remix-ide-e2e/src/tests/workspace.test.ts | 20 ++++++++++++++++ .../src/app/tabs/locales/en/filePanel.json | 1 + apps/remix-ide/src/remixEngine.js | 1 + .../src/lib/components/homeTabGetStarted.tsx | 23 +++++++++++++------ .../workspace/src/lib/actions/workspace.ts | 23 ++++++++++++++----- .../workspace/src/lib/remix-ui-workspace.tsx | 8 ++++++- .../remix-ui/workspace/src/lib/types/index.ts | 2 +- .../workspace/src/lib/utils/constants.ts | 20 +++++++++++++++- 8 files changed, 82 insertions(+), 16 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/workspace.test.ts b/apps/remix-ide-e2e/src/tests/workspace.test.ts index c8b391e2fd..6c9d7e6b07 100644 --- a/apps/remix-ide-e2e/src/tests/workspace.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace.test.ts @@ -540,6 +540,26 @@ module.exports = { }, + 'Should create a cookbook workspace #group3': function (browser: NightwatchBrowser) { + browser + .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=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() }) + .waitForElementVisible('[data-id="PermissionHandler-modal-footer-ok-react"]', 300000) + .click('[data-id="PermissionHandler-modal-footer-ok-react"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemsrc"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemsrc/MULTI_SIG"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemsrc/MULTI_SIG/MultiSigSwapHook.sol"]') + }, + tearDown: sauce } diff --git a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json index d2a2973e5f..ecd13cbdbd 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json +++ b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json @@ -108,6 +108,7 @@ "filePanel.rln": "Rate-Limiting Nullifier", "filePanel.breakthroughLabsUniswapv4Hooks": "Breakthrough-Labs Uniswapv4Hooks", "filePanel.uniswapV4Periphery": "Uniswap v4 Periphery", + "filePanel.uniswapV4HookBookMultiSigSwapHook": "Uniswap V4 HookBook MultiSigSwapHook", "filePanel.transparent": "Transparent", "filePanel.initGitRepoTitle": "Check option to initialize workspace as a new git repository", "filePanel.switchToBranchTitle1": "Checkout new branch from remote branch", diff --git a/apps/remix-ide/src/remixEngine.js b/apps/remix-ide/src/remixEngine.js index 83c043c059..cc277997c4 100644 --- a/apps/remix-ide/src/remixEngine.js +++ b/apps/remix-ide/src/remixEngine.js @@ -23,6 +23,7 @@ export class RemixEngine extends Engine { if (name === 'circuit-compiler') return { queueTimeout: 60000 * 4 } if (name === 'filePanel') return { queueTimeout: 60000 * 20 } if (name === 'openaigpt') return { queueTimeout: 60000 * 2 } + if (name === 'cookbookdev') return { queueTimeout: 60000 * 2 } return { queueTimeout: 10000 } } 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 6cb03236cb..1ce54b15fb 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx @@ -61,14 +61,23 @@ function HomeTabGetStarted({plugin}: HomeTabGetStartedProps) { let templateDisplayName = TEMPLATE_NAMES[templateName] const metadata = TEMPLATE_METADATA[templateName] if (metadata) { - await plugin.call('dGitProvider', 'clone', {url: metadata.url, branch: metadata.branch}, templateDisplayName) - return + if (metadata && metadata.type === 'git') { + await plugin.call('dGitProvider', 'clone', {url: metadata.url, branch: metadata.branch}, templateDisplayName) + } else if (metadata && metadata.type === 'plugin') { + await plugin.appManager.activatePlugin('filePanel') + templateDisplayName = await plugin.call('filePanel', 'getAvailableWorkspaceName', templateDisplayName) + await plugin.call('filePanel', 'createWorkspace', templateDisplayName, 'blank') + await plugin.call('filePanel', 'setWorkspace', templateDisplayName) + plugin.verticalIcons.select('filePanel') + await plugin.call(metadata.name, metadata.endpoint, ...metadata.params) + } + } else { + await plugin.appManager.activatePlugin('filePanel') + templateDisplayName = await plugin.call('filePanel', 'getAvailableWorkspaceName', templateDisplayName) + await plugin.call('filePanel', 'createWorkspace', templateDisplayName, templateName) + await plugin.call('filePanel', 'setWorkspace', templateDisplayName) + plugin.verticalIcons.select('filePanel') } - await plugin.appManager.activatePlugin('filePanel') - templateDisplayName = await plugin.call('filePanel', 'getAvailableWorkspaceName', templateDisplayName) - await plugin.call('filePanel', 'createWorkspace', templateDisplayName, templateName) - await plugin.call('filePanel', 'setWorkspace', templateDisplayName) - plugin.verticalIcons.select('filePanel') _paq.push(['trackEvent', 'hometab', 'homeGetStarted', templateName]) } diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index e1c2469128..1444d5335c 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -1,7 +1,7 @@ import React from 'react' import { bufferToHex } from '@ethereumjs/util' import { hash } from '@remix-project/remix-lib' -import { TEMPLATE_METADATA, TEMPLATE_NAMES } from '../utils/constants' +import { TEMPLATE_METADATA, TEMPLATE_NAMES, TemplateType } from '../utils/constants' import axios, { AxiosResponse } from 'axios' import { addInputFieldSuccess, @@ -125,7 +125,8 @@ export const createWorkspace = async ( createCommit: boolean = true ) => { await plugin.fileManager.closeAllFiles() - const promise = createWorkspaceTemplate(workspaceName, workspaceTemplateName) + const metadata = TEMPLATE_METADATA[workspaceTemplateName] + const promise = createWorkspaceTemplate(workspaceName, workspaceTemplateName, metadata) dispatch(createWorkspaceRequest()) promise.then(async () => { dispatch(createWorkspaceSuccess({ name: workspaceName, isGitRepo })) @@ -170,7 +171,18 @@ export const createWorkspace = async ( } } } - if (!isEmpty && !(isGitRepo && createCommit)) await loadWorkspacePreset(workspaceTemplateName, opts) + if (metadata && metadata.type === 'plugin') { + plugin.call('notification', 'toast', 'Please wait while the workspace is being populated with the template.') + dispatch(cloneRepositoryRequest()) + setTimeout(() => { + plugin.call(metadata.name, metadata.endpoint, ...metadata.params).then(() => { + dispatch(cloneRepositorySuccess()) + }).catch((e) => { + dispatch(cloneRepositorySuccess()) + plugin.call('notification', 'toast', 'error adding template ' + e.message || e) + }) + }, 5000) + } else if (!isEmpty && !(isGitRepo && createCommit)) await loadWorkspacePreset(workspaceTemplateName, opts) cb && cb(null, workspaceName) if (isGitRepo) { await checkGit() @@ -190,12 +202,11 @@ export const createWorkspace = async ( return promise } -export const createWorkspaceTemplate = async (workspaceName: string, template: WorkspaceTemplate = 'remixDefault') => { - const metadata = TEMPLATE_METADATA[template] +export const createWorkspaceTemplate = async (workspaceName: string, template: WorkspaceTemplate = 'remixDefault', metadata?: TemplateType) => { if (!workspaceName) throw new Error('workspace name cannot be empty') if (checkSpecialChars(workspaceName) || checkSlash(workspaceName)) throw new Error('special characters are not allowed') if ((await workspaceExists(workspaceName)) && template === 'remixDefault') throw new Error('workspace already exists') - else if (metadata) { + else if (metadata && metadata.type === 'git') { await plugin.call('dGitProvider', 'clone', {url: metadata.url, branch: metadata.branch}, workspaceName) } else { const workspaceProvider = plugin.fileProviders.workspace diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 743cdbdae8..fd3de98e64 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -763,7 +763,13 @@ export function Workspace() { + + + + +
diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index 5d913be102..1984114bca 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -17,7 +17,7 @@ export interface JSONStandardInput { } } export type MenuItems = action[] -export type WorkspaceTemplate = 'gist-template' | 'code-template' | 'remixDefault' | 'blank' | 'ozerc20' | 'zeroxErc20' | 'ozerc721' | 'playground' | 'semaphore' | 'hashchecker' | 'rln' | 'breakthroughLabsUniswapv4Hooks' | 'uniswapV4Periphery' +export type WorkspaceTemplate = 'gist-template' | 'code-template' | 'remixDefault' | 'blank' | 'ozerc20' | 'zeroxErc20' | 'ozerc721' | 'playground' | 'semaphore' | 'hashchecker' | 'rln' | 'breakthroughLabsUniswapv4Hooks' | 'uniswapV4Periphery' | 'uniswapV4HookBookMultiSigSwapHook' export interface WorkspaceProps { plugin: FilePanelType } diff --git a/libs/remix-ui/workspace/src/lib/utils/constants.ts b/libs/remix-ui/workspace/src/lib/utils/constants.ts index 374d42708e..5f24e1a5e5 100644 --- a/libs/remix-ui/workspace/src/lib/utils/constants.ts +++ b/libs/remix-ui/workspace/src/lib/utils/constants.ts @@ -87,15 +87,33 @@ export const TEMPLATE_NAMES = { 'rln': 'Rate-Limiting Nullifier', 'breakthroughLabsUniswapv4Hooks': 'Breakthrough-Labs Uniswapv4Hooks', 'uniswapV4Periphery': 'Uniswap v4 Periphery', + 'uniswapV4HookBookMultiSigSwapHook': 'Uniswap V4 HookBook MultiSigSwapHook', } -export const TEMPLATE_METADATA = { +export const TEMPLATE_METADATA: Record = { 'breakthroughLabsUniswapv4Hooks': { + type: 'git', url: 'https://github.com/Breakthrough-Labs/Uniswapv4Hooks', branch: 'foundry_pure' }, 'uniswapV4Periphery': { + type: 'git', url: 'https://github.com/Uniswap/v4-periphery', branch: 'main' + }, + 'uniswapV4HookBookMultiSigSwapHook': { + type: 'plugin', + name: 'cookbookdev', + endpoint: 'openPattern', + params: ['Uniswap-V4-HookBook-MultiSigSwapHook', true] } } + +export type TemplateType = { + type: 'git' | 'plugin' + url?: string + branch?: string + name?: string + endpoint?: string + params?: any[] +}