add cookbook template

pull/5370/head
yann300 11 months ago committed by Aniket
parent f3c2c67e76
commit 937fa20686
  1. 20
      apps/remix-ide-e2e/src/tests/workspace.test.ts
  2. 1
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  3. 1
      apps/remix-ide/src/remixEngine.js
  4. 23
      libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx
  5. 23
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  6. 6
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  7. 2
      libs/remix-ui/workspace/src/lib/types/index.ts
  8. 20
      libs/remix-ui/workspace/src/lib/utils/constants.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 tearDown: sauce
} }

@ -108,6 +108,7 @@
"filePanel.rln": "Rate-Limiting Nullifier", "filePanel.rln": "Rate-Limiting Nullifier",
"filePanel.breakthroughLabsUniswapv4Hooks": "Breakthrough-Labs Uniswapv4Hooks", "filePanel.breakthroughLabsUniswapv4Hooks": "Breakthrough-Labs Uniswapv4Hooks",
"filePanel.uniswapV4Periphery": "Uniswap v4 Periphery", "filePanel.uniswapV4Periphery": "Uniswap v4 Periphery",
"filePanel.uniswapV4HookBookMultiSigSwapHook": "Uniswap V4 HookBook MultiSigSwapHook",
"filePanel.transparent": "Transparent", "filePanel.transparent": "Transparent",
"filePanel.initGitRepoTitle": "Check option to initialize workspace as a new git repository", "filePanel.initGitRepoTitle": "Check option to initialize workspace as a new git repository",
"filePanel.switchToBranchTitle1": "Checkout new branch from remote branch", "filePanel.switchToBranchTitle1": "Checkout new branch from remote branch",

@ -23,6 +23,7 @@ export class RemixEngine extends Engine {
if (name === 'circuit-compiler') return { queueTimeout: 60000 * 4 } if (name === 'circuit-compiler') return { queueTimeout: 60000 * 4 }
if (name === 'filePanel') return { queueTimeout: 60000 * 20 } if (name === 'filePanel') return { queueTimeout: 60000 * 20 }
if (name === 'openaigpt') return { queueTimeout: 60000 * 2 } if (name === 'openaigpt') return { queueTimeout: 60000 * 2 }
if (name === 'cookbookdev') return { queueTimeout: 60000 * 2 }
return { queueTimeout: 10000 } return { queueTimeout: 10000 }
} }

@ -61,14 +61,23 @@ function HomeTabGetStarted({plugin}: HomeTabGetStartedProps) {
let templateDisplayName = TEMPLATE_NAMES[templateName] let templateDisplayName = TEMPLATE_NAMES[templateName]
const metadata = TEMPLATE_METADATA[templateName] const metadata = TEMPLATE_METADATA[templateName]
if (metadata) { if (metadata) {
await plugin.call('dGitProvider', 'clone', {url: metadata.url, branch: metadata.branch}, templateDisplayName) if (metadata && metadata.type === 'git') {
return 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]) _paq.push(['trackEvent', 'hometab', 'homeGetStarted', templateName])
} }

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import { bufferToHex } from '@ethereumjs/util' import { bufferToHex } from '@ethereumjs/util'
import { hash } from '@remix-project/remix-lib' 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 axios, { AxiosResponse } from 'axios'
import { import {
addInputFieldSuccess, addInputFieldSuccess,
@ -125,7 +125,8 @@ export const createWorkspace = async (
createCommit: boolean = true createCommit: boolean = true
) => { ) => {
await plugin.fileManager.closeAllFiles() await plugin.fileManager.closeAllFiles()
const promise = createWorkspaceTemplate(workspaceName, workspaceTemplateName) const metadata = TEMPLATE_METADATA[workspaceTemplateName]
const promise = createWorkspaceTemplate(workspaceName, workspaceTemplateName, metadata)
dispatch(createWorkspaceRequest()) dispatch(createWorkspaceRequest())
promise.then(async () => { promise.then(async () => {
dispatch(createWorkspaceSuccess({ name: workspaceName, isGitRepo })) 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) cb && cb(null, workspaceName)
if (isGitRepo) { if (isGitRepo) {
await checkGit() await checkGit()
@ -190,12 +202,11 @@ export const createWorkspace = async (
return promise return promise
} }
export const createWorkspaceTemplate = async (workspaceName: string, template: WorkspaceTemplate = 'remixDefault') => { export const createWorkspaceTemplate = async (workspaceName: string, template: WorkspaceTemplate = 'remixDefault', metadata?: TemplateType) => {
const metadata = TEMPLATE_METADATA[template]
if (!workspaceName) throw new Error('workspace name cannot be empty') if (!workspaceName) throw new Error('workspace name cannot be empty')
if (checkSpecialChars(workspaceName) || checkSlash(workspaceName)) throw new Error('special characters are not allowed') 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') 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) await plugin.call('dGitProvider', 'clone', {url: metadata.url, branch: metadata.branch}, workspaceName)
} else { } else {
const workspaceProvider = plugin.fileProviders.workspace const workspaceProvider = plugin.fileProviders.workspace

@ -764,6 +764,12 @@ export function Workspace() {
<option style={{fontSize: 'small'}} value="breakthroughLabsUniswapv4Hooks"> <option style={{fontSize: 'small'}} value="breakthroughLabsUniswapv4Hooks">
{intl.formatMessage({id: 'filePanel.breakthroughLabsUniswapv4Hooks'})} {intl.formatMessage({id: 'filePanel.breakthroughLabsUniswapv4Hooks'})}
</option> </option>
<option style={{fontSize: 'small'}} value="uniswapV4HookBookMultiSigSwapHook">
{intl.formatMessage({id: 'filePanel.uniswapV4HookBookMultiSigSwapHook'})}
</option>
</optgroup> </optgroup>
</select> </select>
<div id="ozcustomization" data-id="ozCustomization" ref={displayOzCustomRef} style={{display: 'none'}} className="mb-2"> <div id="ozcustomization" data-id="ozCustomization" ref={displayOzCustomRef} style={{display: 'none'}} className="mb-2">

@ -17,7 +17,7 @@ export interface JSONStandardInput {
} }
} }
export type MenuItems = action[] 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 { export interface WorkspaceProps {
plugin: FilePanelType plugin: FilePanelType
} }

@ -87,15 +87,33 @@ export const TEMPLATE_NAMES = {
'rln': 'Rate-Limiting Nullifier', 'rln': 'Rate-Limiting Nullifier',
'breakthroughLabsUniswapv4Hooks': 'Breakthrough-Labs Uniswapv4Hooks', 'breakthroughLabsUniswapv4Hooks': 'Breakthrough-Labs Uniswapv4Hooks',
'uniswapV4Periphery': 'Uniswap v4 Periphery', 'uniswapV4Periphery': 'Uniswap v4 Periphery',
'uniswapV4HookBookMultiSigSwapHook': 'Uniswap V4 HookBook MultiSigSwapHook',
} }
export const TEMPLATE_METADATA = { export const TEMPLATE_METADATA: Record<string, TemplateType> = {
'breakthroughLabsUniswapv4Hooks': { 'breakthroughLabsUniswapv4Hooks': {
type: 'git',
url: 'https://github.com/Breakthrough-Labs/Uniswapv4Hooks', url: 'https://github.com/Breakthrough-Labs/Uniswapv4Hooks',
branch: 'foundry_pure' branch: 'foundry_pure'
}, },
'uniswapV4Periphery': { 'uniswapV4Periphery': {
type: 'git',
url: 'https://github.com/Uniswap/v4-periphery', url: 'https://github.com/Uniswap/v4-periphery',
branch: 'main' 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[]
}

Loading…
Cancel
Save