@lv-x-software-house/x_view 1.1.9-dev.1 → 1.1.9-dev.11
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 +376 -154
- package/dist/index.mjs +381 -157
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -122,6 +122,7 @@ function ContextMenu({
|
|
|
122
122
|
onRenderAncestry,
|
|
123
123
|
onEditAncestry,
|
|
124
124
|
onDeleteAncestry,
|
|
125
|
+
onFocusNode,
|
|
125
126
|
onClose
|
|
126
127
|
}) {
|
|
127
128
|
var _a, _b;
|
|
@@ -271,7 +272,10 @@ function ContextMenu({
|
|
|
271
272
|
const canCreateVersion = ability.can("create", "Versioning");
|
|
272
273
|
const canReadVersion = ability.can("read", "Versioning");
|
|
273
274
|
const shouldShowVersioningBtn = canCreateVersion || canReadVersion && hasVersions;
|
|
274
|
-
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" },
|
|
275
|
+
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
|
+
onFocusNode == null ? void 0 : onFocusNode(data.nodeData);
|
|
277
|
+
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.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"))));
|
|
275
279
|
};
|
|
276
280
|
const renderVersionSubMenuView = () => {
|
|
277
281
|
const group = versionSubMenu;
|
|
@@ -2698,7 +2702,10 @@ var IGNORED_KEYS = [
|
|
|
2698
2702
|
"isAddingNodes",
|
|
2699
2703
|
"ancestryDescriptionSections",
|
|
2700
2704
|
"direction",
|
|
2701
|
-
"is_private"
|
|
2705
|
+
"is_private",
|
|
2706
|
+
"abstraction_tree",
|
|
2707
|
+
"selectedAbstractionParentId",
|
|
2708
|
+
"isAddingAbstractionNodes"
|
|
2702
2709
|
];
|
|
2703
2710
|
function extractCustomPropsFromNode(node) {
|
|
2704
2711
|
const customPropTypes = node._customPropTypes || {};
|
|
@@ -4464,6 +4471,65 @@ function DescriptionDisplay({
|
|
|
4464
4471
|
// src/components/DescriptionReadModePanel.jsx
|
|
4465
4472
|
var import_react7 = __toESM(require("react"));
|
|
4466
4473
|
var import_fi6 = require("react-icons/fi");
|
|
4474
|
+
var findNodePath = (tree, targetNodeId, currentPath = []) => {
|
|
4475
|
+
var _a;
|
|
4476
|
+
if (!tree) return null;
|
|
4477
|
+
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
4478
|
+
if (String(currentNodeId) === String(targetNodeId)) {
|
|
4479
|
+
return { node: tree, path: currentPath };
|
|
4480
|
+
}
|
|
4481
|
+
if (tree.children) {
|
|
4482
|
+
for (let i = 0; i < tree.children.length; i++) {
|
|
4483
|
+
const res = findNodePath(tree.children[i], targetNodeId, [...currentPath, i]);
|
|
4484
|
+
if (res) return res;
|
|
4485
|
+
}
|
|
4486
|
+
}
|
|
4487
|
+
return null;
|
|
4488
|
+
};
|
|
4489
|
+
var ReadOnlyNodeItem = ({ nodeData, onViewSelect, highlightedPathIds = [], targetRenderNodeId, level = 0, isLast = false }) => {
|
|
4490
|
+
var _a, _b;
|
|
4491
|
+
const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
|
|
4492
|
+
const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
|
|
4493
|
+
const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
|
|
4494
|
+
const isHighlightedPath = highlightedPathIds.includes(String(itemId));
|
|
4495
|
+
const hasChildren = nodeData.children && nodeData.children.length > 0;
|
|
4496
|
+
let itemBgClass = "bg-slate-900/50 hover:bg-slate-800/80";
|
|
4497
|
+
let textColorClass = "text-slate-200";
|
|
4498
|
+
if (nodeData.is_section) {
|
|
4499
|
+
itemBgClass = "bg-purple-900/20 border border-purple-500/30 hover:bg-purple-900/40";
|
|
4500
|
+
textColorClass = "text-purple-300";
|
|
4501
|
+
} else {
|
|
4502
|
+
if (isTargetViewNode) {
|
|
4503
|
+
itemBgClass = "bg-fuchsia-600/40 ring-2 ring-fuchsia-400 shadow-[0_0_15px_rgba(217,70,239,0.3)]";
|
|
4504
|
+
textColorClass = "text-white font-bold";
|
|
4505
|
+
} else if (isHighlightedPath) {
|
|
4506
|
+
itemBgClass = "bg-fuchsia-900/30 border border-fuchsia-500/40";
|
|
4507
|
+
textColorClass = "text-fuchsia-200 font-semibold";
|
|
4508
|
+
}
|
|
4509
|
+
}
|
|
4510
|
+
return /* @__PURE__ */ import_react7.default.createElement("div", { className: "relative" }, level > 0 && /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement("span", { className: `absolute -left-4 top-0 w-px ${isHighlightedPath ? "bg-fuchsia-500 shadow-[0_0_8px_rgba(217,70,239,0.8)]" : "bg-cyan-600/60"} ${isLast ? "h-[1.125rem]" : "h-full"}`, "aria-hidden": "true" }), /* @__PURE__ */ import_react7.default.createElement("span", { className: `absolute -left-4 top-[1.125rem] h-px w-4 ${isHighlightedPath ? "bg-fuchsia-500 shadow-[0_0_8px_rgba(217,70,239,0.8)]" : "bg-cyan-600/60"}`, "aria-hidden": "true" })), /* @__PURE__ */ import_react7.default.createElement(
|
|
4511
|
+
"div",
|
|
4512
|
+
{
|
|
4513
|
+
onClick: (e) => {
|
|
4514
|
+
e.stopPropagation();
|
|
4515
|
+
if (onViewSelect) onViewSelect(itemId);
|
|
4516
|
+
},
|
|
4517
|
+
className: `flex items-center justify-between gap-2 px-3 h-9 rounded-md transition-all duration-150 border border-transparent cursor-pointer ${itemBgClass}`
|
|
4518
|
+
},
|
|
4519
|
+
/* @__PURE__ */ import_react7.default.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ import_react7.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", className: "mr-1.5 inline-block" }, /* @__PURE__ */ import_react7.default.createElement("circle", { cx: "9", cy: "9", r: "7" }), /* @__PURE__ */ import_react7.default.createElement("circle", { cx: "15", cy: "15", r: "7" })), nodeData.is_section && /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiFolder, { className: "mr-2" }), itemName)
|
|
4520
|
+
), hasChildren && /* @__PURE__ */ import_react7.default.createElement("div", { className: "mt-2 space-y-2 pl-8" }, nodeData.children.map((child, index) => /* @__PURE__ */ import_react7.default.createElement(
|
|
4521
|
+
ReadOnlyNodeItem,
|
|
4522
|
+
{
|
|
4523
|
+
key: `${child.is_section ? child.id : child.node.id}-${index}`,
|
|
4524
|
+
nodeData: child,
|
|
4525
|
+
onViewSelect,
|
|
4526
|
+
highlightedPathIds,
|
|
4527
|
+
targetRenderNodeId,
|
|
4528
|
+
level: level + 1,
|
|
4529
|
+
isLast: index === nodeData.children.length - 1
|
|
4530
|
+
}
|
|
4531
|
+
))));
|
|
4532
|
+
};
|
|
4467
4533
|
function DescriptionReadModePanel({
|
|
4468
4534
|
title,
|
|
4469
4535
|
description,
|
|
@@ -4485,14 +4551,40 @@ function DescriptionReadModePanel({
|
|
|
4485
4551
|
backNavigationInfo,
|
|
4486
4552
|
customProperties = [],
|
|
4487
4553
|
onImageClick,
|
|
4488
|
-
userRole
|
|
4489
|
-
//
|
|
4554
|
+
userRole,
|
|
4555
|
+
// --- NOVAS PROPS PARA ABSTRAÇÃO ---
|
|
4556
|
+
abstractionTree = null,
|
|
4557
|
+
onRenderAbstractionTree = null
|
|
4490
4558
|
}) {
|
|
4491
4559
|
const [showProperties, setShowProperties] = (0, import_react7.useState)(false);
|
|
4560
|
+
const [showAbstraction, setShowAbstraction] = (0, import_react7.useState)(false);
|
|
4561
|
+
const [targetRenderNodeId, setTargetRenderNodeId] = (0, import_react7.useState)(null);
|
|
4492
4562
|
const swallow = (e) => e.stopPropagation();
|
|
4493
4563
|
const hasCustomProps = customProperties && customProperties.length > 0;
|
|
4564
|
+
const hasAbstraction = Boolean(abstractionTree && (abstractionTree.node || abstractionTree.children && abstractionTree.children.length > 0));
|
|
4494
4565
|
const ability = (0, import_react7.useMemo)(() => defineAbilityFor(userRole), [userRole]);
|
|
4495
4566
|
const canEditAncestry = ability.can("update", "Ancestry");
|
|
4567
|
+
const highlightedPathIds = (0, import_react7.useMemo)(() => {
|
|
4568
|
+
var _a, _b;
|
|
4569
|
+
if (!targetRenderNodeId || !abstractionTree) return [];
|
|
4570
|
+
const found = findNodePath(abstractionTree, targetRenderNodeId);
|
|
4571
|
+
if (!found) return [];
|
|
4572
|
+
let current = abstractionTree;
|
|
4573
|
+
const ids = [current.is_section ? current.section_id : String((_a = current.node) == null ? void 0 : _a.id)];
|
|
4574
|
+
for (let i of found.path) {
|
|
4575
|
+
current = current.children[i];
|
|
4576
|
+
ids.push(current.is_section ? current.section_id : String((_b = current.node) == null ? void 0 : _b.id));
|
|
4577
|
+
}
|
|
4578
|
+
return ids;
|
|
4579
|
+
}, [targetRenderNodeId, abstractionTree]);
|
|
4580
|
+
const handleToggleProperties = () => {
|
|
4581
|
+
setShowProperties(!showProperties);
|
|
4582
|
+
if (!showProperties) setShowAbstraction(false);
|
|
4583
|
+
};
|
|
4584
|
+
const handleToggleAbstraction = () => {
|
|
4585
|
+
setShowAbstraction(!showAbstraction);
|
|
4586
|
+
if (!showAbstraction) setShowProperties(false);
|
|
4587
|
+
};
|
|
4496
4588
|
const leftAction = (0, import_react7.useMemo)(() => {
|
|
4497
4589
|
if (activeNodeBranches == null ? void 0 : activeNodeBranches.left) {
|
|
4498
4590
|
return {
|
|
@@ -4537,21 +4629,38 @@ function DescriptionReadModePanel({
|
|
|
4537
4629
|
/* @__PURE__ */ import_react7.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4 border-b border-white/10 shrink-0 bg-slate-950/50 backdrop-blur-md z-20" }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ import_react7.default.createElement(
|
|
4538
4630
|
"button",
|
|
4539
4631
|
{
|
|
4540
|
-
onClick:
|
|
4632
|
+
onClick: () => {
|
|
4633
|
+
if (showAbstraction) {
|
|
4634
|
+
setShowAbstraction(false);
|
|
4635
|
+
} else if (showProperties) {
|
|
4636
|
+
setShowProperties(false);
|
|
4637
|
+
} else if (onBack) {
|
|
4638
|
+
onBack();
|
|
4639
|
+
}
|
|
4640
|
+
},
|
|
4541
4641
|
className: "w-8 h-8 flex-shrink-0 grid place-content-center rounded-lg border border-white/10 bg-white/5 hover:bg-white/10 transition-colors text-slate-300",
|
|
4542
4642
|
title: "Voltar"
|
|
4543
4643
|
},
|
|
4544
4644
|
/* @__PURE__ */ import_react7.default.createElement(import_fi6.FiArrowLeft, { size: 16 })
|
|
4545
|
-
), /* @__PURE__ */ import_react7.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react7.default.createElement("p", { className: "text-xs/relaxed text-slate-400 uppercase tracking-wider font-semibold" }, showProperties ? "Propriedades Adicionais" : "Modo de Leitura"), /* @__PURE__ */ import_react7.default.createElement("h2", { className: "text-lg sm:text-xl font-semibold tracking-tight text-white truncate", title }, title || "Sem T\xEDtulo"))), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" }, hasCustomProps && /* @__PURE__ */ import_react7.default.createElement(
|
|
4645
|
+
), /* @__PURE__ */ import_react7.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react7.default.createElement("p", { className: "text-xs/relaxed text-slate-400 uppercase tracking-wider font-semibold" }, showAbstraction ? "Tree de Abstra\xE7\xE3o" : showProperties ? "Propriedades Adicionais" : "Modo de Leitura"), /* @__PURE__ */ import_react7.default.createElement("h2", { className: "text-lg sm:text-xl font-semibold tracking-tight text-white truncate", title }, title || "Sem T\xEDtulo"))), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" }, hasCustomProps && /* @__PURE__ */ import_react7.default.createElement(
|
|
4546
4646
|
"button",
|
|
4547
4647
|
{
|
|
4548
|
-
onClick:
|
|
4648
|
+
onClick: handleToggleProperties,
|
|
4549
4649
|
className: `relative w-9 h-9 grid place-content-center rounded-lg border transition-colors
|
|
4550
4650
|
${showProperties ? "border-cyan-500/50 bg-cyan-500/10 text-cyan-300" : "border-white/15 bg-transparent hover:bg-white/5 text-slate-300 hover:text-white"}`,
|
|
4551
4651
|
title: showProperties ? "Ver Descri\xE7\xE3o" : "Ver Propriedades Adicionais"
|
|
4552
4652
|
},
|
|
4553
4653
|
showProperties ? /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiAlignLeft, { size: 16 }) : /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiList, { size: 16 }),
|
|
4554
|
-
!showProperties && /* @__PURE__ */ import_react7.default.createElement("span", { className: "absolute top-1.5 right-1.5 block h-2 w-2 rounded-full bg-cyan-400 ring-2 ring-slate-900 animate-pulse" })
|
|
4654
|
+
!showProperties && !showAbstraction && /* @__PURE__ */ import_react7.default.createElement("span", { className: "absolute top-1.5 right-1.5 block h-2 w-2 rounded-full bg-cyan-400 ring-2 ring-slate-900 animate-pulse" })
|
|
4655
|
+
), hasAbstraction && /* @__PURE__ */ import_react7.default.createElement(
|
|
4656
|
+
"button",
|
|
4657
|
+
{
|
|
4658
|
+
onClick: handleToggleAbstraction,
|
|
4659
|
+
className: `relative w-9 h-9 grid place-content-center rounded-lg border transition-colors
|
|
4660
|
+
${showAbstraction ? "border-purple-500/50 bg-purple-500/10 text-purple-300" : "border-white/15 bg-transparent hover:bg-white/5 text-slate-300 hover:text-white"}`,
|
|
4661
|
+
title: showAbstraction ? "Voltar \xE0 Descri\xE7\xE3o" : "Ver Tree de Abstra\xE7\xE3o"
|
|
4662
|
+
},
|
|
4663
|
+
/* @__PURE__ */ import_react7.default.createElement(import_fi6.FiGitBranch, { size: 16 })
|
|
4555
4664
|
), onRenderFullAncestry && /* @__PURE__ */ import_react7.default.createElement(
|
|
4556
4665
|
"button",
|
|
4557
4666
|
{
|
|
@@ -4565,7 +4674,7 @@ function DescriptionReadModePanel({
|
|
|
4565
4674
|
{
|
|
4566
4675
|
onClick: onEdit,
|
|
4567
4676
|
className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-slate-300 hover:text-white",
|
|
4568
|
-
title: "Editar Descri\xE7\xE3o"
|
|
4677
|
+
title: "Editar Descri\xE7\xE3o / Estrutura"
|
|
4569
4678
|
},
|
|
4570
4679
|
/* @__PURE__ */ import_react7.default.createElement(import_fi6.FiEdit2, { size: 16 })
|
|
4571
4680
|
), /* @__PURE__ */ import_react7.default.createElement(
|
|
@@ -4577,7 +4686,40 @@ function DescriptionReadModePanel({
|
|
|
4577
4686
|
},
|
|
4578
4687
|
"\xD7"
|
|
4579
4688
|
))),
|
|
4580
|
-
/* @__PURE__ */ import_react7.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10" },
|
|
4689
|
+
/* @__PURE__ */ import_react7.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10", onClick: () => setTargetRenderNodeId(null) }, showAbstraction ? /* @__PURE__ */ import_react7.default.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4" }, /* @__PURE__ */ import_react7.default.createElement("h3", { className: "text-sm font-semibold text-purple-300 uppercase tracking-wider" }, "Explorar Hierarquia"), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex flex-wrap gap-2" }, targetRenderNodeId && onRenderAbstractionTree && /* @__PURE__ */ import_react7.default.createElement(
|
|
4690
|
+
"button",
|
|
4691
|
+
{
|
|
4692
|
+
onClick: (e) => {
|
|
4693
|
+
e.stopPropagation();
|
|
4694
|
+
onRenderAbstractionTree(targetRenderNodeId);
|
|
4695
|
+
},
|
|
4696
|
+
className: "px-3 py-1.5 rounded-md bg-fuchsia-600 text-white hover:bg-fuchsia-500 transition-colors flex items-center gap-1.5 text-xs font-bold shadow-lg animate-in zoom-in-95 duration-200",
|
|
4697
|
+
title: "Renderiza no 3D apenas o caminho at\xE9 o Node selecionado"
|
|
4698
|
+
},
|
|
4699
|
+
/* @__PURE__ */ import_react7.default.createElement(import_fi6.FiLayers, { size: 14 }),
|
|
4700
|
+
" Renderizar Caminho"
|
|
4701
|
+
), onRenderAbstractionTree && /* @__PURE__ */ import_react7.default.createElement(
|
|
4702
|
+
"button",
|
|
4703
|
+
{
|
|
4704
|
+
onClick: (e) => {
|
|
4705
|
+
e.stopPropagation();
|
|
4706
|
+
setTargetRenderNodeId(null);
|
|
4707
|
+
onRenderAbstractionTree(null);
|
|
4708
|
+
},
|
|
4709
|
+
className: "px-3 py-1.5 rounded-md bg-slate-700 border border-white/10 text-slate-200 hover:bg-slate-600 hover:text-white transition-colors flex items-center gap-1.5 text-xs font-semibold",
|
|
4710
|
+
title: "Renderiza a Abstraction Tree inteira verticalmente"
|
|
4711
|
+
},
|
|
4712
|
+
/* @__PURE__ */ import_react7.default.createElement(import_fi6.FiLayers, { size: 14 }),
|
|
4713
|
+
" Renderizar Completa"
|
|
4714
|
+
))), /* @__PURE__ */ import_react7.default.createElement("div", { className: "bg-slate-900/60 border border-white/10 rounded-lg p-4" }, /* @__PURE__ */ import_react7.default.createElement(
|
|
4715
|
+
ReadOnlyNodeItem,
|
|
4716
|
+
{
|
|
4717
|
+
nodeData: abstractionTree,
|
|
4718
|
+
onViewSelect: setTargetRenderNodeId,
|
|
4719
|
+
highlightedPathIds,
|
|
4720
|
+
targetRenderNodeId
|
|
4721
|
+
}
|
|
4722
|
+
))) : showProperties ? /* @__PURE__ */ import_react7.default.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300" }, customProperties.map((prop) => /* @__PURE__ */ import_react7.default.createElement(
|
|
4581
4723
|
CustomPropertyDisplay,
|
|
4582
4724
|
{
|
|
4583
4725
|
key: prop.id,
|
|
@@ -4606,7 +4748,7 @@ function DescriptionReadModePanel({
|
|
|
4606
4748
|
onImageClick
|
|
4607
4749
|
}
|
|
4608
4750
|
)),
|
|
4609
|
-
leftAction && /* @__PURE__ */ import_react7.default.createElement(
|
|
4751
|
+
leftAction && !showAbstraction && !showProperties && /* @__PURE__ */ import_react7.default.createElement(
|
|
4610
4752
|
"button",
|
|
4611
4753
|
{
|
|
4612
4754
|
onClick: leftAction.onClick,
|
|
@@ -4618,7 +4760,7 @@ function DescriptionReadModePanel({
|
|
|
4618
4760
|
${leftAction.type === "branch" ? "bg-indigo-500/20 text-indigo-300 group-hover/btn:text-white group-hover/btn:bg-indigo-500" : "bg-rose-500/20 text-rose-300 group-hover/btn:text-white group-hover/btn:bg-rose-500"}
|
|
4619
4761
|
` }, leftAction.type === "branch" ? /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiChevronLeft, { size: 20 }) : /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiCornerUpLeft, { size: 20 }))
|
|
4620
4762
|
),
|
|
4621
|
-
rightAction && /* @__PURE__ */ import_react7.default.createElement(
|
|
4763
|
+
rightAction && !showAbstraction && !showProperties && /* @__PURE__ */ import_react7.default.createElement(
|
|
4622
4764
|
"button",
|
|
4623
4765
|
{
|
|
4624
4766
|
onClick: rightAction.onClick,
|
|
@@ -4871,7 +5013,7 @@ function AncestryPickerModal({
|
|
|
4871
5013
|
}
|
|
4872
5014
|
|
|
4873
5015
|
// src/components/CreateAncestryPanel.jsx
|
|
4874
|
-
var
|
|
5016
|
+
var findNodePath2 = (tree, targetNodeId, currentPath = []) => {
|
|
4875
5017
|
var _a;
|
|
4876
5018
|
if (!tree) return null;
|
|
4877
5019
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
@@ -4880,22 +5022,41 @@ var findNodePath = (tree, targetNodeId, currentPath = []) => {
|
|
|
4880
5022
|
}
|
|
4881
5023
|
if (tree.children) {
|
|
4882
5024
|
for (let i = 0; i < tree.children.length; i++) {
|
|
4883
|
-
const res =
|
|
5025
|
+
const res = findNodePath2(tree.children[i], targetNodeId, [...currentPath, i]);
|
|
4884
5026
|
if (res) return res;
|
|
4885
5027
|
}
|
|
4886
5028
|
}
|
|
4887
5029
|
return null;
|
|
4888
5030
|
};
|
|
4889
|
-
var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, onMoveNode, selectedParentId, level = 0, isLast = false, path = [], isEditable }) => {
|
|
5031
|
+
var NodeItem = ({ nodeData, onSelectParent, onViewSelect, highlightedPathIds = [], targetRenderNodeId, onRemoveNode, onEditRelationship, onMoveNode, selectedParentId, level = 0, isLast = false, path = [], isEditable }) => {
|
|
4890
5032
|
var _a, _b;
|
|
4891
5033
|
const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
|
|
4892
5034
|
const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
|
|
4893
5035
|
const [isDragOver, setIsDragOver] = (0, import_react10.useState)(false);
|
|
4894
|
-
const
|
|
5036
|
+
const isSelectedParent = String(selectedParentId) === String(itemId);
|
|
5037
|
+
const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
|
|
5038
|
+
const isHighlightedPath = highlightedPathIds.includes(String(itemId));
|
|
4895
5039
|
const hasChildren = nodeData.children && nodeData.children.length > 0;
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
5040
|
+
let itemBgClass = "bg-slate-900/50 hover:bg-slate-800/80";
|
|
5041
|
+
let textColorClass = "text-slate-200";
|
|
5042
|
+
if (nodeData.is_section) {
|
|
5043
|
+
itemBgClass = isSelectedParent ? "bg-indigo-500/30 ring-2 ring-indigo-400" : "bg-indigo-900/20 border border-indigo-500/30 hover:bg-indigo-900/40";
|
|
5044
|
+
textColorClass = isSelectedParent ? "text-indigo-200 font-bold" : "text-indigo-300";
|
|
5045
|
+
} else {
|
|
5046
|
+
if (isSelectedParent) {
|
|
5047
|
+
itemBgClass = "bg-purple-500/30 ring-2 ring-purple-400";
|
|
5048
|
+
textColorClass = "text-purple-200 font-semibold";
|
|
5049
|
+
} else if (isTargetViewNode) {
|
|
5050
|
+
itemBgClass = "bg-fuchsia-600/40 ring-2 ring-fuchsia-400 shadow-[0_0_15px_rgba(217,70,239,0.3)]";
|
|
5051
|
+
textColorClass = "text-white font-bold";
|
|
5052
|
+
} else if (isHighlightedPath) {
|
|
5053
|
+
itemBgClass = "bg-fuchsia-900/30 border border-fuchsia-500/40";
|
|
5054
|
+
textColorClass = "text-fuchsia-200 font-semibold";
|
|
5055
|
+
} else {
|
|
5056
|
+
textColorClass = "text-slate-200";
|
|
5057
|
+
}
|
|
5058
|
+
}
|
|
5059
|
+
const cursorClass = isEditable ? "cursor-grab active:cursor-grabbing" : "cursor-pointer";
|
|
4899
5060
|
const handleDragStart = (e) => {
|
|
4900
5061
|
if (!isEditable) {
|
|
4901
5062
|
e.preventDefault();
|
|
@@ -4925,23 +5086,9 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4925
5086
|
if (!isEditable) return;
|
|
4926
5087
|
const sourceId = e.dataTransfer.getData("nodeId");
|
|
4927
5088
|
if (sourceId === String(itemId)) return;
|
|
4928
|
-
if (onMoveNode)
|
|
4929
|
-
onMoveNode(sourceId, itemId);
|
|
4930
|
-
}
|
|
5089
|
+
if (onMoveNode) onMoveNode(sourceId, itemId);
|
|
4931
5090
|
};
|
|
4932
|
-
return /* @__PURE__ */ import_react10.default.createElement("div", { className: "relative" }, level > 0 && /* @__PURE__ */ import_react10.default.createElement(import_react10.default.Fragment, null, /* @__PURE__ */ import_react10.default.createElement(
|
|
4933
|
-
"span",
|
|
4934
|
-
{
|
|
4935
|
-
className: `absolute -left-4 top-0 w-px bg-cyan-600/60 ${isLast ? "h-[1.125rem]" : "h-full"}`,
|
|
4936
|
-
"aria-hidden": "true"
|
|
4937
|
-
}
|
|
4938
|
-
), /* @__PURE__ */ import_react10.default.createElement(
|
|
4939
|
-
"span",
|
|
4940
|
-
{
|
|
4941
|
-
className: `absolute -left-4 top-[1.125rem] h-px w-4 bg-cyan-600/60`,
|
|
4942
|
-
"aria-hidden": "true"
|
|
4943
|
-
}
|
|
4944
|
-
)), /* @__PURE__ */ import_react10.default.createElement(
|
|
5091
|
+
return /* @__PURE__ */ import_react10.default.createElement("div", { className: "relative" }, level > 0 && /* @__PURE__ */ import_react10.default.createElement(import_react10.default.Fragment, null, /* @__PURE__ */ import_react10.default.createElement("span", { className: `absolute -left-4 top-0 w-px ${isHighlightedPath ? "bg-fuchsia-500 shadow-[0_0_8px_rgba(217,70,239,0.8)]" : "bg-cyan-600/60"} ${isLast ? "h-[1.125rem]" : "h-full"}`, "aria-hidden": "true" }), /* @__PURE__ */ import_react10.default.createElement("span", { className: `absolute -left-4 top-[1.125rem] h-px w-4 ${isHighlightedPath ? "bg-fuchsia-500 shadow-[0_0_8px_rgba(217,70,239,0.8)]" : "bg-cyan-600/60"}`, "aria-hidden": "true" })), /* @__PURE__ */ import_react10.default.createElement(
|
|
4945
5092
|
"div",
|
|
4946
5093
|
{
|
|
4947
5094
|
draggable: isEditable,
|
|
@@ -4949,63 +5096,35 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4949
5096
|
onDragOver: handleDragOver,
|
|
4950
5097
|
onDragLeave: handleDragLeave,
|
|
4951
5098
|
onDrop: handleDrop,
|
|
4952
|
-
onClick: () => {
|
|
5099
|
+
onClick: (e) => {
|
|
5100
|
+
e.stopPropagation();
|
|
4953
5101
|
if (isEditable) {
|
|
4954
5102
|
onSelectParent(itemId);
|
|
5103
|
+
} else if (onViewSelect) {
|
|
5104
|
+
onViewSelect(itemId);
|
|
4955
5105
|
}
|
|
4956
5106
|
},
|
|
4957
5107
|
className: `flex items-center justify-between gap-2 px-3 h-9 rounded-md transition-all duration-150 border
|
|
4958
5108
|
${isDragOver ? "border-dashed border-yellow-400 bg-yellow-400/10" : "border-transparent"}
|
|
4959
5109
|
${itemBgClass} ${cursorClass}`
|
|
4960
5110
|
},
|
|
4961
|
-
/* @__PURE__ */ import_react10.default.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ import_react10.default.createElement(
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
stroke: "currentColor",
|
|
4970
|
-
strokeWidth: "2",
|
|
4971
|
-
strokeLinecap: "round",
|
|
4972
|
-
strokeLinejoin: "round",
|
|
4973
|
-
className: "lucide lucide-blend-icon lucide-blend mr-1.5 inline-block"
|
|
4974
|
-
},
|
|
4975
|
-
/* @__PURE__ */ import_react10.default.createElement("circle", { cx: "9", cy: "9", r: "7" }),
|
|
4976
|
-
/* @__PURE__ */ import_react10.default.createElement("circle", { cx: "15", cy: "15", r: "7" })
|
|
4977
|
-
), nodeData.is_section && /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiFolder, { className: "mr-2" }), itemName),
|
|
4978
|
-
level > 0 && isEditable && /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-1 animate-in fade-in duration-200" }, !nodeData.is_section && /* @__PURE__ */ import_react10.default.createElement(
|
|
4979
|
-
"button",
|
|
4980
|
-
{
|
|
4981
|
-
onClick: (e) => {
|
|
4982
|
-
e.stopPropagation();
|
|
4983
|
-
onEditRelationship(path, nodeData.relationship || {});
|
|
4984
|
-
},
|
|
4985
|
-
className: "w-6 h-6 grid place-content-center rounded-full hover:bg-cyan-500/20 text-cyan-400 transition-colors flex-shrink-0",
|
|
4986
|
-
title: "Editar detalhes da rela\xE7\xE3o",
|
|
4987
|
-
style: { cursor: "pointer" }
|
|
4988
|
-
},
|
|
4989
|
-
/* @__PURE__ */ import_react10.default.createElement(import_fi9.FiEdit2, { size: 12 })
|
|
4990
|
-
), /* @__PURE__ */ import_react10.default.createElement(
|
|
4991
|
-
"button",
|
|
4992
|
-
{
|
|
4993
|
-
onClick: (e) => {
|
|
4994
|
-
e.stopPropagation();
|
|
4995
|
-
onRemoveNode(path);
|
|
4996
|
-
},
|
|
4997
|
-
className: "w-6 h-6 grid place-content-center rounded-full hover:bg-red-500/20 text-red-400 text-lg transition-colors flex-shrink-0",
|
|
4998
|
-
title: "Remover Node da ancestralidade",
|
|
4999
|
-
style: { cursor: "pointer" }
|
|
5000
|
-
},
|
|
5001
|
-
"\xD7"
|
|
5002
|
-
))
|
|
5111
|
+
/* @__PURE__ */ import_react10.default.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ import_react10.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", className: "mr-1.5 inline-block" }, /* @__PURE__ */ import_react10.default.createElement("circle", { cx: "9", cy: "9", r: "7" }), /* @__PURE__ */ import_react10.default.createElement("circle", { cx: "15", cy: "15", r: "7" })), nodeData.is_section && /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiFolder, { className: "mr-2" }), itemName),
|
|
5112
|
+
level > 0 && isEditable && /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-1 animate-in fade-in duration-200" }, !nodeData.is_section && /* @__PURE__ */ import_react10.default.createElement("button", { onClick: (e) => {
|
|
5113
|
+
e.stopPropagation();
|
|
5114
|
+
onEditRelationship(path, nodeData.relationship || {});
|
|
5115
|
+
}, className: "w-6 h-6 grid place-content-center rounded-full hover:bg-cyan-500/20 text-cyan-400 transition-colors flex-shrink-0", title: "Editar detalhes da rela\xE7\xE3o" }, /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiEdit2, { size: 12 })), /* @__PURE__ */ import_react10.default.createElement("button", { onClick: (e) => {
|
|
5116
|
+
e.stopPropagation();
|
|
5117
|
+
onRemoveNode(path);
|
|
5118
|
+
}, className: "w-6 h-6 grid place-content-center rounded-full hover:bg-red-500/20 text-red-400 text-lg transition-colors flex-shrink-0", title: "Remover Node" }, "\xD7"))
|
|
5003
5119
|
), hasChildren && /* @__PURE__ */ import_react10.default.createElement("div", { className: "mt-2 space-y-2 pl-8" }, nodeData.children.map((child, index) => /* @__PURE__ */ import_react10.default.createElement(
|
|
5004
5120
|
NodeItem,
|
|
5005
5121
|
{
|
|
5006
5122
|
key: `${child.is_section ? child.id : child.node.id}-${index}`,
|
|
5007
5123
|
nodeData: child,
|
|
5008
5124
|
onSelectParent,
|
|
5125
|
+
onViewSelect,
|
|
5126
|
+
highlightedPathIds,
|
|
5127
|
+
targetRenderNodeId,
|
|
5009
5128
|
onRemoveNode,
|
|
5010
5129
|
onEditRelationship,
|
|
5011
5130
|
onMoveNode,
|
|
@@ -5020,11 +5139,8 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
5020
5139
|
function CreateAncestryPanel({
|
|
5021
5140
|
ancestryMode,
|
|
5022
5141
|
setAncestryMode,
|
|
5023
|
-
// <--- Nova prop necessária para as novas funções manipuladoras
|
|
5024
5142
|
onSelectParent,
|
|
5025
|
-
// Mantido para compatibilidade, mas as novas funções usam setAncestryMode
|
|
5026
5143
|
onRemoveNode,
|
|
5027
|
-
// Mantido para compatibilidade
|
|
5028
5144
|
onSave,
|
|
5029
5145
|
onClose,
|
|
5030
5146
|
onEditRelationship,
|
|
@@ -5035,14 +5151,12 @@ function CreateAncestryPanel({
|
|
|
5035
5151
|
onUpdateTree,
|
|
5036
5152
|
onAncestrySectionChange,
|
|
5037
5153
|
onToggleAddNodes,
|
|
5038
|
-
// Mantido para compatibilidade
|
|
5039
5154
|
onRenderFullAncestry,
|
|
5040
5155
|
onHighlightNode,
|
|
5041
5156
|
onClearAncestryVisuals,
|
|
5042
5157
|
onUploadFile,
|
|
5043
5158
|
onOpenImageViewer,
|
|
5044
5159
|
onRenderAbstractionTree
|
|
5045
|
-
// <--- Nova prop recebida
|
|
5046
5160
|
}) {
|
|
5047
5161
|
const {
|
|
5048
5162
|
tree: rootTree,
|
|
@@ -5059,6 +5173,20 @@ function CreateAncestryPanel({
|
|
|
5059
5173
|
const [customProps, setCustomProps] = (0, import_react10.useState)([]);
|
|
5060
5174
|
const propsEndRef = (0, import_react10.useRef)(null);
|
|
5061
5175
|
const [branchStack, setBranchStack] = (0, import_react10.useState)([]);
|
|
5176
|
+
const [targetRenderNodeId, setTargetRenderNodeId] = (0, import_react10.useState)(null);
|
|
5177
|
+
const highlightedPathIds = (0, import_react10.useMemo)(() => {
|
|
5178
|
+
var _a, _b;
|
|
5179
|
+
if (!targetRenderNodeId || !ancestryMode.abstraction_tree) return [];
|
|
5180
|
+
const found = findNodePath2(ancestryMode.abstraction_tree, targetRenderNodeId);
|
|
5181
|
+
if (!found) return [];
|
|
5182
|
+
let current = ancestryMode.abstraction_tree;
|
|
5183
|
+
const ids = [current.is_section ? current.section_id : String((_a = current.node) == null ? void 0 : _a.id)];
|
|
5184
|
+
for (let i of found.path) {
|
|
5185
|
+
current = current.children[i];
|
|
5186
|
+
ids.push(current.is_section ? current.section_id : String((_b = current.node) == null ? void 0 : _b.id));
|
|
5187
|
+
}
|
|
5188
|
+
return ids;
|
|
5189
|
+
}, [targetRenderNodeId, ancestryMode.abstraction_tree]);
|
|
5062
5190
|
const [targetScrollSectionId, setTargetScrollSectionId] = (0, import_react10.useState)(null);
|
|
5063
5191
|
const [internalHighlightedNodeId, setInternalHighlightedNodeId] = (0, import_react10.useState)(null);
|
|
5064
5192
|
const [ancestryName, setAncestryName] = (0, import_react10.useState)(initialName);
|
|
@@ -5082,6 +5210,9 @@ function CreateAncestryPanel({
|
|
|
5082
5210
|
setAncestryMode((prev) => isAbstraction ? { ...prev, selectedAbstractionParentId: nodeId } : { ...prev, selectedParentId: nodeId });
|
|
5083
5211
|
};
|
|
5084
5212
|
const handleToggleAddMode = (isAbstraction = false) => {
|
|
5213
|
+
if (isAbstraction && !ancestryMode.isAddingAbstractionNodes) {
|
|
5214
|
+
setTargetRenderNodeId(null);
|
|
5215
|
+
}
|
|
5085
5216
|
setAncestryMode((prev) => isAbstraction ? { ...prev, isAddingAbstractionNodes: !prev.isAddingAbstractionNodes } : { ...prev, isAddingNodes: !prev.isAddingNodes });
|
|
5086
5217
|
};
|
|
5087
5218
|
const handleRemoveNode = (0, import_react10.useCallback)((pathToRemove, isAbstraction = false) => {
|
|
@@ -5113,7 +5244,7 @@ function CreateAncestryPanel({
|
|
|
5113
5244
|
if (!isAbstraction && branchStack.length > 0) {
|
|
5114
5245
|
let ptr = rootTreeClone;
|
|
5115
5246
|
for (const step of branchStack) {
|
|
5116
|
-
const found =
|
|
5247
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5117
5248
|
if (found && found.node.parallel_branches) {
|
|
5118
5249
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5119
5250
|
if (branch) ptr = branch.tree;
|
|
@@ -5163,14 +5294,15 @@ function CreateAncestryPanel({
|
|
|
5163
5294
|
}
|
|
5164
5295
|
}
|
|
5165
5296
|
};
|
|
5166
|
-
const takeSnapshot = (tree, name, desc, sections, customProps2, isPrivateVal) => {
|
|
5297
|
+
const takeSnapshot = (tree, name, desc, sections, customProps2, isPrivateVal, abstractionTree = null) => {
|
|
5167
5298
|
return {
|
|
5168
5299
|
tree: JSON.stringify(tree),
|
|
5169
5300
|
name,
|
|
5170
5301
|
description: desc || "",
|
|
5171
5302
|
sections: JSON.stringify(sections || []),
|
|
5172
5303
|
customProps: JSON.stringify(customProps2 || []),
|
|
5173
|
-
isPrivate: isPrivateVal
|
|
5304
|
+
isPrivate: isPrivateVal,
|
|
5305
|
+
abstractionTree: JSON.stringify(abstractionTree)
|
|
5174
5306
|
};
|
|
5175
5307
|
};
|
|
5176
5308
|
const getCurrentContext = () => {
|
|
@@ -5189,7 +5321,7 @@ function CreateAncestryPanel({
|
|
|
5189
5321
|
let currentBranch = null;
|
|
5190
5322
|
let currentDirection = null;
|
|
5191
5323
|
for (const step of branchStack) {
|
|
5192
|
-
const found =
|
|
5324
|
+
const found = findNodePath2(currentTreePtr, step.nodeId);
|
|
5193
5325
|
if (!found || !found.node.parallel_branches) return null;
|
|
5194
5326
|
currentBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5195
5327
|
if (!currentBranch) return null;
|
|
@@ -5271,7 +5403,7 @@ function CreateAncestryPanel({
|
|
|
5271
5403
|
let ptr = ancestryMode.tree;
|
|
5272
5404
|
let foundBranch = null;
|
|
5273
5405
|
for (const step of branchStack) {
|
|
5274
|
-
const found =
|
|
5406
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5275
5407
|
if (found && found.node.parallel_branches) {
|
|
5276
5408
|
foundBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5277
5409
|
if (foundBranch) ptr = foundBranch.tree;
|
|
@@ -5304,7 +5436,8 @@ function CreateAncestryPanel({
|
|
|
5304
5436
|
ancestryMode.ancestryDescription,
|
|
5305
5437
|
ancestryMode.ancestryDescriptionSections,
|
|
5306
5438
|
extractedProps,
|
|
5307
|
-
ancestryMode.is_private
|
|
5439
|
+
ancestryMode.is_private,
|
|
5440
|
+
ancestryMode.abstraction_tree
|
|
5308
5441
|
));
|
|
5309
5442
|
} else if (ctx) {
|
|
5310
5443
|
setLastSavedSnapshot(takeSnapshot(
|
|
@@ -5313,7 +5446,8 @@ function CreateAncestryPanel({
|
|
|
5313
5446
|
ctx.description,
|
|
5314
5447
|
ctx.sections,
|
|
5315
5448
|
extractedProps,
|
|
5316
|
-
isPrivate
|
|
5449
|
+
isPrivate,
|
|
5450
|
+
ancestryMode.abstraction_tree
|
|
5317
5451
|
));
|
|
5318
5452
|
}
|
|
5319
5453
|
}, [branchStack, ancestryMode]);
|
|
@@ -5328,7 +5462,7 @@ function CreateAncestryPanel({
|
|
|
5328
5462
|
let ptr = rootTreeClone;
|
|
5329
5463
|
let targetBranch = null;
|
|
5330
5464
|
for (const step of branchStack) {
|
|
5331
|
-
const found =
|
|
5465
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5332
5466
|
if (found && found.node.parallel_branches) {
|
|
5333
5467
|
targetBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5334
5468
|
if (targetBranch) ptr = targetBranch.tree;
|
|
@@ -5356,7 +5490,7 @@ function CreateAncestryPanel({
|
|
|
5356
5490
|
rootTreeClone,
|
|
5357
5491
|
rootExtras
|
|
5358
5492
|
);
|
|
5359
|
-
setLastSavedSnapshot(takeSnapshot(rootTreeClone, ancestryName, description, processedSections, [], isPrivate));
|
|
5493
|
+
setLastSavedSnapshot(takeSnapshot(rootTreeClone, ancestryName, description, processedSections, [], isPrivate, ancestryMode.abstraction_tree));
|
|
5360
5494
|
if (onRenderFullAncestry) {
|
|
5361
5495
|
const fullTreePayload = {
|
|
5362
5496
|
ancestry_id: ancestryMode.currentAncestryId || "temp_root",
|
|
@@ -5386,14 +5520,14 @@ function CreateAncestryPanel({
|
|
|
5386
5520
|
let ptr = rootTreeClone;
|
|
5387
5521
|
for (let i = 0; i < branchStack.length - 1; i++) {
|
|
5388
5522
|
const step = branchStack[i];
|
|
5389
|
-
const found =
|
|
5523
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5390
5524
|
if (found && found.node.parallel_branches) {
|
|
5391
5525
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5392
5526
|
if (branch) ptr = branch.tree;
|
|
5393
5527
|
}
|
|
5394
5528
|
}
|
|
5395
5529
|
const currentStep = branchStack[branchStack.length - 1];
|
|
5396
|
-
const foundParentPath =
|
|
5530
|
+
const foundParentPath = findNodePath2(ptr, currentStep.nodeId);
|
|
5397
5531
|
if (foundParentPath && foundParentPath.node && foundParentPath.node.parallel_branches) {
|
|
5398
5532
|
const branchIndex = foundParentPath.node.parallel_branches.findIndex((b) => b.id === currentStep.branchId);
|
|
5399
5533
|
if (branchIndex !== -1) {
|
|
@@ -5417,7 +5551,8 @@ function CreateAncestryPanel({
|
|
|
5417
5551
|
ancestryMode.ancestryDescription,
|
|
5418
5552
|
ancestryMode.ancestryDescriptionSections,
|
|
5419
5553
|
currentRootProps,
|
|
5420
|
-
isPrivate
|
|
5554
|
+
isPrivate,
|
|
5555
|
+
ancestryMode.abstraction_tree
|
|
5421
5556
|
));
|
|
5422
5557
|
if (onClearAncestryVisuals) {
|
|
5423
5558
|
onClearAncestryVisuals(currentStep.branchId);
|
|
@@ -5436,7 +5571,7 @@ function CreateAncestryPanel({
|
|
|
5436
5571
|
const actions = { left: null, right: null };
|
|
5437
5572
|
const isInBranch = branchStack.length > 0;
|
|
5438
5573
|
if (internalHighlightedNodeId) {
|
|
5439
|
-
const found =
|
|
5574
|
+
const found = findNodePath2(activeTree, internalHighlightedNodeId);
|
|
5440
5575
|
if (found && found.node) {
|
|
5441
5576
|
const branches = found.node.parallel_branches || [];
|
|
5442
5577
|
const leftBranch = branches.find((b) => (b.direction || "right") === "left");
|
|
@@ -5488,7 +5623,7 @@ function CreateAncestryPanel({
|
|
|
5488
5623
|
if (branchStack.length > 0) {
|
|
5489
5624
|
let ptr = rootTreeClone;
|
|
5490
5625
|
for (const step of branchStack) {
|
|
5491
|
-
const found =
|
|
5626
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5492
5627
|
if (found && found.node.parallel_branches) {
|
|
5493
5628
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5494
5629
|
if (branch) ptr = branch.tree;
|
|
@@ -5606,6 +5741,11 @@ function CreateAncestryPanel({
|
|
|
5606
5741
|
const sectionsChanged = JSON.stringify(existingSections) !== lastSavedSnapshot.sections;
|
|
5607
5742
|
const propsChanged = JSON.stringify(customProps) !== lastSavedSnapshot.customProps;
|
|
5608
5743
|
const privateChanged = isPrivate !== lastSavedSnapshot.isPrivate;
|
|
5744
|
+
let abstractionTreeChanged = false;
|
|
5745
|
+
if (branchStack.length === 0) {
|
|
5746
|
+
const currentAbsTreeStr = JSON.stringify(ancestryMode.abstraction_tree);
|
|
5747
|
+
abstractionTreeChanged = currentAbsTreeStr !== lastSavedSnapshot.abstractionTree;
|
|
5748
|
+
}
|
|
5609
5749
|
return treeChanged || nameChanged || descChanged || sectionsChanged || propsChanged || privateChanged;
|
|
5610
5750
|
}, [
|
|
5611
5751
|
ancestryName,
|
|
@@ -5615,6 +5755,7 @@ function CreateAncestryPanel({
|
|
|
5615
5755
|
branchStack,
|
|
5616
5756
|
lastSavedSnapshot,
|
|
5617
5757
|
ancestryMode.tree,
|
|
5758
|
+
ancestryMode.abstraction_tree,
|
|
5618
5759
|
customProps,
|
|
5619
5760
|
isPrivate
|
|
5620
5761
|
]);
|
|
@@ -5628,7 +5769,7 @@ function CreateAncestryPanel({
|
|
|
5628
5769
|
let parentTreePtr = rootTree;
|
|
5629
5770
|
let parentBranch = null;
|
|
5630
5771
|
for (const step of parentStack) {
|
|
5631
|
-
const found =
|
|
5772
|
+
const found = findNodePath2(parentTreePtr, step.nodeId);
|
|
5632
5773
|
if (found && found.node.parallel_branches) {
|
|
5633
5774
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5634
5775
|
if (branch) {
|
|
@@ -5706,7 +5847,7 @@ function CreateAncestryPanel({
|
|
|
5706
5847
|
const rootTreeClone = JSON.parse(JSON.stringify(ancestryMode.tree));
|
|
5707
5848
|
let ptr = rootTreeClone;
|
|
5708
5849
|
for (const step of branchStack) {
|
|
5709
|
-
const foundParent =
|
|
5850
|
+
const foundParent = findNodePath2(ptr, step.nodeId);
|
|
5710
5851
|
if (foundParent && foundParent.node && foundParent.node.parallel_branches) {
|
|
5711
5852
|
const existingBranch = foundParent.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5712
5853
|
if (existingBranch) {
|
|
@@ -5714,7 +5855,7 @@ function CreateAncestryPanel({
|
|
|
5714
5855
|
}
|
|
5715
5856
|
}
|
|
5716
5857
|
}
|
|
5717
|
-
const found =
|
|
5858
|
+
const found = findNodePath2(ptr, nodeId);
|
|
5718
5859
|
if (!found) {
|
|
5719
5860
|
console.error("Node alvo n\xE3o encontrado no contexto atual.");
|
|
5720
5861
|
return;
|
|
@@ -5827,7 +5968,7 @@ function CreateAncestryPanel({
|
|
|
5827
5968
|
let ptr = updatedRootTree;
|
|
5828
5969
|
let targetBranch = null;
|
|
5829
5970
|
for (const step of branchStack) {
|
|
5830
|
-
const found =
|
|
5971
|
+
const found = findNodePath2(ptr, step.nodeId);
|
|
5831
5972
|
if (found && found.node.parallel_branches) {
|
|
5832
5973
|
targetBranch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
5833
5974
|
if (targetBranch) ptr = targetBranch.tree;
|
|
@@ -5857,7 +5998,8 @@ function CreateAncestryPanel({
|
|
|
5857
5998
|
currentInputDesc,
|
|
5858
5999
|
processedSections,
|
|
5859
6000
|
customProps,
|
|
5860
|
-
isPrivate
|
|
6001
|
+
isPrivate,
|
|
6002
|
+
ancestryMode.abstraction_tree
|
|
5861
6003
|
));
|
|
5862
6004
|
if (onRenderFullAncestry) {
|
|
5863
6005
|
const rotation = branchStack.reduce((acc, step) => {
|
|
@@ -5916,7 +6058,8 @@ function CreateAncestryPanel({
|
|
|
5916
6058
|
currentInputDesc,
|
|
5917
6059
|
processedSections,
|
|
5918
6060
|
customProps,
|
|
5919
|
-
isPrivate
|
|
6061
|
+
isPrivate,
|
|
6062
|
+
ancestryMode.abstraction_tree
|
|
5920
6063
|
));
|
|
5921
6064
|
if (!keepOpen) onClose();
|
|
5922
6065
|
} finally {
|
|
@@ -5969,7 +6112,9 @@ function CreateAncestryPanel({
|
|
|
5969
6112
|
const node = findNode(activeTree, selectedParentId);
|
|
5970
6113
|
return node ? node.name : "Nenhum";
|
|
5971
6114
|
};
|
|
5972
|
-
const
|
|
6115
|
+
const hasMainChildren = activeTree && activeTree.children && activeTree.children.length > 0;
|
|
6116
|
+
const hasAbstractionChildren = branchStack.length === 0 && ancestryMode.abstraction_tree && ancestryMode.abstraction_tree.children && ancestryMode.abstraction_tree.children.length > 0;
|
|
6117
|
+
const canSave = hasMainChildren || hasAbstractionChildren;
|
|
5973
6118
|
const handleSectionChangeWrapper = (sectionId) => {
|
|
5974
6119
|
const ctx = getCurrentContext();
|
|
5975
6120
|
const currentDesc = ctx ? ctx.description : description;
|
|
@@ -6172,7 +6317,7 @@ function CreateAncestryPanel({
|
|
|
6172
6317
|
unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type),
|
|
6173
6318
|
onUploadFile
|
|
6174
6319
|
}
|
|
6175
|
-
)), /* @__PURE__ */ import_react10.default.createElement("div", { ref: propsEndRef }))), /* @__PURE__ */ import_react10.default.createElement("div", { className: `rounded-lg border transition-all duration-300 overflow-hidden ${isAddingNodes ? "border-cyan-500/40 bg-slate-900/60 ring-1 ring-cyan-500/20" : "border-white/10 bg-slate-800/60"}` }, /* @__PURE__ */ import_react10.default.createElement("div", { className: `flex items-center justify-between px-3 py-2 border-b ${isAddingNodes ? "bg-cyan-900/20 border-cyan-500/20" : "bg-white/5 border-white/5"}` }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react10.default.createElement("span", { className: `text-xs font-semibold uppercase tracking-wider ${isAddingNodes ? "text-cyan-300" : "text-slate-400"}` }, "
|
|
6320
|
+
)), /* @__PURE__ */ import_react10.default.createElement("div", { ref: propsEndRef }))), /* @__PURE__ */ import_react10.default.createElement("div", { className: `rounded-lg border transition-all duration-300 overflow-hidden ${isAddingNodes ? "border-cyan-500/40 bg-slate-900/60 ring-1 ring-cyan-500/20" : "border-white/10 bg-slate-800/60"}` }, /* @__PURE__ */ import_react10.default.createElement("div", { className: `flex items-center justify-between px-3 py-2 border-b ${isAddingNodes ? "bg-cyan-900/20 border-cyan-500/20" : "bg-white/5 border-white/5"}` }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react10.default.createElement("span", { className: `text-xs font-semibold uppercase tracking-wider ${isAddingNodes ? "text-cyan-300" : "text-slate-400"}` }, "TREE DE ANCESTRALIDADE ", branchStack.length > 0 && "(Aba)"), isAddingNodes && /* @__PURE__ */ import_react10.default.createElement("span", { className: "text-[10px] bg-cyan-500/20 text-cyan-300 px-1.5 py-0.5 rounded animate-pulse" }, "Editando")), /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react10.default.createElement(
|
|
6176
6321
|
"button",
|
|
6177
6322
|
{
|
|
6178
6323
|
type: "button",
|
|
@@ -6203,44 +6348,77 @@ function CreateAncestryPanel({
|
|
|
6203
6348
|
path: [],
|
|
6204
6349
|
isEditable: isAddingNodes
|
|
6205
6350
|
}
|
|
6206
|
-
), (!activeTree || activeTree.children.length === 0) && !isAddingNodes && /* @__PURE__ */ import_react10.default.createElement("div", { className: "text-center py-4 text-xs text-slate-500 italic" }, "A estrutura est\xE1 vazia. Clique no l\xE1pis acima para adicionar nodes."))), branchStack.length === 0 && ancestryMode.abstraction_tree && /* @__PURE__ */ import_react10.default.createElement(
|
|
6207
|
-
"
|
|
6208
|
-
{
|
|
6209
|
-
type: "button",
|
|
6210
|
-
onClick: () => {
|
|
6211
|
-
const tempPayload = {
|
|
6212
|
-
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6213
|
-
abstraction_tree: ancestryMode.abstraction_tree
|
|
6214
|
-
};
|
|
6215
|
-
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload);
|
|
6216
|
-
},
|
|
6217
|
-
className: "p-1.5 rounded-md bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600 transition-colors",
|
|
6218
|
-
title: "Renderizar Verticalmente no Cen\xE1rio"
|
|
6219
|
-
},
|
|
6220
|
-
/* @__PURE__ */ import_react10.default.createElement(import_fi9.FiLayers, { size: 14 })
|
|
6221
|
-
), /* @__PURE__ */ import_react10.default.createElement(
|
|
6222
|
-
"button",
|
|
6351
|
+
), (!activeTree || activeTree.children.length === 0) && !isAddingNodes && /* @__PURE__ */ import_react10.default.createElement("div", { className: "text-center py-4 text-xs text-slate-500 italic" }, "A estrutura est\xE1 vazia. Clique no l\xE1pis acima para adicionar nodes."))), branchStack.length === 0 && ancestryMode.abstraction_tree && /* @__PURE__ */ import_react10.default.createElement(
|
|
6352
|
+
"div",
|
|
6223
6353
|
{
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
title: "Editar estrutura da abstra\xE7\xE3o"
|
|
6354
|
+
className: `mt-6 rounded-lg border transition-all duration-300 overflow-hidden ${ancestryMode.isAddingAbstractionNodes ? "border-purple-500/40 bg-slate-900/60 ring-1 ring-purple-500/20" : "border-white/10 bg-slate-800/60"}`,
|
|
6355
|
+
onClick: () => setTargetRenderNodeId(null)
|
|
6227
6356
|
},
|
|
6228
|
-
ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ import_react10.default.createElement(
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6357
|
+
/* @__PURE__ */ import_react10.default.createElement("div", { className: `flex items-center justify-between px-3 py-2 border-b ${ancestryMode.isAddingAbstractionNodes ? "bg-purple-900/20 border-purple-500/20" : "bg-white/5 border-white/5"}` }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react10.default.createElement("span", { className: `text-xs font-semibold uppercase tracking-wider ${ancestryMode.isAddingAbstractionNodes ? "text-purple-300" : "text-slate-400"}` }, "Tree de Abstra\xE7\xE3o"), ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ import_react10.default.createElement("span", { className: "text-[10px] bg-purple-500/20 text-purple-300 px-1.5 py-0.5 rounded animate-pulse" }, "Editando")), /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, targetRenderNodeId && !ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ import_react10.default.createElement(
|
|
6358
|
+
"button",
|
|
6359
|
+
{
|
|
6360
|
+
type: "button",
|
|
6361
|
+
onClick: (e) => {
|
|
6362
|
+
e.stopPropagation();
|
|
6363
|
+
const tempPayload = {
|
|
6364
|
+
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6365
|
+
abstraction_tree: ancestryMode.abstraction_tree
|
|
6366
|
+
};
|
|
6367
|
+
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload, targetRenderNodeId);
|
|
6368
|
+
},
|
|
6369
|
+
className: "px-2 py-1.5 rounded-md bg-fuchsia-600 text-white hover:bg-fuchsia-500 transition-colors flex items-center gap-1 shadow-lg animate-in fade-in zoom-in",
|
|
6370
|
+
title: "Renderizar cen\xE1rio at\xE9 o caminho selecionado"
|
|
6371
|
+
},
|
|
6372
|
+
/* @__PURE__ */ import_react10.default.createElement(import_fi9.FiLayers, { size: 13 }),
|
|
6373
|
+
/* @__PURE__ */ import_react10.default.createElement("span", { className: "text-[10px] font-bold uppercase tracking-wider" }, "Renderizar")
|
|
6374
|
+
), /* @__PURE__ */ import_react10.default.createElement(
|
|
6375
|
+
"button",
|
|
6376
|
+
{
|
|
6377
|
+
type: "button",
|
|
6378
|
+
onClick: (e) => {
|
|
6379
|
+
e.stopPropagation();
|
|
6380
|
+
const tempPayload = {
|
|
6381
|
+
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6382
|
+
abstraction_tree: ancestryMode.abstraction_tree
|
|
6383
|
+
};
|
|
6384
|
+
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload);
|
|
6385
|
+
},
|
|
6386
|
+
className: "p-1.5 rounded-md bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600 transition-colors",
|
|
6387
|
+
title: "Renderizar Verticalmente Completo"
|
|
6388
|
+
},
|
|
6389
|
+
/* @__PURE__ */ import_react10.default.createElement(import_fi9.FiLayers, { size: 14 })
|
|
6390
|
+
), /* @__PURE__ */ import_react10.default.createElement(
|
|
6391
|
+
"button",
|
|
6392
|
+
{
|
|
6393
|
+
type: "button",
|
|
6394
|
+
onClick: (e) => {
|
|
6395
|
+
e.stopPropagation();
|
|
6396
|
+
handleToggleAddMode(true);
|
|
6397
|
+
},
|
|
6398
|
+
className: `p-1.5 rounded-md transition-colors ${ancestryMode.isAddingAbstractionNodes ? "bg-purple-500 text-white shadow-lg shadow-purple-500/30" : "bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600"}`,
|
|
6399
|
+
title: "Editar estrutura da abstra\xE7\xE3o"
|
|
6400
|
+
},
|
|
6401
|
+
ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiCheck, { size: 14 }) : /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiEdit2, { size: 14 })
|
|
6402
|
+
))),
|
|
6403
|
+
/* @__PURE__ */ import_react10.default.createElement("div", { className: "p-4 space-y-2" }, ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ import_react10.default.createElement("div", { className: "mb-3 p-2 rounded bg-purple-900/20 border border-purple-500/20 text-xs text-purple-200 flex items-start gap-2" }, /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiMousePointer, { className: "mt-0.5 flex-shrink-0" }), /* @__PURE__ */ import_react10.default.createElement("span", null, "Clique nos nodes do cen\xE1rio para adicion\xE1-los. Arraste e solte para organizar a hierarquia.")), /* @__PURE__ */ import_react10.default.createElement(
|
|
6404
|
+
NodeItem,
|
|
6405
|
+
{
|
|
6406
|
+
nodeData: ancestryMode.abstraction_tree,
|
|
6407
|
+
onSelectParent: (id) => handleSelectAncestryParent(id, true),
|
|
6408
|
+
onViewSelect: setTargetRenderNodeId,
|
|
6409
|
+
highlightedPathIds,
|
|
6410
|
+
targetRenderNodeId,
|
|
6411
|
+
onRemoveNode: (path) => handleRemoveNode(path, true),
|
|
6412
|
+
onEditRelationship,
|
|
6413
|
+
onMoveNode: (s, t) => handleMoveNode(s, t, true),
|
|
6414
|
+
selectedParentId: ancestryMode.selectedAbstractionParentId,
|
|
6415
|
+
level: 0,
|
|
6416
|
+
isLast: true,
|
|
6417
|
+
path: [],
|
|
6418
|
+
isEditable: ancestryMode.isAddingAbstractionNodes
|
|
6419
|
+
}
|
|
6420
|
+
))
|
|
6421
|
+
), branchStack.length === 0 && /* @__PURE__ */ import_react10.default.createElement("div", { className: "mt-3 flex items-center justify-end px-1" }, /* @__PURE__ */ import_react10.default.createElement("label", { className: "flex items-center gap-2 cursor-pointer group select-none" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${isPrivate ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, isPrivate && /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react10.default.createElement(
|
|
6244
6422
|
"input",
|
|
6245
6423
|
{
|
|
6246
6424
|
type: "checkbox",
|
|
@@ -6248,7 +6426,7 @@ function CreateAncestryPanel({
|
|
|
6248
6426
|
onChange: (e) => setIsPrivate(e.target.checked),
|
|
6249
6427
|
className: "hidden"
|
|
6250
6428
|
}
|
|
6251
|
-
), /* @__PURE__ */ import_react10.default.createElement("span", { className: `text-xs flex items-center gap-1 transition-colors ${isPrivate ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiLock, { size: 10 }), " N\xE3o Export\xE1vel"))))), /* @__PURE__ */ import_react10.default.createElement("div", { className: "px-6 pt-2 pb-5 flex-shrink-0" },
|
|
6429
|
+
), /* @__PURE__ */ import_react10.default.createElement("span", { className: `text-xs flex items-center gap-1 transition-colors ${isPrivate ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiLock, { size: 10 }), " N\xE3o Export\xE1vel"))))), /* @__PURE__ */ import_react10.default.createElement("div", { className: "px-6 pt-2 pb-5 flex-shrink-0" }, canSave && /* @__PURE__ */ import_react10.default.createElement(
|
|
6252
6430
|
"button",
|
|
6253
6431
|
{
|
|
6254
6432
|
onClick: () => handleLocalSave(false),
|
|
@@ -8758,7 +8936,7 @@ var getAllNodeIdsFromTree = (treeNode) => {
|
|
|
8758
8936
|
traverse(treeNode);
|
|
8759
8937
|
return Array.from(ids);
|
|
8760
8938
|
};
|
|
8761
|
-
var
|
|
8939
|
+
var findNodePath3 = (tree, targetNodeId, currentPath = []) => {
|
|
8762
8940
|
var _a;
|
|
8763
8941
|
if (!tree) return null;
|
|
8764
8942
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
@@ -8767,7 +8945,7 @@ var findNodePath2 = (tree, targetNodeId, currentPath = []) => {
|
|
|
8767
8945
|
}
|
|
8768
8946
|
if (tree.children) {
|
|
8769
8947
|
for (let i = 0; i < tree.children.length; i++) {
|
|
8770
|
-
const res =
|
|
8948
|
+
const res = findNodePath3(tree.children[i], targetNodeId, [...currentPath, i]);
|
|
8771
8949
|
if (res) return res;
|
|
8772
8950
|
}
|
|
8773
8951
|
}
|
|
@@ -10836,13 +11014,34 @@ function XViewScene({
|
|
|
10836
11014
|
},
|
|
10837
11015
|
[addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, readingMode.isActive, ancestryMode.isActive]
|
|
10838
11016
|
);
|
|
10839
|
-
const handleRenderAbstractionTree = (0, import_react23.useCallback)((ancestryObject) => {
|
|
11017
|
+
const handleRenderAbstractionTree = (0, import_react23.useCallback)((ancestryObject, targetNodeId = null) => {
|
|
10840
11018
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
10841
11019
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
10842
11020
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
10843
11021
|
const allParentNodes = Object.values(parentDataRef.current).flatMap((f) => f.nodes);
|
|
10844
|
-
|
|
11022
|
+
let fullTree = buildFullAncestryTree(ancestryObject.abstraction_tree, allParentNodes, ancestryDataRef.current);
|
|
10845
11023
|
if (!fullTree || !fullTree.node) return;
|
|
11024
|
+
if (targetNodeId) {
|
|
11025
|
+
const pruneTreeToPath = (treeNode, targetId) => {
|
|
11026
|
+
var _a2;
|
|
11027
|
+
if (!treeNode) return null;
|
|
11028
|
+
const currentId = treeNode.is_section ? treeNode.section_id : String((_a2 = treeNode.node) == null ? void 0 : _a2.id);
|
|
11029
|
+
if (String(currentId) === String(targetId)) {
|
|
11030
|
+
return { ...treeNode, children: [] };
|
|
11031
|
+
}
|
|
11032
|
+
if (treeNode.children && treeNode.children.length > 0) {
|
|
11033
|
+
for (let child of treeNode.children) {
|
|
11034
|
+
const prunedChild = pruneTreeToPath(child, targetId);
|
|
11035
|
+
if (prunedChild) {
|
|
11036
|
+
return { ...treeNode, children: [prunedChild] };
|
|
11037
|
+
}
|
|
11038
|
+
}
|
|
11039
|
+
}
|
|
11040
|
+
return null;
|
|
11041
|
+
};
|
|
11042
|
+
const pruned = pruneTreeToPath(fullTree, targetNodeId);
|
|
11043
|
+
if (pruned) fullTree = pruned;
|
|
11044
|
+
}
|
|
10846
11045
|
const absId = ancestryObject.ancestry_id + "_abs";
|
|
10847
11046
|
handleClearAncestryVisuals(absId);
|
|
10848
11047
|
const colorHex = 9133302;
|
|
@@ -10884,13 +11083,13 @@ function XViewScene({
|
|
|
10884
11083
|
if (action === "open") {
|
|
10885
11084
|
let currentPtr = fullTree;
|
|
10886
11085
|
for (const step of branchStack) {
|
|
10887
|
-
const found =
|
|
11086
|
+
const found = findNodePath3(currentPtr, step.nodeId);
|
|
10888
11087
|
if (found && found.node.parallel_branches) {
|
|
10889
11088
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
10890
11089
|
if (branch) currentPtr = branch.tree;
|
|
10891
11090
|
}
|
|
10892
11091
|
}
|
|
10893
|
-
const foundTarget =
|
|
11092
|
+
const foundTarget = findNodePath3(currentPtr, nodeId);
|
|
10894
11093
|
if (foundTarget && foundTarget.node && foundTarget.node.parallel_branches && foundTarget.node.parallel_branches.length > 0) {
|
|
10895
11094
|
const branchToOpen = foundTarget.node.parallel_branches.find((b) => (b.direction || "right") === direction);
|
|
10896
11095
|
if (!branchToOpen) return;
|
|
@@ -10957,7 +11156,7 @@ function XViewScene({
|
|
|
10957
11156
|
if (newStack.length > 0) {
|
|
10958
11157
|
let ptr = fullTree;
|
|
10959
11158
|
for (const step of newStack) {
|
|
10960
|
-
const found =
|
|
11159
|
+
const found = findNodePath3(ptr, step.nodeId);
|
|
10961
11160
|
if (found && found.node.parallel_branches) {
|
|
10962
11161
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
10963
11162
|
if (branch) {
|
|
@@ -11098,7 +11297,7 @@ function XViewScene({
|
|
|
11098
11297
|
let currentMeta = ancestry;
|
|
11099
11298
|
let currentDirection = null;
|
|
11100
11299
|
for (const step of branchStack) {
|
|
11101
|
-
const found =
|
|
11300
|
+
const found = findNodePath3(currentPtr, step.nodeId);
|
|
11102
11301
|
if (found && found.node.parallel_branches) {
|
|
11103
11302
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
11104
11303
|
if (branch) {
|
|
@@ -11118,6 +11317,18 @@ function XViewScene({
|
|
|
11118
11317
|
// <--- ADICIONADO
|
|
11119
11318
|
};
|
|
11120
11319
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
11320
|
+
const readModeAbstractionTree = (0, import_react23.useMemo)(() => {
|
|
11321
|
+
if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
|
|
11322
|
+
return null;
|
|
11323
|
+
}
|
|
11324
|
+
const allNodes = Object.values(parentDataRef.current || {}).flatMap((f) => f.nodes || []);
|
|
11325
|
+
const allAncestries = ancestryDataRef.current || [];
|
|
11326
|
+
return buildFullAncestryTree(
|
|
11327
|
+
readingMode.ancestry.abstraction_tree,
|
|
11328
|
+
allNodes,
|
|
11329
|
+
allAncestries
|
|
11330
|
+
);
|
|
11331
|
+
}, [readingMode.isActive, readingMode.ancestry, buildFullAncestryTree, sceneVersion]);
|
|
11121
11332
|
const handleStartReadingAncestry = (0, import_react23.useCallback)(
|
|
11122
11333
|
async (ancestryObject) => {
|
|
11123
11334
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
@@ -11158,7 +11369,7 @@ function XViewScene({
|
|
|
11158
11369
|
);
|
|
11159
11370
|
let currentPtr = fullTree;
|
|
11160
11371
|
for (const step of branchStack) {
|
|
11161
|
-
const found =
|
|
11372
|
+
const found = findNodePath3(currentPtr, step.nodeId);
|
|
11162
11373
|
if (found && found.node && found.node.parallel_branches) {
|
|
11163
11374
|
const branch = found.node.parallel_branches.find((b) => b.id === step.branchId);
|
|
11164
11375
|
if (branch) {
|
|
@@ -11709,6 +11920,13 @@ function XViewScene({
|
|
|
11709
11920
|
const handleToggleAncestryAddMode = (0, import_react23.useCallback)(() => {
|
|
11710
11921
|
setAncestryMode((prev) => ({ ...prev, isAddingNodes: !prev.isAddingNodes }));
|
|
11711
11922
|
}, []);
|
|
11923
|
+
const handleFocusNode = (0, import_react23.useCallback)((nodeData) => {
|
|
11924
|
+
if (!nodeData) return;
|
|
11925
|
+
const nodeMesh = stateRef.current.nodeObjects[String(nodeData.id)];
|
|
11926
|
+
if (nodeMesh) {
|
|
11927
|
+
tweenToTarget(nodeMesh, 1.2);
|
|
11928
|
+
}
|
|
11929
|
+
}, [tweenToTarget]);
|
|
11712
11930
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
11713
11931
|
return /* @__PURE__ */ import_react23.default.createElement(LoadingScreen, null);
|
|
11714
11932
|
}
|
|
@@ -11826,7 +12044,9 @@ function XViewScene({
|
|
|
11826
12044
|
activeNodeBranches,
|
|
11827
12045
|
backNavigationInfo,
|
|
11828
12046
|
onImageClick: (url, name) => handleOpenImageViewer([{ name: name || "Imagem", value: url }], 0),
|
|
11829
|
-
userRole: userPermissionRole
|
|
12047
|
+
userRole: userPermissionRole,
|
|
12048
|
+
abstractionTree: readModeAbstractionTree,
|
|
12049
|
+
onRenderAbstractionTree: (targetId) => handleRenderAbstractionTree(readingMode.ancestry, targetId)
|
|
11830
12050
|
}
|
|
11831
12051
|
)
|
|
11832
12052
|
),
|
|
@@ -11834,6 +12054,7 @@ function XViewScene({
|
|
|
11834
12054
|
CreateAncestryPanel,
|
|
11835
12055
|
{
|
|
11836
12056
|
ancestryMode,
|
|
12057
|
+
setAncestryMode,
|
|
11837
12058
|
onSelectParent: handleSelectAncestryParent,
|
|
11838
12059
|
onRemoveNode: handleRemoveFromAncestry,
|
|
11839
12060
|
onSave: handleSaveAncestry,
|
|
@@ -11853,7 +12074,7 @@ function XViewScene({
|
|
|
11853
12074
|
onClearAncestryVisuals: handleClearAncestryVisuals,
|
|
11854
12075
|
onUploadFile: upload_file_action,
|
|
11855
12076
|
onOpenImageViewer: handleOpenImageViewer,
|
|
11856
|
-
onRenderAbstractionTree: (data) => handleRenderAbstractionTree(data)
|
|
12077
|
+
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
11857
12078
|
}
|
|
11858
12079
|
),
|
|
11859
12080
|
editingAncestryRel.visible && /* @__PURE__ */ import_react23.default.createElement(
|
|
@@ -11967,7 +12188,8 @@ function XViewScene({
|
|
|
11967
12188
|
onExpandConnections: (sourceNode, links) => userActionHandlers.handleExpandConnections(actionHandlerContext, sourceNode, links),
|
|
11968
12189
|
onRenderAncestry: handleStartReadingAncestry,
|
|
11969
12190
|
onEditAncestry: handleEditAncestry,
|
|
11970
|
-
onDeleteAncestry: (ancestryId) => handleDeleteAncestry(ancestryId)
|
|
12191
|
+
onDeleteAncestry: (ancestryId) => handleDeleteAncestry(ancestryId),
|
|
12192
|
+
onFocusNode: handleFocusNode
|
|
11971
12193
|
}
|
|
11972
12194
|
),
|
|
11973
12195
|
/* @__PURE__ */ import_react23.default.createElement(
|