порядок действий при удалении вопроса и переходе в ЦС компонент

This commit is contained in:
Nastya 2023-12-27 10:25:30 +03:00
parent ee87a5d7a8
commit 39379e8bda
18 changed files with 258 additions and 343 deletions

@ -56,7 +56,7 @@ function CsComponent({
}: CsComponentProps) {
const quiz = useCurrentQuiz();
const { dragQuestionContentId, desireToOpenABranchingModal, canCreatePublic } = useUiTools()
const { dragQuestionContentId, desireToOpenABranchingModal, canCreatePublic, someWorkBackend } = useUiTools()
const trashQuestions = useQuestionsStore().questions
const questions = trashQuestions.filter((question) => question.type !== "result" && question.type !== null && !question.deleted)
const [startCreate, setStartCreate] = useState("");
@ -87,13 +87,6 @@ function CsComponent({
gearsContainer,
});
useEffect(() => {
return () => {
// if (!canCreatePublic) updateModalInfoWhyCantCreate(true)
}
}, []);
useLayoutEffect(() => {
const cy = cyRef?.current
if (desireToOpenABranchingModal) {
@ -104,11 +97,14 @@ function CsComponent({
cy?.elements().data("eroticeyeblink", false)
}
}, [desireToOpenABranchingModal])
//Техническая штучка. Гарантирует не отрисовку модалки по первому входу на страничку. И очистка данных по расскоменчиванию
//Быстро просто дешево и сердито :)
useLayoutEffect(() => {
updateOpenedModalSettingsId()
// updateRootContentId(quiz.id, "")
// clearRuleForAll()
}, [])
//Отлов mouseup для отрисовки ноды
useEffect(() => {
if (modalQuestionTargetContentId.length !== 0 && modalQuestionParentContentId.length !== 0) {
addNode({ parentNodeContentId: modalQuestionParentContentId, targetNodeContentId: modalQuestionTargetContentId })
@ -188,14 +184,12 @@ function CsComponent({
})
if (!noChild) {//детей больше 1
console.log("детей ", noChild, " открываем модалку ветвления")
//- предупреждаем стор вопросов об открытии модалки ветвления
updateOpenedModalSettingsId(targetQuestion.content.id)
}
}
useEffect(() => {
if (startCreate) {
addNode({ parentNodeContentId: startCreate });
@ -211,26 +205,40 @@ function CsComponent({
}
}, [startRemove]);
//Отработка первичного рендера странички графика
const firstRender = useRef(true)
useEffect(() => {
document
.querySelector("#root")
?.addEventListener("mouseup", cleardragQuestionContentId);
const cy = cyRef.current;
const eles = cy?.add(
storeToNodes(
questions.filter(
(question) => question.type && question.type !== "result"
) as AnyTypedQuizQuestion[]
)
);
cy?.data("changed", true);
// cy.data('changed', true)
const elecs = eles?.layout(layoutOptions).run();
cy?.on("add", () => cy.data("changed", true));
cy?.fit();
//cy?.layout().run()
console.log("____________ПЕРВЧИНЫЙ РЕНДЕР____________")
console.log("______someWorkBackend______", someWorkBackend)
if (!someWorkBackend && firstRender.current) {
console.log("цс первично отрабатывает")
document
.querySelector("#root")
?.addEventListener("mouseup", cleardragQuestionContentId);
const cy = cyRef.current;
console.log("СПИСОК ЭЛЕМЕНТОВ ЦИТОСКЕЙПА В ПЕРВЧИНЫЙ РЕНДЕР")
console.log(cy?.elements())
const eles = cy?.add(
storeToNodes(
questions.filter(
(question) => question.type && question.type !== "result"
) as AnyTypedQuizQuestion[]
)
);
cy?.data("changed", true);
// cy.data('changed', true)
const elecs = eles?.layout(layoutOptions).run();
cy?.on("add", () => cy.data("changed", true));
cy?.fit();
//cy?.layout().run()
firstRender.current = false
}
return () => {
console.log("разрендер")
document
.querySelector("#root")
?.removeEventListener("mouseup", cleardragQuestionContentId);
@ -239,7 +247,7 @@ function CsComponent({
crossesContainer.current?.remove();
gearsContainer.current?.remove();
};
}, []);
}, [someWorkBackend]);
return (

@ -17,6 +17,7 @@ export const FirstNodeField = ({ setOpenedModalQuestions, modalQuestionTargetCon
useLayoutEffect(() => {
console.log("компонент с плюсом")
updateOpenedModalSettingsId()
updateRootContentId(quiz.id, "")
clearRuleForAll()

@ -8,6 +8,7 @@ import { useUiTools } from "@root/uiTools/store";
export const BranchingMap = () => {
const quiz = useCurrentQuiz();
console.log("рендер странички ветвления")
const { dragQuestionContentId } = useUiTools();
const [modalQuestionParentContentId, setModalQuestionParentContentId] =
useState<string>("");

@ -27,6 +27,8 @@ import { updateOpenedModalSettingsId } from "@root/uiTools/actions";
import { updateRootContentId } from "@root/quizes/actions";
import { useUiTools } from "@root/uiTools/store";
import {useState} from "react";
import { updateSomeWorkBackend } from "@root/uiTools/actions";
import { DeleteFunction } from "@utils/deleteFunc";
interface Props {
switchState: string;
@ -52,61 +54,6 @@ export default function ButtonsOptions({
updateDesireToOpenABranchingModal(question.content.id);
};
const deleteFn = () => {
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 buttonSetting: {
icon: JSX.Element;
title: string;
@ -334,7 +281,7 @@ export default function ButtonsOptions({
if(question.content.rule.parentId.length !== 0) {
setOpenDelete(true)
} else {
deleteQuestionWithTimeout(question.id, deleteFn);
deleteQuestionWithTimeout(question.id, () => DeleteFunction(questions, question, quiz));
}
}}
@ -376,7 +323,7 @@ export default function ButtonsOptions({
variant="contained"
sx={{ minWidth: "150px" }}
onClick={() => {
deleteQuestionWithTimeout(question.id, deleteFn);
deleteQuestionWithTimeout(question.id, () => DeleteFunction(questions, question, quiz));
}}
>
Подтвердить

@ -29,6 +29,8 @@ import { enqueueSnackbar } from "notistack";
import { useCurrentQuiz } from "@root/quizes/hooks";
import { updateRootContentId } from "@root/quizes/actions";
import {AnyTypedQuizQuestion} from "@model/questionTypes/shared";
import { updateSomeWorkBackend } from "@root/uiTools/actions";
import { DeleteFunction } from "@utils/deleteFunc";
interface Props {
@ -53,60 +55,6 @@ export default function ButtonsOptionsAndPict({
const [openDelete, setOpenDelete] = useState<boolean>(false);
const deleteFn = () => {
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.content.rule.parentId === parentQuestion.content.id) {//если у вопроса совпал родитель с родителем => он потомок, в кучу его
if (targetQuestion.type !== null && targetQuestion.type !== "result") {
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);
}
};
useEffect(() => {
if (question.deleteTimeoutId) {
clearTimeout(question.deleteTimeoutId);
@ -370,7 +318,7 @@ export default function ButtonsOptionsAndPict({
if(question.content.rule.parentId.length !== 0) {
setOpenDelete(true)
} else {
deleteQuestionWithTimeout(question.id, deleteFn);
deleteQuestionWithTimeout(question.id, () => DeleteFunction(questions, question, quiz));
}
}}
data-cy="delete-question"
@ -411,7 +359,7 @@ export default function ButtonsOptionsAndPict({
variant="contained"
sx={{ minWidth: "150px" }}
onClick={() => {
deleteQuestionWithTimeout(question.id, deleteFn);
deleteQuestionWithTimeout(question.id, () => DeleteFunction(questions, question, quiz));
}}
>
Подтвердить

@ -29,7 +29,6 @@ function DraggableListItem({ question, isDragging, index }: Props) {
updateEditSomeQuestion();
}
}, 200);
}
}, [editSomeQuestion]);

@ -55,6 +55,8 @@ import TypeQuestions from "../TypeQuestions";
import { QuestionType } from "@model/question/question";
import { useCurrentQuiz } from "@root/quizes/hooks";
import { useQuestionsStore } from "@root/questions/store";
import { updateSomeWorkBackend } from "@root/uiTools/actions";
import { DeleteFunction } from "@utils/deleteFunc";
interface Props {
question: AnyTypedQuizQuestion | UntypedQuizQuestion;
@ -87,61 +89,6 @@ const maxLengthTextField = 225;
});
}, 200);
const deleteFn = () => {
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 !== null && targetQuestion.type !== "result") {
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 handleInputFocus = () => {
setIsTextFieldtActive(true);
};
@ -333,7 +280,7 @@ const maxLengthTextField = 225;
if (question.content.rule.parentId.length !== 0) {
setOpenDelete(true);
} else {
deleteQuestionWithTimeout(question.id, deleteFn);
deleteQuestionWithTimeout(question.id, () => DeleteFunction(questions, question, quiz));
}
}}
data-cy="delete-question"
@ -371,7 +318,7 @@ const maxLengthTextField = 225;
variant="contained"
sx={{ minWidth: "150px" }}
onClick={() => {
deleteQuestionWithTimeout(question.id, deleteFn);
deleteQuestionWithTimeout(question.id, () => DeleteFunction(questions, question, quiz));
}}
>
Подтвердить

@ -251,7 +251,7 @@ export default function QuestionsPageCard({ question, questionIndex, draggablePr
margin: "0 5px 0 10px",
}}
onClick={() => {
deleteQuestionWithTimeout(question.id, deleteQuestion(question.id));
deleteQuestionWithTimeout(question.id, () => deleteQuestion(question.id));
}}
>

@ -1,4 +1,4 @@
import { useEffect } from "react";
import { useEffect, useLayoutEffect } from "react";
import { Box, useMediaQuery, useTheme } from "@mui/material";
import { DraggableList } from "./DraggableList";
import { SwitchBranchingPanel } from "./SwitchBranchingPanel";
@ -7,6 +7,7 @@ import { useQuestionsStore } from "@root/questions/store";
import { useUiTools } from "@root/uiTools/store";
import { useQuestions } from "@root/questions/hooks";
import { useCurrentQuiz } from "@root/quizes/hooks";
import { updateSomeWorkBackend } from "@root/uiTools/actions";
import {
copyQuestion,
@ -19,103 +20,29 @@ import {
import { updateRootContentId } from "@root/quizes/actions";
import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
import { DeleteFunction } from "@utils/deleteFunc";
import { deleteTimeoutedQuestions } from "@utils/deleteTimeoutedQuestions";
export const QuestionSwitchWindowTool = () => {
interface Props {
openBranchingPage: boolean;
setOpenBranchingPage: (a:boolean) => void;
}
export const QuestionSwitchWindowTool = ({
openBranchingPage,
setOpenBranchingPage}:Props) => {
const { questions } = useQuestionsStore.getState();
const { openBranchingPanel } = useUiTools();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(600));
const quiz = useCurrentQuiz();
console.log("Я компонент в котором отвечала")
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 openBranchingPageHC = () => {
if (!openBranchingPage) {
deleteTimeoutedQuestions(questions, quiz)
}
};
const deleteTimeoutedQuestions = () => {
const questionsForDeletion = questions.filter(
({ type, deleted }) => type && type !== "result" && deleted
) as AnyTypedQuizQuestion[];
questionsForDeletion.forEach(deleteFn);
};
useEffect(() => {
if (openBranchingPanel) {
deleteTimeoutedQuestions();
}
}, [openBranchingPanel]);
setOpenBranchingPage(!openBranchingPage)
}
return (
<Box
@ -127,9 +54,13 @@ export const QuestionSwitchWindowTool = () => {
}}
>
<Box sx={{ flexBasis: "796px" }}>
{openBranchingPanel ? <BranchingMap /> : <DraggableList />}
{openBranchingPage ? <BranchingMap /> : <DraggableList />}
</Box>
<SwitchBranchingPanel />
<SwitchBranchingPanel
openBranchingPage={openBranchingPage}
setOpenBranchingPage={openBranchingPageHC}
/>
</Box>
);
};

@ -13,7 +13,14 @@ import { useQuestionsStore } from "@root/questions/store";
import { updateOpenBranchingPanel, updateEditSomeQuestion } from "@root/uiTools/actions";
import { useUiTools } from "@root/uiTools/store";
export default function QuestionsPage() {
interface Props {
openBranchingPage: boolean;
setOpenBranchingPage: (a:boolean) => void;
}
export default function QuestionsPage({
openBranchingPage,
setOpenBranchingPage}:Props) {
const theme = useTheme();
const { openedModalSettingsId, openBranchingPanel } = useUiTools();
const isMobile = useMediaQuery(theme.breakpoints.down(660));
@ -55,7 +62,10 @@ export default function QuestionsPage() {
Свернуть всё
</Button>
</Box>
<QuestionSwitchWindowTool />
<QuestionSwitchWindowTool
openBranchingPage={openBranchingPage}
setOpenBranchingPage={setOpenBranchingPage}
/>
<Box
sx={{
display: "flex",

@ -13,15 +13,20 @@ import { useQuestionsStore } from "@root/questions/store";
import { useRef } from "react";
import { useUiTools } from "@root/uiTools/store";
interface Props {
openBranchingPage: boolean;
setOpenBranchingPage: () => void;
}
export const SwitchBranchingPanel = () => {
export const SwitchBranchingPanel = ({
openBranchingPage,
setOpenBranchingPage}:Props) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(660));
const isTablet = useMediaQuery(theme.breakpoints.down(1446));
const { openBranchingPanel } = useUiTools();
const ref = useRef();
return !isTablet || openBranchingPanel ? (
return !isTablet || openBranchingPage ? (
<Box sx={{ userSelect: "none", maxWidth: "350px", width: "100%" }}>
<Box
sx={{
@ -35,10 +40,8 @@ export const SwitchBranchingPanel = () => {
}}
>
<Switch
checked={openBranchingPanel}
onChange={({ target }) => {
updateOpenBranchingPanel(target.checked);
}}
checked={openBranchingPage}
onChange={setOpenBranchingPage}
sx={{
width: 50,
height: 30,
@ -92,7 +95,7 @@ export const SwitchBranchingPanel = () => {
</Typography>
</Box>
</Box>
{openBranchingPanel && <QuestionsList />}
{openBranchingPage && <QuestionsList />}
</Box>
) : (
<></>

@ -63,13 +63,16 @@ import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
import { ModalInfoWhyCantCreate } from "./ModalInfoWhyCantCreate";
import { ConfirmLeaveModal } from "./ConfirmLeaveModal";
import { checkQuestionHint } from "@utils/checkQuestionHint";
import { deleteTimeoutedQuestions } from "@utils/deleteTimeoutedQuestions";
let init:() => void
export default function EditPage() {
const quiz = useCurrentQuiz();
const { editQuizId } = useQuizStore();
const { questions } = useQuestionsStore();
console.log(quiz);
console.log('quiz ',quiz);
console.log(questions);
useEffect(() => {
const getData = async () => {
const quizes = await quizApi.getList();
@ -78,19 +81,21 @@ export default function EditPage() {
if (editQuizId) {
const questions = await questionApi.getList({ quiz_id: editQuizId });
setQuestions(questions);
//Всегда должен существовать хоть 1 резулт - "line"
// console.log("сейчас будем ворошиться в этих квешенах ", questions);
if (
!questions?.find(
(q) =>
(q.type === "result" && q.content.includes(':"line"')) ||
q.content.includes(":'line'")
)
) {
createResult(quiz?.backendId, "line");
console.log("Я не нашёл линейный резулт и собираюсь создать новый")
}
}
//Всегда должен существовать хоть 1 резулт - "line"
console.log(questions);
if (
!questions?.find(
(q) =>
(q.type === "result" && q.content.includes(':"line"')) ||
q.content.includes(":'line'")
)
)
createResult(quiz?.backendId, "line");
};
getData();
}, []);
@ -110,6 +115,14 @@ export default function EditPage() {
const [nextStep, setNextStep] = useState<number>(0);
const quizConfig = quiz?.config;
const disableTest = quiz === undefined ? true : quiz.config.type === null;
const [openBranchingPage, setOpenBranchingPage] = useState<boolean>(false);
const openBranchingPageHC = () => {
if (!openBranchingPage) {
deleteTimeoutedQuestions(questions, quiz)
}
setOpenBranchingPage(old => !old)
}
useEffect(() => {
if (editQuizId === null) navigate("/list");
@ -310,6 +323,8 @@ export default function EditPage() {
quizType={quizConfig.type}
quizResults={quizConfig.results}
quizStartPageType={quizConfig.startpageType}
openBranchingPage={openBranchingPage}
setOpenBranchingPage={setOpenBranchingPage}
/>
</>
)}
@ -344,8 +359,8 @@ export default function EditPage() {
}}
>
<Switch
checked={openBranchingPanel}
onChange={(e) => updateOpenBranchingPanel(e.target.checked)}
checked={openBranchingPage}
onChange={openBranchingPageHC}
sx={{
width: 50,
height: 30,
@ -413,7 +428,7 @@ export default function EditPage() {
}}
onClick={() =>
Object.keys(whyCantCreatePublic).length === 0
? () => {}
? () => { }
: updateModalInfoWhyCantCreate(true)
}
>
@ -459,10 +474,10 @@ export default function EditPage() {
onClick={
Object.keys(whyCantCreatePublic).length === 0
? () =>
updateQuiz(quiz?.id, (state) => {
state.status =
quiz?.status === "start" ? "stop" : "start";
})
updateQuiz(quiz?.id, (state) => {
state.status =
quiz?.status === "start" ? "stop" : "start";
})
: () => updateModalInfoWhyCantCreate(true)
}
>

@ -177,7 +177,7 @@ const REQUEST_DEBOUNCE = 200;
const requestQueue = new RequestQueue();
let requestTimeoutId: ReturnType<typeof setTimeout>;
export const updateQuestion = <T = AnyTypedQuizQuestion>(
export const updateQuestion = async <T = AnyTypedQuizQuestion>(
questionId: string,
updateFn: (question: T) => void,
skipQueue = false,
@ -481,20 +481,22 @@ export const getQuestionByContentId = (questionContentId: string | null) => {
export const clearRuleForAll = () => {
const { questions } = useQuestionsStore.getState();
questions.forEach(question => {
if (question.type !== null &&
return Promise.allSettled(
questions.map(question => {
if (question.type !== null &&
(question.content.rule.main.length > 0
|| question.content.rule.default.length > 0
|| question.content.rule.parentId.length > 0)
&& question.type !== "result") {
updateQuestion(question.content.id, question => {
question.content.rule.parentId = "";
question.content.rule.main = [];
question.content.rule.default = "";
});
}
});
|| question.content.rule.default.length > 0
|| question.content.rule.parentId.length > 0)
&& question.type !== "result") {
console.log("вызываю очистку рул вопросов")
updateQuestion(question.content.id, question => {
question.content.rule.parentId = "";
question.content.rule.main = [];
question.content.rule.default = "";
});
}
})
)
};
export const createResult = async (
@ -506,7 +508,7 @@ export const createResult = async (
}
//Мы получили запрос на создание резулта. Анализируем существует ли такой. Если да - просто делаем его активным
const question = useQuestionsStore.getState().questions.find(q=> q.type !== null && q?.content.rule.parentId === parentContentId)
const question = useQuestionsStore.getState().questions.find(q => q.type !== null && q?.content.rule.parentId === parentContentId)
console.log("Получил запрос на создание результа родителю ", parentContentId)
console.log("Ищу такой же результ в списке ", question)
@ -519,9 +521,9 @@ export const createResult = async (
} else {//не существует, создаём
const content = JSON.parse(JSON.stringify(defaultQuestionByType["result"].content));
content.rule.parentId = parentContentId;
try {
const createdQuestion:RawQuestion = await questionApi.create({
const createdQuestion: RawQuestion = await questionApi.create({
quiz_id: quizId,
type: "result",
title: "",
@ -530,7 +532,7 @@ export const createResult = async (
required: true,
content: JSON.stringify(content),
});
setProducedState(state => {
state.questions.push(rawQuestionToQuestion(createdQuestion))
}, {
@ -541,6 +543,6 @@ export const createResult = async (
devlog("Error creating question", error);
enqueueSnackbar("Не удалось создать вопрос");
}
}
}
});

@ -39,3 +39,6 @@ export const updateCanCreatePublic = (can: boolean) => useUiTools.setState({ can
export const updateModalInfoWhyCantCreate = (can: boolean) => useUiTools.setState({ openModalInfoWhyCantCreate: can });
export const updateDeleteId = (deleteNodeId: string | null = null) => useUiTools.setState({ deleteNodeId });
export const setShowConfirmLeaveModal = (showConfirmLeaveModal: boolean) => useUiTools.setState({ showConfirmLeaveModal });
export const updateSomeWorkBackend = (someWorkBackend: boolean) => useUiTools.setState({ someWorkBackend });

@ -12,6 +12,7 @@ export type UiTools = {
openModalInfoWhyCantCreate: boolean;
deleteNodeId: string | null;
showConfirmLeaveModal: boolean;
someWorkBackend: boolean;
};
export type WhyCantCreatePublic = {
@ -31,6 +32,7 @@ const initialState: UiTools = {
openModalInfoWhyCantCreate: false,
deleteNodeId: null,
showConfirmLeaveModal: false,
someWorkBackend: false
};
export const useUiTools = create<UiTools>()(

@ -16,6 +16,8 @@ interface Props {
quizType: QuizType;
quizStartPageType: QuizStartpageType;
quizResults: QuizResultsType;
openBranchingPage: boolean;
setOpenBranchingPage: (a:boolean) => void;
}
export default function SwitchStepPages({
@ -23,6 +25,8 @@ export default function SwitchStepPages({
quizType,
quizStartPageType,
quizResults,
openBranchingPage,
setOpenBranchingPage
}: Props) {
switch (activeStep) {
case 0: {
@ -30,7 +34,10 @@ export default function SwitchStepPages({
if (!quizStartPageType) return <Steptwo />;
return <StartPageSettings />;
}
case 1: return quizType === "form" ? <FormQuestionsPage /> : <QuestionsPage />;
case 1: return quizType === "form" ? <FormQuestionsPage /> : <QuestionsPage
openBranchingPage={openBranchingPage}
setOpenBranchingPage={setOpenBranchingPage}
/>;
case 2: return <ResultPage />;
case 3: return <ContactFormPage />;
case 4: return <InstallQuiz />;

66
src/utils/deleteFunc.ts Normal file

@ -0,0 +1,66 @@
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
import { clearRuleForAll, deleteQuestion, getQuestionByContentId, updateQuestion } from "@root/questions/actions";
import { updateRootContentId } from "@root/quizes/actions";
//Всё здесь нужно сделать последовательно. И пусть весь мир ждёт.
export const DeleteFunction = async (questions: any, question: any, quiz: any) => {
if (question.type !== null) {
if (question.content.rule.parentId === "root") { //удалить из стора root и очистить rule всем вопросам
updateRootContentId(quiz.id, "");
await clearRuleForAll();
console.log("очистка рулов закончилась")
await 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);
//чистим потомков от инфы ветвления
await Promise.allSettled(
clearQuestions.map((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);
await updateQuestion(question.content.rule.parentId, (PQ) => {
PQ.content.rule = newRule;
});
await deleteQuestion(question.id);
}
await deleteQuestion(question.id);
const result = questions.find(q => q.type === "result" && q.content.rule.parentId === question.content.id)
if (result) await deleteQuestion(result.id);
} else {
await deleteQuestion(question.id);
}
}

@ -0,0 +1,25 @@
import { AnyTypedQuizQuestion, UntypedQuizQuestion } from "@model/questionTypes/shared";
import { Quiz } from "@model/quiz/quiz";
import { updateSomeWorkBackend } from "@root/uiTools/actions";
import { DeleteFunction } from "@utils/deleteFunc";
type allQuestionsTypes = AnyTypedQuizQuestion | UntypedQuizQuestion
export const deleteTimeoutedQuestions = async (questions: allQuestionsTypes[], quiz: Quiz|undefined) => {
console.log("Я отвечаю за удаление неудалёнышей при переключении. Привет, буде знакомы")
const questionsForDeletion = questions.filter(
({ type, deleted }) => type && type !== "result" && deleted
) as AnyTypedQuizQuestion[];
if (questionsForDeletion.length > 0) {
console.log("меняю занятость беком на true")
updateSomeWorkBackend(true)
await Promise.allSettled(
questionsForDeletion.map(question => DeleteFunction(questions, question, quiz))
)
console.log("______________меняю на 'можно редактировать дальше'______________")
updateSomeWorkBackend(false)
}
};