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
65f2e759
Commit
65f2e759
authored
Jul 26, 2021
by
ioedeveloper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Manage workspaces from reducer
parent
d41396e1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
104 additions
and
197 deletions
+104
-197
file-panel.js
apps/remix-ide/src/app/panels/file-panel.js
+0
-71
workspace.ts
libs/remix-ui/workspace/src/lib/actions/workspace.ts
+59
-42
workspace.ts
libs/remix-ui/workspace/src/lib/reducers/workspace.ts
+12
-2
remix-ui-workspace.tsx
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
+33
-82
No files found.
apps/remix-ide/src/app/panels/file-panel.js
View file @
65f2e759
...
...
@@ -4,7 +4,6 @@ import * as packageJson from '../../../../../package.json'
import
React
from
'react'
// eslint-disable-line
import
ReactDOM
from
'react-dom'
import
{
Workspace
}
from
'@remix-ui/workspace'
// eslint-disable-line
import
{
bufferToHex
,
keccakFromString
}
from
'ethereumjs-util'
import
{
checkSpecialChars
,
checkSlash
}
from
'../../lib/helper'
const
{
RemixdHandle
}
=
require
(
'../files/remixd-handle.js'
)
const
{
GitHandle
}
=
require
(
'../files/git-handle.js'
)
...
...
@@ -12,8 +11,6 @@ const { HardhatHandle } = require('../files/hardhat-handle.js')
const
{
SlitherHandle
}
=
require
(
'../files/slither-handle.js'
)
const
globalRegistry
=
require
(
'../../global/registry'
)
const
examples
=
require
(
'../editor/examples'
)
const
GistHandler
=
require
(
'../../lib/gist-handler'
)
const
QueryParams
=
require
(
'../../lib/query-params'
)
const
modalDialogCustom
=
require
(
'../ui/modal-dialog-custom'
)
/*
Overview of APIs:
...
...
@@ -67,7 +64,6 @@ module.exports = class Filepanel extends ViewPlugin {
}
render
()
{
this
.
on
(
'editor'
,
'editorMounted'
,
()
=>
this
.
initWorkspace
().
then
(()
=>
this
.
getWorkspaces
()).
catch
(
console
.
error
))
return
this
.
el
}
...
...
@@ -149,73 +145,6 @@ module.exports = class Filepanel extends ViewPlugin {
return
this
.
workspaces
}
async
initWorkspace
()
{
this
.
renderComponent
()
const
queryParams
=
new
QueryParams
()
const
gistHandler
=
new
GistHandler
()
const
params
=
queryParams
.
get
()
// get the file from gist
let
loadedFromGist
=
false
if
(
params
.
gist
)
{
await
this
.
processCreateWorkspace
(
'gist-sample'
)
this
.
fileProviders
.
workspace
.
setWorkspace
(
'gist-sample'
)
this
.
initialWorkspace
=
'gist-sample'
loadedFromGist
=
gistHandler
.
loadFromGist
(
params
,
this
.
_deps
.
fileManager
)
}
if
(
loadedFromGist
)
return
if
(
params
.
code
||
params
.
url
)
{
try
{
await
this
.
processCreateWorkspace
(
'code-sample'
)
this
.
fileProviders
.
workspace
.
setWorkspace
(
'code-sample'
)
let
path
=
''
let
content
=
''
if
(
params
.
code
)
{
var
hash
=
bufferToHex
(
keccakFromString
(
params
.
code
))
path
=
'contract-'
+
hash
.
replace
(
'0x'
,
''
).
substring
(
0
,
10
)
+
'.sol'
content
=
atob
(
params
.
code
)
await
this
.
fileProviders
.
workspace
.
set
(
path
,
content
)
}
if
(
params
.
url
)
{
const
data
=
await
this
.
call
(
'contentImport'
,
'resolve'
,
params
.
url
)
path
=
data
.
cleanUrl
content
=
data
.
content
await
this
.
fileProviders
.
workspace
.
set
(
path
,
content
)
}
this
.
initialWorkspace
=
'code-sample'
await
this
.
fileManager
.
openFile
(
path
)
}
catch
(
e
)
{
console
.
error
(
e
)
}
return
}
const
self
=
this
this
.
appManager
.
on
(
'manager'
,
'pluginDeactivated'
,
self
.
removePluginActions
.
bind
(
this
))
// insert example contracts if there are no files to show
return
new
Promise
((
resolve
,
reject
)
=>
{
this
.
fileProviders
.
browser
.
resolveDirectory
(
'/'
,
async
(
error
,
filesList
)
=>
{
if
(
error
)
return
reject
(
error
)
if
(
Object
.
keys
(
filesList
).
length
===
0
)
{
await
this
.
createWorkspace
(
'default_workspace'
)
resolve
(
'default_workspace'
)
}
else
{
this
.
fileProviders
.
browser
.
resolveDirectory
(
'.workspaces'
,
async
(
error
,
filesList
)
=>
{
if
(
error
)
return
reject
(
error
)
if
(
Object
.
keys
(
filesList
).
length
>
0
)
{
const
workspacePath
=
Object
.
keys
(
filesList
)[
0
].
split
(
'/'
).
filter
(
val
=>
val
)
const
workspaceName
=
workspacePath
[
workspacePath
.
length
-
1
]
this
.
fileProviders
.
workspace
.
setWorkspace
(
workspaceName
)
return
resolve
(
workspaceName
)
}
return
reject
(
new
Error
(
'Can
\'
t find available workspace.'
))
})
}
})
})
}
async
createNewFile
()
{
return
await
this
.
request
.
createNewFile
()
}
...
...
libs/remix-ui/workspace/src/lib/actions/workspace.ts
View file @
65f2e759
...
...
@@ -6,13 +6,55 @@ const QueryParams = require('../../../../../../apps/remix-ide/src/lib/query-para
const
examples
=
require
(
'../../../../../../apps/remix-ide/src/app/editor/examples'
)
let
plugin
export
const
setCurrentWorkspace
=
(
workspace
:
string
)
=>
{
const
setCurrentWorkspace
=
(
workspace
:
string
)
=>
{
return
{
type
:
'SET_CURRENT_WORKSPACE'
,
payload
:
workspace
}
}
const
processCreateWorkspace
=
async
(
name
:
string
)
=>
{
const
workspaceProvider
=
plugin
.
fileProviders
.
workspace
const
browserProvider
=
plugin
.
fileProviders
.
browser
const
workspacePath
=
'browser/'
+
workspaceProvider
.
workspacesPath
+
'/'
+
name
const
workspaceRootPath
=
'browser/'
+
workspaceProvider
.
workspacesPath
const
workspaceRootPathExists
=
await
browserProvider
.
exists
(
workspaceRootPath
)
const
workspacePathExists
=
await
browserProvider
.
exists
(
workspacePath
)
if
(
!
workspaceRootPathExists
)
browserProvider
.
createDir
(
workspaceRootPath
)
if
(
!
workspacePathExists
)
browserProvider
.
createDir
(
workspacePath
)
workspaceProvider
.
setWorkspace
(
name
)
}
const
createWorkspace
=
async
(
workspaceName
:
string
,
setDefaults
=
true
)
=>
{
if
(
!
workspaceName
)
throw
new
Error
(
'workspace name cannot be empty'
)
if
(
checkSpecialChars
(
workspaceName
)
||
checkSlash
(
workspaceName
))
throw
new
Error
(
'special characters are not allowed'
)
if
(
await
workspaceExists
(
workspaceName
))
throw
new
Error
(
'workspace already exists'
)
else
{
const
workspaceProvider
=
plugin
.
fileProviders
.
workspace
await
processCreateWorkspace
(
workspaceName
)
if
(
setDefaults
)
{
// insert example contracts if there are no files to show
for
(
const
file
in
examples
)
{
try
{
await
workspaceProvider
.
set
(
examples
[
file
].
name
,
examples
[
file
].
content
)
}
catch
(
error
)
{
console
.
error
(
error
)
}
}
}
}
}
const
workspaceExists
=
async
(
name
:
string
)
=>
{
const
workspaceProvider
=
plugin
.
fileProviders
.
workspace
const
browserProvider
=
plugin
.
fileProviders
.
browser
const
workspacePath
=
'browser/'
+
workspaceProvider
.
workspacesPath
+
'/'
+
name
return
browserProvider
.
exists
(
workspacePath
)
}
export
const
initWorkspace
=
(
filePanelPlugin
)
=>
async
(
dispatch
:
React
.
Dispatch
<
any
>
)
=>
{
plugin
=
filePanelPlugin
const
queryParams
=
new
QueryParams
()
...
...
@@ -66,49 +108,24 @@ export const initWorkspace = (filePanelPlugin) => async (dispatch: React.Dispatc
}
})
})
return
dispatch
(
setCurrentWorkspace
(
initialWorkspace
))
}
const
processCreateWorkspace
=
async
(
name
:
string
)
=>
{
const
workspaceProvider
=
plugin
.
fileProviders
.
workspace
const
browserProvider
=
plugin
.
fileProviders
.
browser
const
workspacePath
=
'browser/'
+
workspaceProvider
.
workspacesPath
+
'/'
+
name
const
workspaceRootPath
=
'browser/'
+
workspaceProvider
.
workspacesPath
const
workspaceRootPathExists
=
await
browserProvider
.
exists
(
workspaceRootPath
)
const
workspacePathExists
=
await
browserProvider
.
exists
(
workspacePath
)
// plugin.fileProviders.localhost.event.off('disconnected', localhostDisconnect)
// plugin.fileProviders.localhost.event.on('disconnected', localhostDisconnect)
// plugin.fileProviders.localhost.event.on('connected', () => {
// remixdExplorer.show()
// setWorkspace(LOCALHOST)
// })
if
(
!
workspaceRootPathExists
)
browserProvider
.
createDir
(
workspaceRootPath
)
if
(
!
workspacePathExists
)
browserProvider
.
createDir
(
workspacePath
)
plugin
.
fileProviders
.
workspace
.
setWorkspace
(
name
)
}
// plugin.fileProviders.localhost.event.on('disconnected', () => {
// remixdExplorer.hide()
// })
const
createWorkspace
=
async
(
workspaceName
,
setDefaults
=
true
)
=>
{
if
(
!
workspaceName
)
throw
new
Error
(
'name cannot be empty'
)
if
(
checkSpecialChars
(
workspaceName
)
||
checkSlash
(
workspaceName
))
throw
new
Error
(
'special characters are not allowed'
)
if
(
await
workspaceExists
(
workspaceName
))
throw
new
Error
(
'workspace already exists'
)
else
{
const
workspaceProvider
=
plugin
.
fileProviders
.
workspace
// plugin.fileProviders.localhost.event.on('loading', () => {
// remixdExplorer.loading()
// })
await
processCreateWorkspace
(
workspaceName
)
workspaceProvider
.
setWorkspace
(
workspaceName
)
plugin
.
workspaceName
=
workspaceName
if
(
setDefaults
)
{
// insert example contracts if there are no files to show
for
(
const
file
in
examples
)
{
try
{
await
workspaceProvider
.
set
(
examples
[
file
].
name
,
examples
[
file
].
content
)
}
catch
(
error
)
{
console
.
error
(
error
)
}
}
}
}
}
const
workspaceExists
=
async
(
name
)
=>
{
const
workspaceProvider
=
plugin
.
fileProviders
.
workspace
const
browserProvider
=
plugin
.
fileProviders
.
browser
const
workspacePath
=
'browser/'
+
workspaceProvider
.
workspacesPath
+
'/'
+
name
return
browserProvider
.
exists
(
workspacePath
)
// plugin.fileProviders.workspace.event.on('createWorkspace', (name) => {
// createNewWorkspace(name)
// })
return
dispatch
(
setCurrentWorkspace
(
initialWorkspace
))
}
libs/remix-ui/workspace/src/lib/reducers/workspace.ts
View file @
65f2e759
...
...
@@ -2,8 +2,17 @@ interface Action {
type
:
string
payload
:
Record
<
string
,
any
>
|
string
}
interface
State
{
browser
:
{
currentWorkspace
:
string
,
workspaces
:
string
[],
isRequesting
:
boolean
,
isSuccessful
:
boolean
,
error
:
string
}
}
export
const
browserInitialState
=
{
export
const
browserInitialState
:
State
=
{
browser
:
{
currentWorkspace
:
''
,
workspaces
:
[],
...
...
@@ -20,7 +29,8 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
...
state
,
browser
:
{
...
state
.
browser
,
currentWorkspace
:
typeof
action
.
payload
===
'string'
?
action
.
payload
:
''
currentWorkspace
:
typeof
action
.
payload
===
'string'
?
action
.
payload
:
''
,
workspaces
:
typeof
action
.
payload
===
'string'
?
state
.
browser
.
workspaces
.
includes
(
action
.
payload
)
?
state
.
browser
.
workspaces
:
[...
state
.
browser
.
workspaces
,
action
.
payload
]
:
state
.
browser
.
workspaces
}
}
}
...
...
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
View file @
65f2e759
...
...
@@ -32,6 +32,37 @@ var canUpload = window.File || window.FileReader || window.FileList || window.Bl
export
const
Workspace
=
(
props
:
WorkspaceProps
)
=>
{
const
LOCALHOST
=
' - connect to localhost - '
const
NO_WORKSPACE
=
' - none - '
const
[
state
,
setState
]
=
useState
({
workspaces
:
[],
reset
:
false
,
currentWorkspace
:
NO_WORKSPACE
,
hideRemixdExplorer
:
true
,
displayNewFile
:
false
,
externalUploads
:
null
,
uploadFileEvent
:
null
,
modal
:
{
hide
:
true
,
title
:
''
,
message
:
null
,
okLabel
:
''
,
okFn
:
()
=>
{},
cancelLabel
:
''
,
cancelFn
:
()
=>
{},
handleHide
:
null
},
loadingLocalhost
:
false
,
toasterMsg
:
''
})
const
[
currentWorkspace
,
setCurrentWorkspace
]
=
useState
<
string
>
(
''
)
const
[
fs
,
dispatch
]
=
useReducer
(
browserReducer
,
browserInitialState
)
useEffect
(()
=>
{
initWorkspace
(
props
.
plugin
)(
dispatch
)
},
[])
useEffect
(()
=>
{
if
(
fs
.
browser
.
currentWorkspace
)
setCurrentWorkspace
(
fs
.
browser
.
currentWorkspace
)
},
[
fs
.
browser
.
currentWorkspace
])
/* extends the parent 'plugin' with some function needed by the file explorer */
props
.
plugin
.
resetFocus
=
(
reset
)
=>
{
...
...
@@ -74,30 +105,6 @@ export const Workspace = (props: WorkspaceProps) => {
return
{
name
:
state
.
currentWorkspace
,
isLocalhost
:
state
.
currentWorkspace
===
LOCALHOST
,
absolutePath
:
`
${
props
.
workspace
.
workspacesPath
}
/
${
state
.
currentWorkspace
}
`
}
}
useEffect
(()
=>
{
let
getWorkspaces
=
async
()
=>
{
if
(
props
.
workspaces
&&
Array
.
isArray
(
props
.
workspaces
))
{
if
(
props
.
workspaces
.
length
>
0
&&
state
.
currentWorkspace
===
NO_WORKSPACE
)
{
const
currentWorkspace
=
props
.
workspace
.
getWorkspace
()
?
props
.
workspace
.
getWorkspace
()
:
props
.
workspaces
[
0
]
await
props
.
workspace
.
setWorkspace
(
currentWorkspace
)
setState
(
prevState
=>
{
return
{
...
prevState
,
workspaces
:
props
.
workspaces
,
currentWorkspace
}
})
}
else
{
setState
(
prevState
=>
{
return
{
...
prevState
,
workspaces
:
props
.
workspaces
}
})
}
}
}
getWorkspaces
()
return
()
=>
{
getWorkspaces
=
async
()
=>
{}
}
},
[
props
.
workspaces
])
const
localhostDisconnect
=
()
=>
{
if
(
state
.
currentWorkspace
===
LOCALHOST
)
setWorkspace
(
props
.
workspaces
.
length
>
0
?
props
.
workspaces
[
0
]
:
NO_WORKSPACE
)
// This should be removed some time after refactoring: https://github.com/ethereum/remix-project/issues/1197
...
...
@@ -107,38 +114,6 @@ export const Workspace = (props: WorkspaceProps) => {
}
}
// useEffect(() => {
// props.localhost.event.off('disconnected', localhostDisconnect)
// props.localhost.event.on('disconnected', localhostDisconnect)
// props.localhost.event.on('connected', () => {
// remixdExplorer.show()
// setWorkspace(LOCALHOST)
// })
// props.localhost.event.on('disconnected', () => {
// remixdExplorer.hide()
// })
// props.localhost.event.on('loading', () => {
// remixdExplorer.loading()
// })
// props.workspace.event.on('createWorkspace', (name) => {
// createNewWorkspace(name)
// })
// if (props.initialWorkspace) {
// props.workspace.setWorkspace(props.initialWorkspace)
// setState(prevState => {
// return { ...prevState, currentWorkspace: props.initialWorkspace }
// })
// }
// }, [])
useEffect
(()
=>
{
initWorkspace
(
props
.
plugin
)(
dispatch
)
},
[])
const
createNewWorkspace
=
async
(
workspaceName
)
=>
{
try
{
await
props
.
fileManager
.
closeAllFiles
()
...
...
@@ -151,30 +126,6 @@ export const Workspace = (props: WorkspaceProps) => {
}
}
const
[
state
,
setState
]
=
useState
({
workspaces
:
[],
reset
:
false
,
currentWorkspace
:
NO_WORKSPACE
,
hideRemixdExplorer
:
true
,
displayNewFile
:
false
,
externalUploads
:
null
,
uploadFileEvent
:
null
,
modal
:
{
hide
:
true
,
title
:
''
,
message
:
null
,
okLabel
:
''
,
okFn
:
()
=>
{},
cancelLabel
:
''
,
cancelFn
:
()
=>
{},
handleHide
:
null
},
loadingLocalhost
:
false
,
toasterMsg
:
''
})
const
[
fs
,
dispatch
]
=
useReducer
(
browserReducer
,
browserInitialState
)
const
toast
=
(
message
:
string
)
=>
{
setState
(
prevState
=>
{
return
{
...
prevState
,
toasterMsg
:
message
}
...
...
@@ -395,9 +346,9 @@ export const Workspace = (props: WorkspaceProps) => {
title=
'Delete'
>
</
span
>
</
span
>
<
select
id=
"workspacesSelect"
value=
{
fs
.
browser
.
currentWorkspace
}
data
-
id=
"workspacesSelect"
onChange=
{
(
e
)
=>
setWorkspace
(
e
.
target
.
value
)
}
className=
"form-control custom-select"
>
<
select
id=
"workspacesSelect"
value=
{
currentWorkspace
}
data
-
id=
"workspacesSelect"
onChange=
{
(
e
)
=>
setWorkspace
(
e
.
target
.
value
)
}
className=
"form-control custom-select"
>
{
state
.
workspaces
fs
.
browser
.
workspaces
.
map
((
folder
,
index
)
=>
{
return
<
option
key=
{
index
}
value=
{
folder
}
>
{
folder
}
</
option
>
})
...
...
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