From d7e537f699332931efa39883fc646b432c72093d Mon Sep 17 00:00:00 2001 From: pandeymangg Date: Fri, 21 Nov 2025 15:26:55 +0530 Subject: [PATCH] fixes UI issues --- apps/web/i18n.lock | 1 + apps/web/locales/de-DE.json | 2 +- apps/web/locales/en-US.json | 2 +- apps/web/locales/fr-FR.json | 2 +- apps/web/locales/ja-JP.json | 2 +- apps/web/locales/pt-BR.json | 2 +- apps/web/locales/pt-PT.json | 2 +- apps/web/locales/ro-RO.json | 2 +- apps/web/locales/zh-Hans-CN.json | 2 +- apps/web/locales/zh-Hant-TW.json | 2 +- .../survey/editor/components/logic-editor.tsx | 32 +++----------- apps/web/modules/survey/editor/lib/utils.tsx | 44 ++++++++++++------- 12 files changed, 43 insertions(+), 52 deletions(-) diff --git a/apps/web/i18n.lock b/apps/web/i18n.lock index 604034c462..e9ceebb23d 100644 --- a/apps/web/i18n.lock +++ b/apps/web/i18n.lock @@ -1385,6 +1385,7 @@ checksums: environments/surveys/edit/move_question_to_block: e8d7ef1e2f727921cb7f5788849492ad environments/surveys/edit/multiply: 89a0bb629167f97750ae1645a46ced0d environments/surveys/edit/needed_for_self_hosted_cal_com_instance: d241e72f0332177d32ce6c35070757dc + environments/surveys/edit/next_block: 53eaa5b1c9333455ab1e99bedd222ba2 environments/surveys/edit/next_button_label: e23522dd38f3eabeeccd3f48f32b73a8 environments/surveys/edit/next_question: 2e0f1ea264fb4bfcb8378b2b0cf7c18f environments/surveys/edit/no_hidden_fields_yet_add_first_one_below: 9cc6cab3a6a42dbf835215897b5b8516 diff --git a/apps/web/locales/de-DE.json b/apps/web/locales/de-DE.json index 8ea5b22422..0d4a8c8604 100644 --- a/apps/web/locales/de-DE.json +++ b/apps/web/locales/de-DE.json @@ -1470,8 +1470,8 @@ "move_question_to_block": "Frage in Block verschieben", "multiply": "Multiplizieren *", "needed_for_self_hosted_cal_com_instance": "Benötigt für eine selbstgehostete Cal.com-Instanz", + "next_block": "Nächster Block", "next_button_label": "Beschriftung der Schaltfläche \"Weiter\"", - "next_question": "Nächste Frage", "no_hidden_fields_yet_add_first_one_below": "Noch keine versteckten Felder. Füge das erste unten hinzu.", "no_images_found_for": "Keine Bilder gefunden für ''{query}\"", "no_languages_found_add_first_one_to_get_started": "Keine Sprachen gefunden. Füge die erste hinzu, um loszulegen.", diff --git a/apps/web/locales/en-US.json b/apps/web/locales/en-US.json index 6f9d0eabec..1174aedd9e 100644 --- a/apps/web/locales/en-US.json +++ b/apps/web/locales/en-US.json @@ -1470,8 +1470,8 @@ "move_question_to_block": "Move question to block", "multiply": "Multiply *", "needed_for_self_hosted_cal_com_instance": "Needed for a self-hosted Cal.com instance", + "next_block": "Next block", "next_button_label": "\"Next\" button label", - "next_question": "Next question", "no_hidden_fields_yet_add_first_one_below": "No hidden fields yet. Add the first one below.", "no_images_found_for": "No images found for ''{query}\"", "no_languages_found_add_first_one_to_get_started": "No languages found. Add the first one to get started.", diff --git a/apps/web/locales/fr-FR.json b/apps/web/locales/fr-FR.json index d650a59020..ca1c7f9eb1 100644 --- a/apps/web/locales/fr-FR.json +++ b/apps/web/locales/fr-FR.json @@ -1470,8 +1470,8 @@ "move_question_to_block": "Déplacer la question vers le bloc", "multiply": "Multiplier *", "needed_for_self_hosted_cal_com_instance": "Nécessaire pour une instance Cal.com auto-hébergée", + "next_block": "Bloc suivant", "next_button_label": "Libellé du bouton « Suivant »", - "next_question": "Question suivante", "no_hidden_fields_yet_add_first_one_below": "Aucun champ caché pour le moment. Ajoutez le premier ci-dessous.", "no_images_found_for": "Aucune image trouvée pour ''{query}\"", "no_languages_found_add_first_one_to_get_started": "Aucune langue trouvée. Ajoutez la première pour commencer.", diff --git a/apps/web/locales/ja-JP.json b/apps/web/locales/ja-JP.json index 75e2b0fcc1..2f343a1b23 100644 --- a/apps/web/locales/ja-JP.json +++ b/apps/web/locales/ja-JP.json @@ -1470,8 +1470,8 @@ "move_question_to_block": "質問をブロックに移動", "multiply": "乗算 *", "needed_for_self_hosted_cal_com_instance": "セルフホストのCal.comインスタンスに必要", + "next_block": "次のブロック", "next_button_label": "「次へ」ボタンのラベル", - "next_question": "次の質問", "no_hidden_fields_yet_add_first_one_below": "まだ非表示フィールドがありません。以下で最初のものを追加してください。", "no_images_found_for": "''{query}'' の画像が見つかりません", "no_languages_found_add_first_one_to_get_started": "言語が見つかりません。始めるには、最初のものを追加してください。", diff --git a/apps/web/locales/pt-BR.json b/apps/web/locales/pt-BR.json index b7e82e7db7..53820e414c 100644 --- a/apps/web/locales/pt-BR.json +++ b/apps/web/locales/pt-BR.json @@ -1470,8 +1470,8 @@ "move_question_to_block": "Mover pergunta para o bloco", "multiply": "Multiplicar *", "needed_for_self_hosted_cal_com_instance": "Necessário para uma instância auto-hospedada do Cal.com", + "next_block": "Próximo bloco", "next_button_label": "Próximo", - "next_question": "próxima pergunta", "no_hidden_fields_yet_add_first_one_below": "Ainda não há campos ocultos. Adicione o primeiro abaixo.", "no_images_found_for": "Nenhuma imagem encontrada para ''{query}\"", "no_languages_found_add_first_one_to_get_started": "Nenhum idioma encontrado. Adicione o primeiro para começar.", diff --git a/apps/web/locales/pt-PT.json b/apps/web/locales/pt-PT.json index 789e3b4fa4..9f0167c466 100644 --- a/apps/web/locales/pt-PT.json +++ b/apps/web/locales/pt-PT.json @@ -1470,8 +1470,8 @@ "move_question_to_block": "Mover pergunta para o bloco", "multiply": "Multiplicar *", "needed_for_self_hosted_cal_com_instance": "Necessário para uma instância auto-hospedada do Cal.com", + "next_block": "Bloco seguinte", "next_button_label": "Rótulo do botão \"Seguinte\"", - "next_question": "Próxima pergunta", "no_hidden_fields_yet_add_first_one_below": "Ainda não há campos ocultos. Adicione o primeiro abaixo.", "no_images_found_for": "Não foram encontradas imagens para ''{query}\"", "no_languages_found_add_first_one_to_get_started": "Nenhuma língua encontrada. Adicione a primeira para começar.", diff --git a/apps/web/locales/ro-RO.json b/apps/web/locales/ro-RO.json index 1fdcc926d6..8e1f912100 100644 --- a/apps/web/locales/ro-RO.json +++ b/apps/web/locales/ro-RO.json @@ -1470,8 +1470,8 @@ "move_question_to_block": "Mută întrebarea în bloc", "multiply": "Multiplicare", "needed_for_self_hosted_cal_com_instance": "Necesar pentru un exemplu autogăzduit Cal.com", + "next_block": "Blocul următor", "next_button_label": "Etichetă buton \"Următorul\"", - "next_question": "Întrebarea următoare", "no_hidden_fields_yet_add_first_one_below": "Nu există încă câmpuri ascunse. Adăugați primul mai jos.", "no_images_found_for": "Nicio imagine găsită pentru ''{query}\"", "no_languages_found_add_first_one_to_get_started": "Nu s-au găsit limbi. Adaugă prima pentru a începe.", diff --git a/apps/web/locales/zh-Hans-CN.json b/apps/web/locales/zh-Hans-CN.json index 2280d0d00b..2820d69a93 100644 --- a/apps/web/locales/zh-Hans-CN.json +++ b/apps/web/locales/zh-Hans-CN.json @@ -1470,8 +1470,8 @@ "move_question_to_block": "将问题移动到区块", "multiply": "乘 *", "needed_for_self_hosted_cal_com_instance": "需要用于 自建 Cal.com 实例", + "next_block": "下一块", "next_button_label": "\"下一步\" 按钮标签", - "next_question": "下一个问题", "no_hidden_fields_yet_add_first_one_below": "还没有隐藏字段。 在下面添加第一个。", "no_images_found_for": "未找到与 \"{query}\" 相关的图片", "no_languages_found_add_first_one_to_get_started": "没有找到语言。添加第一个以开始。", diff --git a/apps/web/locales/zh-Hant-TW.json b/apps/web/locales/zh-Hant-TW.json index 298bf54f70..97e133838e 100644 --- a/apps/web/locales/zh-Hant-TW.json +++ b/apps/web/locales/zh-Hant-TW.json @@ -1470,8 +1470,8 @@ "move_question_to_block": "將問題移至區塊", "multiply": "乘 *", "needed_for_self_hosted_cal_com_instance": "自行託管 Cal.com 執行個體時需要", + "next_block": "下一個區塊", "next_button_label": "「下一步」按鈕標籤", - "next_question": "下一個問題", "no_hidden_fields_yet_add_first_one_below": "尚無隱藏欄位。在下方新增第一個隱藏欄位。", "no_images_found_for": "找不到「'{'query'}'」的圖片", "no_languages_found_add_first_one_to_get_started": "找不到語言。新增第一個語言以開始使用。", diff --git a/apps/web/modules/survey/editor/components/logic-editor.tsx b/apps/web/modules/survey/editor/components/logic-editor.tsx index 569eb3c548..69274d7fea 100644 --- a/apps/web/modules/survey/editor/components/logic-editor.tsx +++ b/apps/web/modules/survey/editor/components/logic-editor.tsx @@ -1,7 +1,7 @@ "use client"; import { ArrowRightIcon } from "lucide-react"; -import { ReactElement, useMemo } from "react"; +import { useMemo } from "react"; import { useTranslation } from "react-i18next"; import { TSurveyBlockLogic } from "@formbricks/types/surveys/blocks"; import { TSurveyBlock } from "@formbricks/types/surveys/blocks"; @@ -10,7 +10,6 @@ import { getTextContent } from "@formbricks/types/surveys/validation"; import { recallToHeadline } from "@/lib/utils/recall"; import { LogicEditorActions } from "@/modules/survey/editor/components/logic-editor-actions"; import { LogicEditorConditions } from "@/modules/survey/editor/components/logic-editor-conditions"; -import { getQuestionIconMap } from "@/modules/survey/lib/questions"; import { Select, SelectContent, @@ -41,39 +40,23 @@ export function LogicEditor({ isLast, }: LogicEditorProps) { const { t } = useTranslation(); - const QUESTIONS_ICON_MAP = getQuestionIconMap(t); const blockLogicFallback = block.logicFallback; const fallbackOptions = useMemo(() => { let options: { - icon?: ReactElement; label: string; value: string; }[] = []; const blocks = localSurvey.blocks; - // Track which blocks we've already added to avoid duplicates when a block has multiple elements - const addedBlockIds = new Set(); - - // Iterate over the elements AFTER the current block + // Add blocks AFTER the current block for (let i = blockIdx + 1; i < blocks.length; i++) { const currentBlock = blocks[i]; - if (addedBlockIds.has(currentBlock.id)) continue; - - addedBlockIds.add(currentBlock.id); - - // Use the first element's headline as the block label - const firstElement = currentBlock.elements[0]; - if (!firstElement) continue; - options.push({ - icon: QUESTIONS_ICON_MAP[firstElement.type], - label: getTextContent( - recallToHeadline(firstElement.headline, localSurvey, false, "default").default ?? "" - ), + label: currentBlock.name, value: currentBlock.id, }); } @@ -92,7 +75,7 @@ export function LogicEditor({ }); return options; - }, [localSurvey, blockIdx, QUESTIONS_ICON_MAP, t]); + }, [localSurvey, blockIdx, t]); return (
@@ -133,15 +116,12 @@ export function LogicEditor({ - {t("environments.surveys.edit.next_question")} + {t("environments.surveys.edit.next_block")} {fallbackOptions.map((option) => ( -
- {option.icon} - {option.label} -
+ {option.label}
))}
diff --git a/apps/web/modules/survey/editor/lib/utils.tsx b/apps/web/modules/survey/editor/lib/utils.tsx index f9e004dc78..5f7e21213d 100644 --- a/apps/web/modules/survey/editor/lib/utils.tsx +++ b/apps/web/modules/survey/editor/lib/utils.tsx @@ -26,7 +26,7 @@ import { isConditionGroup } from "@/lib/surveyLogic/utils"; import { recallToHeadline } from "@/lib/utils/recall"; import { findElementLocation } from "@/modules/survey/editor/lib/blocks"; import { getElementsFromBlocks } from "@/modules/survey/lib/client-utils"; -import { getQuestionTypes } from "@/modules/survey/lib/questions"; +import { getQuestionTypes, getTSurveyQuestionTypeEnumName } from "@/modules/survey/lib/questions"; import { TComboboxGroupedOption, TComboboxOption } from "@/modules/ui/components/input-combo-box"; import { TLogicRuleOption, getLogicRules } from "./logic-rule-engine"; @@ -106,6 +106,23 @@ const getQuestionIconMapping = (t: TFunction) => {} ); +const getElementHeadline = ( + localSurvey: TSurvey, + element: TSurveyElement, + languageCode: string, + t: TFunction +): string => { + const headlineData = recallToHeadline(element.headline, localSurvey, false, languageCode); + const headlineText = headlineData[languageCode]; + if (headlineText) { + const textContent = getTextContent(headlineText); + if (textContent.length > 0) { + return textContent; + } + } + return getTSurveyQuestionTypeEnumName(element.type, t) ?? ""; +}; + export const getConditionValueOptions = ( localSurvey: TSurvey, t: TFunction, @@ -128,9 +145,9 @@ export const getConditionValueOptions = ( allElements.forEach((element) => { if (element.type === TSurveyElementTypeEnum.Matrix) { + const elementHeadline = getElementHeadline(localSurvey, element, "default", t); + // Rows submenu - const processedHeadline = recallToHeadline(element.headline, localSurvey, false, "default"); - const elementHeadline = getTextContent(processedHeadline.default ?? ""); const rows = element.rows.map((row, rowIdx) => { const processedLabel = recallToHeadline(row.label, localSurvey, false, "default"); return { @@ -169,9 +186,7 @@ export const getConditionValueOptions = ( } else { elementOptions.push({ icon: getQuestionIconMapping(t)[element.type], - label: getTextContent( - recallToHeadline(element.headline, localSurvey, false, "default").default ?? "" - ), + label: getElementHeadline(localSurvey, element, "default", t), value: element.id, meta: { type: "question", @@ -715,10 +730,9 @@ export const getMatchValueProps = ( const allowedElements = elements.filter((element) => allowedElementTypes.includes(element.type)); const elementOptions = allowedElements.map((element) => { - const processedHeadline = recallToHeadline(element.headline, localSurvey, false, "default"); return { icon: getQuestionIconMapping(t)[element.type], - label: getTextContent(processedHeadline.default ?? ""), + label: getElementHeadline(localSurvey, element, "default", t), value: element.id, meta: { type: "question", @@ -790,10 +804,9 @@ export const getMatchValueProps = ( ); const elementOptions = allowedElements.map((element) => { - const processedHeadline = recallToHeadline(element.headline, localSurvey, false, "default"); return { icon: getQuestionIconMapping(t)[element.type], - label: getTextContent(processedHeadline.default ?? ""), + label: getElementHeadline(localSurvey, element, "default", t), value: element.id, meta: { type: "question", @@ -871,10 +884,9 @@ export const getMatchValueProps = ( const allowedElements = elements.filter((element) => allowedElementTypes.includes(element.type)); const elementOptions = allowedElements.map((element) => { - const processedHeadline = recallToHeadline(element.headline, localSurvey, false, "default"); return { icon: getQuestionIconMapping(t)[element.type], - label: getTextContent(processedHeadline.default ?? ""), + label: getElementHeadline(localSurvey, element, "default", t), value: element.id, meta: { type: "question", @@ -967,11 +979,10 @@ export const getActionTargetOptions = ( // Return element IDs for requireAnswer return nonRequiredElements.map((element) => { - const processedHeadline = recallToHeadline(element.headline, localSurvey, false, "default"); return { icon: getQuestionIconMapping(t)[element.type], - label: getTextContent(processedHeadline.default ?? ""), - value: element.id, // Element ID + label: getElementHeadline(localSurvey, element, "default", t), + value: element.id, }; }); } @@ -1114,10 +1125,9 @@ export const getActionValueOptions = ( ); const elementOptions = allowedElements.map((element) => { - const processedHeadline = recallToHeadline(element.headline, localSurvey, false, "default"); return { icon: getQuestionIconMapping(t)[element.type], - label: getTextContent(processedHeadline.default ?? ""), + label: getElementHeadline(localSurvey, element, "default", t), value: element.id, meta: { type: "question",