mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-02 20:01:07 -05:00
fix: make description optional for consent and CTA elements
- Made description field optional in consent-element-form.tsx - Made description field optional in cta-element-form.tsx - Added conditional rendering with 'Add description' button when subheader is undefined - Removed special handling that prevented remove description button for CTA/Consent elements - Added useAutoAnimate for smooth transitions when adding/removing description - Ensures consistency with other question element forms where description is optional
This commit is contained in:
@@ -153,9 +153,9 @@ export const ElementFormInput = ({
|
||||
(currentElement &&
|
||||
(id.includes(".")
|
||||
? // Handle nested properties
|
||||
(currentElement[id.split(".")[0] as keyof TSurveyElement] as any)?.[id.split(".")[1]]
|
||||
(currentElement[id.split(".")[0] as keyof TSurveyElement] as any)?.[id.split(".")[1]]
|
||||
: // Original behavior
|
||||
(currentElement[id as keyof TSurveyElement] as TI18nString))) ||
|
||||
(currentElement[id as keyof TSurveyElement] as TI18nString))) ||
|
||||
createI18nString("", surveyLanguageCodes)
|
||||
);
|
||||
}, [
|
||||
@@ -308,14 +308,6 @@ export const ElementFormInput = ({
|
||||
const setFirstRender = externalSetFirstRender ?? setInternalFirstRender;
|
||||
|
||||
const renderRemoveDescriptionButton = () => {
|
||||
if (
|
||||
currentElement &&
|
||||
(currentElement.type === TSurveyElementTypeEnum.CTA ||
|
||||
currentElement.type === TSurveyElementTypeEnum.Consent)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (id === "subheader") {
|
||||
return !!currentElement?.subheader || (endingCard?.type === "endScreen" && !!endingCard?.subheader);
|
||||
}
|
||||
@@ -591,9 +583,8 @@ export const ElementFormInput = ({
|
||||
<div className="h-10 w-full"></div>
|
||||
<div
|
||||
ref={highlightContainerRef}
|
||||
className={`no-scrollbar absolute top-0 z-0 mt-0.5 flex h-10 w-full overflow-scroll whitespace-nowrap px-3 py-2 text-center text-sm text-transparent ${
|
||||
localSurvey.languages?.length > 1 ? "pr-24" : ""
|
||||
}`}
|
||||
className={`no-scrollbar absolute top-0 z-0 mt-0.5 flex h-10 w-full overflow-scroll whitespace-nowrap px-3 py-2 text-center text-sm text-transparent ${localSurvey.languages?.length > 1 ? "pr-24" : ""
|
||||
}`}
|
||||
dir="auto"
|
||||
key={highlightedJSX.toString()}>
|
||||
{highlightedJSX}
|
||||
@@ -620,9 +611,8 @@ export const ElementFormInput = ({
|
||||
maxLength={maxLength}
|
||||
ref={inputRef}
|
||||
onBlur={onBlur}
|
||||
className={`absolute top-0 text-black caret-black ${
|
||||
localSurvey.languages?.length > 1 ? "pr-24" : ""
|
||||
} ${className}`}
|
||||
className={`absolute top-0 text-black caret-black ${localSurvey.languages?.length > 1 ? "pr-24" : ""
|
||||
} ${className}`}
|
||||
isInvalid={
|
||||
isInvalid &&
|
||||
text[usedLanguageCode]?.trim() === "" &&
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { type JSX } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { TSurveyConsentElement } from "@formbricks/types/surveys/elements";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { createI18nString, extractLanguageCodes } from "@/lib/i18n/utils";
|
||||
import { ElementFormInput } from "@/modules/survey/components/element-form-input";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
|
||||
interface ConsentElementFormProps {
|
||||
localSurvey: TSurvey;
|
||||
@@ -33,6 +37,7 @@ export const ConsentElementForm = ({
|
||||
isExternalUrlsAllowed,
|
||||
}: ConsentElementFormProps): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
|
||||
// Common props shared across all ElementFormInput components
|
||||
const commonInputProps = {
|
||||
@@ -47,6 +52,8 @@ export const ConsentElementForm = ({
|
||||
isExternalUrlsAllowed,
|
||||
};
|
||||
|
||||
const [parent] = useAutoAnimate();
|
||||
|
||||
return (
|
||||
<form>
|
||||
<ElementFormInput
|
||||
@@ -57,13 +64,35 @@ export const ConsentElementForm = ({
|
||||
autoFocus={!element.headline?.default || element.headline.default.trim() === ""}
|
||||
/>
|
||||
|
||||
<div className="mt-3">
|
||||
<ElementFormInput
|
||||
{...commonInputProps}
|
||||
id="subheader"
|
||||
value={element.subheader}
|
||||
label={t("common.description")}
|
||||
/>
|
||||
<div ref={parent}>
|
||||
{element.subheader !== undefined && (
|
||||
<div className="inline-flex w-full items-center">
|
||||
<div className="w-full">
|
||||
<ElementFormInput
|
||||
{...commonInputProps}
|
||||
id="subheader"
|
||||
value={element.subheader}
|
||||
label={t("common.description")}
|
||||
autoFocus={!element.subheader?.default || element.subheader.default.trim() === ""}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{element.subheader === undefined && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
className="mt-3"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
updateElement(elementIdx, {
|
||||
subheader: createI18nString("", surveyLanguageCodes),
|
||||
});
|
||||
}}>
|
||||
<PlusIcon className="mr-1 h-4 w-4" />
|
||||
{t("environments.surveys.edit.add_description")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<ElementFormInput
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { type JSX } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { TSurveyCTAElement } from "@formbricks/types/surveys/elements";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { createI18nString, extractLanguageCodes } from "@/lib/i18n/utils";
|
||||
import { ElementFormInput } from "@/modules/survey/components/element-form-input";
|
||||
import { AdvancedOptionToggle } from "@/modules/ui/components/advanced-option-toggle";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
|
||||
@@ -38,6 +42,8 @@ export const CTAElementForm = ({
|
||||
isExternalUrlsAllowed,
|
||||
}: CTAElementFormProps): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
const [parent] = useAutoAnimate();
|
||||
|
||||
return (
|
||||
<form>
|
||||
@@ -57,21 +63,43 @@ export const CTAElementForm = ({
|
||||
isExternalUrlsAllowed={isExternalUrlsAllowed}
|
||||
/>
|
||||
|
||||
<div className="mt-3">
|
||||
<ElementFormInput
|
||||
id="subheader"
|
||||
value={element.subheader}
|
||||
label={t("common.description")}
|
||||
localSurvey={localSurvey}
|
||||
elementIdx={elementIdx}
|
||||
isInvalid={isInvalid}
|
||||
updateElement={updateElement}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
locale={locale}
|
||||
isStorageConfigured={isStorageConfigured}
|
||||
isExternalUrlsAllowed={isExternalUrlsAllowed}
|
||||
/>
|
||||
<div ref={parent}>
|
||||
{element.subheader !== undefined && (
|
||||
<div className="inline-flex w-full items-center">
|
||||
<div className="w-full">
|
||||
<ElementFormInput
|
||||
id="subheader"
|
||||
value={element.subheader}
|
||||
label={t("common.description")}
|
||||
localSurvey={localSurvey}
|
||||
elementIdx={elementIdx}
|
||||
isInvalid={isInvalid}
|
||||
updateElement={updateElement}
|
||||
selectedLanguageCode={selectedLanguageCode}
|
||||
setSelectedLanguageCode={setSelectedLanguageCode}
|
||||
locale={locale}
|
||||
isStorageConfigured={isStorageConfigured}
|
||||
autoFocus={!element.subheader?.default || element.subheader.default.trim() === ""}
|
||||
isExternalUrlsAllowed={isExternalUrlsAllowed}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{element.subheader === undefined && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
className="mt-3"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
updateElement(elementIdx, {
|
||||
subheader: createI18nString("", surveyLanguageCodes),
|
||||
});
|
||||
}}>
|
||||
<PlusIcon className="mr-1 h-4 w-4" />
|
||||
{t("environments.surveys.edit.add_description")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mt-3 flex-1">
|
||||
|
||||
Reference in New Issue
Block a user