@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.js
CHANGED
|
@@ -1225,8 +1225,6 @@ var createMultipleLinkLines = (linksArray, sourceNodeMesh, targetNodeMesh, resol
|
|
|
1225
1225
|
targetNodeMesh,
|
|
1226
1226
|
resolution,
|
|
1227
1227
|
isCurved,
|
|
1228
|
-
isCurved,
|
|
1229
|
-
isCurved,
|
|
1230
1228
|
curveOffset
|
|
1231
1229
|
);
|
|
1232
1230
|
line.userData = {
|
|
@@ -1559,7 +1557,7 @@ var addStandaloneNodeToScene = (state, nodeData, position) => {
|
|
|
1559
1557
|
scaleTween.start();
|
|
1560
1558
|
}
|
|
1561
1559
|
};
|
|
1562
|
-
var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
|
|
1560
|
+
var getParentFileInfoForNode = (allParentData, sceneData, nodeId, sceneConfigId = null, sceneOwnerId = null) => {
|
|
1563
1561
|
const parentDbsArray = (sceneData == null ? void 0 : sceneData.parent_dbs) || [];
|
|
1564
1562
|
for (const parentFileId in allParentData) {
|
|
1565
1563
|
if (allParentData.hasOwnProperty(parentFileId)) {
|
|
@@ -1568,6 +1566,8 @@ var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
|
|
|
1568
1566
|
const parentDbInfo = parentDbsArray.find((db) => String(db.db_id) === String(parentFileId));
|
|
1569
1567
|
if (parentDbInfo) {
|
|
1570
1568
|
return { parentFileId, ownerId: parentDbInfo.owner_id };
|
|
1569
|
+
} else if (sceneConfigId && String(parentFileId) === String(sceneConfigId)) {
|
|
1570
|
+
return { parentFileId, ownerId: sceneOwnerId };
|
|
1571
1571
|
} else {
|
|
1572
1572
|
console.warn(`Owner ID n\xE3o encontrado em sceneData.parent_dbs para o parentFileId: ${parentFileId}`);
|
|
1573
1573
|
return { parentFileId, ownerId: null };
|
|
@@ -1837,6 +1837,7 @@ var userActionHandlers = {
|
|
|
1837
1837
|
setters.setFormPosition((p) => ({ ...p, opacity: 0 }));
|
|
1838
1838
|
},
|
|
1839
1839
|
handleSaveVersionNode: async (context, newNodeData) => {
|
|
1840
|
+
var _a;
|
|
1840
1841
|
const { graphDataRef, sceneDataRef, stateRef, versionMode, setters } = context;
|
|
1841
1842
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
1842
1843
|
const { sourceNodeData } = versionMode;
|
|
@@ -1846,7 +1847,7 @@ var userActionHandlers = {
|
|
|
1846
1847
|
version_node: { is_version: true, parent_node: sourceNodeData.id }
|
|
1847
1848
|
};
|
|
1848
1849
|
const newLink = { id: `link_${import_short_uuid.default.generate()}`, source: sourceNodeData.id, target: newNode.id };
|
|
1849
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
|
|
1850
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
|
|
1850
1851
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
1851
1852
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:", sourceNodeData.id);
|
|
1852
1853
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
|
|
@@ -1856,9 +1857,21 @@ var userActionHandlers = {
|
|
|
1856
1857
|
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
|
|
1857
1858
|
specificParentData.nodes.push(newNode);
|
|
1858
1859
|
specificParentData.links.push(newLink);
|
|
1859
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
1860
1860
|
try {
|
|
1861
|
-
|
|
1861
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
1862
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
1863
|
+
const viewFilePayload = {
|
|
1864
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
1865
|
+
nodes: sceneDataRef.current.nodes,
|
|
1866
|
+
links: sceneDataRef.current.links,
|
|
1867
|
+
quest_nodes: specificParentData.nodes,
|
|
1868
|
+
quest_links: specificParentData.links
|
|
1869
|
+
};
|
|
1870
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
1871
|
+
} else {
|
|
1872
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
1873
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
1874
|
+
}
|
|
1862
1875
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
1863
1876
|
const finalPosition = stateRef.current.ghostElements.node.position.clone();
|
|
1864
1877
|
addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
|
|
@@ -1882,10 +1895,6 @@ var userActionHandlers = {
|
|
|
1882
1895
|
var _a;
|
|
1883
1896
|
const isSource = String(link.source) === String(sourceNode.id);
|
|
1884
1897
|
const targetNodeId = isSource ? link.target : link.source;
|
|
1885
|
-
const linkAlreadyInSceneData = sceneDataRef.current.links.some((l) => String(l.id) === String(link.id));
|
|
1886
|
-
if (!linkAlreadyInSceneData) {
|
|
1887
|
-
sceneDataRef.current.links.push(link);
|
|
1888
|
-
}
|
|
1889
1898
|
if (!nodeObjects[String(targetNodeId)]) {
|
|
1890
1899
|
const allParentNodes = Object.values(graphDataRef.current).flatMap((fileData) => fileData.nodes);
|
|
1891
1900
|
const nodeData = allParentNodes.find((n) => String(n.id) === String(targetNodeId));
|
|
@@ -1893,9 +1902,6 @@ var userActionHandlers = {
|
|
|
1893
1902
|
console.warn(`Dados do Node com ID ${targetNodeId} n\xE3o encontrados no cache.`);
|
|
1894
1903
|
return;
|
|
1895
1904
|
}
|
|
1896
|
-
if (!sceneDataRef.current.nodes.some((n) => String(n.id) === String(nodeData.id))) {
|
|
1897
|
-
sceneDataRef.current.nodes.push(nodeData);
|
|
1898
|
-
}
|
|
1899
1905
|
const startPosition = sourceNodeMesh.position.clone();
|
|
1900
1906
|
const endPosition = startPosition.clone().add(
|
|
1901
1907
|
new THREE.Vector3((Math.random() - 0.5) * 60, (Math.random() - 0.5) * 15, (Math.random() - 0.5) * 60)
|
|
@@ -2015,6 +2021,7 @@ var userActionHandlers = {
|
|
|
2015
2021
|
if (mountRef.current) mountRef.current.style.cursor = "grab";
|
|
2016
2022
|
},
|
|
2017
2023
|
handleCompleteConnection: async (context, targetNodeData) => {
|
|
2024
|
+
var _a;
|
|
2018
2025
|
const { stateRef, graphDataRef, sceneDataRef } = context;
|
|
2019
2026
|
const { sourceNodeData } = stateRef.current.connection;
|
|
2020
2027
|
if (!graphDataRef.current || !sceneDataRef.current || !sourceNodeData || !targetNodeData) {
|
|
@@ -2022,7 +2029,7 @@ var userActionHandlers = {
|
|
|
2022
2029
|
userActionHandlers.handleCancelConnection(context);
|
|
2023
2030
|
return;
|
|
2024
2031
|
}
|
|
2025
|
-
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
|
|
2032
|
+
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
|
|
2026
2033
|
if (!sourceParentInfo || !sourceParentInfo.ownerId) {
|
|
2027
2034
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:", sourceNodeData.id);
|
|
2028
2035
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
|
|
@@ -2037,12 +2044,26 @@ var userActionHandlers = {
|
|
|
2037
2044
|
source: sourceNodeData.id,
|
|
2038
2045
|
target: targetNodeData.id
|
|
2039
2046
|
};
|
|
2040
|
-
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
|
|
2041
|
-
specificParentData.links.push(newLink);
|
|
2042
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
|
|
2043
2047
|
try {
|
|
2044
|
-
|
|
2045
|
-
|
|
2048
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2049
|
+
if (isView && parentFileIdToSave === context.sceneConfigId) {
|
|
2050
|
+
const specificParentData = graphDataRef.current[context.sceneConfigId];
|
|
2051
|
+
specificParentData.links.push(newLink);
|
|
2052
|
+
const viewFilePayload = {
|
|
2053
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2054
|
+
nodes: sceneDataRef.current.nodes,
|
|
2055
|
+
links: sceneDataRef.current.links,
|
|
2056
|
+
quest_nodes: specificParentData.nodes,
|
|
2057
|
+
quest_links: specificParentData.links
|
|
2058
|
+
};
|
|
2059
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2060
|
+
} else {
|
|
2061
|
+
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
|
|
2062
|
+
specificParentData.links.push(newLink);
|
|
2063
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
|
|
2064
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
2065
|
+
graphDataRef.current[parentFileIdToSave] = specificParentData;
|
|
2066
|
+
}
|
|
2046
2067
|
addNewLinkToScene(stateRef.current, newLink);
|
|
2047
2068
|
} catch (error) {
|
|
2048
2069
|
console.error("Falha ao salvar a nova conex\xE3o:", error);
|
|
@@ -2111,14 +2132,28 @@ var userActionHandlers = {
|
|
|
2111
2132
|
} else {
|
|
2112
2133
|
newTargetId = newEndNodeData.id;
|
|
2113
2134
|
}
|
|
2114
|
-
const
|
|
2115
|
-
const
|
|
2116
|
-
|
|
2117
|
-
|
|
2135
|
+
const oldSourceInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId, context.sceneConfigId, context.ownerId);
|
|
2136
|
+
const oldTargetInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldTargetId, context.sceneConfigId, context.ownerId);
|
|
2137
|
+
const newSourceInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId, context.sceneConfigId, context.ownerId);
|
|
2138
|
+
const newTargetInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newTargetId, context.sceneConfigId, context.ownerId);
|
|
2139
|
+
if (!oldSourceInfo || !oldTargetInfo || !newSourceInfo || !newTargetInfo) {
|
|
2140
|
+
console.error("Informa\xE7\xF5es dos arquivos pai incompletas para o relink.");
|
|
2118
2141
|
alert("Ocorreu um erro ao identificar os arquivos pai para salvar a altera\xE7\xE3o.");
|
|
2119
2142
|
userActionHandlers.handleCancelRelink(context);
|
|
2120
2143
|
return;
|
|
2121
2144
|
}
|
|
2145
|
+
let oldGoverningFileId = oldSourceInfo.parentFileId;
|
|
2146
|
+
let oldGoverningOwnerId = oldSourceInfo.ownerId;
|
|
2147
|
+
if (oldSourceInfo.parentFileId === context.sceneConfigId || oldTargetInfo.parentFileId === context.sceneConfigId) {
|
|
2148
|
+
oldGoverningFileId = context.sceneConfigId;
|
|
2149
|
+
oldGoverningOwnerId = context.ownerId;
|
|
2150
|
+
}
|
|
2151
|
+
let newGoverningFileId = newSourceInfo.parentFileId;
|
|
2152
|
+
let newGoverningOwnerId = newSourceInfo.ownerId;
|
|
2153
|
+
if (newSourceInfo.parentFileId === context.sceneConfigId || newTargetInfo.parentFileId === context.sceneConfigId) {
|
|
2154
|
+
newGoverningFileId = context.sceneConfigId;
|
|
2155
|
+
newGoverningOwnerId = context.ownerId;
|
|
2156
|
+
}
|
|
2122
2157
|
const { sourceNode, targetNode, ...dataToKeep } = originalLinkData;
|
|
2123
2158
|
const newLinkData = {
|
|
2124
2159
|
...dataToKeep,
|
|
@@ -2126,34 +2161,44 @@ var userActionHandlers = {
|
|
|
2126
2161
|
target: newTargetId,
|
|
2127
2162
|
id: linkId
|
|
2128
2163
|
};
|
|
2164
|
+
const saveParentData = async (fileId, fileOwnerId, data) => {
|
|
2165
|
+
var _a;
|
|
2166
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2167
|
+
if (isView && fileId === context.sceneConfigId) {
|
|
2168
|
+
const viewFilePayload = {
|
|
2169
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2170
|
+
nodes: sceneDataRef.current.nodes,
|
|
2171
|
+
links: sceneDataRef.current.links,
|
|
2172
|
+
quest_nodes: data.nodes,
|
|
2173
|
+
quest_links: data.links
|
|
2174
|
+
};
|
|
2175
|
+
return context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2176
|
+
} else {
|
|
2177
|
+
return context.actions.save_view_data(`x_view_dbs/${fileOwnerId}/${fileId}`, data);
|
|
2178
|
+
}
|
|
2179
|
+
};
|
|
2129
2180
|
const savePromises = [];
|
|
2130
2181
|
const filesToUpdate = {};
|
|
2131
|
-
if (
|
|
2132
|
-
const updatedOriginalParentData = JSON.parse(JSON.stringify(graphDataRef.current[
|
|
2182
|
+
if (oldGoverningFileId !== newGoverningFileId) {
|
|
2183
|
+
const updatedOriginalParentData = JSON.parse(JSON.stringify(graphDataRef.current[oldGoverningFileId]));
|
|
2133
2184
|
updatedOriginalParentData.links = updatedOriginalParentData.links.filter(
|
|
2134
2185
|
(l) => String(l.id) !== String(linkId)
|
|
2135
2186
|
);
|
|
2136
|
-
filesToUpdate[
|
|
2137
|
-
savePromises.push(
|
|
2138
|
-
|
|
2139
|
-
);
|
|
2140
|
-
const updatedNewParentData = JSON.parse(JSON.stringify(graphDataRef.current[newParentInfo.parentFileId]));
|
|
2187
|
+
filesToUpdate[oldGoverningFileId] = updatedOriginalParentData;
|
|
2188
|
+
savePromises.push(saveParentData(oldGoverningFileId, oldGoverningOwnerId, updatedOriginalParentData));
|
|
2189
|
+
const updatedNewParentData = JSON.parse(JSON.stringify(graphDataRef.current[newGoverningFileId]));
|
|
2141
2190
|
if (!updatedNewParentData.links) updatedNewParentData.links = [];
|
|
2142
2191
|
updatedNewParentData.links.push(newLinkData);
|
|
2143
|
-
filesToUpdate[
|
|
2144
|
-
savePromises.push(
|
|
2145
|
-
context.actions.save_view_data(`x_view_dbs/${newParentInfo.ownerId}/${newParentInfo.parentFileId}`, updatedNewParentData)
|
|
2146
|
-
);
|
|
2192
|
+
filesToUpdate[newGoverningFileId] = updatedNewParentData;
|
|
2193
|
+
savePromises.push(saveParentData(newGoverningFileId, newGoverningOwnerId, updatedNewParentData));
|
|
2147
2194
|
} else {
|
|
2148
|
-
const updatedParentData = JSON.parse(JSON.stringify(graphDataRef.current[
|
|
2195
|
+
const updatedParentData = JSON.parse(JSON.stringify(graphDataRef.current[oldGoverningFileId]));
|
|
2149
2196
|
updatedParentData.links = updatedParentData.links.filter(
|
|
2150
2197
|
(l) => String(l.id) !== String(linkId)
|
|
2151
2198
|
);
|
|
2152
2199
|
updatedParentData.links.push(newLinkData);
|
|
2153
|
-
filesToUpdate[
|
|
2154
|
-
savePromises.push(
|
|
2155
|
-
context.actions.save_view_data(`x_view_dbs/${originalParentInfo.ownerId}/${originalParentInfo.parentFileId}`, updatedParentData)
|
|
2156
|
-
);
|
|
2200
|
+
filesToUpdate[oldGoverningFileId] = updatedParentData;
|
|
2201
|
+
savePromises.push(saveParentData(oldGoverningFileId, oldGoverningOwnerId, updatedParentData));
|
|
2157
2202
|
}
|
|
2158
2203
|
try {
|
|
2159
2204
|
await Promise.all(savePromises);
|
|
@@ -2171,7 +2216,7 @@ var userActionHandlers = {
|
|
|
2171
2216
|
}
|
|
2172
2217
|
},
|
|
2173
2218
|
handleDeleteLink: async (context, linkObject) => {
|
|
2174
|
-
var _a, _b, _c, _d, _e, _f;
|
|
2219
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2175
2220
|
const { stateRef, graphDataRef, sceneDataRef, setters } = context;
|
|
2176
2221
|
setters.setRelationshipMenu({ visible: false });
|
|
2177
2222
|
if (!(linkObject == null ? void 0 : linkObject.userData) || !graphDataRef.current || !sceneDataRef.current) return;
|
|
@@ -2180,7 +2225,7 @@ var userActionHandlers = {
|
|
|
2180
2225
|
console.error("Tentativa de deletar um link sem ID.", linkObject.userData);
|
|
2181
2226
|
return;
|
|
2182
2227
|
}
|
|
2183
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source);
|
|
2228
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source, context.sceneConfigId, context.ownerId);
|
|
2184
2229
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2185
2230
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link:", linkIdToDelete);
|
|
2186
2231
|
alert("Ocorreu um erro ao identificar o arquivo pai da rela\xE7\xE3o para exclus\xE3o.");
|
|
@@ -2192,9 +2237,25 @@ var userActionHandlers = {
|
|
|
2192
2237
|
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
|
|
2193
2238
|
const newLinks = (specificParentData.links || []).filter((l) => String(l.id) !== String(linkIdToDelete));
|
|
2194
2239
|
specificParentData.links = newLinks;
|
|
2195
|
-
|
|
2240
|
+
let filenameToSave;
|
|
2241
|
+
let payloadToSave;
|
|
2242
|
+
const isView = ((_g = context.viewType) == null ? void 0 : _g.toLowerCase()) === "view";
|
|
2243
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2244
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2245
|
+
sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => String(l.id) !== String(linkIdToDelete));
|
|
2246
|
+
payloadToSave = {
|
|
2247
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2248
|
+
nodes: sceneDataRef.current.nodes,
|
|
2249
|
+
links: sceneDataRef.current.links,
|
|
2250
|
+
quest_nodes: specificParentData.nodes,
|
|
2251
|
+
quest_links: specificParentData.links
|
|
2252
|
+
};
|
|
2253
|
+
} else {
|
|
2254
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2255
|
+
payloadToSave = specificParentData;
|
|
2256
|
+
}
|
|
2196
2257
|
try {
|
|
2197
|
-
await context.actions.save_view_data(
|
|
2258
|
+
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2198
2259
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2199
2260
|
setters.setDetailsLink((prev) => String(prev == null ? void 0 : prev.id) === String(linkIdToDelete) ? null : prev);
|
|
2200
2261
|
if (stateRef.current.hoveredLink === linkObject) {
|
|
@@ -2212,12 +2273,6 @@ var userActionHandlers = {
|
|
|
2212
2273
|
if (!nodeData || !sceneDataRef.current) return;
|
|
2213
2274
|
const nodeIdToDismiss = nodeData.id;
|
|
2214
2275
|
const strNodeId = String(nodeIdToDismiss);
|
|
2215
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2216
|
-
(n) => String(n.id) !== strNodeId
|
|
2217
|
-
);
|
|
2218
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2219
|
-
(l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId
|
|
2220
|
-
);
|
|
2221
2276
|
const { ancestryGroup, ancestryLinks } = stateRef.current;
|
|
2222
2277
|
if (ancestryGroup && ancestryLinks) {
|
|
2223
2278
|
const remainingAncestryLinks = [];
|
|
@@ -2259,22 +2314,12 @@ var userActionHandlers = {
|
|
|
2259
2314
|
removeNodeFromScene(stateRef.current, nodeId);
|
|
2260
2315
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
|
|
2261
2316
|
});
|
|
2262
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2263
|
-
(n) => String(n.id) === strNodeIdToKeep
|
|
2264
|
-
);
|
|
2265
|
-
sceneDataRef.current.links = [];
|
|
2266
2317
|
},
|
|
2267
2318
|
handleDismissMultipleNodes: (context, nodeIds) => {
|
|
2268
2319
|
const { stateRef, sceneDataRef, setters } = context;
|
|
2269
2320
|
setters.setMultiContextMenu({ visible: false });
|
|
2270
2321
|
if (!nodeIds || nodeIds.size === 0 || !sceneDataRef.current) return;
|
|
2271
2322
|
const strNodeIds = Array.from(nodeIds).map(String);
|
|
2272
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2273
|
-
(n) => !strNodeIds.includes(String(n.id))
|
|
2274
|
-
);
|
|
2275
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2276
|
-
(l) => !strNodeIds.includes(String(l.source)) && !strNodeIds.includes(String(l.target))
|
|
2277
|
-
);
|
|
2278
2323
|
const { ancestryGroup, ancestryLinks } = stateRef.current;
|
|
2279
2324
|
if (ancestryGroup && ancestryLinks) {
|
|
2280
2325
|
const remainingAncestryLinks = [];
|
|
@@ -2330,15 +2375,10 @@ var userActionHandlers = {
|
|
|
2330
2375
|
removeNodeFromScene(stateRef.current, nodeId);
|
|
2331
2376
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
|
|
2332
2377
|
});
|
|
2333
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2334
|
-
(n) => strNodeIdsToKeep.includes(String(n.id))
|
|
2335
|
-
);
|
|
2336
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2337
|
-
(l) => strNodeIdsToKeep.includes(String(l.source)) && strNodeIdsToKeep.includes(String(l.target))
|
|
2338
|
-
);
|
|
2339
2378
|
stateRef.current.selectedNodes.clear();
|
|
2340
2379
|
},
|
|
2341
2380
|
handleDeleteMultipleNodes: async (context, nodeIds) => {
|
|
2381
|
+
var _a;
|
|
2342
2382
|
const { stateRef, graphDataRef, sceneDataRef, setters, actions } = context;
|
|
2343
2383
|
setters.setMultiContextMenu({ visible: false });
|
|
2344
2384
|
if (!nodeIds || nodeIds.size === 0 || !graphDataRef.current || !sceneDataRef.current) return;
|
|
@@ -2357,7 +2397,7 @@ var userActionHandlers = {
|
|
|
2357
2397
|
}
|
|
2358
2398
|
const changesByParentFile = {};
|
|
2359
2399
|
for (const nodeId of strNodeIdsToDelete) {
|
|
2360
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId);
|
|
2400
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId, context.sceneConfigId, context.ownerId);
|
|
2361
2401
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2362
2402
|
console.warn(`Node com ID ${nodeId} n\xE3o encontrado ou sem ownerId. Ignorando.`);
|
|
2363
2403
|
continue;
|
|
@@ -2391,8 +2431,27 @@ var userActionHandlers = {
|
|
|
2391
2431
|
originalData.links = (originalData.links || []).filter(
|
|
2392
2432
|
(l) => !linksToDelete.has(String(l.id))
|
|
2393
2433
|
);
|
|
2394
|
-
|
|
2395
|
-
|
|
2434
|
+
let filenameToSave;
|
|
2435
|
+
let payloadToSave;
|
|
2436
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2437
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2438
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2439
|
+
const strNodesToDelete = Array.from(nodesToDelete).map(String);
|
|
2440
|
+
const strLinksToDelete = Array.from(linksToDelete).map(String);
|
|
2441
|
+
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter((n) => !strNodesToDelete.includes(String(n.id)));
|
|
2442
|
+
sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => !strLinksToDelete.includes(String(l.id)));
|
|
2443
|
+
payloadToSave = {
|
|
2444
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2445
|
+
nodes: sceneDataRef.current.nodes,
|
|
2446
|
+
links: sceneDataRef.current.links,
|
|
2447
|
+
quest_nodes: originalData.nodes,
|
|
2448
|
+
quest_links: originalData.links
|
|
2449
|
+
};
|
|
2450
|
+
} else {
|
|
2451
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2452
|
+
payloadToSave = originalData;
|
|
2453
|
+
}
|
|
2454
|
+
savePromises.push(context.actions.save_view_data(filenameToSave, payloadToSave));
|
|
2396
2455
|
updatedParentDataCache[parentFileId] = originalData;
|
|
2397
2456
|
}
|
|
2398
2457
|
}
|
|
@@ -2413,6 +2472,7 @@ var userActionHandlers = {
|
|
|
2413
2472
|
}
|
|
2414
2473
|
},
|
|
2415
2474
|
handleDeleteNode: async (context, nodeData) => {
|
|
2475
|
+
var _a;
|
|
2416
2476
|
const { stateRef, graphDataRef, sceneDataRef, setters, actions } = context;
|
|
2417
2477
|
if (actions.delete_file && nodeData) {
|
|
2418
2478
|
const urls = extractFileUrlsFromProperties(nodeData);
|
|
@@ -2424,7 +2484,7 @@ var userActionHandlers = {
|
|
|
2424
2484
|
if (!nodeData || !graphDataRef.current || !sceneDataRef.current) return;
|
|
2425
2485
|
const nodeIdToDelete = nodeData.id;
|
|
2426
2486
|
const strNodeId = String(nodeIdToDelete);
|
|
2427
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete);
|
|
2487
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete, context.sceneConfigId, context.ownerId);
|
|
2428
2488
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2429
2489
|
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);
|
|
2430
2490
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para exclus\xE3o.");
|
|
@@ -2436,9 +2496,28 @@ var userActionHandlers = {
|
|
|
2436
2496
|
const newLinks = (specificParentData.links || []).filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
|
|
2437
2497
|
specificParentData.nodes = newNodes;
|
|
2438
2498
|
specificParentData.links = newLinks;
|
|
2439
|
-
|
|
2499
|
+
let filenameToSave;
|
|
2500
|
+
let payloadToSave;
|
|
2501
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2502
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2503
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2504
|
+
const newVisualNodes = sceneDataRef.current.nodes.filter((n) => String(n.id) !== strNodeId);
|
|
2505
|
+
const newVisualLinks = sceneDataRef.current.links.filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
|
|
2506
|
+
sceneDataRef.current.nodes = newVisualNodes;
|
|
2507
|
+
sceneDataRef.current.links = newVisualLinks;
|
|
2508
|
+
payloadToSave = {
|
|
2509
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2510
|
+
nodes: newVisualNodes,
|
|
2511
|
+
links: newVisualLinks,
|
|
2512
|
+
quest_nodes: specificParentData.nodes,
|
|
2513
|
+
quest_links: specificParentData.links
|
|
2514
|
+
};
|
|
2515
|
+
} else {
|
|
2516
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2517
|
+
payloadToSave = specificParentData;
|
|
2518
|
+
}
|
|
2440
2519
|
try {
|
|
2441
|
-
await context.actions.save_view_data(
|
|
2520
|
+
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2442
2521
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2443
2522
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeIdToDelete) ? null : prev);
|
|
2444
2523
|
removeNodeFromScene(stateRef.current, nodeIdToDelete);
|
|
@@ -2449,10 +2528,11 @@ var userActionHandlers = {
|
|
|
2449
2528
|
}
|
|
2450
2529
|
},
|
|
2451
2530
|
handleSaveNodeDetails: async (context, updatedNode, keepOpen = false) => {
|
|
2531
|
+
var _a;
|
|
2452
2532
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2453
2533
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2454
2534
|
const { _baseEmissiveIntensity: ignored, ...nodeToSave } = updatedNode;
|
|
2455
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id);
|
|
2535
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id, context.sceneConfigId, context.ownerId);
|
|
2456
2536
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2457
2537
|
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);
|
|
2458
2538
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
|
|
@@ -2468,9 +2548,21 @@ var userActionHandlers = {
|
|
|
2468
2548
|
alert("Erro interno: Node n\xE3o encontrado para salvar.");
|
|
2469
2549
|
return;
|
|
2470
2550
|
}
|
|
2471
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2472
2551
|
try {
|
|
2473
|
-
|
|
2552
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2553
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2554
|
+
const viewFilePayload = {
|
|
2555
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2556
|
+
nodes: sceneDataRef.current.nodes,
|
|
2557
|
+
links: sceneDataRef.current.links,
|
|
2558
|
+
quest_nodes: specificParentData.nodes,
|
|
2559
|
+
quest_links: specificParentData.links
|
|
2560
|
+
};
|
|
2561
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2562
|
+
} else {
|
|
2563
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2564
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
2565
|
+
}
|
|
2474
2566
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2475
2567
|
updateExistingNodeVisuals(stateRef.current, nodeToSave);
|
|
2476
2568
|
setters.setSceneVersion((v) => v + 1);
|
|
@@ -2483,10 +2575,11 @@ var userActionHandlers = {
|
|
|
2483
2575
|
}
|
|
2484
2576
|
},
|
|
2485
2577
|
handleSaveLinkDetails: async (context, updatedLink, keepOpen = false) => {
|
|
2578
|
+
var _a;
|
|
2486
2579
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2487
2580
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2488
2581
|
const { sourceNode, targetNode, ...linkToSave } = updatedLink;
|
|
2489
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source);
|
|
2582
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source, context.sceneConfigId, context.ownerId);
|
|
2490
2583
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2491
2584
|
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);
|
|
2492
2585
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
|
|
@@ -2502,9 +2595,21 @@ var userActionHandlers = {
|
|
|
2502
2595
|
alert("Erro interno: link n\xE3o encontrado para salvar.");
|
|
2503
2596
|
return;
|
|
2504
2597
|
}
|
|
2505
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2506
2598
|
try {
|
|
2507
|
-
|
|
2599
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2600
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2601
|
+
const viewFilePayload = {
|
|
2602
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2603
|
+
nodes: sceneDataRef.current.nodes,
|
|
2604
|
+
links: sceneDataRef.current.links,
|
|
2605
|
+
quest_nodes: specificParentData.nodes,
|
|
2606
|
+
quest_links: specificParentData.links
|
|
2607
|
+
};
|
|
2608
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2609
|
+
} else {
|
|
2610
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2611
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
2612
|
+
}
|
|
2508
2613
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2509
2614
|
const lineObject = stateRef.current.allLinks.find(
|
|
2510
2615
|
(l) => String(l.userData.id) === String(linkToSave.id)
|
|
@@ -2527,7 +2632,7 @@ var userActionHandlers = {
|
|
|
2527
2632
|
}
|
|
2528
2633
|
},
|
|
2529
2634
|
handleAddExistingNodeById: (context, nodeId) => {
|
|
2530
|
-
var _a
|
|
2635
|
+
var _a;
|
|
2531
2636
|
const { stateRef, sceneDataRef, graphDataRef, tweenToTarget, setters } = context;
|
|
2532
2637
|
const state = stateRef.current;
|
|
2533
2638
|
const graphFull = graphDataRef.current;
|
|
@@ -2543,16 +2648,12 @@ var userActionHandlers = {
|
|
|
2543
2648
|
tweenToTarget(state.nodeObjects[strNodeId]);
|
|
2544
2649
|
return;
|
|
2545
2650
|
}
|
|
2546
|
-
const alreadyInSceneData = (((_a = sceneDataRef.current) == null ? void 0 : _a.nodes) || []).some((n) => String(n.id) === String(strNodeId));
|
|
2547
|
-
if (!alreadyInSceneData) {
|
|
2548
|
-
sceneDataRef.current.nodes.push(nodeData);
|
|
2549
|
-
}
|
|
2550
2651
|
const base = state.controls ? state.controls.target.clone() : new THREE.Vector3(0, 0, 0);
|
|
2551
2652
|
const offset = new THREE.Vector3((Math.random() - 0.5) * 20, (Math.random() - 0.5) * 6, (Math.random() - 0.5) * 20);
|
|
2552
2653
|
const position = base.add(offset);
|
|
2553
2654
|
addStandaloneNodeToScene(state, nodeData, position);
|
|
2554
2655
|
tweenToTarget(position, 1.3);
|
|
2555
|
-
(
|
|
2656
|
+
(_a = setters == null ? void 0 : setters.setSceneVersion) == null ? void 0 : _a.call(setters, (v) => v + 1);
|
|
2556
2657
|
}
|
|
2557
2658
|
};
|
|
2558
2659
|
|
|
@@ -7853,13 +7954,9 @@ var import_react16 = __toESM(require("react"));
|
|
|
7853
7954
|
var import_fi14 = require("react-icons/fi");
|
|
7854
7955
|
var QUEST_STATUS_COLORS = {
|
|
7855
7956
|
"Backlog": "#64748b",
|
|
7856
|
-
// Slate (Cinza azulado)
|
|
7857
7957
|
"In Progress": "#eab308",
|
|
7858
|
-
// Yellow (Amarelo)
|
|
7859
7958
|
"Review": "#a855f7",
|
|
7860
|
-
// Purple (Roxo)
|
|
7861
7959
|
"Done": "#22c55e"
|
|
7862
|
-
// Green (Verde)
|
|
7863
7960
|
};
|
|
7864
7961
|
function InSceneQuestForm({
|
|
7865
7962
|
onSave,
|
|
@@ -7870,7 +7967,11 @@ function InSceneQuestForm({
|
|
|
7870
7967
|
availableNodes = [],
|
|
7871
7968
|
availableAncestries = [],
|
|
7872
7969
|
onMentionClick,
|
|
7873
|
-
onUploadFile
|
|
7970
|
+
onUploadFile,
|
|
7971
|
+
// NOVAS PROPS PARA O GHOST NODE
|
|
7972
|
+
onNameChange,
|
|
7973
|
+
onColorChange,
|
|
7974
|
+
onSizeChange
|
|
7874
7975
|
}) {
|
|
7875
7976
|
const [name, setName] = (0, import_react16.useState)("");
|
|
7876
7977
|
const [types, setTypes] = (0, import_react16.useState)(["quest"]);
|
|
@@ -7879,6 +7980,7 @@ function InSceneQuestForm({
|
|
|
7879
7980
|
const [size, setSize] = (0, import_react16.useState)("medium");
|
|
7880
7981
|
const [intensity, setIntensity] = (0, import_react16.useState)(0);
|
|
7881
7982
|
const [description, setDescription] = (0, import_react16.useState)("");
|
|
7983
|
+
const [isStatusDropdownOpen, setIsStatusDropdownOpen] = (0, import_react16.useState)(false);
|
|
7882
7984
|
const [customProps, setCustomProps] = (0, import_react16.useState)([]);
|
|
7883
7985
|
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react16.useState)(false);
|
|
7884
7986
|
const propsEndRef = (0, import_react16.useRef)(null);
|
|
@@ -7897,7 +7999,7 @@ function InSceneQuestForm({
|
|
|
7897
7999
|
setCustomProps(newProps);
|
|
7898
8000
|
};
|
|
7899
8001
|
const handleAddType = (newType) => {
|
|
7900
|
-
const trimmed = newType.trim()
|
|
8002
|
+
const trimmed = newType.trim();
|
|
7901
8003
|
if (trimmed && !types.includes(trimmed)) {
|
|
7902
8004
|
setTypes([...types, trimmed]);
|
|
7903
8005
|
setTypeInput("");
|
|
@@ -7929,7 +8031,6 @@ function InSceneQuestForm({
|
|
|
7929
8031
|
name: name.trim(),
|
|
7930
8032
|
type: types,
|
|
7931
8033
|
color: QUEST_STATUS_COLORS[status],
|
|
7932
|
-
// Cor atrelada ao status
|
|
7933
8034
|
status,
|
|
7934
8035
|
size,
|
|
7935
8036
|
intensity,
|
|
@@ -7956,20 +8057,52 @@ function InSceneQuestForm({
|
|
|
7956
8057
|
onDoubleClick: swallow
|
|
7957
8058
|
},
|
|
7958
8059
|
/* @__PURE__ */ import_react16.default.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS[status]}, transparent)` } }),
|
|
7959
|
-
/* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pt-5 pb-3" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ import_react16.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
style: { borderLeft: `4px solid ${QUEST_STATUS_COLORS[status]}` }
|
|
8060
|
+
/* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react16.default.createElement("div", null, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ import_react16.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova quest")), /* @__PURE__ */ import_react16.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")), /* @__PURE__ */ import_react16.default.createElement(
|
|
8061
|
+
"button",
|
|
8062
|
+
{
|
|
8063
|
+
type: "button",
|
|
8064
|
+
onClick: onCancel,
|
|
8065
|
+
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",
|
|
8066
|
+
title: "Fechar"
|
|
7967
8067
|
},
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
8068
|
+
"\xD7"
|
|
8069
|
+
)),
|
|
8070
|
+
/* @__PURE__ */ import_react16.default.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col max-h-[68vh]" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ import_react16.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react16.default.createElement(
|
|
8071
|
+
"button",
|
|
8072
|
+
{
|
|
8073
|
+
type: "button",
|
|
8074
|
+
onClick: () => setIsStatusDropdownOpen(!isStatusDropdownOpen),
|
|
8075
|
+
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"
|
|
8076
|
+
},
|
|
8077
|
+
/* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement("span", { className: "text-slate-200 font-medium" }, status)),
|
|
8078
|
+
/* @__PURE__ */ import_react16.default.createElement(import_fi14.FiChevronDown, { className: `text-slate-400 transition-transform duration-200 ${isStatusDropdownOpen ? "rotate-180" : ""}` })
|
|
8079
|
+
), isStatusDropdownOpen && /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null, /* @__PURE__ */ import_react16.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsStatusDropdownOpen(false) }), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(
|
|
8080
|
+
"li",
|
|
8081
|
+
{
|
|
8082
|
+
key: s,
|
|
8083
|
+
onClick: () => {
|
|
8084
|
+
setStatus(s);
|
|
8085
|
+
setIsStatusDropdownOpen(false);
|
|
8086
|
+
onColorChange == null ? void 0 : onColorChange(QUEST_STATUS_COLORS[s]);
|
|
8087
|
+
},
|
|
8088
|
+
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"}`
|
|
8089
|
+
},
|
|
8090
|
+
/* @__PURE__ */ import_react16.default.createElement("span", { className: "w-3 h-3 rounded-full", style: { backgroundColor: QUEST_STATUS_COLORS[s] } }),
|
|
8091
|
+
s
|
|
8092
|
+
)))))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Quest"), /* @__PURE__ */ import_react16.default.createElement(
|
|
8093
|
+
"input",
|
|
8094
|
+
{
|
|
8095
|
+
required: true,
|
|
8096
|
+
type: "text",
|
|
8097
|
+
placeholder: "Ex.: Refatorar M\xF3dulo X",
|
|
8098
|
+
value: name,
|
|
8099
|
+
onChange: (e) => {
|
|
8100
|
+
setName(e.target.value);
|
|
8101
|
+
onNameChange == null ? void 0 : onNameChange(e.target.value);
|
|
8102
|
+
},
|
|
8103
|
+
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"
|
|
8104
|
+
}
|
|
8105
|
+
)), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Tipos Adicionais"), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.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__ */ import_react16.default.createElement("button", { type: "button", onClick: () => handleRemoveType(index), className: "hover:text-white transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiX, { size: 12 })))), /* @__PURE__ */ import_react16.default.createElement(
|
|
7973
8106
|
"input",
|
|
7974
8107
|
{
|
|
7975
8108
|
type: "text",
|
|
@@ -7980,7 +8113,6 @@ function InSceneQuestForm({
|
|
|
7980
8113
|
if (typeInput.trim()) handleAddType(typeInput);
|
|
7981
8114
|
},
|
|
7982
8115
|
className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
|
|
7983
|
-
placeholder: "Ex.: Bugfix",
|
|
7984
8116
|
autoComplete: "off"
|
|
7985
8117
|
}
|
|
7986
8118
|
))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(
|
|
@@ -7993,7 +8125,20 @@ function InSceneQuestForm({
|
|
|
7993
8125
|
onMentionClick,
|
|
7994
8126
|
onSaveDescription: (newDesc) => setDescription(newDesc)
|
|
7995
8127
|
}
|
|
7996
|
-
), /* @__PURE__ */ import_react16.default.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react16.default.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiEdit2, { size: 14 }))), !description && /* @__PURE__ */ import_react16.default.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no
|
|
8128
|
+
), /* @__PURE__ */ import_react16.default.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react16.default.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiEdit2, { size: 14 }))), !description && /* @__PURE__ */ import_react16.default.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ import_react16.default.createElement(
|
|
8129
|
+
"button",
|
|
8130
|
+
{
|
|
8131
|
+
key: s,
|
|
8132
|
+
type: "button",
|
|
8133
|
+
onClick: () => {
|
|
8134
|
+
setSize(s);
|
|
8135
|
+
onSizeChange == null ? void 0 : onSizeChange(s);
|
|
8136
|
+
},
|
|
8137
|
+
className: "flex items-center gap-2 group cursor-pointer focus:outline-none"
|
|
8138
|
+
},
|
|
8139
|
+
/* @__PURE__ */ import_react16.default.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${size === s ? "bg-indigo-500 border-indigo-500" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, size === s && /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiCheck, { size: 12, className: "text-white" })),
|
|
8140
|
+
/* @__PURE__ */ import_react16.default.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s)
|
|
8141
|
+
)))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react16.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ import_react16.default.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ import_react16.default.createElement(
|
|
7997
8142
|
CustomPropertyDisplay,
|
|
7998
8143
|
{
|
|
7999
8144
|
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 = (0, import_react25.useCallback)(() => {
|
|
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: import_short_uuid2.default.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_${import_short_uuid2.default.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 = (0, import_react25.useCallback)((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 = (0, import_react25.useCallback)(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 = (0, import_react25.useMemo)(() => {
|
|
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
|
+
(0, import_react25.useEffect)(() => {
|
|
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__ */ import_react25.default.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) => {
|