2023-12-04 13:33:43 +00:00
import { useEffect , useLayoutEffect , useRef , useState } from "react" ;
2023-11-29 15:45:15 +00:00
import Cytoscape from "cytoscape" ;
2023-12-09 21:17:05 +00:00
import { Button } from "@mui/material" ;
2023-11-29 15:45:15 +00:00
import CytoscapeComponent from "react-cytoscapejs" ;
import popper from "cytoscape-popper" ;
import { useCurrentQuiz } from "@root/quizes/hooks" ;
2023-12-20 10:46:38 +00:00
import { updateRootContentId } from "@root/quizes/actions" ;
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared" ;
2023-11-29 15:45:15 +00:00
import { useQuestionsStore } from "@root/questions/store" ;
2023-12-20 10:46:38 +00:00
import {
deleteQuestion ,
updateQuestion ,
getQuestionByContentId ,
clearRuleForAll ,
createFrontResult ,
} from "@root/questions/actions" ;
import { updateOpenedModalSettingsId } from "@root/uiTools/actions" ;
2023-12-14 09:40:53 +00:00
import { cleardragQuestionContentId } from "@root/uiTools/actions" ;
2023-12-07 00:03:43 +00:00
import { withErrorBoundary } from "react-error-boundary" ;
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
import { useRemoveNode } from "./hooks/useRemoveNode" ;
import { usePopper } from "./hooks/usePopper" ;
2023-11-29 15:45:15 +00:00
import { storeToNodes } from "./helper" ;
2023-12-20 10:46:38 +00:00
import { stylesheet } from "./stylesheet" ;
2023-11-29 15:45:15 +00:00
import "./styles.css" ;
import type {
Stylesheet ,
Core ,
NodeSingular ,
AbstractEventObject ,
ElementDefinition ,
2023-12-20 10:46:38 +00:00
LayoutEventObject ,
2023-11-29 15:45:15 +00:00
} from "cytoscape" ;
2023-12-02 09:59:31 +00:00
import { enqueueSnackbar } from "notistack" ;
2023-12-14 09:40:53 +00:00
import { useUiTools } from "@root/uiTools/store" ;
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
// type PopperItem = {
// id: () => string;
// };
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
// type Modifier = {
// name: string;
// options: unknown;
// };
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
// type PopperConfig = {
// popper: {
// placement: string;
// modifiers?: Modifier[];
// };
// content: (items: PopperItem[]) => void;
// };
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
// type Popper = {
// update: () => Promise<void>;
// setOptions: (modifiers: { modifiers?: Modifier[] }) => void;
// };
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
// type NodeSingularWithPopper = NodeSingular & {
// popper: (config: PopperConfig) => Popper;
// };
2023-11-29 15:45:15 +00:00
Cytoscape . use ( popper ) ;
2023-12-20 10:46:38 +00:00
type CsComponentProps = {
2023-12-01 19:56:13 +00:00
modalQuestionParentContentId : string ;
modalQuestionTargetContentId : string ;
2023-12-02 13:11:57 +00:00
setOpenedModalQuestions : ( open : boolean ) = > void ;
setModalQuestionParentContentId : ( id : string ) = > void ;
setModalQuestionTargetContentId : ( id : string ) = > void ;
2023-12-20 10:46:38 +00:00
} ;
2023-12-01 19:56:13 +00:00
2023-12-11 10:08:54 +00:00
function CsComponent ( {
2023-12-01 19:56:13 +00:00
modalQuestionParentContentId ,
modalQuestionTargetContentId ,
setOpenedModalQuestions ,
setModalQuestionParentContentId ,
2023-12-20 10:46:38 +00:00
setModalQuestionTargetContentId ,
} : CsComponentProps ) {
2023-11-29 15:45:15 +00:00
const quiz = useCurrentQuiz ( ) ;
2023-12-20 10:46:38 +00:00
const { dragQuestionContentId , desireToOpenABranchingModal } = useUiTools ( ) ;
const trashQuestions = useQuestionsStore ( ) . questions ;
const questions = trashQuestions . filter (
( question ) = > question . type !== "result" && question . type !== null
) ;
2023-11-29 15:45:15 +00:00
const [ startCreate , setStartCreate ] = useState ( "" ) ;
const [ startRemove , setStartRemove ] = useState ( "" ) ;
const cyRef = useRef < Core | null > ( null ) ;
2023-12-01 08:12:59 +00:00
const layoutsContainer = useRef < HTMLDivElement | null > ( null ) ;
2023-11-29 15:45:15 +00:00
const plusesContainer = useRef < HTMLDivElement | null > ( null ) ;
const crossesContainer = useRef < HTMLDivElement | null > ( null ) ;
const gearsContainer = useRef < HTMLDivElement | null > ( null ) ;
2023-12-20 10:46:38 +00:00
// const { layoutOptions } = usePopper({
// layoutsContainer,
// plusesContainer,
// crossesContainer,
// gearsContainer,
// setModalQuestionParentContentId,
// setOpenedModalQuestions,
// setStartCreate,
// setStartRemove,
// });
const layoutOptions = { } ;
const removeNode = ( ) = > { } ;
// const { removeNode } = useRemoveNode({
// cyRef,
// layoutOptions,
// layoutsContainer,
// plusesContainer,
// crossesContainer,
// gearsContainer,
// });
2023-12-05 23:34:40 +00:00
useLayoutEffect ( ( ) = > {
2023-12-20 10:46:38 +00:00
const cy = cyRef ? . current ;
2023-12-05 23:34:40 +00:00
if ( desireToOpenABranchingModal ) {
2023-12-07 00:03:43 +00:00
setTimeout ( ( ) = > {
2023-12-20 10:46:38 +00:00
cy ? . getElementById ( desireToOpenABranchingModal ) ? . data (
"eroticeyeblink" ,
true
) ;
} , 250 ) ;
2023-12-05 23:34:40 +00:00
} else {
2023-12-20 10:46:38 +00:00
cy ? . elements ( ) . data ( "eroticeyeblink" , false ) ;
2023-12-05 23:34:40 +00:00
}
2023-12-20 10:46:38 +00:00
} , [ desireToOpenABranchingModal ] ) ;
2023-12-05 23:34:40 +00:00
useLayoutEffect ( ( ) = > {
2023-12-20 10:46:38 +00:00
updateOpenedModalSettingsId ( ) ;
// updateRootContentId(quiz.id, "")
// clearRuleForAll()
} , [ ] ) ;
2023-12-02 13:11:57 +00:00
useEffect ( ( ) = > {
2023-12-20 10:46:38 +00:00
if (
modalQuestionTargetContentId . length !== 0 &&
modalQuestionParentContentId . length !== 0
) {
addNode ( {
parentNodeContentId : modalQuestionParentContentId ,
targetNodeContentId : modalQuestionTargetContentId ,
} ) ;
2023-12-02 13:11:57 +00:00
}
2023-12-01 08:12:59 +00:00
2023-12-20 10:46:38 +00:00
setModalQuestionParentContentId ( "" ) ;
setModalQuestionTargetContentId ( "" ) ;
} , [ modalQuestionTargetContentId ] ) ;
const addNode = ( {
parentNodeContentId ,
targetNodeContentId ,
} : {
parentNodeContentId : string ;
targetNodeContentId? : string ;
} ) = > {
2023-12-13 10:53:59 +00:00
//запрещаем работу родителя-ребенка если это один и тот же вопрос
2023-12-20 10:46:38 +00:00
if ( parentNodeContentId === targetNodeContentId ) return ;
2023-12-13 10:53:59 +00:00
2023-12-20 10:46:38 +00:00
const cy = cyRef ? . current ;
const parentNodeChildren = cy ? . $ (
'edge[source = "' + parentNodeContentId + '"]'
) ? . length ;
2023-12-02 21:20:41 +00:00
//если есть инфо о выбранном вопросе из модалки - берём родителя из инфо модалки. Иначе из значения дропа
2023-12-20 10:46:38 +00:00
const targetQuestion = {
. . . getQuestionByContentId ( targetNodeContentId || dragQuestionContentId ) ,
} as AnyTypedQuizQuestion ;
if (
Object . keys ( targetQuestion ) . length !== 0 &&
parentNodeContentId &&
parentNodeChildren !== undefined
) {
clearDataAfterAddNode ( {
parentNodeContentId ,
targetQuestion ,
parentNodeChildren ,
} ) ;
cy ? . data ( "changed" , true ) ;
if ( quiz ) {
createFrontResult ( quiz . backendId , targetQuestion . content . id ) ;
}
2023-12-09 20:49:08 +00:00
const es = cy ? . add ( [
2023-12-01 08:12:59 +00:00
{
data : {
2023-12-01 19:56:13 +00:00
id : targetQuestion.content.id ,
2023-12-20 10:46:38 +00:00
label :
targetQuestion . title === "" || targetQuestion . title === " "
? "noname"
: targetQuestion . title ,
} ,
2023-12-01 08:12:59 +00:00
} ,
{
data : {
2023-12-01 19:56:13 +00:00
source : parentNodeContentId ,
2023-12-20 10:46:38 +00:00
target : targetQuestion.content.id ,
} ,
} ,
] ) ;
cy ? . layout ( layoutOptions ) . run ( ) ;
console . log ( es ) ;
cy ? . center ( es ) ;
2023-12-02 09:59:31 +00:00
} else {
2023-12-20 10:46:38 +00:00
enqueueSnackbar ( "Добавляемый вопрос не найден" ) ;
2023-12-02 13:11:57 +00:00
}
2023-12-20 10:46:38 +00:00
} ;
2023-12-11 15:40:42 +00:00
2023-12-20 10:46:38 +00:00
const clearDataAfterAddNode = ( {
parentNodeContentId ,
targetQuestion ,
parentNodeChildren ,
} : {
parentNodeContentId : string ;
targetQuestion : AnyTypedQuizQuestion ;
parentNodeChildren : number ;
} ) = > {
const parentQuestion = {
. . . getQuestionByContentId ( parentNodeContentId ) ,
} as AnyTypedQuizQuestion ;
2023-12-11 15:40:42 +00:00
//смотрим не добавлен ли родителю result. Если да - убираем е г о . Веточкам result не нужен
trashQuestions . forEach ( ( targetQuestion ) = > {
2023-12-20 10:46:38 +00:00
if (
targetQuestion . type === "result" &&
targetQuestion . content . rule . parentId === parentQuestion . content . id
) {
console . log ( "deleteQ" , targetQuestion . id ) ;
2023-12-11 15:40:42 +00:00
deleteQuestion ( targetQuestion . id ) ;
}
2023-12-20 10:46:38 +00:00
} ) ;
2023-12-11 15:40:42 +00:00
2023-12-02 09:59:31 +00:00
//предупреждаем добавленный вопрос о том, кто е г о родитель
2023-12-20 10:46:38 +00:00
updateQuestion ( targetQuestion . content . id , ( question ) = > {
question . content . rule . parentId = parentNodeContentId ;
question . content . rule . main = [ ] ;
} ) ;
2023-12-11 15:40:42 +00:00
//предупреждаем родителя о новом потомке (если он ещё не знает о нём)
2023-12-20 10:46:38 +00:00
if (
! parentQuestion . content . rule . children . includes ( targetQuestion . content . id )
)
updateQuestion ( parentNodeContentId , ( question ) = > {
question . content . rule . children = [
. . . question . content . rule . children ,
targetQuestion . content . id ,
] ;
} ) ;
2023-12-01 19:56:13 +00:00
2023-12-02 13:11:57 +00:00
//Если детей больше 1 - предупреждаем стор вопросов о б открытии модалки ветвления
2023-12-11 15:40:42 +00:00
if ( parentQuestion . content . rule . children >= 1 ) {
2023-12-20 10:46:38 +00:00
updateOpenedModalSettingsId ( targetQuestion . content . id ) ;
2023-12-02 13:11:57 +00:00
}
2023-12-20 10:46:38 +00:00
} ;
2023-12-02 09:59:31 +00:00
2023-12-20 10:46:38 +00:00
// const removeNode = ({ targetNodeContentId }: { targetNodeContentId: string }) => {
// console.log("старт удаление")
// const deleteNodes: string[] = []
// const deleteEdges: any = []
// const cy = cyRef?.current
// const findChildrenToDelete = (node) => {
// //Узнаём грани, идущие от этой ноды
// cy?.$('edge[source = "' + node.id() + '"]')?.toArray().forEach((edge) => {
// const edgeData = edge.data()
// //записываем id грани для дальнейшего удаления
// deleteEdges.push(edge)
// //ищем ноду на конце грани, записываем её ID для дальнейшего удаления
// const targetNode = cy?.$("#" + edgeData.target)
// deleteNodes.push(targetNode.data().id)
// //вызываем функцию для анализа потомков уже у этой ноды
// findChildrenToDelete(targetNode)
// })
// }
// findChildrenToDelete(cy?.getElementById(targetNodeContentId))
// const targetQuestion = getQuestionByContentId(targetNodeContentId)
// if (targetQuestion.content.rule.parentId === "root" && quiz) {
// updateRootContentId(quiz?.id, "")
// updateQuestion(targetNodeContentId, question => {
// question.content.rule.parentId = ""
// question.content.rule.main = []
// question.content.rule.children = []
// question.content.rule.default = ""
// })
// trashQuestions.forEach(q => {
// if (q.type === "result") {
// deleteQuestion(q.id);
// }
// });
// clearRuleForAll()
// } else {
// const parentQuestionContentId = cy?.$('edge[target = "' + targetNodeContentId + '"]')?.toArray()?.[0]?.data()?.source
// if (targetNodeContentId && parentQuestionContentId) {
// if (cy?.edges(`[source="${parentQuestionContentId}"]`).length === 0)
// createFrontResult(quiz.backendId, parentQuestionContentId)
// clearDataAfterRemoveNode({ targetQuestionContentId: targetNodeContentId, parentQuestionContentId })
// cy?.remove(cy?.$('#' + targetNodeContentId)).layout(lyopts).run()
// }
// }
// //После всех манипуляций удаляем грани и ноды из CS Чистим rule потомков на беке
// deleteNodes.forEach((nodeId) => {//Ноды
// cy?.remove(cy?.$("#" + nodeId))
// removeButtons(nodeId)
// updateQuestion(nodeId, question => {
// question.content.rule.parentId = ""
// question.content.rule.main = []
// question.content.rule.default = ""
// question.content.rule.children = []
// })
// })
// deleteEdges.forEach((edge: any) => {//Грани
// cy?.remove(edge)
// })
// removeButtons(targetNodeContentId)
// cy?.data('changed', true)
// cy?.layout(lyopts).run()
// //удаляем result всех потомков
// trashQuestions.forEach((qr) => {
// if (qr.type === "result") {
// if (deleteNodes.includes(qr.content.rule.parentId) || qr.content.rule.parentId === targetQuestion.content.id) {
// deleteQuestion(qr.id);
// }
// }
// })
// }
// const clearDataAfterRemoveNode = ({ targetQuestionContentId, parentQuestionContentId }: { targetQuestionContentId: string, parentQuestionContentId: string }) => {
// 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 newRule = {}
// const newChildren = [...parentQuestion.content.rule.children]
// newChildren.splice(parentQuestion.content.rule.children.indexOf(targetQuestionContentId), 1);
// newRule.main = parentQuestion.content.rule.main.filter((data) => data.next !== targetQuestionContentId) //удаляем условия перехода от родителя к этому вопросу
// newRule.parentId = parentQuestion.content.rule.parentId
// newRule.default = parentQuestion.content.rule.default === targetQuestionContentId ? "" : parentQuestion.content.rule.default
// newRule.children = newChildren
// updateQuestion(parentQuestionContentId, (PQ) => {
// PQ.content.rule = newRule
// })
// }
2023-12-12 15:44:18 +00:00
2023-11-29 15:45:15 +00:00
useEffect ( ( ) = > {
if ( startCreate ) {
2023-12-01 19:56:13 +00:00
addNode ( { parentNodeContentId : startCreate } ) ;
2023-12-20 10:46:38 +00:00
cleardragQuestionContentId ( ) ;
2023-11-29 15:45:15 +00:00
setStartCreate ( "" ) ;
}
} , [ startCreate ] ) ;
useEffect ( ( ) = > {
if ( startRemove ) {
2023-12-20 10:46:38 +00:00
removeNode ( startRemove ) ;
2023-11-29 15:45:15 +00:00
setStartRemove ( "" ) ;
}
} , [ startRemove ] ) ;
2023-12-20 10:46:38 +00:00
// const readyLO = (e) => {
// if (e.cy.data('firstNode') === 'nonroot') {
// e.cy.data('firstNode', 'root')
// e.cy.nodes().sort((a, b) => (a.data('root') ? 1 : -1)).layout(lyopts).run()
// } else {
// e.cy.data('changed', false)
// e.cy.removeData('firstNode')
// }
// //удаляем иконки
// e.cy.nodes().forEach((ele: any) => {
// const data = ele.data()
// data.id && removeButtons(data.id);
// })
// initialPopperIcons(e)
// }
// const lyopts = {
// name: 'preset',
// 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
// e.removeData('lastChild')
// if (incomming.length === 0) {
// if (e.cy().data('firstNode') === undefined)
// e.cy().data('firstNode', 'root')
// e.data('root', true)
// const children = e.cy().edges(`[source="${id}"]`).targets()
// e.data('layer', layer)
// e.data('children', children.length)
// const queue = []
// children.forEach(n => {
// queue.push({ task: n, layer: layer + 1 })
// })
// while (queue.length) {
// const task = queue.pop()
// task.task.data('layer', task.layer)
// task.task.removeData('subtreeWidth')
// const children = e.cy().edges(`[source="${task.task.id()}"]`).targets()
// task.task.data('children', children.length)
// if (children.length !== 0) {
// children.forEach(n => queue.push({ task: n, layer: task.layer + 1 }))
// }
// }
// queue.push({ parent: e, children: children })
// while (queue.length) {
// const task = queue.pop()
// if (task.children.length === 0) {
// task.parent.data('subtreeWidth', task.parent.height() + 50)
// continue
// }
// const unprocessed = task?.children.filter(e => {
// return (e.data('subtreeWidth') === undefined)
// })
// if (unprocessed.length !== 0) {
// queue.push(task)
// unprocessed.forEach(t => {
// queue.push({ parent: t, children: t.cy().edges(`[source="${t.id()}"]`).targets() })
// })
// continue
// }
// task?.parent.data('subtreeWidth', task.children.reduce((p, n) => p + n.data('subtreeWidth'), 0))
// }
// const pos = { x: 0, y: 0 }
// e.data('oldPos', pos)
// 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
// task.task.forEach(n => {
// const width = n.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)
// return pos
// } else {
// 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)
// pan: true, // the pan level to set (prob want fit = false if set)
// fit: false, // whether to fit to viewport
// padding: 30, // padding on fit
// animate: false, // whether to transition the node positions
// animationDuration: 500, // duration of animation in ms if enabled
// animationEasing: undefined, // easing of animation if enabled
// animateFilter: function (node, i) { return false; }, // 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: readyLO, // callback on layoutready
// transform: function (node, position) { return position; } // transform a given node position. Useful for changing flow direction in discrete layouts
// }
2023-12-02 09:59:31 +00:00
useEffect ( ( ) = > {
2023-12-20 10:46:38 +00:00
document
. querySelector ( "#root" )
? . addEventListener ( "mouseup" , cleardragQuestionContentId ) ;
2023-12-02 09:59:31 +00:00
const cy = cyRef . current ;
2023-12-20 10:46:38 +00:00
const eles = cy ? . add (
storeToNodes (
questions . filter (
( question ) = > question . type && question . type !== "result"
) as AnyTypedQuizQuestion [ ]
)
) ;
cy ? . data ( "changed" , true ) ;
2023-12-05 23:34:40 +00:00
// cy.data('changed', true)
2023-12-20 10:46:38 +00:00
const elecs = eles ? . layout ( layoutOptions ) . run ( ) ;
cy ? . on ( "add" , ( ) = > cy . data ( "changed" , true ) ) ;
cy ? . fit ( ) ;
2023-12-02 09:59:31 +00:00
//cy?.layout().run()
2023-11-29 15:45:15 +00:00
return ( ) = > {
2023-12-20 10:46:38 +00:00
document
. querySelector ( "#root" )
? . removeEventListener ( "mouseup" , cleardragQuestionContentId ) ;
2023-12-01 08:12:59 +00:00
layoutsContainer . current ? . remove ( ) ;
2023-11-29 15:45:15 +00:00
plusesContainer . current ? . remove ( ) ;
crossesContainer . current ? . remove ( ) ;
gearsContainer . current ? . remove ( ) ;
} ;
} , [ ] ) ;
2023-12-20 10:46:38 +00:00
// const removeButtons = (id: string) => {
// layoutsContainer.current
// ?.querySelector(`.popper-layout[data-id='${id}']`)
// ?.remove();
// plusesContainer.current
// ?.querySelector(`.popper-plus[data-id='${id}']`)
// ?.remove();
// crossesContainer.current
// ?.querySelector(`.popper-cross[data-id='${id}']`)
// ?.remove();
// gearsContainer.current
// ?.querySelector(`.popper-gear[data-id='${id}']`)
// ?.remove();
// };
// const initialPopperIcons = ({ cy }: LayoutEventObject) => {
// 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);
// }
// if (!layoutsContainer.current) {
// layoutsContainer.current = document.createElement("div");
// layoutsContainer.current.setAttribute("id", "popper-layouts");
// container.append(layoutsContainer.current);
// }
// const ext = cy.extent();
// const nodesInView = cy.nodes().filter((n) => {
// const bb = n.boundingBox();
// return (
// bb.x2 > ext.x1 && bb.x1 < ext.x2 && bb.y2 > ext.y1 && bb.y1 < ext.y2
// );
// });
// nodesInView.toArray()?.forEach((item) => {
// const node = item as NodeSingularWithPopper;
// 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.style.zIndex = "0";
// layoutElement.classList.add("popper-layout");
// layoutElement.setAttribute("data-id", item.id());
// layoutElement.addEventListener("mouseup", () => {
// //Узнаём грани, идущие от этой ноды
// setModalQuestionParentContentId(item.id());
// setOpenedModalQuestions(true);
// });
// 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.style.zIndex = "1";
// 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());
// crossElement.style.zIndex = "2";
// crossesContainer.current?.appendChild(crossElement);
// crossElement.addEventListener("mouseup", () => {
// setStartRemove(node.id());
// });
// return crossElement;
// },
// });
// let gearsPopper: Popper | null = null;
// if (node.data().root !== true) {
// gearsPopper = node.popper({
// popper: {
// placement: "left",
// modifiers: [{ name: "flip", options: { boundary: node } }],
// },
// content: ([item]) => {
// const itemId = item.id();
// 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());
// gearElement.style.zIndex = "1";
// gearsContainer.current?.appendChild(gearElement);
// gearElement.addEventListener("mouseup", (e) => {
// console.log("up");
// updateOpenedModalSettingsId(item.id());
// });
// 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] } },
// ],
// });
// plusesPopper.setOptions({
// modifiers: [
// { name: "flip", options: { boundary: node } },
// { name: "offset", options: { offset: [0, 0 * zoom] } },
// ],
// });
// gearsPopper?.setOptions({
// modifiers: [
// { name: "flip", options: { boundary: node } },
// { name: "offset", options: { offset: [0, 0] } },
// ],
// });
// 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);
// let pressed = false;
// let hide = false;
// cy?.on("mousedown", () => {
// pressed = true;
// });
// cy?.on("mouseup", () => {
// pressed = false;
// hide = false;
// const gc = gearsContainer.current;
// if (gc) gc.style.display = "block";
// const pc = plusesContainer.current;
// const xc = crossesContainer.current;
// const lc = layoutsContainer.current;
// if (pc) pc.style.display = "block";
// if (xc) xc.style.display = "block";
// if (lc) lc.style.display = "block";
// update();
// });
// cy?.on("mousemove", () => {
// if (pressed && !hide) {
// hide = true;
// const gc = gearsContainer.current;
// if (gc) gc.style.display = "none";
// const pc = plusesContainer.current;
// const xc = crossesContainer.current;
// const lc = layoutsContainer.current;
// if (pc) pc.style.display = "none";
// if (xc) xc.style.display = "none";
// if (lc) lc.style.display = "block";
// }
// });
// cy?.on("zoom render", onZoom);
// });
// };
2023-11-29 15:45:15 +00:00
return (
2023-12-02 20:47:28 +00:00
< >
2023-12-11 10:08:54 +00:00
< Button
sx = { {
mb : "20px" ,
height : "27px" ,
color : "#7E2AEA" ,
textDecoration : "underline" ,
fontSize : "16px" ,
} }
variant = "text"
onClick = { ( ) = > {
2023-12-20 10:46:38 +00:00
cyRef . current ? . fit ( ) ;
2023-12-11 10:08:54 +00:00
} }
>
В ы р о в н я т ь
< / Button >
2023-12-04 09:30:14 +00:00
< CytoscapeComponent
wheelSensitivity = { 0.1 }
elements = { [ ] }
// elements={createGraphElements(tree, quiz)}
style = { { height : "480px" , background : "#F2F3F7" } }
stylesheet = { stylesheet }
2023-12-20 10:46:38 +00:00
layout = { layoutOptions }
2023-12-04 09:30:14 +00:00
cy = { ( cy ) = > {
cyRef . current = cy ;
} }
2023-12-11 10:08:54 +00:00
autoungrabify = { true }
2023-12-04 09:30:14 +00:00
/ >
2023-12-14 16:50:02 +00:00
{ / * < b u t t o n o n C l i c k = { ( ) = > {
2023-12-04 09:30:14 +00:00
console . log ( "NODES____________________________" )
cyRef . current ? . elements ( ) . forEach ( ( ele : any ) = > {
console . log ( ele . data ( ) )
} )
} } > nodes < / button >
< button onClick = { ( ) = > {
console . log ( "ELEMENTS____________________________" )
2023-12-04 07:50:55 +00:00
console . log ( questions )
2023-12-14 16:50:02 +00:00
} } > elements < / button > * / }
2023-12-02 20:47:28 +00:00
< / >
2023-11-29 15:45:15 +00:00
) ;
2023-12-20 10:46:38 +00:00
}
2023-12-07 00:03:43 +00:00
2023-12-11 10:08:54 +00:00
function Clear() {
const quiz = useCurrentQuiz ( ) ;
2023-12-20 10:46:38 +00:00
if ( quiz ) {
updateRootContentId ( quiz . id , "" ) ;
}
clearRuleForAll ( ) ;
return < > < / > ;
2023-12-07 00:03:43 +00:00
}
export default withErrorBoundary ( CsComponent , {
2023-12-11 10:08:54 +00:00
fallback : < Clear / > ,
2023-12-07 00:03:43 +00:00
onError : ( error , info ) = > {
2023-12-20 10:46:38 +00:00
enqueueSnackbar ( "Дерево порвалось" ) ;
console . log ( info ) ;
console . log ( error ) ;
2023-12-07 00:03:43 +00:00
} ,
2023-12-09 19:31:06 +00:00
} ) ;