@lv-x-software-house/x_view 1.2.2-dev.13 → 1.2.2-dev.14
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 +871 -791
- package/dist/index.mjs +306 -226
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/XViewScene.jsx
|
|
2
|
-
import React23, { useCallback as
|
|
2
|
+
import React23, { useCallback as useCallback4, useEffect as useEffect21, useRef as useRef17, useState as useState23, 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";
|
|
@@ -735,7 +735,7 @@ function XViewSidebar({
|
|
|
735
735
|
}
|
|
736
736
|
|
|
737
737
|
// src/components/AncestryRelationshipPanel.jsx
|
|
738
|
-
import React8, { useState as
|
|
738
|
+
import React8, { useState as useState9, useEffect as useEffect8, useRef as useRef7 } from "react";
|
|
739
739
|
|
|
740
740
|
// node_modules/uuid/dist/esm-node/rng.js
|
|
741
741
|
import crypto from "crypto";
|
|
@@ -785,6 +785,7 @@ function v4(options, buf, offset) {
|
|
|
785
785
|
var v4_default = v4;
|
|
786
786
|
|
|
787
787
|
// src/logic/x_view_utils.js
|
|
788
|
+
import { useState as useState3, useCallback } from "react";
|
|
788
789
|
import * as THREE2 from "three";
|
|
789
790
|
|
|
790
791
|
// src/logic/x_view_config.js
|
|
@@ -2999,9 +3000,36 @@ var extractFileUrlsFromProperties = (dataObject) => {
|
|
|
2999
3000
|
});
|
|
3000
3001
|
return urlsToDelete;
|
|
3001
3002
|
};
|
|
3003
|
+
function useResizablePanel({ initialWidth, minWidth, maxWidth }) {
|
|
3004
|
+
const [width, setWidth] = useState3(initialWidth);
|
|
3005
|
+
const [isResizing, setIsResizing] = useState3(false);
|
|
3006
|
+
const handlePointerDown = useCallback((e) => {
|
|
3007
|
+
e.preventDefault();
|
|
3008
|
+
e.stopPropagation();
|
|
3009
|
+
setIsResizing(true);
|
|
3010
|
+
const startX = e.clientX;
|
|
3011
|
+
const startWidth = width;
|
|
3012
|
+
const originalUserSelect = document.body.style.userSelect;
|
|
3013
|
+
document.body.style.userSelect = "none";
|
|
3014
|
+
const handlePointerMove = (moveEvent) => {
|
|
3015
|
+
const deltaX = startX - moveEvent.clientX;
|
|
3016
|
+
const newWidth = Math.min(Math.max(startWidth + deltaX, minWidth), maxWidth);
|
|
3017
|
+
setWidth(newWidth);
|
|
3018
|
+
};
|
|
3019
|
+
const handlePointerUp = () => {
|
|
3020
|
+
setIsResizing(false);
|
|
3021
|
+
document.body.style.userSelect = originalUserSelect;
|
|
3022
|
+
document.removeEventListener("pointermove", handlePointerMove);
|
|
3023
|
+
document.removeEventListener("pointerup", handlePointerUp);
|
|
3024
|
+
};
|
|
3025
|
+
document.addEventListener("pointermove", handlePointerMove);
|
|
3026
|
+
document.addEventListener("pointerup", handlePointerUp);
|
|
3027
|
+
}, [width, minWidth, maxWidth]);
|
|
3028
|
+
return { width, isResizing, handlePointerDown, setWidth };
|
|
3029
|
+
}
|
|
3002
3030
|
|
|
3003
3031
|
// src/components/CustomPropertyDisplay.jsx
|
|
3004
|
-
import React3, { useState as
|
|
3032
|
+
import React3, { useState as useState4, useRef as useRef3, useEffect as useEffect3 } from "react";
|
|
3005
3033
|
import { FiCheck, FiX, FiEdit3, FiTrash2, FiExternalLink, FiFileText, FiChevronDown, FiUpload, FiLoader } from "react-icons/fi";
|
|
3006
3034
|
function CustomPropertyDisplay({
|
|
3007
3035
|
prop,
|
|
@@ -3016,12 +3044,12 @@ function CustomPropertyDisplay({
|
|
|
3016
3044
|
},
|
|
3017
3045
|
onUploadFile
|
|
3018
3046
|
}) {
|
|
3019
|
-
const [isEditing, setIsEditing] =
|
|
3020
|
-
const [tempProp, setTempProp] =
|
|
3021
|
-
const [isHovered, setIsHovered] =
|
|
3022
|
-
const [isTypeDropdownOpen, setIsTypeDropdownOpen] =
|
|
3047
|
+
const [isEditing, setIsEditing] = useState4(prop.isEditing ?? false);
|
|
3048
|
+
const [tempProp, setTempProp] = useState4(prop);
|
|
3049
|
+
const [isHovered, setIsHovered] = useState4(false);
|
|
3050
|
+
const [isTypeDropdownOpen, setIsTypeDropdownOpen] = useState4(false);
|
|
3023
3051
|
const dropdownRef = useRef3(null);
|
|
3024
|
-
const [uploadingItemIndex, setUploadingItemIndex] =
|
|
3052
|
+
const [uploadingItemIndex, setUploadingItemIndex] = useState4(null);
|
|
3025
3053
|
const fileInputRef = useRef3(null);
|
|
3026
3054
|
const currentUploadTargetRef = useRef3(null);
|
|
3027
3055
|
useEffect3(() => {
|
|
@@ -3367,15 +3395,15 @@ function CustomPropertyDisplay({
|
|
|
3367
3395
|
import { FiPlus, FiEdit2 as FiEdit22, FiBookOpen } from "react-icons/fi";
|
|
3368
3396
|
|
|
3369
3397
|
// src/components/DescriptionEditModal.jsx
|
|
3370
|
-
import React5, { useState as
|
|
3398
|
+
import React5, { useState as useState6, useEffect as useEffect5, useRef as useRef5, useMemo as useMemo4 } from "react";
|
|
3371
3399
|
import { FiType, FiList, FiCode, FiLink as FiLink2, FiAtSign, FiSearch as FiSearch2, FiHexagon as FiHexagon2, FiGlobe, FiImage } from "react-icons/fi";
|
|
3372
3400
|
|
|
3373
3401
|
// src/components/SectionImportModal.jsx
|
|
3374
|
-
import React4, { useState as
|
|
3402
|
+
import React4, { useState as useState5, useMemo as useMemo3, useRef as useRef4, useEffect as useEffect4 } from "react";
|
|
3375
3403
|
import { FiSearch, FiLayers as FiLayers2, FiHexagon, FiClock, FiCheck as FiCheck2, FiCopy, FiTerminal, FiChevronDown as FiChevronDown2, FiChevronRight, FiDownload, FiLink } from "react-icons/fi";
|
|
3376
3404
|
var CodeBlock = ({ content, isActive, onClick }) => {
|
|
3377
|
-
const [isExpanded, setIsExpanded] =
|
|
3378
|
-
const [copied, setCopied] =
|
|
3405
|
+
const [isExpanded, setIsExpanded] = useState5(false);
|
|
3406
|
+
const [copied, setCopied] = useState5(false);
|
|
3379
3407
|
const cleanContent = content.replace(/^```|```$/g, "").trim();
|
|
3380
3408
|
const isLongCode = cleanContent.split("\n").length > 4;
|
|
3381
3409
|
const handleCopy = (e) => {
|
|
@@ -3438,14 +3466,14 @@ var formatLineContent = (line) => {
|
|
|
3438
3466
|
return /* @__PURE__ */ React4.createElement("span", { className: "break-words" }, line);
|
|
3439
3467
|
};
|
|
3440
3468
|
function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], availableAncestries = [] }) {
|
|
3441
|
-
const [searchTerm, setSearchTerm] =
|
|
3442
|
-
const [selectedItem, setSelectedItem] =
|
|
3443
|
-
const [searchHistory, setSearchHistory] =
|
|
3444
|
-
const [activeIndex, setActiveIndex] =
|
|
3445
|
-
const [selectedIndices, setSelectedIndices] =
|
|
3446
|
-
const [lastSelectedIndex, setLastSelectedIndex] =
|
|
3469
|
+
const [searchTerm, setSearchTerm] = useState5("");
|
|
3470
|
+
const [selectedItem, setSelectedItem] = useState5(null);
|
|
3471
|
+
const [searchHistory, setSearchHistory] = useState5([]);
|
|
3472
|
+
const [activeIndex, setActiveIndex] = useState5(0);
|
|
3473
|
+
const [selectedIndices, setSelectedIndices] = useState5(/* @__PURE__ */ new Set([0]));
|
|
3474
|
+
const [lastSelectedIndex, setLastSelectedIndex] = useState5(0);
|
|
3447
3475
|
const sectionRefs = useRef4([]);
|
|
3448
|
-
const [isDropdownOpen, setIsDropdownOpen] =
|
|
3476
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState5(false);
|
|
3449
3477
|
const inputRef = useRef4(null);
|
|
3450
3478
|
useEffect4(() => {
|
|
3451
3479
|
if (!selectedItem) return;
|
|
@@ -3784,16 +3812,22 @@ function DescriptionEditModal({
|
|
|
3784
3812
|
availableAncestries = [],
|
|
3785
3813
|
availableImages = []
|
|
3786
3814
|
}) {
|
|
3787
|
-
const
|
|
3815
|
+
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.9 : 1200;
|
|
3816
|
+
const { width: panelWidth, isResizing, handlePointerDown: handleResize } = useResizablePanel({
|
|
3817
|
+
initialWidth: 700,
|
|
3818
|
+
minWidth: 400,
|
|
3819
|
+
maxWidth: maxPanelW
|
|
3820
|
+
});
|
|
3821
|
+
const [text, setText] = useState6(initialValue || "");
|
|
3788
3822
|
const textareaRef = useRef5(null);
|
|
3789
|
-
const [isImportModalOpen, setIsImportModalOpen] =
|
|
3790
|
-
const [isMentionModalOpen, setIsMentionModalOpen] =
|
|
3791
|
-
const [mentionSearch, setMentionSearch] =
|
|
3792
|
-
const [mentionTriggerIndex, setMentionTriggerIndex] =
|
|
3793
|
-
const [isImageModalOpen, setIsImageModalOpen] =
|
|
3794
|
-
const [manualImageUrl, setManualImageUrl] =
|
|
3823
|
+
const [isImportModalOpen, setIsImportModalOpen] = useState6(false);
|
|
3824
|
+
const [isMentionModalOpen, setIsMentionModalOpen] = useState6(false);
|
|
3825
|
+
const [mentionSearch, setMentionSearch] = useState6("");
|
|
3826
|
+
const [mentionTriggerIndex, setMentionTriggerIndex] = useState6(null);
|
|
3827
|
+
const [isImageModalOpen, setIsImageModalOpen] = useState6(false);
|
|
3828
|
+
const [manualImageUrl, setManualImageUrl] = useState6("");
|
|
3795
3829
|
const hoverTimeoutRef = useRef5(null);
|
|
3796
|
-
const [tooltipData, setTooltipData] =
|
|
3830
|
+
const [tooltipData, setTooltipData] = useState6(null);
|
|
3797
3831
|
useEffect5(() => {
|
|
3798
3832
|
const handleKeyDown = (e) => {
|
|
3799
3833
|
if (e.key === "Escape") {
|
|
@@ -3952,7 +3986,8 @@ function DescriptionEditModal({
|
|
|
3952
3986
|
return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement("div", { className: "fixed inset-0 z-[2000] flex justify-end pointer-events-none bg-transparent" }, /* @__PURE__ */ React5.createElement(
|
|
3953
3987
|
"div",
|
|
3954
3988
|
{
|
|
3955
|
-
className:
|
|
3989
|
+
className: `ui-overlay pointer-events-auto relative group h-full border-l border-white/10 bg-slate-950/95 shadow-2xl text-white flex flex-col ${isResizing ? "transition-none" : "transition-all duration-300 ease-out"}`,
|
|
3990
|
+
style: { width: `${panelWidth}px`, maxWidth: "90vw" },
|
|
3956
3991
|
onClick: swallow,
|
|
3957
3992
|
onPointerDown: swallow,
|
|
3958
3993
|
onPointerMove: swallow,
|
|
@@ -3961,6 +3996,17 @@ function DescriptionEditModal({
|
|
|
3961
3996
|
onContextMenu: swallow,
|
|
3962
3997
|
onDoubleClick: swallow
|
|
3963
3998
|
},
|
|
3999
|
+
/* @__PURE__ */ React5.createElement(
|
|
4000
|
+
"div",
|
|
4001
|
+
{
|
|
4002
|
+
onPointerDown: (e) => {
|
|
4003
|
+
e.stopPropagation();
|
|
4004
|
+
handleResize(e);
|
|
4005
|
+
},
|
|
4006
|
+
className: "absolute left-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-indigo-500/50 z-[2000] transition-colors",
|
|
4007
|
+
title: "Arraste para redimensionar"
|
|
4008
|
+
}
|
|
4009
|
+
),
|
|
3964
4010
|
/* @__PURE__ */ React5.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0 shrink-0" }),
|
|
3965
4011
|
/* @__PURE__ */ React5.createElement("div", { className: "px-6 pt-5 pb-3 flex items-center justify-between gap-4 shrink-0" }, /* @__PURE__ */ React5.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React5.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80" }), /* @__PURE__ */ React5.createElement("p", { className: "text-sm font-medium text-slate-200" }, title || "Editar Descri\xE7\xE3o")), /* @__PURE__ */ React5.createElement("button", { onClick: handleClose, 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")),
|
|
3966
4012
|
/* @__PURE__ */ React5.createElement("div", { className: "px-6 py-3 flex flex-col gap-3 border-b border-white/5 bg-white/5 shrink-0" }, /* @__PURE__ */ React5.createElement("div", { className: "flex items-center gap-2 overflow-x-auto custom-scrollbar" }, /* @__PURE__ */ React5.createElement(
|
|
@@ -4152,11 +4198,11 @@ function DescriptionEditModal({
|
|
|
4152
4198
|
}
|
|
4153
4199
|
|
|
4154
4200
|
// src/components/DescriptionDisplay.jsx
|
|
4155
|
-
import React6, { useMemo as useMemo5, useState as
|
|
4201
|
+
import React6, { useMemo as useMemo5, useState as useState7, useEffect as useEffect6, useRef as useRef6 } from "react";
|
|
4156
4202
|
import { FiCopy as FiCopy2, FiCheck as FiCheck3, FiChevronDown as FiChevronDown3, FiChevronRight as FiChevronRight2, FiTerminal as FiTerminal2, FiCornerDownRight, FiExternalLink as FiExternalLink2, FiImage as FiImage2 } from "react-icons/fi";
|
|
4157
4203
|
var CodeBlock2 = ({ content, isActive, onClick }) => {
|
|
4158
|
-
const [isExpanded, setIsExpanded] =
|
|
4159
|
-
const [copied, setCopied] =
|
|
4204
|
+
const [isExpanded, setIsExpanded] = useState7(false);
|
|
4205
|
+
const [copied, setCopied] = useState7(false);
|
|
4160
4206
|
const cleanContent = content.replace(/^```|```$/g, "").trim();
|
|
4161
4207
|
const isLongCode = cleanContent.split("\n").length > 4;
|
|
4162
4208
|
const handleCopy = (e) => {
|
|
@@ -4355,7 +4401,7 @@ function DescriptionDisplay({
|
|
|
4355
4401
|
});
|
|
4356
4402
|
return navItems;
|
|
4357
4403
|
}, [sections]);
|
|
4358
|
-
const [currentStepIndex, setCurrentStepIndex] =
|
|
4404
|
+
const [currentStepIndex, setCurrentStepIndex] = useState7(0);
|
|
4359
4405
|
const activeRef = useRef6(null);
|
|
4360
4406
|
const lastNotifiedSectionId = useRef6(null);
|
|
4361
4407
|
const isInitialMount = useRef6(true);
|
|
@@ -4536,7 +4582,7 @@ function DescriptionDisplay({
|
|
|
4536
4582
|
}
|
|
4537
4583
|
|
|
4538
4584
|
// src/components/DescriptionReadModePanel.jsx
|
|
4539
|
-
import React7, { useState as
|
|
4585
|
+
import React7, { useState as useState8, useMemo as useMemo6, useEffect as useEffect7 } from "react";
|
|
4540
4586
|
import {
|
|
4541
4587
|
FiArrowLeft,
|
|
4542
4588
|
FiEdit2,
|
|
@@ -4638,10 +4684,10 @@ function DescriptionReadModePanel({
|
|
|
4638
4684
|
onRenderAbstractionTree = null,
|
|
4639
4685
|
initialShowAbstraction = false
|
|
4640
4686
|
}) {
|
|
4641
|
-
const [showProperties, setShowProperties] =
|
|
4642
|
-
const [showAbstraction, setShowAbstraction] =
|
|
4643
|
-
const [targetRenderNodeId, setTargetRenderNodeId] =
|
|
4644
|
-
const [isLinkCopied, setIsLinkCopied] =
|
|
4687
|
+
const [showProperties, setShowProperties] = useState8(false);
|
|
4688
|
+
const [showAbstraction, setShowAbstraction] = useState8(false);
|
|
4689
|
+
const [targetRenderNodeId, setTargetRenderNodeId] = useState8(null);
|
|
4690
|
+
const [isLinkCopied, setIsLinkCopied] = useState8(false);
|
|
4645
4691
|
const handleCopyLink = (e) => {
|
|
4646
4692
|
e.stopPropagation();
|
|
4647
4693
|
if (!ancestryId) return;
|
|
@@ -4896,11 +4942,11 @@ function AncestryRelationshipPanel({
|
|
|
4896
4942
|
onMentionClick,
|
|
4897
4943
|
onUploadFile
|
|
4898
4944
|
}) {
|
|
4899
|
-
const [description, setDescription] =
|
|
4900
|
-
const [customProps, setCustomProps] =
|
|
4901
|
-
const [existingSections, setExistingSections] =
|
|
4902
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
4903
|
-
const [isReadMode, setIsReadMode] =
|
|
4945
|
+
const [description, setDescription] = useState9((data == null ? void 0 : data.description) ?? "");
|
|
4946
|
+
const [customProps, setCustomProps] = useState9(() => extractCustomPropsFromNode(data || {}));
|
|
4947
|
+
const [existingSections, setExistingSections] = useState9((data == null ? void 0 : data.description_sections) || []);
|
|
4948
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState9(false);
|
|
4949
|
+
const [isReadMode, setIsReadMode] = useState9(false);
|
|
4904
4950
|
const propsEndRef = useRef7(null);
|
|
4905
4951
|
useEffect8(() => {
|
|
4906
4952
|
setDescription((data == null ? void 0 : data.description) ?? "");
|
|
@@ -5042,7 +5088,7 @@ function AncestryRelationshipPanel({
|
|
|
5042
5088
|
}
|
|
5043
5089
|
|
|
5044
5090
|
// src/components/CreateAncestryPanel.jsx
|
|
5045
|
-
import React10, { useState as
|
|
5091
|
+
import React10, { useState as useState11, useEffect as useEffect10, useMemo as useMemo8, useRef as useRef8, useCallback as useCallback2 } from "react";
|
|
5046
5092
|
import {
|
|
5047
5093
|
FiEdit2 as FiEdit23,
|
|
5048
5094
|
FiBookOpen as FiBookOpen2,
|
|
@@ -5062,7 +5108,7 @@ import {
|
|
|
5062
5108
|
} from "react-icons/fi";
|
|
5063
5109
|
|
|
5064
5110
|
// src/components/AncestryPickerModal.jsx
|
|
5065
|
-
import React9, { useState as
|
|
5111
|
+
import React9, { useState as useState10, useMemo as useMemo7, useEffect as useEffect9 } from "react";
|
|
5066
5112
|
import { FiSearch as FiSearch3, FiLayers as FiLayers4, FiCornerUpRight as FiCornerUpRight2 } from "react-icons/fi";
|
|
5067
5113
|
function AncestryPickerModal({
|
|
5068
5114
|
isOpen,
|
|
@@ -5072,7 +5118,7 @@ function AncestryPickerModal({
|
|
|
5072
5118
|
availableNodes = [],
|
|
5073
5119
|
currentAncestryId
|
|
5074
5120
|
}) {
|
|
5075
|
-
const [searchTerm, setSearchTerm] =
|
|
5121
|
+
const [searchTerm, setSearchTerm] = useState10("");
|
|
5076
5122
|
useEffect9(() => {
|
|
5077
5123
|
if (!isOpen) return;
|
|
5078
5124
|
const handleKeyDown = (e) => {
|
|
@@ -5157,7 +5203,7 @@ var NodeItem = ({ nodeData, onSelectParent, onViewSelect, highlightedPathIds = [
|
|
|
5157
5203
|
var _a, _b;
|
|
5158
5204
|
const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
|
|
5159
5205
|
const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
|
|
5160
|
-
const [isDragOver, setIsDragOver] =
|
|
5206
|
+
const [isDragOver, setIsDragOver] = useState11(false);
|
|
5161
5207
|
const isSelectedParent = String(selectedParentId) === String(itemId);
|
|
5162
5208
|
const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
|
|
5163
5209
|
const isHighlightedPath = highlightedPathIds.includes(String(itemId));
|
|
@@ -5293,8 +5339,8 @@ function CreateAncestryPanel({
|
|
|
5293
5339
|
isAddingNodes,
|
|
5294
5340
|
currentAncestryId
|
|
5295
5341
|
} = ancestryMode;
|
|
5296
|
-
const [isSaving, setIsSaving] =
|
|
5297
|
-
const [isLinkCopied, setIsLinkCopied] =
|
|
5342
|
+
const [isSaving, setIsSaving] = useState11(false);
|
|
5343
|
+
const [isLinkCopied, setIsLinkCopied] = useState11(false);
|
|
5298
5344
|
const handleCopyLink = (e) => {
|
|
5299
5345
|
e.stopPropagation();
|
|
5300
5346
|
if (!currentAncestryId || currentAncestryId === "temp_root" || currentAncestryId === "temp_creating") {
|
|
@@ -5308,11 +5354,11 @@ function CreateAncestryPanel({
|
|
|
5308
5354
|
setTimeout(() => setIsLinkCopied(false), 2e3);
|
|
5309
5355
|
}).catch((err) => console.error("Erro ao copiar link:", err));
|
|
5310
5356
|
};
|
|
5311
|
-
const [isPickerOpen, setIsPickerOpen] =
|
|
5312
|
-
const [customProps, setCustomProps] =
|
|
5357
|
+
const [isPickerOpen, setIsPickerOpen] = useState11(false);
|
|
5358
|
+
const [customProps, setCustomProps] = useState11([]);
|
|
5313
5359
|
const propsEndRef = useRef8(null);
|
|
5314
|
-
const [branchStack, setBranchStack] =
|
|
5315
|
-
const [targetRenderNodeId, setTargetRenderNodeId] =
|
|
5360
|
+
const [branchStack, setBranchStack] = useState11([]);
|
|
5361
|
+
const [targetRenderNodeId, setTargetRenderNodeId] = useState11(null);
|
|
5316
5362
|
const highlightedPathIds = useMemo8(() => {
|
|
5317
5363
|
var _a, _b;
|
|
5318
5364
|
if (!targetRenderNodeId || !ancestryMode.abstraction_tree) return [];
|
|
@@ -5326,17 +5372,26 @@ function CreateAncestryPanel({
|
|
|
5326
5372
|
}
|
|
5327
5373
|
return ids;
|
|
5328
5374
|
}, [targetRenderNodeId, ancestryMode.abstraction_tree]);
|
|
5329
|
-
const [targetScrollSectionId, setTargetScrollSectionId] =
|
|
5330
|
-
const [internalHighlightedNodeId, setInternalHighlightedNodeId] =
|
|
5331
|
-
const [ancestryName, setAncestryName] =
|
|
5332
|
-
const [description, setDescription] =
|
|
5333
|
-
const [existingSections, setExistingSections] =
|
|
5334
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
5335
|
-
const [isReadMode, setIsReadMode] =
|
|
5375
|
+
const [targetScrollSectionId, setTargetScrollSectionId] = useState11(null);
|
|
5376
|
+
const [internalHighlightedNodeId, setInternalHighlightedNodeId] = useState11(null);
|
|
5377
|
+
const [ancestryName, setAncestryName] = useState11(initialName);
|
|
5378
|
+
const [description, setDescription] = useState11(initialDescription || "");
|
|
5379
|
+
const [existingSections, setExistingSections] = useState11(initialSections || []);
|
|
5380
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState11(false);
|
|
5381
|
+
const [isReadMode, setIsReadMode] = useState11(false);
|
|
5382
|
+
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
5383
|
+
const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
|
|
5384
|
+
initialWidth: isReadMode ? 700 : 440,
|
|
5385
|
+
minWidth: 320,
|
|
5386
|
+
maxWidth: maxPanelW
|
|
5387
|
+
});
|
|
5388
|
+
useEffect10(() => {
|
|
5389
|
+
setWidth(isReadMode ? 700 : 440);
|
|
5390
|
+
}, [isReadMode, setWidth]);
|
|
5336
5391
|
const currentMaxRenderIndexRef = useRef8(0);
|
|
5337
5392
|
const branchProgressMapRef = useRef8({});
|
|
5338
|
-
const [lastSavedSnapshot, setLastSavedSnapshot] =
|
|
5339
|
-
const [isPrivate, setIsPrivate] =
|
|
5393
|
+
const [lastSavedSnapshot, setLastSavedSnapshot] = useState11(null);
|
|
5394
|
+
const [isPrivate, setIsPrivate] = useState11(ancestryMode.is_private || false);
|
|
5340
5395
|
const initializedContextIdRef = useRef8(null);
|
|
5341
5396
|
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
5342
5397
|
const handleImageClickFromText = (url, name) => {
|
|
@@ -5355,7 +5410,7 @@ function CreateAncestryPanel({
|
|
|
5355
5410
|
}
|
|
5356
5411
|
setAncestryMode((prev) => isAbstraction ? { ...prev, isAddingAbstractionNodes: !prev.isAddingAbstractionNodes } : { ...prev, isAddingNodes: !prev.isAddingNodes });
|
|
5357
5412
|
};
|
|
5358
|
-
const handleRemoveNode =
|
|
5413
|
+
const handleRemoveNode = useCallback2((pathToRemove, isAbstraction = false) => {
|
|
5359
5414
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) return;
|
|
5360
5415
|
const treeKey = isAbstraction ? "abstraction_tree" : "tree";
|
|
5361
5416
|
setAncestryMode((prev) => {
|
|
@@ -6311,10 +6366,8 @@ function CreateAncestryPanel({
|
|
|
6311
6366
|
return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
|
|
6312
6367
|
"div",
|
|
6313
6368
|
{
|
|
6314
|
-
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
|
|
6315
|
-
|
|
6316
|
-
`,
|
|
6317
|
-
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)" },
|
|
6369
|
+
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"}`,
|
|
6370
|
+
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${panelWidth}px`, maxWidth: "92vw" },
|
|
6318
6371
|
onPointerDown: swallow,
|
|
6319
6372
|
onPointerMove: swallow,
|
|
6320
6373
|
onPointerUp: swallow,
|
|
@@ -6323,6 +6376,17 @@ function CreateAncestryPanel({
|
|
|
6323
6376
|
onContextMenu: swallow,
|
|
6324
6377
|
onDoubleClick: swallow
|
|
6325
6378
|
},
|
|
6379
|
+
/* @__PURE__ */ React10.createElement(
|
|
6380
|
+
"div",
|
|
6381
|
+
{
|
|
6382
|
+
onPointerDown: (e) => {
|
|
6383
|
+
e.stopPropagation();
|
|
6384
|
+
handleResize(e);
|
|
6385
|
+
},
|
|
6386
|
+
className: "absolute left-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-indigo-500/50 z-[2000] transition-colors",
|
|
6387
|
+
title: "Arraste para redimensionar"
|
|
6388
|
+
}
|
|
6389
|
+
),
|
|
6326
6390
|
isReadMode ? /* @__PURE__ */ React10.createElement(
|
|
6327
6391
|
DescriptionReadModePanel,
|
|
6328
6392
|
{
|
|
@@ -6619,25 +6683,25 @@ function CreateAncestryPanel({
|
|
|
6619
6683
|
}
|
|
6620
6684
|
|
|
6621
6685
|
// src/components/ImageViewer.jsx
|
|
6622
|
-
import React11, { useState as
|
|
6686
|
+
import React11, { useState as useState12, useEffect as useEffect11, useLayoutEffect as useLayoutEffect2, useCallback as useCallback3 } from "react";
|
|
6623
6687
|
import { FiX as FiX2, FiChevronLeft as FiChevronLeft3, FiChevronRight as FiChevronRight5 } from "react-icons/fi";
|
|
6624
6688
|
function ImageViewer({ data, onClose }) {
|
|
6625
6689
|
var _a;
|
|
6626
6690
|
const { images = [], startIndex = 0, visible } = data;
|
|
6627
|
-
const [currentIndex, setCurrentIndex] =
|
|
6628
|
-
const [isLoading, setIsLoading] =
|
|
6629
|
-
const [loadedSrc, setLoadedSrc] =
|
|
6691
|
+
const [currentIndex, setCurrentIndex] = useState12(startIndex);
|
|
6692
|
+
const [isLoading, setIsLoading] = useState12(false);
|
|
6693
|
+
const [loadedSrc, setLoadedSrc] = useState12(null);
|
|
6630
6694
|
useLayoutEffect2(() => {
|
|
6631
6695
|
if (visible) {
|
|
6632
6696
|
setCurrentIndex(startIndex);
|
|
6633
6697
|
}
|
|
6634
6698
|
}, [visible, startIndex]);
|
|
6635
|
-
const handleNext =
|
|
6699
|
+
const handleNext = useCallback3(() => {
|
|
6636
6700
|
if (images.length > 1) {
|
|
6637
6701
|
setCurrentIndex((prev) => (prev + 1) % images.length);
|
|
6638
6702
|
}
|
|
6639
6703
|
}, [images.length]);
|
|
6640
|
-
const handlePrev =
|
|
6704
|
+
const handlePrev = useCallback3(() => {
|
|
6641
6705
|
if (images.length > 1) {
|
|
6642
6706
|
setCurrentIndex((prev) => (prev - 1 + images.length) % images.length);
|
|
6643
6707
|
}
|
|
@@ -6742,10 +6806,10 @@ function ImageViewer({ data, onClose }) {
|
|
|
6742
6806
|
}
|
|
6743
6807
|
|
|
6744
6808
|
// src/components/InSceneCreationForm.jsx
|
|
6745
|
-
import React13, { useState as
|
|
6809
|
+
import React13, { useState as useState14, useEffect as useEffect13, useRef as useRef10 } from "react";
|
|
6746
6810
|
|
|
6747
6811
|
// src/components/ColorPicker.jsx
|
|
6748
|
-
import React12, { useState as
|
|
6812
|
+
import React12, { useState as useState13, useEffect as useEffect12, useRef as useRef9 } from "react";
|
|
6749
6813
|
import { HexColorPicker } from "react-colorful";
|
|
6750
6814
|
import { FiHash, FiCheck as FiCheck6 } from "react-icons/fi";
|
|
6751
6815
|
var PRESET_COLORS = [
|
|
@@ -6766,7 +6830,7 @@ var PRESET_COLORS = [
|
|
|
6766
6830
|
"#000000"
|
|
6767
6831
|
];
|
|
6768
6832
|
function ColorPicker({ color, onChange, disabled }) {
|
|
6769
|
-
const [isOpen, setIsOpen] =
|
|
6833
|
+
const [isOpen, setIsOpen] = useState13(false);
|
|
6770
6834
|
const popoverRef = useRef9(null);
|
|
6771
6835
|
useEffect12(() => {
|
|
6772
6836
|
const handleClickOutside = (event) => {
|
|
@@ -6865,21 +6929,21 @@ function InSceneCreationForm({
|
|
|
6865
6929
|
viewType
|
|
6866
6930
|
}) {
|
|
6867
6931
|
var _a;
|
|
6868
|
-
const [name, setName] =
|
|
6869
|
-
const [types, setTypes] =
|
|
6870
|
-
const [typeInput, setTypeInput] =
|
|
6871
|
-
const [color, setColor] =
|
|
6872
|
-
const [size, setSize] =
|
|
6873
|
-
const [intensity, setIntensity] =
|
|
6874
|
-
const [description, setDescription] =
|
|
6875
|
-
const [customProps, setCustomProps] =
|
|
6876
|
-
const [showTypeSuggestions, setShowTypeSuggestions] =
|
|
6877
|
-
const [filteredTypes, setFilteredTypes] =
|
|
6878
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
6879
|
-
const [useImageAsTexture, setUseImageAsTexture] =
|
|
6880
|
-
const [selectedImageUrl, setSelectedImageUrl] =
|
|
6881
|
-
const [targetDatasetId, setTargetDatasetId] =
|
|
6882
|
-
const [isDatasetDropdownOpen, setIsDatasetDropdownOpen] =
|
|
6932
|
+
const [name, setName] = useState14("");
|
|
6933
|
+
const [types, setTypes] = useState14([]);
|
|
6934
|
+
const [typeInput, setTypeInput] = useState14("");
|
|
6935
|
+
const [color, setColor] = useState14(initialColor || "#cccccc");
|
|
6936
|
+
const [size, setSize] = useState14("medium");
|
|
6937
|
+
const [intensity, setIntensity] = useState14(0);
|
|
6938
|
+
const [description, setDescription] = useState14("");
|
|
6939
|
+
const [customProps, setCustomProps] = useState14([]);
|
|
6940
|
+
const [showTypeSuggestions, setShowTypeSuggestions] = useState14(false);
|
|
6941
|
+
const [filteredTypes, setFilteredTypes] = useState14([]);
|
|
6942
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState14(false);
|
|
6943
|
+
const [useImageAsTexture, setUseImageAsTexture] = useState14(false);
|
|
6944
|
+
const [selectedImageUrl, setSelectedImageUrl] = useState14(null);
|
|
6945
|
+
const [targetDatasetId, setTargetDatasetId] = useState14(sourceNodeDatasetId || "");
|
|
6946
|
+
const [isDatasetDropdownOpen, setIsDatasetDropdownOpen] = useState14(false);
|
|
6883
6947
|
const datasetDropdownRef = useRef10(null);
|
|
6884
6948
|
useEffect13(() => {
|
|
6885
6949
|
if (sourceNodeDatasetId) setTargetDatasetId(sourceNodeDatasetId);
|
|
@@ -7212,7 +7276,7 @@ function InSceneCreationForm({
|
|
|
7212
7276
|
}
|
|
7213
7277
|
|
|
7214
7278
|
// src/components/InSceneVersionForm.jsx
|
|
7215
|
-
import React14, { useState as
|
|
7279
|
+
import React14, { useState as useState15, useEffect as useEffect14, useRef as useRef11 } from "react";
|
|
7216
7280
|
import { FiPlus as FiPlus4, FiMaximize2 as FiMaximize22, FiCheck as FiCheck8, FiEdit2 as FiEdit25 } from "react-icons/fi";
|
|
7217
7281
|
function InSceneVersionForm({
|
|
7218
7282
|
onSave,
|
|
@@ -7230,14 +7294,14 @@ function InSceneVersionForm({
|
|
|
7230
7294
|
onMentionClick,
|
|
7231
7295
|
onUploadFile
|
|
7232
7296
|
}) {
|
|
7233
|
-
const [name, setName] =
|
|
7234
|
-
const [size, setSize] =
|
|
7235
|
-
const [description, setDescription] =
|
|
7236
|
-
const [customProps, setCustomProps] =
|
|
7237
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
7297
|
+
const [name, setName] = useState15("");
|
|
7298
|
+
const [size, setSize] = useState15("medium");
|
|
7299
|
+
const [description, setDescription] = useState15("");
|
|
7300
|
+
const [customProps, setCustomProps] = useState15([{ id: v4_default(), key: "Date", type: "date", value: { type: "Data", value: "" }, isEditing: true }]);
|
|
7301
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState15(false);
|
|
7238
7302
|
const propsEndRef = useRef11(null);
|
|
7239
|
-
const [useImageAsTexture, setUseImageAsTexture] =
|
|
7240
|
-
const [selectedImageUrl, setSelectedImageUrl] =
|
|
7303
|
+
const [useImageAsTexture, setUseImageAsTexture] = useState15(false);
|
|
7304
|
+
const [selectedImageUrl, setSelectedImageUrl] = useState15(null);
|
|
7241
7305
|
const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
|
|
7242
7306
|
useEffect14(() => {
|
|
7243
7307
|
if (!hasImages && useImageAsTexture) {
|
|
@@ -7430,7 +7494,7 @@ function InSceneVersionForm({
|
|
|
7430
7494
|
}
|
|
7431
7495
|
|
|
7432
7496
|
// src/components/NodeDetailsPanel.jsx
|
|
7433
|
-
import React15, { useState as
|
|
7497
|
+
import React15, { useState as useState16, useEffect as useEffect15, useRef as useRef12 } from "react";
|
|
7434
7498
|
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";
|
|
7435
7499
|
function NodeDetailsPanel({
|
|
7436
7500
|
node,
|
|
@@ -7452,27 +7516,36 @@ function NodeDetailsPanel({
|
|
|
7452
7516
|
userRole,
|
|
7453
7517
|
currentDatasetName
|
|
7454
7518
|
}) {
|
|
7455
|
-
const [name, setName] =
|
|
7456
|
-
const [types, setTypes] =
|
|
7457
|
-
const [typeInput, setTypeInput] =
|
|
7458
|
-
const [color, setColor] =
|
|
7459
|
-
const [size, setSize] =
|
|
7460
|
-
const [description, setDescription] =
|
|
7461
|
-
const [intensity, setIntensity] =
|
|
7462
|
-
const [customProps, setCustomProps] =
|
|
7463
|
-
const [showTypeSuggestions, setShowTypeSuggestions] =
|
|
7464
|
-
const [filteredTypes, setFilteredTypes] =
|
|
7465
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
7466
|
-
const [isReadMode, setIsReadMode] =
|
|
7467
|
-
const [existingSections, setExistingSections] =
|
|
7468
|
-
const [isSaving, setIsSaving] =
|
|
7469
|
-
const [isLinkCopied, setIsLinkCopied] =
|
|
7470
|
-
const [useImageAsTexture, setUseImageAsTexture] =
|
|
7519
|
+
const [name, setName] = useState16((node == null ? void 0 : node.name) ?? "");
|
|
7520
|
+
const [types, setTypes] = useState16([]);
|
|
7521
|
+
const [typeInput, setTypeInput] = useState16("");
|
|
7522
|
+
const [color, setColor] = useState16((node == null ? void 0 : node.color) ?? "#8b5cf6");
|
|
7523
|
+
const [size, setSize] = useState16((node == null ? void 0 : node.size) ?? "medium");
|
|
7524
|
+
const [description, setDescription] = useState16((node == null ? void 0 : node.description) ?? "");
|
|
7525
|
+
const [intensity, setIntensity] = useState16((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
|
|
7526
|
+
const [customProps, setCustomProps] = useState16(() => extractCustomPropsFromNode(node || {}));
|
|
7527
|
+
const [showTypeSuggestions, setShowTypeSuggestions] = useState16(false);
|
|
7528
|
+
const [filteredTypes, setFilteredTypes] = useState16([]);
|
|
7529
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState16(false);
|
|
7530
|
+
const [isReadMode, setIsReadMode] = useState16(false);
|
|
7531
|
+
const [existingSections, setExistingSections] = useState16((node == null ? void 0 : node.description_sections) || []);
|
|
7532
|
+
const [isSaving, setIsSaving] = useState16(false);
|
|
7533
|
+
const [isLinkCopied, setIsLinkCopied] = useState16(false);
|
|
7534
|
+
const [useImageAsTexture, setUseImageAsTexture] = useState16(() => {
|
|
7471
7535
|
if ((node == null ? void 0 : node.useImageAsTexture) === "true") return true;
|
|
7472
7536
|
if ((node == null ? void 0 : node.useImageAsTexture) === "false") return false;
|
|
7473
7537
|
return !!(node == null ? void 0 : node.useImageAsTexture);
|
|
7474
7538
|
});
|
|
7475
|
-
const [selectedImageUrl, setSelectedImageUrl] =
|
|
7539
|
+
const [selectedImageUrl, setSelectedImageUrl] = useState16((node == null ? void 0 : node.textureImageUrl) ?? null);
|
|
7540
|
+
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
7541
|
+
const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
|
|
7542
|
+
initialWidth: isReadMode ? 700 : 440,
|
|
7543
|
+
minWidth: 320,
|
|
7544
|
+
maxWidth: maxPanelW
|
|
7545
|
+
});
|
|
7546
|
+
useEffect15(() => {
|
|
7547
|
+
setWidth(isReadMode ? 700 : 440);
|
|
7548
|
+
}, [isReadMode, setWidth]);
|
|
7476
7549
|
const prevNodeIdRef = useRef12(null);
|
|
7477
7550
|
const propsEndRef = useRef12(null);
|
|
7478
7551
|
const canEdit = userRole !== "viewer";
|
|
@@ -7680,10 +7753,8 @@ function NodeDetailsPanel({
|
|
|
7680
7753
|
return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
|
|
7681
7754
|
"div",
|
|
7682
7755
|
{
|
|
7683
|
-
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
|
|
7684
|
-
|
|
7685
|
-
`,
|
|
7686
|
-
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)" },
|
|
7756
|
+
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"}`,
|
|
7757
|
+
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${panelWidth}px`, maxWidth: "92vw" },
|
|
7687
7758
|
onPointerDown: swallow,
|
|
7688
7759
|
onPointerMove: swallow,
|
|
7689
7760
|
onPointerUp: swallow,
|
|
@@ -7692,6 +7763,17 @@ function NodeDetailsPanel({
|
|
|
7692
7763
|
onContextMenu: swallow,
|
|
7693
7764
|
onDoubleClick: swallow
|
|
7694
7765
|
},
|
|
7766
|
+
/* @__PURE__ */ React15.createElement(
|
|
7767
|
+
"div",
|
|
7768
|
+
{
|
|
7769
|
+
onPointerDown: (e) => {
|
|
7770
|
+
e.stopPropagation();
|
|
7771
|
+
handleResize(e);
|
|
7772
|
+
},
|
|
7773
|
+
className: "absolute left-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-indigo-500/50 z-[2000] transition-colors",
|
|
7774
|
+
title: "Arraste para redimensionar"
|
|
7775
|
+
}
|
|
7776
|
+
),
|
|
7695
7777
|
isReadMode ? /* @__PURE__ */ React15.createElement(
|
|
7696
7778
|
DescriptionReadModePanel,
|
|
7697
7779
|
{
|
|
@@ -7893,7 +7975,7 @@ function NodeDetailsPanel({
|
|
|
7893
7975
|
}
|
|
7894
7976
|
|
|
7895
7977
|
// src/components/MultiNodeContextMenu.jsx
|
|
7896
|
-
import React16, { useLayoutEffect as useLayoutEffect3, useRef as useRef13, useState as
|
|
7978
|
+
import React16, { useLayoutEffect as useLayoutEffect3, useRef as useRef13, useState as useState17, useEffect as useEffect16 } from "react";
|
|
7897
7979
|
function MultiNodeContextMenu({
|
|
7898
7980
|
data,
|
|
7899
7981
|
userRole,
|
|
@@ -7904,7 +7986,7 @@ function MultiNodeContextMenu({
|
|
|
7904
7986
|
onDeleteNodes
|
|
7905
7987
|
}) {
|
|
7906
7988
|
const menuRef = useRef13(null);
|
|
7907
|
-
const [menuPos, setMenuPos] =
|
|
7989
|
+
const [menuPos, setMenuPos] = useState17({ left: 0, top: 0 });
|
|
7908
7990
|
const ability = defineAbilityFor(userRole);
|
|
7909
7991
|
const canDelete = ability.can("delete", "Node");
|
|
7910
7992
|
useLayoutEffect3(() => {
|
|
@@ -7953,7 +8035,7 @@ function MultiNodeContextMenu({
|
|
|
7953
8035
|
}
|
|
7954
8036
|
|
|
7955
8037
|
// src/components/RelationshipDetailsPanel.jsx
|
|
7956
|
-
import React17, { useState as
|
|
8038
|
+
import React17, { useState as useState18, useEffect as useEffect17, useRef as useRef14, useMemo as useMemo9 } from "react";
|
|
7957
8039
|
import { FiPlus as FiPlus6, FiEdit2 as FiEdit27, FiLoader as FiLoader3, FiBookOpen as FiBookOpen4 } from "react-icons/fi";
|
|
7958
8040
|
function RelationshipDetailsPanel({
|
|
7959
8041
|
link,
|
|
@@ -7969,13 +8051,13 @@ function RelationshipDetailsPanel({
|
|
|
7969
8051
|
userRole
|
|
7970
8052
|
// Recebendo userRole via props
|
|
7971
8053
|
}) {
|
|
7972
|
-
const [name, setName] =
|
|
7973
|
-
const [description, setDescription] =
|
|
7974
|
-
const [customProps, setCustomProps] =
|
|
7975
|
-
const [existingSections, setExistingSections] =
|
|
7976
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
7977
|
-
const [isSaving, setIsSaving] =
|
|
7978
|
-
const [isReadMode, setIsReadMode] =
|
|
8054
|
+
const [name, setName] = useState18((link == null ? void 0 : link.name) ?? "");
|
|
8055
|
+
const [description, setDescription] = useState18((link == null ? void 0 : link.description) ?? "");
|
|
8056
|
+
const [customProps, setCustomProps] = useState18(() => extractCustomPropsFromNode(link || {}));
|
|
8057
|
+
const [existingSections, setExistingSections] = useState18((link == null ? void 0 : link.description_sections) || []);
|
|
8058
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState18(false);
|
|
8059
|
+
const [isSaving, setIsSaving] = useState18(false);
|
|
8060
|
+
const [isReadMode, setIsReadMode] = useState18(false);
|
|
7979
8061
|
const propsEndRef = useRef14(null);
|
|
7980
8062
|
const canEdit = useMemo9(() => {
|
|
7981
8063
|
const ability = defineAbilityFor(userRole);
|
|
@@ -8178,7 +8260,7 @@ function RelationshipDetailsPanel({
|
|
|
8178
8260
|
}
|
|
8179
8261
|
|
|
8180
8262
|
// src/components/RelationshipContextMenu.jsx
|
|
8181
|
-
import React18, { useLayoutEffect as useLayoutEffect4, useRef as useRef15, useState as
|
|
8263
|
+
import React18, { useLayoutEffect as useLayoutEffect4, useRef as useRef15, useState as useState19, useEffect as useEffect18, useMemo as useMemo10 } from "react";
|
|
8182
8264
|
function RelationshipContextMenu({
|
|
8183
8265
|
data,
|
|
8184
8266
|
userRole,
|
|
@@ -8190,7 +8272,7 @@ function RelationshipContextMenu({
|
|
|
8190
8272
|
onClose
|
|
8191
8273
|
}) {
|
|
8192
8274
|
const menuRef = useRef15(null);
|
|
8193
|
-
const [menuPos, setMenuPos] =
|
|
8275
|
+
const [menuPos, setMenuPos] = useState19({ left: 0, top: 0 });
|
|
8194
8276
|
const ability = useMemo10(() => defineAbilityFor(userRole), [userRole]);
|
|
8195
8277
|
const sourceName = useMemo10(
|
|
8196
8278
|
() => {
|
|
@@ -8392,7 +8474,7 @@ function LoadingScreen() {
|
|
|
8392
8474
|
}
|
|
8393
8475
|
|
|
8394
8476
|
// src/components/ImportParentFileModal.jsx
|
|
8395
|
-
import React20, { useEffect as useEffect19, useState as
|
|
8477
|
+
import React20, { useEffect as useEffect19, useState as useState20 } from "react";
|
|
8396
8478
|
function ImportParentFileModal({
|
|
8397
8479
|
isOpen,
|
|
8398
8480
|
onClose,
|
|
@@ -8403,11 +8485,11 @@ function ImportParentFileModal({
|
|
|
8403
8485
|
onFetchAvailableFiles,
|
|
8404
8486
|
currentViewName
|
|
8405
8487
|
}) {
|
|
8406
|
-
const [activeTab, setActiveTab] =
|
|
8407
|
-
const [availableDbs, setAvailableDbs] =
|
|
8408
|
-
const [availableViews, setAvailableViews] =
|
|
8409
|
-
const [selectedItem, setSelectedItem] =
|
|
8410
|
-
const [isLoading, setIsLoading] =
|
|
8488
|
+
const [activeTab, setActiveTab] = useState20("databases");
|
|
8489
|
+
const [availableDbs, setAvailableDbs] = useState20([]);
|
|
8490
|
+
const [availableViews, setAvailableViews] = useState20([]);
|
|
8491
|
+
const [selectedItem, setSelectedItem] = useState20(null);
|
|
8492
|
+
const [isLoading, setIsLoading] = useState20(false);
|
|
8411
8493
|
useEffect19(() => {
|
|
8412
8494
|
if (isOpen && session && onFetchAvailableFiles) {
|
|
8413
8495
|
const fetchData = async () => {
|
|
@@ -8553,7 +8635,7 @@ function ImportParentFileModal({
|
|
|
8553
8635
|
}
|
|
8554
8636
|
|
|
8555
8637
|
// src/components/AncestryLinkDetailsPanel.jsx
|
|
8556
|
-
import React21, { useState as
|
|
8638
|
+
import React21, { useState as useState21 } from "react";
|
|
8557
8639
|
import { FiBookOpen as FiBookOpen5 } from "react-icons/fi";
|
|
8558
8640
|
function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
|
|
8559
8641
|
var _a, _b, _c, _d;
|
|
@@ -8563,7 +8645,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
8563
8645
|
const customProps = extractCustomPropsFromNode(relationshipData);
|
|
8564
8646
|
const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
|
|
8565
8647
|
const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
|
|
8566
|
-
const [isReadMode, setIsReadMode] =
|
|
8648
|
+
const [isReadMode, setIsReadMode] = useState21(false);
|
|
8567
8649
|
const swallow = (e) => e.stopPropagation();
|
|
8568
8650
|
const handleImageClickFromText = (url, name) => {
|
|
8569
8651
|
if (onOpenImageViewer) {
|
|
@@ -8629,7 +8711,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
8629
8711
|
}
|
|
8630
8712
|
|
|
8631
8713
|
// src/components/AncestryBoard.jsx
|
|
8632
|
-
import React22, { useState as
|
|
8714
|
+
import React22, { useState as useState22, useMemo as useMemo11, useEffect as useEffect20, useRef as useRef16 } from "react";
|
|
8633
8715
|
import {
|
|
8634
8716
|
FiSearch as FiSearch4,
|
|
8635
8717
|
FiLayers as FiLayers6,
|
|
@@ -8806,11 +8888,11 @@ function AncestryBoard({
|
|
|
8806
8888
|
userRole
|
|
8807
8889
|
// [NOVO] Recebe a role do usuário
|
|
8808
8890
|
}) {
|
|
8809
|
-
const [searchTerm, setSearchTerm] =
|
|
8810
|
-
const [groups, setGroups] =
|
|
8811
|
-
const [isLoaded, setIsLoaded] =
|
|
8812
|
-
const [pickingGroupId, setPickingGroupId] =
|
|
8813
|
-
const [saveStatus, setSaveStatus] =
|
|
8891
|
+
const [searchTerm, setSearchTerm] = useState22("");
|
|
8892
|
+
const [groups, setGroups] = useState22([]);
|
|
8893
|
+
const [isLoaded, setIsLoaded] = useState22(false);
|
|
8894
|
+
const [pickingGroupId, setPickingGroupId] = useState22(null);
|
|
8895
|
+
const [saveStatus, setSaveStatus] = useState22("idle");
|
|
8814
8896
|
const canEdit = useMemo11(() => {
|
|
8815
8897
|
return userRole !== "viewer";
|
|
8816
8898
|
}, [userRole]);
|
|
@@ -9260,37 +9342,37 @@ function XViewScene({
|
|
|
9260
9342
|
const sceneDataRef = useRef17(null);
|
|
9261
9343
|
const parentDataRef = useRef17(null);
|
|
9262
9344
|
const ancestryDataRef = useRef17(null);
|
|
9263
|
-
const [isLoading, setIsLoading] =
|
|
9264
|
-
const [permissionStatus, setPermissionStatus] =
|
|
9265
|
-
const [userPermissionRole, setUserPermissionRole] =
|
|
9266
|
-
const [isInitialized, setIsInitialized] =
|
|
9267
|
-
const [sceneVersion, setSceneVersion] =
|
|
9268
|
-
const [contextMenu, setContextMenu] =
|
|
9269
|
-
const [multiContextMenu, setMultiContextMenu] =
|
|
9270
|
-
const [relationshipMenu, setRelationshipMenu] =
|
|
9271
|
-
const [creationMode, setCreationMode] =
|
|
9272
|
-
const [versionMode, setVersionMode] =
|
|
9273
|
-
const [hasFocusedInitial, setHasFocusedInitial] =
|
|
9274
|
-
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] =
|
|
9275
|
-
const [ancestryMode, setAncestryMode] =
|
|
9276
|
-
const [readingMode, setReadingMode] =
|
|
9345
|
+
const [isLoading, setIsLoading] = useState23(true);
|
|
9346
|
+
const [permissionStatus, setPermissionStatus] = useState23("loading");
|
|
9347
|
+
const [userPermissionRole, setUserPermissionRole] = useState23(null);
|
|
9348
|
+
const [isInitialized, setIsInitialized] = useState23(false);
|
|
9349
|
+
const [sceneVersion, setSceneVersion] = useState23(0);
|
|
9350
|
+
const [contextMenu, setContextMenu] = useState23({ visible: false, x: 0, y: 0, nodeData: null });
|
|
9351
|
+
const [multiContextMenu, setMultiContextMenu] = useState23({ visible: false, x: 0, y: 0, nodeIds: null });
|
|
9352
|
+
const [relationshipMenu, setRelationshipMenu] = useState23({ visible: false, x: 0, y: 0, linkObject: null });
|
|
9353
|
+
const [creationMode, setCreationMode] = useState23({ isActive: false, sourceNodeData: null });
|
|
9354
|
+
const [versionMode, setVersionMode] = useState23({ isActive: false, sourceNodeData: null });
|
|
9355
|
+
const [hasFocusedInitial, setHasFocusedInitial] = useState23(false);
|
|
9356
|
+
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState23(false);
|
|
9357
|
+
const [ancestryMode, setAncestryMode] = useState23({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
9358
|
+
const [readingMode, setReadingMode] = useState23({
|
|
9277
9359
|
isActive: false,
|
|
9278
9360
|
ancestry: null,
|
|
9279
9361
|
branchStack: [],
|
|
9280
9362
|
autoAbstraction: false
|
|
9281
9363
|
});
|
|
9282
|
-
const [formPosition, setFormPosition] =
|
|
9283
|
-
const [detailsNode, setDetailsNode] =
|
|
9284
|
-
const [detailsLink, setDetailsLink] =
|
|
9285
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] =
|
|
9286
|
-
const [imageViewer, setImageViewer] =
|
|
9287
|
-
const [editingAncestryRel, setEditingAncestryRel] =
|
|
9288
|
-
const [isImportModalOpen, setIsImportModalOpen] =
|
|
9289
|
-
const [importSuccessMessage, setImportSuccessMessage] =
|
|
9290
|
-
const [highlightedNodeId, setHighlightedNodeId] =
|
|
9291
|
-
const [isAncestryBoardOpen, setIsAncestryBoardOpen] =
|
|
9292
|
-
const [ancestryBoardData, setAncestryBoardData] =
|
|
9293
|
-
const [isSidebarOpen, setIsSidebarOpen] =
|
|
9364
|
+
const [formPosition, setFormPosition] = useState23({ left: 16, top: 16, opacity: 0 });
|
|
9365
|
+
const [detailsNode, setDetailsNode] = useState23(null);
|
|
9366
|
+
const [detailsLink, setDetailsLink] = useState23(null);
|
|
9367
|
+
const [ancestryLinkDetails, setAncestryLinkDetails] = useState23(null);
|
|
9368
|
+
const [imageViewer, setImageViewer] = useState23({ visible: false, images: [], startIndex: 0 });
|
|
9369
|
+
const [editingAncestryRel, setEditingAncestryRel] = useState23({ visible: false, data: null, path: null });
|
|
9370
|
+
const [isImportModalOpen, setIsImportModalOpen] = useState23(false);
|
|
9371
|
+
const [importSuccessMessage, setImportSuccessMessage] = useState23("");
|
|
9372
|
+
const [highlightedNodeId, setHighlightedNodeId] = useState23(null);
|
|
9373
|
+
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState23(false);
|
|
9374
|
+
const [ancestryBoardData, setAncestryBoardData] = useState23([]);
|
|
9375
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState23(false);
|
|
9294
9376
|
const mountRef = useRef17(null);
|
|
9295
9377
|
const tooltipRef = useRef17(null);
|
|
9296
9378
|
const formRef = useRef17(null);
|
|
@@ -9333,6 +9415,12 @@ function XViewScene({
|
|
|
9333
9415
|
lastDescriptionLength: 0,
|
|
9334
9416
|
highlightedNodeId: null
|
|
9335
9417
|
});
|
|
9418
|
+
const maxReadPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
9419
|
+
const { width: readModeWidth, isResizing: isReadModeResizing, handlePointerDown: handleReadModeResize } = useResizablePanel({
|
|
9420
|
+
initialWidth: 700,
|
|
9421
|
+
minWidth: 320,
|
|
9422
|
+
maxWidth: maxReadPanelW
|
|
9423
|
+
});
|
|
9336
9424
|
useEffect21(() => {
|
|
9337
9425
|
stateRef.current.ancestry = ancestryMode;
|
|
9338
9426
|
}, [ancestryMode]);
|
|
@@ -9357,10 +9445,10 @@ function XViewScene({
|
|
|
9357
9445
|
}
|
|
9358
9446
|
stateRef.current.nodeIdToParentFileMap = map;
|
|
9359
9447
|
}, [isInitialized, sceneVersion]);
|
|
9360
|
-
const handleNavigateBack =
|
|
9448
|
+
const handleNavigateBack = useCallback4(() => {
|
|
9361
9449
|
router.push("/dashboard/scenes");
|
|
9362
9450
|
}, [router]);
|
|
9363
|
-
const handleConfirmImport =
|
|
9451
|
+
const handleConfirmImport = useCallback4(
|
|
9364
9452
|
async (importPayload) => {
|
|
9365
9453
|
var _a2, _b2;
|
|
9366
9454
|
let files = [];
|
|
@@ -9408,7 +9496,6 @@ function XViewScene({
|
|
|
9408
9496
|
if (ancestryResponse.success && Array.isArray(ancestryResponse.data)) {
|
|
9409
9497
|
const viewSpecificAncestries = ancestryResponse.data.filter(
|
|
9410
9498
|
(anc) => anc._source_file_id === viewToImport.id && !anc.is_private
|
|
9411
|
-
// <--- AQUI ESTÁ A TRAVA DE SEGURANÇA
|
|
9412
9499
|
);
|
|
9413
9500
|
const processedAncestries = viewSpecificAncestries.map((anc) => ({
|
|
9414
9501
|
...anc,
|
|
@@ -9459,7 +9546,7 @@ function XViewScene({
|
|
|
9459
9546
|
const handleOpenImageViewer = (images, startIndex) => {
|
|
9460
9547
|
setImageViewer({ visible: true, images, startIndex });
|
|
9461
9548
|
};
|
|
9462
|
-
const tweenToTarget =
|
|
9549
|
+
const tweenToTarget = useCallback4((target, zoomFactor = 1, forcedDirection = null) => {
|
|
9463
9550
|
const { camera, controls, tweenGroup } = stateRef.current;
|
|
9464
9551
|
if (!camera || !controls || !tweenGroup) return;
|
|
9465
9552
|
const targetPos = target instanceof THREE3.Mesh ? target.getWorldPosition(new THREE3.Vector3()) : target;
|
|
@@ -9482,7 +9569,7 @@ function XViewScene({
|
|
|
9482
9569
|
if (!t || typeof t.closest !== "function") return false;
|
|
9483
9570
|
return !!t.closest(".ui-overlay");
|
|
9484
9571
|
};
|
|
9485
|
-
const buildFullAncestryTree =
|
|
9572
|
+
const buildFullAncestryTree = useCallback4((idTree, nodes, ancestries = []) => {
|
|
9486
9573
|
if (!idTree) return null;
|
|
9487
9574
|
const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
|
|
9488
9575
|
const ancestryMap = new Map(ancestries.map((a) => [String(a.ancestry_id), a]));
|
|
@@ -9508,14 +9595,10 @@ function XViewScene({
|
|
|
9508
9595
|
return {
|
|
9509
9596
|
...branch,
|
|
9510
9597
|
name: linkedAncestry.name,
|
|
9511
|
-
// Sobrescreve nome para exibição
|
|
9512
9598
|
description: linkedAncestry.description,
|
|
9513
|
-
// Sobrescreve descrição
|
|
9514
9599
|
description_sections: linkedAncestry.description_sections,
|
|
9515
9600
|
tree: graftedTree,
|
|
9516
|
-
// ENXERTA A ÁRVORE AQUI
|
|
9517
9601
|
isLinked: true
|
|
9518
|
-
// Flag útil
|
|
9519
9602
|
};
|
|
9520
9603
|
}
|
|
9521
9604
|
}
|
|
@@ -9562,7 +9645,7 @@ function XViewScene({
|
|
|
9562
9645
|
}
|
|
9563
9646
|
return recursiveBuild(idTree);
|
|
9564
9647
|
}, []);
|
|
9565
|
-
const handleActivateTimeline =
|
|
9648
|
+
const handleActivateTimeline = useCallback4(() => {
|
|
9566
9649
|
const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
9567
9650
|
if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
|
|
9568
9651
|
while (timelineIntervalsGroup.children.length > 0) {
|
|
@@ -9715,7 +9798,7 @@ function XViewScene({
|
|
|
9715
9798
|
}
|
|
9716
9799
|
});
|
|
9717
9800
|
}, []);
|
|
9718
|
-
const handleVersionTimeline =
|
|
9801
|
+
const handleVersionTimeline = useCallback4((sourceMesh, versionMeshes) => {
|
|
9719
9802
|
const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
9720
9803
|
if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0) return;
|
|
9721
9804
|
versionMeshes.forEach((mesh) => {
|
|
@@ -9908,16 +9991,14 @@ function XViewScene({
|
|
|
9908
9991
|
isInitialized,
|
|
9909
9992
|
permissionStatus,
|
|
9910
9993
|
focusNodeId,
|
|
9911
|
-
// <-- MANTIDO
|
|
9912
9994
|
focusAncestryId
|
|
9913
|
-
// <-- ADICIONADO O focusAncestryId NAS DEPENDÊNCIAS
|
|
9914
9995
|
]);
|
|
9915
|
-
const isNodeInView =
|
|
9996
|
+
const isNodeInView = useCallback4((id) => {
|
|
9916
9997
|
const key = String(id);
|
|
9917
9998
|
const objs = stateRef.current.nodeObjects || {};
|
|
9918
9999
|
return !!objs[key];
|
|
9919
10000
|
}, []);
|
|
9920
|
-
const addOrUpdateNodeMesh =
|
|
10001
|
+
const addOrUpdateNodeMesh = useCallback4((nodeData, position, suppressVersionUpdate = false) => {
|
|
9921
10002
|
const { graphGroup, nodeObjects, clickableNodes, glowTexture, tweenGroup } = stateRef.current;
|
|
9922
10003
|
const nodeId = String(nodeData.id);
|
|
9923
10004
|
if (nodeObjects[nodeId]) {
|
|
@@ -10566,7 +10647,7 @@ function XViewScene({
|
|
|
10566
10647
|
}
|
|
10567
10648
|
};
|
|
10568
10649
|
}, [isInitialized, tweenToTarget, dbSaveUrl, isNodeInView, addOrUpdateNodeMesh, handleActivateTimeline, get_scene_view_data, save_view_data]);
|
|
10569
|
-
const handleGhostNodeImageChange =
|
|
10650
|
+
const handleGhostNodeImageChange = useCallback4((useImage, imageUrl) => {
|
|
10570
10651
|
const { node: ghostNode, line: ghostLine, aura: ghostAura } = stateRef.current.ghostElements;
|
|
10571
10652
|
const { graphGroup, glowTexture } = stateRef.current;
|
|
10572
10653
|
if (!ghostNode || !graphGroup) return;
|
|
@@ -10608,7 +10689,7 @@ function XViewScene({
|
|
|
10608
10689
|
aura: newGhostNode.getObjectByName("aura")
|
|
10609
10690
|
};
|
|
10610
10691
|
}, []);
|
|
10611
|
-
const handleGhostNodeIntensityChange =
|
|
10692
|
+
const handleGhostNodeIntensityChange = useCallback4((newIntensity) => {
|
|
10612
10693
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
10613
10694
|
if (!ghostNode) return;
|
|
10614
10695
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -10629,7 +10710,7 @@ function XViewScene({
|
|
|
10629
10710
|
ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
|
|
10630
10711
|
}
|
|
10631
10712
|
}, []);
|
|
10632
|
-
const handleDetailNodeIntensityChange =
|
|
10713
|
+
const handleDetailNodeIntensityChange = useCallback4((nodeId, newIntensity) => {
|
|
10633
10714
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
10634
10715
|
if (!mesh) return;
|
|
10635
10716
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -10775,7 +10856,7 @@ function XViewScene({
|
|
|
10775
10856
|
mountRef.current.style.cursor = "default";
|
|
10776
10857
|
}
|
|
10777
10858
|
};
|
|
10778
|
-
const handleAncestryTreeUpdate =
|
|
10859
|
+
const handleAncestryTreeUpdate = useCallback4((newTree, extraData = null) => {
|
|
10779
10860
|
setAncestryMode((prev) => {
|
|
10780
10861
|
const prevTreeStr = JSON.stringify(prev.tree);
|
|
10781
10862
|
const newTreeStr = JSON.stringify(newTree);
|
|
@@ -10845,7 +10926,7 @@ function XViewScene({
|
|
|
10845
10926
|
const handleStartVersioning = (nodeData) => {
|
|
10846
10927
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
10847
10928
|
};
|
|
10848
|
-
const handleClearAncestryVisuals =
|
|
10929
|
+
const handleClearAncestryVisuals = useCallback4((ancestryId) => {
|
|
10849
10930
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
10850
10931
|
const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
|
|
10851
10932
|
if (renderIndex !== -1) {
|
|
@@ -10859,7 +10940,7 @@ function XViewScene({
|
|
|
10859
10940
|
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
10860
10941
|
}
|
|
10861
10942
|
}, []);
|
|
10862
|
-
const handleRenderAncestry =
|
|
10943
|
+
const handleRenderAncestry = useCallback4(
|
|
10863
10944
|
async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
|
|
10864
10945
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
10865
10946
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -11275,7 +11356,7 @@ function XViewScene({
|
|
|
11275
11356
|
},
|
|
11276
11357
|
[addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, readingMode.isActive, ancestryMode.isActive]
|
|
11277
11358
|
);
|
|
11278
|
-
const handleRenderAbstractionTree =
|
|
11359
|
+
const handleRenderAbstractionTree = useCallback4((ancestryObject, targetNodeId = null) => {
|
|
11279
11360
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11280
11361
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
11281
11362
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
@@ -11336,7 +11417,7 @@ function XViewScene({
|
|
|
11336
11417
|
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
11337
11418
|
tweenToTarget(rootTargetPos, 0.7);
|
|
11338
11419
|
}, [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, handleClearAncestryVisuals]);
|
|
11339
|
-
const handleReadModeBranchNav =
|
|
11420
|
+
const handleReadModeBranchNav = useCallback4((nodeId, action, direction = "right") => {
|
|
11340
11421
|
const { ancestry, branchStack } = readingMode;
|
|
11341
11422
|
if (!ancestry || !ancestry.tree) return;
|
|
11342
11423
|
const allAncestries = ancestryDataRef.current || [];
|
|
@@ -11374,9 +11455,7 @@ function XViewScene({
|
|
|
11374
11455
|
description_sections: branchToOpen.description_sections,
|
|
11375
11456
|
tree: branchToOpen.tree,
|
|
11376
11457
|
_originNodeId: nodeId,
|
|
11377
|
-
// <--- ID do node pai (link visual)
|
|
11378
11458
|
_branchDirection: direction
|
|
11379
|
-
// <--- Direção para cálculo de posição
|
|
11380
11459
|
};
|
|
11381
11460
|
const allowedIds = /* @__PURE__ */ new Set(["preamble", 0, "0"]);
|
|
11382
11461
|
const branchSections = parseDescriptionSections(branchToOpen.description || "", branchToOpen.description_sections || []);
|
|
@@ -11432,7 +11511,6 @@ function XViewScene({
|
|
|
11432
11511
|
const parentAncestryObj = {
|
|
11433
11512
|
...targetAncestryInfo,
|
|
11434
11513
|
tree: targetTreeToRender,
|
|
11435
|
-
// Re-injeta a origem se o pai também for uma branch aninhada
|
|
11436
11514
|
_originNodeId: activeParentStackItem ? activeParentStackItem.nodeId : null,
|
|
11437
11515
|
_branchDirection: activeParentStackItem ? activeParentStackItem.entryDirection : null
|
|
11438
11516
|
};
|
|
@@ -11480,7 +11558,7 @@ function XViewScene({
|
|
|
11480
11558
|
}));
|
|
11481
11559
|
}
|
|
11482
11560
|
}, [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]);
|
|
11483
|
-
const handleReadModeHighlight =
|
|
11561
|
+
const handleReadModeHighlight = useCallback4((nodeId) => {
|
|
11484
11562
|
if (stateRef.current.highlightedNodeId !== nodeId) {
|
|
11485
11563
|
stateRef.current.highlightedNodeId = nodeId;
|
|
11486
11564
|
}
|
|
@@ -11492,7 +11570,6 @@ function XViewScene({
|
|
|
11492
11570
|
readingMode.ancestry.tree,
|
|
11493
11571
|
Object.values(parentDataRef.current).flatMap((f) => f.nodes),
|
|
11494
11572
|
ancestryDataRef.current
|
|
11495
|
-
// <--- Adicionar
|
|
11496
11573
|
);
|
|
11497
11574
|
const findNodeInTree = (tree, targetId) => {
|
|
11498
11575
|
if (!tree) return null;
|
|
@@ -11546,7 +11623,6 @@ function XViewScene({
|
|
|
11546
11623
|
description_sections: ancestry.description_sections,
|
|
11547
11624
|
direction: null,
|
|
11548
11625
|
customProperties: rootProps
|
|
11549
|
-
// <--- ADICIONADO
|
|
11550
11626
|
};
|
|
11551
11627
|
}
|
|
11552
11628
|
const fullTree = buildFullAncestryTree(
|
|
@@ -11575,7 +11651,6 @@ function XViewScene({
|
|
|
11575
11651
|
description_sections: currentMeta.description_sections,
|
|
11576
11652
|
direction: currentDirection,
|
|
11577
11653
|
customProperties: branchProps
|
|
11578
|
-
// <--- ADICIONADO
|
|
11579
11654
|
};
|
|
11580
11655
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
11581
11656
|
const readModeAbstractionTree = useMemo12(() => {
|
|
@@ -11590,7 +11665,7 @@ function XViewScene({
|
|
|
11590
11665
|
allAncestries
|
|
11591
11666
|
);
|
|
11592
11667
|
}, [readingMode.isActive, readingMode.ancestry, buildFullAncestryTree, sceneVersion]);
|
|
11593
|
-
const handleStartReadingAncestry =
|
|
11668
|
+
const handleStartReadingAncestry = useCallback4(
|
|
11594
11669
|
async (ancestryObject) => {
|
|
11595
11670
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11596
11671
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -11611,7 +11686,6 @@ function XViewScene({
|
|
|
11611
11686
|
ancestry: ancestryObject,
|
|
11612
11687
|
branchStack: [],
|
|
11613
11688
|
autoAbstraction: shouldAutoRenderAbstraction
|
|
11614
|
-
// <--- FLAG ENVIADA PARA A UI
|
|
11615
11689
|
});
|
|
11616
11690
|
if (shouldAutoRenderAbstraction) {
|
|
11617
11691
|
handleRenderAbstractionTree(ancestryObject, null);
|
|
@@ -11625,9 +11699,8 @@ function XViewScene({
|
|
|
11625
11699
|
}
|
|
11626
11700
|
},
|
|
11627
11701
|
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
11628
|
-
// <--- DEPENDÊNCIA ADICIONADA
|
|
11629
11702
|
);
|
|
11630
|
-
const handleReadModeSectionChange =
|
|
11703
|
+
const handleReadModeSectionChange = useCallback4((activeSectionId) => {
|
|
11631
11704
|
const { ancestry, branchStack } = readingMode;
|
|
11632
11705
|
if (!ancestry || !readingMode.isActive) return;
|
|
11633
11706
|
let targetObj = ancestry;
|
|
@@ -11696,10 +11769,10 @@ function XViewScene({
|
|
|
11696
11769
|
}, 0);
|
|
11697
11770
|
handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
|
|
11698
11771
|
}, [readingMode, handleRenderAncestry, buildFullAncestryTree, ancestryDataRef.current]);
|
|
11699
|
-
const handleCloseReadMode =
|
|
11772
|
+
const handleCloseReadMode = useCallback4(() => {
|
|
11700
11773
|
setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
|
|
11701
11774
|
}, []);
|
|
11702
|
-
const handleAncestrySectionChange =
|
|
11775
|
+
const handleAncestrySectionChange = useCallback4((activeSectionId, ancestryOverride = null, rotation = 0) => {
|
|
11703
11776
|
var _a2, _b2;
|
|
11704
11777
|
const currentMode = stateRef.current.ancestry;
|
|
11705
11778
|
let targetObj = ancestryOverride;
|
|
@@ -11751,7 +11824,7 @@ function XViewScene({
|
|
|
11751
11824
|
const renderPayload = { ...targetObj, tree: treeToRender };
|
|
11752
11825
|
handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
|
|
11753
11826
|
}, [handleRenderAncestry]);
|
|
11754
|
-
const handleEditAncestry =
|
|
11827
|
+
const handleEditAncestry = useCallback4(
|
|
11755
11828
|
async (ancestryObject) => {
|
|
11756
11829
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11757
11830
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -11774,10 +11847,8 @@ function XViewScene({
|
|
|
11774
11847
|
...ancestryObject,
|
|
11775
11848
|
tree: fullTree,
|
|
11776
11849
|
abstraction_tree: fullAbstractionTree,
|
|
11777
|
-
// NOVO
|
|
11778
11850
|
selectedParentId: ancestryObject.ancestral_node,
|
|
11779
11851
|
selectedAbstractionParentId: ancestryObject.ancestral_node,
|
|
11780
|
-
// NOVO
|
|
11781
11852
|
isEditMode: true,
|
|
11782
11853
|
currentAncestryId: ancestryObject.ancestry_id,
|
|
11783
11854
|
ancestryName: ancestryObject.name || `Ancestralidade ${fullTree.node.name}`,
|
|
@@ -11785,7 +11856,6 @@ function XViewScene({
|
|
|
11785
11856
|
ancestryDescriptionSections: ancestryObject.description_sections || [],
|
|
11786
11857
|
isAddingNodes: false,
|
|
11787
11858
|
isAddingAbstractionNodes: false
|
|
11788
|
-
// NOVO
|
|
11789
11859
|
});
|
|
11790
11860
|
},
|
|
11791
11861
|
[handleRenderAncestry, buildFullAncestryTree]
|
|
@@ -11793,7 +11863,7 @@ function XViewScene({
|
|
|
11793
11863
|
const handleSelectAncestryParent = (nodeId) => {
|
|
11794
11864
|
setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
|
|
11795
11865
|
};
|
|
11796
|
-
const handleRemoveFromAncestry =
|
|
11866
|
+
const handleRemoveFromAncestry = useCallback4((pathToRemove) => {
|
|
11797
11867
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
|
|
11798
11868
|
console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
|
|
11799
11869
|
return;
|
|
@@ -11818,7 +11888,7 @@ function XViewScene({
|
|
|
11818
11888
|
return { ...prev, tree: newTree };
|
|
11819
11889
|
});
|
|
11820
11890
|
}, []);
|
|
11821
|
-
const handleSaveAncestry =
|
|
11891
|
+
const handleSaveAncestry = useCallback4(
|
|
11822
11892
|
async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
|
|
11823
11893
|
const treeToUse = treeOverride || ancestryMode.tree;
|
|
11824
11894
|
const { isEditMode, currentAncestryId } = ancestryMode;
|
|
@@ -12022,7 +12092,7 @@ function XViewScene({
|
|
|
12022
12092
|
});
|
|
12023
12093
|
setEditingAncestryRel({ visible: false, data: null, path: null });
|
|
12024
12094
|
};
|
|
12025
|
-
const handleDeleteAncestry =
|
|
12095
|
+
const handleDeleteAncestry = useCallback4(
|
|
12026
12096
|
async (ancestryIdToDelete) => {
|
|
12027
12097
|
if (!ancestryIdToDelete) {
|
|
12028
12098
|
alert("ID da ancestralidade n\xE3o encontrado.");
|
|
@@ -12084,15 +12154,15 @@ function XViewScene({
|
|
|
12084
12154
|
},
|
|
12085
12155
|
[save_view_data, delete_file_action]
|
|
12086
12156
|
);
|
|
12087
|
-
const handleOpenAncestryBoard =
|
|
12157
|
+
const handleOpenAncestryBoard = useCallback4(() => {
|
|
12088
12158
|
setIsAncestryBoardOpen(true);
|
|
12089
12159
|
}, []);
|
|
12090
|
-
const handleSelectAncestryFromBoard =
|
|
12160
|
+
const handleSelectAncestryFromBoard = useCallback4((ancestry) => {
|
|
12091
12161
|
setIsAncestryBoardOpen(false);
|
|
12092
12162
|
setIsSidebarOpen(false);
|
|
12093
12163
|
handleStartReadingAncestry(ancestry);
|
|
12094
12164
|
}, [handleStartReadingAncestry]);
|
|
12095
|
-
const handleSaveAncestryBoard =
|
|
12165
|
+
const handleSaveAncestryBoard = useCallback4(async (groups) => {
|
|
12096
12166
|
if (!sceneConfigId || !viewParams || !session) return;
|
|
12097
12167
|
const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
|
|
12098
12168
|
await save_ancestry_board_action(sceneConfigId, sceneType, groups, session, ownerId);
|
|
@@ -12116,13 +12186,13 @@ function XViewScene({
|
|
|
12116
12186
|
return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
|
|
12117
12187
|
});
|
|
12118
12188
|
}, [parentDataRef.current, sceneVersion]);
|
|
12119
|
-
const handleAddExistingNode =
|
|
12189
|
+
const handleAddExistingNode = useCallback4(
|
|
12120
12190
|
(nodeId) => {
|
|
12121
12191
|
return userActionHandlers.handleAddExistingNodeById(actionHandlerContext, nodeId);
|
|
12122
12192
|
},
|
|
12123
12193
|
[actionHandlerContext]
|
|
12124
12194
|
);
|
|
12125
|
-
const handleSaveCurrentView =
|
|
12195
|
+
const handleSaveCurrentView = useCallback4(async () => {
|
|
12126
12196
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
12127
12197
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
12128
12198
|
console.warn("N\xE3o \xE9 poss\xEDvel salvar a cena: estado n\xE3o inicializado ou URL de salvamento ausente.");
|
|
@@ -12162,7 +12232,7 @@ function XViewScene({
|
|
|
12162
12232
|
const allAvailableAncestries = useMemo12(() => {
|
|
12163
12233
|
return ancestryDataRef.current || [];
|
|
12164
12234
|
}, [sceneVersion, isInitialized]);
|
|
12165
|
-
const handleOpenReference =
|
|
12235
|
+
const handleOpenReference = useCallback4((referenceData) => {
|
|
12166
12236
|
const { type, id } = referenceData;
|
|
12167
12237
|
if (type === "node") {
|
|
12168
12238
|
const targetNode = allAvailableNodes.find((n) => String(n.id) === String(id));
|
|
@@ -12189,10 +12259,10 @@ function XViewScene({
|
|
|
12189
12259
|
}
|
|
12190
12260
|
}
|
|
12191
12261
|
}, [allAvailableNodes, allAvailableAncestries, handleEditAncestry, tweenToTarget]);
|
|
12192
|
-
const handleToggleAncestryAddMode =
|
|
12262
|
+
const handleToggleAncestryAddMode = useCallback4(() => {
|
|
12193
12263
|
setAncestryMode((prev) => ({ ...prev, isAddingNodes: !prev.isAddingNodes }));
|
|
12194
12264
|
}, []);
|
|
12195
|
-
const handleFocusNode =
|
|
12265
|
+
const handleFocusNode = useCallback4((nodeData) => {
|
|
12196
12266
|
if (!nodeData) return;
|
|
12197
12267
|
const nodeMesh = stateRef.current.nodeObjects[String(nodeData.id)];
|
|
12198
12268
|
if (nodeMesh) {
|
|
@@ -12262,7 +12332,6 @@ function XViewScene({
|
|
|
12262
12332
|
height: "100vh",
|
|
12263
12333
|
position: "relative",
|
|
12264
12334
|
overflow: "hidden",
|
|
12265
|
-
// <--- ADICIONE ESTA LINHA
|
|
12266
12335
|
cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
|
|
12267
12336
|
}
|
|
12268
12337
|
},
|
|
@@ -12329,9 +12398,20 @@ function XViewScene({
|
|
|
12329
12398
|
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React23.createElement(
|
|
12330
12399
|
"div",
|
|
12331
12400
|
{
|
|
12332
|
-
className:
|
|
12333
|
-
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)" }
|
|
12401
|
+
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"}`,
|
|
12402
|
+
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${readModeWidth}px`, maxWidth: "92vw" }
|
|
12334
12403
|
},
|
|
12404
|
+
/* @__PURE__ */ React23.createElement(
|
|
12405
|
+
"div",
|
|
12406
|
+
{
|
|
12407
|
+
onPointerDown: (e) => {
|
|
12408
|
+
e.stopPropagation();
|
|
12409
|
+
handleReadModeResize(e);
|
|
12410
|
+
},
|
|
12411
|
+
className: "absolute left-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-indigo-500/50 z-[2000] transition-colors",
|
|
12412
|
+
title: "Arraste para redimensionar"
|
|
12413
|
+
}
|
|
12414
|
+
),
|
|
12335
12415
|
/* @__PURE__ */ React23.createElement(
|
|
12336
12416
|
DescriptionReadModePanel,
|
|
12337
12417
|
{
|