fixes coderabbit feedback

This commit is contained in:
pandeymangg
2025-11-05 10:26:20 +05:30
parent c618e7d473
commit 53a9b218bc
17 changed files with 74 additions and 38 deletions

View File

@@ -3603,7 +3603,7 @@ export const customSurveyTemplate = (t: TFunction): TTemplate => {
blocks: [
{
id: createId(),
name: "Block 1",
name: t("templates.custom_survey_block_1_name"),
elements: [
{
id: createId(),

View File

@@ -1352,7 +1352,6 @@ checksums:
environments/surveys/edit/is_skipped: 9fb90b6578f603cca37d4e6c912bb401
environments/surveys/edit/is_submitted: 13e774a97ad5f5609555e6f99514e70f
environments/surveys/edit/italic: 555c60fb1d12ae305136202afa6deb3d
environments/surveys/edit/jump_to_block: 2fc00bd725c44f98861051c57bb2c392
environments/surveys/edit/jump_to_question: 742aabed8845190825418aa429f01b2d
environments/surveys/edit/keep_current_order: a7c944ad6b3515f2c4f83a2c81f8fc26
environments/surveys/edit/keep_showing_while_conditions_match: 2574802d87bd6da151c9145aacce7281

View File

@@ -2248,6 +2248,7 @@
"csat_survey_question_3_headline": "Ugh, sorry! Können wir irgendwas tun, um deine Erfahrung zu verbessern?",
"csat_survey_question_3_placeholder": "Tippe deine Antwort hier...",
"cta_description": "Information anzeigen und Benutzer auffordern, eine bestimmte Aktion auszuführen",
"custom_survey_block_1_name": "Block 1",
"custom_survey_description": "Erstelle eine Umfrage ohne Vorlage.",
"custom_survey_name": "Eigene Umfrage erstellen",
"custom_survey_question_1_headline": "Was möchtest Du wissen?",

View File

@@ -2248,6 +2248,7 @@
"csat_survey_question_3_headline": "Ugh, sorry! Is there anything we can do to improve your experience?",
"csat_survey_question_3_placeholder": "Type your answer here...",
"cta_description": "Display information and prompt users to take a specific action",
"custom_survey_block_1_name": "Block 1",
"custom_survey_description": "Create a survey without template.",
"custom_survey_name": "Start from scratch",
"custom_survey_question_1_headline": "What would you like to know?",

View File

@@ -2248,6 +2248,7 @@
"csat_survey_question_3_headline": "Ah, désolé ! Y a-t-il quelque chose que nous puissions faire pour améliorer votre expérience ?",
"csat_survey_question_3_placeholder": "Entrez votre réponse ici...",
"cta_description": "Afficher des informations et inciter les utilisateurs à effectuer une action spécifique",
"custom_survey_block_1_name": "Bloc 1",
"custom_survey_description": "Créez une enquête sans utiliser de modèle.",
"custom_survey_name": "Tout créer moi-même",
"custom_survey_question_1_headline": "Que voudriez-vous savoir ?",

View File

@@ -2248,6 +2248,7 @@
"csat_survey_question_3_headline": "申し訳ありません!体験を改善するために何かできることはありますか?",
"csat_survey_question_3_placeholder": "ここに回答を入力してください...",
"cta_description": "情報を表示し、特定の行動を促す",
"custom_survey_block_1_name": "ブロック1",
"custom_survey_description": "テンプレートを使わずにアンケートを作成する。",
"custom_survey_name": "最初から始める",
"custom_survey_question_1_headline": "何を知りたいですか?",

View File

@@ -2248,6 +2248,7 @@
"csat_survey_question_3_headline": "Ah, foi mal! Tem algo que a gente possa fazer pra melhorar sua experiência?",
"csat_survey_question_3_placeholder": "Digite sua resposta aqui...",
"cta_description": "Mostrar informações e pedir para os usuários tomarem uma ação específica",
"custom_survey_block_1_name": "Bloco 1",
"custom_survey_description": "Crie uma pesquisa sem modelo.",
"custom_survey_name": "Começar do zero",
"custom_survey_question_1_headline": "O que você gostaria de saber?",

View File

@@ -2248,6 +2248,7 @@
"csat_survey_question_3_headline": "Oh, desculpe! Há algo que possamos fazer para melhorar a sua experiência?",
"csat_survey_question_3_placeholder": "Escreva a sua resposta aqui...",
"cta_description": "Exibir informações e solicitar aos utilizadores que tomem uma ação específica",
"custom_survey_block_1_name": "Bloco 1",
"custom_survey_description": "Crie um inquérito sem modelo.",
"custom_survey_name": "Começar do zero",
"custom_survey_question_1_headline": "O que gostaria de saber?",

View File

@@ -2248,6 +2248,7 @@
"csat_survey_question_3_headline": "Of, îmi pare rău! Există ceva ce putem face pentru a-ți îmbunătăți experiența?",
"csat_survey_question_3_placeholder": "Tastează răspunsul aici...",
"cta_description": "Afișează informații și solicită utilizatorilor să ia o acțiune specifică",
"custom_survey_block_1_name": "Bloc 1",
"custom_survey_description": "Creează un sondaj fără șablon.",
"custom_survey_name": "Începe de la zero",
"custom_survey_question_1_headline": "Ce ați dori să știți?",

View File

@@ -2248,6 +2248,7 @@
"csat_survey_question_3_headline": "糟糕, 对不起!我们可以做些什么来改善您的体验?",
"csat_survey_question_3_placeholder": "在此输入您的答案...",
"cta_description": "显示 信息 并 提示用户采取 特定行动",
"custom_survey_block_1_name": "模块 1",
"custom_survey_description": "创建 一个 没有 模板 的 调查。",
"custom_survey_name": "从零开始",
"custom_survey_question_1_headline": "你 想 知道 什么?",

View File

@@ -2248,6 +2248,7 @@
"csat_survey_question_3_headline": "唉,抱歉!我們是否有任何可以改善您體驗的地方?",
"csat_survey_question_3_placeholder": "在此輸入您的答案...",
"cta_description": "顯示資訊並提示使用者採取特定操作",
"custom_survey_block_1_name": "區塊 1",
"custom_survey_description": "建立沒有範本的問卷。",
"custom_survey_name": "從頭開始",
"custom_survey_question_1_headline": "您想瞭解什麼?",

View File

@@ -81,7 +81,6 @@ export const QuotaModal = ({
const [openConfirmationModal, setOpenConfirmationModal] = useState(false);
const [openConfirmChangesInInclusionCriteria, setOpenConfirmChangesInInclusionCriteria] = useState(false);
// Derive questions from blocks (with fallback to legacy questions)
const questions = useMemo(() => {
return survey.blocks.flatMap((block) => block.elements);
}, [survey.blocks]);

View File

@@ -70,11 +70,12 @@ export const determineImageUploaderVisibility = (questionIdx: number, localSurve
switch (questionIdx) {
case -1: // Welcome Card
return false;
default:
default: {
// Regular Survey Question - derive questions from blocks
const questions = localSurvey.blocks.flatMap((block) => block.elements);
const question = questions[questionIdx];
return (!!question && !!question.imageUrl) || (!!question && !!question.videoUrl);
}
}
};

View File

@@ -49,6 +49,7 @@ export function LogicEditor({
const parentBlock = localSurvey.blocks?.find((block) =>
block.elements.some((element) => element.id === question.id)
);
const blockLogicFallback = parentBlock?.logicFallback;
const fallbackOptions = useMemo(() => {
@@ -62,15 +63,29 @@ export function LogicEditor({
const allQuestions = localSurvey.blocks.flatMap((b) => b.elements);
const blocks = localSurvey.blocks;
// Track which blocks we've already added to avoid duplicates when a block has multiple elements
const addedBlockIds = new Set<string>();
// Iterate over the questions AFTER the current question
for (let i = questionIdx + 1; i < allQuestions.length; i++) {
const ques = allQuestions[i];
// Find block ID for this question
const block = blocks.find((b) => b.elements.some((e) => e.id === ques.id));
if (!block) continue;
// Skip if we've already added this block
if (addedBlockIds.has(block.id)) continue;
addedBlockIds.add(block.id);
// Use the first element's headline as the block label
const firstElement = block.elements[0];
options.push({
icon: QUESTIONS_ICON_MAP[ques.type],
label: getTextContent(recallToHeadline(ques.headline, localSurvey, false, "default").default ?? ""),
value: block?.id ?? ques.id, // Block ID if blocks exist, otherwise question ID
icon: QUESTIONS_ICON_MAP[firstElement.type],
label: getTextContent(
recallToHeadline(firstElement.headline, localSurvey, false, "default").default ?? ""
),
value: block.id,
});
}

View File

@@ -953,17 +953,32 @@ export const getActionTargetOptions = (
}
// For jumpToBlock, we need block IDs
// Track which blocks we've already added to avoid duplicates when a block has multiple elements
const blocks = localSurvey.blocks ?? [];
const questionOptions = questions.map((question) => {
const addedBlockIds = new Set<string>();
const questionOptions: TComboboxOption[] = [];
for (const question of questions) {
// Find which block this question belongs to
const block = blocks.find((b) => b.elements.some((e) => e.id === question.id));
const processedHeadline = recallToHeadline(question.headline, localSurvey, false, "default");
return {
icon: getQuestionIconMapping(t)[question.type],
if (!block) continue;
// Skip if we've already added this block
if (addedBlockIds.has(block.id)) continue;
// Mark this block as added
addedBlockIds.add(block.id);
// Use the first element's headline as the block label
const firstElement = block.elements[0];
const processedHeadline = recallToHeadline(firstElement.headline, localSurvey, false, "default");
questionOptions.push({
icon: getQuestionIconMapping(t)[firstElement.type],
label: getTextContent(processedHeadline.default ?? ""),
value: block?.id ?? question.id, // Block ID for jumpToBlock
};
});
value: block.id,
});
}
// Ending cards
const endingCardOptions = localSurvey.endings.map((ending) => {

View File

@@ -10,6 +10,7 @@ import type {
TResponseVariables,
} from "@formbricks/types/responses";
import { TUploadFileConfig } from "@formbricks/types/storage";
import { TSurveyBlockLogicAction } from "@formbricks/types/surveys/blocks";
import { type TSurveyQuestionId } from "@formbricks/types/surveys/types";
import { EndingCard } from "@/components/general/ending-card";
import { ErrorComponent } from "@/components/general/error-component";
@@ -426,7 +427,7 @@ export function Survey({
) {
const { jumpTarget, requiredQuestionIds, calculations } = performActions(
localSurvey,
logic.actions,
logic.actions as TSurveyBlockLogicAction[], //TODO: Temporary type assertion until the survey editor poc is completed, fix properly later
localResponseData,
calculationResults
);

View File

@@ -1,12 +1,9 @@
import { describe, expect, test, vi } from "vitest";
import { TJsEnvironmentStateSurvey } from "@formbricks/types/js";
import { TResponseData, TResponseVariables } from "@formbricks/types/responses";
import { TSurveyBlockLogicAction } from "@formbricks/types/surveys/blocks";
import { TConditionGroup, TSingleCondition } from "@formbricks/types/surveys/logic";
import {
TSurveyLogicAction,
TSurveyQuestionTypeEnum,
TSurveyVariable,
} from "@formbricks/types/surveys/types";
import { TSurveyQuestionTypeEnum, TSurveyVariable } from "@formbricks/types/surveys/types";
import { evaluateLogic, isConditionGroup, performActions } from "./logic";
// Mock the imported function
@@ -362,10 +359,10 @@ describe("Survey Logic", () => {
};
test("performs jump action", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var1",
objective: "jumpToQuestion",
objective: "jumpToBlock",
target: "q5",
},
];
@@ -377,7 +374,7 @@ describe("Survey Logic", () => {
});
test("performs require answer action", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var1",
objective: "requireAnswer",
@@ -392,7 +389,7 @@ describe("Survey Logic", () => {
});
test("performs calculate action - add", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var2",
objective: "calculate",
@@ -407,7 +404,7 @@ describe("Survey Logic", () => {
});
test("performs calculate action - subtract", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var2",
objective: "calculate",
@@ -422,7 +419,7 @@ describe("Survey Logic", () => {
});
test("performs calculate action - multiply", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var2",
objective: "calculate",
@@ -437,7 +434,7 @@ describe("Survey Logic", () => {
});
test("performs calculate action - divide", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var2",
objective: "calculate",
@@ -452,7 +449,7 @@ describe("Survey Logic", () => {
});
test("handles divide by zero", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var2",
objective: "calculate",
@@ -467,7 +464,7 @@ describe("Survey Logic", () => {
});
test("performs calculate action - assign", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var2",
objective: "calculate",
@@ -482,7 +479,7 @@ describe("Survey Logic", () => {
});
test("performs calculate action - concat", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var1",
objective: "calculate",
@@ -497,7 +494,7 @@ describe("Survey Logic", () => {
});
test("performs calculate action with question value", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var2",
objective: "calculate",
@@ -512,7 +509,7 @@ describe("Survey Logic", () => {
});
test("performs calculate action with variable value", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var2",
objective: "calculate",
@@ -527,7 +524,7 @@ describe("Survey Logic", () => {
});
test("performs multiple actions in order", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var2",
objective: "calculate",
@@ -542,7 +539,7 @@ describe("Survey Logic", () => {
},
{
id: "var2",
objective: "jumpToQuestion",
objective: "jumpToBlock",
target: "q5",
},
];
@@ -554,15 +551,15 @@ describe("Survey Logic", () => {
});
test("takes first jump target when multiple jump actions exist", () => {
const actions: TSurveyLogicAction[] = [
const actions: TSurveyBlockLogicAction[] = [
{
id: "var2",
objective: "jumpToQuestion",
objective: "jumpToBlock",
target: "q2",
},
{
id: "var2",
objective: "jumpToQuestion",
objective: "jumpToBlock",
target: "q3",
},
];