mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
fix: mark failed uploads in store, surface errors, validate extensions on drop
- uploadFile now catches errors and sets status to 'failed' with error message - Both create page and drag-drop check uploadFiles results for failures and show error notifications - Drag-drop validates file extensions against bucket allowedFileExtensions before uploading, rejecting disallowed files with a notification
This commit is contained in:
+23
-16
@@ -82,22 +82,29 @@ const createUploader = () => {
|
||||
n.files.unshift(newFile);
|
||||
return n;
|
||||
});
|
||||
const uploadedFile = await temporaryStorage(region, projectId).createFile({
|
||||
bucketId,
|
||||
fileId: id ?? ID.unique(),
|
||||
file,
|
||||
permissions,
|
||||
onProgress: (progress) => {
|
||||
newFile.$id = progress.$id;
|
||||
newFile.progress = progress.progress;
|
||||
newFile.status = progress.progress === 100 ? 'success' : 'pending';
|
||||
updateFile(progress.$id, newFile);
|
||||
}
|
||||
});
|
||||
newFile.$id = uploadedFile.$id;
|
||||
newFile.progress = 100;
|
||||
newFile.status = 'success';
|
||||
updateFile(newFile.$id, newFile);
|
||||
try {
|
||||
const uploadedFile = await temporaryStorage(region, projectId).createFile({
|
||||
bucketId,
|
||||
fileId: id ?? ID.unique(),
|
||||
file,
|
||||
permissions,
|
||||
onProgress: (progress) => {
|
||||
newFile.$id = progress.$id;
|
||||
newFile.progress = progress.progress;
|
||||
newFile.status = progress.progress === 100 ? 'success' : 'pending';
|
||||
updateFile(progress.$id, newFile);
|
||||
}
|
||||
});
|
||||
newFile.$id = uploadedFile.$id;
|
||||
newFile.progress = 100;
|
||||
newFile.status = 'success';
|
||||
updateFile(newFile.$id, newFile);
|
||||
} catch (e) {
|
||||
newFile.status = 'failed';
|
||||
newFile.error = e?.message ?? 'Upload failed';
|
||||
updateFile(newFile.$id, newFile);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
const uploadFiles = async (
|
||||
|
||||
+31
-3
@@ -105,9 +105,30 @@
|
||||
isDragging = false;
|
||||
if (!event.dataTransfer?.files?.length) return;
|
||||
|
||||
const allowedExtensions: string[] = data.bucket.allowedFileExtensions ?? [];
|
||||
const droppedFiles = Array.from(event.dataTransfer.files);
|
||||
const count = droppedFiles.length;
|
||||
|
||||
const validFiles: File[] = [];
|
||||
const rejectedFiles: File[] = [];
|
||||
for (const file of droppedFiles) {
|
||||
const ext = file.name.split('.').pop()?.toLowerCase();
|
||||
if (allowedExtensions.length && (!ext || !allowedExtensions.includes(ext))) {
|
||||
rejectedFiles.push(file);
|
||||
} else {
|
||||
validFiles.push(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (rejectedFiles.length) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: `${rejectedFiles.length} file(s) rejected — only ${allowedExtensions.join(', ')} allowed`
|
||||
});
|
||||
}
|
||||
|
||||
if (!validFiles.length) return;
|
||||
|
||||
const count = validFiles.length;
|
||||
addNotification({
|
||||
type: 'success',
|
||||
message: count === 1 ? 'File upload in progress' : `${count} file uploads in progress`
|
||||
@@ -115,18 +136,25 @@
|
||||
|
||||
trackEvent(Submit.FileCreate, { customId: false });
|
||||
|
||||
const filesToUpload = droppedFiles.map((file) => ({
|
||||
const filesToUpload = validFiles.map((file) => ({
|
||||
id: ID.unique(),
|
||||
file
|
||||
}));
|
||||
|
||||
await uploader.uploadFiles(
|
||||
const results = await uploader.uploadFiles(
|
||||
page.params.region,
|
||||
page.params.project,
|
||||
page.params.bucket,
|
||||
filesToUpload,
|
||||
[]
|
||||
);
|
||||
const failures = results.filter((r) => r.status === 'rejected');
|
||||
if (failures.length) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: `${failures.length} file(s) failed to upload`
|
||||
});
|
||||
}
|
||||
invalidate(Dependencies.FILES);
|
||||
}
|
||||
|
||||
|
||||
+8
-1
@@ -69,7 +69,14 @@
|
||||
trackEvent(Submit.FileCreate, {
|
||||
customId: !!id
|
||||
});
|
||||
await promise;
|
||||
const results = await promise;
|
||||
const failures = results.filter((r) => r.status === 'rejected');
|
||||
if (failures.length) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: `${failures.length} file(s) failed to upload`
|
||||
});
|
||||
}
|
||||
invalidate(Dependencies.FILES);
|
||||
} catch (e) {
|
||||
addNotification({
|
||||
|
||||
Reference in New Issue
Block a user