From 0ff7bb56ec3842aa37d04219eec7914f4980ff60 Mon Sep 17 00:00:00 2001 From: Dhruwang Jariwala <67850763+Dhruwang@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:11:22 +0530 Subject: [PATCH] fix: download response (#1890) --- .../surveys/[surveyId]/(analysis)/actions.ts | 10 ++++++++-- .../[surveyId]/components/CustomFilter.tsx | 19 +++++++++++++++++-- packages/lib/response/service.ts | 14 +++++++++----- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions.ts b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions.ts index af49156dc0..46baf95737 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions.ts +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions.ts @@ -13,12 +13,18 @@ export default async function revalidateSurveyIdPath(environmentId: string, surv revalidatePath(`/environments/${environmentId}/surveys/${surveyId}`); } -export async function getMoreResponses(surveyId: string, page: number): Promise { +export async function getMoreResponses( + surveyId: string, + page: number, + batchSize?: number +): Promise { const session = await getServerSession(authOptions); if (!session) throw new AuthorizationError("Not authorized"); const isAuthorized = await canUserAccessSurvey(session.user.id, surveyId); if (!isAuthorized) throw new AuthorizationError("Not authorized"); - const responses = await getResponses(surveyId, page); + + batchSize = batchSize ?? 10; + const responses = await getResponses(surveyId, page, batchSize); return responses; } diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/CustomFilter.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/CustomFilter.tsx index 4152c4a959..30a690642a 100755 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/CustomFilter.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/CustomFilter.tsx @@ -4,6 +4,7 @@ import { DateRange, useResponseFilter, } from "@/app/(app)/environments/[environmentId]/components/ResponseFilterContext"; +import { getMoreResponses } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions"; import { fetchFile } from "@/app/lib/fetchFile"; import { generateQuestionAndFilterOptions, getTodayDate } from "@/app/lib/surveys/surveys"; import { createId } from "@paralleldrive/cuid2"; @@ -155,9 +156,23 @@ const CustomFilter = ({ environmentTags, responses, survey, totalResponses }: Cu return keys; }, []); + const getAllResponsesInBatches = useCallback(async () => { + const BATCH_SIZE = 3000; + const responses: TResponse[] = []; + for (let page = 1; ; page++) { + const batchResponses = await getMoreResponses(survey.id, page, BATCH_SIZE); + responses.push(...batchResponses); + if (batchResponses.length < BATCH_SIZE) { + break; + } + } + return responses; + }, [survey.id]); + const downloadResponses = useCallback( async (filter: FilterDownload, filetype: "csv" | "xlsx") => { - const downloadResponse = filter === FilterDownload.ALL ? totalResponses : responses; + const downloadResponse = filter === FilterDownload.ALL ? await getAllResponsesInBatches() : responses; + const questionNames = survey.questions?.map((question) => question.headline); const hiddenFieldIds = survey.hiddenFields.fieldIds; const hiddenFieldResponse = {}; @@ -269,7 +284,7 @@ const CustomFilter = ({ environmentTags, responses, survey, totalResponses }: Cu URL.revokeObjectURL(downloadUrl); }, - [downloadFileName, responses, totalResponses, survey, extracMetadataKeys] + [downloadFileName, responses, survey, extracMetadataKeys, getAllResponsesInBatches] ); const handleDateHoveredChange = (date: Date) => { diff --git a/packages/lib/response/service.ts b/packages/lib/response/service.ts index d0dcb842de..596260ab43 100644 --- a/packages/lib/response/service.ts +++ b/packages/lib/response/service.ts @@ -384,11 +384,15 @@ export const getResponse = async (responseId: string): Promise } as TResponse; }; -export const getResponses = async (surveyId: string, page?: number): Promise => { +export const getResponses = async ( + surveyId: string, + page?: number, + batchSize?: number +): Promise => { const responses = await unstable_cache( async () => { validateInputs([surveyId, ZId], [page, ZOptionalNumber]); - + batchSize = batchSize ?? RESPONSES_PER_PAGE; try { const responses = await prisma.response.findMany({ where: { @@ -400,8 +404,8 @@ export const getResponses = async (surveyId: string, page?: number): Promise