fix: required setting

This commit is contained in:
IlyaDoronin 2023-12-13 21:19:12 +03:00
parent 0f914d1973
commit 939e2038cc
14 changed files with 205 additions and 211 deletions

@ -60,7 +60,6 @@ export interface QuizQuestionBase {
type?: QuestionType | null;
expanded: boolean;
openedModalSettings: boolean;
required: boolean;
deleted: boolean;
deleteTimeoutId: number;
content: {

@ -86,10 +86,10 @@ export default function SettingsData({ question }: SettingsDataProps) {
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={!question.required}
checked={!question.content.required}
handleChange={({ target }) => {
updateQuestion(question.id, question => {
question.required = !target.checked;
updateQuestion<QuizQuestionDate>(question.id, question => {
question.content.required = !target.checked;
});
}}
/>
@ -109,7 +109,7 @@ export default function SettingsData({ question }: SettingsDataProps) {
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestion(question.id, question => {
updateQuestion<QuizQuestionDate>(question.id, question => {
question.content.innerNameCheck = target.checked;
question.content.innerName = target.checked ? question.content.innerName : "";
});

@ -128,10 +128,10 @@ export default function SettingDropDown({ question }: SettingDropDownProps) {
</Typography>
<CustomCheckbox
label={"Необязательный вопрос"}
checked={!question.required}
checked={!question.content.required}
handleChange={(e) => {
updateQuestion(question.id, question => {
question.required = !e.target.checked;
updateQuestion<QuizQuestionSelect>(question.id, question => {
question.content.required = !e.target.checked;
});
}}
/>
@ -141,7 +141,7 @@ export default function SettingDropDown({ question }: SettingDropDownProps) {
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestion(question.id, question => {
updateQuestion<QuizQuestionSelect>(question.id, question => {
question.content.innerNameCheck = target.checked;
question.content.innerName = target.checked ? question.content.innerName : "";
});

@ -85,12 +85,11 @@ export default function SettingEmoji({ question }: SettingEmojiProps) {
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={question.content.required}
handleChange={({ target }) => updateQuestion(question.id, question => {
checked={!question.content.required}
handleChange={({ target }) => updateQuestion<QuizQuestionEmoji>(question.id, question => {
if (question.type !== "emoji") return;
console.log(target.checked)
question.content.required = target.checked;
question.content.required = !target.checked;
})}
/>
<Box
@ -108,7 +107,7 @@ export default function SettingEmoji({ question }: SettingEmojiProps) {
}}
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => updateQuestion(question.id, question => {
handleChange={({ target }) => updateQuestion<QuizQuestionEmoji>(question.id, question => {
question.content.innerNameCheck = target.checked;
question.content.innerName = target.checked ? question.content.innerName : "";
})}

@ -111,11 +111,11 @@ export default function SettingOptionsAndPict({ question }: SettingOptionsAndPic
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={question.content.required}
handleChange={({ target }) => updateQuestion(question.id, question => {
checked={!question.content.required}
handleChange={({ target }) => updateQuestion<QuizQuestionVarImg>(question.id, question => {
if (question.type !== "varimg") return;
question.content.required = target.checked;
question.content.required = !target.checked;
})}
/>
<Box sx={{ display: "flex", alignItems: "center" }}>
@ -126,7 +126,7 @@ export default function SettingOptionsAndPict({ question }: SettingOptionsAndPic
}}
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => updateQuestion(question.id, question => {
handleChange={({ target }) => updateQuestion<QuizQuestionVarImg>(question.id, question => {
question.content.innerNameCheck = target.checked;
question.content.innerName = "";
})}

@ -211,11 +211,11 @@ export default function SettingOpytionsPict({ question }: SettingOpytionsPictPro
<CustomCheckbox
sx={{ alignItems: isMobile ? "flex-start" : "" }}
label={"Необязательный вопрос"}
checked={question.content.required}
handleChange={({ target }) => updateQuestion(question.id, question => {
checked={!question.content.required}
handleChange={({ target }) => updateQuestion<QuizQuestionImages>(question.id, question => {
if (question.type !== "images") return;
question.content.required = target.checked;
question.content.required = !target.checked;
})
}
/>

@ -169,10 +169,10 @@ export default function SettingTextField({
alignItems: isMobile ? "flex-end" : "center",
}}
label={"Необязательный вопрос"}
checked={!question.required}
checked={!question.content.required}
handleChange={(e) => {
updateQuestion(question.id, question => {
question.required = !e.target.checked;
updateQuestion<QuizQuestionText>(question.id, question => {
question.content.required = !e.target.checked;
});
}}
/>
@ -193,7 +193,7 @@ export default function SettingTextField({
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestion(question.id, question => {
updateQuestion<QuizQuestionText>(question.id, question => {
question.content.innerNameCheck = target.checked;
question.content.innerName = target.checked
? question.content.innerName

@ -148,12 +148,12 @@ export default function SettingSlider({ question }: SettingSliderProps) {
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={!question.required}
checked={!question.content.required}
handleChange={(e) => {
updateQuestion(question.id, question => {
updateQuestion<QuizQuestionRating>(question.id, question => {
if (question.type !== "rating") return;
question.required = !e.target.checked;
question.content.required = !e.target.checked;
});
}}
/>

@ -78,12 +78,12 @@ export default function SettingSlider({ question }: SettingSliderProps) {
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px", alignItems: isMobile ? "flex-end" : "center" }}
label={"Необязательный вопрос"}
checked={!question.required}
checked={!question.content.required}
handleChange={(e) => {
updateQuestion(question.id, question => {
updateQuestion<QuizQuestionNumber>(question.id, question => {
if (question.type !== "number") return;
question.required = !e.target.checked;
question.content.required = !e.target.checked;
});
}}
/>

@ -59,10 +59,10 @@ export default function SettingsUpload({ question }: SettingsUploadProps) {
mr: isMobile ? "0px" : "16px",
}}
label={"Необязательный вопрос"}
checked={!question.required}
checked={!question.content.required}
handleChange={(e) => {
updateQuestion(question.id, question => {
question.required = !e.target.checked;
updateQuestion<QuizQuestionFile>(question.id, question => {
question.content.required = !e.target.checked;
});
}}
/>
@ -82,7 +82,7 @@ export default function SettingsUpload({ question }: SettingsUploadProps) {
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestion(question.id, question => {
updateQuestion<QuizQuestionFile>(question.id, question => {
question.content.innerNameCheck = target.checked;
question.content.innerName = target.checked ? question.content.innerName : "";
});

@ -1,9 +1,9 @@
import {
Box,
Tooltip,
Typography,
useMediaQuery,
useTheme,
Box,
Tooltip,
Typography,
useMediaQuery,
useTheme,
} from "@mui/material";
import { setQuestionInnerName, updateQuestion } from "@root/questions/actions";
import CustomCheckbox from "@ui_kit/CustomCheckbox";
@ -12,165 +12,166 @@ import { useDebouncedCallback } from "use-debounce";
import InfoIcon from "../../../assets/icons/InfoIcon";
import type { QuizQuestionVariant } from "../../../model/questionTypes/variant";
interface Props {
question: QuizQuestionVariant;
question: QuizQuestionVariant;
}
export default function ResponseSettings({ question }: Props) {
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(900));
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(900));
const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const updateQuestionInnerName = useDebouncedCallback((value) => {
setQuestionInnerName(question.id, value);
}, 200);
const updateQuestionInnerName = useDebouncedCallback((value) => {
setQuestionInnerName(question.id, value);
}, 200);
return (
<Box
sx={{
display: "flex",
justifyContent: "space-between",
flexDirection: isTablet ? "column" : "none",
marginRight: isFigmaTablte ? (isMobile ? "0" : "0px") : "30px",
}}
return (
<Box
sx={{
display: "flex",
justifyContent: "space-between",
flexDirection: isTablet ? "column" : "none",
marginRight: isFigmaTablte ? (isMobile ? "0" : "0px") : "30px",
}}
>
<Box
sx={{
pt: isMobile ? "25px" : "20px",
pb: isMobile ? "25px" : "20px",
pl: "20px",
display: "flex",
flexDirection: "column",
gap: "14px",
width: "100%",
}}
>
<Typography
sx={{
height: isMobile ? "18px" : "auto",
fontWeight: "500",
fontSize: "18px",
color: " #4D4D4D",
}}
>
<Box
sx={{
pt: isMobile ? "25px" : "20px",
pb: isMobile ? "25px" : "20px",
pl: "20px",
display: "flex",
flexDirection: "column",
gap: "14px",
width: "100%",
}}
Настройки ответов
</Typography>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Длинный текстовый ответ"}
checked={question.content.largeCheck}
handleChange={({ target }) => {
updateQuestion(question.id, (question) => {
if (!("largeCheck" in question.content)) return;
question.content.largeCheck = target.checked;
});
}}
/>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Можно несколько"}
checked={question.content.multi}
dataCy="multiple-answers-checkbox"
handleChange={({ target }) => {
updateQuestion(question.id, (question) => {
if (!("multi" in question.content)) return;
question.content.multi = target.checked;
});
}}
/>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={'Вариант "свой ответ"'}
checked={question.content.own}
handleChange={({ target }) => {
updateQuestion(question.id, (question) => {
if (!("own" in question.content)) return;
question.content.own = target.checked;
});
}}
/>
</Box>
<Box
sx={{
boxSizing: "border-box",
pt: isMobile ? "0px" : "20px",
pb: "20px",
pl: isFigmaTablte ? (isTablet ? "20px" : "34px") : "28px",
pr: isFigmaTablte ? "19px" : "20px",
display: "flex",
flexDirection: "column",
gap: "14px",
width: "100%",
}}
>
<Typography
sx={{
height: isMobile ? "18px" : "auto",
fontWeight: "500",
fontSize: "18px",
color: " #4D4D4D",
}}
>
Настройки вопросов
</Typography>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={!question.content.required}
handleChange={({ target }) => {
updateQuestion<QuizQuestionVariant>(question.id, (question) => {
question.content.required = !target.checked;
});
}}
/>
<Box
sx={{
width: isMobile ? "90%" : "auto",
display: "flex",
alignItems: "center",
}}
>
<CustomCheckbox
sx={{
mr: isMobile ? "0px" : "9px",
height: isMobile ? "42px" : "26px",
alignItems: "start",
}}
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestion<QuizQuestionVariant>(question.id, (question) => {
question.content.innerNameCheck = target.checked;
question.content.innerName = target.checked
? question.content.innerName
: "";
});
}}
/>
{isMobile && (
<Tooltip
title="Будет отображаться как заголовок вопроса в приходящих заявках."
placement="top"
>
<Typography
sx={{
height: isMobile ? "18px" : "auto",
fontWeight: "500",
fontSize: "18px",
color: " #4D4D4D",
}}
>
Настройки ответов
</Typography>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Длинный текстовый ответ"}
checked={question.content.largeCheck}
handleChange={({ target }) => {
updateQuestion(question.id, question => {
if (!("largeCheck" in question.content)) return;
question.content.largeCheck = target.checked;
});
}}
/>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Можно несколько"}
checked={question.content.multi}
dataCy="multiple-answers-checkbox"
handleChange={({ target }) => {
updateQuestion(question.id, question => {
if (!("multi" in question.content)) return;
question.content.multi = target.checked;
});
}}
/>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={'Вариант "свой ответ"'}
checked={question.content.own}
handleChange={({ target }) => {
updateQuestion(question.id, question => {
if (!("own" in question.content)) return;
question.content.own = target.checked;
});
}}
/>
</Box>
<Box
sx={{
boxSizing: "border-box",
pt: isMobile ? "0px" : "20px",
pb: "20px",
pl: isFigmaTablte ? (isTablet ? "20px" : "34px") : "28px",
pr: isFigmaTablte ? "19px" : "20px",
display: "flex",
flexDirection: "column",
gap: "14px",
width: "100%",
}}
>
<Typography
sx={{
height: isMobile ? "18px" : "auto",
fontWeight: "500",
fontSize: "18px",
color: " #4D4D4D",
}}
>
Настройки вопросов
</Typography>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={!question.required}
handleChange={({ target }) => {
updateQuestion(question.id, question => {
question.required = !target.checked;
});
}}
/>
<Box
sx={{
width: isMobile ? "90%" : "auto",
display: "flex",
alignItems: "center",
}}
>
<CustomCheckbox
sx={{
mr: isMobile ? "0px" : "9px",
height: isMobile ? "42px" : "26px",
alignItems: "start",
}}
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestion(question.id, question => {
question.content.innerNameCheck = target.checked;
question.content.innerName = target.checked ? question.content.innerName : "";
});
}}
/>
{isMobile && (
<Tooltip
title="Будет отображаться как заголовок вопроса в приходящих заявках."
placement="top"
>
<Box>
<InfoIcon />
</Box>
</Tooltip>
)}
</Box>
{question.content.innerNameCheck && (
<CustomTextField
sx={{ mr: isMobile ? "0px" : "16px" }}
placeholder={"Развёрнутое описание вопроса"}
text={question.content.innerName}
onChange={({ target }) => updateQuestionInnerName(target.value)}
/>
)}
</Box>
<Box>
<InfoIcon />
</Box>
</Tooltip>
)}
</Box>
);
{question.content.innerNameCheck && (
<CustomTextField
sx={{ mr: isMobile ? "0px" : "16px" }}
placeholder={"Развёрнутое описание вопроса"}
text={question.content.innerName}
onChange={({ target }) => updateQuestionInnerName(target.value)}
/>
)}
</Box>
</Box>
);
}

@ -3,17 +3,14 @@ import { Box, Button, useTheme } from "@mui/material";
import { useQuizViewStore } from "@root/quizView";
import type {
AnyTypedQuizQuestion,
QuizQuestionBase,
} from "../../model/questionTypes/shared";
import type { AnyTypedQuizQuestion, QuizQuestionBase } from "../../model/questionTypes/shared";
import { getQuestionByContentId } from "@root/questions/actions";
import { enqueueSnackbar } from "notistack";
type FooterProps = {
questions: AnyTypedQuizQuestion[];
setCurrentQuestion: (step: AnyTypedQuizQuestion) => void;
question: QuizQuestionBase;
question: AnyTypedQuizQuestion;
};
export const Footer = ({
@ -21,9 +18,6 @@ export const Footer = ({
questions,
question,
}: FooterProps) => {
const [disabledQuestionsId, setDisabledQuestionsId] = useState<Set<string>>(
new Set()
);
const [disablePreviousButton, setDisablePreviousButton] =
useState<boolean>(false);
const [disableNextButton, setDisableNextButton] = useState<boolean>(false);
@ -58,16 +52,18 @@ export const Footer = ({
({ questionId }) => questionId === question.content.id
);
debugger;
if (question.required && answer) {
setDisableNextButton(true);
if ("required" in question.content && question.content.required && answer) {
setDisableNextButton(false);
return;
}
if (question.required && !answer) {
setDisableNextButton(false);
if (
"required" in question.content &&
question.content.required &&
!answer
) {
setDisableNextButton(true);
return;
}
@ -107,7 +103,7 @@ export const Footer = ({
let readyBeNextQuestion = "";
question.content.rule.main.forEach(({ next, rules }) => {
(question as QuizQuestionBase).content.rule.main.forEach(({ next, rules }) => {
let longerArray = Math.max(
rules[0].answers.length,
[answer?.answer].length

@ -57,8 +57,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
currentQuestion.content.id,
currentQuestion.content.chooseRange
? `${currentQuestion.content.start}${max}`
: String(currentQuestion.content.start),
false
: String(currentQuestion.content.start)
);
setMinRange(String(currentQuestion.content.start));

@ -176,9 +176,9 @@ const REQUEST_DEBOUNCE = 200;
const requestQueue = new RequestQueue();
let requestTimeoutId: ReturnType<typeof setTimeout>;
export const updateQuestion = (
export const updateQuestion = <T = AnyTypedQuizQuestion>(
questionId: string,
updateFn: (question: AnyTypedQuizQuestion) => void,
updateFn: (question: T) => void,
skipQueue = false,
) => {
setProducedState(state => {
@ -186,7 +186,7 @@ export const updateQuestion = (
if (!question) return;
if (question.type === null) throw new Error("Cannot update untyped question, use 'updateUntypedQuestion' instead");
updateFn(question);
updateFn(question as T);
}, {
type: "updateQuestion",
questionId,