@lv-x-software-house/x_view 1.2.4-dev.1 → 1.2.4-dev.10
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 +723 -351
- package/dist/index.mjs +643 -271
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -43,9 +43,9 @@ __export(index_exports, {
|
|
|
43
43
|
module.exports = __toCommonJS(index_exports);
|
|
44
44
|
|
|
45
45
|
// src/XViewScene.jsx
|
|
46
|
-
var
|
|
46
|
+
var import_react25 = __toESM(require("react"));
|
|
47
47
|
var import_navigation = require("next/navigation");
|
|
48
|
-
var
|
|
48
|
+
var import_react26 = require("next-auth/react");
|
|
49
49
|
var import_crypto_js = __toESM(require("crypto-js"));
|
|
50
50
|
var THREE3 = __toESM(require("three"));
|
|
51
51
|
var import_OrbitControls = require("three/examples/jsm/controls/OrbitControls.js");
|
|
@@ -1559,7 +1559,7 @@ var addStandaloneNodeToScene = (state, nodeData, position) => {
|
|
|
1559
1559
|
scaleTween.start();
|
|
1560
1560
|
}
|
|
1561
1561
|
};
|
|
1562
|
-
var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
|
|
1562
|
+
var getParentFileInfoForNode = (allParentData, sceneData, nodeId, sceneConfigId = null, sceneOwnerId = null) => {
|
|
1563
1563
|
const parentDbsArray = (sceneData == null ? void 0 : sceneData.parent_dbs) || [];
|
|
1564
1564
|
for (const parentFileId in allParentData) {
|
|
1565
1565
|
if (allParentData.hasOwnProperty(parentFileId)) {
|
|
@@ -1568,6 +1568,8 @@ var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
|
|
|
1568
1568
|
const parentDbInfo = parentDbsArray.find((db) => String(db.db_id) === String(parentFileId));
|
|
1569
1569
|
if (parentDbInfo) {
|
|
1570
1570
|
return { parentFileId, ownerId: parentDbInfo.owner_id };
|
|
1571
|
+
} else if (sceneConfigId && String(parentFileId) === String(sceneConfigId)) {
|
|
1572
|
+
return { parentFileId, ownerId: sceneOwnerId };
|
|
1571
1573
|
} else {
|
|
1572
1574
|
console.warn(`Owner ID n\xE3o encontrado em sceneData.parent_dbs para o parentFileId: ${parentFileId}`);
|
|
1573
1575
|
return { parentFileId, ownerId: null };
|
|
@@ -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.");
|
|
@@ -2022,7 +2024,7 @@ var userActionHandlers = {
|
|
|
2022
2024
|
userActionHandlers.handleCancelConnection(context);
|
|
2023
2025
|
return;
|
|
2024
2026
|
}
|
|
2025
|
-
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
|
|
2027
|
+
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
|
|
2026
2028
|
if (!sourceParentInfo || !sourceParentInfo.ownerId) {
|
|
2027
2029
|
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
2030
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
|
|
@@ -2111,8 +2113,8 @@ var userActionHandlers = {
|
|
|
2111
2113
|
} else {
|
|
2112
2114
|
newTargetId = newEndNodeData.id;
|
|
2113
2115
|
}
|
|
2114
|
-
const originalParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId);
|
|
2115
|
-
const newParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId);
|
|
2116
|
+
const originalParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId, context.sceneConfigId, context.ownerId);
|
|
2117
|
+
const newParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId, context.sceneConfigId, context.ownerId);
|
|
2116
2118
|
if (!originalParentInfo || !newParentInfo || !originalParentInfo.ownerId || !newParentInfo.ownerId) {
|
|
2117
2119
|
console.error("N\xE3o foi poss\xEDvel encontrar informa\xE7\xF5es dos arquivos pai para o relink.");
|
|
2118
2120
|
alert("Ocorreu um erro ao identificar os arquivos pai para salvar a altera\xE7\xE3o.");
|
|
@@ -2180,7 +2182,7 @@ var userActionHandlers = {
|
|
|
2180
2182
|
console.error("Tentativa de deletar um link sem ID.", linkObject.userData);
|
|
2181
2183
|
return;
|
|
2182
2184
|
}
|
|
2183
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source);
|
|
2185
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source, context.sceneConfigId, context.ownerId);
|
|
2184
2186
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2185
2187
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link:", linkIdToDelete);
|
|
2186
2188
|
alert("Ocorreu um erro ao identificar o arquivo pai da rela\xE7\xE3o para exclus\xE3o.");
|
|
@@ -2192,9 +2194,24 @@ var userActionHandlers = {
|
|
|
2192
2194
|
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
|
|
2193
2195
|
const newLinks = (specificParentData.links || []).filter((l) => String(l.id) !== String(linkIdToDelete));
|
|
2194
2196
|
specificParentData.links = newLinks;
|
|
2195
|
-
|
|
2197
|
+
let filenameToSave;
|
|
2198
|
+
let payloadToSave;
|
|
2199
|
+
if (parentFileId === context.sceneConfigId) {
|
|
2200
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2201
|
+
sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => String(l.id) !== String(linkIdToDelete));
|
|
2202
|
+
payloadToSave = {
|
|
2203
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2204
|
+
nodes: sceneDataRef.current.nodes,
|
|
2205
|
+
links: sceneDataRef.current.links,
|
|
2206
|
+
quest_nodes: specificParentData.nodes,
|
|
2207
|
+
quest_links: specificParentData.links
|
|
2208
|
+
};
|
|
2209
|
+
} else {
|
|
2210
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2211
|
+
payloadToSave = specificParentData;
|
|
2212
|
+
}
|
|
2196
2213
|
try {
|
|
2197
|
-
await context.actions.save_view_data(
|
|
2214
|
+
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2198
2215
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2199
2216
|
setters.setDetailsLink((prev) => String(prev == null ? void 0 : prev.id) === String(linkIdToDelete) ? null : prev);
|
|
2200
2217
|
if (stateRef.current.hoveredLink === linkObject) {
|
|
@@ -2357,7 +2374,7 @@ var userActionHandlers = {
|
|
|
2357
2374
|
}
|
|
2358
2375
|
const changesByParentFile = {};
|
|
2359
2376
|
for (const nodeId of strNodeIdsToDelete) {
|
|
2360
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId);
|
|
2377
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId, context.sceneConfigId, context.ownerId);
|
|
2361
2378
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2362
2379
|
console.warn(`Node com ID ${nodeId} n\xE3o encontrado ou sem ownerId. Ignorando.`);
|
|
2363
2380
|
continue;
|
|
@@ -2391,8 +2408,26 @@ var userActionHandlers = {
|
|
|
2391
2408
|
originalData.links = (originalData.links || []).filter(
|
|
2392
2409
|
(l) => !linksToDelete.has(String(l.id))
|
|
2393
2410
|
);
|
|
2394
|
-
|
|
2395
|
-
|
|
2411
|
+
let filenameToSave;
|
|
2412
|
+
let payloadToSave;
|
|
2413
|
+
if (parentFileId === context.sceneConfigId) {
|
|
2414
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2415
|
+
const strNodesToDelete = Array.from(nodesToDelete).map(String);
|
|
2416
|
+
const strLinksToDelete = Array.from(linksToDelete).map(String);
|
|
2417
|
+
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter((n) => !strNodesToDelete.includes(String(n.id)));
|
|
2418
|
+
sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => !strLinksToDelete.includes(String(l.id)));
|
|
2419
|
+
payloadToSave = {
|
|
2420
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2421
|
+
nodes: sceneDataRef.current.nodes,
|
|
2422
|
+
links: sceneDataRef.current.links,
|
|
2423
|
+
quest_nodes: originalData.nodes,
|
|
2424
|
+
quest_links: originalData.links
|
|
2425
|
+
};
|
|
2426
|
+
} else {
|
|
2427
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2428
|
+
payloadToSave = originalData;
|
|
2429
|
+
}
|
|
2430
|
+
savePromises.push(context.actions.save_view_data(filenameToSave, payloadToSave));
|
|
2396
2431
|
updatedParentDataCache[parentFileId] = originalData;
|
|
2397
2432
|
}
|
|
2398
2433
|
}
|
|
@@ -2424,7 +2459,7 @@ var userActionHandlers = {
|
|
|
2424
2459
|
if (!nodeData || !graphDataRef.current || !sceneDataRef.current) return;
|
|
2425
2460
|
const nodeIdToDelete = nodeData.id;
|
|
2426
2461
|
const strNodeId = String(nodeIdToDelete);
|
|
2427
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete);
|
|
2462
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete, context.sceneConfigId, context.ownerId);
|
|
2428
2463
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2429
2464
|
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
2465
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para exclus\xE3o.");
|
|
@@ -2436,9 +2471,27 @@ var userActionHandlers = {
|
|
|
2436
2471
|
const newLinks = (specificParentData.links || []).filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
|
|
2437
2472
|
specificParentData.nodes = newNodes;
|
|
2438
2473
|
specificParentData.links = newLinks;
|
|
2439
|
-
|
|
2474
|
+
let filenameToSave;
|
|
2475
|
+
let payloadToSave;
|
|
2476
|
+
if (parentFileId === context.sceneConfigId) {
|
|
2477
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2478
|
+
const newVisualNodes = sceneDataRef.current.nodes.filter((n) => String(n.id) !== strNodeId);
|
|
2479
|
+
const newVisualLinks = sceneDataRef.current.links.filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
|
|
2480
|
+
sceneDataRef.current.nodes = newVisualNodes;
|
|
2481
|
+
sceneDataRef.current.links = newVisualLinks;
|
|
2482
|
+
payloadToSave = {
|
|
2483
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2484
|
+
nodes: newVisualNodes,
|
|
2485
|
+
links: newVisualLinks,
|
|
2486
|
+
quest_nodes: specificParentData.nodes,
|
|
2487
|
+
quest_links: specificParentData.links
|
|
2488
|
+
};
|
|
2489
|
+
} else {
|
|
2490
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2491
|
+
payloadToSave = specificParentData;
|
|
2492
|
+
}
|
|
2440
2493
|
try {
|
|
2441
|
-
await context.actions.save_view_data(
|
|
2494
|
+
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2442
2495
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2443
2496
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeIdToDelete) ? null : prev);
|
|
2444
2497
|
removeNodeFromScene(stateRef.current, nodeIdToDelete);
|
|
@@ -2452,7 +2505,7 @@ var userActionHandlers = {
|
|
|
2452
2505
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2453
2506
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2454
2507
|
const { _baseEmissiveIntensity: ignored, ...nodeToSave } = updatedNode;
|
|
2455
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id);
|
|
2508
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id, context.sceneConfigId, context.ownerId);
|
|
2456
2509
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2457
2510
|
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
2511
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
|
|
@@ -2486,7 +2539,7 @@ var userActionHandlers = {
|
|
|
2486
2539
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2487
2540
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2488
2541
|
const { sourceNode, targetNode, ...linkToSave } = updatedLink;
|
|
2489
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source);
|
|
2542
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source, context.sceneConfigId, context.ownerId);
|
|
2490
2543
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2491
2544
|
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
2545
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
|
|
@@ -7848,9 +7901,180 @@ function InSceneVersionForm({
|
|
|
7848
7901
|
));
|
|
7849
7902
|
}
|
|
7850
7903
|
|
|
7851
|
-
// src/components/
|
|
7904
|
+
// src/components/InSceneQuestForm.jsx
|
|
7852
7905
|
var import_react16 = __toESM(require("react"));
|
|
7853
7906
|
var import_fi14 = require("react-icons/fi");
|
|
7907
|
+
var QUEST_STATUS_COLORS = {
|
|
7908
|
+
"Backlog": "#64748b",
|
|
7909
|
+
// Slate (Cinza azulado)
|
|
7910
|
+
"In Progress": "#eab308",
|
|
7911
|
+
// Yellow (Amarelo)
|
|
7912
|
+
"Review": "#a855f7",
|
|
7913
|
+
// Purple (Roxo)
|
|
7914
|
+
"Done": "#22c55e"
|
|
7915
|
+
// Green (Verde)
|
|
7916
|
+
};
|
|
7917
|
+
function InSceneQuestForm({
|
|
7918
|
+
onSave,
|
|
7919
|
+
onCancel,
|
|
7920
|
+
style,
|
|
7921
|
+
refEl,
|
|
7922
|
+
onOpenImageViewer,
|
|
7923
|
+
availableNodes = [],
|
|
7924
|
+
availableAncestries = [],
|
|
7925
|
+
onMentionClick,
|
|
7926
|
+
onUploadFile
|
|
7927
|
+
}) {
|
|
7928
|
+
const [name, setName] = (0, import_react16.useState)("");
|
|
7929
|
+
const [types, setTypes] = (0, import_react16.useState)(["quest"]);
|
|
7930
|
+
const [typeInput, setTypeInput] = (0, import_react16.useState)("");
|
|
7931
|
+
const [status, setStatus] = (0, import_react16.useState)("Backlog");
|
|
7932
|
+
const [size, setSize] = (0, import_react16.useState)("medium");
|
|
7933
|
+
const [intensity, setIntensity] = (0, import_react16.useState)(0);
|
|
7934
|
+
const [description, setDescription] = (0, import_react16.useState)("");
|
|
7935
|
+
const [customProps, setCustomProps] = (0, import_react16.useState)([]);
|
|
7936
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react16.useState)(false);
|
|
7937
|
+
const propsEndRef = (0, import_react16.useRef)(null);
|
|
7938
|
+
const handleAddProp = () => {
|
|
7939
|
+
const newProp = createNewCustomProperty(customProps);
|
|
7940
|
+
setCustomProps([...customProps, newProp]);
|
|
7941
|
+
setTimeout(() => {
|
|
7942
|
+
var _a;
|
|
7943
|
+
(_a = propsEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
7944
|
+
}, 100);
|
|
7945
|
+
};
|
|
7946
|
+
const handleRemoveProp = (index) => setCustomProps(customProps.filter((_, i) => i !== index));
|
|
7947
|
+
const handleUpdateProp = (index, updatedProp) => {
|
|
7948
|
+
const newProps = [...customProps];
|
|
7949
|
+
newProps[index] = updatedProp;
|
|
7950
|
+
setCustomProps(newProps);
|
|
7951
|
+
};
|
|
7952
|
+
const handleAddType = (newType) => {
|
|
7953
|
+
const trimmed = newType.trim();
|
|
7954
|
+
if (trimmed && !types.includes(trimmed)) {
|
|
7955
|
+
setTypes([...types, trimmed]);
|
|
7956
|
+
setTypeInput("");
|
|
7957
|
+
}
|
|
7958
|
+
};
|
|
7959
|
+
const handleRemoveType = (indexToRemove) => {
|
|
7960
|
+
if (types[indexToRemove] === "quest") return;
|
|
7961
|
+
setTypes(types.filter((_, index) => index !== indexToRemove));
|
|
7962
|
+
};
|
|
7963
|
+
const handleTypeInputKeyDown = (e) => {
|
|
7964
|
+
if (e.key === "Enter") {
|
|
7965
|
+
e.preventDefault();
|
|
7966
|
+
handleAddType(typeInput);
|
|
7967
|
+
} else if (e.key === "Backspace" && typeInput === "" && types.length > 1) {
|
|
7968
|
+
handleRemoveType(types.length - 1);
|
|
7969
|
+
}
|
|
7970
|
+
};
|
|
7971
|
+
const handleSubmit = (e) => {
|
|
7972
|
+
e.preventDefault();
|
|
7973
|
+
if (!name.trim()) {
|
|
7974
|
+
alert("O campo 'Nome' \xE9 obrigat\xF3rio.");
|
|
7975
|
+
return;
|
|
7976
|
+
}
|
|
7977
|
+
const additionalData = toObjectFromCustomProps(
|
|
7978
|
+
customProps.filter((prop) => prop.key.trim() && !prop.isEditing)
|
|
7979
|
+
);
|
|
7980
|
+
const processedSections = processDescriptionForSave(description, []);
|
|
7981
|
+
onSave({
|
|
7982
|
+
name: name.trim(),
|
|
7983
|
+
type: types,
|
|
7984
|
+
color: QUEST_STATUS_COLORS[status],
|
|
7985
|
+
// Cor atrelada ao status
|
|
7986
|
+
status,
|
|
7987
|
+
size,
|
|
7988
|
+
intensity,
|
|
7989
|
+
description: description.trim(),
|
|
7990
|
+
description_sections: processedSections,
|
|
7991
|
+
useImageAsTexture: false,
|
|
7992
|
+
textureImageUrl: null,
|
|
7993
|
+
...additionalData
|
|
7994
|
+
});
|
|
7995
|
+
};
|
|
7996
|
+
const swallow = (e) => e.stopPropagation();
|
|
7997
|
+
const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
|
|
7998
|
+
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
7999
|
+
return /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null, /* @__PURE__ */ import_react16.default.createElement(
|
|
8000
|
+
"div",
|
|
8001
|
+
{
|
|
8002
|
+
ref: refEl,
|
|
8003
|
+
className: "ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white w-[min(92vw,440px)] overflow-hidden",
|
|
8004
|
+
style,
|
|
8005
|
+
onPointerDown: swallow,
|
|
8006
|
+
onClick: swallow,
|
|
8007
|
+
onWheel: swallow,
|
|
8008
|
+
onContextMenu: swallow,
|
|
8009
|
+
onDoubleClick: swallow
|
|
8010
|
+
},
|
|
8011
|
+
/* @__PURE__ */ import_react16.default.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS[status]}, transparent)` } }),
|
|
8012
|
+
/* @__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 Tarefa / Objetivo")), /* @__PURE__ */ import_react16.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")),
|
|
8013
|
+
/* @__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(
|
|
8014
|
+
"select",
|
|
8015
|
+
{
|
|
8016
|
+
value: status,
|
|
8017
|
+
onChange: (e) => setStatus(e.target.value),
|
|
8018
|
+
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 appearance-none cursor-pointer",
|
|
8019
|
+
style: { borderLeft: `4px solid ${QUEST_STATUS_COLORS[status]}` }
|
|
8020
|
+
},
|
|
8021
|
+
/* @__PURE__ */ import_react16.default.createElement("option", { value: "Backlog" }, "Backlog"),
|
|
8022
|
+
/* @__PURE__ */ import_react16.default.createElement("option", { value: "In Progress" }, "In Progress"),
|
|
8023
|
+
/* @__PURE__ */ import_react16.default.createElement("option", { value: "Review" }, "Review"),
|
|
8024
|
+
/* @__PURE__ */ import_react16.default.createElement("option", { value: "Done" }, "Done")
|
|
8025
|
+
)), /* @__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("input", { required: true, type: "text", placeholder: "Ex.: Refatorar M\xF3dulo X", value: name, onChange: (e) => setName(e.target.value), 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" })), /* @__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(
|
|
8026
|
+
"input",
|
|
8027
|
+
{
|
|
8028
|
+
type: "text",
|
|
8029
|
+
value: typeInput,
|
|
8030
|
+
onChange: (e) => setTypeInput(e.target.value),
|
|
8031
|
+
onKeyDown: handleTypeInputKeyDown,
|
|
8032
|
+
onBlur: () => {
|
|
8033
|
+
if (typeInput.trim()) handleAddType(typeInput);
|
|
8034
|
+
},
|
|
8035
|
+
className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
|
|
8036
|
+
autoComplete: "off"
|
|
8037
|
+
}
|
|
8038
|
+
))), /* @__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(
|
|
8039
|
+
DescriptionDisplay,
|
|
8040
|
+
{
|
|
8041
|
+
description,
|
|
8042
|
+
savedSections: [],
|
|
8043
|
+
availableNodes,
|
|
8044
|
+
availableAncestries,
|
|
8045
|
+
onMentionClick,
|
|
8046
|
+
onSaveDescription: (newDesc) => setDescription(newDesc)
|
|
8047
|
+
}
|
|
8048
|
+
), /* @__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 Cen\xE1rio (Size)"), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ import_react16.default.createElement("button", { key: s, type: "button", onClick: () => setSize(s), className: "flex items-center gap-2 group cursor-pointer focus:outline-none" }, /* @__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" })), /* @__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))))), /* @__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(
|
|
8049
|
+
CustomPropertyDisplay,
|
|
8050
|
+
{
|
|
8051
|
+
key: prop.id,
|
|
8052
|
+
prop,
|
|
8053
|
+
onUpdate: (updatedProp) => handleUpdateProp(index, updatedProp),
|
|
8054
|
+
onRemove: () => handleRemoveProp(index),
|
|
8055
|
+
onOpenImageViewer,
|
|
8056
|
+
unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type),
|
|
8057
|
+
onUploadFile
|
|
8058
|
+
}
|
|
8059
|
+
)), /* @__PURE__ */ import_react16.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react16.default.createElement("button", { type: "button", onClick: onCancel, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm" }, "Cancelar"), /* @__PURE__ */ import_react16.default.createElement("button", { type: "submit", className: "px-4 py-2 rounded-lg bg-gradient-to-tr from-indigo-600 to-indigo-400 hover:from-indigo-500 hover:to-indigo-300 transition-colors font-semibold text-sm shadow-[0_8px_24px_rgba(99,102,241,0.35)]" }, "Salvar Quest")))
|
|
8060
|
+
), isDescriptionModalOpen && /* @__PURE__ */ import_react16.default.createElement(
|
|
8061
|
+
DescriptionEditModal,
|
|
8062
|
+
{
|
|
8063
|
+
isOpen: isDescriptionModalOpen,
|
|
8064
|
+
title: "Editar Descri\xE7\xE3o da Quest",
|
|
8065
|
+
initialValue: description,
|
|
8066
|
+
onSave: (newDescription) => setDescription(newDescription),
|
|
8067
|
+
onClose: () => setIsDescriptionModalOpen(false),
|
|
8068
|
+
availableNodes,
|
|
8069
|
+
availableAncestries,
|
|
8070
|
+
availableImages
|
|
8071
|
+
}
|
|
8072
|
+
));
|
|
8073
|
+
}
|
|
8074
|
+
|
|
8075
|
+
// src/components/NodeDetailsPanel.jsx
|
|
8076
|
+
var import_react17 = __toESM(require("react"));
|
|
8077
|
+
var import_fi15 = require("react-icons/fi");
|
|
7854
8078
|
function NodeDetailsPanel({
|
|
7855
8079
|
node,
|
|
7856
8080
|
onClose,
|
|
@@ -7871,38 +8095,38 @@ function NodeDetailsPanel({
|
|
|
7871
8095
|
userRole,
|
|
7872
8096
|
currentDatasetName
|
|
7873
8097
|
}) {
|
|
7874
|
-
const [name, setName] = (0,
|
|
7875
|
-
const [types, setTypes] = (0,
|
|
7876
|
-
const [typeInput, setTypeInput] = (0,
|
|
7877
|
-
const [color, setColor] = (0,
|
|
7878
|
-
const [size, setSize] = (0,
|
|
7879
|
-
const [description, setDescription] = (0,
|
|
7880
|
-
const [intensity, setIntensity] = (0,
|
|
7881
|
-
const [customProps, setCustomProps] = (0,
|
|
7882
|
-
const [showTypeSuggestions, setShowTypeSuggestions] = (0,
|
|
7883
|
-
const [filteredTypes, setFilteredTypes] = (0,
|
|
7884
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0,
|
|
7885
|
-
const [isReadMode, setIsReadMode] = (0,
|
|
7886
|
-
const [existingSections, setExistingSections] = (0,
|
|
7887
|
-
const [isSaving, setIsSaving] = (0,
|
|
7888
|
-
const [isLinkCopied, setIsLinkCopied] = (0,
|
|
7889
|
-
const [useImageAsTexture, setUseImageAsTexture] = (0,
|
|
8098
|
+
const [name, setName] = (0, import_react17.useState)((node == null ? void 0 : node.name) ?? "");
|
|
8099
|
+
const [types, setTypes] = (0, import_react17.useState)([]);
|
|
8100
|
+
const [typeInput, setTypeInput] = (0, import_react17.useState)("");
|
|
8101
|
+
const [color, setColor] = (0, import_react17.useState)((node == null ? void 0 : node.color) ?? "#8b5cf6");
|
|
8102
|
+
const [size, setSize] = (0, import_react17.useState)((node == null ? void 0 : node.size) ?? "medium");
|
|
8103
|
+
const [description, setDescription] = (0, import_react17.useState)((node == null ? void 0 : node.description) ?? "");
|
|
8104
|
+
const [intensity, setIntensity] = (0, import_react17.useState)((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
|
|
8105
|
+
const [customProps, setCustomProps] = (0, import_react17.useState)(() => extractCustomPropsFromNode(node || {}));
|
|
8106
|
+
const [showTypeSuggestions, setShowTypeSuggestions] = (0, import_react17.useState)(false);
|
|
8107
|
+
const [filteredTypes, setFilteredTypes] = (0, import_react17.useState)([]);
|
|
8108
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react17.useState)(false);
|
|
8109
|
+
const [isReadMode, setIsReadMode] = (0, import_react17.useState)(false);
|
|
8110
|
+
const [existingSections, setExistingSections] = (0, import_react17.useState)((node == null ? void 0 : node.description_sections) || []);
|
|
8111
|
+
const [isSaving, setIsSaving] = (0, import_react17.useState)(false);
|
|
8112
|
+
const [isLinkCopied, setIsLinkCopied] = (0, import_react17.useState)(false);
|
|
8113
|
+
const [useImageAsTexture, setUseImageAsTexture] = (0, import_react17.useState)(() => {
|
|
7890
8114
|
if ((node == null ? void 0 : node.useImageAsTexture) === "true") return true;
|
|
7891
8115
|
if ((node == null ? void 0 : node.useImageAsTexture) === "false") return false;
|
|
7892
8116
|
return !!(node == null ? void 0 : node.useImageAsTexture);
|
|
7893
8117
|
});
|
|
7894
|
-
const [selectedImageUrl, setSelectedImageUrl] = (0,
|
|
8118
|
+
const [selectedImageUrl, setSelectedImageUrl] = (0, import_react17.useState)((node == null ? void 0 : node.textureImageUrl) ?? null);
|
|
7895
8119
|
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
7896
8120
|
const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
|
|
7897
8121
|
initialWidth: isReadMode ? 700 : 440,
|
|
7898
8122
|
minWidth: 320,
|
|
7899
8123
|
maxWidth: maxPanelW
|
|
7900
8124
|
});
|
|
7901
|
-
(0,
|
|
8125
|
+
(0, import_react17.useEffect)(() => {
|
|
7902
8126
|
setWidth(isReadMode ? 700 : 440);
|
|
7903
8127
|
}, [isReadMode, setWidth]);
|
|
7904
|
-
const prevNodeIdRef = (0,
|
|
7905
|
-
const propsEndRef = (0,
|
|
8128
|
+
const prevNodeIdRef = (0, import_react17.useRef)(null);
|
|
8129
|
+
const propsEndRef = (0, import_react17.useRef)(null);
|
|
7906
8130
|
const canEdit = userRole !== "viewer";
|
|
7907
8131
|
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
7908
8132
|
const handleImageClickFromText = (url, name2) => {
|
|
@@ -7910,7 +8134,7 @@ function NodeDetailsPanel({
|
|
|
7910
8134
|
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
7911
8135
|
}
|
|
7912
8136
|
};
|
|
7913
|
-
(0,
|
|
8137
|
+
(0, import_react17.useEffect)(() => {
|
|
7914
8138
|
if ((node == null ? void 0 : node.id) !== prevNodeIdRef.current) {
|
|
7915
8139
|
prevNodeIdRef.current = node == null ? void 0 : node.id;
|
|
7916
8140
|
setName((node == null ? void 0 : node.name) ?? "");
|
|
@@ -7932,13 +8156,13 @@ function NodeDetailsPanel({
|
|
|
7932
8156
|
}
|
|
7933
8157
|
}, [node]);
|
|
7934
8158
|
const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
|
|
7935
|
-
(0,
|
|
8159
|
+
(0, import_react17.useEffect)(() => {
|
|
7936
8160
|
if (!hasImages && useImageAsTexture) {
|
|
7937
8161
|
setUseImageAsTexture(false);
|
|
7938
8162
|
setSelectedImageUrl(null);
|
|
7939
8163
|
}
|
|
7940
8164
|
}, [hasImages, useImageAsTexture]);
|
|
7941
|
-
(0,
|
|
8165
|
+
(0, import_react17.useEffect)(() => {
|
|
7942
8166
|
if (typeInput.trim() === "") {
|
|
7943
8167
|
setFilteredTypes(existingTypes.filter((t) => !types.includes(t)));
|
|
7944
8168
|
} else {
|
|
@@ -8110,7 +8334,7 @@ function NodeDetailsPanel({
|
|
|
8110
8334
|
onClose();
|
|
8111
8335
|
};
|
|
8112
8336
|
const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
|
|
8113
|
-
return /* @__PURE__ */
|
|
8337
|
+
return /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement(
|
|
8114
8338
|
"div",
|
|
8115
8339
|
{
|
|
8116
8340
|
className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col ${isResizing ? "transition-none" : "transition-all duration-300 ease-out"}`,
|
|
@@ -8123,7 +8347,7 @@ function NodeDetailsPanel({
|
|
|
8123
8347
|
onContextMenu: swallow,
|
|
8124
8348
|
onDoubleClick: swallow
|
|
8125
8349
|
},
|
|
8126
|
-
/* @__PURE__ */
|
|
8350
|
+
/* @__PURE__ */ import_react17.default.createElement(
|
|
8127
8351
|
"div",
|
|
8128
8352
|
{
|
|
8129
8353
|
onPointerDown: (e) => {
|
|
@@ -8134,7 +8358,7 @@ function NodeDetailsPanel({
|
|
|
8134
8358
|
title: "Arraste para redimensionar"
|
|
8135
8359
|
}
|
|
8136
8360
|
),
|
|
8137
|
-
isReadMode ? /* @__PURE__ */
|
|
8361
|
+
isReadMode ? /* @__PURE__ */ import_react17.default.createElement(
|
|
8138
8362
|
DescriptionReadModePanel,
|
|
8139
8363
|
{
|
|
8140
8364
|
title: name || (node == null ? void 0 : node.name),
|
|
@@ -8155,23 +8379,23 @@ function NodeDetailsPanel({
|
|
|
8155
8379
|
onImageClick: handleImageClickFromText,
|
|
8156
8380
|
onSaveDescription: handleSaveDescriptionInline
|
|
8157
8381
|
}
|
|
8158
|
-
) : /* @__PURE__ */
|
|
8382
|
+
) : /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ import_react17.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react17.default.createElement("div", null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react17.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ import_react17.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ import_react17.default.createElement(
|
|
8159
8383
|
"button",
|
|
8160
8384
|
{
|
|
8161
8385
|
onClick: handleCopyLink,
|
|
8162
8386
|
className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
|
|
8163
8387
|
title: isLinkCopied ? "Link Copiado!" : "Copiar link para este Node"
|
|
8164
8388
|
},
|
|
8165
|
-
isLinkCopied ? /* @__PURE__ */
|
|
8166
|
-
)), /* @__PURE__ */
|
|
8389
|
+
isLinkCopied ? /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiCheck, { size: 12 }) : /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiLink, { size: 12 })
|
|
8390
|
+
)), /* @__PURE__ */ import_react17.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ import_react17.default.createElement("button", { onClick: handleCancel, disabled: isSaving, 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 disabled:opacity-50", title: "Cancelar" }, "\xD7")), /* @__PURE__ */ import_react17.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Tipos"), /* @__PURE__ */ import_react17.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 ${canEdit ? "focus-within:ring-2 focus-within:ring-indigo-400/60" : ""} transition-all` }, types.map((t, index) => /* @__PURE__ */ import_react17.default.createElement("span", { key: index, className: "flex items-center gap-1 bg-indigo-500/30 text-indigo-100 px-1.5 py-0.5 rounded-md text-xs font-medium border border-indigo-500/20" }, t, canEdit && /* @__PURE__ */ import_react17.default.createElement(
|
|
8167
8391
|
"button",
|
|
8168
8392
|
{
|
|
8169
8393
|
type: "button",
|
|
8170
8394
|
onClick: () => handleRemoveType(index),
|
|
8171
8395
|
className: "hover:text-white transition-colors"
|
|
8172
8396
|
},
|
|
8173
|
-
/* @__PURE__ */
|
|
8174
|
-
))), canEdit && /* @__PURE__ */
|
|
8397
|
+
/* @__PURE__ */ import_react17.default.createElement(import_fi15.FiX, { size: 12 })
|
|
8398
|
+
))), canEdit && /* @__PURE__ */ import_react17.default.createElement(
|
|
8175
8399
|
"input",
|
|
8176
8400
|
{
|
|
8177
8401
|
type: "text",
|
|
@@ -8192,7 +8416,7 @@ function NodeDetailsPanel({
|
|
|
8192
8416
|
placeholder: types.length === 0 ? "Ex.: Cliente" : "",
|
|
8193
8417
|
autoComplete: "off"
|
|
8194
8418
|
}
|
|
8195
|
-
), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */
|
|
8419
|
+
), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */ import_react17.default.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-10 w-full mt-1 max-h-40 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, filteredTypes.map((suggestedType, index) => /* @__PURE__ */ import_react17.default.createElement(
|
|
8196
8420
|
"li",
|
|
8197
8421
|
{
|
|
8198
8422
|
key: index,
|
|
@@ -8203,7 +8427,7 @@ function NodeDetailsPanel({
|
|
|
8203
8427
|
}
|
|
8204
8428
|
},
|
|
8205
8429
|
suggestedType
|
|
8206
|
-
))))), /* @__PURE__ */
|
|
8430
|
+
))))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome"), /* @__PURE__ */ import_react17.default.createElement(
|
|
8207
8431
|
"input",
|
|
8208
8432
|
{
|
|
8209
8433
|
type: "text",
|
|
@@ -8212,7 +8436,7 @@ function NodeDetailsPanel({
|
|
|
8212
8436
|
readOnly: !canEdit,
|
|
8213
8437
|
className: `w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none ${canEdit ? "focus:ring-2 focus:ring-indigo-400/60" : "cursor-default text-slate-400"}`
|
|
8214
8438
|
}
|
|
8215
|
-
)), /* @__PURE__ */
|
|
8439
|
+
)), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react17.default.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ import_react17.default.createElement(
|
|
8216
8440
|
DescriptionDisplay,
|
|
8217
8441
|
{
|
|
8218
8442
|
description,
|
|
@@ -8224,7 +8448,7 @@ function NodeDetailsPanel({
|
|
|
8224
8448
|
onImageClick: handleImageClickFromText,
|
|
8225
8449
|
onSaveDescription: handleSaveDescriptionInline
|
|
8226
8450
|
}
|
|
8227
|
-
), /* @__PURE__ */
|
|
8451
|
+
), /* @__PURE__ */ import_react17.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 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react17.default.createElement(
|
|
8228
8452
|
"button",
|
|
8229
8453
|
{
|
|
8230
8454
|
type: "button",
|
|
@@ -8232,8 +8456,8 @@ function NodeDetailsPanel({
|
|
|
8232
8456
|
className: `p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors ${canEdit ? "border-r border-white/5" : ""}`,
|
|
8233
8457
|
title: "Modo de Leitura"
|
|
8234
8458
|
},
|
|
8235
|
-
/* @__PURE__ */
|
|
8236
|
-
), canEdit && /* @__PURE__ */
|
|
8459
|
+
/* @__PURE__ */ import_react17.default.createElement(import_fi15.FiBookOpen, { size: 14 })
|
|
8460
|
+
), canEdit && /* @__PURE__ */ import_react17.default.createElement(
|
|
8237
8461
|
"button",
|
|
8238
8462
|
{
|
|
8239
8463
|
type: "button",
|
|
@@ -8241,17 +8465,17 @@ function NodeDetailsPanel({
|
|
|
8241
8465
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8242
8466
|
title: "Editar descri\xE7\xE3o (Modo de Escrita)"
|
|
8243
8467
|
},
|
|
8244
|
-
/* @__PURE__ */
|
|
8245
|
-
)), canEdit && !description && /* @__PURE__ */
|
|
8468
|
+
/* @__PURE__ */ import_react17.default.createElement(import_fi15.FiEdit2, { size: 14 })
|
|
8469
|
+
)), canEdit && !description && /* @__PURE__ */ import_react17.default.createElement(
|
|
8246
8470
|
"div",
|
|
8247
8471
|
{
|
|
8248
8472
|
onClick: () => setIsDescriptionModalOpen(true),
|
|
8249
8473
|
className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
|
|
8250
8474
|
},
|
|
8251
8475
|
"Adicionar descri\xE7\xE3o..."
|
|
8252
|
-
))), /* @__PURE__ */
|
|
8476
|
+
))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Size"), /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
|
|
8253
8477
|
const isSelected = size === s;
|
|
8254
|
-
return /* @__PURE__ */
|
|
8478
|
+
return /* @__PURE__ */ import_react17.default.createElement(
|
|
8255
8479
|
"button",
|
|
8256
8480
|
{
|
|
8257
8481
|
key: s,
|
|
@@ -8259,10 +8483,10 @@ function NodeDetailsPanel({
|
|
|
8259
8483
|
onClick: () => canEdit && handleSizeChange(s),
|
|
8260
8484
|
className: `flex items-center gap-2 group focus:outline-none ${canEdit ? "cursor-pointer" : "cursor-default opacity-80"}`
|
|
8261
8485
|
},
|
|
8262
|
-
/* @__PURE__ */
|
|
8263
|
-
/* @__PURE__ */
|
|
8486
|
+
/* @__PURE__ */ import_react17.default.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${isSelected ? "bg-indigo-500 border-indigo-500 shadow-[0_0_10px_rgba(99,102,241,0.4)]" : "border-slate-600 bg-transparent " + (canEdit ? "group-hover:border-slate-500" : "")}` }, isSelected && /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiCheck, { size: 12, className: "text-white" })),
|
|
8487
|
+
/* @__PURE__ */ import_react17.default.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s)
|
|
8264
8488
|
);
|
|
8265
|
-
}))), /* @__PURE__ */
|
|
8489
|
+
}))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), canEdit && hasImages && /* @__PURE__ */ import_react17.default.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${useImageAsTexture ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, useImageAsTexture && /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react17.default.createElement(
|
|
8266
8490
|
"input",
|
|
8267
8491
|
{
|
|
8268
8492
|
type: "checkbox",
|
|
@@ -8270,14 +8494,14 @@ function NodeDetailsPanel({
|
|
|
8270
8494
|
onChange: handleToggleImageMode,
|
|
8271
8495
|
className: "hidden"
|
|
8272
8496
|
}
|
|
8273
|
-
), /* @__PURE__ */
|
|
8497
|
+
), /* @__PURE__ */ import_react17.default.createElement("span", { className: `text-xs ${useImageAsTexture ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, "Usar imagem para representar o node"))), /* @__PURE__ */ import_react17.default.createElement(
|
|
8274
8498
|
ColorPicker,
|
|
8275
8499
|
{
|
|
8276
8500
|
color,
|
|
8277
8501
|
onChange: handleColorChange,
|
|
8278
8502
|
disabled: !canEdit || useImageAsTexture
|
|
8279
8503
|
}
|
|
8280
|
-
), /* @__PURE__ */
|
|
8504
|
+
), /* @__PURE__ */ import_react17.default.createElement("div", { className: "mt-3 flex items-center gap-3" }, /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiSun, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ import_react17.default.createElement(
|
|
8281
8505
|
"input",
|
|
8282
8506
|
{
|
|
8283
8507
|
type: "range",
|
|
@@ -8290,7 +8514,7 @@ function NodeDetailsPanel({
|
|
|
8290
8514
|
className: `w-full h-1.5 bg-slate-700 rounded-lg appearance-none ${canEdit ? "cursor-pointer accent-indigo-500 hover:accent-indigo-400" : "cursor-default accent-slate-500"}`,
|
|
8291
8515
|
title: `Intensidade do brilho: ${intensity}`
|
|
8292
8516
|
}
|
|
8293
|
-
), /* @__PURE__ */
|
|
8517
|
+
), /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-xs text-slate-400 w-6 text-right" }, intensity)), /* @__PURE__ */ import_react17.default.createElement("span", { className: `text-xs block mt-1 transition-opacity ${useImageAsTexture ? "opacity-40" : "text-slate-400"}` }, useImageAsTexture ? "Cor da borda (definida pela imagem)" : "Ajuste a cor e a intensidade do brilho.")), /* @__PURE__ */ import_react17.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react17.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react17.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_react17.default.createElement(import_fi15.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react17.default.createElement(
|
|
8294
8518
|
CustomPropertyDisplay,
|
|
8295
8519
|
{
|
|
8296
8520
|
key: prop.id,
|
|
@@ -8305,7 +8529,7 @@ function NodeDetailsPanel({
|
|
|
8305
8529
|
onUploadFile: canEdit ? onUploadFile : void 0,
|
|
8306
8530
|
readOnly: !canEdit
|
|
8307
8531
|
}
|
|
8308
|
-
)), /* @__PURE__ */
|
|
8532
|
+
)), /* @__PURE__ */ import_react17.default.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ import_react17.default.createElement("div", { className: "pt-3 mt-4 border-t border-white/10 flex items-center justify-end gap-2 text-xs text-slate-400" }, /* @__PURE__ */ import_react17.default.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react17.default.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ import_react17.default.createElement(
|
|
8309
8533
|
"button",
|
|
8310
8534
|
{
|
|
8311
8535
|
onClick: () => handleSave(false),
|
|
@@ -8314,10 +8538,10 @@ function NodeDetailsPanel({
|
|
|
8314
8538
|
${isSaving ? "bg-slate-700 text-slate-300 cursor-wait" : "bg-gradient-to-tr from-indigo-600 to-indigo-400 hover:from-indigo-500 hover:to-indigo-300 text-white"}
|
|
8315
8539
|
`
|
|
8316
8540
|
},
|
|
8317
|
-
isSaving && /* @__PURE__ */
|
|
8541
|
+
isSaving && /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiLoader, { className: "animate-spin" }),
|
|
8318
8542
|
isSaving ? "Salvando..." : "Salvar"
|
|
8319
8543
|
)))
|
|
8320
|
-
), isDescriptionModalOpen && canEdit && /* @__PURE__ */
|
|
8544
|
+
), isDescriptionModalOpen && canEdit && /* @__PURE__ */ import_react17.default.createElement(
|
|
8321
8545
|
DescriptionEditModal,
|
|
8322
8546
|
{
|
|
8323
8547
|
isOpen: isDescriptionModalOpen,
|
|
@@ -8337,7 +8561,7 @@ function NodeDetailsPanel({
|
|
|
8337
8561
|
}
|
|
8338
8562
|
|
|
8339
8563
|
// src/components/MultiNodeContextMenu.jsx
|
|
8340
|
-
var
|
|
8564
|
+
var import_react18 = __toESM(require("react"));
|
|
8341
8565
|
function MultiNodeContextMenu({
|
|
8342
8566
|
data,
|
|
8343
8567
|
userRole,
|
|
@@ -8346,12 +8570,12 @@ function MultiNodeContextMenu({
|
|
|
8346
8570
|
onDismissOtherNodes,
|
|
8347
8571
|
onDeleteNodes
|
|
8348
8572
|
}) {
|
|
8349
|
-
const menuRef = (0,
|
|
8350
|
-
const [menuPos, setMenuPos] = (0,
|
|
8351
|
-
const [isConfirmingDelete, setIsConfirmingDelete] = (0,
|
|
8573
|
+
const menuRef = (0, import_react18.useRef)(null);
|
|
8574
|
+
const [menuPos, setMenuPos] = (0, import_react18.useState)({ left: 0, top: 0 });
|
|
8575
|
+
const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react18.useState)(false);
|
|
8352
8576
|
const ability = defineAbilityFor(userRole);
|
|
8353
8577
|
const canDelete = ability.can("delete", "Node");
|
|
8354
|
-
(0,
|
|
8578
|
+
(0, import_react18.useLayoutEffect)(() => {
|
|
8355
8579
|
if (!data.visible || !menuRef.current) return;
|
|
8356
8580
|
const el = menuRef.current;
|
|
8357
8581
|
const w = el.clientWidth;
|
|
@@ -8364,7 +8588,7 @@ function MultiNodeContextMenu({
|
|
|
8364
8588
|
if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
|
|
8365
8589
|
setMenuPos({ left, top });
|
|
8366
8590
|
}, [data]);
|
|
8367
|
-
(0,
|
|
8591
|
+
(0, import_react18.useEffect)(() => {
|
|
8368
8592
|
if (data.visible) {
|
|
8369
8593
|
setIsConfirmingDelete(false);
|
|
8370
8594
|
}
|
|
@@ -8379,7 +8603,7 @@ function MultiNodeContextMenu({
|
|
|
8379
8603
|
const baseButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-indigo-500/20 text-slate-200 hover:text-white transition-colors duration-150 truncate";
|
|
8380
8604
|
const deleteButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-red-500/25 text-red-400 hover:text-red-300 transition-colors duration-150 truncate";
|
|
8381
8605
|
const nodeCount = data.nodeIds.size;
|
|
8382
|
-
return /* @__PURE__ */
|
|
8606
|
+
return /* @__PURE__ */ import_react18.default.createElement(
|
|
8383
8607
|
"div",
|
|
8384
8608
|
{
|
|
8385
8609
|
ref: menuRef,
|
|
@@ -8393,28 +8617,28 @@ function MultiNodeContextMenu({
|
|
|
8393
8617
|
onContextMenu: swallow,
|
|
8394
8618
|
onDoubleClick: swallow
|
|
8395
8619
|
},
|
|
8396
|
-
/* @__PURE__ */
|
|
8397
|
-
/* @__PURE__ */
|
|
8620
|
+
/* @__PURE__ */ import_react18.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
|
|
8621
|
+
/* @__PURE__ */ import_react18.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ import_react18.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react18.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react18.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_react18.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ import_react18.default.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ import_react18.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight" }, "Esta a\xE7\xE3o \xE9 irrevers\xEDvel. Todas as conex\xF5es associadas a eles ser\xE3o apagadas.")), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react18.default.createElement(
|
|
8398
8622
|
"button",
|
|
8399
8623
|
{
|
|
8400
8624
|
onClick: () => setIsConfirmingDelete(false),
|
|
8401
8625
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
|
|
8402
8626
|
},
|
|
8403
8627
|
"Cancelar"
|
|
8404
|
-
), /* @__PURE__ */
|
|
8628
|
+
), /* @__PURE__ */ import_react18.default.createElement(
|
|
8405
8629
|
"button",
|
|
8406
8630
|
{
|
|
8407
8631
|
onClick: () => onDeleteNodes(data.nodeIds),
|
|
8408
8632
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
|
|
8409
8633
|
},
|
|
8410
8634
|
"Excluir"
|
|
8411
|
-
))) : /* @__PURE__ */
|
|
8635
|
+
))) : /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react18.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_react18.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_react18.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react18.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_react18.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react18.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
|
|
8412
8636
|
);
|
|
8413
8637
|
}
|
|
8414
8638
|
|
|
8415
8639
|
// src/components/RelationshipDetailsPanel.jsx
|
|
8416
|
-
var
|
|
8417
|
-
var
|
|
8640
|
+
var import_react19 = __toESM(require("react"));
|
|
8641
|
+
var import_fi16 = require("react-icons/fi");
|
|
8418
8642
|
function RelationshipDetailsPanel({
|
|
8419
8643
|
link,
|
|
8420
8644
|
onClose,
|
|
@@ -8428,19 +8652,19 @@ function RelationshipDetailsPanel({
|
|
|
8428
8652
|
onUploadFile,
|
|
8429
8653
|
userRole
|
|
8430
8654
|
}) {
|
|
8431
|
-
const [name, setName] = (0,
|
|
8432
|
-
const [description, setDescription] = (0,
|
|
8433
|
-
const [customProps, setCustomProps] = (0,
|
|
8434
|
-
const [existingSections, setExistingSections] = (0,
|
|
8435
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0,
|
|
8436
|
-
const [isSaving, setIsSaving] = (0,
|
|
8437
|
-
const [isReadMode, setIsReadMode] = (0,
|
|
8438
|
-
const propsEndRef = (0,
|
|
8439
|
-
const canEdit = (0,
|
|
8655
|
+
const [name, setName] = (0, import_react19.useState)((link == null ? void 0 : link.name) ?? "");
|
|
8656
|
+
const [description, setDescription] = (0, import_react19.useState)((link == null ? void 0 : link.description) ?? "");
|
|
8657
|
+
const [customProps, setCustomProps] = (0, import_react19.useState)(() => extractCustomPropsFromNode(link || {}));
|
|
8658
|
+
const [existingSections, setExistingSections] = (0, import_react19.useState)((link == null ? void 0 : link.description_sections) || []);
|
|
8659
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react19.useState)(false);
|
|
8660
|
+
const [isSaving, setIsSaving] = (0, import_react19.useState)(false);
|
|
8661
|
+
const [isReadMode, setIsReadMode] = (0, import_react19.useState)(false);
|
|
8662
|
+
const propsEndRef = (0, import_react19.useRef)(null);
|
|
8663
|
+
const canEdit = (0, import_react19.useMemo)(() => {
|
|
8440
8664
|
const ability = defineAbilityFor(userRole);
|
|
8441
8665
|
return ability.can("update", "Connection");
|
|
8442
8666
|
}, [userRole]);
|
|
8443
|
-
(0,
|
|
8667
|
+
(0, import_react19.useEffect)(() => {
|
|
8444
8668
|
setName((link == null ? void 0 : link.name) ?? "");
|
|
8445
8669
|
setDescription((link == null ? void 0 : link.description) ?? "");
|
|
8446
8670
|
setExistingSections((link == null ? void 0 : link.description_sections) || []);
|
|
@@ -8515,7 +8739,7 @@ function RelationshipDetailsPanel({
|
|
|
8515
8739
|
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
8516
8740
|
}
|
|
8517
8741
|
};
|
|
8518
|
-
return /* @__PURE__ */
|
|
8742
|
+
return /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement(
|
|
8519
8743
|
"div",
|
|
8520
8744
|
{
|
|
8521
8745
|
className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden transition-all duration-300 ease-out
|
|
@@ -8530,7 +8754,7 @@ function RelationshipDetailsPanel({
|
|
|
8530
8754
|
onContextMenu: swallow,
|
|
8531
8755
|
onDoubleClick: swallow
|
|
8532
8756
|
},
|
|
8533
|
-
isReadMode ? /* @__PURE__ */
|
|
8757
|
+
isReadMode ? /* @__PURE__ */ import_react19.default.createElement(
|
|
8534
8758
|
DescriptionReadModePanel,
|
|
8535
8759
|
{
|
|
8536
8760
|
title: name || "Rela\xE7\xE3o",
|
|
@@ -8551,7 +8775,7 @@ function RelationshipDetailsPanel({
|
|
|
8551
8775
|
onImageClick: handleImageClickFromText,
|
|
8552
8776
|
onSaveDescription: handleSaveDescriptionInline
|
|
8553
8777
|
}
|
|
8554
|
-
) : /* @__PURE__ */
|
|
8778
|
+
) : /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ import_react19.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react19.default.createElement("div", null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react19.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-teal-400/80 shadow-[0_0_18px_2px_rgba(45,212,191,0.55)]" }), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.default.createElement("button", { onClick: onClose, disabled: isSaving, 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 disabled:opacity-50", title: "Fechar" }, "\xD7")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react19.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react19.default.createElement(
|
|
8555
8779
|
"input",
|
|
8556
8780
|
{
|
|
8557
8781
|
type: "text",
|
|
@@ -8563,7 +8787,7 @@ function RelationshipDetailsPanel({
|
|
|
8563
8787
|
${!canEdit ? "opacity-50 cursor-not-allowed" : ""}
|
|
8564
8788
|
`
|
|
8565
8789
|
}
|
|
8566
|
-
)), /* @__PURE__ */
|
|
8790
|
+
)), /* @__PURE__ */ import_react19.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react19.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react19.default.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ import_react19.default.createElement(
|
|
8567
8791
|
DescriptionDisplay,
|
|
8568
8792
|
{
|
|
8569
8793
|
description,
|
|
@@ -8575,7 +8799,7 @@ function RelationshipDetailsPanel({
|
|
|
8575
8799
|
onImageClick: handleImageClickFromText,
|
|
8576
8800
|
onSaveDescription: handleSaveDescriptionInline
|
|
8577
8801
|
}
|
|
8578
|
-
), /* @__PURE__ */
|
|
8802
|
+
), /* @__PURE__ */ import_react19.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 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react19.default.createElement(
|
|
8579
8803
|
"button",
|
|
8580
8804
|
{
|
|
8581
8805
|
type: "button",
|
|
@@ -8583,8 +8807,8 @@ function RelationshipDetailsPanel({
|
|
|
8583
8807
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors border-r border-white/5",
|
|
8584
8808
|
title: "Modo de Leitura"
|
|
8585
8809
|
},
|
|
8586
|
-
/* @__PURE__ */
|
|
8587
|
-
), canEdit && /* @__PURE__ */
|
|
8810
|
+
/* @__PURE__ */ import_react19.default.createElement(import_fi16.FiBookOpen, { size: 14 })
|
|
8811
|
+
), canEdit && /* @__PURE__ */ import_react19.default.createElement(
|
|
8588
8812
|
"button",
|
|
8589
8813
|
{
|
|
8590
8814
|
type: "button",
|
|
@@ -8592,15 +8816,15 @@ function RelationshipDetailsPanel({
|
|
|
8592
8816
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8593
8817
|
title: "Editar descri\xE7\xE3o"
|
|
8594
8818
|
},
|
|
8595
|
-
/* @__PURE__ */
|
|
8596
|
-
)), !description && canEdit && /* @__PURE__ */
|
|
8819
|
+
/* @__PURE__ */ import_react19.default.createElement(import_fi16.FiEdit2, { size: 14 })
|
|
8820
|
+
)), !description && canEdit && /* @__PURE__ */ import_react19.default.createElement(
|
|
8597
8821
|
"div",
|
|
8598
8822
|
{
|
|
8599
8823
|
onClick: () => setIsDescriptionModalOpen(true),
|
|
8600
8824
|
className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
|
|
8601
8825
|
},
|
|
8602
8826
|
"Adicionar descri\xE7\xE3o..."
|
|
8603
|
-
))), /* @__PURE__ */
|
|
8827
|
+
))), /* @__PURE__ */ import_react19.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react19.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react19.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_react19.default.createElement(import_fi16.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react19.default.createElement(
|
|
8604
8828
|
CustomPropertyDisplay,
|
|
8605
8829
|
{
|
|
8606
8830
|
key: prop.id,
|
|
@@ -8612,7 +8836,7 @@ function RelationshipDetailsPanel({
|
|
|
8612
8836
|
onUploadFile,
|
|
8613
8837
|
disabled: !canEdit
|
|
8614
8838
|
}
|
|
8615
|
-
)), /* @__PURE__ */
|
|
8839
|
+
)), /* @__PURE__ */ import_react19.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react19.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react19.default.createElement("button", { onClick: onClose, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ import_react19.default.createElement(
|
|
8616
8840
|
"button",
|
|
8617
8841
|
{
|
|
8618
8842
|
onClick: () => handleSave(false),
|
|
@@ -8621,10 +8845,10 @@ function RelationshipDetailsPanel({
|
|
|
8621
8845
|
${isSaving ? "bg-slate-700 text-slate-300 cursor-wait" : "bg-gradient-to-tr from-teal-600 to-teal-400 hover:from-teal-500 hover:to-teal-300 text-white"}
|
|
8622
8846
|
`
|
|
8623
8847
|
},
|
|
8624
|
-
isSaving && /* @__PURE__ */
|
|
8848
|
+
isSaving && /* @__PURE__ */ import_react19.default.createElement(import_fi16.FiLoader, { className: "animate-spin" }),
|
|
8625
8849
|
isSaving ? "Salvando..." : "Salvar"
|
|
8626
8850
|
)))
|
|
8627
|
-
), isDescriptionModalOpen && /* @__PURE__ */
|
|
8851
|
+
), isDescriptionModalOpen && /* @__PURE__ */ import_react19.default.createElement(
|
|
8628
8852
|
DescriptionEditModal,
|
|
8629
8853
|
{
|
|
8630
8854
|
isOpen: isDescriptionModalOpen,
|
|
@@ -8645,7 +8869,7 @@ function RelationshipDetailsPanel({
|
|
|
8645
8869
|
}
|
|
8646
8870
|
|
|
8647
8871
|
// src/components/RelationshipContextMenu.jsx
|
|
8648
|
-
var
|
|
8872
|
+
var import_react20 = __toESM(require("react"));
|
|
8649
8873
|
function RelationshipContextMenu({
|
|
8650
8874
|
data,
|
|
8651
8875
|
userRole,
|
|
@@ -8655,25 +8879,25 @@ function RelationshipContextMenu({
|
|
|
8655
8879
|
onDelete,
|
|
8656
8880
|
onClose
|
|
8657
8881
|
}) {
|
|
8658
|
-
const menuRef = (0,
|
|
8659
|
-
const [menuPos, setMenuPos] = (0,
|
|
8660
|
-
const [isConfirmingDelete, setIsConfirmingDelete] = (0,
|
|
8661
|
-
const ability = (0,
|
|
8662
|
-
const sourceName = (0,
|
|
8882
|
+
const menuRef = (0, import_react20.useRef)(null);
|
|
8883
|
+
const [menuPos, setMenuPos] = (0, import_react20.useState)({ left: 0, top: 0 });
|
|
8884
|
+
const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react20.useState)(false);
|
|
8885
|
+
const ability = (0, import_react20.useMemo)(() => defineAbilityFor(userRole), [userRole]);
|
|
8886
|
+
const sourceName = (0, import_react20.useMemo)(
|
|
8663
8887
|
() => {
|
|
8664
8888
|
var _a, _b, _c, _d;
|
|
8665
8889
|
return ((_d = (_c = (_b = (_a = data == null ? void 0 : data.linkObject) == null ? void 0 : _a.userData) == null ? void 0 : _b.sourceNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) ?? "(sem nome)";
|
|
8666
8890
|
},
|
|
8667
8891
|
[data == null ? void 0 : data.linkObject]
|
|
8668
8892
|
);
|
|
8669
|
-
const targetName = (0,
|
|
8893
|
+
const targetName = (0, import_react20.useMemo)(
|
|
8670
8894
|
() => {
|
|
8671
8895
|
var _a, _b, _c, _d;
|
|
8672
8896
|
return ((_d = (_c = (_b = (_a = data == null ? void 0 : data.linkObject) == null ? void 0 : _a.userData) == null ? void 0 : _b.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) ?? "(sem nome)";
|
|
8673
8897
|
},
|
|
8674
8898
|
[data == null ? void 0 : data.linkObject]
|
|
8675
8899
|
);
|
|
8676
|
-
(0,
|
|
8900
|
+
(0, import_react20.useLayoutEffect)(() => {
|
|
8677
8901
|
if (!data.visible || !menuRef.current) return;
|
|
8678
8902
|
const el = menuRef.current;
|
|
8679
8903
|
const w = el.clientWidth;
|
|
@@ -8686,7 +8910,7 @@ function RelationshipContextMenu({
|
|
|
8686
8910
|
if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
|
|
8687
8911
|
setMenuPos({ left, top });
|
|
8688
8912
|
}, [data]);
|
|
8689
|
-
(0,
|
|
8913
|
+
(0, import_react20.useEffect)(() => {
|
|
8690
8914
|
if (data.visible) {
|
|
8691
8915
|
setIsConfirmingDelete(false);
|
|
8692
8916
|
}
|
|
@@ -8702,7 +8926,7 @@ function RelationshipContextMenu({
|
|
|
8702
8926
|
const dangerButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-rose-500/20 text-rose-300 hover:text-rose-100 transition-colors duration-150 truncate";
|
|
8703
8927
|
const canUpdate = ability.can("update", "Connection");
|
|
8704
8928
|
const canDelete = ability.can("delete", "Connection");
|
|
8705
|
-
return /* @__PURE__ */
|
|
8929
|
+
return /* @__PURE__ */ import_react20.default.createElement(
|
|
8706
8930
|
"div",
|
|
8707
8931
|
{
|
|
8708
8932
|
ref: menuRef,
|
|
@@ -8716,29 +8940,29 @@ function RelationshipContextMenu({
|
|
|
8716
8940
|
onContextMenu: swallow,
|
|
8717
8941
|
onDoubleClick: swallow
|
|
8718
8942
|
},
|
|
8719
|
-
/* @__PURE__ */
|
|
8720
|
-
/* @__PURE__ */
|
|
8943
|
+
/* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
|
|
8944
|
+
/* @__PURE__ */ import_react20.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ import_react20.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react20.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ import_react20.default.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ import_react20.default.createElement("strong", null, targetName), ".")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react20.default.createElement(
|
|
8721
8945
|
"button",
|
|
8722
8946
|
{
|
|
8723
8947
|
onClick: () => setIsConfirmingDelete(false),
|
|
8724
8948
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
|
|
8725
8949
|
},
|
|
8726
8950
|
"Cancelar"
|
|
8727
|
-
), /* @__PURE__ */
|
|
8951
|
+
), /* @__PURE__ */ import_react20.default.createElement(
|
|
8728
8952
|
"button",
|
|
8729
8953
|
{
|
|
8730
8954
|
onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
|
|
8731
8955
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-rose-600 hover:bg-rose-500 rounded-md text-white transition-colors"
|
|
8732
8956
|
},
|
|
8733
8957
|
"Excluir"
|
|
8734
|
-
))) : /* @__PURE__ */
|
|
8958
|
+
))) : /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react20.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-teal-400/80 shadow-[0_0_12px_1px_rgba(45,212,191,0.5)]" }), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement(
|
|
8735
8959
|
"button",
|
|
8736
8960
|
{
|
|
8737
8961
|
onClick: () => onRelinkSource == null ? void 0 : onRelinkSource(data.linkObject),
|
|
8738
8962
|
className: baseButtonClass,
|
|
8739
8963
|
title: "Desconectar ponta ligada ao Source"
|
|
8740
8964
|
},
|
|
8741
|
-
/* @__PURE__ */
|
|
8965
|
+
/* @__PURE__ */ import_react20.default.createElement(
|
|
8742
8966
|
"svg",
|
|
8743
8967
|
{
|
|
8744
8968
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8751,18 +8975,18 @@ function RelationshipContextMenu({
|
|
|
8751
8975
|
strokeLinecap: "round",
|
|
8752
8976
|
strokeLinejoin: "round"
|
|
8753
8977
|
},
|
|
8754
|
-
/* @__PURE__ */
|
|
8755
|
-
/* @__PURE__ */
|
|
8978
|
+
/* @__PURE__ */ import_react20.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" }),
|
|
8979
|
+
/* @__PURE__ */ import_react20.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" })
|
|
8756
8980
|
),
|
|
8757
|
-
/* @__PURE__ */
|
|
8758
|
-
), /* @__PURE__ */
|
|
8981
|
+
/* @__PURE__ */ import_react20.default.createElement("span", null, "Desconectar Source (", sourceName, ")")
|
|
8982
|
+
), /* @__PURE__ */ import_react20.default.createElement(
|
|
8759
8983
|
"button",
|
|
8760
8984
|
{
|
|
8761
8985
|
onClick: () => onRelinkTarget == null ? void 0 : onRelinkTarget(data.linkObject),
|
|
8762
8986
|
className: baseButtonClass,
|
|
8763
8987
|
title: "Desconectar ponta ligada ao Target"
|
|
8764
8988
|
},
|
|
8765
|
-
/* @__PURE__ */
|
|
8989
|
+
/* @__PURE__ */ import_react20.default.createElement(
|
|
8766
8990
|
"svg",
|
|
8767
8991
|
{
|
|
8768
8992
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8775,21 +8999,21 @@ function RelationshipContextMenu({
|
|
|
8775
8999
|
strokeLinecap: "round",
|
|
8776
9000
|
strokeLinejoin: "round"
|
|
8777
9001
|
},
|
|
8778
|
-
/* @__PURE__ */
|
|
8779
|
-
/* @__PURE__ */
|
|
8780
|
-
/* @__PURE__ */
|
|
8781
|
-
/* @__PURE__ */
|
|
8782
|
-
/* @__PURE__ */
|
|
9002
|
+
/* @__PURE__ */ import_react20.default.createElement("polyline", { points: "16 3 21 3 21 8" }),
|
|
9003
|
+
/* @__PURE__ */ import_react20.default.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
|
|
9004
|
+
/* @__PURE__ */ import_react20.default.createElement("polyline", { points: "21 16 21 21 16 21" }),
|
|
9005
|
+
/* @__PURE__ */ import_react20.default.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
|
|
9006
|
+
/* @__PURE__ */ import_react20.default.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
|
|
8783
9007
|
),
|
|
8784
|
-
/* @__PURE__ */
|
|
8785
|
-
), /* @__PURE__ */
|
|
9008
|
+
/* @__PURE__ */ import_react20.default.createElement("span", null, "Desconectar Target (", targetName, ")")
|
|
9009
|
+
), /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ import_react20.default.createElement(
|
|
8786
9010
|
"button",
|
|
8787
9011
|
{
|
|
8788
9012
|
onClick: () => onOpenDetails == null ? void 0 : onOpenDetails(data.linkObject),
|
|
8789
9013
|
className: baseButtonClass,
|
|
8790
9014
|
title: "Abrir detalhes da rela\xE7\xE3o"
|
|
8791
9015
|
},
|
|
8792
|
-
/* @__PURE__ */
|
|
9016
|
+
/* @__PURE__ */ import_react20.default.createElement(
|
|
8793
9017
|
"svg",
|
|
8794
9018
|
{
|
|
8795
9019
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8802,19 +9026,19 @@ function RelationshipContextMenu({
|
|
|
8802
9026
|
strokeLinecap: "round",
|
|
8803
9027
|
strokeLinejoin: "round"
|
|
8804
9028
|
},
|
|
8805
|
-
/* @__PURE__ */
|
|
8806
|
-
/* @__PURE__ */
|
|
8807
|
-
/* @__PURE__ */
|
|
9029
|
+
/* @__PURE__ */ import_react20.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
9030
|
+
/* @__PURE__ */ import_react20.default.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
9031
|
+
/* @__PURE__ */ import_react20.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
|
|
8808
9032
|
),
|
|
8809
|
-
/* @__PURE__ */
|
|
8810
|
-
), canDelete && /* @__PURE__ */
|
|
9033
|
+
/* @__PURE__ */ import_react20.default.createElement("span", null, "Abrir Detalhes")
|
|
9034
|
+
), canDelete && /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ import_react20.default.createElement(
|
|
8811
9035
|
"button",
|
|
8812
9036
|
{
|
|
8813
9037
|
onClick: () => setIsConfirmingDelete(true),
|
|
8814
9038
|
className: dangerButtonClass,
|
|
8815
9039
|
title: "Excluir esta conex\xE3o"
|
|
8816
9040
|
},
|
|
8817
|
-
/* @__PURE__ */
|
|
9041
|
+
/* @__PURE__ */ import_react20.default.createElement(
|
|
8818
9042
|
"svg",
|
|
8819
9043
|
{
|
|
8820
9044
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8827,19 +9051,19 @@ function RelationshipContextMenu({
|
|
|
8827
9051
|
strokeLinecap: "round",
|
|
8828
9052
|
strokeLinejoin: "round"
|
|
8829
9053
|
},
|
|
8830
|
-
/* @__PURE__ */
|
|
8831
|
-
/* @__PURE__ */
|
|
8832
|
-
/* @__PURE__ */
|
|
8833
|
-
/* @__PURE__ */
|
|
8834
|
-
/* @__PURE__ */
|
|
9054
|
+
/* @__PURE__ */ import_react20.default.createElement("polyline", { points: "3 6 5 6 21 6" }),
|
|
9055
|
+
/* @__PURE__ */ import_react20.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
|
|
9056
|
+
/* @__PURE__ */ import_react20.default.createElement("path", { d: "M10 11v6" }),
|
|
9057
|
+
/* @__PURE__ */ import_react20.default.createElement("path", { d: "M14 11v6" }),
|
|
9058
|
+
/* @__PURE__ */ import_react20.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
|
|
8835
9059
|
),
|
|
8836
|
-
/* @__PURE__ */
|
|
9060
|
+
/* @__PURE__ */ import_react20.default.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
|
|
8837
9061
|
)))))
|
|
8838
9062
|
);
|
|
8839
9063
|
}
|
|
8840
9064
|
|
|
8841
9065
|
// src/components/LoadingScreen.jsx
|
|
8842
|
-
var
|
|
9066
|
+
var import_react21 = __toESM(require("react"));
|
|
8843
9067
|
var styles = {
|
|
8844
9068
|
loadingOverlay: {
|
|
8845
9069
|
position: "fixed",
|
|
@@ -8871,11 +9095,11 @@ var styles = {
|
|
|
8871
9095
|
`
|
|
8872
9096
|
};
|
|
8873
9097
|
function LoadingScreen() {
|
|
8874
|
-
return /* @__PURE__ */
|
|
9098
|
+
return /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("style", null, styles.keyframes), /* @__PURE__ */ import_react21.default.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ import_react21.default.createElement("div", { style: styles.spinner })));
|
|
8875
9099
|
}
|
|
8876
9100
|
|
|
8877
9101
|
// src/components/ImportParentFileModal.jsx
|
|
8878
|
-
var
|
|
9102
|
+
var import_react22 = __toESM(require("react"));
|
|
8879
9103
|
function ImportParentFileModal({
|
|
8880
9104
|
isOpen,
|
|
8881
9105
|
onClose,
|
|
@@ -8886,12 +9110,12 @@ function ImportParentFileModal({
|
|
|
8886
9110
|
onFetchAvailableFiles,
|
|
8887
9111
|
currentViewName
|
|
8888
9112
|
}) {
|
|
8889
|
-
const [activeTab, setActiveTab] = (0,
|
|
8890
|
-
const [availableDbs, setAvailableDbs] = (0,
|
|
8891
|
-
const [availableViews, setAvailableViews] = (0,
|
|
8892
|
-
const [selectedItem, setSelectedItem] = (0,
|
|
8893
|
-
const [isLoading, setIsLoading] = (0,
|
|
8894
|
-
(0,
|
|
9113
|
+
const [activeTab, setActiveTab] = (0, import_react22.useState)("databases");
|
|
9114
|
+
const [availableDbs, setAvailableDbs] = (0, import_react22.useState)([]);
|
|
9115
|
+
const [availableViews, setAvailableViews] = (0, import_react22.useState)([]);
|
|
9116
|
+
const [selectedItem, setSelectedItem] = (0, import_react22.useState)(null);
|
|
9117
|
+
const [isLoading, setIsLoading] = (0, import_react22.useState)(false);
|
|
9118
|
+
(0, import_react22.useEffect)(() => {
|
|
8895
9119
|
if (isOpen && session && onFetchAvailableFiles) {
|
|
8896
9120
|
const fetchData = async () => {
|
|
8897
9121
|
setIsLoading(true);
|
|
@@ -8927,7 +9151,7 @@ function ImportParentFileModal({
|
|
|
8927
9151
|
fetchData();
|
|
8928
9152
|
}
|
|
8929
9153
|
}, [isOpen, session, parentDbs, onFetchAvailableFiles, currentViewName]);
|
|
8930
|
-
(0,
|
|
9154
|
+
(0, import_react22.useEffect)(() => {
|
|
8931
9155
|
setSelectedItem(null);
|
|
8932
9156
|
}, [activeTab]);
|
|
8933
9157
|
if (!isOpen) {
|
|
@@ -8956,13 +9180,13 @@ function ImportParentFileModal({
|
|
|
8956
9180
|
const swallow = (e) => e.stopPropagation();
|
|
8957
9181
|
const currentList = activeTab === "databases" ? availableDbs : availableViews;
|
|
8958
9182
|
const emptyMessage = activeTab === "databases" ? "Nenhum novo arquivo parent dispon\xEDvel." : "Nenhuma view dispon\xEDvel para importa\xE7\xE3o.";
|
|
8959
|
-
return /* @__PURE__ */
|
|
9183
|
+
return /* @__PURE__ */ import_react22.default.createElement(
|
|
8960
9184
|
"div",
|
|
8961
9185
|
{
|
|
8962
9186
|
className: "ui-overlay fixed inset-0 z-[1200] flex items-center justify-center bg-black/60 backdrop-blur-sm",
|
|
8963
9187
|
onClick: onClose
|
|
8964
9188
|
},
|
|
8965
|
-
/* @__PURE__ */
|
|
9189
|
+
/* @__PURE__ */ import_react22.default.createElement(
|
|
8966
9190
|
"div",
|
|
8967
9191
|
{
|
|
8968
9192
|
className: "ui-overlay relative rounded-2xl border border-white/10 bg-slate-950/80 shadow-[0_20px_80px_rgba(0,0,0,0.6)] text-white w-[min(92vw,500px)] flex flex-col max-h-[85vh]",
|
|
@@ -8974,14 +9198,14 @@ function ImportParentFileModal({
|
|
|
8974
9198
|
onContextMenu: swallow,
|
|
8975
9199
|
onDoubleClick: swallow
|
|
8976
9200
|
},
|
|
8977
|
-
/* @__PURE__ */
|
|
9201
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ import_react22.default.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ import_react22.default.createElement(
|
|
8978
9202
|
"button",
|
|
8979
9203
|
{
|
|
8980
9204
|
onClick: onClose,
|
|
8981
9205
|
className: "p-2 rounded-md text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8982
9206
|
title: "Fechar"
|
|
8983
9207
|
},
|
|
8984
|
-
/* @__PURE__ */
|
|
9208
|
+
/* @__PURE__ */ import_react22.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react22.default.createElement(
|
|
8985
9209
|
"path",
|
|
8986
9210
|
{
|
|
8987
9211
|
fillRule: "evenodd",
|
|
@@ -8990,14 +9214,14 @@ function ImportParentFileModal({
|
|
|
8990
9214
|
}
|
|
8991
9215
|
))
|
|
8992
9216
|
)),
|
|
8993
|
-
/* @__PURE__ */
|
|
9217
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ import_react22.default.createElement(
|
|
8994
9218
|
"button",
|
|
8995
9219
|
{
|
|
8996
9220
|
onClick: () => setActiveTab("databases"),
|
|
8997
9221
|
className: `flex-1 py-3 text-sm font-medium border-b-2 transition-colors ${activeTab === "databases" ? "border-indigo-500 text-white" : "border-transparent text-slate-400 hover:text-slate-200"}`
|
|
8998
9222
|
},
|
|
8999
9223
|
"Arquivos Parent"
|
|
9000
|
-
), /* @__PURE__ */
|
|
9224
|
+
), /* @__PURE__ */ import_react22.default.createElement(
|
|
9001
9225
|
"button",
|
|
9002
9226
|
{
|
|
9003
9227
|
onClick: () => setActiveTab("views"),
|
|
@@ -9005,24 +9229,24 @@ function ImportParentFileModal({
|
|
|
9005
9229
|
},
|
|
9006
9230
|
"Views (Ancestralidades)"
|
|
9007
9231
|
)),
|
|
9008
|
-
/* @__PURE__ */
|
|
9232
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ import_react22.default.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ import_react22.default.createElement(
|
|
9009
9233
|
"div",
|
|
9010
9234
|
{
|
|
9011
9235
|
key: item.id,
|
|
9012
9236
|
onClick: () => setSelectedItem(item),
|
|
9013
9237
|
className: `px-4 py-3 rounded-lg border cursor-pointer transition-all duration-150 flex flex-col gap-1 ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "bg-indigo-600 border-indigo-500 shadow-lg" : "bg-slate-800/60 border-white/10 hover:border-white/20 hover:bg-slate-800"}`
|
|
9014
9238
|
},
|
|
9015
|
-
/* @__PURE__ */
|
|
9016
|
-
item.description && /* @__PURE__ */
|
|
9017
|
-
)) : /* @__PURE__ */
|
|
9018
|
-
/* @__PURE__ */
|
|
9239
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react22.default.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ import_react22.default.createElement("span", { className: "text-[10px] px-1.5 py-0.5 rounded bg-black/30 text-indigo-300 border border-indigo-500/30" }, "VIEW")),
|
|
9240
|
+
item.description && /* @__PURE__ */ import_react22.default.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
|
|
9241
|
+
)) : /* @__PURE__ */ import_react22.default.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
|
|
9242
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: "px-6 py-4 border-t border-white/10 flex justify-end gap-3 flex-shrink-0 bg-slate-900/50" }, /* @__PURE__ */ import_react22.default.createElement(
|
|
9019
9243
|
"button",
|
|
9020
9244
|
{
|
|
9021
9245
|
onClick: onClose,
|
|
9022
9246
|
className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm text-slate-300"
|
|
9023
9247
|
},
|
|
9024
9248
|
"Cancelar"
|
|
9025
|
-
), /* @__PURE__ */
|
|
9249
|
+
), /* @__PURE__ */ import_react22.default.createElement(
|
|
9026
9250
|
"button",
|
|
9027
9251
|
{
|
|
9028
9252
|
onClick: handleConfirm,
|
|
@@ -9036,8 +9260,8 @@ function ImportParentFileModal({
|
|
|
9036
9260
|
}
|
|
9037
9261
|
|
|
9038
9262
|
// src/components/AncestryLinkDetailsPanel.jsx
|
|
9039
|
-
var
|
|
9040
|
-
var
|
|
9263
|
+
var import_react23 = __toESM(require("react"));
|
|
9264
|
+
var import_fi17 = require("react-icons/fi");
|
|
9041
9265
|
function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
|
|
9042
9266
|
var _a, _b, _c, _d;
|
|
9043
9267
|
const relationshipData = data.relationship || {};
|
|
@@ -9046,21 +9270,21 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9046
9270
|
const customProps = extractCustomPropsFromNode(relationshipData);
|
|
9047
9271
|
const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
|
|
9048
9272
|
const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
|
|
9049
|
-
const [isReadMode, setIsReadMode] = (0,
|
|
9273
|
+
const [isReadMode, setIsReadMode] = (0, import_react23.useState)(false);
|
|
9050
9274
|
const swallow = (e) => e.stopPropagation();
|
|
9051
9275
|
const handleImageClickFromText = (url, name) => {
|
|
9052
9276
|
if (onOpenImageViewer) {
|
|
9053
9277
|
onOpenImageViewer([{ name: name || "Imagem", value: url }], 0);
|
|
9054
9278
|
}
|
|
9055
9279
|
};
|
|
9056
|
-
return /* @__PURE__ */
|
|
9280
|
+
return /* @__PURE__ */ import_react23.default.createElement(
|
|
9057
9281
|
"div",
|
|
9058
9282
|
{
|
|
9059
9283
|
className: "ui-overlay fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[1200]",
|
|
9060
9284
|
onClick: onClose,
|
|
9061
9285
|
onPointerDown: swallow
|
|
9062
9286
|
},
|
|
9063
|
-
/* @__PURE__ */
|
|
9287
|
+
/* @__PURE__ */ import_react23.default.createElement(
|
|
9064
9288
|
"div",
|
|
9065
9289
|
{
|
|
9066
9290
|
className: `relative group rounded-2xl border border-white/10 bg-slate-950/80 shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col max-h-[calc(100vh-4rem)] transition-all duration-300 ease-out
|
|
@@ -9068,7 +9292,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9068
9292
|
`,
|
|
9069
9293
|
onClick: swallow
|
|
9070
9294
|
},
|
|
9071
|
-
isReadMode ? /* @__PURE__ */
|
|
9295
|
+
isReadMode ? /* @__PURE__ */ import_react23.default.createElement(
|
|
9072
9296
|
DescriptionReadModePanel,
|
|
9073
9297
|
{
|
|
9074
9298
|
title: `${sourceName} \u2794 ${targetName}`,
|
|
@@ -9080,15 +9304,15 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9080
9304
|
onMentionClick,
|
|
9081
9305
|
onImageClick: handleImageClickFromText
|
|
9082
9306
|
}
|
|
9083
|
-
) : /* @__PURE__ */
|
|
9307
|
+
) : /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ import_react23.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react23.default.createElement("div", null, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react23.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-blue-500/80 shadow-[0_0_18px_2px_rgba(59,130,246,0.55)]" }), /* @__PURE__ */ import_react23.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ import_react23.default.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ import_react23.default.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ import_react23.default.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ import_react23.default.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ import_react23.default.createElement("button", { onClick: onClose, 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", title: "Fechar" }, "\xD7")), /* @__PURE__ */ import_react23.default.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ import_react23.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react23.default.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react23.default.createElement(
|
|
9084
9308
|
"button",
|
|
9085
9309
|
{
|
|
9086
9310
|
onClick: () => setIsReadMode(true),
|
|
9087
9311
|
className: "p-1 text-slate-400 hover:text-white transition-colors",
|
|
9088
9312
|
title: "Modo de Leitura"
|
|
9089
9313
|
},
|
|
9090
|
-
/* @__PURE__ */
|
|
9091
|
-
)), /* @__PURE__ */
|
|
9314
|
+
/* @__PURE__ */ import_react23.default.createElement(import_fi17.FiBookOpen, { size: 14 })
|
|
9315
|
+
)), /* @__PURE__ */ import_react23.default.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ import_react23.default.createElement(
|
|
9092
9316
|
DescriptionDisplay,
|
|
9093
9317
|
{
|
|
9094
9318
|
description,
|
|
@@ -9097,7 +9321,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9097
9321
|
onMentionClick,
|
|
9098
9322
|
onImageClick: handleImageClickFromText
|
|
9099
9323
|
}
|
|
9100
|
-
))), customProps.length > 0 && /* @__PURE__ */
|
|
9324
|
+
))), customProps.length > 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react23.default.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ import_react23.default.createElement(
|
|
9101
9325
|
CustomPropertyDisplay,
|
|
9102
9326
|
{
|
|
9103
9327
|
key: prop.id,
|
|
@@ -9106,14 +9330,14 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9106
9330
|
onOpenImageViewer,
|
|
9107
9331
|
onUploadFile
|
|
9108
9332
|
}
|
|
9109
|
-
)))), !description && customProps.length === 0 && /* @__PURE__ */
|
|
9333
|
+
)))), !description && customProps.length === 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "py-8 text-center text-slate-500 text-sm italic border border-dashed border-white/10 rounded-lg" }, "Nenhum detalhe adicional dispon\xEDvel para esta conex\xE3o."), /* @__PURE__ */ import_react23.default.createElement("div", { className: "mt-4 p-3 bg-blue-500/10 border border-blue-500/20 rounded-lg text-xs text-blue-200/80 text-center" }, 'Para editar esta conex\xE3o, utilize o menu "Editar Ancestralidade".')))
|
|
9110
9334
|
)
|
|
9111
9335
|
);
|
|
9112
9336
|
}
|
|
9113
9337
|
|
|
9114
9338
|
// src/components/AncestryBoard.jsx
|
|
9115
|
-
var
|
|
9116
|
-
var
|
|
9339
|
+
var import_react24 = __toESM(require("react"));
|
|
9340
|
+
var import_fi18 = require("react-icons/fi");
|
|
9117
9341
|
var GroupItem = ({
|
|
9118
9342
|
group,
|
|
9119
9343
|
index,
|
|
@@ -9133,7 +9357,7 @@ var GroupItem = ({
|
|
|
9133
9357
|
}) => {
|
|
9134
9358
|
const canIndent = index > 0;
|
|
9135
9359
|
const isPickingForThisGroup = pickingGroupId === group.id;
|
|
9136
|
-
const textareaRef = (0,
|
|
9360
|
+
const textareaRef = (0, import_react24.useRef)(null);
|
|
9137
9361
|
const adjustHeight = () => {
|
|
9138
9362
|
const textarea = textareaRef.current;
|
|
9139
9363
|
if (textarea) {
|
|
@@ -9141,13 +9365,13 @@ var GroupItem = ({
|
|
|
9141
9365
|
textarea.style.height = `${textarea.scrollHeight}px`;
|
|
9142
9366
|
}
|
|
9143
9367
|
};
|
|
9144
|
-
(0,
|
|
9368
|
+
(0, import_react24.useEffect)(() => {
|
|
9145
9369
|
adjustHeight();
|
|
9146
9370
|
}, [group.text]);
|
|
9147
|
-
return /* @__PURE__ */
|
|
9371
|
+
return /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-col gap-2 mb-3 pl-3 border-l border-white/10 relative group/item animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react24.default.createElement("div", { className: `
|
|
9148
9372
|
flex flex-col gap-2 py-2 px-3 transition-all duration-200
|
|
9149
9373
|
${isPickingForThisGroup ? "bg-indigo-500/10 border-l-2 border-indigo-500" : "hover:bg-white/5 border-l-2 border-transparent hover:border-white/20"}
|
|
9150
|
-
` }, /* @__PURE__ */
|
|
9374
|
+
` }, /* @__PURE__ */ import_react24.default.createElement(
|
|
9151
9375
|
"textarea",
|
|
9152
9376
|
{
|
|
9153
9377
|
ref: textareaRef,
|
|
@@ -9164,9 +9388,9 @@ var GroupItem = ({
|
|
|
9164
9388
|
if (canEdit) onUpdate(group.id, { ...group, text: e.target.value });
|
|
9165
9389
|
}
|
|
9166
9390
|
}
|
|
9167
|
-
), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */
|
|
9391
|
+
), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
|
|
9168
9392
|
const isValid = availableIds.has(String(anc.ancestry_id));
|
|
9169
|
-
return /* @__PURE__ */
|
|
9393
|
+
return /* @__PURE__ */ import_react24.default.createElement(
|
|
9170
9394
|
"div",
|
|
9171
9395
|
{
|
|
9172
9396
|
key: anc.ancestry_id,
|
|
@@ -9178,28 +9402,28 @@ var GroupItem = ({
|
|
|
9178
9402
|
},
|
|
9179
9403
|
isValid ? (
|
|
9180
9404
|
// [MANTIDO] Botão Play visível para todos
|
|
9181
|
-
/* @__PURE__ */
|
|
9405
|
+
/* @__PURE__ */ import_react24.default.createElement(
|
|
9182
9406
|
"button",
|
|
9183
9407
|
{
|
|
9184
9408
|
onClick: () => onPlayAncestry(anc.ancestry_id),
|
|
9185
9409
|
className: "text-indigo-400 hover:text-white hover:bg-indigo-500 p-1 rounded-full transition-colors",
|
|
9186
9410
|
title: "Renderizar no cen\xE1rio"
|
|
9187
9411
|
},
|
|
9188
|
-
/* @__PURE__ */
|
|
9412
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlay, { size: 10, className: "ml-0.5 fill-current" })
|
|
9189
9413
|
)
|
|
9190
|
-
) : /* @__PURE__ */
|
|
9191
|
-
/* @__PURE__ */
|
|
9192
|
-
canEdit && /* @__PURE__ */
|
|
9414
|
+
) : /* @__PURE__ */ import_react24.default.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiAlertTriangle, { size: 10 })),
|
|
9415
|
+
/* @__PURE__ */ import_react24.default.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
|
|
9416
|
+
canEdit && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ import_react24.default.createElement(
|
|
9193
9417
|
"button",
|
|
9194
9418
|
{
|
|
9195
9419
|
onClick: () => onRemoveAncestry(group.id, anc.ancestry_id),
|
|
9196
9420
|
className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
|
|
9197
9421
|
title: "Remover men\xE7\xE3o"
|
|
9198
9422
|
},
|
|
9199
|
-
/* @__PURE__ */
|
|
9423
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiX, { size: 12 })
|
|
9200
9424
|
))
|
|
9201
9425
|
);
|
|
9202
|
-
})), canEdit && /* @__PURE__ */
|
|
9426
|
+
})), canEdit && /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center justify-between pt-2 mt-1 border-t border-white/5 opacity-40 group-hover/item:opacity-100 transition-opacity" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react24.default.createElement(
|
|
9203
9427
|
"button",
|
|
9204
9428
|
{
|
|
9205
9429
|
onClick: () => onRequestPickAncestry(group.id),
|
|
@@ -9209,17 +9433,17 @@ var GroupItem = ({
|
|
|
9209
9433
|
`,
|
|
9210
9434
|
title: "Adicionar Ancestralidade a este grupo"
|
|
9211
9435
|
},
|
|
9212
|
-
isPickingForThisGroup ? /* @__PURE__ */
|
|
9436
|
+
isPickingForThisGroup ? /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiCheckCircle, { size: 12 }) : /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiSearch, { size: 12 }),
|
|
9213
9437
|
isPickingForThisGroup ? "Selecionando..." : "Adicionar"
|
|
9214
|
-
), /* @__PURE__ */
|
|
9438
|
+
), /* @__PURE__ */ import_react24.default.createElement(
|
|
9215
9439
|
"button",
|
|
9216
9440
|
{
|
|
9217
9441
|
onClick: () => onAddSubgroup(group.id),
|
|
9218
9442
|
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
9219
9443
|
title: "Criar Subgrupo"
|
|
9220
9444
|
},
|
|
9221
|
-
/* @__PURE__ */
|
|
9222
|
-
)), /* @__PURE__ */
|
|
9445
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 14 })
|
|
9446
|
+
)), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react24.default.createElement(
|
|
9223
9447
|
"button",
|
|
9224
9448
|
{
|
|
9225
9449
|
onClick: () => onIndent(group.id),
|
|
@@ -9227,24 +9451,24 @@ var GroupItem = ({
|
|
|
9227
9451
|
className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
|
|
9228
9452
|
title: "Aninhar no grupo acima"
|
|
9229
9453
|
},
|
|
9230
|
-
/* @__PURE__ */
|
|
9231
|
-
), /* @__PURE__ */
|
|
9454
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiArrowRight, { size: 14 })
|
|
9455
|
+
), /* @__PURE__ */ import_react24.default.createElement(
|
|
9232
9456
|
"button",
|
|
9233
9457
|
{
|
|
9234
9458
|
onClick: () => onOutdent(group.id),
|
|
9235
9459
|
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
9236
9460
|
title: "Desaninhar"
|
|
9237
9461
|
},
|
|
9238
|
-
/* @__PURE__ */
|
|
9239
|
-
), /* @__PURE__ */
|
|
9462
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiArrowLeft, { size: 14 })
|
|
9463
|
+
), /* @__PURE__ */ import_react24.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react24.default.createElement(
|
|
9240
9464
|
"button",
|
|
9241
9465
|
{
|
|
9242
9466
|
onClick: () => onDelete(group.id),
|
|
9243
9467
|
className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
|
|
9244
9468
|
title: "Remover Grupo"
|
|
9245
9469
|
},
|
|
9246
|
-
/* @__PURE__ */
|
|
9247
|
-
)))), group.children && group.children.length > 0 && /* @__PURE__ */
|
|
9470
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiTrash2, { size: 14 })
|
|
9471
|
+
)))), group.children && group.children.length > 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ import_react24.default.createElement(
|
|
9248
9472
|
GroupItem,
|
|
9249
9473
|
{
|
|
9250
9474
|
key: childGroup.id,
|
|
@@ -9276,21 +9500,21 @@ function AncestryBoard({
|
|
|
9276
9500
|
userRole
|
|
9277
9501
|
// [NOVO] Recebe a role do usuário
|
|
9278
9502
|
}) {
|
|
9279
|
-
const [searchTerm, setSearchTerm] = (0,
|
|
9280
|
-
const [groups, setGroups] = (0,
|
|
9281
|
-
const [isLoaded, setIsLoaded] = (0,
|
|
9282
|
-
const [pickingGroupId, setPickingGroupId] = (0,
|
|
9283
|
-
const [saveStatus, setSaveStatus] = (0,
|
|
9284
|
-
const canEdit = (0,
|
|
9503
|
+
const [searchTerm, setSearchTerm] = (0, import_react24.useState)("");
|
|
9504
|
+
const [groups, setGroups] = (0, import_react24.useState)([]);
|
|
9505
|
+
const [isLoaded, setIsLoaded] = (0, import_react24.useState)(false);
|
|
9506
|
+
const [pickingGroupId, setPickingGroupId] = (0, import_react24.useState)(null);
|
|
9507
|
+
const [saveStatus, setSaveStatus] = (0, import_react24.useState)("idle");
|
|
9508
|
+
const canEdit = (0, import_react24.useMemo)(() => {
|
|
9285
9509
|
return userRole !== "viewer";
|
|
9286
9510
|
}, [userRole]);
|
|
9287
|
-
(0,
|
|
9511
|
+
(0, import_react24.useEffect)(() => {
|
|
9288
9512
|
if (initialGroups && !isLoaded) {
|
|
9289
9513
|
setGroups(initialGroups);
|
|
9290
9514
|
setIsLoaded(true);
|
|
9291
9515
|
}
|
|
9292
9516
|
}, [initialGroups, isLoaded]);
|
|
9293
|
-
const nodeNamesMap = (0,
|
|
9517
|
+
const nodeNamesMap = (0, import_react24.useMemo)(() => {
|
|
9294
9518
|
const map = /* @__PURE__ */ new Map();
|
|
9295
9519
|
if (availableNodes && Array.isArray(availableNodes)) {
|
|
9296
9520
|
availableNodes.forEach((node) => {
|
|
@@ -9301,7 +9525,7 @@ function AncestryBoard({
|
|
|
9301
9525
|
}
|
|
9302
9526
|
return map;
|
|
9303
9527
|
}, [availableNodes]);
|
|
9304
|
-
const availableIds = (0,
|
|
9528
|
+
const availableIds = (0, import_react24.useMemo)(() => {
|
|
9305
9529
|
return new Set(availableAncestries.map((a) => String(a.ancestry_id)));
|
|
9306
9530
|
}, [availableAncestries]);
|
|
9307
9531
|
const sanitizeGroups = (groupList) => {
|
|
@@ -9315,7 +9539,7 @@ function AncestryBoard({
|
|
|
9315
9539
|
children: sanitizeGroups(g.children || [])
|
|
9316
9540
|
}));
|
|
9317
9541
|
};
|
|
9318
|
-
(0,
|
|
9542
|
+
(0, import_react24.useEffect)(() => {
|
|
9319
9543
|
if (!isLoaded || !onSave) return;
|
|
9320
9544
|
const timeoutId = setTimeout(async () => {
|
|
9321
9545
|
setSaveStatus("saving");
|
|
@@ -9333,7 +9557,7 @@ function AncestryBoard({
|
|
|
9333
9557
|
}, 3e3);
|
|
9334
9558
|
return () => clearTimeout(timeoutId);
|
|
9335
9559
|
}, [groups, isLoaded, onSave]);
|
|
9336
|
-
(0,
|
|
9560
|
+
(0, import_react24.useEffect)(() => {
|
|
9337
9561
|
if (!isOpen) return;
|
|
9338
9562
|
const handleKeyDown = (e) => {
|
|
9339
9563
|
if (e.key === "Escape") {
|
|
@@ -9349,7 +9573,7 @@ function AncestryBoard({
|
|
|
9349
9573
|
window.addEventListener("keydown", handleKeyDown);
|
|
9350
9574
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
9351
9575
|
}, [isOpen, onClose, pickingGroupId]);
|
|
9352
|
-
const filtered = (0,
|
|
9576
|
+
const filtered = (0, import_react24.useMemo)(() => {
|
|
9353
9577
|
const term = searchTerm.toLowerCase().trim();
|
|
9354
9578
|
return availableAncestries.filter((a) => {
|
|
9355
9579
|
if (!term) return true;
|
|
@@ -9488,27 +9712,27 @@ function AncestryBoard({
|
|
|
9488
9712
|
});
|
|
9489
9713
|
};
|
|
9490
9714
|
if (!isOpen) return null;
|
|
9491
|
-
return /* @__PURE__ */
|
|
9715
|
+
return /* @__PURE__ */ import_react24.default.createElement(
|
|
9492
9716
|
"div",
|
|
9493
9717
|
{
|
|
9494
9718
|
className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
|
|
9495
9719
|
onClick: onClose
|
|
9496
9720
|
},
|
|
9497
|
-
/* @__PURE__ */
|
|
9721
|
+
/* @__PURE__ */ import_react24.default.createElement(
|
|
9498
9722
|
"div",
|
|
9499
9723
|
{
|
|
9500
9724
|
className: "bg-slate-950 border border-white/10 rounded-xl w-[98vw] h-[97vh] flex flex-col shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-200",
|
|
9501
9725
|
onClick: (e) => e.stopPropagation()
|
|
9502
9726
|
},
|
|
9503
|
-
/* @__PURE__ */
|
|
9727
|
+
/* @__PURE__ */ import_react24.default.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react24.default.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLayers, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-slate-900/50 border border-white/5" }, saveStatus === "saving" && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLoader, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ import_react24.default.createElement(
|
|
9504
9728
|
"button",
|
|
9505
9729
|
{
|
|
9506
9730
|
onClick: handleAddRootGroup,
|
|
9507
9731
|
className: "\n flex items-center gap-2 px-3 py-1.5 \n bg-white/5 hover:bg-white/10 \n border border-white/10 hover:border-white/20\n backdrop-blur-sm\n text-slate-200 hover:text-white\n rounded-md transition-all duration-200\n text-xs font-medium shadow-sm\n "
|
|
9508
9732
|
},
|
|
9509
|
-
/* @__PURE__ */
|
|
9510
|
-
/* @__PURE__ */
|
|
9511
|
-
), /* @__PURE__ */
|
|
9733
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 14, className: "text-indigo-400" }),
|
|
9734
|
+
/* @__PURE__ */ import_react24.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
|
|
9735
|
+
), /* @__PURE__ */ import_react24.default.createElement(
|
|
9512
9736
|
"button",
|
|
9513
9737
|
{
|
|
9514
9738
|
onClick: onClose,
|
|
@@ -9516,11 +9740,11 @@ function AncestryBoard({
|
|
|
9516
9740
|
},
|
|
9517
9741
|
"\xD7"
|
|
9518
9742
|
))),
|
|
9519
|
-
/* @__PURE__ */
|
|
9743
|
+
/* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: `
|
|
9520
9744
|
flex flex-col border-r border-white/10 transition-all duration-300 flex-none
|
|
9521
9745
|
${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
|
|
9522
9746
|
min-w-[280px] max-w-[500px] bg-slate-900
|
|
9523
|
-
` }, /* @__PURE__ */
|
|
9747
|
+
` }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiSearch, { className: `absolute left-3 top-1/2 -translate-y-1/2 transition-colors ${pickingGroupId ? "text-indigo-400" : "text-slate-500 group-focus-within:text-indigo-400"}` }), /* @__PURE__ */ import_react24.default.createElement(
|
|
9524
9748
|
"input",
|
|
9525
9749
|
{
|
|
9526
9750
|
type: "text",
|
|
@@ -9533,10 +9757,10 @@ function AncestryBoard({
|
|
|
9533
9757
|
onChange: (e) => setSearchTerm(e.target.value),
|
|
9534
9758
|
autoFocus: !pickingGroupId
|
|
9535
9759
|
}
|
|
9536
|
-
))), /* @__PURE__ */
|
|
9760
|
+
))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
|
|
9537
9761
|
const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
|
|
9538
9762
|
const isPicking = !!pickingGroupId;
|
|
9539
|
-
return /* @__PURE__ */
|
|
9763
|
+
return /* @__PURE__ */ import_react24.default.createElement(
|
|
9540
9764
|
"div",
|
|
9541
9765
|
{
|
|
9542
9766
|
key: anc.ancestry_id,
|
|
@@ -9548,12 +9772,12 @@ function AncestryBoard({
|
|
|
9548
9772
|
${isPicking ? "border-indigo-500/30 bg-indigo-500/5 hover:bg-indigo-500/20 hover:border-indigo-400 cursor-pointer" : "border-white/5 bg-slate-800/40 hover:bg-indigo-600/10 hover:border-indigo-500/30 cursor-default"}
|
|
9549
9773
|
`
|
|
9550
9774
|
},
|
|
9551
|
-
/* @__PURE__ */
|
|
9775
|
+
/* @__PURE__ */ import_react24.default.createElement("div", { className: `
|
|
9552
9776
|
mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
|
|
9553
9777
|
${isPicking ? "bg-indigo-500 text-white border-indigo-400" : "bg-slate-800 text-indigo-400 border-white/5 group-hover:bg-indigo-500 group-hover:text-white"}
|
|
9554
|
-
` }, isPicking ? /* @__PURE__ */
|
|
9555
|
-
/* @__PURE__ */
|
|
9556
|
-
!isPicking && /* @__PURE__ */
|
|
9778
|
+
` }, isPicking ? /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 16 }) : /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLayers, { size: 14 })),
|
|
9779
|
+
/* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ import_react24.default.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.name || "Sem Nome"), anc.is_private && /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-300 border border-amber-500/20" }, "Priv")), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1.5 mt-0.5 text-[11px] text-slate-500 group-hover:text-indigo-200/70 transition-colors" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiCornerUpRight, { size: 10 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ import_react24.default.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
|
|
9780
|
+
!isPicking && /* @__PURE__ */ import_react24.default.createElement(
|
|
9557
9781
|
"button",
|
|
9558
9782
|
{
|
|
9559
9783
|
onClick: (e) => {
|
|
@@ -9563,10 +9787,10 @@ function AncestryBoard({
|
|
|
9563
9787
|
className: "absolute right-2 bottom-2 opacity-0 group-hover:opacity-100 transition-all duration-300 transform translate-y-2 group-hover:translate-y-0 z-10",
|
|
9564
9788
|
title: "Renderizar Ancestralidade"
|
|
9565
9789
|
},
|
|
9566
|
-
/* @__PURE__ */
|
|
9790
|
+
/* @__PURE__ */ import_react24.default.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlay, { size: 14, className: "ml-0.5" }))
|
|
9567
9791
|
)
|
|
9568
9792
|
);
|
|
9569
|
-
}))), /* @__PURE__ */
|
|
9793
|
+
}))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-3 border-2 border-dashed border-white/5 rounded-xl m-4 bg-slate-900/20" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLayers, { size: 24, className: "opacity-20" }), /* @__PURE__ */ import_react24.default.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ import_react24.default.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ import_react24.default.createElement(
|
|
9570
9794
|
GroupItem,
|
|
9571
9795
|
{
|
|
9572
9796
|
key: group.id,
|
|
@@ -9586,7 +9810,7 @@ function AncestryBoard({
|
|
|
9586
9810
|
canEdit
|
|
9587
9811
|
}
|
|
9588
9812
|
))))),
|
|
9589
|
-
/* @__PURE__ */
|
|
9813
|
+
/* @__PURE__ */ import_react24.default.createElement("div", { className: "px-5 py-2 border-t border-white/10 bg-slate-950/50 text-xs text-slate-500 flex justify-between flex-shrink-0" }, /* @__PURE__ */ import_react24.default.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ import_react24.default.createElement("span", null, groups.length, " grupos raiz"))
|
|
9590
9814
|
)
|
|
9591
9815
|
);
|
|
9592
9816
|
}
|
|
@@ -9666,12 +9890,12 @@ function XViewScene({
|
|
|
9666
9890
|
check_user_permission
|
|
9667
9891
|
}) {
|
|
9668
9892
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
9669
|
-
const { data: session, status } = (0,
|
|
9893
|
+
const { data: session, status } = (0, import_react26.useSession)();
|
|
9670
9894
|
const router = (0, import_navigation.useRouter)();
|
|
9671
9895
|
const searchParams = (0, import_navigation.useSearchParams)();
|
|
9672
9896
|
const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
|
|
9673
9897
|
const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
|
|
9674
|
-
const viewParams = (0,
|
|
9898
|
+
const viewParams = (0, import_react25.useMemo)(() => {
|
|
9675
9899
|
if (encryptedConfig) {
|
|
9676
9900
|
const data = decryptData(encryptedConfig);
|
|
9677
9901
|
if (data) {
|
|
@@ -9680,7 +9904,7 @@ function XViewScene({
|
|
|
9680
9904
|
}
|
|
9681
9905
|
return null;
|
|
9682
9906
|
}, [encryptedConfig, session]);
|
|
9683
|
-
(0,
|
|
9907
|
+
(0, import_react25.useEffect)(() => {
|
|
9684
9908
|
async function verifyPermission() {
|
|
9685
9909
|
if (!viewParams || !session || !check_user_permission) return;
|
|
9686
9910
|
const { id, type, owner_id } = viewParams;
|
|
@@ -9710,64 +9934,65 @@ function XViewScene({
|
|
|
9710
9934
|
setIsLoading(false);
|
|
9711
9935
|
}
|
|
9712
9936
|
}, [viewParams, session, status, check_user_permission]);
|
|
9713
|
-
const sceneConfigId = (0,
|
|
9714
|
-
const ownerId = (0,
|
|
9715
|
-
const dbSaveUrl = (0,
|
|
9937
|
+
const sceneConfigId = (0, import_react25.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
|
|
9938
|
+
const ownerId = (0, import_react25.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
|
|
9939
|
+
const dbSaveUrl = (0, import_react25.useMemo)(() => {
|
|
9716
9940
|
if (ownerId && sceneConfigId) {
|
|
9717
9941
|
return `x_view_dbs/${ownerId}/${sceneConfigId}`;
|
|
9718
9942
|
}
|
|
9719
9943
|
return null;
|
|
9720
9944
|
}, [ownerId, sceneConfigId]);
|
|
9721
|
-
const sceneSaveUrl = (0,
|
|
9945
|
+
const sceneSaveUrl = (0, import_react25.useMemo)(() => {
|
|
9722
9946
|
if (ownerId && sceneConfigId) {
|
|
9723
9947
|
return `x_view_scenes/${ownerId}/${sceneConfigId}`;
|
|
9724
9948
|
}
|
|
9725
9949
|
return null;
|
|
9726
9950
|
}, [ownerId, sceneConfigId]);
|
|
9727
|
-
const ancestry_save_url = (0,
|
|
9951
|
+
const ancestry_save_url = (0, import_react25.useMemo)(() => {
|
|
9728
9952
|
if (ownerId && sceneConfigId) {
|
|
9729
9953
|
return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
|
|
9730
9954
|
}
|
|
9731
9955
|
return null;
|
|
9732
9956
|
}, [ownerId, sceneConfigId]);
|
|
9733
|
-
const sceneDataRef = (0,
|
|
9734
|
-
const parentDataRef = (0,
|
|
9735
|
-
const ancestryDataRef = (0,
|
|
9736
|
-
const [isLoading, setIsLoading] = (0,
|
|
9737
|
-
const [permissionStatus, setPermissionStatus] = (0,
|
|
9738
|
-
const [userPermissionRole, setUserPermissionRole] = (0,
|
|
9739
|
-
const [isInitialized, setIsInitialized] = (0,
|
|
9740
|
-
const [sceneVersion, setSceneVersion] = (0,
|
|
9741
|
-
const [contextMenu, setContextMenu] = (0,
|
|
9742
|
-
const [multiContextMenu, setMultiContextMenu] = (0,
|
|
9743
|
-
const [relationshipMenu, setRelationshipMenu] = (0,
|
|
9744
|
-
const [creationMode, setCreationMode] = (0,
|
|
9745
|
-
const [versionMode, setVersionMode] = (0,
|
|
9746
|
-
const [
|
|
9747
|
-
const [
|
|
9748
|
-
const [
|
|
9749
|
-
const [
|
|
9957
|
+
const sceneDataRef = (0, import_react25.useRef)(null);
|
|
9958
|
+
const parentDataRef = (0, import_react25.useRef)(null);
|
|
9959
|
+
const ancestryDataRef = (0, import_react25.useRef)(null);
|
|
9960
|
+
const [isLoading, setIsLoading] = (0, import_react25.useState)(true);
|
|
9961
|
+
const [permissionStatus, setPermissionStatus] = (0, import_react25.useState)("loading");
|
|
9962
|
+
const [userPermissionRole, setUserPermissionRole] = (0, import_react25.useState)(null);
|
|
9963
|
+
const [isInitialized, setIsInitialized] = (0, import_react25.useState)(false);
|
|
9964
|
+
const [sceneVersion, setSceneVersion] = (0, import_react25.useState)(0);
|
|
9965
|
+
const [contextMenu, setContextMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, nodeData: null });
|
|
9966
|
+
const [multiContextMenu, setMultiContextMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, nodeIds: null });
|
|
9967
|
+
const [relationshipMenu, setRelationshipMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, linkObject: null });
|
|
9968
|
+
const [creationMode, setCreationMode] = (0, import_react25.useState)({ isActive: false, sourceNodeData: null });
|
|
9969
|
+
const [versionMode, setVersionMode] = (0, import_react25.useState)({ isActive: false, sourceNodeData: null });
|
|
9970
|
+
const [questMode, setQuestMode] = (0, import_react25.useState)({ isActive: false });
|
|
9971
|
+
const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react25.useState)(false);
|
|
9972
|
+
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react25.useState)(false);
|
|
9973
|
+
const [ancestryMode, setAncestryMode] = (0, import_react25.useState)({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
9974
|
+
const [readingMode, setReadingMode] = (0, import_react25.useState)({
|
|
9750
9975
|
isActive: false,
|
|
9751
9976
|
ancestry: null,
|
|
9752
9977
|
branchStack: [],
|
|
9753
9978
|
autoAbstraction: false
|
|
9754
9979
|
});
|
|
9755
|
-
const [formPosition, setFormPosition] = (0,
|
|
9756
|
-
const [detailsNode, setDetailsNode] = (0,
|
|
9757
|
-
const [detailsLink, setDetailsLink] = (0,
|
|
9758
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] = (0,
|
|
9759
|
-
const [imageViewer, setImageViewer] = (0,
|
|
9760
|
-
const [editingAncestryRel, setEditingAncestryRel] = (0,
|
|
9761
|
-
const [isImportModalOpen, setIsImportModalOpen] = (0,
|
|
9762
|
-
const [importSuccessMessage, setImportSuccessMessage] = (0,
|
|
9763
|
-
const [highlightedNodeId, setHighlightedNodeId] = (0,
|
|
9764
|
-
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0,
|
|
9765
|
-
const [ancestryBoardData, setAncestryBoardData] = (0,
|
|
9766
|
-
const [isSidebarOpen, setIsSidebarOpen] = (0,
|
|
9767
|
-
const mountRef = (0,
|
|
9768
|
-
const tooltipRef = (0,
|
|
9769
|
-
const formRef = (0,
|
|
9770
|
-
const stateRef = (0,
|
|
9980
|
+
const [formPosition, setFormPosition] = (0, import_react25.useState)({ left: 16, top: 16, opacity: 0 });
|
|
9981
|
+
const [detailsNode, setDetailsNode] = (0, import_react25.useState)(null);
|
|
9982
|
+
const [detailsLink, setDetailsLink] = (0, import_react25.useState)(null);
|
|
9983
|
+
const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react25.useState)(null);
|
|
9984
|
+
const [imageViewer, setImageViewer] = (0, import_react25.useState)({ visible: false, images: [], startIndex: 0 });
|
|
9985
|
+
const [editingAncestryRel, setEditingAncestryRel] = (0, import_react25.useState)({ visible: false, data: null, path: null });
|
|
9986
|
+
const [isImportModalOpen, setIsImportModalOpen] = (0, import_react25.useState)(false);
|
|
9987
|
+
const [importSuccessMessage, setImportSuccessMessage] = (0, import_react25.useState)("");
|
|
9988
|
+
const [highlightedNodeId, setHighlightedNodeId] = (0, import_react25.useState)(null);
|
|
9989
|
+
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react25.useState)(false);
|
|
9990
|
+
const [ancestryBoardData, setAncestryBoardData] = (0, import_react25.useState)([]);
|
|
9991
|
+
const [isSidebarOpen, setIsSidebarOpen] = (0, import_react25.useState)(false);
|
|
9992
|
+
const mountRef = (0, import_react25.useRef)(null);
|
|
9993
|
+
const tooltipRef = (0, import_react25.useRef)(null);
|
|
9994
|
+
const formRef = (0, import_react25.useRef)(null);
|
|
9995
|
+
const stateRef = (0, import_react25.useRef)({
|
|
9771
9996
|
readMode: {
|
|
9772
9997
|
currentMaxIndex: 0,
|
|
9773
9998
|
progressMap: {}
|
|
@@ -9812,10 +10037,10 @@ function XViewScene({
|
|
|
9812
10037
|
minWidth: 320,
|
|
9813
10038
|
maxWidth: maxReadPanelW
|
|
9814
10039
|
});
|
|
9815
|
-
(0,
|
|
10040
|
+
(0, import_react25.useEffect)(() => {
|
|
9816
10041
|
stateRef.current.ancestry = ancestryMode;
|
|
9817
10042
|
}, [ancestryMode]);
|
|
9818
|
-
(0,
|
|
10043
|
+
(0, import_react25.useEffect)(() => {
|
|
9819
10044
|
var _a2;
|
|
9820
10045
|
if (!isInitialized) return;
|
|
9821
10046
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -9836,10 +10061,10 @@ function XViewScene({
|
|
|
9836
10061
|
}
|
|
9837
10062
|
stateRef.current.nodeIdToParentFileMap = map;
|
|
9838
10063
|
}, [isInitialized, sceneVersion]);
|
|
9839
|
-
const handleNavigateBack = (0,
|
|
10064
|
+
const handleNavigateBack = (0, import_react25.useCallback)(() => {
|
|
9840
10065
|
router.push("/dashboard/scenes");
|
|
9841
10066
|
}, [router]);
|
|
9842
|
-
const handleConfirmImport = (0,
|
|
10067
|
+
const handleConfirmImport = (0, import_react25.useCallback)(
|
|
9843
10068
|
async (importPayload) => {
|
|
9844
10069
|
var _a2, _b2;
|
|
9845
10070
|
let files = [];
|
|
@@ -9937,7 +10162,7 @@ function XViewScene({
|
|
|
9937
10162
|
const handleOpenImageViewer = (images, startIndex) => {
|
|
9938
10163
|
setImageViewer({ visible: true, images, startIndex });
|
|
9939
10164
|
};
|
|
9940
|
-
const tweenToTarget = (0,
|
|
10165
|
+
const tweenToTarget = (0, import_react25.useCallback)((target, zoomFactor = 1, forcedDirection = null) => {
|
|
9941
10166
|
const { camera, controls, tweenGroup } = stateRef.current;
|
|
9942
10167
|
if (!camera || !controls || !tweenGroup) return;
|
|
9943
10168
|
const targetPos = target instanceof THREE3.Mesh ? target.getWorldPosition(new THREE3.Vector3()) : target;
|
|
@@ -9960,7 +10185,7 @@ function XViewScene({
|
|
|
9960
10185
|
if (!t || typeof t.closest !== "function") return false;
|
|
9961
10186
|
return !!t.closest(".ui-overlay");
|
|
9962
10187
|
};
|
|
9963
|
-
const buildFullAncestryTree = (0,
|
|
10188
|
+
const buildFullAncestryTree = (0, import_react25.useCallback)((idTree, nodes, ancestries = []) => {
|
|
9964
10189
|
if (!idTree) return null;
|
|
9965
10190
|
const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
|
|
9966
10191
|
const ancestryMap = new Map(ancestries.map((a) => [String(a.ancestry_id), a]));
|
|
@@ -10036,7 +10261,7 @@ function XViewScene({
|
|
|
10036
10261
|
}
|
|
10037
10262
|
return recursiveBuild(idTree);
|
|
10038
10263
|
}, []);
|
|
10039
|
-
const handleActivateTimeline = (0,
|
|
10264
|
+
const handleActivateTimeline = (0, import_react25.useCallback)(() => {
|
|
10040
10265
|
const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
10041
10266
|
if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
|
|
10042
10267
|
while (timelineIntervalsGroup.children.length > 0) {
|
|
@@ -10189,7 +10414,7 @@ function XViewScene({
|
|
|
10189
10414
|
}
|
|
10190
10415
|
});
|
|
10191
10416
|
}, []);
|
|
10192
|
-
const handleVersionTimeline = (0,
|
|
10417
|
+
const handleVersionTimeline = (0, import_react25.useCallback)((sourceMesh, versionMeshes) => {
|
|
10193
10418
|
const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
10194
10419
|
if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0) return;
|
|
10195
10420
|
versionMeshes.forEach((mesh) => {
|
|
@@ -10312,7 +10537,7 @@ function XViewScene({
|
|
|
10312
10537
|
}
|
|
10313
10538
|
});
|
|
10314
10539
|
}, []);
|
|
10315
|
-
(0,
|
|
10540
|
+
(0, import_react25.useEffect)(() => {
|
|
10316
10541
|
async function fetchAllData(configPath, ownerId2) {
|
|
10317
10542
|
var _a2, _b2;
|
|
10318
10543
|
if (!get_scene_view_data) {
|
|
@@ -10384,12 +10609,12 @@ function XViewScene({
|
|
|
10384
10609
|
focusNodeId,
|
|
10385
10610
|
focusAncestryId
|
|
10386
10611
|
]);
|
|
10387
|
-
const isNodeInView = (0,
|
|
10612
|
+
const isNodeInView = (0, import_react25.useCallback)((id) => {
|
|
10388
10613
|
const key = String(id);
|
|
10389
10614
|
const objs = stateRef.current.nodeObjects || {};
|
|
10390
10615
|
return !!objs[key];
|
|
10391
10616
|
}, []);
|
|
10392
|
-
const addOrUpdateNodeMesh = (0,
|
|
10617
|
+
const addOrUpdateNodeMesh = (0, import_react25.useCallback)((nodeData, position, suppressVersionUpdate = false) => {
|
|
10393
10618
|
const { graphGroup, nodeObjects, clickableNodes, glowTexture, tweenGroup } = stateRef.current;
|
|
10394
10619
|
const nodeId = String(nodeData.id);
|
|
10395
10620
|
if (nodeObjects[nodeId]) {
|
|
@@ -10416,7 +10641,7 @@ function XViewScene({
|
|
|
10416
10641
|
}
|
|
10417
10642
|
return mesh;
|
|
10418
10643
|
}, []);
|
|
10419
|
-
(0,
|
|
10644
|
+
(0, import_react25.useEffect)(() => {
|
|
10420
10645
|
if (!isInitialized || !sceneDataRef.current) return;
|
|
10421
10646
|
const currentMount = mountRef.current;
|
|
10422
10647
|
if (!currentMount) return;
|
|
@@ -10809,12 +11034,15 @@ function XViewScene({
|
|
|
10809
11034
|
if (mountRef.current) mountRef.current.style.cursor = "grab";
|
|
10810
11035
|
}
|
|
10811
11036
|
function handleKeyDown(event) {
|
|
11037
|
+
var _a2, _b2, _c2, _d2;
|
|
10812
11038
|
const context = actionHandlerContext;
|
|
10813
11039
|
if (event.key === "Escape") {
|
|
10814
11040
|
if (stateRef.current.connection.isActive) userActionHandlers.handleCancelConnection(context);
|
|
10815
11041
|
if (stateRef.current.relink.isActive) userActionHandlers.handleCancelRelink(context);
|
|
10816
11042
|
if (stateRef.current.creation.isActive) userActionHandlers.handleCancelCreation(context);
|
|
11043
|
+
if ((_a2 = stateRef.current.versionMode) == null ? void 0 : _a2.isActive) userActionHandlers.handleCancelVersioning(context);
|
|
10817
11044
|
if (stateRef.current.ancestry.isActive) handleCancelAncestryCreation();
|
|
11045
|
+
if ((_b2 = context.questMode) == null ? void 0 : _b2.isActive) context.setters.setQuestMode({ isActive: false });
|
|
10818
11046
|
if (stateRef.current.selectedNodes.size > 0) {
|
|
10819
11047
|
stateRef.current.selectedNodes.clear();
|
|
10820
11048
|
}
|
|
@@ -10822,6 +11050,17 @@ function XViewScene({
|
|
|
10822
11050
|
setMultiContextMenu((prev) => ({ ...prev, visible: false }));
|
|
10823
11051
|
setRelationshipMenu((prev) => ({ ...prev, visible: false }));
|
|
10824
11052
|
}
|
|
11053
|
+
if (event.key.toLowerCase() === "q") {
|
|
11054
|
+
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;
|
|
11055
|
+
if (isUiClear) {
|
|
11056
|
+
const isView = ((_d2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _d2.toLowerCase()) === "view";
|
|
11057
|
+
if (!isView) {
|
|
11058
|
+
alert("Nodes de Quest s\xF3 podem ser criados dentro de uma View.");
|
|
11059
|
+
return;
|
|
11060
|
+
}
|
|
11061
|
+
setQuestMode({ isActive: true });
|
|
11062
|
+
}
|
|
11063
|
+
}
|
|
10825
11064
|
}
|
|
10826
11065
|
function handleDoubleClick(event) {
|
|
10827
11066
|
if (stateRef.current.camera) stateRef.current.camera.layers.enableAll();
|
|
@@ -10980,9 +11219,7 @@ function XViewScene({
|
|
|
10980
11219
|
mountEl: currentMount,
|
|
10981
11220
|
isSceneBusy: stateRef.current.isDragging || creation.isActive || connection.isActive || relink.isActive || ancestryMode.isActive,
|
|
10982
11221
|
parentData: parentDataRef.current,
|
|
10983
|
-
// <--- ADICIONADO AQUI
|
|
10984
11222
|
ancestryData: ancestryDataRef.current
|
|
10985
|
-
// <--- ADICIONADO AQUI
|
|
10986
11223
|
});
|
|
10987
11224
|
(_b2 = stateRef.current.tweenGroup) == null ? void 0 : _b2.update(time);
|
|
10988
11225
|
stateRef.current.controls.update();
|
|
@@ -11049,7 +11286,7 @@ function XViewScene({
|
|
|
11049
11286
|
}
|
|
11050
11287
|
};
|
|
11051
11288
|
}, [isInitialized, tweenToTarget, dbSaveUrl, isNodeInView, addOrUpdateNodeMesh, handleActivateTimeline, get_scene_view_data, save_view_data]);
|
|
11052
|
-
const handleGhostNodeImageChange = (0,
|
|
11289
|
+
const handleGhostNodeImageChange = (0, import_react25.useCallback)((useImage, imageUrl) => {
|
|
11053
11290
|
const { node: ghostNode, line: ghostLine, aura: ghostAura } = stateRef.current.ghostElements;
|
|
11054
11291
|
const { graphGroup, glowTexture } = stateRef.current;
|
|
11055
11292
|
if (!ghostNode || !graphGroup) return;
|
|
@@ -11091,7 +11328,7 @@ function XViewScene({
|
|
|
11091
11328
|
aura: newGhostNode.getObjectByName("aura")
|
|
11092
11329
|
};
|
|
11093
11330
|
}, []);
|
|
11094
|
-
const handleGhostNodeIntensityChange = (0,
|
|
11331
|
+
const handleGhostNodeIntensityChange = (0, import_react25.useCallback)((newIntensity) => {
|
|
11095
11332
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
11096
11333
|
if (!ghostNode) return;
|
|
11097
11334
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -11112,7 +11349,7 @@ function XViewScene({
|
|
|
11112
11349
|
ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
|
|
11113
11350
|
}
|
|
11114
11351
|
}, []);
|
|
11115
|
-
const handleDetailNodeIntensityChange = (0,
|
|
11352
|
+
const handleDetailNodeIntensityChange = (0, import_react25.useCallback)((nodeId, newIntensity) => {
|
|
11116
11353
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
11117
11354
|
if (!mesh) return;
|
|
11118
11355
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -11258,7 +11495,7 @@ function XViewScene({
|
|
|
11258
11495
|
mountRef.current.style.cursor = "default";
|
|
11259
11496
|
}
|
|
11260
11497
|
};
|
|
11261
|
-
const handleAncestryTreeUpdate = (0,
|
|
11498
|
+
const handleAncestryTreeUpdate = (0, import_react25.useCallback)((newTree, extraData = null) => {
|
|
11262
11499
|
setAncestryMode((prev) => {
|
|
11263
11500
|
const prevTreeStr = JSON.stringify(prev.tree);
|
|
11264
11501
|
const newTreeStr = JSON.stringify(newTree);
|
|
@@ -11278,7 +11515,7 @@ function XViewScene({
|
|
|
11278
11515
|
};
|
|
11279
11516
|
});
|
|
11280
11517
|
}, []);
|
|
11281
|
-
const actionHandlerContext = (0,
|
|
11518
|
+
const actionHandlerContext = (0, import_react25.useMemo)(
|
|
11282
11519
|
() => {
|
|
11283
11520
|
var _a2;
|
|
11284
11521
|
return {
|
|
@@ -11288,6 +11525,11 @@ function XViewScene({
|
|
|
11288
11525
|
mountRef,
|
|
11289
11526
|
creationMode,
|
|
11290
11527
|
versionMode,
|
|
11528
|
+
questMode,
|
|
11529
|
+
sceneSaveUrl,
|
|
11530
|
+
sceneConfigId,
|
|
11531
|
+
ownerId,
|
|
11532
|
+
viewType: viewParams == null ? void 0 : viewParams.type,
|
|
11291
11533
|
userId: (_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.id,
|
|
11292
11534
|
setters: {
|
|
11293
11535
|
setContextMenu,
|
|
@@ -11299,7 +11541,8 @@ function XViewScene({
|
|
|
11299
11541
|
setDetailsNode,
|
|
11300
11542
|
setDetailsLink,
|
|
11301
11543
|
setSceneVersion,
|
|
11302
|
-
setAncestryMode
|
|
11544
|
+
setAncestryMode,
|
|
11545
|
+
setQuestMode
|
|
11303
11546
|
},
|
|
11304
11547
|
tweenToTarget,
|
|
11305
11548
|
handleVersionTimeline,
|
|
@@ -11315,8 +11558,13 @@ function XViewScene({
|
|
|
11315
11558
|
[
|
|
11316
11559
|
creationMode,
|
|
11317
11560
|
versionMode,
|
|
11318
|
-
|
|
11561
|
+
questMode,
|
|
11562
|
+
sceneSaveUrl,
|
|
11563
|
+
sceneConfigId,
|
|
11564
|
+
ownerId,
|
|
11565
|
+
viewParams == null ? void 0 : viewParams.type,
|
|
11319
11566
|
(_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id,
|
|
11567
|
+
tweenToTarget,
|
|
11320
11568
|
handleVersionTimeline,
|
|
11321
11569
|
save_view_data,
|
|
11322
11570
|
get_single_parent_file,
|
|
@@ -11328,7 +11576,98 @@ function XViewScene({
|
|
|
11328
11576
|
const handleStartVersioning = (nodeData) => {
|
|
11329
11577
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
11330
11578
|
};
|
|
11331
|
-
const
|
|
11579
|
+
const handleSaveQuestNode = async (context, newQuestData) => {
|
|
11580
|
+
const { graphDataRef, sceneDataRef: sceneDataRef2, stateRef: stateRef2, setters, actions, sceneSaveUrl: sceneSaveUrl2, viewType, sceneConfigId: sceneConfigId2, ownerId: ownerId2 } = context;
|
|
11581
|
+
if (!graphDataRef.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
|
|
11582
|
+
const newNode = {
|
|
11583
|
+
id: import_short_uuid2.default.generate(),
|
|
11584
|
+
...newQuestData,
|
|
11585
|
+
is_quest: true,
|
|
11586
|
+
type: ["quest", ...newQuestData.type.filter((t) => t !== "quest")]
|
|
11587
|
+
};
|
|
11588
|
+
if (!graphDataRef.current[sceneConfigId2]) {
|
|
11589
|
+
graphDataRef.current[sceneConfigId2] = { nodes: [], links: [] };
|
|
11590
|
+
}
|
|
11591
|
+
graphDataRef.current[sceneConfigId2].nodes.push(newNode);
|
|
11592
|
+
const sceneFileData = {
|
|
11593
|
+
parent_dbs: sceneDataRef2.current.parent_dbs,
|
|
11594
|
+
nodes: sceneDataRef2.current.nodes,
|
|
11595
|
+
// <-- Mantém o cenário inicial inalterado
|
|
11596
|
+
links: sceneDataRef2.current.links,
|
|
11597
|
+
// <-- Mantém o cenário inicial inalterado
|
|
11598
|
+
quest_nodes: graphDataRef.current[sceneConfigId2].nodes,
|
|
11599
|
+
quest_links: graphDataRef.current[sceneConfigId2].links
|
|
11600
|
+
};
|
|
11601
|
+
try {
|
|
11602
|
+
await actions.save_view_data(sceneSaveUrl2, sceneFileData);
|
|
11603
|
+
stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
11604
|
+
parentFileId: sceneConfigId2,
|
|
11605
|
+
ownerId: ownerId2,
|
|
11606
|
+
datasetName: "Quests Internas (View)"
|
|
11607
|
+
});
|
|
11608
|
+
const basePosition = stateRef2.current.controls.target.clone();
|
|
11609
|
+
const offset = new THREE3.Vector3((Math.random() - 0.5) * 15, (Math.random() - 0.5) * 5, 0);
|
|
11610
|
+
const finalPosition = basePosition.add(offset);
|
|
11611
|
+
addStandaloneNodeToScene(stateRef2.current, newNode, finalPosition);
|
|
11612
|
+
context.tweenToTarget(finalPosition, 1.2);
|
|
11613
|
+
setters.setQuestMode({ isActive: false });
|
|
11614
|
+
setters.setSceneVersion((v) => v + 1);
|
|
11615
|
+
} catch (error) {
|
|
11616
|
+
console.error("Falha ao salvar Quest na View:", error);
|
|
11617
|
+
alert("Ocorreu um erro ao criar a Quest.");
|
|
11618
|
+
}
|
|
11619
|
+
};
|
|
11620
|
+
userActionHandlers.handleCompleteConnection = async (context, targetNodeData) => {
|
|
11621
|
+
const { stateRef: stateRef2, graphDataRef, sceneDataRef: sceneDataRef2, sceneConfigId: sceneConfigId2, sceneSaveUrl: sceneSaveUrl2, ownerId: ownerId2 } = context;
|
|
11622
|
+
const { sourceNodeData } = stateRef2.current.connection;
|
|
11623
|
+
if (!graphDataRef.current || !sceneDataRef2.current || !sourceNodeData || !targetNodeData) {
|
|
11624
|
+
userActionHandlers.handleCancelConnection(context);
|
|
11625
|
+
return;
|
|
11626
|
+
}
|
|
11627
|
+
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, sourceNodeData.id, sceneConfigId2, ownerId2);
|
|
11628
|
+
const targetParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, targetNodeData.id, sceneConfigId2, ownerId2);
|
|
11629
|
+
let parentInfoToSave = sourceParentInfo;
|
|
11630
|
+
if (sourceParentInfo.parentFileId === sceneConfigId2 && targetParentInfo.parentFileId !== sceneConfigId2) {
|
|
11631
|
+
parentInfoToSave = targetParentInfo;
|
|
11632
|
+
} else if (targetParentInfo.parentFileId === sceneConfigId2 && sourceParentInfo.parentFileId !== sceneConfigId2) {
|
|
11633
|
+
parentInfoToSave = sourceParentInfo;
|
|
11634
|
+
}
|
|
11635
|
+
const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
|
|
11636
|
+
const newLink = {
|
|
11637
|
+
id: `link_${import_short_uuid2.default.generate()}`,
|
|
11638
|
+
source: sourceNodeData.id,
|
|
11639
|
+
target: targetNodeData.id
|
|
11640
|
+
};
|
|
11641
|
+
try {
|
|
11642
|
+
if (parentFileIdToSave === sceneConfigId2) {
|
|
11643
|
+
const specificParentData = graphDataRef.current[sceneConfigId2];
|
|
11644
|
+
specificParentData.links.push(newLink);
|
|
11645
|
+
const viewFilePayload = {
|
|
11646
|
+
parent_dbs: sceneDataRef2.current.parent_dbs,
|
|
11647
|
+
nodes: sceneDataRef2.current.nodes,
|
|
11648
|
+
// <-- Usa o estado original intocado
|
|
11649
|
+
links: sceneDataRef2.current.links,
|
|
11650
|
+
// <-- Usa o estado original intocado
|
|
11651
|
+
quest_nodes: specificParentData.nodes,
|
|
11652
|
+
quest_links: specificParentData.links
|
|
11653
|
+
// Salva a conexão aqui!
|
|
11654
|
+
};
|
|
11655
|
+
await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
|
|
11656
|
+
} else {
|
|
11657
|
+
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
|
|
11658
|
+
specificParentData.links.push(newLink);
|
|
11659
|
+
const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
|
|
11660
|
+
await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
|
|
11661
|
+
graphDataRef.current[parentFileIdToSave] = specificParentData;
|
|
11662
|
+
}
|
|
11663
|
+
addNewLinkToScene(stateRef2.current, newLink);
|
|
11664
|
+
} catch (error) {
|
|
11665
|
+
console.error("Falha ao salvar a nova conex\xE3o:", error);
|
|
11666
|
+
alert("Ocorreu um erro ao salvar a nova conex\xE3o.");
|
|
11667
|
+
}
|
|
11668
|
+
userActionHandlers.handleCancelConnection(context);
|
|
11669
|
+
};
|
|
11670
|
+
const handleClearAncestryVisuals = (0, import_react25.useCallback)((ancestryId) => {
|
|
11332
11671
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
11333
11672
|
const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
|
|
11334
11673
|
if (renderIndex !== -1) {
|
|
@@ -11342,7 +11681,7 @@ function XViewScene({
|
|
|
11342
11681
|
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
11343
11682
|
}
|
|
11344
11683
|
}, []);
|
|
11345
|
-
const handleRenderAncestry = (0,
|
|
11684
|
+
const handleRenderAncestry = (0, import_react25.useCallback)(
|
|
11346
11685
|
async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
|
|
11347
11686
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11348
11687
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -11758,7 +12097,7 @@ function XViewScene({
|
|
|
11758
12097
|
},
|
|
11759
12098
|
[addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, readingMode.isActive, ancestryMode.isActive]
|
|
11760
12099
|
);
|
|
11761
|
-
const handleRenderAbstractionTree = (0,
|
|
12100
|
+
const handleRenderAbstractionTree = (0, import_react25.useCallback)((ancestryObject, targetNodeId = null) => {
|
|
11762
12101
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11763
12102
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
11764
12103
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
@@ -11819,7 +12158,7 @@ function XViewScene({
|
|
|
11819
12158
|
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
11820
12159
|
tweenToTarget(rootTargetPos, 0.7);
|
|
11821
12160
|
}, [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, handleClearAncestryVisuals]);
|
|
11822
|
-
const handleReadModeBranchNav = (0,
|
|
12161
|
+
const handleReadModeBranchNav = (0, import_react25.useCallback)((nodeId, action, direction = "right") => {
|
|
11823
12162
|
const { ancestry, branchStack } = readingMode;
|
|
11824
12163
|
if (!ancestry || !ancestry.tree) return;
|
|
11825
12164
|
const allAncestries = ancestryDataRef.current || [];
|
|
@@ -11960,13 +12299,13 @@ function XViewScene({
|
|
|
11960
12299
|
}));
|
|
11961
12300
|
}
|
|
11962
12301
|
}, [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]);
|
|
11963
|
-
const handleReadModeHighlight = (0,
|
|
12302
|
+
const handleReadModeHighlight = (0, import_react25.useCallback)((nodeId) => {
|
|
11964
12303
|
if (stateRef.current.highlightedNodeId !== nodeId) {
|
|
11965
12304
|
stateRef.current.highlightedNodeId = nodeId;
|
|
11966
12305
|
}
|
|
11967
12306
|
setHighlightedNodeId(nodeId);
|
|
11968
12307
|
}, []);
|
|
11969
|
-
const activeNodeBranches = (0,
|
|
12308
|
+
const activeNodeBranches = (0, import_react25.useMemo)(() => {
|
|
11970
12309
|
if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree) return null;
|
|
11971
12310
|
const fullTree = buildFullAncestryTree(
|
|
11972
12311
|
readingMode.ancestry.tree,
|
|
@@ -12003,7 +12342,7 @@ function XViewScene({
|
|
|
12003
12342
|
}
|
|
12004
12343
|
return null;
|
|
12005
12344
|
}, [highlightedNodeId, readingMode.ancestry, buildFullAncestryTree, readingMode.branchStack, ancestryDataRef.current]);
|
|
12006
|
-
const backNavigationInfo = (0,
|
|
12345
|
+
const backNavigationInfo = (0, import_react25.useMemo)(() => {
|
|
12007
12346
|
const { branchStack } = readingMode;
|
|
12008
12347
|
if (!branchStack || branchStack.length === 0) return null;
|
|
12009
12348
|
const lastStep = branchStack[branchStack.length - 1];
|
|
@@ -12014,7 +12353,7 @@ function XViewScene({
|
|
|
12014
12353
|
name: "Voltar para anterior"
|
|
12015
12354
|
};
|
|
12016
12355
|
}, [readingMode.branchStack]);
|
|
12017
|
-
const getReadModeDisplayContext = (0,
|
|
12356
|
+
const getReadModeDisplayContext = (0, import_react25.useMemo)(() => {
|
|
12018
12357
|
const { ancestry, branchStack } = readingMode;
|
|
12019
12358
|
if (!ancestry) return null;
|
|
12020
12359
|
if (branchStack.length === 0) {
|
|
@@ -12055,7 +12394,7 @@ function XViewScene({
|
|
|
12055
12394
|
customProperties: branchProps
|
|
12056
12395
|
};
|
|
12057
12396
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
12058
|
-
const readModeAbstractionTree = (0,
|
|
12397
|
+
const readModeAbstractionTree = (0, import_react25.useMemo)(() => {
|
|
12059
12398
|
if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
|
|
12060
12399
|
return null;
|
|
12061
12400
|
}
|
|
@@ -12067,7 +12406,7 @@ function XViewScene({
|
|
|
12067
12406
|
allAncestries
|
|
12068
12407
|
);
|
|
12069
12408
|
}, [readingMode.isActive, readingMode.ancestry, buildFullAncestryTree, sceneVersion]);
|
|
12070
|
-
const handleStartReadingAncestry = (0,
|
|
12409
|
+
const handleStartReadingAncestry = (0, import_react25.useCallback)(
|
|
12071
12410
|
async (ancestryObject) => {
|
|
12072
12411
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
12073
12412
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -12102,7 +12441,7 @@ function XViewScene({
|
|
|
12102
12441
|
},
|
|
12103
12442
|
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
12104
12443
|
);
|
|
12105
|
-
const handleReadModeSectionChange = (0,
|
|
12444
|
+
const handleReadModeSectionChange = (0, import_react25.useCallback)((activeSectionId) => {
|
|
12106
12445
|
const { ancestry, branchStack } = readingMode;
|
|
12107
12446
|
if (!ancestry || !readingMode.isActive) return;
|
|
12108
12447
|
let targetObj = ancestry;
|
|
@@ -12171,10 +12510,10 @@ function XViewScene({
|
|
|
12171
12510
|
}, 0);
|
|
12172
12511
|
handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
|
|
12173
12512
|
}, [readingMode, handleRenderAncestry, buildFullAncestryTree, ancestryDataRef.current]);
|
|
12174
|
-
const handleCloseReadMode = (0,
|
|
12513
|
+
const handleCloseReadMode = (0, import_react25.useCallback)(() => {
|
|
12175
12514
|
setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
|
|
12176
12515
|
}, []);
|
|
12177
|
-
const handleAncestrySectionChange = (0,
|
|
12516
|
+
const handleAncestrySectionChange = (0, import_react25.useCallback)((activeSectionId, ancestryOverride = null, rotation = 0) => {
|
|
12178
12517
|
var _a2, _b2;
|
|
12179
12518
|
const currentMode = stateRef.current.ancestry;
|
|
12180
12519
|
let targetObj = ancestryOverride;
|
|
@@ -12226,7 +12565,7 @@ function XViewScene({
|
|
|
12226
12565
|
const renderPayload = { ...targetObj, tree: treeToRender };
|
|
12227
12566
|
handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
|
|
12228
12567
|
}, [handleRenderAncestry]);
|
|
12229
|
-
const handleEditAncestry = (0,
|
|
12568
|
+
const handleEditAncestry = (0, import_react25.useCallback)(
|
|
12230
12569
|
async (ancestryObject) => {
|
|
12231
12570
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
12232
12571
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -12265,7 +12604,7 @@ function XViewScene({
|
|
|
12265
12604
|
const handleSelectAncestryParent = (nodeId) => {
|
|
12266
12605
|
setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
|
|
12267
12606
|
};
|
|
12268
|
-
const handleRemoveFromAncestry = (0,
|
|
12607
|
+
const handleRemoveFromAncestry = (0, import_react25.useCallback)((pathToRemove) => {
|
|
12269
12608
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
|
|
12270
12609
|
console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
|
|
12271
12610
|
return;
|
|
@@ -12290,7 +12629,7 @@ function XViewScene({
|
|
|
12290
12629
|
return { ...prev, tree: newTree };
|
|
12291
12630
|
});
|
|
12292
12631
|
}, []);
|
|
12293
|
-
const handleSaveAncestry = (0,
|
|
12632
|
+
const handleSaveAncestry = (0, import_react25.useCallback)(
|
|
12294
12633
|
async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
|
|
12295
12634
|
const treeToUse = treeOverride || ancestryMode.tree;
|
|
12296
12635
|
const { isEditMode, currentAncestryId } = ancestryMode;
|
|
@@ -12494,7 +12833,7 @@ function XViewScene({
|
|
|
12494
12833
|
});
|
|
12495
12834
|
setEditingAncestryRel({ visible: false, data: null, path: null });
|
|
12496
12835
|
};
|
|
12497
|
-
const handleDeleteAncestry = (0,
|
|
12836
|
+
const handleDeleteAncestry = (0, import_react25.useCallback)(
|
|
12498
12837
|
async (ancestryIdToDelete) => {
|
|
12499
12838
|
if (!ancestryIdToDelete) {
|
|
12500
12839
|
alert("ID da ancestralidade n\xE3o encontrado.");
|
|
@@ -12556,20 +12895,20 @@ function XViewScene({
|
|
|
12556
12895
|
},
|
|
12557
12896
|
[save_view_data, delete_file_action]
|
|
12558
12897
|
);
|
|
12559
|
-
const handleOpenAncestryBoard = (0,
|
|
12898
|
+
const handleOpenAncestryBoard = (0, import_react25.useCallback)(() => {
|
|
12560
12899
|
setIsAncestryBoardOpen(true);
|
|
12561
12900
|
}, []);
|
|
12562
|
-
const handleSelectAncestryFromBoard = (0,
|
|
12901
|
+
const handleSelectAncestryFromBoard = (0, import_react25.useCallback)((ancestry) => {
|
|
12563
12902
|
setIsAncestryBoardOpen(false);
|
|
12564
12903
|
setIsSidebarOpen(false);
|
|
12565
12904
|
handleStartReadingAncestry(ancestry);
|
|
12566
12905
|
}, [handleStartReadingAncestry]);
|
|
12567
|
-
const handleSaveAncestryBoard = (0,
|
|
12906
|
+
const handleSaveAncestryBoard = (0, import_react25.useCallback)(async (groups) => {
|
|
12568
12907
|
if (!sceneConfigId || !viewParams || !session) return;
|
|
12569
12908
|
const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
|
|
12570
12909
|
await save_ancestry_board_action(sceneConfigId, sceneType, groups, session, ownerId);
|
|
12571
12910
|
}, [sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]);
|
|
12572
|
-
const existingNodeTypes = (0,
|
|
12911
|
+
const existingNodeTypes = (0, import_react25.useMemo)(() => {
|
|
12573
12912
|
if (!parentDataRef.current) {
|
|
12574
12913
|
return [];
|
|
12575
12914
|
}
|
|
@@ -12579,7 +12918,7 @@ function XViewScene({
|
|
|
12579
12918
|
})).filter(Boolean);
|
|
12580
12919
|
return [...new Set(allTypes)];
|
|
12581
12920
|
}, [parentDataRef.current, sceneVersion]);
|
|
12582
|
-
const searchableDbNodes = (0,
|
|
12921
|
+
const searchableDbNodes = (0, import_react25.useMemo)(() => {
|
|
12583
12922
|
if (!parentDataRef.current) {
|
|
12584
12923
|
return [];
|
|
12585
12924
|
}
|
|
@@ -12588,13 +12927,14 @@ function XViewScene({
|
|
|
12588
12927
|
return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
|
|
12589
12928
|
});
|
|
12590
12929
|
}, [parentDataRef.current, sceneVersion]);
|
|
12591
|
-
const handleAddExistingNode = (0,
|
|
12930
|
+
const handleAddExistingNode = (0, import_react25.useCallback)(
|
|
12592
12931
|
(nodeId) => {
|
|
12593
12932
|
return userActionHandlers.handleAddExistingNodeById(actionHandlerContext, nodeId);
|
|
12594
12933
|
},
|
|
12595
12934
|
[actionHandlerContext]
|
|
12596
12935
|
);
|
|
12597
|
-
const handleSaveCurrentView = (0,
|
|
12936
|
+
const handleSaveCurrentView = (0, import_react25.useCallback)(async () => {
|
|
12937
|
+
var _a2, _b2, _c2;
|
|
12598
12938
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
12599
12939
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
12600
12940
|
console.warn("N\xE3o \xE9 poss\xEDvel salvar a cena: estado n\xE3o inicializado ou URL de salvamento ausente.");
|
|
@@ -12616,25 +12956,30 @@ function XViewScene({
|
|
|
12616
12956
|
const { sourceNode, targetNode, ...serializableLinkData } = line.userData;
|
|
12617
12957
|
return serializableLinkData;
|
|
12618
12958
|
});
|
|
12959
|
+
sceneDataRef.current.nodes = currentNodes;
|
|
12960
|
+
sceneDataRef.current.links = currentLinks;
|
|
12961
|
+
const isView = ((_a2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _a2.toLowerCase()) === "view";
|
|
12619
12962
|
const sceneFileData = {
|
|
12620
12963
|
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
12621
12964
|
nodes: currentNodes,
|
|
12622
|
-
links: currentLinks
|
|
12965
|
+
links: currentLinks,
|
|
12966
|
+
quest_nodes: isView ? ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || [] : sceneDataRef.current.quest_nodes || [],
|
|
12967
|
+
quest_links: isView ? ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || [] : sceneDataRef.current.quest_links || []
|
|
12623
12968
|
};
|
|
12624
12969
|
try {
|
|
12625
12970
|
await save_view_data(sceneSaveUrl, sceneFileData);
|
|
12626
12971
|
} catch (error) {
|
|
12627
12972
|
console.error("Erro na chamada de save_view_data:", error);
|
|
12628
12973
|
}
|
|
12629
|
-
}, [sceneSaveUrl, save_view_data]);
|
|
12630
|
-
const allAvailableNodes = (0,
|
|
12974
|
+
}, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
|
|
12975
|
+
const allAvailableNodes = (0, import_react25.useMemo)(() => {
|
|
12631
12976
|
if (!parentDataRef.current) return [];
|
|
12632
12977
|
return Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
|
|
12633
12978
|
}, [sceneVersion, isInitialized]);
|
|
12634
|
-
const allAvailableAncestries = (0,
|
|
12979
|
+
const allAvailableAncestries = (0, import_react25.useMemo)(() => {
|
|
12635
12980
|
return ancestryDataRef.current || [];
|
|
12636
12981
|
}, [sceneVersion, isInitialized]);
|
|
12637
|
-
const handleOpenReference = (0,
|
|
12982
|
+
const handleOpenReference = (0, import_react25.useCallback)((referenceData) => {
|
|
12638
12983
|
const { type, id } = referenceData;
|
|
12639
12984
|
if (type === "node") {
|
|
12640
12985
|
const targetNode = allAvailableNodes.find((n) => String(n.id) === String(id));
|
|
@@ -12661,17 +13006,17 @@ function XViewScene({
|
|
|
12661
13006
|
}
|
|
12662
13007
|
}
|
|
12663
13008
|
}, [allAvailableNodes, allAvailableAncestries, handleEditAncestry, tweenToTarget]);
|
|
12664
|
-
const handleToggleAncestryAddMode = (0,
|
|
13009
|
+
const handleToggleAncestryAddMode = (0, import_react25.useCallback)(() => {
|
|
12665
13010
|
setAncestryMode((prev) => ({ ...prev, isAddingNodes: !prev.isAddingNodes }));
|
|
12666
13011
|
}, []);
|
|
12667
|
-
const handleFocusNode = (0,
|
|
13012
|
+
const handleFocusNode = (0, import_react25.useCallback)((nodeData) => {
|
|
12668
13013
|
if (!nodeData) return;
|
|
12669
13014
|
const nodeMesh = stateRef.current.nodeObjects[String(nodeData.id)];
|
|
12670
13015
|
if (nodeMesh) {
|
|
12671
13016
|
tweenToTarget(nodeMesh, 1.2);
|
|
12672
13017
|
}
|
|
12673
13018
|
}, [tweenToTarget]);
|
|
12674
|
-
const availableDatasets = (0,
|
|
13019
|
+
const availableDatasets = (0, import_react25.useMemo)(() => {
|
|
12675
13020
|
if (!sceneDataRef.current || !parentDataRef.current) return [];
|
|
12676
13021
|
return sceneDataRef.current.parent_dbs.map((db) => {
|
|
12677
13022
|
var _a2;
|
|
@@ -12683,7 +13028,7 @@ function XViewScene({
|
|
|
12683
13028
|
}, [sceneVersion, isInitialized]);
|
|
12684
13029
|
const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(String(creationMode.sourceNodeData.id))) == null ? void 0 : _b.parentFileId : null;
|
|
12685
13030
|
const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
|
|
12686
|
-
(0,
|
|
13031
|
+
(0, import_react25.useEffect)(() => {
|
|
12687
13032
|
if (isInitialized && focusNodeId && !hasFocusedInitial) {
|
|
12688
13033
|
const nodeObjects = stateRef.current.nodeObjects || {};
|
|
12689
13034
|
const targetMesh = nodeObjects[String(focusNodeId)];
|
|
@@ -12697,7 +13042,7 @@ function XViewScene({
|
|
|
12697
13042
|
}
|
|
12698
13043
|
}
|
|
12699
13044
|
}, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
|
|
12700
|
-
(0,
|
|
13045
|
+
(0, import_react25.useEffect)(() => {
|
|
12701
13046
|
if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
|
|
12702
13047
|
const ancestries = ancestryDataRef.current || [];
|
|
12703
13048
|
const targetAncestry = ancestries.find((a) => String(a.ancestry_id) === String(focusAncestryId));
|
|
@@ -12712,20 +13057,20 @@ function XViewScene({
|
|
|
12712
13057
|
}
|
|
12713
13058
|
}, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
|
|
12714
13059
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
12715
|
-
return /* @__PURE__ */
|
|
13060
|
+
return /* @__PURE__ */ import_react25.default.createElement(LoadingScreen, null);
|
|
12716
13061
|
}
|
|
12717
13062
|
if (permissionStatus === "denied") {
|
|
12718
|
-
return /* @__PURE__ */
|
|
13063
|
+
return /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react25.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "w-16 h-16 mx-auto" }, /* @__PURE__ */ import_react25.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" }))), /* @__PURE__ */ import_react25.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react25.default.createElement("p", { className: "text-slate-400 mb-6" }, "Voc\xEA n\xE3o tem permiss\xE3o para acessar este conte\xFAdo. Solicite acesso ao propriet\xE1rio ou verifique se est\xE1 na conta correta."), /* @__PURE__ */ import_react25.default.createElement(
|
|
12719
13064
|
"button",
|
|
12720
13065
|
{
|
|
12721
13066
|
onClick: () => router.push("/dashboard/scenes"),
|
|
12722
13067
|
className: "flex items-center justify-center gap-2 w-full py-3 px-4 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors font-medium"
|
|
12723
13068
|
},
|
|
12724
|
-
/* @__PURE__ */
|
|
13069
|
+
/* @__PURE__ */ import_react25.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 2, stroke: "currentColor", className: "w-5 h-5" }, /* @__PURE__ */ import_react25.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" })),
|
|
12725
13070
|
"Voltar para Scenes"
|
|
12726
13071
|
)));
|
|
12727
13072
|
}
|
|
12728
|
-
return /* @__PURE__ */
|
|
13073
|
+
return /* @__PURE__ */ import_react25.default.createElement(
|
|
12729
13074
|
"div",
|
|
12730
13075
|
{
|
|
12731
13076
|
ref: mountRef,
|
|
@@ -12737,7 +13082,7 @@ function XViewScene({
|
|
|
12737
13082
|
cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
|
|
12738
13083
|
}
|
|
12739
13084
|
},
|
|
12740
|
-
userPermissionRole !== "link_viewer" && /* @__PURE__ */
|
|
13085
|
+
userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react25.default.createElement(
|
|
12741
13086
|
XViewSidebar,
|
|
12742
13087
|
{
|
|
12743
13088
|
dbNodes: searchableDbNodes,
|
|
@@ -12757,7 +13102,7 @@ function XViewScene({
|
|
|
12757
13102
|
userRole: userPermissionRole
|
|
12758
13103
|
}
|
|
12759
13104
|
),
|
|
12760
|
-
creationMode.isActive && /* @__PURE__ */
|
|
13105
|
+
creationMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
|
|
12761
13106
|
InSceneCreationForm,
|
|
12762
13107
|
{
|
|
12763
13108
|
onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
|
|
@@ -12782,7 +13127,7 @@ function XViewScene({
|
|
|
12782
13127
|
availableAncestries: allAvailableAncestries
|
|
12783
13128
|
}
|
|
12784
13129
|
),
|
|
12785
|
-
versionMode.isActive && /* @__PURE__ */
|
|
13130
|
+
versionMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
|
|
12786
13131
|
InSceneVersionForm,
|
|
12787
13132
|
{
|
|
12788
13133
|
onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
|
|
@@ -12801,13 +13146,27 @@ function XViewScene({
|
|
|
12801
13146
|
availableAncestries: allAvailableAncestries
|
|
12802
13147
|
}
|
|
12803
13148
|
),
|
|
12804
|
-
|
|
13149
|
+
questMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
|
|
13150
|
+
InSceneQuestForm,
|
|
13151
|
+
{
|
|
13152
|
+
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
13153
|
+
onCancel: () => setQuestMode({ isActive: false }),
|
|
13154
|
+
style: { position: "absolute", left: `16px`, top: `16px`, zIndex: 20, transition: "opacity 200ms ease-out" },
|
|
13155
|
+
refEl: formRef,
|
|
13156
|
+
onOpenImageViewer: handleOpenImageViewer,
|
|
13157
|
+
onMentionClick: handleAddExistingNode,
|
|
13158
|
+
onUploadFile: upload_file_action,
|
|
13159
|
+
availableNodes: allAvailableNodes,
|
|
13160
|
+
availableAncestries: allAvailableAncestries
|
|
13161
|
+
}
|
|
13162
|
+
),
|
|
13163
|
+
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react25.default.createElement(
|
|
12805
13164
|
"div",
|
|
12806
13165
|
{
|
|
12807
13166
|
className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col ${isReadModeResizing ? "transition-none" : "transition-all duration-300 ease-out"}`,
|
|
12808
13167
|
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${readModeWidth}px`, maxWidth: "92vw" }
|
|
12809
13168
|
},
|
|
12810
|
-
/* @__PURE__ */
|
|
13169
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
12811
13170
|
"div",
|
|
12812
13171
|
{
|
|
12813
13172
|
onPointerDown: (e) => {
|
|
@@ -12818,7 +13177,7 @@ function XViewScene({
|
|
|
12818
13177
|
title: "Arraste para redimensionar"
|
|
12819
13178
|
}
|
|
12820
13179
|
),
|
|
12821
|
-
/* @__PURE__ */
|
|
13180
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
12822
13181
|
DescriptionReadModePanel,
|
|
12823
13182
|
{
|
|
12824
13183
|
key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
|
|
@@ -12853,7 +13212,7 @@ function XViewScene({
|
|
|
12853
13212
|
}
|
|
12854
13213
|
)
|
|
12855
13214
|
),
|
|
12856
|
-
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */
|
|
13215
|
+
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react25.default.createElement(
|
|
12857
13216
|
CreateAncestryPanel,
|
|
12858
13217
|
{
|
|
12859
13218
|
ancestryMode,
|
|
@@ -12880,7 +13239,7 @@ function XViewScene({
|
|
|
12880
13239
|
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
12881
13240
|
}
|
|
12882
13241
|
),
|
|
12883
|
-
editingAncestryRel.visible && /* @__PURE__ */
|
|
13242
|
+
editingAncestryRel.visible && /* @__PURE__ */ import_react25.default.createElement(
|
|
12884
13243
|
AncestryRelationshipPanel,
|
|
12885
13244
|
{
|
|
12886
13245
|
data: editingAncestryRel.data,
|
|
@@ -12894,7 +13253,7 @@ function XViewScene({
|
|
|
12894
13253
|
onUploadFile: upload_file_action
|
|
12895
13254
|
}
|
|
12896
13255
|
),
|
|
12897
|
-
detailsNode && /* @__PURE__ */
|
|
13256
|
+
detailsNode && /* @__PURE__ */ import_react25.default.createElement(
|
|
12898
13257
|
NodeDetailsPanel,
|
|
12899
13258
|
{
|
|
12900
13259
|
node: detailsNode,
|
|
@@ -12921,7 +13280,7 @@ function XViewScene({
|
|
|
12921
13280
|
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
12922
13281
|
}
|
|
12923
13282
|
),
|
|
12924
|
-
detailsLink && /* @__PURE__ */
|
|
13283
|
+
detailsLink && /* @__PURE__ */ import_react25.default.createElement(
|
|
12925
13284
|
RelationshipDetailsPanel,
|
|
12926
13285
|
{
|
|
12927
13286
|
link: detailsLink,
|
|
@@ -12935,7 +13294,7 @@ function XViewScene({
|
|
|
12935
13294
|
userRole: userPermissionRole
|
|
12936
13295
|
}
|
|
12937
13296
|
),
|
|
12938
|
-
ancestryLinkDetails && /* @__PURE__ */
|
|
13297
|
+
ancestryLinkDetails && /* @__PURE__ */ import_react25.default.createElement(
|
|
12939
13298
|
AncestryLinkDetailsPanel,
|
|
12940
13299
|
{
|
|
12941
13300
|
data: ancestryLinkDetails,
|
|
@@ -12946,7 +13305,7 @@ function XViewScene({
|
|
|
12946
13305
|
onUploadFile: upload_file_action
|
|
12947
13306
|
}
|
|
12948
13307
|
),
|
|
12949
|
-
/* @__PURE__ */
|
|
13308
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
12950
13309
|
"div",
|
|
12951
13310
|
{
|
|
12952
13311
|
ref: tooltipRef,
|
|
@@ -12973,7 +13332,7 @@ function XViewScene({
|
|
|
12973
13332
|
}
|
|
12974
13333
|
}
|
|
12975
13334
|
),
|
|
12976
|
-
/* @__PURE__ */
|
|
13335
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
12977
13336
|
ContextMenu,
|
|
12978
13337
|
{
|
|
12979
13338
|
data: contextMenu,
|
|
@@ -12996,7 +13355,7 @@ function XViewScene({
|
|
|
12996
13355
|
onFocusNode: handleFocusNode
|
|
12997
13356
|
}
|
|
12998
13357
|
),
|
|
12999
|
-
/* @__PURE__ */
|
|
13358
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
13000
13359
|
MultiNodeContextMenu,
|
|
13001
13360
|
{
|
|
13002
13361
|
data: multiContextMenu,
|
|
@@ -13007,7 +13366,7 @@ function XViewScene({
|
|
|
13007
13366
|
onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
|
|
13008
13367
|
}
|
|
13009
13368
|
),
|
|
13010
|
-
/* @__PURE__ */
|
|
13369
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
13011
13370
|
RelationshipContextMenu,
|
|
13012
13371
|
{
|
|
13013
13372
|
data: relationshipMenu,
|
|
@@ -13025,8 +13384,8 @@ function XViewScene({
|
|
|
13025
13384
|
onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
|
|
13026
13385
|
}
|
|
13027
13386
|
),
|
|
13028
|
-
/* @__PURE__ */
|
|
13029
|
-
/* @__PURE__ */
|
|
13387
|
+
/* @__PURE__ */ import_react25.default.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
|
|
13388
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
13030
13389
|
AncestryBoard,
|
|
13031
13390
|
{
|
|
13032
13391
|
isOpen: isAncestryBoardOpen,
|
|
@@ -13039,7 +13398,7 @@ function XViewScene({
|
|
|
13039
13398
|
userRole: userPermissionRole
|
|
13040
13399
|
}
|
|
13041
13400
|
),
|
|
13042
|
-
/* @__PURE__ */
|
|
13401
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
13043
13402
|
ImportParentFileModal,
|
|
13044
13403
|
{
|
|
13045
13404
|
isOpen: isImportModalOpen,
|
|
@@ -13100,11 +13459,24 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
13100
13459
|
);
|
|
13101
13460
|
}
|
|
13102
13461
|
}
|
|
13462
|
+
if (type && type.toLowerCase() === "view") {
|
|
13463
|
+
parentData[scene_config] = {
|
|
13464
|
+
dataset_name: "Quests Internas (View)",
|
|
13465
|
+
nodes: sceneData.quest_nodes || [],
|
|
13466
|
+
links: sceneData.quest_links || []
|
|
13467
|
+
};
|
|
13468
|
+
}
|
|
13103
13469
|
const allNodes = Object.values(parentData).flatMap((db) => db.nodes || []);
|
|
13104
13470
|
const allLinks = Object.values(parentData).flatMap((db) => db.links || []);
|
|
13105
13471
|
const parentNodeMap = new Map(allNodes.map((node) => [String(node.id), node]));
|
|
13106
13472
|
const parentLinkMap = new Map(allLinks.map((link) => [`${link.source}-${link.target}`, link]));
|
|
13107
|
-
const validatedNodes = (sceneData.nodes || []).map((sceneNode) =>
|
|
13473
|
+
const validatedNodes = (sceneData.nodes || []).map((sceneNode) => {
|
|
13474
|
+
const nodeTypes = Array.isArray(sceneNode.type) ? sceneNode.type : [sceneNode.type];
|
|
13475
|
+
if (nodeTypes.includes("quest")) {
|
|
13476
|
+
return sceneNode;
|
|
13477
|
+
}
|
|
13478
|
+
return parentNodeMap.get(String(sceneNode.id));
|
|
13479
|
+
}).filter(Boolean);
|
|
13108
13480
|
const validNodeIdsInScene = new Set(validatedNodes.map((node) => String(node.id)));
|
|
13109
13481
|
const validatedLinks = (sceneData.links || []).filter((sceneLink) => {
|
|
13110
13482
|
const linkExistsInParent = parentLinkMap.has(`${sceneLink.source}-${sceneLink.target}`);
|