Cap folder traversal at remainingDocuments to prevent unnecessary backend folder creation
getFilesFromEvent now tracks a collectedFileCount counter and a fileLimit derived from remainingDocuments. traverseFolder checks the counter before entering directories (skipping folder creation) and before resolving files. Once the budget is exhausted the traversal short-circuits, so no extra API calls are made for folders that would never receive uploads. A fileLimitTruncatedRef signals to onDrop that files were capped during traversal so the warning toast fires even though acceptedFiles.length is already <= remainingDocuments. The else-if branch in onDrop still handles the file-picker path (no traversal) as a safety net. Co-authored-by: Marc Seitz <mfts@users.noreply.github.com>
This commit is contained in:
co-authored by
Marc Seitz
parent
0dd914a87d
commit
0b1acdf136
@@ -114,6 +114,7 @@ export default function UploadZone({
|
||||
// Using promise-lock pattern to prevent race conditions during concurrent folder creation
|
||||
const dataroomFolderPathRef = useRef<string | null>(null);
|
||||
const dataroomFolderCreationPromiseRef = useRef<Promise<string> | null>(null);
|
||||
const fileLimitTruncatedRef = useRef(false);
|
||||
|
||||
// Reset the cached dataroom folder path when the replication setting changes
|
||||
// This ensures we don't use stale cached paths if the setting is toggled
|
||||
@@ -292,7 +293,23 @@ export default function UploadZone({
|
||||
|
||||
let filesToUpload = acceptedFiles;
|
||||
|
||||
if (hasDocumentLimit && acceptedFiles.length > remainingDocuments) {
|
||||
if (fileLimitTruncatedRef.current) {
|
||||
// Folder traversal was already capped at remainingDocuments –
|
||||
// no extra folders were created, just show the warning.
|
||||
fileLimitTruncatedRef.current = false;
|
||||
toast.warning(
|
||||
`Your upload was limited to ${acceptedFiles.length} file${acceptedFiles.length === 1 ? "" : "s"} because your plan only allows ${remainingDocuments} more document${remainingDocuments === 1 ? "" : "s"} (${limits?.usage?.documents}/${limits?.documents} used).`,
|
||||
{
|
||||
action: {
|
||||
label: "Upgrade",
|
||||
onClick: () => router.push("/settings/billing"),
|
||||
},
|
||||
duration: 10000,
|
||||
},
|
||||
);
|
||||
} else if (hasDocumentLimit && acceptedFiles.length > remainingDocuments) {
|
||||
// Safety net for the file-picker path (no folder traversal) or
|
||||
// race conditions where the cap was slightly exceeded.
|
||||
const skippedCount = acceptedFiles.length - remainingDocuments;
|
||||
toast.warning(
|
||||
`You're trying to upload ${acceptedFiles.length} files, but your plan only allows ${remainingDocuments} more document${remainingDocuments === 1 ? "" : "s"} (${limits?.usage?.documents}/${limits?.documents} used). ${skippedCount} file${skippedCount === 1 ? "" : "s"} will be skipped.`,
|
||||
@@ -588,8 +605,15 @@ export default function UploadZone({
|
||||
return [];
|
||||
}
|
||||
|
||||
fileLimitTruncatedRef.current = false;
|
||||
const fileLimit =
|
||||
hasDocumentLimit && isFinite(remainingDocuments)
|
||||
? Math.max(0, remainingDocuments)
|
||||
: Infinity;
|
||||
let collectedFileCount = 0;
|
||||
|
||||
// Early check: skip folder traversal (and folder creation) if document limit is already reached
|
||||
if (hasDocumentLimit && remainingDocuments <= 0) {
|
||||
if (fileLimit <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -614,6 +638,10 @@ export default function UploadZone({
|
||||
return files;
|
||||
}
|
||||
|
||||
if (collectedFileCount >= fileLimit) {
|
||||
return files;
|
||||
}
|
||||
|
||||
if (entry.isDirectory) {
|
||||
/**
|
||||
* Let's create the folder.
|
||||
@@ -759,6 +787,10 @@ export default function UploadZone({
|
||||
return files;
|
||||
}
|
||||
|
||||
if (collectedFileCount >= fileLimit) {
|
||||
return files;
|
||||
}
|
||||
|
||||
let file = await new Promise<FileWithPaths>((resolve) =>
|
||||
(entry as FileSystemFileEntry).file(resolve),
|
||||
);
|
||||
@@ -813,6 +845,7 @@ export default function UploadZone({
|
||||
file.dataroomUploadPath = dataroomParentPath;
|
||||
|
||||
files.push(file);
|
||||
collectedFileCount++;
|
||||
}
|
||||
|
||||
return files;
|
||||
@@ -858,6 +891,10 @@ export default function UploadZone({
|
||||
}
|
||||
}
|
||||
|
||||
if (isFinite(fileLimit) && collectedFileCount >= fileLimit) {
|
||||
fileLimitTruncatedRef.current = true;
|
||||
}
|
||||
|
||||
return filesToBePassedToOnDrop;
|
||||
},
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user