@lv-x-software-house/x_view 1.2.4-dev.2 → 1.2.4-dev.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +481 -176
- package/dist/index.mjs +488 -183
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1181,8 +1181,6 @@ var createMultipleLinkLines = (linksArray, sourceNodeMesh, targetNodeMesh, resol
|
|
|
1181
1181
|
targetNodeMesh,
|
|
1182
1182
|
resolution,
|
|
1183
1183
|
isCurved,
|
|
1184
|
-
isCurved,
|
|
1185
|
-
isCurved,
|
|
1186
1184
|
curveOffset
|
|
1187
1185
|
);
|
|
1188
1186
|
line.userData = {
|
|
@@ -1515,7 +1513,7 @@ var addStandaloneNodeToScene = (state, nodeData, position) => {
|
|
|
1515
1513
|
scaleTween.start();
|
|
1516
1514
|
}
|
|
1517
1515
|
};
|
|
1518
|
-
var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
|
|
1516
|
+
var getParentFileInfoForNode = (allParentData, sceneData, nodeId, sceneConfigId = null, sceneOwnerId = null) => {
|
|
1519
1517
|
const parentDbsArray = (sceneData == null ? void 0 : sceneData.parent_dbs) || [];
|
|
1520
1518
|
for (const parentFileId in allParentData) {
|
|
1521
1519
|
if (allParentData.hasOwnProperty(parentFileId)) {
|
|
@@ -1524,6 +1522,8 @@ var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
|
|
|
1524
1522
|
const parentDbInfo = parentDbsArray.find((db) => String(db.db_id) === String(parentFileId));
|
|
1525
1523
|
if (parentDbInfo) {
|
|
1526
1524
|
return { parentFileId, ownerId: parentDbInfo.owner_id };
|
|
1525
|
+
} else if (sceneConfigId && String(parentFileId) === String(sceneConfigId)) {
|
|
1526
|
+
return { parentFileId, ownerId: sceneOwnerId };
|
|
1527
1527
|
} else {
|
|
1528
1528
|
console.warn(`Owner ID n\xE3o encontrado em sceneData.parent_dbs para o parentFileId: ${parentFileId}`);
|
|
1529
1529
|
return { parentFileId, ownerId: null };
|
|
@@ -1793,6 +1793,7 @@ var userActionHandlers = {
|
|
|
1793
1793
|
setters.setFormPosition((p) => ({ ...p, opacity: 0 }));
|
|
1794
1794
|
},
|
|
1795
1795
|
handleSaveVersionNode: async (context, newNodeData) => {
|
|
1796
|
+
var _a;
|
|
1796
1797
|
const { graphDataRef, sceneDataRef, stateRef, versionMode, setters } = context;
|
|
1797
1798
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
1798
1799
|
const { sourceNodeData } = versionMode;
|
|
@@ -1802,7 +1803,7 @@ var userActionHandlers = {
|
|
|
1802
1803
|
version_node: { is_version: true, parent_node: sourceNodeData.id }
|
|
1803
1804
|
};
|
|
1804
1805
|
const newLink = { id: `link_${short.generate()}`, source: sourceNodeData.id, target: newNode.id };
|
|
1805
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
|
|
1806
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
|
|
1806
1807
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
1807
1808
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:", sourceNodeData.id);
|
|
1808
1809
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
|
|
@@ -1812,9 +1813,21 @@ var userActionHandlers = {
|
|
|
1812
1813
|
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
|
|
1813
1814
|
specificParentData.nodes.push(newNode);
|
|
1814
1815
|
specificParentData.links.push(newLink);
|
|
1815
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
1816
1816
|
try {
|
|
1817
|
-
|
|
1817
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
1818
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
1819
|
+
const viewFilePayload = {
|
|
1820
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
1821
|
+
nodes: sceneDataRef.current.nodes,
|
|
1822
|
+
links: sceneDataRef.current.links,
|
|
1823
|
+
quest_nodes: specificParentData.nodes,
|
|
1824
|
+
quest_links: specificParentData.links
|
|
1825
|
+
};
|
|
1826
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
1827
|
+
} else {
|
|
1828
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
1829
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
1830
|
+
}
|
|
1818
1831
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
1819
1832
|
const finalPosition = stateRef.current.ghostElements.node.position.clone();
|
|
1820
1833
|
addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
|
|
@@ -1838,10 +1851,6 @@ var userActionHandlers = {
|
|
|
1838
1851
|
var _a;
|
|
1839
1852
|
const isSource = String(link.source) === String(sourceNode.id);
|
|
1840
1853
|
const targetNodeId = isSource ? link.target : link.source;
|
|
1841
|
-
const linkAlreadyInSceneData = sceneDataRef.current.links.some((l) => String(l.id) === String(link.id));
|
|
1842
|
-
if (!linkAlreadyInSceneData) {
|
|
1843
|
-
sceneDataRef.current.links.push(link);
|
|
1844
|
-
}
|
|
1845
1854
|
if (!nodeObjects[String(targetNodeId)]) {
|
|
1846
1855
|
const allParentNodes = Object.values(graphDataRef.current).flatMap((fileData) => fileData.nodes);
|
|
1847
1856
|
const nodeData = allParentNodes.find((n) => String(n.id) === String(targetNodeId));
|
|
@@ -1849,9 +1858,6 @@ var userActionHandlers = {
|
|
|
1849
1858
|
console.warn(`Dados do Node com ID ${targetNodeId} n\xE3o encontrados no cache.`);
|
|
1850
1859
|
return;
|
|
1851
1860
|
}
|
|
1852
|
-
if (!sceneDataRef.current.nodes.some((n) => String(n.id) === String(nodeData.id))) {
|
|
1853
|
-
sceneDataRef.current.nodes.push(nodeData);
|
|
1854
|
-
}
|
|
1855
1861
|
const startPosition = sourceNodeMesh.position.clone();
|
|
1856
1862
|
const endPosition = startPosition.clone().add(
|
|
1857
1863
|
new THREE.Vector3((Math.random() - 0.5) * 60, (Math.random() - 0.5) * 15, (Math.random() - 0.5) * 60)
|
|
@@ -1971,6 +1977,7 @@ var userActionHandlers = {
|
|
|
1971
1977
|
if (mountRef.current) mountRef.current.style.cursor = "grab";
|
|
1972
1978
|
},
|
|
1973
1979
|
handleCompleteConnection: async (context, targetNodeData) => {
|
|
1980
|
+
var _a;
|
|
1974
1981
|
const { stateRef, graphDataRef, sceneDataRef } = context;
|
|
1975
1982
|
const { sourceNodeData } = stateRef.current.connection;
|
|
1976
1983
|
if (!graphDataRef.current || !sceneDataRef.current || !sourceNodeData || !targetNodeData) {
|
|
@@ -1978,7 +1985,7 @@ var userActionHandlers = {
|
|
|
1978
1985
|
userActionHandlers.handleCancelConnection(context);
|
|
1979
1986
|
return;
|
|
1980
1987
|
}
|
|
1981
|
-
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
|
|
1988
|
+
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
|
|
1982
1989
|
if (!sourceParentInfo || !sourceParentInfo.ownerId) {
|
|
1983
1990
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:", sourceNodeData.id);
|
|
1984
1991
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
|
|
@@ -1993,12 +2000,26 @@ var userActionHandlers = {
|
|
|
1993
2000
|
source: sourceNodeData.id,
|
|
1994
2001
|
target: targetNodeData.id
|
|
1995
2002
|
};
|
|
1996
|
-
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
|
|
1997
|
-
specificParentData.links.push(newLink);
|
|
1998
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
|
|
1999
2003
|
try {
|
|
2000
|
-
|
|
2001
|
-
|
|
2004
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2005
|
+
if (isView && parentFileIdToSave === context.sceneConfigId) {
|
|
2006
|
+
const specificParentData = graphDataRef.current[context.sceneConfigId];
|
|
2007
|
+
specificParentData.links.push(newLink);
|
|
2008
|
+
const viewFilePayload = {
|
|
2009
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2010
|
+
nodes: sceneDataRef.current.nodes,
|
|
2011
|
+
links: sceneDataRef.current.links,
|
|
2012
|
+
quest_nodes: specificParentData.nodes,
|
|
2013
|
+
quest_links: specificParentData.links
|
|
2014
|
+
};
|
|
2015
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2016
|
+
} else {
|
|
2017
|
+
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
|
|
2018
|
+
specificParentData.links.push(newLink);
|
|
2019
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
|
|
2020
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
2021
|
+
graphDataRef.current[parentFileIdToSave] = specificParentData;
|
|
2022
|
+
}
|
|
2002
2023
|
addNewLinkToScene(stateRef.current, newLink);
|
|
2003
2024
|
} catch (error) {
|
|
2004
2025
|
console.error("Falha ao salvar a nova conex\xE3o:", error);
|
|
@@ -2067,14 +2088,28 @@ var userActionHandlers = {
|
|
|
2067
2088
|
} else {
|
|
2068
2089
|
newTargetId = newEndNodeData.id;
|
|
2069
2090
|
}
|
|
2070
|
-
const
|
|
2071
|
-
const
|
|
2072
|
-
|
|
2073
|
-
|
|
2091
|
+
const oldSourceInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId, context.sceneConfigId, context.ownerId);
|
|
2092
|
+
const oldTargetInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldTargetId, context.sceneConfigId, context.ownerId);
|
|
2093
|
+
const newSourceInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId, context.sceneConfigId, context.ownerId);
|
|
2094
|
+
const newTargetInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newTargetId, context.sceneConfigId, context.ownerId);
|
|
2095
|
+
if (!oldSourceInfo || !oldTargetInfo || !newSourceInfo || !newTargetInfo) {
|
|
2096
|
+
console.error("Informa\xE7\xF5es dos arquivos pai incompletas para o relink.");
|
|
2074
2097
|
alert("Ocorreu um erro ao identificar os arquivos pai para salvar a altera\xE7\xE3o.");
|
|
2075
2098
|
userActionHandlers.handleCancelRelink(context);
|
|
2076
2099
|
return;
|
|
2077
2100
|
}
|
|
2101
|
+
let oldGoverningFileId = oldSourceInfo.parentFileId;
|
|
2102
|
+
let oldGoverningOwnerId = oldSourceInfo.ownerId;
|
|
2103
|
+
if (oldSourceInfo.parentFileId === context.sceneConfigId || oldTargetInfo.parentFileId === context.sceneConfigId) {
|
|
2104
|
+
oldGoverningFileId = context.sceneConfigId;
|
|
2105
|
+
oldGoverningOwnerId = context.ownerId;
|
|
2106
|
+
}
|
|
2107
|
+
let newGoverningFileId = newSourceInfo.parentFileId;
|
|
2108
|
+
let newGoverningOwnerId = newSourceInfo.ownerId;
|
|
2109
|
+
if (newSourceInfo.parentFileId === context.sceneConfigId || newTargetInfo.parentFileId === context.sceneConfigId) {
|
|
2110
|
+
newGoverningFileId = context.sceneConfigId;
|
|
2111
|
+
newGoverningOwnerId = context.ownerId;
|
|
2112
|
+
}
|
|
2078
2113
|
const { sourceNode, targetNode, ...dataToKeep } = originalLinkData;
|
|
2079
2114
|
const newLinkData = {
|
|
2080
2115
|
...dataToKeep,
|
|
@@ -2082,34 +2117,44 @@ var userActionHandlers = {
|
|
|
2082
2117
|
target: newTargetId,
|
|
2083
2118
|
id: linkId
|
|
2084
2119
|
};
|
|
2120
|
+
const saveParentData = async (fileId, fileOwnerId, data) => {
|
|
2121
|
+
var _a;
|
|
2122
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2123
|
+
if (isView && fileId === context.sceneConfigId) {
|
|
2124
|
+
const viewFilePayload = {
|
|
2125
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2126
|
+
nodes: sceneDataRef.current.nodes,
|
|
2127
|
+
links: sceneDataRef.current.links,
|
|
2128
|
+
quest_nodes: data.nodes,
|
|
2129
|
+
quest_links: data.links
|
|
2130
|
+
};
|
|
2131
|
+
return context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2132
|
+
} else {
|
|
2133
|
+
return context.actions.save_view_data(`x_view_dbs/${fileOwnerId}/${fileId}`, data);
|
|
2134
|
+
}
|
|
2135
|
+
};
|
|
2085
2136
|
const savePromises = [];
|
|
2086
2137
|
const filesToUpdate = {};
|
|
2087
|
-
if (
|
|
2088
|
-
const updatedOriginalParentData = JSON.parse(JSON.stringify(graphDataRef.current[
|
|
2138
|
+
if (oldGoverningFileId !== newGoverningFileId) {
|
|
2139
|
+
const updatedOriginalParentData = JSON.parse(JSON.stringify(graphDataRef.current[oldGoverningFileId]));
|
|
2089
2140
|
updatedOriginalParentData.links = updatedOriginalParentData.links.filter(
|
|
2090
2141
|
(l) => String(l.id) !== String(linkId)
|
|
2091
2142
|
);
|
|
2092
|
-
filesToUpdate[
|
|
2093
|
-
savePromises.push(
|
|
2094
|
-
|
|
2095
|
-
);
|
|
2096
|
-
const updatedNewParentData = JSON.parse(JSON.stringify(graphDataRef.current[newParentInfo.parentFileId]));
|
|
2143
|
+
filesToUpdate[oldGoverningFileId] = updatedOriginalParentData;
|
|
2144
|
+
savePromises.push(saveParentData(oldGoverningFileId, oldGoverningOwnerId, updatedOriginalParentData));
|
|
2145
|
+
const updatedNewParentData = JSON.parse(JSON.stringify(graphDataRef.current[newGoverningFileId]));
|
|
2097
2146
|
if (!updatedNewParentData.links) updatedNewParentData.links = [];
|
|
2098
2147
|
updatedNewParentData.links.push(newLinkData);
|
|
2099
|
-
filesToUpdate[
|
|
2100
|
-
savePromises.push(
|
|
2101
|
-
context.actions.save_view_data(`x_view_dbs/${newParentInfo.ownerId}/${newParentInfo.parentFileId}`, updatedNewParentData)
|
|
2102
|
-
);
|
|
2148
|
+
filesToUpdate[newGoverningFileId] = updatedNewParentData;
|
|
2149
|
+
savePromises.push(saveParentData(newGoverningFileId, newGoverningOwnerId, updatedNewParentData));
|
|
2103
2150
|
} else {
|
|
2104
|
-
const updatedParentData = JSON.parse(JSON.stringify(graphDataRef.current[
|
|
2151
|
+
const updatedParentData = JSON.parse(JSON.stringify(graphDataRef.current[oldGoverningFileId]));
|
|
2105
2152
|
updatedParentData.links = updatedParentData.links.filter(
|
|
2106
2153
|
(l) => String(l.id) !== String(linkId)
|
|
2107
2154
|
);
|
|
2108
2155
|
updatedParentData.links.push(newLinkData);
|
|
2109
|
-
filesToUpdate[
|
|
2110
|
-
savePromises.push(
|
|
2111
|
-
context.actions.save_view_data(`x_view_dbs/${originalParentInfo.ownerId}/${originalParentInfo.parentFileId}`, updatedParentData)
|
|
2112
|
-
);
|
|
2156
|
+
filesToUpdate[oldGoverningFileId] = updatedParentData;
|
|
2157
|
+
savePromises.push(saveParentData(oldGoverningFileId, oldGoverningOwnerId, updatedParentData));
|
|
2113
2158
|
}
|
|
2114
2159
|
try {
|
|
2115
2160
|
await Promise.all(savePromises);
|
|
@@ -2127,7 +2172,7 @@ var userActionHandlers = {
|
|
|
2127
2172
|
}
|
|
2128
2173
|
},
|
|
2129
2174
|
handleDeleteLink: async (context, linkObject) => {
|
|
2130
|
-
var _a, _b, _c, _d, _e, _f;
|
|
2175
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2131
2176
|
const { stateRef, graphDataRef, sceneDataRef, setters } = context;
|
|
2132
2177
|
setters.setRelationshipMenu({ visible: false });
|
|
2133
2178
|
if (!(linkObject == null ? void 0 : linkObject.userData) || !graphDataRef.current || !sceneDataRef.current) return;
|
|
@@ -2136,7 +2181,7 @@ var userActionHandlers = {
|
|
|
2136
2181
|
console.error("Tentativa de deletar um link sem ID.", linkObject.userData);
|
|
2137
2182
|
return;
|
|
2138
2183
|
}
|
|
2139
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source);
|
|
2184
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source, context.sceneConfigId, context.ownerId);
|
|
2140
2185
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2141
2186
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link:", linkIdToDelete);
|
|
2142
2187
|
alert("Ocorreu um erro ao identificar o arquivo pai da rela\xE7\xE3o para exclus\xE3o.");
|
|
@@ -2148,9 +2193,25 @@ var userActionHandlers = {
|
|
|
2148
2193
|
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
|
|
2149
2194
|
const newLinks = (specificParentData.links || []).filter((l) => String(l.id) !== String(linkIdToDelete));
|
|
2150
2195
|
specificParentData.links = newLinks;
|
|
2151
|
-
|
|
2196
|
+
let filenameToSave;
|
|
2197
|
+
let payloadToSave;
|
|
2198
|
+
const isView = ((_g = context.viewType) == null ? void 0 : _g.toLowerCase()) === "view";
|
|
2199
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2200
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2201
|
+
sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => String(l.id) !== String(linkIdToDelete));
|
|
2202
|
+
payloadToSave = {
|
|
2203
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2204
|
+
nodes: sceneDataRef.current.nodes,
|
|
2205
|
+
links: sceneDataRef.current.links,
|
|
2206
|
+
quest_nodes: specificParentData.nodes,
|
|
2207
|
+
quest_links: specificParentData.links
|
|
2208
|
+
};
|
|
2209
|
+
} else {
|
|
2210
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2211
|
+
payloadToSave = specificParentData;
|
|
2212
|
+
}
|
|
2152
2213
|
try {
|
|
2153
|
-
await context.actions.save_view_data(
|
|
2214
|
+
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2154
2215
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2155
2216
|
setters.setDetailsLink((prev) => String(prev == null ? void 0 : prev.id) === String(linkIdToDelete) ? null : prev);
|
|
2156
2217
|
if (stateRef.current.hoveredLink === linkObject) {
|
|
@@ -2168,12 +2229,6 @@ var userActionHandlers = {
|
|
|
2168
2229
|
if (!nodeData || !sceneDataRef.current) return;
|
|
2169
2230
|
const nodeIdToDismiss = nodeData.id;
|
|
2170
2231
|
const strNodeId = String(nodeIdToDismiss);
|
|
2171
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2172
|
-
(n) => String(n.id) !== strNodeId
|
|
2173
|
-
);
|
|
2174
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2175
|
-
(l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId
|
|
2176
|
-
);
|
|
2177
2232
|
const { ancestryGroup, ancestryLinks } = stateRef.current;
|
|
2178
2233
|
if (ancestryGroup && ancestryLinks) {
|
|
2179
2234
|
const remainingAncestryLinks = [];
|
|
@@ -2215,22 +2270,12 @@ var userActionHandlers = {
|
|
|
2215
2270
|
removeNodeFromScene(stateRef.current, nodeId);
|
|
2216
2271
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
|
|
2217
2272
|
});
|
|
2218
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2219
|
-
(n) => String(n.id) === strNodeIdToKeep
|
|
2220
|
-
);
|
|
2221
|
-
sceneDataRef.current.links = [];
|
|
2222
2273
|
},
|
|
2223
2274
|
handleDismissMultipleNodes: (context, nodeIds) => {
|
|
2224
2275
|
const { stateRef, sceneDataRef, setters } = context;
|
|
2225
2276
|
setters.setMultiContextMenu({ visible: false });
|
|
2226
2277
|
if (!nodeIds || nodeIds.size === 0 || !sceneDataRef.current) return;
|
|
2227
2278
|
const strNodeIds = Array.from(nodeIds).map(String);
|
|
2228
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2229
|
-
(n) => !strNodeIds.includes(String(n.id))
|
|
2230
|
-
);
|
|
2231
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2232
|
-
(l) => !strNodeIds.includes(String(l.source)) && !strNodeIds.includes(String(l.target))
|
|
2233
|
-
);
|
|
2234
2279
|
const { ancestryGroup, ancestryLinks } = stateRef.current;
|
|
2235
2280
|
if (ancestryGroup && ancestryLinks) {
|
|
2236
2281
|
const remainingAncestryLinks = [];
|
|
@@ -2286,15 +2331,10 @@ var userActionHandlers = {
|
|
|
2286
2331
|
removeNodeFromScene(stateRef.current, nodeId);
|
|
2287
2332
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
|
|
2288
2333
|
});
|
|
2289
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2290
|
-
(n) => strNodeIdsToKeep.includes(String(n.id))
|
|
2291
|
-
);
|
|
2292
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2293
|
-
(l) => strNodeIdsToKeep.includes(String(l.source)) && strNodeIdsToKeep.includes(String(l.target))
|
|
2294
|
-
);
|
|
2295
2334
|
stateRef.current.selectedNodes.clear();
|
|
2296
2335
|
},
|
|
2297
2336
|
handleDeleteMultipleNodes: async (context, nodeIds) => {
|
|
2337
|
+
var _a;
|
|
2298
2338
|
const { stateRef, graphDataRef, sceneDataRef, setters, actions } = context;
|
|
2299
2339
|
setters.setMultiContextMenu({ visible: false });
|
|
2300
2340
|
if (!nodeIds || nodeIds.size === 0 || !graphDataRef.current || !sceneDataRef.current) return;
|
|
@@ -2313,7 +2353,7 @@ var userActionHandlers = {
|
|
|
2313
2353
|
}
|
|
2314
2354
|
const changesByParentFile = {};
|
|
2315
2355
|
for (const nodeId of strNodeIdsToDelete) {
|
|
2316
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId);
|
|
2356
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId, context.sceneConfigId, context.ownerId);
|
|
2317
2357
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2318
2358
|
console.warn(`Node com ID ${nodeId} n\xE3o encontrado ou sem ownerId. Ignorando.`);
|
|
2319
2359
|
continue;
|
|
@@ -2347,8 +2387,27 @@ var userActionHandlers = {
|
|
|
2347
2387
|
originalData.links = (originalData.links || []).filter(
|
|
2348
2388
|
(l) => !linksToDelete.has(String(l.id))
|
|
2349
2389
|
);
|
|
2350
|
-
|
|
2351
|
-
|
|
2390
|
+
let filenameToSave;
|
|
2391
|
+
let payloadToSave;
|
|
2392
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2393
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2394
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2395
|
+
const strNodesToDelete = Array.from(nodesToDelete).map(String);
|
|
2396
|
+
const strLinksToDelete = Array.from(linksToDelete).map(String);
|
|
2397
|
+
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter((n) => !strNodesToDelete.includes(String(n.id)));
|
|
2398
|
+
sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => !strLinksToDelete.includes(String(l.id)));
|
|
2399
|
+
payloadToSave = {
|
|
2400
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2401
|
+
nodes: sceneDataRef.current.nodes,
|
|
2402
|
+
links: sceneDataRef.current.links,
|
|
2403
|
+
quest_nodes: originalData.nodes,
|
|
2404
|
+
quest_links: originalData.links
|
|
2405
|
+
};
|
|
2406
|
+
} else {
|
|
2407
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2408
|
+
payloadToSave = originalData;
|
|
2409
|
+
}
|
|
2410
|
+
savePromises.push(context.actions.save_view_data(filenameToSave, payloadToSave));
|
|
2352
2411
|
updatedParentDataCache[parentFileId] = originalData;
|
|
2353
2412
|
}
|
|
2354
2413
|
}
|
|
@@ -2369,6 +2428,7 @@ var userActionHandlers = {
|
|
|
2369
2428
|
}
|
|
2370
2429
|
},
|
|
2371
2430
|
handleDeleteNode: async (context, nodeData) => {
|
|
2431
|
+
var _a;
|
|
2372
2432
|
const { stateRef, graphDataRef, sceneDataRef, setters, actions } = context;
|
|
2373
2433
|
if (actions.delete_file && nodeData) {
|
|
2374
2434
|
const urls = extractFileUrlsFromProperties(nodeData);
|
|
@@ -2380,7 +2440,7 @@ var userActionHandlers = {
|
|
|
2380
2440
|
if (!nodeData || !graphDataRef.current || !sceneDataRef.current) return;
|
|
2381
2441
|
const nodeIdToDelete = nodeData.id;
|
|
2382
2442
|
const strNodeId = String(nodeIdToDelete);
|
|
2383
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete);
|
|
2443
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete, context.sceneConfigId, context.ownerId);
|
|
2384
2444
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2385
2445
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node a ser exclu\xEDdo:", nodeIdToDelete);
|
|
2386
2446
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para exclus\xE3o.");
|
|
@@ -2392,9 +2452,28 @@ var userActionHandlers = {
|
|
|
2392
2452
|
const newLinks = (specificParentData.links || []).filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
|
|
2393
2453
|
specificParentData.nodes = newNodes;
|
|
2394
2454
|
specificParentData.links = newLinks;
|
|
2395
|
-
|
|
2455
|
+
let filenameToSave;
|
|
2456
|
+
let payloadToSave;
|
|
2457
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2458
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2459
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2460
|
+
const newVisualNodes = sceneDataRef.current.nodes.filter((n) => String(n.id) !== strNodeId);
|
|
2461
|
+
const newVisualLinks = sceneDataRef.current.links.filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
|
|
2462
|
+
sceneDataRef.current.nodes = newVisualNodes;
|
|
2463
|
+
sceneDataRef.current.links = newVisualLinks;
|
|
2464
|
+
payloadToSave = {
|
|
2465
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2466
|
+
nodes: newVisualNodes,
|
|
2467
|
+
links: newVisualLinks,
|
|
2468
|
+
quest_nodes: specificParentData.nodes,
|
|
2469
|
+
quest_links: specificParentData.links
|
|
2470
|
+
};
|
|
2471
|
+
} else {
|
|
2472
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2473
|
+
payloadToSave = specificParentData;
|
|
2474
|
+
}
|
|
2396
2475
|
try {
|
|
2397
|
-
await context.actions.save_view_data(
|
|
2476
|
+
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2398
2477
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2399
2478
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeIdToDelete) ? null : prev);
|
|
2400
2479
|
removeNodeFromScene(stateRef.current, nodeIdToDelete);
|
|
@@ -2405,10 +2484,11 @@ var userActionHandlers = {
|
|
|
2405
2484
|
}
|
|
2406
2485
|
},
|
|
2407
2486
|
handleSaveNodeDetails: async (context, updatedNode, keepOpen = false) => {
|
|
2487
|
+
var _a;
|
|
2408
2488
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2409
2489
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2410
2490
|
const { _baseEmissiveIntensity: ignored, ...nodeToSave } = updatedNode;
|
|
2411
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id);
|
|
2491
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id, context.sceneConfigId, context.ownerId);
|
|
2412
2492
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2413
2493
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node a ser atualizado:", nodeToSave.id);
|
|
2414
2494
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
|
|
@@ -2424,9 +2504,21 @@ var userActionHandlers = {
|
|
|
2424
2504
|
alert("Erro interno: Node n\xE3o encontrado para salvar.");
|
|
2425
2505
|
return;
|
|
2426
2506
|
}
|
|
2427
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2428
2507
|
try {
|
|
2429
|
-
|
|
2508
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2509
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2510
|
+
const viewFilePayload = {
|
|
2511
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2512
|
+
nodes: sceneDataRef.current.nodes,
|
|
2513
|
+
links: sceneDataRef.current.links,
|
|
2514
|
+
quest_nodes: specificParentData.nodes,
|
|
2515
|
+
quest_links: specificParentData.links
|
|
2516
|
+
};
|
|
2517
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2518
|
+
} else {
|
|
2519
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2520
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
2521
|
+
}
|
|
2430
2522
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2431
2523
|
updateExistingNodeVisuals(stateRef.current, nodeToSave);
|
|
2432
2524
|
setters.setSceneVersion((v) => v + 1);
|
|
@@ -2439,10 +2531,11 @@ var userActionHandlers = {
|
|
|
2439
2531
|
}
|
|
2440
2532
|
},
|
|
2441
2533
|
handleSaveLinkDetails: async (context, updatedLink, keepOpen = false) => {
|
|
2534
|
+
var _a;
|
|
2442
2535
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2443
2536
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2444
2537
|
const { sourceNode, targetNode, ...linkToSave } = updatedLink;
|
|
2445
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source);
|
|
2538
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source, context.sceneConfigId, context.ownerId);
|
|
2446
2539
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2447
2540
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link a ser atualizado:", linkToSave.id);
|
|
2448
2541
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
|
|
@@ -2458,9 +2551,21 @@ var userActionHandlers = {
|
|
|
2458
2551
|
alert("Erro interno: link n\xE3o encontrado para salvar.");
|
|
2459
2552
|
return;
|
|
2460
2553
|
}
|
|
2461
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2462
2554
|
try {
|
|
2463
|
-
|
|
2555
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2556
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2557
|
+
const viewFilePayload = {
|
|
2558
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2559
|
+
nodes: sceneDataRef.current.nodes,
|
|
2560
|
+
links: sceneDataRef.current.links,
|
|
2561
|
+
quest_nodes: specificParentData.nodes,
|
|
2562
|
+
quest_links: specificParentData.links
|
|
2563
|
+
};
|
|
2564
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2565
|
+
} else {
|
|
2566
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2567
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
2568
|
+
}
|
|
2464
2569
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2465
2570
|
const lineObject = stateRef.current.allLinks.find(
|
|
2466
2571
|
(l) => String(l.userData.id) === String(linkToSave.id)
|
|
@@ -2483,7 +2588,7 @@ var userActionHandlers = {
|
|
|
2483
2588
|
}
|
|
2484
2589
|
},
|
|
2485
2590
|
handleAddExistingNodeById: (context, nodeId) => {
|
|
2486
|
-
var _a
|
|
2591
|
+
var _a;
|
|
2487
2592
|
const { stateRef, sceneDataRef, graphDataRef, tweenToTarget, setters } = context;
|
|
2488
2593
|
const state = stateRef.current;
|
|
2489
2594
|
const graphFull = graphDataRef.current;
|
|
@@ -2499,16 +2604,12 @@ var userActionHandlers = {
|
|
|
2499
2604
|
tweenToTarget(state.nodeObjects[strNodeId]);
|
|
2500
2605
|
return;
|
|
2501
2606
|
}
|
|
2502
|
-
const alreadyInSceneData = (((_a = sceneDataRef.current) == null ? void 0 : _a.nodes) || []).some((n) => String(n.id) === String(strNodeId));
|
|
2503
|
-
if (!alreadyInSceneData) {
|
|
2504
|
-
sceneDataRef.current.nodes.push(nodeData);
|
|
2505
|
-
}
|
|
2506
2607
|
const base = state.controls ? state.controls.target.clone() : new THREE.Vector3(0, 0, 0);
|
|
2507
2608
|
const offset = new THREE.Vector3((Math.random() - 0.5) * 20, (Math.random() - 0.5) * 6, (Math.random() - 0.5) * 20);
|
|
2508
2609
|
const position = base.add(offset);
|
|
2509
2610
|
addStandaloneNodeToScene(state, nodeData, position);
|
|
2510
2611
|
tweenToTarget(position, 1.3);
|
|
2511
|
-
(
|
|
2612
|
+
(_a = setters == null ? void 0 : setters.setSceneVersion) == null ? void 0 : _a.call(setters, (v) => v + 1);
|
|
2512
2613
|
}
|
|
2513
2614
|
};
|
|
2514
2615
|
|
|
@@ -3097,7 +3198,7 @@ function useResizablePanel({ initialWidth, minWidth, maxWidth }) {
|
|
|
3097
3198
|
|
|
3098
3199
|
// src/components/CustomPropertyDisplay.jsx
|
|
3099
3200
|
import React3, { useState as useState4, useRef as useRef3, useEffect as useEffect3 } from "react";
|
|
3100
|
-
import { FiCheck, FiX
|
|
3201
|
+
import { FiCheck, FiX, FiEdit3, FiTrash2, FiExternalLink, FiFileText, FiChevronDown, FiUpload, FiLoader } from "react-icons/fi";
|
|
3101
3202
|
function CustomPropertyDisplay({
|
|
3102
3203
|
prop,
|
|
3103
3204
|
onUpdate,
|
|
@@ -3388,7 +3489,7 @@ function CustomPropertyDisplay({
|
|
|
3388
3489
|
default:
|
|
3389
3490
|
return /* @__PURE__ */ React3.createElement("input", { type: "text", placeholder: "Valor", value: tempProp.value, onChange: (e) => handlePropChange("value", e.target.value), className: baseInput });
|
|
3390
3491
|
}
|
|
3391
|
-
})()), /* @__PURE__ */ React3.createElement("div", { className: "flex justify-end items-center gap-2 pt-1" }, /* @__PURE__ */ React3.createElement("button", { onClick: handleCancel, type: "button", className: "w-8 h-8 grid place-items-center rounded-lg hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React3.createElement(
|
|
3492
|
+
})()), /* @__PURE__ */ React3.createElement("div", { className: "flex justify-end items-center gap-2 pt-1" }, /* @__PURE__ */ React3.createElement("button", { onClick: handleCancel, type: "button", className: "w-8 h-8 grid place-items-center rounded-lg hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React3.createElement(FiX, { className: "text-red-400" })), /* @__PURE__ */ React3.createElement("button", { onClick: handleSave, type: "button", className: "w-8 h-8 grid place-items-center rounded-lg hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React3.createElement(FiCheck, { className: "text-green-400" }))));
|
|
3392
3493
|
};
|
|
3393
3494
|
const renderDisplayView = () => /* @__PURE__ */ React3.createElement("div", { className: "w-full space-y-2 text-sm" }, /* @__PURE__ */ React3.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React3.createElement("p", { className: "font-semibold text-slate-200" }, prop.key), /* @__PURE__ */ React3.createElement("span", { className: "text-xs capitalize bg-slate-700/50 px-2 py-0.5 rounded text-slate-400" }, prop.type)), /* @__PURE__ */ React3.createElement("div", { className: "text-slate-300 pl-1" }, (() => {
|
|
3394
3495
|
switch (prop.type) {
|
|
@@ -7024,7 +7125,7 @@ function CreateAncestryPanel({
|
|
|
7024
7125
|
|
|
7025
7126
|
// src/components/ImageViewer.jsx
|
|
7026
7127
|
import React11, { useState as useState12, useEffect as useEffect11, useLayoutEffect as useLayoutEffect2, useCallback as useCallback3 } from "react";
|
|
7027
|
-
import { FiX as
|
|
7128
|
+
import { FiX as FiX2, FiChevronLeft as FiChevronLeft3, FiChevronRight as FiChevronRight5 } from "react-icons/fi";
|
|
7028
7129
|
function ImageViewer({ data, onClose }) {
|
|
7029
7130
|
var _a;
|
|
7030
7131
|
const { images = [], startIndex = 0, visible } = data;
|
|
@@ -7109,7 +7210,7 @@ function ImageViewer({ data, onClose }) {
|
|
|
7109
7210
|
className: "absolute top-4 right-4 z-10 w-10 h-10 flex items-center justify-center bg-white/10 hover:bg-white/20 rounded-full text-white text-2xl transition-colors",
|
|
7110
7211
|
"aria-label": "Fechar"
|
|
7111
7212
|
},
|
|
7112
|
-
/* @__PURE__ */ React11.createElement(
|
|
7213
|
+
/* @__PURE__ */ React11.createElement(FiX2, null)
|
|
7113
7214
|
),
|
|
7114
7215
|
/* @__PURE__ */ React11.createElement("div", { className: "relative max-w-full max-h-full flex items-center justify-center" }, isLoading && /* @__PURE__ */ React11.createElement("div", { className: "absolute inset-0 flex items-center justify-center" }, /* @__PURE__ */ React11.createElement("div", { className: "h-10 w-10 border-2 border-white/40 border-t-white rounded-full animate-spin" })), loadedSrc && /* @__PURE__ */ React11.createElement(
|
|
7115
7216
|
"img",
|
|
@@ -7245,7 +7346,7 @@ function ColorPicker({ color, onChange, disabled }) {
|
|
|
7245
7346
|
}
|
|
7246
7347
|
|
|
7247
7348
|
// src/components/InSceneCreationForm.jsx
|
|
7248
|
-
import { FiPlus as FiPlus3, FiMaximize2, FiX as
|
|
7349
|
+
import { FiPlus as FiPlus3, FiMaximize2, FiX as FiX3, FiCheck as FiCheck7, FiEdit2 as FiEdit24, FiSun, FiChevronDown as FiChevronDown4 } from "react-icons/fi";
|
|
7249
7350
|
function InSceneCreationForm({
|
|
7250
7351
|
onSave,
|
|
7251
7352
|
onCancel,
|
|
@@ -7463,7 +7564,7 @@ function InSceneCreationForm({
|
|
|
7463
7564
|
onClick: () => handleRemoveType(index),
|
|
7464
7565
|
className: "hover:text-white transition-colors"
|
|
7465
7566
|
},
|
|
7466
|
-
/* @__PURE__ */ React13.createElement(
|
|
7567
|
+
/* @__PURE__ */ React13.createElement(FiX3, { size: 12 })
|
|
7467
7568
|
))), /* @__PURE__ */ React13.createElement(
|
|
7468
7569
|
"input",
|
|
7469
7570
|
{
|
|
@@ -7837,16 +7938,12 @@ function InSceneVersionForm({
|
|
|
7837
7938
|
|
|
7838
7939
|
// src/components/InSceneQuestForm.jsx
|
|
7839
7940
|
import React15, { useState as useState16, useRef as useRef12 } from "react";
|
|
7840
|
-
import { FiPlus as FiPlus5, FiCheck as FiCheck9, FiEdit2 as FiEdit26, FiTarget } from "react-icons/fi";
|
|
7941
|
+
import { FiPlus as FiPlus5, FiCheck as FiCheck9, FiEdit2 as FiEdit26, FiTarget, FiX as FiX4, FiChevronDown as FiChevronDown5 } from "react-icons/fi";
|
|
7841
7942
|
var QUEST_STATUS_COLORS = {
|
|
7842
7943
|
"Backlog": "#64748b",
|
|
7843
|
-
// Slate (Cinza azulado)
|
|
7844
7944
|
"In Progress": "#eab308",
|
|
7845
|
-
// Yellow (Amarelo)
|
|
7846
7945
|
"Review": "#a855f7",
|
|
7847
|
-
// Purple (Roxo)
|
|
7848
7946
|
"Done": "#22c55e"
|
|
7849
|
-
// Green (Verde)
|
|
7850
7947
|
};
|
|
7851
7948
|
function InSceneQuestForm({
|
|
7852
7949
|
onSave,
|
|
@@ -7857,7 +7954,11 @@ function InSceneQuestForm({
|
|
|
7857
7954
|
availableNodes = [],
|
|
7858
7955
|
availableAncestries = [],
|
|
7859
7956
|
onMentionClick,
|
|
7860
|
-
onUploadFile
|
|
7957
|
+
onUploadFile,
|
|
7958
|
+
// NOVAS PROPS PARA O GHOST NODE
|
|
7959
|
+
onNameChange,
|
|
7960
|
+
onColorChange,
|
|
7961
|
+
onSizeChange
|
|
7861
7962
|
}) {
|
|
7862
7963
|
const [name, setName] = useState16("");
|
|
7863
7964
|
const [types, setTypes] = useState16(["quest"]);
|
|
@@ -7866,6 +7967,7 @@ function InSceneQuestForm({
|
|
|
7866
7967
|
const [size, setSize] = useState16("medium");
|
|
7867
7968
|
const [intensity, setIntensity] = useState16(0);
|
|
7868
7969
|
const [description, setDescription] = useState16("");
|
|
7970
|
+
const [isStatusDropdownOpen, setIsStatusDropdownOpen] = useState16(false);
|
|
7869
7971
|
const [customProps, setCustomProps] = useState16([]);
|
|
7870
7972
|
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState16(false);
|
|
7871
7973
|
const propsEndRef = useRef12(null);
|
|
@@ -7884,7 +7986,7 @@ function InSceneQuestForm({
|
|
|
7884
7986
|
setCustomProps(newProps);
|
|
7885
7987
|
};
|
|
7886
7988
|
const handleAddType = (newType) => {
|
|
7887
|
-
const trimmed = newType.trim()
|
|
7989
|
+
const trimmed = newType.trim();
|
|
7888
7990
|
if (trimmed && !types.includes(trimmed)) {
|
|
7889
7991
|
setTypes([...types, trimmed]);
|
|
7890
7992
|
setTypeInput("");
|
|
@@ -7916,7 +8018,6 @@ function InSceneQuestForm({
|
|
|
7916
8018
|
name: name.trim(),
|
|
7917
8019
|
type: types,
|
|
7918
8020
|
color: QUEST_STATUS_COLORS[status],
|
|
7919
|
-
// Cor atrelada ao status
|
|
7920
8021
|
status,
|
|
7921
8022
|
size,
|
|
7922
8023
|
intensity,
|
|
@@ -7943,20 +8044,52 @@ function InSceneQuestForm({
|
|
|
7943
8044
|
onDoubleClick: swallow
|
|
7944
8045
|
},
|
|
7945
8046
|
/* @__PURE__ */ React15.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS[status]}, transparent)` } }),
|
|
7946
|
-
/* @__PURE__ */ React15.createElement("div", { className: "px-6 pt-5 pb-3" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React15.createElement(FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ React15.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
style: { borderLeft: `4px solid ${QUEST_STATUS_COLORS[status]}` }
|
|
8047
|
+
/* @__PURE__ */ React15.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React15.createElement(FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ React15.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova quest")), /* @__PURE__ */ React15.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")), /* @__PURE__ */ React15.createElement(
|
|
8048
|
+
"button",
|
|
8049
|
+
{
|
|
8050
|
+
type: "button",
|
|
8051
|
+
onClick: onCancel,
|
|
8052
|
+
className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl",
|
|
8053
|
+
title: "Fechar"
|
|
7954
8054
|
},
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
8055
|
+
"\xD7"
|
|
8056
|
+
)),
|
|
8057
|
+
/* @__PURE__ */ React15.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col max-h-[68vh]" }, /* @__PURE__ */ React15.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ React15.createElement("div", { className: "relative" }, /* @__PURE__ */ React15.createElement(
|
|
8058
|
+
"button",
|
|
8059
|
+
{
|
|
8060
|
+
type: "button",
|
|
8061
|
+
onClick: () => setIsStatusDropdownOpen(!isStatusDropdownOpen),
|
|
8062
|
+
className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 hover:border-white/20 focus:outline-none focus:ring-2 focus:ring-indigo-400/60 transition-colors flex items-center justify-between"
|
|
8063
|
+
},
|
|
8064
|
+
/* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15.createElement("span", { className: "w-3 h-3 rounded-full shadow-[0_0_8px_rgba(0,0,0,0.5)]", style: { backgroundColor: QUEST_STATUS_COLORS[status] } }), /* @__PURE__ */ React15.createElement("span", { className: "text-slate-200 font-medium" }, status)),
|
|
8065
|
+
/* @__PURE__ */ React15.createElement(FiChevronDown5, { className: `text-slate-400 transition-transform duration-200 ${isStatusDropdownOpen ? "rotate-180" : ""}` })
|
|
8066
|
+
), isStatusDropdownOpen && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsStatusDropdownOpen(false) }), /* @__PURE__ */ React15.createElement("ul", { className: "absolute top-full left-0 mt-1.5 w-full bg-slate-800 border border-white/10 rounded-lg shadow-[0_8px_30px_rgba(0,0,0,0.5)] z-50 overflow-hidden" }, Object.keys(QUEST_STATUS_COLORS).map((s) => /* @__PURE__ */ React15.createElement(
|
|
8067
|
+
"li",
|
|
8068
|
+
{
|
|
8069
|
+
key: s,
|
|
8070
|
+
onClick: () => {
|
|
8071
|
+
setStatus(s);
|
|
8072
|
+
setIsStatusDropdownOpen(false);
|
|
8073
|
+
onColorChange == null ? void 0 : onColorChange(QUEST_STATUS_COLORS[s]);
|
|
8074
|
+
},
|
|
8075
|
+
className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${status === s ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
|
|
8076
|
+
},
|
|
8077
|
+
/* @__PURE__ */ React15.createElement("span", { className: "w-3 h-3 rounded-full", style: { backgroundColor: QUEST_STATUS_COLORS[s] } }),
|
|
8078
|
+
s
|
|
8079
|
+
)))))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Quest"), /* @__PURE__ */ React15.createElement(
|
|
8080
|
+
"input",
|
|
8081
|
+
{
|
|
8082
|
+
required: true,
|
|
8083
|
+
type: "text",
|
|
8084
|
+
placeholder: "Ex.: Refatorar M\xF3dulo X",
|
|
8085
|
+
value: name,
|
|
8086
|
+
onChange: (e) => {
|
|
8087
|
+
setName(e.target.value);
|
|
8088
|
+
onNameChange == null ? void 0 : onNameChange(e.target.value);
|
|
8089
|
+
},
|
|
8090
|
+
className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60"
|
|
8091
|
+
}
|
|
8092
|
+
)), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tipos Adicionais"), /* @__PURE__ */ React15.createElement("div", { className: "relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 focus-within:ring-2 focus-within:ring-indigo-400/60 transition-all" }, types.map((t, index) => /* @__PURE__ */ React15.createElement("span", { key: index, className: `flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-medium border ${t === "quest" ? "bg-sky-500/20 text-sky-200 border-sky-500/30" : "bg-indigo-500/30 text-indigo-100 border-indigo-500/20"}` }, t, t !== "quest" && /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => handleRemoveType(index), className: "hover:text-white transition-colors" }, /* @__PURE__ */ React15.createElement(FiX4, { size: 12 })))), /* @__PURE__ */ React15.createElement(
|
|
7960
8093
|
"input",
|
|
7961
8094
|
{
|
|
7962
8095
|
type: "text",
|
|
@@ -7967,7 +8100,6 @@ function InSceneQuestForm({
|
|
|
7967
8100
|
if (typeInput.trim()) handleAddType(typeInput);
|
|
7968
8101
|
},
|
|
7969
8102
|
className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
|
|
7970
|
-
placeholder: "Ex.: Bugfix",
|
|
7971
8103
|
autoComplete: "off"
|
|
7972
8104
|
}
|
|
7973
8105
|
))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ React15.createElement("div", { className: "relative group min-h-[80px] bg-slate-800/70 p-2.5 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React15.createElement(
|
|
@@ -7980,7 +8112,20 @@ function InSceneQuestForm({
|
|
|
7980
8112
|
onMentionClick,
|
|
7981
8113
|
onSaveDescription: (newDesc) => setDescription(newDesc)
|
|
7982
8114
|
}
|
|
7983
|
-
), /* @__PURE__ */ React15.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiEdit26, { size: 14 }))), !description && /* @__PURE__ */ React15.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no
|
|
8115
|
+
), /* @__PURE__ */ React15.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiEdit26, { size: 14 }))), !description && /* @__PURE__ */ React15.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ React15.createElement(
|
|
8116
|
+
"button",
|
|
8117
|
+
{
|
|
8118
|
+
key: s,
|
|
8119
|
+
type: "button",
|
|
8120
|
+
onClick: () => {
|
|
8121
|
+
setSize(s);
|
|
8122
|
+
onSizeChange == null ? void 0 : onSizeChange(s);
|
|
8123
|
+
},
|
|
8124
|
+
className: "flex items-center gap-2 group cursor-pointer focus:outline-none"
|
|
8125
|
+
},
|
|
8126
|
+
/* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${size === s ? "bg-indigo-500 border-indigo-500" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, size === s && /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12, className: "text-white" })),
|
|
8127
|
+
/* @__PURE__ */ React15.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s)
|
|
8128
|
+
)))), /* @__PURE__ */ React15.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React15.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiPlus5, { size: 14 }), " Adicionar")), /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ React15.createElement(
|
|
7984
8129
|
CustomPropertyDisplay,
|
|
7985
8130
|
{
|
|
7986
8131
|
key: prop.id,
|
|
@@ -10173,7 +10318,7 @@ function XViewScene({
|
|
|
10173
10318
|
});
|
|
10174
10319
|
}
|
|
10175
10320
|
return {
|
|
10176
|
-
node: effectiveNode
|
|
10321
|
+
...effectiveNode ? { node: effectiveNode } : { node: { id: nodeId, name: "Unknown" } },
|
|
10177
10322
|
relationship: treeItem.relationship || {},
|
|
10178
10323
|
children: (treeItem.children || []).map(recursiveBuild).filter(Boolean),
|
|
10179
10324
|
parallel_branches: processedBranches
|
|
@@ -10872,20 +11017,6 @@ function XViewScene({
|
|
|
10872
11017
|
const context = actionHandlerContext;
|
|
10873
11018
|
if (connection.isActive) {
|
|
10874
11019
|
if (hoveredNode && String(hoveredNode.userData.id) !== String(connection.sourceNodeData.id)) {
|
|
10875
|
-
const sourceId = String(connection.sourceNodeData.id);
|
|
10876
|
-
const targetId = String(hoveredNode.userData.id);
|
|
10877
|
-
let parentInfo = stateRef.current.nodeIdToParentFileMap.get(sourceId);
|
|
10878
|
-
if (!parentInfo || !parentInfo.ownerId) {
|
|
10879
|
-
parentInfo = stateRef.current.nodeIdToParentFileMap.get(targetId);
|
|
10880
|
-
if (parentInfo && parentInfo.ownerId) {
|
|
10881
|
-
stateRef.current.nodeIdToParentFileMap.set(sourceId, parentInfo);
|
|
10882
|
-
} else {
|
|
10883
|
-
console.error("Nenhum dos Nodes possui um Dataset pai v\xE1lido para salvar a conex\xE3o.");
|
|
10884
|
-
alert("N\xE3o \xE9 poss\xEDvel conectar dois Nodes de Quest diretamente sem um Dataset pai, ou ocorreu um erro.");
|
|
10885
|
-
userActionHandlers.handleCancelConnection(context);
|
|
10886
|
-
return;
|
|
10887
|
-
}
|
|
10888
|
-
}
|
|
10889
11020
|
await userActionHandlers.handleCompleteConnection(context, hoveredNode.userData);
|
|
10890
11021
|
} else {
|
|
10891
11022
|
userActionHandlers.handleCancelConnection(context);
|
|
@@ -10991,39 +11122,6 @@ function XViewScene({
|
|
|
10991
11122
|
}
|
|
10992
11123
|
}
|
|
10993
11124
|
}
|
|
10994
|
-
function handleCancelAncestryCreation() {
|
|
10995
|
-
setAncestryMode({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
10996
|
-
if (mountRef.current) mountRef.current.style.cursor = "grab";
|
|
10997
|
-
}
|
|
10998
|
-
function handleKeyDown(event) {
|
|
10999
|
-
var _a2, _b2, _c2, _d2;
|
|
11000
|
-
const context = actionHandlerContext;
|
|
11001
|
-
if (event.key === "Escape") {
|
|
11002
|
-
if (stateRef.current.connection.isActive) userActionHandlers.handleCancelConnection(context);
|
|
11003
|
-
if (stateRef.current.relink.isActive) userActionHandlers.handleCancelRelink(context);
|
|
11004
|
-
if (stateRef.current.creation.isActive) userActionHandlers.handleCancelCreation(context);
|
|
11005
|
-
if ((_a2 = stateRef.current.versionMode) == null ? void 0 : _a2.isActive) userActionHandlers.handleCancelVersioning(context);
|
|
11006
|
-
if (stateRef.current.ancestry.isActive) handleCancelAncestryCreation();
|
|
11007
|
-
if ((_b2 = context.questMode) == null ? void 0 : _b2.isActive) context.setters.setQuestMode({ isActive: false });
|
|
11008
|
-
if (stateRef.current.selectedNodes.size > 0) {
|
|
11009
|
-
stateRef.current.selectedNodes.clear();
|
|
11010
|
-
}
|
|
11011
|
-
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11012
|
-
setMultiContextMenu((prev) => ({ ...prev, visible: false }));
|
|
11013
|
-
setRelationshipMenu((prev) => ({ ...prev, visible: false }));
|
|
11014
|
-
}
|
|
11015
|
-
if (event.key.toLowerCase() === "q") {
|
|
11016
|
-
const isUiClear = !stateRef.current.creation.isActive && !stateRef.current.connection.isActive && !stateRef.current.relink.isActive && !stateRef.current.ancestry.isActive && !((_c2 = context.versionMode) == null ? void 0 : _c2.isActive) && !contextMenu.visible && !multiContextMenu.visible && !relationshipMenu.visible && !readingMode.isActive && !isImportModalOpen && !isAncestryBoardOpen;
|
|
11017
|
-
if (isUiClear) {
|
|
11018
|
-
const isView = ((_d2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _d2.toLowerCase()) === "view";
|
|
11019
|
-
if (!isView) {
|
|
11020
|
-
alert("Nodes de Quest s\xF3 podem ser criados dentro de uma View.");
|
|
11021
|
-
return;
|
|
11022
|
-
}
|
|
11023
|
-
setQuestMode({ isActive: true });
|
|
11024
|
-
}
|
|
11025
|
-
}
|
|
11026
|
-
}
|
|
11027
11125
|
function handleDoubleClick(event) {
|
|
11028
11126
|
if (stateRef.current.camera) stateRef.current.camera.layers.enableAll();
|
|
11029
11127
|
if (isFromUiOverlay(event) || stateRef.current.isDragging || stateRef.current.creation.isActive || stateRef.current.connection.isActive || stateRef.current.relink.isActive) return;
|
|
@@ -11076,7 +11174,6 @@ function XViewScene({
|
|
|
11076
11174
|
currentMount.addEventListener("dblclick", handleDoubleClick);
|
|
11077
11175
|
currentMount.addEventListener("pointermove", onPointerMove);
|
|
11078
11176
|
currentMount.addEventListener("contextmenu", handleContextMenu);
|
|
11079
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
11080
11177
|
const originalBackground = scene.background;
|
|
11081
11178
|
const clock = new THREE3.Clock();
|
|
11082
11179
|
let animationFrameId = 0;
|
|
@@ -11214,7 +11311,6 @@ function XViewScene({
|
|
|
11214
11311
|
return () => {
|
|
11215
11312
|
cancelAnimationFrame(animationFrameId);
|
|
11216
11313
|
window.removeEventListener("resize", handleResize);
|
|
11217
|
-
window.removeEventListener("keydown", handleKeyDown);
|
|
11218
11314
|
currentMount.removeEventListener("pointerdown", onPointerDown);
|
|
11219
11315
|
currentMount.removeEventListener("pointerup", onPointerUp);
|
|
11220
11316
|
currentMount.removeEventListener("dblclick", handleDoubleClick);
|
|
@@ -11488,11 +11584,10 @@ function XViewScene({
|
|
|
11488
11584
|
creationMode,
|
|
11489
11585
|
versionMode,
|
|
11490
11586
|
questMode,
|
|
11491
|
-
// <-- Adicionado
|
|
11492
11587
|
sceneSaveUrl,
|
|
11493
|
-
|
|
11588
|
+
sceneConfigId,
|
|
11589
|
+
ownerId,
|
|
11494
11590
|
viewType: viewParams == null ? void 0 : viewParams.type,
|
|
11495
|
-
// <-- Adicionado
|
|
11496
11591
|
userId: (_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.id,
|
|
11497
11592
|
setters: {
|
|
11498
11593
|
setContextMenu,
|
|
@@ -11506,7 +11601,6 @@ function XViewScene({
|
|
|
11506
11601
|
setSceneVersion,
|
|
11507
11602
|
setAncestryMode,
|
|
11508
11603
|
setQuestMode
|
|
11509
|
-
// <-- Adicionado
|
|
11510
11604
|
},
|
|
11511
11605
|
tweenToTarget,
|
|
11512
11606
|
handleVersionTimeline,
|
|
@@ -11524,9 +11618,11 @@ function XViewScene({
|
|
|
11524
11618
|
versionMode,
|
|
11525
11619
|
questMode,
|
|
11526
11620
|
sceneSaveUrl,
|
|
11621
|
+
sceneConfigId,
|
|
11622
|
+
ownerId,
|
|
11527
11623
|
viewParams == null ? void 0 : viewParams.type,
|
|
11528
|
-
tweenToTarget,
|
|
11529
11624
|
(_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id,
|
|
11625
|
+
tweenToTarget,
|
|
11530
11626
|
handleVersionTimeline,
|
|
11531
11627
|
save_view_data,
|
|
11532
11628
|
get_single_parent_file,
|
|
@@ -11538,33 +11634,116 @@ function XViewScene({
|
|
|
11538
11634
|
const handleStartVersioning = (nodeData) => {
|
|
11539
11635
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
11540
11636
|
};
|
|
11637
|
+
const handleCancelQuest = useCallback4(() => {
|
|
11638
|
+
const { graphGroup, ghostElements } = stateRef.current;
|
|
11639
|
+
if (ghostElements.node && graphGroup) {
|
|
11640
|
+
if (ghostElements.node.userData.labelObject) {
|
|
11641
|
+
graphGroup.remove(ghostElements.node.userData.labelObject);
|
|
11642
|
+
if (ghostElements.node.userData.labelObject.material.map) ghostElements.node.userData.labelObject.material.map.dispose();
|
|
11643
|
+
ghostElements.node.userData.labelObject.material.dispose();
|
|
11644
|
+
}
|
|
11645
|
+
graphGroup.remove(ghostElements.node);
|
|
11646
|
+
ghostElements.node.traverse((child) => {
|
|
11647
|
+
if (child.material) {
|
|
11648
|
+
if (Array.isArray(child.material)) child.material.forEach((m) => m.dispose());
|
|
11649
|
+
else child.material.dispose();
|
|
11650
|
+
}
|
|
11651
|
+
if (child.geometry) child.geometry.dispose();
|
|
11652
|
+
});
|
|
11653
|
+
}
|
|
11654
|
+
stateRef.current.ghostElements = { node: null, line: null, aura: null };
|
|
11655
|
+
setQuestMode({ isActive: false });
|
|
11656
|
+
}, []);
|
|
11541
11657
|
const handleSaveQuestNode = async (context, newQuestData) => {
|
|
11542
|
-
const { sceneDataRef: sceneDataRef2, stateRef: stateRef2, setters, actions, sceneSaveUrl: sceneSaveUrl2, viewType } = context;
|
|
11543
|
-
if (!
|
|
11658
|
+
const { graphDataRef, sceneDataRef: sceneDataRef2, stateRef: stateRef2, setters, actions, sceneSaveUrl: sceneSaveUrl2, viewType, sceneConfigId: sceneConfigId2, ownerId: ownerId2 } = context;
|
|
11659
|
+
if (!graphDataRef.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
|
|
11544
11660
|
const newNode = {
|
|
11545
11661
|
id: short2.generate(),
|
|
11546
11662
|
...newQuestData,
|
|
11663
|
+
is_quest: true,
|
|
11547
11664
|
type: ["quest", ...newQuestData.type.filter((t) => t !== "quest")]
|
|
11548
11665
|
};
|
|
11549
|
-
|
|
11550
|
-
|
|
11551
|
-
|
|
11666
|
+
if (!graphDataRef.current[sceneConfigId2]) {
|
|
11667
|
+
graphDataRef.current[sceneConfigId2] = { nodes: [], links: [] };
|
|
11668
|
+
}
|
|
11669
|
+
graphDataRef.current[sceneConfigId2].nodes.push(newNode);
|
|
11670
|
+
const sceneFileData = {
|
|
11671
|
+
parent_dbs: sceneDataRef2.current.parent_dbs,
|
|
11672
|
+
nodes: sceneDataRef2.current.nodes,
|
|
11673
|
+
links: sceneDataRef2.current.links,
|
|
11674
|
+
quest_nodes: graphDataRef.current[sceneConfigId2].nodes,
|
|
11675
|
+
quest_links: graphDataRef.current[sceneConfigId2].links
|
|
11552
11676
|
};
|
|
11553
11677
|
try {
|
|
11554
|
-
await actions.save_view_data(sceneSaveUrl2,
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
|
|
11678
|
+
await actions.save_view_data(sceneSaveUrl2, sceneFileData);
|
|
11679
|
+
stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
11680
|
+
parentFileId: sceneConfigId2,
|
|
11681
|
+
ownerId: ownerId2,
|
|
11682
|
+
datasetName: "Quests Internas (View)"
|
|
11683
|
+
});
|
|
11684
|
+
const finalPosition = stateRef2.current.ghostElements.node ? stateRef2.current.ghostElements.node.position.clone() : stateRef2.current.controls.target.clone();
|
|
11685
|
+
const { graphGroup, ghostElements } = stateRef2.current;
|
|
11686
|
+
if (ghostElements.node && graphGroup) {
|
|
11687
|
+
if (ghostElements.node.userData.labelObject) graphGroup.remove(ghostElements.node.userData.labelObject);
|
|
11688
|
+
graphGroup.remove(ghostElements.node);
|
|
11689
|
+
}
|
|
11690
|
+
stateRef2.current.ghostElements = { node: null, line: null, aura: null };
|
|
11691
|
+
addStandaloneNodeToScene(stateRef2.current, newNode, finalPosition);
|
|
11560
11692
|
context.tweenToTarget(finalPosition, 1.2);
|
|
11561
11693
|
setters.setQuestMode({ isActive: false });
|
|
11562
11694
|
setters.setSceneVersion((v) => v + 1);
|
|
11563
11695
|
} catch (error) {
|
|
11564
|
-
console.error("Falha ao salvar
|
|
11696
|
+
console.error("Falha ao salvar Quest na View:", error);
|
|
11565
11697
|
alert("Ocorreu um erro ao criar a Quest.");
|
|
11566
11698
|
}
|
|
11567
11699
|
};
|
|
11700
|
+
userActionHandlers.handleCompleteConnection = async (context, targetNodeData) => {
|
|
11701
|
+
const { stateRef: stateRef2, graphDataRef, sceneDataRef: sceneDataRef2, sceneConfigId: sceneConfigId2, sceneSaveUrl: sceneSaveUrl2, ownerId: ownerId2 } = context;
|
|
11702
|
+
const { sourceNodeData } = stateRef2.current.connection;
|
|
11703
|
+
if (!graphDataRef.current || !sceneDataRef2.current || !sourceNodeData || !targetNodeData) {
|
|
11704
|
+
userActionHandlers.handleCancelConnection(context);
|
|
11705
|
+
return;
|
|
11706
|
+
}
|
|
11707
|
+
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, sourceNodeData.id, sceneConfigId2, ownerId2);
|
|
11708
|
+
const targetParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, targetNodeData.id, sceneConfigId2, ownerId2);
|
|
11709
|
+
let parentInfoToSave = sourceParentInfo;
|
|
11710
|
+
const isSourceQuest = sourceParentInfo.parentFileId === sceneConfigId2;
|
|
11711
|
+
const isTargetQuest = targetParentInfo.parentFileId === sceneConfigId2;
|
|
11712
|
+
if (isSourceQuest || isTargetQuest) {
|
|
11713
|
+
parentInfoToSave = { parentFileId: sceneConfigId2, ownerId: ownerId2 };
|
|
11714
|
+
}
|
|
11715
|
+
const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
|
|
11716
|
+
const newLink = {
|
|
11717
|
+
id: `link_${short2.generate()}`,
|
|
11718
|
+
source: sourceNodeData.id,
|
|
11719
|
+
target: targetNodeData.id
|
|
11720
|
+
};
|
|
11721
|
+
try {
|
|
11722
|
+
if (parentFileIdToSave === sceneConfigId2) {
|
|
11723
|
+
const specificParentData = graphDataRef.current[sceneConfigId2];
|
|
11724
|
+
specificParentData.links.push(newLink);
|
|
11725
|
+
const viewFilePayload = {
|
|
11726
|
+
parent_dbs: sceneDataRef2.current.parent_dbs,
|
|
11727
|
+
nodes: sceneDataRef2.current.nodes,
|
|
11728
|
+
links: sceneDataRef2.current.links,
|
|
11729
|
+
quest_nodes: specificParentData.nodes,
|
|
11730
|
+
quest_links: specificParentData.links
|
|
11731
|
+
};
|
|
11732
|
+
await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
|
|
11733
|
+
} else {
|
|
11734
|
+
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
|
|
11735
|
+
specificParentData.links.push(newLink);
|
|
11736
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
|
|
11737
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
11738
|
+
graphDataRef.current[parentFileIdToSave] = specificParentData;
|
|
11739
|
+
}
|
|
11740
|
+
addNewLinkToScene(stateRef2.current, newLink);
|
|
11741
|
+
} catch (error) {
|
|
11742
|
+
console.error("Falha ao salvar a nova conex\xE3o:", error);
|
|
11743
|
+
alert("Ocorreu um erro ao salvar a nova conex\xE3o.");
|
|
11744
|
+
}
|
|
11745
|
+
userActionHandlers.handleCancelConnection(context);
|
|
11746
|
+
};
|
|
11568
11747
|
const handleClearAncestryVisuals = useCallback4((ancestryId) => {
|
|
11569
11748
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
11570
11749
|
const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
|
|
@@ -12832,6 +13011,7 @@ function XViewScene({
|
|
|
12832
13011
|
[actionHandlerContext]
|
|
12833
13012
|
);
|
|
12834
13013
|
const handleSaveCurrentView = useCallback4(async () => {
|
|
13014
|
+
var _a2, _b2, _c2;
|
|
12835
13015
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
12836
13016
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
12837
13017
|
console.warn("N\xE3o \xE9 poss\xEDvel salvar a cena: estado n\xE3o inicializado ou URL de salvamento ausente.");
|
|
@@ -12853,17 +13033,22 @@ function XViewScene({
|
|
|
12853
13033
|
const { sourceNode, targetNode, ...serializableLinkData } = line.userData;
|
|
12854
13034
|
return serializableLinkData;
|
|
12855
13035
|
});
|
|
13036
|
+
sceneDataRef.current.nodes = currentNodes;
|
|
13037
|
+
sceneDataRef.current.links = currentLinks;
|
|
13038
|
+
const isView = ((_a2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _a2.toLowerCase()) === "view";
|
|
12856
13039
|
const sceneFileData = {
|
|
12857
13040
|
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
12858
13041
|
nodes: currentNodes,
|
|
12859
|
-
links: currentLinks
|
|
13042
|
+
links: currentLinks,
|
|
13043
|
+
quest_nodes: isView ? ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || [] : sceneDataRef.current.quest_nodes || [],
|
|
13044
|
+
quest_links: isView ? ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || [] : sceneDataRef.current.quest_links || []
|
|
12860
13045
|
};
|
|
12861
13046
|
try {
|
|
12862
13047
|
await save_view_data(sceneSaveUrl, sceneFileData);
|
|
12863
13048
|
} catch (error) {
|
|
12864
13049
|
console.error("Erro na chamada de save_view_data:", error);
|
|
12865
13050
|
}
|
|
12866
|
-
}, [sceneSaveUrl, save_view_data]);
|
|
13051
|
+
}, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
|
|
12867
13052
|
const allAvailableNodes = useMemo12(() => {
|
|
12868
13053
|
if (!parentDataRef.current) return [];
|
|
12869
13054
|
return Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
|
|
@@ -12948,6 +13133,106 @@ function XViewScene({
|
|
|
12948
13133
|
}
|
|
12949
13134
|
}
|
|
12950
13135
|
}, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
|
|
13136
|
+
useEffect21(() => {
|
|
13137
|
+
function handleKeyDown(event) {
|
|
13138
|
+
var _a2, _b2, _c2;
|
|
13139
|
+
const context = actionHandlerContext;
|
|
13140
|
+
if (event.key === "Escape") {
|
|
13141
|
+
if (stateRef.current.connection.isActive) userActionHandlers.handleCancelConnection(context);
|
|
13142
|
+
if (stateRef.current.relink.isActive) userActionHandlers.handleCancelRelink(context);
|
|
13143
|
+
if (stateRef.current.creation.isActive) userActionHandlers.handleCancelCreation(context);
|
|
13144
|
+
if ((_a2 = stateRef.current.versionMode) == null ? void 0 : _a2.isActive) userActionHandlers.handleCancelVersioning(context);
|
|
13145
|
+
if (stateRef.current.ancestry.isActive) {
|
|
13146
|
+
setAncestryMode({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
13147
|
+
if (mountRef.current) mountRef.current.style.cursor = "grab";
|
|
13148
|
+
}
|
|
13149
|
+
if (questMode.isActive) {
|
|
13150
|
+
handleCancelQuest();
|
|
13151
|
+
}
|
|
13152
|
+
if (stateRef.current.selectedNodes.size > 0) {
|
|
13153
|
+
stateRef.current.selectedNodes.clear();
|
|
13154
|
+
}
|
|
13155
|
+
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
13156
|
+
setMultiContextMenu((prev) => ({ ...prev, visible: false }));
|
|
13157
|
+
setRelationshipMenu((prev) => ({ ...prev, visible: false }));
|
|
13158
|
+
}
|
|
13159
|
+
if (event.key.toLowerCase() === "q") {
|
|
13160
|
+
const isUiClear = !stateRef.current.creation.isActive && !stateRef.current.connection.isActive && !stateRef.current.relink.isActive && !stateRef.current.ancestry.isActive && !((_b2 = context.versionMode) == null ? void 0 : _b2.isActive) && !contextMenu.visible && !multiContextMenu.visible && !relationshipMenu.visible && !readingMode.isActive && !isImportModalOpen && !isAncestryBoardOpen && !isSidebarOpen && !detailsNode && !detailsLink && !ancestryLinkDetails && !imageViewer.visible && !editingAncestryRel.visible && !questMode.isActive;
|
|
13161
|
+
if (isUiClear) {
|
|
13162
|
+
const isView = ((_c2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _c2.toLowerCase()) === "view";
|
|
13163
|
+
if (!isView) return;
|
|
13164
|
+
const { graphGroup, glowTexture, controls, nodeObjects } = stateRef.current;
|
|
13165
|
+
if (graphGroup) {
|
|
13166
|
+
let ghostPosition = controls.target.clone();
|
|
13167
|
+
const existingNodes = Object.values(nodeObjects);
|
|
13168
|
+
let isOccupied = true;
|
|
13169
|
+
let radius = 18;
|
|
13170
|
+
let angle = 0;
|
|
13171
|
+
let attempts = 0;
|
|
13172
|
+
const MIN_CLEARANCE = 15;
|
|
13173
|
+
while (isOccupied && attempts < 30) {
|
|
13174
|
+
isOccupied = existingNodes.some((mesh) => mesh.position.distanceTo(ghostPosition) < MIN_CLEARANCE);
|
|
13175
|
+
if (isOccupied) {
|
|
13176
|
+
ghostPosition.x = controls.target.x + Math.cos(angle) * radius;
|
|
13177
|
+
ghostPosition.y = controls.target.y + (Math.random() - 0.5) * 8;
|
|
13178
|
+
ghostPosition.z = controls.target.z + Math.sin(angle) * radius;
|
|
13179
|
+
angle += Math.PI / 3;
|
|
13180
|
+
radius += 2.5;
|
|
13181
|
+
attempts++;
|
|
13182
|
+
}
|
|
13183
|
+
}
|
|
13184
|
+
const ghostData = {
|
|
13185
|
+
id: "ghost_quest",
|
|
13186
|
+
name: "Nova Quest",
|
|
13187
|
+
color: "#64748b",
|
|
13188
|
+
// Cor padrão de "Backlog"
|
|
13189
|
+
size: "medium",
|
|
13190
|
+
intensity: 0,
|
|
13191
|
+
type: ["quest"]
|
|
13192
|
+
};
|
|
13193
|
+
const ghostNode = createNodeMesh(ghostData, ghostPosition, glowTexture);
|
|
13194
|
+
ghostNode.traverse((child) => {
|
|
13195
|
+
if (child.isMesh) {
|
|
13196
|
+
child.material.transparent = true;
|
|
13197
|
+
child.material.opacity = 0.75;
|
|
13198
|
+
}
|
|
13199
|
+
});
|
|
13200
|
+
graphGroup.add(ghostNode);
|
|
13201
|
+
if (ghostNode.userData.labelObject) {
|
|
13202
|
+
graphGroup.add(ghostNode.userData.labelObject);
|
|
13203
|
+
}
|
|
13204
|
+
stateRef.current.ghostElements = {
|
|
13205
|
+
node: ghostNode,
|
|
13206
|
+
line: null,
|
|
13207
|
+
aura: ghostNode.getObjectByName("aura")
|
|
13208
|
+
};
|
|
13209
|
+
context.tweenToTarget(ghostPosition, 1.6);
|
|
13210
|
+
}
|
|
13211
|
+
setQuestMode({ isActive: true });
|
|
13212
|
+
}
|
|
13213
|
+
}
|
|
13214
|
+
}
|
|
13215
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
13216
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
13217
|
+
}, [
|
|
13218
|
+
contextMenu.visible,
|
|
13219
|
+
multiContextMenu.visible,
|
|
13220
|
+
relationshipMenu.visible,
|
|
13221
|
+
readingMode.isActive,
|
|
13222
|
+
isImportModalOpen,
|
|
13223
|
+
isAncestryBoardOpen,
|
|
13224
|
+
isSidebarOpen,
|
|
13225
|
+
detailsNode,
|
|
13226
|
+
detailsLink,
|
|
13227
|
+
ancestryLinkDetails,
|
|
13228
|
+
imageViewer.visible,
|
|
13229
|
+
editingAncestryRel.visible,
|
|
13230
|
+
questMode.isActive,
|
|
13231
|
+
viewParams,
|
|
13232
|
+
actionHandlerContext,
|
|
13233
|
+
handleCancelQuest
|
|
13234
|
+
// <-- handleCancelQuest adicionado aqui
|
|
13235
|
+
]);
|
|
12951
13236
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
12952
13237
|
return /* @__PURE__ */ React24.createElement(LoadingScreen, null);
|
|
12953
13238
|
}
|
|
@@ -13042,7 +13327,10 @@ function XViewScene({
|
|
|
13042
13327
|
InSceneQuestForm,
|
|
13043
13328
|
{
|
|
13044
13329
|
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
13045
|
-
onCancel:
|
|
13330
|
+
onCancel: handleCancelQuest,
|
|
13331
|
+
onNameChange: handleGhostNodeNameChange,
|
|
13332
|
+
onColorChange: handleGhostNodeColorChange,
|
|
13333
|
+
onSizeChange: handleGhostNodeSizeChange,
|
|
13046
13334
|
style: { position: "absolute", left: `16px`, top: `16px`, zIndex: 20, transition: "opacity 200ms ease-out" },
|
|
13047
13335
|
refEl: formRef,
|
|
13048
13336
|
onOpenImageViewer: handleOpenImageViewer,
|
|
@@ -13334,6 +13622,12 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
13334
13622
|
}
|
|
13335
13623
|
const sceneData = sceneResponse.data;
|
|
13336
13624
|
const parentDbObjects = sceneData.parent_dbs || [];
|
|
13625
|
+
if (type && type.toLowerCase().includes("database")) {
|
|
13626
|
+
const selfExists = parentDbObjects.some((db) => String(db.db_id) === String(scene_config));
|
|
13627
|
+
if (!selfExists) {
|
|
13628
|
+
parentDbObjects.push({ db_id: scene_config, owner_id });
|
|
13629
|
+
}
|
|
13630
|
+
}
|
|
13337
13631
|
const parentResponsesPromises = parentDbObjects.map(
|
|
13338
13632
|
(db_info) => db_services.get_file(`x_view_dbs/${db_info.owner_id}/${db_info.db_id}`)
|
|
13339
13633
|
);
|
|
@@ -13351,6 +13645,13 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
13351
13645
|
);
|
|
13352
13646
|
}
|
|
13353
13647
|
}
|
|
13648
|
+
if (type && type.toLowerCase() === "view") {
|
|
13649
|
+
parentData[scene_config] = {
|
|
13650
|
+
dataset_name: "Quests Internas (View)",
|
|
13651
|
+
nodes: sceneData.quest_nodes || [],
|
|
13652
|
+
links: sceneData.quest_links || []
|
|
13653
|
+
};
|
|
13654
|
+
}
|
|
13354
13655
|
const allNodes = Object.values(parentData).flatMap((db) => db.nodes || []);
|
|
13355
13656
|
const allLinks = Object.values(parentData).flatMap((db) => db.links || []);
|
|
13356
13657
|
const parentNodeMap = new Map(allNodes.map((node) => [String(node.id), node]));
|
|
@@ -13360,7 +13661,11 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
13360
13661
|
if (nodeTypes.includes("quest")) {
|
|
13361
13662
|
return sceneNode;
|
|
13362
13663
|
}
|
|
13363
|
-
|
|
13664
|
+
const dbNode = parentNodeMap.get(String(sceneNode.id));
|
|
13665
|
+
if (dbNode) {
|
|
13666
|
+
return { ...sceneNode, ...dbNode };
|
|
13667
|
+
}
|
|
13668
|
+
return null;
|
|
13364
13669
|
}).filter(Boolean);
|
|
13365
13670
|
const validNodeIdsInScene = new Set(validatedNodes.map((node) => String(node.id)));
|
|
13366
13671
|
const validatedLinks = (sceneData.links || []).filter((sceneLink) => {
|