@lv-x-software-house/x_view 1.2.4-dev.22 → 1.2.4-dev.24
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 +623 -282
- package/dist/index.mjs +563 -222
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -43,9 +43,9 @@ __export(index_exports, {
|
|
|
43
43
|
module.exports = __toCommonJS(index_exports);
|
|
44
44
|
|
|
45
45
|
// src/XViewScene.jsx
|
|
46
|
-
var
|
|
46
|
+
var import_react26 = __toESM(require("react"));
|
|
47
47
|
var import_navigation = require("next/navigation");
|
|
48
|
-
var
|
|
48
|
+
var import_react27 = require("next-auth/react");
|
|
49
49
|
var import_crypto_js = __toESM(require("crypto-js"));
|
|
50
50
|
var THREE3 = __toESM(require("three"));
|
|
51
51
|
var import_OrbitControls = require("three/examples/jsm/controls/OrbitControls.js");
|
|
@@ -2893,7 +2893,9 @@ var IGNORED_KEYS = [
|
|
|
2893
2893
|
"is_private",
|
|
2894
2894
|
"abstraction_tree",
|
|
2895
2895
|
"selectedAbstractionParentId",
|
|
2896
|
-
"isAddingAbstractionNodes"
|
|
2896
|
+
"isAddingAbstractionNodes",
|
|
2897
|
+
"status",
|
|
2898
|
+
"is_quest"
|
|
2897
2899
|
];
|
|
2898
2900
|
function extractCustomPropsFromNode(node) {
|
|
2899
2901
|
const customPropTypes = node._customPropTypes || {};
|
|
@@ -8654,8 +8656,326 @@ function NodeDetailsPanel({
|
|
|
8654
8656
|
));
|
|
8655
8657
|
}
|
|
8656
8658
|
|
|
8657
|
-
// src/components/
|
|
8659
|
+
// src/components/QuestDetailsPanel.jsx
|
|
8658
8660
|
var import_react18 = __toESM(require("react"));
|
|
8661
|
+
var import_fi16 = require("react-icons/fi");
|
|
8662
|
+
var QUEST_STATUS_COLORS2 = {
|
|
8663
|
+
"Backlog": "#64748b",
|
|
8664
|
+
"In Progress": "#eab308",
|
|
8665
|
+
"Review": "#a855f7",
|
|
8666
|
+
"Done": "#22c55e"
|
|
8667
|
+
};
|
|
8668
|
+
function QuestDetailsPanel({
|
|
8669
|
+
node,
|
|
8670
|
+
onClose,
|
|
8671
|
+
onSave,
|
|
8672
|
+
onNameChange,
|
|
8673
|
+
onColorChange,
|
|
8674
|
+
onSizeChange,
|
|
8675
|
+
onDataUpdate,
|
|
8676
|
+
onOpenImageViewer,
|
|
8677
|
+
existingTypes = [],
|
|
8678
|
+
availableNodes = [],
|
|
8679
|
+
availableAncestries = [],
|
|
8680
|
+
onOpenReference,
|
|
8681
|
+
onMentionClick,
|
|
8682
|
+
onUploadFile,
|
|
8683
|
+
userRole,
|
|
8684
|
+
currentDatasetName
|
|
8685
|
+
}) {
|
|
8686
|
+
const [name, setName] = (0, import_react18.useState)((node == null ? void 0 : node.name) ?? "");
|
|
8687
|
+
const [types, setTypes] = (0, import_react18.useState)((node == null ? void 0 : node.type) ? Array.isArray(node.type) ? node.type : [node.type] : ["quest"]);
|
|
8688
|
+
const [typeInput, setTypeInput] = (0, import_react18.useState)("");
|
|
8689
|
+
const [status, setStatus] = (0, import_react18.useState)((node == null ? void 0 : node.status) ?? "Backlog");
|
|
8690
|
+
const [size, setSize] = (0, import_react18.useState)((node == null ? void 0 : node.size) ?? "medium");
|
|
8691
|
+
const [description, setDescription] = (0, import_react18.useState)((node == null ? void 0 : node.description) ?? "");
|
|
8692
|
+
const [intensity, setIntensity] = (0, import_react18.useState)((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
|
|
8693
|
+
const [isStatusDropdownOpen, setIsStatusDropdownOpen] = (0, import_react18.useState)(false);
|
|
8694
|
+
const [customProps, setCustomProps] = (0, import_react18.useState)(() => extractCustomPropsFromNode(node || {}));
|
|
8695
|
+
const [showTypeSuggestions, setShowTypeSuggestions] = (0, import_react18.useState)(false);
|
|
8696
|
+
const [filteredTypes, setFilteredTypes] = (0, import_react18.useState)([]);
|
|
8697
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react18.useState)(false);
|
|
8698
|
+
const [isReadMode, setIsReadMode] = (0, import_react18.useState)(false);
|
|
8699
|
+
const [existingSections, setExistingSections] = (0, import_react18.useState)((node == null ? void 0 : node.description_sections) || []);
|
|
8700
|
+
const [isSaving, setIsSaving] = (0, import_react18.useState)(false);
|
|
8701
|
+
const [isLinkCopied, setIsLinkCopied] = (0, import_react18.useState)(false);
|
|
8702
|
+
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
8703
|
+
const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
|
|
8704
|
+
initialWidth: isReadMode ? 700 : 440,
|
|
8705
|
+
minWidth: 320,
|
|
8706
|
+
maxWidth: maxPanelW
|
|
8707
|
+
});
|
|
8708
|
+
(0, import_react18.useEffect)(() => {
|
|
8709
|
+
setWidth(isReadMode ? 700 : 440);
|
|
8710
|
+
}, [isReadMode, setWidth]);
|
|
8711
|
+
const prevNodeIdRef = (0, import_react18.useRef)(null);
|
|
8712
|
+
const propsEndRef = (0, import_react18.useRef)(null);
|
|
8713
|
+
const canEdit = userRole !== "viewer";
|
|
8714
|
+
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
8715
|
+
const handleImageClickFromText = (url, name2) => {
|
|
8716
|
+
if (onOpenImageViewer) {
|
|
8717
|
+
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
8718
|
+
}
|
|
8719
|
+
};
|
|
8720
|
+
(0, import_react18.useEffect)(() => {
|
|
8721
|
+
if ((node == null ? void 0 : node.id) !== prevNodeIdRef.current) {
|
|
8722
|
+
prevNodeIdRef.current = node == null ? void 0 : node.id;
|
|
8723
|
+
setName((node == null ? void 0 : node.name) ?? "");
|
|
8724
|
+
setTypes((node == null ? void 0 : node.type) ? Array.isArray(node.type) ? node.type : [node.type] : ["quest"]);
|
|
8725
|
+
setStatus((node == null ? void 0 : node.status) ?? "Backlog");
|
|
8726
|
+
setSize((node == null ? void 0 : node.size) ?? "medium");
|
|
8727
|
+
setDescription((node == null ? void 0 : node.description) ?? "");
|
|
8728
|
+
setIntensity((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
|
|
8729
|
+
setExistingSections((node == null ? void 0 : node.description_sections) || []);
|
|
8730
|
+
setCustomProps(extractCustomPropsFromNode(node || {}));
|
|
8731
|
+
}
|
|
8732
|
+
}, [node]);
|
|
8733
|
+
(0, import_react18.useEffect)(() => {
|
|
8734
|
+
if (typeInput.trim() === "") {
|
|
8735
|
+
setFilteredTypes(existingTypes.filter((t) => !types.includes(t)));
|
|
8736
|
+
} else {
|
|
8737
|
+
const lowercasedInput = typeInput.toLowerCase();
|
|
8738
|
+
setFilteredTypes(
|
|
8739
|
+
existingTypes.filter(
|
|
8740
|
+
(t) => t.toLowerCase().includes(lowercasedInput) && !types.includes(t)
|
|
8741
|
+
)
|
|
8742
|
+
);
|
|
8743
|
+
}
|
|
8744
|
+
}, [typeInput, existingTypes, types]);
|
|
8745
|
+
const handleCopyLink = () => {
|
|
8746
|
+
if (!(node == null ? void 0 : node.id)) return;
|
|
8747
|
+
const baseUrl = window.location.origin + window.location.pathname;
|
|
8748
|
+
const fullUrl = `${baseUrl}?focus=${node.id}`;
|
|
8749
|
+
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
8750
|
+
setIsLinkCopied(true);
|
|
8751
|
+
setTimeout(() => setIsLinkCopied(false), 2e3);
|
|
8752
|
+
}).catch((err) => {
|
|
8753
|
+
console.error("Erro ao copiar link:", err);
|
|
8754
|
+
});
|
|
8755
|
+
};
|
|
8756
|
+
const swallow = (e) => e.stopPropagation();
|
|
8757
|
+
const handleNameChange = (e) => {
|
|
8758
|
+
const v = e.target.value;
|
|
8759
|
+
setName(v);
|
|
8760
|
+
onNameChange == null ? void 0 : onNameChange(node.id, v);
|
|
8761
|
+
};
|
|
8762
|
+
const handleSizeChange = (newSize) => {
|
|
8763
|
+
setSize(newSize);
|
|
8764
|
+
onSizeChange == null ? void 0 : onSizeChange(node.id, newSize);
|
|
8765
|
+
};
|
|
8766
|
+
const handleStatusChange = (newStatus) => {
|
|
8767
|
+
setStatus(newStatus);
|
|
8768
|
+
const newColor = QUEST_STATUS_COLORS2[newStatus];
|
|
8769
|
+
onColorChange == null ? void 0 : onColorChange(node.id, newColor);
|
|
8770
|
+
onDataUpdate == null ? void 0 : onDataUpdate({ ...node, status: newStatus, color: newColor });
|
|
8771
|
+
};
|
|
8772
|
+
const handleAddType = (newType) => {
|
|
8773
|
+
const trimmed = newType.trim();
|
|
8774
|
+
if (trimmed && !types.includes(trimmed)) {
|
|
8775
|
+
setTypes([...types, trimmed]);
|
|
8776
|
+
setTypeInput("");
|
|
8777
|
+
setShowTypeSuggestions(false);
|
|
8778
|
+
}
|
|
8779
|
+
};
|
|
8780
|
+
const handleRemoveType = (indexToRemove) => {
|
|
8781
|
+
if (types[indexToRemove] === "quest") return;
|
|
8782
|
+
setTypes(types.filter((_, index) => index !== indexToRemove));
|
|
8783
|
+
};
|
|
8784
|
+
const handleTypeInputKeyDown = (e) => {
|
|
8785
|
+
if (e.key === "Enter") {
|
|
8786
|
+
e.preventDefault();
|
|
8787
|
+
handleAddType(typeInput);
|
|
8788
|
+
} else if (e.key === "Backspace" && typeInput === "" && types.length > 1) {
|
|
8789
|
+
handleRemoveType(types.length - 1);
|
|
8790
|
+
}
|
|
8791
|
+
};
|
|
8792
|
+
const handleAddProp = () => {
|
|
8793
|
+
const newProp = createNewCustomProperty(customProps);
|
|
8794
|
+
setCustomProps((p) => [...p, newProp]);
|
|
8795
|
+
setTimeout(() => {
|
|
8796
|
+
var _a;
|
|
8797
|
+
(_a = propsEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
8798
|
+
}, 100);
|
|
8799
|
+
};
|
|
8800
|
+
const handleRemoveProp = (i) => {
|
|
8801
|
+
const newProps = customProps.filter((_, idx) => idx !== i);
|
|
8802
|
+
setCustomProps(newProps);
|
|
8803
|
+
triggerAutoSave({ customProps: newProps });
|
|
8804
|
+
};
|
|
8805
|
+
const handleUpdateProp = (index, updatedProp) => {
|
|
8806
|
+
const newProps = [...customProps];
|
|
8807
|
+
newProps[index] = updatedProp;
|
|
8808
|
+
setCustomProps(newProps);
|
|
8809
|
+
if (!updatedProp.isEditing) {
|
|
8810
|
+
triggerAutoSave({ customProps: newProps });
|
|
8811
|
+
}
|
|
8812
|
+
};
|
|
8813
|
+
const handleSaveDescriptionInline = (newDescription) => {
|
|
8814
|
+
setDescription(newDescription);
|
|
8815
|
+
onDataUpdate({ ...node, description: newDescription });
|
|
8816
|
+
triggerAutoSave({ description: newDescription });
|
|
8817
|
+
};
|
|
8818
|
+
const handleSave = async (keepOpen = false, overrides = {}) => {
|
|
8819
|
+
const currentName = overrides.name !== void 0 ? overrides.name : name;
|
|
8820
|
+
const currentTypes = overrides.types !== void 0 ? overrides.types : types;
|
|
8821
|
+
const currentDescription = overrides.description !== void 0 ? overrides.description : description;
|
|
8822
|
+
const currentCustomProps = overrides.customProps !== void 0 ? overrides.customProps : customProps;
|
|
8823
|
+
const currentExistingSections = overrides.existingSections !== void 0 ? overrides.existingSections : existingSections;
|
|
8824
|
+
const currentStatus = overrides.status !== void 0 ? overrides.status : status;
|
|
8825
|
+
if (!currentName.trim() || currentTypes.length === 0) {
|
|
8826
|
+
alert("O campo 'Nome' e pelo menos um 'Tipo' s\xE3o obrigat\xF3rios.");
|
|
8827
|
+
return;
|
|
8828
|
+
}
|
|
8829
|
+
setIsSaving(true);
|
|
8830
|
+
try {
|
|
8831
|
+
const extrasObj = toObjectFromCustomProps(currentCustomProps.filter((p) => !p.isEditing));
|
|
8832
|
+
const processedSections = processDescriptionForSave(currentDescription, currentExistingSections);
|
|
8833
|
+
const dataToSave = {
|
|
8834
|
+
id: node.id,
|
|
8835
|
+
name: currentName.trim(),
|
|
8836
|
+
type: currentTypes,
|
|
8837
|
+
color: QUEST_STATUS_COLORS2[currentStatus],
|
|
8838
|
+
status: currentStatus,
|
|
8839
|
+
size,
|
|
8840
|
+
description: currentDescription,
|
|
8841
|
+
description_sections: processedSections,
|
|
8842
|
+
useImageAsTexture: false,
|
|
8843
|
+
textureImageUrl: null,
|
|
8844
|
+
intensity,
|
|
8845
|
+
is_quest: true,
|
|
8846
|
+
...extrasObj,
|
|
8847
|
+
version_node: node.version_node
|
|
8848
|
+
};
|
|
8849
|
+
await onSave(dataToSave, keepOpen);
|
|
8850
|
+
onDataUpdate(dataToSave);
|
|
8851
|
+
if (!keepOpen) {
|
|
8852
|
+
onClose();
|
|
8853
|
+
}
|
|
8854
|
+
} finally {
|
|
8855
|
+
setIsSaving(false);
|
|
8856
|
+
}
|
|
8857
|
+
};
|
|
8858
|
+
const triggerAutoSave = (overrides = {}) => {
|
|
8859
|
+
handleSave(true, overrides);
|
|
8860
|
+
};
|
|
8861
|
+
const handleCancel = () => {
|
|
8862
|
+
if (node) {
|
|
8863
|
+
onNameChange == null ? void 0 : onNameChange(node.id, node.name);
|
|
8864
|
+
onColorChange == null ? void 0 : onColorChange(node.id, node.color);
|
|
8865
|
+
onSizeChange == null ? void 0 : onSizeChange(node.id, node.size || "medium");
|
|
8866
|
+
}
|
|
8867
|
+
onClose();
|
|
8868
|
+
};
|
|
8869
|
+
const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
|
|
8870
|
+
return /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement(
|
|
8871
|
+
"div",
|
|
8872
|
+
{
|
|
8873
|
+
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"}`,
|
|
8874
|
+
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${panelWidth}px`, maxWidth: "92vw" },
|
|
8875
|
+
onPointerDown: swallow,
|
|
8876
|
+
onPointerMove: swallow,
|
|
8877
|
+
onPointerUp: swallow,
|
|
8878
|
+
onClick: swallow,
|
|
8879
|
+
onWheel: swallow,
|
|
8880
|
+
onContextMenu: swallow,
|
|
8881
|
+
onDoubleClick: swallow
|
|
8882
|
+
},
|
|
8883
|
+
/* @__PURE__ */ import_react18.default.createElement("div", { onPointerDown: (e) => {
|
|
8884
|
+
e.stopPropagation();
|
|
8885
|
+
handleResize(e);
|
|
8886
|
+
}, 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" }),
|
|
8887
|
+
isReadMode ? /* @__PURE__ */ import_react18.default.createElement(
|
|
8888
|
+
DescriptionReadModePanel,
|
|
8889
|
+
{
|
|
8890
|
+
title: name || (node == null ? void 0 : node.name),
|
|
8891
|
+
description,
|
|
8892
|
+
savedSections: existingSections,
|
|
8893
|
+
onBack: () => setIsReadMode(false),
|
|
8894
|
+
onEdit: () => {
|
|
8895
|
+
if (canEdit) {
|
|
8896
|
+
setIsReadMode(false);
|
|
8897
|
+
setIsDescriptionModalOpen(true);
|
|
8898
|
+
}
|
|
8899
|
+
},
|
|
8900
|
+
onClose: handleCancel,
|
|
8901
|
+
availableNodes,
|
|
8902
|
+
availableAncestries,
|
|
8903
|
+
onOpenReference,
|
|
8904
|
+
onMentionClick,
|
|
8905
|
+
onImageClick: handleImageClickFromText,
|
|
8906
|
+
onSaveDescription: handleSaveDescriptionInline
|
|
8907
|
+
}
|
|
8908
|
+
) : /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS2[status]}, transparent)` } }), /* @__PURE__ */ import_react18.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react18.default.createElement("div", null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ import_react18.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Quest"), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement(import_fi16.FiCheck, { size: 12 }) : /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiLink, { size: 12 }))), /* @__PURE__ */ import_react18.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ import_react18.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react18.default.createElement(
|
|
8909
|
+
"button",
|
|
8910
|
+
{
|
|
8911
|
+
type: "button",
|
|
8912
|
+
onClick: () => canEdit && setIsStatusDropdownOpen(!isStatusDropdownOpen),
|
|
8913
|
+
disabled: !canEdit,
|
|
8914
|
+
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"}`
|
|
8915
|
+
},
|
|
8916
|
+
/* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("span", { className: "text-slate-200 font-medium" }, status)),
|
|
8917
|
+
canEdit && /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiChevronDown, { className: `text-slate-400 transition-transform duration-200 ${isStatusDropdownOpen ? "rotate-180" : ""}` })
|
|
8918
|
+
), isStatusDropdownOpen && canEdit && /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsStatusDropdownOpen(false) }), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement(
|
|
8919
|
+
"li",
|
|
8920
|
+
{
|
|
8921
|
+
key: s,
|
|
8922
|
+
onClick: () => {
|
|
8923
|
+
handleStatusChange(s);
|
|
8924
|
+
setIsStatusDropdownOpen(false);
|
|
8925
|
+
},
|
|
8926
|
+
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"}`
|
|
8927
|
+
},
|
|
8928
|
+
/* @__PURE__ */ import_react18.default.createElement("span", { className: "w-3 h-3 rounded-full", style: { backgroundColor: QUEST_STATUS_COLORS2[s] } }),
|
|
8929
|
+
s
|
|
8930
|
+
)))))), /* @__PURE__ */ import_react18.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome"), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Tipos Adicionais"), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.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__ */ import_react18.default.createElement("button", { type: "button", onClick: () => handleRemoveType(index), className: "hover:text-white transition-colors" }, /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiX, { size: 12 })))), canEdit && /* @__PURE__ */ import_react18.default.createElement(
|
|
8931
|
+
"input",
|
|
8932
|
+
{
|
|
8933
|
+
type: "text",
|
|
8934
|
+
value: typeInput,
|
|
8935
|
+
onChange: (e) => {
|
|
8936
|
+
setTypeInput(e.target.value);
|
|
8937
|
+
setShowTypeSuggestions(true);
|
|
8938
|
+
},
|
|
8939
|
+
onKeyDown: handleTypeInputKeyDown,
|
|
8940
|
+
onClick: () => setShowTypeSuggestions(true),
|
|
8941
|
+
onBlur: () => {
|
|
8942
|
+
if (typeInput.trim()) {
|
|
8943
|
+
handleAddType(typeInput);
|
|
8944
|
+
}
|
|
8945
|
+
setTimeout(() => setShowTypeSuggestions(false), 150);
|
|
8946
|
+
},
|
|
8947
|
+
className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
|
|
8948
|
+
placeholder: "",
|
|
8949
|
+
autoComplete: "off"
|
|
8950
|
+
}
|
|
8951
|
+
), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("li", { key: index, className: "px-3 py-2 text-sm text-slate-200 cursor-pointer hover:bg-indigo-600/50", onMouseDown: (e) => {
|
|
8952
|
+
e.preventDefault();
|
|
8953
|
+
handleAddType(suggestedType);
|
|
8954
|
+
} }, suggestedType))))), /* @__PURE__ */ import_react18.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement(DescriptionDisplay, { description, savedSections: existingSections, availableNodes, availableAncestries, onOpenReference, onMentionClick, onImageClick: handleImageClickFromText, onSaveDescription: handleSaveDescriptionInline }), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.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__ */ import_react18.default.createElement(import_fi16.FiBookOpen, { size: 14 })), canEdit && /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement(import_fi16.FiEdit2, { size: 14 }))), canEdit && !description && /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
|
|
8955
|
+
const isSelected = size === s;
|
|
8956
|
+
return /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.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__ */ import_react18.default.createElement(import_fi16.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react18.default.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s));
|
|
8957
|
+
}))), /* @__PURE__ */ import_react18.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react18.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement(import_fi16.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ import_react18.default.createElement("div", { className: "pt-3 mt-4 border-t border-white/10 flex items-center justify-end gap-2 text-xs text-slate-400" }, /* @__PURE__ */ import_react18.default.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ import_react18.default.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ import_react18.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react18.default.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement(import_fi16.FiLoader, { className: "animate-spin" }), isSaving ? "Salvando..." : "Salvar Quest")))
|
|
8958
|
+
), isDescriptionModalOpen && canEdit && /* @__PURE__ */ import_react18.default.createElement(
|
|
8959
|
+
DescriptionEditModal,
|
|
8960
|
+
{
|
|
8961
|
+
isOpen: isDescriptionModalOpen,
|
|
8962
|
+
title: "Editar Descri\xE7\xE3o da Quest",
|
|
8963
|
+
initialValue: description,
|
|
8964
|
+
onSave: (newDescription) => {
|
|
8965
|
+
setDescription(newDescription);
|
|
8966
|
+
onDataUpdate((prev) => ({ ...prev, description: newDescription }));
|
|
8967
|
+
triggerAutoSave({ description: newDescription });
|
|
8968
|
+
},
|
|
8969
|
+
onClose: () => setIsDescriptionModalOpen(false),
|
|
8970
|
+
availableNodes,
|
|
8971
|
+
availableAncestries,
|
|
8972
|
+
availableImages
|
|
8973
|
+
}
|
|
8974
|
+
));
|
|
8975
|
+
}
|
|
8976
|
+
|
|
8977
|
+
// src/components/MultiNodeContextMenu.jsx
|
|
8978
|
+
var import_react19 = __toESM(require("react"));
|
|
8659
8979
|
function MultiNodeContextMenu({
|
|
8660
8980
|
data,
|
|
8661
8981
|
userRole,
|
|
@@ -8664,12 +8984,12 @@ function MultiNodeContextMenu({
|
|
|
8664
8984
|
onDismissOtherNodes,
|
|
8665
8985
|
onDeleteNodes
|
|
8666
8986
|
}) {
|
|
8667
|
-
const menuRef = (0,
|
|
8668
|
-
const [menuPos, setMenuPos] = (0,
|
|
8669
|
-
const [isConfirmingDelete, setIsConfirmingDelete] = (0,
|
|
8987
|
+
const menuRef = (0, import_react19.useRef)(null);
|
|
8988
|
+
const [menuPos, setMenuPos] = (0, import_react19.useState)({ left: 0, top: 0 });
|
|
8989
|
+
const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react19.useState)(false);
|
|
8670
8990
|
const ability = defineAbilityFor(userRole);
|
|
8671
8991
|
const canDelete = ability.can("delete", "Node");
|
|
8672
|
-
(0,
|
|
8992
|
+
(0, import_react19.useLayoutEffect)(() => {
|
|
8673
8993
|
if (!data.visible || !menuRef.current) return;
|
|
8674
8994
|
const el = menuRef.current;
|
|
8675
8995
|
const w = el.clientWidth;
|
|
@@ -8682,7 +9002,7 @@ function MultiNodeContextMenu({
|
|
|
8682
9002
|
if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
|
|
8683
9003
|
setMenuPos({ left, top });
|
|
8684
9004
|
}, [data]);
|
|
8685
|
-
(0,
|
|
9005
|
+
(0, import_react19.useEffect)(() => {
|
|
8686
9006
|
if (data.visible) {
|
|
8687
9007
|
setIsConfirmingDelete(false);
|
|
8688
9008
|
}
|
|
@@ -8697,7 +9017,7 @@ function MultiNodeContextMenu({
|
|
|
8697
9017
|
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";
|
|
8698
9018
|
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";
|
|
8699
9019
|
const nodeCount = data.nodeIds.size;
|
|
8700
|
-
return /* @__PURE__ */
|
|
9020
|
+
return /* @__PURE__ */ import_react19.default.createElement(
|
|
8701
9021
|
"div",
|
|
8702
9022
|
{
|
|
8703
9023
|
ref: menuRef,
|
|
@@ -8711,28 +9031,28 @@ function MultiNodeContextMenu({
|
|
|
8711
9031
|
onContextMenu: swallow,
|
|
8712
9032
|
onDoubleClick: swallow
|
|
8713
9033
|
},
|
|
8714
|
-
/* @__PURE__ */
|
|
8715
|
-
/* @__PURE__ */
|
|
9034
|
+
/* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
|
|
9035
|
+
/* @__PURE__ */ import_react19.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ import_react19.default.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react19.default.createElement(
|
|
8716
9036
|
"button",
|
|
8717
9037
|
{
|
|
8718
9038
|
onClick: () => setIsConfirmingDelete(false),
|
|
8719
9039
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
|
|
8720
9040
|
},
|
|
8721
9041
|
"Cancelar"
|
|
8722
|
-
), /* @__PURE__ */
|
|
9042
|
+
), /* @__PURE__ */ import_react19.default.createElement(
|
|
8723
9043
|
"button",
|
|
8724
9044
|
{
|
|
8725
9045
|
onClick: () => onDeleteNodes(data.nodeIds),
|
|
8726
9046
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
|
|
8727
9047
|
},
|
|
8728
9048
|
"Excluir"
|
|
8729
|
-
))) : /* @__PURE__ */
|
|
9049
|
+
))) : /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react19.default.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.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__ */ import_react19.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react19.default.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ import_react19.default.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react19.default.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react19.default.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react19.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react19.default.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
|
|
8730
9050
|
);
|
|
8731
9051
|
}
|
|
8732
9052
|
|
|
8733
9053
|
// src/components/RelationshipDetailsPanel.jsx
|
|
8734
|
-
var
|
|
8735
|
-
var
|
|
9054
|
+
var import_react20 = __toESM(require("react"));
|
|
9055
|
+
var import_fi17 = require("react-icons/fi");
|
|
8736
9056
|
function RelationshipDetailsPanel({
|
|
8737
9057
|
link,
|
|
8738
9058
|
onClose,
|
|
@@ -8746,19 +9066,19 @@ function RelationshipDetailsPanel({
|
|
|
8746
9066
|
onUploadFile,
|
|
8747
9067
|
userRole
|
|
8748
9068
|
}) {
|
|
8749
|
-
const [name, setName] = (0,
|
|
8750
|
-
const [description, setDescription] = (0,
|
|
8751
|
-
const [customProps, setCustomProps] = (0,
|
|
8752
|
-
const [existingSections, setExistingSections] = (0,
|
|
8753
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0,
|
|
8754
|
-
const [isSaving, setIsSaving] = (0,
|
|
8755
|
-
const [isReadMode, setIsReadMode] = (0,
|
|
8756
|
-
const propsEndRef = (0,
|
|
8757
|
-
const canEdit = (0,
|
|
9069
|
+
const [name, setName] = (0, import_react20.useState)((link == null ? void 0 : link.name) ?? "");
|
|
9070
|
+
const [description, setDescription] = (0, import_react20.useState)((link == null ? void 0 : link.description) ?? "");
|
|
9071
|
+
const [customProps, setCustomProps] = (0, import_react20.useState)(() => extractCustomPropsFromNode(link || {}));
|
|
9072
|
+
const [existingSections, setExistingSections] = (0, import_react20.useState)((link == null ? void 0 : link.description_sections) || []);
|
|
9073
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react20.useState)(false);
|
|
9074
|
+
const [isSaving, setIsSaving] = (0, import_react20.useState)(false);
|
|
9075
|
+
const [isReadMode, setIsReadMode] = (0, import_react20.useState)(false);
|
|
9076
|
+
const propsEndRef = (0, import_react20.useRef)(null);
|
|
9077
|
+
const canEdit = (0, import_react20.useMemo)(() => {
|
|
8758
9078
|
const ability = defineAbilityFor(userRole);
|
|
8759
9079
|
return ability.can("update", "Connection");
|
|
8760
9080
|
}, [userRole]);
|
|
8761
|
-
(0,
|
|
9081
|
+
(0, import_react20.useEffect)(() => {
|
|
8762
9082
|
setName((link == null ? void 0 : link.name) ?? "");
|
|
8763
9083
|
setDescription((link == null ? void 0 : link.description) ?? "");
|
|
8764
9084
|
setExistingSections((link == null ? void 0 : link.description_sections) || []);
|
|
@@ -8833,7 +9153,7 @@ function RelationshipDetailsPanel({
|
|
|
8833
9153
|
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
8834
9154
|
}
|
|
8835
9155
|
};
|
|
8836
|
-
return /* @__PURE__ */
|
|
9156
|
+
return /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement(
|
|
8837
9157
|
"div",
|
|
8838
9158
|
{
|
|
8839
9159
|
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
|
|
@@ -8848,7 +9168,7 @@ function RelationshipDetailsPanel({
|
|
|
8848
9168
|
onContextMenu: swallow,
|
|
8849
9169
|
onDoubleClick: swallow
|
|
8850
9170
|
},
|
|
8851
|
-
isReadMode ? /* @__PURE__ */
|
|
9171
|
+
isReadMode ? /* @__PURE__ */ import_react20.default.createElement(
|
|
8852
9172
|
DescriptionReadModePanel,
|
|
8853
9173
|
{
|
|
8854
9174
|
title: name || "Rela\xE7\xE3o",
|
|
@@ -8869,7 +9189,7 @@ function RelationshipDetailsPanel({
|
|
|
8869
9189
|
onImageClick: handleImageClickFromText,
|
|
8870
9190
|
onSaveDescription: handleSaveDescriptionInline
|
|
8871
9191
|
}
|
|
8872
|
-
) : /* @__PURE__ */
|
|
9192
|
+
) : /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ import_react20.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react20.default.createElement("div", null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react20.default.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__ */ import_react20.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ import_react20.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ import_react20.default.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__ */ import_react20.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react20.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react20.default.createElement(
|
|
8873
9193
|
"input",
|
|
8874
9194
|
{
|
|
8875
9195
|
type: "text",
|
|
@@ -8881,7 +9201,7 @@ function RelationshipDetailsPanel({
|
|
|
8881
9201
|
${!canEdit ? "opacity-50 cursor-not-allowed" : ""}
|
|
8882
9202
|
`
|
|
8883
9203
|
}
|
|
8884
|
-
)), /* @__PURE__ */
|
|
9204
|
+
)), /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react20.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react20.default.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__ */ import_react20.default.createElement(
|
|
8885
9205
|
DescriptionDisplay,
|
|
8886
9206
|
{
|
|
8887
9207
|
description,
|
|
@@ -8893,7 +9213,7 @@ function RelationshipDetailsPanel({
|
|
|
8893
9213
|
onImageClick: handleImageClickFromText,
|
|
8894
9214
|
onSaveDescription: handleSaveDescriptionInline
|
|
8895
9215
|
}
|
|
8896
|
-
), /* @__PURE__ */
|
|
9216
|
+
), /* @__PURE__ */ import_react20.default.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__ */ import_react20.default.createElement(
|
|
8897
9217
|
"button",
|
|
8898
9218
|
{
|
|
8899
9219
|
type: "button",
|
|
@@ -8901,8 +9221,8 @@ function RelationshipDetailsPanel({
|
|
|
8901
9221
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors border-r border-white/5",
|
|
8902
9222
|
title: "Modo de Leitura"
|
|
8903
9223
|
},
|
|
8904
|
-
/* @__PURE__ */
|
|
8905
|
-
), canEdit && /* @__PURE__ */
|
|
9224
|
+
/* @__PURE__ */ import_react20.default.createElement(import_fi17.FiBookOpen, { size: 14 })
|
|
9225
|
+
), canEdit && /* @__PURE__ */ import_react20.default.createElement(
|
|
8906
9226
|
"button",
|
|
8907
9227
|
{
|
|
8908
9228
|
type: "button",
|
|
@@ -8910,15 +9230,15 @@ function RelationshipDetailsPanel({
|
|
|
8910
9230
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8911
9231
|
title: "Editar descri\xE7\xE3o"
|
|
8912
9232
|
},
|
|
8913
|
-
/* @__PURE__ */
|
|
8914
|
-
)), !description && canEdit && /* @__PURE__ */
|
|
9233
|
+
/* @__PURE__ */ import_react20.default.createElement(import_fi17.FiEdit2, { size: 14 })
|
|
9234
|
+
)), !description && canEdit && /* @__PURE__ */ import_react20.default.createElement(
|
|
8915
9235
|
"div",
|
|
8916
9236
|
{
|
|
8917
9237
|
onClick: () => setIsDescriptionModalOpen(true),
|
|
8918
9238
|
className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
|
|
8919
9239
|
},
|
|
8920
9240
|
"Adicionar descri\xE7\xE3o..."
|
|
8921
|
-
))), /* @__PURE__ */
|
|
9241
|
+
))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react20.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react20.default.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__ */ import_react20.default.createElement(import_fi17.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react20.default.createElement(
|
|
8922
9242
|
CustomPropertyDisplay,
|
|
8923
9243
|
{
|
|
8924
9244
|
key: prop.id,
|
|
@@ -8930,7 +9250,7 @@ function RelationshipDetailsPanel({
|
|
|
8930
9250
|
onUploadFile,
|
|
8931
9251
|
disabled: !canEdit
|
|
8932
9252
|
}
|
|
8933
|
-
)), /* @__PURE__ */
|
|
9253
|
+
)), /* @__PURE__ */ import_react20.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react20.default.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__ */ import_react20.default.createElement(
|
|
8934
9254
|
"button",
|
|
8935
9255
|
{
|
|
8936
9256
|
onClick: () => handleSave(false),
|
|
@@ -8939,10 +9259,10 @@ function RelationshipDetailsPanel({
|
|
|
8939
9259
|
${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"}
|
|
8940
9260
|
`
|
|
8941
9261
|
},
|
|
8942
|
-
isSaving && /* @__PURE__ */
|
|
9262
|
+
isSaving && /* @__PURE__ */ import_react20.default.createElement(import_fi17.FiLoader, { className: "animate-spin" }),
|
|
8943
9263
|
isSaving ? "Salvando..." : "Salvar"
|
|
8944
9264
|
)))
|
|
8945
|
-
), isDescriptionModalOpen && /* @__PURE__ */
|
|
9265
|
+
), isDescriptionModalOpen && /* @__PURE__ */ import_react20.default.createElement(
|
|
8946
9266
|
DescriptionEditModal,
|
|
8947
9267
|
{
|
|
8948
9268
|
isOpen: isDescriptionModalOpen,
|
|
@@ -8963,7 +9283,7 @@ function RelationshipDetailsPanel({
|
|
|
8963
9283
|
}
|
|
8964
9284
|
|
|
8965
9285
|
// src/components/RelationshipContextMenu.jsx
|
|
8966
|
-
var
|
|
9286
|
+
var import_react21 = __toESM(require("react"));
|
|
8967
9287
|
function RelationshipContextMenu({
|
|
8968
9288
|
data,
|
|
8969
9289
|
userRole,
|
|
@@ -8973,25 +9293,25 @@ function RelationshipContextMenu({
|
|
|
8973
9293
|
onDelete,
|
|
8974
9294
|
onClose
|
|
8975
9295
|
}) {
|
|
8976
|
-
const menuRef = (0,
|
|
8977
|
-
const [menuPos, setMenuPos] = (0,
|
|
8978
|
-
const [isConfirmingDelete, setIsConfirmingDelete] = (0,
|
|
8979
|
-
const ability = (0,
|
|
8980
|
-
const sourceName = (0,
|
|
9296
|
+
const menuRef = (0, import_react21.useRef)(null);
|
|
9297
|
+
const [menuPos, setMenuPos] = (0, import_react21.useState)({ left: 0, top: 0 });
|
|
9298
|
+
const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react21.useState)(false);
|
|
9299
|
+
const ability = (0, import_react21.useMemo)(() => defineAbilityFor(userRole), [userRole]);
|
|
9300
|
+
const sourceName = (0, import_react21.useMemo)(
|
|
8981
9301
|
() => {
|
|
8982
9302
|
var _a, _b, _c, _d;
|
|
8983
9303
|
return ((_d = (_c = (_b = (_a = data == null ? void 0 : data.linkObject) == null ? void 0 : _a.userData) == null ? void 0 : _b.sourceNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) ?? "(sem nome)";
|
|
8984
9304
|
},
|
|
8985
9305
|
[data == null ? void 0 : data.linkObject]
|
|
8986
9306
|
);
|
|
8987
|
-
const targetName = (0,
|
|
9307
|
+
const targetName = (0, import_react21.useMemo)(
|
|
8988
9308
|
() => {
|
|
8989
9309
|
var _a, _b, _c, _d;
|
|
8990
9310
|
return ((_d = (_c = (_b = (_a = data == null ? void 0 : data.linkObject) == null ? void 0 : _a.userData) == null ? void 0 : _b.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) ?? "(sem nome)";
|
|
8991
9311
|
},
|
|
8992
9312
|
[data == null ? void 0 : data.linkObject]
|
|
8993
9313
|
);
|
|
8994
|
-
(0,
|
|
9314
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
8995
9315
|
if (!data.visible || !menuRef.current) return;
|
|
8996
9316
|
const el = menuRef.current;
|
|
8997
9317
|
const w = el.clientWidth;
|
|
@@ -9004,7 +9324,7 @@ function RelationshipContextMenu({
|
|
|
9004
9324
|
if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
|
|
9005
9325
|
setMenuPos({ left, top });
|
|
9006
9326
|
}, [data]);
|
|
9007
|
-
(0,
|
|
9327
|
+
(0, import_react21.useEffect)(() => {
|
|
9008
9328
|
if (data.visible) {
|
|
9009
9329
|
setIsConfirmingDelete(false);
|
|
9010
9330
|
}
|
|
@@ -9020,7 +9340,7 @@ function RelationshipContextMenu({
|
|
|
9020
9340
|
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";
|
|
9021
9341
|
const canUpdate = ability.can("update", "Connection");
|
|
9022
9342
|
const canDelete = ability.can("delete", "Connection");
|
|
9023
|
-
return /* @__PURE__ */
|
|
9343
|
+
return /* @__PURE__ */ import_react21.default.createElement(
|
|
9024
9344
|
"div",
|
|
9025
9345
|
{
|
|
9026
9346
|
ref: menuRef,
|
|
@@ -9034,29 +9354,29 @@ function RelationshipContextMenu({
|
|
|
9034
9354
|
onContextMenu: swallow,
|
|
9035
9355
|
onDoubleClick: swallow
|
|
9036
9356
|
},
|
|
9037
|
-
/* @__PURE__ */
|
|
9038
|
-
/* @__PURE__ */
|
|
9357
|
+
/* @__PURE__ */ import_react21.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
|
|
9358
|
+
/* @__PURE__ */ import_react21.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react21.default.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ import_react21.default.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__ */ import_react21.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react21.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ import_react21.default.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ import_react21.default.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ import_react21.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ import_react21.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ import_react21.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ import_react21.default.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ import_react21.default.createElement("strong", null, targetName), ".")), /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react21.default.createElement(
|
|
9039
9359
|
"button",
|
|
9040
9360
|
{
|
|
9041
9361
|
onClick: () => setIsConfirmingDelete(false),
|
|
9042
9362
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
|
|
9043
9363
|
},
|
|
9044
9364
|
"Cancelar"
|
|
9045
|
-
), /* @__PURE__ */
|
|
9365
|
+
), /* @__PURE__ */ import_react21.default.createElement(
|
|
9046
9366
|
"button",
|
|
9047
9367
|
{
|
|
9048
9368
|
onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
|
|
9049
9369
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-rose-600 hover:bg-rose-500 rounded-md text-white transition-colors"
|
|
9050
9370
|
},
|
|
9051
9371
|
"Excluir"
|
|
9052
|
-
))) : /* @__PURE__ */
|
|
9372
|
+
))) : /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react21.default.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__ */ import_react21.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement(
|
|
9053
9373
|
"button",
|
|
9054
9374
|
{
|
|
9055
9375
|
onClick: () => onRelinkSource == null ? void 0 : onRelinkSource(data.linkObject),
|
|
9056
9376
|
className: baseButtonClass,
|
|
9057
9377
|
title: "Desconectar ponta ligada ao Source"
|
|
9058
9378
|
},
|
|
9059
|
-
/* @__PURE__ */
|
|
9379
|
+
/* @__PURE__ */ import_react21.default.createElement(
|
|
9060
9380
|
"svg",
|
|
9061
9381
|
{
|
|
9062
9382
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -9069,18 +9389,18 @@ function RelationshipContextMenu({
|
|
|
9069
9389
|
strokeLinecap: "round",
|
|
9070
9390
|
strokeLinejoin: "round"
|
|
9071
9391
|
},
|
|
9072
|
-
/* @__PURE__ */
|
|
9073
|
-
/* @__PURE__ */
|
|
9392
|
+
/* @__PURE__ */ import_react21.default.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" }),
|
|
9393
|
+
/* @__PURE__ */ import_react21.default.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" })
|
|
9074
9394
|
),
|
|
9075
|
-
/* @__PURE__ */
|
|
9076
|
-
), /* @__PURE__ */
|
|
9395
|
+
/* @__PURE__ */ import_react21.default.createElement("span", null, "Desconectar Source (", sourceName, ")")
|
|
9396
|
+
), /* @__PURE__ */ import_react21.default.createElement(
|
|
9077
9397
|
"button",
|
|
9078
9398
|
{
|
|
9079
9399
|
onClick: () => onRelinkTarget == null ? void 0 : onRelinkTarget(data.linkObject),
|
|
9080
9400
|
className: baseButtonClass,
|
|
9081
9401
|
title: "Desconectar ponta ligada ao Target"
|
|
9082
9402
|
},
|
|
9083
|
-
/* @__PURE__ */
|
|
9403
|
+
/* @__PURE__ */ import_react21.default.createElement(
|
|
9084
9404
|
"svg",
|
|
9085
9405
|
{
|
|
9086
9406
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -9093,21 +9413,21 @@ function RelationshipContextMenu({
|
|
|
9093
9413
|
strokeLinecap: "round",
|
|
9094
9414
|
strokeLinejoin: "round"
|
|
9095
9415
|
},
|
|
9096
|
-
/* @__PURE__ */
|
|
9097
|
-
/* @__PURE__ */
|
|
9098
|
-
/* @__PURE__ */
|
|
9099
|
-
/* @__PURE__ */
|
|
9100
|
-
/* @__PURE__ */
|
|
9416
|
+
/* @__PURE__ */ import_react21.default.createElement("polyline", { points: "16 3 21 3 21 8" }),
|
|
9417
|
+
/* @__PURE__ */ import_react21.default.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
|
|
9418
|
+
/* @__PURE__ */ import_react21.default.createElement("polyline", { points: "21 16 21 21 16 21" }),
|
|
9419
|
+
/* @__PURE__ */ import_react21.default.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
|
|
9420
|
+
/* @__PURE__ */ import_react21.default.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
|
|
9101
9421
|
),
|
|
9102
|
-
/* @__PURE__ */
|
|
9103
|
-
), /* @__PURE__ */
|
|
9422
|
+
/* @__PURE__ */ import_react21.default.createElement("span", null, "Desconectar Target (", targetName, ")")
|
|
9423
|
+
), /* @__PURE__ */ import_react21.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ import_react21.default.createElement(
|
|
9104
9424
|
"button",
|
|
9105
9425
|
{
|
|
9106
9426
|
onClick: () => onOpenDetails == null ? void 0 : onOpenDetails(data.linkObject),
|
|
9107
9427
|
className: baseButtonClass,
|
|
9108
9428
|
title: "Abrir detalhes da rela\xE7\xE3o"
|
|
9109
9429
|
},
|
|
9110
|
-
/* @__PURE__ */
|
|
9430
|
+
/* @__PURE__ */ import_react21.default.createElement(
|
|
9111
9431
|
"svg",
|
|
9112
9432
|
{
|
|
9113
9433
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -9120,19 +9440,19 @@ function RelationshipContextMenu({
|
|
|
9120
9440
|
strokeLinecap: "round",
|
|
9121
9441
|
strokeLinejoin: "round"
|
|
9122
9442
|
},
|
|
9123
|
-
/* @__PURE__ */
|
|
9124
|
-
/* @__PURE__ */
|
|
9125
|
-
/* @__PURE__ */
|
|
9443
|
+
/* @__PURE__ */ import_react21.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
9444
|
+
/* @__PURE__ */ import_react21.default.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
9445
|
+
/* @__PURE__ */ import_react21.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
|
|
9126
9446
|
),
|
|
9127
|
-
/* @__PURE__ */
|
|
9128
|
-
), canDelete && /* @__PURE__ */
|
|
9447
|
+
/* @__PURE__ */ import_react21.default.createElement("span", null, "Abrir Detalhes")
|
|
9448
|
+
), canDelete && /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ import_react21.default.createElement(
|
|
9129
9449
|
"button",
|
|
9130
9450
|
{
|
|
9131
9451
|
onClick: () => setIsConfirmingDelete(true),
|
|
9132
9452
|
className: dangerButtonClass,
|
|
9133
9453
|
title: "Excluir esta conex\xE3o"
|
|
9134
9454
|
},
|
|
9135
|
-
/* @__PURE__ */
|
|
9455
|
+
/* @__PURE__ */ import_react21.default.createElement(
|
|
9136
9456
|
"svg",
|
|
9137
9457
|
{
|
|
9138
9458
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -9145,19 +9465,19 @@ function RelationshipContextMenu({
|
|
|
9145
9465
|
strokeLinecap: "round",
|
|
9146
9466
|
strokeLinejoin: "round"
|
|
9147
9467
|
},
|
|
9148
|
-
/* @__PURE__ */
|
|
9149
|
-
/* @__PURE__ */
|
|
9150
|
-
/* @__PURE__ */
|
|
9151
|
-
/* @__PURE__ */
|
|
9152
|
-
/* @__PURE__ */
|
|
9468
|
+
/* @__PURE__ */ import_react21.default.createElement("polyline", { points: "3 6 5 6 21 6" }),
|
|
9469
|
+
/* @__PURE__ */ import_react21.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
|
|
9470
|
+
/* @__PURE__ */ import_react21.default.createElement("path", { d: "M10 11v6" }),
|
|
9471
|
+
/* @__PURE__ */ import_react21.default.createElement("path", { d: "M14 11v6" }),
|
|
9472
|
+
/* @__PURE__ */ import_react21.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
|
|
9153
9473
|
),
|
|
9154
|
-
/* @__PURE__ */
|
|
9474
|
+
/* @__PURE__ */ import_react21.default.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
|
|
9155
9475
|
)))))
|
|
9156
9476
|
);
|
|
9157
9477
|
}
|
|
9158
9478
|
|
|
9159
9479
|
// src/components/LoadingScreen.jsx
|
|
9160
|
-
var
|
|
9480
|
+
var import_react22 = __toESM(require("react"));
|
|
9161
9481
|
var styles = {
|
|
9162
9482
|
loadingOverlay: {
|
|
9163
9483
|
position: "fixed",
|
|
@@ -9189,11 +9509,11 @@ var styles = {
|
|
|
9189
9509
|
`
|
|
9190
9510
|
};
|
|
9191
9511
|
function LoadingScreen() {
|
|
9192
|
-
return /* @__PURE__ */
|
|
9512
|
+
return /* @__PURE__ */ import_react22.default.createElement(import_react22.default.Fragment, null, /* @__PURE__ */ import_react22.default.createElement("style", null, styles.keyframes), /* @__PURE__ */ import_react22.default.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ import_react22.default.createElement("div", { style: styles.spinner })));
|
|
9193
9513
|
}
|
|
9194
9514
|
|
|
9195
9515
|
// src/components/ImportParentFileModal.jsx
|
|
9196
|
-
var
|
|
9516
|
+
var import_react23 = __toESM(require("react"));
|
|
9197
9517
|
function ImportParentFileModal({
|
|
9198
9518
|
isOpen,
|
|
9199
9519
|
onClose,
|
|
@@ -9204,12 +9524,12 @@ function ImportParentFileModal({
|
|
|
9204
9524
|
onFetchAvailableFiles,
|
|
9205
9525
|
currentViewName
|
|
9206
9526
|
}) {
|
|
9207
|
-
const [activeTab, setActiveTab] = (0,
|
|
9208
|
-
const [availableDbs, setAvailableDbs] = (0,
|
|
9209
|
-
const [availableViews, setAvailableViews] = (0,
|
|
9210
|
-
const [selectedItem, setSelectedItem] = (0,
|
|
9211
|
-
const [isLoading, setIsLoading] = (0,
|
|
9212
|
-
(0,
|
|
9527
|
+
const [activeTab, setActiveTab] = (0, import_react23.useState)("databases");
|
|
9528
|
+
const [availableDbs, setAvailableDbs] = (0, import_react23.useState)([]);
|
|
9529
|
+
const [availableViews, setAvailableViews] = (0, import_react23.useState)([]);
|
|
9530
|
+
const [selectedItem, setSelectedItem] = (0, import_react23.useState)(null);
|
|
9531
|
+
const [isLoading, setIsLoading] = (0, import_react23.useState)(false);
|
|
9532
|
+
(0, import_react23.useEffect)(() => {
|
|
9213
9533
|
if (isOpen && session && onFetchAvailableFiles) {
|
|
9214
9534
|
const fetchData = async () => {
|
|
9215
9535
|
setIsLoading(true);
|
|
@@ -9245,7 +9565,7 @@ function ImportParentFileModal({
|
|
|
9245
9565
|
fetchData();
|
|
9246
9566
|
}
|
|
9247
9567
|
}, [isOpen, session, parentDbs, onFetchAvailableFiles, currentViewName]);
|
|
9248
|
-
(0,
|
|
9568
|
+
(0, import_react23.useEffect)(() => {
|
|
9249
9569
|
setSelectedItem(null);
|
|
9250
9570
|
}, [activeTab]);
|
|
9251
9571
|
if (!isOpen) {
|
|
@@ -9274,13 +9594,13 @@ function ImportParentFileModal({
|
|
|
9274
9594
|
const swallow = (e) => e.stopPropagation();
|
|
9275
9595
|
const currentList = activeTab === "databases" ? availableDbs : availableViews;
|
|
9276
9596
|
const emptyMessage = activeTab === "databases" ? "Nenhum novo arquivo parent dispon\xEDvel." : "Nenhuma view dispon\xEDvel para importa\xE7\xE3o.";
|
|
9277
|
-
return /* @__PURE__ */
|
|
9597
|
+
return /* @__PURE__ */ import_react23.default.createElement(
|
|
9278
9598
|
"div",
|
|
9279
9599
|
{
|
|
9280
9600
|
className: "ui-overlay fixed inset-0 z-[1200] flex items-center justify-center bg-black/60 backdrop-blur-sm",
|
|
9281
9601
|
onClick: onClose
|
|
9282
9602
|
},
|
|
9283
|
-
/* @__PURE__ */
|
|
9603
|
+
/* @__PURE__ */ import_react23.default.createElement(
|
|
9284
9604
|
"div",
|
|
9285
9605
|
{
|
|
9286
9606
|
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]",
|
|
@@ -9292,14 +9612,14 @@ function ImportParentFileModal({
|
|
|
9292
9612
|
onContextMenu: swallow,
|
|
9293
9613
|
onDoubleClick: swallow
|
|
9294
9614
|
},
|
|
9295
|
-
/* @__PURE__ */
|
|
9615
|
+
/* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ import_react23.default.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ import_react23.default.createElement(
|
|
9296
9616
|
"button",
|
|
9297
9617
|
{
|
|
9298
9618
|
onClick: onClose,
|
|
9299
9619
|
className: "p-2 rounded-md text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
9300
9620
|
title: "Fechar"
|
|
9301
9621
|
},
|
|
9302
|
-
/* @__PURE__ */
|
|
9622
|
+
/* @__PURE__ */ import_react23.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react23.default.createElement(
|
|
9303
9623
|
"path",
|
|
9304
9624
|
{
|
|
9305
9625
|
fillRule: "evenodd",
|
|
@@ -9308,14 +9628,14 @@ function ImportParentFileModal({
|
|
|
9308
9628
|
}
|
|
9309
9629
|
))
|
|
9310
9630
|
)),
|
|
9311
|
-
/* @__PURE__ */
|
|
9631
|
+
/* @__PURE__ */ import_react23.default.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ import_react23.default.createElement(
|
|
9312
9632
|
"button",
|
|
9313
9633
|
{
|
|
9314
9634
|
onClick: () => setActiveTab("databases"),
|
|
9315
9635
|
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"}`
|
|
9316
9636
|
},
|
|
9317
9637
|
"Arquivos Parent"
|
|
9318
|
-
), /* @__PURE__ */
|
|
9638
|
+
), /* @__PURE__ */ import_react23.default.createElement(
|
|
9319
9639
|
"button",
|
|
9320
9640
|
{
|
|
9321
9641
|
onClick: () => setActiveTab("views"),
|
|
@@ -9323,24 +9643,24 @@ function ImportParentFileModal({
|
|
|
9323
9643
|
},
|
|
9324
9644
|
"Views (Ancestralidades)"
|
|
9325
9645
|
)),
|
|
9326
|
-
/* @__PURE__ */
|
|
9646
|
+
/* @__PURE__ */ import_react23.default.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ import_react23.default.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ import_react23.default.createElement(
|
|
9327
9647
|
"div",
|
|
9328
9648
|
{
|
|
9329
9649
|
key: item.id,
|
|
9330
9650
|
onClick: () => setSelectedItem(item),
|
|
9331
9651
|
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"}`
|
|
9332
9652
|
},
|
|
9333
|
-
/* @__PURE__ */
|
|
9334
|
-
item.description && /* @__PURE__ */
|
|
9335
|
-
)) : /* @__PURE__ */
|
|
9336
|
-
/* @__PURE__ */
|
|
9653
|
+
/* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react23.default.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ import_react23.default.createElement("span", { className: "text-[10px] px-1.5 py-0.5 rounded bg-black/30 text-indigo-300 border border-indigo-500/30" }, "VIEW")),
|
|
9654
|
+
item.description && /* @__PURE__ */ import_react23.default.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
|
|
9655
|
+
)) : /* @__PURE__ */ import_react23.default.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
|
|
9656
|
+
/* @__PURE__ */ import_react23.default.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__ */ import_react23.default.createElement(
|
|
9337
9657
|
"button",
|
|
9338
9658
|
{
|
|
9339
9659
|
onClick: onClose,
|
|
9340
9660
|
className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm text-slate-300"
|
|
9341
9661
|
},
|
|
9342
9662
|
"Cancelar"
|
|
9343
|
-
), /* @__PURE__ */
|
|
9663
|
+
), /* @__PURE__ */ import_react23.default.createElement(
|
|
9344
9664
|
"button",
|
|
9345
9665
|
{
|
|
9346
9666
|
onClick: handleConfirm,
|
|
@@ -9354,8 +9674,8 @@ function ImportParentFileModal({
|
|
|
9354
9674
|
}
|
|
9355
9675
|
|
|
9356
9676
|
// src/components/AncestryLinkDetailsPanel.jsx
|
|
9357
|
-
var
|
|
9358
|
-
var
|
|
9677
|
+
var import_react24 = __toESM(require("react"));
|
|
9678
|
+
var import_fi18 = require("react-icons/fi");
|
|
9359
9679
|
function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
|
|
9360
9680
|
var _a, _b, _c, _d;
|
|
9361
9681
|
const relationshipData = data.relationship || {};
|
|
@@ -9364,21 +9684,21 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9364
9684
|
const customProps = extractCustomPropsFromNode(relationshipData);
|
|
9365
9685
|
const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
|
|
9366
9686
|
const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
|
|
9367
|
-
const [isReadMode, setIsReadMode] = (0,
|
|
9687
|
+
const [isReadMode, setIsReadMode] = (0, import_react24.useState)(false);
|
|
9368
9688
|
const swallow = (e) => e.stopPropagation();
|
|
9369
9689
|
const handleImageClickFromText = (url, name) => {
|
|
9370
9690
|
if (onOpenImageViewer) {
|
|
9371
9691
|
onOpenImageViewer([{ name: name || "Imagem", value: url }], 0);
|
|
9372
9692
|
}
|
|
9373
9693
|
};
|
|
9374
|
-
return /* @__PURE__ */
|
|
9694
|
+
return /* @__PURE__ */ import_react24.default.createElement(
|
|
9375
9695
|
"div",
|
|
9376
9696
|
{
|
|
9377
9697
|
className: "ui-overlay fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[1200]",
|
|
9378
9698
|
onClick: onClose,
|
|
9379
9699
|
onPointerDown: swallow
|
|
9380
9700
|
},
|
|
9381
|
-
/* @__PURE__ */
|
|
9701
|
+
/* @__PURE__ */ import_react24.default.createElement(
|
|
9382
9702
|
"div",
|
|
9383
9703
|
{
|
|
9384
9704
|
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
|
|
@@ -9386,7 +9706,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9386
9706
|
`,
|
|
9387
9707
|
onClick: swallow
|
|
9388
9708
|
},
|
|
9389
|
-
isReadMode ? /* @__PURE__ */
|
|
9709
|
+
isReadMode ? /* @__PURE__ */ import_react24.default.createElement(
|
|
9390
9710
|
DescriptionReadModePanel,
|
|
9391
9711
|
{
|
|
9392
9712
|
title: `${sourceName} \u2794 ${targetName}`,
|
|
@@ -9398,15 +9718,15 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9398
9718
|
onMentionClick,
|
|
9399
9719
|
onImageClick: handleImageClickFromText
|
|
9400
9720
|
}
|
|
9401
|
-
) : /* @__PURE__ */
|
|
9721
|
+
) : /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ import_react24.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react24.default.createElement("div", null, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ import_react24.default.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ import_react24.default.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ import_react24.default.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ import_react24.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react24.default.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react24.default.createElement(
|
|
9402
9722
|
"button",
|
|
9403
9723
|
{
|
|
9404
9724
|
onClick: () => setIsReadMode(true),
|
|
9405
9725
|
className: "p-1 text-slate-400 hover:text-white transition-colors",
|
|
9406
9726
|
title: "Modo de Leitura"
|
|
9407
9727
|
},
|
|
9408
|
-
/* @__PURE__ */
|
|
9409
|
-
)), /* @__PURE__ */
|
|
9728
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiBookOpen, { size: 14 })
|
|
9729
|
+
)), /* @__PURE__ */ import_react24.default.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ import_react24.default.createElement(
|
|
9410
9730
|
DescriptionDisplay,
|
|
9411
9731
|
{
|
|
9412
9732
|
description,
|
|
@@ -9415,7 +9735,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9415
9735
|
onMentionClick,
|
|
9416
9736
|
onImageClick: handleImageClickFromText
|
|
9417
9737
|
}
|
|
9418
|
-
))), customProps.length > 0 && /* @__PURE__ */
|
|
9738
|
+
))), customProps.length > 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react24.default.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ import_react24.default.createElement(
|
|
9419
9739
|
CustomPropertyDisplay,
|
|
9420
9740
|
{
|
|
9421
9741
|
key: prop.id,
|
|
@@ -9424,14 +9744,14 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9424
9744
|
onOpenImageViewer,
|
|
9425
9745
|
onUploadFile
|
|
9426
9746
|
}
|
|
9427
|
-
)))), !description && customProps.length === 0 && /* @__PURE__ */
|
|
9747
|
+
)))), !description && customProps.length === 0 && /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.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".')))
|
|
9428
9748
|
)
|
|
9429
9749
|
);
|
|
9430
9750
|
}
|
|
9431
9751
|
|
|
9432
9752
|
// src/components/AncestryBoard.jsx
|
|
9433
|
-
var
|
|
9434
|
-
var
|
|
9753
|
+
var import_react25 = __toESM(require("react"));
|
|
9754
|
+
var import_fi19 = require("react-icons/fi");
|
|
9435
9755
|
var GroupItem = ({
|
|
9436
9756
|
group,
|
|
9437
9757
|
index,
|
|
@@ -9451,7 +9771,7 @@ var GroupItem = ({
|
|
|
9451
9771
|
}) => {
|
|
9452
9772
|
const canIndent = index > 0;
|
|
9453
9773
|
const isPickingForThisGroup = pickingGroupId === group.id;
|
|
9454
|
-
const textareaRef = (0,
|
|
9774
|
+
const textareaRef = (0, import_react25.useRef)(null);
|
|
9455
9775
|
const adjustHeight = () => {
|
|
9456
9776
|
const textarea = textareaRef.current;
|
|
9457
9777
|
if (textarea) {
|
|
@@ -9459,13 +9779,13 @@ var GroupItem = ({
|
|
|
9459
9779
|
textarea.style.height = `${textarea.scrollHeight}px`;
|
|
9460
9780
|
}
|
|
9461
9781
|
};
|
|
9462
|
-
(0,
|
|
9782
|
+
(0, import_react25.useEffect)(() => {
|
|
9463
9783
|
adjustHeight();
|
|
9464
9784
|
}, [group.text]);
|
|
9465
|
-
return /* @__PURE__ */
|
|
9785
|
+
return /* @__PURE__ */ import_react25.default.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__ */ import_react25.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react25.default.createElement("div", { className: `
|
|
9466
9786
|
flex flex-col gap-2 py-2 px-3 transition-all duration-200
|
|
9467
9787
|
${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__ */
|
|
9788
|
+
` }, /* @__PURE__ */ import_react25.default.createElement(
|
|
9469
9789
|
"textarea",
|
|
9470
9790
|
{
|
|
9471
9791
|
ref: textareaRef,
|
|
@@ -9482,9 +9802,9 @@ var GroupItem = ({
|
|
|
9482
9802
|
if (canEdit) onUpdate(group.id, { ...group, text: e.target.value });
|
|
9483
9803
|
}
|
|
9484
9804
|
}
|
|
9485
|
-
), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */
|
|
9805
|
+
), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
|
|
9486
9806
|
const isValid = availableIds.has(String(anc.ancestry_id));
|
|
9487
|
-
return /* @__PURE__ */
|
|
9807
|
+
return /* @__PURE__ */ import_react25.default.createElement(
|
|
9488
9808
|
"div",
|
|
9489
9809
|
{
|
|
9490
9810
|
key: anc.ancestry_id,
|
|
@@ -9496,28 +9816,28 @@ var GroupItem = ({
|
|
|
9496
9816
|
},
|
|
9497
9817
|
isValid ? (
|
|
9498
9818
|
// [MANTIDO] Botão Play visível para todos
|
|
9499
|
-
/* @__PURE__ */
|
|
9819
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
9500
9820
|
"button",
|
|
9501
9821
|
{
|
|
9502
9822
|
onClick: () => onPlayAncestry(anc.ancestry_id),
|
|
9503
9823
|
className: "text-indigo-400 hover:text-white hover:bg-indigo-500 p-1 rounded-full transition-colors",
|
|
9504
9824
|
title: "Renderizar no cen\xE1rio"
|
|
9505
9825
|
},
|
|
9506
|
-
/* @__PURE__ */
|
|
9826
|
+
/* @__PURE__ */ import_react25.default.createElement(import_fi19.FiPlay, { size: 10, className: "ml-0.5 fill-current" })
|
|
9507
9827
|
)
|
|
9508
|
-
) : /* @__PURE__ */
|
|
9509
|
-
/* @__PURE__ */
|
|
9510
|
-
canEdit && /* @__PURE__ */
|
|
9828
|
+
) : /* @__PURE__ */ import_react25.default.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiAlertTriangle, { size: 10 })),
|
|
9829
|
+
/* @__PURE__ */ import_react25.default.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
|
|
9830
|
+
canEdit && /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, /* @__PURE__ */ import_react25.default.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ import_react25.default.createElement(
|
|
9511
9831
|
"button",
|
|
9512
9832
|
{
|
|
9513
9833
|
onClick: () => onRemoveAncestry(group.id, anc.ancestry_id),
|
|
9514
9834
|
className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
|
|
9515
9835
|
title: "Remover men\xE7\xE3o"
|
|
9516
9836
|
},
|
|
9517
|
-
/* @__PURE__ */
|
|
9837
|
+
/* @__PURE__ */ import_react25.default.createElement(import_fi19.FiX, { size: 12 })
|
|
9518
9838
|
))
|
|
9519
9839
|
);
|
|
9520
|
-
})), canEdit && /* @__PURE__ */
|
|
9840
|
+
})), canEdit && /* @__PURE__ */ import_react25.default.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__ */ import_react25.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react25.default.createElement(
|
|
9521
9841
|
"button",
|
|
9522
9842
|
{
|
|
9523
9843
|
onClick: () => onRequestPickAncestry(group.id),
|
|
@@ -9527,17 +9847,17 @@ var GroupItem = ({
|
|
|
9527
9847
|
`,
|
|
9528
9848
|
title: "Adicionar Ancestralidade a este grupo"
|
|
9529
9849
|
},
|
|
9530
|
-
isPickingForThisGroup ? /* @__PURE__ */
|
|
9850
|
+
isPickingForThisGroup ? /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiCheckCircle, { size: 12 }) : /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiSearch, { size: 12 }),
|
|
9531
9851
|
isPickingForThisGroup ? "Selecionando..." : "Adicionar"
|
|
9532
|
-
), /* @__PURE__ */
|
|
9852
|
+
), /* @__PURE__ */ import_react25.default.createElement(
|
|
9533
9853
|
"button",
|
|
9534
9854
|
{
|
|
9535
9855
|
onClick: () => onAddSubgroup(group.id),
|
|
9536
9856
|
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
9537
9857
|
title: "Criar Subgrupo"
|
|
9538
9858
|
},
|
|
9539
|
-
/* @__PURE__ */
|
|
9540
|
-
)), /* @__PURE__ */
|
|
9859
|
+
/* @__PURE__ */ import_react25.default.createElement(import_fi19.FiPlus, { size: 14 })
|
|
9860
|
+
)), /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react25.default.createElement(
|
|
9541
9861
|
"button",
|
|
9542
9862
|
{
|
|
9543
9863
|
onClick: () => onIndent(group.id),
|
|
@@ -9545,24 +9865,24 @@ var GroupItem = ({
|
|
|
9545
9865
|
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
9866
|
title: "Aninhar no grupo acima"
|
|
9547
9867
|
},
|
|
9548
|
-
/* @__PURE__ */
|
|
9549
|
-
), /* @__PURE__ */
|
|
9868
|
+
/* @__PURE__ */ import_react25.default.createElement(import_fi19.FiArrowRight, { size: 14 })
|
|
9869
|
+
), /* @__PURE__ */ import_react25.default.createElement(
|
|
9550
9870
|
"button",
|
|
9551
9871
|
{
|
|
9552
9872
|
onClick: () => onOutdent(group.id),
|
|
9553
9873
|
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
9554
9874
|
title: "Desaninhar"
|
|
9555
9875
|
},
|
|
9556
|
-
/* @__PURE__ */
|
|
9557
|
-
), /* @__PURE__ */
|
|
9876
|
+
/* @__PURE__ */ import_react25.default.createElement(import_fi19.FiArrowLeft, { size: 14 })
|
|
9877
|
+
), /* @__PURE__ */ import_react25.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react25.default.createElement(
|
|
9558
9878
|
"button",
|
|
9559
9879
|
{
|
|
9560
9880
|
onClick: () => onDelete(group.id),
|
|
9561
9881
|
className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
|
|
9562
9882
|
title: "Remover Grupo"
|
|
9563
9883
|
},
|
|
9564
|
-
/* @__PURE__ */
|
|
9565
|
-
)))), group.children && group.children.length > 0 && /* @__PURE__ */
|
|
9884
|
+
/* @__PURE__ */ import_react25.default.createElement(import_fi19.FiTrash2, { size: 14 })
|
|
9885
|
+
)))), group.children && group.children.length > 0 && /* @__PURE__ */ import_react25.default.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ import_react25.default.createElement(
|
|
9566
9886
|
GroupItem,
|
|
9567
9887
|
{
|
|
9568
9888
|
key: childGroup.id,
|
|
@@ -9594,21 +9914,21 @@ function AncestryBoard({
|
|
|
9594
9914
|
userRole
|
|
9595
9915
|
// [NOVO] Recebe a role do usuário
|
|
9596
9916
|
}) {
|
|
9597
|
-
const [searchTerm, setSearchTerm] = (0,
|
|
9598
|
-
const [groups, setGroups] = (0,
|
|
9599
|
-
const [isLoaded, setIsLoaded] = (0,
|
|
9600
|
-
const [pickingGroupId, setPickingGroupId] = (0,
|
|
9601
|
-
const [saveStatus, setSaveStatus] = (0,
|
|
9602
|
-
const canEdit = (0,
|
|
9917
|
+
const [searchTerm, setSearchTerm] = (0, import_react25.useState)("");
|
|
9918
|
+
const [groups, setGroups] = (0, import_react25.useState)([]);
|
|
9919
|
+
const [isLoaded, setIsLoaded] = (0, import_react25.useState)(false);
|
|
9920
|
+
const [pickingGroupId, setPickingGroupId] = (0, import_react25.useState)(null);
|
|
9921
|
+
const [saveStatus, setSaveStatus] = (0, import_react25.useState)("idle");
|
|
9922
|
+
const canEdit = (0, import_react25.useMemo)(() => {
|
|
9603
9923
|
return userRole !== "viewer";
|
|
9604
9924
|
}, [userRole]);
|
|
9605
|
-
(0,
|
|
9925
|
+
(0, import_react25.useEffect)(() => {
|
|
9606
9926
|
if (initialGroups && !isLoaded) {
|
|
9607
9927
|
setGroups(initialGroups);
|
|
9608
9928
|
setIsLoaded(true);
|
|
9609
9929
|
}
|
|
9610
9930
|
}, [initialGroups, isLoaded]);
|
|
9611
|
-
const nodeNamesMap = (0,
|
|
9931
|
+
const nodeNamesMap = (0, import_react25.useMemo)(() => {
|
|
9612
9932
|
const map = /* @__PURE__ */ new Map();
|
|
9613
9933
|
if (availableNodes && Array.isArray(availableNodes)) {
|
|
9614
9934
|
availableNodes.forEach((node) => {
|
|
@@ -9619,7 +9939,7 @@ function AncestryBoard({
|
|
|
9619
9939
|
}
|
|
9620
9940
|
return map;
|
|
9621
9941
|
}, [availableNodes]);
|
|
9622
|
-
const availableIds = (0,
|
|
9942
|
+
const availableIds = (0, import_react25.useMemo)(() => {
|
|
9623
9943
|
return new Set(availableAncestries.map((a) => String(a.ancestry_id)));
|
|
9624
9944
|
}, [availableAncestries]);
|
|
9625
9945
|
const sanitizeGroups = (groupList) => {
|
|
@@ -9633,7 +9953,7 @@ function AncestryBoard({
|
|
|
9633
9953
|
children: sanitizeGroups(g.children || [])
|
|
9634
9954
|
}));
|
|
9635
9955
|
};
|
|
9636
|
-
(0,
|
|
9956
|
+
(0, import_react25.useEffect)(() => {
|
|
9637
9957
|
if (!isLoaded || !onSave) return;
|
|
9638
9958
|
const timeoutId = setTimeout(async () => {
|
|
9639
9959
|
setSaveStatus("saving");
|
|
@@ -9651,7 +9971,7 @@ function AncestryBoard({
|
|
|
9651
9971
|
}, 3e3);
|
|
9652
9972
|
return () => clearTimeout(timeoutId);
|
|
9653
9973
|
}, [groups, isLoaded, onSave]);
|
|
9654
|
-
(0,
|
|
9974
|
+
(0, import_react25.useEffect)(() => {
|
|
9655
9975
|
if (!isOpen) return;
|
|
9656
9976
|
const handleKeyDown = (e) => {
|
|
9657
9977
|
if (e.key === "Escape") {
|
|
@@ -9667,7 +9987,7 @@ function AncestryBoard({
|
|
|
9667
9987
|
window.addEventListener("keydown", handleKeyDown);
|
|
9668
9988
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
9669
9989
|
}, [isOpen, onClose, pickingGroupId]);
|
|
9670
|
-
const filtered = (0,
|
|
9990
|
+
const filtered = (0, import_react25.useMemo)(() => {
|
|
9671
9991
|
const term = searchTerm.toLowerCase().trim();
|
|
9672
9992
|
return availableAncestries.filter((a) => {
|
|
9673
9993
|
if (!term) return true;
|
|
@@ -9806,27 +10126,27 @@ function AncestryBoard({
|
|
|
9806
10126
|
});
|
|
9807
10127
|
};
|
|
9808
10128
|
if (!isOpen) return null;
|
|
9809
|
-
return /* @__PURE__ */
|
|
10129
|
+
return /* @__PURE__ */ import_react25.default.createElement(
|
|
9810
10130
|
"div",
|
|
9811
10131
|
{
|
|
9812
10132
|
className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
|
|
9813
10133
|
onClick: onClose
|
|
9814
10134
|
},
|
|
9815
|
-
/* @__PURE__ */
|
|
10135
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
9816
10136
|
"div",
|
|
9817
10137
|
{
|
|
9818
10138
|
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
10139
|
onClick: (e) => e.stopPropagation()
|
|
9820
10140
|
},
|
|
9821
|
-
/* @__PURE__ */
|
|
10141
|
+
/* @__PURE__ */ import_react25.default.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react25.default.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiLayers, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ import_react25.default.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__ */ import_react25.default.createElement(import_react25.default.Fragment, null, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiLoader, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ import_react25.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ import_react25.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, /* @__PURE__ */ import_react25.default.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ import_react25.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ import_react25.default.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ import_react25.default.createElement(
|
|
9822
10142
|
"button",
|
|
9823
10143
|
{
|
|
9824
10144
|
onClick: handleAddRootGroup,
|
|
9825
10145
|
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
10146
|
},
|
|
9827
|
-
/* @__PURE__ */
|
|
9828
|
-
/* @__PURE__ */
|
|
9829
|
-
), /* @__PURE__ */
|
|
10147
|
+
/* @__PURE__ */ import_react25.default.createElement(import_fi19.FiPlus, { size: 14, className: "text-indigo-400" }),
|
|
10148
|
+
/* @__PURE__ */ import_react25.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
|
|
10149
|
+
), /* @__PURE__ */ import_react25.default.createElement(
|
|
9830
10150
|
"button",
|
|
9831
10151
|
{
|
|
9832
10152
|
onClick: onClose,
|
|
@@ -9834,11 +10154,11 @@ function AncestryBoard({
|
|
|
9834
10154
|
},
|
|
9835
10155
|
"\xD7"
|
|
9836
10156
|
))),
|
|
9837
|
-
/* @__PURE__ */
|
|
10157
|
+
/* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: `
|
|
9838
10158
|
flex flex-col border-r border-white/10 transition-all duration-300 flex-none
|
|
9839
10159
|
${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
|
|
9840
10160
|
min-w-[280px] max-w-[500px] bg-slate-900
|
|
9841
|
-
` }, /* @__PURE__ */
|
|
10161
|
+
` }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiSearch, { 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__ */ import_react25.default.createElement(
|
|
9842
10162
|
"input",
|
|
9843
10163
|
{
|
|
9844
10164
|
type: "text",
|
|
@@ -9851,10 +10171,10 @@ function AncestryBoard({
|
|
|
9851
10171
|
onChange: (e) => setSearchTerm(e.target.value),
|
|
9852
10172
|
autoFocus: !pickingGroupId
|
|
9853
10173
|
}
|
|
9854
|
-
))), /* @__PURE__ */
|
|
10174
|
+
))), /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
|
|
9855
10175
|
const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
|
|
9856
10176
|
const isPicking = !!pickingGroupId;
|
|
9857
|
-
return /* @__PURE__ */
|
|
10177
|
+
return /* @__PURE__ */ import_react25.default.createElement(
|
|
9858
10178
|
"div",
|
|
9859
10179
|
{
|
|
9860
10180
|
key: anc.ancestry_id,
|
|
@@ -9866,12 +10186,12 @@ function AncestryBoard({
|
|
|
9866
10186
|
${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
10187
|
`
|
|
9868
10188
|
},
|
|
9869
|
-
/* @__PURE__ */
|
|
10189
|
+
/* @__PURE__ */ import_react25.default.createElement("div", { className: `
|
|
9870
10190
|
mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
|
|
9871
10191
|
${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__ */
|
|
10192
|
+
` }, isPicking ? /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiPlus, { size: 16 }) : /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiLayers, { size: 14 })),
|
|
10193
|
+
/* @__PURE__ */ import_react25.default.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ import_react25.default.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__ */ import_react25.default.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__ */ import_react25.default.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__ */ import_react25.default.createElement(import_fi19.FiCornerUpRight, { size: 10 }), /* @__PURE__ */ import_react25.default.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ import_react25.default.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
|
|
10194
|
+
!isPicking && /* @__PURE__ */ import_react25.default.createElement(
|
|
9875
10195
|
"button",
|
|
9876
10196
|
{
|
|
9877
10197
|
onClick: (e) => {
|
|
@@ -9881,10 +10201,10 @@ function AncestryBoard({
|
|
|
9881
10201
|
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
10202
|
title: "Renderizar Ancestralidade"
|
|
9883
10203
|
},
|
|
9884
|
-
/* @__PURE__ */
|
|
10204
|
+
/* @__PURE__ */ import_react25.default.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiPlay, { size: 14, className: "ml-0.5" }))
|
|
9885
10205
|
)
|
|
9886
10206
|
);
|
|
9887
|
-
}))), /* @__PURE__ */
|
|
10207
|
+
}))), /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ import_react25.default.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__ */ import_react25.default.createElement(import_fi19.FiLayers, { size: 24, className: "opacity-20" }), /* @__PURE__ */ import_react25.default.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ import_react25.default.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ import_react25.default.createElement(
|
|
9888
10208
|
GroupItem,
|
|
9889
10209
|
{
|
|
9890
10210
|
key: group.id,
|
|
@@ -9904,7 +10224,7 @@ function AncestryBoard({
|
|
|
9904
10224
|
canEdit
|
|
9905
10225
|
}
|
|
9906
10226
|
))))),
|
|
9907
|
-
/* @__PURE__ */
|
|
10227
|
+
/* @__PURE__ */ import_react25.default.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__ */ import_react25.default.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ import_react25.default.createElement("span", null, groups.length, " grupos raiz"))
|
|
9908
10228
|
)
|
|
9909
10229
|
);
|
|
9910
10230
|
}
|
|
@@ -9984,12 +10304,12 @@ function XViewScene({
|
|
|
9984
10304
|
check_user_permission
|
|
9985
10305
|
}) {
|
|
9986
10306
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
9987
|
-
const { data: session, status } = (0,
|
|
10307
|
+
const { data: session, status } = (0, import_react27.useSession)();
|
|
9988
10308
|
const router = (0, import_navigation.useRouter)();
|
|
9989
10309
|
const searchParams = (0, import_navigation.useSearchParams)();
|
|
9990
10310
|
const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
|
|
9991
10311
|
const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
|
|
9992
|
-
const viewParams = (0,
|
|
10312
|
+
const viewParams = (0, import_react26.useMemo)(() => {
|
|
9993
10313
|
if (encryptedConfig) {
|
|
9994
10314
|
const data = decryptData(encryptedConfig);
|
|
9995
10315
|
if (data) {
|
|
@@ -9998,7 +10318,7 @@ function XViewScene({
|
|
|
9998
10318
|
}
|
|
9999
10319
|
return null;
|
|
10000
10320
|
}, [encryptedConfig, session]);
|
|
10001
|
-
(0,
|
|
10321
|
+
(0, import_react26.useEffect)(() => {
|
|
10002
10322
|
async function verifyPermission() {
|
|
10003
10323
|
if (!viewParams || !session || !check_user_permission) return;
|
|
10004
10324
|
const { id, type, owner_id } = viewParams;
|
|
@@ -10028,65 +10348,65 @@ function XViewScene({
|
|
|
10028
10348
|
setIsLoading(false);
|
|
10029
10349
|
}
|
|
10030
10350
|
}, [viewParams, session, status, check_user_permission]);
|
|
10031
|
-
const sceneConfigId = (0,
|
|
10032
|
-
const ownerId = (0,
|
|
10033
|
-
const dbSaveUrl = (0,
|
|
10351
|
+
const sceneConfigId = (0, import_react26.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
|
|
10352
|
+
const ownerId = (0, import_react26.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
|
|
10353
|
+
const dbSaveUrl = (0, import_react26.useMemo)(() => {
|
|
10034
10354
|
if (ownerId && sceneConfigId) {
|
|
10035
10355
|
return `x_view_dbs/${ownerId}/${sceneConfigId}`;
|
|
10036
10356
|
}
|
|
10037
10357
|
return null;
|
|
10038
10358
|
}, [ownerId, sceneConfigId]);
|
|
10039
|
-
const sceneSaveUrl = (0,
|
|
10359
|
+
const sceneSaveUrl = (0, import_react26.useMemo)(() => {
|
|
10040
10360
|
if (ownerId && sceneConfigId) {
|
|
10041
10361
|
return `x_view_scenes/${ownerId}/${sceneConfigId}`;
|
|
10042
10362
|
}
|
|
10043
10363
|
return null;
|
|
10044
10364
|
}, [ownerId, sceneConfigId]);
|
|
10045
|
-
const ancestry_save_url = (0,
|
|
10365
|
+
const ancestry_save_url = (0, import_react26.useMemo)(() => {
|
|
10046
10366
|
if (ownerId && sceneConfigId) {
|
|
10047
10367
|
return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
|
|
10048
10368
|
}
|
|
10049
10369
|
return null;
|
|
10050
10370
|
}, [ownerId, sceneConfigId]);
|
|
10051
|
-
const sceneDataRef = (0,
|
|
10052
|
-
const parentDataRef = (0,
|
|
10053
|
-
const ancestryDataRef = (0,
|
|
10054
|
-
const [isLoading, setIsLoading] = (0,
|
|
10055
|
-
const [permissionStatus, setPermissionStatus] = (0,
|
|
10056
|
-
const [userPermissionRole, setUserPermissionRole] = (0,
|
|
10057
|
-
const [isInitialized, setIsInitialized] = (0,
|
|
10058
|
-
const [sceneVersion, setSceneVersion] = (0,
|
|
10059
|
-
const [contextMenu, setContextMenu] = (0,
|
|
10060
|
-
const [multiContextMenu, setMultiContextMenu] = (0,
|
|
10061
|
-
const [relationshipMenu, setRelationshipMenu] = (0,
|
|
10062
|
-
const [creationMode, setCreationMode] = (0,
|
|
10063
|
-
const [versionMode, setVersionMode] = (0,
|
|
10064
|
-
const [questMode, setQuestMode] = (0,
|
|
10065
|
-
const [hasFocusedInitial, setHasFocusedInitial] = (0,
|
|
10066
|
-
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0,
|
|
10067
|
-
const [ancestryMode, setAncestryMode] = (0,
|
|
10068
|
-
const [readingMode, setReadingMode] = (0,
|
|
10371
|
+
const sceneDataRef = (0, import_react26.useRef)(null);
|
|
10372
|
+
const parentDataRef = (0, import_react26.useRef)(null);
|
|
10373
|
+
const ancestryDataRef = (0, import_react26.useRef)(null);
|
|
10374
|
+
const [isLoading, setIsLoading] = (0, import_react26.useState)(true);
|
|
10375
|
+
const [permissionStatus, setPermissionStatus] = (0, import_react26.useState)("loading");
|
|
10376
|
+
const [userPermissionRole, setUserPermissionRole] = (0, import_react26.useState)(null);
|
|
10377
|
+
const [isInitialized, setIsInitialized] = (0, import_react26.useState)(false);
|
|
10378
|
+
const [sceneVersion, setSceneVersion] = (0, import_react26.useState)(0);
|
|
10379
|
+
const [contextMenu, setContextMenu] = (0, import_react26.useState)({ visible: false, x: 0, y: 0, nodeData: null });
|
|
10380
|
+
const [multiContextMenu, setMultiContextMenu] = (0, import_react26.useState)({ visible: false, x: 0, y: 0, nodeIds: null });
|
|
10381
|
+
const [relationshipMenu, setRelationshipMenu] = (0, import_react26.useState)({ visible: false, x: 0, y: 0, linkObject: null });
|
|
10382
|
+
const [creationMode, setCreationMode] = (0, import_react26.useState)({ isActive: false, sourceNodeData: null });
|
|
10383
|
+
const [versionMode, setVersionMode] = (0, import_react26.useState)({ isActive: false, sourceNodeData: null });
|
|
10384
|
+
const [questMode, setQuestMode] = (0, import_react26.useState)({ isActive: false });
|
|
10385
|
+
const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react26.useState)(false);
|
|
10386
|
+
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react26.useState)(false);
|
|
10387
|
+
const [ancestryMode, setAncestryMode] = (0, import_react26.useState)({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
10388
|
+
const [readingMode, setReadingMode] = (0, import_react26.useState)({
|
|
10069
10389
|
isActive: false,
|
|
10070
10390
|
ancestry: null,
|
|
10071
10391
|
branchStack: [],
|
|
10072
10392
|
autoAbstraction: false
|
|
10073
10393
|
});
|
|
10074
|
-
const [formPosition, setFormPosition] = (0,
|
|
10075
|
-
const [detailsNode, setDetailsNode] = (0,
|
|
10076
|
-
const [detailsLink, setDetailsLink] = (0,
|
|
10077
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] = (0,
|
|
10078
|
-
const [imageViewer, setImageViewer] = (0,
|
|
10079
|
-
const [editingAncestryRel, setEditingAncestryRel] = (0,
|
|
10080
|
-
const [isImportModalOpen, setIsImportModalOpen] = (0,
|
|
10081
|
-
const [importSuccessMessage, setImportSuccessMessage] = (0,
|
|
10082
|
-
const [highlightedNodeId, setHighlightedNodeId] = (0,
|
|
10083
|
-
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0,
|
|
10084
|
-
const [ancestryBoardData, setAncestryBoardData] = (0,
|
|
10085
|
-
const [isSidebarOpen, setIsSidebarOpen] = (0,
|
|
10086
|
-
const mountRef = (0,
|
|
10087
|
-
const tooltipRef = (0,
|
|
10088
|
-
const formRef = (0,
|
|
10089
|
-
const stateRef = (0,
|
|
10394
|
+
const [formPosition, setFormPosition] = (0, import_react26.useState)({ left: 16, top: 16, opacity: 0 });
|
|
10395
|
+
const [detailsNode, setDetailsNode] = (0, import_react26.useState)(null);
|
|
10396
|
+
const [detailsLink, setDetailsLink] = (0, import_react26.useState)(null);
|
|
10397
|
+
const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react26.useState)(null);
|
|
10398
|
+
const [imageViewer, setImageViewer] = (0, import_react26.useState)({ visible: false, images: [], startIndex: 0 });
|
|
10399
|
+
const [editingAncestryRel, setEditingAncestryRel] = (0, import_react26.useState)({ visible: false, data: null, path: null });
|
|
10400
|
+
const [isImportModalOpen, setIsImportModalOpen] = (0, import_react26.useState)(false);
|
|
10401
|
+
const [importSuccessMessage, setImportSuccessMessage] = (0, import_react26.useState)("");
|
|
10402
|
+
const [highlightedNodeId, setHighlightedNodeId] = (0, import_react26.useState)(null);
|
|
10403
|
+
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react26.useState)(false);
|
|
10404
|
+
const [ancestryBoardData, setAncestryBoardData] = (0, import_react26.useState)([]);
|
|
10405
|
+
const [isSidebarOpen, setIsSidebarOpen] = (0, import_react26.useState)(false);
|
|
10406
|
+
const mountRef = (0, import_react26.useRef)(null);
|
|
10407
|
+
const tooltipRef = (0, import_react26.useRef)(null);
|
|
10408
|
+
const formRef = (0, import_react26.useRef)(null);
|
|
10409
|
+
const stateRef = (0, import_react26.useRef)({
|
|
10090
10410
|
readMode: {
|
|
10091
10411
|
currentMaxIndex: 0,
|
|
10092
10412
|
progressMap: {}
|
|
@@ -10131,10 +10451,10 @@ function XViewScene({
|
|
|
10131
10451
|
minWidth: 320,
|
|
10132
10452
|
maxWidth: maxReadPanelW
|
|
10133
10453
|
});
|
|
10134
|
-
(0,
|
|
10454
|
+
(0, import_react26.useEffect)(() => {
|
|
10135
10455
|
stateRef.current.ancestry = ancestryMode;
|
|
10136
10456
|
}, [ancestryMode]);
|
|
10137
|
-
(0,
|
|
10457
|
+
(0, import_react26.useEffect)(() => {
|
|
10138
10458
|
var _a2;
|
|
10139
10459
|
if (!isInitialized) return;
|
|
10140
10460
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -10155,10 +10475,10 @@ function XViewScene({
|
|
|
10155
10475
|
}
|
|
10156
10476
|
stateRef.current.nodeIdToParentFileMap = map;
|
|
10157
10477
|
}, [isInitialized, sceneVersion]);
|
|
10158
|
-
const handleNavigateBack = (0,
|
|
10478
|
+
const handleNavigateBack = (0, import_react26.useCallback)(() => {
|
|
10159
10479
|
router.push("/dashboard/scenes");
|
|
10160
10480
|
}, [router]);
|
|
10161
|
-
const handleConfirmImport = (0,
|
|
10481
|
+
const handleConfirmImport = (0, import_react26.useCallback)(
|
|
10162
10482
|
async (importPayload) => {
|
|
10163
10483
|
var _a2, _b2;
|
|
10164
10484
|
let files = [];
|
|
@@ -10256,7 +10576,7 @@ function XViewScene({
|
|
|
10256
10576
|
const handleOpenImageViewer = (images, startIndex) => {
|
|
10257
10577
|
setImageViewer({ visible: true, images, startIndex });
|
|
10258
10578
|
};
|
|
10259
|
-
const tweenToTarget = (0,
|
|
10579
|
+
const tweenToTarget = (0, import_react26.useCallback)((target, zoomFactor = 1, forcedDirection = null) => {
|
|
10260
10580
|
const { camera, controls, tweenGroup } = stateRef.current;
|
|
10261
10581
|
if (!camera || !controls || !tweenGroup) return;
|
|
10262
10582
|
const targetPos = target instanceof THREE3.Mesh ? target.getWorldPosition(new THREE3.Vector3()) : target;
|
|
@@ -10279,7 +10599,7 @@ function XViewScene({
|
|
|
10279
10599
|
if (!t || typeof t.closest !== "function") return false;
|
|
10280
10600
|
return !!t.closest(".ui-overlay");
|
|
10281
10601
|
};
|
|
10282
|
-
const buildFullAncestryTree = (0,
|
|
10602
|
+
const buildFullAncestryTree = (0, import_react26.useCallback)((idTree, nodes, ancestries = []) => {
|
|
10283
10603
|
if (!idTree) return null;
|
|
10284
10604
|
const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
|
|
10285
10605
|
const ancestryMap = new Map(ancestries.map((a) => [String(a.ancestry_id), a]));
|
|
@@ -10355,7 +10675,7 @@ function XViewScene({
|
|
|
10355
10675
|
}
|
|
10356
10676
|
return recursiveBuild(idTree);
|
|
10357
10677
|
}, []);
|
|
10358
|
-
const handleActivateTimeline = (0,
|
|
10678
|
+
const handleActivateTimeline = (0, import_react26.useCallback)(() => {
|
|
10359
10679
|
const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
10360
10680
|
if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
|
|
10361
10681
|
while (timelineIntervalsGroup.children.length > 0) {
|
|
@@ -10508,7 +10828,7 @@ function XViewScene({
|
|
|
10508
10828
|
}
|
|
10509
10829
|
});
|
|
10510
10830
|
}, []);
|
|
10511
|
-
const handleVersionTimeline = (0,
|
|
10831
|
+
const handleVersionTimeline = (0, import_react26.useCallback)((sourceMesh, versionMeshes) => {
|
|
10512
10832
|
const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
10513
10833
|
if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0) return;
|
|
10514
10834
|
versionMeshes.forEach((mesh) => {
|
|
@@ -10631,7 +10951,7 @@ function XViewScene({
|
|
|
10631
10951
|
}
|
|
10632
10952
|
});
|
|
10633
10953
|
}, []);
|
|
10634
|
-
(0,
|
|
10954
|
+
(0, import_react26.useEffect)(() => {
|
|
10635
10955
|
async function fetchAllData(configPath, ownerId2) {
|
|
10636
10956
|
var _a2, _b2;
|
|
10637
10957
|
if (!get_scene_view_data) {
|
|
@@ -10703,12 +11023,12 @@ function XViewScene({
|
|
|
10703
11023
|
focusNodeId,
|
|
10704
11024
|
focusAncestryId
|
|
10705
11025
|
]);
|
|
10706
|
-
const isNodeInView = (0,
|
|
11026
|
+
const isNodeInView = (0, import_react26.useCallback)((id) => {
|
|
10707
11027
|
const key = String(id);
|
|
10708
11028
|
const objs = stateRef.current.nodeObjects || {};
|
|
10709
11029
|
return !!objs[key];
|
|
10710
11030
|
}, []);
|
|
10711
|
-
const addOrUpdateNodeMesh = (0,
|
|
11031
|
+
const addOrUpdateNodeMesh = (0, import_react26.useCallback)((nodeData, position, suppressVersionUpdate = false) => {
|
|
10712
11032
|
const { graphGroup, nodeObjects, clickableNodes, glowTexture, tweenGroup } = stateRef.current;
|
|
10713
11033
|
const nodeId = String(nodeData.id);
|
|
10714
11034
|
if (nodeObjects[nodeId]) {
|
|
@@ -10735,7 +11055,7 @@ function XViewScene({
|
|
|
10735
11055
|
}
|
|
10736
11056
|
return mesh;
|
|
10737
11057
|
}, []);
|
|
10738
|
-
(0,
|
|
11058
|
+
(0, import_react26.useEffect)(() => {
|
|
10739
11059
|
if (!isInitialized || !sceneDataRef.current) return;
|
|
10740
11060
|
const currentMount = mountRef.current;
|
|
10741
11061
|
if (!currentMount) return;
|
|
@@ -11345,7 +11665,7 @@ function XViewScene({
|
|
|
11345
11665
|
}
|
|
11346
11666
|
};
|
|
11347
11667
|
}, [isInitialized, tweenToTarget, dbSaveUrl, isNodeInView, addOrUpdateNodeMesh, handleActivateTimeline, get_scene_view_data, save_view_data]);
|
|
11348
|
-
const handleGhostNodeImageChange = (0,
|
|
11668
|
+
const handleGhostNodeImageChange = (0, import_react26.useCallback)((useImage, imageUrl) => {
|
|
11349
11669
|
const { node: ghostNode, line: ghostLine, aura: ghostAura } = stateRef.current.ghostElements;
|
|
11350
11670
|
const { graphGroup, glowTexture } = stateRef.current;
|
|
11351
11671
|
if (!ghostNode || !graphGroup) return;
|
|
@@ -11387,7 +11707,7 @@ function XViewScene({
|
|
|
11387
11707
|
aura: newGhostNode.getObjectByName("aura")
|
|
11388
11708
|
};
|
|
11389
11709
|
}, []);
|
|
11390
|
-
const handleGhostNodeIntensityChange = (0,
|
|
11710
|
+
const handleGhostNodeIntensityChange = (0, import_react26.useCallback)((newIntensity) => {
|
|
11391
11711
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
11392
11712
|
if (!ghostNode) return;
|
|
11393
11713
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -11408,7 +11728,7 @@ function XViewScene({
|
|
|
11408
11728
|
ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
|
|
11409
11729
|
}
|
|
11410
11730
|
}, []);
|
|
11411
|
-
const handleDetailNodeIntensityChange = (0,
|
|
11731
|
+
const handleDetailNodeIntensityChange = (0, import_react26.useCallback)((nodeId, newIntensity) => {
|
|
11412
11732
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
11413
11733
|
if (!mesh) return;
|
|
11414
11734
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -11554,7 +11874,7 @@ function XViewScene({
|
|
|
11554
11874
|
mountRef.current.style.cursor = "default";
|
|
11555
11875
|
}
|
|
11556
11876
|
};
|
|
11557
|
-
const handleAncestryTreeUpdate = (0,
|
|
11877
|
+
const handleAncestryTreeUpdate = (0, import_react26.useCallback)((newTree, extraData = null) => {
|
|
11558
11878
|
setAncestryMode((prev) => {
|
|
11559
11879
|
const prevTreeStr = JSON.stringify(prev.tree);
|
|
11560
11880
|
const newTreeStr = JSON.stringify(newTree);
|
|
@@ -11574,7 +11894,7 @@ function XViewScene({
|
|
|
11574
11894
|
};
|
|
11575
11895
|
});
|
|
11576
11896
|
}, []);
|
|
11577
|
-
const actionHandlerContext = (0,
|
|
11897
|
+
const actionHandlerContext = (0, import_react26.useMemo)(
|
|
11578
11898
|
() => {
|
|
11579
11899
|
var _a2;
|
|
11580
11900
|
return {
|
|
@@ -11635,7 +11955,7 @@ function XViewScene({
|
|
|
11635
11955
|
const handleStartVersioning = (nodeData) => {
|
|
11636
11956
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
11637
11957
|
};
|
|
11638
|
-
const handleCancelQuest = (0,
|
|
11958
|
+
const handleCancelQuest = (0, import_react26.useCallback)(() => {
|
|
11639
11959
|
const { graphGroup, ghostElements } = stateRef.current;
|
|
11640
11960
|
if (ghostElements.node && graphGroup) {
|
|
11641
11961
|
if (ghostElements.node.userData.labelObject) {
|
|
@@ -11745,7 +12065,7 @@ function XViewScene({
|
|
|
11745
12065
|
}
|
|
11746
12066
|
userActionHandlers.handleCancelConnection(context);
|
|
11747
12067
|
};
|
|
11748
|
-
const handleClearAncestryVisuals = (0,
|
|
12068
|
+
const handleClearAncestryVisuals = (0, import_react26.useCallback)((ancestryId) => {
|
|
11749
12069
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
11750
12070
|
const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
|
|
11751
12071
|
if (renderIndex !== -1) {
|
|
@@ -11759,7 +12079,7 @@ function XViewScene({
|
|
|
11759
12079
|
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
11760
12080
|
}
|
|
11761
12081
|
}, []);
|
|
11762
|
-
const handleRenderAncestry = (0,
|
|
12082
|
+
const handleRenderAncestry = (0, import_react26.useCallback)(
|
|
11763
12083
|
async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
|
|
11764
12084
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11765
12085
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -12175,7 +12495,7 @@ function XViewScene({
|
|
|
12175
12495
|
},
|
|
12176
12496
|
[addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, readingMode.isActive, ancestryMode.isActive]
|
|
12177
12497
|
);
|
|
12178
|
-
const handleRenderAbstractionTree = (0,
|
|
12498
|
+
const handleRenderAbstractionTree = (0, import_react26.useCallback)((ancestryObject, targetNodeId = null) => {
|
|
12179
12499
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
12180
12500
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
12181
12501
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
@@ -12236,7 +12556,7 @@ function XViewScene({
|
|
|
12236
12556
|
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
12237
12557
|
tweenToTarget(rootTargetPos, 0.7);
|
|
12238
12558
|
}, [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, handleClearAncestryVisuals]);
|
|
12239
|
-
const handleReadModeBranchNav = (0,
|
|
12559
|
+
const handleReadModeBranchNav = (0, import_react26.useCallback)((nodeId, action, direction = "right") => {
|
|
12240
12560
|
const { ancestry, branchStack } = readingMode;
|
|
12241
12561
|
if (!ancestry || !ancestry.tree) return;
|
|
12242
12562
|
const allAncestries = ancestryDataRef.current || [];
|
|
@@ -12377,13 +12697,13 @@ function XViewScene({
|
|
|
12377
12697
|
}));
|
|
12378
12698
|
}
|
|
12379
12699
|
}, [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]);
|
|
12380
|
-
const handleReadModeHighlight = (0,
|
|
12700
|
+
const handleReadModeHighlight = (0, import_react26.useCallback)((nodeId) => {
|
|
12381
12701
|
if (stateRef.current.highlightedNodeId !== nodeId) {
|
|
12382
12702
|
stateRef.current.highlightedNodeId = nodeId;
|
|
12383
12703
|
}
|
|
12384
12704
|
setHighlightedNodeId(nodeId);
|
|
12385
12705
|
}, []);
|
|
12386
|
-
const activeNodeBranches = (0,
|
|
12706
|
+
const activeNodeBranches = (0, import_react26.useMemo)(() => {
|
|
12387
12707
|
if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree) return null;
|
|
12388
12708
|
const fullTree = buildFullAncestryTree(
|
|
12389
12709
|
readingMode.ancestry.tree,
|
|
@@ -12420,7 +12740,7 @@ function XViewScene({
|
|
|
12420
12740
|
}
|
|
12421
12741
|
return null;
|
|
12422
12742
|
}, [highlightedNodeId, readingMode.ancestry, buildFullAncestryTree, readingMode.branchStack, ancestryDataRef.current]);
|
|
12423
|
-
const backNavigationInfo = (0,
|
|
12743
|
+
const backNavigationInfo = (0, import_react26.useMemo)(() => {
|
|
12424
12744
|
const { branchStack } = readingMode;
|
|
12425
12745
|
if (!branchStack || branchStack.length === 0) return null;
|
|
12426
12746
|
const lastStep = branchStack[branchStack.length - 1];
|
|
@@ -12431,7 +12751,7 @@ function XViewScene({
|
|
|
12431
12751
|
name: "Voltar para anterior"
|
|
12432
12752
|
};
|
|
12433
12753
|
}, [readingMode.branchStack]);
|
|
12434
|
-
const getReadModeDisplayContext = (0,
|
|
12754
|
+
const getReadModeDisplayContext = (0, import_react26.useMemo)(() => {
|
|
12435
12755
|
const { ancestry, branchStack } = readingMode;
|
|
12436
12756
|
if (!ancestry) return null;
|
|
12437
12757
|
if (branchStack.length === 0) {
|
|
@@ -12472,7 +12792,7 @@ function XViewScene({
|
|
|
12472
12792
|
customProperties: branchProps
|
|
12473
12793
|
};
|
|
12474
12794
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
12475
|
-
const readModeAbstractionTree = (0,
|
|
12795
|
+
const readModeAbstractionTree = (0, import_react26.useMemo)(() => {
|
|
12476
12796
|
if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
|
|
12477
12797
|
return null;
|
|
12478
12798
|
}
|
|
@@ -12484,7 +12804,7 @@ function XViewScene({
|
|
|
12484
12804
|
allAncestries
|
|
12485
12805
|
);
|
|
12486
12806
|
}, [readingMode.isActive, readingMode.ancestry, buildFullAncestryTree, sceneVersion]);
|
|
12487
|
-
const handleStartReadingAncestry = (0,
|
|
12807
|
+
const handleStartReadingAncestry = (0, import_react26.useCallback)(
|
|
12488
12808
|
async (ancestryObject) => {
|
|
12489
12809
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
12490
12810
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -12519,7 +12839,7 @@ function XViewScene({
|
|
|
12519
12839
|
},
|
|
12520
12840
|
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
12521
12841
|
);
|
|
12522
|
-
const handleReadModeSectionChange = (0,
|
|
12842
|
+
const handleReadModeSectionChange = (0, import_react26.useCallback)((activeSectionId) => {
|
|
12523
12843
|
const { ancestry, branchStack } = readingMode;
|
|
12524
12844
|
if (!ancestry || !readingMode.isActive) return;
|
|
12525
12845
|
let targetObj = ancestry;
|
|
@@ -12588,10 +12908,10 @@ function XViewScene({
|
|
|
12588
12908
|
}, 0);
|
|
12589
12909
|
handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
|
|
12590
12910
|
}, [readingMode, handleRenderAncestry, buildFullAncestryTree, ancestryDataRef.current]);
|
|
12591
|
-
const handleCloseReadMode = (0,
|
|
12911
|
+
const handleCloseReadMode = (0, import_react26.useCallback)(() => {
|
|
12592
12912
|
setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
|
|
12593
12913
|
}, []);
|
|
12594
|
-
const handleAncestrySectionChange = (0,
|
|
12914
|
+
const handleAncestrySectionChange = (0, import_react26.useCallback)((activeSectionId, ancestryOverride = null, rotation = 0) => {
|
|
12595
12915
|
var _a2, _b2;
|
|
12596
12916
|
const currentMode = stateRef.current.ancestry;
|
|
12597
12917
|
let targetObj = ancestryOverride;
|
|
@@ -12643,7 +12963,7 @@ function XViewScene({
|
|
|
12643
12963
|
const renderPayload = { ...targetObj, tree: treeToRender };
|
|
12644
12964
|
handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
|
|
12645
12965
|
}, [handleRenderAncestry]);
|
|
12646
|
-
const handleEditAncestry = (0,
|
|
12966
|
+
const handleEditAncestry = (0, import_react26.useCallback)(
|
|
12647
12967
|
async (ancestryObject) => {
|
|
12648
12968
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
12649
12969
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -12682,7 +13002,7 @@ function XViewScene({
|
|
|
12682
13002
|
const handleSelectAncestryParent = (nodeId) => {
|
|
12683
13003
|
setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
|
|
12684
13004
|
};
|
|
12685
|
-
const handleRemoveFromAncestry = (0,
|
|
13005
|
+
const handleRemoveFromAncestry = (0, import_react26.useCallback)((pathToRemove) => {
|
|
12686
13006
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
|
|
12687
13007
|
console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
|
|
12688
13008
|
return;
|
|
@@ -12707,7 +13027,7 @@ function XViewScene({
|
|
|
12707
13027
|
return { ...prev, tree: newTree };
|
|
12708
13028
|
});
|
|
12709
13029
|
}, []);
|
|
12710
|
-
const handleSaveAncestry = (0,
|
|
13030
|
+
const handleSaveAncestry = (0, import_react26.useCallback)(
|
|
12711
13031
|
async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
|
|
12712
13032
|
const treeToUse = treeOverride || ancestryMode.tree;
|
|
12713
13033
|
const { isEditMode, currentAncestryId } = ancestryMode;
|
|
@@ -12911,7 +13231,7 @@ function XViewScene({
|
|
|
12911
13231
|
});
|
|
12912
13232
|
setEditingAncestryRel({ visible: false, data: null, path: null });
|
|
12913
13233
|
};
|
|
12914
|
-
const handleDeleteAncestry = (0,
|
|
13234
|
+
const handleDeleteAncestry = (0, import_react26.useCallback)(
|
|
12915
13235
|
async (ancestryIdToDelete) => {
|
|
12916
13236
|
if (!ancestryIdToDelete) {
|
|
12917
13237
|
alert("ID da ancestralidade n\xE3o encontrado.");
|
|
@@ -12973,20 +13293,20 @@ function XViewScene({
|
|
|
12973
13293
|
},
|
|
12974
13294
|
[save_view_data, delete_file_action]
|
|
12975
13295
|
);
|
|
12976
|
-
const handleOpenAncestryBoard = (0,
|
|
13296
|
+
const handleOpenAncestryBoard = (0, import_react26.useCallback)(() => {
|
|
12977
13297
|
setIsAncestryBoardOpen(true);
|
|
12978
13298
|
}, []);
|
|
12979
|
-
const handleSelectAncestryFromBoard = (0,
|
|
13299
|
+
const handleSelectAncestryFromBoard = (0, import_react26.useCallback)((ancestry) => {
|
|
12980
13300
|
setIsAncestryBoardOpen(false);
|
|
12981
13301
|
setIsSidebarOpen(false);
|
|
12982
13302
|
handleStartReadingAncestry(ancestry);
|
|
12983
13303
|
}, [handleStartReadingAncestry]);
|
|
12984
|
-
const handleSaveAncestryBoard = (0,
|
|
13304
|
+
const handleSaveAncestryBoard = (0, import_react26.useCallback)(async (groups) => {
|
|
12985
13305
|
if (!sceneConfigId || !viewParams || !session) return;
|
|
12986
13306
|
const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
|
|
12987
13307
|
await save_ancestry_board_action(sceneConfigId, sceneType, groups, session, ownerId);
|
|
12988
13308
|
}, [sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]);
|
|
12989
|
-
const existingNodeTypes = (0,
|
|
13309
|
+
const existingNodeTypes = (0, import_react26.useMemo)(() => {
|
|
12990
13310
|
if (!parentDataRef.current) {
|
|
12991
13311
|
return [];
|
|
12992
13312
|
}
|
|
@@ -12996,7 +13316,7 @@ function XViewScene({
|
|
|
12996
13316
|
})).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
|
|
12997
13317
|
return [...new Set(allTypes)];
|
|
12998
13318
|
}, [parentDataRef.current, sceneVersion]);
|
|
12999
|
-
const searchableDbNodes = (0,
|
|
13319
|
+
const searchableDbNodes = (0, import_react26.useMemo)(() => {
|
|
13000
13320
|
if (!parentDataRef.current) {
|
|
13001
13321
|
return [];
|
|
13002
13322
|
}
|
|
@@ -13005,13 +13325,13 @@ function XViewScene({
|
|
|
13005
13325
|
return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
|
|
13006
13326
|
});
|
|
13007
13327
|
}, [parentDataRef.current, sceneVersion]);
|
|
13008
|
-
const handleAddExistingNode = (0,
|
|
13328
|
+
const handleAddExistingNode = (0, import_react26.useCallback)(
|
|
13009
13329
|
(nodeId) => {
|
|
13010
13330
|
return userActionHandlers.handleAddExistingNodeById(actionHandlerContext, nodeId);
|
|
13011
13331
|
},
|
|
13012
13332
|
[actionHandlerContext]
|
|
13013
13333
|
);
|
|
13014
|
-
const handleSaveCurrentView = (0,
|
|
13334
|
+
const handleSaveCurrentView = (0, import_react26.useCallback)(async () => {
|
|
13015
13335
|
var _a2, _b2, _c2;
|
|
13016
13336
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
13017
13337
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
@@ -13050,14 +13370,14 @@ function XViewScene({
|
|
|
13050
13370
|
console.error("Erro na chamada de save_view_data:", error);
|
|
13051
13371
|
}
|
|
13052
13372
|
}, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
|
|
13053
|
-
const allAvailableNodes = (0,
|
|
13373
|
+
const allAvailableNodes = (0, import_react26.useMemo)(() => {
|
|
13054
13374
|
if (!parentDataRef.current) return [];
|
|
13055
13375
|
return Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
|
|
13056
13376
|
}, [sceneVersion, isInitialized]);
|
|
13057
|
-
const allAvailableAncestries = (0,
|
|
13377
|
+
const allAvailableAncestries = (0, import_react26.useMemo)(() => {
|
|
13058
13378
|
return ancestryDataRef.current || [];
|
|
13059
13379
|
}, [sceneVersion, isInitialized]);
|
|
13060
|
-
const handleOpenReference = (0,
|
|
13380
|
+
const handleOpenReference = (0, import_react26.useCallback)((referenceData) => {
|
|
13061
13381
|
const { type, id } = referenceData;
|
|
13062
13382
|
if (type === "node") {
|
|
13063
13383
|
const targetNode = allAvailableNodes.find((n) => String(n.id) === String(id));
|
|
@@ -13084,17 +13404,17 @@ function XViewScene({
|
|
|
13084
13404
|
}
|
|
13085
13405
|
}
|
|
13086
13406
|
}, [allAvailableNodes, allAvailableAncestries, handleEditAncestry, tweenToTarget]);
|
|
13087
|
-
const handleToggleAncestryAddMode = (0,
|
|
13407
|
+
const handleToggleAncestryAddMode = (0, import_react26.useCallback)(() => {
|
|
13088
13408
|
setAncestryMode((prev) => ({ ...prev, isAddingNodes: !prev.isAddingNodes }));
|
|
13089
13409
|
}, []);
|
|
13090
|
-
const handleFocusNode = (0,
|
|
13410
|
+
const handleFocusNode = (0, import_react26.useCallback)((nodeData) => {
|
|
13091
13411
|
if (!nodeData) return;
|
|
13092
13412
|
const nodeMesh = stateRef.current.nodeObjects[String(nodeData.id)];
|
|
13093
13413
|
if (nodeMesh) {
|
|
13094
13414
|
tweenToTarget(nodeMesh, 1.2);
|
|
13095
13415
|
}
|
|
13096
13416
|
}, [tweenToTarget]);
|
|
13097
|
-
const availableDatasets = (0,
|
|
13417
|
+
const availableDatasets = (0, import_react26.useMemo)(() => {
|
|
13098
13418
|
if (!sceneDataRef.current || !parentDataRef.current) return [];
|
|
13099
13419
|
return sceneDataRef.current.parent_dbs.map((db) => {
|
|
13100
13420
|
var _a2;
|
|
@@ -13106,7 +13426,7 @@ function XViewScene({
|
|
|
13106
13426
|
}, [sceneVersion, isInitialized]);
|
|
13107
13427
|
const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(String(creationMode.sourceNodeData.id))) == null ? void 0 : _b.parentFileId : null;
|
|
13108
13428
|
const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
|
|
13109
|
-
(0,
|
|
13429
|
+
(0, import_react26.useEffect)(() => {
|
|
13110
13430
|
if (isInitialized && focusNodeId && !hasFocusedInitial) {
|
|
13111
13431
|
const nodeObjects = stateRef.current.nodeObjects || {};
|
|
13112
13432
|
const targetMesh = nodeObjects[String(focusNodeId)];
|
|
@@ -13120,7 +13440,7 @@ function XViewScene({
|
|
|
13120
13440
|
}
|
|
13121
13441
|
}
|
|
13122
13442
|
}, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
|
|
13123
|
-
(0,
|
|
13443
|
+
(0, import_react26.useEffect)(() => {
|
|
13124
13444
|
if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
|
|
13125
13445
|
const ancestries = ancestryDataRef.current || [];
|
|
13126
13446
|
const targetAncestry = ancestries.find((a) => String(a.ancestry_id) === String(focusAncestryId));
|
|
@@ -13134,7 +13454,7 @@ function XViewScene({
|
|
|
13134
13454
|
}
|
|
13135
13455
|
}
|
|
13136
13456
|
}, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
|
|
13137
|
-
(0,
|
|
13457
|
+
(0, import_react26.useEffect)(() => {
|
|
13138
13458
|
function handleKeyDown(event) {
|
|
13139
13459
|
var _a2, _b2, _c2;
|
|
13140
13460
|
const context = actionHandlerContext;
|
|
@@ -13235,20 +13555,20 @@ function XViewScene({
|
|
|
13235
13555
|
// <-- handleCancelQuest adicionado aqui
|
|
13236
13556
|
]);
|
|
13237
13557
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
13238
|
-
return /* @__PURE__ */
|
|
13558
|
+
return /* @__PURE__ */ import_react26.default.createElement(LoadingScreen, null);
|
|
13239
13559
|
}
|
|
13240
13560
|
if (permissionStatus === "denied") {
|
|
13241
|
-
return /* @__PURE__ */
|
|
13561
|
+
return /* @__PURE__ */ import_react26.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react26.default.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ import_react26.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react26.default.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__ */ import_react26.default.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__ */ import_react26.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react26.default.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__ */ import_react26.default.createElement(
|
|
13242
13562
|
"button",
|
|
13243
13563
|
{
|
|
13244
13564
|
onClick: () => router.push("/dashboard/scenes"),
|
|
13245
13565
|
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
13566
|
},
|
|
13247
|
-
/* @__PURE__ */
|
|
13567
|
+
/* @__PURE__ */ import_react26.default.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__ */ import_react26.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" })),
|
|
13248
13568
|
"Voltar para Scenes"
|
|
13249
13569
|
)));
|
|
13250
13570
|
}
|
|
13251
|
-
return /* @__PURE__ */
|
|
13571
|
+
return /* @__PURE__ */ import_react26.default.createElement(
|
|
13252
13572
|
"div",
|
|
13253
13573
|
{
|
|
13254
13574
|
ref: mountRef,
|
|
@@ -13260,7 +13580,7 @@ function XViewScene({
|
|
|
13260
13580
|
cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
|
|
13261
13581
|
}
|
|
13262
13582
|
},
|
|
13263
|
-
userPermissionRole !== "link_viewer" && /* @__PURE__ */
|
|
13583
|
+
userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react26.default.createElement(
|
|
13264
13584
|
XViewSidebar,
|
|
13265
13585
|
{
|
|
13266
13586
|
dbNodes: searchableDbNodes,
|
|
@@ -13280,7 +13600,7 @@ function XViewScene({
|
|
|
13280
13600
|
userRole: userPermissionRole
|
|
13281
13601
|
}
|
|
13282
13602
|
),
|
|
13283
|
-
creationMode.isActive && /* @__PURE__ */
|
|
13603
|
+
creationMode.isActive && /* @__PURE__ */ import_react26.default.createElement(
|
|
13284
13604
|
InSceneCreationForm,
|
|
13285
13605
|
{
|
|
13286
13606
|
onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
|
|
@@ -13305,7 +13625,7 @@ function XViewScene({
|
|
|
13305
13625
|
availableAncestries: allAvailableAncestries
|
|
13306
13626
|
}
|
|
13307
13627
|
),
|
|
13308
|
-
versionMode.isActive && /* @__PURE__ */
|
|
13628
|
+
versionMode.isActive && /* @__PURE__ */ import_react26.default.createElement(
|
|
13309
13629
|
InSceneVersionForm,
|
|
13310
13630
|
{
|
|
13311
13631
|
onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
|
|
@@ -13324,7 +13644,7 @@ function XViewScene({
|
|
|
13324
13644
|
availableAncestries: allAvailableAncestries
|
|
13325
13645
|
}
|
|
13326
13646
|
),
|
|
13327
|
-
questMode.isActive && /* @__PURE__ */
|
|
13647
|
+
questMode.isActive && /* @__PURE__ */ import_react26.default.createElement(
|
|
13328
13648
|
InSceneQuestForm,
|
|
13329
13649
|
{
|
|
13330
13650
|
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
@@ -13341,13 +13661,13 @@ function XViewScene({
|
|
|
13341
13661
|
availableAncestries: allAvailableAncestries
|
|
13342
13662
|
}
|
|
13343
13663
|
),
|
|
13344
|
-
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */
|
|
13664
|
+
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react26.default.createElement(
|
|
13345
13665
|
"div",
|
|
13346
13666
|
{
|
|
13347
13667
|
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
13668
|
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${readModeWidth}px`, maxWidth: "92vw" }
|
|
13349
13669
|
},
|
|
13350
|
-
/* @__PURE__ */
|
|
13670
|
+
/* @__PURE__ */ import_react26.default.createElement(
|
|
13351
13671
|
"div",
|
|
13352
13672
|
{
|
|
13353
13673
|
onPointerDown: (e) => {
|
|
@@ -13358,7 +13678,7 @@ function XViewScene({
|
|
|
13358
13678
|
title: "Arraste para redimensionar"
|
|
13359
13679
|
}
|
|
13360
13680
|
),
|
|
13361
|
-
/* @__PURE__ */
|
|
13681
|
+
/* @__PURE__ */ import_react26.default.createElement(
|
|
13362
13682
|
DescriptionReadModePanel,
|
|
13363
13683
|
{
|
|
13364
13684
|
key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
|
|
@@ -13393,7 +13713,7 @@ function XViewScene({
|
|
|
13393
13713
|
}
|
|
13394
13714
|
)
|
|
13395
13715
|
),
|
|
13396
|
-
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */
|
|
13716
|
+
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react26.default.createElement(
|
|
13397
13717
|
CreateAncestryPanel,
|
|
13398
13718
|
{
|
|
13399
13719
|
ancestryMode,
|
|
@@ -13420,7 +13740,7 @@ function XViewScene({
|
|
|
13420
13740
|
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
13421
13741
|
}
|
|
13422
13742
|
),
|
|
13423
|
-
editingAncestryRel.visible && /* @__PURE__ */
|
|
13743
|
+
editingAncestryRel.visible && /* @__PURE__ */ import_react26.default.createElement(
|
|
13424
13744
|
AncestryRelationshipPanel,
|
|
13425
13745
|
{
|
|
13426
13746
|
data: editingAncestryRel.data,
|
|
@@ -13434,7 +13754,28 @@ function XViewScene({
|
|
|
13434
13754
|
onUploadFile: upload_file_action
|
|
13435
13755
|
}
|
|
13436
13756
|
),
|
|
13437
|
-
detailsNode && /* @__PURE__ */
|
|
13757
|
+
detailsNode && detailsNode.is_quest && /* @__PURE__ */ import_react26.default.createElement(
|
|
13758
|
+
QuestDetailsPanel,
|
|
13759
|
+
{
|
|
13760
|
+
node: detailsNode,
|
|
13761
|
+
onClose: () => setDetailsNode(null),
|
|
13762
|
+
onSave: (data) => userActionHandlers.handleSaveNodeDetails(actionHandlerContext, data),
|
|
13763
|
+
onNameChange: handleDetailNodeNameChange,
|
|
13764
|
+
onColorChange: handleDetailNodeColorChange,
|
|
13765
|
+
onSizeChange: handleDetailNodeSizeChange,
|
|
13766
|
+
onDataUpdate: setDetailsNode,
|
|
13767
|
+
onOpenImageViewer: handleOpenImageViewer,
|
|
13768
|
+
existingTypes: existingNodeTypes,
|
|
13769
|
+
availableNodes: allAvailableNodes,
|
|
13770
|
+
availableAncestries: allAvailableAncestries,
|
|
13771
|
+
onOpenReference: handleOpenReference,
|
|
13772
|
+
onMentionClick: handleAddExistingNode,
|
|
13773
|
+
onUploadFile: upload_file_action,
|
|
13774
|
+
userRole: userPermissionRole,
|
|
13775
|
+
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
13776
|
+
}
|
|
13777
|
+
),
|
|
13778
|
+
detailsNode && !detailsNode.is_quest && /* @__PURE__ */ import_react26.default.createElement(
|
|
13438
13779
|
NodeDetailsPanel,
|
|
13439
13780
|
{
|
|
13440
13781
|
node: detailsNode,
|
|
@@ -13461,7 +13802,7 @@ function XViewScene({
|
|
|
13461
13802
|
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
13462
13803
|
}
|
|
13463
13804
|
),
|
|
13464
|
-
detailsLink && /* @__PURE__ */
|
|
13805
|
+
detailsLink && /* @__PURE__ */ import_react26.default.createElement(
|
|
13465
13806
|
RelationshipDetailsPanel,
|
|
13466
13807
|
{
|
|
13467
13808
|
link: detailsLink,
|
|
@@ -13475,7 +13816,7 @@ function XViewScene({
|
|
|
13475
13816
|
userRole: userPermissionRole
|
|
13476
13817
|
}
|
|
13477
13818
|
),
|
|
13478
|
-
ancestryLinkDetails && /* @__PURE__ */
|
|
13819
|
+
ancestryLinkDetails && /* @__PURE__ */ import_react26.default.createElement(
|
|
13479
13820
|
AncestryLinkDetailsPanel,
|
|
13480
13821
|
{
|
|
13481
13822
|
data: ancestryLinkDetails,
|
|
@@ -13486,7 +13827,7 @@ function XViewScene({
|
|
|
13486
13827
|
onUploadFile: upload_file_action
|
|
13487
13828
|
}
|
|
13488
13829
|
),
|
|
13489
|
-
/* @__PURE__ */
|
|
13830
|
+
/* @__PURE__ */ import_react26.default.createElement(
|
|
13490
13831
|
"div",
|
|
13491
13832
|
{
|
|
13492
13833
|
ref: tooltipRef,
|
|
@@ -13513,7 +13854,7 @@ function XViewScene({
|
|
|
13513
13854
|
}
|
|
13514
13855
|
}
|
|
13515
13856
|
),
|
|
13516
|
-
/* @__PURE__ */
|
|
13857
|
+
/* @__PURE__ */ import_react26.default.createElement(
|
|
13517
13858
|
ContextMenu,
|
|
13518
13859
|
{
|
|
13519
13860
|
data: contextMenu,
|
|
@@ -13536,7 +13877,7 @@ function XViewScene({
|
|
|
13536
13877
|
onFocusNode: handleFocusNode
|
|
13537
13878
|
}
|
|
13538
13879
|
),
|
|
13539
|
-
/* @__PURE__ */
|
|
13880
|
+
/* @__PURE__ */ import_react26.default.createElement(
|
|
13540
13881
|
MultiNodeContextMenu,
|
|
13541
13882
|
{
|
|
13542
13883
|
data: multiContextMenu,
|
|
@@ -13547,7 +13888,7 @@ function XViewScene({
|
|
|
13547
13888
|
onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
|
|
13548
13889
|
}
|
|
13549
13890
|
),
|
|
13550
|
-
/* @__PURE__ */
|
|
13891
|
+
/* @__PURE__ */ import_react26.default.createElement(
|
|
13551
13892
|
RelationshipContextMenu,
|
|
13552
13893
|
{
|
|
13553
13894
|
data: relationshipMenu,
|
|
@@ -13565,8 +13906,8 @@ function XViewScene({
|
|
|
13565
13906
|
onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
|
|
13566
13907
|
}
|
|
13567
13908
|
),
|
|
13568
|
-
/* @__PURE__ */
|
|
13569
|
-
/* @__PURE__ */
|
|
13909
|
+
/* @__PURE__ */ import_react26.default.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
|
|
13910
|
+
/* @__PURE__ */ import_react26.default.createElement(
|
|
13570
13911
|
AncestryBoard,
|
|
13571
13912
|
{
|
|
13572
13913
|
isOpen: isAncestryBoardOpen,
|
|
@@ -13579,7 +13920,7 @@ function XViewScene({
|
|
|
13579
13920
|
userRole: userPermissionRole
|
|
13580
13921
|
}
|
|
13581
13922
|
),
|
|
13582
|
-
/* @__PURE__ */
|
|
13923
|
+
/* @__PURE__ */ import_react26.default.createElement(
|
|
13583
13924
|
ImportParentFileModal,
|
|
13584
13925
|
{
|
|
13585
13926
|
isOpen: isImportModalOpen,
|