@lv-x-software-house/x_view 1.1.9 → 1.2.1-dev.2
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 +67 -16
- package/dist/index.mjs +69 -18
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -267,6 +267,17 @@ function ContextMenu({
|
|
|
267
267
|
return ((_a2 = node.version_node) == null ? void 0 : _a2.is_version) && String(node.version_node.parent_node) === String(data.nodeData.id);
|
|
268
268
|
}
|
|
269
269
|
).sort((a, b) => getYearFromDate(b.Date) - getYearFromDate(a.Date));
|
|
270
|
+
const handleCopyLink = (nodeData) => {
|
|
271
|
+
const baseUrl = window.location.origin + window.location.pathname;
|
|
272
|
+
const fullUrl = `${baseUrl}?focus=${nodeData.id}`;
|
|
273
|
+
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
274
|
+
alert("Link do Node copiado para a \xE1rea de transfer\xEAncia!");
|
|
275
|
+
onClose();
|
|
276
|
+
}).catch((err) => {
|
|
277
|
+
console.error("Erro ao copiar link:", err);
|
|
278
|
+
alert("N\xE3o foi poss\xEDvel copiar o link.");
|
|
279
|
+
});
|
|
280
|
+
};
|
|
270
281
|
const renderMainView = () => {
|
|
271
282
|
const hasVersions = computedVersions.length > 0;
|
|
272
283
|
const canCreateVersion = ability.can("create", "Versioning");
|
|
@@ -275,7 +286,7 @@ function ContextMenu({
|
|
|
275
286
|
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: () => {
|
|
276
287
|
onFocusNode == null ? void 0 : onFocusNode(data.nodeData);
|
|
277
288
|
onClose();
|
|
278
|
-
}, 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")), 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
|
|
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"))));
|
|
279
290
|
};
|
|
280
291
|
const renderVersionSubMenuView = () => {
|
|
281
292
|
const group = versionSubMenu;
|
|
@@ -4552,13 +4563,20 @@ function DescriptionReadModePanel({
|
|
|
4552
4563
|
customProperties = [],
|
|
4553
4564
|
onImageClick,
|
|
4554
4565
|
userRole,
|
|
4555
|
-
// --- NOVAS PROPS PARA ABSTRAÇÃO ---
|
|
4556
4566
|
abstractionTree = null,
|
|
4557
|
-
onRenderAbstractionTree = null
|
|
4567
|
+
onRenderAbstractionTree = null,
|
|
4568
|
+
initialShowAbstraction = false
|
|
4569
|
+
// <--- NOVA PROP RECEBIDA
|
|
4558
4570
|
}) {
|
|
4559
4571
|
const [showProperties, setShowProperties] = (0, import_react7.useState)(false);
|
|
4560
4572
|
const [showAbstraction, setShowAbstraction] = (0, import_react7.useState)(false);
|
|
4561
4573
|
const [targetRenderNodeId, setTargetRenderNodeId] = (0, import_react7.useState)(null);
|
|
4574
|
+
import_react7.default.useEffect(() => {
|
|
4575
|
+
setShowAbstraction(initialShowAbstraction);
|
|
4576
|
+
if (initialShowAbstraction) {
|
|
4577
|
+
setShowProperties(false);
|
|
4578
|
+
}
|
|
4579
|
+
}, [initialShowAbstraction]);
|
|
4562
4580
|
const swallow = (e) => e.stopPropagation();
|
|
4563
4581
|
const hasCustomProps = customProperties && customProperties.length > 0;
|
|
4564
4582
|
const hasAbstraction = Boolean(abstractionTree && (abstractionTree.node || abstractionTree.children && abstractionTree.children.length > 0));
|
|
@@ -7252,7 +7270,6 @@ function NodeDetailsPanel({
|
|
|
7252
7270
|
onIntensityChange,
|
|
7253
7271
|
onUploadFile,
|
|
7254
7272
|
userRole
|
|
7255
|
-
// <--- ADIÇÃO: Recebendo a prop userRole
|
|
7256
7273
|
}) {
|
|
7257
7274
|
const [name, setName] = (0, import_react15.useState)((node == null ? void 0 : node.name) ?? "");
|
|
7258
7275
|
const [types, setTypes] = (0, import_react15.useState)([]);
|
|
@@ -7329,6 +7346,14 @@ function NodeDetailsPanel({
|
|
|
7329
7346
|
onIntensityChange == null ? void 0 : onIntensityChange(node.id, val);
|
|
7330
7347
|
onDataUpdate == null ? void 0 : onDataUpdate({ ...node, intensity: val });
|
|
7331
7348
|
};
|
|
7349
|
+
const handleCopyLink = () => {
|
|
7350
|
+
if (!(node == null ? void 0 : node.id)) return;
|
|
7351
|
+
const baseUrl = window.location.origin + window.location.pathname;
|
|
7352
|
+
const fullUrl = `${baseUrl}?focus=${node.id}`;
|
|
7353
|
+
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
7354
|
+
alert("Link copiado! Cole onde desejar.");
|
|
7355
|
+
});
|
|
7356
|
+
};
|
|
7332
7357
|
const swallow = (e) => e.stopPropagation();
|
|
7333
7358
|
const handleNameChange = (e) => {
|
|
7334
7359
|
const v = e.target.value;
|
|
@@ -7502,7 +7527,7 @@ function NodeDetailsPanel({
|
|
|
7502
7527
|
onMentionClick,
|
|
7503
7528
|
onImageClick: handleImageClickFromText
|
|
7504
7529
|
}
|
|
7505
|
-
) : /* @__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("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(
|
|
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("button", { onClick: handleCopyLink, className: "ml-1 p-1 text-slate-400 hover:text-indigo-400 transition-colors", title: "Copiar link para este Node" }, /* @__PURE__ */ import_react15.default.createElement(import_fi14.FiLink, { size: 12 }))), /* @__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(
|
|
7506
7531
|
"button",
|
|
7507
7532
|
{
|
|
7508
7533
|
type: "button",
|
|
@@ -7655,8 +7680,7 @@ function NodeDetailsPanel({
|
|
|
7655
7680
|
isSaving && /* @__PURE__ */ import_react15.default.createElement(import_fi14.FiLoader, { className: "animate-spin" }),
|
|
7656
7681
|
isSaving ? "Salvando..." : "Salvar"
|
|
7657
7682
|
)))
|
|
7658
|
-
), isDescriptionModalOpen && canEdit &&
|
|
7659
|
-
/* @__PURE__ */ import_react15.default.createElement(
|
|
7683
|
+
), isDescriptionModalOpen && canEdit && /* @__PURE__ */ import_react15.default.createElement(
|
|
7660
7684
|
DescriptionEditModal,
|
|
7661
7685
|
{
|
|
7662
7686
|
isOpen: isDescriptionModalOpen,
|
|
@@ -8968,6 +8992,8 @@ function XViewScene({
|
|
|
8968
8992
|
var _a, _b, _c, _d, _e, _f;
|
|
8969
8993
|
const { data: session, status } = (0, import_react24.useSession)();
|
|
8970
8994
|
const router = (0, import_navigation.useRouter)();
|
|
8995
|
+
const searchParams = (0, import_navigation.useSearchParams)();
|
|
8996
|
+
const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
|
|
8971
8997
|
const viewParams = (0, import_react23.useMemo)(() => {
|
|
8972
8998
|
if (encryptedConfig) {
|
|
8973
8999
|
const data = decryptData(encryptedConfig);
|
|
@@ -9034,11 +9060,13 @@ function XViewScene({
|
|
|
9034
9060
|
const [relationshipMenu, setRelationshipMenu] = (0, import_react23.useState)({ visible: false, x: 0, y: 0, linkObject: null });
|
|
9035
9061
|
const [creationMode, setCreationMode] = (0, import_react23.useState)({ isActive: false, sourceNodeData: null });
|
|
9036
9062
|
const [versionMode, setVersionMode] = (0, import_react23.useState)({ isActive: false, sourceNodeData: null });
|
|
9063
|
+
const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react23.useState)(false);
|
|
9037
9064
|
const [ancestryMode, setAncestryMode] = (0, import_react23.useState)({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
9038
9065
|
const [readingMode, setReadingMode] = (0, import_react23.useState)({
|
|
9039
9066
|
isActive: false,
|
|
9040
9067
|
ancestry: null,
|
|
9041
|
-
branchStack: []
|
|
9068
|
+
branchStack: [],
|
|
9069
|
+
autoAbstraction: false
|
|
9042
9070
|
});
|
|
9043
9071
|
const [formPosition, setFormPosition] = (0, import_react23.useState)({ left: 16, top: 16, opacity: 0 });
|
|
9044
9072
|
const [detailsNode, setDetailsNode] = (0, import_react23.useState)(null);
|
|
@@ -9097,6 +9125,17 @@ function XViewScene({
|
|
|
9097
9125
|
(0, import_react23.useEffect)(() => {
|
|
9098
9126
|
stateRef.current.ancestry = ancestryMode;
|
|
9099
9127
|
}, [ancestryMode]);
|
|
9128
|
+
(0, import_react23.useEffect)(() => {
|
|
9129
|
+
if (isInitialized && focusNodeId && !hasFocusedInitial && stateRef.current.nodeObjects) {
|
|
9130
|
+
const targetMesh = stateRef.current.nodeObjects[String(focusNodeId)];
|
|
9131
|
+
if (targetMesh) {
|
|
9132
|
+
setTimeout(() => {
|
|
9133
|
+
tweenToTarget(targetMesh, 1.2);
|
|
9134
|
+
setHasFocusedInitial(true);
|
|
9135
|
+
}, 800);
|
|
9136
|
+
}
|
|
9137
|
+
}
|
|
9138
|
+
}, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
|
|
9100
9139
|
(0, import_react23.useEffect)(() => {
|
|
9101
9140
|
var _a2;
|
|
9102
9141
|
if (!isInitialized) return;
|
|
@@ -11341,19 +11380,30 @@ function XViewScene({
|
|
|
11341
11380
|
currentMaxIndex: 0,
|
|
11342
11381
|
progressMap: {}
|
|
11343
11382
|
};
|
|
11383
|
+
const hasDescription = ancestryObject.description && ancestryObject.description.trim() !== "";
|
|
11384
|
+
const hasMainTreeNodes = ancestryObject.tree.children && ancestryObject.tree.children.length > 0;
|
|
11385
|
+
const hasAbstractionNodes = ancestryObject.abstraction_tree && ancestryObject.abstraction_tree.children && ancestryObject.abstraction_tree.children.length > 0;
|
|
11386
|
+
const shouldAutoRenderAbstraction = !hasDescription && !hasMainTreeNodes && hasAbstractionNodes;
|
|
11344
11387
|
setReadingMode({
|
|
11345
11388
|
isActive: true,
|
|
11346
11389
|
ancestry: ancestryObject,
|
|
11347
|
-
branchStack: []
|
|
11390
|
+
branchStack: [],
|
|
11391
|
+
autoAbstraction: shouldAutoRenderAbstraction
|
|
11392
|
+
// <--- FLAG ENVIADA PARA A UI
|
|
11348
11393
|
});
|
|
11349
|
-
|
|
11350
|
-
|
|
11351
|
-
|
|
11352
|
-
|
|
11353
|
-
|
|
11354
|
-
|
|
11394
|
+
if (shouldAutoRenderAbstraction) {
|
|
11395
|
+
handleRenderAbstractionTree(ancestryObject, null);
|
|
11396
|
+
} else {
|
|
11397
|
+
const initialSections = /* @__PURE__ */ new Set(["preamble", 0, "0"]);
|
|
11398
|
+
const ancestryWithForceUpdate = {
|
|
11399
|
+
...ancestryObject,
|
|
11400
|
+
_forceUpdate: true
|
|
11401
|
+
};
|
|
11402
|
+
await handleRenderAncestry(ancestryWithForceUpdate, initialSections);
|
|
11403
|
+
}
|
|
11355
11404
|
},
|
|
11356
|
-
[handleRenderAncestry]
|
|
11405
|
+
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
11406
|
+
// <--- DEPENDÊNCIA ADICIONADA
|
|
11357
11407
|
);
|
|
11358
11408
|
const handleReadModeSectionChange = (0, import_react23.useCallback)((activeSectionId) => {
|
|
11359
11409
|
const { ancestry, branchStack } = readingMode;
|
|
@@ -12026,6 +12076,7 @@ function XViewScene({
|
|
|
12026
12076
|
description: getReadModeDisplayContext == null ? void 0 : getReadModeDisplayContext.description,
|
|
12027
12077
|
savedSections: getReadModeDisplayContext == null ? void 0 : getReadModeDisplayContext.description_sections,
|
|
12028
12078
|
customProperties: (getReadModeDisplayContext == null ? void 0 : getReadModeDisplayContext.customProperties) || [],
|
|
12079
|
+
initialShowAbstraction: readingMode.autoAbstraction,
|
|
12029
12080
|
onBack: null,
|
|
12030
12081
|
onEdit: () => {
|
|
12031
12082
|
handleCloseReadMode();
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/XViewScene.jsx
|
|
2
2
|
import React23, { useCallback as useCallback3, useEffect as useEffect20, useRef as useRef17, useState as useState22, useMemo as useMemo12 } from "react";
|
|
3
|
-
import { useRouter } from "next/navigation";
|
|
3
|
+
import { useRouter, useSearchParams } from "next/navigation";
|
|
4
4
|
import { useSession } from "next-auth/react";
|
|
5
5
|
import CryptoJS from "crypto-js";
|
|
6
6
|
import * as THREE3 from "three";
|
|
@@ -223,6 +223,17 @@ function ContextMenu({
|
|
|
223
223
|
return ((_a2 = node.version_node) == null ? void 0 : _a2.is_version) && String(node.version_node.parent_node) === String(data.nodeData.id);
|
|
224
224
|
}
|
|
225
225
|
).sort((a, b) => getYearFromDate(b.Date) - getYearFromDate(a.Date));
|
|
226
|
+
const handleCopyLink = (nodeData) => {
|
|
227
|
+
const baseUrl = window.location.origin + window.location.pathname;
|
|
228
|
+
const fullUrl = `${baseUrl}?focus=${nodeData.id}`;
|
|
229
|
+
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
230
|
+
alert("Link do Node copiado para a \xE1rea de transfer\xEAncia!");
|
|
231
|
+
onClose();
|
|
232
|
+
}).catch((err) => {
|
|
233
|
+
console.error("Erro ao copiar link:", err);
|
|
234
|
+
alert("N\xE3o foi poss\xEDvel copiar o link.");
|
|
235
|
+
});
|
|
236
|
+
};
|
|
226
237
|
const renderMainView = () => {
|
|
227
238
|
const hasVersions = computedVersions.length > 0;
|
|
228
239
|
const canCreateVersion = ability.can("create", "Versioning");
|
|
@@ -231,7 +242,7 @@ function ContextMenu({
|
|
|
231
242
|
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: () => {
|
|
232
243
|
onFocusNode == null ? void 0 : onFocusNode(data.nodeData);
|
|
233
244
|
onClose();
|
|
234
|
-
}, 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")), 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
|
|
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", null, "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"))));
|
|
235
246
|
};
|
|
236
247
|
const renderVersionSubMenuView = () => {
|
|
237
248
|
const group = versionSubMenu;
|
|
@@ -4520,13 +4531,20 @@ function DescriptionReadModePanel({
|
|
|
4520
4531
|
customProperties = [],
|
|
4521
4532
|
onImageClick,
|
|
4522
4533
|
userRole,
|
|
4523
|
-
// --- NOVAS PROPS PARA ABSTRAÇÃO ---
|
|
4524
4534
|
abstractionTree = null,
|
|
4525
|
-
onRenderAbstractionTree = null
|
|
4535
|
+
onRenderAbstractionTree = null,
|
|
4536
|
+
initialShowAbstraction = false
|
|
4537
|
+
// <--- NOVA PROP RECEBIDA
|
|
4526
4538
|
}) {
|
|
4527
4539
|
const [showProperties, setShowProperties] = useState7(false);
|
|
4528
4540
|
const [showAbstraction, setShowAbstraction] = useState7(false);
|
|
4529
4541
|
const [targetRenderNodeId, setTargetRenderNodeId] = useState7(null);
|
|
4542
|
+
React7.useEffect(() => {
|
|
4543
|
+
setShowAbstraction(initialShowAbstraction);
|
|
4544
|
+
if (initialShowAbstraction) {
|
|
4545
|
+
setShowProperties(false);
|
|
4546
|
+
}
|
|
4547
|
+
}, [initialShowAbstraction]);
|
|
4530
4548
|
const swallow = (e) => e.stopPropagation();
|
|
4531
4549
|
const hasCustomProps = customProperties && customProperties.length > 0;
|
|
4532
4550
|
const hasAbstraction = Boolean(abstractionTree && (abstractionTree.node || abstractionTree.children && abstractionTree.children.length > 0));
|
|
@@ -7216,7 +7234,7 @@ function InSceneVersionForm({
|
|
|
7216
7234
|
|
|
7217
7235
|
// src/components/NodeDetailsPanel.jsx
|
|
7218
7236
|
import React15, { useState as useState15, useEffect as useEffect14, useRef as useRef12 } from "react";
|
|
7219
|
-
import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize23, FiX as FiX4, FiCheck as FiCheck8, FiImage as FiImage3, FiEdit2 as FiEdit26, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2 } from "react-icons/fi";
|
|
7237
|
+
import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize23, FiX as FiX4, FiCheck as FiCheck8, FiImage as FiImage3, FiEdit2 as FiEdit26, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink3 } from "react-icons/fi";
|
|
7220
7238
|
function NodeDetailsPanel({
|
|
7221
7239
|
node,
|
|
7222
7240
|
onClose,
|
|
@@ -7235,7 +7253,6 @@ function NodeDetailsPanel({
|
|
|
7235
7253
|
onIntensityChange,
|
|
7236
7254
|
onUploadFile,
|
|
7237
7255
|
userRole
|
|
7238
|
-
// <--- ADIÇÃO: Recebendo a prop userRole
|
|
7239
7256
|
}) {
|
|
7240
7257
|
const [name, setName] = useState15((node == null ? void 0 : node.name) ?? "");
|
|
7241
7258
|
const [types, setTypes] = useState15([]);
|
|
@@ -7312,6 +7329,14 @@ function NodeDetailsPanel({
|
|
|
7312
7329
|
onIntensityChange == null ? void 0 : onIntensityChange(node.id, val);
|
|
7313
7330
|
onDataUpdate == null ? void 0 : onDataUpdate({ ...node, intensity: val });
|
|
7314
7331
|
};
|
|
7332
|
+
const handleCopyLink = () => {
|
|
7333
|
+
if (!(node == null ? void 0 : node.id)) return;
|
|
7334
|
+
const baseUrl = window.location.origin + window.location.pathname;
|
|
7335
|
+
const fullUrl = `${baseUrl}?focus=${node.id}`;
|
|
7336
|
+
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
7337
|
+
alert("Link copiado! Cole onde desejar.");
|
|
7338
|
+
});
|
|
7339
|
+
};
|
|
7315
7340
|
const swallow = (e) => e.stopPropagation();
|
|
7316
7341
|
const handleNameChange = (e) => {
|
|
7317
7342
|
const v = e.target.value;
|
|
@@ -7485,7 +7510,7 @@ function NodeDetailsPanel({
|
|
|
7485
7510
|
onMentionClick,
|
|
7486
7511
|
onImageClick: handleImageClickFromText
|
|
7487
7512
|
}
|
|
7488
|
-
) : /* @__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("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(
|
|
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("button", { onClick: handleCopyLink, className: "ml-1 p-1 text-slate-400 hover:text-indigo-400 transition-colors", title: "Copiar link para este Node" }, /* @__PURE__ */ React15.createElement(FiLink3, { size: 12 }))), /* @__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(
|
|
7489
7514
|
"button",
|
|
7490
7515
|
{
|
|
7491
7516
|
type: "button",
|
|
@@ -7638,8 +7663,7 @@ function NodeDetailsPanel({
|
|
|
7638
7663
|
isSaving && /* @__PURE__ */ React15.createElement(FiLoader2, { className: "animate-spin" }),
|
|
7639
7664
|
isSaving ? "Salvando..." : "Salvar"
|
|
7640
7665
|
)))
|
|
7641
|
-
), isDescriptionModalOpen && canEdit &&
|
|
7642
|
-
/* @__PURE__ */ React15.createElement(
|
|
7666
|
+
), isDescriptionModalOpen && canEdit && /* @__PURE__ */ React15.createElement(
|
|
7643
7667
|
DescriptionEditModal,
|
|
7644
7668
|
{
|
|
7645
7669
|
isOpen: isDescriptionModalOpen,
|
|
@@ -8964,6 +8988,8 @@ function XViewScene({
|
|
|
8964
8988
|
var _a, _b, _c, _d, _e, _f;
|
|
8965
8989
|
const { data: session, status } = useSession();
|
|
8966
8990
|
const router = useRouter();
|
|
8991
|
+
const searchParams = useSearchParams();
|
|
8992
|
+
const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
|
|
8967
8993
|
const viewParams = useMemo12(() => {
|
|
8968
8994
|
if (encryptedConfig) {
|
|
8969
8995
|
const data = decryptData(encryptedConfig);
|
|
@@ -9030,11 +9056,13 @@ function XViewScene({
|
|
|
9030
9056
|
const [relationshipMenu, setRelationshipMenu] = useState22({ visible: false, x: 0, y: 0, linkObject: null });
|
|
9031
9057
|
const [creationMode, setCreationMode] = useState22({ isActive: false, sourceNodeData: null });
|
|
9032
9058
|
const [versionMode, setVersionMode] = useState22({ isActive: false, sourceNodeData: null });
|
|
9059
|
+
const [hasFocusedInitial, setHasFocusedInitial] = useState22(false);
|
|
9033
9060
|
const [ancestryMode, setAncestryMode] = useState22({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
9034
9061
|
const [readingMode, setReadingMode] = useState22({
|
|
9035
9062
|
isActive: false,
|
|
9036
9063
|
ancestry: null,
|
|
9037
|
-
branchStack: []
|
|
9064
|
+
branchStack: [],
|
|
9065
|
+
autoAbstraction: false
|
|
9038
9066
|
});
|
|
9039
9067
|
const [formPosition, setFormPosition] = useState22({ left: 16, top: 16, opacity: 0 });
|
|
9040
9068
|
const [detailsNode, setDetailsNode] = useState22(null);
|
|
@@ -9093,6 +9121,17 @@ function XViewScene({
|
|
|
9093
9121
|
useEffect20(() => {
|
|
9094
9122
|
stateRef.current.ancestry = ancestryMode;
|
|
9095
9123
|
}, [ancestryMode]);
|
|
9124
|
+
useEffect20(() => {
|
|
9125
|
+
if (isInitialized && focusNodeId && !hasFocusedInitial && stateRef.current.nodeObjects) {
|
|
9126
|
+
const targetMesh = stateRef.current.nodeObjects[String(focusNodeId)];
|
|
9127
|
+
if (targetMesh) {
|
|
9128
|
+
setTimeout(() => {
|
|
9129
|
+
tweenToTarget(targetMesh, 1.2);
|
|
9130
|
+
setHasFocusedInitial(true);
|
|
9131
|
+
}, 800);
|
|
9132
|
+
}
|
|
9133
|
+
}
|
|
9134
|
+
}, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
|
|
9096
9135
|
useEffect20(() => {
|
|
9097
9136
|
var _a2;
|
|
9098
9137
|
if (!isInitialized) return;
|
|
@@ -11337,19 +11376,30 @@ function XViewScene({
|
|
|
11337
11376
|
currentMaxIndex: 0,
|
|
11338
11377
|
progressMap: {}
|
|
11339
11378
|
};
|
|
11379
|
+
const hasDescription = ancestryObject.description && ancestryObject.description.trim() !== "";
|
|
11380
|
+
const hasMainTreeNodes = ancestryObject.tree.children && ancestryObject.tree.children.length > 0;
|
|
11381
|
+
const hasAbstractionNodes = ancestryObject.abstraction_tree && ancestryObject.abstraction_tree.children && ancestryObject.abstraction_tree.children.length > 0;
|
|
11382
|
+
const shouldAutoRenderAbstraction = !hasDescription && !hasMainTreeNodes && hasAbstractionNodes;
|
|
11340
11383
|
setReadingMode({
|
|
11341
11384
|
isActive: true,
|
|
11342
11385
|
ancestry: ancestryObject,
|
|
11343
|
-
branchStack: []
|
|
11386
|
+
branchStack: [],
|
|
11387
|
+
autoAbstraction: shouldAutoRenderAbstraction
|
|
11388
|
+
// <--- FLAG ENVIADA PARA A UI
|
|
11344
11389
|
});
|
|
11345
|
-
|
|
11346
|
-
|
|
11347
|
-
|
|
11348
|
-
|
|
11349
|
-
|
|
11350
|
-
|
|
11390
|
+
if (shouldAutoRenderAbstraction) {
|
|
11391
|
+
handleRenderAbstractionTree(ancestryObject, null);
|
|
11392
|
+
} else {
|
|
11393
|
+
const initialSections = /* @__PURE__ */ new Set(["preamble", 0, "0"]);
|
|
11394
|
+
const ancestryWithForceUpdate = {
|
|
11395
|
+
...ancestryObject,
|
|
11396
|
+
_forceUpdate: true
|
|
11397
|
+
};
|
|
11398
|
+
await handleRenderAncestry(ancestryWithForceUpdate, initialSections);
|
|
11399
|
+
}
|
|
11351
11400
|
},
|
|
11352
|
-
[handleRenderAncestry]
|
|
11401
|
+
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
11402
|
+
// <--- DEPENDÊNCIA ADICIONADA
|
|
11353
11403
|
);
|
|
11354
11404
|
const handleReadModeSectionChange = useCallback3((activeSectionId) => {
|
|
11355
11405
|
const { ancestry, branchStack } = readingMode;
|
|
@@ -12022,6 +12072,7 @@ function XViewScene({
|
|
|
12022
12072
|
description: getReadModeDisplayContext == null ? void 0 : getReadModeDisplayContext.description,
|
|
12023
12073
|
savedSections: getReadModeDisplayContext == null ? void 0 : getReadModeDisplayContext.description_sections,
|
|
12024
12074
|
customProperties: (getReadModeDisplayContext == null ? void 0 : getReadModeDisplayContext.customProperties) || [],
|
|
12075
|
+
initialShowAbstraction: readingMode.autoAbstraction,
|
|
12025
12076
|
onBack: null,
|
|
12026
12077
|
onEdit: () => {
|
|
12027
12078
|
handleCloseReadMode();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lv-x-software-house/x_view",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.2.1-dev.2",
|
|
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",
|