From a1b02f3756f9052dd7d2fd372062c891853e2398 Mon Sep 17 00:00:00 2001 From: Seth Samuel Date: Wed, 3 Aug 2022 13:17:45 +0100 Subject: [PATCH] drag and drop is now a library --- jest.config.js | 2 +- jest.preset.js | 4 + libs/remix-ui/draggable/.babelrc | 3 + libs/remix-ui/draggable/.eslintrc.json | 33 +++++ libs/remix-ui/draggable/README.md | 10 ++ libs/remix-ui/draggable/jest.config.js | 14 ++ libs/remix-ui/draggable/src/index.ts | 1 + .../src/lib/remix-ui-draggable.spec.ts | 7 + .../draggable/src/lib/remix-ui-draggable.tsx | 104 ++++++++++++++ libs/remix-ui/draggable/tsconfig.json | 19 +++ libs/remix-ui/draggable/tsconfig.lib.json | 11 ++ libs/remix-ui/draggable/tsconfig.spec.json | 15 ++ .../src/lib/components/file-explorer.tsx | 26 ++-- .../workspace/src/lib/contexts/index.ts | 2 + .../src/lib/providers/FileSystemProvider.tsx | 7 +- .../remix-ui/workspace/src/lib/types/index.ts | 1 - package.json | 2 +- tsconfig.base.json | 133 +++++++++++++----- 18 files changed, 340 insertions(+), 54 deletions(-) create mode 100644 jest.preset.js create mode 100644 libs/remix-ui/draggable/.babelrc create mode 100644 libs/remix-ui/draggable/.eslintrc.json create mode 100644 libs/remix-ui/draggable/README.md create mode 100644 libs/remix-ui/draggable/jest.config.js create mode 100644 libs/remix-ui/draggable/src/index.ts create mode 100644 libs/remix-ui/draggable/src/lib/remix-ui-draggable.spec.ts create mode 100644 libs/remix-ui/draggable/src/lib/remix-ui-draggable.tsx create mode 100644 libs/remix-ui/draggable/tsconfig.json create mode 100644 libs/remix-ui/draggable/tsconfig.lib.json create mode 100644 libs/remix-ui/draggable/tsconfig.spec.json diff --git a/jest.config.js b/jest.config.js index b2722cad44..117de1bcd1 100644 --- a/jest.config.js +++ b/jest.config.js @@ -21,5 +21,5 @@ module.exports = { "/../../dist/libs/remix-ws-templates/src/index.js" , "@remix-project/remixd": "/../../dist/libs/remixd/index.js" - } + },"projects": "/libs/remix-ui/draggable" }; diff --git a/jest.preset.js b/jest.preset.js new file mode 100644 index 0000000000..a7ccccd3f1 --- /dev/null +++ b/jest.preset.js @@ -0,0 +1,4 @@ + + const nxPreset = require('@nrwl/jest/preset'); + + module.exports = { ...nxPreset } \ No newline at end of file diff --git a/libs/remix-ui/draggable/.babelrc b/libs/remix-ui/draggable/.babelrc new file mode 100644 index 0000000000..cf7ddd99c6 --- /dev/null +++ b/libs/remix-ui/draggable/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]] +} diff --git a/libs/remix-ui/draggable/.eslintrc.json b/libs/remix-ui/draggable/.eslintrc.json new file mode 100644 index 0000000000..7cd4bf646b --- /dev/null +++ b/libs/remix-ui/draggable/.eslintrc.json @@ -0,0 +1,33 @@ +{ + "extends": [ + "../../../.eslintrc.json" + ], + "ignorePatterns": [ + "!**/*" + ], + "overrides": [ + { + "files": [ + "*.ts", + "*.tsx", + "*.js", + "*.jsx" + ], + "rules": {} + }, + { + "files": [ + "*.ts", + "*.tsx" + ], + "rules": {} + }, + { + "files": [ + "*.js", + "*.jsx" + ], + "rules": {} + } + ] +} \ No newline at end of file diff --git a/libs/remix-ui/draggable/README.md b/libs/remix-ui/draggable/README.md new file mode 100644 index 0000000000..5c429edbde --- /dev/null +++ b/libs/remix-ui/draggable/README.md @@ -0,0 +1,10 @@ +# remix-ui-draggable + +This library was generated with [Nx](https://nx.dev). + + +## Running unit tests + +Run `nx test remix-ui-draggable` to execute the unit tests via [Jest](https://jestjs.io). + + diff --git a/libs/remix-ui/draggable/jest.config.js b/libs/remix-ui/draggable/jest.config.js new file mode 100644 index 0000000000..1798c08a91 --- /dev/null +++ b/libs/remix-ui/draggable/jest.config.js @@ -0,0 +1,14 @@ +module.exports = { + displayName: 'remix-ui-draggable', + preset: '../../../jest.preset.js', + globals: { + 'ts-jest': { + tsconfig: '/tsconfig.spec.json', + } + }, + transform: { + '^.+\\.[tj]sx?$': 'ts-jest' + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: '../../../coverage/libs/remix-ui/draggable' +}; diff --git a/libs/remix-ui/draggable/src/index.ts b/libs/remix-ui/draggable/src/index.ts new file mode 100644 index 0000000000..9a4142a6fc --- /dev/null +++ b/libs/remix-ui/draggable/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-ui-draggable'; diff --git a/libs/remix-ui/draggable/src/lib/remix-ui-draggable.spec.ts b/libs/remix-ui/draggable/src/lib/remix-ui-draggable.spec.ts new file mode 100644 index 0000000000..26a3488b47 --- /dev/null +++ b/libs/remix-ui/draggable/src/lib/remix-ui-draggable.spec.ts @@ -0,0 +1,7 @@ +import { remixUiDraggable } from './remix-ui-draggable'; + +describe('remixUiDraggable', () => { + it('should work', () => { + expect(remixUiDraggable()).toEqual('remix-ui-draggable'); + }) +}) \ No newline at end of file diff --git a/libs/remix-ui/draggable/src/lib/remix-ui-draggable.tsx b/libs/remix-ui/draggable/src/lib/remix-ui-draggable.tsx new file mode 100644 index 0000000000..222eca1ddd --- /dev/null +++ b/libs/remix-ui/draggable/src/lib/remix-ui-draggable.tsx @@ -0,0 +1,104 @@ +import { FileType } from "libs/remix-ui/workspace/src/lib/types"; +import React, { + createContext, + ReactNode, + useContext, + useRef, + useState, +} from "react"; + +interface MoveContextType { + dragged: string; + isDraggable?: boolean; + moveFile: (dest: string, dragged: string) => void; + currentlyMoved: (path: string) => void; +} +interface DraggableType { + children: ReactNode; + file: FileType; + isDraggable?: boolean; + expandedPath: string[]; + handleClickFolder: (path: string, type: string) => void; +} + +interface DragType { + children: ReactNode; + onFileMoved: (dest: string, dragged: string) => void; +} + +export const MoveContext = createContext({ + dragged: "", + moveFile: () => {}, + currentlyMoved: () => {}, +}); + +export const Drag = (props: DragType) => { + const [dragged, setDragged] = useState(""); + + return ( + { + setDragged(() => path); + }, + }} + > + {props.children} + + ); +}; + +export const Draggable = (props: DraggableType) => { + const dragRef = useRef(), + file = props.file, + context = useContext(MoveContext); + + const handleDrop = (event: React.DragEvent) => { + event.preventDefault(); + + if (file.isDirectory) { + context.moveFile(file.path, context.dragged); + } + }; + + const handleDragover = (event: React.DragEvent) => { + //Checks if the folder is opened + event.preventDefault(); + if (file.isDirectory && !props.expandedPath.includes(file.path)) { + props.handleClickFolder(file.path, file.type); + } + }; + const handleDrag = () => { + if (context.dragged !== file.path) { + context.currentlyMoved(file.path); + } + }; + + if (props.isDraggable) { + return <>{props.children}; + } + + return ( + { + handleDrop(event); + }} + onDragStart={(event) => { + if (file) { + handleDrag(); + } + }} + onDragOver={(event) => { + if (file && file.isDirectory) { + handleDragover(event); + } + }} + > + {props.children} + + ); +}; diff --git a/libs/remix-ui/draggable/tsconfig.json b/libs/remix-ui/draggable/tsconfig.json new file mode 100644 index 0000000000..58b5a738e8 --- /dev/null +++ b/libs/remix-ui/draggable/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} \ No newline at end of file diff --git a/libs/remix-ui/draggable/tsconfig.lib.json b/libs/remix-ui/draggable/tsconfig.lib.json new file mode 100644 index 0000000000..a2268f1709 --- /dev/null +++ b/libs/remix-ui/draggable/tsconfig.lib.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "../../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "exclude": ["**/*.spec.ts"], + "include": ["**/*.ts", "src/lib/remix-ui-draggable.tsx"] +} diff --git a/libs/remix-ui/draggable/tsconfig.spec.json b/libs/remix-ui/draggable/tsconfig.spec.json new file mode 100644 index 0000000000..1798b378a9 --- /dev/null +++ b/libs/remix-ui/draggable/tsconfig.spec.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "**/*.spec.ts", + "**/*.spec.tsx", + "**/*.spec.js", + "**/*.spec.jsx", + "**/*.d.ts" + ] +} diff --git a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx index 523a7d3943..09e29bdd3e 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -10,7 +10,7 @@ import '../css/file-explorer.css' import { checkSpecialChars, extractNameFromKey, extractParentFromKey, joinPath } from '@remix-ui/helper' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { FileRender } from './file-render' -import { MoveContext } from '../contexts' +import { Drag } from '@remix-project/remix-ui/draggable' export const FileExplorer = (props: FileExplorerProps) => { const { name, contextMenuItems, removedContextMenuItems, files, fileState } = props @@ -411,21 +411,16 @@ export const FileExplorer = (props: FileExplorerProps) => { props.dispatchHandleExpandPath(expandPath) } + const handleFileMove = (dest: string, dragged:string)=>{ + try { + props.dispatchMoveFile(dragged, dest) + } catch (error) { + props.modal('Moving File Failed', 'Unexpected error while moving file: ' + dragged, 'Close', async () => {}) + } +} return ( - { - try { - props.dispatchMoveFile(dragged, dest) - } catch (error) { - props.modal('Moving File Failed', 'Unexpected error while moving file: ' + dragged, 'Close', async () => {}) - } - }, - currentlyMoved:(path)=>{ - setDragged(path) - } - }}> +
{ /> }
-
) + + ) } export default FileExplorer diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts index c0bcb7c59f..8a94a1aba1 100644 --- a/libs/remix-ui/workspace/src/lib/contexts/index.ts +++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts @@ -32,6 +32,8 @@ export const FileSystemContext = createContext<{ dispatchHandleRestoreBackup: () => Promise dispatchMoveFile: (src: string, dest: string) => Promise, dispatchCloneRepository: (url: string) => Promise + dispatchMoveFile: (src: string, dest: string) => Promise, + }>(null) interface MoveContextType{ diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index fbf1af48dc..985f531e9a 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -5,7 +5,9 @@ import { Toaster } from '@remix-ui/toaster' // eslint-disable-line // eslint-disable-next-line @typescript-eslint/no-unused-vars import { FileSystemContext } from '../contexts' import { browserReducer, browserInitialState } from '../reducers/workspace' -import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles, restoreBackupZip, moveFile, cloneRepository } from '../actions' +import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, + deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, + fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile } from '../actions' import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { Workspace } from '../remix-ui-workspace' @@ -126,11 +128,9 @@ export const FileSystemProvider = (props: WorkspaceProps) => { const dispatchCloneRepository = async (url: string) => { await cloneRepository(url) } - const dispatchMoveFile = async (src: string, dest: string) => { await moveFile(src, dest) } - useEffect(() => { dispatchInitWorkspace() }, []) @@ -247,3 +247,4 @@ export const FileSystemProvider = (props: WorkspaceProps) => { } export default FileSystemProvider + diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index cc78ca6a14..b709dc5e58 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -99,7 +99,6 @@ export interface FileExplorerProps { dispatchAddInputField:(path: string, type: 'file' | 'folder') => Promise, dispatchHandleExpandPath: (paths: string[]) => Promise dispatchMoveFile: (src: string, dest: string) => Promise, - } export interface FileExplorerMenuProps { diff --git a/package.json b/package.json index 11c4897478..c6aee5ac69 100644 --- a/package.json +++ b/package.json @@ -338,4 +338,4 @@ "yo-yo": "github:ioedeveloper/yo-yo", "yo-yoify": "^3.7.3" } -} +} \ No newline at end of file diff --git a/tsconfig.base.json b/tsconfig.base.json index 9174b23427..fa35b7d64a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -10,8 +10,14 @@ "importHelpers": true, "target": "es2015", "module": "commonjs", - "typeRoots": ["node_modules/@types"], - "lib": ["es2017", "es2019", "dom"], + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "es2019", + "dom" + ], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", @@ -22,62 +28,120 @@ "@remix-project/remix-astwalker": [ "dist/libs/remix-astwalker/src/index.js" ], - "@remix-project/remix-debug": ["dist/libs/remix-debug/src/index.js"], - "@remix-project/remix-lib": ["dist/libs/remix-lib/src/index.js"], + "@remix-project/remix-debug": [ + "dist/libs/remix-debug/src/index.js" + ], + "@remix-project/remix-lib": [ + "dist/libs/remix-lib/src/index.js" + ], "@remix-project/remix-simulator": [ "dist/libs/remix-simulator/src/index.js" ], "@remix-project/remix-solidity": [ "dist/libs/remix-solidity/src/index.js" ], - "@remix-project/remix-tests": ["dist/libs/remix-tests/src/index.js"], + "@remix-project/remix-tests": [ + "dist/libs/remix-tests/src/index.js" + ], "@remix-project/remix-url-resolver": [ "dist/libs/remix-url-resolver/src/index.js" ], "@remix-project/remix-ws-templates": [ "dist/libs/remix-ws-templates/src/index.js" ], - "@remixproject/debugger-plugin": ["apps/debugger/src/index.ts"], + "@remixproject/debugger-plugin": [ + "apps/debugger/src/index.ts" + ], "@remixproject/solidity-compiler-plugin": [ "apps/solidity-compiler/src/index.ts" ], - "@remix-project/remixd": ["dist/libs/remixd/index.js"], - "@remix-ui/tree-view": ["libs/remix-ui/tree-view/src/index.ts"], - "@remix-ui/search": ["libs/remix-ui/search/src/index.ts"], - "@remix-ui/debugger-ui": ["libs/remix-ui/debugger-ui/src/index.ts"], - "@remix-ui/utils": ["libs/remix-ui/utils/src/index.ts"], - "@remix-ui/clipboard": ["libs/remix-ui/clipboard/src/index.ts"], - "@remix-project/remix-solidity-ts": ["libs/remix-solidity/src/index.ts"], - "@remix-project/remix-lib-ts": ["libs/remix-lib/src/index.ts"], - "@remix-ui/modal-dialog": ["libs/remix-ui/modal-dialog/src/index.ts"], - "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], - "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], - "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], + "@remix-project/remixd": [ + "dist/libs/remixd/index.js" + ], + "@remix-ui/tree-view": [ + "libs/remix-ui/tree-view/src/index.ts" + ], + "@remix-ui/search": [ + "libs/remix-ui/search/src/index.ts" + ], + "@remix-ui/debugger-ui": [ + "libs/remix-ui/debugger-ui/src/index.ts" + ], + "@remix-ui/utils": [ + "libs/remix-ui/utils/src/index.ts" + ], + "@remix-ui/clipboard": [ + "libs/remix-ui/clipboard/src/index.ts" + ], + "@remix-project/remix-solidity-ts": [ + "libs/remix-solidity/src/index.ts" + ], + "@remix-project/remix-lib-ts": [ + "libs/remix-lib/src/index.ts" + ], + "@remix-ui/modal-dialog": [ + "libs/remix-ui/modal-dialog/src/index.ts" + ], + "@remix-ui/toaster": [ + "libs/remix-ui/toaster/src/index.ts" + ], + "@remix-ui/file-explorer": [ + "libs/remix-ui/file-explorer/src/index.ts" + ], + "@remix-ui/workspace": [ + "libs/remix-ui/workspace/src/index.ts" + ], "@remix-ui/static-analyser": [ "libs/remix-ui/static-analyser/src/index.ts" ], - "@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/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/renderer": ["libs/remix-ui/renderer/src/index.ts"], - "@remix-ui/terminal": ["libs/remix-ui/terminal/src/index.ts"], - "@remix-ui/plugin-manager": ["libs/remix-ui/plugin-manager/src/index.ts"], - "@remix-ui/home-tab": ["libs/remix-ui/home-tab/src/index.ts"], - "@remix-ui/editor": ["libs/remix-ui/editor/src/index.ts"], - "@remix-ui/tabs": ["libs/remix-ui/tabs/src/index.ts"], - "@remix-ui/helper": ["libs/remix-ui/helper/src/index.ts"], - "@remix-ui/app": ["libs/remix-ui/app/src/index.ts"], + "@remix-ui/renderer": [ + "libs/remix-ui/renderer/src/index.ts" + ], + "@remix-ui/terminal": [ + "libs/remix-ui/terminal/src/index.ts" + ], + "@remix-ui/plugin-manager": [ + "libs/remix-ui/plugin-manager/src/index.ts" + ], + "@remix-ui/home-tab": [ + "libs/remix-ui/home-tab/src/index.ts" + ], + "@remix-ui/editor": [ + "libs/remix-ui/editor/src/index.ts" + ], + "@remix-ui/tabs": [ + "libs/remix-ui/tabs/src/index.ts" + ], + "@remix-ui/helper": [ + "libs/remix-ui/helper/src/index.ts" + ], + "@remix-ui/app": [ + "libs/remix-ui/app/src/index.ts" + ], "@remix-ui/vertical-icons-panel": [ "libs/remix-ui/vertical-icons-panel/src/index.ts" ], - "@remix-ui/theme-module": ["libs/remix-ui/theme-module/src/index.ts"], - "@remix-ui/panel": ["libs/remix-ui/panel/src/index.ts"], + "@remix-ui/theme-module": [ + "libs/remix-ui/theme-module/src/index.ts" + ], + "@remix-ui/panel": [ + "libs/remix-ui/panel/src/index.ts" + ], "@remix-ui/editor-context-view": [ "libs/remix-ui/editor-context-view/src/index.ts" ], @@ -92,5 +156,8 @@ "@remix-ui/tooltip-popup": ["libs/remix-ui/tooltip-popup/src/index.ts"] } }, - "exclude": ["node_modules", "tmp"] -} + "exclude": [ + "node_modules", + "tmp" + ] +} \ No newline at end of file