mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-05 23:44:22 +00:00
Enhance uploadFile to support multiple files and update handleMove to process file paths for moving files
This commit is contained in:
@@ -199,20 +199,24 @@ export const moveFile = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* uploadFile uploads a file to a workspace
|
* uploadFile uploads multiple files to a workspace
|
||||||
* @param workspaceName - The name of the workspace
|
* @param workspaceName - The name of the workspace
|
||||||
* @param directoryPath - The directory path where the file should be uploaded
|
* @param directoryPath - The directory path where files should be uploaded
|
||||||
* @param file - The file to upload
|
* @param files - Multiple files to upload
|
||||||
* @returns {Promise<SaveFileResponse>} A promise that resolves to the upload file response
|
* @returns {Promise<SaveFileResponse>} A promise that resolves to the upload file response
|
||||||
* @throws {Error} If the API call fails or returns an invalid response
|
* @throws {Error} If the API call fails or returns an invalid response
|
||||||
*/
|
*/
|
||||||
export const uploadFile = async (
|
export const uploadFile = async (
|
||||||
workspaceName: string,
|
workspaceName: string,
|
||||||
directoryPath: string,
|
directoryPath: string,
|
||||||
file: File
|
files: FileList
|
||||||
): Promise<SaveFileResponse> => {
|
): Promise<SaveFileResponse> => {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file);
|
|
||||||
|
// Add all files to the form data
|
||||||
|
Array.from(files).forEach((file) => {
|
||||||
|
formData.append('file', file);
|
||||||
|
});
|
||||||
|
|
||||||
const response = await apiCall(
|
const response = await apiCall(
|
||||||
`${API_BASE_URL}/workspaces/${encodeURIComponent(
|
`${API_BASE_URL}/workspaces/${encodeURIComponent(
|
||||||
|
|||||||
@@ -103,7 +103,49 @@ function Node({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FileTree: React.FC<FileTreeProps> = ({
|
// Utility function to recursively find file paths by IDs
|
||||||
|
const findFilePathsById = (files: FileNode[], ids: string[]): string[] => {
|
||||||
|
const paths: string[] = [];
|
||||||
|
|
||||||
|
const searchFiles = (nodes: FileNode[]) => {
|
||||||
|
for (const node of nodes) {
|
||||||
|
if (ids.includes(node.id)) {
|
||||||
|
paths.push(node.path);
|
||||||
|
}
|
||||||
|
if (node.children) {
|
||||||
|
searchFiles(node.children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
searchFiles(files);
|
||||||
|
return paths;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Utility function to find parent path by ID
|
||||||
|
const findParentPathById = (
|
||||||
|
files: FileNode[],
|
||||||
|
parentId: string | null
|
||||||
|
): string => {
|
||||||
|
if (!parentId) return '';
|
||||||
|
|
||||||
|
const searchFiles = (nodes: FileNode[]): string | null => {
|
||||||
|
for (const node of nodes) {
|
||||||
|
if (node.id === parentId) {
|
||||||
|
return node.path;
|
||||||
|
}
|
||||||
|
if (node.children) {
|
||||||
|
const result = searchFiles(node.children);
|
||||||
|
if (result) return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
return searchFiles(files) || '';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FileTree: React.FC<FileTreeProps> = ({
|
||||||
files,
|
files,
|
||||||
handleFileSelect,
|
handleFileSelect,
|
||||||
showHiddenFiles,
|
showHiddenFiles,
|
||||||
@@ -143,7 +185,14 @@ const FileTree: React.FC<FileTreeProps> = ({
|
|||||||
index: number;
|
index: number;
|
||||||
}) => {
|
}) => {
|
||||||
try {
|
try {
|
||||||
const success = await handleMove(dragIds, parentId, index);
|
// Map dragged file IDs to their corresponding paths
|
||||||
|
const dragPaths = findFilePathsById(filteredFiles, dragIds);
|
||||||
|
|
||||||
|
// Find the parent path where files will be moved
|
||||||
|
const targetParentPath = findParentPathById(filteredFiles, parentId);
|
||||||
|
|
||||||
|
// Move files to the new location
|
||||||
|
const success = await handleMove(dragPaths, targetParentPath, index);
|
||||||
if (success) {
|
if (success) {
|
||||||
await loadFileList();
|
await loadFileList();
|
||||||
}
|
}
|
||||||
@@ -151,7 +200,7 @@ const FileTree: React.FC<FileTreeProps> = ({
|
|||||||
console.error('Error moving files:', error);
|
console.error('Error moving files:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[handleMove, loadFileList]
|
[handleMove, loadFileList, filteredFiles]
|
||||||
);
|
);
|
||||||
|
|
||||||
// External file drag and drop handlers
|
// External file drag and drop handlers
|
||||||
@@ -256,7 +305,6 @@ const FileTree: React.FC<FileTreeProps> = ({
|
|||||||
height={size.height}
|
height={size.height}
|
||||||
indent={24}
|
indent={24}
|
||||||
rowHeight={28}
|
rowHeight={28}
|
||||||
// Enable drag and drop for moving files
|
|
||||||
onMove={handleTreeMove}
|
onMove={handleTreeMove}
|
||||||
onActivate={(node) => {
|
onActivate={(node) => {
|
||||||
const fileNode = node.data;
|
const fileNode = node.data;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { notifications } from '@mantine/notifications';
|
import { notifications } from '@mantine/notifications';
|
||||||
import { saveFile, deleteFile } from '../api/file';
|
import { saveFile, deleteFile, uploadFile, moveFile } from '../api/file';
|
||||||
import { useWorkspaceData } from '../contexts/WorkspaceDataContext';
|
import { useWorkspaceData } from '../contexts/WorkspaceDataContext';
|
||||||
import { useGitOperations } from './useGitOperations';
|
import { useGitOperations } from './useGitOperations';
|
||||||
import { FileAction } from '@/types/models';
|
import { FileAction } from '@/types/models';
|
||||||
@@ -11,9 +11,9 @@ interface UseFileOperationsResult {
|
|||||||
handleCreate: (fileName: string, initialContent?: string) => Promise<boolean>;
|
handleCreate: (fileName: string, initialContent?: string) => Promise<boolean>;
|
||||||
handleUpload: (files: FileList, targetPath?: string) => Promise<boolean>;
|
handleUpload: (files: FileList, targetPath?: string) => Promise<boolean>;
|
||||||
handleMove: (
|
handleMove: (
|
||||||
dragIds: string[],
|
filePaths: string[],
|
||||||
parentId: string | null,
|
destinationParentPath: string,
|
||||||
index: number
|
index?: number
|
||||||
) => Promise<boolean>;
|
) => Promise<boolean>;
|
||||||
handleRename: (oldPath: string, newPath: string) => Promise<boolean>;
|
handleRename: (oldPath: string, newPath: string) => Promise<boolean>;
|
||||||
}
|
}
|
||||||
@@ -117,13 +117,13 @@ export const useFileOperations = (): UseFileOperationsResult => {
|
|||||||
[currentWorkspace, autoCommit]
|
[currentWorkspace, autoCommit]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add these to your hook implementation:
|
|
||||||
const handleUpload = useCallback(
|
const handleUpload = useCallback(
|
||||||
async (files: FileList, targetPath?: string): Promise<boolean> => {
|
async (files: FileList, targetPath?: string): Promise<boolean> => {
|
||||||
if (!currentWorkspace) return false;
|
if (!currentWorkspace) return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO: Implement your file upload API call
|
// Use unified upload API that handles both single and multiple files
|
||||||
|
await uploadFile(currentWorkspace.name, targetPath || '', files);
|
||||||
|
|
||||||
notifications.show({
|
notifications.show({
|
||||||
title: 'Success',
|
title: 'Success',
|
||||||
@@ -149,18 +149,32 @@ export const useFileOperations = (): UseFileOperationsResult => {
|
|||||||
|
|
||||||
const handleMove = useCallback(
|
const handleMove = useCallback(
|
||||||
async (
|
async (
|
||||||
dragIds: string[],
|
filePaths: string[],
|
||||||
parentId: string | null,
|
destinationParentPath: string,
|
||||||
index: number
|
_index?: number
|
||||||
): Promise<boolean> => {
|
): Promise<boolean> => {
|
||||||
if (!currentWorkspace) return false;
|
if (!currentWorkspace) return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO: Implement your file move API call
|
// Move each file to the destination directory
|
||||||
|
const movePromises = filePaths.map(async (filePath) => {
|
||||||
|
// Extract the filename from the path
|
||||||
|
const fileName = filePath.split('/').pop() || '';
|
||||||
|
|
||||||
|
// Construct the destination path
|
||||||
|
const destinationPath = destinationParentPath
|
||||||
|
? `${destinationParentPath}/${fileName}`
|
||||||
|
: fileName;
|
||||||
|
|
||||||
|
// Call the API to move the file
|
||||||
|
await moveFile(currentWorkspace.name, filePath, destinationPath);
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all(movePromises);
|
||||||
|
|
||||||
notifications.show({
|
notifications.show({
|
||||||
title: 'Success',
|
title: 'Success',
|
||||||
message: `Successfully moved ${dragIds.length} file(s)`,
|
message: `Successfully moved ${filePaths.length} file(s)`,
|
||||||
color: 'green',
|
color: 'green',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -185,8 +199,8 @@ export const useFileOperations = (): UseFileOperationsResult => {
|
|||||||
if (!currentWorkspace) return false;
|
if (!currentWorkspace) return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO: Replace with your actual rename API call
|
// Use moveFile API for renaming (rename is essentially a move operation)
|
||||||
// await renameFile(currentWorkspace.name, oldPath, newPath);
|
await moveFile(currentWorkspace.name, oldPath, newPath);
|
||||||
|
|
||||||
notifications.show({
|
notifications.show({
|
||||||
title: 'Success',
|
title: 'Success',
|
||||||
|
|||||||
Reference in New Issue
Block a user