Skip to content

Commit

Permalink
fix: multi lang issue sync (formbricks#3132)
Browse files Browse the repository at this point in the history
Co-authored-by: Dhruwang <[email protected]>
  • Loading branch information
pandeymangg and Dhruwang authored Sep 12, 2024
1 parent 688dc25 commit 6ab83e2
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 18 deletions.
28 changes: 17 additions & 11 deletions apps/web/app/api/v1/client/[environmentId]/app/sync/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,33 @@ import { TSurvey } from "@formbricks/types/surveys/types";

export const replaceAttributeRecall = (survey: TSurvey, attributes: TAttributes): TSurvey => {
const surveyTemp = structuredClone(survey);
const languages = surveyTemp.languages.map((surveyLanguage) => {
if (surveyLanguage.default) {
return "default";
}
const languages = surveyTemp.languages
.map((surveyLanguage) => {
if (surveyLanguage.default) {
return "default";
}

return surveyLanguage.language.code;
});
if (surveyLanguage.enabled) {
return surveyLanguage.language.code;
}

return null;
})
.filter((language) => language !== null);

surveyTemp.questions.forEach((question) => {
languages.forEach((language) => {
if (question.headline[language].includes("recall:")) {
if (question.headline[language]?.includes("recall:")) {
question.headline[language] = parseRecallInfo(question.headline[language], attributes);
}
if (question.subheader && question.subheader[language].includes("recall:")) {
if (question.subheader && question.subheader[language]?.includes("recall:")) {
question.subheader[language] = parseRecallInfo(question.subheader[language], attributes);
}
});
});
if (surveyTemp.welcomeCard.enabled && surveyTemp.welcomeCard.headline) {
languages.forEach((language) => {
if (surveyTemp.welcomeCard.headline && surveyTemp.welcomeCard.headline[language].includes("recall:")) {
if (surveyTemp.welcomeCard.headline && surveyTemp.welcomeCard.headline[language]?.includes("recall:")) {
surveyTemp.welcomeCard.headline[language] = parseRecallInfo(
surveyTemp.welcomeCard.headline[language],
attributes
Expand All @@ -35,9 +41,9 @@ export const replaceAttributeRecall = (survey: TSurvey, attributes: TAttributes)
surveyTemp.endings.forEach((ending) => {
if (ending.type === "endScreen") {
languages.forEach((language) => {
if (ending.headline && ending.headline[language].includes("recall:")) {
if (ending.headline && ending.headline[language]?.includes("recall:")) {
ending.headline[language] = parseRecallInfo(ending.headline[language], attributes);
if (ending.subheader && ending.subheader[language].includes("recall:")) {
if (ending.subheader && ending.subheader[language]?.includes("recall:")) {
ending.subheader[language] = parseRecallInfo(ending.subheader[language], attributes);
}
}
Expand Down
48 changes: 41 additions & 7 deletions packages/types/surveys/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,23 @@ export const validateQuestionLabels = (
questionIndex: number,
skipArticle = false
): z.IssueData | null => {
// fieldLabel should contain all the keys present in languages
// even if one of the keys is an empty string, its okay but it shouldn't be undefined

for (const language of languages) {
if (
!language.default &&
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- could be undefined
fieldLabel[language.language.code] === undefined
) {
return {
code: z.ZodIssueCode.custom,
message: `The ${field} in question ${String(questionIndex + 1)} is not present for the following languages: ${language.language.code}`,
path: ["questions", questionIndex, field],
};
}
}

const invalidLanguageCodes = validateLabelForAllLanguages(fieldLabel, languages);
const isDefaultOnly = invalidLanguageCodes.length === 1 && invalidLanguageCodes[0] === "default";

Expand All @@ -72,7 +89,7 @@ export const validateQuestionLabels = (
if (invalidLanguageCodes.length) {
return {
code: z.ZodIssueCode.custom,
message: `${messagePrefix}${messageField} in question ${String(questionIndex + 1)}${messageSuffix}`,
message: `${messagePrefix}${messageField} in question ${String(questionIndex + 1)}${messageSuffix} ${invalidLanguageCodes.join()}`,
path: ["questions", questionIndex, field],
params: isDefaultOnly ? undefined : { invalidLanguageCodes },
};
Expand All @@ -89,6 +106,27 @@ export const validateCardFieldsForAllLanguages = (
endingCardIndex?: number,
skipArticle = false
): z.IssueData | null => {
// fieldLabel should contain all the keys present in languages
// even if one of the keys is an empty string, its okay but it shouldn't be undefined

const cardTypeLabel =
cardType === "welcome" ? "Welcome card" : `Redirect to Url ${((endingCardIndex ?? -1) + 1).toString()}`;
const path = cardType === "welcome" ? ["welcomeCard", field] : ["endings", endingCardIndex ?? -1, field];

for (const language of languages) {
if (
!language.default &&
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- could be undefined
fieldLabel[language.language.code] === undefined
) {
return {
code: z.ZodIssueCode.custom,
message: `The ${field} in ${cardTypeLabel} is not present for the following languages: ${language.language.code}`,
path,
};
}
}

const invalidLanguageCodes = validateLabelForAllLanguages(fieldLabel, languages);
const isDefaultOnly = invalidLanguageCodes.length === 1 && invalidLanguageCodes[0] === "default";

Expand All @@ -99,12 +137,8 @@ export const validateCardFieldsForAllLanguages = (
if (invalidLanguageCodes.length) {
return {
code: z.ZodIssueCode.custom,
message: `${messagePrefix}${messageField} on the ${
cardType === "welcome"
? "Welcome card"
: `Redirect to Url ${((endingCardIndex ?? -1) + 1).toString()}`
} ${messageSuffix}`,
path: cardType === "welcome" ? ["welcomeCard", field] : ["endings", endingCardIndex ?? -1, field],
message: `${messagePrefix}${messageField} on the ${cardTypeLabel} ${messageSuffix} ${invalidLanguageCodes.join()}`,
path,
params: isDefaultOnly ? undefined : { invalidLanguageCodes },
};
}
Expand Down

0 comments on commit 6ab83e2

Please sign in to comment.