mirror of
https://github.com/formbricks/formbricks.git
synced 2026-01-05 16:19:55 -06:00
chore: removed contact attributes from recall (#4651)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com> Co-authored-by: Piyush Gupta <piyushguptaa2z123@gmail.com>
This commit is contained in:
committed by
GitHub
parent
24de1559a5
commit
69a7a57f41
@@ -8,7 +8,6 @@ import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyAddressQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -21,7 +20,6 @@ interface AddressQuestionFormProps {
|
||||
isInvalid: boolean;
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -33,7 +31,6 @@ export const AddressQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: AddressQuestionFormProps): JSX.Element => {
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages ?? []);
|
||||
@@ -107,7 +104,6 @@ export const AddressQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -125,7 +121,6 @@ export const AddressQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ConditionalLogic } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/ConditionalLogic";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestion } from "@formbricks/types/surveys/types";
|
||||
import { UpdateQuestionId } from "./UpdateQuestionId";
|
||||
|
||||
@@ -8,7 +7,6 @@ interface AdvancedSettingsProps {
|
||||
questionIdx: number;
|
||||
localSurvey: TSurvey;
|
||||
updateQuestion: (questionIdx: number, updatedAttributes: any) => void;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
}
|
||||
|
||||
export const AdvancedSettings = ({
|
||||
@@ -16,7 +14,6 @@ export const AdvancedSettings = ({
|
||||
questionIdx,
|
||||
localSurvey,
|
||||
updateQuestion,
|
||||
contactAttributeKeys,
|
||||
}: AdvancedSettingsProps) => {
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
@@ -25,7 +22,6 @@ export const AdvancedSettings = ({
|
||||
updateQuestion={updateQuestion}
|
||||
localSurvey={localSurvey}
|
||||
questionIdx={questionIdx}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
/>
|
||||
|
||||
<UpdateQuestionId
|
||||
|
||||
@@ -8,7 +8,6 @@ import { OptionsSwitch } from "@/modules/ui/components/options-switch";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useState } from "react";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyCTAQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -21,7 +20,6 @@ interface CTAQuestionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (languageCode: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -34,7 +32,6 @@ export const CTAQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: CTAQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
@@ -59,7 +56,6 @@ export const CTAQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -103,7 +99,6 @@ export const CTAQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -120,7 +115,6 @@ export const CTAQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
)}
|
||||
@@ -155,7 +149,6 @@ export const CTAQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,6 @@ import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect, useState } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyCalQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -20,7 +19,6 @@ interface CalQuestionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -32,7 +30,6 @@ export const CalQuestionForm = ({
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
isInvalid,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: CalQuestionFormProps): JSX.Element => {
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
@@ -60,7 +57,6 @@ export const CalQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<div>
|
||||
@@ -77,7 +73,6 @@ export const CalQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,6 @@ import { useTranslations } from "next-intl";
|
||||
import { useMemo } from "react";
|
||||
import { duplicateLogicItem } from "@formbricks/lib/surveyLogic/utils";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyLogic, TSurveyQuestion } from "@formbricks/types/surveys/types";
|
||||
|
||||
interface ConditionalLogicProps {
|
||||
@@ -34,11 +33,9 @@ interface ConditionalLogicProps {
|
||||
questionIdx: number;
|
||||
question: TSurveyQuestion;
|
||||
updateQuestion: (questionIdx: number, updatedAttributes: any) => void;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
}
|
||||
|
||||
export function ConditionalLogic({
|
||||
contactAttributeKeys,
|
||||
localSurvey,
|
||||
question,
|
||||
questionIdx,
|
||||
@@ -46,11 +43,11 @@ export function ConditionalLogic({
|
||||
}: ConditionalLogicProps) {
|
||||
const t = useTranslations();
|
||||
const transformedSurvey = useMemo(() => {
|
||||
let modifiedSurvey = replaceHeadlineRecall(localSurvey, "default", contactAttributeKeys);
|
||||
modifiedSurvey = replaceEndingCardHeadlineRecall(modifiedSurvey, "default", contactAttributeKeys);
|
||||
let modifiedSurvey = replaceHeadlineRecall(localSurvey, "default");
|
||||
modifiedSurvey = replaceEndingCardHeadlineRecall(modifiedSurvey, "default");
|
||||
|
||||
return modifiedSurvey;
|
||||
}, [localSurvey, contactAttributeKeys]);
|
||||
}, [localSurvey]);
|
||||
|
||||
const addLogic = () => {
|
||||
const operator = getDefaultOperatorForQuestion(question, t);
|
||||
|
||||
@@ -5,7 +5,6 @@ import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInpu
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useState } from "react";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyConsentQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -17,7 +16,6 @@ interface ConsentQuestionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (languageCode: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -29,7 +27,6 @@ export const ConsentQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: ConsentQuestionFormProps): JSX.Element => {
|
||||
const [firstRender, setFirstRender] = useState(true);
|
||||
@@ -46,7 +43,6 @@ export const ConsentQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -80,7 +76,6 @@ export const ConsentQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</form>
|
||||
|
||||
@@ -8,7 +8,6 @@ import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyContactInfoQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -21,7 +20,6 @@ interface ContactInfoQuestionFormProps {
|
||||
isInvalid: boolean;
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -33,7 +31,6 @@ export const ContactInfoQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: ContactInfoQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
@@ -98,7 +95,6 @@ export const ContactInfoQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -116,7 +112,6 @@ export const ContactInfoQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,6 @@ import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyDateQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -20,7 +19,6 @@ interface IDateQuestionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -47,7 +45,6 @@ export const DateQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: IDateQuestionFormProps): JSX.Element => {
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
@@ -65,7 +62,6 @@ export const DateQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<div ref={parent}>
|
||||
@@ -82,7 +78,6 @@ export const DateQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,6 @@ import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TOrganizationBillingPlan } from "@formbricks/types/organizations";
|
||||
import {
|
||||
TSurvey,
|
||||
@@ -39,7 +38,6 @@ interface EditEndingCardProps {
|
||||
isInvalid: boolean;
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (languageCode: string) => void;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
plan: TOrganizationBillingPlan;
|
||||
addEndingCard: (index: number) => void;
|
||||
isFormbricksCloud: boolean;
|
||||
@@ -55,7 +53,6 @@ export const EditEndingCard = ({
|
||||
isInvalid,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
plan,
|
||||
addEndingCard,
|
||||
isFormbricksCloud,
|
||||
@@ -200,21 +197,13 @@ export const EditEndingCard = ({
|
||||
<p className="text-sm font-semibold">
|
||||
{endingCard.type === "endScreen" &&
|
||||
(endingCard.headline &&
|
||||
recallToHeadline(
|
||||
endingCard.headline,
|
||||
localSurvey,
|
||||
true,
|
||||
selectedLanguageCode,
|
||||
contactAttributeKeys
|
||||
)[selectedLanguageCode]
|
||||
recallToHeadline(endingCard.headline, localSurvey, true, selectedLanguageCode)[
|
||||
selectedLanguageCode
|
||||
]
|
||||
? formatTextWithSlashes(
|
||||
recallToHeadline(
|
||||
endingCard.headline,
|
||||
localSurvey,
|
||||
true,
|
||||
selectedLanguageCode,
|
||||
contactAttributeKeys
|
||||
)[selectedLanguageCode]
|
||||
recallToHeadline(endingCard.headline, localSurvey, true, selectedLanguageCode)[
|
||||
selectedLanguageCode
|
||||
]
|
||||
)
|
||||
: t("environments.surveys.edit.ending_card"))}
|
||||
{endingCard.type === "redirectToUrl" &&
|
||||
@@ -274,19 +263,13 @@ export const EditEndingCard = ({
|
||||
isInvalid={isInvalid}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
updateSurvey={updateSurvey}
|
||||
endingCard={endingCard}
|
||||
locale={locale}
|
||||
/>
|
||||
)}
|
||||
{endingCard.type === "redirectToUrl" && (
|
||||
<RedirectUrlForm
|
||||
localSurvey={localSurvey}
|
||||
endingCard={endingCard}
|
||||
updateSurvey={updateSurvey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
/>
|
||||
<RedirectUrlForm localSurvey={localSurvey} endingCard={endingCard} updateSurvey={updateSurvey} />
|
||||
)}
|
||||
</Collapsible.CollapsibleContent>
|
||||
</Collapsible.Root>
|
||||
|
||||
@@ -11,7 +11,6 @@ import { useTranslations } from "next-intl";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionId, TSurveyWelcomeCard } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -23,7 +22,6 @@ interface EditWelcomeCardProps {
|
||||
isInvalid: boolean;
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (languageCode: string) => void;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -35,7 +33,6 @@ export const EditWelcomeCard = ({
|
||||
isInvalid,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: EditWelcomeCardProps) => {
|
||||
const t = useTranslations();
|
||||
@@ -136,7 +133,6 @@ export const EditWelcomeCard = ({
|
||||
updateSurvey={updateSurvey}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -173,7 +169,6 @@ export const EditWelcomeCard = ({
|
||||
updateSurvey={updateSurvey}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
label={t("environments.surveys.edit.next_button_label")}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -10,7 +10,6 @@ import { useState } from "react";
|
||||
import { useRef } from "react";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { headlineToRecall, recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyEndScreenCard } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -20,7 +19,6 @@ interface EndScreenFormProps {
|
||||
isInvalid: boolean;
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (languageCode: string) => void;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
updateSurvey: (input: Partial<TSurveyEndScreenCard>) => void;
|
||||
endingCard: TSurveyEndScreenCard;
|
||||
locale: TUserLocale;
|
||||
@@ -32,7 +30,6 @@ export const EndScreenForm = ({
|
||||
isInvalid,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
updateSurvey,
|
||||
endingCard,
|
||||
locale,
|
||||
@@ -55,7 +52,6 @@ export const EndScreenForm = ({
|
||||
updateSurvey={updateSurvey}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -69,7 +65,6 @@ export const EndScreenForm = ({
|
||||
updateSurvey={updateSurvey}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<div className="mt-4">
|
||||
@@ -115,7 +110,6 @@ export const EndScreenForm = ({
|
||||
updateSurvey={updateSurvey}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -137,7 +131,6 @@ export const EndScreenForm = ({
|
||||
onAddFallback={() => {
|
||||
inputRef.current?.focus();
|
||||
}}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
isRecallAllowed
|
||||
localSurvey={localSurvey}
|
||||
usedLanguageCode={"default"}
|
||||
@@ -164,8 +157,7 @@ export const EndScreenForm = ({
|
||||
},
|
||||
localSurvey,
|
||||
false,
|
||||
"default",
|
||||
contactAttributeKeys
|
||||
"default"
|
||||
)[selectedLanguageCode]
|
||||
}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
|
||||
@@ -14,7 +14,6 @@ import { toast } from "react-hot-toast";
|
||||
import { extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { createI18nString } from "@formbricks/lib/i18n/utils";
|
||||
import { TAllowedFileExtension, ZAllowedFileExtension } from "@formbricks/types/common";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TProject } from "@formbricks/types/project";
|
||||
import { TSurvey, TSurveyFileUploadQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
@@ -29,7 +28,6 @@ interface FileUploadFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (languageCode: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
isFormbricksCloud: boolean;
|
||||
locale: TUserLocale;
|
||||
}
|
||||
@@ -43,7 +41,6 @@ export const FileUploadQuestionForm = ({
|
||||
project,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
isFormbricksCloud,
|
||||
locale,
|
||||
}: FileUploadFormProps): JSX.Element => {
|
||||
@@ -141,7 +138,6 @@ export const FileUploadQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<div ref={parent}>
|
||||
@@ -158,7 +154,6 @@ export const FileUploadQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,6 @@ import { PlusIcon, TrashIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TI18nString, TSurvey, TSurveyMatrixQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { isLabelValidForAllLanguages } from "../lib/validation";
|
||||
@@ -24,7 +23,6 @@ interface MatrixQuestionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -36,7 +34,6 @@ export const MatrixQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: MatrixQuestionFormProps): JSX.Element => {
|
||||
const languageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
@@ -118,7 +115,6 @@ export const MatrixQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<div ref={parent}>
|
||||
@@ -135,7 +131,6 @@ export const MatrixQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -179,7 +174,6 @@ export const MatrixQuestionForm = ({
|
||||
isInvalid={
|
||||
isInvalid && !isLabelValidForAllLanguages(question.rows[index], localSurvey.languages)
|
||||
}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
{question.rows.length > 2 && (
|
||||
@@ -232,7 +226,6 @@ export const MatrixQuestionForm = ({
|
||||
isInvalid={
|
||||
isInvalid && !isLabelValidForAllLanguages(question.columns[index], localSurvey.languages)
|
||||
}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
{question.columns.length > 2 && (
|
||||
|
||||
@@ -14,7 +14,6 @@ import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect, useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TI18nString,
|
||||
TShuffleOption,
|
||||
@@ -34,7 +33,6 @@ interface MultipleChoiceQuestionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -46,7 +44,6 @@ export const MultipleChoiceQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: MultipleChoiceQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
@@ -180,7 +177,6 @@ export const MultipleChoiceQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -198,7 +194,6 @@ export const MultipleChoiceQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -267,7 +262,6 @@ export const MultipleChoiceQuestionForm = ({
|
||||
question={question}
|
||||
updateQuestion={updateQuestion}
|
||||
surveyLanguageCodes={surveyLanguageCodes}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -8,7 +8,6 @@ import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyNPSQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -21,7 +20,6 @@ interface NPSQuestionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (languageCode: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -34,7 +32,6 @@ export const NPSQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: NPSQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
@@ -54,7 +51,6 @@ export const NPSQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -72,7 +68,6 @@ export const NPSQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -108,7 +103,6 @@ export const NPSQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -123,7 +117,6 @@ export const NPSQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -143,7 +136,6 @@ export const NPSQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,6 @@ import { HashIcon, LinkIcon, MailIcon, MessageSquareTextIcon, PhoneIcon, PlusIco
|
||||
import { useTranslations } from "next-intl";
|
||||
import { JSX, useEffect, useState } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TSurvey,
|
||||
TSurveyOpenTextQuestion,
|
||||
@@ -28,7 +27,6 @@ interface OpenQuestionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -40,7 +38,6 @@ export const OpenQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: OpenQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
@@ -93,7 +90,6 @@ export const OpenQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
label={t("environments.surveys.edit.question") + "*"}
|
||||
locale={locale}
|
||||
/>
|
||||
@@ -111,7 +107,6 @@ export const OpenQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
label={t("common.description")}
|
||||
locale={locale}
|
||||
/>
|
||||
@@ -148,7 +143,6 @@ export const OpenQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
label={t("common.placeholder")}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -10,7 +10,6 @@ import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyPictureSelectionQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -23,7 +22,6 @@ interface PictureSelectionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -35,7 +33,6 @@ export const PictureSelectionForm = ({
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
isInvalid,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: PictureSelectionFormProps): JSX.Element => {
|
||||
const environmentId = localSurvey.environmentId;
|
||||
@@ -84,7 +81,6 @@ export const PictureSelectionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<div ref={parent}>
|
||||
@@ -101,7 +97,6 @@ export const PictureSelectionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,6 @@ import { useState } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { QUESTIONS_ICON_MAP, getTSurveyQuestionTypeEnumName } from "@formbricks/lib/utils/questions";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TProject } from "@formbricks/types/project";
|
||||
import {
|
||||
TI18nString,
|
||||
@@ -56,7 +55,6 @@ interface QuestionCardProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
addQuestion: (question: any, index?: number) => void;
|
||||
isFormbricksCloud: boolean;
|
||||
isCxMode: boolean;
|
||||
@@ -78,7 +76,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
isInvalid,
|
||||
contactAttributeKeys,
|
||||
addQuestion,
|
||||
isFormbricksCloud,
|
||||
isCxMode,
|
||||
@@ -220,21 +217,13 @@ export const QuestionCard = ({
|
||||
</div> */}
|
||||
<div className="flex grow flex-col justify-center" dir="auto">
|
||||
<p className="text-sm font-semibold">
|
||||
{recallToHeadline(
|
||||
question.headline,
|
||||
localSurvey,
|
||||
true,
|
||||
selectedLanguageCode,
|
||||
contactAttributeKeys
|
||||
)[selectedLanguageCode]
|
||||
{recallToHeadline(question.headline, localSurvey, true, selectedLanguageCode)[
|
||||
selectedLanguageCode
|
||||
]
|
||||
? formatTextWithSlashes(
|
||||
recallToHeadline(
|
||||
question.headline,
|
||||
localSurvey,
|
||||
true,
|
||||
selectedLanguageCode,
|
||||
contactAttributeKeys
|
||||
)[selectedLanguageCode] ?? ""
|
||||
recallToHeadline(question.headline, localSurvey, true, selectedLanguageCode)[
|
||||
selectedLanguageCode
|
||||
] ?? ""
|
||||
)
|
||||
: getTSurveyQuestionTypeEnumName(question.type, locale)}
|
||||
</p>
|
||||
@@ -278,7 +267,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.MultipleChoiceSingle ? (
|
||||
@@ -291,7 +279,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.MultipleChoiceMulti ? (
|
||||
@@ -304,7 +291,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.NPS ? (
|
||||
@@ -317,7 +303,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.CTA ? (
|
||||
@@ -330,7 +315,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.Rating ? (
|
||||
@@ -343,7 +327,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.Consent ? (
|
||||
@@ -355,7 +338,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.Date ? (
|
||||
@@ -368,7 +350,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.PictureSelection ? (
|
||||
@@ -381,7 +362,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.FileUpload ? (
|
||||
@@ -395,7 +375,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
isFormbricksCloud={isFormbricksCloud}
|
||||
locale={locale}
|
||||
/>
|
||||
@@ -409,7 +388,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.Matrix ? (
|
||||
@@ -422,7 +400,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.Address ? (
|
||||
@@ -435,7 +412,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.Ranking ? (
|
||||
@@ -448,7 +424,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : question.type === TSurveyQuestionTypeEnum.ContactInfo ? (
|
||||
@@ -461,7 +436,6 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isInvalid={isInvalid}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : null}
|
||||
@@ -510,7 +484,6 @@ export const QuestionCard = ({
|
||||
localSurvey.questions.length - 1
|
||||
);
|
||||
}}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -527,7 +500,6 @@ export const QuestionCard = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
onBlur={(e) => {
|
||||
if (!question.backButtonLabel) return;
|
||||
@@ -557,7 +529,6 @@ export const QuestionCard = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -568,7 +539,6 @@ export const QuestionCard = ({
|
||||
questionIdx={questionIdx}
|
||||
localSurvey={localSurvey}
|
||||
updateQuestion={updateQuestion}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
/>
|
||||
</Collapsible.CollapsibleContent>
|
||||
</Collapsible.Root>
|
||||
|
||||
@@ -7,7 +7,6 @@ import { GripVerticalIcon, PlusIcon, TrashIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { createI18nString } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TI18nString,
|
||||
TSurvey,
|
||||
@@ -37,7 +36,6 @@ interface ChoiceProps {
|
||||
updatedAttributes: Partial<TSurveyMultipleChoiceQuestion> | Partial<TSurveyRankingQuestion>
|
||||
) => void;
|
||||
surveyLanguageCodes: string[];
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -56,7 +54,6 @@ export const QuestionOptionChoice = ({
|
||||
question,
|
||||
surveyLanguageCodes,
|
||||
updateQuestion,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: ChoiceProps) => {
|
||||
const t = useTranslations();
|
||||
@@ -98,7 +95,6 @@ export const QuestionOptionChoice = ({
|
||||
isInvalid && !isLabelValidForAllLanguages(question.choices[choiceIdx].label, surveyLanguages)
|
||||
}
|
||||
className={`${choice.id === "other" ? "border border-dashed" : ""} mt-0`}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
{choice.id === "other" && (
|
||||
@@ -120,7 +116,6 @@ export const QuestionOptionChoice = ({
|
||||
isInvalid && !isLabelValidForAllLanguages(question.choices[choiceIdx].label, surveyLanguages)
|
||||
}
|
||||
className="border border-dashed"
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TProject } from "@formbricks/types/project";
|
||||
import { TSurvey, TSurveyQuestionId } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
@@ -18,7 +17,6 @@ interface QuestionsDraggableProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
invalidQuestions: string[] | null;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
addQuestion: (question: any, index?: number) => void;
|
||||
isFormbricksCloud: boolean;
|
||||
isCxMode: boolean;
|
||||
@@ -37,7 +35,6 @@ export const QuestionsDroppable = ({
|
||||
setActiveQuestionId,
|
||||
setSelectedLanguageCode,
|
||||
updateQuestion,
|
||||
contactAttributeKeys,
|
||||
addQuestion,
|
||||
isFormbricksCloud,
|
||||
isCxMode,
|
||||
@@ -65,7 +62,6 @@ export const QuestionsDroppable = ({
|
||||
setActiveQuestionId={setActiveQuestionId}
|
||||
lastQuestion={questionIdx === localSurvey.questions.length - 1}
|
||||
isInvalid={invalidQuestions ? invalidQuestions.includes(question.id) : false}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
addQuestion={addQuestion}
|
||||
isFormbricksCloud={isFormbricksCloud}
|
||||
isCxMode={isCxMode}
|
||||
|
||||
@@ -23,7 +23,6 @@ import { structuredClone } from "@formbricks/lib/pollyfills/structuredClone";
|
||||
import { isConditionGroup } from "@formbricks/lib/surveyLogic/utils";
|
||||
import { getDefaultEndingCard } from "@formbricks/lib/templates";
|
||||
import { checkForEmptyFallBackValue, extractRecallInfo } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TOrganizationBillingPlan } from "@formbricks/types/organizations";
|
||||
import { TProject } from "@formbricks/types/project";
|
||||
import {
|
||||
@@ -60,7 +59,6 @@ interface QuestionsViewProps {
|
||||
setSelectedLanguageCode: (languageCode: string) => void;
|
||||
isMultiLanguageAllowed?: boolean;
|
||||
isFormbricksCloud: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
plan: TOrganizationBillingPlan;
|
||||
isCxMode: boolean;
|
||||
locale: TUserLocale;
|
||||
@@ -78,7 +76,6 @@ export const QuestionsView = ({
|
||||
selectedLanguageCode,
|
||||
isMultiLanguageAllowed,
|
||||
isFormbricksCloud,
|
||||
contactAttributeKeys,
|
||||
plan,
|
||||
isCxMode,
|
||||
locale,
|
||||
@@ -435,7 +432,6 @@ export const QuestionsView = ({
|
||||
isInvalid={invalidQuestions ? invalidQuestions.includes("start") : false}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -458,7 +454,6 @@ export const QuestionsView = ({
|
||||
activeQuestionId={activeQuestionId}
|
||||
setActiveQuestionId={setActiveQuestionId}
|
||||
invalidQuestions={invalidQuestions}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
addQuestion={addQuestion}
|
||||
isFormbricksCloud={isFormbricksCloud}
|
||||
isCxMode={isCxMode}
|
||||
@@ -487,7 +482,6 @@ export const QuestionsView = ({
|
||||
isInvalid={invalidQuestions ? invalidQuestions.includes(ending.id) : false}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
plan={plan}
|
||||
addEndingCard={addEndingCard}
|
||||
isFormbricksCloud={isFormbricksCloud}
|
||||
|
||||
@@ -12,7 +12,6 @@ import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect, useRef, useState } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TI18nString, TSurvey, TSurveyRankingQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { QuestionOptionChoice } from "./QuestionOptionChoice";
|
||||
@@ -26,7 +25,6 @@ interface RankingQuestionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -38,7 +36,6 @@ export const RankingQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: RankingQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
@@ -131,7 +128,6 @@ export const RankingQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -149,7 +145,6 @@ export const RankingQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -214,7 +209,6 @@ export const RankingQuestionForm = ({
|
||||
question={question}
|
||||
updateQuestion={updateQuestion}
|
||||
surveyLanguageCodes={surveyLanguageCodes}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -6,7 +6,6 @@ import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { HashIcon, PlusIcon, SmileIcon, StarIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyRatingQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { Dropdown } from "./RatingTypeDropdown";
|
||||
@@ -20,7 +19,6 @@ interface RatingQuestionFormProps {
|
||||
selectedLanguageCode: string;
|
||||
setSelectedLanguageCode: (language: string) => void;
|
||||
isInvalid: boolean;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -32,7 +30,6 @@ export const RatingQuestionForm = ({
|
||||
localSurvey,
|
||||
selectedLanguageCode,
|
||||
setSelectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: RatingQuestionFormProps) => {
|
||||
const t = useTranslations();
|
||||
@@ -50,7 +47,6 @@ export const RatingQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -68,7 +64,6 @@ export const RatingQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -144,7 +139,6 @@ export const RatingQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -160,7 +154,6 @@ export const RatingQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
@@ -180,7 +173,6 @@ export const RatingQuestionForm = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -4,22 +4,15 @@ import { Label } from "@/modules/ui/components/label";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRef } from "react";
|
||||
import { headlineToRecall, recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyRedirectUrlCard } from "@formbricks/types/surveys/types";
|
||||
|
||||
interface RedirectUrlFormProps {
|
||||
localSurvey: TSurvey;
|
||||
endingCard: TSurveyRedirectUrlCard;
|
||||
updateSurvey: (input: Partial<TSurveyRedirectUrlCard>) => void;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
}
|
||||
|
||||
export const RedirectUrlForm = ({
|
||||
localSurvey,
|
||||
contactAttributeKeys,
|
||||
endingCard,
|
||||
updateSurvey,
|
||||
}: RedirectUrlFormProps) => {
|
||||
export const RedirectUrlForm = ({ localSurvey, endingCard, updateSurvey }: RedirectUrlFormProps) => {
|
||||
const selectedLanguageCode = "default";
|
||||
const t = useTranslations();
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
@@ -42,7 +35,6 @@ export const RedirectUrlForm = ({
|
||||
onAddFallback={() => {
|
||||
inputRef.current?.focus();
|
||||
}}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
isRecallAllowed
|
||||
localSurvey={localSurvey}
|
||||
usedLanguageCode={"default"}
|
||||
@@ -69,8 +61,7 @@ export const RedirectUrlForm = ({
|
||||
},
|
||||
localSurvey,
|
||||
false,
|
||||
"default",
|
||||
contactAttributeKeys
|
||||
"default"
|
||||
)[selectedLanguageCode]
|
||||
}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
|
||||
@@ -184,7 +184,6 @@ export const SurveyEditor = ({
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
isMultiLanguageAllowed={isMultiLanguageAllowed}
|
||||
isFormbricksCloud={isFormbricksCloud}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
plan={plan}
|
||||
isCxMode={isCxMode}
|
||||
locale={locale}
|
||||
|
||||
@@ -6,7 +6,6 @@ import { isConditionGroup } from "@formbricks/lib/surveyLogic/utils";
|
||||
import { translate } from "@formbricks/lib/templates";
|
||||
import { getQuestionTypes } from "@formbricks/lib/utils/questions";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TConditionGroup,
|
||||
TLeftOperand,
|
||||
@@ -124,21 +123,11 @@ export const getConditionValueOptions = (
|
||||
return groupedOptions;
|
||||
};
|
||||
|
||||
export const replaceEndingCardHeadlineRecall = (
|
||||
survey: TSurvey,
|
||||
language: string,
|
||||
contactAttributeKeys: TContactAttributeKey[]
|
||||
) => {
|
||||
export const replaceEndingCardHeadlineRecall = (survey: TSurvey, language: string) => {
|
||||
const modifiedSurvey = structuredClone(survey);
|
||||
modifiedSurvey.endings.forEach((ending) => {
|
||||
if (ending.type === "endScreen") {
|
||||
ending.headline = recallToHeadline(
|
||||
ending.headline || {},
|
||||
modifiedSurvey,
|
||||
false,
|
||||
language,
|
||||
contactAttributeKeys
|
||||
);
|
||||
ending.headline = recallToHeadline(ending.headline || {}, modifiedSurvey, false, language);
|
||||
}
|
||||
});
|
||||
return modifiedSurvey;
|
||||
|
||||
@@ -25,7 +25,6 @@ import { Controller, useForm } from "react-hook-form";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TIntegrationItem } from "@formbricks/types/integration";
|
||||
import {
|
||||
TIntegrationAirtable,
|
||||
@@ -46,7 +45,6 @@ type AddIntegrationModalProps = {
|
||||
airtableArray: TIntegrationItem[];
|
||||
surveys: TSurvey[];
|
||||
airtableIntegration: TIntegrationAirtable;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
} & EditModeProps;
|
||||
|
||||
export type IntegrationModalInputs = {
|
||||
@@ -79,7 +77,6 @@ export const AddIntegrationModal = ({
|
||||
airtableIntegration,
|
||||
isEditMode,
|
||||
defaultData,
|
||||
contactAttributeKeys,
|
||||
}: AddIntegrationModalProps) => {
|
||||
const t = useTranslations();
|
||||
const router = useRouter();
|
||||
@@ -323,38 +320,34 @@ export const AddIntegrationModal = ({
|
||||
<Label htmlFor="Surveys">{t("common.questions")}</Label>
|
||||
<div className="mt-1 max-h-[15vh] overflow-y-auto rounded-lg border border-slate-200">
|
||||
<div className="grid content-center rounded-lg bg-slate-50 p-3 text-left text-sm text-slate-900">
|
||||
{replaceHeadlineRecall(selectedSurvey, "default", contactAttributeKeys)?.questions.map(
|
||||
(question) => (
|
||||
<Controller
|
||||
key={question.id}
|
||||
control={control}
|
||||
name={"questions"}
|
||||
render={({ field }) => (
|
||||
<div className="my-1 flex items-center space-x-2">
|
||||
<label htmlFor={question.id} className="flex cursor-pointer items-center">
|
||||
<Checkbox
|
||||
type="button"
|
||||
id={question.id}
|
||||
value={question.id}
|
||||
className="bg-white"
|
||||
checked={field.value?.includes(question.id)}
|
||||
onCheckedChange={(checked) => {
|
||||
return checked
|
||||
? field.onChange([...field.value, question.id])
|
||||
: field.onChange(
|
||||
field.value?.filter((value) => value !== question.id)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<span className="ml-2">
|
||||
{getLocalizedValue(question.headline, "default")}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
{replaceHeadlineRecall(selectedSurvey, "default")?.questions.map((question) => (
|
||||
<Controller
|
||||
key={question.id}
|
||||
control={control}
|
||||
name={"questions"}
|
||||
render={({ field }) => (
|
||||
<div className="my-1 flex items-center space-x-2">
|
||||
<label htmlFor={question.id} className="flex cursor-pointer items-center">
|
||||
<Checkbox
|
||||
type="button"
|
||||
id={question.id}
|
||||
value={question.id}
|
||||
className="bg-white"
|
||||
checked={field.value?.includes(question.id)}
|
||||
onCheckedChange={(checked) => {
|
||||
return checked
|
||||
? field.onChange([...field.value, question.id])
|
||||
: field.onChange(field.value?.filter((value) => value !== question.id));
|
||||
}}
|
||||
/>
|
||||
<span className="ml-2">
|
||||
{getLocalizedValue(question.headline, "default")}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,6 @@ import { authorize } from "@/app/(app)/environments/[environmentId]/integrations
|
||||
import airtableLogo from "@/images/airtableLogo.svg";
|
||||
import { ConnectIntegration } from "@/modules/ui/components/connect-integration";
|
||||
import { useState } from "react";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TIntegrationItem } from "@formbricks/types/integration";
|
||||
import { TIntegrationAirtable } from "@formbricks/types/integration/airtable";
|
||||
@@ -20,7 +19,6 @@ interface AirtableWrapperProps {
|
||||
environment: TEnvironment;
|
||||
isEnabled: boolean;
|
||||
webAppUrl: string;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -32,7 +30,6 @@ export const AirtableWrapper = ({
|
||||
environment,
|
||||
isEnabled,
|
||||
webAppUrl,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: AirtableWrapperProps) => {
|
||||
const [isConnected, setIsConnected] = useState(
|
||||
@@ -55,7 +52,6 @@ export const AirtableWrapper = ({
|
||||
airtableIntegration={airtableIntegration}
|
||||
setIsConnected={setIsConnected}
|
||||
surveys={surveys}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
) : (
|
||||
|
||||
@@ -14,7 +14,6 @@ import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { timeSince } from "@formbricks/lib/time";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TIntegrationItem } from "@formbricks/types/integration";
|
||||
import { TIntegrationAirtable } from "@formbricks/types/integration/airtable";
|
||||
@@ -28,7 +27,6 @@ interface ManageIntegrationProps {
|
||||
setIsConnected: (data: boolean) => void;
|
||||
surveys: TSurvey[];
|
||||
airtableArray: TIntegrationItem[];
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -40,15 +38,7 @@ const tableHeaders = [
|
||||
];
|
||||
|
||||
export const ManageIntegration = (props: ManageIntegrationProps) => {
|
||||
const {
|
||||
airtableIntegration,
|
||||
environment,
|
||||
environmentId,
|
||||
setIsConnected,
|
||||
surveys,
|
||||
airtableArray,
|
||||
contactAttributeKeys,
|
||||
} = props;
|
||||
const { airtableIntegration, environment, environmentId, setIsConnected, surveys, airtableArray } = props;
|
||||
const t = useTranslations();
|
||||
const [isDeleting, setisDeleting] = useState(false);
|
||||
const [isDeleteIntegrationModalOpen, setIsDeleteIntegrationModalOpen] = useState(false);
|
||||
@@ -175,7 +165,6 @@ export const ManageIntegration = (props: ManageIntegrationProps) => {
|
||||
environmentId={environmentId}
|
||||
surveys={surveys}
|
||||
airtableIntegration={airtableIntegration}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
{...data}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { AirtableWrapper } from "@/app/(app)/environments/[environmentId]/integrations/airtable/components/AirtableWrapper";
|
||||
import { getContactAttributeKeys } from "@/app/(app)/environments/[environmentId]/integrations/lib/contact-attribute-key";
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { getProjectPermissionByUserId } from "@/modules/ee/teams/lib/roles";
|
||||
import { getTeamPermissionFlags } from "@/modules/ee/teams/utils/teams";
|
||||
@@ -25,12 +24,11 @@ const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const t = await getTranslations();
|
||||
const isEnabled = !!AIRTABLE_CLIENT_ID;
|
||||
const [session, surveys, integrations, environment, contactAttributeKeys] = await Promise.all([
|
||||
const [session, surveys, integrations, environment] = await Promise.all([
|
||||
getServerSession(authOptions),
|
||||
getSurveys(params.environmentId),
|
||||
getIntegrations(params.environmentId),
|
||||
getEnvironment(params.environmentId),
|
||||
getContactAttributeKeys(params.environmentId),
|
||||
]);
|
||||
|
||||
if (!session) {
|
||||
@@ -85,7 +83,6 @@ const Page = async (props) => {
|
||||
surveys={surveys}
|
||||
environment={environment}
|
||||
webAppUrl={WEBAPP_URL}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,6 @@ import { useForm } from "react-hook-form";
|
||||
import toast from "react-hot-toast";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TIntegrationGoogleSheets,
|
||||
TIntegrationGoogleSheetsConfigData,
|
||||
@@ -35,7 +34,6 @@ interface AddIntegrationModalProps {
|
||||
setOpen: (v: boolean) => void;
|
||||
googleSheetIntegration: TIntegrationGoogleSheets;
|
||||
selectedIntegration?: (TIntegrationGoogleSheetsConfigData & { index: number }) | null;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
}
|
||||
|
||||
export const AddIntegrationModal = ({
|
||||
@@ -45,7 +43,6 @@ export const AddIntegrationModal = ({
|
||||
setOpen,
|
||||
googleSheetIntegration,
|
||||
selectedIntegration,
|
||||
contactAttributeKeys,
|
||||
}: AddIntegrationModalProps) => {
|
||||
const t = useTranslations();
|
||||
const integrationData: TIntegrationGoogleSheetsConfigData = {
|
||||
@@ -250,11 +247,7 @@ export const AddIntegrationModal = ({
|
||||
<Label htmlFor="Surveys">{t("common.questions")}</Label>
|
||||
<div className="mt-1 max-h-[15vh] overflow-y-auto overflow-x-hidden rounded-lg border border-slate-200">
|
||||
<div className="grid content-center rounded-lg bg-slate-50 p-3 text-left text-sm text-slate-900">
|
||||
{replaceHeadlineRecall(
|
||||
selectedSurvey,
|
||||
"default",
|
||||
contactAttributeKeys
|
||||
)?.questions.map((question) => (
|
||||
{replaceHeadlineRecall(selectedSurvey, "default")?.questions.map((question) => (
|
||||
<div key={question.id} className="my-1 flex items-center space-x-2">
|
||||
<label htmlFor={question.id} className="flex cursor-pointer items-center">
|
||||
<Checkbox
|
||||
|
||||
@@ -5,7 +5,6 @@ import { authorize } from "@/app/(app)/environments/[environmentId]/integrations
|
||||
import googleSheetLogo from "@/images/googleSheetsLogo.png";
|
||||
import { ConnectIntegration } from "@/modules/ui/components/connect-integration";
|
||||
import { useState } from "react";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import {
|
||||
TIntegrationGoogleSheets,
|
||||
@@ -21,7 +20,6 @@ interface GoogleSheetWrapperProps {
|
||||
surveys: TSurvey[];
|
||||
googleSheetIntegration?: TIntegrationGoogleSheets;
|
||||
webAppUrl: string;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -31,7 +29,6 @@ export const GoogleSheetWrapper = ({
|
||||
surveys,
|
||||
googleSheetIntegration,
|
||||
webAppUrl,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: GoogleSheetWrapperProps) => {
|
||||
const [isConnected, setIsConnected] = useState(
|
||||
@@ -61,7 +58,6 @@ export const GoogleSheetWrapper = ({
|
||||
setOpen={setModalOpen}
|
||||
googleSheetIntegration={googleSheetIntegration}
|
||||
selectedIntegration={selectedIntegration}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
/>
|
||||
<ManageIntegration
|
||||
environment={environment}
|
||||
|
||||
@@ -22,18 +22,16 @@ import { getProjectByEnvironmentId } from "@formbricks/lib/project/service";
|
||||
import { getSurveys } from "@formbricks/lib/survey/service";
|
||||
import { findMatchingLocale } from "@formbricks/lib/utils/locale";
|
||||
import { TIntegrationGoogleSheets } from "@formbricks/types/integration/google-sheet";
|
||||
import { getContactAttributeKeys } from "../lib/contact-attribute-key";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const t = await getTranslations();
|
||||
const isEnabled = !!(GOOGLE_SHEETS_CLIENT_ID && GOOGLE_SHEETS_CLIENT_SECRET && GOOGLE_SHEETS_REDIRECT_URL);
|
||||
const [session, surveys, integrations, environment, contactAttributeKeys] = await Promise.all([
|
||||
const [session, surveys, integrations, environment] = await Promise.all([
|
||||
getServerSession(authOptions),
|
||||
getSurveys(params.environmentId),
|
||||
getIntegrations(params.environmentId),
|
||||
getEnvironment(params.environmentId),
|
||||
getContactAttributeKeys(params.environmentId),
|
||||
]);
|
||||
|
||||
if (!session) {
|
||||
@@ -81,7 +79,6 @@ const Page = async (props) => {
|
||||
surveys={surveys}
|
||||
googleSheetIntegration={googleSheetIntegration}
|
||||
webAppUrl={WEBAPP_URL}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,6 @@ import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { structuredClone } from "@formbricks/lib/pollyfills/structuredClone";
|
||||
import { getQuestionTypes } from "@formbricks/lib/utils/questions";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TIntegrationInput } from "@formbricks/types/integration";
|
||||
import {
|
||||
TIntegrationNotion,
|
||||
@@ -37,7 +36,6 @@ interface AddIntegrationModalProps {
|
||||
notionIntegration: TIntegrationNotion;
|
||||
databases: TIntegrationNotionDatabase[];
|
||||
selectedIntegration: (TIntegrationNotionConfigData & { index: number }) | null;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -49,7 +47,6 @@ export const AddIntegrationModal = ({
|
||||
notionIntegration,
|
||||
databases,
|
||||
selectedIntegration,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: AddIntegrationModalProps) => {
|
||||
const t = useTranslations();
|
||||
@@ -116,7 +113,7 @@ export const AddIntegrationModal = ({
|
||||
|
||||
const questionItems = useMemo(() => {
|
||||
const questions = selectedSurvey
|
||||
? replaceHeadlineRecall(selectedSurvey, "default", contactAttributeKeys)?.questions.map((q) => ({
|
||||
? replaceHeadlineRecall(selectedSurvey, "default")?.questions.map((q) => ({
|
||||
id: q.id,
|
||||
name: getLocalizedValue(q.headline, "default"),
|
||||
type: q.type,
|
||||
|
||||
@@ -5,7 +5,6 @@ import { ManageIntegration } from "@/app/(app)/environments/[environmentId]/inte
|
||||
import notionLogo from "@/images/notion.png";
|
||||
import { ConnectIntegration } from "@/modules/ui/components/connect-integration";
|
||||
import { useState } from "react";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import {
|
||||
TIntegrationNotion,
|
||||
@@ -23,7 +22,6 @@ interface NotionWrapperProps {
|
||||
webAppUrl: string;
|
||||
surveys: TSurvey[];
|
||||
databasesArray: TIntegrationNotionDatabase[];
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -34,7 +32,6 @@ export const NotionWrapper = ({
|
||||
webAppUrl,
|
||||
surveys,
|
||||
databasesArray,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: NotionWrapperProps) => {
|
||||
const [isModalOpen, setModalOpen] = useState(false);
|
||||
@@ -65,7 +62,6 @@ export const NotionWrapper = ({
|
||||
notionIntegration={notionIntegration}
|
||||
databases={databasesArray}
|
||||
selectedIntegration={selectedIntegration}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<ManageIntegration
|
||||
|
||||
@@ -24,7 +24,6 @@ import { getProjectByEnvironmentId } from "@formbricks/lib/project/service";
|
||||
import { getSurveys } from "@formbricks/lib/survey/service";
|
||||
import { findMatchingLocale } from "@formbricks/lib/utils/locale";
|
||||
import { TIntegrationNotion, TIntegrationNotionDatabase } from "@formbricks/types/integration/notion";
|
||||
import { getContactAttributeKeys } from "../lib/contact-attribute-key";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
@@ -35,12 +34,11 @@ const Page = async (props) => {
|
||||
NOTION_AUTH_URL &&
|
||||
NOTION_REDIRECT_URI
|
||||
);
|
||||
const [session, surveys, notionIntegration, environment, contactAttributeKeys] = await Promise.all([
|
||||
const [session, surveys, notionIntegration, environment] = await Promise.all([
|
||||
getServerSession(authOptions),
|
||||
getSurveys(params.environmentId),
|
||||
getIntegrationByType(params.environmentId, "notion"),
|
||||
getEnvironment(params.environmentId),
|
||||
getContactAttributeKeys(params.environmentId),
|
||||
]);
|
||||
|
||||
if (!session) {
|
||||
@@ -89,7 +87,6 @@ const Page = async (props) => {
|
||||
notionIntegration={notionIntegration as TIntegrationNotion}
|
||||
webAppUrl={WEBAPP_URL}
|
||||
databasesArray={databasesArray}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</PageContentWrapper>
|
||||
|
||||
@@ -15,7 +15,6 @@ import { useForm } from "react-hook-form";
|
||||
import toast from "react-hot-toast";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TIntegrationItem } from "@formbricks/types/integration";
|
||||
import {
|
||||
TIntegrationSlack,
|
||||
@@ -32,7 +31,6 @@ interface AddChannelMappingModalProps {
|
||||
slackIntegration: TIntegrationSlack;
|
||||
channels: TIntegrationItem[];
|
||||
selectedIntegration?: (TIntegrationSlackConfigData & { index: number }) | null;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
}
|
||||
|
||||
export const AddChannelMappingModal = ({
|
||||
@@ -43,7 +41,6 @@ export const AddChannelMappingModal = ({
|
||||
channels,
|
||||
slackIntegration,
|
||||
selectedIntegration,
|
||||
contactAttributeKeys,
|
||||
}: AddChannelMappingModalProps) => {
|
||||
const { handleSubmit } = useForm();
|
||||
const t = useTranslations();
|
||||
@@ -257,11 +254,7 @@ export const AddChannelMappingModal = ({
|
||||
<Label htmlFor="Surveys">{t("common.questions")}</Label>
|
||||
<div className="mt-1 max-h-[15vh] overflow-y-auto rounded-lg border border-slate-200">
|
||||
<div className="grid content-center rounded-lg bg-slate-50 p-3 text-left text-sm text-slate-900">
|
||||
{replaceHeadlineRecall(
|
||||
selectedSurvey,
|
||||
"default",
|
||||
contactAttributeKeys
|
||||
)?.questions?.map((question) => (
|
||||
{replaceHeadlineRecall(selectedSurvey, "default")?.questions?.map((question) => (
|
||||
<div key={question.id} className="my-1 flex items-center space-x-2">
|
||||
<label htmlFor={question.id} className="flex cursor-pointer items-center">
|
||||
<Checkbox
|
||||
|
||||
@@ -7,7 +7,6 @@ import { authorize } from "@/app/(app)/environments/[environmentId]/integrations
|
||||
import slackLogo from "@/images/slacklogo.png";
|
||||
import { ConnectIntegration } from "@/modules/ui/components/connect-integration";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TIntegrationItem } from "@formbricks/types/integration";
|
||||
import { TIntegrationSlack, TIntegrationSlackConfigData } from "@formbricks/types/integration/slack";
|
||||
@@ -20,7 +19,6 @@ interface SlackWrapperProps {
|
||||
surveys: TSurvey[];
|
||||
slackIntegration?: TIntegrationSlack;
|
||||
webAppUrl: string;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -30,7 +28,6 @@ export const SlackWrapper = ({
|
||||
surveys,
|
||||
slackIntegration,
|
||||
webAppUrl,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: SlackWrapperProps) => {
|
||||
const [isConnected, setIsConnected] = useState(slackIntegration ? slackIntegration.config?.key : false);
|
||||
@@ -79,7 +76,6 @@ export const SlackWrapper = ({
|
||||
channels={slackChannels}
|
||||
slackIntegration={slackIntegration}
|
||||
selectedIntegration={selectedIntegration}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
/>
|
||||
<ManageIntegration
|
||||
environment={environment}
|
||||
|
||||
@@ -17,19 +17,17 @@ import { getProjectByEnvironmentId } from "@formbricks/lib/project/service";
|
||||
import { getSurveys } from "@formbricks/lib/survey/service";
|
||||
import { findMatchingLocale } from "@formbricks/lib/utils/locale";
|
||||
import { TIntegrationSlack } from "@formbricks/types/integration/slack";
|
||||
import { getContactAttributeKeys } from "../lib/contact-attribute-key";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const isEnabled = !!(SLACK_CLIENT_ID && SLACK_CLIENT_SECRET);
|
||||
|
||||
const t = await getTranslations();
|
||||
const [session, surveys, slackIntegration, environment, contactAttributeKeys] = await Promise.all([
|
||||
const [session, surveys, slackIntegration, environment] = await Promise.all([
|
||||
getServerSession(authOptions),
|
||||
getSurveys(params.environmentId),
|
||||
getIntegrationByType(params.environmentId, "slack"),
|
||||
getEnvironment(params.environmentId),
|
||||
getContactAttributeKeys(params.environmentId),
|
||||
]);
|
||||
|
||||
if (!session) {
|
||||
@@ -74,7 +72,6 @@ const Page = async (props) => {
|
||||
surveys={surveys}
|
||||
slackIntegration={slackIntegration as TIntegrationSlack}
|
||||
webAppUrl={WEBAPP_URL}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
import { useParams, useSearchParams } from "next/navigation";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TResponse } from "@formbricks/types/responses";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
@@ -29,7 +28,6 @@ interface ResponsePageProps {
|
||||
surveyId: string;
|
||||
webAppUrl: string;
|
||||
user?: TUser;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
environmentTags: TTag[];
|
||||
responsesPerPage: number;
|
||||
locale: TUserLocale;
|
||||
@@ -42,7 +40,6 @@ export const ResponsePage = ({
|
||||
surveyId,
|
||||
webAppUrl,
|
||||
user,
|
||||
contactAttributeKeys,
|
||||
environmentTags,
|
||||
responsesPerPage,
|
||||
locale,
|
||||
@@ -112,8 +109,8 @@ export const ResponsePage = ({
|
||||
};
|
||||
|
||||
const surveyMemoized = useMemo(() => {
|
||||
return replaceHeadlineRecall(survey, "default", contactAttributeKeys);
|
||||
}, [contactAttributeKeys, survey]);
|
||||
return replaceHeadlineRecall(survey, "default");
|
||||
}, [survey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!searchParams?.get("referer")) {
|
||||
|
||||
@@ -141,7 +141,7 @@ const getQuestionColumnsData = (
|
||||
<span className="h-4 w-4">{QUESTIONS_ICON_MAP[question.type]}</span>
|
||||
<span className="truncate">
|
||||
{getLocalizedValue(
|
||||
recallToHeadline(question.headline, survey, false, "default", []),
|
||||
recallToHeadline(question.headline, survey, false, "default"),
|
||||
"default"
|
||||
)}
|
||||
</span>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { EnableInsightsBanner } from "@/app/(app)/environments/[environmentId]/s
|
||||
import { SurveyAnalysisCTA } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SurveyAnalysisCTA";
|
||||
import { needsInsightsGeneration } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/lib/utils";
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { getContactAttributeKeys } from "@/modules/ee/contacts/lib/contacts";
|
||||
import { getIsAIEnabled } from "@/modules/ee/license-check/lib/utils";
|
||||
import { getProjectPermissionByUserId } from "@/modules/ee/teams/lib/roles";
|
||||
import { getTeamPermissionFlags } from "@/modules/ee/teams/utils/teams";
|
||||
@@ -35,10 +34,9 @@ const Page = async (props) => {
|
||||
if (!session) {
|
||||
throw new Error(t("common.session_not_found"));
|
||||
}
|
||||
const [survey, environment, contactAttributeKeys] = await Promise.all([
|
||||
const [survey, environment] = await Promise.all([
|
||||
getSurvey(params.surveyId),
|
||||
getEnvironment(params.environmentId),
|
||||
getContactAttributeKeys(params.environmentId),
|
||||
]);
|
||||
|
||||
if (!environment) {
|
||||
@@ -112,7 +110,6 @@ const Page = async (props) => {
|
||||
webAppUrl={WEBAPP_URL}
|
||||
environmentTags={tags}
|
||||
user={user}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
responsesPerPage={RESPONSES_PER_PAGE}
|
||||
locale={locale}
|
||||
isReadOnly={isReadOnly}
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { timeSince } from "@formbricks/lib/time";
|
||||
import { getContactIdentifier } from "@formbricks/lib/utils/contact";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionSummaryAddress } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
@@ -13,26 +12,14 @@ interface AddressSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryAddress;
|
||||
environmentId: string;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
export const AddressSummary = ({
|
||||
questionSummary,
|
||||
environmentId,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: AddressSummaryProps) => {
|
||||
export const AddressSummary = ({ questionSummary, environmentId, survey, locale }: AddressSummaryProps) => {
|
||||
const t = useTranslations();
|
||||
return (
|
||||
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} locale={locale} />
|
||||
<div>
|
||||
<div className="grid h-10 grid-cols-4 items-center border-y border-slate-200 bg-slate-100 text-sm font-bold text-slate-600">
|
||||
<div className="pl-4 md:pl-6">{t("common.user")}</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { ProgressBar } from "@/modules/ui/components/progress-bar";
|
||||
import { InboxIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionSummaryCta } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { convertFloatToNDecimal } from "../lib/utils";
|
||||
@@ -10,11 +9,10 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
interface CTASummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryCta;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
export const CTASummary = ({ questionSummary, survey, contactAttributeKeys, locale }: CTASummaryProps) => {
|
||||
export const CTASummary = ({ questionSummary, survey, locale }: CTASummaryProps) => {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
@@ -23,7 +21,6 @@ export const CTASummary = ({ questionSummary, survey, contactAttributeKeys, loca
|
||||
survey={survey}
|
||||
questionSummary={questionSummary}
|
||||
showResponses={false}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
additionalInfo={
|
||||
<>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { convertFloatToNDecimal } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/lib/utils";
|
||||
import { ProgressBar } from "@/modules/ui/components/progress-bar";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionSummaryCal } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
@@ -10,21 +9,15 @@ interface CalSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryCal;
|
||||
environmentId: string;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
export const CalSummary = ({ questionSummary, survey, contactAttributeKeys, locale }: CalSummaryProps) => {
|
||||
export const CalSummary = ({ questionSummary, survey, locale }: CalSummaryProps) => {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} locale={locale} />
|
||||
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
|
||||
<div>
|
||||
<div className="text flex justify-between px-2 pb-2">
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ProgressBar } from "@/modules/ui/components/progress-bar";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TI18nString,
|
||||
TSurvey,
|
||||
@@ -15,7 +14,6 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
interface ConsentSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryConsent;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
setFilter: (
|
||||
questionId: TSurveyQuestionId,
|
||||
label: TI18nString,
|
||||
@@ -26,13 +24,7 @@ interface ConsentSummaryProps {
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
export const ConsentSummary = ({
|
||||
questionSummary,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
setFilter,
|
||||
locale,
|
||||
}: ConsentSummaryProps) => {
|
||||
export const ConsentSummary = ({ questionSummary, survey, setFilter, locale }: ConsentSummaryProps) => {
|
||||
const t = useTranslations();
|
||||
const summaryItems = [
|
||||
{
|
||||
@@ -48,12 +40,7 @@ export const ConsentSummary = ({
|
||||
];
|
||||
return (
|
||||
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} locale={locale} />
|
||||
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
|
||||
{summaryItems.map((summaryItem) => {
|
||||
return (
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { timeSince } from "@formbricks/lib/time";
|
||||
import { getContactIdentifier } from "@formbricks/lib/utils/contact";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionSummaryContactInfo } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
@@ -13,7 +12,6 @@ interface ContactInfoSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryContactInfo;
|
||||
environmentId: string;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -21,18 +19,12 @@ export const ContactInfoSummary = ({
|
||||
questionSummary,
|
||||
environmentId,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: ContactInfoSummaryProps) => {
|
||||
const t = useTranslations();
|
||||
return (
|
||||
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} locale={locale} />
|
||||
<div>
|
||||
<div className="grid h-10 grid-cols-4 items-center border-y border-slate-200 bg-slate-100 text-sm font-bold text-slate-600">
|
||||
<div className="pl-4 md:pl-6">{t("common.user")}</div>
|
||||
|
||||
@@ -6,7 +6,6 @@ import { useState } from "react";
|
||||
import { timeSince } from "@formbricks/lib/time";
|
||||
import { getContactIdentifier } from "@formbricks/lib/utils/contact";
|
||||
import { formatDateWithOrdinal } from "@formbricks/lib/utils/datetime";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionSummaryDate } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
@@ -15,7 +14,6 @@ interface DateQuestionSummary {
|
||||
questionSummary: TSurveyQuestionSummaryDate;
|
||||
environmentId: string;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -23,7 +21,6 @@ export const DateQuestionSummary = ({
|
||||
questionSummary,
|
||||
environmentId,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: DateQuestionSummary) => {
|
||||
const t = useTranslations();
|
||||
@@ -38,12 +35,7 @@ export const DateQuestionSummary = ({
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} locale={locale} />
|
||||
<div className="">
|
||||
<div className="grid h-10 grid-cols-4 items-center border-y border-slate-200 bg-slate-100 text-sm font-bold text-slate-600">
|
||||
<div className="pl-4 md:pl-6">{t("common.user")}</div>
|
||||
|
||||
@@ -7,7 +7,6 @@ import { useState } from "react";
|
||||
import { getOriginalFileNameFromUrl } from "@formbricks/lib/storage/utils";
|
||||
import { timeSince } from "@formbricks/lib/time";
|
||||
import { getContactIdentifier } from "@formbricks/lib/utils/contact";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionSummaryFileUpload } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
@@ -16,7 +15,6 @@ interface FileUploadSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryFileUpload;
|
||||
environmentId: string;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -24,7 +22,6 @@ export const FileUploadSummary = ({
|
||||
questionSummary,
|
||||
environmentId,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: FileUploadSummaryProps) => {
|
||||
const [visibleResponses, setVisibleResponses] = useState(10);
|
||||
@@ -38,12 +35,7 @@ export const FileUploadSummary = ({
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} locale={locale} />
|
||||
<div className="">
|
||||
<div className="grid h-10 grid-cols-4 items-center border-y border-slate-200 bg-slate-100 text-sm font-bold text-slate-600">
|
||||
<div className="pl-4 md:pl-6">{t("common.user")}</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { TooltipRenderer } from "@/modules/ui/components/tooltip";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TI18nString,
|
||||
TSurvey,
|
||||
@@ -14,7 +13,6 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
interface MatrixQuestionSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryMatrix;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
setFilter: (
|
||||
questionId: TSurveyQuestionId,
|
||||
label: TI18nString,
|
||||
@@ -28,7 +26,6 @@ interface MatrixQuestionSummaryProps {
|
||||
export const MatrixQuestionSummary = ({
|
||||
questionSummary,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
setFilter,
|
||||
locale,
|
||||
}: MatrixQuestionSummaryProps) => {
|
||||
@@ -54,12 +51,7 @@ export const MatrixQuestionSummary = ({
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} locale={locale} />
|
||||
<div className="overflow-x-auto p-6">
|
||||
{/* Summary Table */}
|
||||
<table className="mx-auto border-collapse cursor-default text-left">
|
||||
|
||||
@@ -6,7 +6,6 @@ import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
import { getContactIdentifier } from "@formbricks/lib/utils/contact";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TI18nString,
|
||||
TSurvey,
|
||||
@@ -24,7 +23,6 @@ interface MultipleChoiceSummaryProps {
|
||||
environmentId: string;
|
||||
surveyType: TSurveyType;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
setFilter: (
|
||||
questionId: TSurveyQuestionId,
|
||||
label: TI18nString,
|
||||
@@ -40,7 +38,6 @@ export const MultipleChoiceSummary = ({
|
||||
environmentId,
|
||||
surveyType,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
setFilter,
|
||||
locale,
|
||||
}: MultipleChoiceSummaryProps) => {
|
||||
@@ -73,7 +70,6 @@ export const MultipleChoiceSummary = ({
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
additionalInfo={
|
||||
questionSummary.type === "multipleChoiceMulti" ? (
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { HalfCircle, ProgressBar } from "@/modules/ui/components/progress-bar";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TI18nString,
|
||||
TSurvey,
|
||||
@@ -15,7 +14,6 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
interface NPSSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryNps;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
setFilter: (
|
||||
questionId: TSurveyQuestionId,
|
||||
@@ -26,13 +24,7 @@ interface NPSSummaryProps {
|
||||
) => void;
|
||||
}
|
||||
|
||||
export const NPSSummary = ({
|
||||
questionSummary,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
setFilter,
|
||||
locale,
|
||||
}: NPSSummaryProps) => {
|
||||
export const NPSSummary = ({ questionSummary, survey, setFilter, locale }: NPSSummaryProps) => {
|
||||
const t = useTranslations();
|
||||
const applyFilter = (group: string) => {
|
||||
const filters = {
|
||||
@@ -69,12 +61,7 @@ export const NPSSummary = ({
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} locale={locale} />
|
||||
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
|
||||
{["promoters", "passives", "detractors", "dismissed"].map((group) => (
|
||||
<div className="cursor-pointer hover:opacity-80" key={group} onClick={() => applyFilter(group)}>
|
||||
|
||||
@@ -8,7 +8,6 @@ import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
import { timeSince } from "@formbricks/lib/time";
|
||||
import { getContactIdentifier } from "@formbricks/lib/utils/contact";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionSummaryOpenText } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
@@ -17,7 +16,6 @@ interface OpenTextSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryOpenText;
|
||||
environmentId: string;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
isAIEnabled: boolean;
|
||||
documentsPerPage?: number;
|
||||
locale: TUserLocale;
|
||||
@@ -27,7 +25,6 @@ export const OpenTextSummary = ({
|
||||
questionSummary,
|
||||
environmentId,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
isAIEnabled,
|
||||
documentsPerPage,
|
||||
locale,
|
||||
@@ -64,7 +61,6 @@ export const OpenTextSummary = ({
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
additionalInfo={
|
||||
isAIEnabled && questionSummary.insightsEnabled === false ? (
|
||||
|
||||
@@ -2,7 +2,6 @@ import { ProgressBar } from "@/modules/ui/components/progress-bar";
|
||||
import { InboxIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Image from "next/image";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TI18nString,
|
||||
TSurvey,
|
||||
@@ -17,7 +16,6 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
interface PictureChoiceSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryPictureSelection;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
setFilter: (
|
||||
questionId: TSurveyQuestionId,
|
||||
label: TI18nString,
|
||||
@@ -31,7 +29,6 @@ interface PictureChoiceSummaryProps {
|
||||
export const PictureChoiceSummary = ({
|
||||
questionSummary,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
setFilter,
|
||||
locale,
|
||||
}: PictureChoiceSummaryProps) => {
|
||||
@@ -42,7 +39,6 @@ export const PictureChoiceSummary = ({
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
additionalInfo={
|
||||
questionSummary.question.allowMulti ? (
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { getQuestionTypes } from "@formbricks/lib/utils/questions";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionSummary } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -12,7 +11,6 @@ interface HeadProps {
|
||||
showResponses?: boolean;
|
||||
additionalInfo?: JSX.Element;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -21,7 +19,6 @@ export const QuestionSummaryHeader = ({
|
||||
additionalInfo,
|
||||
showResponses = true,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: HeadProps) => {
|
||||
const questionType = getQuestionTypes(locale).find((type) => type.id === questionSummary.question.type);
|
||||
@@ -50,13 +47,7 @@ export const QuestionSummaryHeader = ({
|
||||
<div className={"align-center flex justify-between gap-4"}>
|
||||
<h3 className="pb-1 text-lg font-semibold text-slate-900 md:text-xl">
|
||||
{formatTextWithSlashes(
|
||||
recallToHeadline(
|
||||
questionSummary.question.headline,
|
||||
survey,
|
||||
true,
|
||||
"default",
|
||||
contactAttributeKeys
|
||||
)["default"]
|
||||
recallToHeadline(questionSummary.question.headline, survey, true, "default")["default"]
|
||||
)}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useTranslations } from "next-intl";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionSummaryRanking, TSurveyType } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { convertFloatToNDecimal } from "../lib/utils";
|
||||
@@ -9,17 +8,10 @@ interface RankingSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryRanking;
|
||||
surveyType: TSurveyType;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
export const RankingSummary = ({
|
||||
questionSummary,
|
||||
surveyType,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: RankingSummaryProps) => {
|
||||
export const RankingSummary = ({ questionSummary, surveyType, survey, locale }: RankingSummaryProps) => {
|
||||
// sort by count and transform to array
|
||||
const t = useTranslations();
|
||||
const results = Object.values(questionSummary.choices).sort((a, b) => {
|
||||
@@ -28,12 +20,7 @@ export const RankingSummary = ({
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} locale={locale} />
|
||||
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
|
||||
{results.map((result, resultsIdx) => (
|
||||
<div key={result.value} className="group cursor-pointer">
|
||||
|
||||
@@ -4,7 +4,6 @@ import { RatingResponse } from "@/modules/ui/components/rating-response";
|
||||
import { CircleSlash2, SmileIcon, StarIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useMemo } from "react";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TI18nString,
|
||||
TSurvey,
|
||||
@@ -18,7 +17,6 @@ import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
|
||||
interface RatingSummaryProps {
|
||||
questionSummary: TSurveyQuestionSummaryRating;
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
setFilter: (
|
||||
questionId: TSurveyQuestionId,
|
||||
label: TI18nString,
|
||||
@@ -29,13 +27,7 @@ interface RatingSummaryProps {
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
export const RatingSummary = ({
|
||||
questionSummary,
|
||||
survey,
|
||||
contactAttributeKeys,
|
||||
setFilter,
|
||||
locale,
|
||||
}: RatingSummaryProps) => {
|
||||
export const RatingSummary = ({ questionSummary, survey, setFilter, locale }: RatingSummaryProps) => {
|
||||
const t = useTranslations();
|
||||
const getIconBasedOnScale = useMemo(() => {
|
||||
const scale = questionSummary.question.scale;
|
||||
@@ -49,7 +41,6 @@ export const RatingSummary = ({
|
||||
<QuestionSummaryHeader
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
additionalInfo={
|
||||
<div className="flex items-center space-x-2 rounded-lg bg-slate-100 p-2">
|
||||
|
||||
@@ -3,16 +3,14 @@ import { TimerIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getQuestionIcon } from "@formbricks/lib/utils/questions";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyQuestionType, TSurveySummary } from "@formbricks/types/surveys/types";
|
||||
|
||||
interface SummaryDropOffsProps {
|
||||
dropOff: TSurveySummary["dropOff"];
|
||||
survey: TSurvey;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
}
|
||||
|
||||
export const SummaryDropOffs = ({ dropOff, survey, contactAttributeKeys }: SummaryDropOffsProps) => {
|
||||
export const SummaryDropOffs = ({ dropOff, survey }: SummaryDropOffsProps) => {
|
||||
const t = useTranslations();
|
||||
const getIcon = (questionType: TSurveyQuestionType) => {
|
||||
const Icon = getQuestionIcon(questionType);
|
||||
@@ -71,8 +69,7 @@ export const SummaryDropOffs = ({ dropOff, survey, contactAttributeKeys }: Summa
|
||||
},
|
||||
survey,
|
||||
true,
|
||||
"default",
|
||||
contactAttributeKeys
|
||||
"default"
|
||||
)["default"]
|
||||
)}
|
||||
</p>
|
||||
|
||||
@@ -26,7 +26,6 @@ import { SkeletonLoader } from "@/modules/ui/components/skeleton-loader";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TI18nString, TSurveyQuestionId, TSurveySummary } from "@formbricks/types/surveys/types";
|
||||
import { TSurveyQuestionTypeEnum } from "@formbricks/types/surveys/types";
|
||||
@@ -40,7 +39,6 @@ interface SummaryListProps {
|
||||
environment: TEnvironment;
|
||||
survey: TSurvey;
|
||||
totalResponseCount: number;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
isAIEnabled: boolean;
|
||||
documentsPerPage?: number;
|
||||
locale: TUserLocale;
|
||||
@@ -52,7 +50,6 @@ export const SummaryList = ({
|
||||
responseCount,
|
||||
survey,
|
||||
totalResponseCount,
|
||||
contactAttributeKeys,
|
||||
isAIEnabled,
|
||||
documentsPerPage,
|
||||
locale,
|
||||
@@ -137,7 +134,6 @@ export const SummaryList = ({
|
||||
questionSummary={questionSummary}
|
||||
environmentId={environment.id}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
isAIEnabled={isAIEnabled}
|
||||
documentsPerPage={documentsPerPage}
|
||||
locale={locale}
|
||||
@@ -155,7 +151,6 @@ export const SummaryList = ({
|
||||
environmentId={environment.id}
|
||||
surveyType={survey.type}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
setFilter={setFilter}
|
||||
locale={locale}
|
||||
/>
|
||||
@@ -167,7 +162,6 @@ export const SummaryList = ({
|
||||
key={questionSummary.question.id}
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
setFilter={setFilter}
|
||||
locale={locale}
|
||||
/>
|
||||
@@ -179,7 +173,6 @@ export const SummaryList = ({
|
||||
key={questionSummary.question.id}
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
);
|
||||
@@ -190,7 +183,6 @@ export const SummaryList = ({
|
||||
key={questionSummary.question.id}
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
setFilter={setFilter}
|
||||
locale={locale}
|
||||
/>
|
||||
@@ -202,7 +194,6 @@ export const SummaryList = ({
|
||||
key={questionSummary.question.id}
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
setFilter={setFilter}
|
||||
locale={locale}
|
||||
/>
|
||||
@@ -214,7 +205,6 @@ export const SummaryList = ({
|
||||
key={questionSummary.question.id}
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
setFilter={setFilter}
|
||||
locale={locale}
|
||||
/>
|
||||
@@ -227,7 +217,6 @@ export const SummaryList = ({
|
||||
questionSummary={questionSummary}
|
||||
environmentId={environment.id}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
);
|
||||
@@ -239,7 +228,6 @@ export const SummaryList = ({
|
||||
questionSummary={questionSummary}
|
||||
environmentId={environment.id}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
);
|
||||
@@ -251,7 +239,6 @@ export const SummaryList = ({
|
||||
questionSummary={questionSummary}
|
||||
environmentId={environment.id}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
);
|
||||
@@ -262,7 +249,6 @@ export const SummaryList = ({
|
||||
key={questionSummary.question.id}
|
||||
questionSummary={questionSummary}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
setFilter={setFilter}
|
||||
locale={locale}
|
||||
/>
|
||||
@@ -275,7 +261,6 @@ export const SummaryList = ({
|
||||
questionSummary={questionSummary}
|
||||
environmentId={environment.id}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
);
|
||||
@@ -287,7 +272,6 @@ export const SummaryList = ({
|
||||
questionSummary={questionSummary}
|
||||
surveyType={survey.type}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
);
|
||||
@@ -309,7 +293,6 @@ export const SummaryList = ({
|
||||
questionSummary={questionSummary}
|
||||
environmentId={environment.id}
|
||||
survey={survey}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -18,7 +18,6 @@ import { useParams, useSearchParams } from "next/navigation";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useIntervalWhenFocused } from "@formbricks/lib/utils/hooks/useIntervalWhenFocused";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TSurvey, TSurveySummary } from "@formbricks/types/surveys/types";
|
||||
import { TUser, TUserLocale } from "@formbricks/types/user";
|
||||
@@ -47,7 +46,6 @@ interface SummaryPageProps {
|
||||
webAppUrl: string;
|
||||
user?: TUser;
|
||||
totalResponseCount: number;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
isAIEnabled: boolean;
|
||||
documentsPerPage?: number;
|
||||
locale: TUserLocale;
|
||||
@@ -60,7 +58,6 @@ export const SummaryPage = ({
|
||||
surveyId,
|
||||
webAppUrl,
|
||||
totalResponseCount,
|
||||
contactAttributeKeys,
|
||||
isAIEnabled,
|
||||
documentsPerPage,
|
||||
locale,
|
||||
@@ -156,8 +153,8 @@ export const SummaryPage = ({
|
||||
);
|
||||
|
||||
const surveyMemoized = useMemo(() => {
|
||||
return replaceHeadlineRecall(survey, "default", contactAttributeKeys);
|
||||
}, [survey, contactAttributeKeys]);
|
||||
return replaceHeadlineRecall(survey, "default");
|
||||
}, [survey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!searchParams?.get("referer")) {
|
||||
@@ -173,13 +170,7 @@ export const SummaryPage = ({
|
||||
setShowDropOffs={setShowDropOffs}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
{showDropOffs && (
|
||||
<SummaryDropOffs
|
||||
dropOff={surveySummary.dropOff}
|
||||
survey={surveyMemoized}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
/>
|
||||
)}
|
||||
{showDropOffs && <SummaryDropOffs dropOff={surveySummary.dropOff} survey={surveyMemoized} />}
|
||||
<div className="flex gap-1.5">
|
||||
<CustomFilter survey={surveyMemoized} />
|
||||
{!isReadOnly && !isSharingPage && (
|
||||
@@ -193,7 +184,6 @@ export const SummaryPage = ({
|
||||
survey={surveyMemoized}
|
||||
environment={environment}
|
||||
totalResponseCount={totalResponseCount}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
isAIEnabled={isAIEnabled}
|
||||
documentsPerPage={documentsPerPage}
|
||||
locale={locale}
|
||||
|
||||
@@ -4,7 +4,6 @@ import { SummaryPage } from "@/app/(app)/environments/[environmentId]/surveys/[s
|
||||
import { SurveyAnalysisCTA } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SurveyAnalysisCTA";
|
||||
import { needsInsightsGeneration } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/lib/utils";
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { getContactAttributeKeys } from "@/modules/ee/contacts/lib/contacts";
|
||||
import { getIsAIEnabled } from "@/modules/ee/license-check/lib/utils";
|
||||
import { getProjectPermissionByUserId } from "@/modules/ee/teams/lib/roles";
|
||||
import { getTeamPermissionFlags } from "@/modules/ee/teams/utils/teams";
|
||||
@@ -42,10 +41,9 @@ const SurveyPage = async (props: { params: Promise<{ environmentId: string; surv
|
||||
return notFound();
|
||||
}
|
||||
|
||||
const [survey, environment, contactAttributeKeys] = await Promise.all([
|
||||
const [survey, environment] = await Promise.all([
|
||||
getSurvey(params.surveyId),
|
||||
getEnvironment(params.environmentId),
|
||||
getContactAttributeKeys(params.environmentId),
|
||||
]);
|
||||
if (!environment) {
|
||||
throw new Error(t("common.environment_not_found"));
|
||||
@@ -118,7 +116,6 @@ const SurveyPage = async (props: { params: Promise<{ environmentId: string; surv
|
||||
webAppUrl={WEBAPP_URL}
|
||||
user={user}
|
||||
totalResponseCount={totalResponseCount}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
isAIEnabled={isAIEnabled}
|
||||
documentsPerPage={DOCUMENTS_PER_PAGE}
|
||||
isReadOnly={isReadOnly}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import { contactAttributeCache } from "@/lib/cache/contact-attribute";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { cache as reactCache } from "react";
|
||||
import { prisma } from "@formbricks/database";
|
||||
import { cache } from "@formbricks/lib/cache";
|
||||
import { validateInputs } from "@formbricks/lib/utils/validate";
|
||||
import { ZId } from "@formbricks/types/common";
|
||||
import { TContactAttributes } from "@formbricks/types/contact-attribute";
|
||||
import { DatabaseError } from "@formbricks/types/errors";
|
||||
|
||||
export const getContactAttributes = reactCache((contactId: string) =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([contactId, ZId]);
|
||||
|
||||
try {
|
||||
const prismaAttributes = await prisma.contactAttribute.findMany({
|
||||
where: {
|
||||
contactId,
|
||||
},
|
||||
select: {
|
||||
attributeKey: {
|
||||
select: {
|
||||
key: true,
|
||||
},
|
||||
},
|
||||
value: true,
|
||||
},
|
||||
});
|
||||
|
||||
return prismaAttributes.reduce((acc, attr) => {
|
||||
acc[attr.attributeKey.key] = attr.value;
|
||||
return acc;
|
||||
}, {}) as TContactAttributes;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[`getContactAttributes-insights-${contactId}`],
|
||||
{
|
||||
tags: [contactAttributeCache.tag.byContactId(contactId)],
|
||||
}
|
||||
)()
|
||||
);
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
TSurveyQuestionTypeEnum,
|
||||
ZSurveyQuestions,
|
||||
} from "@formbricks/types/surveys/types";
|
||||
import { getContactAttributes } from "./contact-attribute";
|
||||
import { TInsightCreateInput, TNearestInsights, ZInsightCreateInput } from "./types";
|
||||
|
||||
export const generateInsightsForSurveyResponsesConcept = async (
|
||||
@@ -99,9 +98,6 @@ export const generateInsightsForSurveyResponsesConcept = async (
|
||||
|
||||
const answersForDocumentCreationPromises = await Promise.all(
|
||||
responsesWithOpenTextAnswers.map(async (response) => {
|
||||
const contactAttributes = response.contactId
|
||||
? await getContactAttributes(response.contactId)
|
||||
: {};
|
||||
const responseEntries = openTextQuestionsWithInsights.map((question) => {
|
||||
const responseText = response.data[question.id] as string;
|
||||
if (!responseText) {
|
||||
@@ -110,7 +106,6 @@ export const generateInsightsForSurveyResponsesConcept = async (
|
||||
|
||||
const headline = parseRecallInfo(
|
||||
question.headline[response.language ?? "default"],
|
||||
contactAttributes,
|
||||
response.data,
|
||||
response.variables
|
||||
);
|
||||
@@ -255,8 +250,6 @@ export const generateInsightsForSurveyResponses = async (
|
||||
const createDocumentPromises: Promise<TCreatedDocument | undefined>[] = [];
|
||||
|
||||
for (const response of responsesWithOpenTextAnswers) {
|
||||
const contactAttributes = response.contactId ? await getContactAttributes(response.contactId) : {};
|
||||
|
||||
for (const question of openTextQuestionsWithInsights) {
|
||||
const responseText = response.data[question.id] as string;
|
||||
if (!responseText) {
|
||||
@@ -265,7 +258,6 @@ export const generateInsightsForSurveyResponses = async (
|
||||
|
||||
const headline = parseRecallInfo(
|
||||
question.headline[response.language ?? "default"],
|
||||
contactAttributes,
|
||||
response.data,
|
||||
response.variables
|
||||
);
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import { contactAttributeCache } from "@/lib/cache/contact-attribute";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { cache as reactCache } from "react";
|
||||
import { prisma } from "@formbricks/database";
|
||||
import { cache } from "@formbricks/lib/cache";
|
||||
import { validateInputs } from "@formbricks/lib/utils/validate";
|
||||
import { ZId } from "@formbricks/types/common";
|
||||
import { TContactAttributes } from "@formbricks/types/contact-attribute";
|
||||
import { DatabaseError } from "@formbricks/types/errors";
|
||||
|
||||
export const getContactAttributes = reactCache((contactId: string) =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([contactId, ZId]);
|
||||
|
||||
try {
|
||||
const prismaAttributes = await prisma.contactAttribute.findMany({
|
||||
where: {
|
||||
contactId,
|
||||
},
|
||||
select: {
|
||||
attributeKey: {
|
||||
select: {
|
||||
key: true,
|
||||
},
|
||||
},
|
||||
value: true,
|
||||
},
|
||||
});
|
||||
|
||||
return prismaAttributes.reduce((acc, attr) => {
|
||||
acc[attr.attributeKey.key] = attr.value;
|
||||
return acc;
|
||||
}, {}) as TContactAttributes;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[`getContactAttributes-pipeline-${contactId}`],
|
||||
{
|
||||
tags: [contactAttributeCache.tag.byContactId(contactId)],
|
||||
}
|
||||
)()
|
||||
);
|
||||
@@ -9,8 +9,6 @@ import { writeDataToSlack } from "@formbricks/lib/slack/service";
|
||||
import { getFormattedDateTimeString } from "@formbricks/lib/utils/datetime";
|
||||
import { parseRecallInfo } from "@formbricks/lib/utils/recall";
|
||||
import { truncateText } from "@formbricks/lib/utils/strings";
|
||||
import { TAttributes } from "@formbricks/types/attributes";
|
||||
import { TContactAttributes } from "@formbricks/types/contact-attribute";
|
||||
import { Result } from "@formbricks/types/error-handlers";
|
||||
import { TIntegration, TIntegrationType } from "@formbricks/types/integration";
|
||||
import { TIntegrationAirtable } from "@formbricks/types/integration/airtable";
|
||||
@@ -42,14 +40,13 @@ const processDataForIntegration = async (
|
||||
includeMetadata: boolean,
|
||||
includeHiddenFields: boolean,
|
||||
includeCreatedAt: boolean,
|
||||
questionIds: string[],
|
||||
contactAttributes?: TContactAttributes
|
||||
questionIds: string[]
|
||||
): Promise<string[][]> => {
|
||||
const ids =
|
||||
includeHiddenFields && survey.hiddenFields.fieldIds
|
||||
? [...questionIds, ...survey.hiddenFields.fieldIds]
|
||||
: questionIds;
|
||||
const values = await extractResponses(integrationType, data, ids, survey, contactAttributes);
|
||||
const values = await extractResponses(integrationType, data, ids, survey);
|
||||
if (includeMetadata) {
|
||||
values[0].push(convertMetaObjectToString(data.response.meta));
|
||||
values[1].push("Metadata");
|
||||
@@ -75,8 +72,7 @@ const processDataForIntegration = async (
|
||||
export const handleIntegrations = async (
|
||||
integrations: TIntegration[],
|
||||
data: TPipelineInput,
|
||||
survey: TSurvey,
|
||||
contactAttributes: TContactAttributes
|
||||
survey: TSurvey
|
||||
) => {
|
||||
for (const integration of integrations) {
|
||||
switch (integration.type) {
|
||||
@@ -91,12 +87,7 @@ export const handleIntegrations = async (
|
||||
}
|
||||
break;
|
||||
case "slack":
|
||||
const slackResult = await handleSlackIntegration(
|
||||
integration as TIntegrationSlack,
|
||||
data,
|
||||
survey,
|
||||
contactAttributes
|
||||
);
|
||||
const slackResult = await handleSlackIntegration(integration as TIntegrationSlack, data, survey);
|
||||
if (!slackResult.ok) {
|
||||
console.error("Error in slack integration: ", slackResult.error);
|
||||
}
|
||||
@@ -201,8 +192,7 @@ const handleGoogleSheetsIntegration = async (
|
||||
const handleSlackIntegration = async (
|
||||
integration: TIntegrationSlack,
|
||||
data: TPipelineInput,
|
||||
survey: TSurvey,
|
||||
contactAttributes: TContactAttributes
|
||||
survey: TSurvey
|
||||
): Promise<Result<void, Error>> => {
|
||||
try {
|
||||
if (integration.config.data.length > 0) {
|
||||
@@ -216,8 +206,7 @@ const handleSlackIntegration = async (
|
||||
!!element.includeMetadata,
|
||||
!!element.includeHiddenFields,
|
||||
!!element.includeCreatedAt,
|
||||
element.questionIds,
|
||||
contactAttributes
|
||||
element.questionIds
|
||||
);
|
||||
await writeDataToSlack(integration.config.key, element.channelId, values, survey?.name);
|
||||
}
|
||||
@@ -240,8 +229,7 @@ const extractResponses = async (
|
||||
integrationType: TIntegrationType,
|
||||
pipelineData: TPipelineInput,
|
||||
questionIds: string[],
|
||||
survey: TSurvey,
|
||||
attributes?: TAttributes
|
||||
survey: TSurvey
|
||||
): Promise<string[][]> => {
|
||||
const responses: string[] = [];
|
||||
const questions: string[] = [];
|
||||
@@ -287,7 +275,6 @@ const extractResponses = async (
|
||||
questions.push(
|
||||
parseRecallInfo(
|
||||
getLocalizedValue(question?.headline, "default"),
|
||||
integrationType === "slack" ? attributes : {},
|
||||
integrationType === "slack" ? pipelineData.response.data : emptyResponseObject,
|
||||
integrationType === "slack" ? pipelineData.response.variables : {}
|
||||
) || ""
|
||||
|
||||
@@ -19,7 +19,6 @@ import { getSurvey, updateSurvey } from "@formbricks/lib/survey/service";
|
||||
import { convertDatesInObject } from "@formbricks/lib/time";
|
||||
import { getPromptText } from "@formbricks/lib/utils/ai";
|
||||
import { parseRecallInfo } from "@formbricks/lib/utils/recall";
|
||||
import { getContactAttributes } from "./lib/contact-attribute";
|
||||
import { handleIntegrations } from "./lib/handleIntegrations";
|
||||
|
||||
export const POST = async (request: Request) => {
|
||||
@@ -44,7 +43,6 @@ export const POST = async (request: Request) => {
|
||||
}
|
||||
|
||||
const { environmentId, surveyId, event, response } = inputValidation.data;
|
||||
const contactAttributes = response.contact?.id ? await getContactAttributes(response.contact?.id) : {};
|
||||
|
||||
const organization = await getOrganizationByEnvironmentId(environmentId);
|
||||
if (!organization) {
|
||||
@@ -107,7 +105,7 @@ export const POST = async (request: Request) => {
|
||||
}
|
||||
|
||||
if (integrations.length > 0) {
|
||||
await handleIntegrations(integrations, inputValidation.data, survey, contactAttributes);
|
||||
await handleIntegrations(integrations, inputValidation.data, survey);
|
||||
}
|
||||
|
||||
// Fetch users with notifications in a single query
|
||||
@@ -219,7 +217,6 @@ export const POST = async (request: Request) => {
|
||||
|
||||
const headline = parseRecallInfo(
|
||||
question.headline[response.language ?? "default"],
|
||||
contactAttributes,
|
||||
response.data,
|
||||
response.variables
|
||||
);
|
||||
|
||||
@@ -25,11 +25,9 @@ export const getNotificationResponse = (
|
||||
const surveys: TWeeklySummaryNotificationDataSurvey[] = [];
|
||||
// iterate through the surveys and calculate the overall insights
|
||||
for (const survey of environment.surveys) {
|
||||
const parsedSurvey = replaceHeadlineRecall(
|
||||
survey as unknown as TSurvey,
|
||||
"default",
|
||||
environment.attributeKeys
|
||||
) as TSurvey & { responses: TWeeklyEmailResponseData[] };
|
||||
const parsedSurvey = replaceHeadlineRecall(survey as unknown as TSurvey, "default") as TSurvey & {
|
||||
responses: TWeeklyEmailResponseData[];
|
||||
};
|
||||
const surveyData: TWeeklySummaryNotificationDataSurvey = {
|
||||
id: parsedSurvey.id,
|
||||
name: parsedSurvey.name,
|
||||
|
||||
@@ -11,7 +11,6 @@ import { useEffect, useMemo, useState } from "react";
|
||||
import { FormbricksAPI } from "@formbricks/api";
|
||||
import { ResponseQueue } from "@formbricks/lib/responseQueue";
|
||||
import { SurveyState } from "@formbricks/lib/surveyState";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TJsFileUploadParams } from "@formbricks/types/js";
|
||||
import { TProject } from "@formbricks/types/project";
|
||||
import {
|
||||
@@ -38,7 +37,6 @@ interface LinkSurveyProps {
|
||||
responseCount?: number;
|
||||
verifiedEmail?: string;
|
||||
languageCode: string;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
isEmbed: boolean;
|
||||
IMPRINT_URL?: string;
|
||||
PRIVACY_URL?: string;
|
||||
@@ -57,7 +55,6 @@ export const LinkSurvey = ({
|
||||
responseCount,
|
||||
verifiedEmail,
|
||||
languageCode,
|
||||
contactAttributeKeys,
|
||||
isEmbed,
|
||||
IMPRINT_URL,
|
||||
PRIVACY_URL,
|
||||
@@ -171,7 +168,6 @@ export const LinkSurvey = ({
|
||||
survey={survey}
|
||||
isErrorComponent={true}
|
||||
languageCode={languageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
styling={project.styling}
|
||||
locale={locale}
|
||||
/>
|
||||
@@ -183,7 +179,6 @@ export const LinkSurvey = ({
|
||||
singleUseId={suId ?? ""}
|
||||
survey={survey}
|
||||
languageCode={languageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
styling={project.styling}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
@@ -7,7 +7,6 @@ import { OTPInput } from "@/modules/ui/components/otp-input";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TProject } from "@formbricks/types/project";
|
||||
import { TResponse } from "@formbricks/types/responses";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
@@ -24,7 +23,6 @@ interface PinScreenProps {
|
||||
IS_FORMBRICKS_CLOUD: boolean;
|
||||
verifiedEmail?: string;
|
||||
languageCode: string;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
isEmbed: boolean;
|
||||
locale: string;
|
||||
isPreview: boolean;
|
||||
@@ -43,7 +41,6 @@ export const PinScreen = (props: PinScreenProps) => {
|
||||
IS_FORMBRICKS_CLOUD,
|
||||
verifiedEmail,
|
||||
languageCode,
|
||||
contactAttributeKeys,
|
||||
isEmbed,
|
||||
locale,
|
||||
isPreview,
|
||||
@@ -123,7 +120,6 @@ export const PinScreen = (props: PinScreenProps) => {
|
||||
webAppUrl={webAppUrl}
|
||||
verifiedEmail={verifiedEmail}
|
||||
languageCode={languageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
isEmbed={isEmbed}
|
||||
IMPRINT_URL={IMPRINT_URL}
|
||||
PRIVACY_URL={PRIVACY_URL}
|
||||
|
||||
@@ -18,7 +18,6 @@ import { Toaster, toast } from "react-hot-toast";
|
||||
import { z } from "zod";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TProjectStyling } from "@formbricks/types/project";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
|
||||
@@ -27,7 +26,6 @@ interface VerifyEmailProps {
|
||||
isErrorComponent?: boolean;
|
||||
singleUseId?: string;
|
||||
languageCode: string;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
styling: TProjectStyling;
|
||||
locale: string;
|
||||
}
|
||||
@@ -43,7 +41,6 @@ export const VerifyEmail = ({
|
||||
singleUseId,
|
||||
languageCode,
|
||||
styling,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: VerifyEmailProps) => {
|
||||
const t = useTranslations();
|
||||
@@ -54,8 +51,8 @@ export const VerifyEmail = ({
|
||||
resolver: zodResolver(ZVerifyEmailInput),
|
||||
});
|
||||
const localSurvey = useMemo(() => {
|
||||
return replaceHeadlineRecall(survey, "default", contactAttributeKeys);
|
||||
}, [survey, contactAttributeKeys]);
|
||||
return replaceHeadlineRecall(survey, "default");
|
||||
}, [survey]);
|
||||
|
||||
const { isSubmitting } = form.formState;
|
||||
const [showPreviewQuestions, setShowPreviewQuestions] = useState(false);
|
||||
|
||||
@@ -14,7 +14,6 @@ import { getSurvey } from "@formbricks/lib/survey/service";
|
||||
import { findMatchingLocale } from "@formbricks/lib/utils/locale";
|
||||
import { ZId } from "@formbricks/types/common";
|
||||
import { TResponse } from "@formbricks/types/responses";
|
||||
import { getContactAttributeKeys } from "./lib/contact-attribute-key";
|
||||
import { getEmailVerificationDetails } from "./lib/helpers";
|
||||
|
||||
interface LinkSurveyPageProps {
|
||||
@@ -124,8 +123,6 @@ const Page = async (props: LinkSurveyPageProps) => {
|
||||
throw new Error("Project not found");
|
||||
}
|
||||
|
||||
const contactAttributeKeys = await getContactAttributeKeys(survey.environmentId);
|
||||
|
||||
const getLanguageCode = (): string => {
|
||||
if (!langParam || !isMultiLanguageAllowed) return "default";
|
||||
else {
|
||||
@@ -161,7 +158,6 @@ const Page = async (props: LinkSurveyPageProps) => {
|
||||
IS_FORMBRICKS_CLOUD={IS_FORMBRICKS_CLOUD}
|
||||
verifiedEmail={verifiedEmail}
|
||||
languageCode={languageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
isEmbed={isEmbed}
|
||||
locale={locale}
|
||||
isPreview={isPreview}
|
||||
@@ -180,7 +176,6 @@ const Page = async (props: LinkSurveyPageProps) => {
|
||||
responseCount={survey.welcomeCard.showResponseCount ? responseCount : undefined}
|
||||
verifiedEmail={verifiedEmail}
|
||||
languageCode={languageCode}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
isEmbed={isEmbed}
|
||||
IMPRINT_URL={IMPRINT_URL}
|
||||
PRIVACY_URL={PRIVACY_URL}
|
||||
|
||||
@@ -69,7 +69,6 @@ const Page = async (props: ResponsesPageProps) => {
|
||||
responsesPerPage={RESPONSES_PER_PAGE}
|
||||
locale={locale}
|
||||
isReadOnly={true}
|
||||
contactAttributeKeys={[]}
|
||||
/>
|
||||
</PageContentWrapper>
|
||||
</div>
|
||||
|
||||
@@ -66,7 +66,6 @@ const Page = async (props: SummaryPageProps) => {
|
||||
surveyId={survey.id}
|
||||
webAppUrl={WEBAPP_URL}
|
||||
totalResponseCount={totalResponseCount}
|
||||
contactAttributeKeys={[]} // not showing any attributes for the sharing page
|
||||
isAIEnabled={false} // Disable AI for sharing page for now
|
||||
isReadOnly={true}
|
||||
locale={DEFAULT_LOCALE}
|
||||
|
||||
@@ -74,7 +74,6 @@ export const QuestionSkip = ({
|
||||
questions.find((question) => question.id === questionId)!.headline,
|
||||
"default"
|
||||
),
|
||||
{},
|
||||
responseData
|
||||
)}
|
||||
</p>
|
||||
@@ -108,7 +107,6 @@ export const QuestionSkip = ({
|
||||
questions.find((question) => question.id === questionId)!.headline,
|
||||
"default"
|
||||
),
|
||||
{},
|
||||
responseData
|
||||
)}
|
||||
</p>
|
||||
|
||||
@@ -78,7 +78,6 @@ export const SingleResponseCardBody = ({
|
||||
{formatTextWithSlashes(
|
||||
parseRecallInfo(
|
||||
getLocalizedValue(question.headline, "default"),
|
||||
{},
|
||||
response.data,
|
||||
response.variables,
|
||||
true
|
||||
|
||||
@@ -8,7 +8,6 @@ import { useEffect, useState } from "react";
|
||||
import { useMembershipRole } from "@formbricks/lib/membership/hooks/useMembershipRole";
|
||||
import { getAccessFlags } from "@formbricks/lib/membership/utils";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TResponse } from "@formbricks/types/responses";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
@@ -21,7 +20,6 @@ interface ResponseTimelineProps {
|
||||
responses: TResponse[];
|
||||
environment: TEnvironment;
|
||||
environmentTags: TTag[];
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
projectPermission: TTeamPermission | null;
|
||||
}
|
||||
@@ -32,7 +30,6 @@ export const ResponseFeed = ({
|
||||
surveys,
|
||||
user,
|
||||
environmentTags,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
projectPermission,
|
||||
}: ResponseTimelineProps) => {
|
||||
@@ -67,7 +64,6 @@ export const ResponseFeed = ({
|
||||
environment={environment}
|
||||
deleteResponses={deleteResponses}
|
||||
updateResponse={updateResponse}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
projectPermission={projectPermission}
|
||||
/>
|
||||
@@ -85,7 +81,6 @@ const ResponseSurveyCard = ({
|
||||
environment,
|
||||
deleteResponses,
|
||||
updateResponse,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
projectPermission,
|
||||
}: {
|
||||
@@ -96,7 +91,6 @@ const ResponseSurveyCard = ({
|
||||
environment: TEnvironment;
|
||||
deleteResponses: (responseIds: string[]) => void;
|
||||
updateResponse: (responseId: string, response: TResponse) => void;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
projectPermission: TTeamPermission | null;
|
||||
}) => {
|
||||
@@ -116,7 +110,7 @@ const ResponseSurveyCard = ({
|
||||
{survey && (
|
||||
<SingleResponseCard
|
||||
response={response}
|
||||
survey={replaceHeadlineRecall(survey, "default", contactAttributeKeys)}
|
||||
survey={replaceHeadlineRecall(survey, "default")}
|
||||
user={user}
|
||||
pageType="people"
|
||||
environmentTags={environmentTags}
|
||||
|
||||
@@ -7,7 +7,6 @@ import { getResponsesByContactId } from "@formbricks/lib/response/service";
|
||||
import { getSurveys } from "@formbricks/lib/survey/service";
|
||||
import { getUser } from "@formbricks/lib/user/service";
|
||||
import { findMatchingLocale } from "@formbricks/lib/utils/locale";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
import { TTag } from "@formbricks/types/tags";
|
||||
@@ -17,15 +16,9 @@ interface ResponseSectionProps {
|
||||
environment: TEnvironment;
|
||||
contactId: string;
|
||||
environmentTags: TTag[];
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
}
|
||||
|
||||
export const ResponseSection = async ({
|
||||
environment,
|
||||
contactId,
|
||||
environmentTags,
|
||||
contactAttributeKeys,
|
||||
}: ResponseSectionProps) => {
|
||||
export const ResponseSection = async ({ environment, contactId, environmentTags }: ResponseSectionProps) => {
|
||||
const responses = await getResponsesByContactId(contactId);
|
||||
const surveyIds = responses?.map((response) => response.surveyId) || [];
|
||||
const surveys: TSurvey[] = surveyIds.length === 0 ? [] : ((await getSurveys(environment.id)) ?? []);
|
||||
@@ -63,7 +56,6 @@ export const ResponseSection = async ({
|
||||
responses={responses}
|
||||
environment={environment}
|
||||
environmentTags={environmentTags}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
projectPermission={projectPermission}
|
||||
/>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { TTeamPermission } from "@/modules/ee/teams/project-teams/types/team";
|
||||
import { ArrowDownUpIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useEffect, useState } from "react";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TResponse } from "@formbricks/types/responses";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
@@ -18,7 +17,6 @@ interface ResponseTimelineProps {
|
||||
responses: TResponse[];
|
||||
environment: TEnvironment;
|
||||
environmentTags: TTag[];
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
projectPermission: TTeamPermission | null;
|
||||
}
|
||||
@@ -29,7 +27,6 @@ export const ResponseTimeline = ({
|
||||
environment,
|
||||
responses,
|
||||
environmentTags,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
projectPermission,
|
||||
}: ResponseTimelineProps) => {
|
||||
@@ -63,7 +60,6 @@ export const ResponseTimeline = ({
|
||||
surveys={surveys}
|
||||
user={user}
|
||||
environmentTags={environmentTags}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
locale={locale}
|
||||
projectPermission={projectPermission}
|
||||
/>
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { AttributesSection } from "@/modules/ee/contacts/[contactId]/components/attributes-section";
|
||||
import { DeleteContactButton } from "@/modules/ee/contacts/[contactId]/components/delete-contact-button";
|
||||
import {
|
||||
getContact,
|
||||
getContactAttributeKeys,
|
||||
getContactAttributes,
|
||||
} from "@/modules/ee/contacts/lib/contacts";
|
||||
import { getContact, getContactAttributes } from "@/modules/ee/contacts/lib/contacts";
|
||||
import { getContactIdentifier } from "@/modules/ee/contacts/lib/utils";
|
||||
import { getProjectPermissionByUserId } from "@/modules/ee/teams/lib/roles";
|
||||
import { getTeamPermissionFlags } from "@/modules/ee/teams/utils/teams";
|
||||
@@ -26,25 +22,16 @@ export const SingleContactPage = async (props: {
|
||||
}) => {
|
||||
const params = await props.params;
|
||||
const t = await getTranslations();
|
||||
const [
|
||||
environment,
|
||||
environmentTags,
|
||||
project,
|
||||
session,
|
||||
organization,
|
||||
contact,
|
||||
contactAttributeKeys,
|
||||
contactAttributes,
|
||||
] = await Promise.all([
|
||||
getEnvironment(params.environmentId),
|
||||
getTagsByEnvironmentId(params.environmentId),
|
||||
getProjectByEnvironmentId(params.environmentId),
|
||||
getServerSession(authOptions),
|
||||
getOrganizationByEnvironmentId(params.environmentId),
|
||||
getContact(params.contactId),
|
||||
getContactAttributeKeys(params.environmentId),
|
||||
getContactAttributes(params.contactId),
|
||||
]);
|
||||
const [environment, environmentTags, project, session, organization, contact, contactAttributes] =
|
||||
await Promise.all([
|
||||
getEnvironment(params.environmentId),
|
||||
getTagsByEnvironmentId(params.environmentId),
|
||||
getProjectByEnvironmentId(params.environmentId),
|
||||
getServerSession(authOptions),
|
||||
getOrganizationByEnvironmentId(params.environmentId),
|
||||
getContact(params.contactId),
|
||||
getContactAttributes(params.contactId),
|
||||
]);
|
||||
|
||||
if (!project) {
|
||||
throw new Error(t("common.project_not_found"));
|
||||
@@ -94,7 +81,6 @@ export const SingleContactPage = async (props: {
|
||||
environment={environment}
|
||||
contactId={params.contactId}
|
||||
environmentTags={environmentTags}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -98,7 +98,7 @@ export function LocalizedEditor({
|
||||
className="fb-htmlbody ml-1" // styles are in global.css
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: DOMPurify.sanitize(
|
||||
recallToHeadline(value, localSurvey, false, "default", []).default ?? ""
|
||||
recallToHeadline(value, localSurvey, false, "default").default ?? ""
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useTranslations } from "next-intl";
|
||||
import React, { ReactNode, useMemo } from "react";
|
||||
import { getEnabledLanguages } from "@formbricks/lib/i18n/utils";
|
||||
import { headlineToRecall, recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TI18nString, TSurvey, TSurveyRecallItem } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -22,7 +21,6 @@ interface MultiLangWrapperProps {
|
||||
setSelectedLanguageCode: (code: string) => void;
|
||||
locale: TUserLocale;
|
||||
render: (props: MultiLangWrapperRenderProps) => ReactNode;
|
||||
contactAttributeKeys?: TContactAttributeKey[];
|
||||
}
|
||||
|
||||
export const MultiLangWrapper = ({
|
||||
@@ -34,7 +32,6 @@ export const MultiLangWrapper = ({
|
||||
locale,
|
||||
render,
|
||||
onChange,
|
||||
contactAttributeKeys,
|
||||
}: MultiLangWrapperProps) => {
|
||||
const t = useTranslations();
|
||||
|
||||
@@ -83,9 +80,7 @@ export const MultiLangWrapper = ({
|
||||
{usedLanguageCode !== "default" && value && typeof value["default"] !== "undefined" && (
|
||||
<div className="mt-1 text-xs text-slate-500">
|
||||
<strong>{t("environments.project.languages.translate")}:</strong>{" "}
|
||||
{contactAttributeKeys
|
||||
? recallToHeadline(value, localSurvey, false, "default", contactAttributeKeys)["default"]
|
||||
: value.default}
|
||||
{recallToHeadline(value, localSurvey, false, "default")["default"]}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -19,11 +19,9 @@ import {
|
||||
PresentationIcon,
|
||||
Rows3Icon,
|
||||
StarIcon,
|
||||
TagIcon,
|
||||
} from "lucide-react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { replaceRecallInfoWithUnderline } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TSurvey,
|
||||
TSurveyHiddenFields,
|
||||
@@ -53,7 +51,6 @@ interface RecallItemSelectProps {
|
||||
recallItems: TSurveyRecallItem[];
|
||||
selectedLanguageCode: string;
|
||||
hiddenFields: TSurveyHiddenFields;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
}
|
||||
|
||||
export const RecallItemSelect = ({
|
||||
@@ -63,7 +60,6 @@ export const RecallItemSelect = ({
|
||||
setShowRecallItemSelect,
|
||||
recallItems,
|
||||
selectedLanguageCode,
|
||||
contactAttributeKeys,
|
||||
}: RecallItemSelectProps) => {
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
const isNotAllowedQuestionType = (question: TSurveyQuestion): boolean => {
|
||||
@@ -96,19 +92,6 @@ export const RecallItemSelect = ({
|
||||
return [];
|
||||
}, [localSurvey.hiddenFields, recallItemIds]);
|
||||
|
||||
const contactAttributekeysRecallItems = useMemo(() => {
|
||||
if (localSurvey.type !== "app") return [];
|
||||
return contactAttributeKeys
|
||||
.filter((attributeKey) => !recallItemIds.includes(attributeKey.key.replaceAll(" ", "nbsp")))
|
||||
.map((attributeKey) => {
|
||||
return {
|
||||
id: attributeKey.key.replaceAll(" ", "nbsp"),
|
||||
label: attributeKey.key,
|
||||
type: "attributeClass" as const,
|
||||
};
|
||||
});
|
||||
}, [contactAttributeKeys, localSurvey.type, recallItemIds]);
|
||||
|
||||
const variableRecallItems = useMemo(() => {
|
||||
if (localSurvey.variables.length) {
|
||||
return localSurvey.variables
|
||||
@@ -145,24 +128,15 @@ export const RecallItemSelect = ({
|
||||
}, [localSurvey.questions, questionId, recallItemIds]);
|
||||
|
||||
const filteredRecallItems: TSurveyRecallItem[] = useMemo(() => {
|
||||
return [
|
||||
...surveyQuestionRecallItems,
|
||||
...hiddenFieldRecallItems,
|
||||
...contactAttributekeysRecallItems,
|
||||
...variableRecallItems,
|
||||
].filter((recallItems) => {
|
||||
if (searchValue.trim() === "") return true;
|
||||
else {
|
||||
return recallItems.label.toLowerCase().startsWith(searchValue.toLowerCase());
|
||||
return [...surveyQuestionRecallItems, ...hiddenFieldRecallItems, ...variableRecallItems].filter(
|
||||
(recallItems) => {
|
||||
if (searchValue.trim() === "") return true;
|
||||
else {
|
||||
return recallItems.label.toLowerCase().startsWith(searchValue.toLowerCase());
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [
|
||||
surveyQuestionRecallItems,
|
||||
hiddenFieldRecallItems,
|
||||
contactAttributekeysRecallItems,
|
||||
variableRecallItems,
|
||||
searchValue,
|
||||
]);
|
||||
);
|
||||
}, [surveyQuestionRecallItems, hiddenFieldRecallItems, variableRecallItems, searchValue]);
|
||||
|
||||
// function to modify headline (recallInfo to corresponding headline)
|
||||
const getRecallLabel = (label: string): string => {
|
||||
@@ -178,8 +152,6 @@ export const RecallItemSelect = ({
|
||||
}
|
||||
case "hiddenField":
|
||||
return EyeOffIcon;
|
||||
case "attributeClass":
|
||||
return TagIcon;
|
||||
case "variable":
|
||||
const variable = localSurvey.variables.find((variable) => variable.id === recallItem.id);
|
||||
return variable?.type === "number" ? FileDigitIcon : FileTextIcon;
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
recallToHeadline,
|
||||
replaceRecallInfoWithUnderline,
|
||||
} from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TSurvey, TSurveyRecallItem } from "@formbricks/types/surveys/types";
|
||||
|
||||
interface RecallWrapperRenderProps {
|
||||
@@ -32,7 +31,6 @@ interface RecallWrapperProps {
|
||||
onChange: (val: string, recallItems: TSurveyRecallItem[], fallbacks: { [id: string]: string }) => void;
|
||||
localSurvey: TSurvey;
|
||||
questionId: string;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
render: (props: RecallWrapperRenderProps) => React.ReactNode;
|
||||
usedLanguageCode: string;
|
||||
isRecallAllowed: boolean;
|
||||
@@ -44,7 +42,6 @@ export const RecallWrapper = ({
|
||||
onChange,
|
||||
localSurvey,
|
||||
questionId,
|
||||
contactAttributeKeys,
|
||||
render,
|
||||
usedLanguageCode,
|
||||
isRecallAllowed,
|
||||
@@ -54,9 +51,7 @@ export const RecallWrapper = ({
|
||||
const [showRecallItemSelect, setShowRecallItemSelect] = useState(false);
|
||||
const [showFallbackInput, setShowFallbackInput] = useState(false);
|
||||
const [recallItems, setRecallItems] = useState<TSurveyRecallItem[]>(
|
||||
value.includes("#recall:")
|
||||
? getRecallItems(value, localSurvey, usedLanguageCode, contactAttributeKeys)
|
||||
: []
|
||||
value.includes("#recall:") ? getRecallItems(value, localSurvey, usedLanguageCode) : []
|
||||
);
|
||||
const [fallbacks, setFallbacks] = useState<{ [id: string]: string }>(
|
||||
value.includes("/fallback:") ? getFallbackValues(value) : {}
|
||||
@@ -84,9 +79,7 @@ export const RecallWrapper = ({
|
||||
[usedLanguageCode]: newVal,
|
||||
};
|
||||
|
||||
const val = recallToHeadline(updatedText, localSurvey, false, usedLanguageCode, contactAttributeKeys)[
|
||||
usedLanguageCode
|
||||
];
|
||||
const val = recallToHeadline(updatedText, localSurvey, false, usedLanguageCode)[usedLanguageCode];
|
||||
|
||||
setInternalValue(newVal);
|
||||
|
||||
@@ -96,16 +89,7 @@ export const RecallWrapper = ({
|
||||
|
||||
onChange(newVal, recallItems, fallbacks);
|
||||
},
|
||||
[
|
||||
checkForRecallSymbol,
|
||||
contactAttributeKeys,
|
||||
isRecallAllowed,
|
||||
localSurvey,
|
||||
onChange,
|
||||
recallItems,
|
||||
fallbacks,
|
||||
usedLanguageCode,
|
||||
]
|
||||
[checkForRecallSymbol, isRecallAllowed, localSurvey, onChange, recallItems, fallbacks, usedLanguageCode]
|
||||
);
|
||||
|
||||
const addRecallItem = useCallback(
|
||||
@@ -217,8 +201,7 @@ export const RecallWrapper = ({
|
||||
{ [usedLanguageCode]: internalValue },
|
||||
localSurvey,
|
||||
false,
|
||||
usedLanguageCode,
|
||||
contactAttributeKeys
|
||||
usedLanguageCode
|
||||
)[usedLanguageCode];
|
||||
|
||||
filterRecallItems(remainingText);
|
||||
@@ -288,7 +271,6 @@ export const RecallWrapper = ({
|
||||
recallItems={recallItems}
|
||||
selectedLanguageCode={usedLanguageCode}
|
||||
hiddenFields={localSurvey.hiddenFields}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import { RefObject, useCallback, useMemo, useRef, useState } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { useSyncScroll } from "@formbricks/lib/utils/hooks/useSyncScroll";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import {
|
||||
TI18nString,
|
||||
TSurvey,
|
||||
@@ -54,7 +53,6 @@ interface QuestionFormInputProps {
|
||||
ref?: RefObject<HTMLInputElement | null>;
|
||||
onBlur?: React.FocusEventHandler<HTMLInputElement>;
|
||||
className?: string;
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
locale: TUserLocale;
|
||||
}
|
||||
|
||||
@@ -75,7 +73,6 @@ export const QuestionFormInput = ({
|
||||
placeholder,
|
||||
onBlur,
|
||||
className,
|
||||
contactAttributeKeys,
|
||||
locale,
|
||||
}: QuestionFormInputProps) => {
|
||||
const t = useTranslations();
|
||||
@@ -283,11 +280,9 @@ export const QuestionFormInput = ({
|
||||
setText(updatedText);
|
||||
debouncedHandleUpdate(updatedText[usedLanguageCode]);
|
||||
}}
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
render={({ value, onChange, children: languageIndicator }) => {
|
||||
return (
|
||||
<RecallWrapper
|
||||
contactAttributeKeys={contactAttributeKeys}
|
||||
localSurvey={localSurvey}
|
||||
questionId={questionId}
|
||||
value={value[usedLanguageCode]}
|
||||
@@ -357,8 +352,7 @@ export const QuestionFormInput = ({
|
||||
},
|
||||
localSurvey,
|
||||
false,
|
||||
usedLanguageCode,
|
||||
contactAttributeKeys
|
||||
usedLanguageCode
|
||||
)[usedLanguageCode]
|
||||
}
|
||||
dir="auto"
|
||||
|
||||
@@ -118,7 +118,6 @@ export const QuestionToggleTable = ({
|
||||
updateQuestion={updateQuestion}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
contactAttributeKeys={[]}
|
||||
locale={locale}
|
||||
/>
|
||||
</td>
|
||||
|
||||
@@ -43,7 +43,7 @@ export const getQuestionResponseMapping = (
|
||||
const answer = response.data[question.id];
|
||||
|
||||
questionResponseMapping.push({
|
||||
question: parseRecallInfo(getLocalizedValue(question.headline, "default"), {}, response.data),
|
||||
question: parseRecallInfo(getLocalizedValue(question.headline, "default"), response.data),
|
||||
response: convertResponseValue(answer, question),
|
||||
type: question.type,
|
||||
});
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { TContactAttributes } from "@formbricks/types/contact-attribute";
|
||||
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
|
||||
import { TResponseData, TResponseVariables } from "@formbricks/types/responses";
|
||||
import { TI18nString, TSurvey, TSurveyQuestion, TSurveyRecallItem } from "@formbricks/types/surveys/types";
|
||||
import { getLocalizedValue } from "../i18n/utils";
|
||||
@@ -57,8 +55,7 @@ export const findRecallInfoById = (text: string, id: string): string | null => {
|
||||
const getRecallItemLabel = <T extends TSurvey>(
|
||||
recallItemId: string,
|
||||
survey: T,
|
||||
languageCode: string,
|
||||
contactAttributeKeys: TContactAttributeKey[]
|
||||
languageCode: string
|
||||
): string | undefined => {
|
||||
const isHiddenField = survey.hiddenFields.fieldIds?.includes(recallItemId);
|
||||
if (isHiddenField) return recallItemId;
|
||||
@@ -66,11 +63,6 @@ const getRecallItemLabel = <T extends TSurvey>(
|
||||
const surveyQuestion = survey.questions.find((question) => question.id === recallItemId);
|
||||
if (surveyQuestion) return surveyQuestion.headline[languageCode];
|
||||
|
||||
const attributeClass = contactAttributeKeys.find(
|
||||
(attributeClass) => attributeClass.key.replaceAll(" ", "nbsp") === recallItemId
|
||||
);
|
||||
if (attributeClass) return attributeClass?.key;
|
||||
|
||||
const variable = survey.variables?.find((variable) => variable.id === recallItemId);
|
||||
if (variable) return variable.name;
|
||||
};
|
||||
@@ -80,8 +72,7 @@ export const recallToHeadline = <T extends TSurvey>(
|
||||
headline: TI18nString,
|
||||
survey: T,
|
||||
withSlash: boolean,
|
||||
languageCode: string,
|
||||
contactAttributeKeys: TContactAttributeKey[]
|
||||
languageCode: string
|
||||
): TI18nString => {
|
||||
let newHeadline = structuredClone(headline);
|
||||
const localizedHeadline = newHeadline[languageCode];
|
||||
@@ -96,8 +87,7 @@ export const recallToHeadline = <T extends TSurvey>(
|
||||
const recallItemId = extractId(recallInfo);
|
||||
if (!recallItemId) break;
|
||||
|
||||
let recallItemLabel =
|
||||
getRecallItemLabel(recallItemId, survey, languageCode, contactAttributeKeys) || recallItemId;
|
||||
let recallItemLabel = getRecallItemLabel(recallItemId, survey, languageCode) || recallItemId;
|
||||
|
||||
while (recallItemLabel.includes("#recall:")) {
|
||||
const nestedRecallInfo = extractRecallInfo(recallItemLabel);
|
||||
@@ -146,31 +136,16 @@ export const checkForEmptyFallBackValue = (survey: TSurvey, language: string): T
|
||||
};
|
||||
|
||||
// Processes each question in a survey to ensure headlines are formatted correctly for recall and return the modified survey.
|
||||
export const replaceHeadlineRecall = <T extends TSurvey>(
|
||||
survey: T,
|
||||
language: string,
|
||||
contactAttributeKeys: TContactAttributeKey[]
|
||||
): T => {
|
||||
export const replaceHeadlineRecall = <T extends TSurvey>(survey: T, language: string): T => {
|
||||
const modifiedSurvey = structuredClone(survey);
|
||||
modifiedSurvey.questions.forEach((question) => {
|
||||
question.headline = recallToHeadline(
|
||||
question.headline,
|
||||
modifiedSurvey,
|
||||
false,
|
||||
language,
|
||||
contactAttributeKeys
|
||||
);
|
||||
question.headline = recallToHeadline(question.headline, modifiedSurvey, false, language);
|
||||
});
|
||||
return modifiedSurvey;
|
||||
};
|
||||
|
||||
// Retrieves an array of survey questions referenced in a text containing recall information.
|
||||
export const getRecallItems = (
|
||||
text: string,
|
||||
survey: TSurvey,
|
||||
languageCode: string,
|
||||
attributeClasses: TContactAttributeKey[]
|
||||
): TSurveyRecallItem[] => {
|
||||
export const getRecallItems = (text: string, survey: TSurvey, languageCode: string): TSurveyRecallItem[] => {
|
||||
if (!text.includes("#recall:")) return [];
|
||||
|
||||
const ids = extractIds(text);
|
||||
@@ -180,23 +155,25 @@ export const getRecallItems = (
|
||||
const isSurveyQuestion = survey.questions.find((question) => question.id === recallItemId);
|
||||
const isVariable = survey.variables.find((variable) => variable.id === recallItemId);
|
||||
|
||||
const recallItemLabel = getRecallItemLabel(recallItemId, survey, languageCode, attributeClasses);
|
||||
const recallItemLabel = getRecallItemLabel(recallItemId, survey, languageCode);
|
||||
|
||||
const getRecallItemType = () => {
|
||||
if (isHiddenField) return "hiddenField";
|
||||
if (isSurveyQuestion) return "question";
|
||||
if (isVariable) return "variable";
|
||||
return "attributeClass";
|
||||
};
|
||||
|
||||
if (recallItemLabel) {
|
||||
let recallItemLabelTemp = recallItemLabel;
|
||||
recallItemLabelTemp = replaceRecallInfoWithUnderline(recallItemLabelTemp);
|
||||
recallItems.push({
|
||||
id: recallItemId,
|
||||
label: recallItemLabelTemp,
|
||||
type: getRecallItemType(),
|
||||
});
|
||||
const recallItemType = getRecallItemType();
|
||||
if (recallItemType) {
|
||||
recallItems.push({
|
||||
id: recallItemId,
|
||||
label: recallItemLabelTemp,
|
||||
type: recallItemType,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return recallItems;
|
||||
@@ -232,34 +209,12 @@ export const headlineToRecall = (
|
||||
|
||||
export const parseRecallInfo = (
|
||||
text: string,
|
||||
contactAttributes?: TContactAttributes,
|
||||
responseData?: TResponseData,
|
||||
variables?: TResponseVariables,
|
||||
withSlash: boolean = false
|
||||
) => {
|
||||
let modifiedText = text;
|
||||
const attributeKeys = contactAttributes ? Object.keys(contactAttributes) : [];
|
||||
const questionIds = responseData ? Object.keys(responseData) : [];
|
||||
if (contactAttributes && attributeKeys.length > 0) {
|
||||
attributeKeys.forEach((attributeKey) => {
|
||||
const recallPattern = `#recall:${attributeKey}`;
|
||||
while (modifiedText.includes(recallPattern)) {
|
||||
const recallInfo = extractRecallInfo(modifiedText, attributeKey);
|
||||
if (!recallInfo) break; // Exit the loop if no recall info is found
|
||||
|
||||
const recallItemId = extractId(recallInfo);
|
||||
if (!recallItemId) continue; // Skip to the next iteration if no ID could be extracted
|
||||
|
||||
const fallback = extractFallbackValue(recallInfo).replaceAll("nbsp", " ");
|
||||
let value = contactAttributes[recallItemId.replace("nbsp", " ")] || fallback;
|
||||
if (withSlash) {
|
||||
modifiedText = modifiedText.replace(recallInfo, "#/" + value + "\\#");
|
||||
} else {
|
||||
modifiedText = modifiedText.replace(recallInfo, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const variableIds = Object.keys(variables || {});
|
||||
|
||||
@@ -298,7 +253,7 @@ export const parseRecallInfo = (
|
||||
const fallback = extractFallbackValue(recallInfo).replaceAll("nbsp", " ");
|
||||
let value;
|
||||
|
||||
// Fetching value from responseData or attributes based on recallItemId
|
||||
// Fetching value from responseData based on recallItemId
|
||||
if (responseData[recallItemId]) {
|
||||
value = (responseData[recallItemId] as string) ?? fallback;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user