@lv-x-software-house/x_view 1.2.4-dev.15 → 1.2.4-dev.17

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 CHANGED
@@ -948,7 +948,7 @@ var createNodeMesh = (nodeData, position, glowTexture) => {
948
948
  if (useImage && nodeData.textureImageUrl) {
949
949
  geometry = new THREE.CircleGeometry(1.5, 48);
950
950
  const texture = getTexture(nodeData.textureImageUrl);
951
- material = new MeshBasicMaterial({
951
+ material = new THREE.MeshBasicMaterial({
952
952
  map: texture,
953
953
  color: 16777215,
954
954
  side: THREE.DoubleSide,
@@ -1225,8 +1225,6 @@ var createMultipleLinkLines = (linksArray, sourceNodeMesh, targetNodeMesh, resol
1225
1225
  targetNodeMesh,
1226
1226
  resolution,
1227
1227
  isCurved,
1228
- isCurved,
1229
- isCurved,
1230
1228
  curveOffset
1231
1229
  );
1232
1230
  line.userData = {
@@ -1897,10 +1895,6 @@ var userActionHandlers = {
1897
1895
  var _a;
1898
1896
  const isSource = String(link.source) === String(sourceNode.id);
1899
1897
  const targetNodeId = isSource ? link.target : link.source;
1900
- const linkAlreadyInSceneData = sceneDataRef.current.links.some((l) => String(l.id) === String(link.id));
1901
- if (!linkAlreadyInSceneData) {
1902
- sceneDataRef.current.links.push(link);
1903
- }
1904
1898
  if (!nodeObjects[String(targetNodeId)]) {
1905
1899
  const allParentNodes = Object.values(graphDataRef.current).flatMap((fileData) => fileData.nodes);
1906
1900
  const nodeData = allParentNodes.find((n) => String(n.id) === String(targetNodeId));
@@ -1908,9 +1902,6 @@ var userActionHandlers = {
1908
1902
  console.warn(`Dados do Node com ID ${targetNodeId} n\xE3o encontrados no cache.`);
1909
1903
  return;
1910
1904
  }
1911
- if (!sceneDataRef.current.nodes.some((n) => String(n.id) === String(nodeData.id))) {
1912
- sceneDataRef.current.nodes.push(nodeData);
1913
- }
1914
1905
  const startPosition = sourceNodeMesh.position.clone();
1915
1906
  const endPosition = startPosition.clone().add(
1916
1907
  new THREE.Vector3((Math.random() - 0.5) * 60, (Math.random() - 0.5) * 15, (Math.random() - 0.5) * 60)
@@ -2141,14 +2132,28 @@ var userActionHandlers = {
2141
2132
  } else {
2142
2133
  newTargetId = newEndNodeData.id;
2143
2134
  }
2144
- const originalParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId, context.sceneConfigId, context.ownerId);
2145
- const newParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId, context.sceneConfigId, context.ownerId);
2146
- if (!originalParentInfo || !newParentInfo || !originalParentInfo.ownerId || !newParentInfo.ownerId) {
2147
- console.error("N\xE3o foi poss\xEDvel encontrar informa\xE7\xF5es dos arquivos pai para o relink.");
2135
+ const oldSourceInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId, context.sceneConfigId, context.ownerId);
2136
+ const oldTargetInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldTargetId, context.sceneConfigId, context.ownerId);
2137
+ const newSourceInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId, context.sceneConfigId, context.ownerId);
2138
+ const newTargetInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newTargetId, context.sceneConfigId, context.ownerId);
2139
+ if (!oldSourceInfo || !oldTargetInfo || !newSourceInfo || !newTargetInfo) {
2140
+ console.error("Informa\xE7\xF5es dos arquivos pai incompletas para o relink.");
2148
2141
  alert("Ocorreu um erro ao identificar os arquivos pai para salvar a altera\xE7\xE3o.");
2149
2142
  userActionHandlers.handleCancelRelink(context);
2150
2143
  return;
2151
2144
  }
2145
+ let oldGoverningFileId = oldSourceInfo.parentFileId;
2146
+ let oldGoverningOwnerId = oldSourceInfo.ownerId;
2147
+ if (oldSourceInfo.parentFileId === context.sceneConfigId || oldTargetInfo.parentFileId === context.sceneConfigId) {
2148
+ oldGoverningFileId = context.sceneConfigId;
2149
+ oldGoverningOwnerId = context.ownerId;
2150
+ }
2151
+ let newGoverningFileId = newSourceInfo.parentFileId;
2152
+ let newGoverningOwnerId = newSourceInfo.ownerId;
2153
+ if (newSourceInfo.parentFileId === context.sceneConfigId || newTargetInfo.parentFileId === context.sceneConfigId) {
2154
+ newGoverningFileId = context.sceneConfigId;
2155
+ newGoverningOwnerId = context.ownerId;
2156
+ }
2152
2157
  const { sourceNode, targetNode, ...dataToKeep } = originalLinkData;
2153
2158
  const newLinkData = {
2154
2159
  ...dataToKeep,
@@ -2174,26 +2179,26 @@ var userActionHandlers = {
2174
2179
  };
2175
2180
  const savePromises = [];
2176
2181
  const filesToUpdate = {};
2177
- if (originalParentInfo.parentFileId !== newParentInfo.parentFileId) {
2178
- const updatedOriginalParentData = JSON.parse(JSON.stringify(graphDataRef.current[originalParentInfo.parentFileId]));
2182
+ if (oldGoverningFileId !== newGoverningFileId) {
2183
+ const updatedOriginalParentData = JSON.parse(JSON.stringify(graphDataRef.current[oldGoverningFileId]));
2179
2184
  updatedOriginalParentData.links = updatedOriginalParentData.links.filter(
2180
2185
  (l) => String(l.id) !== String(linkId)
2181
2186
  );
2182
- filesToUpdate[originalParentInfo.parentFileId] = updatedOriginalParentData;
2183
- savePromises.push(saveParentData(originalParentInfo.parentFileId, originalParentInfo.ownerId, updatedOriginalParentData));
2184
- const updatedNewParentData = JSON.parse(JSON.stringify(graphDataRef.current[newParentInfo.parentFileId]));
2187
+ filesToUpdate[oldGoverningFileId] = updatedOriginalParentData;
2188
+ savePromises.push(saveParentData(oldGoverningFileId, oldGoverningOwnerId, updatedOriginalParentData));
2189
+ const updatedNewParentData = JSON.parse(JSON.stringify(graphDataRef.current[newGoverningFileId]));
2185
2190
  if (!updatedNewParentData.links) updatedNewParentData.links = [];
2186
2191
  updatedNewParentData.links.push(newLinkData);
2187
- filesToUpdate[newParentInfo.parentFileId] = updatedNewParentData;
2188
- savePromises.push(saveParentData(newParentInfo.parentFileId, newParentInfo.ownerId, updatedNewParentData));
2192
+ filesToUpdate[newGoverningFileId] = updatedNewParentData;
2193
+ savePromises.push(saveParentData(newGoverningFileId, newGoverningOwnerId, updatedNewParentData));
2189
2194
  } else {
2190
- const updatedParentData = JSON.parse(JSON.stringify(graphDataRef.current[originalParentInfo.parentFileId]));
2195
+ const updatedParentData = JSON.parse(JSON.stringify(graphDataRef.current[oldGoverningFileId]));
2191
2196
  updatedParentData.links = updatedParentData.links.filter(
2192
2197
  (l) => String(l.id) !== String(linkId)
2193
2198
  );
2194
2199
  updatedParentData.links.push(newLinkData);
2195
- filesToUpdate[originalParentInfo.parentFileId] = updatedParentData;
2196
- savePromises.push(saveParentData(originalParentInfo.parentFileId, originalParentInfo.ownerId, updatedParentData));
2200
+ filesToUpdate[oldGoverningFileId] = updatedParentData;
2201
+ savePromises.push(saveParentData(oldGoverningFileId, oldGoverningOwnerId, updatedParentData));
2197
2202
  }
2198
2203
  try {
2199
2204
  await Promise.all(savePromises);
@@ -2268,12 +2273,6 @@ var userActionHandlers = {
2268
2273
  if (!nodeData || !sceneDataRef.current) return;
2269
2274
  const nodeIdToDismiss = nodeData.id;
2270
2275
  const strNodeId = String(nodeIdToDismiss);
2271
- sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
2272
- (n) => String(n.id) !== strNodeId
2273
- );
2274
- sceneDataRef.current.links = sceneDataRef.current.links.filter(
2275
- (l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId
2276
- );
2277
2276
  const { ancestryGroup, ancestryLinks } = stateRef.current;
2278
2277
  if (ancestryGroup && ancestryLinks) {
2279
2278
  const remainingAncestryLinks = [];
@@ -2315,22 +2314,12 @@ var userActionHandlers = {
2315
2314
  removeNodeFromScene(stateRef.current, nodeId);
2316
2315
  setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
2317
2316
  });
2318
- sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
2319
- (n) => String(n.id) === strNodeIdToKeep
2320
- );
2321
- sceneDataRef.current.links = [];
2322
2317
  },
2323
2318
  handleDismissMultipleNodes: (context, nodeIds) => {
2324
2319
  const { stateRef, sceneDataRef, setters } = context;
2325
2320
  setters.setMultiContextMenu({ visible: false });
2326
2321
  if (!nodeIds || nodeIds.size === 0 || !sceneDataRef.current) return;
2327
2322
  const strNodeIds = Array.from(nodeIds).map(String);
2328
- sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
2329
- (n) => !strNodeIds.includes(String(n.id))
2330
- );
2331
- sceneDataRef.current.links = sceneDataRef.current.links.filter(
2332
- (l) => !strNodeIds.includes(String(l.source)) && !strNodeIds.includes(String(l.target))
2333
- );
2334
2323
  const { ancestryGroup, ancestryLinks } = stateRef.current;
2335
2324
  if (ancestryGroup && ancestryLinks) {
2336
2325
  const remainingAncestryLinks = [];
@@ -2386,12 +2375,6 @@ var userActionHandlers = {
2386
2375
  removeNodeFromScene(stateRef.current, nodeId);
2387
2376
  setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
2388
2377
  });
2389
- sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
2390
- (n) => strNodeIdsToKeep.includes(String(n.id))
2391
- );
2392
- sceneDataRef.current.links = sceneDataRef.current.links.filter(
2393
- (l) => strNodeIdsToKeep.includes(String(l.source)) && strNodeIdsToKeep.includes(String(l.target))
2394
- );
2395
2378
  stateRef.current.selectedNodes.clear();
2396
2379
  },
2397
2380
  handleDeleteMultipleNodes: async (context, nodeIds) => {
@@ -2649,7 +2632,7 @@ var userActionHandlers = {
2649
2632
  }
2650
2633
  },
2651
2634
  handleAddExistingNodeById: (context, nodeId) => {
2652
- var _a, _b;
2635
+ var _a;
2653
2636
  const { stateRef, sceneDataRef, graphDataRef, tweenToTarget, setters } = context;
2654
2637
  const state = stateRef.current;
2655
2638
  const graphFull = graphDataRef.current;
@@ -2665,16 +2648,12 @@ var userActionHandlers = {
2665
2648
  tweenToTarget(state.nodeObjects[strNodeId]);
2666
2649
  return;
2667
2650
  }
2668
- const alreadyInSceneData = (((_a = sceneDataRef.current) == null ? void 0 : _a.nodes) || []).some((n) => String(n.id) === String(strNodeId));
2669
- if (!alreadyInSceneData) {
2670
- sceneDataRef.current.nodes.push(nodeData);
2671
- }
2672
2651
  const base = state.controls ? state.controls.target.clone() : new THREE.Vector3(0, 0, 0);
2673
2652
  const offset = new THREE.Vector3((Math.random() - 0.5) * 20, (Math.random() - 0.5) * 6, (Math.random() - 0.5) * 20);
2674
2653
  const position = base.add(offset);
2675
2654
  addStandaloneNodeToScene(state, nodeData, position);
2676
2655
  tweenToTarget(position, 1.3);
2677
- (_b = setters == null ? void 0 : setters.setSceneVersion) == null ? void 0 : _b.call(setters, (v) => v + 1);
2656
+ (_a = setters == null ? void 0 : setters.setSceneVersion) == null ? void 0 : _a.call(setters, (v) => v + 1);
2678
2657
  }
2679
2658
  };
2680
2659
 
@@ -8074,7 +8053,7 @@ function InSceneQuestForm({
8074
8053
  onDoubleClick: swallow
8075
8054
  },
8076
8055
  /* @__PURE__ */ import_react16.default.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS[status]}, transparent)` } }),
8077
- /* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react16.default.createElement("div", null, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ import_react16.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova Tarefa / Objetivo")), /* @__PURE__ */ import_react16.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")), /* @__PURE__ */ import_react16.default.createElement(
8056
+ /* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react16.default.createElement("div", null, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ import_react16.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova quest")), /* @__PURE__ */ import_react16.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")), /* @__PURE__ */ import_react16.default.createElement(
8078
8057
  "button",
8079
8058
  {
8080
8059
  type: "button",
@@ -8128,7 +8107,7 @@ function InSceneQuestForm({
8128
8107
  onMentionClick,
8129
8108
  onSaveDescription: (newDesc) => setDescription(newDesc)
8130
8109
  }
8131
- ), /* @__PURE__ */ import_react16.default.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react16.default.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiEdit2, { size: 14 }))), !description && /* @__PURE__ */ import_react16.default.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Cen\xE1rio (Size)"), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ import_react16.default.createElement("button", { key: s, type: "button", onClick: () => setSize(s), className: "flex items-center gap-2 group cursor-pointer focus:outline-none" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${size === s ? "bg-indigo-500 border-indigo-500" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, size === s && /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react16.default.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s))))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react16.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ import_react16.default.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ import_react16.default.createElement(
8110
+ ), /* @__PURE__ */ import_react16.default.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react16.default.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiEdit2, { size: 14 }))), !description && /* @__PURE__ */ import_react16.default.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ import_react16.default.createElement("button", { key: s, type: "button", onClick: () => setSize(s), className: "flex items-center gap-2 group cursor-pointer focus:outline-none" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${size === s ? "bg-indigo-500 border-indigo-500" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, size === s && /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react16.default.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s))))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react16.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ import_react16.default.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ import_react16.default.createElement(
8132
8111
  CustomPropertyDisplay,
8133
8112
  {
8134
8113
  key: prop.id,
@@ -11675,10 +11654,10 @@ function XViewScene({
11675
11654
  const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, sourceNodeData.id, sceneConfigId2, ownerId2);
11676
11655
  const targetParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, targetNodeData.id, sceneConfigId2, ownerId2);
11677
11656
  let parentInfoToSave = sourceParentInfo;
11678
- if (sourceParentInfo.parentFileId === sceneConfigId2 && targetParentInfo.parentFileId !== sceneConfigId2) {
11679
- parentInfoToSave = targetParentInfo;
11680
- } else if (targetParentInfo.parentFileId === sceneConfigId2 && sourceParentInfo.parentFileId !== sceneConfigId2) {
11681
- parentInfoToSave = sourceParentInfo;
11657
+ const isSourceQuest = sourceParentInfo.parentFileId === sceneConfigId2;
11658
+ const isTargetQuest = targetParentInfo.parentFileId === sceneConfigId2;
11659
+ if (isSourceQuest || isTargetQuest) {
11660
+ parentInfoToSave = { parentFileId: sceneConfigId2, ownerId: ownerId2 };
11682
11661
  }
11683
11662
  const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
11684
11663
  const newLink = {
package/dist/index.mjs CHANGED
@@ -904,7 +904,7 @@ var createNodeMesh = (nodeData, position, glowTexture) => {
904
904
  if (useImage && nodeData.textureImageUrl) {
905
905
  geometry = new THREE.CircleGeometry(1.5, 48);
906
906
  const texture = getTexture(nodeData.textureImageUrl);
907
- material = new MeshBasicMaterial({
907
+ material = new THREE.MeshBasicMaterial({
908
908
  map: texture,
909
909
  color: 16777215,
910
910
  side: THREE.DoubleSide,
@@ -1181,8 +1181,6 @@ var createMultipleLinkLines = (linksArray, sourceNodeMesh, targetNodeMesh, resol
1181
1181
  targetNodeMesh,
1182
1182
  resolution,
1183
1183
  isCurved,
1184
- isCurved,
1185
- isCurved,
1186
1184
  curveOffset
1187
1185
  );
1188
1186
  line.userData = {
@@ -1853,10 +1851,6 @@ var userActionHandlers = {
1853
1851
  var _a;
1854
1852
  const isSource = String(link.source) === String(sourceNode.id);
1855
1853
  const targetNodeId = isSource ? link.target : link.source;
1856
- const linkAlreadyInSceneData = sceneDataRef.current.links.some((l) => String(l.id) === String(link.id));
1857
- if (!linkAlreadyInSceneData) {
1858
- sceneDataRef.current.links.push(link);
1859
- }
1860
1854
  if (!nodeObjects[String(targetNodeId)]) {
1861
1855
  const allParentNodes = Object.values(graphDataRef.current).flatMap((fileData) => fileData.nodes);
1862
1856
  const nodeData = allParentNodes.find((n) => String(n.id) === String(targetNodeId));
@@ -1864,9 +1858,6 @@ var userActionHandlers = {
1864
1858
  console.warn(`Dados do Node com ID ${targetNodeId} n\xE3o encontrados no cache.`);
1865
1859
  return;
1866
1860
  }
1867
- if (!sceneDataRef.current.nodes.some((n) => String(n.id) === String(nodeData.id))) {
1868
- sceneDataRef.current.nodes.push(nodeData);
1869
- }
1870
1861
  const startPosition = sourceNodeMesh.position.clone();
1871
1862
  const endPosition = startPosition.clone().add(
1872
1863
  new THREE.Vector3((Math.random() - 0.5) * 60, (Math.random() - 0.5) * 15, (Math.random() - 0.5) * 60)
@@ -2097,14 +2088,28 @@ var userActionHandlers = {
2097
2088
  } else {
2098
2089
  newTargetId = newEndNodeData.id;
2099
2090
  }
2100
- const originalParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId, context.sceneConfigId, context.ownerId);
2101
- const newParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId, context.sceneConfigId, context.ownerId);
2102
- if (!originalParentInfo || !newParentInfo || !originalParentInfo.ownerId || !newParentInfo.ownerId) {
2103
- console.error("N\xE3o foi poss\xEDvel encontrar informa\xE7\xF5es dos arquivos pai para o relink.");
2091
+ const oldSourceInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId, context.sceneConfigId, context.ownerId);
2092
+ const oldTargetInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldTargetId, context.sceneConfigId, context.ownerId);
2093
+ const newSourceInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId, context.sceneConfigId, context.ownerId);
2094
+ const newTargetInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newTargetId, context.sceneConfigId, context.ownerId);
2095
+ if (!oldSourceInfo || !oldTargetInfo || !newSourceInfo || !newTargetInfo) {
2096
+ console.error("Informa\xE7\xF5es dos arquivos pai incompletas para o relink.");
2104
2097
  alert("Ocorreu um erro ao identificar os arquivos pai para salvar a altera\xE7\xE3o.");
2105
2098
  userActionHandlers.handleCancelRelink(context);
2106
2099
  return;
2107
2100
  }
2101
+ let oldGoverningFileId = oldSourceInfo.parentFileId;
2102
+ let oldGoverningOwnerId = oldSourceInfo.ownerId;
2103
+ if (oldSourceInfo.parentFileId === context.sceneConfigId || oldTargetInfo.parentFileId === context.sceneConfigId) {
2104
+ oldGoverningFileId = context.sceneConfigId;
2105
+ oldGoverningOwnerId = context.ownerId;
2106
+ }
2107
+ let newGoverningFileId = newSourceInfo.parentFileId;
2108
+ let newGoverningOwnerId = newSourceInfo.ownerId;
2109
+ if (newSourceInfo.parentFileId === context.sceneConfigId || newTargetInfo.parentFileId === context.sceneConfigId) {
2110
+ newGoverningFileId = context.sceneConfigId;
2111
+ newGoverningOwnerId = context.ownerId;
2112
+ }
2108
2113
  const { sourceNode, targetNode, ...dataToKeep } = originalLinkData;
2109
2114
  const newLinkData = {
2110
2115
  ...dataToKeep,
@@ -2130,26 +2135,26 @@ var userActionHandlers = {
2130
2135
  };
2131
2136
  const savePromises = [];
2132
2137
  const filesToUpdate = {};
2133
- if (originalParentInfo.parentFileId !== newParentInfo.parentFileId) {
2134
- const updatedOriginalParentData = JSON.parse(JSON.stringify(graphDataRef.current[originalParentInfo.parentFileId]));
2138
+ if (oldGoverningFileId !== newGoverningFileId) {
2139
+ const updatedOriginalParentData = JSON.parse(JSON.stringify(graphDataRef.current[oldGoverningFileId]));
2135
2140
  updatedOriginalParentData.links = updatedOriginalParentData.links.filter(
2136
2141
  (l) => String(l.id) !== String(linkId)
2137
2142
  );
2138
- filesToUpdate[originalParentInfo.parentFileId] = updatedOriginalParentData;
2139
- savePromises.push(saveParentData(originalParentInfo.parentFileId, originalParentInfo.ownerId, updatedOriginalParentData));
2140
- const updatedNewParentData = JSON.parse(JSON.stringify(graphDataRef.current[newParentInfo.parentFileId]));
2143
+ filesToUpdate[oldGoverningFileId] = updatedOriginalParentData;
2144
+ savePromises.push(saveParentData(oldGoverningFileId, oldGoverningOwnerId, updatedOriginalParentData));
2145
+ const updatedNewParentData = JSON.parse(JSON.stringify(graphDataRef.current[newGoverningFileId]));
2141
2146
  if (!updatedNewParentData.links) updatedNewParentData.links = [];
2142
2147
  updatedNewParentData.links.push(newLinkData);
2143
- filesToUpdate[newParentInfo.parentFileId] = updatedNewParentData;
2144
- savePromises.push(saveParentData(newParentInfo.parentFileId, newParentInfo.ownerId, updatedNewParentData));
2148
+ filesToUpdate[newGoverningFileId] = updatedNewParentData;
2149
+ savePromises.push(saveParentData(newGoverningFileId, newGoverningOwnerId, updatedNewParentData));
2145
2150
  } else {
2146
- const updatedParentData = JSON.parse(JSON.stringify(graphDataRef.current[originalParentInfo.parentFileId]));
2151
+ const updatedParentData = JSON.parse(JSON.stringify(graphDataRef.current[oldGoverningFileId]));
2147
2152
  updatedParentData.links = updatedParentData.links.filter(
2148
2153
  (l) => String(l.id) !== String(linkId)
2149
2154
  );
2150
2155
  updatedParentData.links.push(newLinkData);
2151
- filesToUpdate[originalParentInfo.parentFileId] = updatedParentData;
2152
- savePromises.push(saveParentData(originalParentInfo.parentFileId, originalParentInfo.ownerId, updatedParentData));
2156
+ filesToUpdate[oldGoverningFileId] = updatedParentData;
2157
+ savePromises.push(saveParentData(oldGoverningFileId, oldGoverningOwnerId, updatedParentData));
2153
2158
  }
2154
2159
  try {
2155
2160
  await Promise.all(savePromises);
@@ -2224,12 +2229,6 @@ var userActionHandlers = {
2224
2229
  if (!nodeData || !sceneDataRef.current) return;
2225
2230
  const nodeIdToDismiss = nodeData.id;
2226
2231
  const strNodeId = String(nodeIdToDismiss);
2227
- sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
2228
- (n) => String(n.id) !== strNodeId
2229
- );
2230
- sceneDataRef.current.links = sceneDataRef.current.links.filter(
2231
- (l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId
2232
- );
2233
2232
  const { ancestryGroup, ancestryLinks } = stateRef.current;
2234
2233
  if (ancestryGroup && ancestryLinks) {
2235
2234
  const remainingAncestryLinks = [];
@@ -2271,22 +2270,12 @@ var userActionHandlers = {
2271
2270
  removeNodeFromScene(stateRef.current, nodeId);
2272
2271
  setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
2273
2272
  });
2274
- sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
2275
- (n) => String(n.id) === strNodeIdToKeep
2276
- );
2277
- sceneDataRef.current.links = [];
2278
2273
  },
2279
2274
  handleDismissMultipleNodes: (context, nodeIds) => {
2280
2275
  const { stateRef, sceneDataRef, setters } = context;
2281
2276
  setters.setMultiContextMenu({ visible: false });
2282
2277
  if (!nodeIds || nodeIds.size === 0 || !sceneDataRef.current) return;
2283
2278
  const strNodeIds = Array.from(nodeIds).map(String);
2284
- sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
2285
- (n) => !strNodeIds.includes(String(n.id))
2286
- );
2287
- sceneDataRef.current.links = sceneDataRef.current.links.filter(
2288
- (l) => !strNodeIds.includes(String(l.source)) && !strNodeIds.includes(String(l.target))
2289
- );
2290
2279
  const { ancestryGroup, ancestryLinks } = stateRef.current;
2291
2280
  if (ancestryGroup && ancestryLinks) {
2292
2281
  const remainingAncestryLinks = [];
@@ -2342,12 +2331,6 @@ var userActionHandlers = {
2342
2331
  removeNodeFromScene(stateRef.current, nodeId);
2343
2332
  setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
2344
2333
  });
2345
- sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
2346
- (n) => strNodeIdsToKeep.includes(String(n.id))
2347
- );
2348
- sceneDataRef.current.links = sceneDataRef.current.links.filter(
2349
- (l) => strNodeIdsToKeep.includes(String(l.source)) && strNodeIdsToKeep.includes(String(l.target))
2350
- );
2351
2334
  stateRef.current.selectedNodes.clear();
2352
2335
  },
2353
2336
  handleDeleteMultipleNodes: async (context, nodeIds) => {
@@ -2605,7 +2588,7 @@ var userActionHandlers = {
2605
2588
  }
2606
2589
  },
2607
2590
  handleAddExistingNodeById: (context, nodeId) => {
2608
- var _a, _b;
2591
+ var _a;
2609
2592
  const { stateRef, sceneDataRef, graphDataRef, tweenToTarget, setters } = context;
2610
2593
  const state = stateRef.current;
2611
2594
  const graphFull = graphDataRef.current;
@@ -2621,16 +2604,12 @@ var userActionHandlers = {
2621
2604
  tweenToTarget(state.nodeObjects[strNodeId]);
2622
2605
  return;
2623
2606
  }
2624
- const alreadyInSceneData = (((_a = sceneDataRef.current) == null ? void 0 : _a.nodes) || []).some((n) => String(n.id) === String(strNodeId));
2625
- if (!alreadyInSceneData) {
2626
- sceneDataRef.current.nodes.push(nodeData);
2627
- }
2628
2607
  const base = state.controls ? state.controls.target.clone() : new THREE.Vector3(0, 0, 0);
2629
2608
  const offset = new THREE.Vector3((Math.random() - 0.5) * 20, (Math.random() - 0.5) * 6, (Math.random() - 0.5) * 20);
2630
2609
  const position = base.add(offset);
2631
2610
  addStandaloneNodeToScene(state, nodeData, position);
2632
2611
  tweenToTarget(position, 1.3);
2633
- (_b = setters == null ? void 0 : setters.setSceneVersion) == null ? void 0 : _b.call(setters, (v) => v + 1);
2612
+ (_a = setters == null ? void 0 : setters.setSceneVersion) == null ? void 0 : _a.call(setters, (v) => v + 1);
2634
2613
  }
2635
2614
  };
2636
2615
 
@@ -8061,7 +8040,7 @@ function InSceneQuestForm({
8061
8040
  onDoubleClick: swallow
8062
8041
  },
8063
8042
  /* @__PURE__ */ React15.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS[status]}, transparent)` } }),
8064
- /* @__PURE__ */ React15.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React15.createElement(FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ React15.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova Tarefa / Objetivo")), /* @__PURE__ */ React15.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")), /* @__PURE__ */ React15.createElement(
8043
+ /* @__PURE__ */ React15.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React15.createElement(FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ React15.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova quest")), /* @__PURE__ */ React15.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")), /* @__PURE__ */ React15.createElement(
8065
8044
  "button",
8066
8045
  {
8067
8046
  type: "button",
@@ -8115,7 +8094,7 @@ function InSceneQuestForm({
8115
8094
  onMentionClick,
8116
8095
  onSaveDescription: (newDesc) => setDescription(newDesc)
8117
8096
  }
8118
- ), /* @__PURE__ */ React15.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiEdit26, { size: 14 }))), !description && /* @__PURE__ */ React15.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Cen\xE1rio (Size)"), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ React15.createElement("button", { key: s, type: "button", onClick: () => setSize(s), className: "flex items-center gap-2 group cursor-pointer focus:outline-none" }, /* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${size === s ? "bg-indigo-500 border-indigo-500" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, size === s && /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12, className: "text-white" })), /* @__PURE__ */ React15.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s))))), /* @__PURE__ */ React15.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React15.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiPlus5, { size: 14 }), " Adicionar")), /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ React15.createElement(
8097
+ ), /* @__PURE__ */ React15.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiEdit26, { size: 14 }))), !description && /* @__PURE__ */ React15.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ React15.createElement("button", { key: s, type: "button", onClick: () => setSize(s), className: "flex items-center gap-2 group cursor-pointer focus:outline-none" }, /* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${size === s ? "bg-indigo-500 border-indigo-500" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, size === s && /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12, className: "text-white" })), /* @__PURE__ */ React15.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s))))), /* @__PURE__ */ React15.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React15.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiPlus5, { size: 14 }), " Adicionar")), /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ React15.createElement(
8119
8098
  CustomPropertyDisplay,
8120
8099
  {
8121
8100
  key: prop.id,
@@ -11675,10 +11654,10 @@ function XViewScene({
11675
11654
  const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, sourceNodeData.id, sceneConfigId2, ownerId2);
11676
11655
  const targetParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, targetNodeData.id, sceneConfigId2, ownerId2);
11677
11656
  let parentInfoToSave = sourceParentInfo;
11678
- if (sourceParentInfo.parentFileId === sceneConfigId2 && targetParentInfo.parentFileId !== sceneConfigId2) {
11679
- parentInfoToSave = targetParentInfo;
11680
- } else if (targetParentInfo.parentFileId === sceneConfigId2 && sourceParentInfo.parentFileId !== sceneConfigId2) {
11681
- parentInfoToSave = sourceParentInfo;
11657
+ const isSourceQuest = sourceParentInfo.parentFileId === sceneConfigId2;
11658
+ const isTargetQuest = targetParentInfo.parentFileId === sceneConfigId2;
11659
+ if (isSourceQuest || isTargetQuest) {
11660
+ parentInfoToSave = { parentFileId: sceneConfigId2, ownerId: ownerId2 };
11682
11661
  }
11683
11662
  const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
11684
11663
  const newLink = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lv-x-software-house/x_view",
3
- "version": "1.2.4-dev.15",
3
+ "version": "1.2.4-dev.17",
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",