diff --git a/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/LogicEditorActions.tsx b/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/LogicEditorActions.tsx
index 876281b45e..5705cf2144 100644
--- a/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/LogicEditorActions.tsx
+++ b/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/LogicEditorActions.tsx
@@ -4,6 +4,7 @@ import {
getActionTargetOptions,
getActionValueOptions,
getActionVariableOptions,
+ hasJumpToQuestionAction,
} from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/lib/utils";
import { createId } from "@paralleldrive/cuid2";
import { CopyIcon, CornerDownRightIcon, EllipsisVerticalIcon, PlusIcon, TrashIcon } from "lucide-react";
@@ -60,7 +61,11 @@ export function LogicEditorActions({
actionsClone.splice(actionIdx, 1);
break;
case "addBelow":
- actionsClone.splice(actionIdx + 1, 0, { id: createId(), objective: "jumpToQuestion", target: "" });
+ actionsClone.splice(actionIdx + 1, 0, {
+ id: createId(),
+ objective: hasJumpToQuestionAction(logicItem.actions) ? "requireAnswer" : "jumpToQuestion",
+ target: "",
+ });
break;
case "duplicate":
actionsClone.splice(actionIdx + 1, 0, { ...actionsClone[actionIdx], id: createId() });
@@ -88,6 +93,11 @@ export function LogicEditorActions({
handleActionsChange("update", actionIdx, actionBody);
};
+ const filteredObjectiveOptions = actionObjectiveOptions.filter(
+ (option) => option.value !== "jumpToQuestion"
+ );
+ const jumpToQuestionActionIdx = actions.findIndex((action) => action.objective === "jumpToQuestion");
+
return (
@@ -102,7 +112,11 @@ export function LogicEditorActions({
id={`action-${idx}-objective`}
key={`objective-${action.id}`}
showSearch={false}
- options={actionObjectiveOptions}
+ options={
+ jumpToQuestionActionIdx === -1 || idx === jumpToQuestionActionIdx
+ ? actionObjectiveOptions
+ : filteredObjectiveOptions
+ }
value={action.objective}
onChangeValue={(val: TActionObjective) => {
handleObjectiveChange(idx, val);
diff --git a/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/lib/utils.tsx b/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/lib/utils.tsx
index 3b66577942..639d4cb349 100644
--- a/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/lib/utils.tsx
+++ b/apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/lib/utils.tsx
@@ -13,6 +13,7 @@ import {
TSurvey,
TSurveyLogic,
TSurveyLogicAction,
+ TSurveyLogicActions,
TSurveyLogicConditionsOperator,
TSurveyQuestion,
TSurveyQuestionId,
@@ -147,6 +148,10 @@ export const actionObjectiveOptions: TComboboxOption[] = [
{ label: "environments.surveys.edit.jump_to_question", value: "jumpToQuestion" },
];
+export const hasJumpToQuestionAction = (actions: TSurveyLogicActions): boolean => {
+ return actions.some((action) => action.objective === "jumpToQuestion");
+};
+
const getQuestionOperatorOptions = (question: TSurveyQuestion): TComboboxOption[] => {
let options: TLogicRuleOption;
diff --git a/packages/types/surveys/types.ts b/packages/types/surveys/types.ts
index c1fefbc5a5..bec8f0c2cf 100644
--- a/packages/types/surveys/types.ts
+++ b/packages/types/surveys/types.ts
@@ -444,6 +444,8 @@ export type TSurveyLogicAction = z.infer;
const ZSurveyLogicActions = z.array(ZSurveyLogicAction);
+export type TSurveyLogicActions = z.infer;
+
export const ZSurveyLogic = z.object({
id: ZId,
conditions: ZConditionGroup,
@@ -2025,6 +2027,15 @@ const validateActions = (
return undefined;
});
+ const jumpToQuestionActions = actions.filter((action) => action.objective === "jumpToQuestion");
+ if (jumpToQuestionActions.length > 1) {
+ actionIssues.push({
+ code: z.ZodIssueCode.custom,
+ message: `Conditional Logic: Multiple jump actions are not allowed in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
+ path: ["questions", questionIndex, "logic"],
+ });
+ }
+
const filteredActionIssues = actionIssues.filter((issue): issue is ZodIssue => issue !== undefined);
return filteredActionIssues;
};