mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-27 23:49:51 -05:00
feat: added dropoff visibility (#907)
Co-authored-by: Johannes <johannes@formbricks.com> Co-authored-by: Shubham Palriwala <spalriwalau@gmail.com> Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import PreviewSurvey from "./PreviewSurvey";
|
||||
import { findTemplateByName } from "./templates";
|
||||
import { TTemplate } from "@formbricks/types/surveys";
|
||||
import { TTemplate } from "@formbricks/types/templates";
|
||||
|
||||
interface DemoPreviewProps {
|
||||
template: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TTemplate } from "@formbricks/types/surveys";
|
||||
import { TTemplate } from "@formbricks/types/templates";
|
||||
import { useEffect, useState } from "react";
|
||||
import PreviewSurvey from "./PreviewSurvey";
|
||||
import TemplateList from "./TemplateList";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TTemplate } from "@formbricks/types/surveys";
|
||||
import { TTemplate } from "@formbricks/types/templates";
|
||||
import { useEffect, useState } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { templates } from "./templates";
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
} from "@formbricks/ui/icons";
|
||||
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { TTemplate } from "@formbricks/types/surveys";
|
||||
import { TTemplate } from "@formbricks/types/templates";
|
||||
import { TSurveyQuestionType } from "@formbricks/types/surveys";
|
||||
|
||||
const thankYouCardDefault = {
|
||||
@@ -51,6 +51,13 @@ export const customSurvey: TTemplate = {
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -143,6 +150,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -246,6 +260,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -319,6 +340,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -361,6 +389,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -412,6 +447,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -471,6 +513,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -533,6 +582,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -584,6 +640,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -622,6 +685,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -653,6 +723,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -675,6 +752,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -719,6 +803,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -757,6 +848,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -807,6 +905,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -856,6 +961,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -901,6 +1013,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -924,6 +1043,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -945,6 +1071,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -965,6 +1098,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1002,6 +1142,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1032,6 +1179,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1062,6 +1216,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1112,6 +1273,13 @@ export const templates: TTemplate[] = [
|
||||
},
|
||||
],
|
||||
thankYouCard: thankYouCardDefault,
|
||||
welcomeCard: {
|
||||
enabled: false,
|
||||
timeToFinish: false,
|
||||
},
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ export default function OpenTextSummary({ questionSummary, environmentId }: Open
|
||||
return (
|
||||
<div
|
||||
key={response.id}
|
||||
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
|
||||
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
|
||||
<div className="pl-4 md:pl-6">
|
||||
{response.person ? (
|
||||
<Link
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
import { evaluateCondition } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/evaluateLogic";
|
||||
import { TResponse } from "@formbricks/types/responses";
|
||||
import { TSurvey } from "@formbricks/types/surveys";
|
||||
import { useMemo } from "react";
|
||||
|
||||
interface SummaryDropOffsProps {
|
||||
survey: TSurvey;
|
||||
responses: TResponse[];
|
||||
displayCount: number;
|
||||
}
|
||||
|
||||
export default function SummaryDropOffs({ responses, survey, displayCount }: SummaryDropOffsProps) {
|
||||
const getDropoff = () => {
|
||||
let dropoffArr = new Array(survey.questions.length).fill(0);
|
||||
let viewsArr = new Array(survey.questions.length).fill(0);
|
||||
let dropoffPercentageArr = new Array(survey.questions.length).fill(0);
|
||||
|
||||
responses.forEach((response) => {
|
||||
let currQuesIdx = 0;
|
||||
|
||||
while (currQuesIdx < survey.questions.length) {
|
||||
const currQues = survey.questions[currQuesIdx];
|
||||
|
||||
if (!currQues.required) {
|
||||
if (!response.data[currQues.id]) {
|
||||
viewsArr[currQuesIdx]++;
|
||||
|
||||
if (currQuesIdx === survey.questions.length - 1 && !response.finished) {
|
||||
dropoffArr[currQuesIdx]++;
|
||||
break;
|
||||
}
|
||||
|
||||
const questionHasCustomLogic = currQues.logic;
|
||||
if (questionHasCustomLogic) {
|
||||
let didLogicPass = false;
|
||||
for (let logic of questionHasCustomLogic) {
|
||||
if (!logic.destination) continue;
|
||||
if (evaluateCondition(logic, response.data[currQues.id] ?? null)) {
|
||||
didLogicPass = true;
|
||||
currQuesIdx = survey.questions.findIndex((q) => q.id === logic.destination);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!didLogicPass) currQuesIdx++;
|
||||
} else {
|
||||
currQuesIdx++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(response.data[currQues.id] === undefined && !response.finished) ||
|
||||
(currQues.required && !response.data[currQues.id])
|
||||
) {
|
||||
dropoffArr[currQuesIdx]++;
|
||||
viewsArr[currQuesIdx]++;
|
||||
break;
|
||||
}
|
||||
|
||||
viewsArr[currQuesIdx]++;
|
||||
|
||||
let nextQuesIdx = currQuesIdx + 1;
|
||||
const questionHasCustomLogic = currQues.logic;
|
||||
|
||||
if (questionHasCustomLogic) {
|
||||
for (let logic of questionHasCustomLogic) {
|
||||
if (!logic.destination) continue;
|
||||
if (evaluateCondition(logic, response.data[currQues.id])) {
|
||||
nextQuesIdx = survey.questions.findIndex((q) => q.id === logic.destination);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!response.data[survey.questions[nextQuesIdx]?.id] && !response.finished) {
|
||||
dropoffArr[nextQuesIdx]++;
|
||||
viewsArr[nextQuesIdx]++;
|
||||
break;
|
||||
}
|
||||
|
||||
currQuesIdx = nextQuesIdx;
|
||||
}
|
||||
});
|
||||
|
||||
dropoffPercentageArr[0] = (dropoffArr[0] / displayCount) * 100 || 0;
|
||||
for (let i = 1; i < survey.questions.length; i++) {
|
||||
if (viewsArr[i - 1] !== 0) {
|
||||
dropoffPercentageArr[i] = (dropoffArr[i] / viewsArr[i - 1]) * 100;
|
||||
}
|
||||
}
|
||||
|
||||
return [dropoffArr, viewsArr, dropoffPercentageArr];
|
||||
};
|
||||
|
||||
const [dropoffCount, viewsCount, dropoffPercentage] = useMemo(() => getDropoff(), [responses]);
|
||||
|
||||
return (
|
||||
<div className="rounded-lg border border-slate-200 bg-slate-50 shadow-sm">
|
||||
<div className="rounded-b-lg bg-white ">
|
||||
<div className="grid h-10 grid-cols-5 items-center border-y border-slate-200 bg-slate-100 text-sm font-bold text-slate-600">
|
||||
<div className="col-span-3 pl-4 md:pl-6">Questions</div>
|
||||
<div className="pl-4 text-center md:pl-6">Views</div>
|
||||
<div className="px-4 text-center md:px-6">Drop-off</div>
|
||||
</div>
|
||||
{survey.questions.map((question, i) => (
|
||||
<div
|
||||
key={question.id}
|
||||
className="grid grid-cols-5 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
|
||||
<div className="col-span-3 pl-4 md:pl-6">{question.headline}</div>
|
||||
<div className="whitespace-pre-wrap pl-6 text-center font-semibold">{viewsCount[i]}</div>
|
||||
<div className="px-4 text-center md:px-6">
|
||||
<span className="font-semibold">{dropoffCount[i]} </span>
|
||||
<span>({Math.round(dropoffPercentage[i])}%)</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+19
-2
@@ -1,10 +1,14 @@
|
||||
import { timeSinceConditionally } from "@formbricks/lib/time";
|
||||
import { Button } from "@formbricks/ui/Button";
|
||||
import { TResponse } from "@formbricks/types/responses";
|
||||
import { TSurvey } from "@formbricks/types/surveys";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@formbricks/ui/Tooltip";
|
||||
import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/solid";
|
||||
|
||||
interface SummaryMetadataProps {
|
||||
responses: TResponse[];
|
||||
showDropOffs: boolean;
|
||||
setShowDropOffs: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
survey: TSurvey;
|
||||
displayCount: number;
|
||||
}
|
||||
@@ -30,7 +34,13 @@ const StatCard = ({ label, percentage, value, tooltipText }) => (
|
||||
</TooltipProvider>
|
||||
);
|
||||
|
||||
export default function SummaryMetadata({ responses, survey, displayCount }: SummaryMetadataProps) {
|
||||
export default function SummaryMetadata({
|
||||
responses,
|
||||
survey,
|
||||
displayCount,
|
||||
setShowDropOffs,
|
||||
showDropOffs,
|
||||
}: SummaryMetadataProps) {
|
||||
const completedResponses = responses.filter((r) => r.finished).length;
|
||||
const totalResponses = responses.length;
|
||||
|
||||
@@ -63,10 +73,17 @@ export default function SummaryMetadata({ responses, survey, displayCount }: Sum
|
||||
tooltipText="People who started but not completed the survey."
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col justify-between lg:col-span-1">
|
||||
<div className="flex flex-col justify-between gap-2 lg:col-span-1">
|
||||
<div className="text-right text-xs text-slate-400">
|
||||
Last updated: {timeSinceConditionally(survey.updatedAt.toISOString())}
|
||||
</div>
|
||||
<Button
|
||||
variant="minimal"
|
||||
className="w-max self-start"
|
||||
EndIcon={showDropOffs ? ChevronDownIcon : ChevronUpIcon}
|
||||
onClick={() => setShowDropOffs(!showDropOffs)}>
|
||||
Analyze Drop Offs
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+11
-2
@@ -7,6 +7,8 @@ import SummaryMetadata from "@/app/(app)/environments/[environmentId]/surveys/[s
|
||||
import CustomFilter from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/CustomFilter";
|
||||
import SummaryHeader from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/SummaryHeader";
|
||||
import { getFilterResponses } from "@/app/lib/surveys/surveys";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import SummaryDropOffs from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryDropOffs";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TProduct } from "@formbricks/types/product";
|
||||
import { TProfile } from "@formbricks/types/profile";
|
||||
@@ -15,7 +17,6 @@ import { TSurvey } from "@formbricks/types/surveys";
|
||||
import { TTag } from "@formbricks/types/tags";
|
||||
import ContentWrapper from "@formbricks/ui/ContentWrapper";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useEffect, useMemo } from "react";
|
||||
|
||||
interface SummaryPageProps {
|
||||
environment: TEnvironment;
|
||||
@@ -41,6 +42,7 @@ const SummaryPage = ({
|
||||
displayCount,
|
||||
}: SummaryPageProps) => {
|
||||
const { selectedFilter, dateRange, resetState } = useResponseFilter();
|
||||
const [showDropOffs, setShowDropOffs] = useState<boolean>(false);
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -71,7 +73,14 @@ const SummaryPage = ({
|
||||
totalResponses={responses}
|
||||
/>
|
||||
<SurveyResultsTabs activeId="summary" environmentId={environment.id} surveyId={surveyId} />
|
||||
<SummaryMetadata responses={filterResponses} survey={survey} displayCount={displayCount} />
|
||||
<SummaryMetadata
|
||||
responses={filterResponses}
|
||||
survey={survey}
|
||||
displayCount={displayCount}
|
||||
showDropOffs={showDropOffs}
|
||||
setShowDropOffs={setShowDropOffs}
|
||||
/>
|
||||
{showDropOffs && <SummaryDropOffs survey={survey} responses={responses} displayCount={displayCount} />}
|
||||
<SummaryList responses={filterResponses} survey={survey} environment={environment} />
|
||||
</ContentWrapper>
|
||||
);
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
import { TSurveyLogic } from "@formbricks/types/surveys";
|
||||
|
||||
export function evaluateCondition(logic: TSurveyLogic, responseValue: any): boolean {
|
||||
switch (logic.condition) {
|
||||
case "equals":
|
||||
return (
|
||||
(Array.isArray(responseValue) && responseValue.length === 1 && responseValue.includes(logic.value)) ||
|
||||
responseValue?.toString() === logic.value
|
||||
);
|
||||
case "notEquals":
|
||||
return responseValue !== logic.value;
|
||||
case "lessThan":
|
||||
return logic.value !== undefined && responseValue < logic.value;
|
||||
case "lessEqual":
|
||||
return logic.value !== undefined && responseValue <= logic.value;
|
||||
case "greaterThan":
|
||||
return logic.value !== undefined && responseValue > logic.value;
|
||||
case "greaterEqual":
|
||||
return logic.value !== undefined && responseValue >= logic.value;
|
||||
case "includesAll":
|
||||
return (
|
||||
Array.isArray(responseValue) &&
|
||||
Array.isArray(logic.value) &&
|
||||
logic.value.every((v) => responseValue.includes(v))
|
||||
);
|
||||
case "includesOne":
|
||||
return (
|
||||
Array.isArray(responseValue) &&
|
||||
Array.isArray(logic.value) &&
|
||||
logic.value.some((v) => responseValue.includes(v))
|
||||
);
|
||||
case "accepted":
|
||||
return responseValue === "accepted";
|
||||
case "clicked":
|
||||
return responseValue === "clicked";
|
||||
case "submitted":
|
||||
if (typeof responseValue === "string") {
|
||||
return responseValue !== "dismissed" && responseValue !== "" && responseValue !== null;
|
||||
} else if (Array.isArray(responseValue)) {
|
||||
return responseValue.length > 0;
|
||||
} else if (typeof responseValue === "number") {
|
||||
return responseValue !== null;
|
||||
}
|
||||
return false;
|
||||
case "skipped":
|
||||
return (
|
||||
(Array.isArray(responseValue) && responseValue.length === 0) ||
|
||||
responseValue === "" ||
|
||||
responseValue === null ||
|
||||
responseValue === "dismissed"
|
||||
);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user