Merge pull request #5161 from ethereum/template-explorer-fixes

Template Explorer Fixes
pull/5184/head
Aniket 5 months ago committed by GitHub
commit bf94e6324c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.tsx
  2. 231
      apps/remix-ide/src/app/plugins/templates-selection/templates.ts
  3. 6
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  4. 51
      libs/remix-ui/workspace/src/lib/components/createModal.tsx
  5. 2
      libs/remix-ui/workspace/src/lib/components/workspace-hamburger-item.tsx
  6. 11
      libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx
  7. 22
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx

@ -147,7 +147,7 @@ export class TemplatesSelectionPlugin extends ViewPlugin {
['ERC721', 'secondary'],
['ERC1155', 'primary'],
]}
title='Template explorer'
title='Workspace Templates'
description="Select a template to create a workspace or to add it to current workspace"
>
{

@ -3,7 +3,7 @@ export const templates = (intl, plugin) => {
{
name: "Generic",
items: [
{ value: "remixDefault", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.basic' }), description: 'A default project' },
{ value: "remixDefault", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.basic' }), description: 'The default project' },
{ value: "blank", displayName: intl.formatMessage({ id: 'filePanel.blank' }), IsArtefact: true, description: 'A blank project' }
]
},
@ -14,102 +14,102 @@ export const templates = (intl, plugin) => {
value: "ozerc20",
displayName: "ERC20",
tagList: ["ERC20", "Solidity"],
description: 'A simple ERC20 project'
description: 'A simple fungible token contract'
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
tagList: ["ERC721", "Solidity"],
description: 'A simple ERC721 (aka NFT) project'
value: "ozerc20",
displayName: "ERC20",
description: "An ERC20 contract with:",
tagList: ["Solidity"],
opts: {
mintable: true
}
},
{
value: "ozerc1155",
tagList: ["Solidity"],
displayName: "ERC1155",
description: 'A simple ERC1155 (multi token) project'
value: "ozerc20",
displayName: "ERC20",
description: "An ERC20 contract with:",
tagList: ["Solidity", "ERC20"],
opts: {
mintable: true,
burnable: true
},
},
{
value: "ozerc20",
displayName: "ERC20",
description: "A standard interface for fungible tokens",
tagList: ["Solidity"],
description: "An ERC20 contract with:",
opts: {
mintable: true
}
mintable: true,
pausable: true
},
tagList: ["ERC20", "Solidity"]
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
description: "Non-fungible Token Standard",
tagList: ["Solidity", "ERC721"],
opts: {
mintable: true
}
displayName: "ERC721",
tagList: ["ERC721", "Solidity"],
description: 'A simple non-fungible token (NFT) contract'
},
{
value: "ozerc1155",
displayName: "ERC1155",
tagList: ["Solidity"],
description: "A standard interface for contracts that manage multiple token types",
value: "ozerc721",
displayName: "ERC721",
description: "An ERC721 contract with:",
tagList: ["Solidity", "ERC721"],
opts: {
mintable: true
}
},
{
value: "ozerc20",
displayName: "ERC20",
description: "A standard interface for fungible tokens",
tagList: ["Solidity", "ERC20"],
value: "ozerc721",
displayName: "ERC721 (NFT)",
description: "An ERC721 contract with:",
opts: {
mintable: true,
burnable: true
},
tagList: ["ERC721", "Solidity"]
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
description: "Non-fungible Token Standard",
description: "An ERC721 contract with:",
opts: {
mintable: true,
burnable: true
pausable: true
},
tagList: ["ERC721", "Solidity"]
},
{
value: "ozerc1155",
tagList: ["Solidity"],
displayName: "ERC1155",
description: "A standard interface for contracts that manage multiple token types",
opts: {
mintable: true,
burnable: true
},
tagList: ["ERC1155", "Solidity"]
description: 'A simple multi token contract'
},
{
value: "ozerc20",
displayName: "ERC20",
description: "A standard interface for fungible tokens",
value: "ozerc1155",
displayName: "ERC1155",
tagList: ["Solidity"],
description: "An ERC1155 contract with:",
opts: {
mintable: true,
pausable: true
},
tagList: ["ERC20", "Solidity"]
mintable: true
}
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
description: "Non-fungible Token Standard",
value: "ozerc1155",
displayName: "ERC1155",
description: "An ERC1155 contract with:",
opts: {
mintable: true,
pausable: true
burnable: true
},
tagList: ["ERC721", "Solidity"]
tagList: ["ERC1155", "Solidity"]
},
{
value: "ozerc1155",
displayName: "ERC1155",
description: "A standard interface for contracts that manage multiple token types",
tagList: ["ERC20"],
description: "An ERC1155 contract with:",
tagList: ["ERC1155"],
opts: {
mintable: true,
pausable: true
@ -122,120 +122,120 @@ export const templates = (intl, plugin) => {
items: [
{
value: "ozerc20",
displayName: "ERC20",
description: "A standard interface for fungible tokens",
displayName: "UUPS ERC20",
description: "A simple ERC20 contract using the Universal Upgradeable Proxy Standard (UUPS) pattern",
opts: {
upgradeable: 'uups'
},
tagList: ["ERC20", "Solidity"]
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
description: "Non-fungible Token Standard",
value: "ozerc20",
displayName: "UUPS ERC20",
description: "UUSP ERC20 contract with:",
opts: {
upgradeable: 'uups'
upgradeable: 'uups',
mintable: true
},
tagList: ["ERC721", "Solidity"]
tagList: ["ERC20", "Solidity"]
},
{
value: "ozerc1155",
displayName: "ERC1155",
description: "A standard interface for contracts that manage multiple token types",
value: "ozerc20",
displayName: "UUPS ERC20",
description: "UUSP ERC20 contract with:",
opts: {
upgradeable: 'uups'
upgradeable: 'uups',
mintable: true,
burnable: true
},
tagList: ["ERC1155", "Solidity"]
tagList: ["ERC20", "Solidity"]
},
{
value: "ozerc20",
displayName: "ERC20",
description: "A standard interface for fungible tokens",
displayName: "UUPS ERC20",
description: "UUSP ERC20 contract with:",
opts: {
upgradeable: 'uups',
mintable: true
mintable: true,
pausable: true
},
tagList: ["ERC20", "Solidity"]
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
description: "Non-fungible Token Standard",
displayName: "UUPS ERC721",
description: "A simple UUPS ERC721 contract",
opts: {
upgradeable: 'uups',
mintable: true
upgradeable: 'uups'
},
tagList: ["ERC721", "Solidity"]
},
{
value: "ozerc1155",
displayName: "ERC1155",
description: "A standard interface for contracts that manage multiple token types",
value: "ozerc721",
displayName: "UUPS ERC721",
description: "UUPS ERC721 contract with:",
opts: {
upgradeable: 'uups',
mintable: true
},
tagList: ["ERC1155", "Solidity"]
tagList: ["ERC721", "Solidity"]
},
{
value: "ozerc20",
displayName: "ERC20",
description: "A standard interface for fungible tokens",
value: "ozerc721",
displayName: "UUPS ERC721 (NFT)",
description: "Non-fungible Token Standard",
opts: {
upgradeable: 'uups',
mintable: true,
burnable: true
},
tagList: ["ERC20", "Solidity"]
tagList: ["ERC721", "Solidity"]
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
description: "Non-fungible Token Standard",
displayName: "UUPS ERC721 (NFT)",
description: "UUPS ERC721 with: ",
opts: {
upgradeable: 'uups',
mintable: true,
burnable: true
pausable: true
},
tagList: ["ERC721", "Solidity"]
},
{
value: "ozerc1155",
displayName: "ERC1155",
description: "A standard interface for contracts that manage multiple token types",
displayName: "UUPS ERC1155",
description: "A simple multi token contract using the UUPS pattern",
opts: {
upgradeable: 'uups',
mintable: true,
burnable: true
upgradeable: 'uups'
},
tagList: ["ERC1155", "Solidity"]
},
{
value: "ozerc20",
displayName: "ERC20",
description: "A standard interface for fungible tokens",
value: "ozerc1155",
displayName: "UUPS ERC1155",
description: "UUPS ERC1155 with:",
opts: {
upgradeable: 'uups',
mintable: true,
pausable: true
mintable: true
},
tagList: ["ERC20", "Solidity"]
tagList: ["ERC1155", "Solidity"]
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
description: "Non-fungible Token Standard",
value: "ozerc1155",
displayName: "UUPS ERC1155",
description: "UUPS ERC1155 with:",
opts: {
upgradeable: 'uups',
mintable: true,
pausable: true
burnable: true
},
tagList: ["ERC721", "Solidity"]
tagList: ["ERC1155", "Solidity"]
},
{
value: "ozerc1155",
displayName: "ERC1155",
description: "A standard interface for contracts that manage multiple token types",
displayName: "UUPS ERC1155",
description: "UUPS ERC1155 with:",
opts: {
upgradeable: 'uups',
mintable: true,
@ -245,8 +245,8 @@ export const templates = (intl, plugin) => {
},
{
value: "ozerc1155",
displayName: "ERC1155",
description: "A standard interface for contracts that manage multiple token types",
displayName: "UUPS ERC1155",
description: "UUPS ERC1155 with:",
opts: {
upgradeable: 'uups',
mintable: true,
@ -259,12 +259,12 @@ export const templates = (intl, plugin) => {
},
{
name: "Cookbook",
tooltip: "Cookbook is a smart contract search tool. Click here to open cookbook and browse contracts.",
tooltip: "Cookbook is a Smart Contract Search Tool. Click here to open Cookbook and browse Contracts.",
onClick: async () => {
await plugin.call('manager', 'activatePlugin', 'cookbookdev')
plugin.call('menuicons', 'showContent', 'cookbookdev')
},
onClickLabel: 'Open cookbook plugin',
onClickLabel: 'Open Cookbook Plugin',
items: [
{ value: "token-sale", displayName: 'Token Sale' },
{ value: "simple-nft-sale", displayName: 'Simple Nft Sale' },
@ -274,27 +274,30 @@ export const templates = (intl, plugin) => {
{ value: "nft-staking-with-infinite-rewards", displayName: 'Nft Staking with infinite rewards' },
{ value: "basic-dao", displayName: 'Basic DAO' },
{ value: "soulbound-nft", displayName: 'Soulbound Nft' },
{ value: "multi-collection-nft-with-burnable-nfts-and-pausable-transfers", displayName: 'Multi collection nft with burnable nfts and pausable transfers' },
{ value: "multi-collection-nft-with-burnable-nfts-and-pausable-transfers", displayName: 'Multi collection NFT', description: "Multi collection NFT with:", opts: {
burnable: true,
pausable: true
}, },
]
},
{
name: "OxProject",
items: [
{ value: "zeroxErc20", displayName: "ERC20", tagList: ["ERC20", "Solidity"], description: "A standard interface for fungible tokens by 0xProject" }
{ value: "zeroxErc20", displayName: "ERC20", tagList: ["ERC20", "Solidity"], description: "A fungible token contract by 0xProject" }
]
},
{
name: "Gnosis Safe",
items: [
{ value: "gnosisSafeMultisig", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.multiSigWallet' }), description: 'Deploy or Customize the Gnosis Safe.' }
{ 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.' }
{ value: "semaphore", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.semaphore' }), description: 'Semaphore protocol for casting a message as a provable group member' },
{ value: "hashchecker", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.hashchecker' }), description: 'Hash checker Circom circuit' },
{ value: "rln", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.rln' }), description: 'Rate Limiting Nullifier Circom circuit' }
]
},
{
@ -304,7 +307,7 @@ export const templates = (intl, plugin) => {
value: "sindriScripts",
tagList: ["ZKP"],
displayName: intl.formatMessage({ id: 'filePanel.addscriptsindri' }),
description: 'Use the Sindri API to compile and generate proof.'
description: 'Use the Sindri API to compile and generate proofs'
},
],
},
@ -334,12 +337,12 @@ export const templates = (intl, plugin) => {
value: "contractCreate2Factory",
tagList: ["Solidity"],
displayName: intl.formatMessage({ id: 'filePanel.addcreate2solidityfactory' }),
description: 'Factory for deploying a Contract using the CREATE2 opcode.'
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.'
description: 'Script for deploying a contract using the CREATE2 opcode'
}
]
},
@ -358,16 +361,16 @@ export const templates = (intl, plugin) => {
items: [
{ value: "runJsTestAction",
displayName: intl.formatMessage({ id: 'filePanel.tssoltestghaction' }),
description: 'A Mocha Chai Test Workflow in a GitHub CI.'
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.'
description: 'Run a Solidity unit test workflow in a GitHub CI.'
},
{
value: "runSlitherAction",
displayName: intl.formatMessage({ id: 'filePanel.slitherghaction' }),
description: 'Run a Slither Security Analysis in a GitHub CI.'
description: 'Run a Slither security analysis in a GitHub CI.'
}
],
IsArtefact: true

@ -2,6 +2,9 @@
"filePanel.displayName": "File explorer",
"filePanel.workspace": "WORKSPACES",
"filePanel.create": "Create",
"filePanel.createLabel": "Create Using Template",
"filePanel.createBlank":"Create Blank",
"filePanel.create.desktop": "Create Project",
"filePanel.clone": "Clone",
"filePanel.download": "Download",
@ -9,7 +12,8 @@
"filePanel.restore": "Restore",
"filePanel.name": "Name",
"filePanel.save": "Save",
"filePanel.workspace.create": "Create Workspace",
"filePanel.workspace.create": "Create Workspace using template",
"filePanel.workspace.createBlank": "Create Blank Workspace",
"filePanel.workspace.create.desktop": "Create project in new folder",
"filePanel.workspace.rename": "Rename Workspace",
"filePanel.workspace.save_workspace": "Save Workspace",

@ -0,0 +1,51 @@
import React from 'react'
import { FormattedMessage } from 'react-intl'
export const createModalMessage = async (
defaultName: string,
gitConfigNotSet: boolean,
onChangeTemplateName: (name: string) => void,
onChangeInitGit: (name: string) => void) => {
return (
<>
<label id="wsName" className="form-check-label" style={{ fontWeight: 'bolder' }}>
<FormattedMessage id="filePanel.workspaceName" />
</label>
<input
type="text"
data-id="modalDialogCustomPromptTextCreate"
defaultValue={defaultName}
className="form-control"
onChange={(e) => onChangeTemplateName(e.target.value)}
onInput={(e) => onChangeTemplateName((e.target as any).value)}
/>
<div className="d-flex py-2 align-items-center custom-control custom-checkbox">
<input
id="initGitRepository"
data-id="initGitRepository"
className="form-check-input custom-control-input"
type="checkbox"
disabled={gitConfigNotSet}
onChange={(e) => onChangeInitGit(e.target.value)}
onInput={(e) => onChangeInitGit((e.target as any).value)}
/>
<label
htmlFor="initGitRepository"
data-id="initGitRepositoryLabel"
className="m-0 form-check-label custom-control-label udapp_checkboxAlign"
title={window._intl.formatMessage({ id: 'filePanel.initGitRepoTitle' })}
>
<FormattedMessage id="filePanel.initGitRepositoryLabel" />
</label>
</div>
{gitConfigNotSet ? (
<div className="text-warning">
<FormattedMessage id="filePanel.initGitRepositoryWarning" />
</div>
) : (
<></>
)}
</>
)
}

@ -32,7 +32,7 @@ export function HamburgerMenuItem(props: HamburgerMenuItemProps) {
>
<span hidden={hideOption} id={uid} data-id={uid} className={props.fa + ' pl-2'} style={{ width: '1.4rem' }}></span>
<span className="px-2">
<FormattedMessage id={'filePanel.' + props.kind} />
{props.kind === 'create' ? <FormattedMessage id={'filePanel.createLabel'} /> :<FormattedMessage id={'filePanel.' + props.kind} />}
</span>
</div>
</CustomTooltip>

@ -7,6 +7,7 @@ import { WorkspaceMetadata } from '../types'
export interface HamburgerMenuProps {
selectedWorkspace: WorkspaceMetadata
createWorkspace: () => void
createBlankWorkspace: () => Promise<void>
renameCurrentWorkspace: () => void
downloadCurrentWorkspace: () => void
deleteCurrentWorkspace: () => void
@ -26,6 +27,16 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
const { showIconsMenu, hideWorkspaceOptions, hideLocalhostOptions, hideFileOperations, selectedWorkspace } = props
return (
<>
<HamburgerMenuItem
kind="createBlank"
fa="far fa-plus"
hideOption={hideWorkspaceOptions}
actionOnClick={() => {
props.createBlankWorkspace()
props.hideIconsMenu(!showIconsMenu)
}}
platforms={[appPlatformTypes.web]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="create"
fa="far fa-plus"

@ -18,6 +18,7 @@ import { AppContext, appPlatformTypes, platformContext } from '@remix-ui/app'
import { ElectronMenu } from './components/electron-menu'
import { ElectronWorkspaceName } from './components/electron-workspace-name'
import { branch, GitHubUser, gitUIPanels, userEmails } from '@remix-ui/git'
import { createModalMessage } from './components/createModal'
const _paq = (window._paq = window._paq || [])
@ -335,6 +336,26 @@ export function Workspace() {
)
}
const [counter, setCounter] = useState(1)
const createBlankWorkspace = async () => {
const username = await global.plugin.call('settings', 'get', 'settings/github-user-name')
const email = await global.plugin.call('settings', 'get', 'settings/github-email')
const gitNotSet = !username || !email
const defaultName = await global.plugin.call('filePanel', 'getAvailableWorkspaceName', 'blank')
let workspace = defaultName
let gitInit = false
setCounter((previous) => {
return previous + 1
})
global.modal(
intl.formatMessage({ id: 'filePanel.workspace.createBlank' }),
await createModalMessage(`blank - ${counter}`, gitNotSet, (value) => { workspace = value }, (value) => gitInit = false),
intl.formatMessage({ id: 'filePanel.ok' }),
() => global.dispatchCreateWorkspace(`blank - ${counter}`, 'blank', false),
intl.formatMessage({ id: 'filePanel.cancel' })
)
}
const saveSampleCodeWorkspace = () => {
const workspaceName = global.plugin.getAvailableWorkspaceName('code-sample')
global.modal(
@ -926,6 +947,7 @@ export function Workspace() {
<HamburgerMenu
selectedWorkspace={selectedWorkspace}
createWorkspace={createWorkspace}
createBlankWorkspace={createBlankWorkspace}
renameCurrentWorkspace={renameCurrentWorkspace}
downloadCurrentWorkspace={downloadCurrentWorkspace}
deleteCurrentWorkspace={deleteCurrentWorkspace}

Loading…
Cancel
Save