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

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 +577 -468
  2. package/dist/index.mjs +615 -506
  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(
@@ -2559,7 +2667,7 @@ function createNewCustomProperty(existingProps = []) {
2559
2667
  nextValue = [{ id: (0, import_uuid.v4)(), name: "1", value: "" }];
2560
2668
  break;
2561
2669
  case "date":
2562
- nextKey = "Date";
2670
+ nextKey = "Data";
2563
2671
  nextValue = { type: "Data", value: "" };
2564
2672
  break;
2565
2673
  case "number":
@@ -2813,7 +2921,7 @@ var IGNORED_KEYS = [
2813
2921
  ];
2814
2922
  function extractCustomPropsFromNode(node) {
2815
2923
  const customPropTypes = node._customPropTypes || {};
2816
- return Object.keys(node).filter((k) => !IGNORED_KEYS.includes(k)).map((key) => {
2924
+ return Object.keys(node).filter((k) => !IGNORED_KEYS.includes(k) || customPropTypes[k]).map((key) => {
2817
2925
  const val = node[key];
2818
2926
  const t = customPropTypes[key] || inferPropType(val);
2819
2927
  if (t === "date") {
@@ -5002,7 +5110,7 @@ function CustomPropertyDisplay({
5002
5110
  links: "Links",
5003
5111
  images: "Images",
5004
5112
  documents: "Documents",
5005
- date: "Date"
5113
+ date: "Data"
5006
5114
  };
5007
5115
  const oldKeyIsFixed = Object.values(fixedKeyMap).includes(tempProp.key);
5008
5116
  if (fixedKeyMap[value]) {
@@ -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
  {
@@ -12370,7 +12489,6 @@ function QuestDetailsPanel({
12370
12489
  setIsSaving(false);
12371
12490
  }
12372
12491
  };
12373
- const filteredCustomProps = customProps.filter((p) => p.key !== "Date" && p.key !== "Data");
12374
12492
  const handleAddTimelineNote = async () => {
12375
12493
  if (!noteText.trim() && noteLinks.length === 0 && noteImages.length === 0 || isSaving) return;
12376
12494
  setIsSaving(true);
@@ -15495,13 +15613,12 @@ function XViewScene({
15495
15613
  get_view_members,
15496
15614
  create_google_doc_action,
15497
15615
  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
15616
+ upsert_quest_firestore,
15617
+ delete_quest_firestore,
15618
+ upsert_quest_link_firestore,
15619
+ delete_quest_link_firestore,
15620
+ upsert_milestone_firestore,
15621
+ update_view_counter
15505
15622
  }) {
15506
15623
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
15507
15624
  const { data: session, status } = (0, import_react34.useSession)();
@@ -16061,11 +16178,19 @@ function XViewScene({
16061
16178
  }
16062
16179
  }
16063
16180
  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();
16181
+ const oldTimelineLabel = mesh.getObjectByName("timelineLabel");
16182
+ if (oldTimelineLabel) {
16183
+ mesh.remove(oldTimelineLabel);
16184
+ if (oldTimelineLabel.material.map)
16185
+ oldTimelineLabel.material.map.dispose();
16186
+ oldTimelineLabel.material.dispose();
16187
+ }
16188
+ const oldQuestDateLabel = mesh.getObjectByName("questDateLabel");
16189
+ if (oldQuestDateLabel) {
16190
+ mesh.remove(oldQuestDateLabel);
16191
+ if (oldQuestDateLabel.material.map)
16192
+ oldQuestDateLabel.material.map.dispose();
16193
+ oldQuestDateLabel.material.dispose();
16069
16194
  }
16070
16195
  delete mesh.userData.timelineIntervalBar;
16071
16196
  delete mesh.userData.timelineEndLabel;
@@ -16085,42 +16210,24 @@ function XViewScene({
16085
16210
  return null;
16086
16211
  };
16087
16212
  Object.values(nodeObjects).forEach((mesh) => {
16088
- const dateProp = mesh.userData.Date;
16213
+ var _a2;
16214
+ const dateProp = mesh.userData.Date || ((_a2 = (mesh.userData.properties || []).find(
16215
+ (p) => {
16216
+ var _a3;
16217
+ return ((_a3 = p.name) == null ? void 0 : _a3.toLowerCase()) === "data";
16218
+ }
16219
+ )) == null ? void 0 : _a2.value);
16089
16220
  let nodeInfo = { mesh, type: "point", label: "", isUndated: true };
16090
16221
  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
- }
16222
+ const info = parseDateProp(dateProp);
16223
+ if (!info.isUndated) {
16224
+ nodeInfo.startDate = info.startDate;
16225
+ nodeInfo.endDate = info.endDate;
16226
+ nodeInfo.label = info.label;
16227
+ nodeInfo.type = info.type;
16228
+ nodeInfo.isUndated = false;
16229
+ allTimePoints.add(info.startDate.getTime());
16230
+ if (info.endDate) allTimePoints.add(info.endDate.getTime());
16124
16231
  }
16125
16232
  }
16126
16233
  timelineNodes.push(nodeInfo);
@@ -16248,50 +16355,35 @@ function XViewScene({
16248
16355
  return null;
16249
16356
  };
16250
16357
  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);
16358
+ var _a2;
16359
+ const dateProp = mesh.userData.Date || ((_a2 = (mesh.userData.properties || []).find(
16360
+ (p) => {
16361
+ var _a3;
16362
+ return ((_a3 = p.name) == null ? void 0 : _a3.toLowerCase()) === "data";
16286
16363
  }
16364
+ )) == null ? void 0 : _a2.value);
16365
+ if (!dateProp) return;
16366
+ const info = parseDateProp(dateProp);
16367
+ if (!info.isUndated) {
16368
+ const nodeInfo = {
16369
+ mesh,
16370
+ type: info.type,
16371
+ startDate: info.startDate,
16372
+ endDate: info.endDate,
16373
+ label: info.label
16374
+ };
16375
+ allTimePoints.add(info.startDate.getTime());
16376
+ if (info.endDate) allTimePoints.add(info.endDate.getTime());
16377
+ timelineNodes.push(nodeInfo);
16287
16378
  }
16288
16379
  });
16289
16380
  if (timelineNodes.length === 0) return;
16290
16381
  const sortedTimePoints = Array.from(allTimePoints).sort((a, b) => a - b);
16382
+ const maxTimeIndex = sortedTimePoints.length - 1;
16291
16383
  const timeToYMap = new Map(
16292
16384
  sortedTimePoints.map((time, index) => [
16293
16385
  time,
16294
- index * TIMELINE_LAYER_SPACING_Y
16386
+ (index - maxTimeIndex) * TIMELINE_LAYER_SPACING_Y
16295
16387
  ])
16296
16388
  );
16297
16389
  timelineNodes.sort(
@@ -16299,18 +16391,38 @@ function XViewScene({
16299
16391
  );
16300
16392
  const baseX = sourceMesh.position.x + TIMELINE_NODE_SPACING_X;
16301
16393
  const baseY = sourceMesh.position.y;
16302
- const maxNodeIndex = timelineNodes.length - 1;
16303
- timelineNodes.forEach((node, index) => {
16394
+ const columns = [];
16395
+ const allFinalPoints = [sourceMesh.position.clone()];
16396
+ timelineNodes.forEach((node) => {
16304
16397
  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);
16398
+ const startY = timeToYMap.get(startDate.getTime());
16399
+ const endY = timeToYMap.get(endDate.getTime()) || startY;
16400
+ let foundColumn = false;
16401
+ for (let i = 0; i < columns.length; i++) {
16402
+ if (columns[i].endY < startY) {
16403
+ node.columnIndex = i;
16404
+ columns[i].endY = endY;
16405
+ foundColumn = true;
16406
+ break;
16407
+ }
16408
+ }
16409
+ if (!foundColumn) {
16410
+ node.columnIndex = columns.length;
16411
+ columns.push({ endY });
16412
+ }
16413
+ const x = baseX + node.columnIndex * TIMELINE_NODE_SPACING_X;
16414
+ const y = baseY + startY;
16415
+ allFinalPoints.push(new THREE3.Vector3(x, y, 0));
16416
+ const versionTween = new import_tween2.Tween(mesh.position).to({ x, y, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
16307
16417
  tweenGroup.add(versionTween);
16308
16418
  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);
16419
+ if (!mesh.getObjectByName("questDateLabel")) {
16420
+ const startLabelText = type === "interval" ? startDate.getFullYear().toString() : label;
16421
+ const startLabel = createTextSprite(startLabelText, 48);
16422
+ startLabel.name = "timelineLabel";
16423
+ startLabel.position.set(0, -2.5, 0);
16424
+ mesh.add(startLabel);
16425
+ }
16314
16426
  if (type === "interval") {
16315
16427
  const relativeEndY = timeToYMap.get(endDate.getTime()) - timeToYMap.get(startDate.getTime());
16316
16428
  if (relativeEndY > 0) {
@@ -16344,7 +16456,21 @@ function XViewScene({
16344
16456
  }
16345
16457
  }
16346
16458
  });
16347
- }, []);
16459
+ if (allFinalPoints.length > 0) {
16460
+ const boundingBox = new THREE3.Box3().setFromPoints(allFinalPoints);
16461
+ const center = new THREE3.Vector3();
16462
+ boundingBox.getCenter(center);
16463
+ const size = new THREE3.Vector3();
16464
+ boundingBox.getSize(size);
16465
+ const spread = Math.max(size.x, size.y, size.z, 1);
16466
+ const desiredDistance = Math.max(
16467
+ x_view_config.CAMERA_ZOOM_DISTANCE,
16468
+ spread * 1.5
16469
+ );
16470
+ const zoomFactor = x_view_config.CAMERA_ZOOM_DISTANCE / desiredDistance;
16471
+ tweenToTarget(center, zoomFactor);
16472
+ }
16473
+ }, [tweenToTarget]);
16348
16474
  (0, import_react33.useEffect)(() => {
16349
16475
  async function fetchAllData(configPath, ownerId2) {
16350
16476
  var _a2, _b2;
@@ -18009,12 +18135,13 @@ function XViewScene({
18009
18135
  get_scene_view_data,
18010
18136
  upload_file: upload_file_action,
18011
18137
  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
18138
+ // Adicionado novas importações aqui
18139
+ upsert_quest_firestore,
18140
+ delete_quest_firestore,
18141
+ upsert_quest_link_firestore,
18142
+ delete_quest_link_firestore,
18143
+ upsert_milestone_firestore,
18144
+ update_view_counter
18018
18145
  }
18019
18146
  };
18020
18147
  },
@@ -18034,12 +18161,12 @@ function XViewScene({
18034
18161
  get_scene_view_data,
18035
18162
  upload_file_action,
18036
18163
  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
18164
+ upsert_quest_firestore,
18165
+ delete_quest_firestore,
18166
+ upsert_quest_link_firestore,
18167
+ delete_quest_link_firestore,
18168
+ upsert_milestone_firestore,
18169
+ update_view_counter
18043
18170
  ]
18044
18171
  );
18045
18172
  const handleStartVersioning = (nodeData) => {
@@ -18245,45 +18372,30 @@ function XViewScene({
18245
18372
  parentDataRef.current[sceneConfigId].nodes[parentIndex].quest_abstraction_tree = formattedAbstractionTree;
18246
18373
  }
18247
18374
  }
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"
18375
+ const updatedNodeData = sceneData.quest_nodes[questIndex];
18376
+ if (upsert_quest_firestore) {
18377
+ await upsert_quest_firestore(
18378
+ ownerId,
18379
+ sceneConfigId,
18380
+ updatedNodeData
18267
18381
  );
18268
- await save_view_data(questSaveUrl, questFileData);
18269
18382
  }
18383
+ const nodeMesh = (_a2 = stateRef.current.nodeObjects) == null ? void 0 : _a2[String(questNodeId)];
18384
+ if (nodeMesh) {
18385
+ nodeMesh.userData = {
18386
+ ...nodeMesh.userData,
18387
+ ...updatedNodeData
18388
+ };
18389
+ }
18390
+ if (detailsNode && String(detailsNode.id) === String(questNodeId)) {
18391
+ setDetailsNode((prev) => ({
18392
+ ...prev,
18393
+ quest_tree: formattedTree,
18394
+ quest_abstraction_tree: formattedAbstractionTree
18395
+ }));
18396
+ }
18397
+ setSceneVersion((v) => v + 1);
18270
18398
  }
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
18399
  }
18288
18400
  }
18289
18401
  };
@@ -18332,7 +18444,6 @@ function XViewScene({
18332
18444
  ownerId: ownerId2
18333
18445
  } = context;
18334
18446
  if (!graphDataRef2.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
18335
- const currentCounter = sceneDataRef2.current.quest_counter || 1;
18336
18447
  const newNode = {
18337
18448
  id: import_short_uuid2.default.generate(),
18338
18449
  ...newQuestData,
@@ -18343,25 +18454,16 @@ function XViewScene({
18343
18454
  graphDataRef2.current[sceneConfigId2] = { nodes: [], links: [] };
18344
18455
  }
18345
18456
  graphDataRef2.current[sceneConfigId2].nodes.push(newNode);
18346
- const sceneFileData = {
18347
- ...sceneDataRef2.current,
18348
- quest_counter: currentCounter + 1
18349
- };
18457
+ const currentCounter = sceneDataRef2.current.quest_counter || 1;
18458
+ const nextCounter = currentCounter + 1;
18350
18459
  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);
18460
+ if (actions.upsert_quest_firestore) {
18461
+ await actions.upsert_quest_firestore(ownerId2, sceneConfigId2, newNode);
18462
+ }
18463
+ if (actions.update_view_counter) {
18464
+ await actions.update_view_counter(ownerId2, sceneConfigId2, nextCounter);
18363
18465
  }
18364
- sceneDataRef2.current.quest_counter = currentCounter + 1;
18466
+ sceneDataRef2.current.quest_counter = nextCounter;
18365
18467
  stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
18366
18468
  parentFileId: sceneConfigId2,
18367
18469
  ownerId: ownerId2,
@@ -18392,88 +18494,6 @@ function XViewScene({
18392
18494
  alert("Ocorreu um erro ao criar a Quest.");
18393
18495
  }
18394
18496
  };
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
18497
  const handleClearAncestryVisuals = (0, import_react33.useCallback)((ancestryId) => {
18478
18498
  const { renderedAncestries, ancestryGroup } = stateRef.current;
18479
18499
  const renderIndex = renderedAncestries.findIndex(
@@ -18487,7 +18507,9 @@ function XViewScene({
18487
18507
  if (line.material) line.material.dispose();
18488
18508
  });
18489
18509
  renderedAncestries.splice(renderIndex, 1);
18490
- stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
18510
+ stateRef.current.ancestryLinks = renderedAncestries.flatMap(
18511
+ (a) => a.lines
18512
+ );
18491
18513
  }
18492
18514
  }, []);
18493
18515
  const handleRenderAncestry = (0, import_react33.useCallback)(
@@ -19060,7 +19082,9 @@ function XViewScene({
19060
19082
  });
19061
19083
  };
19062
19084
  renderVertical(fullTree, rootNodeMesh, rootTargetPos, 1);
19063
- stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
19085
+ stateRef.current.ancestryLinks = renderedAncestries.flatMap(
19086
+ (a) => a.lines
19087
+ );
19064
19088
  tweenToTarget(rootTargetPos, 0.7);
19065
19089
  },
19066
19090
  [
@@ -19195,7 +19219,10 @@ function XViewScene({
19195
19219
  };
19196
19220
  const descriptionText = targetAncestryInfo.description || "";
19197
19221
  const savedSections = targetAncestryInfo.description_sections || [];
19198
- const sections = parseDescriptionSections(descriptionText, savedSections);
19222
+ const sections = parseDescriptionSections(
19223
+ descriptionText,
19224
+ savedSections
19225
+ );
19199
19226
  let focusTargetId = null;
19200
19227
  if (popped && popped.nodeId) {
19201
19228
  const mentionTag = `[[MENTION:node:${popped.nodeId}]]`;
@@ -19972,7 +19999,10 @@ function XViewScene({
19972
19999
  }
19973
20000
  if (ancestry_save_url && isExternalSave && get_ancestry_file) {
19974
20001
  try {
19975
- const viewDbResponse = await get_ancestry_file(sceneConfigId, ownerId);
20002
+ const viewDbResponse = await get_ancestry_file(
20003
+ sceneConfigId,
20004
+ ownerId
20005
+ );
19976
20006
  if (viewDbResponse.success && Array.isArray(viewDbResponse.data)) {
19977
20007
  const hasInViewDb = viewDbResponse.data.some(
19978
20008
  (anc) => String(anc.ancestry_id) === String(ancestryIdToDelete)
@@ -20162,61 +20192,31 @@ function XViewScene({
20162
20192
  async (newMilestones) => {
20163
20193
  var _a2, _b2, _c2;
20164
20194
  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
20195
  sceneDataRef.current.milestones = newMilestones;
20173
20196
  setSceneVersion((v) => v + 1);
20174
20197
  const isView = ((_a2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _a2.toLowerCase()) === "view";
20175
20198
  if (!isView || !save_view_data || !sceneSaveUrl) return;
20199
+ const questFileData = {
20200
+ nodes: ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || sceneDataRef.current.quest_nodes || [],
20201
+ links: ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || sceneDataRef.current.quest_links || [],
20202
+ milestones: newMilestones
20203
+ };
20176
20204
  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"
20205
+ if (upsert_milestone_firestore) {
20206
+ await upsert_milestone_firestore(
20207
+ ownerId,
20208
+ sceneConfigId,
20209
+ newMilestones
20209
20210
  );
20210
- await save_view_data(questSaveUrl, questFileData);
20211
20211
  }
20212
20212
  } catch (error) {
20213
20213
  console.error("Erro ao salvar milestones:", error);
20214
20214
  }
20215
20215
  },
20216
- [sceneConfigId, sceneSaveUrl, save_view_data, save_milestone_action, delete_milestone_action, viewParams == null ? void 0 : viewParams.type]
20216
+ [sceneConfigId, sceneSaveUrl, save_view_data, viewParams == null ? void 0 : viewParams.type]
20217
20217
  );
20218
20218
  const handleSaveCurrentView = (0, import_react33.useCallback)(async () => {
20219
- var _a2, _b2, _c2;
20219
+ var _a2;
20220
20220
  const { nodeObjects, allLinks } = stateRef.current;
20221
20221
  if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
20222
20222
  console.warn(
@@ -20246,23 +20246,10 @@ function XViewScene({
20246
20246
  const sceneFileData = {
20247
20247
  ...sceneDataRef.current,
20248
20248
  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 || []
20249
+ links: currentLinks
20256
20250
  };
20257
20251
  try {
20258
20252
  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
20253
  } catch (error) {
20267
20254
  console.error("Erro na chamada de save_view_data:", error);
20268
20255
  }
@@ -20961,12 +20948,18 @@ function XViewScene({
20961
20948
  data: multiContextMenu,
20962
20949
  userRole: userPermissionRole,
20963
20950
  onClose: () => setMultiContextMenu((prev) => ({ ...prev, visible: false })),
20964
- onDismissNodes: (ids) => userActionHandlers.handleDismissMultipleNodes(actionHandlerContext, ids),
20951
+ onDismissNodes: (ids) => userActionHandlers.handleDismissMultipleNodes(
20952
+ actionHandlerContext,
20953
+ ids
20954
+ ),
20965
20955
  onDismissOtherNodes: (ids) => userActionHandlers.handleDismissOtherMultipleNodes(
20966
20956
  actionHandlerContext,
20967
20957
  ids
20968
20958
  ),
20969
- onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
20959
+ onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(
20960
+ actionHandlerContext,
20961
+ ids
20962
+ )
20970
20963
  }
20971
20964
  ),
20972
20965
  /* @__PURE__ */ import_react33.default.createElement(
@@ -21119,25 +21112,40 @@ async function save_view_data_logic(db_services, filename, data) {
21119
21112
  }
21120
21113
  }
21121
21114
  async function get_scene_view_data_logic(db_services, scene_config, owner_id, type, session, focusNodeId = null, focusAncestryId = null) {
21122
- var _a, _b;
21115
+ var _a, _b, _c;
21123
21116
  try {
21124
21117
  if (!session || !session.user) {
21125
21118
  return { success: false, error: "Usu\xE1rio n\xE3o autenticado." };
21126
21119
  }
21127
- const membershipCheck = await db_services.check_membership(owner_id, type, scene_config, session.user.id);
21120
+ const membershipCheck = await db_services.check_membership(
21121
+ owner_id,
21122
+ type,
21123
+ scene_config,
21124
+ session.user.id
21125
+ );
21128
21126
  const isFullMember = membershipCheck.success && membershipCheck.isValidMember;
21129
21127
  if (!isFullMember && !focusNodeId && !focusAncestryId) {
21130
- return { success: false, error: "Acesso Negado: Voc\xEA n\xE3o possui permiss\xE3o para acessar este cen\xE1rio." };
21128
+ return {
21129
+ success: false,
21130
+ error: "Acesso Negado: Voc\xEA n\xE3o possui permiss\xE3o para acessar este cen\xE1rio."
21131
+ };
21131
21132
  }
21132
- const sceneResponse = await db_services.get_file(`x_view_scenes/${owner_id}/${scene_config}`);
21133
+ const sceneResponse = await db_services.get_file(
21134
+ `x_view_scenes/${owner_id}/${scene_config}`
21135
+ );
21133
21136
  if (!sceneResponse || !sceneResponse.success) {
21134
21137
  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}` };
21138
+ return {
21139
+ success: false,
21140
+ error: `N\xE3o foi poss\xEDvel carregar o arquivo da cena: ${scene_config}`
21141
+ };
21136
21142
  }
21137
21143
  const sceneData = sceneResponse.data;
21138
21144
  const parentDbObjects = sceneData.parent_dbs || [];
21139
21145
  if (type && type.toLowerCase().includes("database")) {
21140
- const selfExists = parentDbObjects.some((db) => String(db.db_id) === String(scene_config));
21146
+ const selfExists = parentDbObjects.some(
21147
+ (db) => String(db.db_id) === String(scene_config)
21148
+ );
21141
21149
  if (!selfExists) {
21142
21150
  parentDbObjects.push({ db_id: scene_config, owner_id });
21143
21151
  }
@@ -21146,34 +21154,67 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21146
21154
  const parentResponsesPromises = parentDbObjects.map(
21147
21155
  (db_info) => db_services.get_file(`x_view_dbs/${db_info.owner_id}/${db_info.db_id}`)
21148
21156
  );
21149
- const parentResponsesResults = await Promise.allSettled(parentResponsesPromises);
21157
+ if (isView) {
21158
+ const questFetchWithMigrationPromise = (async () => {
21159
+ try {
21160
+ const questsResponse = await db_services.get_view_quests_firestore(
21161
+ owner_id,
21162
+ scene_config
21163
+ );
21164
+ if (questsResponse.success && questsResponse.hasQuests) {
21165
+ return {
21166
+ success: true,
21167
+ data: questsResponse.data,
21168
+ quest_counter: questsResponse.quest_counter
21169
+ };
21170
+ } else {
21171
+ const legacyResponse = await db_services.get_file(
21172
+ `x_view_quests/${owner_id}/${scene_config}`
21173
+ );
21174
+ if (legacyResponse.success && legacyResponse.data) {
21175
+ await db_services.migrate_json_to_firestore(
21176
+ owner_id,
21177
+ scene_config,
21178
+ legacyResponse.data,
21179
+ sceneData.quest_counter
21180
+ );
21181
+ legacyResponse.quest_counter = sceneData.quest_counter || 1;
21182
+ return legacyResponse;
21183
+ }
21184
+ return legacyResponse;
21185
+ }
21186
+ } catch (err) {
21187
+ return { success: false, error: err.message };
21188
+ }
21189
+ })();
21190
+ parentResponsesPromises.push(questFetchWithMigrationPromise);
21191
+ }
21192
+ const parentResponsesResults = await Promise.allSettled(
21193
+ parentResponsesPromises
21194
+ );
21150
21195
  const parentData = {};
21151
21196
  let questDataObj = null;
21152
21197
  for (let i = 0; i < parentResponsesResults.length; i++) {
21153
21198
  const result = parentResponsesResults[i];
21199
+ if (isView && i === parentResponsesResults.length - 1) {
21200
+ if (result.status === "fulfilled" && ((_a = result.value) == null ? void 0 : _a.success)) {
21201
+ questDataObj = result.value.data;
21202
+ if (result.value.quest_counter !== void 0) {
21203
+ sceneData.quest_counter = result.value.quest_counter;
21204
+ }
21205
+ }
21206
+ continue;
21207
+ }
21154
21208
  const db_info = parentDbObjects[i];
21155
- if (result.status === "fulfilled" && ((_a = result.value) == null ? void 0 : _a.success)) {
21209
+ if (result.status === "fulfilled" && ((_b = result.value) == null ? void 0 : _b.success)) {
21156
21210
  parentData[db_info.db_id] = result.value.data;
21157
21211
  } else {
21158
21212
  console.warn(
21159
21213
  `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
21214
+ result.status === "rejected" ? result.reason : (_c = result.value) == null ? void 0 : _c.error
21161
21215
  );
21162
21216
  }
21163
21217
  }
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
21218
  const currentQuestNodes = (questDataObj == null ? void 0 : questDataObj.nodes) || [];
21178
21219
  const currentQuestLinks = (questDataObj == null ? void 0 : questDataObj.links) || [];
21179
21220
  const currentMilestones = (questDataObj == null ? void 0 : questDataObj.milestones) || [];
@@ -21186,13 +21227,19 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21186
21227
  }
21187
21228
  const allNodes = Object.values(parentData).flatMap((db) => db.nodes || []);
21188
21229
  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]));
21230
+ const parentNodeMap = new Map(
21231
+ allNodes.map((node) => [String(node.id), node])
21232
+ );
21233
+ const parentLinkMap = new Map(
21234
+ allLinks.map((link) => [`${link.source}-${link.target}`, link])
21235
+ );
21191
21236
  const validatedNodes = (sceneData.nodes || []).map((sceneNode) => {
21192
21237
  var _a2, _b2;
21193
21238
  const nodeTypes = Array.isArray(sceneNode.type) ? sceneNode.type : [sceneNode.type];
21194
21239
  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));
21240
+ const dbQuestNode = (_b2 = (_a2 = parentData[scene_config]) == null ? void 0 : _a2.nodes) == null ? void 0 : _b2.find(
21241
+ (qn) => String(qn.id) === String(sceneNode.id)
21242
+ );
21196
21243
  if (dbQuestNode) {
21197
21244
  return { ...sceneNode, ...dbQuestNode };
21198
21245
  }
@@ -21204,18 +21251,22 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21204
21251
  }
21205
21252
  return null;
21206
21253
  }).filter(Boolean);
21207
- const validNodeIdsInScene = new Set(validatedNodes.map((node) => String(node.id)));
21254
+ const validNodeIdsInScene = new Set(
21255
+ validatedNodes.map((node) => String(node.id))
21256
+ );
21208
21257
  const validatedLinks = (sceneData.links || []).filter((sceneLink) => {
21209
- const linkExistsInParent = parentLinkMap.has(`${sceneLink.source}-${sceneLink.target}`);
21258
+ const linkExistsInParent = parentLinkMap.has(
21259
+ `${sceneLink.source}-${sceneLink.target}`
21260
+ );
21210
21261
  const nodesAreValidForScene = validNodeIdsInScene.has(String(sceneLink.source)) && validNodeIdsInScene.has(String(sceneLink.target));
21211
21262
  return linkExistsInParent && nodesAreValidForScene;
21212
- }).map((sceneLink) => parentLinkMap.get(`${sceneLink.source}-${sceneLink.target}`));
21263
+ }).map(
21264
+ (sceneLink) => parentLinkMap.get(`${sceneLink.source}-${sceneLink.target}`)
21265
+ );
21213
21266
  const validatedSceneData = {
21214
21267
  ...sceneData,
21215
21268
  nodes: validatedNodes,
21216
21269
  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
21270
  quest_nodes: currentQuestNodes,
21220
21271
  quest_links: currentQuestLinks,
21221
21272
  milestones: currentMilestones
@@ -21235,7 +21286,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21235
21286
  isSceneFile: false
21236
21287
  });
21237
21288
  });
21238
- const ancestryPromises = ancestryFilePaths.map((file) => db_services.get_file(file.path));
21289
+ const ancestryPromises = ancestryFilePaths.map(
21290
+ (file) => db_services.get_file(file.path)
21291
+ );
21239
21292
  const ancestryResults = await Promise.allSettled(ancestryPromises);
21240
21293
  const ancestriesFromSceneFile = [];
21241
21294
  const ancestriesFromDbFiles = [];
@@ -21261,15 +21314,21 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21261
21314
  }
21262
21315
  });
21263
21316
  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));
21317
+ ancestriesFromDbFiles.forEach(
21318
+ (anc) => ancestryMap.set(anc.ancestry_id, anc)
21319
+ );
21320
+ ancestriesFromSceneFile.forEach(
21321
+ (anc) => ancestryMap.set(anc.ancestry_id, anc)
21322
+ );
21266
21323
  let ancestryData = Array.from(ancestryMap.values());
21267
21324
  const externalSourcesToRefresh = /* @__PURE__ */ new Map();
21268
21325
  ancestryData.forEach((anc) => {
21269
21326
  const targetSourceId = anc._source_file_id || anc._imported_from_view_id;
21270
21327
  const targetOwnerId = anc._source_owner_id || anc._imported_from_view_owner_id;
21271
21328
  if (targetSourceId && targetSourceId !== scene_config && targetOwnerId) {
21272
- const isAlreadyLoadedAsParent = parentDbObjects.some((db) => String(db.db_id) === String(targetSourceId));
21329
+ const isAlreadyLoadedAsParent = parentDbObjects.some(
21330
+ (db) => String(db.db_id) === String(targetSourceId)
21331
+ );
21273
21332
  if (!isAlreadyLoadedAsParent) {
21274
21333
  const key = `${targetOwnerId}/${targetSourceId}`;
21275
21334
  externalSourcesToRefresh.set(key, {
@@ -21310,12 +21369,16 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21310
21369
  return false;
21311
21370
  }
21312
21371
  if (externalSourcesToRefresh.has(key) && successfullyFetchedSources.has(key)) {
21313
- const stillExists = freshAncestryMap.has(String(localAnc.ancestry_id));
21372
+ const stillExists = freshAncestryMap.has(
21373
+ String(localAnc.ancestry_id)
21374
+ );
21314
21375
  return stillExists;
21315
21376
  }
21316
21377
  return true;
21317
21378
  }).map((localAnc) => {
21318
- const freshVersion = freshAncestryMap.get(String(localAnc.ancestry_id));
21379
+ const freshVersion = freshAncestryMap.get(
21380
+ String(localAnc.ancestry_id)
21381
+ );
21319
21382
  if (freshVersion) {
21320
21383
  return {
21321
21384
  ...freshVersion,
@@ -21354,7 +21417,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21354
21417
  parallel_branches: validBranches
21355
21418
  };
21356
21419
  };
21357
- const originalAncestryDataString = JSON.stringify(Array.from(ancestryMap.values()));
21420
+ const originalAncestryDataString = JSON.stringify(
21421
+ Array.from(ancestryMap.values())
21422
+ );
21358
21423
  const cleanedAncestryData = ancestryData.map((ancestry) => {
21359
21424
  if (!parentNodeIds.has(String(ancestry.ancestral_node))) return null;
21360
21425
  const cleanedTree = pruneTree(ancestry.tree);
@@ -21374,7 +21439,10 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21374
21439
  try {
21375
21440
  await db_services.save_file(ancestryFilePath, ancestryData);
21376
21441
  } catch (saveError) {
21377
- console.error("Falha ao salvar o arquivo de ancestralidade da cena atualizado:", saveError);
21442
+ console.error(
21443
+ "Falha ao salvar o arquivo de ancestralidade da cena atualizado:",
21444
+ saveError
21445
+ );
21378
21446
  }
21379
21447
  }
21380
21448
  if (!isFullMember) {
@@ -21382,7 +21450,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21382
21450
  const requiredAncestryIds = /* @__PURE__ */ new Set();
21383
21451
  if (focusNodeId) requiredNodeIds.add(String(focusNodeId));
21384
21452
  if (focusAncestryId) requiredAncestryIds.add(String(focusAncestryId));
21385
- const allNodesFromDb = Object.values(parentData).flatMap((db) => db.nodes || []);
21453
+ const allNodesFromDb = Object.values(parentData).flatMap(
21454
+ (db) => db.nodes || []
21455
+ );
21386
21456
  const extractDependenciesFromText = (text) => {
21387
21457
  if (!text) return;
21388
21458
  const mentionRegex = /\[\[MENTION:node:([a-zA-Z0-9\-_]+)\]\]/g;
@@ -21409,9 +21479,12 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21409
21479
  if (branch.linked_ancestry_id) {
21410
21480
  requiredAncestryIds.add(String(branch.linked_ancestry_id));
21411
21481
  }
21412
- if (branch.description) extractDependenciesFromText(branch.description);
21482
+ if (branch.description)
21483
+ extractDependenciesFromText(branch.description);
21413
21484
  if (branch.description_sections) {
21414
- branch.description_sections.forEach((s) => extractDependenciesFromText(s.content));
21485
+ branch.description_sections.forEach(
21486
+ (s) => extractDependenciesFromText(s.content)
21487
+ );
21415
21488
  }
21416
21489
  extractTreeDependencies(branch.tree);
21417
21490
  });
@@ -21425,7 +21498,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21425
21498
  if (anc && !anc.is_private) {
21426
21499
  if (anc.description) extractDependenciesFromText(anc.description);
21427
21500
  if (anc.description_sections) {
21428
- anc.description_sections.forEach((s) => extractDependenciesFromText(s.content));
21501
+ anc.description_sections.forEach(
21502
+ (s) => extractDependenciesFromText(s.content)
21503
+ );
21429
21504
  }
21430
21505
  extractTreeDependencies(anc.tree);
21431
21506
  extractTreeDependencies(anc.abstraction_tree);
@@ -21436,22 +21511,38 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21436
21511
  if (node) {
21437
21512
  if (node.description) extractDependenciesFromText(node.description);
21438
21513
  if (node.description_sections) {
21439
- node.description_sections.forEach((s) => extractDependenciesFromText(s.content));
21514
+ node.description_sections.forEach(
21515
+ (s) => extractDependenciesFromText(s.content)
21516
+ );
21440
21517
  }
21441
21518
  }
21442
21519
  });
21443
21520
  } while (requiredNodeIds.size + requiredAncestryIds.size > previousSize);
21444
- const restrictedSceneData = { ...validatedSceneData, nodes: [], links: [] };
21521
+ const restrictedSceneData = {
21522
+ ...validatedSceneData,
21523
+ nodes: [],
21524
+ links: []
21525
+ };
21445
21526
  const restrictedParentData = {};
21446
- const restrictedAncestryData = ancestryData.filter((a) => requiredAncestryIds.has(String(a.ancestry_id)) && !a.is_private);
21527
+ const restrictedAncestryData = ancestryData.filter(
21528
+ (a) => requiredAncestryIds.has(String(a.ancestry_id)) && !a.is_private
21529
+ );
21447
21530
  for (const [dbId, dbContent] of Object.entries(parentData)) {
21448
- const filteredNodes = (dbContent.nodes || []).filter((n) => requiredNodeIds.has(String(n.id)));
21531
+ const filteredNodes = (dbContent.nodes || []).filter(
21532
+ (n) => requiredNodeIds.has(String(n.id))
21533
+ );
21449
21534
  if (filteredNodes.length > 0) {
21450
- restrictedParentData[dbId] = { ...dbContent, nodes: filteredNodes, links: [] };
21535
+ restrictedParentData[dbId] = {
21536
+ ...dbContent,
21537
+ nodes: filteredNodes,
21538
+ links: []
21539
+ };
21451
21540
  }
21452
21541
  }
21453
21542
  if (focusNodeId) {
21454
- const mainNode = allNodesFromDb.find((n) => String(n.id) === String(focusNodeId));
21543
+ const mainNode = allNodesFromDb.find(
21544
+ (n) => String(n.id) === String(focusNodeId)
21545
+ );
21455
21546
  if (mainNode) {
21456
21547
  restrictedSceneData.nodes = [mainNode];
21457
21548
  }
@@ -21467,7 +21558,11 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
21467
21558
  }
21468
21559
  return {
21469
21560
  success: true,
21470
- data: { scene: validatedSceneData, parent: parentData, ancestry: ancestryData }
21561
+ data: {
21562
+ scene: validatedSceneData,
21563
+ parent: parentData,
21564
+ ancestry: ancestryData
21565
+ }
21471
21566
  };
21472
21567
  } catch (error) {
21473
21568
  console.error("Erro em get_scene_view_data_logic:", error);
@@ -21487,13 +21582,18 @@ async function import_parent_file_modal_get_logic(db_services, session) {
21487
21582
  }
21488
21583
  };
21489
21584
  } catch (error) {
21490
- console.error("catch (error) em import_parent_file_modal_get_logic:", error);
21585
+ console.error(
21586
+ "catch (error) em import_parent_file_modal_get_logic:",
21587
+ error
21588
+ );
21491
21589
  return { success: false, error: error.message };
21492
21590
  }
21493
21591
  }
21494
21592
  async function get_single_parent_file_logic(db_services, file_id, session) {
21495
21593
  try {
21496
- const call_GCP_cloud_storage_get_file = await db_services.get_file(`x_view_dbs/${session.user.id}/${file_id}`);
21594
+ const call_GCP_cloud_storage_get_file = await db_services.get_file(
21595
+ `x_view_dbs/${session.user.id}/${file_id}`
21596
+ );
21497
21597
  return call_GCP_cloud_storage_get_file;
21498
21598
  } catch (error) {
21499
21599
  console.error("catch (error) em get_single_parent_file_logic:", error);
@@ -21527,7 +21627,13 @@ async function get_ancestry_file_logic(db_services, file_id, owner_id) {
21527
21627
  async function save_boards_logic(db_services, scene_id, type, boardItems, session, owner_id) {
21528
21628
  try {
21529
21629
  const targetOwnerId = owner_id || session.user.id;
21530
- return await db_services.save_boards(session, scene_id, type, boardItems, targetOwnerId);
21630
+ return await db_services.save_boards(
21631
+ session,
21632
+ scene_id,
21633
+ type,
21634
+ boardItems,
21635
+ targetOwnerId
21636
+ );
21531
21637
  } catch (error) {
21532
21638
  console.error("Erro em save_boards_logic:", error);
21533
21639
  return { success: false, error: error.message };
@@ -21556,7 +21662,10 @@ async function delete_uploaded_file_logic(db_services, fileUrl) {
21556
21662
  async function get_view_members_logic(db_services, ownerId, type, itemId) {
21557
21663
  try {
21558
21664
  if (!db_services.get_view_members) {
21559
- return { success: false, error: "Servi\xE7o de busca de membros n\xE3o configurado." };
21665
+ return {
21666
+ success: false,
21667
+ error: "Servi\xE7o de busca de membros n\xE3o configurado."
21668
+ };
21560
21669
  }
21561
21670
  return await db_services.get_view_members(ownerId, type, itemId);
21562
21671
  } catch (error) {