@lv-x-software-house/x_view 1.2.2-dev.12 → 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 +969 -817
- package/dist/index.mjs +405 -253
- 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,12 +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] =
|
|
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);
|
|
3445
3475
|
const sectionRefs = useRef4([]);
|
|
3446
|
-
const [isDropdownOpen, setIsDropdownOpen] =
|
|
3476
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState5(false);
|
|
3447
3477
|
const inputRef = useRef4(null);
|
|
3448
3478
|
useEffect4(() => {
|
|
3449
3479
|
if (!selectedItem) return;
|
|
@@ -3490,6 +3520,8 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
3490
3520
|
}, [selectedItem]);
|
|
3491
3521
|
useEffect4(() => {
|
|
3492
3522
|
setActiveIndex(0);
|
|
3523
|
+
setSelectedIndices(/* @__PURE__ */ new Set([0]));
|
|
3524
|
+
setLastSelectedIndex(0);
|
|
3493
3525
|
}, [selectedItem]);
|
|
3494
3526
|
useEffect4(() => {
|
|
3495
3527
|
if (selectedItem && sectionRefs.current[activeIndex]) {
|
|
@@ -3506,22 +3538,64 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
3506
3538
|
if (document.activeElement === inputRef.current) return;
|
|
3507
3539
|
if (e.key === "ArrowDown" || e.key === "ArrowRight") {
|
|
3508
3540
|
e.preventDefault();
|
|
3509
|
-
setActiveIndex((prev) =>
|
|
3541
|
+
setActiveIndex((prev) => {
|
|
3542
|
+
const next = Math.min(prev + 1, itemSections.length - 1);
|
|
3543
|
+
if (e.shiftKey) {
|
|
3544
|
+
setSelectedIndices((old) => /* @__PURE__ */ new Set([...old, next]));
|
|
3545
|
+
} else if (!e.ctrlKey && !e.metaKey) {
|
|
3546
|
+
setSelectedIndices(/* @__PURE__ */ new Set([next]));
|
|
3547
|
+
setLastSelectedIndex(next);
|
|
3548
|
+
}
|
|
3549
|
+
return next;
|
|
3550
|
+
});
|
|
3510
3551
|
}
|
|
3511
3552
|
if (e.key === "ArrowUp" || e.key === "ArrowLeft") {
|
|
3512
3553
|
e.preventDefault();
|
|
3513
|
-
setActiveIndex((prev) =>
|
|
3554
|
+
setActiveIndex((prev) => {
|
|
3555
|
+
const next = Math.max(prev - 1, 0);
|
|
3556
|
+
if (e.shiftKey) {
|
|
3557
|
+
setSelectedIndices((old) => /* @__PURE__ */ new Set([...old, next]));
|
|
3558
|
+
} else if (!e.ctrlKey && !e.metaKey) {
|
|
3559
|
+
setSelectedIndices(/* @__PURE__ */ new Set([next]));
|
|
3560
|
+
setLastSelectedIndex(next);
|
|
3561
|
+
}
|
|
3562
|
+
return next;
|
|
3563
|
+
});
|
|
3514
3564
|
}
|
|
3515
3565
|
if (e.key === "Enter") {
|
|
3516
3566
|
e.preventDefault();
|
|
3517
|
-
|
|
3518
|
-
handleConfirmImport(itemSections[activeIndex]);
|
|
3519
|
-
}
|
|
3567
|
+
handleConfirmImport();
|
|
3520
3568
|
}
|
|
3521
3569
|
};
|
|
3522
3570
|
window.addEventListener("keydown", handleKeyDown);
|
|
3523
3571
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
3524
|
-
}, [itemSections,
|
|
3572
|
+
}, [itemSections, selectedItem]);
|
|
3573
|
+
const handleSectionClick = (index, e) => {
|
|
3574
|
+
e.stopPropagation();
|
|
3575
|
+
if (e.shiftKey && lastSelectedIndex !== null) {
|
|
3576
|
+
const start = Math.min(lastSelectedIndex, index);
|
|
3577
|
+
const end = Math.max(lastSelectedIndex, index);
|
|
3578
|
+
const newSelection = new Set(selectedIndices);
|
|
3579
|
+
for (let i = start; i <= end; i++) {
|
|
3580
|
+
newSelection.add(i);
|
|
3581
|
+
}
|
|
3582
|
+
setSelectedIndices(newSelection);
|
|
3583
|
+
} else if (e.ctrlKey || e.metaKey) {
|
|
3584
|
+
const newSelection = new Set(selectedIndices);
|
|
3585
|
+
if (newSelection.has(index)) {
|
|
3586
|
+
newSelection.delete(index);
|
|
3587
|
+
if (newSelection.size === 0) newSelection.add(index);
|
|
3588
|
+
} else {
|
|
3589
|
+
newSelection.add(index);
|
|
3590
|
+
}
|
|
3591
|
+
setSelectedIndices(newSelection);
|
|
3592
|
+
setLastSelectedIndex(index);
|
|
3593
|
+
} else {
|
|
3594
|
+
setSelectedIndices(/* @__PURE__ */ new Set([index]));
|
|
3595
|
+
setLastSelectedIndex(index);
|
|
3596
|
+
}
|
|
3597
|
+
setActiveIndex(index);
|
|
3598
|
+
};
|
|
3525
3599
|
const handleSelectItem = (item) => {
|
|
3526
3600
|
setSelectedItem(item);
|
|
3527
3601
|
setSearchHistory((prev) => {
|
|
@@ -3535,16 +3609,22 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
3535
3609
|
setSearchTerm("");
|
|
3536
3610
|
setIsDropdownOpen(false);
|
|
3537
3611
|
};
|
|
3538
|
-
const handleConfirmImport = (
|
|
3539
|
-
|
|
3540
|
-
if (!section) return;
|
|
3612
|
+
const handleConfirmImport = () => {
|
|
3613
|
+
if (selectedIndices.size === 0) return;
|
|
3541
3614
|
const type = selectedItem._type;
|
|
3542
3615
|
const itemId = selectedItem.id || selectedItem.ancestry_id;
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3616
|
+
const indicesToImport = Array.from(selectedIndices).sort((a, b) => a - b);
|
|
3617
|
+
const tagsToImport = [];
|
|
3618
|
+
indicesToImport.forEach((idx) => {
|
|
3619
|
+
const section = itemSections[idx];
|
|
3620
|
+
if (section && section.id) {
|
|
3621
|
+
tagsToImport.push(`[[REF:${type}:${itemId}:${section.id}]]`);
|
|
3622
|
+
}
|
|
3623
|
+
});
|
|
3624
|
+
if (tagsToImport.length > 0) {
|
|
3625
|
+
onSelect(tagsToImport);
|
|
3546
3626
|
} else {
|
|
3547
|
-
alert("
|
|
3627
|
+
alert("Nenhuma se\xE7\xE3o v\xE1lida selecionada.");
|
|
3548
3628
|
}
|
|
3549
3629
|
};
|
|
3550
3630
|
const renderSectionContent = (content) => {
|
|
@@ -3615,7 +3695,8 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
3615
3695
|
/* @__PURE__ */ React4.createElement("div", { className: "truncate" }, /* @__PURE__ */ React4.createElement("div", { className: "text-sm font-medium text-slate-200 truncate" }, item.name), /* @__PURE__ */ React4.createElement("div", { className: "text-[10px] text-slate-500 uppercase tracking-wider" }, isNode ? ((_a = item.version_node) == null ? void 0 : _a.is_version) ? "Vers\xE3o" : "Node" : "Ancestralidade"))
|
|
3616
3696
|
);
|
|
3617
3697
|
}))), /* @__PURE__ */ React4.createElement("div", { className: "flex-1 flex flex-col bg-black/20 relative z-10" }, selectedItem ? /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 pr-8" }, /* @__PURE__ */ React4.createElement("div", { className: "w-full text-sm leading-relaxed text-slate-300 break-words whitespace-pre-wrap" }, itemSections.map((section, index) => {
|
|
3618
|
-
const
|
|
3698
|
+
const isSelected = selectedIndices.has(index);
|
|
3699
|
+
const isFocused = index === activeIndex;
|
|
3619
3700
|
const match = section.content.match(/^(\s*)([\s\S]*?)(\s*)$/);
|
|
3620
3701
|
let leadingSpace = match ? match[1] : "";
|
|
3621
3702
|
const bodyText = match ? match[2] : section.content;
|
|
@@ -3633,10 +3714,11 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
3633
3714
|
refAssigned = true;
|
|
3634
3715
|
}
|
|
3635
3716
|
},
|
|
3636
|
-
onClick: () =>
|
|
3717
|
+
onClick: (e) => handleSectionClick(index, e),
|
|
3637
3718
|
className: `
|
|
3638
3719
|
transition-colors duration-200 cursor-pointer rounded-md px-1 py-0.5 -mx-1 box-decoration-clone
|
|
3639
|
-
${
|
|
3720
|
+
${isSelected ? "bg-indigo-500/30 ring-1 ring-indigo-500/50" : "hover:bg-white/5"}
|
|
3721
|
+
${isFocused && !isSelected ? "ring-1 ring-white/20" : ""}
|
|
3640
3722
|
`
|
|
3641
3723
|
},
|
|
3642
3724
|
renderSectionContent(bodyText)
|
|
@@ -3657,8 +3739,8 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
3657
3739
|
CodeBlock,
|
|
3658
3740
|
{
|
|
3659
3741
|
content: part,
|
|
3660
|
-
isActive,
|
|
3661
|
-
onClick: () =>
|
|
3742
|
+
isActive: isSelected,
|
|
3743
|
+
onClick: (e) => handleSectionClick(index, e)
|
|
3662
3744
|
}
|
|
3663
3745
|
)
|
|
3664
3746
|
);
|
|
@@ -3668,7 +3750,7 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
3668
3750
|
const isLastLine = lineIndex === lines.length - 1;
|
|
3669
3751
|
const isEmptyLine = line.trim() === "";
|
|
3670
3752
|
if (isEmptyLine) {
|
|
3671
|
-
return /* @__PURE__ */ React4.createElement(
|
|
3753
|
+
return /* @__PURE__ */ React4.createElement("br", { key: `${index}-${partIndex}-${lineIndex}` });
|
|
3672
3754
|
}
|
|
3673
3755
|
return /* @__PURE__ */ React4.createElement(React4.Fragment, { key: `${index}-${partIndex}-${lineIndex}` }, /* @__PURE__ */ React4.createElement(
|
|
3674
3756
|
"span",
|
|
@@ -3679,10 +3761,11 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
3679
3761
|
refAssigned = true;
|
|
3680
3762
|
}
|
|
3681
3763
|
},
|
|
3682
|
-
onClick: () =>
|
|
3764
|
+
onClick: (e) => handleSectionClick(index, e),
|
|
3683
3765
|
className: `
|
|
3684
|
-
transition-colors duration-200 cursor-pointer rounded-md px-1 py-0.5 -mx-1 box-decoration-clone
|
|
3685
|
-
${
|
|
3766
|
+
transition-colors duration-200 cursor-pointer rounded-md px-1 py-0.5 -mx-1 box-decoration-clone select-none
|
|
3767
|
+
${isSelected ? "bg-indigo-500/30 text-white ring-1 ring-indigo-500/50 shadow-sm" : "hover:bg-white/5 hover:text-slate-200"}
|
|
3768
|
+
${isFocused && !isSelected ? "ring-1 ring-white/20" : ""}
|
|
3686
3769
|
`
|
|
3687
3770
|
},
|
|
3688
3771
|
formatLineContent(line)
|
|
@@ -3696,7 +3779,8 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
3696
3779
|
className: "flex items-center gap-2 px-6 py-2.5 bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-semibold rounded-lg shadow-lg shadow-indigo-500/20 transition-all transform active:scale-95"
|
|
3697
3780
|
},
|
|
3698
3781
|
/* @__PURE__ */ React4.createElement(FiDownload, { className: "text-indigo-200" }),
|
|
3699
|
-
"Importar
|
|
3782
|
+
"Importar ",
|
|
3783
|
+
selectedIndices.size > 1 ? `${selectedIndices.size} Se\xE7\xF5es` : "Se\xE7\xE3o"
|
|
3700
3784
|
))) : /* @__PURE__ */ React4.createElement("div", { className: "flex-1 flex flex-col items-center justify-center text-slate-500" }, /* @__PURE__ */ React4.createElement("div", { className: "w-16 h-16 rounded-full bg-white/5 flex items-center justify-center mb-4" }, /* @__PURE__ */ React4.createElement(FiSearch, { size: 24, className: "opacity-50" })), /* @__PURE__ */ React4.createElement("p", null, "Selecione um item \xE0 esquerda para visualizar suas se\xE7\xF5es."))))
|
|
3701
3785
|
));
|
|
3702
3786
|
}
|
|
@@ -3728,16 +3812,22 @@ function DescriptionEditModal({
|
|
|
3728
3812
|
availableAncestries = [],
|
|
3729
3813
|
availableImages = []
|
|
3730
3814
|
}) {
|
|
3731
|
-
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 || "");
|
|
3732
3822
|
const textareaRef = useRef5(null);
|
|
3733
|
-
const [isImportModalOpen, setIsImportModalOpen] =
|
|
3734
|
-
const [isMentionModalOpen, setIsMentionModalOpen] =
|
|
3735
|
-
const [mentionSearch, setMentionSearch] =
|
|
3736
|
-
const [mentionTriggerIndex, setMentionTriggerIndex] =
|
|
3737
|
-
const [isImageModalOpen, setIsImageModalOpen] =
|
|
3738
|
-
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("");
|
|
3739
3829
|
const hoverTimeoutRef = useRef5(null);
|
|
3740
|
-
const [tooltipData, setTooltipData] =
|
|
3830
|
+
const [tooltipData, setTooltipData] = useState6(null);
|
|
3741
3831
|
useEffect5(() => {
|
|
3742
3832
|
const handleKeyDown = (e) => {
|
|
3743
3833
|
if (e.key === "Escape") {
|
|
@@ -3830,12 +3920,28 @@ function DescriptionEditModal({
|
|
|
3830
3920
|
const uniqueSuffix = v4_default().slice(0, 4);
|
|
3831
3921
|
insertAtCursor(`*/${nextNum}:${uniqueSuffix}/ `);
|
|
3832
3922
|
};
|
|
3833
|
-
const handleImportSelect = (
|
|
3834
|
-
const
|
|
3835
|
-
const
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3923
|
+
const handleImportSelect = (tags) => {
|
|
3924
|
+
const tagsArray = Array.isArray(tags) ? tags : [tags];
|
|
3925
|
+
const el = textareaRef.current;
|
|
3926
|
+
if (!el) return;
|
|
3927
|
+
let currentText = text;
|
|
3928
|
+
let currentNum = getNextSectionNumber(currentText);
|
|
3929
|
+
let blockToInsert = "";
|
|
3930
|
+
tagsArray.forEach((tag) => {
|
|
3931
|
+
const uniqueSuffix = v4_default().slice(0, 4);
|
|
3932
|
+
blockToInsert += `
|
|
3933
|
+
*/${currentNum}:${uniqueSuffix}/ ${tag}
|
|
3934
|
+
`;
|
|
3935
|
+
currentNum++;
|
|
3936
|
+
});
|
|
3937
|
+
const start = el.selectionStart;
|
|
3938
|
+
const end = el.selectionEnd;
|
|
3939
|
+
const newText = currentText.substring(0, start) + blockToInsert + currentText.substring(end);
|
|
3940
|
+
el.value = newText;
|
|
3941
|
+
el.setSelectionRange(start + blockToInsert.length, start + blockToInsert.length);
|
|
3942
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
3943
|
+
el.focus();
|
|
3944
|
+
setText(newText);
|
|
3839
3945
|
setIsImportModalOpen(false);
|
|
3840
3946
|
};
|
|
3841
3947
|
const handleMentionSelect = (node) => {
|
|
@@ -3880,7 +3986,8 @@ function DescriptionEditModal({
|
|
|
3880
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(
|
|
3881
3987
|
"div",
|
|
3882
3988
|
{
|
|
3883
|
-
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" },
|
|
3884
3991
|
onClick: swallow,
|
|
3885
3992
|
onPointerDown: swallow,
|
|
3886
3993
|
onPointerMove: swallow,
|
|
@@ -3889,6 +3996,17 @@ function DescriptionEditModal({
|
|
|
3889
3996
|
onContextMenu: swallow,
|
|
3890
3997
|
onDoubleClick: swallow
|
|
3891
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
|
+
),
|
|
3892
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" }),
|
|
3893
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")),
|
|
3894
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(
|
|
@@ -4080,11 +4198,11 @@ function DescriptionEditModal({
|
|
|
4080
4198
|
}
|
|
4081
4199
|
|
|
4082
4200
|
// src/components/DescriptionDisplay.jsx
|
|
4083
|
-
import React6, { useMemo as useMemo5, useState as
|
|
4201
|
+
import React6, { useMemo as useMemo5, useState as useState7, useEffect as useEffect6, useRef as useRef6 } from "react";
|
|
4084
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";
|
|
4085
4203
|
var CodeBlock2 = ({ content, isActive, onClick }) => {
|
|
4086
|
-
const [isExpanded, setIsExpanded] =
|
|
4087
|
-
const [copied, setCopied] =
|
|
4204
|
+
const [isExpanded, setIsExpanded] = useState7(false);
|
|
4205
|
+
const [copied, setCopied] = useState7(false);
|
|
4088
4206
|
const cleanContent = content.replace(/^```|```$/g, "").trim();
|
|
4089
4207
|
const isLongCode = cleanContent.split("\n").length > 4;
|
|
4090
4208
|
const handleCopy = (e) => {
|
|
@@ -4283,7 +4401,7 @@ function DescriptionDisplay({
|
|
|
4283
4401
|
});
|
|
4284
4402
|
return navItems;
|
|
4285
4403
|
}, [sections]);
|
|
4286
|
-
const [currentStepIndex, setCurrentStepIndex] =
|
|
4404
|
+
const [currentStepIndex, setCurrentStepIndex] = useState7(0);
|
|
4287
4405
|
const activeRef = useRef6(null);
|
|
4288
4406
|
const lastNotifiedSectionId = useRef6(null);
|
|
4289
4407
|
const isInitialMount = useRef6(true);
|
|
@@ -4464,7 +4582,7 @@ function DescriptionDisplay({
|
|
|
4464
4582
|
}
|
|
4465
4583
|
|
|
4466
4584
|
// src/components/DescriptionReadModePanel.jsx
|
|
4467
|
-
import React7, { useState as
|
|
4585
|
+
import React7, { useState as useState8, useMemo as useMemo6, useEffect as useEffect7 } from "react";
|
|
4468
4586
|
import {
|
|
4469
4587
|
FiArrowLeft,
|
|
4470
4588
|
FiEdit2,
|
|
@@ -4566,10 +4684,10 @@ function DescriptionReadModePanel({
|
|
|
4566
4684
|
onRenderAbstractionTree = null,
|
|
4567
4685
|
initialShowAbstraction = false
|
|
4568
4686
|
}) {
|
|
4569
|
-
const [showProperties, setShowProperties] =
|
|
4570
|
-
const [showAbstraction, setShowAbstraction] =
|
|
4571
|
-
const [targetRenderNodeId, setTargetRenderNodeId] =
|
|
4572
|
-
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);
|
|
4573
4691
|
const handleCopyLink = (e) => {
|
|
4574
4692
|
e.stopPropagation();
|
|
4575
4693
|
if (!ancestryId) return;
|
|
@@ -4824,11 +4942,11 @@ function AncestryRelationshipPanel({
|
|
|
4824
4942
|
onMentionClick,
|
|
4825
4943
|
onUploadFile
|
|
4826
4944
|
}) {
|
|
4827
|
-
const [description, setDescription] =
|
|
4828
|
-
const [customProps, setCustomProps] =
|
|
4829
|
-
const [existingSections, setExistingSections] =
|
|
4830
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
4831
|
-
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);
|
|
4832
4950
|
const propsEndRef = useRef7(null);
|
|
4833
4951
|
useEffect8(() => {
|
|
4834
4952
|
setDescription((data == null ? void 0 : data.description) ?? "");
|
|
@@ -4970,7 +5088,7 @@ function AncestryRelationshipPanel({
|
|
|
4970
5088
|
}
|
|
4971
5089
|
|
|
4972
5090
|
// src/components/CreateAncestryPanel.jsx
|
|
4973
|
-
import React10, { useState as
|
|
5091
|
+
import React10, { useState as useState11, useEffect as useEffect10, useMemo as useMemo8, useRef as useRef8, useCallback as useCallback2 } from "react";
|
|
4974
5092
|
import {
|
|
4975
5093
|
FiEdit2 as FiEdit23,
|
|
4976
5094
|
FiBookOpen as FiBookOpen2,
|
|
@@ -4990,7 +5108,7 @@ import {
|
|
|
4990
5108
|
} from "react-icons/fi";
|
|
4991
5109
|
|
|
4992
5110
|
// src/components/AncestryPickerModal.jsx
|
|
4993
|
-
import React9, { useState as
|
|
5111
|
+
import React9, { useState as useState10, useMemo as useMemo7, useEffect as useEffect9 } from "react";
|
|
4994
5112
|
import { FiSearch as FiSearch3, FiLayers as FiLayers4, FiCornerUpRight as FiCornerUpRight2 } from "react-icons/fi";
|
|
4995
5113
|
function AncestryPickerModal({
|
|
4996
5114
|
isOpen,
|
|
@@ -5000,7 +5118,7 @@ function AncestryPickerModal({
|
|
|
5000
5118
|
availableNodes = [],
|
|
5001
5119
|
currentAncestryId
|
|
5002
5120
|
}) {
|
|
5003
|
-
const [searchTerm, setSearchTerm] =
|
|
5121
|
+
const [searchTerm, setSearchTerm] = useState10("");
|
|
5004
5122
|
useEffect9(() => {
|
|
5005
5123
|
if (!isOpen) return;
|
|
5006
5124
|
const handleKeyDown = (e) => {
|
|
@@ -5085,7 +5203,7 @@ var NodeItem = ({ nodeData, onSelectParent, onViewSelect, highlightedPathIds = [
|
|
|
5085
5203
|
var _a, _b;
|
|
5086
5204
|
const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
|
|
5087
5205
|
const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
|
|
5088
|
-
const [isDragOver, setIsDragOver] =
|
|
5206
|
+
const [isDragOver, setIsDragOver] = useState11(false);
|
|
5089
5207
|
const isSelectedParent = String(selectedParentId) === String(itemId);
|
|
5090
5208
|
const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
|
|
5091
5209
|
const isHighlightedPath = highlightedPathIds.includes(String(itemId));
|
|
@@ -5221,8 +5339,8 @@ function CreateAncestryPanel({
|
|
|
5221
5339
|
isAddingNodes,
|
|
5222
5340
|
currentAncestryId
|
|
5223
5341
|
} = ancestryMode;
|
|
5224
|
-
const [isSaving, setIsSaving] =
|
|
5225
|
-
const [isLinkCopied, setIsLinkCopied] =
|
|
5342
|
+
const [isSaving, setIsSaving] = useState11(false);
|
|
5343
|
+
const [isLinkCopied, setIsLinkCopied] = useState11(false);
|
|
5226
5344
|
const handleCopyLink = (e) => {
|
|
5227
5345
|
e.stopPropagation();
|
|
5228
5346
|
if (!currentAncestryId || currentAncestryId === "temp_root" || currentAncestryId === "temp_creating") {
|
|
@@ -5236,11 +5354,11 @@ function CreateAncestryPanel({
|
|
|
5236
5354
|
setTimeout(() => setIsLinkCopied(false), 2e3);
|
|
5237
5355
|
}).catch((err) => console.error("Erro ao copiar link:", err));
|
|
5238
5356
|
};
|
|
5239
|
-
const [isPickerOpen, setIsPickerOpen] =
|
|
5240
|
-
const [customProps, setCustomProps] =
|
|
5357
|
+
const [isPickerOpen, setIsPickerOpen] = useState11(false);
|
|
5358
|
+
const [customProps, setCustomProps] = useState11([]);
|
|
5241
5359
|
const propsEndRef = useRef8(null);
|
|
5242
|
-
const [branchStack, setBranchStack] =
|
|
5243
|
-
const [targetRenderNodeId, setTargetRenderNodeId] =
|
|
5360
|
+
const [branchStack, setBranchStack] = useState11([]);
|
|
5361
|
+
const [targetRenderNodeId, setTargetRenderNodeId] = useState11(null);
|
|
5244
5362
|
const highlightedPathIds = useMemo8(() => {
|
|
5245
5363
|
var _a, _b;
|
|
5246
5364
|
if (!targetRenderNodeId || !ancestryMode.abstraction_tree) return [];
|
|
@@ -5254,17 +5372,26 @@ function CreateAncestryPanel({
|
|
|
5254
5372
|
}
|
|
5255
5373
|
return ids;
|
|
5256
5374
|
}, [targetRenderNodeId, ancestryMode.abstraction_tree]);
|
|
5257
|
-
const [targetScrollSectionId, setTargetScrollSectionId] =
|
|
5258
|
-
const [internalHighlightedNodeId, setInternalHighlightedNodeId] =
|
|
5259
|
-
const [ancestryName, setAncestryName] =
|
|
5260
|
-
const [description, setDescription] =
|
|
5261
|
-
const [existingSections, setExistingSections] =
|
|
5262
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
5263
|
-
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]);
|
|
5264
5391
|
const currentMaxRenderIndexRef = useRef8(0);
|
|
5265
5392
|
const branchProgressMapRef = useRef8({});
|
|
5266
|
-
const [lastSavedSnapshot, setLastSavedSnapshot] =
|
|
5267
|
-
const [isPrivate, setIsPrivate] =
|
|
5393
|
+
const [lastSavedSnapshot, setLastSavedSnapshot] = useState11(null);
|
|
5394
|
+
const [isPrivate, setIsPrivate] = useState11(ancestryMode.is_private || false);
|
|
5268
5395
|
const initializedContextIdRef = useRef8(null);
|
|
5269
5396
|
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
5270
5397
|
const handleImageClickFromText = (url, name) => {
|
|
@@ -5283,7 +5410,7 @@ function CreateAncestryPanel({
|
|
|
5283
5410
|
}
|
|
5284
5411
|
setAncestryMode((prev) => isAbstraction ? { ...prev, isAddingAbstractionNodes: !prev.isAddingAbstractionNodes } : { ...prev, isAddingNodes: !prev.isAddingNodes });
|
|
5285
5412
|
};
|
|
5286
|
-
const handleRemoveNode =
|
|
5413
|
+
const handleRemoveNode = useCallback2((pathToRemove, isAbstraction = false) => {
|
|
5287
5414
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) return;
|
|
5288
5415
|
const treeKey = isAbstraction ? "abstraction_tree" : "tree";
|
|
5289
5416
|
setAncestryMode((prev) => {
|
|
@@ -6239,10 +6366,8 @@ function CreateAncestryPanel({
|
|
|
6239
6366
|
return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
|
|
6240
6367
|
"div",
|
|
6241
6368
|
{
|
|
6242
|
-
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
|
|
6243
|
-
|
|
6244
|
-
`,
|
|
6245
|
-
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" },
|
|
6246
6371
|
onPointerDown: swallow,
|
|
6247
6372
|
onPointerMove: swallow,
|
|
6248
6373
|
onPointerUp: swallow,
|
|
@@ -6251,6 +6376,17 @@ function CreateAncestryPanel({
|
|
|
6251
6376
|
onContextMenu: swallow,
|
|
6252
6377
|
onDoubleClick: swallow
|
|
6253
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
|
+
),
|
|
6254
6390
|
isReadMode ? /* @__PURE__ */ React10.createElement(
|
|
6255
6391
|
DescriptionReadModePanel,
|
|
6256
6392
|
{
|
|
@@ -6547,25 +6683,25 @@ function CreateAncestryPanel({
|
|
|
6547
6683
|
}
|
|
6548
6684
|
|
|
6549
6685
|
// src/components/ImageViewer.jsx
|
|
6550
|
-
import React11, { useState as
|
|
6686
|
+
import React11, { useState as useState12, useEffect as useEffect11, useLayoutEffect as useLayoutEffect2, useCallback as useCallback3 } from "react";
|
|
6551
6687
|
import { FiX as FiX2, FiChevronLeft as FiChevronLeft3, FiChevronRight as FiChevronRight5 } from "react-icons/fi";
|
|
6552
6688
|
function ImageViewer({ data, onClose }) {
|
|
6553
6689
|
var _a;
|
|
6554
6690
|
const { images = [], startIndex = 0, visible } = data;
|
|
6555
|
-
const [currentIndex, setCurrentIndex] =
|
|
6556
|
-
const [isLoading, setIsLoading] =
|
|
6557
|
-
const [loadedSrc, setLoadedSrc] =
|
|
6691
|
+
const [currentIndex, setCurrentIndex] = useState12(startIndex);
|
|
6692
|
+
const [isLoading, setIsLoading] = useState12(false);
|
|
6693
|
+
const [loadedSrc, setLoadedSrc] = useState12(null);
|
|
6558
6694
|
useLayoutEffect2(() => {
|
|
6559
6695
|
if (visible) {
|
|
6560
6696
|
setCurrentIndex(startIndex);
|
|
6561
6697
|
}
|
|
6562
6698
|
}, [visible, startIndex]);
|
|
6563
|
-
const handleNext =
|
|
6699
|
+
const handleNext = useCallback3(() => {
|
|
6564
6700
|
if (images.length > 1) {
|
|
6565
6701
|
setCurrentIndex((prev) => (prev + 1) % images.length);
|
|
6566
6702
|
}
|
|
6567
6703
|
}, [images.length]);
|
|
6568
|
-
const handlePrev =
|
|
6704
|
+
const handlePrev = useCallback3(() => {
|
|
6569
6705
|
if (images.length > 1) {
|
|
6570
6706
|
setCurrentIndex((prev) => (prev - 1 + images.length) % images.length);
|
|
6571
6707
|
}
|
|
@@ -6670,10 +6806,10 @@ function ImageViewer({ data, onClose }) {
|
|
|
6670
6806
|
}
|
|
6671
6807
|
|
|
6672
6808
|
// src/components/InSceneCreationForm.jsx
|
|
6673
|
-
import React13, { useState as
|
|
6809
|
+
import React13, { useState as useState14, useEffect as useEffect13, useRef as useRef10 } from "react";
|
|
6674
6810
|
|
|
6675
6811
|
// src/components/ColorPicker.jsx
|
|
6676
|
-
import React12, { useState as
|
|
6812
|
+
import React12, { useState as useState13, useEffect as useEffect12, useRef as useRef9 } from "react";
|
|
6677
6813
|
import { HexColorPicker } from "react-colorful";
|
|
6678
6814
|
import { FiHash, FiCheck as FiCheck6 } from "react-icons/fi";
|
|
6679
6815
|
var PRESET_COLORS = [
|
|
@@ -6694,7 +6830,7 @@ var PRESET_COLORS = [
|
|
|
6694
6830
|
"#000000"
|
|
6695
6831
|
];
|
|
6696
6832
|
function ColorPicker({ color, onChange, disabled }) {
|
|
6697
|
-
const [isOpen, setIsOpen] =
|
|
6833
|
+
const [isOpen, setIsOpen] = useState13(false);
|
|
6698
6834
|
const popoverRef = useRef9(null);
|
|
6699
6835
|
useEffect12(() => {
|
|
6700
6836
|
const handleClickOutside = (event) => {
|
|
@@ -6793,21 +6929,21 @@ function InSceneCreationForm({
|
|
|
6793
6929
|
viewType
|
|
6794
6930
|
}) {
|
|
6795
6931
|
var _a;
|
|
6796
|
-
const [name, setName] =
|
|
6797
|
-
const [types, setTypes] =
|
|
6798
|
-
const [typeInput, setTypeInput] =
|
|
6799
|
-
const [color, setColor] =
|
|
6800
|
-
const [size, setSize] =
|
|
6801
|
-
const [intensity, setIntensity] =
|
|
6802
|
-
const [description, setDescription] =
|
|
6803
|
-
const [customProps, setCustomProps] =
|
|
6804
|
-
const [showTypeSuggestions, setShowTypeSuggestions] =
|
|
6805
|
-
const [filteredTypes, setFilteredTypes] =
|
|
6806
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
6807
|
-
const [useImageAsTexture, setUseImageAsTexture] =
|
|
6808
|
-
const [selectedImageUrl, setSelectedImageUrl] =
|
|
6809
|
-
const [targetDatasetId, setTargetDatasetId] =
|
|
6810
|
-
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);
|
|
6811
6947
|
const datasetDropdownRef = useRef10(null);
|
|
6812
6948
|
useEffect13(() => {
|
|
6813
6949
|
if (sourceNodeDatasetId) setTargetDatasetId(sourceNodeDatasetId);
|
|
@@ -7140,7 +7276,7 @@ function InSceneCreationForm({
|
|
|
7140
7276
|
}
|
|
7141
7277
|
|
|
7142
7278
|
// src/components/InSceneVersionForm.jsx
|
|
7143
|
-
import React14, { useState as
|
|
7279
|
+
import React14, { useState as useState15, useEffect as useEffect14, useRef as useRef11 } from "react";
|
|
7144
7280
|
import { FiPlus as FiPlus4, FiMaximize2 as FiMaximize22, FiCheck as FiCheck8, FiEdit2 as FiEdit25 } from "react-icons/fi";
|
|
7145
7281
|
function InSceneVersionForm({
|
|
7146
7282
|
onSave,
|
|
@@ -7158,14 +7294,14 @@ function InSceneVersionForm({
|
|
|
7158
7294
|
onMentionClick,
|
|
7159
7295
|
onUploadFile
|
|
7160
7296
|
}) {
|
|
7161
|
-
const [name, setName] =
|
|
7162
|
-
const [size, setSize] =
|
|
7163
|
-
const [description, setDescription] =
|
|
7164
|
-
const [customProps, setCustomProps] =
|
|
7165
|
-
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);
|
|
7166
7302
|
const propsEndRef = useRef11(null);
|
|
7167
|
-
const [useImageAsTexture, setUseImageAsTexture] =
|
|
7168
|
-
const [selectedImageUrl, setSelectedImageUrl] =
|
|
7303
|
+
const [useImageAsTexture, setUseImageAsTexture] = useState15(false);
|
|
7304
|
+
const [selectedImageUrl, setSelectedImageUrl] = useState15(null);
|
|
7169
7305
|
const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
|
|
7170
7306
|
useEffect14(() => {
|
|
7171
7307
|
if (!hasImages && useImageAsTexture) {
|
|
@@ -7358,7 +7494,7 @@ function InSceneVersionForm({
|
|
|
7358
7494
|
}
|
|
7359
7495
|
|
|
7360
7496
|
// src/components/NodeDetailsPanel.jsx
|
|
7361
|
-
import React15, { useState as
|
|
7497
|
+
import React15, { useState as useState16, useEffect as useEffect15, useRef as useRef12 } from "react";
|
|
7362
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";
|
|
7363
7499
|
function NodeDetailsPanel({
|
|
7364
7500
|
node,
|
|
@@ -7380,27 +7516,36 @@ function NodeDetailsPanel({
|
|
|
7380
7516
|
userRole,
|
|
7381
7517
|
currentDatasetName
|
|
7382
7518
|
}) {
|
|
7383
|
-
const [name, setName] =
|
|
7384
|
-
const [types, setTypes] =
|
|
7385
|
-
const [typeInput, setTypeInput] =
|
|
7386
|
-
const [color, setColor] =
|
|
7387
|
-
const [size, setSize] =
|
|
7388
|
-
const [description, setDescription] =
|
|
7389
|
-
const [intensity, setIntensity] =
|
|
7390
|
-
const [customProps, setCustomProps] =
|
|
7391
|
-
const [showTypeSuggestions, setShowTypeSuggestions] =
|
|
7392
|
-
const [filteredTypes, setFilteredTypes] =
|
|
7393
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
7394
|
-
const [isReadMode, setIsReadMode] =
|
|
7395
|
-
const [existingSections, setExistingSections] =
|
|
7396
|
-
const [isSaving, setIsSaving] =
|
|
7397
|
-
const [isLinkCopied, setIsLinkCopied] =
|
|
7398
|
-
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(() => {
|
|
7399
7535
|
if ((node == null ? void 0 : node.useImageAsTexture) === "true") return true;
|
|
7400
7536
|
if ((node == null ? void 0 : node.useImageAsTexture) === "false") return false;
|
|
7401
7537
|
return !!(node == null ? void 0 : node.useImageAsTexture);
|
|
7402
7538
|
});
|
|
7403
|
-
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]);
|
|
7404
7549
|
const prevNodeIdRef = useRef12(null);
|
|
7405
7550
|
const propsEndRef = useRef12(null);
|
|
7406
7551
|
const canEdit = userRole !== "viewer";
|
|
@@ -7608,10 +7753,8 @@ function NodeDetailsPanel({
|
|
|
7608
7753
|
return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
|
|
7609
7754
|
"div",
|
|
7610
7755
|
{
|
|
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
|
|
7612
|
-
|
|
7613
|
-
`,
|
|
7614
|
-
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" },
|
|
7615
7758
|
onPointerDown: swallow,
|
|
7616
7759
|
onPointerMove: swallow,
|
|
7617
7760
|
onPointerUp: swallow,
|
|
@@ -7620,6 +7763,17 @@ function NodeDetailsPanel({
|
|
|
7620
7763
|
onContextMenu: swallow,
|
|
7621
7764
|
onDoubleClick: swallow
|
|
7622
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
|
+
),
|
|
7623
7777
|
isReadMode ? /* @__PURE__ */ React15.createElement(
|
|
7624
7778
|
DescriptionReadModePanel,
|
|
7625
7779
|
{
|
|
@@ -7821,7 +7975,7 @@ function NodeDetailsPanel({
|
|
|
7821
7975
|
}
|
|
7822
7976
|
|
|
7823
7977
|
// src/components/MultiNodeContextMenu.jsx
|
|
7824
|
-
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";
|
|
7825
7979
|
function MultiNodeContextMenu({
|
|
7826
7980
|
data,
|
|
7827
7981
|
userRole,
|
|
@@ -7832,7 +7986,7 @@ function MultiNodeContextMenu({
|
|
|
7832
7986
|
onDeleteNodes
|
|
7833
7987
|
}) {
|
|
7834
7988
|
const menuRef = useRef13(null);
|
|
7835
|
-
const [menuPos, setMenuPos] =
|
|
7989
|
+
const [menuPos, setMenuPos] = useState17({ left: 0, top: 0 });
|
|
7836
7990
|
const ability = defineAbilityFor(userRole);
|
|
7837
7991
|
const canDelete = ability.can("delete", "Node");
|
|
7838
7992
|
useLayoutEffect3(() => {
|
|
@@ -7881,7 +8035,7 @@ function MultiNodeContextMenu({
|
|
|
7881
8035
|
}
|
|
7882
8036
|
|
|
7883
8037
|
// src/components/RelationshipDetailsPanel.jsx
|
|
7884
|
-
import React17, { useState as
|
|
8038
|
+
import React17, { useState as useState18, useEffect as useEffect17, useRef as useRef14, useMemo as useMemo9 } from "react";
|
|
7885
8039
|
import { FiPlus as FiPlus6, FiEdit2 as FiEdit27, FiLoader as FiLoader3, FiBookOpen as FiBookOpen4 } from "react-icons/fi";
|
|
7886
8040
|
function RelationshipDetailsPanel({
|
|
7887
8041
|
link,
|
|
@@ -7897,13 +8051,13 @@ function RelationshipDetailsPanel({
|
|
|
7897
8051
|
userRole
|
|
7898
8052
|
// Recebendo userRole via props
|
|
7899
8053
|
}) {
|
|
7900
|
-
const [name, setName] =
|
|
7901
|
-
const [description, setDescription] =
|
|
7902
|
-
const [customProps, setCustomProps] =
|
|
7903
|
-
const [existingSections, setExistingSections] =
|
|
7904
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
7905
|
-
const [isSaving, setIsSaving] =
|
|
7906
|
-
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);
|
|
7907
8061
|
const propsEndRef = useRef14(null);
|
|
7908
8062
|
const canEdit = useMemo9(() => {
|
|
7909
8063
|
const ability = defineAbilityFor(userRole);
|
|
@@ -8106,7 +8260,7 @@ function RelationshipDetailsPanel({
|
|
|
8106
8260
|
}
|
|
8107
8261
|
|
|
8108
8262
|
// src/components/RelationshipContextMenu.jsx
|
|
8109
|
-
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";
|
|
8110
8264
|
function RelationshipContextMenu({
|
|
8111
8265
|
data,
|
|
8112
8266
|
userRole,
|
|
@@ -8118,7 +8272,7 @@ function RelationshipContextMenu({
|
|
|
8118
8272
|
onClose
|
|
8119
8273
|
}) {
|
|
8120
8274
|
const menuRef = useRef15(null);
|
|
8121
|
-
const [menuPos, setMenuPos] =
|
|
8275
|
+
const [menuPos, setMenuPos] = useState19({ left: 0, top: 0 });
|
|
8122
8276
|
const ability = useMemo10(() => defineAbilityFor(userRole), [userRole]);
|
|
8123
8277
|
const sourceName = useMemo10(
|
|
8124
8278
|
() => {
|
|
@@ -8320,7 +8474,7 @@ function LoadingScreen() {
|
|
|
8320
8474
|
}
|
|
8321
8475
|
|
|
8322
8476
|
// src/components/ImportParentFileModal.jsx
|
|
8323
|
-
import React20, { useEffect as useEffect19, useState as
|
|
8477
|
+
import React20, { useEffect as useEffect19, useState as useState20 } from "react";
|
|
8324
8478
|
function ImportParentFileModal({
|
|
8325
8479
|
isOpen,
|
|
8326
8480
|
onClose,
|
|
@@ -8331,11 +8485,11 @@ function ImportParentFileModal({
|
|
|
8331
8485
|
onFetchAvailableFiles,
|
|
8332
8486
|
currentViewName
|
|
8333
8487
|
}) {
|
|
8334
|
-
const [activeTab, setActiveTab] =
|
|
8335
|
-
const [availableDbs, setAvailableDbs] =
|
|
8336
|
-
const [availableViews, setAvailableViews] =
|
|
8337
|
-
const [selectedItem, setSelectedItem] =
|
|
8338
|
-
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);
|
|
8339
8493
|
useEffect19(() => {
|
|
8340
8494
|
if (isOpen && session && onFetchAvailableFiles) {
|
|
8341
8495
|
const fetchData = async () => {
|
|
@@ -8481,7 +8635,7 @@ function ImportParentFileModal({
|
|
|
8481
8635
|
}
|
|
8482
8636
|
|
|
8483
8637
|
// src/components/AncestryLinkDetailsPanel.jsx
|
|
8484
|
-
import React21, { useState as
|
|
8638
|
+
import React21, { useState as useState21 } from "react";
|
|
8485
8639
|
import { FiBookOpen as FiBookOpen5 } from "react-icons/fi";
|
|
8486
8640
|
function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
|
|
8487
8641
|
var _a, _b, _c, _d;
|
|
@@ -8491,7 +8645,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
8491
8645
|
const customProps = extractCustomPropsFromNode(relationshipData);
|
|
8492
8646
|
const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
|
|
8493
8647
|
const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
|
|
8494
|
-
const [isReadMode, setIsReadMode] =
|
|
8648
|
+
const [isReadMode, setIsReadMode] = useState21(false);
|
|
8495
8649
|
const swallow = (e) => e.stopPropagation();
|
|
8496
8650
|
const handleImageClickFromText = (url, name) => {
|
|
8497
8651
|
if (onOpenImageViewer) {
|
|
@@ -8557,7 +8711,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
8557
8711
|
}
|
|
8558
8712
|
|
|
8559
8713
|
// src/components/AncestryBoard.jsx
|
|
8560
|
-
import React22, { useState as
|
|
8714
|
+
import React22, { useState as useState22, useMemo as useMemo11, useEffect as useEffect20, useRef as useRef16 } from "react";
|
|
8561
8715
|
import {
|
|
8562
8716
|
FiSearch as FiSearch4,
|
|
8563
8717
|
FiLayers as FiLayers6,
|
|
@@ -8734,11 +8888,11 @@ function AncestryBoard({
|
|
|
8734
8888
|
userRole
|
|
8735
8889
|
// [NOVO] Recebe a role do usuário
|
|
8736
8890
|
}) {
|
|
8737
|
-
const [searchTerm, setSearchTerm] =
|
|
8738
|
-
const [groups, setGroups] =
|
|
8739
|
-
const [isLoaded, setIsLoaded] =
|
|
8740
|
-
const [pickingGroupId, setPickingGroupId] =
|
|
8741
|
-
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");
|
|
8742
8896
|
const canEdit = useMemo11(() => {
|
|
8743
8897
|
return userRole !== "viewer";
|
|
8744
8898
|
}, [userRole]);
|
|
@@ -9188,37 +9342,37 @@ function XViewScene({
|
|
|
9188
9342
|
const sceneDataRef = useRef17(null);
|
|
9189
9343
|
const parentDataRef = useRef17(null);
|
|
9190
9344
|
const ancestryDataRef = useRef17(null);
|
|
9191
|
-
const [isLoading, setIsLoading] =
|
|
9192
|
-
const [permissionStatus, setPermissionStatus] =
|
|
9193
|
-
const [userPermissionRole, setUserPermissionRole] =
|
|
9194
|
-
const [isInitialized, setIsInitialized] =
|
|
9195
|
-
const [sceneVersion, setSceneVersion] =
|
|
9196
|
-
const [contextMenu, setContextMenu] =
|
|
9197
|
-
const [multiContextMenu, setMultiContextMenu] =
|
|
9198
|
-
const [relationshipMenu, setRelationshipMenu] =
|
|
9199
|
-
const [creationMode, setCreationMode] =
|
|
9200
|
-
const [versionMode, setVersionMode] =
|
|
9201
|
-
const [hasFocusedInitial, setHasFocusedInitial] =
|
|
9202
|
-
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] =
|
|
9203
|
-
const [ancestryMode, setAncestryMode] =
|
|
9204
|
-
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({
|
|
9205
9359
|
isActive: false,
|
|
9206
9360
|
ancestry: null,
|
|
9207
9361
|
branchStack: [],
|
|
9208
9362
|
autoAbstraction: false
|
|
9209
9363
|
});
|
|
9210
|
-
const [formPosition, setFormPosition] =
|
|
9211
|
-
const [detailsNode, setDetailsNode] =
|
|
9212
|
-
const [detailsLink, setDetailsLink] =
|
|
9213
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] =
|
|
9214
|
-
const [imageViewer, setImageViewer] =
|
|
9215
|
-
const [editingAncestryRel, setEditingAncestryRel] =
|
|
9216
|
-
const [isImportModalOpen, setIsImportModalOpen] =
|
|
9217
|
-
const [importSuccessMessage, setImportSuccessMessage] =
|
|
9218
|
-
const [highlightedNodeId, setHighlightedNodeId] =
|
|
9219
|
-
const [isAncestryBoardOpen, setIsAncestryBoardOpen] =
|
|
9220
|
-
const [ancestryBoardData, setAncestryBoardData] =
|
|
9221
|
-
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);
|
|
9222
9376
|
const mountRef = useRef17(null);
|
|
9223
9377
|
const tooltipRef = useRef17(null);
|
|
9224
9378
|
const formRef = useRef17(null);
|
|
@@ -9261,6 +9415,12 @@ function XViewScene({
|
|
|
9261
9415
|
lastDescriptionLength: 0,
|
|
9262
9416
|
highlightedNodeId: null
|
|
9263
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
|
+
});
|
|
9264
9424
|
useEffect21(() => {
|
|
9265
9425
|
stateRef.current.ancestry = ancestryMode;
|
|
9266
9426
|
}, [ancestryMode]);
|
|
@@ -9285,10 +9445,10 @@ function XViewScene({
|
|
|
9285
9445
|
}
|
|
9286
9446
|
stateRef.current.nodeIdToParentFileMap = map;
|
|
9287
9447
|
}, [isInitialized, sceneVersion]);
|
|
9288
|
-
const handleNavigateBack =
|
|
9448
|
+
const handleNavigateBack = useCallback4(() => {
|
|
9289
9449
|
router.push("/dashboard/scenes");
|
|
9290
9450
|
}, [router]);
|
|
9291
|
-
const handleConfirmImport =
|
|
9451
|
+
const handleConfirmImport = useCallback4(
|
|
9292
9452
|
async (importPayload) => {
|
|
9293
9453
|
var _a2, _b2;
|
|
9294
9454
|
let files = [];
|
|
@@ -9336,7 +9496,6 @@ function XViewScene({
|
|
|
9336
9496
|
if (ancestryResponse.success && Array.isArray(ancestryResponse.data)) {
|
|
9337
9497
|
const viewSpecificAncestries = ancestryResponse.data.filter(
|
|
9338
9498
|
(anc) => anc._source_file_id === viewToImport.id && !anc.is_private
|
|
9339
|
-
// <--- AQUI ESTÁ A TRAVA DE SEGURANÇA
|
|
9340
9499
|
);
|
|
9341
9500
|
const processedAncestries = viewSpecificAncestries.map((anc) => ({
|
|
9342
9501
|
...anc,
|
|
@@ -9387,7 +9546,7 @@ function XViewScene({
|
|
|
9387
9546
|
const handleOpenImageViewer = (images, startIndex) => {
|
|
9388
9547
|
setImageViewer({ visible: true, images, startIndex });
|
|
9389
9548
|
};
|
|
9390
|
-
const tweenToTarget =
|
|
9549
|
+
const tweenToTarget = useCallback4((target, zoomFactor = 1, forcedDirection = null) => {
|
|
9391
9550
|
const { camera, controls, tweenGroup } = stateRef.current;
|
|
9392
9551
|
if (!camera || !controls || !tweenGroup) return;
|
|
9393
9552
|
const targetPos = target instanceof THREE3.Mesh ? target.getWorldPosition(new THREE3.Vector3()) : target;
|
|
@@ -9410,7 +9569,7 @@ function XViewScene({
|
|
|
9410
9569
|
if (!t || typeof t.closest !== "function") return false;
|
|
9411
9570
|
return !!t.closest(".ui-overlay");
|
|
9412
9571
|
};
|
|
9413
|
-
const buildFullAncestryTree =
|
|
9572
|
+
const buildFullAncestryTree = useCallback4((idTree, nodes, ancestries = []) => {
|
|
9414
9573
|
if (!idTree) return null;
|
|
9415
9574
|
const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
|
|
9416
9575
|
const ancestryMap = new Map(ancestries.map((a) => [String(a.ancestry_id), a]));
|
|
@@ -9436,14 +9595,10 @@ function XViewScene({
|
|
|
9436
9595
|
return {
|
|
9437
9596
|
...branch,
|
|
9438
9597
|
name: linkedAncestry.name,
|
|
9439
|
-
// Sobrescreve nome para exibição
|
|
9440
9598
|
description: linkedAncestry.description,
|
|
9441
|
-
// Sobrescreve descrição
|
|
9442
9599
|
description_sections: linkedAncestry.description_sections,
|
|
9443
9600
|
tree: graftedTree,
|
|
9444
|
-
// ENXERTA A ÁRVORE AQUI
|
|
9445
9601
|
isLinked: true
|
|
9446
|
-
// Flag útil
|
|
9447
9602
|
};
|
|
9448
9603
|
}
|
|
9449
9604
|
}
|
|
@@ -9490,7 +9645,7 @@ function XViewScene({
|
|
|
9490
9645
|
}
|
|
9491
9646
|
return recursiveBuild(idTree);
|
|
9492
9647
|
}, []);
|
|
9493
|
-
const handleActivateTimeline =
|
|
9648
|
+
const handleActivateTimeline = useCallback4(() => {
|
|
9494
9649
|
const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
9495
9650
|
if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
|
|
9496
9651
|
while (timelineIntervalsGroup.children.length > 0) {
|
|
@@ -9643,7 +9798,7 @@ function XViewScene({
|
|
|
9643
9798
|
}
|
|
9644
9799
|
});
|
|
9645
9800
|
}, []);
|
|
9646
|
-
const handleVersionTimeline =
|
|
9801
|
+
const handleVersionTimeline = useCallback4((sourceMesh, versionMeshes) => {
|
|
9647
9802
|
const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
9648
9803
|
if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0) return;
|
|
9649
9804
|
versionMeshes.forEach((mesh) => {
|
|
@@ -9836,16 +9991,14 @@ function XViewScene({
|
|
|
9836
9991
|
isInitialized,
|
|
9837
9992
|
permissionStatus,
|
|
9838
9993
|
focusNodeId,
|
|
9839
|
-
// <-- MANTIDO
|
|
9840
9994
|
focusAncestryId
|
|
9841
|
-
// <-- ADICIONADO O focusAncestryId NAS DEPENDÊNCIAS
|
|
9842
9995
|
]);
|
|
9843
|
-
const isNodeInView =
|
|
9996
|
+
const isNodeInView = useCallback4((id) => {
|
|
9844
9997
|
const key = String(id);
|
|
9845
9998
|
const objs = stateRef.current.nodeObjects || {};
|
|
9846
9999
|
return !!objs[key];
|
|
9847
10000
|
}, []);
|
|
9848
|
-
const addOrUpdateNodeMesh =
|
|
10001
|
+
const addOrUpdateNodeMesh = useCallback4((nodeData, position, suppressVersionUpdate = false) => {
|
|
9849
10002
|
const { graphGroup, nodeObjects, clickableNodes, glowTexture, tweenGroup } = stateRef.current;
|
|
9850
10003
|
const nodeId = String(nodeData.id);
|
|
9851
10004
|
if (nodeObjects[nodeId]) {
|
|
@@ -10494,7 +10647,7 @@ function XViewScene({
|
|
|
10494
10647
|
}
|
|
10495
10648
|
};
|
|
10496
10649
|
}, [isInitialized, tweenToTarget, dbSaveUrl, isNodeInView, addOrUpdateNodeMesh, handleActivateTimeline, get_scene_view_data, save_view_data]);
|
|
10497
|
-
const handleGhostNodeImageChange =
|
|
10650
|
+
const handleGhostNodeImageChange = useCallback4((useImage, imageUrl) => {
|
|
10498
10651
|
const { node: ghostNode, line: ghostLine, aura: ghostAura } = stateRef.current.ghostElements;
|
|
10499
10652
|
const { graphGroup, glowTexture } = stateRef.current;
|
|
10500
10653
|
if (!ghostNode || !graphGroup) return;
|
|
@@ -10536,7 +10689,7 @@ function XViewScene({
|
|
|
10536
10689
|
aura: newGhostNode.getObjectByName("aura")
|
|
10537
10690
|
};
|
|
10538
10691
|
}, []);
|
|
10539
|
-
const handleGhostNodeIntensityChange =
|
|
10692
|
+
const handleGhostNodeIntensityChange = useCallback4((newIntensity) => {
|
|
10540
10693
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
10541
10694
|
if (!ghostNode) return;
|
|
10542
10695
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -10557,7 +10710,7 @@ function XViewScene({
|
|
|
10557
10710
|
ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
|
|
10558
10711
|
}
|
|
10559
10712
|
}, []);
|
|
10560
|
-
const handleDetailNodeIntensityChange =
|
|
10713
|
+
const handleDetailNodeIntensityChange = useCallback4((nodeId, newIntensity) => {
|
|
10561
10714
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
10562
10715
|
if (!mesh) return;
|
|
10563
10716
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -10703,7 +10856,7 @@ function XViewScene({
|
|
|
10703
10856
|
mountRef.current.style.cursor = "default";
|
|
10704
10857
|
}
|
|
10705
10858
|
};
|
|
10706
|
-
const handleAncestryTreeUpdate =
|
|
10859
|
+
const handleAncestryTreeUpdate = useCallback4((newTree, extraData = null) => {
|
|
10707
10860
|
setAncestryMode((prev) => {
|
|
10708
10861
|
const prevTreeStr = JSON.stringify(prev.tree);
|
|
10709
10862
|
const newTreeStr = JSON.stringify(newTree);
|
|
@@ -10773,7 +10926,7 @@ function XViewScene({
|
|
|
10773
10926
|
const handleStartVersioning = (nodeData) => {
|
|
10774
10927
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
10775
10928
|
};
|
|
10776
|
-
const handleClearAncestryVisuals =
|
|
10929
|
+
const handleClearAncestryVisuals = useCallback4((ancestryId) => {
|
|
10777
10930
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
10778
10931
|
const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
|
|
10779
10932
|
if (renderIndex !== -1) {
|
|
@@ -10787,7 +10940,7 @@ function XViewScene({
|
|
|
10787
10940
|
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
10788
10941
|
}
|
|
10789
10942
|
}, []);
|
|
10790
|
-
const handleRenderAncestry =
|
|
10943
|
+
const handleRenderAncestry = useCallback4(
|
|
10791
10944
|
async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
|
|
10792
10945
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
10793
10946
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -11203,7 +11356,7 @@ function XViewScene({
|
|
|
11203
11356
|
},
|
|
11204
11357
|
[addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, readingMode.isActive, ancestryMode.isActive]
|
|
11205
11358
|
);
|
|
11206
|
-
const handleRenderAbstractionTree =
|
|
11359
|
+
const handleRenderAbstractionTree = useCallback4((ancestryObject, targetNodeId = null) => {
|
|
11207
11360
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11208
11361
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
11209
11362
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
@@ -11264,7 +11417,7 @@ function XViewScene({
|
|
|
11264
11417
|
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
11265
11418
|
tweenToTarget(rootTargetPos, 0.7);
|
|
11266
11419
|
}, [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, handleClearAncestryVisuals]);
|
|
11267
|
-
const handleReadModeBranchNav =
|
|
11420
|
+
const handleReadModeBranchNav = useCallback4((nodeId, action, direction = "right") => {
|
|
11268
11421
|
const { ancestry, branchStack } = readingMode;
|
|
11269
11422
|
if (!ancestry || !ancestry.tree) return;
|
|
11270
11423
|
const allAncestries = ancestryDataRef.current || [];
|
|
@@ -11302,9 +11455,7 @@ function XViewScene({
|
|
|
11302
11455
|
description_sections: branchToOpen.description_sections,
|
|
11303
11456
|
tree: branchToOpen.tree,
|
|
11304
11457
|
_originNodeId: nodeId,
|
|
11305
|
-
// <--- ID do node pai (link visual)
|
|
11306
11458
|
_branchDirection: direction
|
|
11307
|
-
// <--- Direção para cálculo de posição
|
|
11308
11459
|
};
|
|
11309
11460
|
const allowedIds = /* @__PURE__ */ new Set(["preamble", 0, "0"]);
|
|
11310
11461
|
const branchSections = parseDescriptionSections(branchToOpen.description || "", branchToOpen.description_sections || []);
|
|
@@ -11360,7 +11511,6 @@ function XViewScene({
|
|
|
11360
11511
|
const parentAncestryObj = {
|
|
11361
11512
|
...targetAncestryInfo,
|
|
11362
11513
|
tree: targetTreeToRender,
|
|
11363
|
-
// Re-injeta a origem se o pai também for uma branch aninhada
|
|
11364
11514
|
_originNodeId: activeParentStackItem ? activeParentStackItem.nodeId : null,
|
|
11365
11515
|
_branchDirection: activeParentStackItem ? activeParentStackItem.entryDirection : null
|
|
11366
11516
|
};
|
|
@@ -11408,7 +11558,7 @@ function XViewScene({
|
|
|
11408
11558
|
}));
|
|
11409
11559
|
}
|
|
11410
11560
|
}, [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]);
|
|
11411
|
-
const handleReadModeHighlight =
|
|
11561
|
+
const handleReadModeHighlight = useCallback4((nodeId) => {
|
|
11412
11562
|
if (stateRef.current.highlightedNodeId !== nodeId) {
|
|
11413
11563
|
stateRef.current.highlightedNodeId = nodeId;
|
|
11414
11564
|
}
|
|
@@ -11420,7 +11570,6 @@ function XViewScene({
|
|
|
11420
11570
|
readingMode.ancestry.tree,
|
|
11421
11571
|
Object.values(parentDataRef.current).flatMap((f) => f.nodes),
|
|
11422
11572
|
ancestryDataRef.current
|
|
11423
|
-
// <--- Adicionar
|
|
11424
11573
|
);
|
|
11425
11574
|
const findNodeInTree = (tree, targetId) => {
|
|
11426
11575
|
if (!tree) return null;
|
|
@@ -11474,7 +11623,6 @@ function XViewScene({
|
|
|
11474
11623
|
description_sections: ancestry.description_sections,
|
|
11475
11624
|
direction: null,
|
|
11476
11625
|
customProperties: rootProps
|
|
11477
|
-
// <--- ADICIONADO
|
|
11478
11626
|
};
|
|
11479
11627
|
}
|
|
11480
11628
|
const fullTree = buildFullAncestryTree(
|
|
@@ -11503,7 +11651,6 @@ function XViewScene({
|
|
|
11503
11651
|
description_sections: currentMeta.description_sections,
|
|
11504
11652
|
direction: currentDirection,
|
|
11505
11653
|
customProperties: branchProps
|
|
11506
|
-
// <--- ADICIONADO
|
|
11507
11654
|
};
|
|
11508
11655
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
11509
11656
|
const readModeAbstractionTree = useMemo12(() => {
|
|
@@ -11518,7 +11665,7 @@ function XViewScene({
|
|
|
11518
11665
|
allAncestries
|
|
11519
11666
|
);
|
|
11520
11667
|
}, [readingMode.isActive, readingMode.ancestry, buildFullAncestryTree, sceneVersion]);
|
|
11521
|
-
const handleStartReadingAncestry =
|
|
11668
|
+
const handleStartReadingAncestry = useCallback4(
|
|
11522
11669
|
async (ancestryObject) => {
|
|
11523
11670
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11524
11671
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -11539,7 +11686,6 @@ function XViewScene({
|
|
|
11539
11686
|
ancestry: ancestryObject,
|
|
11540
11687
|
branchStack: [],
|
|
11541
11688
|
autoAbstraction: shouldAutoRenderAbstraction
|
|
11542
|
-
// <--- FLAG ENVIADA PARA A UI
|
|
11543
11689
|
});
|
|
11544
11690
|
if (shouldAutoRenderAbstraction) {
|
|
11545
11691
|
handleRenderAbstractionTree(ancestryObject, null);
|
|
@@ -11553,9 +11699,8 @@ function XViewScene({
|
|
|
11553
11699
|
}
|
|
11554
11700
|
},
|
|
11555
11701
|
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
11556
|
-
// <--- DEPENDÊNCIA ADICIONADA
|
|
11557
11702
|
);
|
|
11558
|
-
const handleReadModeSectionChange =
|
|
11703
|
+
const handleReadModeSectionChange = useCallback4((activeSectionId) => {
|
|
11559
11704
|
const { ancestry, branchStack } = readingMode;
|
|
11560
11705
|
if (!ancestry || !readingMode.isActive) return;
|
|
11561
11706
|
let targetObj = ancestry;
|
|
@@ -11624,10 +11769,10 @@ function XViewScene({
|
|
|
11624
11769
|
}, 0);
|
|
11625
11770
|
handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
|
|
11626
11771
|
}, [readingMode, handleRenderAncestry, buildFullAncestryTree, ancestryDataRef.current]);
|
|
11627
|
-
const handleCloseReadMode =
|
|
11772
|
+
const handleCloseReadMode = useCallback4(() => {
|
|
11628
11773
|
setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
|
|
11629
11774
|
}, []);
|
|
11630
|
-
const handleAncestrySectionChange =
|
|
11775
|
+
const handleAncestrySectionChange = useCallback4((activeSectionId, ancestryOverride = null, rotation = 0) => {
|
|
11631
11776
|
var _a2, _b2;
|
|
11632
11777
|
const currentMode = stateRef.current.ancestry;
|
|
11633
11778
|
let targetObj = ancestryOverride;
|
|
@@ -11679,7 +11824,7 @@ function XViewScene({
|
|
|
11679
11824
|
const renderPayload = { ...targetObj, tree: treeToRender };
|
|
11680
11825
|
handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
|
|
11681
11826
|
}, [handleRenderAncestry]);
|
|
11682
|
-
const handleEditAncestry =
|
|
11827
|
+
const handleEditAncestry = useCallback4(
|
|
11683
11828
|
async (ancestryObject) => {
|
|
11684
11829
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11685
11830
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -11702,10 +11847,8 @@ function XViewScene({
|
|
|
11702
11847
|
...ancestryObject,
|
|
11703
11848
|
tree: fullTree,
|
|
11704
11849
|
abstraction_tree: fullAbstractionTree,
|
|
11705
|
-
// NOVO
|
|
11706
11850
|
selectedParentId: ancestryObject.ancestral_node,
|
|
11707
11851
|
selectedAbstractionParentId: ancestryObject.ancestral_node,
|
|
11708
|
-
// NOVO
|
|
11709
11852
|
isEditMode: true,
|
|
11710
11853
|
currentAncestryId: ancestryObject.ancestry_id,
|
|
11711
11854
|
ancestryName: ancestryObject.name || `Ancestralidade ${fullTree.node.name}`,
|
|
@@ -11713,7 +11856,6 @@ function XViewScene({
|
|
|
11713
11856
|
ancestryDescriptionSections: ancestryObject.description_sections || [],
|
|
11714
11857
|
isAddingNodes: false,
|
|
11715
11858
|
isAddingAbstractionNodes: false
|
|
11716
|
-
// NOVO
|
|
11717
11859
|
});
|
|
11718
11860
|
},
|
|
11719
11861
|
[handleRenderAncestry, buildFullAncestryTree]
|
|
@@ -11721,7 +11863,7 @@ function XViewScene({
|
|
|
11721
11863
|
const handleSelectAncestryParent = (nodeId) => {
|
|
11722
11864
|
setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
|
|
11723
11865
|
};
|
|
11724
|
-
const handleRemoveFromAncestry =
|
|
11866
|
+
const handleRemoveFromAncestry = useCallback4((pathToRemove) => {
|
|
11725
11867
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
|
|
11726
11868
|
console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
|
|
11727
11869
|
return;
|
|
@@ -11746,7 +11888,7 @@ function XViewScene({
|
|
|
11746
11888
|
return { ...prev, tree: newTree };
|
|
11747
11889
|
});
|
|
11748
11890
|
}, []);
|
|
11749
|
-
const handleSaveAncestry =
|
|
11891
|
+
const handleSaveAncestry = useCallback4(
|
|
11750
11892
|
async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
|
|
11751
11893
|
const treeToUse = treeOverride || ancestryMode.tree;
|
|
11752
11894
|
const { isEditMode, currentAncestryId } = ancestryMode;
|
|
@@ -11950,7 +12092,7 @@ function XViewScene({
|
|
|
11950
12092
|
});
|
|
11951
12093
|
setEditingAncestryRel({ visible: false, data: null, path: null });
|
|
11952
12094
|
};
|
|
11953
|
-
const handleDeleteAncestry =
|
|
12095
|
+
const handleDeleteAncestry = useCallback4(
|
|
11954
12096
|
async (ancestryIdToDelete) => {
|
|
11955
12097
|
if (!ancestryIdToDelete) {
|
|
11956
12098
|
alert("ID da ancestralidade n\xE3o encontrado.");
|
|
@@ -12012,15 +12154,15 @@ function XViewScene({
|
|
|
12012
12154
|
},
|
|
12013
12155
|
[save_view_data, delete_file_action]
|
|
12014
12156
|
);
|
|
12015
|
-
const handleOpenAncestryBoard =
|
|
12157
|
+
const handleOpenAncestryBoard = useCallback4(() => {
|
|
12016
12158
|
setIsAncestryBoardOpen(true);
|
|
12017
12159
|
}, []);
|
|
12018
|
-
const handleSelectAncestryFromBoard =
|
|
12160
|
+
const handleSelectAncestryFromBoard = useCallback4((ancestry) => {
|
|
12019
12161
|
setIsAncestryBoardOpen(false);
|
|
12020
12162
|
setIsSidebarOpen(false);
|
|
12021
12163
|
handleStartReadingAncestry(ancestry);
|
|
12022
12164
|
}, [handleStartReadingAncestry]);
|
|
12023
|
-
const handleSaveAncestryBoard =
|
|
12165
|
+
const handleSaveAncestryBoard = useCallback4(async (groups) => {
|
|
12024
12166
|
if (!sceneConfigId || !viewParams || !session) return;
|
|
12025
12167
|
const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
|
|
12026
12168
|
await save_ancestry_board_action(sceneConfigId, sceneType, groups, session, ownerId);
|
|
@@ -12044,13 +12186,13 @@ function XViewScene({
|
|
|
12044
12186
|
return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
|
|
12045
12187
|
});
|
|
12046
12188
|
}, [parentDataRef.current, sceneVersion]);
|
|
12047
|
-
const handleAddExistingNode =
|
|
12189
|
+
const handleAddExistingNode = useCallback4(
|
|
12048
12190
|
(nodeId) => {
|
|
12049
12191
|
return userActionHandlers.handleAddExistingNodeById(actionHandlerContext, nodeId);
|
|
12050
12192
|
},
|
|
12051
12193
|
[actionHandlerContext]
|
|
12052
12194
|
);
|
|
12053
|
-
const handleSaveCurrentView =
|
|
12195
|
+
const handleSaveCurrentView = useCallback4(async () => {
|
|
12054
12196
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
12055
12197
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
12056
12198
|
console.warn("N\xE3o \xE9 poss\xEDvel salvar a cena: estado n\xE3o inicializado ou URL de salvamento ausente.");
|
|
@@ -12090,7 +12232,7 @@ function XViewScene({
|
|
|
12090
12232
|
const allAvailableAncestries = useMemo12(() => {
|
|
12091
12233
|
return ancestryDataRef.current || [];
|
|
12092
12234
|
}, [sceneVersion, isInitialized]);
|
|
12093
|
-
const handleOpenReference =
|
|
12235
|
+
const handleOpenReference = useCallback4((referenceData) => {
|
|
12094
12236
|
const { type, id } = referenceData;
|
|
12095
12237
|
if (type === "node") {
|
|
12096
12238
|
const targetNode = allAvailableNodes.find((n) => String(n.id) === String(id));
|
|
@@ -12117,10 +12259,10 @@ function XViewScene({
|
|
|
12117
12259
|
}
|
|
12118
12260
|
}
|
|
12119
12261
|
}, [allAvailableNodes, allAvailableAncestries, handleEditAncestry, tweenToTarget]);
|
|
12120
|
-
const handleToggleAncestryAddMode =
|
|
12262
|
+
const handleToggleAncestryAddMode = useCallback4(() => {
|
|
12121
12263
|
setAncestryMode((prev) => ({ ...prev, isAddingNodes: !prev.isAddingNodes }));
|
|
12122
12264
|
}, []);
|
|
12123
|
-
const handleFocusNode =
|
|
12265
|
+
const handleFocusNode = useCallback4((nodeData) => {
|
|
12124
12266
|
if (!nodeData) return;
|
|
12125
12267
|
const nodeMesh = stateRef.current.nodeObjects[String(nodeData.id)];
|
|
12126
12268
|
if (nodeMesh) {
|
|
@@ -12190,7 +12332,6 @@ function XViewScene({
|
|
|
12190
12332
|
height: "100vh",
|
|
12191
12333
|
position: "relative",
|
|
12192
12334
|
overflow: "hidden",
|
|
12193
|
-
// <--- ADICIONE ESTA LINHA
|
|
12194
12335
|
cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
|
|
12195
12336
|
}
|
|
12196
12337
|
},
|
|
@@ -12257,9 +12398,20 @@ function XViewScene({
|
|
|
12257
12398
|
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React23.createElement(
|
|
12258
12399
|
"div",
|
|
12259
12400
|
{
|
|
12260
|
-
className:
|
|
12261
|
-
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" }
|
|
12262
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
|
+
),
|
|
12263
12415
|
/* @__PURE__ */ React23.createElement(
|
|
12264
12416
|
DescriptionReadModePanel,
|
|
12265
12417
|
{
|