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
783e92d0
Commit
783e92d0
authored
Sep 24, 2021
by
ioedeveloper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move context menu operation to reducer and removed duplicate event registration
parent
7ad686d1
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
178 additions
and
66 deletions
+178
-66
file-panel.js
apps/remix-ide/src/app/panels/file-panel.js
+2
-22
events.ts
libs/remix-ui/workspace/src/lib/actions/events.ts
+45
-24
payload.ts
libs/remix-ui/workspace/src/lib/actions/payload.ts
+16
-0
workspace.ts
libs/remix-ui/workspace/src/lib/actions/workspace.ts
+5
-4
FileSystemProvider.tsx
...mix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
+1
-1
workspace.ts
libs/remix-ui/workspace/src/lib/reducers/workspace.ts
+100
-5
remix-ui-workspace.tsx
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
+8
-9
index.ts
libs/remix-ui/workspace/src/lib/types/index.ts
+1
-1
No files found.
apps/remix-ide/src/app/panels/file-panel.js
View file @
783e92d0
...
...
@@ -9,7 +9,6 @@ const { GitHandle } = require('../files/git-handle.js')
const
{
HardhatHandle
}
=
require
(
'../files/hardhat-handle.js'
)
const
{
SlitherHandle
}
=
require
(
'../files/slither-handle.js'
)
const
globalRegistry
=
require
(
'../../global/registry'
)
const
modalDialogCustom
=
require
(
'../ui/modal-dialog-custom'
)
/*
Overview of APIs:
* fileManager: @args fileProviders (browser, shared-folder, swarm, github, etc ...) & config & editor
...
...
@@ -53,11 +52,7 @@ module.exports = class Filepanel extends ViewPlugin {
this
.
gitHandle
=
new
GitHandle
()
this
.
hardhatHandle
=
new
HardhatHandle
()
this
.
slitherHandle
=
new
SlitherHandle
()
this
.
registeredMenuItems
=
[]
this
.
removedMenuItems
=
[]
this
.
request
=
{}
this
.
workspaces
=
[]
this
.
initialWorkspace
=
null
this
.
appManager
=
appManager
this
.
workspaceStatus
=
{}
}
...
...
@@ -81,26 +76,11 @@ module.exports = class Filepanel extends ViewPlugin {
* @param callback (...args) => void
*/
registerContextMenuItem
(
item
)
{
if
(
!
item
)
throw
new
Error
(
'Invalid register context menu argument'
)
if
(
!
item
.
name
||
!
item
.
id
)
throw
new
Error
(
'Item name and id is mandatory'
)
if
(
!
item
.
type
&&
!
item
.
path
&&
!
item
.
extension
&&
!
item
.
pattern
)
throw
new
Error
(
'Invalid file matching criteria provided'
)
if
(
this
.
registeredMenuItems
.
filter
((
o
)
=>
{
return
o
.
id
===
item
.
id
&&
o
.
name
===
item
.
name
}).
length
)
throw
new
Error
(
`Action
${
item
.
name
}
already exists on
${
item
.
id
}
`
)
this
.
registeredMenuItems
=
[...
this
.
registeredMenuItems
,
item
]
this
.
removedMenuItems
=
this
.
removedMenuItems
.
filter
(
menuItem
=>
item
.
id
!==
menuItem
.
id
)
this
.
renderComponent
()
this
.
emit
(
'registerContextMenuItem'
,
item
)
}
removePluginActions
(
plugin
)
{
this
.
registeredMenuItems
=
this
.
registeredMenuItems
.
filter
((
item
)
=>
{
if
(
item
.
id
!==
plugin
.
name
||
item
.
sticky
===
true
)
return
true
else
{
this
.
removedMenuItems
.
push
(
item
)
return
false
}
})
this
.
renderComponent
()
this
.
emit
(
'removePluginActions'
,
plugin
)
}
getCurrentWorkspace
()
{
...
...
libs/remix-ui/workspace/src/lib/actions/events.ts
View file @
783e92d0
import
{
extractParentFromKey
}
from
'@remix-ui/helper'
import
React
from
'react'
import
{
displayNotification
,
fileAddedSuccess
,
fileRemovedSuccess
,
fileRenamedSuccess
,
folderAddedSuccess
,
rootFolderChangedSuccess
}
from
'./payload'
import
{
action
}
from
'../types'
import
{
displayNotification
,
displayPopUp
,
fileAddedSuccess
,
fileRemovedSuccess
,
fileRenamedSuccess
,
folderAddedSuccess
,
removeContextMenuItem
,
rootFolderChangedSuccess
,
setContextMenuItem
}
from
'./payload'
import
{
addInputField
,
createWorkspace
,
fetchWorkspaceDirectory
,
renameWorkspace
,
switchToWorkspace
,
uploadFile
}
from
'./workspace'
const
queuedEvents
=
[]
...
...
@@ -8,8 +9,39 @@ const pendingEvents = {}
const
LOCALHOST
=
' - connect to localhost - '
let
plugin
,
dispatch
:
React
.
Dispatch
<
any
>
export
const
listenOn
Events
=
(
filePanelPlugin
,
provider
)
=>
async
(
reducerDispatch
:
React
.
Dispatch
<
any
>
)
=>
{
export
const
listenOn
PluginEvents
=
(
filePanelPlugin
)
=>
{
plugin
=
filePanelPlugin
plugin
.
on
(
'filePanel'
,
'createWorkspace'
,
(
name
:
string
)
=>
{
createWorkspace
(
name
)
})
plugin
.
on
(
'filePanel'
,
'renameWorkspace'
,
(
oldName
:
string
,
workspaceName
:
string
)
=>
{
renameWorkspace
(
oldName
,
workspaceName
)
})
plugin
.
on
(
'filePanel'
,
'registerContextMenuItem'
,
(
item
:
action
)
=>
{
registerContextMenuItem
(
item
)
})
plugin
.
on
(
'filePanel'
,
'removePluginActions'
,
(
plugin
)
=>
{
removePluginActions
(
plugin
)
})
plugin
.
on
(
'filePanel'
,
'displayNewFileInput'
,
(
path
)
=>
{
addInputField
(
'file'
,
path
)
})
plugin
.
on
(
'filePanel'
,
'uploadFileEvent'
,
(
dir
:
string
,
target
)
=>
{
uploadFile
(
target
,
dir
)
})
plugin
.
on
(
'remixd'
,
'rootFolderChanged'
,
async
(
path
:
string
)
=>
{
await
executeEvent
(
'rootFolderChanged'
,
path
)
})
}
export
const
listenOnProviderEvents
=
(
provider
)
=>
async
(
reducerDispatch
:
React
.
Dispatch
<
any
>
)
=>
{
dispatch
=
reducerDispatch
provider
.
event
.
on
(
'fileAdded'
,
async
(
filePath
:
string
)
=>
{
...
...
@@ -29,10 +61,6 @@ export const listenOnEvents = (filePanelPlugin, provider) => async (reducerDispa
await
executeEvent
(
'fileRenamed'
,
oldPath
,
newPath
)
})
plugin
.
on
(
'remixd'
,
'rootFolderChanged'
,
async
(
path
:
string
)
=>
{
await
executeEvent
(
'rootFolderChanged'
,
path
)
})
// provider.event.on('disconnected', () => {
// dispatch(setMode('browser'))
// })
...
...
@@ -77,29 +105,21 @@ export const listenOnEvents = (filePanelPlugin, provider) => async (reducerDispa
provider
.
event
.
on
(
'fileRenamedError'
,
async
()
=>
{
dispatch
(
displayNotification
(
'File Renamed Failed'
,
''
,
'Ok'
,
'Cancel'
))
})
}
plugin
.
on
(
'filePanel'
,
'displayNewFileInput'
,
(
path
)
=>
{
addInputField
(
'file'
,
path
)
})
plugin
.
on
(
'filePanel'
,
'uploadFileEvent'
,
(
dir
:
string
,
target
)
=>
{
uploadFile
(
target
,
dir
)
})
provider
.
event
.
on
(
'createWorkspace'
,
(
name
:
string
)
=>
{
createWorkspace
(
name
)
})
plugin
.
on
(
'filePanel'
,
'createWorkspace'
,
(
name
:
string
)
=>
{
createWorkspace
(
name
)
})
const
registerContextMenuItem
=
(
item
:
action
)
=>
{
if
(
!
item
)
return
dispatch
(
displayPopUp
(
'Invalid register context menu argument'
))
if
(
!
item
.
name
||
!
item
.
id
)
return
dispatch
(
displayPopUp
(
'Item name and id is mandatory'
))
if
(
!
item
.
type
&&
!
item
.
path
&&
!
item
.
extension
&&
!
item
.
pattern
)
return
dispatch
(
displayPopUp
(
'Invalid file matching criteria provided'
))
dispatch
(
setContextMenuItem
(
item
))
}
plugin
.
on
(
'filePanel'
,
'renameWorkspace'
,
(
oldName
:
string
,
workspaceName
:
string
)
=>
{
renameWorkspace
(
oldName
,
workspaceName
)
})
const
removePluginActions
=
(
plugin
)
=>
{
dispatch
(
removeContextMenuItem
(
plugin
))
}
const
fileAdded
=
async
(
filePath
:
string
)
=>
{
console
.
log
(
'fileAdded: '
,
filePath
)
await
dispatch
(
fileAddedSuccess
(
filePath
))
if
(
filePath
.
includes
(
'_test.sol'
))
{
plugin
.
emit
(
'newTestFileCreated'
,
filePath
)
...
...
@@ -107,6 +127,7 @@ const fileAdded = async (filePath: string) => {
}
const
folderAdded
=
async
(
folderPath
:
string
)
=>
{
console
.
log
(
'folderAdded: '
,
folderPath
)
const
provider
=
plugin
.
fileManager
.
currentFileProvider
()
const
path
=
extractParentFromKey
(
folderPath
)
||
provider
.
workspace
||
provider
.
type
||
''
...
...
libs/remix-ui/workspace/src/lib/actions/payload.ts
View file @
783e92d0
import
{
action
}
from
'../types'
export
const
setCurrentWorkspace
=
(
workspace
:
string
)
=>
{
return
{
type
:
'SET_CURRENT_WORKSPACE'
,
...
...
@@ -184,3 +186,17 @@ export const focusElement = (elements: { key: string, type: 'file' | 'folder' |
payload
:
elements
}
}
export
const
setContextMenuItem
=
(
item
:
action
)
=>
{
return
{
type
:
'SET_CONTEXT_MENU_ITEM'
,
payload
:
item
}
}
export
const
removeContextMenuItem
=
(
plugin
)
=>
{
return
{
type
:
'REMOVE_CONTEXT_MENU_ITEM'
,
payload
:
plugin
}
}
libs/remix-ui/workspace/src/lib/actions/workspace.ts
View file @
783e92d0
...
...
@@ -5,7 +5,7 @@ import { checkSpecialChars, checkSlash, extractNameFromKey, createNonClashingNam
import
Gists
from
'gists'
import
{
customAction
}
from
'@remixproject/plugin-api/lib/file-system/file-panel/type'
import
{
addInputFieldSuccess
,
createWorkspaceError
,
createWorkspaceRequest
,
createWorkspaceSuccess
,
displayNotification
,
displayPopUp
,
fetchDirectoryError
,
fetchDirectoryRequest
,
fetchDirectorySuccess
,
fetchWorkspaceDirectoryError
,
fetchWorkspaceDirectoryRequest
,
fetchWorkspaceDirectorySuccess
,
focusElement
,
hideNotification
,
hidePopUp
,
removeInputFieldSuccess
,
setCurrentWorkspace
,
setDeleteWorkspace
,
setMode
,
setRenameWorkspace
,
setWorkspaces
}
from
'./payload'
import
{
listenOnEvents
}
from
'./events'
import
{
listenOn
PluginEvents
,
listenOnProvider
Events
}
from
'./events'
const
QueryParams
=
require
(
'../../../../../../apps/remix-ide/src/lib/query-params'
)
const
examples
=
require
(
'../../../../../../apps/remix-ide/src/app/editor/examples'
)
...
...
@@ -43,9 +43,9 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
}
}
listenOn
Events
(
plugin
,
workspaceProvider
)(
dispatch
)
listenOn
Events
(
plugin
,
localhost
Provider
)(
dispatch
)
// dispatch(setWorkspaces(workspaces)
)
listenOn
PluginEvents
(
plugin
)
listenOn
ProviderEvents
(
workspace
Provider
)(
dispatch
)
listenOnProviderEvents
(
localhostProvider
)(
dispatch
)
dispatch
(
setMode
(
'browser'
))
}
}
...
...
@@ -106,6 +106,7 @@ export const removeInputField = async (path: string) => {
}
export
const
createWorkspace
=
async
(
workspaceName
:
string
)
=>
{
console
.
log
(
'workspaceName: '
,
workspaceName
)
const
promise
=
createWorkspaceTemplate
(
workspaceName
,
true
,
'default-template'
)
dispatch
(
createWorkspaceRequest
(
promise
))
...
...
libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
View file @
783e92d0
...
...
@@ -209,7 +209,7 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
}
return
(
<
FileSystemContext
.
Provider
value=
{
value
}
>
<
Workspace
plugin=
{
plugin
}
/>
<
Workspace
/>
<
ModalDialog
id=
'fileSystem'
{
...
focusModal
}
handleHide=
{
handleHideModal
}
/>
<
Toaster
message=
{
focusToaster
}
handleHide=
{
handleToaster
}
/>
</
FileSystemContext
.
Provider
>
...
...
libs/remix-ui/workspace/src/lib/reducers/workspace.ts
View file @
783e92d0
import
{
extractNameFromKey
}
from
'@remix-ui/helper'
import
{
FileType
}
from
'../types'
import
{
action
,
FileType
}
from
'../types'
import
*
as
_
from
'lodash'
interface
Action
{
type
:
string
...
...
@@ -13,7 +13,12 @@ export interface BrowserState {
expandPath
:
string
[]
isRequesting
:
boolean
,
isSuccessful
:
boolean
,
error
:
string
error
:
string
,
contextMenu
:
{
registeredMenuItems
:
action
[],
removedMenuItems
:
action
[],
error
:
string
}
},
localhost
:
{
sharedFolder
:
string
,
...
...
@@ -21,7 +26,12 @@ export interface BrowserState {
expandPath
:
string
[],
isRequesting
:
boolean
,
isSuccessful
:
boolean
,
error
:
string
error
:
string
,
contextMenu
:
{
registeredMenuItems
:
action
[],
removedMenuItems
:
action
[],
error
:
string
}
},
mode
:
'browser'
|
'localhost'
,
notification
:
{
...
...
@@ -46,7 +56,12 @@ export const browserInitialState: BrowserState = {
expandPath
:
[],
isRequesting
:
false
,
isSuccessful
:
false
,
error
:
null
error
:
null
,
contextMenu
:
{
registeredMenuItems
:
[],
removedMenuItems
:
[],
error
:
null
}
},
localhost
:
{
sharedFolder
:
''
,
...
...
@@ -54,7 +69,12 @@ export const browserInitialState: BrowserState = {
expandPath
:
[],
isRequesting
:
false
,
isSuccessful
:
false
,
error
:
null
error
:
null
,
contextMenu
:
{
registeredMenuItems
:
[],
removedMenuItems
:
[],
error
:
null
}
},
mode
:
'browser'
,
notification
:
{
...
...
@@ -465,6 +485,38 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
}
case
'SET_CONTEXT_MENU_ITEM'
:
{
const
payload
=
action
.
payload
as
action
return
{
...
state
,
browser
:
{
...
state
.
browser
,
contextMenu
:
state
.
mode
===
'browser'
?
addContextMenuItem
(
state
,
payload
)
:
state
.
browser
.
contextMenu
},
localhost
:
{
...
state
.
localhost
,
contextMenu
:
state
.
mode
===
'localhost'
?
addContextMenuItem
(
state
,
payload
)
:
state
.
localhost
.
contextMenu
}
}
}
case
'REMOVE_CONTEXT_MENU_ITEM'
:
{
const
payload
=
action
.
payload
return
{
...
state
,
browser
:
{
...
state
.
browser
,
contextMenu
:
state
.
mode
===
'browser'
?
removeContextMenuItem
(
state
,
payload
)
:
state
.
browser
.
contextMenu
},
localhost
:
{
...
state
.
localhost
,
contextMenu
:
state
.
mode
===
'localhost'
?
removeContextMenuItem
(
state
,
payload
)
:
state
.
localhost
.
contextMenu
}
}
}
default
:
throw
new
Error
()
}
...
...
@@ -609,3 +661,46 @@ const splitPath = (state: BrowserState, path: string): string[] | string => {
return
_path
}
const
addContextMenuItem
=
(
state
:
BrowserState
,
item
:
action
):
{
registeredMenuItems
:
action
[],
removedMenuItems
:
action
[],
error
:
string
}
=>
{
let
registeredItems
=
state
[
state
.
mode
].
contextMenu
.
registeredMenuItems
let
removedItems
=
state
[
state
.
mode
].
contextMenu
.
removedMenuItems
let
error
=
null
if
(
registeredItems
.
filter
((
o
)
=>
{
return
o
.
id
===
item
.
id
&&
o
.
name
===
item
.
name
}).
length
)
{
error
=
`Action
${
item
.
name
}
already exists on
${
item
.
id
}
`
return
{
registeredMenuItems
:
registeredItems
,
removedMenuItems
:
removedItems
,
error
}
}
registeredItems
=
[...
registeredItems
,
item
]
removedItems
=
removedItems
.
filter
(
menuItem
=>
item
.
id
!==
menuItem
.
id
)
return
{
registeredMenuItems
:
registeredItems
,
removedMenuItems
:
removedItems
,
error
}
}
const
removeContextMenuItem
=
(
state
:
BrowserState
,
plugin
):
{
registeredMenuItems
:
action
[],
removedMenuItems
:
action
[],
error
:
string
}
=>
{
let
registeredItems
=
state
[
state
.
mode
].
contextMenu
.
registeredMenuItems
const
removedItems
=
state
[
state
.
mode
].
contextMenu
.
removedMenuItems
const
error
=
null
registeredItems
=
registeredItems
.
filter
((
item
)
=>
{
if
(
item
.
id
!==
plugin
.
name
||
item
.
sticky
===
true
)
return
true
else
{
removedItems
.
push
(
item
)
return
false
}
})
return
{
registeredMenuItems
:
registeredItems
,
removedMenuItems
:
removedItems
,
error
}
}
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
View file @
783e92d0
import
React
,
{
useState
,
useEffect
,
useRef
,
useContext
}
from
'react'
// eslint-disable-line
import
{
FileExplorer
}
from
'./components/file-explorer'
// eslint-disable-line
import
'./css/remix-ui-workspace.css'
import
{
Workspace
Props
,
Workspace
State
}
from
'./types'
import
{
WorkspaceState
}
from
'./types'
import
{
FileSystemContext
}
from
'./contexts'
const
canUpload
=
window
.
File
||
window
.
FileReader
||
window
.
FileList
||
window
.
Blob
export
function
Workspace
(
props
:
WorkspaceProps
)
{
export
function
Workspace
()
{
const
LOCALHOST
=
' - connect to localhost - '
const
NO_WORKSPACE
=
' - none - '
const
[
state
]
=
useState
<
WorkspaceState
>
({
...
...
@@ -16,6 +16,8 @@ export function Workspace (props: WorkspaceProps) {
})
const
[
currentWorkspace
,
setCurrentWorkspace
]
=
useState
<
string
>
(
NO_WORKSPACE
)
const
global
=
useContext
(
FileSystemContext
)
const
workspaceRenameInput
=
useRef
()
const
workspaceCreateInput
=
useRef
()
useEffect
(()
=>
{
global
.
dispatchInitWorkspace
()
...
...
@@ -54,9 +56,6 @@ export function Workspace (props: WorkspaceProps) {
global
.
modal
(
'Delete Current Workspace'
,
'Are you sure to delete the current workspace?'
,
'OK'
,
onFinishDeleteWorkspace
,
''
)
}
const
workspaceRenameInput
=
useRef
()
const
workspaceCreateInput
=
useRef
()
const
onFinishRenameWorkspace
=
async
()
=>
{
if
(
workspaceRenameInput
.
current
===
undefined
)
return
// @ts-ignore: Object is possibly 'null'.
...
...
@@ -185,8 +184,8 @@ export function Workspace (props: WorkspaceProps) {
<
FileExplorer
name=
{
currentWorkspace
}
menuItems=
{
[
'createNewFile'
,
'createNewFolder'
,
'publishToGist'
,
canUpload
?
'uploadFile'
:
''
]
}
contextMenuItems=
{
props
.
plugin
.
registeredMenuItems
}
removedContextMenuItems=
{
props
.
plugin
.
removedMenuItems
}
contextMenuItems=
{
global
.
fs
.
browser
.
contextMenu
.
registeredMenuItems
}
removedContextMenuItems=
{
global
.
fs
.
browser
.
contextMenu
.
removedMenuItems
}
files=
{
global
.
fs
.
browser
.
files
}
expandPath=
{
global
.
fs
.
browser
.
expandPath
}
focusEdit=
{
global
.
fs
.
focusEdit
}
...
...
@@ -219,8 +218,8 @@ export function Workspace (props: WorkspaceProps) {
<
FileExplorer
name=
'localhost'
menuItems=
{
[
'createNewFile'
,
'createNewFolder'
]
}
contextMenuItems=
{
props
.
plugin
.
registeredMenuItems
}
removedContextMenuItems=
{
props
.
plugin
.
removedMenuItems
}
contextMenuItems=
{
global
.
fs
.
localhost
.
contextMenu
.
registeredMenuItems
}
removedContextMenuItems=
{
global
.
fs
.
localhost
.
contextMenu
.
removedMenuItems
}
files=
{
global
.
fs
.
localhost
.
files
}
expandPath=
{
global
.
fs
.
localhost
.
expandPath
}
focusEdit=
{
global
.
fs
.
focusEdit
}
...
...
libs/remix-ui/workspace/src/lib/types/index.ts
View file @
783e92d0
...
...
@@ -90,7 +90,7 @@ export interface FileExplorerMenuProps {
uploadFile
:
(
target
:
EventTarget
&
HTMLInputElement
)
=>
void
}
export
type
action
=
{
name
:
string
,
type
?:
Array
<
'folder'
|
'gist'
|
'file'
>
,
path
?:
string
[],
extension
?:
string
[],
pattern
?:
string
[],
id
:
string
,
multiselect
:
boolean
,
label
:
string
}
export
type
action
=
{
name
:
string
,
type
?:
Array
<
'folder'
|
'gist'
|
'file'
>
,
path
?:
string
[],
extension
?:
string
[],
pattern
?:
string
[],
id
:
string
,
multiselect
:
boolean
,
label
:
string
,
sticky
?:
boolean
}
export
type
MenuItems
=
action
[]
export
interface
FileExplorerContextMenuProps
{
...
...
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