This commit is contained in:
Nastya 2023-12-01 11:12:59 +03:00
parent 9a880f5b90
commit 2b38c15e3e
6 changed files with 233 additions and 296 deletions

@ -3,9 +3,9 @@ import Cytoscape from "cytoscape";
import CytoscapeComponent from "react-cytoscapejs"; import CytoscapeComponent from "react-cytoscapejs";
import popper from "cytoscape-popper"; import popper from "cytoscape-popper";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
import { AnyQuizQuestion } from "@model/questionTypes/shared"
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { clearDragQuestionId } from "@root/questions/actions"; import { clearDragQuestionId, getQuestionById, updateQuestion, updateOpenedModalSettingsId } from "@root/questions/actions";
import { storeToNodes } from "./helper"; import { storeToNodes } from "./helper";
@ -93,6 +93,7 @@ const stylesheet: Stylesheet[] = [
Cytoscape.use(popper); Cytoscape.use(popper);
export const CsComponent = () => { export const CsComponent = () => {
console.log("Я существую")
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const { dragQuestionId, questions } = useQuestionsStore() const { dragQuestionId, questions } = useQuestionsStore()
@ -100,27 +101,53 @@ export const CsComponent = () => {
const [startRemove, setStartRemove] = useState(""); const [startRemove, setStartRemove] = useState("");
const cyRef = useRef<Core | null>(null); const cyRef = useRef<Core | null>(null);
const layoutsContainer = useRef<HTMLDivElement | null>(null);
const plusesContainer = useRef<HTMLDivElement | null>(null); const plusesContainer = useRef<HTMLDivElement | null>(null);
const crossesContainer = useRef<HTMLDivElement | null>(null); const crossesContainer = useRef<HTMLDivElement | null>(null);
const gearsContainer = useRef<HTMLDivElement | null>(null); const gearsContainer = useRef<HTMLDivElement | null>(null);
const addNode = ({ parentNodeId }: { parentNodeId: string }) => { const addNode = ({ parentNodeId }: { parentNodeId: string }) => {
const cy = cyRef?.current const cy = cyRef?.current
const parentNodeChildren = cy?.$('edge[source = "' + parentNodeId + '"]').length
const targetQuestion = { ...getQuestionById(dragQuestionId) } as AnyQuizQuestion
console.log(parentNodeChildren, parentNodeId)
if (targetQuestion && targetQuestion && parentNodeId && parentNodeChildren !== undefined) {
cy?.add([
{
data: {
id: targetQuestion.id,
label: targetQuestion.title || "noname"
}
},
{
data: {
source: parentNodeId,
target: targetQuestion.id
}
}
])
//Если детей больше 1 - предупреждаем стор вопросов об открытии модалки ветвления //Если детей больше 1 - предупреждаем стор вопросов об открытии модалки ветвления
// if (Object.keys(currentNode.children).length > 1) { if (parentNodeChildren > 1) {
// setOpenedModalSettings(question.index) updateOpenedModalSettingsId(parentNodeId)
// } else { } else {
// //Если ребёнок первый - добавляем его родителю как дефолтный //Если ребёнок первый - добавляем его родителю как дефолтный
// parentQuestion.question.content.rule.default = Object.keys(newNode)[0].split("_").pop() updateQuestion(parentNodeId, question => question.content.rule.default = targetQuestion.id)
// updateQuestionsList(quiz, parentQuestion.index, parentQuestion.question); }
// }
//предупреждаем добавленный вопрос о том, кто его родитель
updateQuestion(targetQuestion.id, question => question.content.rule.parentId = parentNodeId)
}
console.log(dragQuestionId) console.log(dragQuestionId)
// cy?.add({
// })
} }
useEffect(() => { useEffect(() => {
@ -141,137 +168,12 @@ export const CsComponent = () => {
useEffect(() => { useEffect(() => {
document.querySelector("#root")?.addEventListener("mouseup", clearDragQuestionId); document.querySelector("#root")?.addEventListener("mouseup", clearDragQuestionId);
const cy = cyRef.current; const cy = cyRef.current;
//cy?.add(storeToNodes(questions)) cy?.add(storeToNodes(questions))
cy?.add( cy?.layout(ly).run()
[
{
"data": {
"id": "1",
"label": "2"
}
},
{
"data": {
"id": "1 2",
"label": "Вы идёте в школу"
}
},
{
"data": {
"id": "1 3",
"label": "1"
}
},
{
"data": {
"id": "1 2 4",
"label": "3"
}
},
{
"data": {
"id": "1 2 6",
"label": "5"
}
},
{
"data": {
"id": "1 3 5",
"label": "4"
}
},
{
"data": {
"id": "1 3 7",
"label": "6"
}
},
{
"data": {
"id": "1 2 6 9867874",
"label": "7"
}
},
{
"data": {
"id": "1 2 6 7398789",
"label": "8"
}
},
{
"data": {
"id": "1 2 6 9484789",
"label": "11"
}
},
{
"data": {
"source": "1",
"target": "1 2",
"id": "c4881f18-03cf-4ed1-bbc4-1741007f11c5"
}
},
{
"data": {
"source": "1",
"target": "1 3",
"id": "3cc5a94a-0192-4ea2-bdc6-ce1a157b76d4"
}
},
{
"data": {
"source": "1 2",
"target": "1 2 4",
"id": "1baf1bc6-eb40-4c81-b137-27cdd3a15e60"
}
},
{
"data": {
"source": "1 2",
"target": "1 2 6",
"id": "78af38cc-7609-401c-bbff-ebdb3f67ec14"
}
},
{
"data": {
"source": "1 3",
"target": "1 3 5",
"id": "a1c80f9f-7c4b-455c-8ba9-ef5dce5522b5"
}
},
{
"data": {
"source": "1 3",
"target": "1 3 7",
"id": "85ed3ee9-fdd1-4874-8e36-484db46bf1c5"
}
},
{
"data": {
"source": "1 2 6",
"target": "1 2 6 9867874",
"id": "f139548a-abca-412b-9935-740f219a938d"
}
},
{
"data": {
"source": "1 2 6",
"target": "1 2 6 7398789",
"id": "ec8dd60c-df49-447f-b85a-4ae00cde1ae9"
}
},
{
"data": {
"source": "1 2 6",
"target": "1 2 6 9484789",
"id": "9b5ecc61-d0ca-4872-a2a4-4fd72835345e"
}
}
]
)
return () => { return () => {
document.querySelector("#root")?.removeEventListener("mouseup", clearDragQuestionId); document.querySelector("#root")?.removeEventListener("mouseup", clearDragQuestionId);
layoutsContainer.current?.remove();
plusesContainer.current?.remove(); plusesContainer.current?.remove();
crossesContainer.current?.remove(); crossesContainer.current?.remove();
gearsContainer.current?.remove(); gearsContainer.current?.remove();
@ -280,6 +182,9 @@ export const CsComponent = () => {
const removeButtons = (id: string) => { const removeButtons = (id: string) => {
layoutsContainer.current
?.querySelector(`.popper-layout[data-id='${id}']`)
?.remove();
plusesContainer.current plusesContainer.current
?.querySelector(`.popper-plus[data-id='${id}']`) ?.querySelector(`.popper-plus[data-id='${id}']`)
?.remove(); ?.remove();
@ -291,216 +196,26 @@ export const CsComponent = () => {
?.remove(); ?.remove();
}; };
const initialCS = () => {
const cy = cyRef.current;
const container =
(document.body.querySelector(
".__________cytoscape_container"
) as HTMLDivElement) || null;
if (!container) {
return;
}
container.style.overflow = "hidden";
if (!plusesContainer.current) {
plusesContainer.current = document.createElement("div");
plusesContainer.current.setAttribute("id", "popper-pluses");
container.append(plusesContainer.current);
}
if (!crossesContainer.current) {
crossesContainer.current = document.createElement("div");
crossesContainer.current.setAttribute("id", "popper-crosses");
container.append(crossesContainer.current);
}
if (!gearsContainer.current) {
gearsContainer.current = document.createElement("div");
gearsContainer.current.setAttribute("id", "popper-gears");
container.append(gearsContainer.current);
}
cy?.nodes()
.toArray()
?.forEach((item) => {
const node = item as NodeSingularWithPopper;
const plusesPopper = node.popper({ const readyLO = (e) => {
popper: { //удаляем иконки
placement: "right", e.cy.nodes().forEach((ele: any) => {
modifiers: [{ name: "flip", options: { boundary: node } }], const data = ele.data()
}, data.id && removeButtons(data.id);
content: ([item]) => {
const itemId = item.id();
const itemElement = plusesContainer.current?.querySelector(
`.popper-plus[data-id='${itemId}']`
);
if (itemElement) {
return itemElement;
}
const plusElement = document.createElement("div");
plusElement.classList.add("popper-plus");
plusElement.setAttribute("data-id", item.id());
plusesContainer.current?.appendChild(plusElement);
plusElement.addEventListener("mouseup", () =>
setStartCreate(node.id())
);
return plusElement;
},
});
const crossesPopper = node.popper({
popper: {
placement: "top-end",
modifiers: [
{ name: "flip", options: { boundary: node } },
{
name: "hide",
options: { enabled: true },
},
],
},
content: ([item]) => {
const itemId = item.id();
const itemElement = crossesContainer.current?.querySelector(
`.popper-cross[data-id='${itemId}']`
);
if (itemElement) {
return itemElement;
}
const crossElement = document.createElement("div");
crossElement.classList.add("popper-cross");
crossElement.setAttribute("data-id", item.id());
crossesContainer.current?.appendChild(crossElement);
crossElement.addEventListener("click", () => {
console.log('#' + node.id() + ' node', cy.edges('[source = "' + node.id() + '"]'))
console.log('[source = "' + node.id() + '"]')
console.log(cy?.collection)
// cy?.remove('[source = "'+node.id()+'"]')
console.log("папа")
console.log(cy?.$('[target = "' + node.id() + '"]').data().source)
cy?.remove('#' + node.id())
// setStartRemove(node.id())
}
);
node.on('remove', evt => {
console.log(cy.edges())
// cy?.remove('#'+evt.target.target())
}) })
initialPopperIcons(e)
return crossElement; console.log('ready', e)
}, console.log(e.cy.nodes())
}); console.log(e.cy.nodes().data())
const gearsPopper = node.popper({
popper: {
placement: "left",
modifiers: [{ name: "flip", options: { boundary: node } }],
},
content: ([item]) => {
const itemId = item.id();
// if (item.id() === elements[0].data.id) {
// return;
// }
const itemElement = gearsContainer.current?.querySelector(
`.popper-gear[data-id='${itemId}']`
);
if (itemElement) {
return itemElement;
} }
const gearsElement = document.createElement("div"); const [ly, setly] = useState<any>({
gearsElement.classList.add("popper-gear");
gearsElement.setAttribute("data-id", item.id());
gearsContainer.current?.appendChild(gearsElement);
// gearsElement.addEventListener("click", () =>
// setOpenedModalSettings(
// findQuestionById(quiz, node.id().split("_").pop() || "").index
// )
// );
return gearsElement;
},
});
const update = async () => {
await plusesPopper.update();
await crossesPopper.update();
await gearsPopper.update();
};
const onZoom = (event: AbstractEventObject) => {
const zoom = event.cy.zoom();
update();
crossesPopper.setOptions({
modifiers: [
{ name: "flip", options: { boundary: node } },
{ name: "offset", options: { offset: [-5 * zoom, -30 * zoom] } },
{
name: "hide",
options: { enabled: true },
},
],
});
plusesContainer.current
?.querySelectorAll("#popper-pluses > .popper-plus")
.forEach((item) => {
const element = item as HTMLDivElement;
element.style.width = `${40 * zoom}px`;
element.style.height = `${40 * zoom}px`;
element.style.fontSize = `${40 * zoom}px`;
element.style.borderRadius = `${6 * zoom}px`;
});
crossesContainer.current
?.querySelectorAll("#popper-crosses > .popper-cross")
.forEach((item) => {
const element = item as HTMLDivElement;
element.style.width = `${24 * zoom}px`;
element.style.height = `${24 * zoom}px`;
element.style.fontSize = `${24 * zoom}px`;
element.style.borderRadius = `${6 * zoom}px`;
});
gearsContainer.current
?.querySelectorAll("#popper-gears > .popper-gear")
.forEach((item) => {
const element = item as HTMLDivElement;
element.style.width = `${33 * zoom}px`;
element.style.height = `${14 * zoom}px`;
element.style.fontSize = `${24 * zoom}px`;
});
};
node?.on("position", update);
cy?.on("pan zoom resize render", onZoom);
});
};
return (
<CytoscapeComponent
wheelSensitivity={0.1}
elements={[]}
// elements={createGraphElements(tree, quiz)}
style={{ height: "480px", background: "#F2F3F7" }}
layout={{
name: 'preset', name: 'preset',
positions: (e) => { positions: (e) => {
console.log("идёт расчёт позиции")
const id = e.id() const id = e.id()
const incomming = e.cy().edges(`[target="${id}"]`) const incomming = e.cy().edges(`[target="${id}"]`)
const layer = 0 const layer = 0
@ -545,15 +260,15 @@ export const CsComponent = () => {
const lastOffset = parent.data('lastChild') const lastOffset = parent.data('lastChild')
const step = wing * 2 / (parent.data('children') - 1) const step = wing * 2 / (parent.data('children') - 1)
if (e.data('layer') === 1) if (e.data('layer') === 1)
console.log(e.data('subtreeWidth'), e.id(),(parent.data('children')-1), step, wing, e.data('layer'), parent.id(), lastOffset) // console.log(e.data('subtreeWidth'), e.id(), (parent.data('children') - 1), step, wing, e.data('layer'), parent.id(), lastOffset)
//e.removeData('subtreeWidth') //e.removeData('subtreeWidth')
//console.log('poss', e.id(), 'children', parent.data('children'),'lo', lastOffset, 'v', wing) //console.log('poss', e.id(), 'children', parent.data('children'),'lo', lastOffset, 'v', wing)
if (lastOffset !== undefined) { if (lastOffset !== undefined) {
parent.data('lastChild', lastOffset + step) parent.data('lastChild', lastOffset + step)
return {x:200*e.data('layer'),y: lastOffset+step} return { x: 200 * e.data('layer'), y: (lastOffset + step) || 1 }
} else { } else {
parent.data('lastChild', parent.position().y - wing) parent.data('lastChild', parent.position().y - wing)
return {x:200*e.data('layer'),y: parent.position().y - wing} return { x: 200 * e.data('layer'), y: (parent.position().y - wing) || 200 }
} }
} }
}, // map of (node id) => (position obj); or function(node){ return somPos; } }, // map of (node id) => (position obj); or function(node){ return somPos; }
@ -565,11 +280,244 @@ export const CsComponent = () => {
animationDuration: 500, // duration of animation in ms if enabled animationDuration: 500, // duration of animation in ms if enabled
animationEasing: undefined, // easing of animation if enabled animationEasing: undefined, // easing of animation if enabled
animateFilter: function (node, i) { return true; }, // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts animateFilter: function (node, i) { return true; }, // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts
ready: (e) => console.log('ready',e), // callback on layoutready ready: readyLO, // callback on layoutready
stop: (e) => console.log('stop',e), // callback on layoutstop // stop: (e) => console.log('stop', e), // callback on layoutstop
transform: function (node, position) { return position; } // transform a given node position. Useful for changing flow direction in discrete layouts transform: function (node, position) { return position; } // transform a given node position. Useful for changing flow direction in discrete layouts
}} })
const initialPopperIcons = (e) => {
const cy = e.cy
const container =
(document.body.querySelector(
".__________cytoscape_container"
) as HTMLDivElement) || null;
if (!container) {
return;
}
container.style.overflow = "hidden";
if (!layoutsContainer.current) {
layoutsContainer.current = document.createElement("div");
layoutsContainer.current.setAttribute("id", "popper-layouts");
container.append(layoutsContainer.current);
}
if (!plusesContainer.current) {
plusesContainer.current = document.createElement("div");
plusesContainer.current.setAttribute("id", "popper-pluses");
container.append(plusesContainer.current);
}
if (!crossesContainer.current) {
crossesContainer.current = document.createElement("div");
crossesContainer.current.setAttribute("id", "popper-crosses");
container.append(crossesContainer.current);
}
if (!gearsContainer.current) {
gearsContainer.current = document.createElement("div");
gearsContainer.current.setAttribute("id", "popper-gears");
container.append(gearsContainer.current);
}
cy?.nodes()
.toArray()
?.forEach((item) => {
const node = item as NodeSingularWithPopper;
console.log(node)
const layoutsPopper = node.popper({
popper: {
placement: "left",
modifiers: [{ name: "flip", options: { boundary: node } }],
},
content: ([item]) => {
const itemId = item.id();
const itemElement = layoutsContainer.current?.querySelector(
`.popper-layout[data-id='${itemId}']`
);
if (itemElement) {
return itemElement;
}
const layoutElement = document.createElement("div");
layoutElement.classList.add("popper-layout");
layoutElement.setAttribute("data-id", item.id());
// layoutElement.addEventListener("mouseup", () =>{}
// // setStartCreate(node.id())
// );
console.log(layoutsContainer.current)
layoutsContainer.current?.appendChild(layoutElement);
return layoutElement;
},
});
const plusesPopper = node.popper({
popper: {
placement: "right",
modifiers: [{ name: "flip", options: { boundary: node } }],
},
content: ([item]) => {
const itemId = item.id();
const itemElement = plusesContainer.current?.querySelector(
`.popper-plus[data-id='${itemId}']`
);
if (itemElement) {
return itemElement;
}
const plusElement = document.createElement("div");
plusElement.classList.add("popper-plus");
plusElement.setAttribute("data-id", item.id());
plusElement.addEventListener("mouseup", () => {
setStartCreate(node.id());
});
plusesContainer.current?.appendChild(plusElement);
return plusElement;
},
});
const crossesPopper = node.popper({
popper: {
placement: "top-end",
modifiers: [{ name: "flip", options: { boundary: node } }],
},
content: ([item]) => {
const itemId = item.id();
const itemElement = crossesContainer.current?.querySelector(
`.popper-cross[data-id='${itemId}']`
);
if (itemElement) {
return itemElement;
}
const crossElement = document.createElement("div");
crossElement.classList.add("popper-cross");
crossElement.setAttribute("data-id", item.id());
crossesContainer.current?.appendChild(crossElement);
// crossElement.addEventListener("click", () =>
// setStartRemove(node.id())
// );
console.log(crossElement)
return crossElement;
},
});
const gearsPopper = node.popper({
popper: {
placement: "left",
modifiers: [{ name: "flip", options: { boundary: node } }],
},
content: ([item]) => {
console.log(item.data())
const itemId = item.id();
console.log(item.data())
console.log(item.data().lastChild)
if (item.data().lastChild === NaN || item.data().lastChild === undefined) {
return;
}
const itemElement = gearsContainer.current?.querySelector(
`.popper-gear[data-id='${itemId}']`
);
if (itemElement) {
return itemElement;
}
const gearElement = document.createElement("div");
gearElement.classList.add("popper-gear");
gearElement.setAttribute("data-id", item.id());
gearsContainer.current?.appendChild(gearElement);
// gearElement.addEventListener("click", () => {
// setOpenedModalSettings(
// findQuestionById(quizId, node.id().split(" ").pop() || "").index
// );
// });
return gearElement;
},
});
const update = async () => {
await plusesPopper.update();
await crossesPopper.update();
await gearsPopper.update();
await layoutsPopper.update();
};
const onZoom = (event: AbstractEventObject) => {
const zoom = event.cy.zoom();
update();
crossesPopper.setOptions({
modifiers: [
{ name: "flip", options: { boundary: node } },
{ name: "offset", options: { offset: [-5 * zoom, -30 * zoom] } },
],
});
layoutsPopper.setOptions({
modifiers: [
{ name: "flip", options: { boundary: node } },
{ name: "offset", options: { offset: [0, -130 * zoom] } },
],
});
layoutsContainer.current
?.querySelectorAll("#popper-layouts > .popper-layout")
.forEach((item) => {
const element = item as HTMLDivElement;
element.style.width = `${130 * zoom}px`;
element.style.height = `${130 * zoom}px`;
});
plusesContainer.current
?.querySelectorAll("#popper-pluses > .popper-plus")
.forEach((item) => {
const element = item as HTMLDivElement;
element.style.width = `${40 * zoom}px`;
element.style.height = `${40 * zoom}px`;
element.style.fontSize = `${40 * zoom}px`;
element.style.borderRadius = `${6 * zoom}px`;
});
crossesContainer.current
?.querySelectorAll("#popper-crosses > .popper-cross")
.forEach((item) => {
const element = item as HTMLDivElement;
element.style.width = `${24 * zoom}px`;
element.style.height = `${24 * zoom}px`;
element.style.fontSize = `${24 * zoom}px`;
element.style.borderRadius = `${6 * zoom}px`;
});
gearsContainer.current
?.querySelectorAll("#popper-gears > .popper-gear")
.forEach((item) => {
const element = item as HTMLDivElement;
element.style.width = `${60 * zoom}px`;
element.style.height = `${40 * zoom}px`;
});
};
node?.on("position", update);
cy?.on("pan zoom resize render", onZoom);
});
};
return (
<CytoscapeComponent
wheelSensitivity={0.1}
elements={[]}
// elements={createGraphElements(tree, quiz)}
style={{ height: "480px", background: "#F2F3F7" }}
stylesheet={stylesheet} stylesheet={stylesheet}
layout={ly}
cy={(cy) => { cy={(cy) => {
cyRef.current = cy; cyRef.current = cy;
}} }}

@ -1,15 +1,19 @@
import { Box } from "@mui/material" import { Box } from "@mui/material"
import { useEffect, useRef } from "react"; import { useEffect, useRef, useState } from "react";
import { updateDragQuestionId, updateQuestion } from "@root/questions/actions" import { updateDragQuestionId, updateQuestion } from "@root/questions/actions"
import { updateRootInfo } from "@root/quizes/actions" import { updateRootInfo } from "@root/quizes/actions"
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 { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
export const FirstNodeField = () => { interface Props {
setOpenedModalQuestionsId:(str: string|null) => void
}
export const FirstNodeField = ({setOpenedModalQuestionsId}:Props) => {
const { dragQuestionId } = useQuestionsStore() const { dragQuestionId } = useQuestionsStore()
const Container = useRef<HTMLDivElement | null>(null); const Container = useRef<HTMLDivElement | null>(null);
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
console.log(dragQuestionId)
const newRootNode = () => { const newRootNode = () => {
@ -32,6 +36,7 @@ console.log(dragQuestionId)
return ( return (
<Box <Box
onclick
ref={Container} ref={Container}
sx={{ sx={{
height: "100%", height: "100%",

@ -14,43 +14,22 @@ interface Edges {
} }
export const storeToNodes = (questions: AnyQuizQuestion[]) => { export const storeToNodes = (questions: AnyQuizQuestion[]) => {
console.log(questions)
const nodes: Nodes[] = [] const nodes: Nodes[] = []
const edges: Edges[] = [] const edges: Edges[] = []
questions.forEach((question) => { questions.forEach((question) => {
console.log(question)
if (question.content.rule.parentId) { if (question.content.rule.parentId) {
nodes.push({data: { nodes.push({data: {
id: question.id, id: question.id,
label: question.title ? question.title : "noname" label: question.title ? question.title : "noname"
}}) }})
nodes.push({data:{
id: "111",
label: "111"
}})
nodes.push({data:{
id: "222",
label: "222"
}})
edges.push({data: {
source: question.id,
target: "111"
}})
nodes.push({data:{
id: "333",
label: "333"
}})
edges.push({data: {
source: "111",
target: "333"
}})
edges.push({data: {
source: question.id,
target: "222"
}})
if (question.content.rule.parentId !== "root") edges.push({data: { if (question.content.rule.parentId !== "root") edges.push({data: {
source: question.content.rule.parentId, source: question.content.rule.parentId,
target: question.id target: question.id
}}) }})
} }
}) })
console.log([...nodes, ...edges])
return [...nodes, ...edges]; return [...nodes, ...edges];
} }

@ -3,11 +3,13 @@ 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";
export const BranchingMap = () => { export const BranchingMap = () => {
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const { dragQuestionId } = useQuestionsStore() const { dragQuestionId } = useQuestionsStore()
const [openedModalQuestionsId, setOpenedModalQuestionsId] = useState<string>()
return ( return (
<Box <Box
@ -28,7 +30,7 @@ export const BranchingMap = () => {
quiz?.config.haveRoot ? quiz?.config.haveRoot ?
<CsComponent /> <CsComponent />
: :
<FirstNodeField /> <FirstNodeField setOpenedModalQuestionsId={setOpenedModalQuestionsId} />
} }
</Box> </Box>

@ -4,6 +4,7 @@ import { ReactComponent as CheckedIcon } from "@icons/checked.svg";
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { updateDragQuestionId } from "@root/questions/actions"; import { updateDragQuestionId } from "@root/questions/actions";
import { useEffect } from "react"; import { useEffect } from "react";
import { AnyTypedQuizQuestion, UntypedQuizQuestion } from "@model/questionTypes/shared";
const getItemStyle = (isDragging:any, draggableStyle:any) => ({ const getItemStyle = (isDragging:any, draggableStyle:any) => ({
@ -18,6 +19,7 @@ const getItemStyle = (isDragging:any, draggableStyle:any) => ({
// styles we need to apply on draggables // styles we need to apply on draggables
...draggableStyle ...draggableStyle
}); });
type AnyQuestion = UntypedQuizQuestion | AnyTypedQuizQuestion
export const QuestionsList = () => { export const QuestionsList = () => {
const { questions } = useQuestionsStore() const { questions } = useQuestionsStore()
@ -49,7 +51,7 @@ export const QuestionsList = () => {
}} }}
> >
{/* тут нужно будет фильтровать с проверкой, что вопрос имеет тип*/} {/* тут нужно будет фильтровать с проверкой, что вопрос имеет тип*/}
{questions.map(({ title, id, content }, index) => ( {questions.filter((q:AnyQuestion) => q.type).map(({ title, id, content }, index) => (
<Button <Button
onMouseDown={() => {//Разрешаем добавить этот вопрос если у него нет родителя (не добавляли ещё в дерево) onMouseDown={() => {//Разрешаем добавить этот вопрос если у него нет родителя (не добавляли ещё в дерево)
if (!content.rule.parentId) updateDragQuestionId(id) if (!content.rule.parentId) updateDragQuestionId(id)

@ -427,6 +427,7 @@ function setProducedState<A extends string | { type: unknown; }>(
export const clearDragQuestionId = () => { export const clearDragQuestionId = () => {
console.log("чищу чищу")
useQuestionsStore.setState({dragQuestionId: null}); useQuestionsStore.setState({dragQuestionId: null});
}; };