@lv-x-software-house/x_view 1.2.4-dev.1 → 1.2.4-dev.2
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 +589 -332
- package/dist/index.mjs +515 -258
- 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_react25 = __toESM(require("react"));
|
|
47
47
|
var import_navigation = require("next/navigation");
|
|
48
|
-
var
|
|
48
|
+
var import_react26 = 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");
|
|
@@ -7848,9 +7848,181 @@ function InSceneVersionForm({
|
|
|
7848
7848
|
));
|
|
7849
7849
|
}
|
|
7850
7850
|
|
|
7851
|
-
// src/components/
|
|
7851
|
+
// src/components/InSceneQuestForm.jsx
|
|
7852
7852
|
var import_react16 = __toESM(require("react"));
|
|
7853
7853
|
var import_fi14 = require("react-icons/fi");
|
|
7854
|
+
var QUEST_STATUS_COLORS = {
|
|
7855
|
+
"Backlog": "#64748b",
|
|
7856
|
+
// Slate (Cinza azulado)
|
|
7857
|
+
"In Progress": "#eab308",
|
|
7858
|
+
// Yellow (Amarelo)
|
|
7859
|
+
"Review": "#a855f7",
|
|
7860
|
+
// Purple (Roxo)
|
|
7861
|
+
"Done": "#22c55e"
|
|
7862
|
+
// Green (Verde)
|
|
7863
|
+
};
|
|
7864
|
+
function InSceneQuestForm({
|
|
7865
|
+
onSave,
|
|
7866
|
+
onCancel,
|
|
7867
|
+
style,
|
|
7868
|
+
refEl,
|
|
7869
|
+
onOpenImageViewer,
|
|
7870
|
+
availableNodes = [],
|
|
7871
|
+
availableAncestries = [],
|
|
7872
|
+
onMentionClick,
|
|
7873
|
+
onUploadFile
|
|
7874
|
+
}) {
|
|
7875
|
+
const [name, setName] = (0, import_react16.useState)("");
|
|
7876
|
+
const [types, setTypes] = (0, import_react16.useState)(["quest"]);
|
|
7877
|
+
const [typeInput, setTypeInput] = (0, import_react16.useState)("");
|
|
7878
|
+
const [status, setStatus] = (0, import_react16.useState)("Backlog");
|
|
7879
|
+
const [size, setSize] = (0, import_react16.useState)("medium");
|
|
7880
|
+
const [intensity, setIntensity] = (0, import_react16.useState)(0);
|
|
7881
|
+
const [description, setDescription] = (0, import_react16.useState)("");
|
|
7882
|
+
const [customProps, setCustomProps] = (0, import_react16.useState)([]);
|
|
7883
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react16.useState)(false);
|
|
7884
|
+
const propsEndRef = (0, import_react16.useRef)(null);
|
|
7885
|
+
const handleAddProp = () => {
|
|
7886
|
+
const newProp = createNewCustomProperty(customProps);
|
|
7887
|
+
setCustomProps([...customProps, newProp]);
|
|
7888
|
+
setTimeout(() => {
|
|
7889
|
+
var _a;
|
|
7890
|
+
(_a = propsEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
7891
|
+
}, 100);
|
|
7892
|
+
};
|
|
7893
|
+
const handleRemoveProp = (index) => setCustomProps(customProps.filter((_, i) => i !== index));
|
|
7894
|
+
const handleUpdateProp = (index, updatedProp) => {
|
|
7895
|
+
const newProps = [...customProps];
|
|
7896
|
+
newProps[index] = updatedProp;
|
|
7897
|
+
setCustomProps(newProps);
|
|
7898
|
+
};
|
|
7899
|
+
const handleAddType = (newType) => {
|
|
7900
|
+
const trimmed = newType.trim().toLowerCase();
|
|
7901
|
+
if (trimmed && !types.includes(trimmed)) {
|
|
7902
|
+
setTypes([...types, trimmed]);
|
|
7903
|
+
setTypeInput("");
|
|
7904
|
+
}
|
|
7905
|
+
};
|
|
7906
|
+
const handleRemoveType = (indexToRemove) => {
|
|
7907
|
+
if (types[indexToRemove] === "quest") return;
|
|
7908
|
+
setTypes(types.filter((_, index) => index !== indexToRemove));
|
|
7909
|
+
};
|
|
7910
|
+
const handleTypeInputKeyDown = (e) => {
|
|
7911
|
+
if (e.key === "Enter") {
|
|
7912
|
+
e.preventDefault();
|
|
7913
|
+
handleAddType(typeInput);
|
|
7914
|
+
} else if (e.key === "Backspace" && typeInput === "" && types.length > 1) {
|
|
7915
|
+
handleRemoveType(types.length - 1);
|
|
7916
|
+
}
|
|
7917
|
+
};
|
|
7918
|
+
const handleSubmit = (e) => {
|
|
7919
|
+
e.preventDefault();
|
|
7920
|
+
if (!name.trim()) {
|
|
7921
|
+
alert("O campo 'Nome' \xE9 obrigat\xF3rio.");
|
|
7922
|
+
return;
|
|
7923
|
+
}
|
|
7924
|
+
const additionalData = toObjectFromCustomProps(
|
|
7925
|
+
customProps.filter((prop) => prop.key.trim() && !prop.isEditing)
|
|
7926
|
+
);
|
|
7927
|
+
const processedSections = processDescriptionForSave(description, []);
|
|
7928
|
+
onSave({
|
|
7929
|
+
name: name.trim(),
|
|
7930
|
+
type: types,
|
|
7931
|
+
color: QUEST_STATUS_COLORS[status],
|
|
7932
|
+
// Cor atrelada ao status
|
|
7933
|
+
status,
|
|
7934
|
+
size,
|
|
7935
|
+
intensity,
|
|
7936
|
+
description: description.trim(),
|
|
7937
|
+
description_sections: processedSections,
|
|
7938
|
+
useImageAsTexture: false,
|
|
7939
|
+
textureImageUrl: null,
|
|
7940
|
+
...additionalData
|
|
7941
|
+
});
|
|
7942
|
+
};
|
|
7943
|
+
const swallow = (e) => e.stopPropagation();
|
|
7944
|
+
const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
|
|
7945
|
+
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
7946
|
+
return /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null, /* @__PURE__ */ import_react16.default.createElement(
|
|
7947
|
+
"div",
|
|
7948
|
+
{
|
|
7949
|
+
ref: refEl,
|
|
7950
|
+
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 w-[min(92vw,440px)] overflow-hidden",
|
|
7951
|
+
style,
|
|
7952
|
+
onPointerDown: swallow,
|
|
7953
|
+
onClick: swallow,
|
|
7954
|
+
onWheel: swallow,
|
|
7955
|
+
onContextMenu: swallow,
|
|
7956
|
+
onDoubleClick: swallow
|
|
7957
|
+
},
|
|
7958
|
+
/* @__PURE__ */ import_react16.default.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS[status]}, transparent)` } }),
|
|
7959
|
+
/* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pt-5 pb-3" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ import_react16.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova Tarefa / Objetivo")), /* @__PURE__ */ import_react16.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")),
|
|
7960
|
+
/* @__PURE__ */ import_react16.default.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col max-h-[68vh]" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ import_react16.default.createElement(
|
|
7961
|
+
"select",
|
|
7962
|
+
{
|
|
7963
|
+
value: status,
|
|
7964
|
+
onChange: (e) => setStatus(e.target.value),
|
|
7965
|
+
className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60 appearance-none cursor-pointer",
|
|
7966
|
+
style: { borderLeft: `4px solid ${QUEST_STATUS_COLORS[status]}` }
|
|
7967
|
+
},
|
|
7968
|
+
/* @__PURE__ */ import_react16.default.createElement("option", { value: "Backlog" }, "Backlog"),
|
|
7969
|
+
/* @__PURE__ */ import_react16.default.createElement("option", { value: "In Progress" }, "In Progress"),
|
|
7970
|
+
/* @__PURE__ */ import_react16.default.createElement("option", { value: "Review" }, "Review"),
|
|
7971
|
+
/* @__PURE__ */ import_react16.default.createElement("option", { value: "Done" }, "Done")
|
|
7972
|
+
)), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Quest"), /* @__PURE__ */ import_react16.default.createElement("input", { required: true, type: "text", placeholder: "Ex.: Refatorar M\xF3dulo X", value: name, onChange: (e) => setName(e.target.value), className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60" })), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Tipos Adicionais"), /* @__PURE__ */ import_react16.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 focus-within:ring-2 focus-within:ring-indigo-400/60 transition-all" }, types.map((t, index) => /* @__PURE__ */ import_react16.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, t !== "quest" && /* @__PURE__ */ import_react16.default.createElement("button", { type: "button", onClick: () => handleRemoveType(index), className: "hover:text-white transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(FiX, { size: 12 })))), /* @__PURE__ */ import_react16.default.createElement(
|
|
7973
|
+
"input",
|
|
7974
|
+
{
|
|
7975
|
+
type: "text",
|
|
7976
|
+
value: typeInput,
|
|
7977
|
+
onChange: (e) => setTypeInput(e.target.value),
|
|
7978
|
+
onKeyDown: handleTypeInputKeyDown,
|
|
7979
|
+
onBlur: () => {
|
|
7980
|
+
if (typeInput.trim()) handleAddType(typeInput);
|
|
7981
|
+
},
|
|
7982
|
+
className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
|
|
7983
|
+
placeholder: "Ex.: Bugfix",
|
|
7984
|
+
autoComplete: "off"
|
|
7985
|
+
}
|
|
7986
|
+
))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react16.default.createElement("div", { className: "relative group min-h-[80px] bg-slate-800/70 p-2.5 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(
|
|
7987
|
+
DescriptionDisplay,
|
|
7988
|
+
{
|
|
7989
|
+
description,
|
|
7990
|
+
savedSections: [],
|
|
7991
|
+
availableNodes,
|
|
7992
|
+
availableAncestries,
|
|
7993
|
+
onMentionClick,
|
|
7994
|
+
onSaveDescription: (newDesc) => setDescription(newDesc)
|
|
7995
|
+
}
|
|
7996
|
+
), /* @__PURE__ */ import_react16.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 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react16.default.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiEdit2, { size: 14 }))), !description && /* @__PURE__ */ import_react16.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_react16.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Cen\xE1rio (Size)"), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ import_react16.default.createElement("button", { key: s, type: "button", onClick: () => setSize(s), className: "flex items-center gap-2 group cursor-pointer focus:outline-none" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${size === s ? "bg-indigo-500 border-indigo-500" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, size === s && /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react16.default.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s))))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react16.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ import_react16.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_react16.default.createElement(import_fi14.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ import_react16.default.createElement(
|
|
7997
|
+
CustomPropertyDisplay,
|
|
7998
|
+
{
|
|
7999
|
+
key: prop.id,
|
|
8000
|
+
prop,
|
|
8001
|
+
onUpdate: (updatedProp) => handleUpdateProp(index, updatedProp),
|
|
8002
|
+
onRemove: () => handleRemoveProp(index),
|
|
8003
|
+
onOpenImageViewer,
|
|
8004
|
+
unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type),
|
|
8005
|
+
onUploadFile
|
|
8006
|
+
}
|
|
8007
|
+
)), /* @__PURE__ */ import_react16.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react16.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_react16.default.createElement("button", { type: "button", onClick: onCancel, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm" }, "Cancelar"), /* @__PURE__ */ import_react16.default.createElement("button", { type: "submit", className: "px-4 py-2 rounded-lg bg-gradient-to-tr from-indigo-600 to-indigo-400 hover:from-indigo-500 hover:to-indigo-300 transition-colors font-semibold text-sm shadow-[0_8px_24px_rgba(99,102,241,0.35)]" }, "Salvar Quest")))
|
|
8008
|
+
), isDescriptionModalOpen && /* @__PURE__ */ import_react16.default.createElement(
|
|
8009
|
+
DescriptionEditModal,
|
|
8010
|
+
{
|
|
8011
|
+
isOpen: isDescriptionModalOpen,
|
|
8012
|
+
title: "Editar Descri\xE7\xE3o da Quest",
|
|
8013
|
+
initialValue: description,
|
|
8014
|
+
onSave: (newDescription) => setDescription(newDescription),
|
|
8015
|
+
onClose: () => setIsDescriptionModalOpen(false),
|
|
8016
|
+
availableNodes,
|
|
8017
|
+
availableAncestries,
|
|
8018
|
+
availableImages
|
|
8019
|
+
}
|
|
8020
|
+
));
|
|
8021
|
+
}
|
|
8022
|
+
|
|
8023
|
+
// src/components/NodeDetailsPanel.jsx
|
|
8024
|
+
var import_react17 = __toESM(require("react"));
|
|
8025
|
+
var import_fi15 = require("react-icons/fi");
|
|
7854
8026
|
function NodeDetailsPanel({
|
|
7855
8027
|
node,
|
|
7856
8028
|
onClose,
|
|
@@ -7871,38 +8043,38 @@ function NodeDetailsPanel({
|
|
|
7871
8043
|
userRole,
|
|
7872
8044
|
currentDatasetName
|
|
7873
8045
|
}) {
|
|
7874
|
-
const [name, setName] = (0,
|
|
7875
|
-
const [types, setTypes] = (0,
|
|
7876
|
-
const [typeInput, setTypeInput] = (0,
|
|
7877
|
-
const [color, setColor] = (0,
|
|
7878
|
-
const [size, setSize] = (0,
|
|
7879
|
-
const [description, setDescription] = (0,
|
|
7880
|
-
const [intensity, setIntensity] = (0,
|
|
7881
|
-
const [customProps, setCustomProps] = (0,
|
|
7882
|
-
const [showTypeSuggestions, setShowTypeSuggestions] = (0,
|
|
7883
|
-
const [filteredTypes, setFilteredTypes] = (0,
|
|
7884
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0,
|
|
7885
|
-
const [isReadMode, setIsReadMode] = (0,
|
|
7886
|
-
const [existingSections, setExistingSections] = (0,
|
|
7887
|
-
const [isSaving, setIsSaving] = (0,
|
|
7888
|
-
const [isLinkCopied, setIsLinkCopied] = (0,
|
|
7889
|
-
const [useImageAsTexture, setUseImageAsTexture] = (0,
|
|
8046
|
+
const [name, setName] = (0, import_react17.useState)((node == null ? void 0 : node.name) ?? "");
|
|
8047
|
+
const [types, setTypes] = (0, import_react17.useState)([]);
|
|
8048
|
+
const [typeInput, setTypeInput] = (0, import_react17.useState)("");
|
|
8049
|
+
const [color, setColor] = (0, import_react17.useState)((node == null ? void 0 : node.color) ?? "#8b5cf6");
|
|
8050
|
+
const [size, setSize] = (0, import_react17.useState)((node == null ? void 0 : node.size) ?? "medium");
|
|
8051
|
+
const [description, setDescription] = (0, import_react17.useState)((node == null ? void 0 : node.description) ?? "");
|
|
8052
|
+
const [intensity, setIntensity] = (0, import_react17.useState)((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
|
|
8053
|
+
const [customProps, setCustomProps] = (0, import_react17.useState)(() => extractCustomPropsFromNode(node || {}));
|
|
8054
|
+
const [showTypeSuggestions, setShowTypeSuggestions] = (0, import_react17.useState)(false);
|
|
8055
|
+
const [filteredTypes, setFilteredTypes] = (0, import_react17.useState)([]);
|
|
8056
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react17.useState)(false);
|
|
8057
|
+
const [isReadMode, setIsReadMode] = (0, import_react17.useState)(false);
|
|
8058
|
+
const [existingSections, setExistingSections] = (0, import_react17.useState)((node == null ? void 0 : node.description_sections) || []);
|
|
8059
|
+
const [isSaving, setIsSaving] = (0, import_react17.useState)(false);
|
|
8060
|
+
const [isLinkCopied, setIsLinkCopied] = (0, import_react17.useState)(false);
|
|
8061
|
+
const [useImageAsTexture, setUseImageAsTexture] = (0, import_react17.useState)(() => {
|
|
7890
8062
|
if ((node == null ? void 0 : node.useImageAsTexture) === "true") return true;
|
|
7891
8063
|
if ((node == null ? void 0 : node.useImageAsTexture) === "false") return false;
|
|
7892
8064
|
return !!(node == null ? void 0 : node.useImageAsTexture);
|
|
7893
8065
|
});
|
|
7894
|
-
const [selectedImageUrl, setSelectedImageUrl] = (0,
|
|
8066
|
+
const [selectedImageUrl, setSelectedImageUrl] = (0, import_react17.useState)((node == null ? void 0 : node.textureImageUrl) ?? null);
|
|
7895
8067
|
const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
|
|
7896
8068
|
const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
|
|
7897
8069
|
initialWidth: isReadMode ? 700 : 440,
|
|
7898
8070
|
minWidth: 320,
|
|
7899
8071
|
maxWidth: maxPanelW
|
|
7900
8072
|
});
|
|
7901
|
-
(0,
|
|
8073
|
+
(0, import_react17.useEffect)(() => {
|
|
7902
8074
|
setWidth(isReadMode ? 700 : 440);
|
|
7903
8075
|
}, [isReadMode, setWidth]);
|
|
7904
|
-
const prevNodeIdRef = (0,
|
|
7905
|
-
const propsEndRef = (0,
|
|
8076
|
+
const prevNodeIdRef = (0, import_react17.useRef)(null);
|
|
8077
|
+
const propsEndRef = (0, import_react17.useRef)(null);
|
|
7906
8078
|
const canEdit = userRole !== "viewer";
|
|
7907
8079
|
const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
|
|
7908
8080
|
const handleImageClickFromText = (url, name2) => {
|
|
@@ -7910,7 +8082,7 @@ function NodeDetailsPanel({
|
|
|
7910
8082
|
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
7911
8083
|
}
|
|
7912
8084
|
};
|
|
7913
|
-
(0,
|
|
8085
|
+
(0, import_react17.useEffect)(() => {
|
|
7914
8086
|
if ((node == null ? void 0 : node.id) !== prevNodeIdRef.current) {
|
|
7915
8087
|
prevNodeIdRef.current = node == null ? void 0 : node.id;
|
|
7916
8088
|
setName((node == null ? void 0 : node.name) ?? "");
|
|
@@ -7932,13 +8104,13 @@ function NodeDetailsPanel({
|
|
|
7932
8104
|
}
|
|
7933
8105
|
}, [node]);
|
|
7934
8106
|
const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
|
|
7935
|
-
(0,
|
|
8107
|
+
(0, import_react17.useEffect)(() => {
|
|
7936
8108
|
if (!hasImages && useImageAsTexture) {
|
|
7937
8109
|
setUseImageAsTexture(false);
|
|
7938
8110
|
setSelectedImageUrl(null);
|
|
7939
8111
|
}
|
|
7940
8112
|
}, [hasImages, useImageAsTexture]);
|
|
7941
|
-
(0,
|
|
8113
|
+
(0, import_react17.useEffect)(() => {
|
|
7942
8114
|
if (typeInput.trim() === "") {
|
|
7943
8115
|
setFilteredTypes(existingTypes.filter((t) => !types.includes(t)));
|
|
7944
8116
|
} else {
|
|
@@ -8110,7 +8282,7 @@ function NodeDetailsPanel({
|
|
|
8110
8282
|
onClose();
|
|
8111
8283
|
};
|
|
8112
8284
|
const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
|
|
8113
|
-
return /* @__PURE__ */
|
|
8285
|
+
return /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement(
|
|
8114
8286
|
"div",
|
|
8115
8287
|
{
|
|
8116
8288
|
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"}`,
|
|
@@ -8123,7 +8295,7 @@ function NodeDetailsPanel({
|
|
|
8123
8295
|
onContextMenu: swallow,
|
|
8124
8296
|
onDoubleClick: swallow
|
|
8125
8297
|
},
|
|
8126
|
-
/* @__PURE__ */
|
|
8298
|
+
/* @__PURE__ */ import_react17.default.createElement(
|
|
8127
8299
|
"div",
|
|
8128
8300
|
{
|
|
8129
8301
|
onPointerDown: (e) => {
|
|
@@ -8134,7 +8306,7 @@ function NodeDetailsPanel({
|
|
|
8134
8306
|
title: "Arraste para redimensionar"
|
|
8135
8307
|
}
|
|
8136
8308
|
),
|
|
8137
|
-
isReadMode ? /* @__PURE__ */
|
|
8309
|
+
isReadMode ? /* @__PURE__ */ import_react17.default.createElement(
|
|
8138
8310
|
DescriptionReadModePanel,
|
|
8139
8311
|
{
|
|
8140
8312
|
title: name || (node == null ? void 0 : node.name),
|
|
@@ -8155,23 +8327,23 @@ function NodeDetailsPanel({
|
|
|
8155
8327
|
onImageClick: handleImageClickFromText,
|
|
8156
8328
|
onSaveDescription: handleSaveDescriptionInline
|
|
8157
8329
|
}
|
|
8158
|
-
) : /* @__PURE__ */
|
|
8330
|
+
) : /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ import_react17.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react17.default.createElement("div", null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react17.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ import_react17.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ import_react17.default.createElement(
|
|
8159
8331
|
"button",
|
|
8160
8332
|
{
|
|
8161
8333
|
onClick: handleCopyLink,
|
|
8162
8334
|
className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
|
|
8163
8335
|
title: isLinkCopied ? "Link Copiado!" : "Copiar link para este Node"
|
|
8164
8336
|
},
|
|
8165
|
-
isLinkCopied ? /* @__PURE__ */
|
|
8166
|
-
)), /* @__PURE__ */
|
|
8337
|
+
isLinkCopied ? /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiCheck, { size: 12 }) : /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiLink, { size: 12 })
|
|
8338
|
+
)), /* @__PURE__ */ import_react17.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ import_react17.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_react17.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Tipos"), /* @__PURE__ */ import_react17.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_react17.default.createElement("span", { key: index, className: "flex items-center gap-1 bg-indigo-500/30 text-indigo-100 px-1.5 py-0.5 rounded-md text-xs font-medium border border-indigo-500/20" }, t, canEdit && /* @__PURE__ */ import_react17.default.createElement(
|
|
8167
8339
|
"button",
|
|
8168
8340
|
{
|
|
8169
8341
|
type: "button",
|
|
8170
8342
|
onClick: () => handleRemoveType(index),
|
|
8171
8343
|
className: "hover:text-white transition-colors"
|
|
8172
8344
|
},
|
|
8173
|
-
/* @__PURE__ */
|
|
8174
|
-
))), canEdit && /* @__PURE__ */
|
|
8345
|
+
/* @__PURE__ */ import_react17.default.createElement(import_fi15.FiX, { size: 12 })
|
|
8346
|
+
))), canEdit && /* @__PURE__ */ import_react17.default.createElement(
|
|
8175
8347
|
"input",
|
|
8176
8348
|
{
|
|
8177
8349
|
type: "text",
|
|
@@ -8192,7 +8364,7 @@ function NodeDetailsPanel({
|
|
|
8192
8364
|
placeholder: types.length === 0 ? "Ex.: Cliente" : "",
|
|
8193
8365
|
autoComplete: "off"
|
|
8194
8366
|
}
|
|
8195
|
-
), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */
|
|
8367
|
+
), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */ import_react17.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_react17.default.createElement(
|
|
8196
8368
|
"li",
|
|
8197
8369
|
{
|
|
8198
8370
|
key: index,
|
|
@@ -8203,7 +8375,7 @@ function NodeDetailsPanel({
|
|
|
8203
8375
|
}
|
|
8204
8376
|
},
|
|
8205
8377
|
suggestedType
|
|
8206
|
-
))))), /* @__PURE__ */
|
|
8378
|
+
))))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome"), /* @__PURE__ */ import_react17.default.createElement(
|
|
8207
8379
|
"input",
|
|
8208
8380
|
{
|
|
8209
8381
|
type: "text",
|
|
@@ -8212,7 +8384,7 @@ function NodeDetailsPanel({
|
|
|
8212
8384
|
readOnly: !canEdit,
|
|
8213
8385
|
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"}`
|
|
8214
8386
|
}
|
|
8215
|
-
)), /* @__PURE__ */
|
|
8387
|
+
)), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react17.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_react17.default.createElement(
|
|
8216
8388
|
DescriptionDisplay,
|
|
8217
8389
|
{
|
|
8218
8390
|
description,
|
|
@@ -8224,7 +8396,7 @@ function NodeDetailsPanel({
|
|
|
8224
8396
|
onImageClick: handleImageClickFromText,
|
|
8225
8397
|
onSaveDescription: handleSaveDescriptionInline
|
|
8226
8398
|
}
|
|
8227
|
-
), /* @__PURE__ */
|
|
8399
|
+
), /* @__PURE__ */ import_react17.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_react17.default.createElement(
|
|
8228
8400
|
"button",
|
|
8229
8401
|
{
|
|
8230
8402
|
type: "button",
|
|
@@ -8232,8 +8404,8 @@ function NodeDetailsPanel({
|
|
|
8232
8404
|
className: `p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors ${canEdit ? "border-r border-white/5" : ""}`,
|
|
8233
8405
|
title: "Modo de Leitura"
|
|
8234
8406
|
},
|
|
8235
|
-
/* @__PURE__ */
|
|
8236
|
-
), canEdit && /* @__PURE__ */
|
|
8407
|
+
/* @__PURE__ */ import_react17.default.createElement(import_fi15.FiBookOpen, { size: 14 })
|
|
8408
|
+
), canEdit && /* @__PURE__ */ import_react17.default.createElement(
|
|
8237
8409
|
"button",
|
|
8238
8410
|
{
|
|
8239
8411
|
type: "button",
|
|
@@ -8241,17 +8413,17 @@ function NodeDetailsPanel({
|
|
|
8241
8413
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8242
8414
|
title: "Editar descri\xE7\xE3o (Modo de Escrita)"
|
|
8243
8415
|
},
|
|
8244
|
-
/* @__PURE__ */
|
|
8245
|
-
)), canEdit && !description && /* @__PURE__ */
|
|
8416
|
+
/* @__PURE__ */ import_react17.default.createElement(import_fi15.FiEdit2, { size: 14 })
|
|
8417
|
+
)), canEdit && !description && /* @__PURE__ */ import_react17.default.createElement(
|
|
8246
8418
|
"div",
|
|
8247
8419
|
{
|
|
8248
8420
|
onClick: () => setIsDescriptionModalOpen(true),
|
|
8249
8421
|
className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
|
|
8250
8422
|
},
|
|
8251
8423
|
"Adicionar descri\xE7\xE3o..."
|
|
8252
|
-
))), /* @__PURE__ */
|
|
8424
|
+
))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Size"), /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
|
|
8253
8425
|
const isSelected = size === s;
|
|
8254
|
-
return /* @__PURE__ */
|
|
8426
|
+
return /* @__PURE__ */ import_react17.default.createElement(
|
|
8255
8427
|
"button",
|
|
8256
8428
|
{
|
|
8257
8429
|
key: s,
|
|
@@ -8259,10 +8431,10 @@ function NodeDetailsPanel({
|
|
|
8259
8431
|
onClick: () => canEdit && handleSizeChange(s),
|
|
8260
8432
|
className: `flex items-center gap-2 group focus:outline-none ${canEdit ? "cursor-pointer" : "cursor-default opacity-80"}`
|
|
8261
8433
|
},
|
|
8262
|
-
/* @__PURE__ */
|
|
8263
|
-
/* @__PURE__ */
|
|
8434
|
+
/* @__PURE__ */ import_react17.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_react17.default.createElement(import_fi15.FiCheck, { size: 12, className: "text-white" })),
|
|
8435
|
+
/* @__PURE__ */ import_react17.default.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s)
|
|
8264
8436
|
);
|
|
8265
|
-
}))), /* @__PURE__ */
|
|
8437
|
+
}))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), canEdit && hasImages && /* @__PURE__ */ import_react17.default.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${useImageAsTexture ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, useImageAsTexture && /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react17.default.createElement(
|
|
8266
8438
|
"input",
|
|
8267
8439
|
{
|
|
8268
8440
|
type: "checkbox",
|
|
@@ -8270,14 +8442,14 @@ function NodeDetailsPanel({
|
|
|
8270
8442
|
onChange: handleToggleImageMode,
|
|
8271
8443
|
className: "hidden"
|
|
8272
8444
|
}
|
|
8273
|
-
), /* @__PURE__ */
|
|
8445
|
+
), /* @__PURE__ */ import_react17.default.createElement("span", { className: `text-xs ${useImageAsTexture ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, "Usar imagem para representar o node"))), /* @__PURE__ */ import_react17.default.createElement(
|
|
8274
8446
|
ColorPicker,
|
|
8275
8447
|
{
|
|
8276
8448
|
color,
|
|
8277
8449
|
onChange: handleColorChange,
|
|
8278
8450
|
disabled: !canEdit || useImageAsTexture
|
|
8279
8451
|
}
|
|
8280
|
-
), /* @__PURE__ */
|
|
8452
|
+
), /* @__PURE__ */ import_react17.default.createElement("div", { className: "mt-3 flex items-center gap-3" }, /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiSun, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ import_react17.default.createElement(
|
|
8281
8453
|
"input",
|
|
8282
8454
|
{
|
|
8283
8455
|
type: "range",
|
|
@@ -8290,7 +8462,7 @@ function NodeDetailsPanel({
|
|
|
8290
8462
|
className: `w-full h-1.5 bg-slate-700 rounded-lg appearance-none ${canEdit ? "cursor-pointer accent-indigo-500 hover:accent-indigo-400" : "cursor-default accent-slate-500"}`,
|
|
8291
8463
|
title: `Intensidade do brilho: ${intensity}`
|
|
8292
8464
|
}
|
|
8293
|
-
), /* @__PURE__ */
|
|
8465
|
+
), /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-xs text-slate-400 w-6 text-right" }, intensity)), /* @__PURE__ */ import_react17.default.createElement("span", { className: `text-xs block mt-1 transition-opacity ${useImageAsTexture ? "opacity-40" : "text-slate-400"}` }, useImageAsTexture ? "Cor da borda (definida pela imagem)" : "Ajuste a cor e a intensidade do brilho.")), /* @__PURE__ */ import_react17.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react17.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react17.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_react17.default.createElement(import_fi15.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react17.default.createElement(
|
|
8294
8466
|
CustomPropertyDisplay,
|
|
8295
8467
|
{
|
|
8296
8468
|
key: prop.id,
|
|
@@ -8305,7 +8477,7 @@ function NodeDetailsPanel({
|
|
|
8305
8477
|
onUploadFile: canEdit ? onUploadFile : void 0,
|
|
8306
8478
|
readOnly: !canEdit
|
|
8307
8479
|
}
|
|
8308
|
-
)), /* @__PURE__ */
|
|
8480
|
+
)), /* @__PURE__ */ import_react17.default.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ import_react17.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_react17.default.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ import_react17.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_react17.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_react17.default.createElement(
|
|
8309
8481
|
"button",
|
|
8310
8482
|
{
|
|
8311
8483
|
onClick: () => handleSave(false),
|
|
@@ -8314,10 +8486,10 @@ function NodeDetailsPanel({
|
|
|
8314
8486
|
${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"}
|
|
8315
8487
|
`
|
|
8316
8488
|
},
|
|
8317
|
-
isSaving && /* @__PURE__ */
|
|
8489
|
+
isSaving && /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiLoader, { className: "animate-spin" }),
|
|
8318
8490
|
isSaving ? "Salvando..." : "Salvar"
|
|
8319
8491
|
)))
|
|
8320
|
-
), isDescriptionModalOpen && canEdit && /* @__PURE__ */
|
|
8492
|
+
), isDescriptionModalOpen && canEdit && /* @__PURE__ */ import_react17.default.createElement(
|
|
8321
8493
|
DescriptionEditModal,
|
|
8322
8494
|
{
|
|
8323
8495
|
isOpen: isDescriptionModalOpen,
|
|
@@ -8337,7 +8509,7 @@ function NodeDetailsPanel({
|
|
|
8337
8509
|
}
|
|
8338
8510
|
|
|
8339
8511
|
// src/components/MultiNodeContextMenu.jsx
|
|
8340
|
-
var
|
|
8512
|
+
var import_react18 = __toESM(require("react"));
|
|
8341
8513
|
function MultiNodeContextMenu({
|
|
8342
8514
|
data,
|
|
8343
8515
|
userRole,
|
|
@@ -8346,12 +8518,12 @@ function MultiNodeContextMenu({
|
|
|
8346
8518
|
onDismissOtherNodes,
|
|
8347
8519
|
onDeleteNodes
|
|
8348
8520
|
}) {
|
|
8349
|
-
const menuRef = (0,
|
|
8350
|
-
const [menuPos, setMenuPos] = (0,
|
|
8351
|
-
const [isConfirmingDelete, setIsConfirmingDelete] = (0,
|
|
8521
|
+
const menuRef = (0, import_react18.useRef)(null);
|
|
8522
|
+
const [menuPos, setMenuPos] = (0, import_react18.useState)({ left: 0, top: 0 });
|
|
8523
|
+
const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react18.useState)(false);
|
|
8352
8524
|
const ability = defineAbilityFor(userRole);
|
|
8353
8525
|
const canDelete = ability.can("delete", "Node");
|
|
8354
|
-
(0,
|
|
8526
|
+
(0, import_react18.useLayoutEffect)(() => {
|
|
8355
8527
|
if (!data.visible || !menuRef.current) return;
|
|
8356
8528
|
const el = menuRef.current;
|
|
8357
8529
|
const w = el.clientWidth;
|
|
@@ -8364,7 +8536,7 @@ function MultiNodeContextMenu({
|
|
|
8364
8536
|
if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
|
|
8365
8537
|
setMenuPos({ left, top });
|
|
8366
8538
|
}, [data]);
|
|
8367
|
-
(0,
|
|
8539
|
+
(0, import_react18.useEffect)(() => {
|
|
8368
8540
|
if (data.visible) {
|
|
8369
8541
|
setIsConfirmingDelete(false);
|
|
8370
8542
|
}
|
|
@@ -8379,7 +8551,7 @@ function MultiNodeContextMenu({
|
|
|
8379
8551
|
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";
|
|
8380
8552
|
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";
|
|
8381
8553
|
const nodeCount = data.nodeIds.size;
|
|
8382
|
-
return /* @__PURE__ */
|
|
8554
|
+
return /* @__PURE__ */ import_react18.default.createElement(
|
|
8383
8555
|
"div",
|
|
8384
8556
|
{
|
|
8385
8557
|
ref: menuRef,
|
|
@@ -8393,28 +8565,28 @@ function MultiNodeContextMenu({
|
|
|
8393
8565
|
onContextMenu: swallow,
|
|
8394
8566
|
onDoubleClick: swallow
|
|
8395
8567
|
},
|
|
8396
|
-
/* @__PURE__ */
|
|
8397
|
-
/* @__PURE__ */
|
|
8568
|
+
/* @__PURE__ */ import_react18.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
|
|
8569
|
+
/* @__PURE__ */ import_react18.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react18.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_react18.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_react18.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react18.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_react18.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ import_react18.default.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ import_react18.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_react18.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react18.default.createElement(
|
|
8398
8570
|
"button",
|
|
8399
8571
|
{
|
|
8400
8572
|
onClick: () => setIsConfirmingDelete(false),
|
|
8401
8573
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
|
|
8402
8574
|
},
|
|
8403
8575
|
"Cancelar"
|
|
8404
|
-
), /* @__PURE__ */
|
|
8576
|
+
), /* @__PURE__ */ import_react18.default.createElement(
|
|
8405
8577
|
"button",
|
|
8406
8578
|
{
|
|
8407
8579
|
onClick: () => onDeleteNodes(data.nodeIds),
|
|
8408
8580
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
|
|
8409
8581
|
},
|
|
8410
8582
|
"Excluir"
|
|
8411
|
-
))) : /* @__PURE__ */
|
|
8583
|
+
))) : /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react18.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_react18.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_react18.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react18.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_react18.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react18.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
|
|
8412
8584
|
);
|
|
8413
8585
|
}
|
|
8414
8586
|
|
|
8415
8587
|
// src/components/RelationshipDetailsPanel.jsx
|
|
8416
|
-
var
|
|
8417
|
-
var
|
|
8588
|
+
var import_react19 = __toESM(require("react"));
|
|
8589
|
+
var import_fi16 = require("react-icons/fi");
|
|
8418
8590
|
function RelationshipDetailsPanel({
|
|
8419
8591
|
link,
|
|
8420
8592
|
onClose,
|
|
@@ -8428,19 +8600,19 @@ function RelationshipDetailsPanel({
|
|
|
8428
8600
|
onUploadFile,
|
|
8429
8601
|
userRole
|
|
8430
8602
|
}) {
|
|
8431
|
-
const [name, setName] = (0,
|
|
8432
|
-
const [description, setDescription] = (0,
|
|
8433
|
-
const [customProps, setCustomProps] = (0,
|
|
8434
|
-
const [existingSections, setExistingSections] = (0,
|
|
8435
|
-
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0,
|
|
8436
|
-
const [isSaving, setIsSaving] = (0,
|
|
8437
|
-
const [isReadMode, setIsReadMode] = (0,
|
|
8438
|
-
const propsEndRef = (0,
|
|
8439
|
-
const canEdit = (0,
|
|
8603
|
+
const [name, setName] = (0, import_react19.useState)((link == null ? void 0 : link.name) ?? "");
|
|
8604
|
+
const [description, setDescription] = (0, import_react19.useState)((link == null ? void 0 : link.description) ?? "");
|
|
8605
|
+
const [customProps, setCustomProps] = (0, import_react19.useState)(() => extractCustomPropsFromNode(link || {}));
|
|
8606
|
+
const [existingSections, setExistingSections] = (0, import_react19.useState)((link == null ? void 0 : link.description_sections) || []);
|
|
8607
|
+
const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react19.useState)(false);
|
|
8608
|
+
const [isSaving, setIsSaving] = (0, import_react19.useState)(false);
|
|
8609
|
+
const [isReadMode, setIsReadMode] = (0, import_react19.useState)(false);
|
|
8610
|
+
const propsEndRef = (0, import_react19.useRef)(null);
|
|
8611
|
+
const canEdit = (0, import_react19.useMemo)(() => {
|
|
8440
8612
|
const ability = defineAbilityFor(userRole);
|
|
8441
8613
|
return ability.can("update", "Connection");
|
|
8442
8614
|
}, [userRole]);
|
|
8443
|
-
(0,
|
|
8615
|
+
(0, import_react19.useEffect)(() => {
|
|
8444
8616
|
setName((link == null ? void 0 : link.name) ?? "");
|
|
8445
8617
|
setDescription((link == null ? void 0 : link.description) ?? "");
|
|
8446
8618
|
setExistingSections((link == null ? void 0 : link.description_sections) || []);
|
|
@@ -8515,7 +8687,7 @@ function RelationshipDetailsPanel({
|
|
|
8515
8687
|
onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
|
|
8516
8688
|
}
|
|
8517
8689
|
};
|
|
8518
|
-
return /* @__PURE__ */
|
|
8690
|
+
return /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement(
|
|
8519
8691
|
"div",
|
|
8520
8692
|
{
|
|
8521
8693
|
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
|
|
@@ -8530,7 +8702,7 @@ function RelationshipDetailsPanel({
|
|
|
8530
8702
|
onContextMenu: swallow,
|
|
8531
8703
|
onDoubleClick: swallow
|
|
8532
8704
|
},
|
|
8533
|
-
isReadMode ? /* @__PURE__ */
|
|
8705
|
+
isReadMode ? /* @__PURE__ */ import_react19.default.createElement(
|
|
8534
8706
|
DescriptionReadModePanel,
|
|
8535
8707
|
{
|
|
8536
8708
|
title: name || "Rela\xE7\xE3o",
|
|
@@ -8551,7 +8723,7 @@ function RelationshipDetailsPanel({
|
|
|
8551
8723
|
onImageClick: handleImageClickFromText,
|
|
8552
8724
|
onSaveDescription: handleSaveDescriptionInline
|
|
8553
8725
|
}
|
|
8554
|
-
) : /* @__PURE__ */
|
|
8726
|
+
) : /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ import_react19.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react19.default.createElement("div", null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react19.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_react19.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.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_react19.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react19.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react19.default.createElement(
|
|
8555
8727
|
"input",
|
|
8556
8728
|
{
|
|
8557
8729
|
type: "text",
|
|
@@ -8563,7 +8735,7 @@ function RelationshipDetailsPanel({
|
|
|
8563
8735
|
${!canEdit ? "opacity-50 cursor-not-allowed" : ""}
|
|
8564
8736
|
`
|
|
8565
8737
|
}
|
|
8566
|
-
)), /* @__PURE__ */
|
|
8738
|
+
)), /* @__PURE__ */ import_react19.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react19.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react19.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_react19.default.createElement(
|
|
8567
8739
|
DescriptionDisplay,
|
|
8568
8740
|
{
|
|
8569
8741
|
description,
|
|
@@ -8575,7 +8747,7 @@ function RelationshipDetailsPanel({
|
|
|
8575
8747
|
onImageClick: handleImageClickFromText,
|
|
8576
8748
|
onSaveDescription: handleSaveDescriptionInline
|
|
8577
8749
|
}
|
|
8578
|
-
), /* @__PURE__ */
|
|
8750
|
+
), /* @__PURE__ */ import_react19.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_react19.default.createElement(
|
|
8579
8751
|
"button",
|
|
8580
8752
|
{
|
|
8581
8753
|
type: "button",
|
|
@@ -8583,8 +8755,8 @@ function RelationshipDetailsPanel({
|
|
|
8583
8755
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors border-r border-white/5",
|
|
8584
8756
|
title: "Modo de Leitura"
|
|
8585
8757
|
},
|
|
8586
|
-
/* @__PURE__ */
|
|
8587
|
-
), canEdit && /* @__PURE__ */
|
|
8758
|
+
/* @__PURE__ */ import_react19.default.createElement(import_fi16.FiBookOpen, { size: 14 })
|
|
8759
|
+
), canEdit && /* @__PURE__ */ import_react19.default.createElement(
|
|
8588
8760
|
"button",
|
|
8589
8761
|
{
|
|
8590
8762
|
type: "button",
|
|
@@ -8592,15 +8764,15 @@ function RelationshipDetailsPanel({
|
|
|
8592
8764
|
className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8593
8765
|
title: "Editar descri\xE7\xE3o"
|
|
8594
8766
|
},
|
|
8595
|
-
/* @__PURE__ */
|
|
8596
|
-
)), !description && canEdit && /* @__PURE__ */
|
|
8767
|
+
/* @__PURE__ */ import_react19.default.createElement(import_fi16.FiEdit2, { size: 14 })
|
|
8768
|
+
)), !description && canEdit && /* @__PURE__ */ import_react19.default.createElement(
|
|
8597
8769
|
"div",
|
|
8598
8770
|
{
|
|
8599
8771
|
onClick: () => setIsDescriptionModalOpen(true),
|
|
8600
8772
|
className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
|
|
8601
8773
|
},
|
|
8602
8774
|
"Adicionar descri\xE7\xE3o..."
|
|
8603
|
-
))), /* @__PURE__ */
|
|
8775
|
+
))), /* @__PURE__ */ import_react19.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react19.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react19.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_react19.default.createElement(import_fi16.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react19.default.createElement(
|
|
8604
8776
|
CustomPropertyDisplay,
|
|
8605
8777
|
{
|
|
8606
8778
|
key: prop.id,
|
|
@@ -8612,7 +8784,7 @@ function RelationshipDetailsPanel({
|
|
|
8612
8784
|
onUploadFile,
|
|
8613
8785
|
disabled: !canEdit
|
|
8614
8786
|
}
|
|
8615
|
-
)), /* @__PURE__ */
|
|
8787
|
+
)), /* @__PURE__ */ import_react19.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react19.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_react19.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_react19.default.createElement(
|
|
8616
8788
|
"button",
|
|
8617
8789
|
{
|
|
8618
8790
|
onClick: () => handleSave(false),
|
|
@@ -8621,10 +8793,10 @@ function RelationshipDetailsPanel({
|
|
|
8621
8793
|
${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"}
|
|
8622
8794
|
`
|
|
8623
8795
|
},
|
|
8624
|
-
isSaving && /* @__PURE__ */
|
|
8796
|
+
isSaving && /* @__PURE__ */ import_react19.default.createElement(import_fi16.FiLoader, { className: "animate-spin" }),
|
|
8625
8797
|
isSaving ? "Salvando..." : "Salvar"
|
|
8626
8798
|
)))
|
|
8627
|
-
), isDescriptionModalOpen && /* @__PURE__ */
|
|
8799
|
+
), isDescriptionModalOpen && /* @__PURE__ */ import_react19.default.createElement(
|
|
8628
8800
|
DescriptionEditModal,
|
|
8629
8801
|
{
|
|
8630
8802
|
isOpen: isDescriptionModalOpen,
|
|
@@ -8645,7 +8817,7 @@ function RelationshipDetailsPanel({
|
|
|
8645
8817
|
}
|
|
8646
8818
|
|
|
8647
8819
|
// src/components/RelationshipContextMenu.jsx
|
|
8648
|
-
var
|
|
8820
|
+
var import_react20 = __toESM(require("react"));
|
|
8649
8821
|
function RelationshipContextMenu({
|
|
8650
8822
|
data,
|
|
8651
8823
|
userRole,
|
|
@@ -8655,25 +8827,25 @@ function RelationshipContextMenu({
|
|
|
8655
8827
|
onDelete,
|
|
8656
8828
|
onClose
|
|
8657
8829
|
}) {
|
|
8658
|
-
const menuRef = (0,
|
|
8659
|
-
const [menuPos, setMenuPos] = (0,
|
|
8660
|
-
const [isConfirmingDelete, setIsConfirmingDelete] = (0,
|
|
8661
|
-
const ability = (0,
|
|
8662
|
-
const sourceName = (0,
|
|
8830
|
+
const menuRef = (0, import_react20.useRef)(null);
|
|
8831
|
+
const [menuPos, setMenuPos] = (0, import_react20.useState)({ left: 0, top: 0 });
|
|
8832
|
+
const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react20.useState)(false);
|
|
8833
|
+
const ability = (0, import_react20.useMemo)(() => defineAbilityFor(userRole), [userRole]);
|
|
8834
|
+
const sourceName = (0, import_react20.useMemo)(
|
|
8663
8835
|
() => {
|
|
8664
8836
|
var _a, _b, _c, _d;
|
|
8665
8837
|
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)";
|
|
8666
8838
|
},
|
|
8667
8839
|
[data == null ? void 0 : data.linkObject]
|
|
8668
8840
|
);
|
|
8669
|
-
const targetName = (0,
|
|
8841
|
+
const targetName = (0, import_react20.useMemo)(
|
|
8670
8842
|
() => {
|
|
8671
8843
|
var _a, _b, _c, _d;
|
|
8672
8844
|
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)";
|
|
8673
8845
|
},
|
|
8674
8846
|
[data == null ? void 0 : data.linkObject]
|
|
8675
8847
|
);
|
|
8676
|
-
(0,
|
|
8848
|
+
(0, import_react20.useLayoutEffect)(() => {
|
|
8677
8849
|
if (!data.visible || !menuRef.current) return;
|
|
8678
8850
|
const el = menuRef.current;
|
|
8679
8851
|
const w = el.clientWidth;
|
|
@@ -8686,7 +8858,7 @@ function RelationshipContextMenu({
|
|
|
8686
8858
|
if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
|
|
8687
8859
|
setMenuPos({ left, top });
|
|
8688
8860
|
}, [data]);
|
|
8689
|
-
(0,
|
|
8861
|
+
(0, import_react20.useEffect)(() => {
|
|
8690
8862
|
if (data.visible) {
|
|
8691
8863
|
setIsConfirmingDelete(false);
|
|
8692
8864
|
}
|
|
@@ -8702,7 +8874,7 @@ function RelationshipContextMenu({
|
|
|
8702
8874
|
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";
|
|
8703
8875
|
const canUpdate = ability.can("update", "Connection");
|
|
8704
8876
|
const canDelete = ability.can("delete", "Connection");
|
|
8705
|
-
return /* @__PURE__ */
|
|
8877
|
+
return /* @__PURE__ */ import_react20.default.createElement(
|
|
8706
8878
|
"div",
|
|
8707
8879
|
{
|
|
8708
8880
|
ref: menuRef,
|
|
@@ -8716,29 +8888,29 @@ function RelationshipContextMenu({
|
|
|
8716
8888
|
onContextMenu: swallow,
|
|
8717
8889
|
onDoubleClick: swallow
|
|
8718
8890
|
},
|
|
8719
|
-
/* @__PURE__ */
|
|
8720
|
-
/* @__PURE__ */
|
|
8891
|
+
/* @__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" }),
|
|
8892
|
+
/* @__PURE__ */ import_react20.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react20.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_react20.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_react20.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ import_react20.default.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ import_react20.default.createElement("strong", null, targetName), ".")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react20.default.createElement(
|
|
8721
8893
|
"button",
|
|
8722
8894
|
{
|
|
8723
8895
|
onClick: () => setIsConfirmingDelete(false),
|
|
8724
8896
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
|
|
8725
8897
|
},
|
|
8726
8898
|
"Cancelar"
|
|
8727
|
-
), /* @__PURE__ */
|
|
8899
|
+
), /* @__PURE__ */ import_react20.default.createElement(
|
|
8728
8900
|
"button",
|
|
8729
8901
|
{
|
|
8730
8902
|
onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
|
|
8731
8903
|
className: "flex-1 px-2 py-2 text-xs font-medium bg-rose-600 hover:bg-rose-500 rounded-md text-white transition-colors"
|
|
8732
8904
|
},
|
|
8733
8905
|
"Excluir"
|
|
8734
|
-
))) : /* @__PURE__ */
|
|
8906
|
+
))) : /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react20.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_react20.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement(
|
|
8735
8907
|
"button",
|
|
8736
8908
|
{
|
|
8737
8909
|
onClick: () => onRelinkSource == null ? void 0 : onRelinkSource(data.linkObject),
|
|
8738
8910
|
className: baseButtonClass,
|
|
8739
8911
|
title: "Desconectar ponta ligada ao Source"
|
|
8740
8912
|
},
|
|
8741
|
-
/* @__PURE__ */
|
|
8913
|
+
/* @__PURE__ */ import_react20.default.createElement(
|
|
8742
8914
|
"svg",
|
|
8743
8915
|
{
|
|
8744
8916
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8751,18 +8923,18 @@ function RelationshipContextMenu({
|
|
|
8751
8923
|
strokeLinecap: "round",
|
|
8752
8924
|
strokeLinejoin: "round"
|
|
8753
8925
|
},
|
|
8754
|
-
/* @__PURE__ */
|
|
8755
|
-
/* @__PURE__ */
|
|
8926
|
+
/* @__PURE__ */ import_react20.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" }),
|
|
8927
|
+
/* @__PURE__ */ import_react20.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" })
|
|
8756
8928
|
),
|
|
8757
|
-
/* @__PURE__ */
|
|
8758
|
-
), /* @__PURE__ */
|
|
8929
|
+
/* @__PURE__ */ import_react20.default.createElement("span", null, "Desconectar Source (", sourceName, ")")
|
|
8930
|
+
), /* @__PURE__ */ import_react20.default.createElement(
|
|
8759
8931
|
"button",
|
|
8760
8932
|
{
|
|
8761
8933
|
onClick: () => onRelinkTarget == null ? void 0 : onRelinkTarget(data.linkObject),
|
|
8762
8934
|
className: baseButtonClass,
|
|
8763
8935
|
title: "Desconectar ponta ligada ao Target"
|
|
8764
8936
|
},
|
|
8765
|
-
/* @__PURE__ */
|
|
8937
|
+
/* @__PURE__ */ import_react20.default.createElement(
|
|
8766
8938
|
"svg",
|
|
8767
8939
|
{
|
|
8768
8940
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8775,21 +8947,21 @@ function RelationshipContextMenu({
|
|
|
8775
8947
|
strokeLinecap: "round",
|
|
8776
8948
|
strokeLinejoin: "round"
|
|
8777
8949
|
},
|
|
8778
|
-
/* @__PURE__ */
|
|
8779
|
-
/* @__PURE__ */
|
|
8780
|
-
/* @__PURE__ */
|
|
8781
|
-
/* @__PURE__ */
|
|
8782
|
-
/* @__PURE__ */
|
|
8950
|
+
/* @__PURE__ */ import_react20.default.createElement("polyline", { points: "16 3 21 3 21 8" }),
|
|
8951
|
+
/* @__PURE__ */ import_react20.default.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
|
|
8952
|
+
/* @__PURE__ */ import_react20.default.createElement("polyline", { points: "21 16 21 21 16 21" }),
|
|
8953
|
+
/* @__PURE__ */ import_react20.default.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
|
|
8954
|
+
/* @__PURE__ */ import_react20.default.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
|
|
8783
8955
|
),
|
|
8784
|
-
/* @__PURE__ */
|
|
8785
|
-
), /* @__PURE__ */
|
|
8956
|
+
/* @__PURE__ */ import_react20.default.createElement("span", null, "Desconectar Target (", targetName, ")")
|
|
8957
|
+
), /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ import_react20.default.createElement(
|
|
8786
8958
|
"button",
|
|
8787
8959
|
{
|
|
8788
8960
|
onClick: () => onOpenDetails == null ? void 0 : onOpenDetails(data.linkObject),
|
|
8789
8961
|
className: baseButtonClass,
|
|
8790
8962
|
title: "Abrir detalhes da rela\xE7\xE3o"
|
|
8791
8963
|
},
|
|
8792
|
-
/* @__PURE__ */
|
|
8964
|
+
/* @__PURE__ */ import_react20.default.createElement(
|
|
8793
8965
|
"svg",
|
|
8794
8966
|
{
|
|
8795
8967
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8802,19 +8974,19 @@ function RelationshipContextMenu({
|
|
|
8802
8974
|
strokeLinecap: "round",
|
|
8803
8975
|
strokeLinejoin: "round"
|
|
8804
8976
|
},
|
|
8805
|
-
/* @__PURE__ */
|
|
8806
|
-
/* @__PURE__ */
|
|
8807
|
-
/* @__PURE__ */
|
|
8977
|
+
/* @__PURE__ */ import_react20.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
8978
|
+
/* @__PURE__ */ import_react20.default.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
8979
|
+
/* @__PURE__ */ import_react20.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
|
|
8808
8980
|
),
|
|
8809
|
-
/* @__PURE__ */
|
|
8810
|
-
), canDelete && /* @__PURE__ */
|
|
8981
|
+
/* @__PURE__ */ import_react20.default.createElement("span", null, "Abrir Detalhes")
|
|
8982
|
+
), canDelete && /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ import_react20.default.createElement(
|
|
8811
8983
|
"button",
|
|
8812
8984
|
{
|
|
8813
8985
|
onClick: () => setIsConfirmingDelete(true),
|
|
8814
8986
|
className: dangerButtonClass,
|
|
8815
8987
|
title: "Excluir esta conex\xE3o"
|
|
8816
8988
|
},
|
|
8817
|
-
/* @__PURE__ */
|
|
8989
|
+
/* @__PURE__ */ import_react20.default.createElement(
|
|
8818
8990
|
"svg",
|
|
8819
8991
|
{
|
|
8820
8992
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8827,19 +8999,19 @@ function RelationshipContextMenu({
|
|
|
8827
8999
|
strokeLinecap: "round",
|
|
8828
9000
|
strokeLinejoin: "round"
|
|
8829
9001
|
},
|
|
8830
|
-
/* @__PURE__ */
|
|
8831
|
-
/* @__PURE__ */
|
|
8832
|
-
/* @__PURE__ */
|
|
8833
|
-
/* @__PURE__ */
|
|
8834
|
-
/* @__PURE__ */
|
|
9002
|
+
/* @__PURE__ */ import_react20.default.createElement("polyline", { points: "3 6 5 6 21 6" }),
|
|
9003
|
+
/* @__PURE__ */ import_react20.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
|
|
9004
|
+
/* @__PURE__ */ import_react20.default.createElement("path", { d: "M10 11v6" }),
|
|
9005
|
+
/* @__PURE__ */ import_react20.default.createElement("path", { d: "M14 11v6" }),
|
|
9006
|
+
/* @__PURE__ */ import_react20.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
|
|
8835
9007
|
),
|
|
8836
|
-
/* @__PURE__ */
|
|
9008
|
+
/* @__PURE__ */ import_react20.default.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
|
|
8837
9009
|
)))))
|
|
8838
9010
|
);
|
|
8839
9011
|
}
|
|
8840
9012
|
|
|
8841
9013
|
// src/components/LoadingScreen.jsx
|
|
8842
|
-
var
|
|
9014
|
+
var import_react21 = __toESM(require("react"));
|
|
8843
9015
|
var styles = {
|
|
8844
9016
|
loadingOverlay: {
|
|
8845
9017
|
position: "fixed",
|
|
@@ -8871,11 +9043,11 @@ var styles = {
|
|
|
8871
9043
|
`
|
|
8872
9044
|
};
|
|
8873
9045
|
function LoadingScreen() {
|
|
8874
|
-
return /* @__PURE__ */
|
|
9046
|
+
return /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("style", null, styles.keyframes), /* @__PURE__ */ import_react21.default.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ import_react21.default.createElement("div", { style: styles.spinner })));
|
|
8875
9047
|
}
|
|
8876
9048
|
|
|
8877
9049
|
// src/components/ImportParentFileModal.jsx
|
|
8878
|
-
var
|
|
9050
|
+
var import_react22 = __toESM(require("react"));
|
|
8879
9051
|
function ImportParentFileModal({
|
|
8880
9052
|
isOpen,
|
|
8881
9053
|
onClose,
|
|
@@ -8886,12 +9058,12 @@ function ImportParentFileModal({
|
|
|
8886
9058
|
onFetchAvailableFiles,
|
|
8887
9059
|
currentViewName
|
|
8888
9060
|
}) {
|
|
8889
|
-
const [activeTab, setActiveTab] = (0,
|
|
8890
|
-
const [availableDbs, setAvailableDbs] = (0,
|
|
8891
|
-
const [availableViews, setAvailableViews] = (0,
|
|
8892
|
-
const [selectedItem, setSelectedItem] = (0,
|
|
8893
|
-
const [isLoading, setIsLoading] = (0,
|
|
8894
|
-
(0,
|
|
9061
|
+
const [activeTab, setActiveTab] = (0, import_react22.useState)("databases");
|
|
9062
|
+
const [availableDbs, setAvailableDbs] = (0, import_react22.useState)([]);
|
|
9063
|
+
const [availableViews, setAvailableViews] = (0, import_react22.useState)([]);
|
|
9064
|
+
const [selectedItem, setSelectedItem] = (0, import_react22.useState)(null);
|
|
9065
|
+
const [isLoading, setIsLoading] = (0, import_react22.useState)(false);
|
|
9066
|
+
(0, import_react22.useEffect)(() => {
|
|
8895
9067
|
if (isOpen && session && onFetchAvailableFiles) {
|
|
8896
9068
|
const fetchData = async () => {
|
|
8897
9069
|
setIsLoading(true);
|
|
@@ -8927,7 +9099,7 @@ function ImportParentFileModal({
|
|
|
8927
9099
|
fetchData();
|
|
8928
9100
|
}
|
|
8929
9101
|
}, [isOpen, session, parentDbs, onFetchAvailableFiles, currentViewName]);
|
|
8930
|
-
(0,
|
|
9102
|
+
(0, import_react22.useEffect)(() => {
|
|
8931
9103
|
setSelectedItem(null);
|
|
8932
9104
|
}, [activeTab]);
|
|
8933
9105
|
if (!isOpen) {
|
|
@@ -8956,13 +9128,13 @@ function ImportParentFileModal({
|
|
|
8956
9128
|
const swallow = (e) => e.stopPropagation();
|
|
8957
9129
|
const currentList = activeTab === "databases" ? availableDbs : availableViews;
|
|
8958
9130
|
const emptyMessage = activeTab === "databases" ? "Nenhum novo arquivo parent dispon\xEDvel." : "Nenhuma view dispon\xEDvel para importa\xE7\xE3o.";
|
|
8959
|
-
return /* @__PURE__ */
|
|
9131
|
+
return /* @__PURE__ */ import_react22.default.createElement(
|
|
8960
9132
|
"div",
|
|
8961
9133
|
{
|
|
8962
9134
|
className: "ui-overlay fixed inset-0 z-[1200] flex items-center justify-center bg-black/60 backdrop-blur-sm",
|
|
8963
9135
|
onClick: onClose
|
|
8964
9136
|
},
|
|
8965
|
-
/* @__PURE__ */
|
|
9137
|
+
/* @__PURE__ */ import_react22.default.createElement(
|
|
8966
9138
|
"div",
|
|
8967
9139
|
{
|
|
8968
9140
|
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]",
|
|
@@ -8974,14 +9146,14 @@ function ImportParentFileModal({
|
|
|
8974
9146
|
onContextMenu: swallow,
|
|
8975
9147
|
onDoubleClick: swallow
|
|
8976
9148
|
},
|
|
8977
|
-
/* @__PURE__ */
|
|
9149
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ import_react22.default.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ import_react22.default.createElement(
|
|
8978
9150
|
"button",
|
|
8979
9151
|
{
|
|
8980
9152
|
onClick: onClose,
|
|
8981
9153
|
className: "p-2 rounded-md text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
|
|
8982
9154
|
title: "Fechar"
|
|
8983
9155
|
},
|
|
8984
|
-
/* @__PURE__ */
|
|
9156
|
+
/* @__PURE__ */ import_react22.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react22.default.createElement(
|
|
8985
9157
|
"path",
|
|
8986
9158
|
{
|
|
8987
9159
|
fillRule: "evenodd",
|
|
@@ -8990,14 +9162,14 @@ function ImportParentFileModal({
|
|
|
8990
9162
|
}
|
|
8991
9163
|
))
|
|
8992
9164
|
)),
|
|
8993
|
-
/* @__PURE__ */
|
|
9165
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ import_react22.default.createElement(
|
|
8994
9166
|
"button",
|
|
8995
9167
|
{
|
|
8996
9168
|
onClick: () => setActiveTab("databases"),
|
|
8997
9169
|
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"}`
|
|
8998
9170
|
},
|
|
8999
9171
|
"Arquivos Parent"
|
|
9000
|
-
), /* @__PURE__ */
|
|
9172
|
+
), /* @__PURE__ */ import_react22.default.createElement(
|
|
9001
9173
|
"button",
|
|
9002
9174
|
{
|
|
9003
9175
|
onClick: () => setActiveTab("views"),
|
|
@@ -9005,24 +9177,24 @@ function ImportParentFileModal({
|
|
|
9005
9177
|
},
|
|
9006
9178
|
"Views (Ancestralidades)"
|
|
9007
9179
|
)),
|
|
9008
|
-
/* @__PURE__ */
|
|
9180
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ import_react22.default.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ import_react22.default.createElement(
|
|
9009
9181
|
"div",
|
|
9010
9182
|
{
|
|
9011
9183
|
key: item.id,
|
|
9012
9184
|
onClick: () => setSelectedItem(item),
|
|
9013
9185
|
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"}`
|
|
9014
9186
|
},
|
|
9015
|
-
/* @__PURE__ */
|
|
9016
|
-
item.description && /* @__PURE__ */
|
|
9017
|
-
)) : /* @__PURE__ */
|
|
9018
|
-
/* @__PURE__ */
|
|
9187
|
+
/* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react22.default.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ import_react22.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")),
|
|
9188
|
+
item.description && /* @__PURE__ */ import_react22.default.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
|
|
9189
|
+
)) : /* @__PURE__ */ import_react22.default.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
|
|
9190
|
+
/* @__PURE__ */ import_react22.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_react22.default.createElement(
|
|
9019
9191
|
"button",
|
|
9020
9192
|
{
|
|
9021
9193
|
onClick: onClose,
|
|
9022
9194
|
className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm text-slate-300"
|
|
9023
9195
|
},
|
|
9024
9196
|
"Cancelar"
|
|
9025
|
-
), /* @__PURE__ */
|
|
9197
|
+
), /* @__PURE__ */ import_react22.default.createElement(
|
|
9026
9198
|
"button",
|
|
9027
9199
|
{
|
|
9028
9200
|
onClick: handleConfirm,
|
|
@@ -9036,8 +9208,8 @@ function ImportParentFileModal({
|
|
|
9036
9208
|
}
|
|
9037
9209
|
|
|
9038
9210
|
// src/components/AncestryLinkDetailsPanel.jsx
|
|
9039
|
-
var
|
|
9040
|
-
var
|
|
9211
|
+
var import_react23 = __toESM(require("react"));
|
|
9212
|
+
var import_fi17 = require("react-icons/fi");
|
|
9041
9213
|
function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
|
|
9042
9214
|
var _a, _b, _c, _d;
|
|
9043
9215
|
const relationshipData = data.relationship || {};
|
|
@@ -9046,21 +9218,21 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9046
9218
|
const customProps = extractCustomPropsFromNode(relationshipData);
|
|
9047
9219
|
const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
|
|
9048
9220
|
const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
|
|
9049
|
-
const [isReadMode, setIsReadMode] = (0,
|
|
9221
|
+
const [isReadMode, setIsReadMode] = (0, import_react23.useState)(false);
|
|
9050
9222
|
const swallow = (e) => e.stopPropagation();
|
|
9051
9223
|
const handleImageClickFromText = (url, name) => {
|
|
9052
9224
|
if (onOpenImageViewer) {
|
|
9053
9225
|
onOpenImageViewer([{ name: name || "Imagem", value: url }], 0);
|
|
9054
9226
|
}
|
|
9055
9227
|
};
|
|
9056
|
-
return /* @__PURE__ */
|
|
9228
|
+
return /* @__PURE__ */ import_react23.default.createElement(
|
|
9057
9229
|
"div",
|
|
9058
9230
|
{
|
|
9059
9231
|
className: "ui-overlay fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[1200]",
|
|
9060
9232
|
onClick: onClose,
|
|
9061
9233
|
onPointerDown: swallow
|
|
9062
9234
|
},
|
|
9063
|
-
/* @__PURE__ */
|
|
9235
|
+
/* @__PURE__ */ import_react23.default.createElement(
|
|
9064
9236
|
"div",
|
|
9065
9237
|
{
|
|
9066
9238
|
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
|
|
@@ -9068,7 +9240,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9068
9240
|
`,
|
|
9069
9241
|
onClick: swallow
|
|
9070
9242
|
},
|
|
9071
|
-
isReadMode ? /* @__PURE__ */
|
|
9243
|
+
isReadMode ? /* @__PURE__ */ import_react23.default.createElement(
|
|
9072
9244
|
DescriptionReadModePanel,
|
|
9073
9245
|
{
|
|
9074
9246
|
title: `${sourceName} \u2794 ${targetName}`,
|
|
@@ -9080,15 +9252,15 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9080
9252
|
onMentionClick,
|
|
9081
9253
|
onImageClick: handleImageClickFromText
|
|
9082
9254
|
}
|
|
9083
|
-
) : /* @__PURE__ */
|
|
9255
|
+
) : /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ import_react23.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react23.default.createElement("div", null, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react23.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_react23.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ import_react23.default.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ import_react23.default.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ import_react23.default.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ import_react23.default.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ import_react23.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_react23.default.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ import_react23.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react23.default.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react23.default.createElement(
|
|
9084
9256
|
"button",
|
|
9085
9257
|
{
|
|
9086
9258
|
onClick: () => setIsReadMode(true),
|
|
9087
9259
|
className: "p-1 text-slate-400 hover:text-white transition-colors",
|
|
9088
9260
|
title: "Modo de Leitura"
|
|
9089
9261
|
},
|
|
9090
|
-
/* @__PURE__ */
|
|
9091
|
-
)), /* @__PURE__ */
|
|
9262
|
+
/* @__PURE__ */ import_react23.default.createElement(import_fi17.FiBookOpen, { size: 14 })
|
|
9263
|
+
)), /* @__PURE__ */ import_react23.default.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ import_react23.default.createElement(
|
|
9092
9264
|
DescriptionDisplay,
|
|
9093
9265
|
{
|
|
9094
9266
|
description,
|
|
@@ -9097,7 +9269,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9097
9269
|
onMentionClick,
|
|
9098
9270
|
onImageClick: handleImageClickFromText
|
|
9099
9271
|
}
|
|
9100
|
-
))), customProps.length > 0 && /* @__PURE__ */
|
|
9272
|
+
))), customProps.length > 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react23.default.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ import_react23.default.createElement(
|
|
9101
9273
|
CustomPropertyDisplay,
|
|
9102
9274
|
{
|
|
9103
9275
|
key: prop.id,
|
|
@@ -9106,14 +9278,14 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
9106
9278
|
onOpenImageViewer,
|
|
9107
9279
|
onUploadFile
|
|
9108
9280
|
}
|
|
9109
|
-
)))), !description && customProps.length === 0 && /* @__PURE__ */
|
|
9281
|
+
)))), !description && customProps.length === 0 && /* @__PURE__ */ import_react23.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_react23.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".')))
|
|
9110
9282
|
)
|
|
9111
9283
|
);
|
|
9112
9284
|
}
|
|
9113
9285
|
|
|
9114
9286
|
// src/components/AncestryBoard.jsx
|
|
9115
|
-
var
|
|
9116
|
-
var
|
|
9287
|
+
var import_react24 = __toESM(require("react"));
|
|
9288
|
+
var import_fi18 = require("react-icons/fi");
|
|
9117
9289
|
var GroupItem = ({
|
|
9118
9290
|
group,
|
|
9119
9291
|
index,
|
|
@@ -9133,7 +9305,7 @@ var GroupItem = ({
|
|
|
9133
9305
|
}) => {
|
|
9134
9306
|
const canIndent = index > 0;
|
|
9135
9307
|
const isPickingForThisGroup = pickingGroupId === group.id;
|
|
9136
|
-
const textareaRef = (0,
|
|
9308
|
+
const textareaRef = (0, import_react24.useRef)(null);
|
|
9137
9309
|
const adjustHeight = () => {
|
|
9138
9310
|
const textarea = textareaRef.current;
|
|
9139
9311
|
if (textarea) {
|
|
@@ -9141,13 +9313,13 @@ var GroupItem = ({
|
|
|
9141
9313
|
textarea.style.height = `${textarea.scrollHeight}px`;
|
|
9142
9314
|
}
|
|
9143
9315
|
};
|
|
9144
|
-
(0,
|
|
9316
|
+
(0, import_react24.useEffect)(() => {
|
|
9145
9317
|
adjustHeight();
|
|
9146
9318
|
}, [group.text]);
|
|
9147
|
-
return /* @__PURE__ */
|
|
9319
|
+
return /* @__PURE__ */ import_react24.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_react24.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react24.default.createElement("div", { className: `
|
|
9148
9320
|
flex flex-col gap-2 py-2 px-3 transition-all duration-200
|
|
9149
9321
|
${isPickingForThisGroup ? "bg-indigo-500/10 border-l-2 border-indigo-500" : "hover:bg-white/5 border-l-2 border-transparent hover:border-white/20"}
|
|
9150
|
-
` }, /* @__PURE__ */
|
|
9322
|
+
` }, /* @__PURE__ */ import_react24.default.createElement(
|
|
9151
9323
|
"textarea",
|
|
9152
9324
|
{
|
|
9153
9325
|
ref: textareaRef,
|
|
@@ -9164,9 +9336,9 @@ var GroupItem = ({
|
|
|
9164
9336
|
if (canEdit) onUpdate(group.id, { ...group, text: e.target.value });
|
|
9165
9337
|
}
|
|
9166
9338
|
}
|
|
9167
|
-
), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */
|
|
9339
|
+
), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
|
|
9168
9340
|
const isValid = availableIds.has(String(anc.ancestry_id));
|
|
9169
|
-
return /* @__PURE__ */
|
|
9341
|
+
return /* @__PURE__ */ import_react24.default.createElement(
|
|
9170
9342
|
"div",
|
|
9171
9343
|
{
|
|
9172
9344
|
key: anc.ancestry_id,
|
|
@@ -9178,28 +9350,28 @@ var GroupItem = ({
|
|
|
9178
9350
|
},
|
|
9179
9351
|
isValid ? (
|
|
9180
9352
|
// [MANTIDO] Botão Play visível para todos
|
|
9181
|
-
/* @__PURE__ */
|
|
9353
|
+
/* @__PURE__ */ import_react24.default.createElement(
|
|
9182
9354
|
"button",
|
|
9183
9355
|
{
|
|
9184
9356
|
onClick: () => onPlayAncestry(anc.ancestry_id),
|
|
9185
9357
|
className: "text-indigo-400 hover:text-white hover:bg-indigo-500 p-1 rounded-full transition-colors",
|
|
9186
9358
|
title: "Renderizar no cen\xE1rio"
|
|
9187
9359
|
},
|
|
9188
|
-
/* @__PURE__ */
|
|
9360
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlay, { size: 10, className: "ml-0.5 fill-current" })
|
|
9189
9361
|
)
|
|
9190
|
-
) : /* @__PURE__ */
|
|
9191
|
-
/* @__PURE__ */
|
|
9192
|
-
canEdit && /* @__PURE__ */
|
|
9362
|
+
) : /* @__PURE__ */ import_react24.default.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiAlertTriangle, { size: 10 })),
|
|
9363
|
+
/* @__PURE__ */ import_react24.default.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
|
|
9364
|
+
canEdit && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ import_react24.default.createElement(
|
|
9193
9365
|
"button",
|
|
9194
9366
|
{
|
|
9195
9367
|
onClick: () => onRemoveAncestry(group.id, anc.ancestry_id),
|
|
9196
9368
|
className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
|
|
9197
9369
|
title: "Remover men\xE7\xE3o"
|
|
9198
9370
|
},
|
|
9199
|
-
/* @__PURE__ */
|
|
9371
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiX, { size: 12 })
|
|
9200
9372
|
))
|
|
9201
9373
|
);
|
|
9202
|
-
})), canEdit && /* @__PURE__ */
|
|
9374
|
+
})), canEdit && /* @__PURE__ */ import_react24.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_react24.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react24.default.createElement(
|
|
9203
9375
|
"button",
|
|
9204
9376
|
{
|
|
9205
9377
|
onClick: () => onRequestPickAncestry(group.id),
|
|
@@ -9209,17 +9381,17 @@ var GroupItem = ({
|
|
|
9209
9381
|
`,
|
|
9210
9382
|
title: "Adicionar Ancestralidade a este grupo"
|
|
9211
9383
|
},
|
|
9212
|
-
isPickingForThisGroup ? /* @__PURE__ */
|
|
9384
|
+
isPickingForThisGroup ? /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiCheckCircle, { size: 12 }) : /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiSearch, { size: 12 }),
|
|
9213
9385
|
isPickingForThisGroup ? "Selecionando..." : "Adicionar"
|
|
9214
|
-
), /* @__PURE__ */
|
|
9386
|
+
), /* @__PURE__ */ import_react24.default.createElement(
|
|
9215
9387
|
"button",
|
|
9216
9388
|
{
|
|
9217
9389
|
onClick: () => onAddSubgroup(group.id),
|
|
9218
9390
|
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
9219
9391
|
title: "Criar Subgrupo"
|
|
9220
9392
|
},
|
|
9221
|
-
/* @__PURE__ */
|
|
9222
|
-
)), /* @__PURE__ */
|
|
9393
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 14 })
|
|
9394
|
+
)), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react24.default.createElement(
|
|
9223
9395
|
"button",
|
|
9224
9396
|
{
|
|
9225
9397
|
onClick: () => onIndent(group.id),
|
|
@@ -9227,24 +9399,24 @@ var GroupItem = ({
|
|
|
9227
9399
|
className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
|
|
9228
9400
|
title: "Aninhar no grupo acima"
|
|
9229
9401
|
},
|
|
9230
|
-
/* @__PURE__ */
|
|
9231
|
-
), /* @__PURE__ */
|
|
9402
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiArrowRight, { size: 14 })
|
|
9403
|
+
), /* @__PURE__ */ import_react24.default.createElement(
|
|
9232
9404
|
"button",
|
|
9233
9405
|
{
|
|
9234
9406
|
onClick: () => onOutdent(group.id),
|
|
9235
9407
|
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
9236
9408
|
title: "Desaninhar"
|
|
9237
9409
|
},
|
|
9238
|
-
/* @__PURE__ */
|
|
9239
|
-
), /* @__PURE__ */
|
|
9410
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiArrowLeft, { size: 14 })
|
|
9411
|
+
), /* @__PURE__ */ import_react24.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react24.default.createElement(
|
|
9240
9412
|
"button",
|
|
9241
9413
|
{
|
|
9242
9414
|
onClick: () => onDelete(group.id),
|
|
9243
9415
|
className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
|
|
9244
9416
|
title: "Remover Grupo"
|
|
9245
9417
|
},
|
|
9246
|
-
/* @__PURE__ */
|
|
9247
|
-
)))), group.children && group.children.length > 0 && /* @__PURE__ */
|
|
9418
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiTrash2, { size: 14 })
|
|
9419
|
+
)))), group.children && group.children.length > 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ import_react24.default.createElement(
|
|
9248
9420
|
GroupItem,
|
|
9249
9421
|
{
|
|
9250
9422
|
key: childGroup.id,
|
|
@@ -9276,21 +9448,21 @@ function AncestryBoard({
|
|
|
9276
9448
|
userRole
|
|
9277
9449
|
// [NOVO] Recebe a role do usuário
|
|
9278
9450
|
}) {
|
|
9279
|
-
const [searchTerm, setSearchTerm] = (0,
|
|
9280
|
-
const [groups, setGroups] = (0,
|
|
9281
|
-
const [isLoaded, setIsLoaded] = (0,
|
|
9282
|
-
const [pickingGroupId, setPickingGroupId] = (0,
|
|
9283
|
-
const [saveStatus, setSaveStatus] = (0,
|
|
9284
|
-
const canEdit = (0,
|
|
9451
|
+
const [searchTerm, setSearchTerm] = (0, import_react24.useState)("");
|
|
9452
|
+
const [groups, setGroups] = (0, import_react24.useState)([]);
|
|
9453
|
+
const [isLoaded, setIsLoaded] = (0, import_react24.useState)(false);
|
|
9454
|
+
const [pickingGroupId, setPickingGroupId] = (0, import_react24.useState)(null);
|
|
9455
|
+
const [saveStatus, setSaveStatus] = (0, import_react24.useState)("idle");
|
|
9456
|
+
const canEdit = (0, import_react24.useMemo)(() => {
|
|
9285
9457
|
return userRole !== "viewer";
|
|
9286
9458
|
}, [userRole]);
|
|
9287
|
-
(0,
|
|
9459
|
+
(0, import_react24.useEffect)(() => {
|
|
9288
9460
|
if (initialGroups && !isLoaded) {
|
|
9289
9461
|
setGroups(initialGroups);
|
|
9290
9462
|
setIsLoaded(true);
|
|
9291
9463
|
}
|
|
9292
9464
|
}, [initialGroups, isLoaded]);
|
|
9293
|
-
const nodeNamesMap = (0,
|
|
9465
|
+
const nodeNamesMap = (0, import_react24.useMemo)(() => {
|
|
9294
9466
|
const map = /* @__PURE__ */ new Map();
|
|
9295
9467
|
if (availableNodes && Array.isArray(availableNodes)) {
|
|
9296
9468
|
availableNodes.forEach((node) => {
|
|
@@ -9301,7 +9473,7 @@ function AncestryBoard({
|
|
|
9301
9473
|
}
|
|
9302
9474
|
return map;
|
|
9303
9475
|
}, [availableNodes]);
|
|
9304
|
-
const availableIds = (0,
|
|
9476
|
+
const availableIds = (0, import_react24.useMemo)(() => {
|
|
9305
9477
|
return new Set(availableAncestries.map((a) => String(a.ancestry_id)));
|
|
9306
9478
|
}, [availableAncestries]);
|
|
9307
9479
|
const sanitizeGroups = (groupList) => {
|
|
@@ -9315,7 +9487,7 @@ function AncestryBoard({
|
|
|
9315
9487
|
children: sanitizeGroups(g.children || [])
|
|
9316
9488
|
}));
|
|
9317
9489
|
};
|
|
9318
|
-
(0,
|
|
9490
|
+
(0, import_react24.useEffect)(() => {
|
|
9319
9491
|
if (!isLoaded || !onSave) return;
|
|
9320
9492
|
const timeoutId = setTimeout(async () => {
|
|
9321
9493
|
setSaveStatus("saving");
|
|
@@ -9333,7 +9505,7 @@ function AncestryBoard({
|
|
|
9333
9505
|
}, 3e3);
|
|
9334
9506
|
return () => clearTimeout(timeoutId);
|
|
9335
9507
|
}, [groups, isLoaded, onSave]);
|
|
9336
|
-
(0,
|
|
9508
|
+
(0, import_react24.useEffect)(() => {
|
|
9337
9509
|
if (!isOpen) return;
|
|
9338
9510
|
const handleKeyDown = (e) => {
|
|
9339
9511
|
if (e.key === "Escape") {
|
|
@@ -9349,7 +9521,7 @@ function AncestryBoard({
|
|
|
9349
9521
|
window.addEventListener("keydown", handleKeyDown);
|
|
9350
9522
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
9351
9523
|
}, [isOpen, onClose, pickingGroupId]);
|
|
9352
|
-
const filtered = (0,
|
|
9524
|
+
const filtered = (0, import_react24.useMemo)(() => {
|
|
9353
9525
|
const term = searchTerm.toLowerCase().trim();
|
|
9354
9526
|
return availableAncestries.filter((a) => {
|
|
9355
9527
|
if (!term) return true;
|
|
@@ -9488,27 +9660,27 @@ function AncestryBoard({
|
|
|
9488
9660
|
});
|
|
9489
9661
|
};
|
|
9490
9662
|
if (!isOpen) return null;
|
|
9491
|
-
return /* @__PURE__ */
|
|
9663
|
+
return /* @__PURE__ */ import_react24.default.createElement(
|
|
9492
9664
|
"div",
|
|
9493
9665
|
{
|
|
9494
9666
|
className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
|
|
9495
9667
|
onClick: onClose
|
|
9496
9668
|
},
|
|
9497
|
-
/* @__PURE__ */
|
|
9669
|
+
/* @__PURE__ */ import_react24.default.createElement(
|
|
9498
9670
|
"div",
|
|
9499
9671
|
{
|
|
9500
9672
|
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",
|
|
9501
9673
|
onClick: (e) => e.stopPropagation()
|
|
9502
9674
|
},
|
|
9503
|
-
/* @__PURE__ */
|
|
9675
|
+
/* @__PURE__ */ import_react24.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_react24.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react24.default.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLayers, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ import_react24.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_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLoader, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ import_react24.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_react24.default.createElement(
|
|
9504
9676
|
"button",
|
|
9505
9677
|
{
|
|
9506
9678
|
onClick: handleAddRootGroup,
|
|
9507
9679
|
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 "
|
|
9508
9680
|
},
|
|
9509
|
-
/* @__PURE__ */
|
|
9510
|
-
/* @__PURE__ */
|
|
9511
|
-
), /* @__PURE__ */
|
|
9681
|
+
/* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 14, className: "text-indigo-400" }),
|
|
9682
|
+
/* @__PURE__ */ import_react24.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
|
|
9683
|
+
), /* @__PURE__ */ import_react24.default.createElement(
|
|
9512
9684
|
"button",
|
|
9513
9685
|
{
|
|
9514
9686
|
onClick: onClose,
|
|
@@ -9516,11 +9688,11 @@ function AncestryBoard({
|
|
|
9516
9688
|
},
|
|
9517
9689
|
"\xD7"
|
|
9518
9690
|
))),
|
|
9519
|
-
/* @__PURE__ */
|
|
9691
|
+
/* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: `
|
|
9520
9692
|
flex flex-col border-r border-white/10 transition-all duration-300 flex-none
|
|
9521
9693
|
${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
|
|
9522
9694
|
min-w-[280px] max-w-[500px] bg-slate-900
|
|
9523
|
-
` }, /* @__PURE__ */
|
|
9695
|
+
` }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.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_react24.default.createElement(
|
|
9524
9696
|
"input",
|
|
9525
9697
|
{
|
|
9526
9698
|
type: "text",
|
|
@@ -9533,10 +9705,10 @@ function AncestryBoard({
|
|
|
9533
9705
|
onChange: (e) => setSearchTerm(e.target.value),
|
|
9534
9706
|
autoFocus: !pickingGroupId
|
|
9535
9707
|
}
|
|
9536
|
-
))), /* @__PURE__ */
|
|
9708
|
+
))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
|
|
9537
9709
|
const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
|
|
9538
9710
|
const isPicking = !!pickingGroupId;
|
|
9539
|
-
return /* @__PURE__ */
|
|
9711
|
+
return /* @__PURE__ */ import_react24.default.createElement(
|
|
9540
9712
|
"div",
|
|
9541
9713
|
{
|
|
9542
9714
|
key: anc.ancestry_id,
|
|
@@ -9548,12 +9720,12 @@ function AncestryBoard({
|
|
|
9548
9720
|
${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"}
|
|
9549
9721
|
`
|
|
9550
9722
|
},
|
|
9551
|
-
/* @__PURE__ */
|
|
9723
|
+
/* @__PURE__ */ import_react24.default.createElement("div", { className: `
|
|
9552
9724
|
mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
|
|
9553
9725
|
${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"}
|
|
9554
|
-
` }, isPicking ? /* @__PURE__ */
|
|
9555
|
-
/* @__PURE__ */
|
|
9556
|
-
!isPicking && /* @__PURE__ */
|
|
9726
|
+
` }, isPicking ? /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 16 }) : /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLayers, { size: 14 })),
|
|
9727
|
+
/* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ import_react24.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_react24.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_react24.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_react24.default.createElement(import_fi18.FiCornerUpRight, { size: 10 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ import_react24.default.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
|
|
9728
|
+
!isPicking && /* @__PURE__ */ import_react24.default.createElement(
|
|
9557
9729
|
"button",
|
|
9558
9730
|
{
|
|
9559
9731
|
onClick: (e) => {
|
|
@@ -9563,10 +9735,10 @@ function AncestryBoard({
|
|
|
9563
9735
|
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",
|
|
9564
9736
|
title: "Renderizar Ancestralidade"
|
|
9565
9737
|
},
|
|
9566
|
-
/* @__PURE__ */
|
|
9738
|
+
/* @__PURE__ */ import_react24.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_react24.default.createElement(import_fi18.FiPlay, { size: 14, className: "ml-0.5" }))
|
|
9567
9739
|
)
|
|
9568
9740
|
);
|
|
9569
|
-
}))), /* @__PURE__ */
|
|
9741
|
+
}))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ import_react24.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_react24.default.createElement(import_fi18.FiLayers, { size: 24, className: "opacity-20" }), /* @__PURE__ */ import_react24.default.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ import_react24.default.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ import_react24.default.createElement(
|
|
9570
9742
|
GroupItem,
|
|
9571
9743
|
{
|
|
9572
9744
|
key: group.id,
|
|
@@ -9586,7 +9758,7 @@ function AncestryBoard({
|
|
|
9586
9758
|
canEdit
|
|
9587
9759
|
}
|
|
9588
9760
|
))))),
|
|
9589
|
-
/* @__PURE__ */
|
|
9761
|
+
/* @__PURE__ */ import_react24.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_react24.default.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ import_react24.default.createElement("span", null, groups.length, " grupos raiz"))
|
|
9590
9762
|
)
|
|
9591
9763
|
);
|
|
9592
9764
|
}
|
|
@@ -9666,12 +9838,12 @@ function XViewScene({
|
|
|
9666
9838
|
check_user_permission
|
|
9667
9839
|
}) {
|
|
9668
9840
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
9669
|
-
const { data: session, status } = (0,
|
|
9841
|
+
const { data: session, status } = (0, import_react26.useSession)();
|
|
9670
9842
|
const router = (0, import_navigation.useRouter)();
|
|
9671
9843
|
const searchParams = (0, import_navigation.useSearchParams)();
|
|
9672
9844
|
const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
|
|
9673
9845
|
const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
|
|
9674
|
-
const viewParams = (0,
|
|
9846
|
+
const viewParams = (0, import_react25.useMemo)(() => {
|
|
9675
9847
|
if (encryptedConfig) {
|
|
9676
9848
|
const data = decryptData(encryptedConfig);
|
|
9677
9849
|
if (data) {
|
|
@@ -9680,7 +9852,7 @@ function XViewScene({
|
|
|
9680
9852
|
}
|
|
9681
9853
|
return null;
|
|
9682
9854
|
}, [encryptedConfig, session]);
|
|
9683
|
-
(0,
|
|
9855
|
+
(0, import_react25.useEffect)(() => {
|
|
9684
9856
|
async function verifyPermission() {
|
|
9685
9857
|
if (!viewParams || !session || !check_user_permission) return;
|
|
9686
9858
|
const { id, type, owner_id } = viewParams;
|
|
@@ -9710,64 +9882,65 @@ function XViewScene({
|
|
|
9710
9882
|
setIsLoading(false);
|
|
9711
9883
|
}
|
|
9712
9884
|
}, [viewParams, session, status, check_user_permission]);
|
|
9713
|
-
const sceneConfigId = (0,
|
|
9714
|
-
const ownerId = (0,
|
|
9715
|
-
const dbSaveUrl = (0,
|
|
9885
|
+
const sceneConfigId = (0, import_react25.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
|
|
9886
|
+
const ownerId = (0, import_react25.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
|
|
9887
|
+
const dbSaveUrl = (0, import_react25.useMemo)(() => {
|
|
9716
9888
|
if (ownerId && sceneConfigId) {
|
|
9717
9889
|
return `x_view_dbs/${ownerId}/${sceneConfigId}`;
|
|
9718
9890
|
}
|
|
9719
9891
|
return null;
|
|
9720
9892
|
}, [ownerId, sceneConfigId]);
|
|
9721
|
-
const sceneSaveUrl = (0,
|
|
9893
|
+
const sceneSaveUrl = (0, import_react25.useMemo)(() => {
|
|
9722
9894
|
if (ownerId && sceneConfigId) {
|
|
9723
9895
|
return `x_view_scenes/${ownerId}/${sceneConfigId}`;
|
|
9724
9896
|
}
|
|
9725
9897
|
return null;
|
|
9726
9898
|
}, [ownerId, sceneConfigId]);
|
|
9727
|
-
const ancestry_save_url = (0,
|
|
9899
|
+
const ancestry_save_url = (0, import_react25.useMemo)(() => {
|
|
9728
9900
|
if (ownerId && sceneConfigId) {
|
|
9729
9901
|
return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
|
|
9730
9902
|
}
|
|
9731
9903
|
return null;
|
|
9732
9904
|
}, [ownerId, sceneConfigId]);
|
|
9733
|
-
const sceneDataRef = (0,
|
|
9734
|
-
const parentDataRef = (0,
|
|
9735
|
-
const ancestryDataRef = (0,
|
|
9736
|
-
const [isLoading, setIsLoading] = (0,
|
|
9737
|
-
const [permissionStatus, setPermissionStatus] = (0,
|
|
9738
|
-
const [userPermissionRole, setUserPermissionRole] = (0,
|
|
9739
|
-
const [isInitialized, setIsInitialized] = (0,
|
|
9740
|
-
const [sceneVersion, setSceneVersion] = (0,
|
|
9741
|
-
const [contextMenu, setContextMenu] = (0,
|
|
9742
|
-
const [multiContextMenu, setMultiContextMenu] = (0,
|
|
9743
|
-
const [relationshipMenu, setRelationshipMenu] = (0,
|
|
9744
|
-
const [creationMode, setCreationMode] = (0,
|
|
9745
|
-
const [versionMode, setVersionMode] = (0,
|
|
9746
|
-
const [
|
|
9747
|
-
const [
|
|
9748
|
-
const [
|
|
9749
|
-
const [
|
|
9905
|
+
const sceneDataRef = (0, import_react25.useRef)(null);
|
|
9906
|
+
const parentDataRef = (0, import_react25.useRef)(null);
|
|
9907
|
+
const ancestryDataRef = (0, import_react25.useRef)(null);
|
|
9908
|
+
const [isLoading, setIsLoading] = (0, import_react25.useState)(true);
|
|
9909
|
+
const [permissionStatus, setPermissionStatus] = (0, import_react25.useState)("loading");
|
|
9910
|
+
const [userPermissionRole, setUserPermissionRole] = (0, import_react25.useState)(null);
|
|
9911
|
+
const [isInitialized, setIsInitialized] = (0, import_react25.useState)(false);
|
|
9912
|
+
const [sceneVersion, setSceneVersion] = (0, import_react25.useState)(0);
|
|
9913
|
+
const [contextMenu, setContextMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, nodeData: null });
|
|
9914
|
+
const [multiContextMenu, setMultiContextMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, nodeIds: null });
|
|
9915
|
+
const [relationshipMenu, setRelationshipMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, linkObject: null });
|
|
9916
|
+
const [creationMode, setCreationMode] = (0, import_react25.useState)({ isActive: false, sourceNodeData: null });
|
|
9917
|
+
const [versionMode, setVersionMode] = (0, import_react25.useState)({ isActive: false, sourceNodeData: null });
|
|
9918
|
+
const [questMode, setQuestMode] = (0, import_react25.useState)({ isActive: false });
|
|
9919
|
+
const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react25.useState)(false);
|
|
9920
|
+
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react25.useState)(false);
|
|
9921
|
+
const [ancestryMode, setAncestryMode] = (0, import_react25.useState)({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
|
|
9922
|
+
const [readingMode, setReadingMode] = (0, import_react25.useState)({
|
|
9750
9923
|
isActive: false,
|
|
9751
9924
|
ancestry: null,
|
|
9752
9925
|
branchStack: [],
|
|
9753
9926
|
autoAbstraction: false
|
|
9754
9927
|
});
|
|
9755
|
-
const [formPosition, setFormPosition] = (0,
|
|
9756
|
-
const [detailsNode, setDetailsNode] = (0,
|
|
9757
|
-
const [detailsLink, setDetailsLink] = (0,
|
|
9758
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] = (0,
|
|
9759
|
-
const [imageViewer, setImageViewer] = (0,
|
|
9760
|
-
const [editingAncestryRel, setEditingAncestryRel] = (0,
|
|
9761
|
-
const [isImportModalOpen, setIsImportModalOpen] = (0,
|
|
9762
|
-
const [importSuccessMessage, setImportSuccessMessage] = (0,
|
|
9763
|
-
const [highlightedNodeId, setHighlightedNodeId] = (0,
|
|
9764
|
-
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0,
|
|
9765
|
-
const [ancestryBoardData, setAncestryBoardData] = (0,
|
|
9766
|
-
const [isSidebarOpen, setIsSidebarOpen] = (0,
|
|
9767
|
-
const mountRef = (0,
|
|
9768
|
-
const tooltipRef = (0,
|
|
9769
|
-
const formRef = (0,
|
|
9770
|
-
const stateRef = (0,
|
|
9928
|
+
const [formPosition, setFormPosition] = (0, import_react25.useState)({ left: 16, top: 16, opacity: 0 });
|
|
9929
|
+
const [detailsNode, setDetailsNode] = (0, import_react25.useState)(null);
|
|
9930
|
+
const [detailsLink, setDetailsLink] = (0, import_react25.useState)(null);
|
|
9931
|
+
const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react25.useState)(null);
|
|
9932
|
+
const [imageViewer, setImageViewer] = (0, import_react25.useState)({ visible: false, images: [], startIndex: 0 });
|
|
9933
|
+
const [editingAncestryRel, setEditingAncestryRel] = (0, import_react25.useState)({ visible: false, data: null, path: null });
|
|
9934
|
+
const [isImportModalOpen, setIsImportModalOpen] = (0, import_react25.useState)(false);
|
|
9935
|
+
const [importSuccessMessage, setImportSuccessMessage] = (0, import_react25.useState)("");
|
|
9936
|
+
const [highlightedNodeId, setHighlightedNodeId] = (0, import_react25.useState)(null);
|
|
9937
|
+
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react25.useState)(false);
|
|
9938
|
+
const [ancestryBoardData, setAncestryBoardData] = (0, import_react25.useState)([]);
|
|
9939
|
+
const [isSidebarOpen, setIsSidebarOpen] = (0, import_react25.useState)(false);
|
|
9940
|
+
const mountRef = (0, import_react25.useRef)(null);
|
|
9941
|
+
const tooltipRef = (0, import_react25.useRef)(null);
|
|
9942
|
+
const formRef = (0, import_react25.useRef)(null);
|
|
9943
|
+
const stateRef = (0, import_react25.useRef)({
|
|
9771
9944
|
readMode: {
|
|
9772
9945
|
currentMaxIndex: 0,
|
|
9773
9946
|
progressMap: {}
|
|
@@ -9812,10 +9985,10 @@ function XViewScene({
|
|
|
9812
9985
|
minWidth: 320,
|
|
9813
9986
|
maxWidth: maxReadPanelW
|
|
9814
9987
|
});
|
|
9815
|
-
(0,
|
|
9988
|
+
(0, import_react25.useEffect)(() => {
|
|
9816
9989
|
stateRef.current.ancestry = ancestryMode;
|
|
9817
9990
|
}, [ancestryMode]);
|
|
9818
|
-
(0,
|
|
9991
|
+
(0, import_react25.useEffect)(() => {
|
|
9819
9992
|
var _a2;
|
|
9820
9993
|
if (!isInitialized) return;
|
|
9821
9994
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -9836,10 +10009,10 @@ function XViewScene({
|
|
|
9836
10009
|
}
|
|
9837
10010
|
stateRef.current.nodeIdToParentFileMap = map;
|
|
9838
10011
|
}, [isInitialized, sceneVersion]);
|
|
9839
|
-
const handleNavigateBack = (0,
|
|
10012
|
+
const handleNavigateBack = (0, import_react25.useCallback)(() => {
|
|
9840
10013
|
router.push("/dashboard/scenes");
|
|
9841
10014
|
}, [router]);
|
|
9842
|
-
const handleConfirmImport = (0,
|
|
10015
|
+
const handleConfirmImport = (0, import_react25.useCallback)(
|
|
9843
10016
|
async (importPayload) => {
|
|
9844
10017
|
var _a2, _b2;
|
|
9845
10018
|
let files = [];
|
|
@@ -9937,7 +10110,7 @@ function XViewScene({
|
|
|
9937
10110
|
const handleOpenImageViewer = (images, startIndex) => {
|
|
9938
10111
|
setImageViewer({ visible: true, images, startIndex });
|
|
9939
10112
|
};
|
|
9940
|
-
const tweenToTarget = (0,
|
|
10113
|
+
const tweenToTarget = (0, import_react25.useCallback)((target, zoomFactor = 1, forcedDirection = null) => {
|
|
9941
10114
|
const { camera, controls, tweenGroup } = stateRef.current;
|
|
9942
10115
|
if (!camera || !controls || !tweenGroup) return;
|
|
9943
10116
|
const targetPos = target instanceof THREE3.Mesh ? target.getWorldPosition(new THREE3.Vector3()) : target;
|
|
@@ -9960,7 +10133,7 @@ function XViewScene({
|
|
|
9960
10133
|
if (!t || typeof t.closest !== "function") return false;
|
|
9961
10134
|
return !!t.closest(".ui-overlay");
|
|
9962
10135
|
};
|
|
9963
|
-
const buildFullAncestryTree = (0,
|
|
10136
|
+
const buildFullAncestryTree = (0, import_react25.useCallback)((idTree, nodes, ancestries = []) => {
|
|
9964
10137
|
if (!idTree) return null;
|
|
9965
10138
|
const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
|
|
9966
10139
|
const ancestryMap = new Map(ancestries.map((a) => [String(a.ancestry_id), a]));
|
|
@@ -10036,7 +10209,7 @@ function XViewScene({
|
|
|
10036
10209
|
}
|
|
10037
10210
|
return recursiveBuild(idTree);
|
|
10038
10211
|
}, []);
|
|
10039
|
-
const handleActivateTimeline = (0,
|
|
10212
|
+
const handleActivateTimeline = (0, import_react25.useCallback)(() => {
|
|
10040
10213
|
const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
10041
10214
|
if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
|
|
10042
10215
|
while (timelineIntervalsGroup.children.length > 0) {
|
|
@@ -10189,7 +10362,7 @@ function XViewScene({
|
|
|
10189
10362
|
}
|
|
10190
10363
|
});
|
|
10191
10364
|
}, []);
|
|
10192
|
-
const handleVersionTimeline = (0,
|
|
10365
|
+
const handleVersionTimeline = (0, import_react25.useCallback)((sourceMesh, versionMeshes) => {
|
|
10193
10366
|
const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
10194
10367
|
if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0) return;
|
|
10195
10368
|
versionMeshes.forEach((mesh) => {
|
|
@@ -10312,7 +10485,7 @@ function XViewScene({
|
|
|
10312
10485
|
}
|
|
10313
10486
|
});
|
|
10314
10487
|
}, []);
|
|
10315
|
-
(0,
|
|
10488
|
+
(0, import_react25.useEffect)(() => {
|
|
10316
10489
|
async function fetchAllData(configPath, ownerId2) {
|
|
10317
10490
|
var _a2, _b2;
|
|
10318
10491
|
if (!get_scene_view_data) {
|
|
@@ -10384,12 +10557,12 @@ function XViewScene({
|
|
|
10384
10557
|
focusNodeId,
|
|
10385
10558
|
focusAncestryId
|
|
10386
10559
|
]);
|
|
10387
|
-
const isNodeInView = (0,
|
|
10560
|
+
const isNodeInView = (0, import_react25.useCallback)((id) => {
|
|
10388
10561
|
const key = String(id);
|
|
10389
10562
|
const objs = stateRef.current.nodeObjects || {};
|
|
10390
10563
|
return !!objs[key];
|
|
10391
10564
|
}, []);
|
|
10392
|
-
const addOrUpdateNodeMesh = (0,
|
|
10565
|
+
const addOrUpdateNodeMesh = (0, import_react25.useCallback)((nodeData, position, suppressVersionUpdate = false) => {
|
|
10393
10566
|
const { graphGroup, nodeObjects, clickableNodes, glowTexture, tweenGroup } = stateRef.current;
|
|
10394
10567
|
const nodeId = String(nodeData.id);
|
|
10395
10568
|
if (nodeObjects[nodeId]) {
|
|
@@ -10416,7 +10589,7 @@ function XViewScene({
|
|
|
10416
10589
|
}
|
|
10417
10590
|
return mesh;
|
|
10418
10591
|
}, []);
|
|
10419
|
-
(0,
|
|
10592
|
+
(0, import_react25.useEffect)(() => {
|
|
10420
10593
|
if (!isInitialized || !sceneDataRef.current) return;
|
|
10421
10594
|
const currentMount = mountRef.current;
|
|
10422
10595
|
if (!currentMount) return;
|
|
@@ -10699,6 +10872,20 @@ function XViewScene({
|
|
|
10699
10872
|
const context = actionHandlerContext;
|
|
10700
10873
|
if (connection.isActive) {
|
|
10701
10874
|
if (hoveredNode && String(hoveredNode.userData.id) !== String(connection.sourceNodeData.id)) {
|
|
10875
|
+
const sourceId = String(connection.sourceNodeData.id);
|
|
10876
|
+
const targetId = String(hoveredNode.userData.id);
|
|
10877
|
+
let parentInfo = stateRef.current.nodeIdToParentFileMap.get(sourceId);
|
|
10878
|
+
if (!parentInfo || !parentInfo.ownerId) {
|
|
10879
|
+
parentInfo = stateRef.current.nodeIdToParentFileMap.get(targetId);
|
|
10880
|
+
if (parentInfo && parentInfo.ownerId) {
|
|
10881
|
+
stateRef.current.nodeIdToParentFileMap.set(sourceId, parentInfo);
|
|
10882
|
+
} else {
|
|
10883
|
+
console.error("Nenhum dos Nodes possui um Dataset pai v\xE1lido para salvar a conex\xE3o.");
|
|
10884
|
+
alert("N\xE3o \xE9 poss\xEDvel conectar dois Nodes de Quest diretamente sem um Dataset pai, ou ocorreu um erro.");
|
|
10885
|
+
userActionHandlers.handleCancelConnection(context);
|
|
10886
|
+
return;
|
|
10887
|
+
}
|
|
10888
|
+
}
|
|
10702
10889
|
await userActionHandlers.handleCompleteConnection(context, hoveredNode.userData);
|
|
10703
10890
|
} else {
|
|
10704
10891
|
userActionHandlers.handleCancelConnection(context);
|
|
@@ -10809,12 +10996,15 @@ function XViewScene({
|
|
|
10809
10996
|
if (mountRef.current) mountRef.current.style.cursor = "grab";
|
|
10810
10997
|
}
|
|
10811
10998
|
function handleKeyDown(event) {
|
|
10999
|
+
var _a2, _b2, _c2, _d2;
|
|
10812
11000
|
const context = actionHandlerContext;
|
|
10813
11001
|
if (event.key === "Escape") {
|
|
10814
11002
|
if (stateRef.current.connection.isActive) userActionHandlers.handleCancelConnection(context);
|
|
10815
11003
|
if (stateRef.current.relink.isActive) userActionHandlers.handleCancelRelink(context);
|
|
10816
11004
|
if (stateRef.current.creation.isActive) userActionHandlers.handleCancelCreation(context);
|
|
11005
|
+
if ((_a2 = stateRef.current.versionMode) == null ? void 0 : _a2.isActive) userActionHandlers.handleCancelVersioning(context);
|
|
10817
11006
|
if (stateRef.current.ancestry.isActive) handleCancelAncestryCreation();
|
|
11007
|
+
if ((_b2 = context.questMode) == null ? void 0 : _b2.isActive) context.setters.setQuestMode({ isActive: false });
|
|
10818
11008
|
if (stateRef.current.selectedNodes.size > 0) {
|
|
10819
11009
|
stateRef.current.selectedNodes.clear();
|
|
10820
11010
|
}
|
|
@@ -10822,6 +11012,17 @@ function XViewScene({
|
|
|
10822
11012
|
setMultiContextMenu((prev) => ({ ...prev, visible: false }));
|
|
10823
11013
|
setRelationshipMenu((prev) => ({ ...prev, visible: false }));
|
|
10824
11014
|
}
|
|
11015
|
+
if (event.key.toLowerCase() === "q") {
|
|
11016
|
+
const isUiClear = !stateRef.current.creation.isActive && !stateRef.current.connection.isActive && !stateRef.current.relink.isActive && !stateRef.current.ancestry.isActive && !((_c2 = context.versionMode) == null ? void 0 : _c2.isActive) && !contextMenu.visible && !multiContextMenu.visible && !relationshipMenu.visible && !readingMode.isActive && !isImportModalOpen && !isAncestryBoardOpen;
|
|
11017
|
+
if (isUiClear) {
|
|
11018
|
+
const isView = ((_d2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _d2.toLowerCase()) === "view";
|
|
11019
|
+
if (!isView) {
|
|
11020
|
+
alert("Nodes de Quest s\xF3 podem ser criados dentro de uma View.");
|
|
11021
|
+
return;
|
|
11022
|
+
}
|
|
11023
|
+
setQuestMode({ isActive: true });
|
|
11024
|
+
}
|
|
11025
|
+
}
|
|
10825
11026
|
}
|
|
10826
11027
|
function handleDoubleClick(event) {
|
|
10827
11028
|
if (stateRef.current.camera) stateRef.current.camera.layers.enableAll();
|
|
@@ -10980,9 +11181,7 @@ function XViewScene({
|
|
|
10980
11181
|
mountEl: currentMount,
|
|
10981
11182
|
isSceneBusy: stateRef.current.isDragging || creation.isActive || connection.isActive || relink.isActive || ancestryMode.isActive,
|
|
10982
11183
|
parentData: parentDataRef.current,
|
|
10983
|
-
// <--- ADICIONADO AQUI
|
|
10984
11184
|
ancestryData: ancestryDataRef.current
|
|
10985
|
-
// <--- ADICIONADO AQUI
|
|
10986
11185
|
});
|
|
10987
11186
|
(_b2 = stateRef.current.tweenGroup) == null ? void 0 : _b2.update(time);
|
|
10988
11187
|
stateRef.current.controls.update();
|
|
@@ -11049,7 +11248,7 @@ function XViewScene({
|
|
|
11049
11248
|
}
|
|
11050
11249
|
};
|
|
11051
11250
|
}, [isInitialized, tweenToTarget, dbSaveUrl, isNodeInView, addOrUpdateNodeMesh, handleActivateTimeline, get_scene_view_data, save_view_data]);
|
|
11052
|
-
const handleGhostNodeImageChange = (0,
|
|
11251
|
+
const handleGhostNodeImageChange = (0, import_react25.useCallback)((useImage, imageUrl) => {
|
|
11053
11252
|
const { node: ghostNode, line: ghostLine, aura: ghostAura } = stateRef.current.ghostElements;
|
|
11054
11253
|
const { graphGroup, glowTexture } = stateRef.current;
|
|
11055
11254
|
if (!ghostNode || !graphGroup) return;
|
|
@@ -11091,7 +11290,7 @@ function XViewScene({
|
|
|
11091
11290
|
aura: newGhostNode.getObjectByName("aura")
|
|
11092
11291
|
};
|
|
11093
11292
|
}, []);
|
|
11094
|
-
const handleGhostNodeIntensityChange = (0,
|
|
11293
|
+
const handleGhostNodeIntensityChange = (0, import_react25.useCallback)((newIntensity) => {
|
|
11095
11294
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
11096
11295
|
if (!ghostNode) return;
|
|
11097
11296
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -11112,7 +11311,7 @@ function XViewScene({
|
|
|
11112
11311
|
ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
|
|
11113
11312
|
}
|
|
11114
11313
|
}, []);
|
|
11115
|
-
const handleDetailNodeIntensityChange = (0,
|
|
11314
|
+
const handleDetailNodeIntensityChange = (0, import_react25.useCallback)((nodeId, newIntensity) => {
|
|
11116
11315
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
11117
11316
|
if (!mesh) return;
|
|
11118
11317
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -11258,7 +11457,7 @@ function XViewScene({
|
|
|
11258
11457
|
mountRef.current.style.cursor = "default";
|
|
11259
11458
|
}
|
|
11260
11459
|
};
|
|
11261
|
-
const handleAncestryTreeUpdate = (0,
|
|
11460
|
+
const handleAncestryTreeUpdate = (0, import_react25.useCallback)((newTree, extraData = null) => {
|
|
11262
11461
|
setAncestryMode((prev) => {
|
|
11263
11462
|
const prevTreeStr = JSON.stringify(prev.tree);
|
|
11264
11463
|
const newTreeStr = JSON.stringify(newTree);
|
|
@@ -11278,7 +11477,7 @@ function XViewScene({
|
|
|
11278
11477
|
};
|
|
11279
11478
|
});
|
|
11280
11479
|
}, []);
|
|
11281
|
-
const actionHandlerContext = (0,
|
|
11480
|
+
const actionHandlerContext = (0, import_react25.useMemo)(
|
|
11282
11481
|
() => {
|
|
11283
11482
|
var _a2;
|
|
11284
11483
|
return {
|
|
@@ -11288,6 +11487,12 @@ function XViewScene({
|
|
|
11288
11487
|
mountRef,
|
|
11289
11488
|
creationMode,
|
|
11290
11489
|
versionMode,
|
|
11490
|
+
questMode,
|
|
11491
|
+
// <-- Adicionado
|
|
11492
|
+
sceneSaveUrl,
|
|
11493
|
+
// <-- Adicionado
|
|
11494
|
+
viewType: viewParams == null ? void 0 : viewParams.type,
|
|
11495
|
+
// <-- Adicionado
|
|
11291
11496
|
userId: (_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.id,
|
|
11292
11497
|
setters: {
|
|
11293
11498
|
setContextMenu,
|
|
@@ -11299,7 +11504,9 @@ function XViewScene({
|
|
|
11299
11504
|
setDetailsNode,
|
|
11300
11505
|
setDetailsLink,
|
|
11301
11506
|
setSceneVersion,
|
|
11302
|
-
setAncestryMode
|
|
11507
|
+
setAncestryMode,
|
|
11508
|
+
setQuestMode
|
|
11509
|
+
// <-- Adicionado
|
|
11303
11510
|
},
|
|
11304
11511
|
tweenToTarget,
|
|
11305
11512
|
handleVersionTimeline,
|
|
@@ -11315,6 +11522,9 @@ function XViewScene({
|
|
|
11315
11522
|
[
|
|
11316
11523
|
creationMode,
|
|
11317
11524
|
versionMode,
|
|
11525
|
+
questMode,
|
|
11526
|
+
sceneSaveUrl,
|
|
11527
|
+
viewParams == null ? void 0 : viewParams.type,
|
|
11318
11528
|
tweenToTarget,
|
|
11319
11529
|
(_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id,
|
|
11320
11530
|
handleVersionTimeline,
|
|
@@ -11328,7 +11538,34 @@ function XViewScene({
|
|
|
11328
11538
|
const handleStartVersioning = (nodeData) => {
|
|
11329
11539
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
11330
11540
|
};
|
|
11331
|
-
const
|
|
11541
|
+
const handleSaveQuestNode = async (context, newQuestData) => {
|
|
11542
|
+
const { sceneDataRef: sceneDataRef2, stateRef: stateRef2, setters, actions, sceneSaveUrl: sceneSaveUrl2, viewType } = context;
|
|
11543
|
+
if (!sceneDataRef2.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
|
|
11544
|
+
const newNode = {
|
|
11545
|
+
id: import_short_uuid2.default.generate(),
|
|
11546
|
+
...newQuestData,
|
|
11547
|
+
type: ["quest", ...newQuestData.type.filter((t) => t !== "quest")]
|
|
11548
|
+
};
|
|
11549
|
+
const updatedSceneData = {
|
|
11550
|
+
...sceneDataRef2.current,
|
|
11551
|
+
nodes: [...sceneDataRef2.current.nodes, newNode]
|
|
11552
|
+
};
|
|
11553
|
+
try {
|
|
11554
|
+
await actions.save_view_data(sceneSaveUrl2, updatedSceneData);
|
|
11555
|
+
sceneDataRef2.current.nodes.push(newNode);
|
|
11556
|
+
const basePosition = stateRef2.current.controls.target.clone();
|
|
11557
|
+
const offset = new THREE3.Vector3((Math.random() - 0.5) * 10, (Math.random() - 0.5) * 5, (Math.random() - 0.5) * 10);
|
|
11558
|
+
const finalPosition = basePosition.add(offset);
|
|
11559
|
+
addOrUpdateNodeMesh(newNode, finalPosition);
|
|
11560
|
+
context.tweenToTarget(finalPosition, 1.2);
|
|
11561
|
+
setters.setQuestMode({ isActive: false });
|
|
11562
|
+
setters.setSceneVersion((v) => v + 1);
|
|
11563
|
+
} catch (error) {
|
|
11564
|
+
console.error("Falha ao salvar a Quest na View:", error);
|
|
11565
|
+
alert("Ocorreu um erro ao criar a Quest.");
|
|
11566
|
+
}
|
|
11567
|
+
};
|
|
11568
|
+
const handleClearAncestryVisuals = (0, import_react25.useCallback)((ancestryId) => {
|
|
11332
11569
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
11333
11570
|
const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
|
|
11334
11571
|
if (renderIndex !== -1) {
|
|
@@ -11342,7 +11579,7 @@ function XViewScene({
|
|
|
11342
11579
|
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
11343
11580
|
}
|
|
11344
11581
|
}, []);
|
|
11345
|
-
const handleRenderAncestry = (0,
|
|
11582
|
+
const handleRenderAncestry = (0, import_react25.useCallback)(
|
|
11346
11583
|
async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
|
|
11347
11584
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11348
11585
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -11758,7 +11995,7 @@ function XViewScene({
|
|
|
11758
11995
|
},
|
|
11759
11996
|
[addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, readingMode.isActive, ancestryMode.isActive]
|
|
11760
11997
|
);
|
|
11761
|
-
const handleRenderAbstractionTree = (0,
|
|
11998
|
+
const handleRenderAbstractionTree = (0, import_react25.useCallback)((ancestryObject, targetNodeId = null) => {
|
|
11762
11999
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
11763
12000
|
if (!ancestryObject || !ancestryObject.abstraction_tree) return;
|
|
11764
12001
|
const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
|
|
@@ -11819,7 +12056,7 @@ function XViewScene({
|
|
|
11819
12056
|
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
11820
12057
|
tweenToTarget(rootTargetPos, 0.7);
|
|
11821
12058
|
}, [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, handleClearAncestryVisuals]);
|
|
11822
|
-
const handleReadModeBranchNav = (0,
|
|
12059
|
+
const handleReadModeBranchNav = (0, import_react25.useCallback)((nodeId, action, direction = "right") => {
|
|
11823
12060
|
const { ancestry, branchStack } = readingMode;
|
|
11824
12061
|
if (!ancestry || !ancestry.tree) return;
|
|
11825
12062
|
const allAncestries = ancestryDataRef.current || [];
|
|
@@ -11960,13 +12197,13 @@ function XViewScene({
|
|
|
11960
12197
|
}));
|
|
11961
12198
|
}
|
|
11962
12199
|
}, [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]);
|
|
11963
|
-
const handleReadModeHighlight = (0,
|
|
12200
|
+
const handleReadModeHighlight = (0, import_react25.useCallback)((nodeId) => {
|
|
11964
12201
|
if (stateRef.current.highlightedNodeId !== nodeId) {
|
|
11965
12202
|
stateRef.current.highlightedNodeId = nodeId;
|
|
11966
12203
|
}
|
|
11967
12204
|
setHighlightedNodeId(nodeId);
|
|
11968
12205
|
}, []);
|
|
11969
|
-
const activeNodeBranches = (0,
|
|
12206
|
+
const activeNodeBranches = (0, import_react25.useMemo)(() => {
|
|
11970
12207
|
if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree) return null;
|
|
11971
12208
|
const fullTree = buildFullAncestryTree(
|
|
11972
12209
|
readingMode.ancestry.tree,
|
|
@@ -12003,7 +12240,7 @@ function XViewScene({
|
|
|
12003
12240
|
}
|
|
12004
12241
|
return null;
|
|
12005
12242
|
}, [highlightedNodeId, readingMode.ancestry, buildFullAncestryTree, readingMode.branchStack, ancestryDataRef.current]);
|
|
12006
|
-
const backNavigationInfo = (0,
|
|
12243
|
+
const backNavigationInfo = (0, import_react25.useMemo)(() => {
|
|
12007
12244
|
const { branchStack } = readingMode;
|
|
12008
12245
|
if (!branchStack || branchStack.length === 0) return null;
|
|
12009
12246
|
const lastStep = branchStack[branchStack.length - 1];
|
|
@@ -12014,7 +12251,7 @@ function XViewScene({
|
|
|
12014
12251
|
name: "Voltar para anterior"
|
|
12015
12252
|
};
|
|
12016
12253
|
}, [readingMode.branchStack]);
|
|
12017
|
-
const getReadModeDisplayContext = (0,
|
|
12254
|
+
const getReadModeDisplayContext = (0, import_react25.useMemo)(() => {
|
|
12018
12255
|
const { ancestry, branchStack } = readingMode;
|
|
12019
12256
|
if (!ancestry) return null;
|
|
12020
12257
|
if (branchStack.length === 0) {
|
|
@@ -12055,7 +12292,7 @@ function XViewScene({
|
|
|
12055
12292
|
customProperties: branchProps
|
|
12056
12293
|
};
|
|
12057
12294
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
12058
|
-
const readModeAbstractionTree = (0,
|
|
12295
|
+
const readModeAbstractionTree = (0, import_react25.useMemo)(() => {
|
|
12059
12296
|
if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
|
|
12060
12297
|
return null;
|
|
12061
12298
|
}
|
|
@@ -12067,7 +12304,7 @@ function XViewScene({
|
|
|
12067
12304
|
allAncestries
|
|
12068
12305
|
);
|
|
12069
12306
|
}, [readingMode.isActive, readingMode.ancestry, buildFullAncestryTree, sceneVersion]);
|
|
12070
|
-
const handleStartReadingAncestry = (0,
|
|
12307
|
+
const handleStartReadingAncestry = (0, import_react25.useCallback)(
|
|
12071
12308
|
async (ancestryObject) => {
|
|
12072
12309
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
12073
12310
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -12102,7 +12339,7 @@ function XViewScene({
|
|
|
12102
12339
|
},
|
|
12103
12340
|
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
12104
12341
|
);
|
|
12105
|
-
const handleReadModeSectionChange = (0,
|
|
12342
|
+
const handleReadModeSectionChange = (0, import_react25.useCallback)((activeSectionId) => {
|
|
12106
12343
|
const { ancestry, branchStack } = readingMode;
|
|
12107
12344
|
if (!ancestry || !readingMode.isActive) return;
|
|
12108
12345
|
let targetObj = ancestry;
|
|
@@ -12171,10 +12408,10 @@ function XViewScene({
|
|
|
12171
12408
|
}, 0);
|
|
12172
12409
|
handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
|
|
12173
12410
|
}, [readingMode, handleRenderAncestry, buildFullAncestryTree, ancestryDataRef.current]);
|
|
12174
|
-
const handleCloseReadMode = (0,
|
|
12411
|
+
const handleCloseReadMode = (0, import_react25.useCallback)(() => {
|
|
12175
12412
|
setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
|
|
12176
12413
|
}, []);
|
|
12177
|
-
const handleAncestrySectionChange = (0,
|
|
12414
|
+
const handleAncestrySectionChange = (0, import_react25.useCallback)((activeSectionId, ancestryOverride = null, rotation = 0) => {
|
|
12178
12415
|
var _a2, _b2;
|
|
12179
12416
|
const currentMode = stateRef.current.ancestry;
|
|
12180
12417
|
let targetObj = ancestryOverride;
|
|
@@ -12226,7 +12463,7 @@ function XViewScene({
|
|
|
12226
12463
|
const renderPayload = { ...targetObj, tree: treeToRender };
|
|
12227
12464
|
handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
|
|
12228
12465
|
}, [handleRenderAncestry]);
|
|
12229
|
-
const handleEditAncestry = (0,
|
|
12466
|
+
const handleEditAncestry = (0, import_react25.useCallback)(
|
|
12230
12467
|
async (ancestryObject) => {
|
|
12231
12468
|
setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
|
|
12232
12469
|
if (!ancestryObject || !ancestryObject.tree) {
|
|
@@ -12265,7 +12502,7 @@ function XViewScene({
|
|
|
12265
12502
|
const handleSelectAncestryParent = (nodeId) => {
|
|
12266
12503
|
setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
|
|
12267
12504
|
};
|
|
12268
|
-
const handleRemoveFromAncestry = (0,
|
|
12505
|
+
const handleRemoveFromAncestry = (0, import_react25.useCallback)((pathToRemove) => {
|
|
12269
12506
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
|
|
12270
12507
|
console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
|
|
12271
12508
|
return;
|
|
@@ -12290,7 +12527,7 @@ function XViewScene({
|
|
|
12290
12527
|
return { ...prev, tree: newTree };
|
|
12291
12528
|
});
|
|
12292
12529
|
}, []);
|
|
12293
|
-
const handleSaveAncestry = (0,
|
|
12530
|
+
const handleSaveAncestry = (0, import_react25.useCallback)(
|
|
12294
12531
|
async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
|
|
12295
12532
|
const treeToUse = treeOverride || ancestryMode.tree;
|
|
12296
12533
|
const { isEditMode, currentAncestryId } = ancestryMode;
|
|
@@ -12494,7 +12731,7 @@ function XViewScene({
|
|
|
12494
12731
|
});
|
|
12495
12732
|
setEditingAncestryRel({ visible: false, data: null, path: null });
|
|
12496
12733
|
};
|
|
12497
|
-
const handleDeleteAncestry = (0,
|
|
12734
|
+
const handleDeleteAncestry = (0, import_react25.useCallback)(
|
|
12498
12735
|
async (ancestryIdToDelete) => {
|
|
12499
12736
|
if (!ancestryIdToDelete) {
|
|
12500
12737
|
alert("ID da ancestralidade n\xE3o encontrado.");
|
|
@@ -12556,20 +12793,20 @@ function XViewScene({
|
|
|
12556
12793
|
},
|
|
12557
12794
|
[save_view_data, delete_file_action]
|
|
12558
12795
|
);
|
|
12559
|
-
const handleOpenAncestryBoard = (0,
|
|
12796
|
+
const handleOpenAncestryBoard = (0, import_react25.useCallback)(() => {
|
|
12560
12797
|
setIsAncestryBoardOpen(true);
|
|
12561
12798
|
}, []);
|
|
12562
|
-
const handleSelectAncestryFromBoard = (0,
|
|
12799
|
+
const handleSelectAncestryFromBoard = (0, import_react25.useCallback)((ancestry) => {
|
|
12563
12800
|
setIsAncestryBoardOpen(false);
|
|
12564
12801
|
setIsSidebarOpen(false);
|
|
12565
12802
|
handleStartReadingAncestry(ancestry);
|
|
12566
12803
|
}, [handleStartReadingAncestry]);
|
|
12567
|
-
const handleSaveAncestryBoard = (0,
|
|
12804
|
+
const handleSaveAncestryBoard = (0, import_react25.useCallback)(async (groups) => {
|
|
12568
12805
|
if (!sceneConfigId || !viewParams || !session) return;
|
|
12569
12806
|
const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
|
|
12570
12807
|
await save_ancestry_board_action(sceneConfigId, sceneType, groups, session, ownerId);
|
|
12571
12808
|
}, [sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]);
|
|
12572
|
-
const existingNodeTypes = (0,
|
|
12809
|
+
const existingNodeTypes = (0, import_react25.useMemo)(() => {
|
|
12573
12810
|
if (!parentDataRef.current) {
|
|
12574
12811
|
return [];
|
|
12575
12812
|
}
|
|
@@ -12579,7 +12816,7 @@ function XViewScene({
|
|
|
12579
12816
|
})).filter(Boolean);
|
|
12580
12817
|
return [...new Set(allTypes)];
|
|
12581
12818
|
}, [parentDataRef.current, sceneVersion]);
|
|
12582
|
-
const searchableDbNodes = (0,
|
|
12819
|
+
const searchableDbNodes = (0, import_react25.useMemo)(() => {
|
|
12583
12820
|
if (!parentDataRef.current) {
|
|
12584
12821
|
return [];
|
|
12585
12822
|
}
|
|
@@ -12588,13 +12825,13 @@ function XViewScene({
|
|
|
12588
12825
|
return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
|
|
12589
12826
|
});
|
|
12590
12827
|
}, [parentDataRef.current, sceneVersion]);
|
|
12591
|
-
const handleAddExistingNode = (0,
|
|
12828
|
+
const handleAddExistingNode = (0, import_react25.useCallback)(
|
|
12592
12829
|
(nodeId) => {
|
|
12593
12830
|
return userActionHandlers.handleAddExistingNodeById(actionHandlerContext, nodeId);
|
|
12594
12831
|
},
|
|
12595
12832
|
[actionHandlerContext]
|
|
12596
12833
|
);
|
|
12597
|
-
const handleSaveCurrentView = (0,
|
|
12834
|
+
const handleSaveCurrentView = (0, import_react25.useCallback)(async () => {
|
|
12598
12835
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
12599
12836
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
12600
12837
|
console.warn("N\xE3o \xE9 poss\xEDvel salvar a cena: estado n\xE3o inicializado ou URL de salvamento ausente.");
|
|
@@ -12627,14 +12864,14 @@ function XViewScene({
|
|
|
12627
12864
|
console.error("Erro na chamada de save_view_data:", error);
|
|
12628
12865
|
}
|
|
12629
12866
|
}, [sceneSaveUrl, save_view_data]);
|
|
12630
|
-
const allAvailableNodes = (0,
|
|
12867
|
+
const allAvailableNodes = (0, import_react25.useMemo)(() => {
|
|
12631
12868
|
if (!parentDataRef.current) return [];
|
|
12632
12869
|
return Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
|
|
12633
12870
|
}, [sceneVersion, isInitialized]);
|
|
12634
|
-
const allAvailableAncestries = (0,
|
|
12871
|
+
const allAvailableAncestries = (0, import_react25.useMemo)(() => {
|
|
12635
12872
|
return ancestryDataRef.current || [];
|
|
12636
12873
|
}, [sceneVersion, isInitialized]);
|
|
12637
|
-
const handleOpenReference = (0,
|
|
12874
|
+
const handleOpenReference = (0, import_react25.useCallback)((referenceData) => {
|
|
12638
12875
|
const { type, id } = referenceData;
|
|
12639
12876
|
if (type === "node") {
|
|
12640
12877
|
const targetNode = allAvailableNodes.find((n) => String(n.id) === String(id));
|
|
@@ -12661,17 +12898,17 @@ function XViewScene({
|
|
|
12661
12898
|
}
|
|
12662
12899
|
}
|
|
12663
12900
|
}, [allAvailableNodes, allAvailableAncestries, handleEditAncestry, tweenToTarget]);
|
|
12664
|
-
const handleToggleAncestryAddMode = (0,
|
|
12901
|
+
const handleToggleAncestryAddMode = (0, import_react25.useCallback)(() => {
|
|
12665
12902
|
setAncestryMode((prev) => ({ ...prev, isAddingNodes: !prev.isAddingNodes }));
|
|
12666
12903
|
}, []);
|
|
12667
|
-
const handleFocusNode = (0,
|
|
12904
|
+
const handleFocusNode = (0, import_react25.useCallback)((nodeData) => {
|
|
12668
12905
|
if (!nodeData) return;
|
|
12669
12906
|
const nodeMesh = stateRef.current.nodeObjects[String(nodeData.id)];
|
|
12670
12907
|
if (nodeMesh) {
|
|
12671
12908
|
tweenToTarget(nodeMesh, 1.2);
|
|
12672
12909
|
}
|
|
12673
12910
|
}, [tweenToTarget]);
|
|
12674
|
-
const availableDatasets = (0,
|
|
12911
|
+
const availableDatasets = (0, import_react25.useMemo)(() => {
|
|
12675
12912
|
if (!sceneDataRef.current || !parentDataRef.current) return [];
|
|
12676
12913
|
return sceneDataRef.current.parent_dbs.map((db) => {
|
|
12677
12914
|
var _a2;
|
|
@@ -12683,7 +12920,7 @@ function XViewScene({
|
|
|
12683
12920
|
}, [sceneVersion, isInitialized]);
|
|
12684
12921
|
const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(String(creationMode.sourceNodeData.id))) == null ? void 0 : _b.parentFileId : null;
|
|
12685
12922
|
const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
|
|
12686
|
-
(0,
|
|
12923
|
+
(0, import_react25.useEffect)(() => {
|
|
12687
12924
|
if (isInitialized && focusNodeId && !hasFocusedInitial) {
|
|
12688
12925
|
const nodeObjects = stateRef.current.nodeObjects || {};
|
|
12689
12926
|
const targetMesh = nodeObjects[String(focusNodeId)];
|
|
@@ -12697,7 +12934,7 @@ function XViewScene({
|
|
|
12697
12934
|
}
|
|
12698
12935
|
}
|
|
12699
12936
|
}, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
|
|
12700
|
-
(0,
|
|
12937
|
+
(0, import_react25.useEffect)(() => {
|
|
12701
12938
|
if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
|
|
12702
12939
|
const ancestries = ancestryDataRef.current || [];
|
|
12703
12940
|
const targetAncestry = ancestries.find((a) => String(a.ancestry_id) === String(focusAncestryId));
|
|
@@ -12712,20 +12949,20 @@ function XViewScene({
|
|
|
12712
12949
|
}
|
|
12713
12950
|
}, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
|
|
12714
12951
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
12715
|
-
return /* @__PURE__ */
|
|
12952
|
+
return /* @__PURE__ */ import_react25.default.createElement(LoadingScreen, null);
|
|
12716
12953
|
}
|
|
12717
12954
|
if (permissionStatus === "denied") {
|
|
12718
|
-
return /* @__PURE__ */
|
|
12955
|
+
return /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react25.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_react25.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react25.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_react25.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_react25.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react25.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_react25.default.createElement(
|
|
12719
12956
|
"button",
|
|
12720
12957
|
{
|
|
12721
12958
|
onClick: () => router.push("/dashboard/scenes"),
|
|
12722
12959
|
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"
|
|
12723
12960
|
},
|
|
12724
|
-
/* @__PURE__ */
|
|
12961
|
+
/* @__PURE__ */ import_react25.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_react25.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" })),
|
|
12725
12962
|
"Voltar para Scenes"
|
|
12726
12963
|
)));
|
|
12727
12964
|
}
|
|
12728
|
-
return /* @__PURE__ */
|
|
12965
|
+
return /* @__PURE__ */ import_react25.default.createElement(
|
|
12729
12966
|
"div",
|
|
12730
12967
|
{
|
|
12731
12968
|
ref: mountRef,
|
|
@@ -12737,7 +12974,7 @@ function XViewScene({
|
|
|
12737
12974
|
cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
|
|
12738
12975
|
}
|
|
12739
12976
|
},
|
|
12740
|
-
userPermissionRole !== "link_viewer" && /* @__PURE__ */
|
|
12977
|
+
userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react25.default.createElement(
|
|
12741
12978
|
XViewSidebar,
|
|
12742
12979
|
{
|
|
12743
12980
|
dbNodes: searchableDbNodes,
|
|
@@ -12757,7 +12994,7 @@ function XViewScene({
|
|
|
12757
12994
|
userRole: userPermissionRole
|
|
12758
12995
|
}
|
|
12759
12996
|
),
|
|
12760
|
-
creationMode.isActive && /* @__PURE__ */
|
|
12997
|
+
creationMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
|
|
12761
12998
|
InSceneCreationForm,
|
|
12762
12999
|
{
|
|
12763
13000
|
onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
|
|
@@ -12782,7 +13019,7 @@ function XViewScene({
|
|
|
12782
13019
|
availableAncestries: allAvailableAncestries
|
|
12783
13020
|
}
|
|
12784
13021
|
),
|
|
12785
|
-
versionMode.isActive && /* @__PURE__ */
|
|
13022
|
+
versionMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
|
|
12786
13023
|
InSceneVersionForm,
|
|
12787
13024
|
{
|
|
12788
13025
|
onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
|
|
@@ -12801,13 +13038,27 @@ function XViewScene({
|
|
|
12801
13038
|
availableAncestries: allAvailableAncestries
|
|
12802
13039
|
}
|
|
12803
13040
|
),
|
|
12804
|
-
|
|
13041
|
+
questMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
|
|
13042
|
+
InSceneQuestForm,
|
|
13043
|
+
{
|
|
13044
|
+
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
13045
|
+
onCancel: () => setQuestMode({ isActive: false }),
|
|
13046
|
+
style: { position: "absolute", left: `16px`, top: `16px`, zIndex: 20, transition: "opacity 200ms ease-out" },
|
|
13047
|
+
refEl: formRef,
|
|
13048
|
+
onOpenImageViewer: handleOpenImageViewer,
|
|
13049
|
+
onMentionClick: handleAddExistingNode,
|
|
13050
|
+
onUploadFile: upload_file_action,
|
|
13051
|
+
availableNodes: allAvailableNodes,
|
|
13052
|
+
availableAncestries: allAvailableAncestries
|
|
13053
|
+
}
|
|
13054
|
+
),
|
|
13055
|
+
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react25.default.createElement(
|
|
12805
13056
|
"div",
|
|
12806
13057
|
{
|
|
12807
13058
|
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"}`,
|
|
12808
13059
|
style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${readModeWidth}px`, maxWidth: "92vw" }
|
|
12809
13060
|
},
|
|
12810
|
-
/* @__PURE__ */
|
|
13061
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
12811
13062
|
"div",
|
|
12812
13063
|
{
|
|
12813
13064
|
onPointerDown: (e) => {
|
|
@@ -12818,7 +13069,7 @@ function XViewScene({
|
|
|
12818
13069
|
title: "Arraste para redimensionar"
|
|
12819
13070
|
}
|
|
12820
13071
|
),
|
|
12821
|
-
/* @__PURE__ */
|
|
13072
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
12822
13073
|
DescriptionReadModePanel,
|
|
12823
13074
|
{
|
|
12824
13075
|
key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
|
|
@@ -12853,7 +13104,7 @@ function XViewScene({
|
|
|
12853
13104
|
}
|
|
12854
13105
|
)
|
|
12855
13106
|
),
|
|
12856
|
-
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */
|
|
13107
|
+
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react25.default.createElement(
|
|
12857
13108
|
CreateAncestryPanel,
|
|
12858
13109
|
{
|
|
12859
13110
|
ancestryMode,
|
|
@@ -12880,7 +13131,7 @@ function XViewScene({
|
|
|
12880
13131
|
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
12881
13132
|
}
|
|
12882
13133
|
),
|
|
12883
|
-
editingAncestryRel.visible && /* @__PURE__ */
|
|
13134
|
+
editingAncestryRel.visible && /* @__PURE__ */ import_react25.default.createElement(
|
|
12884
13135
|
AncestryRelationshipPanel,
|
|
12885
13136
|
{
|
|
12886
13137
|
data: editingAncestryRel.data,
|
|
@@ -12894,7 +13145,7 @@ function XViewScene({
|
|
|
12894
13145
|
onUploadFile: upload_file_action
|
|
12895
13146
|
}
|
|
12896
13147
|
),
|
|
12897
|
-
detailsNode && /* @__PURE__ */
|
|
13148
|
+
detailsNode && /* @__PURE__ */ import_react25.default.createElement(
|
|
12898
13149
|
NodeDetailsPanel,
|
|
12899
13150
|
{
|
|
12900
13151
|
node: detailsNode,
|
|
@@ -12921,7 +13172,7 @@ function XViewScene({
|
|
|
12921
13172
|
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
12922
13173
|
}
|
|
12923
13174
|
),
|
|
12924
|
-
detailsLink && /* @__PURE__ */
|
|
13175
|
+
detailsLink && /* @__PURE__ */ import_react25.default.createElement(
|
|
12925
13176
|
RelationshipDetailsPanel,
|
|
12926
13177
|
{
|
|
12927
13178
|
link: detailsLink,
|
|
@@ -12935,7 +13186,7 @@ function XViewScene({
|
|
|
12935
13186
|
userRole: userPermissionRole
|
|
12936
13187
|
}
|
|
12937
13188
|
),
|
|
12938
|
-
ancestryLinkDetails && /* @__PURE__ */
|
|
13189
|
+
ancestryLinkDetails && /* @__PURE__ */ import_react25.default.createElement(
|
|
12939
13190
|
AncestryLinkDetailsPanel,
|
|
12940
13191
|
{
|
|
12941
13192
|
data: ancestryLinkDetails,
|
|
@@ -12946,7 +13197,7 @@ function XViewScene({
|
|
|
12946
13197
|
onUploadFile: upload_file_action
|
|
12947
13198
|
}
|
|
12948
13199
|
),
|
|
12949
|
-
/* @__PURE__ */
|
|
13200
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
12950
13201
|
"div",
|
|
12951
13202
|
{
|
|
12952
13203
|
ref: tooltipRef,
|
|
@@ -12973,7 +13224,7 @@ function XViewScene({
|
|
|
12973
13224
|
}
|
|
12974
13225
|
}
|
|
12975
13226
|
),
|
|
12976
|
-
/* @__PURE__ */
|
|
13227
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
12977
13228
|
ContextMenu,
|
|
12978
13229
|
{
|
|
12979
13230
|
data: contextMenu,
|
|
@@ -12996,7 +13247,7 @@ function XViewScene({
|
|
|
12996
13247
|
onFocusNode: handleFocusNode
|
|
12997
13248
|
}
|
|
12998
13249
|
),
|
|
12999
|
-
/* @__PURE__ */
|
|
13250
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
13000
13251
|
MultiNodeContextMenu,
|
|
13001
13252
|
{
|
|
13002
13253
|
data: multiContextMenu,
|
|
@@ -13007,7 +13258,7 @@ function XViewScene({
|
|
|
13007
13258
|
onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
|
|
13008
13259
|
}
|
|
13009
13260
|
),
|
|
13010
|
-
/* @__PURE__ */
|
|
13261
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
13011
13262
|
RelationshipContextMenu,
|
|
13012
13263
|
{
|
|
13013
13264
|
data: relationshipMenu,
|
|
@@ -13025,8 +13276,8 @@ function XViewScene({
|
|
|
13025
13276
|
onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
|
|
13026
13277
|
}
|
|
13027
13278
|
),
|
|
13028
|
-
/* @__PURE__ */
|
|
13029
|
-
/* @__PURE__ */
|
|
13279
|
+
/* @__PURE__ */ import_react25.default.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
|
|
13280
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
13030
13281
|
AncestryBoard,
|
|
13031
13282
|
{
|
|
13032
13283
|
isOpen: isAncestryBoardOpen,
|
|
@@ -13039,7 +13290,7 @@ function XViewScene({
|
|
|
13039
13290
|
userRole: userPermissionRole
|
|
13040
13291
|
}
|
|
13041
13292
|
),
|
|
13042
|
-
/* @__PURE__ */
|
|
13293
|
+
/* @__PURE__ */ import_react25.default.createElement(
|
|
13043
13294
|
ImportParentFileModal,
|
|
13044
13295
|
{
|
|
13045
13296
|
isOpen: isImportModalOpen,
|
|
@@ -13104,7 +13355,13 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
13104
13355
|
const allLinks = Object.values(parentData).flatMap((db) => db.links || []);
|
|
13105
13356
|
const parentNodeMap = new Map(allNodes.map((node) => [String(node.id), node]));
|
|
13106
13357
|
const parentLinkMap = new Map(allLinks.map((link) => [`${link.source}-${link.target}`, link]));
|
|
13107
|
-
const validatedNodes = (sceneData.nodes || []).map((sceneNode) =>
|
|
13358
|
+
const validatedNodes = (sceneData.nodes || []).map((sceneNode) => {
|
|
13359
|
+
const nodeTypes = Array.isArray(sceneNode.type) ? sceneNode.type : [sceneNode.type];
|
|
13360
|
+
if (nodeTypes.includes("quest")) {
|
|
13361
|
+
return sceneNode;
|
|
13362
|
+
}
|
|
13363
|
+
return parentNodeMap.get(String(sceneNode.id));
|
|
13364
|
+
}).filter(Boolean);
|
|
13108
13365
|
const validNodeIdsInScene = new Set(validatedNodes.map((node) => String(node.id)));
|
|
13109
13366
|
const validatedLinks = (sceneData.links || []).filter((sceneLink) => {
|
|
13110
13367
|
const linkExistsInParent = parentLinkMap.has(`${sceneLink.source}-${sceneLink.target}`);
|