@lv-x-software-house/x_view 1.2.2-dev.23 → 1.2.2-dev.26

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 CHANGED
@@ -4368,8 +4368,7 @@ var CodeBlock2 = ({ content, isActive, onClick }) => {
4368
4368
  "button",
4369
4369
  {
4370
4370
  onClick: handleCopy,
4371
- className: "flex items-center gap-1.5 px-2 py-1 rounded hover:bg-white/10 transition-colors text-xs text-slate-400 hover:text-white",
4372
- title: "Copiar c\xF3digo"
4371
+ className: "flex items-center gap-1.5 px-2 py-1 rounded hover:bg-white/10 transition-colors text-xs text-slate-400 hover:text-white"
4373
4372
  },
4374
4373
  copied ? /* @__PURE__ */ import_react7.default.createElement(import_fi5.FiCheck, { size: 12, className: "text-emerald-400" }) : /* @__PURE__ */ import_react7.default.createElement(import_fi5.FiCopy, { size: 12 }),
4375
4374
  copied ? /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-emerald-400" }, "Copiado") : /* @__PURE__ */ import_react7.default.createElement("span", null, "Copiar")
@@ -4398,8 +4397,7 @@ var renderLinks = (text) => {
4398
4397
  target: "_blank",
4399
4398
  rel: "noopener noreferrer",
4400
4399
  className: "inline-flex items-center gap-0.5 text-cyan-400 hover:text-cyan-300 hover:underline decoration-cyan-500/50 underline-offset-2 transition-colors cursor-pointer",
4401
- onClick: (e) => e.stopPropagation(),
4402
- title: `Abrir link externo: ${url}`
4400
+ onClick: (e) => e.stopPropagation()
4403
4401
  },
4404
4402
  part,
4405
4403
  /* @__PURE__ */ import_react7.default.createElement(import_fi5.FiExternalLink, { size: 10, className: "opacity-70 mb-0.5" })
@@ -4428,8 +4426,7 @@ var renderTextWithImages = (text, onImageClick) => {
4428
4426
  e.stopPropagation();
4429
4427
  onImageClick == null ? void 0 : onImageClick(url, name);
4430
4428
  },
4431
- className: "inline-flex items-center gap-1 text-emerald-400 hover:text-emerald-300 hover:underline decoration-emerald-500/50 underline-offset-2 transition-colors cursor-pointer align-baseline mx-0.5",
4432
- title: `Ver imagem: ${name}`
4429
+ className: "inline-flex items-center gap-1 text-emerald-400 hover:text-emerald-300 hover:underline decoration-emerald-500/50 underline-offset-2 transition-colors cursor-pointer align-baseline mx-0.5"
4433
4430
  },
4434
4431
  /* @__PURE__ */ import_react7.default.createElement(import_fi5.FiImage, { size: 11 }),
4435
4432
  /* @__PURE__ */ import_react7.default.createElement("span", null, name)
@@ -4466,8 +4463,7 @@ var renderTextWithMentions = (text, availableNodes, onMentionClick, activeMentio
4466
4463
  className: `
4467
4464
  inline-flex items-center gap-0.5 align-baseline font-medium px-1.5 rounded-md mx-0.5 select-none transition-all cursor-pointer text-[0.95em]
4468
4465
  ${isMentionActive ? "text-white bg-indigo-500 ring-2 ring-yellow-400 shadow-[0_0_10px_rgba(250,204,21,0.5)] z-10 relative" : "text-indigo-200 bg-indigo-600/30 border border-indigo-500/30 hover:bg-indigo-600/50 hover:text-white"}
4469
- `,
4470
- title: `Clique para focar no Node: ${displayName}`
4466
+ `
4471
4467
  },
4472
4468
  /* @__PURE__ */ import_react7.default.createElement("span", { className: "opacity-60 text-[0.8em]" }, "@"),
4473
4469
  displayName
@@ -4541,7 +4537,9 @@ function DescriptionDisplay({
4541
4537
  onHighlightNode,
4542
4538
  initialSectionId,
4543
4539
  currentBranchDirection = null,
4544
- onSaveDescription
4540
+ onSaveDescription,
4541
+ onStepChange
4542
+ // 1. Adicione a nova prop aqui
4545
4543
  }) {
4546
4544
  const [localDescription, setLocalDescription] = (0, import_react7.useState)(description || "");
4547
4545
  (0, import_react7.useEffect)(() => {
@@ -4588,6 +4586,11 @@ function DescriptionDisplay({
4588
4586
  return navItems;
4589
4587
  }, [sections]);
4590
4588
  const [currentStepIndex, setCurrentStepIndex] = (0, import_react7.useState)(0);
4589
+ (0, import_react7.useEffect)(() => {
4590
+ if (onStepChange) {
4591
+ onStepChange(currentStepIndex);
4592
+ }
4593
+ }, [currentStepIndex, onStepChange]);
4591
4594
  const activeRef = (0, import_react7.useRef)(null);
4592
4595
  const lastNotifiedSectionId = (0, import_react7.useRef)(null);
4593
4596
  const isInitialMount = (0, import_react7.useRef)(true);
@@ -4739,8 +4742,7 @@ function DescriptionDisplay({
4739
4742
  if (onOpenReference) {
4740
4743
  onOpenReference({ type: resolved.type, id: resolved.sourceId });
4741
4744
  }
4742
- },
4743
- title: `Ir para ${resolved.type === "node" ? "Node" : "Ancestralidade"}: ${resolved.sourceName}`
4745
+ }
4744
4746
  },
4745
4747
  /* @__PURE__ */ import_react7.default.createElement(import_fi5.FiCornerDownRight, { size: 12, className: "text-indigo-400" }),
4746
4748
  /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-wide flex items-center gap-1" }, "Importado de ", /* @__PURE__ */ import_react7.default.createElement("span", { className: "font-semibold text-indigo-300 hover:underline" }, resolved.sourceName), /* @__PURE__ */ import_react7.default.createElement(import_fi5.FiExternalLink, { size: 10, className: "text-slate-600" }))
@@ -4875,6 +4877,7 @@ function DescriptionReadModePanel({
4875
4877
  const [showAbstraction, setShowAbstraction] = (0, import_react8.useState)(false);
4876
4878
  const [targetRenderNodeId, setTargetRenderNodeId] = (0, import_react8.useState)(null);
4877
4879
  const [isLinkCopied, setIsLinkCopied] = (0, import_react8.useState)(false);
4880
+ const [isAtStartOfBranch, setIsAtStartOfBranch] = (0, import_react8.useState)(true);
4878
4881
  const handleCopyLink = (e) => {
4879
4882
  e.stopPropagation();
4880
4883
  if (!ancestryId) return;
@@ -4927,7 +4930,7 @@ function DescriptionReadModePanel({
4927
4930
  onClick: () => onBranchNav(activeNodeBranches.nodeId, "open", "left")
4928
4931
  };
4929
4932
  }
4930
- if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "left") {
4933
+ if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "left" && isAtStartOfBranch) {
4931
4934
  return {
4932
4935
  type: "back",
4933
4936
  name: backNavigationInfo.name,
@@ -4935,7 +4938,7 @@ function DescriptionReadModePanel({
4935
4938
  };
4936
4939
  }
4937
4940
  return null;
4938
- }, [activeNodeBranches, backNavigationInfo, onBranchNav]);
4941
+ }, [activeNodeBranches, backNavigationInfo, onBranchNav, isAtStartOfBranch]);
4939
4942
  const rightAction = (0, import_react8.useMemo)(() => {
4940
4943
  if (activeNodeBranches == null ? void 0 : activeNodeBranches.right) {
4941
4944
  return {
@@ -4944,7 +4947,7 @@ function DescriptionReadModePanel({
4944
4947
  onClick: () => onBranchNav(activeNodeBranches.nodeId, "open", "right")
4945
4948
  };
4946
4949
  }
4947
- if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "right") {
4950
+ if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "right" && isAtStartOfBranch) {
4948
4951
  return {
4949
4952
  type: "back",
4950
4953
  name: backNavigationInfo.name,
@@ -4952,7 +4955,7 @@ function DescriptionReadModePanel({
4952
4955
  };
4953
4956
  }
4954
4957
  return null;
4955
- }, [activeNodeBranches, backNavigationInfo, onBranchNav]);
4958
+ }, [activeNodeBranches, backNavigationInfo, onBranchNav, isAtStartOfBranch]);
4956
4959
  return /* @__PURE__ */ import_react8.default.createElement(
4957
4960
  "div",
4958
4961
  {
@@ -5088,7 +5091,8 @@ function DescriptionReadModePanel({
5088
5091
  initialSectionId,
5089
5092
  currentBranchDirection,
5090
5093
  onImageClick,
5091
- onSaveDescription
5094
+ onSaveDescription,
5095
+ onStepChange: (stepIndex) => setIsAtStartOfBranch(stepIndex === 0)
5092
5096
  }
5093
5097
  )),
5094
5098
  leftAction && !showAbstraction && !showProperties && /* @__PURE__ */ import_react8.default.createElement(
@@ -5559,6 +5563,7 @@ function CreateAncestryPanel({
5559
5563
  }, [targetRenderNodeId, ancestryMode.abstraction_tree]);
5560
5564
  const [targetScrollSectionId, setTargetScrollSectionId] = (0, import_react11.useState)(null);
5561
5565
  const [internalHighlightedNodeId, setInternalHighlightedNodeId] = (0, import_react11.useState)(null);
5566
+ const [isAtStartOfBranch, setIsAtStartOfBranch] = (0, import_react11.useState)(true);
5562
5567
  const [ancestryName, setAncestryName] = (0, import_react11.useState)(initialName);
5563
5568
  const [description, setDescription] = (0, import_react11.useState)(initialDescription || "");
5564
5569
  const [existingSections, setExistingSections] = (0, import_react11.useState)(initialSections || []);
@@ -5952,6 +5957,62 @@ function CreateAncestryPanel({
5952
5957
  }
5953
5958
  }
5954
5959
  };
5960
+ const handleDeleteBranch = async () => {
5961
+ if (branchStack.length === 0) return;
5962
+ const confirmDelete = window.confirm("Tem certeza que deseja excluir esta ramifica\xE7\xE3o e todo o seu conte\xFAdo interno?");
5963
+ if (!confirmDelete) return;
5964
+ const rootTreeClone = JSON.parse(JSON.stringify(ancestryMode.tree));
5965
+ let ptr = rootTreeClone;
5966
+ for (let i = 0; i < branchStack.length - 1; i++) {
5967
+ const step = branchStack[i];
5968
+ const found = findNodePath2(ptr, step.nodeId);
5969
+ if (found && found.node.parallel_branches) {
5970
+ const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5971
+ if (branch) ptr = branch.tree;
5972
+ }
5973
+ }
5974
+ const currentStep = branchStack[branchStack.length - 1];
5975
+ const foundParentPath = findNodePath2(ptr, currentStep.nodeId);
5976
+ if (foundParentPath && foundParentPath.node && foundParentPath.node.parallel_branches) {
5977
+ const branchIndex = foundParentPath.node.parallel_branches.findIndex((b) => b.id === currentStep.branchId);
5978
+ if (branchIndex !== -1) {
5979
+ foundParentPath.node.parallel_branches.splice(branchIndex, 1);
5980
+ updateGlobalTree(rootTreeClone);
5981
+ try {
5982
+ setIsSaving(true);
5983
+ const currentRootProps = extractCustomPropsFromNode(ancestryMode);
5984
+ const rootExtras = toObjectFromCustomProps(currentRootProps);
5985
+ await onSave(
5986
+ ancestryMode.ancestryName,
5987
+ ancestryMode.ancestryDescription,
5988
+ ancestryMode.ancestryDescriptionSections,
5989
+ true,
5990
+ // keepOpen
5991
+ rootTreeClone,
5992
+ rootExtras
5993
+ );
5994
+ setLastSavedSnapshot(takeSnapshot(
5995
+ rootTreeClone,
5996
+ ancestryMode.ancestryName,
5997
+ ancestryMode.ancestryDescription,
5998
+ ancestryMode.ancestryDescriptionSections,
5999
+ currentRootProps,
6000
+ isPrivate,
6001
+ ancestryMode.abstraction_tree
6002
+ ));
6003
+ if (onClearAncestryVisuals) {
6004
+ onClearAncestryVisuals(currentStep.branchId);
6005
+ }
6006
+ handleNavigateUp();
6007
+ } catch (err) {
6008
+ console.error("Erro ao remover a ramifica\xE7\xE3o:", err);
6009
+ alert("Erro ao remover a ramifica\xE7\xE3o.");
6010
+ } finally {
6011
+ setIsSaving(false);
6012
+ }
6013
+ }
6014
+ }
6015
+ };
5955
6016
  const sideActions = (0, import_react11.useMemo)(() => {
5956
6017
  const actions = { left: null, right: null };
5957
6018
  const isInBranch = branchStack.length > 0;
@@ -5990,7 +6051,7 @@ function CreateAncestryPanel({
5990
6051
  }
5991
6052
  return actions;
5992
6053
  }
5993
- if (isInBranch) {
6054
+ if (isInBranch && isAtStartOfBranch) {
5994
6055
  const lastStep = branchStack[branchStack.length - 1];
5995
6056
  const entryDir = lastStep.entryDirection || "right";
5996
6057
  const backSide = entryDir === "right" ? "left" : "right";
@@ -6001,7 +6062,7 @@ function CreateAncestryPanel({
6001
6062
  };
6002
6063
  }
6003
6064
  return actions;
6004
- }, [internalHighlightedNodeId, branchStack, activeTree]);
6065
+ }, [internalHighlightedNodeId, branchStack, activeTree, isAtStartOfBranch]);
6005
6066
  const applyDescriptionToTree = (baseTree, descText, descSections) => {
6006
6067
  const rootTreeClone = JSON.parse(JSON.stringify(baseTree));
6007
6068
  let targetTree = rootTreeClone;
@@ -6614,7 +6675,7 @@ function CreateAncestryPanel({
6614
6675
  placeholder: "Nome da Ancestralidade",
6615
6676
  className: "text-xl sm:text-2xl font-semibold tracking-tight bg-transparent border-none p-0 focus:ring-2 focus:ring-indigo-500 rounded-md -ml-1.5 px-1.5 w-full outline-none transition-all focus:bg-slate-800/70"
6616
6677
  }
6617
- )), /* @__PURE__ */ import_react11.default.createElement("button", { onClick: onClose, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl flex-shrink-0", title: "Cancelar" }, "\xD7")), branchStack.length > 0 && /* @__PURE__ */ import_react11.default.createElement("div", { className: "px-6 pb-2" }, /* @__PURE__ */ import_react11.default.createElement(
6678
+ )), /* @__PURE__ */ import_react11.default.createElement("button", { onClick: onClose, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl flex-shrink-0", title: "Cancelar" }, "\xD7")), branchStack.length > 0 && /* @__PURE__ */ import_react11.default.createElement("div", { className: "px-6 pb-2 flex items-center justify-between" }, /* @__PURE__ */ import_react11.default.createElement(
6618
6679
  "button",
6619
6680
  {
6620
6681
  onClick: handleNavigateUp,
@@ -6622,6 +6683,15 @@ function CreateAncestryPanel({
6622
6683
  },
6623
6684
  /* @__PURE__ */ import_react11.default.createElement(import_fi9.FiArrowLeft, null),
6624
6685
  " Voltar para Principal / N\xEDvel Anterior"
6686
+ ), !isContextLinked && /* @__PURE__ */ import_react11.default.createElement(
6687
+ "button",
6688
+ {
6689
+ onClick: handleDeleteBranch,
6690
+ className: "flex items-center gap-1.5 text-xs text-rose-400 hover:text-white hover:bg-rose-500/20 px-2 py-1 rounded transition-colors",
6691
+ title: "Excluir permanentemente esta ramifica\xE7\xE3o e seu conte\xFAdo"
6692
+ },
6693
+ /* @__PURE__ */ import_react11.default.createElement(import_fi9.FiTrash2, null),
6694
+ " Excluir Ramifica\xE7\xE3o"
6625
6695
  )), /* @__PURE__ */ import_react11.default.createElement("div", { className: "px-6 pb-4 pt-2 overflow-y-auto flex-grow custom-scrollbar" }, branchStack.length > 0 && /* @__PURE__ */ import_react11.default.createElement("div", { className: "mb-4" }, isContextLinked ? /* @__PURE__ */ import_react11.default.createElement("div", { className: "p-3 rounded-lg bg-indigo-500/10 border border-indigo-500/30 flex items-center justify-between" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "w-8 h-8 rounded bg-indigo-500/20 text-indigo-300 grid place-content-center" }, /* @__PURE__ */ import_react11.default.createElement(import_fi9.FiLayers, null)), /* @__PURE__ */ import_react11.default.createElement("div", null, /* @__PURE__ */ import_react11.default.createElement("div", { className: "text-xs text-indigo-200 font-semibold uppercase tracking-wider" }, "Ancestralidade Vinculada"), /* @__PURE__ */ import_react11.default.createElement("div", { className: "text-sm text-white font-medium truncate max-w-[200px]" }, currentContext.name.replace("[REF] ", "")))), /* @__PURE__ */ import_react11.default.createElement(
6626
6696
  "button",
6627
6697
  {
@@ -6653,7 +6723,8 @@ function CreateAncestryPanel({
6653
6723
  initialSectionId: targetScrollSectionId,
6654
6724
  currentBranchDirection: currentContext ? currentContext.direction : null,
6655
6725
  onImageClick: handleImageClickFromText,
6656
- onSaveDescription: handleSaveDescriptionInline
6726
+ onSaveDescription: handleSaveDescriptionInline,
6727
+ onStepChange: (stepIndex) => setIsAtStartOfBranch(stepIndex === 0)
6657
6728
  }
6658
6729
  ), /* @__PURE__ */ import_react11.default.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5 z-30" }, /* @__PURE__ */ import_react11.default.createElement(
6659
6730
  "button",
package/dist/index.mjs CHANGED
@@ -4324,8 +4324,7 @@ var CodeBlock2 = ({ content, isActive, onClick }) => {
4324
4324
  "button",
4325
4325
  {
4326
4326
  onClick: handleCopy,
4327
- className: "flex items-center gap-1.5 px-2 py-1 rounded hover:bg-white/10 transition-colors text-xs text-slate-400 hover:text-white",
4328
- title: "Copiar c\xF3digo"
4327
+ className: "flex items-center gap-1.5 px-2 py-1 rounded hover:bg-white/10 transition-colors text-xs text-slate-400 hover:text-white"
4329
4328
  },
4330
4329
  copied ? /* @__PURE__ */ React6.createElement(FiCheck3, { size: 12, className: "text-emerald-400" }) : /* @__PURE__ */ React6.createElement(FiCopy2, { size: 12 }),
4331
4330
  copied ? /* @__PURE__ */ React6.createElement("span", { className: "text-emerald-400" }, "Copiado") : /* @__PURE__ */ React6.createElement("span", null, "Copiar")
@@ -4354,8 +4353,7 @@ var renderLinks = (text) => {
4354
4353
  target: "_blank",
4355
4354
  rel: "noopener noreferrer",
4356
4355
  className: "inline-flex items-center gap-0.5 text-cyan-400 hover:text-cyan-300 hover:underline decoration-cyan-500/50 underline-offset-2 transition-colors cursor-pointer",
4357
- onClick: (e) => e.stopPropagation(),
4358
- title: `Abrir link externo: ${url}`
4356
+ onClick: (e) => e.stopPropagation()
4359
4357
  },
4360
4358
  part,
4361
4359
  /* @__PURE__ */ React6.createElement(FiExternalLink2, { size: 10, className: "opacity-70 mb-0.5" })
@@ -4384,8 +4382,7 @@ var renderTextWithImages = (text, onImageClick) => {
4384
4382
  e.stopPropagation();
4385
4383
  onImageClick == null ? void 0 : onImageClick(url, name);
4386
4384
  },
4387
- className: "inline-flex items-center gap-1 text-emerald-400 hover:text-emerald-300 hover:underline decoration-emerald-500/50 underline-offset-2 transition-colors cursor-pointer align-baseline mx-0.5",
4388
- title: `Ver imagem: ${name}`
4385
+ className: "inline-flex items-center gap-1 text-emerald-400 hover:text-emerald-300 hover:underline decoration-emerald-500/50 underline-offset-2 transition-colors cursor-pointer align-baseline mx-0.5"
4389
4386
  },
4390
4387
  /* @__PURE__ */ React6.createElement(FiImage2, { size: 11 }),
4391
4388
  /* @__PURE__ */ React6.createElement("span", null, name)
@@ -4422,8 +4419,7 @@ var renderTextWithMentions = (text, availableNodes, onMentionClick, activeMentio
4422
4419
  className: `
4423
4420
  inline-flex items-center gap-0.5 align-baseline font-medium px-1.5 rounded-md mx-0.5 select-none transition-all cursor-pointer text-[0.95em]
4424
4421
  ${isMentionActive ? "text-white bg-indigo-500 ring-2 ring-yellow-400 shadow-[0_0_10px_rgba(250,204,21,0.5)] z-10 relative" : "text-indigo-200 bg-indigo-600/30 border border-indigo-500/30 hover:bg-indigo-600/50 hover:text-white"}
4425
- `,
4426
- title: `Clique para focar no Node: ${displayName}`
4422
+ `
4427
4423
  },
4428
4424
  /* @__PURE__ */ React6.createElement("span", { className: "opacity-60 text-[0.8em]" }, "@"),
4429
4425
  displayName
@@ -4497,7 +4493,9 @@ function DescriptionDisplay({
4497
4493
  onHighlightNode,
4498
4494
  initialSectionId,
4499
4495
  currentBranchDirection = null,
4500
- onSaveDescription
4496
+ onSaveDescription,
4497
+ onStepChange
4498
+ // 1. Adicione a nova prop aqui
4501
4499
  }) {
4502
4500
  const [localDescription, setLocalDescription] = useState7(description || "");
4503
4501
  useEffect6(() => {
@@ -4544,6 +4542,11 @@ function DescriptionDisplay({
4544
4542
  return navItems;
4545
4543
  }, [sections]);
4546
4544
  const [currentStepIndex, setCurrentStepIndex] = useState7(0);
4545
+ useEffect6(() => {
4546
+ if (onStepChange) {
4547
+ onStepChange(currentStepIndex);
4548
+ }
4549
+ }, [currentStepIndex, onStepChange]);
4547
4550
  const activeRef = useRef6(null);
4548
4551
  const lastNotifiedSectionId = useRef6(null);
4549
4552
  const isInitialMount = useRef6(true);
@@ -4695,8 +4698,7 @@ function DescriptionDisplay({
4695
4698
  if (onOpenReference) {
4696
4699
  onOpenReference({ type: resolved.type, id: resolved.sourceId });
4697
4700
  }
4698
- },
4699
- title: `Ir para ${resolved.type === "node" ? "Node" : "Ancestralidade"}: ${resolved.sourceName}`
4701
+ }
4700
4702
  },
4701
4703
  /* @__PURE__ */ React6.createElement(FiCornerDownRight, { size: 12, className: "text-indigo-400" }),
4702
4704
  /* @__PURE__ */ React6.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-wide flex items-center gap-1" }, "Importado de ", /* @__PURE__ */ React6.createElement("span", { className: "font-semibold text-indigo-300 hover:underline" }, resolved.sourceName), /* @__PURE__ */ React6.createElement(FiExternalLink2, { size: 10, className: "text-slate-600" }))
@@ -4845,6 +4847,7 @@ function DescriptionReadModePanel({
4845
4847
  const [showAbstraction, setShowAbstraction] = useState8(false);
4846
4848
  const [targetRenderNodeId, setTargetRenderNodeId] = useState8(null);
4847
4849
  const [isLinkCopied, setIsLinkCopied] = useState8(false);
4850
+ const [isAtStartOfBranch, setIsAtStartOfBranch] = useState8(true);
4848
4851
  const handleCopyLink = (e) => {
4849
4852
  e.stopPropagation();
4850
4853
  if (!ancestryId) return;
@@ -4897,7 +4900,7 @@ function DescriptionReadModePanel({
4897
4900
  onClick: () => onBranchNav(activeNodeBranches.nodeId, "open", "left")
4898
4901
  };
4899
4902
  }
4900
- if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "left") {
4903
+ if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "left" && isAtStartOfBranch) {
4901
4904
  return {
4902
4905
  type: "back",
4903
4906
  name: backNavigationInfo.name,
@@ -4905,7 +4908,7 @@ function DescriptionReadModePanel({
4905
4908
  };
4906
4909
  }
4907
4910
  return null;
4908
- }, [activeNodeBranches, backNavigationInfo, onBranchNav]);
4911
+ }, [activeNodeBranches, backNavigationInfo, onBranchNav, isAtStartOfBranch]);
4909
4912
  const rightAction = useMemo6(() => {
4910
4913
  if (activeNodeBranches == null ? void 0 : activeNodeBranches.right) {
4911
4914
  return {
@@ -4914,7 +4917,7 @@ function DescriptionReadModePanel({
4914
4917
  onClick: () => onBranchNav(activeNodeBranches.nodeId, "open", "right")
4915
4918
  };
4916
4919
  }
4917
- if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "right") {
4920
+ if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "right" && isAtStartOfBranch) {
4918
4921
  return {
4919
4922
  type: "back",
4920
4923
  name: backNavigationInfo.name,
@@ -4922,7 +4925,7 @@ function DescriptionReadModePanel({
4922
4925
  };
4923
4926
  }
4924
4927
  return null;
4925
- }, [activeNodeBranches, backNavigationInfo, onBranchNav]);
4928
+ }, [activeNodeBranches, backNavigationInfo, onBranchNav, isAtStartOfBranch]);
4926
4929
  return /* @__PURE__ */ React7.createElement(
4927
4930
  "div",
4928
4931
  {
@@ -5058,7 +5061,8 @@ function DescriptionReadModePanel({
5058
5061
  initialSectionId,
5059
5062
  currentBranchDirection,
5060
5063
  onImageClick,
5061
- onSaveDescription
5064
+ onSaveDescription,
5065
+ onStepChange: (stepIndex) => setIsAtStartOfBranch(stepIndex === 0)
5062
5066
  }
5063
5067
  )),
5064
5068
  leftAction && !showAbstraction && !showProperties && /* @__PURE__ */ React7.createElement(
@@ -5275,7 +5279,8 @@ import {
5275
5279
  FiGitBranch as FiGitBranch2,
5276
5280
  FiPlus as FiPlus2,
5277
5281
  FiLock,
5278
- FiLink as FiLink4
5282
+ FiLink as FiLink4,
5283
+ FiTrash2 as FiTrash22
5279
5284
  } from "react-icons/fi";
5280
5285
 
5281
5286
  // src/components/AncestryPickerModal.jsx
@@ -5545,6 +5550,7 @@ function CreateAncestryPanel({
5545
5550
  }, [targetRenderNodeId, ancestryMode.abstraction_tree]);
5546
5551
  const [targetScrollSectionId, setTargetScrollSectionId] = useState11(null);
5547
5552
  const [internalHighlightedNodeId, setInternalHighlightedNodeId] = useState11(null);
5553
+ const [isAtStartOfBranch, setIsAtStartOfBranch] = useState11(true);
5548
5554
  const [ancestryName, setAncestryName] = useState11(initialName);
5549
5555
  const [description, setDescription] = useState11(initialDescription || "");
5550
5556
  const [existingSections, setExistingSections] = useState11(initialSections || []);
@@ -5938,6 +5944,62 @@ function CreateAncestryPanel({
5938
5944
  }
5939
5945
  }
5940
5946
  };
5947
+ const handleDeleteBranch = async () => {
5948
+ if (branchStack.length === 0) return;
5949
+ const confirmDelete = window.confirm("Tem certeza que deseja excluir esta ramifica\xE7\xE3o e todo o seu conte\xFAdo interno?");
5950
+ if (!confirmDelete) return;
5951
+ const rootTreeClone = JSON.parse(JSON.stringify(ancestryMode.tree));
5952
+ let ptr = rootTreeClone;
5953
+ for (let i = 0; i < branchStack.length - 1; i++) {
5954
+ const step = branchStack[i];
5955
+ const found = findNodePath2(ptr, step.nodeId);
5956
+ if (found && found.node.parallel_branches) {
5957
+ const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
5958
+ if (branch) ptr = branch.tree;
5959
+ }
5960
+ }
5961
+ const currentStep = branchStack[branchStack.length - 1];
5962
+ const foundParentPath = findNodePath2(ptr, currentStep.nodeId);
5963
+ if (foundParentPath && foundParentPath.node && foundParentPath.node.parallel_branches) {
5964
+ const branchIndex = foundParentPath.node.parallel_branches.findIndex((b) => b.id === currentStep.branchId);
5965
+ if (branchIndex !== -1) {
5966
+ foundParentPath.node.parallel_branches.splice(branchIndex, 1);
5967
+ updateGlobalTree(rootTreeClone);
5968
+ try {
5969
+ setIsSaving(true);
5970
+ const currentRootProps = extractCustomPropsFromNode(ancestryMode);
5971
+ const rootExtras = toObjectFromCustomProps(currentRootProps);
5972
+ await onSave(
5973
+ ancestryMode.ancestryName,
5974
+ ancestryMode.ancestryDescription,
5975
+ ancestryMode.ancestryDescriptionSections,
5976
+ true,
5977
+ // keepOpen
5978
+ rootTreeClone,
5979
+ rootExtras
5980
+ );
5981
+ setLastSavedSnapshot(takeSnapshot(
5982
+ rootTreeClone,
5983
+ ancestryMode.ancestryName,
5984
+ ancestryMode.ancestryDescription,
5985
+ ancestryMode.ancestryDescriptionSections,
5986
+ currentRootProps,
5987
+ isPrivate,
5988
+ ancestryMode.abstraction_tree
5989
+ ));
5990
+ if (onClearAncestryVisuals) {
5991
+ onClearAncestryVisuals(currentStep.branchId);
5992
+ }
5993
+ handleNavigateUp();
5994
+ } catch (err) {
5995
+ console.error("Erro ao remover a ramifica\xE7\xE3o:", err);
5996
+ alert("Erro ao remover a ramifica\xE7\xE3o.");
5997
+ } finally {
5998
+ setIsSaving(false);
5999
+ }
6000
+ }
6001
+ }
6002
+ };
5941
6003
  const sideActions = useMemo8(() => {
5942
6004
  const actions = { left: null, right: null };
5943
6005
  const isInBranch = branchStack.length > 0;
@@ -5976,7 +6038,7 @@ function CreateAncestryPanel({
5976
6038
  }
5977
6039
  return actions;
5978
6040
  }
5979
- if (isInBranch) {
6041
+ if (isInBranch && isAtStartOfBranch) {
5980
6042
  const lastStep = branchStack[branchStack.length - 1];
5981
6043
  const entryDir = lastStep.entryDirection || "right";
5982
6044
  const backSide = entryDir === "right" ? "left" : "right";
@@ -5987,7 +6049,7 @@ function CreateAncestryPanel({
5987
6049
  };
5988
6050
  }
5989
6051
  return actions;
5990
- }, [internalHighlightedNodeId, branchStack, activeTree]);
6052
+ }, [internalHighlightedNodeId, branchStack, activeTree, isAtStartOfBranch]);
5991
6053
  const applyDescriptionToTree = (baseTree, descText, descSections) => {
5992
6054
  const rootTreeClone = JSON.parse(JSON.stringify(baseTree));
5993
6055
  let targetTree = rootTreeClone;
@@ -6600,7 +6662,7 @@ function CreateAncestryPanel({
6600
6662
  placeholder: "Nome da Ancestralidade",
6601
6663
  className: "text-xl sm:text-2xl font-semibold tracking-tight bg-transparent border-none p-0 focus:ring-2 focus:ring-indigo-500 rounded-md -ml-1.5 px-1.5 w-full outline-none transition-all focus:bg-slate-800/70"
6602
6664
  }
6603
- )), /* @__PURE__ */ React10.createElement("button", { onClick: onClose, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl flex-shrink-0", title: "Cancelar" }, "\xD7")), branchStack.length > 0 && /* @__PURE__ */ React10.createElement("div", { className: "px-6 pb-2" }, /* @__PURE__ */ React10.createElement(
6665
+ )), /* @__PURE__ */ React10.createElement("button", { onClick: onClose, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl flex-shrink-0", title: "Cancelar" }, "\xD7")), branchStack.length > 0 && /* @__PURE__ */ React10.createElement("div", { className: "px-6 pb-2 flex items-center justify-between" }, /* @__PURE__ */ React10.createElement(
6604
6666
  "button",
6605
6667
  {
6606
6668
  onClick: handleNavigateUp,
@@ -6608,6 +6670,15 @@ function CreateAncestryPanel({
6608
6670
  },
6609
6671
  /* @__PURE__ */ React10.createElement(FiArrowLeft2, null),
6610
6672
  " Voltar para Principal / N\xEDvel Anterior"
6673
+ ), !isContextLinked && /* @__PURE__ */ React10.createElement(
6674
+ "button",
6675
+ {
6676
+ onClick: handleDeleteBranch,
6677
+ className: "flex items-center gap-1.5 text-xs text-rose-400 hover:text-white hover:bg-rose-500/20 px-2 py-1 rounded transition-colors",
6678
+ title: "Excluir permanentemente esta ramifica\xE7\xE3o e seu conte\xFAdo"
6679
+ },
6680
+ /* @__PURE__ */ React10.createElement(FiTrash22, null),
6681
+ " Excluir Ramifica\xE7\xE3o"
6611
6682
  )), /* @__PURE__ */ React10.createElement("div", { className: "px-6 pb-4 pt-2 overflow-y-auto flex-grow custom-scrollbar" }, branchStack.length > 0 && /* @__PURE__ */ React10.createElement("div", { className: "mb-4" }, isContextLinked ? /* @__PURE__ */ React10.createElement("div", { className: "p-3 rounded-lg bg-indigo-500/10 border border-indigo-500/30 flex items-center justify-between" }, /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React10.createElement("div", { className: "w-8 h-8 rounded bg-indigo-500/20 text-indigo-300 grid place-content-center" }, /* @__PURE__ */ React10.createElement(FiLayers5, null)), /* @__PURE__ */ React10.createElement("div", null, /* @__PURE__ */ React10.createElement("div", { className: "text-xs text-indigo-200 font-semibold uppercase tracking-wider" }, "Ancestralidade Vinculada"), /* @__PURE__ */ React10.createElement("div", { className: "text-sm text-white font-medium truncate max-w-[200px]" }, currentContext.name.replace("[REF] ", "")))), /* @__PURE__ */ React10.createElement(
6612
6683
  "button",
6613
6684
  {
@@ -6639,7 +6710,8 @@ function CreateAncestryPanel({
6639
6710
  initialSectionId: targetScrollSectionId,
6640
6711
  currentBranchDirection: currentContext ? currentContext.direction : null,
6641
6712
  onImageClick: handleImageClickFromText,
6642
- onSaveDescription: handleSaveDescriptionInline
6713
+ onSaveDescription: handleSaveDescriptionInline,
6714
+ onStepChange: (stepIndex) => setIsAtStartOfBranch(stepIndex === 0)
6643
6715
  }
6644
6716
  ), /* @__PURE__ */ React10.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5 z-30" }, /* @__PURE__ */ React10.createElement(
6645
6717
  "button",
@@ -8943,7 +9015,7 @@ import {
8943
9015
  FiCornerUpRight as FiCornerUpRight4,
8944
9016
  FiPlay,
8945
9017
  FiPlus as FiPlus7,
8946
- FiTrash2 as FiTrash22,
9018
+ FiTrash2 as FiTrash23,
8947
9019
  FiArrowLeft as FiArrowLeft3,
8948
9020
  FiArrowRight,
8949
9021
  FiCheckCircle,
@@ -9080,7 +9152,7 @@ var GroupItem = ({
9080
9152
  className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
9081
9153
  title: "Remover Grupo"
9082
9154
  },
9083
- /* @__PURE__ */ React22.createElement(FiTrash22, { size: 14 })
9155
+ /* @__PURE__ */ React22.createElement(FiTrash23, { size: 14 })
9084
9156
  )))), group.children && group.children.length > 0 && /* @__PURE__ */ React22.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ React22.createElement(
9085
9157
  GroupItem,
9086
9158
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lv-x-software-house/x_view",
3
- "version": "1.2.2-dev.23",
3
+ "version": "1.2.2-dev.26",
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",