diff --git a/app/components/workbench/FileTree.tsx b/app/components/workbench/FileTree.tsx index 5b6e7a9..eb185cb 100644 --- a/app/components/workbench/FileTree.tsx +++ b/app/components/workbench/FileTree.tsx @@ -111,6 +111,22 @@ export const FileTree = memo( }); }; + const onCopyPath = (fileOrFolder: FileNode | FolderNode) => { + try { + navigator.clipboard.writeText(fileOrFolder.fullPath); + } catch (error) { + logger.error(error); + } + }; + + const onCopyRelativePath = (fileOrFolder: FileNode | FolderNode) => { + try { + navigator.clipboard.writeText(fileOrFolder.fullPath.substring((rootFolder || '').length)); + } catch (error) { + logger.error(error); + } + }; + return (
{filteredFileList.map((fileOrFolder) => { @@ -122,6 +138,12 @@ export const FileTree = memo( selected={selectedFile === fileOrFolder.fullPath} file={fileOrFolder} unsavedChanges={unsavedFiles?.has(fileOrFolder.fullPath)} + onCopyPath={() => { + onCopyPath(fileOrFolder); + }} + onCopyRelativePath={() => { + onCopyRelativePath(fileOrFolder); + }} onClick={() => { onFileSelect?.(fileOrFolder.fullPath); }} @@ -135,6 +157,12 @@ export const FileTree = memo( folder={fileOrFolder} selected={allowFolderSelection && selectedFile === fileOrFolder.fullPath} collapsed={collapsedFolders.has(fileOrFolder.fullPath)} + onCopyPath={() => { + onCopyPath(fileOrFolder); + }} + onCopyRelativePath={() => { + onCopyRelativePath(fileOrFolder); + }} onClick={() => { toggleCollapseState(fileOrFolder.fullPath); }} @@ -157,23 +185,30 @@ interface FolderProps { folder: FolderNode; collapsed: boolean; selected?: boolean; + onCopyPath: () => void; + onCopyRelativePath: () => void; onClick: () => void; } interface FolderContextMenuProps { + onCopyPath?: () => void; + onCopyRelativePath?: () => void; children: ReactNode; } -function ContextMenuItem({ children }: { children: ReactNode }) { +function ContextMenuItem({ onSelect, children }: { onSelect?: () => void; children: ReactNode }) { return ( - + {children} ); } -function FolderContextMenu({ children }: FolderContextMenuProps) { +function FileContextMenu({ onCopyPath, onCopyRelativePath, children }: FolderContextMenuProps) { return ( {children} @@ -183,16 +218,8 @@ function FolderContextMenu({ children }: FolderContextMenuProps) { className="border border-bolt-elements-borderColor rounded-md z-context-menu bg-bolt-elements-background-depth-1 dark:bg-bolt-elements-background-depth-2 data-[state=open]:animate-in animate-duration-100 data-[state=open]:fade-in-0 data-[state=open]:zoom-in-98 w-56" > - New file... - New folder... - - - Copy path - Copy relative path - - - Rename... - Delete + Copy path + Copy relative path @@ -200,9 +227,9 @@ function FolderContextMenu({ children }: FolderContextMenuProps) { ); } -function Folder({ folder, collapsed, selected = false, onClick }: FolderProps) { +function Folder({ folder, collapsed, selected = false, onCopyPath, onCopyRelativePath, onClick }: FolderProps) { return ( - + {folder.name} - + ); } @@ -226,31 +253,43 @@ interface FileProps { file: FileNode; selected: boolean; unsavedChanges?: boolean; + onCopyPath: () => void; + onCopyRelativePath: () => void; onClick: () => void; } -function File({ file: { depth, name }, onClick, selected, unsavedChanges = false }: FileProps) { +function File({ + file: { depth, name }, + onClick, + onCopyPath, + onCopyRelativePath, + selected, + unsavedChanges = false, +}: FileProps) { return ( - -
+ -
{name}
- {unsavedChanges && } -
-
+
+
{name}
+ {unsavedChanges && } +
+ + ); }