@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.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/XViewScene.jsx
|
|
2
|
-
import
|
|
2
|
+
import React24, { useCallback as useCallback4, useEffect as useEffect21, useRef as useRef18, useState as useState24, useMemo as useMemo12 } from "react";
|
|
3
3
|
import { useRouter, useSearchParams } from "next/navigation";
|
|
4
4
|
import { useSession } from "next-auth/react";
|
|
5
5
|
import CryptoJS from "crypto-js";
|
|
@@ -1515,7 +1515,7 @@ var addStandaloneNodeToScene = (state, nodeData, position) => {
|
|
|
1515
1515
|
scaleTween.start();
|
|
1516
1516
|
}
|
|
1517
1517
|
};
|
|
1518
|
-
var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
|
|
1518
|
+
var getParentFileInfoForNode = (allParentData, sceneData, nodeId, sceneConfigId = null, sceneOwnerId = null) => {
|
|
1519
1519
|
const parentDbsArray = (sceneData == null ? void 0 : sceneData.parent_dbs) || [];
|
|
1520
1520
|
for (const parentFileId in allParentData) {
|
|
1521
1521
|
if (allParentData.hasOwnProperty(parentFileId)) {
|
|
@@ -1524,6 +1524,8 @@ var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
|
|
|
1524
1524
|
const parentDbInfo = parentDbsArray.find((db) => String(db.db_id) === String(parentFileId));
|
|
1525
1525
|
if (parentDbInfo) {
|
|
1526
1526
|
return { parentFileId, ownerId: parentDbInfo.owner_id };
|
|
1527
|
+
} else if (sceneConfigId && String(parentFileId) === String(sceneConfigId)) {
|
|
1528
|
+
return { parentFileId, ownerId: sceneOwnerId };
|
|
1527
1529
|
} else {
|
|
1528
1530
|
console.warn(`Owner ID n\xE3o encontrado em sceneData.parent_dbs para o parentFileId: ${parentFileId}`);
|
|
1529
1531
|
return { parentFileId, ownerId: null };
|
|
@@ -1802,7 +1804,7 @@ var userActionHandlers = {
|
|
|
1802
1804
|
version_node: { is_version: true, parent_node: sourceNodeData.id }
|
|
1803
1805
|
};
|
|
1804
1806
|
const newLink = { id: `link_${short.generate()}`, source: sourceNodeData.id, target: newNode.id };
|
|
1805
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
|
|
1807
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
|
|
1806
1808
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
1807
1809
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:", sourceNodeData.id);
|
|
1808
1810
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
|
|
@@ -1978,7 +1980,7 @@ var userActionHandlers = {
|
|
|
1978
1980
|
userActionHandlers.handleCancelConnection(context);
|
|
1979
1981
|
return;
|
|
1980
1982
|
}
|
|
1981
|
-
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
|
|
1983
|
+
const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
|
|
1982
1984
|
if (!sourceParentInfo || !sourceParentInfo.ownerId) {
|
|
1983
1985
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:", sourceNodeData.id);
|
|
1984
1986
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
|
|
@@ -2067,8 +2069,8 @@ var userActionHandlers = {
|
|
|
2067
2069
|
} else {
|
|
2068
2070
|
newTargetId = newEndNodeData.id;
|
|
2069
2071
|
}
|
|
2070
|
-
const originalParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId);
|
|
2071
|
-
const newParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId);
|
|
2072
|
+
const originalParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId, context.sceneConfigId, context.ownerId);
|
|
2073
|
+
const newParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId, context.sceneConfigId, context.ownerId);
|
|
2072
2074
|
if (!originalParentInfo || !newParentInfo || !originalParentInfo.ownerId || !newParentInfo.ownerId) {
|
|
2073
2075
|
console.error("N\xE3o foi poss\xEDvel encontrar informa\xE7\xF5es dos arquivos pai para o relink.");
|
|
2074
2076
|
alert("Ocorreu um erro ao identificar os arquivos pai para salvar a altera\xE7\xE3o.");
|
|
@@ -2136,7 +2138,7 @@ var userActionHandlers = {
|
|
|
2136
2138
|
console.error("Tentativa de deletar um link sem ID.", linkObject.userData);
|
|
2137
2139
|
return;
|
|
2138
2140
|
}
|
|
2139
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source);
|
|
2141
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source, context.sceneConfigId, context.ownerId);
|
|
2140
2142
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2141
2143
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link:", linkIdToDelete);
|
|
2142
2144
|
alert("Ocorreu um erro ao identificar o arquivo pai da rela\xE7\xE3o para exclus\xE3o.");
|
|
@@ -2148,9 +2150,24 @@ var userActionHandlers = {
|
|
|
2148
2150
|
const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
|
|
2149
2151
|
const newLinks = (specificParentData.links || []).filter((l) => String(l.id) !== String(linkIdToDelete));
|
|
2150
2152
|
specificParentData.links = newLinks;
|
|
2151
|
-
|
|
2153
|
+
let filenameToSave;
|
|
2154
|
+
let payloadToSave;
|
|
2155
|
+
if (parentFileId === context.sceneConfigId) {
|
|
2156
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2157
|
+
sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => String(l.id) !== String(linkIdToDelete));
|
|
2158
|
+
payloadToSave = {
|
|
2159
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2160
|
+
nodes: sceneDataRef.current.nodes,
|
|
2161
|
+
links: sceneDataRef.current.links,
|
|
2162
|
+
quest_nodes: specificParentData.nodes,
|
|
2163
|
+
quest_links: specificParentData.links
|
|
2164
|
+
};
|
|
2165
|
+
} else {
|
|
2166
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2167
|
+
payloadToSave = specificParentData;
|
|
2168
|
+
}
|
|
2152
2169
|
try {
|
|
2153
|
-
await context.actions.save_view_data(
|
|
2170
|
+
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2154
2171
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2155
2172
|
setters.setDetailsLink((prev) => String(prev == null ? void 0 : prev.id) === String(linkIdToDelete) ? null : prev);
|
|
2156
2173
|
if (stateRef.current.hoveredLink === linkObject) {
|
|
@@ -2313,7 +2330,7 @@ var userActionHandlers = {
|
|
|
2313
2330
|
}
|
|
2314
2331
|
const changesByParentFile = {};
|
|
2315
2332
|
for (const nodeId of strNodeIdsToDelete) {
|
|
2316
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId);
|
|
2333
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId, context.sceneConfigId, context.ownerId);
|
|
2317
2334
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2318
2335
|
console.warn(`Node com ID ${nodeId} n\xE3o encontrado ou sem ownerId. Ignorando.`);
|
|
2319
2336
|
continue;
|
|
@@ -2347,8 +2364,26 @@ var userActionHandlers = {
|
|
|
2347
2364
|
originalData.links = (originalData.links || []).filter(
|
|
2348
2365
|
(l) => !linksToDelete.has(String(l.id))
|
|
2349
2366
|
);
|
|
2350
|
-
|
|
2351
|
-
|
|
2367
|
+
let filenameToSave;
|
|
2368
|
+
let payloadToSave;
|
|
2369
|
+
if (parentFileId === context.sceneConfigId) {
|
|
2370
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2371
|
+
const strNodesToDelete = Array.from(nodesToDelete).map(String);
|
|
2372
|
+
const strLinksToDelete = Array.from(linksToDelete).map(String);
|
|
2373
|
+
sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter((n) => !strNodesToDelete.includes(String(n.id)));
|
|
2374
|
+
sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => !strLinksToDelete.includes(String(l.id)));
|
|
2375
|
+
payloadToSave = {
|
|
2376
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2377
|
+
nodes: sceneDataRef.current.nodes,
|
|
2378
|
+
links: sceneDataRef.current.links,
|
|
2379
|
+
quest_nodes: originalData.nodes,
|
|
2380
|
+
quest_links: originalData.links
|
|
2381
|
+
};
|
|
2382
|
+
} else {
|
|
2383
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2384
|
+
payloadToSave = originalData;
|
|
2385
|
+
}
|
|
2386
|
+
savePromises.push(context.actions.save_view_data(filenameToSave, payloadToSave));
|
|
2352
2387
|
updatedParentDataCache[parentFileId] = originalData;
|
|
2353
2388
|
}
|
|
2354
2389
|
}
|
|
@@ -2380,7 +2415,7 @@ var userActionHandlers = {
|
|
|
2380
2415
|
if (!nodeData || !graphDataRef.current || !sceneDataRef.current) return;
|
|
2381
2416
|
const nodeIdToDelete = nodeData.id;
|
|
2382
2417
|
const strNodeId = String(nodeIdToDelete);
|
|
2383
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete);
|
|
2418
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete, context.sceneConfigId, context.ownerId);
|
|
2384
2419
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2385
2420
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node a ser exclu\xEDdo:", nodeIdToDelete);
|
|
2386
2421
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para exclus\xE3o.");
|
|
@@ -2392,9 +2427,27 @@ var userActionHandlers = {
|
|
|
2392
2427
|
const newLinks = (specificParentData.links || []).filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
|
|
2393
2428
|
specificParentData.nodes = newNodes;
|
|
2394
2429
|
specificParentData.links = newLinks;
|
|
2395
|
-
|
|
2430
|
+
let filenameToSave;
|
|
2431
|
+
let payloadToSave;
|
|
2432
|
+
if (parentFileId === context.sceneConfigId) {
|
|
2433
|
+
filenameToSave = context.sceneSaveUrl;
|
|
2434
|
+
const newVisualNodes = sceneDataRef.current.nodes.filter((n) => String(n.id) !== strNodeId);
|
|
2435
|
+
const newVisualLinks = sceneDataRef.current.links.filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
|
|
2436
|
+
sceneDataRef.current.nodes = newVisualNodes;
|
|
2437
|
+
sceneDataRef.current.links = newVisualLinks;
|
|
2438
|
+
payloadToSave = {
|
|
2439
|
+
parent_dbs: sceneDataRef.current.parent_dbs,
|
|
2440
|
+
nodes: newVisualNodes,
|
|
2441
|
+
links: newVisualLinks,
|
|
2442
|
+
quest_nodes: specificParentData.nodes,
|
|
2443
|
+
quest_links: specificParentData.links
|
|
2444
|
+
};
|
|
2445
|
+
} else {
|
|
2446
|
+
filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
|
|
2447
|
+
payloadToSave = specificParentData;
|
|
2448
|
+
}
|
|
2396
2449
|
try {
|
|
2397
|
-
await context.actions.save_view_data(
|
|
2450
|
+
await context.actions.save_view_data(filenameToSave, payloadToSave);
|
|
2398
2451
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2399
2452
|
setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeIdToDelete) ? null : prev);
|
|
2400
2453
|
removeNodeFromScene(stateRef.current, nodeIdToDelete);
|
|
@@ -2408,7 +2461,7 @@ var userActionHandlers = {
|
|
|
2408
2461
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2409
2462
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2410
2463
|
const { _baseEmissiveIntensity: ignored, ...nodeToSave } = updatedNode;
|
|
2411
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id);
|
|
2464
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id, context.sceneConfigId, context.ownerId);
|
|
2412
2465
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2413
2466
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node a ser atualizado:", nodeToSave.id);
|
|
2414
2467
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
|
|
@@ -2442,7 +2495,7 @@ var userActionHandlers = {
|
|
|
2442
2495
|
const { graphDataRef, sceneDataRef, stateRef, setters } = context;
|
|
2443
2496
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
2444
2497
|
const { sourceNode, targetNode, ...linkToSave } = updatedLink;
|
|
2445
|
-
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source);
|
|
2498
|
+
const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source, context.sceneConfigId, context.ownerId);
|
|
2446
2499
|
if (!parentInfo || !parentInfo.ownerId) {
|
|
2447
2500
|
console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link a ser atualizado:", linkToSave.id);
|
|
2448
2501
|
alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
|
|
@@ -7835,9 +7888,180 @@ function InSceneVersionForm({
|
|
|
7835
7888
|
));
|
|
7836
7889
|
}
|
|
7837
7890
|
|
|
7891
|
+
// src/components/InSceneQuestForm.jsx
|
|
7892
|
+
import React15, { useState as useState16, useRef as useRef12 } from "react";
|
|
7893
|
+
import { FiPlus as FiPlus5, FiCheck as FiCheck9, FiEdit2 as FiEdit26, FiTarget, FiX as FiX4 } from "react-icons/fi";
|
|
7894
|
+
var QUEST_STATUS_COLORS = {
|
|
7895
|
+
"Backlog": "#64748b",
|
|
7896
|
+
// Slate (Cinza azulado)
|
|
7897
|
+
"In Progress": "#eab308",
|
|
7898
|
+
// Yellow (Amarelo)
|
|
7899
|
+
"Review": "#a855f7",
|
|
7900
|
+
// Purple (Roxo)
|
|
7901
|
+
"Done": "#22c55e"
|
|
7902
|
+
// Green (Verde)
|
|
7903
|
+
};
|
|
7904
|
+
function InSceneQuestForm({
|
|
7905
|
+
onSave,
|
|
7906
|
+
onCancel,
|
|
7907
|
+
style,
|
|
7908
|
+
refEl,
|
|
7909
|
+
onOpenImageViewer,
|
|
7910
|
+
availableNodes = [],
|
|
7911
|
+
availableAncestries = [],
|
|
7912
|
+
onMentionClick,
|
|
7913
|
+
onUploadFile
|
|
7914
|
+
}) {
|
|
7915
|
+
const [name, setName] = useState16("");
|
|
7916
|
+
const [types, setTypes] = useState16(["quest"]);
|
|
7917
|
+
const [typeInput, setTypeInput] = useState16("");
|
|
7918
|
+
const [status, setStatus] = useState16("Backlog");
|
|
7919
|
+
const [size, setSize] = useState16("medium");
|
|
7920
|
+
const [intensity, setIntensity] = useState16(0);
|
|
7921
|
+
const [description, setDescription] = useState16("");
|
|
7922
|
+
const [customProps, setCustomProps] = useState16([]);
|
|
7923
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState16(false);
|
|
7924
|
+
const propsEndRef = useRef12(null);
|
|
7925
|
+
const handleAddProp = () => {
|
|
7926
|
+
const newProp = createNewCustomProperty(customProps);
|
|
7927
|
+
setCustomProps([...customProps, newProp]);
|
|
7928
|
+
setTimeout(() => {
|
|
7929
|
+
var _a;
|
|
7930
|
+
(_a = propsEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
7931
|
+
}, 100);
|
|
7932
|
+
};
|
|
7933
|
+
const handleRemoveProp = (index) => setCustomProps(customProps.filter((_, i) => i !== index));
|
|
7934
|
+
const handleUpdateProp = (index, updatedProp) => {
|
|
7935
|
+
const newProps = [...customProps];
|
|
7936
|
+
newProps[index] = updatedProp;
|
|
7937
|
+
setCustomProps(newProps);
|
|
7938
|
+
};
|
|
7939
|
+
const handleAddType = (newType) => {
|
|
7940
|
+
const trimmed = newType.trim();
|
|
7941
|
+
if (trimmed && !types.includes(trimmed)) {
|
|
7942
|
+
setTypes([...types, trimmed]);
|
|
7943
|
+
setTypeInput("");
|
|
7944
|
+
}
|
|
7945
|
+
};
|
|
7946
|
+
const handleRemoveType = (indexToRemove) => {
|
|
7947
|
+
if (types[indexToRemove] === "quest") return;
|
|
7948
|
+
setTypes(types.filter((_, index) => index !== indexToRemove));
|
|
7949
|
+
};
|
|
7950
|
+
const handleTypeInputKeyDown = (e) => {
|
|
7951
|
+
if (e.key === "Enter") {
|
|
7952
|
+
e.preventDefault();
|
|
7953
|
+
handleAddType(typeInput);
|
|
7954
|
+
} else if (e.key === "Backspace" && typeInput === "" && types.length > 1) {
|
|
7955
|
+
handleRemoveType(types.length - 1);
|
|
7956
|
+
}
|
|
7957
|
+
};
|
|
7958
|
+
const handleSubmit = (e) => {
|
|
7959
|
+
e.preventDefault();
|
|
7960
|
+
if (!name.trim()) {
|
|
7961
|
+
alert("O campo 'Nome' \xE9 obrigat\xF3rio.");
|
|
7962
|
+
return;
|
|
7963
|
+
}
|
|
7964
|
+
const additionalData = toObjectFromCustomProps(
|
|
7965
|
+
customProps.filter((prop) => prop.key.trim() && !prop.isEditing)
|
|
7966
|
+
);
|
|
7967
|
+
const processedSections = processDescriptionForSave(description, []);
|
|
7968
|
+
onSave({
|
|
7969
|
+
name: name.trim(),
|
|
7970
|
+
type: types,
|
|
7971
|
+
color: QUEST_STATUS_COLORS[status],
|
|
7972
|
+
// Cor atrelada ao status
|
|
7973
|
+
status,
|
|
7974
|
+
size,
|
|
7975
|
+
intensity,
|
|
7976
|
+
description: description.trim(),
|
|
7977
|
+
description_sections: processedSections,
|
|
7978
|
+
useImageAsTexture: false,
|
|
7979
|
+
textureImageUrl: null,
|
|
7980
|
+
...additionalData
|
|
7981
|
+
});
|
|
7982
|
+
};
|
|
7983
|
+
const swallow = (e) => e.stopPropagation();
|
|
7984
|
+
const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
|
|
7985
|
+
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
7986
|
+
return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
|
|
7987
|
+
"div",
|
|
7988
|
+
{
|
|
7989
|
+
ref: refEl,
|
|
7990
|
+
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",
|
|
7991
|
+
style,
|
|
7992
|
+
onPointerDown: swallow,
|
|
7993
|
+
onClick: swallow,
|
|
7994
|
+
onWheel: swallow,
|
|
7995
|
+
onContextMenu: swallow,
|
|
7996
|
+
onDoubleClick: swallow
|
|
7997
|
+
},
|
|
7998
|
+
/* @__PURE__ */ React15.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS[status]}, transparent)` } }),
|
|
7999
|
+
/* @__PURE__ */ React15.createElement("div", { className: "px-6 pt-5 pb-3" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React15.createElement(FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ React15.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova Tarefa / Objetivo")), /* @__PURE__ */ React15.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")),
|
|
8000
|
+
/* @__PURE__ */ React15.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col max-h-[68vh]" }, /* @__PURE__ */ React15.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ React15.createElement(
|
|
8001
|
+
"select",
|
|
8002
|
+
{
|
|
8003
|
+
value: status,
|
|
8004
|
+
onChange: (e) => setStatus(e.target.value),
|
|
8005
|
+
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",
|
|
8006
|
+
style: { borderLeft: `4px solid ${QUEST_STATUS_COLORS[status]}` }
|
|
8007
|
+
},
|
|
8008
|
+
/* @__PURE__ */ React15.createElement("option", { value: "Backlog" }, "Backlog"),
|
|
8009
|
+
/* @__PURE__ */ React15.createElement("option", { value: "In Progress" }, "In Progress"),
|
|
8010
|
+
/* @__PURE__ */ React15.createElement("option", { value: "Review" }, "Review"),
|
|
8011
|
+
/* @__PURE__ */ React15.createElement("option", { value: "Done" }, "Done")
|
|
8012
|
+
)), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Quest"), /* @__PURE__ */ React15.createElement("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__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tipos Adicionais"), /* @__PURE__ */ React15.createElement("div", { className: "relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 focus-within:ring-2 focus-within:ring-indigo-400/60 transition-all" }, types.map((t, index) => /* @__PURE__ */ React15.createElement("span", { key: index, className: `flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-medium border ${t === "quest" ? "bg-sky-500/20 text-sky-200 border-sky-500/30" : "bg-indigo-500/30 text-indigo-100 border-indigo-500/20"}` }, t, t !== "quest" && /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => handleRemoveType(index), className: "hover:text-white transition-colors" }, /* @__PURE__ */ React15.createElement(FiX4, { size: 12 })))), /* @__PURE__ */ React15.createElement(
|
|
8013
|
+
"input",
|
|
8014
|
+
{
|
|
8015
|
+
type: "text",
|
|
8016
|
+
value: typeInput,
|
|
8017
|
+
onChange: (e) => setTypeInput(e.target.value),
|
|
8018
|
+
onKeyDown: handleTypeInputKeyDown,
|
|
8019
|
+
onBlur: () => {
|
|
8020
|
+
if (typeInput.trim()) handleAddType(typeInput);
|
|
8021
|
+
},
|
|
8022
|
+
className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
|
|
8023
|
+
autoComplete: "off"
|
|
8024
|
+
}
|
|
8025
|
+
))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ React15.createElement("div", { className: "relative group min-h-[80px] bg-slate-800/70 p-2.5 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React15.createElement(
|
|
8026
|
+
DescriptionDisplay,
|
|
8027
|
+
{
|
|
8028
|
+
description,
|
|
8029
|
+
savedSections: [],
|
|
8030
|
+
availableNodes,
|
|
8031
|
+
availableAncestries,
|
|
8032
|
+
onMentionClick,
|
|
8033
|
+
onSaveDescription: (newDesc) => setDescription(newDesc)
|
|
8034
|
+
}
|
|
8035
|
+
), /* @__PURE__ */ React15.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiEdit26, { size: 14 }))), !description && /* @__PURE__ */ React15.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Cen\xE1rio (Size)"), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ React15.createElement("button", { key: s, type: "button", onClick: () => setSize(s), className: "flex items-center gap-2 group cursor-pointer focus:outline-none" }, /* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${size === s ? "bg-indigo-500 border-indigo-500" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, size === s && /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12, className: "text-white" })), /* @__PURE__ */ React15.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s))))), /* @__PURE__ */ React15.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React15.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiPlus5, { size: 14 }), " Adicionar")), /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ React15.createElement(
|
|
8036
|
+
CustomPropertyDisplay,
|
|
8037
|
+
{
|
|
8038
|
+
key: prop.id,
|
|
8039
|
+
prop,
|
|
8040
|
+
onUpdate: (updatedProp) => handleUpdateProp(index, updatedProp),
|
|
8041
|
+
onRemove: () => handleRemoveProp(index),
|
|
8042
|
+
onOpenImageViewer,
|
|
8043
|
+
unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type),
|
|
8044
|
+
onUploadFile
|
|
8045
|
+
}
|
|
8046
|
+
)), /* @__PURE__ */ React15.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ React15.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__ */ React15.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__ */ React15.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")))
|
|
8047
|
+
), isDescriptionModalOpen && /* @__PURE__ */ React15.createElement(
|
|
8048
|
+
DescriptionEditModal,
|
|
8049
|
+
{
|
|
8050
|
+
isOpen: isDescriptionModalOpen,
|
|
8051
|
+
title: "Editar Descri\xE7\xE3o da Quest",
|
|
8052
|
+
initialValue: description,
|
|
8053
|
+
onSave: (newDescription) => setDescription(newDescription),
|
|
8054
|
+
onClose: () => setIsDescriptionModalOpen(false),
|
|
8055
|
+
availableNodes,
|
|
8056
|
+
availableAncestries,
|
|
8057
|
+
availableImages
|
|
8058
|
+
}
|
|
8059
|
+
));
|
|
8060
|
+
}
|
|
8061
|
+
|
|
7838
8062
|
// src/components/NodeDetailsPanel.jsx
|
|
7839
|
-
import
|
|
7840
|
-
import { FiPlus as
|
|
8063
|
+
import React16, { useState as useState17, useEffect as useEffect15, useRef as useRef13 } from "react";
|
|
8064
|
+
import { FiPlus as FiPlus6, FiMaximize2 as FiMaximize23, FiX as FiX5, FiCheck as FiCheck10, FiImage as FiImage3, FiEdit2 as FiEdit27, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5, FiDatabase } from "react-icons/fi";
|
|
7841
8065
|
function NodeDetailsPanel({
|
|
7842
8066
|
node,
|
|
7843
8067
|
onClose,
|
|
@@ -7858,27 +8082,27 @@ function NodeDetailsPanel({
|
|
|
7858
8082
|
userRole,
|
|
7859
8083
|
currentDatasetName
|
|
7860
8084
|
}) {
|
|
7861
|
-
const [name, setName] =
|
|
7862
|
-
const [types, setTypes] =
|
|
7863
|
-
const [typeInput, setTypeInput] =
|
|
7864
|
-
const [color, setColor] =
|
|
7865
|
-
const [size, setSize] =
|
|
7866
|
-
const [description, setDescription] =
|
|
7867
|
-
const [intensity, setIntensity] =
|
|
7868
|
-
const [customProps, setCustomProps] =
|
|
7869
|
-
const [showTypeSuggestions, setShowTypeSuggestions] =
|
|
7870
|
-
const [filteredTypes, setFilteredTypes] =
|
|
7871
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
7872
|
-
const [isReadMode, setIsReadMode] =
|
|
7873
|
-
const [existingSections, setExistingSections] =
|
|
7874
|
-
const [isSaving, setIsSaving] =
|
|
7875
|
-
const [isLinkCopied, setIsLinkCopied] =
|
|
7876
|
-
const [useImageAsTexture, setUseImageAsTexture] =
|
|
8085
|
+
const [name, setName] = useState17((node == null ? void 0 : node.name) ?? "");
|
|
8086
|
+
const [types, setTypes] = useState17([]);
|
|
8087
|
+
const [typeInput, setTypeInput] = useState17("");
|
|
8088
|
+
const [color, setColor] = useState17((node == null ? void 0 : node.color) ?? "#8b5cf6");
|
|
8089
|
+
const [size, setSize] = useState17((node == null ? void 0 : node.size) ?? "medium");
|
|
8090
|
+
const [description, setDescription] = useState17((node == null ? void 0 : node.description) ?? "");
|
|
8091
|
+
const [intensity, setIntensity] = useState17((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
|
|
8092
|
+
const [customProps, setCustomProps] = useState17(() => extractCustomPropsFromNode(node || {}));
|
|
8093
|
+
const [showTypeSuggestions, setShowTypeSuggestions] = useState17(false);
|
|
8094
|
+
const [filteredTypes, setFilteredTypes] = useState17([]);
|
|
8095
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState17(false);
|
|
8096
|
+
const [isReadMode, setIsReadMode] = useState17(false);
|
|
8097
|
+
const [existingSections, setExistingSections] = useState17((node == null ? void 0 : node.description_sections) || []);
|
|
8098
|
+
const [isSaving, setIsSaving] = useState17(false);
|
|
8099
|
+
const [isLinkCopied, setIsLinkCopied] = useState17(false);
|
|
8100
|
+
const [useImageAsTexture, setUseImageAsTexture] = useState17(() => {
|
|
7877
8101
|
if ((node == null ? void 0 : node.useImageAsTexture) === "true") return true;
|
|
7878
8102
|
if ((node == null ? void 0 : node.useImageAsTexture) === "false") return false;
|
|
7879
8103
|
return !!(node == null ? void 0 : node.useImageAsTexture);
|
|
7880
8104
|
});
|
|
7881
|
-
const [selectedImageUrl, setSelectedImageUrl] =
|
|
8105
|
+
const [selectedImageUrl, setSelectedImageUrl] = useState17((node == null ? void 0 : node.textureImageUrl) ?? null);
|
|
7882
8106
|
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
7883
8107
|
const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
|
|
7884
8108
|
initialWidth: isReadMode ? 700 : 440,
|
|
@@ -7888,8 +8112,8 @@ function NodeDetailsPanel({
|
|
|
7888
8112
|
useEffect15(() => {
|
|
7889
8113
|
setWidth(isReadMode ? 700 : 440);
|
|
7890
8114
|
}, [isReadMode, setWidth]);
|
|
7891
|
-
const prevNodeIdRef =
|
|
7892
|
-
const propsEndRef =
|
|
8115
|
+
const prevNodeIdRef = useRef13(null);
|
|
8116
|
+
const propsEndRef = useRef13(null);
|
|
7893
8117
|
const canEdit = userRole !== "viewer";
|
|
7894
8118
|
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
7895
8119
|
const handleImageClickFromText = (url, name2) => {
|
|
@@ -8097,7 +8321,7 @@ function NodeDetailsPanel({
|
|
|
8097
8321
|
onClose();
|
|
8098
8322
|
};
|
|
8099
8323
|
const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
|
|
8100
|
-
return /* @__PURE__ */
|
|
8324
|
+
return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(
|
|
8101
8325
|
"div",
|
|
8102
8326
|
{
|
|
8103
8327
|
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"}`,
|
|
@@ -8110,7 +8334,7 @@ function NodeDetailsPanel({
|
|
|
8110
8334
|
onContextMenu: swallow,
|
|
8111
8335
|
onDoubleClick: swallow
|
|
8112
8336
|
},
|
|
8113
|
-
/* @__PURE__ */
|
|
8337
|
+
/* @__PURE__ */ React16.createElement(
|
|
8114
8338
|
"div",
|
|
8115
8339
|
{
|
|
8116
8340
|
onPointerDown: (e) => {
|
|
@@ -8121,7 +8345,7 @@ function NodeDetailsPanel({
|
|
|
8121
8345
|
title: "Arraste para redimensionar"
|
|
8122
8346
|
}
|
|
8123
8347
|
),
|
|
8124
|
-
isReadMode ? /* @__PURE__ */
|
|
8348
|
+
isReadMode ? /* @__PURE__ */ React16.createElement(
|
|
8125
8349
|
DescriptionReadModePanel,
|
|
8126
8350
|
{
|
|
8127
8351
|
title: name || (node == null ? void 0 : node.name),
|
|
@@ -8142,23 +8366,23 @@ function NodeDetailsPanel({
|
|
|
8142
8366
|
onImageClick: handleImageClickFromText,
|
|
8143
8367
|
onSaveDescription: handleSaveDescriptionInline
|
|
8144
8368
|
}
|
|
8145
|
-
) : /* @__PURE__ */
|
|
8369
|
+
) : /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ React16.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React16.createElement("div", null, /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React16.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__ */ React16.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ React16.createElement(
|
|
8146
8370
|
"button",
|
|
8147
8371
|
{
|
|
8148
8372
|
onClick: handleCopyLink,
|
|
8149
8373
|
className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
|
|
8150
8374
|
title: isLinkCopied ? "Link Copiado!" : "Copiar link para este Node"
|
|
8151
8375
|
},
|
|
8152
|
-
isLinkCopied ? /* @__PURE__ */
|
|
8153
|
-
)), /* @__PURE__ */
|
|
8376
|
+
isLinkCopied ? /* @__PURE__ */ React16.createElement(FiCheck10, { size: 12 }) : /* @__PURE__ */ React16.createElement(FiLink5, { size: 12 })
|
|
8377
|
+
)), /* @__PURE__ */ React16.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ React16.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__ */ React16.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300" }, "Tipos"), /* @__PURE__ */ React16.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__ */ React16.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__ */ React16.createElement(
|
|
8154
8378
|
"button",
|
|
8155
8379
|
{
|
|
8156
8380
|
type: "button",
|
|
8157
8381
|
onClick: () => handleRemoveType(index),
|
|
8158
8382
|
className: "hover:text-white transition-colors"
|
|
8159
8383
|
},
|
|
8160
|
-
/* @__PURE__ */
|
|
8161
|
-
))), canEdit && /* @__PURE__ */
|
|
8384
|
+
/* @__PURE__ */ React16.createElement(FiX5, { size: 12 })
|
|
8385
|
+
))), canEdit && /* @__PURE__ */ React16.createElement(
|
|
8162
8386
|
"input",
|
|
8163
8387
|
{
|
|
8164
8388
|
type: "text",
|
|
@@ -8179,7 +8403,7 @@ function NodeDetailsPanel({
|
|
|
8179
8403
|
placeholder: types.length === 0 ? "Ex.: Cliente" : "",
|
|
8180
8404
|
autoComplete: "off"
|
|
8181
8405
|
}
|
|
8182
|
-
), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */
|
|
8406
|
+
), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */ React16.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__ */ React16.createElement(
|
|
8183
8407
|
"li",
|
|
8184
8408
|
{
|
|
8185
8409
|
key: index,
|
|
@@ -8190,7 +8414,7 @@ function NodeDetailsPanel({
|
|
|
8190
8414
|
}
|
|
8191
8415
|
},
|
|
8192
8416
|
suggestedType
|
|
8193
|
-
))))), /* @__PURE__ */
|
|
8417
|
+
))))), /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300" }, "Nome"), /* @__PURE__ */ React16.createElement(
|
|
8194
8418
|
"input",
|
|
8195
8419
|
{
|
|
8196
8420
|
type: "text",
|
|
@@ -8199,7 +8423,7 @@ function NodeDetailsPanel({
|
|
|
8199
8423
|
readOnly: !canEdit,
|
|
8200
8424
|
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"}`
|
|
8201
8425
|
}
|
|
8202
|
-
)), /* @__PURE__ */
|
|
8426
|
+
)), /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React16.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__ */ React16.createElement(
|
|
8203
8427
|
DescriptionDisplay,
|
|
8204
8428
|
{
|
|
8205
8429
|
description,
|
|
@@ -8211,7 +8435,7 @@ function NodeDetailsPanel({
|
|
|
8211
8435
|
onImageClick: handleImageClickFromText,
|
|
8212
8436
|
onSaveDescription: handleSaveDescriptionInline
|
|
8213
8437
|
}
|
|
8214
|
-
), /* @__PURE__ */
|
|
8438
|
+
), /* @__PURE__ */ React16.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__ */ React16.createElement(
|
|
8215
8439
|
"button",
|
|
8216
8440
|
{
|
|
8217
8441
|
type: "button",
|
|
@@ -8219,8 +8443,8 @@ function NodeDetailsPanel({
|
|
|
8219
8443
|
className: `p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors ${canEdit ? "border-r border-white/5" : ""}`,
|
|
8220
8444
|
title: "Modo de Leitura"
|
|
8221
8445
|
},
|
|
8222
|
-
/* @__PURE__ */
|
|
8223
|
-
), canEdit && /* @__PURE__ */
|
|
8446
|
+
/* @__PURE__ */ React16.createElement(FiBookOpen3, { size: 14 })
|
|
8447
|
+
), canEdit && /* @__PURE__ */ React16.createElement(
|
|
8224
8448
|
"button",
|
|
8225
8449
|
{
|
|
8226
8450
|
type: "button",
|
|
@@ -8228,17 +8452,17 @@ function NodeDetailsPanel({
|
|
|
8228
8452
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8229
8453
|
title: "Editar descri\xE7\xE3o (Modo de Escrita)"
|
|
8230
8454
|
},
|
|
8231
|
-
/* @__PURE__ */
|
|
8232
|
-
)), canEdit && !description && /* @__PURE__ */
|
|
8455
|
+
/* @__PURE__ */ React16.createElement(FiEdit27, { size: 14 })
|
|
8456
|
+
)), canEdit && !description && /* @__PURE__ */ React16.createElement(
|
|
8233
8457
|
"div",
|
|
8234
8458
|
{
|
|
8235
8459
|
onClick: () => setIsDescriptionModalOpen(true),
|
|
8236
8460
|
className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
|
|
8237
8461
|
},
|
|
8238
8462
|
"Adicionar descri\xE7\xE3o..."
|
|
8239
|
-
))), /* @__PURE__ */
|
|
8463
|
+
))), /* @__PURE__ */ React16.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300" }, "Size"), /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
|
|
8240
8464
|
const isSelected = size === s;
|
|
8241
|
-
return /* @__PURE__ */
|
|
8465
|
+
return /* @__PURE__ */ React16.createElement(
|
|
8242
8466
|
"button",
|
|
8243
8467
|
{
|
|
8244
8468
|
key: s,
|
|
@@ -8246,10 +8470,10 @@ function NodeDetailsPanel({
|
|
|
8246
8470
|
onClick: () => canEdit && handleSizeChange(s),
|
|
8247
8471
|
className: `flex items-center gap-2 group focus:outline-none ${canEdit ? "cursor-pointer" : "cursor-default opacity-80"}`
|
|
8248
8472
|
},
|
|
8249
|
-
/* @__PURE__ */
|
|
8250
|
-
/* @__PURE__ */
|
|
8473
|
+
/* @__PURE__ */ React16.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__ */ React16.createElement(FiCheck10, { size: 12, className: "text-white" })),
|
|
8474
|
+
/* @__PURE__ */ React16.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s)
|
|
8251
8475
|
);
|
|
8252
|
-
}))), /* @__PURE__ */
|
|
8476
|
+
}))), /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React16.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), canEdit && hasImages && /* @__PURE__ */ React16.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ React16.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__ */ React16.createElement(FiCheck10, { size: 12, className: "text-white" })), /* @__PURE__ */ React16.createElement(
|
|
8253
8477
|
"input",
|
|
8254
8478
|
{
|
|
8255
8479
|
type: "checkbox",
|
|
@@ -8257,14 +8481,14 @@ function NodeDetailsPanel({
|
|
|
8257
8481
|
onChange: handleToggleImageMode,
|
|
8258
8482
|
className: "hidden"
|
|
8259
8483
|
}
|
|
8260
|
-
), /* @__PURE__ */
|
|
8484
|
+
), /* @__PURE__ */ React16.createElement("span", { className: `text-xs ${useImageAsTexture ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, "Usar imagem para representar o node"))), /* @__PURE__ */ React16.createElement(
|
|
8261
8485
|
ColorPicker,
|
|
8262
8486
|
{
|
|
8263
8487
|
color,
|
|
8264
8488
|
onChange: handleColorChange,
|
|
8265
8489
|
disabled: !canEdit || useImageAsTexture
|
|
8266
8490
|
}
|
|
8267
|
-
), /* @__PURE__ */
|
|
8491
|
+
), /* @__PURE__ */ React16.createElement("div", { className: "mt-3 flex items-center gap-3" }, /* @__PURE__ */ React16.createElement(FiSun2, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ React16.createElement(
|
|
8268
8492
|
"input",
|
|
8269
8493
|
{
|
|
8270
8494
|
type: "range",
|
|
@@ -8277,7 +8501,7 @@ function NodeDetailsPanel({
|
|
|
8277
8501
|
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"}`,
|
|
8278
8502
|
title: `Intensidade do brilho: ${intensity}`
|
|
8279
8503
|
}
|
|
8280
|
-
), /* @__PURE__ */
|
|
8504
|
+
), /* @__PURE__ */ React16.createElement("span", { className: "text-xs text-slate-400 w-6 text-right" }, intensity)), /* @__PURE__ */ React16.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__ */ React16.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React16.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React16.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ React16.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__ */ React16.createElement(FiPlus6, { size: 14 }), " Adicionar")), /* @__PURE__ */ React16.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ React16.createElement(
|
|
8281
8505
|
CustomPropertyDisplay,
|
|
8282
8506
|
{
|
|
8283
8507
|
key: prop.id,
|
|
@@ -8292,7 +8516,7 @@ function NodeDetailsPanel({
|
|
|
8292
8516
|
onUploadFile: canEdit ? onUploadFile : void 0,
|
|
8293
8517
|
readOnly: !canEdit
|
|
8294
8518
|
}
|
|
8295
|
-
)), /* @__PURE__ */
|
|
8519
|
+
)), /* @__PURE__ */ React16.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ React16.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__ */ React16.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ React16.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ React16.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__ */ React16.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__ */ React16.createElement(
|
|
8296
8520
|
"button",
|
|
8297
8521
|
{
|
|
8298
8522
|
onClick: () => handleSave(false),
|
|
@@ -8301,10 +8525,10 @@ function NodeDetailsPanel({
|
|
|
8301
8525
|
${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"}
|
|
8302
8526
|
`
|
|
8303
8527
|
},
|
|
8304
|
-
isSaving && /* @__PURE__ */
|
|
8528
|
+
isSaving && /* @__PURE__ */ React16.createElement(FiLoader2, { className: "animate-spin" }),
|
|
8305
8529
|
isSaving ? "Salvando..." : "Salvar"
|
|
8306
8530
|
)))
|
|
8307
|
-
), isDescriptionModalOpen && canEdit && /* @__PURE__ */
|
|
8531
|
+
), isDescriptionModalOpen && canEdit && /* @__PURE__ */ React16.createElement(
|
|
8308
8532
|
DescriptionEditModal,
|
|
8309
8533
|
{
|
|
8310
8534
|
isOpen: isDescriptionModalOpen,
|
|
@@ -8324,7 +8548,7 @@ function NodeDetailsPanel({
|
|
|
8324
8548
|
}
|
|
8325
8549
|
|
|
8326
8550
|
// src/components/MultiNodeContextMenu.jsx
|
|
8327
|
-
import
|
|
8551
|
+
import React17, { useLayoutEffect as useLayoutEffect3, useRef as useRef14, useState as useState18, useEffect as useEffect16 } from "react";
|
|
8328
8552
|
function MultiNodeContextMenu({
|
|
8329
8553
|
data,
|
|
8330
8554
|
userRole,
|
|
@@ -8333,9 +8557,9 @@ function MultiNodeContextMenu({
|
|
|
8333
8557
|
onDismissOtherNodes,
|
|
8334
8558
|
onDeleteNodes
|
|
8335
8559
|
}) {
|
|
8336
|
-
const menuRef =
|
|
8337
|
-
const [menuPos, setMenuPos] =
|
|
8338
|
-
const [isConfirmingDelete, setIsConfirmingDelete] =
|
|
8560
|
+
const menuRef = useRef14(null);
|
|
8561
|
+
const [menuPos, setMenuPos] = useState18({ left: 0, top: 0 });
|
|
8562
|
+
const [isConfirmingDelete, setIsConfirmingDelete] = useState18(false);
|
|
8339
8563
|
const ability = defineAbilityFor(userRole);
|
|
8340
8564
|
const canDelete = ability.can("delete", "Node");
|
|
8341
8565
|
useLayoutEffect3(() => {
|
|
@@ -8366,7 +8590,7 @@ function MultiNodeContextMenu({
|
|
|
8366
8590
|
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";
|
|
8367
8591
|
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";
|
|
8368
8592
|
const nodeCount = data.nodeIds.size;
|
|
8369
|
-
return /* @__PURE__ */
|
|
8593
|
+
return /* @__PURE__ */ React17.createElement(
|
|
8370
8594
|
"div",
|
|
8371
8595
|
{
|
|
8372
8596
|
ref: menuRef,
|
|
@@ -8380,28 +8604,28 @@ function MultiNodeContextMenu({
|
|
|
8380
8604
|
onContextMenu: swallow,
|
|
8381
8605
|
onDoubleClick: swallow
|
|
8382
8606
|
},
|
|
8383
|
-
/* @__PURE__ */
|
|
8384
|
-
/* @__PURE__ */
|
|
8607
|
+
/* @__PURE__ */ React17.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
|
|
8608
|
+
/* @__PURE__ */ React17.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React17.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ React17.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__ */ React17.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React17.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__ */ React17.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ React17.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ React17.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__ */ React17.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React17.createElement(
|
|
8385
8609
|
"button",
|
|
8386
8610
|
{
|
|
8387
8611
|
onClick: () => setIsConfirmingDelete(false),
|
|
8388
8612
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
|
|
8389
8613
|
},
|
|
8390
8614
|
"Cancelar"
|
|
8391
|
-
), /* @__PURE__ */
|
|
8615
|
+
), /* @__PURE__ */ React17.createElement(
|
|
8392
8616
|
"button",
|
|
8393
8617
|
{
|
|
8394
8618
|
onClick: () => onDeleteNodes(data.nodeIds),
|
|
8395
8619
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
|
|
8396
8620
|
},
|
|
8397
8621
|
"Excluir"
|
|
8398
|
-
))) : /* @__PURE__ */
|
|
8622
|
+
))) : /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React17.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__ */ React17.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React17.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ React17.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__ */ React17.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ React17.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__ */ React17.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__ */ React17.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ React17.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ React17.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ React17.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__ */ React17.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ React17.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ React17.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React17.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ React17.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ React17.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React17.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ React17.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__ */ React17.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React17.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__ */ React17.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ React17.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ React17.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
|
|
8399
8623
|
);
|
|
8400
8624
|
}
|
|
8401
8625
|
|
|
8402
8626
|
// src/components/RelationshipDetailsPanel.jsx
|
|
8403
|
-
import
|
|
8404
|
-
import { FiPlus as
|
|
8627
|
+
import React18, { useState as useState19, useEffect as useEffect17, useRef as useRef15, useMemo as useMemo9 } from "react";
|
|
8628
|
+
import { FiPlus as FiPlus7, FiEdit2 as FiEdit28, FiLoader as FiLoader3, FiBookOpen as FiBookOpen4 } from "react-icons/fi";
|
|
8405
8629
|
function RelationshipDetailsPanel({
|
|
8406
8630
|
link,
|
|
8407
8631
|
onClose,
|
|
@@ -8415,14 +8639,14 @@ function RelationshipDetailsPanel({
|
|
|
8415
8639
|
onUploadFile,
|
|
8416
8640
|
userRole
|
|
8417
8641
|
}) {
|
|
8418
|
-
const [name, setName] =
|
|
8419
|
-
const [description, setDescription] =
|
|
8420
|
-
const [customProps, setCustomProps] =
|
|
8421
|
-
const [existingSections, setExistingSections] =
|
|
8422
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
8423
|
-
const [isSaving, setIsSaving] =
|
|
8424
|
-
const [isReadMode, setIsReadMode] =
|
|
8425
|
-
const propsEndRef =
|
|
8642
|
+
const [name, setName] = useState19((link == null ? void 0 : link.name) ?? "");
|
|
8643
|
+
const [description, setDescription] = useState19((link == null ? void 0 : link.description) ?? "");
|
|
8644
|
+
const [customProps, setCustomProps] = useState19(() => extractCustomPropsFromNode(link || {}));
|
|
8645
|
+
const [existingSections, setExistingSections] = useState19((link == null ? void 0 : link.description_sections) || []);
|
|
8646
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState19(false);
|
|
8647
|
+
const [isSaving, setIsSaving] = useState19(false);
|
|
8648
|
+
const [isReadMode, setIsReadMode] = useState19(false);
|
|
8649
|
+
const propsEndRef = useRef15(null);
|
|
8426
8650
|
const canEdit = useMemo9(() => {
|
|
8427
8651
|
const ability = defineAbilityFor(userRole);
|
|
8428
8652
|
return ability.can("update", "Connection");
|
|
@@ -8502,7 +8726,7 @@ function RelationshipDetailsPanel({
|
|
|
8502
8726
|
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
8503
8727
|
}
|
|
8504
8728
|
};
|
|
8505
|
-
return /* @__PURE__ */
|
|
8729
|
+
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(
|
|
8506
8730
|
"div",
|
|
8507
8731
|
{
|
|
8508
8732
|
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
|
|
@@ -8517,7 +8741,7 @@ function RelationshipDetailsPanel({
|
|
|
8517
8741
|
onContextMenu: swallow,
|
|
8518
8742
|
onDoubleClick: swallow
|
|
8519
8743
|
},
|
|
8520
|
-
isReadMode ? /* @__PURE__ */
|
|
8744
|
+
isReadMode ? /* @__PURE__ */ React18.createElement(
|
|
8521
8745
|
DescriptionReadModePanel,
|
|
8522
8746
|
{
|
|
8523
8747
|
title: name || "Rela\xE7\xE3o",
|
|
@@ -8538,7 +8762,7 @@ function RelationshipDetailsPanel({
|
|
|
8538
8762
|
onImageClick: handleImageClickFromText,
|
|
8539
8763
|
onSaveDescription: handleSaveDescriptionInline
|
|
8540
8764
|
}
|
|
8541
|
-
) : /* @__PURE__ */
|
|
8765
|
+
) : /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ React18.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React18.createElement("div", null, /* @__PURE__ */ React18.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React18.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__ */ React18.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ React18.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ React18.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__ */ React18.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ React18.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React18.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ React18.createElement(
|
|
8542
8766
|
"input",
|
|
8543
8767
|
{
|
|
8544
8768
|
type: "text",
|
|
@@ -8550,7 +8774,7 @@ function RelationshipDetailsPanel({
|
|
|
8550
8774
|
${!canEdit ? "opacity-50 cursor-not-allowed" : ""}
|
|
8551
8775
|
`
|
|
8552
8776
|
}
|
|
8553
|
-
)), /* @__PURE__ */
|
|
8777
|
+
)), /* @__PURE__ */ React18.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React18.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React18.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__ */ React18.createElement(
|
|
8554
8778
|
DescriptionDisplay,
|
|
8555
8779
|
{
|
|
8556
8780
|
description,
|
|
@@ -8562,7 +8786,7 @@ function RelationshipDetailsPanel({
|
|
|
8562
8786
|
onImageClick: handleImageClickFromText,
|
|
8563
8787
|
onSaveDescription: handleSaveDescriptionInline
|
|
8564
8788
|
}
|
|
8565
|
-
), /* @__PURE__ */
|
|
8789
|
+
), /* @__PURE__ */ React18.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__ */ React18.createElement(
|
|
8566
8790
|
"button",
|
|
8567
8791
|
{
|
|
8568
8792
|
type: "button",
|
|
@@ -8570,8 +8794,8 @@ function RelationshipDetailsPanel({
|
|
|
8570
8794
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors border-r border-white/5",
|
|
8571
8795
|
title: "Modo de Leitura"
|
|
8572
8796
|
},
|
|
8573
|
-
/* @__PURE__ */
|
|
8574
|
-
), canEdit && /* @__PURE__ */
|
|
8797
|
+
/* @__PURE__ */ React18.createElement(FiBookOpen4, { size: 14 })
|
|
8798
|
+
), canEdit && /* @__PURE__ */ React18.createElement(
|
|
8575
8799
|
"button",
|
|
8576
8800
|
{
|
|
8577
8801
|
type: "button",
|
|
@@ -8579,15 +8803,15 @@ function RelationshipDetailsPanel({
|
|
|
8579
8803
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8580
8804
|
title: "Editar descri\xE7\xE3o"
|
|
8581
8805
|
},
|
|
8582
|
-
/* @__PURE__ */
|
|
8583
|
-
)), !description && canEdit && /* @__PURE__ */
|
|
8806
|
+
/* @__PURE__ */ React18.createElement(FiEdit28, { size: 14 })
|
|
8807
|
+
)), !description && canEdit && /* @__PURE__ */ React18.createElement(
|
|
8584
8808
|
"div",
|
|
8585
8809
|
{
|
|
8586
8810
|
onClick: () => setIsDescriptionModalOpen(true),
|
|
8587
8811
|
className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
|
|
8588
8812
|
},
|
|
8589
8813
|
"Adicionar descri\xE7\xE3o..."
|
|
8590
|
-
))), /* @__PURE__ */
|
|
8814
|
+
))), /* @__PURE__ */ React18.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React18.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React18.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ React18.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__ */ React18.createElement(FiPlus7, { size: 14 }), " Adicionar")), /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ React18.createElement(
|
|
8591
8815
|
CustomPropertyDisplay,
|
|
8592
8816
|
{
|
|
8593
8817
|
key: prop.id,
|
|
@@ -8599,7 +8823,7 @@ function RelationshipDetailsPanel({
|
|
|
8599
8823
|
onUploadFile,
|
|
8600
8824
|
disabled: !canEdit
|
|
8601
8825
|
}
|
|
8602
|
-
)), /* @__PURE__ */
|
|
8826
|
+
)), /* @__PURE__ */ React18.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ React18.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__ */ React18.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__ */ React18.createElement(
|
|
8603
8827
|
"button",
|
|
8604
8828
|
{
|
|
8605
8829
|
onClick: () => handleSave(false),
|
|
@@ -8608,10 +8832,10 @@ function RelationshipDetailsPanel({
|
|
|
8608
8832
|
${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"}
|
|
8609
8833
|
`
|
|
8610
8834
|
},
|
|
8611
|
-
isSaving && /* @__PURE__ */
|
|
8835
|
+
isSaving && /* @__PURE__ */ React18.createElement(FiLoader3, { className: "animate-spin" }),
|
|
8612
8836
|
isSaving ? "Salvando..." : "Salvar"
|
|
8613
8837
|
)))
|
|
8614
|
-
), isDescriptionModalOpen && /* @__PURE__ */
|
|
8838
|
+
), isDescriptionModalOpen && /* @__PURE__ */ React18.createElement(
|
|
8615
8839
|
DescriptionEditModal,
|
|
8616
8840
|
{
|
|
8617
8841
|
isOpen: isDescriptionModalOpen,
|
|
@@ -8632,7 +8856,7 @@ function RelationshipDetailsPanel({
|
|
|
8632
8856
|
}
|
|
8633
8857
|
|
|
8634
8858
|
// src/components/RelationshipContextMenu.jsx
|
|
8635
|
-
import
|
|
8859
|
+
import React19, { useLayoutEffect as useLayoutEffect4, useRef as useRef16, useState as useState20, useEffect as useEffect18, useMemo as useMemo10 } from "react";
|
|
8636
8860
|
function RelationshipContextMenu({
|
|
8637
8861
|
data,
|
|
8638
8862
|
userRole,
|
|
@@ -8642,9 +8866,9 @@ function RelationshipContextMenu({
|
|
|
8642
8866
|
onDelete,
|
|
8643
8867
|
onClose
|
|
8644
8868
|
}) {
|
|
8645
|
-
const menuRef =
|
|
8646
|
-
const [menuPos, setMenuPos] =
|
|
8647
|
-
const [isConfirmingDelete, setIsConfirmingDelete] =
|
|
8869
|
+
const menuRef = useRef16(null);
|
|
8870
|
+
const [menuPos, setMenuPos] = useState20({ left: 0, top: 0 });
|
|
8871
|
+
const [isConfirmingDelete, setIsConfirmingDelete] = useState20(false);
|
|
8648
8872
|
const ability = useMemo10(() => defineAbilityFor(userRole), [userRole]);
|
|
8649
8873
|
const sourceName = useMemo10(
|
|
8650
8874
|
() => {
|
|
@@ -8689,7 +8913,7 @@ function RelationshipContextMenu({
|
|
|
8689
8913
|
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";
|
|
8690
8914
|
const canUpdate = ability.can("update", "Connection");
|
|
8691
8915
|
const canDelete = ability.can("delete", "Connection");
|
|
8692
|
-
return /* @__PURE__ */
|
|
8916
|
+
return /* @__PURE__ */ React19.createElement(
|
|
8693
8917
|
"div",
|
|
8694
8918
|
{
|
|
8695
8919
|
ref: menuRef,
|
|
@@ -8703,29 +8927,29 @@ function RelationshipContextMenu({
|
|
|
8703
8927
|
onContextMenu: swallow,
|
|
8704
8928
|
onDoubleClick: swallow
|
|
8705
8929
|
},
|
|
8706
|
-
/* @__PURE__ */
|
|
8707
|
-
/* @__PURE__ */
|
|
8930
|
+
/* @__PURE__ */ React19.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
|
|
8931
|
+
/* @__PURE__ */ React19.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React19.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ React19.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__ */ React19.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React19.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ React19.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ React19.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ React19.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ React19.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ React19.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ React19.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ React19.createElement("strong", null, targetName), ".")), /* @__PURE__ */ React19.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React19.createElement(
|
|
8708
8932
|
"button",
|
|
8709
8933
|
{
|
|
8710
8934
|
onClick: () => setIsConfirmingDelete(false),
|
|
8711
8935
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
|
|
8712
8936
|
},
|
|
8713
8937
|
"Cancelar"
|
|
8714
|
-
), /* @__PURE__ */
|
|
8938
|
+
), /* @__PURE__ */ React19.createElement(
|
|
8715
8939
|
"button",
|
|
8716
8940
|
{
|
|
8717
8941
|
onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
|
|
8718
8942
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-rose-600 hover:bg-rose-500 rounded-md text-white transition-colors"
|
|
8719
8943
|
},
|
|
8720
8944
|
"Excluir"
|
|
8721
|
-
))) : /* @__PURE__ */
|
|
8945
|
+
))) : /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React19.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__ */ React19.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(
|
|
8722
8946
|
"button",
|
|
8723
8947
|
{
|
|
8724
8948
|
onClick: () => onRelinkSource == null ? void 0 : onRelinkSource(data.linkObject),
|
|
8725
8949
|
className: baseButtonClass,
|
|
8726
8950
|
title: "Desconectar ponta ligada ao Source"
|
|
8727
8951
|
},
|
|
8728
|
-
/* @__PURE__ */
|
|
8952
|
+
/* @__PURE__ */ React19.createElement(
|
|
8729
8953
|
"svg",
|
|
8730
8954
|
{
|
|
8731
8955
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8738,18 +8962,18 @@ function RelationshipContextMenu({
|
|
|
8738
8962
|
strokeLinecap: "round",
|
|
8739
8963
|
strokeLinejoin: "round"
|
|
8740
8964
|
},
|
|
8741
|
-
/* @__PURE__ */
|
|
8742
|
-
/* @__PURE__ */
|
|
8965
|
+
/* @__PURE__ */ React19.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" }),
|
|
8966
|
+
/* @__PURE__ */ React19.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" })
|
|
8743
8967
|
),
|
|
8744
|
-
/* @__PURE__ */
|
|
8745
|
-
), /* @__PURE__ */
|
|
8968
|
+
/* @__PURE__ */ React19.createElement("span", null, "Desconectar Source (", sourceName, ")")
|
|
8969
|
+
), /* @__PURE__ */ React19.createElement(
|
|
8746
8970
|
"button",
|
|
8747
8971
|
{
|
|
8748
8972
|
onClick: () => onRelinkTarget == null ? void 0 : onRelinkTarget(data.linkObject),
|
|
8749
8973
|
className: baseButtonClass,
|
|
8750
8974
|
title: "Desconectar ponta ligada ao Target"
|
|
8751
8975
|
},
|
|
8752
|
-
/* @__PURE__ */
|
|
8976
|
+
/* @__PURE__ */ React19.createElement(
|
|
8753
8977
|
"svg",
|
|
8754
8978
|
{
|
|
8755
8979
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8762,21 +8986,21 @@ function RelationshipContextMenu({
|
|
|
8762
8986
|
strokeLinecap: "round",
|
|
8763
8987
|
strokeLinejoin: "round"
|
|
8764
8988
|
},
|
|
8765
|
-
/* @__PURE__ */
|
|
8766
|
-
/* @__PURE__ */
|
|
8767
|
-
/* @__PURE__ */
|
|
8768
|
-
/* @__PURE__ */
|
|
8769
|
-
/* @__PURE__ */
|
|
8989
|
+
/* @__PURE__ */ React19.createElement("polyline", { points: "16 3 21 3 21 8" }),
|
|
8990
|
+
/* @__PURE__ */ React19.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
|
|
8991
|
+
/* @__PURE__ */ React19.createElement("polyline", { points: "21 16 21 21 16 21" }),
|
|
8992
|
+
/* @__PURE__ */ React19.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
|
|
8993
|
+
/* @__PURE__ */ React19.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
|
|
8770
8994
|
),
|
|
8771
|
-
/* @__PURE__ */
|
|
8772
|
-
), /* @__PURE__ */
|
|
8995
|
+
/* @__PURE__ */ React19.createElement("span", null, "Desconectar Target (", targetName, ")")
|
|
8996
|
+
), /* @__PURE__ */ React19.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ React19.createElement(
|
|
8773
8997
|
"button",
|
|
8774
8998
|
{
|
|
8775
8999
|
onClick: () => onOpenDetails == null ? void 0 : onOpenDetails(data.linkObject),
|
|
8776
9000
|
className: baseButtonClass,
|
|
8777
9001
|
title: "Abrir detalhes da rela\xE7\xE3o"
|
|
8778
9002
|
},
|
|
8779
|
-
/* @__PURE__ */
|
|
9003
|
+
/* @__PURE__ */ React19.createElement(
|
|
8780
9004
|
"svg",
|
|
8781
9005
|
{
|
|
8782
9006
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8789,19 +9013,19 @@ function RelationshipContextMenu({
|
|
|
8789
9013
|
strokeLinecap: "round",
|
|
8790
9014
|
strokeLinejoin: "round"
|
|
8791
9015
|
},
|
|
8792
|
-
/* @__PURE__ */
|
|
8793
|
-
/* @__PURE__ */
|
|
8794
|
-
/* @__PURE__ */
|
|
9016
|
+
/* @__PURE__ */ React19.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
9017
|
+
/* @__PURE__ */ React19.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
9018
|
+
/* @__PURE__ */ React19.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
|
|
8795
9019
|
),
|
|
8796
|
-
/* @__PURE__ */
|
|
8797
|
-
), canDelete && /* @__PURE__ */
|
|
9020
|
+
/* @__PURE__ */ React19.createElement("span", null, "Abrir Detalhes")
|
|
9021
|
+
), canDelete && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ React19.createElement(
|
|
8798
9022
|
"button",
|
|
8799
9023
|
{
|
|
8800
9024
|
onClick: () => setIsConfirmingDelete(true),
|
|
8801
9025
|
className: dangerButtonClass,
|
|
8802
9026
|
title: "Excluir esta conex\xE3o"
|
|
8803
9027
|
},
|
|
8804
|
-
/* @__PURE__ */
|
|
9028
|
+
/* @__PURE__ */ React19.createElement(
|
|
8805
9029
|
"svg",
|
|
8806
9030
|
{
|
|
8807
9031
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8814,19 +9038,19 @@ function RelationshipContextMenu({
|
|
|
8814
9038
|
strokeLinecap: "round",
|
|
8815
9039
|
strokeLinejoin: "round"
|
|
8816
9040
|
},
|
|
8817
|
-
/* @__PURE__ */
|
|
8818
|
-
/* @__PURE__ */
|
|
8819
|
-
/* @__PURE__ */
|
|
8820
|
-
/* @__PURE__ */
|
|
8821
|
-
/* @__PURE__ */
|
|
9041
|
+
/* @__PURE__ */ React19.createElement("polyline", { points: "3 6 5 6 21 6" }),
|
|
9042
|
+
/* @__PURE__ */ React19.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
|
|
9043
|
+
/* @__PURE__ */ React19.createElement("path", { d: "M10 11v6" }),
|
|
9044
|
+
/* @__PURE__ */ React19.createElement("path", { d: "M14 11v6" }),
|
|
9045
|
+
/* @__PURE__ */ React19.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
|
|
8822
9046
|
),
|
|
8823
|
-
/* @__PURE__ */
|
|
9047
|
+
/* @__PURE__ */ React19.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
|
|
8824
9048
|
)))))
|
|
8825
9049
|
);
|
|
8826
9050
|
}
|
|
8827
9051
|
|
|
8828
9052
|
// src/components/LoadingScreen.jsx
|
|
8829
|
-
import
|
|
9053
|
+
import React20 from "react";
|
|
8830
9054
|
var styles = {
|
|
8831
9055
|
loadingOverlay: {
|
|
8832
9056
|
position: "fixed",
|
|
@@ -8858,11 +9082,11 @@ var styles = {
|
|
|
8858
9082
|
`
|
|
8859
9083
|
};
|
|
8860
9084
|
function LoadingScreen() {
|
|
8861
|
-
return /* @__PURE__ */
|
|
9085
|
+
return /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement("style", null, styles.keyframes), /* @__PURE__ */ React20.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ React20.createElement("div", { style: styles.spinner })));
|
|
8862
9086
|
}
|
|
8863
9087
|
|
|
8864
9088
|
// src/components/ImportParentFileModal.jsx
|
|
8865
|
-
import
|
|
9089
|
+
import React21, { useEffect as useEffect19, useState as useState21 } from "react";
|
|
8866
9090
|
function ImportParentFileModal({
|
|
8867
9091
|
isOpen,
|
|
8868
9092
|
onClose,
|
|
@@ -8873,11 +9097,11 @@ function ImportParentFileModal({
|
|
|
8873
9097
|
onFetchAvailableFiles,
|
|
8874
9098
|
currentViewName
|
|
8875
9099
|
}) {
|
|
8876
|
-
const [activeTab, setActiveTab] =
|
|
8877
|
-
const [availableDbs, setAvailableDbs] =
|
|
8878
|
-
const [availableViews, setAvailableViews] =
|
|
8879
|
-
const [selectedItem, setSelectedItem] =
|
|
8880
|
-
const [isLoading, setIsLoading] =
|
|
9100
|
+
const [activeTab, setActiveTab] = useState21("databases");
|
|
9101
|
+
const [availableDbs, setAvailableDbs] = useState21([]);
|
|
9102
|
+
const [availableViews, setAvailableViews] = useState21([]);
|
|
9103
|
+
const [selectedItem, setSelectedItem] = useState21(null);
|
|
9104
|
+
const [isLoading, setIsLoading] = useState21(false);
|
|
8881
9105
|
useEffect19(() => {
|
|
8882
9106
|
if (isOpen && session && onFetchAvailableFiles) {
|
|
8883
9107
|
const fetchData = async () => {
|
|
@@ -8943,13 +9167,13 @@ function ImportParentFileModal({
|
|
|
8943
9167
|
const swallow = (e) => e.stopPropagation();
|
|
8944
9168
|
const currentList = activeTab === "databases" ? availableDbs : availableViews;
|
|
8945
9169
|
const emptyMessage = activeTab === "databases" ? "Nenhum novo arquivo parent dispon\xEDvel." : "Nenhuma view dispon\xEDvel para importa\xE7\xE3o.";
|
|
8946
|
-
return /* @__PURE__ */
|
|
9170
|
+
return /* @__PURE__ */ React21.createElement(
|
|
8947
9171
|
"div",
|
|
8948
9172
|
{
|
|
8949
9173
|
className: "ui-overlay fixed inset-0 z-[1200] flex items-center justify-center bg-black/60 backdrop-blur-sm",
|
|
8950
9174
|
onClick: onClose
|
|
8951
9175
|
},
|
|
8952
|
-
/* @__PURE__ */
|
|
9176
|
+
/* @__PURE__ */ React21.createElement(
|
|
8953
9177
|
"div",
|
|
8954
9178
|
{
|
|
8955
9179
|
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]",
|
|
@@ -8961,14 +9185,14 @@ function ImportParentFileModal({
|
|
|
8961
9185
|
onContextMenu: swallow,
|
|
8962
9186
|
onDoubleClick: swallow
|
|
8963
9187
|
},
|
|
8964
|
-
/* @__PURE__ */
|
|
9188
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ React21.createElement(
|
|
8965
9189
|
"button",
|
|
8966
9190
|
{
|
|
8967
9191
|
onClick: onClose,
|
|
8968
9192
|
className: "p-2 rounded-md text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8969
9193
|
title: "Fechar"
|
|
8970
9194
|
},
|
|
8971
|
-
/* @__PURE__ */
|
|
9195
|
+
/* @__PURE__ */ React21.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React21.createElement(
|
|
8972
9196
|
"path",
|
|
8973
9197
|
{
|
|
8974
9198
|
fillRule: "evenodd",
|
|
@@ -8977,14 +9201,14 @@ function ImportParentFileModal({
|
|
|
8977
9201
|
}
|
|
8978
9202
|
))
|
|
8979
9203
|
)),
|
|
8980
|
-
/* @__PURE__ */
|
|
9204
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ React21.createElement(
|
|
8981
9205
|
"button",
|
|
8982
9206
|
{
|
|
8983
9207
|
onClick: () => setActiveTab("databases"),
|
|
8984
9208
|
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"}`
|
|
8985
9209
|
},
|
|
8986
9210
|
"Arquivos Parent"
|
|
8987
|
-
), /* @__PURE__ */
|
|
9211
|
+
), /* @__PURE__ */ React21.createElement(
|
|
8988
9212
|
"button",
|
|
8989
9213
|
{
|
|
8990
9214
|
onClick: () => setActiveTab("views"),
|
|
@@ -8992,24 +9216,24 @@ function ImportParentFileModal({
|
|
|
8992
9216
|
},
|
|
8993
9217
|
"Views (Ancestralidades)"
|
|
8994
9218
|
)),
|
|
8995
|
-
/* @__PURE__ */
|
|
9219
|
+
/* @__PURE__ */ React21.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ React21.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ React21.createElement(
|
|
8996
9220
|
"div",
|
|
8997
9221
|
{
|
|
8998
9222
|
key: item.id,
|
|
8999
9223
|
onClick: () => setSelectedItem(item),
|
|
9000
9224
|
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"}`
|
|
9001
9225
|
},
|
|
9002
|
-
/* @__PURE__ */
|
|
9003
|
-
item.description && /* @__PURE__ */
|
|
9004
|
-
)) : /* @__PURE__ */
|
|
9005
|
-
/* @__PURE__ */
|
|
9226
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ React21.createElement("span", { className: "text-[10px] px-1.5 py-0.5 rounded bg-black/30 text-indigo-300 border border-indigo-500/30" }, "VIEW")),
|
|
9227
|
+
item.description && /* @__PURE__ */ React21.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
|
|
9228
|
+
)) : /* @__PURE__ */ React21.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
|
|
9229
|
+
/* @__PURE__ */ React21.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__ */ React21.createElement(
|
|
9006
9230
|
"button",
|
|
9007
9231
|
{
|
|
9008
9232
|
onClick: onClose,
|
|
9009
9233
|
className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm text-slate-300"
|
|
9010
9234
|
},
|
|
9011
9235
|
"Cancelar"
|
|
9012
|
-
), /* @__PURE__ */
|
|
9236
|
+
), /* @__PURE__ */ React21.createElement(
|
|
9013
9237
|
"button",
|
|
9014
9238
|
{
|
|
9015
9239
|
onClick: handleConfirm,
|
|
@@ -9023,7 +9247,7 @@ function ImportParentFileModal({
|
|
|
9023
9247
|
}
|
|
9024
9248
|
|
|
9025
9249
|
// src/components/AncestryLinkDetailsPanel.jsx
|
|
9026
|
-
import
|
|
9250
|
+
import React22, { useState as useState22 } from "react";
|
|
9027
9251
|
import { FiBookOpen as FiBookOpen5 } from "react-icons/fi";
|
|
9028
9252
|
function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
|
|
9029
9253
|
var _a, _b, _c, _d;
|
|
@@ -9033,21 +9257,21 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9033
9257
|
const customProps = extractCustomPropsFromNode(relationshipData);
|
|
9034
9258
|
const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
|
|
9035
9259
|
const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
|
|
9036
|
-
const [isReadMode, setIsReadMode] =
|
|
9260
|
+
const [isReadMode, setIsReadMode] = useState22(false);
|
|
9037
9261
|
const swallow = (e) => e.stopPropagation();
|
|
9038
9262
|
const handleImageClickFromText = (url, name) => {
|
|
9039
9263
|
if (onOpenImageViewer) {
|
|
9040
9264
|
onOpenImageViewer([{ name: name || "Imagem", value: url }], 0);
|
|
9041
9265
|
}
|
|
9042
9266
|
};
|
|
9043
|
-
return /* @__PURE__ */
|
|
9267
|
+
return /* @__PURE__ */ React22.createElement(
|
|
9044
9268
|
"div",
|
|
9045
9269
|
{
|
|
9046
9270
|
className: "ui-overlay fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[1200]",
|
|
9047
9271
|
onClick: onClose,
|
|
9048
9272
|
onPointerDown: swallow
|
|
9049
9273
|
},
|
|
9050
|
-
/* @__PURE__ */
|
|
9274
|
+
/* @__PURE__ */ React22.createElement(
|
|
9051
9275
|
"div",
|
|
9052
9276
|
{
|
|
9053
9277
|
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
|
|
@@ -9055,7 +9279,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9055
9279
|
`,
|
|
9056
9280
|
onClick: swallow
|
|
9057
9281
|
},
|
|
9058
|
-
isReadMode ? /* @__PURE__ */
|
|
9282
|
+
isReadMode ? /* @__PURE__ */ React22.createElement(
|
|
9059
9283
|
DescriptionReadModePanel,
|
|
9060
9284
|
{
|
|
9061
9285
|
title: `${sourceName} \u2794 ${targetName}`,
|
|
@@ -9067,15 +9291,15 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9067
9291
|
onMentionClick,
|
|
9068
9292
|
onImageClick: handleImageClickFromText
|
|
9069
9293
|
}
|
|
9070
|
-
) : /* @__PURE__ */
|
|
9294
|
+
) : /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ React22.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React22.createElement("div", null, /* @__PURE__ */ React22.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React22.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__ */ React22.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ React22.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ React22.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ React22.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ React22.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ React22.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__ */ React22.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ React22.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React22.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React22.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React22.createElement(
|
|
9071
9295
|
"button",
|
|
9072
9296
|
{
|
|
9073
9297
|
onClick: () => setIsReadMode(true),
|
|
9074
9298
|
className: "p-1 text-slate-400 hover:text-white transition-colors",
|
|
9075
9299
|
title: "Modo de Leitura"
|
|
9076
9300
|
},
|
|
9077
|
-
/* @__PURE__ */
|
|
9078
|
-
)), /* @__PURE__ */
|
|
9301
|
+
/* @__PURE__ */ React22.createElement(FiBookOpen5, { size: 14 })
|
|
9302
|
+
)), /* @__PURE__ */ React22.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ React22.createElement(
|
|
9079
9303
|
DescriptionDisplay,
|
|
9080
9304
|
{
|
|
9081
9305
|
description,
|
|
@@ -9084,7 +9308,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9084
9308
|
onMentionClick,
|
|
9085
9309
|
onImageClick: handleImageClickFromText
|
|
9086
9310
|
}
|
|
9087
|
-
))), customProps.length > 0 && /* @__PURE__ */
|
|
9311
|
+
))), customProps.length > 0 && /* @__PURE__ */ React22.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React22.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ React22.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ React22.createElement(
|
|
9088
9312
|
CustomPropertyDisplay,
|
|
9089
9313
|
{
|
|
9090
9314
|
key: prop.id,
|
|
@@ -9093,25 +9317,25 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9093
9317
|
onOpenImageViewer,
|
|
9094
9318
|
onUploadFile
|
|
9095
9319
|
}
|
|
9096
|
-
)))), !description && customProps.length === 0 && /* @__PURE__ */
|
|
9320
|
+
)))), !description && customProps.length === 0 && /* @__PURE__ */ React22.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__ */ React22.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".')))
|
|
9097
9321
|
)
|
|
9098
9322
|
);
|
|
9099
9323
|
}
|
|
9100
9324
|
|
|
9101
9325
|
// src/components/AncestryBoard.jsx
|
|
9102
|
-
import
|
|
9326
|
+
import React23, { useState as useState23, useMemo as useMemo11, useEffect as useEffect20, useRef as useRef17 } from "react";
|
|
9103
9327
|
import {
|
|
9104
9328
|
FiSearch as FiSearch4,
|
|
9105
9329
|
FiLayers as FiLayers6,
|
|
9106
9330
|
FiCornerUpRight as FiCornerUpRight4,
|
|
9107
9331
|
FiPlay,
|
|
9108
|
-
FiPlus as
|
|
9332
|
+
FiPlus as FiPlus8,
|
|
9109
9333
|
FiTrash2 as FiTrash23,
|
|
9110
9334
|
FiArrowLeft as FiArrowLeft3,
|
|
9111
9335
|
FiArrowRight,
|
|
9112
9336
|
FiCheckCircle,
|
|
9113
9337
|
FiLoader as FiLoader4,
|
|
9114
|
-
FiX as
|
|
9338
|
+
FiX as FiX6,
|
|
9115
9339
|
FiAlertTriangle
|
|
9116
9340
|
} from "react-icons/fi";
|
|
9117
9341
|
var GroupItem = ({
|
|
@@ -9133,7 +9357,7 @@ var GroupItem = ({
|
|
|
9133
9357
|
}) => {
|
|
9134
9358
|
const canIndent = index > 0;
|
|
9135
9359
|
const isPickingForThisGroup = pickingGroupId === group.id;
|
|
9136
|
-
const textareaRef =
|
|
9360
|
+
const textareaRef = useRef17(null);
|
|
9137
9361
|
const adjustHeight = () => {
|
|
9138
9362
|
const textarea = textareaRef.current;
|
|
9139
9363
|
if (textarea) {
|
|
@@ -9144,10 +9368,10 @@ var GroupItem = ({
|
|
|
9144
9368
|
useEffect20(() => {
|
|
9145
9369
|
adjustHeight();
|
|
9146
9370
|
}, [group.text]);
|
|
9147
|
-
return /* @__PURE__ */
|
|
9371
|
+
return /* @__PURE__ */ React23.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__ */ React23.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ React23.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__ */ React23.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__ */ React23.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__ */ React23.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__ */ React23.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__ */ React23.createElement(FiPlay, { size: 10, className: "ml-0.5 fill-current" })
|
|
9189
9413
|
)
|
|
9190
|
-
) : /* @__PURE__ */
|
|
9191
|
-
/* @__PURE__ */
|
|
9192
|
-
canEdit && /* @__PURE__ */
|
|
9414
|
+
) : /* @__PURE__ */ React23.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ React23.createElement(FiAlertTriangle, { size: 10 })),
|
|
9415
|
+
/* @__PURE__ */ React23.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
|
|
9416
|
+
canEdit && /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ React23.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__ */ React23.createElement(FiX6, { size: 12 })
|
|
9200
9424
|
))
|
|
9201
9425
|
);
|
|
9202
|
-
})), canEdit && /* @__PURE__ */
|
|
9426
|
+
})), canEdit && /* @__PURE__ */ React23.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__ */ React23.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React23.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__ */ React23.createElement(FiCheckCircle, { size: 12 }) : /* @__PURE__ */ React23.createElement(FiSearch4, { size: 12 }),
|
|
9213
9437
|
isPickingForThisGroup ? "Selecionando..." : "Adicionar"
|
|
9214
|
-
), /* @__PURE__ */
|
|
9438
|
+
), /* @__PURE__ */ React23.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__ */ React23.createElement(FiPlus8, { size: 14 })
|
|
9446
|
+
)), /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React23.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__ */ React23.createElement(FiArrowRight, { size: 14 })
|
|
9455
|
+
), /* @__PURE__ */ React23.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__ */ React23.createElement(FiArrowLeft3, { size: 14 })
|
|
9463
|
+
), /* @__PURE__ */ React23.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ React23.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__ */ React23.createElement(FiTrash23, { size: 14 })
|
|
9471
|
+
)))), group.children && group.children.length > 0 && /* @__PURE__ */ React23.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ React23.createElement(
|
|
9248
9472
|
GroupItem,
|
|
9249
9473
|
{
|
|
9250
9474
|
key: childGroup.id,
|
|
@@ -9276,11 +9500,11 @@ function AncestryBoard({
|
|
|
9276
9500
|
userRole
|
|
9277
9501
|
// [NOVO] Recebe a role do usuário
|
|
9278
9502
|
}) {
|
|
9279
|
-
const [searchTerm, setSearchTerm] =
|
|
9280
|
-
const [groups, setGroups] =
|
|
9281
|
-
const [isLoaded, setIsLoaded] =
|
|
9282
|
-
const [pickingGroupId, setPickingGroupId] =
|
|
9283
|
-
const [saveStatus, setSaveStatus] =
|
|
9503
|
+
const [searchTerm, setSearchTerm] = useState23("");
|
|
9504
|
+
const [groups, setGroups] = useState23([]);
|
|
9505
|
+
const [isLoaded, setIsLoaded] = useState23(false);
|
|
9506
|
+
const [pickingGroupId, setPickingGroupId] = useState23(null);
|
|
9507
|
+
const [saveStatus, setSaveStatus] = useState23("idle");
|
|
9284
9508
|
const canEdit = useMemo11(() => {
|
|
9285
9509
|
return userRole !== "viewer";
|
|
9286
9510
|
}, [userRole]);
|
|
@@ -9488,27 +9712,27 @@ function AncestryBoard({
|
|
|
9488
9712
|
});
|
|
9489
9713
|
};
|
|
9490
9714
|
if (!isOpen) return null;
|
|
9491
|
-
return /* @__PURE__ */
|
|
9715
|
+
return /* @__PURE__ */ React23.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__ */ React23.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__ */ React23.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React23.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ React23.createElement(FiLayers6, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React23.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ React23.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__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(FiLoader4, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ React23.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ React23.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ React23.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ React23.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ React23.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__ */ React23.createElement(FiPlus8, { size: 14, className: "text-indigo-400" }),
|
|
9734
|
+
/* @__PURE__ */ React23.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
|
|
9735
|
+
), /* @__PURE__ */ React23.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__ */ React23.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ React23.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__ */ React23.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ React23.createElement("div", { className: "relative group" }, /* @__PURE__ */ React23.createElement(FiSearch4, { 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__ */ React23.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__ */ React23.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__ */ React23.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__ */ React23.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__ */ React23.createElement(FiPlus8, { size: 16 }) : /* @__PURE__ */ React23.createElement(FiLayers6, { size: 14 })),
|
|
9779
|
+
/* @__PURE__ */ React23.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ React23.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React23.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__ */ React23.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__ */ React23.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__ */ React23.createElement(FiCornerUpRight4, { size: 10 }), /* @__PURE__ */ React23.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ React23.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
|
|
9780
|
+
!isPicking && /* @__PURE__ */ React23.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__ */ React23.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ React23.createElement(FiPlay, { size: 14, className: "ml-0.5" }))
|
|
9567
9791
|
)
|
|
9568
9792
|
);
|
|
9569
|
-
}))), /* @__PURE__ */
|
|
9793
|
+
}))), /* @__PURE__ */ React23.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ React23.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ React23.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__ */ React23.createElement(FiLayers6, { size: 24, className: "opacity-20" }), /* @__PURE__ */ React23.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ React23.createElement(React23.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ React23.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ React23.createElement(React23.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ React23.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__ */ React23.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__ */ React23.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ React23.createElement("span", null, groups.length, " grupos raiz"))
|
|
9590
9814
|
)
|
|
9591
9815
|
);
|
|
9592
9816
|
}
|
|
@@ -9730,44 +9954,45 @@ function XViewScene({
|
|
|
9730
9954
|
}
|
|
9731
9955
|
return null;
|
|
9732
9956
|
}, [ownerId, sceneConfigId]);
|
|
9733
|
-
const sceneDataRef =
|
|
9734
|
-
const parentDataRef =
|
|
9735
|
-
const ancestryDataRef =
|
|
9736
|
-
const [isLoading, setIsLoading] =
|
|
9737
|
-
const [permissionStatus, setPermissionStatus] =
|
|
9738
|
-
const [userPermissionRole, setUserPermissionRole] =
|
|
9739
|
-
const [isInitialized, setIsInitialized] =
|
|
9740
|
-
const [sceneVersion, setSceneVersion] =
|
|
9741
|
-
const [contextMenu, setContextMenu] =
|
|
9742
|
-
const [multiContextMenu, setMultiContextMenu] =
|
|
9743
|
-
const [relationshipMenu, setRelationshipMenu] =
|
|
9744
|
-
const [creationMode, setCreationMode] =
|
|
9745
|
-
const [versionMode, setVersionMode] =
|
|
9746
|
-
const [
|
|
9747
|
-
const [
|
|
9748
|
-
const [
|
|
9749
|
-
const [
|
|
9957
|
+
const sceneDataRef = useRef18(null);
|
|
9958
|
+
const parentDataRef = useRef18(null);
|
|
9959
|
+
const ancestryDataRef = useRef18(null);
|
|
9960
|
+
const [isLoading, setIsLoading] = useState24(true);
|
|
9961
|
+
const [permissionStatus, setPermissionStatus] = useState24("loading");
|
|
9962
|
+
const [userPermissionRole, setUserPermissionRole] = useState24(null);
|
|
9963
|
+
const [isInitialized, setIsInitialized] = useState24(false);
|
|
9964
|
+
const [sceneVersion, setSceneVersion] = useState24(0);
|
|
9965
|
+
const [contextMenu, setContextMenu] = useState24({ visible: false, x: 0, y: 0, nodeData: null });
|
|
9966
|
+
const [multiContextMenu, setMultiContextMenu] = useState24({ visible: false, x: 0, y: 0, nodeIds: null });
|
|
9967
|
+
const [relationshipMenu, setRelationshipMenu] = useState24({ visible: false, x: 0, y: 0, linkObject: null });
|
|
9968
|
+
const [creationMode, setCreationMode] = useState24({ isActive: false, sourceNodeData: null });
|
|
9969
|
+
const [versionMode, setVersionMode] = useState24({ isActive: false, sourceNodeData: null });
|
|
9970
|
+
const [questMode, setQuestMode] = useState24({ isActive: false });
|
|
9971
|
+
const [hasFocusedInitial, setHasFocusedInitial] = useState24(false);
|
|
9972
|
+
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState24(false);
|
|
9973
|
+
const [ancestryMode, setAncestryMode] = useState24({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
9974
|
+
const [readingMode, setReadingMode] = useState24({
|
|
9750
9975
|
isActive: false,
|
|
9751
9976
|
ancestry: null,
|
|
9752
9977
|
branchStack: [],
|
|
9753
9978
|
autoAbstraction: false
|
|
9754
9979
|
});
|
|
9755
|
-
const [formPosition, setFormPosition] =
|
|
9756
|
-
const [detailsNode, setDetailsNode] =
|
|
9757
|
-
const [detailsLink, setDetailsLink] =
|
|
9758
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] =
|
|
9759
|
-
const [imageViewer, setImageViewer] =
|
|
9760
|
-
const [editingAncestryRel, setEditingAncestryRel] =
|
|
9761
|
-
const [isImportModalOpen, setIsImportModalOpen] =
|
|
9762
|
-
const [importSuccessMessage, setImportSuccessMessage] =
|
|
9763
|
-
const [highlightedNodeId, setHighlightedNodeId] =
|
|
9764
|
-
const [isAncestryBoardOpen, setIsAncestryBoardOpen] =
|
|
9765
|
-
const [ancestryBoardData, setAncestryBoardData] =
|
|
9766
|
-
const [isSidebarOpen, setIsSidebarOpen] =
|
|
9767
|
-
const mountRef =
|
|
9768
|
-
const tooltipRef =
|
|
9769
|
-
const formRef =
|
|
9770
|
-
const stateRef =
|
|
9980
|
+
const [formPosition, setFormPosition] = useState24({ left: 16, top: 16, opacity: 0 });
|
|
9981
|
+
const [detailsNode, setDetailsNode] = useState24(null);
|
|
9982
|
+
const [detailsLink, setDetailsLink] = useState24(null);
|
|
9983
|
+
const [ancestryLinkDetails, setAncestryLinkDetails] = useState24(null);
|
|
9984
|
+
const [imageViewer, setImageViewer] = useState24({ visible: false, images: [], startIndex: 0 });
|
|
9985
|
+
const [editingAncestryRel, setEditingAncestryRel] = useState24({ visible: false, data: null, path: null });
|
|
9986
|
+
const [isImportModalOpen, setIsImportModalOpen] = useState24(false);
|
|
9987
|
+
const [importSuccessMessage, setImportSuccessMessage] = useState24("");
|
|
9988
|
+
const [highlightedNodeId, setHighlightedNodeId] = useState24(null);
|
|
9989
|
+
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState24(false);
|
|
9990
|
+
const [ancestryBoardData, setAncestryBoardData] = useState24([]);
|
|
9991
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState24(false);
|
|
9992
|
+
const mountRef = useRef18(null);
|
|
9993
|
+
const tooltipRef = useRef18(null);
|
|
9994
|
+
const formRef = useRef18(null);
|
|
9995
|
+
const stateRef = useRef18({
|
|
9771
9996
|
readMode: {
|
|
9772
9997
|
currentMaxIndex: 0,
|
|
9773
9998
|
progressMap: {}
|
|
@@ -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();
|
|
@@ -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,6 +11576,97 @@ function XViewScene({
|
|
|
11328
11576
|
const handleStartVersioning = (nodeData) => {
|
|
11329
11577
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
11330
11578
|
};
|
|
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: short2.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_${short2.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
|
+
};
|
|
11331
11670
|
const handleClearAncestryVisuals = useCallback4((ancestryId) => {
|
|
11332
11671
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
11333
11672
|
const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
|
|
@@ -12595,6 +12934,7 @@ function XViewScene({
|
|
|
12595
12934
|
[actionHandlerContext]
|
|
12596
12935
|
);
|
|
12597
12936
|
const handleSaveCurrentView = useCallback4(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,17 +12956,22 @@ 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]);
|
|
12974
|
+
}, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
|
|
12630
12975
|
const allAvailableNodes = useMemo12(() => {
|
|
12631
12976
|
if (!parentDataRef.current) return [];
|
|
12632
12977
|
return Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
|
|
@@ -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__ */ React24.createElement(LoadingScreen, null);
|
|
12716
13061
|
}
|
|
12717
13062
|
if (permissionStatus === "denied") {
|
|
12718
|
-
return /* @__PURE__ */
|
|
13063
|
+
return /* @__PURE__ */ React24.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ React24.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ React24.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ React24.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__ */ React24.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__ */ React24.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.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__ */ React24.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
|
|
13388
|
+
/* @__PURE__ */ React24.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__ */ React24.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}`);
|