mirror of
https://github.com/formbricks/formbricks.git
synced 2026-01-30 10:49:55 -06:00
Fix Logic Jumps are not updated properly when questions are updated or deleted (#530)
* modified updateQuestion functio * added type defs * pnpm format * fix LogicEditor fields not updating properly --------- Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
committed by
GitHub
parent
83b94de977
commit
3f2ef3e776
@@ -82,6 +82,7 @@ export default function LogicEditor({
|
||||
cta: ["clicked", "skipped"],
|
||||
consent: ["skipped", "accepted"],
|
||||
};
|
||||
|
||||
const logicConditions: LogicConditions = {
|
||||
submitted: {
|
||||
label: "is submitted",
|
||||
@@ -201,10 +202,9 @@ export default function LogicEditor({
|
||||
};
|
||||
|
||||
const deleteLogic = (logicIdx: number) => {
|
||||
const newLogic = !question.logic
|
||||
? []
|
||||
: (question.logic as Logic[]).filter((_: any, idx: number) => idx !== logicIdx);
|
||||
updateQuestion(questionIdx, { logic: newLogic });
|
||||
const updatedLogic = !question.logic ? [] : JSON.parse(JSON.stringify(question.logic));
|
||||
updatedLogic.splice(logicIdx, 1);
|
||||
updateQuestion(questionIdx, { logic: updatedLogic });
|
||||
};
|
||||
|
||||
const truncate = (str: string, n: number) =>
|
||||
@@ -225,9 +225,7 @@ export default function LogicEditor({
|
||||
<BsArrowReturnRight className="h-4 w-4" />
|
||||
<p className="text-slate-700">If this answer</p>
|
||||
|
||||
<Select
|
||||
defaultValue={logic.condition}
|
||||
onValueChange={(e) => updateLogic(logicIdx, { condition: e })}>
|
||||
<Select value={logic.condition} onValueChange={(e) => updateLogic(logicIdx, { condition: e })}>
|
||||
<SelectTrigger className="min-w-fit flex-1">
|
||||
<SelectValue placeholder="Select condition" />
|
||||
</SelectTrigger>
|
||||
@@ -246,9 +244,7 @@ export default function LogicEditor({
|
||||
{logic.condition && logicConditions[logic.condition].values != null && (
|
||||
<div className="flex-1 basis-1/5">
|
||||
{!logicConditions[logic.condition].multiSelect ? (
|
||||
<Select
|
||||
defaultValue={logic.value}
|
||||
onValueChange={(e) => updateLogic(logicIdx, { value: e })}>
|
||||
<Select value={logic.value} onValueChange={(e) => updateLogic(logicIdx, { value: e })}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select match type" />
|
||||
</SelectTrigger>
|
||||
@@ -294,7 +290,7 @@ export default function LogicEditor({
|
||||
<p className="text-slate-700">skip to</p>
|
||||
|
||||
<Select
|
||||
defaultValue={logic.destination}
|
||||
value={logic.destination}
|
||||
onValueChange={(e) => updateLogic(logicIdx, { destination: e })}>
|
||||
<SelectTrigger className="w-fit overflow-hidden ">
|
||||
<SelectValue placeholder="Select question" />
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import AdvancedSettings from "@/app/environments/[environmentId]/surveys/[surveyId]/edit/AdvancedSettings";
|
||||
import { getQuestionTypeName } from "@/lib/questions";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { QuestionType, type Question } from "@formbricks/types/questions";
|
||||
import { QuestionType } from "@formbricks/types/questions";
|
||||
import type { Survey } from "@formbricks/types/surveys";
|
||||
import { Input, Label, Switch } from "@formbricks/ui";
|
||||
import {
|
||||
@@ -20,18 +21,16 @@ import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useState } from "react";
|
||||
import { Draggable } from "react-beautiful-dnd";
|
||||
import CTAQuestionForm from "./CTAQuestionForm";
|
||||
import ConsentQuestionForm from "./ConsentQuestionForm";
|
||||
import MultipleChoiceMultiForm from "./MultipleChoiceMultiForm";
|
||||
import MultipleChoiceSingleForm from "./MultipleChoiceSingleForm";
|
||||
import NPSQuestionForm from "./NPSQuestionForm";
|
||||
import OpenQuestionForm from "./OpenQuestionForm";
|
||||
import QuestionDropdown from "./QuestionMenu";
|
||||
import RatingQuestionForm from "./RatingQuestionForm";
|
||||
import ConsentQuestionForm from "./ConsentQuestionForm";
|
||||
import AdvancedSettings from "@/app/environments/[environmentId]/surveys/[surveyId]/edit/AdvancedSettings";
|
||||
|
||||
interface QuestionCardProps {
|
||||
localSurvey: Survey;
|
||||
question: Question;
|
||||
questionIdx: number;
|
||||
moveQuestion: (questionIndex: number, up: boolean) => void;
|
||||
updateQuestion: (questionIdx: number, updatedAttributes: any) => void;
|
||||
@@ -44,7 +43,6 @@ interface QuestionCardProps {
|
||||
|
||||
export default function QuestionCard({
|
||||
localSurvey,
|
||||
question,
|
||||
questionIdx,
|
||||
moveQuestion,
|
||||
updateQuestion,
|
||||
@@ -54,6 +52,7 @@ export default function QuestionCard({
|
||||
setActiveQuestionId,
|
||||
lastQuestion,
|
||||
}: QuestionCardProps) {
|
||||
const question = localSurvey.questions[questionIdx];
|
||||
const open = activeQuestionId === question.id;
|
||||
const [openAdvanced, setOpenAdvanced] = useState(question.logic && question.logic.length > 0);
|
||||
return (
|
||||
|
||||
@@ -32,35 +32,45 @@ export default function QuestionsView({
|
||||
}, {});
|
||||
}, []);
|
||||
|
||||
const handleQuestionLogicChange = (survey: Survey, compareId: string, updatedId: string): Survey => {
|
||||
survey.questions.forEach((question) => {
|
||||
if (!question.logic) return;
|
||||
question.logic.forEach((rule) => {
|
||||
if (rule.destination === compareId) {
|
||||
rule.destination = updatedId;
|
||||
}
|
||||
});
|
||||
});
|
||||
return survey;
|
||||
};
|
||||
|
||||
const updateQuestion = (questionIdx: number, updatedAttributes: any) => {
|
||||
const updatedSurvey = JSON.parse(JSON.stringify(localSurvey));
|
||||
updatedSurvey.questions[questionIdx] = {
|
||||
...updatedSurvey.questions[questionIdx],
|
||||
...updatedAttributes,
|
||||
};
|
||||
setLocalSurvey(updatedSurvey);
|
||||
let updatedSurvey = JSON.parse(JSON.stringify(localSurvey));
|
||||
if ("id" in updatedAttributes) {
|
||||
// if the survey whose id is to be changed is linked to logic of any other survey then changing it
|
||||
const initialQuestionId = updatedSurvey.questions[questionIdx].id;
|
||||
updatedSurvey = handleQuestionLogicChange(updatedSurvey, initialQuestionId, updatedAttributes.id);
|
||||
|
||||
// relink the question to internal Id
|
||||
internalQuestionIdMap[updatedAttributes.id] =
|
||||
internalQuestionIdMap[localSurvey.questions[questionIdx].id];
|
||||
delete internalQuestionIdMap[localSurvey.questions[questionIdx].id];
|
||||
setActiveQuestionId(updatedAttributes.id);
|
||||
}
|
||||
|
||||
updatedSurvey.questions[questionIdx] = {
|
||||
...updatedSurvey.questions[questionIdx],
|
||||
...updatedAttributes,
|
||||
};
|
||||
setLocalSurvey(updatedSurvey);
|
||||
};
|
||||
|
||||
const deleteQuestion = (questionIdx: number) => {
|
||||
const questionId = localSurvey.questions[questionIdx].id;
|
||||
const updatedSurvey: Survey = JSON.parse(JSON.stringify(localSurvey));
|
||||
let updatedSurvey: Survey = JSON.parse(JSON.stringify(localSurvey));
|
||||
updatedSurvey.questions.splice(questionIdx, 1);
|
||||
|
||||
updatedSurvey.questions.forEach((question) => {
|
||||
if (!question.logic) return;
|
||||
question.logic.forEach((rule) => {
|
||||
if (rule.destination === questionId) {
|
||||
rule.destination = "end";
|
||||
}
|
||||
});
|
||||
});
|
||||
updatedSurvey = handleQuestionLogicChange(updatedSurvey, questionId, "end");
|
||||
|
||||
setLocalSurvey(updatedSurvey);
|
||||
delete internalQuestionIdMap[questionId];
|
||||
@@ -141,7 +151,6 @@ export default function QuestionsView({
|
||||
<QuestionCard
|
||||
key={internalQuestionIdMap[question.id]}
|
||||
localSurvey={localSurvey}
|
||||
question={question}
|
||||
questionIdx={questionIdx}
|
||||
moveQuestion={moveQuestion}
|
||||
updateQuestion={updateQuestion}
|
||||
|
||||
Reference in New Issue
Block a user