Fix: all the changes suggested in the issue

This commit is contained in:
AshutoshBhadauriya
2023-06-09 20:31:21 +05:30
parent 9d3117b9c1
commit ac83286b27
7 changed files with 167 additions and 87 deletions

View File

@@ -0,0 +1,39 @@
import React from "react";
import LogicEditor from "@/app/environments/[environmentId]/surveys/[surveyId]/edit/LogicEditor";
import UpdateQuestionId from "./UpdateQuestionId";
import { Question } from "@formbricks/types/questions";
import { Survey } from "@formbricks/types/surveys";
interface AdvancedSettingsProps {
question: Question;
questionIdx: number;
localSurvey: Survey;
updateQuestion: (questionIdx: number, updatedAttributes: any) => void;
}
export default function AdvancedSettings({
question,
questionIdx,
localSurvey,
updateQuestion,
}: AdvancedSettingsProps) {
return (
<div>
<div className="mb-4">
<LogicEditor
question={question}
updateQuestion={updateQuestion}
localSurvey={localSurvey}
questionIdx={questionIdx}
/>
</div>
<UpdateQuestionId
question={question}
questionIdx={questionIdx}
localSurvey={localSurvey}
updateQuestion={updateQuestion}
/>
</div>
);
}

View File

@@ -1,7 +1,7 @@
import type { MultipleChoiceMultiQuestion } from "@formbricks/types/questions";
import { Survey } from "@formbricks/types/surveys";
import { Button, Input, Label } from "@formbricks/ui";
import { TrashIcon } from "@heroicons/react/24/solid";
import { PlusIcon, TrashIcon } from "@heroicons/react/24/solid";
import { createId } from "@paralleldrive/cuid2";
import { cn } from "@formbricks/lib/cn";
import { useEffect, useRef, useState } from "react";
@@ -36,14 +36,33 @@ export default function MultipleChoiceMultiForm({
updateQuestion(questionIdx, { choices: newChoices });
};
const addChoice = () => {
// const addChoice = () => {
// setIsNew(false); // This question is no longer new.
// let newChoices = !question.choices ? [] : question.choices;
// const otherChoice = newChoices.find((choice) => choice.id === "other");
// if (otherChoice) {
// newChoices = newChoices.filter((choice) => choice.id !== "other");
// }
// newChoices.push({ id: createId(), label: "" });
// if (otherChoice) {
// newChoices.push(otherChoice);
// }
// updateQuestion(questionIdx, { choices: newChoices });
// };
const addChoice = (choiceIdx?: number) => {
setIsNew(false); // This question is no longer new.
let newChoices = !question.choices ? [] : question.choices;
const otherChoice = newChoices.find((choice) => choice.id === "other");
if (otherChoice) {
newChoices = newChoices.filter((choice) => choice.id !== "other");
}
newChoices.push({ id: createId(), label: "" });
const newChoice = { id: createId(), label: "" };
if (choiceIdx !== undefined) {
newChoices.splice(choiceIdx + 1, 0, newChoice);
} else {
newChoices.push(newChoice);
}
if (otherChoice) {
newChoices.push(otherChoice);
}
@@ -104,7 +123,7 @@ export default function MultipleChoiceMultiForm({
</div>
</div>
<div className="mt-3">
{/* <div className="mt-3">
<Label htmlFor="subheader">Description</Label>
<div className="mt-2">
<Input
@@ -114,7 +133,25 @@ export default function MultipleChoiceMultiForm({
onChange={(e) => updateQuestion(questionIdx, { subheader: e.target.value })}
/>
</div>
</div>
</div> */}
{question.subheader && (
<div className="mt-3">
<Label htmlFor="subheader">Description</Label>
<div className="mt-2 inline-flex w-full items-center">
<Input
id="subheader"
name="subheader"
value={question.subheader}
onChange={(e) => updateQuestion(questionIdx, { subheader: e.target.value })}
/>
<TrashIcon
className="ml-2 h-4 w-4 cursor-pointer text-slate-400 hover:text-slate-500"
onClick={() => updateQuestion(questionIdx, { subheader: "" })}
/>
</div>
</div>
)}
<div className="mt-3">
<Label htmlFor="choices">Options</Label>
@@ -137,15 +174,17 @@ export default function MultipleChoiceMultiForm({
onClick={() => deleteChoice(choiceIdx)}
/>
)}
{choice.id !== "other" && (
<PlusIcon
className="ml-2 h-4 w-4 cursor-pointer text-slate-400 hover:text-slate-500"
onClick={() => addChoice(choiceIdx)}
/>
)}
</div>
))}
<div className="flex items-center space-x-2">
<Button variant="secondary" size="sm" type="button" onClick={() => addChoice()}>
Add Option
</Button>
{question.choices.filter((c) => c.id === "other").length === 0 && (
<>
<p>or</p>
<Button size="sm" variant="minimal" type="button" onClick={() => addOther()}>
Add &quot;Other&quot; with specify
</Button>
@@ -154,19 +193,6 @@ export default function MultipleChoiceMultiForm({
</div>
</div>
</div>
<div className="mt-3">
<Label htmlFor="buttonLabel">Button Label</Label>
<div className="mt-2">
<Input
id="buttonLabel"
name="buttonLabel"
value={question.buttonLabel}
placeholder={lastQuestion ? "Finish" : "Next"}
onChange={(e) => updateQuestion(questionIdx, { buttonLabel: e.target.value })}
/>
</div>
</div>
</form>
);
}

View File

@@ -148,10 +148,12 @@ export default function MultipleChoiceSingleForm({
onClick={() => deleteChoice(choiceIdx)}
/>
)}
<PlusIcon
className="ml-2 h-4 w-4 cursor-pointer text-slate-400 hover:text-slate-500"
onClick={() => addChoice(choiceIdx)}
/>
{choice.id !== "other" && (
<PlusIcon
className="ml-2 h-4 w-4 cursor-pointer text-slate-400 hover:text-slate-500"
onClick={() => addChoice(choiceIdx)}
/>
)}
</div>
))}
<div className="flex items-center space-x-2">

View File

@@ -1,6 +1,7 @@
import type { NPSQuestion } from "@formbricks/types/questions";
import { Survey } from "@formbricks/types/surveys";
import { Input, Label } from "@formbricks/ui";
import { TrashIcon } from "@heroicons/react/24/solid";
interface NPSQuestionFormProps {
localSurvey: Survey;
@@ -31,17 +32,23 @@ export default function NPSQuestionForm({
</div>
</div>
<div className="mt-3">
<Label htmlFor="subheader">Description</Label>
<div className="mt-2">
<Input
id="subheader"
name="subheader"
value={question.subheader}
onChange={(e) => updateQuestion(questionIdx, { subheader: e.target.value })}
/>
{question.subheader && (
<div className="mt-3">
<Label htmlFor="subheader">Description</Label>
<div className="mt-2 inline-flex w-full items-center">
<Input
id="subheader"
name="subheader"
value={question.subheader}
onChange={(e) => updateQuestion(questionIdx, { subheader: e.target.value })}
/>
<TrashIcon
className="ml-2 h-4 w-4 cursor-pointer text-slate-400 hover:text-slate-500"
onClick={() => updateQuestion(questionIdx, { subheader: "" })}
/>
</div>
</div>
</div>
)}
<div className="mt-3 flex justify-between">
<div>

View File

@@ -1,6 +1,7 @@
import type { OpenTextQuestion } from "@formbricks/types/questions";
import { Survey } from "@formbricks/types/surveys";
import { Input, Label } from "@formbricks/ui";
import { TrashIcon } from "@heroicons/react/24/solid";
interface OpenQuestionFormProps {
localSurvey: Survey;
@@ -31,7 +32,7 @@ export default function OpenQuestionForm({
</div>
</div>
<div className="mt-3">
{/* <div className="mt-3">
<Label htmlFor="subheader">Description</Label>
<div className="mt-2">
<Input
@@ -41,7 +42,25 @@ export default function OpenQuestionForm({
onChange={(e) => updateQuestion(questionIdx, { subheader: e.target.value })}
/>
</div>
</div>
</div> */}
{question.subheader && (
<div className="mt-3">
<Label htmlFor="subheader">Description</Label>
<div className="mt-2 inline-flex w-full items-center">
<Input
id="subheader"
name="subheader"
value={question.subheader}
onChange={(e) => updateQuestion(questionIdx, { subheader: e.target.value })}
/>
<TrashIcon
className="ml-2 h-4 w-4 cursor-pointer text-slate-400 hover:text-slate-500"
onClick={() => updateQuestion(questionIdx, { subheader: "" })}
/>
</div>
</div>
)}
<div className="mt-3">
<Label htmlFor="placeholder">Placeholder</Label>
@@ -54,19 +73,6 @@ export default function OpenQuestionForm({
/>
</div>
</div>
<div className="mt-3">
<Label htmlFor="buttonLabel">Button Label</Label>
<div className="mt-2">
<Input
id="buttonLabel"
name="buttonLabel"
value={question.buttonLabel}
placeholder={lastQuestion ? "Finish" : "Next"}
onChange={(e) => updateQuestion(questionIdx, { buttonLabel: e.target.value })}
/>
</div>
</div>
</form>
);
}

View File

@@ -26,7 +26,7 @@ import NPSQuestionForm from "./NPSQuestionForm";
import OpenQuestionForm from "./OpenQuestionForm";
import QuestionDropdown from "./QuestionMenu";
import RatingQuestionForm from "./RatingQuestionForm";
import UpdateQuestionId from "./UpdateQuestionId";
import AdvancedSettings from "@/app/environments/[environmentId]/surveys/[surveyId]/edit/AdvancedSettings";
interface QuestionCardProps {
localSurvey: Survey;
@@ -54,7 +54,7 @@ export default function QuestionCard({
lastQuestion,
}: QuestionCardProps) {
const open = activeQuestionId === question.id;
const [openAdvanced, setOpenAdvanced] = useState(false);
const [openAdvanced, setOpenAdvanced] = useState(question.logic && question.logic.length > 0);
return (
<Draggable draggableId={question.id} index={questionIdx}>
{(provided) => (
@@ -176,9 +176,9 @@ export default function QuestionCard({
lastQuestion={lastQuestion}
/>
) : null}
<div className="mt-4 border-t border-slate-200">
<div className="mt-4">
<Collapsible.Root open={openAdvanced} onOpenChange={setOpenAdvanced} className="mt-5">
<Collapsible.CollapsibleTrigger className="flex items-center text-xs text-slate-700 ">
<Collapsible.CollapsibleTrigger className="flex items-center text-xs text-slate-700">
{openAdvanced ? (
<ChevronDownIcon className="mr-1 h-4 w-3" />
) : (
@@ -187,40 +187,36 @@ export default function QuestionCard({
{openAdvanced ? "Hide Advanced Settings" : "Show Advanced Settings"}
</Collapsible.CollapsibleTrigger>
<Collapsible.CollapsibleContent className="space-y-2">
<div className="mt-3">
<Label htmlFor="buttonLabel">Button Label</Label>
<div className="mt-2">
<Input
id="buttonLabel"
name="buttonLabel"
value={question.buttonLabel}
placeholder={lastQuestion ? "Finish" : "Next"}
onChange={(e) => updateQuestion(questionIdx, { buttonLabel: e.target.value })}
/>
<Collapsible.CollapsibleContent className="space-y-4">
{question.type !== "nps" && question.type !== "rating" && question.type !== "cta" ? (
<div className="mt-4">
<Label htmlFor="buttonLabel">Button Label</Label>
<div className="mt-2">
<Input
id="buttonLabel"
name="buttonLabel"
value={question.buttonLabel}
placeholder={lastQuestion ? "Finish" : "Next"}
onChange={(e) => updateQuestion(questionIdx, { buttonLabel: e.target.value })}
/>
</div>
</div>
</div>
<LogicEditor
) : null}
<AdvancedSettings
question={question}
updateQuestion={updateQuestion}
localSurvey={localSurvey}
questionIdx={questionIdx}
localSurvey={localSurvey}
updateQuestion={updateQuestion}
/>
<div className="mt-3">
<UpdateQuestionId
question={question}
questionIdx={questionIdx}
localSurvey={localSurvey}
updateQuestion={updateQuestion}
/>
</div>
</Collapsible.CollapsibleContent>
</Collapsible.Root>
</div>
</Collapsible.CollapsibleContent>
<div className="m-4 mt-0 border-t border-slate-200">
{open && (
<div className="mb-4 mr-4 mt-4 flex items-center justify-end space-x-2">
{open && (
<div className="m-4 mt-0 border-t border-slate-200">
<div className="m-4 mr-0 flex items-center justify-end space-x-2">
<Label htmlFor="required-toggle">Required</Label>
<Switch
id="required-toggle"
@@ -231,8 +227,8 @@ export default function QuestionCard({
}}
/>
</div>
)}
</div>
</div>
)}
</Collapsible.Root>
</div>
)}

View File

@@ -20,7 +20,9 @@ export default function QuestionActions({
return (
<div className="flex space-x-4">
<ArrowUpIcon
className={`h-4 cursor-pointer text-slate-500 ${questionIdx === 0 ? "opacity-50" : ""}`}
className={`h-4 cursor-pointer text-slate-500 hover:text-slate-600 ${
questionIdx === 0 ? "opacity-50" : ""
}`}
onClick={(e) => {
if (questionIdx !== 0) {
e.stopPropagation();
@@ -29,7 +31,9 @@ export default function QuestionActions({
}}
/>
<ArrowDownIcon
className={`h-4 cursor-pointer text-slate-500 ${lastQuestion ? "opacity-50" : ""}`}
className={`h-4 cursor-pointer text-slate-500 hover:text-slate-600 ${
lastQuestion ? "opacity-50" : ""
}`}
onClick={(e) => {
if (!lastQuestion) {
e.stopPropagation();
@@ -38,14 +42,14 @@ export default function QuestionActions({
}}
/>
<DocumentDuplicateIcon
className="h-4 cursor-pointer text-slate-500"
className="h-4 cursor-pointer text-slate-500 hover:text-slate-600"
onClick={(e) => {
e.stopPropagation();
duplicateQuestion(questionIdx);
}}
/>
<TrashIcon
className="h-4 cursor-pointer text-slate-500"
className="h-4 cursor-pointer text-slate-500 hover:text-slate-600"
onClick={(e) => {
e.stopPropagation();
deleteQuestion(questionIdx);