Include pattern for context menu

pull/668/head
ioedeveloper 4 years ago
parent adcdb3d440
commit 154b95d3ae
  1. 16
      libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx
  2. 121
      libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
  3. 3
      libs/remix-ui/file-explorer/src/lib/types/index.ts

@ -4,7 +4,7 @@ import { FileExplorerContextMenuProps } from './types'
import './css/file-explorer-context-menu.css' import './css/file-explorer-context-menu.css'
export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => { export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => {
const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, extractParentFromKey, publishToGist, pageX, pageY, path, type, ...otherProps } = props const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, extractParentFromKey, publishToGist, runScript, pageX, pageY, path, type, ...otherProps } = props
const contextMenuRef = useRef(null) const contextMenuRef = useRef(null)
useEffect(() => { useEffect(() => {
@ -23,10 +23,13 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) =>
}, [pageX, pageY]) }, [pageX, pageY])
const menu = () => { const menu = () => {
return actions.filter(item => item.type.findIndex(name => { return actions.filter(item => {
if ((name === 'browser/gists') && (type === 'folder') && (extractParentFromKey(path) === name)) return true // add publish to gist for gist folders if (item.type.findIndex(name => name === type) !== -1) return true
return name === type else if (item.path.findIndex(key => key === path) !== -1) return true
}) !== -1).map((item, index) => { else if (item.extension.findIndex(ext => path.endsWith(ext)) !== -1) return true
else if (item.pattern.filter(value => path.match(new RegExp(value))).length > 0) return true
else return false
}).map((item, index) => {
return <li return <li
id={`menuitem${item.name.toLowerCase()}`} id={`menuitem${item.name.toLowerCase()}`}
key={index} key={index}
@ -49,6 +52,9 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) =>
case 'Push changes to gist': case 'Push changes to gist':
publishToGist() publishToGist()
break break
case 'Run':
runScript(path)
break
default: default:
break break
} }

@ -77,19 +77,40 @@ export const FileExplorer = (props: FileExplorerProps) => {
const files = await fetchDirectoryContent(name) const files = await fetchDirectoryContent(name)
const actions = [{ const actions = [{
name: 'New File', name: 'New File',
type: ['folder'] type: ['folder'],
path: [],
extension: [],
pattern: []
}, { }, {
name: 'New Folder', name: 'New Folder',
type: ['folder'] type: ['folder'],
path: [],
extension: [],
pattern: []
}, { }, {
name: 'Rename', name: 'Rename',
type: ['file', 'folder'] type: ['file', 'folder'],
path: [],
extension: [],
pattern: []
}, { }, {
name: 'Delete', name: 'Delete',
type: ['file', 'folder'] type: ['file', 'folder'],
path: [],
extension: [],
pattern: []
}, { }, {
name: 'Push changes to gist', name: 'Push changes to gist',
type: ['browser/gists'] type: [],
path: [],
extension: [],
pattern: ['^browser/gists/([0-9]|[a-z])*$']
}, {
name: 'Run',
type: [],
path: [],
extension: ['.js'],
pattern: []
}] }]
setState(prevState => { setState(prevState => {
@ -100,8 +121,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
useEffect(() => { useEffect(() => {
if (state.fileManager) { if (state.fileManager) {
props.filesProvider.event.register('fileExternallyChanged', fileExternallyChanged) filesProvider.event.register('fileExternallyChanged', fileExternallyChanged)
props.filesProvider.event.register('fileRenamedError', fileRenamedError) filesProvider.event.register('fileRenamedError', fileRenamedError)
} }
}, [state.fileManager]) }, [state.fileManager])
@ -125,14 +146,14 @@ export const FileExplorer = (props: FileExplorerProps) => {
useEffect(() => { useEffect(() => {
// unregister event to update state in callback // unregister event to update state in callback
if (props.filesProvider.event.registered.fileAdded) props.filesProvider.event.unregister('fileAdded', fileAdded) if (filesProvider.event.registered.fileAdded) filesProvider.event.unregister('fileAdded', fileAdded)
if (props.filesProvider.event.registered.folderAdded) props.filesProvider.event.unregister('folderAdded', folderAdded) if (filesProvider.event.registered.folderAdded) filesProvider.event.unregister('folderAdded', folderAdded)
if (props.filesProvider.event.registered.fileRemoved) props.filesProvider.event.unregister('fileRemoved', fileRemoved) if (filesProvider.event.registered.fileRemoved) filesProvider.event.unregister('fileRemoved', fileRemoved)
if (props.filesProvider.event.registered.fileRenamed) props.filesProvider.event.unregister('fileRenamed', fileRenamed) if (filesProvider.event.registered.fileRenamed) filesProvider.event.unregister('fileRenamed', fileRenamed)
props.filesProvider.event.register('fileAdded', fileAdded) filesProvider.event.register('fileAdded', fileAdded)
props.filesProvider.event.register('folderAdded', folderAdded) filesProvider.event.register('folderAdded', folderAdded)
props.filesProvider.event.register('fileRemoved', fileRemoved) filesProvider.event.register('fileRemoved', fileRemoved)
props.filesProvider.event.register('fileRenamed', fileRenamed) filesProvider.event.register('fileRenamed', fileRenamed)
}, [state.files]) }, [state.files])
const resolveDirectory = async (folderPath, dir: File[]): Promise<File[]> => { const resolveDirectory = async (folderPath, dir: File[]): Promise<File[]> => {
@ -302,64 +323,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
} }
} }
const addEmptyFile = (parentFolder: string, files: File[]): File[] => {
if (parentFolder === name) {
files.push({
path: 'browser/blank',
name: '',
isDirectory: false
})
return files
}
return files.map(file => {
if (file.child) {
if (file.path === parentFolder) {
file.child = [...file.child, {
path: file.path + '/blank',
name: '',
isDirectory: false
}]
return file
} else {
file.child = addEmptyFile(parentFolder, file.child)
return file
}
} else {
return file
}
})
}
const addEmptyFolder = (parentFolder: string, files: File[]): File[] => {
if (parentFolder === name) {
files.unshift({
path: 'browser/blank',
name: '',
isDirectory: true
})
return files
}
return files.map(file => {
if (file.child) {
if (file.path === parentFolder) {
file.child = [{
path: file.path + '/blank',
name: '',
isDirectory: true
}, ...file.child]
return file
} else {
file.child = addEmptyFolder(parentFolder, file.child)
return file
}
} else {
return file
}
})
}
const removePath = (path: string, files: File[]): File[] => { const removePath = (path: string, files: File[]): File[] => {
return files.map(file => { return files.map(file => {
if (file.path === path) { if (file.path === path) {
@ -474,7 +437,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
// pick that up via the 'fileAdded' event from the files module. // pick that up via the 'fileAdded' event from the files module.
[...target.files].forEach((file) => { [...target.files].forEach((file) => {
const files = props.filesProvider const files = filesProvider
const loadFile = (name: string): void => { const loadFile = (name: string): void => {
const fileReader = new FileReader() const fileReader = new FileReader()
@ -574,7 +537,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
// If 'id' is not defined, it is not a gist update but a creation so we have to take the files from the browser explorer. // If 'id' is not defined, it is not a gist update but a creation so we have to take the files from the browser explorer.
const folder = id ? 'browser/gists/' + id : 'browser/' const folder = id ? 'browser/gists/' + id : 'browser/'
packageFiles(props.filesProvider, folder, async (error, packaged) => { packageFiles(filesProvider, folder, async (error, packaged) => {
if (error) { if (error) {
console.log(error) console.log(error)
modal('Publish to gist Failed', 'Failed to create gist: ' + error.message, { modal('Publish to gist Failed', 'Failed to create gist: ' + error.message, {
@ -640,6 +603,13 @@ export const FileExplorer = (props: FileExplorerProps) => {
}) })
} }
const runScript = async (path: string) => {
filesProvider.get(path, (error, content: string) => {
if (error) return console.log(error)
plugin.call('scriptRunner', 'execute', content)
})
}
const handleHideModal = () => { const handleHideModal = () => {
setState(prevState => { setState(prevState => {
return { ...prevState, modalOptions: { ...state.modalOptions, hide: true } } return { ...prevState, modalOptions: { ...state.modalOptions, hide: true } }
@ -910,6 +880,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
createNewFolder={handleNewFolderInput} createNewFolder={handleNewFolderInput}
deletePath={deletePath} deletePath={deletePath}
renamePath={editModeOn} renamePath={editModeOn}
runScript={runScript}
pageX={state.focusContext.x} pageX={state.focusContext.x}
pageY={state.focusContext.y} pageY={state.focusContext.y}
path={file.path} path={file.path}

@ -25,7 +25,7 @@ export interface FileExplorerMenuProps {
} }
export interface FileExplorerContextMenuProps { export interface FileExplorerContextMenuProps {
actions: { name: string, type: string[] }[], actions: { name: string, type: string[], path: string[], extension: string[], pattern: string[] }[],
createNewFile: (folder?: string) => void, createNewFile: (folder?: string) => void,
createNewFolder: (parentFolder?: string) => void, createNewFolder: (parentFolder?: string) => void,
deletePath: (path: string) => void, deletePath: (path: string) => void,
@ -33,6 +33,7 @@ export interface FileExplorerContextMenuProps {
hideContextMenu: () => void, hideContextMenu: () => void,
extractParentFromKey?: (key: string) => string, extractParentFromKey?: (key: string) => string,
publishToGist?: () => void, publishToGist?: () => void,
runScript?: (path: string) => void,
pageX: number, pageX: number,
pageY: number, pageY: number,
path: string, path: string,

Loading…
Cancel
Save