@lv-x-software-house/x_view 1.2.5 → 1.2.6-dev.10
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 +781 -671
- package/dist/index.mjs +788 -676
- package/dist/server.js +480 -0
- package/dist/server.mjs +445 -0
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// src/XViewScene.jsx
|
|
2
|
-
import
|
|
3
|
-
useCallback as
|
|
4
|
-
useEffect as
|
|
5
|
-
useRef as
|
|
6
|
-
useState as
|
|
7
|
-
useMemo as
|
|
2
|
+
import React30, {
|
|
3
|
+
useCallback as useCallback5,
|
|
4
|
+
useEffect as useEffect24,
|
|
5
|
+
useRef as useRef20,
|
|
6
|
+
useState as useState29,
|
|
7
|
+
useMemo as useMemo13
|
|
8
8
|
} from "react";
|
|
9
9
|
import { useRouter, useSearchParams } from "next/navigation";
|
|
10
10
|
import { useSession } from "next-auth/react";
|
|
@@ -79,55 +79,7 @@ function defineAbilityFor(role) {
|
|
|
79
79
|
|
|
80
80
|
// src/logic/x_view_utils.js
|
|
81
81
|
import { useState, useCallback } from "react";
|
|
82
|
-
|
|
83
|
-
// node_modules/uuid/dist/esm-node/rng.js
|
|
84
|
-
import crypto from "crypto";
|
|
85
|
-
var rnds8Pool = new Uint8Array(256);
|
|
86
|
-
var poolPtr = rnds8Pool.length;
|
|
87
|
-
function rng() {
|
|
88
|
-
if (poolPtr > rnds8Pool.length - 16) {
|
|
89
|
-
crypto.randomFillSync(rnds8Pool);
|
|
90
|
-
poolPtr = 0;
|
|
91
|
-
}
|
|
92
|
-
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// node_modules/uuid/dist/esm-node/stringify.js
|
|
96
|
-
var byteToHex = [];
|
|
97
|
-
for (let i = 0; i < 256; ++i) {
|
|
98
|
-
byteToHex.push((i + 256).toString(16).slice(1));
|
|
99
|
-
}
|
|
100
|
-
function unsafeStringify(arr, offset = 0) {
|
|
101
|
-
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// node_modules/uuid/dist/esm-node/native.js
|
|
105
|
-
import crypto2 from "crypto";
|
|
106
|
-
var native_default = {
|
|
107
|
-
randomUUID: crypto2.randomUUID
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
// node_modules/uuid/dist/esm-node/v4.js
|
|
111
|
-
function v4(options, buf, offset) {
|
|
112
|
-
if (native_default.randomUUID && !buf && !options) {
|
|
113
|
-
return native_default.randomUUID();
|
|
114
|
-
}
|
|
115
|
-
options = options || {};
|
|
116
|
-
const rnds = options.random || (options.rng || rng)();
|
|
117
|
-
rnds[6] = rnds[6] & 15 | 64;
|
|
118
|
-
rnds[8] = rnds[8] & 63 | 128;
|
|
119
|
-
if (buf) {
|
|
120
|
-
offset = offset || 0;
|
|
121
|
-
for (let i = 0; i < 16; ++i) {
|
|
122
|
-
buf[offset + i] = rnds[i];
|
|
123
|
-
}
|
|
124
|
-
return buf;
|
|
125
|
-
}
|
|
126
|
-
return unsafeStringify(rnds);
|
|
127
|
-
}
|
|
128
|
-
var v4_default = v4;
|
|
129
|
-
|
|
130
|
-
// src/logic/x_view_utils.js
|
|
82
|
+
import { v4 as uuidv4 } from "uuid";
|
|
131
83
|
import * as THREE2 from "three";
|
|
132
84
|
|
|
133
85
|
// src/logic/x_view_config.js
|
|
@@ -1101,6 +1053,8 @@ var userActionHandlers = {
|
|
|
1101
1053
|
if (isCrossDataset) {
|
|
1102
1054
|
graphDataRef.current[finalTargetDatasetId] = targetDataToUpdate;
|
|
1103
1055
|
}
|
|
1056
|
+
if (sceneDataRef.current.parent_dbs.some((db) => String(db.db_id) === String(sourceParentInfo.parentFileId))) {
|
|
1057
|
+
}
|
|
1104
1058
|
const finalPosition = stateRef.current.ghostElements.node.position.clone();
|
|
1105
1059
|
addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
|
|
1106
1060
|
stateRef.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
@@ -1299,6 +1253,9 @@ var userActionHandlers = {
|
|
|
1299
1253
|
);
|
|
1300
1254
|
}
|
|
1301
1255
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
1256
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
1257
|
+
sceneDataRef.current.quest_nodes = [...specificParentData.nodes];
|
|
1258
|
+
}
|
|
1302
1259
|
const finalPosition = stateRef.current.ghostElements.node.position.clone();
|
|
1303
1260
|
addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
|
|
1304
1261
|
setters.setSceneVersion((v) => v + 1);
|
|
@@ -2330,6 +2287,10 @@ var userActionHandlers = {
|
|
|
2330
2287
|
);
|
|
2331
2288
|
}
|
|
2332
2289
|
graphDataRef.current[parentFileId] = specificParentData;
|
|
2290
|
+
if (isView && parentFileId === context.sceneConfigId) {
|
|
2291
|
+
sceneDataRef.current.quest_nodes = [...specificParentData.nodes];
|
|
2292
|
+
sceneDataRef.current.quest_counter = specificParentData.quest_counter || sceneDataRef.current.quest_counter;
|
|
2293
|
+
}
|
|
2333
2294
|
updateExistingNodeVisuals(stateRef.current, nodeToSave);
|
|
2334
2295
|
setters.setSceneVersion((v) => v + 1);
|
|
2335
2296
|
if (!keepOpen) {
|
|
@@ -2478,15 +2439,15 @@ function createNewCustomProperty(existingProps = []) {
|
|
|
2478
2439
|
switch (nextType) {
|
|
2479
2440
|
case "links":
|
|
2480
2441
|
nextKey = "Links";
|
|
2481
|
-
nextValue = [{ id:
|
|
2442
|
+
nextValue = [{ id: uuidv4(), name: "", value: "" }];
|
|
2482
2443
|
break;
|
|
2483
2444
|
case "images":
|
|
2484
2445
|
nextKey = "Images";
|
|
2485
|
-
nextValue = [{ id:
|
|
2446
|
+
nextValue = [{ id: uuidv4(), name: "1", value: "" }];
|
|
2486
2447
|
break;
|
|
2487
2448
|
case "documents":
|
|
2488
2449
|
nextKey = "Documents";
|
|
2489
|
-
nextValue = [{ id:
|
|
2450
|
+
nextValue = [{ id: uuidv4(), name: "1", value: "" }];
|
|
2490
2451
|
break;
|
|
2491
2452
|
case "date":
|
|
2492
2453
|
nextKey = "Date";
|
|
@@ -2496,14 +2457,14 @@ function createNewCustomProperty(existingProps = []) {
|
|
|
2496
2457
|
nextValue = 0;
|
|
2497
2458
|
break;
|
|
2498
2459
|
case "list":
|
|
2499
|
-
nextValue = [{ id:
|
|
2460
|
+
nextValue = [{ id: uuidv4(), name: "", value: "" }];
|
|
2500
2461
|
break;
|
|
2501
2462
|
default:
|
|
2502
2463
|
nextValue = "";
|
|
2503
2464
|
break;
|
|
2504
2465
|
}
|
|
2505
2466
|
return {
|
|
2506
|
-
id:
|
|
2467
|
+
id: uuidv4(),
|
|
2507
2468
|
key: nextKey,
|
|
2508
2469
|
type: nextType,
|
|
2509
2470
|
value: nextValue,
|
|
@@ -2748,7 +2709,7 @@ function extractCustomPropsFromNode(node) {
|
|
|
2748
2709
|
if (val && typeof val === "object") {
|
|
2749
2710
|
if ("date_interval" in val) {
|
|
2750
2711
|
return {
|
|
2751
|
-
id:
|
|
2712
|
+
id: uuidv4(),
|
|
2752
2713
|
key,
|
|
2753
2714
|
type: "date",
|
|
2754
2715
|
value: {
|
|
@@ -2760,7 +2721,7 @@ function extractCustomPropsFromNode(node) {
|
|
|
2760
2721
|
}
|
|
2761
2722
|
if ("year" in val) {
|
|
2762
2723
|
return {
|
|
2763
|
-
id:
|
|
2724
|
+
id: uuidv4(),
|
|
2764
2725
|
key,
|
|
2765
2726
|
type: "date",
|
|
2766
2727
|
value: { type: "Ano", value: val.year || "" }
|
|
@@ -2768,7 +2729,7 @@ function extractCustomPropsFromNode(node) {
|
|
|
2768
2729
|
}
|
|
2769
2730
|
if ("date" in val) {
|
|
2770
2731
|
return {
|
|
2771
|
-
id:
|
|
2732
|
+
id: uuidv4(),
|
|
2772
2733
|
key,
|
|
2773
2734
|
type: "date",
|
|
2774
2735
|
value: { type: "Data", value: val.date || "" }
|
|
@@ -2776,7 +2737,7 @@ function extractCustomPropsFromNode(node) {
|
|
|
2776
2737
|
}
|
|
2777
2738
|
}
|
|
2778
2739
|
return {
|
|
2779
|
-
id:
|
|
2740
|
+
id: uuidv4(),
|
|
2780
2741
|
key,
|
|
2781
2742
|
type: "date",
|
|
2782
2743
|
value: { type: "Data", value: "" }
|
|
@@ -2784,14 +2745,14 @@ function extractCustomPropsFromNode(node) {
|
|
|
2784
2745
|
}
|
|
2785
2746
|
if (t === "list" || t === "links" || t === "images" || t === "documents") {
|
|
2786
2747
|
const safeList = (val || []).map((item) => ({
|
|
2787
|
-
id: item.id ||
|
|
2748
|
+
id: item.id || uuidv4(),
|
|
2788
2749
|
name: item.name ?? "",
|
|
2789
2750
|
value: item.value ?? ""
|
|
2790
2751
|
}));
|
|
2791
|
-
return { id:
|
|
2752
|
+
return { id: uuidv4(), key, type: t, value: safeList };
|
|
2792
2753
|
}
|
|
2793
2754
|
return {
|
|
2794
|
-
id:
|
|
2755
|
+
id: uuidv4(),
|
|
2795
2756
|
key,
|
|
2796
2757
|
type: t,
|
|
2797
2758
|
value: t === "number" ? Number(val) || 0 : String(val ?? "")
|
|
@@ -3064,16 +3025,16 @@ var processDescriptionForSave = (text, existingSections = []) => {
|
|
|
3064
3025
|
if (existingMatch) {
|
|
3065
3026
|
finalUuid = existingMatch.id;
|
|
3066
3027
|
} else {
|
|
3067
|
-
finalUuid =
|
|
3028
|
+
finalUuid = uuidv4();
|
|
3068
3029
|
}
|
|
3069
3030
|
} else {
|
|
3070
3031
|
finalUuid = numericMap.get(numStr);
|
|
3071
3032
|
if (!finalUuid) {
|
|
3072
|
-
finalUuid =
|
|
3033
|
+
finalUuid = uuidv4();
|
|
3073
3034
|
}
|
|
3074
3035
|
}
|
|
3075
3036
|
if (usedIds.has(finalUuid)) {
|
|
3076
|
-
finalUuid =
|
|
3037
|
+
finalUuid = uuidv4();
|
|
3077
3038
|
}
|
|
3078
3039
|
usedIds.add(finalUuid);
|
|
3079
3040
|
processedSections.push({
|
|
@@ -3184,18 +3145,18 @@ function useResizablePanel({ initialWidth, minWidth, maxWidth }) {
|
|
|
3184
3145
|
function createTimelineEntry(actorId, description, type = "comment", extras = {}) {
|
|
3185
3146
|
const { links = [], images = [], metadata = {} } = extras;
|
|
3186
3147
|
return {
|
|
3187
|
-
id:
|
|
3148
|
+
id: uuidv4(),
|
|
3188
3149
|
type,
|
|
3189
3150
|
timestamp: Date.now(),
|
|
3190
3151
|
actorId,
|
|
3191
3152
|
description,
|
|
3192
3153
|
links: links.map((l) => ({
|
|
3193
|
-
id: l.id ||
|
|
3154
|
+
id: l.id || uuidv4(),
|
|
3194
3155
|
name: l.name || "",
|
|
3195
3156
|
value: l.value || ""
|
|
3196
3157
|
})),
|
|
3197
3158
|
images: images.map((img) => ({
|
|
3198
|
-
id: img.id ||
|
|
3159
|
+
id: img.id || uuidv4(),
|
|
3199
3160
|
name: img.name || "",
|
|
3200
3161
|
value: img.value || ""
|
|
3201
3162
|
}))
|
|
@@ -4422,6 +4383,7 @@ function XViewSidebar({
|
|
|
4422
4383
|
|
|
4423
4384
|
// src/components/AncestryRelationshipPanel.jsx
|
|
4424
4385
|
import React8, { useState as useState9, useEffect as useEffect8, useRef as useRef7 } from "react";
|
|
4386
|
+
import { v4 as uuidv43 } from "uuid";
|
|
4425
4387
|
|
|
4426
4388
|
// src/components/CustomPropertyDisplay.jsx
|
|
4427
4389
|
import React3, { useState as useState4, useRef as useRef3, useEffect as useEffect3 } from "react";
|
|
@@ -5181,6 +5143,7 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
5181
5143
|
}
|
|
5182
5144
|
|
|
5183
5145
|
// src/components/DescriptionEditModal.jsx
|
|
5146
|
+
import { v4 as uuidv42 } from "uuid";
|
|
5184
5147
|
var getNextSectionNumber = (currentText) => {
|
|
5185
5148
|
const regex = /\*\/\s*(\d+)(?::[a-zA-Z0-9-]+)?\s*\//g;
|
|
5186
5149
|
let max = 0;
|
|
@@ -5312,7 +5275,7 @@ function DescriptionEditModal({
|
|
|
5312
5275
|
const el = textareaRef.current;
|
|
5313
5276
|
if (!el) return;
|
|
5314
5277
|
const nextNum = getNextSectionNumber(text);
|
|
5315
|
-
const uniqueSuffix =
|
|
5278
|
+
const uniqueSuffix = uuidv42().slice(0, 4);
|
|
5316
5279
|
insertAtCursor(`*/${nextNum}:${uniqueSuffix}/ `);
|
|
5317
5280
|
};
|
|
5318
5281
|
const handleImportSelect = (tags) => {
|
|
@@ -5323,7 +5286,7 @@ function DescriptionEditModal({
|
|
|
5323
5286
|
let currentNum = getNextSectionNumber(currentText);
|
|
5324
5287
|
let blockToInsert = "";
|
|
5325
5288
|
tagsArray.forEach((tag) => {
|
|
5326
|
-
const uniqueSuffix =
|
|
5289
|
+
const uniqueSuffix = uuidv42().slice(0, 4);
|
|
5327
5290
|
blockToInsert += `
|
|
5328
5291
|
*/${currentNum}:${uniqueSuffix}/ ${tag}
|
|
5329
5292
|
`;
|
|
@@ -6683,6 +6646,7 @@ import {
|
|
|
6683
6646
|
FiLink as FiLink4,
|
|
6684
6647
|
FiTrash2 as FiTrash22
|
|
6685
6648
|
} from "react-icons/fi";
|
|
6649
|
+
import { v4 as uuidv44 } from "uuid";
|
|
6686
6650
|
|
|
6687
6651
|
// src/components/AncestryPickerModal.jsx
|
|
6688
6652
|
import React9, { useState as useState10, useMemo as useMemo7, useEffect as useEffect9 } from "react";
|
|
@@ -7719,7 +7683,7 @@ function CreateAncestryPanel({
|
|
|
7719
7683
|
const nodeData = availableNodes.find((n) => String(n.id) === String(nodeId));
|
|
7720
7684
|
const dirSuffix = direction === "left" ? "(Esq)" : "(Dir)";
|
|
7721
7685
|
branch = {
|
|
7722
|
-
id:
|
|
7686
|
+
id: uuidv44(),
|
|
7723
7687
|
name: `Ramifica\xE7\xE3o ${dirSuffix} de ${(nodeData == null ? void 0 : nodeData.name) || "Node"}`,
|
|
7724
7688
|
description: "",
|
|
7725
7689
|
description_sections: [],
|
|
@@ -8498,6 +8462,7 @@ function ImageViewer({ data, onClose }) {
|
|
|
8498
8462
|
|
|
8499
8463
|
// src/components/InSceneCreationForm.jsx
|
|
8500
8464
|
import React13, { useState as useState14, useEffect as useEffect13, useRef as useRef10 } from "react";
|
|
8465
|
+
import { v4 as uuidv45 } from "uuid";
|
|
8501
8466
|
|
|
8502
8467
|
// src/components/ColorPicker.jsx
|
|
8503
8468
|
import React12, { useState as useState13, useEffect as useEffect12, useRef as useRef9 } from "react";
|
|
@@ -9082,6 +9047,7 @@ function InSceneCreationForm({
|
|
|
9082
9047
|
|
|
9083
9048
|
// src/components/InSceneVersionForm.jsx
|
|
9084
9049
|
import React14, { useState as useState15, useEffect as useEffect14, useRef as useRef11 } from "react";
|
|
9050
|
+
import { v4 as uuidv46 } from "uuid";
|
|
9085
9051
|
import { FiPlus as FiPlus4, FiMaximize2 as FiMaximize22, FiCheck as FiCheck8, FiEdit2 as FiEdit25 } from "react-icons/fi";
|
|
9086
9052
|
function InSceneVersionForm({
|
|
9087
9053
|
onSave,
|
|
@@ -9104,7 +9070,7 @@ function InSceneVersionForm({
|
|
|
9104
9070
|
const [description, setDescription] = useState15("");
|
|
9105
9071
|
const [customProps, setCustomProps] = useState15([
|
|
9106
9072
|
{
|
|
9107
|
-
id:
|
|
9073
|
+
id: uuidv46(),
|
|
9108
9074
|
key: "Date",
|
|
9109
9075
|
type: "date",
|
|
9110
9076
|
value: { type: "Data", value: "" },
|
|
@@ -9397,6 +9363,7 @@ function InSceneVersionForm({
|
|
|
9397
9363
|
|
|
9398
9364
|
// src/components/InSceneQuestForm.jsx
|
|
9399
9365
|
import React16, { useState as useState17, useRef as useRef12 } from "react";
|
|
9366
|
+
import { v4 as uuidv47 } from "uuid";
|
|
9400
9367
|
import {
|
|
9401
9368
|
FiPlus as FiPlus6,
|
|
9402
9369
|
FiCheck as FiCheck9,
|
|
@@ -10321,6 +10288,7 @@ function InSceneQuestForm({
|
|
|
10321
10288
|
|
|
10322
10289
|
// src/components/NodeDetailsPanel.jsx
|
|
10323
10290
|
import React17, { useState as useState18, useEffect as useEffect15, useRef as useRef13 } from "react";
|
|
10291
|
+
import { v4 as uuidv48 } from "uuid";
|
|
10324
10292
|
import { FiPlus as FiPlus7, FiMaximize2 as FiMaximize23, FiX as FiX6, FiCheck as FiCheck10, FiImage as FiImage3, FiEdit2 as FiEdit27, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5, FiDatabase } from "react-icons/fi";
|
|
10325
10293
|
function NodeDetailsPanel({
|
|
10326
10294
|
node,
|
|
@@ -10835,6 +10803,7 @@ function NodeDetailsPanel({
|
|
|
10835
10803
|
|
|
10836
10804
|
// src/components/QuestDetailsPanel.jsx
|
|
10837
10805
|
import React19, { useState as useState19, useEffect as useEffect16, useRef as useRef14 } from "react";
|
|
10806
|
+
import { v4 as uuidv49 } from "uuid";
|
|
10838
10807
|
import { FiPlus as FiPlus8, FiX as FiX7, FiCheck as FiCheck11, FiEdit2 as FiEdit28, FiLoader as FiLoader3, FiBookOpen as FiBookOpen4, FiLink as FiLink7, FiTarget as FiTarget3, FiChevronDown as FiChevronDown7, FiUser as FiUser3, FiSearch as FiSearch7, FiRepeat as FiRepeat2, FiCalendar as FiCalendar2, FiImage as FiImage4 } from "react-icons/fi";
|
|
10839
10808
|
|
|
10840
10809
|
// src/components/QuestTimeline.jsx
|
|
@@ -11285,7 +11254,7 @@ ${noteText}` : noteText : entry.notes,
|
|
|
11285
11254
|
}, 100);
|
|
11286
11255
|
};
|
|
11287
11256
|
const addLinkToNote = () => {
|
|
11288
|
-
setNoteLinks([...noteLinks, { id:
|
|
11257
|
+
setNoteLinks([...noteLinks, { id: uuidv49(), name: "", value: "" }]);
|
|
11289
11258
|
};
|
|
11290
11259
|
const removeLinkFromNote = (id) => {
|
|
11291
11260
|
setNoteLinks(noteLinks.filter((l) => l.id !== id));
|
|
@@ -11294,7 +11263,7 @@ ${noteText}` : noteText : entry.notes,
|
|
|
11294
11263
|
setNoteLinks(noteLinks.map((l) => l.id === id ? { ...l, [field]: val } : l));
|
|
11295
11264
|
};
|
|
11296
11265
|
const addImageToNote = () => {
|
|
11297
|
-
setNoteImages([...noteImages, { id:
|
|
11266
|
+
setNoteImages([...noteImages, { id: uuidv49(), name: "Image", value: "" }]);
|
|
11298
11267
|
};
|
|
11299
11268
|
const removeImageFromNote = (id) => {
|
|
11300
11269
|
setNoteImages(noteImages.filter((img) => img.id !== id));
|
|
@@ -12171,6 +12140,7 @@ function MultiNodeContextMenu({
|
|
|
12171
12140
|
|
|
12172
12141
|
// src/components/RelationshipDetailsPanel.jsx
|
|
12173
12142
|
import React21, { useState as useState21, useEffect as useEffect18, useRef as useRef16, useMemo as useMemo9 } from "react";
|
|
12143
|
+
import { v4 as uuidv410 } from "uuid";
|
|
12174
12144
|
import { FiPlus as FiPlus9, FiEdit2 as FiEdit29, FiLoader as FiLoader4, FiBookOpen as FiBookOpen5 } from "react-icons/fi";
|
|
12175
12145
|
function RelationshipDetailsPanel({
|
|
12176
12146
|
link,
|
|
@@ -12980,10 +12950,10 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
12980
12950
|
}
|
|
12981
12951
|
|
|
12982
12952
|
// src/components/AncestryBoard.jsx
|
|
12983
|
-
import
|
|
12953
|
+
import React28, { useState as useState27, useMemo as useMemo12, useEffect as useEffect23 } from "react";
|
|
12984
12954
|
import {
|
|
12985
12955
|
FiSearch as FiSearch8,
|
|
12986
|
-
FiLayers as
|
|
12956
|
+
FiLayers as FiLayers7,
|
|
12987
12957
|
FiCornerUpRight as FiCornerUpRight4,
|
|
12988
12958
|
FiPlay,
|
|
12989
12959
|
FiPlus as FiPlus10,
|
|
@@ -12993,173 +12963,418 @@ import {
|
|
|
12993
12963
|
FiCheckCircle,
|
|
12994
12964
|
FiLoader as FiLoader5,
|
|
12995
12965
|
FiX as FiX8,
|
|
12996
|
-
|
|
12966
|
+
FiBox as FiBox2,
|
|
12967
|
+
FiCheckSquare as FiCheckSquare4,
|
|
12968
|
+
FiGitBranch as FiGitBranch4
|
|
12997
12969
|
} from "react-icons/fi";
|
|
12970
|
+
import { v4 as uuidv411 } from "uuid";
|
|
12971
|
+
|
|
12972
|
+
// src/components/RichGroupEditor.jsx
|
|
12973
|
+
import React27, { useEffect as useEffect22, useRef as useRef19, useState as useState26, useCallback as useCallback4 } from "react";
|
|
12974
|
+
|
|
12975
|
+
// src/components/MentionPopover.jsx
|
|
12976
|
+
import React26, { useEffect as useEffect21, useRef as useRef18, useState as useState25, useMemo as useMemo11 } from "react";
|
|
12977
|
+
import { FiLayers as FiLayers6, FiCheckSquare as FiCheckSquare3, FiGitBranch as FiGitBranch3, FiBox } from "react-icons/fi";
|
|
12978
|
+
var TYPE_CONFIG = {
|
|
12979
|
+
ancestry: { Icon: FiLayers6, color: "text-indigo-400", label: "Ancestralidade" },
|
|
12980
|
+
quest: { Icon: FiCheckSquare3, color: "text-emerald-400", label: "Quest" },
|
|
12981
|
+
version: { Icon: FiGitBranch3, color: "text-amber-400", label: "Vers\xE3o" },
|
|
12982
|
+
node: { Icon: FiBox, color: "text-slate-400", label: "Node" }
|
|
12983
|
+
};
|
|
12984
|
+
function MentionPopover({ query, items, position, onSelect, onClose }) {
|
|
12985
|
+
const [activeIndex, setActiveIndex] = useState25(0);
|
|
12986
|
+
const listRef = useRef18(null);
|
|
12987
|
+
const filtered = useMemo11(() => {
|
|
12988
|
+
const term = (query || "").toLowerCase().trim();
|
|
12989
|
+
if (!term) return items.slice(0, 8);
|
|
12990
|
+
return items.filter(
|
|
12991
|
+
(item) => (item.searchLabel || "").toLowerCase().includes(term) || (item.searchDesc || "").toLowerCase().includes(term)
|
|
12992
|
+
).slice(0, 8);
|
|
12993
|
+
}, [items, query]);
|
|
12994
|
+
useEffect21(() => {
|
|
12995
|
+
setActiveIndex(0);
|
|
12996
|
+
}, [query]);
|
|
12997
|
+
useEffect21(() => {
|
|
12998
|
+
const handleKeyDown = (e) => {
|
|
12999
|
+
if (e.key === "ArrowDown") {
|
|
13000
|
+
e.preventDefault();
|
|
13001
|
+
setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));
|
|
13002
|
+
} else if (e.key === "ArrowUp") {
|
|
13003
|
+
e.preventDefault();
|
|
13004
|
+
setActiveIndex((i) => Math.max(i - 1, 0));
|
|
13005
|
+
} else if (e.key === "Enter" || e.key === "Tab") {
|
|
13006
|
+
e.preventDefault();
|
|
13007
|
+
if (filtered[activeIndex]) onSelect(filtered[activeIndex]);
|
|
13008
|
+
} else if (e.key === "Escape") {
|
|
13009
|
+
e.preventDefault();
|
|
13010
|
+
onClose();
|
|
13011
|
+
}
|
|
13012
|
+
};
|
|
13013
|
+
window.addEventListener("keydown", handleKeyDown, true);
|
|
13014
|
+
return () => window.removeEventListener("keydown", handleKeyDown, true);
|
|
13015
|
+
}, [filtered, activeIndex, onSelect, onClose]);
|
|
13016
|
+
useEffect21(() => {
|
|
13017
|
+
if (listRef.current) {
|
|
13018
|
+
const el = listRef.current.children[activeIndex];
|
|
13019
|
+
if (el) el.scrollIntoView({ block: "nearest" });
|
|
13020
|
+
}
|
|
13021
|
+
}, [activeIndex]);
|
|
13022
|
+
return /* @__PURE__ */ React26.createElement(
|
|
13023
|
+
"div",
|
|
13024
|
+
{
|
|
13025
|
+
style: { top: position.top, left: position.left, position: "fixed", zIndex: 9999 },
|
|
13026
|
+
className: "bg-slate-900 border border-white/10 rounded-xl shadow-2xl py-1.5 min-w-[260px] max-h-[240px] overflow-y-auto custom-scrollbar animate-in fade-in zoom-in-95 duration-100",
|
|
13027
|
+
ref: listRef,
|
|
13028
|
+
onMouseDown: (e) => e.preventDefault()
|
|
13029
|
+
},
|
|
13030
|
+
filtered.length === 0 ? /* @__PURE__ */ React26.createElement("div", { className: "px-4 py-3 text-xs text-slate-500" }, "Nenhum resultado para", " ", /* @__PURE__ */ React26.createElement("span", { className: "text-slate-300 font-medium" }, '"', query, '"')) : filtered.map((item, idx) => {
|
|
13031
|
+
const config = TYPE_CONFIG[item.type] || TYPE_CONFIG.node;
|
|
13032
|
+
const { Icon } = config;
|
|
13033
|
+
return /* @__PURE__ */ React26.createElement(
|
|
13034
|
+
"div",
|
|
13035
|
+
{
|
|
13036
|
+
key: item.id,
|
|
13037
|
+
onMouseDown: (e) => {
|
|
13038
|
+
e.preventDefault();
|
|
13039
|
+
onSelect(item);
|
|
13040
|
+
},
|
|
13041
|
+
onMouseEnter: () => setActiveIndex(idx),
|
|
13042
|
+
className: `flex items-center gap-2.5 px-3 py-2 cursor-pointer text-sm transition-colors duration-100 ${idx === activeIndex ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5"}`
|
|
13043
|
+
},
|
|
13044
|
+
/* @__PURE__ */ React26.createElement(Icon, { size: 13, className: config.color }),
|
|
13045
|
+
/* @__PURE__ */ React26.createElement("span", { className: "flex-1 truncate font-medium" }, item.searchLabel || "Sem Nome"),
|
|
13046
|
+
/* @__PURE__ */ React26.createElement("span", { className: "text-[9px] px-1.5 py-0.5 rounded-full bg-white/5 text-slate-500 border border-white/5 uppercase tracking-wide shrink-0" }, config.label)
|
|
13047
|
+
);
|
|
13048
|
+
})
|
|
13049
|
+
);
|
|
13050
|
+
}
|
|
13051
|
+
|
|
13052
|
+
// src/components/RichGroupEditor.jsx
|
|
13053
|
+
var MENTION_BASE_STYLE = "display:inline-flex;align-items:center;padding:1px 7px;border-radius:5px;margin:0 2px;font-size:0.78em;font-weight:600;cursor:pointer;white-space:nowrap;vertical-align:middle;user-select:none;line-height:1.6;";
|
|
13054
|
+
var MENTION_TYPE_STYLE = {
|
|
13055
|
+
ancestry: "background:rgba(99,102,241,0.18);color:#a5b4fc;border:1px solid rgba(99,102,241,0.35);",
|
|
13056
|
+
quest: "background:rgba(16,185,129,0.18);color:#6ee7b7;border:1px solid rgba(16,185,129,0.35);",
|
|
13057
|
+
version: "background:rgba(245,158,11,0.18);color:#fcd34d;border:1px solid rgba(245,158,11,0.35);",
|
|
13058
|
+
node: "background:rgba(100,116,139,0.18);color:#94a3b8;border:1px solid rgba(100,116,139,0.35);"
|
|
13059
|
+
};
|
|
13060
|
+
function mentionStyle(type) {
|
|
13061
|
+
return MENTION_BASE_STYLE + (MENTION_TYPE_STYLE[type] || MENTION_TYPE_STYLE.node);
|
|
13062
|
+
}
|
|
13063
|
+
function escapeHtml(str) {
|
|
13064
|
+
return String(str || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
13065
|
+
}
|
|
13066
|
+
function contentToHTML(content) {
|
|
13067
|
+
if (!content || content.length === 0) return "";
|
|
13068
|
+
return content.map((seg) => {
|
|
13069
|
+
if (seg.type === "text") {
|
|
13070
|
+
return escapeHtml(seg.value).replace(/\n/g, "<br>");
|
|
13071
|
+
}
|
|
13072
|
+
if (seg.type === "mention") {
|
|
13073
|
+
const style = mentionStyle(seg.mentionType);
|
|
13074
|
+
return `<span contenteditable="false" data-mention="true" data-id="${escapeHtml(String(seg.id))}" data-name="${escapeHtml(seg.name || "")}" data-mention-type="${escapeHtml(seg.mentionType || "node")}" style="${style}" title="Clique para focar na cena">@${escapeHtml(seg.name || "")}</span>`;
|
|
13075
|
+
}
|
|
13076
|
+
return "";
|
|
13077
|
+
}).join("");
|
|
13078
|
+
}
|
|
13079
|
+
function domToContent(el) {
|
|
13080
|
+
const segments = [];
|
|
13081
|
+
function pushText(text) {
|
|
13082
|
+
const clean = text.replace(/\u200B/g, "");
|
|
13083
|
+
if (!clean) return;
|
|
13084
|
+
const last = segments[segments.length - 1];
|
|
13085
|
+
if (last && last.type === "text") {
|
|
13086
|
+
last.value += clean;
|
|
13087
|
+
} else {
|
|
13088
|
+
segments.push({ type: "text", value: clean });
|
|
13089
|
+
}
|
|
13090
|
+
}
|
|
13091
|
+
function walk(node) {
|
|
13092
|
+
var _a;
|
|
13093
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
13094
|
+
pushText(node.textContent);
|
|
13095
|
+
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
13096
|
+
if (((_a = node.dataset) == null ? void 0 : _a.mention) === "true") {
|
|
13097
|
+
segments.push({
|
|
13098
|
+
type: "mention",
|
|
13099
|
+
id: node.dataset.id,
|
|
13100
|
+
name: node.dataset.name,
|
|
13101
|
+
mentionType: node.dataset.mentionType
|
|
13102
|
+
});
|
|
13103
|
+
} else if (node.tagName === "BR") {
|
|
13104
|
+
pushText("\n");
|
|
13105
|
+
} else {
|
|
13106
|
+
if (["DIV", "P"].includes(node.tagName) && segments.length > 0) {
|
|
13107
|
+
pushText("\n");
|
|
13108
|
+
}
|
|
13109
|
+
node.childNodes.forEach(walk);
|
|
13110
|
+
}
|
|
13111
|
+
}
|
|
13112
|
+
}
|
|
13113
|
+
el.childNodes.forEach(walk);
|
|
13114
|
+
return segments;
|
|
13115
|
+
}
|
|
13116
|
+
function RichGroupEditor({
|
|
13117
|
+
content,
|
|
13118
|
+
onChange,
|
|
13119
|
+
onMentionClick,
|
|
13120
|
+
searchItems,
|
|
13121
|
+
readOnly,
|
|
13122
|
+
placeholder
|
|
13123
|
+
}) {
|
|
13124
|
+
const editorRef = useRef19(null);
|
|
13125
|
+
const isMountedRef = useRef19(false);
|
|
13126
|
+
const [mentionState, setMentionState] = useState26(null);
|
|
13127
|
+
const [isEmpty, setIsEmpty] = useState26(true);
|
|
13128
|
+
useEffect22(() => {
|
|
13129
|
+
if (!isMountedRef.current && editorRef.current) {
|
|
13130
|
+
editorRef.current.innerHTML = contentToHTML(content);
|
|
13131
|
+
const hasContent = !!editorRef.current.innerText.replace(/\u200B/g, "").trim();
|
|
13132
|
+
const hasMentions = !!editorRef.current.querySelector("[data-mention]");
|
|
13133
|
+
setIsEmpty(!hasContent && !hasMentions);
|
|
13134
|
+
isMountedRef.current = true;
|
|
13135
|
+
}
|
|
13136
|
+
}, []);
|
|
13137
|
+
const getMentionContext = useCallback4(() => {
|
|
13138
|
+
const selection = window.getSelection();
|
|
13139
|
+
if (!selection || selection.rangeCount === 0) return null;
|
|
13140
|
+
const range = selection.getRangeAt(0);
|
|
13141
|
+
if (range.startContainer.nodeType !== Node.TEXT_NODE) return null;
|
|
13142
|
+
const textBefore = range.startContainer.textContent.substring(0, range.startOffset);
|
|
13143
|
+
const atIndex = textBefore.lastIndexOf("@");
|
|
13144
|
+
if (atIndex === -1) return null;
|
|
13145
|
+
const query = textBefore.substring(atIndex + 1);
|
|
13146
|
+
if (query.includes(" ") || query.includes(".") || query.includes(",") || query.length > 40) {
|
|
13147
|
+
return null;
|
|
13148
|
+
}
|
|
13149
|
+
const rect = range.getBoundingClientRect();
|
|
13150
|
+
return {
|
|
13151
|
+
query,
|
|
13152
|
+
position: { top: rect.bottom + 6, left: rect.left }
|
|
13153
|
+
};
|
|
13154
|
+
}, []);
|
|
13155
|
+
const handleInput = useCallback4(() => {
|
|
13156
|
+
if (!editorRef.current) return;
|
|
13157
|
+
const serialized = domToContent(editorRef.current);
|
|
13158
|
+
onChange(serialized);
|
|
13159
|
+
const text = editorRef.current.innerText.replace(/\u200B/g, "").trim();
|
|
13160
|
+
const hasMentions = !!editorRef.current.querySelector("[data-mention]");
|
|
13161
|
+
setIsEmpty(!text && !hasMentions);
|
|
13162
|
+
const ctx = getMentionContext();
|
|
13163
|
+
setMentionState(ctx);
|
|
13164
|
+
}, [onChange, getMentionContext]);
|
|
13165
|
+
const handleKeyDown = useCallback4(
|
|
13166
|
+
(e) => {
|
|
13167
|
+
if (mentionState && ["ArrowDown", "ArrowUp", "Enter", "Tab", "Escape"].includes(e.key)) {
|
|
13168
|
+
return;
|
|
13169
|
+
}
|
|
13170
|
+
if (e.key === "Enter") {
|
|
13171
|
+
e.preventDefault();
|
|
13172
|
+
const sel = window.getSelection();
|
|
13173
|
+
const range = sel.getRangeAt(0);
|
|
13174
|
+
const br = document.createElement("br");
|
|
13175
|
+
range.deleteContents();
|
|
13176
|
+
range.insertNode(br);
|
|
13177
|
+
const afterBr = br.nextSibling || (() => {
|
|
13178
|
+
const zws = document.createTextNode("\u200B");
|
|
13179
|
+
br.parentNode.insertBefore(zws, br.nextSibling);
|
|
13180
|
+
return zws;
|
|
13181
|
+
})();
|
|
13182
|
+
const newRange = document.createRange();
|
|
13183
|
+
newRange.setStartBefore(afterBr);
|
|
13184
|
+
newRange.collapse(true);
|
|
13185
|
+
sel.removeAllRanges();
|
|
13186
|
+
sel.addRange(newRange);
|
|
13187
|
+
handleInput();
|
|
13188
|
+
}
|
|
13189
|
+
},
|
|
13190
|
+
[mentionState, handleInput]
|
|
13191
|
+
);
|
|
13192
|
+
const insertMention = useCallback4(
|
|
13193
|
+
(item) => {
|
|
13194
|
+
if (!editorRef.current) return;
|
|
13195
|
+
const sel = window.getSelection();
|
|
13196
|
+
if (!sel || sel.rangeCount === 0) return;
|
|
13197
|
+
const range = sel.getRangeAt(0);
|
|
13198
|
+
const textNode = range.startContainer;
|
|
13199
|
+
if (textNode.nodeType !== Node.TEXT_NODE) {
|
|
13200
|
+
setMentionState(null);
|
|
13201
|
+
return;
|
|
13202
|
+
}
|
|
13203
|
+
const cursorPos = range.startOffset;
|
|
13204
|
+
const textContent = textNode.textContent;
|
|
13205
|
+
const atIndex = textContent.lastIndexOf("@", cursorPos - 1);
|
|
13206
|
+
if (atIndex === -1) {
|
|
13207
|
+
setMentionState(null);
|
|
13208
|
+
return;
|
|
13209
|
+
}
|
|
13210
|
+
const before = textContent.substring(0, atIndex);
|
|
13211
|
+
const after = textContent.substring(cursorPos);
|
|
13212
|
+
textNode.textContent = before;
|
|
13213
|
+
const parent = textNode.parentNode;
|
|
13214
|
+
const nextSib = textNode.nextSibling;
|
|
13215
|
+
const span = document.createElement("span");
|
|
13216
|
+
span.contentEditable = "false";
|
|
13217
|
+
span.dataset.mention = "true";
|
|
13218
|
+
span.dataset.id = item.id;
|
|
13219
|
+
span.dataset.name = item.searchLabel || item.name || "";
|
|
13220
|
+
span.dataset.mentionType = item.type;
|
|
13221
|
+
span.style.cssText = mentionStyle(item.type);
|
|
13222
|
+
span.title = "Clique para focar na cena";
|
|
13223
|
+
span.textContent = `@${item.searchLabel || item.name || ""}`;
|
|
13224
|
+
parent.insertBefore(span, nextSib);
|
|
13225
|
+
const trailing = document.createTextNode(after || "\u200B");
|
|
13226
|
+
parent.insertBefore(trailing, span.nextSibling);
|
|
13227
|
+
const newRange = document.createRange();
|
|
13228
|
+
newRange.setStart(trailing, after ? 0 : 1);
|
|
13229
|
+
newRange.collapse(true);
|
|
13230
|
+
sel.removeAllRanges();
|
|
13231
|
+
sel.addRange(newRange);
|
|
13232
|
+
const serialized = domToContent(editorRef.current);
|
|
13233
|
+
onChange(serialized);
|
|
13234
|
+
setMentionState(null);
|
|
13235
|
+
setIsEmpty(false);
|
|
13236
|
+
},
|
|
13237
|
+
[onChange]
|
|
13238
|
+
);
|
|
13239
|
+
const handlePaste = useCallback4(
|
|
13240
|
+
(e) => {
|
|
13241
|
+
e.preventDefault();
|
|
13242
|
+
const text = e.clipboardData.getData("text/plain");
|
|
13243
|
+
if (text) {
|
|
13244
|
+
document.execCommand("insertText", false, text);
|
|
13245
|
+
handleInput();
|
|
13246
|
+
}
|
|
13247
|
+
},
|
|
13248
|
+
[handleInput]
|
|
13249
|
+
);
|
|
13250
|
+
const handleClick = useCallback4(
|
|
13251
|
+
(e) => {
|
|
13252
|
+
const chip = e.target.closest("[data-mention='true']");
|
|
13253
|
+
if (chip && onMentionClick) {
|
|
13254
|
+
e.stopPropagation();
|
|
13255
|
+
const id = chip.dataset.id;
|
|
13256
|
+
const full = searchItems == null ? void 0 : searchItems.find((i) => String(i.id) === String(id));
|
|
13257
|
+
if (full) {
|
|
13258
|
+
onMentionClick(full);
|
|
13259
|
+
} else {
|
|
13260
|
+
onMentionClick({
|
|
13261
|
+
id,
|
|
13262
|
+
name: chip.dataset.name,
|
|
13263
|
+
type: chip.dataset.mentionType,
|
|
13264
|
+
searchLabel: chip.dataset.name
|
|
13265
|
+
});
|
|
13266
|
+
}
|
|
13267
|
+
return;
|
|
13268
|
+
}
|
|
13269
|
+
setTimeout(() => {
|
|
13270
|
+
const ctx = getMentionContext();
|
|
13271
|
+
setMentionState(ctx);
|
|
13272
|
+
}, 0);
|
|
13273
|
+
},
|
|
13274
|
+
[onMentionClick, getMentionContext, searchItems]
|
|
13275
|
+
);
|
|
13276
|
+
const handleBlur = useCallback4(() => {
|
|
13277
|
+
setTimeout(() => setMentionState(null), 200);
|
|
13278
|
+
}, []);
|
|
13279
|
+
return /* @__PURE__ */ React27.createElement("div", { className: "relative" }, isEmpty && !readOnly && /* @__PURE__ */ React27.createElement("div", { className: "absolute top-0 left-0 text-sm text-slate-600 pointer-events-none select-none" }, placeholder || "Escreva sobre este grupo\u2026 ou digite @ para mencionar"), /* @__PURE__ */ React27.createElement(
|
|
13280
|
+
"div",
|
|
13281
|
+
{
|
|
13282
|
+
ref: editorRef,
|
|
13283
|
+
contentEditable: readOnly ? "false" : "true",
|
|
13284
|
+
suppressContentEditableWarning: true,
|
|
13285
|
+
onInput: handleInput,
|
|
13286
|
+
onKeyDown: handleKeyDown,
|
|
13287
|
+
onPaste: handlePaste,
|
|
13288
|
+
onClick: handleClick,
|
|
13289
|
+
onBlur: handleBlur,
|
|
13290
|
+
className: `w-full min-h-[1.5rem] max-h-[250px] overflow-y-auto text-sm text-slate-200 focus:outline-none leading-relaxed ${!readOnly ? "cursor-text" : "cursor-default"}`,
|
|
13291
|
+
style: { overflowWrap: "break-word", wordBreak: "break-word" }
|
|
13292
|
+
}
|
|
13293
|
+
), mentionState && !readOnly && /* @__PURE__ */ React27.createElement(
|
|
13294
|
+
MentionPopover,
|
|
13295
|
+
{
|
|
13296
|
+
query: mentionState.query,
|
|
13297
|
+
items: searchItems || [],
|
|
13298
|
+
position: mentionState.position,
|
|
13299
|
+
onSelect: insertMention,
|
|
13300
|
+
onClose: () => setMentionState(null)
|
|
13301
|
+
}
|
|
13302
|
+
));
|
|
13303
|
+
}
|
|
13304
|
+
|
|
13305
|
+
// src/components/AncestryBoard.jsx
|
|
12998
13306
|
var GroupItem = ({
|
|
12999
13307
|
group,
|
|
13000
13308
|
index,
|
|
13001
|
-
siblings,
|
|
13002
13309
|
onUpdate,
|
|
13003
13310
|
onDelete,
|
|
13004
13311
|
onAddSubgroup,
|
|
13005
13312
|
onIndent,
|
|
13006
13313
|
onOutdent,
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
pickingGroupId,
|
|
13010
|
-
onPlayAncestry,
|
|
13011
|
-
availableIds,
|
|
13314
|
+
searchItems,
|
|
13315
|
+
onMentionClick,
|
|
13012
13316
|
canEdit
|
|
13013
13317
|
}) => {
|
|
13014
13318
|
const canIndent = index > 0;
|
|
13015
|
-
const
|
|
13016
|
-
|
|
13017
|
-
const adjustHeight = () => {
|
|
13018
|
-
const textarea = textareaRef.current;
|
|
13019
|
-
if (textarea) {
|
|
13020
|
-
textarea.style.height = "auto";
|
|
13021
|
-
textarea.style.height = `${textarea.scrollHeight}px`;
|
|
13022
|
-
}
|
|
13319
|
+
const handleContentChange = (content) => {
|
|
13320
|
+
onUpdate(group.id, { ...group, content });
|
|
13023
13321
|
};
|
|
13024
|
-
|
|
13025
|
-
|
|
13026
|
-
}, [group.text]);
|
|
13027
|
-
return /* @__PURE__ */ React26.createElement("div", { className: "flex flex-col gap-2 mb-3 pl-3 border-l border-white/10 relative group/item animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React26.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ React26.createElement(
|
|
13028
|
-
"div",
|
|
13322
|
+
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(
|
|
13323
|
+
RichGroupEditor,
|
|
13029
13324
|
{
|
|
13030
|
-
|
|
13031
|
-
|
|
13032
|
-
|
|
13033
|
-
|
|
13325
|
+
content: group.content,
|
|
13326
|
+
onChange: handleContentChange,
|
|
13327
|
+
onMentionClick,
|
|
13328
|
+
searchItems,
|
|
13329
|
+
readOnly: !canEdit,
|
|
13330
|
+
placeholder: "Escreva sobre este grupo\u2026 ou @ para mencionar"
|
|
13331
|
+
}
|
|
13332
|
+
), canEdit && /* @__PURE__ */ React28.createElement("div", { className: "flex items-center justify-between pt-2 mt-1 border-t border-white/5 opacity-40 group-hover/item:opacity-100 transition-opacity" }, /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React28.createElement(
|
|
13333
|
+
"button",
|
|
13334
|
+
{
|
|
13335
|
+
onClick: () => onAddSubgroup(group.id),
|
|
13336
|
+
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
13337
|
+
title: "Criar Subgrupo"
|
|
13034
13338
|
},
|
|
13035
|
-
/* @__PURE__ */
|
|
13036
|
-
|
|
13037
|
-
|
|
13038
|
-
|
|
13039
|
-
|
|
13040
|
-
|
|
13041
|
-
|
|
13042
|
-
|
|
13043
|
-
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
|
|
13047
|
-
|
|
13048
|
-
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
13052
|
-
)
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
13057
|
-
|
|
13058
|
-
|
|
13059
|
-
|
|
13060
|
-
|
|
13061
|
-
|
|
13062
|
-
`,
|
|
13063
|
-
title: isValid ? "" : "Esta ancestralidade foi removida ou n\xE3o existe mais."
|
|
13064
|
-
},
|
|
13065
|
-
isValid ? (
|
|
13066
|
-
// [MANTIDO] Botão Play visível para todos
|
|
13067
|
-
/* @__PURE__ */ React26.createElement(
|
|
13068
|
-
"button",
|
|
13069
|
-
{
|
|
13070
|
-
onClick: () => onPlayAncestry(anc.ancestry_id),
|
|
13071
|
-
className: "text-indigo-400 hover:text-white hover:bg-indigo-500 p-1 rounded-full transition-colors",
|
|
13072
|
-
title: "Renderizar no cen\xE1rio"
|
|
13073
|
-
},
|
|
13074
|
-
/* @__PURE__ */ React26.createElement(FiPlay, { size: 10, className: "ml-0.5 fill-current" })
|
|
13075
|
-
)
|
|
13076
|
-
) : /* @__PURE__ */ React26.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ React26.createElement(FiAlertTriangle, { size: 10 })),
|
|
13077
|
-
/* @__PURE__ */ React26.createElement(
|
|
13078
|
-
"span",
|
|
13079
|
-
{
|
|
13080
|
-
className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}`
|
|
13081
|
-
},
|
|
13082
|
-
anc.name
|
|
13083
|
-
),
|
|
13084
|
-
canEdit && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(
|
|
13085
|
-
"div",
|
|
13086
|
-
{
|
|
13087
|
-
className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}`
|
|
13088
|
-
}
|
|
13089
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13090
|
-
"button",
|
|
13091
|
-
{
|
|
13092
|
-
onClick: () => onRemoveAncestry(group.id, anc.ancestry_id),
|
|
13093
|
-
className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
|
|
13094
|
-
title: "Remover men\xE7\xE3o"
|
|
13095
|
-
},
|
|
13096
|
-
/* @__PURE__ */ React26.createElement(FiX8, { size: 12 })
|
|
13097
|
-
))
|
|
13098
|
-
);
|
|
13099
|
-
})),
|
|
13100
|
-
canEdit && /* @__PURE__ */ React26.createElement("div", { className: "flex items-center justify-between pt-2 mt-1 border-t border-white/5 opacity-40 group-hover/item:opacity-100 transition-opacity" }, /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React26.createElement(
|
|
13101
|
-
"button",
|
|
13102
|
-
{
|
|
13103
|
-
onClick: () => onRequestPickAncestry(group.id),
|
|
13104
|
-
className: `
|
|
13105
|
-
flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium transition-colors
|
|
13106
|
-
${isPickingForThisGroup ? "text-indigo-300 animate-pulse" : "text-slate-500 hover:text-indigo-300 hover:bg-indigo-500/10"}
|
|
13107
|
-
`,
|
|
13108
|
-
title: "Adicionar Ancestralidade a este grupo"
|
|
13109
|
-
},
|
|
13110
|
-
isPickingForThisGroup ? /* @__PURE__ */ React26.createElement(FiCheckCircle, { size: 12 }) : /* @__PURE__ */ React26.createElement(FiSearch8, { size: 12 }),
|
|
13111
|
-
isPickingForThisGroup ? "Selecionando..." : "Adicionar"
|
|
13112
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13113
|
-
"button",
|
|
13114
|
-
{
|
|
13115
|
-
onClick: () => onAddSubgroup(group.id),
|
|
13116
|
-
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
13117
|
-
title: "Criar Subgrupo"
|
|
13118
|
-
},
|
|
13119
|
-
/* @__PURE__ */ React26.createElement(FiPlus10, { size: 14 })
|
|
13120
|
-
)), /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React26.createElement(
|
|
13121
|
-
"button",
|
|
13122
|
-
{
|
|
13123
|
-
onClick: () => onIndent(group.id),
|
|
13124
|
-
disabled: !canIndent,
|
|
13125
|
-
className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
|
|
13126
|
-
title: "Aninhar no grupo acima"
|
|
13127
|
-
},
|
|
13128
|
-
/* @__PURE__ */ React26.createElement(FiArrowRight2, { size: 14 })
|
|
13129
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13130
|
-
"button",
|
|
13131
|
-
{
|
|
13132
|
-
onClick: () => onOutdent(group.id),
|
|
13133
|
-
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
13134
|
-
title: "Desaninhar"
|
|
13135
|
-
},
|
|
13136
|
-
/* @__PURE__ */ React26.createElement(FiArrowLeft3, { size: 14 })
|
|
13137
|
-
), /* @__PURE__ */ React26.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ React26.createElement(
|
|
13138
|
-
"button",
|
|
13139
|
-
{
|
|
13140
|
-
onClick: () => onDelete(group.id),
|
|
13141
|
-
className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
|
|
13142
|
-
title: "Remover Grupo"
|
|
13143
|
-
},
|
|
13144
|
-
/* @__PURE__ */ React26.createElement(FiTrash23, { size: 14 })
|
|
13145
|
-
)))
|
|
13146
|
-
), group.children && group.children.length > 0 && /* @__PURE__ */ React26.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ React26.createElement(
|
|
13339
|
+
/* @__PURE__ */ React28.createElement(FiPlus10, { size: 14 })
|
|
13340
|
+
)), /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React28.createElement(
|
|
13341
|
+
"button",
|
|
13342
|
+
{
|
|
13343
|
+
onClick: () => onIndent(group.id),
|
|
13344
|
+
disabled: !canIndent,
|
|
13345
|
+
className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
|
|
13346
|
+
title: "Aninhar no grupo acima"
|
|
13347
|
+
},
|
|
13348
|
+
/* @__PURE__ */ React28.createElement(FiArrowRight2, { size: 14 })
|
|
13349
|
+
), /* @__PURE__ */ React28.createElement(
|
|
13350
|
+
"button",
|
|
13351
|
+
{
|
|
13352
|
+
onClick: () => onOutdent(group.id),
|
|
13353
|
+
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
13354
|
+
title: "Desaninhar"
|
|
13355
|
+
},
|
|
13356
|
+
/* @__PURE__ */ React28.createElement(FiArrowLeft3, { size: 14 })
|
|
13357
|
+
), /* @__PURE__ */ React28.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ React28.createElement(
|
|
13358
|
+
"button",
|
|
13359
|
+
{
|
|
13360
|
+
onClick: () => onDelete(group.id),
|
|
13361
|
+
className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
|
|
13362
|
+
title: "Remover Grupo"
|
|
13363
|
+
},
|
|
13364
|
+
/* @__PURE__ */ React28.createElement(FiTrash23, { size: 14 })
|
|
13365
|
+
)))), group.children && group.children.length > 0 && /* @__PURE__ */ React28.createElement("div", { className: "ml-2" }, group.children.map((child, idx) => /* @__PURE__ */ React28.createElement(
|
|
13147
13366
|
GroupItem,
|
|
13148
13367
|
{
|
|
13149
|
-
key:
|
|
13368
|
+
key: child.id,
|
|
13150
13369
|
index: idx,
|
|
13151
|
-
group:
|
|
13152
|
-
siblings: group.children,
|
|
13370
|
+
group: child,
|
|
13153
13371
|
onUpdate,
|
|
13154
13372
|
onDelete,
|
|
13155
13373
|
onAddSubgroup,
|
|
13156
13374
|
onIndent,
|
|
13157
13375
|
onOutdent,
|
|
13158
|
-
|
|
13159
|
-
|
|
13160
|
-
pickingGroupId,
|
|
13161
|
-
onPlayAncestry,
|
|
13162
|
-
availableIds,
|
|
13376
|
+
searchItems,
|
|
13377
|
+
onMentionClick,
|
|
13163
13378
|
canEdit
|
|
13164
13379
|
}
|
|
13165
13380
|
))));
|
|
@@ -13173,141 +13388,127 @@ function AncestryBoard({
|
|
|
13173
13388
|
initialGroups = [],
|
|
13174
13389
|
onSave,
|
|
13175
13390
|
userRole
|
|
13176
|
-
// [NOVO] Recebe a role do usuário
|
|
13177
13391
|
}) {
|
|
13178
|
-
const [searchTerm, setSearchTerm] =
|
|
13179
|
-
const [groups, setGroups] =
|
|
13180
|
-
const [isLoaded, setIsLoaded] =
|
|
13181
|
-
const [
|
|
13182
|
-
const
|
|
13183
|
-
|
|
13184
|
-
return userRole !== "viewer";
|
|
13185
|
-
}, [userRole]);
|
|
13186
|
-
useEffect21(() => {
|
|
13392
|
+
const [searchTerm, setSearchTerm] = useState27("");
|
|
13393
|
+
const [groups, setGroups] = useState27([]);
|
|
13394
|
+
const [isLoaded, setIsLoaded] = useState27(false);
|
|
13395
|
+
const [saveStatus, setSaveStatus] = useState27("idle");
|
|
13396
|
+
const canEdit = useMemo12(() => userRole !== "viewer", [userRole]);
|
|
13397
|
+
useEffect23(() => {
|
|
13187
13398
|
if (initialGroups && !isLoaded) {
|
|
13188
|
-
|
|
13399
|
+
const migrate = (list) => list.map((g) => ({
|
|
13400
|
+
id: g.id || uuidv411(),
|
|
13401
|
+
content: Array.isArray(g.content) ? g.content : [],
|
|
13402
|
+
// descarta dados legados
|
|
13403
|
+
children: migrate(g.children || [])
|
|
13404
|
+
}));
|
|
13405
|
+
setGroups(migrate(initialGroups));
|
|
13189
13406
|
setIsLoaded(true);
|
|
13190
13407
|
}
|
|
13191
13408
|
}, [initialGroups, isLoaded]);
|
|
13192
|
-
const nodeNamesMap =
|
|
13409
|
+
const nodeNamesMap = useMemo12(() => {
|
|
13193
13410
|
const map = /* @__PURE__ */ new Map();
|
|
13194
|
-
|
|
13195
|
-
|
|
13196
|
-
|
|
13197
|
-
map.set(String(node.id), node.name);
|
|
13198
|
-
}
|
|
13199
|
-
});
|
|
13200
|
-
}
|
|
13411
|
+
availableNodes.forEach((n) => {
|
|
13412
|
+
if (n == null ? void 0 : n.id) map.set(String(n.id), n.name);
|
|
13413
|
+
});
|
|
13201
13414
|
return map;
|
|
13202
13415
|
}, [availableNodes]);
|
|
13203
|
-
const
|
|
13204
|
-
|
|
13205
|
-
|
|
13206
|
-
|
|
13207
|
-
|
|
13208
|
-
|
|
13209
|
-
|
|
13210
|
-
|
|
13211
|
-
|
|
13212
|
-
|
|
13213
|
-
|
|
13214
|
-
|
|
13215
|
-
|
|
13216
|
-
|
|
13217
|
-
|
|
13416
|
+
const allSearchableItems = useMemo12(() => {
|
|
13417
|
+
const items = [];
|
|
13418
|
+
availableAncestries.forEach((anc) => {
|
|
13419
|
+
items.push({
|
|
13420
|
+
...anc,
|
|
13421
|
+
id: String(anc.ancestry_id),
|
|
13422
|
+
type: "ancestry",
|
|
13423
|
+
searchLabel: anc.name || "",
|
|
13424
|
+
searchDesc: anc.description || ""
|
|
13425
|
+
});
|
|
13426
|
+
});
|
|
13427
|
+
availableNodes.forEach((node) => {
|
|
13428
|
+
var _a;
|
|
13429
|
+
let type = "node";
|
|
13430
|
+
if (node.is_quest) type = "quest";
|
|
13431
|
+
else if ((_a = node.version_node) == null ? void 0 : _a.is_version) type = "version";
|
|
13432
|
+
items.push({
|
|
13433
|
+
...node,
|
|
13434
|
+
id: String(node.id),
|
|
13435
|
+
type,
|
|
13436
|
+
searchLabel: node.name || node.raw_title || "",
|
|
13437
|
+
searchDesc: node.description || ""
|
|
13438
|
+
});
|
|
13439
|
+
});
|
|
13440
|
+
return items;
|
|
13441
|
+
}, [availableAncestries, availableNodes]);
|
|
13442
|
+
const filtered = useMemo12(() => {
|
|
13443
|
+
const term = searchTerm.toLowerCase().trim();
|
|
13444
|
+
return allSearchableItems.filter((item) => {
|
|
13445
|
+
if (!term) return true;
|
|
13446
|
+
const labelMatch = (item.searchLabel || "").toLowerCase().includes(term);
|
|
13447
|
+
const descMatch = (item.searchDesc || "").toLowerCase().includes(term);
|
|
13448
|
+
let parentMatch = false;
|
|
13449
|
+
if (item.type === "ancestry") {
|
|
13450
|
+
const parentName = nodeNamesMap.get(String(item.ancestral_node)) || "";
|
|
13451
|
+
parentMatch = parentName.toLowerCase().includes(term);
|
|
13452
|
+
}
|
|
13453
|
+
return labelMatch || descMatch || parentMatch;
|
|
13454
|
+
});
|
|
13455
|
+
}, [allSearchableItems, searchTerm, nodeNamesMap]);
|
|
13456
|
+
const sanitizeGroups = (list) => list.map((g) => ({
|
|
13457
|
+
id: g.id,
|
|
13458
|
+
content: g.content || [],
|
|
13459
|
+
children: sanitizeGroups(g.children || [])
|
|
13460
|
+
}));
|
|
13461
|
+
useEffect23(() => {
|
|
13218
13462
|
if (!isLoaded || !onSave) return;
|
|
13219
|
-
const
|
|
13463
|
+
const id = setTimeout(async () => {
|
|
13220
13464
|
setSaveStatus("saving");
|
|
13221
|
-
const cleanData = sanitizeGroups(groups);
|
|
13222
13465
|
try {
|
|
13223
|
-
await onSave(
|
|
13466
|
+
await onSave(sanitizeGroups(groups));
|
|
13224
13467
|
setSaveStatus("saved");
|
|
13225
|
-
setTimeout(() =>
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
} catch (error) {
|
|
13229
|
-
console.error("Erro ao salvar board:", error);
|
|
13468
|
+
setTimeout(() => setSaveStatus("idle"), 3e3);
|
|
13469
|
+
} catch (err) {
|
|
13470
|
+
console.error("Erro ao salvar board:", err);
|
|
13230
13471
|
setSaveStatus("error");
|
|
13231
13472
|
}
|
|
13232
13473
|
}, 3e3);
|
|
13233
|
-
return () => clearTimeout(
|
|
13474
|
+
return () => clearTimeout(id);
|
|
13234
13475
|
}, [groups, isLoaded, onSave]);
|
|
13235
|
-
|
|
13476
|
+
useEffect23(() => {
|
|
13236
13477
|
if (!isOpen) return;
|
|
13237
|
-
const
|
|
13478
|
+
const handler = (e) => {
|
|
13238
13479
|
if (e.key === "Escape") {
|
|
13239
|
-
|
|
13240
|
-
setPickingGroupId(null);
|
|
13241
|
-
} else {
|
|
13242
|
-
onClose();
|
|
13243
|
-
}
|
|
13480
|
+
onClose();
|
|
13244
13481
|
e.preventDefault();
|
|
13245
13482
|
e.stopPropagation();
|
|
13246
13483
|
}
|
|
13247
13484
|
};
|
|
13248
|
-
window.addEventListener("keydown",
|
|
13249
|
-
return () => window.removeEventListener("keydown",
|
|
13250
|
-
}, [isOpen, onClose
|
|
13251
|
-
const filtered = useMemo11(() => {
|
|
13252
|
-
const term = searchTerm.toLowerCase().trim();
|
|
13253
|
-
return availableAncestries.filter((a) => {
|
|
13254
|
-
if (!term) return true;
|
|
13255
|
-
const nameMatch = a.name && a.name.toLowerCase().includes(term);
|
|
13256
|
-
const descMatch = a.description && a.description.toLowerCase().includes(term);
|
|
13257
|
-
const parentName = nodeNamesMap.get(String(a.ancestral_node)) || "";
|
|
13258
|
-
const parentMatch = parentName.toLowerCase().includes(term);
|
|
13259
|
-
return nameMatch || descMatch || parentMatch;
|
|
13260
|
-
});
|
|
13261
|
-
}, [availableAncestries, searchTerm, nodeNamesMap]);
|
|
13485
|
+
window.addEventListener("keydown", handler);
|
|
13486
|
+
return () => window.removeEventListener("keydown", handler);
|
|
13487
|
+
}, [isOpen, onClose]);
|
|
13262
13488
|
const handleAddRootGroup = () => {
|
|
13263
|
-
|
|
13264
|
-
id: v4_default(),
|
|
13265
|
-
text: "",
|
|
13266
|
-
ancestries: [],
|
|
13267
|
-
children: []
|
|
13268
|
-
};
|
|
13269
|
-
setGroups((prev) => [newGroup, ...prev]);
|
|
13489
|
+
setGroups((prev) => [{ id: uuidv411(), content: [], children: [] }, ...prev]);
|
|
13270
13490
|
};
|
|
13271
13491
|
const handleAddSubgroup = (parentId) => {
|
|
13272
|
-
const newGroup = {
|
|
13273
|
-
|
|
13274
|
-
|
|
13275
|
-
|
|
13276
|
-
|
|
13277
|
-
};
|
|
13278
|
-
const addRecursive = (list) => {
|
|
13279
|
-
return list.map((g) => {
|
|
13280
|
-
if (g.id === parentId) {
|
|
13281
|
-
return { ...g, children: [newGroup, ...g.children] };
|
|
13282
|
-
}
|
|
13283
|
-
return { ...g, children: addRecursive(g.children) };
|
|
13284
|
-
});
|
|
13285
|
-
};
|
|
13286
|
-
setGroups((prev) => addRecursive(prev));
|
|
13492
|
+
const newGroup = { id: uuidv411(), content: [], children: [] };
|
|
13493
|
+
const add = (list) => list.map(
|
|
13494
|
+
(g) => g.id === parentId ? { ...g, children: [newGroup, ...g.children] } : { ...g, children: add(g.children) }
|
|
13495
|
+
);
|
|
13496
|
+
setGroups((prev) => add(prev));
|
|
13287
13497
|
};
|
|
13288
13498
|
const handleUpdateGroup = (id, newData) => {
|
|
13289
|
-
const
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
});
|
|
13294
|
-
};
|
|
13295
|
-
setGroups((prev) => updateRecursive(prev));
|
|
13499
|
+
const update = (list) => list.map(
|
|
13500
|
+
(g) => g.id === id ? newData : { ...g, children: update(g.children) }
|
|
13501
|
+
);
|
|
13502
|
+
setGroups((prev) => update(prev));
|
|
13296
13503
|
};
|
|
13297
13504
|
const handleDeleteGroup = (id) => {
|
|
13298
|
-
const
|
|
13299
|
-
|
|
13300
|
-
...g,
|
|
13301
|
-
children: deleteRecursive(g.children)
|
|
13302
|
-
}));
|
|
13303
|
-
};
|
|
13304
|
-
setGroups((prev) => deleteRecursive(prev));
|
|
13505
|
+
const del = (list) => list.filter((g) => g.id !== id).map((g) => ({ ...g, children: del(g.children) }));
|
|
13506
|
+
setGroups((prev) => del(prev));
|
|
13305
13507
|
};
|
|
13306
13508
|
const findGroupAndParent = (list, targetId, parent = null) => {
|
|
13307
13509
|
for (let i = 0; i < list.length; i++) {
|
|
13308
|
-
if (list[i].id === targetId)
|
|
13510
|
+
if (list[i].id === targetId)
|
|
13309
13511
|
return { group: list[i], parent, index: i, siblings: list };
|
|
13310
|
-
}
|
|
13311
13512
|
if (list[i].children.length > 0) {
|
|
13312
13513
|
const found = findGroupAndParent(list[i].children, targetId, list[i]);
|
|
13313
13514
|
if (found) return found;
|
|
@@ -13317,216 +13518,119 @@ function AncestryBoard({
|
|
|
13317
13518
|
};
|
|
13318
13519
|
const handleIndent = (id) => {
|
|
13319
13520
|
setGroups((prev) => {
|
|
13320
|
-
const
|
|
13321
|
-
const found = findGroupAndParent(
|
|
13521
|
+
const next = JSON.parse(JSON.stringify(prev));
|
|
13522
|
+
const found = findGroupAndParent(next, id);
|
|
13322
13523
|
if (!found || found.index === 0) return prev;
|
|
13323
13524
|
const { group, siblings, index } = found;
|
|
13324
|
-
const prevSibling = siblings[index - 1];
|
|
13325
13525
|
siblings.splice(index, 1);
|
|
13326
|
-
|
|
13327
|
-
return
|
|
13526
|
+
siblings[index - 1].children.push(group);
|
|
13527
|
+
return next;
|
|
13328
13528
|
});
|
|
13329
13529
|
};
|
|
13330
13530
|
const handleOutdent = (id) => {
|
|
13331
13531
|
setGroups((prev) => {
|
|
13332
|
-
const
|
|
13333
|
-
const found = findGroupAndParent(
|
|
13532
|
+
const next = JSON.parse(JSON.stringify(prev));
|
|
13533
|
+
const found = findGroupAndParent(next, id);
|
|
13334
13534
|
if (!found || !found.parent) return prev;
|
|
13335
13535
|
const { group, siblings, index, parent } = found;
|
|
13336
13536
|
siblings.splice(index, 1);
|
|
13337
|
-
const parentFound = findGroupAndParent(
|
|
13537
|
+
const parentFound = findGroupAndParent(next, parent.id);
|
|
13338
13538
|
if (parentFound) {
|
|
13339
13539
|
parentFound.siblings.splice(parentFound.index + 1, 0, group);
|
|
13340
13540
|
} else {
|
|
13341
|
-
|
|
13541
|
+
next.push(group);
|
|
13342
13542
|
}
|
|
13343
|
-
return
|
|
13543
|
+
return next;
|
|
13344
13544
|
});
|
|
13345
13545
|
};
|
|
13346
|
-
const
|
|
13347
|
-
|
|
13348
|
-
};
|
|
13349
|
-
const handleSelectAncestry = (ancestry) => {
|
|
13350
|
-
if (pickingGroupId) {
|
|
13351
|
-
setGroups((prev) => {
|
|
13352
|
-
const addRecursive = (list) => {
|
|
13353
|
-
return list.map((g) => {
|
|
13354
|
-
if (g.id === pickingGroupId) {
|
|
13355
|
-
const exists = g.ancestries.some(
|
|
13356
|
-
(a) => a.ancestry_id === ancestry.ancestry_id
|
|
13357
|
-
);
|
|
13358
|
-
if (exists) return g;
|
|
13359
|
-
return { ...g, ancestries: [...g.ancestries, ancestry] };
|
|
13360
|
-
}
|
|
13361
|
-
return { ...g, children: addRecursive(g.children) };
|
|
13362
|
-
});
|
|
13363
|
-
};
|
|
13364
|
-
return addRecursive(prev);
|
|
13365
|
-
});
|
|
13366
|
-
setPickingGroupId(null);
|
|
13367
|
-
} else {
|
|
13368
|
-
const fullAncestry = availableAncestries.find(
|
|
13369
|
-
(a) => a.ancestry_id === ancestry.ancestry_id
|
|
13370
|
-
) || ancestry;
|
|
13371
|
-
onSelect(fullAncestry);
|
|
13372
|
-
}
|
|
13373
|
-
};
|
|
13374
|
-
const handlePlayFromGroup = (ancestryId) => {
|
|
13375
|
-
const fullAncestry = availableAncestries.find(
|
|
13376
|
-
(a) => a.ancestry_id === ancestryId
|
|
13377
|
-
);
|
|
13378
|
-
if (fullAncestry && onSelect) {
|
|
13379
|
-
onSelect(fullAncestry);
|
|
13380
|
-
}
|
|
13381
|
-
};
|
|
13382
|
-
const handleRemoveAncestryFromGroup = (groupId, ancestryId) => {
|
|
13383
|
-
setGroups((prev) => {
|
|
13384
|
-
const removeRecursive = (list) => {
|
|
13385
|
-
return list.map((g) => {
|
|
13386
|
-
if (g.id === groupId) {
|
|
13387
|
-
return {
|
|
13388
|
-
...g,
|
|
13389
|
-
ancestries: g.ancestries.filter(
|
|
13390
|
-
(a) => a.ancestry_id !== ancestryId
|
|
13391
|
-
)
|
|
13392
|
-
};
|
|
13393
|
-
}
|
|
13394
|
-
return { ...g, children: removeRecursive(g.children) };
|
|
13395
|
-
});
|
|
13396
|
-
};
|
|
13397
|
-
return removeRecursive(prev);
|
|
13398
|
-
});
|
|
13546
|
+
const handleMentionClick = (item) => {
|
|
13547
|
+
if (onSelect) onSelect(item);
|
|
13399
13548
|
};
|
|
13400
13549
|
if (!isOpen) return null;
|
|
13401
|
-
return /* @__PURE__ */
|
|
13550
|
+
return /* @__PURE__ */ React28.createElement(
|
|
13402
13551
|
"div",
|
|
13403
13552
|
{
|
|
13404
13553
|
className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
|
|
13405
13554
|
onClick: onClose
|
|
13406
13555
|
},
|
|
13407
|
-
/* @__PURE__ */
|
|
13556
|
+
/* @__PURE__ */ React28.createElement(
|
|
13408
13557
|
"div",
|
|
13409
13558
|
{
|
|
13410
13559
|
className: "bg-slate-950 border border-white/10 rounded-xl w-[98vw] h-[97vh] flex flex-col shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-200",
|
|
13411
13560
|
onClick: (e) => e.stopPropagation()
|
|
13412
13561
|
},
|
|
13413
|
-
/* @__PURE__ */
|
|
13414
|
-
FiLoader5,
|
|
13415
|
-
{
|
|
13416
|
-
className: "animate-spin text-indigo-400",
|
|
13417
|
-
size: 12
|
|
13418
|
-
}
|
|
13419
|
-
), /* @__PURE__ */ React26.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ React26.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ React26.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ React26.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ React26.createElement(
|
|
13562
|
+
/* @__PURE__ */ React28.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React28.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ React28.createElement(FiLayers7, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React28.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-slate-900/50 border border-white/5" }, saveStatus === "saving" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(FiLoader5, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ React28.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ React28.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ React28.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-3" }, canEdit && /* @__PURE__ */ React28.createElement(
|
|
13420
13563
|
"button",
|
|
13421
13564
|
{
|
|
13422
13565
|
onClick: handleAddRootGroup,
|
|
13423
|
-
className: "
|
|
13566
|
+
className: "flex items-center gap-2 px-3 py-1.5 bg-white/5 hover:bg-white/10 border border-white/10 hover:border-white/20 backdrop-blur-sm text-slate-200 hover:text-white rounded-md transition-all duration-200 text-xs font-medium shadow-sm"
|
|
13424
13567
|
},
|
|
13425
|
-
/* @__PURE__ */
|
|
13426
|
-
/* @__PURE__ */
|
|
13427
|
-
), /* @__PURE__ */
|
|
13568
|
+
/* @__PURE__ */ React28.createElement(FiPlus10, { size: 14, className: "text-indigo-400" }),
|
|
13569
|
+
/* @__PURE__ */ React28.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
|
|
13570
|
+
), /* @__PURE__ */ React28.createElement(
|
|
13428
13571
|
"button",
|
|
13429
13572
|
{
|
|
13430
13573
|
onClick: onClose,
|
|
13431
13574
|
className: "w-8 h-8 rounded-lg flex items-center justify-center text-slate-400 hover:text-white hover:bg-white/10 transition-colors"
|
|
13432
13575
|
},
|
|
13433
|
-
|
|
13576
|
+
/* @__PURE__ */ React28.createElement(FiX8, { size: 16 })
|
|
13434
13577
|
))),
|
|
13435
|
-
/* @__PURE__ */
|
|
13436
|
-
"
|
|
13578
|
+
/* @__PURE__ */ React28.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col border-r border-white/10 w-[20%] min-w-[280px] max-w-[460px] bg-slate-900 flex-none" }, /* @__PURE__ */ React28.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ React28.createElement("div", { className: "relative group" }, /* @__PURE__ */ React28.createElement(FiSearch8, { className: "absolute left-3 top-1/2 -translate-y-1/2 text-slate-500 group-focus-within:text-indigo-400 transition-colors" }), /* @__PURE__ */ React28.createElement(
|
|
13579
|
+
"input",
|
|
13437
13580
|
{
|
|
13438
|
-
|
|
13439
|
-
|
|
13440
|
-
|
|
13441
|
-
|
|
13442
|
-
|
|
13443
|
-
|
|
13444
|
-
|
|
13445
|
-
|
|
13446
|
-
|
|
13447
|
-
|
|
13448
|
-
|
|
13449
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13450
|
-
"input",
|
|
13581
|
+
type: "text",
|
|
13582
|
+
placeholder: "Navegar nas ancestralidades e nodes\u2026",
|
|
13583
|
+
className: "w-full rounded-md pl-9 pr-4 py-2 text-sm bg-slate-950 border border-white/10 text-slate-200 placeholder-slate-600 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-all",
|
|
13584
|
+
value: searchTerm,
|
|
13585
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
|
13586
|
+
autoFocus: true
|
|
13587
|
+
}
|
|
13588
|
+
))), /* @__PURE__ */ React28.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
|
|
13589
|
+
const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
|
|
13590
|
+
return /* @__PURE__ */ React28.createElement(
|
|
13591
|
+
"div",
|
|
13451
13592
|
{
|
|
13452
|
-
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
onChange: (e) => setSearchTerm(e.target.value),
|
|
13460
|
-
autoFocus: !pickingGroupId
|
|
13461
|
-
}
|
|
13462
|
-
))),
|
|
13463
|
-
/* @__PURE__ */ React26.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
|
|
13464
|
-
const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
|
|
13465
|
-
const isPicking = !!pickingGroupId;
|
|
13466
|
-
return /* @__PURE__ */ React26.createElement(
|
|
13467
|
-
"div",
|
|
13593
|
+
key: anc.id,
|
|
13594
|
+
className: "group relative flex items-start gap-3 p-3 text-left rounded-lg border border-white/5 bg-slate-800/40 hover:bg-indigo-600/10 hover:border-indigo-500/30 cursor-default transition-all duration-200"
|
|
13595
|
+
},
|
|
13596
|
+
/* @__PURE__ */ React28.createElement("div", { className: "mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border bg-slate-800 border-white/5 group-hover:bg-indigo-500 group-hover:text-white transition-all shadow-lg" }, anc.type === "quest" ? /* @__PURE__ */ React28.createElement(FiCheckSquare4, { size: 14, className: "text-emerald-400 group-hover:text-white" }) : anc.type === "version" ? /* @__PURE__ */ React28.createElement(FiGitBranch4, { size: 14, className: "text-amber-400 group-hover:text-white" }) : anc.type === "node" ? /* @__PURE__ */ React28.createElement(FiBox2, { size: 14, className: "text-slate-400 group-hover:text-white" }) : /* @__PURE__ */ React28.createElement(FiLayers7, { size: 14, className: "text-indigo-400 group-hover:text-white" })),
|
|
13597
|
+
/* @__PURE__ */ React28.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ React28.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React28.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.searchLabel || "Sem Nome"), /* @__PURE__ */ React28.createElement("span", { className: "text-[9px] px-1.5 py-0.5 rounded-full bg-white/5 text-slate-500 border border-white/5 uppercase tracking-tighter" }, anc.type)), anc.type === "ancestry" && /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-1.5 mt-0.5 text-[11px] text-slate-500 group-hover:text-indigo-200/70 transition-colors" }, /* @__PURE__ */ React28.createElement(FiCornerUpRight4, { size: 10 }), /* @__PURE__ */ React28.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.searchDesc && /* @__PURE__ */ React28.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.searchDesc)),
|
|
13598
|
+
/* @__PURE__ */ React28.createElement(
|
|
13599
|
+
"button",
|
|
13468
13600
|
{
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
if (
|
|
13601
|
+
onClick: (e) => {
|
|
13602
|
+
e.stopPropagation();
|
|
13603
|
+
if (onSelect) onSelect(anc);
|
|
13472
13604
|
},
|
|
13473
|
-
className:
|
|
13474
|
-
|
|
13475
|
-
${isPicking ? "border-indigo-500/30 bg-indigo-500/5 hover:bg-indigo-500/20 hover:border-indigo-400 cursor-pointer" : "border-white/5 bg-slate-800/40 hover:bg-indigo-600/10 hover:border-indigo-500/30 cursor-default"}
|
|
13476
|
-
`
|
|
13605
|
+
className: "absolute right-2 bottom-2 opacity-0 group-hover:opacity-100 transition-all duration-300 transform translate-y-2 group-hover:translate-y-0 z-10",
|
|
13606
|
+
title: "Focar no cen\xE1rio"
|
|
13477
13607
|
},
|
|
13478
|
-
/* @__PURE__ */
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
|
|
13483
|
-
${isPicking ? "bg-indigo-500 text-white border-indigo-400" : "bg-slate-800 text-indigo-400 border-white/5 group-hover:bg-indigo-500 group-hover:text-white"}
|
|
13484
|
-
`
|
|
13485
|
-
},
|
|
13486
|
-
isPicking ? /* @__PURE__ */ React26.createElement(FiPlus10, { size: 16 }) : /* @__PURE__ */ React26.createElement(FiLayers6, { size: 14 })
|
|
13487
|
-
),
|
|
13488
|
-
/* @__PURE__ */ React26.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ React26.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React26.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.name || "Sem Nome"), anc.is_private && /* @__PURE__ */ React26.createElement("span", { className: "text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-300 border border-amber-500/20" }, "Priv")), /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-1.5 mt-0.5 text-[11px] text-slate-500 group-hover:text-indigo-200/70 transition-colors" }, /* @__PURE__ */ React26.createElement(FiCornerUpRight4, { size: 10 }), /* @__PURE__ */ React26.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ React26.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
|
|
13489
|
-
!isPicking && /* @__PURE__ */ React26.createElement(
|
|
13490
|
-
"button",
|
|
13491
|
-
{
|
|
13492
|
-
onClick: (e) => {
|
|
13493
|
-
e.stopPropagation();
|
|
13494
|
-
handleSelectAncestry(anc);
|
|
13495
|
-
},
|
|
13496
|
-
className: "absolute right-2 bottom-2 opacity-0 group-hover:opacity-100 transition-all duration-300 transform translate-y-2 group-hover:translate-y-0 z-10",
|
|
13497
|
-
title: "Renderizar Ancestralidade"
|
|
13498
|
-
},
|
|
13499
|
-
/* @__PURE__ */ React26.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ React26.createElement(FiPlay, { size: 14, className: "ml-0.5" }))
|
|
13500
|
-
)
|
|
13501
|
-
);
|
|
13502
|
-
}))
|
|
13503
|
-
), /* @__PURE__ */ React26.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ React26.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ React26.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-3 border-2 border-dashed border-white/5 rounded-xl m-4 bg-slate-900/20" }, /* @__PURE__ */ React26.createElement(FiLayers6, { size: 24, className: "opacity-20" }), /* @__PURE__ */ React26.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ React26.createElement(React26.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ React26.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ React26.createElement(React26.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ React26.createElement(
|
|
13608
|
+
/* @__PURE__ */ React28.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ React28.createElement(FiPlay, { size: 14, className: "ml-0.5" }))
|
|
13609
|
+
)
|
|
13610
|
+
);
|
|
13611
|
+
}))), /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ React28.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-3 border-2 border-dashed border-white/5 rounded-xl m-4 bg-slate-900/20" }, /* @__PURE__ */ React28.createElement(FiLayers7, { size: 24, className: "opacity-20" }), /* @__PURE__ */ React28.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ React28.createElement(React28.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ React28.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ React28.createElement(React28.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ React28.createElement(
|
|
13504
13612
|
GroupItem,
|
|
13505
13613
|
{
|
|
13506
13614
|
key: group.id,
|
|
13507
13615
|
index,
|
|
13508
13616
|
group,
|
|
13509
|
-
siblings: groups,
|
|
13510
13617
|
onUpdate: handleUpdateGroup,
|
|
13511
13618
|
onDelete: handleDeleteGroup,
|
|
13512
13619
|
onAddSubgroup: handleAddSubgroup,
|
|
13513
13620
|
onIndent: handleIndent,
|
|
13514
13621
|
onOutdent: handleOutdent,
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
pickingGroupId,
|
|
13518
|
-
onPlayAncestry: handlePlayFromGroup,
|
|
13519
|
-
availableIds,
|
|
13622
|
+
searchItems: allSearchableItems,
|
|
13623
|
+
onMentionClick: handleMentionClick,
|
|
13520
13624
|
canEdit
|
|
13521
13625
|
}
|
|
13522
13626
|
))))),
|
|
13523
|
-
/* @__PURE__ */
|
|
13627
|
+
/* @__PURE__ */ React28.createElement("div", { className: "px-5 py-2 border-t border-white/10 bg-slate-950/50 text-xs text-slate-500 flex justify-between flex-shrink-0" }, /* @__PURE__ */ React28.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ React28.createElement("span", null, groups.length, " grupos raiz"))
|
|
13524
13628
|
)
|
|
13525
13629
|
);
|
|
13526
13630
|
}
|
|
13527
13631
|
|
|
13528
13632
|
// src/components/MilestoneManager.jsx
|
|
13529
|
-
import
|
|
13633
|
+
import React29, { useState as useState28 } from "react";
|
|
13530
13634
|
import { FiTarget as FiTarget4, FiPlus as FiPlus11, FiTrash2 as FiTrash24, FiX as FiX9, FiCheck as FiCheck12, FiPauseCircle, FiPlayCircle } from "react-icons/fi";
|
|
13531
13635
|
function MilestoneManager({
|
|
13532
13636
|
isOpen,
|
|
@@ -13535,7 +13639,7 @@ function MilestoneManager({
|
|
|
13535
13639
|
onUpdateMilestones = () => {
|
|
13536
13640
|
}
|
|
13537
13641
|
}) {
|
|
13538
|
-
const [newMilestoneName, setNewMilestoneName] =
|
|
13642
|
+
const [newMilestoneName, setNewMilestoneName] = useState28("");
|
|
13539
13643
|
const handleAddMilestone = () => {
|
|
13540
13644
|
if (!newMilestoneName.trim()) return;
|
|
13541
13645
|
const newMilestone = {
|
|
@@ -13560,27 +13664,27 @@ function MilestoneManager({
|
|
|
13560
13664
|
};
|
|
13561
13665
|
if (!isOpen) return null;
|
|
13562
13666
|
const swallow = (e) => e.stopPropagation();
|
|
13563
|
-
return /* @__PURE__ */
|
|
13667
|
+
return /* @__PURE__ */ React29.createElement(
|
|
13564
13668
|
"div",
|
|
13565
13669
|
{
|
|
13566
13670
|
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",
|
|
13567
13671
|
onClick: onClose
|
|
13568
13672
|
},
|
|
13569
|
-
/* @__PURE__ */
|
|
13673
|
+
/* @__PURE__ */ React29.createElement(
|
|
13570
13674
|
"div",
|
|
13571
13675
|
{
|
|
13572
13676
|
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",
|
|
13573
13677
|
onClick: swallow
|
|
13574
13678
|
},
|
|
13575
|
-
/* @__PURE__ */
|
|
13679
|
+
/* @__PURE__ */ React29.createElement("div", { className: "px-6 py-4 border-b border-white/10 flex items-center justify-between" }, /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React29.createElement("div", { className: "p-2 rounded-lg bg-indigo-500/20 text-indigo-400" }, /* @__PURE__ */ React29.createElement(FiTarget4, { size: 20 })), /* @__PURE__ */ React29.createElement("div", null, /* @__PURE__ */ React29.createElement("h2", { className: "text-lg font-semibold text-slate-100" }, "Milestones"), /* @__PURE__ */ React29.createElement("p", { className: "text-xs text-slate-400" }, "Gerencie os marcos do seu cen\xE1rio"))), /* @__PURE__ */ React29.createElement(
|
|
13576
13680
|
"button",
|
|
13577
13681
|
{
|
|
13578
13682
|
onClick: onClose,
|
|
13579
13683
|
className: "p-2 rounded-full hover:bg-white/10 text-slate-400 hover:text-white transition-colors"
|
|
13580
13684
|
},
|
|
13581
|
-
/* @__PURE__ */
|
|
13685
|
+
/* @__PURE__ */ React29.createElement(FiX9, { size: 20 })
|
|
13582
13686
|
)),
|
|
13583
|
-
/* @__PURE__ */
|
|
13687
|
+
/* @__PURE__ */ React29.createElement("div", { className: "px-6 py-5 bg-white/5 border-b border-white/5" }, /* @__PURE__ */ React29.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React29.createElement(
|
|
13584
13688
|
"input",
|
|
13585
13689
|
{
|
|
13586
13690
|
type: "text",
|
|
@@ -13590,47 +13694,47 @@ function MilestoneManager({
|
|
|
13590
13694
|
placeholder: "Adicionar novo milestone...",
|
|
13591
13695
|
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"
|
|
13592
13696
|
}
|
|
13593
|
-
), /* @__PURE__ */
|
|
13697
|
+
), /* @__PURE__ */ React29.createElement(
|
|
13594
13698
|
"button",
|
|
13595
13699
|
{
|
|
13596
13700
|
onClick: handleAddMilestone,
|
|
13597
13701
|
disabled: !newMilestoneName.trim(),
|
|
13598
13702
|
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"
|
|
13599
13703
|
},
|
|
13600
|
-
/* @__PURE__ */
|
|
13704
|
+
/* @__PURE__ */ React29.createElement(FiPlus11, { size: 18 }),
|
|
13601
13705
|
"Adicionar"
|
|
13602
13706
|
))),
|
|
13603
|
-
/* @__PURE__ */
|
|
13707
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex-1 overflow-y-auto px-6 py-4 custom-scrollbar" }, milestones.length > 0 ? /* @__PURE__ */ React29.createElement("div", { className: "space-y-3" }, milestones.map((ms) => /* @__PURE__ */ React29.createElement(
|
|
13604
13708
|
"div",
|
|
13605
13709
|
{
|
|
13606
13710
|
key: ms.id,
|
|
13607
13711
|
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]"}`
|
|
13608
13712
|
},
|
|
13609
|
-
/* @__PURE__ */
|
|
13713
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ React29.createElement(
|
|
13610
13714
|
"div",
|
|
13611
13715
|
{
|
|
13612
13716
|
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"}`
|
|
13613
13717
|
}
|
|
13614
|
-
), /* @__PURE__ */
|
|
13615
|
-
/* @__PURE__ */
|
|
13718
|
+
), /* @__PURE__ */ React29.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ React29.createElement("span", { className: `text-sm font-medium truncate ${ms.status === "active" ? "text-slate-100" : "text-slate-400 line-through"}` }, ms.name), /* @__PURE__ */ React29.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-wider" }, ms.status === "active" ? "Ativo" : "Inativo"))),
|
|
13719
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React29.createElement(
|
|
13616
13720
|
"button",
|
|
13617
13721
|
{
|
|
13618
13722
|
onClick: () => handleToggleMilestoneStatus(ms.id),
|
|
13619
13723
|
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"}`,
|
|
13620
13724
|
title: ms.status === "active" ? "Inativar" : "Ativar"
|
|
13621
13725
|
},
|
|
13622
|
-
ms.status === "active" ? /* @__PURE__ */
|
|
13623
|
-
), /* @__PURE__ */
|
|
13726
|
+
ms.status === "active" ? /* @__PURE__ */ React29.createElement(FiPauseCircle, { size: 18 }) : /* @__PURE__ */ React29.createElement(FiPlayCircle, { size: 18 })
|
|
13727
|
+
), /* @__PURE__ */ React29.createElement(
|
|
13624
13728
|
"button",
|
|
13625
13729
|
{
|
|
13626
13730
|
onClick: () => handleRemoveMilestone(ms.id),
|
|
13627
13731
|
className: "p-2 rounded-lg hover:bg-red-500/20 text-slate-500 hover:text-red-400 transition-all",
|
|
13628
13732
|
title: "Remover"
|
|
13629
13733
|
},
|
|
13630
|
-
/* @__PURE__ */
|
|
13734
|
+
/* @__PURE__ */ React29.createElement(FiTrash24, { size: 18 })
|
|
13631
13735
|
))
|
|
13632
|
-
))) : /* @__PURE__ */
|
|
13633
|
-
/* @__PURE__ */
|
|
13736
|
+
))) : /* @__PURE__ */ React29.createElement("div", { className: "flex flex-col items-center justify-center py-12 text-center" }, /* @__PURE__ */ React29.createElement("div", { className: "p-4 rounded-full bg-slate-800/30 text-slate-600 mb-4" }, /* @__PURE__ */ React29.createElement(FiTarget4, { size: 40 })), /* @__PURE__ */ React29.createElement("h3", { className: "text-slate-400 font-medium" }, "Nenhum milestone definido"), /* @__PURE__ */ React29.createElement("p", { className: "text-xs text-slate-600 max-w-[200px] mt-1 italic" }, "Defina marcos importantes para orientar o progresso do projeto."))),
|
|
13737
|
+
/* @__PURE__ */ React29.createElement("div", { className: "px-6 py-4 border-t border-white/5 bg-slate-900/50 flex items-center justify-between rounded-b-2xl" }, /* @__PURE__ */ React29.createElement("div", { className: "flex gap-4" }, /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React29.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Total:"), /* @__PURE__ */ React29.createElement("span", { className: "text-xs font-bold text-slate-300" }, milestones.length)), /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React29.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Ativos:"), /* @__PURE__ */ React29.createElement("span", { className: "text-xs font-bold text-indigo-400" }, milestones.filter((m) => m.status === "active").length))))
|
|
13634
13738
|
)
|
|
13635
13739
|
);
|
|
13636
13740
|
}
|
|
@@ -13722,7 +13826,7 @@ function XViewScene({
|
|
|
13722
13826
|
const searchParams = useSearchParams();
|
|
13723
13827
|
const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
|
|
13724
13828
|
const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
|
|
13725
|
-
const viewParams =
|
|
13829
|
+
const viewParams = useMemo13(() => {
|
|
13726
13830
|
if (encryptedConfig) {
|
|
13727
13831
|
const data = decryptData(encryptedConfig);
|
|
13728
13832
|
if (data) {
|
|
@@ -13731,7 +13835,7 @@ function XViewScene({
|
|
|
13731
13835
|
}
|
|
13732
13836
|
return null;
|
|
13733
13837
|
}, [encryptedConfig, session]);
|
|
13734
|
-
|
|
13838
|
+
useEffect24(() => {
|
|
13735
13839
|
async function verifyPermission() {
|
|
13736
13840
|
if (!viewParams || !session || !check_user_permission) return;
|
|
13737
13841
|
const { id, type, owner_id } = viewParams;
|
|
@@ -13768,65 +13872,65 @@ function XViewScene({
|
|
|
13768
13872
|
setIsLoading(false);
|
|
13769
13873
|
}
|
|
13770
13874
|
}, [viewParams, session, status, check_user_permission]);
|
|
13771
|
-
const sceneConfigId =
|
|
13772
|
-
const ownerId =
|
|
13773
|
-
const dbSaveUrl =
|
|
13875
|
+
const sceneConfigId = useMemo13(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
|
|
13876
|
+
const ownerId = useMemo13(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
|
|
13877
|
+
const dbSaveUrl = useMemo13(() => {
|
|
13774
13878
|
if (ownerId && sceneConfigId) {
|
|
13775
13879
|
return `x_view_dbs/${ownerId}/${sceneConfigId}`;
|
|
13776
13880
|
}
|
|
13777
13881
|
return null;
|
|
13778
13882
|
}, [ownerId, sceneConfigId]);
|
|
13779
|
-
const sceneSaveUrl =
|
|
13883
|
+
const sceneSaveUrl = useMemo13(() => {
|
|
13780
13884
|
if (ownerId && sceneConfigId) {
|
|
13781
13885
|
return `x_view_scenes/${ownerId}/${sceneConfigId}`;
|
|
13782
13886
|
}
|
|
13783
13887
|
return null;
|
|
13784
13888
|
}, [ownerId, sceneConfigId]);
|
|
13785
|
-
const ancestry_save_url =
|
|
13889
|
+
const ancestry_save_url = useMemo13(() => {
|
|
13786
13890
|
if (ownerId && sceneConfigId) {
|
|
13787
13891
|
return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
|
|
13788
13892
|
}
|
|
13789
13893
|
return null;
|
|
13790
13894
|
}, [ownerId, sceneConfigId]);
|
|
13791
|
-
const sceneDataRef =
|
|
13792
|
-
const parentDataRef =
|
|
13793
|
-
const ancestryDataRef =
|
|
13794
|
-
const [isLoading, setIsLoading] =
|
|
13795
|
-
const [permissionStatus, setPermissionStatus] =
|
|
13796
|
-
const [userPermissionRole, setUserPermissionRole] =
|
|
13797
|
-
const [viewMembers, setViewMembers] =
|
|
13798
|
-
const [isInitialized, setIsInitialized] =
|
|
13799
|
-
const [sceneVersion, setSceneVersion] =
|
|
13800
|
-
const [contextMenu, setContextMenu] =
|
|
13895
|
+
const sceneDataRef = useRef20(null);
|
|
13896
|
+
const parentDataRef = useRef20(null);
|
|
13897
|
+
const ancestryDataRef = useRef20(null);
|
|
13898
|
+
const [isLoading, setIsLoading] = useState29(true);
|
|
13899
|
+
const [permissionStatus, setPermissionStatus] = useState29("loading");
|
|
13900
|
+
const [userPermissionRole, setUserPermissionRole] = useState29(null);
|
|
13901
|
+
const [viewMembers, setViewMembers] = useState29([]);
|
|
13902
|
+
const [isInitialized, setIsInitialized] = useState29(false);
|
|
13903
|
+
const [sceneVersion, setSceneVersion] = useState29(0);
|
|
13904
|
+
const [contextMenu, setContextMenu] = useState29({
|
|
13801
13905
|
visible: false,
|
|
13802
13906
|
x: 0,
|
|
13803
13907
|
y: 0,
|
|
13804
13908
|
nodeData: null
|
|
13805
13909
|
});
|
|
13806
|
-
const [multiContextMenu, setMultiContextMenu] =
|
|
13910
|
+
const [multiContextMenu, setMultiContextMenu] = useState29({
|
|
13807
13911
|
visible: false,
|
|
13808
13912
|
x: 0,
|
|
13809
13913
|
y: 0,
|
|
13810
13914
|
nodeIds: null
|
|
13811
13915
|
});
|
|
13812
|
-
const [relationshipMenu, setRelationshipMenu] =
|
|
13916
|
+
const [relationshipMenu, setRelationshipMenu] = useState29({
|
|
13813
13917
|
visible: false,
|
|
13814
13918
|
x: 0,
|
|
13815
13919
|
y: 0,
|
|
13816
13920
|
linkObject: null
|
|
13817
13921
|
});
|
|
13818
|
-
const [creationMode, setCreationMode] =
|
|
13922
|
+
const [creationMode, setCreationMode] = useState29({
|
|
13819
13923
|
isActive: false,
|
|
13820
13924
|
sourceNodeData: null
|
|
13821
13925
|
});
|
|
13822
|
-
const [versionMode, setVersionMode] =
|
|
13926
|
+
const [versionMode, setVersionMode] = useState29({
|
|
13823
13927
|
isActive: false,
|
|
13824
13928
|
sourceNodeData: null
|
|
13825
13929
|
});
|
|
13826
|
-
const [questMode, setQuestMode] =
|
|
13827
|
-
const [hasFocusedInitial, setHasFocusedInitial] =
|
|
13828
|
-
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] =
|
|
13829
|
-
const [ancestryMode, setAncestryMode] =
|
|
13930
|
+
const [questMode, setQuestMode] = useState29({ isActive: false });
|
|
13931
|
+
const [hasFocusedInitial, setHasFocusedInitial] = useState29(false);
|
|
13932
|
+
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState29(false);
|
|
13933
|
+
const [ancestryMode, setAncestryMode] = useState29({
|
|
13830
13934
|
isActive: false,
|
|
13831
13935
|
tree: null,
|
|
13832
13936
|
selectedParentId: null,
|
|
@@ -13837,42 +13941,42 @@ function XViewScene({
|
|
|
13837
13941
|
ancestryDescriptionSections: [],
|
|
13838
13942
|
isAddingNodes: false
|
|
13839
13943
|
});
|
|
13840
|
-
const [readingMode, setReadingMode] =
|
|
13944
|
+
const [readingMode, setReadingMode] = useState29({
|
|
13841
13945
|
isActive: false,
|
|
13842
13946
|
ancestry: null,
|
|
13843
13947
|
branchStack: [],
|
|
13844
13948
|
autoAbstraction: false
|
|
13845
13949
|
});
|
|
13846
|
-
const [formPosition, setFormPosition] =
|
|
13950
|
+
const [formPosition, setFormPosition] = useState29({
|
|
13847
13951
|
left: 16,
|
|
13848
13952
|
top: 16,
|
|
13849
13953
|
opacity: 0
|
|
13850
13954
|
});
|
|
13851
|
-
const [detailsNode, setDetailsNode] =
|
|
13852
|
-
const [detailsLink, setDetailsLink] =
|
|
13853
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] =
|
|
13854
|
-
const [imageViewer, setImageViewer] =
|
|
13955
|
+
const [detailsNode, setDetailsNode] = useState29(null);
|
|
13956
|
+
const [detailsLink, setDetailsLink] = useState29(null);
|
|
13957
|
+
const [ancestryLinkDetails, setAncestryLinkDetails] = useState29(null);
|
|
13958
|
+
const [imageViewer, setImageViewer] = useState29({
|
|
13855
13959
|
visible: false,
|
|
13856
13960
|
images: [],
|
|
13857
13961
|
startIndex: 0
|
|
13858
13962
|
});
|
|
13859
|
-
const [editingAncestryRel, setEditingAncestryRel] =
|
|
13963
|
+
const [editingAncestryRel, setEditingAncestryRel] = useState29({
|
|
13860
13964
|
visible: false,
|
|
13861
13965
|
data: null,
|
|
13862
13966
|
path: null
|
|
13863
13967
|
});
|
|
13864
|
-
const [isImportModalOpen, setIsImportModalOpen] =
|
|
13865
|
-
const [importSuccessMessage, setImportSuccessMessage] =
|
|
13866
|
-
const [invalidTargetError, setInvalidTargetError] =
|
|
13867
|
-
const [highlightedNodeId, setHighlightedNodeId] =
|
|
13868
|
-
const [isAncestryBoardOpen, setIsAncestryBoardOpen] =
|
|
13869
|
-
const [ancestryBoardData, setAncestryBoardData] =
|
|
13870
|
-
const [isSidebarOpen, setIsSidebarOpen] =
|
|
13871
|
-
const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] =
|
|
13872
|
-
const mountRef =
|
|
13873
|
-
const tooltipRef =
|
|
13874
|
-
const formRef =
|
|
13875
|
-
const stateRef =
|
|
13968
|
+
const [isImportModalOpen, setIsImportModalOpen] = useState29(false);
|
|
13969
|
+
const [importSuccessMessage, setImportSuccessMessage] = useState29("");
|
|
13970
|
+
const [invalidTargetError, setInvalidTargetError] = useState29(null);
|
|
13971
|
+
const [highlightedNodeId, setHighlightedNodeId] = useState29(null);
|
|
13972
|
+
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState29(false);
|
|
13973
|
+
const [ancestryBoardData, setAncestryBoardData] = useState29([]);
|
|
13974
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState29(false);
|
|
13975
|
+
const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = useState29(false);
|
|
13976
|
+
const mountRef = useRef20(null);
|
|
13977
|
+
const tooltipRef = useRef20(null);
|
|
13978
|
+
const formRef = useRef20(null);
|
|
13979
|
+
const stateRef = useRef20({
|
|
13876
13980
|
readMode: {
|
|
13877
13981
|
currentMaxIndex: 0,
|
|
13878
13982
|
progressMap: {}
|
|
@@ -13936,10 +14040,10 @@ function XViewScene({
|
|
|
13936
14040
|
minWidth: 320,
|
|
13937
14041
|
maxWidth: maxReadPanelW
|
|
13938
14042
|
});
|
|
13939
|
-
|
|
14043
|
+
useEffect24(() => {
|
|
13940
14044
|
stateRef.current.ancestry = ancestryMode;
|
|
13941
14045
|
}, [ancestryMode]);
|
|
13942
|
-
|
|
14046
|
+
useEffect24(() => {
|
|
13943
14047
|
var _a2;
|
|
13944
14048
|
if (!isInitialized) return;
|
|
13945
14049
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -13962,10 +14066,10 @@ function XViewScene({
|
|
|
13962
14066
|
}
|
|
13963
14067
|
stateRef.current.nodeIdToParentFileMap = map;
|
|
13964
14068
|
}, [isInitialized, sceneVersion]);
|
|
13965
|
-
const handleNavigateBack =
|
|
14069
|
+
const handleNavigateBack = useCallback5(() => {
|
|
13966
14070
|
router.push("/dashboard/scenes");
|
|
13967
14071
|
}, [router]);
|
|
13968
|
-
const handleConfirmImport =
|
|
14072
|
+
const handleConfirmImport = useCallback5(
|
|
13969
14073
|
async (importPayload) => {
|
|
13970
14074
|
var _a2, _b2;
|
|
13971
14075
|
let files = [];
|
|
@@ -14093,7 +14197,7 @@ function XViewScene({
|
|
|
14093
14197
|
const handleOpenImageViewer = (images, startIndex) => {
|
|
14094
14198
|
setImageViewer({ visible: true, images, startIndex });
|
|
14095
14199
|
};
|
|
14096
|
-
const tweenToTarget =
|
|
14200
|
+
const tweenToTarget = useCallback5(
|
|
14097
14201
|
(target, zoomFactor = 1, forcedDirection = null) => {
|
|
14098
14202
|
const { camera, controls, tweenGroup } = stateRef.current;
|
|
14099
14203
|
if (!camera || !controls || !tweenGroup) return;
|
|
@@ -14119,7 +14223,7 @@ function XViewScene({
|
|
|
14119
14223
|
if (!t || typeof t.closest !== "function") return false;
|
|
14120
14224
|
return !!t.closest(".ui-overlay");
|
|
14121
14225
|
};
|
|
14122
|
-
const buildFullAncestryTree =
|
|
14226
|
+
const buildFullAncestryTree = useCallback5(
|
|
14123
14227
|
(idTree, nodes, ancestries = []) => {
|
|
14124
14228
|
if (!idTree) return null;
|
|
14125
14229
|
const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
|
|
@@ -14204,7 +14308,7 @@ function XViewScene({
|
|
|
14204
14308
|
},
|
|
14205
14309
|
[]
|
|
14206
14310
|
);
|
|
14207
|
-
const handleActivateTimeline =
|
|
14311
|
+
const handleActivateTimeline = useCallback5(() => {
|
|
14208
14312
|
const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
14209
14313
|
if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
|
|
14210
14314
|
while (timelineIntervalsGroup.children.length > 0) {
|
|
@@ -14364,7 +14468,7 @@ function XViewScene({
|
|
|
14364
14468
|
}
|
|
14365
14469
|
});
|
|
14366
14470
|
}, []);
|
|
14367
|
-
const handleVersionTimeline =
|
|
14471
|
+
const handleVersionTimeline = useCallback5((sourceMesh, versionMeshes) => {
|
|
14368
14472
|
const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
14369
14473
|
if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0)
|
|
14370
14474
|
return;
|
|
@@ -14501,7 +14605,7 @@ function XViewScene({
|
|
|
14501
14605
|
}
|
|
14502
14606
|
});
|
|
14503
14607
|
}, []);
|
|
14504
|
-
|
|
14608
|
+
useEffect24(() => {
|
|
14505
14609
|
async function fetchAllData(configPath, ownerId2) {
|
|
14506
14610
|
var _a2, _b2;
|
|
14507
14611
|
if (!get_scene_view_data) {
|
|
@@ -14606,12 +14710,12 @@ function XViewScene({
|
|
|
14606
14710
|
focusNodeId,
|
|
14607
14711
|
focusAncestryId
|
|
14608
14712
|
]);
|
|
14609
|
-
const isNodeInView =
|
|
14713
|
+
const isNodeInView = useCallback5((id) => {
|
|
14610
14714
|
const key = String(id);
|
|
14611
14715
|
const objs = stateRef.current.nodeObjects || {};
|
|
14612
14716
|
return !!objs[key];
|
|
14613
14717
|
}, []);
|
|
14614
|
-
const addOrUpdateNodeMesh =
|
|
14718
|
+
const addOrUpdateNodeMesh = useCallback5(
|
|
14615
14719
|
(nodeData, position, suppressVersionUpdate = false, forceShowQuestDate = false) => {
|
|
14616
14720
|
const {
|
|
14617
14721
|
graphGroup,
|
|
@@ -14652,7 +14756,7 @@ function XViewScene({
|
|
|
14652
14756
|
},
|
|
14653
14757
|
[]
|
|
14654
14758
|
);
|
|
14655
|
-
const handleActivateQuestLens =
|
|
14759
|
+
const handleActivateQuestLens = useCallback5(({ assigneeId, status: status2, milestoneId }) => {
|
|
14656
14760
|
var _a2;
|
|
14657
14761
|
const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
|
|
14658
14762
|
if (!nodeObjects || !tweenGroup || !graphGroup) return;
|
|
@@ -14866,7 +14970,7 @@ function XViewScene({
|
|
|
14866
14970
|
camTween.start();
|
|
14867
14971
|
}
|
|
14868
14972
|
}, [addOrUpdateNodeMesh]);
|
|
14869
|
-
|
|
14973
|
+
useEffect24(() => {
|
|
14870
14974
|
if (!isInitialized || !sceneDataRef.current) return;
|
|
14871
14975
|
const currentMount = mountRef.current;
|
|
14872
14976
|
if (!currentMount) return;
|
|
@@ -15622,7 +15726,7 @@ function XViewScene({
|
|
|
15622
15726
|
get_scene_view_data,
|
|
15623
15727
|
save_view_data
|
|
15624
15728
|
]);
|
|
15625
|
-
const handleGhostNodeImageChange =
|
|
15729
|
+
const handleGhostNodeImageChange = useCallback5((useImage, imageUrl) => {
|
|
15626
15730
|
const {
|
|
15627
15731
|
node: ghostNode,
|
|
15628
15732
|
line: ghostLine,
|
|
@@ -15670,7 +15774,7 @@ function XViewScene({
|
|
|
15670
15774
|
aura: newGhostNode.getObjectByName("aura")
|
|
15671
15775
|
};
|
|
15672
15776
|
}, []);
|
|
15673
|
-
const handleGhostNodeIntensityChange =
|
|
15777
|
+
const handleGhostNodeIntensityChange = useCallback5((newIntensity) => {
|
|
15674
15778
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
15675
15779
|
if (!ghostNode) return;
|
|
15676
15780
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -15691,7 +15795,7 @@ function XViewScene({
|
|
|
15691
15795
|
ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
|
|
15692
15796
|
}
|
|
15693
15797
|
}, []);
|
|
15694
|
-
const handleDetailNodeIntensityChange =
|
|
15798
|
+
const handleDetailNodeIntensityChange = useCallback5(
|
|
15695
15799
|
(nodeId, newIntensity) => {
|
|
15696
15800
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
15697
15801
|
if (!mesh) return;
|
|
@@ -15847,7 +15951,7 @@ function XViewScene({
|
|
|
15847
15951
|
mountRef.current.style.cursor = "default";
|
|
15848
15952
|
}
|
|
15849
15953
|
};
|
|
15850
|
-
const handleAncestryTreeUpdate =
|
|
15954
|
+
const handleAncestryTreeUpdate = useCallback5((newTree, extraData = null) => {
|
|
15851
15955
|
setAncestryMode((prev) => {
|
|
15852
15956
|
const prevTreeStr = JSON.stringify(prev.tree);
|
|
15853
15957
|
const newTreeStr = JSON.stringify(newTree);
|
|
@@ -15870,7 +15974,7 @@ function XViewScene({
|
|
|
15870
15974
|
};
|
|
15871
15975
|
});
|
|
15872
15976
|
}, []);
|
|
15873
|
-
const actionHandlerContext =
|
|
15977
|
+
const actionHandlerContext = useMemo13(
|
|
15874
15978
|
() => {
|
|
15875
15979
|
var _a2;
|
|
15876
15980
|
return {
|
|
@@ -15931,7 +16035,7 @@ function XViewScene({
|
|
|
15931
16035
|
const handleStartVersioning = (nodeData) => {
|
|
15932
16036
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
15933
16037
|
};
|
|
15934
|
-
const handleStartQuestQuick =
|
|
16038
|
+
const handleStartQuestQuick = useCallback5((questNode) => {
|
|
15935
16039
|
var _a2, _b2, _c2;
|
|
15936
16040
|
if (!questNode || !actionHandlerContext) return;
|
|
15937
16041
|
const allParentNodes = Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
|
|
@@ -15966,7 +16070,7 @@ function XViewScene({
|
|
|
15966
16070
|
}
|
|
15967
16071
|
setDetailsNode(updatedNode);
|
|
15968
16072
|
}, [session, actionHandlerContext]);
|
|
15969
|
-
const handleFinishQuestQuick =
|
|
16073
|
+
const handleFinishQuestQuick = useCallback5((questNode) => {
|
|
15970
16074
|
var _a2, _b2, _c2, _d2;
|
|
15971
16075
|
if (!questNode || !actionHandlerContext) return;
|
|
15972
16076
|
const {
|
|
@@ -16040,7 +16144,7 @@ function XViewScene({
|
|
|
16040
16144
|
setDetailsNode(null);
|
|
16041
16145
|
}
|
|
16042
16146
|
}, [session, actionHandlerContext, viewMembers, detailsNode]);
|
|
16043
|
-
const handleCancelQuest =
|
|
16147
|
+
const handleCancelQuest = useCallback5(() => {
|
|
16044
16148
|
const { graphGroup, ghostElements } = stateRef.current;
|
|
16045
16149
|
if (ghostElements.node && graphGroup) {
|
|
16046
16150
|
if (ghostElements.node.userData.labelObject) {
|
|
@@ -16104,6 +16208,10 @@ function XViewScene({
|
|
|
16104
16208
|
ownerId: ownerId2,
|
|
16105
16209
|
datasetName: "Quests Internas (View)"
|
|
16106
16210
|
});
|
|
16211
|
+
sceneDataRef2.current.quest_nodes = [...graphDataRef.current[sceneConfigId2].nodes];
|
|
16212
|
+
if (parentDataRef.current[sceneConfigId2]) {
|
|
16213
|
+
parentDataRef.current[sceneConfigId2].nodes = [...graphDataRef.current[sceneConfigId2].nodes];
|
|
16214
|
+
}
|
|
16107
16215
|
const finalPosition = stateRef2.current.ghostElements.node ? stateRef2.current.ghostElements.node.position.clone() : stateRef2.current.controls.target.clone();
|
|
16108
16216
|
const { graphGroup, ghostElements } = stateRef2.current;
|
|
16109
16217
|
if (ghostElements.node && graphGroup) {
|
|
@@ -16193,7 +16301,7 @@ function XViewScene({
|
|
|
16193
16301
|
}
|
|
16194
16302
|
userActionHandlers.handleCancelConnection(context);
|
|
16195
16303
|
};
|
|
16196
|
-
const handleClearAncestryVisuals =
|
|
16304
|
+
const handleClearAncestryVisuals = useCallback5((ancestryId) => {
|
|
16197
16305
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
16198
16306
|
const renderIndex = renderedAncestries.findIndex(
|
|
16199
16307
|
(a) => String(a.id) === String(ancestryId)
|
|
@@ -16211,7 +16319,7 @@ function XViewScene({
|
|
|
16211
16319
|
);
|
|
16212
16320
|
}
|
|
16213
16321
|
}, []);
|
|
16214
|
-
const handleRenderAncestry =
|
|
16322
|
+
const handleRenderAncestry = useCallback5(
|
|
16215
16323
|
async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
|
|
16216
16324
|
setContextMenu(
|
|
16217
16325
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -16705,7 +16813,7 @@ function XViewScene({
|
|
|
16705
16813
|
ancestryMode.isActive
|
|
16706
16814
|
]
|
|
16707
16815
|
);
|
|
16708
|
-
const handleRenderAbstractionTree =
|
|
16816
|
+
const handleRenderAbstractionTree = useCallback5(
|
|
16709
16817
|
(ancestryObject, targetNodeId = null) => {
|
|
16710
16818
|
setContextMenu(
|
|
16711
16819
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -16793,7 +16901,7 @@ function XViewScene({
|
|
|
16793
16901
|
handleClearAncestryVisuals
|
|
16794
16902
|
]
|
|
16795
16903
|
);
|
|
16796
|
-
const handleReadModeBranchNav =
|
|
16904
|
+
const handleReadModeBranchNav = useCallback5(
|
|
16797
16905
|
(nodeId, action, direction = "right") => {
|
|
16798
16906
|
const { ancestry, branchStack } = readingMode;
|
|
16799
16907
|
if (!ancestry || !ancestry.tree) return;
|
|
@@ -16971,13 +17079,13 @@ function XViewScene({
|
|
|
16971
17079
|
},
|
|
16972
17080
|
[readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]
|
|
16973
17081
|
);
|
|
16974
|
-
const handleReadModeHighlight =
|
|
17082
|
+
const handleReadModeHighlight = useCallback5((nodeId) => {
|
|
16975
17083
|
if (stateRef.current.highlightedNodeId !== nodeId) {
|
|
16976
17084
|
stateRef.current.highlightedNodeId = nodeId;
|
|
16977
17085
|
}
|
|
16978
17086
|
setHighlightedNodeId(nodeId);
|
|
16979
17087
|
}, []);
|
|
16980
|
-
const activeNodeBranches =
|
|
17088
|
+
const activeNodeBranches = useMemo13(() => {
|
|
16981
17089
|
if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree)
|
|
16982
17090
|
return null;
|
|
16983
17091
|
const fullTree = buildFullAncestryTree(
|
|
@@ -17021,7 +17129,7 @@ function XViewScene({
|
|
|
17021
17129
|
readingMode.branchStack,
|
|
17022
17130
|
ancestryDataRef.current
|
|
17023
17131
|
]);
|
|
17024
|
-
const backNavigationInfo =
|
|
17132
|
+
const backNavigationInfo = useMemo13(() => {
|
|
17025
17133
|
const { branchStack } = readingMode;
|
|
17026
17134
|
if (!branchStack || branchStack.length === 0) return null;
|
|
17027
17135
|
const lastStep = branchStack[branchStack.length - 1];
|
|
@@ -17032,7 +17140,7 @@ function XViewScene({
|
|
|
17032
17140
|
name: "Voltar para anterior"
|
|
17033
17141
|
};
|
|
17034
17142
|
}, [readingMode.branchStack]);
|
|
17035
|
-
const getReadModeDisplayContext =
|
|
17143
|
+
const getReadModeDisplayContext = useMemo13(() => {
|
|
17036
17144
|
const { ancestry, branchStack } = readingMode;
|
|
17037
17145
|
if (!ancestry) return null;
|
|
17038
17146
|
if (branchStack.length === 0) {
|
|
@@ -17075,7 +17183,7 @@ function XViewScene({
|
|
|
17075
17183
|
customProperties: branchProps
|
|
17076
17184
|
};
|
|
17077
17185
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
17078
|
-
const readModeAbstractionTree =
|
|
17186
|
+
const readModeAbstractionTree = useMemo13(() => {
|
|
17079
17187
|
if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
|
|
17080
17188
|
return null;
|
|
17081
17189
|
}
|
|
@@ -17094,7 +17202,7 @@ function XViewScene({
|
|
|
17094
17202
|
buildFullAncestryTree,
|
|
17095
17203
|
sceneVersion
|
|
17096
17204
|
]);
|
|
17097
|
-
const handleStartReadingAncestry =
|
|
17205
|
+
const handleStartReadingAncestry = useCallback5(
|
|
17098
17206
|
async (ancestryObject, renderMode = "full") => {
|
|
17099
17207
|
setContextMenu(
|
|
17100
17208
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -17137,7 +17245,7 @@ function XViewScene({
|
|
|
17137
17245
|
},
|
|
17138
17246
|
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
17139
17247
|
);
|
|
17140
|
-
const handleReadModeSectionChange =
|
|
17248
|
+
const handleReadModeSectionChange = useCallback5(
|
|
17141
17249
|
(activeSectionId) => {
|
|
17142
17250
|
const { ancestry, branchStack } = readingMode;
|
|
17143
17251
|
if (!ancestry || !readingMode.isActive) return;
|
|
@@ -17222,10 +17330,10 @@ function XViewScene({
|
|
|
17222
17330
|
ancestryDataRef.current
|
|
17223
17331
|
]
|
|
17224
17332
|
);
|
|
17225
|
-
const handleCloseReadMode =
|
|
17333
|
+
const handleCloseReadMode = useCallback5(() => {
|
|
17226
17334
|
setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
|
|
17227
17335
|
}, []);
|
|
17228
|
-
const handleAncestrySectionChange =
|
|
17336
|
+
const handleAncestrySectionChange = useCallback5(
|
|
17229
17337
|
(activeSectionId, ancestryOverride = null, rotation = 0) => {
|
|
17230
17338
|
var _a2, _b2;
|
|
17231
17339
|
const currentMode = stateRef.current.ancestry;
|
|
@@ -17287,7 +17395,7 @@ function XViewScene({
|
|
|
17287
17395
|
},
|
|
17288
17396
|
[handleRenderAncestry]
|
|
17289
17397
|
);
|
|
17290
|
-
const handleEditAncestry =
|
|
17398
|
+
const handleEditAncestry = useCallback5(
|
|
17291
17399
|
async (ancestryObject) => {
|
|
17292
17400
|
setContextMenu(
|
|
17293
17401
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -17342,7 +17450,7 @@ function XViewScene({
|
|
|
17342
17450
|
const handleSelectAncestryParent = (nodeId) => {
|
|
17343
17451
|
setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
|
|
17344
17452
|
};
|
|
17345
|
-
const handleRemoveFromAncestry =
|
|
17453
|
+
const handleRemoveFromAncestry = useCallback5((pathToRemove) => {
|
|
17346
17454
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
|
|
17347
17455
|
console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
|
|
17348
17456
|
return;
|
|
@@ -17367,7 +17475,7 @@ function XViewScene({
|
|
|
17367
17475
|
return { ...prev, tree: newTree };
|
|
17368
17476
|
});
|
|
17369
17477
|
}, []);
|
|
17370
|
-
const handleSaveAncestry =
|
|
17478
|
+
const handleSaveAncestry = useCallback5(
|
|
17371
17479
|
async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
|
|
17372
17480
|
const treeToUse = treeOverride || ancestryMode.tree;
|
|
17373
17481
|
const { isEditMode, currentAncestryId } = ancestryMode;
|
|
@@ -17603,7 +17711,7 @@ function XViewScene({
|
|
|
17603
17711
|
});
|
|
17604
17712
|
setEditingAncestryRel({ visible: false, data: null, path: null });
|
|
17605
17713
|
};
|
|
17606
|
-
const handleDeleteAncestry =
|
|
17714
|
+
const handleDeleteAncestry = useCallback5(
|
|
17607
17715
|
async (ancestryIdToDelete) => {
|
|
17608
17716
|
if (!ancestryIdToDelete) {
|
|
17609
17717
|
alert("ID da ancestralidade n\xE3o encontrado.");
|
|
@@ -17685,18 +17793,70 @@ function XViewScene({
|
|
|
17685
17793
|
},
|
|
17686
17794
|
[save_view_data, delete_file_action]
|
|
17687
17795
|
);
|
|
17688
|
-
const handleOpenAncestryBoard =
|
|
17796
|
+
const handleOpenAncestryBoard = useCallback5(() => {
|
|
17689
17797
|
setIsAncestryBoardOpen(true);
|
|
17690
17798
|
}, []);
|
|
17691
|
-
const
|
|
17692
|
-
(
|
|
17799
|
+
const allAvailableNodes = useMemo13(() => {
|
|
17800
|
+
if (!parentDataRef.current) return [];
|
|
17801
|
+
return Object.values(parentDataRef.current).flatMap(
|
|
17802
|
+
(fileData) => fileData.nodes || []
|
|
17803
|
+
);
|
|
17804
|
+
}, [sceneVersion, isInitialized]);
|
|
17805
|
+
const allAvailableAncestries = useMemo13(() => {
|
|
17806
|
+
return ancestryDataRef.current || [];
|
|
17807
|
+
}, [sceneVersion, isInitialized]);
|
|
17808
|
+
const handleOpenReference = useCallback5(
|
|
17809
|
+
(referenceData) => {
|
|
17810
|
+
const { type, id } = referenceData;
|
|
17811
|
+
if (type === "node") {
|
|
17812
|
+
const targetNode = allAvailableNodes.find(
|
|
17813
|
+
(n) => String(n.id) === String(id)
|
|
17814
|
+
);
|
|
17815
|
+
if (targetNode) {
|
|
17816
|
+
setAncestryLinkDetails(null);
|
|
17817
|
+
setDetailsLink(null);
|
|
17818
|
+
setDetailsNode(targetNode);
|
|
17819
|
+
const sceneMesh = stateRef.current.nodeObjects[String(id)];
|
|
17820
|
+
if (sceneMesh) {
|
|
17821
|
+
tweenToTarget(sceneMesh);
|
|
17822
|
+
}
|
|
17823
|
+
} else {
|
|
17824
|
+
alert("Node original n\xE3o encontrado neste contexto.");
|
|
17825
|
+
}
|
|
17826
|
+
} else if (type === "ancestry") {
|
|
17827
|
+
const targetAncestry = allAvailableAncestries.find(
|
|
17828
|
+
(a) => String(a.ancestry_id) === String(id)
|
|
17829
|
+
);
|
|
17830
|
+
if (targetAncestry) {
|
|
17831
|
+
setDetailsNode(null);
|
|
17832
|
+
setDetailsLink(null);
|
|
17833
|
+
setAncestryLinkDetails(null);
|
|
17834
|
+
handleEditAncestry(targetAncestry);
|
|
17835
|
+
} else {
|
|
17836
|
+
alert("Ancestralidade original n\xE3o encontrada neste contexto.");
|
|
17837
|
+
}
|
|
17838
|
+
}
|
|
17839
|
+
},
|
|
17840
|
+
[
|
|
17841
|
+
allAvailableNodes,
|
|
17842
|
+
allAvailableAncestries,
|
|
17843
|
+
handleEditAncestry,
|
|
17844
|
+
tweenToTarget
|
|
17845
|
+
]
|
|
17846
|
+
);
|
|
17847
|
+
const handleSelectAncestryFromBoard = useCallback5(
|
|
17848
|
+
(item) => {
|
|
17693
17849
|
setIsAncestryBoardOpen(false);
|
|
17694
17850
|
setIsSidebarOpen(false);
|
|
17695
|
-
|
|
17851
|
+
if (item.type === "ancestry") {
|
|
17852
|
+
handleStartReadingAncestry(item);
|
|
17853
|
+
} else {
|
|
17854
|
+
handleOpenReference({ type: "node", id: item.id });
|
|
17855
|
+
}
|
|
17696
17856
|
},
|
|
17697
|
-
[handleStartReadingAncestry]
|
|
17857
|
+
[handleStartReadingAncestry, handleOpenReference]
|
|
17698
17858
|
);
|
|
17699
|
-
const handleSaveAncestryBoard =
|
|
17859
|
+
const handleSaveAncestryBoard = useCallback5(
|
|
17700
17860
|
async (groups) => {
|
|
17701
17861
|
if (!sceneConfigId || !viewParams || !session) return;
|
|
17702
17862
|
const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
|
|
@@ -17710,7 +17870,7 @@ function XViewScene({
|
|
|
17710
17870
|
},
|
|
17711
17871
|
[sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]
|
|
17712
17872
|
);
|
|
17713
|
-
const existingNodeTypes =
|
|
17873
|
+
const existingNodeTypes = useMemo13(() => {
|
|
17714
17874
|
if (!parentDataRef.current) {
|
|
17715
17875
|
return [];
|
|
17716
17876
|
}
|
|
@@ -17722,7 +17882,7 @@ function XViewScene({
|
|
|
17722
17882
|
).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
|
|
17723
17883
|
return [...new Set(allTypes)];
|
|
17724
17884
|
}, [parentDataRef.current, sceneVersion]);
|
|
17725
|
-
const searchableDbNodes =
|
|
17885
|
+
const searchableDbNodes = useMemo13(() => {
|
|
17726
17886
|
if (!parentDataRef.current) {
|
|
17727
17887
|
return [];
|
|
17728
17888
|
}
|
|
@@ -17737,7 +17897,7 @@ function XViewScene({
|
|
|
17737
17897
|
return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
|
|
17738
17898
|
});
|
|
17739
17899
|
}, [parentDataRef.current, sceneVersion]);
|
|
17740
|
-
const handleAddExistingNode =
|
|
17900
|
+
const handleAddExistingNode = useCallback5(
|
|
17741
17901
|
(nodeId) => {
|
|
17742
17902
|
return userActionHandlers.handleAddExistingNodeById(
|
|
17743
17903
|
actionHandlerContext,
|
|
@@ -17746,7 +17906,7 @@ function XViewScene({
|
|
|
17746
17906
|
},
|
|
17747
17907
|
[actionHandlerContext]
|
|
17748
17908
|
);
|
|
17749
|
-
const handleUpdateMilestones =
|
|
17909
|
+
const handleUpdateMilestones = useCallback5(
|
|
17750
17910
|
async (newMilestones) => {
|
|
17751
17911
|
var _a2, _b2, _c2;
|
|
17752
17912
|
if (!sceneDataRef.current) return;
|
|
@@ -17792,7 +17952,7 @@ function XViewScene({
|
|
|
17792
17952
|
viewParams == null ? void 0 : viewParams.type
|
|
17793
17953
|
]
|
|
17794
17954
|
);
|
|
17795
|
-
const handleSaveCurrentView =
|
|
17955
|
+
const handleSaveCurrentView = useCallback5(async () => {
|
|
17796
17956
|
var _a2, _b2, _c2;
|
|
17797
17957
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
17798
17958
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
@@ -17835,61 +17995,13 @@ function XViewScene({
|
|
|
17835
17995
|
console.error("Erro na chamada de save_view_data:", error);
|
|
17836
17996
|
}
|
|
17837
17997
|
}, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
|
|
17838
|
-
const
|
|
17839
|
-
if (!parentDataRef.current) return [];
|
|
17840
|
-
return Object.values(parentDataRef.current).flatMap(
|
|
17841
|
-
(fileData) => fileData.nodes || []
|
|
17842
|
-
);
|
|
17843
|
-
}, [sceneVersion, isInitialized]);
|
|
17844
|
-
const allAvailableAncestries = useMemo12(() => {
|
|
17845
|
-
return ancestryDataRef.current || [];
|
|
17846
|
-
}, [sceneVersion, isInitialized]);
|
|
17847
|
-
const handleOpenReference = useCallback4(
|
|
17848
|
-
(referenceData) => {
|
|
17849
|
-
const { type, id } = referenceData;
|
|
17850
|
-
if (type === "node") {
|
|
17851
|
-
const targetNode = allAvailableNodes.find(
|
|
17852
|
-
(n) => String(n.id) === String(id)
|
|
17853
|
-
);
|
|
17854
|
-
if (targetNode) {
|
|
17855
|
-
setAncestryLinkDetails(null);
|
|
17856
|
-
setDetailsLink(null);
|
|
17857
|
-
setDetailsNode(targetNode);
|
|
17858
|
-
const sceneMesh = stateRef.current.nodeObjects[String(id)];
|
|
17859
|
-
if (sceneMesh) {
|
|
17860
|
-
tweenToTarget(sceneMesh);
|
|
17861
|
-
}
|
|
17862
|
-
} else {
|
|
17863
|
-
alert("Node original n\xE3o encontrado neste contexto.");
|
|
17864
|
-
}
|
|
17865
|
-
} else if (type === "ancestry") {
|
|
17866
|
-
const targetAncestry = allAvailableAncestries.find(
|
|
17867
|
-
(a) => String(a.ancestry_id) === String(id)
|
|
17868
|
-
);
|
|
17869
|
-
if (targetAncestry) {
|
|
17870
|
-
setDetailsNode(null);
|
|
17871
|
-
setDetailsLink(null);
|
|
17872
|
-
setAncestryLinkDetails(null);
|
|
17873
|
-
handleEditAncestry(targetAncestry);
|
|
17874
|
-
} else {
|
|
17875
|
-
alert("Ancestralidade original n\xE3o encontrada neste contexto.");
|
|
17876
|
-
}
|
|
17877
|
-
}
|
|
17878
|
-
},
|
|
17879
|
-
[
|
|
17880
|
-
allAvailableNodes,
|
|
17881
|
-
allAvailableAncestries,
|
|
17882
|
-
handleEditAncestry,
|
|
17883
|
-
tweenToTarget
|
|
17884
|
-
]
|
|
17885
|
-
);
|
|
17886
|
-
const handleToggleAncestryAddMode = useCallback4(() => {
|
|
17998
|
+
const handleToggleAncestryAddMode = useCallback5(() => {
|
|
17887
17999
|
setAncestryMode((prev) => ({
|
|
17888
18000
|
...prev,
|
|
17889
18001
|
isAddingNodes: !prev.isAddingNodes
|
|
17890
18002
|
}));
|
|
17891
18003
|
}, []);
|
|
17892
|
-
const handleFocusNode =
|
|
18004
|
+
const handleFocusNode = useCallback5(
|
|
17893
18005
|
(nodeData) => {
|
|
17894
18006
|
var _a2;
|
|
17895
18007
|
if (!nodeData) return;
|
|
@@ -17905,7 +18017,7 @@ function XViewScene({
|
|
|
17905
18017
|
},
|
|
17906
18018
|
[tweenToTarget]
|
|
17907
18019
|
);
|
|
17908
|
-
const availableDatasets =
|
|
18020
|
+
const availableDatasets = useMemo13(() => {
|
|
17909
18021
|
if (!sceneDataRef.current || !parentDataRef.current) return [];
|
|
17910
18022
|
return sceneDataRef.current.parent_dbs.map((db) => {
|
|
17911
18023
|
var _a2;
|
|
@@ -17919,7 +18031,7 @@ function XViewScene({
|
|
|
17919
18031
|
String(creationMode.sourceNodeData.id)
|
|
17920
18032
|
)) == null ? void 0 : _b.parentFileId : null;
|
|
17921
18033
|
const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
|
|
17922
|
-
|
|
18034
|
+
useEffect24(() => {
|
|
17923
18035
|
if (isInitialized && focusNodeId && !hasFocusedInitial) {
|
|
17924
18036
|
const nodeObjects = stateRef.current.nodeObjects || {};
|
|
17925
18037
|
const targetMesh = nodeObjects[String(focusNodeId)];
|
|
@@ -17942,7 +18054,7 @@ function XViewScene({
|
|
|
17942
18054
|
hasFocusedInitial,
|
|
17943
18055
|
tweenToTarget
|
|
17944
18056
|
]);
|
|
17945
|
-
|
|
18057
|
+
useEffect24(() => {
|
|
17946
18058
|
if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
|
|
17947
18059
|
const ancestries = ancestryDataRef.current || [];
|
|
17948
18060
|
const targetAncestry = ancestries.find(
|
|
@@ -17967,7 +18079,7 @@ function XViewScene({
|
|
|
17967
18079
|
hasOpenedInitialAncestry,
|
|
17968
18080
|
handleStartReadingAncestry
|
|
17969
18081
|
]);
|
|
17970
|
-
|
|
18082
|
+
useEffect24(() => {
|
|
17971
18083
|
function handleKeyDown(event) {
|
|
17972
18084
|
var _a2, _b2, _c2;
|
|
17973
18085
|
const context = actionHandlerContext;
|
|
@@ -18090,10 +18202,10 @@ function XViewScene({
|
|
|
18090
18202
|
// <-- handleCancelQuest adicionado aqui
|
|
18091
18203
|
]);
|
|
18092
18204
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
18093
|
-
return /* @__PURE__ */
|
|
18205
|
+
return /* @__PURE__ */ React30.createElement(LoadingScreen, null);
|
|
18094
18206
|
}
|
|
18095
18207
|
if (permissionStatus === "denied") {
|
|
18096
|
-
return /* @__PURE__ */
|
|
18208
|
+
return /* @__PURE__ */ React30.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ React30.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ React30.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ React30.createElement(
|
|
18097
18209
|
"svg",
|
|
18098
18210
|
{
|
|
18099
18211
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -18103,7 +18215,7 @@ function XViewScene({
|
|
|
18103
18215
|
stroke: "currentColor",
|
|
18104
18216
|
className: "w-16 h-16 mx-auto"
|
|
18105
18217
|
},
|
|
18106
|
-
/* @__PURE__ */
|
|
18218
|
+
/* @__PURE__ */ React30.createElement(
|
|
18107
18219
|
"path",
|
|
18108
18220
|
{
|
|
18109
18221
|
strokeLinecap: "round",
|
|
@@ -18111,13 +18223,13 @@ function XViewScene({
|
|
|
18111
18223
|
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"
|
|
18112
18224
|
}
|
|
18113
18225
|
)
|
|
18114
|
-
)), /* @__PURE__ */
|
|
18226
|
+
)), /* @__PURE__ */ React30.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ React30.createElement("p", { className: "text-slate-400 mb-6" }, "Voc\xEA n\xE3o tem permiss\xE3o para acessar este conte\xFAdo. Solicite acesso ao propriet\xE1rio ou verifique se est\xE1 na conta correta."), /* @__PURE__ */ React30.createElement(
|
|
18115
18227
|
"button",
|
|
18116
18228
|
{
|
|
18117
18229
|
onClick: () => router.push("/dashboard/scenes"),
|
|
18118
18230
|
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"
|
|
18119
18231
|
},
|
|
18120
|
-
/* @__PURE__ */
|
|
18232
|
+
/* @__PURE__ */ React30.createElement(
|
|
18121
18233
|
"svg",
|
|
18122
18234
|
{
|
|
18123
18235
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -18127,7 +18239,7 @@ function XViewScene({
|
|
|
18127
18239
|
stroke: "currentColor",
|
|
18128
18240
|
className: "w-5 h-5"
|
|
18129
18241
|
},
|
|
18130
|
-
/* @__PURE__ */
|
|
18242
|
+
/* @__PURE__ */ React30.createElement(
|
|
18131
18243
|
"path",
|
|
18132
18244
|
{
|
|
18133
18245
|
strokeLinecap: "round",
|
|
@@ -18139,7 +18251,7 @@ function XViewScene({
|
|
|
18139
18251
|
"Voltar para Scenes"
|
|
18140
18252
|
)));
|
|
18141
18253
|
}
|
|
18142
|
-
return /* @__PURE__ */
|
|
18254
|
+
return /* @__PURE__ */ React30.createElement(
|
|
18143
18255
|
"div",
|
|
18144
18256
|
{
|
|
18145
18257
|
ref: mountRef,
|
|
@@ -18151,7 +18263,7 @@ function XViewScene({
|
|
|
18151
18263
|
cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
|
|
18152
18264
|
}
|
|
18153
18265
|
},
|
|
18154
|
-
userPermissionRole !== "link_viewer" && /* @__PURE__ */
|
|
18266
|
+
userPermissionRole !== "link_viewer" && /* @__PURE__ */ React30.createElement(
|
|
18155
18267
|
XViewSidebar,
|
|
18156
18268
|
{
|
|
18157
18269
|
dbNodes: searchableDbNodes,
|
|
@@ -18175,7 +18287,7 @@ function XViewScene({
|
|
|
18175
18287
|
onOpenMilestoneManager: () => setIsMilestoneManagerOpen(true)
|
|
18176
18288
|
}
|
|
18177
18289
|
),
|
|
18178
|
-
creationMode.isActive && /* @__PURE__ */
|
|
18290
|
+
creationMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18179
18291
|
InSceneCreationForm,
|
|
18180
18292
|
{
|
|
18181
18293
|
onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
|
|
@@ -18207,7 +18319,7 @@ function XViewScene({
|
|
|
18207
18319
|
availableAncestries: allAvailableAncestries
|
|
18208
18320
|
}
|
|
18209
18321
|
),
|
|
18210
|
-
versionMode.isActive && /* @__PURE__ */
|
|
18322
|
+
versionMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18211
18323
|
InSceneVersionForm,
|
|
18212
18324
|
{
|
|
18213
18325
|
onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
|
|
@@ -18233,7 +18345,7 @@ function XViewScene({
|
|
|
18233
18345
|
availableAncestries: allAvailableAncestries
|
|
18234
18346
|
}
|
|
18235
18347
|
),
|
|
18236
|
-
questMode.isActive && /* @__PURE__ */
|
|
18348
|
+
questMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18237
18349
|
InSceneQuestForm,
|
|
18238
18350
|
{
|
|
18239
18351
|
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
@@ -18261,7 +18373,7 @@ function XViewScene({
|
|
|
18261
18373
|
onUpdateMilestones: handleUpdateMilestones
|
|
18262
18374
|
}
|
|
18263
18375
|
),
|
|
18264
|
-
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */
|
|
18376
|
+
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React30.createElement(
|
|
18265
18377
|
"div",
|
|
18266
18378
|
{
|
|
18267
18379
|
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"}`,
|
|
@@ -18274,7 +18386,7 @@ function XViewScene({
|
|
|
18274
18386
|
maxWidth: "92vw"
|
|
18275
18387
|
}
|
|
18276
18388
|
},
|
|
18277
|
-
/* @__PURE__ */
|
|
18389
|
+
/* @__PURE__ */ React30.createElement(
|
|
18278
18390
|
"div",
|
|
18279
18391
|
{
|
|
18280
18392
|
onPointerDown: (e) => {
|
|
@@ -18285,7 +18397,7 @@ function XViewScene({
|
|
|
18285
18397
|
title: "Arraste para redimensionar"
|
|
18286
18398
|
}
|
|
18287
18399
|
),
|
|
18288
|
-
/* @__PURE__ */
|
|
18400
|
+
/* @__PURE__ */ React30.createElement(
|
|
18289
18401
|
DescriptionReadModePanel,
|
|
18290
18402
|
{
|
|
18291
18403
|
key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
|
|
@@ -18320,7 +18432,7 @@ function XViewScene({
|
|
|
18320
18432
|
}
|
|
18321
18433
|
)
|
|
18322
18434
|
),
|
|
18323
|
-
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */
|
|
18435
|
+
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ React30.createElement(
|
|
18324
18436
|
CreateAncestryPanel,
|
|
18325
18437
|
{
|
|
18326
18438
|
ancestryMode,
|
|
@@ -18356,7 +18468,7 @@ function XViewScene({
|
|
|
18356
18468
|
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
18357
18469
|
}
|
|
18358
18470
|
),
|
|
18359
|
-
editingAncestryRel.visible && /* @__PURE__ */
|
|
18471
|
+
editingAncestryRel.visible && /* @__PURE__ */ React30.createElement(
|
|
18360
18472
|
AncestryRelationshipPanel,
|
|
18361
18473
|
{
|
|
18362
18474
|
data: editingAncestryRel.data,
|
|
@@ -18370,7 +18482,7 @@ function XViewScene({
|
|
|
18370
18482
|
onUploadFile: upload_file_action
|
|
18371
18483
|
}
|
|
18372
18484
|
),
|
|
18373
|
-
detailsNode && detailsNode.is_quest && /* @__PURE__ */
|
|
18485
|
+
detailsNode && detailsNode.is_quest && /* @__PURE__ */ React30.createElement(
|
|
18374
18486
|
QuestDetailsPanel,
|
|
18375
18487
|
{
|
|
18376
18488
|
node: detailsNode,
|
|
@@ -18396,7 +18508,7 @@ function XViewScene({
|
|
|
18396
18508
|
onUpdateMilestones: handleUpdateMilestones
|
|
18397
18509
|
}
|
|
18398
18510
|
),
|
|
18399
|
-
detailsNode && !detailsNode.is_quest && /* @__PURE__ */
|
|
18511
|
+
detailsNode && !detailsNode.is_quest && /* @__PURE__ */ React30.createElement(
|
|
18400
18512
|
NodeDetailsPanel,
|
|
18401
18513
|
{
|
|
18402
18514
|
node: detailsNode,
|
|
@@ -18428,7 +18540,7 @@ function XViewScene({
|
|
|
18428
18540
|
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
18429
18541
|
}
|
|
18430
18542
|
),
|
|
18431
|
-
detailsLink && /* @__PURE__ */
|
|
18543
|
+
detailsLink && /* @__PURE__ */ React30.createElement(
|
|
18432
18544
|
RelationshipDetailsPanel,
|
|
18433
18545
|
{
|
|
18434
18546
|
link: detailsLink,
|
|
@@ -18442,7 +18554,7 @@ function XViewScene({
|
|
|
18442
18554
|
userRole: userPermissionRole
|
|
18443
18555
|
}
|
|
18444
18556
|
),
|
|
18445
|
-
ancestryLinkDetails && /* @__PURE__ */
|
|
18557
|
+
ancestryLinkDetails && /* @__PURE__ */ React30.createElement(
|
|
18446
18558
|
AncestryLinkDetailsPanel,
|
|
18447
18559
|
{
|
|
18448
18560
|
data: ancestryLinkDetails,
|
|
@@ -18453,7 +18565,7 @@ function XViewScene({
|
|
|
18453
18565
|
onUploadFile: upload_file_action
|
|
18454
18566
|
}
|
|
18455
18567
|
),
|
|
18456
|
-
/* @__PURE__ */
|
|
18568
|
+
/* @__PURE__ */ React30.createElement(
|
|
18457
18569
|
"div",
|
|
18458
18570
|
{
|
|
18459
18571
|
ref: tooltipRef,
|
|
@@ -18480,7 +18592,7 @@ function XViewScene({
|
|
|
18480
18592
|
}
|
|
18481
18593
|
}
|
|
18482
18594
|
),
|
|
18483
|
-
/* @__PURE__ */
|
|
18595
|
+
/* @__PURE__ */ React30.createElement(
|
|
18484
18596
|
ContextMenu,
|
|
18485
18597
|
{
|
|
18486
18598
|
data: contextMenu,
|
|
@@ -18513,7 +18625,7 @@ function XViewScene({
|
|
|
18513
18625
|
onFinishQuest: handleFinishQuestQuick
|
|
18514
18626
|
}
|
|
18515
18627
|
),
|
|
18516
|
-
/* @__PURE__ */
|
|
18628
|
+
/* @__PURE__ */ React30.createElement(
|
|
18517
18629
|
MultiNodeContextMenu,
|
|
18518
18630
|
{
|
|
18519
18631
|
data: multiContextMenu,
|
|
@@ -18533,7 +18645,7 @@ function XViewScene({
|
|
|
18533
18645
|
)
|
|
18534
18646
|
}
|
|
18535
18647
|
),
|
|
18536
|
-
/* @__PURE__ */
|
|
18648
|
+
/* @__PURE__ */ React30.createElement(
|
|
18537
18649
|
RelationshipContextMenu,
|
|
18538
18650
|
{
|
|
18539
18651
|
data: relationshipMenu,
|
|
@@ -18551,14 +18663,14 @@ function XViewScene({
|
|
|
18551
18663
|
onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
|
|
18552
18664
|
}
|
|
18553
18665
|
),
|
|
18554
|
-
/* @__PURE__ */
|
|
18666
|
+
/* @__PURE__ */ React30.createElement(
|
|
18555
18667
|
ImageViewer,
|
|
18556
18668
|
{
|
|
18557
18669
|
data: imageViewer,
|
|
18558
18670
|
onClose: () => setImageViewer({ ...imageViewer, visible: false })
|
|
18559
18671
|
}
|
|
18560
18672
|
),
|
|
18561
|
-
/* @__PURE__ */
|
|
18673
|
+
/* @__PURE__ */ React30.createElement(
|
|
18562
18674
|
AncestryBoard,
|
|
18563
18675
|
{
|
|
18564
18676
|
isOpen: isAncestryBoardOpen,
|
|
@@ -18571,7 +18683,7 @@ function XViewScene({
|
|
|
18571
18683
|
userRole: userPermissionRole
|
|
18572
18684
|
}
|
|
18573
18685
|
),
|
|
18574
|
-
/* @__PURE__ */
|
|
18686
|
+
/* @__PURE__ */ React30.createElement(
|
|
18575
18687
|
MilestoneManager,
|
|
18576
18688
|
{
|
|
18577
18689
|
isOpen: isMilestoneManagerOpen,
|
|
@@ -18580,7 +18692,7 @@ function XViewScene({
|
|
|
18580
18692
|
onUpdateMilestones: handleUpdateMilestones
|
|
18581
18693
|
}
|
|
18582
18694
|
),
|
|
18583
|
-
/* @__PURE__ */
|
|
18695
|
+
/* @__PURE__ */ React30.createElement(
|
|
18584
18696
|
ImportParentFileModal,
|
|
18585
18697
|
{
|
|
18586
18698
|
isOpen: isImportModalOpen,
|
|
@@ -18593,7 +18705,7 @@ function XViewScene({
|
|
|
18593
18705
|
currentAncestries: ancestryDataRef.current || []
|
|
18594
18706
|
}
|
|
18595
18707
|
),
|
|
18596
|
-
invalidTargetError && /* @__PURE__ */
|
|
18708
|
+
invalidTargetError && /* @__PURE__ */ React30.createElement(
|
|
18597
18709
|
"div",
|
|
18598
18710
|
{
|
|
18599
18711
|
className: "ui-overlay",
|
|
@@ -18618,13 +18730,13 @@ function XViewScene({
|
|
|
18618
18730
|
animation: "fadeInDown 0.5s cubic-bezier(0.16, 1, 0.3, 1)"
|
|
18619
18731
|
}
|
|
18620
18732
|
},
|
|
18621
|
-
/* @__PURE__ */
|
|
18733
|
+
/* @__PURE__ */ React30.createElement("style", null, `
|
|
18622
18734
|
@keyframes fadeInDown {
|
|
18623
18735
|
from { opacity: 0; transform: translate(-50%, -20px); }
|
|
18624
18736
|
to { opacity: 1; transform: translate(-50%, 0); }
|
|
18625
18737
|
}
|
|
18626
18738
|
`),
|
|
18627
|
-
/* @__PURE__ */
|
|
18739
|
+
/* @__PURE__ */ React30.createElement(
|
|
18628
18740
|
"svg",
|
|
18629
18741
|
{
|
|
18630
18742
|
width: "20",
|
|
@@ -18636,12 +18748,12 @@ function XViewScene({
|
|
|
18636
18748
|
strokeLinecap: "round",
|
|
18637
18749
|
strokeLinejoin: "round"
|
|
18638
18750
|
},
|
|
18639
|
-
/* @__PURE__ */
|
|
18640
|
-
/* @__PURE__ */
|
|
18641
|
-
/* @__PURE__ */
|
|
18751
|
+
/* @__PURE__ */ React30.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
18752
|
+
/* @__PURE__ */ React30.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
18753
|
+
/* @__PURE__ */ React30.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
18642
18754
|
),
|
|
18643
|
-
/* @__PURE__ */
|
|
18644
|
-
/* @__PURE__ */
|
|
18755
|
+
/* @__PURE__ */ React30.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
|
|
18756
|
+
/* @__PURE__ */ React30.createElement(
|
|
18645
18757
|
"button",
|
|
18646
18758
|
{
|
|
18647
18759
|
onClick: () => setInvalidTargetError(null),
|