From 291f628415151eeb8ebd10a48437fb3b58b3e0fa Mon Sep 17 00:00:00 2001 From: Dhruwang Jariwala <67850763+Dhruwang@users.noreply.github.com> Date: Wed, 29 May 2024 18:21:42 +0530 Subject: [PATCH] feat: Added recall highlighting to summary header (#2672) Co-authored-by: Matthias Nannt --- .../summary/components/AddressSummary.tsx | 18 ++++- .../summary/components/CTASummary.tsx | 9 ++- .../summary/components/CalSummary.tsx | 13 +++- .../summary/components/ConsentSummary.tsx | 13 +++- .../components/DateQuestionSummary.tsx | 18 ++++- .../summary/components/FileUploadSummary.tsx | 18 ++++- .../components/MatrixQuestionSummary.tsx | 17 ++++- .../components/MultipleChoiceSummary.tsx | 13 +++- .../summary/components/NPSSummary.tsx | 13 +++- .../summary/components/OpenTextSummary.tsx | 18 ++++- .../components/PictureChoiceSummary.tsx | 17 ++++- .../components/QuestionSummaryHeader.tsx | 40 ++++++++++-- .../summary/components/RatingSummary.tsx | 13 +++- .../summary/components/SummaryList.tsx | 65 +++++++++++++++++-- .../summary/components/SummaryPage.tsx | 1 + apps/web/app/api/pipeline/route.ts | 5 +- packages/lib/response/service.ts | 9 +-- packages/lib/responses.ts | 4 +- pnpm-lock.yaml | 2 +- 19 files changed, 247 insertions(+), 59 deletions(-) diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/AddressSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/AddressSummary.tsx index 5ace48a133..2063f86613 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/AddressSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/AddressSummary.tsx @@ -2,7 +2,8 @@ import Link from "next/link"; import { getPersonIdentifier } from "@formbricks/lib/person/utils"; import { timeSince } from "@formbricks/lib/time"; -import { TSurveyQuestionSummaryAddress } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryAddress } from "@formbricks/types/surveys"; import { AddressResponse } from "@formbricks/ui/AddressResponse"; import { PersonAvatar } from "@formbricks/ui/Avatars"; @@ -11,12 +12,23 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface AddressSummaryProps { questionSummary: TSurveyQuestionSummaryAddress; environmentId: string; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const AddressSummary = ({ questionSummary, environmentId }: AddressSummaryProps) => { +export const AddressSummary = ({ + questionSummary, + environmentId, + survey, + attributeClasses, +}: AddressSummaryProps) => { return (
- +
User
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CTASummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CTASummary.tsx index c47d5f5a7e..0dd2ddcea8 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CTASummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CTASummary.tsx @@ -1,6 +1,7 @@ import { InboxIcon } from "lucide-react"; -import { TSurveyQuestionSummaryCta } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryCta } from "@formbricks/types/surveys"; import { ProgressBar } from "@formbricks/ui/ProgressBar"; import { convertFloatToNDecimal } from "../lib/utils"; @@ -8,14 +9,18 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface CTASummaryProps { questionSummary: TSurveyQuestionSummaryCta; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const CTASummary = ({ questionSummary }: CTASummaryProps) => { +export const CTASummary = ({ questionSummary, survey, attributeClasses }: CTASummaryProps) => { return (
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CalSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CalSummary.tsx index e3cdcbfa8c..d296181674 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CalSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/CalSummary.tsx @@ -1,6 +1,7 @@ import { convertFloatToNDecimal } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/lib/utils"; -import { TSurveyQuestionSummaryCal } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryCal } from "@formbricks/types/surveys"; import { ProgressBar } from "@formbricks/ui/ProgressBar"; import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; @@ -8,12 +9,18 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface CalSummaryProps { questionSummary: TSurveyQuestionSummaryCal; environmentId: string; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const CalSummary = ({ questionSummary }: CalSummaryProps) => { +export const CalSummary = ({ questionSummary, survey, attributeClasses }: CalSummaryProps) => { return (
- +
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ConsentSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ConsentSummary.tsx index 49abc8cbc9..82809076ac 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ConsentSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ConsentSummary.tsx @@ -1,4 +1,5 @@ -import { TSurveyQuestionSummaryConsent } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryConsent } from "@formbricks/types/surveys"; import { ProgressBar } from "@formbricks/ui/ProgressBar"; import { convertFloatToNDecimal } from "../lib/utils"; @@ -6,12 +7,18 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface ConsentSummaryProps { questionSummary: TSurveyQuestionSummaryConsent; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const ConsentSummary = ({ questionSummary }: ConsentSummaryProps) => { +export const ConsentSummary = ({ questionSummary, survey, attributeClasses }: ConsentSummaryProps) => { return (
- +
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/DateQuestionSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/DateQuestionSummary.tsx index de04cc4fe1..d8be2000aa 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/DateQuestionSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/DateQuestionSummary.tsx @@ -4,7 +4,8 @@ import { useState } from "react"; import { getPersonIdentifier } from "@formbricks/lib/person/utils"; import { timeSince } from "@formbricks/lib/time"; import { formatDateWithOrdinal } from "@formbricks/lib/utils/datetime"; -import { TSurveyQuestionSummaryDate } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryDate } from "@formbricks/types/surveys"; import { PersonAvatar } from "@formbricks/ui/Avatars"; import { Button } from "@formbricks/ui/Button"; @@ -13,9 +14,16 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface DateQuestionSummary { questionSummary: TSurveyQuestionSummaryDate; environmentId: string; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const DateQuestionSummary = ({ questionSummary, environmentId }: DateQuestionSummary) => { +export const DateQuestionSummary = ({ + questionSummary, + environmentId, + survey, + attributeClasses, +}: DateQuestionSummary) => { const [visibleResponses, setVisibleResponses] = useState(10); const handleLoadMore = () => { @@ -27,7 +35,11 @@ export const DateQuestionSummary = ({ questionSummary, environmentId }: DateQues return (
- +
User
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/FileUploadSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/FileUploadSummary.tsx index d43226cbac..f22d1ff16b 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/FileUploadSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/FileUploadSummary.tsx @@ -5,7 +5,8 @@ import { useState } from "react"; import { getPersonIdentifier } from "@formbricks/lib/person/utils"; import { getOriginalFileNameFromUrl } from "@formbricks/lib/storage/utils"; import { timeSince } from "@formbricks/lib/time"; -import { TSurveyQuestionSummaryFileUpload } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryFileUpload } from "@formbricks/types/surveys"; import { PersonAvatar } from "@formbricks/ui/Avatars"; import { Button } from "@formbricks/ui/Button"; @@ -14,9 +15,16 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface FileUploadSummaryProps { questionSummary: TSurveyQuestionSummaryFileUpload; environmentId: string; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const FileUploadSummary = ({ questionSummary, environmentId }: FileUploadSummaryProps) => { +export const FileUploadSummary = ({ + questionSummary, + environmentId, + survey, + attributeClasses, +}: FileUploadSummaryProps) => { const [visibleResponses, setVisibleResponses] = useState(10); const handleLoadMore = () => { @@ -28,7 +36,11 @@ export const FileUploadSummary = ({ questionSummary, environmentId }: FileUpload return (
- +
User
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/MatrixQuestionSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/MatrixQuestionSummary.tsx index 229f9881af..ae7306e076 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/MatrixQuestionSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/MatrixQuestionSummary.tsx @@ -1,13 +1,20 @@ -import { TSurveyQuestionSummaryMatrix } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryMatrix } from "@formbricks/types/surveys"; import { TooltipRenderer } from "@formbricks/ui/Tooltip"; import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface MatrixQuestionSummaryProps { questionSummary: TSurveyQuestionSummaryMatrix; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const MatrixQuestionSummary = ({ questionSummary }: MatrixQuestionSummaryProps) => { +export const MatrixQuestionSummary = ({ + questionSummary, + survey, + attributeClasses, +}: MatrixQuestionSummaryProps) => { const getOpacityLevel = (percentage: number): string => { const parsedPercentage = percentage; const opacity = parsedPercentage * 0.75 + 15; @@ -27,7 +34,11 @@ export const MatrixQuestionSummary = ({ questionSummary }: MatrixQuestionSummary return (
- +
{/* Summary Table */} diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/MultipleChoiceSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/MultipleChoiceSummary.tsx index 918962574a..c7a4949659 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/MultipleChoiceSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/MultipleChoiceSummary.tsx @@ -2,7 +2,8 @@ import Link from "next/link"; import { useState } from "react"; import { getPersonIdentifier } from "@formbricks/lib/person/utils"; -import { TSurveyQuestionSummaryMultipleChoice, TSurveyType } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryMultipleChoice, TSurveyType } from "@formbricks/types/surveys"; import { PersonAvatar } from "@formbricks/ui/Avatars"; import { Button } from "@formbricks/ui/Button"; import { ProgressBar } from "@formbricks/ui/ProgressBar"; @@ -14,12 +15,16 @@ interface MultipleChoiceSummaryProps { questionSummary: TSurveyQuestionSummaryMultipleChoice; environmentId: string; surveyType: TSurveyType; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } export const MultipleChoiceSummary = ({ questionSummary, environmentId, surveyType, + survey, + attributeClasses, }: MultipleChoiceSummaryProps) => { const [visibleOtherResponses, setVisibleOtherResponses] = useState(10); @@ -45,7 +50,11 @@ export const MultipleChoiceSummary = ({ return (
- +
{results.map((result, resultsIdx) => (
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/NPSSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/NPSSummary.tsx index 7a2ea4484e..9fa149764f 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/NPSSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/NPSSummary.tsx @@ -1,4 +1,5 @@ -import { TSurveyQuestionSummaryNps } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryNps } from "@formbricks/types/surveys"; import { HalfCircle, ProgressBar } from "@formbricks/ui/ProgressBar"; import { convertFloatToNDecimal } from "../lib/utils"; @@ -6,12 +7,18 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface NPSSummaryProps { questionSummary: TSurveyQuestionSummaryNps; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const NPSSummary = ({ questionSummary }: NPSSummaryProps) => { +export const NPSSummary = ({ questionSummary, survey, attributeClasses }: NPSSummaryProps) => { return (
- +
{["promoters", "passives", "detractors"].map((group) => (
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/OpenTextSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/OpenTextSummary.tsx index 8385c2388b..321a457500 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/OpenTextSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/OpenTextSummary.tsx @@ -3,7 +3,8 @@ import { useState } from "react"; import { getPersonIdentifier } from "@formbricks/lib/person/utils"; import { timeSince } from "@formbricks/lib/time"; -import { TSurveyQuestionSummaryOpenText } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryOpenText } from "@formbricks/types/surveys"; import { PersonAvatar } from "@formbricks/ui/Avatars"; import { Button } from "@formbricks/ui/Button"; @@ -12,9 +13,16 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface OpenTextSummaryProps { questionSummary: TSurveyQuestionSummaryOpenText; environmentId: string; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const OpenTextSummary = ({ questionSummary, environmentId }: OpenTextSummaryProps) => { +export const OpenTextSummary = ({ + questionSummary, + environmentId, + survey, + attributeClasses, +}: OpenTextSummaryProps) => { const [visibleResponses, setVisibleResponses] = useState(10); const handleLoadMore = () => { @@ -26,7 +34,11 @@ export const OpenTextSummary = ({ questionSummary, environmentId }: OpenTextSumm return (
- +
User
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/PictureChoiceSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/PictureChoiceSummary.tsx index 5e1ace6f3b..dd7a852f0a 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/PictureChoiceSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/PictureChoiceSummary.tsx @@ -1,6 +1,7 @@ import Image from "next/image"; -import { TSurveyQuestionSummaryPictureSelection } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryPictureSelection } from "@formbricks/types/surveys"; import { ProgressBar } from "@formbricks/ui/ProgressBar"; import { convertFloatToNDecimal } from "../lib/utils"; @@ -8,14 +9,24 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface PictureChoiceSummaryProps { questionSummary: TSurveyQuestionSummaryPictureSelection; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const PictureChoiceSummary = ({ questionSummary }: PictureChoiceSummaryProps) => { +export const PictureChoiceSummary = ({ + questionSummary, + survey, + attributeClasses, +}: PictureChoiceSummaryProps) => { const results = questionSummary.choices.sort((a, b) => b.count - a.count); return (
- +
{results.map((result) => (
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/QuestionSummaryHeader.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/QuestionSummaryHeader.tsx index 12316b7b1d..b1a74157e7 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/QuestionSummaryHeader.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/QuestionSummaryHeader.tsx @@ -1,23 +1,55 @@ import { questionTypes } from "@/app/lib/questions"; import { InboxIcon } from "lucide-react"; -import { getLocalizedValue } from "@formbricks/lib/i18n/utils"; -import { TSurveyQuestionSummary } from "@formbricks/types/surveys"; +import { recallToHeadline } from "@formbricks/lib/utils/recall"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummary } from "@formbricks/types/surveys"; interface HeadProps { questionSummary: TSurveyQuestionSummary; showResponses?: boolean; insights?: JSX.Element; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const QuestionSummaryHeader = ({ questionSummary, insights, showResponses = true }: HeadProps) => { +export const QuestionSummaryHeader = ({ + questionSummary, + insights, + showResponses = true, + survey, + attributeClasses, +}: HeadProps) => { const questionType = questionTypes.find((type) => type.id === questionSummary.question.type); + // formats the text to highlight specific parts of the text with slashes + const formatTextWithSlashes = (text: string): (string | JSX.Element)[] => { + const regex = /\/(.*?)\\/g; + const parts = text.split(regex); + + return parts.map((part, index) => { + // Check if the part was inside slashes + if (index % 2 !== 0) { + return ( + + @{part} + + ); + } else { + return part; + } + }); + }; + return (

- {getLocalizedValue(questionSummary.question.headline, "default")} + {formatTextWithSlashes( + recallToHeadline(questionSummary.question.headline, survey, true, "default", attributeClasses)[ + "default" + ] + )}

diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/RatingSummary.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/RatingSummary.tsx index 32fc0888b5..3cc91bf9ab 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/RatingSummary.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/RatingSummary.tsx @@ -1,6 +1,7 @@ import { convertFloatToNDecimal } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/lib/utils"; -import { TSurveyQuestionSummaryRating } from "@formbricks/types/surveys"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; +import { TSurvey, TSurveyQuestionSummaryRating } from "@formbricks/types/surveys"; import { ProgressBar } from "@formbricks/ui/ProgressBar"; import { RatingResponse } from "@formbricks/ui/RatingResponse"; @@ -8,12 +9,18 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader"; interface RatingSummaryProps { questionSummary: TSurveyQuestionSummaryRating; + survey: TSurvey; + attributeClasses: TAttributeClass[]; } -export const RatingSummary = ({ questionSummary }: RatingSummaryProps) => { +export const RatingSummary = ({ questionSummary, survey, attributeClasses }: RatingSummaryProps) => { return (
- +
{questionSummary.choices.map((result) => (
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryList.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryList.tsx index 25c6c4f6b6..673514ed61 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryList.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryList.tsx @@ -12,6 +12,7 @@ import { OpenTextSummary } from "@/app/(app)/environments/[environmentId]/survey import { PictureChoiceSummary } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/PictureChoiceSummary"; import { RatingSummary } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/RatingSummary"; +import { TAttributeClass } from "@formbricks/types/attributeClasses"; import { TEnvironment } from "@formbricks/types/environment"; import { TSurveySummary } from "@formbricks/types/surveys"; import { TSurveyQuestionType } from "@formbricks/types/surveys"; @@ -28,6 +29,7 @@ interface SummaryListProps { survey: TSurvey; fetchingSummary: boolean; totalResponseCount: number; + attributeClasses: TAttributeClass[]; } export const SummaryList = ({ @@ -37,6 +39,7 @@ export const SummaryList = ({ survey, fetchingSummary, totalResponseCount, + attributeClasses, }: SummaryListProps) => { return (
@@ -61,6 +64,8 @@ export const SummaryList = ({ key={questionSummary.question.id} questionSummary={questionSummary} environmentId={environment.id} + survey={survey} + attributeClasses={attributeClasses} /> ); } @@ -74,24 +79,59 @@ export const SummaryList = ({ questionSummary={questionSummary} environmentId={environment.id} surveyType={survey.type} + survey={survey} + attributeClasses={attributeClasses} /> ); } if (questionSummary.type === TSurveyQuestionType.NPS) { - return ; + return ( + + ); } if (questionSummary.type === TSurveyQuestionType.CTA) { - return ; + return ( + + ); } if (questionSummary.type === TSurveyQuestionType.Rating) { - return ; + return ( + + ); } if (questionSummary.type === TSurveyQuestionType.Consent) { - return ; + return ( + + ); } if (questionSummary.type === TSurveyQuestionType.PictureSelection) { return ( - + ); } if (questionSummary.type === TSurveyQuestionType.Date) { @@ -100,6 +140,8 @@ export const SummaryList = ({ key={questionSummary.question.id} questionSummary={questionSummary} environmentId={environment.id} + survey={survey} + attributeClasses={attributeClasses} /> ); } @@ -109,6 +151,8 @@ export const SummaryList = ({ key={questionSummary.question.id} questionSummary={questionSummary} environmentId={environment.id} + survey={survey} + attributeClasses={attributeClasses} /> ); } @@ -118,12 +162,19 @@ export const SummaryList = ({ key={questionSummary.question.id} questionSummary={questionSummary} environmentId={environment.id} + survey={survey} + attributeClasses={attributeClasses} /> ); } if (questionSummary.type === TSurveyQuestionType.Matrix) { return ( - + ); } if (questionSummary.type === TSurveyQuestionType.Address) { @@ -132,6 +183,8 @@ export const SummaryList = ({ key={questionSummary.question.id} questionSummary={questionSummary} environmentId={environment.id} + survey={survey} + attributeClasses={attributeClasses} /> ); } diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryPage.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryPage.tsx index 0448d2fff6..db7f240cc5 100644 --- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryPage.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryPage.tsx @@ -136,6 +136,7 @@ export const SummaryPage = ({ environment={environment} fetchingSummary={isFetchingSummary} totalResponseCount={totalResponseCount} + attributeClasses={attributeClasses} /> ); diff --git a/apps/web/app/api/pipeline/route.ts b/apps/web/app/api/pipeline/route.ts index 8d4eb53415..6e8f590b32 100644 --- a/apps/web/app/api/pipeline/route.ts +++ b/apps/web/app/api/pipeline/route.ts @@ -4,14 +4,12 @@ import { headers } from "next/headers"; import { prisma } from "@formbricks/database"; import { sendResponseFinishedEmail } from "@formbricks/email"; -import { getAttributeClasses } from "@formbricks/lib/attributeClass/service"; import { INTERNAL_SECRET } from "@formbricks/lib/constants"; import { getIntegrations } from "@formbricks/lib/integration/service"; import { getProductByEnvironmentId } from "@formbricks/lib/product/service"; import { getResponseCountBySurveyId } from "@formbricks/lib/response/service"; import { getSurvey, updateSurvey } from "@formbricks/lib/survey/service"; import { convertDatesInObject } from "@formbricks/lib/time"; -import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall"; import { ZPipelineInput } from "@formbricks/types/pipelines"; import { TUserNotificationSettings } from "@formbricks/types/user"; @@ -39,7 +37,6 @@ export const POST = async (request: Request) => { const { environmentId, surveyId, event, response } = inputValidation.data; const product = await getProductByEnvironmentId(environmentId); - const attributeClasses = await getAttributeClasses(environmentId); if (!product) return; // get all webhooks of this environment where event in triggers @@ -108,7 +105,7 @@ export const POST = async (request: Request) => { getIntegrations(environmentId), getSurvey(surveyId), ]); - const survey = surveyData ? replaceHeadlineRecall(surveyData, "default", attributeClasses) : undefined; + const survey = surveyData ?? undefined; if (integrations.length > 0 && survey) { handleIntegrations(integrations, inputValidation.data, survey); diff --git a/packages/lib/response/service.ts b/packages/lib/response/service.ts index 6d73cd33ff..3c5205cf96 100644 --- a/packages/lib/response/service.ts +++ b/packages/lib/response/service.ts @@ -25,7 +25,6 @@ import { TSurveySummary } from "@formbricks/types/surveys"; import { TTag } from "@formbricks/types/tags"; import { getAttributes } from "../attribute/service"; -import { getAttributeClasses } from "../attributeClass/service"; import { cache } from "../cache"; import { ITEMS_PER_PAGE, WEBAPP_URL } from "../constants"; import { displayCache } from "../display/cache"; @@ -37,7 +36,6 @@ import { putFile } from "../storage/service"; import { getSurvey } from "../survey/service"; import { captureTelemetry } from "../telemetry"; import { convertToCsv, convertToXlsxBuffer } from "../utils/fileConversion"; -import { replaceHeadlineRecall } from "../utils/recall"; import { validateInputs } from "../utils/validate"; import { responseCache } from "./cache"; import { @@ -563,7 +561,6 @@ export const getSurveySummary = ( if (!survey) { throw new ResourceNotFoundError("Survey", surveyId); } - const attributeClasses = await getAttributeClasses(survey.environmentId); const batchSize = 3000; const responseCount = await getResponseCountBySurveyId(surveyId, filterCriteria); @@ -582,11 +579,7 @@ export const getSurveySummary = ( const dropOff = getSurveySummaryDropOff(survey, responses, displayCount); const meta = getSurveySummaryMeta(responses, displayCount); - const questionWiseSummary = getQuestionWiseSummary( - replaceHeadlineRecall(survey, "default", attributeClasses), - responses, - dropOff - ); + const questionWiseSummary = getQuestionWiseSummary(survey, responses, dropOff); return { meta, dropOff, summary: questionWiseSummary }; } catch (error) { diff --git a/packages/lib/responses.ts b/packages/lib/responses.ts index f7d1a91fc3..135aebc78f 100644 --- a/packages/lib/responses.ts +++ b/packages/lib/responses.ts @@ -2,6 +2,7 @@ import { TResponse } from "@formbricks/types/responses"; import { TSurvey, TSurveyQuestion, TSurveyQuestionType } from "@formbricks/types/surveys"; import { getLocalizedValue } from "./i18n/utils"; +import { parseRecallInfo } from "./utils/recall"; // function to convert response value of type string | number | string[] or Record to string | string[] export const convertResponseValue = ( @@ -41,12 +42,11 @@ export const getQuestionResponseMapping = ( response: string | string[]; type: TSurveyQuestionType; }[] = []; - for (const question of survey.questions) { const answer = response.data[question.id]; questionResponseMapping.push({ - question: getLocalizedValue(question.headline, "default"), + question: parseRecallInfo(getLocalizedValue(question.headline, "default"), {}, response.data), response: convertResponseValue(answer, question), type: question.type, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 899a16e887..385073ac97 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21109,4 +21109,4 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - dev: false + dev: false \ No newline at end of file