Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
d56bf6d4
Unverified
Commit
d56bf6d4
authored
Mar 04, 2021
by
yann300
Committed by
GitHub
Mar 04, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #933 from ethereum/throwIfNoWorkspace
Throw if no workspace
parents
ea0be92c
aaeea9d1
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
140 additions
and
42 deletions
+140
-42
gist.test.ts
apps/remix-ide-e2e/src/tests/gist.test.ts
+1
-1
solidityImport.test.ts
apps/remix-ide-e2e/src/tests/solidityImport.test.ts
+1
-0
solidityUnittests.test.ts
apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts
+2
-0
workspace.test.ts
apps/remix-ide-e2e/src/tests/workspace.test.ts
+23
-0
fileManager.js
apps/remix-ide/src/app/files/fileManager.js
+12
-2
workspaceFileProvider.js
apps/remix-ide/src/app/files/workspaceFileProvider.js
+12
-0
file-panel.js
apps/remix-ide/src/app/panels/file-panel.js
+15
-2
test-tab-styles.js
apps/remix-ide/src/app/tabs/styles/test-tab-styles.js
+3
-0
test-tab.js
apps/remix-ide/src/app/tabs/test-tab.js
+14
-3
testTab.js
apps/remix-ide/src/app/tabs/testTab/testTab.js
+5
-2
landing-page.js
apps/remix-ide/src/app/ui/landing-page/landing-page.js
+9
-4
modal-dialog-custom.js
apps/remix-ide/src/app/ui/modal-dialog-custom.js
+1
-1
gist-handler.js
apps/remix-ide/src/lib/gist-handler.js
+4
-2
helper.js
apps/remix-ide/src/lib/helper.js
+3
-0
migrateFileSystem.js
apps/remix-ide/src/migrateFileSystem.js
+8
-5
file-explorer-menu.tsx
libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx
+2
-2
remix-ui-workspace.tsx
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
+25
-18
No files found.
apps/remix-ide-e2e/src/tests/gist.test.ts
View file @
d56bf6d4
...
@@ -84,7 +84,7 @@ module.exports = {
...
@@ -84,7 +84,7 @@ module.exports = {
.
setValue
(
'*[data-id="modalDialogCustomPromptText"]'
,
testData
.
invalidGistId
)
.
setValue
(
'*[data-id="modalDialogCustomPromptText"]'
,
testData
.
invalidGistId
)
.
modalFooterOKClick
()
.
modalFooterOKClick
()
.
waitForElementVisible
(
'*[data-id="modalDialogModalBody"]'
)
.
waitForElementVisible
(
'*[data-id="modalDialogModalBody"]'
)
.
assert
.
containsText
(
'*[data-id="modalDialogModalBody"]'
,
'
Gist load error:
Not Found'
)
.
assert
.
containsText
(
'*[data-id="modalDialogModalBody"]'
,
'Not Found'
)
.
modalFooterOKClick
()
.
modalFooterOKClick
()
},
},
...
...
apps/remix-ide-e2e/src/tests/solidityImport.test.ts
View file @
d56bf6d4
...
@@ -21,6 +21,7 @@ module.exports = {
...
@@ -21,6 +21,7 @@ module.exports = {
.
addFile
(
'Untitled2.sol'
,
sources
[
1
][
'Untitled2.sol'
])
.
addFile
(
'Untitled2.sol'
,
sources
[
1
][
'Untitled2.sol'
])
.
openFile
(
'Untitled1.sol'
)
.
openFile
(
'Untitled1.sol'
)
.
verifyContracts
([
'test6'
,
'test4'
,
'test5'
])
.
verifyContracts
([
'test6'
,
'test4'
,
'test5'
])
.
pause
(
1000
)
},
},
'Test Failed Import'
:
function
(
browser
:
NightwatchBrowser
)
{
'Test Failed Import'
:
function
(
browser
:
NightwatchBrowser
)
{
...
...
apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts
View file @
d56bf6d4
...
@@ -149,12 +149,14 @@ module.exports = {
...
@@ -149,12 +149,14 @@ module.exports = {
.
addFile
(
'myTests/simple_storage_test.sol'
,
sources
[
0
][
'tests/simple_storage_test.sol'
])
.
addFile
(
'myTests/simple_storage_test.sol'
,
sources
[
0
][
'tests/simple_storage_test.sol'
])
.
clickLaunchIcon
(
'solidityUnitTesting'
)
.
clickLaunchIcon
(
'solidityUnitTesting'
)
.
setValue
(
'*[data-id="uiPathInput"]'
,
'myTests'
)
.
setValue
(
'*[data-id="uiPathInput"]'
,
'myTests'
)
.
click
(
'*[data-id="testTabGenerateTestFolder"]'
)
.
clickElementAtPosition
(
'.singleTestLabel'
,
0
)
.
clickElementAtPosition
(
'.singleTestLabel'
,
0
)
.
scrollAndClick
(
'*[data-id="testTabRunTestsTabRunAction"]'
)
.
scrollAndClick
(
'*[data-id="testTabRunTestsTabRunAction"]'
)
.
waitForElementPresent
(
'*[data-id="testTabSolidityUnitTestsOutputheader"]'
,
40000
)
.
waitForElementPresent
(
'*[data-id="testTabSolidityUnitTestsOutputheader"]'
,
40000
)
.
waitForElementPresent
(
'*[data-id="testTabSolidityUnitTestsOutput"]'
)
.
waitForElementPresent
(
'*[data-id="testTabSolidityUnitTestsOutput"]'
)
.
clearValue
(
'*[data-id="uiPathInput"]'
)
.
clearValue
(
'*[data-id="uiPathInput"]'
)
.
setValue
(
'*[data-id="uiPathInput"]'
,
'tests'
)
.
setValue
(
'*[data-id="uiPathInput"]'
,
'tests'
)
.
click
(
'*[data-id="testTabGenerateTestFolder"]'
)
},
},
'Solidity Unittests'
:
function
(
browser
:
NightwatchBrowser
)
{
'Solidity Unittests'
:
function
(
browser
:
NightwatchBrowser
)
{
...
...
apps/remix-ide-e2e/src/tests/workspace.test.ts
View file @
d56bf6d4
...
@@ -50,6 +50,29 @@ module.exports = {
...
@@ -50,6 +50,29 @@ module.exports = {
.
waitForElementNotPresent
(
'*[data-id="treeViewLitreeViewItemtest.sol"]'
)
.
waitForElementNotPresent
(
'*[data-id="treeViewLitreeViewItemtest.sol"]'
)
.
click
(
'*[data-id="workspacesSelect"] option[value="workspace_name"]'
)
.
click
(
'*[data-id="workspacesSelect"] option[value="workspace_name"]'
)
.
waitForElementVisible
(
'*[data-id="treeViewLitreeViewItemtests"]'
)
.
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
()
.
end
()
},
},
...
...
apps/remix-ide/src/app/files/fileManager.js
View file @
d56bf6d4
...
@@ -514,6 +514,8 @@ class FileManager extends Plugin {
...
@@ -514,6 +514,8 @@ class FileManager extends Plugin {
if
(
file
.
startsWith
(
'browser'
))
{
if
(
file
.
startsWith
(
'browser'
))
{
return
this
.
_deps
.
filesProviders
.
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
return
this
.
_deps
.
filesProviders
.
workspace
}
}
...
@@ -579,7 +581,11 @@ class FileManager extends Plugin {
...
@@ -579,7 +581,11 @@ class FileManager extends Plugin {
async
.
each
(
Object
.
keys
(
filesSet
),
(
file
,
callback
)
=>
{
async
.
each
(
Object
.
keys
(
filesSet
),
(
file
,
callback
)
=>
{
if
(
override
)
{
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
)
self
.
syncEditor
(
fileProvider
+
file
)
return
callback
()
return
callback
()
}
}
...
@@ -591,7 +597,11 @@ class FileManager extends Plugin {
...
@@ -591,7 +597,11 @@ class FileManager extends Plugin {
}
else
if
(
helper
.
checkSpecialChars
(
name
))
{
}
else
if
(
helper
.
checkSpecialChars
(
name
))
{
modalDialogCustom
.
alert
(
'Special characters are not allowed'
)
modalDialogCustom
.
alert
(
'Special characters are not allowed'
)
}
else
{
}
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
)
self
.
syncEditor
(
fileProvider
+
name
)
}
}
callback
()
callback
()
...
...
apps/remix-ide/src/app/files/workspaceFileProvider.js
View file @
d56bf6d4
...
@@ -6,6 +6,7 @@ class WorkspaceFileProvider extends FileProvider {
...
@@ -6,6 +6,7 @@ class WorkspaceFileProvider extends FileProvider {
constructor
()
{
constructor
()
{
super
(
''
)
super
(
''
)
this
.
workspacesPath
=
'.workspaces'
this
.
workspacesPath
=
'.workspaces'
this
.
workspace
=
null
}
}
setWorkspace
(
workspace
)
{
setWorkspace
(
workspace
)
{
...
@@ -13,11 +14,20 @@ class WorkspaceFileProvider extends FileProvider {
...
@@ -13,11 +14,20 @@ class WorkspaceFileProvider extends FileProvider {
this
.
workspace
=
workspace
this
.
workspace
=
workspace
}
}
getWorkspace
()
{
return
this
.
workspace
}
isReady
()
{
return
this
.
workspace
!==
null
}
clearWorkspace
()
{
clearWorkspace
()
{
this
.
workspace
=
null
this
.
workspace
=
null
}
}
removePrefix
(
path
)
{
removePrefix
(
path
)
{
if
(
!
this
.
workspace
)
throw
new
Error
(
'No workspace has been opened.'
)
path
=
path
.
replace
(
/^
\/
|
\/
$/g
,
''
)
// remove first and last slash
path
=
path
.
replace
(
/^
\/
|
\/
$/g
,
''
)
// remove first and last slash
if
(
path
.
startsWith
(
this
.
workspacesPath
+
'/'
+
this
.
workspace
))
return
path
if
(
path
.
startsWith
(
this
.
workspacesPath
+
'/'
+
this
.
workspace
))
return
path
if
(
path
.
startsWith
(
this
.
workspace
))
return
this
.
workspacesPath
+
'/'
+
this
.
workspace
if
(
path
.
startsWith
(
this
.
workspace
))
return
this
.
workspacesPath
+
'/'
+
this
.
workspace
...
@@ -27,6 +37,7 @@ class WorkspaceFileProvider extends FileProvider {
...
@@ -27,6 +37,7 @@ class WorkspaceFileProvider extends FileProvider {
}
}
resolveDirectory
(
path
,
callback
)
{
resolveDirectory
(
path
,
callback
)
{
if
(
!
this
.
workspace
)
throw
new
Error
(
'No workspace has been opened.'
)
super
.
resolveDirectory
(
path
,
(
error
,
files
)
=>
{
super
.
resolveDirectory
(
path
,
(
error
,
files
)
=>
{
if
(
error
)
return
callback
(
error
)
if
(
error
)
return
callback
(
error
)
const
unscoped
=
{}
const
unscoped
=
{}
...
@@ -38,6 +49,7 @@ class WorkspaceFileProvider extends FileProvider {
...
@@ -38,6 +49,7 @@ class WorkspaceFileProvider extends FileProvider {
}
}
_normalizePath
(
path
)
{
_normalizePath
(
path
)
{
if
(
!
this
.
workspace
)
throw
new
Error
(
'No workspace has been opened.'
)
return
path
.
replace
(
this
.
workspacesPath
+
'/'
+
this
.
workspace
+
'/'
,
''
)
return
path
.
replace
(
this
.
workspacesPath
+
'/'
+
this
.
workspace
+
'/'
,
''
)
}
}
}
}
...
...
apps/remix-ide/src/app/panels/file-panel.js
View file @
d56bf6d4
...
@@ -5,6 +5,7 @@ import React from 'react' // eslint-disable-line
...
@@ -5,6 +5,7 @@ import React from 'react' // eslint-disable-line
import
ReactDOM
from
'react-dom'
import
ReactDOM
from
'react-dom'
import
{
Workspace
}
from
'@remix-ui/workspace'
// eslint-disable-line
import
{
Workspace
}
from
'@remix-ui/workspace'
// eslint-disable-line
import
*
as
ethutil
from
'ethereumjs-util'
import
*
as
ethutil
from
'ethereumjs-util'
import
{
checkSpecialChars
,
checkSlash
}
from
'../../lib/helper'
var
EventManager
=
require
(
'../../lib/events'
)
var
EventManager
=
require
(
'../../lib/events'
)
var
{
RemixdHandle
}
=
require
(
'../files/remixd-handle.js'
)
var
{
RemixdHandle
}
=
require
(
'../files/remixd-handle.js'
)
var
{
GitHandle
}
=
require
(
'../files/git-handle.js'
)
var
{
GitHandle
}
=
require
(
'../files/git-handle.js'
)
...
@@ -74,6 +75,7 @@ module.exports = class Filepanel extends ViewPlugin {
...
@@ -74,6 +75,7 @@ module.exports = class Filepanel extends ViewPlugin {
ReactDOM
.
render
(
ReactDOM
.
render
(
<
Workspace
<
Workspace
createWorkspace
=
{
this
.
createWorkspace
.
bind
(
this
)}
createWorkspace
=
{
this
.
createWorkspace
.
bind
(
this
)}
renameWorkspace
=
{
this
.
renameWorkspace
.
bind
(
this
)}
setWorkspace
=
{
this
.
setWorkspace
.
bind
(
this
)}
setWorkspace
=
{
this
.
setWorkspace
.
bind
(
this
)}
workspaceRenamed
=
{
this
.
workspaceRenamed
.
bind
(
this
)}
workspaceRenamed
=
{
this
.
workspaceRenamed
.
bind
(
this
)}
workspaceDeleted
=
{
this
.
workspaceDeleted
.
bind
(
this
)}
workspaceDeleted
=
{
this
.
workspaceDeleted
.
bind
(
this
)}
...
@@ -165,8 +167,8 @@ module.exports = class Filepanel extends ViewPlugin {
...
@@ -165,8 +167,8 @@ module.exports = class Filepanel extends ViewPlugin {
return
await
this
.
request
.
createNewFile
()
return
await
this
.
request
.
createNewFile
()
}
}
async
uploadFile
()
{
async
uploadFile
(
event
)
{
return
await
this
.
request
.
uploadFile
()
return
await
this
.
request
.
uploadFile
(
event
)
}
}
async
processCreateWorkspace
(
name
)
{
async
processCreateWorkspace
(
name
)
{
...
@@ -186,6 +188,8 @@ module.exports = class Filepanel extends ViewPlugin {
...
@@ -186,6 +188,8 @@ module.exports = class Filepanel extends ViewPlugin {
}
}
async
createWorkspace
(
workspaceName
)
{
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'
)
if
(
await
this
.
workspaceExists
(
workspaceName
))
throw
new
Error
(
'workspace already exists'
)
const
browserProvider
=
this
.
_deps
.
fileProviders
.
browser
const
browserProvider
=
this
.
_deps
.
fileProviders
.
browser
const
workspacesPath
=
this
.
_deps
.
fileProviders
.
workspace
.
workspacesPath
const
workspacesPath
=
this
.
_deps
.
fileProviders
.
workspace
.
workspacesPath
...
@@ -199,6 +203,15 @@ module.exports = class Filepanel extends ViewPlugin {
...
@@ -199,6 +203,15 @@ module.exports = class Filepanel extends ViewPlugin {
}
}
}
}
async
renameWorkspace
(
oldName
,
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
browserProvider
.
rename
(
'browser/'
+
workspacesPath
+
'/'
+
oldName
,
'browser/'
+
workspacesPath
+
'/'
+
workspaceName
,
true
)
}
/** these are called by the react component, action is already finished whent it's called */
/** these are called by the react component, action is already finished whent it's called */
async
setWorkspace
(
workspace
)
{
async
setWorkspace
(
workspace
)
{
this
.
_deps
.
fileManager
.
removeTabsOf
(
this
.
_deps
.
fileProviders
.
workspace
)
this
.
_deps
.
fileManager
.
removeTabsOf
(
this
.
_deps
.
fileProviders
.
workspace
)
...
...
apps/remix-ide/src/app/tabs/styles/test-tab-styles.js
View file @
d56bf6d4
...
@@ -48,5 +48,8 @@ var css = csjs`
...
@@ -48,5 +48,8 @@ var css = csjs`
.labelOnBtn {
.labelOnBtn {
border: hidden;
border: hidden;
}
}
.inputFolder {
width: 80%;
}
`
`
module
.
exports
=
css
module
.
exports
=
css
apps/remix-ide/src/app/tabs/test-tab.js
View file @
d56bf6d4
...
@@ -573,7 +573,7 @@ module.exports = class TestTab extends ViewPlugin {
...
@@ -573,7 +573,7 @@ module.exports = class TestTab extends ViewPlugin {
this
.
inputPath
=
yo
`<input
this
.
inputPath
=
yo
`<input
placeholder=
${
this
.
defaultPath
}
placeholder=
${
this
.
defaultPath
}
list="utPathList"
list="utPathList"
class="custom-select"
class="
${
css
.
inputFolder
}
custom-select"
id="utPath"
id="utPath"
data-id="uiPathInput"
data-id="uiPathInput"
name="utPath"
name="utPath"
...
@@ -581,10 +581,21 @@ module.exports = class TestTab extends ViewPlugin {
...
@@ -581,10 +581,21 @@ module.exports = class TestTab extends ViewPlugin {
onkeydown=
${(
e
)
=>
{
if
(
e
.
keyCode
===
191
)
this
.
updateDirList
()
}}
onkeydown=
${(
e
)
=>
{
if
(
e
.
keyCode
===
191
)
this
.
updateDirList
()
}}
onchange
=
$
{(
e
)
=>
this
.
updateCurrentPath
(
e
)}
/>`
onchange
=
$
{(
e
)
=>
this
.
updateCurrentPath
(
e
)}
/>`
const
createTestFolder
=
yo
`<button
class="btn border ml-2"
data-id="testTabGenerateTestFolder"
title="Create a test folder"
onclick=
${(
e
)
=>
{
this
.
testTabLogic
.
generateTestFolder
(
this
.
inputPath
.
value
)
}}
>
Create
<
/button>
`
const
availablePaths
=
yo
`
const
availablePaths
=
yo
`
<div>
<div>
${
this
.
inputPath
}
<div class="d-flex p-2">
${
this
.
uiPathList
}
${
this
.
inputPath
}
${
createTestFolder
}
${
this
.
uiPathList
}
</div>
</div>
</div>
`
`
this
.
updateDirList
()
this
.
updateDirList
()
...
...
apps/remix-ide/src/app/tabs/testTab/testTab.js
View file @
d56bf6d4
...
@@ -11,6 +11,9 @@ class TestTabLogic {
...
@@ -11,6 +11,9 @@ class TestTabLogic {
setCurrentPath
(
path
)
{
setCurrentPath
(
path
)
{
if
(
path
.
indexOf
(
'/'
)
===
0
)
return
if
(
path
.
indexOf
(
'/'
)
===
0
)
return
this
.
currentPath
=
path
this
.
currentPath
=
path
}
generateTestFolder
(
path
)
{
const
fileProvider
=
this
.
fileManager
.
fileProviderOf
(
path
.
split
(
'/'
)[
0
])
const
fileProvider
=
this
.
fileManager
.
fileProviderOf
(
path
.
split
(
'/'
)[
0
])
fileProvider
.
exists
(
path
,
(
e
,
res
)
=>
{
if
(
!
res
)
fileProvider
.
createDir
(
path
)
})
fileProvider
.
exists
(
path
,
(
e
,
res
)
=>
{
if
(
!
res
)
fileProvider
.
createDir
(
path
)
})
}
}
...
@@ -44,9 +47,9 @@ class TestTabLogic {
...
@@ -44,9 +47,9 @@ class TestTabLogic {
const
provider
=
this
.
fileManager
.
fileProviderOf
(
this
.
currentPath
)
const
provider
=
this
.
fileManager
.
fileProviderOf
(
this
.
currentPath
)
if
(
!
provider
)
return
cb
(
null
,
[])
if
(
!
provider
)
return
cb
(
null
,
[])
const
tests
=
[]
const
tests
=
[]
let
files
let
files
=
[]
try
{
try
{
files
=
await
this
.
fileManager
.
readdir
(
this
.
currentPath
)
if
(
await
this
.
fileManager
.
exists
(
this
.
currentPath
))
files
=
await
this
.
fileManager
.
readdir
(
this
.
currentPath
)
}
catch
(
e
)
{
}
catch
(
e
)
{
cb
(
e
.
message
)
cb
(
e
.
message
)
}
}
...
...
apps/remix-ide/src/app/ui/landing-page/landing-page.js
View file @
d56bf6d4
...
@@ -240,17 +240,22 @@ export class LandingPage extends ViewPlugin {
...
@@ -240,17 +240,22 @@ export class LandingPage extends ViewPlugin {
<div>e.g
${
examples
.
map
((
url
)
=>
{
return
yo
`<div class="p-1"><a>
${
url
}
</a></div>`
})}
</div>
<div>e.g
${
examples
.
map
((
url
)
=>
{
return
yo
`<div class="p-1"><a>
${
url
}
</a></div>`
})}
</div>
</div>`
</div>`
modalDialogCustom
.
prompt
(
`Import from
${
service
}
`
,
msg
,
null
,
(
target
)
=>
{
const
title
=
`Import from
${
service
}
`
modalDialogCustom
.
prompt
(
title
,
msg
,
null
,
(
target
)
=>
{
if
(
target
!==
''
)
{
if
(
target
!==
''
)
{
compilerImport
.
import
(
compilerImport
.
import
(
target
,
target
,
(
loadingMsg
)
=>
{
tooltip
(
loadingMsg
)
},
(
loadingMsg
)
=>
{
tooltip
(
loadingMsg
)
},
(
error
,
content
,
cleanUrl
,
type
,
url
)
=>
{
(
error
,
content
,
cleanUrl
,
type
,
url
)
=>
{
if
(
error
)
{
if
(
error
)
{
modalDialogCustom
.
alert
(
error
)
modalDialogCustom
.
alert
(
title
,
error
.
message
||
error
)
}
else
{
}
else
{
fileProviders
.
browser
.
addExternal
(
type
+
'/'
+
cleanUrl
,
content
,
url
)
try
{
this
.
verticalIcons
.
select
(
'fileExplorers'
)
fileProviders
.
workspace
.
addExternal
(
type
+
'/'
+
cleanUrl
,
content
,
url
)
this
.
verticalIcons
.
select
(
'fileExplorers'
)
}
catch
(
e
)
{
modalDialogCustom
.
alert
(
title
,
e
.
message
)
}
}
}
}
}
)
)
...
...
apps/remix-ide/src/app/ui/modal-dialog-custom.js
View file @
d56bf6d4
...
@@ -5,7 +5,7 @@ var css = require('./styles/modal-dialog-custom-styles')
...
@@ -5,7 +5,7 @@ var css = require('./styles/modal-dialog-custom-styles')
module
.
exports
=
{
module
.
exports
=
{
alert
:
function
(
title
,
text
)
{
alert
:
function
(
title
,
text
)
{
if
(
text
)
return
modal
(
title
,
yo
`<div>
${
text
}
</div>`
,
null
,
{
label
:
null
})
if
(
text
)
return
modal
(
title
,
yo
`<div>
${
text
}
</div>`
,
null
,
{
label
:
null
})
return
modal
(
''
,
yo
`<div>
${
title
}
</div>`
,
null
,
{
label
:
null
})
return
modal
(
'
Alert
'
,
yo
`<div>
${
title
}
</div>`
,
null
,
{
label
:
null
})
},
},
prompt
:
function
(
title
,
text
,
inputValue
,
ok
,
cancel
,
focus
)
{
prompt
:
function
(
title
,
text
,
inputValue
,
ok
,
cancel
,
focus
)
{
return
prompt
(
title
,
text
,
false
,
inputValue
,
ok
,
cancel
,
focus
)
return
prompt
(
title
,
text
,
false
,
inputValue
,
ok
,
cancel
,
focus
)
...
...
apps/remix-ide/src/lib/gist-handler.js
View file @
d56bf6d4
...
@@ -20,7 +20,7 @@ function GistHandler (_window) {
...
@@ -20,7 +20,7 @@ function GistHandler (_window) {
if
(
gistId
)
{
if
(
gistId
)
{
cb
(
gistId
)
cb
(
gistId
)
}
else
{
}
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) {
...
@@ -49,7 +49,7 @@ function GistHandler (_window) {
json
:
true
json
:
true
},
async
(
error
,
response
,
data
=
{})
=>
{
},
async
(
error
,
response
,
data
=
{})
=>
{
if
(
error
||
!
data
.
files
)
{
if
(
error
||
!
data
.
files
)
{
modalDialogCustom
.
alert
(
`Gist load error:
${
error
||
data
.
message
}
`
)
modalDialogCustom
.
alert
(
'Gist load error'
,
error
||
data
.
message
)
return
return
}
}
const
obj
=
{}
const
obj
=
{}
...
@@ -60,6 +60,8 @@ function GistHandler (_window) {
...
@@ -60,6 +60,8 @@ function GistHandler (_window) {
if
(
!
errorLoadingFile
)
{
if
(
!
errorLoadingFile
)
{
const
provider
=
fileManager
.
getProvider
(
'workspace'
)
const
provider
=
fileManager
.
getProvider
(
'workspace'
)
provider
.
lastLoadedGistId
=
gistId
provider
.
lastLoadedGistId
=
gistId
}
else
{
modalDialogCustom
.
alert
(
'Gist load error'
,
errorLoadingFile
.
message
||
errorLoadingFile
)
}
}
})
})
})
})
...
...
apps/remix-ide/src/lib/helper.js
View file @
d56bf6d4
...
@@ -55,6 +55,9 @@ module.exports = {
...
@@ -55,6 +55,9 @@ module.exports = {
checkSpecialChars
(
name
)
{
checkSpecialChars
(
name
)
{
return
name
.
match
(
/
[
:*?"<>
\\
'|
]
/
)
!=
null
return
name
.
match
(
/
[
:*?"<>
\\
'|
]
/
)
!=
null
},
},
checkSlash
(
name
)
{
return
name
.
match
(
/
\/
/
)
!=
null
},
isHexadecimal
(
value
)
{
isHexadecimal
(
value
)
{
return
/^
[
0-9a-fA-F
]
+$/
.
test
(
value
)
&&
(
value
.
length
%
2
===
0
)
return
/^
[
0-9a-fA-F
]
+$/
.
test
(
value
)
&&
(
value
.
length
%
2
===
0
)
},
},
...
...
apps/remix-ide/src/migrateFileSystem.js
View file @
d56bf6d4
...
@@ -29,17 +29,20 @@ export async function migrateToWorkspace (fileManager, filePanel) {
...
@@ -29,17 +29,20 @@ export async function migrateToWorkspace (fileManager, filePanel) {
if
(
fileStorageBrowserWorkspace
.
get
(
flag
)
===
'done'
)
return
if
(
fileStorageBrowserWorkspace
.
get
(
flag
)
===
'done'
)
return
const
files
=
await
browserProvider
.
copyFolderToJson
(
'/'
)
const
files
=
await
browserProvider
.
copyFolderToJson
(
'/'
)
console
.
log
(
files
)
console
.
log
(
files
)
const
workspaceName
=
'default_workspace'
if
(
Object
.
keys
(
files
).
length
>
0
)
{
const
workspacePath
=
joinPath
(
'browser'
,
workspaceProvider
.
workspacesPath
,
workspaceName
)
const
workspaceName
=
'default_workspace'
await
filePanel
.
createWorkspace
(
workspaceName
)
const
workspacePath
=
joinPath
(
'browser'
,
workspaceProvider
.
workspacesPath
,
workspaceName
)
filePanel
.
getWorkspaces
()
// refresh list
await
filePanel
.
processCreateWorkspace
(
workspaceName
)
await
populateWorkspace
(
workspacePath
,
files
,
browserProvider
)
filePanel
.
getWorkspaces
()
// refresh list
await
populateWorkspace
(
workspacePath
,
files
,
browserProvider
)
}
fileStorageBrowserWorkspace
.
set
(
flag
,
'done'
)
fileStorageBrowserWorkspace
.
set
(
flag
,
'done'
)
}
}
const
populateWorkspace
=
async
(
workspace
,
json
,
browserProvider
)
=>
{
const
populateWorkspace
=
async
(
workspace
,
json
,
browserProvider
)
=>
{
for
(
const
item
in
json
)
{
for
(
const
item
in
json
)
{
const
isFolder
=
json
[
item
].
content
===
undefined
const
isFolder
=
json
[
item
].
content
===
undefined
if
(
isFolder
&&
item
===
'/.workspaces'
)
continue
// we don't want to replicate this one.
if
(
isFolder
)
{
if
(
isFolder
)
{
browserProvider
.
createDir
(
joinPath
(
workspace
,
item
))
browserProvider
.
createDir
(
joinPath
(
workspace
,
item
))
await
populateWorkspace
(
workspace
,
json
[
item
].
children
,
browserProvider
)
await
populateWorkspace
(
workspace
,
json
[
item
].
children
,
browserProvider
)
...
...
libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx
View file @
d56bf6d4
...
@@ -16,12 +16,12 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => {
...
@@ -16,12 +16,12 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => {
},
},
{
{
action
:
'publishToGist'
,
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'
icon
:
'fab fa-github'
},
},
{
{
action
:
'uploadFile'
,
action
:
'uploadFile'
,
title
:
'Load a local file into
Remix
\'
s browser folder
'
,
title
:
'Load a local file into
current workspace
'
,
icon
:
'fa fa-upload'
icon
:
'fa fa-upload'
},
},
{
{
...
...
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
View file @
d56bf6d4
...
@@ -7,6 +7,7 @@ import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
...
@@ -7,6 +7,7 @@ import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
export
interface
WorkspaceProps
{
export
interface
WorkspaceProps
{
setWorkspace
:
({
name
:
string
,
isLocalhost
:
boolean
})
=>
void
,
setWorkspace
:
({
name
:
string
,
isLocalhost
:
boolean
})
=>
void
,
createWorkspace
:
(
name
:
string
)
=>
void
,
createWorkspace
:
(
name
:
string
)
=>
void
,
renameWorkspace
:
(
oldName
:
string
,
newName
:
string
)
=>
void
workspaceRenamed
:
({
name
:
string
})
=>
void
,
workspaceRenamed
:
({
name
:
string
})
=>
void
,
workspaceCreated
:
({
name
:
string
})
=>
void
,
workspaceCreated
:
({
name
:
string
})
=>
void
,
workspaceDeleted
:
({
name
:
string
})
=>
void
,
workspaceDeleted
:
({
name
:
string
})
=>
void
,
...
@@ -28,9 +29,9 @@ export const Workspace = (props: WorkspaceProps) => {
...
@@ -28,9 +29,9 @@ export const Workspace = (props: WorkspaceProps) => {
const
NO_WORKSPACE
=
' - none - '
const
NO_WORKSPACE
=
' - none - '
/* extends the parent 'plugin' with some function needed by the file explorer */
/* extends the parent 'plugin' with some function needed by the file explorer */
props
.
plugin
.
resetFocus
=
()
=>
{
props
.
plugin
.
resetFocus
=
(
reset
)
=>
{
setState
(
prevState
=>
{
setState
(
prevState
=>
{
return
{
...
prevState
,
reset
:
true
}
return
{
...
prevState
,
reset
}
})
})
}
}
...
@@ -40,6 +41,8 @@ export const Workspace = (props: WorkspaceProps) => {
...
@@ -40,6 +41,8 @@ export const Workspace = (props: WorkspaceProps) => {
})
})
}
}
props
.
plugin
.
resetUploadFile
=
()
=>
{}
/* implement an external API, consumed by the parent */
/* implement an external API, consumed by the parent */
props
.
request
.
createWorkspace
=
()
=>
{
props
.
request
.
createWorkspace
=
()
=>
{
return
createWorkspace
()
return
createWorkspace
()
...
@@ -142,7 +145,7 @@ export const Workspace = (props: WorkspaceProps) => {
...
@@ -142,7 +145,7 @@ export const Workspace = (props: WorkspaceProps) => {
}
}
const
deleteCurrentWorkspace
=
()
=>
{
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'
,
label
:
'OK'
,
fn
:
onFinishDeleteWorkspace
fn
:
onFinishDeleteWorkspace
},
{
},
{
...
@@ -152,13 +155,12 @@ export const Workspace = (props: WorkspaceProps) => {
...
@@ -152,13 +155,12 @@ export const Workspace = (props: WorkspaceProps) => {
}
}
const
modalMessage
=
(
title
:
string
,
body
:
string
)
=>
{
const
modalMessage
=
(
title
:
string
,
body
:
string
)
=>
{
modal
(
title
,
body
,
{
setTimeout
(()
=>
{
// wait for any previous modal a chance to close
label
:
'OK'
,
modal
(
title
,
body
,
{
fn
:
()
=>
{}
label
:
'OK'
,
},
{
fn
:
()
=>
{}
label
:
null
,
},
null
)
fn
:
null
},
200
)
})
}
}
const
workspaceRenameInput
=
useRef
()
const
workspaceRenameInput
=
useRef
()
...
@@ -168,10 +170,15 @@ export const Workspace = (props: WorkspaceProps) => {
...
@@ -168,10 +170,15 @@ export const Workspace = (props: WorkspaceProps) => {
if
(
workspaceRenameInput
.
current
===
undefined
)
return
if
(
workspaceRenameInput
.
current
===
undefined
)
return
// @ts-ignore: Object is possibly 'null'.
// @ts-ignore: Object is possibly 'null'.
const
workspaceName
=
workspaceRenameInput
.
current
.
value
const
workspaceName
=
workspaceRenameInput
.
current
.
value
const
workspacesPath
=
props
.
workspace
.
workspacesPath
await
props
.
fileManager
.
rename
(
'browser/'
+
workspacesPath
+
'/'
+
state
.
currentWorkspace
,
'browser/'
+
workspacesPath
+
'/'
+
workspaceName
)
try
{
setWorkspace
(
workspaceName
)
await
props
.
renameWorkspace
(
state
.
currentWorkspace
,
workspaceName
)
props
.
workspaceRenamed
({
name
:
state
.
currentWorkspace
})
setWorkspace
(
workspaceName
)
props
.
workspaceRenamed
({
name
:
workspaceName
})
}
catch
(
e
)
{
modalMessage
(
'Rename Workspace'
,
e
.
message
)
console
.
error
(
e
)
}
}
}
const
onFinishCreateWorkspace
=
async
()
=>
{
const
onFinishCreateWorkspace
=
async
()
=>
{
...
@@ -181,11 +188,11 @@ export const Workspace = (props: WorkspaceProps) => {
...
@@ -181,11 +188,11 @@ export const Workspace = (props: WorkspaceProps) => {
try
{
try
{
await
props
.
createWorkspace
(
workspaceName
)
await
props
.
createWorkspace
(
workspaceName
)
await
setWorkspace
(
workspaceName
)
}
catch
(
e
)
{
}
catch
(
e
)
{
modalMessage
(
'
Workspace Creation
'
,
e
.
message
)
modalMessage
(
'
Create Workspace
'
,
e
.
message
)
console
.
error
(
e
)
console
.
error
(
e
)
}
}
await
setWorkspace
(
workspaceName
)
}
}
const
onFinishDeleteWorkspace
=
async
()
=>
{
const
onFinishDeleteWorkspace
=
async
()
=>
{
...
@@ -261,7 +268,7 @@ export const Workspace = (props: WorkspaceProps) => {
...
@@ -261,7 +268,7 @@ export const Workspace = (props: WorkspaceProps) => {
return
(
return
(
<>
<>
<
span
>
{
state
.
modal
.
message
}
</
span
>
<
span
>
{
state
.
modal
.
message
}
</
span
>
<
input
type=
"text"
data
-
id=
"modalDialogCustomPromptTextCreate"
placeholder
=
{
`workspace_${Date.now()}`
}
ref=
{
workspaceCreateInput
}
className=
"form-control"
/>
<
input
type=
"text"
data
-
id=
"modalDialogCustomPromptTextCreate"
defaultValue
=
{
`workspace_${Date.now()}`
}
ref=
{
workspaceCreateInput
}
className=
"form-control"
/>
</>
</>
)
)
}
}
...
@@ -270,7 +277,7 @@ export const Workspace = (props: WorkspaceProps) => {
...
@@ -270,7 +277,7 @@ export const Workspace = (props: WorkspaceProps) => {
return
(
return
(
<>
<>
<
span
>
{
state
.
modal
.
message
}
</
span
>
<
span
>
{
state
.
modal
.
message
}
</
span
>
<
input
type=
"text"
data
-
id=
"modalDialogCustomPromptTextRename"
placeholder
=
{
state
.
currentWorkspace
}
ref=
{
workspaceRenameInput
}
className=
"form-control"
/>
<
input
type=
"text"
data
-
id=
"modalDialogCustomPromptTextRename"
defaultValue
=
{
state
.
currentWorkspace
}
ref=
{
workspaceRenameInput
}
className=
"form-control"
/>
</>
</>
)
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment