@lv-x-software-house/x_view 1.2.1-dev.4 → 1.2.1-dev.6
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 +40 -25
- package/dist/index.mjs +40 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -131,6 +131,7 @@ function ContextMenu({
|
|
|
131
131
|
const [menuView, setMenuView] = (0, import_react.useState)("main");
|
|
132
132
|
const [selectedAncestry, setSelectedAncestry] = (0, import_react.useState)(null);
|
|
133
133
|
const [versionSubMenu, setVersionSubMenu] = (0, import_react.useState)(null);
|
|
134
|
+
const [isLinkCopied, setIsLinkCopied] = (0, import_react.useState)(false);
|
|
134
135
|
const ability = (0, import_react.useMemo)(() => defineAbilityFor(userRole), [userRole]);
|
|
135
136
|
(0, import_react.useEffect)(() => {
|
|
136
137
|
if (data.visible) {
|
|
@@ -267,15 +268,18 @@ function ContextMenu({
|
|
|
267
268
|
return ((_a2 = node.version_node) == null ? void 0 : _a2.is_version) && String(node.version_node.parent_node) === String(data.nodeData.id);
|
|
268
269
|
}
|
|
269
270
|
).sort((a, b) => getYearFromDate(b.Date) - getYearFromDate(a.Date));
|
|
270
|
-
const handleCopyLink = (nodeData) => {
|
|
271
|
+
const handleCopyLink = (e, nodeData) => {
|
|
272
|
+
e.stopPropagation();
|
|
271
273
|
const baseUrl = window.location.origin + window.location.pathname;
|
|
272
274
|
const fullUrl = `${baseUrl}?focus=${nodeData.id}`;
|
|
273
275
|
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
+
setIsLinkCopied(true);
|
|
277
|
+
setTimeout(() => {
|
|
278
|
+
setIsLinkCopied(false);
|
|
279
|
+
onClose();
|
|
280
|
+
}, 1500);
|
|
276
281
|
}).catch((err) => {
|
|
277
282
|
console.error("Erro ao copiar link:", err);
|
|
278
|
-
alert("N\xE3o foi poss\xEDvel copiar o link.");
|
|
279
283
|
});
|
|
280
284
|
};
|
|
281
285
|
const renderMainView = () => {
|
|
@@ -286,7 +290,7 @@ function ContextMenu({
|
|
|
286
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" }, /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
|
|
287
291
|
onFocusNode == null ? void 0 : onFocusNode(data.nodeData);
|
|
288
292
|
onClose();
|
|
289
|
-
}, 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: () => handleCopyLink(data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, /* @__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, "Copiar Link")), 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" }), 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("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" }), 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"))));
|
|
290
294
|
};
|
|
291
295
|
const renderVersionSubMenuView = () => {
|
|
292
296
|
const group = versionSubMenu;
|
|
@@ -7285,6 +7289,7 @@ function NodeDetailsPanel({
|
|
|
7285
7289
|
const [isReadMode, setIsReadMode] = (0, import_react15.useState)(false);
|
|
7286
7290
|
const [existingSections, setExistingSections] = (0, import_react15.useState)((node == null ? void 0 : node.description_sections) || []);
|
|
7287
7291
|
const [isSaving, setIsSaving] = (0, import_react15.useState)(false);
|
|
7292
|
+
const [isLinkCopied, setIsLinkCopied] = (0, import_react15.useState)(false);
|
|
7288
7293
|
const [useImageAsTexture, setUseImageAsTexture] = (0, import_react15.useState)(() => {
|
|
7289
7294
|
if ((node == null ? void 0 : node.useImageAsTexture) === "true") return true;
|
|
7290
7295
|
if ((node == null ? void 0 : node.useImageAsTexture) === "false") return false;
|
|
@@ -7351,7 +7356,10 @@ function NodeDetailsPanel({
|
|
|
7351
7356
|
const baseUrl = window.location.origin + window.location.pathname;
|
|
7352
7357
|
const fullUrl = `${baseUrl}?focus=${node.id}`;
|
|
7353
7358
|
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
7354
|
-
|
|
7359
|
+
setIsLinkCopied(true);
|
|
7360
|
+
setTimeout(() => setIsLinkCopied(false), 2e3);
|
|
7361
|
+
}).catch((err) => {
|
|
7362
|
+
console.error("Erro ao copiar link:", err);
|
|
7355
7363
|
});
|
|
7356
7364
|
};
|
|
7357
7365
|
const swallow = (e) => e.stopPropagation();
|
|
@@ -7527,7 +7535,15 @@ function NodeDetailsPanel({
|
|
|
7527
7535
|
onMentionClick,
|
|
7528
7536
|
onImageClick: handleImageClickFromText
|
|
7529
7537
|
}
|
|
7530
|
-
) : /* @__PURE__ */ import_react15.default.createElement(import_react15.default.Fragment, null, /* @__PURE__ */ import_react15.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ import_react15.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react15.default.createElement("div", null, /* @__PURE__ */ import_react15.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react15.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ import_react15.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ import_react15.default.createElement(
|
|
7538
|
+
) : /* @__PURE__ */ import_react15.default.createElement(import_react15.default.Fragment, null, /* @__PURE__ */ import_react15.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ import_react15.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react15.default.createElement("div", null, /* @__PURE__ */ import_react15.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react15.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ import_react15.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ import_react15.default.createElement(
|
|
7539
|
+
"button",
|
|
7540
|
+
{
|
|
7541
|
+
onClick: handleCopyLink,
|
|
7542
|
+
className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
|
|
7543
|
+
title: isLinkCopied ? "Link Copiado!" : "Copiar link para este Node"
|
|
7544
|
+
},
|
|
7545
|
+
isLinkCopied ? /* @__PURE__ */ import_react15.default.createElement(import_fi14.FiCheck, { size: 12 }) : /* @__PURE__ */ import_react15.default.createElement(import_fi14.FiLink, { size: 12 })
|
|
7546
|
+
)), /* @__PURE__ */ import_react15.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ import_react15.default.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl disabled:opacity-50", title: "Cancelar" }, "\xD7")), /* @__PURE__ */ import_react15.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react15.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react15.default.createElement("label", { className: "text-xs text-slate-300" }, "Tipos"), /* @__PURE__ */ import_react15.default.createElement("div", { className: `relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 ${canEdit ? "focus-within:ring-2 focus-within:ring-indigo-400/60" : ""} transition-all` }, types.map((t, index) => /* @__PURE__ */ import_react15.default.createElement("span", { key: index, className: "flex items-center gap-1 bg-indigo-500/30 text-indigo-100 px-1.5 py-0.5 rounded-md text-xs font-medium border border-indigo-500/20" }, t, canEdit && /* @__PURE__ */ import_react15.default.createElement(
|
|
7531
7547
|
"button",
|
|
7532
7548
|
{
|
|
7533
7549
|
type: "button",
|
|
@@ -9641,12 +9657,20 @@ function XViewScene({
|
|
|
9641
9657
|
const boardPromise = get_ancestry_board_action && session ? get_ancestry_board_action(configPath, sceneType, session, ownerId2) : Promise.resolve({ success: false, data: [] });
|
|
9642
9658
|
const [sceneResponse, boardResponse] = await Promise.all([scenePromise, boardPromise]);
|
|
9643
9659
|
if ((sceneResponse == null ? void 0 : sceneResponse.success) && ((_a2 = sceneResponse.data) == null ? void 0 : _a2.scene) && ((_b2 = sceneResponse.data) == null ? void 0 : _b2.parent)) {
|
|
9660
|
+
if (focusNodeId) {
|
|
9661
|
+
let targetNode = sceneResponse.data.scene.nodes.find((n) => String(n.id) === String(focusNodeId));
|
|
9662
|
+
if (!targetNode) {
|
|
9663
|
+
const allParentNodes = Object.values(sceneResponse.data.parent).flatMap((f) => f.nodes || []);
|
|
9664
|
+
targetNode = allParentNodes.find((n) => String(n.id) === String(focusNodeId));
|
|
9665
|
+
}
|
|
9666
|
+
if (targetNode) {
|
|
9667
|
+
sceneResponse.data.scene.nodes = [targetNode];
|
|
9668
|
+
sceneResponse.data.scene.links = [];
|
|
9669
|
+
}
|
|
9670
|
+
}
|
|
9644
9671
|
sceneDataRef.current = sceneResponse.data.scene;
|
|
9645
9672
|
parentDataRef.current = sceneResponse.data.parent;
|
|
9646
9673
|
ancestryDataRef.current = sceneResponse.data.ancestry;
|
|
9647
|
-
console.log("Console de sceneDataRef.current no useEffect inicial:", sceneDataRef.current);
|
|
9648
|
-
console.log("Console de parentDataRef.current no useEffect inicial:", parentDataRef.current);
|
|
9649
|
-
console.log("Console de ancestryDataRef.current no useEffect inicial:", ancestryDataRef.current);
|
|
9650
9674
|
setIsInitialized(true);
|
|
9651
9675
|
} else {
|
|
9652
9676
|
console.error("Falha ao buscar dados da cena:", (sceneResponse == null ? void 0 : sceneResponse.error) || "Resposta inv\xE1lida.");
|
|
@@ -9654,7 +9678,6 @@ function XViewScene({
|
|
|
9654
9678
|
if (boardResponse == null ? void 0 : boardResponse.success) {
|
|
9655
9679
|
setAncestryBoardData(boardResponse.data);
|
|
9656
9680
|
} else {
|
|
9657
|
-
console.warn("Ancestry Board n\xE3o carregado ou vazio:", boardResponse == null ? void 0 : boardResponse.error);
|
|
9658
9681
|
setAncestryBoardData([]);
|
|
9659
9682
|
}
|
|
9660
9683
|
} catch (error) {
|
|
@@ -9678,11 +9701,12 @@ function XViewScene({
|
|
|
9678
9701
|
status,
|
|
9679
9702
|
ownerId,
|
|
9680
9703
|
viewParams,
|
|
9681
|
-
// Importante incluir viewParams nas dependências
|
|
9682
9704
|
get_scene_view_data,
|
|
9683
9705
|
get_ancestry_board_action,
|
|
9684
9706
|
isInitialized,
|
|
9685
|
-
permissionStatus
|
|
9707
|
+
permissionStatus,
|
|
9708
|
+
focusNodeId
|
|
9709
|
+
// <-- ADICIONADO O focusNodeId NAS DEPENDÊNCIAS
|
|
9686
9710
|
]);
|
|
9687
9711
|
const isNodeInView = (0, import_react23.useCallback)((id) => {
|
|
9688
9712
|
const key = String(id);
|
|
@@ -11974,21 +11998,12 @@ function XViewScene({
|
|
|
11974
11998
|
setTimeout(() => {
|
|
11975
11999
|
tweenToTarget(targetMesh, 1.2);
|
|
11976
12000
|
setHasFocusedInitial(true);
|
|
11977
|
-
},
|
|
12001
|
+
}, 300);
|
|
11978
12002
|
} else {
|
|
11979
|
-
|
|
11980
|
-
const nodeExistsInDb = allParentNodes.find((n) => String(n.id) === String(focusNodeId));
|
|
11981
|
-
if (nodeExistsInDb) {
|
|
11982
|
-
setTimeout(() => {
|
|
11983
|
-
handleAddExistingNode(focusNodeId);
|
|
11984
|
-
setHasFocusedInitial(true);
|
|
11985
|
-
}, 800);
|
|
11986
|
-
} else if (Object.keys(nodeObjects).length > 0) {
|
|
11987
|
-
setHasFocusedInitial(true);
|
|
11988
|
-
}
|
|
12003
|
+
setHasFocusedInitial(true);
|
|
11989
12004
|
}
|
|
11990
12005
|
}
|
|
11991
|
-
}, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget
|
|
12006
|
+
}, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
|
|
11992
12007
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
11993
12008
|
return /* @__PURE__ */ import_react23.default.createElement(LoadingScreen, null);
|
|
11994
12009
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -87,6 +87,7 @@ function ContextMenu({
|
|
|
87
87
|
const [menuView, setMenuView] = useState("main");
|
|
88
88
|
const [selectedAncestry, setSelectedAncestry] = useState(null);
|
|
89
89
|
const [versionSubMenu, setVersionSubMenu] = useState(null);
|
|
90
|
+
const [isLinkCopied, setIsLinkCopied] = useState(false);
|
|
90
91
|
const ability = useMemo(() => defineAbilityFor(userRole), [userRole]);
|
|
91
92
|
useEffect(() => {
|
|
92
93
|
if (data.visible) {
|
|
@@ -223,15 +224,18 @@ function ContextMenu({
|
|
|
223
224
|
return ((_a2 = node.version_node) == null ? void 0 : _a2.is_version) && String(node.version_node.parent_node) === String(data.nodeData.id);
|
|
224
225
|
}
|
|
225
226
|
).sort((a, b) => getYearFromDate(b.Date) - getYearFromDate(a.Date));
|
|
226
|
-
const handleCopyLink = (nodeData) => {
|
|
227
|
+
const handleCopyLink = (e, nodeData) => {
|
|
228
|
+
e.stopPropagation();
|
|
227
229
|
const baseUrl = window.location.origin + window.location.pathname;
|
|
228
230
|
const fullUrl = `${baseUrl}?focus=${nodeData.id}`;
|
|
229
231
|
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
+
setIsLinkCopied(true);
|
|
233
|
+
setTimeout(() => {
|
|
234
|
+
setIsLinkCopied(false);
|
|
235
|
+
onClose();
|
|
236
|
+
}, 1500);
|
|
232
237
|
}).catch((err) => {
|
|
233
238
|
console.error("Erro ao copiar link:", err);
|
|
234
|
-
alert("N\xE3o foi poss\xEDvel copiar o link.");
|
|
235
239
|
});
|
|
236
240
|
};
|
|
237
241
|
const renderMainView = () => {
|
|
@@ -242,7 +246,7 @@ function ContextMenu({
|
|
|
242
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" }, /* @__PURE__ */ React.createElement("button", { onClick: () => {
|
|
243
247
|
onFocusNode == null ? void 0 : onFocusNode(data.nodeData);
|
|
244
248
|
onClose();
|
|
245
|
-
}, 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: () => handleCopyLink(data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, /* @__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",
|
|
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("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" }), 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"))));
|
|
246
250
|
};
|
|
247
251
|
const renderVersionSubMenuView = () => {
|
|
248
252
|
const group = versionSubMenu;
|
|
@@ -7268,6 +7272,7 @@ function NodeDetailsPanel({
|
|
|
7268
7272
|
const [isReadMode, setIsReadMode] = useState15(false);
|
|
7269
7273
|
const [existingSections, setExistingSections] = useState15((node == null ? void 0 : node.description_sections) || []);
|
|
7270
7274
|
const [isSaving, setIsSaving] = useState15(false);
|
|
7275
|
+
const [isLinkCopied, setIsLinkCopied] = useState15(false);
|
|
7271
7276
|
const [useImageAsTexture, setUseImageAsTexture] = useState15(() => {
|
|
7272
7277
|
if ((node == null ? void 0 : node.useImageAsTexture) === "true") return true;
|
|
7273
7278
|
if ((node == null ? void 0 : node.useImageAsTexture) === "false") return false;
|
|
@@ -7334,7 +7339,10 @@ function NodeDetailsPanel({
|
|
|
7334
7339
|
const baseUrl = window.location.origin + window.location.pathname;
|
|
7335
7340
|
const fullUrl = `${baseUrl}?focus=${node.id}`;
|
|
7336
7341
|
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
7337
|
-
|
|
7342
|
+
setIsLinkCopied(true);
|
|
7343
|
+
setTimeout(() => setIsLinkCopied(false), 2e3);
|
|
7344
|
+
}).catch((err) => {
|
|
7345
|
+
console.error("Erro ao copiar link:", err);
|
|
7338
7346
|
});
|
|
7339
7347
|
};
|
|
7340
7348
|
const swallow = (e) => e.stopPropagation();
|
|
@@ -7510,7 +7518,15 @@ function NodeDetailsPanel({
|
|
|
7510
7518
|
onMentionClick,
|
|
7511
7519
|
onImageClick: handleImageClickFromText
|
|
7512
7520
|
}
|
|
7513
|
-
) : /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ React15.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React15.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ React15.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ React15.createElement(
|
|
7521
|
+
) : /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ React15.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React15.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ React15.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ React15.createElement(
|
|
7522
|
+
"button",
|
|
7523
|
+
{
|
|
7524
|
+
onClick: handleCopyLink,
|
|
7525
|
+
className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
|
|
7526
|
+
title: isLinkCopied ? "Link Copiado!" : "Copiar link para este Node"
|
|
7527
|
+
},
|
|
7528
|
+
isLinkCopied ? /* @__PURE__ */ React15.createElement(FiCheck8, { size: 12 }) : /* @__PURE__ */ React15.createElement(FiLink3, { size: 12 })
|
|
7529
|
+
)), /* @__PURE__ */ React15.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ React15.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl disabled:opacity-50", title: "Cancelar" }, "\xD7")), /* @__PURE__ */ React15.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tipos"), /* @__PURE__ */ React15.createElement("div", { className: `relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 ${canEdit ? "focus-within:ring-2 focus-within:ring-indigo-400/60" : ""} transition-all` }, types.map((t, index) => /* @__PURE__ */ React15.createElement("span", { key: index, className: "flex items-center gap-1 bg-indigo-500/30 text-indigo-100 px-1.5 py-0.5 rounded-md text-xs font-medium border border-indigo-500/20" }, t, canEdit && /* @__PURE__ */ React15.createElement(
|
|
7514
7530
|
"button",
|
|
7515
7531
|
{
|
|
7516
7532
|
type: "button",
|
|
@@ -9637,12 +9653,20 @@ function XViewScene({
|
|
|
9637
9653
|
const boardPromise = get_ancestry_board_action && session ? get_ancestry_board_action(configPath, sceneType, session, ownerId2) : Promise.resolve({ success: false, data: [] });
|
|
9638
9654
|
const [sceneResponse, boardResponse] = await Promise.all([scenePromise, boardPromise]);
|
|
9639
9655
|
if ((sceneResponse == null ? void 0 : sceneResponse.success) && ((_a2 = sceneResponse.data) == null ? void 0 : _a2.scene) && ((_b2 = sceneResponse.data) == null ? void 0 : _b2.parent)) {
|
|
9656
|
+
if (focusNodeId) {
|
|
9657
|
+
let targetNode = sceneResponse.data.scene.nodes.find((n) => String(n.id) === String(focusNodeId));
|
|
9658
|
+
if (!targetNode) {
|
|
9659
|
+
const allParentNodes = Object.values(sceneResponse.data.parent).flatMap((f) => f.nodes || []);
|
|
9660
|
+
targetNode = allParentNodes.find((n) => String(n.id) === String(focusNodeId));
|
|
9661
|
+
}
|
|
9662
|
+
if (targetNode) {
|
|
9663
|
+
sceneResponse.data.scene.nodes = [targetNode];
|
|
9664
|
+
sceneResponse.data.scene.links = [];
|
|
9665
|
+
}
|
|
9666
|
+
}
|
|
9640
9667
|
sceneDataRef.current = sceneResponse.data.scene;
|
|
9641
9668
|
parentDataRef.current = sceneResponse.data.parent;
|
|
9642
9669
|
ancestryDataRef.current = sceneResponse.data.ancestry;
|
|
9643
|
-
console.log("Console de sceneDataRef.current no useEffect inicial:", sceneDataRef.current);
|
|
9644
|
-
console.log("Console de parentDataRef.current no useEffect inicial:", parentDataRef.current);
|
|
9645
|
-
console.log("Console de ancestryDataRef.current no useEffect inicial:", ancestryDataRef.current);
|
|
9646
9670
|
setIsInitialized(true);
|
|
9647
9671
|
} else {
|
|
9648
9672
|
console.error("Falha ao buscar dados da cena:", (sceneResponse == null ? void 0 : sceneResponse.error) || "Resposta inv\xE1lida.");
|
|
@@ -9650,7 +9674,6 @@ function XViewScene({
|
|
|
9650
9674
|
if (boardResponse == null ? void 0 : boardResponse.success) {
|
|
9651
9675
|
setAncestryBoardData(boardResponse.data);
|
|
9652
9676
|
} else {
|
|
9653
|
-
console.warn("Ancestry Board n\xE3o carregado ou vazio:", boardResponse == null ? void 0 : boardResponse.error);
|
|
9654
9677
|
setAncestryBoardData([]);
|
|
9655
9678
|
}
|
|
9656
9679
|
} catch (error) {
|
|
@@ -9674,11 +9697,12 @@ function XViewScene({
|
|
|
9674
9697
|
status,
|
|
9675
9698
|
ownerId,
|
|
9676
9699
|
viewParams,
|
|
9677
|
-
// Importante incluir viewParams nas dependências
|
|
9678
9700
|
get_scene_view_data,
|
|
9679
9701
|
get_ancestry_board_action,
|
|
9680
9702
|
isInitialized,
|
|
9681
|
-
permissionStatus
|
|
9703
|
+
permissionStatus,
|
|
9704
|
+
focusNodeId
|
|
9705
|
+
// <-- ADICIONADO O focusNodeId NAS DEPENDÊNCIAS
|
|
9682
9706
|
]);
|
|
9683
9707
|
const isNodeInView = useCallback3((id) => {
|
|
9684
9708
|
const key = String(id);
|
|
@@ -11970,21 +11994,12 @@ function XViewScene({
|
|
|
11970
11994
|
setTimeout(() => {
|
|
11971
11995
|
tweenToTarget(targetMesh, 1.2);
|
|
11972
11996
|
setHasFocusedInitial(true);
|
|
11973
|
-
},
|
|
11997
|
+
}, 300);
|
|
11974
11998
|
} else {
|
|
11975
|
-
|
|
11976
|
-
const nodeExistsInDb = allParentNodes.find((n) => String(n.id) === String(focusNodeId));
|
|
11977
|
-
if (nodeExistsInDb) {
|
|
11978
|
-
setTimeout(() => {
|
|
11979
|
-
handleAddExistingNode(focusNodeId);
|
|
11980
|
-
setHasFocusedInitial(true);
|
|
11981
|
-
}, 800);
|
|
11982
|
-
} else if (Object.keys(nodeObjects).length > 0) {
|
|
11983
|
-
setHasFocusedInitial(true);
|
|
11984
|
-
}
|
|
11999
|
+
setHasFocusedInitial(true);
|
|
11985
12000
|
}
|
|
11986
12001
|
}
|
|
11987
|
-
}, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget
|
|
12002
|
+
}, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
|
|
11988
12003
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
11989
12004
|
return /* @__PURE__ */ React23.createElement(LoadingScreen, null);
|
|
11990
12005
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lv-x-software-house/x_view",
|
|
3
|
-
"version": "1.2.1-dev.
|
|
3
|
+
"version": "1.2.1-dev.6",
|
|
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",
|