diff --git a/src/constants/base.ts b/src/constants/base.ts index fbb62c3a..f588bfc6 100644 --- a/src/constants/base.ts +++ b/src/constants/base.ts @@ -18,6 +18,7 @@ export const QUIZ_QUESTION_BASE: Omit = { video: "", }, rule: { + children: [], main: [] as QuestionBranchingRuleMain[], parentId: "", default: "" diff --git a/src/model/questionTypes/shared.ts b/src/model/questionTypes/shared.ts index e0607c83..fb1ed933 100644 --- a/src/model/questionTypes/shared.ts +++ b/src/model/questionTypes/shared.ts @@ -23,6 +23,7 @@ export interface QuestionBranchingRuleMain { } export interface QuestionBranchingRule { + children: string[], //список условий main: QuestionBranchingRuleMain[]; parentId: string | null | "root"; diff --git a/src/pages/Questions/BranchingMap/CsComponent.tsx b/src/pages/Questions/BranchingMap/CsComponent.tsx index e836dc35..127af77d 100644 --- a/src/pages/Questions/BranchingMap/CsComponent.tsx +++ b/src/pages/Questions/BranchingMap/CsComponent.tsx @@ -7,7 +7,7 @@ import { useCurrentQuiz } from "@root/quizes/hooks"; import { updateRootContentId } from "@root/quizes/actions" import { AnyTypedQuizQuestion } from "@model/questionTypes/shared" import { useQuestionsStore } from "@root/questions/store"; -import { cleardragQuestionContentId, updateQuestion, updateOpenedModalSettingsId, getQuestionByContentId, clearRuleForAll } from "@root/questions/actions"; +import { deleteQuestion, cleardragQuestionContentId, updateQuestion, updateOpenedModalSettingsId, getQuestionByContentId, clearRuleForAll } from "@root/questions/actions"; import { withErrorBoundary } from "react-error-boundary"; import { storeToNodes } from "./helper"; @@ -112,13 +112,13 @@ interface Props { } -function CsComponent ({ +function CsComponent({ modalQuestionParentContentId, modalQuestionTargetContentId, setOpenedModalQuestions, setModalQuestionParentContentId, setModalQuestionTargetContentId -}: Props) { +}: Props) { const quiz = useCurrentQuiz(); const { dragQuestionContentId, desireToOpenABranchingModal } = useQuestionsStore() @@ -192,13 +192,15 @@ function CsComponent ({ question.content.rule.parentId = parentNodeContentId question.content.rule.main = [] }) + //предупреждаем родителя о новом потомке + updateQuestion(parentNodeContentId, question => { + question.content.rule.children = [...question.content.rule.children, targetQuestion.content.id] + }) + //Если детей больше 1 - предупреждаем стор вопросов об открытии модалки ветвления if (parentNodeChildren >= 1) { updateOpenedModalSettingsId(targetQuestion.content.id) - } else { - //Если ребёнок первый - добавляем его родителю как дефолтный - updateQuestion(parentNodeContentId, question => question.content.rule.default = targetQuestion.content.id) } } @@ -232,10 +234,18 @@ function CsComponent ({ updateQuestion(targetNodeContentId, question => { question.content.rule.parentId = "" question.content.rule.main = [] + question.content.rule.children = [] question.content.rule.default = "" }) + questions.forEach(q => { + if (q.type === "result") { + deleteQuestion(q.id); + } + }); clearRuleForAll() + } else { + const parentQuestionContentId = cy?.$('edge[target = "' + targetNodeContentId + '"]')?.toArray()?.[0]?.data()?.source if (targetNodeContentId && parentQuestionContentId) { @@ -245,7 +255,7 @@ function CsComponent ({ } - //После всех манипуляций удаляем грани из CS и ноды из бекенда + //После всех манипуляций удаляем грани и ноды из CS Чистим rule потомков на беке deleteNodes.forEach((nodeId) => {//Ноды cy?.remove(cy?.$("#" + nodeId)) @@ -254,6 +264,7 @@ function CsComponent ({ question.content.rule.parentId = "" question.content.rule.main = [] question.content.rule.default = "" + question.content.rule.children = [] }) }) @@ -264,28 +275,37 @@ function CsComponent ({ removeButtons(targetNodeContentId) cy?.data('changed', true) cy?.layout(lyopts).run() + + //удаляем result всех потомков + questions.forEach((targetQuestion) => { + if (deleteNodes.includes(targetQuestion.content.rule.parentId)) { + if (targetQuestion.type === "result") { + deleteQuestion(targetQuestion.id); + } + } + }) } + + const clearDataAfterRemoveNode = ({ targetQuestionContentId, parentQuestionContentId }: { targetQuestionContentId: string, parentQuestionContentId: string }) => { - - console.log("target ",targetQuestionContentId, "parent ", parentQuestionContentId) - - + + console.log("target ", targetQuestionContentId, "parent ", parentQuestionContentId) + + updateQuestion(targetQuestionContentId, question => { question.content.rule.parentId = "" + question.content.rule.children = [] question.content.rule.main = [] question.content.rule.default = "" }) //чистим rule родителя - const parentQuestion = getQuestionByContentId(parentQuestionContentId) + const parentQuestion = getQuestionByContentId(targetQuestionContentId) const newRule = {} newRule.main = parentQuestion.content.rule.main.filter((data) => data.next !== targetQuestionContentId) //удаляем условия перехода от родителя к этому вопросу newRule.parentId = parentQuestion.content.rule.parentId - newRule.default = questions.filter((q) => { - return q.content.rule.parentId === parentQuestionContentId && q.content.id !== targetQuestionContentId - })[0]?.content.id || "" - //Если этот вопрос был дефолтным у родителя - чистим дефолт - //Смотрим можем ли мы заменить id на один из main + newRule.default = parentQuestion.content.rule.parentId === targetQuestionContentId ? "" : parentQuestion.content.rule.parentId + newRule.children = [...parentQuestion.content.rule.children].splice(parentQuestion.content.rule.children.indexOf(question.content.id), 1); updateQuestion(parentQuestionContentId, (PQ) => { PQ.content.rule = newRule @@ -335,7 +355,7 @@ function CsComponent ({ positions: (e) => { if (!e.cy().data('changed')) { return e.data('oldPos') - } + } const id = e.id() const incomming = e.cy().edges(`[target="${id}"]`) const layer = 0 @@ -366,7 +386,7 @@ function CsComponent ({ while (queue.length) { const task = queue.pop() if (task.children.length === 0) { - task.parent.data('subtreeWidth', task.parent.height()+50) + task.parent.data('subtreeWidth', task.parent.height() + 50) continue } const unprocessed = task?.children.filter(e => { @@ -385,19 +405,19 @@ function CsComponent ({ const pos = { x: 0, y: 0 } e.data('oldPos', pos) - - queue.push({task: children, parent: e}) + + queue.push({ task: children, parent: e }) while (queue.length) { const task = queue.pop() const oldPos = task.parent.data('oldPos') - let yoffset = oldPos.y - task.parent.data('subtreeWidth') / 2 + let yoffset = oldPos.y - task.parent.data('subtreeWidth') / 2 task.task.forEach(n => { const width = n.data('subtreeWidth') - console.log('ORORORORO',n.data(), yoffset, width, oldPos, task.parent.data('subtreeWidth')) - n.data('oldPos',{x: 250 * n.data('layer'),y: yoffset + width/2}) - yoffset+=width - queue.push({task: n.cy().edges(`[source="${n.id()}"]`).targets(), parent: n}) + console.log('ORORORORO', n.data(), yoffset, width, oldPos, task.parent.data('subtreeWidth')) + n.data('oldPos', { x: 250 * n.data('layer'), y: yoffset + width / 2 }) + yoffset += width + queue.push({ task: n.cy().edges(`[source="${n.id()}"]`).targets(), parent: n }) }) } e.cy().data('changed', false) @@ -407,7 +427,7 @@ function CsComponent ({ const opos = e.data('oldPos') if (opos) { return opos - } + } } }, // map of (node id) => (position obj); or function(node){ return somPos; } zoom: undefined, // the zoom level to set (prob want fit = false if set) @@ -425,7 +445,7 @@ function CsComponent ({ useEffect(() => { document.querySelector("#root")?.addEventListener("mouseup", cleardragQuestionContentId); const cy = cyRef.current; - const eles = cy?.add(storeToNodes(questions.filter((question:AnyTypedQuizQuestion) => (question.type !== "result" && question.type !== null)))) + const eles = cy?.add(storeToNodes(questions.filter((question: AnyTypedQuizQuestion) => (question.type !== "result" && question.type !== null)))) cy.data('changed', true) // cy.data('changed', true) const elecs = eles.layout(lyopts).run() @@ -693,23 +713,23 @@ function CsComponent ({ return ( <> - + }} + > + Выровнять + { cyRef.current = cy; }} - autoungrabify={true} + autoungrabify={true} />