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
079cd362
Commit
079cd362
authored
Sep 22, 2021
by
ioedeveloper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
finalize child components
parent
882251f6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
209 additions
and
110 deletions
+209
-110
file-panel.js
apps/remix-ide/src/app/panels/file-panel.js
+5
-2
workspace.ts
libs/remix-ui/workspace/src/lib/actions/workspace.ts
+4
-0
file-explorer-context-menu.tsx
...rkspace/src/lib/components/file-explorer-context-menu.tsx
+1
-1
file-explorer.tsx
libs/remix-ui/workspace/src/lib/components/file-explorer.tsx
+0
-0
file-label.tsx
libs/remix-ui/workspace/src/lib/components/file-label.tsx
+59
-0
file-render.tsx
libs/remix-ui/workspace/src/lib/components/file-render.tsx
+116
-0
workspace.ts
libs/remix-ui/workspace/src/lib/reducers/workspace.ts
+8
-7
remix-ui-workspace.css
libs/remix-ui/workspace/src/lib/remix-ui-workspace.css
+0
-62
remix-ui-workspace.tsx
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
+11
-31
index.ts
libs/remix-ui/workspace/src/lib/types/index.ts
+5
-7
No files found.
apps/remix-ide/src/app/panels/file-panel.js
View file @
079cd362
...
...
@@ -138,8 +138,11 @@ module.exports = class Filepanel extends ViewPlugin {
this
.
emit
(
'displayNewFileInput'
,
dir
)
}
async
uploadFile
(
event
)
{
return
await
this
.
request
.
uploadFile
(
event
)
async
uploadFile
(
target
)
{
const
provider
=
this
.
fileManager
.
currentFileProvider
()
const
dir
=
provider
.
workspace
||
'/'
return
this
.
emit
(
'uploadFileEvent'
,
dir
,
target
)
}
async
processCreateWorkspace
(
name
)
{
...
...
libs/remix-ui/workspace/src/lib/actions/workspace.ts
View file @
079cd362
...
...
@@ -484,6 +484,10 @@ const listenOnEvents = (provider) => {
plugin
.
on
(
'filePanel'
,
'displayNewFileInput'
,
(
path
)
=>
{
addInputField
(
'file'
,
path
)(
dispatch
)
})
plugin
.
on
(
'filePanel'
,
'uploadFileEvent'
,
(
dir
:
string
,
target
)
=>
{
uploadFile
(
target
,
dir
)(
dispatch
)
})
}
export
const
initWorkspace
=
(
filePanelPlugin
)
=>
async
(
reducerDispatch
:
React
.
Dispatch
<
any
>
)
=>
{
...
...
libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx
View file @
079cd362
import
React
,
{
useRef
,
useEffect
}
from
'react'
// eslint-disable-line
import
{
action
,
FileExplorerContextMenuProps
}
from
'../types'
import
'./css/file-explorer-context-menu.css'
import
'.
.
/css/file-explorer-context-menu.css'
import
{
customAction
}
from
'@remixproject/plugin-api/lib/file-system/file-panel'
declare
global
{
...
...
libs/remix-ui/workspace/src/lib/components/file-explorer.tsx
View file @
079cd362
This diff is collapsed.
Click to expand it.
libs/remix-ui/workspace/src/lib/components/file-label.tsx
0 → 100644
View file @
079cd362
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import
React
,
{
useEffect
,
useRef
}
from
'react'
import
{
FileType
}
from
'../types'
export
interface
FileLabelProps
{
file
:
FileType
,
focusEdit
:
{
element
:
string
type
:
string
isNew
:
boolean
lastEdit
:
string
}
editModeOff
:
(
content
:
string
)
=>
void
}
export
const
FileLabel
=
(
props
:
FileLabelProps
)
=>
{
const
{
file
,
focusEdit
,
editModeOff
}
=
props
const
isEditable
=
focusEdit
.
element
===
file
.
path
const
labelRef
=
useRef
(
null
)
useEffect
(()
=>
{
if
(
isEditable
)
{
setTimeout
(()
=>
{
labelRef
.
current
.
focus
()
},
0
)
}
},
[
isEditable
])
const
handleEditInput
=
(
event
:
React
.
KeyboardEvent
<
HTMLDivElement
>
)
=>
{
if
(
event
.
which
===
13
)
{
event
.
preventDefault
()
editModeOff
(
labelRef
.
current
.
innerText
)
}
}
const
handleEditBlur
=
(
event
:
React
.
SyntheticEvent
)
=>
{
event
.
stopPropagation
()
editModeOff
(
labelRef
.
current
.
innerText
)
}
return
(
<
div
className=
'remixui_items d-inline-block w-100'
ref=
{
labelRef
}
suppressContentEditableWarning=
{
true
}
contentEditable=
{
isEditable
}
onKeyDown=
{
handleEditInput
}
onBlur=
{
handleEditBlur
}
>
<
span
title=
{
file
.
path
}
className=
{
'remixui_label '
+
(
file
.
isDirectory
?
'folder'
:
'remixui_leaf'
)
}
data
-
path=
{
file
.
path
}
>
{
file
.
name
}
</
span
>
</
div
>
)
}
libs/remix-ui/workspace/src/lib/components/file-render.tsx
0 → 100644
View file @
079cd362
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import
React
,
{
SyntheticEvent
,
useState
}
from
'react'
import
{
FileType
}
from
'../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import
{
TreeView
,
TreeViewItem
}
from
'@remix-ui/tree-view'
import
{
getPathIcon
}
from
'@remix-ui/helper'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import
{
FileLabel
}
from
'./file-label'
export
interface
RenderFileProps
{
file
:
FileType
,
index
:
number
,
focusEdit
:
{
element
:
string
,
type
:
string
,
isNew
:
boolean
,
lastEdit
:
string
},
focusElement
:
{
key
:
string
,
type
:
'file'
|
'folder'
|
'gist'
}[],
focusContext
:
{
element
:
string
,
x
:
number
,
y
:
number
,
type
:
string
},
ctrlKey
:
boolean
,
expandPath
:
string
[],
editModeOff
:
(
content
:
string
)
=>
void
,
handleClickFolder
:
(
path
:
string
,
type
:
string
)
=>
void
,
handleClickFile
:
(
path
:
string
,
type
:
string
)
=>
void
,
handleContextMenu
:
(
pageX
:
number
,
pageY
:
number
,
path
:
string
,
content
:
string
,
type
:
string
)
=>
void
}
export
const
FileRender
=
(
props
:
RenderFileProps
)
=>
{
const
{
file
}
=
props
if
(
!
file
||
!
file
.
path
||
typeof
file
===
'string'
||
typeof
file
===
'number'
||
typeof
file
===
'boolean'
)
return
const
[
hover
,
setHover
]
=
useState
<
boolean
>
(
false
)
const
labelClass
=
props
.
focusEdit
.
element
===
file
.
path
?
'bg-light'
:
props
.
focusElement
.
findIndex
(
item
=>
item
.
key
===
file
.
path
)
!==
-
1
?
'bg-secondary'
:
hover
?
'bg-light border'
:
(
props
.
focusContext
.
element
===
file
.
path
)
&&
(
props
.
focusEdit
.
element
!==
file
.
path
)
?
'bg-light border'
:
''
const
icon
=
getPathIcon
(
file
.
path
)
const
spreadProps
=
{
onClick
:
(
e
)
=>
e
.
stopPropagation
()
}
const
handleFolderClick
=
(
event
:
SyntheticEvent
)
=>
{
event
.
stopPropagation
()
if
(
props
.
focusEdit
.
element
!==
file
.
path
)
props
.
handleClickFolder
(
file
.
path
,
file
.
type
)
}
const
handleFileClick
=
(
event
:
SyntheticEvent
)
=>
{
event
.
stopPropagation
()
if
(
props
.
focusEdit
.
element
!==
file
.
path
)
props
.
handleClickFile
(
file
.
path
,
file
.
type
)
}
const
handleContextMenu
=
(
event
:
PointerEvent
)
=>
{
event
.
preventDefault
()
event
.
stopPropagation
()
props
.
handleContextMenu
(
event
.
pageX
,
event
.
pageY
,
file
.
path
,
(
event
.
target
as
HTMLElement
).
textContent
,
file
.
type
)
}
const
handleMouseOut
=
(
event
:
SyntheticEvent
)
=>
{
event
.
stopPropagation
()
setHover
(
false
)
}
const
handleMouseOver
=
(
event
:
SyntheticEvent
)
=>
{
event
.
stopPropagation
()
setHover
(
true
)
}
if
(
file
.
isDirectory
)
{
return
(
<
TreeViewItem
id=
{
`treeViewItem${file.path}`
}
iconX=
'pr-3 fa fa-folder'
iconY=
'pr-3 fa fa-folder-open'
key=
{
`${file.path + props.index}`
}
label=
{
<
FileLabel
file=
{
file
}
focusEdit=
{
props
.
focusEdit
}
editModeOff=
{
props
.
editModeOff
}
/>
}
onClick=
{
handleFolderClick
}
onContextMenu=
{
handleContextMenu
}
labelClass=
{
labelClass
}
controlBehaviour=
{
props
.
ctrlKey
}
expand=
{
props
.
expandPath
.
includes
(
file
.
path
)
}
onMouseOver=
{
handleMouseOver
}
onMouseOut=
{
handleMouseOut
}
>
{
file
.
child
?
<
TreeView
id=
{
`treeView${file.path}`
}
key=
{
`treeView${file.path}`
}
{
...
spreadProps
}
>
{
Object
.
keys
(
file
.
child
).
map
((
key
,
index
)
=>
<
FileRender
file=
{
file
.
child
[
key
]
}
index=
{
index
}
focusContext=
{
props
.
focusContext
}
focusEdit=
{
props
.
focusEdit
}
focusElement=
{
props
.
focusElement
}
ctrlKey=
{
props
.
ctrlKey
}
editModeOff=
{
props
.
editModeOff
}
handleClickFile=
{
props
.
handleClickFile
}
handleClickFolder=
{
props
.
handleClickFolder
}
handleContextMenu=
{
props
.
handleContextMenu
}
expandPath=
{
props
.
expandPath
}
/>)
}
</
TreeView
>
:
<
TreeView
id=
{
`treeView${file.path}`
}
key=
{
`treeView${file.path}`
}
{
...
spreadProps
}
/>
}
</
TreeViewItem
>
)
}
else
{
return
(
<
TreeViewItem
id=
{
`treeViewItem${file.path}`
}
key=
{
`treeView${file.path}`
}
label=
{
<
FileLabel
file=
{
file
}
focusEdit=
{
props
.
focusEdit
}
editModeOff=
{
props
.
editModeOff
}
/>
}
onClick=
{
handleFileClick
}
onContextMenu=
{
handleContextMenu
}
icon=
{
icon
}
labelClass=
{
labelClass
}
onMouseOver=
{
handleMouseOver
}
onMouseOut=
{
handleMouseOut
}
/>
)
}
}
libs/remix-ui/workspace/src/lib/reducers/workspace.ts
View file @
079cd362
import
{
extractNameFromKey
}
from
'@remix-ui/helper'
import
{
FileType
}
from
'../types'
import
*
as
_
from
'lodash'
interface
Action
{
type
:
string
...
...
@@ -8,7 +9,7 @@ export interface BrowserState {
browser
:
{
currentWorkspace
:
string
,
workspaces
:
string
[],
files
:
{
[
x
:
string
]:
Record
<
string
,
File
>
},
files
:
{
[
x
:
string
]:
Record
<
string
,
File
Type
>
},
expandPath
:
string
[]
isRequesting
:
boolean
,
isSuccessful
:
boolean
,
...
...
@@ -16,7 +17,7 @@ export interface BrowserState {
},
localhost
:
{
sharedFolder
:
string
,
files
:
{
[
x
:
string
]:
Record
<
string
,
File
>
},
files
:
{
[
x
:
string
]:
Record
<
string
,
File
Type
>
},
expandPath
:
string
[],
isRequesting
:
boolean
,
isSuccessful
:
boolean
,
...
...
@@ -469,7 +470,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
}
const
fileAdded
=
(
state
:
BrowserState
,
path
:
string
):
{
[
x
:
string
]:
Record
<
string
,
File
>
}
=>
{
const
fileAdded
=
(
state
:
BrowserState
,
path
:
string
):
{
[
x
:
string
]:
Record
<
string
,
File
Type
>
}
=>
{
let
files
=
state
.
mode
===
'browser'
?
state
.
browser
.
files
:
state
.
localhost
.
files
const
_path
=
splitPath
(
state
,
path
)
...
...
@@ -482,7 +483,7 @@ const fileAdded = (state: BrowserState, path: string): { [x: string]: Record<str
return
files
}
const
fileRemoved
=
(
state
:
BrowserState
,
path
:
string
):
{
[
x
:
string
]:
Record
<
string
,
File
>
}
=>
{
const
fileRemoved
=
(
state
:
BrowserState
,
path
:
string
):
{
[
x
:
string
]:
Record
<
string
,
File
Type
>
}
=>
{
const
files
=
state
.
mode
===
'browser'
?
state
.
browser
.
files
:
state
.
localhost
.
files
const
_path
=
splitPath
(
state
,
path
)
...
...
@@ -491,7 +492,7 @@ const fileRemoved = (state: BrowserState, path: string): { [x: string]: Record<s
}
// IDEA: Modify function to remove blank input field without fetching content
const
fetchDirectoryContent
=
(
state
:
BrowserState
,
payload
:
{
fileTree
,
path
:
string
,
type
?:
'file'
|
'folder'
},
deletePath
?:
string
):
{
[
x
:
string
]:
Record
<
string
,
File
>
}
=>
{
const
fetchDirectoryContent
=
(
state
:
BrowserState
,
payload
:
{
fileTree
,
path
:
string
,
type
?:
'file'
|
'folder'
},
deletePath
?:
string
):
{
[
x
:
string
]:
Record
<
string
,
File
Type
>
}
=>
{
if
(
!
payload
.
fileTree
)
return
state
.
mode
===
'browser'
?
state
.
browser
.
files
:
state
[
state
.
mode
].
files
if
(
state
.
mode
===
'browser'
)
{
if
(
payload
.
path
===
state
.
browser
.
currentWorkspace
)
{
...
...
@@ -538,7 +539,7 @@ const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: s
}
}
const
fetchWorkspaceDirectoryContent
=
(
state
:
BrowserState
,
payload
:
{
fileTree
,
path
:
string
}):
{
[
x
:
string
]:
Record
<
string
,
File
>
}
=>
{
const
fetchWorkspaceDirectoryContent
=
(
state
:
BrowserState
,
payload
:
{
fileTree
,
path
:
string
}):
{
[
x
:
string
]:
Record
<
string
,
File
Type
>
}
=>
{
if
(
state
.
mode
===
'browser'
)
{
const
files
=
normalize
(
payload
.
fileTree
,
payload
.
path
)
...
...
@@ -548,7 +549,7 @@ const fetchWorkspaceDirectoryContent = (state: BrowserState, payload: { fileTree
}
}
const
normalize
=
(
filesList
,
directory
?:
string
,
newInputType
?:
'folder'
|
'file'
):
Record
<
string
,
File
>
=>
{
const
normalize
=
(
filesList
,
directory
?:
string
,
newInputType
?:
'folder'
|
'file'
):
Record
<
string
,
File
Type
>
=>
{
const
folders
=
{}
const
files
=
{}
...
...
libs/remix-ui/workspace/src/lib/remix-ui-workspace.css
deleted
100644 → 0
View file @
882251f6
.remixui_container
{
display
:
flex
;
flex-direction
:
row
;
width
:
100%
;
height
:
100%
;
box-sizing
:
border-box
;
}
.remixui_fileexplorer
{
display
:
flex
;
flex-direction
:
column
;
position
:
relative
;
width
:
100%
;
padding-left
:
6px
;
padding-right
:
6px
;
padding-top
:
6px
;
}
.remixui_fileExplorerTree
{
cursor
:
default
;
}
.remixui_gist
{
padding
:
10px
;
}
.remixui_gist
i
{
cursor
:
pointer
;
}
.remixui_gist
i
:hover
{
color
:
orange
;
}
.remixui_connectToLocalhost
{
padding
:
10px
;
}
.remixui_connectToLocalhost
i
{
cursor
:
pointer
;
}
.remixui_connectToLocalhost
i
:hover
{
color
:
var
(
--secondary
)
}
.remixui_uploadFile
{
padding
:
10px
;
}
.remixui_uploadFile
label
:hover
{
color
:
var
(
--secondary
)
}
.remixui_uploadFile
label
{
cursor
:
pointer
;
}
.remixui_treeview
{
overflow-y
:
auto
;
}
.remixui_dialog
{
display
:
flex
;
flex-direction
:
column
;
}
.remixui_dialogParagraph
{
margin-bottom
:
2em
;
word-break
:
break-word
;
}
.remixui_menuicon
{
padding-right
:
10px
;
}
\ No newline at end of file
libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
View file @
079cd362
import
React
,
{
useState
,
useEffect
,
useRef
,
useContext
}
from
'react'
// eslint-disable-line
import
{
FileExplorer
}
from
'./components/file-explorer'
// eslint-disable-line
import
'./remix-ui-workspace.css'
import
'./
css/
remix-ui-workspace.css'
import
{
WorkspaceProps
,
WorkspaceState
}
from
'./types'
import
{
FileSystemContext
}
from
'./contexts'
...
...
@@ -9,12 +9,9 @@ const canUpload = window.File || window.FileReader || window.FileList || window.
export
function
Workspace
(
props
:
WorkspaceProps
)
{
const
LOCALHOST
=
' - connect to localhost - '
const
NO_WORKSPACE
=
' - none - '
const
[
state
,
setState
]
=
useState
<
WorkspaceState
>
({
reset
:
false
,
const
[
state
]
=
useState
<
WorkspaceState
>
({
hideRemixdExplorer
:
true
,
displayNewFile
:
false
,
externalUploads
:
null
,
uploadFileEvent
:
null
,
loadingLocalhost
:
false
})
const
[
currentWorkspace
,
setCurrentWorkspace
]
=
useState
<
string
>
(
NO_WORKSPACE
)
...
...
@@ -50,19 +47,6 @@ export function Workspace (props: WorkspaceProps) {
return
createWorkspace
()
}
// props.plugin.request.createNewFile = async () => {
// if (!state.workspaces.length) await createNewWorkspace('default_workspace')
// props.plugin.resetNewFile()
// }
// props.plugin.request.uploadFile = async (target: EventTarget & HTMLInputElement) => {
// if (!state.workspaces.length) await createNewWorkspace('default_workspace')
// setState(prevState => {
// return { ...prevState, uploadFileEvent: target }
// })
// }
props
.
plugin
.
request
.
getCurrentWorkspace
=
()
=>
{
return
{
name
:
currentWorkspace
,
isLocalhost
:
currentWorkspace
===
LOCALHOST
,
absolutePath
:
`
${
props
.
plugin
.
workspace
.
workspacesPath
}
/
${
currentWorkspace
}
`
}
}
...
...
@@ -120,10 +104,8 @@ export function Workspace (props: WorkspaceProps) {
}
/** ** ****/
const
resetFocus
=
(
reset
)
=>
{
setState
(
prevState
=>
{
return
{
...
prevState
,
reset
}
})
const
resetFocus
=
()
=>
{
global
.
dispatchSetFocusElement
([{
key
:
''
,
type
:
'folder'
}])
}
const
switchWorkspace
=
async
(
name
:
string
)
=>
{
...
...
@@ -153,7 +135,7 @@ export function Workspace (props: WorkspaceProps) {
return
(
<
div
className=
'remixui_container'
>
<
div
className=
'remixui_fileexplorer'
onClick=
{
()
=>
resetFocus
(
true
)
}
>
<
div
className=
'remixui_fileexplorer'
onClick=
{
resetFocus
}
>
<
div
>
<
header
>
<
div
className=
"mb-2"
>
...
...
@@ -214,14 +196,12 @@ export function Workspace (props: WorkspaceProps) {
<
FileExplorer
name=
{
currentWorkspace
}
menuItems=
{
[
'createNewFile'
,
'createNewFolder'
,
'publishToGist'
,
canUpload
?
'uploadFile'
:
''
]
}
plugin=
{
props
.
plugin
}
focusRoot=
{
state
.
reset
}
contextMenuItems=
{
props
.
plugin
.
registeredMenuItems
}
removedContextMenuItems=
{
props
.
plugin
.
removedMenuItems
}
displayInput=
{
state
.
displayNewFile
}
externalUploads=
{
state
.
uploadFileEvent
}
resetFocus=
{
resetFocus
}
files=
{
global
.
fs
.
browser
.
files
}
expandPath=
{
global
.
fs
.
browser
.
expandPath
}
focusEdit=
{
global
.
fs
.
focusEdit
}
focusElement=
{
global
.
fs
.
focusElement
}
/>
}
</
div
>
...
...
@@ -232,12 +212,12 @@ export function Workspace (props: WorkspaceProps) {
<
FileExplorer
name=
'localhost'
menuItems=
{
[
'createNewFile'
,
'createNewFolder'
]
}
plugin=
{
props
.
plugin
}
focusRoot=
{
state
.
reset
}
contextMenuItems=
{
props
.
plugin
.
registeredMenuItems
}
removedContextMenuItems=
{
props
.
plugin
.
removedMenuItems
}
resetFocus=
{
resetFocus
}
files=
{
global
.
fs
.
localhost
.
files
}
expandPath=
{
global
.
fs
.
localhost
.
expandPath
}
focusEdit=
{
global
.
fs
.
focusEdit
}
focusElement=
{
global
.
fs
.
focusElement
}
/>
}
</
div
>
...
...
libs/remix-ui/workspace/src/lib/types/index.ts
View file @
079cd362
...
...
@@ -28,11 +28,8 @@ export interface WorkspaceProps {
}
}
export
interface
WorkspaceState
{
reset
:
boolean
hideRemixdExplorer
:
boolean
displayNewFile
:
boolean
externalUploads
:
EventTarget
&
HTMLInputElement
uploadFileEvent
:
EventTarget
&
HTMLInputElement
loadingLocalhost
:
boolean
}
...
...
@@ -46,7 +43,7 @@ export interface Modal {
cancelFn
:
()
=>
void
}
export
interface
File
{
export
interface
File
Type
{
path
:
string
,
name
:
string
,
isDirectory
:
boolean
,
...
...
@@ -58,13 +55,14 @@ export interface File {
export
interface
FileExplorerProps
{
name
:
string
,
menuItems
?:
string
[],
focusRoot
:
boolean
,
contextMenuItems
:
MenuItems
,
removedContextMenuItems
:
MenuItems
,
displayInput
?:
boolean
,
externalUploads
?:
EventTarget
&
HTMLInputElement
,
resetFocus
?:
(
value
:
boolean
)
=>
void
,
files
:
{
[
x
:
string
]:
Record
<
string
,
File
>
}
files
:
{
[
x
:
string
]:
Record
<
string
,
FileType
>
},
expandPath
:
string
[],
focusEdit
:
string
,
focusElement
:
{
key
:
string
,
type
:
'file'
|
'folder'
|
'gist'
}[]
}
export
interface
FileExplorerMenuProps
{
...
...
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