@lv-x-software-house/x_view 1.2.2-dev.22 → 1.2.2-dev.24

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
@@ -290,7 +290,7 @@ function ContextMenu({
290
290
  return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ import_react.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es R\xE1pidas")), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col gap-1" }, ability.can("create", "Connection") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartConnection == null ? void 0 : onStartConnection(data.nodeData), className: baseButtonClass, title: "Conectar" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Conectar")), ability.can("create", "Node") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartCreation == null ? void 0 : onStartCreation(data.nodeData), className: baseButtonClass, title: "Criar e Conectar" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "16" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "8", y1: "12", x2: "16", y2: "12" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Criar e Conectar")), ability.can("create", "Ancestry") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartAncestryCreation == null ? void 0 : onStartAncestryCreation(data.nodeData), className: baseButtonClass, title: "Criar Ancestralidade" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 20.5c.5-.5.8-1.2.8-2s-.3-1.5-.8-2c-.5-.5-1.2-.8-2-.8s-1.5.3-2 .8c-.5.5-.8 1.2-.8 2s.3 1.5.8 2c.5.5 1.2-.8 2 .8s1.5-.3 2-.8Z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 16v-3a2 2 0 0 1 2-2h4" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 3.5c.5.5.8 1.2.8 2s-.3 1.5-.8 2c-.5-.5-1.2-.8-2 .8s1.5.3-2-.8c-.5-.5-.8-1.2-.8-2s.3-1.5.8-2c.5.5 1.2-.8 2 .8s1.5.3 2 .8Z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 8v3a2 2 0 0 0 2 2h4" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Criar Ancestralidade")), shouldShowVersioningBtn && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("versioning"), className: baseButtonClass, title: hasVersions ? "Versionamento" : "Criar Versionamento" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("line", { x1: "6", y1: "3", x2: "6", y2: "15" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "18", cy: "6", r: "3" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "6", cy: "18", r: "3" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })), /* @__PURE__ */ import_react.default.createElement("span", null, hasVersions || !canCreateVersion ? "Versionamento" : "Criar Versionamento")), (connections.length > 0 || availableAncestries.length > 0) && ability.can("read", "Connection") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("connections"), className: baseButtonClass, title: "Conex\xF5es" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M8 12h8" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 8v8" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Conex\xF5es (", totalConnectionsCount, ")"))), /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
291
291
  onFocusNode == null ? void 0 : onFocusNode(data.nodeData);
292
292
  onClose();
293
- }, className: baseButtonClass, title: "Focar na c\xE2mera" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Focar neste Node")), /* @__PURE__ */ import_react.default.createElement("button", { onClick: (e) => handleCopyLink(e, data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, isLinkCopied ? /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#4ade80", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "20 6 9 17 4 12" })) : /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ import_react.default.createElement("span", { className: isLinkCopied ? "text-green-400" : "" }, isLinkCopied ? "Copiado!" : "Copiar Link")), ability.can("dismiss", "Node") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDismissNode == null ? void 0 : onDismissNode(data.nodeData), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Dismiss")), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDismissOtherNodes == null ? void 0 : onDismissOtherNodes(data.nodeData), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Dismiss other nodes"))), ability.can("delete", "Node") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDeleteNode == null ? void 0 : onDeleteNode(data.nodeData), className: deleteButtonClass, title: "Excluir Node" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Excluir Node"))));
293
+ }, className: baseButtonClass, title: "Focar na c\xE2mera" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Focar neste Node")), /* @__PURE__ */ import_react.default.createElement("button", { onClick: (e) => handleCopyLink(e, data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, isLinkCopied ? /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#4ade80", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "20 6 9 17 4 12" })) : /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ import_react.default.createElement("span", { className: isLinkCopied ? "text-green-400" : "" }, isLinkCopied ? "Copiado!" : "Copiar Link")), ability.can("dismiss", "Node") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDismissNode == null ? void 0 : onDismissNode(data.nodeData), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Dismiss")), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDismissOtherNodes == null ? void 0 : onDismissOtherNodes(data.nodeData), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Dismiss other nodes"))), ability.can("delete", "Node") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("deleteConfirmation"), className: deleteButtonClass, title: "Excluir Node" }, /* @__PURE__ */ import_react.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" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Excluir Node"))));
294
294
  };
295
295
  const renderVersionSubMenuView = () => {
296
296
  const group = versionSubMenu;
@@ -382,6 +382,24 @@ function ContextMenu({
382
382
  /* @__PURE__ */ import_react.default.createElement("span", { className: "flex-1 truncate" }, version.name)
383
383
  ))));
384
384
  };
385
+ const renderDeleteConfirmationView = () => {
386
+ var _a2;
387
+ return /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ import_react.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ import_react.default.createElement("strong", null, (_a2 = data.nodeData) == null ? void 0 : _a2.name), "?"), /* @__PURE__ */ import_react.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight" }, "Todas as conex\xF5es associadas tamb\xE9m ser\xE3o apagadas.")), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react.default.createElement(
388
+ "button",
389
+ {
390
+ onClick: () => setMenuView("main"),
391
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
392
+ },
393
+ "Cancelar"
394
+ ), /* @__PURE__ */ import_react.default.createElement(
395
+ "button",
396
+ {
397
+ onClick: () => onDeleteNode == null ? void 0 : onDeleteNode(data.nodeData),
398
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
399
+ },
400
+ "Excluir"
401
+ )));
402
+ };
385
403
  return /* @__PURE__ */ import_react.default.createElement(
386
404
  "div",
387
405
  {
@@ -397,7 +415,7 @@ function ContextMenu({
397
415
  onDoubleClick: swallow
398
416
  },
399
417
  /* @__PURE__ */ import_react.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
400
- /* @__PURE__ */ import_react.default.createElement("div", { className: "p-1.5" }, menuView === "main" && renderMainView(), menuView === "connections" && renderConnectionsView(), menuView === "ancestryActions" && renderAncestryActionsView(), menuView === "versioning" && renderVersioningView())
418
+ /* @__PURE__ */ import_react.default.createElement("div", { className: "p-1.5" }, menuView === "main" && renderMainView(), menuView === "connections" && renderConnectionsView(), menuView === "ancestryActions" && renderAncestryActionsView(), menuView === "versioning" && renderVersioningView(), menuView === "deleteConfirmation" && renderDeleteConfirmationView())
401
419
  );
402
420
  }
403
421
 
@@ -1579,7 +1597,6 @@ var userActionHandlers = {
1579
1597
  color: ghostColor,
1580
1598
  emissive: ghostEmissive,
1581
1599
  emissiveIntensity: MIN_VISIBILITY_INTENSITY,
1582
- // <-- Forçamos o brilho mínimo
1583
1600
  roughness: 0.6,
1584
1601
  metalness: 0,
1585
1602
  transparent: true,
@@ -1736,7 +1753,6 @@ var userActionHandlers = {
1736
1753
  color: ghostColor,
1737
1754
  emissive: ghostEmissive,
1738
1755
  emissiveIntensity: MIN_VISIBILITY_INTENSITY,
1739
- // <-- Forçamos o brilho mínimo
1740
1756
  roughness: 0.6,
1741
1757
  metalness: 0,
1742
1758
  transparent: true,
@@ -2033,9 +2049,7 @@ var userActionHandlers = {
2033
2049
  linkObject.visible = false;
2034
2050
  controls.enabled = false;
2035
2051
  if (mountRef.current) mountRef.current.style.cursor = "crosshair";
2036
- const tempMat = new import_LineMaterial.LineMaterial({
2037
- /* ... material tracejado ... */
2038
- });
2052
+ const tempMat = new import_LineMaterial.LineMaterial({});
2039
2053
  const tempGeom = new import_LineGeometry.LineGeometry().setPositions([
2040
2054
  ...fixedNode.position.toArray(),
2041
2055
  ...fixedNode.position.toArray()
@@ -2164,9 +2178,6 @@ var userActionHandlers = {
2164
2178
  const { parentFileId, ownerId } = parentInfo;
2165
2179
  const srcName = ((_c = (_b = (_a = linkObject.userData) == null ? void 0 : _a.sourceNode) == null ? void 0 : _b.userData) == null ? void 0 : _c.name) ?? linkObject.userData.source;
2166
2180
  const tgtName = ((_f = (_e = (_d = linkObject.userData) == null ? void 0 : _d.targetNode) == null ? void 0 : _e.userData) == null ? void 0 : _f.name) ?? linkObject.userData.target;
2167
- if (!window.confirm(`Tem certeza que deseja excluir a conex\xE3o entre "${srcName}" \u2192 "${tgtName}"?`)) {
2168
- return;
2169
- }
2170
2181
  const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
2171
2182
  const newLinks = (specificParentData.links || []).filter((l) => String(l.id) !== String(linkIdToDelete));
2172
2183
  specificParentData.links = newLinks;
@@ -2320,9 +2331,6 @@ var userActionHandlers = {
2320
2331
  const { stateRef, graphDataRef, sceneDataRef, setters, actions } = context;
2321
2332
  setters.setMultiContextMenu({ visible: false });
2322
2333
  if (!nodeIds || nodeIds.size === 0 || !graphDataRef.current || !sceneDataRef.current) return;
2323
- if (!window.confirm(`Tem certeza que deseja excluir ${nodeIds.size} Nodes e todas as suas conex\xF5es? Esta a\xE7\xE3o \xE9 irrevers\xEDvel.`)) {
2324
- return;
2325
- }
2326
2334
  const strNodeIdsToDelete = Array.from(nodeIds).map(String);
2327
2335
  if (actions.delete_file) {
2328
2336
  strNodeIdsToDelete.forEach((id) => {
@@ -2403,9 +2411,6 @@ var userActionHandlers = {
2403
2411
  }
2404
2412
  setters.setContextMenu({ visible: false });
2405
2413
  if (!nodeData || !graphDataRef.current || !sceneDataRef.current) return;
2406
- if (!window.confirm(`Tem certeza que deseja excluir o Node "${nodeData.name}" e todas as sua conex\xF5es?`)) {
2407
- return;
2408
- }
2409
2414
  const nodeIdToDelete = nodeData.id;
2410
2415
  const strNodeId = String(nodeIdToDelete);
2411
2416
  const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete);
@@ -4363,8 +4368,7 @@ var CodeBlock2 = ({ content, isActive, onClick }) => {
4363
4368
  "button",
4364
4369
  {
4365
4370
  onClick: handleCopy,
4366
- 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",
4367
- 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"
4368
4372
  },
4369
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 }),
4370
4374
  copied ? /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-emerald-400" }, "Copiado") : /* @__PURE__ */ import_react7.default.createElement("span", null, "Copiar")
@@ -4393,8 +4397,7 @@ var renderLinks = (text) => {
4393
4397
  target: "_blank",
4394
4398
  rel: "noopener noreferrer",
4395
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",
4396
- onClick: (e) => e.stopPropagation(),
4397
- title: `Abrir link externo: ${url}`
4400
+ onClick: (e) => e.stopPropagation()
4398
4401
  },
4399
4402
  part,
4400
4403
  /* @__PURE__ */ import_react7.default.createElement(import_fi5.FiExternalLink, { size: 10, className: "opacity-70 mb-0.5" })
@@ -4423,8 +4426,7 @@ var renderTextWithImages = (text, onImageClick) => {
4423
4426
  e.stopPropagation();
4424
4427
  onImageClick == null ? void 0 : onImageClick(url, name);
4425
4428
  },
4426
- 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",
4427
- 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"
4428
4430
  },
4429
4431
  /* @__PURE__ */ import_react7.default.createElement(import_fi5.FiImage, { size: 11 }),
4430
4432
  /* @__PURE__ */ import_react7.default.createElement("span", null, name)
@@ -4461,8 +4463,7 @@ var renderTextWithMentions = (text, availableNodes, onMentionClick, activeMentio
4461
4463
  className: `
4462
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]
4463
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"}
4464
- `,
4465
- title: `Clique para focar no Node: ${displayName}`
4466
+ `
4466
4467
  },
4467
4468
  /* @__PURE__ */ import_react7.default.createElement("span", { className: "opacity-60 text-[0.8em]" }, "@"),
4468
4469
  displayName
@@ -4536,7 +4537,9 @@ function DescriptionDisplay({
4536
4537
  onHighlightNode,
4537
4538
  initialSectionId,
4538
4539
  currentBranchDirection = null,
4539
- onSaveDescription
4540
+ onSaveDescription,
4541
+ onStepChange
4542
+ // 1. Adicione a nova prop aqui
4540
4543
  }) {
4541
4544
  const [localDescription, setLocalDescription] = (0, import_react7.useState)(description || "");
4542
4545
  (0, import_react7.useEffect)(() => {
@@ -4583,6 +4586,11 @@ function DescriptionDisplay({
4583
4586
  return navItems;
4584
4587
  }, [sections]);
4585
4588
  const [currentStepIndex, setCurrentStepIndex] = (0, import_react7.useState)(0);
4589
+ (0, import_react7.useEffect)(() => {
4590
+ if (onStepChange) {
4591
+ onStepChange(currentStepIndex);
4592
+ }
4593
+ }, [currentStepIndex, onStepChange]);
4586
4594
  const activeRef = (0, import_react7.useRef)(null);
4587
4595
  const lastNotifiedSectionId = (0, import_react7.useRef)(null);
4588
4596
  const isInitialMount = (0, import_react7.useRef)(true);
@@ -4734,8 +4742,7 @@ function DescriptionDisplay({
4734
4742
  if (onOpenReference) {
4735
4743
  onOpenReference({ type: resolved.type, id: resolved.sourceId });
4736
4744
  }
4737
- },
4738
- title: `Ir para ${resolved.type === "node" ? "Node" : "Ancestralidade"}: ${resolved.sourceName}`
4745
+ }
4739
4746
  },
4740
4747
  /* @__PURE__ */ import_react7.default.createElement(import_fi5.FiCornerDownRight, { size: 12, className: "text-indigo-400" }),
4741
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" }))
@@ -4870,6 +4877,7 @@ function DescriptionReadModePanel({
4870
4877
  const [showAbstraction, setShowAbstraction] = (0, import_react8.useState)(false);
4871
4878
  const [targetRenderNodeId, setTargetRenderNodeId] = (0, import_react8.useState)(null);
4872
4879
  const [isLinkCopied, setIsLinkCopied] = (0, import_react8.useState)(false);
4880
+ const [isAtStartOfBranch, setIsAtStartOfBranch] = (0, import_react8.useState)(true);
4873
4881
  const handleCopyLink = (e) => {
4874
4882
  e.stopPropagation();
4875
4883
  if (!ancestryId) return;
@@ -4922,7 +4930,7 @@ function DescriptionReadModePanel({
4922
4930
  onClick: () => onBranchNav(activeNodeBranches.nodeId, "open", "left")
4923
4931
  };
4924
4932
  }
4925
- if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "left") {
4933
+ if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "left" && isAtStartOfBranch) {
4926
4934
  return {
4927
4935
  type: "back",
4928
4936
  name: backNavigationInfo.name,
@@ -4930,7 +4938,7 @@ function DescriptionReadModePanel({
4930
4938
  };
4931
4939
  }
4932
4940
  return null;
4933
- }, [activeNodeBranches, backNavigationInfo, onBranchNav]);
4941
+ }, [activeNodeBranches, backNavigationInfo, onBranchNav, isAtStartOfBranch]);
4934
4942
  const rightAction = (0, import_react8.useMemo)(() => {
4935
4943
  if (activeNodeBranches == null ? void 0 : activeNodeBranches.right) {
4936
4944
  return {
@@ -4939,7 +4947,7 @@ function DescriptionReadModePanel({
4939
4947
  onClick: () => onBranchNav(activeNodeBranches.nodeId, "open", "right")
4940
4948
  };
4941
4949
  }
4942
- if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "right") {
4950
+ if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "right" && isAtStartOfBranch) {
4943
4951
  return {
4944
4952
  type: "back",
4945
4953
  name: backNavigationInfo.name,
@@ -4947,7 +4955,7 @@ function DescriptionReadModePanel({
4947
4955
  };
4948
4956
  }
4949
4957
  return null;
4950
- }, [activeNodeBranches, backNavigationInfo, onBranchNav]);
4958
+ }, [activeNodeBranches, backNavigationInfo, onBranchNav, isAtStartOfBranch]);
4951
4959
  return /* @__PURE__ */ import_react8.default.createElement(
4952
4960
  "div",
4953
4961
  {
@@ -5083,7 +5091,8 @@ function DescriptionReadModePanel({
5083
5091
  initialSectionId,
5084
5092
  currentBranchDirection,
5085
5093
  onImageClick,
5086
- onSaveDescription
5094
+ onSaveDescription,
5095
+ onStepChange: (stepIndex) => setIsAtStartOfBranch(stepIndex === 0)
5087
5096
  }
5088
5097
  )),
5089
5098
  leftAction && !showAbstraction && !showProperties && /* @__PURE__ */ import_react8.default.createElement(
@@ -5554,6 +5563,7 @@ function CreateAncestryPanel({
5554
5563
  }, [targetRenderNodeId, ancestryMode.abstraction_tree]);
5555
5564
  const [targetScrollSectionId, setTargetScrollSectionId] = (0, import_react11.useState)(null);
5556
5565
  const [internalHighlightedNodeId, setInternalHighlightedNodeId] = (0, import_react11.useState)(null);
5566
+ const [isAtStartOfBranch, setIsAtStartOfBranch] = (0, import_react11.useState)(true);
5557
5567
  const [ancestryName, setAncestryName] = (0, import_react11.useState)(initialName);
5558
5568
  const [description, setDescription] = (0, import_react11.useState)(initialDescription || "");
5559
5569
  const [existingSections, setExistingSections] = (0, import_react11.useState)(initialSections || []);
@@ -5985,7 +5995,7 @@ function CreateAncestryPanel({
5985
5995
  }
5986
5996
  return actions;
5987
5997
  }
5988
- if (isInBranch) {
5998
+ if (isInBranch && isAtStartOfBranch) {
5989
5999
  const lastStep = branchStack[branchStack.length - 1];
5990
6000
  const entryDir = lastStep.entryDirection || "right";
5991
6001
  const backSide = entryDir === "right" ? "left" : "right";
@@ -5996,7 +6006,7 @@ function CreateAncestryPanel({
5996
6006
  };
5997
6007
  }
5998
6008
  return actions;
5999
- }, [internalHighlightedNodeId, branchStack, activeTree]);
6009
+ }, [internalHighlightedNodeId, branchStack, activeTree, isAtStartOfBranch]);
6000
6010
  const applyDescriptionToTree = (baseTree, descText, descSections) => {
6001
6011
  const rootTreeClone = JSON.parse(JSON.stringify(baseTree));
6002
6012
  let targetTree = rootTreeClone;
@@ -6648,7 +6658,8 @@ function CreateAncestryPanel({
6648
6658
  initialSectionId: targetScrollSectionId,
6649
6659
  currentBranchDirection: currentContext ? currentContext.direction : null,
6650
6660
  onImageClick: handleImageClickFromText,
6651
- onSaveDescription: handleSaveDescriptionInline
6661
+ onSaveDescription: handleSaveDescriptionInline,
6662
+ onStepChange: (stepIndex) => setIsAtStartOfBranch(stepIndex === 0)
6652
6663
  }
6653
6664
  ), /* @__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(
6654
6665
  "button",
@@ -8174,7 +8185,6 @@ var import_react17 = __toESM(require("react"));
8174
8185
  function MultiNodeContextMenu({
8175
8186
  data,
8176
8187
  userRole,
8177
- // 2. Recebendo a role do usuário nas props
8178
8188
  onClose,
8179
8189
  onDismissNodes,
8180
8190
  onDismissOtherNodes,
@@ -8182,6 +8192,7 @@ function MultiNodeContextMenu({
8182
8192
  }) {
8183
8193
  const menuRef = (0, import_react17.useRef)(null);
8184
8194
  const [menuPos, setMenuPos] = (0, import_react17.useState)({ left: 0, top: 0 });
8195
+ const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react17.useState)(false);
8185
8196
  const ability = defineAbilityFor(userRole);
8186
8197
  const canDelete = ability.can("delete", "Node");
8187
8198
  (0, import_react17.useLayoutEffect)(() => {
@@ -8198,7 +8209,9 @@ function MultiNodeContextMenu({
8198
8209
  setMenuPos({ left, top });
8199
8210
  }, [data]);
8200
8211
  (0, import_react17.useEffect)(() => {
8201
- if (!data.visible) return;
8212
+ if (data.visible) {
8213
+ setIsConfirmingDelete(false);
8214
+ }
8202
8215
  const handleClickOutside = (e) => {
8203
8216
  if (menuRef.current && !menuRef.current.contains(e.target)) onClose();
8204
8217
  };
@@ -8225,7 +8238,21 @@ function MultiNodeContextMenu({
8225
8238
  onDoubleClick: swallow
8226
8239
  },
8227
8240
  /* @__PURE__ */ import_react17.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
8228
- /* @__PURE__ */ import_react17.default.createElement("div", { className: "p-1.5" }, /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react17.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ import_react17.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react17.default.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react17.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" }, /* @__PURE__ */ import_react17.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ import_react17.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react17.default.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ import_react17.default.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react17.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" }, /* @__PURE__ */ import_react17.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react17.default.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react17.default.createElement("button", { onClick: () => onDeleteNodes(data.nodeIds), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ import_react17.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" }, /* @__PURE__ */ import_react17.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react17.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react17.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react17.default.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
8241
+ /* @__PURE__ */ import_react17.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ import_react17.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react17.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ import_react17.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ import_react17.default.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ import_react17.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight" }, "Esta a\xE7\xE3o \xE9 irrevers\xEDvel. Todas as conex\xF5es associadas a eles ser\xE3o apagadas.")), /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react17.default.createElement(
8242
+ "button",
8243
+ {
8244
+ onClick: () => setIsConfirmingDelete(false),
8245
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
8246
+ },
8247
+ "Cancelar"
8248
+ ), /* @__PURE__ */ import_react17.default.createElement(
8249
+ "button",
8250
+ {
8251
+ onClick: () => onDeleteNodes(data.nodeIds),
8252
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
8253
+ },
8254
+ "Excluir"
8255
+ ))) : /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react17.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ import_react17.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react17.default.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react17.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" }, /* @__PURE__ */ import_react17.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ import_react17.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react17.default.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ import_react17.default.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react17.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" }, /* @__PURE__ */ import_react17.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react17.default.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react17.default.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ import_react17.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" }, /* @__PURE__ */ import_react17.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react17.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react17.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react17.default.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
8229
8256
  );
8230
8257
  }
8231
8258
 
@@ -8466,7 +8493,6 @@ var import_react19 = __toESM(require("react"));
8466
8493
  function RelationshipContextMenu({
8467
8494
  data,
8468
8495
  userRole,
8469
- // Recebemos a role do usuário para verificar permissões
8470
8496
  onRelinkSource,
8471
8497
  onRelinkTarget,
8472
8498
  onOpenDetails,
@@ -8475,6 +8501,7 @@ function RelationshipContextMenu({
8475
8501
  }) {
8476
8502
  const menuRef = (0, import_react19.useRef)(null);
8477
8503
  const [menuPos, setMenuPos] = (0, import_react19.useState)({ left: 0, top: 0 });
8504
+ const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react19.useState)(false);
8478
8505
  const ability = (0, import_react19.useMemo)(() => defineAbilityFor(userRole), [userRole]);
8479
8506
  const sourceName = (0, import_react19.useMemo)(
8480
8507
  () => {
@@ -8504,7 +8531,9 @@ function RelationshipContextMenu({
8504
8531
  setMenuPos({ left, top });
8505
8532
  }, [data]);
8506
8533
  (0, import_react19.useEffect)(() => {
8507
- if (!data.visible) return;
8534
+ if (data.visible) {
8535
+ setIsConfirmingDelete(false);
8536
+ }
8508
8537
  const handleClickOutside = (e) => {
8509
8538
  if (menuRef.current && !menuRef.current.contains(e.target)) onClose();
8510
8539
  };
@@ -8532,7 +8561,21 @@ function RelationshipContextMenu({
8532
8561
  onDoubleClick: swallow
8533
8562
  },
8534
8563
  /* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
8535
- /* @__PURE__ */ import_react19.default.createElement("div", { className: "p-1.5" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react19.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-teal-400/80 shadow-[0_0_12px_1px_rgba(45,212,191,0.5)]" }), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement(
8564
+ /* @__PURE__ */ import_react19.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ import_react19.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react19.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ import_react19.default.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ import_react19.default.createElement("strong", null, targetName), ".")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react19.default.createElement(
8565
+ "button",
8566
+ {
8567
+ onClick: () => setIsConfirmingDelete(false),
8568
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
8569
+ },
8570
+ "Cancelar"
8571
+ ), /* @__PURE__ */ import_react19.default.createElement(
8572
+ "button",
8573
+ {
8574
+ onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
8575
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-rose-600 hover:bg-rose-500 rounded-md text-white transition-colors"
8576
+ },
8577
+ "Excluir"
8578
+ ))) : /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react19.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-teal-400/80 shadow-[0_0_12px_1px_rgba(45,212,191,0.5)]" }), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement(
8536
8579
  "button",
8537
8580
  {
8538
8581
  onClick: () => onRelinkSource == null ? void 0 : onRelinkSource(data.linkObject),
@@ -8611,7 +8654,7 @@ function RelationshipContextMenu({
8611
8654
  ), canDelete && /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ import_react19.default.createElement(
8612
8655
  "button",
8613
8656
  {
8614
- onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
8657
+ onClick: () => setIsConfirmingDelete(true),
8615
8658
  className: dangerButtonClass,
8616
8659
  title: "Excluir esta conex\xE3o"
8617
8660
  },
@@ -8635,7 +8678,7 @@ function RelationshipContextMenu({
8635
8678
  /* @__PURE__ */ import_react19.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
8636
8679
  ),
8637
8680
  /* @__PURE__ */ import_react19.default.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
8638
- ))))
8681
+ )))))
8639
8682
  );
8640
8683
  }
8641
8684
 
package/dist/index.mjs CHANGED
@@ -246,7 +246,7 @@ function ContextMenu({
246
246
  return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ React.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es R\xE1pidas")), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-1" }, ability.can("create", "Connection") && /* @__PURE__ */ React.createElement("button", { onClick: () => onStartConnection == null ? void 0 : onStartConnection(data.nodeData), className: baseButtonClass, title: "Conectar" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ React.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ React.createElement("span", null, "Conectar")), ability.can("create", "Node") && /* @__PURE__ */ React.createElement("button", { onClick: () => onStartCreation == null ? void 0 : onStartCreation(data.nodeData), className: baseButtonClass, title: "Criar e Conectar" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ React.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "16" }), /* @__PURE__ */ React.createElement("line", { x1: "8", y1: "12", x2: "16", y2: "12" })), /* @__PURE__ */ React.createElement("span", null, "Criar e Conectar")), ability.can("create", "Ancestry") && /* @__PURE__ */ React.createElement("button", { onClick: () => onStartAncestryCreation == null ? void 0 : onStartAncestryCreation(data.nodeData), className: baseButtonClass, title: "Criar Ancestralidade" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("path", { d: "M10 20.5c.5-.5.8-1.2.8-2s-.3-1.5-.8-2c-.5-.5-1.2-.8-2-.8s-1.5.3-2 .8c-.5.5-.8 1.2-.8 2s.3 1.5.8 2c.5.5 1.2-.8 2 .8s1.5-.3 2-.8Z" }), /* @__PURE__ */ React.createElement("path", { d: "M10 16v-3a2 2 0 0 1 2-2h4" }), /* @__PURE__ */ React.createElement("path", { d: "M14 3.5c.5.5.8 1.2.8 2s-.3 1.5-.8 2c-.5-.5-1.2-.8-2 .8s1.5.3-2-.8c-.5-.5-.8-1.2-.8-2s.3-1.5.8-2c.5.5 1.2-.8 2 .8s1.5.3 2 .8Z" }), /* @__PURE__ */ React.createElement("path", { d: "M14 8v3a2 2 0 0 0 2 2h4" })), /* @__PURE__ */ React.createElement("span", null, "Criar Ancestralidade")), shouldShowVersioningBtn && /* @__PURE__ */ React.createElement("button", { onClick: () => setMenuView("versioning"), className: baseButtonClass, title: hasVersions ? "Versionamento" : "Criar Versionamento" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("line", { x1: "6", y1: "3", x2: "6", y2: "15" }), /* @__PURE__ */ React.createElement("circle", { cx: "18", cy: "6", r: "3" }), /* @__PURE__ */ React.createElement("circle", { cx: "6", cy: "18", r: "3" }), /* @__PURE__ */ React.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })), /* @__PURE__ */ React.createElement("span", null, hasVersions || !canCreateVersion ? "Versionamento" : "Criar Versionamento")), (connections.length > 0 || availableAncestries.length > 0) && ability.can("read", "Connection") && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React.createElement("button", { onClick: () => setMenuView("connections"), className: baseButtonClass, title: "Conex\xF5es" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2z" }), /* @__PURE__ */ React.createElement("path", { d: "M8 12h8" }), /* @__PURE__ */ React.createElement("path", { d: "M12 8v8" })), /* @__PURE__ */ React.createElement("span", null, "Conex\xF5es (", totalConnectionsCount, ")"))), /* @__PURE__ */ React.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React.createElement("button", { onClick: () => {
247
247
  onFocusNode == null ? void 0 : onFocusNode(data.nodeData);
248
248
  onClose();
249
- }, className: baseButtonClass, title: "Focar na c\xE2mera" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ React.createElement("span", null, "Focar neste Node")), /* @__PURE__ */ React.createElement("button", { onClick: (e) => handleCopyLink(e, data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, isLinkCopied ? /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#4ade80", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("polyline", { points: "20 6 9 17 4 12" })) : /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ React.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ React.createElement("span", { className: isLinkCopied ? "text-green-400" : "" }, isLinkCopied ? "Copiado!" : "Copiar Link")), ability.can("dismiss", "Node") && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("button", { onClick: () => onDismissNode == null ? void 0 : onDismissNode(data.nodeData), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ React.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ React.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ React.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ React.createElement("span", null, "Dismiss")), /* @__PURE__ */ React.createElement("button", { onClick: () => onDismissOtherNodes == null ? void 0 : onDismissOtherNodes(data.nodeData), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ React.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ React.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ React.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ React.createElement("span", null, "Dismiss other nodes"))), ability.can("delete", "Node") && /* @__PURE__ */ React.createElement("button", { onClick: () => onDeleteNode == null ? void 0 : onDeleteNode(data.nodeData), className: deleteButtonClass, title: "Excluir Node" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ React.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ React.createElement("span", null, "Excluir Node"))));
249
+ }, className: baseButtonClass, title: "Focar na c\xE2mera" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ React.createElement("span", null, "Focar neste Node")), /* @__PURE__ */ React.createElement("button", { onClick: (e) => handleCopyLink(e, data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, isLinkCopied ? /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#4ade80", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("polyline", { points: "20 6 9 17 4 12" })) : /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ React.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ React.createElement("span", { className: isLinkCopied ? "text-green-400" : "" }, isLinkCopied ? "Copiado!" : "Copiar Link")), ability.can("dismiss", "Node") && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("button", { onClick: () => onDismissNode == null ? void 0 : onDismissNode(data.nodeData), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ React.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ React.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ React.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ React.createElement("span", null, "Dismiss")), /* @__PURE__ */ React.createElement("button", { onClick: () => onDismissOtherNodes == null ? void 0 : onDismissOtherNodes(data.nodeData), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ React.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ React.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ React.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ React.createElement("span", null, "Dismiss other nodes"))), ability.can("delete", "Node") && /* @__PURE__ */ React.createElement("button", { onClick: () => setMenuView("deleteConfirmation"), className: deleteButtonClass, title: "Excluir Node" }, /* @__PURE__ */ React.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" }, /* @__PURE__ */ React.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ React.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ React.createElement("span", null, "Excluir Node"))));
250
250
  };
251
251
  const renderVersionSubMenuView = () => {
252
252
  const group = versionSubMenu;
@@ -338,6 +338,24 @@ function ContextMenu({
338
338
  /* @__PURE__ */ React.createElement("span", { className: "flex-1 truncate" }, version.name)
339
339
  ))));
340
340
  };
341
+ const renderDeleteConfirmationView = () => {
342
+ var _a2;
343
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ React.createElement("strong", null, (_a2 = data.nodeData) == null ? void 0 : _a2.name), "?"), /* @__PURE__ */ React.createElement("p", { className: "text-[11px] text-slate-400 leading-tight" }, "Todas as conex\xF5es associadas tamb\xE9m ser\xE3o apagadas.")), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React.createElement(
344
+ "button",
345
+ {
346
+ onClick: () => setMenuView("main"),
347
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
348
+ },
349
+ "Cancelar"
350
+ ), /* @__PURE__ */ React.createElement(
351
+ "button",
352
+ {
353
+ onClick: () => onDeleteNode == null ? void 0 : onDeleteNode(data.nodeData),
354
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
355
+ },
356
+ "Excluir"
357
+ )));
358
+ };
341
359
  return /* @__PURE__ */ React.createElement(
342
360
  "div",
343
361
  {
@@ -353,7 +371,7 @@ function ContextMenu({
353
371
  onDoubleClick: swallow
354
372
  },
355
373
  /* @__PURE__ */ React.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
356
- /* @__PURE__ */ React.createElement("div", { className: "p-1.5" }, menuView === "main" && renderMainView(), menuView === "connections" && renderConnectionsView(), menuView === "ancestryActions" && renderAncestryActionsView(), menuView === "versioning" && renderVersioningView())
374
+ /* @__PURE__ */ React.createElement("div", { className: "p-1.5" }, menuView === "main" && renderMainView(), menuView === "connections" && renderConnectionsView(), menuView === "ancestryActions" && renderAncestryActionsView(), menuView === "versioning" && renderVersioningView(), menuView === "deleteConfirmation" && renderDeleteConfirmationView())
357
375
  );
358
376
  }
359
377
 
@@ -1535,7 +1553,6 @@ var userActionHandlers = {
1535
1553
  color: ghostColor,
1536
1554
  emissive: ghostEmissive,
1537
1555
  emissiveIntensity: MIN_VISIBILITY_INTENSITY,
1538
- // <-- Forçamos o brilho mínimo
1539
1556
  roughness: 0.6,
1540
1557
  metalness: 0,
1541
1558
  transparent: true,
@@ -1692,7 +1709,6 @@ var userActionHandlers = {
1692
1709
  color: ghostColor,
1693
1710
  emissive: ghostEmissive,
1694
1711
  emissiveIntensity: MIN_VISIBILITY_INTENSITY,
1695
- // <-- Forçamos o brilho mínimo
1696
1712
  roughness: 0.6,
1697
1713
  metalness: 0,
1698
1714
  transparent: true,
@@ -1989,9 +2005,7 @@ var userActionHandlers = {
1989
2005
  linkObject.visible = false;
1990
2006
  controls.enabled = false;
1991
2007
  if (mountRef.current) mountRef.current.style.cursor = "crosshair";
1992
- const tempMat = new LineMaterial({
1993
- /* ... material tracejado ... */
1994
- });
2008
+ const tempMat = new LineMaterial({});
1995
2009
  const tempGeom = new LineGeometry().setPositions([
1996
2010
  ...fixedNode.position.toArray(),
1997
2011
  ...fixedNode.position.toArray()
@@ -2120,9 +2134,6 @@ var userActionHandlers = {
2120
2134
  const { parentFileId, ownerId } = parentInfo;
2121
2135
  const srcName = ((_c = (_b = (_a = linkObject.userData) == null ? void 0 : _a.sourceNode) == null ? void 0 : _b.userData) == null ? void 0 : _c.name) ?? linkObject.userData.source;
2122
2136
  const tgtName = ((_f = (_e = (_d = linkObject.userData) == null ? void 0 : _d.targetNode) == null ? void 0 : _e.userData) == null ? void 0 : _f.name) ?? linkObject.userData.target;
2123
- if (!window.confirm(`Tem certeza que deseja excluir a conex\xE3o entre "${srcName}" \u2192 "${tgtName}"?`)) {
2124
- return;
2125
- }
2126
2137
  const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
2127
2138
  const newLinks = (specificParentData.links || []).filter((l) => String(l.id) !== String(linkIdToDelete));
2128
2139
  specificParentData.links = newLinks;
@@ -2276,9 +2287,6 @@ var userActionHandlers = {
2276
2287
  const { stateRef, graphDataRef, sceneDataRef, setters, actions } = context;
2277
2288
  setters.setMultiContextMenu({ visible: false });
2278
2289
  if (!nodeIds || nodeIds.size === 0 || !graphDataRef.current || !sceneDataRef.current) return;
2279
- if (!window.confirm(`Tem certeza que deseja excluir ${nodeIds.size} Nodes e todas as suas conex\xF5es? Esta a\xE7\xE3o \xE9 irrevers\xEDvel.`)) {
2280
- return;
2281
- }
2282
2290
  const strNodeIdsToDelete = Array.from(nodeIds).map(String);
2283
2291
  if (actions.delete_file) {
2284
2292
  strNodeIdsToDelete.forEach((id) => {
@@ -2359,9 +2367,6 @@ var userActionHandlers = {
2359
2367
  }
2360
2368
  setters.setContextMenu({ visible: false });
2361
2369
  if (!nodeData || !graphDataRef.current || !sceneDataRef.current) return;
2362
- if (!window.confirm(`Tem certeza que deseja excluir o Node "${nodeData.name}" e todas as sua conex\xF5es?`)) {
2363
- return;
2364
- }
2365
2370
  const nodeIdToDelete = nodeData.id;
2366
2371
  const strNodeId = String(nodeIdToDelete);
2367
2372
  const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete);
@@ -4319,8 +4324,7 @@ var CodeBlock2 = ({ content, isActive, onClick }) => {
4319
4324
  "button",
4320
4325
  {
4321
4326
  onClick: handleCopy,
4322
- 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",
4323
- 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"
4324
4328
  },
4325
4329
  copied ? /* @__PURE__ */ React6.createElement(FiCheck3, { size: 12, className: "text-emerald-400" }) : /* @__PURE__ */ React6.createElement(FiCopy2, { size: 12 }),
4326
4330
  copied ? /* @__PURE__ */ React6.createElement("span", { className: "text-emerald-400" }, "Copiado") : /* @__PURE__ */ React6.createElement("span", null, "Copiar")
@@ -4349,8 +4353,7 @@ var renderLinks = (text) => {
4349
4353
  target: "_blank",
4350
4354
  rel: "noopener noreferrer",
4351
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",
4352
- onClick: (e) => e.stopPropagation(),
4353
- title: `Abrir link externo: ${url}`
4356
+ onClick: (e) => e.stopPropagation()
4354
4357
  },
4355
4358
  part,
4356
4359
  /* @__PURE__ */ React6.createElement(FiExternalLink2, { size: 10, className: "opacity-70 mb-0.5" })
@@ -4379,8 +4382,7 @@ var renderTextWithImages = (text, onImageClick) => {
4379
4382
  e.stopPropagation();
4380
4383
  onImageClick == null ? void 0 : onImageClick(url, name);
4381
4384
  },
4382
- 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",
4383
- 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"
4384
4386
  },
4385
4387
  /* @__PURE__ */ React6.createElement(FiImage2, { size: 11 }),
4386
4388
  /* @__PURE__ */ React6.createElement("span", null, name)
@@ -4417,8 +4419,7 @@ var renderTextWithMentions = (text, availableNodes, onMentionClick, activeMentio
4417
4419
  className: `
4418
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]
4419
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"}
4420
- `,
4421
- title: `Clique para focar no Node: ${displayName}`
4422
+ `
4422
4423
  },
4423
4424
  /* @__PURE__ */ React6.createElement("span", { className: "opacity-60 text-[0.8em]" }, "@"),
4424
4425
  displayName
@@ -4492,7 +4493,9 @@ function DescriptionDisplay({
4492
4493
  onHighlightNode,
4493
4494
  initialSectionId,
4494
4495
  currentBranchDirection = null,
4495
- onSaveDescription
4496
+ onSaveDescription,
4497
+ onStepChange
4498
+ // 1. Adicione a nova prop aqui
4496
4499
  }) {
4497
4500
  const [localDescription, setLocalDescription] = useState7(description || "");
4498
4501
  useEffect6(() => {
@@ -4539,6 +4542,11 @@ function DescriptionDisplay({
4539
4542
  return navItems;
4540
4543
  }, [sections]);
4541
4544
  const [currentStepIndex, setCurrentStepIndex] = useState7(0);
4545
+ useEffect6(() => {
4546
+ if (onStepChange) {
4547
+ onStepChange(currentStepIndex);
4548
+ }
4549
+ }, [currentStepIndex, onStepChange]);
4542
4550
  const activeRef = useRef6(null);
4543
4551
  const lastNotifiedSectionId = useRef6(null);
4544
4552
  const isInitialMount = useRef6(true);
@@ -4690,8 +4698,7 @@ function DescriptionDisplay({
4690
4698
  if (onOpenReference) {
4691
4699
  onOpenReference({ type: resolved.type, id: resolved.sourceId });
4692
4700
  }
4693
- },
4694
- title: `Ir para ${resolved.type === "node" ? "Node" : "Ancestralidade"}: ${resolved.sourceName}`
4701
+ }
4695
4702
  },
4696
4703
  /* @__PURE__ */ React6.createElement(FiCornerDownRight, { size: 12, className: "text-indigo-400" }),
4697
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" }))
@@ -4840,6 +4847,7 @@ function DescriptionReadModePanel({
4840
4847
  const [showAbstraction, setShowAbstraction] = useState8(false);
4841
4848
  const [targetRenderNodeId, setTargetRenderNodeId] = useState8(null);
4842
4849
  const [isLinkCopied, setIsLinkCopied] = useState8(false);
4850
+ const [isAtStartOfBranch, setIsAtStartOfBranch] = useState8(true);
4843
4851
  const handleCopyLink = (e) => {
4844
4852
  e.stopPropagation();
4845
4853
  if (!ancestryId) return;
@@ -4892,7 +4900,7 @@ function DescriptionReadModePanel({
4892
4900
  onClick: () => onBranchNav(activeNodeBranches.nodeId, "open", "left")
4893
4901
  };
4894
4902
  }
4895
- if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "left") {
4903
+ if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "left" && isAtStartOfBranch) {
4896
4904
  return {
4897
4905
  type: "back",
4898
4906
  name: backNavigationInfo.name,
@@ -4900,7 +4908,7 @@ function DescriptionReadModePanel({
4900
4908
  };
4901
4909
  }
4902
4910
  return null;
4903
- }, [activeNodeBranches, backNavigationInfo, onBranchNav]);
4911
+ }, [activeNodeBranches, backNavigationInfo, onBranchNav, isAtStartOfBranch]);
4904
4912
  const rightAction = useMemo6(() => {
4905
4913
  if (activeNodeBranches == null ? void 0 : activeNodeBranches.right) {
4906
4914
  return {
@@ -4909,7 +4917,7 @@ function DescriptionReadModePanel({
4909
4917
  onClick: () => onBranchNav(activeNodeBranches.nodeId, "open", "right")
4910
4918
  };
4911
4919
  }
4912
- if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "right") {
4920
+ if ((backNavigationInfo == null ? void 0 : backNavigationInfo.trigger) === "right" && isAtStartOfBranch) {
4913
4921
  return {
4914
4922
  type: "back",
4915
4923
  name: backNavigationInfo.name,
@@ -4917,7 +4925,7 @@ function DescriptionReadModePanel({
4917
4925
  };
4918
4926
  }
4919
4927
  return null;
4920
- }, [activeNodeBranches, backNavigationInfo, onBranchNav]);
4928
+ }, [activeNodeBranches, backNavigationInfo, onBranchNav, isAtStartOfBranch]);
4921
4929
  return /* @__PURE__ */ React7.createElement(
4922
4930
  "div",
4923
4931
  {
@@ -5053,7 +5061,8 @@ function DescriptionReadModePanel({
5053
5061
  initialSectionId,
5054
5062
  currentBranchDirection,
5055
5063
  onImageClick,
5056
- onSaveDescription
5064
+ onSaveDescription,
5065
+ onStepChange: (stepIndex) => setIsAtStartOfBranch(stepIndex === 0)
5057
5066
  }
5058
5067
  )),
5059
5068
  leftAction && !showAbstraction && !showProperties && /* @__PURE__ */ React7.createElement(
@@ -5540,6 +5549,7 @@ function CreateAncestryPanel({
5540
5549
  }, [targetRenderNodeId, ancestryMode.abstraction_tree]);
5541
5550
  const [targetScrollSectionId, setTargetScrollSectionId] = useState11(null);
5542
5551
  const [internalHighlightedNodeId, setInternalHighlightedNodeId] = useState11(null);
5552
+ const [isAtStartOfBranch, setIsAtStartOfBranch] = useState11(true);
5543
5553
  const [ancestryName, setAncestryName] = useState11(initialName);
5544
5554
  const [description, setDescription] = useState11(initialDescription || "");
5545
5555
  const [existingSections, setExistingSections] = useState11(initialSections || []);
@@ -5971,7 +5981,7 @@ function CreateAncestryPanel({
5971
5981
  }
5972
5982
  return actions;
5973
5983
  }
5974
- if (isInBranch) {
5984
+ if (isInBranch && isAtStartOfBranch) {
5975
5985
  const lastStep = branchStack[branchStack.length - 1];
5976
5986
  const entryDir = lastStep.entryDirection || "right";
5977
5987
  const backSide = entryDir === "right" ? "left" : "right";
@@ -5982,7 +5992,7 @@ function CreateAncestryPanel({
5982
5992
  };
5983
5993
  }
5984
5994
  return actions;
5985
- }, [internalHighlightedNodeId, branchStack, activeTree]);
5995
+ }, [internalHighlightedNodeId, branchStack, activeTree, isAtStartOfBranch]);
5986
5996
  const applyDescriptionToTree = (baseTree, descText, descSections) => {
5987
5997
  const rootTreeClone = JSON.parse(JSON.stringify(baseTree));
5988
5998
  let targetTree = rootTreeClone;
@@ -6634,7 +6644,8 @@ function CreateAncestryPanel({
6634
6644
  initialSectionId: targetScrollSectionId,
6635
6645
  currentBranchDirection: currentContext ? currentContext.direction : null,
6636
6646
  onImageClick: handleImageClickFromText,
6637
- onSaveDescription: handleSaveDescriptionInline
6647
+ onSaveDescription: handleSaveDescriptionInline,
6648
+ onStepChange: (stepIndex) => setIsAtStartOfBranch(stepIndex === 0)
6638
6649
  }
6639
6650
  ), /* @__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(
6640
6651
  "button",
@@ -8160,7 +8171,6 @@ import React16, { useLayoutEffect as useLayoutEffect3, useRef as useRef13, useSt
8160
8171
  function MultiNodeContextMenu({
8161
8172
  data,
8162
8173
  userRole,
8163
- // 2. Recebendo a role do usuário nas props
8164
8174
  onClose,
8165
8175
  onDismissNodes,
8166
8176
  onDismissOtherNodes,
@@ -8168,6 +8178,7 @@ function MultiNodeContextMenu({
8168
8178
  }) {
8169
8179
  const menuRef = useRef13(null);
8170
8180
  const [menuPos, setMenuPos] = useState17({ left: 0, top: 0 });
8181
+ const [isConfirmingDelete, setIsConfirmingDelete] = useState17(false);
8171
8182
  const ability = defineAbilityFor(userRole);
8172
8183
  const canDelete = ability.can("delete", "Node");
8173
8184
  useLayoutEffect3(() => {
@@ -8184,7 +8195,9 @@ function MultiNodeContextMenu({
8184
8195
  setMenuPos({ left, top });
8185
8196
  }, [data]);
8186
8197
  useEffect16(() => {
8187
- if (!data.visible) return;
8198
+ if (data.visible) {
8199
+ setIsConfirmingDelete(false);
8200
+ }
8188
8201
  const handleClickOutside = (e) => {
8189
8202
  if (menuRef.current && !menuRef.current.contains(e.target)) onClose();
8190
8203
  };
@@ -8211,7 +8224,21 @@ function MultiNodeContextMenu({
8211
8224
  onDoubleClick: swallow
8212
8225
  },
8213
8226
  /* @__PURE__ */ React16.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
8214
- /* @__PURE__ */ React16.createElement("div", { className: "p-1.5" }, /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React16.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ React16.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ React16.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React16.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ React16.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" }, /* @__PURE__ */ React16.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ React16.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ React16.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ React16.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ React16.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ React16.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ React16.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" }, /* @__PURE__ */ React16.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ React16.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ React16.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React16.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ React16.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ React16.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React16.createElement("button", { onClick: () => onDeleteNodes(data.nodeIds), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ React16.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" }, /* @__PURE__ */ React16.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React16.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React16.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ React16.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ React16.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
8227
+ /* @__PURE__ */ React16.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ React16.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React16.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React16.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ React16.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React16.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React16.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ React16.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ React16.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ React16.createElement("p", { className: "text-[11px] text-slate-400 leading-tight" }, "Esta a\xE7\xE3o \xE9 irrevers\xEDvel. Todas as conex\xF5es associadas a eles ser\xE3o apagadas.")), /* @__PURE__ */ React16.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React16.createElement(
8228
+ "button",
8229
+ {
8230
+ onClick: () => setIsConfirmingDelete(false),
8231
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
8232
+ },
8233
+ "Cancelar"
8234
+ ), /* @__PURE__ */ React16.createElement(
8235
+ "button",
8236
+ {
8237
+ onClick: () => onDeleteNodes(data.nodeIds),
8238
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
8239
+ },
8240
+ "Excluir"
8241
+ ))) : /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React16.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ React16.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ React16.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React16.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ React16.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" }, /* @__PURE__ */ React16.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ React16.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ React16.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ React16.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ React16.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ React16.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ React16.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" }, /* @__PURE__ */ React16.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ React16.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ React16.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React16.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ React16.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ React16.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React16.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ React16.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" }, /* @__PURE__ */ React16.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React16.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React16.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ React16.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ React16.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
8215
8242
  );
8216
8243
  }
8217
8244
 
@@ -8452,7 +8479,6 @@ import React18, { useLayoutEffect as useLayoutEffect4, useRef as useRef15, useSt
8452
8479
  function RelationshipContextMenu({
8453
8480
  data,
8454
8481
  userRole,
8455
- // Recebemos a role do usuário para verificar permissões
8456
8482
  onRelinkSource,
8457
8483
  onRelinkTarget,
8458
8484
  onOpenDetails,
@@ -8461,6 +8487,7 @@ function RelationshipContextMenu({
8461
8487
  }) {
8462
8488
  const menuRef = useRef15(null);
8463
8489
  const [menuPos, setMenuPos] = useState19({ left: 0, top: 0 });
8490
+ const [isConfirmingDelete, setIsConfirmingDelete] = useState19(false);
8464
8491
  const ability = useMemo10(() => defineAbilityFor(userRole), [userRole]);
8465
8492
  const sourceName = useMemo10(
8466
8493
  () => {
@@ -8490,7 +8517,9 @@ function RelationshipContextMenu({
8490
8517
  setMenuPos({ left, top });
8491
8518
  }, [data]);
8492
8519
  useEffect18(() => {
8493
- if (!data.visible) return;
8520
+ if (data.visible) {
8521
+ setIsConfirmingDelete(false);
8522
+ }
8494
8523
  const handleClickOutside = (e) => {
8495
8524
  if (menuRef.current && !menuRef.current.contains(e.target)) onClose();
8496
8525
  };
@@ -8518,7 +8547,21 @@ function RelationshipContextMenu({
8518
8547
  onDoubleClick: swallow
8519
8548
  },
8520
8549
  /* @__PURE__ */ React18.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
8521
- /* @__PURE__ */ React18.createElement("div", { className: "p-1.5" }, /* @__PURE__ */ React18.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React18.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-teal-400/80 shadow-[0_0_12px_1px_rgba(45,212,191,0.5)]" }), /* @__PURE__ */ React18.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(
8550
+ /* @__PURE__ */ React18.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React18.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ React18.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React18.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React18.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ React18.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ React18.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ React18.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ React18.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ React18.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ React18.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ React18.createElement("strong", null, targetName), ".")), /* @__PURE__ */ React18.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React18.createElement(
8551
+ "button",
8552
+ {
8553
+ onClick: () => setIsConfirmingDelete(false),
8554
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
8555
+ },
8556
+ "Cancelar"
8557
+ ), /* @__PURE__ */ React18.createElement(
8558
+ "button",
8559
+ {
8560
+ onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
8561
+ className: "flex-1 px-2 py-2 text-xs font-medium bg-rose-600 hover:bg-rose-500 rounded-md text-white transition-colors"
8562
+ },
8563
+ "Excluir"
8564
+ ))) : /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React18.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-teal-400/80 shadow-[0_0_12px_1px_rgba(45,212,191,0.5)]" }), /* @__PURE__ */ React18.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(
8522
8565
  "button",
8523
8566
  {
8524
8567
  onClick: () => onRelinkSource == null ? void 0 : onRelinkSource(data.linkObject),
@@ -8597,7 +8640,7 @@ function RelationshipContextMenu({
8597
8640
  ), canDelete && /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ React18.createElement(
8598
8641
  "button",
8599
8642
  {
8600
- onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
8643
+ onClick: () => setIsConfirmingDelete(true),
8601
8644
  className: dangerButtonClass,
8602
8645
  title: "Excluir esta conex\xE3o"
8603
8646
  },
@@ -8621,7 +8664,7 @@ function RelationshipContextMenu({
8621
8664
  /* @__PURE__ */ React18.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
8622
8665
  ),
8623
8666
  /* @__PURE__ */ React18.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
8624
- ))))
8667
+ )))))
8625
8668
  );
8626
8669
  }
8627
8670
 
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.22",
3
+ "version": "1.2.2-dev.24",
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",