@lv-x-software-house/x_view 1.1.9-dev.2 → 1.1.9-dev.5
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 +191 -131
- package/dist/index.mjs +191 -131
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -186,8 +186,8 @@ function ContextMenu({
|
|
|
186
186
|
return !isVisible;
|
|
187
187
|
}).map((link) => {
|
|
188
188
|
const isSource = String(link.source) === String(data.nodeData.id);
|
|
189
|
-
const
|
|
190
|
-
const targetNode = nodeMap.get(String(
|
|
189
|
+
const targetNodeId2 = isSource ? link.target : link.source;
|
|
190
|
+
const targetNode = nodeMap.get(String(targetNodeId2));
|
|
191
191
|
return { link, targetNode, direction: isSource ? "outgoing" : "incoming" };
|
|
192
192
|
}).filter((c) => {
|
|
193
193
|
var _a2;
|
|
@@ -1812,16 +1812,16 @@ var userActionHandlers = {
|
|
|
1812
1812
|
linksToExpand.forEach((link) => {
|
|
1813
1813
|
var _a;
|
|
1814
1814
|
const isSource = String(link.source) === String(sourceNode.id);
|
|
1815
|
-
const
|
|
1815
|
+
const targetNodeId2 = isSource ? link.target : link.source;
|
|
1816
1816
|
const linkAlreadyInSceneData = sceneDataRef.current.links.some((l) => String(l.id) === String(link.id));
|
|
1817
1817
|
if (!linkAlreadyInSceneData) {
|
|
1818
1818
|
sceneDataRef.current.links.push(link);
|
|
1819
1819
|
}
|
|
1820
|
-
if (!nodeObjects[String(
|
|
1820
|
+
if (!nodeObjects[String(targetNodeId2)]) {
|
|
1821
1821
|
const allParentNodes = Object.values(graphDataRef.current).flatMap((fileData) => fileData.nodes);
|
|
1822
|
-
const nodeData = allParentNodes.find((n) => String(n.id) === String(
|
|
1822
|
+
const nodeData = allParentNodes.find((n) => String(n.id) === String(targetNodeId2));
|
|
1823
1823
|
if (!nodeData) {
|
|
1824
|
-
console.warn(`Dados do Node com ID ${
|
|
1824
|
+
console.warn(`Dados do Node com ID ${targetNodeId2} n\xE3o encontrados no cache.`);
|
|
1825
1825
|
return;
|
|
1826
1826
|
}
|
|
1827
1827
|
if (!sceneDataRef.current.nodes.some((n) => String(n.id) === String(nodeData.id))) {
|
|
@@ -1838,7 +1838,7 @@ var userActionHandlers = {
|
|
|
1838
1838
|
if (targetMesh.userData.labelObject) {
|
|
1839
1839
|
graphGroup.add(targetMesh.userData.labelObject);
|
|
1840
1840
|
}
|
|
1841
|
-
nodeObjects[String(
|
|
1841
|
+
nodeObjects[String(targetNodeId2)] = targetMesh;
|
|
1842
1842
|
clickableNodes.push(targetMesh);
|
|
1843
1843
|
const posTween = new import_tween.Tween(targetMesh.position).to(endPosition, 1200).easing(import_tween.Easing.Quadratic.Out);
|
|
1844
1844
|
tweenGroup.add(posTween);
|
|
@@ -2698,7 +2698,10 @@ var IGNORED_KEYS = [
|
|
|
2698
2698
|
"isAddingNodes",
|
|
2699
2699
|
"ancestryDescriptionSections",
|
|
2700
2700
|
"direction",
|
|
2701
|
-
"is_private"
|
|
2701
|
+
"is_private",
|
|
2702
|
+
"abstraction_tree",
|
|
2703
|
+
"selectedAbstractionParentId",
|
|
2704
|
+
"isAddingAbstractionNodes"
|
|
2702
2705
|
];
|
|
2703
2706
|
function extractCustomPropsFromNode(node) {
|
|
2704
2707
|
const customPropTypes = node._customPropTypes || {};
|
|
@@ -4871,31 +4874,50 @@ function AncestryPickerModal({
|
|
|
4871
4874
|
}
|
|
4872
4875
|
|
|
4873
4876
|
// src/components/CreateAncestryPanel.jsx
|
|
4874
|
-
var findNodePath = (tree,
|
|
4877
|
+
var findNodePath = (tree, targetNodeId2, currentPath = []) => {
|
|
4875
4878
|
var _a;
|
|
4876
4879
|
if (!tree) return null;
|
|
4877
4880
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
4878
|
-
if (String(currentNodeId) === String(
|
|
4881
|
+
if (String(currentNodeId) === String(targetNodeId2)) {
|
|
4879
4882
|
return { node: tree, path: currentPath };
|
|
4880
4883
|
}
|
|
4881
4884
|
if (tree.children) {
|
|
4882
4885
|
for (let i = 0; i < tree.children.length; i++) {
|
|
4883
|
-
const res = findNodePath(tree.children[i],
|
|
4886
|
+
const res = findNodePath(tree.children[i], targetNodeId2, [...currentPath, i]);
|
|
4884
4887
|
if (res) return res;
|
|
4885
4888
|
}
|
|
4886
4889
|
}
|
|
4887
4890
|
return null;
|
|
4888
4891
|
};
|
|
4889
|
-
var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, onMoveNode, selectedParentId, level = 0, isLast = false, path = [], isEditable }) => {
|
|
4892
|
+
var NodeItem = ({ nodeData, onSelectParent, onViewSelect, highlightedPathIds = [], targetRenderNodeId, onRemoveNode, onEditRelationship, onMoveNode, selectedParentId, level = 0, isLast = false, path = [], isEditable }) => {
|
|
4890
4893
|
var _a, _b;
|
|
4891
4894
|
const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
|
|
4892
4895
|
const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
|
|
4893
4896
|
const [isDragOver, setIsDragOver] = (0, import_react10.useState)(false);
|
|
4894
|
-
const
|
|
4897
|
+
const isSelectedParent = String(selectedParentId) === String(itemId);
|
|
4898
|
+
const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
|
|
4899
|
+
const isHighlightedPath = highlightedPathIds.includes(String(itemId));
|
|
4895
4900
|
const hasChildren = nodeData.children && nodeData.children.length > 0;
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4901
|
+
let itemBgClass = "bg-slate-900/50 hover:bg-slate-800/80";
|
|
4902
|
+
let textColorClass = "text-slate-200";
|
|
4903
|
+
if (nodeData.is_section) {
|
|
4904
|
+
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";
|
|
4905
|
+
textColorClass = isSelectedParent ? "text-indigo-200 font-bold" : "text-indigo-300";
|
|
4906
|
+
} else {
|
|
4907
|
+
if (isSelectedParent) {
|
|
4908
|
+
itemBgClass = "bg-purple-500/30 ring-2 ring-purple-400";
|
|
4909
|
+
textColorClass = "text-purple-200 font-semibold";
|
|
4910
|
+
} else if (isTargetViewNode) {
|
|
4911
|
+
itemBgClass = "bg-fuchsia-600/40 ring-2 ring-fuchsia-400 shadow-[0_0_15px_rgba(217,70,239,0.3)]";
|
|
4912
|
+
textColorClass = "text-white font-bold";
|
|
4913
|
+
} else if (isHighlightedPath) {
|
|
4914
|
+
itemBgClass = "bg-fuchsia-900/30 border border-fuchsia-500/40";
|
|
4915
|
+
textColorClass = "text-fuchsia-200 font-semibold";
|
|
4916
|
+
} else {
|
|
4917
|
+
textColorClass = "text-slate-200";
|
|
4918
|
+
}
|
|
4919
|
+
}
|
|
4920
|
+
const cursorClass = isEditable ? "cursor-grab active:cursor-grabbing" : "cursor-pointer";
|
|
4899
4921
|
const handleDragStart = (e) => {
|
|
4900
4922
|
if (!isEditable) {
|
|
4901
4923
|
e.preventDefault();
|
|
@@ -4925,23 +4947,9 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4925
4947
|
if (!isEditable) return;
|
|
4926
4948
|
const sourceId = e.dataTransfer.getData("nodeId");
|
|
4927
4949
|
if (sourceId === String(itemId)) return;
|
|
4928
|
-
if (onMoveNode)
|
|
4929
|
-
onMoveNode(sourceId, itemId);
|
|
4930
|
-
}
|
|
4950
|
+
if (onMoveNode) onMoveNode(sourceId, itemId);
|
|
4931
4951
|
};
|
|
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(
|
|
4952
|
+
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
4953
|
"div",
|
|
4946
4954
|
{
|
|
4947
4955
|
draggable: isEditable,
|
|
@@ -4949,63 +4957,35 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4949
4957
|
onDragOver: handleDragOver,
|
|
4950
4958
|
onDragLeave: handleDragLeave,
|
|
4951
4959
|
onDrop: handleDrop,
|
|
4952
|
-
onClick: () => {
|
|
4960
|
+
onClick: (e) => {
|
|
4961
|
+
e.stopPropagation();
|
|
4953
4962
|
if (isEditable) {
|
|
4954
4963
|
onSelectParent(itemId);
|
|
4964
|
+
} else if (onViewSelect) {
|
|
4965
|
+
onViewSelect(itemId);
|
|
4955
4966
|
}
|
|
4956
4967
|
},
|
|
4957
4968
|
className: `flex items-center justify-between gap-2 px-3 h-9 rounded-md transition-all duration-150 border
|
|
4958
4969
|
${isDragOver ? "border-dashed border-yellow-400 bg-yellow-400/10" : "border-transparent"}
|
|
4959
4970
|
${itemBgClass} ${cursorClass}`
|
|
4960
4971
|
},
|
|
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
|
-
))
|
|
4972
|
+
/* @__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),
|
|
4973
|
+
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) => {
|
|
4974
|
+
e.stopPropagation();
|
|
4975
|
+
onEditRelationship(path, nodeData.relationship || {});
|
|
4976
|
+
}, 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) => {
|
|
4977
|
+
e.stopPropagation();
|
|
4978
|
+
onRemoveNode(path);
|
|
4979
|
+
}, 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
4980
|
), 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
4981
|
NodeItem,
|
|
5005
4982
|
{
|
|
5006
4983
|
key: `${child.is_section ? child.id : child.node.id}-${index}`,
|
|
5007
4984
|
nodeData: child,
|
|
5008
4985
|
onSelectParent,
|
|
4986
|
+
onViewSelect,
|
|
4987
|
+
highlightedPathIds,
|
|
4988
|
+
targetRenderNodeId,
|
|
5009
4989
|
onRemoveNode,
|
|
5010
4990
|
onEditRelationship,
|
|
5011
4991
|
onMoveNode,
|
|
@@ -5020,11 +5000,8 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
5020
5000
|
function CreateAncestryPanel({
|
|
5021
5001
|
ancestryMode,
|
|
5022
5002
|
setAncestryMode,
|
|
5023
|
-
// <--- Nova prop necessária para as novas funções manipuladoras
|
|
5024
5003
|
onSelectParent,
|
|
5025
|
-
// Mantido para compatibilidade, mas as novas funções usam setAncestryMode
|
|
5026
5004
|
onRemoveNode,
|
|
5027
|
-
// Mantido para compatibilidade
|
|
5028
5005
|
onSave,
|
|
5029
5006
|
onClose,
|
|
5030
5007
|
onEditRelationship,
|
|
@@ -5035,14 +5012,12 @@ function CreateAncestryPanel({
|
|
|
5035
5012
|
onUpdateTree,
|
|
5036
5013
|
onAncestrySectionChange,
|
|
5037
5014
|
onToggleAddNodes,
|
|
5038
|
-
// Mantido para compatibilidade
|
|
5039
5015
|
onRenderFullAncestry,
|
|
5040
5016
|
onHighlightNode,
|
|
5041
5017
|
onClearAncestryVisuals,
|
|
5042
5018
|
onUploadFile,
|
|
5043
5019
|
onOpenImageViewer,
|
|
5044
5020
|
onRenderAbstractionTree
|
|
5045
|
-
// <--- Nova prop recebida
|
|
5046
5021
|
}) {
|
|
5047
5022
|
const {
|
|
5048
5023
|
tree: rootTree,
|
|
@@ -5059,6 +5034,20 @@ function CreateAncestryPanel({
|
|
|
5059
5034
|
const [customProps, setCustomProps] = (0, import_react10.useState)([]);
|
|
5060
5035
|
const propsEndRef = (0, import_react10.useRef)(null);
|
|
5061
5036
|
const [branchStack, setBranchStack] = (0, import_react10.useState)([]);
|
|
5037
|
+
const [targetRenderNodeId, setTargetRenderNodeId] = (0, import_react10.useState)(null);
|
|
5038
|
+
const highlightedPathIds = (0, import_react10.useMemo)(() => {
|
|
5039
|
+
var _a, _b;
|
|
5040
|
+
if (!targetRenderNodeId || !ancestryMode.abstraction_tree) return [];
|
|
5041
|
+
const found = findNodePath(ancestryMode.abstraction_tree, targetRenderNodeId);
|
|
5042
|
+
if (!found) return [];
|
|
5043
|
+
let current = ancestryMode.abstraction_tree;
|
|
5044
|
+
const ids = [current.is_section ? current.section_id : String((_a = current.node) == null ? void 0 : _a.id)];
|
|
5045
|
+
for (let i of found.path) {
|
|
5046
|
+
current = current.children[i];
|
|
5047
|
+
ids.push(current.is_section ? current.section_id : String((_b = current.node) == null ? void 0 : _b.id));
|
|
5048
|
+
}
|
|
5049
|
+
return ids;
|
|
5050
|
+
}, [targetRenderNodeId, ancestryMode.abstraction_tree]);
|
|
5062
5051
|
const [targetScrollSectionId, setTargetScrollSectionId] = (0, import_react10.useState)(null);
|
|
5063
5052
|
const [internalHighlightedNodeId, setInternalHighlightedNodeId] = (0, import_react10.useState)(null);
|
|
5064
5053
|
const [ancestryName, setAncestryName] = (0, import_react10.useState)(initialName);
|
|
@@ -5082,6 +5071,9 @@ function CreateAncestryPanel({
|
|
|
5082
5071
|
setAncestryMode((prev) => isAbstraction ? { ...prev, selectedAbstractionParentId: nodeId } : { ...prev, selectedParentId: nodeId });
|
|
5083
5072
|
};
|
|
5084
5073
|
const handleToggleAddMode = (isAbstraction = false) => {
|
|
5074
|
+
if (isAbstraction && !ancestryMode.isAddingAbstractionNodes) {
|
|
5075
|
+
setTargetRenderNodeId(null);
|
|
5076
|
+
}
|
|
5085
5077
|
setAncestryMode((prev) => isAbstraction ? { ...prev, isAddingAbstractionNodes: !prev.isAddingAbstractionNodes } : { ...prev, isAddingNodes: !prev.isAddingNodes });
|
|
5086
5078
|
};
|
|
5087
5079
|
const handleRemoveNode = (0, import_react10.useCallback)((pathToRemove, isAbstraction = false) => {
|
|
@@ -5163,14 +5155,15 @@ function CreateAncestryPanel({
|
|
|
5163
5155
|
}
|
|
5164
5156
|
}
|
|
5165
5157
|
};
|
|
5166
|
-
const takeSnapshot = (tree, name, desc, sections, customProps2, isPrivateVal) => {
|
|
5158
|
+
const takeSnapshot = (tree, name, desc, sections, customProps2, isPrivateVal, abstractionTree = null) => {
|
|
5167
5159
|
return {
|
|
5168
5160
|
tree: JSON.stringify(tree),
|
|
5169
5161
|
name,
|
|
5170
5162
|
description: desc || "",
|
|
5171
5163
|
sections: JSON.stringify(sections || []),
|
|
5172
5164
|
customProps: JSON.stringify(customProps2 || []),
|
|
5173
|
-
isPrivate: isPrivateVal
|
|
5165
|
+
isPrivate: isPrivateVal,
|
|
5166
|
+
abstractionTree: JSON.stringify(abstractionTree)
|
|
5174
5167
|
};
|
|
5175
5168
|
};
|
|
5176
5169
|
const getCurrentContext = () => {
|
|
@@ -5304,7 +5297,8 @@ function CreateAncestryPanel({
|
|
|
5304
5297
|
ancestryMode.ancestryDescription,
|
|
5305
5298
|
ancestryMode.ancestryDescriptionSections,
|
|
5306
5299
|
extractedProps,
|
|
5307
|
-
ancestryMode.is_private
|
|
5300
|
+
ancestryMode.is_private,
|
|
5301
|
+
ancestryMode.abstraction_tree
|
|
5308
5302
|
));
|
|
5309
5303
|
} else if (ctx) {
|
|
5310
5304
|
setLastSavedSnapshot(takeSnapshot(
|
|
@@ -5313,7 +5307,8 @@ function CreateAncestryPanel({
|
|
|
5313
5307
|
ctx.description,
|
|
5314
5308
|
ctx.sections,
|
|
5315
5309
|
extractedProps,
|
|
5316
|
-
isPrivate
|
|
5310
|
+
isPrivate,
|
|
5311
|
+
ancestryMode.abstraction_tree
|
|
5317
5312
|
));
|
|
5318
5313
|
}
|
|
5319
5314
|
}, [branchStack, ancestryMode]);
|
|
@@ -5356,7 +5351,7 @@ function CreateAncestryPanel({
|
|
|
5356
5351
|
rootTreeClone,
|
|
5357
5352
|
rootExtras
|
|
5358
5353
|
);
|
|
5359
|
-
setLastSavedSnapshot(takeSnapshot(rootTreeClone, ancestryName, description, processedSections, [], isPrivate));
|
|
5354
|
+
setLastSavedSnapshot(takeSnapshot(rootTreeClone, ancestryName, description, processedSections, [], isPrivate, ancestryMode.abstraction_tree));
|
|
5360
5355
|
if (onRenderFullAncestry) {
|
|
5361
5356
|
const fullTreePayload = {
|
|
5362
5357
|
ancestry_id: ancestryMode.currentAncestryId || "temp_root",
|
|
@@ -5417,7 +5412,8 @@ function CreateAncestryPanel({
|
|
|
5417
5412
|
ancestryMode.ancestryDescription,
|
|
5418
5413
|
ancestryMode.ancestryDescriptionSections,
|
|
5419
5414
|
currentRootProps,
|
|
5420
|
-
isPrivate
|
|
5415
|
+
isPrivate,
|
|
5416
|
+
ancestryMode.abstraction_tree
|
|
5421
5417
|
));
|
|
5422
5418
|
if (onClearAncestryVisuals) {
|
|
5423
5419
|
onClearAncestryVisuals(currentStep.branchId);
|
|
@@ -5606,6 +5602,11 @@ function CreateAncestryPanel({
|
|
|
5606
5602
|
const sectionsChanged = JSON.stringify(existingSections) !== lastSavedSnapshot.sections;
|
|
5607
5603
|
const propsChanged = JSON.stringify(customProps) !== lastSavedSnapshot.customProps;
|
|
5608
5604
|
const privateChanged = isPrivate !== lastSavedSnapshot.isPrivate;
|
|
5605
|
+
let abstractionTreeChanged = false;
|
|
5606
|
+
if (branchStack.length === 0) {
|
|
5607
|
+
const currentAbsTreeStr = JSON.stringify(ancestryMode.abstraction_tree);
|
|
5608
|
+
abstractionTreeChanged = currentAbsTreeStr !== lastSavedSnapshot.abstractionTree;
|
|
5609
|
+
}
|
|
5609
5610
|
return treeChanged || nameChanged || descChanged || sectionsChanged || propsChanged || privateChanged;
|
|
5610
5611
|
}, [
|
|
5611
5612
|
ancestryName,
|
|
@@ -5615,6 +5616,7 @@ function CreateAncestryPanel({
|
|
|
5615
5616
|
branchStack,
|
|
5616
5617
|
lastSavedSnapshot,
|
|
5617
5618
|
ancestryMode.tree,
|
|
5619
|
+
ancestryMode.abstraction_tree,
|
|
5618
5620
|
customProps,
|
|
5619
5621
|
isPrivate
|
|
5620
5622
|
]);
|
|
@@ -5857,7 +5859,8 @@ function CreateAncestryPanel({
|
|
|
5857
5859
|
currentInputDesc,
|
|
5858
5860
|
processedSections,
|
|
5859
5861
|
customProps,
|
|
5860
|
-
isPrivate
|
|
5862
|
+
isPrivate,
|
|
5863
|
+
ancestryMode.abstraction_tree
|
|
5861
5864
|
));
|
|
5862
5865
|
if (onRenderFullAncestry) {
|
|
5863
5866
|
const rotation = branchStack.reduce((acc, step) => {
|
|
@@ -5916,7 +5919,8 @@ function CreateAncestryPanel({
|
|
|
5916
5919
|
currentInputDesc,
|
|
5917
5920
|
processedSections,
|
|
5918
5921
|
customProps,
|
|
5919
|
-
isPrivate
|
|
5922
|
+
isPrivate,
|
|
5923
|
+
ancestryMode.abstraction_tree
|
|
5920
5924
|
));
|
|
5921
5925
|
if (!keepOpen) onClose();
|
|
5922
5926
|
} finally {
|
|
@@ -5969,7 +5973,9 @@ function CreateAncestryPanel({
|
|
|
5969
5973
|
const node = findNode(activeTree, selectedParentId);
|
|
5970
5974
|
return node ? node.name : "Nenhum";
|
|
5971
5975
|
};
|
|
5972
|
-
const
|
|
5976
|
+
const hasMainChildren = activeTree && activeTree.children && activeTree.children.length > 0;
|
|
5977
|
+
const hasAbstractionChildren = branchStack.length === 0 && ancestryMode.abstraction_tree && ancestryMode.abstraction_tree.children && ancestryMode.abstraction_tree.children.length > 0;
|
|
5978
|
+
const canSave = hasMainChildren || hasAbstractionChildren;
|
|
5973
5979
|
const handleSectionChangeWrapper = (sectionId) => {
|
|
5974
5980
|
const ctx = getCurrentContext();
|
|
5975
5981
|
const currentDesc = ctx ? ctx.description : description;
|
|
@@ -6203,44 +6209,77 @@ function CreateAncestryPanel({
|
|
|
6203
6209
|
path: [],
|
|
6204
6210
|
isEditable: isAddingNodes
|
|
6205
6211
|
}
|
|
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",
|
|
6212
|
+
), (!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(
|
|
6213
|
+
"div",
|
|
6223
6214
|
{
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
title: "Editar estrutura da abstra\xE7\xE3o"
|
|
6215
|
+
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"}`,
|
|
6216
|
+
onClick: () => setTargetRenderNodeId(null)
|
|
6227
6217
|
},
|
|
6228
|
-
ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ import_react10.default.createElement(
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6218
|
+
/* @__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"}` }, "Estrutura 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(
|
|
6219
|
+
"button",
|
|
6220
|
+
{
|
|
6221
|
+
type: "button",
|
|
6222
|
+
onClick: (e) => {
|
|
6223
|
+
e.stopPropagation();
|
|
6224
|
+
const tempPayload = {
|
|
6225
|
+
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6226
|
+
abstraction_tree: ancestryMode.abstraction_tree
|
|
6227
|
+
};
|
|
6228
|
+
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload, targetRenderNodeId);
|
|
6229
|
+
},
|
|
6230
|
+
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",
|
|
6231
|
+
title: "Renderizar cen\xE1rio at\xE9 o caminho selecionado"
|
|
6232
|
+
},
|
|
6233
|
+
/* @__PURE__ */ import_react10.default.createElement(import_fi9.FiLayers, { size: 13 }),
|
|
6234
|
+
/* @__PURE__ */ import_react10.default.createElement("span", { className: "text-[10px] font-bold uppercase tracking-wider" }, "Caminho")
|
|
6235
|
+
), /* @__PURE__ */ import_react10.default.createElement(
|
|
6236
|
+
"button",
|
|
6237
|
+
{
|
|
6238
|
+
type: "button",
|
|
6239
|
+
onClick: (e) => {
|
|
6240
|
+
e.stopPropagation();
|
|
6241
|
+
const tempPayload = {
|
|
6242
|
+
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6243
|
+
abstraction_tree: ancestryMode.abstraction_tree
|
|
6244
|
+
};
|
|
6245
|
+
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload);
|
|
6246
|
+
},
|
|
6247
|
+
className: "p-1.5 rounded-md bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600 transition-colors",
|
|
6248
|
+
title: "Renderizar Verticalmente Completo"
|
|
6249
|
+
},
|
|
6250
|
+
/* @__PURE__ */ import_react10.default.createElement(import_fi9.FiLayers, { size: 14 })
|
|
6251
|
+
), /* @__PURE__ */ import_react10.default.createElement(
|
|
6252
|
+
"button",
|
|
6253
|
+
{
|
|
6254
|
+
type: "button",
|
|
6255
|
+
onClick: (e) => {
|
|
6256
|
+
e.stopPropagation();
|
|
6257
|
+
handleToggleAddMode(true);
|
|
6258
|
+
},
|
|
6259
|
+
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"}`,
|
|
6260
|
+
title: "Editar estrutura da abstra\xE7\xE3o"
|
|
6261
|
+
},
|
|
6262
|
+
ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiCheck, { size: 14 }) : /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiEdit2, { size: 14 })
|
|
6263
|
+
))),
|
|
6264
|
+
/* @__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(
|
|
6265
|
+
NodeItem,
|
|
6266
|
+
{
|
|
6267
|
+
nodeData: ancestryMode.abstraction_tree,
|
|
6268
|
+
onSelectParent: (id) => handleSelectAncestryParent(id, true),
|
|
6269
|
+
onViewSelect: setTargetRenderNodeId,
|
|
6270
|
+
highlightedPathIds,
|
|
6271
|
+
targetRenderNodeId,
|
|
6272
|
+
onRemoveNode: (path) => handleRemoveNode(path, true),
|
|
6273
|
+
onEditRelationship,
|
|
6274
|
+
onMoveNode: (s, t) => handleMoveNode(s, t, true),
|
|
6275
|
+
selectedParentId: ancestryMode.selectedAbstractionParentId,
|
|
6276
|
+
level: 0,
|
|
6277
|
+
isLast: true,
|
|
6278
|
+
path: [],
|
|
6279
|
+
isEditable: ancestryMode.isAddingAbstractionNodes
|
|
6280
|
+
}
|
|
6281
|
+
))
|
|
6282
|
+
), 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
6283
|
"input",
|
|
6245
6284
|
{
|
|
6246
6285
|
type: "checkbox",
|
|
@@ -6248,7 +6287,7 @@ function CreateAncestryPanel({
|
|
|
6248
6287
|
onChange: (e) => setIsPrivate(e.target.checked),
|
|
6249
6288
|
className: "hidden"
|
|
6250
6289
|
}
|
|
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" },
|
|
6290
|
+
), /* @__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
6291
|
"button",
|
|
6253
6292
|
{
|
|
6254
6293
|
onClick: () => handleLocalSave(false),
|
|
@@ -8758,16 +8797,16 @@ var getAllNodeIdsFromTree = (treeNode) => {
|
|
|
8758
8797
|
traverse(treeNode);
|
|
8759
8798
|
return Array.from(ids);
|
|
8760
8799
|
};
|
|
8761
|
-
var findNodePath2 = (tree,
|
|
8800
|
+
var findNodePath2 = (tree, targetNodeId2, currentPath = []) => {
|
|
8762
8801
|
var _a;
|
|
8763
8802
|
if (!tree) return null;
|
|
8764
8803
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
8765
|
-
if (String(currentNodeId) === String(
|
|
8804
|
+
if (String(currentNodeId) === String(targetNodeId2)) {
|
|
8766
8805
|
return { node: tree, path: currentPath };
|
|
8767
8806
|
}
|
|
8768
8807
|
if (tree.children) {
|
|
8769
8808
|
for (let i = 0; i < tree.children.length; i++) {
|
|
8770
|
-
const res = findNodePath2(tree.children[i],
|
|
8809
|
+
const res = findNodePath2(tree.children[i], targetNodeId2, [...currentPath, i]);
|
|
8771
8810
|
if (res) return res;
|
|
8772
8811
|
}
|
|
8773
8812
|
}
|
|
@@ -10841,8 +10880,29 @@ function XViewScene({
|
|
|
10841
10880
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
10842
10881
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
10843
10882
|
const allParentNodes = Object.values(parentDataRef.current).flatMap((f) => f.nodes);
|
|
10844
|
-
|
|
10883
|
+
let fullTree = buildFullAncestryTree(ancestryObject.abstraction_tree, allParentNodes, ancestryDataRef.current);
|
|
10845
10884
|
if (!fullTree || !fullTree.node) return;
|
|
10885
|
+
if (targetNodeId) {
|
|
10886
|
+
const pruneTreeToPath = (treeNode, targetId) => {
|
|
10887
|
+
var _a2;
|
|
10888
|
+
if (!treeNode) return null;
|
|
10889
|
+
const currentId = treeNode.is_section ? treeNode.section_id : String((_a2 = treeNode.node) == null ? void 0 : _a2.id);
|
|
10890
|
+
if (String(currentId) === String(targetId)) {
|
|
10891
|
+
return { ...treeNode, children: [] };
|
|
10892
|
+
}
|
|
10893
|
+
if (treeNode.children && treeNode.children.length > 0) {
|
|
10894
|
+
for (let child of treeNode.children) {
|
|
10895
|
+
const prunedChild = pruneTreeToPath(child, targetId);
|
|
10896
|
+
if (prunedChild) {
|
|
10897
|
+
return { ...treeNode, children: [prunedChild] };
|
|
10898
|
+
}
|
|
10899
|
+
}
|
|
10900
|
+
}
|
|
10901
|
+
return null;
|
|
10902
|
+
};
|
|
10903
|
+
const pruned = pruneTreeToPath(fullTree, targetNodeId);
|
|
10904
|
+
if (pruned) fullTree = pruned;
|
|
10905
|
+
}
|
|
10846
10906
|
const absId = ancestryObject.ancestry_id + "_abs";
|
|
10847
10907
|
handleClearAncestryVisuals(absId);
|
|
10848
10908
|
const colorHex = 9133302;
|
|
@@ -11854,7 +11914,7 @@ function XViewScene({
|
|
|
11854
11914
|
onClearAncestryVisuals: handleClearAncestryVisuals,
|
|
11855
11915
|
onUploadFile: upload_file_action,
|
|
11856
11916
|
onOpenImageViewer: handleOpenImageViewer,
|
|
11857
|
-
onRenderAbstractionTree: (data) => handleRenderAbstractionTree(data)
|
|
11917
|
+
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
11858
11918
|
}
|
|
11859
11919
|
),
|
|
11860
11920
|
editingAncestryRel.visible && /* @__PURE__ */ import_react23.default.createElement(
|
package/dist/index.mjs
CHANGED
|
@@ -142,8 +142,8 @@ function ContextMenu({
|
|
|
142
142
|
return !isVisible;
|
|
143
143
|
}).map((link) => {
|
|
144
144
|
const isSource = String(link.source) === String(data.nodeData.id);
|
|
145
|
-
const
|
|
146
|
-
const targetNode = nodeMap.get(String(
|
|
145
|
+
const targetNodeId2 = isSource ? link.target : link.source;
|
|
146
|
+
const targetNode = nodeMap.get(String(targetNodeId2));
|
|
147
147
|
return { link, targetNode, direction: isSource ? "outgoing" : "incoming" };
|
|
148
148
|
}).filter((c) => {
|
|
149
149
|
var _a2;
|
|
@@ -1768,16 +1768,16 @@ var userActionHandlers = {
|
|
|
1768
1768
|
linksToExpand.forEach((link) => {
|
|
1769
1769
|
var _a;
|
|
1770
1770
|
const isSource = String(link.source) === String(sourceNode.id);
|
|
1771
|
-
const
|
|
1771
|
+
const targetNodeId2 = isSource ? link.target : link.source;
|
|
1772
1772
|
const linkAlreadyInSceneData = sceneDataRef.current.links.some((l) => String(l.id) === String(link.id));
|
|
1773
1773
|
if (!linkAlreadyInSceneData) {
|
|
1774
1774
|
sceneDataRef.current.links.push(link);
|
|
1775
1775
|
}
|
|
1776
|
-
if (!nodeObjects[String(
|
|
1776
|
+
if (!nodeObjects[String(targetNodeId2)]) {
|
|
1777
1777
|
const allParentNodes = Object.values(graphDataRef.current).flatMap((fileData) => fileData.nodes);
|
|
1778
|
-
const nodeData = allParentNodes.find((n) => String(n.id) === String(
|
|
1778
|
+
const nodeData = allParentNodes.find((n) => String(n.id) === String(targetNodeId2));
|
|
1779
1779
|
if (!nodeData) {
|
|
1780
|
-
console.warn(`Dados do Node com ID ${
|
|
1780
|
+
console.warn(`Dados do Node com ID ${targetNodeId2} n\xE3o encontrados no cache.`);
|
|
1781
1781
|
return;
|
|
1782
1782
|
}
|
|
1783
1783
|
if (!sceneDataRef.current.nodes.some((n) => String(n.id) === String(nodeData.id))) {
|
|
@@ -1794,7 +1794,7 @@ var userActionHandlers = {
|
|
|
1794
1794
|
if (targetMesh.userData.labelObject) {
|
|
1795
1795
|
graphGroup.add(targetMesh.userData.labelObject);
|
|
1796
1796
|
}
|
|
1797
|
-
nodeObjects[String(
|
|
1797
|
+
nodeObjects[String(targetNodeId2)] = targetMesh;
|
|
1798
1798
|
clickableNodes.push(targetMesh);
|
|
1799
1799
|
const posTween = new Tween(targetMesh.position).to(endPosition, 1200).easing(Easing.Quadratic.Out);
|
|
1800
1800
|
tweenGroup.add(posTween);
|
|
@@ -2654,7 +2654,10 @@ var IGNORED_KEYS = [
|
|
|
2654
2654
|
"isAddingNodes",
|
|
2655
2655
|
"ancestryDescriptionSections",
|
|
2656
2656
|
"direction",
|
|
2657
|
-
"is_private"
|
|
2657
|
+
"is_private",
|
|
2658
|
+
"abstraction_tree",
|
|
2659
|
+
"selectedAbstractionParentId",
|
|
2660
|
+
"isAddingAbstractionNodes"
|
|
2658
2661
|
];
|
|
2659
2662
|
function extractCustomPropsFromNode(node) {
|
|
2660
2663
|
const customPropTypes = node._customPropTypes || {};
|
|
@@ -4852,31 +4855,50 @@ function AncestryPickerModal({
|
|
|
4852
4855
|
}
|
|
4853
4856
|
|
|
4854
4857
|
// src/components/CreateAncestryPanel.jsx
|
|
4855
|
-
var findNodePath = (tree,
|
|
4858
|
+
var findNodePath = (tree, targetNodeId2, currentPath = []) => {
|
|
4856
4859
|
var _a;
|
|
4857
4860
|
if (!tree) return null;
|
|
4858
4861
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
4859
|
-
if (String(currentNodeId) === String(
|
|
4862
|
+
if (String(currentNodeId) === String(targetNodeId2)) {
|
|
4860
4863
|
return { node: tree, path: currentPath };
|
|
4861
4864
|
}
|
|
4862
4865
|
if (tree.children) {
|
|
4863
4866
|
for (let i = 0; i < tree.children.length; i++) {
|
|
4864
|
-
const res = findNodePath(tree.children[i],
|
|
4867
|
+
const res = findNodePath(tree.children[i], targetNodeId2, [...currentPath, i]);
|
|
4865
4868
|
if (res) return res;
|
|
4866
4869
|
}
|
|
4867
4870
|
}
|
|
4868
4871
|
return null;
|
|
4869
4872
|
};
|
|
4870
|
-
var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, onMoveNode, selectedParentId, level = 0, isLast = false, path = [], isEditable }) => {
|
|
4873
|
+
var NodeItem = ({ nodeData, onSelectParent, onViewSelect, highlightedPathIds = [], targetRenderNodeId, onRemoveNode, onEditRelationship, onMoveNode, selectedParentId, level = 0, isLast = false, path = [], isEditable }) => {
|
|
4871
4874
|
var _a, _b;
|
|
4872
4875
|
const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
|
|
4873
4876
|
const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
|
|
4874
4877
|
const [isDragOver, setIsDragOver] = useState10(false);
|
|
4875
|
-
const
|
|
4878
|
+
const isSelectedParent = String(selectedParentId) === String(itemId);
|
|
4879
|
+
const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
|
|
4880
|
+
const isHighlightedPath = highlightedPathIds.includes(String(itemId));
|
|
4876
4881
|
const hasChildren = nodeData.children && nodeData.children.length > 0;
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4882
|
+
let itemBgClass = "bg-slate-900/50 hover:bg-slate-800/80";
|
|
4883
|
+
let textColorClass = "text-slate-200";
|
|
4884
|
+
if (nodeData.is_section) {
|
|
4885
|
+
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";
|
|
4886
|
+
textColorClass = isSelectedParent ? "text-indigo-200 font-bold" : "text-indigo-300";
|
|
4887
|
+
} else {
|
|
4888
|
+
if (isSelectedParent) {
|
|
4889
|
+
itemBgClass = "bg-purple-500/30 ring-2 ring-purple-400";
|
|
4890
|
+
textColorClass = "text-purple-200 font-semibold";
|
|
4891
|
+
} else if (isTargetViewNode) {
|
|
4892
|
+
itemBgClass = "bg-fuchsia-600/40 ring-2 ring-fuchsia-400 shadow-[0_0_15px_rgba(217,70,239,0.3)]";
|
|
4893
|
+
textColorClass = "text-white font-bold";
|
|
4894
|
+
} else if (isHighlightedPath) {
|
|
4895
|
+
itemBgClass = "bg-fuchsia-900/30 border border-fuchsia-500/40";
|
|
4896
|
+
textColorClass = "text-fuchsia-200 font-semibold";
|
|
4897
|
+
} else {
|
|
4898
|
+
textColorClass = "text-slate-200";
|
|
4899
|
+
}
|
|
4900
|
+
}
|
|
4901
|
+
const cursorClass = isEditable ? "cursor-grab active:cursor-grabbing" : "cursor-pointer";
|
|
4880
4902
|
const handleDragStart = (e) => {
|
|
4881
4903
|
if (!isEditable) {
|
|
4882
4904
|
e.preventDefault();
|
|
@@ -4906,23 +4928,9 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4906
4928
|
if (!isEditable) return;
|
|
4907
4929
|
const sourceId = e.dataTransfer.getData("nodeId");
|
|
4908
4930
|
if (sourceId === String(itemId)) return;
|
|
4909
|
-
if (onMoveNode)
|
|
4910
|
-
onMoveNode(sourceId, itemId);
|
|
4911
|
-
}
|
|
4931
|
+
if (onMoveNode) onMoveNode(sourceId, itemId);
|
|
4912
4932
|
};
|
|
4913
|
-
return /* @__PURE__ */ React10.createElement("div", { className: "relative" }, level > 0 && /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
|
|
4914
|
-
"span",
|
|
4915
|
-
{
|
|
4916
|
-
className: `absolute -left-4 top-0 w-px bg-cyan-600/60 ${isLast ? "h-[1.125rem]" : "h-full"}`,
|
|
4917
|
-
"aria-hidden": "true"
|
|
4918
|
-
}
|
|
4919
|
-
), /* @__PURE__ */ React10.createElement(
|
|
4920
|
-
"span",
|
|
4921
|
-
{
|
|
4922
|
-
className: `absolute -left-4 top-[1.125rem] h-px w-4 bg-cyan-600/60`,
|
|
4923
|
-
"aria-hidden": "true"
|
|
4924
|
-
}
|
|
4925
|
-
)), /* @__PURE__ */ React10.createElement(
|
|
4933
|
+
return /* @__PURE__ */ React10.createElement("div", { className: "relative" }, level > 0 && /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.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__ */ React10.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__ */ React10.createElement(
|
|
4926
4934
|
"div",
|
|
4927
4935
|
{
|
|
4928
4936
|
draggable: isEditable,
|
|
@@ -4930,63 +4938,35 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4930
4938
|
onDragOver: handleDragOver,
|
|
4931
4939
|
onDragLeave: handleDragLeave,
|
|
4932
4940
|
onDrop: handleDrop,
|
|
4933
|
-
onClick: () => {
|
|
4941
|
+
onClick: (e) => {
|
|
4942
|
+
e.stopPropagation();
|
|
4934
4943
|
if (isEditable) {
|
|
4935
4944
|
onSelectParent(itemId);
|
|
4945
|
+
} else if (onViewSelect) {
|
|
4946
|
+
onViewSelect(itemId);
|
|
4936
4947
|
}
|
|
4937
4948
|
},
|
|
4938
4949
|
className: `flex items-center justify-between gap-2 px-3 h-9 rounded-md transition-all duration-150 border
|
|
4939
4950
|
${isDragOver ? "border-dashed border-yellow-400 bg-yellow-400/10" : "border-transparent"}
|
|
4940
4951
|
${itemBgClass} ${cursorClass}`
|
|
4941
4952
|
},
|
|
4942
|
-
/* @__PURE__ */ React10.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ React10.createElement(
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
stroke: "currentColor",
|
|
4951
|
-
strokeWidth: "2",
|
|
4952
|
-
strokeLinecap: "round",
|
|
4953
|
-
strokeLinejoin: "round",
|
|
4954
|
-
className: "lucide lucide-blend-icon lucide-blend mr-1.5 inline-block"
|
|
4955
|
-
},
|
|
4956
|
-
/* @__PURE__ */ React10.createElement("circle", { cx: "9", cy: "9", r: "7" }),
|
|
4957
|
-
/* @__PURE__ */ React10.createElement("circle", { cx: "15", cy: "15", r: "7" })
|
|
4958
|
-
), nodeData.is_section && /* @__PURE__ */ React10.createElement(FiFolder, { className: "mr-2" }), itemName),
|
|
4959
|
-
level > 0 && isEditable && /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-1 animate-in fade-in duration-200" }, !nodeData.is_section && /* @__PURE__ */ React10.createElement(
|
|
4960
|
-
"button",
|
|
4961
|
-
{
|
|
4962
|
-
onClick: (e) => {
|
|
4963
|
-
e.stopPropagation();
|
|
4964
|
-
onEditRelationship(path, nodeData.relationship || {});
|
|
4965
|
-
},
|
|
4966
|
-
className: "w-6 h-6 grid place-content-center rounded-full hover:bg-cyan-500/20 text-cyan-400 transition-colors flex-shrink-0",
|
|
4967
|
-
title: "Editar detalhes da rela\xE7\xE3o",
|
|
4968
|
-
style: { cursor: "pointer" }
|
|
4969
|
-
},
|
|
4970
|
-
/* @__PURE__ */ React10.createElement(FiEdit23, { size: 12 })
|
|
4971
|
-
), /* @__PURE__ */ React10.createElement(
|
|
4972
|
-
"button",
|
|
4973
|
-
{
|
|
4974
|
-
onClick: (e) => {
|
|
4975
|
-
e.stopPropagation();
|
|
4976
|
-
onRemoveNode(path);
|
|
4977
|
-
},
|
|
4978
|
-
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",
|
|
4979
|
-
title: "Remover Node da ancestralidade",
|
|
4980
|
-
style: { cursor: "pointer" }
|
|
4981
|
-
},
|
|
4982
|
-
"\xD7"
|
|
4983
|
-
))
|
|
4953
|
+
/* @__PURE__ */ React10.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ React10.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__ */ React10.createElement("circle", { cx: "9", cy: "9", r: "7" }), /* @__PURE__ */ React10.createElement("circle", { cx: "15", cy: "15", r: "7" })), nodeData.is_section && /* @__PURE__ */ React10.createElement(FiFolder, { className: "mr-2" }), itemName),
|
|
4954
|
+
level > 0 && isEditable && /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-1 animate-in fade-in duration-200" }, !nodeData.is_section && /* @__PURE__ */ React10.createElement("button", { onClick: (e) => {
|
|
4955
|
+
e.stopPropagation();
|
|
4956
|
+
onEditRelationship(path, nodeData.relationship || {});
|
|
4957
|
+
}, 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__ */ React10.createElement(FiEdit23, { size: 12 })), /* @__PURE__ */ React10.createElement("button", { onClick: (e) => {
|
|
4958
|
+
e.stopPropagation();
|
|
4959
|
+
onRemoveNode(path);
|
|
4960
|
+
}, 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"))
|
|
4984
4961
|
), hasChildren && /* @__PURE__ */ React10.createElement("div", { className: "mt-2 space-y-2 pl-8" }, nodeData.children.map((child, index) => /* @__PURE__ */ React10.createElement(
|
|
4985
4962
|
NodeItem,
|
|
4986
4963
|
{
|
|
4987
4964
|
key: `${child.is_section ? child.id : child.node.id}-${index}`,
|
|
4988
4965
|
nodeData: child,
|
|
4989
4966
|
onSelectParent,
|
|
4967
|
+
onViewSelect,
|
|
4968
|
+
highlightedPathIds,
|
|
4969
|
+
targetRenderNodeId,
|
|
4990
4970
|
onRemoveNode,
|
|
4991
4971
|
onEditRelationship,
|
|
4992
4972
|
onMoveNode,
|
|
@@ -5001,11 +4981,8 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
5001
4981
|
function CreateAncestryPanel({
|
|
5002
4982
|
ancestryMode,
|
|
5003
4983
|
setAncestryMode,
|
|
5004
|
-
// <--- Nova prop necessária para as novas funções manipuladoras
|
|
5005
4984
|
onSelectParent,
|
|
5006
|
-
// Mantido para compatibilidade, mas as novas funções usam setAncestryMode
|
|
5007
4985
|
onRemoveNode,
|
|
5008
|
-
// Mantido para compatibilidade
|
|
5009
4986
|
onSave,
|
|
5010
4987
|
onClose,
|
|
5011
4988
|
onEditRelationship,
|
|
@@ -5016,14 +4993,12 @@ function CreateAncestryPanel({
|
|
|
5016
4993
|
onUpdateTree,
|
|
5017
4994
|
onAncestrySectionChange,
|
|
5018
4995
|
onToggleAddNodes,
|
|
5019
|
-
// Mantido para compatibilidade
|
|
5020
4996
|
onRenderFullAncestry,
|
|
5021
4997
|
onHighlightNode,
|
|
5022
4998
|
onClearAncestryVisuals,
|
|
5023
4999
|
onUploadFile,
|
|
5024
5000
|
onOpenImageViewer,
|
|
5025
5001
|
onRenderAbstractionTree
|
|
5026
|
-
// <--- Nova prop recebida
|
|
5027
5002
|
}) {
|
|
5028
5003
|
const {
|
|
5029
5004
|
tree: rootTree,
|
|
@@ -5040,6 +5015,20 @@ function CreateAncestryPanel({
|
|
|
5040
5015
|
const [customProps, setCustomProps] = useState10([]);
|
|
5041
5016
|
const propsEndRef = useRef8(null);
|
|
5042
5017
|
const [branchStack, setBranchStack] = useState10([]);
|
|
5018
|
+
const [targetRenderNodeId, setTargetRenderNodeId] = useState10(null);
|
|
5019
|
+
const highlightedPathIds = useMemo8(() => {
|
|
5020
|
+
var _a, _b;
|
|
5021
|
+
if (!targetRenderNodeId || !ancestryMode.abstraction_tree) return [];
|
|
5022
|
+
const found = findNodePath(ancestryMode.abstraction_tree, targetRenderNodeId);
|
|
5023
|
+
if (!found) return [];
|
|
5024
|
+
let current = ancestryMode.abstraction_tree;
|
|
5025
|
+
const ids = [current.is_section ? current.section_id : String((_a = current.node) == null ? void 0 : _a.id)];
|
|
5026
|
+
for (let i of found.path) {
|
|
5027
|
+
current = current.children[i];
|
|
5028
|
+
ids.push(current.is_section ? current.section_id : String((_b = current.node) == null ? void 0 : _b.id));
|
|
5029
|
+
}
|
|
5030
|
+
return ids;
|
|
5031
|
+
}, [targetRenderNodeId, ancestryMode.abstraction_tree]);
|
|
5043
5032
|
const [targetScrollSectionId, setTargetScrollSectionId] = useState10(null);
|
|
5044
5033
|
const [internalHighlightedNodeId, setInternalHighlightedNodeId] = useState10(null);
|
|
5045
5034
|
const [ancestryName, setAncestryName] = useState10(initialName);
|
|
@@ -5063,6 +5052,9 @@ function CreateAncestryPanel({
|
|
|
5063
5052
|
setAncestryMode((prev) => isAbstraction ? { ...prev, selectedAbstractionParentId: nodeId } : { ...prev, selectedParentId: nodeId });
|
|
5064
5053
|
};
|
|
5065
5054
|
const handleToggleAddMode = (isAbstraction = false) => {
|
|
5055
|
+
if (isAbstraction && !ancestryMode.isAddingAbstractionNodes) {
|
|
5056
|
+
setTargetRenderNodeId(null);
|
|
5057
|
+
}
|
|
5066
5058
|
setAncestryMode((prev) => isAbstraction ? { ...prev, isAddingAbstractionNodes: !prev.isAddingAbstractionNodes } : { ...prev, isAddingNodes: !prev.isAddingNodes });
|
|
5067
5059
|
};
|
|
5068
5060
|
const handleRemoveNode = useCallback((pathToRemove, isAbstraction = false) => {
|
|
@@ -5144,14 +5136,15 @@ function CreateAncestryPanel({
|
|
|
5144
5136
|
}
|
|
5145
5137
|
}
|
|
5146
5138
|
};
|
|
5147
|
-
const takeSnapshot = (tree, name, desc, sections, customProps2, isPrivateVal) => {
|
|
5139
|
+
const takeSnapshot = (tree, name, desc, sections, customProps2, isPrivateVal, abstractionTree = null) => {
|
|
5148
5140
|
return {
|
|
5149
5141
|
tree: JSON.stringify(tree),
|
|
5150
5142
|
name,
|
|
5151
5143
|
description: desc || "",
|
|
5152
5144
|
sections: JSON.stringify(sections || []),
|
|
5153
5145
|
customProps: JSON.stringify(customProps2 || []),
|
|
5154
|
-
isPrivate: isPrivateVal
|
|
5146
|
+
isPrivate: isPrivateVal,
|
|
5147
|
+
abstractionTree: JSON.stringify(abstractionTree)
|
|
5155
5148
|
};
|
|
5156
5149
|
};
|
|
5157
5150
|
const getCurrentContext = () => {
|
|
@@ -5285,7 +5278,8 @@ function CreateAncestryPanel({
|
|
|
5285
5278
|
ancestryMode.ancestryDescription,
|
|
5286
5279
|
ancestryMode.ancestryDescriptionSections,
|
|
5287
5280
|
extractedProps,
|
|
5288
|
-
ancestryMode.is_private
|
|
5281
|
+
ancestryMode.is_private,
|
|
5282
|
+
ancestryMode.abstraction_tree
|
|
5289
5283
|
));
|
|
5290
5284
|
} else if (ctx) {
|
|
5291
5285
|
setLastSavedSnapshot(takeSnapshot(
|
|
@@ -5294,7 +5288,8 @@ function CreateAncestryPanel({
|
|
|
5294
5288
|
ctx.description,
|
|
5295
5289
|
ctx.sections,
|
|
5296
5290
|
extractedProps,
|
|
5297
|
-
isPrivate
|
|
5291
|
+
isPrivate,
|
|
5292
|
+
ancestryMode.abstraction_tree
|
|
5298
5293
|
));
|
|
5299
5294
|
}
|
|
5300
5295
|
}, [branchStack, ancestryMode]);
|
|
@@ -5337,7 +5332,7 @@ function CreateAncestryPanel({
|
|
|
5337
5332
|
rootTreeClone,
|
|
5338
5333
|
rootExtras
|
|
5339
5334
|
);
|
|
5340
|
-
setLastSavedSnapshot(takeSnapshot(rootTreeClone, ancestryName, description, processedSections, [], isPrivate));
|
|
5335
|
+
setLastSavedSnapshot(takeSnapshot(rootTreeClone, ancestryName, description, processedSections, [], isPrivate, ancestryMode.abstraction_tree));
|
|
5341
5336
|
if (onRenderFullAncestry) {
|
|
5342
5337
|
const fullTreePayload = {
|
|
5343
5338
|
ancestry_id: ancestryMode.currentAncestryId || "temp_root",
|
|
@@ -5398,7 +5393,8 @@ function CreateAncestryPanel({
|
|
|
5398
5393
|
ancestryMode.ancestryDescription,
|
|
5399
5394
|
ancestryMode.ancestryDescriptionSections,
|
|
5400
5395
|
currentRootProps,
|
|
5401
|
-
isPrivate
|
|
5396
|
+
isPrivate,
|
|
5397
|
+
ancestryMode.abstraction_tree
|
|
5402
5398
|
));
|
|
5403
5399
|
if (onClearAncestryVisuals) {
|
|
5404
5400
|
onClearAncestryVisuals(currentStep.branchId);
|
|
@@ -5587,6 +5583,11 @@ function CreateAncestryPanel({
|
|
|
5587
5583
|
const sectionsChanged = JSON.stringify(existingSections) !== lastSavedSnapshot.sections;
|
|
5588
5584
|
const propsChanged = JSON.stringify(customProps) !== lastSavedSnapshot.customProps;
|
|
5589
5585
|
const privateChanged = isPrivate !== lastSavedSnapshot.isPrivate;
|
|
5586
|
+
let abstractionTreeChanged = false;
|
|
5587
|
+
if (branchStack.length === 0) {
|
|
5588
|
+
const currentAbsTreeStr = JSON.stringify(ancestryMode.abstraction_tree);
|
|
5589
|
+
abstractionTreeChanged = currentAbsTreeStr !== lastSavedSnapshot.abstractionTree;
|
|
5590
|
+
}
|
|
5590
5591
|
return treeChanged || nameChanged || descChanged || sectionsChanged || propsChanged || privateChanged;
|
|
5591
5592
|
}, [
|
|
5592
5593
|
ancestryName,
|
|
@@ -5596,6 +5597,7 @@ function CreateAncestryPanel({
|
|
|
5596
5597
|
branchStack,
|
|
5597
5598
|
lastSavedSnapshot,
|
|
5598
5599
|
ancestryMode.tree,
|
|
5600
|
+
ancestryMode.abstraction_tree,
|
|
5599
5601
|
customProps,
|
|
5600
5602
|
isPrivate
|
|
5601
5603
|
]);
|
|
@@ -5838,7 +5840,8 @@ function CreateAncestryPanel({
|
|
|
5838
5840
|
currentInputDesc,
|
|
5839
5841
|
processedSections,
|
|
5840
5842
|
customProps,
|
|
5841
|
-
isPrivate
|
|
5843
|
+
isPrivate,
|
|
5844
|
+
ancestryMode.abstraction_tree
|
|
5842
5845
|
));
|
|
5843
5846
|
if (onRenderFullAncestry) {
|
|
5844
5847
|
const rotation = branchStack.reduce((acc, step) => {
|
|
@@ -5897,7 +5900,8 @@ function CreateAncestryPanel({
|
|
|
5897
5900
|
currentInputDesc,
|
|
5898
5901
|
processedSections,
|
|
5899
5902
|
customProps,
|
|
5900
|
-
isPrivate
|
|
5903
|
+
isPrivate,
|
|
5904
|
+
ancestryMode.abstraction_tree
|
|
5901
5905
|
));
|
|
5902
5906
|
if (!keepOpen) onClose();
|
|
5903
5907
|
} finally {
|
|
@@ -5950,7 +5954,9 @@ function CreateAncestryPanel({
|
|
|
5950
5954
|
const node = findNode(activeTree, selectedParentId);
|
|
5951
5955
|
return node ? node.name : "Nenhum";
|
|
5952
5956
|
};
|
|
5953
|
-
const
|
|
5957
|
+
const hasMainChildren = activeTree && activeTree.children && activeTree.children.length > 0;
|
|
5958
|
+
const hasAbstractionChildren = branchStack.length === 0 && ancestryMode.abstraction_tree && ancestryMode.abstraction_tree.children && ancestryMode.abstraction_tree.children.length > 0;
|
|
5959
|
+
const canSave = hasMainChildren || hasAbstractionChildren;
|
|
5954
5960
|
const handleSectionChangeWrapper = (sectionId) => {
|
|
5955
5961
|
const ctx = getCurrentContext();
|
|
5956
5962
|
const currentDesc = ctx ? ctx.description : description;
|
|
@@ -6184,44 +6190,77 @@ function CreateAncestryPanel({
|
|
|
6184
6190
|
path: [],
|
|
6185
6191
|
isEditable: isAddingNodes
|
|
6186
6192
|
}
|
|
6187
|
-
), (!activeTree || activeTree.children.length === 0) && !isAddingNodes && /* @__PURE__ */ React10.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__ */ React10.createElement(
|
|
6188
|
-
"
|
|
6189
|
-
{
|
|
6190
|
-
type: "button",
|
|
6191
|
-
onClick: () => {
|
|
6192
|
-
const tempPayload = {
|
|
6193
|
-
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6194
|
-
abstraction_tree: ancestryMode.abstraction_tree
|
|
6195
|
-
};
|
|
6196
|
-
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload);
|
|
6197
|
-
},
|
|
6198
|
-
className: "p-1.5 rounded-md bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600 transition-colors",
|
|
6199
|
-
title: "Renderizar Verticalmente no Cen\xE1rio"
|
|
6200
|
-
},
|
|
6201
|
-
/* @__PURE__ */ React10.createElement(FiLayers5, { size: 14 })
|
|
6202
|
-
), /* @__PURE__ */ React10.createElement(
|
|
6203
|
-
"button",
|
|
6193
|
+
), (!activeTree || activeTree.children.length === 0) && !isAddingNodes && /* @__PURE__ */ React10.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__ */ React10.createElement(
|
|
6194
|
+
"div",
|
|
6204
6195
|
{
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
title: "Editar estrutura da abstra\xE7\xE3o"
|
|
6196
|
+
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"}`,
|
|
6197
|
+
onClick: () => setTargetRenderNodeId(null)
|
|
6208
6198
|
},
|
|
6209
|
-
ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ React10.createElement(
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6199
|
+
/* @__PURE__ */ React10.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__ */ React10.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React10.createElement("span", { className: `text-xs font-semibold uppercase tracking-wider ${ancestryMode.isAddingAbstractionNodes ? "text-purple-300" : "text-slate-400"}` }, "Estrutura de Abstra\xE7\xE3o"), ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ React10.createElement("span", { className: "text-[10px] bg-purple-500/20 text-purple-300 px-1.5 py-0.5 rounded animate-pulse" }, "Editando")), /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-2" }, targetRenderNodeId && !ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ React10.createElement(
|
|
6200
|
+
"button",
|
|
6201
|
+
{
|
|
6202
|
+
type: "button",
|
|
6203
|
+
onClick: (e) => {
|
|
6204
|
+
e.stopPropagation();
|
|
6205
|
+
const tempPayload = {
|
|
6206
|
+
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6207
|
+
abstraction_tree: ancestryMode.abstraction_tree
|
|
6208
|
+
};
|
|
6209
|
+
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload, targetRenderNodeId);
|
|
6210
|
+
},
|
|
6211
|
+
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",
|
|
6212
|
+
title: "Renderizar cen\xE1rio at\xE9 o caminho selecionado"
|
|
6213
|
+
},
|
|
6214
|
+
/* @__PURE__ */ React10.createElement(FiLayers5, { size: 13 }),
|
|
6215
|
+
/* @__PURE__ */ React10.createElement("span", { className: "text-[10px] font-bold uppercase tracking-wider" }, "Caminho")
|
|
6216
|
+
), /* @__PURE__ */ React10.createElement(
|
|
6217
|
+
"button",
|
|
6218
|
+
{
|
|
6219
|
+
type: "button",
|
|
6220
|
+
onClick: (e) => {
|
|
6221
|
+
e.stopPropagation();
|
|
6222
|
+
const tempPayload = {
|
|
6223
|
+
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6224
|
+
abstraction_tree: ancestryMode.abstraction_tree
|
|
6225
|
+
};
|
|
6226
|
+
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload);
|
|
6227
|
+
},
|
|
6228
|
+
className: "p-1.5 rounded-md bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600 transition-colors",
|
|
6229
|
+
title: "Renderizar Verticalmente Completo"
|
|
6230
|
+
},
|
|
6231
|
+
/* @__PURE__ */ React10.createElement(FiLayers5, { size: 14 })
|
|
6232
|
+
), /* @__PURE__ */ React10.createElement(
|
|
6233
|
+
"button",
|
|
6234
|
+
{
|
|
6235
|
+
type: "button",
|
|
6236
|
+
onClick: (e) => {
|
|
6237
|
+
e.stopPropagation();
|
|
6238
|
+
handleToggleAddMode(true);
|
|
6239
|
+
},
|
|
6240
|
+
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"}`,
|
|
6241
|
+
title: "Editar estrutura da abstra\xE7\xE3o"
|
|
6242
|
+
},
|
|
6243
|
+
ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ React10.createElement(FiCheck4, { size: 14 }) : /* @__PURE__ */ React10.createElement(FiEdit23, { size: 14 })
|
|
6244
|
+
))),
|
|
6245
|
+
/* @__PURE__ */ React10.createElement("div", { className: "p-4 space-y-2" }, ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ React10.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__ */ React10.createElement(FiMousePointer, { className: "mt-0.5 flex-shrink-0" }), /* @__PURE__ */ React10.createElement("span", null, "Clique nos nodes do cen\xE1rio para adicion\xE1-los. Arraste e solte para organizar a hierarquia.")), /* @__PURE__ */ React10.createElement(
|
|
6246
|
+
NodeItem,
|
|
6247
|
+
{
|
|
6248
|
+
nodeData: ancestryMode.abstraction_tree,
|
|
6249
|
+
onSelectParent: (id) => handleSelectAncestryParent(id, true),
|
|
6250
|
+
onViewSelect: setTargetRenderNodeId,
|
|
6251
|
+
highlightedPathIds,
|
|
6252
|
+
targetRenderNodeId,
|
|
6253
|
+
onRemoveNode: (path) => handleRemoveNode(path, true),
|
|
6254
|
+
onEditRelationship,
|
|
6255
|
+
onMoveNode: (s, t) => handleMoveNode(s, t, true),
|
|
6256
|
+
selectedParentId: ancestryMode.selectedAbstractionParentId,
|
|
6257
|
+
level: 0,
|
|
6258
|
+
isLast: true,
|
|
6259
|
+
path: [],
|
|
6260
|
+
isEditable: ancestryMode.isAddingAbstractionNodes
|
|
6261
|
+
}
|
|
6262
|
+
))
|
|
6263
|
+
), branchStack.length === 0 && /* @__PURE__ */ React10.createElement("div", { className: "mt-3 flex items-center justify-end px-1" }, /* @__PURE__ */ React10.createElement("label", { className: "flex items-center gap-2 cursor-pointer group select-none" }, /* @__PURE__ */ React10.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__ */ React10.createElement(FiCheck4, { size: 12, className: "text-white" })), /* @__PURE__ */ React10.createElement(
|
|
6225
6264
|
"input",
|
|
6226
6265
|
{
|
|
6227
6266
|
type: "checkbox",
|
|
@@ -6229,7 +6268,7 @@ function CreateAncestryPanel({
|
|
|
6229
6268
|
onChange: (e) => setIsPrivate(e.target.checked),
|
|
6230
6269
|
className: "hidden"
|
|
6231
6270
|
}
|
|
6232
|
-
), /* @__PURE__ */ React10.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__ */ React10.createElement(FiLock, { size: 10 }), " N\xE3o Export\xE1vel"))))), /* @__PURE__ */ React10.createElement("div", { className: "px-6 pt-2 pb-5 flex-shrink-0" },
|
|
6271
|
+
), /* @__PURE__ */ React10.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__ */ React10.createElement(FiLock, { size: 10 }), " N\xE3o Export\xE1vel"))))), /* @__PURE__ */ React10.createElement("div", { className: "px-6 pt-2 pb-5 flex-shrink-0" }, canSave && /* @__PURE__ */ React10.createElement(
|
|
6233
6272
|
"button",
|
|
6234
6273
|
{
|
|
6235
6274
|
onClick: () => handleLocalSave(false),
|
|
@@ -8752,16 +8791,16 @@ var getAllNodeIdsFromTree = (treeNode) => {
|
|
|
8752
8791
|
traverse(treeNode);
|
|
8753
8792
|
return Array.from(ids);
|
|
8754
8793
|
};
|
|
8755
|
-
var findNodePath2 = (tree,
|
|
8794
|
+
var findNodePath2 = (tree, targetNodeId2, currentPath = []) => {
|
|
8756
8795
|
var _a;
|
|
8757
8796
|
if (!tree) return null;
|
|
8758
8797
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
8759
|
-
if (String(currentNodeId) === String(
|
|
8798
|
+
if (String(currentNodeId) === String(targetNodeId2)) {
|
|
8760
8799
|
return { node: tree, path: currentPath };
|
|
8761
8800
|
}
|
|
8762
8801
|
if (tree.children) {
|
|
8763
8802
|
for (let i = 0; i < tree.children.length; i++) {
|
|
8764
|
-
const res = findNodePath2(tree.children[i],
|
|
8803
|
+
const res = findNodePath2(tree.children[i], targetNodeId2, [...currentPath, i]);
|
|
8765
8804
|
if (res) return res;
|
|
8766
8805
|
}
|
|
8767
8806
|
}
|
|
@@ -10835,8 +10874,29 @@ function XViewScene({
|
|
|
10835
10874
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
10836
10875
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
10837
10876
|
const allParentNodes = Object.values(parentDataRef.current).flatMap((f) => f.nodes);
|
|
10838
|
-
|
|
10877
|
+
let fullTree = buildFullAncestryTree(ancestryObject.abstraction_tree, allParentNodes, ancestryDataRef.current);
|
|
10839
10878
|
if (!fullTree || !fullTree.node) return;
|
|
10879
|
+
if (targetNodeId) {
|
|
10880
|
+
const pruneTreeToPath = (treeNode, targetId) => {
|
|
10881
|
+
var _a2;
|
|
10882
|
+
if (!treeNode) return null;
|
|
10883
|
+
const currentId = treeNode.is_section ? treeNode.section_id : String((_a2 = treeNode.node) == null ? void 0 : _a2.id);
|
|
10884
|
+
if (String(currentId) === String(targetId)) {
|
|
10885
|
+
return { ...treeNode, children: [] };
|
|
10886
|
+
}
|
|
10887
|
+
if (treeNode.children && treeNode.children.length > 0) {
|
|
10888
|
+
for (let child of treeNode.children) {
|
|
10889
|
+
const prunedChild = pruneTreeToPath(child, targetId);
|
|
10890
|
+
if (prunedChild) {
|
|
10891
|
+
return { ...treeNode, children: [prunedChild] };
|
|
10892
|
+
}
|
|
10893
|
+
}
|
|
10894
|
+
}
|
|
10895
|
+
return null;
|
|
10896
|
+
};
|
|
10897
|
+
const pruned = pruneTreeToPath(fullTree, targetNodeId);
|
|
10898
|
+
if (pruned) fullTree = pruned;
|
|
10899
|
+
}
|
|
10840
10900
|
const absId = ancestryObject.ancestry_id + "_abs";
|
|
10841
10901
|
handleClearAncestryVisuals(absId);
|
|
10842
10902
|
const colorHex = 9133302;
|
|
@@ -11848,7 +11908,7 @@ function XViewScene({
|
|
|
11848
11908
|
onClearAncestryVisuals: handleClearAncestryVisuals,
|
|
11849
11909
|
onUploadFile: upload_file_action,
|
|
11850
11910
|
onOpenImageViewer: handleOpenImageViewer,
|
|
11851
|
-
onRenderAbstractionTree: (data) => handleRenderAbstractionTree(data)
|
|
11911
|
+
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
11852
11912
|
}
|
|
11853
11913
|
),
|
|
11854
11914
|
editingAncestryRel.visible && /* @__PURE__ */ React23.createElement(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lv-x-software-house/x_view",
|
|
3
|
-
"version": "1.1.9-dev.
|
|
3
|
+
"version": "1.1.9-dev.5",
|
|
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",
|