@lv-x-software-house/x_view 1.2.6-dev.7 → 1.2.6-dev.9
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 +700 -608
- package/dist/index.mjs +706 -615
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// src/XViewScene.jsx
|
|
2
|
-
import
|
|
3
|
-
useCallback as
|
|
4
|
-
useEffect as
|
|
5
|
-
useRef as
|
|
6
|
-
useState as
|
|
7
|
-
useMemo as
|
|
2
|
+
import React30, {
|
|
3
|
+
useCallback as useCallback5,
|
|
4
|
+
useEffect as useEffect24,
|
|
5
|
+
useRef as useRef20,
|
|
6
|
+
useState as useState29,
|
|
7
|
+
useMemo as useMemo13
|
|
8
8
|
} from "react";
|
|
9
9
|
import { useRouter, useSearchParams } from "next/navigation";
|
|
10
10
|
import { useSession } from "next-auth/react";
|
|
@@ -12950,10 +12950,10 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
12950
12950
|
}
|
|
12951
12951
|
|
|
12952
12952
|
// src/components/AncestryBoard.jsx
|
|
12953
|
-
import
|
|
12953
|
+
import React28, { useState as useState27, useMemo as useMemo12, useEffect as useEffect23 } from "react";
|
|
12954
12954
|
import {
|
|
12955
12955
|
FiSearch as FiSearch8,
|
|
12956
|
-
FiLayers as
|
|
12956
|
+
FiLayers as FiLayers7,
|
|
12957
12957
|
FiCornerUpRight as FiCornerUpRight4,
|
|
12958
12958
|
FiPlay,
|
|
12959
12959
|
FiPlus as FiPlus10,
|
|
@@ -12963,175 +12963,416 @@ import {
|
|
|
12963
12963
|
FiCheckCircle,
|
|
12964
12964
|
FiLoader as FiLoader5,
|
|
12965
12965
|
FiX as FiX8,
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
FiGitBranch as FiGitBranch3
|
|
12966
|
+
FiBox as FiBox2,
|
|
12967
|
+
FiCheckSquare as FiCheckSquare4,
|
|
12968
|
+
FiGitBranch as FiGitBranch4
|
|
12970
12969
|
} from "react-icons/fi";
|
|
12971
12970
|
import { v4 as uuidv411 } from "uuid";
|
|
12971
|
+
|
|
12972
|
+
// src/components/RichGroupEditor.jsx
|
|
12973
|
+
import React27, { useEffect as useEffect22, useRef as useRef19, useState as useState26, useCallback as useCallback4 } from "react";
|
|
12974
|
+
|
|
12975
|
+
// src/components/MentionPopover.jsx
|
|
12976
|
+
import React26, { useEffect as useEffect21, useRef as useRef18, useState as useState25, useMemo as useMemo11 } from "react";
|
|
12977
|
+
import { FiLayers as FiLayers6, FiCheckSquare as FiCheckSquare3, FiGitBranch as FiGitBranch3, FiBox } from "react-icons/fi";
|
|
12978
|
+
var TYPE_CONFIG = {
|
|
12979
|
+
ancestry: { Icon: FiLayers6, color: "text-indigo-400", label: "Ancestralidade" },
|
|
12980
|
+
quest: { Icon: FiCheckSquare3, color: "text-emerald-400", label: "Quest" },
|
|
12981
|
+
version: { Icon: FiGitBranch3, color: "text-amber-400", label: "Vers\xE3o" },
|
|
12982
|
+
node: { Icon: FiBox, color: "text-slate-400", label: "Node" }
|
|
12983
|
+
};
|
|
12984
|
+
function MentionPopover({ query, items, position, onSelect, onClose }) {
|
|
12985
|
+
const [activeIndex, setActiveIndex] = useState25(0);
|
|
12986
|
+
const listRef = useRef18(null);
|
|
12987
|
+
const filtered = useMemo11(() => {
|
|
12988
|
+
const term = (query || "").toLowerCase().trim();
|
|
12989
|
+
if (!term) return items.slice(0, 8);
|
|
12990
|
+
return items.filter(
|
|
12991
|
+
(item) => (item.searchLabel || "").toLowerCase().includes(term) || (item.searchDesc || "").toLowerCase().includes(term)
|
|
12992
|
+
).slice(0, 8);
|
|
12993
|
+
}, [items, query]);
|
|
12994
|
+
useEffect21(() => {
|
|
12995
|
+
setActiveIndex(0);
|
|
12996
|
+
}, [query]);
|
|
12997
|
+
useEffect21(() => {
|
|
12998
|
+
const handleKeyDown = (e) => {
|
|
12999
|
+
if (e.key === "ArrowDown") {
|
|
13000
|
+
e.preventDefault();
|
|
13001
|
+
setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));
|
|
13002
|
+
} else if (e.key === "ArrowUp") {
|
|
13003
|
+
e.preventDefault();
|
|
13004
|
+
setActiveIndex((i) => Math.max(i - 1, 0));
|
|
13005
|
+
} else if (e.key === "Enter" || e.key === "Tab") {
|
|
13006
|
+
e.preventDefault();
|
|
13007
|
+
if (filtered[activeIndex]) onSelect(filtered[activeIndex]);
|
|
13008
|
+
} else if (e.key === "Escape") {
|
|
13009
|
+
e.preventDefault();
|
|
13010
|
+
onClose();
|
|
13011
|
+
}
|
|
13012
|
+
};
|
|
13013
|
+
window.addEventListener("keydown", handleKeyDown, true);
|
|
13014
|
+
return () => window.removeEventListener("keydown", handleKeyDown, true);
|
|
13015
|
+
}, [filtered, activeIndex, onSelect, onClose]);
|
|
13016
|
+
useEffect21(() => {
|
|
13017
|
+
if (listRef.current) {
|
|
13018
|
+
const el = listRef.current.children[activeIndex];
|
|
13019
|
+
if (el) el.scrollIntoView({ block: "nearest" });
|
|
13020
|
+
}
|
|
13021
|
+
}, [activeIndex]);
|
|
13022
|
+
return /* @__PURE__ */ React26.createElement(
|
|
13023
|
+
"div",
|
|
13024
|
+
{
|
|
13025
|
+
style: { top: position.top, left: position.left, position: "fixed", zIndex: 9999 },
|
|
13026
|
+
className: "bg-slate-900 border border-white/10 rounded-xl shadow-2xl py-1.5 min-w-[260px] max-h-[240px] overflow-y-auto custom-scrollbar animate-in fade-in zoom-in-95 duration-100",
|
|
13027
|
+
ref: listRef,
|
|
13028
|
+
onMouseDown: (e) => e.preventDefault()
|
|
13029
|
+
},
|
|
13030
|
+
filtered.length === 0 ? /* @__PURE__ */ React26.createElement("div", { className: "px-4 py-3 text-xs text-slate-500" }, "Nenhum resultado para", " ", /* @__PURE__ */ React26.createElement("span", { className: "text-slate-300 font-medium" }, '"', query, '"')) : filtered.map((item, idx) => {
|
|
13031
|
+
const config = TYPE_CONFIG[item.type] || TYPE_CONFIG.node;
|
|
13032
|
+
const { Icon } = config;
|
|
13033
|
+
return /* @__PURE__ */ React26.createElement(
|
|
13034
|
+
"div",
|
|
13035
|
+
{
|
|
13036
|
+
key: item.id,
|
|
13037
|
+
onMouseDown: (e) => {
|
|
13038
|
+
e.preventDefault();
|
|
13039
|
+
onSelect(item);
|
|
13040
|
+
},
|
|
13041
|
+
onMouseEnter: () => setActiveIndex(idx),
|
|
13042
|
+
className: `flex items-center gap-2.5 px-3 py-2 cursor-pointer text-sm transition-colors duration-100 ${idx === activeIndex ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5"}`
|
|
13043
|
+
},
|
|
13044
|
+
/* @__PURE__ */ React26.createElement(Icon, { size: 13, className: config.color }),
|
|
13045
|
+
/* @__PURE__ */ React26.createElement("span", { className: "flex-1 truncate font-medium" }, item.searchLabel || "Sem Nome"),
|
|
13046
|
+
/* @__PURE__ */ React26.createElement("span", { className: "text-[9px] px-1.5 py-0.5 rounded-full bg-white/5 text-slate-500 border border-white/5 uppercase tracking-wide shrink-0" }, config.label)
|
|
13047
|
+
);
|
|
13048
|
+
})
|
|
13049
|
+
);
|
|
13050
|
+
}
|
|
13051
|
+
|
|
13052
|
+
// src/components/RichGroupEditor.jsx
|
|
13053
|
+
var MENTION_BASE_STYLE = "display:inline-flex;align-items:center;padding:1px 7px;border-radius:5px;margin:0 2px;font-size:0.78em;font-weight:600;cursor:pointer;white-space:nowrap;vertical-align:middle;user-select:none;line-height:1.6;";
|
|
13054
|
+
var MENTION_TYPE_STYLE = {
|
|
13055
|
+
ancestry: "background:rgba(99,102,241,0.18);color:#a5b4fc;border:1px solid rgba(99,102,241,0.35);",
|
|
13056
|
+
quest: "background:rgba(16,185,129,0.18);color:#6ee7b7;border:1px solid rgba(16,185,129,0.35);",
|
|
13057
|
+
version: "background:rgba(245,158,11,0.18);color:#fcd34d;border:1px solid rgba(245,158,11,0.35);",
|
|
13058
|
+
node: "background:rgba(100,116,139,0.18);color:#94a3b8;border:1px solid rgba(100,116,139,0.35);"
|
|
13059
|
+
};
|
|
13060
|
+
function mentionStyle(type) {
|
|
13061
|
+
return MENTION_BASE_STYLE + (MENTION_TYPE_STYLE[type] || MENTION_TYPE_STYLE.node);
|
|
13062
|
+
}
|
|
13063
|
+
function escapeHtml(str) {
|
|
13064
|
+
return String(str || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
13065
|
+
}
|
|
13066
|
+
function contentToHTML(content) {
|
|
13067
|
+
if (!content || content.length === 0) return "";
|
|
13068
|
+
return content.map((seg) => {
|
|
13069
|
+
if (seg.type === "text") {
|
|
13070
|
+
return escapeHtml(seg.value).replace(/\n/g, "<br>");
|
|
13071
|
+
}
|
|
13072
|
+
if (seg.type === "mention") {
|
|
13073
|
+
const style = mentionStyle(seg.mentionType);
|
|
13074
|
+
return `<span contenteditable="false" data-mention="true" data-id="${escapeHtml(String(seg.id))}" data-name="${escapeHtml(seg.name || "")}" data-mention-type="${escapeHtml(seg.mentionType || "node")}" style="${style}" title="Clique para focar na cena">@${escapeHtml(seg.name || "")}</span>`;
|
|
13075
|
+
}
|
|
13076
|
+
return "";
|
|
13077
|
+
}).join("");
|
|
13078
|
+
}
|
|
13079
|
+
function domToContent(el) {
|
|
13080
|
+
const segments = [];
|
|
13081
|
+
function pushText(text) {
|
|
13082
|
+
const clean = text.replace(/\u200B/g, "");
|
|
13083
|
+
if (!clean) return;
|
|
13084
|
+
const last = segments[segments.length - 1];
|
|
13085
|
+
if (last && last.type === "text") {
|
|
13086
|
+
last.value += clean;
|
|
13087
|
+
} else {
|
|
13088
|
+
segments.push({ type: "text", value: clean });
|
|
13089
|
+
}
|
|
13090
|
+
}
|
|
13091
|
+
function walk(node) {
|
|
13092
|
+
var _a;
|
|
13093
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
13094
|
+
pushText(node.textContent);
|
|
13095
|
+
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
13096
|
+
if (((_a = node.dataset) == null ? void 0 : _a.mention) === "true") {
|
|
13097
|
+
segments.push({
|
|
13098
|
+
type: "mention",
|
|
13099
|
+
id: node.dataset.id,
|
|
13100
|
+
name: node.dataset.name,
|
|
13101
|
+
mentionType: node.dataset.mentionType
|
|
13102
|
+
});
|
|
13103
|
+
} else if (node.tagName === "BR") {
|
|
13104
|
+
pushText("\n");
|
|
13105
|
+
} else {
|
|
13106
|
+
if (["DIV", "P"].includes(node.tagName) && segments.length > 0) {
|
|
13107
|
+
pushText("\n");
|
|
13108
|
+
}
|
|
13109
|
+
node.childNodes.forEach(walk);
|
|
13110
|
+
}
|
|
13111
|
+
}
|
|
13112
|
+
}
|
|
13113
|
+
el.childNodes.forEach(walk);
|
|
13114
|
+
return segments;
|
|
13115
|
+
}
|
|
13116
|
+
function RichGroupEditor({
|
|
13117
|
+
content,
|
|
13118
|
+
onChange,
|
|
13119
|
+
onMentionClick,
|
|
13120
|
+
searchItems,
|
|
13121
|
+
readOnly,
|
|
13122
|
+
placeholder
|
|
13123
|
+
}) {
|
|
13124
|
+
const editorRef = useRef19(null);
|
|
13125
|
+
const isMountedRef = useRef19(false);
|
|
13126
|
+
const [mentionState, setMentionState] = useState26(null);
|
|
13127
|
+
const [isEmpty, setIsEmpty] = useState26(true);
|
|
13128
|
+
useEffect22(() => {
|
|
13129
|
+
if (!isMountedRef.current && editorRef.current) {
|
|
13130
|
+
editorRef.current.innerHTML = contentToHTML(content);
|
|
13131
|
+
const hasContent = !!editorRef.current.innerText.replace(/\u200B/g, "").trim();
|
|
13132
|
+
const hasMentions = !!editorRef.current.querySelector("[data-mention]");
|
|
13133
|
+
setIsEmpty(!hasContent && !hasMentions);
|
|
13134
|
+
isMountedRef.current = true;
|
|
13135
|
+
}
|
|
13136
|
+
}, []);
|
|
13137
|
+
const getMentionContext = useCallback4(() => {
|
|
13138
|
+
const selection = window.getSelection();
|
|
13139
|
+
if (!selection || selection.rangeCount === 0) return null;
|
|
13140
|
+
const range = selection.getRangeAt(0);
|
|
13141
|
+
if (range.startContainer.nodeType !== Node.TEXT_NODE) return null;
|
|
13142
|
+
const textBefore = range.startContainer.textContent.substring(0, range.startOffset);
|
|
13143
|
+
const atIndex = textBefore.lastIndexOf("@");
|
|
13144
|
+
if (atIndex === -1) return null;
|
|
13145
|
+
const query = textBefore.substring(atIndex + 1);
|
|
13146
|
+
if (query.includes(" ") || query.length > 40) return null;
|
|
13147
|
+
const rect = range.getBoundingClientRect();
|
|
13148
|
+
return {
|
|
13149
|
+
query,
|
|
13150
|
+
position: { top: rect.bottom + 6, left: rect.left }
|
|
13151
|
+
};
|
|
13152
|
+
}, []);
|
|
13153
|
+
const handleInput = useCallback4(() => {
|
|
13154
|
+
if (!editorRef.current) return;
|
|
13155
|
+
const serialized = domToContent(editorRef.current);
|
|
13156
|
+
onChange(serialized);
|
|
13157
|
+
const text = editorRef.current.innerText.replace(/\u200B/g, "").trim();
|
|
13158
|
+
const hasMentions = !!editorRef.current.querySelector("[data-mention]");
|
|
13159
|
+
setIsEmpty(!text && !hasMentions);
|
|
13160
|
+
const ctx = getMentionContext();
|
|
13161
|
+
setMentionState(ctx);
|
|
13162
|
+
}, [onChange, getMentionContext]);
|
|
13163
|
+
const handleKeyDown = useCallback4(
|
|
13164
|
+
(e) => {
|
|
13165
|
+
if (mentionState && ["ArrowDown", "ArrowUp", "Enter", "Tab", "Escape"].includes(e.key)) {
|
|
13166
|
+
return;
|
|
13167
|
+
}
|
|
13168
|
+
if (e.key === "Enter") {
|
|
13169
|
+
e.preventDefault();
|
|
13170
|
+
const sel = window.getSelection();
|
|
13171
|
+
const range = sel.getRangeAt(0);
|
|
13172
|
+
const br = document.createElement("br");
|
|
13173
|
+
range.deleteContents();
|
|
13174
|
+
range.insertNode(br);
|
|
13175
|
+
const afterBr = br.nextSibling || (() => {
|
|
13176
|
+
const zws = document.createTextNode("\u200B");
|
|
13177
|
+
br.parentNode.insertBefore(zws, br.nextSibling);
|
|
13178
|
+
return zws;
|
|
13179
|
+
})();
|
|
13180
|
+
const newRange = document.createRange();
|
|
13181
|
+
newRange.setStartBefore(afterBr);
|
|
13182
|
+
newRange.collapse(true);
|
|
13183
|
+
sel.removeAllRanges();
|
|
13184
|
+
sel.addRange(newRange);
|
|
13185
|
+
handleInput();
|
|
13186
|
+
}
|
|
13187
|
+
},
|
|
13188
|
+
[mentionState, handleInput]
|
|
13189
|
+
);
|
|
13190
|
+
const insertMention = useCallback4(
|
|
13191
|
+
(item) => {
|
|
13192
|
+
if (!editorRef.current) return;
|
|
13193
|
+
const sel = window.getSelection();
|
|
13194
|
+
if (!sel || sel.rangeCount === 0) return;
|
|
13195
|
+
const range = sel.getRangeAt(0);
|
|
13196
|
+
const textNode = range.startContainer;
|
|
13197
|
+
if (textNode.nodeType !== Node.TEXT_NODE) {
|
|
13198
|
+
setMentionState(null);
|
|
13199
|
+
return;
|
|
13200
|
+
}
|
|
13201
|
+
const cursorPos = range.startOffset;
|
|
13202
|
+
const textContent = textNode.textContent;
|
|
13203
|
+
const atIndex = textContent.lastIndexOf("@", cursorPos - 1);
|
|
13204
|
+
if (atIndex === -1) {
|
|
13205
|
+
setMentionState(null);
|
|
13206
|
+
return;
|
|
13207
|
+
}
|
|
13208
|
+
const before = textContent.substring(0, atIndex);
|
|
13209
|
+
const after = textContent.substring(cursorPos);
|
|
13210
|
+
textNode.textContent = before;
|
|
13211
|
+
const parent = textNode.parentNode;
|
|
13212
|
+
const nextSib = textNode.nextSibling;
|
|
13213
|
+
const span = document.createElement("span");
|
|
13214
|
+
span.contentEditable = "false";
|
|
13215
|
+
span.dataset.mention = "true";
|
|
13216
|
+
span.dataset.id = item.id;
|
|
13217
|
+
span.dataset.name = item.searchLabel || item.name || "";
|
|
13218
|
+
span.dataset.mentionType = item.type;
|
|
13219
|
+
span.style.cssText = mentionStyle(item.type);
|
|
13220
|
+
span.title = "Clique para focar na cena";
|
|
13221
|
+
span.textContent = `@${item.searchLabel || item.name || ""}`;
|
|
13222
|
+
parent.insertBefore(span, nextSib);
|
|
13223
|
+
const trailing = document.createTextNode(after || "\u200B");
|
|
13224
|
+
parent.insertBefore(trailing, span.nextSibling);
|
|
13225
|
+
const newRange = document.createRange();
|
|
13226
|
+
newRange.setStart(trailing, after ? 0 : 1);
|
|
13227
|
+
newRange.collapse(true);
|
|
13228
|
+
sel.removeAllRanges();
|
|
13229
|
+
sel.addRange(newRange);
|
|
13230
|
+
const serialized = domToContent(editorRef.current);
|
|
13231
|
+
onChange(serialized);
|
|
13232
|
+
setMentionState(null);
|
|
13233
|
+
setIsEmpty(false);
|
|
13234
|
+
},
|
|
13235
|
+
[onChange]
|
|
13236
|
+
);
|
|
13237
|
+
const handlePaste = useCallback4(
|
|
13238
|
+
(e) => {
|
|
13239
|
+
e.preventDefault();
|
|
13240
|
+
const text = e.clipboardData.getData("text/plain");
|
|
13241
|
+
if (text) {
|
|
13242
|
+
document.execCommand("insertText", false, text);
|
|
13243
|
+
handleInput();
|
|
13244
|
+
}
|
|
13245
|
+
},
|
|
13246
|
+
[handleInput]
|
|
13247
|
+
);
|
|
13248
|
+
const handleClick = useCallback4(
|
|
13249
|
+
(e) => {
|
|
13250
|
+
const chip = e.target.closest("[data-mention='true']");
|
|
13251
|
+
if (chip && onMentionClick) {
|
|
13252
|
+
e.stopPropagation();
|
|
13253
|
+
const id = chip.dataset.id;
|
|
13254
|
+
const full = searchItems == null ? void 0 : searchItems.find((i) => String(i.id) === String(id));
|
|
13255
|
+
if (full) {
|
|
13256
|
+
onMentionClick(full);
|
|
13257
|
+
} else {
|
|
13258
|
+
onMentionClick({
|
|
13259
|
+
id,
|
|
13260
|
+
name: chip.dataset.name,
|
|
13261
|
+
type: chip.dataset.mentionType,
|
|
13262
|
+
searchLabel: chip.dataset.name
|
|
13263
|
+
});
|
|
13264
|
+
}
|
|
13265
|
+
return;
|
|
13266
|
+
}
|
|
13267
|
+
setTimeout(() => {
|
|
13268
|
+
const ctx = getMentionContext();
|
|
13269
|
+
setMentionState(ctx);
|
|
13270
|
+
}, 0);
|
|
13271
|
+
},
|
|
13272
|
+
[onMentionClick, getMentionContext, searchItems]
|
|
13273
|
+
);
|
|
13274
|
+
const handleBlur = useCallback4(() => {
|
|
13275
|
+
setTimeout(() => setMentionState(null), 200);
|
|
13276
|
+
}, []);
|
|
13277
|
+
return /* @__PURE__ */ React27.createElement("div", { className: "relative" }, isEmpty && !readOnly && /* @__PURE__ */ React27.createElement("div", { className: "absolute top-0 left-0 text-sm text-slate-600 pointer-events-none select-none" }, placeholder || "Escreva sobre este grupo\u2026 ou digite @ para mencionar"), /* @__PURE__ */ React27.createElement(
|
|
13278
|
+
"div",
|
|
13279
|
+
{
|
|
13280
|
+
ref: editorRef,
|
|
13281
|
+
contentEditable: readOnly ? "false" : "true",
|
|
13282
|
+
suppressContentEditableWarning: true,
|
|
13283
|
+
onInput: handleInput,
|
|
13284
|
+
onKeyDown: handleKeyDown,
|
|
13285
|
+
onPaste: handlePaste,
|
|
13286
|
+
onClick: handleClick,
|
|
13287
|
+
onBlur: handleBlur,
|
|
13288
|
+
className: `w-full min-h-[1.5rem] max-h-[250px] overflow-y-auto text-sm text-slate-200 focus:outline-none leading-relaxed ${!readOnly ? "cursor-text" : "cursor-default"}`,
|
|
13289
|
+
style: { overflowWrap: "break-word", wordBreak: "break-word" }
|
|
13290
|
+
}
|
|
13291
|
+
), mentionState && !readOnly && /* @__PURE__ */ React27.createElement(
|
|
13292
|
+
MentionPopover,
|
|
13293
|
+
{
|
|
13294
|
+
query: mentionState.query,
|
|
13295
|
+
items: searchItems || [],
|
|
13296
|
+
position: mentionState.position,
|
|
13297
|
+
onSelect: insertMention,
|
|
13298
|
+
onClose: () => setMentionState(null)
|
|
13299
|
+
}
|
|
13300
|
+
));
|
|
13301
|
+
}
|
|
13302
|
+
|
|
13303
|
+
// src/components/AncestryBoard.jsx
|
|
12972
13304
|
var GroupItem = ({
|
|
12973
13305
|
group,
|
|
12974
13306
|
index,
|
|
12975
|
-
siblings,
|
|
12976
13307
|
onUpdate,
|
|
12977
13308
|
onDelete,
|
|
12978
13309
|
onAddSubgroup,
|
|
12979
13310
|
onIndent,
|
|
12980
13311
|
onOutdent,
|
|
12981
|
-
|
|
12982
|
-
|
|
12983
|
-
pickingGroupId,
|
|
12984
|
-
onPlayAncestry,
|
|
12985
|
-
availableIds,
|
|
13312
|
+
searchItems,
|
|
13313
|
+
onMentionClick,
|
|
12986
13314
|
canEdit
|
|
12987
13315
|
}) => {
|
|
12988
13316
|
const canIndent = index > 0;
|
|
12989
|
-
const
|
|
12990
|
-
|
|
12991
|
-
const adjustHeight = () => {
|
|
12992
|
-
const textarea = textareaRef.current;
|
|
12993
|
-
if (textarea) {
|
|
12994
|
-
textarea.style.height = "auto";
|
|
12995
|
-
textarea.style.height = `${textarea.scrollHeight}px`;
|
|
12996
|
-
}
|
|
13317
|
+
const handleContentChange = (content) => {
|
|
13318
|
+
onUpdate(group.id, { ...group, content });
|
|
12997
13319
|
};
|
|
12998
|
-
|
|
12999
|
-
|
|
13000
|
-
}, [group.text]);
|
|
13001
|
-
return /* @__PURE__ */ React26.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__ */ React26.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ React26.createElement(
|
|
13002
|
-
"div",
|
|
13320
|
+
return /* @__PURE__ */ React28.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__ */ React28.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col gap-2 py-2 px-3 transition-all duration-200 hover:bg-white/5 border-l-2 border-transparent hover:border-white/20" }, /* @__PURE__ */ React28.createElement(
|
|
13321
|
+
RichGroupEditor,
|
|
13003
13322
|
{
|
|
13004
|
-
|
|
13005
|
-
|
|
13006
|
-
|
|
13007
|
-
|
|
13323
|
+
content: group.content,
|
|
13324
|
+
onChange: handleContentChange,
|
|
13325
|
+
onMentionClick,
|
|
13326
|
+
searchItems,
|
|
13327
|
+
readOnly: !canEdit,
|
|
13328
|
+
placeholder: "Escreva sobre este grupo\u2026 ou @ para mencionar"
|
|
13329
|
+
}
|
|
13330
|
+
), canEdit && /* @__PURE__ */ React28.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__ */ React28.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React28.createElement(
|
|
13331
|
+
"button",
|
|
13332
|
+
{
|
|
13333
|
+
onClick: () => onAddSubgroup(group.id),
|
|
13334
|
+
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
13335
|
+
title: "Criar Subgrupo"
|
|
13008
13336
|
},
|
|
13009
|
-
/* @__PURE__ */
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
|
|
13014
|
-
|
|
13015
|
-
|
|
13016
|
-
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
|
|
13024
|
-
|
|
13025
|
-
|
|
13026
|
-
)
|
|
13027
|
-
|
|
13028
|
-
|
|
13029
|
-
|
|
13030
|
-
|
|
13031
|
-
|
|
13032
|
-
|
|
13033
|
-
|
|
13034
|
-
|
|
13035
|
-
|
|
13036
|
-
`,
|
|
13037
|
-
title: isValid ? "" : "Esta ancestralidade foi removida ou n\xE3o existe mais."
|
|
13038
|
-
},
|
|
13039
|
-
isValid ? /* @__PURE__ */ React26.createElement(
|
|
13040
|
-
"button",
|
|
13041
|
-
{
|
|
13042
|
-
onClick: () => onPlayAncestry(anc),
|
|
13043
|
-
className: "text-indigo-400 hover:text-white hover:bg-indigo-500 p-1 rounded-full transition-colors",
|
|
13044
|
-
title: "Focar no cen\xE1rio"
|
|
13045
|
-
},
|
|
13046
|
-
/* @__PURE__ */ React26.createElement(FiPlay, { size: 10, className: "ml-0.5 fill-current" })
|
|
13047
|
-
) : /* @__PURE__ */ React26.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ React26.createElement(FiAlertTriangle, { size: 10 })),
|
|
13048
|
-
/* @__PURE__ */ React26.createElement(
|
|
13049
|
-
"div",
|
|
13050
|
-
{
|
|
13051
|
-
className: `flex items-center gap-1.5 font-medium truncate max-w-[180px] ${!isValid && "line-through decoration-red-500/50"}`
|
|
13052
|
-
},
|
|
13053
|
-
!isValid ? null : anc.type === "node" ? /* @__PURE__ */ React26.createElement(FiBox, { size: 10, className: "text-slate-400" }) : anc.type === "quest" ? /* @__PURE__ */ React26.createElement(FiCheckSquare3, { size: 10, className: "text-emerald-400" }) : anc.type === "version" ? /* @__PURE__ */ React26.createElement(FiGitBranch3, { size: 10, className: "text-amber-400" }) : /* @__PURE__ */ React26.createElement(FiLayers6, { size: 10, className: "text-indigo-400" }),
|
|
13054
|
-
anc.name
|
|
13055
|
-
),
|
|
13056
|
-
canEdit && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(
|
|
13057
|
-
"div",
|
|
13058
|
-
{
|
|
13059
|
-
className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}`
|
|
13060
|
-
}
|
|
13061
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13062
|
-
"button",
|
|
13063
|
-
{
|
|
13064
|
-
onClick: () => onRemoveAncestry(group.id, anc.ancestry_id),
|
|
13065
|
-
className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
|
|
13066
|
-
title: "Remover men\xE7\xE3o"
|
|
13067
|
-
},
|
|
13068
|
-
/* @__PURE__ */ React26.createElement(FiX8, { size: 12 })
|
|
13069
|
-
))
|
|
13070
|
-
);
|
|
13071
|
-
})),
|
|
13072
|
-
canEdit && /* @__PURE__ */ React26.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__ */ React26.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React26.createElement(
|
|
13073
|
-
"button",
|
|
13074
|
-
{
|
|
13075
|
-
onClick: () => onRequestPickAncestry(group.id),
|
|
13076
|
-
className: `
|
|
13077
|
-
flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium transition-colors
|
|
13078
|
-
${isPickingForThisGroup ? "text-indigo-300 animate-pulse" : "text-slate-500 hover:text-indigo-300 hover:bg-indigo-500/10"}
|
|
13079
|
-
`,
|
|
13080
|
-
title: "Adicionar Ancestralidade a este grupo"
|
|
13081
|
-
},
|
|
13082
|
-
isPickingForThisGroup ? /* @__PURE__ */ React26.createElement(FiCheckCircle, { size: 12 }) : /* @__PURE__ */ React26.createElement(FiSearch8, { size: 12 }),
|
|
13083
|
-
isPickingForThisGroup ? "Selecionando..." : "Adicionar"
|
|
13084
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13085
|
-
"button",
|
|
13086
|
-
{
|
|
13087
|
-
onClick: () => onAddSubgroup(group.id),
|
|
13088
|
-
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
13089
|
-
title: "Criar Subgrupo"
|
|
13090
|
-
},
|
|
13091
|
-
/* @__PURE__ */ React26.createElement(FiPlus10, { size: 14 })
|
|
13092
|
-
)), /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React26.createElement(
|
|
13093
|
-
"button",
|
|
13094
|
-
{
|
|
13095
|
-
onClick: () => onIndent(group.id),
|
|
13096
|
-
disabled: !canIndent,
|
|
13097
|
-
className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
|
|
13098
|
-
title: "Aninhar no grupo acima"
|
|
13099
|
-
},
|
|
13100
|
-
/* @__PURE__ */ React26.createElement(FiArrowRight2, { size: 14 })
|
|
13101
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13102
|
-
"button",
|
|
13103
|
-
{
|
|
13104
|
-
onClick: () => onOutdent(group.id),
|
|
13105
|
-
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
13106
|
-
title: "Desaninhar"
|
|
13107
|
-
},
|
|
13108
|
-
/* @__PURE__ */ React26.createElement(FiArrowLeft3, { size: 14 })
|
|
13109
|
-
), /* @__PURE__ */ React26.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ React26.createElement(
|
|
13110
|
-
"button",
|
|
13111
|
-
{
|
|
13112
|
-
onClick: () => onDelete(group.id),
|
|
13113
|
-
className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
|
|
13114
|
-
title: "Remover Grupo"
|
|
13115
|
-
},
|
|
13116
|
-
/* @__PURE__ */ React26.createElement(FiTrash23, { size: 14 })
|
|
13117
|
-
)))
|
|
13118
|
-
), group.children && group.children.length > 0 && /* @__PURE__ */ React26.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ React26.createElement(
|
|
13337
|
+
/* @__PURE__ */ React28.createElement(FiPlus10, { size: 14 })
|
|
13338
|
+
)), /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React28.createElement(
|
|
13339
|
+
"button",
|
|
13340
|
+
{
|
|
13341
|
+
onClick: () => onIndent(group.id),
|
|
13342
|
+
disabled: !canIndent,
|
|
13343
|
+
className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
|
|
13344
|
+
title: "Aninhar no grupo acima"
|
|
13345
|
+
},
|
|
13346
|
+
/* @__PURE__ */ React28.createElement(FiArrowRight2, { size: 14 })
|
|
13347
|
+
), /* @__PURE__ */ React28.createElement(
|
|
13348
|
+
"button",
|
|
13349
|
+
{
|
|
13350
|
+
onClick: () => onOutdent(group.id),
|
|
13351
|
+
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
13352
|
+
title: "Desaninhar"
|
|
13353
|
+
},
|
|
13354
|
+
/* @__PURE__ */ React28.createElement(FiArrowLeft3, { size: 14 })
|
|
13355
|
+
), /* @__PURE__ */ React28.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ React28.createElement(
|
|
13356
|
+
"button",
|
|
13357
|
+
{
|
|
13358
|
+
onClick: () => onDelete(group.id),
|
|
13359
|
+
className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
|
|
13360
|
+
title: "Remover Grupo"
|
|
13361
|
+
},
|
|
13362
|
+
/* @__PURE__ */ React28.createElement(FiTrash23, { size: 14 })
|
|
13363
|
+
)))), group.children && group.children.length > 0 && /* @__PURE__ */ React28.createElement("div", { className: "ml-2" }, group.children.map((child, idx) => /* @__PURE__ */ React28.createElement(
|
|
13119
13364
|
GroupItem,
|
|
13120
13365
|
{
|
|
13121
|
-
key:
|
|
13366
|
+
key: child.id,
|
|
13122
13367
|
index: idx,
|
|
13123
|
-
group:
|
|
13124
|
-
siblings: group.children,
|
|
13368
|
+
group: child,
|
|
13125
13369
|
onUpdate,
|
|
13126
13370
|
onDelete,
|
|
13127
13371
|
onAddSubgroup,
|
|
13128
13372
|
onIndent,
|
|
13129
13373
|
onOutdent,
|
|
13130
|
-
|
|
13131
|
-
|
|
13132
|
-
pickingGroupId,
|
|
13133
|
-
onPlayAncestry,
|
|
13134
|
-
availableIds,
|
|
13374
|
+
searchItems,
|
|
13375
|
+
onMentionClick,
|
|
13135
13376
|
canEdit
|
|
13136
13377
|
}
|
|
13137
13378
|
))));
|
|
@@ -13145,40 +13386,32 @@ function AncestryBoard({
|
|
|
13145
13386
|
initialGroups = [],
|
|
13146
13387
|
onSave,
|
|
13147
13388
|
userRole
|
|
13148
|
-
// [NOVO] Recebe a role do usuário
|
|
13149
13389
|
}) {
|
|
13150
|
-
const [searchTerm, setSearchTerm] =
|
|
13151
|
-
const [groups, setGroups] =
|
|
13152
|
-
const [isLoaded, setIsLoaded] =
|
|
13153
|
-
const [
|
|
13154
|
-
const
|
|
13155
|
-
|
|
13156
|
-
return userRole !== "viewer";
|
|
13157
|
-
}, [userRole]);
|
|
13158
|
-
useEffect21(() => {
|
|
13390
|
+
const [searchTerm, setSearchTerm] = useState27("");
|
|
13391
|
+
const [groups, setGroups] = useState27([]);
|
|
13392
|
+
const [isLoaded, setIsLoaded] = useState27(false);
|
|
13393
|
+
const [saveStatus, setSaveStatus] = useState27("idle");
|
|
13394
|
+
const canEdit = useMemo12(() => userRole !== "viewer", [userRole]);
|
|
13395
|
+
useEffect23(() => {
|
|
13159
13396
|
if (initialGroups && !isLoaded) {
|
|
13160
|
-
|
|
13397
|
+
const migrate = (list) => list.map((g) => ({
|
|
13398
|
+
id: g.id || uuidv411(),
|
|
13399
|
+
content: Array.isArray(g.content) ? g.content : [],
|
|
13400
|
+
// descarta dados legados
|
|
13401
|
+
children: migrate(g.children || [])
|
|
13402
|
+
}));
|
|
13403
|
+
setGroups(migrate(initialGroups));
|
|
13161
13404
|
setIsLoaded(true);
|
|
13162
13405
|
}
|
|
13163
13406
|
}, [initialGroups, isLoaded]);
|
|
13164
|
-
const nodeNamesMap =
|
|
13407
|
+
const nodeNamesMap = useMemo12(() => {
|
|
13165
13408
|
const map = /* @__PURE__ */ new Map();
|
|
13166
|
-
|
|
13167
|
-
|
|
13168
|
-
|
|
13169
|
-
map.set(String(node.id), node.name);
|
|
13170
|
-
}
|
|
13171
|
-
});
|
|
13172
|
-
}
|
|
13409
|
+
availableNodes.forEach((n) => {
|
|
13410
|
+
if (n == null ? void 0 : n.id) map.set(String(n.id), n.name);
|
|
13411
|
+
});
|
|
13173
13412
|
return map;
|
|
13174
13413
|
}, [availableNodes]);
|
|
13175
|
-
const
|
|
13176
|
-
const ids = /* @__PURE__ */ new Set();
|
|
13177
|
-
availableAncestries.forEach((a) => ids.add(String(a.ancestry_id)));
|
|
13178
|
-
availableNodes.forEach((n) => ids.add(String(n.id)));
|
|
13179
|
-
return ids;
|
|
13180
|
-
}, [availableAncestries, availableNodes]);
|
|
13181
|
-
const allSearchableItems = useMemo11(() => {
|
|
13414
|
+
const allSearchableItems = useMemo12(() => {
|
|
13182
13415
|
const items = [];
|
|
13183
13416
|
availableAncestries.forEach((anc) => {
|
|
13184
13417
|
items.push({
|
|
@@ -13204,117 +13437,76 @@ function AncestryBoard({
|
|
|
13204
13437
|
});
|
|
13205
13438
|
return items;
|
|
13206
13439
|
}, [availableAncestries, availableNodes]);
|
|
13207
|
-
const
|
|
13208
|
-
|
|
13209
|
-
|
|
13210
|
-
|
|
13211
|
-
|
|
13212
|
-
|
|
13213
|
-
|
|
13214
|
-
|
|
13215
|
-
|
|
13216
|
-
|
|
13217
|
-
|
|
13218
|
-
|
|
13219
|
-
|
|
13220
|
-
|
|
13440
|
+
const filtered = useMemo12(() => {
|
|
13441
|
+
const term = searchTerm.toLowerCase().trim();
|
|
13442
|
+
return allSearchableItems.filter((item) => {
|
|
13443
|
+
if (!term) return true;
|
|
13444
|
+
const labelMatch = (item.searchLabel || "").toLowerCase().includes(term);
|
|
13445
|
+
const descMatch = (item.searchDesc || "").toLowerCase().includes(term);
|
|
13446
|
+
let parentMatch = false;
|
|
13447
|
+
if (item.type === "ancestry") {
|
|
13448
|
+
const parentName = nodeNamesMap.get(String(item.ancestral_node)) || "";
|
|
13449
|
+
parentMatch = parentName.toLowerCase().includes(term);
|
|
13450
|
+
}
|
|
13451
|
+
return labelMatch || descMatch || parentMatch;
|
|
13452
|
+
});
|
|
13453
|
+
}, [allSearchableItems, searchTerm, nodeNamesMap]);
|
|
13454
|
+
const sanitizeGroups = (list) => list.map((g) => ({
|
|
13455
|
+
id: g.id,
|
|
13456
|
+
content: g.content || [],
|
|
13457
|
+
children: sanitizeGroups(g.children || [])
|
|
13458
|
+
}));
|
|
13459
|
+
useEffect23(() => {
|
|
13221
13460
|
if (!isLoaded || !onSave) return;
|
|
13222
|
-
const
|
|
13461
|
+
const id = setTimeout(async () => {
|
|
13223
13462
|
setSaveStatus("saving");
|
|
13224
|
-
const cleanData = sanitizeGroups(groups);
|
|
13225
13463
|
try {
|
|
13226
|
-
await onSave(
|
|
13464
|
+
await onSave(sanitizeGroups(groups));
|
|
13227
13465
|
setSaveStatus("saved");
|
|
13228
|
-
setTimeout(() =>
|
|
13229
|
-
|
|
13230
|
-
|
|
13231
|
-
} catch (error) {
|
|
13232
|
-
console.error("Erro ao salvar board:", error);
|
|
13466
|
+
setTimeout(() => setSaveStatus("idle"), 3e3);
|
|
13467
|
+
} catch (err) {
|
|
13468
|
+
console.error("Erro ao salvar board:", err);
|
|
13233
13469
|
setSaveStatus("error");
|
|
13234
13470
|
}
|
|
13235
13471
|
}, 3e3);
|
|
13236
|
-
return () => clearTimeout(
|
|
13472
|
+
return () => clearTimeout(id);
|
|
13237
13473
|
}, [groups, isLoaded, onSave]);
|
|
13238
|
-
|
|
13474
|
+
useEffect23(() => {
|
|
13239
13475
|
if (!isOpen) return;
|
|
13240
|
-
const
|
|
13476
|
+
const handler = (e) => {
|
|
13241
13477
|
if (e.key === "Escape") {
|
|
13242
|
-
|
|
13243
|
-
setPickingGroupId(null);
|
|
13244
|
-
} else {
|
|
13245
|
-
onClose();
|
|
13246
|
-
}
|
|
13478
|
+
onClose();
|
|
13247
13479
|
e.preventDefault();
|
|
13248
13480
|
e.stopPropagation();
|
|
13249
13481
|
}
|
|
13250
13482
|
};
|
|
13251
|
-
window.addEventListener("keydown",
|
|
13252
|
-
return () => window.removeEventListener("keydown",
|
|
13253
|
-
}, [isOpen, onClose
|
|
13254
|
-
const filtered = useMemo11(() => {
|
|
13255
|
-
const term = searchTerm.toLowerCase().trim();
|
|
13256
|
-
return allSearchableItems.filter((item) => {
|
|
13257
|
-
var _a, _b;
|
|
13258
|
-
if (!term) return true;
|
|
13259
|
-
const labelMatch = (_a = item.searchLabel) == null ? void 0 : _a.toLowerCase().includes(term);
|
|
13260
|
-
const descMatch = (_b = item.searchDesc) == null ? void 0 : _b.toLowerCase().includes(term);
|
|
13261
|
-
let parentMatch = false;
|
|
13262
|
-
if (item.type === "ancestry") {
|
|
13263
|
-
const parentName = nodeNamesMap.get(String(item.ancestral_node)) || "";
|
|
13264
|
-
parentMatch = parentName.toLowerCase().includes(term);
|
|
13265
|
-
}
|
|
13266
|
-
return labelMatch || descMatch || parentMatch;
|
|
13267
|
-
});
|
|
13268
|
-
}, [allSearchableItems, searchTerm, nodeNamesMap]);
|
|
13483
|
+
window.addEventListener("keydown", handler);
|
|
13484
|
+
return () => window.removeEventListener("keydown", handler);
|
|
13485
|
+
}, [isOpen, onClose]);
|
|
13269
13486
|
const handleAddRootGroup = () => {
|
|
13270
|
-
|
|
13271
|
-
id: uuidv411(),
|
|
13272
|
-
text: "",
|
|
13273
|
-
ancestries: [],
|
|
13274
|
-
children: []
|
|
13275
|
-
};
|
|
13276
|
-
setGroups((prev) => [newGroup, ...prev]);
|
|
13487
|
+
setGroups((prev) => [{ id: uuidv411(), content: [], children: [] }, ...prev]);
|
|
13277
13488
|
};
|
|
13278
13489
|
const handleAddSubgroup = (parentId) => {
|
|
13279
|
-
const newGroup = {
|
|
13280
|
-
|
|
13281
|
-
|
|
13282
|
-
|
|
13283
|
-
|
|
13284
|
-
};
|
|
13285
|
-
const addRecursive = (list) => {
|
|
13286
|
-
return list.map((g) => {
|
|
13287
|
-
if (g.id === parentId) {
|
|
13288
|
-
return { ...g, children: [newGroup, ...g.children] };
|
|
13289
|
-
}
|
|
13290
|
-
return { ...g, children: addRecursive(g.children) };
|
|
13291
|
-
});
|
|
13292
|
-
};
|
|
13293
|
-
setGroups((prev) => addRecursive(prev));
|
|
13490
|
+
const newGroup = { id: uuidv411(), content: [], children: [] };
|
|
13491
|
+
const add = (list) => list.map(
|
|
13492
|
+
(g) => g.id === parentId ? { ...g, children: [newGroup, ...g.children] } : { ...g, children: add(g.children) }
|
|
13493
|
+
);
|
|
13494
|
+
setGroups((prev) => add(prev));
|
|
13294
13495
|
};
|
|
13295
13496
|
const handleUpdateGroup = (id, newData) => {
|
|
13296
|
-
const
|
|
13297
|
-
|
|
13298
|
-
|
|
13299
|
-
|
|
13300
|
-
});
|
|
13301
|
-
};
|
|
13302
|
-
setGroups((prev) => updateRecursive(prev));
|
|
13497
|
+
const update = (list) => list.map(
|
|
13498
|
+
(g) => g.id === id ? newData : { ...g, children: update(g.children) }
|
|
13499
|
+
);
|
|
13500
|
+
setGroups((prev) => update(prev));
|
|
13303
13501
|
};
|
|
13304
13502
|
const handleDeleteGroup = (id) => {
|
|
13305
|
-
const
|
|
13306
|
-
|
|
13307
|
-
...g,
|
|
13308
|
-
children: deleteRecursive(g.children)
|
|
13309
|
-
}));
|
|
13310
|
-
};
|
|
13311
|
-
setGroups((prev) => deleteRecursive(prev));
|
|
13503
|
+
const del = (list) => list.filter((g) => g.id !== id).map((g) => ({ ...g, children: del(g.children) }));
|
|
13504
|
+
setGroups((prev) => del(prev));
|
|
13312
13505
|
};
|
|
13313
13506
|
const findGroupAndParent = (list, targetId, parent = null) => {
|
|
13314
13507
|
for (let i = 0; i < list.length; i++) {
|
|
13315
|
-
if (list[i].id === targetId)
|
|
13508
|
+
if (list[i].id === targetId)
|
|
13316
13509
|
return { group: list[i], parent, index: i, siblings: list };
|
|
13317
|
-
}
|
|
13318
13510
|
if (list[i].children.length > 0) {
|
|
13319
13511
|
const found = findGroupAndParent(list[i].children, targetId, list[i]);
|
|
13320
13512
|
if (found) return found;
|
|
@@ -13324,220 +13516,119 @@ function AncestryBoard({
|
|
|
13324
13516
|
};
|
|
13325
13517
|
const handleIndent = (id) => {
|
|
13326
13518
|
setGroups((prev) => {
|
|
13327
|
-
const
|
|
13328
|
-
const found = findGroupAndParent(
|
|
13519
|
+
const next = JSON.parse(JSON.stringify(prev));
|
|
13520
|
+
const found = findGroupAndParent(next, id);
|
|
13329
13521
|
if (!found || found.index === 0) return prev;
|
|
13330
13522
|
const { group, siblings, index } = found;
|
|
13331
|
-
const prevSibling = siblings[index - 1];
|
|
13332
13523
|
siblings.splice(index, 1);
|
|
13333
|
-
|
|
13334
|
-
return
|
|
13524
|
+
siblings[index - 1].children.push(group);
|
|
13525
|
+
return next;
|
|
13335
13526
|
});
|
|
13336
13527
|
};
|
|
13337
13528
|
const handleOutdent = (id) => {
|
|
13338
13529
|
setGroups((prev) => {
|
|
13339
|
-
const
|
|
13340
|
-
const found = findGroupAndParent(
|
|
13530
|
+
const next = JSON.parse(JSON.stringify(prev));
|
|
13531
|
+
const found = findGroupAndParent(next, id);
|
|
13341
13532
|
if (!found || !found.parent) return prev;
|
|
13342
13533
|
const { group, siblings, index, parent } = found;
|
|
13343
13534
|
siblings.splice(index, 1);
|
|
13344
|
-
const parentFound = findGroupAndParent(
|
|
13535
|
+
const parentFound = findGroupAndParent(next, parent.id);
|
|
13345
13536
|
if (parentFound) {
|
|
13346
13537
|
parentFound.siblings.splice(parentFound.index + 1, 0, group);
|
|
13347
13538
|
} else {
|
|
13348
|
-
|
|
13539
|
+
next.push(group);
|
|
13349
13540
|
}
|
|
13350
|
-
return
|
|
13541
|
+
return next;
|
|
13351
13542
|
});
|
|
13352
13543
|
};
|
|
13353
|
-
const
|
|
13354
|
-
|
|
13355
|
-
};
|
|
13356
|
-
const handleSelectAncestry = (ancestry) => {
|
|
13357
|
-
if (pickingGroupId) {
|
|
13358
|
-
setGroups((prev) => {
|
|
13359
|
-
const addRecursive = (list) => {
|
|
13360
|
-
return list.map((g) => {
|
|
13361
|
-
if (g.id === pickingGroupId) {
|
|
13362
|
-
const exists = g.ancestries.some(
|
|
13363
|
-
(a) => String(a.id || a.ancestry_id) === String(ancestry.id)
|
|
13364
|
-
);
|
|
13365
|
-
if (exists) return g;
|
|
13366
|
-
return {
|
|
13367
|
-
...g,
|
|
13368
|
-
ancestries: [
|
|
13369
|
-
...g.ancestries,
|
|
13370
|
-
{
|
|
13371
|
-
id: ancestry.id,
|
|
13372
|
-
ancestry_id: ancestry.id,
|
|
13373
|
-
name: ancestry.searchLabel,
|
|
13374
|
-
type: ancestry.type
|
|
13375
|
-
}
|
|
13376
|
-
]
|
|
13377
|
-
};
|
|
13378
|
-
}
|
|
13379
|
-
return { ...g, children: addRecursive(g.children) };
|
|
13380
|
-
});
|
|
13381
|
-
};
|
|
13382
|
-
return addRecursive(prev);
|
|
13383
|
-
});
|
|
13384
|
-
onSelect(ancestry);
|
|
13385
|
-
}
|
|
13386
|
-
};
|
|
13387
|
-
const handlePlayFromGroup = (ancestry) => {
|
|
13388
|
-
if (ancestry && onSelect) {
|
|
13389
|
-
onSelect(ancestry);
|
|
13390
|
-
}
|
|
13391
|
-
};
|
|
13392
|
-
const handleRemoveAncestryFromGroup = (groupId, ancestryId) => {
|
|
13393
|
-
setGroups((prev) => {
|
|
13394
|
-
const removeRecursive = (list) => {
|
|
13395
|
-
return list.map((g) => {
|
|
13396
|
-
if (g.id === groupId) {
|
|
13397
|
-
return {
|
|
13398
|
-
...g,
|
|
13399
|
-
ancestries: g.ancestries.filter(
|
|
13400
|
-
(a) => String(a.id || a.ancestry_id) !== String(ancestryId)
|
|
13401
|
-
)
|
|
13402
|
-
};
|
|
13403
|
-
}
|
|
13404
|
-
return { ...g, children: removeRecursive(g.children) };
|
|
13405
|
-
});
|
|
13406
|
-
};
|
|
13407
|
-
return removeRecursive(prev);
|
|
13408
|
-
});
|
|
13544
|
+
const handleMentionClick = (item) => {
|
|
13545
|
+
if (onSelect) onSelect(item);
|
|
13409
13546
|
};
|
|
13410
13547
|
if (!isOpen) return null;
|
|
13411
|
-
return /* @__PURE__ */
|
|
13548
|
+
return /* @__PURE__ */ React28.createElement(
|
|
13412
13549
|
"div",
|
|
13413
13550
|
{
|
|
13414
13551
|
className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
|
|
13415
13552
|
onClick: onClose
|
|
13416
13553
|
},
|
|
13417
|
-
/* @__PURE__ */
|
|
13554
|
+
/* @__PURE__ */ React28.createElement(
|
|
13418
13555
|
"div",
|
|
13419
13556
|
{
|
|
13420
13557
|
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",
|
|
13421
13558
|
onClick: (e) => e.stopPropagation()
|
|
13422
13559
|
},
|
|
13423
|
-
/* @__PURE__ */
|
|
13424
|
-
FiLoader5,
|
|
13425
|
-
{
|
|
13426
|
-
className: "animate-spin text-indigo-400",
|
|
13427
|
-
size: 12
|
|
13428
|
-
}
|
|
13429
|
-
), /* @__PURE__ */ React26.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ React26.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ React26.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ React26.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ React26.createElement(
|
|
13560
|
+
/* @__PURE__ */ React28.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React28.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ React28.createElement(FiLayers7, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React28.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ React28.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__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(FiLoader5, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ React28.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ React28.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ React28.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-3" }, canEdit && /* @__PURE__ */ React28.createElement(
|
|
13430
13561
|
"button",
|
|
13431
13562
|
{
|
|
13432
13563
|
onClick: handleAddRootGroup,
|
|
13433
|
-
className: "
|
|
13564
|
+
className: "flex items-center gap-2 px-3 py-1.5 bg-white/5 hover:bg-white/10 border border-white/10 hover:border-white/20 backdrop-blur-sm text-slate-200 hover:text-white rounded-md transition-all duration-200 text-xs font-medium shadow-sm"
|
|
13434
13565
|
},
|
|
13435
|
-
/* @__PURE__ */
|
|
13436
|
-
/* @__PURE__ */
|
|
13437
|
-
), /* @__PURE__ */
|
|
13566
|
+
/* @__PURE__ */ React28.createElement(FiPlus10, { size: 14, className: "text-indigo-400" }),
|
|
13567
|
+
/* @__PURE__ */ React28.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
|
|
13568
|
+
), /* @__PURE__ */ React28.createElement(
|
|
13438
13569
|
"button",
|
|
13439
13570
|
{
|
|
13440
13571
|
onClick: onClose,
|
|
13441
13572
|
className: "w-8 h-8 rounded-lg flex items-center justify-center text-slate-400 hover:text-white hover:bg-white/10 transition-colors"
|
|
13442
13573
|
},
|
|
13443
|
-
|
|
13574
|
+
/* @__PURE__ */ React28.createElement(FiX8, { size: 16 })
|
|
13444
13575
|
))),
|
|
13445
|
-
/* @__PURE__ */
|
|
13446
|
-
"
|
|
13576
|
+
/* @__PURE__ */ React28.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col border-r border-white/10 w-[20%] min-w-[280px] max-w-[460px] bg-slate-900 flex-none" }, /* @__PURE__ */ React28.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ React28.createElement("div", { className: "relative group" }, /* @__PURE__ */ React28.createElement(FiSearch8, { className: "absolute left-3 top-1/2 -translate-y-1/2 text-slate-500 group-focus-within:text-indigo-400 transition-colors" }), /* @__PURE__ */ React28.createElement(
|
|
13577
|
+
"input",
|
|
13447
13578
|
{
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13460
|
-
"input",
|
|
13579
|
+
type: "text",
|
|
13580
|
+
placeholder: "Navegar nas ancestralidades e nodes\u2026",
|
|
13581
|
+
className: "w-full rounded-md pl-9 pr-4 py-2 text-sm bg-slate-950 border border-white/10 text-slate-200 placeholder-slate-600 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-all",
|
|
13582
|
+
value: searchTerm,
|
|
13583
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
|
13584
|
+
autoFocus: true
|
|
13585
|
+
}
|
|
13586
|
+
))), /* @__PURE__ */ React28.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
|
|
13587
|
+
const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
|
|
13588
|
+
return /* @__PURE__ */ React28.createElement(
|
|
13589
|
+
"div",
|
|
13461
13590
|
{
|
|
13462
|
-
|
|
13463
|
-
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
onChange: (e) => setSearchTerm(e.target.value),
|
|
13470
|
-
autoFocus: !pickingGroupId
|
|
13471
|
-
}
|
|
13472
|
-
))),
|
|
13473
|
-
/* @__PURE__ */ React26.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
|
|
13474
|
-
const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
|
|
13475
|
-
const isPicking = !!pickingGroupId;
|
|
13476
|
-
return /* @__PURE__ */ React26.createElement(
|
|
13477
|
-
"div",
|
|
13591
|
+
key: anc.id,
|
|
13592
|
+
className: "group relative flex items-start gap-3 p-3 text-left rounded-lg border border-white/5 bg-slate-800/40 hover:bg-indigo-600/10 hover:border-indigo-500/30 cursor-default transition-all duration-200"
|
|
13593
|
+
},
|
|
13594
|
+
/* @__PURE__ */ React28.createElement("div", { className: "mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border bg-slate-800 border-white/5 group-hover:bg-indigo-500 group-hover:text-white transition-all shadow-lg" }, anc.type === "quest" ? /* @__PURE__ */ React28.createElement(FiCheckSquare4, { size: 14, className: "text-emerald-400 group-hover:text-white" }) : anc.type === "version" ? /* @__PURE__ */ React28.createElement(FiGitBranch4, { size: 14, className: "text-amber-400 group-hover:text-white" }) : anc.type === "node" ? /* @__PURE__ */ React28.createElement(FiBox2, { size: 14, className: "text-slate-400 group-hover:text-white" }) : /* @__PURE__ */ React28.createElement(FiLayers7, { size: 14, className: "text-indigo-400 group-hover:text-white" })),
|
|
13595
|
+
/* @__PURE__ */ React28.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ React28.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React28.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.searchLabel || "Sem Nome"), /* @__PURE__ */ React28.createElement("span", { className: "text-[9px] px-1.5 py-0.5 rounded-full bg-white/5 text-slate-500 border border-white/5 uppercase tracking-tighter" }, anc.type)), anc.type === "ancestry" && /* @__PURE__ */ React28.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__ */ React28.createElement(FiCornerUpRight4, { size: 10 }), /* @__PURE__ */ React28.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.searchDesc && /* @__PURE__ */ React28.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.searchDesc)),
|
|
13596
|
+
/* @__PURE__ */ React28.createElement(
|
|
13597
|
+
"button",
|
|
13478
13598
|
{
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
if (
|
|
13599
|
+
onClick: (e) => {
|
|
13600
|
+
e.stopPropagation();
|
|
13601
|
+
if (onSelect) onSelect(anc);
|
|
13482
13602
|
},
|
|
13483
|
-
className:
|
|
13484
|
-
|
|
13485
|
-
${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"}
|
|
13486
|
-
`
|
|
13603
|
+
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",
|
|
13604
|
+
title: "Focar no cen\xE1rio"
|
|
13487
13605
|
},
|
|
13488
|
-
/* @__PURE__ */
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
|
|
13493
|
-
${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"}
|
|
13494
|
-
${anc.type === "quest" ? "text-emerald-400" : anc.type === "version" ? "text-amber-400" : anc.type === "node" ? "text-slate-400" : "text-indigo-400"}
|
|
13495
|
-
`
|
|
13496
|
-
},
|
|
13497
|
-
isPicking ? /* @__PURE__ */ React26.createElement(FiPlus10, { size: 16 }) : anc.type === "quest" ? /* @__PURE__ */ React26.createElement(FiCheckSquare3, { size: 14 }) : anc.type === "version" ? /* @__PURE__ */ React26.createElement(FiGitBranch3, { size: 14 }) : anc.type === "node" ? /* @__PURE__ */ React26.createElement(FiBox, { size: 14 }) : /* @__PURE__ */ React26.createElement(FiLayers6, { size: 14 })
|
|
13498
|
-
),
|
|
13499
|
-
/* @__PURE__ */ React26.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ React26.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React26.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.searchLabel || "Sem Nome"), /* @__PURE__ */ React26.createElement("span", { className: "text-[9px] px-1.5 py-0.5 rounded-full bg-white/5 text-slate-500 border border-white/5 uppercase tracking-tighter" }, anc.type)), anc.type === "ancestry" && /* @__PURE__ */ React26.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__ */ React26.createElement(FiCornerUpRight4, { size: 10 }), /* @__PURE__ */ React26.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.searchDesc && /* @__PURE__ */ React26.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.searchDesc)),
|
|
13500
|
-
!isPicking && /* @__PURE__ */ React26.createElement(
|
|
13501
|
-
"button",
|
|
13502
|
-
{
|
|
13503
|
-
onClick: (e) => {
|
|
13504
|
-
e.stopPropagation();
|
|
13505
|
-
handleSelectAncestry(anc);
|
|
13506
|
-
},
|
|
13507
|
-
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",
|
|
13508
|
-
title: "Focar no cen\xE1rio"
|
|
13509
|
-
},
|
|
13510
|
-
/* @__PURE__ */ React26.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ React26.createElement(FiPlay, { size: 14, className: "ml-0.5" }))
|
|
13511
|
-
)
|
|
13512
|
-
);
|
|
13513
|
-
}))
|
|
13514
|
-
), /* @__PURE__ */ React26.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ React26.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ React26.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__ */ React26.createElement(FiLayers6, { size: 24, className: "opacity-20" }), /* @__PURE__ */ React26.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ React26.createElement(React26.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ React26.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ React26.createElement(React26.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ React26.createElement(
|
|
13606
|
+
/* @__PURE__ */ React28.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ React28.createElement(FiPlay, { size: 14, className: "ml-0.5" }))
|
|
13607
|
+
)
|
|
13608
|
+
);
|
|
13609
|
+
}))), /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ React28.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ React28.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__ */ React28.createElement(FiLayers7, { size: 24, className: "opacity-20" }), /* @__PURE__ */ React28.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ React28.createElement(React28.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ React28.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ React28.createElement(React28.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ React28.createElement(
|
|
13515
13610
|
GroupItem,
|
|
13516
13611
|
{
|
|
13517
13612
|
key: group.id,
|
|
13518
13613
|
index,
|
|
13519
13614
|
group,
|
|
13520
|
-
siblings: groups,
|
|
13521
13615
|
onUpdate: handleUpdateGroup,
|
|
13522
13616
|
onDelete: handleDeleteGroup,
|
|
13523
13617
|
onAddSubgroup: handleAddSubgroup,
|
|
13524
13618
|
onIndent: handleIndent,
|
|
13525
13619
|
onOutdent: handleOutdent,
|
|
13526
|
-
|
|
13527
|
-
|
|
13528
|
-
pickingGroupId,
|
|
13529
|
-
onPlayAncestry: handlePlayFromGroup,
|
|
13530
|
-
availableIds,
|
|
13620
|
+
searchItems: allSearchableItems,
|
|
13621
|
+
onMentionClick: handleMentionClick,
|
|
13531
13622
|
canEdit
|
|
13532
13623
|
}
|
|
13533
13624
|
))))),
|
|
13534
|
-
/* @__PURE__ */
|
|
13625
|
+
/* @__PURE__ */ React28.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__ */ React28.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ React28.createElement("span", null, groups.length, " grupos raiz"))
|
|
13535
13626
|
)
|
|
13536
13627
|
);
|
|
13537
13628
|
}
|
|
13538
13629
|
|
|
13539
13630
|
// src/components/MilestoneManager.jsx
|
|
13540
|
-
import
|
|
13631
|
+
import React29, { useState as useState28 } from "react";
|
|
13541
13632
|
import { FiTarget as FiTarget4, FiPlus as FiPlus11, FiTrash2 as FiTrash24, FiX as FiX9, FiCheck as FiCheck12, FiPauseCircle, FiPlayCircle } from "react-icons/fi";
|
|
13542
13633
|
function MilestoneManager({
|
|
13543
13634
|
isOpen,
|
|
@@ -13546,7 +13637,7 @@ function MilestoneManager({
|
|
|
13546
13637
|
onUpdateMilestones = () => {
|
|
13547
13638
|
}
|
|
13548
13639
|
}) {
|
|
13549
|
-
const [newMilestoneName, setNewMilestoneName] =
|
|
13640
|
+
const [newMilestoneName, setNewMilestoneName] = useState28("");
|
|
13550
13641
|
const handleAddMilestone = () => {
|
|
13551
13642
|
if (!newMilestoneName.trim()) return;
|
|
13552
13643
|
const newMilestone = {
|
|
@@ -13571,27 +13662,27 @@ function MilestoneManager({
|
|
|
13571
13662
|
};
|
|
13572
13663
|
if (!isOpen) return null;
|
|
13573
13664
|
const swallow = (e) => e.stopPropagation();
|
|
13574
|
-
return /* @__PURE__ */
|
|
13665
|
+
return /* @__PURE__ */ React29.createElement(
|
|
13575
13666
|
"div",
|
|
13576
13667
|
{
|
|
13577
13668
|
className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-950/40 backdrop-blur-sm animate-in fade-in duration-300",
|
|
13578
13669
|
onClick: onClose
|
|
13579
13670
|
},
|
|
13580
|
-
/* @__PURE__ */
|
|
13671
|
+
/* @__PURE__ */ React29.createElement(
|
|
13581
13672
|
"div",
|
|
13582
13673
|
{
|
|
13583
13674
|
className: "w-full max-w-lg bg-slate-900/90 backdrop-blur-xl border border-white/10 rounded-2xl shadow-2xl flex flex-col max-h-[85vh] animate-in zoom-in-95 duration-300",
|
|
13584
13675
|
onClick: swallow
|
|
13585
13676
|
},
|
|
13586
|
-
/* @__PURE__ */
|
|
13677
|
+
/* @__PURE__ */ React29.createElement("div", { className: "px-6 py-4 border-b border-white/10 flex items-center justify-between" }, /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React29.createElement("div", { className: "p-2 rounded-lg bg-indigo-500/20 text-indigo-400" }, /* @__PURE__ */ React29.createElement(FiTarget4, { size: 20 })), /* @__PURE__ */ React29.createElement("div", null, /* @__PURE__ */ React29.createElement("h2", { className: "text-lg font-semibold text-slate-100" }, "Milestones"), /* @__PURE__ */ React29.createElement("p", { className: "text-xs text-slate-400" }, "Gerencie os marcos do seu cen\xE1rio"))), /* @__PURE__ */ React29.createElement(
|
|
13587
13678
|
"button",
|
|
13588
13679
|
{
|
|
13589
13680
|
onClick: onClose,
|
|
13590
13681
|
className: "p-2 rounded-full hover:bg-white/10 text-slate-400 hover:text-white transition-colors"
|
|
13591
13682
|
},
|
|
13592
|
-
/* @__PURE__ */
|
|
13683
|
+
/* @__PURE__ */ React29.createElement(FiX9, { size: 20 })
|
|
13593
13684
|
)),
|
|
13594
|
-
/* @__PURE__ */
|
|
13685
|
+
/* @__PURE__ */ React29.createElement("div", { className: "px-6 py-5 bg-white/5 border-b border-white/5" }, /* @__PURE__ */ React29.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React29.createElement(
|
|
13595
13686
|
"input",
|
|
13596
13687
|
{
|
|
13597
13688
|
type: "text",
|
|
@@ -13601,47 +13692,47 @@ function MilestoneManager({
|
|
|
13601
13692
|
placeholder: "Adicionar novo milestone...",
|
|
13602
13693
|
className: "flex-1 bg-slate-800/50 border border-white/10 rounded-xl px-4 py-2.5 text-sm text-slate-100 placeholder:text-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/40 focus:border-indigo-500/50 transition-all shadow-inner"
|
|
13603
13694
|
}
|
|
13604
|
-
), /* @__PURE__ */
|
|
13695
|
+
), /* @__PURE__ */ React29.createElement(
|
|
13605
13696
|
"button",
|
|
13606
13697
|
{
|
|
13607
13698
|
onClick: handleAddMilestone,
|
|
13608
13699
|
disabled: !newMilestoneName.trim(),
|
|
13609
13700
|
className: "px-4 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 disabled:opacity-30 disabled:cursor-not-allowed text-white text-sm font-medium transition-all flex items-center gap-2 shadow-lg shadow-indigo-500/20 active:scale-95"
|
|
13610
13701
|
},
|
|
13611
|
-
/* @__PURE__ */
|
|
13702
|
+
/* @__PURE__ */ React29.createElement(FiPlus11, { size: 18 }),
|
|
13612
13703
|
"Adicionar"
|
|
13613
13704
|
))),
|
|
13614
|
-
/* @__PURE__ */
|
|
13705
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex-1 overflow-y-auto px-6 py-4 custom-scrollbar" }, milestones.length > 0 ? /* @__PURE__ */ React29.createElement("div", { className: "space-y-3" }, milestones.map((ms) => /* @__PURE__ */ React29.createElement(
|
|
13615
13706
|
"div",
|
|
13616
13707
|
{
|
|
13617
13708
|
key: ms.id,
|
|
13618
13709
|
className: `group flex items-center justify-between p-4 rounded-xl border transition-all duration-200 ${ms.status === "active" ? "bg-slate-800/40 border-indigo-500/20 hover:border-indigo-500/40" : "bg-slate-900/40 border-white/5 opacity-60 grayscale-[0.3]"}`
|
|
13619
13710
|
},
|
|
13620
|
-
/* @__PURE__ */
|
|
13711
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ React29.createElement(
|
|
13621
13712
|
"div",
|
|
13622
13713
|
{
|
|
13623
13714
|
className: `w-2 h-2 rounded-full shrink-0 ${ms.status === "active" ? "bg-indigo-400 shadow-[0_0_8px_rgba(129,140,248,0.6)]" : "bg-slate-600"}`
|
|
13624
13715
|
}
|
|
13625
|
-
), /* @__PURE__ */
|
|
13626
|
-
/* @__PURE__ */
|
|
13716
|
+
), /* @__PURE__ */ React29.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ React29.createElement("span", { className: `text-sm font-medium truncate ${ms.status === "active" ? "text-slate-100" : "text-slate-400 line-through"}` }, ms.name), /* @__PURE__ */ React29.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-wider" }, ms.status === "active" ? "Ativo" : "Inativo"))),
|
|
13717
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React29.createElement(
|
|
13627
13718
|
"button",
|
|
13628
13719
|
{
|
|
13629
13720
|
onClick: () => handleToggleMilestoneStatus(ms.id),
|
|
13630
13721
|
className: `p-2 rounded-lg transition-all ${ms.status === "active" ? "hover:bg-slate-700 text-slate-400" : "hover:bg-indigo-500/20 text-indigo-400"}`,
|
|
13631
13722
|
title: ms.status === "active" ? "Inativar" : "Ativar"
|
|
13632
13723
|
},
|
|
13633
|
-
ms.status === "active" ? /* @__PURE__ */
|
|
13634
|
-
), /* @__PURE__ */
|
|
13724
|
+
ms.status === "active" ? /* @__PURE__ */ React29.createElement(FiPauseCircle, { size: 18 }) : /* @__PURE__ */ React29.createElement(FiPlayCircle, { size: 18 })
|
|
13725
|
+
), /* @__PURE__ */ React29.createElement(
|
|
13635
13726
|
"button",
|
|
13636
13727
|
{
|
|
13637
13728
|
onClick: () => handleRemoveMilestone(ms.id),
|
|
13638
13729
|
className: "p-2 rounded-lg hover:bg-red-500/20 text-slate-500 hover:text-red-400 transition-all",
|
|
13639
13730
|
title: "Remover"
|
|
13640
13731
|
},
|
|
13641
|
-
/* @__PURE__ */
|
|
13732
|
+
/* @__PURE__ */ React29.createElement(FiTrash24, { size: 18 })
|
|
13642
13733
|
))
|
|
13643
|
-
))) : /* @__PURE__ */
|
|
13644
|
-
/* @__PURE__ */
|
|
13734
|
+
))) : /* @__PURE__ */ React29.createElement("div", { className: "flex flex-col items-center justify-center py-12 text-center" }, /* @__PURE__ */ React29.createElement("div", { className: "p-4 rounded-full bg-slate-800/30 text-slate-600 mb-4" }, /* @__PURE__ */ React29.createElement(FiTarget4, { size: 40 })), /* @__PURE__ */ React29.createElement("h3", { className: "text-slate-400 font-medium" }, "Nenhum milestone definido"), /* @__PURE__ */ React29.createElement("p", { className: "text-xs text-slate-600 max-w-[200px] mt-1 italic" }, "Defina marcos importantes para orientar o progresso do projeto."))),
|
|
13735
|
+
/* @__PURE__ */ React29.createElement("div", { className: "px-6 py-4 border-t border-white/5 bg-slate-900/50 flex items-center justify-between rounded-b-2xl" }, /* @__PURE__ */ React29.createElement("div", { className: "flex gap-4" }, /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React29.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Total:"), /* @__PURE__ */ React29.createElement("span", { className: "text-xs font-bold text-slate-300" }, milestones.length)), /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React29.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Ativos:"), /* @__PURE__ */ React29.createElement("span", { className: "text-xs font-bold text-indigo-400" }, milestones.filter((m) => m.status === "active").length))))
|
|
13645
13736
|
)
|
|
13646
13737
|
);
|
|
13647
13738
|
}
|
|
@@ -13733,7 +13824,7 @@ function XViewScene({
|
|
|
13733
13824
|
const searchParams = useSearchParams();
|
|
13734
13825
|
const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
|
|
13735
13826
|
const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
|
|
13736
|
-
const viewParams =
|
|
13827
|
+
const viewParams = useMemo13(() => {
|
|
13737
13828
|
if (encryptedConfig) {
|
|
13738
13829
|
const data = decryptData(encryptedConfig);
|
|
13739
13830
|
if (data) {
|
|
@@ -13742,7 +13833,7 @@ function XViewScene({
|
|
|
13742
13833
|
}
|
|
13743
13834
|
return null;
|
|
13744
13835
|
}, [encryptedConfig, session]);
|
|
13745
|
-
|
|
13836
|
+
useEffect24(() => {
|
|
13746
13837
|
async function verifyPermission() {
|
|
13747
13838
|
if (!viewParams || !session || !check_user_permission) return;
|
|
13748
13839
|
const { id, type, owner_id } = viewParams;
|
|
@@ -13779,65 +13870,65 @@ function XViewScene({
|
|
|
13779
13870
|
setIsLoading(false);
|
|
13780
13871
|
}
|
|
13781
13872
|
}, [viewParams, session, status, check_user_permission]);
|
|
13782
|
-
const sceneConfigId =
|
|
13783
|
-
const ownerId =
|
|
13784
|
-
const dbSaveUrl =
|
|
13873
|
+
const sceneConfigId = useMemo13(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
|
|
13874
|
+
const ownerId = useMemo13(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
|
|
13875
|
+
const dbSaveUrl = useMemo13(() => {
|
|
13785
13876
|
if (ownerId && sceneConfigId) {
|
|
13786
13877
|
return `x_view_dbs/${ownerId}/${sceneConfigId}`;
|
|
13787
13878
|
}
|
|
13788
13879
|
return null;
|
|
13789
13880
|
}, [ownerId, sceneConfigId]);
|
|
13790
|
-
const sceneSaveUrl =
|
|
13881
|
+
const sceneSaveUrl = useMemo13(() => {
|
|
13791
13882
|
if (ownerId && sceneConfigId) {
|
|
13792
13883
|
return `x_view_scenes/${ownerId}/${sceneConfigId}`;
|
|
13793
13884
|
}
|
|
13794
13885
|
return null;
|
|
13795
13886
|
}, [ownerId, sceneConfigId]);
|
|
13796
|
-
const ancestry_save_url =
|
|
13887
|
+
const ancestry_save_url = useMemo13(() => {
|
|
13797
13888
|
if (ownerId && sceneConfigId) {
|
|
13798
13889
|
return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
|
|
13799
13890
|
}
|
|
13800
13891
|
return null;
|
|
13801
13892
|
}, [ownerId, sceneConfigId]);
|
|
13802
|
-
const sceneDataRef =
|
|
13803
|
-
const parentDataRef =
|
|
13804
|
-
const ancestryDataRef =
|
|
13805
|
-
const [isLoading, setIsLoading] =
|
|
13806
|
-
const [permissionStatus, setPermissionStatus] =
|
|
13807
|
-
const [userPermissionRole, setUserPermissionRole] =
|
|
13808
|
-
const [viewMembers, setViewMembers] =
|
|
13809
|
-
const [isInitialized, setIsInitialized] =
|
|
13810
|
-
const [sceneVersion, setSceneVersion] =
|
|
13811
|
-
const [contextMenu, setContextMenu] =
|
|
13893
|
+
const sceneDataRef = useRef20(null);
|
|
13894
|
+
const parentDataRef = useRef20(null);
|
|
13895
|
+
const ancestryDataRef = useRef20(null);
|
|
13896
|
+
const [isLoading, setIsLoading] = useState29(true);
|
|
13897
|
+
const [permissionStatus, setPermissionStatus] = useState29("loading");
|
|
13898
|
+
const [userPermissionRole, setUserPermissionRole] = useState29(null);
|
|
13899
|
+
const [viewMembers, setViewMembers] = useState29([]);
|
|
13900
|
+
const [isInitialized, setIsInitialized] = useState29(false);
|
|
13901
|
+
const [sceneVersion, setSceneVersion] = useState29(0);
|
|
13902
|
+
const [contextMenu, setContextMenu] = useState29({
|
|
13812
13903
|
visible: false,
|
|
13813
13904
|
x: 0,
|
|
13814
13905
|
y: 0,
|
|
13815
13906
|
nodeData: null
|
|
13816
13907
|
});
|
|
13817
|
-
const [multiContextMenu, setMultiContextMenu] =
|
|
13908
|
+
const [multiContextMenu, setMultiContextMenu] = useState29({
|
|
13818
13909
|
visible: false,
|
|
13819
13910
|
x: 0,
|
|
13820
13911
|
y: 0,
|
|
13821
13912
|
nodeIds: null
|
|
13822
13913
|
});
|
|
13823
|
-
const [relationshipMenu, setRelationshipMenu] =
|
|
13914
|
+
const [relationshipMenu, setRelationshipMenu] = useState29({
|
|
13824
13915
|
visible: false,
|
|
13825
13916
|
x: 0,
|
|
13826
13917
|
y: 0,
|
|
13827
13918
|
linkObject: null
|
|
13828
13919
|
});
|
|
13829
|
-
const [creationMode, setCreationMode] =
|
|
13920
|
+
const [creationMode, setCreationMode] = useState29({
|
|
13830
13921
|
isActive: false,
|
|
13831
13922
|
sourceNodeData: null
|
|
13832
13923
|
});
|
|
13833
|
-
const [versionMode, setVersionMode] =
|
|
13924
|
+
const [versionMode, setVersionMode] = useState29({
|
|
13834
13925
|
isActive: false,
|
|
13835
13926
|
sourceNodeData: null
|
|
13836
13927
|
});
|
|
13837
|
-
const [questMode, setQuestMode] =
|
|
13838
|
-
const [hasFocusedInitial, setHasFocusedInitial] =
|
|
13839
|
-
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] =
|
|
13840
|
-
const [ancestryMode, setAncestryMode] =
|
|
13928
|
+
const [questMode, setQuestMode] = useState29({ isActive: false });
|
|
13929
|
+
const [hasFocusedInitial, setHasFocusedInitial] = useState29(false);
|
|
13930
|
+
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState29(false);
|
|
13931
|
+
const [ancestryMode, setAncestryMode] = useState29({
|
|
13841
13932
|
isActive: false,
|
|
13842
13933
|
tree: null,
|
|
13843
13934
|
selectedParentId: null,
|
|
@@ -13848,42 +13939,42 @@ function XViewScene({
|
|
|
13848
13939
|
ancestryDescriptionSections: [],
|
|
13849
13940
|
isAddingNodes: false
|
|
13850
13941
|
});
|
|
13851
|
-
const [readingMode, setReadingMode] =
|
|
13942
|
+
const [readingMode, setReadingMode] = useState29({
|
|
13852
13943
|
isActive: false,
|
|
13853
13944
|
ancestry: null,
|
|
13854
13945
|
branchStack: [],
|
|
13855
13946
|
autoAbstraction: false
|
|
13856
13947
|
});
|
|
13857
|
-
const [formPosition, setFormPosition] =
|
|
13948
|
+
const [formPosition, setFormPosition] = useState29({
|
|
13858
13949
|
left: 16,
|
|
13859
13950
|
top: 16,
|
|
13860
13951
|
opacity: 0
|
|
13861
13952
|
});
|
|
13862
|
-
const [detailsNode, setDetailsNode] =
|
|
13863
|
-
const [detailsLink, setDetailsLink] =
|
|
13864
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] =
|
|
13865
|
-
const [imageViewer, setImageViewer] =
|
|
13953
|
+
const [detailsNode, setDetailsNode] = useState29(null);
|
|
13954
|
+
const [detailsLink, setDetailsLink] = useState29(null);
|
|
13955
|
+
const [ancestryLinkDetails, setAncestryLinkDetails] = useState29(null);
|
|
13956
|
+
const [imageViewer, setImageViewer] = useState29({
|
|
13866
13957
|
visible: false,
|
|
13867
13958
|
images: [],
|
|
13868
13959
|
startIndex: 0
|
|
13869
13960
|
});
|
|
13870
|
-
const [editingAncestryRel, setEditingAncestryRel] =
|
|
13961
|
+
const [editingAncestryRel, setEditingAncestryRel] = useState29({
|
|
13871
13962
|
visible: false,
|
|
13872
13963
|
data: null,
|
|
13873
13964
|
path: null
|
|
13874
13965
|
});
|
|
13875
|
-
const [isImportModalOpen, setIsImportModalOpen] =
|
|
13876
|
-
const [importSuccessMessage, setImportSuccessMessage] =
|
|
13877
|
-
const [invalidTargetError, setInvalidTargetError] =
|
|
13878
|
-
const [highlightedNodeId, setHighlightedNodeId] =
|
|
13879
|
-
const [isAncestryBoardOpen, setIsAncestryBoardOpen] =
|
|
13880
|
-
const [ancestryBoardData, setAncestryBoardData] =
|
|
13881
|
-
const [isSidebarOpen, setIsSidebarOpen] =
|
|
13882
|
-
const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] =
|
|
13883
|
-
const mountRef =
|
|
13884
|
-
const tooltipRef =
|
|
13885
|
-
const formRef =
|
|
13886
|
-
const stateRef =
|
|
13966
|
+
const [isImportModalOpen, setIsImportModalOpen] = useState29(false);
|
|
13967
|
+
const [importSuccessMessage, setImportSuccessMessage] = useState29("");
|
|
13968
|
+
const [invalidTargetError, setInvalidTargetError] = useState29(null);
|
|
13969
|
+
const [highlightedNodeId, setHighlightedNodeId] = useState29(null);
|
|
13970
|
+
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState29(false);
|
|
13971
|
+
const [ancestryBoardData, setAncestryBoardData] = useState29([]);
|
|
13972
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState29(false);
|
|
13973
|
+
const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = useState29(false);
|
|
13974
|
+
const mountRef = useRef20(null);
|
|
13975
|
+
const tooltipRef = useRef20(null);
|
|
13976
|
+
const formRef = useRef20(null);
|
|
13977
|
+
const stateRef = useRef20({
|
|
13887
13978
|
readMode: {
|
|
13888
13979
|
currentMaxIndex: 0,
|
|
13889
13980
|
progressMap: {}
|
|
@@ -13947,10 +14038,10 @@ function XViewScene({
|
|
|
13947
14038
|
minWidth: 320,
|
|
13948
14039
|
maxWidth: maxReadPanelW
|
|
13949
14040
|
});
|
|
13950
|
-
|
|
14041
|
+
useEffect24(() => {
|
|
13951
14042
|
stateRef.current.ancestry = ancestryMode;
|
|
13952
14043
|
}, [ancestryMode]);
|
|
13953
|
-
|
|
14044
|
+
useEffect24(() => {
|
|
13954
14045
|
var _a2;
|
|
13955
14046
|
if (!isInitialized) return;
|
|
13956
14047
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -13973,10 +14064,10 @@ function XViewScene({
|
|
|
13973
14064
|
}
|
|
13974
14065
|
stateRef.current.nodeIdToParentFileMap = map;
|
|
13975
14066
|
}, [isInitialized, sceneVersion]);
|
|
13976
|
-
const handleNavigateBack =
|
|
14067
|
+
const handleNavigateBack = useCallback5(() => {
|
|
13977
14068
|
router.push("/dashboard/scenes");
|
|
13978
14069
|
}, [router]);
|
|
13979
|
-
const handleConfirmImport =
|
|
14070
|
+
const handleConfirmImport = useCallback5(
|
|
13980
14071
|
async (importPayload) => {
|
|
13981
14072
|
var _a2, _b2;
|
|
13982
14073
|
let files = [];
|
|
@@ -14104,7 +14195,7 @@ function XViewScene({
|
|
|
14104
14195
|
const handleOpenImageViewer = (images, startIndex) => {
|
|
14105
14196
|
setImageViewer({ visible: true, images, startIndex });
|
|
14106
14197
|
};
|
|
14107
|
-
const tweenToTarget =
|
|
14198
|
+
const tweenToTarget = useCallback5(
|
|
14108
14199
|
(target, zoomFactor = 1, forcedDirection = null) => {
|
|
14109
14200
|
const { camera, controls, tweenGroup } = stateRef.current;
|
|
14110
14201
|
if (!camera || !controls || !tweenGroup) return;
|
|
@@ -14130,7 +14221,7 @@ function XViewScene({
|
|
|
14130
14221
|
if (!t || typeof t.closest !== "function") return false;
|
|
14131
14222
|
return !!t.closest(".ui-overlay");
|
|
14132
14223
|
};
|
|
14133
|
-
const buildFullAncestryTree =
|
|
14224
|
+
const buildFullAncestryTree = useCallback5(
|
|
14134
14225
|
(idTree, nodes, ancestries = []) => {
|
|
14135
14226
|
if (!idTree) return null;
|
|
14136
14227
|
const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
|
|
@@ -14215,7 +14306,7 @@ function XViewScene({
|
|
|
14215
14306
|
},
|
|
14216
14307
|
[]
|
|
14217
14308
|
);
|
|
14218
|
-
const handleActivateTimeline =
|
|
14309
|
+
const handleActivateTimeline = useCallback5(() => {
|
|
14219
14310
|
const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
14220
14311
|
if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
|
|
14221
14312
|
while (timelineIntervalsGroup.children.length > 0) {
|
|
@@ -14375,7 +14466,7 @@ function XViewScene({
|
|
|
14375
14466
|
}
|
|
14376
14467
|
});
|
|
14377
14468
|
}, []);
|
|
14378
|
-
const handleVersionTimeline =
|
|
14469
|
+
const handleVersionTimeline = useCallback5((sourceMesh, versionMeshes) => {
|
|
14379
14470
|
const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
14380
14471
|
if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0)
|
|
14381
14472
|
return;
|
|
@@ -14512,7 +14603,7 @@ function XViewScene({
|
|
|
14512
14603
|
}
|
|
14513
14604
|
});
|
|
14514
14605
|
}, []);
|
|
14515
|
-
|
|
14606
|
+
useEffect24(() => {
|
|
14516
14607
|
async function fetchAllData(configPath, ownerId2) {
|
|
14517
14608
|
var _a2, _b2;
|
|
14518
14609
|
if (!get_scene_view_data) {
|
|
@@ -14617,12 +14708,12 @@ function XViewScene({
|
|
|
14617
14708
|
focusNodeId,
|
|
14618
14709
|
focusAncestryId
|
|
14619
14710
|
]);
|
|
14620
|
-
const isNodeInView =
|
|
14711
|
+
const isNodeInView = useCallback5((id) => {
|
|
14621
14712
|
const key = String(id);
|
|
14622
14713
|
const objs = stateRef.current.nodeObjects || {};
|
|
14623
14714
|
return !!objs[key];
|
|
14624
14715
|
}, []);
|
|
14625
|
-
const addOrUpdateNodeMesh =
|
|
14716
|
+
const addOrUpdateNodeMesh = useCallback5(
|
|
14626
14717
|
(nodeData, position, suppressVersionUpdate = false, forceShowQuestDate = false) => {
|
|
14627
14718
|
const {
|
|
14628
14719
|
graphGroup,
|
|
@@ -14663,7 +14754,7 @@ function XViewScene({
|
|
|
14663
14754
|
},
|
|
14664
14755
|
[]
|
|
14665
14756
|
);
|
|
14666
|
-
const handleActivateQuestLens =
|
|
14757
|
+
const handleActivateQuestLens = useCallback5(({ assigneeId, status: status2, milestoneId }) => {
|
|
14667
14758
|
var _a2;
|
|
14668
14759
|
const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
|
|
14669
14760
|
if (!nodeObjects || !tweenGroup || !graphGroup) return;
|
|
@@ -14877,7 +14968,7 @@ function XViewScene({
|
|
|
14877
14968
|
camTween.start();
|
|
14878
14969
|
}
|
|
14879
14970
|
}, [addOrUpdateNodeMesh]);
|
|
14880
|
-
|
|
14971
|
+
useEffect24(() => {
|
|
14881
14972
|
if (!isInitialized || !sceneDataRef.current) return;
|
|
14882
14973
|
const currentMount = mountRef.current;
|
|
14883
14974
|
if (!currentMount) return;
|
|
@@ -15633,7 +15724,7 @@ function XViewScene({
|
|
|
15633
15724
|
get_scene_view_data,
|
|
15634
15725
|
save_view_data
|
|
15635
15726
|
]);
|
|
15636
|
-
const handleGhostNodeImageChange =
|
|
15727
|
+
const handleGhostNodeImageChange = useCallback5((useImage, imageUrl) => {
|
|
15637
15728
|
const {
|
|
15638
15729
|
node: ghostNode,
|
|
15639
15730
|
line: ghostLine,
|
|
@@ -15681,7 +15772,7 @@ function XViewScene({
|
|
|
15681
15772
|
aura: newGhostNode.getObjectByName("aura")
|
|
15682
15773
|
};
|
|
15683
15774
|
}, []);
|
|
15684
|
-
const handleGhostNodeIntensityChange =
|
|
15775
|
+
const handleGhostNodeIntensityChange = useCallback5((newIntensity) => {
|
|
15685
15776
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
15686
15777
|
if (!ghostNode) return;
|
|
15687
15778
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -15702,7 +15793,7 @@ function XViewScene({
|
|
|
15702
15793
|
ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
|
|
15703
15794
|
}
|
|
15704
15795
|
}, []);
|
|
15705
|
-
const handleDetailNodeIntensityChange =
|
|
15796
|
+
const handleDetailNodeIntensityChange = useCallback5(
|
|
15706
15797
|
(nodeId, newIntensity) => {
|
|
15707
15798
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
15708
15799
|
if (!mesh) return;
|
|
@@ -15858,7 +15949,7 @@ function XViewScene({
|
|
|
15858
15949
|
mountRef.current.style.cursor = "default";
|
|
15859
15950
|
}
|
|
15860
15951
|
};
|
|
15861
|
-
const handleAncestryTreeUpdate =
|
|
15952
|
+
const handleAncestryTreeUpdate = useCallback5((newTree, extraData = null) => {
|
|
15862
15953
|
setAncestryMode((prev) => {
|
|
15863
15954
|
const prevTreeStr = JSON.stringify(prev.tree);
|
|
15864
15955
|
const newTreeStr = JSON.stringify(newTree);
|
|
@@ -15881,7 +15972,7 @@ function XViewScene({
|
|
|
15881
15972
|
};
|
|
15882
15973
|
});
|
|
15883
15974
|
}, []);
|
|
15884
|
-
const actionHandlerContext =
|
|
15975
|
+
const actionHandlerContext = useMemo13(
|
|
15885
15976
|
() => {
|
|
15886
15977
|
var _a2;
|
|
15887
15978
|
return {
|
|
@@ -15942,7 +16033,7 @@ function XViewScene({
|
|
|
15942
16033
|
const handleStartVersioning = (nodeData) => {
|
|
15943
16034
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
15944
16035
|
};
|
|
15945
|
-
const handleStartQuestQuick =
|
|
16036
|
+
const handleStartQuestQuick = useCallback5((questNode) => {
|
|
15946
16037
|
var _a2, _b2, _c2;
|
|
15947
16038
|
if (!questNode || !actionHandlerContext) return;
|
|
15948
16039
|
const allParentNodes = Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
|
|
@@ -15977,7 +16068,7 @@ function XViewScene({
|
|
|
15977
16068
|
}
|
|
15978
16069
|
setDetailsNode(updatedNode);
|
|
15979
16070
|
}, [session, actionHandlerContext]);
|
|
15980
|
-
const handleFinishQuestQuick =
|
|
16071
|
+
const handleFinishQuestQuick = useCallback5((questNode) => {
|
|
15981
16072
|
var _a2, _b2, _c2, _d2;
|
|
15982
16073
|
if (!questNode || !actionHandlerContext) return;
|
|
15983
16074
|
const {
|
|
@@ -16051,7 +16142,7 @@ function XViewScene({
|
|
|
16051
16142
|
setDetailsNode(null);
|
|
16052
16143
|
}
|
|
16053
16144
|
}, [session, actionHandlerContext, viewMembers, detailsNode]);
|
|
16054
|
-
const handleCancelQuest =
|
|
16145
|
+
const handleCancelQuest = useCallback5(() => {
|
|
16055
16146
|
const { graphGroup, ghostElements } = stateRef.current;
|
|
16056
16147
|
if (ghostElements.node && graphGroup) {
|
|
16057
16148
|
if (ghostElements.node.userData.labelObject) {
|
|
@@ -16208,7 +16299,7 @@ function XViewScene({
|
|
|
16208
16299
|
}
|
|
16209
16300
|
userActionHandlers.handleCancelConnection(context);
|
|
16210
16301
|
};
|
|
16211
|
-
const handleClearAncestryVisuals =
|
|
16302
|
+
const handleClearAncestryVisuals = useCallback5((ancestryId) => {
|
|
16212
16303
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
16213
16304
|
const renderIndex = renderedAncestries.findIndex(
|
|
16214
16305
|
(a) => String(a.id) === String(ancestryId)
|
|
@@ -16226,7 +16317,7 @@ function XViewScene({
|
|
|
16226
16317
|
);
|
|
16227
16318
|
}
|
|
16228
16319
|
}, []);
|
|
16229
|
-
const handleRenderAncestry =
|
|
16320
|
+
const handleRenderAncestry = useCallback5(
|
|
16230
16321
|
async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
|
|
16231
16322
|
setContextMenu(
|
|
16232
16323
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -16720,7 +16811,7 @@ function XViewScene({
|
|
|
16720
16811
|
ancestryMode.isActive
|
|
16721
16812
|
]
|
|
16722
16813
|
);
|
|
16723
|
-
const handleRenderAbstractionTree =
|
|
16814
|
+
const handleRenderAbstractionTree = useCallback5(
|
|
16724
16815
|
(ancestryObject, targetNodeId = null) => {
|
|
16725
16816
|
setContextMenu(
|
|
16726
16817
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -16808,7 +16899,7 @@ function XViewScene({
|
|
|
16808
16899
|
handleClearAncestryVisuals
|
|
16809
16900
|
]
|
|
16810
16901
|
);
|
|
16811
|
-
const handleReadModeBranchNav =
|
|
16902
|
+
const handleReadModeBranchNav = useCallback5(
|
|
16812
16903
|
(nodeId, action, direction = "right") => {
|
|
16813
16904
|
const { ancestry, branchStack } = readingMode;
|
|
16814
16905
|
if (!ancestry || !ancestry.tree) return;
|
|
@@ -16986,13 +17077,13 @@ function XViewScene({
|
|
|
16986
17077
|
},
|
|
16987
17078
|
[readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]
|
|
16988
17079
|
);
|
|
16989
|
-
const handleReadModeHighlight =
|
|
17080
|
+
const handleReadModeHighlight = useCallback5((nodeId) => {
|
|
16990
17081
|
if (stateRef.current.highlightedNodeId !== nodeId) {
|
|
16991
17082
|
stateRef.current.highlightedNodeId = nodeId;
|
|
16992
17083
|
}
|
|
16993
17084
|
setHighlightedNodeId(nodeId);
|
|
16994
17085
|
}, []);
|
|
16995
|
-
const activeNodeBranches =
|
|
17086
|
+
const activeNodeBranches = useMemo13(() => {
|
|
16996
17087
|
if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree)
|
|
16997
17088
|
return null;
|
|
16998
17089
|
const fullTree = buildFullAncestryTree(
|
|
@@ -17036,7 +17127,7 @@ function XViewScene({
|
|
|
17036
17127
|
readingMode.branchStack,
|
|
17037
17128
|
ancestryDataRef.current
|
|
17038
17129
|
]);
|
|
17039
|
-
const backNavigationInfo =
|
|
17130
|
+
const backNavigationInfo = useMemo13(() => {
|
|
17040
17131
|
const { branchStack } = readingMode;
|
|
17041
17132
|
if (!branchStack || branchStack.length === 0) return null;
|
|
17042
17133
|
const lastStep = branchStack[branchStack.length - 1];
|
|
@@ -17047,7 +17138,7 @@ function XViewScene({
|
|
|
17047
17138
|
name: "Voltar para anterior"
|
|
17048
17139
|
};
|
|
17049
17140
|
}, [readingMode.branchStack]);
|
|
17050
|
-
const getReadModeDisplayContext =
|
|
17141
|
+
const getReadModeDisplayContext = useMemo13(() => {
|
|
17051
17142
|
const { ancestry, branchStack } = readingMode;
|
|
17052
17143
|
if (!ancestry) return null;
|
|
17053
17144
|
if (branchStack.length === 0) {
|
|
@@ -17090,7 +17181,7 @@ function XViewScene({
|
|
|
17090
17181
|
customProperties: branchProps
|
|
17091
17182
|
};
|
|
17092
17183
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
17093
|
-
const readModeAbstractionTree =
|
|
17184
|
+
const readModeAbstractionTree = useMemo13(() => {
|
|
17094
17185
|
if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
|
|
17095
17186
|
return null;
|
|
17096
17187
|
}
|
|
@@ -17109,7 +17200,7 @@ function XViewScene({
|
|
|
17109
17200
|
buildFullAncestryTree,
|
|
17110
17201
|
sceneVersion
|
|
17111
17202
|
]);
|
|
17112
|
-
const handleStartReadingAncestry =
|
|
17203
|
+
const handleStartReadingAncestry = useCallback5(
|
|
17113
17204
|
async (ancestryObject, renderMode = "full") => {
|
|
17114
17205
|
setContextMenu(
|
|
17115
17206
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -17152,7 +17243,7 @@ function XViewScene({
|
|
|
17152
17243
|
},
|
|
17153
17244
|
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
17154
17245
|
);
|
|
17155
|
-
const handleReadModeSectionChange =
|
|
17246
|
+
const handleReadModeSectionChange = useCallback5(
|
|
17156
17247
|
(activeSectionId) => {
|
|
17157
17248
|
const { ancestry, branchStack } = readingMode;
|
|
17158
17249
|
if (!ancestry || !readingMode.isActive) return;
|
|
@@ -17237,10 +17328,10 @@ function XViewScene({
|
|
|
17237
17328
|
ancestryDataRef.current
|
|
17238
17329
|
]
|
|
17239
17330
|
);
|
|
17240
|
-
const handleCloseReadMode =
|
|
17331
|
+
const handleCloseReadMode = useCallback5(() => {
|
|
17241
17332
|
setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
|
|
17242
17333
|
}, []);
|
|
17243
|
-
const handleAncestrySectionChange =
|
|
17334
|
+
const handleAncestrySectionChange = useCallback5(
|
|
17244
17335
|
(activeSectionId, ancestryOverride = null, rotation = 0) => {
|
|
17245
17336
|
var _a2, _b2;
|
|
17246
17337
|
const currentMode = stateRef.current.ancestry;
|
|
@@ -17302,7 +17393,7 @@ function XViewScene({
|
|
|
17302
17393
|
},
|
|
17303
17394
|
[handleRenderAncestry]
|
|
17304
17395
|
);
|
|
17305
|
-
const handleEditAncestry =
|
|
17396
|
+
const handleEditAncestry = useCallback5(
|
|
17306
17397
|
async (ancestryObject) => {
|
|
17307
17398
|
setContextMenu(
|
|
17308
17399
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -17357,7 +17448,7 @@ function XViewScene({
|
|
|
17357
17448
|
const handleSelectAncestryParent = (nodeId) => {
|
|
17358
17449
|
setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
|
|
17359
17450
|
};
|
|
17360
|
-
const handleRemoveFromAncestry =
|
|
17451
|
+
const handleRemoveFromAncestry = useCallback5((pathToRemove) => {
|
|
17361
17452
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
|
|
17362
17453
|
console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
|
|
17363
17454
|
return;
|
|
@@ -17382,7 +17473,7 @@ function XViewScene({
|
|
|
17382
17473
|
return { ...prev, tree: newTree };
|
|
17383
17474
|
});
|
|
17384
17475
|
}, []);
|
|
17385
|
-
const handleSaveAncestry =
|
|
17476
|
+
const handleSaveAncestry = useCallback5(
|
|
17386
17477
|
async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
|
|
17387
17478
|
const treeToUse = treeOverride || ancestryMode.tree;
|
|
17388
17479
|
const { isEditMode, currentAncestryId } = ancestryMode;
|
|
@@ -17618,7 +17709,7 @@ function XViewScene({
|
|
|
17618
17709
|
});
|
|
17619
17710
|
setEditingAncestryRel({ visible: false, data: null, path: null });
|
|
17620
17711
|
};
|
|
17621
|
-
const handleDeleteAncestry =
|
|
17712
|
+
const handleDeleteAncestry = useCallback5(
|
|
17622
17713
|
async (ancestryIdToDelete) => {
|
|
17623
17714
|
if (!ancestryIdToDelete) {
|
|
17624
17715
|
alert("ID da ancestralidade n\xE3o encontrado.");
|
|
@@ -17700,10 +17791,58 @@ function XViewScene({
|
|
|
17700
17791
|
},
|
|
17701
17792
|
[save_view_data, delete_file_action]
|
|
17702
17793
|
);
|
|
17703
|
-
const handleOpenAncestryBoard =
|
|
17794
|
+
const handleOpenAncestryBoard = useCallback5(() => {
|
|
17704
17795
|
setIsAncestryBoardOpen(true);
|
|
17705
17796
|
}, []);
|
|
17706
|
-
const
|
|
17797
|
+
const allAvailableNodes = useMemo13(() => {
|
|
17798
|
+
if (!parentDataRef.current) return [];
|
|
17799
|
+
return Object.values(parentDataRef.current).flatMap(
|
|
17800
|
+
(fileData) => fileData.nodes || []
|
|
17801
|
+
);
|
|
17802
|
+
}, [sceneVersion, isInitialized]);
|
|
17803
|
+
const allAvailableAncestries = useMemo13(() => {
|
|
17804
|
+
return ancestryDataRef.current || [];
|
|
17805
|
+
}, [sceneVersion, isInitialized]);
|
|
17806
|
+
const handleOpenReference = useCallback5(
|
|
17807
|
+
(referenceData) => {
|
|
17808
|
+
const { type, id } = referenceData;
|
|
17809
|
+
if (type === "node") {
|
|
17810
|
+
const targetNode = allAvailableNodes.find(
|
|
17811
|
+
(n) => String(n.id) === String(id)
|
|
17812
|
+
);
|
|
17813
|
+
if (targetNode) {
|
|
17814
|
+
setAncestryLinkDetails(null);
|
|
17815
|
+
setDetailsLink(null);
|
|
17816
|
+
setDetailsNode(targetNode);
|
|
17817
|
+
const sceneMesh = stateRef.current.nodeObjects[String(id)];
|
|
17818
|
+
if (sceneMesh) {
|
|
17819
|
+
tweenToTarget(sceneMesh);
|
|
17820
|
+
}
|
|
17821
|
+
} else {
|
|
17822
|
+
alert("Node original n\xE3o encontrado neste contexto.");
|
|
17823
|
+
}
|
|
17824
|
+
} else if (type === "ancestry") {
|
|
17825
|
+
const targetAncestry = allAvailableAncestries.find(
|
|
17826
|
+
(a) => String(a.ancestry_id) === String(id)
|
|
17827
|
+
);
|
|
17828
|
+
if (targetAncestry) {
|
|
17829
|
+
setDetailsNode(null);
|
|
17830
|
+
setDetailsLink(null);
|
|
17831
|
+
setAncestryLinkDetails(null);
|
|
17832
|
+
handleEditAncestry(targetAncestry);
|
|
17833
|
+
} else {
|
|
17834
|
+
alert("Ancestralidade original n\xE3o encontrada neste contexto.");
|
|
17835
|
+
}
|
|
17836
|
+
}
|
|
17837
|
+
},
|
|
17838
|
+
[
|
|
17839
|
+
allAvailableNodes,
|
|
17840
|
+
allAvailableAncestries,
|
|
17841
|
+
handleEditAncestry,
|
|
17842
|
+
tweenToTarget
|
|
17843
|
+
]
|
|
17844
|
+
);
|
|
17845
|
+
const handleSelectAncestryFromBoard = useCallback5(
|
|
17707
17846
|
(item) => {
|
|
17708
17847
|
setIsAncestryBoardOpen(false);
|
|
17709
17848
|
setIsSidebarOpen(false);
|
|
@@ -17715,7 +17854,7 @@ function XViewScene({
|
|
|
17715
17854
|
},
|
|
17716
17855
|
[handleStartReadingAncestry, handleOpenReference]
|
|
17717
17856
|
);
|
|
17718
|
-
const handleSaveAncestryBoard =
|
|
17857
|
+
const handleSaveAncestryBoard = useCallback5(
|
|
17719
17858
|
async (groups) => {
|
|
17720
17859
|
if (!sceneConfigId || !viewParams || !session) return;
|
|
17721
17860
|
const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
|
|
@@ -17729,7 +17868,7 @@ function XViewScene({
|
|
|
17729
17868
|
},
|
|
17730
17869
|
[sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]
|
|
17731
17870
|
);
|
|
17732
|
-
const existingNodeTypes =
|
|
17871
|
+
const existingNodeTypes = useMemo13(() => {
|
|
17733
17872
|
if (!parentDataRef.current) {
|
|
17734
17873
|
return [];
|
|
17735
17874
|
}
|
|
@@ -17741,7 +17880,7 @@ function XViewScene({
|
|
|
17741
17880
|
).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
|
|
17742
17881
|
return [...new Set(allTypes)];
|
|
17743
17882
|
}, [parentDataRef.current, sceneVersion]);
|
|
17744
|
-
const searchableDbNodes =
|
|
17883
|
+
const searchableDbNodes = useMemo13(() => {
|
|
17745
17884
|
if (!parentDataRef.current) {
|
|
17746
17885
|
return [];
|
|
17747
17886
|
}
|
|
@@ -17756,7 +17895,7 @@ function XViewScene({
|
|
|
17756
17895
|
return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
|
|
17757
17896
|
});
|
|
17758
17897
|
}, [parentDataRef.current, sceneVersion]);
|
|
17759
|
-
const handleAddExistingNode =
|
|
17898
|
+
const handleAddExistingNode = useCallback5(
|
|
17760
17899
|
(nodeId) => {
|
|
17761
17900
|
return userActionHandlers.handleAddExistingNodeById(
|
|
17762
17901
|
actionHandlerContext,
|
|
@@ -17765,7 +17904,7 @@ function XViewScene({
|
|
|
17765
17904
|
},
|
|
17766
17905
|
[actionHandlerContext]
|
|
17767
17906
|
);
|
|
17768
|
-
const handleUpdateMilestones =
|
|
17907
|
+
const handleUpdateMilestones = useCallback5(
|
|
17769
17908
|
async (newMilestones) => {
|
|
17770
17909
|
var _a2, _b2, _c2;
|
|
17771
17910
|
if (!sceneDataRef.current) return;
|
|
@@ -17811,7 +17950,7 @@ function XViewScene({
|
|
|
17811
17950
|
viewParams == null ? void 0 : viewParams.type
|
|
17812
17951
|
]
|
|
17813
17952
|
);
|
|
17814
|
-
const handleSaveCurrentView =
|
|
17953
|
+
const handleSaveCurrentView = useCallback5(async () => {
|
|
17815
17954
|
var _a2, _b2, _c2;
|
|
17816
17955
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
17817
17956
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
@@ -17854,61 +17993,13 @@ function XViewScene({
|
|
|
17854
17993
|
console.error("Erro na chamada de save_view_data:", error);
|
|
17855
17994
|
}
|
|
17856
17995
|
}, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
|
|
17857
|
-
const
|
|
17858
|
-
if (!parentDataRef.current) return [];
|
|
17859
|
-
return Object.values(parentDataRef.current).flatMap(
|
|
17860
|
-
(fileData) => fileData.nodes || []
|
|
17861
|
-
);
|
|
17862
|
-
}, [sceneVersion, isInitialized]);
|
|
17863
|
-
const allAvailableAncestries = useMemo12(() => {
|
|
17864
|
-
return ancestryDataRef.current || [];
|
|
17865
|
-
}, [sceneVersion, isInitialized]);
|
|
17866
|
-
const handleOpenReference = useCallback4(
|
|
17867
|
-
(referenceData) => {
|
|
17868
|
-
const { type, id } = referenceData;
|
|
17869
|
-
if (type === "node") {
|
|
17870
|
-
const targetNode = allAvailableNodes.find(
|
|
17871
|
-
(n) => String(n.id) === String(id)
|
|
17872
|
-
);
|
|
17873
|
-
if (targetNode) {
|
|
17874
|
-
setAncestryLinkDetails(null);
|
|
17875
|
-
setDetailsLink(null);
|
|
17876
|
-
setDetailsNode(targetNode);
|
|
17877
|
-
const sceneMesh = stateRef.current.nodeObjects[String(id)];
|
|
17878
|
-
if (sceneMesh) {
|
|
17879
|
-
tweenToTarget(sceneMesh);
|
|
17880
|
-
}
|
|
17881
|
-
} else {
|
|
17882
|
-
alert("Node original n\xE3o encontrado neste contexto.");
|
|
17883
|
-
}
|
|
17884
|
-
} else if (type === "ancestry") {
|
|
17885
|
-
const targetAncestry = allAvailableAncestries.find(
|
|
17886
|
-
(a) => String(a.ancestry_id) === String(id)
|
|
17887
|
-
);
|
|
17888
|
-
if (targetAncestry) {
|
|
17889
|
-
setDetailsNode(null);
|
|
17890
|
-
setDetailsLink(null);
|
|
17891
|
-
setAncestryLinkDetails(null);
|
|
17892
|
-
handleEditAncestry(targetAncestry);
|
|
17893
|
-
} else {
|
|
17894
|
-
alert("Ancestralidade original n\xE3o encontrada neste contexto.");
|
|
17895
|
-
}
|
|
17896
|
-
}
|
|
17897
|
-
},
|
|
17898
|
-
[
|
|
17899
|
-
allAvailableNodes,
|
|
17900
|
-
allAvailableAncestries,
|
|
17901
|
-
handleEditAncestry,
|
|
17902
|
-
tweenToTarget
|
|
17903
|
-
]
|
|
17904
|
-
);
|
|
17905
|
-
const handleToggleAncestryAddMode = useCallback4(() => {
|
|
17996
|
+
const handleToggleAncestryAddMode = useCallback5(() => {
|
|
17906
17997
|
setAncestryMode((prev) => ({
|
|
17907
17998
|
...prev,
|
|
17908
17999
|
isAddingNodes: !prev.isAddingNodes
|
|
17909
18000
|
}));
|
|
17910
18001
|
}, []);
|
|
17911
|
-
const handleFocusNode =
|
|
18002
|
+
const handleFocusNode = useCallback5(
|
|
17912
18003
|
(nodeData) => {
|
|
17913
18004
|
var _a2;
|
|
17914
18005
|
if (!nodeData) return;
|
|
@@ -17924,7 +18015,7 @@ function XViewScene({
|
|
|
17924
18015
|
},
|
|
17925
18016
|
[tweenToTarget]
|
|
17926
18017
|
);
|
|
17927
|
-
const availableDatasets =
|
|
18018
|
+
const availableDatasets = useMemo13(() => {
|
|
17928
18019
|
if (!sceneDataRef.current || !parentDataRef.current) return [];
|
|
17929
18020
|
return sceneDataRef.current.parent_dbs.map((db) => {
|
|
17930
18021
|
var _a2;
|
|
@@ -17938,7 +18029,7 @@ function XViewScene({
|
|
|
17938
18029
|
String(creationMode.sourceNodeData.id)
|
|
17939
18030
|
)) == null ? void 0 : _b.parentFileId : null;
|
|
17940
18031
|
const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
|
|
17941
|
-
|
|
18032
|
+
useEffect24(() => {
|
|
17942
18033
|
if (isInitialized && focusNodeId && !hasFocusedInitial) {
|
|
17943
18034
|
const nodeObjects = stateRef.current.nodeObjects || {};
|
|
17944
18035
|
const targetMesh = nodeObjects[String(focusNodeId)];
|
|
@@ -17961,7 +18052,7 @@ function XViewScene({
|
|
|
17961
18052
|
hasFocusedInitial,
|
|
17962
18053
|
tweenToTarget
|
|
17963
18054
|
]);
|
|
17964
|
-
|
|
18055
|
+
useEffect24(() => {
|
|
17965
18056
|
if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
|
|
17966
18057
|
const ancestries = ancestryDataRef.current || [];
|
|
17967
18058
|
const targetAncestry = ancestries.find(
|
|
@@ -17986,7 +18077,7 @@ function XViewScene({
|
|
|
17986
18077
|
hasOpenedInitialAncestry,
|
|
17987
18078
|
handleStartReadingAncestry
|
|
17988
18079
|
]);
|
|
17989
|
-
|
|
18080
|
+
useEffect24(() => {
|
|
17990
18081
|
function handleKeyDown(event) {
|
|
17991
18082
|
var _a2, _b2, _c2;
|
|
17992
18083
|
const context = actionHandlerContext;
|
|
@@ -18109,10 +18200,10 @@ function XViewScene({
|
|
|
18109
18200
|
// <-- handleCancelQuest adicionado aqui
|
|
18110
18201
|
]);
|
|
18111
18202
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
18112
|
-
return /* @__PURE__ */
|
|
18203
|
+
return /* @__PURE__ */ React30.createElement(LoadingScreen, null);
|
|
18113
18204
|
}
|
|
18114
18205
|
if (permissionStatus === "denied") {
|
|
18115
|
-
return /* @__PURE__ */
|
|
18206
|
+
return /* @__PURE__ */ React30.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ React30.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ React30.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ React30.createElement(
|
|
18116
18207
|
"svg",
|
|
18117
18208
|
{
|
|
18118
18209
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -18122,7 +18213,7 @@ function XViewScene({
|
|
|
18122
18213
|
stroke: "currentColor",
|
|
18123
18214
|
className: "w-16 h-16 mx-auto"
|
|
18124
18215
|
},
|
|
18125
|
-
/* @__PURE__ */
|
|
18216
|
+
/* @__PURE__ */ React30.createElement(
|
|
18126
18217
|
"path",
|
|
18127
18218
|
{
|
|
18128
18219
|
strokeLinecap: "round",
|
|
@@ -18130,13 +18221,13 @@ function XViewScene({
|
|
|
18130
18221
|
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"
|
|
18131
18222
|
}
|
|
18132
18223
|
)
|
|
18133
|
-
)), /* @__PURE__ */
|
|
18224
|
+
)), /* @__PURE__ */ React30.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ React30.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__ */ React30.createElement(
|
|
18134
18225
|
"button",
|
|
18135
18226
|
{
|
|
18136
18227
|
onClick: () => router.push("/dashboard/scenes"),
|
|
18137
18228
|
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"
|
|
18138
18229
|
},
|
|
18139
|
-
/* @__PURE__ */
|
|
18230
|
+
/* @__PURE__ */ React30.createElement(
|
|
18140
18231
|
"svg",
|
|
18141
18232
|
{
|
|
18142
18233
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -18146,7 +18237,7 @@ function XViewScene({
|
|
|
18146
18237
|
stroke: "currentColor",
|
|
18147
18238
|
className: "w-5 h-5"
|
|
18148
18239
|
},
|
|
18149
|
-
/* @__PURE__ */
|
|
18240
|
+
/* @__PURE__ */ React30.createElement(
|
|
18150
18241
|
"path",
|
|
18151
18242
|
{
|
|
18152
18243
|
strokeLinecap: "round",
|
|
@@ -18158,7 +18249,7 @@ function XViewScene({
|
|
|
18158
18249
|
"Voltar para Scenes"
|
|
18159
18250
|
)));
|
|
18160
18251
|
}
|
|
18161
|
-
return /* @__PURE__ */
|
|
18252
|
+
return /* @__PURE__ */ React30.createElement(
|
|
18162
18253
|
"div",
|
|
18163
18254
|
{
|
|
18164
18255
|
ref: mountRef,
|
|
@@ -18170,7 +18261,7 @@ function XViewScene({
|
|
|
18170
18261
|
cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
|
|
18171
18262
|
}
|
|
18172
18263
|
},
|
|
18173
|
-
userPermissionRole !== "link_viewer" && /* @__PURE__ */
|
|
18264
|
+
userPermissionRole !== "link_viewer" && /* @__PURE__ */ React30.createElement(
|
|
18174
18265
|
XViewSidebar,
|
|
18175
18266
|
{
|
|
18176
18267
|
dbNodes: searchableDbNodes,
|
|
@@ -18194,7 +18285,7 @@ function XViewScene({
|
|
|
18194
18285
|
onOpenMilestoneManager: () => setIsMilestoneManagerOpen(true)
|
|
18195
18286
|
}
|
|
18196
18287
|
),
|
|
18197
|
-
creationMode.isActive && /* @__PURE__ */
|
|
18288
|
+
creationMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18198
18289
|
InSceneCreationForm,
|
|
18199
18290
|
{
|
|
18200
18291
|
onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
|
|
@@ -18226,7 +18317,7 @@ function XViewScene({
|
|
|
18226
18317
|
availableAncestries: allAvailableAncestries
|
|
18227
18318
|
}
|
|
18228
18319
|
),
|
|
18229
|
-
versionMode.isActive && /* @__PURE__ */
|
|
18320
|
+
versionMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18230
18321
|
InSceneVersionForm,
|
|
18231
18322
|
{
|
|
18232
18323
|
onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
|
|
@@ -18252,7 +18343,7 @@ function XViewScene({
|
|
|
18252
18343
|
availableAncestries: allAvailableAncestries
|
|
18253
18344
|
}
|
|
18254
18345
|
),
|
|
18255
|
-
questMode.isActive && /* @__PURE__ */
|
|
18346
|
+
questMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18256
18347
|
InSceneQuestForm,
|
|
18257
18348
|
{
|
|
18258
18349
|
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
@@ -18280,7 +18371,7 @@ function XViewScene({
|
|
|
18280
18371
|
onUpdateMilestones: handleUpdateMilestones
|
|
18281
18372
|
}
|
|
18282
18373
|
),
|
|
18283
|
-
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */
|
|
18374
|
+
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React30.createElement(
|
|
18284
18375
|
"div",
|
|
18285
18376
|
{
|
|
18286
18377
|
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"}`,
|
|
@@ -18293,7 +18384,7 @@ function XViewScene({
|
|
|
18293
18384
|
maxWidth: "92vw"
|
|
18294
18385
|
}
|
|
18295
18386
|
},
|
|
18296
|
-
/* @__PURE__ */
|
|
18387
|
+
/* @__PURE__ */ React30.createElement(
|
|
18297
18388
|
"div",
|
|
18298
18389
|
{
|
|
18299
18390
|
onPointerDown: (e) => {
|
|
@@ -18304,7 +18395,7 @@ function XViewScene({
|
|
|
18304
18395
|
title: "Arraste para redimensionar"
|
|
18305
18396
|
}
|
|
18306
18397
|
),
|
|
18307
|
-
/* @__PURE__ */
|
|
18398
|
+
/* @__PURE__ */ React30.createElement(
|
|
18308
18399
|
DescriptionReadModePanel,
|
|
18309
18400
|
{
|
|
18310
18401
|
key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
|
|
@@ -18339,7 +18430,7 @@ function XViewScene({
|
|
|
18339
18430
|
}
|
|
18340
18431
|
)
|
|
18341
18432
|
),
|
|
18342
|
-
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */
|
|
18433
|
+
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ React30.createElement(
|
|
18343
18434
|
CreateAncestryPanel,
|
|
18344
18435
|
{
|
|
18345
18436
|
ancestryMode,
|
|
@@ -18375,7 +18466,7 @@ function XViewScene({
|
|
|
18375
18466
|
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
18376
18467
|
}
|
|
18377
18468
|
),
|
|
18378
|
-
editingAncestryRel.visible && /* @__PURE__ */
|
|
18469
|
+
editingAncestryRel.visible && /* @__PURE__ */ React30.createElement(
|
|
18379
18470
|
AncestryRelationshipPanel,
|
|
18380
18471
|
{
|
|
18381
18472
|
data: editingAncestryRel.data,
|
|
@@ -18389,7 +18480,7 @@ function XViewScene({
|
|
|
18389
18480
|
onUploadFile: upload_file_action
|
|
18390
18481
|
}
|
|
18391
18482
|
),
|
|
18392
|
-
detailsNode && detailsNode.is_quest && /* @__PURE__ */
|
|
18483
|
+
detailsNode && detailsNode.is_quest && /* @__PURE__ */ React30.createElement(
|
|
18393
18484
|
QuestDetailsPanel,
|
|
18394
18485
|
{
|
|
18395
18486
|
node: detailsNode,
|
|
@@ -18415,7 +18506,7 @@ function XViewScene({
|
|
|
18415
18506
|
onUpdateMilestones: handleUpdateMilestones
|
|
18416
18507
|
}
|
|
18417
18508
|
),
|
|
18418
|
-
detailsNode && !detailsNode.is_quest && /* @__PURE__ */
|
|
18509
|
+
detailsNode && !detailsNode.is_quest && /* @__PURE__ */ React30.createElement(
|
|
18419
18510
|
NodeDetailsPanel,
|
|
18420
18511
|
{
|
|
18421
18512
|
node: detailsNode,
|
|
@@ -18447,7 +18538,7 @@ function XViewScene({
|
|
|
18447
18538
|
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
18448
18539
|
}
|
|
18449
18540
|
),
|
|
18450
|
-
detailsLink && /* @__PURE__ */
|
|
18541
|
+
detailsLink && /* @__PURE__ */ React30.createElement(
|
|
18451
18542
|
RelationshipDetailsPanel,
|
|
18452
18543
|
{
|
|
18453
18544
|
link: detailsLink,
|
|
@@ -18461,7 +18552,7 @@ function XViewScene({
|
|
|
18461
18552
|
userRole: userPermissionRole
|
|
18462
18553
|
}
|
|
18463
18554
|
),
|
|
18464
|
-
ancestryLinkDetails && /* @__PURE__ */
|
|
18555
|
+
ancestryLinkDetails && /* @__PURE__ */ React30.createElement(
|
|
18465
18556
|
AncestryLinkDetailsPanel,
|
|
18466
18557
|
{
|
|
18467
18558
|
data: ancestryLinkDetails,
|
|
@@ -18472,7 +18563,7 @@ function XViewScene({
|
|
|
18472
18563
|
onUploadFile: upload_file_action
|
|
18473
18564
|
}
|
|
18474
18565
|
),
|
|
18475
|
-
/* @__PURE__ */
|
|
18566
|
+
/* @__PURE__ */ React30.createElement(
|
|
18476
18567
|
"div",
|
|
18477
18568
|
{
|
|
18478
18569
|
ref: tooltipRef,
|
|
@@ -18499,7 +18590,7 @@ function XViewScene({
|
|
|
18499
18590
|
}
|
|
18500
18591
|
}
|
|
18501
18592
|
),
|
|
18502
|
-
/* @__PURE__ */
|
|
18593
|
+
/* @__PURE__ */ React30.createElement(
|
|
18503
18594
|
ContextMenu,
|
|
18504
18595
|
{
|
|
18505
18596
|
data: contextMenu,
|
|
@@ -18532,7 +18623,7 @@ function XViewScene({
|
|
|
18532
18623
|
onFinishQuest: handleFinishQuestQuick
|
|
18533
18624
|
}
|
|
18534
18625
|
),
|
|
18535
|
-
/* @__PURE__ */
|
|
18626
|
+
/* @__PURE__ */ React30.createElement(
|
|
18536
18627
|
MultiNodeContextMenu,
|
|
18537
18628
|
{
|
|
18538
18629
|
data: multiContextMenu,
|
|
@@ -18552,7 +18643,7 @@ function XViewScene({
|
|
|
18552
18643
|
)
|
|
18553
18644
|
}
|
|
18554
18645
|
),
|
|
18555
|
-
/* @__PURE__ */
|
|
18646
|
+
/* @__PURE__ */ React30.createElement(
|
|
18556
18647
|
RelationshipContextMenu,
|
|
18557
18648
|
{
|
|
18558
18649
|
data: relationshipMenu,
|
|
@@ -18570,14 +18661,14 @@ function XViewScene({
|
|
|
18570
18661
|
onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
|
|
18571
18662
|
}
|
|
18572
18663
|
),
|
|
18573
|
-
/* @__PURE__ */
|
|
18664
|
+
/* @__PURE__ */ React30.createElement(
|
|
18574
18665
|
ImageViewer,
|
|
18575
18666
|
{
|
|
18576
18667
|
data: imageViewer,
|
|
18577
18668
|
onClose: () => setImageViewer({ ...imageViewer, visible: false })
|
|
18578
18669
|
}
|
|
18579
18670
|
),
|
|
18580
|
-
/* @__PURE__ */
|
|
18671
|
+
/* @__PURE__ */ React30.createElement(
|
|
18581
18672
|
AncestryBoard,
|
|
18582
18673
|
{
|
|
18583
18674
|
isOpen: isAncestryBoardOpen,
|
|
@@ -18590,7 +18681,7 @@ function XViewScene({
|
|
|
18590
18681
|
userRole: userPermissionRole
|
|
18591
18682
|
}
|
|
18592
18683
|
),
|
|
18593
|
-
/* @__PURE__ */
|
|
18684
|
+
/* @__PURE__ */ React30.createElement(
|
|
18594
18685
|
MilestoneManager,
|
|
18595
18686
|
{
|
|
18596
18687
|
isOpen: isMilestoneManagerOpen,
|
|
@@ -18599,7 +18690,7 @@ function XViewScene({
|
|
|
18599
18690
|
onUpdateMilestones: handleUpdateMilestones
|
|
18600
18691
|
}
|
|
18601
18692
|
),
|
|
18602
|
-
/* @__PURE__ */
|
|
18693
|
+
/* @__PURE__ */ React30.createElement(
|
|
18603
18694
|
ImportParentFileModal,
|
|
18604
18695
|
{
|
|
18605
18696
|
isOpen: isImportModalOpen,
|
|
@@ -18612,7 +18703,7 @@ function XViewScene({
|
|
|
18612
18703
|
currentAncestries: ancestryDataRef.current || []
|
|
18613
18704
|
}
|
|
18614
18705
|
),
|
|
18615
|
-
invalidTargetError && /* @__PURE__ */
|
|
18706
|
+
invalidTargetError && /* @__PURE__ */ React30.createElement(
|
|
18616
18707
|
"div",
|
|
18617
18708
|
{
|
|
18618
18709
|
className: "ui-overlay",
|
|
@@ -18637,13 +18728,13 @@ function XViewScene({
|
|
|
18637
18728
|
animation: "fadeInDown 0.5s cubic-bezier(0.16, 1, 0.3, 1)"
|
|
18638
18729
|
}
|
|
18639
18730
|
},
|
|
18640
|
-
/* @__PURE__ */
|
|
18731
|
+
/* @__PURE__ */ React30.createElement("style", null, `
|
|
18641
18732
|
@keyframes fadeInDown {
|
|
18642
18733
|
from { opacity: 0; transform: translate(-50%, -20px); }
|
|
18643
18734
|
to { opacity: 1; transform: translate(-50%, 0); }
|
|
18644
18735
|
}
|
|
18645
18736
|
`),
|
|
18646
|
-
/* @__PURE__ */
|
|
18737
|
+
/* @__PURE__ */ React30.createElement(
|
|
18647
18738
|
"svg",
|
|
18648
18739
|
{
|
|
18649
18740
|
width: "20",
|
|
@@ -18655,12 +18746,12 @@ function XViewScene({
|
|
|
18655
18746
|
strokeLinecap: "round",
|
|
18656
18747
|
strokeLinejoin: "round"
|
|
18657
18748
|
},
|
|
18658
|
-
/* @__PURE__ */
|
|
18659
|
-
/* @__PURE__ */
|
|
18660
|
-
/* @__PURE__ */
|
|
18749
|
+
/* @__PURE__ */ React30.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
18750
|
+
/* @__PURE__ */ React30.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
18751
|
+
/* @__PURE__ */ React30.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
18661
18752
|
),
|
|
18662
|
-
/* @__PURE__ */
|
|
18663
|
-
/* @__PURE__ */
|
|
18753
|
+
/* @__PURE__ */ React30.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
|
|
18754
|
+
/* @__PURE__ */ React30.createElement(
|
|
18664
18755
|
"button",
|
|
18665
18756
|
{
|
|
18666
18757
|
onClick: () => setInvalidTargetError(null),
|