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
ee357b65
Commit
ee357b65
authored
Apr 19, 2021
by
ioedeveloper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change files structure.
parent
48f6b50e
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
193 additions
and
144 deletions
+193
-144
fileSystem.ts
libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts
+50
-31
file-explorer.tsx
libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
+68
-112
fileSystem.ts
libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts
+75
-1
No files found.
libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts
View file @
ee357b65
import
React
from
'react'
import
{
File
}
from
'../types'
import
{
extractNameFromKey
,
extractParentFromKey
}
from
'../utils'
const
globalRegistry
=
require
(
'../../../../../../apps/remix-ide/src/global/registry'
)
const
initializeProvider
=
()
=>
{
const
fileProviders
=
globalRegistry
.
get
(
'fileproviders'
).
api
const
browser
=
fileProviders
.
browser
// eslint-disable-line
const
workspace
=
fileProviders
.
workspace
const
localhost
=
fileProviders
.
localhost
// eslint-disable-line
}
import
{
extractNameFromKey
}
from
'../utils'
export
const
fetchDirectoryError
=
(
error
:
any
)
=>
{
return
{
...
...
@@ -37,9 +29,9 @@ export const fileSystemReset = () => {
}
}
const
normalize
=
(
filesList
):
File
[]
=>
{
const
folders
=
[]
const
files
=
[]
const
normalize
=
(
filesList
):
any
=>
{
const
folders
=
{}
const
files
=
{}
Object
.
keys
(
filesList
||
{}).
forEach
(
key
=>
{
key
=
key
.
replace
(
/^
\/
|
\/
$/g
,
''
)
// remove first and last slash
...
...
@@ -47,36 +39,35 @@ const normalize = (filesList): File[] => {
path
=
path
.
replace
(
/^
\/
|
\/
$/g
,
''
)
// remove first and last slash
if
(
filesList
[
key
].
isDirectory
)
{
folders
.
push
(
{
folders
[
key
]
=
{
path
,
name
:
extractNameFromKey
(
path
),
isDirectory
:
filesList
[
key
].
isDirectory
}
)
}
}
else
{
files
.
push
(
{
files
[
key
]
=
{
path
,
name
:
extractNameFromKey
(
path
),
isDirectory
:
filesList
[
key
].
isDirectory
}
)
}
}
})
return
[...
folders
,
...
files
]
return
Object
.
assign
({},
folders
,
files
)
}
const
fetchDirectoryContent
=
async
(
provider
,
folderPath
:
string
):
Promise
<
File
[]
>
=>
{
const
fetchDirectoryContent
=
async
(
provider
,
folderPath
:
string
):
Promise
<
any
>
=>
{
return
new
Promise
((
resolve
)
=>
{
provider
.
resolveDirectory
(
folderPath
,
(
error
,
fileTree
)
=>
{
if
(
error
)
console
.
error
(
error
)
const
files
=
normalize
(
fileTree
)
resolve
(
files
)
resolve
(
{
[
extractNameFromKey
(
folderPath
)]:
files
}
)
})
})
}
export
const
fetchDirectory
=
(
provider
,
path
:
string
)
=>
(
dispatch
:
React
.
Dispatch
<
any
>
)
=>
{
initializeProvider
()
const
promise
=
fetchDirectoryContent
(
provider
,
path
)
dispatch
(
fetchDirectoryRequest
(
promise
))
...
...
@@ -88,6 +79,39 @@ export const fetchDirectory = (provider, path: string) => (dispatch: React.Dispa
return
promise
}
export
const
resolveDirectoryError
=
(
error
:
any
)
=>
{
return
{
type
:
'RESOLVE_DIRECTORY_ERROR'
,
payload
:
error
}
}
export
const
resolveDirectoryRequest
=
(
promise
:
Promise
<
any
>
)
=>
{
return
{
type
:
'RESOLVE_DIRECTORY_REQUEST'
,
payload
:
promise
}
}
export
const
resolveDirectorySuccess
=
(
path
:
string
,
files
:
File
[])
=>
{
return
{
type
:
'RESOLVE_DIRECTORY_SUCCESS'
,
payload
:
{
path
,
files
}
}
}
export
const
resolveDirectory
=
(
provider
,
path
:
string
)
=>
(
dispatch
:
React
.
Dispatch
<
any
>
)
=>
{
const
promise
=
fetchDirectoryContent
(
provider
,
path
)
dispatch
(
resolveDirectoryRequest
(
promise
))
promise
.
then
((
files
)
=>
{
dispatch
(
resolveDirectorySuccess
(
path
,
files
))
}).
catch
((
error
)
=>
{
dispatch
(
resolveDirectoryError
({
error
}))
})
return
promise
}
export
const
fetchProviderError
=
(
error
:
any
)
=>
{
return
{
type
:
'FETCH_PROVIDER_ERROR'
,
...
...
@@ -109,15 +133,10 @@ export const fetchProviderSuccess = (provider: any) => {
}
}
export
const
setProvider
=
()
=>
(
dispatch
:
React
.
Dispatch
<
any
>
)
=>
{
initializeProvider
()
const
promise
=
fetchDirectoryContent
(
provider
,
path
)
dispatch
(
fetchDirectoryRequest
(
promise
))
promise
.
then
((
files
)
=>
{
dispatch
(
fetchDirectorySuccess
(
path
,
files
))
}).
catch
((
error
)
=>
{
dispatch
(
fetchDirectoryError
({
error
}))
})
return
promise
export
const
setProvider
=
(
provider
)
=>
(
dispatch
:
React
.
Dispatch
<
any
>
)
=>
{
if
(
provider
)
{
dispatch
(
fetchProviderSuccess
(
provider
))
}
else
{
dispatch
(
fetchProviderError
(
'No provider available'
))
}
}
libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
View file @
ee357b65
...
...
@@ -8,7 +8,7 @@ import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line
import
{
FileExplorerContextMenu
}
from
'./file-explorer-context-menu'
// eslint-disable-line
import
{
FileExplorerProps
,
File
}
from
'./types'
import
{
fileSystemReducer
,
fileSystemInitialState
}
from
'./reducers/fileSystem'
import
{
fetchDirectory
}
from
'./actions/fileSystem'
import
{
fetchDirectory
,
setProvider
,
resolveDirectory
}
from
'./actions/fileSystem'
import
*
as
helper
from
'../../../../../apps/remix-ide/src/lib/helper'
import
QueryParams
from
'../../../../../apps/remix-ide/src/lib/query-params'
...
...
@@ -17,7 +17,7 @@ import './css/file-explorer.css'
const
queryParams
=
new
QueryParams
()
export
const
FileExplorer
=
(
props
:
FileExplorerProps
)
=>
{
const
{
filesProvider
,
name
,
registry
,
plugin
,
focusRoot
,
contextMenuItems
,
displayInput
,
externalUploads
}
=
props
const
{
name
,
registry
,
plugin
,
focusRoot
,
contextMenuItems
,
displayInput
,
externalUploads
}
=
props
const
[
state
,
setState
]
=
useState
({
focusElement
:
[{
key
:
''
,
...
...
@@ -26,10 +26,51 @@ export const FileExplorer = (props: FileExplorerProps) => {
focusPath
:
null
,
files
:
[],
fileManager
:
null
,
filesProvider
,
ctrlKey
:
false
,
newFileName
:
''
,
actions
:
[],
actions
:
[{
id
:
'newFile'
,
name
:
'New File'
,
type
:
[
'folder'
],
path
:
[],
extension
:
[],
pattern
:
[]
},
{
id
:
'newFolder'
,
name
:
'New Folder'
,
type
:
[
'folder'
],
path
:
[],
extension
:
[],
pattern
:
[]
},
{
id
:
'rename'
,
name
:
'Rename'
,
type
:
[
'file'
,
'folder'
],
path
:
[],
extension
:
[],
pattern
:
[]
},
{
id
:
'delete'
,
name
:
'Delete'
,
type
:
[
'file'
,
'folder'
],
path
:
[],
extension
:
[],
pattern
:
[]
},
{
id
:
'pushChangesToGist'
,
name
:
'Push changes to gist'
,
type
:
[],
path
:
[],
extension
:
[],
pattern
:
[
'^browser/gists/([0-9]|[a-z])*$'
]
},
{
id
:
'run'
,
name
:
'Run'
,
type
:
[],
path
:
[],
extension
:
[
'.js'
],
pattern
:
[]
}],
focusContext
:
{
element
:
null
,
x
:
null
,
...
...
@@ -66,6 +107,20 @@ export const FileExplorer = (props: FileExplorerProps) => {
const
editRef
=
useRef
(
null
)
useEffect
(()
=>
{
if
(
props
.
filesProvider
)
{
setProvider
(
props
.
filesProvider
)(
dispatch
)
}
},
[
props
.
filesProvider
])
useEffect
(()
=>
{
const
provider
=
fileSystem
.
provider
.
provider
if
(
provider
)
{
fetchDirectory
(
provider
,
props
.
name
)(
dispatch
)
}
},
[
fileSystem
.
provider
.
provider
])
useEffect
(()
=>
{
if
(
state
.
focusEdit
.
element
)
{
setTimeout
(()
=>
{
if
(
editRef
&&
editRef
.
current
)
{
...
...
@@ -77,83 +132,21 @@ export const FileExplorer = (props: FileExplorerProps) => {
useEffect
(()
=>
{
(
async
()
=>
{
await
fetchDirectory
(
filesProvider
,
name
)(
dispatch
)
const
fileManager
=
registry
.
get
(
'filemanager'
).
api
const
actions
=
[{
id
:
'newFile'
,
name
:
'New File'
,
type
:
[
'folder'
],
path
:
[],
extension
:
[],
pattern
:
[]
},
{
id
:
'newFolder'
,
name
:
'New Folder'
,
type
:
[
'folder'
],
path
:
[],
extension
:
[],
pattern
:
[]
},
{
id
:
'rename'
,
name
:
'Rename'
,
type
:
[
'file'
,
'folder'
],
path
:
[],
extension
:
[],
pattern
:
[]
},
{
id
:
'delete'
,
name
:
'Delete'
,
type
:
[
'file'
,
'folder'
],
path
:
[],
extension
:
[],
pattern
:
[]
},
{
id
:
'pushChangesToGist'
,
name
:
'Push changes to gist'
,
type
:
[],
path
:
[],
extension
:
[],
pattern
:
[
'^browser/gists/([0-9]|[a-z])*$'
]
},
{
id
:
'run'
,
name
:
'Run'
,
type
:
[],
path
:
[],
extension
:
[
'.js'
],
pattern
:
[]
}]
setState
(
prevState
=>
{
return
{
...
prevState
,
fileManager
,
actions
,
expandPath
:
[
name
]
}
return
{
...
prevState
,
fileManager
,
expandPath
:
[
name
]
}
})
})()
},
[
name
])
useEffect
(()
=>
{
if
(
state
.
fileManager
)
{
filesProvider
.
event
.
register
(
'fileExternallyChanged'
,
fileExternallyChanged
)
filesProvider
.
event
.
register
(
'fileRenamedError'
,
fileRenamedError
)
filesProvider
.
event
.
register
(
'rootFolderChanged'
,
rootFolderChanged
)
}
},
[
state
.
fileManager
])
// useEffect(() => {
// const { expandPath } = state
// const expandFn = async () => {
// let files = state.files
// for (let i = 0; i < expandPath.length; i++) {
// files = await resolveDirectory(expandPath[i], files)
// await setState(prevState => {
// return { ...prevState, files }
// })
// }
// if (state.fileManager) {
// filesProvider.event.register('fileExternallyChanged', fileExternallyChanged)
// filesProvider.event.register('fileRenamedError', fileRenamedError)
// filesProvider.event.register('rootFolderChanged', rootFolderChanged)
// }
// if (expandPath && expandPath.length > 0) {
// expandFn()
// }
// }, [state.expandPath])
// }, [state.fileManager])
// useEffect(() => {
// // unregister event to update state in callback
...
...
@@ -262,44 +255,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
// return dir
// }
const
fetchDirectoryContent
=
async
(
folderPath
:
string
):
Promise
<
File
[]
>
=>
{
console
.
log
(
'folderPath: '
,
folderPath
)
return
new
Promise
((
resolve
)
=>
{
filesProvider
.
resolveDirectory
(
folderPath
,
(
_error
,
fileTree
)
=>
{
const
files
=
normalize
(
fileTree
)
console
.
log
(
'files: '
,
files
)
resolve
(
files
)
})
})
}
const
normalize
=
(
filesList
):
File
[]
=>
{
const
folders
=
[]
const
files
=
[]
Object
.
keys
(
filesList
||
{}).
forEach
(
key
=>
{
key
=
key
.
replace
(
/^
\/
|
\/
$/g
,
''
)
// remove first and last slash
let
path
=
key
path
=
path
.
replace
(
/^
\/
|
\/
$/g
,
''
)
// remove first and last slash
if
(
filesList
[
key
].
isDirectory
)
{
folders
.
push
({
path
,
name
:
extractNameFromKey
(
path
),
isDirectory
:
filesList
[
key
].
isDirectory
})
}
else
{
files
.
push
({
path
,
name
:
extractNameFromKey
(
path
),
isDirectory
:
filesList
[
key
].
isDirectory
})
}
})
return
[...
folders
,
...
files
]
}
const
extractNameFromKey
=
(
key
:
string
):
string
=>
{
const
keyPath
=
key
.
split
(
'/'
)
...
...
@@ -771,6 +726,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
setState
(
prevState
=>
{
return
{
...
prevState
,
focusElement
:
[{
key
:
path
,
type
:
'folder'
}],
expandPath
}
})
resolveDirectory
(
path
)(
dispatch
)
}
}
...
...
@@ -1033,8 +989,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
<
div
className=
'pb-2'
>
<
TreeView
id=
'treeViewMenu'
>
{
fileSystem
.
files
.
files
.
map
((
file
,
index
)
=>
{
return
renderFiles
(
file
,
index
)
fileSystem
.
files
.
files
[
props
.
name
]
&&
Object
.
keys
(
fileSystem
.
files
.
files
[
props
.
name
]).
map
((
key
,
index
)
=>
{
return
renderFiles
(
file
System
.
files
.
files
[
props
.
name
][
key
]
,
index
)
})
}
</
TreeView
>
...
...
libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts
View file @
ee357b65
import
{
extractNameFromKey
,
extractParentFromKey
}
from
'../util
s'
import
{
File
}
from
'../type
s'
interface
Action
{
type
:
string
;
payload
:
Record
<
string
,
any
>
;
...
...
@@ -7,6 +7,7 @@ interface Action {
export
const
fileSystemInitialState
=
{
files
:
{
files
:
[],
activeDirectory
:
{},
expandPath
:
[],
isRequesting
:
false
,
isSuccessful
:
false
,
...
...
@@ -57,6 +58,41 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action
}
}
}
case
'RESOLVE_DIRECTORY_REQUEST'
:
{
return
{
...
state
,
files
:
{
...
state
.
files
,
isRequesting
:
true
,
isSuccessful
:
false
,
error
:
null
}
}
}
case
'RESOLVE_DIRECTORY_SUCCESS'
:
{
return
{
...
state
,
files
:
{
...
state
.
files
,
files
:
action
.
payload
.
files
,
expandPath
:
[...
state
.
files
.
expandPath
,
action
.
payload
.
path
],
isRequesting
:
false
,
isSuccessful
:
true
,
error
:
null
}
}
}
case
'RESOLVE_DIRECTORY_ERROR'
:
{
return
{
...
state
,
files
:
{
...
state
.
files
,
isRequesting
:
false
,
isSuccessful
:
false
,
error
:
action
.
payload
}
}
}
case
'FETCH_PROVIDER_REQUEST'
:
{
return
{
...
state
,
...
...
@@ -91,7 +127,45 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action
}
}
}
case
'ADD_EMPTY_FILE'
:
{
return
{
...
state
,
files
:
{
...
state
.
files
,
files
:
[]
}
}
}
default
:
throw
new
Error
()
}
}
const
addEmptyFile
=
(
path
:
string
,
files
:
File
[]):
File
[]
=>
{
if
(
path
===
name
)
{
files
.
push
({
path
:
'browser/blank'
,
name
:
''
,
isDirectory
:
false
})
return
files
}
return
files
.
map
(
file
=>
{
if
(
file
.
child
)
{
if
(
file
.
path
===
path
)
{
file
.
child
=
[...
file
.
child
,
{
path
:
file
.
path
+
'/blank'
,
name
:
''
,
isDirectory
:
false
}]
return
file
}
else
{
file
.
child
=
addEmptyFile
(
path
,
file
.
child
)
return
file
}
}
else
{
return
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