From 4cb526396d39d84c6749249e59f42c15aaeb3138 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 2 Mar 2021 14:40:51 +0100 Subject: [PATCH 01/22] throw if no workspace --- apps/remix-ide/src/app/files/fileManager.js | 14 ++++++++++++-- .../src/app/files/workspaceFileProvider.js | 12 ++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.js b/apps/remix-ide/src/app/files/fileManager.js index d1838738e2..0ffe4f714b 100644 --- a/apps/remix-ide/src/app/files/fileManager.js +++ b/apps/remix-ide/src/app/files/fileManager.js @@ -514,6 +514,8 @@ class FileManager extends Plugin { if (file.startsWith('browser')) { return this._deps.filesProviders.browser } + const provider = this._deps.filesProviders.workspace + if (!provider.isReady()) throw createError({ code: 'ECONNRESET', message: 'No workspace has been opened.' }) return this._deps.filesProviders.workspace } @@ -579,7 +581,11 @@ class FileManager extends Plugin { async.each(Object.keys(filesSet), (file, callback) => { if (override) { - self._deps.filesProviders[fileProvider].set(file, filesSet[file].content) + try { + self._deps.filesProviders[fileProvider].set(file, filesSet[file].content) + } catch (e) { + return callback(e.message || e) + } self.syncEditor(fileProvider + file) return callback() } @@ -591,7 +597,11 @@ class FileManager extends Plugin { } else if (helper.checkSpecialChars(name)) { modalDialogCustom.alert('Special characters are not allowed') } else { - self._deps.filesProviders[fileProvider].set(name, filesSet[file].content) + try { + self._deps.filesProviders[fileProvider].set(name, filesSet[file].content) + } catch (e) { + return callback(e.message || e) + } self.syncEditor(fileProvider + name) } callback() diff --git a/apps/remix-ide/src/app/files/workspaceFileProvider.js b/apps/remix-ide/src/app/files/workspaceFileProvider.js index 9f8ae10eba..8522f5ff4c 100644 --- a/apps/remix-ide/src/app/files/workspaceFileProvider.js +++ b/apps/remix-ide/src/app/files/workspaceFileProvider.js @@ -6,6 +6,7 @@ class WorkspaceFileProvider extends FileProvider { constructor () { super('') this.workspacesPath = '.workspaces' + this.workspace = null } setWorkspace (workspace) { @@ -13,11 +14,20 @@ class WorkspaceFileProvider extends FileProvider { this.workspace = workspace } + getWorkspace () { + return this.workspace + } + + isReady () { + return this.workspace !== null + } + clearWorkspace () { this.workspace = null } removePrefix (path) { + if (!this.workspace) throw new Error('No workspace has been opened.') path = path.replace(/^\/|\/$/g, '') // remove first and last slash if (path.startsWith(this.workspacesPath + '/' + this.workspace)) return path if (path.startsWith(this.workspace)) return this.workspacesPath + '/' + this.workspace @@ -27,6 +37,7 @@ class WorkspaceFileProvider extends FileProvider { } resolveDirectory (path, callback) { + if (!this.workspace) throw new Error('No workspace has been opened.') super.resolveDirectory(path, (error, files) => { if (error) return callback(error) const unscoped = {} @@ -38,6 +49,7 @@ class WorkspaceFileProvider extends FileProvider { } _normalizePath (path) { + if (!this.workspace) throw new Error('No workspace has been opened.') return path.replace(this.workspacesPath + '/' + this.workspace + '/', '') } } From 354b0b1400087c8656b0a814e023aec19d647274 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 2 Mar 2021 14:41:05 +0100 Subject: [PATCH 02/22] modal alert if error --- apps/remix-ide/src/app/ui/landing-page/landing-page.js | 10 +++++++--- apps/remix-ide/src/lib/gist-handler.js | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide/src/app/ui/landing-page/landing-page.js b/apps/remix-ide/src/app/ui/landing-page/landing-page.js index e35de92041..c03c14cb8a 100644 --- a/apps/remix-ide/src/app/ui/landing-page/landing-page.js +++ b/apps/remix-ide/src/app/ui/landing-page/landing-page.js @@ -247,10 +247,14 @@ export class LandingPage extends ViewPlugin { (loadingMsg) => { tooltip(loadingMsg) }, (error, content, cleanUrl, type, url) => { if (error) { - modalDialogCustom.alert(error) + modalDialogCustom.alert(error.message || error) } else { - fileProviders.browser.addExternal(type + '/' + cleanUrl, content, url) - this.verticalIcons.select('fileExplorers') + try { + fileProviders.workspace.addExternal(type + '/' + cleanUrl, content, url) + this.verticalIcons.select('fileExplorers') + } catch (e) { + modalDialogCustom.alert(e.message) + } } } ) diff --git a/apps/remix-ide/src/lib/gist-handler.js b/apps/remix-ide/src/lib/gist-handler.js index d046befd24..9b92b5e2f8 100644 --- a/apps/remix-ide/src/lib/gist-handler.js +++ b/apps/remix-ide/src/lib/gist-handler.js @@ -60,6 +60,8 @@ function GistHandler (_window) { if (!errorLoadingFile) { const provider = fileManager.getProvider('workspace') provider.lastLoadedGistId = gistId + } else { + modalDialogCustom.alert(errorLoadingFile.message || errorLoadingFile) } }) }) From 1c7507d3a24c6da3fb319dfc1d3195b4077348c5 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 2 Mar 2021 18:15:37 +0100 Subject: [PATCH 03/22] linting --- apps/remix-ide/src/app/ui/landing-page/landing-page.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/ui/landing-page/landing-page.js b/apps/remix-ide/src/app/ui/landing-page/landing-page.js index c03c14cb8a..fea70a5a5a 100644 --- a/apps/remix-ide/src/app/ui/landing-page/landing-page.js +++ b/apps/remix-ide/src/app/ui/landing-page/landing-page.js @@ -251,10 +251,10 @@ export class LandingPage extends ViewPlugin { } else { try { fileProviders.workspace.addExternal(type + '/' + cleanUrl, content, url) - this.verticalIcons.select('fileExplorers') + this.verticalIcons.select('fileExplorers') } catch (e) { modalDialogCustom.alert(e.message) - } + } } } ) From 37d9c377e392fc9ff46e38d235e65655b8ef811e Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 09:37:53 +0100 Subject: [PATCH 04/22] ensure alert has a title --- apps/remix-ide/src/app/ui/landing-page/landing-page.js | 7 ++++--- apps/remix-ide/src/app/ui/modal-dialog-custom.js | 2 +- apps/remix-ide/src/lib/gist-handler.js | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/remix-ide/src/app/ui/landing-page/landing-page.js b/apps/remix-ide/src/app/ui/landing-page/landing-page.js index fea70a5a5a..bf89d166d8 100644 --- a/apps/remix-ide/src/app/ui/landing-page/landing-page.js +++ b/apps/remix-ide/src/app/ui/landing-page/landing-page.js @@ -240,20 +240,21 @@ export class LandingPage extends ViewPlugin {
e.g ${examples.map((url) => { return yo`` })}
` - modalDialogCustom.prompt(`Import from ${service}`, msg, null, (target) => { + const title = `Import from ${service}` + modalDialogCustom.prompt(title, msg, null, (target) => { if (target !== '') { compilerImport.import( target, (loadingMsg) => { tooltip(loadingMsg) }, (error, content, cleanUrl, type, url) => { if (error) { - modalDialogCustom.alert(error.message || error) + modalDialogCustom.alert(title, error.message || error) } else { try { fileProviders.workspace.addExternal(type + '/' + cleanUrl, content, url) this.verticalIcons.select('fileExplorers') } catch (e) { - modalDialogCustom.alert(e.message) + modalDialogCustom.alert(title, e.message) } } } diff --git a/apps/remix-ide/src/app/ui/modal-dialog-custom.js b/apps/remix-ide/src/app/ui/modal-dialog-custom.js index bcbd4aaec5..e681102428 100644 --- a/apps/remix-ide/src/app/ui/modal-dialog-custom.js +++ b/apps/remix-ide/src/app/ui/modal-dialog-custom.js @@ -5,7 +5,7 @@ var css = require('./styles/modal-dialog-custom-styles') module.exports = { alert: function (title, text) { if (text) return modal(title, yo`
${text}
`, null, { label: null }) - return modal('', yo`
${title}
`, null, { label: null }) + return modal('alert', yo`
${title}
`, null, { label: null }) }, prompt: function (title, text, inputValue, ok, cancel, focus) { return prompt(title, text, false, inputValue, ok, cancel, focus) diff --git a/apps/remix-ide/src/lib/gist-handler.js b/apps/remix-ide/src/lib/gist-handler.js index 9b92b5e2f8..92c170b10f 100644 --- a/apps/remix-ide/src/lib/gist-handler.js +++ b/apps/remix-ide/src/lib/gist-handler.js @@ -20,7 +20,7 @@ function GistHandler (_window) { if (gistId) { cb(gistId) } else { - modalDialogCustom.alert('Error while loading gist. Please provide a valid Gist ID or URL.') + modalDialogCustom.alert('Gist load error', 'Error while loading gist. Please provide a valid Gist ID or URL.') } } }) @@ -49,7 +49,7 @@ function GistHandler (_window) { json: true }, async (error, response, data = {}) => { if (error || !data.files) { - modalDialogCustom.alert(`Gist load error: ${error || data.message}`) + modalDialogCustom.alert('Gist load error', error || data.message) return } const obj = {} @@ -61,7 +61,7 @@ function GistHandler (_window) { const provider = fileManager.getProvider('workspace') provider.lastLoadedGistId = gistId } else { - modalDialogCustom.alert(errorLoadingFile.message || errorLoadingFile) + modalDialogCustom.alert('Gist load error', errorLoadingFile.message || errorLoadingFile) } }) }) From b38996d92a9085db5a5bd4914dfb4527393593be Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 10:09:15 +0100 Subject: [PATCH 05/22] fix e2e --- apps/remix-ide-e2e/src/tests/gist.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/gist.test.ts b/apps/remix-ide-e2e/src/tests/gist.test.ts index 4ebcb17e22..f832379e1f 100644 --- a/apps/remix-ide-e2e/src/tests/gist.test.ts +++ b/apps/remix-ide-e2e/src/tests/gist.test.ts @@ -84,7 +84,7 @@ module.exports = { .setValue('*[data-id="modalDialogCustomPromptText"]', testData.invalidGistId) .modalFooterOKClick() .waitForElementVisible('*[data-id="modalDialogModalBody"]') - .assert.containsText('*[data-id="modalDialogModalBody"]', 'Gist load error: Not Found') + .assert.containsText('*[data-id="modalDialogModalBody"]', 'Not Found') .modalFooterOKClick() }, From 0667661a4f7012a9e7d6240eee553aaa831892a9 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 10:51:08 +0100 Subject: [PATCH 06/22] use defaultValue not placeHolder --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 d97990e788..d56c278791 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -261,7 +261,7 @@ export const Workspace = (props: WorkspaceProps) => { return ( <> { state.modal.message } - + ) } @@ -270,7 +270,7 @@ export const Workspace = (props: WorkspaceProps) => { return ( <> { state.modal.message } - + ) } From 814c12ff3d76b0a70cc4867f5aa803960042ec03 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 11:06:46 +0100 Subject: [PATCH 07/22] add more check during workspace creattion --- apps/remix-ide/src/app/panels/file-panel.js | 3 +++ apps/remix-ide/src/lib/helper.js | 3 +++ libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index dad049d335..1c9c39c9e5 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -5,6 +5,7 @@ import React from 'react' // eslint-disable-line import ReactDOM from 'react-dom' import { Workspace } from '@remix-ui/workspace' // eslint-disable-line import * as ethutil from 'ethereumjs-util' +import { checkSpecialChars, checkSlash } from '../../lib/helper' var EventManager = require('../../lib/events') var { RemixdHandle } = require('../files/remixd-handle.js') var { GitHandle } = require('../files/git-handle.js') @@ -186,6 +187,8 @@ module.exports = class Filepanel extends ViewPlugin { } async createWorkspace (workspaceName) { + if (!workspaceName) throw new Error('name cannot be empty') + if (checkSpecialChars(workspaceName) || checkSlash(workspaceName)) throw new Error('special characters are not allowed') if (await this.workspaceExists(workspaceName)) throw new Error('workspace already exists') const browserProvider = this._deps.fileProviders.browser const workspacesPath = this._deps.fileProviders.workspace.workspacesPath diff --git a/apps/remix-ide/src/lib/helper.js b/apps/remix-ide/src/lib/helper.js index a96b8b0256..ac3f71a0e5 100644 --- a/apps/remix-ide/src/lib/helper.js +++ b/apps/remix-ide/src/lib/helper.js @@ -55,6 +55,9 @@ module.exports = { checkSpecialChars (name) { return name.match(/[:*?"<>\\'|]/) != null }, + checkSlash (name) { + return name.match(/\//) != null + }, isHexadecimal (value) { return /^[0-9a-fA-F]+$/.test(value) && (value.length % 2 === 0) }, 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 d56c278791..32916ebc6a 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -181,11 +181,11 @@ export const Workspace = (props: WorkspaceProps) => { try { await props.createWorkspace(workspaceName) + await setWorkspace(workspaceName) } catch (e) { modalMessage('Workspace Creation', e.message) console.error(e) } - await setWorkspace(workspaceName) } const onFinishDeleteWorkspace = async () => { From b6604ad2a1274abc26796ec99a6fd76e75429125 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 11:10:21 +0100 Subject: [PATCH 08/22] do not show 'cancel' for alert --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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 32916ebc6a..e989f1e55d 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -155,10 +155,7 @@ export const Workspace = (props: WorkspaceProps) => { modal(title, body, { label: 'OK', fn: () => {} - }, { - label: null, - fn: null - }) + }, null) } const workspaceRenameInput = useRef() From 4aac9bbdeab4b2786b8460e79afff42938553430 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 11:37:57 +0100 Subject: [PATCH 09/22] fix e2e --- apps/remix-ide-e2e/src/tests/solidityImport.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/remix-ide-e2e/src/tests/solidityImport.test.ts b/apps/remix-ide-e2e/src/tests/solidityImport.test.ts index adad6482ed..afbf1fe84f 100644 --- a/apps/remix-ide-e2e/src/tests/solidityImport.test.ts +++ b/apps/remix-ide-e2e/src/tests/solidityImport.test.ts @@ -21,6 +21,7 @@ module.exports = { .addFile('Untitled2.sol', sources[1]['Untitled2.sol']) .openFile('Untitled1.sol') .verifyContracts(['test6', 'test4', 'test5']) + .pause(1000) }, 'Test Failed Import': function (browser: NightwatchBrowser) { From d3b93057d54bb1b3d73113ff7d802ace79a4ecbd Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 12:05:58 +0100 Subject: [PATCH 10/22] capitalize --- apps/remix-ide/src/app/ui/modal-dialog-custom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/ui/modal-dialog-custom.js b/apps/remix-ide/src/app/ui/modal-dialog-custom.js index e681102428..d2b1daba44 100644 --- a/apps/remix-ide/src/app/ui/modal-dialog-custom.js +++ b/apps/remix-ide/src/app/ui/modal-dialog-custom.js @@ -5,7 +5,7 @@ var css = require('./styles/modal-dialog-custom-styles') module.exports = { alert: function (title, text) { if (text) return modal(title, yo`
${text}
`, null, { label: null }) - return modal('alert', yo`
${title}
`, null, { label: null }) + return modal('Alert', yo`
${title}
`, null, { label: null }) }, prompt: function (title, text, inputValue, ok, cancel, focus) { return prompt(title, text, false, inputValue, ok, cancel, focus) From ad47b45da769964c8fd1ee816b921ad92e5a5e2a Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 16:58:21 +0100 Subject: [PATCH 11/22] renaming, tes special character --- .../workspace/src/lib/remix-ui-workspace.tsx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) 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 e989f1e55d..382aeedec5 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -22,6 +22,10 @@ export interface WorkspaceProps { initialWorkspace: string } +const hasSpecialChar = (value) => { + return value.match(/[:*?"<>\\'|]/) != null || value.match(/\//) != null +} + var canUpload = window.File || window.FileReader || window.FileList || window.Blob export const Workspace = (props: WorkspaceProps) => { const LOCALHOST = ' - connect to localhost - ' @@ -152,10 +156,12 @@ export const Workspace = (props: WorkspaceProps) => { } const modalMessage = (title: string, body: string) => { - modal(title, body, { - label: 'OK', - fn: () => {} - }, null) + setTimeout(() => { // wait for any previous modal a chance to close + modal(title, body, { + label: 'OK', + fn: () => {} + }, null) + }, 200) } const workspaceRenameInput = useRef() @@ -165,6 +171,8 @@ export const Workspace = (props: WorkspaceProps) => { if (workspaceRenameInput.current === undefined) return // @ts-ignore: Object is possibly 'null'. const workspaceName = workspaceRenameInput.current.value + if (hasSpecialChar(workspaceName)) return modalMessage('Workspace Rename', 'special characters are not allowed') + const workspacesPath = props.workspace.workspacesPath await props.fileManager.rename('browser/' + workspacesPath + '/' + state.currentWorkspace, 'browser/' + workspacesPath + '/' + workspaceName) setWorkspace(workspaceName) From 08c1347ba4bce1b7f06cd7b86a17fdadeff69c62 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 17:16:09 +0100 Subject: [PATCH 12/22] fix workspace rename --- apps/remix-ide/src/app/panels/file-panel.js | 10 ++++++++++ .../workspace/src/lib/remix-ui-workspace.tsx | 18 +++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 1c9c39c9e5..305dc91c77 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -75,6 +75,7 @@ module.exports = class Filepanel extends ViewPlugin { ReactDOM.render( void, createWorkspace: (name: string) => void, + renameWorkspace: (oldName: string, newName: string) => void workspaceRenamed: ({ name: string }) => void, workspaceCreated: ({ name: string }) => void, workspaceDeleted: ({ name: string }) => void, @@ -22,10 +23,6 @@ export interface WorkspaceProps { initialWorkspace: string } -const hasSpecialChar = (value) => { - return value.match(/[:*?"<>\\'|]/) != null || value.match(/\//) != null -} - var canUpload = window.File || window.FileReader || window.FileList || window.Blob export const Workspace = (props: WorkspaceProps) => { const LOCALHOST = ' - connect to localhost - ' @@ -171,12 +168,15 @@ export const Workspace = (props: WorkspaceProps) => { if (workspaceRenameInput.current === undefined) return // @ts-ignore: Object is possibly 'null'. const workspaceName = workspaceRenameInput.current.value - if (hasSpecialChar(workspaceName)) return modalMessage('Workspace Rename', 'special characters are not allowed') - const workspacesPath = props.workspace.workspacesPath - await props.fileManager.rename('browser/' + workspacesPath + '/' + state.currentWorkspace, 'browser/' + workspacesPath + '/' + workspaceName) - setWorkspace(workspaceName) - props.workspaceRenamed({ name: state.currentWorkspace }) + try { + await props.renameWorkspace(state.currentWorkspace, workspaceName) + setWorkspace(workspaceName) + props.workspaceRenamed({ name: workspaceName }) + } catch (e) { + modalMessage('Workspace Rename', e.message) + console.error(e) + } } const onFinishCreateWorkspace = async () => { From 77925a01ccf4f8fa949ca354aa73fea01b9d9e45 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 17:25:37 +0100 Subject: [PATCH 13/22] add e2e tests --- .../remix-ide-e2e/src/tests/workspace.test.ts | 23 +++++++++++++++++++ .../workspace/src/lib/remix-ui-workspace.tsx | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/workspace.test.ts b/apps/remix-ide-e2e/src/tests/workspace.test.ts index 6ce4c81c60..9b04dc9500 100644 --- a/apps/remix-ide-e2e/src/tests/workspace.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace.test.ts @@ -50,6 +50,29 @@ module.exports = { .waitForElementNotPresent('*[data-id="treeViewLitreeViewItemtest.sol"]') .click('*[data-id="workspacesSelect"] option[value="workspace_name"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]') + }, + + 'Should rename a workspace': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="workspaceRename"]') // rename workspace_name + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]') + .waitForElementVisible('*[data-id="modalDialogCustomPromptTextRename"]') + // eslint-disable-next-line dot-notation + .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextRename"]')['value'] = 'workspace_name_renamed' }) + .click('*[data-id="workspacesModalDialogModalDialogModalFooter-react"] .modal-ok') + .click('*[data-id="workspacesSelect"] option[value="workspace_name_1"]') + .waitForElementNotPresent('*[data-id="treeViewLitreeViewItemtest.sol"]') + .click('*[data-id="workspacesSelect"] option[value="workspace_name_renamed"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtest.sol"]') + }, + + 'Should delete a workspace': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="workspacesSelect"] option[value="workspace_name_1"]') + .click('*[data-id="workspaceDelete"]') // delete workspace_name_1 + .waitForElementVisible('*[data-id="workspacesModalDialogModalDialogModalFooter-react"] .modal-ok') + .click('*[data-id="workspacesModalDialogModalDialogModalFooter-react"] .modal-ok') + .waitForElementNotPresent('*[data-id="workspacesSelect"] option[value="workspace_name_1"]') .end() }, 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 5ac80a1bfc..94273790e5 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -143,7 +143,7 @@ export const Workspace = (props: WorkspaceProps) => { } const deleteCurrentWorkspace = () => { - modal('Remove Workspace', 'Please choose a name for the workspace', { + modal('Remove Workspace', 'Are you sure to delete the current workspace?', { label: 'OK', fn: onFinishDeleteWorkspace }, { From a0d1fcc6245fe71a7717ea4a71fb9262ccd6c510 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 3 Mar 2021 20:27:57 +0100 Subject: [PATCH 14/22] linting --- apps/remix-ide-e2e/src/tests/workspace.test.ts | 2 +- apps/remix-ide/src/app/panels/file-panel.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/workspace.test.ts b/apps/remix-ide-e2e/src/tests/workspace.test.ts index 9b04dc9500..15b435c890 100644 --- a/apps/remix-ide-e2e/src/tests/workspace.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace.test.ts @@ -63,7 +63,7 @@ module.exports = { .click('*[data-id="workspacesSelect"] option[value="workspace_name_1"]') .waitForElementNotPresent('*[data-id="treeViewLitreeViewItemtest.sol"]') .click('*[data-id="workspacesSelect"] option[value="workspace_name_renamed"]') - .waitForElementVisible('*[data-id="treeViewLitreeViewItemtest.sol"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtest.sol"]') }, 'Should delete a workspace': function (browser: NightwatchBrowser) { diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 305dc91c77..f8edd1c841 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -209,7 +209,7 @@ module.exports = class Filepanel extends ViewPlugin { if (await this.workspaceExists(workspaceName)) throw new Error('workspace already exists') const browserProvider = this._deps.fileProviders.browser const workspacesPath = this._deps.fileProviders.workspace.workspacesPath - browserProvider.rename('browser/' + workspacesPath + '/' + oldName, 'browser/' + workspacesPath + '/' + workspaceName, true) + browserProvider.rename('browser/' + workspacesPath + '/' + oldName, 'browser/' + workspacesPath + '/' + workspaceName, true) } /** these are called by the react component, action is already finished whent it's called */ From fee2e1b240a50574a52253139d89f06d404fc3ed Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 4 Mar 2021 10:26:51 +0100 Subject: [PATCH 15/22] update label --- libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx | 4 ++-- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx index 19bb68b89f..eabf61d29e 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx @@ -16,12 +16,12 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => { }, { action: 'publishToGist', - title: 'Publish all [browser] explorer files to a github gist', + title: 'Publish all the current workspace files (only root) to a github gist', icon: 'fab fa-github' }, { action: 'uploadFile', - title: 'Load a local file into Remix\'s browser folder', + title: 'Load a local file into current workspace', icon: 'fa fa-upload' }, { 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 94273790e5..1fc77a66d5 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -174,7 +174,7 @@ export const Workspace = (props: WorkspaceProps) => { setWorkspace(workspaceName) props.workspaceRenamed({ name: workspaceName }) } catch (e) { - modalMessage('Workspace Rename', e.message) + modalMessage('Rename Workspace', e.message) console.error(e) } } @@ -188,7 +188,7 @@ export const Workspace = (props: WorkspaceProps) => { await props.createWorkspace(workspaceName) await setWorkspace(workspaceName) } catch (e) { - modalMessage('Workspace Creation', e.message) + modalMessage('Create Workspace', e.message) console.error(e) } } From c759cf72328205ff48a17215dda8f8991ee32978 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 4 Mar 2021 11:55:57 +0100 Subject: [PATCH 16/22] ensure folder exists before reading it --- apps/remix-ide/src/app/tabs/testTab/testTab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/testTab/testTab.js b/apps/remix-ide/src/app/tabs/testTab/testTab.js index 3132cba452..f0c85c773f 100644 --- a/apps/remix-ide/src/app/tabs/testTab/testTab.js +++ b/apps/remix-ide/src/app/tabs/testTab/testTab.js @@ -44,9 +44,9 @@ class TestTabLogic { const provider = this.fileManager.fileProviderOf(this.currentPath) if (!provider) return cb(null, []) const tests = [] - let files + let files = [] try { - files = await this.fileManager.readdir(this.currentPath) + if (await this.fileManager.exists(this.currentPath)) files = await this.fileManager.readdir(this.currentPath) } catch (e) { cb(e.message) } From 6ae7edd7c1df55e729b1d06b759298618cc2f186 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 4 Mar 2021 12:02:37 +0100 Subject: [PATCH 17/22] do not automatically create a folder --- .../src/app/tabs/styles/test-tab-styles.js | 3 +++ apps/remix-ide/src/app/tabs/test-tab.js | 20 ++++++++++++++----- .../remix-ide/src/app/tabs/testTab/testTab.js | 3 +++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/styles/test-tab-styles.js b/apps/remix-ide/src/app/tabs/styles/test-tab-styles.js index ce267b02bf..b6cce75aeb 100644 --- a/apps/remix-ide/src/app/tabs/styles/test-tab-styles.js +++ b/apps/remix-ide/src/app/tabs/styles/test-tab-styles.js @@ -48,5 +48,8 @@ var css = csjs` .labelOnBtn { border: hidden; } + .inputFolder { + width: 80%; + } ` module.exports = css diff --git a/apps/remix-ide/src/app/tabs/test-tab.js b/apps/remix-ide/src/app/tabs/test-tab.js index 2154232d23..36dcbed3a6 100644 --- a/apps/remix-ide/src/app/tabs/test-tab.js +++ b/apps/remix-ide/src/app/tabs/test-tab.js @@ -573,18 +573,28 @@ module.exports = class TestTab extends ViewPlugin { this.inputPath = yo` { if (e.keyCode === 191) this.updateDirList() }} - onchange=${(e) => this.updateCurrentPath(e)}/>` + onkeydown=${(e) => { if (e.keyCode === 191) this.updateDirList() }}/>` + + const createTestFolder = yo`` const availablePaths = yo`
- ${this.inputPath} - ${this.uiPathList} +
+ ${this.inputPath} + ${createTestFolder} + ${this.uiPathList} +
` this.updateDirList() diff --git a/apps/remix-ide/src/app/tabs/testTab/testTab.js b/apps/remix-ide/src/app/tabs/testTab/testTab.js index f0c85c773f..77c8fb4102 100644 --- a/apps/remix-ide/src/app/tabs/testTab/testTab.js +++ b/apps/remix-ide/src/app/tabs/testTab/testTab.js @@ -11,6 +11,9 @@ class TestTabLogic { setCurrentPath (path) { if (path.indexOf('/') === 0) return this.currentPath = path + } + + generateTestFolder (path) { const fileProvider = this.fileManager.fileProviderOf(path.split('/')[0]) fileProvider.exists(path, (e, res) => { if (!res) fileProvider.createDir(path) }) } From 04b0a419464b627a47d48bf102f7115be5f1e0f4 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 4 Mar 2021 12:02:52 +0100 Subject: [PATCH 18/22] fix open file --- apps/remix-ide/src/app/panels/file-panel.js | 4 ++-- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index f8edd1c841..e247b66326 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -167,8 +167,8 @@ module.exports = class Filepanel extends ViewPlugin { return await this.request.createNewFile() } - async uploadFile () { - return await this.request.uploadFile() + async uploadFile (event) { + return await this.request.uploadFile(event) } async processCreateWorkspace (name) { 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 1fc77a66d5..9c656bfb3a 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -41,6 +41,8 @@ export const Workspace = (props: WorkspaceProps) => { }) } + props.plugin.resetUploadFile = () => {} + /* implement an external API, consumed by the parent */ props.request.createWorkspace = () => { return createWorkspace() From 401ebef5137b135890747268c2b70cedd226b324 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 4 Mar 2021 12:14:50 +0100 Subject: [PATCH 19/22] fix reset focus --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 9c656bfb3a..00ae818a0f 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -29,9 +29,9 @@ export const Workspace = (props: WorkspaceProps) => { const NO_WORKSPACE = ' - none - ' /* extends the parent 'plugin' with some function needed by the file explorer */ - props.plugin.resetFocus = () => { + props.plugin.resetFocus = (reset) => { setState(prevState => { - return { ...prevState, reset: true } + return { ...prevState, reset } }) } From 50f9286e1b1542d8b5daf536f1cbb403ba05e770 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 4 Mar 2021 12:23:31 +0100 Subject: [PATCH 20/22] improve file migration --- apps/remix-ide/src/migrateFileSystem.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide/src/migrateFileSystem.js b/apps/remix-ide/src/migrateFileSystem.js index f626e1c20b..3ade9c0c88 100644 --- a/apps/remix-ide/src/migrateFileSystem.js +++ b/apps/remix-ide/src/migrateFileSystem.js @@ -29,11 +29,13 @@ export async function migrateToWorkspace (fileManager, filePanel) { if (fileStorageBrowserWorkspace.get(flag) === 'done') return const files = await browserProvider.copyFolderToJson('/') console.log(files) - const workspaceName = 'default_workspace' - const workspacePath = joinPath('browser', workspaceProvider.workspacesPath, workspaceName) - await filePanel.createWorkspace(workspaceName) - filePanel.getWorkspaces() // refresh list - await populateWorkspace(workspacePath, files, browserProvider) + if (Object.keys(files).length > 0) { + const workspaceName = 'default_workspace' + const workspacePath = joinPath('browser', workspaceProvider.workspacesPath, workspaceName) + await filePanel.createWorkspace(workspaceName) + filePanel.getWorkspaces() // refresh list + await populateWorkspace(workspacePath, files, browserProvider) + } fileStorageBrowserWorkspace.set(flag, 'done') } From 5e9df881ff90ca96ad31e38cbb1d0084e8e147c7 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 4 Mar 2021 14:19:45 +0100 Subject: [PATCH 21/22] fix e2e tests --- apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts | 2 ++ apps/remix-ide/src/app/tabs/test-tab.js | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts index 8ed2635e1d..284adb9efa 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts @@ -149,12 +149,14 @@ module.exports = { .addFile('myTests/simple_storage_test.sol', sources[0]['tests/simple_storage_test.sol']) .clickLaunchIcon('solidityUnitTesting') .setValue('*[data-id="uiPathInput"]', 'myTests') + .click('*[data-id="testTabGenerateTestFolder"]') .clickElementAtPosition('.singleTestLabel', 0) .scrollAndClick('*[data-id="testTabRunTestsTabRunAction"]') .waitForElementPresent('*[data-id="testTabSolidityUnitTestsOutputheader"]', 40000) .waitForElementPresent('*[data-id="testTabSolidityUnitTestsOutput"]') .clearValue('*[data-id="uiPathInput"]') .setValue('*[data-id="uiPathInput"]', 'tests') + .click('*[data-id="testTabGenerateTestFolder"]') }, 'Solidity Unittests': function (browser: NightwatchBrowser) { diff --git a/apps/remix-ide/src/app/tabs/test-tab.js b/apps/remix-ide/src/app/tabs/test-tab.js index 36dcbed3a6..a7052c2a1a 100644 --- a/apps/remix-ide/src/app/tabs/test-tab.js +++ b/apps/remix-ide/src/app/tabs/test-tab.js @@ -578,7 +578,8 @@ module.exports = class TestTab extends ViewPlugin { data-id="uiPathInput" name="utPath" style="background-image: var(--primary);" - onkeydown=${(e) => { if (e.keyCode === 191) this.updateDirList() }}/>` + onkeydown=${(e) => { if (e.keyCode === 191) this.updateDirList() }} + onchange=${(e) => this.updateCurrentPath(e)}/>` const createTestFolder = yo`