feat: Added recall highlighting to summary header (#2672)

Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
Dhruwang Jariwala
2024-05-29 18:21:42 +05:30
committed by GitHub
parent d53ceaaaac
commit 291f628415
19 changed files with 247 additions and 59 deletions

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="">
<div className="grid h-10 grid-cols-4 items-center border-y border-slate-200 bg-slate-100 text-sm font-bold text-slate-600">
<div className="pl-4 md:pl-6">User</div>

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader
survey={survey}
questionSummary={questionSummary}
showResponses={false}
attributeClasses={attributeClasses}
insights={
<>
<div className="flex items-center rounded-lg bg-slate-100 p-2">

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
<div>
<div className="text flex justify-between px-2 pb-2">

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
<div>
<div className="text flex justify-between px-2 pb-2">

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="">
<div className="grid h-10 grid-cols-4 items-center border-y border-slate-200 bg-slate-100 text-sm font-bold text-slate-600">
<div className="pl-4 md:pl-6">User</div>

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="">
<div className="grid h-10 grid-cols-4 items-center border-y border-slate-200 bg-slate-100 text-sm font-bold text-slate-600">
<div className="pl-4 md:pl-6">User</div>

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="overflow-x-auto p-6">
{/* Summary Table */}
<table className="mx-auto border-collapse cursor-default text-left">

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
{results.map((result, resultsIdx) => (
<div key={result.value}>

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
{["promoters", "passives", "detractors"].map((group) => (
<div key={group}>

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="">
<div className="grid h-10 grid-cols-4 items-center border-y border-slate-200 bg-slate-100 text-sm font-bold text-slate-600">
<div className="pl-4 md:pl-6">User</div>

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
{results.map((result) => (
<div key={result.id}>

View File

@@ -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 (
<span key={index} className="mx-1 rounded-md bg-slate-100 p-1 px-2 text-lg">
@{part}
</span>
);
} else {
return part;
}
});
};
return (
<div className="space-y-2 px-4 pb-5 pt-6 md:px-6">
<div className={"align-center flex justify-between gap-4 "}>
<h3 className="pb-1 text-lg font-semibold text-slate-900 md:text-xl">
{getLocalizedValue(questionSummary.question.headline, "default")}
{formatTextWithSlashes(
recallToHeadline(questionSummary.question.headline, survey, true, "default", attributeClasses)[
"default"
]
)}
</h3>
</div>
<div className="flex space-x-2 text-xs font-semibold text-slate-600 md:text-sm">

View File

@@ -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 (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
<QuestionSummaryHeader
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
{questionSummary.choices.map((result) => (
<div key={result.rating}>

View File

@@ -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 (
<div className="mt-10 space-y-8">
@@ -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 <NPSSummary key={questionSummary.question.id} questionSummary={questionSummary} />;
return (
<NPSSummary
key={questionSummary.question.id}
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
);
}
if (questionSummary.type === TSurveyQuestionType.CTA) {
return <CTASummary key={questionSummary.question.id} questionSummary={questionSummary} />;
return (
<CTASummary
key={questionSummary.question.id}
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
);
}
if (questionSummary.type === TSurveyQuestionType.Rating) {
return <RatingSummary key={questionSummary.question.id} questionSummary={questionSummary} />;
return (
<RatingSummary
key={questionSummary.question.id}
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
);
}
if (questionSummary.type === TSurveyQuestionType.Consent) {
return <ConsentSummary key={questionSummary.question.id} questionSummary={questionSummary} />;
return (
<ConsentSummary
key={questionSummary.question.id}
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
);
}
if (questionSummary.type === TSurveyQuestionType.PictureSelection) {
return (
<PictureChoiceSummary key={questionSummary.question.id} questionSummary={questionSummary} />
<PictureChoiceSummary
key={questionSummary.question.id}
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
);
}
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 (
<MatrixQuestionSummary key={questionSummary.question.id} questionSummary={questionSummary} />
<MatrixQuestionSummary
key={questionSummary.question.id}
questionSummary={questionSummary}
survey={survey}
attributeClasses={attributeClasses}
/>
);
}
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}
/>
);
}

View File

@@ -136,6 +136,7 @@ export const SummaryPage = ({
environment={environment}
fetchingSummary={isFetchingSummary}
totalResponseCount={totalResponseCount}
attributeClasses={attributeClasses}
/>
</>
);

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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<string, string> 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,
});

2
pnpm-lock.yaml generated
View File

@@ -21109,4 +21109,4 @@ packages:
/zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
dev: false
dev: false