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
eb353fa5
Commit
eb353fa5
authored
Nov 23, 2020
by
ioedeveloper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
File Explorer barebone
parent
cd08b816
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
255 additions
and
253 deletions
+255
-253
file-panel.js
apps/remix-ide/src/app/panels/file-panel.js
+11
-3
.eslintrc
libs/remix-ui/file-explorer/.eslintrc
+16
-245
file-explorer.css
libs/remix-ui/file-explorer/src/lib/file-explorer.css
+56
-0
file-explorer.tsx
libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
+165
-5
index.ts
libs/remix-ui/file-explorer/src/lib/types/index.ts
+7
-0
No files found.
apps/remix-ide/src/app/panels/file-panel.js
View file @
eb353fa5
import
{
ViewPlugin
}
from
'@remixproject/engine-web'
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
ReactDOM
from
'react-dom'
import
{
FileExplorer
}
from
'@remix-ui/file-explorer'
var
yo
=
require
(
'yo-yo'
)
var
yo
=
require
(
'yo-yo'
)
var
EventManager
=
require
(
'../../lib/events'
)
var
EventManager
=
require
(
'../../lib/events'
)
var
FileExplorer
=
require
(
'../files/file-explorer'
)
//
var FileExplorer = require('../files/file-explorer')
var
{
RemixdHandle
}
=
require
(
'../files/remixd-handle.js'
)
var
{
RemixdHandle
}
=
require
(
'../files/remixd-handle.js'
)
var
{
GitHandle
}
=
require
(
'../files/git-handle.js'
)
var
{
GitHandle
}
=
require
(
'../files/git-handle.js'
)
var
globalRegistry
=
require
(
'../../global/registry'
)
var
globalRegistry
=
require
(
'../../global/registry'
)
...
@@ -54,13 +57,18 @@ module.exports = class Filepanel extends ViewPlugin {
...
@@ -54,13 +57,18 @@ module.exports = class Filepanel extends ViewPlugin {
}
}
function
createProvider
(
key
,
menuItems
)
{
function
createProvider
(
key
,
menuItems
)
{
return
new
FileExplorer
(
self
.
_components
.
registry
,
self
.
_deps
.
fileProviders
[
key
],
menuItems
,
self
)
return
<
FileExplorer
localRegistry
=
{
self
.
_components
.
registry
}
files
=
{
self
.
_deps
.
fileProviders
[
key
]}
menuItems
=
{
menuItems
}
plugin
=
{
self
}
/
>
}
}
var
fileExplorer
=
createProvider
(
'browser'
,
[
'createNewFile'
,
'publishToGist'
,
canUpload
?
'uploadFile'
:
''
])
var
fileExplorer
=
createProvider
(
'browser'
,
[
'createNewFile'
,
'publishToGist'
,
canUpload
?
'uploadFile'
:
''
])
var
fileSystemExplorer
=
createProvider
(
'localhost'
)
var
fileSystemExplorer
=
createProvider
(
'localhost'
)
self
.
remixdHandle
=
new
RemixdHandle
(
fileSystemExplorer
,
self
.
_deps
.
fileProviders
.
localhost
,
appManager
)
//
self.remixdHandle = new RemixdHandle(fileSystemExplorer, self._deps.fileProviders.localhost, appManager)
self
.
gitHandle
=
new
GitHandle
()
self
.
gitHandle
=
new
GitHandle
()
const
explorers
=
yo
`
const
explorers
=
yo
`
...
...
libs/remix-ui/file-explorer/.eslintrc
View file @
eb353fa5
{
{
"rules": {
"array-callback-return": "warn",
"dot-location": ["warn", "property"],
"eqeqeq": ["warn", "smart"],
"new-parens": "warn",
"no-caller": "warn",
"no-cond-assign": ["warn", "except-parens"],
"no-const-assign": "warn",
"no-control-regex": "warn",
"no-delete-var": "warn",
"no-dupe-args": "warn",
"no-dupe-keys": "warn",
"no-duplicate-case": "warn",
"no-empty-character-class": "warn",
"no-empty-pattern": "warn",
"no-eval": "warn",
"no-ex-assign": "warn",
"no-extend-native": "warn",
"no-extra-bind": "warn",
"no-extra-label": "warn",
"no-fallthrough": "warn",
"no-func-assign": "warn",
"no-implied-eval": "warn",
"no-invalid-regexp": "warn",
"no-iterator": "warn",
"no-label-var": "warn",
"no-labels": ["warn", { "allowLoop": true, "allowSwitch": false }],
"no-lone-blocks": "warn",
"no-loop-func": "warn",
"no-mixed-operators": [
"warn",
{
"groups": [
["&", "|", "^", "~", "<<", ">>", ">>>"],
["==", "!=", "===", "!==", ">", ">=", "<", "<="],
["&&", "||"],
["in", "instanceof"]
],
"allowSamePrecedence": false
}
],
"no-multi-str": "warn",
"no-native-reassign": "warn",
"no-negated-in-lhs": "warn",
"no-new-func": "warn",
"no-new-object": "warn",
"no-new-symbol": "warn",
"no-new-wrappers": "warn",
"no-obj-calls": "warn",
"no-octal": "warn",
"no-octal-escape": "warn",
"no-redeclare": "warn",
"no-regex-spaces": "warn",
"no-restricted-syntax": ["warn", "WithStatement"],
"no-script-url": "warn",
"no-self-assign": "warn",
"no-self-compare": "warn",
"no-sequences": "warn",
"no-shadow-restricted-names": "warn",
"no-sparse-arrays": "warn",
"no-template-curly-in-string": "warn",
"no-this-before-super": "warn",
"no-throw-literal": "warn",
"no-restricted-globals": [
"error",
"addEventListener",
"blur",
"close",
"closed",
"confirm",
"defaultStatus",
"defaultstatus",
"event",
"external",
"find",
"focus",
"frameElement",
"frames",
"history",
"innerHeight",
"innerWidth",
"length",
"location",
"locationbar",
"menubar",
"moveBy",
"moveTo",
"name",
"onblur",
"onerror",
"onfocus",
"onload",
"onresize",
"onunload",
"open",
"opener",
"opera",
"outerHeight",
"outerWidth",
"pageXOffset",
"pageYOffset",
"parent",
"print",
"removeEventListener",
"resizeBy",
"resizeTo",
"screen",
"screenLeft",
"screenTop",
"screenX",
"screenY",
"scroll",
"scrollbars",
"scrollBy",
"scrollTo",
"scrollX",
"scrollY",
"self",
"status",
"statusbar",
"stop",
"toolbar",
"top"
],
"no-unexpected-multiline": "warn",
"no-unreachable": "warn",
"no-unused-expressions": [
"error",
{
"allowShortCircuit": true,
"allowTernary": true,
"allowTaggedTemplates": true
}
],
"no-unused-labels": "warn",
"no-useless-computed-key": "warn",
"no-useless-concat": "warn",
"no-useless-escape": "warn",
"no-useless-rename": [
"warn",
{
"ignoreDestructuring": false,
"ignoreImport": false,
"ignoreExport": false
}
],
"no-with": "warn",
"no-whitespace-before-property": "warn",
"react-hooks/exhaustive-deps": "warn",
"require-yield": "warn",
"rest-spread-spacing": ["warn", "never"],
"strict": ["warn", "never"],
"unicode-bom": ["warn", "never"],
"use-isnan": "warn",
"valid-typeof": "warn",
"no-restricted-properties": [
"error",
{
"object": "require",
"property": "ensure",
"message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting"
},
{
"object": "System",
"property": "import",
"message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting"
}
],
"getter-return": "warn",
"import/first": "error",
"import/no-amd": "error",
"import/no-webpack-loader-syntax": "error",
"react/forbid-foreign-prop-types": ["warn", { "allowInPropTypes": true }],
"react/jsx-no-comment-textnodes": "warn",
"react/jsx-no-duplicate-props": "warn",
"react/jsx-no-target-blank": "warn",
"react/jsx-no-undef": "error",
"react/jsx-pascal-case": ["warn", { "allowAllCaps": true, "ignore": [] }],
"react/jsx-uses-react": "warn",
"react/jsx-uses-vars": "warn",
"react/no-danger-with-children": "warn",
"react/no-direct-mutation-state": "warn",
"react/no-is-mounted": "warn",
"react/no-typos": "error",
"react/react-in-jsx-scope": "error",
"react/require-render-return": "error",
"react/style-prop-object": "warn",
"react/jsx-no-useless-fragment": "warn",
"jsx-a11y/accessible-emoji": "warn",
"jsx-a11y/alt-text": "warn",
"jsx-a11y/anchor-has-content": "warn",
"jsx-a11y/anchor-is-valid": [
"warn",
{ "aspects": ["noHref", "invalidHref"] }
],
"jsx-a11y/aria-activedescendant-has-tabindex": "warn",
"jsx-a11y/aria-props": "warn",
"jsx-a11y/aria-proptypes": "warn",
"jsx-a11y/aria-role": "warn",
"jsx-a11y/aria-unsupported-elements": "warn",
"jsx-a11y/heading-has-content": "warn",
"jsx-a11y/iframe-has-title": "warn",
"jsx-a11y/img-redundant-alt": "warn",
"jsx-a11y/no-access-key": "warn",
"jsx-a11y/no-distracting-elements": "warn",
"jsx-a11y/no-redundant-roles": "warn",
"jsx-a11y/role-has-required-aria-props": "warn",
"jsx-a11y/role-supports-aria-props": "warn",
"jsx-a11y/scope": "warn",
"react-hooks/rules-of-hooks": "error",
"default-case": "off",
"no-dupe-class-members": "off",
"no-undef": "off",
"@typescript-eslint/consistent-type-assertions": "warn",
"no-array-constructor": "off",
"@typescript-eslint/no-array-constructor": "warn",
"@typescript-eslint/no-namespace": "error",
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": [
"warn",
{
"functions": false,
"classes": false,
"variables": false,
"typedefs": false
}
],
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{ "args": "none", "ignoreRestSiblings": true }
],
"no-useless-constructor": "off",
"@typescript-eslint/no-useless-constructor": "warn"
},
"env": {
"env": {
"browser": true,
"browser": true,
"commonjs": true,
"es6": true
"es6": true,
},
"jest": true,
"extends": "../../../.eslintrc",
"node": true
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
},
"settings": { "react": { "version": "detect" } },
"parserOptions": {
"plugins": ["import", "jsx-a11y", "react", "react-hooks"],
"ecmaVersion": 11,
"extends": ["../../../.eslintrc"],
"sourceType": "module"
"ignorePatterns": ["!**/*"]
},
}
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error"
}
}
libs/remix-ui/file-explorer/src/lib/file-explorer.css
View file @
eb353fa5
.remixui_label
{
margin-top
:
4px
;
}
.remixui_leaf
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
width
:
90%
;
margin-bottom
:
0px
;
}
.remixui_fileexplorer
{
box-sizing
:
border-box
;
}
input
[
type
=
"file"
]
{
display
:
none
;
}
.remixui_folder
,
.remixui_file
{
font-size
:
14px
;
cursor
:
pointer
;
}
.remixui_file
{
padding
:
4px
;
}
.remixui_newFile
{
padding-right
:
10px
;
}
.remixui_newFile
i
{
cursor
:
pointer
;
}
.remixui_newFile
:hover
{
transform
:
scale
(
1.3
);
}
.remixui_menu
{
margin-left
:
20px
;
}
.remixui_items
{
display
:
inline
}
.remixui_remove
{
margin-left
:
auto
;
padding-left
:
5px
;
padding-right
:
5px
;
}
.remixui_activeMode
{
display
:
flex
;
width
:
100%
;
margin-right
:
10px
;
padding-right
:
19px
;
}
.remixui_activeMode
>
div
{
min-width
:
10px
;
}
ul
{
padding
:
0
;
}
\ No newline at end of file
libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
View file @
eb353fa5
import
React
from
'react'
import
React
,
{
useReducer
,
useState
}
from
'react'
// eslint-disable-line
import
{
TreeView
,
TreeViewItem
}
from
'@remix-ui/tree-view'
import
*
as
helper
from
'../../../../../apps/remix-ide/src/lib/helper'
import
{
FileExplorerProps
}
from
'./types'
import
'./
remix-ui-
file-explorer.css'
import
'./file-explorer.css'
/* eslint-disable-next-line */
function
extractData
(
value
,
tree
,
key
)
{
export
interface
FileExplorerProps
{}
const
newValue
=
{}
let
isFile
=
false
Object
.
keys
(
value
).
filter
((
x
)
=>
{
if
(
x
===
'/content'
)
isFile
=
true
if
(
x
[
0
]
!==
'/'
)
return
true
}).
forEach
((
x
)
=>
{
newValue
[
x
]
=
value
[
x
]
})
return
{
path
:
(
tree
||
{}).
path
?
tree
.
path
+
'/'
+
key
:
key
,
children
:
isFile
?
undefined
:
value
instanceof
Array
?
value
.
map
((
item
,
index
)
=>
({
key
:
index
,
value
:
item
}))
:
value
instanceof
Object
?
Object
.
keys
(
value
).
map
(
subkey
=>
({
key
:
subkey
,
value
:
value
[
subkey
]
}))
:
undefined
}
}
export
const
FileExplorer
=
(
props
:
FileExplorerProps
)
=>
{
export
const
FileExplorer
=
(
props
:
FileExplorerProps
)
=>
{
const
[
state
,
setState
]
=
useState
({
files
:
props
.
files
,
focusElement
:
null
,
focusPath
:
null
,
menuItems
:
[
{
action
:
'createNewFile'
,
title
:
'Create New File'
,
icon
:
'fas fa-plus-circle'
},
{
action
:
'publishToGist'
,
title
:
'Publish all [browser] explorer files to a github gist'
,
icon
:
'fab fa-github'
},
{
action
:
'uploadFile'
,
title
:
'Add Local file to the Browser Storage Explorer'
,
icon
:
'far fa-folder-open'
},
{
action
:
'updateGist'
,
title
:
'Update the current [gist] explorer'
,
icon
:
'fab fa-github'
}
].
filter
(
item
=>
props
.
menuItems
&&
props
.
menuItems
.
find
((
name
)
=>
{
return
name
===
item
.
action
}))
})
const
formatSelf
=
(
key
,
data
,
li
)
=>
{
const
isRoot
=
data
.
path
===
state
.
files
.
type
const
isFolder
=
!!
data
.
children
return
(
<
div
className=
'remixui_items'
>
<
span
title=
{
data
.
path
}
className=
{
'remixui_label '
+
!
isRoot
?
!
isFolder
?
'remixui_leaf'
:
'folder'
:
''
}
data
-
path=
{
data
.
path
}
style=
{
{
fontWeight
:
isRoot
?
'bold'
:
null
}
}
// onkeydown=${editModeOff}
// onblur=${editModeOff}
>
{
key
.
split
(
'/'
).
pop
()
}
</
span
>
{
isRoot
?
renderMenuItems
()
:
''
}
</
div
>
)
}
const
remixdDialog
=
()
=>
{
return
<
div
>
This file has been changed outside of Remix IDE.
</
div
>
}
const
fileRenamedError
=
(
error
)
=>
{
console
.
log
(
error
)
// modalDialogCustom.alert(error)
}
const
extractNameFromKey
=
(
key
)
=>
{
const
keyPath
=
key
.
split
(
'/'
)
return
keyPath
[
keyPath
.
length
-
1
]
}
const
renderMenuItems
=
()
=>
{
let
items
if
(
state
.
menuItems
)
{
items
=
state
.
menuItems
.
map
(({
action
,
title
,
icon
})
=>
{
if
(
action
===
'uploadFile'
)
{
return
(
<
label
id=
{
action
}
data
-
id=
{
'fileExplorerUploadFile'
+
action
}
className=
{
icon
+
' mb-0 remixui_newFile'
}
title=
{
title
}
>
<
input
id=
"fileUpload"
data
-
id=
"fileExplorerFileUpload"
type=
"file"
onChange=
{
({
stopPropagation
,
target
})
=>
{
stopPropagation
()
uploadFile
(
target
)
}
}
multiple
/>
</
label
>
)
}
else
{
return
(
<
span
id=
{
action
}
data
-
id=
{
'fileExplorerNewFile'
+
action
}
// onclick={({ stopPropagation }) => { stopPropagation(); this[action]() }}
className=
{
'newFile '
+
icon
+
' remixui_newFile'
}
title=
{
title
}
>
</
span
>
)
}
})
}
return
<
span
className=
"remixui_menu"
>
{
items
}
</
span
>
}
const
uploadFile
=
(
target
)
=>
{
// 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
files
=
state
.
files
function
loadFile
()
{
const
fileReader
=
new
FileReader
()
fileReader
.
onload
=
async
function
(
event
)
{
if
(
helper
.
checkSpecialChars
(
file
.
name
))
{
// modalDialogCustom.alert('Special characters are not allowed')
return
}
const
success
=
await
files
.
set
(
name
,
event
.
target
.
result
)
if
(
!
success
)
{
// modalDialogCustom.alert('Failed to create file ' + name)
}
else
{
// self.events.trigger('focus', [name])
}
}
fileReader
.
readAsText
(
file
)
}
const
name
=
files
.
type
+
'/'
+
file
.
name
files
.
exists
(
name
,
(
error
,
exist
)
=>
{
if
(
error
)
console
.
log
(
error
)
if
(
!
exist
)
{
loadFile
()
}
else
{
// modalDialogCustom.confirm('Confirm overwrite', `The file ${name} already exists! Would you like to overwrite it?`, () => { loadFile() })
}
})
})
}
return
(
return
(
<
div
>
<
div
>
<
h1
>
Welcome to file-explorer!
</
h1
>
</
div
>
</
div
>
)
)
}
}
...
...
libs/remix-ui/file-explorer/src/lib/types/index.ts
0 → 100644
View file @
eb353fa5
/* eslint-disable-next-line */
export
interface
FileExplorerProps
{
localRegistry
:
any
,
files
:
any
,
menuItems
?:
string
[],
plugin
:
any
}
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