@lv-x-software-house/x_view 1.2.8-dev.2 → 1.2.8-dev.20

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.
Files changed (3) hide show
  1. package/dist/index.js +574 -464
  2. package/dist/index.mjs +612 -502
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -322,7 +322,12 @@ var updateExistingNodeVisuals = (state, updatedNode) => {
322
322
  if (oldLabelObject.material) oldLabelObject.material.dispose();
323
323
  }
324
324
  }
325
- const newMesh = createNodeMesh(updatedNode, position, state.glowTexture, hadQuestDateLabel);
325
+ const newMesh = createNodeMesh(
326
+ updatedNode,
327
+ position,
328
+ state.glowTexture,
329
+ hadQuestDateLabel
330
+ );
326
331
  if (oldTimelineBar) {
327
332
  newMesh.userData.timelineIntervalBar = oldTimelineBar;
328
333
  }
@@ -874,7 +879,12 @@ var removeNodeFromScene = (state, nodeId) => {
874
879
  var addStandaloneNodeToScene = (state, nodeData, position, forceShowQuestDate = false) => {
875
880
  const { graphGroup, nodeObjects, clickableNodes, glowTexture } = state;
876
881
  if (!graphGroup) return;
877
- const mesh = createNodeMesh(nodeData, position, glowTexture, forceShowQuestDate);
882
+ const mesh = createNodeMesh(
883
+ nodeData,
884
+ position,
885
+ glowTexture,
886
+ forceShowQuestDate
887
+ );
878
888
  mesh.scale.set(0.01, 0.01, 0.01);
879
889
  graphGroup.add(mesh);
880
890
  if (mesh.userData.labelObject) {
@@ -1092,7 +1102,9 @@ var userActionHandlers = {
1092
1102
  if (isCrossDataset) {
1093
1103
  graphDataRef.current[finalTargetDatasetId] = targetDataToUpdate;
1094
1104
  }
1095
- if (sceneDataRef.current.parent_dbs.some((db) => String(db.db_id) === String(sourceParentInfo.parentFileId))) {
1105
+ if (sceneDataRef.current.parent_dbs.some(
1106
+ (db) => String(db.db_id) === String(sourceParentInfo.parentFileId)
1107
+ )) {
1096
1108
  }
1097
1109
  const finalPosition = stateRef.current.ghostElements.node.position.clone();
1098
1110
  addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
@@ -1287,7 +1299,10 @@ var userActionHandlers = {
1287
1299
  context.sceneSaveUrl,
1288
1300
  viewFilePayload
1289
1301
  );
1290
- const questSaveUrl = context.sceneSaveUrl.replace("x_view_scenes", "x_view_quests");
1302
+ const questSaveUrl = context.sceneSaveUrl.replace(
1303
+ "x_view_scenes",
1304
+ "x_view_quests"
1305
+ );
1291
1306
  await context.actions.save_view_data(questSaveUrl, questFilePayload);
1292
1307
  } else {
1293
1308
  const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
@@ -1363,7 +1378,12 @@ var userActionHandlers = {
1363
1378
  )
1364
1379
  );
1365
1380
  targetFinalPositions.push(endPosition);
1366
- const targetMesh = createNodeMesh(nodeData, startPosition, glowTexture);
1381
+ const targetMesh = createNodeMesh(
1382
+ nodeData,
1383
+ startPosition,
1384
+ glowTexture,
1385
+ !!nodeData.is_quest
1386
+ );
1367
1387
  targetMesh.scale.set(0.01, 0.01, 0.01);
1368
1388
  graphGroup.add(targetMesh);
1369
1389
  if (targetMesh.userData.labelObject) {
@@ -1515,10 +1535,16 @@ var userActionHandlers = {
1515
1535
  context.sceneConfigId,
1516
1536
  context.ownerId
1517
1537
  );
1518
- if (!sourceParentInfo || !sourceParentInfo.ownerId) {
1538
+ const targetParentInfo = getParentFileInfoForNode(
1539
+ graphDataRef.current,
1540
+ sceneDataRef.current,
1541
+ targetNodeData.id,
1542
+ context.sceneConfigId,
1543
+ context.ownerId
1544
+ );
1545
+ if (!sourceParentInfo || !sourceParentInfo.ownerId || !targetParentInfo) {
1519
1546
  console.error(
1520
- "N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:",
1521
- sourceNodeData.id
1547
+ "N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para os Nodes da conex\xE3o."
1522
1548
  );
1523
1549
  alert(
1524
1550
  "Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio."
@@ -1526,9 +1552,13 @@ var userActionHandlers = {
1526
1552
  userActionHandlers.handleCancelConnection(context);
1527
1553
  return;
1528
1554
  }
1529
- const { parentFileId: sourceParentFileId, ownerId: sourceOwnerId } = sourceParentInfo;
1530
- const parentFileIdToSave = sourceParentFileId;
1531
- const ownerIdToSave = sourceOwnerId;
1555
+ let parentInfoToSave = sourceParentInfo;
1556
+ const isSourceQuest = sourceParentInfo.parentFileId === context.sceneConfigId;
1557
+ const isTargetQuest = targetParentInfo.parentFileId === context.sceneConfigId;
1558
+ if (isSourceQuest || isTargetQuest) {
1559
+ parentInfoToSave = { parentFileId: context.sceneConfigId, ownerId: context.ownerId };
1560
+ }
1561
+ const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
1532
1562
  const newLink = {
1533
1563
  id: `link_${import_short_uuid.default.generate()}`,
1534
1564
  source: sourceNodeData.id,
@@ -1542,20 +1572,19 @@ var userActionHandlers = {
1542
1572
  const viewFilePayload = {
1543
1573
  parent_dbs: sceneDataRef.current.parent_dbs,
1544
1574
  nodes: sceneDataRef.current.nodes,
1545
- links: sceneDataRef.current.links,
1546
- quest_counter: sceneDataRef.current.quest_counter || 1
1547
- };
1548
- const questFilePayload = {
1549
- nodes: specificParentData.nodes,
1550
- links: specificParentData.links,
1551
- milestones: sceneDataRef.current.milestones || []
1575
+ links: sceneDataRef.current.links
1552
1576
  };
1553
1577
  await context.actions.save_view_data(
1554
1578
  context.sceneSaveUrl,
1555
1579
  viewFilePayload
1556
1580
  );
1557
- const questSaveUrl = context.sceneSaveUrl.replace("x_view_scenes", "x_view_quests");
1558
- await context.actions.save_view_data(questSaveUrl, questFilePayload);
1581
+ if (context.actions.upsert_quest_link_firestore) {
1582
+ await context.actions.upsert_quest_link_firestore(
1583
+ context.ownerId,
1584
+ context.sceneConfigId,
1585
+ newLink
1586
+ );
1587
+ }
1559
1588
  } else {
1560
1589
  const specificParentData = JSON.parse(
1561
1590
  JSON.stringify(graphDataRef.current[parentFileIdToSave])
@@ -1704,18 +1733,12 @@ var userActionHandlers = {
1704
1733
  const viewFilePayload = {
1705
1734
  parent_dbs: sceneDataRef.current.parent_dbs,
1706
1735
  nodes: sceneDataRef.current.nodes,
1707
- links: sceneDataRef.current.links,
1708
- quest_counter: sceneDataRef.current.quest_counter || 1
1736
+ links: sceneDataRef.current.links
1709
1737
  };
1710
- const questFilePayload = {
1711
- nodes: data.nodes,
1712
- links: data.links,
1713
- milestones: sceneDataRef.current.milestones || []
1714
- };
1715
- const p1 = context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
1716
- const questSaveUrl = context.sceneSaveUrl.replace("x_view_scenes", "x_view_quests");
1717
- const p2 = context.actions.save_view_data(questSaveUrl, questFilePayload);
1718
- return Promise.all([p1, p2]);
1738
+ return context.actions.save_view_data(
1739
+ context.sceneSaveUrl,
1740
+ viewFilePayload
1741
+ );
1719
1742
  } else {
1720
1743
  return context.actions.save_view_data(
1721
1744
  `x_view_dbs/${fileOwnerId}/${fileId}`,
@@ -1740,6 +1763,15 @@ var userActionHandlers = {
1740
1763
  updatedOriginalParentData
1741
1764
  )
1742
1765
  );
1766
+ if (oldGoverningFileId === context.sceneConfigId && context.actions.delete_quest_link_firestore) {
1767
+ savePromises.push(
1768
+ context.actions.delete_quest_link_firestore(
1769
+ context.ownerId,
1770
+ context.sceneConfigId,
1771
+ linkId
1772
+ )
1773
+ );
1774
+ }
1743
1775
  const updatedNewParentData = JSON.parse(
1744
1776
  JSON.stringify(graphDataRef.current[newGoverningFileId])
1745
1777
  );
@@ -1753,6 +1785,15 @@ var userActionHandlers = {
1753
1785
  updatedNewParentData
1754
1786
  )
1755
1787
  );
1788
+ if (newGoverningFileId === context.sceneConfigId && context.actions.upsert_quest_link_firestore) {
1789
+ savePromises.push(
1790
+ context.actions.upsert_quest_link_firestore(
1791
+ context.ownerId,
1792
+ context.sceneConfigId,
1793
+ newLinkData
1794
+ )
1795
+ );
1796
+ }
1756
1797
  } else {
1757
1798
  const updatedParentData = JSON.parse(
1758
1799
  JSON.stringify(graphDataRef.current[oldGoverningFileId])
@@ -1769,6 +1810,15 @@ var userActionHandlers = {
1769
1810
  updatedParentData
1770
1811
  )
1771
1812
  );
1813
+ if (oldGoverningFileId === context.sceneConfigId && context.actions.upsert_quest_link_firestore) {
1814
+ savePromises.push(
1815
+ context.actions.upsert_quest_link_firestore(
1816
+ context.ownerId,
1817
+ context.sceneConfigId,
1818
+ newLinkData
1819
+ )
1820
+ );
1821
+ }
1772
1822
  }
1773
1823
  try {
1774
1824
  await Promise.all(savePromises);
@@ -1799,14 +1849,21 @@ var userActionHandlers = {
1799
1849
  );
1800
1850
  return;
1801
1851
  }
1802
- const parentInfo = getParentFileInfoForNode(
1852
+ const sourceParentInfo = getParentFileInfoForNode(
1803
1853
  graphDataRef.current,
1804
1854
  sceneDataRef.current,
1805
1855
  linkObject.userData.source,
1806
1856
  context.sceneConfigId,
1807
1857
  context.ownerId
1808
1858
  );
1809
- if (!parentInfo || !parentInfo.ownerId) {
1859
+ const targetParentInfo = getParentFileInfoForNode(
1860
+ graphDataRef.current,
1861
+ sceneDataRef.current,
1862
+ linkObject.userData.target,
1863
+ context.sceneConfigId,
1864
+ context.ownerId
1865
+ );
1866
+ if (!sourceParentInfo || !sourceParentInfo.ownerId) {
1810
1867
  console.error(
1811
1868
  "N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link:",
1812
1869
  linkIdToDelete
@@ -1816,6 +1873,12 @@ var userActionHandlers = {
1816
1873
  );
1817
1874
  return;
1818
1875
  }
1876
+ let parentInfo = sourceParentInfo;
1877
+ const isSourceQuest = sourceParentInfo.parentFileId === context.sceneConfigId;
1878
+ const isTargetQuest = (targetParentInfo == null ? void 0 : targetParentInfo.parentFileId) === context.sceneConfigId;
1879
+ if (isSourceQuest || isTargetQuest) {
1880
+ parentInfo = { parentFileId: context.sceneConfigId, ownerId: context.ownerId };
1881
+ }
1819
1882
  const { parentFileId, ownerId } = parentInfo;
1820
1883
  const srcName = ((_c = (_b = (_a = linkObject.userData) == null ? void 0 : _a.sourceNode) == null ? void 0 : _b.userData) == null ? void 0 : _c.name) ?? linkObject.userData.source;
1821
1884
  const tgtName = ((_f = (_e = (_d = linkObject.userData) == null ? void 0 : _d.targetNode) == null ? void 0 : _e.userData) == null ? void 0 : _f.name) ?? linkObject.userData.target;
@@ -1828,8 +1891,6 @@ var userActionHandlers = {
1828
1891
  specificParentData.links = newLinks;
1829
1892
  let filenameToSave;
1830
1893
  let payloadToSave;
1831
- let questSaveUrl;
1832
- let questFilePayload;
1833
1894
  const isView = ((_g = context.viewType) == null ? void 0 : _g.toLowerCase()) === "view";
1834
1895
  if (isView && parentFileId === context.sceneConfigId) {
1835
1896
  filenameToSave = context.sceneSaveUrl;
@@ -1839,14 +1900,7 @@ var userActionHandlers = {
1839
1900
  payloadToSave = {
1840
1901
  parent_dbs: sceneDataRef.current.parent_dbs,
1841
1902
  nodes: sceneDataRef.current.nodes,
1842
- links: sceneDataRef.current.links,
1843
- quest_counter: sceneDataRef.current.quest_counter || 1
1844
- };
1845
- questSaveUrl = context.sceneSaveUrl.replace("x_view_scenes", "x_view_quests");
1846
- questFilePayload = {
1847
- nodes: specificParentData.nodes,
1848
- links: specificParentData.links,
1849
- milestones: sceneDataRef.current.milestones || []
1903
+ links: sceneDataRef.current.links
1850
1904
  };
1851
1905
  } else {
1852
1906
  filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
@@ -1854,8 +1908,12 @@ var userActionHandlers = {
1854
1908
  }
1855
1909
  try {
1856
1910
  await context.actions.save_view_data(filenameToSave, payloadToSave);
1857
- if (questSaveUrl && questFilePayload) {
1858
- await context.actions.save_view_data(questSaveUrl, questFilePayload);
1911
+ if (isView && parentFileId === context.sceneConfigId && context.actions.delete_quest_link_firestore) {
1912
+ await context.actions.delete_quest_link_firestore(
1913
+ context.ownerId,
1914
+ context.sceneConfigId,
1915
+ linkIdToDelete
1916
+ );
1859
1917
  }
1860
1918
  graphDataRef.current[parentFileId] = specificParentData;
1861
1919
  setters.setDetailsLink(
@@ -2084,16 +2142,30 @@ var userActionHandlers = {
2084
2142
  payloadToSave = {
2085
2143
  parent_dbs: sceneDataRef.current.parent_dbs,
2086
2144
  nodes: sceneDataRef.current.nodes,
2087
- links: sceneDataRef.current.links,
2088
- quest_counter: sceneDataRef.current.quest_counter || 1
2145
+ links: sceneDataRef.current.links
2089
2146
  };
2090
- const questFilePayload = {
2091
- nodes: originalData.nodes,
2092
- links: originalData.links,
2093
- milestones: sceneDataRef.current.milestones || []
2094
- };
2095
- const questSaveUrl = context.sceneSaveUrl.replace("x_view_scenes", "x_view_quests");
2096
- savePromises.push(context.actions.save_view_data(questSaveUrl, questFilePayload));
2147
+ if (context.actions.delete_quest_firestore) {
2148
+ nodesToDelete.forEach((nodeIdToDelete) => {
2149
+ savePromises.push(
2150
+ context.actions.delete_quest_firestore(
2151
+ context.ownerId,
2152
+ context.sceneConfigId,
2153
+ nodeIdToDelete
2154
+ )
2155
+ );
2156
+ });
2157
+ if (context.actions.delete_quest_link_firestore) {
2158
+ linksToDelete.forEach((linkIdToDelete) => {
2159
+ savePromises.push(
2160
+ context.actions.delete_quest_link_firestore(
2161
+ context.ownerId,
2162
+ context.sceneConfigId,
2163
+ linkIdToDelete
2164
+ )
2165
+ );
2166
+ });
2167
+ }
2168
+ }
2097
2169
  } else {
2098
2170
  filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
2099
2171
  payloadToSave = originalData;
@@ -2164,6 +2236,9 @@ var userActionHandlers = {
2164
2236
  const newLinks = (specificParentData.links || []).filter(
2165
2237
  (l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId
2166
2238
  );
2239
+ const linksToDelete = (specificParentData.links || []).filter(
2240
+ (l) => String(l.source) === strNodeId || String(l.target) === strNodeId
2241
+ );
2167
2242
  specificParentData.nodes = newNodes;
2168
2243
  specificParentData.links = newLinks;
2169
2244
  let filenameToSave;
@@ -2182,18 +2257,27 @@ var userActionHandlers = {
2182
2257
  payloadToSave = {
2183
2258
  parent_dbs: sceneDataRef.current.parent_dbs,
2184
2259
  nodes: newVisualNodes,
2185
- links: newVisualLinks,
2186
- quest_counter: sceneDataRef.current.quest_counter || 1
2187
- };
2188
- const questFilePayload = {
2189
- nodes: specificParentData.nodes,
2190
- links: specificParentData.links,
2191
- milestones: sceneDataRef.current.milestones || []
2260
+ links: newVisualLinks
2192
2261
  };
2193
- const questSaveUrl = context.sceneSaveUrl.replace("x_view_scenes", "x_view_quests");
2194
2262
  try {
2195
2263
  await context.actions.save_view_data(filenameToSave, payloadToSave);
2196
- await context.actions.save_view_data(questSaveUrl, questFilePayload);
2264
+ if (context.actions.delete_quest_firestore) {
2265
+ await context.actions.delete_quest_firestore(
2266
+ context.ownerId,
2267
+ context.sceneConfigId,
2268
+ nodeIdToDelete
2269
+ );
2270
+ if (context.actions.delete_quest_link_firestore && linksToDelete.length > 0) {
2271
+ const linkDeletePromises = linksToDelete.map(
2272
+ (link) => context.actions.delete_quest_link_firestore(
2273
+ context.ownerId,
2274
+ context.sceneConfigId,
2275
+ link.id
2276
+ )
2277
+ );
2278
+ await Promise.all(linkDeletePromises);
2279
+ }
2280
+ }
2197
2281
  graphDataRef.current[parentFileId] = specificParentData;
2198
2282
  setters.setDetailsNode(
2199
2283
  (prev) => String(prev == null ? void 0 : prev.id) === String(nodeIdToDelete) ? null : prev
@@ -2226,6 +2310,7 @@ var userActionHandlers = {
2226
2310
  var _a, _b, _c, _d;
2227
2311
  const { graphDataRef, sceneDataRef, stateRef, setters } = context;
2228
2312
  if (!graphDataRef.current || !sceneDataRef.current) return;
2313
+ const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
2229
2314
  const {
2230
2315
  _baseEmissiveIntensity,
2231
2316
  _baseScale,
@@ -2270,7 +2355,7 @@ var userActionHandlers = {
2270
2355
  const oldNode = specificParentData.nodes[nodeIndex];
2271
2356
  const isNewDone = oldNode.status !== "Done" && nodeToSave.status === "Done";
2272
2357
  specificParentData.nodes[nodeIndex] = { ...nodeToSave };
2273
- if (isNewDone && nodeToSave.is_quest && ((_a = nodeToSave.recurrence_config) == null ? void 0 : _a.enabled)) {
2358
+ if (isNewDone && nodeToSave.is_quest && ((_b = nodeToSave.recurrence_config) == null ? void 0 : _b.enabled)) {
2274
2359
  const nextDateObj = calculateNextRecurrenceDate(
2275
2360
  nodeToSave.recurrence_config
2276
2361
  );
@@ -2295,12 +2380,10 @@ var userActionHandlers = {
2295
2380
  }
2296
2381
  const nextQuestNode = {
2297
2382
  ...JSON.parse(JSON.stringify(nodeToSave)),
2298
- // Deep copy properties
2299
2383
  id: import_short_uuid.default.generate(),
2300
2384
  name: nextName,
2301
2385
  status: "Backlog",
2302
2386
  color: "#64748b",
2303
- // QUEST_STATUS_COLORS["Backlog"]
2304
2387
  assignee_id: nodeToSave.recurrence_config.next_assignee_id || "",
2305
2388
  Date: nextDateObj,
2306
2389
  timeline: [
@@ -2317,7 +2400,7 @@ var userActionHandlers = {
2317
2400
  ],
2318
2401
  version_node: {
2319
2402
  is_version: true,
2320
- parent_node: ((_b = nodeToSave.version_node) == null ? void 0 : _b.parent_node) || nodeToSave.id
2403
+ parent_node: ((_c = nodeToSave.version_node) == null ? void 0 : _c.parent_node) || nodeToSave.id
2321
2404
  },
2322
2405
  reviewStack: (nodeToSave.reviewStack || []).map((r) => ({
2323
2406
  ...r,
@@ -2325,21 +2408,56 @@ var userActionHandlers = {
2325
2408
  })),
2326
2409
  recurrence_config: nextRecurrenceConfig
2327
2410
  };
2328
- specificParentData.nodes.push(nextQuestNode);
2411
+ const rootId = ((_d = nodeToSave.version_node) == null ? void 0 : _d.parent_node) || nodeToSave.id;
2412
+ const nextQuestLink = {
2413
+ id: `link_${import_short_uuid.default.generate()}`,
2414
+ source: rootId,
2415
+ target: nextQuestNode.id
2416
+ };
2417
+ await context.actions.upsert_quest_firestore(
2418
+ context.ownerId,
2419
+ context.sceneConfigId,
2420
+ nextQuestNode
2421
+ );
2422
+ await context.actions.upsert_quest_link_firestore(
2423
+ context.ownerId,
2424
+ context.sceneConfigId,
2425
+ nextQuestLink
2426
+ );
2427
+ await context.actions.update_view_counter(
2428
+ context.ownerId,
2429
+ context.sceneConfigId,
2430
+ nextCounter
2431
+ );
2432
+ if (specificParentData.links) {
2433
+ specificParentData.links.push(nextQuestLink);
2434
+ }
2435
+ if (specificParentData.nodes) {
2436
+ specificParentData.nodes.push(nextQuestNode);
2437
+ }
2438
+ if (isView && parentFileId === context.sceneConfigId) {
2439
+ if (!sceneDataRef.current.links) sceneDataRef.current.links = [];
2440
+ sceneDataRef.current.links.push(nextQuestLink);
2441
+ sceneDataRef.current.quest_nodes = [...specificParentData.nodes];
2442
+ }
2329
2443
  if (stateRef.current.nodeObjects[String(nodeToSave.id)]) {
2330
2444
  const oldMeshPosition = stateRef.current.nodeObjects[String(nodeToSave.id)].position.clone();
2331
2445
  setTimeout(() => {
2332
2446
  if (stateRef.current && stateRef.current.graphGroup) {
2333
2447
  const pos = oldMeshPosition.clone();
2334
2448
  pos.x += 12;
2335
- addStandaloneNodeToScene(stateRef.current, nextQuestNode, pos, true);
2449
+ addStandaloneNodeToScene(
2450
+ stateRef.current,
2451
+ nextQuestNode,
2452
+ pos,
2453
+ true
2454
+ );
2336
2455
  }
2337
2456
  }, 2e3);
2338
2457
  }
2339
2458
  }
2340
2459
  }
2341
2460
  try {
2342
- const isView = ((_c = context.viewType) == null ? void 0 : _c.toLowerCase()) === "view";
2343
2461
  if (isView && parentFileId === context.sceneConfigId) {
2344
2462
  const visualNodeIndex = sceneDataRef.current.nodes.findIndex(
2345
2463
  (n) => String(n.id) === String(nodeToSave.id)
@@ -2350,39 +2468,26 @@ var userActionHandlers = {
2350
2468
  ...nodeToSave
2351
2469
  };
2352
2470
  }
2353
- if (nodeToSave.is_quest && context.actions.save_quest_action) {
2354
- await context.actions.save_quest_action(context.ownerId, context.sceneConfigId, nodeToSave, sceneDataRef.current.quest_counter);
2355
- if (isNewDone && ((_d = nodeToSave.recurrence_config) == null ? void 0 : _d.enabled)) {
2356
- const createdRecurrenceQuest = specificParentData.nodes[specificParentData.nodes.length - 1];
2357
- if (createdRecurrenceQuest && String(createdRecurrenceQuest.id) !== String(nodeToSave.id)) {
2358
- await context.actions.save_quest_action(context.ownerId, context.sceneConfigId, createdRecurrenceQuest, sceneDataRef.current.quest_counter);
2359
- }
2360
- }
2361
- const viewFilePayload = {
2362
- parent_dbs: sceneDataRef.current.parent_dbs,
2363
- nodes: sceneDataRef.current.nodes,
2364
- links: sceneDataRef.current.links,
2365
- quest_counter: sceneDataRef.current.quest_counter || 1
2366
- };
2367
- await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
2368
- } else {
2369
- const viewFilePayload = {
2370
- parent_dbs: sceneDataRef.current.parent_dbs,
2371
- nodes: sceneDataRef.current.nodes,
2372
- links: sceneDataRef.current.links,
2373
- quest_counter: sceneDataRef.current.quest_counter || 1
2374
- };
2375
- const questFilePayload = {
2376
- nodes: specificParentData.nodes,
2377
- links: specificParentData.links,
2378
- milestones: sceneDataRef.current.milestones || []
2379
- };
2380
- await context.actions.save_view_data(
2381
- context.sceneSaveUrl,
2382
- viewFilePayload
2471
+ const viewFilePayload = {
2472
+ parent_dbs: sceneDataRef.current.parent_dbs,
2473
+ nodes: sceneDataRef.current.nodes,
2474
+ links: sceneDataRef.current.links
2475
+ };
2476
+ const questFilePayload = {
2477
+ nodes: specificParentData.nodes,
2478
+ links: specificParentData.links,
2479
+ milestones: sceneDataRef.current.milestones || []
2480
+ };
2481
+ await context.actions.save_view_data(
2482
+ context.sceneSaveUrl,
2483
+ viewFilePayload
2484
+ );
2485
+ if (context.actions.upsert_quest_firestore) {
2486
+ await context.actions.upsert_quest_firestore(
2487
+ context.ownerId,
2488
+ context.sceneConfigId,
2489
+ nodeToSave
2383
2490
  );
2384
- const questSaveUrl = context.sceneSaveUrl.replace("x_view_scenes", "x_view_quests");
2385
- await context.actions.save_view_data(questSaveUrl, questFilePayload);
2386
2491
  }
2387
2492
  } else {
2388
2493
  const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
@@ -2394,7 +2499,6 @@ var userActionHandlers = {
2394
2499
  graphDataRef.current[parentFileId] = specificParentData;
2395
2500
  if (isView && parentFileId === context.sceneConfigId) {
2396
2501
  sceneDataRef.current.quest_nodes = [...specificParentData.nodes];
2397
- sceneDataRef.current.quest_counter = specificParentData.quest_counter || sceneDataRef.current.quest_counter;
2398
2502
  }
2399
2503
  updateExistingNodeVisuals(stateRef.current, nodeToSave);
2400
2504
  setters.setSceneVersion((v) => v + 1);
@@ -2451,8 +2555,7 @@ var userActionHandlers = {
2451
2555
  const viewFilePayload = {
2452
2556
  parent_dbs: sceneDataRef.current.parent_dbs,
2453
2557
  nodes: sceneDataRef.current.nodes,
2454
- links: sceneDataRef.current.links,
2455
- quest_counter: sceneDataRef.current.quest_counter || 1
2558
+ links: sceneDataRef.current.links
2456
2559
  };
2457
2560
  const questFilePayload = {
2458
2561
  nodes: specificParentData.nodes,
@@ -2463,8 +2566,13 @@ var userActionHandlers = {
2463
2566
  context.sceneSaveUrl,
2464
2567
  viewFilePayload
2465
2568
  );
2466
- const questSaveUrl = context.sceneSaveUrl.replace("x_view_scenes", "x_view_quests");
2467
- await context.actions.save_view_data(questSaveUrl, questFilePayload);
2569
+ if (context.actions.upsert_quest_link_firestore) {
2570
+ await context.actions.upsert_quest_link_firestore(
2571
+ context.ownerId,
2572
+ context.sceneConfigId,
2573
+ linkToSave
2574
+ );
2575
+ }
2468
2576
  } else {
2469
2577
  const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
2470
2578
  await context.actions.save_view_data(
@@ -8947,6 +9055,7 @@ function CreateQuestTreePanel({
8947
9055
  const [isSaving, setIsSaving] = (0, import_react12.useState)(false);
8948
9056
  const [hasUnsavedChanges, setHasUnsavedChanges] = (0, import_react12.useState)(false);
8949
9057
  const [activeTab, setActiveTab] = (0, import_react12.useState)("tree");
9058
+ const isInitialLoad = (0, import_react12.useRef)(true);
8950
9059
  const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
8951
9060
  const { width: panelWidth, isResizing, handlePointerDown: handleResize } = useResizablePanel({
8952
9061
  initialWidth: 440,
@@ -8980,10 +9089,11 @@ function CreateQuestTreePanel({
8980
9089
  const indexToRemove = pathToRemove[pathToRemove.length - 1];
8981
9090
  if (currentParent.children && currentParent.children.length > indexToRemove) {
8982
9091
  currentParent.children.splice(indexToRemove, 1);
8983
- setHasUnsavedChanges(true);
9092
+ return { ...prev, [treeKey]: newTree };
8984
9093
  }
8985
- return { ...prev, [treeKey]: newTree };
9094
+ return prev;
8986
9095
  });
9096
+ setHasUnsavedChanges(true);
8987
9097
  }, [setQuestTreeMode, activeTab]);
8988
9098
  const handleMoveNode = (sourceId, targetId) => {
8989
9099
  const isAbstraction = activeTab === "abstraction";
@@ -9060,6 +9170,15 @@ function CreateQuestTreePanel({
9060
9170
  }));
9061
9171
  }
9062
9172
  }, [tree, abstraction_tree, questTreeMode.questNodeId, setQuestTreeMode]);
9173
+ (0, import_react12.useEffect)(() => {
9174
+ if (tree || abstraction_tree) {
9175
+ if (isInitialLoad.current) {
9176
+ isInitialLoad.current = false;
9177
+ return;
9178
+ }
9179
+ setHasUnsavedChanges(true);
9180
+ }
9181
+ }, [tree, abstraction_tree]);
9063
9182
  return /* @__PURE__ */ import_react12.default.createElement(
9064
9183
  "div",
9065
9184
  {
@@ -15495,13 +15614,12 @@ function XViewScene({
15495
15614
  get_view_members,
15496
15615
  create_google_doc_action,
15497
15616
  open_google_picker_action,
15498
- // Firestore Atomic Actions (Quests & Milestones)
15499
- save_quest_action,
15500
- delete_quest_action,
15501
- save_quest_link_action,
15502
- delete_quest_link_action,
15503
- save_milestone_action,
15504
- delete_milestone_action
15617
+ upsert_quest_firestore,
15618
+ delete_quest_firestore,
15619
+ upsert_quest_link_firestore,
15620
+ delete_quest_link_firestore,
15621
+ upsert_milestone_firestore,
15622
+ update_view_counter
15505
15623
  }) {
15506
15624
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
15507
15625
  const { data: session, status } = (0, import_react34.useSession)();
@@ -16061,11 +16179,19 @@ function XViewScene({
16061
16179
  }
16062
16180
  }
16063
16181
  Object.values(nodeObjects).forEach((mesh) => {
16064
- const oldLabel = mesh.getObjectByName("timelineLabel");
16065
- if (oldLabel) {
16066
- mesh.remove(oldLabel);
16067
- if (oldLabel.material.map) oldLabel.material.map.dispose();
16068
- oldLabel.material.dispose();
16182
+ const oldTimelineLabel = mesh.getObjectByName("timelineLabel");
16183
+ if (oldTimelineLabel) {
16184
+ mesh.remove(oldTimelineLabel);
16185
+ if (oldTimelineLabel.material.map)
16186
+ oldTimelineLabel.material.map.dispose();
16187
+ oldTimelineLabel.material.dispose();
16188
+ }
16189
+ const oldQuestDateLabel = mesh.getObjectByName("questDateLabel");
16190
+ if (oldQuestDateLabel) {
16191
+ mesh.remove(oldQuestDateLabel);
16192
+ if (oldQuestDateLabel.material.map)
16193
+ oldQuestDateLabel.material.map.dispose();
16194
+ oldQuestDateLabel.material.dispose();
16069
16195
  }
16070
16196
  delete mesh.userData.timelineIntervalBar;
16071
16197
  delete mesh.userData.timelineEndLabel;
@@ -16085,42 +16211,24 @@ function XViewScene({
16085
16211
  return null;
16086
16212
  };
16087
16213
  Object.values(nodeObjects).forEach((mesh) => {
16088
- const dateProp = mesh.userData.Date;
16214
+ var _a2;
16215
+ const dateProp = mesh.userData.Date || ((_a2 = (mesh.userData.properties || []).find(
16216
+ (p) => {
16217
+ var _a3;
16218
+ return ((_a3 = p.name) == null ? void 0 : _a3.toLowerCase()) === "data";
16219
+ }
16220
+ )) == null ? void 0 : _a2.value);
16089
16221
  let nodeInfo = { mesh, type: "point", label: "", isUndated: true };
16090
16222
  if (dateProp) {
16091
- if (dateProp.date) {
16092
- const date = parseDate2(dateProp.date);
16093
- if (date) {
16094
- nodeInfo.startDate = date;
16095
- nodeInfo.endDate = date;
16096
- nodeInfo.label = dateProp.date;
16097
- nodeInfo.isUndated = false;
16098
- allTimePoints.add(date.getTime());
16099
- }
16100
- } else if (dateProp.year) {
16101
- const year = parseInt(dateProp.year, 10);
16102
- if (!isNaN(year)) {
16103
- const date = new Date(year, 0, 1);
16104
- nodeInfo.startDate = date;
16105
- nodeInfo.endDate = date;
16106
- nodeInfo.label = String(year);
16107
- nodeInfo.isUndated = false;
16108
- allTimePoints.add(date.getTime());
16109
- }
16110
- } else if (dateProp.date_interval && dateProp.date_interval.start) {
16111
- const startYear = parseInt(dateProp.date_interval.start, 10);
16112
- const endYear = parseInt(dateProp.date_interval.end, 10) || startYear;
16113
- if (!isNaN(startYear)) {
16114
- const startDate = new Date(startYear, 0, 1);
16115
- const endDate = new Date(endYear, 11, 31);
16116
- nodeInfo.type = "interval";
16117
- nodeInfo.startDate = startDate;
16118
- nodeInfo.endDate = endDate;
16119
- nodeInfo.label = `${startYear} - ${endYear}`;
16120
- nodeInfo.isUndated = false;
16121
- allTimePoints.add(startDate.getTime());
16122
- allTimePoints.add(endDate.getTime());
16123
- }
16223
+ const info = parseDateProp(dateProp);
16224
+ if (!info.isUndated) {
16225
+ nodeInfo.startDate = info.startDate;
16226
+ nodeInfo.endDate = info.endDate;
16227
+ nodeInfo.label = info.label;
16228
+ nodeInfo.type = info.type;
16229
+ nodeInfo.isUndated = false;
16230
+ allTimePoints.add(info.startDate.getTime());
16231
+ if (info.endDate) allTimePoints.add(info.endDate.getTime());
16124
16232
  }
16125
16233
  }
16126
16234
  timelineNodes.push(nodeInfo);
@@ -16248,50 +16356,35 @@ function XViewScene({
16248
16356
  return null;
16249
16357
  };
16250
16358
  versionMeshes.forEach((mesh) => {
16251
- const dateProp = mesh.userData.Date;
16252
- if (!dateProp) return;
16253
- let nodeInfo = { mesh, type: "point", label: "" };
16254
- if (dateProp.date) {
16255
- const date = parseDate2(dateProp.date);
16256
- if (date) {
16257
- nodeInfo.startDate = date;
16258
- nodeInfo.endDate = date;
16259
- nodeInfo.label = dateProp.date;
16260
- allTimePoints.add(date.getTime());
16261
- timelineNodes.push(nodeInfo);
16262
- }
16263
- } else if (dateProp.year) {
16264
- const year = parseInt(dateProp.year, 10);
16265
- if (!isNaN(year)) {
16266
- const date = new Date(year, 0, 1);
16267
- nodeInfo.startDate = date;
16268
- nodeInfo.endDate = date;
16269
- nodeInfo.label = String(year);
16270
- allTimePoints.add(date.getTime());
16271
- timelineNodes.push(nodeInfo);
16272
- }
16273
- } else if (dateProp.date_interval && dateProp.date_interval.start) {
16274
- const startYear = parseInt(dateProp.date_interval.start, 10);
16275
- const endYear = parseInt(dateProp.date_interval.end, 10) || startYear;
16276
- if (!isNaN(startYear)) {
16277
- const startDate = new Date(startYear, 0, 1);
16278
- const endDate = new Date(endYear, 11, 31);
16279
- nodeInfo.type = "interval";
16280
- nodeInfo.startDate = startDate;
16281
- nodeInfo.endDate = endDate;
16282
- nodeInfo.label = `${startYear} - ${endYear}`;
16283
- allTimePoints.add(startDate.getTime());
16284
- allTimePoints.add(endDate.getTime());
16285
- timelineNodes.push(nodeInfo);
16359
+ var _a2;
16360
+ const dateProp = mesh.userData.Date || ((_a2 = (mesh.userData.properties || []).find(
16361
+ (p) => {
16362
+ var _a3;
16363
+ return ((_a3 = p.name) == null ? void 0 : _a3.toLowerCase()) === "data";
16286
16364
  }
16365
+ )) == null ? void 0 : _a2.value);
16366
+ if (!dateProp) return;
16367
+ const info = parseDateProp(dateProp);
16368
+ if (!info.isUndated) {
16369
+ const nodeInfo = {
16370
+ mesh,
16371
+ type: info.type,
16372
+ startDate: info.startDate,
16373
+ endDate: info.endDate,
16374
+ label: info.label
16375
+ };
16376
+ allTimePoints.add(info.startDate.getTime());
16377
+ if (info.endDate) allTimePoints.add(info.endDate.getTime());
16378
+ timelineNodes.push(nodeInfo);
16287
16379
  }
16288
16380
  });
16289
16381
  if (timelineNodes.length === 0) return;
16290
16382
  const sortedTimePoints = Array.from(allTimePoints).sort((a, b) => a - b);
16383
+ const maxTimeIndex = sortedTimePoints.length - 1;
16291
16384
  const timeToYMap = new Map(
16292
16385
  sortedTimePoints.map((time, index) => [
16293
16386
  time,
16294
- index * TIMELINE_LAYER_SPACING_Y
16387
+ (index - maxTimeIndex) * TIMELINE_LAYER_SPACING_Y
16295
16388
  ])
16296
16389
  );
16297
16390
  timelineNodes.sort(
@@ -16299,18 +16392,38 @@ function XViewScene({
16299
16392
  );
16300
16393
  const baseX = sourceMesh.position.x + TIMELINE_NODE_SPACING_X;
16301
16394
  const baseY = sourceMesh.position.y;
16302
- const maxNodeIndex = timelineNodes.length - 1;
16303
- timelineNodes.forEach((node, index) => {
16395
+ const columns = [];
16396
+ const allFinalPoints = [sourceMesh.position.clone()];
16397
+ timelineNodes.forEach((node) => {
16304
16398
  const { mesh, type, startDate, endDate, label } = node;
16305
- const y = baseY + (index - maxNodeIndex) * TIMELINE_LAYER_SPACING_Y;
16306
- const versionTween = new import_tween2.Tween(mesh.position).to({ x: baseX, y, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
16399
+ const startY = timeToYMap.get(startDate.getTime());
16400
+ const endY = timeToYMap.get(endDate.getTime()) || startY;
16401
+ let foundColumn = false;
16402
+ for (let i = 0; i < columns.length; i++) {
16403
+ if (columns[i].endY < startY) {
16404
+ node.columnIndex = i;
16405
+ columns[i].endY = endY;
16406
+ foundColumn = true;
16407
+ break;
16408
+ }
16409
+ }
16410
+ if (!foundColumn) {
16411
+ node.columnIndex = columns.length;
16412
+ columns.push({ endY });
16413
+ }
16414
+ const x = baseX + node.columnIndex * TIMELINE_NODE_SPACING_X;
16415
+ const y = baseY + startY;
16416
+ allFinalPoints.push(new THREE3.Vector3(x, y, 0));
16417
+ const versionTween = new import_tween2.Tween(mesh.position).to({ x, y, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
16307
16418
  tweenGroup.add(versionTween);
16308
16419
  versionTween.start();
16309
- const startLabelText = type === "interval" ? startDate.getFullYear().toString() : label;
16310
- const startLabel = createTextSprite(startLabelText, 48);
16311
- startLabel.name = "timelineLabel";
16312
- startLabel.position.set(0, -2.5, 0);
16313
- mesh.add(startLabel);
16420
+ if (!mesh.getObjectByName("questDateLabel")) {
16421
+ const startLabelText = type === "interval" ? startDate.getFullYear().toString() : label;
16422
+ const startLabel = createTextSprite(startLabelText, 48);
16423
+ startLabel.name = "timelineLabel";
16424
+ startLabel.position.set(0, -2.5, 0);
16425
+ mesh.add(startLabel);
16426
+ }
16314
16427
  if (type === "interval") {
16315
16428
  const relativeEndY = timeToYMap.get(endDate.getTime()) - timeToYMap.get(startDate.getTime());
16316
16429
  if (relativeEndY > 0) {
@@ -16344,7 +16457,21 @@ function XViewScene({
16344
16457
  }
16345
16458
  }
16346
16459
  });
16347
- }, []);
16460
+ if (allFinalPoints.length > 0) {
16461
+ const boundingBox = new THREE3.Box3().setFromPoints(allFinalPoints);
16462
+ const center = new THREE3.Vector3();
16463
+ boundingBox.getCenter(center);
16464
+ const size = new THREE3.Vector3();
16465
+ boundingBox.getSize(size);
16466
+ const spread = Math.max(size.x, size.y, size.z, 1);
16467
+ const desiredDistance = Math.max(
16468
+ x_view_config.CAMERA_ZOOM_DISTANCE,
16469
+ spread * 1.5
16470
+ );
16471
+ const zoomFactor = x_view_config.CAMERA_ZOOM_DISTANCE / desiredDistance;
16472
+ tweenToTarget(center, zoomFactor);
16473
+ }
16474
+ }, [tweenToTarget]);
16348
16475
  (0, import_react33.useEffect)(() => {
16349
16476
  async function fetchAllData(configPath, ownerId2) {
16350
16477
  var _a2, _b2;
@@ -18009,12 +18136,13 @@ function XViewScene({
18009
18136
  get_scene_view_data,
18010
18137
  upload_file: upload_file_action,
18011
18138
  delete_file: delete_file_action,
18012
- save_quest_action,
18013
- delete_quest_action,
18014
- save_quest_link_action,
18015
- delete_quest_link_action,
18016
- save_milestone_action,
18017
- delete_milestone_action
18139
+ // Adicionado novas importações aqui
18140
+ upsert_quest_firestore,
18141
+ delete_quest_firestore,
18142
+ upsert_quest_link_firestore,
18143
+ delete_quest_link_firestore,
18144
+ upsert_milestone_firestore,
18145
+ update_view_counter
18018
18146
  }
18019
18147
  };
18020
18148
  },
@@ -18034,12 +18162,12 @@ function XViewScene({
18034
18162
  get_scene_view_data,
18035
18163
  upload_file_action,
18036
18164
  delete_file_action,
18037
- save_quest_action,
18038
- delete_quest_action,
18039
- save_quest_link_action,
18040
- delete_quest_link_action,
18041
- save_milestone_action,
18042
- delete_milestone_action
18165
+ upsert_quest_firestore,
18166
+ delete_quest_firestore,
18167
+ upsert_quest_link_firestore,
18168
+ delete_quest_link_firestore,
18169
+ upsert_milestone_firestore,
18170
+ update_view_counter
18043
18171
  ]
18044
18172
  );
18045
18173
  const handleStartVersioning = (nodeData) => {
@@ -18245,45 +18373,30 @@ function XViewScene({
18245
18373
  parentDataRef.current[sceneConfigId].nodes[parentIndex].quest_abstraction_tree = formattedAbstractionTree;
18246
18374
  }
18247
18375
  }
18248
- if (save_quest_action) {
18249
- const updatedNodeData2 = sceneData.quest_nodes[questIndex];
18250
- await save_quest_action(ownerId, sceneConfigId, updatedNodeData2, sceneData.quest_counter || 1);
18251
- } else {
18252
- const sceneFileData = {
18253
- ...sceneData,
18254
- nodes: sceneData.nodes || [],
18255
- links: sceneData.links || [],
18256
- quest_counter: sceneData.quest_counter || 1
18257
- };
18258
- const questFileData = {
18259
- nodes: sceneData.quest_nodes || [],
18260
- links: sceneData.quest_links || [],
18261
- milestones: sceneData.milestones || []
18262
- };
18263
- await save_view_data(sceneSaveUrl, sceneFileData);
18264
- const questSaveUrl = sceneSaveUrl.replace(
18265
- "x_view_scenes",
18266
- "x_view_quests"
18376
+ const updatedNodeData = sceneData.quest_nodes[questIndex];
18377
+ if (upsert_quest_firestore) {
18378
+ await upsert_quest_firestore(
18379
+ ownerId,
18380
+ sceneConfigId,
18381
+ updatedNodeData
18267
18382
  );
18268
- await save_view_data(questSaveUrl, questFileData);
18269
18383
  }
18384
+ const nodeMesh = (_a2 = stateRef.current.nodeObjects) == null ? void 0 : _a2[String(questNodeId)];
18385
+ if (nodeMesh) {
18386
+ nodeMesh.userData = {
18387
+ ...nodeMesh.userData,
18388
+ ...updatedNodeData
18389
+ };
18390
+ }
18391
+ if (detailsNode && String(detailsNode.id) === String(questNodeId)) {
18392
+ setDetailsNode((prev) => ({
18393
+ ...prev,
18394
+ quest_tree: formattedTree,
18395
+ quest_abstraction_tree: formattedAbstractionTree
18396
+ }));
18397
+ }
18398
+ setSceneVersion((v) => v + 1);
18270
18399
  }
18271
- const updatedNodeData = sceneData.quest_nodes[questIndex];
18272
- const nodeMesh = (_a2 = stateRef.current.nodeObjects) == null ? void 0 : _a2[String(questNodeId)];
18273
- if (nodeMesh) {
18274
- nodeMesh.userData = {
18275
- ...nodeMesh.userData,
18276
- ...updatedNodeData
18277
- };
18278
- }
18279
- if (detailsNode && String(detailsNode.id) === String(questNodeId)) {
18280
- setDetailsNode((prev) => ({
18281
- ...prev,
18282
- quest_tree: formattedTree,
18283
- quest_abstraction_tree: formattedAbstractionTree
18284
- }));
18285
- }
18286
- setSceneVersion((v) => v + 1);
18287
18400
  }
18288
18401
  }
18289
18402
  };
@@ -18332,7 +18445,6 @@ function XViewScene({
18332
18445
  ownerId: ownerId2
18333
18446
  } = context;
18334
18447
  if (!graphDataRef2.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
18335
- const currentCounter = sceneDataRef2.current.quest_counter || 1;
18336
18448
  const newNode = {
18337
18449
  id: import_short_uuid2.default.generate(),
18338
18450
  ...newQuestData,
@@ -18343,25 +18455,16 @@ function XViewScene({
18343
18455
  graphDataRef2.current[sceneConfigId2] = { nodes: [], links: [] };
18344
18456
  }
18345
18457
  graphDataRef2.current[sceneConfigId2].nodes.push(newNode);
18346
- const sceneFileData = {
18347
- ...sceneDataRef2.current,
18348
- quest_counter: currentCounter + 1
18349
- };
18458
+ const currentCounter = sceneDataRef2.current.quest_counter || 1;
18459
+ const nextCounter = currentCounter + 1;
18350
18460
  try {
18351
- if (actions.save_quest_action) {
18352
- await actions.save_quest_action(ownerId2, sceneConfigId2, newNode, currentCounter + 1);
18353
- await actions.save_view_data(sceneSaveUrl2, sceneFileData);
18354
- } else {
18355
- const questFileData = {
18356
- nodes: graphDataRef2.current[sceneConfigId2].nodes,
18357
- links: graphDataRef2.current[sceneConfigId2].links,
18358
- milestones: sceneDataRef2.current.milestones || []
18359
- };
18360
- await actions.save_view_data(sceneSaveUrl2, sceneFileData);
18361
- const questSaveUrl = sceneSaveUrl2.replace("x_view_scenes", "x_view_quests");
18362
- await actions.save_view_data(questSaveUrl, questFileData);
18461
+ if (actions.upsert_quest_firestore) {
18462
+ await actions.upsert_quest_firestore(ownerId2, sceneConfigId2, newNode);
18463
+ }
18464
+ if (actions.update_view_counter) {
18465
+ await actions.update_view_counter(ownerId2, sceneConfigId2, nextCounter);
18363
18466
  }
18364
- sceneDataRef2.current.quest_counter = currentCounter + 1;
18467
+ sceneDataRef2.current.quest_counter = nextCounter;
18365
18468
  stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
18366
18469
  parentFileId: sceneConfigId2,
18367
18470
  ownerId: ownerId2,
@@ -18392,88 +18495,6 @@ function XViewScene({
18392
18495
  alert("Ocorreu um erro ao criar a Quest.");
18393
18496
  }
18394
18497
  };
18395
- userActionHandlers.handleCompleteConnection = async (context, targetNodeData) => {
18396
- const {
18397
- stateRef: stateRef2,
18398
- graphDataRef: graphDataRef2,
18399
- sceneDataRef: sceneDataRef2,
18400
- sceneConfigId: sceneConfigId2,
18401
- sceneSaveUrl: sceneSaveUrl2,
18402
- ownerId: ownerId2
18403
- } = context;
18404
- const { sourceNodeData } = stateRef2.current.connection;
18405
- if (!graphDataRef2.current || !sceneDataRef2.current || !sourceNodeData || !targetNodeData) {
18406
- userActionHandlers.handleCancelConnection(context);
18407
- return;
18408
- }
18409
- const sourceParentInfo = getParentFileInfoForNode(
18410
- graphDataRef2.current,
18411
- sceneDataRef2.current,
18412
- sourceNodeData.id,
18413
- sceneConfigId2,
18414
- ownerId2
18415
- );
18416
- const targetParentInfo = getParentFileInfoForNode(
18417
- graphDataRef2.current,
18418
- sceneDataRef2.current,
18419
- targetNodeData.id,
18420
- sceneConfigId2,
18421
- ownerId2
18422
- );
18423
- let parentInfoToSave = sourceParentInfo;
18424
- const isSourceQuest = sourceParentInfo.parentFileId === sceneConfigId2;
18425
- const isTargetQuest = targetParentInfo.parentFileId === sceneConfigId2;
18426
- if (isSourceQuest || isTargetQuest) {
18427
- parentInfoToSave = { parentFileId: sceneConfigId2, ownerId: ownerId2 };
18428
- }
18429
- const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
18430
- const newLink = {
18431
- id: `link_${import_short_uuid2.default.generate()}`,
18432
- source: sourceNodeData.id,
18433
- target: targetNodeData.id
18434
- };
18435
- try {
18436
- if (parentFileIdToSave === sceneConfigId2) {
18437
- const specificParentData = graphDataRef2.current[sceneConfigId2];
18438
- specificParentData.links.push(newLink);
18439
- if (context.actions.save_quest_link_action && (isSourceQuest || isTargetQuest)) {
18440
- await context.actions.save_quest_link_action(ownerId2, sceneConfigId2, newLink);
18441
- } else {
18442
- const viewFilePayload = {
18443
- ...sceneDataRef2.current,
18444
- quest_counter: sceneDataRef2.current.quest_counter || 1
18445
- };
18446
- const questFilePayload = {
18447
- nodes: specificParentData.nodes,
18448
- links: specificParentData.links,
18449
- milestones: sceneDataRef2.current.milestones || []
18450
- };
18451
- await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
18452
- const questSaveUrl = sceneSaveUrl2.replace(
18453
- "x_view_scenes",
18454
- "x_view_quests"
18455
- );
18456
- await context.actions.save_view_data(questSaveUrl, questFilePayload);
18457
- }
18458
- } else {
18459
- const specificParentData = JSON.parse(
18460
- JSON.stringify(graphDataRef2.current[parentFileIdToSave])
18461
- );
18462
- specificParentData.links.push(newLink);
18463
- const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
18464
- await context.actions.save_view_data(
18465
- filenameForSpecificParent,
18466
- specificParentData
18467
- );
18468
- graphDataRef2.current[parentFileIdToSave] = specificParentData;
18469
- }
18470
- addNewLinkToScene(stateRef2.current, newLink);
18471
- } catch (error) {
18472
- console.error("Falha ao salvar a nova conex\xE3o:", error);
18473
- alert("Ocorreu um erro ao salvar a nova conex\xE3o.");
18474
- }
18475
- userActionHandlers.handleCancelConnection(context);
18476
- };
18477
18498
  const handleClearAncestryVisuals = (0, import_react33.useCallback)((ancestryId) => {
18478
18499
  const { renderedAncestries, ancestryGroup } = stateRef.current;
18479
18500
  const renderIndex = renderedAncestries.findIndex(
@@ -18487,7 +18508,9 @@ function XViewScene({
18487
18508
  if (line.material) line.material.dispose();
18488
18509
  });
18489
18510
  renderedAncestries.splice(renderIndex, 1);
18490
- stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
18511
+ stateRef.current.ancestryLinks = renderedAncestries.flatMap(
18512
+ (a) => a.lines
18513
+ );
18491
18514
  }
18492
18515
  }, []);
18493
18516
  const handleRenderAncestry = (0, import_react33.useCallback)(
@@ -19060,7 +19083,9 @@ function XViewScene({
19060
19083
  });
19061
19084
  };
19062
19085
  renderVertical(fullTree, rootNodeMesh, rootTargetPos, 1);
19063
- stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
19086
+ stateRef.current.ancestryLinks = renderedAncestries.flatMap(
19087
+ (a) => a.lines
19088
+ );
19064
19089
  tweenToTarget(rootTargetPos, 0.7);
19065
19090
  },
19066
19091
  [
@@ -19195,7 +19220,10 @@ function XViewScene({
19195
19220
  };
19196
19221
  const descriptionText = targetAncestryInfo.description || "";
19197
19222
  const savedSections = targetAncestryInfo.description_sections || [];
19198
- const sections = parseDescriptionSections(descriptionText, savedSections);
19223
+ const sections = parseDescriptionSections(
19224
+ descriptionText,
19225
+ savedSections
19226
+ );
19199
19227
  let focusTargetId = null;
19200
19228
  if (popped && popped.nodeId) {
19201
19229
  const mentionTag = `[[MENTION:node:${popped.nodeId}]]`;
@@ -19972,7 +20000,10 @@ function XViewScene({
19972
20000
  }
19973
20001
  if (ancestry_save_url && isExternalSave && get_ancestry_file) {
19974
20002
  try {
19975
- const viewDbResponse = await get_ancestry_file(sceneConfigId, ownerId);
20003
+ const viewDbResponse = await get_ancestry_file(
20004
+ sceneConfigId,
20005
+ ownerId
20006
+ );
19976
20007
  if (viewDbResponse.success && Array.isArray(viewDbResponse.data)) {
19977
20008
  const hasInViewDb = viewDbResponse.data.some(
19978
20009
  (anc) => String(anc.ancestry_id) === String(ancestryIdToDelete)
@@ -20162,61 +20193,31 @@ function XViewScene({
20162
20193
  async (newMilestones) => {
20163
20194
  var _a2, _b2, _c2;
20164
20195
  if (!sceneDataRef.current) return;
20165
- const oldMilestones = sceneDataRef.current.milestones || [];
20166
- const removedMilestones = oldMilestones.filter(
20167
- (oldM) => !newMilestones.some((newM) => String(newM.id) === String(oldM.id))
20168
- );
20169
- const addedOrUpdatedMilestones = newMilestones.filter(
20170
- (newM) => !oldMilestones.some((oldM) => JSON.stringify(oldM) === JSON.stringify(newM))
20171
- );
20172
20196
  sceneDataRef.current.milestones = newMilestones;
20173
20197
  setSceneVersion((v) => v + 1);
20174
20198
  const isView = ((_a2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _a2.toLowerCase()) === "view";
20175
20199
  if (!isView || !save_view_data || !sceneSaveUrl) return;
20200
+ const questFileData = {
20201
+ nodes: ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || sceneDataRef.current.quest_nodes || [],
20202
+ links: ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || sceneDataRef.current.quest_links || [],
20203
+ milestones: newMilestones
20204
+ };
20176
20205
  try {
20177
- if (save_milestone_action) {
20178
- const promises = [];
20179
- if (delete_milestone_action) {
20180
- removedMilestones.forEach((m) => promises.push(delete_milestone_action(ownerId, sceneConfigId, m.id)));
20181
- }
20182
- if (addedOrUpdatedMilestones.length > 0) {
20183
- addedOrUpdatedMilestones.forEach((m) => promises.push(save_milestone_action(ownerId, sceneConfigId, m)));
20184
- }
20185
- await Promise.all(promises);
20186
- const sceneFileData = {
20187
- ...sceneDataRef.current,
20188
- nodes: sceneDataRef.current.nodes || [],
20189
- links: sceneDataRef.current.links || [],
20190
- quest_counter: sceneDataRef.current.quest_counter || 1
20191
- };
20192
- await save_view_data(sceneSaveUrl, sceneFileData);
20193
- } else {
20194
- const sceneFileData = {
20195
- ...sceneDataRef.current,
20196
- nodes: sceneDataRef.current.nodes || [],
20197
- links: sceneDataRef.current.links || [],
20198
- quest_counter: sceneDataRef.current.quest_counter || 1
20199
- };
20200
- const questFileData = {
20201
- nodes: ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || sceneDataRef.current.quest_nodes || [],
20202
- links: ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || sceneDataRef.current.quest_links || [],
20203
- milestones: newMilestones
20204
- };
20205
- await save_view_data(sceneSaveUrl, sceneFileData);
20206
- const questSaveUrl = sceneSaveUrl.replace(
20207
- "x_view_scenes",
20208
- "x_view_quests"
20206
+ if (upsert_milestone_firestore) {
20207
+ await upsert_milestone_firestore(
20208
+ ownerId,
20209
+ sceneConfigId,
20210
+ newMilestones
20209
20211
  );
20210
- await save_view_data(questSaveUrl, questFileData);
20211
20212
  }
20212
20213
  } catch (error) {
20213
20214
  console.error("Erro ao salvar milestones:", error);
20214
20215
  }
20215
20216
  },
20216
- [sceneConfigId, sceneSaveUrl, save_view_data, save_milestone_action, delete_milestone_action, viewParams == null ? void 0 : viewParams.type]
20217
+ [sceneConfigId, sceneSaveUrl, save_view_data, viewParams == null ? void 0 : viewParams.type]
20217
20218
  );
20218
20219
  const handleSaveCurrentView = (0, import_react33.useCallback)(async () => {
20219
- var _a2, _b2, _c2;
20220
+ var _a2;
20220
20221
  const { nodeObjects, allLinks } = stateRef.current;
20221
20222
  if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
20222
20223
  console.warn(
@@ -20246,23 +20247,10 @@ function XViewScene({
20246
20247
  const sceneFileData = {
20247
20248
  ...sceneDataRef.current,
20248
20249
  nodes: currentNodes,
20249
- links: currentLinks,
20250
- quest_counter: sceneDataRef.current.quest_counter || 1
20251
- };
20252
- const questFileData = {
20253
- nodes: isView ? ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || [] : sceneDataRef.current.quest_nodes || [],
20254
- links: isView ? ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || [] : sceneDataRef.current.quest_links || [],
20255
- milestones: sceneDataRef.current.milestones || []
20250
+ links: currentLinks
20256
20251
  };
20257
20252
  try {
20258
20253
  await save_view_data(sceneSaveUrl, sceneFileData);
20259
- if (isView) {
20260
- const questSaveUrl = sceneSaveUrl.replace(
20261
- "x_view_scenes",
20262
- "x_view_quests"
20263
- );
20264
- await save_view_data(questSaveUrl, questFileData);
20265
- }
20266
20254
  } catch (error) {
20267
20255
  console.error("Erro na chamada de save_view_data:", error);
20268
20256
  }
@@ -20961,12 +20949,18 @@ function XViewScene({
20961
20949
  data: multiContextMenu,
20962
20950
  userRole: userPermissionRole,
20963
20951
  onClose: () => setMultiContextMenu((prev) => ({ ...prev, visible: false })),
20964
- onDismissNodes: (ids) => userActionHandlers.handleDismissMultipleNodes(actionHandlerContext, ids),
20952
+ onDismissNodes: (ids) => userActionHandlers.handleDismissMultipleNodes(
20953
+ actionHandlerContext,
20954
+ ids
20955
+ ),
20965
20956
  onDismissOtherNodes: (ids) => userActionHandlers.handleDismissOtherMultipleNodes(
20966
20957
  actionHandlerContext,
20967
20958
  ids
20968
20959
  ),
20969
- onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
20960
+ onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(
20961
+ actionHandlerContext,
20962
+ ids
20963
+ )
20970
20964
  }
20971
20965
  ),
20972
20966
  /* @__PURE__ */ import_react33.default.createElement(
@@ -21119,25 +21113,40 @@ async function save_view_data_logic(db_services, filename, data) {
21119
21113
  }
21120
21114
  }
21121
21115
  async function get_scene_view_data_logic(db_services, scene_config, owner_id, type, session, focusNodeId = null, focusAncestryId = null) {
21122
- var _a, _b;
21116
+ var _a, _b, _c;
21123
21117
  try {
21124
21118
  if (!session || !session.user) {
21125
21119
  return { success: false, error: "Usu\xE1rio n\xE3o autenticado." };
21126
21120
  }
21127
- const membershipCheck = await db_services.check_membership(owner_id, type, scene_config, session.user.id);
21121
+ const membershipCheck = await db_services.check_membership(
21122
+ owner_id,
21123
+ type,
21124
+ scene_config,
21125
+ session.user.id
21126
+ );
21128
21127
  const isFullMember = membershipCheck.success && membershipCheck.isValidMember;
21129
21128
  if (!isFullMember && !focusNodeId && !focusAncestryId) {
21130
- return { success: false, error: "Acesso Negado: Voc\xEA n\xE3o possui permiss\xE3o para acessar este cen\xE1rio." };
21129
+ return {
21130
+ success: false,
21131
+ error: "Acesso Negado: Voc\xEA n\xE3o possui permiss\xE3o para acessar este cen\xE1rio."
21132
+ };
21131
21133
  }
21132
- const sceneResponse = await db_services.get_file(`x_view_scenes/${owner_id}/${scene_config}`);
21134
+ const sceneResponse = await db_services.get_file(
21135
+ `x_view_scenes/${owner_id}/${scene_config}`
21136
+ );
21133
21137
  if (!sceneResponse || !sceneResponse.success) {
21134
21138
  console.error("Falha ao buscar dados da cena:", sceneResponse == null ? void 0 : sceneResponse.error);
21135
- return { success: false, error: `N\xE3o foi poss\xEDvel carregar o arquivo da cena: ${scene_config}` };
21139
+ return {
21140
+ success: false,
21141
+ error: `N\xE3o foi poss\xEDvel carregar o arquivo da cena: ${scene_config}`
21142
+ };
21136
21143
  }
21137
21144
  const sceneData = sceneResponse.data;
21138
21145
  const parentDbObjects = sceneData.parent_dbs || [];
21139
21146
  if (type && type.toLowerCase().includes("database")) {
21140
- const selfExists = parentDbObjects.some((db) => String(db.db_id) === String(scene_config));
21147
+ const selfExists = parentDbObjects.some(
21148
+ (db) => String(db.db_id) === String(scene_config)
21149
+ );
21141
21150
  if (!selfExists) {
21142
21151
  parentDbObjects.push({ db_id: scene_config, owner_id });
21143
21152
  }
@@ -21146,34 +21155,67 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21146
21155
  const parentResponsesPromises = parentDbObjects.map(
21147
21156
  (db_info) => db_services.get_file(`x_view_dbs/${db_info.owner_id}/${db_info.db_id}`)
21148
21157
  );
21149
- const parentResponsesResults = await Promise.allSettled(parentResponsesPromises);
21158
+ if (isView) {
21159
+ const questFetchWithMigrationPromise = (async () => {
21160
+ try {
21161
+ const questsResponse = await db_services.get_view_quests_firestore(
21162
+ owner_id,
21163
+ scene_config
21164
+ );
21165
+ if (questsResponse.success && questsResponse.hasQuests) {
21166
+ return {
21167
+ success: true,
21168
+ data: questsResponse.data,
21169
+ quest_counter: questsResponse.quest_counter
21170
+ };
21171
+ } else {
21172
+ const legacyResponse = await db_services.get_file(
21173
+ `x_view_quests/${owner_id}/${scene_config}`
21174
+ );
21175
+ if (legacyResponse.success && legacyResponse.data) {
21176
+ await db_services.migrate_json_to_firestore(
21177
+ owner_id,
21178
+ scene_config,
21179
+ legacyResponse.data,
21180
+ sceneData.quest_counter
21181
+ );
21182
+ legacyResponse.quest_counter = sceneData.quest_counter || 1;
21183
+ return legacyResponse;
21184
+ }
21185
+ return legacyResponse;
21186
+ }
21187
+ } catch (err) {
21188
+ return { success: false, error: err.message };
21189
+ }
21190
+ })();
21191
+ parentResponsesPromises.push(questFetchWithMigrationPromise);
21192
+ }
21193
+ const parentResponsesResults = await Promise.allSettled(
21194
+ parentResponsesPromises
21195
+ );
21150
21196
  const parentData = {};
21151
21197
  let questDataObj = null;
21152
21198
  for (let i = 0; i < parentResponsesResults.length; i++) {
21153
21199
  const result = parentResponsesResults[i];
21200
+ if (isView && i === parentResponsesResults.length - 1) {
21201
+ if (result.status === "fulfilled" && ((_a = result.value) == null ? void 0 : _a.success)) {
21202
+ questDataObj = result.value.data;
21203
+ if (result.value.quest_counter !== void 0) {
21204
+ sceneData.quest_counter = result.value.quest_counter;
21205
+ }
21206
+ }
21207
+ continue;
21208
+ }
21154
21209
  const db_info = parentDbObjects[i];
21155
- if (result.status === "fulfilled" && ((_a = result.value) == null ? void 0 : _a.success)) {
21210
+ if (result.status === "fulfilled" && ((_b = result.value) == null ? void 0 : _b.success)) {
21156
21211
  parentData[db_info.db_id] = result.value.data;
21157
21212
  } else {
21158
21213
  console.warn(
21159
21214
  `Arquivo pai n\xE3o carregado: ${db_info.db_id}. Pode ter sido deletado.`,
21160
- result.status === "rejected" ? result.reason : (_b = result.value) == null ? void 0 : _b.error
21215
+ result.status === "rejected" ? result.reason : (_c = result.value) == null ? void 0 : _c.error
21161
21216
  );
21162
21217
  }
21163
21218
  }
21164
- if (isView) {
21165
- if (db_services.get_x_view_quests_data) {
21166
- const questDataRes = await db_services.get_x_view_quests_data(session, owner_id, scene_config);
21167
- if (questDataRes && questDataRes.success) {
21168
- questDataObj = questDataRes.data;
21169
- }
21170
- } else {
21171
- const questDataRes = await db_services.get_file(`x_view_quests/${owner_id}/${scene_config}`);
21172
- if (questDataRes && questDataRes.success) {
21173
- questDataObj = questDataRes.data;
21174
- }
21175
- }
21176
- }
21177
21219
  const currentQuestNodes = (questDataObj == null ? void 0 : questDataObj.nodes) || [];
21178
21220
  const currentQuestLinks = (questDataObj == null ? void 0 : questDataObj.links) || [];
21179
21221
  const currentMilestones = (questDataObj == null ? void 0 : questDataObj.milestones) || [];
@@ -21186,13 +21228,19 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21186
21228
  }
21187
21229
  const allNodes = Object.values(parentData).flatMap((db) => db.nodes || []);
21188
21230
  const allLinks = Object.values(parentData).flatMap((db) => db.links || []);
21189
- const parentNodeMap = new Map(allNodes.map((node) => [String(node.id), node]));
21190
- const parentLinkMap = new Map(allLinks.map((link) => [`${link.source}-${link.target}`, link]));
21231
+ const parentNodeMap = new Map(
21232
+ allNodes.map((node) => [String(node.id), node])
21233
+ );
21234
+ const parentLinkMap = new Map(
21235
+ allLinks.map((link) => [`${link.source}-${link.target}`, link])
21236
+ );
21191
21237
  const validatedNodes = (sceneData.nodes || []).map((sceneNode) => {
21192
21238
  var _a2, _b2;
21193
21239
  const nodeTypes = Array.isArray(sceneNode.type) ? sceneNode.type : [sceneNode.type];
21194
21240
  if (nodeTypes.includes("quest")) {
21195
- const dbQuestNode = (_b2 = (_a2 = parentData[scene_config]) == null ? void 0 : _a2.nodes) == null ? void 0 : _b2.find((qn) => String(qn.id) === String(sceneNode.id));
21241
+ const dbQuestNode = (_b2 = (_a2 = parentData[scene_config]) == null ? void 0 : _a2.nodes) == null ? void 0 : _b2.find(
21242
+ (qn) => String(qn.id) === String(sceneNode.id)
21243
+ );
21196
21244
  if (dbQuestNode) {
21197
21245
  return { ...sceneNode, ...dbQuestNode };
21198
21246
  }
@@ -21204,18 +21252,22 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21204
21252
  }
21205
21253
  return null;
21206
21254
  }).filter(Boolean);
21207
- const validNodeIdsInScene = new Set(validatedNodes.map((node) => String(node.id)));
21255
+ const validNodeIdsInScene = new Set(
21256
+ validatedNodes.map((node) => String(node.id))
21257
+ );
21208
21258
  const validatedLinks = (sceneData.links || []).filter((sceneLink) => {
21209
- const linkExistsInParent = parentLinkMap.has(`${sceneLink.source}-${sceneLink.target}`);
21259
+ const linkExistsInParent = parentLinkMap.has(
21260
+ `${sceneLink.source}-${sceneLink.target}`
21261
+ );
21210
21262
  const nodesAreValidForScene = validNodeIdsInScene.has(String(sceneLink.source)) && validNodeIdsInScene.has(String(sceneLink.target));
21211
21263
  return linkExistsInParent && nodesAreValidForScene;
21212
- }).map((sceneLink) => parentLinkMap.get(`${sceneLink.source}-${sceneLink.target}`));
21264
+ }).map(
21265
+ (sceneLink) => parentLinkMap.get(`${sceneLink.source}-${sceneLink.target}`)
21266
+ );
21213
21267
  const validatedSceneData = {
21214
21268
  ...sceneData,
21215
21269
  nodes: validatedNodes,
21216
21270
  links: validatedLinks,
21217
- // Re-injetando no validated para que o restante do sistema (e.g. XViewScene local state)
21218
- // continue acessando as quests sem perceber a separação física
21219
21271
  quest_nodes: currentQuestNodes,
21220
21272
  quest_links: currentQuestLinks,
21221
21273
  milestones: currentMilestones
@@ -21235,7 +21287,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21235
21287
  isSceneFile: false
21236
21288
  });
21237
21289
  });
21238
- const ancestryPromises = ancestryFilePaths.map((file) => db_services.get_file(file.path));
21290
+ const ancestryPromises = ancestryFilePaths.map(
21291
+ (file) => db_services.get_file(file.path)
21292
+ );
21239
21293
  const ancestryResults = await Promise.allSettled(ancestryPromises);
21240
21294
  const ancestriesFromSceneFile = [];
21241
21295
  const ancestriesFromDbFiles = [];
@@ -21261,15 +21315,21 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21261
21315
  }
21262
21316
  });
21263
21317
  const ancestryMap = /* @__PURE__ */ new Map();
21264
- ancestriesFromDbFiles.forEach((anc) => ancestryMap.set(anc.ancestry_id, anc));
21265
- ancestriesFromSceneFile.forEach((anc) => ancestryMap.set(anc.ancestry_id, anc));
21318
+ ancestriesFromDbFiles.forEach(
21319
+ (anc) => ancestryMap.set(anc.ancestry_id, anc)
21320
+ );
21321
+ ancestriesFromSceneFile.forEach(
21322
+ (anc) => ancestryMap.set(anc.ancestry_id, anc)
21323
+ );
21266
21324
  let ancestryData = Array.from(ancestryMap.values());
21267
21325
  const externalSourcesToRefresh = /* @__PURE__ */ new Map();
21268
21326
  ancestryData.forEach((anc) => {
21269
21327
  const targetSourceId = anc._source_file_id || anc._imported_from_view_id;
21270
21328
  const targetOwnerId = anc._source_owner_id || anc._imported_from_view_owner_id;
21271
21329
  if (targetSourceId && targetSourceId !== scene_config && targetOwnerId) {
21272
- const isAlreadyLoadedAsParent = parentDbObjects.some((db) => String(db.db_id) === String(targetSourceId));
21330
+ const isAlreadyLoadedAsParent = parentDbObjects.some(
21331
+ (db) => String(db.db_id) === String(targetSourceId)
21332
+ );
21273
21333
  if (!isAlreadyLoadedAsParent) {
21274
21334
  const key = `${targetOwnerId}/${targetSourceId}`;
21275
21335
  externalSourcesToRefresh.set(key, {
@@ -21310,12 +21370,16 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21310
21370
  return false;
21311
21371
  }
21312
21372
  if (externalSourcesToRefresh.has(key) && successfullyFetchedSources.has(key)) {
21313
- const stillExists = freshAncestryMap.has(String(localAnc.ancestry_id));
21373
+ const stillExists = freshAncestryMap.has(
21374
+ String(localAnc.ancestry_id)
21375
+ );
21314
21376
  return stillExists;
21315
21377
  }
21316
21378
  return true;
21317
21379
  }).map((localAnc) => {
21318
- const freshVersion = freshAncestryMap.get(String(localAnc.ancestry_id));
21380
+ const freshVersion = freshAncestryMap.get(
21381
+ String(localAnc.ancestry_id)
21382
+ );
21319
21383
  if (freshVersion) {
21320
21384
  return {
21321
21385
  ...freshVersion,
@@ -21354,7 +21418,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21354
21418
  parallel_branches: validBranches
21355
21419
  };
21356
21420
  };
21357
- const originalAncestryDataString = JSON.stringify(Array.from(ancestryMap.values()));
21421
+ const originalAncestryDataString = JSON.stringify(
21422
+ Array.from(ancestryMap.values())
21423
+ );
21358
21424
  const cleanedAncestryData = ancestryData.map((ancestry) => {
21359
21425
  if (!parentNodeIds.has(String(ancestry.ancestral_node))) return null;
21360
21426
  const cleanedTree = pruneTree(ancestry.tree);
@@ -21374,7 +21440,10 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21374
21440
  try {
21375
21441
  await db_services.save_file(ancestryFilePath, ancestryData);
21376
21442
  } catch (saveError) {
21377
- console.error("Falha ao salvar o arquivo de ancestralidade da cena atualizado:", saveError);
21443
+ console.error(
21444
+ "Falha ao salvar o arquivo de ancestralidade da cena atualizado:",
21445
+ saveError
21446
+ );
21378
21447
  }
21379
21448
  }
21380
21449
  if (!isFullMember) {
@@ -21382,7 +21451,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21382
21451
  const requiredAncestryIds = /* @__PURE__ */ new Set();
21383
21452
  if (focusNodeId) requiredNodeIds.add(String(focusNodeId));
21384
21453
  if (focusAncestryId) requiredAncestryIds.add(String(focusAncestryId));
21385
- const allNodesFromDb = Object.values(parentData).flatMap((db) => db.nodes || []);
21454
+ const allNodesFromDb = Object.values(parentData).flatMap(
21455
+ (db) => db.nodes || []
21456
+ );
21386
21457
  const extractDependenciesFromText = (text) => {
21387
21458
  if (!text) return;
21388
21459
  const mentionRegex = /\[\[MENTION:node:([a-zA-Z0-9\-_]+)\]\]/g;
@@ -21409,9 +21480,12 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21409
21480
  if (branch.linked_ancestry_id) {
21410
21481
  requiredAncestryIds.add(String(branch.linked_ancestry_id));
21411
21482
  }
21412
- if (branch.description) extractDependenciesFromText(branch.description);
21483
+ if (branch.description)
21484
+ extractDependenciesFromText(branch.description);
21413
21485
  if (branch.description_sections) {
21414
- branch.description_sections.forEach((s) => extractDependenciesFromText(s.content));
21486
+ branch.description_sections.forEach(
21487
+ (s) => extractDependenciesFromText(s.content)
21488
+ );
21415
21489
  }
21416
21490
  extractTreeDependencies(branch.tree);
21417
21491
  });
@@ -21425,7 +21499,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21425
21499
  if (anc && !anc.is_private) {
21426
21500
  if (anc.description) extractDependenciesFromText(anc.description);
21427
21501
  if (anc.description_sections) {
21428
- anc.description_sections.forEach((s) => extractDependenciesFromText(s.content));
21502
+ anc.description_sections.forEach(
21503
+ (s) => extractDependenciesFromText(s.content)
21504
+ );
21429
21505
  }
21430
21506
  extractTreeDependencies(anc.tree);
21431
21507
  extractTreeDependencies(anc.abstraction_tree);
@@ -21436,22 +21512,38 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21436
21512
  if (node) {
21437
21513
  if (node.description) extractDependenciesFromText(node.description);
21438
21514
  if (node.description_sections) {
21439
- node.description_sections.forEach((s) => extractDependenciesFromText(s.content));
21515
+ node.description_sections.forEach(
21516
+ (s) => extractDependenciesFromText(s.content)
21517
+ );
21440
21518
  }
21441
21519
  }
21442
21520
  });
21443
21521
  } while (requiredNodeIds.size + requiredAncestryIds.size > previousSize);
21444
- const restrictedSceneData = { ...validatedSceneData, nodes: [], links: [] };
21522
+ const restrictedSceneData = {
21523
+ ...validatedSceneData,
21524
+ nodes: [],
21525
+ links: []
21526
+ };
21445
21527
  const restrictedParentData = {};
21446
- const restrictedAncestryData = ancestryData.filter((a) => requiredAncestryIds.has(String(a.ancestry_id)) && !a.is_private);
21528
+ const restrictedAncestryData = ancestryData.filter(
21529
+ (a) => requiredAncestryIds.has(String(a.ancestry_id)) && !a.is_private
21530
+ );
21447
21531
  for (const [dbId, dbContent] of Object.entries(parentData)) {
21448
- const filteredNodes = (dbContent.nodes || []).filter((n) => requiredNodeIds.has(String(n.id)));
21532
+ const filteredNodes = (dbContent.nodes || []).filter(
21533
+ (n) => requiredNodeIds.has(String(n.id))
21534
+ );
21449
21535
  if (filteredNodes.length > 0) {
21450
- restrictedParentData[dbId] = { ...dbContent, nodes: filteredNodes, links: [] };
21536
+ restrictedParentData[dbId] = {
21537
+ ...dbContent,
21538
+ nodes: filteredNodes,
21539
+ links: []
21540
+ };
21451
21541
  }
21452
21542
  }
21453
21543
  if (focusNodeId) {
21454
- const mainNode = allNodesFromDb.find((n) => String(n.id) === String(focusNodeId));
21544
+ const mainNode = allNodesFromDb.find(
21545
+ (n) => String(n.id) === String(focusNodeId)
21546
+ );
21455
21547
  if (mainNode) {
21456
21548
  restrictedSceneData.nodes = [mainNode];
21457
21549
  }
@@ -21467,7 +21559,11 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21467
21559
  }
21468
21560
  return {
21469
21561
  success: true,
21470
- data: { scene: validatedSceneData, parent: parentData, ancestry: ancestryData }
21562
+ data: {
21563
+ scene: validatedSceneData,
21564
+ parent: parentData,
21565
+ ancestry: ancestryData
21566
+ }
21471
21567
  };
21472
21568
  } catch (error) {
21473
21569
  console.error("Erro em get_scene_view_data_logic:", error);
@@ -21487,13 +21583,18 @@ async function import_parent_file_modal_get_logic(db_services, session) {
21487
21583
  }
21488
21584
  };
21489
21585
  } catch (error) {
21490
- console.error("catch (error) em import_parent_file_modal_get_logic:", error);
21586
+ console.error(
21587
+ "catch (error) em import_parent_file_modal_get_logic:",
21588
+ error
21589
+ );
21491
21590
  return { success: false, error: error.message };
21492
21591
  }
21493
21592
  }
21494
21593
  async function get_single_parent_file_logic(db_services, file_id, session) {
21495
21594
  try {
21496
- const call_GCP_cloud_storage_get_file = await db_services.get_file(`x_view_dbs/${session.user.id}/${file_id}`);
21595
+ const call_GCP_cloud_storage_get_file = await db_services.get_file(
21596
+ `x_view_dbs/${session.user.id}/${file_id}`
21597
+ );
21497
21598
  return call_GCP_cloud_storage_get_file;
21498
21599
  } catch (error) {
21499
21600
  console.error("catch (error) em get_single_parent_file_logic:", error);
@@ -21527,7 +21628,13 @@ async function get_ancestry_file_logic(db_services, file_id, owner_id) {
21527
21628
  async function save_boards_logic(db_services, scene_id, type, boardItems, session, owner_id) {
21528
21629
  try {
21529
21630
  const targetOwnerId = owner_id || session.user.id;
21530
- return await db_services.save_boards(session, scene_id, type, boardItems, targetOwnerId);
21631
+ return await db_services.save_boards(
21632
+ session,
21633
+ scene_id,
21634
+ type,
21635
+ boardItems,
21636
+ targetOwnerId
21637
+ );
21531
21638
  } catch (error) {
21532
21639
  console.error("Erro em save_boards_logic:", error);
21533
21640
  return { success: false, error: error.message };
@@ -21556,7 +21663,10 @@ async function delete_uploaded_file_logic(db_services, fileUrl) {
21556
21663
  async function get_view_members_logic(db_services, ownerId, type, itemId) {
21557
21664
  try {
21558
21665
  if (!db_services.get_view_members) {
21559
- return { success: false, error: "Servi\xE7o de busca de membros n\xE3o configurado." };
21666
+ return {
21667
+ success: false,
21668
+ error: "Servi\xE7o de busca de membros n\xE3o configurado."
21669
+ };
21560
21670
  }
21561
21671
  return await db_services.get_view_members(ownerId, type, itemId);
21562
21672
  } catch (error) {