@lv-x-software-house/x_view 1.2.6-dev.31 → 1.2.6-dev.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -13069,7 +13069,7 @@ function domToContent(el) {
13069
13069
  el.childNodes.forEach(walk);
13070
13070
  return segments;
13071
13071
  }
13072
- function RichGroupEditor({
13072
+ var RichGroupEditor = import_react28.default.memo(function RichGroupEditor2({
13073
13073
  content,
13074
13074
  onChange,
13075
13075
  onMentionClick,
@@ -13279,14 +13279,17 @@ function RichGroupEditor({
13279
13279
  onClose: handleMentionDismiss
13280
13280
  }
13281
13281
  ));
13282
- }
13282
+ }, (prevProps, nextProps) => {
13283
+ return prevProps.readOnly === nextProps.readOnly && prevProps.placeholder === nextProps.placeholder && prevProps.content === nextProps.content && prevProps.searchItems === nextProps.searchItems;
13284
+ });
13285
+ var RichGroupEditor_default = RichGroupEditor;
13283
13286
 
13284
13287
  // src/components/Boards.jsx
13285
13288
  var Tooltip = ({ text, children }) => {
13286
13289
  if (!text) return children;
13287
13290
  return /* @__PURE__ */ import_react29.default.createElement("div", { className: "relative group/tooltip" }, children, /* @__PURE__ */ import_react29.default.createElement("div", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 bg-slate-900 border border-white/10 text-white text-[10px] rounded opacity-0 group-hover/tooltip:opacity-100 transition-opacity pointer-events-none whitespace-nowrap z-[3000] shadow-2xl" }, text));
13288
13291
  };
13289
- var BoardItem = ({
13292
+ var BoardItem = import_react29.default.memo(({
13290
13293
  item,
13291
13294
  index,
13292
13295
  prevItem,
@@ -13309,7 +13312,6 @@ var BoardItem = ({
13309
13312
  const isFolder = item.type === "folder";
13310
13313
  const canMoveUp = index > 0;
13311
13314
  const canMoveDown = nextItem !== void 0;
13312
- const isNested = onOutdent !== void 0;
13313
13315
  const getIndentUpTooltip = () => {
13314
13316
  if (!prevItem) return null;
13315
13317
  const typeLabel = prevItem.type === "folder" ? "pasta" : "grupo de texto";
@@ -13414,7 +13416,7 @@ var BoardItem = ({
13414
13416
  ));
13415
13417
  }
13416
13418
  return /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex flex-col gap-2 mb-3 pl-3 border-l border-white/10 relative group/item animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react29.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex flex-col gap-2 py-2 px-3 transition-all duration-200 hover:bg-white/5 border-l-2 border-transparent hover:border-white/20" }, /* @__PURE__ */ import_react29.default.createElement(
13417
- RichGroupEditor,
13419
+ RichGroupEditor_default,
13418
13420
  {
13419
13421
  content: item.content,
13420
13422
  onChange: handleContentChange,
@@ -13500,7 +13502,7 @@ var BoardItem = ({
13500
13502
  isAtRoot: false
13501
13503
  }
13502
13504
  ))));
13503
- };
13505
+ });
13504
13506
  function Boards({
13505
13507
  isOpen,
13506
13508
  onClose,
@@ -13517,13 +13519,24 @@ function Boards({
13517
13519
  const [navigationStack, setNavigationStack] = (0, import_react29.useState)([]);
13518
13520
  const lastSavedBoardItemsRef = (0, import_react29.useRef)(null);
13519
13521
  const canEdit = (0, import_react29.useMemo)(() => userRole !== "viewer", [userRole]);
13520
- const sanitizeBoardItems = (list) => list.map((g) => ({
13522
+ const findGroupAndParent = (list, targetId, parent = null) => {
13523
+ for (let i = 0; i < list.length; i++) {
13524
+ if (list[i].id === targetId)
13525
+ return { group: list[i], parent, index: i, siblings: list };
13526
+ if (list[i].children.length > 0) {
13527
+ const found = findGroupAndParent(list[i].children, targetId, list[i]);
13528
+ if (found) return found;
13529
+ }
13530
+ }
13531
+ return null;
13532
+ };
13533
+ const sanitizeBoardItems = (0, import_react29.useCallback)((list) => list.map((g) => ({
13521
13534
  id: g.id,
13522
13535
  type: g.type || "text_group",
13523
13536
  name: g.name || "",
13524
13537
  content: g.content || [],
13525
13538
  children: sanitizeBoardItems(g.children || [])
13526
- }));
13539
+ })), []);
13527
13540
  (0, import_react29.useEffect)(() => {
13528
13541
  if (initialBoardItems && !isLoaded) {
13529
13542
  const hasLegacyTypes = (list) => list.some(
@@ -13594,8 +13607,8 @@ function Boards({
13594
13607
  }
13595
13608
  }, 3e3);
13596
13609
  return () => clearTimeout(id);
13597
- }, [boardItems, isLoaded, onSave]);
13598
- const triggerInstantSave = async (updatedBoardItems) => {
13610
+ }, [boardItems, isLoaded, onSave, sanitizeBoardItems]);
13611
+ const triggerInstantSave = (0, import_react29.useCallback)(async (updatedBoardItems) => {
13599
13612
  if (!onSave) return;
13600
13613
  const sanitized = sanitizeBoardItems(updatedBoardItems);
13601
13614
  const sanitizedJson = JSON.stringify(sanitized);
@@ -13609,7 +13622,7 @@ function Boards({
13609
13622
  console.error("Erro ao salvar board:", err);
13610
13623
  setSaveStatus("error");
13611
13624
  }
13612
- };
13625
+ }, [onSave, sanitizeBoardItems]);
13613
13626
  (0, import_react29.useEffect)(() => {
13614
13627
  if (!isOpen) return;
13615
13628
  const handler = (e) => {
@@ -13638,19 +13651,7 @@ function Boards({
13638
13651
  const lastFolder = currentPath[currentPath.length - 1];
13639
13652
  return lastFolder ? lastFolder.children : boardItems;
13640
13653
  }, [boardItems, currentPath]);
13641
- const navigateUp = () => {
13642
- setNavigationStack((prev) => prev.slice(0, -1));
13643
- };
13644
- const navigateTo = (folderId) => {
13645
- setNavigationStack((prev) => [...prev, folderId]);
13646
- };
13647
- const navigateToBreadcrumb = (index) => {
13648
- setNavigationStack((prev) => prev.slice(0, index + 1));
13649
- };
13650
- const navigateHome = () => {
13651
- setNavigationStack([]);
13652
- };
13653
- const handleAddItem = (type = "text_group") => {
13654
+ const handleAddItem = (0, import_react29.useCallback)((type = "text_group") => {
13654
13655
  const newItem = {
13655
13656
  id: (0, import_uuid11.v4)(),
13656
13657
  type,
@@ -13667,8 +13668,8 @@ function Boards({
13667
13668
  );
13668
13669
  setBoardItems((prev) => add(prev));
13669
13670
  }
13670
- };
13671
- const handleAddSubgroup = (parentId, type = "text_group") => {
13671
+ }, [navigationStack]);
13672
+ const handleAddSubgroup = (0, import_react29.useCallback)((parentId, type = "text_group") => {
13672
13673
  const add = (list) => list.map((g) => {
13673
13674
  if (g.id === parentId) {
13674
13675
  if (g.type === "text_group" && type === "folder") return g;
@@ -13684,57 +13685,42 @@ function Boards({
13684
13685
  return { ...g, children: add(g.children) };
13685
13686
  });
13686
13687
  setBoardItems((prev) => add(prev));
13687
- };
13688
- const handleUpdateItem = (id, newData) => {
13688
+ }, []);
13689
+ const handleUpdateItem = (0, import_react29.useCallback)((id, newData) => {
13689
13690
  const update = (list) => list.map(
13690
13691
  (g) => g.id === id ? newData : { ...g, children: update(g.children) }
13691
13692
  );
13692
13693
  setBoardItems((prev) => update(prev));
13693
- };
13694
- const handleDeleteItem = (id) => {
13694
+ }, []);
13695
+ const handleDeleteItem = (0, import_react29.useCallback)((id) => {
13695
13696
  const del = (list) => list.filter((g) => g.id !== id).map((g) => ({ ...g, children: del(g.children) }));
13696
13697
  setBoardItems((prev) => del(prev));
13697
- };
13698
- const findGroupAndParent = (list, targetId, parent = null) => {
13699
- for (let i = 0; i < list.length; i++) {
13700
- if (list[i].id === targetId)
13701
- return { group: list[i], parent, index: i, siblings: list };
13702
- if (list[i].children.length > 0) {
13703
- const found = findGroupAndParent(list[i].children, targetId, list[i]);
13704
- if (found) return found;
13705
- }
13706
- }
13707
- return null;
13708
- };
13709
- const handleIndent = (id) => {
13698
+ }, []);
13699
+ const handleIndent = (0, import_react29.useCallback)((id) => {
13710
13700
  const next = JSON.parse(JSON.stringify(boardItems));
13711
13701
  const found = findGroupAndParent(next, id);
13712
13702
  if (!found || found.index === 0) return;
13713
13703
  const { group, siblings, index } = found;
13714
13704
  const targetParent = siblings[index - 1];
13715
- if (group.type === "folder" && targetParent.type === "text_group") {
13716
- return;
13717
- }
13705
+ if (group.type === "folder" && targetParent.type === "text_group") return;
13718
13706
  siblings.splice(index, 1);
13719
13707
  targetParent.children.push(group);
13720
13708
  setBoardItems(next);
13721
13709
  triggerInstantSave(next);
13722
- };
13723
- const handleIndentDown = (id) => {
13710
+ }, [boardItems, triggerInstantSave]);
13711
+ const handleIndentDown = (0, import_react29.useCallback)((id) => {
13724
13712
  const next = JSON.parse(JSON.stringify(boardItems));
13725
13713
  const found = findGroupAndParent(next, id);
13726
13714
  if (!found || found.index === found.siblings.length - 1) return;
13727
13715
  const { group, siblings, index } = found;
13728
13716
  const targetParent = siblings[index + 1];
13729
- if (group.type === "folder" && targetParent.type === "text_group") {
13730
- return;
13731
- }
13717
+ if (group.type === "folder" && targetParent.type === "text_group") return;
13732
13718
  siblings.splice(index, 1);
13733
13719
  targetParent.children.push(group);
13734
13720
  setBoardItems(next);
13735
13721
  triggerInstantSave(next);
13736
- };
13737
- const handleOutdent = (id) => {
13722
+ }, [boardItems, triggerInstantSave]);
13723
+ const handleOutdent = (0, import_react29.useCallback)((id) => {
13738
13724
  const next = JSON.parse(JSON.stringify(boardItems));
13739
13725
  const found = findGroupAndParent(next, id);
13740
13726
  if (!found || !found.parent) return;
@@ -13748,8 +13734,8 @@ function Boards({
13748
13734
  }
13749
13735
  setBoardItems(next);
13750
13736
  triggerInstantSave(next);
13751
- };
13752
- const handleMoveUp = (id) => {
13737
+ }, [boardItems, triggerInstantSave]);
13738
+ const handleMoveUp = (0, import_react29.useCallback)((id) => {
13753
13739
  const next = JSON.parse(JSON.stringify(boardItems));
13754
13740
  const found = findGroupAndParent(next, id);
13755
13741
  if (!found || found.index === 0) return;
@@ -13759,8 +13745,8 @@ function Boards({
13759
13745
  siblings.splice(index - 1, 0, item);
13760
13746
  setBoardItems(next);
13761
13747
  triggerInstantSave(next);
13762
- };
13763
- const handleMoveDown = (id) => {
13748
+ }, [boardItems, triggerInstantSave]);
13749
+ const handleMoveDown = (0, import_react29.useCallback)((id) => {
13764
13750
  const next = JSON.parse(JSON.stringify(boardItems));
13765
13751
  const found = findGroupAndParent(next, id);
13766
13752
  if (!found || found.index === found.siblings.length - 1) return;
@@ -13770,10 +13756,22 @@ function Boards({
13770
13756
  siblings.splice(index + 1, 0, item);
13771
13757
  setBoardItems(next);
13772
13758
  triggerInstantSave(next);
13773
- };
13774
- const handleMentionClick = (item) => {
13759
+ }, [boardItems, triggerInstantSave]);
13760
+ const handleMentionClick = (0, import_react29.useCallback)((item) => {
13775
13761
  if (onSelect) onSelect(item);
13776
- };
13762
+ }, [onSelect]);
13763
+ const navigateUp = (0, import_react29.useCallback)(() => {
13764
+ setNavigationStack((prev) => prev.slice(0, -1));
13765
+ }, []);
13766
+ const navigateTo = (0, import_react29.useCallback)((folderId) => {
13767
+ setNavigationStack((prev) => [...prev, folderId]);
13768
+ }, []);
13769
+ const navigateToBreadcrumb = (0, import_react29.useCallback)((index) => {
13770
+ setNavigationStack((prev) => prev.slice(0, index + 1));
13771
+ }, []);
13772
+ const navigateHome = (0, import_react29.useCallback)(() => {
13773
+ setNavigationStack([]);
13774
+ }, []);
13777
13775
  if (!isOpen) return null;
13778
13776
  return /* @__PURE__ */ import_react29.default.createElement(
13779
13777
  "div",
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/XViewScene.jsx
2
2
  import React30, {
3
- useCallback as useCallback5,
3
+ useCallback as useCallback6,
4
4
  useEffect as useEffect24,
5
5
  useRef as useRef21,
6
6
  useState as useState29,
@@ -12950,7 +12950,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
12950
12950
  }
12951
12951
 
12952
12952
  // src/components/Boards.jsx
12953
- import React28, { useState as useState27, useMemo as useMemo12, useEffect as useEffect23, useRef as useRef20 } from "react";
12953
+ import React28, { useState as useState27, useMemo as useMemo12, useEffect as useEffect23, useRef as useRef20, useCallback as useCallback5 } from "react";
12954
12954
  import {
12955
12955
  FiSearch as FiSearch8,
12956
12956
  FiLayers as FiLayers7,
@@ -13119,7 +13119,7 @@ function domToContent(el) {
13119
13119
  el.childNodes.forEach(walk);
13120
13120
  return segments;
13121
13121
  }
13122
- function RichGroupEditor({
13122
+ var RichGroupEditor = React27.memo(function RichGroupEditor2({
13123
13123
  content,
13124
13124
  onChange,
13125
13125
  onMentionClick,
@@ -13329,14 +13329,17 @@ function RichGroupEditor({
13329
13329
  onClose: handleMentionDismiss
13330
13330
  }
13331
13331
  ));
13332
- }
13332
+ }, (prevProps, nextProps) => {
13333
+ return prevProps.readOnly === nextProps.readOnly && prevProps.placeholder === nextProps.placeholder && prevProps.content === nextProps.content && prevProps.searchItems === nextProps.searchItems;
13334
+ });
13335
+ var RichGroupEditor_default = RichGroupEditor;
13333
13336
 
13334
13337
  // src/components/Boards.jsx
13335
13338
  var Tooltip = ({ text, children }) => {
13336
13339
  if (!text) return children;
13337
13340
  return /* @__PURE__ */ React28.createElement("div", { className: "relative group/tooltip" }, children, /* @__PURE__ */ React28.createElement("div", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 bg-slate-900 border border-white/10 text-white text-[10px] rounded opacity-0 group-hover/tooltip:opacity-100 transition-opacity pointer-events-none whitespace-nowrap z-[3000] shadow-2xl" }, text));
13338
13341
  };
13339
- var BoardItem = ({
13342
+ var BoardItem = React28.memo(({
13340
13343
  item,
13341
13344
  index,
13342
13345
  prevItem,
@@ -13359,7 +13362,6 @@ var BoardItem = ({
13359
13362
  const isFolder = item.type === "folder";
13360
13363
  const canMoveUp = index > 0;
13361
13364
  const canMoveDown = nextItem !== void 0;
13362
- const isNested = onOutdent !== void 0;
13363
13365
  const getIndentUpTooltip = () => {
13364
13366
  if (!prevItem) return null;
13365
13367
  const typeLabel = prevItem.type === "folder" ? "pasta" : "grupo de texto";
@@ -13464,7 +13466,7 @@ var BoardItem = ({
13464
13466
  ));
13465
13467
  }
13466
13468
  return /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col gap-2 mb-3 pl-3 border-l border-white/10 relative group/item animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React28.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col gap-2 py-2 px-3 transition-all duration-200 hover:bg-white/5 border-l-2 border-transparent hover:border-white/20" }, /* @__PURE__ */ React28.createElement(
13467
- RichGroupEditor,
13469
+ RichGroupEditor_default,
13468
13470
  {
13469
13471
  content: item.content,
13470
13472
  onChange: handleContentChange,
@@ -13550,7 +13552,7 @@ var BoardItem = ({
13550
13552
  isAtRoot: false
13551
13553
  }
13552
13554
  ))));
13553
- };
13555
+ });
13554
13556
  function Boards({
13555
13557
  isOpen,
13556
13558
  onClose,
@@ -13567,13 +13569,24 @@ function Boards({
13567
13569
  const [navigationStack, setNavigationStack] = useState27([]);
13568
13570
  const lastSavedBoardItemsRef = useRef20(null);
13569
13571
  const canEdit = useMemo12(() => userRole !== "viewer", [userRole]);
13570
- const sanitizeBoardItems = (list) => list.map((g) => ({
13572
+ const findGroupAndParent = (list, targetId, parent = null) => {
13573
+ for (let i = 0; i < list.length; i++) {
13574
+ if (list[i].id === targetId)
13575
+ return { group: list[i], parent, index: i, siblings: list };
13576
+ if (list[i].children.length > 0) {
13577
+ const found = findGroupAndParent(list[i].children, targetId, list[i]);
13578
+ if (found) return found;
13579
+ }
13580
+ }
13581
+ return null;
13582
+ };
13583
+ const sanitizeBoardItems = useCallback5((list) => list.map((g) => ({
13571
13584
  id: g.id,
13572
13585
  type: g.type || "text_group",
13573
13586
  name: g.name || "",
13574
13587
  content: g.content || [],
13575
13588
  children: sanitizeBoardItems(g.children || [])
13576
- }));
13589
+ })), []);
13577
13590
  useEffect23(() => {
13578
13591
  if (initialBoardItems && !isLoaded) {
13579
13592
  const hasLegacyTypes = (list) => list.some(
@@ -13644,8 +13657,8 @@ function Boards({
13644
13657
  }
13645
13658
  }, 3e3);
13646
13659
  return () => clearTimeout(id);
13647
- }, [boardItems, isLoaded, onSave]);
13648
- const triggerInstantSave = async (updatedBoardItems) => {
13660
+ }, [boardItems, isLoaded, onSave, sanitizeBoardItems]);
13661
+ const triggerInstantSave = useCallback5(async (updatedBoardItems) => {
13649
13662
  if (!onSave) return;
13650
13663
  const sanitized = sanitizeBoardItems(updatedBoardItems);
13651
13664
  const sanitizedJson = JSON.stringify(sanitized);
@@ -13659,7 +13672,7 @@ function Boards({
13659
13672
  console.error("Erro ao salvar board:", err);
13660
13673
  setSaveStatus("error");
13661
13674
  }
13662
- };
13675
+ }, [onSave, sanitizeBoardItems]);
13663
13676
  useEffect23(() => {
13664
13677
  if (!isOpen) return;
13665
13678
  const handler = (e) => {
@@ -13688,19 +13701,7 @@ function Boards({
13688
13701
  const lastFolder = currentPath[currentPath.length - 1];
13689
13702
  return lastFolder ? lastFolder.children : boardItems;
13690
13703
  }, [boardItems, currentPath]);
13691
- const navigateUp = () => {
13692
- setNavigationStack((prev) => prev.slice(0, -1));
13693
- };
13694
- const navigateTo = (folderId) => {
13695
- setNavigationStack((prev) => [...prev, folderId]);
13696
- };
13697
- const navigateToBreadcrumb = (index) => {
13698
- setNavigationStack((prev) => prev.slice(0, index + 1));
13699
- };
13700
- const navigateHome = () => {
13701
- setNavigationStack([]);
13702
- };
13703
- const handleAddItem = (type = "text_group") => {
13704
+ const handleAddItem = useCallback5((type = "text_group") => {
13704
13705
  const newItem = {
13705
13706
  id: uuidv411(),
13706
13707
  type,
@@ -13717,8 +13718,8 @@ function Boards({
13717
13718
  );
13718
13719
  setBoardItems((prev) => add(prev));
13719
13720
  }
13720
- };
13721
- const handleAddSubgroup = (parentId, type = "text_group") => {
13721
+ }, [navigationStack]);
13722
+ const handleAddSubgroup = useCallback5((parentId, type = "text_group") => {
13722
13723
  const add = (list) => list.map((g) => {
13723
13724
  if (g.id === parentId) {
13724
13725
  if (g.type === "text_group" && type === "folder") return g;
@@ -13734,57 +13735,42 @@ function Boards({
13734
13735
  return { ...g, children: add(g.children) };
13735
13736
  });
13736
13737
  setBoardItems((prev) => add(prev));
13737
- };
13738
- const handleUpdateItem = (id, newData) => {
13738
+ }, []);
13739
+ const handleUpdateItem = useCallback5((id, newData) => {
13739
13740
  const update = (list) => list.map(
13740
13741
  (g) => g.id === id ? newData : { ...g, children: update(g.children) }
13741
13742
  );
13742
13743
  setBoardItems((prev) => update(prev));
13743
- };
13744
- const handleDeleteItem = (id) => {
13744
+ }, []);
13745
+ const handleDeleteItem = useCallback5((id) => {
13745
13746
  const del = (list) => list.filter((g) => g.id !== id).map((g) => ({ ...g, children: del(g.children) }));
13746
13747
  setBoardItems((prev) => del(prev));
13747
- };
13748
- const findGroupAndParent = (list, targetId, parent = null) => {
13749
- for (let i = 0; i < list.length; i++) {
13750
- if (list[i].id === targetId)
13751
- return { group: list[i], parent, index: i, siblings: list };
13752
- if (list[i].children.length > 0) {
13753
- const found = findGroupAndParent(list[i].children, targetId, list[i]);
13754
- if (found) return found;
13755
- }
13756
- }
13757
- return null;
13758
- };
13759
- const handleIndent = (id) => {
13748
+ }, []);
13749
+ const handleIndent = useCallback5((id) => {
13760
13750
  const next = JSON.parse(JSON.stringify(boardItems));
13761
13751
  const found = findGroupAndParent(next, id);
13762
13752
  if (!found || found.index === 0) return;
13763
13753
  const { group, siblings, index } = found;
13764
13754
  const targetParent = siblings[index - 1];
13765
- if (group.type === "folder" && targetParent.type === "text_group") {
13766
- return;
13767
- }
13755
+ if (group.type === "folder" && targetParent.type === "text_group") return;
13768
13756
  siblings.splice(index, 1);
13769
13757
  targetParent.children.push(group);
13770
13758
  setBoardItems(next);
13771
13759
  triggerInstantSave(next);
13772
- };
13773
- const handleIndentDown = (id) => {
13760
+ }, [boardItems, triggerInstantSave]);
13761
+ const handleIndentDown = useCallback5((id) => {
13774
13762
  const next = JSON.parse(JSON.stringify(boardItems));
13775
13763
  const found = findGroupAndParent(next, id);
13776
13764
  if (!found || found.index === found.siblings.length - 1) return;
13777
13765
  const { group, siblings, index } = found;
13778
13766
  const targetParent = siblings[index + 1];
13779
- if (group.type === "folder" && targetParent.type === "text_group") {
13780
- return;
13781
- }
13767
+ if (group.type === "folder" && targetParent.type === "text_group") return;
13782
13768
  siblings.splice(index, 1);
13783
13769
  targetParent.children.push(group);
13784
13770
  setBoardItems(next);
13785
13771
  triggerInstantSave(next);
13786
- };
13787
- const handleOutdent = (id) => {
13772
+ }, [boardItems, triggerInstantSave]);
13773
+ const handleOutdent = useCallback5((id) => {
13788
13774
  const next = JSON.parse(JSON.stringify(boardItems));
13789
13775
  const found = findGroupAndParent(next, id);
13790
13776
  if (!found || !found.parent) return;
@@ -13798,8 +13784,8 @@ function Boards({
13798
13784
  }
13799
13785
  setBoardItems(next);
13800
13786
  triggerInstantSave(next);
13801
- };
13802
- const handleMoveUp = (id) => {
13787
+ }, [boardItems, triggerInstantSave]);
13788
+ const handleMoveUp = useCallback5((id) => {
13803
13789
  const next = JSON.parse(JSON.stringify(boardItems));
13804
13790
  const found = findGroupAndParent(next, id);
13805
13791
  if (!found || found.index === 0) return;
@@ -13809,8 +13795,8 @@ function Boards({
13809
13795
  siblings.splice(index - 1, 0, item);
13810
13796
  setBoardItems(next);
13811
13797
  triggerInstantSave(next);
13812
- };
13813
- const handleMoveDown = (id) => {
13798
+ }, [boardItems, triggerInstantSave]);
13799
+ const handleMoveDown = useCallback5((id) => {
13814
13800
  const next = JSON.parse(JSON.stringify(boardItems));
13815
13801
  const found = findGroupAndParent(next, id);
13816
13802
  if (!found || found.index === found.siblings.length - 1) return;
@@ -13820,10 +13806,22 @@ function Boards({
13820
13806
  siblings.splice(index + 1, 0, item);
13821
13807
  setBoardItems(next);
13822
13808
  triggerInstantSave(next);
13823
- };
13824
- const handleMentionClick = (item) => {
13809
+ }, [boardItems, triggerInstantSave]);
13810
+ const handleMentionClick = useCallback5((item) => {
13825
13811
  if (onSelect) onSelect(item);
13826
- };
13812
+ }, [onSelect]);
13813
+ const navigateUp = useCallback5(() => {
13814
+ setNavigationStack((prev) => prev.slice(0, -1));
13815
+ }, []);
13816
+ const navigateTo = useCallback5((folderId) => {
13817
+ setNavigationStack((prev) => [...prev, folderId]);
13818
+ }, []);
13819
+ const navigateToBreadcrumb = useCallback5((index) => {
13820
+ setNavigationStack((prev) => prev.slice(0, index + 1));
13821
+ }, []);
13822
+ const navigateHome = useCallback5(() => {
13823
+ setNavigationStack([]);
13824
+ }, []);
13827
13825
  if (!isOpen) return null;
13828
13826
  return /* @__PURE__ */ React28.createElement(
13829
13827
  "div",
@@ -14355,10 +14353,10 @@ function XViewScene({
14355
14353
  }
14356
14354
  stateRef.current.nodeIdToParentFileMap = map;
14357
14355
  }, [isInitialized, sceneVersion]);
14358
- const handleNavigateBack = useCallback5(() => {
14356
+ const handleNavigateBack = useCallback6(() => {
14359
14357
  router.push("/dashboard/scenes");
14360
14358
  }, [router]);
14361
- const handleConfirmImport = useCallback5(
14359
+ const handleConfirmImport = useCallback6(
14362
14360
  async (importPayload) => {
14363
14361
  var _a2, _b2;
14364
14362
  let files = [];
@@ -14486,7 +14484,7 @@ function XViewScene({
14486
14484
  const handleOpenImageViewer = (images, startIndex) => {
14487
14485
  setImageViewer({ visible: true, images, startIndex });
14488
14486
  };
14489
- const tweenToTarget = useCallback5(
14487
+ const tweenToTarget = useCallback6(
14490
14488
  (target, zoomFactor = 1, forcedDirection = null) => {
14491
14489
  const { camera, controls, tweenGroup } = stateRef.current;
14492
14490
  if (!camera || !controls || !tweenGroup) return;
@@ -14512,7 +14510,7 @@ function XViewScene({
14512
14510
  if (!t || typeof t.closest !== "function") return false;
14513
14511
  return !!t.closest(".ui-overlay");
14514
14512
  };
14515
- const buildFullAncestryTree = useCallback5(
14513
+ const buildFullAncestryTree = useCallback6(
14516
14514
  (idTree, nodes, ancestries = []) => {
14517
14515
  if (!idTree) return null;
14518
14516
  const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
@@ -14597,7 +14595,7 @@ function XViewScene({
14597
14595
  },
14598
14596
  []
14599
14597
  );
14600
- const handleActivateTimeline = useCallback5(() => {
14598
+ const handleActivateTimeline = useCallback6(() => {
14601
14599
  const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
14602
14600
  if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
14603
14601
  while (timelineIntervalsGroup.children.length > 0) {
@@ -14757,7 +14755,7 @@ function XViewScene({
14757
14755
  }
14758
14756
  });
14759
14757
  }, []);
14760
- const handleVersionTimeline = useCallback5((sourceMesh, versionMeshes) => {
14758
+ const handleVersionTimeline = useCallback6((sourceMesh, versionMeshes) => {
14761
14759
  const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
14762
14760
  if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0)
14763
14761
  return;
@@ -14999,12 +14997,12 @@ function XViewScene({
14999
14997
  focusNodeId,
15000
14998
  focusAncestryId
15001
14999
  ]);
15002
- const isNodeInView = useCallback5((id) => {
15000
+ const isNodeInView = useCallback6((id) => {
15003
15001
  const key = String(id);
15004
15002
  const objs = stateRef.current.nodeObjects || {};
15005
15003
  return !!objs[key];
15006
15004
  }, []);
15007
- const addOrUpdateNodeMesh = useCallback5(
15005
+ const addOrUpdateNodeMesh = useCallback6(
15008
15006
  (nodeData, position, suppressVersionUpdate = false, forceShowQuestDate = false) => {
15009
15007
  const {
15010
15008
  graphGroup,
@@ -15045,7 +15043,7 @@ function XViewScene({
15045
15043
  },
15046
15044
  []
15047
15045
  );
15048
- const handleActivateQuestLens = useCallback5(({ assigneeId, status: status2, milestoneId }) => {
15046
+ const handleActivateQuestLens = useCallback6(({ assigneeId, status: status2, milestoneId }) => {
15049
15047
  var _a2;
15050
15048
  const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
15051
15049
  if (!nodeObjects || !tweenGroup || !graphGroup) return;
@@ -16015,7 +16013,7 @@ function XViewScene({
16015
16013
  get_scene_view_data,
16016
16014
  save_view_data
16017
16015
  ]);
16018
- const handleGhostNodeImageChange = useCallback5((useImage, imageUrl) => {
16016
+ const handleGhostNodeImageChange = useCallback6((useImage, imageUrl) => {
16019
16017
  const {
16020
16018
  node: ghostNode,
16021
16019
  line: ghostLine,
@@ -16063,7 +16061,7 @@ function XViewScene({
16063
16061
  aura: newGhostNode.getObjectByName("aura")
16064
16062
  };
16065
16063
  }, []);
16066
- const handleGhostNodeIntensityChange = useCallback5((newIntensity) => {
16064
+ const handleGhostNodeIntensityChange = useCallback6((newIntensity) => {
16067
16065
  const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
16068
16066
  if (!ghostNode) return;
16069
16067
  const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
@@ -16084,7 +16082,7 @@ function XViewScene({
16084
16082
  ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
16085
16083
  }
16086
16084
  }, []);
16087
- const handleDetailNodeIntensityChange = useCallback5(
16085
+ const handleDetailNodeIntensityChange = useCallback6(
16088
16086
  (nodeId, newIntensity) => {
16089
16087
  const mesh = stateRef.current.nodeObjects[String(nodeId)];
16090
16088
  if (!mesh) return;
@@ -16240,7 +16238,7 @@ function XViewScene({
16240
16238
  mountRef.current.style.cursor = "default";
16241
16239
  }
16242
16240
  };
16243
- const handleAncestryTreeUpdate = useCallback5((newTree, extraData = null) => {
16241
+ const handleAncestryTreeUpdate = useCallback6((newTree, extraData = null) => {
16244
16242
  setAncestryMode((prev) => {
16245
16243
  const prevTreeStr = JSON.stringify(prev.tree);
16246
16244
  const newTreeStr = JSON.stringify(newTree);
@@ -16324,7 +16322,7 @@ function XViewScene({
16324
16322
  const handleStartVersioning = (nodeData) => {
16325
16323
  userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
16326
16324
  };
16327
- const handleStartQuestQuick = useCallback5((questNode) => {
16325
+ const handleStartQuestQuick = useCallback6((questNode) => {
16328
16326
  var _a2, _b2, _c2;
16329
16327
  if (!questNode || !actionHandlerContext) return;
16330
16328
  const allParentNodes = Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
@@ -16359,7 +16357,7 @@ function XViewScene({
16359
16357
  }
16360
16358
  setDetailsNode(updatedNode);
16361
16359
  }, [session, actionHandlerContext]);
16362
- const handleFinishQuestQuick = useCallback5((questNode) => {
16360
+ const handleFinishQuestQuick = useCallback6((questNode) => {
16363
16361
  var _a2, _b2, _c2, _d2;
16364
16362
  if (!questNode || !actionHandlerContext) return;
16365
16363
  const {
@@ -16433,7 +16431,7 @@ function XViewScene({
16433
16431
  setDetailsNode(null);
16434
16432
  }
16435
16433
  }, [session, actionHandlerContext, viewMembers, detailsNode]);
16436
- const handleCancelQuest = useCallback5(() => {
16434
+ const handleCancelQuest = useCallback6(() => {
16437
16435
  const { graphGroup, ghostElements } = stateRef.current;
16438
16436
  if (ghostElements.node && graphGroup) {
16439
16437
  if (ghostElements.node.userData.labelObject) {
@@ -16590,7 +16588,7 @@ function XViewScene({
16590
16588
  }
16591
16589
  userActionHandlers.handleCancelConnection(context);
16592
16590
  };
16593
- const handleClearAncestryVisuals = useCallback5((ancestryId) => {
16591
+ const handleClearAncestryVisuals = useCallback6((ancestryId) => {
16594
16592
  const { renderedAncestries, ancestryGroup } = stateRef.current;
16595
16593
  const renderIndex = renderedAncestries.findIndex(
16596
16594
  (a) => String(a.id) === String(ancestryId)
@@ -16608,7 +16606,7 @@ function XViewScene({
16608
16606
  );
16609
16607
  }
16610
16608
  }, []);
16611
- const handleRenderAncestry = useCallback5(
16609
+ const handleRenderAncestry = useCallback6(
16612
16610
  async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
16613
16611
  setContextMenu(
16614
16612
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -17102,7 +17100,7 @@ function XViewScene({
17102
17100
  ancestryMode.isActive
17103
17101
  ]
17104
17102
  );
17105
- const handleRenderAbstractionTree = useCallback5(
17103
+ const handleRenderAbstractionTree = useCallback6(
17106
17104
  (ancestryObject, targetNodeId = null) => {
17107
17105
  setContextMenu(
17108
17106
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -17190,7 +17188,7 @@ function XViewScene({
17190
17188
  handleClearAncestryVisuals
17191
17189
  ]
17192
17190
  );
17193
- const handleReadModeBranchNav = useCallback5(
17191
+ const handleReadModeBranchNav = useCallback6(
17194
17192
  (nodeId, action, direction = "right") => {
17195
17193
  const { ancestry, branchStack } = readingMode;
17196
17194
  if (!ancestry || !ancestry.tree) return;
@@ -17368,7 +17366,7 @@ function XViewScene({
17368
17366
  },
17369
17367
  [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]
17370
17368
  );
17371
- const handleReadModeHighlight = useCallback5((nodeId) => {
17369
+ const handleReadModeHighlight = useCallback6((nodeId) => {
17372
17370
  if (stateRef.current.highlightedNodeId !== nodeId) {
17373
17371
  stateRef.current.highlightedNodeId = nodeId;
17374
17372
  }
@@ -17491,7 +17489,7 @@ function XViewScene({
17491
17489
  buildFullAncestryTree,
17492
17490
  sceneVersion
17493
17491
  ]);
17494
- const handleStartReadingAncestry = useCallback5(
17492
+ const handleStartReadingAncestry = useCallback6(
17495
17493
  async (ancestryObject, renderMode = "full") => {
17496
17494
  setContextMenu(
17497
17495
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -17534,7 +17532,7 @@ function XViewScene({
17534
17532
  },
17535
17533
  [handleRenderAncestry, handleRenderAbstractionTree]
17536
17534
  );
17537
- const handleReadModeSectionChange = useCallback5(
17535
+ const handleReadModeSectionChange = useCallback6(
17538
17536
  (activeSectionId) => {
17539
17537
  const { ancestry, branchStack } = readingMode;
17540
17538
  if (!ancestry || !readingMode.isActive) return;
@@ -17619,10 +17617,10 @@ function XViewScene({
17619
17617
  ancestryDataRef.current
17620
17618
  ]
17621
17619
  );
17622
- const handleCloseReadMode = useCallback5(() => {
17620
+ const handleCloseReadMode = useCallback6(() => {
17623
17621
  setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
17624
17622
  }, []);
17625
- const handleAncestrySectionChange = useCallback5(
17623
+ const handleAncestrySectionChange = useCallback6(
17626
17624
  (activeSectionId, ancestryOverride = null, rotation = 0) => {
17627
17625
  var _a2, _b2;
17628
17626
  const currentMode = stateRef.current.ancestry;
@@ -17684,7 +17682,7 @@ function XViewScene({
17684
17682
  },
17685
17683
  [handleRenderAncestry]
17686
17684
  );
17687
- const handleEditAncestry = useCallback5(
17685
+ const handleEditAncestry = useCallback6(
17688
17686
  async (ancestryObject) => {
17689
17687
  setContextMenu(
17690
17688
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -17739,7 +17737,7 @@ function XViewScene({
17739
17737
  const handleSelectAncestryParent = (nodeId) => {
17740
17738
  setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
17741
17739
  };
17742
- const handleRemoveFromAncestry = useCallback5((pathToRemove) => {
17740
+ const handleRemoveFromAncestry = useCallback6((pathToRemove) => {
17743
17741
  if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
17744
17742
  console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
17745
17743
  return;
@@ -17764,7 +17762,7 @@ function XViewScene({
17764
17762
  return { ...prev, tree: newTree };
17765
17763
  });
17766
17764
  }, []);
17767
- const handleSaveAncestry = useCallback5(
17765
+ const handleSaveAncestry = useCallback6(
17768
17766
  async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
17769
17767
  const treeToUse = treeOverride || ancestryMode.tree;
17770
17768
  const { isEditMode, currentAncestryId } = ancestryMode;
@@ -18000,7 +17998,7 @@ function XViewScene({
18000
17998
  });
18001
17999
  setEditingAncestryRel({ visible: false, data: null, path: null });
18002
18000
  };
18003
- const handleDeleteAncestry = useCallback5(
18001
+ const handleDeleteAncestry = useCallback6(
18004
18002
  async (ancestryIdToDelete) => {
18005
18003
  if (!ancestryIdToDelete) {
18006
18004
  alert("ID da ancestralidade n\xE3o encontrado.");
@@ -18082,7 +18080,7 @@ function XViewScene({
18082
18080
  },
18083
18081
  [save_view_data, delete_file_action]
18084
18082
  );
18085
- const handleOpenBoards = useCallback5(() => {
18083
+ const handleOpenBoards = useCallback6(() => {
18086
18084
  setIsBoardsOpen(true);
18087
18085
  }, []);
18088
18086
  const allAvailableNodes = useMemo13(() => {
@@ -18094,7 +18092,7 @@ function XViewScene({
18094
18092
  const allAvailableAncestries = useMemo13(() => {
18095
18093
  return ancestryDataRef.current || [];
18096
18094
  }, [sceneVersion, isInitialized]);
18097
- const handleFocusNode = useCallback5(
18095
+ const handleFocusNode = useCallback6(
18098
18096
  (nodeData) => {
18099
18097
  var _a2;
18100
18098
  if (!nodeData) return;
@@ -18110,7 +18108,7 @@ function XViewScene({
18110
18108
  },
18111
18109
  [tweenToTarget]
18112
18110
  );
18113
- const handleOpenReference = useCallback5(
18111
+ const handleOpenReference = useCallback6(
18114
18112
  (referenceData) => {
18115
18113
  const { type, id } = referenceData;
18116
18114
  if (type === "node") {
@@ -18146,7 +18144,7 @@ function XViewScene({
18146
18144
  handleFocusNode
18147
18145
  ]
18148
18146
  );
18149
- const handleSelectAncestryFromBoard = useCallback5(
18147
+ const handleSelectAncestryFromBoard = useCallback6(
18150
18148
  (item) => {
18151
18149
  setIsBoardsOpen(false);
18152
18150
  setIsSidebarOpen(false);
@@ -18158,7 +18156,7 @@ function XViewScene({
18158
18156
  },
18159
18157
  [handleStartReadingAncestry, handleOpenReference]
18160
18158
  );
18161
- const handleSaveBoards = useCallback5(
18159
+ const handleSaveBoards = useCallback6(
18162
18160
  async (boardItems2) => {
18163
18161
  if (!sceneConfigId || !viewParams || !session) return;
18164
18162
  const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
@@ -18199,7 +18197,7 @@ function XViewScene({
18199
18197
  return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
18200
18198
  });
18201
18199
  }, [parentDataRef.current, sceneVersion]);
18202
- const handleAddExistingNode = useCallback5(
18200
+ const handleAddExistingNode = useCallback6(
18203
18201
  (nodeId) => {
18204
18202
  return userActionHandlers.handleAddExistingNodeById(
18205
18203
  actionHandlerContext,
@@ -18208,7 +18206,7 @@ function XViewScene({
18208
18206
  },
18209
18207
  [actionHandlerContext]
18210
18208
  );
18211
- const handleUpdateMilestones = useCallback5(
18209
+ const handleUpdateMilestones = useCallback6(
18212
18210
  async (newMilestones) => {
18213
18211
  var _a2, _b2, _c2;
18214
18212
  if (!sceneDataRef.current) return;
@@ -18254,7 +18252,7 @@ function XViewScene({
18254
18252
  viewParams == null ? void 0 : viewParams.type
18255
18253
  ]
18256
18254
  );
18257
- const handleSaveCurrentView = useCallback5(async () => {
18255
+ const handleSaveCurrentView = useCallback6(async () => {
18258
18256
  var _a2, _b2, _c2;
18259
18257
  const { nodeObjects, allLinks } = stateRef.current;
18260
18258
  if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
@@ -18297,7 +18295,7 @@ function XViewScene({
18297
18295
  console.error("Erro na chamada de save_view_data:", error);
18298
18296
  }
18299
18297
  }, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
18300
- const handleToggleAncestryAddMode = useCallback5(() => {
18298
+ const handleToggleAncestryAddMode = useCallback6(() => {
18301
18299
  setAncestryMode((prev) => ({
18302
18300
  ...prev,
18303
18301
  isAddingNodes: !prev.isAddingNodes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lv-x-software-house/x_view",
3
- "version": "1.2.6-dev.31",
3
+ "version": "1.2.6-dev.33",
4
4
  "description": "Pacote privado contendo os componentes e lógica de renderização 3D do X View.",
5
5
  "author": "iv.x - Engenharia de Software - ivxsoftwarehouse@gmail.com",
6
6
  "license": "UNLICENSED",