Unverified Commit f816a5a6 authored by yann300's avatar yann300 Committed by GitHub

Merge pull request #924 from ethereum/open-save-workspace

Move workspace to a react component
parents 57c55f0f ce43be0f
......@@ -3,9 +3,9 @@ import { NightwatchBrowser } from 'nightwatch'
const EventEmitter = require('events')
class RemoveFile extends EventEmitter {
command (this: NightwatchBrowser, path: string): NightwatchBrowser {
command (this: NightwatchBrowser, path: string, workspace: string): NightwatchBrowser {
this.api.perform((done) => {
removeFile(this.api, path, () => {
removeFile(this.api, path, workspace, () => {
done()
this.emit('complete')
})
......@@ -14,7 +14,7 @@ class RemoveFile extends EventEmitter {
}
}
function removeFile (browser: NightwatchBrowser, path: string, done: VoidFunction) {
function removeFile (browser: NightwatchBrowser, path: string, workspace: string, done: VoidFunction) {
browser.execute(function (path) {
function contextMenuClick (element) {
const evt = element.ownerDocument.createEvent('MouseEvents')
......@@ -39,8 +39,8 @@ function removeFile (browser: NightwatchBrowser, path: string, done: VoidFunctio
.pause(2000)
.perform(() => {
console.log(path, 'to remove')
browser.waitForElementVisible('.modal-ok')
.click('.modal-ok')
browser.waitForElementVisible('*[data-id="' + workspace + 'ModalDialogContainer-react"] .modal-ok')
.click('*[data-id="' + workspace + 'ModalDialogContainer-react"] .modal-ok')
.waitForElementNotPresent('[data-path="' + path + '"]')
done()
})
......
......@@ -40,11 +40,7 @@ module.exports = {
'Should delete file `5_Renamed_Contract.sol` from file explorer': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="treeViewLitreeViewItem5_Renamed_Contract.sol"]')
.rightClick('[data-path="5_Renamed_Contract.sol"]')
.click('*[id="menuitemdelete"]')
.waitForElementVisible('*[data-id="default_workspaceModalDialogContainer-react"]')
.pause(2000)
.click('.modal-ok')
.removeFile('5_Renamed_Contract.sol', 'default_workspace')
.waitForElementNotPresent('*[data-id="treeViewLitreeViewItem5_Renamed_Contract.sol"')
},
......@@ -75,7 +71,7 @@ module.exports = {
.click('*[id="menuitemdelete"]')
.waitForElementVisible('*[data-id="default_workspaceModalDialogContainer-react"]')
.pause(2000)
.click('.modal-ok')
.click('*[data-id="default_workspaceModalDialogContainer-react"] .modal-ok')
.waitForElementNotPresent('*[data-id="treeViewLitreeViewItemBrowser_E2E_Tests"]')
},
......@@ -88,11 +84,11 @@ module.exports = {
.click('*[data-id="fileExplorerNewFilepublishToGist"]')
.waitForElementVisible('*[data-id="default_workspaceModalDialogContainer-react"]')
.pause(2000)
.click('.modal-ok')
.click('*[data-id="default_workspaceModalDialogContainer-react"] .modal-ok')
.pause(2000)
.waitForElementVisible('*[data-id="default_workspaceModalDialogContainer-react"]')
.pause(2000)
.click('.modal-ok')
.click('*[data-id="default_workspaceModalDialogContainer-react"] .modal-ok')
.pause(2000)
.perform((done) => {
if (runtimeBrowser === 'chrome') {
......
......@@ -38,7 +38,7 @@ module.exports = {
.click('*[data-id="fileExplorerNewFilepublishToGist"]')
.pause(2000)
.waitForElementVisible('*[data-id="default_workspaceModalDialogContainer-react"]')
.click('.modal-ok')
.click('*[data-id="default_workspaceModalDialogContainer-react"] .modal-ok')
.pause(10000)
.getText('[data-id="default_workspaceModalDialogModalBody-react"]', (result) => {
console.log(result)
......@@ -99,7 +99,7 @@ module.exports = {
.click('*[data-id="fileExplorerNewFilepublishToGist"]')
.waitForElementVisible('*[data-id="default_workspaceModalDialogContainer-react"]')
.pause(2000)
.click('.modal-ok')
.click('*[data-id="default_workspaceModalDialogContainer-react"] .modal-ok')
.pause(10000)
.getText('[data-id="default_workspaceModalDialogModalBody-react"]', (result) => {
browser.assert.ok(result.value === 'Remix requires an access token (which includes gists creation permission). Please go to the settings tab to create one.', 'Assert failed. Gist token error message not displayed.')
......
......@@ -125,7 +125,7 @@ function runTests (browser: NightwatchBrowser) {
.pause(1000)
.renamePath('folder1/contract_' + browserName + '.sol', 'renamed_contract_' + browserName + '.sol', 'folder1/renamed_contract_' + browserName + '.sol')
.pause(1000)
.removeFile('folder1/contract_' + browserName + '_toremove.sol')
.removeFile('folder1/contract_' + browserName + '_toremove.sol', 'localhost')
.perform(function (done) {
testImportFromRemixd(browser, () => { done() })
})
......
......@@ -37,7 +37,7 @@ module.exports = {
.clickLaunchIcon('fileExplorers')
.pause(10000)
.openFile('tests/simple_storage_test.sol')
.removeFile('tests/simple_storage_test.sol')
.removeFile('tests/simple_storage_test.sol', 'default_workspace')
},
'Should run simple unit test `simple_storage_test.sol` ': function (browser: NightwatchBrowser) {
......
......@@ -18,6 +18,8 @@ module.exports = {
'Editor should be focused on the 3_Ballot.sol': function (browser: NightwatchBrowser) {
browser
.pause(5000)
.refresh()
.pause(2000)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf('contract Ballot {') !== -1, 'content doesn\'t include Ballot contract')
})
......@@ -32,18 +34,18 @@ module.exports = {
browser
.clickLaunchIcon('fileExplorers')
.click('*[data-id="workspaceCreate"]') // create workspace_name
.waitForElementVisible('*[data-id="modalDialogCustomPromptText"]')
.clearValue('*[data-id="modalDialogCustomPromptText"]')
.setValue('*[data-id="modalDialogCustomPromptText"]', 'workspace_name')
.modalFooterOKClick()
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
// eslint-disable-next-line dot-notation
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_name' })
.click('*[data-id="workspacesModalDialogModalDialogModalFooter-react"] .modal-ok')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]')
.addFile('test.sol', { content: 'test' })
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtest.sol"]')
.click('*[data-id="workspaceCreate"]') // create workspace_name_1
.waitForElementVisible('*[data-id="modalDialogCustomPromptText"]')
.clearValue('*[data-id="modalDialogCustomPromptText"]')
.setValue('*[data-id="modalDialogCustomPromptText"]', 'workspace_name_1')
.modalFooterOKClick()
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
// eslint-disable-next-line dot-notation
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_name_1' })
.click('*[data-id="workspacesModalDialogModalDialogModalFooter-react"] .modal-ok')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]')
.waitForElementNotPresent('*[data-id="treeViewLitreeViewItemtest.sol"]')
.click('*[data-id="workspacesSelect"] option[value="workspace_name"]')
......
......@@ -41,7 +41,7 @@ declare module "nightwatch" {
getInstalledPlugins(cb: (plugins: string[]) => void): NightwatchBrowser,
verifyCallReturnValue(address: string, checks: string[]): NightwatchBrowser,
testEditorValue(testvalue: string): NightwatchBrowser,
removeFile(path: string): NightwatchBrowser,
removeFile(path: string, workspace: string): NightwatchBrowser,
switchBrowserWindow(url: string, windowName: string, cb: (browser: NightwatchBrowser, window?: NightwatchCallbackResult<Window>) => void): NightwatchBrowser,
setupMetamask(passphrase: string, password: string): NightwatchBrowser,
signMessage(msg: string, callback: (hash: { value: string }, signature: { value: string }) => void): NightwatchBrowser,
......
......@@ -444,7 +444,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
await appManager.activatePlugin(['contentImport', 'theme', 'editor', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'web3Provider', 'offsetToLineColumnConverter'])
await appManager.activatePlugin(['mainPanel', 'menuicons'])
await appManager.activatePlugin(['sidePanel']) // activating host plugin separately
await appManager.activatePlugin(['home', 'hiddenPanel', 'pluginManager', 'fileExplorers', 'settings', 'contextualListener', 'terminal', 'fetchAndCompile'])
await appManager.activatePlugin(['home'])
await appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'fileExplorers', 'settings', 'contextualListener', 'terminal', 'fetchAndCompile'])
const queryParams = new QueryParams()
const params = queryParams.get()
......@@ -486,6 +487,5 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
migrateToWorkspace(fileManager)
filePanel.initWorkspace()
if (params.embed) framingService.embed()
}
......@@ -49,6 +49,10 @@ class FileManager extends Plugin {
this.init()
}
getOpenedFiles () {
return this.openedFiles
}
setMode (mode) {
this.mode = mode
}
......@@ -589,6 +593,12 @@ class FileManager extends Plugin {
if (!this.exists(workspaceRootPath)) await this.mkdir(workspaceRootPath)
if (!this.exists(workspacePath)) await this.mkdir(workspacePath)
}
async workspaceExists (name) {
const workspaceProvider = this._deps.filesProviders.workspace
const workspacePath = 'browser/' + workspaceProvider.workspacesPath + '/' + name
return this.exists(workspacePath)
}
}
module.exports = FileManager
......@@ -54,6 +54,11 @@ module.exports = class RemixDProvider {
close (cb) {
this._isReady = false
cb()
this.event.trigger('disconnected')
}
preInit () {
this._registerEvent()
}
init (cb) {
......@@ -63,6 +68,7 @@ module.exports = class RemixDProvider {
this._isReady = true
this._readOnlyMode = result
this._registerEvent()
this.event.trigger('connected')
cb && cb()
}).catch((error) => {
cb && cb(error)
......
......@@ -30,15 +30,13 @@ const profile = {
}
export class RemixdHandle extends WebsocketPlugin {
constructor (fileSystemExplorer, locahostProvider, appManager) {
constructor (locahostProvider, appManager) {
super(profile)
this.fileSystemExplorer = fileSystemExplorer
this.locahostProvider = locahostProvider
this.appManager = appManager
}
deactivate () {
this.fileSystemExplorer.hide()
if (super.socket) super.deactivate()
this.call('manager', 'deactivatePlugin', 'git')
this.locahostProvider.close((error) => {
......@@ -82,9 +80,7 @@ export class RemixdHandle extends WebsocketPlugin {
this.canceled()
}
}, 3000)
this.locahostProvider.init(() => {
this.fileSystemExplorer.show()
})
this.locahostProvider.init(() => {})
this.call('manager', 'activatePlugin', 'git')
}
}
......
This diff is collapsed.
var csjs = require('csjs-inject')
var css = csjs`
.container {
display : flex;
flex-direction : row;
width : 100%;
height : 100%;
box-sizing : border-box;
}
.fileexplorer {
display : flex;
flex-direction : column;
position : relative;
width : 100%;
padding-left : 6px;
padding-top : 6px;
}
.fileExplorerTree {
cursor : default;
}
.gist {
padding : 10px;
}
.gist i {
cursor : pointer;
}
.gist i:hover {
color : orange;
}
.connectToLocalhost {
padding : 10px;
}
.connectToLocalhost i {
cursor : pointer;
}
.connectToLocalhost i:hover {
color : var(--secondary)
}
.uploadFile {
padding : 10px;
}
.uploadFile label:hover {
color : var(--secondary)
}
.uploadFile label {
cursor : pointer;
}
.treeview {
overflow-y : auto;
}
.dialog {
display: flex;
flex-direction: column;
}
.dialogParagraph {
margin-bottom: 2em;
word-break: break-word;
}
`
module.exports = css
......@@ -40,6 +40,13 @@ export const ModalDialog = (props: ModalDialogProps) => {
handleHide()
}
const handleBlur = (e) => {
if (!e.currentTarget.contains(e.relatedTarget)) {
e.stopPropagation()
handleHide()
}
}
return (
<div
data-id={`${props.id}ModalDialogContainer-react`}
......@@ -51,10 +58,7 @@ export const ModalDialog = (props: ModalDialogProps) => {
>
<div className="modal-dialog" role="document">
<div
onBlur={(e) => {
e.stopPropagation()
handleHide()
}}
onBlur={handleBlur}
ref={modal}
tabIndex={-1}
className={'modal-content remixModalContent ' + (props.modalClass ? props.modalClass : '')}
......
{
"presets": ["@nrwl/react/babel"],
"plugins": []
}
{
"env": {
"browser": true,
"es6": true
},
"extends": "../../../.eslintrc",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 11,
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error"
}
}
# remix-ui-workspace
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test remix-ui-workspace` to execute the unit tests via [Jest](https://jestjs.io).
export * from './lib/remix-ui-workspace';
.remixui_container {
display : flex;
flex-direction : row;
width : 100%;
height : 100%;
box-sizing : border-box;
}
.remixui_fileexplorer {
display : flex;
flex-direction : column;
position : relative;
width : 100%;
padding-left : 6px;
padding-top : 6px;
}
.remixui_fileExplorerTree {
cursor : default;
}
.remixui_gist {
padding : 10px;
}
.remixui_gist i {
cursor : pointer;
}
.remixui_gist i:hover {
color : orange;
}
.remixui_connectToLocalhost {
padding : 10px;
}
.remixui_connectToLocalhost i {
cursor : pointer;
}
.remixui_connectToLocalhost i:hover {
color : var(--secondary)
}
.remixui_uploadFile {
padding : 10px;
}
.remixui_uploadFile label:hover {
color : var(--secondary)
}
.remixui_uploadFile label {
cursor : pointer;
}
.remixui_treeview {
overflow-y : auto;
}
.remixui_dialog {
display: flex;
flex-direction: column;
}
.remixui_dialogParagraph {
margin-bottom: 2em;
word-break: break-word;
}
.remixui_menuicon {
padding-right : 10px;
}
display : flex;
flex-direction : row;
width : 100%;
height : 100%;
box-sizing : border-box;
}
.remixui_fileexplorer {
display : flex;
flex-direction : column;
position : relative;
width : 100%;
padding-left : 6px;
padding-top : 6px;
}
.remixui_fileExplorerTree {
cursor : default;
}
.remixui_gist {
padding : 10px;
}
.remixui_gist i {
cursor : pointer;
}
.remixui_gist i:hover {
color : orange;
}
.remixui_connectToLocalhost {
padding : 10px;
}
.remixui_connectToLocalhost i {
cursor : pointer;
}
.remixui_connectToLocalhost i:hover {
color : var(--secondary)
}
.remixui_uploadFile {
padding : 10px;
}
.remixui_uploadFile label:hover {
color : var(--secondary)
}
.remixui_uploadFile label {
cursor : pointer;
}
.remixui_treeview {
overflow-y : auto;
}
.remixui_dialog {
display: flex;
flex-direction: column;
}
.remixui_dialogParagraph {
margin-bottom: 2em;
word-break: break-word;
}
.remixui_menuicon {
padding-right : 10px;
}
\ No newline at end of file
This diff is collapsed.
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}
......@@ -92,6 +92,9 @@
},
"debugger": {
"tags": []
},
"remix-ui-workspace": {
"tags": []
}
}
}
......@@ -20,7 +20,9 @@
"@remix-project/remix-astwalker": ["dist/libs/remix-astwalker/index.js"],
"@remix-project/remix-debug": ["dist/libs/remix-debug/src/index.js"],
"@remix-project/remix-lib": ["dist/libs/remix-lib/src/index.js"],
"@remix-project/remix-simulator": ["dist/libs/remix-simulator/src/index.js"],
"@remix-project/remix-simulator": [
"dist/libs/remix-simulator/src/index.js"
],
"@remix-project/remix-solidity": ["dist/libs/remix-solidity/index.js"],
"@remix-project/remix-tests": ["dist/libs/remix-tests/src/index.js"],
"@remix-project/remix-url-resolver": [
......@@ -35,7 +37,8 @@
"@remix-project/remix-solidity-ts": ["libs/remix-solidity/src/index.ts"],
"@remix-ui/modal-dialog": ["libs/remix-ui/modal-dialog/src/index.ts"],
"@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"],
"@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"]
"@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"],
"@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"]
}
},
"exclude": ["node_modules", "tmp"]
......
......@@ -347,7 +347,11 @@
"linter": "eslint",
"config": "libs/remix-tests/.eslintrc",
"tsConfig": ["libs/remix-tests/tsconfig.lib.json"],
"exclude": ["**/node_modules/**", "libs/remix-tests/tests/**/*", "**/dist/**"]
"exclude": [
"**/node_modules/**",
"libs/remix-tests/tests/**/*",
"**/dist/**"
]
}
},
"test": {
......@@ -705,6 +709,22 @@
}
}
}
},
"remix-ui-workspace": {
"root": "libs/remix-ui/workspace",
"sourceRoot": "libs/remix-ui/workspace/src",
"projectType": "library",
"schematics": {},
"architect": {
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": ["libs/remix-ui/workspace/tsconfig.lib.json"],
"exclude": ["**/node_modules/**", "!libs/remix-ui/workspace/**/*"]
}
}
}
}
},
"cli": {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment