при удалении вопросов из списка и или дерева гарантируем, что default будет заполнен оставшимися потомками. очистим main от удаляемого потомка. сломанное дерево очистится
This commit is contained in:
parent
7cfb84534f
commit
1eca4195c5
@ -40,6 +40,7 @@
|
|||||||
"react-dnd-html5-backend": "^16.0.1",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-easy-crop": "^5.0.0",
|
"react-easy-crop": "^5.0.0",
|
||||||
|
"react-error-boundary": "^4.0.11",
|
||||||
"react-image-crop": "^10.1.5",
|
"react-image-crop": "^10.1.5",
|
||||||
"react-image-file-resizer": "^0.4.8",
|
"react-image-file-resizer": "^0.4.8",
|
||||||
"react-rnd": "^10.4.1",
|
"react-rnd": "^10.4.1",
|
||||||
|
@ -6,7 +6,8 @@ import { useCurrentQuiz } from "@root/quizes/hooks";
|
|||||||
import { updateRootContentId } from "@root/quizes/actions"
|
import { updateRootContentId } from "@root/quizes/actions"
|
||||||
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"
|
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"
|
||||||
import { useQuestionsStore } from "@root/questions/store";
|
import { useQuestionsStore } from "@root/questions/store";
|
||||||
import { cleardragQuestionContentId, updateQuestion, updateOpenedModalSettingsId, getQuestionByContentId } from "@root/questions/actions";
|
import { cleardragQuestionContentId, updateQuestion, updateOpenedModalSettingsId, getQuestionByContentId, clearRuleForAll } from "@root/questions/actions";
|
||||||
|
import { withErrorBoundary } from "react-error-boundary";
|
||||||
|
|
||||||
import { storeToNodes } from "./helper";
|
import { storeToNodes } from "./helper";
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ import type {
|
|||||||
} from "cytoscape";
|
} from "cytoscape";
|
||||||
import { QuestionsList } from "../SwitchBranchingPanel/QuestionsList";
|
import { QuestionsList } from "../SwitchBranchingPanel/QuestionsList";
|
||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
|
import { Typography } from "@mui/material";
|
||||||
|
|
||||||
type PopperItem = {
|
type PopperItem = {
|
||||||
id: () => string;
|
id: () => string;
|
||||||
@ -111,13 +113,13 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const CsComponent = ({
|
function CsComponent ({
|
||||||
modalQuestionParentContentId,
|
modalQuestionParentContentId,
|
||||||
modalQuestionTargetContentId,
|
modalQuestionTargetContentId,
|
||||||
setOpenedModalQuestions,
|
setOpenedModalQuestions,
|
||||||
setModalQuestionParentContentId,
|
setModalQuestionParentContentId,
|
||||||
setModalQuestionTargetContentId
|
setModalQuestionTargetContentId
|
||||||
}: Props) => {
|
}: Props) {
|
||||||
const quiz = useCurrentQuiz();
|
const quiz = useCurrentQuiz();
|
||||||
|
|
||||||
const { dragQuestionContentId, questions, desireToOpenABranchingModal } = useQuestionsStore()
|
const { dragQuestionContentId, questions, desireToOpenABranchingModal } = useQuestionsStore()
|
||||||
@ -131,17 +133,19 @@ export const CsComponent = ({
|
|||||||
const gearsContainer = useRef<HTMLDivElement | null>(null);
|
const gearsContainer = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const cy = cyRef?.current
|
const cy = cyRef?.current
|
||||||
if (desireToOpenABranchingModal) {
|
if (desireToOpenABranchingModal) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
cy?.getElementById(desireToOpenABranchingModal)?.data("eroticeyeblink", true)
|
cy?.getElementById(desireToOpenABranchingModal)?.data("eroticeyeblink", true)
|
||||||
}, 250)
|
}, 250)
|
||||||
} else {
|
} else {
|
||||||
cy?.elements().data("eroticeyeblink", false)
|
cy?.elements().data("eroticeyeblink", false)
|
||||||
}
|
}
|
||||||
}, [desireToOpenABranchingModal])
|
}, [desireToOpenABranchingModal])
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
updateOpenedModalSettingsId()
|
updateOpenedModalSettingsId()
|
||||||
|
// updateRootContentId(quiz.id, "")
|
||||||
|
// clearRuleForAll()
|
||||||
}, [])
|
}, [])
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (modalQuestionTargetContentId.length !== 0 && modalQuestionParentContentId.length !== 0) {
|
if (modalQuestionTargetContentId.length !== 0 && modalQuestionParentContentId.length !== 0) {
|
||||||
@ -149,7 +153,6 @@ const cy = cyRef?.current
|
|||||||
}
|
}
|
||||||
setModalQuestionParentContentId("")
|
setModalQuestionParentContentId("")
|
||||||
setModalQuestionTargetContentId("")
|
setModalQuestionTargetContentId("")
|
||||||
|
|
||||||
}, [modalQuestionTargetContentId])
|
}, [modalQuestionTargetContentId])
|
||||||
|
|
||||||
const addNode = ({ parentNodeContentId, targetNodeContentId }: { parentNodeContentId: string, targetNodeContentId?: string }) => {
|
const addNode = ({ parentNodeContentId, targetNodeContentId }: { parentNodeContentId: string, targetNodeContentId?: string }) => {
|
||||||
@ -229,6 +232,7 @@ const cy = cyRef?.current
|
|||||||
question.content.rule.main = []
|
question.content.rule.main = []
|
||||||
question.content.rule.default = ""
|
question.content.rule.default = ""
|
||||||
})
|
})
|
||||||
|
clearRuleForAll()
|
||||||
} else {
|
} else {
|
||||||
const parentQuestionContentId = cy?.$('edge[target = "' + targetNodeContentId + '"]')?.toArray()?.[0]?.data()?.source
|
const parentQuestionContentId = cy?.$('edge[target = "' + targetNodeContentId + '"]')?.toArray()?.[0]?.data()?.source
|
||||||
if (targetNodeContentId && parentQuestionContentId) {
|
if (targetNodeContentId && parentQuestionContentId) {
|
||||||
@ -266,11 +270,21 @@ const cy = cyRef?.current
|
|||||||
question.content.rule.default = ""
|
question.content.rule.default = ""
|
||||||
})
|
})
|
||||||
|
|
||||||
updateQuestion(parentQuestionContentId, question => {
|
//чистим rule родителя
|
||||||
//Заменяем id удаляемого вопроса либо на id одного из оставшихся, либо на пустую строку
|
const parentQuestion = getQuestionByContentId(parentQuestionContentId)
|
||||||
if (question.content.rule.default === targetQuestionContentId) question.content.rule.default = ""
|
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
|
||||||
|
|
||||||
|
console.log(newRule)
|
||||||
|
updateQuestion(parentQuestionContentId, (PQ) => {
|
||||||
|
PQ.content.rule = newRule
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -686,7 +700,7 @@ const cy = cyRef?.current
|
|||||||
}}
|
}}
|
||||||
// autolock
|
// autolock
|
||||||
/>
|
/>
|
||||||
{/* <button onClick={() => {
|
<button onClick={() => {
|
||||||
console.log("NODES____________________________")
|
console.log("NODES____________________________")
|
||||||
cyRef.current?.elements().forEach((ele: any) => {
|
cyRef.current?.elements().forEach((ele: any) => {
|
||||||
console.log(ele.data())
|
console.log(ele.data())
|
||||||
@ -695,7 +709,23 @@ const cy = cyRef?.current
|
|||||||
<button onClick={() => {
|
<button onClick={() => {
|
||||||
console.log("ELEMENTS____________________________")
|
console.log("ELEMENTS____________________________")
|
||||||
console.log(questions)
|
console.log(questions)
|
||||||
}}>elements</button> */}
|
}}>elements</button>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function Clear () {
|
||||||
|
const quiz = useCurrentQuiz();
|
||||||
|
updateRootContentId(quiz.id, "")
|
||||||
|
clearRuleForAll()
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(CsComponent, {
|
||||||
|
fallback: <Clear/>,
|
||||||
|
onError: (error, info) => {
|
||||||
|
enqueueSnackbar("Дерево порвалось")
|
||||||
|
console.log(info)
|
||||||
|
console.log(error)
|
||||||
|
},
|
||||||
|
});
|
@ -1,6 +1,6 @@
|
|||||||
import { Box } from "@mui/material";
|
import { Box } from "@mui/material";
|
||||||
import { FirstNodeField } from "./FirstNodeField";
|
import { FirstNodeField } from "./FirstNodeField";
|
||||||
import { CsComponent } from "./CsComponent";
|
import CsComponent from "./CsComponent";
|
||||||
import { useQuestionsStore } from "@root/questions/store"
|
import { useQuestionsStore } from "@root/questions/store"
|
||||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import { questionApi } from "@api/question";
|
import { questionApi } from "@api/question";
|
||||||
import { quizApi } from "@api/quiz";
|
import { quizApi } from "@api/quiz";
|
||||||
import { devlog } from "@frontend/kitui";
|
import { devlog } from "@frontend/kitui";
|
||||||
@ -13,6 +14,7 @@ import { RequestQueue } from "../../utils/requestQueue";
|
|||||||
import { updateRootContentId } from "@root/quizes/actions"
|
import { updateRootContentId } from "@root/quizes/actions"
|
||||||
import { useCurrentQuiz } from "@root/quizes/hooks"
|
import { useCurrentQuiz } from "@root/quizes/hooks"
|
||||||
import { QuestionsStore, useQuestionsStore } from "./store";
|
import { QuestionsStore, useQuestionsStore } from "./store";
|
||||||
|
import { withErrorBoundary } from "react-error-boundary";
|
||||||
|
|
||||||
|
|
||||||
export const setQuestions = (questions: RawQuestion[] | null) => setProducedState(state => {
|
export const setQuestions = (questions: RawQuestion[] | null) => setProducedState(state => {
|
||||||
@ -321,8 +323,8 @@ export const deleteQuestion = async (questionId: string, quizId: string) => requ
|
|||||||
await questionApi.delete(question.backendId);
|
await questionApi.delete(question.backendId);
|
||||||
if (question.content.rule.parentId === "root") { //удалить из стора root и очистить rule всем вопросам
|
if (question.content.rule.parentId === "root") { //удалить из стора root и очистить rule всем вопросам
|
||||||
updateRootContentId(quizId, "")
|
updateRootContentId(quizId, "")
|
||||||
clearRoleForAll()
|
clearRuleForAll()
|
||||||
} else if (question.content.rule.parentId.length > 0) { //удалить из стора вопрос из дерева и очищаем его потомков
|
} else if (question.content.rule.parentId.length > 0) { //удалить из стора вопрос из дерева и очистить его потомков
|
||||||
const clearQuestions = [] as string[]
|
const clearQuestions = [] as string[]
|
||||||
|
|
||||||
const getChildren = (parentQuestion: AnyTypedQuizQuestion) => {
|
const getChildren = (parentQuestion: AnyTypedQuizQuestion) => {
|
||||||
@ -343,8 +345,22 @@ export const deleteQuestion = async (questionId: string, quizId: string) => requ
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
//чистим 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 = questions.filter((q) => {
|
||||||
|
return q.content.rule.parentId === question.content.rule.parentId && q.content.id !== question.content.id
|
||||||
|
})[0]?.content.id || ""
|
||||||
|
//Если этот вопрос был дефолтным у родителя - чистим дефолт
|
||||||
|
//Смотрим можем ли мы заменить id на один из main
|
||||||
|
|
||||||
|
console.log(newRule)
|
||||||
|
updateQuestion(question.content.rule.parentId, (PQ) => {
|
||||||
|
PQ.content.rule = newRule
|
||||||
|
})
|
||||||
|
}
|
||||||
removeQuestion(questionId);
|
removeQuestion(questionId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
devlog("Error deleting question", error);
|
devlog("Error deleting question", error);
|
||||||
@ -425,7 +441,7 @@ export const updateDragQuestionContentId = (contentId?: string) => {
|
|||||||
useQuestionsStore.setState({ dragQuestionContentId: contentId ? contentId : null });
|
useQuestionsStore.setState({ dragQuestionContentId: contentId ? contentId : null });
|
||||||
}
|
}
|
||||||
|
|
||||||
export const clearRoleForAll = () => {
|
export const clearRuleForAll = () => {
|
||||||
const { questions } = useQuestionsStore.getState()
|
const { questions } = useQuestionsStore.getState()
|
||||||
questions.forEach(question => {
|
questions.forEach(question => {
|
||||||
if (question.type !== null && (question.content.rule.main.length > 0 || question.content.rule.default.length > 0 || question.content.rule.parentId.length > 0)) {
|
if (question.type !== null && (question.content.rule.main.length > 0 || question.content.rule.default.length > 0 || question.content.rule.parentId.length > 0)) {
|
||||||
@ -454,4 +470,4 @@ export const clearDesireToOpenABranchingModal = () => {
|
|||||||
}
|
}
|
||||||
export const updateEditSomeQuestion = (contentId?: string) => {
|
export const updateEditSomeQuestion = (contentId?: string) => {
|
||||||
useQuestionsStore.setState({ editSomeQuestion: contentId === undefined ? null : contentId })
|
useQuestionsStore.setState({ editSomeQuestion: contentId === undefined ? null : contentId })
|
||||||
}
|
}
|
||||||
|
@ -8628,6 +8628,13 @@ react-easy-crop@^5.0.0:
|
|||||||
normalize-wheel "^1.0.1"
|
normalize-wheel "^1.0.1"
|
||||||
tslib "2.0.1"
|
tslib "2.0.1"
|
||||||
|
|
||||||
|
react-error-boundary@^4.0.11:
|
||||||
|
version "4.0.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-4.0.11.tgz#36bf44de7746714725a814630282fee83a7c9a1c"
|
||||||
|
integrity sha512-U13ul67aP5DOSPNSCWQ/eO0AQEYzEFkVljULQIjMV0KlffTAhxuDoBKdO0pb/JZ8mDhMKFZ9NZi0BmLGUiNphw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.12.5"
|
||||||
|
|
||||||
react-error-overlay@^6.0.11:
|
react-error-overlay@^6.0.11:
|
||||||
version "6.0.11"
|
version "6.0.11"
|
||||||
resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz"
|
resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz"
|
||||||
|
Loading…
Reference in New Issue
Block a user