upload button

This commit is contained in:
2025-11-10 00:32:41 +01:00
parent 20cf597c5c
commit ac24297a7b
5 changed files with 153 additions and 51 deletions
@@ -2,6 +2,26 @@ import { useCallback, useRef, useState } from 'react';
import useFileDrop from './useFileDrop';
import { DEFAULT_FOLDER_NAME, hasFiles } from '../../app/appLayoutUtils';
const mapFilesToEntries = (filesInput) => {
if (!filesInput) {
return [];
}
const files = Array.isArray(filesInput) ? filesInput : Array.from(filesInput);
return files
.filter(Boolean)
.map((file) => {
const relativePath =
typeof file.webkitRelativePath === 'string' ? file.webkitRelativePath : '';
const segments = relativePath
? relativePath
.split('/')
.slice(0, -1)
.filter(Boolean)
: [];
return { file, segments };
});
};
const useDocumentUploads = ({
apiClient,
token,
@@ -34,23 +54,27 @@ const useDocumentUploads = ({
formData.append('folder_id', targetFolderId);
}
try {
const { data, status } = await apiClient.post('/documents', formData);
const duplicate = data?.reused || status === 200;
setStatusMessage(
duplicate
? `${file.name} already exists; reused existing document.`
: `Uploaded ${file.name}`,
duplicate ? 'info' : 'success',
);
return data;
} catch (error) {
const message = error.response?.data?.error || `Failed to upload ${file.name}.`;
notifyApiError(error, message);
throw error;
try {
const { data, status } = await apiClient.post('/documents', formData);
const duplicate = data?.reused || status === 200;
setStatusMessage(
duplicate
? `${file.name} already exists; reused existing document.`
: `Uploaded ${file.name}`,
duplicate ? 'info' : 'success',
);
return data;
} catch (error) {
if (error.response?.status === 409) {
setStatusMessage(`${file.name} already exists on the server.`, 'info');
return null;
}
},
[apiClient, notifyApiError, setStatusMessage],
const message = error.response?.data?.error || `Failed to upload ${file.name}.`;
notifyApiError(error, message);
throw error;
}
},
[apiClient, notifyApiError, setStatusMessage],
);
const ensureFolderPathOnServer = useCallback(
@@ -200,35 +224,27 @@ const useDocumentUploads = ({
return results;
}, []);
const handleFileDrop = useCallback(
async (dataTransfer, targetFolderId) => {
const uploadFileEntries = useCallback(
async (entries, targetFolderId) => {
if (!token) {
setStatusMessage('Please log in before uploading.', 'error');
return;
}
if (!entries || !entries.length) {
setStatusMessage('No files to upload.', 'info');
return;
}
setLoading(true);
try {
folderPathCacheRef.current.clear();
let extracted;
try {
extracted = await extractFilesFromDataTransfer(dataTransfer);
} catch (error) {
const message = error.message || 'Failed to process dropped files.';
notifyApiError(error, message);
return;
}
if (!extracted.length) {
setStatusMessage('No files to upload.', 'info');
return;
}
const baseFolderId =
targetFolderId && targetFolderId !== 'root' ? targetFolderId : null;
for (const { file, segments } of extracted) {
for (const { file, segments } of entries) {
// eslint-disable-next-line no-await-in-loop
const destinationId = segments.length
? await ensureFolderPathOnServer(baseFolderId, segments)
@@ -259,7 +275,6 @@ const useDocumentUploads = ({
},
[
token,
extractFilesFromDataTransfer,
ensureFolderPathOnServer,
uploadFile,
refreshCurrentFolder,
@@ -271,6 +286,30 @@ const useDocumentUploads = ({
],
);
const handleFileDrop = useCallback(
async (dataTransfer, targetFolderId) => {
let extracted;
try {
extracted = await extractFilesFromDataTransfer(dataTransfer);
} catch (error) {
const message = error.message || 'Failed to process dropped files.';
notifyApiError(error, message);
return;
}
await uploadFileEntries(extracted, targetFolderId);
},
[extractFilesFromDataTransfer, uploadFileEntries, notifyApiError],
);
const handleFileSelection = useCallback(
async (files, targetFolderId) => {
const entries = mapFilesToEntries(files);
await uploadFileEntries(entries, targetFolderId);
},
[uploadFileEntries],
);
useFileDrop({
shellRef,
token,
@@ -294,6 +333,7 @@ const useDocumentUploads = ({
setDropOverlayState,
dragCounterRef,
handleFileDrop,
handleFileSelection,
uploadFile,
extractFilesFromDataTransfer,
resetUploadsState,
@@ -533,6 +533,7 @@ const useDocumentsWorkspace = ({
const {
dropOverlayState,
handleFileDrop,
handleFileSelection,
resetUploadsState,
} = useDocumentUploads({
apiClient: api,
@@ -1371,6 +1372,7 @@ const useDocumentsWorkspace = ({
currentTenantId,
handleTenantSelect,
openSettings,
handleFileSelection,
});