frontPanel/src/pages/Questions/BranchingModal/BranchingQuestionsModal.tsx

264 lines
8.1 KiB
TypeScript
Raw Normal View History

import { useState, useRef, useEffect, useLayoutEffect } from "react";
2023-11-29 15:45:15 +00:00
import {
Box,
Button,
FormControl,
FormControlLabel,
Link,
Modal,
Radio,
RadioGroup,
Tooltip,
Typography,
useTheme,
Checkbox,
useMediaQuery,
2023-11-29 15:45:15 +00:00
} from "@mui/material";
2023-12-31 02:53:25 +00:00
import {
AnyTypedQuizQuestion,
createBranchingRuleMain,
} from "../../../model/questionTypes/shared";
2023-11-29 15:45:15 +00:00
import { Select } from "../Select";
import RadioCheck from "@ui_kit/RadioCheck";
import RadioIcon from "@ui_kit/RadioIcon";
import InfoIcon from "@icons/Info";
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
import { TypeSwitch, BlockRule } from "./Settings";
2023-12-31 02:53:25 +00:00
import {
getQuestionById,
getQuestionByContentId,
updateQuestion,
} from "@root/questions/actions";
import { updateOpenedModalSettingsId } from "@root/uiTools/actions";
2023-12-14 13:56:26 +00:00
import { useUiTools } from "@root/uiTools/store";
2023-11-29 15:45:15 +00:00
import { enqueueSnackbar } from "notistack";
import TooltipClickInfo from "@ui_kit/Toolbars/TooltipClickInfo";
2023-11-29 15:45:15 +00:00
export default function BranchingQuestions() {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(650));
2023-12-14 13:56:26 +00:00
const { openedModalSettingsId } = useUiTools();
2023-12-31 02:53:25 +00:00
const [targetQuestion, setTargetQuestion] =
useState<AnyTypedQuizQuestion | null>(
getQuestionById(openedModalSettingsId) ||
getQuestionByContentId(openedModalSettingsId),
);
const [parentQuestion, setParentQuestion] =
useState<AnyTypedQuizQuestion | null>(
getQuestionByContentId(targetQuestion?.content.rule.parentId),
);
useLayoutEffect(() => {
2023-12-19 23:08:33 +00:00
if (parentQuestion === null) return;
if (parentQuestion.content.rule.main.length === 0) {
2023-12-19 23:08:33 +00:00
let mutate = JSON.parse(JSON.stringify(parentQuestion));
mutate.content.rule.main = [
{
next: targetQuestion.content.id,
or: true,
rules: [
{
question: parentQuestion.content.id,
answers: [],
},
],
},
];
setParentQuestion(mutate);
}
2023-12-19 23:08:33 +00:00
});
2023-11-29 15:45:15 +00:00
if (targetQuestion === null || parentQuestion === null) {
2023-12-19 23:08:33 +00:00
enqueueSnackbar("Невозможно найти данные ветвления для этого вопроса");
return <></>;
2023-11-29 15:45:15 +00:00
}
const saveData = () => {
if (parentQuestion !== null) {
2023-12-31 02:53:25 +00:00
updateQuestion(
parentQuestion.content.id,
(question) => (question.content = parentQuestion.content),
);
}
2023-12-19 23:08:33 +00:00
handleClose();
};
2023-11-29 15:45:15 +00:00
const handleClose = () => {
2023-12-19 23:08:33 +00:00
updateOpenedModalSettingsId();
2023-11-29 15:45:15 +00:00
};
return (
<>
<Modal open={openedModalSettingsId !== null} onClose={handleClose}>
<Box
sx={{
position: "absolute",
overflow: "hidden",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
maxWidth: "620px",
width: "100%",
bgcolor: "background.paper",
borderRadius: "12px",
boxShadow: 24,
p: 0,
}}
>
<>
<Box
sx={{
boxSizing: "border-box",
background: "#F2F3F7",
height: "70px",
padding: "0 25px",
display: "flex",
alignItems: "center",
}}
>
<Box sx={{ color: "#4d4d4d" }}>
<Typography component="span">{targetQuestion.title}</Typography>
</Box>
{isMobile ? (
<TooltipClickInfo
title={
"Настройте условия, при которых данный вопрос будет отображаться в quiz."
}
/>
) : (
<Tooltip
title="Настройте условия, при которых данный вопрос будет отображаться в quiz."
placement="top"
>
<Box>
<InfoIcon />
</Box>
</Tooltip>
)}
2023-11-29 15:45:15 +00:00
</Box>
<Box
sx={{
height: "400px",
2023-12-19 23:08:33 +00:00
overflow: "auto",
2023-11-29 15:45:15 +00:00
}}
>
2023-12-19 23:08:33 +00:00
{parentQuestion.content.rule.main.length ? (
parentQuestion.content.rule.main.map((e: any, i: number) => {
if (e.next === targetQuestion.content.id) {
return (
<TypeSwitch
key={i}
setParentQuestion={setParentQuestion}
targetQuestion={targetQuestion}
parentQuestion={parentQuestion}
ruleIndex={i}
/>
);
} else {
<></>;
}
})
) : (
<TypeSwitch
targetQuestion={targetQuestion}
setParentQuestion={setParentQuestion}
parentQuestion={parentQuestion}
ruleIndex={0}
/>
)}
2023-11-29 15:45:15 +00:00
</Box>
<Box
sx={{
margin: "20px 0 0 20px",
display: "flex",
2023-12-19 23:08:33 +00:00
flexDirection: "column",
2023-11-29 15:45:15 +00:00
}}
>
<Link
variant="body2"
sx={{
color: theme.palette.brightPurple.main,
marginBottom: "10px",
2023-12-19 23:08:33 +00:00
cursor: "pointer",
2023-11-29 15:45:15 +00:00
}}
2023-12-04 07:50:55 +00:00
onClick={() => {
2023-12-19 23:08:33 +00:00
const mutate = JSON.parse(JSON.stringify(parentQuestion));
mutate.content.rule.main.push(
2023-12-31 02:53:25 +00:00
createBranchingRuleMain(
targetQuestion.content.id,
parentQuestion.content.id,
),
2023-12-19 23:08:33 +00:00
);
setParentQuestion(mutate);
2023-12-04 07:50:55 +00:00
}}
2023-11-29 15:45:15 +00:00
>
Добавить условие
</Link>
2023-12-19 23:08:33 +00:00
<FormControlLabel
control={
<Checkbox
sx={{
margin: 0,
}}
2023-12-31 02:53:25 +00:00
checked={
parentQuestion.content.rule.default ===
targetQuestion.content.id
}
2023-12-19 23:08:33 +00:00
onClick={() => {
let mutate = JSON.parse(JSON.stringify(parentQuestion));
if (parentQuestion.content.rule.children.length === 1) {
//Если потомок 1 - можно только чекнуть чекбокс (по-умолчанию и так должен быть чекнут единственный)
2023-12-31 02:53:25 +00:00
mutate.content.rule.default = targetQuestion.content.id;
} else {
//Изменять чекбокс можно только если много потомков
mutate.content.rule.default =
2023-12-31 02:53:25 +00:00
parentQuestion.content.rule.default ===
targetQuestion.content.id
? ""
: targetQuestion.content.id;
}
2023-12-19 23:08:33 +00:00
setParentQuestion(mutate);
}}
/>
}
label="Следующий вопрос по-умолчанию"
/>
2023-11-29 15:45:15 +00:00
</Box>
2023-12-31 02:53:25 +00:00
<Box
sx={{
display: "flex",
justifyContent: "end",
gap: "10px",
margin: "20px",
}}
>
<Button
variant="outlined"
onClick={handleClose}
sx={{ width: "100%", maxWidth: "130px" }}
>
2023-11-29 15:45:15 +00:00
Отмена
</Button>
2023-12-31 02:53:25 +00:00
<Button
variant="contained"
sx={{ width: "100%", maxWidth: "130px" }}
onClick={saveData}
>
2023-11-29 15:45:15 +00:00
Готово
</Button>
</Box>
</>
</Box>
</Modal>
</>
);
}