@lv-x-software-house/x_view 1.2.6-dev.2 → 1.2.6-dev.7

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.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  // src/XViewScene.jsx
2
- import React30, {
2
+ import React28, {
3
3
  useCallback as useCallback4,
4
- useEffect as useEffect24,
4
+ useEffect as useEffect22,
5
5
  useRef as useRef19,
6
- useState as useState28,
7
- useMemo as useMemo13
6
+ useState as useState27,
7
+ useMemo as useMemo12
8
8
  } from "react";
9
9
  import { useRouter, useSearchParams } from "next/navigation";
10
10
  import { useSession } from "next-auth/react";
@@ -1053,6 +1053,8 @@ var userActionHandlers = {
1053
1053
  if (isCrossDataset) {
1054
1054
  graphDataRef.current[finalTargetDatasetId] = targetDataToUpdate;
1055
1055
  }
1056
+ if (sceneDataRef.current.parent_dbs.some((db) => String(db.db_id) === String(sourceParentInfo.parentFileId))) {
1057
+ }
1056
1058
  const finalPosition = stateRef.current.ghostElements.node.position.clone();
1057
1059
  addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
1058
1060
  stateRef.current.nodeIdToParentFileMap.set(String(newNode.id), {
@@ -1251,6 +1253,9 @@ var userActionHandlers = {
1251
1253
  );
1252
1254
  }
1253
1255
  graphDataRef.current[parentFileId] = specificParentData;
1256
+ if (isView && parentFileId === context.sceneConfigId) {
1257
+ sceneDataRef.current.quest_nodes = [...specificParentData.nodes];
1258
+ }
1254
1259
  const finalPosition = stateRef.current.ghostElements.node.position.clone();
1255
1260
  addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
1256
1261
  setters.setSceneVersion((v) => v + 1);
@@ -2270,8 +2275,6 @@ var userActionHandlers = {
2270
2275
  milestones: sceneDataRef.current.milestones || [],
2271
2276
  quest_counter: sceneDataRef.current.quest_counter || 1
2272
2277
  };
2273
- sceneDataRef.current.quest_nodes = specificParentData.nodes;
2274
- sceneDataRef.current.quest_links = specificParentData.links;
2275
2278
  await context.actions.save_view_data(
2276
2279
  context.sceneSaveUrl,
2277
2280
  viewFilePayload
@@ -2284,6 +2287,10 @@ var userActionHandlers = {
2284
2287
  );
2285
2288
  }
2286
2289
  graphDataRef.current[parentFileId] = specificParentData;
2290
+ if (isView && parentFileId === context.sceneConfigId) {
2291
+ sceneDataRef.current.quest_nodes = [...specificParentData.nodes];
2292
+ sceneDataRef.current.quest_counter = specificParentData.quest_counter || sceneDataRef.current.quest_counter;
2293
+ }
2287
2294
  updateExistingNodeVisuals(stateRef.current, nodeToSave);
2288
2295
  setters.setSceneVersion((v) => v + 1);
2289
2296
  if (!keepOpen) {
@@ -12943,10 +12950,10 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
12943
12950
  }
12944
12951
 
12945
12952
  // src/components/AncestryBoard.jsx
12946
- import React28, { useState as useState26, useMemo as useMemo12, useEffect as useEffect23, useRef as useRef18 } from "react";
12953
+ import React26, { useState as useState25, useMemo as useMemo11, useEffect as useEffect21, useRef as useRef18 } from "react";
12947
12954
  import {
12948
- FiSearch as FiSearch9,
12949
- FiLayers as FiLayers7,
12955
+ FiSearch as FiSearch8,
12956
+ FiLayers as FiLayers6,
12950
12957
  FiCornerUpRight as FiCornerUpRight4,
12951
12958
  FiPlay,
12952
12959
  FiPlus as FiPlus10,
@@ -12957,322 +12964,132 @@ import {
12957
12964
  FiLoader as FiLoader5,
12958
12965
  FiX as FiX8,
12959
12966
  FiAlertTriangle,
12960
- FiCheckSquare as FiCheckSquare4,
12961
- FiBox as FiBox2,
12962
- FiGitBranch as FiGitBranch4
12963
- } from "react-icons/fi";
12964
- import { v4 as uuidv411 } from "uuid";
12965
-
12966
- // src/components/MentionEditor.jsx
12967
- import React27, { useMemo as useMemo11, useEffect as useEffect22 } from "react";
12968
- import { useEditor, EditorContent, ReactRenderer } from "@tiptap/react";
12969
- import StarterKit from "@tiptap/starter-kit";
12970
- import Mention from "@tiptap/extension-mention";
12971
- import tippy from "tippy.js";
12972
-
12973
- // src/components/MentionList.jsx
12974
- import React26, {
12975
- forwardRef,
12976
- useEffect as useEffect21,
12977
- useImperativeHandle,
12978
- useState as useState25
12979
- } from "react";
12980
- import {
12981
- FiLayers as FiLayers6,
12982
- FiCheckSquare as FiCheckSquare3,
12983
12967
  FiBox,
12984
- FiGitBranch as FiGitBranch3,
12985
- FiSearch as FiSearch8
12968
+ FiCheckSquare as FiCheckSquare3,
12969
+ FiGitBranch as FiGitBranch3
12986
12970
  } from "react-icons/fi";
12987
- var MentionList = forwardRef((props, ref) => {
12988
- const [selectedIndex, setSelectedIndex] = useState25(0);
12989
- const selectItem = (index) => {
12990
- const item = props.items[index];
12991
- if (item) {
12992
- props.command({ id: item.id, label: item.name, type: item.type });
12993
- }
12994
- };
12995
- const upHandler = () => {
12996
- setSelectedIndex(
12997
- (selectedIndex + props.items.length - 1) % props.items.length
12998
- );
12999
- };
13000
- const downHandler = () => {
13001
- setSelectedIndex((selectedIndex + 1) % props.items.length);
13002
- };
13003
- const enterHandler = () => {
13004
- selectItem(selectedIndex);
13005
- };
13006
- useEffect21(() => setSelectedIndex(0), [props.items]);
13007
- useImperativeHandle(ref, () => ({
13008
- onKeyDown: ({ event }) => {
13009
- if (event.key === "ArrowUp") {
13010
- upHandler();
13011
- return true;
13012
- }
13013
- if (event.key === "ArrowDown") {
13014
- downHandler();
13015
- return true;
13016
- }
13017
- if (event.key === "Enter") {
13018
- enterHandler();
13019
- return true;
13020
- }
13021
- return false;
13022
- }
13023
- }));
13024
- return /* @__PURE__ */ React26.createElement("div", { className: "z-[3000] bg-slate-900 border border-white/10 rounded-lg shadow-2xl overflow-hidden min-w-[280px] max-w-[400px] animate-in fade-in zoom-in-95 duration-200" }, /* @__PURE__ */ React26.createElement("div", { className: "p-2 border-b border-white/5 bg-slate-950/50 flex items-center gap-2" }, /* @__PURE__ */ React26.createElement(FiSearch8, { className: "text-indigo-400", size: 14 }), /* @__PURE__ */ React26.createElement("span", { className: "text-[10px] uppercase tracking-wider font-bold text-slate-500" }, "Mencionar Recurso")), /* @__PURE__ */ React26.createElement("div", { className: "p-1 max-h-[300px] overflow-y-auto custom-scrollbar" }, props.items.length ? props.items.map((item, index) => {
13025
- const isQuest = item.type === "quest";
13026
- const isVersion = item.type === "version";
13027
- const isNode = item.type === "node";
13028
- let Icon = FiLayers6;
13029
- let colorClass = "text-indigo-400";
13030
- let badgeText = "Ancestralidade";
13031
- if (isQuest) {
13032
- Icon = FiCheckSquare3;
13033
- colorClass = "text-amber-400";
13034
- badgeText = "Quest";
13035
- } else if (isVersion) {
13036
- Icon = FiGitBranch3;
13037
- colorClass = "text-purple-400";
13038
- badgeText = "Vers\xE3o";
13039
- } else if (isNode) {
13040
- Icon = FiBox;
13041
- colorClass = "text-emerald-400";
13042
- badgeText = "Node";
13043
- }
13044
- return /* @__PURE__ */ React26.createElement(
13045
- "button",
13046
- {
13047
- className: `
13048
- w-full flex items-center gap-3 px-3 py-2 text-left rounded-md transition-all
13049
- ${index === selectedIndex ? "bg-indigo-500/20 border border-indigo-500/30 text-white" : "text-slate-400 hover:bg-white/5 border border-transparent"}
13050
- `,
13051
- key: item.id,
13052
- onClick: () => selectItem(index)
13053
- },
13054
- /* @__PURE__ */ React26.createElement("div", { className: `shrink-0 w-8 h-8 rounded border border-white/5 flex items-center justify-center bg-slate-800/50 ${colorClass}` }, /* @__PURE__ */ React26.createElement(Icon, { size: 14 })),
13055
- /* @__PURE__ */ React26.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React26.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React26.createElement("span", { className: "text-sm font-medium truncate" }, item.name), /* @__PURE__ */ React26.createElement("span", { className: `text-[9px] px-1 py-0.5 rounded border border-current opacity-60 ${colorClass}` }, badgeText)))
13056
- );
13057
- }) : /* @__PURE__ */ React26.createElement("div", { className: "p-4 text-center text-slate-500 text-sm italic" }, "Nenhum resultado encontrado...")));
13058
- });
13059
- MentionList.displayName = "MentionList";
13060
- var MentionList_default = MentionList;
13061
-
13062
- // src/components/MentionEditor.jsx
13063
- var CustomMention = Mention.extend({
13064
- addAttributes() {
13065
- var _a;
13066
- return {
13067
- ...(_a = this.parent) == null ? void 0 : _a.call(this),
13068
- type: {
13069
- default: null,
13070
- parseHTML: (element) => element.getAttribute("data-mention-type"),
13071
- renderHTML: (attributes) => {
13072
- if (!attributes.type) {
13073
- return {};
13074
- }
13075
- return {
13076
- "data-mention-type": attributes.type
13077
- };
13078
- }
13079
- }
13080
- };
13081
- }
13082
- });
13083
- var MentionEditor = ({
13084
- initialValue = "",
13085
- onChange,
13086
- onPlay,
13087
- // Mantido para futura expansão se quisermos badges clicáveis reais no editor
13088
- availableItems = [],
13089
- canEdit = true,
13090
- placeholder = "Escreva algo... use @ para mencionar"
13091
- }) => {
13092
- const parseInitialContent = (text) => {
13093
- if (!text) return "<p></p>";
13094
- const parts = text.split(/(\[\[MENTION:[^\]]+\]\])/g);
13095
- return parts.map((part) => {
13096
- const match = part.match(/\[\[MENTION:([^:]+):([^:]+):([^\]]+)\]\]/);
13097
- if (match) {
13098
- const [, type, id, label] = match;
13099
- return `<span data-type="mention" data-id="${id}" data-mention-type="${type}" data-label="${label}">@${label}</span>`;
13100
- }
13101
- return part;
13102
- }).join("");
13103
- };
13104
- const content = useMemo11(() => parseInitialContent(initialValue), [initialValue]);
13105
- const editor = useEditor({
13106
- extensions: [
13107
- StarterKit.configure({
13108
- heading: false,
13109
- bulletList: false,
13110
- orderedList: false,
13111
- codeBlock: false,
13112
- blockquote: false
13113
- }),
13114
- CustomMention.configure({
13115
- HTMLAttributes: {
13116
- class: "mention"
13117
- },
13118
- suggestion: {
13119
- items: ({ query }) => {
13120
- return availableItems.filter(
13121
- (item) => item.name.toLowerCase().includes(query.toLowerCase())
13122
- ).slice(0, 10);
13123
- },
13124
- render: () => {
13125
- let component;
13126
- let popup;
13127
- return {
13128
- onStart: (props) => {
13129
- component = new ReactRenderer(MentionList_default, {
13130
- props,
13131
- editor: props.editor
13132
- });
13133
- if (!props.clientRect) {
13134
- return;
13135
- }
13136
- popup = tippy("body", {
13137
- getReferenceClientRect: props.clientRect,
13138
- appendTo: () => document.body,
13139
- content: component.element,
13140
- showOnCreate: true,
13141
- interactive: true,
13142
- trigger: "manual",
13143
- placement: "bottom-start"
13144
- });
13145
- },
13146
- onUpdate(props) {
13147
- component.updateProps(props);
13148
- if (!props.clientRect) {
13149
- return;
13150
- }
13151
- popup[0].setProps({
13152
- getReferenceClientRect: props.clientRect
13153
- });
13154
- },
13155
- onKeyDown(props) {
13156
- var _a;
13157
- if (props.event.key === "Escape") {
13158
- popup[0].hide();
13159
- return true;
13160
- }
13161
- return (_a = component == null ? void 0 : component.ref) == null ? void 0 : _a.onKeyDown(props);
13162
- },
13163
- onExit() {
13164
- if (popup && popup[0]) popup[0].destroy();
13165
- if (component) component.destroy();
13166
- }
13167
- };
13168
- }
13169
- }
13170
- })
13171
- ],
13172
- content,
13173
- editable: canEdit,
13174
- onUpdate: ({ editor: editor2 }) => {
13175
- const serialize = (json) => {
13176
- if (!json.content) return "";
13177
- return json.content.map((block) => {
13178
- if (block.type === "paragraph") {
13179
- const inner = block.content ? block.content.map((node) => {
13180
- if (node.type === "text") return node.text;
13181
- if (node.type === "mention") {
13182
- return `[[MENTION:${node.attrs.type}:${node.attrs.id}:${node.attrs.label}]]`;
13183
- }
13184
- return "";
13185
- }).join("") : "";
13186
- return inner;
13187
- }
13188
- return "";
13189
- }).join("\n").trim();
13190
- };
13191
- const serialized = serialize(editor2.getJSON());
13192
- onChange(serialized);
13193
- }
13194
- });
13195
- if (!editor) {
13196
- return null;
13197
- }
13198
- return /* @__PURE__ */ React27.createElement("div", { className: "relative group/editor min-h-[1.5rem] w-full" }, /* @__PURE__ */ React27.createElement(
13199
- EditorContent,
13200
- {
13201
- editor,
13202
- className: "text-sm text-slate-200 placeholder-slate-600 focus:outline-none"
13203
- }
13204
- ), /* @__PURE__ */ React27.createElement("style", null, `
13205
- .tiptap p {
13206
- margin: 0;
13207
- min-height: 1.2em;
13208
- }
13209
- .tiptap .mention {
13210
- display: inline-flex;
13211
- align-items: center;
13212
- background-color: rgba(99, 102, 241, 0.15);
13213
- border: 1px solid rgba(99, 102, 241, 0.3);
13214
- border-radius: 4px;
13215
- padding: 0 4px;
13216
- color: #a5b4fc;
13217
- font-weight: 500;
13218
- cursor: pointer;
13219
- margin: 0 2px;
13220
- transition: all 0.2s;
13221
- }
13222
- .tiptap .mention:hover {
13223
- background-color: rgba(99, 102, 241, 0.25);
13224
- border-color: rgba(99, 102, 241, 0.5);
13225
- color: white;
13226
- }
13227
- .tiptap:focus {
13228
- outline: none;
13229
- }
13230
- `));
13231
- };
13232
- var MentionEditor_default = MentionEditor;
13233
-
13234
- // src/components/AncestryBoard.jsx
12971
+ import { v4 as uuidv411 } from "uuid";
13235
12972
  var GroupItem = ({
13236
12973
  group,
13237
12974
  index,
12975
+ siblings,
13238
12976
  onUpdate,
13239
12977
  onDelete,
13240
12978
  onAddSubgroup,
13241
12979
  onIndent,
13242
12980
  onOutdent,
12981
+ onRemoveAncestry,
12982
+ onRequestPickAncestry,
12983
+ pickingGroupId,
13243
12984
  onPlayAncestry,
13244
- availableMentionItems,
12985
+ availableIds,
13245
12986
  canEdit
13246
12987
  }) => {
13247
12988
  const canIndent = index > 0;
13248
- 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(
12989
+ const isPickingForThisGroup = pickingGroupId === group.id;
12990
+ const textareaRef = useRef18(null);
12991
+ const adjustHeight = () => {
12992
+ const textarea = textareaRef.current;
12993
+ if (textarea) {
12994
+ textarea.style.height = "auto";
12995
+ textarea.style.height = `${textarea.scrollHeight}px`;
12996
+ }
12997
+ };
12998
+ useEffect21(() => {
12999
+ adjustHeight();
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(
13249
13002
  "div",
13250
13003
  {
13251
- 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"
13004
+ className: `
13005
+ flex flex-col gap-2 py-2 px-3 transition-all duration-200
13006
+ ${isPickingForThisGroup ? "bg-indigo-500/10 border-l-2 border-indigo-500" : "hover:bg-white/5 border-l-2 border-transparent hover:border-white/20"}
13007
+ `
13252
13008
  },
13253
- /* @__PURE__ */ React28.createElement(
13254
- MentionEditor_default,
13009
+ /* @__PURE__ */ React26.createElement(
13010
+ "textarea",
13255
13011
  {
13256
- initialValue: group.text,
13257
- onChange: (newText) => {
13258
- if (canEdit) onUpdate(group.id, { ...group, text: newText });
13012
+ ref: textareaRef,
13013
+ className: `w-full bg-transparent text-sm text-slate-200 placeholder-slate-600 resize-none focus:outline-none focus:placeholder-slate-500 overflow-y-auto ${!canEdit ? "cursor-default" : ""}`,
13014
+ rows: 1,
13015
+ style: {
13016
+ minHeight: "1.5rem",
13017
+ maxHeight: "250px"
13259
13018
  },
13260
- onPlay: onPlayAncestry,
13261
- availableItems: availableMentionItems,
13262
- canEdit,
13263
- placeholder: "Escreva sobre este grupo... use @ para mencionar"
13019
+ placeholder: canEdit ? "Escreva sobre este grupo..." : "",
13020
+ value: group.text,
13021
+ readOnly: !canEdit,
13022
+ onChange: (e) => {
13023
+ if (canEdit) onUpdate(group.id, { ...group, text: e.target.value });
13024
+ }
13264
13025
  }
13265
13026
  ),
13266
- canEdit && /* @__PURE__ */ React28.createElement("div", { className: "flex items-center justify-between pt-2 mt-1 border-t border-white/5 opacity-0 group-hover/item:opacity-100 transition-opacity" }, /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React28.createElement(
13027
+ group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ React26.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
13028
+ const isValid = availableIds.has(String(anc.ancestry_id));
13029
+ return /* @__PURE__ */ React26.createElement(
13030
+ "div",
13031
+ {
13032
+ key: anc.ancestry_id,
13033
+ className: `
13034
+ flex items-center gap-2 rounded-md px-3 py-1.5 text-xs transition-all group/card border
13035
+ ${isValid ? "bg-slate-800/60 border-white/10 hover:border-indigo-500/30 text-slate-200" : "bg-red-900/10 border-red-500/30 text-red-300/70 hover:bg-red-900/20"}
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(
13267
13085
  "button",
13268
13086
  {
13269
13087
  onClick: () => onAddSubgroup(group.id),
13270
- className: "flex items-center gap-1.5 px-3 py-1.5 text-xs text-slate-500 hover:text-white hover:bg-white/10 rounded-md transition-colors",
13088
+ className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
13271
13089
  title: "Criar Subgrupo"
13272
13090
  },
13273
- /* @__PURE__ */ React28.createElement(FiPlus10, { size: 14 }),
13274
- /* @__PURE__ */ React28.createElement("span", null, "Adicionar Subgrupo")
13275
- )), /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React28.createElement(
13091
+ /* @__PURE__ */ React26.createElement(FiPlus10, { size: 14 })
13092
+ )), /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React26.createElement(
13276
13093
  "button",
13277
13094
  {
13278
13095
  onClick: () => onIndent(group.id),
@@ -13280,25 +13097,25 @@ var GroupItem = ({
13280
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"}`,
13281
13098
  title: "Aninhar no grupo acima"
13282
13099
  },
13283
- /* @__PURE__ */ React28.createElement(FiArrowRight2, { size: 14 })
13284
- ), /* @__PURE__ */ React28.createElement(
13100
+ /* @__PURE__ */ React26.createElement(FiArrowRight2, { size: 14 })
13101
+ ), /* @__PURE__ */ React26.createElement(
13285
13102
  "button",
13286
13103
  {
13287
13104
  onClick: () => onOutdent(group.id),
13288
13105
  className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
13289
13106
  title: "Desaninhar"
13290
13107
  },
13291
- /* @__PURE__ */ React28.createElement(FiArrowLeft3, { size: 14 })
13292
- ), /* @__PURE__ */ React28.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ React28.createElement(
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(
13293
13110
  "button",
13294
13111
  {
13295
13112
  onClick: () => onDelete(group.id),
13296
13113
  className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
13297
13114
  title: "Remover Grupo"
13298
13115
  },
13299
- /* @__PURE__ */ React28.createElement(FiTrash23, { size: 14 })
13116
+ /* @__PURE__ */ React26.createElement(FiTrash23, { size: 14 })
13300
13117
  )))
13301
- ), group.children && group.children.length > 0 && /* @__PURE__ */ React28.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ React28.createElement(
13118
+ ), group.children && group.children.length > 0 && /* @__PURE__ */ React26.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ React26.createElement(
13302
13119
  GroupItem,
13303
13120
  {
13304
13121
  key: childGroup.id,
@@ -13310,8 +13127,11 @@ var GroupItem = ({
13310
13127
  onAddSubgroup,
13311
13128
  onIndent,
13312
13129
  onOutdent,
13130
+ onRemoveAncestry,
13131
+ onRequestPickAncestry,
13132
+ pickingGroupId,
13313
13133
  onPlayAncestry,
13314
- availableMentionItems,
13134
+ availableIds,
13315
13135
  canEdit
13316
13136
  }
13317
13137
  ))));
@@ -13325,20 +13145,23 @@ function AncestryBoard({
13325
13145
  initialGroups = [],
13326
13146
  onSave,
13327
13147
  userRole
13148
+ // [NOVO] Recebe a role do usuário
13328
13149
  }) {
13329
- const [groups, setGroups] = useState26([]);
13330
- const [isLoaded, setIsLoaded] = useState26(false);
13331
- const [saveStatus, setSaveStatus] = useState26("idle");
13332
- const canEdit = useMemo12(() => {
13150
+ const [searchTerm, setSearchTerm] = useState25("");
13151
+ const [groups, setGroups] = useState25([]);
13152
+ const [isLoaded, setIsLoaded] = useState25(false);
13153
+ const [pickingGroupId, setPickingGroupId] = useState25(null);
13154
+ const [saveStatus, setSaveStatus] = useState25("idle");
13155
+ const canEdit = useMemo11(() => {
13333
13156
  return userRole !== "viewer";
13334
13157
  }, [userRole]);
13335
- useEffect23(() => {
13158
+ useEffect21(() => {
13336
13159
  if (initialGroups && !isLoaded) {
13337
13160
  setGroups(initialGroups);
13338
13161
  setIsLoaded(true);
13339
13162
  }
13340
13163
  }, [initialGroups, isLoaded]);
13341
- const nodeNamesMap = useMemo12(() => {
13164
+ const nodeNamesMap = useMemo11(() => {
13342
13165
  const map = /* @__PURE__ */ new Map();
13343
13166
  if (availableNodes && Array.isArray(availableNodes)) {
13344
13167
  availableNodes.forEach((node) => {
@@ -13349,41 +13172,52 @@ function AncestryBoard({
13349
13172
  }
13350
13173
  return map;
13351
13174
  }, [availableNodes]);
13352
- const availableIds = useMemo12(() => {
13353
- return new Set(availableAncestries.map((a) => String(a.ancestry_id)));
13354
- }, [availableAncestries]);
13355
- const availableMentionItems = useMemo12(() => {
13356
- const ancestries = availableAncestries.map((a) => ({
13357
- id: String(a.ancestry_id),
13358
- ancestry_id: a.ancestry_id,
13359
- name: a.name,
13360
- description: a.description,
13361
- type: "ancestry",
13362
- ancestral_node: a.ancestral_node,
13363
- is_private: a.is_private
13364
- }));
13365
- const nodes = availableNodes.map((n) => {
13175
+ const availableIds = useMemo11(() => {
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(() => {
13182
+ const items = [];
13183
+ availableAncestries.forEach((anc) => {
13184
+ items.push({
13185
+ ...anc,
13186
+ id: String(anc.ancestry_id),
13187
+ type: "ancestry",
13188
+ searchLabel: anc.name || "",
13189
+ searchDesc: anc.description || ""
13190
+ });
13191
+ });
13192
+ availableNodes.forEach((node) => {
13193
+ var _a;
13366
13194
  let type = "node";
13367
- if (n.is_quest) type = "quest";
13368
- else if (n.is_version) type = "version";
13369
- return {
13370
- id: String(n.id),
13371
- name: n.name,
13372
- description: n.description,
13195
+ if (node.is_quest) type = "quest";
13196
+ else if ((_a = node.version_node) == null ? void 0 : _a.is_version) type = "version";
13197
+ items.push({
13198
+ ...node,
13199
+ id: String(node.id),
13373
13200
  type,
13374
- raw_node: n
13375
- };
13201
+ searchLabel: node.name || node.raw_title || "",
13202
+ searchDesc: node.description || ""
13203
+ });
13376
13204
  });
13377
- return [...ancestries, ...nodes];
13205
+ return items;
13378
13206
  }, [availableAncestries, availableNodes]);
13379
13207
  const sanitizeGroups = (groupList) => {
13380
13208
  return groupList.map((g) => ({
13381
13209
  id: g.id,
13382
13210
  text: g.text || "",
13211
+ ancestries: (g.ancestries || []).map((a) => ({
13212
+ id: a.id || a.ancestry_id,
13213
+ ancestry_id: a.ancestry_id || a.id,
13214
+ name: a.name,
13215
+ type: a.type || "ancestry"
13216
+ })),
13383
13217
  children: sanitizeGroups(g.children || [])
13384
13218
  }));
13385
13219
  };
13386
- useEffect23(() => {
13220
+ useEffect21(() => {
13387
13221
  if (!isLoaded || !onSave) return;
13388
13222
  const timeoutId = setTimeout(async () => {
13389
13223
  setSaveStatus("saving");
@@ -13401,22 +13235,42 @@ function AncestryBoard({
13401
13235
  }, 3e3);
13402
13236
  return () => clearTimeout(timeoutId);
13403
13237
  }, [groups, isLoaded, onSave]);
13404
- useEffect23(() => {
13238
+ useEffect21(() => {
13405
13239
  if (!isOpen) return;
13406
13240
  const handleKeyDown = (e) => {
13407
13241
  if (e.key === "Escape") {
13408
- onClose();
13242
+ if (pickingGroupId) {
13243
+ setPickingGroupId(null);
13244
+ } else {
13245
+ onClose();
13246
+ }
13409
13247
  e.preventDefault();
13410
13248
  e.stopPropagation();
13411
13249
  }
13412
13250
  };
13413
13251
  window.addEventListener("keydown", handleKeyDown);
13414
13252
  return () => window.removeEventListener("keydown", handleKeyDown);
13415
- }, [isOpen, onClose]);
13253
+ }, [isOpen, onClose, pickingGroupId]);
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]);
13416
13269
  const handleAddRootGroup = () => {
13417
13270
  const newGroup = {
13418
13271
  id: uuidv411(),
13419
13272
  text: "",
13273
+ ancestries: [],
13420
13274
  children: []
13421
13275
  };
13422
13276
  setGroups((prev) => [newGroup, ...prev]);
@@ -13425,6 +13279,7 @@ function AncestryBoard({
13425
13279
  const newGroup = {
13426
13280
  id: uuidv411(),
13427
13281
  text: "",
13282
+ ancestries: [],
13428
13283
  children: []
13429
13284
  };
13430
13285
  const addRecursive = (list) => {
@@ -13495,49 +13350,91 @@ function AncestryBoard({
13495
13350
  return newList;
13496
13351
  });
13497
13352
  };
13498
- const handlePlayFromGroup = (item) => {
13499
- let fullItem = item;
13500
- if (item.type === "ancestry" || !item.type) {
13501
- fullItem = availableAncestries.find(
13502
- (a) => String(a.ancestry_id) === String(item.id || item.ancestry_id)
13503
- ) || item;
13504
- } else {
13505
- fullItem = availableNodes.find(
13506
- (n) => String(n.id) === String(item.id)
13507
- ) || item;
13353
+ const handleRequestPick = (groupId) => {
13354
+ setPickingGroupId((prev) => prev === groupId ? null : groupId);
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);
13508
13385
  }
13509
- if (fullItem && onSelect) {
13510
- onSelect(fullItem);
13386
+ };
13387
+ const handlePlayFromGroup = (ancestry) => {
13388
+ if (ancestry && onSelect) {
13389
+ onSelect(ancestry);
13511
13390
  }
13512
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
+ });
13409
+ };
13513
13410
  if (!isOpen) return null;
13514
- return /* @__PURE__ */ React28.createElement(
13411
+ return /* @__PURE__ */ React26.createElement(
13515
13412
  "div",
13516
13413
  {
13517
13414
  className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
13518
13415
  onClick: onClose
13519
13416
  },
13520
- /* @__PURE__ */ React28.createElement(
13417
+ /* @__PURE__ */ React26.createElement(
13521
13418
  "div",
13522
13419
  {
13523
- className: "bg-slate-950 border border-white/10 rounded-xl w-[90vw] max-w-[1200px] h-[90vh] flex flex-col shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-200",
13420
+ 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",
13524
13421
  onClick: (e) => e.stopPropagation()
13525
13422
  },
13526
- /* @__PURE__ */ React28.createElement("div", { className: "h-14 px-6 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(
13423
+ /* @__PURE__ */ React26.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React26.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ React26.createElement(FiLayers6, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React26.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ React26.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__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(
13527
13424
  FiLoader5,
13528
13425
  {
13529
13426
  className: "animate-spin text-indigo-400",
13530
13427
  size: 12
13531
13428
  }
13532
- ), /* @__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(
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(
13533
13430
  "button",
13534
13431
  {
13535
13432
  onClick: handleAddRootGroup,
13536
13433
  className: "\n flex items-center gap-2 px-3 py-1.5 \n bg-white/5 hover:bg-white/10 \n border border-white/10 hover:border-white/20\n backdrop-blur-sm\n text-slate-200 hover:text-white\n rounded-md transition-all duration-200\n text-xs font-medium shadow-sm\n "
13537
13434
  },
13538
- /* @__PURE__ */ React28.createElement(FiPlus10, { size: 14, className: "text-indigo-400" }),
13539
- /* @__PURE__ */ React28.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
13540
- ), /* @__PURE__ */ React28.createElement(
13435
+ /* @__PURE__ */ React26.createElement(FiPlus10, { size: 14, className: "text-indigo-400" }),
13436
+ /* @__PURE__ */ React26.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
13437
+ ), /* @__PURE__ */ React26.createElement(
13541
13438
  "button",
13542
13439
  {
13543
13440
  onClick: onClose,
@@ -13545,36 +13442,102 @@ function AncestryBoard({
13545
13442
  },
13546
13443
  "\xD7"
13547
13444
  ))),
13548
- /* @__PURE__ */ React28.createElement("div", { className: "flex flex-1 overflow-hidden bg-slate-900/20" }, /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ React28.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-8 max-w-[900px] mx-auto w-full space-y-6" }, groups.length === 0 ? /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-4 border-2 border-dashed border-white/5 rounded-2xl bg-slate-900/40 p-12" }, /* @__PURE__ */ React28.createElement(FiLayers7, { size: 40, className: "opacity-10 text-indigo-400" }), /* @__PURE__ */ React28.createElement("div", { className: "text-center space-y-1" }, /* @__PURE__ */ React28.createElement("p", { className: "text-sm font-medium text-slate-300" }, "Nenhum grupo criado"), /* @__PURE__ */ React28.createElement("p", { className: "text-xs text-slate-500 max-w-[200px]" }, canEdit ? "Comece organizando sua narrativa criando o primeiro grupo." : "Este board ainda n\xE3o possui conte\xFAdo.")), canEdit && /* @__PURE__ */ React28.createElement(
13549
- "button",
13445
+ /* @__PURE__ */ React26.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ React26.createElement(
13446
+ "div",
13550
13447
  {
13551
- onClick: handleAddRootGroup,
13552
- className: "mt-2 px-4 py-2 bg-indigo-500/10 hover:bg-indigo-500/20 text-indigo-400 rounded-lg border border-indigo-500/20 transition-all text-xs font-bold uppercase tracking-wider"
13448
+ className: `
13449
+ flex flex-col border-r border-white/10 transition-all duration-300 flex-none
13450
+ ${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
13451
+ min-w-[280px] max-w-[500px] bg-slate-900
13452
+ `
13553
13453
  },
13554
- "Criar Primeiro Grupo"
13555
- )) : groups.map((group, index) => /* @__PURE__ */ React28.createElement(
13454
+ /* @__PURE__ */ React26.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ React26.createElement("div", { className: "relative group" }, /* @__PURE__ */ React26.createElement(
13455
+ FiSearch8,
13456
+ {
13457
+ className: `absolute left-3 top-1/2 -translate-y-1/2 transition-colors ${pickingGroupId ? "text-indigo-400" : "text-slate-500 group-focus-within:text-indigo-400"}`
13458
+ }
13459
+ ), /* @__PURE__ */ React26.createElement(
13460
+ "input",
13461
+ {
13462
+ type: "text",
13463
+ placeholder: pickingGroupId ? "Pesquise nodes ou ancestralidades..." : "Pesquisar no board...",
13464
+ className: `
13465
+ w-full rounded-md pl-9 pr-4 py-2 text-sm transition-all focus:outline-none focus:ring-1 focus:ring-indigo-500 border
13466
+ ${pickingGroupId ? "bg-indigo-950/30 border-indigo-500/30 text-white placeholder-indigo-300/50" : "bg-slate-950 border-white/10 text-slate-200 placeholder-slate-600"}
13467
+ `,
13468
+ value: searchTerm,
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",
13478
+ {
13479
+ key: anc.id,
13480
+ onClick: () => {
13481
+ if (isPicking) handleSelectAncestry(anc);
13482
+ },
13483
+ className: `
13484
+ group relative flex items-start gap-3 p-3 text-left rounded-lg border transition-all duration-200
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
+ `
13487
+ },
13488
+ /* @__PURE__ */ React26.createElement(
13489
+ "div",
13490
+ {
13491
+ className: `
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(
13556
13515
  GroupItem,
13557
13516
  {
13558
13517
  key: group.id,
13559
13518
  index,
13560
13519
  group,
13520
+ siblings: groups,
13561
13521
  onUpdate: handleUpdateGroup,
13562
13522
  onDelete: handleDeleteGroup,
13563
13523
  onAddSubgroup: handleAddSubgroup,
13564
13524
  onIndent: handleIndent,
13565
13525
  onOutdent: handleOutdent,
13526
+ onRemoveAncestry: handleRemoveAncestryFromGroup,
13527
+ onRequestPickAncestry: handleRequestPick,
13528
+ pickingGroupId,
13566
13529
  onPlayAncestry: handlePlayFromGroup,
13567
- availableMentionItems,
13530
+ availableIds,
13568
13531
  canEdit
13569
13532
  }
13570
13533
  ))))),
13571
- /* @__PURE__ */ React28.createElement("div", { className: "px-6 py-3 border-t border-white/10 bg-slate-950/50 text-[10px] uppercase tracking-widest font-bold text-slate-600 flex justify-between items-center flex-shrink-0" }, /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React28.createElement("span", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React28.createElement("div", { className: "w-1.5 h-1.5 rounded-full bg-indigo-500" }), " ", availableMentionItems.length, " RECURSOS DISPON\xCDVEIS"), /* @__PURE__ */ React28.createElement("span", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React28.createElement("div", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500" }), " ", groups.length, " GRUPOS PRINCIPAIS")), /* @__PURE__ */ React28.createElement("span", { className: "text-slate-700" }, "X.VIEW :: ANCESTRY BOARD ENGINE"))
13534
+ /* @__PURE__ */ React26.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__ */ React26.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ React26.createElement("span", null, groups.length, " grupos raiz"))
13572
13535
  )
13573
13536
  );
13574
13537
  }
13575
13538
 
13576
13539
  // src/components/MilestoneManager.jsx
13577
- import React29, { useState as useState27 } from "react";
13540
+ import React27, { useState as useState26 } from "react";
13578
13541
  import { FiTarget as FiTarget4, FiPlus as FiPlus11, FiTrash2 as FiTrash24, FiX as FiX9, FiCheck as FiCheck12, FiPauseCircle, FiPlayCircle } from "react-icons/fi";
13579
13542
  function MilestoneManager({
13580
13543
  isOpen,
@@ -13583,7 +13546,7 @@ function MilestoneManager({
13583
13546
  onUpdateMilestones = () => {
13584
13547
  }
13585
13548
  }) {
13586
- const [newMilestoneName, setNewMilestoneName] = useState27("");
13549
+ const [newMilestoneName, setNewMilestoneName] = useState26("");
13587
13550
  const handleAddMilestone = () => {
13588
13551
  if (!newMilestoneName.trim()) return;
13589
13552
  const newMilestone = {
@@ -13608,27 +13571,27 @@ function MilestoneManager({
13608
13571
  };
13609
13572
  if (!isOpen) return null;
13610
13573
  const swallow = (e) => e.stopPropagation();
13611
- return /* @__PURE__ */ React29.createElement(
13574
+ return /* @__PURE__ */ React27.createElement(
13612
13575
  "div",
13613
13576
  {
13614
13577
  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",
13615
13578
  onClick: onClose
13616
13579
  },
13617
- /* @__PURE__ */ React29.createElement(
13580
+ /* @__PURE__ */ React27.createElement(
13618
13581
  "div",
13619
13582
  {
13620
13583
  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",
13621
13584
  onClick: swallow
13622
13585
  },
13623
- /* @__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(
13586
+ /* @__PURE__ */ React27.createElement("div", { className: "px-6 py-4 border-b border-white/10 flex items-center justify-between" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React27.createElement("div", { className: "p-2 rounded-lg bg-indigo-500/20 text-indigo-400" }, /* @__PURE__ */ React27.createElement(FiTarget4, { size: 20 })), /* @__PURE__ */ React27.createElement("div", null, /* @__PURE__ */ React27.createElement("h2", { className: "text-lg font-semibold text-slate-100" }, "Milestones"), /* @__PURE__ */ React27.createElement("p", { className: "text-xs text-slate-400" }, "Gerencie os marcos do seu cen\xE1rio"))), /* @__PURE__ */ React27.createElement(
13624
13587
  "button",
13625
13588
  {
13626
13589
  onClick: onClose,
13627
13590
  className: "p-2 rounded-full hover:bg-white/10 text-slate-400 hover:text-white transition-colors"
13628
13591
  },
13629
- /* @__PURE__ */ React29.createElement(FiX9, { size: 20 })
13592
+ /* @__PURE__ */ React27.createElement(FiX9, { size: 20 })
13630
13593
  )),
13631
- /* @__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(
13594
+ /* @__PURE__ */ React27.createElement("div", { className: "px-6 py-5 bg-white/5 border-b border-white/5" }, /* @__PURE__ */ React27.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React27.createElement(
13632
13595
  "input",
13633
13596
  {
13634
13597
  type: "text",
@@ -13638,47 +13601,47 @@ function MilestoneManager({
13638
13601
  placeholder: "Adicionar novo milestone...",
13639
13602
  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"
13640
13603
  }
13641
- ), /* @__PURE__ */ React29.createElement(
13604
+ ), /* @__PURE__ */ React27.createElement(
13642
13605
  "button",
13643
13606
  {
13644
13607
  onClick: handleAddMilestone,
13645
13608
  disabled: !newMilestoneName.trim(),
13646
13609
  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"
13647
13610
  },
13648
- /* @__PURE__ */ React29.createElement(FiPlus11, { size: 18 }),
13611
+ /* @__PURE__ */ React27.createElement(FiPlus11, { size: 18 }),
13649
13612
  "Adicionar"
13650
13613
  ))),
13651
- /* @__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(
13614
+ /* @__PURE__ */ React27.createElement("div", { className: "flex-1 overflow-y-auto px-6 py-4 custom-scrollbar" }, milestones.length > 0 ? /* @__PURE__ */ React27.createElement("div", { className: "space-y-3" }, milestones.map((ms) => /* @__PURE__ */ React27.createElement(
13652
13615
  "div",
13653
13616
  {
13654
13617
  key: ms.id,
13655
13618
  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]"}`
13656
13619
  },
13657
- /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ React29.createElement(
13620
+ /* @__PURE__ */ React27.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ React27.createElement(
13658
13621
  "div",
13659
13622
  {
13660
13623
  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"}`
13661
13624
  }
13662
- ), /* @__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"))),
13663
- /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React29.createElement(
13625
+ ), /* @__PURE__ */ React27.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ React27.createElement("span", { className: `text-sm font-medium truncate ${ms.status === "active" ? "text-slate-100" : "text-slate-400 line-through"}` }, ms.name), /* @__PURE__ */ React27.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-wider" }, ms.status === "active" ? "Ativo" : "Inativo"))),
13626
+ /* @__PURE__ */ React27.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React27.createElement(
13664
13627
  "button",
13665
13628
  {
13666
13629
  onClick: () => handleToggleMilestoneStatus(ms.id),
13667
13630
  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"}`,
13668
13631
  title: ms.status === "active" ? "Inativar" : "Ativar"
13669
13632
  },
13670
- ms.status === "active" ? /* @__PURE__ */ React29.createElement(FiPauseCircle, { size: 18 }) : /* @__PURE__ */ React29.createElement(FiPlayCircle, { size: 18 })
13671
- ), /* @__PURE__ */ React29.createElement(
13633
+ ms.status === "active" ? /* @__PURE__ */ React27.createElement(FiPauseCircle, { size: 18 }) : /* @__PURE__ */ React27.createElement(FiPlayCircle, { size: 18 })
13634
+ ), /* @__PURE__ */ React27.createElement(
13672
13635
  "button",
13673
13636
  {
13674
13637
  onClick: () => handleRemoveMilestone(ms.id),
13675
13638
  className: "p-2 rounded-lg hover:bg-red-500/20 text-slate-500 hover:text-red-400 transition-all",
13676
13639
  title: "Remover"
13677
13640
  },
13678
- /* @__PURE__ */ React29.createElement(FiTrash24, { size: 18 })
13641
+ /* @__PURE__ */ React27.createElement(FiTrash24, { size: 18 })
13679
13642
  ))
13680
- ))) : /* @__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."))),
13681
- /* @__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))))
13643
+ ))) : /* @__PURE__ */ React27.createElement("div", { className: "flex flex-col items-center justify-center py-12 text-center" }, /* @__PURE__ */ React27.createElement("div", { className: "p-4 rounded-full bg-slate-800/30 text-slate-600 mb-4" }, /* @__PURE__ */ React27.createElement(FiTarget4, { size: 40 })), /* @__PURE__ */ React27.createElement("h3", { className: "text-slate-400 font-medium" }, "Nenhum milestone definido"), /* @__PURE__ */ React27.createElement("p", { className: "text-xs text-slate-600 max-w-[200px] mt-1 italic" }, "Defina marcos importantes para orientar o progresso do projeto."))),
13644
+ /* @__PURE__ */ React27.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__ */ React27.createElement("div", { className: "flex gap-4" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React27.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Total:"), /* @__PURE__ */ React27.createElement("span", { className: "text-xs font-bold text-slate-300" }, milestones.length)), /* @__PURE__ */ React27.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React27.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Ativos:"), /* @__PURE__ */ React27.createElement("span", { className: "text-xs font-bold text-indigo-400" }, milestones.filter((m) => m.status === "active").length))))
13682
13645
  )
13683
13646
  );
13684
13647
  }
@@ -13764,13 +13727,13 @@ function XViewScene({
13764
13727
  check_user_permission,
13765
13728
  get_view_members
13766
13729
  }) {
13767
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
13730
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
13768
13731
  const { data: session, status } = useSession();
13769
13732
  const router = useRouter();
13770
13733
  const searchParams = useSearchParams();
13771
13734
  const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
13772
13735
  const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
13773
- const viewParams = useMemo13(() => {
13736
+ const viewParams = useMemo12(() => {
13774
13737
  if (encryptedConfig) {
13775
13738
  const data = decryptData(encryptedConfig);
13776
13739
  if (data) {
@@ -13779,7 +13742,7 @@ function XViewScene({
13779
13742
  }
13780
13743
  return null;
13781
13744
  }, [encryptedConfig, session]);
13782
- useEffect24(() => {
13745
+ useEffect22(() => {
13783
13746
  async function verifyPermission() {
13784
13747
  if (!viewParams || !session || !check_user_permission) return;
13785
13748
  const { id, type, owner_id } = viewParams;
@@ -13816,21 +13779,21 @@ function XViewScene({
13816
13779
  setIsLoading(false);
13817
13780
  }
13818
13781
  }, [viewParams, session, status, check_user_permission]);
13819
- const sceneConfigId = useMemo13(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
13820
- const ownerId = useMemo13(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
13821
- const dbSaveUrl = useMemo13(() => {
13782
+ const sceneConfigId = useMemo12(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
13783
+ const ownerId = useMemo12(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
13784
+ const dbSaveUrl = useMemo12(() => {
13822
13785
  if (ownerId && sceneConfigId) {
13823
13786
  return `x_view_dbs/${ownerId}/${sceneConfigId}`;
13824
13787
  }
13825
13788
  return null;
13826
13789
  }, [ownerId, sceneConfigId]);
13827
- const sceneSaveUrl = useMemo13(() => {
13790
+ const sceneSaveUrl = useMemo12(() => {
13828
13791
  if (ownerId && sceneConfigId) {
13829
13792
  return `x_view_scenes/${ownerId}/${sceneConfigId}`;
13830
13793
  }
13831
13794
  return null;
13832
13795
  }, [ownerId, sceneConfigId]);
13833
- const ancestry_save_url = useMemo13(() => {
13796
+ const ancestry_save_url = useMemo12(() => {
13834
13797
  if (ownerId && sceneConfigId) {
13835
13798
  return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
13836
13799
  }
@@ -13839,42 +13802,42 @@ function XViewScene({
13839
13802
  const sceneDataRef = useRef19(null);
13840
13803
  const parentDataRef = useRef19(null);
13841
13804
  const ancestryDataRef = useRef19(null);
13842
- const [isLoading, setIsLoading] = useState28(true);
13843
- const [permissionStatus, setPermissionStatus] = useState28("loading");
13844
- const [userPermissionRole, setUserPermissionRole] = useState28(null);
13845
- const [viewMembers, setViewMembers] = useState28([]);
13846
- const [isInitialized, setIsInitialized] = useState28(false);
13847
- const [sceneVersion, setSceneVersion] = useState28(0);
13848
- const [contextMenu, setContextMenu] = useState28({
13805
+ const [isLoading, setIsLoading] = useState27(true);
13806
+ const [permissionStatus, setPermissionStatus] = useState27("loading");
13807
+ const [userPermissionRole, setUserPermissionRole] = useState27(null);
13808
+ const [viewMembers, setViewMembers] = useState27([]);
13809
+ const [isInitialized, setIsInitialized] = useState27(false);
13810
+ const [sceneVersion, setSceneVersion] = useState27(0);
13811
+ const [contextMenu, setContextMenu] = useState27({
13849
13812
  visible: false,
13850
13813
  x: 0,
13851
13814
  y: 0,
13852
13815
  nodeData: null
13853
13816
  });
13854
- const [multiContextMenu, setMultiContextMenu] = useState28({
13817
+ const [multiContextMenu, setMultiContextMenu] = useState27({
13855
13818
  visible: false,
13856
13819
  x: 0,
13857
13820
  y: 0,
13858
13821
  nodeIds: null
13859
13822
  });
13860
- const [relationshipMenu, setRelationshipMenu] = useState28({
13823
+ const [relationshipMenu, setRelationshipMenu] = useState27({
13861
13824
  visible: false,
13862
13825
  x: 0,
13863
13826
  y: 0,
13864
13827
  linkObject: null
13865
13828
  });
13866
- const [creationMode, setCreationMode] = useState28({
13829
+ const [creationMode, setCreationMode] = useState27({
13867
13830
  isActive: false,
13868
13831
  sourceNodeData: null
13869
13832
  });
13870
- const [versionMode, setVersionMode] = useState28({
13833
+ const [versionMode, setVersionMode] = useState27({
13871
13834
  isActive: false,
13872
13835
  sourceNodeData: null
13873
13836
  });
13874
- const [questMode, setQuestMode] = useState28({ isActive: false });
13875
- const [hasFocusedInitial, setHasFocusedInitial] = useState28(false);
13876
- const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState28(false);
13877
- const [ancestryMode, setAncestryMode] = useState28({
13837
+ const [questMode, setQuestMode] = useState27({ isActive: false });
13838
+ const [hasFocusedInitial, setHasFocusedInitial] = useState27(false);
13839
+ const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState27(false);
13840
+ const [ancestryMode, setAncestryMode] = useState27({
13878
13841
  isActive: false,
13879
13842
  tree: null,
13880
13843
  selectedParentId: null,
@@ -13885,38 +13848,38 @@ function XViewScene({
13885
13848
  ancestryDescriptionSections: [],
13886
13849
  isAddingNodes: false
13887
13850
  });
13888
- const [readingMode, setReadingMode] = useState28({
13851
+ const [readingMode, setReadingMode] = useState27({
13889
13852
  isActive: false,
13890
13853
  ancestry: null,
13891
13854
  branchStack: [],
13892
13855
  autoAbstraction: false
13893
13856
  });
13894
- const [formPosition, setFormPosition] = useState28({
13857
+ const [formPosition, setFormPosition] = useState27({
13895
13858
  left: 16,
13896
13859
  top: 16,
13897
13860
  opacity: 0
13898
13861
  });
13899
- const [detailsNode, setDetailsNode] = useState28(null);
13900
- const [detailsLink, setDetailsLink] = useState28(null);
13901
- const [ancestryLinkDetails, setAncestryLinkDetails] = useState28(null);
13902
- const [imageViewer, setImageViewer] = useState28({
13862
+ const [detailsNode, setDetailsNode] = useState27(null);
13863
+ const [detailsLink, setDetailsLink] = useState27(null);
13864
+ const [ancestryLinkDetails, setAncestryLinkDetails] = useState27(null);
13865
+ const [imageViewer, setImageViewer] = useState27({
13903
13866
  visible: false,
13904
13867
  images: [],
13905
13868
  startIndex: 0
13906
13869
  });
13907
- const [editingAncestryRel, setEditingAncestryRel] = useState28({
13870
+ const [editingAncestryRel, setEditingAncestryRel] = useState27({
13908
13871
  visible: false,
13909
13872
  data: null,
13910
13873
  path: null
13911
13874
  });
13912
- const [isImportModalOpen, setIsImportModalOpen] = useState28(false);
13913
- const [importSuccessMessage, setImportSuccessMessage] = useState28("");
13914
- const [invalidTargetError, setInvalidTargetError] = useState28(null);
13915
- const [highlightedNodeId, setHighlightedNodeId] = useState28(null);
13916
- const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState28(false);
13917
- const [ancestryBoardData, setAncestryBoardData] = useState28([]);
13918
- const [isSidebarOpen, setIsSidebarOpen] = useState28(false);
13919
- const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = useState28(false);
13875
+ const [isImportModalOpen, setIsImportModalOpen] = useState27(false);
13876
+ const [importSuccessMessage, setImportSuccessMessage] = useState27("");
13877
+ const [invalidTargetError, setInvalidTargetError] = useState27(null);
13878
+ const [highlightedNodeId, setHighlightedNodeId] = useState27(null);
13879
+ const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState27(false);
13880
+ const [ancestryBoardData, setAncestryBoardData] = useState27([]);
13881
+ const [isSidebarOpen, setIsSidebarOpen] = useState27(false);
13882
+ const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = useState27(false);
13920
13883
  const mountRef = useRef19(null);
13921
13884
  const tooltipRef = useRef19(null);
13922
13885
  const formRef = useRef19(null);
@@ -13984,10 +13947,10 @@ function XViewScene({
13984
13947
  minWidth: 320,
13985
13948
  maxWidth: maxReadPanelW
13986
13949
  });
13987
- useEffect24(() => {
13950
+ useEffect22(() => {
13988
13951
  stateRef.current.ancestry = ancestryMode;
13989
13952
  }, [ancestryMode]);
13990
- useEffect24(() => {
13953
+ useEffect22(() => {
13991
13954
  var _a2;
13992
13955
  if (!isInitialized) return;
13993
13956
  const map = /* @__PURE__ */ new Map();
@@ -14549,7 +14512,7 @@ function XViewScene({
14549
14512
  }
14550
14513
  });
14551
14514
  }, []);
14552
- useEffect24(() => {
14515
+ useEffect22(() => {
14553
14516
  async function fetchAllData(configPath, ownerId2) {
14554
14517
  var _a2, _b2;
14555
14518
  if (!get_scene_view_data) {
@@ -14914,7 +14877,7 @@ function XViewScene({
14914
14877
  camTween.start();
14915
14878
  }
14916
14879
  }, [addOrUpdateNodeMesh]);
14917
- useEffect24(() => {
14880
+ useEffect22(() => {
14918
14881
  if (!isInitialized || !sceneDataRef.current) return;
14919
14882
  const currentMount = mountRef.current;
14920
14883
  if (!currentMount) return;
@@ -15918,7 +15881,7 @@ function XViewScene({
15918
15881
  };
15919
15882
  });
15920
15883
  }, []);
15921
- const actionHandlerContext = useMemo13(
15884
+ const actionHandlerContext = useMemo12(
15922
15885
  () => {
15923
15886
  var _a2;
15924
15887
  return {
@@ -16147,13 +16110,15 @@ function XViewScene({
16147
16110
  try {
16148
16111
  await actions.save_view_data(sceneSaveUrl2, sceneFileData);
16149
16112
  sceneDataRef2.current.quest_counter = currentCounter + 1;
16150
- sceneDataRef2.current.quest_nodes = sceneFileData.quest_nodes;
16151
- sceneDataRef2.current.quest_links = sceneFileData.quest_links;
16152
16113
  stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
16153
16114
  parentFileId: sceneConfigId2,
16154
16115
  ownerId: ownerId2,
16155
16116
  datasetName: "Quests Internas (View)"
16156
16117
  });
16118
+ sceneDataRef2.current.quest_nodes = [...graphDataRef.current[sceneConfigId2].nodes];
16119
+ if (parentDataRef.current[sceneConfigId2]) {
16120
+ parentDataRef.current[sceneConfigId2].nodes = [...graphDataRef.current[sceneConfigId2].nodes];
16121
+ }
16157
16122
  const finalPosition = stateRef2.current.ghostElements.node ? stateRef2.current.ghostElements.node.position.clone() : stateRef2.current.controls.target.clone();
16158
16123
  const { graphGroup, ghostElements } = stateRef2.current;
16159
16124
  if (ghostElements.node && graphGroup) {
@@ -17027,7 +16992,7 @@ function XViewScene({
17027
16992
  }
17028
16993
  setHighlightedNodeId(nodeId);
17029
16994
  }, []);
17030
- const activeNodeBranches = useMemo13(() => {
16995
+ const activeNodeBranches = useMemo12(() => {
17031
16996
  if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree)
17032
16997
  return null;
17033
16998
  const fullTree = buildFullAncestryTree(
@@ -17071,7 +17036,7 @@ function XViewScene({
17071
17036
  readingMode.branchStack,
17072
17037
  ancestryDataRef.current
17073
17038
  ]);
17074
- const backNavigationInfo = useMemo13(() => {
17039
+ const backNavigationInfo = useMemo12(() => {
17075
17040
  const { branchStack } = readingMode;
17076
17041
  if (!branchStack || branchStack.length === 0) return null;
17077
17042
  const lastStep = branchStack[branchStack.length - 1];
@@ -17082,7 +17047,7 @@ function XViewScene({
17082
17047
  name: "Voltar para anterior"
17083
17048
  };
17084
17049
  }, [readingMode.branchStack]);
17085
- const getReadModeDisplayContext = useMemo13(() => {
17050
+ const getReadModeDisplayContext = useMemo12(() => {
17086
17051
  const { ancestry, branchStack } = readingMode;
17087
17052
  if (!ancestry) return null;
17088
17053
  if (branchStack.length === 0) {
@@ -17125,7 +17090,7 @@ function XViewScene({
17125
17090
  customProperties: branchProps
17126
17091
  };
17127
17092
  }, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
17128
- const readModeAbstractionTree = useMemo13(() => {
17093
+ const readModeAbstractionTree = useMemo12(() => {
17129
17094
  if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
17130
17095
  return null;
17131
17096
  }
@@ -17742,19 +17707,13 @@ function XViewScene({
17742
17707
  (item) => {
17743
17708
  setIsAncestryBoardOpen(false);
17744
17709
  setIsSidebarOpen(false);
17745
- if (item.type === "ancestry" || !item.type) {
17710
+ if (item.type === "ancestry") {
17746
17711
  handleStartReadingAncestry(item);
17747
17712
  } else {
17748
- const nodeId = String(item.id);
17749
- const sceneMesh = stateRef.current.nodeObjects[nodeId];
17750
- if (sceneMesh) {
17751
- tweenToTarget(sceneMesh);
17752
- } else {
17753
- console.warn("Objeto n\xE3o encontrado na cena para foco:", nodeId);
17754
- }
17713
+ handleOpenReference({ type: "node", id: item.id });
17755
17714
  }
17756
17715
  },
17757
- [handleStartReadingAncestry, tweenToTarget]
17716
+ [handleStartReadingAncestry, handleOpenReference]
17758
17717
  );
17759
17718
  const handleSaveAncestryBoard = useCallback4(
17760
17719
  async (groups) => {
@@ -17770,7 +17729,7 @@ function XViewScene({
17770
17729
  },
17771
17730
  [sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]
17772
17731
  );
17773
- const existingNodeTypes = useMemo13(() => {
17732
+ const existingNodeTypes = useMemo12(() => {
17774
17733
  if (!parentDataRef.current) {
17775
17734
  return [];
17776
17735
  }
@@ -17782,27 +17741,21 @@ function XViewScene({
17782
17741
  ).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
17783
17742
  return [...new Set(allTypes)];
17784
17743
  }, [parentDataRef.current, sceneVersion]);
17785
- const searchableDbNodes = useMemo13(() => {
17786
- var _a2;
17744
+ const searchableDbNodes = useMemo12(() => {
17787
17745
  if (!parentDataRef.current) {
17788
17746
  return [];
17789
17747
  }
17790
- const datasetsPool = Object.entries(parentDataRef.current).flatMap(([dbId, fileData]) => {
17748
+ return Object.entries(parentDataRef.current).flatMap(([dbId, fileData]) => {
17791
17749
  const datasetName = fileData.dataset_name || `Dataset #${dbId.substring(0, 6)}`;
17792
17750
  return (fileData.nodes || []).map((node) => ({
17793
17751
  ...node,
17794
17752
  dataset_name: datasetName
17795
17753
  }));
17754
+ }).filter((node) => {
17755
+ var _a2;
17756
+ return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
17796
17757
  });
17797
- const questsPool = (((_a2 = sceneDataRef.current) == null ? void 0 : _a2.quest_nodes) || []).map((node) => ({
17798
- ...node,
17799
- dataset_name: "Quests Internas (View)"
17800
- }));
17801
- return [...datasetsPool, ...questsPool].filter((node) => {
17802
- var _a3;
17803
- return !((_a3 = node.version_node) == null ? void 0 : _a3.is_version);
17804
- });
17805
- }, [parentDataRef.current, (_b = sceneDataRef.current) == null ? void 0 : _b.quest_nodes, sceneVersion]);
17758
+ }, [parentDataRef.current, sceneVersion]);
17806
17759
  const handleAddExistingNode = useCallback4(
17807
17760
  (nodeId) => {
17808
17761
  return userActionHandlers.handleAddExistingNodeById(
@@ -17901,13 +17854,13 @@ function XViewScene({
17901
17854
  console.error("Erro na chamada de save_view_data:", error);
17902
17855
  }
17903
17856
  }, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
17904
- const allAvailableNodes = useMemo13(() => {
17857
+ const allAvailableNodes = useMemo12(() => {
17905
17858
  if (!parentDataRef.current) return [];
17906
17859
  return Object.values(parentDataRef.current).flatMap(
17907
17860
  (fileData) => fileData.nodes || []
17908
17861
  );
17909
17862
  }, [sceneVersion, isInitialized]);
17910
- const allAvailableAncestries = useMemo13(() => {
17863
+ const allAvailableAncestries = useMemo12(() => {
17911
17864
  return ancestryDataRef.current || [];
17912
17865
  }, [sceneVersion, isInitialized]);
17913
17866
  const handleOpenReference = useCallback4(
@@ -17971,7 +17924,7 @@ function XViewScene({
17971
17924
  },
17972
17925
  [tweenToTarget]
17973
17926
  );
17974
- const availableDatasets = useMemo13(() => {
17927
+ const availableDatasets = useMemo12(() => {
17975
17928
  if (!sceneDataRef.current || !parentDataRef.current) return [];
17976
17929
  return sceneDataRef.current.parent_dbs.map((db) => {
17977
17930
  var _a2;
@@ -17981,11 +17934,11 @@ function XViewScene({
17981
17934
  };
17982
17935
  });
17983
17936
  }, [sceneVersion, isInitialized]);
17984
- const sourceNodeDatasetId = creationMode.sourceNodeData ? (_c = stateRef.current.nodeIdToParentFileMap.get(
17937
+ const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(
17985
17938
  String(creationMode.sourceNodeData.id)
17986
- )) == null ? void 0 : _c.parentFileId : null;
17939
+ )) == null ? void 0 : _b.parentFileId : null;
17987
17940
  const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
17988
- useEffect24(() => {
17941
+ useEffect22(() => {
17989
17942
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
17990
17943
  const nodeObjects = stateRef.current.nodeObjects || {};
17991
17944
  const targetMesh = nodeObjects[String(focusNodeId)];
@@ -18008,7 +17961,7 @@ function XViewScene({
18008
17961
  hasFocusedInitial,
18009
17962
  tweenToTarget
18010
17963
  ]);
18011
- useEffect24(() => {
17964
+ useEffect22(() => {
18012
17965
  if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
18013
17966
  const ancestries = ancestryDataRef.current || [];
18014
17967
  const targetAncestry = ancestries.find(
@@ -18033,7 +17986,7 @@ function XViewScene({
18033
17986
  hasOpenedInitialAncestry,
18034
17987
  handleStartReadingAncestry
18035
17988
  ]);
18036
- useEffect24(() => {
17989
+ useEffect22(() => {
18037
17990
  function handleKeyDown(event) {
18038
17991
  var _a2, _b2, _c2;
18039
17992
  const context = actionHandlerContext;
@@ -18156,10 +18109,10 @@ function XViewScene({
18156
18109
  // <-- handleCancelQuest adicionado aqui
18157
18110
  ]);
18158
18111
  if (isLoading || status === "loading" || permissionStatus === "loading") {
18159
- return /* @__PURE__ */ React30.createElement(LoadingScreen, null);
18112
+ return /* @__PURE__ */ React28.createElement(LoadingScreen, null);
18160
18113
  }
18161
18114
  if (permissionStatus === "denied") {
18162
- 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(
18115
+ return /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ React28.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ React28.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ React28.createElement(
18163
18116
  "svg",
18164
18117
  {
18165
18118
  xmlns: "http://www.w3.org/2000/svg",
@@ -18169,7 +18122,7 @@ function XViewScene({
18169
18122
  stroke: "currentColor",
18170
18123
  className: "w-16 h-16 mx-auto"
18171
18124
  },
18172
- /* @__PURE__ */ React30.createElement(
18125
+ /* @__PURE__ */ React28.createElement(
18173
18126
  "path",
18174
18127
  {
18175
18128
  strokeLinecap: "round",
@@ -18177,13 +18130,13 @@ function XViewScene({
18177
18130
  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"
18178
18131
  }
18179
18132
  )
18180
- )), /* @__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(
18133
+ )), /* @__PURE__ */ React28.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ React28.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__ */ React28.createElement(
18181
18134
  "button",
18182
18135
  {
18183
18136
  onClick: () => router.push("/dashboard/scenes"),
18184
18137
  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"
18185
18138
  },
18186
- /* @__PURE__ */ React30.createElement(
18139
+ /* @__PURE__ */ React28.createElement(
18187
18140
  "svg",
18188
18141
  {
18189
18142
  xmlns: "http://www.w3.org/2000/svg",
@@ -18193,7 +18146,7 @@ function XViewScene({
18193
18146
  stroke: "currentColor",
18194
18147
  className: "w-5 h-5"
18195
18148
  },
18196
- /* @__PURE__ */ React30.createElement(
18149
+ /* @__PURE__ */ React28.createElement(
18197
18150
  "path",
18198
18151
  {
18199
18152
  strokeLinecap: "round",
@@ -18205,7 +18158,7 @@ function XViewScene({
18205
18158
  "Voltar para Scenes"
18206
18159
  )));
18207
18160
  }
18208
- return /* @__PURE__ */ React30.createElement(
18161
+ return /* @__PURE__ */ React28.createElement(
18209
18162
  "div",
18210
18163
  {
18211
18164
  ref: mountRef,
@@ -18217,7 +18170,7 @@ function XViewScene({
18217
18170
  cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
18218
18171
  }
18219
18172
  },
18220
- userPermissionRole !== "link_viewer" && /* @__PURE__ */ React30.createElement(
18173
+ userPermissionRole !== "link_viewer" && /* @__PURE__ */ React28.createElement(
18221
18174
  XViewSidebar,
18222
18175
  {
18223
18176
  dbNodes: searchableDbNodes,
@@ -18237,11 +18190,11 @@ function XViewScene({
18237
18190
  onToggle: setIsSidebarOpen,
18238
18191
  userRole: userPermissionRole,
18239
18192
  viewMembers,
18240
- milestones: ((_d = sceneDataRef.current) == null ? void 0 : _d.milestones) || [],
18193
+ milestones: ((_c = sceneDataRef.current) == null ? void 0 : _c.milestones) || [],
18241
18194
  onOpenMilestoneManager: () => setIsMilestoneManagerOpen(true)
18242
18195
  }
18243
18196
  ),
18244
- creationMode.isActive && /* @__PURE__ */ React30.createElement(
18197
+ creationMode.isActive && /* @__PURE__ */ React28.createElement(
18245
18198
  InSceneCreationForm,
18246
18199
  {
18247
18200
  onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
@@ -18262,8 +18215,8 @@ function XViewScene({
18262
18215
  },
18263
18216
  refEl: formRef,
18264
18217
  existingTypes: existingNodeTypes,
18265
- initialColor: (_e = creationMode.sourceNodeData) == null ? void 0 : _e.color,
18266
- sourceTypes: (_f = creationMode.sourceNodeData) == null ? void 0 : _f.type,
18218
+ initialColor: (_d = creationMode.sourceNodeData) == null ? void 0 : _d.color,
18219
+ sourceTypes: (_e = creationMode.sourceNodeData) == null ? void 0 : _e.type,
18267
18220
  onIntensityChange: handleGhostNodeIntensityChange,
18268
18221
  onUploadFile: upload_file_action,
18269
18222
  availableDatasets,
@@ -18273,7 +18226,7 @@ function XViewScene({
18273
18226
  availableAncestries: allAvailableAncestries
18274
18227
  }
18275
18228
  ),
18276
- versionMode.isActive && /* @__PURE__ */ React30.createElement(
18229
+ versionMode.isActive && /* @__PURE__ */ React28.createElement(
18277
18230
  InSceneVersionForm,
18278
18231
  {
18279
18232
  onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
@@ -18292,14 +18245,14 @@ function XViewScene({
18292
18245
  transition: "opacity 200ms ease-out"
18293
18246
  },
18294
18247
  refEl: formRef,
18295
- fixedType: (_g = versionMode.sourceNodeData) == null ? void 0 : _g.type,
18296
- fixedColor: (_h = versionMode.sourceNodeData) == null ? void 0 : _h.color,
18248
+ fixedType: (_f = versionMode.sourceNodeData) == null ? void 0 : _f.type,
18249
+ fixedColor: (_g = versionMode.sourceNodeData) == null ? void 0 : _g.color,
18297
18250
  onUploadFile: upload_file_action,
18298
18251
  availableNodes: allAvailableNodes,
18299
18252
  availableAncestries: allAvailableAncestries
18300
18253
  }
18301
18254
  ),
18302
- questMode.isActive && /* @__PURE__ */ React30.createElement(
18255
+ questMode.isActive && /* @__PURE__ */ React28.createElement(
18303
18256
  InSceneQuestForm,
18304
18257
  {
18305
18258
  onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
@@ -18321,13 +18274,13 @@ function XViewScene({
18321
18274
  availableNodes: allAvailableNodes,
18322
18275
  availableAncestries: allAvailableAncestries,
18323
18276
  viewName: viewParams == null ? void 0 : viewParams.name,
18324
- questCounter: ((_i = sceneDataRef.current) == null ? void 0 : _i.quest_counter) || 1,
18277
+ questCounter: ((_h = sceneDataRef.current) == null ? void 0 : _h.quest_counter) || 1,
18325
18278
  viewMembers,
18326
- milestones: ((_j = sceneDataRef.current) == null ? void 0 : _j.milestones) || [],
18279
+ milestones: ((_i = sceneDataRef.current) == null ? void 0 : _i.milestones) || [],
18327
18280
  onUpdateMilestones: handleUpdateMilestones
18328
18281
  }
18329
18282
  ),
18330
- readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React30.createElement(
18283
+ readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React28.createElement(
18331
18284
  "div",
18332
18285
  {
18333
18286
  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"}`,
@@ -18340,7 +18293,7 @@ function XViewScene({
18340
18293
  maxWidth: "92vw"
18341
18294
  }
18342
18295
  },
18343
- /* @__PURE__ */ React30.createElement(
18296
+ /* @__PURE__ */ React28.createElement(
18344
18297
  "div",
18345
18298
  {
18346
18299
  onPointerDown: (e) => {
@@ -18351,7 +18304,7 @@ function XViewScene({
18351
18304
  title: "Arraste para redimensionar"
18352
18305
  }
18353
18306
  ),
18354
- /* @__PURE__ */ React30.createElement(
18307
+ /* @__PURE__ */ React28.createElement(
18355
18308
  DescriptionReadModePanel,
18356
18309
  {
18357
18310
  key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
@@ -18386,7 +18339,7 @@ function XViewScene({
18386
18339
  }
18387
18340
  )
18388
18341
  ),
18389
- ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ React30.createElement(
18342
+ ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ React28.createElement(
18390
18343
  CreateAncestryPanel,
18391
18344
  {
18392
18345
  ancestryMode,
@@ -18422,7 +18375,7 @@ function XViewScene({
18422
18375
  onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
18423
18376
  }
18424
18377
  ),
18425
- editingAncestryRel.visible && /* @__PURE__ */ React30.createElement(
18378
+ editingAncestryRel.visible && /* @__PURE__ */ React28.createElement(
18426
18379
  AncestryRelationshipPanel,
18427
18380
  {
18428
18381
  data: editingAncestryRel.data,
@@ -18436,7 +18389,7 @@ function XViewScene({
18436
18389
  onUploadFile: upload_file_action
18437
18390
  }
18438
18391
  ),
18439
- detailsNode && detailsNode.is_quest && /* @__PURE__ */ React30.createElement(
18392
+ detailsNode && detailsNode.is_quest && /* @__PURE__ */ React28.createElement(
18440
18393
  QuestDetailsPanel,
18441
18394
  {
18442
18395
  node: detailsNode,
@@ -18458,11 +18411,11 @@ function XViewScene({
18458
18411
  currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName,
18459
18412
  viewMembers,
18460
18413
  currentUser: session == null ? void 0 : session.user,
18461
- milestones: ((_k = sceneDataRef.current) == null ? void 0 : _k.milestones) || [],
18414
+ milestones: ((_j = sceneDataRef.current) == null ? void 0 : _j.milestones) || [],
18462
18415
  onUpdateMilestones: handleUpdateMilestones
18463
18416
  }
18464
18417
  ),
18465
- detailsNode && !detailsNode.is_quest && /* @__PURE__ */ React30.createElement(
18418
+ detailsNode && !detailsNode.is_quest && /* @__PURE__ */ React28.createElement(
18466
18419
  NodeDetailsPanel,
18467
18420
  {
18468
18421
  node: detailsNode,
@@ -18494,7 +18447,7 @@ function XViewScene({
18494
18447
  currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
18495
18448
  }
18496
18449
  ),
18497
- detailsLink && /* @__PURE__ */ React30.createElement(
18450
+ detailsLink && /* @__PURE__ */ React28.createElement(
18498
18451
  RelationshipDetailsPanel,
18499
18452
  {
18500
18453
  link: detailsLink,
@@ -18508,7 +18461,7 @@ function XViewScene({
18508
18461
  userRole: userPermissionRole
18509
18462
  }
18510
18463
  ),
18511
- ancestryLinkDetails && /* @__PURE__ */ React30.createElement(
18464
+ ancestryLinkDetails && /* @__PURE__ */ React28.createElement(
18512
18465
  AncestryLinkDetailsPanel,
18513
18466
  {
18514
18467
  data: ancestryLinkDetails,
@@ -18519,7 +18472,7 @@ function XViewScene({
18519
18472
  onUploadFile: upload_file_action
18520
18473
  }
18521
18474
  ),
18522
- /* @__PURE__ */ React30.createElement(
18475
+ /* @__PURE__ */ React28.createElement(
18523
18476
  "div",
18524
18477
  {
18525
18478
  ref: tooltipRef,
@@ -18546,7 +18499,7 @@ function XViewScene({
18546
18499
  }
18547
18500
  }
18548
18501
  ),
18549
- /* @__PURE__ */ React30.createElement(
18502
+ /* @__PURE__ */ React28.createElement(
18550
18503
  ContextMenu,
18551
18504
  {
18552
18505
  data: contextMenu,
@@ -18579,7 +18532,7 @@ function XViewScene({
18579
18532
  onFinishQuest: handleFinishQuestQuick
18580
18533
  }
18581
18534
  ),
18582
- /* @__PURE__ */ React30.createElement(
18535
+ /* @__PURE__ */ React28.createElement(
18583
18536
  MultiNodeContextMenu,
18584
18537
  {
18585
18538
  data: multiContextMenu,
@@ -18599,7 +18552,7 @@ function XViewScene({
18599
18552
  )
18600
18553
  }
18601
18554
  ),
18602
- /* @__PURE__ */ React30.createElement(
18555
+ /* @__PURE__ */ React28.createElement(
18603
18556
  RelationshipContextMenu,
18604
18557
  {
18605
18558
  data: relationshipMenu,
@@ -18617,14 +18570,14 @@ function XViewScene({
18617
18570
  onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
18618
18571
  }
18619
18572
  ),
18620
- /* @__PURE__ */ React30.createElement(
18573
+ /* @__PURE__ */ React28.createElement(
18621
18574
  ImageViewer,
18622
18575
  {
18623
18576
  data: imageViewer,
18624
18577
  onClose: () => setImageViewer({ ...imageViewer, visible: false })
18625
18578
  }
18626
18579
  ),
18627
- /* @__PURE__ */ React30.createElement(
18580
+ /* @__PURE__ */ React28.createElement(
18628
18581
  AncestryBoard,
18629
18582
  {
18630
18583
  isOpen: isAncestryBoardOpen,
@@ -18637,29 +18590,29 @@ function XViewScene({
18637
18590
  userRole: userPermissionRole
18638
18591
  }
18639
18592
  ),
18640
- /* @__PURE__ */ React30.createElement(
18593
+ /* @__PURE__ */ React28.createElement(
18641
18594
  MilestoneManager,
18642
18595
  {
18643
18596
  isOpen: isMilestoneManagerOpen,
18644
18597
  onClose: () => setIsMilestoneManagerOpen(false),
18645
- milestones: ((_l = sceneDataRef.current) == null ? void 0 : _l.milestones) || [],
18598
+ milestones: ((_k = sceneDataRef.current) == null ? void 0 : _k.milestones) || [],
18646
18599
  onUpdateMilestones: handleUpdateMilestones
18647
18600
  }
18648
18601
  ),
18649
- /* @__PURE__ */ React30.createElement(
18602
+ /* @__PURE__ */ React28.createElement(
18650
18603
  ImportParentFileModal,
18651
18604
  {
18652
18605
  isOpen: isImportModalOpen,
18653
18606
  onClose: () => setIsImportModalOpen(false),
18654
18607
  onConfirm: handleConfirmImport,
18655
18608
  session,
18656
- parentDbs: ((_m = sceneDataRef.current) == null ? void 0 : _m.parent_dbs) || [],
18609
+ parentDbs: ((_l = sceneDataRef.current) == null ? void 0 : _l.parent_dbs) || [],
18657
18610
  onFetchAvailableFiles: import_parent_file_modal_get,
18658
18611
  currentViewName: viewParams == null ? void 0 : viewParams.name,
18659
18612
  currentAncestries: ancestryDataRef.current || []
18660
18613
  }
18661
18614
  ),
18662
- invalidTargetError && /* @__PURE__ */ React30.createElement(
18615
+ invalidTargetError && /* @__PURE__ */ React28.createElement(
18663
18616
  "div",
18664
18617
  {
18665
18618
  className: "ui-overlay",
@@ -18684,13 +18637,13 @@ function XViewScene({
18684
18637
  animation: "fadeInDown 0.5s cubic-bezier(0.16, 1, 0.3, 1)"
18685
18638
  }
18686
18639
  },
18687
- /* @__PURE__ */ React30.createElement("style", null, `
18640
+ /* @__PURE__ */ React28.createElement("style", null, `
18688
18641
  @keyframes fadeInDown {
18689
18642
  from { opacity: 0; transform: translate(-50%, -20px); }
18690
18643
  to { opacity: 1; transform: translate(-50%, 0); }
18691
18644
  }
18692
18645
  `),
18693
- /* @__PURE__ */ React30.createElement(
18646
+ /* @__PURE__ */ React28.createElement(
18694
18647
  "svg",
18695
18648
  {
18696
18649
  width: "20",
@@ -18702,12 +18655,12 @@ function XViewScene({
18702
18655
  strokeLinecap: "round",
18703
18656
  strokeLinejoin: "round"
18704
18657
  },
18705
- /* @__PURE__ */ React30.createElement("circle", { cx: "12", cy: "12", r: "10" }),
18706
- /* @__PURE__ */ React30.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
18707
- /* @__PURE__ */ React30.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
18658
+ /* @__PURE__ */ React28.createElement("circle", { cx: "12", cy: "12", r: "10" }),
18659
+ /* @__PURE__ */ React28.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
18660
+ /* @__PURE__ */ React28.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
18708
18661
  ),
18709
- /* @__PURE__ */ React30.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
18710
- /* @__PURE__ */ React30.createElement(
18662
+ /* @__PURE__ */ React28.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
18663
+ /* @__PURE__ */ React28.createElement(
18711
18664
  "button",
18712
18665
  {
18713
18666
  onClick: () => setInvalidTargetError(null),