@lv-x-software-house/x_view 1.2.4-dev.21 → 1.2.4-dev.23
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 +607 -281
- package/dist/index.mjs +547 -221
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/XViewScene.jsx
|
|
2
|
-
import
|
|
2
|
+
import React25, { useCallback as useCallback4, useEffect as useEffect22, useRef as useRef19, useState as useState25, 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";
|
|
@@ -8641,8 +8641,313 @@ function NodeDetailsPanel({
|
|
|
8641
8641
|
));
|
|
8642
8642
|
}
|
|
8643
8643
|
|
|
8644
|
+
// src/components/QuestDetailsPanel.jsx
|
|
8645
|
+
import React17, { useState as useState18, useEffect as useEffect16, useRef as useRef14 } from "react";
|
|
8646
|
+
import { FiPlus as FiPlus7, FiX as FiX6, FiCheck as FiCheck11, FiEdit2 as FiEdit28, FiLoader as FiLoader3, FiBookOpen as FiBookOpen4, FiLink as FiLink6, FiTarget as FiTarget2, FiChevronDown as FiChevronDown6 } from "react-icons/fi";
|
|
8647
|
+
var QUEST_STATUS_COLORS2 = {
|
|
8648
|
+
"Backlog": "#64748b",
|
|
8649
|
+
"In Progress": "#eab308",
|
|
8650
|
+
"Review": "#a855f7",
|
|
8651
|
+
"Done": "#22c55e"
|
|
8652
|
+
};
|
|
8653
|
+
function QuestDetailsPanel({
|
|
8654
|
+
node,
|
|
8655
|
+
onClose,
|
|
8656
|
+
onSave,
|
|
8657
|
+
onNameChange,
|
|
8658
|
+
onColorChange,
|
|
8659
|
+
onSizeChange,
|
|
8660
|
+
onDataUpdate,
|
|
8661
|
+
onOpenImageViewer,
|
|
8662
|
+
existingTypes = [],
|
|
8663
|
+
availableNodes = [],
|
|
8664
|
+
availableAncestries = [],
|
|
8665
|
+
onOpenReference,
|
|
8666
|
+
onMentionClick,
|
|
8667
|
+
onUploadFile,
|
|
8668
|
+
userRole,
|
|
8669
|
+
currentDatasetName
|
|
8670
|
+
}) {
|
|
8671
|
+
const [name, setName] = useState18((node == null ? void 0 : node.name) ?? "");
|
|
8672
|
+
const [types, setTypes] = useState18((node == null ? void 0 : node.type) ? Array.isArray(node.type) ? node.type : [node.type] : ["quest"]);
|
|
8673
|
+
const [typeInput, setTypeInput] = useState18("");
|
|
8674
|
+
const [status, setStatus] = useState18((node == null ? void 0 : node.status) ?? "Backlog");
|
|
8675
|
+
const [size, setSize] = useState18((node == null ? void 0 : node.size) ?? "medium");
|
|
8676
|
+
const [description, setDescription] = useState18((node == null ? void 0 : node.description) ?? "");
|
|
8677
|
+
const [intensity, setIntensity] = useState18((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
|
|
8678
|
+
const [isStatusDropdownOpen, setIsStatusDropdownOpen] = useState18(false);
|
|
8679
|
+
const [customProps, setCustomProps] = useState18(() => extractCustomPropsFromNode(node || {}));
|
|
8680
|
+
const [showTypeSuggestions, setShowTypeSuggestions] = useState18(false);
|
|
8681
|
+
const [filteredTypes, setFilteredTypes] = useState18([]);
|
|
8682
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState18(false);
|
|
8683
|
+
const [isReadMode, setIsReadMode] = useState18(false);
|
|
8684
|
+
const [existingSections, setExistingSections] = useState18((node == null ? void 0 : node.description_sections) || []);
|
|
8685
|
+
const [isSaving, setIsSaving] = useState18(false);
|
|
8686
|
+
const [isLinkCopied, setIsLinkCopied] = useState18(false);
|
|
8687
|
+
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
8688
|
+
const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
|
|
8689
|
+
initialWidth: isReadMode ? 700 : 440,
|
|
8690
|
+
minWidth: 320,
|
|
8691
|
+
maxWidth: maxPanelW
|
|
8692
|
+
});
|
|
8693
|
+
useEffect16(() => {
|
|
8694
|
+
setWidth(isReadMode ? 700 : 440);
|
|
8695
|
+
}, [isReadMode, setWidth]);
|
|
8696
|
+
const prevNodeIdRef = useRef14(null);
|
|
8697
|
+
const propsEndRef = useRef14(null);
|
|
8698
|
+
const canEdit = userRole !== "viewer";
|
|
8699
|
+
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
8700
|
+
const handleImageClickFromText = (url, name2) => {
|
|
8701
|
+
if (onOpenImageViewer) {
|
|
8702
|
+
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
8703
|
+
}
|
|
8704
|
+
};
|
|
8705
|
+
useEffect16(() => {
|
|
8706
|
+
if ((node == null ? void 0 : node.id) !== prevNodeIdRef.current) {
|
|
8707
|
+
prevNodeIdRef.current = node == null ? void 0 : node.id;
|
|
8708
|
+
setName((node == null ? void 0 : node.name) ?? "");
|
|
8709
|
+
setTypes((node == null ? void 0 : node.type) ? Array.isArray(node.type) ? node.type : [node.type] : ["quest"]);
|
|
8710
|
+
setStatus((node == null ? void 0 : node.status) ?? "Backlog");
|
|
8711
|
+
setSize((node == null ? void 0 : node.size) ?? "medium");
|
|
8712
|
+
setDescription((node == null ? void 0 : node.description) ?? "");
|
|
8713
|
+
setIntensity((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
|
|
8714
|
+
setExistingSections((node == null ? void 0 : node.description_sections) || []);
|
|
8715
|
+
setCustomProps(extractCustomPropsFromNode(node || {}));
|
|
8716
|
+
}
|
|
8717
|
+
}, [node]);
|
|
8718
|
+
useEffect16(() => {
|
|
8719
|
+
if (typeInput.trim() === "") {
|
|
8720
|
+
setFilteredTypes(existingTypes.filter((t) => !types.includes(t)));
|
|
8721
|
+
} else {
|
|
8722
|
+
const lowercasedInput = typeInput.toLowerCase();
|
|
8723
|
+
setFilteredTypes(
|
|
8724
|
+
existingTypes.filter(
|
|
8725
|
+
(t) => t.toLowerCase().includes(lowercasedInput) && !types.includes(t)
|
|
8726
|
+
)
|
|
8727
|
+
);
|
|
8728
|
+
}
|
|
8729
|
+
}, [typeInput, existingTypes, types]);
|
|
8730
|
+
const handleCopyLink = () => {
|
|
8731
|
+
if (!(node == null ? void 0 : node.id)) return;
|
|
8732
|
+
const baseUrl = window.location.origin + window.location.pathname;
|
|
8733
|
+
const fullUrl = `${baseUrl}?focus=${node.id}`;
|
|
8734
|
+
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
8735
|
+
setIsLinkCopied(true);
|
|
8736
|
+
setTimeout(() => setIsLinkCopied(false), 2e3);
|
|
8737
|
+
}).catch((err) => {
|
|
8738
|
+
console.error("Erro ao copiar link:", err);
|
|
8739
|
+
});
|
|
8740
|
+
};
|
|
8741
|
+
const swallow = (e) => e.stopPropagation();
|
|
8742
|
+
const handleNameChange = (e) => {
|
|
8743
|
+
const v = e.target.value;
|
|
8744
|
+
setName(v);
|
|
8745
|
+
onNameChange == null ? void 0 : onNameChange(node.id, v);
|
|
8746
|
+
};
|
|
8747
|
+
const handleSizeChange = (newSize) => {
|
|
8748
|
+
setSize(newSize);
|
|
8749
|
+
onSizeChange == null ? void 0 : onSizeChange(node.id, newSize);
|
|
8750
|
+
};
|
|
8751
|
+
const handleStatusChange = (newStatus) => {
|
|
8752
|
+
setStatus(newStatus);
|
|
8753
|
+
const newColor = QUEST_STATUS_COLORS2[newStatus];
|
|
8754
|
+
onColorChange == null ? void 0 : onColorChange(node.id, newColor);
|
|
8755
|
+
onDataUpdate == null ? void 0 : onDataUpdate({ ...node, status: newStatus, color: newColor });
|
|
8756
|
+
};
|
|
8757
|
+
const handleAddType = (newType) => {
|
|
8758
|
+
const trimmed = newType.trim();
|
|
8759
|
+
if (trimmed && !types.includes(trimmed)) {
|
|
8760
|
+
setTypes([...types, trimmed]);
|
|
8761
|
+
setTypeInput("");
|
|
8762
|
+
setShowTypeSuggestions(false);
|
|
8763
|
+
}
|
|
8764
|
+
};
|
|
8765
|
+
const handleRemoveType = (indexToRemove) => {
|
|
8766
|
+
if (types[indexToRemove] === "quest") return;
|
|
8767
|
+
setTypes(types.filter((_, index) => index !== indexToRemove));
|
|
8768
|
+
};
|
|
8769
|
+
const handleTypeInputKeyDown = (e) => {
|
|
8770
|
+
if (e.key === "Enter") {
|
|
8771
|
+
e.preventDefault();
|
|
8772
|
+
handleAddType(typeInput);
|
|
8773
|
+
} else if (e.key === "Backspace" && typeInput === "" && types.length > 1) {
|
|
8774
|
+
handleRemoveType(types.length - 1);
|
|
8775
|
+
}
|
|
8776
|
+
};
|
|
8777
|
+
const handleAddProp = () => {
|
|
8778
|
+
const newProp = createNewCustomProperty(customProps);
|
|
8779
|
+
setCustomProps((p) => [...p, newProp]);
|
|
8780
|
+
setTimeout(() => {
|
|
8781
|
+
var _a;
|
|
8782
|
+
(_a = propsEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
8783
|
+
}, 100);
|
|
8784
|
+
};
|
|
8785
|
+
const handleRemoveProp = (i) => {
|
|
8786
|
+
const newProps = customProps.filter((_, idx) => idx !== i);
|
|
8787
|
+
setCustomProps(newProps);
|
|
8788
|
+
triggerAutoSave({ customProps: newProps });
|
|
8789
|
+
};
|
|
8790
|
+
const handleUpdateProp = (index, updatedProp) => {
|
|
8791
|
+
const newProps = [...customProps];
|
|
8792
|
+
newProps[index] = updatedProp;
|
|
8793
|
+
setCustomProps(newProps);
|
|
8794
|
+
if (!updatedProp.isEditing) {
|
|
8795
|
+
triggerAutoSave({ customProps: newProps });
|
|
8796
|
+
}
|
|
8797
|
+
};
|
|
8798
|
+
const handleSaveDescriptionInline = (newDescription) => {
|
|
8799
|
+
setDescription(newDescription);
|
|
8800
|
+
onDataUpdate({ ...node, description: newDescription });
|
|
8801
|
+
triggerAutoSave({ description: newDescription });
|
|
8802
|
+
};
|
|
8803
|
+
const handleSave = async (keepOpen = false, overrides = {}) => {
|
|
8804
|
+
const currentName = overrides.name !== void 0 ? overrides.name : name;
|
|
8805
|
+
const currentTypes = overrides.types !== void 0 ? overrides.types : types;
|
|
8806
|
+
const currentDescription = overrides.description !== void 0 ? overrides.description : description;
|
|
8807
|
+
const currentCustomProps = overrides.customProps !== void 0 ? overrides.customProps : customProps;
|
|
8808
|
+
const currentExistingSections = overrides.existingSections !== void 0 ? overrides.existingSections : existingSections;
|
|
8809
|
+
const currentStatus = overrides.status !== void 0 ? overrides.status : status;
|
|
8810
|
+
if (!currentName.trim() || currentTypes.length === 0) {
|
|
8811
|
+
alert("O campo 'Nome' e pelo menos um 'Tipo' s\xE3o obrigat\xF3rios.");
|
|
8812
|
+
return;
|
|
8813
|
+
}
|
|
8814
|
+
setIsSaving(true);
|
|
8815
|
+
try {
|
|
8816
|
+
const extrasObj = toObjectFromCustomProps(currentCustomProps.filter((p) => !p.isEditing));
|
|
8817
|
+
const processedSections = processDescriptionForSave(currentDescription, currentExistingSections);
|
|
8818
|
+
const dataToSave = {
|
|
8819
|
+
id: node.id,
|
|
8820
|
+
name: currentName.trim(),
|
|
8821
|
+
type: currentTypes,
|
|
8822
|
+
color: QUEST_STATUS_COLORS2[currentStatus],
|
|
8823
|
+
status: currentStatus,
|
|
8824
|
+
size,
|
|
8825
|
+
description: currentDescription,
|
|
8826
|
+
description_sections: processedSections,
|
|
8827
|
+
useImageAsTexture: false,
|
|
8828
|
+
textureImageUrl: null,
|
|
8829
|
+
intensity,
|
|
8830
|
+
is_quest: true,
|
|
8831
|
+
...extrasObj,
|
|
8832
|
+
version_node: node.version_node
|
|
8833
|
+
};
|
|
8834
|
+
await onSave(dataToSave, keepOpen);
|
|
8835
|
+
onDataUpdate(dataToSave);
|
|
8836
|
+
if (!keepOpen) {
|
|
8837
|
+
onClose();
|
|
8838
|
+
}
|
|
8839
|
+
} finally {
|
|
8840
|
+
setIsSaving(false);
|
|
8841
|
+
}
|
|
8842
|
+
};
|
|
8843
|
+
const triggerAutoSave = (overrides = {}) => {
|
|
8844
|
+
handleSave(true, overrides);
|
|
8845
|
+
};
|
|
8846
|
+
const handleCancel = () => {
|
|
8847
|
+
if (node) {
|
|
8848
|
+
onNameChange == null ? void 0 : onNameChange(node.id, node.name);
|
|
8849
|
+
onColorChange == null ? void 0 : onColorChange(node.id, node.color);
|
|
8850
|
+
onSizeChange == null ? void 0 : onSizeChange(node.id, node.size || "medium");
|
|
8851
|
+
}
|
|
8852
|
+
onClose();
|
|
8853
|
+
};
|
|
8854
|
+
const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
|
|
8855
|
+
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(
|
|
8856
|
+
"div",
|
|
8857
|
+
{
|
|
8858
|
+
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"}`,
|
|
8859
|
+
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${panelWidth}px`, maxWidth: "92vw" },
|
|
8860
|
+
onPointerDown: swallow,
|
|
8861
|
+
onPointerMove: swallow,
|
|
8862
|
+
onPointerUp: swallow,
|
|
8863
|
+
onClick: swallow,
|
|
8864
|
+
onWheel: swallow,
|
|
8865
|
+
onContextMenu: swallow,
|
|
8866
|
+
onDoubleClick: swallow
|
|
8867
|
+
},
|
|
8868
|
+
/* @__PURE__ */ React17.createElement("div", { onPointerDown: (e) => {
|
|
8869
|
+
e.stopPropagation();
|
|
8870
|
+
handleResize(e);
|
|
8871
|
+
}, className: "absolute left-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-indigo-500/50 z-[2000] transition-colors", title: "Arraste para redimensionar" }),
|
|
8872
|
+
isReadMode ? /* @__PURE__ */ React17.createElement(
|
|
8873
|
+
DescriptionReadModePanel,
|
|
8874
|
+
{
|
|
8875
|
+
title: name || (node == null ? void 0 : node.name),
|
|
8876
|
+
description,
|
|
8877
|
+
savedSections: existingSections,
|
|
8878
|
+
onBack: () => setIsReadMode(false),
|
|
8879
|
+
onEdit: () => {
|
|
8880
|
+
if (canEdit) {
|
|
8881
|
+
setIsReadMode(false);
|
|
8882
|
+
setIsDescriptionModalOpen(true);
|
|
8883
|
+
}
|
|
8884
|
+
},
|
|
8885
|
+
onClose: handleCancel,
|
|
8886
|
+
availableNodes,
|
|
8887
|
+
availableAncestries,
|
|
8888
|
+
onOpenReference,
|
|
8889
|
+
onMentionClick,
|
|
8890
|
+
onImageClick: handleImageClickFromText,
|
|
8891
|
+
onSaveDescription: handleSaveDescriptionInline
|
|
8892
|
+
}
|
|
8893
|
+
) : /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS2[status]}, transparent)` } }), /* @__PURE__ */ React17.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React17.createElement("div", null, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React17.createElement(FiTarget2, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ React17.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Quest"), /* @__PURE__ */ React17.createElement("button", { onClick: handleCopyLink, className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-sky-400"}`, title: isLinkCopied ? "Link Copiado!" : "Copiar link para esta Quest" }, isLinkCopied ? /* @__PURE__ */ React17.createElement(FiCheck11, { size: 12 }) : /* @__PURE__ */ React17.createElement(FiLink6, { size: 12 }))), /* @__PURE__ */ React17.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ React17.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl disabled:opacity-50", title: "Cancelar" }, "\xD7")), /* @__PURE__ */ React17.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ React17.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React17.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ React17.createElement("div", { className: "relative" }, /* @__PURE__ */ React17.createElement(
|
|
8894
|
+
"button",
|
|
8895
|
+
{
|
|
8896
|
+
type: "button",
|
|
8897
|
+
onClick: () => canEdit && setIsStatusDropdownOpen(!isStatusDropdownOpen),
|
|
8898
|
+
disabled: !canEdit,
|
|
8899
|
+
className: `w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 transition-colors flex items-center justify-between ${canEdit ? "hover:border-white/20 focus:ring-2 focus:ring-indigo-400/60 cursor-pointer" : "cursor-default opacity-80"}`
|
|
8900
|
+
},
|
|
8901
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React17.createElement("span", { className: "w-3 h-3 rounded-full shadow-[0_0_8px_rgba(0,0,0,0.5)]", style: { backgroundColor: QUEST_STATUS_COLORS2[status] } }), /* @__PURE__ */ React17.createElement("span", { className: "text-slate-200 font-medium" }, status)),
|
|
8902
|
+
canEdit && /* @__PURE__ */ React17.createElement(FiChevronDown6, { className: `text-slate-400 transition-transform duration-200 ${isStatusDropdownOpen ? "rotate-180" : ""}` })
|
|
8903
|
+
), isStatusDropdownOpen && canEdit && /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsStatusDropdownOpen(false) }), /* @__PURE__ */ React17.createElement("ul", { className: "absolute top-full left-0 mt-1.5 w-full bg-slate-800 border border-white/10 rounded-lg shadow-[0_8px_30px_rgba(0,0,0,0.5)] z-50 overflow-hidden" }, Object.keys(QUEST_STATUS_COLORS2).map((s) => /* @__PURE__ */ React17.createElement(
|
|
8904
|
+
"li",
|
|
8905
|
+
{
|
|
8906
|
+
key: s,
|
|
8907
|
+
onClick: () => {
|
|
8908
|
+
handleStatusChange(s);
|
|
8909
|
+
setIsStatusDropdownOpen(false);
|
|
8910
|
+
},
|
|
8911
|
+
className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${status === s ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
|
|
8912
|
+
},
|
|
8913
|
+
/* @__PURE__ */ React17.createElement("span", { className: "w-3 h-3 rounded-full", style: { backgroundColor: QUEST_STATUS_COLORS2[s] } }),
|
|
8914
|
+
s
|
|
8915
|
+
)))))), /* @__PURE__ */ React17.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React17.createElement("label", { className: "text-xs text-slate-300" }, "Nome"), /* @__PURE__ */ React17.createElement("input", { type: "text", value: name, onChange: handleNameChange, readOnly: !canEdit, className: `w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none ${canEdit ? "focus:ring-2 focus:ring-indigo-400/60" : "cursor-default text-slate-400"}` })), /* @__PURE__ */ React17.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React17.createElement("label", { className: "text-xs text-slate-300" }, "Tipos Adicionais"), /* @__PURE__ */ React17.createElement("div", { className: `relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 ${canEdit ? "focus-within:ring-2 focus-within:ring-indigo-400/60" : ""} transition-all` }, types.map((t, index) => /* @__PURE__ */ React17.createElement("span", { key: index, className: `flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-medium border ${t === "quest" ? "bg-sky-500/20 text-sky-200 border-sky-500/30" : "bg-indigo-500/30 text-indigo-100 border-indigo-500/20"}` }, t, canEdit && t !== "quest" && /* @__PURE__ */ React17.createElement("button", { type: "button", onClick: () => handleRemoveType(index), className: "hover:text-white transition-colors" }, /* @__PURE__ */ React17.createElement(FiX6, { size: 12 })))), canEdit && /* @__PURE__ */ React17.createElement("input", { type: "text", value: typeInput, onChange: (e) => {
|
|
8916
|
+
setTypeInput(e.target.value);
|
|
8917
|
+
setShowTypeSuggestions(true);
|
|
8918
|
+
}, onKeyDown: handleTypeInputKeyDown, onClick: () => setShowTypeSuggestions(true), onBlur: () => {
|
|
8919
|
+
if (typeInput.trim()) {
|
|
8920
|
+
handleAddType(typeInput);
|
|
8921
|
+
}
|
|
8922
|
+
setTimeout(() => setShowTypeSuggestions(false), 150);
|
|
8923
|
+
}, className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200", placeholder: types.length === 1 ? "Ex.: Client" : "", autoComplete: "off" }), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */ React17.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-10 w-full mt-1 max-h-40 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, filteredTypes.map((suggestedType, index) => /* @__PURE__ */ React17.createElement("li", { key: index, className: "px-3 py-2 text-sm text-slate-200 cursor-pointer hover:bg-indigo-600/50", onMouseDown: (e) => {
|
|
8924
|
+
e.preventDefault();
|
|
8925
|
+
handleAddType(suggestedType);
|
|
8926
|
+
} }, suggestedType))))), /* @__PURE__ */ React17.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React17.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React17.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React17.createElement(DescriptionDisplay, { description, savedSections: existingSections, availableNodes, availableAncestries, onOpenReference, onMentionClick, onImageClick: handleImageClickFromText, onSaveDescription: handleSaveDescriptionInline }), /* @__PURE__ */ React17.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React17.createElement("button", { type: "button", onClick: () => setIsReadMode(true), className: `p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors ${canEdit ? "border-r border-white/5" : ""}`, title: "Modo de Leitura" }, /* @__PURE__ */ React17.createElement(FiBookOpen4, { size: 14 })), canEdit && /* @__PURE__ */ React17.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors", title: "Editar descri\xE7\xE3o (Modo de Escrita)" }, /* @__PURE__ */ React17.createElement(FiEdit28, { size: 14 }))), canEdit && !description && /* @__PURE__ */ React17.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ React17.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React17.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
|
|
8927
|
+
const isSelected = size === s;
|
|
8928
|
+
return /* @__PURE__ */ React17.createElement("button", { key: s, type: "button", onClick: () => canEdit && handleSizeChange(s), className: `flex items-center gap-2 group focus:outline-none ${canEdit ? "cursor-pointer" : "cursor-default opacity-80"}` }, /* @__PURE__ */ React17.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${isSelected ? "bg-indigo-500 border-indigo-500 shadow-[0_0_10px_rgba(99,102,241,0.4)]" : "border-slate-600 bg-transparent " + (canEdit ? "group-hover:border-slate-500" : "")}` }, isSelected && /* @__PURE__ */ React17.createElement(FiCheck11, { size: 12, className: "text-white" })), /* @__PURE__ */ React17.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s));
|
|
8929
|
+
}))), /* @__PURE__ */ React17.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React17.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ React17.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React17.createElement(FiPlus7, { size: 14 }), " Adicionar")), /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ React17.createElement(CustomPropertyDisplay, { key: prop.id, prop, onUpdate: canEdit ? (updatedProp) => handleUpdateProp(idx, updatedProp) : void 0, onRemove: canEdit ? () => handleRemoveProp(idx) : void 0, onOpenImageViewer, unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type), isTextureMode: false, onUploadFile: canEdit ? onUploadFile : void 0, readOnly: !canEdit })), /* @__PURE__ */ React17.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ React17.createElement("div", { className: "pt-3 mt-4 border-t border-white/10 flex items-center justify-end gap-2 text-xs text-slate-400" }, /* @__PURE__ */ React17.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ React17.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ React17.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ React17.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ React17.createElement("button", { onClick: () => handleSave(false), disabled: isSaving, className: `px-4 py-2 rounded-lg transition-all font-semibold text-sm shadow-[0_8px_24px_rgba(99,102,241,0.35)] flex items-center gap-2 ${isSaving ? "bg-slate-700 text-slate-300 cursor-wait" : "bg-gradient-to-tr from-indigo-600 to-indigo-400 hover:from-indigo-500 hover:to-indigo-300 text-white"}` }, isSaving && /* @__PURE__ */ React17.createElement(FiLoader3, { className: "animate-spin" }), isSaving ? "Salvando..." : "Salvar Quest")))
|
|
8930
|
+
), isDescriptionModalOpen && canEdit && /* @__PURE__ */ React17.createElement(
|
|
8931
|
+
DescriptionEditModal,
|
|
8932
|
+
{
|
|
8933
|
+
isOpen: isDescriptionModalOpen,
|
|
8934
|
+
title: "Editar Descri\xE7\xE3o da Quest",
|
|
8935
|
+
initialValue: description,
|
|
8936
|
+
onSave: (newDescription) => {
|
|
8937
|
+
setDescription(newDescription);
|
|
8938
|
+
onDataUpdate((prev) => ({ ...prev, description: newDescription }));
|
|
8939
|
+
triggerAutoSave({ description: newDescription });
|
|
8940
|
+
},
|
|
8941
|
+
onClose: () => setIsDescriptionModalOpen(false),
|
|
8942
|
+
availableNodes,
|
|
8943
|
+
availableAncestries,
|
|
8944
|
+
availableImages
|
|
8945
|
+
}
|
|
8946
|
+
));
|
|
8947
|
+
}
|
|
8948
|
+
|
|
8644
8949
|
// src/components/MultiNodeContextMenu.jsx
|
|
8645
|
-
import
|
|
8950
|
+
import React18, { useLayoutEffect as useLayoutEffect3, useRef as useRef15, useState as useState19, useEffect as useEffect17 } from "react";
|
|
8646
8951
|
function MultiNodeContextMenu({
|
|
8647
8952
|
data,
|
|
8648
8953
|
userRole,
|
|
@@ -8651,9 +8956,9 @@ function MultiNodeContextMenu({
|
|
|
8651
8956
|
onDismissOtherNodes,
|
|
8652
8957
|
onDeleteNodes
|
|
8653
8958
|
}) {
|
|
8654
|
-
const menuRef =
|
|
8655
|
-
const [menuPos, setMenuPos] =
|
|
8656
|
-
const [isConfirmingDelete, setIsConfirmingDelete] =
|
|
8959
|
+
const menuRef = useRef15(null);
|
|
8960
|
+
const [menuPos, setMenuPos] = useState19({ left: 0, top: 0 });
|
|
8961
|
+
const [isConfirmingDelete, setIsConfirmingDelete] = useState19(false);
|
|
8657
8962
|
const ability = defineAbilityFor(userRole);
|
|
8658
8963
|
const canDelete = ability.can("delete", "Node");
|
|
8659
8964
|
useLayoutEffect3(() => {
|
|
@@ -8669,7 +8974,7 @@ function MultiNodeContextMenu({
|
|
|
8669
8974
|
if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
|
|
8670
8975
|
setMenuPos({ left, top });
|
|
8671
8976
|
}, [data]);
|
|
8672
|
-
|
|
8977
|
+
useEffect17(() => {
|
|
8673
8978
|
if (data.visible) {
|
|
8674
8979
|
setIsConfirmingDelete(false);
|
|
8675
8980
|
}
|
|
@@ -8684,7 +8989,7 @@ function MultiNodeContextMenu({
|
|
|
8684
8989
|
const baseButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-indigo-500/20 text-slate-200 hover:text-white transition-colors duration-150 truncate";
|
|
8685
8990
|
const deleteButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-red-500/25 text-red-400 hover:text-red-300 transition-colors duration-150 truncate";
|
|
8686
8991
|
const nodeCount = data.nodeIds.size;
|
|
8687
|
-
return /* @__PURE__ */
|
|
8992
|
+
return /* @__PURE__ */ React18.createElement(
|
|
8688
8993
|
"div",
|
|
8689
8994
|
{
|
|
8690
8995
|
ref: menuRef,
|
|
@@ -8698,28 +9003,28 @@ function MultiNodeContextMenu({
|
|
|
8698
9003
|
onContextMenu: swallow,
|
|
8699
9004
|
onDoubleClick: swallow
|
|
8700
9005
|
},
|
|
8701
|
-
/* @__PURE__ */
|
|
8702
|
-
/* @__PURE__ */
|
|
9006
|
+
/* @__PURE__ */ React18.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
|
|
9007
|
+
/* @__PURE__ */ React18.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React18.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ React18.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React18.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React18.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ React18.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ React18.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ React18.createElement("p", { className: "text-[11px] text-slate-400 leading-tight" }, "Esta a\xE7\xE3o \xE9 irrevers\xEDvel. Todas as conex\xF5es associadas a eles ser\xE3o apagadas.")), /* @__PURE__ */ React18.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React18.createElement(
|
|
8703
9008
|
"button",
|
|
8704
9009
|
{
|
|
8705
9010
|
onClick: () => setIsConfirmingDelete(false),
|
|
8706
9011
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
|
|
8707
9012
|
},
|
|
8708
9013
|
"Cancelar"
|
|
8709
|
-
), /* @__PURE__ */
|
|
9014
|
+
), /* @__PURE__ */ React18.createElement(
|
|
8710
9015
|
"button",
|
|
8711
9016
|
{
|
|
8712
9017
|
onClick: () => onDeleteNodes(data.nodeIds),
|
|
8713
9018
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
|
|
8714
9019
|
},
|
|
8715
9020
|
"Excluir"
|
|
8716
|
-
))) : /* @__PURE__ */
|
|
9021
|
+
))) : /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React18.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ React18.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React18.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ React18.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React18.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ React18.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ React18.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ React18.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ React18.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ React18.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ React18.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React18.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ React18.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ React18.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React18.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ React18.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ React18.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React18.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ React18.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React18.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React18.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React18.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ React18.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ React18.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
|
|
8717
9022
|
);
|
|
8718
9023
|
}
|
|
8719
9024
|
|
|
8720
9025
|
// src/components/RelationshipDetailsPanel.jsx
|
|
8721
|
-
import
|
|
8722
|
-
import { FiPlus as
|
|
9026
|
+
import React19, { useState as useState20, useEffect as useEffect18, useRef as useRef16, useMemo as useMemo9 } from "react";
|
|
9027
|
+
import { FiPlus as FiPlus8, FiEdit2 as FiEdit29, FiLoader as FiLoader4, FiBookOpen as FiBookOpen5 } from "react-icons/fi";
|
|
8723
9028
|
function RelationshipDetailsPanel({
|
|
8724
9029
|
link,
|
|
8725
9030
|
onClose,
|
|
@@ -8733,19 +9038,19 @@ function RelationshipDetailsPanel({
|
|
|
8733
9038
|
onUploadFile,
|
|
8734
9039
|
userRole
|
|
8735
9040
|
}) {
|
|
8736
|
-
const [name, setName] =
|
|
8737
|
-
const [description, setDescription] =
|
|
8738
|
-
const [customProps, setCustomProps] =
|
|
8739
|
-
const [existingSections, setExistingSections] =
|
|
8740
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] =
|
|
8741
|
-
const [isSaving, setIsSaving] =
|
|
8742
|
-
const [isReadMode, setIsReadMode] =
|
|
8743
|
-
const propsEndRef =
|
|
9041
|
+
const [name, setName] = useState20((link == null ? void 0 : link.name) ?? "");
|
|
9042
|
+
const [description, setDescription] = useState20((link == null ? void 0 : link.description) ?? "");
|
|
9043
|
+
const [customProps, setCustomProps] = useState20(() => extractCustomPropsFromNode(link || {}));
|
|
9044
|
+
const [existingSections, setExistingSections] = useState20((link == null ? void 0 : link.description_sections) || []);
|
|
9045
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState20(false);
|
|
9046
|
+
const [isSaving, setIsSaving] = useState20(false);
|
|
9047
|
+
const [isReadMode, setIsReadMode] = useState20(false);
|
|
9048
|
+
const propsEndRef = useRef16(null);
|
|
8744
9049
|
const canEdit = useMemo9(() => {
|
|
8745
9050
|
const ability = defineAbilityFor(userRole);
|
|
8746
9051
|
return ability.can("update", "Connection");
|
|
8747
9052
|
}, [userRole]);
|
|
8748
|
-
|
|
9053
|
+
useEffect18(() => {
|
|
8749
9054
|
setName((link == null ? void 0 : link.name) ?? "");
|
|
8750
9055
|
setDescription((link == null ? void 0 : link.description) ?? "");
|
|
8751
9056
|
setExistingSections((link == null ? void 0 : link.description_sections) || []);
|
|
@@ -8820,7 +9125,7 @@ function RelationshipDetailsPanel({
|
|
|
8820
9125
|
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
8821
9126
|
}
|
|
8822
9127
|
};
|
|
8823
|
-
return /* @__PURE__ */
|
|
9128
|
+
return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(
|
|
8824
9129
|
"div",
|
|
8825
9130
|
{
|
|
8826
9131
|
className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden transition-all duration-300 ease-out
|
|
@@ -8835,7 +9140,7 @@ function RelationshipDetailsPanel({
|
|
|
8835
9140
|
onContextMenu: swallow,
|
|
8836
9141
|
onDoubleClick: swallow
|
|
8837
9142
|
},
|
|
8838
|
-
isReadMode ? /* @__PURE__ */
|
|
9143
|
+
isReadMode ? /* @__PURE__ */ React19.createElement(
|
|
8839
9144
|
DescriptionReadModePanel,
|
|
8840
9145
|
{
|
|
8841
9146
|
title: name || "Rela\xE7\xE3o",
|
|
@@ -8856,7 +9161,7 @@ function RelationshipDetailsPanel({
|
|
|
8856
9161
|
onImageClick: handleImageClickFromText,
|
|
8857
9162
|
onSaveDescription: handleSaveDescriptionInline
|
|
8858
9163
|
}
|
|
8859
|
-
) : /* @__PURE__ */
|
|
9164
|
+
) : /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ React19.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React19.createElement("div", null, /* @__PURE__ */ React19.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React19.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-teal-400/80 shadow-[0_0_18px_2px_rgba(45,212,191,0.55)]" }), /* @__PURE__ */ React19.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ React19.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ React19.createElement("button", { onClick: onClose, disabled: isSaving, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl disabled:opacity-50", title: "Fechar" }, "\xD7")), /* @__PURE__ */ React19.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ React19.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React19.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ React19.createElement(
|
|
8860
9165
|
"input",
|
|
8861
9166
|
{
|
|
8862
9167
|
type: "text",
|
|
@@ -8868,7 +9173,7 @@ function RelationshipDetailsPanel({
|
|
|
8868
9173
|
${!canEdit ? "opacity-50 cursor-not-allowed" : ""}
|
|
8869
9174
|
`
|
|
8870
9175
|
}
|
|
8871
|
-
)), /* @__PURE__ */
|
|
9176
|
+
)), /* @__PURE__ */ React19.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React19.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React19.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React19.createElement(
|
|
8872
9177
|
DescriptionDisplay,
|
|
8873
9178
|
{
|
|
8874
9179
|
description,
|
|
@@ -8880,7 +9185,7 @@ function RelationshipDetailsPanel({
|
|
|
8880
9185
|
onImageClick: handleImageClickFromText,
|
|
8881
9186
|
onSaveDescription: handleSaveDescriptionInline
|
|
8882
9187
|
}
|
|
8883
|
-
), /* @__PURE__ */
|
|
9188
|
+
), /* @__PURE__ */ React19.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React19.createElement(
|
|
8884
9189
|
"button",
|
|
8885
9190
|
{
|
|
8886
9191
|
type: "button",
|
|
@@ -8888,8 +9193,8 @@ function RelationshipDetailsPanel({
|
|
|
8888
9193
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors border-r border-white/5",
|
|
8889
9194
|
title: "Modo de Leitura"
|
|
8890
9195
|
},
|
|
8891
|
-
/* @__PURE__ */
|
|
8892
|
-
), canEdit && /* @__PURE__ */
|
|
9196
|
+
/* @__PURE__ */ React19.createElement(FiBookOpen5, { size: 14 })
|
|
9197
|
+
), canEdit && /* @__PURE__ */ React19.createElement(
|
|
8893
9198
|
"button",
|
|
8894
9199
|
{
|
|
8895
9200
|
type: "button",
|
|
@@ -8897,15 +9202,15 @@ function RelationshipDetailsPanel({
|
|
|
8897
9202
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8898
9203
|
title: "Editar descri\xE7\xE3o"
|
|
8899
9204
|
},
|
|
8900
|
-
/* @__PURE__ */
|
|
8901
|
-
)), !description && canEdit && /* @__PURE__ */
|
|
9205
|
+
/* @__PURE__ */ React19.createElement(FiEdit29, { size: 14 })
|
|
9206
|
+
)), !description && canEdit && /* @__PURE__ */ React19.createElement(
|
|
8902
9207
|
"div",
|
|
8903
9208
|
{
|
|
8904
9209
|
onClick: () => setIsDescriptionModalOpen(true),
|
|
8905
9210
|
className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
|
|
8906
9211
|
},
|
|
8907
9212
|
"Adicionar descri\xE7\xE3o..."
|
|
8908
|
-
))), /* @__PURE__ */
|
|
9213
|
+
))), /* @__PURE__ */ React19.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React19.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React19.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ React19.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React19.createElement(FiPlus8, { size: 14 }), " Adicionar")), /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ React19.createElement(
|
|
8909
9214
|
CustomPropertyDisplay,
|
|
8910
9215
|
{
|
|
8911
9216
|
key: prop.id,
|
|
@@ -8917,7 +9222,7 @@ function RelationshipDetailsPanel({
|
|
|
8917
9222
|
onUploadFile,
|
|
8918
9223
|
disabled: !canEdit
|
|
8919
9224
|
}
|
|
8920
|
-
)), /* @__PURE__ */
|
|
9225
|
+
)), /* @__PURE__ */ React19.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ React19.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ React19.createElement("button", { onClick: onClose, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ React19.createElement(
|
|
8921
9226
|
"button",
|
|
8922
9227
|
{
|
|
8923
9228
|
onClick: () => handleSave(false),
|
|
@@ -8926,10 +9231,10 @@ function RelationshipDetailsPanel({
|
|
|
8926
9231
|
${isSaving ? "bg-slate-700 text-slate-300 cursor-wait" : "bg-gradient-to-tr from-teal-600 to-teal-400 hover:from-teal-500 hover:to-teal-300 text-white"}
|
|
8927
9232
|
`
|
|
8928
9233
|
},
|
|
8929
|
-
isSaving && /* @__PURE__ */
|
|
9234
|
+
isSaving && /* @__PURE__ */ React19.createElement(FiLoader4, { className: "animate-spin" }),
|
|
8930
9235
|
isSaving ? "Salvando..." : "Salvar"
|
|
8931
9236
|
)))
|
|
8932
|
-
), isDescriptionModalOpen && /* @__PURE__ */
|
|
9237
|
+
), isDescriptionModalOpen && /* @__PURE__ */ React19.createElement(
|
|
8933
9238
|
DescriptionEditModal,
|
|
8934
9239
|
{
|
|
8935
9240
|
isOpen: isDescriptionModalOpen,
|
|
@@ -8950,7 +9255,7 @@ function RelationshipDetailsPanel({
|
|
|
8950
9255
|
}
|
|
8951
9256
|
|
|
8952
9257
|
// src/components/RelationshipContextMenu.jsx
|
|
8953
|
-
import
|
|
9258
|
+
import React20, { useLayoutEffect as useLayoutEffect4, useRef as useRef17, useState as useState21, useEffect as useEffect19, useMemo as useMemo10 } from "react";
|
|
8954
9259
|
function RelationshipContextMenu({
|
|
8955
9260
|
data,
|
|
8956
9261
|
userRole,
|
|
@@ -8960,9 +9265,9 @@ function RelationshipContextMenu({
|
|
|
8960
9265
|
onDelete,
|
|
8961
9266
|
onClose
|
|
8962
9267
|
}) {
|
|
8963
|
-
const menuRef =
|
|
8964
|
-
const [menuPos, setMenuPos] =
|
|
8965
|
-
const [isConfirmingDelete, setIsConfirmingDelete] =
|
|
9268
|
+
const menuRef = useRef17(null);
|
|
9269
|
+
const [menuPos, setMenuPos] = useState21({ left: 0, top: 0 });
|
|
9270
|
+
const [isConfirmingDelete, setIsConfirmingDelete] = useState21(false);
|
|
8966
9271
|
const ability = useMemo10(() => defineAbilityFor(userRole), [userRole]);
|
|
8967
9272
|
const sourceName = useMemo10(
|
|
8968
9273
|
() => {
|
|
@@ -8991,7 +9296,7 @@ function RelationshipContextMenu({
|
|
|
8991
9296
|
if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
|
|
8992
9297
|
setMenuPos({ left, top });
|
|
8993
9298
|
}, [data]);
|
|
8994
|
-
|
|
9299
|
+
useEffect19(() => {
|
|
8995
9300
|
if (data.visible) {
|
|
8996
9301
|
setIsConfirmingDelete(false);
|
|
8997
9302
|
}
|
|
@@ -9007,7 +9312,7 @@ function RelationshipContextMenu({
|
|
|
9007
9312
|
const dangerButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-rose-500/20 text-rose-300 hover:text-rose-100 transition-colors duration-150 truncate";
|
|
9008
9313
|
const canUpdate = ability.can("update", "Connection");
|
|
9009
9314
|
const canDelete = ability.can("delete", "Connection");
|
|
9010
|
-
return /* @__PURE__ */
|
|
9315
|
+
return /* @__PURE__ */ React20.createElement(
|
|
9011
9316
|
"div",
|
|
9012
9317
|
{
|
|
9013
9318
|
ref: menuRef,
|
|
@@ -9021,29 +9326,29 @@ function RelationshipContextMenu({
|
|
|
9021
9326
|
onContextMenu: swallow,
|
|
9022
9327
|
onDoubleClick: swallow
|
|
9023
9328
|
},
|
|
9024
|
-
/* @__PURE__ */
|
|
9025
|
-
/* @__PURE__ */
|
|
9329
|
+
/* @__PURE__ */ React20.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
|
|
9330
|
+
/* @__PURE__ */ React20.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ React20.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React20.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React20.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ React20.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React20.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React20.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ React20.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ React20.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ React20.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ React20.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ React20.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ React20.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ React20.createElement("strong", null, targetName), ".")), /* @__PURE__ */ React20.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React20.createElement(
|
|
9026
9331
|
"button",
|
|
9027
9332
|
{
|
|
9028
9333
|
onClick: () => setIsConfirmingDelete(false),
|
|
9029
9334
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
|
|
9030
9335
|
},
|
|
9031
9336
|
"Cancelar"
|
|
9032
|
-
), /* @__PURE__ */
|
|
9337
|
+
), /* @__PURE__ */ React20.createElement(
|
|
9033
9338
|
"button",
|
|
9034
9339
|
{
|
|
9035
9340
|
onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
|
|
9036
9341
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-rose-600 hover:bg-rose-500 rounded-md text-white transition-colors"
|
|
9037
9342
|
},
|
|
9038
9343
|
"Excluir"
|
|
9039
|
-
))) : /* @__PURE__ */
|
|
9344
|
+
))) : /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React20.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-teal-400/80 shadow-[0_0_12px_1px_rgba(45,212,191,0.5)]" }), /* @__PURE__ */ React20.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ React20.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(
|
|
9040
9345
|
"button",
|
|
9041
9346
|
{
|
|
9042
9347
|
onClick: () => onRelinkSource == null ? void 0 : onRelinkSource(data.linkObject),
|
|
9043
9348
|
className: baseButtonClass,
|
|
9044
9349
|
title: "Desconectar ponta ligada ao Source"
|
|
9045
9350
|
},
|
|
9046
|
-
/* @__PURE__ */
|
|
9351
|
+
/* @__PURE__ */ React20.createElement(
|
|
9047
9352
|
"svg",
|
|
9048
9353
|
{
|
|
9049
9354
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -9056,18 +9361,18 @@ function RelationshipContextMenu({
|
|
|
9056
9361
|
strokeLinecap: "round",
|
|
9057
9362
|
strokeLinejoin: "round"
|
|
9058
9363
|
},
|
|
9059
|
-
/* @__PURE__ */
|
|
9060
|
-
/* @__PURE__ */
|
|
9364
|
+
/* @__PURE__ */ React20.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }),
|
|
9365
|
+
/* @__PURE__ */ React20.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })
|
|
9061
9366
|
),
|
|
9062
|
-
/* @__PURE__ */
|
|
9063
|
-
), /* @__PURE__ */
|
|
9367
|
+
/* @__PURE__ */ React20.createElement("span", null, "Desconectar Source (", sourceName, ")")
|
|
9368
|
+
), /* @__PURE__ */ React20.createElement(
|
|
9064
9369
|
"button",
|
|
9065
9370
|
{
|
|
9066
9371
|
onClick: () => onRelinkTarget == null ? void 0 : onRelinkTarget(data.linkObject),
|
|
9067
9372
|
className: baseButtonClass,
|
|
9068
9373
|
title: "Desconectar ponta ligada ao Target"
|
|
9069
9374
|
},
|
|
9070
|
-
/* @__PURE__ */
|
|
9375
|
+
/* @__PURE__ */ React20.createElement(
|
|
9071
9376
|
"svg",
|
|
9072
9377
|
{
|
|
9073
9378
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -9080,21 +9385,21 @@ function RelationshipContextMenu({
|
|
|
9080
9385
|
strokeLinecap: "round",
|
|
9081
9386
|
strokeLinejoin: "round"
|
|
9082
9387
|
},
|
|
9083
|
-
/* @__PURE__ */
|
|
9084
|
-
/* @__PURE__ */
|
|
9085
|
-
/* @__PURE__ */
|
|
9086
|
-
/* @__PURE__ */
|
|
9087
|
-
/* @__PURE__ */
|
|
9388
|
+
/* @__PURE__ */ React20.createElement("polyline", { points: "16 3 21 3 21 8" }),
|
|
9389
|
+
/* @__PURE__ */ React20.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
|
|
9390
|
+
/* @__PURE__ */ React20.createElement("polyline", { points: "21 16 21 21 16 21" }),
|
|
9391
|
+
/* @__PURE__ */ React20.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
|
|
9392
|
+
/* @__PURE__ */ React20.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
|
|
9088
9393
|
),
|
|
9089
|
-
/* @__PURE__ */
|
|
9090
|
-
), /* @__PURE__ */
|
|
9394
|
+
/* @__PURE__ */ React20.createElement("span", null, "Desconectar Target (", targetName, ")")
|
|
9395
|
+
), /* @__PURE__ */ React20.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ React20.createElement(
|
|
9091
9396
|
"button",
|
|
9092
9397
|
{
|
|
9093
9398
|
onClick: () => onOpenDetails == null ? void 0 : onOpenDetails(data.linkObject),
|
|
9094
9399
|
className: baseButtonClass,
|
|
9095
9400
|
title: "Abrir detalhes da rela\xE7\xE3o"
|
|
9096
9401
|
},
|
|
9097
|
-
/* @__PURE__ */
|
|
9402
|
+
/* @__PURE__ */ React20.createElement(
|
|
9098
9403
|
"svg",
|
|
9099
9404
|
{
|
|
9100
9405
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -9107,19 +9412,19 @@ function RelationshipContextMenu({
|
|
|
9107
9412
|
strokeLinecap: "round",
|
|
9108
9413
|
strokeLinejoin: "round"
|
|
9109
9414
|
},
|
|
9110
|
-
/* @__PURE__ */
|
|
9111
|
-
/* @__PURE__ */
|
|
9112
|
-
/* @__PURE__ */
|
|
9415
|
+
/* @__PURE__ */ React20.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
9416
|
+
/* @__PURE__ */ React20.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
9417
|
+
/* @__PURE__ */ React20.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
|
|
9113
9418
|
),
|
|
9114
|
-
/* @__PURE__ */
|
|
9115
|
-
), canDelete && /* @__PURE__ */
|
|
9419
|
+
/* @__PURE__ */ React20.createElement("span", null, "Abrir Detalhes")
|
|
9420
|
+
), canDelete && /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ React20.createElement(
|
|
9116
9421
|
"button",
|
|
9117
9422
|
{
|
|
9118
9423
|
onClick: () => setIsConfirmingDelete(true),
|
|
9119
9424
|
className: dangerButtonClass,
|
|
9120
9425
|
title: "Excluir esta conex\xE3o"
|
|
9121
9426
|
},
|
|
9122
|
-
/* @__PURE__ */
|
|
9427
|
+
/* @__PURE__ */ React20.createElement(
|
|
9123
9428
|
"svg",
|
|
9124
9429
|
{
|
|
9125
9430
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -9132,19 +9437,19 @@ function RelationshipContextMenu({
|
|
|
9132
9437
|
strokeLinecap: "round",
|
|
9133
9438
|
strokeLinejoin: "round"
|
|
9134
9439
|
},
|
|
9135
|
-
/* @__PURE__ */
|
|
9136
|
-
/* @__PURE__ */
|
|
9137
|
-
/* @__PURE__ */
|
|
9138
|
-
/* @__PURE__ */
|
|
9139
|
-
/* @__PURE__ */
|
|
9440
|
+
/* @__PURE__ */ React20.createElement("polyline", { points: "3 6 5 6 21 6" }),
|
|
9441
|
+
/* @__PURE__ */ React20.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
|
|
9442
|
+
/* @__PURE__ */ React20.createElement("path", { d: "M10 11v6" }),
|
|
9443
|
+
/* @__PURE__ */ React20.createElement("path", { d: "M14 11v6" }),
|
|
9444
|
+
/* @__PURE__ */ React20.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
|
|
9140
9445
|
),
|
|
9141
|
-
/* @__PURE__ */
|
|
9446
|
+
/* @__PURE__ */ React20.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
|
|
9142
9447
|
)))))
|
|
9143
9448
|
);
|
|
9144
9449
|
}
|
|
9145
9450
|
|
|
9146
9451
|
// src/components/LoadingScreen.jsx
|
|
9147
|
-
import
|
|
9452
|
+
import React21 from "react";
|
|
9148
9453
|
var styles = {
|
|
9149
9454
|
loadingOverlay: {
|
|
9150
9455
|
position: "fixed",
|
|
@@ -9176,11 +9481,11 @@ var styles = {
|
|
|
9176
9481
|
`
|
|
9177
9482
|
};
|
|
9178
9483
|
function LoadingScreen() {
|
|
9179
|
-
return /* @__PURE__ */
|
|
9484
|
+
return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("style", null, styles.keyframes), /* @__PURE__ */ React21.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ React21.createElement("div", { style: styles.spinner })));
|
|
9180
9485
|
}
|
|
9181
9486
|
|
|
9182
9487
|
// src/components/ImportParentFileModal.jsx
|
|
9183
|
-
import
|
|
9488
|
+
import React22, { useEffect as useEffect20, useState as useState22 } from "react";
|
|
9184
9489
|
function ImportParentFileModal({
|
|
9185
9490
|
isOpen,
|
|
9186
9491
|
onClose,
|
|
@@ -9191,12 +9496,12 @@ function ImportParentFileModal({
|
|
|
9191
9496
|
onFetchAvailableFiles,
|
|
9192
9497
|
currentViewName
|
|
9193
9498
|
}) {
|
|
9194
|
-
const [activeTab, setActiveTab] =
|
|
9195
|
-
const [availableDbs, setAvailableDbs] =
|
|
9196
|
-
const [availableViews, setAvailableViews] =
|
|
9197
|
-
const [selectedItem, setSelectedItem] =
|
|
9198
|
-
const [isLoading, setIsLoading] =
|
|
9199
|
-
|
|
9499
|
+
const [activeTab, setActiveTab] = useState22("databases");
|
|
9500
|
+
const [availableDbs, setAvailableDbs] = useState22([]);
|
|
9501
|
+
const [availableViews, setAvailableViews] = useState22([]);
|
|
9502
|
+
const [selectedItem, setSelectedItem] = useState22(null);
|
|
9503
|
+
const [isLoading, setIsLoading] = useState22(false);
|
|
9504
|
+
useEffect20(() => {
|
|
9200
9505
|
if (isOpen && session && onFetchAvailableFiles) {
|
|
9201
9506
|
const fetchData = async () => {
|
|
9202
9507
|
setIsLoading(true);
|
|
@@ -9232,7 +9537,7 @@ function ImportParentFileModal({
|
|
|
9232
9537
|
fetchData();
|
|
9233
9538
|
}
|
|
9234
9539
|
}, [isOpen, session, parentDbs, onFetchAvailableFiles, currentViewName]);
|
|
9235
|
-
|
|
9540
|
+
useEffect20(() => {
|
|
9236
9541
|
setSelectedItem(null);
|
|
9237
9542
|
}, [activeTab]);
|
|
9238
9543
|
if (!isOpen) {
|
|
@@ -9261,13 +9566,13 @@ function ImportParentFileModal({
|
|
|
9261
9566
|
const swallow = (e) => e.stopPropagation();
|
|
9262
9567
|
const currentList = activeTab === "databases" ? availableDbs : availableViews;
|
|
9263
9568
|
const emptyMessage = activeTab === "databases" ? "Nenhum novo arquivo parent dispon\xEDvel." : "Nenhuma view dispon\xEDvel para importa\xE7\xE3o.";
|
|
9264
|
-
return /* @__PURE__ */
|
|
9569
|
+
return /* @__PURE__ */ React22.createElement(
|
|
9265
9570
|
"div",
|
|
9266
9571
|
{
|
|
9267
9572
|
className: "ui-overlay fixed inset-0 z-[1200] flex items-center justify-center bg-black/60 backdrop-blur-sm",
|
|
9268
9573
|
onClick: onClose
|
|
9269
9574
|
},
|
|
9270
|
-
/* @__PURE__ */
|
|
9575
|
+
/* @__PURE__ */ React22.createElement(
|
|
9271
9576
|
"div",
|
|
9272
9577
|
{
|
|
9273
9578
|
className: "ui-overlay relative rounded-2xl border border-white/10 bg-slate-950/80 shadow-[0_20px_80px_rgba(0,0,0,0.6)] text-white w-[min(92vw,500px)] flex flex-col max-h-[85vh]",
|
|
@@ -9279,14 +9584,14 @@ function ImportParentFileModal({
|
|
|
9279
9584
|
onContextMenu: swallow,
|
|
9280
9585
|
onDoubleClick: swallow
|
|
9281
9586
|
},
|
|
9282
|
-
/* @__PURE__ */
|
|
9587
|
+
/* @__PURE__ */ React22.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ React22.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ React22.createElement(
|
|
9283
9588
|
"button",
|
|
9284
9589
|
{
|
|
9285
9590
|
onClick: onClose,
|
|
9286
9591
|
className: "p-2 rounded-md text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
9287
9592
|
title: "Fechar"
|
|
9288
9593
|
},
|
|
9289
|
-
/* @__PURE__ */
|
|
9594
|
+
/* @__PURE__ */ React22.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React22.createElement(
|
|
9290
9595
|
"path",
|
|
9291
9596
|
{
|
|
9292
9597
|
fillRule: "evenodd",
|
|
@@ -9295,14 +9600,14 @@ function ImportParentFileModal({
|
|
|
9295
9600
|
}
|
|
9296
9601
|
))
|
|
9297
9602
|
)),
|
|
9298
|
-
/* @__PURE__ */
|
|
9603
|
+
/* @__PURE__ */ React22.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ React22.createElement(
|
|
9299
9604
|
"button",
|
|
9300
9605
|
{
|
|
9301
9606
|
onClick: () => setActiveTab("databases"),
|
|
9302
9607
|
className: `flex-1 py-3 text-sm font-medium border-b-2 transition-colors ${activeTab === "databases" ? "border-indigo-500 text-white" : "border-transparent text-slate-400 hover:text-slate-200"}`
|
|
9303
9608
|
},
|
|
9304
9609
|
"Arquivos Parent"
|
|
9305
|
-
), /* @__PURE__ */
|
|
9610
|
+
), /* @__PURE__ */ React22.createElement(
|
|
9306
9611
|
"button",
|
|
9307
9612
|
{
|
|
9308
9613
|
onClick: () => setActiveTab("views"),
|
|
@@ -9310,24 +9615,24 @@ function ImportParentFileModal({
|
|
|
9310
9615
|
},
|
|
9311
9616
|
"Views (Ancestralidades)"
|
|
9312
9617
|
)),
|
|
9313
|
-
/* @__PURE__ */
|
|
9618
|
+
/* @__PURE__ */ React22.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ React22.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ React22.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ React22.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ React22.createElement(
|
|
9314
9619
|
"div",
|
|
9315
9620
|
{
|
|
9316
9621
|
key: item.id,
|
|
9317
9622
|
onClick: () => setSelectedItem(item),
|
|
9318
9623
|
className: `px-4 py-3 rounded-lg border cursor-pointer transition-all duration-150 flex flex-col gap-1 ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "bg-indigo-600 border-indigo-500 shadow-lg" : "bg-slate-800/60 border-white/10 hover:border-white/20 hover:bg-slate-800"}`
|
|
9319
9624
|
},
|
|
9320
|
-
/* @__PURE__ */
|
|
9321
|
-
item.description && /* @__PURE__ */
|
|
9322
|
-
)) : /* @__PURE__ */
|
|
9323
|
-
/* @__PURE__ */
|
|
9625
|
+
/* @__PURE__ */ React22.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React22.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ React22.createElement("span", { className: "text-[10px] px-1.5 py-0.5 rounded bg-black/30 text-indigo-300 border border-indigo-500/30" }, "VIEW")),
|
|
9626
|
+
item.description && /* @__PURE__ */ React22.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
|
|
9627
|
+
)) : /* @__PURE__ */ React22.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
|
|
9628
|
+
/* @__PURE__ */ React22.createElement("div", { className: "px-6 py-4 border-t border-white/10 flex justify-end gap-3 flex-shrink-0 bg-slate-900/50" }, /* @__PURE__ */ React22.createElement(
|
|
9324
9629
|
"button",
|
|
9325
9630
|
{
|
|
9326
9631
|
onClick: onClose,
|
|
9327
9632
|
className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm text-slate-300"
|
|
9328
9633
|
},
|
|
9329
9634
|
"Cancelar"
|
|
9330
|
-
), /* @__PURE__ */
|
|
9635
|
+
), /* @__PURE__ */ React22.createElement(
|
|
9331
9636
|
"button",
|
|
9332
9637
|
{
|
|
9333
9638
|
onClick: handleConfirm,
|
|
@@ -9341,8 +9646,8 @@ function ImportParentFileModal({
|
|
|
9341
9646
|
}
|
|
9342
9647
|
|
|
9343
9648
|
// src/components/AncestryLinkDetailsPanel.jsx
|
|
9344
|
-
import
|
|
9345
|
-
import { FiBookOpen as
|
|
9649
|
+
import React23, { useState as useState23 } from "react";
|
|
9650
|
+
import { FiBookOpen as FiBookOpen6 } from "react-icons/fi";
|
|
9346
9651
|
function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
|
|
9347
9652
|
var _a, _b, _c, _d;
|
|
9348
9653
|
const relationshipData = data.relationship || {};
|
|
@@ -9351,21 +9656,21 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9351
9656
|
const customProps = extractCustomPropsFromNode(relationshipData);
|
|
9352
9657
|
const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
|
|
9353
9658
|
const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
|
|
9354
|
-
const [isReadMode, setIsReadMode] =
|
|
9659
|
+
const [isReadMode, setIsReadMode] = useState23(false);
|
|
9355
9660
|
const swallow = (e) => e.stopPropagation();
|
|
9356
9661
|
const handleImageClickFromText = (url, name) => {
|
|
9357
9662
|
if (onOpenImageViewer) {
|
|
9358
9663
|
onOpenImageViewer([{ name: name || "Imagem", value: url }], 0);
|
|
9359
9664
|
}
|
|
9360
9665
|
};
|
|
9361
|
-
return /* @__PURE__ */
|
|
9666
|
+
return /* @__PURE__ */ React23.createElement(
|
|
9362
9667
|
"div",
|
|
9363
9668
|
{
|
|
9364
9669
|
className: "ui-overlay fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[1200]",
|
|
9365
9670
|
onClick: onClose,
|
|
9366
9671
|
onPointerDown: swallow
|
|
9367
9672
|
},
|
|
9368
|
-
/* @__PURE__ */
|
|
9673
|
+
/* @__PURE__ */ React23.createElement(
|
|
9369
9674
|
"div",
|
|
9370
9675
|
{
|
|
9371
9676
|
className: `relative group rounded-2xl border border-white/10 bg-slate-950/80 shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col max-h-[calc(100vh-4rem)] transition-all duration-300 ease-out
|
|
@@ -9373,7 +9678,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9373
9678
|
`,
|
|
9374
9679
|
onClick: swallow
|
|
9375
9680
|
},
|
|
9376
|
-
isReadMode ? /* @__PURE__ */
|
|
9681
|
+
isReadMode ? /* @__PURE__ */ React23.createElement(
|
|
9377
9682
|
DescriptionReadModePanel,
|
|
9378
9683
|
{
|
|
9379
9684
|
title: `${sourceName} \u2794 ${targetName}`,
|
|
@@ -9385,15 +9690,15 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9385
9690
|
onMentionClick,
|
|
9386
9691
|
onImageClick: handleImageClickFromText
|
|
9387
9692
|
}
|
|
9388
|
-
) : /* @__PURE__ */
|
|
9693
|
+
) : /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ React23.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React23.createElement("div", null, /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React23.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-blue-500/80 shadow-[0_0_18px_2px_rgba(59,130,246,0.55)]" }), /* @__PURE__ */ React23.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ React23.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ React23.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ React23.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ React23.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ React23.createElement("button", { onClick: onClose, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl", title: "Fechar" }, "\xD7")), /* @__PURE__ */ React23.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ React23.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React23.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React23.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React23.createElement(
|
|
9389
9694
|
"button",
|
|
9390
9695
|
{
|
|
9391
9696
|
onClick: () => setIsReadMode(true),
|
|
9392
9697
|
className: "p-1 text-slate-400 hover:text-white transition-colors",
|
|
9393
9698
|
title: "Modo de Leitura"
|
|
9394
9699
|
},
|
|
9395
|
-
/* @__PURE__ */
|
|
9396
|
-
)), /* @__PURE__ */
|
|
9700
|
+
/* @__PURE__ */ React23.createElement(FiBookOpen6, { size: 14 })
|
|
9701
|
+
)), /* @__PURE__ */ React23.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ React23.createElement(
|
|
9397
9702
|
DescriptionDisplay,
|
|
9398
9703
|
{
|
|
9399
9704
|
description,
|
|
@@ -9402,7 +9707,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9402
9707
|
onMentionClick,
|
|
9403
9708
|
onImageClick: handleImageClickFromText
|
|
9404
9709
|
}
|
|
9405
|
-
))), customProps.length > 0 && /* @__PURE__ */
|
|
9710
|
+
))), customProps.length > 0 && /* @__PURE__ */ React23.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React23.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ React23.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ React23.createElement(
|
|
9406
9711
|
CustomPropertyDisplay,
|
|
9407
9712
|
{
|
|
9408
9713
|
key: prop.id,
|
|
@@ -9411,25 +9716,25 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9411
9716
|
onOpenImageViewer,
|
|
9412
9717
|
onUploadFile
|
|
9413
9718
|
}
|
|
9414
|
-
)))), !description && customProps.length === 0 && /* @__PURE__ */
|
|
9719
|
+
)))), !description && customProps.length === 0 && /* @__PURE__ */ React23.createElement("div", { className: "py-8 text-center text-slate-500 text-sm italic border border-dashed border-white/10 rounded-lg" }, "Nenhum detalhe adicional dispon\xEDvel para esta conex\xE3o."), /* @__PURE__ */ React23.createElement("div", { className: "mt-4 p-3 bg-blue-500/10 border border-blue-500/20 rounded-lg text-xs text-blue-200/80 text-center" }, 'Para editar esta conex\xE3o, utilize o menu "Editar Ancestralidade".')))
|
|
9415
9720
|
)
|
|
9416
9721
|
);
|
|
9417
9722
|
}
|
|
9418
9723
|
|
|
9419
9724
|
// src/components/AncestryBoard.jsx
|
|
9420
|
-
import
|
|
9725
|
+
import React24, { useState as useState24, useMemo as useMemo11, useEffect as useEffect21, useRef as useRef18 } from "react";
|
|
9421
9726
|
import {
|
|
9422
9727
|
FiSearch as FiSearch4,
|
|
9423
9728
|
FiLayers as FiLayers6,
|
|
9424
9729
|
FiCornerUpRight as FiCornerUpRight4,
|
|
9425
9730
|
FiPlay,
|
|
9426
|
-
FiPlus as
|
|
9731
|
+
FiPlus as FiPlus9,
|
|
9427
9732
|
FiTrash2 as FiTrash23,
|
|
9428
9733
|
FiArrowLeft as FiArrowLeft3,
|
|
9429
9734
|
FiArrowRight,
|
|
9430
9735
|
FiCheckCircle,
|
|
9431
|
-
FiLoader as
|
|
9432
|
-
FiX as
|
|
9736
|
+
FiLoader as FiLoader5,
|
|
9737
|
+
FiX as FiX7,
|
|
9433
9738
|
FiAlertTriangle
|
|
9434
9739
|
} from "react-icons/fi";
|
|
9435
9740
|
var GroupItem = ({
|
|
@@ -9451,7 +9756,7 @@ var GroupItem = ({
|
|
|
9451
9756
|
}) => {
|
|
9452
9757
|
const canIndent = index > 0;
|
|
9453
9758
|
const isPickingForThisGroup = pickingGroupId === group.id;
|
|
9454
|
-
const textareaRef =
|
|
9759
|
+
const textareaRef = useRef18(null);
|
|
9455
9760
|
const adjustHeight = () => {
|
|
9456
9761
|
const textarea = textareaRef.current;
|
|
9457
9762
|
if (textarea) {
|
|
@@ -9459,13 +9764,13 @@ var GroupItem = ({
|
|
|
9459
9764
|
textarea.style.height = `${textarea.scrollHeight}px`;
|
|
9460
9765
|
}
|
|
9461
9766
|
};
|
|
9462
|
-
|
|
9767
|
+
useEffect21(() => {
|
|
9463
9768
|
adjustHeight();
|
|
9464
9769
|
}, [group.text]);
|
|
9465
|
-
return /* @__PURE__ */
|
|
9770
|
+
return /* @__PURE__ */ React24.createElement("div", { className: "flex flex-col gap-2 mb-3 pl-3 border-l border-white/10 relative group/item animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React24.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ React24.createElement("div", { className: `
|
|
9466
9771
|
flex flex-col gap-2 py-2 px-3 transition-all duration-200
|
|
9467
9772
|
${isPickingForThisGroup ? "bg-indigo-500/10 border-l-2 border-indigo-500" : "hover:bg-white/5 border-l-2 border-transparent hover:border-white/20"}
|
|
9468
|
-
` }, /* @__PURE__ */
|
|
9773
|
+
` }, /* @__PURE__ */ React24.createElement(
|
|
9469
9774
|
"textarea",
|
|
9470
9775
|
{
|
|
9471
9776
|
ref: textareaRef,
|
|
@@ -9482,9 +9787,9 @@ var GroupItem = ({
|
|
|
9482
9787
|
if (canEdit) onUpdate(group.id, { ...group, text: e.target.value });
|
|
9483
9788
|
}
|
|
9484
9789
|
}
|
|
9485
|
-
), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */
|
|
9790
|
+
), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ React24.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
|
|
9486
9791
|
const isValid = availableIds.has(String(anc.ancestry_id));
|
|
9487
|
-
return /* @__PURE__ */
|
|
9792
|
+
return /* @__PURE__ */ React24.createElement(
|
|
9488
9793
|
"div",
|
|
9489
9794
|
{
|
|
9490
9795
|
key: anc.ancestry_id,
|
|
@@ -9496,28 +9801,28 @@ var GroupItem = ({
|
|
|
9496
9801
|
},
|
|
9497
9802
|
isValid ? (
|
|
9498
9803
|
// [MANTIDO] Botão Play visível para todos
|
|
9499
|
-
/* @__PURE__ */
|
|
9804
|
+
/* @__PURE__ */ React24.createElement(
|
|
9500
9805
|
"button",
|
|
9501
9806
|
{
|
|
9502
9807
|
onClick: () => onPlayAncestry(anc.ancestry_id),
|
|
9503
9808
|
className: "text-indigo-400 hover:text-white hover:bg-indigo-500 p-1 rounded-full transition-colors",
|
|
9504
9809
|
title: "Renderizar no cen\xE1rio"
|
|
9505
9810
|
},
|
|
9506
|
-
/* @__PURE__ */
|
|
9811
|
+
/* @__PURE__ */ React24.createElement(FiPlay, { size: 10, className: "ml-0.5 fill-current" })
|
|
9507
9812
|
)
|
|
9508
|
-
) : /* @__PURE__ */
|
|
9509
|
-
/* @__PURE__ */
|
|
9510
|
-
canEdit && /* @__PURE__ */
|
|
9813
|
+
) : /* @__PURE__ */ React24.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ React24.createElement(FiAlertTriangle, { size: 10 })),
|
|
9814
|
+
/* @__PURE__ */ React24.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
|
|
9815
|
+
canEdit && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ React24.createElement(
|
|
9511
9816
|
"button",
|
|
9512
9817
|
{
|
|
9513
9818
|
onClick: () => onRemoveAncestry(group.id, anc.ancestry_id),
|
|
9514
9819
|
className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
|
|
9515
9820
|
title: "Remover men\xE7\xE3o"
|
|
9516
9821
|
},
|
|
9517
|
-
/* @__PURE__ */
|
|
9822
|
+
/* @__PURE__ */ React24.createElement(FiX7, { size: 12 })
|
|
9518
9823
|
))
|
|
9519
9824
|
);
|
|
9520
|
-
})), canEdit && /* @__PURE__ */
|
|
9825
|
+
})), canEdit && /* @__PURE__ */ React24.createElement("div", { className: "flex items-center justify-between pt-2 mt-1 border-t border-white/5 opacity-40 group-hover/item:opacity-100 transition-opacity" }, /* @__PURE__ */ React24.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React24.createElement(
|
|
9521
9826
|
"button",
|
|
9522
9827
|
{
|
|
9523
9828
|
onClick: () => onRequestPickAncestry(group.id),
|
|
@@ -9527,17 +9832,17 @@ var GroupItem = ({
|
|
|
9527
9832
|
`,
|
|
9528
9833
|
title: "Adicionar Ancestralidade a este grupo"
|
|
9529
9834
|
},
|
|
9530
|
-
isPickingForThisGroup ? /* @__PURE__ */
|
|
9835
|
+
isPickingForThisGroup ? /* @__PURE__ */ React24.createElement(FiCheckCircle, { size: 12 }) : /* @__PURE__ */ React24.createElement(FiSearch4, { size: 12 }),
|
|
9531
9836
|
isPickingForThisGroup ? "Selecionando..." : "Adicionar"
|
|
9532
|
-
), /* @__PURE__ */
|
|
9837
|
+
), /* @__PURE__ */ React24.createElement(
|
|
9533
9838
|
"button",
|
|
9534
9839
|
{
|
|
9535
9840
|
onClick: () => onAddSubgroup(group.id),
|
|
9536
9841
|
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
9537
9842
|
title: "Criar Subgrupo"
|
|
9538
9843
|
},
|
|
9539
|
-
/* @__PURE__ */
|
|
9540
|
-
)), /* @__PURE__ */
|
|
9844
|
+
/* @__PURE__ */ React24.createElement(FiPlus9, { size: 14 })
|
|
9845
|
+
)), /* @__PURE__ */ React24.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React24.createElement(
|
|
9541
9846
|
"button",
|
|
9542
9847
|
{
|
|
9543
9848
|
onClick: () => onIndent(group.id),
|
|
@@ -9545,24 +9850,24 @@ var GroupItem = ({
|
|
|
9545
9850
|
className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
|
|
9546
9851
|
title: "Aninhar no grupo acima"
|
|
9547
9852
|
},
|
|
9548
|
-
/* @__PURE__ */
|
|
9549
|
-
), /* @__PURE__ */
|
|
9853
|
+
/* @__PURE__ */ React24.createElement(FiArrowRight, { size: 14 })
|
|
9854
|
+
), /* @__PURE__ */ React24.createElement(
|
|
9550
9855
|
"button",
|
|
9551
9856
|
{
|
|
9552
9857
|
onClick: () => onOutdent(group.id),
|
|
9553
9858
|
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
9554
9859
|
title: "Desaninhar"
|
|
9555
9860
|
},
|
|
9556
|
-
/* @__PURE__ */
|
|
9557
|
-
), /* @__PURE__ */
|
|
9861
|
+
/* @__PURE__ */ React24.createElement(FiArrowLeft3, { size: 14 })
|
|
9862
|
+
), /* @__PURE__ */ React24.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ React24.createElement(
|
|
9558
9863
|
"button",
|
|
9559
9864
|
{
|
|
9560
9865
|
onClick: () => onDelete(group.id),
|
|
9561
9866
|
className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
|
|
9562
9867
|
title: "Remover Grupo"
|
|
9563
9868
|
},
|
|
9564
|
-
/* @__PURE__ */
|
|
9565
|
-
)))), group.children && group.children.length > 0 && /* @__PURE__ */
|
|
9869
|
+
/* @__PURE__ */ React24.createElement(FiTrash23, { size: 14 })
|
|
9870
|
+
)))), group.children && group.children.length > 0 && /* @__PURE__ */ React24.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ React24.createElement(
|
|
9566
9871
|
GroupItem,
|
|
9567
9872
|
{
|
|
9568
9873
|
key: childGroup.id,
|
|
@@ -9594,15 +9899,15 @@ function AncestryBoard({
|
|
|
9594
9899
|
userRole
|
|
9595
9900
|
// [NOVO] Recebe a role do usuário
|
|
9596
9901
|
}) {
|
|
9597
|
-
const [searchTerm, setSearchTerm] =
|
|
9598
|
-
const [groups, setGroups] =
|
|
9599
|
-
const [isLoaded, setIsLoaded] =
|
|
9600
|
-
const [pickingGroupId, setPickingGroupId] =
|
|
9601
|
-
const [saveStatus, setSaveStatus] =
|
|
9902
|
+
const [searchTerm, setSearchTerm] = useState24("");
|
|
9903
|
+
const [groups, setGroups] = useState24([]);
|
|
9904
|
+
const [isLoaded, setIsLoaded] = useState24(false);
|
|
9905
|
+
const [pickingGroupId, setPickingGroupId] = useState24(null);
|
|
9906
|
+
const [saveStatus, setSaveStatus] = useState24("idle");
|
|
9602
9907
|
const canEdit = useMemo11(() => {
|
|
9603
9908
|
return userRole !== "viewer";
|
|
9604
9909
|
}, [userRole]);
|
|
9605
|
-
|
|
9910
|
+
useEffect21(() => {
|
|
9606
9911
|
if (initialGroups && !isLoaded) {
|
|
9607
9912
|
setGroups(initialGroups);
|
|
9608
9913
|
setIsLoaded(true);
|
|
@@ -9633,7 +9938,7 @@ function AncestryBoard({
|
|
|
9633
9938
|
children: sanitizeGroups(g.children || [])
|
|
9634
9939
|
}));
|
|
9635
9940
|
};
|
|
9636
|
-
|
|
9941
|
+
useEffect21(() => {
|
|
9637
9942
|
if (!isLoaded || !onSave) return;
|
|
9638
9943
|
const timeoutId = setTimeout(async () => {
|
|
9639
9944
|
setSaveStatus("saving");
|
|
@@ -9651,7 +9956,7 @@ function AncestryBoard({
|
|
|
9651
9956
|
}, 3e3);
|
|
9652
9957
|
return () => clearTimeout(timeoutId);
|
|
9653
9958
|
}, [groups, isLoaded, onSave]);
|
|
9654
|
-
|
|
9959
|
+
useEffect21(() => {
|
|
9655
9960
|
if (!isOpen) return;
|
|
9656
9961
|
const handleKeyDown = (e) => {
|
|
9657
9962
|
if (e.key === "Escape") {
|
|
@@ -9806,27 +10111,27 @@ function AncestryBoard({
|
|
|
9806
10111
|
});
|
|
9807
10112
|
};
|
|
9808
10113
|
if (!isOpen) return null;
|
|
9809
|
-
return /* @__PURE__ */
|
|
10114
|
+
return /* @__PURE__ */ React24.createElement(
|
|
9810
10115
|
"div",
|
|
9811
10116
|
{
|
|
9812
10117
|
className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
|
|
9813
10118
|
onClick: onClose
|
|
9814
10119
|
},
|
|
9815
|
-
/* @__PURE__ */
|
|
10120
|
+
/* @__PURE__ */ React24.createElement(
|
|
9816
10121
|
"div",
|
|
9817
10122
|
{
|
|
9818
10123
|
className: "bg-slate-950 border border-white/10 rounded-xl w-[98vw] h-[97vh] flex flex-col shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-200",
|
|
9819
10124
|
onClick: (e) => e.stopPropagation()
|
|
9820
10125
|
},
|
|
9821
|
-
/* @__PURE__ */
|
|
10126
|
+
/* @__PURE__ */ React24.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ React24.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React24.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ React24.createElement(FiLayers6, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ React24.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React24.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ React24.createElement("div", { className: "flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-slate-900/50 border border-white/5" }, saveStatus === "saving" && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(FiLoader5, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ React24.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ React24.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ React24.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ React24.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ React24.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ React24.createElement(
|
|
9822
10127
|
"button",
|
|
9823
10128
|
{
|
|
9824
10129
|
onClick: handleAddRootGroup,
|
|
9825
10130
|
className: "\n flex items-center gap-2 px-3 py-1.5 \n bg-white/5 hover:bg-white/10 \n border border-white/10 hover:border-white/20\n backdrop-blur-sm\n text-slate-200 hover:text-white\n rounded-md transition-all duration-200\n text-xs font-medium shadow-sm\n "
|
|
9826
10131
|
},
|
|
9827
|
-
/* @__PURE__ */
|
|
9828
|
-
/* @__PURE__ */
|
|
9829
|
-
), /* @__PURE__ */
|
|
10132
|
+
/* @__PURE__ */ React24.createElement(FiPlus9, { size: 14, className: "text-indigo-400" }),
|
|
10133
|
+
/* @__PURE__ */ React24.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
|
|
10134
|
+
), /* @__PURE__ */ React24.createElement(
|
|
9830
10135
|
"button",
|
|
9831
10136
|
{
|
|
9832
10137
|
onClick: onClose,
|
|
@@ -9834,11 +10139,11 @@ function AncestryBoard({
|
|
|
9834
10139
|
},
|
|
9835
10140
|
"\xD7"
|
|
9836
10141
|
))),
|
|
9837
|
-
/* @__PURE__ */
|
|
10142
|
+
/* @__PURE__ */ React24.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ React24.createElement("div", { className: `
|
|
9838
10143
|
flex flex-col border-r border-white/10 transition-all duration-300 flex-none
|
|
9839
10144
|
${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
|
|
9840
10145
|
min-w-[280px] max-w-[500px] bg-slate-900
|
|
9841
|
-
` }, /* @__PURE__ */
|
|
10146
|
+
` }, /* @__PURE__ */ React24.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ React24.createElement("div", { className: "relative group" }, /* @__PURE__ */ React24.createElement(FiSearch4, { className: `absolute left-3 top-1/2 -translate-y-1/2 transition-colors ${pickingGroupId ? "text-indigo-400" : "text-slate-500 group-focus-within:text-indigo-400"}` }), /* @__PURE__ */ React24.createElement(
|
|
9842
10147
|
"input",
|
|
9843
10148
|
{
|
|
9844
10149
|
type: "text",
|
|
@@ -9851,10 +10156,10 @@ function AncestryBoard({
|
|
|
9851
10156
|
onChange: (e) => setSearchTerm(e.target.value),
|
|
9852
10157
|
autoFocus: !pickingGroupId
|
|
9853
10158
|
}
|
|
9854
|
-
))), /* @__PURE__ */
|
|
10159
|
+
))), /* @__PURE__ */ React24.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
|
|
9855
10160
|
const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
|
|
9856
10161
|
const isPicking = !!pickingGroupId;
|
|
9857
|
-
return /* @__PURE__ */
|
|
10162
|
+
return /* @__PURE__ */ React24.createElement(
|
|
9858
10163
|
"div",
|
|
9859
10164
|
{
|
|
9860
10165
|
key: anc.ancestry_id,
|
|
@@ -9866,12 +10171,12 @@ function AncestryBoard({
|
|
|
9866
10171
|
${isPicking ? "border-indigo-500/30 bg-indigo-500/5 hover:bg-indigo-500/20 hover:border-indigo-400 cursor-pointer" : "border-white/5 bg-slate-800/40 hover:bg-indigo-600/10 hover:border-indigo-500/30 cursor-default"}
|
|
9867
10172
|
`
|
|
9868
10173
|
},
|
|
9869
|
-
/* @__PURE__ */
|
|
10174
|
+
/* @__PURE__ */ React24.createElement("div", { className: `
|
|
9870
10175
|
mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
|
|
9871
10176
|
${isPicking ? "bg-indigo-500 text-white border-indigo-400" : "bg-slate-800 text-indigo-400 border-white/5 group-hover:bg-indigo-500 group-hover:text-white"}
|
|
9872
|
-
` }, isPicking ? /* @__PURE__ */
|
|
9873
|
-
/* @__PURE__ */
|
|
9874
|
-
!isPicking && /* @__PURE__ */
|
|
10177
|
+
` }, isPicking ? /* @__PURE__ */ React24.createElement(FiPlus9, { size: 16 }) : /* @__PURE__ */ React24.createElement(FiLayers6, { size: 14 })),
|
|
10178
|
+
/* @__PURE__ */ React24.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ React24.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React24.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.name || "Sem Nome"), anc.is_private && /* @__PURE__ */ React24.createElement("span", { className: "text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-300 border border-amber-500/20" }, "Priv")), /* @__PURE__ */ React24.createElement("div", { className: "flex items-center gap-1.5 mt-0.5 text-[11px] text-slate-500 group-hover:text-indigo-200/70 transition-colors" }, /* @__PURE__ */ React24.createElement(FiCornerUpRight4, { size: 10 }), /* @__PURE__ */ React24.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ React24.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
|
|
10179
|
+
!isPicking && /* @__PURE__ */ React24.createElement(
|
|
9875
10180
|
"button",
|
|
9876
10181
|
{
|
|
9877
10182
|
onClick: (e) => {
|
|
@@ -9881,10 +10186,10 @@ function AncestryBoard({
|
|
|
9881
10186
|
className: "absolute right-2 bottom-2 opacity-0 group-hover:opacity-100 transition-all duration-300 transform translate-y-2 group-hover:translate-y-0 z-10",
|
|
9882
10187
|
title: "Renderizar Ancestralidade"
|
|
9883
10188
|
},
|
|
9884
|
-
/* @__PURE__ */
|
|
10189
|
+
/* @__PURE__ */ React24.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ React24.createElement(FiPlay, { size: 14, className: "ml-0.5" }))
|
|
9885
10190
|
)
|
|
9886
10191
|
);
|
|
9887
|
-
}))), /* @__PURE__ */
|
|
10192
|
+
}))), /* @__PURE__ */ React24.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ React24.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ React24.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-3 border-2 border-dashed border-white/5 rounded-xl m-4 bg-slate-900/20" }, /* @__PURE__ */ React24.createElement(FiLayers6, { size: 24, className: "opacity-20" }), /* @__PURE__ */ React24.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ React24.createElement(React24.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ React24.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ React24.createElement(React24.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ React24.createElement(
|
|
9888
10193
|
GroupItem,
|
|
9889
10194
|
{
|
|
9890
10195
|
key: group.id,
|
|
@@ -9904,7 +10209,7 @@ function AncestryBoard({
|
|
|
9904
10209
|
canEdit
|
|
9905
10210
|
}
|
|
9906
10211
|
))))),
|
|
9907
|
-
/* @__PURE__ */
|
|
10212
|
+
/* @__PURE__ */ React24.createElement("div", { className: "px-5 py-2 border-t border-white/10 bg-slate-950/50 text-xs text-slate-500 flex justify-between flex-shrink-0" }, /* @__PURE__ */ React24.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ React24.createElement("span", null, groups.length, " grupos raiz"))
|
|
9908
10213
|
)
|
|
9909
10214
|
);
|
|
9910
10215
|
}
|
|
@@ -9998,7 +10303,7 @@ function XViewScene({
|
|
|
9998
10303
|
}
|
|
9999
10304
|
return null;
|
|
10000
10305
|
}, [encryptedConfig, session]);
|
|
10001
|
-
|
|
10306
|
+
useEffect22(() => {
|
|
10002
10307
|
async function verifyPermission() {
|
|
10003
10308
|
if (!viewParams || !session || !check_user_permission) return;
|
|
10004
10309
|
const { id, type, owner_id } = viewParams;
|
|
@@ -10048,45 +10353,45 @@ function XViewScene({
|
|
|
10048
10353
|
}
|
|
10049
10354
|
return null;
|
|
10050
10355
|
}, [ownerId, sceneConfigId]);
|
|
10051
|
-
const sceneDataRef =
|
|
10052
|
-
const parentDataRef =
|
|
10053
|
-
const ancestryDataRef =
|
|
10054
|
-
const [isLoading, setIsLoading] =
|
|
10055
|
-
const [permissionStatus, setPermissionStatus] =
|
|
10056
|
-
const [userPermissionRole, setUserPermissionRole] =
|
|
10057
|
-
const [isInitialized, setIsInitialized] =
|
|
10058
|
-
const [sceneVersion, setSceneVersion] =
|
|
10059
|
-
const [contextMenu, setContextMenu] =
|
|
10060
|
-
const [multiContextMenu, setMultiContextMenu] =
|
|
10061
|
-
const [relationshipMenu, setRelationshipMenu] =
|
|
10062
|
-
const [creationMode, setCreationMode] =
|
|
10063
|
-
const [versionMode, setVersionMode] =
|
|
10064
|
-
const [questMode, setQuestMode] =
|
|
10065
|
-
const [hasFocusedInitial, setHasFocusedInitial] =
|
|
10066
|
-
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] =
|
|
10067
|
-
const [ancestryMode, setAncestryMode] =
|
|
10068
|
-
const [readingMode, setReadingMode] =
|
|
10356
|
+
const sceneDataRef = useRef19(null);
|
|
10357
|
+
const parentDataRef = useRef19(null);
|
|
10358
|
+
const ancestryDataRef = useRef19(null);
|
|
10359
|
+
const [isLoading, setIsLoading] = useState25(true);
|
|
10360
|
+
const [permissionStatus, setPermissionStatus] = useState25("loading");
|
|
10361
|
+
const [userPermissionRole, setUserPermissionRole] = useState25(null);
|
|
10362
|
+
const [isInitialized, setIsInitialized] = useState25(false);
|
|
10363
|
+
const [sceneVersion, setSceneVersion] = useState25(0);
|
|
10364
|
+
const [contextMenu, setContextMenu] = useState25({ visible: false, x: 0, y: 0, nodeData: null });
|
|
10365
|
+
const [multiContextMenu, setMultiContextMenu] = useState25({ visible: false, x: 0, y: 0, nodeIds: null });
|
|
10366
|
+
const [relationshipMenu, setRelationshipMenu] = useState25({ visible: false, x: 0, y: 0, linkObject: null });
|
|
10367
|
+
const [creationMode, setCreationMode] = useState25({ isActive: false, sourceNodeData: null });
|
|
10368
|
+
const [versionMode, setVersionMode] = useState25({ isActive: false, sourceNodeData: null });
|
|
10369
|
+
const [questMode, setQuestMode] = useState25({ isActive: false });
|
|
10370
|
+
const [hasFocusedInitial, setHasFocusedInitial] = useState25(false);
|
|
10371
|
+
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState25(false);
|
|
10372
|
+
const [ancestryMode, setAncestryMode] = useState25({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
10373
|
+
const [readingMode, setReadingMode] = useState25({
|
|
10069
10374
|
isActive: false,
|
|
10070
10375
|
ancestry: null,
|
|
10071
10376
|
branchStack: [],
|
|
10072
10377
|
autoAbstraction: false
|
|
10073
10378
|
});
|
|
10074
|
-
const [formPosition, setFormPosition] =
|
|
10075
|
-
const [detailsNode, setDetailsNode] =
|
|
10076
|
-
const [detailsLink, setDetailsLink] =
|
|
10077
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] =
|
|
10078
|
-
const [imageViewer, setImageViewer] =
|
|
10079
|
-
const [editingAncestryRel, setEditingAncestryRel] =
|
|
10080
|
-
const [isImportModalOpen, setIsImportModalOpen] =
|
|
10081
|
-
const [importSuccessMessage, setImportSuccessMessage] =
|
|
10082
|
-
const [highlightedNodeId, setHighlightedNodeId] =
|
|
10083
|
-
const [isAncestryBoardOpen, setIsAncestryBoardOpen] =
|
|
10084
|
-
const [ancestryBoardData, setAncestryBoardData] =
|
|
10085
|
-
const [isSidebarOpen, setIsSidebarOpen] =
|
|
10086
|
-
const mountRef =
|
|
10087
|
-
const tooltipRef =
|
|
10088
|
-
const formRef =
|
|
10089
|
-
const stateRef =
|
|
10379
|
+
const [formPosition, setFormPosition] = useState25({ left: 16, top: 16, opacity: 0 });
|
|
10380
|
+
const [detailsNode, setDetailsNode] = useState25(null);
|
|
10381
|
+
const [detailsLink, setDetailsLink] = useState25(null);
|
|
10382
|
+
const [ancestryLinkDetails, setAncestryLinkDetails] = useState25(null);
|
|
10383
|
+
const [imageViewer, setImageViewer] = useState25({ visible: false, images: [], startIndex: 0 });
|
|
10384
|
+
const [editingAncestryRel, setEditingAncestryRel] = useState25({ visible: false, data: null, path: null });
|
|
10385
|
+
const [isImportModalOpen, setIsImportModalOpen] = useState25(false);
|
|
10386
|
+
const [importSuccessMessage, setImportSuccessMessage] = useState25("");
|
|
10387
|
+
const [highlightedNodeId, setHighlightedNodeId] = useState25(null);
|
|
10388
|
+
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState25(false);
|
|
10389
|
+
const [ancestryBoardData, setAncestryBoardData] = useState25([]);
|
|
10390
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState25(false);
|
|
10391
|
+
const mountRef = useRef19(null);
|
|
10392
|
+
const tooltipRef = useRef19(null);
|
|
10393
|
+
const formRef = useRef19(null);
|
|
10394
|
+
const stateRef = useRef19({
|
|
10090
10395
|
readMode: {
|
|
10091
10396
|
currentMaxIndex: 0,
|
|
10092
10397
|
progressMap: {}
|
|
@@ -10131,10 +10436,10 @@ function XViewScene({
|
|
|
10131
10436
|
minWidth: 320,
|
|
10132
10437
|
maxWidth: maxReadPanelW
|
|
10133
10438
|
});
|
|
10134
|
-
|
|
10439
|
+
useEffect22(() => {
|
|
10135
10440
|
stateRef.current.ancestry = ancestryMode;
|
|
10136
10441
|
}, [ancestryMode]);
|
|
10137
|
-
|
|
10442
|
+
useEffect22(() => {
|
|
10138
10443
|
var _a2;
|
|
10139
10444
|
if (!isInitialized) return;
|
|
10140
10445
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -10631,7 +10936,7 @@ function XViewScene({
|
|
|
10631
10936
|
}
|
|
10632
10937
|
});
|
|
10633
10938
|
}, []);
|
|
10634
|
-
|
|
10939
|
+
useEffect22(() => {
|
|
10635
10940
|
async function fetchAllData(configPath, ownerId2) {
|
|
10636
10941
|
var _a2, _b2;
|
|
10637
10942
|
if (!get_scene_view_data) {
|
|
@@ -10735,7 +11040,7 @@ function XViewScene({
|
|
|
10735
11040
|
}
|
|
10736
11041
|
return mesh;
|
|
10737
11042
|
}, []);
|
|
10738
|
-
|
|
11043
|
+
useEffect22(() => {
|
|
10739
11044
|
if (!isInitialized || !sceneDataRef.current) return;
|
|
10740
11045
|
const currentMount = mountRef.current;
|
|
10741
11046
|
if (!currentMount) return;
|
|
@@ -13106,7 +13411,7 @@ function XViewScene({
|
|
|
13106
13411
|
}, [sceneVersion, isInitialized]);
|
|
13107
13412
|
const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(String(creationMode.sourceNodeData.id))) == null ? void 0 : _b.parentFileId : null;
|
|
13108
13413
|
const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
|
|
13109
|
-
|
|
13414
|
+
useEffect22(() => {
|
|
13110
13415
|
if (isInitialized && focusNodeId && !hasFocusedInitial) {
|
|
13111
13416
|
const nodeObjects = stateRef.current.nodeObjects || {};
|
|
13112
13417
|
const targetMesh = nodeObjects[String(focusNodeId)];
|
|
@@ -13120,7 +13425,7 @@ function XViewScene({
|
|
|
13120
13425
|
}
|
|
13121
13426
|
}
|
|
13122
13427
|
}, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
|
|
13123
|
-
|
|
13428
|
+
useEffect22(() => {
|
|
13124
13429
|
if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
|
|
13125
13430
|
const ancestries = ancestryDataRef.current || [];
|
|
13126
13431
|
const targetAncestry = ancestries.find((a) => String(a.ancestry_id) === String(focusAncestryId));
|
|
@@ -13134,7 +13439,7 @@ function XViewScene({
|
|
|
13134
13439
|
}
|
|
13135
13440
|
}
|
|
13136
13441
|
}, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
|
|
13137
|
-
|
|
13442
|
+
useEffect22(() => {
|
|
13138
13443
|
function handleKeyDown(event) {
|
|
13139
13444
|
var _a2, _b2, _c2;
|
|
13140
13445
|
const context = actionHandlerContext;
|
|
@@ -13235,20 +13540,20 @@ function XViewScene({
|
|
|
13235
13540
|
// <-- handleCancelQuest adicionado aqui
|
|
13236
13541
|
]);
|
|
13237
13542
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
13238
|
-
return /* @__PURE__ */
|
|
13543
|
+
return /* @__PURE__ */ React25.createElement(LoadingScreen, null);
|
|
13239
13544
|
}
|
|
13240
13545
|
if (permissionStatus === "denied") {
|
|
13241
|
-
return /* @__PURE__ */
|
|
13546
|
+
return /* @__PURE__ */ React25.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ React25.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ React25.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ React25.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "w-16 h-16 mx-auto" }, /* @__PURE__ */ React25.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" }))), /* @__PURE__ */ React25.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ React25.createElement("p", { className: "text-slate-400 mb-6" }, "Voc\xEA n\xE3o tem permiss\xE3o para acessar este conte\xFAdo. Solicite acesso ao propriet\xE1rio ou verifique se est\xE1 na conta correta."), /* @__PURE__ */ React25.createElement(
|
|
13242
13547
|
"button",
|
|
13243
13548
|
{
|
|
13244
13549
|
onClick: () => router.push("/dashboard/scenes"),
|
|
13245
13550
|
className: "flex items-center justify-center gap-2 w-full py-3 px-4 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors font-medium"
|
|
13246
13551
|
},
|
|
13247
|
-
/* @__PURE__ */
|
|
13552
|
+
/* @__PURE__ */ React25.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 2, stroke: "currentColor", className: "w-5 h-5" }, /* @__PURE__ */ React25.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" })),
|
|
13248
13553
|
"Voltar para Scenes"
|
|
13249
13554
|
)));
|
|
13250
13555
|
}
|
|
13251
|
-
return /* @__PURE__ */
|
|
13556
|
+
return /* @__PURE__ */ React25.createElement(
|
|
13252
13557
|
"div",
|
|
13253
13558
|
{
|
|
13254
13559
|
ref: mountRef,
|
|
@@ -13260,7 +13565,7 @@ function XViewScene({
|
|
|
13260
13565
|
cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
|
|
13261
13566
|
}
|
|
13262
13567
|
},
|
|
13263
|
-
userPermissionRole !== "link_viewer" && /* @__PURE__ */
|
|
13568
|
+
userPermissionRole !== "link_viewer" && /* @__PURE__ */ React25.createElement(
|
|
13264
13569
|
XViewSidebar,
|
|
13265
13570
|
{
|
|
13266
13571
|
dbNodes: searchableDbNodes,
|
|
@@ -13280,7 +13585,7 @@ function XViewScene({
|
|
|
13280
13585
|
userRole: userPermissionRole
|
|
13281
13586
|
}
|
|
13282
13587
|
),
|
|
13283
|
-
creationMode.isActive && /* @__PURE__ */
|
|
13588
|
+
creationMode.isActive && /* @__PURE__ */ React25.createElement(
|
|
13284
13589
|
InSceneCreationForm,
|
|
13285
13590
|
{
|
|
13286
13591
|
onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
|
|
@@ -13305,7 +13610,7 @@ function XViewScene({
|
|
|
13305
13610
|
availableAncestries: allAvailableAncestries
|
|
13306
13611
|
}
|
|
13307
13612
|
),
|
|
13308
|
-
versionMode.isActive && /* @__PURE__ */
|
|
13613
|
+
versionMode.isActive && /* @__PURE__ */ React25.createElement(
|
|
13309
13614
|
InSceneVersionForm,
|
|
13310
13615
|
{
|
|
13311
13616
|
onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
|
|
@@ -13324,7 +13629,7 @@ function XViewScene({
|
|
|
13324
13629
|
availableAncestries: allAvailableAncestries
|
|
13325
13630
|
}
|
|
13326
13631
|
),
|
|
13327
|
-
questMode.isActive && /* @__PURE__ */
|
|
13632
|
+
questMode.isActive && /* @__PURE__ */ React25.createElement(
|
|
13328
13633
|
InSceneQuestForm,
|
|
13329
13634
|
{
|
|
13330
13635
|
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
@@ -13341,13 +13646,13 @@ function XViewScene({
|
|
|
13341
13646
|
availableAncestries: allAvailableAncestries
|
|
13342
13647
|
}
|
|
13343
13648
|
),
|
|
13344
|
-
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */
|
|
13649
|
+
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React25.createElement(
|
|
13345
13650
|
"div",
|
|
13346
13651
|
{
|
|
13347
13652
|
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"}`,
|
|
13348
13653
|
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${readModeWidth}px`, maxWidth: "92vw" }
|
|
13349
13654
|
},
|
|
13350
|
-
/* @__PURE__ */
|
|
13655
|
+
/* @__PURE__ */ React25.createElement(
|
|
13351
13656
|
"div",
|
|
13352
13657
|
{
|
|
13353
13658
|
onPointerDown: (e) => {
|
|
@@ -13358,7 +13663,7 @@ function XViewScene({
|
|
|
13358
13663
|
title: "Arraste para redimensionar"
|
|
13359
13664
|
}
|
|
13360
13665
|
),
|
|
13361
|
-
/* @__PURE__ */
|
|
13666
|
+
/* @__PURE__ */ React25.createElement(
|
|
13362
13667
|
DescriptionReadModePanel,
|
|
13363
13668
|
{
|
|
13364
13669
|
key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
|
|
@@ -13393,7 +13698,7 @@ function XViewScene({
|
|
|
13393
13698
|
}
|
|
13394
13699
|
)
|
|
13395
13700
|
),
|
|
13396
|
-
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */
|
|
13701
|
+
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ React25.createElement(
|
|
13397
13702
|
CreateAncestryPanel,
|
|
13398
13703
|
{
|
|
13399
13704
|
ancestryMode,
|
|
@@ -13420,7 +13725,7 @@ function XViewScene({
|
|
|
13420
13725
|
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
13421
13726
|
}
|
|
13422
13727
|
),
|
|
13423
|
-
editingAncestryRel.visible && /* @__PURE__ */
|
|
13728
|
+
editingAncestryRel.visible && /* @__PURE__ */ React25.createElement(
|
|
13424
13729
|
AncestryRelationshipPanel,
|
|
13425
13730
|
{
|
|
13426
13731
|
data: editingAncestryRel.data,
|
|
@@ -13434,7 +13739,28 @@ function XViewScene({
|
|
|
13434
13739
|
onUploadFile: upload_file_action
|
|
13435
13740
|
}
|
|
13436
13741
|
),
|
|
13437
|
-
detailsNode && /* @__PURE__ */
|
|
13742
|
+
detailsNode && detailsNode.is_quest && /* @__PURE__ */ React25.createElement(
|
|
13743
|
+
QuestDetailsPanel,
|
|
13744
|
+
{
|
|
13745
|
+
node: detailsNode,
|
|
13746
|
+
onClose: () => setDetailsNode(null),
|
|
13747
|
+
onSave: (data) => userActionHandlers.handleSaveNodeDetails(actionHandlerContext, data),
|
|
13748
|
+
onNameChange: handleDetailNodeNameChange,
|
|
13749
|
+
onColorChange: handleDetailNodeColorChange,
|
|
13750
|
+
onSizeChange: handleDetailNodeSizeChange,
|
|
13751
|
+
onDataUpdate: setDetailsNode,
|
|
13752
|
+
onOpenImageViewer: handleOpenImageViewer,
|
|
13753
|
+
existingTypes: existingNodeTypes,
|
|
13754
|
+
availableNodes: allAvailableNodes,
|
|
13755
|
+
availableAncestries: allAvailableAncestries,
|
|
13756
|
+
onOpenReference: handleOpenReference,
|
|
13757
|
+
onMentionClick: handleAddExistingNode,
|
|
13758
|
+
onUploadFile: upload_file_action,
|
|
13759
|
+
userRole: userPermissionRole,
|
|
13760
|
+
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
13761
|
+
}
|
|
13762
|
+
),
|
|
13763
|
+
detailsNode && !detailsNode.is_quest && /* @__PURE__ */ React25.createElement(
|
|
13438
13764
|
NodeDetailsPanel,
|
|
13439
13765
|
{
|
|
13440
13766
|
node: detailsNode,
|
|
@@ -13461,7 +13787,7 @@ function XViewScene({
|
|
|
13461
13787
|
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
13462
13788
|
}
|
|
13463
13789
|
),
|
|
13464
|
-
detailsLink && /* @__PURE__ */
|
|
13790
|
+
detailsLink && /* @__PURE__ */ React25.createElement(
|
|
13465
13791
|
RelationshipDetailsPanel,
|
|
13466
13792
|
{
|
|
13467
13793
|
link: detailsLink,
|
|
@@ -13475,7 +13801,7 @@ function XViewScene({
|
|
|
13475
13801
|
userRole: userPermissionRole
|
|
13476
13802
|
}
|
|
13477
13803
|
),
|
|
13478
|
-
ancestryLinkDetails && /* @__PURE__ */
|
|
13804
|
+
ancestryLinkDetails && /* @__PURE__ */ React25.createElement(
|
|
13479
13805
|
AncestryLinkDetailsPanel,
|
|
13480
13806
|
{
|
|
13481
13807
|
data: ancestryLinkDetails,
|
|
@@ -13486,7 +13812,7 @@ function XViewScene({
|
|
|
13486
13812
|
onUploadFile: upload_file_action
|
|
13487
13813
|
}
|
|
13488
13814
|
),
|
|
13489
|
-
/* @__PURE__ */
|
|
13815
|
+
/* @__PURE__ */ React25.createElement(
|
|
13490
13816
|
"div",
|
|
13491
13817
|
{
|
|
13492
13818
|
ref: tooltipRef,
|
|
@@ -13513,7 +13839,7 @@ function XViewScene({
|
|
|
13513
13839
|
}
|
|
13514
13840
|
}
|
|
13515
13841
|
),
|
|
13516
|
-
/* @__PURE__ */
|
|
13842
|
+
/* @__PURE__ */ React25.createElement(
|
|
13517
13843
|
ContextMenu,
|
|
13518
13844
|
{
|
|
13519
13845
|
data: contextMenu,
|
|
@@ -13536,7 +13862,7 @@ function XViewScene({
|
|
|
13536
13862
|
onFocusNode: handleFocusNode
|
|
13537
13863
|
}
|
|
13538
13864
|
),
|
|
13539
|
-
/* @__PURE__ */
|
|
13865
|
+
/* @__PURE__ */ React25.createElement(
|
|
13540
13866
|
MultiNodeContextMenu,
|
|
13541
13867
|
{
|
|
13542
13868
|
data: multiContextMenu,
|
|
@@ -13547,7 +13873,7 @@ function XViewScene({
|
|
|
13547
13873
|
onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
|
|
13548
13874
|
}
|
|
13549
13875
|
),
|
|
13550
|
-
/* @__PURE__ */
|
|
13876
|
+
/* @__PURE__ */ React25.createElement(
|
|
13551
13877
|
RelationshipContextMenu,
|
|
13552
13878
|
{
|
|
13553
13879
|
data: relationshipMenu,
|
|
@@ -13565,8 +13891,8 @@ function XViewScene({
|
|
|
13565
13891
|
onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
|
|
13566
13892
|
}
|
|
13567
13893
|
),
|
|
13568
|
-
/* @__PURE__ */
|
|
13569
|
-
/* @__PURE__ */
|
|
13894
|
+
/* @__PURE__ */ React25.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
|
|
13895
|
+
/* @__PURE__ */ React25.createElement(
|
|
13570
13896
|
AncestryBoard,
|
|
13571
13897
|
{
|
|
13572
13898
|
isOpen: isAncestryBoardOpen,
|
|
@@ -13579,7 +13905,7 @@ function XViewScene({
|
|
|
13579
13905
|
userRole: userPermissionRole
|
|
13580
13906
|
}
|
|
13581
13907
|
),
|
|
13582
|
-
/* @__PURE__ */
|
|
13908
|
+
/* @__PURE__ */ React25.createElement(
|
|
13583
13909
|
ImportParentFileModal,
|
|
13584
13910
|
{
|
|
13585
13911
|
isOpen: isImportModalOpen,
|