@lv-x-software-house/x_view 1.1.9-dev.6 → 1.1.9-dev.7

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.
Files changed (3) hide show
  1. package/dist/index.js +164 -35
  2. package/dist/index.mjs +170 -39
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4467,6 +4467,65 @@ function DescriptionDisplay({
4467
4467
  // src/components/DescriptionReadModePanel.jsx
4468
4468
  var import_react7 = __toESM(require("react"));
4469
4469
  var import_fi6 = require("react-icons/fi");
4470
+ var findNodePath = (tree, targetNodeId, currentPath = []) => {
4471
+ var _a;
4472
+ if (!tree) return null;
4473
+ const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
4474
+ if (String(currentNodeId) === String(targetNodeId)) {
4475
+ return { node: tree, path: currentPath };
4476
+ }
4477
+ if (tree.children) {
4478
+ for (let i = 0; i < tree.children.length; i++) {
4479
+ const res = findNodePath(tree.children[i], targetNodeId, [...currentPath, i]);
4480
+ if (res) return res;
4481
+ }
4482
+ }
4483
+ return null;
4484
+ };
4485
+ var ReadOnlyNodeItem = ({ nodeData, onViewSelect, highlightedPathIds = [], targetRenderNodeId, level = 0, isLast = false }) => {
4486
+ var _a, _b;
4487
+ const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
4488
+ const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
4489
+ const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
4490
+ const isHighlightedPath = highlightedPathIds.includes(String(itemId));
4491
+ const hasChildren = nodeData.children && nodeData.children.length > 0;
4492
+ let itemBgClass = "bg-slate-900/50 hover:bg-slate-800/80";
4493
+ let textColorClass = "text-slate-200";
4494
+ if (nodeData.is_section) {
4495
+ itemBgClass = "bg-purple-900/20 border border-purple-500/30 hover:bg-purple-900/40";
4496
+ textColorClass = "text-purple-300";
4497
+ } else {
4498
+ if (isTargetViewNode) {
4499
+ itemBgClass = "bg-fuchsia-600/40 ring-2 ring-fuchsia-400 shadow-[0_0_15px_rgba(217,70,239,0.3)]";
4500
+ textColorClass = "text-white font-bold";
4501
+ } else if (isHighlightedPath) {
4502
+ itemBgClass = "bg-fuchsia-900/30 border border-fuchsia-500/40";
4503
+ textColorClass = "text-fuchsia-200 font-semibold";
4504
+ }
4505
+ }
4506
+ return /* @__PURE__ */ import_react7.default.createElement("div", { className: "relative" }, level > 0 && /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.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__ */ import_react7.default.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__ */ import_react7.default.createElement(
4507
+ "div",
4508
+ {
4509
+ onClick: (e) => {
4510
+ e.stopPropagation();
4511
+ if (onViewSelect) onViewSelect(itemId);
4512
+ },
4513
+ className: `flex items-center justify-between gap-2 px-3 h-9 rounded-md transition-all duration-150 border border-transparent cursor-pointer ${itemBgClass}`
4514
+ },
4515
+ /* @__PURE__ */ import_react7.default.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ import_react7.default.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__ */ import_react7.default.createElement("circle", { cx: "9", cy: "9", r: "7" }), /* @__PURE__ */ import_react7.default.createElement("circle", { cx: "15", cy: "15", r: "7" })), nodeData.is_section && /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiFolder, { className: "mr-2" }), itemName)
4516
+ ), hasChildren && /* @__PURE__ */ import_react7.default.createElement("div", { className: "mt-2 space-y-2 pl-8" }, nodeData.children.map((child, index) => /* @__PURE__ */ import_react7.default.createElement(
4517
+ ReadOnlyNodeItem,
4518
+ {
4519
+ key: `${child.is_section ? child.id : child.node.id}-${index}`,
4520
+ nodeData: child,
4521
+ onViewSelect,
4522
+ highlightedPathIds,
4523
+ targetRenderNodeId,
4524
+ level: level + 1,
4525
+ isLast: index === nodeData.children.length - 1
4526
+ }
4527
+ ))));
4528
+ };
4470
4529
  function DescriptionReadModePanel({
4471
4530
  title,
4472
4531
  description,
@@ -4488,14 +4547,40 @@ function DescriptionReadModePanel({
4488
4547
  backNavigationInfo,
4489
4548
  customProperties = [],
4490
4549
  onImageClick,
4491
- userRole
4492
- // <--- NOVA PROP: Recebendo a role do usuário
4550
+ userRole,
4551
+ // --- NOVAS PROPS PARA ABSTRAÇÃO ---
4552
+ abstractionTree = null,
4553
+ onRenderAbstractionTree = null
4493
4554
  }) {
4494
4555
  const [showProperties, setShowProperties] = (0, import_react7.useState)(false);
4556
+ const [showAbstraction, setShowAbstraction] = (0, import_react7.useState)(false);
4557
+ const [targetRenderNodeId, setTargetRenderNodeId] = (0, import_react7.useState)(null);
4495
4558
  const swallow = (e) => e.stopPropagation();
4496
4559
  const hasCustomProps = customProperties && customProperties.length > 0;
4560
+ const hasAbstraction = abstractionTree && abstractionTree.node;
4497
4561
  const ability = (0, import_react7.useMemo)(() => defineAbilityFor(userRole), [userRole]);
4498
4562
  const canEditAncestry = ability.can("update", "Ancestry");
4563
+ const highlightedPathIds = (0, import_react7.useMemo)(() => {
4564
+ var _a, _b;
4565
+ if (!targetRenderNodeId || !abstractionTree) return [];
4566
+ const found = findNodePath(abstractionTree, targetRenderNodeId);
4567
+ if (!found) return [];
4568
+ let current = abstractionTree;
4569
+ const ids = [current.is_section ? current.section_id : String((_a = current.node) == null ? void 0 : _a.id)];
4570
+ for (let i of found.path) {
4571
+ current = current.children[i];
4572
+ ids.push(current.is_section ? current.section_id : String((_b = current.node) == null ? void 0 : _b.id));
4573
+ }
4574
+ return ids;
4575
+ }, [targetRenderNodeId, abstractionTree]);
4576
+ const handleToggleProperties = () => {
4577
+ setShowProperties(!showProperties);
4578
+ if (!showProperties) setShowAbstraction(false);
4579
+ };
4580
+ const handleToggleAbstraction = () => {
4581
+ setShowAbstraction(!showAbstraction);
4582
+ if (!showAbstraction) setShowProperties(false);
4583
+ };
4499
4584
  const leftAction = (0, import_react7.useMemo)(() => {
4500
4585
  if (activeNodeBranches == null ? void 0 : activeNodeBranches.left) {
4501
4586
  return {
@@ -4545,16 +4630,25 @@ function DescriptionReadModePanel({
4545
4630
  title: "Voltar"
4546
4631
  },
4547
4632
  /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiArrowLeft, { size: 16 })
4548
- ), /* @__PURE__ */ import_react7.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react7.default.createElement("p", { className: "text-xs/relaxed text-slate-400 uppercase tracking-wider font-semibold" }, showProperties ? "Propriedades Adicionais" : "Modo de Leitura"), /* @__PURE__ */ import_react7.default.createElement("h2", { className: "text-lg sm:text-xl font-semibold tracking-tight text-white truncate", title }, title || "Sem T\xEDtulo"))), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" }, hasCustomProps && /* @__PURE__ */ import_react7.default.createElement(
4633
+ ), /* @__PURE__ */ import_react7.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react7.default.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__ */ import_react7.default.createElement("h2", { className: "text-lg sm:text-xl font-semibold tracking-tight text-white truncate", title }, title || "Sem T\xEDtulo"))), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" }, hasCustomProps && /* @__PURE__ */ import_react7.default.createElement(
4549
4634
  "button",
4550
4635
  {
4551
- onClick: () => setShowProperties(!showProperties),
4636
+ onClick: handleToggleProperties,
4552
4637
  className: `relative w-9 h-9 grid place-content-center rounded-lg border transition-colors
4553
4638
  ${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"}`,
4554
4639
  title: showProperties ? "Ver Descri\xE7\xE3o" : "Ver Propriedades Adicionais"
4555
4640
  },
4556
4641
  showProperties ? /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiAlignLeft, { size: 16 }) : /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiList, { size: 16 }),
4557
- !showProperties && /* @__PURE__ */ import_react7.default.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" })
4642
+ !showProperties && !showAbstraction && /* @__PURE__ */ import_react7.default.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" })
4643
+ ), hasAbstraction && /* @__PURE__ */ import_react7.default.createElement(
4644
+ "button",
4645
+ {
4646
+ onClick: handleToggleAbstraction,
4647
+ className: `relative w-9 h-9 grid place-content-center rounded-lg border transition-colors
4648
+ ${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"}`,
4649
+ title: showAbstraction ? "Voltar \xE0 Descri\xE7\xE3o" : "Ver Tree de Abstra\xE7\xE3o"
4650
+ },
4651
+ /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiGitBranch, { size: 16 })
4558
4652
  ), onRenderFullAncestry && /* @__PURE__ */ import_react7.default.createElement(
4559
4653
  "button",
4560
4654
  {
@@ -4568,7 +4662,7 @@ function DescriptionReadModePanel({
4568
4662
  {
4569
4663
  onClick: onEdit,
4570
4664
  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",
4571
- title: "Editar Descri\xE7\xE3o"
4665
+ title: "Editar Descri\xE7\xE3o / Estrutura"
4572
4666
  },
4573
4667
  /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiEdit2, { size: 16 })
4574
4668
  ), /* @__PURE__ */ import_react7.default.createElement(
@@ -4580,7 +4674,40 @@ function DescriptionReadModePanel({
4580
4674
  },
4581
4675
  "\xD7"
4582
4676
  ))),
4583
- /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10" }, showProperties ? /* @__PURE__ */ import_react7.default.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300" }, customProperties.map((prop) => /* @__PURE__ */ import_react7.default.createElement(
4677
+ /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10", onClick: () => setTargetRenderNodeId(null) }, showAbstraction ? /* @__PURE__ */ import_react7.default.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4" }, /* @__PURE__ */ import_react7.default.createElement("h3", { className: "text-sm font-semibold text-purple-300 uppercase tracking-wider" }, "Explorar Hierarquia"), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex flex-wrap gap-2" }, targetRenderNodeId && onRenderAbstractionTree && /* @__PURE__ */ import_react7.default.createElement(
4678
+ "button",
4679
+ {
4680
+ onClick: (e) => {
4681
+ e.stopPropagation();
4682
+ onRenderAbstractionTree(targetRenderNodeId);
4683
+ },
4684
+ 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",
4685
+ title: "Renderiza no 3D apenas o caminho at\xE9 o Node selecionado"
4686
+ },
4687
+ /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiLayers, { size: 14 }),
4688
+ " Renderizar Caminho"
4689
+ ), onRenderAbstractionTree && /* @__PURE__ */ import_react7.default.createElement(
4690
+ "button",
4691
+ {
4692
+ onClick: (e) => {
4693
+ e.stopPropagation();
4694
+ setTargetRenderNodeId(null);
4695
+ onRenderAbstractionTree(null);
4696
+ },
4697
+ 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",
4698
+ title: "Renderiza a Abstraction Tree inteira verticalmente"
4699
+ },
4700
+ /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiLayers, { size: 14 }),
4701
+ " Renderizar Completa"
4702
+ ))), /* @__PURE__ */ import_react7.default.createElement("div", { className: "bg-slate-900/60 border border-white/10 rounded-lg p-4" }, /* @__PURE__ */ import_react7.default.createElement(
4703
+ ReadOnlyNodeItem,
4704
+ {
4705
+ nodeData: abstractionTree,
4706
+ onViewSelect: setTargetRenderNodeId,
4707
+ highlightedPathIds,
4708
+ targetRenderNodeId
4709
+ }
4710
+ ))) : showProperties ? /* @__PURE__ */ import_react7.default.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300" }, customProperties.map((prop) => /* @__PURE__ */ import_react7.default.createElement(
4584
4711
  CustomPropertyDisplay,
4585
4712
  {
4586
4713
  key: prop.id,
@@ -4609,7 +4736,7 @@ function DescriptionReadModePanel({
4609
4736
  onImageClick
4610
4737
  }
4611
4738
  )),
4612
- leftAction && /* @__PURE__ */ import_react7.default.createElement(
4739
+ leftAction && !showAbstraction && !showProperties && /* @__PURE__ */ import_react7.default.createElement(
4613
4740
  "button",
4614
4741
  {
4615
4742
  onClick: leftAction.onClick,
@@ -4621,7 +4748,7 @@ function DescriptionReadModePanel({
4621
4748
  ${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"}
4622
4749
  ` }, leftAction.type === "branch" ? /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiChevronLeft, { size: 20 }) : /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiCornerUpLeft, { size: 20 }))
4623
4750
  ),
4624
- rightAction && /* @__PURE__ */ import_react7.default.createElement(
4751
+ rightAction && !showAbstraction && !showProperties && /* @__PURE__ */ import_react7.default.createElement(
4625
4752
  "button",
4626
4753
  {
4627
4754
  onClick: rightAction.onClick,
@@ -4874,7 +5001,7 @@ function AncestryPickerModal({
4874
5001
  }
4875
5002
 
4876
5003
  // src/components/CreateAncestryPanel.jsx
4877
- var findNodePath = (tree, targetNodeId, currentPath = []) => {
5004
+ var findNodePath2 = (tree, targetNodeId, currentPath = []) => {
4878
5005
  var _a;
4879
5006
  if (!tree) return null;
4880
5007
  const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
@@ -4883,7 +5010,7 @@ var findNodePath = (tree, targetNodeId, currentPath = []) => {
4883
5010
  }
4884
5011
  if (tree.children) {
4885
5012
  for (let i = 0; i < tree.children.length; i++) {
4886
- const res = findNodePath(tree.children[i], targetNodeId, [...currentPath, i]);
5013
+ const res = findNodePath2(tree.children[i], targetNodeId, [...currentPath, i]);
4887
5014
  if (res) return res;
4888
5015
  }
4889
5016
  }
@@ -5038,7 +5165,7 @@ function CreateAncestryPanel({
5038
5165
  const highlightedPathIds = (0, import_react10.useMemo)(() => {
5039
5166
  var _a, _b;
5040
5167
  if (!targetRenderNodeId || !ancestryMode.abstraction_tree) return [];
5041
- const found = findNodePath(ancestryMode.abstraction_tree, targetRenderNodeId);
5168
+ const found = findNodePath2(ancestryMode.abstraction_tree, targetRenderNodeId);
5042
5169
  if (!found) return [];
5043
5170
  let current = ancestryMode.abstraction_tree;
5044
5171
  const ids = [current.is_section ? current.section_id : String((_a = current.node) == null ? void 0 : _a.id)];
@@ -5105,7 +5232,7 @@ function CreateAncestryPanel({
5105
5232
  if (!isAbstraction && branchStack.length > 0) {
5106
5233
  let ptr = rootTreeClone;
5107
5234
  for (const step of branchStack) {
5108
- const found = findNodePath(ptr, step.nodeId);
5235
+ const found = findNodePath2(ptr, step.nodeId);
5109
5236
  if (found && found.node.parallel_branches) {
5110
5237
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5111
5238
  if (branch) ptr = branch.tree;
@@ -5182,7 +5309,7 @@ function CreateAncestryPanel({
5182
5309
  let currentBranch = null;
5183
5310
  let currentDirection = null;
5184
5311
  for (const step of branchStack) {
5185
- const found = findNodePath(currentTreePtr, step.nodeId);
5312
+ const found = findNodePath2(currentTreePtr, step.nodeId);
5186
5313
  if (!found || !found.node.parallel_branches) return null;
5187
5314
  currentBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5188
5315
  if (!currentBranch) return null;
@@ -5264,7 +5391,7 @@ function CreateAncestryPanel({
5264
5391
  let ptr = ancestryMode.tree;
5265
5392
  let foundBranch = null;
5266
5393
  for (const step of branchStack) {
5267
- const found = findNodePath(ptr, step.nodeId);
5394
+ const found = findNodePath2(ptr, step.nodeId);
5268
5395
  if (found && found.node.parallel_branches) {
5269
5396
  foundBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5270
5397
  if (foundBranch) ptr = foundBranch.tree;
@@ -5323,7 +5450,7 @@ function CreateAncestryPanel({
5323
5450
  let ptr = rootTreeClone;
5324
5451
  let targetBranch = null;
5325
5452
  for (const step of branchStack) {
5326
- const found = findNodePath(ptr, step.nodeId);
5453
+ const found = findNodePath2(ptr, step.nodeId);
5327
5454
  if (found && found.node.parallel_branches) {
5328
5455
  targetBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5329
5456
  if (targetBranch) ptr = targetBranch.tree;
@@ -5381,14 +5508,14 @@ function CreateAncestryPanel({
5381
5508
  let ptr = rootTreeClone;
5382
5509
  for (let i = 0; i < branchStack.length - 1; i++) {
5383
5510
  const step = branchStack[i];
5384
- const found = findNodePath(ptr, step.nodeId);
5511
+ const found = findNodePath2(ptr, step.nodeId);
5385
5512
  if (found && found.node.parallel_branches) {
5386
5513
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5387
5514
  if (branch) ptr = branch.tree;
5388
5515
  }
5389
5516
  }
5390
5517
  const currentStep = branchStack[branchStack.length - 1];
5391
- const foundParentPath = findNodePath(ptr, currentStep.nodeId);
5518
+ const foundParentPath = findNodePath2(ptr, currentStep.nodeId);
5392
5519
  if (foundParentPath && foundParentPath.node && foundParentPath.node.parallel_branches) {
5393
5520
  const branchIndex = foundParentPath.node.parallel_branches.findIndex((b) => b.id === currentStep.branchId);
5394
5521
  if (branchIndex !== -1) {
@@ -5432,7 +5559,7 @@ function CreateAncestryPanel({
5432
5559
  const actions = { left: null, right: null };
5433
5560
  const isInBranch = branchStack.length > 0;
5434
5561
  if (internalHighlightedNodeId) {
5435
- const found = findNodePath(activeTree, internalHighlightedNodeId);
5562
+ const found = findNodePath2(activeTree, internalHighlightedNodeId);
5436
5563
  if (found && found.node) {
5437
5564
  const branches = found.node.parallel_branches || [];
5438
5565
  const leftBranch = branches.find((b) => (b.direction || "right") === "left");
@@ -5484,7 +5611,7 @@ function CreateAncestryPanel({
5484
5611
  if (branchStack.length > 0) {
5485
5612
  let ptr = rootTreeClone;
5486
5613
  for (const step of branchStack) {
5487
- const found = findNodePath(ptr, step.nodeId);
5614
+ const found = findNodePath2(ptr, step.nodeId);
5488
5615
  if (found && found.node.parallel_branches) {
5489
5616
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5490
5617
  if (branch) ptr = branch.tree;
@@ -5630,7 +5757,7 @@ function CreateAncestryPanel({
5630
5757
  let parentTreePtr = rootTree;
5631
5758
  let parentBranch = null;
5632
5759
  for (const step of parentStack) {
5633
- const found = findNodePath(parentTreePtr, step.nodeId);
5760
+ const found = findNodePath2(parentTreePtr, step.nodeId);
5634
5761
  if (found && found.node.parallel_branches) {
5635
5762
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5636
5763
  if (branch) {
@@ -5708,7 +5835,7 @@ function CreateAncestryPanel({
5708
5835
  const rootTreeClone = JSON.parse(JSON.stringify(ancestryMode.tree));
5709
5836
  let ptr = rootTreeClone;
5710
5837
  for (const step of branchStack) {
5711
- const foundParent = findNodePath(ptr, step.nodeId);
5838
+ const foundParent = findNodePath2(ptr, step.nodeId);
5712
5839
  if (foundParent && foundParent.node && foundParent.node.parallel_branches) {
5713
5840
  const existingBranch = foundParent.node.parallel_branches.find((b) => b.id === step.branchId);
5714
5841
  if (existingBranch) {
@@ -5716,7 +5843,7 @@ function CreateAncestryPanel({
5716
5843
  }
5717
5844
  }
5718
5845
  }
5719
- const found = findNodePath(ptr, nodeId);
5846
+ const found = findNodePath2(ptr, nodeId);
5720
5847
  if (!found) {
5721
5848
  console.error("Node alvo n\xE3o encontrado no contexto atual.");
5722
5849
  return;
@@ -5829,7 +5956,7 @@ function CreateAncestryPanel({
5829
5956
  let ptr = updatedRootTree;
5830
5957
  let targetBranch = null;
5831
5958
  for (const step of branchStack) {
5832
- const found = findNodePath(ptr, step.nodeId);
5959
+ const found = findNodePath2(ptr, step.nodeId);
5833
5960
  if (found && found.node.parallel_branches) {
5834
5961
  targetBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5835
5962
  if (targetBranch) ptr = targetBranch.tree;
@@ -6178,7 +6305,7 @@ function CreateAncestryPanel({
6178
6305
  unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type),
6179
6306
  onUploadFile
6180
6307
  }
6181
- )), /* @__PURE__ */ import_react10.default.createElement("div", { ref: propsEndRef }))), /* @__PURE__ */ import_react10.default.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__ */ import_react10.default.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__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react10.default.createElement("span", { className: `text-xs font-semibold uppercase tracking-wider ${isAddingNodes ? "text-cyan-300" : "text-slate-400"}` }, "Estrutura ", branchStack.length > 0 && "(Aba)"), isAddingNodes && /* @__PURE__ */ import_react10.default.createElement("span", { className: "text-[10px] bg-cyan-500/20 text-cyan-300 px-1.5 py-0.5 rounded animate-pulse" }, "Editando")), /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react10.default.createElement(
6308
+ )), /* @__PURE__ */ import_react10.default.createElement("div", { ref: propsEndRef }))), /* @__PURE__ */ import_react10.default.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__ */ import_react10.default.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__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react10.default.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__ */ import_react10.default.createElement("span", { className: "text-[10px] bg-cyan-500/20 text-cyan-300 px-1.5 py-0.5 rounded animate-pulse" }, "Editando")), /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react10.default.createElement(
6182
6309
  "button",
6183
6310
  {
6184
6311
  type: "button",
@@ -6215,7 +6342,7 @@ function CreateAncestryPanel({
6215
6342
  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"}`,
6216
6343
  onClick: () => setTargetRenderNodeId(null)
6217
6344
  },
6218
- /* @__PURE__ */ import_react10.default.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__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react10.default.createElement("span", { className: `text-xs font-semibold uppercase tracking-wider ${ancestryMode.isAddingAbstractionNodes ? "text-purple-300" : "text-slate-400"}` }, "Estrutura de Abstra\xE7\xE3o"), ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ import_react10.default.createElement("span", { className: "text-[10px] bg-purple-500/20 text-purple-300 px-1.5 py-0.5 rounded animate-pulse" }, "Editando")), /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, targetRenderNodeId && !ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ import_react10.default.createElement(
6345
+ /* @__PURE__ */ import_react10.default.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__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react10.default.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__ */ import_react10.default.createElement("span", { className: "text-[10px] bg-purple-500/20 text-purple-300 px-1.5 py-0.5 rounded animate-pulse" }, "Editando")), /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, targetRenderNodeId && !ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ import_react10.default.createElement(
6219
6346
  "button",
6220
6347
  {
6221
6348
  type: "button",
@@ -6231,7 +6358,7 @@ function CreateAncestryPanel({
6231
6358
  title: "Renderizar cen\xE1rio at\xE9 o caminho selecionado"
6232
6359
  },
6233
6360
  /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiLayers, { size: 13 }),
6234
- /* @__PURE__ */ import_react10.default.createElement("span", { className: "text-[10px] font-bold uppercase tracking-wider" }, "Caminho")
6361
+ /* @__PURE__ */ import_react10.default.createElement("span", { className: "text-[10px] font-bold uppercase tracking-wider" }, "Renderizar")
6235
6362
  ), /* @__PURE__ */ import_react10.default.createElement(
6236
6363
  "button",
6237
6364
  {
@@ -8797,7 +8924,7 @@ var getAllNodeIdsFromTree = (treeNode) => {
8797
8924
  traverse(treeNode);
8798
8925
  return Array.from(ids);
8799
8926
  };
8800
- var findNodePath2 = (tree, targetNodeId, currentPath = []) => {
8927
+ var findNodePath3 = (tree, targetNodeId, currentPath = []) => {
8801
8928
  var _a;
8802
8929
  if (!tree) return null;
8803
8930
  const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
@@ -8806,7 +8933,7 @@ var findNodePath2 = (tree, targetNodeId, currentPath = []) => {
8806
8933
  }
8807
8934
  if (tree.children) {
8808
8935
  for (let i = 0; i < tree.children.length; i++) {
8809
- const res = findNodePath2(tree.children[i], targetNodeId, [...currentPath, i]);
8936
+ const res = findNodePath3(tree.children[i], targetNodeId, [...currentPath, i]);
8810
8937
  if (res) return res;
8811
8938
  }
8812
8939
  }
@@ -10944,13 +11071,13 @@ function XViewScene({
10944
11071
  if (action === "open") {
10945
11072
  let currentPtr = fullTree;
10946
11073
  for (const step of branchStack) {
10947
- const found = findNodePath2(currentPtr, step.nodeId);
11074
+ const found = findNodePath3(currentPtr, step.nodeId);
10948
11075
  if (found && found.node.parallel_branches) {
10949
11076
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
10950
11077
  if (branch) currentPtr = branch.tree;
10951
11078
  }
10952
11079
  }
10953
- const foundTarget = findNodePath2(currentPtr, nodeId);
11080
+ const foundTarget = findNodePath3(currentPtr, nodeId);
10954
11081
  if (foundTarget && foundTarget.node && foundTarget.node.parallel_branches && foundTarget.node.parallel_branches.length > 0) {
10955
11082
  const branchToOpen = foundTarget.node.parallel_branches.find((b) => (b.direction || "right") === direction);
10956
11083
  if (!branchToOpen) return;
@@ -11017,7 +11144,7 @@ function XViewScene({
11017
11144
  if (newStack.length > 0) {
11018
11145
  let ptr = fullTree;
11019
11146
  for (const step of newStack) {
11020
- const found = findNodePath2(ptr, step.nodeId);
11147
+ const found = findNodePath3(ptr, step.nodeId);
11021
11148
  if (found && found.node.parallel_branches) {
11022
11149
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
11023
11150
  if (branch) {
@@ -11158,7 +11285,7 @@ function XViewScene({
11158
11285
  let currentMeta = ancestry;
11159
11286
  let currentDirection = null;
11160
11287
  for (const step of branchStack) {
11161
- const found = findNodePath2(currentPtr, step.nodeId);
11288
+ const found = findNodePath3(currentPtr, step.nodeId);
11162
11289
  if (found && found.node.parallel_branches) {
11163
11290
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
11164
11291
  if (branch) {
@@ -11218,7 +11345,7 @@ function XViewScene({
11218
11345
  );
11219
11346
  let currentPtr = fullTree;
11220
11347
  for (const step of branchStack) {
11221
- const found = findNodePath2(currentPtr, step.nodeId);
11348
+ const found = findNodePath3(currentPtr, step.nodeId);
11222
11349
  if (found && found.node && found.node.parallel_branches) {
11223
11350
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
11224
11351
  if (branch) {
@@ -11886,7 +12013,9 @@ function XViewScene({
11886
12013
  activeNodeBranches,
11887
12014
  backNavigationInfo,
11888
12015
  onImageClick: (url, name) => handleOpenImageViewer([{ name: name || "Imagem", value: url }], 0),
11889
- userRole: userPermissionRole
12016
+ userRole: userPermissionRole,
12017
+ abstractionTree: readingMode.ancestry.abstraction_tree,
12018
+ onRenderAbstractionTree: (targetId) => handleRenderAbstractionTree(readingMode.ancestry, targetId)
11890
12019
  }
11891
12020
  )
11892
12021
  ),
package/dist/index.mjs CHANGED
@@ -4431,8 +4431,69 @@ import {
4431
4431
  FiCornerUpLeft,
4432
4432
  FiCornerUpRight,
4433
4433
  FiList as FiList2,
4434
- FiAlignLeft
4434
+ FiAlignLeft,
4435
+ FiGitBranch,
4436
+ FiFolder
4435
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
+ };
4436
4497
  function DescriptionReadModePanel({
4437
4498
  title,
4438
4499
  description,
@@ -4454,14 +4515,40 @@ function DescriptionReadModePanel({
4454
4515
  backNavigationInfo,
4455
4516
  customProperties = [],
4456
4517
  onImageClick,
4457
- userRole
4458
- // <--- NOVA PROP: Recebendo a role do usuário
4518
+ userRole,
4519
+ // --- NOVAS PROPS PARA ABSTRAÇÃO ---
4520
+ abstractionTree = null,
4521
+ onRenderAbstractionTree = null
4459
4522
  }) {
4460
4523
  const [showProperties, setShowProperties] = useState7(false);
4524
+ const [showAbstraction, setShowAbstraction] = useState7(false);
4525
+ const [targetRenderNodeId, setTargetRenderNodeId] = useState7(null);
4461
4526
  const swallow = (e) => e.stopPropagation();
4462
4527
  const hasCustomProps = customProperties && customProperties.length > 0;
4528
+ const hasAbstraction = abstractionTree && abstractionTree.node;
4463
4529
  const ability = useMemo6(() => defineAbilityFor(userRole), [userRole]);
4464
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
+ };
4465
4552
  const leftAction = useMemo6(() => {
4466
4553
  if (activeNodeBranches == null ? void 0 : activeNodeBranches.left) {
4467
4554
  return {
@@ -4511,16 +4598,25 @@ function DescriptionReadModePanel({
4511
4598
  title: "Voltar"
4512
4599
  },
4513
4600
  /* @__PURE__ */ React7.createElement(FiArrowLeft, { size: 16 })
4514
- ), /* @__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(
4601
+ ), /* @__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(
4515
4602
  "button",
4516
4603
  {
4517
- onClick: () => setShowProperties(!showProperties),
4604
+ onClick: handleToggleProperties,
4518
4605
  className: `relative w-9 h-9 grid place-content-center rounded-lg border transition-colors
4519
4606
  ${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"}`,
4520
4607
  title: showProperties ? "Ver Descri\xE7\xE3o" : "Ver Propriedades Adicionais"
4521
4608
  },
4522
4609
  showProperties ? /* @__PURE__ */ React7.createElement(FiAlignLeft, { size: 16 }) : /* @__PURE__ */ React7.createElement(FiList2, { size: 16 }),
4523
- !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" })
4610
+ !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" })
4611
+ ), hasAbstraction && /* @__PURE__ */ React7.createElement(
4612
+ "button",
4613
+ {
4614
+ onClick: handleToggleAbstraction,
4615
+ className: `relative w-9 h-9 grid place-content-center rounded-lg border transition-colors
4616
+ ${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"}`,
4617
+ title: showAbstraction ? "Voltar \xE0 Descri\xE7\xE3o" : "Ver Tree de Abstra\xE7\xE3o"
4618
+ },
4619
+ /* @__PURE__ */ React7.createElement(FiGitBranch, { size: 16 })
4524
4620
  ), onRenderFullAncestry && /* @__PURE__ */ React7.createElement(
4525
4621
  "button",
4526
4622
  {
@@ -4534,7 +4630,7 @@ function DescriptionReadModePanel({
4534
4630
  {
4535
4631
  onClick: onEdit,
4536
4632
  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",
4537
- title: "Editar Descri\xE7\xE3o"
4633
+ title: "Editar Descri\xE7\xE3o / Estrutura"
4538
4634
  },
4539
4635
  /* @__PURE__ */ React7.createElement(FiEdit2, { size: 16 })
4540
4636
  ), /* @__PURE__ */ React7.createElement(
@@ -4546,7 +4642,40 @@ function DescriptionReadModePanel({
4546
4642
  },
4547
4643
  "\xD7"
4548
4644
  ))),
4549
- /* @__PURE__ */ React7.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10" }, 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(
4645
+ /* @__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(
4646
+ "button",
4647
+ {
4648
+ onClick: (e) => {
4649
+ e.stopPropagation();
4650
+ onRenderAbstractionTree(targetRenderNodeId);
4651
+ },
4652
+ 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",
4653
+ title: "Renderiza no 3D apenas o caminho at\xE9 o Node selecionado"
4654
+ },
4655
+ /* @__PURE__ */ React7.createElement(FiLayers3, { size: 14 }),
4656
+ " Renderizar Caminho"
4657
+ ), onRenderAbstractionTree && /* @__PURE__ */ React7.createElement(
4658
+ "button",
4659
+ {
4660
+ onClick: (e) => {
4661
+ e.stopPropagation();
4662
+ setTargetRenderNodeId(null);
4663
+ onRenderAbstractionTree(null);
4664
+ },
4665
+ 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",
4666
+ title: "Renderiza a Abstraction Tree inteira verticalmente"
4667
+ },
4668
+ /* @__PURE__ */ React7.createElement(FiLayers3, { size: 14 }),
4669
+ " Renderizar Completa"
4670
+ ))), /* @__PURE__ */ React7.createElement("div", { className: "bg-slate-900/60 border border-white/10 rounded-lg p-4" }, /* @__PURE__ */ React7.createElement(
4671
+ ReadOnlyNodeItem,
4672
+ {
4673
+ nodeData: abstractionTree,
4674
+ onViewSelect: setTargetRenderNodeId,
4675
+ highlightedPathIds,
4676
+ targetRenderNodeId
4677
+ }
4678
+ ))) : 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(
4550
4679
  CustomPropertyDisplay,
4551
4680
  {
4552
4681
  key: prop.id,
@@ -4575,7 +4704,7 @@ function DescriptionReadModePanel({
4575
4704
  onImageClick
4576
4705
  }
4577
4706
  )),
4578
- leftAction && /* @__PURE__ */ React7.createElement(
4707
+ leftAction && !showAbstraction && !showProperties && /* @__PURE__ */ React7.createElement(
4579
4708
  "button",
4580
4709
  {
4581
4710
  onClick: leftAction.onClick,
@@ -4587,7 +4716,7 @@ function DescriptionReadModePanel({
4587
4716
  ${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"}
4588
4717
  ` }, leftAction.type === "branch" ? /* @__PURE__ */ React7.createElement(FiChevronLeft, { size: 20 }) : /* @__PURE__ */ React7.createElement(FiCornerUpLeft, { size: 20 }))
4589
4718
  ),
4590
- rightAction && /* @__PURE__ */ React7.createElement(
4719
+ rightAction && !showAbstraction && !showProperties && /* @__PURE__ */ React7.createElement(
4591
4720
  "button",
4592
4721
  {
4593
4722
  onClick: rightAction.onClick,
@@ -4764,7 +4893,7 @@ import React10, { useState as useState10, useEffect as useEffect9, useMemo as us
4764
4893
  import {
4765
4894
  FiEdit2 as FiEdit23,
4766
4895
  FiBookOpen as FiBookOpen2,
4767
- FiFolder,
4896
+ FiFolder as FiFolder2,
4768
4897
  FiMousePointer,
4769
4898
  FiCheck as FiCheck4,
4770
4899
  FiLayers as FiLayers5,
@@ -4773,7 +4902,7 @@ import {
4773
4902
  FiChevronRight as FiChevronRight4,
4774
4903
  FiCornerUpLeft as FiCornerUpLeft2,
4775
4904
  FiCornerUpRight as FiCornerUpRight3,
4776
- FiGitBranch,
4905
+ FiGitBranch as FiGitBranch2,
4777
4906
  FiPlus as FiPlus2,
4778
4907
  FiLock
4779
4908
  } from "react-icons/fi";
@@ -4855,7 +4984,7 @@ function AncestryPickerModal({
4855
4984
  }
4856
4985
 
4857
4986
  // src/components/CreateAncestryPanel.jsx
4858
- var findNodePath = (tree, targetNodeId, currentPath = []) => {
4987
+ var findNodePath2 = (tree, targetNodeId, currentPath = []) => {
4859
4988
  var _a;
4860
4989
  if (!tree) return null;
4861
4990
  const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
@@ -4864,7 +4993,7 @@ var findNodePath = (tree, targetNodeId, currentPath = []) => {
4864
4993
  }
4865
4994
  if (tree.children) {
4866
4995
  for (let i = 0; i < tree.children.length; i++) {
4867
- const res = findNodePath(tree.children[i], targetNodeId, [...currentPath, i]);
4996
+ const res = findNodePath2(tree.children[i], targetNodeId, [...currentPath, i]);
4868
4997
  if (res) return res;
4869
4998
  }
4870
4999
  }
@@ -4950,7 +5079,7 @@ var NodeItem = ({ nodeData, onSelectParent, onViewSelect, highlightedPathIds = [
4950
5079
  ${isDragOver ? "border-dashed border-yellow-400 bg-yellow-400/10" : "border-transparent"}
4951
5080
  ${itemBgClass} ${cursorClass}`
4952
5081
  },
4953
- /* @__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(FiFolder, { className: "mr-2" }), itemName),
5082
+ /* @__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),
4954
5083
  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) => {
4955
5084
  e.stopPropagation();
4956
5085
  onEditRelationship(path, nodeData.relationship || {});
@@ -5019,7 +5148,7 @@ function CreateAncestryPanel({
5019
5148
  const highlightedPathIds = useMemo8(() => {
5020
5149
  var _a, _b;
5021
5150
  if (!targetRenderNodeId || !ancestryMode.abstraction_tree) return [];
5022
- const found = findNodePath(ancestryMode.abstraction_tree, targetRenderNodeId);
5151
+ const found = findNodePath2(ancestryMode.abstraction_tree, targetRenderNodeId);
5023
5152
  if (!found) return [];
5024
5153
  let current = ancestryMode.abstraction_tree;
5025
5154
  const ids = [current.is_section ? current.section_id : String((_a = current.node) == null ? void 0 : _a.id)];
@@ -5086,7 +5215,7 @@ function CreateAncestryPanel({
5086
5215
  if (!isAbstraction && branchStack.length > 0) {
5087
5216
  let ptr = rootTreeClone;
5088
5217
  for (const step of branchStack) {
5089
- const found = findNodePath(ptr, step.nodeId);
5218
+ const found = findNodePath2(ptr, step.nodeId);
5090
5219
  if (found && found.node.parallel_branches) {
5091
5220
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5092
5221
  if (branch) ptr = branch.tree;
@@ -5163,7 +5292,7 @@ function CreateAncestryPanel({
5163
5292
  let currentBranch = null;
5164
5293
  let currentDirection = null;
5165
5294
  for (const step of branchStack) {
5166
- const found = findNodePath(currentTreePtr, step.nodeId);
5295
+ const found = findNodePath2(currentTreePtr, step.nodeId);
5167
5296
  if (!found || !found.node.parallel_branches) return null;
5168
5297
  currentBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5169
5298
  if (!currentBranch) return null;
@@ -5245,7 +5374,7 @@ function CreateAncestryPanel({
5245
5374
  let ptr = ancestryMode.tree;
5246
5375
  let foundBranch = null;
5247
5376
  for (const step of branchStack) {
5248
- const found = findNodePath(ptr, step.nodeId);
5377
+ const found = findNodePath2(ptr, step.nodeId);
5249
5378
  if (found && found.node.parallel_branches) {
5250
5379
  foundBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5251
5380
  if (foundBranch) ptr = foundBranch.tree;
@@ -5304,7 +5433,7 @@ function CreateAncestryPanel({
5304
5433
  let ptr = rootTreeClone;
5305
5434
  let targetBranch = null;
5306
5435
  for (const step of branchStack) {
5307
- const found = findNodePath(ptr, step.nodeId);
5436
+ const found = findNodePath2(ptr, step.nodeId);
5308
5437
  if (found && found.node.parallel_branches) {
5309
5438
  targetBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5310
5439
  if (targetBranch) ptr = targetBranch.tree;
@@ -5362,14 +5491,14 @@ function CreateAncestryPanel({
5362
5491
  let ptr = rootTreeClone;
5363
5492
  for (let i = 0; i < branchStack.length - 1; i++) {
5364
5493
  const step = branchStack[i];
5365
- const found = findNodePath(ptr, step.nodeId);
5494
+ const found = findNodePath2(ptr, step.nodeId);
5366
5495
  if (found && found.node.parallel_branches) {
5367
5496
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5368
5497
  if (branch) ptr = branch.tree;
5369
5498
  }
5370
5499
  }
5371
5500
  const currentStep = branchStack[branchStack.length - 1];
5372
- const foundParentPath = findNodePath(ptr, currentStep.nodeId);
5501
+ const foundParentPath = findNodePath2(ptr, currentStep.nodeId);
5373
5502
  if (foundParentPath && foundParentPath.node && foundParentPath.node.parallel_branches) {
5374
5503
  const branchIndex = foundParentPath.node.parallel_branches.findIndex((b) => b.id === currentStep.branchId);
5375
5504
  if (branchIndex !== -1) {
@@ -5413,7 +5542,7 @@ function CreateAncestryPanel({
5413
5542
  const actions = { left: null, right: null };
5414
5543
  const isInBranch = branchStack.length > 0;
5415
5544
  if (internalHighlightedNodeId) {
5416
- const found = findNodePath(activeTree, internalHighlightedNodeId);
5545
+ const found = findNodePath2(activeTree, internalHighlightedNodeId);
5417
5546
  if (found && found.node) {
5418
5547
  const branches = found.node.parallel_branches || [];
5419
5548
  const leftBranch = branches.find((b) => (b.direction || "right") === "left");
@@ -5465,7 +5594,7 @@ function CreateAncestryPanel({
5465
5594
  if (branchStack.length > 0) {
5466
5595
  let ptr = rootTreeClone;
5467
5596
  for (const step of branchStack) {
5468
- const found = findNodePath(ptr, step.nodeId);
5597
+ const found = findNodePath2(ptr, step.nodeId);
5469
5598
  if (found && found.node.parallel_branches) {
5470
5599
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5471
5600
  if (branch) ptr = branch.tree;
@@ -5611,7 +5740,7 @@ function CreateAncestryPanel({
5611
5740
  let parentTreePtr = rootTree;
5612
5741
  let parentBranch = null;
5613
5742
  for (const step of parentStack) {
5614
- const found = findNodePath(parentTreePtr, step.nodeId);
5743
+ const found = findNodePath2(parentTreePtr, step.nodeId);
5615
5744
  if (found && found.node.parallel_branches) {
5616
5745
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5617
5746
  if (branch) {
@@ -5689,7 +5818,7 @@ function CreateAncestryPanel({
5689
5818
  const rootTreeClone = JSON.parse(JSON.stringify(ancestryMode.tree));
5690
5819
  let ptr = rootTreeClone;
5691
5820
  for (const step of branchStack) {
5692
- const foundParent = findNodePath(ptr, step.nodeId);
5821
+ const foundParent = findNodePath2(ptr, step.nodeId);
5693
5822
  if (foundParent && foundParent.node && foundParent.node.parallel_branches) {
5694
5823
  const existingBranch = foundParent.node.parallel_branches.find((b) => b.id === step.branchId);
5695
5824
  if (existingBranch) {
@@ -5697,7 +5826,7 @@ function CreateAncestryPanel({
5697
5826
  }
5698
5827
  }
5699
5828
  }
5700
- const found = findNodePath(ptr, nodeId);
5829
+ const found = findNodePath2(ptr, nodeId);
5701
5830
  if (!found) {
5702
5831
  console.error("Node alvo n\xE3o encontrado no contexto atual.");
5703
5832
  return;
@@ -5810,7 +5939,7 @@ function CreateAncestryPanel({
5810
5939
  let ptr = updatedRootTree;
5811
5940
  let targetBranch = null;
5812
5941
  for (const step of branchStack) {
5813
- const found = findNodePath(ptr, step.nodeId);
5942
+ const found = findNodePath2(ptr, step.nodeId);
5814
5943
  if (found && found.node.parallel_branches) {
5815
5944
  targetBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5816
5945
  if (targetBranch) ptr = targetBranch.tree;
@@ -6159,7 +6288,7 @@ function CreateAncestryPanel({
6159
6288
  unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type),
6160
6289
  onUploadFile
6161
6290
  }
6162
- )), /* @__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"}` }, "Estrutura ", 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(
6291
+ )), /* @__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(
6163
6292
  "button",
6164
6293
  {
6165
6294
  type: "button",
@@ -6196,7 +6325,7 @@ function CreateAncestryPanel({
6196
6325
  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"}`,
6197
6326
  onClick: () => setTargetRenderNodeId(null)
6198
6327
  },
6199
- /* @__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"}` }, "Estrutura 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(
6328
+ /* @__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(
6200
6329
  "button",
6201
6330
  {
6202
6331
  type: "button",
@@ -6212,7 +6341,7 @@ function CreateAncestryPanel({
6212
6341
  title: "Renderizar cen\xE1rio at\xE9 o caminho selecionado"
6213
6342
  },
6214
6343
  /* @__PURE__ */ React10.createElement(FiLayers5, { size: 13 }),
6215
- /* @__PURE__ */ React10.createElement("span", { className: "text-[10px] font-bold uppercase tracking-wider" }, "Caminho")
6344
+ /* @__PURE__ */ React10.createElement("span", { className: "text-[10px] font-bold uppercase tracking-wider" }, "Renderizar")
6216
6345
  ), /* @__PURE__ */ React10.createElement(
6217
6346
  "button",
6218
6347
  {
@@ -8791,7 +8920,7 @@ var getAllNodeIdsFromTree = (treeNode) => {
8791
8920
  traverse(treeNode);
8792
8921
  return Array.from(ids);
8793
8922
  };
8794
- var findNodePath2 = (tree, targetNodeId, currentPath = []) => {
8923
+ var findNodePath3 = (tree, targetNodeId, currentPath = []) => {
8795
8924
  var _a;
8796
8925
  if (!tree) return null;
8797
8926
  const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
@@ -8800,7 +8929,7 @@ var findNodePath2 = (tree, targetNodeId, currentPath = []) => {
8800
8929
  }
8801
8930
  if (tree.children) {
8802
8931
  for (let i = 0; i < tree.children.length; i++) {
8803
- const res = findNodePath2(tree.children[i], targetNodeId, [...currentPath, i]);
8932
+ const res = findNodePath3(tree.children[i], targetNodeId, [...currentPath, i]);
8804
8933
  if (res) return res;
8805
8934
  }
8806
8935
  }
@@ -10938,13 +11067,13 @@ function XViewScene({
10938
11067
  if (action === "open") {
10939
11068
  let currentPtr = fullTree;
10940
11069
  for (const step of branchStack) {
10941
- const found = findNodePath2(currentPtr, step.nodeId);
11070
+ const found = findNodePath3(currentPtr, step.nodeId);
10942
11071
  if (found && found.node.parallel_branches) {
10943
11072
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
10944
11073
  if (branch) currentPtr = branch.tree;
10945
11074
  }
10946
11075
  }
10947
- const foundTarget = findNodePath2(currentPtr, nodeId);
11076
+ const foundTarget = findNodePath3(currentPtr, nodeId);
10948
11077
  if (foundTarget && foundTarget.node && foundTarget.node.parallel_branches && foundTarget.node.parallel_branches.length > 0) {
10949
11078
  const branchToOpen = foundTarget.node.parallel_branches.find((b) => (b.direction || "right") === direction);
10950
11079
  if (!branchToOpen) return;
@@ -11011,7 +11140,7 @@ function XViewScene({
11011
11140
  if (newStack.length > 0) {
11012
11141
  let ptr = fullTree;
11013
11142
  for (const step of newStack) {
11014
- const found = findNodePath2(ptr, step.nodeId);
11143
+ const found = findNodePath3(ptr, step.nodeId);
11015
11144
  if (found && found.node.parallel_branches) {
11016
11145
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
11017
11146
  if (branch) {
@@ -11152,7 +11281,7 @@ function XViewScene({
11152
11281
  let currentMeta = ancestry;
11153
11282
  let currentDirection = null;
11154
11283
  for (const step of branchStack) {
11155
- const found = findNodePath2(currentPtr, step.nodeId);
11284
+ const found = findNodePath3(currentPtr, step.nodeId);
11156
11285
  if (found && found.node.parallel_branches) {
11157
11286
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
11158
11287
  if (branch) {
@@ -11212,7 +11341,7 @@ function XViewScene({
11212
11341
  );
11213
11342
  let currentPtr = fullTree;
11214
11343
  for (const step of branchStack) {
11215
- const found = findNodePath2(currentPtr, step.nodeId);
11344
+ const found = findNodePath3(currentPtr, step.nodeId);
11216
11345
  if (found && found.node && found.node.parallel_branches) {
11217
11346
  const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
11218
11347
  if (branch) {
@@ -11880,7 +12009,9 @@ function XViewScene({
11880
12009
  activeNodeBranches,
11881
12010
  backNavigationInfo,
11882
12011
  onImageClick: (url, name) => handleOpenImageViewer([{ name: name || "Imagem", value: url }], 0),
11883
- userRole: userPermissionRole
12012
+ userRole: userPermissionRole,
12013
+ abstractionTree: readingMode.ancestry.abstraction_tree,
12014
+ onRenderAbstractionTree: (targetId) => handleRenderAbstractionTree(readingMode.ancestry, targetId)
11884
12015
  }
11885
12016
  )
11886
12017
  ),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lv-x-software-house/x_view",
3
- "version": "1.1.9-dev.6",
3
+ "version": "1.1.9-dev.7",
4
4
  "description": "Pacote privado contendo os componentes e lógica de renderização 3D do X View.",
5
5
  "author": "iv.x - Engenharia de Software - ivxsoftwarehouse@gmail.com",
6
6
  "license": "UNLICENSED",