2023-12-25 15:38:40 +00:00
|
|
|
|
import { useEffect } from "react";
|
|
|
|
|
import { Box, useMediaQuery, useTheme } from "@mui/material";
|
2023-11-29 15:45:15 +00:00
|
|
|
|
import { DraggableList } from "./DraggableList";
|
2023-12-05 23:34:40 +00:00
|
|
|
|
import { SwitchBranchingPanel } from "./SwitchBranchingPanel";
|
2023-11-29 15:45:15 +00:00
|
|
|
|
import { BranchingMap } from "./BranchingMap";
|
2023-12-25 15:38:40 +00:00
|
|
|
|
import { useQuestionsStore } from "@root/questions/store";
|
2023-12-14 09:40:53 +00:00
|
|
|
|
import { useUiTools } from "@root/uiTools/store";
|
2023-12-25 15:38:40 +00:00
|
|
|
|
import { useQuestions } from "@root/questions/hooks";
|
|
|
|
|
import { useCurrentQuiz } from "@root/quizes/hooks";
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
copyQuestion,
|
|
|
|
|
deleteQuestion,
|
|
|
|
|
deleteQuestionWithTimeout,
|
|
|
|
|
clearRuleForAll,
|
|
|
|
|
updateQuestion,
|
|
|
|
|
getQuestionByContentId,
|
|
|
|
|
} from "@root/questions/actions";
|
|
|
|
|
import { updateRootContentId } from "@root/quizes/actions";
|
2023-11-29 15:45:15 +00:00
|
|
|
|
|
2023-12-25 15:38:40 +00:00
|
|
|
|
import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
|
2023-11-29 15:45:15 +00:00
|
|
|
|
|
2023-12-04 11:44:08 +00:00
|
|
|
|
export const QuestionSwitchWindowTool = () => {
|
2023-12-25 15:38:40 +00:00
|
|
|
|
const { questions } = useQuestionsStore.getState();
|
|
|
|
|
const { openBranchingPanel } = useUiTools();
|
|
|
|
|
const theme = useTheme();
|
|
|
|
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
|
|
|
|
const quiz = useCurrentQuiz();
|
|
|
|
|
|
|
|
|
|
const deleteFn = (question: AnyTypedQuizQuestion) => {
|
|
|
|
|
if (question.type !== null) {
|
|
|
|
|
if (question.content.rule.parentId === "root") {
|
|
|
|
|
//удалить из стора root и очистить rule всем вопросам
|
|
|
|
|
updateRootContentId(quiz?.id || "", "");
|
|
|
|
|
clearRuleForAll();
|
|
|
|
|
deleteQuestion(question.id);
|
|
|
|
|
} else if (question.content.rule.parentId.length > 0) {
|
|
|
|
|
//удалить из стора вопрос из дерева и очистить его потомков
|
|
|
|
|
const clearQuestions = [] as string[];
|
|
|
|
|
|
|
|
|
|
//записываем потомков , а их результаты удаляем
|
|
|
|
|
const getChildren = (parentQuestion: AnyTypedQuizQuestion) => {
|
|
|
|
|
questions.forEach((targetQuestion) => {
|
|
|
|
|
if (
|
|
|
|
|
targetQuestion.type !== null &&
|
|
|
|
|
targetQuestion.content.rule.parentId === parentQuestion.content.id
|
|
|
|
|
) {
|
|
|
|
|
//если у вопроса совпал родитель с родителем => он потомок, в кучу его
|
|
|
|
|
if (
|
|
|
|
|
targetQuestion.type !== "result" &&
|
|
|
|
|
targetQuestion.type !== null
|
|
|
|
|
) {
|
|
|
|
|
if (!clearQuestions.includes(targetQuestion.content.id))
|
|
|
|
|
clearQuestions.push(targetQuestion.content.id);
|
|
|
|
|
getChildren(targetQuestion); //и ищем его потомков
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
getChildren(question);
|
|
|
|
|
//чистим потомков от инфы ветвления
|
|
|
|
|
clearQuestions.forEach((id) => {
|
|
|
|
|
updateQuestion(id, (question) => {
|
|
|
|
|
question.content.rule.parentId = "";
|
|
|
|
|
question.content.rule.main = [];
|
|
|
|
|
question.content.rule.default = "";
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//чистим rule родителя
|
|
|
|
|
const parentQuestion = getQuestionByContentId(
|
|
|
|
|
question.content.rule.parentId
|
|
|
|
|
);
|
|
|
|
|
const newRule = {};
|
|
|
|
|
newRule.main = parentQuestion.content.rule.main.filter(
|
|
|
|
|
(data) => data.next !== question.content.id
|
|
|
|
|
); //удаляем условия перехода от родителя к этому вопросу
|
|
|
|
|
newRule.parentId = parentQuestion.content.rule.parentId;
|
|
|
|
|
newRule.default =
|
|
|
|
|
parentQuestion.content.rule.parentId === question.content.id
|
|
|
|
|
? ""
|
|
|
|
|
: parentQuestion.content.rule.parentId;
|
|
|
|
|
newRule.children = [...parentQuestion.content.rule.children].splice(
|
|
|
|
|
parentQuestion.content.rule.children.indexOf(question.content.id),
|
|
|
|
|
1
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
updateQuestion(question.content.rule.parentId, (PQ) => {
|
|
|
|
|
PQ.content.rule = newRule;
|
|
|
|
|
});
|
|
|
|
|
deleteQuestion(question.id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deleteQuestion(question.id);
|
|
|
|
|
|
|
|
|
|
const result = questions.find(
|
|
|
|
|
(q) =>
|
|
|
|
|
q.type === "result" && q.content.rule.parentId === question.content.id
|
|
|
|
|
);
|
|
|
|
|
if (result) deleteQuestion(result.id);
|
|
|
|
|
} else {
|
|
|
|
|
deleteQuestion(question.id);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const deleteTimeoutedQuestions = () => {
|
|
|
|
|
const questionsForDeletion = questions.filter(
|
|
|
|
|
({ type, deleted }) => type && type !== "result" && deleted
|
|
|
|
|
) as AnyTypedQuizQuestion[];
|
|
|
|
|
|
|
|
|
|
questionsForDeletion.forEach(deleteFn);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (openBranchingPanel) {
|
|
|
|
|
deleteTimeoutedQuestions();
|
|
|
|
|
}
|
|
|
|
|
}, [openBranchingPanel]);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
gap: "20px",
|
|
|
|
|
flexWrap: "wrap",
|
|
|
|
|
marginBottom: isMobile ? "20px" : undefined,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Box sx={{ flexBasis: "796px" }}>
|
|
|
|
|
{openBranchingPanel ? <BranchingMap /> : <DraggableList />}
|
|
|
|
|
</Box>
|
|
|
|
|
<SwitchBranchingPanel />
|
|
|
|
|
</Box>
|
|
|
|
|
);
|
|
|
|
|
};
|