diff --git a/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/FileUploadQuestionForm.tsx b/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/FileUploadQuestionForm.tsx index 619ccfaeff..82be6dc8d5 100644 --- a/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/FileUploadQuestionForm.tsx +++ b/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/FileUploadQuestionForm.tsx @@ -115,6 +115,12 @@ export const FileUploadQuestionForm = ({ return 10; }, [billingInfo, billingInfoError, billingInfoLoading]); + const handleMaxSizeInMBToggle = (checked: boolean) => { + const defaultMaxSizeInMB = isFormbricksCloud ? maxSizeInMBLimit : 1024; + + updateQuestion(questionIdx, { maxSizeInMB: checked ? defaultMaxSizeInMB : undefined }); + }; + return (
updateQuestion(questionIdx, { maxSizeInMB: checked ? 10 : undefined })} + onToggle={handleMaxSizeInMBToggle} htmlId="maxFileSize" title="Max file size" description="Limit the maximum file size." @@ -193,11 +199,9 @@ export const FileUploadQuestionForm = ({ onChange={(e) => { const parsedValue = parseInt(e.target.value, 10); - if (parsedValue > maxSizeInMBLimit) { + if (isFormbricksCloud && parsedValue > maxSizeInMBLimit) { toast.error(`Max file size limit is ${maxSizeInMBLimit} MB`); - if (isFormbricksCloud) { - setMaxSizeError(true); - } + setMaxSizeError(true); updateQuestion(questionIdx, { maxSizeInMB: maxSizeInMBLimit }); return; } diff --git a/packages/lib/storage/service.ts b/packages/lib/storage/service.ts index 244a7a0b1f..6ad5bb6c15 100644 --- a/packages/lib/storage/service.ts +++ b/packages/lib/storage/service.ts @@ -15,6 +15,7 @@ import { lookup } from "mime-types"; import path, { join } from "path"; import { TAccessType } from "@formbricks/types/storage"; import { + IS_FORMBRICKS_CLOUD, MAX_SIZES, S3_ACCESS_KEY, S3_BUCKET_NAME, @@ -211,8 +212,15 @@ export const getS3UploadSignedUrl = async ( environmentId: string, isBiggerFileUploadAllowed: boolean = false ) => { - const maxSize = isBiggerFileUploadAllowed ? MAX_SIZES.big : MAX_SIZES.standard; - const postConditions: PresignedPostOptions["Conditions"] = [["content-length-range", 0, maxSize]]; + const maxSize = IS_FORMBRICKS_CLOUD + ? isBiggerFileUploadAllowed + ? MAX_SIZES.big + : MAX_SIZES.standard + : Infinity; + + const postConditions: PresignedPostOptions["Conditions"] = IS_FORMBRICKS_CLOUD + ? [["content-length-range", 0, maxSize]] + : undefined; try { const s3Client = getS3Client(); @@ -251,7 +259,11 @@ export const putFileToLocalStorage = async ( const buffer = Buffer.from(fileBuffer); const bufferBytes = buffer.byteLength; - const maxSize = isBiggerFileUploadAllowed ? MAX_SIZES.big : MAX_SIZES.standard; + const maxSize = IS_FORMBRICKS_CLOUD + ? isBiggerFileUploadAllowed + ? MAX_SIZES.big + : MAX_SIZES.standard + : Infinity; if (bufferBytes > maxSize) { const err = new Error(`File size exceeds the ${maxSize / (1024 * 1024)} MB limit`); diff --git a/packages/lib/utils/promises.ts b/packages/lib/utils/promises.ts index f9070711bb..9b5e7dbdba 100644 --- a/packages/lib/utils/promises.ts +++ b/packages/lib/utils/promises.ts @@ -1,3 +1,11 @@ export const delay = (ms: number) => { return new Promise((resolve) => setTimeout(resolve, ms)); }; + +export const isFulfilled = (val: PromiseSettledResult): val is PromiseFulfilledResult => { + return val.status === "fulfilled"; +}; + +export const isRejected = (val: PromiseSettledResult): val is PromiseRejectedResult => { + return val.status === "rejected"; +}; diff --git a/packages/surveys/src/components/general/FileInput.tsx b/packages/surveys/src/components/general/FileInput.tsx index 468751ccd8..8e98dfe8e9 100644 --- a/packages/surveys/src/components/general/FileInput.tsx +++ b/packages/surveys/src/components/general/FileInput.tsx @@ -1,6 +1,7 @@ import { useMemo, useState } from "preact/hooks"; import { JSXInternal } from "preact/src/jsx"; import { getOriginalFileNameFromUrl } from "@formbricks/lib/storage/utils"; +import { isFulfilled, isRejected } from "@formbricks/lib/utils/promises"; import { TAllowedFileExtension } from "@formbricks/types/common"; import { TUploadFileConfig } from "@formbricks/types/storage"; @@ -58,11 +59,22 @@ export const FileInput = ({ const uploadPromises = filteredFiles.map((file) => onFileUpload(file, { allowedFileExtensions, surveyId }) ); - const uploadedUrls = await Promise.all(uploadPromises); + + const uploadedFiles = await Promise.allSettled(uploadPromises); + + const rejectedFiles = uploadedFiles.filter(isRejected); + const uploadedFilesUrl = uploadedFiles.filter(isFulfilled).map((url) => url.value); + setSelectedFiles((prevFiles) => [...prevFiles, ...filteredFiles]); - onUploadCallback(fileUrls ? [...fileUrls, ...uploadedUrls] : uploadedUrls); + onUploadCallback(fileUrls ? [...fileUrls, ...uploadedFilesUrl] : uploadedFilesUrl); + + if (rejectedFiles.length > 0) { + if (rejectedFiles[0].reason?.name === "FileTooLargeError") { + alert(rejectedFiles[0].reason.message); + } + } } catch (err: any) { - alert(err.name === "FileTooLargeError" ? err.message : "Upload failed! Please try again."); + alert("Upload failed! Please try again."); } finally { setIsUploading(false); }