@lv-x-software-house/x_view 1.2.4-dev.2 → 1.2.4-dev.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +484 -178
- package/dist/index.mjs +491 -185
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -294,11 +294,12 @@ function ContextMenu({
|
|
|
294
294
|
});
|
|
295
295
|
};
|
|
296
296
|
const renderMainView = () => {
|
|
297
|
+
var _a2;
|
|
297
298
|
const hasVersions = computedVersions.length > 0;
|
|
298
299
|
const canCreateVersion = ability.can("create", "Versioning");
|
|
299
300
|
const canReadVersion = ability.can("read", "Versioning");
|
|
300
301
|
const shouldShowVersioningBtn = canCreateVersion || canReadVersion && hasVersions;
|
|
301
|
-
return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ import_react.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es R\xE1pidas")), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col gap-1" }, ability.can("create", "Connection") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartConnection == null ? void 0 : onStartConnection(data.nodeData), className: baseButtonClass, title: "Conectar" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Conectar")), ability.can("create", "Node") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartCreation == null ? void 0 : onStartCreation(data.nodeData), className: baseButtonClass, title: "Criar e Conectar" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "16" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "8", y1: "12", x2: "16", y2: "12" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Criar e Conectar")), ability.can("create", "Ancestry") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartAncestryCreation == null ? void 0 : onStartAncestryCreation(data.nodeData), className: baseButtonClass, title: "Criar Ancestralidade" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 20.5c.5-.5.8-1.2.8-2s-.3-1.5-.8-2c-.5-.5-1.2-.8-2-.8s-1.5.3-2 .8c-.5.5-.8 1.2-.8 2s.3 1.5.8 2c.5.5 1.2-.8 2 .8s1.5-.3 2-.8Z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 16v-3a2 2 0 0 1 2-2h4" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 3.5c.5.5.8 1.2.8 2s-.3 1.5-.8 2c-.5-.5-1.2-.8-2 .8s1.5.3-2-.8c-.5-.5-.8-1.2-.8-2s.3-1.5.8-2c.5.5 1.2-.8 2 .8s1.5.3 2 .8Z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 8v3a2 2 0 0 0 2 2h4" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Criar Ancestralidade")), shouldShowVersioningBtn && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("versioning"), className: baseButtonClass, title: hasVersions ? "Versionamento" : "Criar Versionamento" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("line", { x1: "6", y1: "3", x2: "6", y2: "15" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "18", cy: "6", r: "3" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "6", cy: "18", r: "3" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })), /* @__PURE__ */ import_react.default.createElement("span", null, hasVersions || !canCreateVersion ? "Versionamento" : "Criar Versionamento")), (connections.length > 0 || availableAncestries.length > 0) && ability.can("read", "Connection") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("connections"), className: baseButtonClass, title: "Conex\xF5es" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M8 12h8" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 8v8" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Conex\xF5es (", totalConnectionsCount, ")"))), /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
|
|
302
|
+
return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ import_react.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es R\xE1pidas")), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col gap-1" }, ability.can("create", "Connection") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartConnection == null ? void 0 : onStartConnection(data.nodeData), className: baseButtonClass, title: "Conectar" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Conectar")), ability.can("create", "Node") && !((_a2 = data.nodeData) == null ? void 0 : _a2.is_quest) && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartCreation == null ? void 0 : onStartCreation(data.nodeData), className: baseButtonClass, title: "Criar e Conectar" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "16" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "8", y1: "12", x2: "16", y2: "12" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Criar e Conectar")), ability.can("create", "Ancestry") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartAncestryCreation == null ? void 0 : onStartAncestryCreation(data.nodeData), className: baseButtonClass, title: "Criar Ancestralidade" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 20.5c.5-.5.8-1.2.8-2s-.3-1.5-.8-2c-.5-.5-1.2-.8-2-.8s-1.5.3-2 .8c-.5.5-.8 1.2-.8 2s.3 1.5.8 2c.5.5 1.2-.8 2 .8s1.5-.3 2-.8Z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 16v-3a2 2 0 0 1 2-2h4" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 3.5c.5.5.8 1.2.8 2s-.3 1.5-.8 2c-.5-.5-1.2-.8-2 .8s1.5.3-2-.8c-.5-.5-.8-1.2-.8-2s.3-1.5.8-2c.5.5 1.2-.8 2 .8s1.5.3 2 .8Z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 8v3a2 2 0 0 0 2 2h4" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Criar Ancestralidade")), shouldShowVersioningBtn && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("versioning"), className: baseButtonClass, title: hasVersions ? "Versionamento" : "Criar Versionamento" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("line", { x1: "6", y1: "3", x2: "6", y2: "15" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "18", cy: "6", r: "3" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "6", cy: "18", r: "3" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })), /* @__PURE__ */ import_react.default.createElement("span", null, hasVersions || !canCreateVersion ? "Versionamento" : "Criar Versionamento")), (connections.length > 0 || availableAncestries.length > 0) && ability.can("read", "Connection") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("connections"), className: baseButtonClass, title: "Conex\xF5es" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M8 12h8" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 8v8" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Conex\xF5es (", totalConnectionsCount, ")"))), /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
|
|
302
303
|
onFocusNode == null ? void 0 : onFocusNode(data.nodeData);
|
|
303
304
|
onClose();
|
|
304
305
|
}, className: baseButtonClass, title: "Focar na c\xE2mera" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Focar neste Node")), /* @__PURE__ */ import_react.default.createElement("button", { onClick: (e) => handleCopyLink(e, data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, isLinkCopied ? /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#4ade80", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "20 6 9 17 4 12" })) : /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ import_react.default.createElement("span", { className: isLinkCopied ? "text-green-400" : "" }, isLinkCopied ? "Copiado!" : "Copiar Link")), ability.can("dismiss", "Node") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDismissNode == null ? void 0 : onDismissNode(data.nodeData), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Dismiss")), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDismissOtherNodes == null ? void 0 : onDismissOtherNodes(data.nodeData), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Dismiss other nodes"))), ability.can("delete", "Node") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("deleteConfirmation"), className: deleteButtonClass, title: "Excluir Node" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Excluir Node"))));
|
|
@@ -1225,8 +1226,6 @@ var createMultipleLinkLines = (linksArray, sourceNodeMesh, targetNodeMesh, resol
|
|
|
1225
1226
|
targetNodeMesh,
|
|
1226
1227
|
resolution,
|
|
1227
1228
|
isCurved,
|
|
1228
|
-
isCurved,
|
|
1229
|
-
isCurved,
|
|
1230
1229
|
curveOffset
|
|
1231
1230
|
);
|
|
1232
1231
|
line.userData = {
|
|
@@ -1559,7 +1558,7 @@ var addStandaloneNodeToScene = (state, nodeData, position) => {
|
|
|
1559
1558
|
scaleTween.start();
|
|
1560
1559
|
}
|
|
1561
1560
|
};
|
|
1562
|
-
var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
|
|
1561
|
+
var getParentFileInfoForNode = (allParentData, sceneData, nodeId, sceneConfigId = null, sceneOwnerId = null) => {
|
|
1563
1562
|
const parentDbsArray = (sceneData == null ? void 0 : sceneData.parent_dbs) || [];
|
|
1564
1563
|
for (const parentFileId in allParentData) {
|
|
1565
1564
|
if (allParentData.hasOwnProperty(parentFileId)) {
|
|
@@ -1568,6 +1567,8 @@ var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
|
|
|
1568
1567
|
const parentDbInfo = parentDbsArray.find((db) => String(db.db_id) === String(parentFileId));
|
|
1569
1568
|
if (parentDbInfo) {
|
|
1570
1569
|
return { parentFileId, ownerId: parentDbInfo.owner_id };
|
|
1570
|
+
} else if (sceneConfigId && String(parentFileId) === String(sceneConfigId)) {
|
|
1571
|
+
return { parentFileId, ownerId: sceneOwnerId };
|
|
1571
1572
|
} else {
|
|
1572
1573
|
console.warn(`Owner ID n\xE3o encontrado em sceneData.parent_dbs para o parentFileId: ${parentFileId}`);
|
|
1573
1574
|
return { parentFileId, ownerId: null };
|
|
@@ -1837,6 +1838,7 @@ var userActionHandlers = {
|
|
|
1837
1838
|
setters.setFormPosition((p) => ({ ...p, opacity: 0 }));
|
|
1838
1839
|
},
|
|
1839
1840
|
handleSaveVersionNode: async (context, newNodeData) => {
|
|
1841
|
+
var _a;
|
|
1840
1842
|
const { graphDataRef, sceneDataRef, stateRef, versionMode, setters } = context;
|
|
1841
1843
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
1842
1844
|
const { sourceNodeData } = versionMode;
|
|
@@ -1846,7 +1848,7 @@ var userActionHandlers = {
|
|
|
1846
1848
|
version_node: { is_version: true, parent_node: sourceNodeData.id }
|
|
1847
1849
|
};
|
|
1848
1850
|
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);
|
|
1851
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
|
|
1850
1852
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
1851
1853
|
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
1854
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
|
|
@@ -1856,9 +1858,21 @@ var userActionHandlers = {
|
|
|
1856
1858
|
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
|
|
1857
1859
|
specificParentData.nodes.push(newNode);
|
|
1858
1860
|
specificParentData.links.push(newLink);
|
|
1859
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
1860
1861
|
try {
|
|
1861
|
-
|
|
1862
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
1863
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
1864
|
+
const viewFilePayload = {
|
|
1865
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
1866
|
+
nodes: sceneDataRef.current.nodes,
|
|
1867
|
+
links: sceneDataRef.current.links,
|
|
1868
|
+
quest_nodes: specificParentData.nodes,
|
|
1869
|
+
quest_links: specificParentData.links
|
|
1870
|
+
};
|
|
1871
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
1872
|
+
} else {
|
|
1873
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
1874
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
1875
|
+
}
|
|
1862
1876
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
1863
1877
|
const finalPosition = stateRef.current.ghostElements.node.position.clone();
|
|
1864
1878
|
addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
|
|
@@ -1882,10 +1896,6 @@ var userActionHandlers = {
|
|
|
1882
1896
|
var _a;
|
|
1883
1897
|
const isSource = String(link.source) === String(sourceNode.id);
|
|
1884
1898
|
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
1899
|
if (!nodeObjects[String(targetNodeId)]) {
|
|
1890
1900
|
const allParentNodes = Object.values(graphDataRef.current).flatMap((fileData) => fileData.nodes);
|
|
1891
1901
|
const nodeData = allParentNodes.find((n) => String(n.id) === String(targetNodeId));
|
|
@@ -1893,9 +1903,6 @@ var userActionHandlers = {
|
|
|
1893
1903
|
console.warn(`Dados do Node com ID ${targetNodeId} n\xE3o encontrados no cache.`);
|
|
1894
1904
|
return;
|
|
1895
1905
|
}
|
|
1896
|
-
if (!sceneDataRef.current.nodes.some((n) => String(n.id) === String(nodeData.id))) {
|
|
1897
|
-
sceneDataRef.current.nodes.push(nodeData);
|
|
1898
|
-
}
|
|
1899
1906
|
const startPosition = sourceNodeMesh.position.clone();
|
|
1900
1907
|
const endPosition = startPosition.clone().add(
|
|
1901
1908
|
new THREE.Vector3((Math.random() - 0.5) * 60, (Math.random() - 0.5) * 15, (Math.random() - 0.5) * 60)
|
|
@@ -2015,6 +2022,7 @@ var userActionHandlers = {
|
|
|
2015
2022
|
if (mountRef.current) mountRef.current.style.cursor = "grab";
|
|
2016
2023
|
},
|
|
2017
2024
|
handleCompleteConnection: async (context, targetNodeData) => {
|
|
2025
|
+
var _a;
|
|
2018
2026
|
const { stateRef, graphDataRef, sceneDataRef } = context;
|
|
2019
2027
|
const { sourceNodeData } = stateRef.current.connection;
|
|
2020
2028
|
if (!graphDataRef.current || !sceneDataRef.current || !sourceNodeData || !targetNodeData) {
|
|
@@ -2022,7 +2030,7 @@ var userActionHandlers = {
|
|
|
2022
2030
|
userActionHandlers.handleCancelConnection(context);
|
|
2023
2031
|
return;
|
|
2024
2032
|
}
|
|
2025
|
-
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
|
|
2033
|
+
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
|
|
2026
2034
|
if (!sourceParentInfo || !sourceParentInfo.ownerId) {
|
|
2027
2035
|
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
2036
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
|
|
@@ -2037,12 +2045,26 @@ var userActionHandlers = {
|
|
|
2037
2045
|
source: sourceNodeData.id,
|
|
2038
2046
|
target: targetNodeData.id
|
|
2039
2047
|
};
|
|
2040
|
-
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
|
|
2041
|
-
specificParentData.links.push(newLink);
|
|
2042
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
|
|
2043
2048
|
try {
|
|
2044
|
-
|
|
2045
|
-
|
|
2049
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2050
|
+
if (isView && parentFileIdToSave === context.sceneConfigId) {
|
|
2051
|
+
const specificParentData = graphDataRef.current[context.sceneConfigId];
|
|
2052
|
+
specificParentData.links.push(newLink);
|
|
2053
|
+
const viewFilePayload = {
|
|
2054
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2055
|
+
nodes: sceneDataRef.current.nodes,
|
|
2056
|
+
links: sceneDataRef.current.links,
|
|
2057
|
+
quest_nodes: specificParentData.nodes,
|
|
2058
|
+
quest_links: specificParentData.links
|
|
2059
|
+
};
|
|
2060
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2061
|
+
} else {
|
|
2062
|
+
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
|
|
2063
|
+
specificParentData.links.push(newLink);
|
|
2064
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
|
|
2065
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
2066
|
+
graphDataRef.current[parentFileIdToSave] = specificParentData;
|
|
2067
|
+
}
|
|
2046
2068
|
addNewLinkToScene(stateRef.current, newLink);
|
|
2047
2069
|
} catch (error) {
|
|
2048
2070
|
console.error("Falha ao salvar a nova conex\xE3o:", error);
|
|
@@ -2111,14 +2133,28 @@ var userActionHandlers = {
|
|
|
2111
2133
|
} else {
|
|
2112
2134
|
newTargetId = newEndNodeData.id;
|
|
2113
2135
|
}
|
|
2114
|
-
const
|
|
2115
|
-
const
|
|
2116
|
-
|
|
2117
|
-
|
|
2136
|
+
const oldSourceInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId, context.sceneConfigId, context.ownerId);
|
|
2137
|
+
const oldTargetInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldTargetId, context.sceneConfigId, context.ownerId);
|
|
2138
|
+
const newSourceInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId, context.sceneConfigId, context.ownerId);
|
|
2139
|
+
const newTargetInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newTargetId, context.sceneConfigId, context.ownerId);
|
|
2140
|
+
if (!oldSourceInfo || !oldTargetInfo || !newSourceInfo || !newTargetInfo) {
|
|
2141
|
+
console.error("Informa\xE7\xF5es dos arquivos pai incompletas para o relink.");
|
|
2118
2142
|
alert("Ocorreu um erro ao identificar os arquivos pai para salvar a altera\xE7\xE3o.");
|
|
2119
2143
|
userActionHandlers.handleCancelRelink(context);
|
|
2120
2144
|
return;
|
|
2121
2145
|
}
|
|
2146
|
+
let oldGoverningFileId = oldSourceInfo.parentFileId;
|
|
2147
|
+
let oldGoverningOwnerId = oldSourceInfo.ownerId;
|
|
2148
|
+
if (oldSourceInfo.parentFileId === context.sceneConfigId || oldTargetInfo.parentFileId === context.sceneConfigId) {
|
|
2149
|
+
oldGoverningFileId = context.sceneConfigId;
|
|
2150
|
+
oldGoverningOwnerId = context.ownerId;
|
|
2151
|
+
}
|
|
2152
|
+
let newGoverningFileId = newSourceInfo.parentFileId;
|
|
2153
|
+
let newGoverningOwnerId = newSourceInfo.ownerId;
|
|
2154
|
+
if (newSourceInfo.parentFileId === context.sceneConfigId || newTargetInfo.parentFileId === context.sceneConfigId) {
|
|
2155
|
+
newGoverningFileId = context.sceneConfigId;
|
|
2156
|
+
newGoverningOwnerId = context.ownerId;
|
|
2157
|
+
}
|
|
2122
2158
|
const { sourceNode, targetNode, ...dataToKeep } = originalLinkData;
|
|
2123
2159
|
const newLinkData = {
|
|
2124
2160
|
...dataToKeep,
|
|
@@ -2126,34 +2162,44 @@ var userActionHandlers = {
|
|
|
2126
2162
|
target: newTargetId,
|
|
2127
2163
|
id: linkId
|
|
2128
2164
|
};
|
|
2165
|
+
const saveParentData = async (fileId, fileOwnerId, data) => {
|
|
2166
|
+
var _a;
|
|
2167
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2168
|
+
if (isView && fileId === context.sceneConfigId) {
|
|
2169
|
+
const viewFilePayload = {
|
|
2170
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2171
|
+
nodes: sceneDataRef.current.nodes,
|
|
2172
|
+
links: sceneDataRef.current.links,
|
|
2173
|
+
quest_nodes: data.nodes,
|
|
2174
|
+
quest_links: data.links
|
|
2175
|
+
};
|
|
2176
|
+
return context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2177
|
+
} else {
|
|
2178
|
+
return context.actions.save_view_data(`x_view_dbs/${fileOwnerId}/${fileId}`, data);
|
|
2179
|
+
}
|
|
2180
|
+
};
|
|
2129
2181
|
const savePromises = [];
|
|
2130
2182
|
const filesToUpdate = {};
|
|
2131
|
-
if (
|
|
2132
|
-
const updatedOriginalParentData = JSON.parse(JSON.stringify(graphDataRef.current[
|
|
2183
|
+
if (oldGoverningFileId !== newGoverningFileId) {
|
|
2184
|
+
const updatedOriginalParentData = JSON.parse(JSON.stringify(graphDataRef.current[oldGoverningFileId]));
|
|
2133
2185
|
updatedOriginalParentData.links = updatedOriginalParentData.links.filter(
|
|
2134
2186
|
(l) => String(l.id) !== String(linkId)
|
|
2135
2187
|
);
|
|
2136
|
-
filesToUpdate[
|
|
2137
|
-
savePromises.push(
|
|
2138
|
-
|
|
2139
|
-
);
|
|
2140
|
-
const updatedNewParentData = JSON.parse(JSON.stringify(graphDataRef.current[newParentInfo.parentFileId]));
|
|
2188
|
+
filesToUpdate[oldGoverningFileId] = updatedOriginalParentData;
|
|
2189
|
+
savePromises.push(saveParentData(oldGoverningFileId, oldGoverningOwnerId, updatedOriginalParentData));
|
|
2190
|
+
const updatedNewParentData = JSON.parse(JSON.stringify(graphDataRef.current[newGoverningFileId]));
|
|
2141
2191
|
if (!updatedNewParentData.links) updatedNewParentData.links = [];
|
|
2142
2192
|
updatedNewParentData.links.push(newLinkData);
|
|
2143
|
-
filesToUpdate[
|
|
2144
|
-
savePromises.push(
|
|
2145
|
-
context.actions.save_view_data(`x_view_dbs/${newParentInfo.ownerId}/${newParentInfo.parentFileId}`, updatedNewParentData)
|
|
2146
|
-
);
|
|
2193
|
+
filesToUpdate[newGoverningFileId] = updatedNewParentData;
|
|
2194
|
+
savePromises.push(saveParentData(newGoverningFileId, newGoverningOwnerId, updatedNewParentData));
|
|
2147
2195
|
} else {
|
|
2148
|
-
const updatedParentData = JSON.parse(JSON.stringify(graphDataRef.current[
|
|
2196
|
+
const updatedParentData = JSON.parse(JSON.stringify(graphDataRef.current[oldGoverningFileId]));
|
|
2149
2197
|
updatedParentData.links = updatedParentData.links.filter(
|
|
2150
2198
|
(l) => String(l.id) !== String(linkId)
|
|
2151
2199
|
);
|
|
2152
2200
|
updatedParentData.links.push(newLinkData);
|
|
2153
|
-
filesToUpdate[
|
|
2154
|
-
savePromises.push(
|
|
2155
|
-
context.actions.save_view_data(`x_view_dbs/${originalParentInfo.ownerId}/${originalParentInfo.parentFileId}`, updatedParentData)
|
|
2156
|
-
);
|
|
2201
|
+
filesToUpdate[oldGoverningFileId] = updatedParentData;
|
|
2202
|
+
savePromises.push(saveParentData(oldGoverningFileId, oldGoverningOwnerId, updatedParentData));
|
|
2157
2203
|
}
|
|
2158
2204
|
try {
|
|
2159
2205
|
await Promise.all(savePromises);
|
|
@@ -2171,7 +2217,7 @@ var userActionHandlers = {
|
|
|
2171
2217
|
}
|
|
2172
2218
|
},
|
|
2173
2219
|
handleDeleteLink: async (context, linkObject) => {
|
|
2174
|
-
var _a, _b, _c, _d, _e, _f;
|
|
2220
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2175
2221
|
const { stateRef, graphDataRef, sceneDataRef, setters } = context;
|
|
2176
2222
|
setters.setRelationshipMenu({ visible: false });
|
|
2177
2223
|
if (!(linkObject == null ? void 0 : linkObject.userData) || !graphDataRef.current || !sceneDataRef.current) return;
|
|
@@ -2180,7 +2226,7 @@ var userActionHandlers = {
|
|
|
2180
2226
|
console.error("Tentativa de deletar um link sem ID.", linkObject.userData);
|
|
2181
2227
|
return;
|
|
2182
2228
|
}
|
|
2183
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source);
|
|
2229
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source, context.sceneConfigId, context.ownerId);
|
|
2184
2230
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2185
2231
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link:", linkIdToDelete);
|
|
2186
2232
|
alert("Ocorreu um erro ao identificar o arquivo pai da rela\xE7\xE3o para exclus\xE3o.");
|
|
@@ -2192,9 +2238,25 @@ var userActionHandlers = {
|
|
|
2192
2238
|
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
|
|
2193
2239
|
const newLinks = (specificParentData.links || []).filter((l) => String(l.id) !== String(linkIdToDelete));
|
|
2194
2240
|
specificParentData.links = newLinks;
|
|
2195
|
-
|
|
2241
|
+
let filenameToSave;
|
|
2242
|
+
let payloadToSave;
|
|
2243
|
+
const isView = ((_g = context.viewType) == null ? void 0 : _g.toLowerCase()) === "view";
|
|
2244
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2245
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2246
|
+
sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => String(l.id) !== String(linkIdToDelete));
|
|
2247
|
+
payloadToSave = {
|
|
2248
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2249
|
+
nodes: sceneDataRef.current.nodes,
|
|
2250
|
+
links: sceneDataRef.current.links,
|
|
2251
|
+
quest_nodes: specificParentData.nodes,
|
|
2252
|
+
quest_links: specificParentData.links
|
|
2253
|
+
};
|
|
2254
|
+
} else {
|
|
2255
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2256
|
+
payloadToSave = specificParentData;
|
|
2257
|
+
}
|
|
2196
2258
|
try {
|
|
2197
|
-
await context.actions.save_view_data(
|
|
2259
|
+
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2198
2260
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2199
2261
|
setters.setDetailsLink((prev) => String(prev == null ? void 0 : prev.id) === String(linkIdToDelete) ? null : prev);
|
|
2200
2262
|
if (stateRef.current.hoveredLink === linkObject) {
|
|
@@ -2212,12 +2274,6 @@ var userActionHandlers = {
|
|
|
2212
2274
|
if (!nodeData || !sceneDataRef.current) return;
|
|
2213
2275
|
const nodeIdToDismiss = nodeData.id;
|
|
2214
2276
|
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
2277
|
const { ancestryGroup, ancestryLinks } = stateRef.current;
|
|
2222
2278
|
if (ancestryGroup && ancestryLinks) {
|
|
2223
2279
|
const remainingAncestryLinks = [];
|
|
@@ -2259,22 +2315,12 @@ var userActionHandlers = {
|
|
|
2259
2315
|
removeNodeFromScene(stateRef.current, nodeId);
|
|
2260
2316
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
|
|
2261
2317
|
});
|
|
2262
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2263
|
-
(n) => String(n.id) === strNodeIdToKeep
|
|
2264
|
-
);
|
|
2265
|
-
sceneDataRef.current.links = [];
|
|
2266
2318
|
},
|
|
2267
2319
|
handleDismissMultipleNodes: (context, nodeIds) => {
|
|
2268
2320
|
const { stateRef, sceneDataRef, setters } = context;
|
|
2269
2321
|
setters.setMultiContextMenu({ visible: false });
|
|
2270
2322
|
if (!nodeIds || nodeIds.size === 0 || !sceneDataRef.current) return;
|
|
2271
2323
|
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
2324
|
const { ancestryGroup, ancestryLinks } = stateRef.current;
|
|
2279
2325
|
if (ancestryGroup && ancestryLinks) {
|
|
2280
2326
|
const remainingAncestryLinks = [];
|
|
@@ -2330,15 +2376,10 @@ var userActionHandlers = {
|
|
|
2330
2376
|
removeNodeFromScene(stateRef.current, nodeId);
|
|
2331
2377
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
|
|
2332
2378
|
});
|
|
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
2379
|
stateRef.current.selectedNodes.clear();
|
|
2340
2380
|
},
|
|
2341
2381
|
handleDeleteMultipleNodes: async (context, nodeIds) => {
|
|
2382
|
+
var _a;
|
|
2342
2383
|
const { stateRef, graphDataRef, sceneDataRef, setters, actions } = context;
|
|
2343
2384
|
setters.setMultiContextMenu({ visible: false });
|
|
2344
2385
|
if (!nodeIds || nodeIds.size === 0 || !graphDataRef.current || !sceneDataRef.current) return;
|
|
@@ -2357,7 +2398,7 @@ var userActionHandlers = {
|
|
|
2357
2398
|
}
|
|
2358
2399
|
const changesByParentFile = {};
|
|
2359
2400
|
for (const nodeId of strNodeIdsToDelete) {
|
|
2360
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId);
|
|
2401
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId, context.sceneConfigId, context.ownerId);
|
|
2361
2402
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2362
2403
|
console.warn(`Node com ID ${nodeId} n\xE3o encontrado ou sem ownerId. Ignorando.`);
|
|
2363
2404
|
continue;
|
|
@@ -2391,8 +2432,27 @@ var userActionHandlers = {
|
|
|
2391
2432
|
originalData.links = (originalData.links || []).filter(
|
|
2392
2433
|
(l) => !linksToDelete.has(String(l.id))
|
|
2393
2434
|
);
|
|
2394
|
-
|
|
2395
|
-
|
|
2435
|
+
let filenameToSave;
|
|
2436
|
+
let payloadToSave;
|
|
2437
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2438
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2439
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2440
|
+
const strNodesToDelete = Array.from(nodesToDelete).map(String);
|
|
2441
|
+
const strLinksToDelete = Array.from(linksToDelete).map(String);
|
|
2442
|
+
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter((n) => !strNodesToDelete.includes(String(n.id)));
|
|
2443
|
+
sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => !strLinksToDelete.includes(String(l.id)));
|
|
2444
|
+
payloadToSave = {
|
|
2445
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2446
|
+
nodes: sceneDataRef.current.nodes,
|
|
2447
|
+
links: sceneDataRef.current.links,
|
|
2448
|
+
quest_nodes: originalData.nodes,
|
|
2449
|
+
quest_links: originalData.links
|
|
2450
|
+
};
|
|
2451
|
+
} else {
|
|
2452
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2453
|
+
payloadToSave = originalData;
|
|
2454
|
+
}
|
|
2455
|
+
savePromises.push(context.actions.save_view_data(filenameToSave, payloadToSave));
|
|
2396
2456
|
updatedParentDataCache[parentFileId] = originalData;
|
|
2397
2457
|
}
|
|
2398
2458
|
}
|
|
@@ -2413,6 +2473,7 @@ var userActionHandlers = {
|
|
|
2413
2473
|
}
|
|
2414
2474
|
},
|
|
2415
2475
|
handleDeleteNode: async (context, nodeData) => {
|
|
2476
|
+
var _a;
|
|
2416
2477
|
const { stateRef, graphDataRef, sceneDataRef, setters, actions } = context;
|
|
2417
2478
|
if (actions.delete_file && nodeData) {
|
|
2418
2479
|
const urls = extractFileUrlsFromProperties(nodeData);
|
|
@@ -2424,7 +2485,7 @@ var userActionHandlers = {
|
|
|
2424
2485
|
if (!nodeData || !graphDataRef.current || !sceneDataRef.current) return;
|
|
2425
2486
|
const nodeIdToDelete = nodeData.id;
|
|
2426
2487
|
const strNodeId = String(nodeIdToDelete);
|
|
2427
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete);
|
|
2488
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete, context.sceneConfigId, context.ownerId);
|
|
2428
2489
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2429
2490
|
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
2491
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para exclus\xE3o.");
|
|
@@ -2436,9 +2497,28 @@ var userActionHandlers = {
|
|
|
2436
2497
|
const newLinks = (specificParentData.links || []).filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
|
|
2437
2498
|
specificParentData.nodes = newNodes;
|
|
2438
2499
|
specificParentData.links = newLinks;
|
|
2439
|
-
|
|
2500
|
+
let filenameToSave;
|
|
2501
|
+
let payloadToSave;
|
|
2502
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2503
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2504
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2505
|
+
const newVisualNodes = sceneDataRef.current.nodes.filter((n) => String(n.id) !== strNodeId);
|
|
2506
|
+
const newVisualLinks = sceneDataRef.current.links.filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
|
|
2507
|
+
sceneDataRef.current.nodes = newVisualNodes;
|
|
2508
|
+
sceneDataRef.current.links = newVisualLinks;
|
|
2509
|
+
payloadToSave = {
|
|
2510
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2511
|
+
nodes: newVisualNodes,
|
|
2512
|
+
links: newVisualLinks,
|
|
2513
|
+
quest_nodes: specificParentData.nodes,
|
|
2514
|
+
quest_links: specificParentData.links
|
|
2515
|
+
};
|
|
2516
|
+
} else {
|
|
2517
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2518
|
+
payloadToSave = specificParentData;
|
|
2519
|
+
}
|
|
2440
2520
|
try {
|
|
2441
|
-
await context.actions.save_view_data(
|
|
2521
|
+
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2442
2522
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2443
2523
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeIdToDelete) ? null : prev);
|
|
2444
2524
|
removeNodeFromScene(stateRef.current, nodeIdToDelete);
|
|
@@ -2449,10 +2529,11 @@ var userActionHandlers = {
|
|
|
2449
2529
|
}
|
|
2450
2530
|
},
|
|
2451
2531
|
handleSaveNodeDetails: async (context, updatedNode, keepOpen = false) => {
|
|
2532
|
+
var _a;
|
|
2452
2533
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2453
2534
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2454
2535
|
const { _baseEmissiveIntensity: ignored, ...nodeToSave } = updatedNode;
|
|
2455
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id);
|
|
2536
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id, context.sceneConfigId, context.ownerId);
|
|
2456
2537
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2457
2538
|
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
2539
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
|
|
@@ -2468,9 +2549,21 @@ var userActionHandlers = {
|
|
|
2468
2549
|
alert("Erro interno: Node n\xE3o encontrado para salvar.");
|
|
2469
2550
|
return;
|
|
2470
2551
|
}
|
|
2471
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2472
2552
|
try {
|
|
2473
|
-
|
|
2553
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2554
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2555
|
+
const viewFilePayload = {
|
|
2556
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2557
|
+
nodes: sceneDataRef.current.nodes,
|
|
2558
|
+
links: sceneDataRef.current.links,
|
|
2559
|
+
quest_nodes: specificParentData.nodes,
|
|
2560
|
+
quest_links: specificParentData.links
|
|
2561
|
+
};
|
|
2562
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2563
|
+
} else {
|
|
2564
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2565
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
2566
|
+
}
|
|
2474
2567
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2475
2568
|
updateExistingNodeVisuals(stateRef.current, nodeToSave);
|
|
2476
2569
|
setters.setSceneVersion((v) => v + 1);
|
|
@@ -2483,10 +2576,11 @@ var userActionHandlers = {
|
|
|
2483
2576
|
}
|
|
2484
2577
|
},
|
|
2485
2578
|
handleSaveLinkDetails: async (context, updatedLink, keepOpen = false) => {
|
|
2579
|
+
var _a;
|
|
2486
2580
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2487
2581
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2488
2582
|
const { sourceNode, targetNode, ...linkToSave } = updatedLink;
|
|
2489
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source);
|
|
2583
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source, context.sceneConfigId, context.ownerId);
|
|
2490
2584
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2491
2585
|
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
2586
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
|
|
@@ -2502,9 +2596,21 @@ var userActionHandlers = {
|
|
|
2502
2596
|
alert("Erro interno: link n\xE3o encontrado para salvar.");
|
|
2503
2597
|
return;
|
|
2504
2598
|
}
|
|
2505
|
-
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2506
2599
|
try {
|
|
2507
|
-
|
|
2600
|
+
const isView = ((_a = context.viewType) == null ? void 0 : _a.toLowerCase()) === "view";
|
|
2601
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2602
|
+
const viewFilePayload = {
|
|
2603
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2604
|
+
nodes: sceneDataRef.current.nodes,
|
|
2605
|
+
links: sceneDataRef.current.links,
|
|
2606
|
+
quest_nodes: specificParentData.nodes,
|
|
2607
|
+
quest_links: specificParentData.links
|
|
2608
|
+
};
|
|
2609
|
+
await context.actions.save_view_data(context.sceneSaveUrl, viewFilePayload);
|
|
2610
|
+
} else {
|
|
2611
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2612
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
2613
|
+
}
|
|
2508
2614
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2509
2615
|
const lineObject = stateRef.current.allLinks.find(
|
|
2510
2616
|
(l) => String(l.userData.id) === String(linkToSave.id)
|
|
@@ -2527,7 +2633,7 @@ var userActionHandlers = {
|
|
|
2527
2633
|
}
|
|
2528
2634
|
},
|
|
2529
2635
|
handleAddExistingNodeById: (context, nodeId) => {
|
|
2530
|
-
var _a
|
|
2636
|
+
var _a;
|
|
2531
2637
|
const { stateRef, sceneDataRef, graphDataRef, tweenToTarget, setters } = context;
|
|
2532
2638
|
const state = stateRef.current;
|
|
2533
2639
|
const graphFull = graphDataRef.current;
|
|
@@ -2543,16 +2649,12 @@ var userActionHandlers = {
|
|
|
2543
2649
|
tweenToTarget(state.nodeObjects[strNodeId]);
|
|
2544
2650
|
return;
|
|
2545
2651
|
}
|
|
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
2652
|
const base = state.controls ? state.controls.target.clone() : new THREE.Vector3(0, 0, 0);
|
|
2551
2653
|
const offset = new THREE.Vector3((Math.random() - 0.5) * 20, (Math.random() - 0.5) * 6, (Math.random() - 0.5) * 20);
|
|
2552
2654
|
const position = base.add(offset);
|
|
2553
2655
|
addStandaloneNodeToScene(state, nodeData, position);
|
|
2554
2656
|
tweenToTarget(position, 1.3);
|
|
2555
|
-
(
|
|
2657
|
+
(_a = setters == null ? void 0 : setters.setSceneVersion) == null ? void 0 : _a.call(setters, (v) => v + 1);
|
|
2556
2658
|
}
|
|
2557
2659
|
};
|
|
2558
2660
|
|
|
@@ -7853,13 +7955,9 @@ var import_react16 = __toESM(require("react"));
|
|
|
7853
7955
|
var import_fi14 = require("react-icons/fi");
|
|
7854
7956
|
var QUEST_STATUS_COLORS = {
|
|
7855
7957
|
"Backlog": "#64748b",
|
|
7856
|
-
// Slate (Cinza azulado)
|
|
7857
7958
|
"In Progress": "#eab308",
|
|
7858
|
-
// Yellow (Amarelo)
|
|
7859
7959
|
"Review": "#a855f7",
|
|
7860
|
-
// Purple (Roxo)
|
|
7861
7960
|
"Done": "#22c55e"
|
|
7862
|
-
// Green (Verde)
|
|
7863
7961
|
};
|
|
7864
7962
|
function InSceneQuestForm({
|
|
7865
7963
|
onSave,
|
|
@@ -7870,7 +7968,11 @@ function InSceneQuestForm({
|
|
|
7870
7968
|
availableNodes = [],
|
|
7871
7969
|
availableAncestries = [],
|
|
7872
7970
|
onMentionClick,
|
|
7873
|
-
onUploadFile
|
|
7971
|
+
onUploadFile,
|
|
7972
|
+
// NOVAS PROPS PARA O GHOST NODE
|
|
7973
|
+
onNameChange,
|
|
7974
|
+
onColorChange,
|
|
7975
|
+
onSizeChange
|
|
7874
7976
|
}) {
|
|
7875
7977
|
const [name, setName] = (0, import_react16.useState)("");
|
|
7876
7978
|
const [types, setTypes] = (0, import_react16.useState)(["quest"]);
|
|
@@ -7879,6 +7981,7 @@ function InSceneQuestForm({
|
|
|
7879
7981
|
const [size, setSize] = (0, import_react16.useState)("medium");
|
|
7880
7982
|
const [intensity, setIntensity] = (0, import_react16.useState)(0);
|
|
7881
7983
|
const [description, setDescription] = (0, import_react16.useState)("");
|
|
7984
|
+
const [isStatusDropdownOpen, setIsStatusDropdownOpen] = (0, import_react16.useState)(false);
|
|
7882
7985
|
const [customProps, setCustomProps] = (0, import_react16.useState)([]);
|
|
7883
7986
|
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react16.useState)(false);
|
|
7884
7987
|
const propsEndRef = (0, import_react16.useRef)(null);
|
|
@@ -7897,7 +8000,7 @@ function InSceneQuestForm({
|
|
|
7897
8000
|
setCustomProps(newProps);
|
|
7898
8001
|
};
|
|
7899
8002
|
const handleAddType = (newType) => {
|
|
7900
|
-
const trimmed = newType.trim()
|
|
8003
|
+
const trimmed = newType.trim();
|
|
7901
8004
|
if (trimmed && !types.includes(trimmed)) {
|
|
7902
8005
|
setTypes([...types, trimmed]);
|
|
7903
8006
|
setTypeInput("");
|
|
@@ -7929,7 +8032,6 @@ function InSceneQuestForm({
|
|
|
7929
8032
|
name: name.trim(),
|
|
7930
8033
|
type: types,
|
|
7931
8034
|
color: QUEST_STATUS_COLORS[status],
|
|
7932
|
-
// Cor atrelada ao status
|
|
7933
8035
|
status,
|
|
7934
8036
|
size,
|
|
7935
8037
|
intensity,
|
|
@@ -7956,20 +8058,52 @@ function InSceneQuestForm({
|
|
|
7956
8058
|
onDoubleClick: swallow
|
|
7957
8059
|
},
|
|
7958
8060
|
/* @__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
|
-
|
|
8061
|
+
/* @__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(
|
|
8062
|
+
"button",
|
|
8063
|
+
{
|
|
8064
|
+
type: "button",
|
|
8065
|
+
onClick: onCancel,
|
|
8066
|
+
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",
|
|
8067
|
+
title: "Fechar"
|
|
8068
|
+
},
|
|
8069
|
+
"\xD7"
|
|
8070
|
+
)),
|
|
8071
|
+
/* @__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(
|
|
8072
|
+
"button",
|
|
8073
|
+
{
|
|
8074
|
+
type: "button",
|
|
8075
|
+
onClick: () => setIsStatusDropdownOpen(!isStatusDropdownOpen),
|
|
8076
|
+
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"
|
|
8077
|
+
},
|
|
8078
|
+
/* @__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)),
|
|
8079
|
+
/* @__PURE__ */ import_react16.default.createElement(import_fi14.FiChevronDown, { className: `text-slate-400 transition-transform duration-200 ${isStatusDropdownOpen ? "rotate-180" : ""}` })
|
|
8080
|
+
), 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(
|
|
8081
|
+
"li",
|
|
8082
|
+
{
|
|
8083
|
+
key: s,
|
|
8084
|
+
onClick: () => {
|
|
8085
|
+
setStatus(s);
|
|
8086
|
+
setIsStatusDropdownOpen(false);
|
|
8087
|
+
onColorChange == null ? void 0 : onColorChange(QUEST_STATUS_COLORS[s]);
|
|
8088
|
+
},
|
|
8089
|
+
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"}`
|
|
7967
8090
|
},
|
|
7968
|
-
/* @__PURE__ */ import_react16.default.createElement("
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
8091
|
+
/* @__PURE__ */ import_react16.default.createElement("span", { className: "w-3 h-3 rounded-full", style: { backgroundColor: QUEST_STATUS_COLORS[s] } }),
|
|
8092
|
+
s
|
|
8093
|
+
)))))), /* @__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(
|
|
8094
|
+
"input",
|
|
8095
|
+
{
|
|
8096
|
+
required: true,
|
|
8097
|
+
type: "text",
|
|
8098
|
+
placeholder: "Ex.: Refatorar M\xF3dulo X",
|
|
8099
|
+
value: name,
|
|
8100
|
+
onChange: (e) => {
|
|
8101
|
+
setName(e.target.value);
|
|
8102
|
+
onNameChange == null ? void 0 : onNameChange(e.target.value);
|
|
8103
|
+
},
|
|
8104
|
+
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"
|
|
8105
|
+
}
|
|
8106
|
+
)), /* @__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
8107
|
"input",
|
|
7974
8108
|
{
|
|
7975
8109
|
type: "text",
|
|
@@ -7980,7 +8114,6 @@ function InSceneQuestForm({
|
|
|
7980
8114
|
if (typeInput.trim()) handleAddType(typeInput);
|
|
7981
8115
|
},
|
|
7982
8116
|
className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
|
|
7983
|
-
placeholder: "Ex.: Bugfix",
|
|
7984
8117
|
autoComplete: "off"
|
|
7985
8118
|
}
|
|
7986
8119
|
))), /* @__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 +8126,20 @@ function InSceneQuestForm({
|
|
|
7993
8126
|
onMentionClick,
|
|
7994
8127
|
onSaveDescription: (newDesc) => setDescription(newDesc)
|
|
7995
8128
|
}
|
|
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
|
|
8129
|
+
), /* @__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(
|
|
8130
|
+
"button",
|
|
8131
|
+
{
|
|
8132
|
+
key: s,
|
|
8133
|
+
type: "button",
|
|
8134
|
+
onClick: () => {
|
|
8135
|
+
setSize(s);
|
|
8136
|
+
onSizeChange == null ? void 0 : onSizeChange(s);
|
|
8137
|
+
},
|
|
8138
|
+
className: "flex items-center gap-2 group cursor-pointer focus:outline-none"
|
|
8139
|
+
},
|
|
8140
|
+
/* @__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" })),
|
|
8141
|
+
/* @__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)
|
|
8142
|
+
)))), /* @__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
8143
|
CustomPropertyDisplay,
|
|
7998
8144
|
{
|
|
7999
8145
|
key: prop.id,
|
|
@@ -10173,7 +10319,7 @@ function XViewScene({
|
|
|
10173
10319
|
});
|
|
10174
10320
|
}
|
|
10175
10321
|
return {
|
|
10176
|
-
node: effectiveNode
|
|
10322
|
+
...effectiveNode ? { node: effectiveNode } : { node: { id: nodeId, name: "Unknown" } },
|
|
10177
10323
|
relationship: treeItem.relationship || {},
|
|
10178
10324
|
children: (treeItem.children || []).map(recursiveBuild).filter(Boolean),
|
|
10179
10325
|
parallel_branches: processedBranches
|
|
@@ -10872,20 +11018,6 @@ function XViewScene({
|
|
|
10872
11018
|
const context = actionHandlerContext;
|
|
10873
11019
|
if (connection.isActive) {
|
|
10874
11020
|
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
11021
|
await userActionHandlers.handleCompleteConnection(context, hoveredNode.userData);
|
|
10890
11022
|
} else {
|
|
10891
11023
|
userActionHandlers.handleCancelConnection(context);
|
|
@@ -10991,39 +11123,6 @@ function XViewScene({
|
|
|
10991
11123
|
}
|
|
10992
11124
|
}
|
|
10993
11125
|
}
|
|
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
11126
|
function handleDoubleClick(event) {
|
|
11028
11127
|
if (stateRef.current.camera) stateRef.current.camera.layers.enableAll();
|
|
11029
11128
|
if (isFromUiOverlay(event) || stateRef.current.isDragging || stateRef.current.creation.isActive || stateRef.current.connection.isActive || stateRef.current.relink.isActive) return;
|
|
@@ -11076,7 +11175,6 @@ function XViewScene({
|
|
|
11076
11175
|
currentMount.addEventListener("dblclick", handleDoubleClick);
|
|
11077
11176
|
currentMount.addEventListener("pointermove", onPointerMove);
|
|
11078
11177
|
currentMount.addEventListener("contextmenu", handleContextMenu);
|
|
11079
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
11080
11178
|
const originalBackground = scene.background;
|
|
11081
11179
|
const clock = new THREE3.Clock();
|
|
11082
11180
|
let animationFrameId = 0;
|
|
@@ -11214,7 +11312,6 @@ function XViewScene({
|
|
|
11214
11312
|
return () => {
|
|
11215
11313
|
cancelAnimationFrame(animationFrameId);
|
|
11216
11314
|
window.removeEventListener("resize", handleResize);
|
|
11217
|
-
window.removeEventListener("keydown", handleKeyDown);
|
|
11218
11315
|
currentMount.removeEventListener("pointerdown", onPointerDown);
|
|
11219
11316
|
currentMount.removeEventListener("pointerup", onPointerUp);
|
|
11220
11317
|
currentMount.removeEventListener("dblclick", handleDoubleClick);
|
|
@@ -11488,11 +11585,10 @@ function XViewScene({
|
|
|
11488
11585
|
creationMode,
|
|
11489
11586
|
versionMode,
|
|
11490
11587
|
questMode,
|
|
11491
|
-
// <-- Adicionado
|
|
11492
11588
|
sceneSaveUrl,
|
|
11493
|
-
|
|
11589
|
+
sceneConfigId,
|
|
11590
|
+
ownerId,
|
|
11494
11591
|
viewType: viewParams == null ? void 0 : viewParams.type,
|
|
11495
|
-
// <-- Adicionado
|
|
11496
11592
|
userId: (_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.id,
|
|
11497
11593
|
setters: {
|
|
11498
11594
|
setContextMenu,
|
|
@@ -11506,7 +11602,6 @@ function XViewScene({
|
|
|
11506
11602
|
setSceneVersion,
|
|
11507
11603
|
setAncestryMode,
|
|
11508
11604
|
setQuestMode
|
|
11509
|
-
// <-- Adicionado
|
|
11510
11605
|
},
|
|
11511
11606
|
tweenToTarget,
|
|
11512
11607
|
handleVersionTimeline,
|
|
@@ -11524,9 +11619,11 @@ function XViewScene({
|
|
|
11524
11619
|
versionMode,
|
|
11525
11620
|
questMode,
|
|
11526
11621
|
sceneSaveUrl,
|
|
11622
|
+
sceneConfigId,
|
|
11623
|
+
ownerId,
|
|
11527
11624
|
viewParams == null ? void 0 : viewParams.type,
|
|
11528
|
-
tweenToTarget,
|
|
11529
11625
|
(_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id,
|
|
11626
|
+
tweenToTarget,
|
|
11530
11627
|
handleVersionTimeline,
|
|
11531
11628
|
save_view_data,
|
|
11532
11629
|
get_single_parent_file,
|
|
@@ -11538,33 +11635,116 @@ function XViewScene({
|
|
|
11538
11635
|
const handleStartVersioning = (nodeData) => {
|
|
11539
11636
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
11540
11637
|
};
|
|
11638
|
+
const handleCancelQuest = (0, import_react25.useCallback)(() => {
|
|
11639
|
+
const { graphGroup, ghostElements } = stateRef.current;
|
|
11640
|
+
if (ghostElements.node && graphGroup) {
|
|
11641
|
+
if (ghostElements.node.userData.labelObject) {
|
|
11642
|
+
graphGroup.remove(ghostElements.node.userData.labelObject);
|
|
11643
|
+
if (ghostElements.node.userData.labelObject.material.map) ghostElements.node.userData.labelObject.material.map.dispose();
|
|
11644
|
+
ghostElements.node.userData.labelObject.material.dispose();
|
|
11645
|
+
}
|
|
11646
|
+
graphGroup.remove(ghostElements.node);
|
|
11647
|
+
ghostElements.node.traverse((child) => {
|
|
11648
|
+
if (child.material) {
|
|
11649
|
+
if (Array.isArray(child.material)) child.material.forEach((m) => m.dispose());
|
|
11650
|
+
else child.material.dispose();
|
|
11651
|
+
}
|
|
11652
|
+
if (child.geometry) child.geometry.dispose();
|
|
11653
|
+
});
|
|
11654
|
+
}
|
|
11655
|
+
stateRef.current.ghostElements = { node: null, line: null, aura: null };
|
|
11656
|
+
setQuestMode({ isActive: false });
|
|
11657
|
+
}, []);
|
|
11541
11658
|
const handleSaveQuestNode = async (context, newQuestData) => {
|
|
11542
|
-
const { sceneDataRef: sceneDataRef2, stateRef: stateRef2, setters, actions, sceneSaveUrl: sceneSaveUrl2, viewType } = context;
|
|
11543
|
-
if (!
|
|
11659
|
+
const { graphDataRef, sceneDataRef: sceneDataRef2, stateRef: stateRef2, setters, actions, sceneSaveUrl: sceneSaveUrl2, viewType, sceneConfigId: sceneConfigId2, ownerId: ownerId2 } = context;
|
|
11660
|
+
if (!graphDataRef.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
|
|
11544
11661
|
const newNode = {
|
|
11545
11662
|
id: import_short_uuid2.default.generate(),
|
|
11546
11663
|
...newQuestData,
|
|
11664
|
+
is_quest: true,
|
|
11547
11665
|
type: ["quest", ...newQuestData.type.filter((t) => t !== "quest")]
|
|
11548
11666
|
};
|
|
11549
|
-
|
|
11550
|
-
|
|
11551
|
-
|
|
11667
|
+
if (!graphDataRef.current[sceneConfigId2]) {
|
|
11668
|
+
graphDataRef.current[sceneConfigId2] = { nodes: [], links: [] };
|
|
11669
|
+
}
|
|
11670
|
+
graphDataRef.current[sceneConfigId2].nodes.push(newNode);
|
|
11671
|
+
const sceneFileData = {
|
|
11672
|
+
parent_dbs: sceneDataRef2.current.parent_dbs,
|
|
11673
|
+
nodes: sceneDataRef2.current.nodes,
|
|
11674
|
+
links: sceneDataRef2.current.links,
|
|
11675
|
+
quest_nodes: graphDataRef.current[sceneConfigId2].nodes,
|
|
11676
|
+
quest_links: graphDataRef.current[sceneConfigId2].links
|
|
11552
11677
|
};
|
|
11553
11678
|
try {
|
|
11554
|
-
await actions.save_view_data(sceneSaveUrl2,
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
|
|
11679
|
+
await actions.save_view_data(sceneSaveUrl2, sceneFileData);
|
|
11680
|
+
stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
11681
|
+
parentFileId: sceneConfigId2,
|
|
11682
|
+
ownerId: ownerId2,
|
|
11683
|
+
datasetName: "Quests Internas (View)"
|
|
11684
|
+
});
|
|
11685
|
+
const finalPosition = stateRef2.current.ghostElements.node ? stateRef2.current.ghostElements.node.position.clone() : stateRef2.current.controls.target.clone();
|
|
11686
|
+
const { graphGroup, ghostElements } = stateRef2.current;
|
|
11687
|
+
if (ghostElements.node && graphGroup) {
|
|
11688
|
+
if (ghostElements.node.userData.labelObject) graphGroup.remove(ghostElements.node.userData.labelObject);
|
|
11689
|
+
graphGroup.remove(ghostElements.node);
|
|
11690
|
+
}
|
|
11691
|
+
stateRef2.current.ghostElements = { node: null, line: null, aura: null };
|
|
11692
|
+
addStandaloneNodeToScene(stateRef2.current, newNode, finalPosition);
|
|
11560
11693
|
context.tweenToTarget(finalPosition, 1.2);
|
|
11561
11694
|
setters.setQuestMode({ isActive: false });
|
|
11562
11695
|
setters.setSceneVersion((v) => v + 1);
|
|
11563
11696
|
} catch (error) {
|
|
11564
|
-
console.error("Falha ao salvar
|
|
11697
|
+
console.error("Falha ao salvar Quest na View:", error);
|
|
11565
11698
|
alert("Ocorreu um erro ao criar a Quest.");
|
|
11566
11699
|
}
|
|
11567
11700
|
};
|
|
11701
|
+
userActionHandlers.handleCompleteConnection = async (context, targetNodeData) => {
|
|
11702
|
+
const { stateRef: stateRef2, graphDataRef, sceneDataRef: sceneDataRef2, sceneConfigId: sceneConfigId2, sceneSaveUrl: sceneSaveUrl2, ownerId: ownerId2 } = context;
|
|
11703
|
+
const { sourceNodeData } = stateRef2.current.connection;
|
|
11704
|
+
if (!graphDataRef.current || !sceneDataRef2.current || !sourceNodeData || !targetNodeData) {
|
|
11705
|
+
userActionHandlers.handleCancelConnection(context);
|
|
11706
|
+
return;
|
|
11707
|
+
}
|
|
11708
|
+
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, sourceNodeData.id, sceneConfigId2, ownerId2);
|
|
11709
|
+
const targetParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, targetNodeData.id, sceneConfigId2, ownerId2);
|
|
11710
|
+
let parentInfoToSave = sourceParentInfo;
|
|
11711
|
+
const isSourceQuest = sourceParentInfo.parentFileId === sceneConfigId2;
|
|
11712
|
+
const isTargetQuest = targetParentInfo.parentFileId === sceneConfigId2;
|
|
11713
|
+
if (isSourceQuest || isTargetQuest) {
|
|
11714
|
+
parentInfoToSave = { parentFileId: sceneConfigId2, ownerId: ownerId2 };
|
|
11715
|
+
}
|
|
11716
|
+
const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
|
|
11717
|
+
const newLink = {
|
|
11718
|
+
id: `link_${import_short_uuid2.default.generate()}`,
|
|
11719
|
+
source: sourceNodeData.id,
|
|
11720
|
+
target: targetNodeData.id
|
|
11721
|
+
};
|
|
11722
|
+
try {
|
|
11723
|
+
if (parentFileIdToSave === sceneConfigId2) {
|
|
11724
|
+
const specificParentData = graphDataRef.current[sceneConfigId2];
|
|
11725
|
+
specificParentData.links.push(newLink);
|
|
11726
|
+
const viewFilePayload = {
|
|
11727
|
+
parent_dbs: sceneDataRef2.current.parent_dbs,
|
|
11728
|
+
nodes: sceneDataRef2.current.nodes,
|
|
11729
|
+
links: sceneDataRef2.current.links,
|
|
11730
|
+
quest_nodes: specificParentData.nodes,
|
|
11731
|
+
quest_links: specificParentData.links
|
|
11732
|
+
};
|
|
11733
|
+
await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
|
|
11734
|
+
} else {
|
|
11735
|
+
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
|
|
11736
|
+
specificParentData.links.push(newLink);
|
|
11737
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
|
|
11738
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
11739
|
+
graphDataRef.current[parentFileIdToSave] = specificParentData;
|
|
11740
|
+
}
|
|
11741
|
+
addNewLinkToScene(stateRef2.current, newLink);
|
|
11742
|
+
} catch (error) {
|
|
11743
|
+
console.error("Falha ao salvar a nova conex\xE3o:", error);
|
|
11744
|
+
alert("Ocorreu um erro ao salvar a nova conex\xE3o.");
|
|
11745
|
+
}
|
|
11746
|
+
userActionHandlers.handleCancelConnection(context);
|
|
11747
|
+
};
|
|
11568
11748
|
const handleClearAncestryVisuals = (0, import_react25.useCallback)((ancestryId) => {
|
|
11569
11749
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
11570
11750
|
const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
|
|
@@ -12813,7 +12993,7 @@ function XViewScene({
|
|
|
12813
12993
|
const allTypes = Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes.flatMap((node) => {
|
|
12814
12994
|
if (Array.isArray(node.type)) return node.type;
|
|
12815
12995
|
return [node.type];
|
|
12816
|
-
})).filter(Boolean);
|
|
12996
|
+
})).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
|
|
12817
12997
|
return [...new Set(allTypes)];
|
|
12818
12998
|
}, [parentDataRef.current, sceneVersion]);
|
|
12819
12999
|
const searchableDbNodes = (0, import_react25.useMemo)(() => {
|
|
@@ -12832,6 +13012,7 @@ function XViewScene({
|
|
|
12832
13012
|
[actionHandlerContext]
|
|
12833
13013
|
);
|
|
12834
13014
|
const handleSaveCurrentView = (0, import_react25.useCallback)(async () => {
|
|
13015
|
+
var _a2, _b2, _c2;
|
|
12835
13016
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
12836
13017
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
12837
13018
|
console.warn("N\xE3o \xE9 poss\xEDvel salvar a cena: estado n\xE3o inicializado ou URL de salvamento ausente.");
|
|
@@ -12853,17 +13034,22 @@ function XViewScene({
|
|
|
12853
13034
|
const { sourceNode, targetNode, ...serializableLinkData } = line.userData;
|
|
12854
13035
|
return serializableLinkData;
|
|
12855
13036
|
});
|
|
13037
|
+
sceneDataRef.current.nodes = currentNodes;
|
|
13038
|
+
sceneDataRef.current.links = currentLinks;
|
|
13039
|
+
const isView = ((_a2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _a2.toLowerCase()) === "view";
|
|
12856
13040
|
const sceneFileData = {
|
|
12857
13041
|
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
12858
13042
|
nodes: currentNodes,
|
|
12859
|
-
links: currentLinks
|
|
13043
|
+
links: currentLinks,
|
|
13044
|
+
quest_nodes: isView ? ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || [] : sceneDataRef.current.quest_nodes || [],
|
|
13045
|
+
quest_links: isView ? ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || [] : sceneDataRef.current.quest_links || []
|
|
12860
13046
|
};
|
|
12861
13047
|
try {
|
|
12862
13048
|
await save_view_data(sceneSaveUrl, sceneFileData);
|
|
12863
13049
|
} catch (error) {
|
|
12864
13050
|
console.error("Erro na chamada de save_view_data:", error);
|
|
12865
13051
|
}
|
|
12866
|
-
}, [sceneSaveUrl, save_view_data]);
|
|
13052
|
+
}, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
|
|
12867
13053
|
const allAvailableNodes = (0, import_react25.useMemo)(() => {
|
|
12868
13054
|
if (!parentDataRef.current) return [];
|
|
12869
13055
|
return Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
|
|
@@ -12948,6 +13134,106 @@ function XViewScene({
|
|
|
12948
13134
|
}
|
|
12949
13135
|
}
|
|
12950
13136
|
}, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
|
|
13137
|
+
(0, import_react25.useEffect)(() => {
|
|
13138
|
+
function handleKeyDown(event) {
|
|
13139
|
+
var _a2, _b2, _c2;
|
|
13140
|
+
const context = actionHandlerContext;
|
|
13141
|
+
if (event.key === "Escape") {
|
|
13142
|
+
if (stateRef.current.connection.isActive) userActionHandlers.handleCancelConnection(context);
|
|
13143
|
+
if (stateRef.current.relink.isActive) userActionHandlers.handleCancelRelink(context);
|
|
13144
|
+
if (stateRef.current.creation.isActive) userActionHandlers.handleCancelCreation(context);
|
|
13145
|
+
if ((_a2 = stateRef.current.versionMode) == null ? void 0 : _a2.isActive) userActionHandlers.handleCancelVersioning(context);
|
|
13146
|
+
if (stateRef.current.ancestry.isActive) {
|
|
13147
|
+
setAncestryMode({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
13148
|
+
if (mountRef.current) mountRef.current.style.cursor = "grab";
|
|
13149
|
+
}
|
|
13150
|
+
if (questMode.isActive) {
|
|
13151
|
+
handleCancelQuest();
|
|
13152
|
+
}
|
|
13153
|
+
if (stateRef.current.selectedNodes.size > 0) {
|
|
13154
|
+
stateRef.current.selectedNodes.clear();
|
|
13155
|
+
}
|
|
13156
|
+
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
13157
|
+
setMultiContextMenu((prev) => ({ ...prev, visible: false }));
|
|
13158
|
+
setRelationshipMenu((prev) => ({ ...prev, visible: false }));
|
|
13159
|
+
}
|
|
13160
|
+
if (event.key.toLowerCase() === "q") {
|
|
13161
|
+
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;
|
|
13162
|
+
if (isUiClear) {
|
|
13163
|
+
const isView = ((_c2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _c2.toLowerCase()) === "view";
|
|
13164
|
+
if (!isView) return;
|
|
13165
|
+
const { graphGroup, glowTexture, controls, nodeObjects } = stateRef.current;
|
|
13166
|
+
if (graphGroup) {
|
|
13167
|
+
let ghostPosition = controls.target.clone();
|
|
13168
|
+
const existingNodes = Object.values(nodeObjects);
|
|
13169
|
+
let isOccupied = true;
|
|
13170
|
+
let radius = 18;
|
|
13171
|
+
let angle = 0;
|
|
13172
|
+
let attempts = 0;
|
|
13173
|
+
const MIN_CLEARANCE = 15;
|
|
13174
|
+
while (isOccupied && attempts < 30) {
|
|
13175
|
+
isOccupied = existingNodes.some((mesh) => mesh.position.distanceTo(ghostPosition) < MIN_CLEARANCE);
|
|
13176
|
+
if (isOccupied) {
|
|
13177
|
+
ghostPosition.x = controls.target.x + Math.cos(angle) * radius;
|
|
13178
|
+
ghostPosition.y = controls.target.y + (Math.random() - 0.5) * 8;
|
|
13179
|
+
ghostPosition.z = controls.target.z + Math.sin(angle) * radius;
|
|
13180
|
+
angle += Math.PI / 3;
|
|
13181
|
+
radius += 2.5;
|
|
13182
|
+
attempts++;
|
|
13183
|
+
}
|
|
13184
|
+
}
|
|
13185
|
+
const ghostData = {
|
|
13186
|
+
id: "ghost_quest",
|
|
13187
|
+
name: "Nova Quest",
|
|
13188
|
+
color: "#64748b",
|
|
13189
|
+
// Cor padrão de "Backlog"
|
|
13190
|
+
size: "medium",
|
|
13191
|
+
intensity: 0,
|
|
13192
|
+
type: ["quest"]
|
|
13193
|
+
};
|
|
13194
|
+
const ghostNode = createNodeMesh(ghostData, ghostPosition, glowTexture);
|
|
13195
|
+
ghostNode.traverse((child) => {
|
|
13196
|
+
if (child.isMesh) {
|
|
13197
|
+
child.material.transparent = true;
|
|
13198
|
+
child.material.opacity = 0.75;
|
|
13199
|
+
}
|
|
13200
|
+
});
|
|
13201
|
+
graphGroup.add(ghostNode);
|
|
13202
|
+
if (ghostNode.userData.labelObject) {
|
|
13203
|
+
graphGroup.add(ghostNode.userData.labelObject);
|
|
13204
|
+
}
|
|
13205
|
+
stateRef.current.ghostElements = {
|
|
13206
|
+
node: ghostNode,
|
|
13207
|
+
line: null,
|
|
13208
|
+
aura: ghostNode.getObjectByName("aura")
|
|
13209
|
+
};
|
|
13210
|
+
context.tweenToTarget(ghostPosition, 1.6);
|
|
13211
|
+
}
|
|
13212
|
+
setQuestMode({ isActive: true });
|
|
13213
|
+
}
|
|
13214
|
+
}
|
|
13215
|
+
}
|
|
13216
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
13217
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
13218
|
+
}, [
|
|
13219
|
+
contextMenu.visible,
|
|
13220
|
+
multiContextMenu.visible,
|
|
13221
|
+
relationshipMenu.visible,
|
|
13222
|
+
readingMode.isActive,
|
|
13223
|
+
isImportModalOpen,
|
|
13224
|
+
isAncestryBoardOpen,
|
|
13225
|
+
isSidebarOpen,
|
|
13226
|
+
detailsNode,
|
|
13227
|
+
detailsLink,
|
|
13228
|
+
ancestryLinkDetails,
|
|
13229
|
+
imageViewer.visible,
|
|
13230
|
+
editingAncestryRel.visible,
|
|
13231
|
+
questMode.isActive,
|
|
13232
|
+
viewParams,
|
|
13233
|
+
actionHandlerContext,
|
|
13234
|
+
handleCancelQuest
|
|
13235
|
+
// <-- handleCancelQuest adicionado aqui
|
|
13236
|
+
]);
|
|
12951
13237
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
12952
13238
|
return /* @__PURE__ */ import_react25.default.createElement(LoadingScreen, null);
|
|
12953
13239
|
}
|
|
@@ -13042,7 +13328,10 @@ function XViewScene({
|
|
|
13042
13328
|
InSceneQuestForm,
|
|
13043
13329
|
{
|
|
13044
13330
|
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
13045
|
-
onCancel:
|
|
13331
|
+
onCancel: handleCancelQuest,
|
|
13332
|
+
onNameChange: handleGhostNodeNameChange,
|
|
13333
|
+
onColorChange: handleGhostNodeColorChange,
|
|
13334
|
+
onSizeChange: handleGhostNodeSizeChange,
|
|
13046
13335
|
style: { position: "absolute", left: `16px`, top: `16px`, zIndex: 20, transition: "opacity 200ms ease-out" },
|
|
13047
13336
|
refEl: formRef,
|
|
13048
13337
|
onOpenImageViewer: handleOpenImageViewer,
|
|
@@ -13334,6 +13623,12 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
13334
13623
|
}
|
|
13335
13624
|
const sceneData = sceneResponse.data;
|
|
13336
13625
|
const parentDbObjects = sceneData.parent_dbs || [];
|
|
13626
|
+
if (type && type.toLowerCase().includes("database")) {
|
|
13627
|
+
const selfExists = parentDbObjects.some((db) => String(db.db_id) === String(scene_config));
|
|
13628
|
+
if (!selfExists) {
|
|
13629
|
+
parentDbObjects.push({ db_id: scene_config, owner_id });
|
|
13630
|
+
}
|
|
13631
|
+
}
|
|
13337
13632
|
const parentResponsesPromises = parentDbObjects.map(
|
|
13338
13633
|
(db_info) => db_services.get_file(`x_view_dbs/${db_info.owner_id}/${db_info.db_id}`)
|
|
13339
13634
|
);
|
|
@@ -13351,6 +13646,13 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
13351
13646
|
);
|
|
13352
13647
|
}
|
|
13353
13648
|
}
|
|
13649
|
+
if (type && type.toLowerCase() === "view") {
|
|
13650
|
+
parentData[scene_config] = {
|
|
13651
|
+
dataset_name: "Quests Internas (View)",
|
|
13652
|
+
nodes: sceneData.quest_nodes || [],
|
|
13653
|
+
links: sceneData.quest_links || []
|
|
13654
|
+
};
|
|
13655
|
+
}
|
|
13354
13656
|
const allNodes = Object.values(parentData).flatMap((db) => db.nodes || []);
|
|
13355
13657
|
const allLinks = Object.values(parentData).flatMap((db) => db.links || []);
|
|
13356
13658
|
const parentNodeMap = new Map(allNodes.map((node) => [String(node.id), node]));
|
|
@@ -13360,7 +13662,11 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
13360
13662
|
if (nodeTypes.includes("quest")) {
|
|
13361
13663
|
return sceneNode;
|
|
13362
13664
|
}
|
|
13363
|
-
|
|
13665
|
+
const dbNode = parentNodeMap.get(String(sceneNode.id));
|
|
13666
|
+
if (dbNode) {
|
|
13667
|
+
return { ...sceneNode, ...dbNode };
|
|
13668
|
+
}
|
|
13669
|
+
return null;
|
|
13364
13670
|
}).filter(Boolean);
|
|
13365
13671
|
const validNodeIdsInScene = new Set(validatedNodes.map((node) => String(node.id)));
|
|
13366
13672
|
const validatedLinks = (sceneData.links || []).filter((sceneLink) => {
|