@lv-x-software-house/x_view 1.2.4-dev.16 → 1.2.4-dev.18
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 +108 -59
- package/dist/index.mjs +108 -59
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1895,10 +1895,6 @@ var userActionHandlers = {
|
|
|
1895
1895
|
var _a;
|
|
1896
1896
|
const isSource = String(link.source) === String(sourceNode.id);
|
|
1897
1897
|
const targetNodeId = isSource ? link.target : link.source;
|
|
1898
|
-
const linkAlreadyInSceneData = sceneDataRef.current.links.some((l) => String(l.id) === String(link.id));
|
|
1899
|
-
if (!linkAlreadyInSceneData) {
|
|
1900
|
-
sceneDataRef.current.links.push(link);
|
|
1901
|
-
}
|
|
1902
1898
|
if (!nodeObjects[String(targetNodeId)]) {
|
|
1903
1899
|
const allParentNodes = Object.values(graphDataRef.current).flatMap((fileData) => fileData.nodes);
|
|
1904
1900
|
const nodeData = allParentNodes.find((n) => String(n.id) === String(targetNodeId));
|
|
@@ -1906,9 +1902,6 @@ var userActionHandlers = {
|
|
|
1906
1902
|
console.warn(`Dados do Node com ID ${targetNodeId} n\xE3o encontrados no cache.`);
|
|
1907
1903
|
return;
|
|
1908
1904
|
}
|
|
1909
|
-
if (!sceneDataRef.current.nodes.some((n) => String(n.id) === String(nodeData.id))) {
|
|
1910
|
-
sceneDataRef.current.nodes.push(nodeData);
|
|
1911
|
-
}
|
|
1912
1905
|
const startPosition = sourceNodeMesh.position.clone();
|
|
1913
1906
|
const endPosition = startPosition.clone().add(
|
|
1914
1907
|
new THREE.Vector3((Math.random() - 0.5) * 60, (Math.random() - 0.5) * 15, (Math.random() - 0.5) * 60)
|
|
@@ -2280,12 +2273,6 @@ var userActionHandlers = {
|
|
|
2280
2273
|
if (!nodeData || !sceneDataRef.current) return;
|
|
2281
2274
|
const nodeIdToDismiss = nodeData.id;
|
|
2282
2275
|
const strNodeId = String(nodeIdToDismiss);
|
|
2283
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2284
|
-
(n) => String(n.id) !== strNodeId
|
|
2285
|
-
);
|
|
2286
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2287
|
-
(l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId
|
|
2288
|
-
);
|
|
2289
2276
|
const { ancestryGroup, ancestryLinks } = stateRef.current;
|
|
2290
2277
|
if (ancestryGroup && ancestryLinks) {
|
|
2291
2278
|
const remainingAncestryLinks = [];
|
|
@@ -2327,22 +2314,12 @@ var userActionHandlers = {
|
|
|
2327
2314
|
removeNodeFromScene(stateRef.current, nodeId);
|
|
2328
2315
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
|
|
2329
2316
|
});
|
|
2330
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2331
|
-
(n) => String(n.id) === strNodeIdToKeep
|
|
2332
|
-
);
|
|
2333
|
-
sceneDataRef.current.links = [];
|
|
2334
2317
|
},
|
|
2335
2318
|
handleDismissMultipleNodes: (context, nodeIds) => {
|
|
2336
2319
|
const { stateRef, sceneDataRef, setters } = context;
|
|
2337
2320
|
setters.setMultiContextMenu({ visible: false });
|
|
2338
2321
|
if (!nodeIds || nodeIds.size === 0 || !sceneDataRef.current) return;
|
|
2339
2322
|
const strNodeIds = Array.from(nodeIds).map(String);
|
|
2340
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2341
|
-
(n) => !strNodeIds.includes(String(n.id))
|
|
2342
|
-
);
|
|
2343
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2344
|
-
(l) => !strNodeIds.includes(String(l.source)) && !strNodeIds.includes(String(l.target))
|
|
2345
|
-
);
|
|
2346
2323
|
const { ancestryGroup, ancestryLinks } = stateRef.current;
|
|
2347
2324
|
if (ancestryGroup && ancestryLinks) {
|
|
2348
2325
|
const remainingAncestryLinks = [];
|
|
@@ -2398,12 +2375,6 @@ var userActionHandlers = {
|
|
|
2398
2375
|
removeNodeFromScene(stateRef.current, nodeId);
|
|
2399
2376
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
|
|
2400
2377
|
});
|
|
2401
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2402
|
-
(n) => strNodeIdsToKeep.includes(String(n.id))
|
|
2403
|
-
);
|
|
2404
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2405
|
-
(l) => strNodeIdsToKeep.includes(String(l.source)) && strNodeIdsToKeep.includes(String(l.target))
|
|
2406
|
-
);
|
|
2407
2378
|
stateRef.current.selectedNodes.clear();
|
|
2408
2379
|
},
|
|
2409
2380
|
handleDeleteMultipleNodes: async (context, nodeIds) => {
|
|
@@ -2661,7 +2632,7 @@ var userActionHandlers = {
|
|
|
2661
2632
|
}
|
|
2662
2633
|
},
|
|
2663
2634
|
handleAddExistingNodeById: (context, nodeId) => {
|
|
2664
|
-
var _a
|
|
2635
|
+
var _a;
|
|
2665
2636
|
const { stateRef, sceneDataRef, graphDataRef, tweenToTarget, setters } = context;
|
|
2666
2637
|
const state = stateRef.current;
|
|
2667
2638
|
const graphFull = graphDataRef.current;
|
|
@@ -2677,16 +2648,12 @@ var userActionHandlers = {
|
|
|
2677
2648
|
tweenToTarget(state.nodeObjects[strNodeId]);
|
|
2678
2649
|
return;
|
|
2679
2650
|
}
|
|
2680
|
-
const alreadyInSceneData = (((_a = sceneDataRef.current) == null ? void 0 : _a.nodes) || []).some((n) => String(n.id) === String(strNodeId));
|
|
2681
|
-
if (!alreadyInSceneData) {
|
|
2682
|
-
sceneDataRef.current.nodes.push(nodeData);
|
|
2683
|
-
}
|
|
2684
2651
|
const base = state.controls ? state.controls.target.clone() : new THREE.Vector3(0, 0, 0);
|
|
2685
2652
|
const offset = new THREE.Vector3((Math.random() - 0.5) * 20, (Math.random() - 0.5) * 6, (Math.random() - 0.5) * 20);
|
|
2686
2653
|
const position = base.add(offset);
|
|
2687
2654
|
addStandaloneNodeToScene(state, nodeData, position);
|
|
2688
2655
|
tweenToTarget(position, 1.3);
|
|
2689
|
-
(
|
|
2656
|
+
(_a = setters == null ? void 0 : setters.setSceneVersion) == null ? void 0 : _a.call(setters, (v) => v + 1);
|
|
2690
2657
|
}
|
|
2691
2658
|
};
|
|
2692
2659
|
|
|
@@ -8000,7 +7967,11 @@ function InSceneQuestForm({
|
|
|
8000
7967
|
availableNodes = [],
|
|
8001
7968
|
availableAncestries = [],
|
|
8002
7969
|
onMentionClick,
|
|
8003
|
-
onUploadFile
|
|
7970
|
+
onUploadFile,
|
|
7971
|
+
// NOVAS PROPS PARA O GHOST NODE
|
|
7972
|
+
onNameChange,
|
|
7973
|
+
onColorChange,
|
|
7974
|
+
onSizeChange
|
|
8004
7975
|
}) {
|
|
8005
7976
|
const [name, setName] = (0, import_react16.useState)("");
|
|
8006
7977
|
const [types, setTypes] = (0, import_react16.useState)(["quest"]);
|
|
@@ -8112,12 +8083,26 @@ function InSceneQuestForm({
|
|
|
8112
8083
|
onClick: () => {
|
|
8113
8084
|
setStatus(s);
|
|
8114
8085
|
setIsStatusDropdownOpen(false);
|
|
8086
|
+
onColorChange == null ? void 0 : onColorChange(QUEST_STATUS_COLORS[s]);
|
|
8115
8087
|
},
|
|
8116
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"}`
|
|
8117
8089
|
},
|
|
8118
8090
|
/* @__PURE__ */ import_react16.default.createElement("span", { className: "w-3 h-3 rounded-full", style: { backgroundColor: QUEST_STATUS_COLORS[s] } }),
|
|
8119
8091
|
s
|
|
8120
|
-
)))))), /* @__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(
|
|
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(
|
|
8121
8106
|
"input",
|
|
8122
8107
|
{
|
|
8123
8108
|
type: "text",
|
|
@@ -8140,7 +8125,20 @@ function InSceneQuestForm({
|
|
|
8140
8125
|
onMentionClick,
|
|
8141
8126
|
onSaveDescription: (newDesc) => setDescription(newDesc)
|
|
8142
8127
|
}
|
|
8143
|
-
), /* @__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(
|
|
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(
|
|
8144
8142
|
CustomPropertyDisplay,
|
|
8145
8143
|
{
|
|
8146
8144
|
key: prop.id,
|
|
@@ -11636,6 +11634,26 @@ function XViewScene({
|
|
|
11636
11634
|
const handleStartVersioning = (nodeData) => {
|
|
11637
11635
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
11638
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
|
+
}, []);
|
|
11639
11657
|
const handleSaveQuestNode = async (context, newQuestData) => {
|
|
11640
11658
|
const { graphDataRef, sceneDataRef: sceneDataRef2, stateRef: stateRef2, setters, actions, sceneSaveUrl: sceneSaveUrl2, viewType, sceneConfigId: sceneConfigId2, ownerId: ownerId2 } = context;
|
|
11641
11659
|
if (!graphDataRef.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
|
|
@@ -11652,9 +11670,7 @@ function XViewScene({
|
|
|
11652
11670
|
const sceneFileData = {
|
|
11653
11671
|
parent_dbs: sceneDataRef2.current.parent_dbs,
|
|
11654
11672
|
nodes: sceneDataRef2.current.nodes,
|
|
11655
|
-
// <-- Mantém o cenário inicial inalterado
|
|
11656
11673
|
links: sceneDataRef2.current.links,
|
|
11657
|
-
// <-- Mantém o cenário inicial inalterado
|
|
11658
11674
|
quest_nodes: graphDataRef.current[sceneConfigId2].nodes,
|
|
11659
11675
|
quest_links: graphDataRef.current[sceneConfigId2].links
|
|
11660
11676
|
};
|
|
@@ -11665,9 +11681,13 @@ function XViewScene({
|
|
|
11665
11681
|
ownerId: ownerId2,
|
|
11666
11682
|
datasetName: "Quests Internas (View)"
|
|
11667
11683
|
});
|
|
11668
|
-
const
|
|
11669
|
-
const
|
|
11670
|
-
|
|
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 };
|
|
11671
11691
|
addStandaloneNodeToScene(stateRef2.current, newNode, finalPosition);
|
|
11672
11692
|
context.tweenToTarget(finalPosition, 1.2);
|
|
11673
11693
|
setters.setQuestMode({ isActive: false });
|
|
@@ -11705,12 +11725,9 @@ function XViewScene({
|
|
|
11705
11725
|
const viewFilePayload = {
|
|
11706
11726
|
parent_dbs: sceneDataRef2.current.parent_dbs,
|
|
11707
11727
|
nodes: sceneDataRef2.current.nodes,
|
|
11708
|
-
// <-- Usa o estado original intocado
|
|
11709
11728
|
links: sceneDataRef2.current.links,
|
|
11710
|
-
// <-- Usa o estado original intocado
|
|
11711
11729
|
quest_nodes: specificParentData.nodes,
|
|
11712
11730
|
quest_links: specificParentData.links
|
|
11713
|
-
// Salva a conexão aqui!
|
|
11714
11731
|
};
|
|
11715
11732
|
await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
|
|
11716
11733
|
} else {
|
|
@@ -13118,7 +13135,7 @@ function XViewScene({
|
|
|
13118
13135
|
}, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
|
|
13119
13136
|
(0, import_react25.useEffect)(() => {
|
|
13120
13137
|
function handleKeyDown(event) {
|
|
13121
|
-
var _a2, _b2, _c2
|
|
13138
|
+
var _a2, _b2, _c2;
|
|
13122
13139
|
const context = actionHandlerContext;
|
|
13123
13140
|
if (event.key === "Escape") {
|
|
13124
13141
|
if (stateRef.current.connection.isActive) userActionHandlers.handleCancelConnection(context);
|
|
@@ -13129,7 +13146,9 @@ function XViewScene({
|
|
|
13129
13146
|
setAncestryMode({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
13130
13147
|
if (mountRef.current) mountRef.current.style.cursor = "grab";
|
|
13131
13148
|
}
|
|
13132
|
-
if (
|
|
13149
|
+
if (questMode.isActive) {
|
|
13150
|
+
handleCancelQuest();
|
|
13151
|
+
}
|
|
13133
13152
|
if (stateRef.current.selectedNodes.size > 0) {
|
|
13134
13153
|
stateRef.current.selectedNodes.clear();
|
|
13135
13154
|
}
|
|
@@ -13138,16 +13157,42 @@ function XViewScene({
|
|
|
13138
13157
|
setRelationshipMenu((prev) => ({ ...prev, visible: false }));
|
|
13139
13158
|
}
|
|
13140
13159
|
if (event.key.toLowerCase() === "q") {
|
|
13141
|
-
const isUiClear = !stateRef.current.creation.isActive && !stateRef.current.connection.isActive && !stateRef.current.relink.isActive && !stateRef.current.ancestry.isActive && !((
|
|
13142
|
-
!detailsNode && // Condição nova
|
|
13143
|
-
!detailsLink && // Condição nova
|
|
13144
|
-
!ancestryLinkDetails && // Condição nova
|
|
13145
|
-
!imageViewer.visible && // Condição nova
|
|
13146
|
-
!editingAncestryRel.visible && // Condição nova
|
|
13147
|
-
!questMode.isActive;
|
|
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;
|
|
13148
13161
|
if (isUiClear) {
|
|
13149
|
-
const isView = ((
|
|
13162
|
+
const isView = ((_c2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _c2.toLowerCase()) === "view";
|
|
13150
13163
|
if (!isView) return;
|
|
13164
|
+
const { graphGroup, glowTexture, controls } = stateRef.current;
|
|
13165
|
+
if (graphGroup) {
|
|
13166
|
+
const basePosition = controls.target.clone();
|
|
13167
|
+
const offset = new THREE3.Vector3((Math.random() - 0.5) * 15, (Math.random() - 0.5) * 5, 0);
|
|
13168
|
+
const ghostPosition = basePosition.add(offset);
|
|
13169
|
+
const ghostData = {
|
|
13170
|
+
id: "ghost_quest",
|
|
13171
|
+
name: "Nova Quest",
|
|
13172
|
+
color: "#64748b",
|
|
13173
|
+
// Cor padrão de "Backlog"
|
|
13174
|
+
size: "medium",
|
|
13175
|
+
intensity: 0,
|
|
13176
|
+
type: ["quest"]
|
|
13177
|
+
};
|
|
13178
|
+
const ghostNode = createNodeMesh(ghostData, ghostPosition, glowTexture);
|
|
13179
|
+
ghostNode.traverse((child) => {
|
|
13180
|
+
if (child.isMesh) {
|
|
13181
|
+
child.material.transparent = true;
|
|
13182
|
+
child.material.opacity = 0.75;
|
|
13183
|
+
}
|
|
13184
|
+
});
|
|
13185
|
+
graphGroup.add(ghostNode);
|
|
13186
|
+
if (ghostNode.userData.labelObject) {
|
|
13187
|
+
graphGroup.add(ghostNode.userData.labelObject);
|
|
13188
|
+
}
|
|
13189
|
+
stateRef.current.ghostElements = {
|
|
13190
|
+
node: ghostNode,
|
|
13191
|
+
line: null,
|
|
13192
|
+
// Quests não possuem linha de conexão na criação
|
|
13193
|
+
aura: ghostNode.getObjectByName("aura")
|
|
13194
|
+
};
|
|
13195
|
+
}
|
|
13151
13196
|
setQuestMode({ isActive: true });
|
|
13152
13197
|
}
|
|
13153
13198
|
}
|
|
@@ -13155,7 +13200,6 @@ function XViewScene({
|
|
|
13155
13200
|
window.addEventListener("keydown", handleKeyDown);
|
|
13156
13201
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
13157
13202
|
}, [
|
|
13158
|
-
// Dependências: sempre que um painel abrir ou fechar, o React atualiza o listener com os dados frescos
|
|
13159
13203
|
contextMenu.visible,
|
|
13160
13204
|
multiContextMenu.visible,
|
|
13161
13205
|
relationshipMenu.visible,
|
|
@@ -13170,7 +13214,9 @@ function XViewScene({
|
|
|
13170
13214
|
editingAncestryRel.visible,
|
|
13171
13215
|
questMode.isActive,
|
|
13172
13216
|
viewParams,
|
|
13173
|
-
actionHandlerContext
|
|
13217
|
+
actionHandlerContext,
|
|
13218
|
+
handleCancelQuest
|
|
13219
|
+
// <-- handleCancelQuest adicionado aqui
|
|
13174
13220
|
]);
|
|
13175
13221
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
13176
13222
|
return /* @__PURE__ */ import_react25.default.createElement(LoadingScreen, null);
|
|
@@ -13266,7 +13312,10 @@ function XViewScene({
|
|
|
13266
13312
|
InSceneQuestForm,
|
|
13267
13313
|
{
|
|
13268
13314
|
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
13269
|
-
onCancel:
|
|
13315
|
+
onCancel: handleCancelQuest,
|
|
13316
|
+
onNameChange: handleGhostNodeNameChange,
|
|
13317
|
+
onColorChange: handleGhostNodeColorChange,
|
|
13318
|
+
onSizeChange: handleGhostNodeSizeChange,
|
|
13270
13319
|
style: { position: "absolute", left: `16px`, top: `16px`, zIndex: 20, transition: "opacity 200ms ease-out" },
|
|
13271
13320
|
refEl: formRef,
|
|
13272
13321
|
onOpenImageViewer: handleOpenImageViewer,
|
package/dist/index.mjs
CHANGED
|
@@ -1851,10 +1851,6 @@ var userActionHandlers = {
|
|
|
1851
1851
|
var _a;
|
|
1852
1852
|
const isSource = String(link.source) === String(sourceNode.id);
|
|
1853
1853
|
const targetNodeId = isSource ? link.target : link.source;
|
|
1854
|
-
const linkAlreadyInSceneData = sceneDataRef.current.links.some((l) => String(l.id) === String(link.id));
|
|
1855
|
-
if (!linkAlreadyInSceneData) {
|
|
1856
|
-
sceneDataRef.current.links.push(link);
|
|
1857
|
-
}
|
|
1858
1854
|
if (!nodeObjects[String(targetNodeId)]) {
|
|
1859
1855
|
const allParentNodes = Object.values(graphDataRef.current).flatMap((fileData) => fileData.nodes);
|
|
1860
1856
|
const nodeData = allParentNodes.find((n) => String(n.id) === String(targetNodeId));
|
|
@@ -1862,9 +1858,6 @@ var userActionHandlers = {
|
|
|
1862
1858
|
console.warn(`Dados do Node com ID ${targetNodeId} n\xE3o encontrados no cache.`);
|
|
1863
1859
|
return;
|
|
1864
1860
|
}
|
|
1865
|
-
if (!sceneDataRef.current.nodes.some((n) => String(n.id) === String(nodeData.id))) {
|
|
1866
|
-
sceneDataRef.current.nodes.push(nodeData);
|
|
1867
|
-
}
|
|
1868
1861
|
const startPosition = sourceNodeMesh.position.clone();
|
|
1869
1862
|
const endPosition = startPosition.clone().add(
|
|
1870
1863
|
new THREE.Vector3((Math.random() - 0.5) * 60, (Math.random() - 0.5) * 15, (Math.random() - 0.5) * 60)
|
|
@@ -2236,12 +2229,6 @@ var userActionHandlers = {
|
|
|
2236
2229
|
if (!nodeData || !sceneDataRef.current) return;
|
|
2237
2230
|
const nodeIdToDismiss = nodeData.id;
|
|
2238
2231
|
const strNodeId = String(nodeIdToDismiss);
|
|
2239
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2240
|
-
(n) => String(n.id) !== strNodeId
|
|
2241
|
-
);
|
|
2242
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2243
|
-
(l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId
|
|
2244
|
-
);
|
|
2245
2232
|
const { ancestryGroup, ancestryLinks } = stateRef.current;
|
|
2246
2233
|
if (ancestryGroup && ancestryLinks) {
|
|
2247
2234
|
const remainingAncestryLinks = [];
|
|
@@ -2283,22 +2270,12 @@ var userActionHandlers = {
|
|
|
2283
2270
|
removeNodeFromScene(stateRef.current, nodeId);
|
|
2284
2271
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
|
|
2285
2272
|
});
|
|
2286
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2287
|
-
(n) => String(n.id) === strNodeIdToKeep
|
|
2288
|
-
);
|
|
2289
|
-
sceneDataRef.current.links = [];
|
|
2290
2273
|
},
|
|
2291
2274
|
handleDismissMultipleNodes: (context, nodeIds) => {
|
|
2292
2275
|
const { stateRef, sceneDataRef, setters } = context;
|
|
2293
2276
|
setters.setMultiContextMenu({ visible: false });
|
|
2294
2277
|
if (!nodeIds || nodeIds.size === 0 || !sceneDataRef.current) return;
|
|
2295
2278
|
const strNodeIds = Array.from(nodeIds).map(String);
|
|
2296
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2297
|
-
(n) => !strNodeIds.includes(String(n.id))
|
|
2298
|
-
);
|
|
2299
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2300
|
-
(l) => !strNodeIds.includes(String(l.source)) && !strNodeIds.includes(String(l.target))
|
|
2301
|
-
);
|
|
2302
2279
|
const { ancestryGroup, ancestryLinks } = stateRef.current;
|
|
2303
2280
|
if (ancestryGroup && ancestryLinks) {
|
|
2304
2281
|
const remainingAncestryLinks = [];
|
|
@@ -2354,12 +2331,6 @@ var userActionHandlers = {
|
|
|
2354
2331
|
removeNodeFromScene(stateRef.current, nodeId);
|
|
2355
2332
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeId) ? null : prev);
|
|
2356
2333
|
});
|
|
2357
|
-
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter(
|
|
2358
|
-
(n) => strNodeIdsToKeep.includes(String(n.id))
|
|
2359
|
-
);
|
|
2360
|
-
sceneDataRef.current.links = sceneDataRef.current.links.filter(
|
|
2361
|
-
(l) => strNodeIdsToKeep.includes(String(l.source)) && strNodeIdsToKeep.includes(String(l.target))
|
|
2362
|
-
);
|
|
2363
2334
|
stateRef.current.selectedNodes.clear();
|
|
2364
2335
|
},
|
|
2365
2336
|
handleDeleteMultipleNodes: async (context, nodeIds) => {
|
|
@@ -2617,7 +2588,7 @@ var userActionHandlers = {
|
|
|
2617
2588
|
}
|
|
2618
2589
|
},
|
|
2619
2590
|
handleAddExistingNodeById: (context, nodeId) => {
|
|
2620
|
-
var _a
|
|
2591
|
+
var _a;
|
|
2621
2592
|
const { stateRef, sceneDataRef, graphDataRef, tweenToTarget, setters } = context;
|
|
2622
2593
|
const state = stateRef.current;
|
|
2623
2594
|
const graphFull = graphDataRef.current;
|
|
@@ -2633,16 +2604,12 @@ var userActionHandlers = {
|
|
|
2633
2604
|
tweenToTarget(state.nodeObjects[strNodeId]);
|
|
2634
2605
|
return;
|
|
2635
2606
|
}
|
|
2636
|
-
const alreadyInSceneData = (((_a = sceneDataRef.current) == null ? void 0 : _a.nodes) || []).some((n) => String(n.id) === String(strNodeId));
|
|
2637
|
-
if (!alreadyInSceneData) {
|
|
2638
|
-
sceneDataRef.current.nodes.push(nodeData);
|
|
2639
|
-
}
|
|
2640
2607
|
const base = state.controls ? state.controls.target.clone() : new THREE.Vector3(0, 0, 0);
|
|
2641
2608
|
const offset = new THREE.Vector3((Math.random() - 0.5) * 20, (Math.random() - 0.5) * 6, (Math.random() - 0.5) * 20);
|
|
2642
2609
|
const position = base.add(offset);
|
|
2643
2610
|
addStandaloneNodeToScene(state, nodeData, position);
|
|
2644
2611
|
tweenToTarget(position, 1.3);
|
|
2645
|
-
(
|
|
2612
|
+
(_a = setters == null ? void 0 : setters.setSceneVersion) == null ? void 0 : _a.call(setters, (v) => v + 1);
|
|
2646
2613
|
}
|
|
2647
2614
|
};
|
|
2648
2615
|
|
|
@@ -7987,7 +7954,11 @@ function InSceneQuestForm({
|
|
|
7987
7954
|
availableNodes = [],
|
|
7988
7955
|
availableAncestries = [],
|
|
7989
7956
|
onMentionClick,
|
|
7990
|
-
onUploadFile
|
|
7957
|
+
onUploadFile,
|
|
7958
|
+
// NOVAS PROPS PARA O GHOST NODE
|
|
7959
|
+
onNameChange,
|
|
7960
|
+
onColorChange,
|
|
7961
|
+
onSizeChange
|
|
7991
7962
|
}) {
|
|
7992
7963
|
const [name, setName] = useState16("");
|
|
7993
7964
|
const [types, setTypes] = useState16(["quest"]);
|
|
@@ -8099,12 +8070,26 @@ function InSceneQuestForm({
|
|
|
8099
8070
|
onClick: () => {
|
|
8100
8071
|
setStatus(s);
|
|
8101
8072
|
setIsStatusDropdownOpen(false);
|
|
8073
|
+
onColorChange == null ? void 0 : onColorChange(QUEST_STATUS_COLORS[s]);
|
|
8102
8074
|
},
|
|
8103
8075
|
className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${status === s ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
|
|
8104
8076
|
},
|
|
8105
8077
|
/* @__PURE__ */ React15.createElement("span", { className: "w-3 h-3 rounded-full", style: { backgroundColor: QUEST_STATUS_COLORS[s] } }),
|
|
8106
8078
|
s
|
|
8107
|
-
)))))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Quest"), /* @__PURE__ */ React15.createElement(
|
|
8079
|
+
)))))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Quest"), /* @__PURE__ */ React15.createElement(
|
|
8080
|
+
"input",
|
|
8081
|
+
{
|
|
8082
|
+
required: true,
|
|
8083
|
+
type: "text",
|
|
8084
|
+
placeholder: "Ex.: Refatorar M\xF3dulo X",
|
|
8085
|
+
value: name,
|
|
8086
|
+
onChange: (e) => {
|
|
8087
|
+
setName(e.target.value);
|
|
8088
|
+
onNameChange == null ? void 0 : onNameChange(e.target.value);
|
|
8089
|
+
},
|
|
8090
|
+
className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60"
|
|
8091
|
+
}
|
|
8092
|
+
)), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tipos Adicionais"), /* @__PURE__ */ React15.createElement("div", { className: "relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 focus-within:ring-2 focus-within:ring-indigo-400/60 transition-all" }, types.map((t, index) => /* @__PURE__ */ React15.createElement("span", { key: index, className: `flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-medium border ${t === "quest" ? "bg-sky-500/20 text-sky-200 border-sky-500/30" : "bg-indigo-500/30 text-indigo-100 border-indigo-500/20"}` }, t, t !== "quest" && /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => handleRemoveType(index), className: "hover:text-white transition-colors" }, /* @__PURE__ */ React15.createElement(FiX4, { size: 12 })))), /* @__PURE__ */ React15.createElement(
|
|
8108
8093
|
"input",
|
|
8109
8094
|
{
|
|
8110
8095
|
type: "text",
|
|
@@ -8127,7 +8112,20 @@ function InSceneQuestForm({
|
|
|
8127
8112
|
onMentionClick,
|
|
8128
8113
|
onSaveDescription: (newDesc) => setDescription(newDesc)
|
|
8129
8114
|
}
|
|
8130
|
-
), /* @__PURE__ */ React15.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiEdit26, { size: 14 }))), !description && /* @__PURE__ */ React15.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ React15.createElement(
|
|
8115
|
+
), /* @__PURE__ */ React15.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiEdit26, { size: 14 }))), !description && /* @__PURE__ */ React15.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ React15.createElement(
|
|
8116
|
+
"button",
|
|
8117
|
+
{
|
|
8118
|
+
key: s,
|
|
8119
|
+
type: "button",
|
|
8120
|
+
onClick: () => {
|
|
8121
|
+
setSize(s);
|
|
8122
|
+
onSizeChange == null ? void 0 : onSizeChange(s);
|
|
8123
|
+
},
|
|
8124
|
+
className: "flex items-center gap-2 group cursor-pointer focus:outline-none"
|
|
8125
|
+
},
|
|
8126
|
+
/* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${size === s ? "bg-indigo-500 border-indigo-500" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, size === s && /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12, className: "text-white" })),
|
|
8127
|
+
/* @__PURE__ */ React15.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s)
|
|
8128
|
+
)))), /* @__PURE__ */ React15.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React15.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiPlus5, { size: 14 }), " Adicionar")), /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ React15.createElement(
|
|
8131
8129
|
CustomPropertyDisplay,
|
|
8132
8130
|
{
|
|
8133
8131
|
key: prop.id,
|
|
@@ -11636,6 +11634,26 @@ function XViewScene({
|
|
|
11636
11634
|
const handleStartVersioning = (nodeData) => {
|
|
11637
11635
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
11638
11636
|
};
|
|
11637
|
+
const handleCancelQuest = useCallback4(() => {
|
|
11638
|
+
const { graphGroup, ghostElements } = stateRef.current;
|
|
11639
|
+
if (ghostElements.node && graphGroup) {
|
|
11640
|
+
if (ghostElements.node.userData.labelObject) {
|
|
11641
|
+
graphGroup.remove(ghostElements.node.userData.labelObject);
|
|
11642
|
+
if (ghostElements.node.userData.labelObject.material.map) ghostElements.node.userData.labelObject.material.map.dispose();
|
|
11643
|
+
ghostElements.node.userData.labelObject.material.dispose();
|
|
11644
|
+
}
|
|
11645
|
+
graphGroup.remove(ghostElements.node);
|
|
11646
|
+
ghostElements.node.traverse((child) => {
|
|
11647
|
+
if (child.material) {
|
|
11648
|
+
if (Array.isArray(child.material)) child.material.forEach((m) => m.dispose());
|
|
11649
|
+
else child.material.dispose();
|
|
11650
|
+
}
|
|
11651
|
+
if (child.geometry) child.geometry.dispose();
|
|
11652
|
+
});
|
|
11653
|
+
}
|
|
11654
|
+
stateRef.current.ghostElements = { node: null, line: null, aura: null };
|
|
11655
|
+
setQuestMode({ isActive: false });
|
|
11656
|
+
}, []);
|
|
11639
11657
|
const handleSaveQuestNode = async (context, newQuestData) => {
|
|
11640
11658
|
const { graphDataRef, sceneDataRef: sceneDataRef2, stateRef: stateRef2, setters, actions, sceneSaveUrl: sceneSaveUrl2, viewType, sceneConfigId: sceneConfigId2, ownerId: ownerId2 } = context;
|
|
11641
11659
|
if (!graphDataRef.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
|
|
@@ -11652,9 +11670,7 @@ function XViewScene({
|
|
|
11652
11670
|
const sceneFileData = {
|
|
11653
11671
|
parent_dbs: sceneDataRef2.current.parent_dbs,
|
|
11654
11672
|
nodes: sceneDataRef2.current.nodes,
|
|
11655
|
-
// <-- Mantém o cenário inicial inalterado
|
|
11656
11673
|
links: sceneDataRef2.current.links,
|
|
11657
|
-
// <-- Mantém o cenário inicial inalterado
|
|
11658
11674
|
quest_nodes: graphDataRef.current[sceneConfigId2].nodes,
|
|
11659
11675
|
quest_links: graphDataRef.current[sceneConfigId2].links
|
|
11660
11676
|
};
|
|
@@ -11665,9 +11681,13 @@ function XViewScene({
|
|
|
11665
11681
|
ownerId: ownerId2,
|
|
11666
11682
|
datasetName: "Quests Internas (View)"
|
|
11667
11683
|
});
|
|
11668
|
-
const
|
|
11669
|
-
const
|
|
11670
|
-
|
|
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 };
|
|
11671
11691
|
addStandaloneNodeToScene(stateRef2.current, newNode, finalPosition);
|
|
11672
11692
|
context.tweenToTarget(finalPosition, 1.2);
|
|
11673
11693
|
setters.setQuestMode({ isActive: false });
|
|
@@ -11705,12 +11725,9 @@ function XViewScene({
|
|
|
11705
11725
|
const viewFilePayload = {
|
|
11706
11726
|
parent_dbs: sceneDataRef2.current.parent_dbs,
|
|
11707
11727
|
nodes: sceneDataRef2.current.nodes,
|
|
11708
|
-
// <-- Usa o estado original intocado
|
|
11709
11728
|
links: sceneDataRef2.current.links,
|
|
11710
|
-
// <-- Usa o estado original intocado
|
|
11711
11729
|
quest_nodes: specificParentData.nodes,
|
|
11712
11730
|
quest_links: specificParentData.links
|
|
11713
|
-
// Salva a conexão aqui!
|
|
11714
11731
|
};
|
|
11715
11732
|
await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
|
|
11716
11733
|
} else {
|
|
@@ -13118,7 +13135,7 @@ function XViewScene({
|
|
|
13118
13135
|
}, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
|
|
13119
13136
|
useEffect21(() => {
|
|
13120
13137
|
function handleKeyDown(event) {
|
|
13121
|
-
var _a2, _b2, _c2
|
|
13138
|
+
var _a2, _b2, _c2;
|
|
13122
13139
|
const context = actionHandlerContext;
|
|
13123
13140
|
if (event.key === "Escape") {
|
|
13124
13141
|
if (stateRef.current.connection.isActive) userActionHandlers.handleCancelConnection(context);
|
|
@@ -13129,7 +13146,9 @@ function XViewScene({
|
|
|
13129
13146
|
setAncestryMode({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
13130
13147
|
if (mountRef.current) mountRef.current.style.cursor = "grab";
|
|
13131
13148
|
}
|
|
13132
|
-
if (
|
|
13149
|
+
if (questMode.isActive) {
|
|
13150
|
+
handleCancelQuest();
|
|
13151
|
+
}
|
|
13133
13152
|
if (stateRef.current.selectedNodes.size > 0) {
|
|
13134
13153
|
stateRef.current.selectedNodes.clear();
|
|
13135
13154
|
}
|
|
@@ -13138,16 +13157,42 @@ function XViewScene({
|
|
|
13138
13157
|
setRelationshipMenu((prev) => ({ ...prev, visible: false }));
|
|
13139
13158
|
}
|
|
13140
13159
|
if (event.key.toLowerCase() === "q") {
|
|
13141
|
-
const isUiClear = !stateRef.current.creation.isActive && !stateRef.current.connection.isActive && !stateRef.current.relink.isActive && !stateRef.current.ancestry.isActive && !((
|
|
13142
|
-
!detailsNode && // Condição nova
|
|
13143
|
-
!detailsLink && // Condição nova
|
|
13144
|
-
!ancestryLinkDetails && // Condição nova
|
|
13145
|
-
!imageViewer.visible && // Condição nova
|
|
13146
|
-
!editingAncestryRel.visible && // Condição nova
|
|
13147
|
-
!questMode.isActive;
|
|
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;
|
|
13148
13161
|
if (isUiClear) {
|
|
13149
|
-
const isView = ((
|
|
13162
|
+
const isView = ((_c2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _c2.toLowerCase()) === "view";
|
|
13150
13163
|
if (!isView) return;
|
|
13164
|
+
const { graphGroup, glowTexture, controls } = stateRef.current;
|
|
13165
|
+
if (graphGroup) {
|
|
13166
|
+
const basePosition = controls.target.clone();
|
|
13167
|
+
const offset = new THREE3.Vector3((Math.random() - 0.5) * 15, (Math.random() - 0.5) * 5, 0);
|
|
13168
|
+
const ghostPosition = basePosition.add(offset);
|
|
13169
|
+
const ghostData = {
|
|
13170
|
+
id: "ghost_quest",
|
|
13171
|
+
name: "Nova Quest",
|
|
13172
|
+
color: "#64748b",
|
|
13173
|
+
// Cor padrão de "Backlog"
|
|
13174
|
+
size: "medium",
|
|
13175
|
+
intensity: 0,
|
|
13176
|
+
type: ["quest"]
|
|
13177
|
+
};
|
|
13178
|
+
const ghostNode = createNodeMesh(ghostData, ghostPosition, glowTexture);
|
|
13179
|
+
ghostNode.traverse((child) => {
|
|
13180
|
+
if (child.isMesh) {
|
|
13181
|
+
child.material.transparent = true;
|
|
13182
|
+
child.material.opacity = 0.75;
|
|
13183
|
+
}
|
|
13184
|
+
});
|
|
13185
|
+
graphGroup.add(ghostNode);
|
|
13186
|
+
if (ghostNode.userData.labelObject) {
|
|
13187
|
+
graphGroup.add(ghostNode.userData.labelObject);
|
|
13188
|
+
}
|
|
13189
|
+
stateRef.current.ghostElements = {
|
|
13190
|
+
node: ghostNode,
|
|
13191
|
+
line: null,
|
|
13192
|
+
// Quests não possuem linha de conexão na criação
|
|
13193
|
+
aura: ghostNode.getObjectByName("aura")
|
|
13194
|
+
};
|
|
13195
|
+
}
|
|
13151
13196
|
setQuestMode({ isActive: true });
|
|
13152
13197
|
}
|
|
13153
13198
|
}
|
|
@@ -13155,7 +13200,6 @@ function XViewScene({
|
|
|
13155
13200
|
window.addEventListener("keydown", handleKeyDown);
|
|
13156
13201
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
13157
13202
|
}, [
|
|
13158
|
-
// Dependências: sempre que um painel abrir ou fechar, o React atualiza o listener com os dados frescos
|
|
13159
13203
|
contextMenu.visible,
|
|
13160
13204
|
multiContextMenu.visible,
|
|
13161
13205
|
relationshipMenu.visible,
|
|
@@ -13170,7 +13214,9 @@ function XViewScene({
|
|
|
13170
13214
|
editingAncestryRel.visible,
|
|
13171
13215
|
questMode.isActive,
|
|
13172
13216
|
viewParams,
|
|
13173
|
-
actionHandlerContext
|
|
13217
|
+
actionHandlerContext,
|
|
13218
|
+
handleCancelQuest
|
|
13219
|
+
// <-- handleCancelQuest adicionado aqui
|
|
13174
13220
|
]);
|
|
13175
13221
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
13176
13222
|
return /* @__PURE__ */ React24.createElement(LoadingScreen, null);
|
|
@@ -13266,7 +13312,10 @@ function XViewScene({
|
|
|
13266
13312
|
InSceneQuestForm,
|
|
13267
13313
|
{
|
|
13268
13314
|
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
13269
|
-
onCancel:
|
|
13315
|
+
onCancel: handleCancelQuest,
|
|
13316
|
+
onNameChange: handleGhostNodeNameChange,
|
|
13317
|
+
onColorChange: handleGhostNodeColorChange,
|
|
13318
|
+
onSizeChange: handleGhostNodeSizeChange,
|
|
13270
13319
|
style: { position: "absolute", left: `16px`, top: `16px`, zIndex: 20, transition: "opacity 200ms ease-out" },
|
|
13271
13320
|
refEl: formRef,
|
|
13272
13321
|
onOpenImageViewer: handleOpenImageViewer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lv-x-software-house/x_view",
|
|
3
|
-
"version": "1.2.4-dev.
|
|
3
|
+
"version": "1.2.4-dev.18",
|
|
4
4
|
"description": "Pacote privado contendo os componentes e lógica de renderização 3D do X View.",
|
|
5
5
|
"author": "iv.x - Engenharia de Software - ivxsoftwarehouse@gmail.com",
|
|
6
6
|
"license": "UNLICENSED",
|