@lv-x-software-house/x_view 1.2.2-dev.1 → 1.2.2-dev.11
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 +162 -62
- package/dist/index.mjs +164 -64
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -855,7 +855,6 @@ var x_view_config = {
|
|
|
855
855
|
ANCESTOR_HIGHLIGHT_COLOR: "#FFD700",
|
|
856
856
|
BLOOM_EFFECT: { strength: 1.35, radius: 0.6, threshold: 0.52 },
|
|
857
857
|
EMISSIVE_MULTIPLIER: {
|
|
858
|
-
// AJUSTE: Valores agora representam ADIÇÃO de intensidade, não multiplicação
|
|
859
858
|
BASE: 0,
|
|
860
859
|
HOVER: 2,
|
|
861
860
|
SELECTED: 1.5,
|
|
@@ -907,7 +906,6 @@ var computeNodeMaterialProps = (colorHex) => {
|
|
|
907
906
|
return {
|
|
908
907
|
color: srgb,
|
|
909
908
|
emissive: emissiveColor
|
|
910
|
-
// Intensity é controlada externamente
|
|
911
909
|
};
|
|
912
910
|
};
|
|
913
911
|
var createNodeMesh = (nodeData, position, glowTexture) => {
|
|
@@ -1198,6 +1196,7 @@ var createMultipleLinkLines = (linksArray, sourceNodeMesh, targetNodeMesh, resol
|
|
|
1198
1196
|
resolution,
|
|
1199
1197
|
isCurved,
|
|
1200
1198
|
isCurved,
|
|
1199
|
+
isCurved,
|
|
1201
1200
|
curveOffset
|
|
1202
1201
|
);
|
|
1203
1202
|
line.userData = {
|
|
@@ -1574,12 +1573,12 @@ var userActionHandlers = {
|
|
|
1574
1573
|
stateRef.current.creation = { isActive: true, sourceNodeData };
|
|
1575
1574
|
const ghostGeometry = new THREE.SphereGeometry(1.5, 32, 32);
|
|
1576
1575
|
const sourceColor = sourceNodeData.color || "#cccccc";
|
|
1577
|
-
const {
|
|
1578
|
-
const ghostColor = new THREE.Color(sourceColor);
|
|
1576
|
+
const { color: ghostColor, emissive: ghostEmissive } = computeNodeMaterialProps(sourceColor);
|
|
1579
1577
|
const ghostMaterial = new THREE.MeshStandardMaterial({
|
|
1580
1578
|
color: ghostColor,
|
|
1581
|
-
emissive:
|
|
1582
|
-
emissiveIntensity,
|
|
1579
|
+
emissive: ghostEmissive,
|
|
1580
|
+
emissiveIntensity: MIN_VISIBILITY_INTENSITY,
|
|
1581
|
+
// <-- Forçamos o brilho mínimo
|
|
1583
1582
|
roughness: 0.6,
|
|
1584
1583
|
metalness: 0,
|
|
1585
1584
|
transparent: true,
|
|
@@ -1650,27 +1649,50 @@ var userActionHandlers = {
|
|
|
1650
1649
|
setters.setFormPosition((p) => ({ ...p, opacity: 0 }));
|
|
1651
1650
|
},
|
|
1652
1651
|
handleSaveNode: async (context, newNodeData) => {
|
|
1653
|
-
const { graphDataRef, sceneDataRef, stateRef, creationMode, setters } = context;
|
|
1652
|
+
const { graphDataRef, sceneDataRef, stateRef, creationMode, setters, actions } = context;
|
|
1654
1653
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
1655
1654
|
const { sourceNodeData } = creationMode;
|
|
1656
|
-
const
|
|
1655
|
+
const { targetDatasetId, ...nodeDataToSave } = newNodeData;
|
|
1656
|
+
const newNode = { id: import_short_uuid.default.generate(), ...nodeDataToSave };
|
|
1657
1657
|
const newLink = { id: `link_${import_short_uuid.default.generate()}`, source: sourceNodeData.id, target: newNode.id };
|
|
1658
|
-
const
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1658
|
+
const sourceParentInfo = stateRef.current.nodeIdToParentFileMap.get(String(sourceNodeData.id));
|
|
1659
|
+
const finalTargetDatasetId = targetDatasetId || sourceParentInfo.parentFileId;
|
|
1660
|
+
const targetParentInfo = sceneDataRef.current.parent_dbs.find((db) => String(db.db_id) === String(finalTargetDatasetId));
|
|
1661
|
+
if (!sourceParentInfo || !targetParentInfo) {
|
|
1662
|
+
alert("Erro ao identificar os datasets de origem ou destino.");
|
|
1662
1663
|
return;
|
|
1663
1664
|
}
|
|
1664
|
-
const
|
|
1665
|
-
const
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1665
|
+
const isCrossDataset = String(sourceParentInfo.parentFileId) !== String(finalTargetDatasetId);
|
|
1666
|
+
const sourceDataToUpdate = JSON.parse(JSON.stringify(graphDataRef.current[sourceParentInfo.parentFileId]));
|
|
1667
|
+
let targetDataToUpdate = isCrossDataset ? JSON.parse(JSON.stringify(graphDataRef.current[finalTargetDatasetId])) : sourceDataToUpdate;
|
|
1668
|
+
targetDataToUpdate.nodes.push(newNode);
|
|
1669
|
+
sourceDataToUpdate.links.push(newLink);
|
|
1670
|
+
const savePromises = [];
|
|
1671
|
+
if (isCrossDataset) {
|
|
1672
|
+
savePromises.push(
|
|
1673
|
+
actions.save_view_data(`x_view_dbs/${sourceParentInfo.ownerId}/${sourceParentInfo.parentFileId}`, sourceDataToUpdate)
|
|
1674
|
+
);
|
|
1675
|
+
savePromises.push(
|
|
1676
|
+
actions.save_view_data(`x_view_dbs/${targetParentInfo.owner_id}/${finalTargetDatasetId}`, targetDataToUpdate)
|
|
1677
|
+
);
|
|
1678
|
+
} else {
|
|
1679
|
+
savePromises.push(
|
|
1680
|
+
actions.save_view_data(`x_view_dbs/${sourceParentInfo.ownerId}/${sourceParentInfo.parentFileId}`, sourceDataToUpdate)
|
|
1681
|
+
);
|
|
1682
|
+
}
|
|
1669
1683
|
try {
|
|
1670
|
-
await
|
|
1671
|
-
graphDataRef.current[parentFileId] =
|
|
1684
|
+
await Promise.all(savePromises);
|
|
1685
|
+
graphDataRef.current[sourceParentInfo.parentFileId] = sourceDataToUpdate;
|
|
1686
|
+
if (isCrossDataset) {
|
|
1687
|
+
graphDataRef.current[finalTargetDatasetId] = targetDataToUpdate;
|
|
1688
|
+
}
|
|
1672
1689
|
const finalPosition = stateRef.current.ghostElements.node.position.clone();
|
|
1673
1690
|
addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
|
|
1691
|
+
stateRef.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
1692
|
+
parentFileId: finalTargetDatasetId,
|
|
1693
|
+
ownerId: targetParentInfo.owner_id,
|
|
1694
|
+
datasetName: targetDataToUpdate.dataset_name || "Dataset Desconhecido"
|
|
1695
|
+
});
|
|
1674
1696
|
setters.setSceneVersion((v) => v + 1);
|
|
1675
1697
|
} catch (error) {
|
|
1676
1698
|
console.error("Falha ao salvar os dados do grafo:", error);
|
|
@@ -1708,12 +1730,12 @@ var userActionHandlers = {
|
|
|
1708
1730
|
stateRef.current.creation = { isActive: true, sourceNodeData };
|
|
1709
1731
|
const ghostGeometry = new THREE.SphereGeometry(1.5, 32, 32);
|
|
1710
1732
|
const sourceColor = sourceNodeData.color || "#cccccc";
|
|
1711
|
-
const {
|
|
1712
|
-
const ghostColor = new THREE.Color(sourceColor);
|
|
1733
|
+
const { color: ghostColor, emissive: ghostEmissive } = computeNodeMaterialProps(sourceColor);
|
|
1713
1734
|
const ghostMaterial = new THREE.MeshStandardMaterial({
|
|
1714
1735
|
color: ghostColor,
|
|
1715
|
-
emissive:
|
|
1716
|
-
emissiveIntensity,
|
|
1736
|
+
emissive: ghostEmissive,
|
|
1737
|
+
emissiveIntensity: MIN_VISIBILITY_INTENSITY,
|
|
1738
|
+
// <-- Forçamos o brilho mínimo
|
|
1717
1739
|
roughness: 0.6,
|
|
1718
1740
|
metalness: 0,
|
|
1719
1741
|
transparent: true,
|
|
@@ -3767,6 +3789,7 @@ function DescriptionEditModal({
|
|
|
3767
3789
|
e.preventDefault();
|
|
3768
3790
|
e.stopPropagation();
|
|
3769
3791
|
e.stopImmediatePropagation();
|
|
3792
|
+
if (hoverTimeoutRef.current) clearTimeout(hoverTimeoutRef.current);
|
|
3770
3793
|
setIsMentionModalOpen(false);
|
|
3771
3794
|
setMentionTriggerIndex(null);
|
|
3772
3795
|
setTooltipData(null);
|
|
@@ -3860,6 +3883,7 @@ function DescriptionEditModal({
|
|
|
3860
3883
|
setIsImportModalOpen(false);
|
|
3861
3884
|
};
|
|
3862
3885
|
const handleMentionSelect = (node) => {
|
|
3886
|
+
if (hoverTimeoutRef.current) clearTimeout(hoverTimeoutRef.current);
|
|
3863
3887
|
const tag = `[[MENTION:node:${node.id}]]`;
|
|
3864
3888
|
const el = textareaRef.current;
|
|
3865
3889
|
if (mentionTriggerIndex !== null && el) {
|
|
@@ -4073,7 +4097,7 @@ function DescriptionEditModal({
|
|
|
4073
4097
|
className: "px-3 py-1.5 bg-indigo-600/30 hover:bg-indigo-600 text-indigo-200 text-xs rounded-lg transition-colors disabled:opacity-50"
|
|
4074
4098
|
},
|
|
4075
4099
|
"OK"
|
|
4076
|
-
))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "p-2 border-t border-white/10 bg-slate-950/50 flex justify-end" }, /* @__PURE__ */ import_react5.default.createElement("button", { onClick: () => setIsImageModalOpen(false), className: "px-3 py-1.5 text-xs text-slate-400 hover:text-white transition-colors" }, "Cancelar"))))
|
|
4100
|
+
))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "p-2 border-t border-white/10 bg-slate-950/50 flex justify-end" }, /* @__PURE__ */ import_react5.default.createElement("button", { onClick: () => setIsImageModalOpen(false), className: "px-3 py-1.5 text-xs text-slate-400 hover:text-white transition-colors" }, "Cancelar"))))),
|
|
4077
4101
|
/* @__PURE__ */ import_react5.default.createElement("div", { className: "sticky bottom-0 z-10 bg-slate-950/95 border-t border-white/10 px-6 py-4 flex justify-end gap-3 shrink-0" }, /* @__PURE__ */ import_react5.default.createElement("button", { onClick: handleSave, className: "px-6 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"))
|
|
4078
4102
|
)), tooltipData && /* @__PURE__ */ import_react5.default.createElement(
|
|
4079
4103
|
"div",
|
|
@@ -4549,7 +4573,6 @@ function DescriptionReadModePanel({
|
|
|
4549
4573
|
title,
|
|
4550
4574
|
description,
|
|
4551
4575
|
ancestryId,
|
|
4552
|
-
// <-- NOVO: Prop recebida do XViewScene
|
|
4553
4576
|
savedSections,
|
|
4554
4577
|
onBack,
|
|
4555
4578
|
onEdit,
|
|
@@ -4658,7 +4681,7 @@ function DescriptionReadModePanel({
|
|
|
4658
4681
|
return /* @__PURE__ */ import_react7.default.createElement(
|
|
4659
4682
|
"div",
|
|
4660
4683
|
{
|
|
4661
|
-
className: "flex flex-col h-full w-full bg-slate-950/50 relative overflow-hidden group",
|
|
4684
|
+
className: "flex flex-col h-full max-h-full w-full bg-slate-950/50 relative overflow-hidden group min-h-0",
|
|
4662
4685
|
onPointerDown: swallow,
|
|
4663
4686
|
onClick: swallow
|
|
4664
4687
|
},
|
|
@@ -4730,7 +4753,7 @@ function DescriptionReadModePanel({
|
|
|
4730
4753
|
},
|
|
4731
4754
|
"\xD7"
|
|
4732
4755
|
))),
|
|
4733
|
-
/* @__PURE__ */ import_react7.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10", onClick: () => setTargetRenderNodeId(null) }, showAbstraction ? /* @__PURE__ */ import_react7.default.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4" }, /* @__PURE__ */ import_react7.default.createElement("h3", { className: "text-sm font-semibold text-purple-300 uppercase tracking-wider" }, "Explorar Hierarquia"), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex flex-wrap gap-2" }, targetRenderNodeId && onRenderAbstractionTree && /* @__PURE__ */ import_react7.default.createElement(
|
|
4756
|
+
/* @__PURE__ */ import_react7.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10 min-h-0", onClick: () => setTargetRenderNodeId(null) }, showAbstraction ? /* @__PURE__ */ import_react7.default.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4" }, /* @__PURE__ */ import_react7.default.createElement("h3", { className: "text-sm font-semibold text-purple-300 uppercase tracking-wider" }, "Explorar Hierarquia"), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex flex-wrap gap-2" }, targetRenderNodeId && onRenderAbstractionTree && /* @__PURE__ */ import_react7.default.createElement(
|
|
4734
4757
|
"button",
|
|
4735
4758
|
{
|
|
4736
4759
|
onClick: (e) => {
|
|
@@ -5256,6 +5279,7 @@ function CreateAncestryPanel({
|
|
|
5256
5279
|
const branchProgressMapRef = (0, import_react10.useRef)({});
|
|
5257
5280
|
const [lastSavedSnapshot, setLastSavedSnapshot] = (0, import_react10.useState)(null);
|
|
5258
5281
|
const [isPrivate, setIsPrivate] = (0, import_react10.useState)(ancestryMode.is_private || false);
|
|
5282
|
+
const initializedContextIdRef = (0, import_react10.useRef)(null);
|
|
5259
5283
|
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
5260
5284
|
const handleImageClickFromText = (url, name) => {
|
|
5261
5285
|
if (onOpenImageViewer) {
|
|
@@ -5454,6 +5478,11 @@ function CreateAncestryPanel({
|
|
|
5454
5478
|
}, [isContextLinked, branchStack]);
|
|
5455
5479
|
(0, import_react10.useEffect)(() => {
|
|
5456
5480
|
const ctx = getCurrentContext();
|
|
5481
|
+
const currentContextId = branchStack.length > 0 ? branchStack[branchStack.length - 1].branchId : ancestryMode.currentAncestryId || `new_${ancestryMode.ancestral_node}`;
|
|
5482
|
+
if (initializedContextIdRef.current === currentContextId) {
|
|
5483
|
+
return;
|
|
5484
|
+
}
|
|
5485
|
+
initializedContextIdRef.current = currentContextId;
|
|
5457
5486
|
let sourceObject = {};
|
|
5458
5487
|
if (ctx) {
|
|
5459
5488
|
sourceObject = ctx;
|
|
@@ -5804,7 +5833,7 @@ function CreateAncestryPanel({
|
|
|
5804
5833
|
const currentAbsTreeStr = JSON.stringify(ancestryMode.abstraction_tree);
|
|
5805
5834
|
abstractionTreeChanged = currentAbsTreeStr !== lastSavedSnapshot.abstractionTree;
|
|
5806
5835
|
}
|
|
5807
|
-
return treeChanged || nameChanged || descChanged || sectionsChanged || propsChanged || privateChanged;
|
|
5836
|
+
return treeChanged || nameChanged || descChanged || sectionsChanged || propsChanged || privateChanged || abstractionTreeChanged;
|
|
5808
5837
|
}, [
|
|
5809
5838
|
ancestryName,
|
|
5810
5839
|
description,
|
|
@@ -6772,8 +6801,12 @@ function InSceneCreationForm({
|
|
|
6772
6801
|
availableAncestries = [],
|
|
6773
6802
|
onMentionClick,
|
|
6774
6803
|
sourceTypes,
|
|
6775
|
-
onUploadFile
|
|
6804
|
+
onUploadFile,
|
|
6805
|
+
availableDatasets = [],
|
|
6806
|
+
sourceNodeDatasetId,
|
|
6807
|
+
viewType
|
|
6776
6808
|
}) {
|
|
6809
|
+
var _a;
|
|
6777
6810
|
const [name, setName] = (0, import_react13.useState)("");
|
|
6778
6811
|
const [types, setTypes] = (0, import_react13.useState)([]);
|
|
6779
6812
|
const [typeInput, setTypeInput] = (0, import_react13.useState)("");
|
|
@@ -6787,6 +6820,25 @@ function InSceneCreationForm({
|
|
|
6787
6820
|
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react13.useState)(false);
|
|
6788
6821
|
const [useImageAsTexture, setUseImageAsTexture] = (0, import_react13.useState)(false);
|
|
6789
6822
|
const [selectedImageUrl, setSelectedImageUrl] = (0, import_react13.useState)(null);
|
|
6823
|
+
const [targetDatasetId, setTargetDatasetId] = (0, import_react13.useState)(sourceNodeDatasetId || "");
|
|
6824
|
+
const [isDatasetDropdownOpen, setIsDatasetDropdownOpen] = (0, import_react13.useState)(false);
|
|
6825
|
+
const datasetDropdownRef = (0, import_react13.useRef)(null);
|
|
6826
|
+
(0, import_react13.useEffect)(() => {
|
|
6827
|
+
if (sourceNodeDatasetId) setTargetDatasetId(sourceNodeDatasetId);
|
|
6828
|
+
}, [sourceNodeDatasetId]);
|
|
6829
|
+
(0, import_react13.useEffect)(() => {
|
|
6830
|
+
function handleClickOutside(event) {
|
|
6831
|
+
if (datasetDropdownRef.current && !datasetDropdownRef.current.contains(event.target)) {
|
|
6832
|
+
setIsDatasetDropdownOpen(false);
|
|
6833
|
+
}
|
|
6834
|
+
}
|
|
6835
|
+
if (isDatasetDropdownOpen) {
|
|
6836
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
6837
|
+
}
|
|
6838
|
+
return () => {
|
|
6839
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
6840
|
+
};
|
|
6841
|
+
}, [isDatasetDropdownOpen]);
|
|
6790
6842
|
const propsEndRef = (0, import_react13.useRef)(null);
|
|
6791
6843
|
const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
|
|
6792
6844
|
(0, import_react13.useEffect)(() => {
|
|
@@ -6832,8 +6884,8 @@ function InSceneCreationForm({
|
|
|
6832
6884
|
const newProp = createNewCustomProperty(customProps);
|
|
6833
6885
|
setCustomProps([...customProps, newProp]);
|
|
6834
6886
|
setTimeout(() => {
|
|
6835
|
-
var
|
|
6836
|
-
(
|
|
6887
|
+
var _a2;
|
|
6888
|
+
(_a2 = propsEndRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
6837
6889
|
}, 100);
|
|
6838
6890
|
};
|
|
6839
6891
|
const handleRemoveProp = (index) => setCustomProps(customProps.filter((_, i) => i !== index));
|
|
@@ -6866,12 +6918,12 @@ function InSceneCreationForm({
|
|
|
6866
6918
|
onSizeChange == null ? void 0 : onSizeChange(newSize);
|
|
6867
6919
|
};
|
|
6868
6920
|
const handleToggleImageMode = () => {
|
|
6869
|
-
var
|
|
6921
|
+
var _a2, _b;
|
|
6870
6922
|
const newValue = !useImageAsTexture;
|
|
6871
6923
|
setUseImageAsTexture(newValue);
|
|
6872
6924
|
if (newValue) {
|
|
6873
6925
|
const firstImageProp = customProps.find((p) => p.type === "images");
|
|
6874
|
-
if (firstImageProp && ((_b = (
|
|
6926
|
+
if (firstImageProp && ((_b = (_a2 = firstImageProp.value) == null ? void 0 : _a2[0]) == null ? void 0 : _b.value)) {
|
|
6875
6927
|
const url = firstImageProp.value[0].value;
|
|
6876
6928
|
setSelectedImageUrl(url);
|
|
6877
6929
|
onImageChange == null ? void 0 : onImageChange(true, url);
|
|
@@ -6904,6 +6956,7 @@ function InSceneCreationForm({
|
|
|
6904
6956
|
description_sections: processedSections,
|
|
6905
6957
|
useImageAsTexture,
|
|
6906
6958
|
textureImageUrl: useImageAsTexture ? selectedImageUrl : null,
|
|
6959
|
+
targetDatasetId,
|
|
6907
6960
|
...additionalData
|
|
6908
6961
|
});
|
|
6909
6962
|
};
|
|
@@ -6924,6 +6977,7 @@ function InSceneCreationForm({
|
|
|
6924
6977
|
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
6925
6978
|
}
|
|
6926
6979
|
};
|
|
6980
|
+
const selectedDatasetName = ((_a = availableDatasets.find((ds) => ds.id === targetDatasetId)) == null ? void 0 : _a.name) || "Selecione um Dataset...";
|
|
6927
6981
|
return /* @__PURE__ */ import_react13.default.createElement(import_react13.default.Fragment, null, /* @__PURE__ */ import_react13.default.createElement(
|
|
6928
6982
|
"div",
|
|
6929
6983
|
{
|
|
@@ -6981,7 +7035,27 @@ function InSceneCreationForm({
|
|
|
6981
7035
|
}
|
|
6982
7036
|
},
|
|
6983
7037
|
suggestedType
|
|
6984
|
-
))))), /* @__PURE__ */ import_react13.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react13.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome do Node"), /* @__PURE__ */ import_react13.default.createElement("input", { required: true, type: "text", placeholder: "Ex.: Cliente XPTO", value: name, onChange: handleNameInputChange, className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60" })), /* @__PURE__ */ import_react13.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react13.default.createElement("label", { className: "text-xs text-slate-300" }, "
|
|
7038
|
+
))))), /* @__PURE__ */ import_react13.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react13.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome do Node"), /* @__PURE__ */ import_react13.default.createElement("input", { required: true, type: "text", placeholder: "Ex.: Cliente XPTO", value: name, onChange: handleNameInputChange, 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" })), viewType === "view" && availableDatasets.length > 0 && /* @__PURE__ */ import_react13.default.createElement("div", { className: "space-y-1.5 relative", ref: datasetDropdownRef }, /* @__PURE__ */ import_react13.default.createElement("label", { className: "text-xs text-slate-300" }, "Criar Node no Dataset:"), /* @__PURE__ */ import_react13.default.createElement(
|
|
7039
|
+
"button",
|
|
7040
|
+
{
|
|
7041
|
+
type: "button",
|
|
7042
|
+
onClick: () => setIsDatasetDropdownOpen(!isDatasetDropdownOpen),
|
|
7043
|
+
className: "w-full flex items-center justify-between 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 hover:bg-slate-700/70 transition-colors text-slate-200 text-left"
|
|
7044
|
+
},
|
|
7045
|
+
/* @__PURE__ */ import_react13.default.createElement("span", { className: "truncate pr-2" }, selectedDatasetName),
|
|
7046
|
+
/* @__PURE__ */ import_react13.default.createElement(import_fi12.FiChevronDown, { className: `flex-shrink-0 text-slate-400 transition-transform ${isDatasetDropdownOpen ? "rotate-180" : ""}` })
|
|
7047
|
+
), isDatasetDropdownOpen && /* @__PURE__ */ import_react13.default.createElement("ul", { className: "custom-scrollbar absolute top-[66px] left-0 z-20 w-full max-h-48 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-xl py-1" }, availableDatasets.map((ds) => /* @__PURE__ */ import_react13.default.createElement(
|
|
7048
|
+
"li",
|
|
7049
|
+
{
|
|
7050
|
+
key: ds.id,
|
|
7051
|
+
onClick: () => {
|
|
7052
|
+
setTargetDatasetId(ds.id);
|
|
7053
|
+
setIsDatasetDropdownOpen(false);
|
|
7054
|
+
},
|
|
7055
|
+
className: `px-3 py-2 text-sm cursor-pointer transition-colors ${targetDatasetId === ds.id ? "bg-indigo-600/40 text-indigo-200 font-medium" : "text-slate-300 hover:bg-white/5"}`
|
|
7056
|
+
},
|
|
7057
|
+
ds.name
|
|
7058
|
+
)))), /* @__PURE__ */ import_react13.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react13.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react13.default.createElement("div", { className: "relative group min-h-[80px] bg-slate-800/70 p-2.5 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ import_react13.default.createElement(
|
|
6985
7059
|
DescriptionDisplay,
|
|
6986
7060
|
{
|
|
6987
7061
|
description,
|
|
@@ -7317,7 +7391,8 @@ function NodeDetailsPanel({
|
|
|
7317
7391
|
onMentionClick,
|
|
7318
7392
|
onIntensityChange,
|
|
7319
7393
|
onUploadFile,
|
|
7320
|
-
userRole
|
|
7394
|
+
userRole,
|
|
7395
|
+
currentDatasetName
|
|
7321
7396
|
}) {
|
|
7322
7397
|
const [name, setName] = (0, import_react15.useState)((node == null ? void 0 : node.name) ?? "");
|
|
7323
7398
|
const [types, setTypes] = (0, import_react15.useState)([]);
|
|
@@ -7547,10 +7622,10 @@ function NodeDetailsPanel({
|
|
|
7547
7622
|
return /* @__PURE__ */ import_react15.default.createElement(import_react15.default.Fragment, null, /* @__PURE__ */ import_react15.default.createElement(
|
|
7548
7623
|
"div",
|
|
7549
7624
|
{
|
|
7550
|
-
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
|
|
7625
|
+
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 transition-all duration-300 ease-out
|
|
7551
7626
|
${isReadMode ? "w-[min(92vw,700px)]" : "w-[min(92vw,440px)]"}
|
|
7552
7627
|
`,
|
|
7553
|
-
style: { top: 16, right: 16, zIndex: 1100 },
|
|
7628
|
+
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)" },
|
|
7554
7629
|
onPointerDown: swallow,
|
|
7555
7630
|
onPointerMove: swallow,
|
|
7556
7631
|
onPointerUp: swallow,
|
|
@@ -7728,7 +7803,7 @@ function NodeDetailsPanel({
|
|
|
7728
7803
|
onUploadFile: canEdit ? onUploadFile : void 0,
|
|
7729
7804
|
readOnly: !canEdit
|
|
7730
7805
|
}
|
|
7731
|
-
)), /* @__PURE__ */ import_react15.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react15.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react15.default.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ import_react15.default.createElement(
|
|
7806
|
+
)), /* @__PURE__ */ import_react15.default.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ import_react15.default.createElement("div", { className: "pt-3 mt-4 border-t border-white/10 flex items-center justify-end gap-2 text-xs text-slate-400" }, /* @__PURE__ */ import_react15.default.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ import_react15.default.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ import_react15.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react15.default.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ import_react15.default.createElement(
|
|
7732
7807
|
"button",
|
|
7733
7808
|
{
|
|
7734
7809
|
onClick: () => handleSave(false),
|
|
@@ -9049,7 +9124,7 @@ function XViewScene({
|
|
|
9049
9124
|
delete_file_action,
|
|
9050
9125
|
check_user_permission
|
|
9051
9126
|
}) {
|
|
9052
|
-
var _a, _b, _c, _d, _e, _f;
|
|
9127
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
9053
9128
|
const { data: session, status } = (0, import_react24.useSession)();
|
|
9054
9129
|
const router = (0, import_navigation.useRouter)();
|
|
9055
9130
|
const searchParams = (0, import_navigation.useSearchParams)();
|
|
@@ -9201,9 +9276,10 @@ function XViewScene({
|
|
|
9201
9276
|
const parentFile = allParentData[parentFileId];
|
|
9202
9277
|
const parentDbInfo = parentDbsArray.find((db) => String(db.db_id) === String(parentFileId));
|
|
9203
9278
|
const ownerId2 = (parentDbInfo == null ? void 0 : parentDbInfo.owner_id) || null;
|
|
9279
|
+
const datasetName = parentFile.dataset_name || `Dataset #${parentFileId.substring(0, 6)}`;
|
|
9204
9280
|
if (parentFile.nodes && ownerId2) {
|
|
9205
9281
|
for (const node of parentFile.nodes) {
|
|
9206
|
-
map.set(String(node.id), { parentFileId, ownerId: ownerId2 });
|
|
9282
|
+
map.set(String(node.id), { parentFileId, ownerId: ownerId2, datasetName });
|
|
9207
9283
|
}
|
|
9208
9284
|
}
|
|
9209
9285
|
}
|
|
@@ -9723,6 +9799,9 @@ function XViewScene({
|
|
|
9723
9799
|
sceneDataRef.current = sceneResponse.data.scene;
|
|
9724
9800
|
parentDataRef.current = sceneResponse.data.parent;
|
|
9725
9801
|
ancestryDataRef.current = sceneResponse.data.ancestry;
|
|
9802
|
+
console.log("Console de sceneResponse.data.scene:", sceneResponse.data.scene);
|
|
9803
|
+
console.log("Console de sceneResponse.data.parent:", sceneResponse.data.parent);
|
|
9804
|
+
console.log("Console de sceneResponse.data.ancestry:", sceneResponse.data.ancestry);
|
|
9726
9805
|
setIsInitialized(true);
|
|
9727
9806
|
} else {
|
|
9728
9807
|
console.error("Falha ao buscar dados da cena:", (sceneResponse == null ? void 0 : sceneResponse.error) || "Resposta inv\xE1lida.");
|
|
@@ -10504,32 +10583,33 @@ function XViewScene({
|
|
|
10504
10583
|
const handleGhostNodeColorChange = (newColor) => {
|
|
10505
10584
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
10506
10585
|
if (!ghostNode) return;
|
|
10507
|
-
const {
|
|
10508
|
-
const
|
|
10586
|
+
const { color, emissive } = computeNodeMaterialProps(newColor);
|
|
10587
|
+
const currentIntensity = ghostNode.userData.intensity !== void 0 ? Number(ghostNode.userData.intensity) : 0;
|
|
10588
|
+
const finalIntensity = currentIntensity + MIN_VISIBILITY_INTENSITY;
|
|
10509
10589
|
const isImageNode = ghostNode.userData.useImageAsTexture === true || String(ghostNode.userData.useImageAsTexture) === "true";
|
|
10510
10590
|
if (isImageNode) {
|
|
10511
10591
|
const borderMesh = ghostNode.getObjectByName("borderRing");
|
|
10512
10592
|
if (borderMesh && borderMesh.material) {
|
|
10513
|
-
borderMesh.material.color.copy(
|
|
10593
|
+
borderMesh.material.color.copy(color);
|
|
10514
10594
|
if (borderMesh.material.emissive) {
|
|
10515
|
-
borderMesh.material.emissive.copy(
|
|
10516
|
-
borderMesh.material.emissiveIntensity =
|
|
10595
|
+
borderMesh.material.emissive.copy(emissive);
|
|
10596
|
+
borderMesh.material.emissiveIntensity = finalIntensity;
|
|
10517
10597
|
}
|
|
10518
10598
|
}
|
|
10519
10599
|
} else {
|
|
10520
10600
|
if (ghostNode.material) {
|
|
10521
|
-
ghostNode.material.color.copy(
|
|
10601
|
+
ghostNode.material.color.copy(color);
|
|
10522
10602
|
if (ghostNode.material.emissive) {
|
|
10523
|
-
ghostNode.material.emissive.copy(
|
|
10524
|
-
ghostNode.material.emissiveIntensity =
|
|
10603
|
+
ghostNode.material.emissive.copy(emissive);
|
|
10604
|
+
ghostNode.material.emissiveIntensity = finalIntensity;
|
|
10525
10605
|
}
|
|
10526
10606
|
}
|
|
10527
10607
|
}
|
|
10528
10608
|
if (ghostAura && ghostAura.material) {
|
|
10529
|
-
ghostAura.material.color.
|
|
10609
|
+
ghostAura.material.color.copy(color).lerp(new THREE3.Color("#ffffff"), 0.25);
|
|
10530
10610
|
}
|
|
10531
10611
|
ghostNode.userData.color = newColor;
|
|
10532
|
-
ghostNode.userData._baseEmissiveIntensity =
|
|
10612
|
+
ghostNode.userData._baseEmissiveIntensity = finalIntensity;
|
|
10533
10613
|
};
|
|
10534
10614
|
const handleGhostNodeSizeChange = (sizeKey) => {
|
|
10535
10615
|
const { node: ghostNode } = stateRef.current.ghostElements;
|
|
@@ -10570,7 +10650,9 @@ function XViewScene({
|
|
|
10570
10650
|
var _a2;
|
|
10571
10651
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
10572
10652
|
if (!mesh) return;
|
|
10573
|
-
const { color, emissive
|
|
10653
|
+
const { color, emissive } = computeNodeMaterialProps(newColor);
|
|
10654
|
+
const currentIntensity = mesh.userData.intensity !== void 0 ? Number(mesh.userData.intensity) : 0;
|
|
10655
|
+
const finalIntensity = currentIntensity + MIN_VISIBILITY_INTENSITY;
|
|
10574
10656
|
const isImageNode = mesh.userData.useImageAsTexture === true || String(mesh.userData.useImageAsTexture) === "true";
|
|
10575
10657
|
if (isImageNode) {
|
|
10576
10658
|
const borderMesh = mesh.getObjectByName("borderRing");
|
|
@@ -10578,20 +10660,22 @@ function XViewScene({
|
|
|
10578
10660
|
borderMesh.material.color.copy(color);
|
|
10579
10661
|
if (borderMesh.material.emissive) {
|
|
10580
10662
|
borderMesh.material.emissive.copy(emissive);
|
|
10581
|
-
borderMesh.material.emissiveIntensity =
|
|
10663
|
+
borderMesh.material.emissiveIntensity = finalIntensity;
|
|
10582
10664
|
}
|
|
10583
10665
|
}
|
|
10584
10666
|
} else {
|
|
10585
10667
|
if (mesh.material) {
|
|
10586
10668
|
mesh.material.color.copy(color);
|
|
10587
10669
|
mesh.material.emissive.copy(emissive);
|
|
10588
|
-
mesh.material.emissiveIntensity =
|
|
10670
|
+
mesh.material.emissiveIntensity = finalIntensity;
|
|
10589
10671
|
}
|
|
10590
10672
|
}
|
|
10591
10673
|
const aura = mesh.getObjectByName("aura");
|
|
10592
|
-
if ((_a2 = aura == null ? void 0 : aura.material) == null ? void 0 : _a2.color)
|
|
10674
|
+
if ((_a2 = aura == null ? void 0 : aura.material) == null ? void 0 : _a2.color) {
|
|
10675
|
+
aura.material.color.copy(color).lerp(new THREE3.Color("#ffffff"), 0.25);
|
|
10676
|
+
}
|
|
10593
10677
|
mesh.userData.color = newColor;
|
|
10594
|
-
mesh.userData._baseEmissiveIntensity =
|
|
10678
|
+
mesh.userData._baseEmissiveIntensity = finalIntensity;
|
|
10595
10679
|
};
|
|
10596
10680
|
const handleDetailNodeSizeChange = (nodeId, newSize) => {
|
|
10597
10681
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
@@ -12044,6 +12128,18 @@ function XViewScene({
|
|
|
12044
12128
|
tweenToTarget(nodeMesh, 1.2);
|
|
12045
12129
|
}
|
|
12046
12130
|
}, [tweenToTarget]);
|
|
12131
|
+
const availableDatasets = (0, import_react23.useMemo)(() => {
|
|
12132
|
+
if (!sceneDataRef.current || !parentDataRef.current) return [];
|
|
12133
|
+
return sceneDataRef.current.parent_dbs.map((db) => {
|
|
12134
|
+
var _a2;
|
|
12135
|
+
return {
|
|
12136
|
+
id: db.db_id,
|
|
12137
|
+
name: ((_a2 = parentDataRef.current[db.db_id]) == null ? void 0 : _a2.dataset_name) || `Dataset #${db.db_id.substring(0, 6)}`
|
|
12138
|
+
};
|
|
12139
|
+
});
|
|
12140
|
+
}, [sceneVersion, isInitialized]);
|
|
12141
|
+
const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(String(creationMode.sourceNodeData.id))) == null ? void 0 : _b.parentFileId : null;
|
|
12142
|
+
const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
|
|
12047
12143
|
(0, import_react23.useEffect)(() => {
|
|
12048
12144
|
if (isInitialized && focusNodeId && !hasFocusedInitial) {
|
|
12049
12145
|
const nodeObjects = stateRef.current.nodeObjects || {};
|
|
@@ -12133,10 +12229,13 @@ function XViewScene({
|
|
|
12133
12229
|
style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
|
|
12134
12230
|
refEl: formRef,
|
|
12135
12231
|
existingTypes: existingNodeTypes,
|
|
12136
|
-
initialColor: (
|
|
12137
|
-
sourceTypes: (
|
|
12232
|
+
initialColor: (_c = creationMode.sourceNodeData) == null ? void 0 : _c.color,
|
|
12233
|
+
sourceTypes: (_d = creationMode.sourceNodeData) == null ? void 0 : _d.type,
|
|
12138
12234
|
onIntensityChange: handleGhostNodeIntensityChange,
|
|
12139
|
-
onUploadFile: upload_file_action
|
|
12235
|
+
onUploadFile: upload_file_action,
|
|
12236
|
+
availableDatasets,
|
|
12237
|
+
sourceNodeDatasetId,
|
|
12238
|
+
viewType: viewParams == null ? void 0 : viewParams.type
|
|
12140
12239
|
}
|
|
12141
12240
|
),
|
|
12142
12241
|
versionMode.isActive && /* @__PURE__ */ import_react23.default.createElement(
|
|
@@ -12151,8 +12250,8 @@ function XViewScene({
|
|
|
12151
12250
|
onMentionClick: handleAddExistingNode,
|
|
12152
12251
|
style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
|
|
12153
12252
|
refEl: formRef,
|
|
12154
|
-
fixedType: (
|
|
12155
|
-
fixedColor: (
|
|
12253
|
+
fixedType: (_e = versionMode.sourceNodeData) == null ? void 0 : _e.type,
|
|
12254
|
+
fixedColor: (_f = versionMode.sourceNodeData) == null ? void 0 : _f.color,
|
|
12156
12255
|
onUploadFile: upload_file_action
|
|
12157
12256
|
}
|
|
12158
12257
|
),
|
|
@@ -12261,7 +12360,8 @@ function XViewScene({
|
|
|
12261
12360
|
onMentionClick: handleAddExistingNode,
|
|
12262
12361
|
onIntensityChange: handleDetailNodeIntensityChange,
|
|
12263
12362
|
onUploadFile: upload_file_action,
|
|
12264
|
-
userRole: userPermissionRole
|
|
12363
|
+
userRole: userPermissionRole,
|
|
12364
|
+
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
12265
12365
|
}
|
|
12266
12366
|
),
|
|
12267
12367
|
detailsLink && /* @__PURE__ */ import_react23.default.createElement(
|
|
@@ -12389,7 +12489,7 @@ function XViewScene({
|
|
|
12389
12489
|
onClose: () => setIsImportModalOpen(false),
|
|
12390
12490
|
onConfirm: handleConfirmImport,
|
|
12391
12491
|
session,
|
|
12392
|
-
parentDbs: ((
|
|
12492
|
+
parentDbs: ((_g = sceneDataRef.current) == null ? void 0 : _g.parent_dbs) || [],
|
|
12393
12493
|
onFetchAvailableFiles: import_parent_file_modal_get,
|
|
12394
12494
|
currentViewName: viewParams == null ? void 0 : viewParams.name,
|
|
12395
12495
|
currentAncestries: ancestryDataRef.current || []
|
package/dist/index.mjs
CHANGED
|
@@ -811,7 +811,6 @@ var x_view_config = {
|
|
|
811
811
|
ANCESTOR_HIGHLIGHT_COLOR: "#FFD700",
|
|
812
812
|
BLOOM_EFFECT: { strength: 1.35, radius: 0.6, threshold: 0.52 },
|
|
813
813
|
EMISSIVE_MULTIPLIER: {
|
|
814
|
-
// AJUSTE: Valores agora representam ADIÇÃO de intensidade, não multiplicação
|
|
815
814
|
BASE: 0,
|
|
816
815
|
HOVER: 2,
|
|
817
816
|
SELECTED: 1.5,
|
|
@@ -863,7 +862,6 @@ var computeNodeMaterialProps = (colorHex) => {
|
|
|
863
862
|
return {
|
|
864
863
|
color: srgb,
|
|
865
864
|
emissive: emissiveColor
|
|
866
|
-
// Intensity é controlada externamente
|
|
867
865
|
};
|
|
868
866
|
};
|
|
869
867
|
var createNodeMesh = (nodeData, position, glowTexture) => {
|
|
@@ -1154,6 +1152,7 @@ var createMultipleLinkLines = (linksArray, sourceNodeMesh, targetNodeMesh, resol
|
|
|
1154
1152
|
resolution,
|
|
1155
1153
|
isCurved,
|
|
1156
1154
|
isCurved,
|
|
1155
|
+
isCurved,
|
|
1157
1156
|
curveOffset
|
|
1158
1157
|
);
|
|
1159
1158
|
line.userData = {
|
|
@@ -1530,12 +1529,12 @@ var userActionHandlers = {
|
|
|
1530
1529
|
stateRef.current.creation = { isActive: true, sourceNodeData };
|
|
1531
1530
|
const ghostGeometry = new THREE.SphereGeometry(1.5, 32, 32);
|
|
1532
1531
|
const sourceColor = sourceNodeData.color || "#cccccc";
|
|
1533
|
-
const {
|
|
1534
|
-
const ghostColor = new THREE.Color(sourceColor);
|
|
1532
|
+
const { color: ghostColor, emissive: ghostEmissive } = computeNodeMaterialProps(sourceColor);
|
|
1535
1533
|
const ghostMaterial = new THREE.MeshStandardMaterial({
|
|
1536
1534
|
color: ghostColor,
|
|
1537
|
-
emissive:
|
|
1538
|
-
emissiveIntensity,
|
|
1535
|
+
emissive: ghostEmissive,
|
|
1536
|
+
emissiveIntensity: MIN_VISIBILITY_INTENSITY,
|
|
1537
|
+
// <-- Forçamos o brilho mínimo
|
|
1539
1538
|
roughness: 0.6,
|
|
1540
1539
|
metalness: 0,
|
|
1541
1540
|
transparent: true,
|
|
@@ -1606,27 +1605,50 @@ var userActionHandlers = {
|
|
|
1606
1605
|
setters.setFormPosition((p) => ({ ...p, opacity: 0 }));
|
|
1607
1606
|
},
|
|
1608
1607
|
handleSaveNode: async (context, newNodeData) => {
|
|
1609
|
-
const { graphDataRef, sceneDataRef, stateRef, creationMode, setters } = context;
|
|
1608
|
+
const { graphDataRef, sceneDataRef, stateRef, creationMode, setters, actions } = context;
|
|
1610
1609
|
if (!graphDataRef.current || !sceneDataRef.current) return;
|
|
1611
1610
|
const { sourceNodeData } = creationMode;
|
|
1612
|
-
const
|
|
1611
|
+
const { targetDatasetId, ...nodeDataToSave } = newNodeData;
|
|
1612
|
+
const newNode = { id: short.generate(), ...nodeDataToSave };
|
|
1613
1613
|
const newLink = { id: `link_${short.generate()}`, source: sourceNodeData.id, target: newNode.id };
|
|
1614
|
-
const
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1614
|
+
const sourceParentInfo = stateRef.current.nodeIdToParentFileMap.get(String(sourceNodeData.id));
|
|
1615
|
+
const finalTargetDatasetId = targetDatasetId || sourceParentInfo.parentFileId;
|
|
1616
|
+
const targetParentInfo = sceneDataRef.current.parent_dbs.find((db) => String(db.db_id) === String(finalTargetDatasetId));
|
|
1617
|
+
if (!sourceParentInfo || !targetParentInfo) {
|
|
1618
|
+
alert("Erro ao identificar os datasets de origem ou destino.");
|
|
1618
1619
|
return;
|
|
1619
1620
|
}
|
|
1620
|
-
const
|
|
1621
|
-
const
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1621
|
+
const isCrossDataset = String(sourceParentInfo.parentFileId) !== String(finalTargetDatasetId);
|
|
1622
|
+
const sourceDataToUpdate = JSON.parse(JSON.stringify(graphDataRef.current[sourceParentInfo.parentFileId]));
|
|
1623
|
+
let targetDataToUpdate = isCrossDataset ? JSON.parse(JSON.stringify(graphDataRef.current[finalTargetDatasetId])) : sourceDataToUpdate;
|
|
1624
|
+
targetDataToUpdate.nodes.push(newNode);
|
|
1625
|
+
sourceDataToUpdate.links.push(newLink);
|
|
1626
|
+
const savePromises = [];
|
|
1627
|
+
if (isCrossDataset) {
|
|
1628
|
+
savePromises.push(
|
|
1629
|
+
actions.save_view_data(`x_view_dbs/${sourceParentInfo.ownerId}/${sourceParentInfo.parentFileId}`, sourceDataToUpdate)
|
|
1630
|
+
);
|
|
1631
|
+
savePromises.push(
|
|
1632
|
+
actions.save_view_data(`x_view_dbs/${targetParentInfo.owner_id}/${finalTargetDatasetId}`, targetDataToUpdate)
|
|
1633
|
+
);
|
|
1634
|
+
} else {
|
|
1635
|
+
savePromises.push(
|
|
1636
|
+
actions.save_view_data(`x_view_dbs/${sourceParentInfo.ownerId}/${sourceParentInfo.parentFileId}`, sourceDataToUpdate)
|
|
1637
|
+
);
|
|
1638
|
+
}
|
|
1625
1639
|
try {
|
|
1626
|
-
await
|
|
1627
|
-
graphDataRef.current[parentFileId] =
|
|
1640
|
+
await Promise.all(savePromises);
|
|
1641
|
+
graphDataRef.current[sourceParentInfo.parentFileId] = sourceDataToUpdate;
|
|
1642
|
+
if (isCrossDataset) {
|
|
1643
|
+
graphDataRef.current[finalTargetDatasetId] = targetDataToUpdate;
|
|
1644
|
+
}
|
|
1628
1645
|
const finalPosition = stateRef.current.ghostElements.node.position.clone();
|
|
1629
1646
|
addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
|
|
1647
|
+
stateRef.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
1648
|
+
parentFileId: finalTargetDatasetId,
|
|
1649
|
+
ownerId: targetParentInfo.owner_id,
|
|
1650
|
+
datasetName: targetDataToUpdate.dataset_name || "Dataset Desconhecido"
|
|
1651
|
+
});
|
|
1630
1652
|
setters.setSceneVersion((v) => v + 1);
|
|
1631
1653
|
} catch (error) {
|
|
1632
1654
|
console.error("Falha ao salvar os dados do grafo:", error);
|
|
@@ -1664,12 +1686,12 @@ var userActionHandlers = {
|
|
|
1664
1686
|
stateRef.current.creation = { isActive: true, sourceNodeData };
|
|
1665
1687
|
const ghostGeometry = new THREE.SphereGeometry(1.5, 32, 32);
|
|
1666
1688
|
const sourceColor = sourceNodeData.color || "#cccccc";
|
|
1667
|
-
const {
|
|
1668
|
-
const ghostColor = new THREE.Color(sourceColor);
|
|
1689
|
+
const { color: ghostColor, emissive: ghostEmissive } = computeNodeMaterialProps(sourceColor);
|
|
1669
1690
|
const ghostMaterial = new THREE.MeshStandardMaterial({
|
|
1670
1691
|
color: ghostColor,
|
|
1671
|
-
emissive:
|
|
1672
|
-
emissiveIntensity,
|
|
1692
|
+
emissive: ghostEmissive,
|
|
1693
|
+
emissiveIntensity: MIN_VISIBILITY_INTENSITY,
|
|
1694
|
+
// <-- Forçamos o brilho mínimo
|
|
1673
1695
|
roughness: 0.6,
|
|
1674
1696
|
metalness: 0,
|
|
1675
1697
|
transparent: true,
|
|
@@ -3723,6 +3745,7 @@ function DescriptionEditModal({
|
|
|
3723
3745
|
e.preventDefault();
|
|
3724
3746
|
e.stopPropagation();
|
|
3725
3747
|
e.stopImmediatePropagation();
|
|
3748
|
+
if (hoverTimeoutRef.current) clearTimeout(hoverTimeoutRef.current);
|
|
3726
3749
|
setIsMentionModalOpen(false);
|
|
3727
3750
|
setMentionTriggerIndex(null);
|
|
3728
3751
|
setTooltipData(null);
|
|
@@ -3816,6 +3839,7 @@ function DescriptionEditModal({
|
|
|
3816
3839
|
setIsImportModalOpen(false);
|
|
3817
3840
|
};
|
|
3818
3841
|
const handleMentionSelect = (node) => {
|
|
3842
|
+
if (hoverTimeoutRef.current) clearTimeout(hoverTimeoutRef.current);
|
|
3819
3843
|
const tag = `[[MENTION:node:${node.id}]]`;
|
|
3820
3844
|
const el = textareaRef.current;
|
|
3821
3845
|
if (mentionTriggerIndex !== null && el) {
|
|
@@ -4029,7 +4053,7 @@ function DescriptionEditModal({
|
|
|
4029
4053
|
className: "px-3 py-1.5 bg-indigo-600/30 hover:bg-indigo-600 text-indigo-200 text-xs rounded-lg transition-colors disabled:opacity-50"
|
|
4030
4054
|
},
|
|
4031
4055
|
"OK"
|
|
4032
|
-
))), /* @__PURE__ */ React5.createElement("div", { className: "p-2 border-t border-white/10 bg-slate-950/50 flex justify-end" }, /* @__PURE__ */ React5.createElement("button", { onClick: () => setIsImageModalOpen(false), className: "px-3 py-1.5 text-xs text-slate-400 hover:text-white transition-colors" }, "Cancelar"))))
|
|
4056
|
+
))), /* @__PURE__ */ React5.createElement("div", { className: "p-2 border-t border-white/10 bg-slate-950/50 flex justify-end" }, /* @__PURE__ */ React5.createElement("button", { onClick: () => setIsImageModalOpen(false), className: "px-3 py-1.5 text-xs text-slate-400 hover:text-white transition-colors" }, "Cancelar"))))),
|
|
4033
4057
|
/* @__PURE__ */ React5.createElement("div", { className: "sticky bottom-0 z-10 bg-slate-950/95 border-t border-white/10 px-6 py-4 flex justify-end gap-3 shrink-0" }, /* @__PURE__ */ React5.createElement("button", { onClick: handleSave, className: "px-6 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"))
|
|
4034
4058
|
)), tooltipData && /* @__PURE__ */ React5.createElement(
|
|
4035
4059
|
"div",
|
|
@@ -4519,7 +4543,6 @@ function DescriptionReadModePanel({
|
|
|
4519
4543
|
title,
|
|
4520
4544
|
description,
|
|
4521
4545
|
ancestryId,
|
|
4522
|
-
// <-- NOVO: Prop recebida do XViewScene
|
|
4523
4546
|
savedSections,
|
|
4524
4547
|
onBack,
|
|
4525
4548
|
onEdit,
|
|
@@ -4628,7 +4651,7 @@ function DescriptionReadModePanel({
|
|
|
4628
4651
|
return /* @__PURE__ */ React7.createElement(
|
|
4629
4652
|
"div",
|
|
4630
4653
|
{
|
|
4631
|
-
className: "flex flex-col h-full w-full bg-slate-950/50 relative overflow-hidden group",
|
|
4654
|
+
className: "flex flex-col h-full max-h-full w-full bg-slate-950/50 relative overflow-hidden group min-h-0",
|
|
4632
4655
|
onPointerDown: swallow,
|
|
4633
4656
|
onClick: swallow
|
|
4634
4657
|
},
|
|
@@ -4700,7 +4723,7 @@ function DescriptionReadModePanel({
|
|
|
4700
4723
|
},
|
|
4701
4724
|
"\xD7"
|
|
4702
4725
|
))),
|
|
4703
|
-
/* @__PURE__ */ React7.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10", onClick: () => setTargetRenderNodeId(null) }, showAbstraction ? /* @__PURE__ */ React7.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4" }, /* @__PURE__ */ React7.createElement("h3", { className: "text-sm font-semibold text-purple-300 uppercase tracking-wider" }, "Explorar Hierarquia"), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-wrap gap-2" }, targetRenderNodeId && onRenderAbstractionTree && /* @__PURE__ */ React7.createElement(
|
|
4726
|
+
/* @__PURE__ */ React7.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 bg-slate-900/20 relative z-10 min-h-0", onClick: () => setTargetRenderNodeId(null) }, showAbstraction ? /* @__PURE__ */ React7.createElement("div", { className: "space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4" }, /* @__PURE__ */ React7.createElement("h3", { className: "text-sm font-semibold text-purple-300 uppercase tracking-wider" }, "Explorar Hierarquia"), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-wrap gap-2" }, targetRenderNodeId && onRenderAbstractionTree && /* @__PURE__ */ React7.createElement(
|
|
4704
4727
|
"button",
|
|
4705
4728
|
{
|
|
4706
4729
|
onClick: (e) => {
|
|
@@ -5242,6 +5265,7 @@ function CreateAncestryPanel({
|
|
|
5242
5265
|
const branchProgressMapRef = useRef8({});
|
|
5243
5266
|
const [lastSavedSnapshot, setLastSavedSnapshot] = useState10(null);
|
|
5244
5267
|
const [isPrivate, setIsPrivate] = useState10(ancestryMode.is_private || false);
|
|
5268
|
+
const initializedContextIdRef = useRef8(null);
|
|
5245
5269
|
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
5246
5270
|
const handleImageClickFromText = (url, name) => {
|
|
5247
5271
|
if (onOpenImageViewer) {
|
|
@@ -5440,6 +5464,11 @@ function CreateAncestryPanel({
|
|
|
5440
5464
|
}, [isContextLinked, branchStack]);
|
|
5441
5465
|
useEffect10(() => {
|
|
5442
5466
|
const ctx = getCurrentContext();
|
|
5467
|
+
const currentContextId = branchStack.length > 0 ? branchStack[branchStack.length - 1].branchId : ancestryMode.currentAncestryId || `new_${ancestryMode.ancestral_node}`;
|
|
5468
|
+
if (initializedContextIdRef.current === currentContextId) {
|
|
5469
|
+
return;
|
|
5470
|
+
}
|
|
5471
|
+
initializedContextIdRef.current = currentContextId;
|
|
5443
5472
|
let sourceObject = {};
|
|
5444
5473
|
if (ctx) {
|
|
5445
5474
|
sourceObject = ctx;
|
|
@@ -5790,7 +5819,7 @@ function CreateAncestryPanel({
|
|
|
5790
5819
|
const currentAbsTreeStr = JSON.stringify(ancestryMode.abstraction_tree);
|
|
5791
5820
|
abstractionTreeChanged = currentAbsTreeStr !== lastSavedSnapshot.abstractionTree;
|
|
5792
5821
|
}
|
|
5793
|
-
return treeChanged || nameChanged || descChanged || sectionsChanged || propsChanged || privateChanged;
|
|
5822
|
+
return treeChanged || nameChanged || descChanged || sectionsChanged || propsChanged || privateChanged || abstractionTreeChanged;
|
|
5794
5823
|
}, [
|
|
5795
5824
|
ancestryName,
|
|
5796
5825
|
description,
|
|
@@ -6740,7 +6769,7 @@ function ColorPicker({ color, onChange, disabled }) {
|
|
|
6740
6769
|
}
|
|
6741
6770
|
|
|
6742
6771
|
// src/components/InSceneCreationForm.jsx
|
|
6743
|
-
import { FiPlus as FiPlus3, FiMaximize2, FiX as FiX3, FiCheck as FiCheck7, FiEdit2 as FiEdit24, FiSun } from "react-icons/fi";
|
|
6772
|
+
import { FiPlus as FiPlus3, FiMaximize2, FiX as FiX3, FiCheck as FiCheck7, FiEdit2 as FiEdit24, FiSun, FiChevronDown as FiChevronDown4 } from "react-icons/fi";
|
|
6744
6773
|
function InSceneCreationForm({
|
|
6745
6774
|
onSave,
|
|
6746
6775
|
onCancel,
|
|
@@ -6758,8 +6787,12 @@ function InSceneCreationForm({
|
|
|
6758
6787
|
availableAncestries = [],
|
|
6759
6788
|
onMentionClick,
|
|
6760
6789
|
sourceTypes,
|
|
6761
|
-
onUploadFile
|
|
6790
|
+
onUploadFile,
|
|
6791
|
+
availableDatasets = [],
|
|
6792
|
+
sourceNodeDatasetId,
|
|
6793
|
+
viewType
|
|
6762
6794
|
}) {
|
|
6795
|
+
var _a;
|
|
6763
6796
|
const [name, setName] = useState13("");
|
|
6764
6797
|
const [types, setTypes] = useState13([]);
|
|
6765
6798
|
const [typeInput, setTypeInput] = useState13("");
|
|
@@ -6773,6 +6806,25 @@ function InSceneCreationForm({
|
|
|
6773
6806
|
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState13(false);
|
|
6774
6807
|
const [useImageAsTexture, setUseImageAsTexture] = useState13(false);
|
|
6775
6808
|
const [selectedImageUrl, setSelectedImageUrl] = useState13(null);
|
|
6809
|
+
const [targetDatasetId, setTargetDatasetId] = useState13(sourceNodeDatasetId || "");
|
|
6810
|
+
const [isDatasetDropdownOpen, setIsDatasetDropdownOpen] = useState13(false);
|
|
6811
|
+
const datasetDropdownRef = useRef10(null);
|
|
6812
|
+
useEffect13(() => {
|
|
6813
|
+
if (sourceNodeDatasetId) setTargetDatasetId(sourceNodeDatasetId);
|
|
6814
|
+
}, [sourceNodeDatasetId]);
|
|
6815
|
+
useEffect13(() => {
|
|
6816
|
+
function handleClickOutside(event) {
|
|
6817
|
+
if (datasetDropdownRef.current && !datasetDropdownRef.current.contains(event.target)) {
|
|
6818
|
+
setIsDatasetDropdownOpen(false);
|
|
6819
|
+
}
|
|
6820
|
+
}
|
|
6821
|
+
if (isDatasetDropdownOpen) {
|
|
6822
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
6823
|
+
}
|
|
6824
|
+
return () => {
|
|
6825
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
6826
|
+
};
|
|
6827
|
+
}, [isDatasetDropdownOpen]);
|
|
6776
6828
|
const propsEndRef = useRef10(null);
|
|
6777
6829
|
const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
|
|
6778
6830
|
useEffect13(() => {
|
|
@@ -6818,8 +6870,8 @@ function InSceneCreationForm({
|
|
|
6818
6870
|
const newProp = createNewCustomProperty(customProps);
|
|
6819
6871
|
setCustomProps([...customProps, newProp]);
|
|
6820
6872
|
setTimeout(() => {
|
|
6821
|
-
var
|
|
6822
|
-
(
|
|
6873
|
+
var _a2;
|
|
6874
|
+
(_a2 = propsEndRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
6823
6875
|
}, 100);
|
|
6824
6876
|
};
|
|
6825
6877
|
const handleRemoveProp = (index) => setCustomProps(customProps.filter((_, i) => i !== index));
|
|
@@ -6852,12 +6904,12 @@ function InSceneCreationForm({
|
|
|
6852
6904
|
onSizeChange == null ? void 0 : onSizeChange(newSize);
|
|
6853
6905
|
};
|
|
6854
6906
|
const handleToggleImageMode = () => {
|
|
6855
|
-
var
|
|
6907
|
+
var _a2, _b;
|
|
6856
6908
|
const newValue = !useImageAsTexture;
|
|
6857
6909
|
setUseImageAsTexture(newValue);
|
|
6858
6910
|
if (newValue) {
|
|
6859
6911
|
const firstImageProp = customProps.find((p) => p.type === "images");
|
|
6860
|
-
if (firstImageProp && ((_b = (
|
|
6912
|
+
if (firstImageProp && ((_b = (_a2 = firstImageProp.value) == null ? void 0 : _a2[0]) == null ? void 0 : _b.value)) {
|
|
6861
6913
|
const url = firstImageProp.value[0].value;
|
|
6862
6914
|
setSelectedImageUrl(url);
|
|
6863
6915
|
onImageChange == null ? void 0 : onImageChange(true, url);
|
|
@@ -6890,6 +6942,7 @@ function InSceneCreationForm({
|
|
|
6890
6942
|
description_sections: processedSections,
|
|
6891
6943
|
useImageAsTexture,
|
|
6892
6944
|
textureImageUrl: useImageAsTexture ? selectedImageUrl : null,
|
|
6945
|
+
targetDatasetId,
|
|
6893
6946
|
...additionalData
|
|
6894
6947
|
});
|
|
6895
6948
|
};
|
|
@@ -6910,6 +6963,7 @@ function InSceneCreationForm({
|
|
|
6910
6963
|
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
6911
6964
|
}
|
|
6912
6965
|
};
|
|
6966
|
+
const selectedDatasetName = ((_a = availableDatasets.find((ds) => ds.id === targetDatasetId)) == null ? void 0 : _a.name) || "Selecione um Dataset...";
|
|
6913
6967
|
return /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(
|
|
6914
6968
|
"div",
|
|
6915
6969
|
{
|
|
@@ -6967,7 +7021,27 @@ function InSceneCreationForm({
|
|
|
6967
7021
|
}
|
|
6968
7022
|
},
|
|
6969
7023
|
suggestedType
|
|
6970
|
-
))))), /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Nome do Node"), /* @__PURE__ */ React13.createElement("input", { required: true, type: "text", placeholder: "Ex.: Cliente XPTO", value: name, onChange: handleNameInputChange, 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__ */ React13.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "
|
|
7024
|
+
))))), /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Nome do Node"), /* @__PURE__ */ React13.createElement("input", { required: true, type: "text", placeholder: "Ex.: Cliente XPTO", value: name, onChange: handleNameInputChange, 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" })), viewType === "view" && availableDatasets.length > 0 && /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5 relative", ref: datasetDropdownRef }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Criar Node no Dataset:"), /* @__PURE__ */ React13.createElement(
|
|
7025
|
+
"button",
|
|
7026
|
+
{
|
|
7027
|
+
type: "button",
|
|
7028
|
+
onClick: () => setIsDatasetDropdownOpen(!isDatasetDropdownOpen),
|
|
7029
|
+
className: "w-full flex items-center justify-between 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 hover:bg-slate-700/70 transition-colors text-slate-200 text-left"
|
|
7030
|
+
},
|
|
7031
|
+
/* @__PURE__ */ React13.createElement("span", { className: "truncate pr-2" }, selectedDatasetName),
|
|
7032
|
+
/* @__PURE__ */ React13.createElement(FiChevronDown4, { className: `flex-shrink-0 text-slate-400 transition-transform ${isDatasetDropdownOpen ? "rotate-180" : ""}` })
|
|
7033
|
+
), isDatasetDropdownOpen && /* @__PURE__ */ React13.createElement("ul", { className: "custom-scrollbar absolute top-[66px] left-0 z-20 w-full max-h-48 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-xl py-1" }, availableDatasets.map((ds) => /* @__PURE__ */ React13.createElement(
|
|
7034
|
+
"li",
|
|
7035
|
+
{
|
|
7036
|
+
key: ds.id,
|
|
7037
|
+
onClick: () => {
|
|
7038
|
+
setTargetDatasetId(ds.id);
|
|
7039
|
+
setIsDatasetDropdownOpen(false);
|
|
7040
|
+
},
|
|
7041
|
+
className: `px-3 py-2 text-sm cursor-pointer transition-colors ${targetDatasetId === ds.id ? "bg-indigo-600/40 text-indigo-200 font-medium" : "text-slate-300 hover:bg-white/5"}`
|
|
7042
|
+
},
|
|
7043
|
+
ds.name
|
|
7044
|
+
)))), /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ React13.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__ */ React13.createElement(
|
|
6971
7045
|
DescriptionDisplay,
|
|
6972
7046
|
{
|
|
6973
7047
|
description,
|
|
@@ -7285,7 +7359,7 @@ function InSceneVersionForm({
|
|
|
7285
7359
|
|
|
7286
7360
|
// src/components/NodeDetailsPanel.jsx
|
|
7287
7361
|
import React15, { useState as useState15, useEffect as useEffect15, useRef as useRef12 } from "react";
|
|
7288
|
-
import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize23, FiX as FiX4, FiCheck as FiCheck9, FiImage as FiImage3, FiEdit2 as FiEdit26, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5 } from "react-icons/fi";
|
|
7362
|
+
import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize23, FiX as FiX4, FiCheck as FiCheck9, FiImage as FiImage3, FiEdit2 as FiEdit26, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5, FiDatabase } from "react-icons/fi";
|
|
7289
7363
|
function NodeDetailsPanel({
|
|
7290
7364
|
node,
|
|
7291
7365
|
onClose,
|
|
@@ -7303,7 +7377,8 @@ function NodeDetailsPanel({
|
|
|
7303
7377
|
onMentionClick,
|
|
7304
7378
|
onIntensityChange,
|
|
7305
7379
|
onUploadFile,
|
|
7306
|
-
userRole
|
|
7380
|
+
userRole,
|
|
7381
|
+
currentDatasetName
|
|
7307
7382
|
}) {
|
|
7308
7383
|
const [name, setName] = useState15((node == null ? void 0 : node.name) ?? "");
|
|
7309
7384
|
const [types, setTypes] = useState15([]);
|
|
@@ -7533,10 +7608,10 @@ function NodeDetailsPanel({
|
|
|
7533
7608
|
return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
|
|
7534
7609
|
"div",
|
|
7535
7610
|
{
|
|
7536
|
-
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
|
|
7611
|
+
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 transition-all duration-300 ease-out
|
|
7537
7612
|
${isReadMode ? "w-[min(92vw,700px)]" : "w-[min(92vw,440px)]"}
|
|
7538
7613
|
`,
|
|
7539
|
-
style: { top: 16, right: 16, zIndex: 1100 },
|
|
7614
|
+
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)" },
|
|
7540
7615
|
onPointerDown: swallow,
|
|
7541
7616
|
onPointerMove: swallow,
|
|
7542
7617
|
onPointerUp: swallow,
|
|
@@ -7714,7 +7789,7 @@ function NodeDetailsPanel({
|
|
|
7714
7789
|
onUploadFile: canEdit ? onUploadFile : void 0,
|
|
7715
7790
|
readOnly: !canEdit
|
|
7716
7791
|
}
|
|
7717
|
-
)), /* @__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", { 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__ */ React15.createElement(
|
|
7792
|
+
)), /* @__PURE__ */ React15.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ React15.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__ */ React15.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ React15.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__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", { 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__ */ React15.createElement(
|
|
7718
7793
|
"button",
|
|
7719
7794
|
{
|
|
7720
7795
|
onClick: () => handleSave(false),
|
|
@@ -9048,7 +9123,7 @@ function XViewScene({
|
|
|
9048
9123
|
delete_file_action,
|
|
9049
9124
|
check_user_permission
|
|
9050
9125
|
}) {
|
|
9051
|
-
var _a, _b, _c, _d, _e, _f;
|
|
9126
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
9052
9127
|
const { data: session, status } = useSession();
|
|
9053
9128
|
const router = useRouter();
|
|
9054
9129
|
const searchParams = useSearchParams();
|
|
@@ -9200,9 +9275,10 @@ function XViewScene({
|
|
|
9200
9275
|
const parentFile = allParentData[parentFileId];
|
|
9201
9276
|
const parentDbInfo = parentDbsArray.find((db) => String(db.db_id) === String(parentFileId));
|
|
9202
9277
|
const ownerId2 = (parentDbInfo == null ? void 0 : parentDbInfo.owner_id) || null;
|
|
9278
|
+
const datasetName = parentFile.dataset_name || `Dataset #${parentFileId.substring(0, 6)}`;
|
|
9203
9279
|
if (parentFile.nodes && ownerId2) {
|
|
9204
9280
|
for (const node of parentFile.nodes) {
|
|
9205
|
-
map.set(String(node.id), { parentFileId, ownerId: ownerId2 });
|
|
9281
|
+
map.set(String(node.id), { parentFileId, ownerId: ownerId2, datasetName });
|
|
9206
9282
|
}
|
|
9207
9283
|
}
|
|
9208
9284
|
}
|
|
@@ -9722,6 +9798,9 @@ function XViewScene({
|
|
|
9722
9798
|
sceneDataRef.current = sceneResponse.data.scene;
|
|
9723
9799
|
parentDataRef.current = sceneResponse.data.parent;
|
|
9724
9800
|
ancestryDataRef.current = sceneResponse.data.ancestry;
|
|
9801
|
+
console.log("Console de sceneResponse.data.scene:", sceneResponse.data.scene);
|
|
9802
|
+
console.log("Console de sceneResponse.data.parent:", sceneResponse.data.parent);
|
|
9803
|
+
console.log("Console de sceneResponse.data.ancestry:", sceneResponse.data.ancestry);
|
|
9725
9804
|
setIsInitialized(true);
|
|
9726
9805
|
} else {
|
|
9727
9806
|
console.error("Falha ao buscar dados da cena:", (sceneResponse == null ? void 0 : sceneResponse.error) || "Resposta inv\xE1lida.");
|
|
@@ -10503,32 +10582,33 @@ function XViewScene({
|
|
|
10503
10582
|
const handleGhostNodeColorChange = (newColor) => {
|
|
10504
10583
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
10505
10584
|
if (!ghostNode) return;
|
|
10506
|
-
const {
|
|
10507
|
-
const
|
|
10585
|
+
const { color, emissive } = computeNodeMaterialProps(newColor);
|
|
10586
|
+
const currentIntensity = ghostNode.userData.intensity !== void 0 ? Number(ghostNode.userData.intensity) : 0;
|
|
10587
|
+
const finalIntensity = currentIntensity + MIN_VISIBILITY_INTENSITY;
|
|
10508
10588
|
const isImageNode = ghostNode.userData.useImageAsTexture === true || String(ghostNode.userData.useImageAsTexture) === "true";
|
|
10509
10589
|
if (isImageNode) {
|
|
10510
10590
|
const borderMesh = ghostNode.getObjectByName("borderRing");
|
|
10511
10591
|
if (borderMesh && borderMesh.material) {
|
|
10512
|
-
borderMesh.material.color.copy(
|
|
10592
|
+
borderMesh.material.color.copy(color);
|
|
10513
10593
|
if (borderMesh.material.emissive) {
|
|
10514
|
-
borderMesh.material.emissive.copy(
|
|
10515
|
-
borderMesh.material.emissiveIntensity =
|
|
10594
|
+
borderMesh.material.emissive.copy(emissive);
|
|
10595
|
+
borderMesh.material.emissiveIntensity = finalIntensity;
|
|
10516
10596
|
}
|
|
10517
10597
|
}
|
|
10518
10598
|
} else {
|
|
10519
10599
|
if (ghostNode.material) {
|
|
10520
|
-
ghostNode.material.color.copy(
|
|
10600
|
+
ghostNode.material.color.copy(color);
|
|
10521
10601
|
if (ghostNode.material.emissive) {
|
|
10522
|
-
ghostNode.material.emissive.copy(
|
|
10523
|
-
ghostNode.material.emissiveIntensity =
|
|
10602
|
+
ghostNode.material.emissive.copy(emissive);
|
|
10603
|
+
ghostNode.material.emissiveIntensity = finalIntensity;
|
|
10524
10604
|
}
|
|
10525
10605
|
}
|
|
10526
10606
|
}
|
|
10527
10607
|
if (ghostAura && ghostAura.material) {
|
|
10528
|
-
ghostAura.material.color.
|
|
10608
|
+
ghostAura.material.color.copy(color).lerp(new THREE3.Color("#ffffff"), 0.25);
|
|
10529
10609
|
}
|
|
10530
10610
|
ghostNode.userData.color = newColor;
|
|
10531
|
-
ghostNode.userData._baseEmissiveIntensity =
|
|
10611
|
+
ghostNode.userData._baseEmissiveIntensity = finalIntensity;
|
|
10532
10612
|
};
|
|
10533
10613
|
const handleGhostNodeSizeChange = (sizeKey) => {
|
|
10534
10614
|
const { node: ghostNode } = stateRef.current.ghostElements;
|
|
@@ -10569,7 +10649,9 @@ function XViewScene({
|
|
|
10569
10649
|
var _a2;
|
|
10570
10650
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
10571
10651
|
if (!mesh) return;
|
|
10572
|
-
const { color, emissive
|
|
10652
|
+
const { color, emissive } = computeNodeMaterialProps(newColor);
|
|
10653
|
+
const currentIntensity = mesh.userData.intensity !== void 0 ? Number(mesh.userData.intensity) : 0;
|
|
10654
|
+
const finalIntensity = currentIntensity + MIN_VISIBILITY_INTENSITY;
|
|
10573
10655
|
const isImageNode = mesh.userData.useImageAsTexture === true || String(mesh.userData.useImageAsTexture) === "true";
|
|
10574
10656
|
if (isImageNode) {
|
|
10575
10657
|
const borderMesh = mesh.getObjectByName("borderRing");
|
|
@@ -10577,20 +10659,22 @@ function XViewScene({
|
|
|
10577
10659
|
borderMesh.material.color.copy(color);
|
|
10578
10660
|
if (borderMesh.material.emissive) {
|
|
10579
10661
|
borderMesh.material.emissive.copy(emissive);
|
|
10580
|
-
borderMesh.material.emissiveIntensity =
|
|
10662
|
+
borderMesh.material.emissiveIntensity = finalIntensity;
|
|
10581
10663
|
}
|
|
10582
10664
|
}
|
|
10583
10665
|
} else {
|
|
10584
10666
|
if (mesh.material) {
|
|
10585
10667
|
mesh.material.color.copy(color);
|
|
10586
10668
|
mesh.material.emissive.copy(emissive);
|
|
10587
|
-
mesh.material.emissiveIntensity =
|
|
10669
|
+
mesh.material.emissiveIntensity = finalIntensity;
|
|
10588
10670
|
}
|
|
10589
10671
|
}
|
|
10590
10672
|
const aura = mesh.getObjectByName("aura");
|
|
10591
|
-
if ((_a2 = aura == null ? void 0 : aura.material) == null ? void 0 : _a2.color)
|
|
10673
|
+
if ((_a2 = aura == null ? void 0 : aura.material) == null ? void 0 : _a2.color) {
|
|
10674
|
+
aura.material.color.copy(color).lerp(new THREE3.Color("#ffffff"), 0.25);
|
|
10675
|
+
}
|
|
10592
10676
|
mesh.userData.color = newColor;
|
|
10593
|
-
mesh.userData._baseEmissiveIntensity =
|
|
10677
|
+
mesh.userData._baseEmissiveIntensity = finalIntensity;
|
|
10594
10678
|
};
|
|
10595
10679
|
const handleDetailNodeSizeChange = (nodeId, newSize) => {
|
|
10596
10680
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
@@ -12043,6 +12127,18 @@ function XViewScene({
|
|
|
12043
12127
|
tweenToTarget(nodeMesh, 1.2);
|
|
12044
12128
|
}
|
|
12045
12129
|
}, [tweenToTarget]);
|
|
12130
|
+
const availableDatasets = useMemo12(() => {
|
|
12131
|
+
if (!sceneDataRef.current || !parentDataRef.current) return [];
|
|
12132
|
+
return sceneDataRef.current.parent_dbs.map((db) => {
|
|
12133
|
+
var _a2;
|
|
12134
|
+
return {
|
|
12135
|
+
id: db.db_id,
|
|
12136
|
+
name: ((_a2 = parentDataRef.current[db.db_id]) == null ? void 0 : _a2.dataset_name) || `Dataset #${db.db_id.substring(0, 6)}`
|
|
12137
|
+
};
|
|
12138
|
+
});
|
|
12139
|
+
}, [sceneVersion, isInitialized]);
|
|
12140
|
+
const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(String(creationMode.sourceNodeData.id))) == null ? void 0 : _b.parentFileId : null;
|
|
12141
|
+
const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
|
|
12046
12142
|
useEffect21(() => {
|
|
12047
12143
|
if (isInitialized && focusNodeId && !hasFocusedInitial) {
|
|
12048
12144
|
const nodeObjects = stateRef.current.nodeObjects || {};
|
|
@@ -12132,10 +12228,13 @@ function XViewScene({
|
|
|
12132
12228
|
style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
|
|
12133
12229
|
refEl: formRef,
|
|
12134
12230
|
existingTypes: existingNodeTypes,
|
|
12135
|
-
initialColor: (
|
|
12136
|
-
sourceTypes: (
|
|
12231
|
+
initialColor: (_c = creationMode.sourceNodeData) == null ? void 0 : _c.color,
|
|
12232
|
+
sourceTypes: (_d = creationMode.sourceNodeData) == null ? void 0 : _d.type,
|
|
12137
12233
|
onIntensityChange: handleGhostNodeIntensityChange,
|
|
12138
|
-
onUploadFile: upload_file_action
|
|
12234
|
+
onUploadFile: upload_file_action,
|
|
12235
|
+
availableDatasets,
|
|
12236
|
+
sourceNodeDatasetId,
|
|
12237
|
+
viewType: viewParams == null ? void 0 : viewParams.type
|
|
12139
12238
|
}
|
|
12140
12239
|
),
|
|
12141
12240
|
versionMode.isActive && /* @__PURE__ */ React23.createElement(
|
|
@@ -12150,8 +12249,8 @@ function XViewScene({
|
|
|
12150
12249
|
onMentionClick: handleAddExistingNode,
|
|
12151
12250
|
style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
|
|
12152
12251
|
refEl: formRef,
|
|
12153
|
-
fixedType: (
|
|
12154
|
-
fixedColor: (
|
|
12252
|
+
fixedType: (_e = versionMode.sourceNodeData) == null ? void 0 : _e.type,
|
|
12253
|
+
fixedColor: (_f = versionMode.sourceNodeData) == null ? void 0 : _f.color,
|
|
12155
12254
|
onUploadFile: upload_file_action
|
|
12156
12255
|
}
|
|
12157
12256
|
),
|
|
@@ -12260,7 +12359,8 @@ function XViewScene({
|
|
|
12260
12359
|
onMentionClick: handleAddExistingNode,
|
|
12261
12360
|
onIntensityChange: handleDetailNodeIntensityChange,
|
|
12262
12361
|
onUploadFile: upload_file_action,
|
|
12263
|
-
userRole: userPermissionRole
|
|
12362
|
+
userRole: userPermissionRole,
|
|
12363
|
+
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
12264
12364
|
}
|
|
12265
12365
|
),
|
|
12266
12366
|
detailsLink && /* @__PURE__ */ React23.createElement(
|
|
@@ -12388,7 +12488,7 @@ function XViewScene({
|
|
|
12388
12488
|
onClose: () => setIsImportModalOpen(false),
|
|
12389
12489
|
onConfirm: handleConfirmImport,
|
|
12390
12490
|
session,
|
|
12391
|
-
parentDbs: ((
|
|
12491
|
+
parentDbs: ((_g = sceneDataRef.current) == null ? void 0 : _g.parent_dbs) || [],
|
|
12392
12492
|
onFetchAvailableFiles: import_parent_file_modal_get,
|
|
12393
12493
|
currentViewName: viewParams == null ? void 0 : viewParams.name,
|
|
12394
12494
|
currentAncestries: ancestryDataRef.current || []
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lv-x-software-house/x_view",
|
|
3
|
-
"version": "1.2.2-dev.
|
|
3
|
+
"version": "1.2.2-dev.11",
|
|
4
4
|
"description": "Pacote privado contendo os componentes e lógica de renderização 3D do X View.",
|
|
5
5
|
"author": "iv.x - Engenharia de Software - ivxsoftwarehouse@gmail.com",
|
|
6
6
|
"license": "UNLICENSED",
|