|
|
@ -27,6 +27,9 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
element: null, |
|
|
|
element: null, |
|
|
|
x: null, |
|
|
|
x: null, |
|
|
|
y: null |
|
|
|
y: null |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
focusEdit: { |
|
|
|
|
|
|
|
element: null |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
@ -127,9 +130,7 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const createNewFile = (parentFolder?: string) => { |
|
|
|
const createNewFile = (parentFolder?: string) => { |
|
|
|
console.log('parentFolderBefore: ', parentFolder) |
|
|
|
|
|
|
|
if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key : extractParentFromKey(state.focusElement[0].key) : name |
|
|
|
if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key : extractParentFromKey(state.focusElement[0].key) : name |
|
|
|
console.log('parentFolderAfter: ', parentFolder) |
|
|
|
|
|
|
|
// const self = this
|
|
|
|
// const self = this
|
|
|
|
// modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => {
|
|
|
|
// modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => {
|
|
|
|
// if (!input) input = 'New file'
|
|
|
|
// if (!input) input = 'New file'
|
|
|
@ -152,10 +153,8 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const createNewFolder = async (parentFolder?: string) => { |
|
|
|
const createNewFolder = async (parentFolder?: string) => { |
|
|
|
console.log('parentFolderBefore: ', parentFolder) |
|
|
|
|
|
|
|
if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key : extractParentFromKey(state.focusElement[0].key) : name |
|
|
|
if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key : extractParentFromKey(state.focusElement[0].key) : name |
|
|
|
else if (parentFolder.indexOf('.sol') !== -1) parentFolder = extractParentFromKey(parentFolder) |
|
|
|
else if (parentFolder.indexOf('.sol') !== -1) parentFolder = extractParentFromKey(parentFolder) |
|
|
|
console.log('parentFolderAfter: ', parentFolder) |
|
|
|
|
|
|
|
// const self = this
|
|
|
|
// const self = this
|
|
|
|
// modalDialogCustom.prompt('Create new folder', '', 'New folder', (input) => {
|
|
|
|
// modalDialogCustom.prompt('Create new folder', '', 'New folder', (input) => {
|
|
|
|
// if (!input) {
|
|
|
|
// if (!input) {
|
|
|
@ -178,6 +177,39 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
// }, null, true)
|
|
|
|
// }, null, true)
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const deletePath = async (path: string) => { |
|
|
|
|
|
|
|
// if (self.files.isReadOnly(key)) { return tooltip('cannot delete file. ' + self.files.type + ' is a read only explorer') }
|
|
|
|
|
|
|
|
if (files.isReadOnly(path)) return |
|
|
|
|
|
|
|
// const currentFilename = extractNameFromKey(path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// modalDialogCustom.confirm(
|
|
|
|
|
|
|
|
// 'Delete file', `Are you sure you want to delete ${currentFilename} file?`,
|
|
|
|
|
|
|
|
// async () => {
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
const fileManager = state.fileManager |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await fileManager.remove(path) |
|
|
|
|
|
|
|
const files = removePath(path, state.files) |
|
|
|
|
|
|
|
const updatedFiles = files.filter(file => file) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setState(prevState => { |
|
|
|
|
|
|
|
return { ...prevState, files: updatedFiles } |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
console.log('e: ', e) |
|
|
|
|
|
|
|
// tooltip(`Failed to remove file ${key}.`)
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// () => {}
|
|
|
|
|
|
|
|
// )
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const renamePath = async (path: string) => { |
|
|
|
|
|
|
|
// if (self.files.isReadOnly(key)) { return tooltip('cannot rename folder. ' + self.files.type + ' is a read only explorer') }
|
|
|
|
|
|
|
|
if (files.isReadOnly(path)) return |
|
|
|
|
|
|
|
editModeOn(path) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const addFile = async (parentFolder: string, newFileName: string) => { |
|
|
|
const addFile = async (parentFolder: string, newFileName: string) => { |
|
|
|
if (parentFolder === name) { |
|
|
|
if (parentFolder === name) { |
|
|
|
setState(prevState => { |
|
|
|
setState(prevState => { |
|
|
@ -225,6 +257,21 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const removePath = (path: string, files: File[]): File[] => { |
|
|
|
|
|
|
|
return files.map(file => { |
|
|
|
|
|
|
|
if (file.path === path) { |
|
|
|
|
|
|
|
return null |
|
|
|
|
|
|
|
} else if (file.child) { |
|
|
|
|
|
|
|
const childFiles = removePath(path, file.child) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
file.child = childFiles.filter(file => file) |
|
|
|
|
|
|
|
return file |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return file |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// self._components = {}
|
|
|
|
// self._components = {}
|
|
|
|
// self._components.registry = localRegistry || globalRegistry
|
|
|
|
// self._components.registry = localRegistry || globalRegistry
|
|
|
|
// self._deps = {
|
|
|
|
// self._deps = {
|
|
|
@ -344,7 +391,6 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const handleContextMenuFolder = (pageX: number, pageY: number, path: string) => { |
|
|
|
const handleContextMenuFolder = (pageX: number, pageY: number, path: string) => { |
|
|
|
console.log('path: ', path) |
|
|
|
|
|
|
|
setState(prevState => { |
|
|
|
setState(prevState => { |
|
|
|
return { ...prevState, focusContext: { element: path, x: pageX, y: pageY } } |
|
|
|
return { ...prevState, focusContext: { element: path, x: pageX, y: pageY } } |
|
|
|
}) |
|
|
|
}) |
|
|
@ -356,94 +402,101 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const editModeOn = (path) => { |
|
|
|
|
|
|
|
setState(prevState => { |
|
|
|
|
|
|
|
return { ...prevState, focusEdit: { element: path } } |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const editModeOff = (path) => { |
|
|
|
|
|
|
|
setState(prevState => { |
|
|
|
|
|
|
|
return { ...prevState, focusEdit: { element: null } } |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const renderFiles = (file: File, index: number) => { |
|
|
|
const renderFiles = (file: File, index: number) => { |
|
|
|
if (file.isDirectory) { |
|
|
|
if (file.isDirectory) { |
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<Droppable droppableId={file.path} key={index}> |
|
|
|
<> |
|
|
|
{(provided) => ( |
|
|
|
<TreeViewItem |
|
|
|
<> |
|
|
|
id={`treeViewItem${file.path}`} |
|
|
|
<TreeViewItem |
|
|
|
iconX='pr-3 far fa-folder' |
|
|
|
{ ...provided.droppableProps } |
|
|
|
iconY='pr-3 far fa-folder-open' |
|
|
|
innerRef={ provided.innerRef } |
|
|
|
key={`${file.path + index}`} |
|
|
|
id={`treeViewItem${file.path}`} |
|
|
|
label={label(file)} |
|
|
|
iconX='pr-3 far fa-folder' |
|
|
|
onClick={(e) => { |
|
|
|
iconY='pr-3 far fa-folder-open' |
|
|
|
e.stopPropagation() |
|
|
|
key={`${file.path + index}`} |
|
|
|
handleClickFolder(file.path) |
|
|
|
label={label(file)} |
|
|
|
}} |
|
|
|
onClick={(e) => { |
|
|
|
onContextMenu={(e) => { |
|
|
|
e.stopPropagation() |
|
|
|
e.preventDefault() |
|
|
|
handleClickFolder(file.path) |
|
|
|
e.stopPropagation() |
|
|
|
}} |
|
|
|
handleContextMenuFolder(e.pageX, e.pageY, file.path) |
|
|
|
onContextMenu={(e) => { |
|
|
|
}} |
|
|
|
e.preventDefault() |
|
|
|
labelClass={ state.focusEdit.element === file.path ? 'bg-light' : state.focusElement.findIndex(item => item.key === file.path) !== -1 ? 'bg-secondary' : '' } |
|
|
|
e.stopPropagation() |
|
|
|
editable={state.focusEdit.element === file.path} |
|
|
|
handleContextMenuFolder(e.pageX, e.pageY, file.path) |
|
|
|
onBlur={() => editModeOff(file.path)} |
|
|
|
}} |
|
|
|
controlBehaviour={ state.ctrlKey } |
|
|
|
labelClass={ state.focusElement.findIndex(item => item.key === file.path) !== -1 ? 'bg-secondary' : '' } |
|
|
|
> |
|
|
|
controlBehaviour={ state.ctrlKey } |
|
|
|
{ |
|
|
|
> |
|
|
|
file.child ? <TreeView id={`treeView${file.path}`} key={index}>{ |
|
|
|
{ |
|
|
|
file.child.map((file, index) => { |
|
|
|
file.child ? <TreeView id={`treeView${file.path}`} key={index}>{ |
|
|
|
return renderFiles(file, index) |
|
|
|
file.child.map((file, index) => { |
|
|
|
}) |
|
|
|
return renderFiles(file, index) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
</TreeView> : <TreeView id={`treeView${file.path}`} key={index} /> |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
{ provided.placeholder } |
|
|
|
|
|
|
|
</TreeViewItem> |
|
|
|
|
|
|
|
{ (state.focusContext.element === file.path) && |
|
|
|
|
|
|
|
<FileExplorerContextMenu |
|
|
|
|
|
|
|
actions={ state.actions.filter(item => item.type.findIndex(name => name === 'folder') !== -1) } |
|
|
|
|
|
|
|
hideContextMenu={hideContextMenu} |
|
|
|
|
|
|
|
createNewFile={createNewFile} |
|
|
|
|
|
|
|
createNewFolder={createNewFolder} |
|
|
|
|
|
|
|
pageX={state.focusContext.x} |
|
|
|
|
|
|
|
pageY={state.focusContext.y} |
|
|
|
|
|
|
|
folder={file.path} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
</> |
|
|
|
</TreeView> : <TreeView id={`treeView${file.path}`} key={index} /> |
|
|
|
)} |
|
|
|
} |
|
|
|
</Droppable> |
|
|
|
</TreeViewItem> |
|
|
|
|
|
|
|
{ (state.focusContext.element === file.path) && |
|
|
|
|
|
|
|
<FileExplorerContextMenu |
|
|
|
|
|
|
|
actions={ state.actions.filter(item => item.type.findIndex(name => name === 'folder') !== -1) } |
|
|
|
|
|
|
|
hideContextMenu={hideContextMenu} |
|
|
|
|
|
|
|
createNewFile={createNewFile} |
|
|
|
|
|
|
|
createNewFolder={createNewFolder} |
|
|
|
|
|
|
|
deletePath={deletePath} |
|
|
|
|
|
|
|
renamePath={renamePath} |
|
|
|
|
|
|
|
pageX={state.focusContext.x} |
|
|
|
|
|
|
|
pageY={state.focusContext.y} |
|
|
|
|
|
|
|
path={file.path} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
</> |
|
|
|
) |
|
|
|
) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<Draggable draggableId={file.path} index={index} key={index}> |
|
|
|
<> |
|
|
|
{(provided) => ( |
|
|
|
<TreeViewItem |
|
|
|
<> |
|
|
|
id={`treeViewItem${file.path}`} |
|
|
|
<TreeViewItem |
|
|
|
key={index} |
|
|
|
{...provided.draggableProps} |
|
|
|
label={label(file)} |
|
|
|
{...provided.dragHandleProps} |
|
|
|
onClick={(e) => { |
|
|
|
innerRef={provided.innerRef} |
|
|
|
e.stopPropagation() |
|
|
|
id={`treeViewItem${file.path}`} |
|
|
|
if (state.focusEdit.element !== file.path) handleClickFile(file.path) |
|
|
|
key={index} |
|
|
|
}} |
|
|
|
label={label(file)} |
|
|
|
onContextMenu={(e) => { |
|
|
|
onClick={(e) => { |
|
|
|
e.preventDefault() |
|
|
|
e.stopPropagation() |
|
|
|
e.stopPropagation() |
|
|
|
handleClickFile(file.path) |
|
|
|
handleContextMenuFile(e.pageX, e.pageY, file.path) |
|
|
|
}} |
|
|
|
}} |
|
|
|
onContextMenu={(e) => { |
|
|
|
icon='fa fa-file' |
|
|
|
e.preventDefault() |
|
|
|
labelClass={ state.focusEdit.element === file.path ? 'bg-light' : state.focusElement.findIndex(item => item.key === file.path) !== -1 ? 'bg-secondary' : '' } |
|
|
|
e.stopPropagation() |
|
|
|
editable={state.focusEdit.element === file.path} |
|
|
|
handleContextMenuFile(e.pageX, e.pageY, file.path) |
|
|
|
onBlur={() => editModeOff(file.path)} |
|
|
|
}} |
|
|
|
/> |
|
|
|
icon='fa fa-file' |
|
|
|
{ (state.focusContext.element === file.path) && |
|
|
|
labelClass={ state.focusElement.findIndex(item => item.key === file.path) !== -1 ? 'bg-secondary' : '' } |
|
|
|
<FileExplorerContextMenu |
|
|
|
/> |
|
|
|
actions={ state.actions.filter(item => item.type.findIndex(name => name === 'file') !== -1) } |
|
|
|
{ (state.focusContext.element === file.path) && |
|
|
|
hideContextMenu={hideContextMenu} |
|
|
|
<FileExplorerContextMenu |
|
|
|
createNewFile={createNewFile} |
|
|
|
actions={ state.actions.filter(item => item.type.findIndex(name => name === 'file') !== -1) } |
|
|
|
createNewFolder={createNewFolder} |
|
|
|
hideContextMenu={hideContextMenu} |
|
|
|
deletePath={deletePath} |
|
|
|
createNewFile={createNewFile} |
|
|
|
renamePath={renamePath} |
|
|
|
createNewFolder={createNewFolder} |
|
|
|
pageX={state.focusContext.x} |
|
|
|
pageX={state.focusContext.x} |
|
|
|
pageY={state.focusContext.y} |
|
|
|
pageY={state.focusContext.y} |
|
|
|
path={file.path} |
|
|
|
/> |
|
|
|
/> |
|
|
|
} |
|
|
|
} |
|
|
|
</> |
|
|
|
</> |
|
|
|
)} |
|
|
|
|
|
|
|
</Draggable> |
|
|
|
|
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -480,24 +533,15 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
/> |
|
|
|
/> |
|
|
|
} |
|
|
|
} |
|
|
|
expand={true}> |
|
|
|
expand={true}> |
|
|
|
<DragDropContext onDragEnd={onDragEnd}> |
|
|
|
<div> |
|
|
|
<Droppable droppableId='droppableTreeView'> |
|
|
|
<TreeView id='treeViewMenu'> |
|
|
|
{(provided) => ( |
|
|
|
{ |
|
|
|
<div |
|
|
|
state.files.map((file, index) => { |
|
|
|
{ ...provided.droppableProps } |
|
|
|
return renderFiles(file, index) |
|
|
|
ref={ provided.innerRef }> |
|
|
|
}) |
|
|
|
<TreeView id='treeViewMenu'> |
|
|
|
} |
|
|
|
{ |
|
|
|
</TreeView> |
|
|
|
state.files.map((file, index) => { |
|
|
|
</div> |
|
|
|
return renderFiles(file, index) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
</TreeView> |
|
|
|
|
|
|
|
{ provided.placeholder } |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
)} |
|
|
|
|
|
|
|
</Droppable> |
|
|
|
|
|
|
|
</DragDropContext> |
|
|
|
|
|
|
|
</TreeViewItem> |
|
|
|
</TreeViewItem> |
|
|
|
</TreeView> |
|
|
|
</TreeView> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|