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
825db4a6
Commit
825db4a6
authored
Sep 15, 2021
by
ioedeveloper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Upload file
parent
f7db2794
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
64 additions
and
67 deletions
+64
-67
file-explorer.tsx
libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
+6
-57
index.ts
libs/remix-ui/file-explorer/src/lib/types/index.ts
+0
-3
workspace.ts
libs/remix-ui/workspace/src/lib/actions/workspace.ts
+47
-2
index.ts
libs/remix-ui/workspace/src/lib/contexts/index.ts
+3
-2
FileSystemProvider.tsx
...mix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
+8
-3
No files found.
libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
View file @
825db4a6
...
...
@@ -13,13 +13,12 @@ import { contextMenuActions } from './utils'
import
'./css/file-explorer.css'
export
const
FileExplorer
=
(
props
:
FileExplorerProps
)
=>
{
const
{
name
,
plugin
,
focusRoot
,
contextMenuItems
,
displayInput
,
externalUploads
,
removedContextMenuItems
,
resetFocus
,
files
}
=
props
const
{
name
,
focusRoot
,
contextMenuItems
,
displayInput
,
externalUploads
,
removedContextMenuItems
,
resetFocus
,
files
}
=
props
const
[
state
,
setState
]
=
useState
<
FileExplorerState
>
({
focusElement
:
[{
key
:
''
,
type
:
'folder'
}],
fileManager
:
null
,
ctrlKey
:
false
,
newFileName
:
''
,
actions
:
contextMenuActions
,
...
...
@@ -36,7 +35,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
lastEdit
:
''
},
expandPath
:
[
name
],
toasterMsg
:
''
,
mouseOverElement
:
null
,
showContextMenu
:
false
,
reservedKeywords
:
[
name
,
'gist-'
],
...
...
@@ -205,7 +203,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
const
createFile
=
await
fileManager
.
writeFile
(
newName
,
''
)
if
(
!
createFile
)
{
return
toast
(
'Failed to create file '
+
newName
)
return
global
.
toast
(
'Failed to create file '
+
newName
)
}
else
{
const
path
=
newName
.
indexOf
(
props
.
name
+
'/'
)
===
0
?
newName
.
replace
(
props
.
name
+
'/'
,
''
)
:
newName
...
...
@@ -239,7 +237,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
const
deletePath
=
async
(
path
:
string
|
string
[])
=>
{
if
(
global
.
fs
.
readonly
)
return
toast
(
'cannot delete file. '
+
name
+
' is a read only explorer'
)
if
(
global
.
fs
.
readonly
)
return
global
.
toast
(
'cannot delete file. '
+
name
+
' is a read only explorer'
)
if
(
!
Array
.
isArray
(
path
))
path
=
[
path
]
global
.
modal
(
`Delete
${
path
.
length
>
1
?
'items'
:
'item'
}
`
,
deleteMessage
(
path
),
'OK'
,
async
()
=>
{
...
...
@@ -251,7 +249,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
catch
(
e
)
{
const
isDir
=
await
state
.
fileManager
.
isDirectory
(
p
)
toast
(
`Failed to remove
${
isDir
?
'folder'
:
'file'
}
${
p
}
.`
)
global
.
toast
(
`Failed to remove
${
isDir
?
'folder'
:
'file'
}
${
p
}
.`
)
}
}
},
'Cancel'
,
()
=>
{})
...
...
@@ -273,55 +271,13 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
const
uploadFile
=
(
target
)
=>
{
const
filesProvider
=
fileSystem
.
provider
.
provider
// TODO The file explorer is merely a view on the current state of
// the files module. Please ask the user here if they want to overwrite
// a file and then just use `files.add`. The file explorer will
// pick that up via the 'fileAdded' event from the files module.
const
parentFolder
=
getFocusedFolder
()
const
expandPath
=
[...
new
Set
([...
state
.
expandPath
,
parentFolder
])]
setState
(
prevState
=>
{
return
{
...
prevState
,
expandPath
}
});
[...
target
.
files
].
forEach
((
file
)
=>
{
const
loadFile
=
(
name
:
string
):
void
=>
{
const
fileReader
=
new
FileReader
()
fileReader
.
onload
=
async
function
(
event
)
{
if
(
helper
.
checkSpecialChars
(
file
.
name
))
{
global
.
modal
(
'File Upload Failed'
,
'Special characters are not allowed'
,
'Close'
,
async
()
=>
{})
return
}
const
success
=
await
filesProvider
.
set
(
name
,
event
.
target
.
result
)
if
(
!
success
)
{
return
global
.
modal
(
'File Upload Failed'
,
'Failed to create file '
+
name
,
'Close'
,
async
()
=>
{})
}
const
config
=
registry
.
get
(
'config'
).
api
const
editor
=
registry
.
get
(
'editor'
).
api
if
((
config
.
get
(
'currentFile'
)
===
name
)
&&
(
editor
.
currentContent
()
!==
event
.
target
.
result
))
{
editor
.
setText
(
event
.
target
.
result
)
}
}
fileReader
.
readAsText
(
file
)
}
const
name
=
`
${
parentFolder
}
/
${
file
.
name
}
`
filesProvider
.
exists
(
name
).
then
(
exist
=>
{
if
(
!
exist
)
{
loadFile
(
name
)
}
else
{
global
.
modal
(
'Confirm overwrite'
,
`The file
${
name
}
already exists! Would you like to overwrite it?`
,
'OK'
,
()
=>
{
loadFile
(
name
)
},
'Cancel'
,
()
=>
{})
}
}).
catch
(
error
=>
{
if
(
error
)
console
.
log
(
error
)
})
})
global
.
dispatchUploadFile
(
target
,
parentFolder
)
}
const
copyFile
=
(
src
:
string
,
dest
:
string
)
=>
{
...
...
@@ -377,12 +333,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
plugin
.
call
(
cmd
.
id
,
cmd
.
name
,
cmd
)
}
const
toast
=
(
message
:
string
)
=>
{
setState
(
prevState
=>
{
return
{
...
prevState
,
toasterMsg
:
message
}
})
}
const
handleClickFile
=
(
path
:
string
,
type
:
'folder'
|
'file'
|
'gist'
)
=>
{
path
=
path
.
indexOf
(
props
.
name
+
'/'
)
===
0
?
path
.
replace
(
props
.
name
+
'/'
,
''
)
:
path
if
(
!
state
.
ctrlKey
)
{
...
...
@@ -564,7 +514,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
return
{
...
prevState
,
copyElement
:
[{
key
:
path
,
type
}]
}
})
setCanPaste
(
true
)
toast
(
`Copied to clipboard
${
path
}
`
)
global
.
toast
(
`Copied to clipboard
${
path
}
`
)
}
const
handlePasteClick
=
(
dest
:
string
,
destType
:
string
)
=>
{
...
...
@@ -735,7 +685,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
</
div
>
</
TreeViewItem
>
</
TreeView
>
<
Toaster
message=
{
state
.
toasterMsg
}
/>
{
state
.
showContextMenu
&&
<
FileExplorerContextMenu
actions=
{
state
.
focusElement
.
length
>
1
?
state
.
actions
.
filter
(
item
=>
item
.
multiselect
)
:
state
.
actions
.
filter
(
item
=>
!
item
.
multiselect
)
}
...
...
libs/remix-ui/file-explorer/src/lib/types/index.ts
View file @
825db4a6
...
...
@@ -5,7 +5,6 @@ export type MenuItems = action[] // eslint-disable-line no-use-before-define
export
interface
FileExplorerProps
{
name
:
string
,
menuItems
?:
string
[],
plugin
:
any
,
focusRoot
:
boolean
,
contextMenuItems
:
MenuItems
,
removedContextMenuItems
:
MenuItems
,
...
...
@@ -63,7 +62,6 @@ export interface FileExplorerState {
key
:
string
type
:
'folder'
|
'file'
|
'gist'
}[]
fileManager
:
any
ctrlKey
:
boolean
newFileName
:
string
actions
:
{
...
...
@@ -89,7 +87,6 @@ export interface FileExplorerState {
lastEdit
:
string
}
expandPath
:
string
[]
toasterMsg
:
string
mouseOverElement
:
string
showContextMenu
:
boolean
reservedKeywords
:
string
[]
...
...
libs/remix-ui/workspace/src/lib/actions/workspace.ts
View file @
825db4a6
...
...
@@ -254,7 +254,7 @@ const createWorkspaceTemplate = async (workspaceName: string, setDefaults = true
provider
.
lastLoadedGistId
=
gistId
}
else
{
disp
layNotification
(
''
,
errorLoadingFile
.
message
||
errorLoadingFile
,
'OK'
,
null
,
()
=>
{},
null
)
disp
atch
(
displayNotification
(
''
,
errorLoadingFile
.
message
||
errorLoadingFile
,
'OK'
,
null
,
()
=>
{},
null
)
)
}
})
}
catch
(
e
)
{
...
...
@@ -697,7 +697,7 @@ export const publishToGist = (path?: string, type?: string) => async (dispatch:
}
}
catch
(
error
)
{
console
.
log
(
error
)
disp
layNotification
(
'Publish to gist Failed'
,
'Failed to create gist: '
+
error
.
message
,
'Close'
,
null
,
async
()
=>
{}
)
disp
atch
(
displayNotification
(
'Publish to gist Failed'
,
'Failed to create gist: '
+
error
.
message
,
'Close'
,
null
,
async
()
=>
{})
)
}
}
...
...
@@ -705,6 +705,51 @@ export const clearPopUp = () => async (dispatch: React.Dispatch<any>) => {
dispatch
(
hidePopUp
())
}
export
const
uploadFile
=
(
target
,
targetFolder
:
string
)
=>
async
(
dispatch
:
React
.
Dispatch
<
any
>
)
=>
{
// TODO The file explorer is merely a view on the current state of
// the files module. Please ask the user here if they want to overwrite
// a file and then just use `files.add`. The file explorer will
// pick that up via the 'fileAdded' event from the files module.
[...
target
.
files
].
forEach
((
file
)
=>
{
const
workspaceProvider
=
plugin
.
fileProviders
.
workspace
const
loadFile
=
(
name
:
string
):
void
=>
{
const
fileReader
=
new
FileReader
()
fileReader
.
onload
=
async
function
(
event
)
{
if
(
checkSpecialChars
(
file
.
name
))
{
dispatch
(
displayNotification
(
'File Upload Failed'
,
'Special characters are not allowed'
,
'Close'
,
null
,
async
()
=>
{}))
return
}
const
success
=
await
workspaceProvider
.
set
(
name
,
event
.
target
.
result
)
if
(
!
success
)
{
return
dispatch
(
displayNotification
(
'File Upload Failed'
,
'Failed to create file '
+
name
,
'Close'
,
null
,
async
()
=>
{}))
}
const
config
=
plugin
.
registry
.
get
(
'config'
).
api
const
editor
=
plugin
.
registry
.
get
(
'editor'
).
api
if
((
config
.
get
(
'currentFile'
)
===
name
)
&&
(
editor
.
currentContent
()
!==
event
.
target
.
result
))
{
editor
.
setText
(
event
.
target
.
result
)
}
}
fileReader
.
readAsText
(
file
)
}
const
name
=
`
${
targetFolder
}
/
${
file
.
name
}
`
workspaceProvider
.
exists
(
name
).
then
(
exist
=>
{
if
(
!
exist
)
{
loadFile
(
name
)
}
else
{
dispatch
(
displayNotification
(
'Confirm overwrite'
,
`The file
${
name
}
already exists! Would you like to overwrite it?`
,
'OK'
,
null
,
()
=>
{
loadFile
(
name
)
},
()
=>
{}))
}
}).
catch
(
error
=>
{
if
(
error
)
console
.
log
(
error
)
})
})
}
const
fileAdded
=
async
(
filePath
:
string
)
=>
{
await
dispatch
(
fileAddedSuccess
(
filePath
))
if
(
filePath
.
includes
(
'_test.sol'
))
{
...
...
libs/remix-ui/workspace/src/lib/contexts/index.ts
View file @
825db4a6
import
{
createContext
}
from
'react'
import
{
createContext
,
SyntheticEvent
}
from
'react'
import
{
BrowserState
}
from
'../reducers/workspace'
export
const
FileSystemContext
=
createContext
<
{
...
...
@@ -14,5 +14,6 @@ export const FileSystemContext = createContext<{
dispatchSwitchToWorkspace
:
(
name
:
string
)
=>
Promise
<
void
>
,
dispatchRenameWorkspace
:
(
oldName
:
string
,
workspaceName
:
string
)
=>
Promise
<
void
>
,
dispatchDeleteWorkspace
:
(
workspaceName
:
string
)
=>
Promise
<
void
>
,
dispatchPublishToGist
:
(
path
?:
string
,
type
?:
string
)
=>
Promise
<
void
>
dispatchPublishToGist
:
(
path
?:
string
,
type
?:
string
)
=>
Promise
<
void
>
,
dispatchUploadFile
:
(
target
?:
SyntheticEvent
,
targetFolder
?:
string
)
=>
Promise
<
void
>
}
>
(
null
)
libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
View file @
825db4a6
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import
React
,
{
useReducer
,
useState
,
useEffect
}
from
'react'
import
React
,
{
useReducer
,
useState
,
useEffect
,
SyntheticEvent
}
from
'react'
import
{
ModalDialog
}
from
'@remix-ui/modal-dialog'
// eslint-disable-line
import
{
Toaster
}
from
'@remix-ui/toaster'
// eslint-disable-line
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import
{
FileSystemContext
}
from
'../contexts'
import
{
browserReducer
,
browserInitialState
}
from
'../reducers/workspace'
import
{
initWorkspace
,
fetchDirectory
,
addInputField
,
removeInputField
,
createWorkspace
,
fetchWorkspaceDirectory
,
switchToWorkspace
,
renameWorkspace
,
deleteWorkspace
,
clearPopUp
,
publishToGist
}
from
'../actions/workspace'
import
{
initWorkspace
,
fetchDirectory
,
addInputField
,
removeInputField
,
createWorkspace
,
fetchWorkspaceDirectory
,
switchToWorkspace
,
renameWorkspace
,
deleteWorkspace
,
clearPopUp
,
publishToGist
,
uploadFile
}
from
'../actions/workspace'
import
{
Modal
,
WorkspaceProps
}
from
'../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import
{
Workspace
}
from
'../remix-ui-workspace'
...
...
@@ -66,6 +66,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
await
publishToGist
(
path
,
type
)(
fsDispatch
)
}
const
dispatchUploadFile
=
async
(
target
?:
SyntheticEvent
,
targetFolder
?:
string
)
=>
{
await
uploadFile
(
target
,
targetFolder
)(
fsDispatch
)
}
useEffect
(()
=>
{
if
(
modals
.
length
>
0
)
{
setFocusModal
(()
=>
{
...
...
@@ -149,7 +153,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
dispatchSwitchToWorkspace
,
dispatchRenameWorkspace
,
dispatchDeleteWorkspace
,
dispatchPublishToGist
dispatchPublishToGist
,
dispatchUploadFile
}
return
(
<
FileSystemContext
.
Provider
value=
{
value
}
>
...
...
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