From d293af79d9f84e661e5c9c66921b05fbcff289aa Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 25 Apr 2024 08:54:50 +0100 Subject: [PATCH 01/60] add types --- .../remix-ui/workspace/src/lib/types/index.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index 1d8b515759..f70b7611e3 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -342,3 +342,25 @@ export interface Action { export type Actions = {[A in keyof ActionPayloadTypes]: Action}[keyof ActionPayloadTypes] export type WorkspaceElement = 'folder' | 'file' | 'workspace' + +export interface FlatTreeDropProps { + moveFile: (dest: string, src: string) => void + moveFolder: (dest: string, src: string) => void + moveFolderSilently: (dest: string, src: string) => Promise + moveFileSilently: (dest: string, src: string) => Promise + getFlatTreeItem: (path: string) => FileType + handleClickFolder: (path: string, type: string) => void + dragSource: FileType + children: React.ReactNode + expandPath: string[] +} + +export type DragStructure = { + position: { + top: number + left: number + } + path: string + type: string + content: string +} From cc46dfab89641289ba6a3620dac1b50e3bbf9b62 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 25 Apr 2024 08:55:52 +0100 Subject: [PATCH 02/60] pass props --- .../workspace/src/lib/components/flat-tree.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx index db5a960cbe..da9eb1aca5 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx @@ -1,4 +1,4 @@ -import React, { SyntheticEvent, useEffect, useRef, useState, RefObject, useMemo } from 'react' +import React, { SyntheticEvent, useEffect, useRef, useState, RefObject, useMemo, useContext } from 'react' import { Popover } from 'react-bootstrap' import { FileType, WorkspaceElement } from '../types' import { getPathIcon } from '@remix-ui/helper'; @@ -9,6 +9,7 @@ import { getEventTarget } from '../utils/getEventTarget'; import { fileDecoration, FileDecorationIcons } from '@remix-ui/file-decorators'; import { FileHoverIcons } from './file-explorer-hovericons'; import { deletePath } from '../actions'; +import { FileSystemContext } from '../contexts'; export default function useOnScreen(ref: RefObject) { @@ -37,6 +38,8 @@ interface FlatTreeProps { handleClickFolder: (path: string, type: string) => void moveFile: (dest: string, src: string) => void moveFolder: (dest: string, src: string) => void + moveFolderSilently: (dest: string, src: string) => Promise + moveFileSilently: (dest: string, src: string) => Promise fileState: fileDecoration[] createNewFile?: any createNewFolder?: any @@ -50,7 +53,7 @@ let mouseTimer: any = { } export const FlatTree = (props: FlatTreeProps) => { - const { files, flatTree, expandPath, focusEdit, editModeOff, handleTreeClick, moveFile, moveFolder, fileState, focusElement, handleClickFolder, deletePath, editPath } = props + const { files, flatTree, expandPath, focusEdit, editModeOff, handleTreeClick, moveFile, moveFolder, fileState, focusElement, handleClickFolder, deletePath, moveFileSilently, moveFolderSilently } = props const [hover, setHover] = useState('') const [mouseOverTarget, setMouseOverTarget] = useState<{ path: string, @@ -249,6 +252,8 @@ export const FlatTree = (props: FlatTreeProps) => { getFlatTreeItem={getFlatTreeItem} moveFile={moveFile} moveFolder={moveFolder} + moveFolderSilently={moveFolderSilently} + moveFileSilently={moveFileSilently} handleClickFolder={handleClickFolder} expandPath={expandPath} > @@ -257,7 +262,8 @@ export const FlatTree = (props: FlatTreeProps) => { onClick={handleTreeClick} onMouseLeave={onMouseLeave} onMouseMove={onMouseMove} - onContextMenu={handleContextMenu}> + onContextMenu={handleContextMenu} + > { showMouseOverTarget && mouseOverTarget && !isDragging && Date: Thu, 25 Apr 2024 08:56:41 +0100 Subject: [PATCH 03/60] add functions for silent moving of files --- .../src/lib/components/file-explorer.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) 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 e3b301901c..211994d118 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -292,6 +292,50 @@ export const FileExplorer = (props: FileExplorerProps) => { props.dispatchHandleExpandPath(expandPath) } + /** + * This offers the ability to move a file to a new location + * without showing a modal dialong to the user. + * @param dest path of the destination + * @param src path of the source + * @returns {void} + */ + const moveFileSilently = async (dest: string, src: string) => { + if (dest.length === 0 || src.length === 0) return + if (await moveFileIsAllowed(src, dest) === false) return + try { + props.dispatchMoveFile(src, dest) + } catch (error) { + props.modal( + intl.formatMessage({ id: 'filePanel.movingFileFailed' }), + intl.formatMessage({ id: 'filePanel.movingFileFailedMsg' }, { src }), + intl.formatMessage({ id: 'filePanel.close' }), + async () => { } + ) + } + } + + /** + * This offers the ability to move a folder to a new location + * without showing a modal dialong to the user. + * @param dest path of the destination + * @param src path of the source + * @returns {void} + */ + const moveFolderSilently = async (dest: string, src: string) => { + if (dest.length === 0 || src.length === 0) return + if (await moveFolderIsAllowed(src, dest) === false) return + try { + props.dispatchMoveFolder(src, dest) + } catch (error) { + props.modal( + intl.formatMessage({ id: 'filePanel.movingFolderFailed' }), + intl.formatMessage({ id: 'filePanel.movingFolderFailedMsg' }, { src }), + intl.formatMessage({ id: 'filePanel.close' }), + async () => { } + ) + } + } + const handleFileMove = async (dest: string, src: string) => { if (await moveFileIsAllowed(src, dest) === false) return try { @@ -403,6 +447,8 @@ export const FileExplorer = (props: FileExplorerProps) => { handleContextMenu={handleContextMenu} moveFile={handleFileMove} moveFolder={handleFolderMove} + moveFolderSilently={moveFolderSilently} + moveFileSilently={moveFileSilently} handleClickFolder={handleClickFolder} createNewFile={props.createNewFile} createNewFolder={props.createNewFolder} From f75a36bffbc9dd7c1b2e77219d1fb22486f07e29 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 25 Apr 2024 08:57:41 +0100 Subject: [PATCH 04/60] consume function to move files silently --- .../src/lib/components/flat-tree-drop.tsx | 101 ++++++++++++++++-- 1 file changed, 90 insertions(+), 11 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index 92de1ff8f1..d7aaee0fe9 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -1,16 +1,11 @@ -import React, { SyntheticEvent, useEffect, useRef, useState } from 'react' -import { FileType } from '../types' +import React, { SyntheticEvent, useContext, useEffect, useRef, useState } from 'react' +import { DragStructure, FileType, FlatTreeDropProps } from '../types' import { getEventTarget } from '../utils/getEventTarget' import { extractParentFromKey } from '@remix-ui/helper' -interface FlatTreeDropProps { - moveFile: (dest: string, src: string) => void - moveFolder: (dest: string, src: string) => void - getFlatTreeItem: (path: string) => FileType - handleClickFolder: (path: string, type: string) => void - dragSource: FileType - children: React.ReactNode - expandPath: string[] -} +import { FileSystemContext } from '../contexts' + + + export const FlatTreeDrop = (props: FlatTreeDropProps) => { const { getFlatTreeItem, dragSource, moveFile, moveFolder, handleClickFolder, expandPath } = props @@ -18,10 +13,21 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { const [timer, setTimer] = useState() // folder to open const [folderToOpen, setFolderToOpen] = useState() + const globalFEContext = useContext(FileSystemContext) + const [selectedItems, setSelectedItems] = useState([]) + +<<<<<<< HEAD +======= + useEffect(() => { + }, [globalFEContext.fs.focusElement.length]) + +>>>>>>> consume function to move files silently const onDragOver = async (e: SyntheticEvent) => { e.preventDefault() + const target = await getEventTarget(e) + buildMultiSelectedItemProfiles(target) if (!target || !target.path) { clearTimeout(timer) setFolderToOpen(null) @@ -50,6 +56,8 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { event.preventDefault() const target = await getEventTarget(event) + const items = buildMultiSelectedItemProfiles(target) + console.log('onDrop', { items, target }) let dragDestination: any if (!target || !target.path) { dragDestination = { @@ -62,20 +70,91 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { if (dragDestination.isDirectory) { if (dragSource.isDirectory) { moveFolder(dragDestination.path, dragSource.path) + await moveFoldersSilently(items, dragDestination.path) } else { moveFile(dragDestination.path, dragSource.path) + await moveFilesSilently(items, dragDestination.path) } } else { const path = extractParentFromKey(dragDestination.path) || '/' if (dragSource.isDirectory) { moveFolder(path, dragSource.path) + await moveFoldersSilently(items, dragDestination.path) } else { moveFile(path, dragSource.path) + await moveFilesSilently(items, dragDestination.path) } } } + /** + * When multiple files are selected in FileExplorer, + * and these files are dragged to a target folder, + * this function will build the profile of each selected item + * in FileExplorer so they can be moved when dropped + * @param target - Initial target item in FileExplorer + * @returns - {DragStructure} Array of selected items + */ + const buildMultiSelectedItemProfiles = (target: { + path: string + type: string + content: string + position: { + top: number + left: number + } + }) => { + const selectItems = [] + document.querySelectorAll('li.bg-secondary.li_tv').forEach(item => { + + const dragTarget = { + position: { top: target?.position.top || 0, left: target?.position.left || 0 }, + path: item.getAttribute('data-path') || item.getAttribute('data-label-path') || '', + type: item.getAttribute('data-type') || item.getAttribute('data-label-type') || '', + content: item.textContent || '' + } + selectItems.push(dragTarget) + }) + // console.log('selectItem', { selectItems, target }) + return selectItems + } + + /** + * Moves items silently without showing a confirmation dialog. + * @param items MultiSelected items built into a DragStructure profile + * @param dragSource source FileExplorer item being dragged. + * @returns Promise + */ + const moveFilesSilently = async (items: DragStructure[], targetPath: string) => { + console.log('moveItemsSilently', { items, targetPath }) + const promises = items.filter(item => item.path !== targetPath) + .map(async (item) => { + if (item.type === 'file') { + await props.moveFileSilently(item.path, targetPath) + } + }) + await Promise.all(promises) + } + + /** + * Moves items silently without showing a confirmation dialog. + * @param items MultiSelected items built into a DragStructure profile + * @param dragSource source FileExplorer item being dragged. + * @returns Promise + */ + const moveFoldersSilently = async (items: DragStructure[], targetPath: string) => { + console.log('moveItemsSilently', { items, targetPath }) + const promises = items.filter(item => item.path !== targetPath) + .map(async (item) => { + if (item.type === 'folder') { + await props.moveFolderSilently(item.path, targetPath) + } + }) + await Promise.all(promises) + } + + return (
Date: Thu, 25 Apr 2024 09:23:21 +0100 Subject: [PATCH 05/60] remove console log --- libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index d7aaee0fe9..5c5bec50b4 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -116,7 +116,6 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { } selectItems.push(dragTarget) }) - // console.log('selectItem', { selectItems, target }) return selectItems } From ae9af3bb951706560f705ed12bd51310ec1d23b8 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 25 Apr 2024 10:23:25 +0100 Subject: [PATCH 06/60] fix parameter order --- .../workspace/src/lib/components/flat-tree-drop.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index 5c5bec50b4..0fc8f38637 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -107,7 +107,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { }) => { const selectItems = [] document.querySelectorAll('li.bg-secondary.li_tv').forEach(item => { - + item.classList.add('dragging') const dragTarget = { position: { top: target?.position.top || 0, left: target?.position.left || 0 }, path: item.getAttribute('data-path') || item.getAttribute('data-label-path') || '', @@ -130,7 +130,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { const promises = items.filter(item => item.path !== targetPath) .map(async (item) => { if (item.type === 'file') { - await props.moveFileSilently(item.path, targetPath) + await props.moveFileSilently(targetPath, item.path) } }) await Promise.all(promises) @@ -147,7 +147,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { const promises = items.filter(item => item.path !== targetPath) .map(async (item) => { if (item.type === 'folder') { - await props.moveFolderSilently(item.path, targetPath) + await props.moveFolderSilently(targetPath, item.path) } }) await Promise.all(promises) From c12ea724a6afa48aabe3beed53c1e76396dc67cf Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 25 Apr 2024 10:51:08 +0100 Subject: [PATCH 07/60] add jsdoc comments --- apps/remix-ide/src/app/files/fileManager.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index bf0564d814..be40d899ab 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -927,6 +927,12 @@ class FileManager extends Plugin { return exists } + /** + * Check if a file can be moved + * @param src source file + * @param dest destination file + * @returns {boolean} true if the file is allowed to be moved + */ async moveFileIsAllowed (src: string, dest: string) { try { src = this.normalize(src) @@ -949,6 +955,12 @@ class FileManager extends Plugin { } } + /** + * Check if a folder can be moved + * @param src source folder + * @param dest destination folder + * @returns {boolean} true if the folder is allowed to be moved + */ async moveDirIsAllowed (src: string, dest: string) { try { src = this.normalize(src) From 6db2efec50a43ef712841b1f969759da79196390 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 25 Apr 2024 10:51:36 +0100 Subject: [PATCH 08/60] add functions to handle array of source paths --- .../workspace/src/lib/actions/index.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index b4480e2019..772bdff1a6 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -656,3 +656,21 @@ export const moveFolderIsAllowed = async (src: string, dest: string) => { return isAllowed } +export const moveFilesIsAllowed = async (src: string[], dest: string) => { + const fileManager = plugin.fileManager + const boolArray: boolean[] = [] + for (const srcFile of src) { + boolArray.push(await fileManager.moveFileIsAllowed(srcFile, dest)) + } + return boolArray.every(p => p === true) || false +} + +export const moveFoldersIsAllowed = async (src: string[], dest: string) => { + const fileManager = plugin.fileManager + const boolArray: boolean[] = [] + for (const srcFile of src) { + boolArray.push(await fileManager.moveDirIsAllowed(srcFile, dest)) + } + return boolArray.every(p => p === true) || false +} + From 45ece83528f7bffb8f17027874de373ddcff58ab Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 25 Apr 2024 10:51:55 +0100 Subject: [PATCH 09/60] add dispatch functions to handle multiple files --- .../src/lib/providers/FileSystemProvider.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index 481991dd12..1b2057be99 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -201,10 +201,22 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await moveFile(src, dest) } + const dispatchMoveFiles = async (src: string[], dest: string) => { + for (const path of src) { + await moveFile(path, dest) + } + } + const dispatchMoveFolder = async (src: string, dest: string) => { await moveFolder(src, dest) } + const dispatchMoveFolders = async (src: string[], dest: string) => { + for (const path of src) { + await moveFolder(path, dest) + } + } + const dispatchShowAllBranches = async () => { await showAllBranches() } @@ -367,7 +379,9 @@ export const FileSystemProvider = (props: WorkspaceProps) => { dispatchHandleRestoreBackup, dispatchCloneRepository, dispatchMoveFile, + dispatchMoveFiles, dispatchMoveFolder, + dispatchMoveFolders, dispatchShowAllBranches, dispatchSwitchToBranch, dispatchCreateNewBranch, From 1f59ab14dd1f22554fd2010e5c186c4df96c6cf6 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 25 Apr 2024 11:28:53 +0100 Subject: [PATCH 10/60] refactor to handle string array --- .../src/lib/components/file-explorer.tsx | 36 +++++++++++-------- .../src/lib/components/flat-tree-drop.tsx | 12 +++---- .../src/lib/components/flat-tree.tsx | 8 ++--- .../workspace/src/lib/contexts/index.ts | 2 ++ .../workspace/src/lib/remix-ui-workspace.tsx | 4 +++ .../remix-ui/workspace/src/lib/types/index.ts | 10 +++--- 6 files changed, 43 insertions(+), 29 deletions(-) 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 211994d118..c423ab4987 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -9,7 +9,7 @@ import '../css/file-explorer.css' import { checkSpecialChars, extractNameFromKey, extractParentFromKey, getPathIcon, joinPath } from '@remix-ui/helper' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { ROOT_PATH } from '../utils/constants' -import { moveFileIsAllowed, moveFolderIsAllowed } from '../actions' +import { moveFileIsAllowed, moveFilesIsAllowed, moveFolderIsAllowed, moveFoldersIsAllowed } from '../actions' import { FlatTree } from './flat-tree' export const FileExplorer = (props: FileExplorerProps) => { @@ -299,11 +299,13 @@ export const FileExplorer = (props: FileExplorerProps) => { * @param src path of the source * @returns {void} */ - const moveFileSilently = async (dest: string, src: string) => { - if (dest.length === 0 || src.length === 0) return - if (await moveFileIsAllowed(src, dest) === false) return + const moveFileSilently = async (dest: string, sourcesrc: string[]) => { + if (dest.length === 0 || sourcesrc.length === 0) return + if (await moveFilesIsAllowed(sourcesrc, dest) === false) return + + const src = sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') try { - props.dispatchMoveFile(src, dest) + props.dispatchMoveFiles(sourcesrc, dest) } catch (error) { props.modal( intl.formatMessage({ id: 'filePanel.movingFileFailed' }), @@ -321,11 +323,13 @@ export const FileExplorer = (props: FileExplorerProps) => { * @param src path of the source * @returns {void} */ - const moveFolderSilently = async (dest: string, src: string) => { - if (dest.length === 0 || src.length === 0) return - if (await moveFolderIsAllowed(src, dest) === false) return + const moveFolderSilently = async (dest: string, sourcesrc: string[]) => { + if (dest.length === 0 || sourcesrc.length === 0) return + if (await moveFoldersIsAllowed(sourcesrc, dest) === false) return + + const src = sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') try { - props.dispatchMoveFolder(src, dest) + props.dispatchMoveFolders(sourcesrc, dest) } catch (error) { props.modal( intl.formatMessage({ id: 'filePanel.movingFolderFailed' }), @@ -336,14 +340,15 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - const handleFileMove = async (dest: string, src: string) => { - if (await moveFileIsAllowed(src, dest) === false) return + const handleFileMove = async (dest: string, sourcesrc: string[]) => { + if (await moveFilesIsAllowed(sourcesrc, dest) === false) return + const src = sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') try { props.modal( intl.formatMessage({ id: 'filePanel.moveFile' }), intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }), intl.formatMessage({ id: 'filePanel.yes' }), - () => props.dispatchMoveFile(src, dest), + () => props.dispatchMoveFiles(sourcesrc, dest), intl.formatMessage({ id: 'filePanel.cancel' }), () => { } ) @@ -357,14 +362,15 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - const handleFolderMove = async (dest: string, src: string) => { - if (await moveFolderIsAllowed(src, dest) === false) return + const handleFolderMove = async (dest: string, sourcesrc: string[]) => { + if (await moveFoldersIsAllowed(sourcesrc, dest) === false) return + const src = sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') try { props.modal( intl.formatMessage({ id: 'filePanel.moveFile' }), intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }), intl.formatMessage({ id: 'filePanel.yes' }), - () => props.dispatchMoveFolder(src, dest), + () => props.dispatchMoveFolders(sourcesrc, dest), intl.formatMessage({ id: 'filePanel.cancel' }), () => { } ) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index 0fc8f38637..e4d3d558d2 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -69,20 +69,20 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { } if (dragDestination.isDirectory) { if (dragSource.isDirectory) { - moveFolder(dragDestination.path, dragSource.path) + moveFolder(dragDestination.path, [dragSource.path]) await moveFoldersSilently(items, dragDestination.path) } else { - moveFile(dragDestination.path, dragSource.path) + moveFile(dragDestination.path, [dragSource.path]) await moveFilesSilently(items, dragDestination.path) } } else { const path = extractParentFromKey(dragDestination.path) || '/' if (dragSource.isDirectory) { - moveFolder(path, dragSource.path) + moveFolder(path, [dragSource.path]) await moveFoldersSilently(items, dragDestination.path) } else { - moveFile(path, dragSource.path) + moveFile(path, [dragSource.path]) await moveFilesSilently(items, dragDestination.path) } } @@ -130,7 +130,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { const promises = items.filter(item => item.path !== targetPath) .map(async (item) => { if (item.type === 'file') { - await props.moveFileSilently(targetPath, item.path) + await props.moveFileSilently(targetPath, [item.path]) } }) await Promise.all(promises) @@ -147,7 +147,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { const promises = items.filter(item => item.path !== targetPath) .map(async (item) => { if (item.type === 'folder') { - await props.moveFolderSilently(targetPath, item.path) + await props.moveFolderSilently(targetPath, [item.path]) } }) await Promise.all(promises) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx index da9eb1aca5..af7048c932 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx @@ -36,10 +36,10 @@ interface FlatTreeProps { handleContextMenu: (pageX: number, pageY: number, path: string, content: string, type: string) => void handleTreeClick: (e: SyntheticEvent) => void handleClickFolder: (path: string, type: string) => void - moveFile: (dest: string, src: string) => void - moveFolder: (dest: string, src: string) => void - moveFolderSilently: (dest: string, src: string) => Promise - moveFileSilently: (dest: string, src: string) => Promise + moveFile: (dest: string, src: string[]) => void + moveFolder: (dest: string, src: string[]) => void + moveFolderSilently: (dest: string, src: string[]) => Promise + moveFileSilently: (dest: string, src: string[]) => Promise fileState: fileDecoration[] createNewFile?: any createNewFolder?: any diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts index 7e297ffb0d..5b58bfba61 100644 --- a/libs/remix-ui/workspace/src/lib/contexts/index.ts +++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts @@ -39,6 +39,8 @@ export const FileSystemContext = createContext<{ dispatchCloneRepository: (url: string) => Promise, dispatchMoveFile: (src: string, dest: string) => Promise, dispatchMoveFolder: (src: string, dest: string) => Promise, + dispatchMoveFiles: (src: string[], dest: string) => Promise, + dispatchMoveFolders: (src: string[], dest: string) => Promise, dispatchShowAllBranches: () => Promise, dispatchSwitchToBranch: (branch: string) => Promise, dispatchCreateNewBranch: (branch: string) => Promise, 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 3da9063576..29a52a8654 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -1251,7 +1251,9 @@ export function Workspace() { dispatchAddInputField={global.dispatchAddInputField} dispatchHandleExpandPath={global.dispatchHandleExpandPath} dispatchMoveFile={global.dispatchMoveFile} + dispatchMoveFiles={global.dispatchMoveFiles} dispatchMoveFolder={global.dispatchMoveFolder} + dispatchMoveFolders={global.dispatchMoveFolders} handleCopyClick={handleCopyClick} handlePasteClick={handlePasteClick} addMenuItems={addMenuItems} @@ -1317,7 +1319,9 @@ export function Workspace() { dispatchAddInputField={global.dispatchAddInputField} dispatchHandleExpandPath={global.dispatchHandleExpandPath} dispatchMoveFile={global.dispatchMoveFile} + dispatchMoveFiles={global.dispatchMoveFiles} dispatchMoveFolder={global.dispatchMoveFolder} + dispatchMoveFolders={global.dispatchMoveFolders} handleCopyClick={handleCopyClick} handlePasteClick={handlePasteClick} addMenuItems={addMenuItems} diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index f70b7611e3..95f3380b99 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -135,6 +135,8 @@ export interface FileExplorerProps { dispatchAddInputField:(path: string, type: 'file' | 'folder') => Promise, dispatchHandleExpandPath: (paths: string[]) => Promise, dispatchMoveFile: (src: string, dest: string) => Promise, + dispatchMoveFiles: (src: string[], dest: string) => Promise, + dispatchMoveFolders: (src: string[], dest: string) => Promise, dispatchMoveFolder: (src: string, dest: string) => Promise, handlePasteClick: (dest: string, destType: string) => void handleCopyClick: (path: string, type: WorkspaceElement) => void @@ -344,10 +346,10 @@ export type Actions = {[A in keyof ActionPayloadTypes]: Action}[keyof ActionP export type WorkspaceElement = 'folder' | 'file' | 'workspace' export interface FlatTreeDropProps { - moveFile: (dest: string, src: string) => void - moveFolder: (dest: string, src: string) => void - moveFolderSilently: (dest: string, src: string) => Promise - moveFileSilently: (dest: string, src: string) => Promise + moveFile: (dest: string, src: string[]) => void + moveFolder: (dest: string, src: string[]) => void + moveFolderSilently: (dest: string, src: string[]) => Promise + moveFileSilently: (dest: string, src: string[]) => Promise getFlatTreeItem: (path: string) => FileType handleClickFolder: (path: string, type: string) => void dragSource: FileType From 12619db60d82fe389ebc6a2cfbe065072e94e90d Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 25 Apr 2024 12:16:34 +0100 Subject: [PATCH 11/60] add state to track file names being moved. --- .../workspace/src/lib/components/file-explorer.tsx | 10 ++++++++-- .../workspace/src/lib/components/flat-tree-drop.tsx | 6 +++++- .../workspace/src/lib/components/flat-tree.tsx | 6 ++++-- libs/remix-ui/workspace/src/lib/types/index.ts | 3 ++- 4 files changed, 19 insertions(+), 6 deletions(-) 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 c423ab4987..b3eaeddab1 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -35,6 +35,7 @@ export const FileExplorer = (props: FileExplorerProps) => { const [state, setState] = useState(workspaceState) // const [isPending, startTransition] = useTransition(); const treeRef = useRef(null) + const [filesSelected, setFilesSelected] = useState([]) useEffect(() => { if (contextMenuItems) { @@ -342,7 +343,9 @@ export const FileExplorer = (props: FileExplorerProps) => { const handleFileMove = async (dest: string, sourcesrc: string[]) => { if (await moveFilesIsAllowed(sourcesrc, dest) === false) return - const src = sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') + const files = filesSelected && filesSelected.length > 0 && filesSelected.join('\n') + console.log(files) + const src = files.length > 0 ? files : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') try { props.modal( intl.formatMessage({ id: 'filePanel.moveFile' }), @@ -364,7 +367,9 @@ export const FileExplorer = (props: FileExplorerProps) => { const handleFolderMove = async (dest: string, sourcesrc: string[]) => { if (await moveFoldersIsAllowed(sourcesrc, dest) === false) return - const src = sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') + const folders = filesSelected && filesSelected.length > 0 && filesSelected.join('\n') + console.log(folders) + const src = folders.length > 0 ? folders : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') try { props.modal( intl.formatMessage({ id: 'filePanel.moveFile' }), @@ -455,6 +460,7 @@ export const FileExplorer = (props: FileExplorerProps) => { moveFolder={handleFolderMove} moveFolderSilently={moveFolderSilently} moveFileSilently={moveFileSilently} + setFilesSelected={setFilesSelected} handleClickFolder={handleClickFolder} createNewFile={props.createNewFile} createNewFolder={props.createNewFolder} diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index e4d3d558d2..26ace2dce1 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -57,7 +57,11 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { const target = await getEventTarget(event) const items = buildMultiSelectedItemProfiles(target) - console.log('onDrop', { items, target }) + const filePaths = [] + filePaths.push(target && target.path ? target.path : '/') + items.forEach((item) => filePaths.push(item.path)) + props.setFilesSelected(filePaths) + console.log('onDrop', { items, target, filePaths }) let dragDestination: any if (!target || !target.path) { dragDestination = { diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx index af7048c932..1d22b912f6 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx @@ -1,4 +1,4 @@ -import React, { SyntheticEvent, useEffect, useRef, useState, RefObject, useMemo, useContext } from 'react' +import React, { SyntheticEvent, useEffect, useRef, useState, RefObject, useMemo, useContext, Dispatch } from 'react' import { Popover } from 'react-bootstrap' import { FileType, WorkspaceElement } from '../types' import { getPathIcon } from '@remix-ui/helper'; @@ -40,6 +40,7 @@ interface FlatTreeProps { moveFolder: (dest: string, src: string[]) => void moveFolderSilently: (dest: string, src: string[]) => Promise moveFileSilently: (dest: string, src: string[]) => Promise + setFilesSelected: Dispatch> fileState: fileDecoration[] createNewFile?: any createNewFolder?: any @@ -53,7 +54,7 @@ let mouseTimer: any = { } export const FlatTree = (props: FlatTreeProps) => { - const { files, flatTree, expandPath, focusEdit, editModeOff, handleTreeClick, moveFile, moveFolder, fileState, focusElement, handleClickFolder, deletePath, moveFileSilently, moveFolderSilently } = props + const { files, flatTree, expandPath, focusEdit, editModeOff, handleTreeClick, moveFile, moveFolder, fileState, focusElement, handleClickFolder, deletePath, moveFileSilently, moveFolderSilently, setFilesSelected } = props const [hover, setHover] = useState('') const [mouseOverTarget, setMouseOverTarget] = useState<{ path: string, @@ -254,6 +255,7 @@ export const FlatTree = (props: FlatTreeProps) => { moveFolder={moveFolder} moveFolderSilently={moveFolderSilently} moveFileSilently={moveFileSilently} + setFilesSelected={setFilesSelected} handleClickFolder={handleClickFolder} expandPath={expandPath} > diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index 95f3380b99..4fa993bc70 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -1,5 +1,5 @@ /* eslint-disable @nrwl/nx/enforce-module-boundaries */ -import React from 'react' +import React, { Dispatch } from 'react' import { customAction } from '@remixproject/plugin-api' import { fileDecoration } from '@remix-ui/file-decorators' import { RemixAppManager } from 'libs/remix-ui/plugin-manager/src/types' @@ -350,6 +350,7 @@ export interface FlatTreeDropProps { moveFolder: (dest: string, src: string[]) => void moveFolderSilently: (dest: string, src: string[]) => Promise moveFileSilently: (dest: string, src: string[]) => Promise + setFilesSelected: Dispatch> getFlatTreeItem: (path: string) => FileType handleClickFolder: (path: string, type: string) => void dragSource: FileType From f233290bcd6b0751ba2f90ce58ebb69cb5bca0a5 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Fri, 26 Apr 2024 13:15:36 +0100 Subject: [PATCH 12/60] fix exception when files have been dropped on destination --- .../workspace/src/lib/components/flat-tree-drop.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index 26ace2dce1..652b1e43f8 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -58,10 +58,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { const target = await getEventTarget(event) const items = buildMultiSelectedItemProfiles(target) const filePaths = [] - filePaths.push(target && target.path ? target.path : '/') - items.forEach((item) => filePaths.push(item.path)) - props.setFilesSelected(filePaths) - console.log('onDrop', { items, target, filePaths }) + // console.log('onDrop', { items, target, filePaths }) let dragDestination: any if (!target || !target.path) { dragDestination = { @@ -71,6 +68,11 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { } else { dragDestination = getFlatTreeItem(target.path) } + + filePaths.push(dragDestination.path) + items.forEach((item) => filePaths.push(item.path)) + props.setFilesSelected(filePaths) + if (dragDestination.isDirectory) { if (dragSource.isDirectory) { moveFolder(dragDestination.path, [dragSource.path]) From 28072ed6e157553b10417333ce88edbd6d1fe591 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 09:35:17 +0100 Subject: [PATCH 13/60] changes after review --- .../src/lib/components/file-explorer.tsx | 19 ++++++++++--------- .../src/lib/components/flat-tree-drop.tsx | 6 +++--- 2 files changed, 13 insertions(+), 12 deletions(-) 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 b3eaeddab1..f4aaa85e8e 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -304,13 +304,13 @@ export const FileExplorer = (props: FileExplorerProps) => { if (dest.length === 0 || sourcesrc.length === 0) return if (await moveFilesIsAllowed(sourcesrc, dest) === false) return - const src = sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') try { props.dispatchMoveFiles(sourcesrc, dest) } catch (error) { props.modal( intl.formatMessage({ id: 'filePanel.movingFileFailed' }), - intl.formatMessage({ id: 'filePanel.movingFileFailedMsg' }, { src }), + intl.formatMessage({ id: 'filePanel.movingFileFailedMsg' }, { src: sourcesrc.join(' ') }), + intl.formatMessage({ id: 'filePanel.close' }), async () => { } ) @@ -328,13 +328,13 @@ export const FileExplorer = (props: FileExplorerProps) => { if (dest.length === 0 || sourcesrc.length === 0) return if (await moveFoldersIsAllowed(sourcesrc, dest) === false) return - const src = sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') + // console.log('moveFolderSilently', { src, dest, sourcesrc }) try { props.dispatchMoveFolders(sourcesrc, dest) } catch (error) { props.modal( intl.formatMessage({ id: 'filePanel.movingFolderFailed' }), - intl.formatMessage({ id: 'filePanel.movingFolderFailedMsg' }, { src }), + intl.formatMessage({ id: 'filePanel.movingFolderFailedMsg' }, { src: sourcesrc.join(' ') }), intl.formatMessage({ id: 'filePanel.close' }), async () => { } ) @@ -343,9 +343,10 @@ export const FileExplorer = (props: FileExplorerProps) => { const handleFileMove = async (dest: string, sourcesrc: string[]) => { if (await moveFilesIsAllowed(sourcesrc, dest) === false) return - const files = filesSelected && filesSelected.length > 0 && filesSelected.join('\n') - console.log(files) - const src = files.length > 0 ? files : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') + console.log('What files have been selected?', filesSelected) + const files = filesSelected && filesSelected.length > 0 && filesSelected.join(' ') + const src = files.length > 0 ? files : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join(' ') + console.log('handleFileMove sourcesrc', {files, sourcesrc, dest, src }) try { props.modal( intl.formatMessage({ id: 'filePanel.moveFile' }), @@ -367,9 +368,9 @@ export const FileExplorer = (props: FileExplorerProps) => { const handleFolderMove = async (dest: string, sourcesrc: string[]) => { if (await moveFoldersIsAllowed(sourcesrc, dest) === false) return - const folders = filesSelected && filesSelected.length > 0 && filesSelected.join('\n') + const folders = filesSelected && filesSelected.length > 0 && filesSelected.join(' ') console.log(folders) - const src = folders.length > 0 ? folders : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join('\n') + const src = folders.length > 0 ? folders : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join(' ') try { props.modal( intl.formatMessage({ id: 'filePanel.moveFile' }), diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index 652b1e43f8..2a5c29575b 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -53,12 +53,13 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { } const onDrop = async (event: SyntheticEvent) => { + event.stopPropagation() event.preventDefault() const target = await getEventTarget(event) const items = buildMultiSelectedItemProfiles(target) const filePaths = [] - // console.log('onDrop', { items, target, filePaths }) + let dragDestination: any if (!target || !target.path) { dragDestination = { @@ -68,8 +69,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { } else { dragDestination = getFlatTreeItem(target.path) } - - filePaths.push(dragDestination.path) + items.forEach((item) => filePaths.push(item.path)) props.setFilesSelected(filePaths) From 639a2080ab4cc47adbe12c3c990862c6ecb65088 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 09:57:37 +0100 Subject: [PATCH 14/60] change css class selector --- .../workspace/src/lib/components/file-explorer.tsx | 1 - .../workspace/src/lib/components/flat-tree-drop.tsx | 8 +++++--- libs/remix-ui/workspace/src/lib/components/flat-tree.tsx | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) 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 f4aaa85e8e..8d092c33f3 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -310,7 +310,6 @@ export const FileExplorer = (props: FileExplorerProps) => { props.modal( intl.formatMessage({ id: 'filePanel.movingFileFailed' }), intl.formatMessage({ id: 'filePanel.movingFileFailedMsg' }, { src: sourcesrc.join(' ') }), - intl.formatMessage({ id: 'filePanel.close' }), async () => { } ) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index 2a5c29575b..aea7d1fbac 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -53,7 +53,6 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { } const onDrop = async (event: SyntheticEvent) => { - event.stopPropagation() event.preventDefault() const target = await getEventTarget(event) @@ -92,6 +91,9 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { await moveFilesSilently(items, dragDestination.path) } } + document.querySelectorAll('li.remix_selected').forEach(item => { + item.classList.remove('remix_selected') + }) } /** @@ -112,8 +114,8 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { } }) => { const selectItems = [] - document.querySelectorAll('li.bg-secondary.li_tv').forEach(item => { - item.classList.add('dragging') + document.querySelectorAll('li.remix_selected').forEach(item => { + const dragTarget = { position: { top: target?.position.top || 0, left: target?.position.left || 0 }, path: item.getAttribute('data-path') || item.getAttribute('data-label-path') || '', diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx index 1d22b912f6..61050ae965 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx @@ -76,7 +76,7 @@ export const FlatTree = (props: FlatTreeProps) => { props.focusEdit.element === file.path ? 'bg-light' : props.focusElement.findIndex((item) => item.key === file.path) !== -1 - ? 'bg-secondary' + ? 'bg-secondary remix_selected' : hover == file.path ? 'bg-light border-no-shift' : props.focusContext.element === file.path && props.focusEdit.element !== file.path From cd273264594df5978ef6edf48f9c45ec5d88b30a Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 12:11:01 +0100 Subject: [PATCH 15/60] move function outside of drop component --- .../workspace/src/lib/utils/getEventTarget.ts | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/libs/remix-ui/workspace/src/lib/utils/getEventTarget.ts b/libs/remix-ui/workspace/src/lib/utils/getEventTarget.ts index e61cc7a226..e7cd32bc4a 100644 --- a/libs/remix-ui/workspace/src/lib/utils/getEventTarget.ts +++ b/libs/remix-ui/workspace/src/lib/utils/getEventTarget.ts @@ -22,4 +22,35 @@ export const getEventTarget = async (e: any, useLabel: boolean = false) => { position: endPosition } } -} \ No newline at end of file +} + +/** + * When multiple files are selected in FileExplorer, + * and these files are dragged to a target folder, + * this function will build the profile of each selected item + * in FileExplorer so they can be moved when dropped + * @param target - Initial target item in FileExplorer + * @returns - {DragStructure} Array of selected items + */ +export const buildMultiSelectedItemProfiles = (target: { + path: string + type: string + content: string + position: { + top: number + left: number + } + }) => { + const selectItems = [] + document.querySelectorAll('li.remixui_selected').forEach(item => { + + const dragTarget = { + position: { top: target?.position.top || 0, left: target?.position.left || 0 }, + path: item.getAttribute('data-path') || item.getAttribute('data-label-path') || '', + type: item.getAttribute('data-type') || item.getAttribute('data-label-type') || '', + content: item.textContent || '' + } + selectItems.push(dragTarget) + }) + return selectItems +} From ef35ea21b48c7c40a01d2b86d64eed56bcd95e8b Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 12:11:26 +0100 Subject: [PATCH 16/60] clean up types removing string array parameter --- libs/remix-ui/workspace/src/lib/types/index.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index 4fa993bc70..56bf8b839e 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -346,16 +346,18 @@ export type Actions = {[A in keyof ActionPayloadTypes]: Action}[keyof ActionP export type WorkspaceElement = 'folder' | 'file' | 'workspace' export interface FlatTreeDropProps { - moveFile: (dest: string, src: string[]) => void - moveFolder: (dest: string, src: string[]) => void - moveFolderSilently: (dest: string, src: string[]) => Promise - moveFileSilently: (dest: string, src: string[]) => Promise + moveFile: (dest: string, src: string) => void + moveFolder: (dest: string, src: string) => void + moveFolderSilently: (dest: string, src: string) => Promise + moveFileSilently: (dest: string, src: string) => Promise setFilesSelected: Dispatch> getFlatTreeItem: (path: string) => FileType handleClickFolder: (path: string, type: string) => void dragSource: FileType children: React.ReactNode expandPath: string[] + selectedItems: DragStructure[] + setSelectedItems: Dispatch> } export type DragStructure = { From ecba8151c459a3eca229b61d2469f39448296058 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 12:11:48 +0100 Subject: [PATCH 17/60] add placeholder css class for selected files --- libs/remix-ui/workspace/src/lib/css/file-explorer.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/remix-ui/workspace/src/lib/css/file-explorer.css b/libs/remix-ui/workspace/src/lib/css/file-explorer.css index 16f0ffca51..4ccf2096c7 100644 --- a/libs/remix-ui/workspace/src/lib/css/file-explorer.css +++ b/libs/remix-ui/workspace/src/lib/css/file-explorer.css @@ -69,3 +69,7 @@ ul { .remixui_icons:hover { color: var(--text); } + +.remixui_selected { + +} From b519f8dfc82895e3b41fc9a27497bc7b9fa72294 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 12:12:06 +0100 Subject: [PATCH 18/60] hoist function to fileTree component --- .../src/lib/components/file-explorer.tsx | 43 ++++++----- .../src/lib/components/flat-tree-drop.tsx | 72 +++++-------------- .../src/lib/components/flat-tree.tsx | 21 ++++-- 3 files changed, 53 insertions(+), 83 deletions(-) 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 8d092c33f3..7530cbf2c0 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -300,16 +300,16 @@ export const FileExplorer = (props: FileExplorerProps) => { * @param src path of the source * @returns {void} */ - const moveFileSilently = async (dest: string, sourcesrc: string[]) => { - if (dest.length === 0 || sourcesrc.length === 0) return - if (await moveFilesIsAllowed(sourcesrc, dest) === false) return + const moveFileSilently = async (dest: string, src: string) => { + if (dest.length === 0 || src.length === 0) return + if (await moveFileIsAllowed(src, dest) === false) return try { - props.dispatchMoveFiles(sourcesrc, dest) + props.dispatchMoveFile(src, dest) } catch (error) { props.modal( intl.formatMessage({ id: 'filePanel.movingFileFailed' }), - intl.formatMessage({ id: 'filePanel.movingFileFailedMsg' }, { src: sourcesrc.join(' ') }), + intl.formatMessage({ id: 'filePanel.movingFileFailedMsg' }, { src }), intl.formatMessage({ id: 'filePanel.close' }), async () => { } ) @@ -323,35 +323,34 @@ export const FileExplorer = (props: FileExplorerProps) => { * @param src path of the source * @returns {void} */ - const moveFolderSilently = async (dest: string, sourcesrc: string[]) => { - if (dest.length === 0 || sourcesrc.length === 0) return - if (await moveFoldersIsAllowed(sourcesrc, dest) === false) return + const moveFolderSilently = async (dest: string, src: string) => { + if (dest.length === 0 || src.length === 0) return + if (await moveFolderIsAllowed(src, dest) === false) return - // console.log('moveFolderSilently', { src, dest, sourcesrc }) try { - props.dispatchMoveFolders(sourcesrc, dest) + props.dispatchMoveFolder(src, dest) } catch (error) { props.modal( intl.formatMessage({ id: 'filePanel.movingFolderFailed' }), - intl.formatMessage({ id: 'filePanel.movingFolderFailedMsg' }, { src: sourcesrc.join(' ') }), + intl.formatMessage({ id: 'filePanel.movingFolderFailedMsg' }, { src }), intl.formatMessage({ id: 'filePanel.close' }), async () => { } ) } } - const handleFileMove = async (dest: string, sourcesrc: string[]) => { - if (await moveFilesIsAllowed(sourcesrc, dest) === false) return - console.log('What files have been selected?', filesSelected) - const files = filesSelected && filesSelected.length > 0 && filesSelected.join(' ') - const src = files.length > 0 ? files : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join(' ') - console.log('handleFileMove sourcesrc', {files, sourcesrc, dest, src }) + const handleFileMove = async (dest: string, copySrc: string) => { + if (await moveFileIsAllowed(copySrc, dest) === false) return + + const src = filesSelected && filesSelected.length > 0 ? filesSelected.join(' ') : '' + + console.log('handleFileMove sourcesrc', {src, copySrc, dest }) try { props.modal( intl.formatMessage({ id: 'filePanel.moveFile' }), intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }), intl.formatMessage({ id: 'filePanel.yes' }), - () => props.dispatchMoveFiles(sourcesrc, dest), + () => props.dispatchMoveFile(copySrc, dest), intl.formatMessage({ id: 'filePanel.cancel' }), () => { } ) @@ -365,17 +364,17 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - const handleFolderMove = async (dest: string, sourcesrc: string[]) => { - if (await moveFoldersIsAllowed(sourcesrc, dest) === false) return + const handleFolderMove = async (dest: string, src: string) => { + if (await moveFolderIsAllowed(src, dest) === false) return const folders = filesSelected && filesSelected.length > 0 && filesSelected.join(' ') console.log(folders) - const src = folders.length > 0 ? folders : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join(' ') + try { props.modal( intl.formatMessage({ id: 'filePanel.moveFile' }), intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }), intl.formatMessage({ id: 'filePanel.yes' }), - () => props.dispatchMoveFolders(sourcesrc, dest), + () => props.dispatchMoveFolder(src, dest), intl.formatMessage({ id: 'filePanel.cancel' }), () => { } ) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index aea7d1fbac..11300819ad 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -1,6 +1,6 @@ import React, { SyntheticEvent, useContext, useEffect, useRef, useState } from 'react' import { DragStructure, FileType, FlatTreeDropProps } from '../types' -import { getEventTarget } from '../utils/getEventTarget' +import { buildMultiSelectedItemProfiles, getEventTarget } from '../utils/getEventTarget' import { extractParentFromKey } from '@remix-ui/helper' import { FileSystemContext } from '../contexts' @@ -14,20 +14,14 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { // folder to open const [folderToOpen, setFolderToOpen] = useState() const globalFEContext = useContext(FileSystemContext) - const [selectedItems, setSelectedItems] = useState([]) - -<<<<<<< HEAD -======= - useEffect(() => { - }, [globalFEContext.fs.focusElement.length]) + const [selectedItems, setSelectedItems] = useState([]) ->>>>>>> consume function to move files silently const onDragOver = async (e: SyntheticEvent) => { e.preventDefault() const target = await getEventTarget(e) - buildMultiSelectedItemProfiles(target) + if (!target || !target.path) { clearTimeout(timer) setFolderToOpen(null) @@ -56,7 +50,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { event.preventDefault() const target = await getEventTarget(event) - const items = buildMultiSelectedItemProfiles(target) + // const items = buildMultiSelectedItemProfiles(target) const filePaths = [] let dragDestination: any @@ -69,62 +63,32 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { dragDestination = getFlatTreeItem(target.path) } - items.forEach((item) => filePaths.push(item.path)) + props.selectedItems.forEach((item) => filePaths.push(item.path)) props.setFilesSelected(filePaths) if (dragDestination.isDirectory) { if (dragSource.isDirectory) { - moveFolder(dragDestination.path, [dragSource.path]) - await moveFoldersSilently(items, dragDestination.path) + moveFolder(dragDestination.path, dragSource.path) + await moveFoldersSilently(props.selectedItems, dragDestination.path) } else { - moveFile(dragDestination.path, [dragSource.path]) - await moveFilesSilently(items, dragDestination.path) + moveFile(dragDestination.path, dragSource.path) + await moveFilesSilently(props.selectedItems, dragDestination.path) } } else { const path = extractParentFromKey(dragDestination.path) || '/' if (dragSource.isDirectory) { - moveFolder(path, [dragSource.path]) - await moveFoldersSilently(items, dragDestination.path) + moveFolder(path, dragSource.path) + await moveFoldersSilently(props.selectedItems, dragDestination.path) } else { - moveFile(path, [dragSource.path]) - await moveFilesSilently(items, dragDestination.path) + moveFile(path, dragSource.path) + await moveFilesSilently(props.selectedItems, dragDestination.path) } } - document.querySelectorAll('li.remix_selected').forEach(item => { - item.classList.remove('remix_selected') - }) - } - - /** - * When multiple files are selected in FileExplorer, - * and these files are dragged to a target folder, - * this function will build the profile of each selected item - * in FileExplorer so they can be moved when dropped - * @param target - Initial target item in FileExplorer - * @returns - {DragStructure} Array of selected items - */ - const buildMultiSelectedItemProfiles = (target: { - path: string - type: string - content: string - position: { - top: number - left: number - } - }) => { - const selectItems = [] - document.querySelectorAll('li.remix_selected').forEach(item => { - - const dragTarget = { - position: { top: target?.position.top || 0, left: target?.position.left || 0 }, - path: item.getAttribute('data-path') || item.getAttribute('data-label-path') || '', - type: item.getAttribute('data-type') || item.getAttribute('data-label-type') || '', - content: item.textContent || '' - } - selectItems.push(dragTarget) + document.querySelectorAll('li.remixui_selected').forEach(item => { + item.classList.remove('remixui_selected') + item.classList.remove('bg-secondary') }) - return selectItems } /** @@ -138,7 +102,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { const promises = items.filter(item => item.path !== targetPath) .map(async (item) => { if (item.type === 'file') { - await props.moveFileSilently(targetPath, [item.path]) + await props.moveFileSilently(targetPath, item.path) } }) await Promise.all(promises) @@ -155,7 +119,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { const promises = items.filter(item => item.path !== targetPath) .map(async (item) => { if (item.type === 'folder') { - await props.moveFolderSilently(targetPath, [item.path]) + await props.moveFolderSilently(targetPath, item.path) } }) await Promise.all(promises) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx index 61050ae965..6a56153cf8 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx @@ -1,11 +1,11 @@ import React, { SyntheticEvent, useEffect, useRef, useState, RefObject, useMemo, useContext, Dispatch } from 'react' import { Popover } from 'react-bootstrap' -import { FileType, WorkspaceElement } from '../types' +import { DragStructure, FileType, WorkspaceElement } from '../types' import { getPathIcon } from '@remix-ui/helper'; import { Virtuoso, VirtuosoHandle } from 'react-virtuoso' import { FlatTreeItemInput } from './flat-tree-item-input'; import { FlatTreeDrop } from './flat-tree-drop'; -import { getEventTarget } from '../utils/getEventTarget'; +import { buildMultiSelectedItemProfiles, getEventTarget } from '../utils/getEventTarget'; import { fileDecoration, FileDecorationIcons } from '@remix-ui/file-decorators'; import { FileHoverIcons } from './file-explorer-hovericons'; import { deletePath } from '../actions'; @@ -36,10 +36,10 @@ interface FlatTreeProps { handleContextMenu: (pageX: number, pageY: number, path: string, content: string, type: string) => void handleTreeClick: (e: SyntheticEvent) => void handleClickFolder: (path: string, type: string) => void - moveFile: (dest: string, src: string[]) => void - moveFolder: (dest: string, src: string[]) => void - moveFolderSilently: (dest: string, src: string[]) => Promise - moveFileSilently: (dest: string, src: string[]) => Promise + moveFile: (dest: string, src: string) => void + moveFolder: (dest: string, src: string) => void + moveFolderSilently: (dest: string, src: string) => Promise + moveFileSilently: (dest: string, src: string) => Promise setFilesSelected: Dispatch> fileState: fileDecoration[] createNewFile?: any @@ -71,12 +71,14 @@ export const FlatTree = (props: FlatTreeProps) => { const ref = useRef(null) const containerRef = useRef(null) const virtuoso = useRef(null) + const [selectedItems, setSelectedItems] = useState([]) + const labelClass = (file: FileType) => props.focusEdit.element === file.path ? 'bg-light' : props.focusElement.findIndex((item) => item.key === file.path) !== -1 - ? 'bg-secondary remix_selected' + ? 'bg-secondary remixui_selected' : hover == file.path ? 'bg-light border-no-shift' : props.focusContext.element === file.path && props.focusEdit.element !== file.path @@ -107,6 +109,9 @@ export const FlatTree = (props: FlatTreeProps) => { const target = await getEventTarget(event) setDragSource(flatTree.find((item) => item.path === target.path)) setIsDragging(true) + const items = buildMultiSelectedItemProfiles(target) + setSelectedItems(items) + setFilesSelected(items.map((item) => item.path)) } useEffect(() => { @@ -258,6 +263,8 @@ export const FlatTree = (props: FlatTreeProps) => { setFilesSelected={setFilesSelected} handleClickFolder={handleClickFolder} expandPath={expandPath} + selectedItems={selectedItems} + setSelectedItems={setSelectedItems} >
Date: Mon, 29 Apr 2024 12:24:44 +0100 Subject: [PATCH 19/60] rename parameter for moveSilently. cleanup comment --- .../workspace/src/lib/components/file-explorer.tsx | 9 ++++----- .../workspace/src/lib/components/flat-tree-drop.tsx | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) 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 7530cbf2c0..d9618e8453 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -364,17 +364,16 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - const handleFolderMove = async (dest: string, src: string) => { - if (await moveFolderIsAllowed(src, dest) === false) return - const folders = filesSelected && filesSelected.length > 0 && filesSelected.join(' ') - console.log(folders) + const handleFolderMove = async (dest: string, copySrc: string) => { + if (await moveFolderIsAllowed(copySrc, dest) === false) return + const src = filesSelected && filesSelected.length > 0 ? filesSelected.join(' ') : '' try { props.modal( intl.formatMessage({ id: 'filePanel.moveFile' }), intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }), intl.formatMessage({ id: 'filePanel.yes' }), - () => props.dispatchMoveFolder(src, dest), + () => props.dispatchMoveFolder(copySrc, dest), intl.formatMessage({ id: 'filePanel.cancel' }), () => { } ) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index 11300819ad..acbc74a075 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -50,7 +50,6 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { event.preventDefault() const target = await getEventTarget(event) - // const items = buildMultiSelectedItemProfiles(target) const filePaths = [] let dragDestination: any From 8e369e39d572aef71a97cba6621ab4da5ae5a30e Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 12:31:12 +0100 Subject: [PATCH 20/60] update JSDoc --- libs/remix-ui/workspace/src/lib/components/file-explorer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 d9618e8453..ff2daf211e 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -298,7 +298,7 @@ export const FileExplorer = (props: FileExplorerProps) => { * without showing a modal dialong to the user. * @param dest path of the destination * @param src path of the source - * @returns {void} + * @returns {Promise} */ const moveFileSilently = async (dest: string, src: string) => { if (dest.length === 0 || src.length === 0) return @@ -321,7 +321,7 @@ export const FileExplorer = (props: FileExplorerProps) => { * without showing a modal dialong to the user. * @param dest path of the destination * @param src path of the source - * @returns {void} + * @returns {Promise} */ const moveFolderSilently = async (dest: string, src: string) => { if (dest.length === 0 || src.length === 0) return From f383677905087c75acf419fbbde915301bab6efc Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 12:59:31 +0100 Subject: [PATCH 21/60] add console log --- libs/remix-ui/workspace/src/lib/components/file-explorer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 ff2daf211e..7768366f4b 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -303,7 +303,7 @@ export const FileExplorer = (props: FileExplorerProps) => { const moveFileSilently = async (dest: string, src: string) => { if (dest.length === 0 || src.length === 0) return if (await moveFileIsAllowed(src, dest) === false) return - + console.log({ src, dest }) try { props.dispatchMoveFile(src, dest) } catch (error) { @@ -326,7 +326,7 @@ export const FileExplorer = (props: FileExplorerProps) => { const moveFolderSilently = async (dest: string, src: string) => { if (dest.length === 0 || src.length === 0) return if (await moveFolderIsAllowed(src, dest) === false) return - + console.log({ src, dest }) try { props.dispatchMoveFolder(src, dest) } catch (error) { From 29d6ddada4c7dfac16c4d4580650cce22cb37ca2 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 14:12:46 +0100 Subject: [PATCH 22/60] clean onDrop function in flat-tree --- libs/remix-ui/workspace/src/lib/components/flat-tree.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx index 6a56153cf8..42ced37826 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx @@ -125,6 +125,12 @@ export const FlatTree = (props: FlatTreeProps) => { const onDragEnd = (event: SyntheticEvent) => { setIsDragging(false) + document.querySelectorAll('li.remixui_selected').forEach(item => { + item.classList.remove('remixui_selected') + item.classList.remove('bg-secondary') + }) + props.setFilesSelected([]) + setSelectedItems([]) } const getFlatTreeItem = (path: string) => { From e10ea923457335883104402d144c520d6d520759 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 14:13:05 +0100 Subject: [PATCH 23/60] refactor --- apps/remix-ide/src/app/files/fileManager.ts | 1 + libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index be40d899ab..401cce42ee 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -83,6 +83,7 @@ class FileManager extends Plugin { * @param {string} message message to display if path doesn't exist. */ async _handleExists(path: string, message?: string) { + console.log('_handleExists is called ', { path, message }) const exists = await this.exists(path) if (!exists) { diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index acbc74a075..121e790b38 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -84,10 +84,6 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { await moveFilesSilently(props.selectedItems, dragDestination.path) } } - document.querySelectorAll('li.remixui_selected').forEach(item => { - item.classList.remove('remixui_selected') - item.classList.remove('bg-secondary') - }) } /** From 6a50dbca2643a1b78e89f3f9876d0f0d51644422 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 29 Apr 2024 14:38:44 +0100 Subject: [PATCH 24/60] using path --- libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index 121e790b38..fb2c08ff21 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -78,10 +78,10 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { if (dragSource.isDirectory) { moveFolder(path, dragSource.path) - await moveFoldersSilently(props.selectedItems, dragDestination.path) + await moveFoldersSilently(props.selectedItems, path) } else { moveFile(path, dragSource.path) - await moveFilesSilently(props.selectedItems, dragDestination.path) + await moveFilesSilently(props.selectedItems, path) } } } From 9c48c6e563ae12cca276c34114dc9b7fa704de07 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 29 Apr 2024 19:20:29 +0200 Subject: [PATCH 25/60] add warn message --- .../src/lib/components/file-explorer.tsx | 22 ++++++++++++++----- .../src/lib/components/flat-tree-drop.tsx | 20 ++++++++--------- .../src/lib/components/flat-tree.tsx | 4 +++- .../remix-ui/workspace/src/lib/types/index.ts | 1 + 4 files changed, 30 insertions(+), 17 deletions(-) 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 7768366f4b..8169053528 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -339,12 +339,23 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - const handleFileMove = async (dest: string, copySrc: string) => { - if (await moveFileIsAllowed(copySrc, dest) === false) return - - const src = filesSelected && filesSelected.length > 0 ? filesSelected.join(' ') : '' + const warnMovingItems = async (src: string[], dest: string): Promise => { + return new Promise((resolve, reject) => { + props.modal( + intl.formatMessage({ id: 'filePanel.moveFile' }), + intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src: src.join(', '), dest }), + intl.formatMessage({ id: 'filePanel.yes' }), + () => resolve(null), + intl.formatMessage({ id: 'filePanel.cancel' }), + () => reject() + ) + }) + } - console.log('handleFileMove sourcesrc', {src, copySrc, dest }) + const handleFileMove = async (dest: string, sourcesrc: string[]) => { + if (await moveFilesIsAllowed(sourcesrc, dest) === false) return + const files = filesSelected && filesSelected.length > 0 && filesSelected.join(' ') + const src = files.length > 0 ? files : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join(' ') try { props.modal( intl.formatMessage({ id: 'filePanel.moveFile' }), @@ -454,6 +465,7 @@ export const FileExplorer = (props: FileExplorerProps) => { fileState={fileState} expandPath={props.expandPath} handleContextMenu={handleContextMenu} + warnMovingItems={warnMovingItems} moveFile={handleFileMove} moveFolder={handleFolderMove} moveFolderSilently={moveFolderSilently} diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index fb2c08ff21..8d48aaccd9 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -8,7 +8,7 @@ import { FileSystemContext } from '../contexts' export const FlatTreeDrop = (props: FlatTreeDropProps) => { - const { getFlatTreeItem, dragSource, moveFile, moveFolder, handleClickFolder, expandPath } = props + const { getFlatTreeItem, dragSource, handleClickFolder, expandPath } = props // delay timer const [timer, setTimer] = useState() // folder to open @@ -67,21 +67,21 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { if (dragDestination.isDirectory) { if (dragSource.isDirectory) { - moveFolder(dragDestination.path, dragSource.path) - await moveFoldersSilently(props.selectedItems, dragDestination.path) + await props.warnMovingItems(filePaths, dragDestination.path) + await moveFoldersSilently(filePaths, dragDestination.path) } else { - moveFile(dragDestination.path, dragSource.path) - await moveFilesSilently(props.selectedItems, dragDestination.path) + await props.warnMovingItems(filePaths, dragDestination.path) + await moveFilesSilently(filePaths, dragDestination.path) } } else { const path = extractParentFromKey(dragDestination.path) || '/' if (dragSource.isDirectory) { - moveFolder(path, dragSource.path) - await moveFoldersSilently(props.selectedItems, path) + await props.warnMovingItems(filePaths, path) + await moveFoldersSilently(filePaths, path) } else { - moveFile(path, dragSource.path) - await moveFilesSilently(props.selectedItems, path) + await props.warnMovingItems(filePaths, path) + await moveFilesSilently(filePaths, path) } } } @@ -93,7 +93,6 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { * @returns Promise */ const moveFilesSilently = async (items: DragStructure[], targetPath: string) => { - console.log('moveItemsSilently', { items, targetPath }) const promises = items.filter(item => item.path !== targetPath) .map(async (item) => { if (item.type === 'file') { @@ -110,7 +109,6 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { * @returns Promise */ const moveFoldersSilently = async (items: DragStructure[], targetPath: string) => { - console.log('moveItemsSilently', { items, targetPath }) const promises = items.filter(item => item.path !== targetPath) .map(async (item) => { if (item.type === 'folder') { diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx index 42ced37826..4f8e8f7aa0 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx @@ -46,6 +46,7 @@ interface FlatTreeProps { createNewFolder?: any deletePath?: (path: string | string[]) => void | Promise editPath?: (path: string, type: string, isNew?: boolean) => void + warnMovingItems: (srcs: string[], dests: string) => Promise } let mouseTimer: any = { @@ -54,7 +55,7 @@ let mouseTimer: any = { } export const FlatTree = (props: FlatTreeProps) => { - const { files, flatTree, expandPath, focusEdit, editModeOff, handleTreeClick, moveFile, moveFolder, fileState, focusElement, handleClickFolder, deletePath, moveFileSilently, moveFolderSilently, setFilesSelected } = props + const { files, flatTree, expandPath, focusEdit, editModeOff, handleTreeClick, moveFile, moveFolder, warnMovingItems, fileState, focusElement, handleClickFolder, deletePath, moveFileSilently, moveFolderSilently, setFilesSelected } = props const [hover, setHover] = useState('') const [mouseOverTarget, setMouseOverTarget] = useState<{ path: string, @@ -264,6 +265,7 @@ export const FlatTree = (props: FlatTreeProps) => { getFlatTreeItem={getFlatTreeItem} moveFile={moveFile} moveFolder={moveFolder} + warnMovingItems={warnMovingItems} moveFolderSilently={moveFolderSilently} moveFileSilently={moveFileSilently} setFilesSelected={setFilesSelected} diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index 56bf8b839e..9ba1843b4c 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -358,6 +358,7 @@ export interface FlatTreeDropProps { expandPath: string[] selectedItems: DragStructure[] setSelectedItems: Dispatch> + warnMovingItems: (srcs: string[], dest: string) => Promise } export type DragStructure = { From b31285cf3979f133f2b92d9cb310035f55b94dc6 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 29 Apr 2024 19:46:06 +0200 Subject: [PATCH 26/60] refactor and fix --- apps/remix-ide/src/app/files/fileManager.ts | 1 - .../src/lib/components/file-explorer.tsx | 50 ------------------- .../src/lib/components/flat-tree-drop.tsx | 8 +-- .../src/lib/components/flat-tree.tsx | 6 +-- .../remix-ui/workspace/src/lib/types/index.ts | 2 - 5 files changed, 5 insertions(+), 62 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index 401cce42ee..be40d899ab 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -83,7 +83,6 @@ class FileManager extends Plugin { * @param {string} message message to display if path doesn't exist. */ async _handleExists(path: string, message?: string) { - console.log('_handleExists is called ', { path, message }) const exists = await this.exists(path) if (!exists) { 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 8169053528..47599beca3 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -303,7 +303,6 @@ export const FileExplorer = (props: FileExplorerProps) => { const moveFileSilently = async (dest: string, src: string) => { if (dest.length === 0 || src.length === 0) return if (await moveFileIsAllowed(src, dest) === false) return - console.log({ src, dest }) try { props.dispatchMoveFile(src, dest) } catch (error) { @@ -326,7 +325,6 @@ export const FileExplorer = (props: FileExplorerProps) => { const moveFolderSilently = async (dest: string, src: string) => { if (dest.length === 0 || src.length === 0) return if (await moveFolderIsAllowed(src, dest) === false) return - console.log({ src, dest }) try { props.dispatchMoveFolder(src, dest) } catch (error) { @@ -352,52 +350,6 @@ export const FileExplorer = (props: FileExplorerProps) => { }) } - const handleFileMove = async (dest: string, sourcesrc: string[]) => { - if (await moveFilesIsAllowed(sourcesrc, dest) === false) return - const files = filesSelected && filesSelected.length > 0 && filesSelected.join(' ') - const src = files.length > 0 ? files : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join(' ') - try { - props.modal( - intl.formatMessage({ id: 'filePanel.moveFile' }), - intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }), - intl.formatMessage({ id: 'filePanel.yes' }), - () => props.dispatchMoveFile(copySrc, dest), - intl.formatMessage({ id: 'filePanel.cancel' }), - () => { } - ) - } catch (error) { - props.modal( - intl.formatMessage({ id: 'filePanel.movingFileFailed' }), - intl.formatMessage({ id: 'filePanel.movingFileFailedMsg' }, { src }), - intl.formatMessage({ id: 'filePanel.close' }), - async () => { } - ) - } - } - - const handleFolderMove = async (dest: string, copySrc: string) => { - if (await moveFolderIsAllowed(copySrc, dest) === false) return - const src = filesSelected && filesSelected.length > 0 ? filesSelected.join(' ') : '' - - try { - props.modal( - intl.formatMessage({ id: 'filePanel.moveFile' }), - intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }), - intl.formatMessage({ id: 'filePanel.yes' }), - () => props.dispatchMoveFolder(copySrc, dest), - intl.formatMessage({ id: 'filePanel.cancel' }), - () => { } - ) - } catch (error) { - props.modal( - intl.formatMessage({ id: 'filePanel.movingFolderFailed' }), - intl.formatMessage({ id: 'filePanel.movingFolderFailedMsg' }, { src }), - intl.formatMessage({ id: 'filePanel.close' }), - async () => { } - ) - } - } - const handleTreeClick = (event: SyntheticEvent) => { let target = event.target as HTMLElement while (target && target.getAttribute && !target.getAttribute('data-path')) { @@ -466,8 +418,6 @@ export const FileExplorer = (props: FileExplorerProps) => { expandPath={props.expandPath} handleContextMenu={handleContextMenu} warnMovingItems={warnMovingItems} - moveFile={handleFileMove} - moveFolder={handleFolderMove} moveFolderSilently={moveFolderSilently} moveFileSilently={moveFileSilently} setFilesSelected={setFilesSelected} diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index 8d48aaccd9..d825bb99ad 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -68,20 +68,20 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { if (dragDestination.isDirectory) { if (dragSource.isDirectory) { await props.warnMovingItems(filePaths, dragDestination.path) - await moveFoldersSilently(filePaths, dragDestination.path) + await moveFoldersSilently(props.selectedItems, dragDestination.path) } else { await props.warnMovingItems(filePaths, dragDestination.path) - await moveFilesSilently(filePaths, dragDestination.path) + await moveFilesSilently(props.selectedItems, dragDestination.path) } } else { const path = extractParentFromKey(dragDestination.path) || '/' if (dragSource.isDirectory) { await props.warnMovingItems(filePaths, path) - await moveFoldersSilently(filePaths, path) + await moveFoldersSilently(props.selectedItems, path) } else { await props.warnMovingItems(filePaths, path) - await moveFilesSilently(filePaths, path) + await moveFilesSilently(props.selectedItems, path) } } } diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx index 4f8e8f7aa0..deacbfbac0 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx @@ -36,8 +36,6 @@ interface FlatTreeProps { handleContextMenu: (pageX: number, pageY: number, path: string, content: string, type: string) => void handleTreeClick: (e: SyntheticEvent) => void handleClickFolder: (path: string, type: string) => void - moveFile: (dest: string, src: string) => void - moveFolder: (dest: string, src: string) => void moveFolderSilently: (dest: string, src: string) => Promise moveFileSilently: (dest: string, src: string) => Promise setFilesSelected: Dispatch> @@ -55,7 +53,7 @@ let mouseTimer: any = { } export const FlatTree = (props: FlatTreeProps) => { - const { files, flatTree, expandPath, focusEdit, editModeOff, handleTreeClick, moveFile, moveFolder, warnMovingItems, fileState, focusElement, handleClickFolder, deletePath, moveFileSilently, moveFolderSilently, setFilesSelected } = props + const { files, flatTree, expandPath, focusEdit, editModeOff, handleTreeClick, warnMovingItems, fileState, focusElement, handleClickFolder, deletePath, moveFileSilently, moveFolderSilently, setFilesSelected } = props const [hover, setHover] = useState('') const [mouseOverTarget, setMouseOverTarget] = useState<{ path: string, @@ -263,8 +261,6 @@ export const FlatTree = (props: FlatTreeProps) => { }[keyof ActionP export type WorkspaceElement = 'folder' | 'file' | 'workspace' export interface FlatTreeDropProps { - moveFile: (dest: string, src: string) => void - moveFolder: (dest: string, src: string) => void moveFolderSilently: (dest: string, src: string) => Promise moveFileSilently: (dest: string, src: string) => Promise setFilesSelected: Dispatch> From 803ffb612ea56f16f5390e4919cfde1a4c36599c Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Tue, 30 Apr 2024 09:55:07 +0100 Subject: [PATCH 27/60] add e2e tests --- .../tests/file_explorer_multiselect.test.ts | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index 1d31d6a9b5..65ff7c553e 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -22,6 +22,49 @@ module.exports = { .assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') .assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') .assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemtests"]') - .end() + }, + 'Should select multiple items in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { + const selectedElements = [] + browser + .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) + .findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]', locateStrategy: 'xpath' }, (el) => { + selectedElements.push(el) + }) + browser.selectFiles(selectedElements) + browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }, + (el: any) => { + const id = (el as any).value.getId() + browser + .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests"]') + .dragAndDrop('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', id) + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/1_Storage.sol"]') + .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/2_Owner.sol"]') + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') + }) + }, + 'should select multiple files and folders in file explorer to contracts folder #group1': function (browser: NightwatchBrowser) { + const selectedElements = [] + browser + .click({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }) + .findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemREADME.txt"]', locateStrategy: 'xpath' }, (el) => { + selectedElements.push(el) + }) + browser.selectFiles(selectedElements) + browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts"]', locateStrategy: 'xpath' }, + (el: any) => { + const id = (el as any).value.getId() + browser + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts"]') + .dragAndDrop('li[data-id="treeViewLitreeViewItemtests"]', id) + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/tests"]') + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/README.txt"]') + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemtests"]') + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemREADME.txt"]') + }) } } From 215d356972bf3d94ebdb224a47ac1e7b28d18ca3 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 30 Apr 2024 11:00:50 +0200 Subject: [PATCH 28/60] fix tests --- .../tests/file_explorer_multiselect.test.ts | 4 +- .../src/lib/components/file-explorer.tsx | 2 +- .../src/lib/components/flat-tree-drop.tsx | 43 +++---------------- .../src/lib/components/flat-tree.tsx | 1 - 4 files changed, 9 insertions(+), 41 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index 65ff7c553e..8d1ce137d1 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -23,7 +23,7 @@ module.exports = { .assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') .assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemtests"]') }, - 'Should select multiple items in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { + 'Should drag and drop multiple files in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { const selectedElements = [] browser .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) @@ -45,7 +45,7 @@ module.exports = { .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') }) }, - 'should select multiple files and folders in file explorer to contracts folder #group1': function (browser: NightwatchBrowser) { + 'should drag and drop multiple files and folders in file explorer to contracts folder #group1': function (browser: NightwatchBrowser) { const selectedElements = [] browser .click({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }) 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 47599beca3..3d421830a1 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -347,7 +347,7 @@ export const FileExplorer = (props: FileExplorerProps) => { intl.formatMessage({ id: 'filePanel.cancel' }), () => reject() ) - }) + }) } const handleTreeClick = (event: SyntheticEvent) => { diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index d825bb99ad..75697137b2 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -4,8 +4,6 @@ import { buildMultiSelectedItemProfiles, getEventTarget } from '../utils/getEven import { extractParentFromKey } from '@remix-ui/helper' import { FileSystemContext } from '../contexts' - - export const FlatTreeDrop = (props: FlatTreeDropProps) => { const { getFlatTreeItem, dragSource, handleClickFolder, expandPath } = props @@ -13,9 +11,6 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { const [timer, setTimer] = useState() // folder to open const [folderToOpen, setFolderToOpen] = useState() - const globalFEContext = useContext(FileSystemContext) - - const [selectedItems, setSelectedItems] = useState([]) const onDragOver = async (e: SyntheticEvent) => { e.preventDefault() @@ -66,23 +61,12 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { props.setFilesSelected(filePaths) if (dragDestination.isDirectory) { - if (dragSource.isDirectory) { - await props.warnMovingItems(filePaths, dragDestination.path) - await moveFoldersSilently(props.selectedItems, dragDestination.path) - } else { - await props.warnMovingItems(filePaths, dragDestination.path) - await moveFilesSilently(props.selectedItems, dragDestination.path) - } + await props.warnMovingItems(filePaths, dragDestination.path) + await moveItemsSilently(props.selectedItems, dragDestination.path) } else { const path = extractParentFromKey(dragDestination.path) || '/' - - if (dragSource.isDirectory) { - await props.warnMovingItems(filePaths, path) - await moveFoldersSilently(props.selectedItems, path) - } else { - await props.warnMovingItems(filePaths, path) - await moveFilesSilently(props.selectedItems, path) - } + await props.warnMovingItems(filePaths, path) + await moveItemsSilently(props.selectedItems, path) } } @@ -92,33 +76,18 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { * @param dragSource source FileExplorer item being dragged. * @returns Promise */ - const moveFilesSilently = async (items: DragStructure[], targetPath: string) => { + const moveItemsSilently = async (items: DragStructure[], targetPath: string) => { const promises = items.filter(item => item.path !== targetPath) .map(async (item) => { if (item.type === 'file') { await props.moveFileSilently(targetPath, item.path) - } - }) - await Promise.all(promises) - } - - /** - * Moves items silently without showing a confirmation dialog. - * @param items MultiSelected items built into a DragStructure profile - * @param dragSource source FileExplorer item being dragged. - * @returns Promise - */ - const moveFoldersSilently = async (items: DragStructure[], targetPath: string) => { - const promises = items.filter(item => item.path !== targetPath) - .map(async (item) => { - if (item.type === 'folder') { + } else if (item.type === 'folder') { await props.moveFolderSilently(targetPath, item.path) } }) await Promise.all(promises) } - return (
{ const virtuoso = useRef(null) const [selectedItems, setSelectedItems] = useState([]) - const labelClass = (file: FileType) => props.focusEdit.element === file.path ? 'bg-light' From 8bef427b64634795bcd7fc61b97d3d1a446c509f Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 30 Apr 2024 16:19:00 +0200 Subject: [PATCH 29/60] fix dragging --- libs/remix-ui/workspace/src/lib/utils/getEventTarget.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/utils/getEventTarget.ts b/libs/remix-ui/workspace/src/lib/utils/getEventTarget.ts index e7cd32bc4a..ea663acf11 100644 --- a/libs/remix-ui/workspace/src/lib/utils/getEventTarget.ts +++ b/libs/remix-ui/workspace/src/lib/utils/getEventTarget.ts @@ -42,15 +42,15 @@ export const buildMultiSelectedItemProfiles = (target: { } }) => { const selectItems = [] + selectItems.push(target) document.querySelectorAll('li.remixui_selected').forEach(item => { - const dragTarget = { position: { top: target?.position.top || 0, left: target?.position.left || 0 }, path: item.getAttribute('data-path') || item.getAttribute('data-label-path') || '', type: item.getAttribute('data-type') || item.getAttribute('data-label-type') || '', content: item.textContent || '' } - selectItems.push(dragTarget) + if (dragTarget.path !== target.path) selectItems.push(dragTarget) }) return selectItems } From 0a34381fd39561a72043ad4ae2d5c7a732bf2f3d Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 30 Apr 2024 16:47:16 +0200 Subject: [PATCH 30/60] fix test --- apps/remix-ide-e2e/src/commands/selectFiles.ts | 2 +- .../src/tests/file_explorer_multiselect.test.ts | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide-e2e/src/commands/selectFiles.ts b/apps/remix-ide-e2e/src/commands/selectFiles.ts index d24ec1e42b..86a2777440 100644 --- a/apps/remix-ide-e2e/src/commands/selectFiles.ts +++ b/apps/remix-ide-e2e/src/commands/selectFiles.ts @@ -11,7 +11,7 @@ class SelectFiles extends EventEmitter { for(let i = 0; i < selectedElements.length; i++) { actions.click(selectedElements[i].value) } - return actions.contextClick(selectedElements[0].value) + // return actions.contextClick(selectedElements[0].value) }) this.emit('complete') return this diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index 8d1ce137d1..b137f42af5 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -2,6 +2,7 @@ import { NightwatchBrowser } from 'nightwatch' import init from '../helpers/init' module.exports = { + "@disabled": true, before: function (browser: NightwatchBrowser, done: VoidFunction) { init(browser, done) }, @@ -31,7 +32,8 @@ module.exports = { selectedElements.push(el) }) browser.selectFiles(selectedElements) - browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }, + .perform((done) => { + browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }, (el: any) => { const id = (el as any).value.getId() browser @@ -43,17 +45,21 @@ module.exports = { .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/2_Owner.sol"]') .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') + .perform(() => done()) }) + }) }, - 'should drag and drop multiple files and folders in file explorer to contracts folder #group1': function (browser: NightwatchBrowser) { + 'should drag and drop multiple files and folders in file explorer to contracts folder #group3': function (browser: NightwatchBrowser) { const selectedElements = [] browser + .clickLaunchIcon('filePanel') .click({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }) .findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemREADME.txt"]', locateStrategy: 'xpath' }, (el) => { selectedElements.push(el) }) browser.selectFiles(selectedElements) - browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts"]', locateStrategy: 'xpath' }, + .perform((done) => { + browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts"]', locateStrategy: 'xpath' }, (el: any) => { const id = (el as any).value.getId() browser @@ -65,6 +71,8 @@ module.exports = { .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/README.txt"]') .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemtests"]') .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemREADME.txt"]') + .perform(() => done()) }) + }) } } From ff07fa0ef7161dc7c8f2db181a089421ccbfc960 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 30 May 2024 13:56:52 +0200 Subject: [PATCH 31/60] fix test --- .../remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index b137f42af5..87caa9a626 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -67,8 +67,8 @@ module.exports = { .dragAndDrop('li[data-id="treeViewLitreeViewItemtests"]', id) .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/tests"]') - .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/README.txt"]') + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/tests"]', 5000) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/README.txt"]', 5000) .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemtests"]') .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemREADME.txt"]') .perform(() => done()) From ff556aeb4fc6165a5f532fa92293dba369350030 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 30 May 2024 15:01:27 +0200 Subject: [PATCH 32/60] add resetMultiselect --- .../workspace/src/lib/components/file-explorer.tsx | 7 +++++++ .../workspace/src/lib/components/flat-tree-drop.tsx | 1 + libs/remix-ui/workspace/src/lib/components/flat-tree.tsx | 2 ++ libs/remix-ui/workspace/src/lib/types/index.ts | 1 + 4 files changed, 11 insertions(+) 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 3d421830a1..10dea83d97 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -315,6 +315,12 @@ export const FileExplorer = (props: FileExplorerProps) => { } } + const resetMultiselect = () => { + setState((prevState) => { + return { ...prevState, ctrlKey: false } + }) + } + /** * This offers the ability to move a folder to a new location * without showing a modal dialong to the user. @@ -420,6 +426,7 @@ export const FileExplorer = (props: FileExplorerProps) => { warnMovingItems={warnMovingItems} moveFolderSilently={moveFolderSilently} moveFileSilently={moveFileSilently} + resetMultiselect={resetMultiselect} setFilesSelected={setFilesSelected} handleClickFolder={handleClickFolder} createNewFile={props.createNewFile} diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx index 75697137b2..d049a2bb6c 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx @@ -86,6 +86,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => { } }) await Promise.all(promises) + props.resetMultiselect() } return (
void moveFolderSilently: (dest: string, src: string) => Promise moveFileSilently: (dest: string, src: string) => Promise + resetMultiselect: () => void setFilesSelected: Dispatch> fileState: fileDecoration[] createNewFile?: any @@ -263,6 +264,7 @@ export const FlatTree = (props: FlatTreeProps) => { warnMovingItems={warnMovingItems} moveFolderSilently={moveFolderSilently} moveFileSilently={moveFileSilently} + resetMultiselect={props.resetMultiselect} setFilesSelected={setFilesSelected} handleClickFolder={handleClickFolder} expandPath={expandPath} diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index af6f5d95ac..684bf80046 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -346,6 +346,7 @@ export type Actions = {[A in keyof ActionPayloadTypes]: Action}[keyof ActionP export type WorkspaceElement = 'folder' | 'file' | 'workspace' export interface FlatTreeDropProps { + resetMultiselect: () => void moveFolderSilently: (dest: string, src: string) => Promise moveFileSilently: (dest: string, src: string) => Promise setFilesSelected: Dispatch> From 47ecf5ff24bc3f1034ea1dea8553eac6c4df9718 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Tue, 25 Jun 2024 13:26:58 +0100 Subject: [PATCH 33/60] changes to e2e --- .../src/tests/file_explorer_multiselect.test.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index 87caa9a626..e494e5bac2 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -11,11 +11,13 @@ module.exports = { const selectedElements = [] browser .openFile('contracts') - .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) - .findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]', locateStrategy: 'xpath' }, (el) => { + .pause() + // .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) + .click({ selector: '//*[@data-id="treeViewDivtreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) + .findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemcontracts/2_Owner.sol"]', locateStrategy: 'xpath' }, (el) => { selectedElements.push(el) }) - browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }, + browser.findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemtests"]', locateStrategy: 'xpath' }, (el: any) => { selectedElements.push(el) }) @@ -47,7 +49,7 @@ module.exports = { .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') .perform(() => done()) }) - }) + }) }, 'should drag and drop multiple files and folders in file explorer to contracts folder #group3': function (browser: NightwatchBrowser) { const selectedElements = [] @@ -73,6 +75,6 @@ module.exports = { .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemREADME.txt"]') .perform(() => done()) }) - }) + }) } } From 7bb1cea9f2cd339f04de8c166bf94bb27ccf9098 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Wed, 26 Jun 2024 09:48:08 +0100 Subject: [PATCH 34/60] fix e2e --- .../remix-ide-e2e/src/commands/selectFiles.ts | 5 +- .../tests/file_explorer_multiselect.test.ts | 63 ++++++++++--------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/apps/remix-ide-e2e/src/commands/selectFiles.ts b/apps/remix-ide-e2e/src/commands/selectFiles.ts index 86a2777440..544f36ba3d 100644 --- a/apps/remix-ide-e2e/src/commands/selectFiles.ts +++ b/apps/remix-ide-e2e/src/commands/selectFiles.ts @@ -8,15 +8,14 @@ class SelectFiles extends EventEmitter { browser.perform(function () { const actions = this.actions({ async: true }) actions.keyDown(this.Keys.SHIFT) - for(let i = 0; i < selectedElements.length; i++) { + for (let i = 0; i < selectedElements.length; i++) { actions.click(selectedElements[i].value) } - // return actions.contextClick(selectedElements[0].value) + return actions//.contextClick(selectedElements[0].value) }) this.emit('complete') return this } } - module.exports = SelectFiles diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index e494e5bac2..fdfa4c3e42 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -11,7 +11,6 @@ module.exports = { const selectedElements = [] browser .openFile('contracts') - .pause() // .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) .click({ selector: '//*[@data-id="treeViewDivtreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) .findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemcontracts/2_Owner.sol"]', locateStrategy: 'xpath' }, (el) => { @@ -29,27 +28,29 @@ module.exports = { 'Should drag and drop multiple files in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { const selectedElements = [] browser + .click({ selector: '//*[@data-id="treeViewUltreeViewMenu"]', locateStrategy: 'xpath' }) .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) .findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]', locateStrategy: 'xpath' }, (el) => { selectedElements.push(el) }) browser.selectFiles(selectedElements) - .perform((done) => { - browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }, - (el: any) => { - const id = (el as any).value.getId() - browser - .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests"]') - .dragAndDrop('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', id) - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/1_Storage.sol"]') - .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/2_Owner.sol"]') - .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') - .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') - .perform(() => done()) + .perform((done) => { + browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }, + (el: any) => { + const id = (el as any).value.getId() + browser + .pause() + .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests"]') + .dragAndDrop('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', id) + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/1_Storage.sol"]') + .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/2_Owner.sol"]') + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') + .perform(() => done()) + }) }) - }) }, 'should drag and drop multiple files and folders in file explorer to contracts folder #group3': function (browser: NightwatchBrowser) { const selectedElements = [] @@ -60,21 +61,21 @@ module.exports = { selectedElements.push(el) }) browser.selectFiles(selectedElements) - .perform((done) => { - browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts"]', locateStrategy: 'xpath' }, - (el: any) => { - const id = (el as any).value.getId() - browser - .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts"]') - .dragAndDrop('li[data-id="treeViewLitreeViewItemtests"]', id) - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/tests"]', 5000) - .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/README.txt"]', 5000) - .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemtests"]') - .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemREADME.txt"]') - .perform(() => done()) + .perform((done) => { + browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts"]', locateStrategy: 'xpath' }, + (el: any) => { + const id = (el as any).value.getId() + browser + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts"]') + .dragAndDrop('li[data-id="treeViewLitreeViewItemtests"]', id) + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/tests"]', 5000) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/README.txt"]', 5000) + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemtests"]') + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemREADME.txt"]') + .perform(() => done()) + }) }) - }) } } From b40d6dd9945fb8985f8ed1c23423e9aa8a515c8d Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Wed, 26 Jun 2024 11:06:29 +0100 Subject: [PATCH 35/60] fixed more e2e --- .../src/tests/file_explorer_multiselect.test.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index fdfa4c3e42..6707b1ca7f 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -11,7 +11,6 @@ module.exports = { const selectedElements = [] browser .openFile('contracts') - // .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) .click({ selector: '//*[@data-id="treeViewDivtreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) .findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemcontracts/2_Owner.sol"]', locateStrategy: 'xpath' }, (el) => { selectedElements.push(el) @@ -39,7 +38,6 @@ module.exports = { (el: any) => { const id = (el as any).value.getId() browser - .pause() .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests"]') .dragAndDrop('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', id) .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') @@ -57,7 +55,11 @@ module.exports = { browser .clickLaunchIcon('filePanel') .click({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }) - .findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemREADME.txt"]', locateStrategy: 'xpath' }, (el) => { + .findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemscripts"]', locateStrategy: 'xpath' }, (el) => { + selectedElements.push(el) + }) + browser.findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemREADME.txt"]', locateStrategy: 'xpath' }, + (el: any) => { selectedElements.push(el) }) browser.selectFiles(selectedElements) @@ -72,6 +74,7 @@ module.exports = { .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/tests"]', 5000) .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/README.txt"]', 5000) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/scripts"]', 5000) .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemtests"]') .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemREADME.txt"]') .perform(() => done()) From ae23e6698abca77370d239f6fe6ff39eca4a5693 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 27 Jun 2024 22:51:35 +0100 Subject: [PATCH 36/60] address firefox failure --- apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index 6707b1ca7f..434e2d1111 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -26,6 +26,7 @@ module.exports = { }, 'Should drag and drop multiple files in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { const selectedElements = [] + if (browser.browserName.indexOf('firefox') > -1) return browser .click({ selector: '//*[@data-id="treeViewUltreeViewMenu"]', locateStrategy: 'xpath' }) .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) From 0face74a39b8471bb19c67c9deb6ec4c733a1907 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 27 Jun 2024 23:23:52 +0100 Subject: [PATCH 37/60] end session correctly for firefox --- .../src/tests/file_explorer_multiselect.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index 434e2d1111..77224ad604 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -26,7 +26,11 @@ module.exports = { }, 'Should drag and drop multiple files in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { const selectedElements = [] - if (browser.browserName.indexOf('firefox') > -1) return + if (browser.options.desiredCapabilities.browserName === 'firefox') { + console.log('Skipping test for Firefox') + browser.end() + return + } browser .click({ selector: '//*[@data-id="treeViewUltreeViewMenu"]', locateStrategy: 'xpath' }) .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) From a384fd88d32f21ab11f77ace4bd7b0fbd38ac837 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 27 Jun 2024 23:43:43 +0100 Subject: [PATCH 38/60] fix e2e --- .../src/tests/file_explorer_multiselect.test.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index 77224ad604..1e1df4309b 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -26,11 +26,7 @@ module.exports = { }, 'Should drag and drop multiple files in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { const selectedElements = [] - if (browser.options.desiredCapabilities.browserName === 'firefox') { - console.log('Skipping test for Firefox') - browser.end() - return - } + browser .click({ selector: '//*[@data-id="treeViewUltreeViewMenu"]', locateStrategy: 'xpath' }) .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) From b35520ba229e97dfa2cb9274457118f5d2d1733e Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Thu, 4 Jul 2024 21:09:58 +0100 Subject: [PATCH 39/60] Add padding to right side panel --- libs/remix-ui/app/src/lib/remix-app/style/remix-app.css | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/remix-ui/app/src/lib/remix-app/style/remix-app.css b/libs/remix-ui/app/src/lib/remix-app/style/remix-app.css index 8c56059bfb..a1d447e8a5 100644 --- a/libs/remix-ui/app/src/lib/remix-app/style/remix-app.css +++ b/libs/remix-ui/app/src/lib/remix-app/style/remix-app.css @@ -43,6 +43,7 @@ pre { .pinnedpanel { width : 320px; transition : width 0.25s; + padding-bottom : 1.4rem; } .highlightcode { position : absolute; From d803514fda14ad2cf6603b23b306268739f82f16 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 8 Jul 2024 14:59:05 +0100 Subject: [PATCH 40/60] disabled test for firefox --- .../src/tests/file_explorer_multiselect.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index 1e1df4309b..701afb9b27 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -26,6 +26,11 @@ module.exports = { }, 'Should drag and drop multiple files in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { const selectedElements = [] + if (browser.options.desiredCapabilities?.browserName === 'firefox') { + console.log('Skipping test for firefox') + browser.end() + return; + } browser .click({ selector: '//*[@data-id="treeViewUltreeViewMenu"]', locateStrategy: 'xpath' }) From 92d9257f4186c1928cef6515921f79a82217270c Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 8 Jul 2024 17:02:09 +0100 Subject: [PATCH 41/60] disable flaky test --- apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index 701afb9b27..e9852fd6b6 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -24,7 +24,7 @@ module.exports = { .assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') .assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemtests"]') }, - 'Should drag and drop multiple files in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { + 'Should drag and drop multiple files in file explorer to tests folder #group1': ''+function (browser: NightwatchBrowser) { const selectedElements = [] if (browser.options.desiredCapabilities?.browserName === 'firefox') { console.log('Skipping test for firefox') From c21f26b41a5c1789f0507b311e05c5d091285009 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 8 Jul 2024 23:18:44 +0100 Subject: [PATCH 42/60] deal with flaky test --- .../tests/file_explorer_multiselect.test.ts | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index e9852fd6b6..c38a0673ed 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -24,37 +24,37 @@ module.exports = { .assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') .assert.visible('.bg-secondary[data-id="treeViewLitreeViewItemtests"]') }, - 'Should drag and drop multiple files in file explorer to tests folder #group1': ''+function (browser: NightwatchBrowser) { + 'Should drag and drop multiple files in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { const selectedElements = [] if (browser.options.desiredCapabilities?.browserName === 'firefox') { console.log('Skipping test for firefox') browser.end() return; + } else { + browser + .click({ selector: '//*[@data-id="treeViewUltreeViewMenu"]', locateStrategy: 'xpath' }) + .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) + .findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]', locateStrategy: 'xpath' }, (el) => { + selectedElements.push(el) + }) + browser.selectFiles(selectedElements) + .perform((done) => { + browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }, + (el: any) => { + const id = (el as any).value.getId() + browser + .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests"]') + .dragAndDrop('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', id) + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/1_Storage.sol"]') + .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/2_Owner.sol"]') + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') + .perform(() => done()) + }) + }) } - - browser - .click({ selector: '//*[@data-id="treeViewUltreeViewMenu"]', locateStrategy: 'xpath' }) - .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) - .findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]', locateStrategy: 'xpath' }, (el) => { - selectedElements.push(el) - }) - browser.selectFiles(selectedElements) - .perform((done) => { - browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }, - (el: any) => { - const id = (el as any).value.getId() - browser - .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests"]') - .dragAndDrop('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', id) - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/1_Storage.sol"]') - .waitForElementVisible('li[data-id="treeViewLitreeViewItemtests/2_Owner.sol"]') - .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') - .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemcontracts/2_Owner.sol"]') - .perform(() => done()) - }) - }) }, 'should drag and drop multiple files and folders in file explorer to contracts folder #group3': function (browser: NightwatchBrowser) { const selectedElements = [] From 9a2c690ff3ebeb4c66f4e19992ea891a6e834f55 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 1 Jul 2024 14:25:05 +0100 Subject: [PATCH 43/60] prepare to handle shortcut keys --- .../workspace/src/lib/components/file-explorer.tsx | 13 +++++++++++++ libs/remix-ui/workspace/src/lib/types/index.ts | 3 +++ 2 files changed, 16 insertions(+) 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 e3b301901c..7831f93124 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -96,6 +96,19 @@ export const FileExplorer = (props: FileExplorerProps) => { } }, [treeRef.current]) + useEffect(() => { + const deleteKeyPressHandler = (eve: KeyboardEvent) => { + if (eve.key === 'Delete' || eve.key === 'Backspace' ) { + console.log('delete key was pressed') + } + } + + treeRef.current?.addEventListener('keydown', deleteKeyPressHandler) + return () => { + treeRef.current?.removeEventListener('keydown', deleteKeyPressHandler) + } + }, []) + const hasReservedKeyword = (content: string): boolean => { if (state.reservedKeywords.findIndex((value) => content.startsWith(value)) !== -1) return true else return false diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index aff1b70bd8..89c50f79fa 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -201,6 +201,9 @@ export interface FileExplorerContextMenuProps { export interface WorkSpaceState { ctrlKey: boolean + deleteKey?: boolean + backspaceKey?: boolean + F2Key?: boolean newFileName: string actions: { id: string From 091fb3b2b1645ebb3f5f16976afb49bca7f1caa7 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Tue, 9 Jul 2024 13:41:11 +0100 Subject: [PATCH 44/60] add delete behaviour. add rename behaviour --- .../src/lib/components/file-explorer.tsx | 69 ++++++++++++++++--- .../src/lib/components/flat-tree.tsx | 8 +++ 2 files changed, 69 insertions(+), 8 deletions(-) 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 7831f93124..31011a98cd 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useRef, SyntheticEvent } from 'react' // eslint-disable-line +import React, { useEffect, useState, useRef, SyntheticEvent, useContext } from 'react' // eslint-disable-line import { useIntl } from 'react-intl' import { TreeView } from '@remix-ui/tree-view' // eslint-disable-line import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line @@ -11,6 +11,7 @@ import { checkSpecialChars, extractNameFromKey, extractParentFromKey, getPathIco import { ROOT_PATH } from '../utils/constants' import { moveFileIsAllowed, moveFolderIsAllowed } from '../actions' import { FlatTree } from './flat-tree' +import { FileSystemContext } from '../contexts' export const FileExplorer = (props: FileExplorerProps) => { const intl = useIntl() @@ -35,6 +36,8 @@ export const FileExplorer = (props: FileExplorerProps) => { const [state, setState] = useState(workspaceState) // const [isPending, startTransition] = useTransition(); const treeRef = useRef(null) + const { plugin } = useContext(FileSystemContext) + const [feTarget, setFeTarget] = useState<{ key: string, type: 'file' | 'folder' }[]>({} as { key: string, type: 'file' | 'folder' }[]) useEffect(() => { if (contextMenuItems) { @@ -97,17 +100,62 @@ export const FileExplorer = (props: FileExplorerProps) => { }, [treeRef.current]) useEffect(() => { - const deleteKeyPressHandler = (eve: KeyboardEvent) => { - if (eve.key === 'Delete' || eve.key === 'Backspace' ) { - console.log('delete key was pressed') + const performDeleteion = async () => { + const path: string[] = [] + if (feTarget?.length > 0 && feTarget[0]?.key.length > 0) { + feTarget.forEach((one) => { + path.push(one.key) + }) + await deletePath(path) + } + } + + if (treeRef.current) { + const deleteKeyPressHandler = async (eve: KeyboardEvent) => { + eve.preventDefault() + if (eve.key === 'Delete' ) { + performDeleteion() + return + } + if (eve.metaKey) { + eve.preventDefault() + if (eve.key === 'Backspace') { + performDeleteion() + return + } + } + } + + treeRef.current?.addEventListener('keydown', deleteKeyPressHandler) + return () => { + treeRef.current?.removeEventListener('keydown', deleteKeyPressHandler) } } + }, [treeRef.current, feTarget]) - treeRef.current?.addEventListener('keydown', deleteKeyPressHandler) - return () => { - treeRef.current?.removeEventListener('keydown', deleteKeyPressHandler) + useEffect(() => { + const performRename = async () => { + if (feTarget?.length > 0 && feTarget[0]?.key.length > 0) { + await plugin.call('notification', 'alert', { id: 'renameAlert', message: 'You cannot rename multiple files at once!' }) + } + await props.dispatchRenamePath(feTarget[0].key, feTarget[0].type) } - }, []) + if (treeRef.current) { + const F2KeyPressHandler = async (eve: KeyboardEvent) => { + eve.preventDefault() + if (eve.key === 'F2' ) { + console.log('F2 key was pressed so renaming happening') + await performRename() + return + } + } + + treeRef.current?.addEventListener('keydown', F2KeyPressHandler) + return () => { + treeRef.current?.removeEventListener('keydown', F2KeyPressHandler) + } + } + }, [treeRef.current]) const hasReservedKeyword = (content: string): boolean => { if (state.reservedKeywords.findIndex((value) => content.startsWith(value)) !== -1) return true @@ -348,6 +396,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleTreeClick = (event: SyntheticEvent) => { + console.log({ props, state }) let target = event.target as HTMLElement while (target && target.getAttribute && !target.getAttribute('data-path')) { target = target.parentElement @@ -369,6 +418,8 @@ export const FileExplorer = (props: FileExplorerProps) => { } + console.log(feTarget) + return (
{ createNewFolder={props.createNewFolder} deletePath={deletePath} editPath={props.editModeOn} + fileTarget={feTarget} + setTargetFiles={setFeTarget} />
diff --git a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx index db5a960cbe..df9e615441 100644 --- a/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx +++ b/libs/remix-ui/workspace/src/lib/components/flat-tree.tsx @@ -25,6 +25,8 @@ export default function useOnScreen(ref: RefObject) { return isIntersecting } interface FlatTreeProps { + fileTarget: any + setTargetFiles: React.Dispatch files: { [x: string]: Record }, flatTree: FileType[], expandPath: string[], @@ -79,6 +81,12 @@ export const FlatTree = (props: FlatTreeProps) => { ? 'bg-light border-no-shift' : '' + useEffect(() => { + if (props.focusElement && props.focusElement.length > 0) { + props.setTargetFiles(props.focusElement) + } + }, [props.focusElement, props.focusElement.length]) + const getIndentLevelDiv = (path: string) => { // remove double slash path = path.replace(/\/\//g, '/') From 8d3fdd2055b031f28de3dc49fb09eb56f176c2c8 Mon Sep 17 00:00:00 2001 From: shubhiscoding Date: Sat, 6 Jul 2024 01:18:30 +0530 Subject: [PATCH 45/60] Solved Undeclared EVM Logs aren't shown in receipt UI #4929 --- libs/remix-ui/terminal/src/lib/components/Table.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/terminal/src/lib/components/Table.tsx b/libs/remix-ui/terminal/src/lib/components/Table.tsx index 5aa3823f00..abfd2055fc 100644 --- a/libs/remix-ui/terminal/src/lib/components/Table.tsx +++ b/libs/remix-ui/terminal/src/lib/components/Table.tsx @@ -186,9 +186,9 @@ const showTable = (opts, showTableHash) => { - {JSON.stringify(stringified, null, '\t')} + {JSON.stringify(opts.logs.raw, null, 2)?(
{JSON.stringify(opts.logs.raw || '0', null, 2)}
):(JSON.stringify(stringified, null, '\t'))} - + ) : null} From 77420ea7a88ae7324d9e669d9468ca88984b9969 Mon Sep 17 00:00:00 2001 From: shubhiscoding Date: Mon, 8 Jul 2024 23:31:11 +0530 Subject: [PATCH 46/60] seperated declared and undeclared logs --- .../src/app/tabs/locales/en/terminal.json | 3 ++- .../src/app/tabs/locales/es/terminal.json | 3 ++- .../src/app/tabs/locales/fr/terminal.json | 3 ++- .../src/app/tabs/locales/it/terminal.json | 3 ++- .../src/app/tabs/locales/ko/terminal.json | 3 ++- .../src/app/tabs/locales/ru/terminal.json | 3 ++- .../src/app/tabs/locales/zh/terminal.json | 3 ++- .../remix-ui/terminal/src/lib/components/Table.tsx | 14 ++++++++++++-- package.json | 5 +++-- 9 files changed, 29 insertions(+), 11 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/locales/en/terminal.json b/apps/remix-ide/src/app/tabs/locales/en/terminal.json index 431f54fbba..da76845fcd 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/en/terminal.json @@ -40,5 +40,6 @@ "terminal.input": "input", "terminal.decodedInput": "decoded input", "terminal.decodedOutput": "decoded output", - "terminal.logs": "logs" + "terminal.undeclaredlogs": "undeclared logs", + "terminal.declaredlogs": "declared logs" } diff --git a/apps/remix-ide/src/app/tabs/locales/es/terminal.json b/apps/remix-ide/src/app/tabs/locales/es/terminal.json index 9c59e05ada..a916bb1db1 100644 --- a/apps/remix-ide/src/app/tabs/locales/es/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/es/terminal.json @@ -39,5 +39,6 @@ "terminal.input": "entrada", "terminal.decodedInput": "entrada descodificada", "terminal.decodedOutput": "salida descodificada", - "terminal.logs": "registros" + "terminal.undeclaredlogs": "registros no declarados", + "terminal.declaredlogs": "registros declarados" } diff --git a/apps/remix-ide/src/app/tabs/locales/fr/terminal.json b/apps/remix-ide/src/app/tabs/locales/fr/terminal.json index 8183140a97..96c96d9b3d 100644 --- a/apps/remix-ide/src/app/tabs/locales/fr/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/fr/terminal.json @@ -39,5 +39,6 @@ "terminal.input": "entrée", "terminal.decodedInput": "entrée décodée", "terminal.decodedOutput": "sortie décodée", - "terminal.logs": "logs" + "terminal.undeclaredlogs": "logs non déclarés", + "terminal.declaredlogs": "logs déclarés" } diff --git a/apps/remix-ide/src/app/tabs/locales/it/terminal.json b/apps/remix-ide/src/app/tabs/locales/it/terminal.json index 8bdc6c7dc8..c6c050bf86 100644 --- a/apps/remix-ide/src/app/tabs/locales/it/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/it/terminal.json @@ -39,5 +39,6 @@ "terminal.input": "input", "terminal.decodedInput": "input decodificato", "terminal.decodedOutput": "output decodificato", - "terminal.logs": "Log" + "terminal.undeclaredlogs": "log non dichiarati", + "terminal.declaredlogs": "log dichiarati" } diff --git a/apps/remix-ide/src/app/tabs/locales/ko/terminal.json b/apps/remix-ide/src/app/tabs/locales/ko/terminal.json index 171a981094..828edd36fd 100644 --- a/apps/remix-ide/src/app/tabs/locales/ko/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/ko/terminal.json @@ -39,5 +39,6 @@ "terminal.input": "입력", "terminal.decodedInput": "디코드된 입력", "terminal.decodedOutput": "디코드된 출력", - "terminal.logs": "로그" + "terminal.undeclaredlogs": "선언되지 않은 로그", + "terminal.declaredlogs": "선언된 로그" } diff --git a/apps/remix-ide/src/app/tabs/locales/ru/terminal.json b/apps/remix-ide/src/app/tabs/locales/ru/terminal.json index 2778fb35de..0a3f7f744e 100644 --- a/apps/remix-ide/src/app/tabs/locales/ru/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/ru/terminal.json @@ -39,5 +39,6 @@ "terminal.input": "ввод", "terminal.decodedInput": "декодированный ввод", "terminal.decodedOutput": "декодированный вывод", - "terminal.logs": "журналы" + "terminal.undeclaredlogs": "необъявленные журналы", + "terminal.declaredlogs": "объявленные журналы" } diff --git a/apps/remix-ide/src/app/tabs/locales/zh/terminal.json b/apps/remix-ide/src/app/tabs/locales/zh/terminal.json index 40e6d3791c..975a0f601e 100644 --- a/apps/remix-ide/src/app/tabs/locales/zh/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/zh/terminal.json @@ -39,5 +39,6 @@ "terminal.input": "输入", "terminal.decodedInput": "解码输入", "terminal.decodedOutput": "解码输出", - "terminal.logs": "日志" + "terminal.undeclaredlogs": "未声明的日志", + "terminal.declaredlogs": "已声明的日志" } diff --git a/libs/remix-ui/terminal/src/lib/components/Table.tsx b/libs/remix-ui/terminal/src/lib/components/Table.tsx index abfd2055fc..da90540cbc 100644 --- a/libs/remix-ui/terminal/src/lib/components/Table.tsx +++ b/libs/remix-ui/terminal/src/lib/components/Table.tsx @@ -183,11 +183,21 @@ const showTable = (opts, showTableHash) => { {opts.logs ? ( - + - {JSON.stringify(opts.logs.raw, null, 2)?(
{JSON.stringify(opts.logs.raw || '0', null, 2)}
):(JSON.stringify(stringified, null, '\t'))} + {JSON.stringify(stringified, null, '\t')} + + + ) : null} + {opts.logs ? ( + + + + + +
{JSON.stringify(opts.logs.raw || '0', null, 2)}
diff --git a/package.json b/package.json index bec82a4009..ca75f30147 100644 --- a/package.json +++ b/package.json @@ -98,10 +98,10 @@ "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", "@ethersphere/bee-js": "^3.2.0", + "@floating-ui/react": "^0.26.15", "@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", - "@floating-ui/react": "^0.26.15", "@gradio/client": "^0.10.1", "@isomorphic-git/lightning-fs": "^4.4.1", "@metamask/eth-sig-util": "^7.0.2", @@ -211,6 +211,7 @@ "tree-kill": "^1.2.2", "ts-loader": "^9.2.6", "tslib": "^2.3.0", + "util": "^0.12.5", "web3": "^4.1.0", "winston": "^3.3.3", "ws": "^7.3.0", @@ -317,7 +318,7 @@ "eslint-plugin-react": "7.31.8", "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-standard": "4.0.1", - "events": "^3.0.0", + "events": "^3.3.0", "execr": "^1.0.1", "exorcist": "^0.4.0", "exports-loader": "^1.1.0", From 3e6867f20ad2d1ff2b261d3c0d7a357cddb7a60f Mon Sep 17 00:00:00 2001 From: shubhiscoding Date: Tue, 9 Jul 2024 01:49:06 +0530 Subject: [PATCH 47/60] reverted changes in package.json and made undeclared, declared logs as raw logs and logs --- apps/remix-ide/src/app/tabs/locales/en/terminal.json | 4 ++-- apps/remix-ide/src/app/tabs/locales/es/terminal.json | 4 ++-- apps/remix-ide/src/app/tabs/locales/fr/terminal.json | 4 ++-- apps/remix-ide/src/app/tabs/locales/it/terminal.json | 4 ++-- apps/remix-ide/src/app/tabs/locales/ko/terminal.json | 4 ++-- apps/remix-ide/src/app/tabs/locales/ru/terminal.json | 4 ++-- apps/remix-ide/src/app/tabs/locales/zh/terminal.json | 4 ++-- libs/remix-lib/package.json | 2 +- libs/remix-ui/terminal/src/lib/components/Table.tsx | 5 +++-- package.json | 5 ++--- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/locales/en/terminal.json b/apps/remix-ide/src/app/tabs/locales/en/terminal.json index da76845fcd..9ce7d78d6f 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/en/terminal.json @@ -40,6 +40,6 @@ "terminal.input": "input", "terminal.decodedInput": "decoded input", "terminal.decodedOutput": "decoded output", - "terminal.undeclaredlogs": "undeclared logs", - "terminal.declaredlogs": "declared logs" + "terminal.rawlogs": "raw logs", + "terminal.logs": "logs" } diff --git a/apps/remix-ide/src/app/tabs/locales/es/terminal.json b/apps/remix-ide/src/app/tabs/locales/es/terminal.json index a916bb1db1..17eb3d6a40 100644 --- a/apps/remix-ide/src/app/tabs/locales/es/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/es/terminal.json @@ -39,6 +39,6 @@ "terminal.input": "entrada", "terminal.decodedInput": "entrada descodificada", "terminal.decodedOutput": "salida descodificada", - "terminal.undeclaredlogs": "registros no declarados", - "terminal.declaredlogs": "registros declarados" + "terminal.rawlogs": "registros sin procesar", + "terminal.logs": "registros" } diff --git a/apps/remix-ide/src/app/tabs/locales/fr/terminal.json b/apps/remix-ide/src/app/tabs/locales/fr/terminal.json index 96c96d9b3d..e67a0c7b4f 100644 --- a/apps/remix-ide/src/app/tabs/locales/fr/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/fr/terminal.json @@ -39,6 +39,6 @@ "terminal.input": "entrée", "terminal.decodedInput": "entrée décodée", "terminal.decodedOutput": "sortie décodée", - "terminal.undeclaredlogs": "logs non déclarés", - "terminal.declaredlogs": "logs déclarés" + "terminal.rawlogs": "logs bruts", + "terminal.logs": "Log" } diff --git a/apps/remix-ide/src/app/tabs/locales/it/terminal.json b/apps/remix-ide/src/app/tabs/locales/it/terminal.json index c6c050bf86..19653883b1 100644 --- a/apps/remix-ide/src/app/tabs/locales/it/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/it/terminal.json @@ -39,6 +39,6 @@ "terminal.input": "input", "terminal.decodedInput": "input decodificato", "terminal.decodedOutput": "output decodificato", - "terminal.undeclaredlogs": "log non dichiarati", - "terminal.declaredlogs": "log dichiarati" + "terminal.rawlogs": "log grezzi", + "terminal.logs": "Log" } diff --git a/apps/remix-ide/src/app/tabs/locales/ko/terminal.json b/apps/remix-ide/src/app/tabs/locales/ko/terminal.json index 828edd36fd..23db143c61 100644 --- a/apps/remix-ide/src/app/tabs/locales/ko/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/ko/terminal.json @@ -39,6 +39,6 @@ "terminal.input": "입력", "terminal.decodedInput": "디코드된 입력", "terminal.decodedOutput": "디코드된 출력", - "terminal.undeclaredlogs": "선언되지 않은 로그", - "terminal.declaredlogs": "선언된 로그" + "terminal.rawlogs": "원시 로그", + "terminal.logs": "로그" } diff --git a/apps/remix-ide/src/app/tabs/locales/ru/terminal.json b/apps/remix-ide/src/app/tabs/locales/ru/terminal.json index 0a3f7f744e..6d10549196 100644 --- a/apps/remix-ide/src/app/tabs/locales/ru/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/ru/terminal.json @@ -39,6 +39,6 @@ "terminal.input": "ввод", "terminal.decodedInput": "декодированный ввод", "terminal.decodedOutput": "декодированный вывод", - "terminal.undeclaredlogs": "необъявленные журналы", - "terminal.declaredlogs": "объявленные журналы" + "terminal.rawlogs": "необработанные журналы", + "terminal.logs": "журналы" } diff --git a/apps/remix-ide/src/app/tabs/locales/zh/terminal.json b/apps/remix-ide/src/app/tabs/locales/zh/terminal.json index 975a0f601e..eac8de2d0b 100644 --- a/apps/remix-ide/src/app/tabs/locales/zh/terminal.json +++ b/apps/remix-ide/src/app/tabs/locales/zh/terminal.json @@ -39,6 +39,6 @@ "terminal.input": "输入", "terminal.decodedInput": "解码输入", "terminal.decodedOutput": "解码输出", - "terminal.undeclaredlogs": "未声明的日志", - "terminal.declaredlogs": "已声明的日志" + "terminal.rawlogs": "原始日志", + "terminal.logs": "日志" } diff --git a/libs/remix-lib/package.json b/libs/remix-lib/package.json index fac86e3732..dffc187d0a 100644 --- a/libs/remix-lib/package.json +++ b/libs/remix-lib/package.json @@ -57,4 +57,4 @@ "typings": "src/index.d.ts", "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55", "types": "./src/index.d.ts" -} \ No newline at end of file +} diff --git a/libs/remix-ui/terminal/src/lib/components/Table.tsx b/libs/remix-ui/terminal/src/lib/components/Table.tsx index da90540cbc..90a2b40032 100644 --- a/libs/remix-ui/terminal/src/lib/components/Table.tsx +++ b/libs/remix-ui/terminal/src/lib/components/Table.tsx @@ -183,18 +183,19 @@ const showTable = (opts, showTableHash) => { {opts.logs ? ( - + {JSON.stringify(stringified, null, '\t')} + ) : null} {opts.logs ? ( - +
{JSON.stringify(opts.logs.raw || '0', null, 2)}
diff --git a/package.json b/package.json index ca75f30147..bec82a4009 100644 --- a/package.json +++ b/package.json @@ -98,10 +98,10 @@ "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", "@ethersphere/bee-js": "^3.2.0", - "@floating-ui/react": "^0.26.15", "@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", + "@floating-ui/react": "^0.26.15", "@gradio/client": "^0.10.1", "@isomorphic-git/lightning-fs": "^4.4.1", "@metamask/eth-sig-util": "^7.0.2", @@ -211,7 +211,6 @@ "tree-kill": "^1.2.2", "ts-loader": "^9.2.6", "tslib": "^2.3.0", - "util": "^0.12.5", "web3": "^4.1.0", "winston": "^3.3.3", "ws": "^7.3.0", @@ -318,7 +317,7 @@ "eslint-plugin-react": "7.31.8", "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-standard": "4.0.1", - "events": "^3.3.0", + "events": "^3.0.0", "execr": "^1.0.1", "exorcist": "^0.4.0", "exports-loader": "^1.1.0", From e3eaf9dfd883b6230b460a6d894ded32114952ac Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Wed, 10 Jul 2024 12:15:25 +0100 Subject: [PATCH 48/60] fix state bug --- .../src/lib/components/file-explorer.tsx | 44 ++++++++++++++++--- .../remix-ui/workspace/src/lib/types/index.ts | 1 - 2 files changed, 39 insertions(+), 6 deletions(-) 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 31011a98cd..23783919b9 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -112,14 +112,35 @@ export const FileExplorer = (props: FileExplorerProps) => { if (treeRef.current) { const deleteKeyPressHandler = async (eve: KeyboardEvent) => { - eve.preventDefault() if (eve.key === 'Delete' ) { + setState((prevState) => { + return { ...prevState, deleteKey: true } + }) performDeleteion() return } if (eve.metaKey) { - eve.preventDefault() if (eve.key === 'Backspace') { + setState((prevState) => { + return { ...prevState, deleteKey: true } + }) + performDeleteion() + return + } + } + } + const deleteKeyPressUpHandler = async (eve: KeyboardEvent) => { + if (eve.key === 'Delete' ) { + setState((prevState) => { + return { ...prevState, deleteKey: false } + }) + return + } + if (eve.metaKey) { + if (eve.key === 'Backspace') { + setState((prevState) => { + return { ...prevState, deleteKey: false } + }) performDeleteion() return } @@ -127,8 +148,10 @@ export const FileExplorer = (props: FileExplorerProps) => { } treeRef.current?.addEventListener('keydown', deleteKeyPressHandler) + treeRef.current?.addEventListener('keyup', deleteKeyPressUpHandler) return () => { treeRef.current?.removeEventListener('keydown', deleteKeyPressHandler) + treeRef.current?.addEventListener('keyup', deleteKeyPressUpHandler) } } }, [treeRef.current, feTarget]) @@ -142,20 +165,31 @@ export const FileExplorer = (props: FileExplorerProps) => { } if (treeRef.current) { const F2KeyPressHandler = async (eve: KeyboardEvent) => { - eve.preventDefault() if (eve.key === 'F2' ) { - console.log('F2 key was pressed so renaming happening') await performRename() + setState((prevState) => { + return { ...prevState, F2Key: true } + }) + return + } + } + const F2KeyPressUpHandler = async (eve: KeyboardEvent) => { + if (eve.key === 'F2' ) { + setState((prevState) => { + return { ...prevState, F2Key: false } + }) return } } treeRef.current?.addEventListener('keydown', F2KeyPressHandler) + treeRef.current?.addEventListener('keyup', F2KeyPressUpHandler) return () => { treeRef.current?.removeEventListener('keydown', F2KeyPressHandler) + treeRef.current?.addEventListener('keyup', F2KeyPressUpHandler) } } - }, [treeRef.current]) + }, [treeRef.current, feTarget]) const hasReservedKeyword = (content: string): boolean => { if (state.reservedKeywords.findIndex((value) => content.startsWith(value)) !== -1) return true diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index 89c50f79fa..a1c71efa2f 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -202,7 +202,6 @@ export interface FileExplorerContextMenuProps { export interface WorkSpaceState { ctrlKey: boolean deleteKey?: boolean - backspaceKey?: boolean F2Key?: boolean newFileName: string actions: { From 5ae3b0abbf7ccb88c046fd2b646460893bdc4fbd Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Wed, 10 Jul 2024 12:33:08 +0100 Subject: [PATCH 49/60] fix F2 rename bug --- libs/remix-ui/workspace/src/lib/components/file-explorer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 23783919b9..f7cd390bc6 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -158,10 +158,10 @@ export const FileExplorer = (props: FileExplorerProps) => { useEffect(() => { const performRename = async () => { - if (feTarget?.length > 0 && feTarget[0]?.key.length > 0) { + if (feTarget?.length > 1 && feTarget[0]?.key.length > 1) { await plugin.call('notification', 'alert', { id: 'renameAlert', message: 'You cannot rename multiple files at once!' }) } - await props.dispatchRenamePath(feTarget[0].key, feTarget[0].type) + await props.editModeOn(feTarget[0].key, feTarget[0].type, false) } if (treeRef.current) { const F2KeyPressHandler = async (eve: KeyboardEvent) => { From 8df0b582274cd6774490bdf67ece8f42f21208d2 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Wed, 10 Jul 2024 12:41:52 +0100 Subject: [PATCH 50/60] clean console log --- libs/remix-ui/workspace/src/lib/components/file-explorer.tsx | 2 -- 1 file changed, 2 deletions(-) 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 f7cd390bc6..866419d9eb 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -452,8 +452,6 @@ export const FileExplorer = (props: FileExplorerProps) => { } - console.log(feTarget) - return (
Date: Wed, 10 Jul 2024 15:28:31 +0200 Subject: [PATCH 51/60] git name change --- apps/remix-ide/src/app/plugins/git.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/remix-ide/src/app/plugins/git.tsx b/apps/remix-ide/src/app/plugins/git.tsx index 35129dfceb..73331d87ed 100644 --- a/apps/remix-ide/src/app/plugins/git.tsx +++ b/apps/remix-ide/src/app/plugins/git.tsx @@ -6,6 +6,7 @@ import * as packageJson from '../../../../../package.json' const profile = { name: 'dgit', + displayName: 'Git', desciption: 'Git plugin for Remix', methods: ['pull', 'track', 'diff', 'clone', 'open'], events: [''], From e23f8c0f784aac2dc8c3eddd61e18f9dc4d33365 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Wed, 10 Jul 2024 20:22:31 +0100 Subject: [PATCH 52/60] Update _paq.push implementation --- .../src/app/services/circomPluginClient.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/circuit-compiler/src/app/services/circomPluginClient.ts b/apps/circuit-compiler/src/app/services/circomPluginClient.ts index 50cb710d68..93a2445861 100644 --- a/apps/circuit-compiler/src/app/services/circomPluginClient.ts +++ b/apps/circuit-compiler/src/app/services/circomPluginClient.ts @@ -10,8 +10,6 @@ import * as compilerV215 from 'circom_wasm/v2.1.5' import { extractNameFromKey, extractParentFromKey } from '@remix-ui/helper' import { CompilationConfig, CompilerReport, PrimeValue, ResolverOutput } from '../types' -// @ts-ignore -const _paq = (window._paq = window._paq || []) export class CircomPluginClient extends PluginClient { public internalEvents: EventManager private _compilationConfig: CompilationConfig = { @@ -22,6 +20,11 @@ export class CircomPluginClient extends PluginClient { private lastParsedFiles: Record = {} private lastCompiledFile: string = '' private compiler: typeof compilerV215 & typeof compilerV216 & typeof compilerV217 & typeof compilerV218 + private _paq = { + push: (args) => { + this.call('matomo' as any, 'track', args) + } + } constructor() { super() @@ -164,7 +167,7 @@ export class CircomPluginClient extends PluginClient { const circuitErrors = circuitApi.report() this.logCompilerReport(circuitErrors) - _paq.push(['trackEvent', 'circuit-compiler', 'compile', 'Compilation failed']) + this._paq.push(['trackEvent', 'circuit-compiler', 'compile', 'Compilation failed']) throw new Error(circuitErrors) } else { this.lastCompiledFile = path @@ -184,7 +187,7 @@ export class CircomPluginClient extends PluginClient { } else { this.internalEvents.emit('circuit_compiling_done', []) } - _paq.push(['trackEvent', 'circuit-compiler', 'compile', 'Compilation successful']) + this._paq.push(['trackEvent', 'circuit-compiler', 'compile', 'Compilation successful']) circuitApi.log().map(log => { log && this.call('terminal', 'log', { type: 'log', value: log }) }) @@ -226,7 +229,7 @@ export class CircomPluginClient extends PluginClient { const r1csErrors = r1csApi.report() this.logCompilerReport(r1csErrors) - _paq.push(['trackEvent', 'circuit-compiler', 'generateR1cs', 'R1CS Generation failed']) + this._paq.push(['trackEvent', 'circuit-compiler', 'generateR1cs', 'R1CS Generation failed']) throw new Error(r1csErrors) } else { this.internalEvents.emit('circuit_generating_r1cs_done') @@ -235,7 +238,7 @@ export class CircomPluginClient extends PluginClient { // @ts-ignore await this.call('fileManager', 'writeFile', writePath, r1csProgram, true) - _paq.push(['trackEvent', 'circuit-compiler', 'generateR1cs', 'R1CS Generation successful']) + this._paq.push(['trackEvent', 'circuit-compiler', 'generateR1cs', 'R1CS Generation successful']) r1csApi.log().map(log => { log && this.call('terminal', 'log', { type: 'log', value: log }) }) @@ -256,7 +259,7 @@ export class CircomPluginClient extends PluginClient { const witness = this.compiler ? await this.compiler.generate_witness(dataRead, input) : await generate_witness(dataRead, input) // @ts-ignore await this.call('fileManager', 'writeFile', wasmPath.replace('.wasm', '.wtn'), witness, true) - _paq.push(['trackEvent', 'circuit-compiler', 'computeWitness', 'Witness computing successful']) + this._paq.push(['trackEvent', 'circuit-compiler', 'computeWitness', 'Witness computing successful']) this.internalEvents.emit('circuit_computing_witness_done') this.emit('statusChanged', { key: 'succeed', title: 'witness computed successfully', type: 'success' }) } From 50e860415a213853b2be5275e5f9bf2dd69c095d Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 11 Jul 2024 10:48:22 +0100 Subject: [PATCH 53/60] disable test in firefox --- .../src/tests/file_explorer_multiselect.test.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index c38a0673ed..d7c04376c7 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -8,6 +8,7 @@ module.exports = { }, 'Should select multiple items in file explorer #group1': function (browser: NightwatchBrowser) { + console.log(browser) const selectedElements = [] browser .openFile('contracts') @@ -26,11 +27,7 @@ module.exports = { }, 'Should drag and drop multiple files in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { const selectedElements = [] - if (browser.options.desiredCapabilities?.browserName === 'firefox') { - console.log('Skipping test for firefox') - browser.end() - return; - } else { + if (browser.options.desiredCapabilities?.browserName === 'chrome') { browser .click({ selector: '//*[@data-id="treeViewUltreeViewMenu"]', locateStrategy: 'xpath' }) .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) @@ -54,6 +51,8 @@ module.exports = { .perform(() => done()) }) }) + } else { + browser.end() } }, 'should drag and drop multiple files and folders in file explorer to contracts folder #group3': function (browser: NightwatchBrowser) { From fd0ffc1c796a22caa81a68a268047d9c90892b8f Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 11 Jul 2024 11:16:03 +0100 Subject: [PATCH 54/60] disable duplicate test --- .../src/tests/file_explorer_multiselect.test.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index d7c04376c7..18a52f587f 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -8,7 +8,6 @@ module.exports = { }, 'Should select multiple items in file explorer #group1': function (browser: NightwatchBrowser) { - console.log(browser) const selectedElements = [] browser .openFile('contracts') @@ -27,7 +26,11 @@ module.exports = { }, 'Should drag and drop multiple files in file explorer to tests folder #group1': function (browser: NightwatchBrowser) { const selectedElements = [] - if (browser.options.desiredCapabilities?.browserName === 'chrome') { + if (browser.options.desiredCapabilities?.browserName === 'firefox') { + console.log('Skipping test for firefox') + browser.end() + return; + } else { browser .click({ selector: '//*[@data-id="treeViewUltreeViewMenu"]', locateStrategy: 'xpath' }) .click({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]', locateStrategy: 'xpath' }) @@ -51,11 +54,9 @@ module.exports = { .perform(() => done()) }) }) - } else { - browser.end() } }, - 'should drag and drop multiple files and folders in file explorer to contracts folder #group3': function (browser: NightwatchBrowser) { + 'should drag and drop multiple files and folders in file explorer to contracts folder #group3': ''+function (browser: NightwatchBrowser) { const selectedElements = [] browser .clickLaunchIcon('filePanel') From ba251d7efc6ff338b44f72d1e568ee558ed4b07c Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 11 Jul 2024 11:25:11 +0100 Subject: [PATCH 55/60] skip firefox for test --- .../tests/file_explorer_multiselect.test.ts | 64 ++++++++++--------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts index 18a52f587f..214217af38 100644 --- a/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts +++ b/apps/remix-ide-e2e/src/tests/file_explorer_multiselect.test.ts @@ -56,35 +56,41 @@ module.exports = { }) } }, - 'should drag and drop multiple files and folders in file explorer to contracts folder #group3': ''+function (browser: NightwatchBrowser) { + 'should drag and drop multiple files and folders in file explorer to contracts folder #group3': function (browser: NightwatchBrowser) { const selectedElements = [] - browser - .clickLaunchIcon('filePanel') - .click({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }) - .findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemscripts"]', locateStrategy: 'xpath' }, (el) => { - selectedElements.push(el) - }) - browser.findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemREADME.txt"]', locateStrategy: 'xpath' }, - (el: any) => { - selectedElements.push(el) - }) - browser.selectFiles(selectedElements) - .perform((done) => { - browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts"]', locateStrategy: 'xpath' }, - (el: any) => { - const id = (el as any).value.getId() - browser - .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts"]') - .dragAndDrop('li[data-id="treeViewLitreeViewItemtests"]', id) - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/tests"]', 5000) - .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/README.txt"]', 5000) - .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/scripts"]', 5000) - .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemtests"]') - .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemREADME.txt"]') - .perform(() => done()) - }) - }) + if (browser.options.desiredCapabilities?.browserName === 'firefox') { + console.log('Skipping test for firefox') + browser.end() + return; + } else { + browser + .clickLaunchIcon('filePanel') + .click({ selector: '//*[@data-id="treeViewLitreeViewItemtests"]', locateStrategy: 'xpath' }) + .findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemscripts"]', locateStrategy: 'xpath' }, (el) => { + selectedElements.push(el) + }) + browser.findElement({ selector: '//*[@data-id="treeViewDivtreeViewItemREADME.txt"]', locateStrategy: 'xpath' }, + (el: any) => { + selectedElements.push(el) + }) + browser.selectFiles(selectedElements) + .perform((done) => { + browser.findElement({ selector: '//*[@data-id="treeViewLitreeViewItemcontracts"]', locateStrategy: 'xpath' }, + (el: any) => { + const id = (el as any).value.getId() + browser + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts"]') + .dragAndDrop('li[data-id="treeViewLitreeViewItemtests"]', id) + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/tests"]', 5000) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/README.txt"]', 5000) + .waitForElementVisible('li[data-id="treeViewLitreeViewItemcontracts/scripts"]', 5000) + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemtests"]') + .waitForElementNotPresent('li[data-id="treeViewLitreeViewItemREADME.txt"]') + .perform(() => done()) + }) + }) + } } } From 9730d2a4ac6c47a1180ca229cbd0378bb1132420 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 11 Jul 2024 12:54:57 +0200 Subject: [PATCH 56/60] fix gh actions --- .../ci/deploy_from_travis_remix-alpha.sh | 5 +++ .../ci/deploy_from_travis_remix-beta.sh | 5 +++ .../ci/deploy_from_travis_remix-live.sh | 5 +++ apps/remix-ide/ci/gh-actions-deploy.yml | 43 +++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 apps/remix-ide/ci/gh-actions-deploy.yml diff --git a/apps/remix-ide/ci/deploy_from_travis_remix-alpha.sh b/apps/remix-ide/ci/deploy_from_travis_remix-alpha.sh index c57de7fea5..964da156b1 100755 --- a/apps/remix-ide/ci/deploy_from_travis_remix-alpha.sh +++ b/apps/remix-ide/ci/deploy_from_travis_remix-alpha.sh @@ -5,6 +5,11 @@ SHA=`git rev-parse --short --verify HEAD` cd dist/apps/remix-ide +# this gh action is used to deploy the build to the gh pages +mkdir dist/apps/remix-ide/.github +mkdir dist/apps/remix-ide/.github/workflows +cp apps/remix-ide/ci/gh-actions-deploy.yml dist/apps/remix-ide/.github/workflows + git init git checkout -b gh-pages git config user.name "$COMMIT_AUTHOR" diff --git a/apps/remix-ide/ci/deploy_from_travis_remix-beta.sh b/apps/remix-ide/ci/deploy_from_travis_remix-beta.sh index 134d9c2090..98f7af21c8 100755 --- a/apps/remix-ide/ci/deploy_from_travis_remix-beta.sh +++ b/apps/remix-ide/ci/deploy_from_travis_remix-beta.sh @@ -5,6 +5,11 @@ SHA=`git rev-parse --short --verify HEAD` cd dist/apps/remix-ide +# this gh action is used to deploy the build to the gh pages +mkdir dist/apps/remix-ide/.github +mkdir dist/apps/remix-ide/.github/workflows +cp apps/remix-ide/ci/gh-actions-deploy.yml dist/apps/remix-ide/.github/workflows + git init git checkout -b gh-pages git config user.name "$COMMIT_AUTHOR" diff --git a/apps/remix-ide/ci/deploy_from_travis_remix-live.sh b/apps/remix-ide/ci/deploy_from_travis_remix-live.sh index 1376cda6f0..0aadafc75c 100755 --- a/apps/remix-ide/ci/deploy_from_travis_remix-live.sh +++ b/apps/remix-ide/ci/deploy_from_travis_remix-live.sh @@ -5,6 +5,11 @@ SHA=`git rev-parse --short --verify HEAD` cd dist/apps/remix-ide +# this gh action is used to deploy the build to the gh pages +mkdir dist/apps/remix-ide/.github +mkdir dist/apps/remix-ide/.github/workflows +cp apps/remix-ide/ci/gh-actions-deploy.yml dist/apps/remix-ide/.github/workflows/gh-actions-deploy.yml + git init git checkout -b gh-pages git config user.name "$COMMIT_AUTHOR" diff --git a/apps/remix-ide/ci/gh-actions-deploy.yml b/apps/remix-ide/ci/gh-actions-deploy.yml new file mode 100644 index 0000000000..a25c381cb9 --- /dev/null +++ b/apps/remix-ide/ci/gh-actions-deploy.yml @@ -0,0 +1,43 @@ +# Simple workflow for deploying static content to GitHub Pages +name: Deploy static content to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["gh-pages"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Single deploy job since we're just deploying + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Pages + uses: actions/configure-pages@v5 + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + # Upload entire repository + path: '.' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file From 4922f4f6e621b33d32acf8bff9fcc0d6368308a7 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Wed, 10 Jul 2024 14:49:22 +0100 Subject: [PATCH 57/60] add matomo to handlers --- libs/remix-ui/workspace/src/lib/components/file-explorer.tsx | 3 +++ 1 file changed, 3 insertions(+) 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 aa2103bbd1..46ce4351c2 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -115,6 +115,7 @@ export const FileExplorer = (props: FileExplorerProps) => { if (treeRef.current) { const deleteKeyPressHandler = async (eve: KeyboardEvent) => { if (eve.key === 'Delete' ) { + (window as any)._paq.push(['trackEvent', 'fileExplorer', 'deleteKey']) setState((prevState) => { return { ...prevState, deleteKey: true } }) @@ -123,6 +124,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } if (eve.metaKey) { if (eve.key === 'Backspace') { + (window as any)._paq.push(['trackEvent', 'fileExplorer', 'osxDeleteKey']) setState((prevState) => { return { ...prevState, deleteKey: true } }) @@ -168,6 +170,7 @@ export const FileExplorer = (props: FileExplorerProps) => { if (treeRef.current) { const F2KeyPressHandler = async (eve: KeyboardEvent) => { if (eve.key === 'F2' ) { + (window as any)._paq.push(['trackEvent', 'fileExplorer', 'f2ToRename']) await performRename() setState((prevState) => { return { ...prevState, F2Key: true } From de6b038b14b65cedcfe2ee13d5c76093987b513b Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Fri, 12 Jul 2024 16:27:33 +0100 Subject: [PATCH 58/60] updates as per @Aniket-Engg comments --- .../workspace/src/lib/components/file-explorer.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) 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 46ce4351c2..e92be4b50a 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -102,7 +102,7 @@ export const FileExplorer = (props: FileExplorerProps) => { }, [treeRef.current]) useEffect(() => { - const performDeleteion = async () => { + const performDeletion = async () => { const path: string[] = [] if (feTarget?.length > 0 && feTarget[0]?.key.length > 0) { feTarget.forEach((one) => { @@ -119,7 +119,7 @@ export const FileExplorer = (props: FileExplorerProps) => { setState((prevState) => { return { ...prevState, deleteKey: true } }) - performDeleteion() + performDeletion() return } if (eve.metaKey) { @@ -128,7 +128,7 @@ export const FileExplorer = (props: FileExplorerProps) => { setState((prevState) => { return { ...prevState, deleteKey: true } }) - performDeleteion() + performDeletion() return } } @@ -145,7 +145,7 @@ export const FileExplorer = (props: FileExplorerProps) => { setState((prevState) => { return { ...prevState, deleteKey: false } }) - performDeleteion() + performDeletion() return } } @@ -155,7 +155,7 @@ export const FileExplorer = (props: FileExplorerProps) => { treeRef.current?.addEventListener('keyup', deleteKeyPressUpHandler) return () => { treeRef.current?.removeEventListener('keydown', deleteKeyPressHandler) - treeRef.current?.addEventListener('keyup', deleteKeyPressUpHandler) + treeRef.current?.removeEventListener('keyup', deleteKeyPressUpHandler) } } }, [treeRef.current, feTarget]) @@ -191,7 +191,7 @@ export const FileExplorer = (props: FileExplorerProps) => { treeRef.current?.addEventListener('keyup', F2KeyPressUpHandler) return () => { treeRef.current?.removeEventListener('keydown', F2KeyPressHandler) - treeRef.current?.addEventListener('keyup', F2KeyPressUpHandler) + treeRef.current?.removeEventListener('keyup', F2KeyPressUpHandler) } } }, [treeRef.current, feTarget]) @@ -456,7 +456,6 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleTreeClick = (event: SyntheticEvent) => { - console.log({ props, state }) let target = event.target as HTMLElement while (target && target.getAttribute && !target.getAttribute('data-path')) { target = target.parentElement From a0397a8dc86ee110c90ab72c34a1aee99f1b55cb Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Fri, 12 Jul 2024 16:29:37 +0100 Subject: [PATCH 59/60] remove redundant performDelete call --- libs/remix-ui/workspace/src/lib/components/file-explorer.tsx | 1 - 1 file changed, 1 deletion(-) 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 e92be4b50a..b3026ef663 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -145,7 +145,6 @@ export const FileExplorer = (props: FileExplorerProps) => { setState((prevState) => { return { ...prevState, deleteKey: false } }) - performDeletion() return } } From dde5a6d370db53b6ad85bbce770b18a0e464e8cf Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 15 Jul 2024 08:02:43 +0100 Subject: [PATCH 60/60] fixed comments --- .../workspace/src/lib/components/file-explorer.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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 b3026ef663..950c2810ff 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -40,6 +40,7 @@ export const FileExplorer = (props: FileExplorerProps) => { const { plugin } = useContext(FileSystemContext) const [feTarget, setFeTarget] = useState<{ key: string, type: 'file' | 'folder' }[]>({} as { key: string, type: 'file' | 'folder' }[]) const [filesSelected, setFilesSelected] = useState([]) + const feWindow = (window as any) useEffect(() => { if (contextMenuItems) { @@ -115,7 +116,7 @@ export const FileExplorer = (props: FileExplorerProps) => { if (treeRef.current) { const deleteKeyPressHandler = async (eve: KeyboardEvent) => { if (eve.key === 'Delete' ) { - (window as any)._paq.push(['trackEvent', 'fileExplorer', 'deleteKey']) + feWindow._paq.push(['trackEvent', 'fileExplorer', 'deleteKey', 'deletePath']) setState((prevState) => { return { ...prevState, deleteKey: true } }) @@ -124,7 +125,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } if (eve.metaKey) { if (eve.key === 'Backspace') { - (window as any)._paq.push(['trackEvent', 'fileExplorer', 'osxDeleteKey']) + feWindow._paq.push(['trackEvent', 'fileExplorer', 'osxDeleteKey', 'deletePath']) setState((prevState) => { return { ...prevState, deleteKey: true } }) @@ -164,12 +165,12 @@ export const FileExplorer = (props: FileExplorerProps) => { if (feTarget?.length > 1 && feTarget[0]?.key.length > 1) { await plugin.call('notification', 'alert', { id: 'renameAlert', message: 'You cannot rename multiple files at once!' }) } - await props.editModeOn(feTarget[0].key, feTarget[0].type, false) + props.editModeOn(feTarget[0].key, feTarget[0].type, false) } if (treeRef.current) { const F2KeyPressHandler = async (eve: KeyboardEvent) => { if (eve.key === 'F2' ) { - (window as any)._paq.push(['trackEvent', 'fileExplorer', 'f2ToRename']) + feWindow._paq.push(['trackEvent', 'fileExplorer', 'f2ToRename', 'RenamePath']) await performRename() setState((prevState) => { return { ...prevState, F2Key: true }