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'], ['ERC721', 'secondary'],
['ERC1155', 'primary'], ['ERC1155', 'primary'],
]} ]}
title='Template explorer' title='Workspace Templates'
description="Select a template to create a workspace or to add it to current workspace" 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", name: "Generic",
items: [ 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' } { 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", value: "ozerc20",
displayName: "ERC20", displayName: "ERC20",
tagList: ["ERC20", "Solidity"], tagList: ["ERC20", "Solidity"],
description: 'A simple ERC20 project' description: 'A simple fungible token contract'
}, },
{ {
value: "ozerc721", value: "ozerc20",
displayName: "ERC721 (NFT)", displayName: "ERC20",
tagList: ["ERC721", "Solidity"], description: "An ERC20 contract with:",
description: 'A simple ERC721 (aka NFT) project' tagList: ["Solidity"],
opts: {
mintable: true
}
}, },
{ {
value: "ozerc1155", value: "ozerc20",
tagList: ["Solidity"], displayName: "ERC20",
displayName: "ERC1155", description: "An ERC20 contract with:",
description: 'A simple ERC1155 (multi token) project' tagList: ["Solidity", "ERC20"],
opts: {
mintable: true,
burnable: true
},
}, },
{ {
value: "ozerc20", value: "ozerc20",
displayName: "ERC20", displayName: "ERC20",
description: "A standard interface for fungible tokens", description: "An ERC20 contract with:",
tagList: ["Solidity"],
opts: { opts: {
mintable: true mintable: true,
} pausable: true
},
tagList: ["ERC20", "Solidity"]
}, },
{ {
value: "ozerc721", value: "ozerc721",
displayName: "ERC721 (NFT)", displayName: "ERC721",
description: "Non-fungible Token Standard", tagList: ["ERC721", "Solidity"],
tagList: ["Solidity", "ERC721"], description: 'A simple non-fungible token (NFT) contract'
opts: {
mintable: true
}
}, },
{ {
value: "ozerc1155", value: "ozerc721",
displayName: "ERC1155", displayName: "ERC721",
tagList: ["Solidity"], description: "An ERC721 contract with:",
description: "A standard interface for contracts that manage multiple token types", tagList: ["Solidity", "ERC721"],
opts: { opts: {
mintable: true mintable: true
} }
}, },
{ {
value: "ozerc20", value: "ozerc721",
displayName: "ERC20", displayName: "ERC721 (NFT)",
description: "A standard interface for fungible tokens", description: "An ERC721 contract with:",
tagList: ["Solidity", "ERC20"],
opts: { opts: {
mintable: true, mintable: true,
burnable: true burnable: true
}, },
tagList: ["ERC721", "Solidity"]
}, },
{ {
value: "ozerc721", value: "ozerc721",
displayName: "ERC721 (NFT)", displayName: "ERC721 (NFT)",
description: "Non-fungible Token Standard", description: "An ERC721 contract with:",
opts: { opts: {
mintable: true, mintable: true,
burnable: true pausable: true
}, },
tagList: ["ERC721", "Solidity"] tagList: ["ERC721", "Solidity"]
}, },
{ {
value: "ozerc1155", value: "ozerc1155",
tagList: ["Solidity"],
displayName: "ERC1155", displayName: "ERC1155",
description: "A standard interface for contracts that manage multiple token types", description: 'A simple multi token contract'
opts: {
mintable: true,
burnable: true
},
tagList: ["ERC1155", "Solidity"]
}, },
{ {
value: "ozerc20", value: "ozerc1155",
displayName: "ERC20", displayName: "ERC1155",
description: "A standard interface for fungible tokens", tagList: ["Solidity"],
description: "An ERC1155 contract with:",
opts: { opts: {
mintable: true, mintable: true
pausable: true }
},
tagList: ["ERC20", "Solidity"]
}, },
{ {
value: "ozerc721", value: "ozerc1155",
displayName: "ERC721 (NFT)", displayName: "ERC1155",
description: "Non-fungible Token Standard", description: "An ERC1155 contract with:",
opts: { opts: {
mintable: true, mintable: true,
pausable: true burnable: true
}, },
tagList: ["ERC721", "Solidity"] tagList: ["ERC1155", "Solidity"]
}, },
{ {
value: "ozerc1155", value: "ozerc1155",
displayName: "ERC1155", displayName: "ERC1155",
description: "A standard interface for contracts that manage multiple token types", description: "An ERC1155 contract with:",
tagList: ["ERC20"], tagList: ["ERC1155"],
opts: { opts: {
mintable: true, mintable: true,
pausable: true pausable: true
@ -122,120 +122,120 @@ export const templates = (intl, plugin) => {
items: [ items: [
{ {
value: "ozerc20", value: "ozerc20",
displayName: "ERC20", displayName: "UUPS ERC20",
description: "A standard interface for fungible tokens", description: "A simple ERC20 contract using the Universal Upgradeable Proxy Standard (UUPS) pattern",
opts: { opts: {
upgradeable: 'uups' upgradeable: 'uups'
}, },
tagList: ["ERC20", "Solidity"] tagList: ["ERC20", "Solidity"]
}, },
{ {
value: "ozerc721", value: "ozerc20",
displayName: "ERC721 (NFT)", displayName: "UUPS ERC20",
description: "Non-fungible Token Standard", description: "UUSP ERC20 contract with:",
opts: { opts: {
upgradeable: 'uups' upgradeable: 'uups',
mintable: true
}, },
tagList: ["ERC721", "Solidity"] tagList: ["ERC20", "Solidity"]
}, },
{ {
value: "ozerc1155", value: "ozerc20",
displayName: "ERC1155", displayName: "UUPS ERC20",
description: "A standard interface for contracts that manage multiple token types", description: "UUSP ERC20 contract with:",
opts: { opts: {
upgradeable: 'uups' upgradeable: 'uups',
mintable: true,
burnable: true
}, },
tagList: ["ERC1155", "Solidity"] tagList: ["ERC20", "Solidity"]
}, },
{ {
value: "ozerc20", value: "ozerc20",
displayName: "ERC20", displayName: "UUPS ERC20",
description: "A standard interface for fungible tokens", description: "UUSP ERC20 contract with:",
opts: { opts: {
upgradeable: 'uups', upgradeable: 'uups',
mintable: true mintable: true,
pausable: true
}, },
tagList: ["ERC20", "Solidity"] tagList: ["ERC20", "Solidity"]
}, },
{ {
value: "ozerc721", value: "ozerc721",
displayName: "ERC721 (NFT)", displayName: "UUPS ERC721",
description: "Non-fungible Token Standard", description: "A simple UUPS ERC721 contract",
opts: { opts: {
upgradeable: 'uups', upgradeable: 'uups'
mintable: true
}, },
tagList: ["ERC721", "Solidity"] tagList: ["ERC721", "Solidity"]
}, },
{ {
value: "ozerc1155", value: "ozerc721",
displayName: "ERC1155", displayName: "UUPS ERC721",
description: "A standard interface for contracts that manage multiple token types", description: "UUPS ERC721 contract with:",
opts: { opts: {
upgradeable: 'uups', upgradeable: 'uups',
mintable: true mintable: true
}, },
tagList: ["ERC1155", "Solidity"] tagList: ["ERC721", "Solidity"]
}, },
{ {
value: "ozerc20", value: "ozerc721",
displayName: "ERC20", displayName: "UUPS ERC721 (NFT)",
description: "A standard interface for fungible tokens", description: "Non-fungible Token Standard",
opts: { opts: {
upgradeable: 'uups', upgradeable: 'uups',
mintable: true, mintable: true,
burnable: true burnable: true
}, },
tagList: ["ERC20", "Solidity"] tagList: ["ERC721", "Solidity"]
}, },
{ {
value: "ozerc721", value: "ozerc721",
displayName: "ERC721 (NFT)", displayName: "UUPS ERC721 (NFT)",
description: "Non-fungible Token Standard", description: "UUPS ERC721 with: ",
opts: { opts: {
upgradeable: 'uups', upgradeable: 'uups',
mintable: true, mintable: true,
burnable: true pausable: true
}, },
tagList: ["ERC721", "Solidity"] tagList: ["ERC721", "Solidity"]
}, },
{ {
value: "ozerc1155", value: "ozerc1155",
displayName: "ERC1155", displayName: "UUPS ERC1155",
description: "A standard interface for contracts that manage multiple token types", description: "A simple multi token contract using the UUPS pattern",
opts: { opts: {
upgradeable: 'uups', upgradeable: 'uups'
mintable: true,
burnable: true
}, },
tagList: ["ERC1155", "Solidity"] tagList: ["ERC1155", "Solidity"]
}, },
{ {
value: "ozerc20", value: "ozerc1155",
displayName: "ERC20", displayName: "UUPS ERC1155",
description: "A standard interface for fungible tokens", description: "UUPS ERC1155 with:",
opts: { opts: {
upgradeable: 'uups', upgradeable: 'uups',
mintable: true, mintable: true
pausable: true
}, },
tagList: ["ERC20", "Solidity"] tagList: ["ERC1155", "Solidity"]
}, },
{ {
value: "ozerc721", value: "ozerc1155",
displayName: "ERC721 (NFT)", displayName: "UUPS ERC1155",
description: "Non-fungible Token Standard", description: "UUPS ERC1155 with:",
opts: { opts: {
upgradeable: 'uups', upgradeable: 'uups',
mintable: true, mintable: true,
pausable: true burnable: true
}, },
tagList: ["ERC721", "Solidity"] tagList: ["ERC1155", "Solidity"]
}, },
{ {
value: "ozerc1155", value: "ozerc1155",
displayName: "ERC1155", displayName: "UUPS ERC1155",
description: "A standard interface for contracts that manage multiple token types", description: "UUPS ERC1155 with:",
opts: { opts: {
upgradeable: 'uups', upgradeable: 'uups',
mintable: true, mintable: true,
@ -245,8 +245,8 @@ export const templates = (intl, plugin) => {
}, },
{ {
value: "ozerc1155", value: "ozerc1155",
displayName: "ERC1155", displayName: "UUPS ERC1155",
description: "A standard interface for contracts that manage multiple token types", description: "UUPS ERC1155 with:",
opts: { opts: {
upgradeable: 'uups', upgradeable: 'uups',
mintable: true, mintable: true,
@ -259,12 +259,12 @@ export const templates = (intl, plugin) => {
}, },
{ {
name: "Cookbook", 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 () => { onClick: async () => {
await plugin.call('manager', 'activatePlugin', 'cookbookdev') await plugin.call('manager', 'activatePlugin', 'cookbookdev')
plugin.call('menuicons', 'showContent', 'cookbookdev') plugin.call('menuicons', 'showContent', 'cookbookdev')
}, },
onClickLabel: 'Open cookbook plugin', onClickLabel: 'Open Cookbook Plugin',
items: [ items: [
{ value: "token-sale", displayName: 'Token Sale' }, { value: "token-sale", displayName: 'Token Sale' },
{ value: "simple-nft-sale", displayName: 'Simple Nft 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: "nft-staking-with-infinite-rewards", displayName: 'Nft Staking with infinite rewards' },
{ value: "basic-dao", displayName: 'Basic DAO' }, { value: "basic-dao", displayName: 'Basic DAO' },
{ value: "soulbound-nft", displayName: 'Soulbound Nft' }, { 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", name: "OxProject",
items: [ 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", name: "Gnosis Safe",
items: [ 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", name: "Circom ZKP",
items: [ items: [
{ value: "semaphore", tagList: ["ZKP"], displayName: intl.formatMessage({ id: 'filePanel.semaphore' }), description: 'Run a ZK Semaphore 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: 'Run a ZK Hash checker circom circuit.' }, { 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: 'Run a Rate Limiting Nullifier 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", value: "sindriScripts",
tagList: ["ZKP"], tagList: ["ZKP"],
displayName: intl.formatMessage({ id: 'filePanel.addscriptsindri' }), 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", value: "contractCreate2Factory",
tagList: ["Solidity"], tagList: ["Solidity"],
displayName: intl.formatMessage({ id: 'filePanel.addcreate2solidityfactory' }), 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", value: "contractDeployerScripts",
displayName: intl.formatMessage({ id: 'filePanel.addscriptdeployer' }), 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: [ items: [
{ value: "runJsTestAction", { value: "runJsTestAction",
displayName: intl.formatMessage({ id: 'filePanel.tssoltestghaction' }), 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", { value: "runSolidityUnittestingAction",
displayName: intl.formatMessage({ id: 'filePanel.solghaction' }), 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", value: "runSlitherAction",
displayName: intl.formatMessage({ id: 'filePanel.slitherghaction' }), 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 IsArtefact: true

@ -2,6 +2,9 @@
"filePanel.displayName": "File explorer", "filePanel.displayName": "File explorer",
"filePanel.workspace": "WORKSPACES", "filePanel.workspace": "WORKSPACES",
"filePanel.create": "Create", "filePanel.create": "Create",
"filePanel.createLabel": "Create Using Template",
"filePanel.createBlank":"Create Blank",
"filePanel.create.desktop": "Create Project", "filePanel.create.desktop": "Create Project",
"filePanel.clone": "Clone", "filePanel.clone": "Clone",
"filePanel.download": "Download", "filePanel.download": "Download",
@ -9,7 +12,8 @@
"filePanel.restore": "Restore", "filePanel.restore": "Restore",
"filePanel.name": "Name", "filePanel.name": "Name",
"filePanel.save": "Save", "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.create.desktop": "Create project in new folder",
"filePanel.workspace.rename": "Rename Workspace", "filePanel.workspace.rename": "Rename Workspace",
"filePanel.workspace.save_workspace": "Save 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 hidden={hideOption} id={uid} data-id={uid} className={props.fa + ' pl-2'} style={{ width: '1.4rem' }}></span>
<span className="px-2"> <span className="px-2">
<FormattedMessage id={'filePanel.' + props.kind} /> {props.kind === 'create' ? <FormattedMessage id={'filePanel.createLabel'} /> :<FormattedMessage id={'filePanel.' + props.kind} />}
</span> </span>
</div> </div>
</CustomTooltip> </CustomTooltip>

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

@ -18,6 +18,7 @@ import { AppContext, appPlatformTypes, platformContext } from '@remix-ui/app'
import { ElectronMenu } from './components/electron-menu' import { ElectronMenu } from './components/electron-menu'
import { ElectronWorkspaceName } from './components/electron-workspace-name' import { ElectronWorkspaceName } from './components/electron-workspace-name'
import { branch, GitHubUser, gitUIPanels, userEmails } from '@remix-ui/git' import { branch, GitHubUser, gitUIPanels, userEmails } from '@remix-ui/git'
import { createModalMessage } from './components/createModal'
const _paq = (window._paq = window._paq || []) 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 saveSampleCodeWorkspace = () => {
const workspaceName = global.plugin.getAvailableWorkspaceName('code-sample') const workspaceName = global.plugin.getAvailableWorkspaceName('code-sample')
global.modal( global.modal(
@ -926,6 +947,7 @@ export function Workspace() {
<HamburgerMenu <HamburgerMenu
selectedWorkspace={selectedWorkspace} selectedWorkspace={selectedWorkspace}
createWorkspace={createWorkspace} createWorkspace={createWorkspace}
createBlankWorkspace={createBlankWorkspace}
renameCurrentWorkspace={renameCurrentWorkspace} renameCurrentWorkspace={renameCurrentWorkspace}
downloadCurrentWorkspace={downloadCurrentWorkspace} downloadCurrentWorkspace={downloadCurrentWorkspace}
deleteCurrentWorkspace={deleteCurrentWorkspace} deleteCurrentWorkspace={deleteCurrentWorkspace}

Loading…
Cancel
Save