diff --git a/apps/web/app/api/(internal)/pipeline/lib/handleIntegrations.ts b/apps/web/app/api/(internal)/pipeline/lib/handleIntegrations.ts index 2d11b6389f..f267a66fc2 100644 --- a/apps/web/app/api/(internal)/pipeline/lib/handleIntegrations.ts +++ b/apps/web/app/api/(internal)/pipeline/lib/handleIntegrations.ts @@ -357,7 +357,10 @@ const buildNotionPayloadProperties = ( // notion requires specific payload for each column type // * TYPES NOT SUPPORTED BY NOTION API - rollup, created_by, created_time, last_edited_by, or last_edited_time -const getValue = (colType: string, value: string | string[] | Date | number | Record) => { +const getValue = ( + colType: string, + value: string | string[] | Date | number | Record | undefined +) => { try { switch (colType) { case "select": diff --git a/apps/web/lib/responses.ts b/apps/web/lib/responses.ts index e8760e1377..5db594e27e 100644 --- a/apps/web/lib/responses.ts +++ b/apps/web/lib/responses.ts @@ -1,11 +1,11 @@ import { parseRecallInfo } from "@/lib/utils/recall"; -import { TResponse } from "@formbricks/types/responses"; +import { TResponse, TResponseDataValue } from "@formbricks/types/responses"; import { TSurvey, TSurveyQuestion, TSurveyQuestionType } from "@formbricks/types/surveys/types"; import { getLanguageCode, getLocalizedValue } from "./i18n/utils"; // function to convert response value of type string | number | string[] or Record to string | string[] export const convertResponseValue = ( - answer: string | number | string[] | Record, + answer: TResponseDataValue, question: TSurveyQuestion ): string | string[] => { switch (question.type) { @@ -57,9 +57,7 @@ export const getQuestionResponseMapping = ( return questionResponseMapping; }; -export const processResponseData = ( - responseData: string | number | string[] | Record -): string => { +export const processResponseData = (responseData: TResponseDataValue): string => { switch (typeof responseData) { case "string": return responseData; diff --git a/apps/web/lib/surveyLogic/utils.ts b/apps/web/lib/surveyLogic/utils.ts index 890b0a2cac..2528505ebb 100644 --- a/apps/web/lib/surveyLogic/utils.ts +++ b/apps/web/lib/surveyLogic/utils.ts @@ -450,7 +450,7 @@ const evaluateSingleCondition = ( return ( Array.isArray(leftValue) && Array.isArray(rightValue) && - rightValue.some((v) => !leftValue.includes(v)) + !rightValue.some((v) => leftValue.includes(v)) ); case "isAccepted": return leftValue === "accepted"; diff --git a/apps/web/modules/analysis/components/SingleResponseCard/components/RenderResponse.tsx b/apps/web/modules/analysis/components/SingleResponseCard/components/RenderResponse.tsx index 547c329842..2cdab6b0bb 100644 --- a/apps/web/modules/analysis/components/SingleResponseCard/components/RenderResponse.tsx +++ b/apps/web/modules/analysis/components/SingleResponseCard/components/RenderResponse.tsx @@ -13,6 +13,7 @@ import { RatingResponse } from "@/modules/ui/components/rating-response"; import { ResponseBadges } from "@/modules/ui/components/response-badges"; import { CheckCheckIcon, MousePointerClickIcon, PhoneIcon } from "lucide-react"; import React from "react"; +import { TResponseDataValue } from "@formbricks/types/responses"; import { TSurvey, TSurveyMatrixQuestion, @@ -23,7 +24,7 @@ import { } from "@formbricks/types/surveys/types"; interface RenderResponseProps { - responseData: string | number | string[] | Record; + responseData: TResponseDataValue; question: TSurveyQuestion; survey: TSurvey; language: string | null; diff --git a/apps/web/modules/analysis/components/SingleResponseCard/util.ts b/apps/web/modules/analysis/components/SingleResponseCard/util.ts index e6ffa45e9b..af76d0a68b 100644 --- a/apps/web/modules/analysis/components/SingleResponseCard/util.ts +++ b/apps/web/modules/analysis/components/SingleResponseCard/util.ts @@ -1,4 +1,6 @@ -export const isValidValue = (value: string | number | Record | string[]) => { +import { TResponseDataValue } from "@formbricks/types/responses"; + +export const isValidValue = (value: TResponseDataValue) => { return ( (typeof value === "string" && value.trim() !== "") || (Array.isArray(value) && value.length > 0) || diff --git a/packages/surveys/src/components/general/question-conditional.tsx b/packages/surveys/src/components/general/question-conditional.tsx index edf002f8ee..9b29c27a8e 100644 --- a/packages/surveys/src/components/general/question-conditional.tsx +++ b/packages/surveys/src/components/general/question-conditional.tsx @@ -27,7 +27,7 @@ import { interface QuestionConditionalProps { question: TSurveyQuestion; - value: string | number | string[] | Record; + value: TResponseDataValue; onChange: (responseData: TResponseData) => void; onSubmit: (data: TResponseData, ttc: TResponseTtc) => void; onBack: () => void; diff --git a/packages/surveys/src/components/questions/multiple-choice-single-question.tsx b/packages/surveys/src/components/questions/multiple-choice-single-question.tsx index 2c3d52693d..24e7140bfa 100644 --- a/packages/surveys/src/components/questions/multiple-choice-single-question.tsx +++ b/packages/surveys/src/components/questions/multiple-choice-single-question.tsx @@ -112,7 +112,7 @@ export function MultipleChoiceSingleQuestion({ e.preventDefault(); const updatedTtcObj = getUpdatedTtc(ttc, question.id, performance.now() - startTime); setTtc(updatedTtcObj); - onSubmit({ [question.id]: value ?? "" }, updatedTtcObj); + onSubmit({ [question.id]: value }, updatedTtcObj); }} className="fb-w-full"> {isMediaAvailable ? : null} @@ -208,9 +208,13 @@ export function MultipleChoiceSingleQuestion({ value={getLocalizedValue(otherOption.label, languageCode)} className="fb-border-brand fb-text-brand fb-h-4 fb-w-4 fb-flex-shrink-0 fb-border focus:fb-ring-0 focus:fb-ring-offset-0" aria-labelledby={`${otherOption.id}-label`} - onChange={() => { - setOtherSelected(!otherSelected); - onChange({ [question.id]: "" }); + onClick={() => { + if (otherSelected) { + onChange({ [question.id]: undefined }); + } else { + setOtherSelected(!otherSelected); + onChange({ [question.id]: "" }); + } }} checked={otherSelected} /> diff --git a/packages/surveys/src/lib/logic.ts b/packages/surveys/src/lib/logic.ts index 5ea5594812..2b0610b0ce 100644 --- a/packages/surveys/src/lib/logic.ts +++ b/packages/surveys/src/lib/logic.ts @@ -407,7 +407,7 @@ const evaluateSingleCondition = ( return ( Array.isArray(leftValue) && Array.isArray(rightValue) && - rightValue.some((v) => !leftValue.includes(v)) + !rightValue.some((v) => leftValue.includes(v)) ); case "isAccepted": return leftValue === "accepted"; diff --git a/packages/types/responses.ts b/packages/types/responses.ts index 9d359f6f0c..598c27fd2c 100644 --- a/packages/types/responses.ts +++ b/packages/types/responses.ts @@ -4,12 +4,9 @@ import { ZSurveyQuota } from "./quota"; import { ZSurvey } from "./surveys/types"; import { ZTag } from "./tags"; -export const ZResponseDataValue = z.union([ - z.string(), - z.number(), - z.array(z.string()), - z.record(z.string()), -]); +export const ZResponseDataValue = z + .union([z.string(), z.number(), z.array(z.string()), z.record(z.string())]) + .optional(); export const ZResponseFilterCondition = z.enum([ "accepted",