@lv-x-software-house/x_view 1.2.8-dev.4 → 1.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +553 -423
- package/dist/index.mjs +591 -461
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import React32, {
|
|
3
3
|
useCallback as useCallback7,
|
|
4
4
|
useEffect as useEffect25,
|
|
5
|
-
useRef as
|
|
5
|
+
useRef as useRef22,
|
|
6
6
|
useState as useState30,
|
|
7
7
|
useMemo as useMemo14
|
|
8
8
|
} from "react";
|
|
@@ -283,7 +283,12 @@ var updateExistingNodeVisuals = (state, updatedNode) => {
|
|
|
283
283
|
if (oldLabelObject.material) oldLabelObject.material.dispose();
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
const newMesh = createNodeMesh(
|
|
286
|
+
const newMesh = createNodeMesh(
|
|
287
|
+
updatedNode,
|
|
288
|
+
position,
|
|
289
|
+
state.glowTexture,
|
|
290
|
+
hadQuestDateLabel
|
|
291
|
+
);
|
|
287
292
|
if (oldTimelineBar) {
|
|
288
293
|
newMesh.userData.timelineIntervalBar = oldTimelineBar;
|
|
289
294
|
}
|
|
@@ -835,7 +840,12 @@ var removeNodeFromScene = (state, nodeId) => {
|
|
|
835
840
|
var addStandaloneNodeToScene = (state, nodeData, position, forceShowQuestDate = false) => {
|
|
836
841
|
const { graphGroup, nodeObjects, clickableNodes, glowTexture } = state;
|
|
837
842
|
if (!graphGroup) return;
|
|
838
|
-
const mesh = createNodeMesh(
|
|
843
|
+
const mesh = createNodeMesh(
|
|
844
|
+
nodeData,
|
|
845
|
+
position,
|
|
846
|
+
glowTexture,
|
|
847
|
+
forceShowQuestDate
|
|
848
|
+
);
|
|
839
849
|
mesh.scale.set(0.01, 0.01, 0.01);
|
|
840
850
|
graphGroup.add(mesh);
|
|
841
851
|
if (mesh.userData.labelObject) {
|
|
@@ -1053,7 +1063,9 @@ var userActionHandlers = {
|
|
|
1053
1063
|
if (isCrossDataset) {
|
|
1054
1064
|
graphDataRef.current[finalTargetDatasetId] = targetDataToUpdate;
|
|
1055
1065
|
}
|
|
1056
|
-
if (sceneDataRef.current.parent_dbs.some(
|
|
1066
|
+
if (sceneDataRef.current.parent_dbs.some(
|
|
1067
|
+
(db) => String(db.db_id) === String(sourceParentInfo.parentFileId)
|
|
1068
|
+
)) {
|
|
1057
1069
|
}
|
|
1058
1070
|
const finalPosition = stateRef.current.ghostElements.node.position.clone();
|
|
1059
1071
|
addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
|
|
@@ -1248,7 +1260,10 @@ var userActionHandlers = {
|
|
|
1248
1260
|
context.sceneSaveUrl,
|
|
1249
1261
|
viewFilePayload
|
|
1250
1262
|
);
|
|
1251
|
-
const questSaveUrl = context.sceneSaveUrl.replace(
|
|
1263
|
+
const questSaveUrl = context.sceneSaveUrl.replace(
|
|
1264
|
+
"x_view_scenes",
|
|
1265
|
+
"x_view_quests"
|
|
1266
|
+
);
|
|
1252
1267
|
await context.actions.save_view_data(questSaveUrl, questFilePayload);
|
|
1253
1268
|
} else {
|
|
1254
1269
|
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
@@ -1324,7 +1339,12 @@ var userActionHandlers = {
|
|
|
1324
1339
|
)
|
|
1325
1340
|
);
|
|
1326
1341
|
targetFinalPositions.push(endPosition);
|
|
1327
|
-
const targetMesh = createNodeMesh(
|
|
1342
|
+
const targetMesh = createNodeMesh(
|
|
1343
|
+
nodeData,
|
|
1344
|
+
startPosition,
|
|
1345
|
+
glowTexture,
|
|
1346
|
+
!!nodeData.is_quest
|
|
1347
|
+
);
|
|
1328
1348
|
targetMesh.scale.set(0.01, 0.01, 0.01);
|
|
1329
1349
|
graphGroup.add(targetMesh);
|
|
1330
1350
|
if (targetMesh.userData.labelObject) {
|
|
@@ -1476,10 +1496,16 @@ var userActionHandlers = {
|
|
|
1476
1496
|
context.sceneConfigId,
|
|
1477
1497
|
context.ownerId
|
|
1478
1498
|
);
|
|
1479
|
-
|
|
1499
|
+
const targetParentInfo = getParentFileInfoForNode(
|
|
1500
|
+
graphDataRef.current,
|
|
1501
|
+
sceneDataRef.current,
|
|
1502
|
+
targetNodeData.id,
|
|
1503
|
+
context.sceneConfigId,
|
|
1504
|
+
context.ownerId
|
|
1505
|
+
);
|
|
1506
|
+
if (!sourceParentInfo || !sourceParentInfo.ownerId || !targetParentInfo) {
|
|
1480
1507
|
console.error(
|
|
1481
|
-
"N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para
|
|
1482
|
-
sourceNodeData.id
|
|
1508
|
+
"N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para os Nodes da conex\xE3o."
|
|
1483
1509
|
);
|
|
1484
1510
|
alert(
|
|
1485
1511
|
"Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio."
|
|
@@ -1487,9 +1513,13 @@ var userActionHandlers = {
|
|
|
1487
1513
|
userActionHandlers.handleCancelConnection(context);
|
|
1488
1514
|
return;
|
|
1489
1515
|
}
|
|
1490
|
-
|
|
1491
|
-
const
|
|
1492
|
-
const
|
|
1516
|
+
let parentInfoToSave = sourceParentInfo;
|
|
1517
|
+
const isSourceQuest = sourceParentInfo.parentFileId === context.sceneConfigId;
|
|
1518
|
+
const isTargetQuest = targetParentInfo.parentFileId === context.sceneConfigId;
|
|
1519
|
+
if (isSourceQuest || isTargetQuest) {
|
|
1520
|
+
parentInfoToSave = { parentFileId: context.sceneConfigId, ownerId: context.ownerId };
|
|
1521
|
+
}
|
|
1522
|
+
const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
|
|
1493
1523
|
const newLink = {
|
|
1494
1524
|
id: `link_${short.generate()}`,
|
|
1495
1525
|
source: sourceNodeData.id,
|
|
@@ -1503,14 +1533,19 @@ var userActionHandlers = {
|
|
|
1503
1533
|
const viewFilePayload = {
|
|
1504
1534
|
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
1505
1535
|
nodes: sceneDataRef.current.nodes,
|
|
1506
|
-
links: sceneDataRef.current.links
|
|
1507
|
-
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
1536
|
+
links: sceneDataRef.current.links
|
|
1508
1537
|
};
|
|
1509
1538
|
await context.actions.save_view_data(
|
|
1510
1539
|
context.sceneSaveUrl,
|
|
1511
1540
|
viewFilePayload
|
|
1512
1541
|
);
|
|
1513
|
-
|
|
1542
|
+
if (context.actions.upsert_quest_link_firestore) {
|
|
1543
|
+
await context.actions.upsert_quest_link_firestore(
|
|
1544
|
+
context.ownerId,
|
|
1545
|
+
context.sceneConfigId,
|
|
1546
|
+
newLink
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1514
1549
|
} else {
|
|
1515
1550
|
const specificParentData = JSON.parse(
|
|
1516
1551
|
JSON.stringify(graphDataRef.current[parentFileIdToSave])
|
|
@@ -1659,18 +1694,12 @@ var userActionHandlers = {
|
|
|
1659
1694
|
const viewFilePayload = {
|
|
1660
1695
|
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
1661
1696
|
nodes: sceneDataRef.current.nodes,
|
|
1662
|
-
links: sceneDataRef.current.links
|
|
1663
|
-
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
1664
|
-
};
|
|
1665
|
-
const questFilePayload = {
|
|
1666
|
-
nodes: data.nodes,
|
|
1667
|
-
links: data.links,
|
|
1668
|
-
milestones: sceneDataRef.current.milestones || []
|
|
1697
|
+
links: sceneDataRef.current.links
|
|
1669
1698
|
};
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1699
|
+
return context.actions.save_view_data(
|
|
1700
|
+
context.sceneSaveUrl,
|
|
1701
|
+
viewFilePayload
|
|
1702
|
+
);
|
|
1674
1703
|
} else {
|
|
1675
1704
|
return context.actions.save_view_data(
|
|
1676
1705
|
`x_view_dbs/${fileOwnerId}/${fileId}`,
|
|
@@ -1695,6 +1724,15 @@ var userActionHandlers = {
|
|
|
1695
1724
|
updatedOriginalParentData
|
|
1696
1725
|
)
|
|
1697
1726
|
);
|
|
1727
|
+
if (oldGoverningFileId === context.sceneConfigId && context.actions.delete_quest_link_firestore) {
|
|
1728
|
+
savePromises.push(
|
|
1729
|
+
context.actions.delete_quest_link_firestore(
|
|
1730
|
+
context.ownerId,
|
|
1731
|
+
context.sceneConfigId,
|
|
1732
|
+
linkId
|
|
1733
|
+
)
|
|
1734
|
+
);
|
|
1735
|
+
}
|
|
1698
1736
|
const updatedNewParentData = JSON.parse(
|
|
1699
1737
|
JSON.stringify(graphDataRef.current[newGoverningFileId])
|
|
1700
1738
|
);
|
|
@@ -1708,6 +1746,15 @@ var userActionHandlers = {
|
|
|
1708
1746
|
updatedNewParentData
|
|
1709
1747
|
)
|
|
1710
1748
|
);
|
|
1749
|
+
if (newGoverningFileId === context.sceneConfigId && context.actions.upsert_quest_link_firestore) {
|
|
1750
|
+
savePromises.push(
|
|
1751
|
+
context.actions.upsert_quest_link_firestore(
|
|
1752
|
+
context.ownerId,
|
|
1753
|
+
context.sceneConfigId,
|
|
1754
|
+
newLinkData
|
|
1755
|
+
)
|
|
1756
|
+
);
|
|
1757
|
+
}
|
|
1711
1758
|
} else {
|
|
1712
1759
|
const updatedParentData = JSON.parse(
|
|
1713
1760
|
JSON.stringify(graphDataRef.current[oldGoverningFileId])
|
|
@@ -1724,6 +1771,15 @@ var userActionHandlers = {
|
|
|
1724
1771
|
updatedParentData
|
|
1725
1772
|
)
|
|
1726
1773
|
);
|
|
1774
|
+
if (oldGoverningFileId === context.sceneConfigId && context.actions.upsert_quest_link_firestore) {
|
|
1775
|
+
savePromises.push(
|
|
1776
|
+
context.actions.upsert_quest_link_firestore(
|
|
1777
|
+
context.ownerId,
|
|
1778
|
+
context.sceneConfigId,
|
|
1779
|
+
newLinkData
|
|
1780
|
+
)
|
|
1781
|
+
);
|
|
1782
|
+
}
|
|
1727
1783
|
}
|
|
1728
1784
|
try {
|
|
1729
1785
|
await Promise.all(savePromises);
|
|
@@ -1754,14 +1810,21 @@ var userActionHandlers = {
|
|
|
1754
1810
|
);
|
|
1755
1811
|
return;
|
|
1756
1812
|
}
|
|
1757
|
-
const
|
|
1813
|
+
const sourceParentInfo = getParentFileInfoForNode(
|
|
1758
1814
|
graphDataRef.current,
|
|
1759
1815
|
sceneDataRef.current,
|
|
1760
1816
|
linkObject.userData.source,
|
|
1761
1817
|
context.sceneConfigId,
|
|
1762
1818
|
context.ownerId
|
|
1763
1819
|
);
|
|
1764
|
-
|
|
1820
|
+
const targetParentInfo = getParentFileInfoForNode(
|
|
1821
|
+
graphDataRef.current,
|
|
1822
|
+
sceneDataRef.current,
|
|
1823
|
+
linkObject.userData.target,
|
|
1824
|
+
context.sceneConfigId,
|
|
1825
|
+
context.ownerId
|
|
1826
|
+
);
|
|
1827
|
+
if (!sourceParentInfo || !sourceParentInfo.ownerId) {
|
|
1765
1828
|
console.error(
|
|
1766
1829
|
"N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link:",
|
|
1767
1830
|
linkIdToDelete
|
|
@@ -1771,6 +1834,12 @@ var userActionHandlers = {
|
|
|
1771
1834
|
);
|
|
1772
1835
|
return;
|
|
1773
1836
|
}
|
|
1837
|
+
let parentInfo = sourceParentInfo;
|
|
1838
|
+
const isSourceQuest = sourceParentInfo.parentFileId === context.sceneConfigId;
|
|
1839
|
+
const isTargetQuest = (targetParentInfo == null ? void 0 : targetParentInfo.parentFileId) === context.sceneConfigId;
|
|
1840
|
+
if (isSourceQuest || isTargetQuest) {
|
|
1841
|
+
parentInfo = { parentFileId: context.sceneConfigId, ownerId: context.ownerId };
|
|
1842
|
+
}
|
|
1774
1843
|
const { parentFileId, ownerId } = parentInfo;
|
|
1775
1844
|
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;
|
|
1776
1845
|
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;
|
|
@@ -1783,8 +1852,6 @@ var userActionHandlers = {
|
|
|
1783
1852
|
specificParentData.links = newLinks;
|
|
1784
1853
|
let filenameToSave;
|
|
1785
1854
|
let payloadToSave;
|
|
1786
|
-
let questSaveUrl;
|
|
1787
|
-
let questFilePayload;
|
|
1788
1855
|
const isView = ((_g = context.viewType) == null ? void 0 : _g.toLowerCase()) === "view";
|
|
1789
1856
|
if (isView && parentFileId === context.sceneConfigId) {
|
|
1790
1857
|
filenameToSave = context.sceneSaveUrl;
|
|
@@ -1794,8 +1861,7 @@ var userActionHandlers = {
|
|
|
1794
1861
|
payloadToSave = {
|
|
1795
1862
|
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
1796
1863
|
nodes: sceneDataRef.current.nodes,
|
|
1797
|
-
links: sceneDataRef.current.links
|
|
1798
|
-
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
1864
|
+
links: sceneDataRef.current.links
|
|
1799
1865
|
};
|
|
1800
1866
|
} else {
|
|
1801
1867
|
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
@@ -1803,8 +1869,12 @@ var userActionHandlers = {
|
|
|
1803
1869
|
}
|
|
1804
1870
|
try {
|
|
1805
1871
|
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
1806
|
-
if (isView && parentFileId === context.sceneConfigId && context.actions.
|
|
1807
|
-
await context.actions.
|
|
1872
|
+
if (isView && parentFileId === context.sceneConfigId && context.actions.delete_quest_link_firestore) {
|
|
1873
|
+
await context.actions.delete_quest_link_firestore(
|
|
1874
|
+
context.ownerId,
|
|
1875
|
+
context.sceneConfigId,
|
|
1876
|
+
linkIdToDelete
|
|
1877
|
+
);
|
|
1808
1878
|
}
|
|
1809
1879
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
1810
1880
|
setters.setDetailsLink(
|
|
@@ -2033,18 +2103,30 @@ var userActionHandlers = {
|
|
|
2033
2103
|
payloadToSave = {
|
|
2034
2104
|
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2035
2105
|
nodes: sceneDataRef.current.nodes,
|
|
2036
|
-
links: sceneDataRef.current.links
|
|
2037
|
-
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
2106
|
+
links: sceneDataRef.current.links
|
|
2038
2107
|
};
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2108
|
+
if (context.actions.delete_quest_firestore) {
|
|
2109
|
+
nodesToDelete.forEach((nodeIdToDelete) => {
|
|
2110
|
+
savePromises.push(
|
|
2111
|
+
context.actions.delete_quest_firestore(
|
|
2112
|
+
context.ownerId,
|
|
2113
|
+
context.sceneConfigId,
|
|
2114
|
+
nodeIdToDelete
|
|
2115
|
+
)
|
|
2116
|
+
);
|
|
2117
|
+
});
|
|
2118
|
+
if (context.actions.delete_quest_link_firestore) {
|
|
2119
|
+
linksToDelete.forEach((linkIdToDelete) => {
|
|
2120
|
+
savePromises.push(
|
|
2121
|
+
context.actions.delete_quest_link_firestore(
|
|
2122
|
+
context.ownerId,
|
|
2123
|
+
context.sceneConfigId,
|
|
2124
|
+
linkIdToDelete
|
|
2125
|
+
)
|
|
2126
|
+
);
|
|
2127
|
+
});
|
|
2043
2128
|
}
|
|
2044
2129
|
}
|
|
2045
|
-
for (const linkId of linksToDelete) {
|
|
2046
|
-
await context.actions.delete_quest_link(ownerId, context.sceneConfigId, linkId);
|
|
2047
|
-
}
|
|
2048
2130
|
} else {
|
|
2049
2131
|
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2050
2132
|
payloadToSave = originalData;
|
|
@@ -2115,6 +2197,9 @@ var userActionHandlers = {
|
|
|
2115
2197
|
const newLinks = (specificParentData.links || []).filter(
|
|
2116
2198
|
(l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId
|
|
2117
2199
|
);
|
|
2200
|
+
const linksToDelete = (specificParentData.links || []).filter(
|
|
2201
|
+
(l) => String(l.source) === strNodeId || String(l.target) === strNodeId
|
|
2202
|
+
);
|
|
2118
2203
|
specificParentData.nodes = newNodes;
|
|
2119
2204
|
specificParentData.links = newLinks;
|
|
2120
2205
|
let filenameToSave;
|
|
@@ -2133,12 +2218,27 @@ var userActionHandlers = {
|
|
|
2133
2218
|
payloadToSave = {
|
|
2134
2219
|
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2135
2220
|
nodes: newVisualNodes,
|
|
2136
|
-
links: newVisualLinks
|
|
2137
|
-
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
2221
|
+
links: newVisualLinks
|
|
2138
2222
|
};
|
|
2139
2223
|
try {
|
|
2140
2224
|
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2141
|
-
|
|
2225
|
+
if (context.actions.delete_quest_firestore) {
|
|
2226
|
+
await context.actions.delete_quest_firestore(
|
|
2227
|
+
context.ownerId,
|
|
2228
|
+
context.sceneConfigId,
|
|
2229
|
+
nodeIdToDelete
|
|
2230
|
+
);
|
|
2231
|
+
if (context.actions.delete_quest_link_firestore && linksToDelete.length > 0) {
|
|
2232
|
+
const linkDeletePromises = linksToDelete.map(
|
|
2233
|
+
(link) => context.actions.delete_quest_link_firestore(
|
|
2234
|
+
context.ownerId,
|
|
2235
|
+
context.sceneConfigId,
|
|
2236
|
+
link.id
|
|
2237
|
+
)
|
|
2238
|
+
);
|
|
2239
|
+
await Promise.all(linkDeletePromises);
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2142
2242
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2143
2243
|
setters.setDetailsNode(
|
|
2144
2244
|
(prev) => String(prev == null ? void 0 : prev.id) === String(nodeIdToDelete) ? null : prev
|
|
@@ -2168,9 +2268,10 @@ var userActionHandlers = {
|
|
|
2168
2268
|
}
|
|
2169
2269
|
},
|
|
2170
2270
|
handleSaveNodeDetails: async (context, updatedNode, keepOpen = false) => {
|
|
2171
|
-
var _a, _b, _c;
|
|
2271
|
+
var _a, _b, _c, _d;
|
|
2172
2272
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2173
2273
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2274
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2174
2275
|
const {
|
|
2175
2276
|
_baseEmissiveIntensity,
|
|
2176
2277
|
_baseScale,
|
|
@@ -2215,7 +2316,7 @@ var userActionHandlers = {
|
|
|
2215
2316
|
const oldNode = specificParentData.nodes[nodeIndex];
|
|
2216
2317
|
const isNewDone = oldNode.status !== "Done" && nodeToSave.status === "Done";
|
|
2217
2318
|
specificParentData.nodes[nodeIndex] = { ...nodeToSave };
|
|
2218
|
-
if (isNewDone && nodeToSave.is_quest && ((
|
|
2319
|
+
if (isNewDone && nodeToSave.is_quest && ((_b = nodeToSave.recurrence_config) == null ? void 0 : _b.enabled)) {
|
|
2219
2320
|
const nextDateObj = calculateNextRecurrenceDate(
|
|
2220
2321
|
nodeToSave.recurrence_config
|
|
2221
2322
|
);
|
|
@@ -2240,12 +2341,10 @@ var userActionHandlers = {
|
|
|
2240
2341
|
}
|
|
2241
2342
|
const nextQuestNode = {
|
|
2242
2343
|
...JSON.parse(JSON.stringify(nodeToSave)),
|
|
2243
|
-
// Deep copy properties
|
|
2244
2344
|
id: short.generate(),
|
|
2245
2345
|
name: nextName,
|
|
2246
2346
|
status: "Backlog",
|
|
2247
2347
|
color: "#64748b",
|
|
2248
|
-
// QUEST_STATUS_COLORS["Backlog"]
|
|
2249
2348
|
assignee_id: nodeToSave.recurrence_config.next_assignee_id || "",
|
|
2250
2349
|
Date: nextDateObj,
|
|
2251
2350
|
timeline: [
|
|
@@ -2262,7 +2361,7 @@ var userActionHandlers = {
|
|
|
2262
2361
|
],
|
|
2263
2362
|
version_node: {
|
|
2264
2363
|
is_version: true,
|
|
2265
|
-
parent_node: ((
|
|
2364
|
+
parent_node: ((_c = nodeToSave.version_node) == null ? void 0 : _c.parent_node) || nodeToSave.id
|
|
2266
2365
|
},
|
|
2267
2366
|
reviewStack: (nodeToSave.reviewStack || []).map((r) => ({
|
|
2268
2367
|
...r,
|
|
@@ -2270,21 +2369,56 @@ var userActionHandlers = {
|
|
|
2270
2369
|
})),
|
|
2271
2370
|
recurrence_config: nextRecurrenceConfig
|
|
2272
2371
|
};
|
|
2273
|
-
|
|
2372
|
+
const rootId = ((_d = nodeToSave.version_node) == null ? void 0 : _d.parent_node) || nodeToSave.id;
|
|
2373
|
+
const nextQuestLink = {
|
|
2374
|
+
id: `link_${short.generate()}`,
|
|
2375
|
+
source: rootId,
|
|
2376
|
+
target: nextQuestNode.id
|
|
2377
|
+
};
|
|
2378
|
+
await context.actions.upsert_quest_firestore(
|
|
2379
|
+
context.ownerId,
|
|
2380
|
+
context.sceneConfigId,
|
|
2381
|
+
nextQuestNode
|
|
2382
|
+
);
|
|
2383
|
+
await context.actions.upsert_quest_link_firestore(
|
|
2384
|
+
context.ownerId,
|
|
2385
|
+
context.sceneConfigId,
|
|
2386
|
+
nextQuestLink
|
|
2387
|
+
);
|
|
2388
|
+
await context.actions.update_view_counter(
|
|
2389
|
+
context.ownerId,
|
|
2390
|
+
context.sceneConfigId,
|
|
2391
|
+
nextCounter
|
|
2392
|
+
);
|
|
2393
|
+
if (specificParentData.links) {
|
|
2394
|
+
specificParentData.links.push(nextQuestLink);
|
|
2395
|
+
}
|
|
2396
|
+
if (specificParentData.nodes) {
|
|
2397
|
+
specificParentData.nodes.push(nextQuestNode);
|
|
2398
|
+
}
|
|
2399
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2400
|
+
if (!sceneDataRef.current.links) sceneDataRef.current.links = [];
|
|
2401
|
+
sceneDataRef.current.links.push(nextQuestLink);
|
|
2402
|
+
sceneDataRef.current.quest_nodes = [...specificParentData.nodes];
|
|
2403
|
+
}
|
|
2274
2404
|
if (stateRef.current.nodeObjects[String(nodeToSave.id)]) {
|
|
2275
2405
|
const oldMeshPosition = stateRef.current.nodeObjects[String(nodeToSave.id)].position.clone();
|
|
2276
2406
|
setTimeout(() => {
|
|
2277
2407
|
if (stateRef.current && stateRef.current.graphGroup) {
|
|
2278
2408
|
const pos = oldMeshPosition.clone();
|
|
2279
2409
|
pos.x += 12;
|
|
2280
|
-
addStandaloneNodeToScene(
|
|
2410
|
+
addStandaloneNodeToScene(
|
|
2411
|
+
stateRef.current,
|
|
2412
|
+
nextQuestNode,
|
|
2413
|
+
pos,
|
|
2414
|
+
true
|
|
2415
|
+
);
|
|
2281
2416
|
}
|
|
2282
2417
|
}, 2e3);
|
|
2283
2418
|
}
|
|
2284
2419
|
}
|
|
2285
2420
|
}
|
|
2286
2421
|
try {
|
|
2287
|
-
const isView = ((_c = context.viewType) == null ? void 0 : _c.toLowerCase()) === "view";
|
|
2288
2422
|
if (isView && parentFileId === context.sceneConfigId) {
|
|
2289
2423
|
const visualNodeIndex = sceneDataRef.current.nodes.findIndex(
|
|
2290
2424
|
(n) => String(n.id) === String(nodeToSave.id)
|
|
@@ -2298,14 +2432,24 @@ var userActionHandlers = {
|
|
|
2298
2432
|
const viewFilePayload = {
|
|
2299
2433
|
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2300
2434
|
nodes: sceneDataRef.current.nodes,
|
|
2301
|
-
links: sceneDataRef.current.links
|
|
2302
|
-
|
|
2435
|
+
links: sceneDataRef.current.links
|
|
2436
|
+
};
|
|
2437
|
+
const questFilePayload = {
|
|
2438
|
+
nodes: specificParentData.nodes,
|
|
2439
|
+
links: specificParentData.links,
|
|
2440
|
+
milestones: sceneDataRef.current.milestones || []
|
|
2303
2441
|
};
|
|
2304
2442
|
await context.actions.save_view_data(
|
|
2305
2443
|
context.sceneSaveUrl,
|
|
2306
2444
|
viewFilePayload
|
|
2307
2445
|
);
|
|
2308
|
-
|
|
2446
|
+
if (context.actions.upsert_quest_firestore) {
|
|
2447
|
+
await context.actions.upsert_quest_firestore(
|
|
2448
|
+
context.ownerId,
|
|
2449
|
+
context.sceneConfigId,
|
|
2450
|
+
nodeToSave
|
|
2451
|
+
);
|
|
2452
|
+
}
|
|
2309
2453
|
} else {
|
|
2310
2454
|
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2311
2455
|
await context.actions.save_view_data(
|
|
@@ -2316,7 +2460,6 @@ var userActionHandlers = {
|
|
|
2316
2460
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2317
2461
|
if (isView && parentFileId === context.sceneConfigId) {
|
|
2318
2462
|
sceneDataRef.current.quest_nodes = [...specificParentData.nodes];
|
|
2319
|
-
sceneDataRef.current.quest_counter = specificParentData.quest_counter || sceneDataRef.current.quest_counter;
|
|
2320
2463
|
}
|
|
2321
2464
|
updateExistingNodeVisuals(stateRef.current, nodeToSave);
|
|
2322
2465
|
setters.setSceneVersion((v) => v + 1);
|
|
@@ -2373,8 +2516,7 @@ var userActionHandlers = {
|
|
|
2373
2516
|
const viewFilePayload = {
|
|
2374
2517
|
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2375
2518
|
nodes: sceneDataRef.current.nodes,
|
|
2376
|
-
links: sceneDataRef.current.links
|
|
2377
|
-
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
2519
|
+
links: sceneDataRef.current.links
|
|
2378
2520
|
};
|
|
2379
2521
|
const questFilePayload = {
|
|
2380
2522
|
nodes: specificParentData.nodes,
|
|
@@ -2385,8 +2527,13 @@ var userActionHandlers = {
|
|
|
2385
2527
|
context.sceneSaveUrl,
|
|
2386
2528
|
viewFilePayload
|
|
2387
2529
|
);
|
|
2388
|
-
|
|
2389
|
-
|
|
2530
|
+
if (context.actions.upsert_quest_link_firestore) {
|
|
2531
|
+
await context.actions.upsert_quest_link_firestore(
|
|
2532
|
+
context.ownerId,
|
|
2533
|
+
context.sceneConfigId,
|
|
2534
|
+
linkToSave
|
|
2535
|
+
);
|
|
2536
|
+
}
|
|
2390
2537
|
} else {
|
|
2391
2538
|
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2392
2539
|
await context.actions.save_view_data(
|
|
@@ -2481,7 +2628,7 @@ function createNewCustomProperty(existingProps = []) {
|
|
|
2481
2628
|
nextValue = [{ id: uuidv4(), name: "1", value: "" }];
|
|
2482
2629
|
break;
|
|
2483
2630
|
case "date":
|
|
2484
|
-
nextKey = "
|
|
2631
|
+
nextKey = "Data";
|
|
2485
2632
|
nextValue = { type: "Data", value: "" };
|
|
2486
2633
|
break;
|
|
2487
2634
|
case "number":
|
|
@@ -2735,7 +2882,7 @@ var IGNORED_KEYS = [
|
|
|
2735
2882
|
];
|
|
2736
2883
|
function extractCustomPropsFromNode(node) {
|
|
2737
2884
|
const customPropTypes = node._customPropTypes || {};
|
|
2738
|
-
return Object.keys(node).filter((k) => !IGNORED_KEYS.includes(k)).map((key) => {
|
|
2885
|
+
return Object.keys(node).filter((k) => !IGNORED_KEYS.includes(k) || customPropTypes[k]).map((key) => {
|
|
2739
2886
|
const val = node[key];
|
|
2740
2887
|
const t = customPropTypes[key] || inferPropType(val);
|
|
2741
2888
|
if (t === "date") {
|
|
@@ -3251,6 +3398,17 @@ var parseDate = (str) => {
|
|
|
3251
3398
|
}
|
|
3252
3399
|
return null;
|
|
3253
3400
|
};
|
|
3401
|
+
function extractDatePropFromNode(node) {
|
|
3402
|
+
if (!node) return null;
|
|
3403
|
+
if (node.Date) return node.Date;
|
|
3404
|
+
if (node._customPropTypes) {
|
|
3405
|
+
const dateKey = Object.keys(node._customPropTypes).find(
|
|
3406
|
+
(k) => node._customPropTypes[k] === "date"
|
|
3407
|
+
);
|
|
3408
|
+
if (dateKey && node[dateKey]) return node[dateKey];
|
|
3409
|
+
}
|
|
3410
|
+
return null;
|
|
3411
|
+
}
|
|
3254
3412
|
var parseDateProp = (dateProp) => {
|
|
3255
3413
|
let info = { isUndated: true, label: "", type: "point" };
|
|
3256
3414
|
if (!dateProp) return info;
|
|
@@ -4924,7 +5082,7 @@ function CustomPropertyDisplay({
|
|
|
4924
5082
|
links: "Links",
|
|
4925
5083
|
images: "Images",
|
|
4926
5084
|
documents: "Documents",
|
|
4927
|
-
date: "
|
|
5085
|
+
date: "Data"
|
|
4928
5086
|
};
|
|
4929
5087
|
const oldKeyIsFixed = Object.values(fixedKeyMap).includes(tempProp.key);
|
|
4930
5088
|
if (fixedKeyMap[value]) {
|
|
@@ -8789,7 +8947,7 @@ function CreateAncestryPanel({
|
|
|
8789
8947
|
}
|
|
8790
8948
|
|
|
8791
8949
|
// src/components/CreateQuestTreePanel.jsx
|
|
8792
|
-
import React11, { useState as useState12, useEffect as useEffect11, useCallback as useCallback3, useMemo as useMemo9 } from "react";
|
|
8950
|
+
import React11, { useState as useState12, useEffect as useEffect11, useCallback as useCallback3, useMemo as useMemo9, useRef as useRef9 } from "react";
|
|
8793
8951
|
import {
|
|
8794
8952
|
FiFolder as FiFolder3,
|
|
8795
8953
|
FiLayers as FiLayers6,
|
|
@@ -8906,6 +9064,7 @@ function CreateQuestTreePanel({
|
|
|
8906
9064
|
const [isSaving, setIsSaving] = useState12(false);
|
|
8907
9065
|
const [hasUnsavedChanges, setHasUnsavedChanges] = useState12(false);
|
|
8908
9066
|
const [activeTab, setActiveTab] = useState12("tree");
|
|
9067
|
+
const isInitialLoad = useRef9(true);
|
|
8909
9068
|
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
8910
9069
|
const { width: panelWidth, isResizing, handlePointerDown: handleResize } = useResizablePanel({
|
|
8911
9070
|
initialWidth: 440,
|
|
@@ -8939,10 +9098,11 @@ function CreateQuestTreePanel({
|
|
|
8939
9098
|
const indexToRemove = pathToRemove[pathToRemove.length - 1];
|
|
8940
9099
|
if (currentParent.children && currentParent.children.length > indexToRemove) {
|
|
8941
9100
|
currentParent.children.splice(indexToRemove, 1);
|
|
8942
|
-
|
|
9101
|
+
return { ...prev, [treeKey]: newTree };
|
|
8943
9102
|
}
|
|
8944
|
-
return
|
|
9103
|
+
return prev;
|
|
8945
9104
|
});
|
|
9105
|
+
setHasUnsavedChanges(true);
|
|
8946
9106
|
}, [setQuestTreeMode, activeTab]);
|
|
8947
9107
|
const handleMoveNode = (sourceId, targetId) => {
|
|
8948
9108
|
const isAbstraction = activeTab === "abstraction";
|
|
@@ -9019,6 +9179,15 @@ function CreateQuestTreePanel({
|
|
|
9019
9179
|
}));
|
|
9020
9180
|
}
|
|
9021
9181
|
}, [tree, abstraction_tree, questTreeMode.questNodeId, setQuestTreeMode]);
|
|
9182
|
+
useEffect11(() => {
|
|
9183
|
+
if (tree || abstraction_tree) {
|
|
9184
|
+
if (isInitialLoad.current) {
|
|
9185
|
+
isInitialLoad.current = false;
|
|
9186
|
+
return;
|
|
9187
|
+
}
|
|
9188
|
+
setHasUnsavedChanges(true);
|
|
9189
|
+
}
|
|
9190
|
+
}, [tree, abstraction_tree]);
|
|
9022
9191
|
return /* @__PURE__ */ React11.createElement(
|
|
9023
9192
|
"div",
|
|
9024
9193
|
{
|
|
@@ -9209,11 +9378,11 @@ function ImageViewer({ data, onClose }) {
|
|
|
9209
9378
|
}
|
|
9210
9379
|
|
|
9211
9380
|
// src/components/InSceneCreationForm.jsx
|
|
9212
|
-
import React15, { useState as useState15, useEffect as useEffect14, useRef as
|
|
9381
|
+
import React15, { useState as useState15, useEffect as useEffect14, useRef as useRef11 } from "react";
|
|
9213
9382
|
import { v4 as uuidv45 } from "uuid";
|
|
9214
9383
|
|
|
9215
9384
|
// src/components/ColorPicker.jsx
|
|
9216
|
-
import React13, { useState as useState14, useEffect as useEffect13, useRef as
|
|
9385
|
+
import React13, { useState as useState14, useEffect as useEffect13, useRef as useRef10 } from "react";
|
|
9217
9386
|
import { HexColorPicker } from "react-colorful";
|
|
9218
9387
|
import { FiHash, FiCheck as FiCheck6 } from "react-icons/fi";
|
|
9219
9388
|
var PRESET_COLORS = [
|
|
@@ -9235,7 +9404,7 @@ var PRESET_COLORS = [
|
|
|
9235
9404
|
];
|
|
9236
9405
|
function ColorPicker({ color, onChange, disabled, isCompact = false }) {
|
|
9237
9406
|
const [isOpen, setIsOpen] = useState14(false);
|
|
9238
|
-
const popoverRef =
|
|
9407
|
+
const popoverRef = useRef10(null);
|
|
9239
9408
|
useEffect13(() => {
|
|
9240
9409
|
const handleClickOutside = (event) => {
|
|
9241
9410
|
if (popoverRef.current && !popoverRef.current.contains(event.target)) {
|
|
@@ -9462,7 +9631,7 @@ function InSceneCreationForm({
|
|
|
9462
9631
|
const [isDatasetDropdownOpen, setIsDatasetDropdownOpen] = useState15(false);
|
|
9463
9632
|
const [isLoadingDocs, setIsLoadingDocs] = useState15(false);
|
|
9464
9633
|
const [docError, setDocError] = useState15(null);
|
|
9465
|
-
const datasetDropdownRef =
|
|
9634
|
+
const datasetDropdownRef = useRef11(null);
|
|
9466
9635
|
useEffect14(() => {
|
|
9467
9636
|
if (sourceNodeDatasetId) setTargetDatasetId(sourceNodeDatasetId);
|
|
9468
9637
|
}, [sourceNodeDatasetId]);
|
|
@@ -9479,7 +9648,7 @@ function InSceneCreationForm({
|
|
|
9479
9648
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
9480
9649
|
};
|
|
9481
9650
|
}, [isDatasetDropdownOpen]);
|
|
9482
|
-
const propsEndRef =
|
|
9651
|
+
const propsEndRef = useRef11(null);
|
|
9483
9652
|
const hasImages = customProps.some(
|
|
9484
9653
|
(p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value)
|
|
9485
9654
|
);
|
|
@@ -9982,7 +10151,7 @@ function InSceneCreationForm({
|
|
|
9982
10151
|
}
|
|
9983
10152
|
|
|
9984
10153
|
// src/components/InSceneVersionForm.jsx
|
|
9985
|
-
import React16, { useState as useState16, useEffect as useEffect15, useRef as
|
|
10154
|
+
import React16, { useState as useState16, useEffect as useEffect15, useRef as useRef12 } from "react";
|
|
9986
10155
|
import { v4 as uuidv46 } from "uuid";
|
|
9987
10156
|
import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize22, FiCheck as FiCheck8, FiEdit2 as FiEdit25 } from "react-icons/fi";
|
|
9988
10157
|
function InSceneVersionForm({
|
|
@@ -10014,7 +10183,7 @@ function InSceneVersionForm({
|
|
|
10014
10183
|
}
|
|
10015
10184
|
]);
|
|
10016
10185
|
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState16(false);
|
|
10017
|
-
const propsEndRef =
|
|
10186
|
+
const propsEndRef = useRef12(null);
|
|
10018
10187
|
const [useImageAsTexture, setUseImageAsTexture] = useState16(false);
|
|
10019
10188
|
const [selectedImageUrl, setSelectedImageUrl] = useState16(null);
|
|
10020
10189
|
const hasImages = customProps.some(
|
|
@@ -10298,7 +10467,7 @@ function InSceneVersionForm({
|
|
|
10298
10467
|
}
|
|
10299
10468
|
|
|
10300
10469
|
// src/components/InSceneQuestForm.jsx
|
|
10301
|
-
import React18, { useState as useState18, useRef as
|
|
10470
|
+
import React18, { useState as useState18, useRef as useRef13 } from "react";
|
|
10302
10471
|
import { v4 as uuidv47 } from "uuid";
|
|
10303
10472
|
import {
|
|
10304
10473
|
FiPlus as FiPlus7,
|
|
@@ -10537,7 +10706,7 @@ function InSceneQuestForm({
|
|
|
10537
10706
|
const [docError, setDocError] = useState18(null);
|
|
10538
10707
|
const [customProps, setCustomProps] = useState18([]);
|
|
10539
10708
|
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState18(false);
|
|
10540
|
-
const propsEndRef =
|
|
10709
|
+
const propsEndRef = useRef13(null);
|
|
10541
10710
|
const [milestoneInput, setMilestoneInput] = useState18("");
|
|
10542
10711
|
const [showMilestoneSuggestions, setShowMilestoneSuggestions] = useState18(false);
|
|
10543
10712
|
const activeMilestones = React18.useMemo(
|
|
@@ -11332,7 +11501,7 @@ function InSceneQuestForm({
|
|
|
11332
11501
|
}
|
|
11333
11502
|
|
|
11334
11503
|
// src/components/NodeDetailsPanel.jsx
|
|
11335
|
-
import React19, { useState as useState19, useEffect as useEffect16, useRef as
|
|
11504
|
+
import React19, { useState as useState19, useEffect as useEffect16, useRef as useRef14 } from "react";
|
|
11336
11505
|
import { v4 as uuidv48 } from "uuid";
|
|
11337
11506
|
import { FiPlus as FiPlus8, FiMaximize2 as FiMaximize23, FiX as FiX6, FiCheck as FiCheck10, FiImage as FiImage3, FiEdit2 as FiEdit27, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5, FiDatabase } from "react-icons/fi";
|
|
11338
11507
|
import { AiOutlineLoading3Quarters as AiOutlineLoading3Quarters3 } from "react-icons/ai";
|
|
@@ -11392,8 +11561,8 @@ function NodeDetailsPanel({
|
|
|
11392
11561
|
useEffect16(() => {
|
|
11393
11562
|
setWidth(isReadMode ? 700 : 440);
|
|
11394
11563
|
}, [isReadMode, setWidth]);
|
|
11395
|
-
const prevNodeIdRef =
|
|
11396
|
-
const propsEndRef =
|
|
11564
|
+
const prevNodeIdRef = useRef14(null);
|
|
11565
|
+
const propsEndRef = useRef14(null);
|
|
11397
11566
|
const canEdit = userRole !== "viewer";
|
|
11398
11567
|
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
11399
11568
|
const handleImageClickFromText = (url, name2) => {
|
|
@@ -11958,7 +12127,7 @@ function NodeDetailsPanel({
|
|
|
11958
12127
|
}
|
|
11959
12128
|
|
|
11960
12129
|
// src/components/QuestDetailsPanel.jsx
|
|
11961
|
-
import React21, { useState as useState20, useEffect as useEffect17, useRef as
|
|
12130
|
+
import React21, { useState as useState20, useEffect as useEffect17, useRef as useRef15 } from "react";
|
|
11962
12131
|
import { v4 as uuidv49 } from "uuid";
|
|
11963
12132
|
import { FiPlus as FiPlus9, FiX as FiX7, FiCheck as FiCheck11, FiEdit2 as FiEdit28, FiLoader as FiLoader3, FiBookOpen as FiBookOpen4, FiLink as FiLink7, FiTarget as FiTarget3, FiChevronDown as FiChevronDown7, FiUser as FiUser3, FiSearch as FiSearch7, FiRepeat as FiRepeat2, FiCalendar as FiCalendar2, FiImage as FiImage4, FiCopy as FiCopy4, FiGitBranch as FiGitBranch4 } from "react-icons/fi";
|
|
11964
12133
|
|
|
@@ -12226,8 +12395,8 @@ function QuestDetailsPanel({
|
|
|
12226
12395
|
useEffect17(() => {
|
|
12227
12396
|
setWidth(isReadMode ? 700 : 440);
|
|
12228
12397
|
}, [isReadMode, setWidth]);
|
|
12229
|
-
const prevNodeIdRef =
|
|
12230
|
-
const propsEndRef =
|
|
12398
|
+
const prevNodeIdRef = useRef15(null);
|
|
12399
|
+
const propsEndRef = useRef15(null);
|
|
12231
12400
|
const canEdit = userRole !== "viewer";
|
|
12232
12401
|
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
12233
12402
|
const handleImageClickFromText = (url, name) => {
|
|
@@ -12369,7 +12538,6 @@ function QuestDetailsPanel({
|
|
|
12369
12538
|
setIsSaving(false);
|
|
12370
12539
|
}
|
|
12371
12540
|
};
|
|
12372
|
-
const filteredCustomProps = customProps.filter((p) => p.key !== "Date" && p.key !== "Data");
|
|
12373
12541
|
const handleAddTimelineNote = async () => {
|
|
12374
12542
|
if (!noteText.trim() && noteLinks.length === 0 && noteImages.length === 0 || isSaving) return;
|
|
12375
12543
|
setIsSaving(true);
|
|
@@ -13378,7 +13546,7 @@ ${noteText}` : noteText : entry.notes,
|
|
|
13378
13546
|
}
|
|
13379
13547
|
|
|
13380
13548
|
// src/components/MultiNodeContextMenu.jsx
|
|
13381
|
-
import React22, { useLayoutEffect as useLayoutEffect3, useRef as
|
|
13549
|
+
import React22, { useLayoutEffect as useLayoutEffect3, useRef as useRef16, useState as useState21, useEffect as useEffect18 } from "react";
|
|
13382
13550
|
function MultiNodeContextMenu({
|
|
13383
13551
|
data,
|
|
13384
13552
|
userRole,
|
|
@@ -13387,7 +13555,7 @@ function MultiNodeContextMenu({
|
|
|
13387
13555
|
onDismissOtherNodes,
|
|
13388
13556
|
onDeleteNodes
|
|
13389
13557
|
}) {
|
|
13390
|
-
const menuRef =
|
|
13558
|
+
const menuRef = useRef16(null);
|
|
13391
13559
|
const [menuPos, setMenuPos] = useState21({ left: 0, top: 0 });
|
|
13392
13560
|
const [isConfirmingDelete, setIsConfirmingDelete] = useState21(false);
|
|
13393
13561
|
const ability = defineAbilityFor(userRole);
|
|
@@ -13454,7 +13622,7 @@ function MultiNodeContextMenu({
|
|
|
13454
13622
|
}
|
|
13455
13623
|
|
|
13456
13624
|
// src/components/RelationshipDetailsPanel.jsx
|
|
13457
|
-
import React23, { useState as useState22, useEffect as useEffect19, useRef as
|
|
13625
|
+
import React23, { useState as useState22, useEffect as useEffect19, useRef as useRef17, useMemo as useMemo10 } from "react";
|
|
13458
13626
|
import { v4 as uuidv410 } from "uuid";
|
|
13459
13627
|
import { FiPlus as FiPlus10, FiEdit2 as FiEdit29, FiLoader as FiLoader4, FiBookOpen as FiBookOpen5 } from "react-icons/fi";
|
|
13460
13628
|
function RelationshipDetailsPanel({
|
|
@@ -13485,7 +13653,7 @@ function RelationshipDetailsPanel({
|
|
|
13485
13653
|
const [isSaving, setIsSaving] = useState22(false);
|
|
13486
13654
|
const [isReadMode, setIsReadMode] = useState22(false);
|
|
13487
13655
|
const [hasUnsavedChanges, setHasUnsavedChanges] = useState22(false);
|
|
13488
|
-
const propsEndRef =
|
|
13656
|
+
const propsEndRef = useRef17(null);
|
|
13489
13657
|
const canEdit = useMemo10(() => {
|
|
13490
13658
|
const ability = defineAbilityFor(userRole);
|
|
13491
13659
|
return ability.can("update", "Connection");
|
|
@@ -13806,7 +13974,7 @@ function RelationshipDetailsPanel({
|
|
|
13806
13974
|
}
|
|
13807
13975
|
|
|
13808
13976
|
// src/components/RelationshipContextMenu.jsx
|
|
13809
|
-
import React24, { useLayoutEffect as useLayoutEffect4, useRef as
|
|
13977
|
+
import React24, { useLayoutEffect as useLayoutEffect4, useRef as useRef18, useState as useState23, useEffect as useEffect20, useMemo as useMemo11 } from "react";
|
|
13810
13978
|
function RelationshipContextMenu({
|
|
13811
13979
|
data,
|
|
13812
13980
|
userRole,
|
|
@@ -13816,7 +13984,7 @@ function RelationshipContextMenu({
|
|
|
13816
13984
|
onDelete,
|
|
13817
13985
|
onClose
|
|
13818
13986
|
}) {
|
|
13819
|
-
const menuRef =
|
|
13987
|
+
const menuRef = useRef18(null);
|
|
13820
13988
|
const [menuPos, setMenuPos] = useState23({ left: 0, top: 0 });
|
|
13821
13989
|
const [isConfirmingDelete, setIsConfirmingDelete] = useState23(false);
|
|
13822
13990
|
const ability = useMemo11(() => defineAbilityFor(userRole), [userRole]);
|
|
@@ -14298,7 +14466,7 @@ import React30, {
|
|
|
14298
14466
|
useState as useState28,
|
|
14299
14467
|
useMemo as useMemo13,
|
|
14300
14468
|
useEffect as useEffect24,
|
|
14301
|
-
useRef as
|
|
14469
|
+
useRef as useRef21,
|
|
14302
14470
|
useCallback as useCallback6
|
|
14303
14471
|
} from "react";
|
|
14304
14472
|
import {
|
|
@@ -14324,10 +14492,10 @@ import {
|
|
|
14324
14492
|
import { v4 as uuidv411 } from "uuid";
|
|
14325
14493
|
|
|
14326
14494
|
// src/components/RichGroupEditor.jsx
|
|
14327
|
-
import React29, { useEffect as useEffect23, useRef as
|
|
14495
|
+
import React29, { useEffect as useEffect23, useRef as useRef20, useState as useState27, useCallback as useCallback5 } from "react";
|
|
14328
14496
|
|
|
14329
14497
|
// src/components/MentionPopover.jsx
|
|
14330
|
-
import React28, { useEffect as useEffect22, useRef as
|
|
14498
|
+
import React28, { useEffect as useEffect22, useRef as useRef19, useState as useState26, useMemo as useMemo12 } from "react";
|
|
14331
14499
|
import { FiLayers as FiLayers7, FiCheckSquare as FiCheckSquare3, FiGitBranch as FiGitBranch5, FiBox } from "react-icons/fi";
|
|
14332
14500
|
var TYPE_CONFIG = {
|
|
14333
14501
|
ancestry: { Icon: FiLayers7, color: "text-indigo-400", label: "Ancestralidade" },
|
|
@@ -14337,7 +14505,7 @@ var TYPE_CONFIG = {
|
|
|
14337
14505
|
};
|
|
14338
14506
|
function MentionPopover({ query, items, position, onSelect, onClose }) {
|
|
14339
14507
|
const [activeIndex, setActiveIndex] = useState26(0);
|
|
14340
|
-
const listRef =
|
|
14508
|
+
const listRef = useRef19(null);
|
|
14341
14509
|
const filtered = useMemo12(() => {
|
|
14342
14510
|
const term = (query || "").toLowerCase().trim();
|
|
14343
14511
|
if (!term) return items.slice(0, 8);
|
|
@@ -14477,9 +14645,9 @@ var RichGroupEditor = React29.memo(function RichGroupEditor2({
|
|
|
14477
14645
|
readOnly,
|
|
14478
14646
|
placeholder
|
|
14479
14647
|
}) {
|
|
14480
|
-
const editorRef =
|
|
14481
|
-
const isMountedRef =
|
|
14482
|
-
const dismissedTriggerRef =
|
|
14648
|
+
const editorRef = useRef20(null);
|
|
14649
|
+
const isMountedRef = useRef20(false);
|
|
14650
|
+
const dismissedTriggerRef = useRef20(null);
|
|
14483
14651
|
const [mentionState, setMentionState] = useState27(null);
|
|
14484
14652
|
const [isEmpty, setIsEmpty] = useState27(true);
|
|
14485
14653
|
useEffect23(() => {
|
|
@@ -14947,7 +15115,7 @@ function Boards({
|
|
|
14947
15115
|
const [isLoaded, setIsLoaded] = useState28(false);
|
|
14948
15116
|
const [saveStatus, setSaveStatus] = useState28("idle");
|
|
14949
15117
|
const [navigationStack, setNavigationStack] = useState28([]);
|
|
14950
|
-
const lastSavedBoardItemsRef =
|
|
15118
|
+
const lastSavedBoardItemsRef = useRef21(null);
|
|
14951
15119
|
const canEdit = useMemo13(() => userRole !== "viewer", [userRole]);
|
|
14952
15120
|
const findGroupAndParent = (list, targetId, parent = null) => {
|
|
14953
15121
|
for (let i = 0; i < list.length; i++) {
|
|
@@ -15519,12 +15687,12 @@ function XViewScene({
|
|
|
15519
15687
|
get_view_members,
|
|
15520
15688
|
create_google_doc_action,
|
|
15521
15689
|
open_google_picker_action,
|
|
15522
|
-
|
|
15523
|
-
|
|
15524
|
-
|
|
15525
|
-
|
|
15526
|
-
|
|
15527
|
-
|
|
15690
|
+
upsert_quest_firestore,
|
|
15691
|
+
delete_quest_firestore,
|
|
15692
|
+
upsert_quest_link_firestore,
|
|
15693
|
+
delete_quest_link_firestore,
|
|
15694
|
+
upsert_milestone_firestore,
|
|
15695
|
+
update_view_counter
|
|
15528
15696
|
}) {
|
|
15529
15697
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
|
|
15530
15698
|
const { data: session, status } = useSession();
|
|
@@ -15598,10 +15766,10 @@ function XViewScene({
|
|
|
15598
15766
|
}
|
|
15599
15767
|
return null;
|
|
15600
15768
|
}, [ownerId, sceneConfigId]);
|
|
15601
|
-
const sceneDataRef =
|
|
15602
|
-
const parentDataRef =
|
|
15769
|
+
const sceneDataRef = useRef22(null);
|
|
15770
|
+
const parentDataRef = useRef22(null);
|
|
15603
15771
|
const graphDataRef = parentDataRef;
|
|
15604
|
-
const ancestryDataRef =
|
|
15772
|
+
const ancestryDataRef = useRef22(null);
|
|
15605
15773
|
const [isLoading, setIsLoading] = useState30(true);
|
|
15606
15774
|
const [permissionStatus, setPermissionStatus] = useState30("loading");
|
|
15607
15775
|
const [userPermissionRole, setUserPermissionRole] = useState30(null);
|
|
@@ -15690,10 +15858,10 @@ function XViewScene({
|
|
|
15690
15858
|
const [boardItems, setBoardItems] = useState30([]);
|
|
15691
15859
|
const [isSidebarOpen, setIsSidebarOpen] = useState30(false);
|
|
15692
15860
|
const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = useState30(false);
|
|
15693
|
-
const mountRef =
|
|
15694
|
-
const tooltipRef =
|
|
15695
|
-
const formRef =
|
|
15696
|
-
const stateRef =
|
|
15861
|
+
const mountRef = useRef22(null);
|
|
15862
|
+
const tooltipRef = useRef22(null);
|
|
15863
|
+
const formRef = useRef22(null);
|
|
15864
|
+
const stateRef = useRef22({
|
|
15697
15865
|
readMode: {
|
|
15698
15866
|
currentMaxIndex: 0,
|
|
15699
15867
|
progressMap: {}
|
|
@@ -16084,11 +16252,19 @@ function XViewScene({
|
|
|
16084
16252
|
}
|
|
16085
16253
|
}
|
|
16086
16254
|
Object.values(nodeObjects).forEach((mesh) => {
|
|
16087
|
-
const
|
|
16088
|
-
if (
|
|
16089
|
-
mesh.remove(
|
|
16090
|
-
if (
|
|
16091
|
-
|
|
16255
|
+
const oldTimelineLabel = mesh.getObjectByName("timelineLabel");
|
|
16256
|
+
if (oldTimelineLabel) {
|
|
16257
|
+
mesh.remove(oldTimelineLabel);
|
|
16258
|
+
if (oldTimelineLabel.material.map)
|
|
16259
|
+
oldTimelineLabel.material.map.dispose();
|
|
16260
|
+
oldTimelineLabel.material.dispose();
|
|
16261
|
+
}
|
|
16262
|
+
const oldQuestDateLabel = mesh.getObjectByName("questDateLabel");
|
|
16263
|
+
if (oldQuestDateLabel) {
|
|
16264
|
+
mesh.remove(oldQuestDateLabel);
|
|
16265
|
+
if (oldQuestDateLabel.material.map)
|
|
16266
|
+
oldQuestDateLabel.material.map.dispose();
|
|
16267
|
+
oldQuestDateLabel.material.dispose();
|
|
16092
16268
|
}
|
|
16093
16269
|
delete mesh.userData.timelineIntervalBar;
|
|
16094
16270
|
delete mesh.userData.timelineEndLabel;
|
|
@@ -16108,42 +16284,18 @@ function XViewScene({
|
|
|
16108
16284
|
return null;
|
|
16109
16285
|
};
|
|
16110
16286
|
Object.values(nodeObjects).forEach((mesh) => {
|
|
16111
|
-
const dateProp = mesh.userData
|
|
16287
|
+
const dateProp = extractDatePropFromNode(mesh.userData);
|
|
16112
16288
|
let nodeInfo = { mesh, type: "point", label: "", isUndated: true };
|
|
16113
16289
|
if (dateProp) {
|
|
16114
|
-
|
|
16115
|
-
|
|
16116
|
-
|
|
16117
|
-
|
|
16118
|
-
|
|
16119
|
-
|
|
16120
|
-
|
|
16121
|
-
|
|
16122
|
-
|
|
16123
|
-
} else if (dateProp.year) {
|
|
16124
|
-
const year = parseInt(dateProp.year, 10);
|
|
16125
|
-
if (!isNaN(year)) {
|
|
16126
|
-
const date = new Date(year, 0, 1);
|
|
16127
|
-
nodeInfo.startDate = date;
|
|
16128
|
-
nodeInfo.endDate = date;
|
|
16129
|
-
nodeInfo.label = String(year);
|
|
16130
|
-
nodeInfo.isUndated = false;
|
|
16131
|
-
allTimePoints.add(date.getTime());
|
|
16132
|
-
}
|
|
16133
|
-
} else if (dateProp.date_interval && dateProp.date_interval.start) {
|
|
16134
|
-
const startYear = parseInt(dateProp.date_interval.start, 10);
|
|
16135
|
-
const endYear = parseInt(dateProp.date_interval.end, 10) || startYear;
|
|
16136
|
-
if (!isNaN(startYear)) {
|
|
16137
|
-
const startDate = new Date(startYear, 0, 1);
|
|
16138
|
-
const endDate = new Date(endYear, 11, 31);
|
|
16139
|
-
nodeInfo.type = "interval";
|
|
16140
|
-
nodeInfo.startDate = startDate;
|
|
16141
|
-
nodeInfo.endDate = endDate;
|
|
16142
|
-
nodeInfo.label = `${startYear} - ${endYear}`;
|
|
16143
|
-
nodeInfo.isUndated = false;
|
|
16144
|
-
allTimePoints.add(startDate.getTime());
|
|
16145
|
-
allTimePoints.add(endDate.getTime());
|
|
16146
|
-
}
|
|
16290
|
+
const info = parseDateProp(dateProp);
|
|
16291
|
+
if (!info.isUndated) {
|
|
16292
|
+
nodeInfo.startDate = info.startDate;
|
|
16293
|
+
nodeInfo.endDate = info.endDate;
|
|
16294
|
+
nodeInfo.label = info.label;
|
|
16295
|
+
nodeInfo.type = info.type;
|
|
16296
|
+
nodeInfo.isUndated = false;
|
|
16297
|
+
allTimePoints.add(info.startDate.getTime());
|
|
16298
|
+
if (info.endDate) allTimePoints.add(info.endDate.getTime());
|
|
16147
16299
|
}
|
|
16148
16300
|
}
|
|
16149
16301
|
timelineNodes.push(nodeInfo);
|
|
@@ -16271,50 +16423,29 @@ function XViewScene({
|
|
|
16271
16423
|
return null;
|
|
16272
16424
|
};
|
|
16273
16425
|
versionMeshes.forEach((mesh) => {
|
|
16274
|
-
const dateProp = mesh.userData
|
|
16426
|
+
const dateProp = extractDatePropFromNode(mesh.userData);
|
|
16275
16427
|
if (!dateProp) return;
|
|
16276
|
-
|
|
16277
|
-
if (
|
|
16278
|
-
const
|
|
16279
|
-
|
|
16280
|
-
|
|
16281
|
-
|
|
16282
|
-
|
|
16283
|
-
|
|
16284
|
-
|
|
16285
|
-
|
|
16286
|
-
|
|
16287
|
-
|
|
16288
|
-
if (!isNaN(year)) {
|
|
16289
|
-
const date = new Date(year, 0, 1);
|
|
16290
|
-
nodeInfo.startDate = date;
|
|
16291
|
-
nodeInfo.endDate = date;
|
|
16292
|
-
nodeInfo.label = String(year);
|
|
16293
|
-
allTimePoints.add(date.getTime());
|
|
16294
|
-
timelineNodes.push(nodeInfo);
|
|
16295
|
-
}
|
|
16296
|
-
} else if (dateProp.date_interval && dateProp.date_interval.start) {
|
|
16297
|
-
const startYear = parseInt(dateProp.date_interval.start, 10);
|
|
16298
|
-
const endYear = parseInt(dateProp.date_interval.end, 10) || startYear;
|
|
16299
|
-
if (!isNaN(startYear)) {
|
|
16300
|
-
const startDate = new Date(startYear, 0, 1);
|
|
16301
|
-
const endDate = new Date(endYear, 11, 31);
|
|
16302
|
-
nodeInfo.type = "interval";
|
|
16303
|
-
nodeInfo.startDate = startDate;
|
|
16304
|
-
nodeInfo.endDate = endDate;
|
|
16305
|
-
nodeInfo.label = `${startYear} - ${endYear}`;
|
|
16306
|
-
allTimePoints.add(startDate.getTime());
|
|
16307
|
-
allTimePoints.add(endDate.getTime());
|
|
16308
|
-
timelineNodes.push(nodeInfo);
|
|
16309
|
-
}
|
|
16428
|
+
const info = parseDateProp(dateProp);
|
|
16429
|
+
if (!info.isUndated) {
|
|
16430
|
+
const nodeInfo = {
|
|
16431
|
+
mesh,
|
|
16432
|
+
type: info.type,
|
|
16433
|
+
startDate: info.startDate,
|
|
16434
|
+
endDate: info.endDate,
|
|
16435
|
+
label: info.label
|
|
16436
|
+
};
|
|
16437
|
+
allTimePoints.add(info.startDate.getTime());
|
|
16438
|
+
if (info.endDate) allTimePoints.add(info.endDate.getTime());
|
|
16439
|
+
timelineNodes.push(nodeInfo);
|
|
16310
16440
|
}
|
|
16311
16441
|
});
|
|
16312
16442
|
if (timelineNodes.length === 0) return;
|
|
16313
16443
|
const sortedTimePoints = Array.from(allTimePoints).sort((a, b) => a - b);
|
|
16444
|
+
const maxTimeIndex = sortedTimePoints.length - 1;
|
|
16314
16445
|
const timeToYMap = new Map(
|
|
16315
16446
|
sortedTimePoints.map((time, index) => [
|
|
16316
16447
|
time,
|
|
16317
|
-
index * TIMELINE_LAYER_SPACING_Y
|
|
16448
|
+
(index - maxTimeIndex) * TIMELINE_LAYER_SPACING_Y
|
|
16318
16449
|
])
|
|
16319
16450
|
);
|
|
16320
16451
|
timelineNodes.sort(
|
|
@@ -16322,18 +16453,38 @@ function XViewScene({
|
|
|
16322
16453
|
);
|
|
16323
16454
|
const baseX = sourceMesh.position.x + TIMELINE_NODE_SPACING_X;
|
|
16324
16455
|
const baseY = sourceMesh.position.y;
|
|
16325
|
-
const
|
|
16326
|
-
|
|
16456
|
+
const columns = [];
|
|
16457
|
+
const allFinalPoints = [sourceMesh.position.clone()];
|
|
16458
|
+
timelineNodes.forEach((node) => {
|
|
16327
16459
|
const { mesh, type, startDate, endDate, label } = node;
|
|
16328
|
-
const
|
|
16329
|
-
const
|
|
16460
|
+
const startY = timeToYMap.get(startDate.getTime());
|
|
16461
|
+
const endY = timeToYMap.get(endDate.getTime()) || startY;
|
|
16462
|
+
let foundColumn = false;
|
|
16463
|
+
for (let i = 0; i < columns.length; i++) {
|
|
16464
|
+
if (columns[i].endY < startY) {
|
|
16465
|
+
node.columnIndex = i;
|
|
16466
|
+
columns[i].endY = endY;
|
|
16467
|
+
foundColumn = true;
|
|
16468
|
+
break;
|
|
16469
|
+
}
|
|
16470
|
+
}
|
|
16471
|
+
if (!foundColumn) {
|
|
16472
|
+
node.columnIndex = columns.length;
|
|
16473
|
+
columns.push({ endY });
|
|
16474
|
+
}
|
|
16475
|
+
const x = baseX + node.columnIndex * TIMELINE_NODE_SPACING_X;
|
|
16476
|
+
const y = baseY + startY;
|
|
16477
|
+
allFinalPoints.push(new THREE3.Vector3(x, y, 0));
|
|
16478
|
+
const versionTween = new Tween2(mesh.position).to({ x, y, z: 0 }, 1500).easing(Easing2.Cubic.InOut);
|
|
16330
16479
|
tweenGroup.add(versionTween);
|
|
16331
16480
|
versionTween.start();
|
|
16332
|
-
|
|
16333
|
-
|
|
16334
|
-
|
|
16335
|
-
|
|
16336
|
-
|
|
16481
|
+
if (!mesh.getObjectByName("questDateLabel")) {
|
|
16482
|
+
const startLabelText = type === "interval" ? startDate.getFullYear().toString() : label;
|
|
16483
|
+
const startLabel = createTextSprite(startLabelText, 48);
|
|
16484
|
+
startLabel.name = "timelineLabel";
|
|
16485
|
+
startLabel.position.set(0, -2.5, 0);
|
|
16486
|
+
mesh.add(startLabel);
|
|
16487
|
+
}
|
|
16337
16488
|
if (type === "interval") {
|
|
16338
16489
|
const relativeEndY = timeToYMap.get(endDate.getTime()) - timeToYMap.get(startDate.getTime());
|
|
16339
16490
|
if (relativeEndY > 0) {
|
|
@@ -16367,7 +16518,21 @@ function XViewScene({
|
|
|
16367
16518
|
}
|
|
16368
16519
|
}
|
|
16369
16520
|
});
|
|
16370
|
-
|
|
16521
|
+
if (allFinalPoints.length > 0) {
|
|
16522
|
+
const boundingBox = new THREE3.Box3().setFromPoints(allFinalPoints);
|
|
16523
|
+
const center = new THREE3.Vector3();
|
|
16524
|
+
boundingBox.getCenter(center);
|
|
16525
|
+
const size = new THREE3.Vector3();
|
|
16526
|
+
boundingBox.getSize(size);
|
|
16527
|
+
const spread = Math.max(size.x, size.y, size.z, 1);
|
|
16528
|
+
const desiredDistance = Math.max(
|
|
16529
|
+
x_view_config.CAMERA_ZOOM_DISTANCE,
|
|
16530
|
+
spread * 1.5
|
|
16531
|
+
);
|
|
16532
|
+
const zoomFactor = x_view_config.CAMERA_ZOOM_DISTANCE / desiredDistance;
|
|
16533
|
+
tweenToTarget(center, zoomFactor);
|
|
16534
|
+
}
|
|
16535
|
+
}, [tweenToTarget]);
|
|
16371
16536
|
useEffect25(() => {
|
|
16372
16537
|
async function fetchAllData(configPath, ownerId2) {
|
|
16373
16538
|
var _a2, _b2;
|
|
@@ -16388,32 +16553,11 @@ function XViewScene({
|
|
|
16388
16553
|
focusAncestryId
|
|
16389
16554
|
);
|
|
16390
16555
|
const boardPromise = get_boards_action && session ? get_boards_action(configPath, sceneType, session, ownerId2) : Promise.resolve({ success: false, data: [] });
|
|
16391
|
-
const
|
|
16392
|
-
const [sceneResponse, boardResponse, questResponse] = await Promise.all([
|
|
16556
|
+
const [sceneResponse, boardResponse] = await Promise.all([
|
|
16393
16557
|
scenePromise,
|
|
16394
|
-
boardPromise
|
|
16395
|
-
questPromise
|
|
16558
|
+
boardPromise
|
|
16396
16559
|
]);
|
|
16397
16560
|
if ((sceneResponse == null ? void 0 : sceneResponse.success) && ((_a2 = sceneResponse.data) == null ? void 0 : _a2.scene) && ((_b2 = sceneResponse.data) == null ? void 0 : _b2.parent)) {
|
|
16398
|
-
const sceneData = sceneResponse.data.scene;
|
|
16399
|
-
let firestoreQuests = (questResponse == null ? void 0 : questResponse.success) ? questResponse.quests : [];
|
|
16400
|
-
let firestoreLinks = (questResponse == null ? void 0 : questResponse.success) ? questResponse.links : [];
|
|
16401
|
-
if (!sceneData.quests_migrated && firestoreQuests.length === 0) {
|
|
16402
|
-
const legacyQuests = sceneData.quest_nodes || [];
|
|
16403
|
-
const legacyLinks = sceneData.quest_links || [];
|
|
16404
|
-
if ((legacyQuests.length > 0 || legacyLinks.length > 0) && migrate_legacy_quests_action) {
|
|
16405
|
-
console.log(
|
|
16406
|
-
"X-View: Iniciando Lazy Migration de Quests para Firestore..."
|
|
16407
|
-
);
|
|
16408
|
-
await migrate_legacy_quests_action(ownerId2, sceneConfigId, {
|
|
16409
|
-
nodes: legacyQuests,
|
|
16410
|
-
links: legacyLinks
|
|
16411
|
-
});
|
|
16412
|
-
firestoreQuests = legacyQuests;
|
|
16413
|
-
firestoreLinks = legacyLinks;
|
|
16414
|
-
sceneData.quests_migrated = true;
|
|
16415
|
-
}
|
|
16416
|
-
}
|
|
16417
16561
|
if (focusNodeId) {
|
|
16418
16562
|
let targetNode = sceneResponse.data.scene.nodes.find(
|
|
16419
16563
|
(n) => String(n.id) === String(focusNodeId)
|
|
@@ -16435,29 +16579,10 @@ function XViewScene({
|
|
|
16435
16579
|
sceneResponse.data.scene.links = [];
|
|
16436
16580
|
}
|
|
16437
16581
|
sceneDataRef.current = {
|
|
16438
|
-
...
|
|
16439
|
-
|
|
16440
|
-
milestones: sceneData.milestones || []
|
|
16582
|
+
...sceneResponse.data.scene,
|
|
16583
|
+
milestones: sceneResponse.data.scene.milestones || []
|
|
16441
16584
|
};
|
|
16442
|
-
|
|
16443
|
-
if (currentParentData && currentParentData[sceneConfigId]) {
|
|
16444
|
-
const existingNodes = currentParentData[sceneConfigId].nodes || [];
|
|
16445
|
-
const firestoreQuestIds = new Set(firestoreQuests.map((q) => String(q.id)));
|
|
16446
|
-
const filteredExisting = existingNodes.filter(
|
|
16447
|
-
(n) => !firestoreQuestIds.has(String(n.id))
|
|
16448
|
-
);
|
|
16449
|
-
currentParentData[sceneConfigId].nodes = [
|
|
16450
|
-
...filteredExisting,
|
|
16451
|
-
...firestoreQuests
|
|
16452
|
-
];
|
|
16453
|
-
if (firestoreLinks && firestoreLinks.length > 0) {
|
|
16454
|
-
currentParentData[sceneConfigId].links = [
|
|
16455
|
-
...currentParentData[sceneConfigId].links || [],
|
|
16456
|
-
...firestoreLinks
|
|
16457
|
-
];
|
|
16458
|
-
}
|
|
16459
|
-
}
|
|
16460
|
-
parentDataRef.current = currentParentData;
|
|
16585
|
+
parentDataRef.current = sceneResponse.data.parent;
|
|
16461
16586
|
ancestryDataRef.current = sceneResponse.data.ancestry;
|
|
16462
16587
|
console.log(
|
|
16463
16588
|
"Console de sceneResponse.data.scene:",
|
|
@@ -18072,12 +18197,13 @@ function XViewScene({
|
|
|
18072
18197
|
get_scene_view_data,
|
|
18073
18198
|
upload_file: upload_file_action,
|
|
18074
18199
|
delete_file: delete_file_action,
|
|
18075
|
-
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
|
|
18079
|
-
|
|
18080
|
-
|
|
18200
|
+
// Adicionado novas importações aqui
|
|
18201
|
+
upsert_quest_firestore,
|
|
18202
|
+
delete_quest_firestore,
|
|
18203
|
+
upsert_quest_link_firestore,
|
|
18204
|
+
delete_quest_link_firestore,
|
|
18205
|
+
upsert_milestone_firestore,
|
|
18206
|
+
update_view_counter
|
|
18081
18207
|
}
|
|
18082
18208
|
};
|
|
18083
18209
|
},
|
|
@@ -18097,12 +18223,12 @@ function XViewScene({
|
|
|
18097
18223
|
get_scene_view_data,
|
|
18098
18224
|
upload_file_action,
|
|
18099
18225
|
delete_file_action,
|
|
18100
|
-
|
|
18101
|
-
|
|
18102
|
-
|
|
18103
|
-
|
|
18104
|
-
|
|
18105
|
-
|
|
18226
|
+
upsert_quest_firestore,
|
|
18227
|
+
delete_quest_firestore,
|
|
18228
|
+
upsert_quest_link_firestore,
|
|
18229
|
+
delete_quest_link_firestore,
|
|
18230
|
+
upsert_milestone_firestore,
|
|
18231
|
+
update_view_counter
|
|
18106
18232
|
]
|
|
18107
18233
|
);
|
|
18108
18234
|
const handleStartVersioning = (nodeData) => {
|
|
@@ -18308,36 +18434,30 @@ function XViewScene({
|
|
|
18308
18434
|
parentDataRef.current[sceneConfigId].nodes[parentIndex].quest_abstraction_tree = formattedAbstractionTree;
|
|
18309
18435
|
}
|
|
18310
18436
|
}
|
|
18311
|
-
const
|
|
18312
|
-
|
|
18313
|
-
|
|
18314
|
-
|
|
18315
|
-
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18324
|
-
|
|
18325
|
-
|
|
18326
|
-
|
|
18327
|
-
|
|
18328
|
-
|
|
18329
|
-
|
|
18330
|
-
|
|
18331
|
-
|
|
18332
|
-
|
|
18333
|
-
|
|
18334
|
-
setDetailsNode((prev) => ({
|
|
18335
|
-
...prev,
|
|
18336
|
-
quest_tree: formattedTree,
|
|
18337
|
-
quest_abstraction_tree: formattedAbstractionTree
|
|
18338
|
-
}));
|
|
18437
|
+
const updatedNodeData = sceneData.quest_nodes[questIndex];
|
|
18438
|
+
if (upsert_quest_firestore) {
|
|
18439
|
+
await upsert_quest_firestore(
|
|
18440
|
+
ownerId,
|
|
18441
|
+
sceneConfigId,
|
|
18442
|
+
updatedNodeData
|
|
18443
|
+
);
|
|
18444
|
+
}
|
|
18445
|
+
const nodeMesh = (_a2 = stateRef.current.nodeObjects) == null ? void 0 : _a2[String(questNodeId)];
|
|
18446
|
+
if (nodeMesh) {
|
|
18447
|
+
nodeMesh.userData = {
|
|
18448
|
+
...nodeMesh.userData,
|
|
18449
|
+
...updatedNodeData
|
|
18450
|
+
};
|
|
18451
|
+
}
|
|
18452
|
+
if (detailsNode && String(detailsNode.id) === String(questNodeId)) {
|
|
18453
|
+
setDetailsNode((prev) => ({
|
|
18454
|
+
...prev,
|
|
18455
|
+
quest_tree: formattedTree,
|
|
18456
|
+
quest_abstraction_tree: formattedAbstractionTree
|
|
18457
|
+
}));
|
|
18458
|
+
}
|
|
18459
|
+
setSceneVersion((v) => v + 1);
|
|
18339
18460
|
}
|
|
18340
|
-
setSceneVersion((v) => v + 1);
|
|
18341
18461
|
}
|
|
18342
18462
|
}
|
|
18343
18463
|
};
|
|
@@ -18386,7 +18506,6 @@ function XViewScene({
|
|
|
18386
18506
|
ownerId: ownerId2
|
|
18387
18507
|
} = context;
|
|
18388
18508
|
if (!graphDataRef2.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
|
|
18389
|
-
const currentCounter = sceneDataRef2.current.quest_counter || 1;
|
|
18390
18509
|
const newNode = {
|
|
18391
18510
|
id: short2.generate(),
|
|
18392
18511
|
...newQuestData,
|
|
@@ -18397,19 +18516,16 @@ function XViewScene({
|
|
|
18397
18516
|
graphDataRef2.current[sceneConfigId2] = { nodes: [], links: [] };
|
|
18398
18517
|
}
|
|
18399
18518
|
graphDataRef2.current[sceneConfigId2].nodes.push(newNode);
|
|
18400
|
-
const
|
|
18401
|
-
|
|
18402
|
-
quest_counter: currentCounter + 1
|
|
18403
|
-
};
|
|
18404
|
-
const questFileData = {
|
|
18405
|
-
nodes: graphDataRef2.current[sceneConfigId2].nodes,
|
|
18406
|
-
links: graphDataRef2.current[sceneConfigId2].links,
|
|
18407
|
-
milestones: sceneDataRef2.current.milestones || []
|
|
18408
|
-
};
|
|
18519
|
+
const currentCounter = sceneDataRef2.current.quest_counter || 1;
|
|
18520
|
+
const nextCounter = currentCounter + 1;
|
|
18409
18521
|
try {
|
|
18410
|
-
|
|
18411
|
-
|
|
18412
|
-
|
|
18522
|
+
if (actions.upsert_quest_firestore) {
|
|
18523
|
+
await actions.upsert_quest_firestore(ownerId2, sceneConfigId2, newNode);
|
|
18524
|
+
}
|
|
18525
|
+
if (actions.update_view_counter) {
|
|
18526
|
+
await actions.update_view_counter(ownerId2, sceneConfigId2, nextCounter);
|
|
18527
|
+
}
|
|
18528
|
+
sceneDataRef2.current.quest_counter = nextCounter;
|
|
18413
18529
|
stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
18414
18530
|
parentFileId: sceneConfigId2,
|
|
18415
18531
|
ownerId: ownerId2,
|
|
@@ -18440,84 +18556,6 @@ function XViewScene({
|
|
|
18440
18556
|
alert("Ocorreu um erro ao criar a Quest.");
|
|
18441
18557
|
}
|
|
18442
18558
|
};
|
|
18443
|
-
userActionHandlers.handleCompleteConnection = async (context, targetNodeData) => {
|
|
18444
|
-
const {
|
|
18445
|
-
stateRef: stateRef2,
|
|
18446
|
-
graphDataRef: graphDataRef2,
|
|
18447
|
-
sceneDataRef: sceneDataRef2,
|
|
18448
|
-
sceneConfigId: sceneConfigId2,
|
|
18449
|
-
sceneSaveUrl: sceneSaveUrl2,
|
|
18450
|
-
ownerId: ownerId2
|
|
18451
|
-
} = context;
|
|
18452
|
-
const { sourceNodeData } = stateRef2.current.connection;
|
|
18453
|
-
if (!graphDataRef2.current || !sceneDataRef2.current || !sourceNodeData || !targetNodeData) {
|
|
18454
|
-
userActionHandlers.handleCancelConnection(context);
|
|
18455
|
-
return;
|
|
18456
|
-
}
|
|
18457
|
-
const sourceParentInfo = getParentFileInfoForNode(
|
|
18458
|
-
graphDataRef2.current,
|
|
18459
|
-
sceneDataRef2.current,
|
|
18460
|
-
sourceNodeData.id,
|
|
18461
|
-
sceneConfigId2,
|
|
18462
|
-
ownerId2
|
|
18463
|
-
);
|
|
18464
|
-
const targetParentInfo = getParentFileInfoForNode(
|
|
18465
|
-
graphDataRef2.current,
|
|
18466
|
-
sceneDataRef2.current,
|
|
18467
|
-
targetNodeData.id,
|
|
18468
|
-
sceneConfigId2,
|
|
18469
|
-
ownerId2
|
|
18470
|
-
);
|
|
18471
|
-
let parentInfoToSave = sourceParentInfo;
|
|
18472
|
-
const isSourceQuest = sourceParentInfo.parentFileId === sceneConfigId2;
|
|
18473
|
-
const isTargetQuest = targetParentInfo.parentFileId === sceneConfigId2;
|
|
18474
|
-
if (isSourceQuest || isTargetQuest) {
|
|
18475
|
-
parentInfoToSave = { parentFileId: sceneConfigId2, ownerId: ownerId2 };
|
|
18476
|
-
}
|
|
18477
|
-
const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
|
|
18478
|
-
const newLink = {
|
|
18479
|
-
id: `link_${short2.generate()}`,
|
|
18480
|
-
source: sourceNodeData.id,
|
|
18481
|
-
target: targetNodeData.id
|
|
18482
|
-
};
|
|
18483
|
-
try {
|
|
18484
|
-
if (parentFileIdToSave === sceneConfigId2) {
|
|
18485
|
-
const specificParentData = graphDataRef2.current[sceneConfigId2];
|
|
18486
|
-
specificParentData.links.push(newLink);
|
|
18487
|
-
const viewFilePayload = {
|
|
18488
|
-
...sceneDataRef2.current,
|
|
18489
|
-
quest_counter: sceneDataRef2.current.quest_counter || 1
|
|
18490
|
-
};
|
|
18491
|
-
const questFilePayload = {
|
|
18492
|
-
nodes: specificParentData.nodes,
|
|
18493
|
-
links: specificParentData.links,
|
|
18494
|
-
milestones: sceneDataRef2.current.milestones || []
|
|
18495
|
-
};
|
|
18496
|
-
await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
|
|
18497
|
-
const questSaveUrl = sceneSaveUrl2.replace(
|
|
18498
|
-
"x_view_scenes",
|
|
18499
|
-
"x_view_quests"
|
|
18500
|
-
);
|
|
18501
|
-
await context.actions.save_view_data(questSaveUrl, questFilePayload);
|
|
18502
|
-
} else {
|
|
18503
|
-
const specificParentData = JSON.parse(
|
|
18504
|
-
JSON.stringify(graphDataRef2.current[parentFileIdToSave])
|
|
18505
|
-
);
|
|
18506
|
-
specificParentData.links.push(newLink);
|
|
18507
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
|
|
18508
|
-
await context.actions.save_view_data(
|
|
18509
|
-
filenameForSpecificParent,
|
|
18510
|
-
specificParentData
|
|
18511
|
-
);
|
|
18512
|
-
graphDataRef2.current[parentFileIdToSave] = specificParentData;
|
|
18513
|
-
}
|
|
18514
|
-
addNewLinkToScene(stateRef2.current, newLink);
|
|
18515
|
-
} catch (error) {
|
|
18516
|
-
console.error("Falha ao salvar a nova conex\xE3o:", error);
|
|
18517
|
-
alert("Ocorreu um erro ao salvar a nova conex\xE3o.");
|
|
18518
|
-
}
|
|
18519
|
-
userActionHandlers.handleCancelConnection(context);
|
|
18520
|
-
};
|
|
18521
18559
|
const handleClearAncestryVisuals = useCallback7((ancestryId) => {
|
|
18522
18560
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
18523
18561
|
const renderIndex = renderedAncestries.findIndex(
|
|
@@ -20220,24 +20258,19 @@ function XViewScene({
|
|
|
20220
20258
|
setSceneVersion((v) => v + 1);
|
|
20221
20259
|
const isView = ((_a2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _a2.toLowerCase()) === "view";
|
|
20222
20260
|
if (!isView || !save_view_data || !sceneSaveUrl) return;
|
|
20223
|
-
const sceneFileData = {
|
|
20224
|
-
...sceneDataRef.current,
|
|
20225
|
-
nodes: sceneDataRef.current.nodes || [],
|
|
20226
|
-
links: sceneDataRef.current.links || [],
|
|
20227
|
-
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
20228
|
-
};
|
|
20229
20261
|
const questFileData = {
|
|
20230
20262
|
nodes: ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || sceneDataRef.current.quest_nodes || [],
|
|
20231
20263
|
links: ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || sceneDataRef.current.quest_links || [],
|
|
20232
20264
|
milestones: newMilestones
|
|
20233
20265
|
};
|
|
20234
20266
|
try {
|
|
20235
|
-
|
|
20236
|
-
|
|
20237
|
-
|
|
20238
|
-
|
|
20239
|
-
|
|
20240
|
-
|
|
20267
|
+
if (upsert_milestone_firestore) {
|
|
20268
|
+
await upsert_milestone_firestore(
|
|
20269
|
+
ownerId,
|
|
20270
|
+
sceneConfigId,
|
|
20271
|
+
newMilestones
|
|
20272
|
+
);
|
|
20273
|
+
}
|
|
20241
20274
|
} catch (error) {
|
|
20242
20275
|
console.error("Erro ao salvar milestones:", error);
|
|
20243
20276
|
}
|
|
@@ -20245,7 +20278,7 @@ function XViewScene({
|
|
|
20245
20278
|
[sceneConfigId, sceneSaveUrl, save_view_data, viewParams == null ? void 0 : viewParams.type]
|
|
20246
20279
|
);
|
|
20247
20280
|
const handleSaveCurrentView = useCallback7(async () => {
|
|
20248
|
-
var _a2
|
|
20281
|
+
var _a2;
|
|
20249
20282
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
20250
20283
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
20251
20284
|
console.warn(
|
|
@@ -20275,23 +20308,10 @@ function XViewScene({
|
|
|
20275
20308
|
const sceneFileData = {
|
|
20276
20309
|
...sceneDataRef.current,
|
|
20277
20310
|
nodes: currentNodes,
|
|
20278
|
-
links: currentLinks
|
|
20279
|
-
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
20280
|
-
};
|
|
20281
|
-
const questFileData = {
|
|
20282
|
-
nodes: isView ? ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || [] : sceneDataRef.current.quest_nodes || [],
|
|
20283
|
-
links: isView ? ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || [] : sceneDataRef.current.quest_links || [],
|
|
20284
|
-
milestones: sceneDataRef.current.milestones || []
|
|
20311
|
+
links: currentLinks
|
|
20285
20312
|
};
|
|
20286
20313
|
try {
|
|
20287
20314
|
await save_view_data(sceneSaveUrl, sceneFileData);
|
|
20288
|
-
if (isView) {
|
|
20289
|
-
const questSaveUrl = sceneSaveUrl.replace(
|
|
20290
|
-
"x_view_scenes",
|
|
20291
|
-
"x_view_quests"
|
|
20292
|
-
);
|
|
20293
|
-
await save_view_data(questSaveUrl, questFileData);
|
|
20294
|
-
}
|
|
20295
20315
|
} catch (error) {
|
|
20296
20316
|
console.error("Erro na chamada de save_view_data:", error);
|
|
20297
20317
|
}
|
|
@@ -21154,25 +21174,40 @@ async function save_view_data_logic(db_services, filename, data) {
|
|
|
21154
21174
|
}
|
|
21155
21175
|
}
|
|
21156
21176
|
async function get_scene_view_data_logic(db_services, scene_config, owner_id, type, session, focusNodeId = null, focusAncestryId = null) {
|
|
21157
|
-
var _a, _b;
|
|
21177
|
+
var _a, _b, _c;
|
|
21158
21178
|
try {
|
|
21159
21179
|
if (!session || !session.user) {
|
|
21160
21180
|
return { success: false, error: "Usu\xE1rio n\xE3o autenticado." };
|
|
21161
21181
|
}
|
|
21162
|
-
const membershipCheck = await db_services.check_membership(
|
|
21182
|
+
const membershipCheck = await db_services.check_membership(
|
|
21183
|
+
owner_id,
|
|
21184
|
+
type,
|
|
21185
|
+
scene_config,
|
|
21186
|
+
session.user.id
|
|
21187
|
+
);
|
|
21163
21188
|
const isFullMember = membershipCheck.success && membershipCheck.isValidMember;
|
|
21164
21189
|
if (!isFullMember && !focusNodeId && !focusAncestryId) {
|
|
21165
|
-
return {
|
|
21190
|
+
return {
|
|
21191
|
+
success: false,
|
|
21192
|
+
error: "Acesso Negado: Voc\xEA n\xE3o possui permiss\xE3o para acessar este cen\xE1rio."
|
|
21193
|
+
};
|
|
21166
21194
|
}
|
|
21167
|
-
const sceneResponse = await db_services.get_file(
|
|
21195
|
+
const sceneResponse = await db_services.get_file(
|
|
21196
|
+
`x_view_scenes/${owner_id}/${scene_config}`
|
|
21197
|
+
);
|
|
21168
21198
|
if (!sceneResponse || !sceneResponse.success) {
|
|
21169
21199
|
console.error("Falha ao buscar dados da cena:", sceneResponse == null ? void 0 : sceneResponse.error);
|
|
21170
|
-
return {
|
|
21200
|
+
return {
|
|
21201
|
+
success: false,
|
|
21202
|
+
error: `N\xE3o foi poss\xEDvel carregar o arquivo da cena: ${scene_config}`
|
|
21203
|
+
};
|
|
21171
21204
|
}
|
|
21172
21205
|
const sceneData = sceneResponse.data;
|
|
21173
21206
|
const parentDbObjects = sceneData.parent_dbs || [];
|
|
21174
21207
|
if (type && type.toLowerCase().includes("database")) {
|
|
21175
|
-
const selfExists = parentDbObjects.some(
|
|
21208
|
+
const selfExists = parentDbObjects.some(
|
|
21209
|
+
(db) => String(db.db_id) === String(scene_config)
|
|
21210
|
+
);
|
|
21176
21211
|
if (!selfExists) {
|
|
21177
21212
|
parentDbObjects.push({ db_id: scene_config, owner_id });
|
|
21178
21213
|
}
|
|
@@ -21181,43 +21216,70 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21181
21216
|
const parentResponsesPromises = parentDbObjects.map(
|
|
21182
21217
|
(db_info) => db_services.get_file(`x_view_dbs/${db_info.owner_id}/${db_info.db_id}`)
|
|
21183
21218
|
);
|
|
21184
|
-
const parentResponsesResults = await Promise.allSettled(parentResponsesPromises);
|
|
21185
|
-
const parentData = {};
|
|
21186
|
-
let currentQuestNodes = [];
|
|
21187
|
-
let currentQuestLinks = [];
|
|
21188
|
-
let currentMilestones = [];
|
|
21189
21219
|
if (isView) {
|
|
21190
|
-
const
|
|
21191
|
-
|
|
21192
|
-
|
|
21193
|
-
|
|
21194
|
-
|
|
21195
|
-
|
|
21196
|
-
|
|
21197
|
-
|
|
21198
|
-
|
|
21199
|
-
|
|
21200
|
-
|
|
21201
|
-
|
|
21202
|
-
|
|
21203
|
-
|
|
21204
|
-
|
|
21205
|
-
|
|
21220
|
+
const questFetchWithMigrationPromise = (async () => {
|
|
21221
|
+
try {
|
|
21222
|
+
const questsResponse = await db_services.get_view_quests_firestore(
|
|
21223
|
+
owner_id,
|
|
21224
|
+
scene_config
|
|
21225
|
+
);
|
|
21226
|
+
if (questsResponse.success && questsResponse.hasQuests) {
|
|
21227
|
+
return {
|
|
21228
|
+
success: true,
|
|
21229
|
+
data: questsResponse.data,
|
|
21230
|
+
quest_counter: questsResponse.quest_counter
|
|
21231
|
+
};
|
|
21232
|
+
} else {
|
|
21233
|
+
const legacyResponse = await db_services.get_file(
|
|
21234
|
+
`x_view_quests/${owner_id}/${scene_config}`
|
|
21235
|
+
);
|
|
21236
|
+
if (legacyResponse.success && legacyResponse.data) {
|
|
21237
|
+
await db_services.migrate_json_to_firestore(
|
|
21238
|
+
owner_id,
|
|
21239
|
+
scene_config,
|
|
21240
|
+
legacyResponse.data,
|
|
21241
|
+
sceneData.quest_counter
|
|
21242
|
+
);
|
|
21243
|
+
legacyResponse.quest_counter = sceneData.quest_counter || 1;
|
|
21244
|
+
return legacyResponse;
|
|
21245
|
+
}
|
|
21246
|
+
return legacyResponse;
|
|
21247
|
+
}
|
|
21248
|
+
} catch (err) {
|
|
21249
|
+
return { success: false, error: err.message };
|
|
21206
21250
|
}
|
|
21207
|
-
}
|
|
21251
|
+
})();
|
|
21252
|
+
parentResponsesPromises.push(questFetchWithMigrationPromise);
|
|
21208
21253
|
}
|
|
21254
|
+
const parentResponsesResults = await Promise.allSettled(
|
|
21255
|
+
parentResponsesPromises
|
|
21256
|
+
);
|
|
21257
|
+
const parentData = {};
|
|
21258
|
+
let questDataObj = null;
|
|
21209
21259
|
for (let i = 0; i < parentResponsesResults.length; i++) {
|
|
21210
21260
|
const result = parentResponsesResults[i];
|
|
21261
|
+
if (isView && i === parentResponsesResults.length - 1) {
|
|
21262
|
+
if (result.status === "fulfilled" && ((_a = result.value) == null ? void 0 : _a.success)) {
|
|
21263
|
+
questDataObj = result.value.data;
|
|
21264
|
+
if (result.value.quest_counter !== void 0) {
|
|
21265
|
+
sceneData.quest_counter = result.value.quest_counter;
|
|
21266
|
+
}
|
|
21267
|
+
}
|
|
21268
|
+
continue;
|
|
21269
|
+
}
|
|
21211
21270
|
const db_info = parentDbObjects[i];
|
|
21212
|
-
if (result.status === "fulfilled" && ((
|
|
21271
|
+
if (result.status === "fulfilled" && ((_b = result.value) == null ? void 0 : _b.success)) {
|
|
21213
21272
|
parentData[db_info.db_id] = result.value.data;
|
|
21214
21273
|
} else {
|
|
21215
21274
|
console.warn(
|
|
21216
21275
|
`Arquivo pai n\xE3o carregado: ${db_info.db_id}. Pode ter sido deletado.`,
|
|
21217
|
-
result.status === "rejected" ? result.reason : (
|
|
21276
|
+
result.status === "rejected" ? result.reason : (_c = result.value) == null ? void 0 : _c.error
|
|
21218
21277
|
);
|
|
21219
21278
|
}
|
|
21220
21279
|
}
|
|
21280
|
+
const currentQuestNodes = (questDataObj == null ? void 0 : questDataObj.nodes) || [];
|
|
21281
|
+
const currentQuestLinks = (questDataObj == null ? void 0 : questDataObj.links) || [];
|
|
21282
|
+
const currentMilestones = (questDataObj == null ? void 0 : questDataObj.milestones) || [];
|
|
21221
21283
|
if (isView) {
|
|
21222
21284
|
parentData[scene_config] = {
|
|
21223
21285
|
dataset_name: "Quests Internas (View)",
|
|
@@ -21227,13 +21289,19 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21227
21289
|
}
|
|
21228
21290
|
const allNodes = Object.values(parentData).flatMap((db) => db.nodes || []);
|
|
21229
21291
|
const allLinks = Object.values(parentData).flatMap((db) => db.links || []);
|
|
21230
|
-
const parentNodeMap = new Map(
|
|
21231
|
-
|
|
21292
|
+
const parentNodeMap = new Map(
|
|
21293
|
+
allNodes.map((node) => [String(node.id), node])
|
|
21294
|
+
);
|
|
21295
|
+
const parentLinkMap = new Map(
|
|
21296
|
+
allLinks.map((link) => [`${link.source}-${link.target}`, link])
|
|
21297
|
+
);
|
|
21232
21298
|
const validatedNodes = (sceneData.nodes || []).map((sceneNode) => {
|
|
21233
21299
|
var _a2, _b2;
|
|
21234
21300
|
const nodeTypes = Array.isArray(sceneNode.type) ? sceneNode.type : [sceneNode.type];
|
|
21235
21301
|
if (nodeTypes.includes("quest")) {
|
|
21236
|
-
const dbQuestNode = (_b2 = (_a2 = parentData[scene_config]) == null ? void 0 : _a2.nodes) == null ? void 0 : _b2.find(
|
|
21302
|
+
const dbQuestNode = (_b2 = (_a2 = parentData[scene_config]) == null ? void 0 : _a2.nodes) == null ? void 0 : _b2.find(
|
|
21303
|
+
(qn) => String(qn.id) === String(sceneNode.id)
|
|
21304
|
+
);
|
|
21237
21305
|
if (dbQuestNode) {
|
|
21238
21306
|
return { ...sceneNode, ...dbQuestNode };
|
|
21239
21307
|
}
|
|
@@ -21245,18 +21313,22 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21245
21313
|
}
|
|
21246
21314
|
return null;
|
|
21247
21315
|
}).filter(Boolean);
|
|
21248
|
-
const validNodeIdsInScene = new Set(
|
|
21316
|
+
const validNodeIdsInScene = new Set(
|
|
21317
|
+
validatedNodes.map((node) => String(node.id))
|
|
21318
|
+
);
|
|
21249
21319
|
const validatedLinks = (sceneData.links || []).filter((sceneLink) => {
|
|
21250
|
-
const linkExistsInParent = parentLinkMap.has(
|
|
21320
|
+
const linkExistsInParent = parentLinkMap.has(
|
|
21321
|
+
`${sceneLink.source}-${sceneLink.target}`
|
|
21322
|
+
);
|
|
21251
21323
|
const nodesAreValidForScene = validNodeIdsInScene.has(String(sceneLink.source)) && validNodeIdsInScene.has(String(sceneLink.target));
|
|
21252
21324
|
return linkExistsInParent && nodesAreValidForScene;
|
|
21253
|
-
}).map(
|
|
21325
|
+
}).map(
|
|
21326
|
+
(sceneLink) => parentLinkMap.get(`${sceneLink.source}-${sceneLink.target}`)
|
|
21327
|
+
);
|
|
21254
21328
|
const validatedSceneData = {
|
|
21255
21329
|
...sceneData,
|
|
21256
21330
|
nodes: validatedNodes,
|
|
21257
21331
|
links: validatedLinks,
|
|
21258
|
-
// Re-injetando no validated para que o restante do sistema (e.g. XViewScene local state)
|
|
21259
|
-
// continue acessando as quests sem perceber a separação física
|
|
21260
21332
|
quest_nodes: currentQuestNodes,
|
|
21261
21333
|
quest_links: currentQuestLinks,
|
|
21262
21334
|
milestones: currentMilestones
|
|
@@ -21276,7 +21348,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21276
21348
|
isSceneFile: false
|
|
21277
21349
|
});
|
|
21278
21350
|
});
|
|
21279
|
-
const ancestryPromises = ancestryFilePaths.map(
|
|
21351
|
+
const ancestryPromises = ancestryFilePaths.map(
|
|
21352
|
+
(file) => db_services.get_file(file.path)
|
|
21353
|
+
);
|
|
21280
21354
|
const ancestryResults = await Promise.allSettled(ancestryPromises);
|
|
21281
21355
|
const ancestriesFromSceneFile = [];
|
|
21282
21356
|
const ancestriesFromDbFiles = [];
|
|
@@ -21302,15 +21376,21 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21302
21376
|
}
|
|
21303
21377
|
});
|
|
21304
21378
|
const ancestryMap = /* @__PURE__ */ new Map();
|
|
21305
|
-
ancestriesFromDbFiles.forEach(
|
|
21306
|
-
|
|
21379
|
+
ancestriesFromDbFiles.forEach(
|
|
21380
|
+
(anc) => ancestryMap.set(anc.ancestry_id, anc)
|
|
21381
|
+
);
|
|
21382
|
+
ancestriesFromSceneFile.forEach(
|
|
21383
|
+
(anc) => ancestryMap.set(anc.ancestry_id, anc)
|
|
21384
|
+
);
|
|
21307
21385
|
let ancestryData = Array.from(ancestryMap.values());
|
|
21308
21386
|
const externalSourcesToRefresh = /* @__PURE__ */ new Map();
|
|
21309
21387
|
ancestryData.forEach((anc) => {
|
|
21310
21388
|
const targetSourceId = anc._source_file_id || anc._imported_from_view_id;
|
|
21311
21389
|
const targetOwnerId = anc._source_owner_id || anc._imported_from_view_owner_id;
|
|
21312
21390
|
if (targetSourceId && targetSourceId !== scene_config && targetOwnerId) {
|
|
21313
|
-
const isAlreadyLoadedAsParent = parentDbObjects.some(
|
|
21391
|
+
const isAlreadyLoadedAsParent = parentDbObjects.some(
|
|
21392
|
+
(db) => String(db.db_id) === String(targetSourceId)
|
|
21393
|
+
);
|
|
21314
21394
|
if (!isAlreadyLoadedAsParent) {
|
|
21315
21395
|
const key = `${targetOwnerId}/${targetSourceId}`;
|
|
21316
21396
|
externalSourcesToRefresh.set(key, {
|
|
@@ -21351,12 +21431,16 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21351
21431
|
return false;
|
|
21352
21432
|
}
|
|
21353
21433
|
if (externalSourcesToRefresh.has(key) && successfullyFetchedSources.has(key)) {
|
|
21354
|
-
const stillExists = freshAncestryMap.has(
|
|
21434
|
+
const stillExists = freshAncestryMap.has(
|
|
21435
|
+
String(localAnc.ancestry_id)
|
|
21436
|
+
);
|
|
21355
21437
|
return stillExists;
|
|
21356
21438
|
}
|
|
21357
21439
|
return true;
|
|
21358
21440
|
}).map((localAnc) => {
|
|
21359
|
-
const freshVersion = freshAncestryMap.get(
|
|
21441
|
+
const freshVersion = freshAncestryMap.get(
|
|
21442
|
+
String(localAnc.ancestry_id)
|
|
21443
|
+
);
|
|
21360
21444
|
if (freshVersion) {
|
|
21361
21445
|
return {
|
|
21362
21446
|
...freshVersion,
|
|
@@ -21395,7 +21479,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21395
21479
|
parallel_branches: validBranches
|
|
21396
21480
|
};
|
|
21397
21481
|
};
|
|
21398
|
-
const originalAncestryDataString = JSON.stringify(
|
|
21482
|
+
const originalAncestryDataString = JSON.stringify(
|
|
21483
|
+
Array.from(ancestryMap.values())
|
|
21484
|
+
);
|
|
21399
21485
|
const cleanedAncestryData = ancestryData.map((ancestry) => {
|
|
21400
21486
|
if (!parentNodeIds.has(String(ancestry.ancestral_node))) return null;
|
|
21401
21487
|
const cleanedTree = pruneTree(ancestry.tree);
|
|
@@ -21415,7 +21501,10 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21415
21501
|
try {
|
|
21416
21502
|
await db_services.save_file(ancestryFilePath, ancestryData);
|
|
21417
21503
|
} catch (saveError) {
|
|
21418
|
-
console.error(
|
|
21504
|
+
console.error(
|
|
21505
|
+
"Falha ao salvar o arquivo de ancestralidade da cena atualizado:",
|
|
21506
|
+
saveError
|
|
21507
|
+
);
|
|
21419
21508
|
}
|
|
21420
21509
|
}
|
|
21421
21510
|
if (!isFullMember) {
|
|
@@ -21423,7 +21512,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21423
21512
|
const requiredAncestryIds = /* @__PURE__ */ new Set();
|
|
21424
21513
|
if (focusNodeId) requiredNodeIds.add(String(focusNodeId));
|
|
21425
21514
|
if (focusAncestryId) requiredAncestryIds.add(String(focusAncestryId));
|
|
21426
|
-
const allNodesFromDb = Object.values(parentData).flatMap(
|
|
21515
|
+
const allNodesFromDb = Object.values(parentData).flatMap(
|
|
21516
|
+
(db) => db.nodes || []
|
|
21517
|
+
);
|
|
21427
21518
|
const extractDependenciesFromText = (text) => {
|
|
21428
21519
|
if (!text) return;
|
|
21429
21520
|
const mentionRegex = /\[\[MENTION:node:([a-zA-Z0-9\-_]+)\]\]/g;
|
|
@@ -21450,9 +21541,12 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21450
21541
|
if (branch.linked_ancestry_id) {
|
|
21451
21542
|
requiredAncestryIds.add(String(branch.linked_ancestry_id));
|
|
21452
21543
|
}
|
|
21453
|
-
if (branch.description)
|
|
21544
|
+
if (branch.description)
|
|
21545
|
+
extractDependenciesFromText(branch.description);
|
|
21454
21546
|
if (branch.description_sections) {
|
|
21455
|
-
branch.description_sections.forEach(
|
|
21547
|
+
branch.description_sections.forEach(
|
|
21548
|
+
(s) => extractDependenciesFromText(s.content)
|
|
21549
|
+
);
|
|
21456
21550
|
}
|
|
21457
21551
|
extractTreeDependencies(branch.tree);
|
|
21458
21552
|
});
|
|
@@ -21466,7 +21560,9 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21466
21560
|
if (anc && !anc.is_private) {
|
|
21467
21561
|
if (anc.description) extractDependenciesFromText(anc.description);
|
|
21468
21562
|
if (anc.description_sections) {
|
|
21469
|
-
anc.description_sections.forEach(
|
|
21563
|
+
anc.description_sections.forEach(
|
|
21564
|
+
(s) => extractDependenciesFromText(s.content)
|
|
21565
|
+
);
|
|
21470
21566
|
}
|
|
21471
21567
|
extractTreeDependencies(anc.tree);
|
|
21472
21568
|
extractTreeDependencies(anc.abstraction_tree);
|
|
@@ -21477,22 +21573,38 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21477
21573
|
if (node) {
|
|
21478
21574
|
if (node.description) extractDependenciesFromText(node.description);
|
|
21479
21575
|
if (node.description_sections) {
|
|
21480
|
-
node.description_sections.forEach(
|
|
21576
|
+
node.description_sections.forEach(
|
|
21577
|
+
(s) => extractDependenciesFromText(s.content)
|
|
21578
|
+
);
|
|
21481
21579
|
}
|
|
21482
21580
|
}
|
|
21483
21581
|
});
|
|
21484
21582
|
} while (requiredNodeIds.size + requiredAncestryIds.size > previousSize);
|
|
21485
|
-
const restrictedSceneData = {
|
|
21583
|
+
const restrictedSceneData = {
|
|
21584
|
+
...validatedSceneData,
|
|
21585
|
+
nodes: [],
|
|
21586
|
+
links: []
|
|
21587
|
+
};
|
|
21486
21588
|
const restrictedParentData = {};
|
|
21487
|
-
const restrictedAncestryData = ancestryData.filter(
|
|
21589
|
+
const restrictedAncestryData = ancestryData.filter(
|
|
21590
|
+
(a) => requiredAncestryIds.has(String(a.ancestry_id)) && !a.is_private
|
|
21591
|
+
);
|
|
21488
21592
|
for (const [dbId, dbContent] of Object.entries(parentData)) {
|
|
21489
|
-
const filteredNodes = (dbContent.nodes || []).filter(
|
|
21593
|
+
const filteredNodes = (dbContent.nodes || []).filter(
|
|
21594
|
+
(n) => requiredNodeIds.has(String(n.id))
|
|
21595
|
+
);
|
|
21490
21596
|
if (filteredNodes.length > 0) {
|
|
21491
|
-
restrictedParentData[dbId] = {
|
|
21597
|
+
restrictedParentData[dbId] = {
|
|
21598
|
+
...dbContent,
|
|
21599
|
+
nodes: filteredNodes,
|
|
21600
|
+
links: []
|
|
21601
|
+
};
|
|
21492
21602
|
}
|
|
21493
21603
|
}
|
|
21494
21604
|
if (focusNodeId) {
|
|
21495
|
-
const mainNode = allNodesFromDb.find(
|
|
21605
|
+
const mainNode = allNodesFromDb.find(
|
|
21606
|
+
(n) => String(n.id) === String(focusNodeId)
|
|
21607
|
+
);
|
|
21496
21608
|
if (mainNode) {
|
|
21497
21609
|
restrictedSceneData.nodes = [mainNode];
|
|
21498
21610
|
}
|
|
@@ -21508,7 +21620,11 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
21508
21620
|
}
|
|
21509
21621
|
return {
|
|
21510
21622
|
success: true,
|
|
21511
|
-
data: {
|
|
21623
|
+
data: {
|
|
21624
|
+
scene: validatedSceneData,
|
|
21625
|
+
parent: parentData,
|
|
21626
|
+
ancestry: ancestryData
|
|
21627
|
+
}
|
|
21512
21628
|
};
|
|
21513
21629
|
} catch (error) {
|
|
21514
21630
|
console.error("Erro em get_scene_view_data_logic:", error);
|
|
@@ -21528,13 +21644,18 @@ async function import_parent_file_modal_get_logic(db_services, session) {
|
|
|
21528
21644
|
}
|
|
21529
21645
|
};
|
|
21530
21646
|
} catch (error) {
|
|
21531
|
-
console.error(
|
|
21647
|
+
console.error(
|
|
21648
|
+
"catch (error) em import_parent_file_modal_get_logic:",
|
|
21649
|
+
error
|
|
21650
|
+
);
|
|
21532
21651
|
return { success: false, error: error.message };
|
|
21533
21652
|
}
|
|
21534
21653
|
}
|
|
21535
21654
|
async function get_single_parent_file_logic(db_services, file_id, session) {
|
|
21536
21655
|
try {
|
|
21537
|
-
const call_GCP_cloud_storage_get_file = await db_services.get_file(
|
|
21656
|
+
const call_GCP_cloud_storage_get_file = await db_services.get_file(
|
|
21657
|
+
`x_view_dbs/${session.user.id}/${file_id}`
|
|
21658
|
+
);
|
|
21538
21659
|
return call_GCP_cloud_storage_get_file;
|
|
21539
21660
|
} catch (error) {
|
|
21540
21661
|
console.error("catch (error) em get_single_parent_file_logic:", error);
|
|
@@ -21568,7 +21689,13 @@ async function get_ancestry_file_logic(db_services, file_id, owner_id) {
|
|
|
21568
21689
|
async function save_boards_logic(db_services, scene_id, type, boardItems, session, owner_id) {
|
|
21569
21690
|
try {
|
|
21570
21691
|
const targetOwnerId = owner_id || session.user.id;
|
|
21571
|
-
return await db_services.save_boards(
|
|
21692
|
+
return await db_services.save_boards(
|
|
21693
|
+
session,
|
|
21694
|
+
scene_id,
|
|
21695
|
+
type,
|
|
21696
|
+
boardItems,
|
|
21697
|
+
targetOwnerId
|
|
21698
|
+
);
|
|
21572
21699
|
} catch (error) {
|
|
21573
21700
|
console.error("Erro em save_boards_logic:", error);
|
|
21574
21701
|
return { success: false, error: error.message };
|
|
@@ -21597,7 +21724,10 @@ async function delete_uploaded_file_logic(db_services, fileUrl) {
|
|
|
21597
21724
|
async function get_view_members_logic(db_services, ownerId, type, itemId) {
|
|
21598
21725
|
try {
|
|
21599
21726
|
if (!db_services.get_view_members) {
|
|
21600
|
-
return {
|
|
21727
|
+
return {
|
|
21728
|
+
success: false,
|
|
21729
|
+
error: "Servi\xE7o de busca de membros n\xE3o configurado."
|
|
21730
|
+
};
|
|
21601
21731
|
}
|
|
21602
21732
|
return await db_services.get_view_members(ownerId, type, itemId);
|
|
21603
21733
|
} catch (error) {
|