@lv-x-software-house/x_view 1.1.9-dev.1 → 1.1.9-dev.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +362 -152
- package/dist/index.mjs +367 -155
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2654,7 +2654,10 @@ var IGNORED_KEYS = [
|
|
|
2654
2654
|
"isAddingNodes",
|
|
2655
2655
|
"ancestryDescriptionSections",
|
|
2656
2656
|
"direction",
|
|
2657
|
-
"is_private"
|
|
2657
|
+
"is_private",
|
|
2658
|
+
"abstraction_tree",
|
|
2659
|
+
"selectedAbstractionParentId",
|
|
2660
|
+
"isAddingAbstractionNodes"
|
|
2658
2661
|
];
|
|
2659
2662
|
function extractCustomPropsFromNode(node) {
|
|
2660
2663
|
const customPropTypes = node._customPropTypes || {};
|
|
@@ -4428,8 +4431,69 @@ import {
|
|
|
4428
4431
|
FiCornerUpLeft,
|
|
4429
4432
|
FiCornerUpRight,
|
|
4430
4433
|
FiList as FiList2,
|
|
4431
|
-
FiAlignLeft
|
|
4434
|
+
FiAlignLeft,
|
|
4435
|
+
FiGitBranch,
|
|
4436
|
+
FiFolder
|
|
4432
4437
|
} from "react-icons/fi";
|
|
4438
|
+
var findNodePath = (tree, targetNodeId, currentPath = []) => {
|
|
4439
|
+
var _a;
|
|
4440
|
+
if (!tree) return null;
|
|
4441
|
+
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
4442
|
+
if (String(currentNodeId) === String(targetNodeId)) {
|
|
4443
|
+
return { node: tree, path: currentPath };
|
|
4444
|
+
}
|
|
4445
|
+
if (tree.children) {
|
|
4446
|
+
for (let i = 0; i < tree.children.length; i++) {
|
|
4447
|
+
const res = findNodePath(tree.children[i], targetNodeId, [...currentPath, i]);
|
|
4448
|
+
if (res) return res;
|
|
4449
|
+
}
|
|
4450
|
+
}
|
|
4451
|
+
return null;
|
|
4452
|
+
};
|
|
4453
|
+
var ReadOnlyNodeItem = ({ nodeData, onViewSelect, highlightedPathIds = [], targetRenderNodeId, level = 0, isLast = false }) => {
|
|
4454
|
+
var _a, _b;
|
|
4455
|
+
const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
|
|
4456
|
+
const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
|
|
4457
|
+
const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
|
|
4458
|
+
const isHighlightedPath = highlightedPathIds.includes(String(itemId));
|
|
4459
|
+
const hasChildren = nodeData.children && nodeData.children.length > 0;
|
|
4460
|
+
let itemBgClass = "bg-slate-900/50 hover:bg-slate-800/80";
|
|
4461
|
+
let textColorClass = "text-slate-200";
|
|
4462
|
+
if (nodeData.is_section) {
|
|
4463
|
+
itemBgClass = "bg-purple-900/20 border border-purple-500/30 hover:bg-purple-900/40";
|
|
4464
|
+
textColorClass = "text-purple-300";
|
|
4465
|
+
} else {
|
|
4466
|
+
if (isTargetViewNode) {
|
|
4467
|
+
itemBgClass = "bg-fuchsia-600/40 ring-2 ring-fuchsia-400 shadow-[0_0_15px_rgba(217,70,239,0.3)]";
|
|
4468
|
+
textColorClass = "text-white font-bold";
|
|
4469
|
+
} else if (isHighlightedPath) {
|
|
4470
|
+
itemBgClass = "bg-fuchsia-900/30 border border-fuchsia-500/40";
|
|
4471
|
+
textColorClass = "text-fuchsia-200 font-semibold";
|
|
4472
|
+
}
|
|
4473
|
+
}
|
|
4474
|
+
return /* @__PURE__ */ React7.createElement("div", { className: "relative" }, level > 0 && /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement("span", { className: `absolute -left-4 top-0 w-px ${isHighlightedPath ? "bg-fuchsia-500 shadow-[0_0_8px_rgba(217,70,239,0.8)]" : "bg-cyan-600/60"} ${isLast ? "h-[1.125rem]" : "h-full"}`, "aria-hidden": "true" }), /* @__PURE__ */ React7.createElement("span", { className: `absolute -left-4 top-[1.125rem] h-px w-4 ${isHighlightedPath ? "bg-fuchsia-500 shadow-[0_0_8px_rgba(217,70,239,0.8)]" : "bg-cyan-600/60"}`, "aria-hidden": "true" })), /* @__PURE__ */ React7.createElement(
|
|
4475
|
+
"div",
|
|
4476
|
+
{
|
|
4477
|
+
onClick: (e) => {
|
|
4478
|
+
e.stopPropagation();
|
|
4479
|
+
if (onViewSelect) onViewSelect(itemId);
|
|
4480
|
+
},
|
|
4481
|
+
className: `flex items-center justify-between gap-2 px-3 h-9 rounded-md transition-all duration-150 border border-transparent cursor-pointer ${itemBgClass}`
|
|
4482
|
+
},
|
|
4483
|
+
/* @__PURE__ */ React7.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ React7.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "mr-1.5 inline-block" }, /* @__PURE__ */ React7.createElement("circle", { cx: "9", cy: "9", r: "7" }), /* @__PURE__ */ React7.createElement("circle", { cx: "15", cy: "15", r: "7" })), nodeData.is_section && /* @__PURE__ */ React7.createElement(FiFolder, { className: "mr-2" }), itemName)
|
|
4484
|
+
), hasChildren && /* @__PURE__ */ React7.createElement("div", { className: "mt-2 space-y-2 pl-8" }, nodeData.children.map((child, index) => /* @__PURE__ */ React7.createElement(
|
|
4485
|
+
ReadOnlyNodeItem,
|
|
4486
|
+
{
|
|
4487
|
+
key: `${child.is_section ? child.id : child.node.id}-${index}`,
|
|
4488
|
+
nodeData: child,
|
|
4489
|
+
onViewSelect,
|
|
4490
|
+
highlightedPathIds,
|
|
4491
|
+
targetRenderNodeId,
|
|
4492
|
+
level: level + 1,
|
|
4493
|
+
isLast: index === nodeData.children.length - 1
|
|
4494
|
+
}
|
|
4495
|
+
))));
|
|
4496
|
+
};
|
|
4433
4497
|
function DescriptionReadModePanel({
|
|
4434
4498
|
title,
|
|
4435
4499
|
description,
|
|
@@ -4451,14 +4515,40 @@ function DescriptionReadModePanel({
|
|
|
4451
4515
|
backNavigationInfo,
|
|
4452
4516
|
customProperties = [],
|
|
4453
4517
|
onImageClick,
|
|
4454
|
-
userRole
|
|
4455
|
-
//
|
|
4518
|
+
userRole,
|
|
4519
|
+
// --- NOVAS PROPS PARA ABSTRAÇÃO ---
|
|
4520
|
+
abstractionTree = null,
|
|
4521
|
+
onRenderAbstractionTree = null
|
|
4456
4522
|
}) {
|
|
4457
4523
|
const [showProperties, setShowProperties] = useState7(false);
|
|
4524
|
+
const [showAbstraction, setShowAbstraction] = useState7(false);
|
|
4525
|
+
const [targetRenderNodeId, setTargetRenderNodeId] = useState7(null);
|
|
4458
4526
|
const swallow = (e) => e.stopPropagation();
|
|
4459
4527
|
const hasCustomProps = customProperties && customProperties.length > 0;
|
|
4528
|
+
const hasAbstraction = Boolean(abstractionTree && (abstractionTree.node || abstractionTree.children && abstractionTree.children.length > 0));
|
|
4460
4529
|
const ability = useMemo6(() => defineAbilityFor(userRole), [userRole]);
|
|
4461
4530
|
const canEditAncestry = ability.can("update", "Ancestry");
|
|
4531
|
+
const highlightedPathIds = useMemo6(() => {
|
|
4532
|
+
var _a, _b;
|
|
4533
|
+
if (!targetRenderNodeId || !abstractionTree) return [];
|
|
4534
|
+
const found = findNodePath(abstractionTree, targetRenderNodeId);
|
|
4535
|
+
if (!found) return [];
|
|
4536
|
+
let current = abstractionTree;
|
|
4537
|
+
const ids = [current.is_section ? current.section_id : String((_a = current.node) == null ? void 0 : _a.id)];
|
|
4538
|
+
for (let i of found.path) {
|
|
4539
|
+
current = current.children[i];
|
|
4540
|
+
ids.push(current.is_section ? current.section_id : String((_b = current.node) == null ? void 0 : _b.id));
|
|
4541
|
+
}
|
|
4542
|
+
return ids;
|
|
4543
|
+
}, [targetRenderNodeId, abstractionTree]);
|
|
4544
|
+
const handleToggleProperties = () => {
|
|
4545
|
+
setShowProperties(!showProperties);
|
|
4546
|
+
if (!showProperties) setShowAbstraction(false);
|
|
4547
|
+
};
|
|
4548
|
+
const handleToggleAbstraction = () => {
|
|
4549
|
+
setShowAbstraction(!showAbstraction);
|
|
4550
|
+
if (!showAbstraction) setShowProperties(false);
|
|
4551
|
+
};
|
|
4462
4552
|
const leftAction = useMemo6(() => {
|
|
4463
4553
|
if (activeNodeBranches == null ? void 0 : activeNodeBranches.left) {
|
|
4464
4554
|
return {
|
|
@@ -4503,21 +4593,38 @@ function DescriptionReadModePanel({
|
|
|
4503
4593
|
/* @__PURE__ */ React7.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4 border-b border-white/10 shrink-0 bg-slate-950/50 backdrop-blur-md z-20" }, /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ React7.createElement(
|
|
4504
4594
|
"button",
|
|
4505
4595
|
{
|
|
4506
|
-
onClick:
|
|
4596
|
+
onClick: () => {
|
|
4597
|
+
if (showAbstraction) {
|
|
4598
|
+
setShowAbstraction(false);
|
|
4599
|
+
} else if (showProperties) {
|
|
4600
|
+
setShowProperties(false);
|
|
4601
|
+
} else if (onBack) {
|
|
4602
|
+
onBack();
|
|
4603
|
+
}
|
|
4604
|
+
},
|
|
4507
4605
|
className: "w-8 h-8 flex-shrink-0 grid place-content-center rounded-lg border border-white/10 bg-white/5 hover:bg-white/10 transition-colors text-slate-300",
|
|
4508
4606
|
title: "Voltar"
|
|
4509
4607
|
},
|
|
4510
4608
|
/* @__PURE__ */ React7.createElement(FiArrowLeft, { size: 16 })
|
|
4511
|
-
), /* @__PURE__ */ React7.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React7.createElement("p", { className: "text-xs/relaxed text-slate-400 uppercase tracking-wider font-semibold" }, showProperties ? "Propriedades Adicionais" : "Modo de Leitura"), /* @__PURE__ */ React7.createElement("h2", { className: "text-lg sm:text-xl font-semibold tracking-tight text-white truncate", title }, title || "Sem T\xEDtulo"))), /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" }, hasCustomProps && /* @__PURE__ */ React7.createElement(
|
|
4609
|
+
), /* @__PURE__ */ React7.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React7.createElement("p", { className: "text-xs/relaxed text-slate-400 uppercase tracking-wider font-semibold" }, showAbstraction ? "Tree de Abstra\xE7\xE3o" : showProperties ? "Propriedades Adicionais" : "Modo de Leitura"), /* @__PURE__ */ React7.createElement("h2", { className: "text-lg sm:text-xl font-semibold tracking-tight text-white truncate", title }, title || "Sem T\xEDtulo"))), /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" }, hasCustomProps && /* @__PURE__ */ React7.createElement(
|
|
4512
4610
|
"button",
|
|
4513
4611
|
{
|
|
4514
|
-
onClick:
|
|
4612
|
+
onClick: handleToggleProperties,
|
|
4515
4613
|
className: `relative w-9 h-9 grid place-content-center rounded-lg border transition-colors
|
|
4516
4614
|
${showProperties ? "border-cyan-500/50 bg-cyan-500/10 text-cyan-300" : "border-white/15 bg-transparent hover:bg-white/5 text-slate-300 hover:text-white"}`,
|
|
4517
4615
|
title: showProperties ? "Ver Descri\xE7\xE3o" : "Ver Propriedades Adicionais"
|
|
4518
4616
|
},
|
|
4519
4617
|
showProperties ? /* @__PURE__ */ React7.createElement(FiAlignLeft, { size: 16 }) : /* @__PURE__ */ React7.createElement(FiList2, { size: 16 }),
|
|
4520
|
-
!showProperties && /* @__PURE__ */ React7.createElement("span", { className: "absolute top-1.5 right-1.5 block h-2 w-2 rounded-full bg-cyan-400 ring-2 ring-slate-900 animate-pulse" })
|
|
4618
|
+
!showProperties && !showAbstraction && /* @__PURE__ */ React7.createElement("span", { className: "absolute top-1.5 right-1.5 block h-2 w-2 rounded-full bg-cyan-400 ring-2 ring-slate-900 animate-pulse" })
|
|
4619
|
+
), hasAbstraction && /* @__PURE__ */ React7.createElement(
|
|
4620
|
+
"button",
|
|
4621
|
+
{
|
|
4622
|
+
onClick: handleToggleAbstraction,
|
|
4623
|
+
className: `relative w-9 h-9 grid place-content-center rounded-lg border transition-colors
|
|
4624
|
+
${showAbstraction ? "border-purple-500/50 bg-purple-500/10 text-purple-300" : "border-white/15 bg-transparent hover:bg-white/5 text-slate-300 hover:text-white"}`,
|
|
4625
|
+
title: showAbstraction ? "Voltar \xE0 Descri\xE7\xE3o" : "Ver Tree de Abstra\xE7\xE3o"
|
|
4626
|
+
},
|
|
4627
|
+
/* @__PURE__ */ React7.createElement(FiGitBranch, { size: 16 })
|
|
4521
4628
|
), onRenderFullAncestry && /* @__PURE__ */ React7.createElement(
|
|
4522
4629
|
"button",
|
|
4523
4630
|
{
|
|
@@ -4531,7 +4638,7 @@ function DescriptionReadModePanel({
|
|
|
4531
4638
|
{
|
|
4532
4639
|
onClick: onEdit,
|
|
4533
4640
|
className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-slate-300 hover:text-white",
|
|
4534
|
-
title: "Editar Descri\xE7\xE3o"
|
|
4641
|
+
title: "Editar Descri\xE7\xE3o / Estrutura"
|
|
4535
4642
|
},
|
|
4536
4643
|
/* @__PURE__ */ React7.createElement(FiEdit2, { size: 16 })
|
|
4537
4644
|
), /* @__PURE__ */ React7.createElement(
|
|
@@ -4543,7 +4650,40 @@ function DescriptionReadModePanel({
|
|
|
4543
4650
|
},
|
|
4544
4651
|
"\xD7"
|
|
4545
4652
|
))),
|
|
4546
|
-
/* @__PURE__ */ React7.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10" },
|
|
4653
|
+
/* @__PURE__ */ React7.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10", onClick: () => setTargetRenderNodeId(null) }, showAbstraction ? /* @__PURE__ */ React7.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4" }, /* @__PURE__ */ React7.createElement("h3", { className: "text-sm font-semibold text-purple-300 uppercase tracking-wider" }, "Explorar Hierarquia"), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-wrap gap-2" }, targetRenderNodeId && onRenderAbstractionTree && /* @__PURE__ */ React7.createElement(
|
|
4654
|
+
"button",
|
|
4655
|
+
{
|
|
4656
|
+
onClick: (e) => {
|
|
4657
|
+
e.stopPropagation();
|
|
4658
|
+
onRenderAbstractionTree(targetRenderNodeId);
|
|
4659
|
+
},
|
|
4660
|
+
className: "px-3 py-1.5 rounded-md bg-fuchsia-600 text-white hover:bg-fuchsia-500 transition-colors flex items-center gap-1.5 text-xs font-bold shadow-lg animate-in zoom-in-95 duration-200",
|
|
4661
|
+
title: "Renderiza no 3D apenas o caminho at\xE9 o Node selecionado"
|
|
4662
|
+
},
|
|
4663
|
+
/* @__PURE__ */ React7.createElement(FiLayers3, { size: 14 }),
|
|
4664
|
+
" Renderizar Caminho"
|
|
4665
|
+
), onRenderAbstractionTree && /* @__PURE__ */ React7.createElement(
|
|
4666
|
+
"button",
|
|
4667
|
+
{
|
|
4668
|
+
onClick: (e) => {
|
|
4669
|
+
e.stopPropagation();
|
|
4670
|
+
setTargetRenderNodeId(null);
|
|
4671
|
+
onRenderAbstractionTree(null);
|
|
4672
|
+
},
|
|
4673
|
+
className: "px-3 py-1.5 rounded-md bg-slate-700 border border-white/10 text-slate-200 hover:bg-slate-600 hover:text-white transition-colors flex items-center gap-1.5 text-xs font-semibold",
|
|
4674
|
+
title: "Renderiza a Abstraction Tree inteira verticalmente"
|
|
4675
|
+
},
|
|
4676
|
+
/* @__PURE__ */ React7.createElement(FiLayers3, { size: 14 }),
|
|
4677
|
+
" Renderizar Completa"
|
|
4678
|
+
))), /* @__PURE__ */ React7.createElement("div", { className: "bg-slate-900/60 border border-white/10 rounded-lg p-4" }, /* @__PURE__ */ React7.createElement(
|
|
4679
|
+
ReadOnlyNodeItem,
|
|
4680
|
+
{
|
|
4681
|
+
nodeData: abstractionTree,
|
|
4682
|
+
onViewSelect: setTargetRenderNodeId,
|
|
4683
|
+
highlightedPathIds,
|
|
4684
|
+
targetRenderNodeId
|
|
4685
|
+
}
|
|
4686
|
+
))) : showProperties ? /* @__PURE__ */ React7.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300" }, customProperties.map((prop) => /* @__PURE__ */ React7.createElement(
|
|
4547
4687
|
CustomPropertyDisplay,
|
|
4548
4688
|
{
|
|
4549
4689
|
key: prop.id,
|
|
@@ -4572,7 +4712,7 @@ function DescriptionReadModePanel({
|
|
|
4572
4712
|
onImageClick
|
|
4573
4713
|
}
|
|
4574
4714
|
)),
|
|
4575
|
-
leftAction && /* @__PURE__ */ React7.createElement(
|
|
4715
|
+
leftAction && !showAbstraction && !showProperties && /* @__PURE__ */ React7.createElement(
|
|
4576
4716
|
"button",
|
|
4577
4717
|
{
|
|
4578
4718
|
onClick: leftAction.onClick,
|
|
@@ -4584,7 +4724,7 @@ function DescriptionReadModePanel({
|
|
|
4584
4724
|
${leftAction.type === "branch" ? "bg-indigo-500/20 text-indigo-300 group-hover/btn:text-white group-hover/btn:bg-indigo-500" : "bg-rose-500/20 text-rose-300 group-hover/btn:text-white group-hover/btn:bg-rose-500"}
|
|
4585
4725
|
` }, leftAction.type === "branch" ? /* @__PURE__ */ React7.createElement(FiChevronLeft, { size: 20 }) : /* @__PURE__ */ React7.createElement(FiCornerUpLeft, { size: 20 }))
|
|
4586
4726
|
),
|
|
4587
|
-
rightAction && /* @__PURE__ */ React7.createElement(
|
|
4727
|
+
rightAction && !showAbstraction && !showProperties && /* @__PURE__ */ React7.createElement(
|
|
4588
4728
|
"button",
|
|
4589
4729
|
{
|
|
4590
4730
|
onClick: rightAction.onClick,
|
|
@@ -4761,7 +4901,7 @@ import React10, { useState as useState10, useEffect as useEffect9, useMemo as us
|
|
|
4761
4901
|
import {
|
|
4762
4902
|
FiEdit2 as FiEdit23,
|
|
4763
4903
|
FiBookOpen as FiBookOpen2,
|
|
4764
|
-
FiFolder,
|
|
4904
|
+
FiFolder as FiFolder2,
|
|
4765
4905
|
FiMousePointer,
|
|
4766
4906
|
FiCheck as FiCheck4,
|
|
4767
4907
|
FiLayers as FiLayers5,
|
|
@@ -4770,7 +4910,7 @@ import {
|
|
|
4770
4910
|
FiChevronRight as FiChevronRight4,
|
|
4771
4911
|
FiCornerUpLeft as FiCornerUpLeft2,
|
|
4772
4912
|
FiCornerUpRight as FiCornerUpRight3,
|
|
4773
|
-
FiGitBranch,
|
|
4913
|
+
FiGitBranch as FiGitBranch2,
|
|
4774
4914
|
FiPlus as FiPlus2,
|
|
4775
4915
|
FiLock
|
|
4776
4916
|
} from "react-icons/fi";
|
|
@@ -4852,7 +4992,7 @@ function AncestryPickerModal({
|
|
|
4852
4992
|
}
|
|
4853
4993
|
|
|
4854
4994
|
// src/components/CreateAncestryPanel.jsx
|
|
4855
|
-
var
|
|
4995
|
+
var findNodePath2 = (tree, targetNodeId, currentPath = []) => {
|
|
4856
4996
|
var _a;
|
|
4857
4997
|
if (!tree) return null;
|
|
4858
4998
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
@@ -4861,22 +5001,41 @@ var findNodePath = (tree, targetNodeId, currentPath = []) => {
|
|
|
4861
5001
|
}
|
|
4862
5002
|
if (tree.children) {
|
|
4863
5003
|
for (let i = 0; i < tree.children.length; i++) {
|
|
4864
|
-
const res =
|
|
5004
|
+
const res = findNodePath2(tree.children[i], targetNodeId, [...currentPath, i]);
|
|
4865
5005
|
if (res) return res;
|
|
4866
5006
|
}
|
|
4867
5007
|
}
|
|
4868
5008
|
return null;
|
|
4869
5009
|
};
|
|
4870
|
-
var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, onMoveNode, selectedParentId, level = 0, isLast = false, path = [], isEditable }) => {
|
|
5010
|
+
var NodeItem = ({ nodeData, onSelectParent, onViewSelect, highlightedPathIds = [], targetRenderNodeId, onRemoveNode, onEditRelationship, onMoveNode, selectedParentId, level = 0, isLast = false, path = [], isEditable }) => {
|
|
4871
5011
|
var _a, _b;
|
|
4872
5012
|
const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
|
|
4873
5013
|
const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
|
|
4874
5014
|
const [isDragOver, setIsDragOver] = useState10(false);
|
|
4875
|
-
const
|
|
5015
|
+
const isSelectedParent = String(selectedParentId) === String(itemId);
|
|
5016
|
+
const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
|
|
5017
|
+
const isHighlightedPath = highlightedPathIds.includes(String(itemId));
|
|
4876
5018
|
const hasChildren = nodeData.children && nodeData.children.length > 0;
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
5019
|
+
let itemBgClass = "bg-slate-900/50 hover:bg-slate-800/80";
|
|
5020
|
+
let textColorClass = "text-slate-200";
|
|
5021
|
+
if (nodeData.is_section) {
|
|
5022
|
+
itemBgClass = isSelectedParent ? "bg-indigo-500/30 ring-2 ring-indigo-400" : "bg-indigo-900/20 border border-indigo-500/30 hover:bg-indigo-900/40";
|
|
5023
|
+
textColorClass = isSelectedParent ? "text-indigo-200 font-bold" : "text-indigo-300";
|
|
5024
|
+
} else {
|
|
5025
|
+
if (isSelectedParent) {
|
|
5026
|
+
itemBgClass = "bg-purple-500/30 ring-2 ring-purple-400";
|
|
5027
|
+
textColorClass = "text-purple-200 font-semibold";
|
|
5028
|
+
} else if (isTargetViewNode) {
|
|
5029
|
+
itemBgClass = "bg-fuchsia-600/40 ring-2 ring-fuchsia-400 shadow-[0_0_15px_rgba(217,70,239,0.3)]";
|
|
5030
|
+
textColorClass = "text-white font-bold";
|
|
5031
|
+
} else if (isHighlightedPath) {
|
|
5032
|
+
itemBgClass = "bg-fuchsia-900/30 border border-fuchsia-500/40";
|
|
5033
|
+
textColorClass = "text-fuchsia-200 font-semibold";
|
|
5034
|
+
} else {
|
|
5035
|
+
textColorClass = "text-slate-200";
|
|
5036
|
+
}
|
|
5037
|
+
}
|
|
5038
|
+
const cursorClass = isEditable ? "cursor-grab active:cursor-grabbing" : "cursor-pointer";
|
|
4880
5039
|
const handleDragStart = (e) => {
|
|
4881
5040
|
if (!isEditable) {
|
|
4882
5041
|
e.preventDefault();
|
|
@@ -4906,23 +5065,9 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4906
5065
|
if (!isEditable) return;
|
|
4907
5066
|
const sourceId = e.dataTransfer.getData("nodeId");
|
|
4908
5067
|
if (sourceId === String(itemId)) return;
|
|
4909
|
-
if (onMoveNode)
|
|
4910
|
-
onMoveNode(sourceId, itemId);
|
|
4911
|
-
}
|
|
5068
|
+
if (onMoveNode) onMoveNode(sourceId, itemId);
|
|
4912
5069
|
};
|
|
4913
|
-
return /* @__PURE__ */ React10.createElement("div", { className: "relative" }, level > 0 && /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
|
|
4914
|
-
"span",
|
|
4915
|
-
{
|
|
4916
|
-
className: `absolute -left-4 top-0 w-px bg-cyan-600/60 ${isLast ? "h-[1.125rem]" : "h-full"}`,
|
|
4917
|
-
"aria-hidden": "true"
|
|
4918
|
-
}
|
|
4919
|
-
), /* @__PURE__ */ React10.createElement(
|
|
4920
|
-
"span",
|
|
4921
|
-
{
|
|
4922
|
-
className: `absolute -left-4 top-[1.125rem] h-px w-4 bg-cyan-600/60`,
|
|
4923
|
-
"aria-hidden": "true"
|
|
4924
|
-
}
|
|
4925
|
-
)), /* @__PURE__ */ React10.createElement(
|
|
5070
|
+
return /* @__PURE__ */ React10.createElement("div", { className: "relative" }, level > 0 && /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement("span", { className: `absolute -left-4 top-0 w-px ${isHighlightedPath ? "bg-fuchsia-500 shadow-[0_0_8px_rgba(217,70,239,0.8)]" : "bg-cyan-600/60"} ${isLast ? "h-[1.125rem]" : "h-full"}`, "aria-hidden": "true" }), /* @__PURE__ */ React10.createElement("span", { className: `absolute -left-4 top-[1.125rem] h-px w-4 ${isHighlightedPath ? "bg-fuchsia-500 shadow-[0_0_8px_rgba(217,70,239,0.8)]" : "bg-cyan-600/60"}`, "aria-hidden": "true" })), /* @__PURE__ */ React10.createElement(
|
|
4926
5071
|
"div",
|
|
4927
5072
|
{
|
|
4928
5073
|
draggable: isEditable,
|
|
@@ -4930,63 +5075,35 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4930
5075
|
onDragOver: handleDragOver,
|
|
4931
5076
|
onDragLeave: handleDragLeave,
|
|
4932
5077
|
onDrop: handleDrop,
|
|
4933
|
-
onClick: () => {
|
|
5078
|
+
onClick: (e) => {
|
|
5079
|
+
e.stopPropagation();
|
|
4934
5080
|
if (isEditable) {
|
|
4935
5081
|
onSelectParent(itemId);
|
|
5082
|
+
} else if (onViewSelect) {
|
|
5083
|
+
onViewSelect(itemId);
|
|
4936
5084
|
}
|
|
4937
5085
|
},
|
|
4938
5086
|
className: `flex items-center justify-between gap-2 px-3 h-9 rounded-md transition-all duration-150 border
|
|
4939
5087
|
${isDragOver ? "border-dashed border-yellow-400 bg-yellow-400/10" : "border-transparent"}
|
|
4940
5088
|
${itemBgClass} ${cursorClass}`
|
|
4941
5089
|
},
|
|
4942
|
-
/* @__PURE__ */ React10.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ React10.createElement(
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
stroke: "currentColor",
|
|
4951
|
-
strokeWidth: "2",
|
|
4952
|
-
strokeLinecap: "round",
|
|
4953
|
-
strokeLinejoin: "round",
|
|
4954
|
-
className: "lucide lucide-blend-icon lucide-blend mr-1.5 inline-block"
|
|
4955
|
-
},
|
|
4956
|
-
/* @__PURE__ */ React10.createElement("circle", { cx: "9", cy: "9", r: "7" }),
|
|
4957
|
-
/* @__PURE__ */ React10.createElement("circle", { cx: "15", cy: "15", r: "7" })
|
|
4958
|
-
), nodeData.is_section && /* @__PURE__ */ React10.createElement(FiFolder, { className: "mr-2" }), itemName),
|
|
4959
|
-
level > 0 && isEditable && /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-1 animate-in fade-in duration-200" }, !nodeData.is_section && /* @__PURE__ */ React10.createElement(
|
|
4960
|
-
"button",
|
|
4961
|
-
{
|
|
4962
|
-
onClick: (e) => {
|
|
4963
|
-
e.stopPropagation();
|
|
4964
|
-
onEditRelationship(path, nodeData.relationship || {});
|
|
4965
|
-
},
|
|
4966
|
-
className: "w-6 h-6 grid place-content-center rounded-full hover:bg-cyan-500/20 text-cyan-400 transition-colors flex-shrink-0",
|
|
4967
|
-
title: "Editar detalhes da rela\xE7\xE3o",
|
|
4968
|
-
style: { cursor: "pointer" }
|
|
4969
|
-
},
|
|
4970
|
-
/* @__PURE__ */ React10.createElement(FiEdit23, { size: 12 })
|
|
4971
|
-
), /* @__PURE__ */ React10.createElement(
|
|
4972
|
-
"button",
|
|
4973
|
-
{
|
|
4974
|
-
onClick: (e) => {
|
|
4975
|
-
e.stopPropagation();
|
|
4976
|
-
onRemoveNode(path);
|
|
4977
|
-
},
|
|
4978
|
-
className: "w-6 h-6 grid place-content-center rounded-full hover:bg-red-500/20 text-red-400 text-lg transition-colors flex-shrink-0",
|
|
4979
|
-
title: "Remover Node da ancestralidade",
|
|
4980
|
-
style: { cursor: "pointer" }
|
|
4981
|
-
},
|
|
4982
|
-
"\xD7"
|
|
4983
|
-
))
|
|
5090
|
+
/* @__PURE__ */ React10.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ React10.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "mr-1.5 inline-block" }, /* @__PURE__ */ React10.createElement("circle", { cx: "9", cy: "9", r: "7" }), /* @__PURE__ */ React10.createElement("circle", { cx: "15", cy: "15", r: "7" })), nodeData.is_section && /* @__PURE__ */ React10.createElement(FiFolder2, { className: "mr-2" }), itemName),
|
|
5091
|
+
level > 0 && isEditable && /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-1 animate-in fade-in duration-200" }, !nodeData.is_section && /* @__PURE__ */ React10.createElement("button", { onClick: (e) => {
|
|
5092
|
+
e.stopPropagation();
|
|
5093
|
+
onEditRelationship(path, nodeData.relationship || {});
|
|
5094
|
+
}, className: "w-6 h-6 grid place-content-center rounded-full hover:bg-cyan-500/20 text-cyan-400 transition-colors flex-shrink-0", title: "Editar detalhes da rela\xE7\xE3o" }, /* @__PURE__ */ React10.createElement(FiEdit23, { size: 12 })), /* @__PURE__ */ React10.createElement("button", { onClick: (e) => {
|
|
5095
|
+
e.stopPropagation();
|
|
5096
|
+
onRemoveNode(path);
|
|
5097
|
+
}, className: "w-6 h-6 grid place-content-center rounded-full hover:bg-red-500/20 text-red-400 text-lg transition-colors flex-shrink-0", title: "Remover Node" }, "\xD7"))
|
|
4984
5098
|
), hasChildren && /* @__PURE__ */ React10.createElement("div", { className: "mt-2 space-y-2 pl-8" }, nodeData.children.map((child, index) => /* @__PURE__ */ React10.createElement(
|
|
4985
5099
|
NodeItem,
|
|
4986
5100
|
{
|
|
4987
5101
|
key: `${child.is_section ? child.id : child.node.id}-${index}`,
|
|
4988
5102
|
nodeData: child,
|
|
4989
5103
|
onSelectParent,
|
|
5104
|
+
onViewSelect,
|
|
5105
|
+
highlightedPathIds,
|
|
5106
|
+
targetRenderNodeId,
|
|
4990
5107
|
onRemoveNode,
|
|
4991
5108
|
onEditRelationship,
|
|
4992
5109
|
onMoveNode,
|
|
@@ -5001,11 +5118,8 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
5001
5118
|
function CreateAncestryPanel({
|
|
5002
5119
|
ancestryMode,
|
|
5003
5120
|
setAncestryMode,
|
|
5004
|
-
// <--- Nova prop necessária para as novas funções manipuladoras
|
|
5005
5121
|
onSelectParent,
|
|
5006
|
-
// Mantido para compatibilidade, mas as novas funções usam setAncestryMode
|
|
5007
5122
|
onRemoveNode,
|
|
5008
|
-
// Mantido para compatibilidade
|
|
5009
5123
|
onSave,
|
|
5010
5124
|
onClose,
|
|
5011
5125
|
onEditRelationship,
|
|
@@ -5016,14 +5130,12 @@ function CreateAncestryPanel({
|
|
|
5016
5130
|
onUpdateTree,
|
|
5017
5131
|
onAncestrySectionChange,
|
|
5018
5132
|
onToggleAddNodes,
|
|
5019
|
-
// Mantido para compatibilidade
|
|
5020
5133
|
onRenderFullAncestry,
|
|
5021
5134
|
onHighlightNode,
|
|
5022
5135
|
onClearAncestryVisuals,
|
|
5023
5136
|
onUploadFile,
|
|
5024
5137
|
onOpenImageViewer,
|
|
5025
5138
|
onRenderAbstractionTree
|
|
5026
|
-
// <--- Nova prop recebida
|
|
5027
5139
|
}) {
|
|
5028
5140
|
const {
|
|
5029
5141
|
tree: rootTree,
|
|
@@ -5040,6 +5152,20 @@ function CreateAncestryPanel({
|
|
|
5040
5152
|
const [customProps, setCustomProps] = useState10([]);
|
|
5041
5153
|
const propsEndRef = useRef8(null);
|
|
5042
5154
|
const [branchStack, setBranchStack] = useState10([]);
|
|
5155
|
+
const [targetRenderNodeId, setTargetRenderNodeId] = useState10(null);
|
|
5156
|
+
const highlightedPathIds = useMemo8(() => {
|
|
5157
|
+
var _a, _b;
|
|
5158
|
+
if (!targetRenderNodeId || !ancestryMode.abstraction_tree) return [];
|
|
5159
|
+
const found = findNodePath2(ancestryMode.abstraction_tree, targetRenderNodeId);
|
|
5160
|
+
if (!found) return [];
|
|
5161
|
+
let current = ancestryMode.abstraction_tree;
|
|
5162
|
+
const ids = [current.is_section ? current.section_id : String((_a = current.node) == null ? void 0 : _a.id)];
|
|
5163
|
+
for (let i of found.path) {
|
|
5164
|
+
current = current.children[i];
|
|
5165
|
+
ids.push(current.is_section ? current.section_id : String((_b = current.node) == null ? void 0 : _b.id));
|
|
5166
|
+
}
|
|
5167
|
+
return ids;
|
|
5168
|
+
}, [targetRenderNodeId, ancestryMode.abstraction_tree]);
|
|
5043
5169
|
const [targetScrollSectionId, setTargetScrollSectionId] = useState10(null);
|
|
5044
5170
|
const [internalHighlightedNodeId, setInternalHighlightedNodeId] = useState10(null);
|
|
5045
5171
|
const [ancestryName, setAncestryName] = useState10(initialName);
|
|
@@ -5063,6 +5189,9 @@ function CreateAncestryPanel({
|
|
|
5063
5189
|
setAncestryMode((prev) => isAbstraction ? { ...prev, selectedAbstractionParentId: nodeId } : { ...prev, selectedParentId: nodeId });
|
|
5064
5190
|
};
|
|
5065
5191
|
const handleToggleAddMode = (isAbstraction = false) => {
|
|
5192
|
+
if (isAbstraction && !ancestryMode.isAddingAbstractionNodes) {
|
|
5193
|
+
setTargetRenderNodeId(null);
|
|
5194
|
+
}
|
|
5066
5195
|
setAncestryMode((prev) => isAbstraction ? { ...prev, isAddingAbstractionNodes: !prev.isAddingAbstractionNodes } : { ...prev, isAddingNodes: !prev.isAddingNodes });
|
|
5067
5196
|
};
|
|
5068
5197
|
const handleRemoveNode = useCallback((pathToRemove, isAbstraction = false) => {
|
|
@@ -5094,7 +5223,7 @@ function CreateAncestryPanel({
|
|
|
5094
5223
|
if (!isAbstraction && branchStack.length > 0) {
|
|
5095
5224
|
let ptr = rootTreeClone;
|
|
5096
5225
|
for (const step of branchStack) {
|
|
5097
|
-
const found =
|
|
5226
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5098
5227
|
if (found && found.node.parallel_branches) {
|
|
5099
5228
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5100
5229
|
if (branch) ptr = branch.tree;
|
|
@@ -5144,14 +5273,15 @@ function CreateAncestryPanel({
|
|
|
5144
5273
|
}
|
|
5145
5274
|
}
|
|
5146
5275
|
};
|
|
5147
|
-
const takeSnapshot = (tree, name, desc, sections, customProps2, isPrivateVal) => {
|
|
5276
|
+
const takeSnapshot = (tree, name, desc, sections, customProps2, isPrivateVal, abstractionTree = null) => {
|
|
5148
5277
|
return {
|
|
5149
5278
|
tree: JSON.stringify(tree),
|
|
5150
5279
|
name,
|
|
5151
5280
|
description: desc || "",
|
|
5152
5281
|
sections: JSON.stringify(sections || []),
|
|
5153
5282
|
customProps: JSON.stringify(customProps2 || []),
|
|
5154
|
-
isPrivate: isPrivateVal
|
|
5283
|
+
isPrivate: isPrivateVal,
|
|
5284
|
+
abstractionTree: JSON.stringify(abstractionTree)
|
|
5155
5285
|
};
|
|
5156
5286
|
};
|
|
5157
5287
|
const getCurrentContext = () => {
|
|
@@ -5170,7 +5300,7 @@ function CreateAncestryPanel({
|
|
|
5170
5300
|
let currentBranch = null;
|
|
5171
5301
|
let currentDirection = null;
|
|
5172
5302
|
for (const step of branchStack) {
|
|
5173
|
-
const found =
|
|
5303
|
+
const found = findNodePath2(currentTreePtr, step.nodeId);
|
|
5174
5304
|
if (!found || !found.node.parallel_branches) return null;
|
|
5175
5305
|
currentBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5176
5306
|
if (!currentBranch) return null;
|
|
@@ -5252,7 +5382,7 @@ function CreateAncestryPanel({
|
|
|
5252
5382
|
let ptr = ancestryMode.tree;
|
|
5253
5383
|
let foundBranch = null;
|
|
5254
5384
|
for (const step of branchStack) {
|
|
5255
|
-
const found =
|
|
5385
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5256
5386
|
if (found && found.node.parallel_branches) {
|
|
5257
5387
|
foundBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5258
5388
|
if (foundBranch) ptr = foundBranch.tree;
|
|
@@ -5285,7 +5415,8 @@ function CreateAncestryPanel({
|
|
|
5285
5415
|
ancestryMode.ancestryDescription,
|
|
5286
5416
|
ancestryMode.ancestryDescriptionSections,
|
|
5287
5417
|
extractedProps,
|
|
5288
|
-
ancestryMode.is_private
|
|
5418
|
+
ancestryMode.is_private,
|
|
5419
|
+
ancestryMode.abstraction_tree
|
|
5289
5420
|
));
|
|
5290
5421
|
} else if (ctx) {
|
|
5291
5422
|
setLastSavedSnapshot(takeSnapshot(
|
|
@@ -5294,7 +5425,8 @@ function CreateAncestryPanel({
|
|
|
5294
5425
|
ctx.description,
|
|
5295
5426
|
ctx.sections,
|
|
5296
5427
|
extractedProps,
|
|
5297
|
-
isPrivate
|
|
5428
|
+
isPrivate,
|
|
5429
|
+
ancestryMode.abstraction_tree
|
|
5298
5430
|
));
|
|
5299
5431
|
}
|
|
5300
5432
|
}, [branchStack, ancestryMode]);
|
|
@@ -5309,7 +5441,7 @@ function CreateAncestryPanel({
|
|
|
5309
5441
|
let ptr = rootTreeClone;
|
|
5310
5442
|
let targetBranch = null;
|
|
5311
5443
|
for (const step of branchStack) {
|
|
5312
|
-
const found =
|
|
5444
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5313
5445
|
if (found && found.node.parallel_branches) {
|
|
5314
5446
|
targetBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5315
5447
|
if (targetBranch) ptr = targetBranch.tree;
|
|
@@ -5337,7 +5469,7 @@ function CreateAncestryPanel({
|
|
|
5337
5469
|
rootTreeClone,
|
|
5338
5470
|
rootExtras
|
|
5339
5471
|
);
|
|
5340
|
-
setLastSavedSnapshot(takeSnapshot(rootTreeClone, ancestryName, description, processedSections, [], isPrivate));
|
|
5472
|
+
setLastSavedSnapshot(takeSnapshot(rootTreeClone, ancestryName, description, processedSections, [], isPrivate, ancestryMode.abstraction_tree));
|
|
5341
5473
|
if (onRenderFullAncestry) {
|
|
5342
5474
|
const fullTreePayload = {
|
|
5343
5475
|
ancestry_id: ancestryMode.currentAncestryId || "temp_root",
|
|
@@ -5367,14 +5499,14 @@ function CreateAncestryPanel({
|
|
|
5367
5499
|
let ptr = rootTreeClone;
|
|
5368
5500
|
for (let i = 0; i < branchStack.length - 1; i++) {
|
|
5369
5501
|
const step = branchStack[i];
|
|
5370
|
-
const found =
|
|
5502
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5371
5503
|
if (found && found.node.parallel_branches) {
|
|
5372
5504
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5373
5505
|
if (branch) ptr = branch.tree;
|
|
5374
5506
|
}
|
|
5375
5507
|
}
|
|
5376
5508
|
const currentStep = branchStack[branchStack.length - 1];
|
|
5377
|
-
const foundParentPath =
|
|
5509
|
+
const foundParentPath = findNodePath2(ptr, currentStep.nodeId);
|
|
5378
5510
|
if (foundParentPath && foundParentPath.node && foundParentPath.node.parallel_branches) {
|
|
5379
5511
|
const branchIndex = foundParentPath.node.parallel_branches.findIndex((b) => b.id === currentStep.branchId);
|
|
5380
5512
|
if (branchIndex !== -1) {
|
|
@@ -5398,7 +5530,8 @@ function CreateAncestryPanel({
|
|
|
5398
5530
|
ancestryMode.ancestryDescription,
|
|
5399
5531
|
ancestryMode.ancestryDescriptionSections,
|
|
5400
5532
|
currentRootProps,
|
|
5401
|
-
isPrivate
|
|
5533
|
+
isPrivate,
|
|
5534
|
+
ancestryMode.abstraction_tree
|
|
5402
5535
|
));
|
|
5403
5536
|
if (onClearAncestryVisuals) {
|
|
5404
5537
|
onClearAncestryVisuals(currentStep.branchId);
|
|
@@ -5417,7 +5550,7 @@ function CreateAncestryPanel({
|
|
|
5417
5550
|
const actions = { left: null, right: null };
|
|
5418
5551
|
const isInBranch = branchStack.length > 0;
|
|
5419
5552
|
if (internalHighlightedNodeId) {
|
|
5420
|
-
const found =
|
|
5553
|
+
const found = findNodePath2(activeTree, internalHighlightedNodeId);
|
|
5421
5554
|
if (found && found.node) {
|
|
5422
5555
|
const branches = found.node.parallel_branches || [];
|
|
5423
5556
|
const leftBranch = branches.find((b) => (b.direction || "right") === "left");
|
|
@@ -5469,7 +5602,7 @@ function CreateAncestryPanel({
|
|
|
5469
5602
|
if (branchStack.length > 0) {
|
|
5470
5603
|
let ptr = rootTreeClone;
|
|
5471
5604
|
for (const step of branchStack) {
|
|
5472
|
-
const found =
|
|
5605
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5473
5606
|
if (found && found.node.parallel_branches) {
|
|
5474
5607
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5475
5608
|
if (branch) ptr = branch.tree;
|
|
@@ -5587,6 +5720,11 @@ function CreateAncestryPanel({
|
|
|
5587
5720
|
const sectionsChanged = JSON.stringify(existingSections) !== lastSavedSnapshot.sections;
|
|
5588
5721
|
const propsChanged = JSON.stringify(customProps) !== lastSavedSnapshot.customProps;
|
|
5589
5722
|
const privateChanged = isPrivate !== lastSavedSnapshot.isPrivate;
|
|
5723
|
+
let abstractionTreeChanged = false;
|
|
5724
|
+
if (branchStack.length === 0) {
|
|
5725
|
+
const currentAbsTreeStr = JSON.stringify(ancestryMode.abstraction_tree);
|
|
5726
|
+
abstractionTreeChanged = currentAbsTreeStr !== lastSavedSnapshot.abstractionTree;
|
|
5727
|
+
}
|
|
5590
5728
|
return treeChanged || nameChanged || descChanged || sectionsChanged || propsChanged || privateChanged;
|
|
5591
5729
|
}, [
|
|
5592
5730
|
ancestryName,
|
|
@@ -5596,6 +5734,7 @@ function CreateAncestryPanel({
|
|
|
5596
5734
|
branchStack,
|
|
5597
5735
|
lastSavedSnapshot,
|
|
5598
5736
|
ancestryMode.tree,
|
|
5737
|
+
ancestryMode.abstraction_tree,
|
|
5599
5738
|
customProps,
|
|
5600
5739
|
isPrivate
|
|
5601
5740
|
]);
|
|
@@ -5609,7 +5748,7 @@ function CreateAncestryPanel({
|
|
|
5609
5748
|
let parentTreePtr = rootTree;
|
|
5610
5749
|
let parentBranch = null;
|
|
5611
5750
|
for (const step of parentStack) {
|
|
5612
|
-
const found =
|
|
5751
|
+
const found = findNodePath2(parentTreePtr, step.nodeId);
|
|
5613
5752
|
if (found && found.node.parallel_branches) {
|
|
5614
5753
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5615
5754
|
if (branch) {
|
|
@@ -5687,7 +5826,7 @@ function CreateAncestryPanel({
|
|
|
5687
5826
|
const rootTreeClone = JSON.parse(JSON.stringify(ancestryMode.tree));
|
|
5688
5827
|
let ptr = rootTreeClone;
|
|
5689
5828
|
for (const step of branchStack) {
|
|
5690
|
-
const foundParent =
|
|
5829
|
+
const foundParent = findNodePath2(ptr, step.nodeId);
|
|
5691
5830
|
if (foundParent && foundParent.node && foundParent.node.parallel_branches) {
|
|
5692
5831
|
const existingBranch = foundParent.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5693
5832
|
if (existingBranch) {
|
|
@@ -5695,7 +5834,7 @@ function CreateAncestryPanel({
|
|
|
5695
5834
|
}
|
|
5696
5835
|
}
|
|
5697
5836
|
}
|
|
5698
|
-
const found =
|
|
5837
|
+
const found = findNodePath2(ptr, nodeId);
|
|
5699
5838
|
if (!found) {
|
|
5700
5839
|
console.error("Node alvo n\xE3o encontrado no contexto atual.");
|
|
5701
5840
|
return;
|
|
@@ -5808,7 +5947,7 @@ function CreateAncestryPanel({
|
|
|
5808
5947
|
let ptr = updatedRootTree;
|
|
5809
5948
|
let targetBranch = null;
|
|
5810
5949
|
for (const step of branchStack) {
|
|
5811
|
-
const found =
|
|
5950
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5812
5951
|
if (found && found.node.parallel_branches) {
|
|
5813
5952
|
targetBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5814
5953
|
if (targetBranch) ptr = targetBranch.tree;
|
|
@@ -5838,7 +5977,8 @@ function CreateAncestryPanel({
|
|
|
5838
5977
|
currentInputDesc,
|
|
5839
5978
|
processedSections,
|
|
5840
5979
|
customProps,
|
|
5841
|
-
isPrivate
|
|
5980
|
+
isPrivate,
|
|
5981
|
+
ancestryMode.abstraction_tree
|
|
5842
5982
|
));
|
|
5843
5983
|
if (onRenderFullAncestry) {
|
|
5844
5984
|
const rotation = branchStack.reduce((acc, step) => {
|
|
@@ -5897,7 +6037,8 @@ function CreateAncestryPanel({
|
|
|
5897
6037
|
currentInputDesc,
|
|
5898
6038
|
processedSections,
|
|
5899
6039
|
customProps,
|
|
5900
|
-
isPrivate
|
|
6040
|
+
isPrivate,
|
|
6041
|
+
ancestryMode.abstraction_tree
|
|
5901
6042
|
));
|
|
5902
6043
|
if (!keepOpen) onClose();
|
|
5903
6044
|
} finally {
|
|
@@ -5950,7 +6091,9 @@ function CreateAncestryPanel({
|
|
|
5950
6091
|
const node = findNode(activeTree, selectedParentId);
|
|
5951
6092
|
return node ? node.name : "Nenhum";
|
|
5952
6093
|
};
|
|
5953
|
-
const
|
|
6094
|
+
const hasMainChildren = activeTree && activeTree.children && activeTree.children.length > 0;
|
|
6095
|
+
const hasAbstractionChildren = branchStack.length === 0 && ancestryMode.abstraction_tree && ancestryMode.abstraction_tree.children && ancestryMode.abstraction_tree.children.length > 0;
|
|
6096
|
+
const canSave = hasMainChildren || hasAbstractionChildren;
|
|
5954
6097
|
const handleSectionChangeWrapper = (sectionId) => {
|
|
5955
6098
|
const ctx = getCurrentContext();
|
|
5956
6099
|
const currentDesc = ctx ? ctx.description : description;
|
|
@@ -6153,7 +6296,7 @@ function CreateAncestryPanel({
|
|
|
6153
6296
|
unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type),
|
|
6154
6297
|
onUploadFile
|
|
6155
6298
|
}
|
|
6156
|
-
)), /* @__PURE__ */ React10.createElement("div", { ref: propsEndRef }))), /* @__PURE__ */ React10.createElement("div", { className: `rounded-lg border transition-all duration-300 overflow-hidden ${isAddingNodes ? "border-cyan-500/40 bg-slate-900/60 ring-1 ring-cyan-500/20" : "border-white/10 bg-slate-800/60"}` }, /* @__PURE__ */ React10.createElement("div", { className: `flex items-center justify-between px-3 py-2 border-b ${isAddingNodes ? "bg-cyan-900/20 border-cyan-500/20" : "bg-white/5 border-white/5"}` }, /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React10.createElement("span", { className: `text-xs font-semibold uppercase tracking-wider ${isAddingNodes ? "text-cyan-300" : "text-slate-400"}` }, "
|
|
6299
|
+
)), /* @__PURE__ */ React10.createElement("div", { ref: propsEndRef }))), /* @__PURE__ */ React10.createElement("div", { className: `rounded-lg border transition-all duration-300 overflow-hidden ${isAddingNodes ? "border-cyan-500/40 bg-slate-900/60 ring-1 ring-cyan-500/20" : "border-white/10 bg-slate-800/60"}` }, /* @__PURE__ */ React10.createElement("div", { className: `flex items-center justify-between px-3 py-2 border-b ${isAddingNodes ? "bg-cyan-900/20 border-cyan-500/20" : "bg-white/5 border-white/5"}` }, /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React10.createElement("span", { className: `text-xs font-semibold uppercase tracking-wider ${isAddingNodes ? "text-cyan-300" : "text-slate-400"}` }, "TREE DE ANCESTRALIDADE ", branchStack.length > 0 && "(Aba)"), isAddingNodes && /* @__PURE__ */ React10.createElement("span", { className: "text-[10px] bg-cyan-500/20 text-cyan-300 px-1.5 py-0.5 rounded animate-pulse" }, "Editando")), /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React10.createElement(
|
|
6157
6300
|
"button",
|
|
6158
6301
|
{
|
|
6159
6302
|
type: "button",
|
|
@@ -6184,44 +6327,77 @@ function CreateAncestryPanel({
|
|
|
6184
6327
|
path: [],
|
|
6185
6328
|
isEditable: isAddingNodes
|
|
6186
6329
|
}
|
|
6187
|
-
), (!activeTree || activeTree.children.length === 0) && !isAddingNodes && /* @__PURE__ */ React10.createElement("div", { className: "text-center py-4 text-xs text-slate-500 italic" }, "A estrutura est\xE1 vazia. Clique no l\xE1pis acima para adicionar nodes."))), branchStack.length === 0 && ancestryMode.abstraction_tree && /* @__PURE__ */ React10.createElement(
|
|
6188
|
-
"
|
|
6189
|
-
{
|
|
6190
|
-
type: "button",
|
|
6191
|
-
onClick: () => {
|
|
6192
|
-
const tempPayload = {
|
|
6193
|
-
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6194
|
-
abstraction_tree: ancestryMode.abstraction_tree
|
|
6195
|
-
};
|
|
6196
|
-
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload);
|
|
6197
|
-
},
|
|
6198
|
-
className: "p-1.5 rounded-md bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600 transition-colors",
|
|
6199
|
-
title: "Renderizar Verticalmente no Cen\xE1rio"
|
|
6200
|
-
},
|
|
6201
|
-
/* @__PURE__ */ React10.createElement(FiLayers5, { size: 14 })
|
|
6202
|
-
), /* @__PURE__ */ React10.createElement(
|
|
6203
|
-
"button",
|
|
6330
|
+
), (!activeTree || activeTree.children.length === 0) && !isAddingNodes && /* @__PURE__ */ React10.createElement("div", { className: "text-center py-4 text-xs text-slate-500 italic" }, "A estrutura est\xE1 vazia. Clique no l\xE1pis acima para adicionar nodes."))), branchStack.length === 0 && ancestryMode.abstraction_tree && /* @__PURE__ */ React10.createElement(
|
|
6331
|
+
"div",
|
|
6204
6332
|
{
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
title: "Editar estrutura da abstra\xE7\xE3o"
|
|
6333
|
+
className: `mt-6 rounded-lg border transition-all duration-300 overflow-hidden ${ancestryMode.isAddingAbstractionNodes ? "border-purple-500/40 bg-slate-900/60 ring-1 ring-purple-500/20" : "border-white/10 bg-slate-800/60"}`,
|
|
6334
|
+
onClick: () => setTargetRenderNodeId(null)
|
|
6208
6335
|
},
|
|
6209
|
-
ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ React10.createElement(
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6336
|
+
/* @__PURE__ */ React10.createElement("div", { className: `flex items-center justify-between px-3 py-2 border-b ${ancestryMode.isAddingAbstractionNodes ? "bg-purple-900/20 border-purple-500/20" : "bg-white/5 border-white/5"}` }, /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React10.createElement("span", { className: `text-xs font-semibold uppercase tracking-wider ${ancestryMode.isAddingAbstractionNodes ? "text-purple-300" : "text-slate-400"}` }, "Tree de Abstra\xE7\xE3o"), ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ React10.createElement("span", { className: "text-[10px] bg-purple-500/20 text-purple-300 px-1.5 py-0.5 rounded animate-pulse" }, "Editando")), /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-2" }, targetRenderNodeId && !ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ React10.createElement(
|
|
6337
|
+
"button",
|
|
6338
|
+
{
|
|
6339
|
+
type: "button",
|
|
6340
|
+
onClick: (e) => {
|
|
6341
|
+
e.stopPropagation();
|
|
6342
|
+
const tempPayload = {
|
|
6343
|
+
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6344
|
+
abstraction_tree: ancestryMode.abstraction_tree
|
|
6345
|
+
};
|
|
6346
|
+
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload, targetRenderNodeId);
|
|
6347
|
+
},
|
|
6348
|
+
className: "px-2 py-1.5 rounded-md bg-fuchsia-600 text-white hover:bg-fuchsia-500 transition-colors flex items-center gap-1 shadow-lg animate-in fade-in zoom-in",
|
|
6349
|
+
title: "Renderizar cen\xE1rio at\xE9 o caminho selecionado"
|
|
6350
|
+
},
|
|
6351
|
+
/* @__PURE__ */ React10.createElement(FiLayers5, { size: 13 }),
|
|
6352
|
+
/* @__PURE__ */ React10.createElement("span", { className: "text-[10px] font-bold uppercase tracking-wider" }, "Renderizar")
|
|
6353
|
+
), /* @__PURE__ */ React10.createElement(
|
|
6354
|
+
"button",
|
|
6355
|
+
{
|
|
6356
|
+
type: "button",
|
|
6357
|
+
onClick: (e) => {
|
|
6358
|
+
e.stopPropagation();
|
|
6359
|
+
const tempPayload = {
|
|
6360
|
+
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6361
|
+
abstraction_tree: ancestryMode.abstraction_tree
|
|
6362
|
+
};
|
|
6363
|
+
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload);
|
|
6364
|
+
},
|
|
6365
|
+
className: "p-1.5 rounded-md bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600 transition-colors",
|
|
6366
|
+
title: "Renderizar Verticalmente Completo"
|
|
6367
|
+
},
|
|
6368
|
+
/* @__PURE__ */ React10.createElement(FiLayers5, { size: 14 })
|
|
6369
|
+
), /* @__PURE__ */ React10.createElement(
|
|
6370
|
+
"button",
|
|
6371
|
+
{
|
|
6372
|
+
type: "button",
|
|
6373
|
+
onClick: (e) => {
|
|
6374
|
+
e.stopPropagation();
|
|
6375
|
+
handleToggleAddMode(true);
|
|
6376
|
+
},
|
|
6377
|
+
className: `p-1.5 rounded-md transition-colors ${ancestryMode.isAddingAbstractionNodes ? "bg-purple-500 text-white shadow-lg shadow-purple-500/30" : "bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600"}`,
|
|
6378
|
+
title: "Editar estrutura da abstra\xE7\xE3o"
|
|
6379
|
+
},
|
|
6380
|
+
ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ React10.createElement(FiCheck4, { size: 14 }) : /* @__PURE__ */ React10.createElement(FiEdit23, { size: 14 })
|
|
6381
|
+
))),
|
|
6382
|
+
/* @__PURE__ */ React10.createElement("div", { className: "p-4 space-y-2" }, ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ React10.createElement("div", { className: "mb-3 p-2 rounded bg-purple-900/20 border border-purple-500/20 text-xs text-purple-200 flex items-start gap-2" }, /* @__PURE__ */ React10.createElement(FiMousePointer, { className: "mt-0.5 flex-shrink-0" }), /* @__PURE__ */ React10.createElement("span", null, "Clique nos nodes do cen\xE1rio para adicion\xE1-los. Arraste e solte para organizar a hierarquia.")), /* @__PURE__ */ React10.createElement(
|
|
6383
|
+
NodeItem,
|
|
6384
|
+
{
|
|
6385
|
+
nodeData: ancestryMode.abstraction_tree,
|
|
6386
|
+
onSelectParent: (id) => handleSelectAncestryParent(id, true),
|
|
6387
|
+
onViewSelect: setTargetRenderNodeId,
|
|
6388
|
+
highlightedPathIds,
|
|
6389
|
+
targetRenderNodeId,
|
|
6390
|
+
onRemoveNode: (path) => handleRemoveNode(path, true),
|
|
6391
|
+
onEditRelationship,
|
|
6392
|
+
onMoveNode: (s, t) => handleMoveNode(s, t, true),
|
|
6393
|
+
selectedParentId: ancestryMode.selectedAbstractionParentId,
|
|
6394
|
+
level: 0,
|
|
6395
|
+
isLast: true,
|
|
6396
|
+
path: [],
|
|
6397
|
+
isEditable: ancestryMode.isAddingAbstractionNodes
|
|
6398
|
+
}
|
|
6399
|
+
))
|
|
6400
|
+
), branchStack.length === 0 && /* @__PURE__ */ React10.createElement("div", { className: "mt-3 flex items-center justify-end px-1" }, /* @__PURE__ */ React10.createElement("label", { className: "flex items-center gap-2 cursor-pointer group select-none" }, /* @__PURE__ */ React10.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${isPrivate ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, isPrivate && /* @__PURE__ */ React10.createElement(FiCheck4, { size: 12, className: "text-white" })), /* @__PURE__ */ React10.createElement(
|
|
6225
6401
|
"input",
|
|
6226
6402
|
{
|
|
6227
6403
|
type: "checkbox",
|
|
@@ -6229,7 +6405,7 @@ function CreateAncestryPanel({
|
|
|
6229
6405
|
onChange: (e) => setIsPrivate(e.target.checked),
|
|
6230
6406
|
className: "hidden"
|
|
6231
6407
|
}
|
|
6232
|
-
), /* @__PURE__ */ React10.createElement("span", { className: `text-xs flex items-center gap-1 transition-colors ${isPrivate ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, /* @__PURE__ */ React10.createElement(FiLock, { size: 10 }), " N\xE3o Export\xE1vel"))))), /* @__PURE__ */ React10.createElement("div", { className: "px-6 pt-2 pb-5 flex-shrink-0" },
|
|
6408
|
+
), /* @__PURE__ */ React10.createElement("span", { className: `text-xs flex items-center gap-1 transition-colors ${isPrivate ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, /* @__PURE__ */ React10.createElement(FiLock, { size: 10 }), " N\xE3o Export\xE1vel"))))), /* @__PURE__ */ React10.createElement("div", { className: "px-6 pt-2 pb-5 flex-shrink-0" }, canSave && /* @__PURE__ */ React10.createElement(
|
|
6233
6409
|
"button",
|
|
6234
6410
|
{
|
|
6235
6411
|
onClick: () => handleLocalSave(false),
|
|
@@ -8752,7 +8928,7 @@ var getAllNodeIdsFromTree = (treeNode) => {
|
|
|
8752
8928
|
traverse(treeNode);
|
|
8753
8929
|
return Array.from(ids);
|
|
8754
8930
|
};
|
|
8755
|
-
var
|
|
8931
|
+
var findNodePath3 = (tree, targetNodeId, currentPath = []) => {
|
|
8756
8932
|
var _a;
|
|
8757
8933
|
if (!tree) return null;
|
|
8758
8934
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
@@ -8761,7 +8937,7 @@ var findNodePath2 = (tree, targetNodeId, currentPath = []) => {
|
|
|
8761
8937
|
}
|
|
8762
8938
|
if (tree.children) {
|
|
8763
8939
|
for (let i = 0; i < tree.children.length; i++) {
|
|
8764
|
-
const res =
|
|
8940
|
+
const res = findNodePath3(tree.children[i], targetNodeId, [...currentPath, i]);
|
|
8765
8941
|
if (res) return res;
|
|
8766
8942
|
}
|
|
8767
8943
|
}
|
|
@@ -10830,13 +11006,34 @@ function XViewScene({
|
|
|
10830
11006
|
},
|
|
10831
11007
|
[addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, readingMode.isActive, ancestryMode.isActive]
|
|
10832
11008
|
);
|
|
10833
|
-
const handleRenderAbstractionTree = useCallback3((ancestryObject) => {
|
|
11009
|
+
const handleRenderAbstractionTree = useCallback3((ancestryObject, targetNodeId = null) => {
|
|
10834
11010
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
10835
11011
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
10836
11012
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
10837
11013
|
const allParentNodes = Object.values(parentDataRef.current).flatMap((f) => f.nodes);
|
|
10838
|
-
|
|
11014
|
+
let fullTree = buildFullAncestryTree(ancestryObject.abstraction_tree, allParentNodes, ancestryDataRef.current);
|
|
10839
11015
|
if (!fullTree || !fullTree.node) return;
|
|
11016
|
+
if (targetNodeId) {
|
|
11017
|
+
const pruneTreeToPath = (treeNode, targetId) => {
|
|
11018
|
+
var _a2;
|
|
11019
|
+
if (!treeNode) return null;
|
|
11020
|
+
const currentId = treeNode.is_section ? treeNode.section_id : String((_a2 = treeNode.node) == null ? void 0 : _a2.id);
|
|
11021
|
+
if (String(currentId) === String(targetId)) {
|
|
11022
|
+
return { ...treeNode, children: [] };
|
|
11023
|
+
}
|
|
11024
|
+
if (treeNode.children && treeNode.children.length > 0) {
|
|
11025
|
+
for (let child of treeNode.children) {
|
|
11026
|
+
const prunedChild = pruneTreeToPath(child, targetId);
|
|
11027
|
+
if (prunedChild) {
|
|
11028
|
+
return { ...treeNode, children: [prunedChild] };
|
|
11029
|
+
}
|
|
11030
|
+
}
|
|
11031
|
+
}
|
|
11032
|
+
return null;
|
|
11033
|
+
};
|
|
11034
|
+
const pruned = pruneTreeToPath(fullTree, targetNodeId);
|
|
11035
|
+
if (pruned) fullTree = pruned;
|
|
11036
|
+
}
|
|
10840
11037
|
const absId = ancestryObject.ancestry_id + "_abs";
|
|
10841
11038
|
handleClearAncestryVisuals(absId);
|
|
10842
11039
|
const colorHex = 9133302;
|
|
@@ -10878,13 +11075,13 @@ function XViewScene({
|
|
|
10878
11075
|
if (action === "open") {
|
|
10879
11076
|
let currentPtr = fullTree;
|
|
10880
11077
|
for (const step of branchStack) {
|
|
10881
|
-
const found =
|
|
11078
|
+
const found = findNodePath3(currentPtr, step.nodeId);
|
|
10882
11079
|
if (found && found.node.parallel_branches) {
|
|
10883
11080
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
10884
11081
|
if (branch) currentPtr = branch.tree;
|
|
10885
11082
|
}
|
|
10886
11083
|
}
|
|
10887
|
-
const foundTarget =
|
|
11084
|
+
const foundTarget = findNodePath3(currentPtr, nodeId);
|
|
10888
11085
|
if (foundTarget && foundTarget.node && foundTarget.node.parallel_branches && foundTarget.node.parallel_branches.length > 0) {
|
|
10889
11086
|
const branchToOpen = foundTarget.node.parallel_branches.find((b) => (b.direction || "right") === direction);
|
|
10890
11087
|
if (!branchToOpen) return;
|
|
@@ -10951,7 +11148,7 @@ function XViewScene({
|
|
|
10951
11148
|
if (newStack.length > 0) {
|
|
10952
11149
|
let ptr = fullTree;
|
|
10953
11150
|
for (const step of newStack) {
|
|
10954
|
-
const found =
|
|
11151
|
+
const found = findNodePath3(ptr, step.nodeId);
|
|
10955
11152
|
if (found && found.node.parallel_branches) {
|
|
10956
11153
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
10957
11154
|
if (branch) {
|
|
@@ -11092,7 +11289,7 @@ function XViewScene({
|
|
|
11092
11289
|
let currentMeta = ancestry;
|
|
11093
11290
|
let currentDirection = null;
|
|
11094
11291
|
for (const step of branchStack) {
|
|
11095
|
-
const found =
|
|
11292
|
+
const found = findNodePath3(currentPtr, step.nodeId);
|
|
11096
11293
|
if (found && found.node.parallel_branches) {
|
|
11097
11294
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
11098
11295
|
if (branch) {
|
|
@@ -11112,6 +11309,18 @@ function XViewScene({
|
|
|
11112
11309
|
// <--- ADICIONADO
|
|
11113
11310
|
};
|
|
11114
11311
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
11312
|
+
const readModeAbstractionTree = useMemo12(() => {
|
|
11313
|
+
if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
|
|
11314
|
+
return null;
|
|
11315
|
+
}
|
|
11316
|
+
const allNodes = Object.values(parentDataRef.current || {}).flatMap((f) => f.nodes || []);
|
|
11317
|
+
const allAncestries = ancestryDataRef.current || [];
|
|
11318
|
+
return buildFullAncestryTree(
|
|
11319
|
+
readingMode.ancestry.abstraction_tree,
|
|
11320
|
+
allNodes,
|
|
11321
|
+
allAncestries
|
|
11322
|
+
);
|
|
11323
|
+
}, [readingMode.isActive, readingMode.ancestry, buildFullAncestryTree, sceneVersion]);
|
|
11115
11324
|
const handleStartReadingAncestry = useCallback3(
|
|
11116
11325
|
async (ancestryObject) => {
|
|
11117
11326
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
@@ -11152,7 +11361,7 @@ function XViewScene({
|
|
|
11152
11361
|
);
|
|
11153
11362
|
let currentPtr = fullTree;
|
|
11154
11363
|
for (const step of branchStack) {
|
|
11155
|
-
const found =
|
|
11364
|
+
const found = findNodePath3(currentPtr, step.nodeId);
|
|
11156
11365
|
if (found && found.node && found.node.parallel_branches) {
|
|
11157
11366
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
11158
11367
|
if (branch) {
|
|
@@ -11820,7 +12029,9 @@ function XViewScene({
|
|
|
11820
12029
|
activeNodeBranches,
|
|
11821
12030
|
backNavigationInfo,
|
|
11822
12031
|
onImageClick: (url, name) => handleOpenImageViewer([{ name: name || "Imagem", value: url }], 0),
|
|
11823
|
-
userRole: userPermissionRole
|
|
12032
|
+
userRole: userPermissionRole,
|
|
12033
|
+
abstractionTree: readModeAbstractionTree,
|
|
12034
|
+
onRenderAbstractionTree: (targetId) => handleRenderAbstractionTree(readingMode.ancestry, targetId)
|
|
11824
12035
|
}
|
|
11825
12036
|
)
|
|
11826
12037
|
),
|
|
@@ -11828,6 +12039,7 @@ function XViewScene({
|
|
|
11828
12039
|
CreateAncestryPanel,
|
|
11829
12040
|
{
|
|
11830
12041
|
ancestryMode,
|
|
12042
|
+
setAncestryMode,
|
|
11831
12043
|
onSelectParent: handleSelectAncestryParent,
|
|
11832
12044
|
onRemoveNode: handleRemoveFromAncestry,
|
|
11833
12045
|
onSave: handleSaveAncestry,
|
|
@@ -11847,7 +12059,7 @@ function XViewScene({
|
|
|
11847
12059
|
onClearAncestryVisuals: handleClearAncestryVisuals,
|
|
11848
12060
|
onUploadFile: upload_file_action,
|
|
11849
12061
|
onOpenImageViewer: handleOpenImageViewer,
|
|
11850
|
-
onRenderAbstractionTree: (data) => handleRenderAbstractionTree(data)
|
|
12062
|
+
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
11851
12063
|
}
|
|
11852
12064
|
),
|
|
11853
12065
|
editingAncestryRel.visible && /* @__PURE__ */ React23.createElement(
|