Merge branch 'master' into nx3

pull/3397/head
bunsenstraat 2 years ago committed by GitHub
commit 88a83f266d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      apps/remix-ide-e2e/src/tests/solidityImport.test.ts
  2. 1
      apps/remix-ide/src/app/plugins/permission-handler-plugin.tsx
  3. 2
      apps/remix-ide/src/app/providers/custom-vm-fork-provider.tsx
  4. 4
      apps/remix-ide/src/app/providers/injected-provider.tsx
  5. 6
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  6. 2
      apps/remix-ide/src/app/tabs/locales/en/settings.json
  7. 7
      apps/remix-ide/src/app/tabs/locales/zh/filePanel.json
  8. 27
      apps/remix-ide/src/app/udapp/run-tab.js
  9. 12
      apps/remix-ide/src/assets/css/themes/bootstrap-cyborg.min.css
  10. 2
      apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css
  11. 4
      apps/remix-ide/src/assets/css/themes/remix-hacker_owl.css
  12. 2
      apps/remix-ide/src/remixAppManager.js
  13. 31
      libs/remix-core-plugin/src/lib/compiler-artefacts.ts
  14. 13
      libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts
  15. 3
      libs/remix-core-plugin/src/types/contract.ts
  16. 10
      libs/remix-lib/src/util.ts
  17. 8
      libs/remix-lib/test/util.ts
  18. 2
      libs/remix-simulator/src/provider.ts
  19. 2
      libs/remix-ui/helper/src/lib/helper-components.tsx
  20. 4
      libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx
  21. 2
      libs/remix-ui/permission-handler/src/lib/permission-dialog.tsx
  22. 2
      libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx
  23. 1
      libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx
  24. 2
      libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx
  25. 11
      libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx
  26. 33
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx

@ -29,10 +29,9 @@ module.exports = {
.clickLaunchIcon('solidity')
.click('[data-id="compilerContainerCompileBtn"]')
.isVisible({
selector: "//span[contains(.,'not found Untitled11')]",
selector: "//span[contains(.,'not found /Untitled11')]",
locateStrategy: 'xpath',
timeout: 120000,
suppressNotFoundErrors: true
})
},

@ -11,7 +11,6 @@ const profile = {
description: 'Plugin to handle permissions',
methods: ['askPermission']
}
export class PermissionHandlerPlugin extends Plugin {
permissions: any
currentVersion: number

@ -39,7 +39,7 @@ export class CustomForkVMProvider extends BasicVMProvider {
</div>
<div>
<label className="mt-3 mb-1">EVM</label>
<select data-id="CustomForkEvmType" name="evmType" className="border form-control border-right-0">
<select data-id="CustomForkEvmType" name="evmType" defaultValue="merge" className="border form-control border-right-0">
{Object.keys(Hardfork).map((value, index) => {
return <option value={Hardfork[value]} key={index}>{value}</option>
})}

@ -35,10 +35,11 @@ export class InjectedProvider extends Plugin implements IProvider {
async init () {
const injectedProvider = (window as any).ethereum
if (injectedProvider === undefined) {
this.call('notification', 'toast', noInjectedProviderMsg)
throw new Error(noInjectedProviderMsg)
} else {
if (injectedProvider && injectedProvider._metamask && injectedProvider._metamask.isUnlocked) {
if (!await injectedProvider._metamask.isUnlocked()) throw new Error('Please make sure the injected provider is unlocked (e.g Metamask).')
if (!await injectedProvider._metamask.isUnlocked()) this.call('notification', 'toast', 'Please make sure the injected provider is unlocked (e.g Metamask).')
}
this.askPermission(true)
}
@ -60,7 +61,6 @@ export class InjectedProvider extends Plugin implements IProvider {
}
try {
if ((window as any) && typeof (window as any).ethereum.request === "function") (window as any).ethereum.request({ method: "eth_requestAccounts" });
if (!await (window as any).ethereum._metamask.isUnlocked()) this.call('notification', 'toast', 'Please make sure the injected provider is unlocked (e.g Metamask).')
const resultData = await this.provider.currentProvider.send(data.method, data.params)
resolve({ jsonrpc: '2.0', result: resultData.result, id: data.id })
} catch (error) {

@ -10,7 +10,8 @@
"filePanel.workspace.delete": "Delete Workspace",
"filePanel.workspace.deleteConfirm": "Are you sure to delete the current workspace?",
"filePanel.workspace.deleteAll": "Delete All Workspaces",
"filePanel.workspace.deleteAllConfirm": "Are you absolutely sure you want to delete all your workspaces? Deleted workspaces can not be restored in any manner.",
"filePanel.workspace.deleteAllConfirm1": "Are you absolutely sure you want to delete all your workspaces?",
"filePanel.workspace.deleteAllConfirm2": "Deleted workspaces can not be restored in any manner.",
"filePanel.workspace.name": "Workspace name",
"filePanel.workspace.chooseTemplate": "Choose a template",
"filePanel.workspace.download": "Backup Workspaces",
@ -54,5 +55,6 @@
"filePanel.customizeTemplate": "Customize template",
"filePanel.features": "Features",
"filePanel.upgradeability": "Upgradeability",
"filePanel.ok": "OK"
"filePanel.ok": "OK",
"filePanel.cancel": "Cancel"
}

@ -3,7 +3,7 @@
"settings.reset": "Reset to Default settings",
"settings.general": "General settings",
"settings.generateContractMetadataText": "Generate contract metadata. Generate a JSON file in the contract folder. Allows to specify library addresses the contract depends on. If nothing is specified, Remix deploys libraries automatically.",
"settings.ethereunVMText": "Always use Javascript VM at load",
"settings.ethereunVMText": "Always use the Remix VM at load",
"settings.wordWrapText": "Word wrap in editor",
"settings.useAutoCompleteText": "Enable code completion in editor.",
"settings.useShowGasInEditorText": "Display gas estimates in editor.",

@ -10,8 +10,8 @@
"filePanel.workspace.delete": "删除工作空间",
"filePanel.workspace.deleteConfirm": "确定要删除当前工作空间?",
"filePanel.workspace.deleteAll": "Delete All Workspaces",
"filePanel.workspace.deleteAllConfirm": "Are you absolutely sure you want to delete all your workspaces? Deleted workspaces can not be restored in any manner.",
"filePanel.workspace.name": "工作空间名称",
"filePanel.workspace.deleteAllConfirm1": "Are you absolutely sure you want to delete all your workspaces?",
"filePanel.workspace.deleteAllConfirm2": "Deleted workspaces can not be restored in any manner.", "filePanel.workspace.name": "工作空间名称",
"filePanel.workspace.chooseTemplate": "选择一个工作空间模板",
"filePanel.workspace.download": "下载工作空间",
"filePanel.workspace.restore": "恢复工作空间",
@ -54,5 +54,6 @@
"filePanel.customizeTemplate": "自定义模板",
"filePanel.features": "特点",
"filePanel.upgradeability": "可升级性",
"filePanel.ok": "确认"
"filePanel.ok": "确认",
"filePanel.cancel": "Cancel"
}

@ -131,6 +131,12 @@ export class RunTab extends ViewPlugin {
})
}
// basic injected
const displayNameInjected = `Injected Provider${(window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)) ?
window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet ? ' - Coinbase' :
window.ethereum.isBraveWallet || window.ethereum.selectedProvider?.isBraveWallet ? ' - Brave' :
window.ethereum.isMetaMask || window.ethereum.selectedProvider?.isMetaMask ? ' - MetaMask' : '' : ''}`
await addProvider('injected', displayNameInjected, true, false)
// VM
const titleVM = 'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.'
await addProvider('vm-merge', 'Remix VM (Merge)', false, true, 'merge', 'settingsVMMergeMode', titleVM)
@ -142,20 +148,17 @@ export class RunTab extends ViewPlugin {
await addProvider('vm-custom-fork', 'Remix VM - Custom fork', false, true, '', 'settingsVMCustomMode', titleVM)
// external provider
await addProvider('hardhat-provider', 'Hardhat Provider', false, false)
await addProvider('ganache-provider', 'Ganache Provider', false, false)
await addProvider('foundry-provider', 'Foundry Provider', false, false)
await addProvider('walletconnect', 'Wallet Connect', false, false)
await addProvider('basic-http-provider', 'External Http Provider', false, false)
await addProvider('basic-http-provider', 'Custom - External Http Provider', false, false)
await addProvider('hardhat-provider', 'Dev - Hardhat Provider', false, false)
await addProvider('ganache-provider', 'Dev - Ganache Provider', false, false)
await addProvider('foundry-provider', 'Dev - Foundry Provider', false, false)
// injected provider
const displayNameInjected = `Injected Provider${(window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)) ?
window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet ? ' - Coinbase' :
window.ethereum.isBraveWallet || window.ethereum.selectedProvider?.isBraveWallet ? ' - Brave' :
window.ethereum.isMetaMask || window.ethereum.selectedProvider?.isMetaMask ? ' - MetaMask' : '' : ''}`
await addProvider('injected', displayNameInjected, true, false)
await addProvider('injected-optimism-provider', 'Optimism Provider', true, false)
await addProvider('injected-arbitrum-one-provider', 'Arbitrum One Provider', true, false)
await addProvider('injected-optimism-provider', 'L2 - Optimism Provider', true, false)
await addProvider('injected-arbitrum-one-provider', 'L2 - Arbitrum One Provider', true, false)
await addProvider('walletconnect', 'Wallet Connect', false, false)
}
writeFile (fileName, content) {

@ -8611,28 +8611,28 @@ legend {
text-decoration:underline
}
.alert-primary {
background-color:#2a9fd6
background-color:#2a9fd685
}
.alert-secondary {
background-color:#555
}
.alert-success {
background-color:#77b300
background-color:#77b3007a
}
.alert-info {
background-color:#93c
background-color:#9933cc91
}
.alert-warning {
background-color:#f80
background-color:#ff8800a1
}
.alert-danger {
background-color:#c00
background-color:#cc00009c
}
.alert-light {
background-color:#222
}
.alert-dark {
background-color:#adafae
background-color:#adafae99
}
.badge-warning {
color:#fff

@ -4481,7 +4481,7 @@ a.badge-dark:focus {
}
.alert-primary {
color: #fff;
background-color: #5CBDEE;
background-color: #5cbdee94;
border-color: #5CBDEE;
}
.alert-primary hr {

@ -13,7 +13,7 @@
--cyan: #355f7d;
--white: #fff;
--gray: #8B99A6;
--gray-dark: #343a40;
--gray-dark: #8694a1;
--primary: #007aa6;
--secondary: #0E2A3E;
--success: #C4E07F;
@ -4491,7 +4491,7 @@ a.badge-dark:focus {
}
.alert-primary {
color: #fff;
background-color: #5CBDEE;
background-color: #5cbdee94;
border-color: #5CBDEE;
}
.alert-primary hr {

@ -10,7 +10,7 @@ const requiredModules = [ // services + layout views + system views
'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons',
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout',
'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy',
'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected', 'injected-optimism-provider', 'injected-arbitrum-one-provider',
'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected', 'injected-optimism-provider', 'injected-arbitrum-one-provider', 'vm-custom-fork', 'vm-goerli-fork', 'vm-mainnet-fork', 'vm-sepolia-fork', 'vm-merge', 'vm-london', 'vm-berlin',
'compileAndRun', 'search', 'recorder', 'fileDecorator', 'codeParser', 'codeFormatter', 'solidityumlgen', 'contractflattener']
// dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd)

@ -5,7 +5,7 @@ import { CompilerAbstract } from '@remix-project/remix-solidity'
const profile = {
name: 'compilerArtefacts',
methods: ['get', 'addResolvedContract', 'getCompilerAbstract', 'getAllContractDatas', 'getLastCompilationResult', 'getArtefactsByContractName', 'getContractDataFromAddress'],
methods: ['get', 'addResolvedContract', 'getCompilerAbstract', 'getAllContractDatas', 'getLastCompilationResult', 'getArtefactsByContractName', 'getContractDataFromAddress', 'getContractDataFromByteCode'],
events: [],
version: '0.0.1'
}
@ -98,16 +98,17 @@ export class CompilerArtefacts extends Plugin {
filterAllContractDatas (filter) {
const contractsData = {}
Object.keys(this.compilersArtefactsPerFile).map((targetFile) => {
const contracts = this.compilersArtefactsPerFile[targetFile].getContracts()
const artefact = this.compilersArtefactsPerFile[targetFile]
const contracts = artefact.getContracts()
Object.keys(contracts).map((file) => {
if (filter(file, contracts[file])) contractsData[file] = contracts[file]
if (filter(file, contracts[file], artefact)) contractsData[file] = contracts[file]
})
})
// making sure we save last compilation result in there
if (this.compilersArtefacts.__last) {
const contracts = this.compilersArtefacts.__last.getContracts()
Object.keys(contracts).map((file) => {
if (filter(file, contracts[file])) contractsData[file] = contracts[file]
if (filter(file, contracts[file], this.compilersArtefacts.__last)) contractsData[file] = contracts[file]
})
}
return contractsData
@ -194,8 +195,20 @@ export class CompilerArtefacts extends Plugin {
}
}
getCompilerAbstract (file) {
return this.compilersArtefactsPerFile[file]
async getCompilerAbstract (file) {
if (!file) return null
if (this.compilersArtefactsPerFile[file]) return this.compilersArtefactsPerFile[file]
const path = await this.call('fileManager', 'getPathFromUrl', file)
if (path && path.file && this.compilersArtefactsPerFile[path.file]) return this.compilersArtefactsPerFile[path.file]
let artefact = null
this.filterAllContractDatas((localFile, data, parentArtefact) => {
if (localFile === file || (path && path.file && localFile === path.file)) {
artefact = parentArtefact
}
})
return artefact
}
addResolvedContract (address: string, compilerData: CompilerAbstract) {
@ -212,12 +225,16 @@ export class CompilerArtefacts extends Plugin {
async getContractDataFromAddress (address) {
const code = await this.call('blockchain', 'getCode', address)
return this.getContractDataFromByteCode(code)
}
async getContractDataFromByteCode (code) {
let found
this.filterAllContractDatas((file, contractsData) => {
for (const name of Object.keys(contractsData)) {
const contract = contractsData[name]
if (util.compareByteCode(code, '0x' + contract.evm.deployedBytecode.object)) {
found = { name, contract }
found = { name, contract, file }
return true
}
}

@ -43,7 +43,14 @@ export class FetchAndCompile extends Plugin {
async resolve (contractAddress, codeAtAddress, targetPath) {
contractAddress = toChecksumAddress(contractAddress)
const localCompilation = async () => await this.call('compilerArtefacts', 'get', contractAddress) ? await this.call('compilerArtefacts', 'get', contractAddress) : await this.call('compilerArtefacts', 'get', '__last') ? await this.call('compilerArtefacts', 'get', '__last') : null
const localCompilation = async () => {
const contractData = await this.call('compilerArtefacts', 'getContractDataFromByteCode', codeAtAddress)
if (contractData) {
return await this.call('compilerArtefacts', 'getCompilerAbstract', contractData.file)
}
else
return await this.call('compilerArtefacts', 'get', '__last')
}
const resolved = await this.call('compilerArtefacts', 'get', contractAddress)
if (resolved) return resolved
@ -87,8 +94,7 @@ export class FetchAndCompile extends Plugin {
return localCompilation()
}
if (!network) return localCompilation()
if (!this.sourceVerifierNetWork.includes(network.name)) return localCompilation()
if (!this.sourceVerifierNetWork.includes(network.name)) {
// check if the contract if part of the local compilation result
const compilation = await localCompilation()
if (compilation) {
@ -103,6 +109,7 @@ export class FetchAndCompile extends Plugin {
return compilation
}
}
}
targetPath = `${targetPath}/${network.id}/${contractAddress}`
let data

@ -20,7 +20,8 @@ export interface ContractData {
getConstructorInterface: () => any,
getConstructorInputs: () => any,
isOverSizeLimit: () => boolean,
metadata: any
metadata: any,
contractName?: string
}
export interface ContractAST {

@ -258,6 +258,12 @@ export function compareByteCode (code1, code2) {
code2 = extractcborMetadata(code2)
if (code1 && code2) {
if (code1.length !== code2.length) {
// if the length isn't the same, we have an issue with extracting the metadata hash.
const minLength = code1.length > code2.length ? code2.length: code1.length
code1 = code1.substr(0, minLength - 10)
code2 = code2.substr(0, minLength - 10)
}
const compare = stringSimilarity.compareTwoStrings(code1, code2)
return compare == 1
}
@ -294,12 +300,12 @@ function removeByIndex (code, index, length, emptyRef) {
function removeImmutableReference (code1, code2) {
try {
const refOccurence = code2.match(/7f000000000000000000000000000000000000000000000000000000000000000073/g)
const refOccurence = code2.match(/7f0000000000000000000000000000000000000000000000000000000000000000/g)
if (!refOccurence) return code1
let offset = 0
refOccurence.map((value) => {
offset = code2.indexOf(value, offset)
code1 = removeByIndex(code1, offset, value.length, '7f000000000000000000000000000000000000000000000000000000000000000073')
code1 = removeByIndex(code1, offset, value.length, '7f0000000000000000000000000000000000000000000000000000000000000000')
offset = offset + 1
})
} catch (e) {

File diff suppressed because one or more lines are too long

@ -23,7 +23,7 @@ export class Provider {
constructor (options: Record<string, string | number> = {}) {
this.options = options
this.connected = true
this.vmContext = new VMContext(options['fork'] as string, options['nodeUrl'] as string, options['blockNumber'] as number)
this.vmContext = new VMContext(options['fork'] as string, options['nodeUrl'] as string, options['blockNumber'] as (number | 'latest'))
this.Accounts = new Web3Accounts(this.vmContext)
this.Transactions = new Transactions(this.vmContext)

@ -119,7 +119,7 @@ export const upgradeWithProxyMsg = () => (
export const unavailableProxyLayoutMsg = () => (
<div>
<p>Previous contract implementation is NOT available for upgrade comparison. <br /> A new storage layout will be saved for future upgrades.</p>
<p>The previous contract implementation is NOT available for an upgrade comparison<br /> A new storage layout will be saved for future upgrades.</p>
</div>
)

@ -98,7 +98,7 @@ export const ModalDialog = (props: ModalDialogProps) => {
{/* todo add autofocus ^^ */}
{ props.okLabel && <button
data-id={`${props.id}-modal-footer-ok-react`}
className={'modal-ok btn btn-sm ' + (props.okBtnClass ? props.okBtnClass : state.toggleBtn ? 'btn-dark' : 'btn-light')}
className={'modal-ok btn btn-sm ' + (props.okBtnClass ? props.okBtnClass : state.toggleBtn ? 'border-primary' : 'border-secondary')}
disabled={props.validation && !props.validation.valid}
onClick={() => {
if (props.validation && !props.validation.valid) return
@ -111,7 +111,7 @@ export const ModalDialog = (props: ModalDialogProps) => {
}
{ props.cancelLabel && <button
data-id={`${props.id}-modal-footer-cancel-react`}
className={'modal-cancel btn btn-sm ' + (props.cancelBtnClass ? props.cancelBtnClass : state.toggleBtn ? 'btn-light' : 'btn-dark')}
className={'modal-cancel btn btn-sm ' + (props.cancelBtnClass ? props.cancelBtnClass : state.toggleBtn ? 'border-secondary' : 'border-primary')}
data-dismiss="modal"
onClick={() => {
if (props.cancelFn) props.cancelFn()

@ -62,7 +62,7 @@ const PermissionHandlerDialog = (props: PermissionHandlerProps) => {
<label htmlFor='remember' className="form-check-label" data-id="permissionHandlerRememberChoice"><FormattedMessage id='permissionHandler.rememberThisChoice' /></label>
</div>
}
<button className="btn btn-sm" onClick={reset}><FormattedMessage id='permissionHandler.resetAllPermissions' /></button>
<button className="btn-secondary btn-sm" onClick={reset}><FormattedMessage id='permissionHandler.resetAllPermissions' /></button>
</article>
<div>{feedback}</div>
</section>)

@ -235,7 +235,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
}
const isValidProxyUpgrade = (proxyAddress: string) => {
return props.isValidProxyUpgrade(proxyAddress, loadedContractData.name, loadedContractData.compiler.source, loadedContractData.compiler.data)
return props.isValidProxyUpgrade(proxyAddress, loadedContractData.contractName || loadedContractData.name, loadedContractData.compiler.source, loadedContractData.compiler.data)
}
const checkSumWarning = () => {

@ -537,6 +537,7 @@ export function ContractGUI (props: ContractGUIProps) {
tooltipClasses="text-nowrap"
tooltipId={`proxyAddressTooltip${index}`}
tooltipText={'Deployed ' + shortenDate(deployment.date)}
key={index}
>
<Dropdown.Item
key={index}

@ -44,7 +44,7 @@ export function InstanceContainerUI (props: InstanceContainerProps) {
{ instanceList.length > 0
? <div> { props.instances.instanceList.map((instance, index) => {
return <UniversalDappUI
key={instance.address}
key={index}
instance={instance}
context={props.getContext()}
removeInstance={props.removeInstance}

@ -188,7 +188,8 @@ export const ContractSelection = (props: ContractSelectionProps) => {
}
const copyBytecode = () => {
return copyContractProperty('bytecode')
const bytecodeObj = JSON.parse(copyContractProperty('bytecode'))
return bytecodeObj.object
}
return (
@ -244,14 +245,14 @@ export const ContractSelection = (props: ContractSelectionProps) => {
<div className="remixui_contractHelperButtons">
<div className="input-group">
<div className="btn-group" role="group" aria-label="Copy to Clipboard">
<CopyToClipboard title="Copy ABI to clipboard" getContent={copyABI} direction='top'>
<button className="btn remixui_copyButton" title="Copy ABI to clipboard">
<CopyToClipboard tip="Copy ABI to clipboard" getContent={copyABI} direction='top'>
<button className="btn remixui_copyButton" >
<i className="remixui_copyIcon far fa-copy" aria-hidden="true"></i>
<span>ABI</span>
</button>
</CopyToClipboard>
<CopyToClipboard title="Copy ABI to clipboard" getContent={copyBytecode} direction='top'>
<button className="btn remixui_copyButton" title="Copy Bytecode to clipboard">
<CopyToClipboard tip="Copy Bytecode to clipboard" getContent={copyBytecode} direction='top'>
<button className="btn remixui_copyButton">
<i className="remixui_copyIcon far fa-copy" aria-hidden="true"></i>
<span>Bytecode</span>
</button>

@ -73,11 +73,11 @@ export function Workspace () {
}, [currentWorkspace])
const renameCurrentWorkspace = () => {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.rename' }), renameModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishRenameWorkspace, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.rename' }), renameModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishRenameWorkspace, intl.formatMessage({ id: 'filePanel.cancel' }))
}
const createWorkspace = () => {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), createModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishCreateWorkspace, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), createModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishCreateWorkspace, intl.formatMessage({ id: 'filePanel.cancel' }))
}
const deleteCurrentWorkspace = () => {
@ -86,17 +86,22 @@ export function Workspace () {
intl.formatMessage({ id: 'filePanel.workspace.deleteConfirm' }),
intl.formatMessage({ id: 'filePanel.ok' }),
onFinishDeleteWorkspace,
''
intl.formatMessage({ id: 'filePanel.cancel' })
)
}
const deleteAllWorkspaces = () => {
global.modal(
intl.formatMessage({ id: 'filePanel.workspace.deleteAll' }),
intl.formatMessage({ id: 'filePanel.workspace.deleteAllConfirm' }),
<>
<div className="d-flex flex-column">
<span className='pb-1'>{intl.formatMessage({ id: 'filePanel.workspace.deleteAllConfirm1' })}</span>
<span>{intl.formatMessage({ id: 'filePanel.workspace.deleteAllConfirm2' })}</span>
</div>
</>,
intl.formatMessage({ id: 'filePanel.ok' }),
onFinishDeleteAllWorkspaces,
''
intl.formatMessage({ id: 'filePanel.cancel' })
)
}
@ -106,7 +111,7 @@ export function Workspace () {
cloneModalMessage(),
intl.formatMessage({ id: 'filePanel.ok' }),
handleTypingUrl,
''
intl.formatMessage({ id: 'filePanel.cancel' })
)
}
@ -146,7 +151,7 @@ export function Workspace () {
try {
await global.dispatchRenameWorkspace(currentWorkspace, workspaceName)
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.rename' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.rename' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
@ -172,7 +177,7 @@ export function Workspace () {
try {
await global.dispatchCreateWorkspace(workspaceName, workspaceTemplateName, opts, initGitRepo)
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
@ -181,7 +186,7 @@ export function Workspace () {
try {
await global.dispatchDeleteWorkspace(global.fs.browser.currentWorkspace)
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.delete' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.delete' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
@ -190,7 +195,7 @@ export function Workspace () {
try {
await global.dispatchDeleteAllWorkspaces()
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.deleteAll' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.deleteAll' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
@ -204,7 +209,7 @@ export function Workspace () {
await global.dispatchSwitchToWorkspace(name)
global.dispatchHandleExpandPath([])
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.switch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, '')
global.modal(intl.formatMessage({ id: 'filePanel.workspace.switch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
@ -240,7 +245,7 @@ export function Workspace () {
intl.formatMessage({ id: 'filePanel.workspace.cloneMessage' }),
intl.formatMessage({ id: 'filePanel.ok' }),
() => {},
''
intl.formatMessage({ id: 'filePanel.cancel' })
)
}
}
@ -279,7 +284,7 @@ export function Workspace () {
}
} catch (e) {
console.error(e)
global.modal(intl.formatMessage({ id: 'filePanel.checkoutGitBranch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {})
global.modal(intl.formatMessage({ id: 'filePanel.checkoutGitBranch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
}
}
@ -288,7 +293,7 @@ export function Workspace () {
await global.dispatchCreateNewBranch(branchFilter)
_paq.push(['trackEvent', 'Workspace', 'GIT', 'switch_to_new_branch'])
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.checkoutGitBranch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {})
global.modal(intl.formatMessage({ id: 'filePanel.checkoutGitBranch' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
}
}

Loading…
Cancel
Save