fix: comparison fixes

This commit is contained in:
Piyush Gupta
2024-09-12 15:57:11 +05:30
parent 887c5c0eef
commit 0bf5e0fd4c
11 changed files with 176 additions and 188 deletions

View File

@@ -157,7 +157,7 @@ export function AdvancedLogicEditorActions({
placeholder: "Value",
type: localSurvey.variables.find((v) => v.id === action.variableId)?.type || "text",
}}
groupedOptions={getActionValueOptions(action.variableId, localSurvey, questionIdx)}
groupedOptions={getActionValueOptions(action.variableId, localSurvey)}
onChangeValue={(val, option, fromInput) => {
const fieldType = option?.meta?.type as TActionVariableValueType;

View File

@@ -236,24 +236,23 @@ export const getMatchValueProps = (
if (condition.leftOperand.type === "question") {
if (selectedQuestion?.type === TSurveyQuestionTypeEnum.OpenText) {
const allowedQuestions = questions.filter((question) => {
const allowedQuestionTypes = [
TSurveyQuestionTypeEnum.OpenText,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
TSurveyQuestionTypeEnum.Rating,
TSurveyQuestionTypeEnum.NPS,
];
const allowedQuestionTypes = [TSurveyQuestionTypeEnum.OpenText];
if (selectedQuestion.inputType === "number") {
allowedQuestionTypes.push(TSurveyQuestionTypeEnum.Rating, TSurveyQuestionTypeEnum.NPS);
}
if (["equals", "doesNotEqual"].includes(condition.operator)) {
if (selectedQuestion.inputType !== "number") {
allowedQuestionTypes.push(TSurveyQuestionTypeEnum.Date);
allowedQuestionTypes.push(
TSurveyQuestionTypeEnum.Date,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
TSurveyQuestionTypeEnum.MultipleChoiceMulti
);
}
}
if (["equals", "doesNotEqual"].includes(condition.operator)) {
allowedQuestionTypes.push(TSurveyQuestionTypeEnum.MultipleChoiceMulti);
}
return allowedQuestionTypes.includes(question.type);
});
const allowedQuestions = questions.filter((question) => allowedQuestionTypes.includes(question.type));
const questionOptions = allowedQuestions.map((question) => {
return {
@@ -528,15 +527,16 @@ export const getMatchValueProps = (
}
} else if (condition.leftOperand.type === "variable") {
if (selectedVariable?.type === "text") {
const allowedQuestions = questions.filter((question) =>
[
TSurveyQuestionTypeEnum.OpenText,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
TSurveyQuestionTypeEnum.Rating,
TSurveyQuestionTypeEnum.NPS,
TSurveyQuestionTypeEnum.Date,
].includes(question.type)
);
const allowedQuestionTypes = [
TSurveyQuestionTypeEnum.OpenText,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
];
if (["equals", "doesNotEqual"].includes(condition.operator)) {
allowedQuestionTypes.push(TSurveyQuestionTypeEnum.MultipleChoiceMulti, TSurveyQuestionTypeEnum.Date);
}
const allowedQuestions = questions.filter((question) => allowedQuestionTypes.includes(question.type));
const questionOptions = allowedQuestions.map((question) => {
return {
@@ -679,16 +679,16 @@ export const getMatchValueProps = (
};
}
} else if (condition.leftOperand.type === "hiddenField") {
const allowedQuestions = questions.filter((question) =>
[
TSurveyQuestionTypeEnum.OpenText,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
TSurveyQuestionTypeEnum.MultipleChoiceMulti,
TSurveyQuestionTypeEnum.Rating,
TSurveyQuestionTypeEnum.NPS,
TSurveyQuestionTypeEnum.Date,
].includes(question.type)
);
const allowedQuestionTypes = [
TSurveyQuestionTypeEnum.OpenText,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
];
if (["equals", "doesNotEqual"].includes(condition.operator)) {
allowedQuestionTypes.push(TSurveyQuestionTypeEnum.MultipleChoiceMulti, TSurveyQuestionTypeEnum.Date);
}
const allowedQuestions = questions.filter((question) => allowedQuestionTypes.includes(question.type));
const questionOptions = allowedQuestions.map((question) => {
return {
@@ -701,16 +701,18 @@ export const getMatchValueProps = (
};
});
const variableOptions = variables.map((variable) => {
return {
icon: variable.type === "number" ? FileDigitIcon : FileType2Icon,
label: variable.name,
value: variable.id,
meta: {
type: "variable",
},
};
});
const variableOptions = variables
.filter((variable) => variable.type === "text")
.map((variable) => {
return {
icon: FileType2Icon,
label: variable.name,
value: variable.id,
meta: {
type: "variable",
},
};
});
const hiddenFieldsOptions = hiddenFields.map((field) => {
return {
@@ -848,11 +850,7 @@ export const getActionOpeartorOptions = (variableType?: TSurveyVariable["type"])
return [];
};
export const getActionValueOptions = (
variableId: string,
localSurvey: TSurvey,
currQuestionIdx: number
): TComboboxGroupedOption[] => {
export const getActionValueOptions = (variableId: string, localSurvey: TSurvey): TComboboxGroupedOption[] => {
const hiddenFields = localSurvey.hiddenFields?.fieldIds || [];
let variables = localSurvey.variables || [];
const questions = localSurvey.questions;
@@ -875,16 +873,14 @@ export const getActionValueOptions = (
if (!selectedVariable) return [];
if (selectedVariable.type === "text") {
const allowedQuestions = questions.filter(
(question, idx) =>
idx !== currQuestionIdx &&
[
TSurveyQuestionTypeEnum.OpenText,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
TSurveyQuestionTypeEnum.Rating,
TSurveyQuestionTypeEnum.NPS,
TSurveyQuestionTypeEnum.Date,
].includes(question.type)
const allowedQuestions = questions.filter((question) =>
[
TSurveyQuestionTypeEnum.OpenText,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
TSurveyQuestionTypeEnum.Rating,
TSurveyQuestionTypeEnum.NPS,
TSurveyQuestionTypeEnum.Date,
].includes(question.type)
);
const questionOptions = allowedQuestions.map((question) => {
@@ -939,10 +935,8 @@ export const getActionValueOptions = (
return groupedOptions;
} else if (selectedVariable.type === "number") {
const allowedQuestions = questions.filter(
(question, idx) =>
idx !== currQuestionIdx &&
[TSurveyQuestionTypeEnum.Rating, TSurveyQuestionTypeEnum.NPS].includes(question.type)
const allowedQuestions = questions.filter((question) =>
[TSurveyQuestionTypeEnum.Rating, TSurveyQuestionTypeEnum.NPS].includes(question.type)
);
const questionOptions = allowedQuestions.map((question) => {

View File

@@ -146,7 +146,7 @@ export const createGroupFromResource = (group: TConditionGroup, resourceId: stri
conditions: [item],
};
group.conditions[i] = newGroup;
group.connector = "and";
group.connector = group.connector ?? "and";
return;
}

View File

@@ -85,38 +85,23 @@ const evaluateSingleCondition = (
switch (condition.operator) {
case "equals":
// when left value is of picture selection question and right value is its option
if (
condition.leftOperand.type === "question" &&
(leftField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.PictureSelection &&
Array.isArray(leftValue) &&
leftValue.length > 0 &&
typeof rightValue === "string"
) {
return leftValue.includes(rightValue);
}
// when left value is of date question and right value is string
if (
condition.leftOperand.type === "question" &&
(leftField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.Date &&
typeof leftValue === "string" &&
typeof rightValue === "string"
) {
return new Date(leftValue).getTime() === new Date(rightValue).getTime();
if (condition.leftOperand.type === "question") {
if (
(leftField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.Date &&
typeof leftValue === "string" &&
typeof rightValue === "string"
) {
// when left value is of date question and right value is string
return new Date(leftValue).getTime() === new Date(rightValue).getTime();
}
}
// when left value is of openText, hiddenField, variable and right value is of multichoice
if (condition.rightOperand?.type === "question") {
if (
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceSingle ||
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceMulti
) {
if (Array.isArray(condition.rightOperand.value)) {
return condition.rightOperand.value.includes(leftValue);
} else {
return leftValue === condition.rightOperand.value;
}
if ((rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceMulti) {
if (Array.isArray(rightValue) && typeof leftValue === "string" && rightValue.length === 1) {
return rightValue.includes(leftValue as string);
} else return false;
} else if (
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.Date &&
typeof leftValue === "string" &&
@@ -157,15 +142,10 @@ const evaluateSingleCondition = (
// when left value is of openText, hiddenField, variable and right value is of multichoice
if (condition.rightOperand?.type === "question") {
if (
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceSingle ||
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceMulti
) {
if (Array.isArray(condition.rightOperand.value)) {
return !condition.rightOperand.value.includes(leftValue);
} else {
return leftValue !== condition.rightOperand.value;
}
if ((rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceMulti) {
if (Array.isArray(rightValue) && typeof leftValue === "string" && rightValue.length === 1) {
return !rightValue.includes(leftValue as string);
} else return false;
} else if (
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.Date &&
typeof leftValue === "string" &&
@@ -281,6 +261,10 @@ const getLeftOperandValue = (
const responseValue = data[leftOperand.value];
if (currentQuestion.type === "openText" && currentQuestion.inputType === "number") {
return Number(responseValue) || 0;
}
if (currentQuestion.type === "multipleChoiceSingle" || currentQuestion.type === "multipleChoiceMulti") {
const isOthersEnabled = currentQuestion.choices.at(-1)?.id === "other";
@@ -357,7 +341,9 @@ const getRightOperandValue = (
if (variable.type === "number") return Number(variableValue) || 0;
return variableValue || "";
case "hiddenField":
return data[rightOperand.value];
return !isNaN(data[rightOperand.value] as number)
? Number(data[rightOperand.value])
: data[rightOperand.value];
case "static":
return rightOperand.value;
default:

View File

@@ -7,7 +7,7 @@ import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { replaceRecallInfo } from "@/lib/recall";
import { useEffect } from "preact/hooks";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
import { TResponseData } from "@formbricks/types/responses";
import { TResponseData, TResponseVariables } from "@formbricks/types/responses";
import { TSurvey, TSurveyEndScreenCard, TSurveyRedirectUrlCard } from "@formbricks/types/surveys/types";
interface EndingCardProps {
@@ -19,6 +19,7 @@ interface EndingCardProps {
isCurrent: boolean;
languageCode: string;
responseData: TResponseData;
variablesData: TResponseVariables;
}
export const EndingCard = ({
@@ -30,6 +31,7 @@ export const EndingCard = ({
isCurrent,
languageCode,
responseData,
variablesData,
}: EndingCardProps) => {
const media =
endingCard.type === "endScreen" && (endingCard.imageUrl || endingCard.videoUrl) ? (
@@ -99,7 +101,7 @@ export const EndingCard = ({
? replaceRecallInfo(
getLocalizedValue(endingCard.headline, languageCode),
responseData,
survey.variables
variablesData
)
: "Respondants will not see this card"
}
@@ -111,7 +113,7 @@ export const EndingCard = ({
? replaceRecallInfo(
getLocalizedValue(endingCard.subheader, languageCode),
responseData,
survey.variables
variablesData
)
: "They will be forwarded immediately"
}
@@ -123,7 +125,7 @@ export const EndingCard = ({
buttonLabel={replaceRecallInfo(
getLocalizedValue(endingCard.buttonLabel, languageCode),
responseData,
survey.variables
variablesData
)}
isLastQuestion={false}
focus={autoFocusEnabled}

View File

@@ -9,7 +9,7 @@ import { WelcomeCard } from "@/components/general/WelcomeCard";
import { AutoCloseWrapper } from "@/components/wrappers/AutoCloseWrapper";
import { StackedCardsContainer } from "@/components/wrappers/StackedCardsContainer";
import { evaluateAdvancedLogic, performActions } from "@/lib/logicEvaluator";
import { parseRecallInformation, replaceRecallInfo } from "@/lib/recall";
import { parseRecallInformation } from "@/lib/recall";
import { cn } from "@/lib/utils";
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
import { SurveyBaseProps } from "@formbricks/types/formbricks-surveys";
@@ -341,9 +341,9 @@ export const Survey = ({
languageCode={selectedLanguage}
responseCount={responseCount}
autoFocusEnabled={autoFocusEnabled}
replaceRecallInfo={replaceRecallInfo}
isCurrent={offset === 0}
responseData={responseData}
variablesData={currentVariables}
/>
);
} else if (questionIdx >= localSurvey.questions.length) {
@@ -361,6 +361,7 @@ export const Survey = ({
languageCode={selectedLanguage}
isResponseSendingFinished={isResponseSendingFinished}
responseData={responseData}
variablesData={currentVariables}
/>
);
}
@@ -371,12 +372,7 @@ export const Survey = ({
<QuestionConditional
key={question.id}
surveyId={localSurvey.id}
question={parseRecallInformation(
question,
selectedLanguage,
responseData,
localSurvey.variables
)}
question={parseRecallInformation(question, selectedLanguage, responseData, currentVariables)}
value={responseData[question.id]}
onChange={onChange}
onSubmit={onSubmit}

View File

@@ -1,10 +1,11 @@
import { SubmitButton } from "@/components/buttons/SubmitButton";
import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
import { replaceRecallInfo } from "@/lib/recall";
import { calculateElementIdx } from "@/lib/utils";
import { useEffect } from "preact/hooks";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
import { TResponseData, TResponseTtc } from "@formbricks/types/responses";
import { TI18nString, TSurvey, TSurveyVariables } from "@formbricks/types/surveys/types";
import { TResponseData, TResponseTtc, TResponseVariables } from "@formbricks/types/responses";
import { TI18nString, TSurvey } from "@formbricks/types/surveys/types";
import { Headline } from "./Headline";
import { HtmlBody } from "./HtmlBody";
@@ -18,9 +19,9 @@ interface WelcomeCardProps {
languageCode: string;
responseCount?: number;
autoFocusEnabled: boolean;
replaceRecallInfo: (text: string, responseData: TResponseData, variables: TSurveyVariables) => string;
isCurrent: boolean;
responseData: TResponseData;
variablesData: TResponseVariables;
}
const TimerIcon = () => {
@@ -70,9 +71,9 @@ export const WelcomeCard = ({
survey,
responseCount,
autoFocusEnabled,
replaceRecallInfo,
isCurrent,
responseData,
variablesData,
}: WelcomeCardProps) => {
const calculateTimeToComplete = () => {
let idx = calculateElementIdx(survey, 0);
@@ -145,16 +146,12 @@ export const WelcomeCard = ({
headline={replaceRecallInfo(
getLocalizedValue(headline, languageCode),
responseData,
survey.variables
variablesData
)}
questionId="welcomeCard"
/>
<HtmlBody
htmlString={replaceRecallInfo(
getLocalizedValue(html, languageCode),
responseData,
survey.variables
)}
htmlString={replaceRecallInfo(getLocalizedValue(html, languageCode), responseData, variablesData)}
questionId="welcomeCard"
/>
</div>

View File

@@ -85,38 +85,23 @@ const evaluateSingleCondition = (
switch (condition.operator) {
case "equals":
// when left value is of picture selection question and right value is its option
if (
condition.leftOperand.type === "question" &&
(leftField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.PictureSelection &&
Array.isArray(leftValue) &&
leftValue.length > 0 &&
typeof rightValue === "string"
) {
return leftValue.includes(rightValue);
}
// when left value is of date question and right value is string
if (
condition.leftOperand.type === "question" &&
(leftField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.Date &&
typeof leftValue === "string" &&
typeof rightValue === "string"
) {
return new Date(leftValue).getTime() === new Date(rightValue).getTime();
if (condition.leftOperand.type === "question") {
if (
(leftField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.Date &&
typeof leftValue === "string" &&
typeof rightValue === "string"
) {
// when left value is of date question and right value is string
return new Date(leftValue).getTime() === new Date(rightValue).getTime();
}
}
// when left value is of openText, hiddenField, variable and right value is of multichoice
if (condition.rightOperand?.type === "question") {
if (
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceSingle ||
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceMulti
) {
if (Array.isArray(condition.rightOperand.value)) {
return condition.rightOperand.value.includes(leftValue);
} else {
return leftValue === condition.rightOperand.value;
}
if ((rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceMulti) {
if (Array.isArray(rightValue) && typeof leftValue === "string" && rightValue.length === 1) {
return rightValue.includes(leftValue as string);
} else return false;
} else if (
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.Date &&
typeof leftValue === "string" &&
@@ -157,15 +142,10 @@ const evaluateSingleCondition = (
// when left value is of openText, hiddenField, variable and right value is of multichoice
if (condition.rightOperand?.type === "question") {
if (
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceSingle ||
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceMulti
) {
if (Array.isArray(condition.rightOperand.value)) {
return !condition.rightOperand.value.includes(leftValue);
} else {
return leftValue !== condition.rightOperand.value;
}
if ((rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.MultipleChoiceMulti) {
if (Array.isArray(rightValue) && typeof leftValue === "string" && rightValue.length === 1) {
return !rightValue.includes(leftValue as string);
} else return false;
} else if (
(rightField as TSurveyQuestion).type === TSurveyQuestionTypeEnum.Date &&
typeof leftValue === "string" &&
@@ -281,6 +261,10 @@ const getLeftOperandValue = (
const responseValue = data[leftOperand.value];
if (currentQuestion.type === "openText" && currentQuestion.inputType === "number") {
return Number(responseValue) || 0;
}
if (currentQuestion.type === "multipleChoiceSingle" || currentQuestion.type === "multipleChoiceMulti") {
const isOthersEnabled = currentQuestion.choices.at(-1)?.id === "other";
@@ -357,7 +341,9 @@ const getRightOperandValue = (
if (variable.type === "number") return Number(variableValue) || 0;
return variableValue || "";
case "hiddenField":
return data[rightOperand.value];
return !isNaN(data[rightOperand.value] as number)
? Number(data[rightOperand.value])
: data[rightOperand.value];
case "static":
return rightOperand.value;
default:

View File

@@ -2,13 +2,13 @@ import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
import { structuredClone } from "@formbricks/lib/pollyfills/structuredClone";
import { formatDateWithOrdinal, isValidDateString } from "@formbricks/lib/utils/datetime";
import { extractFallbackValue, extractId, extractRecallInfo } from "@formbricks/lib/utils/recall";
import { TResponseData } from "@formbricks/types/responses";
import { TSurveyQuestion, TSurveyVariables } from "@formbricks/types/surveys/types";
import { TResponseData, TResponseVariables } from "@formbricks/types/responses";
import { TSurveyQuestion } from "@formbricks/types/surveys/types";
export const replaceRecallInfo = (
text: string,
responseData: TResponseData,
variables: TSurveyVariables
variables: TResponseVariables
): string => {
let modifiedText = text;
@@ -23,9 +23,8 @@ export const replaceRecallInfo = (
let value: string | null = null;
// Fetching value from variables based on recallItemId
if (variables.length) {
const variable = variables.find((variable) => variable.id === recallItemId);
value = variable?.value?.toString() ?? fallback;
if (variables[recallItemId]) {
value = (variables[recallItemId] as string) ?? fallback;
}
// Fetching value from responseData or attributes based on recallItemId
@@ -53,7 +52,7 @@ export const parseRecallInformation = (
question: TSurveyQuestion,
languageCode: string,
responseData: TResponseData,
variables: TSurveyVariables
variables: TResponseVariables
) => {
const modifiedQuestion = structuredClone(question);
if (question.headline && question.headline[languageCode]?.includes("recall:")) {

View File

@@ -106,14 +106,19 @@ export const ZSingleCondition = z
if (val.rightOperand === undefined) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Conditional Logic: rightOperand is required for operator "${val.operator}"`,
message: `Conditional Logic: right operand is required for operator "${val.operator}"`,
path: ["rightOperand"],
});
} else if (val.rightOperand.type === "static" && val.rightOperand.value === "") {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Conditional Logic: right operand value cannot be empty for operator "${val.operator}"`,
});
}
} else if (val.rightOperand !== undefined) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Conditional Logic: rightOperand should not be present for operator "${val.operator}"`,
message: `Conditional Logic: right operand should not be present for operator "${val.operator}"`,
path: ["rightOperand"],
});
}

View File

@@ -1159,18 +1159,28 @@ const validateConditions = (
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
});
} else {
const validQuestionTypes = [
TSurveyQuestionTypeEnum.OpenText,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
TSurveyQuestionTypeEnum.MultipleChoiceMulti,
TSurveyQuestionTypeEnum.Rating,
TSurveyQuestionTypeEnum.NPS,
TSurveyQuestionTypeEnum.Date,
];
if (!validQuestionTypes.includes(question.type)) {
const validQuestionTypes = [TSurveyQuestionTypeEnum.OpenText];
if (question.inputType === "number") {
validQuestionTypes.push(...[TSurveyQuestionTypeEnum.Rating, TSurveyQuestionTypeEnum.NPS]);
}
if (["equals", "doesNotEqual"].includes(condition.operator)) {
if (question.inputType !== "number") {
validQuestionTypes.push(
...[
TSurveyQuestionTypeEnum.Date,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
TSurveyQuestionTypeEnum.MultipleChoiceMulti,
]
);
}
}
if (!validQuestionTypes.includes(ques.type)) {
issues.push({
code: z.ZodIssueCode.custom,
message: `Conditional Logic: Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
message: `Conditional Logic: Invalid question type "${ques.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
});
}
@@ -1467,11 +1477,15 @@ const validateConditions = (
const validQuestionTypes = [
TSurveyQuestionTypeEnum.OpenText,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
TSurveyQuestionTypeEnum.Rating,
TSurveyQuestionTypeEnum.NPS,
TSurveyQuestionTypeEnum.Date,
];
if (["equals", "doesNotEqual"].includes(operator)) {
validQuestionTypes.push(
TSurveyQuestionTypeEnum.MultipleChoiceMulti,
TSurveyQuestionTypeEnum.Date
);
}
if (!validQuestionTypes.includes(question.type)) {
issues.push({
code: z.ZodIssueCode.custom,
@@ -1547,12 +1561,15 @@ const validateConditions = (
const validQuestionTypes = [
TSurveyQuestionTypeEnum.OpenText,
TSurveyQuestionTypeEnum.MultipleChoiceSingle,
TSurveyQuestionTypeEnum.MultipleChoiceMulti,
TSurveyQuestionTypeEnum.Rating,
TSurveyQuestionTypeEnum.NPS,
TSurveyQuestionTypeEnum.Date,
];
if (["equals", "doesNotEqual"].includes(condition.operator)) {
validQuestionTypes.push(
TSurveyQuestionTypeEnum.MultipleChoiceMulti,
TSurveyQuestionTypeEnum.Date
);
}
if (!validQuestionTypes.includes(question.type)) {
issues.push({
code: z.ZodIssueCode.custom,
@@ -1571,6 +1588,12 @@ const validateConditions = (
message: `Conditional Logic: Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
});
} else if (variable.type !== "text") {
issues.push({
code: z.ZodIssueCode.custom,
message: `Conditional Logic: Variable type should be text in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
});
}
} else if (rightOperand?.type === "hiddenField") {
const fieldId = rightOperand.value;