From 882251f6487f076c2a15a7993855dd071bbee316 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Mon, 20 Sep 2021 12:02:21 +0100 Subject: [PATCH] Remove file-explorer react library --- libs/remix-ui/file-explorer/.babelrc | 4 - libs/remix-ui/file-explorer/.eslintrc | 19 - libs/remix-ui/file-explorer/README.md | 7 - libs/remix-ui/file-explorer/src/index.ts | 3 - .../lib/css/file-explorer-context-menu.css | 28 - .../src/lib/css/file-explorer.css | 56 -- .../src/lib/file-explorer-context-menu.tsx | 135 ---- .../src/lib/file-explorer-menu.tsx | 98 --- .../file-explorer/src/lib/file-explorer.tsx | 654 ------------------ .../file-explorer/src/lib/types/index.ts | 92 --- .../file-explorer/src/lib/utils/index.ts | 77 --- libs/remix-ui/file-explorer/tsconfig.json | 16 - libs/remix-ui/file-explorer/tsconfig.lib.json | 13 - .../workspace/src/lib/reducers/workspace.ts | 2 +- .../workspace/src/lib/remix-ui-workspace.tsx | 2 +- nx.json | 3 - tsconfig.base.json | 8 +- workspace.json | 19 - 18 files changed, 8 insertions(+), 1228 deletions(-) delete mode 100644 libs/remix-ui/file-explorer/.babelrc delete mode 100644 libs/remix-ui/file-explorer/.eslintrc delete mode 100644 libs/remix-ui/file-explorer/README.md delete mode 100644 libs/remix-ui/file-explorer/src/index.ts delete mode 100644 libs/remix-ui/file-explorer/src/lib/css/file-explorer-context-menu.css delete mode 100644 libs/remix-ui/file-explorer/src/lib/css/file-explorer.css delete mode 100644 libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx delete mode 100644 libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx delete mode 100644 libs/remix-ui/file-explorer/src/lib/file-explorer.tsx delete mode 100644 libs/remix-ui/file-explorer/src/lib/types/index.ts delete mode 100644 libs/remix-ui/file-explorer/src/lib/utils/index.ts delete mode 100644 libs/remix-ui/file-explorer/tsconfig.json delete mode 100644 libs/remix-ui/file-explorer/tsconfig.lib.json diff --git a/libs/remix-ui/file-explorer/.babelrc b/libs/remix-ui/file-explorer/.babelrc deleted file mode 100644 index 09d67939cc..0000000000 --- a/libs/remix-ui/file-explorer/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@nrwl/react/babel"], - "plugins": [] -} diff --git a/libs/remix-ui/file-explorer/.eslintrc b/libs/remix-ui/file-explorer/.eslintrc deleted file mode 100644 index dae5c6feeb..0000000000 --- a/libs/remix-ui/file-explorer/.eslintrc +++ /dev/null @@ -1,19 +0,0 @@ -{ - "env": { - "browser": true, - "es6": true - }, - "extends": "../../../.eslintrc", - "globals": { - "Atomics": "readonly", - "SharedArrayBuffer": "readonly" - }, - "parserOptions": { - "ecmaVersion": 11, - "sourceType": "module" - }, - "rules": { - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "error" - } -} diff --git a/libs/remix-ui/file-explorer/README.md b/libs/remix-ui/file-explorer/README.md deleted file mode 100644 index d38b498f59..0000000000 --- a/libs/remix-ui/file-explorer/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# remix-ui-file-explorer - -This library was generated with [Nx](https://nx.dev). - -## Running unit tests - -Run `nx test remix-ui-file-explorer` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/remix-ui/file-explorer/src/index.ts b/libs/remix-ui/file-explorer/src/index.ts deleted file mode 100644 index 81d8437a71..0000000000 --- a/libs/remix-ui/file-explorer/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './lib/file-explorer' -export * from './lib/types' -export * from './lib/utils' diff --git a/libs/remix-ui/file-explorer/src/lib/css/file-explorer-context-menu.css b/libs/remix-ui/file-explorer/src/lib/css/file-explorer-context-menu.css deleted file mode 100644 index f88c8825a8..0000000000 --- a/libs/remix-ui/file-explorer/src/lib/css/file-explorer-context-menu.css +++ /dev/null @@ -1,28 +0,0 @@ -.remixui_contextContainer -{ - display: block; - position: fixed; - border-radius: 2px; - z-index: 1000; - box-shadow: 0 0 4px var(--dark); -} -.remixui_contextContainer:focus { - outline: none; -} -.remixui_liitem -{ - padding: 2px; - padding-left: 6px; - cursor: pointer; - color: var(--text-dark); - background-color: var(--light); -} -.remixui_liitem:hover -{ - background-color: var(--secondary); -} -#remixui_menuitems -{ - list-style: none; - margin: 0px; -} \ No newline at end of file diff --git a/libs/remix-ui/file-explorer/src/lib/css/file-explorer.css b/libs/remix-ui/file-explorer/src/lib/css/file-explorer.css deleted file mode 100644 index 4da076bc44..0000000000 --- a/libs/remix-ui/file-explorer/src/lib/css/file-explorer.css +++ /dev/null @@ -1,56 +0,0 @@ -.remixui_label { - margin-top : 4px; -} -.remixui_leaf { - overflow : hidden; - text-overflow : ellipsis; - width : 90%; - margin-bottom : 0px; -} -.remixui_fileexplorer { - box-sizing : border-box; - user-select : none; -} -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; -} diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx deleted file mode 100644 index 53dbddde3d..0000000000 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import React, { useRef, useEffect } from 'react' // eslint-disable-line -import { action, FileExplorerContextMenuProps } from './types' - -import './css/file-explorer-context-menu.css' -import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel' - -declare global { - interface Window { - _paq: any - } -} -const _paq = window._paq = window._paq || [] //eslint-disable-line - -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 contextMenuRef = useRef(null) - useEffect(() => { - contextMenuRef.current.focus() - }, []) - - useEffect(() => { - const menuItemsContainer = contextMenuRef.current - const boundary = menuItemsContainer.getBoundingClientRect() - - if (boundary.bottom > (window.innerHeight || document.documentElement.clientHeight)) { - menuItemsContainer.style.position = 'fixed' - menuItemsContainer.style.bottom = '10px' - menuItemsContainer.style.top = null - } - }, [pageX, pageY]) - - const filterItem = (item: action) => { - /** - * if there are multiple elements focused we need to take this and all conditions must be met - * for example : 'downloadAsZip' with type ['file','folder'] will work on files and folders when multiple are selected - **/ - const nonRootFocus = focus.filter((el) => { return !(el.key === '' && el.type === 'folder') }) - if (nonRootFocus.length > 1) { - for (const element of nonRootFocus) { - if (!itemMatchesCondition(item, element.type, element.key)) return false - } - return true - } else { - return itemMatchesCondition(item, type, path) - } - } - - const itemMatchesCondition = (item: action, itemType: string, itemPath: string) => { - if (item.type && Array.isArray(item.type) && (item.type.findIndex(name => name === itemType) !== -1)) return true - else if (item.path && Array.isArray(item.path) && (item.path.findIndex(key => key === itemPath) !== -1)) return true - else if (item.extension && Array.isArray(item.extension) && (item.extension.findIndex(ext => itemPath.endsWith(ext)) !== -1)) return true - else if (item.pattern && Array.isArray(item.pattern) && (item.pattern.filter(value => itemPath.match(new RegExp(value))).length > 0)) return true - else return false - } - - const getPath = () => { - if (focus.length > 1) { - return focus.map((element) => element.key) - } else { - return path - } - } - - const menu = () => { - return actions.filter(item => filterItem(item)).map((item, index) => { - return
  • { - e.stopPropagation() - switch (item.name) { - case 'New File': - createNewFile(path) - break - case 'New Folder': - createNewFolder(path) - break - case 'Rename': - renamePath(path, type) - break - case 'Delete': - deletePath(getPath()) - break - case 'Push changes to gist': - _paq.push(['trackEvent', 'fileExplorer', 'pushToChangesoGist']) - pushChangesToGist(path, type) - break - case 'Publish folder to gist': - _paq.push(['trackEvent', 'fileExplorer', 'publishFolderToGist']) - publishFolderToGist(path, type) - break - case 'Publish file to gist': - _paq.push(['trackEvent', 'fileExplorer', 'publishFileToGist']) - publishFileToGist(path, type) - break - case 'Run': - _paq.push(['trackEvent', 'fileExplorer', 'runScript']) - runScript(path) - break - case 'Copy': - copy(path, type) - break - case 'Paste': - paste(path, type) - break - case 'Delete All': - deletePath(getPath()) - break - default: - _paq.push(['trackEvent', 'fileExplorer', 'customAction', `${item.id}/${item.name}`]) - emit && emit({ ...item, path: [path] } as customAction) - break - } - hideContextMenu() - }}>{item.label || item.name}
  • - }) - } - - return ( - - ) -} - -export default FileExplorerContextMenu diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx deleted file mode 100644 index 0b4d89686f..0000000000 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer-menu.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import React, { useState, useEffect } from 'react' //eslint-disable-line -import { FileExplorerMenuProps } from './types' - -export const FileExplorerMenu = (props: FileExplorerMenuProps) => { - const [state, setState] = useState({ - menuItems: [ - { - action: 'createNewFile', - title: 'Create New File', - icon: 'far fa-file' - }, - { - action: 'createNewFolder', - title: 'Create New Folder', - icon: 'far fa-folder' - }, - { - action: 'publishToGist', - title: 'Publish all the current workspace files (only root) to a github gist', - icon: 'fab fa-github' - }, - { - action: 'uploadFile', - title: 'Load a local file into current workspace', - icon: 'fa fa-upload' - }, - { - action: 'updateGist', - title: 'Update the current [gist] explorer', - icon: 'fab fa-github' - } - ].filter(item => props.menuItems && props.menuItems.find((name) => { return name === item.action })), - actions: {} - }) - - useEffect(() => { - const actions = { - updateGist: () => {} - } - - setState(prevState => { - return { ...prevState, actions } - }) - }, []) - - return ( - <> - { props.title } - { - state.menuItems.map(({ action, title, icon }, index) => { - if (action === 'uploadFile') { - return ( - - ) - } else { - return ( - { - e.stopPropagation() - if (action === 'createNewFile') { - props.createNewFile() - } else if (action === 'createNewFolder') { - props.createNewFolder() - } else if (action === 'publishToGist') { - props.publishToGist() - } else { - state.actions[action]() - } - }} - className={'newFile ' + icon + ' remixui_newFile'} - title={title} - key={index} - > - - ) - } - })} - - - ) -} - -export default FileExplorerMenu diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx deleted file mode 100644 index 57533c3116..0000000000 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ /dev/null @@ -1,654 +0,0 @@ -import React, { useEffect, useState, useRef, useContext } from 'react' // eslint-disable-line -// import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd' // eslint-disable-line -import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line -import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line -import { FileExplorerContextMenu } from './file-explorer-context-menu' // eslint-disable-line -import { FileExplorerProps, File, MenuItems, FileExplorerState } from './types' -import { FileSystemContext } from '@remix-ui/workspace' -import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel' -import { contextMenuActions } from './utils' - -import './css/file-explorer.css' -import { checkSpecialChars, extractParentFromKey, getPathIcon, joinPath } from '@remix-ui/helper' - -export const FileExplorer = (props: FileExplorerProps) => { - const { name, focusRoot, contextMenuItems, externalUploads, removedContextMenuItems, resetFocus, files } = props - const [state, setState] = useState({ - ctrlKey: false, - newFileName: '', - actions: contextMenuActions, - focusContext: { - element: null, - x: null, - y: null, - type: '' - }, - focusEdit: { - element: null, - type: '', - isNew: false, - lastEdit: '' - }, - expandPath: [name], - mouseOverElement: null, - showContextMenu: false, - reservedKeywords: [name, 'gist-'], - copyElement: [] - }) - const [canPaste, setCanPaste] = useState(false) - const editRef = useRef(null) - const global = useContext(FileSystemContext) - - useEffect(() => { - if (global.fs.mode === 'browser') { - setState(prevState => { - return { ...prevState, expandPath: [...new Set([...prevState.expandPath, ...global.fs.browser.expandPath])] } - }) - } else if (global.fs.mode === 'localhost') { - setState(prevState => { - return { ...prevState, expandPath: [...new Set([...prevState.expandPath, ...global.fs.localhost.expandPath])] } - }) - } - }, [global.fs.browser.expandPath, global.fs.localhost.expandPath]) - - useEffect(() => { - if (state.focusEdit.element) { - setTimeout(() => { - if (editRef && editRef.current) { - editRef.current.focus() - } - }, 0) - } - }, [state.focusEdit.element]) - - useEffect(() => { - if (focusRoot) { - global.dispatchSetFocusElement([{ key: '', type: 'folder' }]) - resetFocus(false) - } - }, [focusRoot]) - - useEffect(() => { - if (contextMenuItems) { - addMenuItems(contextMenuItems) - } - }, [contextMenuItems]) - - useEffect(() => { - if (removedContextMenuItems) { - removeMenuItems(removedContextMenuItems) - } - }, [contextMenuItems]) - - useEffect(() => { - if (global.fs.focusEdit) { - setState(prevState => { - return { ...prevState, focusEdit: { element: global.fs.focusEdit, type: 'file', isNew: true, lastEdit: null } } - }) - } - }, [global.fs.focusEdit]) - - useEffect(() => { - if (externalUploads) { - uploadFile(externalUploads) - } - }, [externalUploads]) - - useEffect(() => { - const keyPressHandler = (e: KeyboardEvent) => { - if (e.shiftKey) { - setState(prevState => { - return { ...prevState, ctrlKey: true } - }) - } - } - - const keyUpHandler = (e: KeyboardEvent) => { - if (!e.shiftKey) { - setState(prevState => { - return { ...prevState, ctrlKey: false } - }) - } - } - - document.addEventListener('keydown', keyPressHandler) - document.addEventListener('keyup', keyUpHandler) - return () => { - document.removeEventListener('keydown', keyPressHandler) - document.removeEventListener('keyup', keyUpHandler) - } - }, []) - - useEffect(() => { - if (canPaste) { - addMenuItems([{ - id: 'paste', - name: 'Paste', - type: ['folder', 'file'], - path: [], - extension: [], - pattern: [], - multiselect: false, - label: '' - }]) - } else { - removeMenuItems([{ - id: 'paste', - name: 'Paste', - type: ['folder', 'file'], - path: [], - extension: [], - pattern: [], - multiselect: false, - label: '' - }]) - } - }, [canPaste]) - - const addMenuItems = (items: MenuItems) => { - setState(prevState => { - // filter duplicate items - const actions = items.filter(({ name }) => prevState.actions.findIndex(action => action.name === name) === -1) - - return { ...prevState, actions: [...prevState.actions, ...actions] } - }) - } - - const removeMenuItems = (items: MenuItems) => { - setState(prevState => { - const actions = prevState.actions.filter(({ id, name }) => items.findIndex(item => id === item.id && name === item.name) === -1) - return { ...prevState, actions } - }) - } - - const extractNameFromKey = (key: string):string => { - const keyPath = key.split('/') - - return keyPath[keyPath.length - 1] - } - - const hasReservedKeyword = (content: string): boolean => { - if (state.reservedKeywords.findIndex(value => content.startsWith(value)) !== -1) return true - else return false - } - - const getFocusedFolder = () => { - if (global.fs.focusElement[0]) { - if (global.fs.focusElement[0].type === 'folder' && global.fs.focusElement[0].key) return global.fs.focusElement[0].key - else if (global.fs.focusElement[0].type === 'gist' && global.fs.focusElement[0].key) return global.fs.focusElement[0].key - else if (global.fs.focusElement[0].type === 'file' && global.fs.focusElement[0].key) return extractParentFromKey(global.fs.focusElement[0].key) ? extractParentFromKey(global.fs.focusElement[0].key) : name - else return name - } - } - - const createNewFile = async (newFilePath: string) => { - try { - global.dispatchCreateNewFile(newFilePath, props.name) - } catch (error) { - return global.modal('File Creation Failed', typeof error === 'string' ? error : error.message, 'Close', async () => {}) - } - } - - const createNewFolder = async (newFolderPath: string) => { - try { - global.dispatchCreateNewFolder(newFolderPath, props.name) - } catch (e) { - return global.modal('Folder Creation Failed', typeof e === 'string' ? e : e.message, 'Close', async () => {}) - } - } - - const deletePath = async (path: string[]) => { - if (global.fs.readonly) return global.toast('cannot delete file. ' + name + ' is a read only explorer') - if (!Array.isArray(path)) path = [path] - - global.modal(`Delete ${path.length > 1 ? 'items' : 'item'}`, deleteMessage(path), 'OK', () => { global.dispatchDeletePath(path) }, 'Cancel', () => {}) - } - - const renamePath = async (oldPath: string, newPath: string) => { - try { - global.dispatchRenamePath(oldPath, newPath) - } catch (error) { - global.modal('Rename File Failed', 'Unexpected error while renaming: ' + typeof error === 'string' ? error : error.message, 'Close', async () => {}) - } - } - - const uploadFile = (target) => { - const parentFolder = getFocusedFolder() - const expandPath = [...new Set([...state.expandPath, parentFolder])] - - setState(prevState => { - return { ...prevState, expandPath } - }) - global.dispatchUploadFile(target, parentFolder) - } - - const copyFile = (src: string, dest: string) => { - try { - global.dispatchCopyFile(src, dest) - } catch (error) { - global.modal('Copy File Failed', 'Unexpected error while copying file: ' + src, 'Close', async () => {}) - } - } - - const copyFolder = (src: string, dest: string) => { - try { - global.dispatchCopyFolder(src, dest) - } catch (error) { - global.modal('Copy Folder Failed', 'Unexpected error while copying folder: ' + src, 'Close', async () => {}) - } - } - - const publishToGist = (path?: string, type?: string) => { - global.modal('Create a public gist', `Are you sure you want to anonymously publish all your files in the ${name} workspace as a public gist on github.com?`, 'OK', () => toGist(path, type), 'Cancel', () => {}) - } - - const pushChangesToGist = (path?: string, type?: string) => { - global.modal('Create a public gist', 'Are you sure you want to push changes to remote gist file on github.com?', 'OK', () => toGist(path, type), 'Cancel', () => {}) - } - - const publishFolderToGist = (path?: string, type?: string) => { - global.modal('Create a public gist', `Are you sure you want to anonymously publish all your files in the ${path} folder as a public gist on github.com?`, 'OK', () => toGist(path, type), 'Cancel', () => {}) - } - - const publishFileToGist = (path?: string, type?: string) => { - global.modal('Create a public gist', `Are you sure you want to anonymously publish ${path} file as a public gist on github.com?`, 'OK', () => toGist(path, type), 'Cancel', () => {}) - } - - const toGist = (path?: string, type?: string) => { - global.dispatchPublishToGist(path, type) - } - - const runScript = async (path: string) => { - try { - global.dispatchRunScript(path) - } catch (error) { - global.toast('Run script failed') - } - } - - const emitContextMenuEvent = (cmd: customAction) => { - try { - global.dispatchEmitContextMenuEvent(cmd) - } catch (error) { - global.toast(error) - } - } - - const handleClickFile = (path: string, type: 'folder' | 'file' | 'gist') => { - path = path.indexOf(props.name + '/') === 0 ? path.replace(props.name + '/', '') : path - if (!state.ctrlKey) { - global.dispatchHandleClickFile(path, type) - } else { - if (global.fs.focusElement.findIndex(item => item.key === path) !== -1) { - const focusElement = global.fs.focusElement.filter(item => item.key !== path) - - global.dispatchSetFocusElement(focusElement) - } else { - const nonRootFocus = global.fs.focusElement.filter((el) => { return !(el.key === '' && el.type === 'folder') }) - - nonRootFocus.push({ key: path, type }) - global.dispatchSetFocusElement(nonRootFocus) - } - } - } - - const handleClickFolder = async (path: string, type: 'folder' | 'file' | 'gist') => { - if (state.ctrlKey) { - if (global.fs.focusElement.findIndex(item => item.key === path) !== -1) { - const focusElement = global.fs.focusElement.filter(item => item.key !== path) - - global.dispatchSetFocusElement(focusElement) - } else { - const nonRootFocus = global.fs.focusElement.filter((el) => { return !(el.key === '' && el.type === 'folder') }) - - nonRootFocus.push({ key: path, type }) - global.dispatchSetFocusElement(nonRootFocus) - } - } else { - let expandPath = [] - - if (!state.expandPath.includes(path)) { - expandPath = [...new Set([...state.expandPath, path])] - global.dispatchFetchDirectory(path) - } else { - expandPath = [...new Set(state.expandPath.filter(key => key && (typeof key === 'string') && !key.startsWith(path)))] - } - - global.dispatchSetFocusElement([{ key: path, type }]) - setState(prevState => { - return { ...prevState, expandPath } - }) - } - } - - const handleContextMenuFile = (pageX: number, pageY: number, path: string, content: string, type: string) => { - if (!content) return - setState(prevState => { - return { ...prevState, focusContext: { element: path, x: pageX, y: pageY, type }, focusEdit: { ...prevState.focusEdit, lastEdit: content }, showContextMenu: prevState.focusEdit.element !== path } - }) - } - - const handleContextMenuFolder = (pageX: number, pageY: number, path: string, content: string, type: string) => { - if (!content) return - setState(prevState => { - return { ...prevState, focusContext: { element: path, x: pageX, y: pageY, type }, focusEdit: { ...prevState.focusEdit, lastEdit: content }, showContextMenu: prevState.focusEdit.element !== path } - }) - } - - const hideContextMenu = () => { - setState(prevState => { - return { ...prevState, focusContext: { element: null, x: 0, y: 0, type: '' }, showContextMenu: false } - }) - } - - const editModeOn = (path: string, type: string, isNew: boolean = false) => { - if (global.fs.readonly) return - setState(prevState => { - return { ...prevState, focusEdit: { ...prevState.focusEdit, element: path, isNew, type } } - }) - } - - const editModeOff = async (content: string) => { - if (typeof content === 'string') content = content.trim() - const parentFolder = extractParentFromKey(state.focusEdit.element) - - if (!content || (content.trim() === '')) { - if (state.focusEdit.isNew) { - global.dispatchRemoveInputField(parentFolder) - setState(prevState => { - return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - }) - } else { - editRef.current.textContent = state.focusEdit.lastEdit - setState(prevState => { - return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - }) - } - } else { - if (state.focusEdit.lastEdit === content) { - editRef.current.textContent = content - return setState(prevState => { - return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - }) - } - if (checkSpecialChars(content)) { - global.modal('Validation Error', 'Special characters are not allowed', 'OK', () => {}) - } else { - if (state.focusEdit.isNew) { - if (hasReservedKeyword(content)) { - global.dispatchRemoveInputField(parentFolder) - global.modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, 'Close', () => {}) - } else { - state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) - global.dispatchRemoveInputField(parentFolder) - } - } else { - if (hasReservedKeyword(content)) { - editRef.current.textContent = state.focusEdit.lastEdit - global.modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, 'Close', () => {}) - } else { - const oldPath: string = state.focusEdit.element - const oldName = extractNameFromKey(oldPath) - const newPath = oldPath.replace(oldName, content) - - editRef.current.textContent = extractNameFromKey(oldPath) - renamePath(oldPath, newPath) - } - } - setState(prevState => { - return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - }) - } - } - } - - const handleNewFileInput = async (parentFolder?: string) => { - if (!parentFolder) parentFolder = getFocusedFolder() - const expandPath = [...new Set([...state.expandPath, parentFolder])] - - await global.dispatchAddInputField(parentFolder, 'file') - setState(prevState => { - return { ...prevState, expandPath } - }) - editModeOn(parentFolder + '/blank', 'file', true) - } - - const handleNewFolderInput = async (parentFolder?: string) => { - if (!parentFolder) parentFolder = getFocusedFolder() - else if ((parentFolder.indexOf('.sol') !== -1) || (parentFolder.indexOf('.js') !== -1)) parentFolder = extractParentFromKey(parentFolder) - const expandPath = [...new Set([...state.expandPath, parentFolder])] - - await global.dispatchAddInputField(parentFolder, 'folder') - setState(prevState => { - return { ...prevState, expandPath } - }) - editModeOn(parentFolder + '/blank', 'folder', true) - } - - const handleEditInput = (event) => { - if (event.which === 13) { - event.preventDefault() - editModeOff(editRef.current.innerText) - } - } - - const handleMouseOver = (path: string) => { - setState(prevState => { - return { ...prevState, mouseOverElement: path } - }) - } - - const handleMouseOut = () => { - setState(prevState => { - return { ...prevState, mouseOverElement: null } - }) - } - - const handleCopyClick = (path: string, type: 'folder' | 'gist' | 'file') => { - setState(prevState => { - return { ...prevState, copyElement: [{ key: path, type }] } - }) - setCanPaste(true) - global.toast(`Copied to clipboard ${path}`) - } - - const handlePasteClick = (dest: string, destType: string) => { - dest = destType === 'file' ? extractParentFromKey(dest) || props.name : dest - state.copyElement.map(({ key, type }) => { - type === 'file' ? copyFile(key, dest) : copyFolder(key, dest) - }) - } - - const deleteMessage = (path: string[]) => { - return ( -
    -
    Are you sure you want to delete {path.length > 1 ? 'these items' : 'this item'}?
    - { - path.map((item, i) => (
  • {item}
  • )) - } -
    - ) - } - - const label = (file: File) => { - const isEditable = (state.focusEdit.element === file.path) || (global.fs.focusEdit === file.path) - - return ( -
    { - e.stopPropagation() - editModeOff(editRef.current.innerText) - }} - > - - { file.name } - -
    - ) - } - - const renderFiles = (file: File, index: number) => { - if (!file || !file.path || typeof file === 'string' || typeof file === 'number' || typeof file === 'boolean') return - const labelClass = state.focusEdit.element === file.path - ? 'bg-light' : global.fs.focusElement.findIndex(item => item.key === file.path) !== -1 - ? 'bg-secondary' : state.mouseOverElement === file.path - ? 'bg-light border' : (state.focusContext.element === file.path) && (state.focusEdit.element !== file.path) - ? 'bg-light border' : '' - const icon = getPathIcon(file.path) - const spreadProps = { - onClick: (e) => e.stopPropagation() - } - - if (file.isDirectory) { - return ( - { - e.stopPropagation() - if (state.focusEdit.element !== file.path) handleClickFolder(file.path, file.type) - }} - onContextMenu={(e) => { - e.preventDefault() - e.stopPropagation() - handleContextMenuFolder(e.pageX, e.pageY, file.path, e.target.textContent, file.type) - }} - labelClass={labelClass} - controlBehaviour={ state.ctrlKey } - expand={state.expandPath.includes(file.path)} - onMouseOver={(e) => { - e.stopPropagation() - handleMouseOver(file.path) - }} - onMouseOut={(e) => { - e.stopPropagation() - if (state.mouseOverElement === file.path) handleMouseOut() - }} - > - { - file.child ? { - Object.keys(file.child).map((key, index) => { - return renderFiles(file.child[key], index) - }) - } - : - } - - ) - } else { - return ( - { - e.stopPropagation() - if (state.focusEdit.element !== file.path) handleClickFile(file.path, file.type) - }} - onContextMenu={(e) => { - e.preventDefault() - e.stopPropagation() - handleContextMenuFile(e.pageX, e.pageY, file.path, e.target.textContent, file.type) - }} - icon={icon} - labelClass={labelClass} - onMouseOver={(e) => { - e.stopPropagation() - handleMouseOver(file.path) - }} - onMouseOut={(e) => { - e.stopPropagation() - if (state.mouseOverElement === file.path) handleMouseOut() - }} - /> - ) - } - } - - return ( -
    - - { - e.stopPropagation() - if (e && (e.target as any).getAttribute('data-id') === 'fileExplorerUploadFileuploadFile') return // we don't want to let propagate the input of type file - if (e && (e.target as any).getAttribute('data-id') === 'fileExplorerFileUpload') return // we don't want to let propagate the input of type file - let expandPath = [] - - if (!state.expandPath.includes(props.name)) { - expandPath = [props.name, ...new Set([...state.expandPath])] - } else { - expandPath = [...new Set(state.expandPath.filter(key => key && (typeof key === 'string') && !key.startsWith(props.name)))] - } - setState(prevState => { - return { ...prevState, expandPath } - }) - resetFocus(true) - }}> - -
    - } - expand={true}> -
    - - { - files[props.name] && Object.keys(files[props.name]).map((key, index) => { - return renderFiles(files[props.name][key], index) - }) - } - -
    -
    - - { state.showContextMenu && - 1 ? state.actions.filter(item => item.multiselect) : state.actions.filter(item => !item.multiselect)} - hideContextMenu={hideContextMenu} - createNewFile={handleNewFileInput} - createNewFolder={handleNewFolderInput} - deletePath={deletePath} - renamePath={editModeOn} - runScript={runScript} - copy={handleCopyClick} - paste={handlePasteClick} - emit={emitContextMenuEvent} - pageX={state.focusContext.x} - pageY={state.focusContext.y} - path={state.focusContext.element} - type={state.focusContext.type} - focus={global.fs.focusElement} - onMouseOver={(e) => { - e.stopPropagation() - handleMouseOver(state.focusContext.element) - }} - pushChangesToGist={pushChangesToGist} - publishFolderToGist={publishFolderToGist} - publishFileToGist={publishFileToGist} - /> - } - - ) -} - -export default FileExplorer diff --git a/libs/remix-ui/file-explorer/src/lib/types/index.ts b/libs/remix-ui/file-explorer/src/lib/types/index.ts deleted file mode 100644 index 5d74d9ffed..0000000000 --- a/libs/remix-ui/file-explorer/src/lib/types/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel' -export type MenuItems = action[] // eslint-disable-line no-use-before-define - -/* eslint-disable-next-line */ -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 } -} - -export interface File { - path: string, - name: string, - isDirectory: boolean, - type: 'folder' | 'file' | 'gist', - child?: File[] -} - -export interface FileExplorerMenuProps { - title: string, - menuItems: string[], - createNewFile: (folder?: string) => void, - createNewFolder: (parentFolder?: string) => void, - publishToGist: (path?: string) => void, - uploadFile: (target: EventTarget & HTMLInputElement) => void -} - -export type action = { name: string, type?: Array<'folder' | 'gist' | 'file'>, path?: string[], extension?: string[], pattern?: string[], id: string, multiselect: boolean, label: string } - -export interface FileExplorerContextMenuProps { - actions: action[], - createNewFile: (folder?: string) => void, - createNewFolder: (parentFolder?: string) => void, - deletePath: (path: string | string[]) => void, - renamePath: (path: string, type: string) => void, - hideContextMenu: () => void, - publishToGist?: (path?: string, type?: string) => void, - pushChangesToGist?: (path?: string, type?: string) => void, - publishFolderToGist?: (path?: string, type?: string) => void, - publishFileToGist?: (path?: string, type?: string) => void, - runScript?: (path: string) => void, - emit?: (cmd: customAction) => void, - pageX: number, - pageY: number, - path: string, - type: string, - focus: {key:string, type:string}[], - onMouseOver?: (...args) => void, - copy?: (path: string, type: string) => void, - paste?: (destination: string, type: string) => void -} - -export interface FileExplorerState { - ctrlKey: boolean - newFileName: string - actions: { - id: string - name: string - type?: Array<'folder' | 'gist' | 'file'> - path?: string[] - extension?: string[] - pattern?: string[] - multiselect: boolean - label: string - }[] - focusContext: { - element: string - x: number - y: number - type: string - } - focusEdit: { - element: string - type: string - isNew: boolean - lastEdit: string - } - expandPath: string[] - mouseOverElement: string - showContextMenu: boolean - reservedKeywords: string[] - copyElement: { - key: string - type: 'folder' | 'gist' | 'file' - }[] - } diff --git a/libs/remix-ui/file-explorer/src/lib/utils/index.ts b/libs/remix-ui/file-explorer/src/lib/utils/index.ts deleted file mode 100644 index 56a7453de9..0000000000 --- a/libs/remix-ui/file-explorer/src/lib/utils/index.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { MenuItems } from '../types' - -export const extractNameFromKey = (key: string): string => { - const keyPath = key.split('/') - - return keyPath[keyPath.length - 1] -} - -export const extractParentFromKey = (key: string):string => { - if (!key) return - const keyPath = key.split('/') - keyPath.pop() - - return keyPath.join('/') -} - -export const contextMenuActions: MenuItems = [{ - id: 'newFile', - name: 'New File', - type: ['folder', 'gist'], - multiselect: false, - label: '' -}, { - id: 'newFolder', - name: 'New Folder', - type: ['folder', 'gist'], - multiselect: false, - label: '' -}, { - id: 'rename', - name: 'Rename', - type: ['file', 'folder'], - multiselect: false, - label: '' -}, { - id: 'delete', - name: 'Delete', - type: ['file', 'folder', 'gist'], - multiselect: false, - label: '' -}, { - id: 'run', - name: 'Run', - extension: ['.js'], - multiselect: false, - label: '' -}, { - id: 'pushChangesToGist', - name: 'Push changes to gist', - type: ['gist'], - multiselect: false, - label: '' -}, { - id: 'publishFolderToGist', - name: 'Publish folder to gist', - type: ['folder'], - multiselect: false, - label: '' -}, { - id: 'publishFileToGist', - name: 'Publish file to gist', - type: ['file'], - multiselect: false, - label: '' -}, { - id: 'copy', - name: 'Copy', - type: ['folder', 'file'], - multiselect: false, - label: '' -}, { - id: 'deleteAll', - name: 'Delete All', - type: ['folder', 'file'], - multiselect: true, - label: '' -}] diff --git a/libs/remix-ui/file-explorer/tsconfig.json b/libs/remix-ui/file-explorer/tsconfig.json deleted file mode 100644 index d52e31ad74..0000000000 --- a/libs/remix-ui/file-explorer/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "jsx": "react", - "allowJs": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.lib.json" - } - ] -} diff --git a/libs/remix-ui/file-explorer/tsconfig.lib.json b/libs/remix-ui/file-explorer/tsconfig.lib.json deleted file mode 100644 index b560bc4dec..0000000000 --- a/libs/remix-ui/file-explorer/tsconfig.lib.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": ["node"] - }, - "files": [ - "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", - "../../../node_modules/@nrwl/react/typings/image.d.ts" - ], - "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], - "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] -} diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index 27a50b5955..1904e37d8c 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -1,4 +1,4 @@ -import { extractNameFromKey, File } from '@remix-ui/file-explorer' +import { extractNameFromKey } from '@remix-ui/helper' import * as _ from 'lodash' interface Action { type: string diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index a0eb50820c..a2bf940253 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useRef, useContext } from 'react' // eslint-disable-line -import { FileExplorer } from '@remix-ui/file-explorer' // eslint-disable-line +import { FileExplorer } from './components/file-explorer' // eslint-disable-line import './remix-ui-workspace.css' import { WorkspaceProps, WorkspaceState } from './types' import { FileSystemContext } from './contexts' diff --git a/nx.json b/nx.json index a5cae4682b..be231f010c 100644 --- a/nx.json +++ b/nx.json @@ -88,9 +88,6 @@ "remix-ui-toaster": { "tags": [] }, - "remix-ui-file-explorer": { - "tags": [] - }, "debugger": { "tags": [] }, diff --git a/tsconfig.base.json b/tsconfig.base.json index 07d0225fe0..7121d2e13b 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -45,8 +45,12 @@ "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"], "@remix-ui/settings": ["libs/remix-ui/settings/src/index.ts"], "@remix-project/core-plugin": ["libs/remix-core-plugin/src/index.ts"], - "@remix-ui/solidity-compiler": ["libs/remix-ui/solidity-compiler/src/index.ts"], - "@remix-ui/publish-to-storage": ["libs/remix-ui/publish-to-storage/src/index.ts"], + "@remix-ui/solidity-compiler": [ + "libs/remix-ui/solidity-compiler/src/index.ts" + ], + "@remix-ui/publish-to-storage": [ + "libs/remix-ui/publish-to-storage/src/index.ts" + ], "@remix-ui/plugin-manager": ["libs/remix-ui/plugin-manager/src/index.ts"], "@remix-ui/renderer": ["libs/remix-ui/renderer/src/index.ts"], "@remix-ui/terminal": ["libs/remix-ui/terminal/src/index.ts"], diff --git a/workspace.json b/workspace.json index 890d74e2fc..f1496361d6 100644 --- a/workspace.json +++ b/workspace.json @@ -623,25 +623,6 @@ } } }, - "remix-ui-file-explorer": { - "root": "libs/remix-ui/file-explorer", - "sourceRoot": "libs/remix-ui/file-explorer/src", - "projectType": "library", - "schematics": {}, - "architect": { - "lint": { - "builder": "@nrwl/linter:lint", - "options": { - "linter": "eslint", - "tsConfig": ["libs/remix-ui/file-explorer/tsconfig.lib.json"], - "exclude": [ - "**/node_modules/**", - "!libs/remix-ui/file-explorer/**/*" - ] - } - } - } - }, "debugger": { "root": "apps/debugger", "sourceRoot": "apps/debugger/src",