Merge pull request #1182 from ethereum/contextmenu

added customactions
pull/1281/head
David Disu 3 years ago committed by GitHub
commit c40274f64c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      apps/remix-ide/src/app/panels/file-panel.js
  2. 3
      libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx
  3. 28
      libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
  4. 7
      libs/remix-ui/file-explorer/src/lib/types/index.ts
  5. 6
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  6. 3
      package.json

@ -34,7 +34,7 @@ const modalDialogCustom = require('../ui/modal-dialog-custom')
const profile = { const profile = {
name: 'filePanel', name: 'filePanel',
displayName: 'File explorers', displayName: 'File explorers',
methods: ['createNewFile', 'uploadFile', 'getCurrentWorkspace', 'getWorkspaces', 'createWorkspace', 'setWorkspace'], methods: ['createNewFile', 'uploadFile', 'getCurrentWorkspace', 'getWorkspaces', 'createWorkspace', 'setWorkspace', 'registerContextMenuItem'],
events: ['setWorkspace', 'renameWorkspace', 'deleteWorkspace', 'createWorkspace'], events: ['setWorkspace', 'renameWorkspace', 'deleteWorkspace', 'createWorkspace'],
icon: 'assets/img/fileManager.webp', icon: 'assets/img/fileManager.webp',
description: ' - ', description: ' - ',
@ -60,9 +60,11 @@ module.exports = class Filepanel extends ViewPlugin {
this.gitHandle = new GitHandle() this.gitHandle = new GitHandle()
this.hardhatHandle = new HardhatHandle() this.hardhatHandle = new HardhatHandle()
this.registeredMenuItems = [] this.registeredMenuItems = []
this.removedMenuItems = []
this.request = {} this.request = {}
this.workspaces = [] this.workspaces = []
this.initialWorkspace = null this.initialWorkspace = null
this.appManager = appManager
} }
render () { render () {
@ -88,6 +90,7 @@ module.exports = class Filepanel extends ViewPlugin {
request={this.request} request={this.request}
workspaces={this.workspaces} workspaces={this.workspaces}
registeredMenuItems={this.registeredMenuItems} registeredMenuItems={this.registeredMenuItems}
removedMenuItems={this.removedMenuItems}
initialWorkspace={this.initialWorkspace} initialWorkspace={this.initialWorkspace}
/> />
, this.el) , this.el)
@ -101,8 +104,22 @@ module.exports = class Filepanel extends ViewPlugin {
if (!item) throw new Error('Invalid register context menu argument') if (!item) throw new Error('Invalid register context menu argument')
if (!item.name || !item.id) throw new Error('Item name and id is mandatory') if (!item.name || !item.id) throw new Error('Item name and id is mandatory')
if (!item.type && !item.path && !item.extension && !item.pattern) throw new Error('Invalid file matching criteria provided') if (!item.type && !item.path && !item.extension && !item.pattern) throw new Error('Invalid file matching criteria provided')
if (this.registeredMenuItems.filter((o) => {
return o.id === item.id & o.name === item.name
}).length) throw new Error(`Action ${item.name} already exists on ${item.id}`)
this.registeredMenuItems = [...this.registeredMenuItems, item] this.registeredMenuItems = [...this.registeredMenuItems, item]
this.removedMenuItems = this.removedMenuItems.filter(menuItem => item.id !== menuItem.id)
this.renderComponent()
}
removePluginActions (plugin) {
this.registeredMenuItems = this.registeredMenuItems.filter((item) => {
if (item.id !== plugin.name || item.sticky === true) return true
else {
this.removedMenuItems.push(item)
return false
}
})
this.renderComponent() this.renderComponent()
} }
@ -163,6 +180,9 @@ module.exports = class Filepanel extends ViewPlugin {
} }
return return
} }
const self = this
this.appManager.on('manager', 'pluginDeactivated', self.removePluginActions.bind(this))
// insert example contracts if there are no files to show // insert example contracts if there are no files to show
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this._deps.fileProviders.browser.resolveDirectory('/', async (error, filesList) => { this._deps.fileProviders.browser.resolveDirectory('/', async (error, filesList) => {

@ -2,6 +2,7 @@ import React, { useRef, useEffect } from 'react' // eslint-disable-line
import { action, FileExplorerContextMenuProps } from './types' 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'
export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => { export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => {
const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, pushChangesToGist, publishFileToGist, publishFolderToGist, copy, paste, runScript, emit, pageX, pageY, path, type, focus, ...otherProps } = props const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, pushChangesToGist, publishFileToGist, publishFolderToGist, copy, paste, runScript, emit, pageX, pageY, path, type, focus, ...otherProps } = props
@ -96,7 +97,7 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) =>
deletePath(getPath()) deletePath(getPath())
break break
default: default:
emit && emit(item.id, getPath()) emit && emit({ ...item, path: [path] } as customAction)
break break
} }
hideContextMenu() hideContextMenu()

@ -11,13 +11,14 @@ import { fileSystemReducer, fileSystemInitialState } from './reducers/fileSystem
import { fetchDirectory, init, resolveDirectory, addInputField, removeInputField } from './actions/fileSystem' import { fetchDirectory, init, resolveDirectory, addInputField, removeInputField } from './actions/fileSystem'
import * as helper from '../../../../../apps/remix-ide/src/lib/helper' import * as helper from '../../../../../apps/remix-ide/src/lib/helper'
import QueryParams from '../../../../../apps/remix-ide/src/lib/query-params' import QueryParams from '../../../../../apps/remix-ide/src/lib/query-params'
import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel'
import './css/file-explorer.css' import './css/file-explorer.css'
const queryParams = new QueryParams() const queryParams = new QueryParams()
export const FileExplorer = (props: FileExplorerProps) => { export const FileExplorer = (props: FileExplorerProps) => {
const { name, registry, plugin, focusRoot, contextMenuItems, displayInput, externalUploads } = props const { name, registry, plugin, focusRoot, contextMenuItems, displayInput, externalUploads, removedContextMenuItems } = props
const [state, setState] = useState({ const [state, setState] = useState({
focusElement: [{ focusElement: [{
key: '', key: '',
@ -203,6 +204,12 @@ export const FileExplorer = (props: FileExplorerProps) => {
} }
}, [contextMenuItems]) }, [contextMenuItems])
useEffect(() => {
if (removedContextMenuItems) {
removeMenuItems(removedContextMenuItems)
}
}, [contextMenuItems])
useEffect(() => { useEffect(() => {
if (displayInput) { if (displayInput) {
handleNewFileInput() handleNewFileInput()
@ -278,7 +285,15 @@ export const FileExplorer = (props: FileExplorerProps) => {
multiselect: false multiselect: false
}]) }])
} else { } else {
removeMenuItems(['paste']) removeMenuItems([{
id: 'paste',
name: 'Paste',
type: ['folder', 'file'],
path: [],
extension: [],
pattern: [],
multiselect: false
}])
} }
}, [canPaste]) }, [canPaste])
@ -291,10 +306,9 @@ export const FileExplorer = (props: FileExplorerProps) => {
}) })
} }
const removeMenuItems = (ids: string[]) => { const removeMenuItems = (items: MenuItems) => {
setState(prevState => { setState(prevState => {
const actions = prevState.actions.filter(({ id }) => ids.findIndex(value => value === id) === -1) const actions = prevState.actions.filter(({ id, name }) => items.findIndex(item => id === item.id && name === item.name) === -1)
return { ...prevState, actions } return { ...prevState, actions }
}) })
} }
@ -601,8 +615,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
}) })
} }
const emitContextMenuEvent = (id: string, path: string | string[]) => { const emitContextMenuEvent = (cmd: customAction) => {
plugin.emit(id, path) plugin.call(cmd.id, cmd.name, cmd)
} }
const handleHideModal = () => { const handleHideModal = () => {

@ -1,3 +1,5 @@
import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel'
/* eslint-disable-next-line */ /* eslint-disable-next-line */
export interface FileExplorerProps { export interface FileExplorerProps {
name: string, name: string,
@ -7,8 +9,9 @@ export interface FileExplorerProps {
plugin: any, plugin: any,
focusRoot: boolean, focusRoot: boolean,
contextMenuItems: MenuItems, contextMenuItems: MenuItems,
removedContextMenuItems: MenuItems,
displayInput?: boolean, displayInput?: boolean,
externalUploads?: EventTarget & HTMLInputElement externalUploads?: EventTarget & HTMLInputElement,
} }
export interface File { export interface File {
@ -44,7 +47,7 @@ export interface FileExplorerContextMenuProps {
publishFolderToGist?: (path?: string, type?: string) => void, publishFolderToGist?: (path?: string, type?: string) => void,
publishFileToGist?: (path?: string, type?: string) => void, publishFileToGist?: (path?: string, type?: string) => void,
runScript?: (path: string) => void, runScript?: (path: string) => void,
emit?: (id: string, path: string | string[]) => void, emit?: (cmd: customAction) => void,
pageX: number, pageX: number,
pageY: number, pageY: number,
path: string, path: string,

@ -3,6 +3,7 @@ import { FileExplorer } from '@remix-ui/file-explorer' // eslint-disable-line
import './remix-ui-workspace.css' import './remix-ui-workspace.css'
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
import { Toaster } from '@remix-ui/toaster'// eslint-disable-line import { Toaster } from '@remix-ui/toaster'// eslint-disable-line
import { MenuItems } from 'libs/remix-ui/file-explorer/src/lib/types'
/* eslint-disable-next-line */ /* eslint-disable-next-line */
export interface WorkspaceProps { export interface WorkspaceProps {
@ -20,7 +21,8 @@ export interface WorkspaceProps {
plugin: any // plugin call and resetFocus plugin: any // plugin call and resetFocus
request: any // api request, request: any // api request,
workspaces: any, workspaces: any,
registeredMenuItems: [] // menu items registeredMenuItems: MenuItems // menu items
removedMenuItems: MenuItems
initialWorkspace: string initialWorkspace: string
} }
@ -409,6 +411,7 @@ export const Workspace = (props: WorkspaceProps) => {
plugin={props.plugin} plugin={props.plugin}
focusRoot={state.reset} focusRoot={state.reset}
contextMenuItems={props.registeredMenuItems} contextMenuItems={props.registeredMenuItems}
removedContextMenuItems={props.removedMenuItems}
displayInput={state.displayNewFile} displayInput={state.displayNewFile}
externalUploads={state.uploadFileEvent} externalUploads={state.uploadFileEvent}
/> />
@ -426,6 +429,7 @@ export const Workspace = (props: WorkspaceProps) => {
plugin={props.plugin} plugin={props.plugin}
focusRoot={state.reset} focusRoot={state.reset}
contextMenuItems={props.registeredMenuItems} contextMenuItems={props.registeredMenuItems}
removedContextMenuItems={props.removedMenuItems}
/> />
} }
</div> </div>

@ -163,7 +163,6 @@
"jquery": "^3.3.1", "jquery": "^3.3.1",
"jszip": "^3.6.0", "jszip": "^3.6.0",
"latest-version": "^5.1.0", "latest-version": "^5.1.0",
"lodash": "^4.17.21",
"merge": "^1.2.0", "merge": "^1.2.0",
"npm-install-version": "^6.0.2", "npm-install-version": "^6.0.2",
"react": "16.13.1", "react": "16.13.1",
@ -178,7 +177,7 @@
"web3": "1.2.4", "web3": "1.2.4",
"winston": "^3.3.3", "winston": "^3.3.3",
"ws": "^7.3.0" "ws": "^7.3.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.4.5", "@babel/core": "^7.4.5",
"@babel/plugin-transform-modules-amd": "^7.10.4", "@babel/plugin-transform-modules-amd": "^7.10.4",

Loading…
Cancel
Save