@lv-x-software-house/x_view 1.2.5-dev.47 → 1.2.5-dev.49

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.
Files changed (3) hide show
  1. package/dist/index.js +283 -223
  2. package/dist/index.mjs +213 -153
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -44,9 +44,9 @@ __export(index_exports, {
44
44
  module.exports = __toCommonJS(index_exports);
45
45
 
46
46
  // src/XViewScene.jsx
47
- var import_react28 = __toESM(require("react"));
47
+ var import_react29 = __toESM(require("react"));
48
48
  var import_navigation = require("next/navigation");
49
- var import_react29 = require("next-auth/react");
49
+ var import_react30 = require("next-auth/react");
50
50
  var import_crypto_js = __toESM(require("crypto-js"));
51
51
  var THREE3 = __toESM(require("three"));
52
52
  var import_OrbitControls = require("three/examples/jsm/controls/OrbitControls.js");
@@ -627,14 +627,13 @@ function XViewSidebar({
627
627
  onActivateQuestLens = () => {
628
628
  },
629
629
  milestones = [],
630
- onUpdateMilestones = () => {
630
+ onOpenMilestoneManager = () => {
631
631
  }
632
632
  }) {
633
633
  const [query, setQuery] = (0, import_react2.useState)("");
634
634
  const [showList, setShowList] = (0, import_react2.useState)(false);
635
635
  const [selectedNodeId, setSelectedNodeId] = (0, import_react2.useState)(null);
636
636
  const [isSaving, setIsSaving] = (0, import_react2.useState)(false);
637
- const [newMilestoneName, setNewMilestoneName] = (0, import_react2.useState)("");
638
637
  const [activeFilters, setActiveFilters] = (0, import_react2.useState)([]);
639
638
  const [isFilterMenuOpen, setIsFilterMenuOpen] = (0, import_react2.useState)(false);
640
639
  const [filterCategory, setFilterCategory] = (0, import_react2.useState)("Type");
@@ -846,28 +845,6 @@ function XViewSidebar({
846
845
  setIsTypeDropdownOpen(false);
847
846
  }
848
847
  };
849
- const handleAddMilestone = () => {
850
- if (!newMilestoneName.trim()) return;
851
- const newMilestone = {
852
- id: `ms_${Date.now()}`,
853
- name: newMilestoneName.trim(),
854
- status: "active"
855
- };
856
- onUpdateMilestones([...milestones, newMilestone]);
857
- setNewMilestoneName("");
858
- };
859
- const handleToggleMilestoneStatus = (id) => {
860
- const updated = milestones.map(
861
- (ms) => ms.id === id ? { ...ms, status: ms.status === "active" ? "inactive" : "active" } : ms
862
- );
863
- onUpdateMilestones(updated);
864
- };
865
- const handleRemoveMilestone = (id) => {
866
- var _a;
867
- if (!confirm(`Deseja remover o milestone "${(_a = milestones.find((m) => m.id === id)) == null ? void 0 : _a.name}"?`)) return;
868
- const updated = milestones.filter((ms) => ms.id !== id);
869
- onUpdateMilestones(updated);
870
- };
871
848
  const ToggleButton = /* @__PURE__ */ import_react2.default.createElement(
872
849
  "button",
873
850
  {
@@ -1059,25 +1036,7 @@ function XViewSidebar({
1059
1036
  },
1060
1037
  /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), /* @__PURE__ */ import_react2.default.createElement("polyline", { points: "17 8 12 3 7 8" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "12", y1: "3", x2: "12", y2: "15" })),
1061
1038
  "Importar arquivo"
1062
- ), /* @__PURE__ */ import_react2.default.createElement("p", { className: "mt-1.5 text-xs text-slate-400 text-center px-1 leading-tight" }, "Importar datasets ou ancestralidades das views."), /* @__PURE__ */ import_react2.default.createElement("div", { className: "h-9 mt-1 flex items-center justify-center" }, importSuccessMessage && /* @__PURE__ */ import_react2.default.createElement("p", { className: "w-full text-center text-xs font-medium text-indigo-300 bg-indigo-500/10 border border-indigo-500/20 rounded-md py-1.5 px-2" }, importSuccessMessage)))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "h-px bg-white/10" }), /* @__PURE__ */ import_react2.default.createElement("section", { className: "space-y-2" }, /* @__PURE__ */ import_react2.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Lentes"), /* @__PURE__ */ import_react2.default.createElement(
1063
- "button",
1064
- {
1065
- onClick: onActivateTimeline,
1066
- className: buttonBaseClass,
1067
- title: "Ativar a visualiza\xE7\xE3o de Timeline"
1068
- },
1069
- /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react2.default.createElement("polyline", { points: "12 6 12 12 16 14" })),
1070
- "Timeline"
1071
- ), /* @__PURE__ */ import_react2.default.createElement(
1072
- "button",
1073
- {
1074
- onClick: onOpenAncestryBoard,
1075
- className: buttonBaseClass,
1076
- title: "Abrir painel de Ancestralidades"
1077
- },
1078
- /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("polygon", { points: "12 2 2 7 12 12 22 7 12 2" }), /* @__PURE__ */ import_react2.default.createElement("polyline", { points: "2 17 12 22 22 17" }), /* @__PURE__ */ import_react2.default.createElement("polyline", { points: "2 12 12 17 22 12" })),
1079
- "Ancestry Board"
1080
- ), /* @__PURE__ */ import_react2.default.createElement("div", { className: "relative", ref: questLensRef }, /* @__PURE__ */ import_react2.default.createElement(
1039
+ ), /* @__PURE__ */ import_react2.default.createElement("p", { className: "mt-1.5 text-xs text-slate-400 text-center px-1 leading-tight" }, "Importar datasets ou ancestralidades das views."), /* @__PURE__ */ import_react2.default.createElement("div", { className: "h-9 mt-1 flex items-center justify-center" }, importSuccessMessage && /* @__PURE__ */ import_react2.default.createElement("p", { className: "w-full text-center text-xs font-medium text-indigo-300 bg-indigo-500/10 border border-indigo-500/20 rounded-md py-1.5 px-2" }, importSuccessMessage)))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "h-px bg-white/10" }), /* @__PURE__ */ import_react2.default.createElement("section", { className: "space-y-2" }, /* @__PURE__ */ import_react2.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Lentes"), /* @__PURE__ */ import_react2.default.createElement("div", { className: "relative", ref: questLensRef }, /* @__PURE__ */ import_react2.default.createElement(
1081
1040
  "button",
1082
1041
  {
1083
1042
  onClick: () => setIsQuestLensMenuOpen(!isQuestLensMenuOpen),
@@ -1129,54 +1088,35 @@ function XViewSidebar({
1129
1088
  className: "flex-[2] py-2 bg-indigo-600 hover:bg-indigo-500 text-white text-[11px] font-bold rounded-lg shadow-lg shadow-indigo-500/20 transition-all hover:scale-[1.02] active:scale-95"
1130
1089
  },
1131
1090
  "Aplicar Lente"
1132
- ))))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "h-px bg-white/10" }), /* @__PURE__ */ import_react2.default.createElement("section", { className: "space-y-3" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react2.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Milestones")), /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ import_react2.default.createElement(
1133
- "input",
1091
+ )))), /* @__PURE__ */ import_react2.default.createElement(
1092
+ "button",
1134
1093
  {
1135
- type: "text",
1136
- value: newMilestoneName,
1137
- onChange: (e) => setNewMilestoneName(e.target.value),
1138
- onKeyDown: (e) => e.key === "Enter" && handleAddMilestone(),
1139
- placeholder: "Novo Milestone...",
1140
- className: "flex-1 bg-slate-900/50 border border-white/10 rounded-md px-2 py-1.5 text-xs text-slate-100 placeholder:text-slate-600 focus:outline-none focus:border-indigo-500/50"
1141
- }
1094
+ onClick: onActivateTimeline,
1095
+ className: buttonBaseClass,
1096
+ title: "Ativar a visualiza\xE7\xE3o de Timeline"
1097
+ },
1098
+ /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react2.default.createElement("polyline", { points: "12 6 12 12 16 14" })),
1099
+ "Timeline"
1142
1100
  ), /* @__PURE__ */ import_react2.default.createElement(
1143
1101
  "button",
1144
1102
  {
1145
- onClick: handleAddMilestone,
1146
- disabled: !newMilestoneName.trim(),
1147
- className: "p-1.5 rounded-md bg-indigo-500/10 hover:bg-indigo-500/20 border border-indigo-500/30 text-indigo-300 disabled:opacity-30 transition-colors"
1103
+ onClick: onOpenAncestryBoard,
1104
+ className: buttonBaseClass,
1105
+ title: "Abrir painel de Ancestralidades"
1148
1106
  },
1149
- /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("line", { x1: "12", y1: "5", x2: "12", y2: "19" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "5", y1: "12", x2: "19", y2: "12" }))
1150
- )), /* @__PURE__ */ import_react2.default.createElement("div", { className: "space-y-1.5 max-h-[200px] overflow-y-auto custom-scrollbar pr-1" }, milestones.length > 0 ? milestones.map((ms) => /* @__PURE__ */ import_react2.default.createElement(
1151
- "div",
1107
+ /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("polygon", { points: "12 2 2 7 12 12 22 7 12 2" }), /* @__PURE__ */ import_react2.default.createElement("polyline", { points: "2 17 12 22 22 17" }), /* @__PURE__ */ import_react2.default.createElement("polyline", { points: "2 12 12 17 22 12" })),
1108
+ "Ancestry Board"
1109
+ )), /* @__PURE__ */ import_react2.default.createElement("div", { className: "h-px bg-white/10" }), /* @__PURE__ */ import_react2.default.createElement("section", { className: "space-y-3" }, /* @__PURE__ */ import_react2.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Milestones"), /* @__PURE__ */ import_react2.default.createElement(
1110
+ "button",
1152
1111
  {
1153
- key: ms.id,
1154
- className: `group flex items-center justify-between px-2.5 py-2 rounded-lg border transition-all ${ms.status === "active" ? "bg-indigo-500/5 border-indigo-500/20" : "bg-slate-900/30 border-white/5 opacity-60"}`
1112
+ onClick: onOpenMilestoneManager,
1113
+ className: buttonBaseClass,
1114
+ title: "Gerenciar os milestones deste cen\xE1rio"
1155
1115
  },
1156
- /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ import_react2.default.createElement(
1157
- "div",
1158
- {
1159
- className: `w-1.5 h-1.5 rounded-full shrink-0 ${ms.status === "active" ? "bg-indigo-400 shadow-[0_0_8px_rgba(129,140,248,0.5)]" : "bg-slate-600"}`
1160
- }
1161
- ), /* @__PURE__ */ import_react2.default.createElement("span", { className: `text-[11px] truncate font-medium ${ms.status === "active" ? "text-slate-100" : "text-slate-500 line-through"}` }, ms.name)),
1162
- /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity" }, /* @__PURE__ */ import_react2.default.createElement(
1163
- "button",
1164
- {
1165
- onClick: () => handleToggleMilestoneStatus(ms.id),
1166
- className: `p-1 rounded hover:bg-white/10 transition-colors ${ms.status === "active" ? "text-slate-400" : "text-indigo-400"}`,
1167
- title: ms.status === "active" ? "Inativar" : "Ativar"
1168
- },
1169
- ms.status === "active" ? /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("rect", { x: "6", y: "4", width: "4", height: "16" }), /* @__PURE__ */ import_react2.default.createElement("rect", { x: "14", y: "4", width: "4", height: "16" })) : /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("polygon", { points: "5 3 19 12 5 21 5 3" }))
1170
- ), /* @__PURE__ */ import_react2.default.createElement(
1171
- "button",
1172
- {
1173
- onClick: () => handleRemoveMilestone(ms.id),
1174
- className: "p-1 rounded hover:bg-red-500/20 text-slate-500 hover:text-red-400 transition-colors",
1175
- title: "Remover"
1176
- },
1177
- /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react2.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" }))
1178
- ))
1179
- )) : /* @__PURE__ */ import_react2.default.createElement("p", { className: "text-[10px] text-slate-600 text-center py-2 italic font-light italic" }, "Nenhum milestone definido")))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "px-4 py-3 border-t border-white/10 bg-slate-900/30" }, /* @__PURE__ */ import_react2.default.createElement("section", { className: "space-y-2" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react2.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Navega\xE7\xE3o")), ability.can("update", "Scene") && /* @__PURE__ */ import_react2.default.createElement(
1116
+ /* @__PURE__ */ import_react2.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "12", cy: "12", r: "6" }), /* @__PURE__ */ import_react2.default.createElement("circle", { cx: "12", cy: "12", r: "2" })),
1117
+ "Gerenciar Milestones",
1118
+ milestones.length > 0 && /* @__PURE__ */ import_react2.default.createElement("span", { className: "ml-1.5 px-1.5 py-0.5 rounded-full bg-indigo-500/30 text-[10px] font-bold border border-indigo-400/30" }, milestones.length)
1119
+ ))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "px-4 py-3 border-t border-white/10 bg-slate-900/30" }, /* @__PURE__ */ import_react2.default.createElement("section", { className: "space-y-2" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react2.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Navega\xE7\xE3o")), ability.can("update", "Scene") && /* @__PURE__ */ import_react2.default.createElement(
1180
1120
  "button",
1181
1121
  {
1182
1122
  onClick: handleSaveClick,
@@ -13251,6 +13191,116 @@ function AncestryBoard({
13251
13191
  );
13252
13192
  }
13253
13193
 
13194
+ // src/components/MilestoneManager.jsx
13195
+ var import_react28 = __toESM(require("react"));
13196
+ var import_fi22 = require("react-icons/fi");
13197
+ function MilestoneManager({
13198
+ isOpen,
13199
+ onClose,
13200
+ milestones = [],
13201
+ onUpdateMilestones = () => {
13202
+ }
13203
+ }) {
13204
+ const [newMilestoneName, setNewMilestoneName] = (0, import_react28.useState)("");
13205
+ const handleAddMilestone = () => {
13206
+ if (!newMilestoneName.trim()) return;
13207
+ const newMilestone = {
13208
+ id: `ms_${Date.now()}`,
13209
+ name: newMilestoneName.trim(),
13210
+ status: "active"
13211
+ };
13212
+ onUpdateMilestones([...milestones, newMilestone]);
13213
+ setNewMilestoneName("");
13214
+ };
13215
+ const handleToggleMilestoneStatus = (id) => {
13216
+ const updated = milestones.map(
13217
+ (ms) => ms.id === id ? { ...ms, status: ms.status === "active" ? "inactive" : "active" } : ms
13218
+ );
13219
+ onUpdateMilestones(updated);
13220
+ };
13221
+ const handleRemoveMilestone = (id) => {
13222
+ var _a;
13223
+ if (!confirm(`Deseja remover o milestone "${(_a = milestones.find((m) => m.id === id)) == null ? void 0 : _a.name}"?`)) return;
13224
+ const updated = milestones.filter((ms) => ms.id !== id);
13225
+ onUpdateMilestones(updated);
13226
+ };
13227
+ if (!isOpen) return null;
13228
+ const swallow = (e) => e.stopPropagation();
13229
+ return /* @__PURE__ */ import_react28.default.createElement(
13230
+ "div",
13231
+ {
13232
+ 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",
13233
+ onClick: onClose
13234
+ },
13235
+ /* @__PURE__ */ import_react28.default.createElement(
13236
+ "div",
13237
+ {
13238
+ 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",
13239
+ onClick: swallow
13240
+ },
13241
+ /* @__PURE__ */ import_react28.default.createElement("div", { className: "px-6 py-4 border-b border-white/10 flex items-center justify-between" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "p-2 rounded-lg bg-indigo-500/20 text-indigo-400" }, /* @__PURE__ */ import_react28.default.createElement(import_fi22.FiTarget, { size: 20 })), /* @__PURE__ */ import_react28.default.createElement("div", null, /* @__PURE__ */ import_react28.default.createElement("h2", { className: "text-lg font-semibold text-slate-100" }, "Milestones"), /* @__PURE__ */ import_react28.default.createElement("p", { className: "text-xs text-slate-400" }, "Gerencie os marcos do seu cen\xE1rio"))), /* @__PURE__ */ import_react28.default.createElement(
13242
+ "button",
13243
+ {
13244
+ onClick: onClose,
13245
+ className: "p-2 rounded-full hover:bg-white/10 text-slate-400 hover:text-white transition-colors"
13246
+ },
13247
+ /* @__PURE__ */ import_react28.default.createElement(import_fi22.FiX, { size: 20 })
13248
+ )),
13249
+ /* @__PURE__ */ import_react28.default.createElement("div", { className: "px-6 py-5 bg-white/5 border-b border-white/5" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ import_react28.default.createElement(
13250
+ "input",
13251
+ {
13252
+ type: "text",
13253
+ value: newMilestoneName,
13254
+ onChange: (e) => setNewMilestoneName(e.target.value),
13255
+ onKeyDown: (e) => e.key === "Enter" && handleAddMilestone(),
13256
+ placeholder: "Adicionar novo milestone...",
13257
+ 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"
13258
+ }
13259
+ ), /* @__PURE__ */ import_react28.default.createElement(
13260
+ "button",
13261
+ {
13262
+ onClick: handleAddMilestone,
13263
+ disabled: !newMilestoneName.trim(),
13264
+ 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"
13265
+ },
13266
+ /* @__PURE__ */ import_react28.default.createElement(import_fi22.FiPlus, { size: 18 }),
13267
+ "Adicionar"
13268
+ ))),
13269
+ /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex-1 overflow-y-auto px-6 py-4 custom-scrollbar" }, milestones.length > 0 ? /* @__PURE__ */ import_react28.default.createElement("div", { className: "space-y-3" }, milestones.map((ms) => /* @__PURE__ */ import_react28.default.createElement(
13270
+ "div",
13271
+ {
13272
+ key: ms.id,
13273
+ 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]"}`
13274
+ },
13275
+ /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ import_react28.default.createElement(
13276
+ "div",
13277
+ {
13278
+ 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"}`
13279
+ }
13280
+ ), /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react28.default.createElement("span", { className: `text-sm font-medium truncate ${ms.status === "active" ? "text-slate-100" : "text-slate-400 line-through"}` }, ms.name), /* @__PURE__ */ import_react28.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-wider" }, ms.status === "active" ? "Ativo" : "Inativo"))),
13281
+ /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react28.default.createElement(
13282
+ "button",
13283
+ {
13284
+ onClick: () => handleToggleMilestoneStatus(ms.id),
13285
+ 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"}`,
13286
+ title: ms.status === "active" ? "Inativar" : "Ativar"
13287
+ },
13288
+ ms.status === "active" ? /* @__PURE__ */ import_react28.default.createElement(import_fi22.FiPauseCircle, { size: 18 }) : /* @__PURE__ */ import_react28.default.createElement(import_fi22.FiPlayCircle, { size: 18 })
13289
+ ), /* @__PURE__ */ import_react28.default.createElement(
13290
+ "button",
13291
+ {
13292
+ onClick: () => handleRemoveMilestone(ms.id),
13293
+ className: "p-2 rounded-lg hover:bg-red-500/20 text-slate-500 hover:text-red-400 transition-all",
13294
+ title: "Remover"
13295
+ },
13296
+ /* @__PURE__ */ import_react28.default.createElement(import_fi22.FiTrash2, { size: 18 })
13297
+ ))
13298
+ ))) : /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex flex-col items-center justify-center py-12 text-center" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "p-4 rounded-full bg-slate-800/30 text-slate-600 mb-4" }, /* @__PURE__ */ import_react28.default.createElement(import_fi22.FiTarget, { size: 40 })), /* @__PURE__ */ import_react28.default.createElement("h3", { className: "text-slate-400 font-medium" }, "Nenhum milestone definido"), /* @__PURE__ */ import_react28.default.createElement("p", { className: "text-xs text-slate-600 max-w-[200px] mt-1 italic" }, "Defina marcos importantes para orientar o progresso do projeto."))),
13299
+ /* @__PURE__ */ import_react28.default.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__ */ import_react28.default.createElement("div", { className: "flex gap-4" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react28.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Total:"), /* @__PURE__ */ import_react28.default.createElement("span", { className: "text-xs font-bold text-slate-300" }, milestones.length)), /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react28.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Ativos:"), /* @__PURE__ */ import_react28.default.createElement("span", { className: "text-xs font-bold text-indigo-400" }, milestones.filter((m) => m.status === "active").length))))
13300
+ )
13301
+ );
13302
+ }
13303
+
13254
13304
  // src/XViewScene.jsx
13255
13305
  var import_short_uuid2 = __toESM(require("short-uuid"));
13256
13306
  var secretKey = process.env.NEXT_PUBLIC_CRYPTO_KEY;
@@ -13332,13 +13382,13 @@ function XViewScene({
13332
13382
  check_user_permission,
13333
13383
  get_view_members
13334
13384
  }) {
13335
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
13336
- const { data: session, status } = (0, import_react29.useSession)();
13385
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
13386
+ const { data: session, status } = (0, import_react30.useSession)();
13337
13387
  const router = (0, import_navigation.useRouter)();
13338
13388
  const searchParams = (0, import_navigation.useSearchParams)();
13339
13389
  const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
13340
13390
  const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
13341
- const viewParams = (0, import_react28.useMemo)(() => {
13391
+ const viewParams = (0, import_react29.useMemo)(() => {
13342
13392
  if (encryptedConfig) {
13343
13393
  const data = decryptData(encryptedConfig);
13344
13394
  if (data) {
@@ -13347,7 +13397,7 @@ function XViewScene({
13347
13397
  }
13348
13398
  return null;
13349
13399
  }, [encryptedConfig, session]);
13350
- (0, import_react28.useEffect)(() => {
13400
+ (0, import_react29.useEffect)(() => {
13351
13401
  async function verifyPermission() {
13352
13402
  if (!viewParams || !session || !check_user_permission) return;
13353
13403
  const { id, type, owner_id } = viewParams;
@@ -13384,65 +13434,65 @@ function XViewScene({
13384
13434
  setIsLoading(false);
13385
13435
  }
13386
13436
  }, [viewParams, session, status, check_user_permission]);
13387
- const sceneConfigId = (0, import_react28.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
13388
- const ownerId = (0, import_react28.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
13389
- const dbSaveUrl = (0, import_react28.useMemo)(() => {
13437
+ const sceneConfigId = (0, import_react29.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
13438
+ const ownerId = (0, import_react29.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
13439
+ const dbSaveUrl = (0, import_react29.useMemo)(() => {
13390
13440
  if (ownerId && sceneConfigId) {
13391
13441
  return `x_view_dbs/${ownerId}/${sceneConfigId}`;
13392
13442
  }
13393
13443
  return null;
13394
13444
  }, [ownerId, sceneConfigId]);
13395
- const sceneSaveUrl = (0, import_react28.useMemo)(() => {
13445
+ const sceneSaveUrl = (0, import_react29.useMemo)(() => {
13396
13446
  if (ownerId && sceneConfigId) {
13397
13447
  return `x_view_scenes/${ownerId}/${sceneConfigId}`;
13398
13448
  }
13399
13449
  return null;
13400
13450
  }, [ownerId, sceneConfigId]);
13401
- const ancestry_save_url = (0, import_react28.useMemo)(() => {
13451
+ const ancestry_save_url = (0, import_react29.useMemo)(() => {
13402
13452
  if (ownerId && sceneConfigId) {
13403
13453
  return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
13404
13454
  }
13405
13455
  return null;
13406
13456
  }, [ownerId, sceneConfigId]);
13407
- const sceneDataRef = (0, import_react28.useRef)(null);
13408
- const parentDataRef = (0, import_react28.useRef)(null);
13409
- const ancestryDataRef = (0, import_react28.useRef)(null);
13410
- const [isLoading, setIsLoading] = (0, import_react28.useState)(true);
13411
- const [permissionStatus, setPermissionStatus] = (0, import_react28.useState)("loading");
13412
- const [userPermissionRole, setUserPermissionRole] = (0, import_react28.useState)(null);
13413
- const [viewMembers, setViewMembers] = (0, import_react28.useState)([]);
13414
- const [isInitialized, setIsInitialized] = (0, import_react28.useState)(false);
13415
- const [sceneVersion, setSceneVersion] = (0, import_react28.useState)(0);
13416
- const [contextMenu, setContextMenu] = (0, import_react28.useState)({
13457
+ const sceneDataRef = (0, import_react29.useRef)(null);
13458
+ const parentDataRef = (0, import_react29.useRef)(null);
13459
+ const ancestryDataRef = (0, import_react29.useRef)(null);
13460
+ const [isLoading, setIsLoading] = (0, import_react29.useState)(true);
13461
+ const [permissionStatus, setPermissionStatus] = (0, import_react29.useState)("loading");
13462
+ const [userPermissionRole, setUserPermissionRole] = (0, import_react29.useState)(null);
13463
+ const [viewMembers, setViewMembers] = (0, import_react29.useState)([]);
13464
+ const [isInitialized, setIsInitialized] = (0, import_react29.useState)(false);
13465
+ const [sceneVersion, setSceneVersion] = (0, import_react29.useState)(0);
13466
+ const [contextMenu, setContextMenu] = (0, import_react29.useState)({
13417
13467
  visible: false,
13418
13468
  x: 0,
13419
13469
  y: 0,
13420
13470
  nodeData: null
13421
13471
  });
13422
- const [multiContextMenu, setMultiContextMenu] = (0, import_react28.useState)({
13472
+ const [multiContextMenu, setMultiContextMenu] = (0, import_react29.useState)({
13423
13473
  visible: false,
13424
13474
  x: 0,
13425
13475
  y: 0,
13426
13476
  nodeIds: null
13427
13477
  });
13428
- const [relationshipMenu, setRelationshipMenu] = (0, import_react28.useState)({
13478
+ const [relationshipMenu, setRelationshipMenu] = (0, import_react29.useState)({
13429
13479
  visible: false,
13430
13480
  x: 0,
13431
13481
  y: 0,
13432
13482
  linkObject: null
13433
13483
  });
13434
- const [creationMode, setCreationMode] = (0, import_react28.useState)({
13484
+ const [creationMode, setCreationMode] = (0, import_react29.useState)({
13435
13485
  isActive: false,
13436
13486
  sourceNodeData: null
13437
13487
  });
13438
- const [versionMode, setVersionMode] = (0, import_react28.useState)({
13488
+ const [versionMode, setVersionMode] = (0, import_react29.useState)({
13439
13489
  isActive: false,
13440
13490
  sourceNodeData: null
13441
13491
  });
13442
- const [questMode, setQuestMode] = (0, import_react28.useState)({ isActive: false });
13443
- const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react28.useState)(false);
13444
- const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react28.useState)(false);
13445
- const [ancestryMode, setAncestryMode] = (0, import_react28.useState)({
13492
+ const [questMode, setQuestMode] = (0, import_react29.useState)({ isActive: false });
13493
+ const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react29.useState)(false);
13494
+ const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react29.useState)(false);
13495
+ const [ancestryMode, setAncestryMode] = (0, import_react29.useState)({
13446
13496
  isActive: false,
13447
13497
  tree: null,
13448
13498
  selectedParentId: null,
@@ -13453,41 +13503,42 @@ function XViewScene({
13453
13503
  ancestryDescriptionSections: [],
13454
13504
  isAddingNodes: false
13455
13505
  });
13456
- const [readingMode, setReadingMode] = (0, import_react28.useState)({
13506
+ const [readingMode, setReadingMode] = (0, import_react29.useState)({
13457
13507
  isActive: false,
13458
13508
  ancestry: null,
13459
13509
  branchStack: [],
13460
13510
  autoAbstraction: false
13461
13511
  });
13462
- const [formPosition, setFormPosition] = (0, import_react28.useState)({
13512
+ const [formPosition, setFormPosition] = (0, import_react29.useState)({
13463
13513
  left: 16,
13464
13514
  top: 16,
13465
13515
  opacity: 0
13466
13516
  });
13467
- const [detailsNode, setDetailsNode] = (0, import_react28.useState)(null);
13468
- const [detailsLink, setDetailsLink] = (0, import_react28.useState)(null);
13469
- const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react28.useState)(null);
13470
- const [imageViewer, setImageViewer] = (0, import_react28.useState)({
13517
+ const [detailsNode, setDetailsNode] = (0, import_react29.useState)(null);
13518
+ const [detailsLink, setDetailsLink] = (0, import_react29.useState)(null);
13519
+ const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react29.useState)(null);
13520
+ const [imageViewer, setImageViewer] = (0, import_react29.useState)({
13471
13521
  visible: false,
13472
13522
  images: [],
13473
13523
  startIndex: 0
13474
13524
  });
13475
- const [editingAncestryRel, setEditingAncestryRel] = (0, import_react28.useState)({
13525
+ const [editingAncestryRel, setEditingAncestryRel] = (0, import_react29.useState)({
13476
13526
  visible: false,
13477
13527
  data: null,
13478
13528
  path: null
13479
13529
  });
13480
- const [isImportModalOpen, setIsImportModalOpen] = (0, import_react28.useState)(false);
13481
- const [importSuccessMessage, setImportSuccessMessage] = (0, import_react28.useState)("");
13482
- const [invalidTargetError, setInvalidTargetError] = (0, import_react28.useState)(null);
13483
- const [highlightedNodeId, setHighlightedNodeId] = (0, import_react28.useState)(null);
13484
- const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react28.useState)(false);
13485
- const [ancestryBoardData, setAncestryBoardData] = (0, import_react28.useState)([]);
13486
- const [isSidebarOpen, setIsSidebarOpen] = (0, import_react28.useState)(false);
13487
- const mountRef = (0, import_react28.useRef)(null);
13488
- const tooltipRef = (0, import_react28.useRef)(null);
13489
- const formRef = (0, import_react28.useRef)(null);
13490
- const stateRef = (0, import_react28.useRef)({
13530
+ const [isImportModalOpen, setIsImportModalOpen] = (0, import_react29.useState)(false);
13531
+ const [importSuccessMessage, setImportSuccessMessage] = (0, import_react29.useState)("");
13532
+ const [invalidTargetError, setInvalidTargetError] = (0, import_react29.useState)(null);
13533
+ const [highlightedNodeId, setHighlightedNodeId] = (0, import_react29.useState)(null);
13534
+ const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react29.useState)(false);
13535
+ const [ancestryBoardData, setAncestryBoardData] = (0, import_react29.useState)([]);
13536
+ const [isSidebarOpen, setIsSidebarOpen] = (0, import_react29.useState)(false);
13537
+ const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = (0, import_react29.useState)(false);
13538
+ const mountRef = (0, import_react29.useRef)(null);
13539
+ const tooltipRef = (0, import_react29.useRef)(null);
13540
+ const formRef = (0, import_react29.useRef)(null);
13541
+ const stateRef = (0, import_react29.useRef)({
13491
13542
  readMode: {
13492
13543
  currentMaxIndex: 0,
13493
13544
  progressMap: {}
@@ -13551,10 +13602,10 @@ function XViewScene({
13551
13602
  minWidth: 320,
13552
13603
  maxWidth: maxReadPanelW
13553
13604
  });
13554
- (0, import_react28.useEffect)(() => {
13605
+ (0, import_react29.useEffect)(() => {
13555
13606
  stateRef.current.ancestry = ancestryMode;
13556
13607
  }, [ancestryMode]);
13557
- (0, import_react28.useEffect)(() => {
13608
+ (0, import_react29.useEffect)(() => {
13558
13609
  var _a2;
13559
13610
  if (!isInitialized) return;
13560
13611
  const map = /* @__PURE__ */ new Map();
@@ -13577,10 +13628,10 @@ function XViewScene({
13577
13628
  }
13578
13629
  stateRef.current.nodeIdToParentFileMap = map;
13579
13630
  }, [isInitialized, sceneVersion]);
13580
- const handleNavigateBack = (0, import_react28.useCallback)(() => {
13631
+ const handleNavigateBack = (0, import_react29.useCallback)(() => {
13581
13632
  router.push("/dashboard/scenes");
13582
13633
  }, [router]);
13583
- const handleConfirmImport = (0, import_react28.useCallback)(
13634
+ const handleConfirmImport = (0, import_react29.useCallback)(
13584
13635
  async (importPayload) => {
13585
13636
  var _a2, _b2;
13586
13637
  let files = [];
@@ -13708,7 +13759,7 @@ function XViewScene({
13708
13759
  const handleOpenImageViewer = (images, startIndex) => {
13709
13760
  setImageViewer({ visible: true, images, startIndex });
13710
13761
  };
13711
- const tweenToTarget = (0, import_react28.useCallback)(
13762
+ const tweenToTarget = (0, import_react29.useCallback)(
13712
13763
  (target, zoomFactor = 1, forcedDirection = null) => {
13713
13764
  const { camera, controls, tweenGroup } = stateRef.current;
13714
13765
  if (!camera || !controls || !tweenGroup) return;
@@ -13734,7 +13785,7 @@ function XViewScene({
13734
13785
  if (!t || typeof t.closest !== "function") return false;
13735
13786
  return !!t.closest(".ui-overlay");
13736
13787
  };
13737
- const buildFullAncestryTree = (0, import_react28.useCallback)(
13788
+ const buildFullAncestryTree = (0, import_react29.useCallback)(
13738
13789
  (idTree, nodes, ancestries = []) => {
13739
13790
  if (!idTree) return null;
13740
13791
  const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
@@ -13819,7 +13870,7 @@ function XViewScene({
13819
13870
  },
13820
13871
  []
13821
13872
  );
13822
- const handleActivateTimeline = (0, import_react28.useCallback)(() => {
13873
+ const handleActivateTimeline = (0, import_react29.useCallback)(() => {
13823
13874
  const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
13824
13875
  if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
13825
13876
  while (timelineIntervalsGroup.children.length > 0) {
@@ -13979,7 +14030,7 @@ function XViewScene({
13979
14030
  }
13980
14031
  });
13981
14032
  }, []);
13982
- const handleVersionTimeline = (0, import_react28.useCallback)((sourceMesh, versionMeshes) => {
14033
+ const handleVersionTimeline = (0, import_react29.useCallback)((sourceMesh, versionMeshes) => {
13983
14034
  const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
13984
14035
  if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0)
13985
14036
  return;
@@ -14116,7 +14167,7 @@ function XViewScene({
14116
14167
  }
14117
14168
  });
14118
14169
  }, []);
14119
- (0, import_react28.useEffect)(() => {
14170
+ (0, import_react29.useEffect)(() => {
14120
14171
  async function fetchAllData(configPath, ownerId2) {
14121
14172
  var _a2, _b2;
14122
14173
  if (!get_scene_view_data) {
@@ -14221,12 +14272,12 @@ function XViewScene({
14221
14272
  focusNodeId,
14222
14273
  focusAncestryId
14223
14274
  ]);
14224
- const isNodeInView = (0, import_react28.useCallback)((id) => {
14275
+ const isNodeInView = (0, import_react29.useCallback)((id) => {
14225
14276
  const key = String(id);
14226
14277
  const objs = stateRef.current.nodeObjects || {};
14227
14278
  return !!objs[key];
14228
14279
  }, []);
14229
- const addOrUpdateNodeMesh = (0, import_react28.useCallback)(
14280
+ const addOrUpdateNodeMesh = (0, import_react29.useCallback)(
14230
14281
  (nodeData, position, suppressVersionUpdate = false) => {
14231
14282
  const {
14232
14283
  graphGroup,
@@ -14266,7 +14317,7 @@ function XViewScene({
14266
14317
  },
14267
14318
  []
14268
14319
  );
14269
- const handleActivateQuestLens = (0, import_react28.useCallback)(({ assigneeId, status: status2 }) => {
14320
+ const handleActivateQuestLens = (0, import_react29.useCallback)(({ assigneeId, status: status2 }) => {
14270
14321
  var _a2;
14271
14322
  const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
14272
14323
  if (!nodeObjects || !tweenGroup || !graphGroup) return;
@@ -14479,7 +14530,7 @@ function XViewScene({
14479
14530
  camTween.start();
14480
14531
  }
14481
14532
  }, [addOrUpdateNodeMesh]);
14482
- (0, import_react28.useEffect)(() => {
14533
+ (0, import_react29.useEffect)(() => {
14483
14534
  if (!isInitialized || !sceneDataRef.current) return;
14484
14535
  const currentMount = mountRef.current;
14485
14536
  if (!currentMount) return;
@@ -15235,7 +15286,7 @@ function XViewScene({
15235
15286
  get_scene_view_data,
15236
15287
  save_view_data
15237
15288
  ]);
15238
- const handleGhostNodeImageChange = (0, import_react28.useCallback)((useImage, imageUrl) => {
15289
+ const handleGhostNodeImageChange = (0, import_react29.useCallback)((useImage, imageUrl) => {
15239
15290
  const {
15240
15291
  node: ghostNode,
15241
15292
  line: ghostLine,
@@ -15283,7 +15334,7 @@ function XViewScene({
15283
15334
  aura: newGhostNode.getObjectByName("aura")
15284
15335
  };
15285
15336
  }, []);
15286
- const handleGhostNodeIntensityChange = (0, import_react28.useCallback)((newIntensity) => {
15337
+ const handleGhostNodeIntensityChange = (0, import_react29.useCallback)((newIntensity) => {
15287
15338
  const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
15288
15339
  if (!ghostNode) return;
15289
15340
  const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
@@ -15304,7 +15355,7 @@ function XViewScene({
15304
15355
  ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
15305
15356
  }
15306
15357
  }, []);
15307
- const handleDetailNodeIntensityChange = (0, import_react28.useCallback)(
15358
+ const handleDetailNodeIntensityChange = (0, import_react29.useCallback)(
15308
15359
  (nodeId, newIntensity) => {
15309
15360
  const mesh = stateRef.current.nodeObjects[String(nodeId)];
15310
15361
  if (!mesh) return;
@@ -15460,7 +15511,7 @@ function XViewScene({
15460
15511
  mountRef.current.style.cursor = "default";
15461
15512
  }
15462
15513
  };
15463
- const handleAncestryTreeUpdate = (0, import_react28.useCallback)((newTree, extraData = null) => {
15514
+ const handleAncestryTreeUpdate = (0, import_react29.useCallback)((newTree, extraData = null) => {
15464
15515
  setAncestryMode((prev) => {
15465
15516
  const prevTreeStr = JSON.stringify(prev.tree);
15466
15517
  const newTreeStr = JSON.stringify(newTree);
@@ -15483,7 +15534,7 @@ function XViewScene({
15483
15534
  };
15484
15535
  });
15485
15536
  }, []);
15486
- const actionHandlerContext = (0, import_react28.useMemo)(
15537
+ const actionHandlerContext = (0, import_react29.useMemo)(
15487
15538
  () => {
15488
15539
  var _a2;
15489
15540
  return {
@@ -15544,7 +15595,7 @@ function XViewScene({
15544
15595
  const handleStartVersioning = (nodeData) => {
15545
15596
  userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
15546
15597
  };
15547
- const handleStartQuestQuick = (0, import_react28.useCallback)((questNode) => {
15598
+ const handleStartQuestQuick = (0, import_react29.useCallback)((questNode) => {
15548
15599
  var _a2, _b2, _c2;
15549
15600
  if (!questNode || !actionHandlerContext) return;
15550
15601
  const {
@@ -15573,7 +15624,7 @@ function XViewScene({
15573
15624
  }
15574
15625
  setDetailsNode(updatedNode);
15575
15626
  }, [session, actionHandlerContext]);
15576
- const handleFinishQuestQuick = (0, import_react28.useCallback)((questNode) => {
15627
+ const handleFinishQuestQuick = (0, import_react29.useCallback)((questNode) => {
15577
15628
  var _a2, _b2, _c2, _d2;
15578
15629
  if (!questNode || !actionHandlerContext) return;
15579
15630
  const {
@@ -15647,7 +15698,7 @@ function XViewScene({
15647
15698
  setDetailsNode(null);
15648
15699
  }
15649
15700
  }, [session, actionHandlerContext, viewMembers, detailsNode]);
15650
- const handleCancelQuest = (0, import_react28.useCallback)(() => {
15701
+ const handleCancelQuest = (0, import_react29.useCallback)(() => {
15651
15702
  const { graphGroup, ghostElements } = stateRef.current;
15652
15703
  if (ghostElements.node && graphGroup) {
15653
15704
  if (ghostElements.node.userData.labelObject) {
@@ -15800,7 +15851,7 @@ function XViewScene({
15800
15851
  }
15801
15852
  userActionHandlers.handleCancelConnection(context);
15802
15853
  };
15803
- const handleClearAncestryVisuals = (0, import_react28.useCallback)((ancestryId) => {
15854
+ const handleClearAncestryVisuals = (0, import_react29.useCallback)((ancestryId) => {
15804
15855
  const { renderedAncestries, ancestryGroup } = stateRef.current;
15805
15856
  const renderIndex = renderedAncestries.findIndex(
15806
15857
  (a) => String(a.id) === String(ancestryId)
@@ -15818,7 +15869,7 @@ function XViewScene({
15818
15869
  );
15819
15870
  }
15820
15871
  }, []);
15821
- const handleRenderAncestry = (0, import_react28.useCallback)(
15872
+ const handleRenderAncestry = (0, import_react29.useCallback)(
15822
15873
  async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
15823
15874
  setContextMenu(
15824
15875
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -16312,7 +16363,7 @@ function XViewScene({
16312
16363
  ancestryMode.isActive
16313
16364
  ]
16314
16365
  );
16315
- const handleRenderAbstractionTree = (0, import_react28.useCallback)(
16366
+ const handleRenderAbstractionTree = (0, import_react29.useCallback)(
16316
16367
  (ancestryObject, targetNodeId = null) => {
16317
16368
  setContextMenu(
16318
16369
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -16400,7 +16451,7 @@ function XViewScene({
16400
16451
  handleClearAncestryVisuals
16401
16452
  ]
16402
16453
  );
16403
- const handleReadModeBranchNav = (0, import_react28.useCallback)(
16454
+ const handleReadModeBranchNav = (0, import_react29.useCallback)(
16404
16455
  (nodeId, action, direction = "right") => {
16405
16456
  const { ancestry, branchStack } = readingMode;
16406
16457
  if (!ancestry || !ancestry.tree) return;
@@ -16578,13 +16629,13 @@ function XViewScene({
16578
16629
  },
16579
16630
  [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]
16580
16631
  );
16581
- const handleReadModeHighlight = (0, import_react28.useCallback)((nodeId) => {
16632
+ const handleReadModeHighlight = (0, import_react29.useCallback)((nodeId) => {
16582
16633
  if (stateRef.current.highlightedNodeId !== nodeId) {
16583
16634
  stateRef.current.highlightedNodeId = nodeId;
16584
16635
  }
16585
16636
  setHighlightedNodeId(nodeId);
16586
16637
  }, []);
16587
- const activeNodeBranches = (0, import_react28.useMemo)(() => {
16638
+ const activeNodeBranches = (0, import_react29.useMemo)(() => {
16588
16639
  if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree)
16589
16640
  return null;
16590
16641
  const fullTree = buildFullAncestryTree(
@@ -16628,7 +16679,7 @@ function XViewScene({
16628
16679
  readingMode.branchStack,
16629
16680
  ancestryDataRef.current
16630
16681
  ]);
16631
- const backNavigationInfo = (0, import_react28.useMemo)(() => {
16682
+ const backNavigationInfo = (0, import_react29.useMemo)(() => {
16632
16683
  const { branchStack } = readingMode;
16633
16684
  if (!branchStack || branchStack.length === 0) return null;
16634
16685
  const lastStep = branchStack[branchStack.length - 1];
@@ -16639,7 +16690,7 @@ function XViewScene({
16639
16690
  name: "Voltar para anterior"
16640
16691
  };
16641
16692
  }, [readingMode.branchStack]);
16642
- const getReadModeDisplayContext = (0, import_react28.useMemo)(() => {
16693
+ const getReadModeDisplayContext = (0, import_react29.useMemo)(() => {
16643
16694
  const { ancestry, branchStack } = readingMode;
16644
16695
  if (!ancestry) return null;
16645
16696
  if (branchStack.length === 0) {
@@ -16682,7 +16733,7 @@ function XViewScene({
16682
16733
  customProperties: branchProps
16683
16734
  };
16684
16735
  }, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
16685
- const readModeAbstractionTree = (0, import_react28.useMemo)(() => {
16736
+ const readModeAbstractionTree = (0, import_react29.useMemo)(() => {
16686
16737
  if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
16687
16738
  return null;
16688
16739
  }
@@ -16701,7 +16752,7 @@ function XViewScene({
16701
16752
  buildFullAncestryTree,
16702
16753
  sceneVersion
16703
16754
  ]);
16704
- const handleStartReadingAncestry = (0, import_react28.useCallback)(
16755
+ const handleStartReadingAncestry = (0, import_react29.useCallback)(
16705
16756
  async (ancestryObject, renderMode = "full") => {
16706
16757
  setContextMenu(
16707
16758
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -16744,7 +16795,7 @@ function XViewScene({
16744
16795
  },
16745
16796
  [handleRenderAncestry, handleRenderAbstractionTree]
16746
16797
  );
16747
- const handleReadModeSectionChange = (0, import_react28.useCallback)(
16798
+ const handleReadModeSectionChange = (0, import_react29.useCallback)(
16748
16799
  (activeSectionId) => {
16749
16800
  const { ancestry, branchStack } = readingMode;
16750
16801
  if (!ancestry || !readingMode.isActive) return;
@@ -16829,10 +16880,10 @@ function XViewScene({
16829
16880
  ancestryDataRef.current
16830
16881
  ]
16831
16882
  );
16832
- const handleCloseReadMode = (0, import_react28.useCallback)(() => {
16883
+ const handleCloseReadMode = (0, import_react29.useCallback)(() => {
16833
16884
  setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
16834
16885
  }, []);
16835
- const handleAncestrySectionChange = (0, import_react28.useCallback)(
16886
+ const handleAncestrySectionChange = (0, import_react29.useCallback)(
16836
16887
  (activeSectionId, ancestryOverride = null, rotation = 0) => {
16837
16888
  var _a2, _b2;
16838
16889
  const currentMode = stateRef.current.ancestry;
@@ -16894,7 +16945,7 @@ function XViewScene({
16894
16945
  },
16895
16946
  [handleRenderAncestry]
16896
16947
  );
16897
- const handleEditAncestry = (0, import_react28.useCallback)(
16948
+ const handleEditAncestry = (0, import_react29.useCallback)(
16898
16949
  async (ancestryObject) => {
16899
16950
  setContextMenu(
16900
16951
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -16949,7 +17000,7 @@ function XViewScene({
16949
17000
  const handleSelectAncestryParent = (nodeId) => {
16950
17001
  setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
16951
17002
  };
16952
- const handleRemoveFromAncestry = (0, import_react28.useCallback)((pathToRemove) => {
17003
+ const handleRemoveFromAncestry = (0, import_react29.useCallback)((pathToRemove) => {
16953
17004
  if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
16954
17005
  console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
16955
17006
  return;
@@ -16974,7 +17025,7 @@ function XViewScene({
16974
17025
  return { ...prev, tree: newTree };
16975
17026
  });
16976
17027
  }, []);
16977
- const handleSaveAncestry = (0, import_react28.useCallback)(
17028
+ const handleSaveAncestry = (0, import_react29.useCallback)(
16978
17029
  async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
16979
17030
  const treeToUse = treeOverride || ancestryMode.tree;
16980
17031
  const { isEditMode, currentAncestryId } = ancestryMode;
@@ -17210,7 +17261,7 @@ function XViewScene({
17210
17261
  });
17211
17262
  setEditingAncestryRel({ visible: false, data: null, path: null });
17212
17263
  };
17213
- const handleDeleteAncestry = (0, import_react28.useCallback)(
17264
+ const handleDeleteAncestry = (0, import_react29.useCallback)(
17214
17265
  async (ancestryIdToDelete) => {
17215
17266
  if (!ancestryIdToDelete) {
17216
17267
  alert("ID da ancestralidade n\xE3o encontrado.");
@@ -17292,10 +17343,10 @@ function XViewScene({
17292
17343
  },
17293
17344
  [save_view_data, delete_file_action]
17294
17345
  );
17295
- const handleOpenAncestryBoard = (0, import_react28.useCallback)(() => {
17346
+ const handleOpenAncestryBoard = (0, import_react29.useCallback)(() => {
17296
17347
  setIsAncestryBoardOpen(true);
17297
17348
  }, []);
17298
- const handleSelectAncestryFromBoard = (0, import_react28.useCallback)(
17349
+ const handleSelectAncestryFromBoard = (0, import_react29.useCallback)(
17299
17350
  (ancestry) => {
17300
17351
  setIsAncestryBoardOpen(false);
17301
17352
  setIsSidebarOpen(false);
@@ -17303,7 +17354,7 @@ function XViewScene({
17303
17354
  },
17304
17355
  [handleStartReadingAncestry]
17305
17356
  );
17306
- const handleSaveAncestryBoard = (0, import_react28.useCallback)(
17357
+ const handleSaveAncestryBoard = (0, import_react29.useCallback)(
17307
17358
  async (groups) => {
17308
17359
  if (!sceneConfigId || !viewParams || !session) return;
17309
17360
  const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
@@ -17317,7 +17368,7 @@ function XViewScene({
17317
17368
  },
17318
17369
  [sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]
17319
17370
  );
17320
- const existingNodeTypes = (0, import_react28.useMemo)(() => {
17371
+ const existingNodeTypes = (0, import_react29.useMemo)(() => {
17321
17372
  if (!parentDataRef.current) {
17322
17373
  return [];
17323
17374
  }
@@ -17329,7 +17380,7 @@ function XViewScene({
17329
17380
  ).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
17330
17381
  return [...new Set(allTypes)];
17331
17382
  }, [parentDataRef.current, sceneVersion]);
17332
- const searchableDbNodes = (0, import_react28.useMemo)(() => {
17383
+ const searchableDbNodes = (0, import_react29.useMemo)(() => {
17333
17384
  if (!parentDataRef.current) {
17334
17385
  return [];
17335
17386
  }
@@ -17344,7 +17395,7 @@ function XViewScene({
17344
17395
  return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
17345
17396
  });
17346
17397
  }, [parentDataRef.current, sceneVersion]);
17347
- const handleAddExistingNode = (0, import_react28.useCallback)(
17398
+ const handleAddExistingNode = (0, import_react29.useCallback)(
17348
17399
  (nodeId) => {
17349
17400
  return userActionHandlers.handleAddExistingNodeById(
17350
17401
  actionHandlerContext,
@@ -17353,7 +17404,7 @@ function XViewScene({
17353
17404
  },
17354
17405
  [actionHandlerContext]
17355
17406
  );
17356
- const handleUpdateMilestones = (0, import_react28.useCallback)(
17407
+ const handleUpdateMilestones = (0, import_react29.useCallback)(
17357
17408
  async (newMilestones) => {
17358
17409
  var _a2, _b2, _c2;
17359
17410
  if (!sceneDataRef.current) return;
@@ -17399,7 +17450,7 @@ function XViewScene({
17399
17450
  viewParams == null ? void 0 : viewParams.type
17400
17451
  ]
17401
17452
  );
17402
- const handleSaveCurrentView = (0, import_react28.useCallback)(async () => {
17453
+ const handleSaveCurrentView = (0, import_react29.useCallback)(async () => {
17403
17454
  var _a2, _b2, _c2;
17404
17455
  const { nodeObjects, allLinks } = stateRef.current;
17405
17456
  if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
@@ -17442,16 +17493,16 @@ function XViewScene({
17442
17493
  console.error("Erro na chamada de save_view_data:", error);
17443
17494
  }
17444
17495
  }, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
17445
- const allAvailableNodes = (0, import_react28.useMemo)(() => {
17496
+ const allAvailableNodes = (0, import_react29.useMemo)(() => {
17446
17497
  if (!parentDataRef.current) return [];
17447
17498
  return Object.values(parentDataRef.current).flatMap(
17448
17499
  (fileData) => fileData.nodes || []
17449
17500
  );
17450
17501
  }, [sceneVersion, isInitialized]);
17451
- const allAvailableAncestries = (0, import_react28.useMemo)(() => {
17502
+ const allAvailableAncestries = (0, import_react29.useMemo)(() => {
17452
17503
  return ancestryDataRef.current || [];
17453
17504
  }, [sceneVersion, isInitialized]);
17454
- const handleOpenReference = (0, import_react28.useCallback)(
17505
+ const handleOpenReference = (0, import_react29.useCallback)(
17455
17506
  (referenceData) => {
17456
17507
  const { type, id } = referenceData;
17457
17508
  if (type === "node") {
@@ -17490,13 +17541,13 @@ function XViewScene({
17490
17541
  tweenToTarget
17491
17542
  ]
17492
17543
  );
17493
- const handleToggleAncestryAddMode = (0, import_react28.useCallback)(() => {
17544
+ const handleToggleAncestryAddMode = (0, import_react29.useCallback)(() => {
17494
17545
  setAncestryMode((prev) => ({
17495
17546
  ...prev,
17496
17547
  isAddingNodes: !prev.isAddingNodes
17497
17548
  }));
17498
17549
  }, []);
17499
- const handleFocusNode = (0, import_react28.useCallback)(
17550
+ const handleFocusNode = (0, import_react29.useCallback)(
17500
17551
  (nodeData) => {
17501
17552
  if (!nodeData) return;
17502
17553
  const nodeMesh = stateRef.current.nodeObjects[String(nodeData.id)];
@@ -17506,7 +17557,7 @@ function XViewScene({
17506
17557
  },
17507
17558
  [tweenToTarget]
17508
17559
  );
17509
- const availableDatasets = (0, import_react28.useMemo)(() => {
17560
+ const availableDatasets = (0, import_react29.useMemo)(() => {
17510
17561
  if (!sceneDataRef.current || !parentDataRef.current) return [];
17511
17562
  return sceneDataRef.current.parent_dbs.map((db) => {
17512
17563
  var _a2;
@@ -17520,7 +17571,7 @@ function XViewScene({
17520
17571
  String(creationMode.sourceNodeData.id)
17521
17572
  )) == null ? void 0 : _b.parentFileId : null;
17522
17573
  const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
17523
- (0, import_react28.useEffect)(() => {
17574
+ (0, import_react29.useEffect)(() => {
17524
17575
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
17525
17576
  const nodeObjects = stateRef.current.nodeObjects || {};
17526
17577
  const targetMesh = nodeObjects[String(focusNodeId)];
@@ -17543,7 +17594,7 @@ function XViewScene({
17543
17594
  hasFocusedInitial,
17544
17595
  tweenToTarget
17545
17596
  ]);
17546
- (0, import_react28.useEffect)(() => {
17597
+ (0, import_react29.useEffect)(() => {
17547
17598
  if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
17548
17599
  const ancestries = ancestryDataRef.current || [];
17549
17600
  const targetAncestry = ancestries.find(
@@ -17568,7 +17619,7 @@ function XViewScene({
17568
17619
  hasOpenedInitialAncestry,
17569
17620
  handleStartReadingAncestry
17570
17621
  ]);
17571
- (0, import_react28.useEffect)(() => {
17622
+ (0, import_react29.useEffect)(() => {
17572
17623
  function handleKeyDown(event) {
17573
17624
  var _a2, _b2, _c2;
17574
17625
  const context = actionHandlerContext;
@@ -17691,10 +17742,10 @@ function XViewScene({
17691
17742
  // <-- handleCancelQuest adicionado aqui
17692
17743
  ]);
17693
17744
  if (isLoading || status === "loading" || permissionStatus === "loading") {
17694
- return /* @__PURE__ */ import_react28.default.createElement(LoadingScreen, null);
17745
+ return /* @__PURE__ */ import_react29.default.createElement(LoadingScreen, null);
17695
17746
  }
17696
17747
  if (permissionStatus === "denied") {
17697
- return /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react28.default.createElement(
17748
+ return /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react29.default.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ import_react29.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react29.default.createElement(
17698
17749
  "svg",
17699
17750
  {
17700
17751
  xmlns: "http://www.w3.org/2000/svg",
@@ -17704,7 +17755,7 @@ function XViewScene({
17704
17755
  stroke: "currentColor",
17705
17756
  className: "w-16 h-16 mx-auto"
17706
17757
  },
17707
- /* @__PURE__ */ import_react28.default.createElement(
17758
+ /* @__PURE__ */ import_react29.default.createElement(
17708
17759
  "path",
17709
17760
  {
17710
17761
  strokeLinecap: "round",
@@ -17712,13 +17763,13 @@ function XViewScene({
17712
17763
  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"
17713
17764
  }
17714
17765
  )
17715
- )), /* @__PURE__ */ import_react28.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react28.default.createElement("p", { className: "text-slate-400 mb-6" }, "Voc\xEA n\xE3o tem permiss\xE3o para acessar este conte\xFAdo. Solicite acesso ao propriet\xE1rio ou verifique se est\xE1 na conta correta."), /* @__PURE__ */ import_react28.default.createElement(
17766
+ )), /* @__PURE__ */ import_react29.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react29.default.createElement("p", { className: "text-slate-400 mb-6" }, "Voc\xEA n\xE3o tem permiss\xE3o para acessar este conte\xFAdo. Solicite acesso ao propriet\xE1rio ou verifique se est\xE1 na conta correta."), /* @__PURE__ */ import_react29.default.createElement(
17716
17767
  "button",
17717
17768
  {
17718
17769
  onClick: () => router.push("/dashboard/scenes"),
17719
17770
  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"
17720
17771
  },
17721
- /* @__PURE__ */ import_react28.default.createElement(
17772
+ /* @__PURE__ */ import_react29.default.createElement(
17722
17773
  "svg",
17723
17774
  {
17724
17775
  xmlns: "http://www.w3.org/2000/svg",
@@ -17728,7 +17779,7 @@ function XViewScene({
17728
17779
  stroke: "currentColor",
17729
17780
  className: "w-5 h-5"
17730
17781
  },
17731
- /* @__PURE__ */ import_react28.default.createElement(
17782
+ /* @__PURE__ */ import_react29.default.createElement(
17732
17783
  "path",
17733
17784
  {
17734
17785
  strokeLinecap: "round",
@@ -17740,7 +17791,7 @@ function XViewScene({
17740
17791
  "Voltar para Scenes"
17741
17792
  )));
17742
17793
  }
17743
- return /* @__PURE__ */ import_react28.default.createElement(
17794
+ return /* @__PURE__ */ import_react29.default.createElement(
17744
17795
  "div",
17745
17796
  {
17746
17797
  ref: mountRef,
@@ -17752,7 +17803,7 @@ function XViewScene({
17752
17803
  cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
17753
17804
  }
17754
17805
  },
17755
- userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react28.default.createElement(
17806
+ userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react29.default.createElement(
17756
17807
  XViewSidebar,
17757
17808
  {
17758
17809
  dbNodes: searchableDbNodes,
@@ -17773,10 +17824,10 @@ function XViewScene({
17773
17824
  userRole: userPermissionRole,
17774
17825
  viewMembers,
17775
17826
  milestones: ((_c = sceneDataRef.current) == null ? void 0 : _c.milestones) || [],
17776
- onUpdateMilestones: handleUpdateMilestones
17827
+ onOpenMilestoneManager: () => setIsMilestoneManagerOpen(true)
17777
17828
  }
17778
17829
  ),
17779
- creationMode.isActive && /* @__PURE__ */ import_react28.default.createElement(
17830
+ creationMode.isActive && /* @__PURE__ */ import_react29.default.createElement(
17780
17831
  InSceneCreationForm,
17781
17832
  {
17782
17833
  onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
@@ -17808,7 +17859,7 @@ function XViewScene({
17808
17859
  availableAncestries: allAvailableAncestries
17809
17860
  }
17810
17861
  ),
17811
- versionMode.isActive && /* @__PURE__ */ import_react28.default.createElement(
17862
+ versionMode.isActive && /* @__PURE__ */ import_react29.default.createElement(
17812
17863
  InSceneVersionForm,
17813
17864
  {
17814
17865
  onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
@@ -17834,7 +17885,7 @@ function XViewScene({
17834
17885
  availableAncestries: allAvailableAncestries
17835
17886
  }
17836
17887
  ),
17837
- questMode.isActive && /* @__PURE__ */ import_react28.default.createElement(
17888
+ questMode.isActive && /* @__PURE__ */ import_react29.default.createElement(
17838
17889
  InSceneQuestForm,
17839
17890
  {
17840
17891
  onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
@@ -17862,7 +17913,7 @@ function XViewScene({
17862
17913
  onUpdateMilestones: handleUpdateMilestones
17863
17914
  }
17864
17915
  ),
17865
- readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react28.default.createElement(
17916
+ readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react29.default.createElement(
17866
17917
  "div",
17867
17918
  {
17868
17919
  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"}`,
@@ -17875,7 +17926,7 @@ function XViewScene({
17875
17926
  maxWidth: "92vw"
17876
17927
  }
17877
17928
  },
17878
- /* @__PURE__ */ import_react28.default.createElement(
17929
+ /* @__PURE__ */ import_react29.default.createElement(
17879
17930
  "div",
17880
17931
  {
17881
17932
  onPointerDown: (e) => {
@@ -17886,7 +17937,7 @@ function XViewScene({
17886
17937
  title: "Arraste para redimensionar"
17887
17938
  }
17888
17939
  ),
17889
- /* @__PURE__ */ import_react28.default.createElement(
17940
+ /* @__PURE__ */ import_react29.default.createElement(
17890
17941
  DescriptionReadModePanel,
17891
17942
  {
17892
17943
  key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
@@ -17921,7 +17972,7 @@ function XViewScene({
17921
17972
  }
17922
17973
  )
17923
17974
  ),
17924
- ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react28.default.createElement(
17975
+ ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react29.default.createElement(
17925
17976
  CreateAncestryPanel,
17926
17977
  {
17927
17978
  ancestryMode,
@@ -17957,7 +18008,7 @@ function XViewScene({
17957
18008
  onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
17958
18009
  }
17959
18010
  ),
17960
- editingAncestryRel.visible && /* @__PURE__ */ import_react28.default.createElement(
18011
+ editingAncestryRel.visible && /* @__PURE__ */ import_react29.default.createElement(
17961
18012
  AncestryRelationshipPanel,
17962
18013
  {
17963
18014
  data: editingAncestryRel.data,
@@ -17971,7 +18022,7 @@ function XViewScene({
17971
18022
  onUploadFile: upload_file_action
17972
18023
  }
17973
18024
  ),
17974
- detailsNode && detailsNode.is_quest && /* @__PURE__ */ import_react28.default.createElement(
18025
+ detailsNode && detailsNode.is_quest && /* @__PURE__ */ import_react29.default.createElement(
17975
18026
  QuestDetailsPanel,
17976
18027
  {
17977
18028
  node: detailsNode,
@@ -17996,7 +18047,7 @@ function XViewScene({
17996
18047
  onUpdateMilestones: handleUpdateMilestones
17997
18048
  }
17998
18049
  ),
17999
- detailsNode && !detailsNode.is_quest && /* @__PURE__ */ import_react28.default.createElement(
18050
+ detailsNode && !detailsNode.is_quest && /* @__PURE__ */ import_react29.default.createElement(
18000
18051
  NodeDetailsPanel,
18001
18052
  {
18002
18053
  node: detailsNode,
@@ -18028,7 +18079,7 @@ function XViewScene({
18028
18079
  currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
18029
18080
  }
18030
18081
  ),
18031
- detailsLink && /* @__PURE__ */ import_react28.default.createElement(
18082
+ detailsLink && /* @__PURE__ */ import_react29.default.createElement(
18032
18083
  RelationshipDetailsPanel,
18033
18084
  {
18034
18085
  link: detailsLink,
@@ -18042,7 +18093,7 @@ function XViewScene({
18042
18093
  userRole: userPermissionRole
18043
18094
  }
18044
18095
  ),
18045
- ancestryLinkDetails && /* @__PURE__ */ import_react28.default.createElement(
18096
+ ancestryLinkDetails && /* @__PURE__ */ import_react29.default.createElement(
18046
18097
  AncestryLinkDetailsPanel,
18047
18098
  {
18048
18099
  data: ancestryLinkDetails,
@@ -18053,7 +18104,7 @@ function XViewScene({
18053
18104
  onUploadFile: upload_file_action
18054
18105
  }
18055
18106
  ),
18056
- /* @__PURE__ */ import_react28.default.createElement(
18107
+ /* @__PURE__ */ import_react29.default.createElement(
18057
18108
  "div",
18058
18109
  {
18059
18110
  ref: tooltipRef,
@@ -18080,7 +18131,7 @@ function XViewScene({
18080
18131
  }
18081
18132
  }
18082
18133
  ),
18083
- /* @__PURE__ */ import_react28.default.createElement(
18134
+ /* @__PURE__ */ import_react29.default.createElement(
18084
18135
  ContextMenu,
18085
18136
  {
18086
18137
  data: contextMenu,
@@ -18113,7 +18164,7 @@ function XViewScene({
18113
18164
  onFinishQuest: handleFinishQuestQuick
18114
18165
  }
18115
18166
  ),
18116
- /* @__PURE__ */ import_react28.default.createElement(
18167
+ /* @__PURE__ */ import_react29.default.createElement(
18117
18168
  MultiNodeContextMenu,
18118
18169
  {
18119
18170
  data: multiContextMenu,
@@ -18133,7 +18184,7 @@ function XViewScene({
18133
18184
  )
18134
18185
  }
18135
18186
  ),
18136
- /* @__PURE__ */ import_react28.default.createElement(
18187
+ /* @__PURE__ */ import_react29.default.createElement(
18137
18188
  RelationshipContextMenu,
18138
18189
  {
18139
18190
  data: relationshipMenu,
@@ -18151,14 +18202,14 @@ function XViewScene({
18151
18202
  onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
18152
18203
  }
18153
18204
  ),
18154
- /* @__PURE__ */ import_react28.default.createElement(
18205
+ /* @__PURE__ */ import_react29.default.createElement(
18155
18206
  ImageViewer,
18156
18207
  {
18157
18208
  data: imageViewer,
18158
18209
  onClose: () => setImageViewer({ ...imageViewer, visible: false })
18159
18210
  }
18160
18211
  ),
18161
- /* @__PURE__ */ import_react28.default.createElement(
18212
+ /* @__PURE__ */ import_react29.default.createElement(
18162
18213
  AncestryBoard,
18163
18214
  {
18164
18215
  isOpen: isAncestryBoardOpen,
@@ -18171,20 +18222,29 @@ function XViewScene({
18171
18222
  userRole: userPermissionRole
18172
18223
  }
18173
18224
  ),
18174
- /* @__PURE__ */ import_react28.default.createElement(
18225
+ /* @__PURE__ */ import_react29.default.createElement(
18226
+ MilestoneManager,
18227
+ {
18228
+ isOpen: isMilestoneManagerOpen,
18229
+ onClose: () => setIsMilestoneManagerOpen(false),
18230
+ milestones: ((_k = sceneDataRef.current) == null ? void 0 : _k.milestones) || [],
18231
+ onUpdateMilestones: handleUpdateMilestones
18232
+ }
18233
+ ),
18234
+ /* @__PURE__ */ import_react29.default.createElement(
18175
18235
  ImportParentFileModal,
18176
18236
  {
18177
18237
  isOpen: isImportModalOpen,
18178
18238
  onClose: () => setIsImportModalOpen(false),
18179
18239
  onConfirm: handleConfirmImport,
18180
18240
  session,
18181
- parentDbs: ((_k = sceneDataRef.current) == null ? void 0 : _k.parent_dbs) || [],
18241
+ parentDbs: ((_l = sceneDataRef.current) == null ? void 0 : _l.parent_dbs) || [],
18182
18242
  onFetchAvailableFiles: import_parent_file_modal_get,
18183
18243
  currentViewName: viewParams == null ? void 0 : viewParams.name,
18184
18244
  currentAncestries: ancestryDataRef.current || []
18185
18245
  }
18186
18246
  ),
18187
- invalidTargetError && /* @__PURE__ */ import_react28.default.createElement(
18247
+ invalidTargetError && /* @__PURE__ */ import_react29.default.createElement(
18188
18248
  "div",
18189
18249
  {
18190
18250
  className: "ui-overlay",
@@ -18209,13 +18269,13 @@ function XViewScene({
18209
18269
  animation: "fadeInDown 0.5s cubic-bezier(0.16, 1, 0.3, 1)"
18210
18270
  }
18211
18271
  },
18212
- /* @__PURE__ */ import_react28.default.createElement("style", null, `
18272
+ /* @__PURE__ */ import_react29.default.createElement("style", null, `
18213
18273
  @keyframes fadeInDown {
18214
18274
  from { opacity: 0; transform: translate(-50%, -20px); }
18215
18275
  to { opacity: 1; transform: translate(-50%, 0); }
18216
18276
  }
18217
18277
  `),
18218
- /* @__PURE__ */ import_react28.default.createElement(
18278
+ /* @__PURE__ */ import_react29.default.createElement(
18219
18279
  "svg",
18220
18280
  {
18221
18281
  width: "20",
@@ -18227,12 +18287,12 @@ function XViewScene({
18227
18287
  strokeLinecap: "round",
18228
18288
  strokeLinejoin: "round"
18229
18289
  },
18230
- /* @__PURE__ */ import_react28.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
18231
- /* @__PURE__ */ import_react28.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
18232
- /* @__PURE__ */ import_react28.default.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
18290
+ /* @__PURE__ */ import_react29.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
18291
+ /* @__PURE__ */ import_react29.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
18292
+ /* @__PURE__ */ import_react29.default.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
18233
18293
  ),
18234
- /* @__PURE__ */ import_react28.default.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
18235
- /* @__PURE__ */ import_react28.default.createElement(
18294
+ /* @__PURE__ */ import_react29.default.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
18295
+ /* @__PURE__ */ import_react29.default.createElement(
18236
18296
  "button",
18237
18297
  {
18238
18298
  onClick: () => setInvalidTargetError(null),