@lv-x-software-house/x_view 1.2.5-dev.1 → 1.2.5-dev.3

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
@@ -446,11 +446,18 @@ function ContextMenu({
446
446
  ))));
447
447
  };
448
448
  const renderAncestryActionsView = () => {
449
+ var _a2, _b2;
449
450
  const ancestryTitle = (selectedAncestry == null ? void 0 : selectedAncestry.name) || `Ancestralidade #${selectedAncestry == null ? void 0 : selectedAncestry.ancestry_id.substring(0, 8)}`;
450
- return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center justify-between gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("connections"), className: "p-1 rounded-full hover:bg-white/10 text-slate-400 hover:text-white flex-shrink-0" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "15 18 9 12 15 6" }))), /* @__PURE__ */ import_react.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400 truncate", title: ancestryTitle }, ancestryTitle))), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col gap-1" }, ability.can("read", "Ancestry") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
451
- onRenderAncestry == null ? void 0 : onRenderAncestry(selectedAncestry);
451
+ return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center justify-between gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("connections"), className: "p-1 rounded-full hover:bg-white/10 text-slate-400 hover:text-white flex-shrink-0" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "15 18 9 12 15 6" }))), /* @__PURE__ */ import_react.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400 truncate", title: ancestryTitle }, ancestryTitle))), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col gap-1" }, ability.can("read", "Ancestry") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
452
+ onRenderAncestry == null ? void 0 : onRenderAncestry(selectedAncestry, "full");
453
+ onClose();
454
+ }, className: baseButtonClass, title: "Renderizar Ancestralidade Completa" }, /* @__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: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Renderizar Ancestralidade")), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
455
+ onRenderAncestry == null ? void 0 : onRenderAncestry(selectedAncestry, "ancestry_only");
452
456
  onClose();
453
- }, className: baseButtonClass, title: "Renderizar 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: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Renderizar Ancestralidade")), ability.can("update", "Ancestry") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
457
+ }, className: baseButtonClass, title: "Renderizar apenas a \xC1rvore de Ancestralidade (Radial)" }, /* @__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: "M12 2v3m0 14v3m10-10h-3m-14 0H2m15.66-6.34-2.12 2.12m-9.08 9.08-2.12 2.12m13.32 0-2.12-2.12m-9.08-9.08-2.12-2.12" })), /* @__PURE__ */ import_react.default.createElement("span", null, "\xC1rvore de Ancestralidade")), ((_b2 = (_a2 = selectedAncestry == null ? void 0 : selectedAncestry.abstraction_tree) == null ? void 0 : _a2.children) == null ? void 0 : _b2.length) > 0 && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
458
+ onRenderAncestry == null ? void 0 : onRenderAncestry(selectedAncestry, "abstraction_only");
459
+ onClose();
460
+ }, className: baseButtonClass, title: "Renderizar apenas a \xC1rvore de Abstra\xE7\xE3o (Vertical)" }, /* @__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("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }), /* @__PURE__ */ import_react.default.createElement("rect", { x: "14", y: "3", width: "7", height: "7", rx: "1" }), /* @__PURE__ */ import_react.default.createElement("rect", { x: "14", y: "14", width: "7", height: "7", rx: "1" }), /* @__PURE__ */ import_react.default.createElement("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 6.5h4" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 17.5h4" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M6.5 10v4" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M17.5 10v4" })), /* @__PURE__ */ import_react.default.createElement("span", null, "\xC1rvore de Abstra\xE7\xE3o"))), ability.can("update", "Ancestry") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
454
461
  onEditAncestry == null ? void 0 : onEditAncestry(selectedAncestry);
455
462
  onClose();
456
463
  }, className: baseButtonClass, title: "Editar 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: "M12 20h9" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Editar Ancestralidade")), (ability.can("update", "Ancestry") || ability.can("delete", "Ancestry")) && /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), ability.can("delete", "Ancestry") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
@@ -10621,6 +10628,7 @@ function XViewScene({
10621
10628
  });
10622
10629
  const [isImportModalOpen, setIsImportModalOpen] = (0, import_react26.useState)(false);
10623
10630
  const [importSuccessMessage, setImportSuccessMessage] = (0, import_react26.useState)("");
10631
+ const [invalidTargetError, setInvalidTargetError] = (0, import_react26.useState)(null);
10624
10632
  const [highlightedNodeId, setHighlightedNodeId] = (0, import_react26.useState)(null);
10625
10633
  const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react26.useState)(false);
10626
10634
  const [ancestryBoardData, setAncestryBoardData] = (0, import_react26.useState)([]);
@@ -13522,7 +13530,7 @@ function XViewScene({
13522
13530
  sceneVersion
13523
13531
  ]);
13524
13532
  const handleStartReadingAncestry = (0, import_react26.useCallback)(
13525
- async (ancestryObject) => {
13533
+ async (ancestryObject, renderMode = "full") => {
13526
13534
  setContextMenu(
13527
13535
  (prev) => prev.visible ? { ...prev, visible: false } : prev
13528
13536
  );
@@ -13538,14 +13546,20 @@ function XViewScene({
13538
13546
  const hasDescription = ancestryObject.description && ancestryObject.description.trim() !== "";
13539
13547
  const hasMainTreeNodes = ancestryObject.tree.children && ancestryObject.tree.children.length > 0;
13540
13548
  const hasAbstractionNodes = ancestryObject.abstraction_tree && ancestryObject.abstraction_tree.children && ancestryObject.abstraction_tree.children.length > 0;
13541
- const shouldAutoRenderAbstraction = !hasDescription && !hasMainTreeNodes && hasAbstractionNodes;
13549
+ const isFull = renderMode === "full";
13550
+ const isAncestryOnly = renderMode === "ancestry_only";
13551
+ const isAbstractionOnly = renderMode === "abstraction_only";
13552
+ let shouldRenderAbstraction = isAbstractionOnly;
13553
+ if (isFull) {
13554
+ shouldRenderAbstraction = !hasDescription && !hasMainTreeNodes && hasAbstractionNodes;
13555
+ }
13542
13556
  setReadingMode({
13543
- isActive: hasDescription,
13557
+ isActive: isFull ? hasDescription : false,
13544
13558
  ancestry: ancestryObject,
13545
13559
  branchStack: [],
13546
- autoAbstraction: shouldAutoRenderAbstraction
13560
+ autoAbstraction: shouldRenderAbstraction
13547
13561
  });
13548
- if (shouldAutoRenderAbstraction) {
13562
+ if (shouldRenderAbstraction) {
13549
13563
  handleRenderAbstractionTree(ancestryObject, null);
13550
13564
  } else {
13551
13565
  const initialSections = /* @__PURE__ */ new Set(["preamble", 0, "0"]);
@@ -14291,6 +14305,9 @@ function XViewScene({
14291
14305
  }, 300);
14292
14306
  } else {
14293
14307
  setHasFocusedInitial(true);
14308
+ setInvalidTargetError(
14309
+ "O link aponta para um item que n\xE3o foi encontrado ou foi exclu\xEDdo."
14310
+ );
14294
14311
  }
14295
14312
  }
14296
14313
  }, [
@@ -14313,6 +14330,9 @@ function XViewScene({
14313
14330
  }, 300);
14314
14331
  } else {
14315
14332
  setHasOpenedInitialAncestry(true);
14333
+ setInvalidTargetError(
14334
+ "O link aponta para uma ancestralidade que n\xE3o foi encontrada ou foi exclu\xEDda."
14335
+ );
14316
14336
  }
14317
14337
  }
14318
14338
  }, [
@@ -14922,6 +14942,83 @@ function XViewScene({
14922
14942
  currentViewName: viewParams == null ? void 0 : viewParams.name,
14923
14943
  currentAncestries: ancestryDataRef.current || []
14924
14944
  }
14945
+ ),
14946
+ invalidTargetError && /* @__PURE__ */ import_react26.default.createElement(
14947
+ "div",
14948
+ {
14949
+ className: "ui-overlay",
14950
+ style: {
14951
+ position: "fixed",
14952
+ top: "24px",
14953
+ left: "50%",
14954
+ transform: "translateX(-50%)",
14955
+ zIndex: 1e4,
14956
+ padding: "16px 24px",
14957
+ background: "rgba(30, 20, 20, 0.85)",
14958
+ backdropFilter: "blur(12px)",
14959
+ WebkitBackdropFilter: "blur(12px)",
14960
+ border: "1px solid rgba(255, 70, 70, 0.35)",
14961
+ borderRadius: "16px",
14962
+ boxShadow: "0 12px 40px rgba(0,0,0,0.5), 0 0 30px rgba(255, 50, 50, 0.1)",
14963
+ color: "#ffa0a0",
14964
+ display: "flex",
14965
+ alignItems: "center",
14966
+ gap: "16px",
14967
+ fontFamily: "Inter, sans-serif",
14968
+ animation: "fadeInDown 0.5s cubic-bezier(0.16, 1, 0.3, 1)"
14969
+ }
14970
+ },
14971
+ /* @__PURE__ */ import_react26.default.createElement("style", null, `
14972
+ @keyframes fadeInDown {
14973
+ from { opacity: 0; transform: translate(-50%, -20px); }
14974
+ to { opacity: 1; transform: translate(-50%, 0); }
14975
+ }
14976
+ `),
14977
+ /* @__PURE__ */ import_react26.default.createElement(
14978
+ "svg",
14979
+ {
14980
+ width: "20",
14981
+ height: "20",
14982
+ viewBox: "0 0 24 24",
14983
+ fill: "none",
14984
+ stroke: "currentColor",
14985
+ strokeWidth: "2",
14986
+ strokeLinecap: "round",
14987
+ strokeLinejoin: "round"
14988
+ },
14989
+ /* @__PURE__ */ import_react26.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
14990
+ /* @__PURE__ */ import_react26.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
14991
+ /* @__PURE__ */ import_react26.default.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
14992
+ ),
14993
+ /* @__PURE__ */ import_react26.default.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
14994
+ /* @__PURE__ */ import_react26.default.createElement(
14995
+ "button",
14996
+ {
14997
+ onClick: () => setInvalidTargetError(null),
14998
+ style: {
14999
+ background: "rgba(255, 255, 255, 0.1)",
15000
+ border: "none",
15001
+ color: "white",
15002
+ padding: "4px 10px",
15003
+ borderRadius: "8px",
15004
+ cursor: "pointer",
15005
+ fontSize: "12px",
15006
+ fontWeight: 600,
15007
+ transition: "all 0.2s",
15008
+ marginLeft: "8px",
15009
+ border: "1px solid rgba(255,255,255,0.1)"
15010
+ },
15011
+ onMouseOver: (e) => {
15012
+ e.currentTarget.style.background = "rgba(255, 255, 255, 0.15)";
15013
+ e.currentTarget.style.transform = "translateY(-1px)";
15014
+ },
15015
+ onMouseOut: (e) => {
15016
+ e.currentTarget.style.background = "rgba(255, 255, 255, 0.1)";
15017
+ e.currentTarget.style.transform = "translateY(0)";
15018
+ }
15019
+ },
15020
+ "Fechar"
15021
+ )
14925
15022
  )
14926
15023
  );
14927
15024
  }
package/dist/index.mjs CHANGED
@@ -408,11 +408,18 @@ function ContextMenu({
408
408
  ))));
409
409
  };
410
410
  const renderAncestryActionsView = () => {
411
+ var _a2, _b2;
411
412
  const ancestryTitle = (selectedAncestry == null ? void 0 : selectedAncestry.name) || `Ancestralidade #${selectedAncestry == null ? void 0 : selectedAncestry.ancestry_id.substring(0, 8)}`;
412
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setMenuView("connections"), className: "p-1 rounded-full hover:bg-white/10 text-slate-400 hover:text-white flex-shrink-0" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("polyline", { points: "15 18 9 12 15 6" }))), /* @__PURE__ */ React.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400 truncate", title: ancestryTitle }, ancestryTitle))), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-1" }, ability.can("read", "Ancestry") && /* @__PURE__ */ React.createElement("button", { onClick: () => {
413
- onRenderAncestry == null ? void 0 : onRenderAncestry(selectedAncestry);
413
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setMenuView("connections"), className: "p-1 rounded-full hover:bg-white/10 text-slate-400 hover:text-white flex-shrink-0" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("polyline", { points: "15 18 9 12 15 6" }))), /* @__PURE__ */ React.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400 truncate", title: ancestryTitle }, ancestryTitle))), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-1" }, ability.can("read", "Ancestry") && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("button", { onClick: () => {
414
+ onRenderAncestry == null ? void 0 : onRenderAncestry(selectedAncestry, "full");
415
+ onClose();
416
+ }, className: baseButtonClass, title: "Renderizar Ancestralidade Completa" }, /* @__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: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" }), /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ React.createElement("span", null, "Renderizar Ancestralidade")), /* @__PURE__ */ React.createElement("button", { onClick: () => {
417
+ onRenderAncestry == null ? void 0 : onRenderAncestry(selectedAncestry, "ancestry_only");
414
418
  onClose();
415
- }, className: baseButtonClass, title: "Renderizar 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: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" }), /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ React.createElement("span", null, "Renderizar Ancestralidade")), ability.can("update", "Ancestry") && /* @__PURE__ */ React.createElement("button", { onClick: () => {
419
+ }, className: baseButtonClass, title: "Renderizar apenas a \xC1rvore de Ancestralidade (Radial)" }, /* @__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: "M12 2v3m0 14v3m10-10h-3m-14 0H2m15.66-6.34-2.12 2.12m-9.08 9.08-2.12 2.12m13.32 0-2.12-2.12m-9.08-9.08-2.12-2.12" })), /* @__PURE__ */ React.createElement("span", null, "\xC1rvore de Ancestralidade")), ((_b2 = (_a2 = selectedAncestry == null ? void 0 : selectedAncestry.abstraction_tree) == null ? void 0 : _a2.children) == null ? void 0 : _b2.length) > 0 && /* @__PURE__ */ React.createElement("button", { onClick: () => {
420
+ onRenderAncestry == null ? void 0 : onRenderAncestry(selectedAncestry, "abstraction_only");
421
+ onClose();
422
+ }, className: baseButtonClass, title: "Renderizar apenas a \xC1rvore de Abstra\xE7\xE3o (Vertical)" }, /* @__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("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }), /* @__PURE__ */ React.createElement("rect", { x: "14", y: "3", width: "7", height: "7", rx: "1" }), /* @__PURE__ */ React.createElement("rect", { x: "14", y: "14", width: "7", height: "7", rx: "1" }), /* @__PURE__ */ React.createElement("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }), /* @__PURE__ */ React.createElement("path", { d: "M10 6.5h4" }), /* @__PURE__ */ React.createElement("path", { d: "M10 17.5h4" }), /* @__PURE__ */ React.createElement("path", { d: "M6.5 10v4" }), /* @__PURE__ */ React.createElement("path", { d: "M17.5 10v4" })), /* @__PURE__ */ React.createElement("span", null, "\xC1rvore de Abstra\xE7\xE3o"))), ability.can("update", "Ancestry") && /* @__PURE__ */ React.createElement("button", { onClick: () => {
416
423
  onEditAncestry == null ? void 0 : onEditAncestry(selectedAncestry);
417
424
  onClose();
418
425
  }, className: baseButtonClass, title: "Editar 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: "M12 20h9" }), /* @__PURE__ */ React.createElement("path", { d: "M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" })), /* @__PURE__ */ React.createElement("span", null, "Editar Ancestralidade")), (ability.can("update", "Ancestry") || ability.can("delete", "Ancestry")) && /* @__PURE__ */ React.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), ability.can("delete", "Ancestry") && /* @__PURE__ */ React.createElement("button", { onClick: () => {
@@ -10627,6 +10634,7 @@ function XViewScene({
10627
10634
  });
10628
10635
  const [isImportModalOpen, setIsImportModalOpen] = useState25(false);
10629
10636
  const [importSuccessMessage, setImportSuccessMessage] = useState25("");
10637
+ const [invalidTargetError, setInvalidTargetError] = useState25(null);
10630
10638
  const [highlightedNodeId, setHighlightedNodeId] = useState25(null);
10631
10639
  const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState25(false);
10632
10640
  const [ancestryBoardData, setAncestryBoardData] = useState25([]);
@@ -13528,7 +13536,7 @@ function XViewScene({
13528
13536
  sceneVersion
13529
13537
  ]);
13530
13538
  const handleStartReadingAncestry = useCallback4(
13531
- async (ancestryObject) => {
13539
+ async (ancestryObject, renderMode = "full") => {
13532
13540
  setContextMenu(
13533
13541
  (prev) => prev.visible ? { ...prev, visible: false } : prev
13534
13542
  );
@@ -13544,14 +13552,20 @@ function XViewScene({
13544
13552
  const hasDescription = ancestryObject.description && ancestryObject.description.trim() !== "";
13545
13553
  const hasMainTreeNodes = ancestryObject.tree.children && ancestryObject.tree.children.length > 0;
13546
13554
  const hasAbstractionNodes = ancestryObject.abstraction_tree && ancestryObject.abstraction_tree.children && ancestryObject.abstraction_tree.children.length > 0;
13547
- const shouldAutoRenderAbstraction = !hasDescription && !hasMainTreeNodes && hasAbstractionNodes;
13555
+ const isFull = renderMode === "full";
13556
+ const isAncestryOnly = renderMode === "ancestry_only";
13557
+ const isAbstractionOnly = renderMode === "abstraction_only";
13558
+ let shouldRenderAbstraction = isAbstractionOnly;
13559
+ if (isFull) {
13560
+ shouldRenderAbstraction = !hasDescription && !hasMainTreeNodes && hasAbstractionNodes;
13561
+ }
13548
13562
  setReadingMode({
13549
- isActive: hasDescription,
13563
+ isActive: isFull ? hasDescription : false,
13550
13564
  ancestry: ancestryObject,
13551
13565
  branchStack: [],
13552
- autoAbstraction: shouldAutoRenderAbstraction
13566
+ autoAbstraction: shouldRenderAbstraction
13553
13567
  });
13554
- if (shouldAutoRenderAbstraction) {
13568
+ if (shouldRenderAbstraction) {
13555
13569
  handleRenderAbstractionTree(ancestryObject, null);
13556
13570
  } else {
13557
13571
  const initialSections = /* @__PURE__ */ new Set(["preamble", 0, "0"]);
@@ -14297,6 +14311,9 @@ function XViewScene({
14297
14311
  }, 300);
14298
14312
  } else {
14299
14313
  setHasFocusedInitial(true);
14314
+ setInvalidTargetError(
14315
+ "O link aponta para um item que n\xE3o foi encontrado ou foi exclu\xEDdo."
14316
+ );
14300
14317
  }
14301
14318
  }
14302
14319
  }, [
@@ -14319,6 +14336,9 @@ function XViewScene({
14319
14336
  }, 300);
14320
14337
  } else {
14321
14338
  setHasOpenedInitialAncestry(true);
14339
+ setInvalidTargetError(
14340
+ "O link aponta para uma ancestralidade que n\xE3o foi encontrada ou foi exclu\xEDda."
14341
+ );
14322
14342
  }
14323
14343
  }
14324
14344
  }, [
@@ -14928,6 +14948,83 @@ function XViewScene({
14928
14948
  currentViewName: viewParams == null ? void 0 : viewParams.name,
14929
14949
  currentAncestries: ancestryDataRef.current || []
14930
14950
  }
14951
+ ),
14952
+ invalidTargetError && /* @__PURE__ */ React25.createElement(
14953
+ "div",
14954
+ {
14955
+ className: "ui-overlay",
14956
+ style: {
14957
+ position: "fixed",
14958
+ top: "24px",
14959
+ left: "50%",
14960
+ transform: "translateX(-50%)",
14961
+ zIndex: 1e4,
14962
+ padding: "16px 24px",
14963
+ background: "rgba(30, 20, 20, 0.85)",
14964
+ backdropFilter: "blur(12px)",
14965
+ WebkitBackdropFilter: "blur(12px)",
14966
+ border: "1px solid rgba(255, 70, 70, 0.35)",
14967
+ borderRadius: "16px",
14968
+ boxShadow: "0 12px 40px rgba(0,0,0,0.5), 0 0 30px rgba(255, 50, 50, 0.1)",
14969
+ color: "#ffa0a0",
14970
+ display: "flex",
14971
+ alignItems: "center",
14972
+ gap: "16px",
14973
+ fontFamily: "Inter, sans-serif",
14974
+ animation: "fadeInDown 0.5s cubic-bezier(0.16, 1, 0.3, 1)"
14975
+ }
14976
+ },
14977
+ /* @__PURE__ */ React25.createElement("style", null, `
14978
+ @keyframes fadeInDown {
14979
+ from { opacity: 0; transform: translate(-50%, -20px); }
14980
+ to { opacity: 1; transform: translate(-50%, 0); }
14981
+ }
14982
+ `),
14983
+ /* @__PURE__ */ React25.createElement(
14984
+ "svg",
14985
+ {
14986
+ width: "20",
14987
+ height: "20",
14988
+ viewBox: "0 0 24 24",
14989
+ fill: "none",
14990
+ stroke: "currentColor",
14991
+ strokeWidth: "2",
14992
+ strokeLinecap: "round",
14993
+ strokeLinejoin: "round"
14994
+ },
14995
+ /* @__PURE__ */ React25.createElement("circle", { cx: "12", cy: "12", r: "10" }),
14996
+ /* @__PURE__ */ React25.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
14997
+ /* @__PURE__ */ React25.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
14998
+ ),
14999
+ /* @__PURE__ */ React25.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
15000
+ /* @__PURE__ */ React25.createElement(
15001
+ "button",
15002
+ {
15003
+ onClick: () => setInvalidTargetError(null),
15004
+ style: {
15005
+ background: "rgba(255, 255, 255, 0.1)",
15006
+ border: "none",
15007
+ color: "white",
15008
+ padding: "4px 10px",
15009
+ borderRadius: "8px",
15010
+ cursor: "pointer",
15011
+ fontSize: "12px",
15012
+ fontWeight: 600,
15013
+ transition: "all 0.2s",
15014
+ marginLeft: "8px",
15015
+ border: "1px solid rgba(255,255,255,0.1)"
15016
+ },
15017
+ onMouseOver: (e) => {
15018
+ e.currentTarget.style.background = "rgba(255, 255, 255, 0.15)";
15019
+ e.currentTarget.style.transform = "translateY(-1px)";
15020
+ },
15021
+ onMouseOut: (e) => {
15022
+ e.currentTarget.style.background = "rgba(255, 255, 255, 0.1)";
15023
+ e.currentTarget.style.transform = "translateY(0)";
15024
+ }
15025
+ },
15026
+ "Fechar"
15027
+ )
14931
15028
  )
14932
15029
  );
14933
15030
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lv-x-software-house/x_view",
3
- "version": "1.2.5-dev.1",
3
+ "version": "1.2.5-dev.3",
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",