@lv-x-software-house/x_view 1.1.9-dev.3 → 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 +163 -120
- package/dist/index.mjs +163 -120
- 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);
|
|
@@ -4874,31 +4874,50 @@ function AncestryPickerModal({
|
|
|
4874
4874
|
}
|
|
4875
4875
|
|
|
4876
4876
|
// src/components/CreateAncestryPanel.jsx
|
|
4877
|
-
var findNodePath = (tree,
|
|
4877
|
+
var findNodePath = (tree, targetNodeId2, currentPath = []) => {
|
|
4878
4878
|
var _a;
|
|
4879
4879
|
if (!tree) return null;
|
|
4880
4880
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
4881
|
-
if (String(currentNodeId) === String(
|
|
4881
|
+
if (String(currentNodeId) === String(targetNodeId2)) {
|
|
4882
4882
|
return { node: tree, path: currentPath };
|
|
4883
4883
|
}
|
|
4884
4884
|
if (tree.children) {
|
|
4885
4885
|
for (let i = 0; i < tree.children.length; i++) {
|
|
4886
|
-
const res = findNodePath(tree.children[i],
|
|
4886
|
+
const res = findNodePath(tree.children[i], targetNodeId2, [...currentPath, i]);
|
|
4887
4887
|
if (res) return res;
|
|
4888
4888
|
}
|
|
4889
4889
|
}
|
|
4890
4890
|
return null;
|
|
4891
4891
|
};
|
|
4892
|
-
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 }) => {
|
|
4893
4893
|
var _a, _b;
|
|
4894
4894
|
const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
|
|
4895
4895
|
const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
|
|
4896
4896
|
const [isDragOver, setIsDragOver] = (0, import_react10.useState)(false);
|
|
4897
|
-
const
|
|
4897
|
+
const isSelectedParent = String(selectedParentId) === String(itemId);
|
|
4898
|
+
const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
|
|
4899
|
+
const isHighlightedPath = highlightedPathIds.includes(String(itemId));
|
|
4898
4900
|
const hasChildren = nodeData.children && nodeData.children.length > 0;
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
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";
|
|
4902
4921
|
const handleDragStart = (e) => {
|
|
4903
4922
|
if (!isEditable) {
|
|
4904
4923
|
e.preventDefault();
|
|
@@ -4928,23 +4947,9 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4928
4947
|
if (!isEditable) return;
|
|
4929
4948
|
const sourceId = e.dataTransfer.getData("nodeId");
|
|
4930
4949
|
if (sourceId === String(itemId)) return;
|
|
4931
|
-
if (onMoveNode)
|
|
4932
|
-
onMoveNode(sourceId, itemId);
|
|
4933
|
-
}
|
|
4950
|
+
if (onMoveNode) onMoveNode(sourceId, itemId);
|
|
4934
4951
|
};
|
|
4935
|
-
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(
|
|
4936
|
-
"span",
|
|
4937
|
-
{
|
|
4938
|
-
className: `absolute -left-4 top-0 w-px bg-cyan-600/60 ${isLast ? "h-[1.125rem]" : "h-full"}`,
|
|
4939
|
-
"aria-hidden": "true"
|
|
4940
|
-
}
|
|
4941
|
-
), /* @__PURE__ */ import_react10.default.createElement(
|
|
4942
|
-
"span",
|
|
4943
|
-
{
|
|
4944
|
-
className: `absolute -left-4 top-[1.125rem] h-px w-4 bg-cyan-600/60`,
|
|
4945
|
-
"aria-hidden": "true"
|
|
4946
|
-
}
|
|
4947
|
-
)), /* @__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(
|
|
4948
4953
|
"div",
|
|
4949
4954
|
{
|
|
4950
4955
|
draggable: isEditable,
|
|
@@ -4952,63 +4957,35 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4952
4957
|
onDragOver: handleDragOver,
|
|
4953
4958
|
onDragLeave: handleDragLeave,
|
|
4954
4959
|
onDrop: handleDrop,
|
|
4955
|
-
onClick: () => {
|
|
4960
|
+
onClick: (e) => {
|
|
4961
|
+
e.stopPropagation();
|
|
4956
4962
|
if (isEditable) {
|
|
4957
4963
|
onSelectParent(itemId);
|
|
4964
|
+
} else if (onViewSelect) {
|
|
4965
|
+
onViewSelect(itemId);
|
|
4958
4966
|
}
|
|
4959
4967
|
},
|
|
4960
4968
|
className: `flex items-center justify-between gap-2 px-3 h-9 rounded-md transition-all duration-150 border
|
|
4961
4969
|
${isDragOver ? "border-dashed border-yellow-400 bg-yellow-400/10" : "border-transparent"}
|
|
4962
4970
|
${itemBgClass} ${cursorClass}`
|
|
4963
4971
|
},
|
|
4964
|
-
/* @__PURE__ */ import_react10.default.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ import_react10.default.createElement(
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
stroke: "currentColor",
|
|
4973
|
-
strokeWidth: "2",
|
|
4974
|
-
strokeLinecap: "round",
|
|
4975
|
-
strokeLinejoin: "round",
|
|
4976
|
-
className: "lucide lucide-blend-icon lucide-blend mr-1.5 inline-block"
|
|
4977
|
-
},
|
|
4978
|
-
/* @__PURE__ */ import_react10.default.createElement("circle", { cx: "9", cy: "9", r: "7" }),
|
|
4979
|
-
/* @__PURE__ */ import_react10.default.createElement("circle", { cx: "15", cy: "15", r: "7" })
|
|
4980
|
-
), nodeData.is_section && /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiFolder, { className: "mr-2" }), itemName),
|
|
4981
|
-
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(
|
|
4982
|
-
"button",
|
|
4983
|
-
{
|
|
4984
|
-
onClick: (e) => {
|
|
4985
|
-
e.stopPropagation();
|
|
4986
|
-
onEditRelationship(path, nodeData.relationship || {});
|
|
4987
|
-
},
|
|
4988
|
-
className: "w-6 h-6 grid place-content-center rounded-full hover:bg-cyan-500/20 text-cyan-400 transition-colors flex-shrink-0",
|
|
4989
|
-
title: "Editar detalhes da rela\xE7\xE3o",
|
|
4990
|
-
style: { cursor: "pointer" }
|
|
4991
|
-
},
|
|
4992
|
-
/* @__PURE__ */ import_react10.default.createElement(import_fi9.FiEdit2, { size: 12 })
|
|
4993
|
-
), /* @__PURE__ */ import_react10.default.createElement(
|
|
4994
|
-
"button",
|
|
4995
|
-
{
|
|
4996
|
-
onClick: (e) => {
|
|
4997
|
-
e.stopPropagation();
|
|
4998
|
-
onRemoveNode(path);
|
|
4999
|
-
},
|
|
5000
|
-
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",
|
|
5001
|
-
title: "Remover Node da ancestralidade",
|
|
5002
|
-
style: { cursor: "pointer" }
|
|
5003
|
-
},
|
|
5004
|
-
"\xD7"
|
|
5005
|
-
))
|
|
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"))
|
|
5006
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(
|
|
5007
4981
|
NodeItem,
|
|
5008
4982
|
{
|
|
5009
4983
|
key: `${child.is_section ? child.id : child.node.id}-${index}`,
|
|
5010
4984
|
nodeData: child,
|
|
5011
4985
|
onSelectParent,
|
|
4986
|
+
onViewSelect,
|
|
4987
|
+
highlightedPathIds,
|
|
4988
|
+
targetRenderNodeId,
|
|
5012
4989
|
onRemoveNode,
|
|
5013
4990
|
onEditRelationship,
|
|
5014
4991
|
onMoveNode,
|
|
@@ -5023,11 +5000,8 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
5023
5000
|
function CreateAncestryPanel({
|
|
5024
5001
|
ancestryMode,
|
|
5025
5002
|
setAncestryMode,
|
|
5026
|
-
// <--- Nova prop necessária para as novas funções manipuladoras
|
|
5027
5003
|
onSelectParent,
|
|
5028
|
-
// Mantido para compatibilidade, mas as novas funções usam setAncestryMode
|
|
5029
5004
|
onRemoveNode,
|
|
5030
|
-
// Mantido para compatibilidade
|
|
5031
5005
|
onSave,
|
|
5032
5006
|
onClose,
|
|
5033
5007
|
onEditRelationship,
|
|
@@ -5038,14 +5012,12 @@ function CreateAncestryPanel({
|
|
|
5038
5012
|
onUpdateTree,
|
|
5039
5013
|
onAncestrySectionChange,
|
|
5040
5014
|
onToggleAddNodes,
|
|
5041
|
-
// Mantido para compatibilidade
|
|
5042
5015
|
onRenderFullAncestry,
|
|
5043
5016
|
onHighlightNode,
|
|
5044
5017
|
onClearAncestryVisuals,
|
|
5045
5018
|
onUploadFile,
|
|
5046
5019
|
onOpenImageViewer,
|
|
5047
5020
|
onRenderAbstractionTree
|
|
5048
|
-
// <--- Nova prop recebida
|
|
5049
5021
|
}) {
|
|
5050
5022
|
const {
|
|
5051
5023
|
tree: rootTree,
|
|
@@ -5062,6 +5034,20 @@ function CreateAncestryPanel({
|
|
|
5062
5034
|
const [customProps, setCustomProps] = (0, import_react10.useState)([]);
|
|
5063
5035
|
const propsEndRef = (0, import_react10.useRef)(null);
|
|
5064
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]);
|
|
5065
5051
|
const [targetScrollSectionId, setTargetScrollSectionId] = (0, import_react10.useState)(null);
|
|
5066
5052
|
const [internalHighlightedNodeId, setInternalHighlightedNodeId] = (0, import_react10.useState)(null);
|
|
5067
5053
|
const [ancestryName, setAncestryName] = (0, import_react10.useState)(initialName);
|
|
@@ -5085,6 +5071,9 @@ function CreateAncestryPanel({
|
|
|
5085
5071
|
setAncestryMode((prev) => isAbstraction ? { ...prev, selectedAbstractionParentId: nodeId } : { ...prev, selectedParentId: nodeId });
|
|
5086
5072
|
};
|
|
5087
5073
|
const handleToggleAddMode = (isAbstraction = false) => {
|
|
5074
|
+
if (isAbstraction && !ancestryMode.isAddingAbstractionNodes) {
|
|
5075
|
+
setTargetRenderNodeId(null);
|
|
5076
|
+
}
|
|
5088
5077
|
setAncestryMode((prev) => isAbstraction ? { ...prev, isAddingAbstractionNodes: !prev.isAddingAbstractionNodes } : { ...prev, isAddingNodes: !prev.isAddingNodes });
|
|
5089
5078
|
};
|
|
5090
5079
|
const handleRemoveNode = (0, import_react10.useCallback)((pathToRemove, isAbstraction = false) => {
|
|
@@ -6220,44 +6209,77 @@ function CreateAncestryPanel({
|
|
|
6220
6209
|
path: [],
|
|
6221
6210
|
isEditable: isAddingNodes
|
|
6222
6211
|
}
|
|
6223
|
-
), (!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(
|
|
6224
|
-
"
|
|
6225
|
-
{
|
|
6226
|
-
type: "button",
|
|
6227
|
-
onClick: () => {
|
|
6228
|
-
const tempPayload = {
|
|
6229
|
-
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6230
|
-
abstraction_tree: ancestryMode.abstraction_tree
|
|
6231
|
-
};
|
|
6232
|
-
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload);
|
|
6233
|
-
},
|
|
6234
|
-
className: "p-1.5 rounded-md bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600 transition-colors",
|
|
6235
|
-
title: "Renderizar Verticalmente no Cen\xE1rio"
|
|
6236
|
-
},
|
|
6237
|
-
/* @__PURE__ */ import_react10.default.createElement(import_fi9.FiLayers, { size: 14 })
|
|
6238
|
-
), /* @__PURE__ */ import_react10.default.createElement(
|
|
6239
|
-
"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",
|
|
6240
6214
|
{
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
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)
|
|
6244
6217
|
},
|
|
6245
|
-
ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ import_react10.default.createElement(
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
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(
|
|
6261
6283
|
"input",
|
|
6262
6284
|
{
|
|
6263
6285
|
type: "checkbox",
|
|
@@ -8775,16 +8797,16 @@ var getAllNodeIdsFromTree = (treeNode) => {
|
|
|
8775
8797
|
traverse(treeNode);
|
|
8776
8798
|
return Array.from(ids);
|
|
8777
8799
|
};
|
|
8778
|
-
var findNodePath2 = (tree,
|
|
8800
|
+
var findNodePath2 = (tree, targetNodeId2, currentPath = []) => {
|
|
8779
8801
|
var _a;
|
|
8780
8802
|
if (!tree) return null;
|
|
8781
8803
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
8782
|
-
if (String(currentNodeId) === String(
|
|
8804
|
+
if (String(currentNodeId) === String(targetNodeId2)) {
|
|
8783
8805
|
return { node: tree, path: currentPath };
|
|
8784
8806
|
}
|
|
8785
8807
|
if (tree.children) {
|
|
8786
8808
|
for (let i = 0; i < tree.children.length; i++) {
|
|
8787
|
-
const res = findNodePath2(tree.children[i],
|
|
8809
|
+
const res = findNodePath2(tree.children[i], targetNodeId2, [...currentPath, i]);
|
|
8788
8810
|
if (res) return res;
|
|
8789
8811
|
}
|
|
8790
8812
|
}
|
|
@@ -10858,8 +10880,29 @@ function XViewScene({
|
|
|
10858
10880
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
10859
10881
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
10860
10882
|
const allParentNodes = Object.values(parentDataRef.current).flatMap((f) => f.nodes);
|
|
10861
|
-
|
|
10883
|
+
let fullTree = buildFullAncestryTree(ancestryObject.abstraction_tree, allParentNodes, ancestryDataRef.current);
|
|
10862
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
|
+
}
|
|
10863
10906
|
const absId = ancestryObject.ancestry_id + "_abs";
|
|
10864
10907
|
handleClearAncestryVisuals(absId);
|
|
10865
10908
|
const colorHex = 9133302;
|
|
@@ -11871,7 +11914,7 @@ function XViewScene({
|
|
|
11871
11914
|
onClearAncestryVisuals: handleClearAncestryVisuals,
|
|
11872
11915
|
onUploadFile: upload_file_action,
|
|
11873
11916
|
onOpenImageViewer: handleOpenImageViewer,
|
|
11874
|
-
onRenderAbstractionTree: (data) => handleRenderAbstractionTree(data)
|
|
11917
|
+
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
11875
11918
|
}
|
|
11876
11919
|
),
|
|
11877
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);
|
|
@@ -4855,31 +4855,50 @@ function AncestryPickerModal({
|
|
|
4855
4855
|
}
|
|
4856
4856
|
|
|
4857
4857
|
// src/components/CreateAncestryPanel.jsx
|
|
4858
|
-
var findNodePath = (tree,
|
|
4858
|
+
var findNodePath = (tree, targetNodeId2, currentPath = []) => {
|
|
4859
4859
|
var _a;
|
|
4860
4860
|
if (!tree) return null;
|
|
4861
4861
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
4862
|
-
if (String(currentNodeId) === String(
|
|
4862
|
+
if (String(currentNodeId) === String(targetNodeId2)) {
|
|
4863
4863
|
return { node: tree, path: currentPath };
|
|
4864
4864
|
}
|
|
4865
4865
|
if (tree.children) {
|
|
4866
4866
|
for (let i = 0; i < tree.children.length; i++) {
|
|
4867
|
-
const res = findNodePath(tree.children[i],
|
|
4867
|
+
const res = findNodePath(tree.children[i], targetNodeId2, [...currentPath, i]);
|
|
4868
4868
|
if (res) return res;
|
|
4869
4869
|
}
|
|
4870
4870
|
}
|
|
4871
4871
|
return null;
|
|
4872
4872
|
};
|
|
4873
|
-
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 }) => {
|
|
4874
4874
|
var _a, _b;
|
|
4875
4875
|
const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
|
|
4876
4876
|
const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
|
|
4877
4877
|
const [isDragOver, setIsDragOver] = useState10(false);
|
|
4878
|
-
const
|
|
4878
|
+
const isSelectedParent = String(selectedParentId) === String(itemId);
|
|
4879
|
+
const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
|
|
4880
|
+
const isHighlightedPath = highlightedPathIds.includes(String(itemId));
|
|
4879
4881
|
const hasChildren = nodeData.children && nodeData.children.length > 0;
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
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";
|
|
4883
4902
|
const handleDragStart = (e) => {
|
|
4884
4903
|
if (!isEditable) {
|
|
4885
4904
|
e.preventDefault();
|
|
@@ -4909,23 +4928,9 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4909
4928
|
if (!isEditable) return;
|
|
4910
4929
|
const sourceId = e.dataTransfer.getData("nodeId");
|
|
4911
4930
|
if (sourceId === String(itemId)) return;
|
|
4912
|
-
if (onMoveNode)
|
|
4913
|
-
onMoveNode(sourceId, itemId);
|
|
4914
|
-
}
|
|
4931
|
+
if (onMoveNode) onMoveNode(sourceId, itemId);
|
|
4915
4932
|
};
|
|
4916
|
-
return /* @__PURE__ */ React10.createElement("div", { className: "relative" }, level > 0 && /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
|
|
4917
|
-
"span",
|
|
4918
|
-
{
|
|
4919
|
-
className: `absolute -left-4 top-0 w-px bg-cyan-600/60 ${isLast ? "h-[1.125rem]" : "h-full"}`,
|
|
4920
|
-
"aria-hidden": "true"
|
|
4921
|
-
}
|
|
4922
|
-
), /* @__PURE__ */ React10.createElement(
|
|
4923
|
-
"span",
|
|
4924
|
-
{
|
|
4925
|
-
className: `absolute -left-4 top-[1.125rem] h-px w-4 bg-cyan-600/60`,
|
|
4926
|
-
"aria-hidden": "true"
|
|
4927
|
-
}
|
|
4928
|
-
)), /* @__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(
|
|
4929
4934
|
"div",
|
|
4930
4935
|
{
|
|
4931
4936
|
draggable: isEditable,
|
|
@@ -4933,63 +4938,35 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
4933
4938
|
onDragOver: handleDragOver,
|
|
4934
4939
|
onDragLeave: handleDragLeave,
|
|
4935
4940
|
onDrop: handleDrop,
|
|
4936
|
-
onClick: () => {
|
|
4941
|
+
onClick: (e) => {
|
|
4942
|
+
e.stopPropagation();
|
|
4937
4943
|
if (isEditable) {
|
|
4938
4944
|
onSelectParent(itemId);
|
|
4945
|
+
} else if (onViewSelect) {
|
|
4946
|
+
onViewSelect(itemId);
|
|
4939
4947
|
}
|
|
4940
4948
|
},
|
|
4941
4949
|
className: `flex items-center justify-between gap-2 px-3 h-9 rounded-md transition-all duration-150 border
|
|
4942
4950
|
${isDragOver ? "border-dashed border-yellow-400 bg-yellow-400/10" : "border-transparent"}
|
|
4943
4951
|
${itemBgClass} ${cursorClass}`
|
|
4944
4952
|
},
|
|
4945
|
-
/* @__PURE__ */ React10.createElement("span", { className: `truncate flex items-center ${textColorClass}` }, level === 0 && !nodeData.is_section && /* @__PURE__ */ React10.createElement(
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
stroke: "currentColor",
|
|
4954
|
-
strokeWidth: "2",
|
|
4955
|
-
strokeLinecap: "round",
|
|
4956
|
-
strokeLinejoin: "round",
|
|
4957
|
-
className: "lucide lucide-blend-icon lucide-blend mr-1.5 inline-block"
|
|
4958
|
-
},
|
|
4959
|
-
/* @__PURE__ */ React10.createElement("circle", { cx: "9", cy: "9", r: "7" }),
|
|
4960
|
-
/* @__PURE__ */ React10.createElement("circle", { cx: "15", cy: "15", r: "7" })
|
|
4961
|
-
), nodeData.is_section && /* @__PURE__ */ React10.createElement(FiFolder, { className: "mr-2" }), itemName),
|
|
4962
|
-
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(
|
|
4963
|
-
"button",
|
|
4964
|
-
{
|
|
4965
|
-
onClick: (e) => {
|
|
4966
|
-
e.stopPropagation();
|
|
4967
|
-
onEditRelationship(path, nodeData.relationship || {});
|
|
4968
|
-
},
|
|
4969
|
-
className: "w-6 h-6 grid place-content-center rounded-full hover:bg-cyan-500/20 text-cyan-400 transition-colors flex-shrink-0",
|
|
4970
|
-
title: "Editar detalhes da rela\xE7\xE3o",
|
|
4971
|
-
style: { cursor: "pointer" }
|
|
4972
|
-
},
|
|
4973
|
-
/* @__PURE__ */ React10.createElement(FiEdit23, { size: 12 })
|
|
4974
|
-
), /* @__PURE__ */ React10.createElement(
|
|
4975
|
-
"button",
|
|
4976
|
-
{
|
|
4977
|
-
onClick: (e) => {
|
|
4978
|
-
e.stopPropagation();
|
|
4979
|
-
onRemoveNode(path);
|
|
4980
|
-
},
|
|
4981
|
-
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",
|
|
4982
|
-
title: "Remover Node da ancestralidade",
|
|
4983
|
-
style: { cursor: "pointer" }
|
|
4984
|
-
},
|
|
4985
|
-
"\xD7"
|
|
4986
|
-
))
|
|
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"))
|
|
4987
4961
|
), hasChildren && /* @__PURE__ */ React10.createElement("div", { className: "mt-2 space-y-2 pl-8" }, nodeData.children.map((child, index) => /* @__PURE__ */ React10.createElement(
|
|
4988
4962
|
NodeItem,
|
|
4989
4963
|
{
|
|
4990
4964
|
key: `${child.is_section ? child.id : child.node.id}-${index}`,
|
|
4991
4965
|
nodeData: child,
|
|
4992
4966
|
onSelectParent,
|
|
4967
|
+
onViewSelect,
|
|
4968
|
+
highlightedPathIds,
|
|
4969
|
+
targetRenderNodeId,
|
|
4993
4970
|
onRemoveNode,
|
|
4994
4971
|
onEditRelationship,
|
|
4995
4972
|
onMoveNode,
|
|
@@ -5004,11 +4981,8 @@ var NodeItem = ({ nodeData, onSelectParent, onRemoveNode, onEditRelationship, on
|
|
|
5004
4981
|
function CreateAncestryPanel({
|
|
5005
4982
|
ancestryMode,
|
|
5006
4983
|
setAncestryMode,
|
|
5007
|
-
// <--- Nova prop necessária para as novas funções manipuladoras
|
|
5008
4984
|
onSelectParent,
|
|
5009
|
-
// Mantido para compatibilidade, mas as novas funções usam setAncestryMode
|
|
5010
4985
|
onRemoveNode,
|
|
5011
|
-
// Mantido para compatibilidade
|
|
5012
4986
|
onSave,
|
|
5013
4987
|
onClose,
|
|
5014
4988
|
onEditRelationship,
|
|
@@ -5019,14 +4993,12 @@ function CreateAncestryPanel({
|
|
|
5019
4993
|
onUpdateTree,
|
|
5020
4994
|
onAncestrySectionChange,
|
|
5021
4995
|
onToggleAddNodes,
|
|
5022
|
-
// Mantido para compatibilidade
|
|
5023
4996
|
onRenderFullAncestry,
|
|
5024
4997
|
onHighlightNode,
|
|
5025
4998
|
onClearAncestryVisuals,
|
|
5026
4999
|
onUploadFile,
|
|
5027
5000
|
onOpenImageViewer,
|
|
5028
5001
|
onRenderAbstractionTree
|
|
5029
|
-
// <--- Nova prop recebida
|
|
5030
5002
|
}) {
|
|
5031
5003
|
const {
|
|
5032
5004
|
tree: rootTree,
|
|
@@ -5043,6 +5015,20 @@ function CreateAncestryPanel({
|
|
|
5043
5015
|
const [customProps, setCustomProps] = useState10([]);
|
|
5044
5016
|
const propsEndRef = useRef8(null);
|
|
5045
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]);
|
|
5046
5032
|
const [targetScrollSectionId, setTargetScrollSectionId] = useState10(null);
|
|
5047
5033
|
const [internalHighlightedNodeId, setInternalHighlightedNodeId] = useState10(null);
|
|
5048
5034
|
const [ancestryName, setAncestryName] = useState10(initialName);
|
|
@@ -5066,6 +5052,9 @@ function CreateAncestryPanel({
|
|
|
5066
5052
|
setAncestryMode((prev) => isAbstraction ? { ...prev, selectedAbstractionParentId: nodeId } : { ...prev, selectedParentId: nodeId });
|
|
5067
5053
|
};
|
|
5068
5054
|
const handleToggleAddMode = (isAbstraction = false) => {
|
|
5055
|
+
if (isAbstraction && !ancestryMode.isAddingAbstractionNodes) {
|
|
5056
|
+
setTargetRenderNodeId(null);
|
|
5057
|
+
}
|
|
5069
5058
|
setAncestryMode((prev) => isAbstraction ? { ...prev, isAddingAbstractionNodes: !prev.isAddingAbstractionNodes } : { ...prev, isAddingNodes: !prev.isAddingNodes });
|
|
5070
5059
|
};
|
|
5071
5060
|
const handleRemoveNode = useCallback((pathToRemove, isAbstraction = false) => {
|
|
@@ -6201,44 +6190,77 @@ function CreateAncestryPanel({
|
|
|
6201
6190
|
path: [],
|
|
6202
6191
|
isEditable: isAddingNodes
|
|
6203
6192
|
}
|
|
6204
|
-
), (!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(
|
|
6205
|
-
"
|
|
6206
|
-
{
|
|
6207
|
-
type: "button",
|
|
6208
|
-
onClick: () => {
|
|
6209
|
-
const tempPayload = {
|
|
6210
|
-
ancestry_id: currentAncestryId || "temp_rendering",
|
|
6211
|
-
abstraction_tree: ancestryMode.abstraction_tree
|
|
6212
|
-
};
|
|
6213
|
-
if (onRenderAbstractionTree) onRenderAbstractionTree(tempPayload);
|
|
6214
|
-
},
|
|
6215
|
-
className: "p-1.5 rounded-md bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600 transition-colors",
|
|
6216
|
-
title: "Renderizar Verticalmente no Cen\xE1rio"
|
|
6217
|
-
},
|
|
6218
|
-
/* @__PURE__ */ React10.createElement(FiLayers5, { size: 14 })
|
|
6219
|
-
), /* @__PURE__ */ React10.createElement(
|
|
6220
|
-
"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",
|
|
6221
6195
|
{
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
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)
|
|
6225
6198
|
},
|
|
6226
|
-
ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ React10.createElement(
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
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(
|
|
6242
6264
|
"input",
|
|
6243
6265
|
{
|
|
6244
6266
|
type: "checkbox",
|
|
@@ -8769,16 +8791,16 @@ var getAllNodeIdsFromTree = (treeNode) => {
|
|
|
8769
8791
|
traverse(treeNode);
|
|
8770
8792
|
return Array.from(ids);
|
|
8771
8793
|
};
|
|
8772
|
-
var findNodePath2 = (tree,
|
|
8794
|
+
var findNodePath2 = (tree, targetNodeId2, currentPath = []) => {
|
|
8773
8795
|
var _a;
|
|
8774
8796
|
if (!tree) return null;
|
|
8775
8797
|
const currentNodeId = tree.is_section ? tree.section_id : String((_a = tree.node) == null ? void 0 : _a.id);
|
|
8776
|
-
if (String(currentNodeId) === String(
|
|
8798
|
+
if (String(currentNodeId) === String(targetNodeId2)) {
|
|
8777
8799
|
return { node: tree, path: currentPath };
|
|
8778
8800
|
}
|
|
8779
8801
|
if (tree.children) {
|
|
8780
8802
|
for (let i = 0; i < tree.children.length; i++) {
|
|
8781
|
-
const res = findNodePath2(tree.children[i],
|
|
8803
|
+
const res = findNodePath2(tree.children[i], targetNodeId2, [...currentPath, i]);
|
|
8782
8804
|
if (res) return res;
|
|
8783
8805
|
}
|
|
8784
8806
|
}
|
|
@@ -10852,8 +10874,29 @@ function XViewScene({
|
|
|
10852
10874
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
10853
10875
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
10854
10876
|
const allParentNodes = Object.values(parentDataRef.current).flatMap((f) => f.nodes);
|
|
10855
|
-
|
|
10877
|
+
let fullTree = buildFullAncestryTree(ancestryObject.abstraction_tree, allParentNodes, ancestryDataRef.current);
|
|
10856
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
|
+
}
|
|
10857
10900
|
const absId = ancestryObject.ancestry_id + "_abs";
|
|
10858
10901
|
handleClearAncestryVisuals(absId);
|
|
10859
10902
|
const colorHex = 9133302;
|
|
@@ -11865,7 +11908,7 @@ function XViewScene({
|
|
|
11865
11908
|
onClearAncestryVisuals: handleClearAncestryVisuals,
|
|
11866
11909
|
onUploadFile: upload_file_action,
|
|
11867
11910
|
onOpenImageViewer: handleOpenImageViewer,
|
|
11868
|
-
onRenderAbstractionTree: (data) => handleRenderAbstractionTree(data)
|
|
11911
|
+
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
11869
11912
|
}
|
|
11870
11913
|
),
|
|
11871
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",
|