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
501d4b01
Commit
501d4b01
authored
Aug 13, 2021
by
ioedeveloper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update loading code from url params and fetch gist using axios
parent
da9207dd
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
301 additions
and
131 deletions
+301
-131
file-panel.js
apps/remix-ide/src/app/panels/file-panel.js
+6
-4
file-explorer.tsx
libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
+0
-0
index.ts
libs/remix-ui/file-explorer/src/lib/types/index.ts
+45
-3
index.ts
libs/remix-ui/file-explorer/src/lib/utils/index.ts
+64
-0
index.ts
libs/remix-ui/helper/src/index.ts
+1
-1
remix-ui-helper.ts
libs/remix-ui/helper/src/lib/remix-ui-helper.ts
+20
-2
index.ts
libs/remix-ui/workspace/src/index.ts
+1
-1
gist-handler.ts
libs/remix-ui/workspace/src/lib/actions/gist-handler.ts
+0
-55
workspace.ts
libs/remix-ui/workspace/src/lib/actions/workspace.ts
+69
-27
FileSystemProvider.tsx
...mix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
+19
-15
workspace.ts
libs/remix-ui/workspace/src/lib/reducers/workspace.ts
+52
-9
remix-ui-workspace.tsx
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
+16
-12
index.ts
libs/remix-ui/workspace/src/lib/types/index.ts
+8
-2
No files found.
apps/remix-ide/src/app/panels/file-panel.js
View file @
501d4b01
...
@@ -3,7 +3,7 @@ import { ViewPlugin } from '@remixproject/engine-web'
...
@@ -3,7 +3,7 @@ import { ViewPlugin } from '@remixproject/engine-web'
import
*
as
packageJson
from
'../../../../../package.json'
import
*
as
packageJson
from
'../../../../../package.json'
import
React
from
'react'
// eslint-disable-line
import
React
from
'react'
// eslint-disable-line
import
ReactDOM
from
'react-dom'
import
ReactDOM
from
'react-dom'
import
{
FileSystemProvider
,
Workspace
}
from
'@remix-ui/workspace'
// eslint-disable-line
import
{
FileSystemProvider
}
from
'@remix-ui/workspace'
// eslint-disable-line
import
{
checkSpecialChars
,
checkSlash
}
from
'../../lib/helper'
import
{
checkSpecialChars
,
checkSlash
}
from
'../../lib/helper'
const
{
RemixdHandle
}
=
require
(
'../files/remixd-handle.js'
)
const
{
RemixdHandle
}
=
require
(
'../files/remixd-handle.js'
)
const
{
GitHandle
}
=
require
(
'../files/git-handle.js'
)
const
{
GitHandle
}
=
require
(
'../files/git-handle.js'
)
...
@@ -63,15 +63,17 @@ module.exports = class Filepanel extends ViewPlugin {
...
@@ -63,15 +63,17 @@ module.exports = class Filepanel extends ViewPlugin {
this
.
appManager
=
appManager
this
.
appManager
=
appManager
}
}
onActivation
()
{
this
.
renderComponent
()
}
render
()
{
render
()
{
return
this
.
el
return
this
.
el
}
}
renderComponent
()
{
renderComponent
()
{
ReactDOM
.
render
(
ReactDOM
.
render
(
<
FileSystemProvider
plugin
=
{
this
}
>
<
FileSystemProvider
plugin
=
{
this
}
/
>
<
Workspace
plugin
=
{
this
}
/
>
<
/FileSystemProvider
>
,
this
.
el
)
,
this
.
el
)
}
}
...
...
libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
View file @
501d4b01
This diff is collapsed.
Click to expand it.
libs/remix-ui/file-explorer/src/lib/types/index.ts
View file @
501d4b01
...
@@ -13,14 +13,15 @@ export interface FileExplorerProps {
...
@@ -13,14 +13,15 @@ export interface FileExplorerProps {
removedContextMenuItems
:
MenuItems
,
removedContextMenuItems
:
MenuItems
,
displayInput
?:
boolean
,
displayInput
?:
boolean
,
externalUploads
?:
EventTarget
&
HTMLInputElement
,
externalUploads
?:
EventTarget
&
HTMLInputElement
,
resetFocus
?:
(
value
:
boolean
)
=>
void
resetFocus
?:
(
value
:
boolean
)
=>
void
,
files
:
{
[
x
:
string
]:
Record
<
string
,
File
>
}
}
}
export
interface
File
{
export
interface
File
{
path
:
string
,
path
:
string
,
name
:
string
,
name
:
string
,
isDirectory
:
boolean
,
isDirectory
:
boolean
,
type
:
string
,
type
:
'folder'
|
'file'
|
'gist'
,
child
?:
File
[]
child
?:
File
[]
}
}
...
@@ -34,7 +35,7 @@ export interface FileExplorerMenuProps {
...
@@ -34,7 +35,7 @@ export interface FileExplorerMenuProps {
uploadFile
:
(
target
:
EventTarget
&
HTMLInputElement
)
=>
void
uploadFile
:
(
target
:
EventTarget
&
HTMLInputElement
)
=>
void
}
}
export
type
action
=
{
name
:
string
,
type
:
string
[],
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
}
export
interface
FileExplorerContextMenuProps
{
export
interface
FileExplorerContextMenuProps
{
actions
:
action
[],
actions
:
action
[],
...
@@ -58,3 +59,44 @@ export interface FileExplorerContextMenuProps {
...
@@ -58,3 +59,44 @@ export interface FileExplorerContextMenuProps {
copy
?:
(
path
:
string
,
type
:
string
)
=>
void
,
copy
?:
(
path
:
string
,
type
:
string
)
=>
void
,
paste
?:
(
destination
:
string
,
type
:
string
)
=>
void
paste
?:
(
destination
:
string
,
type
:
string
)
=>
void
}
}
export
interface
FileExplorerState
{
focusElement
:
{
key
:
string
type
:
'folder'
|
'file'
|
'gist'
}[]
fileManager
:
any
ctrlKey
:
boolean
newFileName
:
string
actions
:
{
id
:
string
name
:
string
type
?:
Array
<
'folder'
|
'gist'
|
'file'
>
path
?:
string
[]
extension
?:
string
[]
pattern
?:
string
[]
multiselect
:
boolean
label
:
string
}[]
focusContext
:
{
element
:
string
x
:
number
y
:
number
type
:
string
}
focusEdit
:
{
element
:
string
type
:
string
isNew
:
boolean
lastEdit
:
string
}
expandPath
:
string
[]
toasterMsg
:
string
mouseOverElement
:
string
showContextMenu
:
boolean
reservedKeywords
:
string
[]
copyElement
:
{
key
:
string
type
:
'folder'
|
'gist'
|
'file'
}[]
}
libs/remix-ui/file-explorer/src/lib/utils/index.ts
View file @
501d4b01
import
{
MenuItems
}
from
'../types'
export
const
extractNameFromKey
=
(
key
:
string
):
string
=>
{
export
const
extractNameFromKey
=
(
key
:
string
):
string
=>
{
const
keyPath
=
key
.
split
(
'/'
)
const
keyPath
=
key
.
split
(
'/'
)
...
@@ -11,3 +13,65 @@ export const extractParentFromKey = (key: string):string => {
...
@@ -11,3 +13,65 @@ export const extractParentFromKey = (key: string):string => {
return
keyPath
.
join
(
'/'
)
return
keyPath
.
join
(
'/'
)
}
}
export
const
contextMenuActions
:
MenuItems
=
[{
id
:
'newFile'
,
name
:
'New File'
,
type
:
[
'folder'
,
'gist'
],
multiselect
:
false
,
label
:
''
},
{
id
:
'newFolder'
,
name
:
'New Folder'
,
type
:
[
'folder'
,
'gist'
],
multiselect
:
false
,
label
:
''
},
{
id
:
'rename'
,
name
:
'Rename'
,
type
:
[
'file'
,
'folder'
],
multiselect
:
false
,
label
:
''
},
{
id
:
'delete'
,
name
:
'Delete'
,
type
:
[
'file'
,
'folder'
,
'gist'
],
multiselect
:
false
,
label
:
''
},
{
id
:
'run'
,
name
:
'Run'
,
extension
:
[
'.js'
],
multiselect
:
false
,
label
:
''
},
{
id
:
'pushChangesToGist'
,
name
:
'Push changes to gist'
,
type
:
[
'gist'
],
multiselect
:
false
,
label
:
''
},
{
id
:
'publishFolderToGist'
,
name
:
'Publish folder to gist'
,
type
:
[
'folder'
],
multiselect
:
false
,
label
:
''
},
{
id
:
'publishFileToGist'
,
name
:
'Publish file to gist'
,
type
:
[
'file'
],
multiselect
:
false
,
label
:
''
},
{
id
:
'copy'
,
name
:
'Copy'
,
type
:
[
'folder'
,
'file'
],
multiselect
:
false
,
label
:
''
},
{
id
:
'deleteAll'
,
name
:
'Delete All'
,
type
:
[
'folder'
,
'file'
],
multiselect
:
true
,
label
:
''
}]
libs/remix-ui/helper/src/index.ts
View file @
501d4b01
export
*
from
'./lib/remix-ui-helper'
;
export
*
from
'./lib/remix-ui-helper'
libs/remix-ui/helper/src/lib/remix-ui-helper.ts
View file @
501d4b01
export
function
remixUiHelper
():
string
{
export
const
extractNameFromKey
=
(
key
:
string
):
string
=>
{
return
'remix-ui-helper'
;
const
keyPath
=
key
.
split
(
'/'
)
return
keyPath
[
keyPath
.
length
-
1
]
}
export
const
extractParentFromKey
=
(
key
:
string
):
string
=>
{
if
(
!
key
)
return
const
keyPath
=
key
.
split
(
'/'
)
keyPath
.
pop
()
return
keyPath
.
join
(
'/'
)
}
export
const
checkSpecialChars
=
(
name
:
string
)
=>
{
return
name
.
match
(
/
[
:*?"<>
\\
'|
]
/
)
!=
null
}
export
const
checkSlash
=
(
name
:
string
)
=>
{
return
name
.
match
(
/
\/
/
)
!=
null
}
}
libs/remix-ui/workspace/src/index.ts
View file @
501d4b01
export
*
from
'./lib/remix-ui-workspace'
export
*
from
'./lib/providers/FileSystemProvider'
export
*
from
'./lib/providers/FileSystemProvider'
export
*
from
'./lib/contexts'
libs/remix-ui/workspace/src/lib/actions/gist-handler.ts
deleted
100644 → 0
View file @
da9207dd
// var modalDialogCustom = require('../app/ui/modal-dialog-custom')
import
*
as
request
from
'request'
export
class
GistHandler
{
handleLoad
(
params
)
{
let
loadingFromGist
=
false
let
gistId
if
(
params
.
gist
)
{
loadingFromGist
=
true
}
else
{
gistId
=
params
.
gist
loadingFromGist
=
!!
gistId
}
return
gistId
}
getGistId
(
str
:
string
)
{
const
idr
=
/
[
0-9A-Fa-f
]{8,}
/
const
match
=
idr
.
exec
(
str
)
return
match
?
match
[
0
]
:
null
}
loadFromGist
(
params
,
fileManager
)
{
const
gistId
=
this
.
handleLoad
(
params
)
request
.
get
({
url
:
`https://api.github.com/gists/
${
gistId
}
`
,
json
:
true
},
async
(
error
,
response
,
data
=
{})
=>
{
if
(
error
||
!
data
.
files
)
{
// modalDialogCustom.alert('Gist load error', error || data.message)
return
}
const
obj
=
{}
Object
.
keys
(
data
.
files
).
forEach
((
element
)
=>
{
const
path
=
element
.
replace
(
/
\.\.\.
/g
,
'/'
)
obj
[
'/'
+
'gist-'
+
gistId
+
'/'
+
path
]
=
data
.
files
[
element
]
})
fileManager
.
setBatchFiles
(
obj
,
'workspace'
,
true
,
(
errorLoadingFile
)
=>
{
if
(
!
errorLoadingFile
)
{
const
provider
=
fileManager
.
getProvider
(
'workspace'
)
provider
.
lastLoadedGistId
=
gistId
}
else
{
// modalDialogCustom.alert('Gist load error', errorLoadingFile.message || errorLoadingFile)
}
})
})
}
}
libs/remix-ui/workspace/src/lib/actions/workspace.ts
View file @
501d4b01
import
{
bufferToHex
,
keccakFromString
}
from
'ethereumjs-util'
import
{
checkSpecialChars
,
checkSlash
}
from
'../../../../../../apps/remix-ide/src/lib/helper'
import
React
from
'react'
import
React
from
'react'
import
{
bufferToHex
,
keccakFromString
}
from
'ethereumjs-util'
import
axios
,
{
AxiosResponse
}
from
'axios'
import
{
checkSpecialChars
,
checkSlash
}
from
'@remix-ui/helper'
// const GistHandler = require('../../../../../../apps/remix-ide/src/lib/gist-handler')
const
QueryParams
=
require
(
'../../../../../../apps/remix-ide/src/lib/query-params'
)
const
QueryParams
=
require
(
'../../../../../../apps/remix-ide/src/lib/query-params'
)
const
examples
=
require
(
'../../../../../../apps/remix-ide/src/app/editor/examples'
)
const
examples
=
require
(
'../../../../../../apps/remix-ide/src/app/editor/examples'
)
// const queuedEvents = []
// const queuedEvents = []
...
@@ -51,6 +51,19 @@ const fetchDirectorySuccess = (path: string, files) => {
...
@@ -51,6 +51,19 @@ const fetchDirectorySuccess = (path: string, files) => {
}
}
}
}
export
const
displayNotification
=
(
title
:
string
,
message
:
string
,
labelOk
:
string
,
labelCancel
:
string
,
actionOk
?:
(...
args
)
=>
void
,
actionCancel
?:
(...
args
)
=>
void
)
=>
{
return
{
type
:
'DISPLAY_NOTIFICATION'
,
payload
:
{
title
,
message
,
labelOk
,
labelCancel
,
actionOk
,
actionCancel
}
}
}
export
const
hideNotification
=
()
=>
{
return
{
type
:
'DISPLAY_NOTIFICATION'
}
}
export
const
fetchDirectory
=
(
mode
:
'browser'
|
'localhost'
,
path
:
string
)
=>
(
dispatch
:
React
.
Dispatch
<
any
>
)
=>
{
export
const
fetchDirectory
=
(
mode
:
'browser'
|
'localhost'
,
path
:
string
)
=>
(
dispatch
:
React
.
Dispatch
<
any
>
)
=>
{
const
provider
=
mode
===
'browser'
?
plugin
.
fileProviders
.
workspace
:
plugin
.
fileProviders
.
localhost
const
provider
=
mode
===
'browser'
?
plugin
.
fileProviders
.
workspace
:
plugin
.
fileProviders
.
localhost
const
promise
=
new
Promise
((
resolve
)
=>
{
const
promise
=
new
Promise
((
resolve
)
=>
{
...
@@ -73,34 +86,75 @@ export const fetchDirectory = (mode: 'browser' | 'localhost', path: string) => (
...
@@ -73,34 +86,75 @@ export const fetchDirectory = (mode: 'browser' | 'localhost', path: string) => (
const
createWorkspaceTemplate
=
async
(
workspaceName
:
string
,
setDefaults
=
true
,
template
:
'gist-template'
|
'code-template'
|
'default-template'
=
'default-template'
)
=>
{
const
createWorkspaceTemplate
=
async
(
workspaceName
:
string
,
setDefaults
=
true
,
template
:
'gist-template'
|
'code-template'
|
'default-template'
=
'default-template'
)
=>
{
if
(
!
workspaceName
)
throw
new
Error
(
'workspace name cannot be empty'
)
if
(
!
workspaceName
)
throw
new
Error
(
'workspace name cannot be empty'
)
if
(
checkSpecialChars
(
workspaceName
)
||
checkSlash
(
workspaceName
))
throw
new
Error
(
'special characters are not allowed'
)
if
(
checkSpecialChars
(
workspaceName
)
||
checkSlash
(
workspaceName
))
throw
new
Error
(
'special characters are not allowed'
)
if
(
await
workspaceExists
(
workspaceName
))
throw
new
Error
(
'workspace already exists'
)
if
(
await
workspaceExists
(
workspaceName
)
&&
template
===
'default-template'
)
throw
new
Error
(
'workspace already exists'
)
else
{
else
{
const
workspaceProvider
=
plugin
.
fileProviders
.
workspace
const
workspaceProvider
=
plugin
.
fileProviders
.
workspace
await
workspaceProvider
.
createWorkspace
(
workspaceName
)
await
workspaceProvider
.
createWorkspace
(
workspaceName
)
if
(
setDefaults
)
{
if
(
setDefaults
)
{
const
queryParams
=
new
QueryParams
()
const
params
=
queryParams
.
get
()
switch
(
template
)
{
switch
(
template
)
{
case
'code-template'
:
case
'code-template'
:
// creates a new workspace code-sample and loads code from url params.
// creates a new workspace code-sample and loads code from url params.
try
{
try
{
const
queryParams
=
new
QueryParams
()
const
params
=
queryParams
.
get
()
await
workspaceProvider
.
createWorkspace
(
workspaceName
)
await
workspaceProvider
.
createWorkspace
(
workspaceName
)
let
path
=
''
;
let
content
=
''
if
(
params
.
code
)
{
const
hash
=
bufferToHex
(
keccakFromString
(
params
.
code
))
const
hash
=
bufferToHex
(
keccakFromString
(
params
.
code
))
const
fileName
=
'contract-'
+
hash
.
replace
(
'0x'
,
''
).
substring
(
0
,
10
)
+
'.sol'
const
path
=
fileName
await
workspaceProvider
.
set
(
path
,
atob
(
params
.
code
))
path
=
'contract-'
+
hash
.
replace
(
'0x'
,
''
).
substring
(
0
,
10
)
+
'.sol'
await
plugin
.
fileManager
.
openFile
(
fileName
)
content
=
atob
(
params
.
code
)
await
workspaceProvider
.
set
(
path
,
content
)
}
else
if
(
params
.
url
)
{
const
data
=
await
plugin
.
call
(
'contentImport'
,
'resolve'
,
params
.
url
)
path
=
data
.
cleanUrl
content
=
data
.
content
await
workspaceProvider
.
set
(
path
,
content
)
}
await
plugin
.
fileManager
.
openFile
(
path
)
}
catch
(
e
)
{
}
catch
(
e
)
{
console
.
error
(
e
)
console
.
error
(
e
)
}
}
break
break
case
'gist-template'
:
case
'gist-template'
:
// creates a new workspace gist-sample and get the file from gist
// creates a new workspace gist-sample and get the file from gist
try
{
const
gistId
=
params
.
gist
const
response
:
AxiosResponse
=
await
axios
.
get
(
`https://api.github.com/gists/
${
gistId
}
`
)
const
data
=
response
.
data
console
.
log
(
'data: '
,
data
)
if
(
!
data
.
files
)
{
dispatch
(
displayNotification
(
'Gist load error'
,
'No files found'
,
'OK'
,
null
,
()
=>
{},
null
))
return
}
// const obj = {}
// Object.keys(data.files).forEach((element) => {
// const path = element.replace(/\.\.\./g, '/')
// obj['/' + 'gist-' + gistId + '/' + path] = data.files[element]
// })
// fileManager.setBatchFiles(obj, 'workspace', true, (errorLoadingFile) => {
// if (!errorLoadingFile) {
// const provider = fileManager.getProvider('workspace')
// provider.lastLoadedGistId = gistId
// } else {
// // modalDialogCustom.alert('', errorLoadingFile.message || errorLoadingFile)
// }
// })
}
catch
(
e
)
{
dispatch
(
displayNotification
(
'Gist load error'
,
e
.
message
,
'OK'
,
null
,
()
=>
{},
null
))
console
.
error
(
e
)
}
break
break
case
'default-template'
:
case
'default-template'
:
// creates a new workspace and populates it with default project template.
// creates a new workspace and populates it with default project template.
// insert example contracts
// insert example contracts
...
@@ -150,29 +204,17 @@ const getWorkspaces = async (): Promise<string[]> | undefined => {
...
@@ -150,29 +204,17 @@ const getWorkspaces = async (): Promise<string[]> | undefined => {
export
const
initWorkspace
=
(
filePanelPlugin
)
=>
async
(
reducerDispatch
:
React
.
Dispatch
<
any
>
)
=>
{
export
const
initWorkspace
=
(
filePanelPlugin
)
=>
async
(
reducerDispatch
:
React
.
Dispatch
<
any
>
)
=>
{
if
(
filePanelPlugin
)
{
if
(
filePanelPlugin
)
{
console
.
log
(
'filePanelPlugin: '
,
filePanelPlugin
)
plugin
=
filePanelPlugin
plugin
=
filePanelPlugin
dispatch
=
reducerDispatch
dispatch
=
reducerDispatch
const
provider
=
filePanelPlugin
.
fileProviders
.
workspace
const
provider
=
filePanelPlugin
.
fileProviders
.
workspace
const
queryParams
=
new
QueryParams
()
const
queryParams
=
new
QueryParams
()
// const gistHandler = new GistHandler()
const
params
=
queryParams
.
get
()
const
params
=
queryParams
.
get
()
// let loadedFromGist = false
const
workspaces
=
await
getWorkspaces
()
||
[]
const
workspaces
=
await
getWorkspaces
()
||
[]
// if (params.gist) {
// initialWorkspace = 'gist-sample'
// await provider.createWorkspace(initialWorkspace)
// loadedFromGist = gistHandler.loadFromGist(params, plugin.fileManager)
// }
// if (loadedFromGist) {
// dispatch(setWorkspaces(workspaces))
// dispatch(setCurrentWorkspace(initialWorkspace))
// return
// }
if
(
params
.
gist
)
{
if
(
params
.
gist
)
{
await
createWorkspaceTemplate
(
'gist-sample'
,
true
,
'gist-template'
)
}
else
if
(
params
.
code
)
{
dispatch
(
setCurrentWorkspace
(
'gist-sample'
))
}
else
if
(
params
.
code
||
params
.
url
)
{
await
createWorkspaceTemplate
(
'code-sample'
,
true
,
'code-template'
)
await
createWorkspaceTemplate
(
'code-sample'
,
true
,
'code-template'
)
dispatch
(
setCurrentWorkspace
(
'code-sample'
))
dispatch
(
setCurrentWorkspace
(
'code-sample'
))
}
else
{
}
else
{
...
@@ -225,7 +267,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
...
@@ -225,7 +267,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
// provider.event.on('createWorkspace', (name) => {
// provider.event.on('createWorkspace', (name) => {
// createNewWorkspace(name)
// createNewWorkspace(name)
// })
// })
dispatch
(
setWorkspaces
(
workspaces
))
//
dispatch(setWorkspaces(workspaces))
dispatch
(
setMode
(
'browser'
))
dispatch
(
setMode
(
'browser'
))
}
}
}
}
...
...
libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
View file @
501d4b01
// eslint-disable-next-line @typescript-eslint/no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import
React
,
{
useReducer
,
useState
,
useEffect
}
from
'react'
import
React
,
{
useReducer
,
useState
,
useEffect
}
from
'react'
import
{
ModalDialog
}
from
'@remix-ui/modal-dialog'
// eslint-disable-line
// eslint-disable-next-line @typescript-eslint/no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import
{
FileSystemContext
}
from
'../contexts'
import
{
FileSystemContext
}
from
'../contexts'
import
{
browserReducer
,
browserInitialState
}
from
'../reducers/workspace'
import
{
browserReducer
,
browserInitialState
}
from
'../reducers/workspace'
import
{
initWorkspace
,
initLocalhost
,
fetchDirectory
}
from
'../actions/workspace'
import
{
initWorkspace
,
initLocalhost
,
fetchDirectory
}
from
'../actions/workspace'
import
{
ModalDialog
}
from
'@remix-ui/modal-dialog'
// eslint-disable-line
import
{
Modal
,
WorkspaceProps
}
from
'../types'
import
{
Modal
}
from
'../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import
{
Workspace
}
from
'../remix-ui-workspace'
export
const
FileSystemProvider
=
({
filePanel
,
children
})
=>
{
export
const
FileSystemProvider
=
(
props
:
WorkspaceProps
)
=>
{
const
{
plugin
}
=
props
const
[
fs
,
fsDispatch
]
=
useReducer
(
browserReducer
,
browserInitialState
)
const
[
fs
,
fsDispatch
]
=
useReducer
(
browserReducer
,
browserInitialState
)
const
[
focusModal
,
setFocusModal
]
=
useState
<
Modal
>
({
const
[
focusModal
,
setFocusModal
]
=
useState
<
Modal
>
({
hide
:
true
,
hide
:
true
,
...
@@ -21,11 +24,11 @@ export const FileSystemProvider = ({ filePanel, children }) => {
...
@@ -21,11 +24,11 @@ export const FileSystemProvider = ({ filePanel, children }) => {
const
[
modals
,
setModals
]
=
useState
<
Modal
[]
>
([])
const
[
modals
,
setModals
]
=
useState
<
Modal
[]
>
([])
const
dispatchInitWorkspace
=
async
()
=>
{
const
dispatchInitWorkspace
=
async
()
=>
{
await
initWorkspace
(
filePanel
)(
fsDispatch
)
await
initWorkspace
(
plugin
)(
fsDispatch
)
}
}
const
dispatchInitLocalhost
=
async
()
=>
{
const
dispatchInitLocalhost
=
async
()
=>
{
await
initLocalhost
(
filePanel
)(
fsDispatch
)
await
initLocalhost
(
plugin
)(
fsDispatch
)
}
}
const
dispatchFetchDirectory
=
async
(
path
:
string
)
=>
{
const
dispatchFetchDirectory
=
async
(
path
:
string
)
=>
{
...
@@ -34,7 +37,7 @@ export const FileSystemProvider = ({ filePanel, children }) => {
...
@@ -34,7 +37,7 @@ export const FileSystemProvider = ({ filePanel, children }) => {
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
modals
.
length
>
0
)
{
if
(
modals
.
length
>
0
)
{
set
Modals
(
modals
=>
{
set
FocusModal
(()
=>
{
const
focusModal
=
{
const
focusModal
=
{
hide
:
false
,
hide
:
false
,
title
:
modals
[
0
].
title
,
title
:
modals
[
0
].
title
,
...
@@ -44,14 +47,12 @@ export const FileSystemProvider = ({ filePanel, children }) => {
...
@@ -44,14 +47,12 @@ export const FileSystemProvider = ({ filePanel, children }) => {
cancelLabel
:
modals
[
0
].
cancelLabel
,
cancelLabel
:
modals
[
0
].
cancelLabel
,
cancelFn
:
modals
[
0
].
cancelFn
cancelFn
:
modals
[
0
].
cancelFn
}
}
return
focusModal
modals
.
shift
()
return
{
...
modals
,
focusModal
,
modals
:
modals
}
})
})
const
modalList
=
modals
.
slice
()
modalList
.
shift
()
setModals
(
modalList
)
}
}
},
[
modals
])
},
[
modals
])
...
@@ -62,7 +63,10 @@ export const FileSystemProvider = ({ filePanel, children }) => {
...
@@ -62,7 +63,10 @@ export const FileSystemProvider = ({ filePanel, children }) => {
}
}
const
modal
=
(
title
:
string
,
message
:
string
|
JSX
.
Element
,
okLabel
:
string
,
okFn
:
()
=>
void
,
cancelLabel
?:
string
,
cancelFn
?:
()
=>
void
)
=>
{
const
modal
=
(
title
:
string
,
message
:
string
|
JSX
.
Element
,
okLabel
:
string
,
okFn
:
()
=>
void
,
cancelLabel
?:
string
,
cancelFn
?:
()
=>
void
)
=>
{
setModals
(
modals
=>
[...
modals
,
{
message
,
title
,
okLabel
,
okFn
,
cancelLabel
,
cancelFn
}])
setModals
(
modals
=>
{
modals
.
push
({
message
,
title
,
okLabel
,
okFn
,
cancelLabel
,
cancelFn
})
return
[...
modals
]
})
}
}
const
value
=
{
const
value
=
{
...
@@ -74,7 +78,7 @@ export const FileSystemProvider = ({ filePanel, children }) => {
...
@@ -74,7 +78,7 @@ export const FileSystemProvider = ({ filePanel, children }) => {
}
}
return
(
return
(
<
FileSystemContext
.
Provider
value=
{
value
}
>
<
FileSystemContext
.
Provider
value=
{
value
}
>
{
children
}
<
Workspace
plugin=
{
plugin
}
/>
<
ModalDialog
id=
'fileSystem'
{
...
focusModal
}
handleHide=
{
handleHideModal
}
/>
<
ModalDialog
id=
'fileSystem'
{
...
focusModal
}
handleHide=
{
handleHideModal
}
/>
</
FileSystemContext
.
Provider
>
</
FileSystemContext
.
Provider
>
)
)
...
...
libs/remix-ui/workspace/src/lib/reducers/workspace.ts
View file @
501d4b01
import
{
extractNameFromKey
}
from
'@remix-ui/file-explorer'
import
{
extractNameFromKey
,
File
}
from
'@remix-ui/file-explorer'
interface
Action
{
interface
Action
{
type
:
string
type
:
string
payload
:
any
payload
:
any
...
@@ -7,36 +7,52 @@ export interface BrowserState {
...
@@ -7,36 +7,52 @@ export interface BrowserState {
browser
:
{
browser
:
{
currentWorkspace
:
string
,
currentWorkspace
:
string
,
workspaces
:
string
[],
workspaces
:
string
[],
files
:
[]
files
:
{
[
x
:
string
]:
Record
<
string
,
File
>
}
isRequesting
:
boolean
,
isRequesting
:
boolean
,
isSuccessful
:
boolean
,
isSuccessful
:
boolean
,
error
:
string
error
:
string
},
},
localhost
:
{
localhost
:
{
files
:
[]
,
files
:
{
[
x
:
string
]:
Record
<
string
,
File
>
}
,
isRequesting
:
boolean
,
isRequesting
:
boolean
,
isSuccessful
:
boolean
,
isSuccessful
:
boolean
,
error
:
string
error
:
string
},
},
mode
:
'browser'
|
'localhost'
mode
:
'browser'
|
'localhost'
,
notification
:
{
title
:
string
,
message
:
string
,
actionOk
:
()
=>
void
,
actionCancel
:
(()
=>
void
)
|
null
,
labelOk
:
string
,
labelCancel
:
string
}
}
}
export
const
browserInitialState
:
BrowserState
=
{
export
const
browserInitialState
:
BrowserState
=
{
browser
:
{
browser
:
{
currentWorkspace
:
''
,
currentWorkspace
:
''
,
workspaces
:
[],
workspaces
:
[],
files
:
[]
,
files
:
{}
,
isRequesting
:
false
,
isRequesting
:
false
,
isSuccessful
:
false
,
isSuccessful
:
false
,
error
:
null
error
:
null
},
},
localhost
:
{
localhost
:
{
files
:
[]
,
files
:
{}
,
isRequesting
:
false
,
isRequesting
:
false
,
isSuccessful
:
false
,
isSuccessful
:
false
,
error
:
null
error
:
null
},
},
mode
:
'browser'
mode
:
'browser'
,
notification
:
{
title
:
''
,
message
:
''
,
actionOk
:
()
=>
{},
actionCancel
:
()
=>
{},
labelOk
:
''
,
labelCancel
:
''
}
}
}
export
const
browserReducer
=
(
state
=
browserInitialState
,
action
:
Action
)
=>
{
export
const
browserReducer
=
(
state
=
browserInitialState
,
action
:
Action
)
=>
{
...
@@ -67,9 +83,11 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
...
@@ -67,9 +83,11 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
}
case
'SET_MODE'
:
{
case
'SET_MODE'
:
{
const
payload
=
action
.
payload
as
'browser'
|
'localhost'
return
{
return
{
...
state
,
...
state
,
mode
:
action
.
payload
mode
:
payload
}
}
}
}
...
@@ -84,6 +102,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
...
@@ -84,6 +102,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
}
}
}
}
}
case
'FETCH_DIRECTORY_SUCCESS'
:
{
case
'FETCH_DIRECTORY_SUCCESS'
:
{
const
payload
=
action
.
payload
as
{
path
:
string
,
files
}
const
payload
=
action
.
payload
as
{
path
:
string
,
files
}
...
@@ -98,6 +117,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
...
@@ -98,6 +117,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
}
}
}
}
}
case
'FETCH_DIRECTORY_ERROR'
:
{
case
'FETCH_DIRECTORY_ERROR'
:
{
return
{
return
{
...
state
,
...
state
,
...
@@ -109,6 +129,29 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
...
@@ -109,6 +129,29 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
}
}
}
}
}
case
'DISPLAY_NOTIFICATION'
:
{
const
payload
=
action
.
payload
as
{
title
:
string
,
message
:
string
,
actionOk
:
()
=>
void
,
actionCancel
:
()
=>
void
,
labelOk
:
string
,
labelCancel
:
string
}
return
{
...
state
,
notification
:
{
title
:
payload
.
title
,
message
:
payload
.
message
,
actionOk
:
payload
.
actionOk
||
browserInitialState
.
notification
.
actionOk
,
actionCancel
:
payload
.
actionCancel
||
browserInitialState
.
notification
.
actionCancel
,
labelOk
:
payload
.
labelOk
,
labelCancel
:
payload
.
labelCancel
}
}
}
case
'HIDE_NOTIFICATION'
:
{
return
{
...
state
,
notification
:
browserInitialState
.
notification
}
}
default
:
default
:
throw
new
Error
()
throw
new
Error
()
}
}
...
@@ -120,7 +163,7 @@ const fetchDirectoryContent = (fileTree, folderPath: string) => {
...
@@ -120,7 +163,7 @@ const fetchDirectoryContent = (fileTree, folderPath: string) => {
return
{
[
extractNameFromKey
(
folderPath
)]:
files
}
return
{
[
extractNameFromKey
(
folderPath
)]:
files
}
}
}
const
normalize
=
(
filesList
):
any
=>
{
const
normalize
=
(
filesList
):
Record
<
string
,
File
>
=>
{
const
folders
=
{}
const
folders
=
{}
const
files
=
{}
const
files
=
{}
...
...
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
View file @
501d4b01
...
@@ -11,7 +11,6 @@ export function Workspace (props: WorkspaceProps) {
...
@@ -11,7 +11,6 @@ export function Workspace (props: WorkspaceProps) {
const
LOCALHOST
=
' - connect to localhost - '
const
LOCALHOST
=
' - connect to localhost - '
const
NO_WORKSPACE
=
' - none - '
const
NO_WORKSPACE
=
' - none - '
const
[
state
,
setState
]
=
useState
<
WorkspaceState
>
({
const
[
state
,
setState
]
=
useState
<
WorkspaceState
>
({
workspaces
:
[],
reset
:
false
,
reset
:
false
,
hideRemixdExplorer
:
true
,
hideRemixdExplorer
:
true
,
displayNewFile
:
false
,
displayNewFile
:
false
,
...
@@ -28,7 +27,10 @@ export function Workspace (props: WorkspaceProps) {
...
@@ -28,7 +27,10 @@ export function Workspace (props: WorkspaceProps) {
},
[])
},
[])
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
global
.
fs
.
browser
.
currentWorkspace
)
setCurrentWorkspace
(
global
.
fs
.
browser
.
currentWorkspace
)
if
(
global
.
fs
.
browser
.
currentWorkspace
)
{
setCurrentWorkspace
(
global
.
fs
.
browser
.
currentWorkspace
)
global
.
dispatchFetchDirectory
(
global
.
fs
.
browser
.
currentWorkspace
)
}
},
[
global
.
fs
.
browser
.
currentWorkspace
])
},
[
global
.
fs
.
browser
.
currentWorkspace
])
props
.
plugin
.
resetNewFile
=
()
=>
{
props
.
plugin
.
resetNewFile
=
()
=>
{
...
@@ -46,18 +48,18 @@ export function Workspace (props: WorkspaceProps) {
...
@@ -46,18 +48,18 @@ export function Workspace (props: WorkspaceProps) {
return
setWorkspace
(
workspaceName
)
return
setWorkspace
(
workspaceName
)
}
}
props
.
plugin
.
request
.
createNewFile
=
async
()
=>
{
//
props.plugin.request.createNewFile = async () => {
if
(
!
state
.
workspaces
.
length
)
await
createNewWorkspace
(
'default_workspace'
)
//
if (!state.workspaces.length) await createNewWorkspace('default_workspace')
props
.
plugin
.
resetNewFile
()
//
props.plugin.resetNewFile()
}
//
}
props
.
plugin
.
request
.
uploadFile
=
async
(
target
:
EventTarget
&
HTMLInputElement
)
=>
{
//
props.plugin.request.uploadFile = async (target: EventTarget & HTMLInputElement) => {
if
(
!
state
.
workspaces
.
length
)
await
createNewWorkspace
(
'default_workspace'
)
//
if (!state.workspaces.length) await createNewWorkspace('default_workspace')
setState
(
prevState
=>
{
//
setState(prevState => {
return
{
...
prevState
,
uploadFileEvent
:
target
}
//
return { ...prevState, uploadFileEvent: target }
})
//
})
}
//
}
props
.
plugin
.
request
.
getCurrentWorkspace
=
()
=>
{
props
.
plugin
.
request
.
getCurrentWorkspace
=
()
=>
{
return
{
name
:
currentWorkspace
,
isLocalhost
:
currentWorkspace
===
LOCALHOST
,
absolutePath
:
`
${
props
.
plugin
.
workspace
.
workspacesPath
}
/
${
currentWorkspace
}
`
}
return
{
name
:
currentWorkspace
,
isLocalhost
:
currentWorkspace
===
LOCALHOST
,
absolutePath
:
`
${
props
.
plugin
.
workspace
.
workspacesPath
}
/
${
currentWorkspace
}
`
}
...
@@ -287,6 +289,7 @@ export function Workspace (props: WorkspaceProps) {
...
@@ -287,6 +289,7 @@ export function Workspace (props: WorkspaceProps) {
displayInput=
{
state
.
displayNewFile
}
displayInput=
{
state
.
displayNewFile
}
externalUploads=
{
state
.
uploadFileEvent
}
externalUploads=
{
state
.
uploadFileEvent
}
resetFocus=
{
resetFocus
}
resetFocus=
{
resetFocus
}
files=
{
global
.
fs
.
browser
.
files
}
/>
/>
}
}
</
div
>
</
div
>
...
@@ -304,6 +307,7 @@ export function Workspace (props: WorkspaceProps) {
...
@@ -304,6 +307,7 @@ export function Workspace (props: WorkspaceProps) {
contextMenuItems=
{
props
.
plugin
.
registeredMenuItems
}
contextMenuItems=
{
props
.
plugin
.
registeredMenuItems
}
removedContextMenuItems=
{
props
.
plugin
.
removedMenuItems
}
removedContextMenuItems=
{
props
.
plugin
.
removedMenuItems
}
resetFocus=
{
resetFocus
}
resetFocus=
{
resetFocus
}
files=
{
global
.
fs
.
localhost
.
files
}
/>
/>
}
}
</
div
>
</
div
>
...
...
libs/remix-ui/workspace/src/lib/types/index.ts
View file @
501d4b01
import
{
MenuItems
}
from
'@remix-ui/file-explorer'
import
{
MenuItems
}
from
'@remix-ui/file-explorer'
export
interface
WorkspaceProps
{
export
interface
WorkspaceProps
{
plugin
:
{
plugin
:
{
setWorkspace
:
({
name
:
string
,
isLocalhost
:
boolean
},
setEvent
:
boolean
)
=>
void
,
setWorkspace
:
({
name
:
string
,
isLocalhost
:
boolean
},
setEvent
:
boolean
)
=>
void
,
...
@@ -29,7 +28,6 @@ export interface WorkspaceProps {
...
@@ -29,7 +28,6 @@ export interface WorkspaceProps {
}
}
}
}
export
interface
WorkspaceState
{
export
interface
WorkspaceState
{
workspaces
:
string
[]
reset
:
boolean
reset
:
boolean
hideRemixdExplorer
:
boolean
hideRemixdExplorer
:
boolean
displayNewFile
:
boolean
displayNewFile
:
boolean
...
@@ -48,3 +46,11 @@ export interface Modal {
...
@@ -48,3 +46,11 @@ export interface Modal {
cancelLabel
:
string
cancelLabel
:
string
cancelFn
:
()
=>
void
cancelFn
:
()
=>
void
}
}
export
interface
File
{
path
:
string
,
name
:
string
,
isDirectory
:
boolean
,
type
:
'folder'
|
'file'
|
'gist'
,
child
?:
File
[]
}
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