changed left operand id -> value

This commit is contained in:
Piyush Gupta
2024-09-05 17:00:39 +05:30
parent 6ec0861c49
commit 97b04f9e43
12 changed files with 252 additions and 244 deletions

View File

@@ -10,8 +10,9 @@ import { CopyIcon, CornerDownRightIcon, MoreVerticalIcon, PlusIcon, TrashIcon }
import { getUpdatedActionBody } from "@formbricks/lib/survey/logic/utils";
import {
TAction,
TActionNumberVariableCalculateOperator,
TActionObjective,
TActionVariableCalculateOperator,
TActionTextVariableCalculateOperator,
TActionVariableValueType,
TSurveyAdvancedLogic,
ZAction,
@@ -98,7 +99,6 @@ export function AdvancedLogicEditorActions({
objective: val,
});
}}
// comboboxClasses="max-w-[200px]"
comboboxClasses="grow"
/>
<InputCombobox
@@ -115,8 +115,6 @@ export function AdvancedLogicEditorActions({
...(action.objective === "calculate" ? { variableId: val } : { target: val }),
});
}}
// comboboxClasses="grow min-w-[100px] max-w-[200px]"
comboboxClasses="grow"
/>
{action.objective === "calculate" && (
<>
@@ -127,13 +125,13 @@ export function AdvancedLogicEditorActions({
localSurvey.variables.find((v) => v.id === action.variableId)?.type
)}
value={action.operator}
onChangeValue={(val: TActionVariableCalculateOperator) => {
onChangeValue={(
val: TActionTextVariableCalculateOperator | TActionNumberVariableCalculateOperator
) => {
updateAction(idx, {
operator: val,
});
}}
// comboboxClasses="min-w-[100px] max-w-[200px]"
comboboxClasses="grow"
/>
<InputCombobox
key="value"
@@ -143,33 +141,27 @@ export function AdvancedLogicEditorActions({
inputProps={{
placeholder: "Value",
type: localSurvey.variables.find((v) => v.id === action.variableId)?.type || "text",
// value: action.value?.value ?? "",
// onChange: (e) => {
// let val: string | number = e.target.value;
// const variable = localSurvey.variables.find((v) => v.id === action.variableId);
// if (variable?.type === "number") {
// val = Number(val);
// }
// updateAction(idx, {
// value: {
// type: "static",
// value: val,
// },
// });
// },
}}
groupedOptions={getActionValueOptions(action.variableId, localSurvey, questionIdx)}
onChangeValue={(val: string, option) => {
updateAction(idx, {
value: {
type: option?.meta?.type as TActionVariableValueType,
value: val,
},
});
onChangeValue={(val: string | number, option) => {
const fieldType = option?.meta?.type as TActionVariableValueType;
if (fieldType !== "static") {
updateAction(idx, {
value: {
type: fieldType,
value: val as string,
},
});
} else if (fieldType === "static") {
updateAction(idx, {
value: {
type: fieldType,
value: val as string,
},
});
}
}}
// comboboxClasses="flex min-w-[100px] max-w-[200px]"
comboboxClasses="grow"
/>
</>
)}

View File

@@ -118,7 +118,7 @@ export function AdvancedLogicEditorConditions({
const handleQuestionChange = (condition: TSingleCondition, value: string, option?: TComboboxOption) => {
handleUpdateCondition(condition.id, {
leftOperand: {
id: value,
value,
type: option?.meta?.type as TDyanmicLogicField,
},
operator: "isSkipped",
@@ -206,7 +206,7 @@ export function AdvancedLogicEditorConditions({
handleAddConditionBelow(condition.id, {
id: createId(),
leftOperand: {
id: localSurvey.questions[questionIdx].id,
value: localSurvey.questions[questionIdx].id,
type: "question",
},
operator: "equals",
@@ -253,7 +253,7 @@ export function AdvancedLogicEditorConditions({
key="conditionValue"
showSearch={false}
groupedOptions={conditionValueOptions}
value={condition.leftOperand.id}
value={condition.leftOperand.value}
onChangeValue={(val: string, option) => {
handleQuestionChange(condition, val, option);
}}
@@ -299,7 +299,7 @@ export function AdvancedLogicEditorConditions({
handleAddConditionBelow(condition.id, {
id: createId(),
leftOperand: {
id: localSurvey.questions[questionIdx].id,
value: localSurvey.questions[questionIdx].id,
type: "question",
},
operator: "equals",

View File

@@ -45,8 +45,8 @@ export function ConditionalLogic({
{
id: createId(),
leftOperand: {
value: localSurvey.questions[questionIdx].id,
type: "question",
id: localSurvey.questions[questionIdx].id,
},
operator: "isSkipped",
},

View File

@@ -102,8 +102,8 @@ export const QuestionsView = ({
const updateSingleCondition = (condition: TSingleCondition): TSingleCondition => {
let updatedCondition = { ...condition };
if (condition.leftOperand.id === compareId) {
updatedCondition.leftOperand = { ...condition.leftOperand, id: updatedId };
if (condition.leftOperand.value === compareId) {
updatedCondition.leftOperand = { ...condition.leftOperand, value: updatedId };
}
if (condition.rightOperand?.type === "question" && condition.rightOperand.value === compareId) {

View File

@@ -152,13 +152,14 @@ export const getConditionOperatorOptions = (
if (condition.leftOperand.type === "variable") {
const variables = localSurvey.variables || [];
const variableType =
variables.find((variable) => variable.id === condition.leftOperand.id)?.type || "text";
variables.find((variable) => variable.id === condition.leftOperand.value)?.type || "text";
return ruleEngine.variable[variableType].options;
} else if (condition.leftOperand.type === "hiddenField") {
return ruleEngine.hiddenField.options;
} else if (condition.leftOperand.type === "question") {
const questions = localSurvey.questions || [];
const question = questions.find((question) => question.id === condition.leftOperand.id) || questions[0];
const question =
questions.find((question) => question.id === condition.leftOperand.value) || questions[0];
if (question.type === "openText") {
const inputType = question.inputType === "number" ? "number" : "text";
return ruleEngine.question.openText[inputType].options;
@@ -195,15 +196,15 @@ export const getMatchValueProps = (
let variables = localSurvey.variables || [];
let hiddenFields = localSurvey.hiddenFields?.fieldIds || [];
const selectedQuestion = questions.find((question) => question.id === condition.leftOperand.id);
const selectedVariable = variables.find((variable) => variable.id === condition.leftOperand.id);
const selectedQuestion = questions.find((question) => question.id === condition.leftOperand.value);
const selectedVariable = variables.find((variable) => variable.id === condition.leftOperand.value);
if (condition.leftOperand.type === "question") {
questions = questions.filter((question) => question.id !== condition.leftOperand.id);
questions = questions.filter((question) => question.id !== condition.leftOperand.value);
} else if (condition.leftOperand.type === "variable") {
variables = variables.filter((variable) => variable.id !== condition.leftOperand.id);
variables = variables.filter((variable) => variable.id !== condition.leftOperand.value);
} else if (condition.leftOperand.type === "hiddenField") {
hiddenFields = hiddenFields.filter((field) => field !== condition.leftOperand.id);
hiddenFields = hiddenFields.filter((field) => field !== condition.leftOperand.value);
}
if (condition.leftOperand.type === "question") {
@@ -971,7 +972,7 @@ export const findQuestionUsedInLogic = (survey: TSurvey, questionId: string): nu
};
const isUsedInLeftOperand = (leftOperand: TLeftOperand, id: string): boolean => {
return leftOperand.type === "question" && leftOperand.id === id;
return leftOperand.type === "question" && leftOperand.value === id;
};
const isUsedInRightOperand = (rightOperand: TRightOperand, id: string): boolean => {
@@ -1006,7 +1007,7 @@ export const findOptionUsedInLogic = (survey: TSurvey, questionId: string, optio
};
const isUsedInOperand = (condition: TSingleCondition): boolean => {
if (condition.leftOperand.type === "question" && condition.leftOperand.id === questionId) {
if (condition.leftOperand.type === "question" && condition.leftOperand.value === questionId) {
if (condition.rightOperand && condition.rightOperand.type === "static") {
if (Array.isArray(condition.rightOperand.value)) {
return condition.rightOperand.value.includes(optionId);
@@ -1040,7 +1041,7 @@ export const findVariableUsedInLogic = (survey: TSurvey, variableId: string): nu
};
const isUsedInLeftOperand = (leftOperand: TLeftOperand): boolean => {
return leftOperand.type === "variable" && leftOperand.id === variableId;
return leftOperand.type === "variable" && leftOperand.value === variableId;
};
const isUsedInRightOperand = (rightOperand: TRightOperand): boolean => {
@@ -1073,7 +1074,7 @@ export const findHiddenFieldUsedInLogic = (survey: TSurvey, hiddenFieldId: strin
};
const isUsedInLeftOperand = (leftOperand: TLeftOperand): boolean => {
return leftOperand.type === "hiddenField" && leftOperand.id === hiddenFieldId;
return leftOperand.type === "hiddenField" && leftOperand.value === hiddenFieldId;
};
const isUsedInRightOperand = (rightOperand: TRightOperand): boolean => {

View File

@@ -152,7 +152,7 @@ function convertLogicCondition(
id: createId(),
leftOperand: {
type: "question",
id: question.id,
value: question.id,
},
operator,
...(doesRightOperandExistResult ? { rightOperand: rightOperandValue } : {}),

View File

@@ -79,7 +79,7 @@ const cartAbandonmentSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isSkipped",
@@ -196,7 +196,7 @@ const cartAbandonmentSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSkipped",
@@ -268,7 +268,7 @@ const siteAbandonmentSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isSkipped",
@@ -385,7 +385,7 @@ const siteAbandonmentSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSkipped",
@@ -457,7 +457,7 @@ const productMarketFitSuperhuman = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isSkipped",
@@ -692,7 +692,7 @@ const churnSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -720,7 +720,7 @@ const churnSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -748,7 +748,7 @@ const churnSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -776,7 +776,7 @@ const churnSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -804,7 +804,7 @@ const churnSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -848,7 +848,7 @@ const churnSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -886,7 +886,7 @@ const churnSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "isClicked",
@@ -922,7 +922,7 @@ const churnSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[3],
value: reusableQuestionIds[3],
type: "question",
},
operator: "isSubmitted",
@@ -959,7 +959,7 @@ const churnSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[4],
value: reusableQuestionIds[4],
type: "question",
},
operator: "isClicked",
@@ -1015,7 +1015,7 @@ const earnedAdvocacyScore = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -1056,8 +1056,8 @@ const earnedAdvocacyScore = (): TTemplate => {
{
id: createId(),
leftOperand: {
value: reusableQuestionIds[1],
type: "question",
id: reusableQuestionIds[1],
},
operator: "isSubmitted",
},
@@ -1098,8 +1098,8 @@ const earnedAdvocacyScore = (): TTemplate => {
{
id: createId(),
leftOperand: {
value: reusableQuestionIds[3],
type: "question",
id: reusableQuestionIds[3],
},
operator: "equals",
rightOperand: {
@@ -1175,7 +1175,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -1203,7 +1203,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -1231,7 +1231,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -1259,7 +1259,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -1287,7 +1287,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -1331,7 +1331,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -1365,7 +1365,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "isSubmitted",
@@ -1403,7 +1403,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[3],
value: reusableQuestionIds[3],
type: "question",
},
operator: "isClicked",
@@ -1439,7 +1439,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[4],
value: reusableQuestionIds[4],
type: "question",
},
operator: "isSubmitted",
@@ -1474,7 +1474,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[5],
value: reusableQuestionIds[5],
type: "question",
},
operator: "isSubmitted",
@@ -1498,7 +1498,7 @@ const improveTrialConversion = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[5],
value: reusableQuestionIds[5],
type: "question",
},
operator: "isSkipped",
@@ -1550,7 +1550,7 @@ const reviewPrompt = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isLessThanOrEqual",
@@ -1592,7 +1592,7 @@ const reviewPrompt = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isClicked",
@@ -1683,7 +1683,7 @@ const improveActivationRate = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -1711,7 +1711,7 @@ const improveActivationRate = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -1739,7 +1739,7 @@ const improveActivationRate = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -1767,7 +1767,7 @@ const improveActivationRate = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -1812,7 +1812,7 @@ const improveActivationRate = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -1846,7 +1846,7 @@ const improveActivationRate = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "isSubmitted",
@@ -1880,7 +1880,7 @@ const improveActivationRate = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[3],
value: reusableQuestionIds[3],
type: "question",
},
operator: "isSubmitted",
@@ -1914,7 +1914,7 @@ const improveActivationRate = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[4],
value: reusableQuestionIds[4],
type: "question",
},
operator: "isSubmitted",
@@ -2323,7 +2323,7 @@ const feedbackBox = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -2351,7 +2351,7 @@ const feedbackBox = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -2392,7 +2392,7 @@ const feedbackBox = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -2430,7 +2430,7 @@ const feedbackBox = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "isClicked",
@@ -2454,7 +2454,7 @@ const feedbackBox = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "isSkipped",
@@ -2517,7 +2517,7 @@ const integrationSetupSurvey = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isGreaterThanOrEqual",
@@ -2716,7 +2716,7 @@ const customerSatisfactionScore = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isLessThanOrEqual",
@@ -2757,7 +2757,7 @@ const customerSatisfactionScore = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -2824,7 +2824,7 @@ const collectFeedback = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isLessThanOrEqual",
@@ -2866,7 +2866,7 @@ const collectFeedback = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -3187,7 +3187,7 @@ const rateCheckoutExperience = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isGreaterThanOrEqual",
@@ -3228,7 +3228,7 @@ const rateCheckoutExperience = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -3288,7 +3288,7 @@ const measureSearchExperience = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isGreaterThanOrEqual",
@@ -3329,7 +3329,7 @@ const measureSearchExperience = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -3389,7 +3389,7 @@ const evaluateContentQuality = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isGreaterThanOrEqual",
@@ -3430,7 +3430,7 @@ const evaluateContentQuality = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -3492,7 +3492,7 @@ const measureTaskAccomplishment = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -3520,7 +3520,7 @@ const measureTaskAccomplishment = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -3548,7 +3548,7 @@ const measureTaskAccomplishment = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -3589,7 +3589,7 @@ const measureTaskAccomplishment = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isGreaterThanOrEqual",
@@ -3630,7 +3630,7 @@ const measureTaskAccomplishment = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "isSubmitted",
@@ -3638,7 +3638,7 @@ const measureTaskAccomplishment = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSkipped",
@@ -3672,7 +3672,7 @@ const measureTaskAccomplishment = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[3],
value: reusableQuestionIds[3],
type: "question",
},
operator: "isSubmitted",
@@ -3680,7 +3680,7 @@ const measureTaskAccomplishment = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSkipped",
@@ -3757,7 +3757,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isSkipped",
@@ -3792,7 +3792,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "equals",
@@ -3834,7 +3834,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "equals",
@@ -3862,7 +3862,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "equals",
@@ -3890,7 +3890,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "equals",
@@ -3918,7 +3918,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "equals",
@@ -3946,7 +3946,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "equals",
@@ -3989,7 +3989,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[3],
value: reusableQuestionIds[3],
type: "question",
},
operator: "isSubmitted",
@@ -4023,7 +4023,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[4],
value: reusableQuestionIds[4],
type: "question",
},
operator: "isSubmitted",
@@ -4057,7 +4057,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[5],
value: reusableQuestionIds[5],
type: "question",
},
operator: "isSubmitted",
@@ -4091,7 +4091,7 @@ const identifySignUpBarriers = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[6],
value: reusableQuestionIds[6],
type: "question",
},
operator: "isSubmitted",
@@ -4203,7 +4203,7 @@ const understandPurchaseIntention = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isLessThanOrEqual",
@@ -4231,7 +4231,7 @@ const understandPurchaseIntention = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -4259,7 +4259,7 @@ const understandPurchaseIntention = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -4287,7 +4287,7 @@ const understandPurchaseIntention = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -4328,7 +4328,7 @@ const understandPurchaseIntention = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -4336,7 +4336,7 @@ const understandPurchaseIntention = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSkipped",
@@ -4396,7 +4396,7 @@ const improveNewsletterContent = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -4424,7 +4424,7 @@ const improveNewsletterContent = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "isLessThan",
@@ -4465,7 +4465,7 @@ const improveNewsletterContent = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -4473,7 +4473,7 @@ const improveNewsletterContent = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSkipped",
@@ -4563,7 +4563,7 @@ const evaluateAProductIdea = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isLessThanOrEqual",
@@ -4591,7 +4591,7 @@ const evaluateAProductIdea = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isGreaterThanOrEqual",
@@ -4654,7 +4654,7 @@ const evaluateAProductIdea = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[4],
value: reusableQuestionIds[4],
type: "question",
},
operator: "isLessThanOrEqual",
@@ -4682,7 +4682,7 @@ const evaluateAProductIdea = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[4],
value: reusableQuestionIds[4],
type: "question",
},
operator: "isGreaterThanOrEqual",
@@ -4723,7 +4723,7 @@ const evaluateAProductIdea = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[5],
value: reusableQuestionIds[5],
type: "question",
},
operator: "isSubmitted",
@@ -4794,7 +4794,7 @@ const understandLowEngagement = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -4822,7 +4822,7 @@ const understandLowEngagement = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -4850,7 +4850,7 @@ const understandLowEngagement = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -4878,7 +4878,7 @@ const understandLowEngagement = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -4906,7 +4906,7 @@ const understandLowEngagement = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[0],
value: reusableQuestionIds[0],
type: "question",
},
operator: "equals",
@@ -4949,7 +4949,7 @@ const understandLowEngagement = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[1],
value: reusableQuestionIds[1],
type: "question",
},
operator: "isSubmitted",
@@ -4983,7 +4983,7 @@ const understandLowEngagement = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[2],
value: reusableQuestionIds[2],
type: "question",
},
operator: "isSubmitted",
@@ -5017,7 +5017,7 @@ const understandLowEngagement = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[3],
value: reusableQuestionIds[3],
type: "question",
},
operator: "isSubmitted",
@@ -5051,7 +5051,7 @@ const understandLowEngagement = (): TTemplate => {
{
id: createId(),
leftOperand: {
id: reusableQuestionIds[4],
value: reusableQuestionIds[4],
type: "question",
},
operator: "isSubmitted",

View File

@@ -128,10 +128,10 @@ const getLeftOperandValue = (
) => {
switch (leftOperand.type) {
case "question":
const currentQuestion = localSurvey.questions.find((q) => q.id === leftOperand.id);
const currentQuestion = localSurvey.questions.find((q) => q.id === leftOperand.value);
if (!currentQuestion) return undefined;
const responseValue = data[leftOperand.id];
const responseValue = data[leftOperand.value];
if (currentQuestion.type === "multipleChoiceSingle" || currentQuestion.type === "multipleChoiceMulti") {
let choice;
@@ -156,19 +156,19 @@ const getLeftOperandValue = (
return choice;
}
}
return data[leftOperand.id];
return data[leftOperand.value];
case "variable":
const variables = localSurvey.variables || [];
const variable = variables.find((v) => v.id === leftOperand.id);
const variable = variables.find((v) => v.id === leftOperand.value);
if (!variable) return undefined;
const variableValue = data[leftOperand.id];
const variableValue = data[leftOperand.value];
if (variable.type === "number") return Number(variableValue) || 0;
return variableValue || "";
case "hiddenField":
return data[leftOperand.id];
return data[leftOperand.value];
default:
return undefined;
}

View File

@@ -222,7 +222,7 @@ export const Survey = ({
if (currQuesTemp.logic && currQuesTemp.logic.length > 0) {
for (const logic of currQuesTemp.logic) {
if (evaluateAdvancedLogic(localSurvey, data, logic.conditions, selectedLanguage)) {
if (evaluateAdvancedLogic(localSurvey, data, currentVariables, logic.conditions, selectedLanguage)) {
const { jumpTarget, requiredQuestionIds, calculations } = performActions(
localSurvey,
logic.actions,

View File

@@ -17,6 +17,7 @@ import {
export const evaluateAdvancedLogic = (
localSurvey: TSurvey,
data: TResponseData,
variablesData: TResponseVariables,
conditions: TConditionGroup,
selectedLanguage: string
): boolean => {
@@ -25,7 +26,7 @@ export const evaluateAdvancedLogic = (
if (isConditionsGroup(condition)) {
return evaluateConditionGroup(condition);
} else {
return evaluateSingleCondition(localSurvey, data, condition, selectedLanguage);
return evaluateSingleCondition(localSurvey, data, variablesData, condition, selectedLanguage);
}
});
@@ -38,25 +39,32 @@ export const evaluateAdvancedLogic = (
const evaluateSingleCondition = (
localSurvey: TSurvey,
data: TResponseData,
variablesData: TResponseVariables,
condition: TSingleCondition,
selectedLanguage: string
): boolean => {
const leftValue = getLeftOperandValue(localSurvey, data, condition.leftOperand, selectedLanguage);
const leftValue = getLeftOperandValue(
localSurvey,
data,
variablesData,
condition.leftOperand,
selectedLanguage
);
const rightValue = condition.rightOperand
? getRightOperandValue(localSurvey, condition.rightOperand, data)
? getRightOperandValue(localSurvey, data, variablesData, condition.rightOperand)
: undefined;
let leftField: TSurveyQuestion | TSurveyVariable | string;
switch (condition.leftOperand.type) {
case "question":
leftField = localSurvey.questions.find((q) => q.id === condition.leftOperand.id) as TSurveyQuestion;
leftField = localSurvey.questions.find((q) => q.id === condition.leftOperand.value) as TSurveyQuestion;
break;
case "variable":
leftField = localSurvey.variables.find((v) => v.id === condition.leftOperand.id) as TSurveyVariable;
leftField = localSurvey.variables.find((v) => v.id === condition.leftOperand.value) as TSurveyVariable;
break;
case "hiddenField":
leftField = condition.leftOperand.id as string;
leftField = condition.leftOperand.value as string;
break;
default:
leftField = "";
@@ -158,15 +166,16 @@ const evaluateSingleCondition = (
const getLeftOperandValue = (
localSurvey: TSurvey,
data: TResponseData,
variablesData: TResponseVariables,
leftOperand: TSingleCondition["leftOperand"],
selectedLanguage: string
) => {
switch (leftOperand.type) {
case "question":
const currentQuestion = localSurvey.questions.find((q) => q.id === leftOperand.id);
const currentQuestion = localSurvey.questions.find((q) => q.id === leftOperand.value);
if (!currentQuestion) return undefined;
const responseValue = data[leftOperand.id];
const responseValue = data[leftOperand.value];
if (currentQuestion.type === "multipleChoiceSingle" || currentQuestion.type === "multipleChoiceMulti") {
let choice;
@@ -191,19 +200,19 @@ const getLeftOperandValue = (
return choice;
}
}
return data[leftOperand.id];
return data[leftOperand.value];
case "variable":
const variables = localSurvey.variables || [];
const variable = variables.find((v) => v.id === leftOperand.id);
const variable = variables.find((v) => v.id === leftOperand.value);
if (!variable) return undefined;
const variableValue = data[leftOperand.id];
const variableValue = variablesData[leftOperand.value];
if (variable.type === "number") return Number(variableValue) || 0;
return variableValue || "";
case "hiddenField":
return data[leftOperand.id];
return data[leftOperand.value];
default:
return undefined;
}
@@ -211,8 +220,9 @@ const getLeftOperandValue = (
const getRightOperandValue = (
localSurvey: TSurvey,
rightOperand: TSingleCondition["rightOperand"],
data: TResponseData
data: TResponseData,
variablesData: TResponseVariables,
rightOperand: TSingleCondition["rightOperand"]
) => {
if (!rightOperand) return undefined;
@@ -225,7 +235,7 @@ const getRightOperandValue = (
if (!variable) return undefined;
const variableValue = data[rightOperand.value];
const variableValue = variablesData[rightOperand.value];
if (variable.type === "number") return Number(variableValue) || 0;
return variableValue || "";

View File

@@ -323,51 +323,40 @@ export const ZActionNumberVariableCalculateOperator = z.enum([
"divide",
"assign",
]);
export const ZActionVariableCalculateOperator = z.union([
ZActionTextVariableCalculateOperator,
ZActionNumberVariableCalculateOperator,
]);
const ZDynamicQuestion = z.object({
type: z.literal("question"),
value: z.string(),
});
const ZDynamicVariable = z.object({
type: z.literal("variable"),
value: z.string().cuid2(),
});
const ZDynamicHiddenField = z.object({
type: z.literal("hiddenField"),
value: z.string(),
});
const ZDynamicLogicFieldValue = z.union([ZDynamicQuestion, ZDynamicVariable, ZDynamicHiddenField]);
export type TSurveyLogicCondition = z.infer<typeof ZSurveyLogicCondition>;
export type TDyanmicLogicField = z.infer<typeof ZDyanmicLogicField>;
export type TActionObjective = z.infer<typeof ZActionObjective>;
export type TActionTextVariableCalculateOperator = z.infer<typeof ZActionTextVariableCalculateOperator>;
export type TActionNumberVariableCalculateOperator = z.infer<typeof ZActionNumberVariableCalculateOperator>;
export type TActionVariableCalculateOperator = z.infer<typeof ZActionVariableCalculateOperator>;
// Conditions
const ZLeftOperandBase = z.object({
type: ZDyanmicLogicField,
id: z.string(),
});
const ZLeftOperandVariable = ZLeftOperandBase.extend({
type: z.literal("variable"),
id: z.string().cuid2(),
});
export const ZLeftOperand = z.union([ZLeftOperandBase, ZLeftOperandVariable]);
const ZLeftOperand = ZDynamicLogicFieldValue;
export type TLeftOperand = z.infer<typeof ZLeftOperand>;
export const ZRightOperand = z.discriminatedUnion("type", [
z.object({
type: z.literal("static"),
value: z.union([z.string(), z.number(), z.array(z.string())]),
}),
z.object({
type: z.literal("question"),
value: z.string(),
}),
z.object({
type: z.literal("variable"),
value: z.string().cuid2(),
}),
z.object({
type: z.literal("hiddenField"),
value: z.string(),
}),
]);
export const ZRightOperandStatic = z.object({
type: z.literal("static"),
value: z.union([z.string(), z.number(), z.array(z.string())]),
});
export const ZRightOperand = z.union([ZRightOperandStatic, ZDynamicLogicFieldValue]);
export type TRightOperand = z.infer<typeof ZRightOperand>;
export const ZSingleCondition = z
@@ -410,27 +399,46 @@ const ZActionBase = z.object({
export type TActionBase = z.infer<typeof ZActionBase>;
const ZActionCalculate = ZActionBase.extend({
const ZActionCalculateBase = ZActionBase.extend({
objective: z.literal("calculate"),
variableId: z.string(),
operator: ZActionVariableCalculateOperator,
value: z.object({
type: z.union([z.literal("static"), ZDyanmicLogicField]),
value: z.union([z.string(), z.number()]),
}),
});
const ZActionCalculateText = ZActionCalculateBase.extend({
operator: ZActionTextVariableCalculateOperator,
value: z.union([
z.object({
type: z.literal("static"),
value: z.string(),
}),
ZDynamicLogicFieldValue,
]),
});
const ZActionCalculateNumber = ZActionCalculateBase.extend({
operator: ZActionNumberVariableCalculateOperator,
value: z.union([
z.object({
type: z.literal("static"),
value: z.number(),
}),
ZDynamicLogicFieldValue,
]),
});
const ZActionCalculate = z.union([ZActionCalculateText, ZActionCalculateNumber]);
export type TActionCalculate = z.infer<typeof ZActionCalculate>;
const ZActionRequireAnswer = ZActionBase.extend({
objective: z.literal("requireAnswer"),
target: z.string(),
target: z.string().min(1, "Target question id cannot be empty"),
});
export type TActionRequireAnswer = z.infer<typeof ZActionRequireAnswer>;
const ZActionJumpToQuestion = ZActionBase.extend({
objective: z.literal("jumpToQuestion"),
target: z.string(),
target: z.string().min(1, "Target question id cannot be empty"),
});
export type TActionJumpToQuestion = z.infer<typeof ZActionJumpToQuestion>;

View File

@@ -827,40 +827,32 @@ export const ZSurvey = z
}
}
// if (question.logic) {
// question.logic.forEach((logic, logicIndex) => {
// const logicConditions = ["condition", "value", "destination"] as const;
// const validFields = logicConditions.filter((field) => logic[field] !== undefined).length;
// if (question.logic) {
// question.logic.forEach((logic, logicIndex) => {
// // validate condition
// // validate actions
// if (validFields < 2) {
// ctx.addIssue({
// code: z.ZodIssueCode.custom,
// message: `Logic for question ${String(questionIndex + 1)} is missing required fields`,
// path: ["questions", questionIndex, "logic"],
// });
// }
// if (question.required && logic.condition === "skipped") {
// ctx.addIssue({
// code: z.ZodIssueCode.custom,
// message: `Logic for question ${String(questionIndex + 1)} is invalid. Required questions cannot be skipped.`,
// path: ["questions", questionIndex, "logic"],
// });
// }
// // logic condition and value mapping should not be repeated
// const thisLogic = `${logic.condition ?? ""}-${Array.isArray(logic.value) ? logic.value.sort().join(",") : String(logic.value)}`;
// if (existingLogicConditions.has(thisLogic)) {
// ctx.addIssue({
// code: z.ZodIssueCode.custom,
// message:
// "There are two competing logic conditions: Please update or delete one in the Questions tab.",
// path: ["questions", questionIndex, "logic", logicIndex],
// });
// }
// existingLogicConditions.add(thisLogic);
// });
// }
// // if (
// // [
// // "isSubmitted",
// // "isSkipped",
// // "isClicked",
// // "isAccepted",
// // "isBooked",
// // "isPartiallySubmitted",
// // "isCompletelySubmitted",
// // ].includes(condition.operator) &&
// // condition.rightOperand !== undefined
// // ) {
// // ctx.addIssue({
// // code: z.ZodIssueCode.custom,
// // message: `${messagePrefix}${messageField} in question ${String(questionIndex + 1)}${messageSuffix}`,
// // path: ["questions", questionIndex, field],
// // params: isDefaultOnly ? undefined : { invalidLanguageCodes },
// // })
// // }
// });
// }
});
const questionsWithCyclicLogic = findQuestionsWithCyclicLogic(questions);
@@ -874,6 +866,7 @@ export const ZSurvey = z
});
});
}
endings.forEach((ending, index) => {
// thank you card validations
if (ending.type === "endScreen") {
@@ -928,6 +921,10 @@ export const ZSurvey = z
});
});
// const validateActions = (actions: TAction[], ctx: z.RefinementCtx) => {
// // check if
// };
// ZSurvey is a refinement, so to extend it to ZSurveyUpdateInput, we need to transform the innerType and then apply the same refinements.
export const ZSurveyUpdateInput = ZSurvey.innerType()
.omit({ createdAt: true, updatedAt: true })