@lv-x-software-house/x_view 1.2.6-dev.1 → 1.2.6-dev.11
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 +744 -796
- package/dist/index.mjs +751 -804
- 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);
|
|
@@ -2318,8 +2275,6 @@ var userActionHandlers = {
|
|
|
2318
2275
|
milestones: sceneDataRef.current.milestones || [],
|
|
2319
2276
|
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
2320
2277
|
};
|
|
2321
|
-
sceneDataRef.current.quest_nodes = specificParentData.nodes;
|
|
2322
|
-
sceneDataRef.current.quest_links = specificParentData.links;
|
|
2323
2278
|
await context.actions.save_view_data(
|
|
2324
2279
|
context.sceneSaveUrl,
|
|
2325
2280
|
viewFilePayload
|
|
@@ -2332,6 +2287,10 @@ var userActionHandlers = {
|
|
|
2332
2287
|
);
|
|
2333
2288
|
}
|
|
2334
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
|
+
}
|
|
2335
2294
|
updateExistingNodeVisuals(stateRef.current, nodeToSave);
|
|
2336
2295
|
setters.setSceneVersion((v) => v + 1);
|
|
2337
2296
|
if (!keepOpen) {
|
|
@@ -2480,15 +2439,15 @@ function createNewCustomProperty(existingProps = []) {
|
|
|
2480
2439
|
switch (nextType) {
|
|
2481
2440
|
case "links":
|
|
2482
2441
|
nextKey = "Links";
|
|
2483
|
-
nextValue = [{ id:
|
|
2442
|
+
nextValue = [{ id: uuidv4(), name: "", value: "" }];
|
|
2484
2443
|
break;
|
|
2485
2444
|
case "images":
|
|
2486
2445
|
nextKey = "Images";
|
|
2487
|
-
nextValue = [{ id:
|
|
2446
|
+
nextValue = [{ id: uuidv4(), name: "1", value: "" }];
|
|
2488
2447
|
break;
|
|
2489
2448
|
case "documents":
|
|
2490
2449
|
nextKey = "Documents";
|
|
2491
|
-
nextValue = [{ id:
|
|
2450
|
+
nextValue = [{ id: uuidv4(), name: "1", value: "" }];
|
|
2492
2451
|
break;
|
|
2493
2452
|
case "date":
|
|
2494
2453
|
nextKey = "Date";
|
|
@@ -2498,14 +2457,14 @@ function createNewCustomProperty(existingProps = []) {
|
|
|
2498
2457
|
nextValue = 0;
|
|
2499
2458
|
break;
|
|
2500
2459
|
case "list":
|
|
2501
|
-
nextValue = [{ id:
|
|
2460
|
+
nextValue = [{ id: uuidv4(), name: "", value: "" }];
|
|
2502
2461
|
break;
|
|
2503
2462
|
default:
|
|
2504
2463
|
nextValue = "";
|
|
2505
2464
|
break;
|
|
2506
2465
|
}
|
|
2507
2466
|
return {
|
|
2508
|
-
id:
|
|
2467
|
+
id: uuidv4(),
|
|
2509
2468
|
key: nextKey,
|
|
2510
2469
|
type: nextType,
|
|
2511
2470
|
value: nextValue,
|
|
@@ -2750,7 +2709,7 @@ function extractCustomPropsFromNode(node) {
|
|
|
2750
2709
|
if (val && typeof val === "object") {
|
|
2751
2710
|
if ("date_interval" in val) {
|
|
2752
2711
|
return {
|
|
2753
|
-
id:
|
|
2712
|
+
id: uuidv4(),
|
|
2754
2713
|
key,
|
|
2755
2714
|
type: "date",
|
|
2756
2715
|
value: {
|
|
@@ -2762,7 +2721,7 @@ function extractCustomPropsFromNode(node) {
|
|
|
2762
2721
|
}
|
|
2763
2722
|
if ("year" in val) {
|
|
2764
2723
|
return {
|
|
2765
|
-
id:
|
|
2724
|
+
id: uuidv4(),
|
|
2766
2725
|
key,
|
|
2767
2726
|
type: "date",
|
|
2768
2727
|
value: { type: "Ano", value: val.year || "" }
|
|
@@ -2770,7 +2729,7 @@ function extractCustomPropsFromNode(node) {
|
|
|
2770
2729
|
}
|
|
2771
2730
|
if ("date" in val) {
|
|
2772
2731
|
return {
|
|
2773
|
-
id:
|
|
2732
|
+
id: uuidv4(),
|
|
2774
2733
|
key,
|
|
2775
2734
|
type: "date",
|
|
2776
2735
|
value: { type: "Data", value: val.date || "" }
|
|
@@ -2778,7 +2737,7 @@ function extractCustomPropsFromNode(node) {
|
|
|
2778
2737
|
}
|
|
2779
2738
|
}
|
|
2780
2739
|
return {
|
|
2781
|
-
id:
|
|
2740
|
+
id: uuidv4(),
|
|
2782
2741
|
key,
|
|
2783
2742
|
type: "date",
|
|
2784
2743
|
value: { type: "Data", value: "" }
|
|
@@ -2786,14 +2745,14 @@ function extractCustomPropsFromNode(node) {
|
|
|
2786
2745
|
}
|
|
2787
2746
|
if (t === "list" || t === "links" || t === "images" || t === "documents") {
|
|
2788
2747
|
const safeList = (val || []).map((item) => ({
|
|
2789
|
-
id: item.id ||
|
|
2748
|
+
id: item.id || uuidv4(),
|
|
2790
2749
|
name: item.name ?? "",
|
|
2791
2750
|
value: item.value ?? ""
|
|
2792
2751
|
}));
|
|
2793
|
-
return { id:
|
|
2752
|
+
return { id: uuidv4(), key, type: t, value: safeList };
|
|
2794
2753
|
}
|
|
2795
2754
|
return {
|
|
2796
|
-
id:
|
|
2755
|
+
id: uuidv4(),
|
|
2797
2756
|
key,
|
|
2798
2757
|
type: t,
|
|
2799
2758
|
value: t === "number" ? Number(val) || 0 : String(val ?? "")
|
|
@@ -3066,16 +3025,16 @@ var processDescriptionForSave = (text, existingSections = []) => {
|
|
|
3066
3025
|
if (existingMatch) {
|
|
3067
3026
|
finalUuid = existingMatch.id;
|
|
3068
3027
|
} else {
|
|
3069
|
-
finalUuid =
|
|
3028
|
+
finalUuid = uuidv4();
|
|
3070
3029
|
}
|
|
3071
3030
|
} else {
|
|
3072
3031
|
finalUuid = numericMap.get(numStr);
|
|
3073
3032
|
if (!finalUuid) {
|
|
3074
|
-
finalUuid =
|
|
3033
|
+
finalUuid = uuidv4();
|
|
3075
3034
|
}
|
|
3076
3035
|
}
|
|
3077
3036
|
if (usedIds.has(finalUuid)) {
|
|
3078
|
-
finalUuid =
|
|
3037
|
+
finalUuid = uuidv4();
|
|
3079
3038
|
}
|
|
3080
3039
|
usedIds.add(finalUuid);
|
|
3081
3040
|
processedSections.push({
|
|
@@ -3186,18 +3145,18 @@ function useResizablePanel({ initialWidth, minWidth, maxWidth }) {
|
|
|
3186
3145
|
function createTimelineEntry(actorId, description, type = "comment", extras = {}) {
|
|
3187
3146
|
const { links = [], images = [], metadata = {} } = extras;
|
|
3188
3147
|
return {
|
|
3189
|
-
id:
|
|
3148
|
+
id: uuidv4(),
|
|
3190
3149
|
type,
|
|
3191
3150
|
timestamp: Date.now(),
|
|
3192
3151
|
actorId,
|
|
3193
3152
|
description,
|
|
3194
3153
|
links: links.map((l) => ({
|
|
3195
|
-
id: l.id ||
|
|
3154
|
+
id: l.id || uuidv4(),
|
|
3196
3155
|
name: l.name || "",
|
|
3197
3156
|
value: l.value || ""
|
|
3198
3157
|
})),
|
|
3199
3158
|
images: images.map((img) => ({
|
|
3200
|
-
id: img.id ||
|
|
3159
|
+
id: img.id || uuidv4(),
|
|
3201
3160
|
name: img.name || "",
|
|
3202
3161
|
value: img.value || ""
|
|
3203
3162
|
}))
|
|
@@ -4424,6 +4383,7 @@ function XViewSidebar({
|
|
|
4424
4383
|
|
|
4425
4384
|
// src/components/AncestryRelationshipPanel.jsx
|
|
4426
4385
|
import React8, { useState as useState9, useEffect as useEffect8, useRef as useRef7 } from "react";
|
|
4386
|
+
import { v4 as uuidv43 } from "uuid";
|
|
4427
4387
|
|
|
4428
4388
|
// src/components/CustomPropertyDisplay.jsx
|
|
4429
4389
|
import React3, { useState as useState4, useRef as useRef3, useEffect as useEffect3 } from "react";
|
|
@@ -5183,6 +5143,7 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
|
|
|
5183
5143
|
}
|
|
5184
5144
|
|
|
5185
5145
|
// src/components/DescriptionEditModal.jsx
|
|
5146
|
+
import { v4 as uuidv42 } from "uuid";
|
|
5186
5147
|
var getNextSectionNumber = (currentText) => {
|
|
5187
5148
|
const regex = /\*\/\s*(\d+)(?::[a-zA-Z0-9-]+)?\s*\//g;
|
|
5188
5149
|
let max = 0;
|
|
@@ -5314,7 +5275,7 @@ function DescriptionEditModal({
|
|
|
5314
5275
|
const el = textareaRef.current;
|
|
5315
5276
|
if (!el) return;
|
|
5316
5277
|
const nextNum = getNextSectionNumber(text);
|
|
5317
|
-
const uniqueSuffix =
|
|
5278
|
+
const uniqueSuffix = uuidv42().slice(0, 4);
|
|
5318
5279
|
insertAtCursor(`*/${nextNum}:${uniqueSuffix}/ `);
|
|
5319
5280
|
};
|
|
5320
5281
|
const handleImportSelect = (tags) => {
|
|
@@ -5325,7 +5286,7 @@ function DescriptionEditModal({
|
|
|
5325
5286
|
let currentNum = getNextSectionNumber(currentText);
|
|
5326
5287
|
let blockToInsert = "";
|
|
5327
5288
|
tagsArray.forEach((tag) => {
|
|
5328
|
-
const uniqueSuffix =
|
|
5289
|
+
const uniqueSuffix = uuidv42().slice(0, 4);
|
|
5329
5290
|
blockToInsert += `
|
|
5330
5291
|
*/${currentNum}:${uniqueSuffix}/ ${tag}
|
|
5331
5292
|
`;
|
|
@@ -6685,6 +6646,7 @@ import {
|
|
|
6685
6646
|
FiLink as FiLink4,
|
|
6686
6647
|
FiTrash2 as FiTrash22
|
|
6687
6648
|
} from "react-icons/fi";
|
|
6649
|
+
import { v4 as uuidv44 } from "uuid";
|
|
6688
6650
|
|
|
6689
6651
|
// src/components/AncestryPickerModal.jsx
|
|
6690
6652
|
import React9, { useState as useState10, useMemo as useMemo7, useEffect as useEffect9 } from "react";
|
|
@@ -7721,7 +7683,7 @@ function CreateAncestryPanel({
|
|
|
7721
7683
|
const nodeData = availableNodes.find((n) => String(n.id) === String(nodeId));
|
|
7722
7684
|
const dirSuffix = direction === "left" ? "(Esq)" : "(Dir)";
|
|
7723
7685
|
branch = {
|
|
7724
|
-
id:
|
|
7686
|
+
id: uuidv44(),
|
|
7725
7687
|
name: `Ramifica\xE7\xE3o ${dirSuffix} de ${(nodeData == null ? void 0 : nodeData.name) || "Node"}`,
|
|
7726
7688
|
description: "",
|
|
7727
7689
|
description_sections: [],
|
|
@@ -8500,6 +8462,7 @@ function ImageViewer({ data, onClose }) {
|
|
|
8500
8462
|
|
|
8501
8463
|
// src/components/InSceneCreationForm.jsx
|
|
8502
8464
|
import React13, { useState as useState14, useEffect as useEffect13, useRef as useRef10 } from "react";
|
|
8465
|
+
import { v4 as uuidv45 } from "uuid";
|
|
8503
8466
|
|
|
8504
8467
|
// src/components/ColorPicker.jsx
|
|
8505
8468
|
import React12, { useState as useState13, useEffect as useEffect12, useRef as useRef9 } from "react";
|
|
@@ -9084,6 +9047,7 @@ function InSceneCreationForm({
|
|
|
9084
9047
|
|
|
9085
9048
|
// src/components/InSceneVersionForm.jsx
|
|
9086
9049
|
import React14, { useState as useState15, useEffect as useEffect14, useRef as useRef11 } from "react";
|
|
9050
|
+
import { v4 as uuidv46 } from "uuid";
|
|
9087
9051
|
import { FiPlus as FiPlus4, FiMaximize2 as FiMaximize22, FiCheck as FiCheck8, FiEdit2 as FiEdit25 } from "react-icons/fi";
|
|
9088
9052
|
function InSceneVersionForm({
|
|
9089
9053
|
onSave,
|
|
@@ -9106,7 +9070,7 @@ function InSceneVersionForm({
|
|
|
9106
9070
|
const [description, setDescription] = useState15("");
|
|
9107
9071
|
const [customProps, setCustomProps] = useState15([
|
|
9108
9072
|
{
|
|
9109
|
-
id:
|
|
9073
|
+
id: uuidv46(),
|
|
9110
9074
|
key: "Date",
|
|
9111
9075
|
type: "date",
|
|
9112
9076
|
value: { type: "Data", value: "" },
|
|
@@ -9399,6 +9363,7 @@ function InSceneVersionForm({
|
|
|
9399
9363
|
|
|
9400
9364
|
// src/components/InSceneQuestForm.jsx
|
|
9401
9365
|
import React16, { useState as useState17, useRef as useRef12 } from "react";
|
|
9366
|
+
import { v4 as uuidv47 } from "uuid";
|
|
9402
9367
|
import {
|
|
9403
9368
|
FiPlus as FiPlus6,
|
|
9404
9369
|
FiCheck as FiCheck9,
|
|
@@ -10323,6 +10288,7 @@ function InSceneQuestForm({
|
|
|
10323
10288
|
|
|
10324
10289
|
// src/components/NodeDetailsPanel.jsx
|
|
10325
10290
|
import React17, { useState as useState18, useEffect as useEffect15, useRef as useRef13 } from "react";
|
|
10291
|
+
import { v4 as uuidv48 } from "uuid";
|
|
10326
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";
|
|
10327
10293
|
function NodeDetailsPanel({
|
|
10328
10294
|
node,
|
|
@@ -10837,6 +10803,7 @@ function NodeDetailsPanel({
|
|
|
10837
10803
|
|
|
10838
10804
|
// src/components/QuestDetailsPanel.jsx
|
|
10839
10805
|
import React19, { useState as useState19, useEffect as useEffect16, useRef as useRef14 } from "react";
|
|
10806
|
+
import { v4 as uuidv49 } from "uuid";
|
|
10840
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";
|
|
10841
10808
|
|
|
10842
10809
|
// src/components/QuestTimeline.jsx
|
|
@@ -11287,7 +11254,7 @@ ${noteText}` : noteText : entry.notes,
|
|
|
11287
11254
|
}, 100);
|
|
11288
11255
|
};
|
|
11289
11256
|
const addLinkToNote = () => {
|
|
11290
|
-
setNoteLinks([...noteLinks, { id:
|
|
11257
|
+
setNoteLinks([...noteLinks, { id: uuidv49(), name: "", value: "" }]);
|
|
11291
11258
|
};
|
|
11292
11259
|
const removeLinkFromNote = (id) => {
|
|
11293
11260
|
setNoteLinks(noteLinks.filter((l) => l.id !== id));
|
|
@@ -11296,7 +11263,7 @@ ${noteText}` : noteText : entry.notes,
|
|
|
11296
11263
|
setNoteLinks(noteLinks.map((l) => l.id === id ? { ...l, [field]: val } : l));
|
|
11297
11264
|
};
|
|
11298
11265
|
const addImageToNote = () => {
|
|
11299
|
-
setNoteImages([...noteImages, { id:
|
|
11266
|
+
setNoteImages([...noteImages, { id: uuidv49(), name: "Image", value: "" }]);
|
|
11300
11267
|
};
|
|
11301
11268
|
const removeImageFromNote = (id) => {
|
|
11302
11269
|
setNoteImages(noteImages.filter((img) => img.id !== id));
|
|
@@ -12173,6 +12140,7 @@ function MultiNodeContextMenu({
|
|
|
12173
12140
|
|
|
12174
12141
|
// src/components/RelationshipDetailsPanel.jsx
|
|
12175
12142
|
import React21, { useState as useState21, useEffect as useEffect18, useRef as useRef16, useMemo as useMemo9 } from "react";
|
|
12143
|
+
import { v4 as uuidv410 } from "uuid";
|
|
12176
12144
|
import { FiPlus as FiPlus9, FiEdit2 as FiEdit29, FiLoader as FiLoader4, FiBookOpen as FiBookOpen5 } from "react-icons/fi";
|
|
12177
12145
|
function RelationshipDetailsPanel({
|
|
12178
12146
|
link,
|
|
@@ -12982,10 +12950,10 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
|
|
|
12982
12950
|
}
|
|
12983
12951
|
|
|
12984
12952
|
// src/components/AncestryBoard.jsx
|
|
12985
|
-
import
|
|
12953
|
+
import React28, { useState as useState27, useMemo as useMemo12, useEffect as useEffect23 } from "react";
|
|
12986
12954
|
import {
|
|
12987
12955
|
FiSearch as FiSearch8,
|
|
12988
|
-
FiLayers as
|
|
12956
|
+
FiLayers as FiLayers7,
|
|
12989
12957
|
FiCornerUpRight as FiCornerUpRight4,
|
|
12990
12958
|
FiPlay,
|
|
12991
12959
|
FiPlus as FiPlus10,
|
|
@@ -12995,194 +12963,418 @@ import {
|
|
|
12995
12963
|
FiCheckCircle,
|
|
12996
12964
|
FiLoader as FiLoader5,
|
|
12997
12965
|
FiX as FiX8,
|
|
12998
|
-
|
|
12999
|
-
FiCheckSquare as
|
|
13000
|
-
|
|
13001
|
-
FiGitBranch as FiGitBranch3
|
|
12966
|
+
FiBox as FiBox2,
|
|
12967
|
+
FiCheckSquare as FiCheckSquare4,
|
|
12968
|
+
FiGitBranch as FiGitBranch4
|
|
13002
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
|
|
13003
13306
|
var GroupItem = ({
|
|
13004
13307
|
group,
|
|
13005
13308
|
index,
|
|
13006
|
-
siblings,
|
|
13007
13309
|
onUpdate,
|
|
13008
13310
|
onDelete,
|
|
13009
13311
|
onAddSubgroup,
|
|
13010
13312
|
onIndent,
|
|
13011
13313
|
onOutdent,
|
|
13012
|
-
|
|
13013
|
-
|
|
13014
|
-
pickingGroupId,
|
|
13015
|
-
onPlayAncestry,
|
|
13016
|
-
availableIds,
|
|
13314
|
+
searchItems,
|
|
13315
|
+
onMentionClick,
|
|
13017
13316
|
canEdit
|
|
13018
13317
|
}) => {
|
|
13019
13318
|
const canIndent = index > 0;
|
|
13020
|
-
const
|
|
13021
|
-
|
|
13022
|
-
const adjustHeight = () => {
|
|
13023
|
-
const textarea = textareaRef.current;
|
|
13024
|
-
if (textarea) {
|
|
13025
|
-
textarea.style.height = "auto";
|
|
13026
|
-
textarea.style.height = `${textarea.scrollHeight}px`;
|
|
13027
|
-
}
|
|
13319
|
+
const handleContentChange = (content) => {
|
|
13320
|
+
onUpdate(group.id, { ...group, content });
|
|
13028
13321
|
};
|
|
13029
|
-
|
|
13030
|
-
|
|
13031
|
-
}, [group.text]);
|
|
13032
|
-
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(
|
|
13033
|
-
"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,
|
|
13034
13324
|
{
|
|
13035
|
-
|
|
13036
|
-
|
|
13037
|
-
|
|
13038
|
-
|
|
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"
|
|
13039
13338
|
},
|
|
13040
|
-
/* @__PURE__ */
|
|
13041
|
-
|
|
13042
|
-
|
|
13043
|
-
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
|
|
13047
|
-
|
|
13048
|
-
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
13052
|
-
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
13057
|
-
)
|
|
13058
|
-
|
|
13059
|
-
|
|
13060
|
-
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
|
|
13064
|
-
|
|
13065
|
-
|
|
13066
|
-
|
|
13067
|
-
} else if (anc.type === "version") {
|
|
13068
|
-
Icon = FiGitBranch3;
|
|
13069
|
-
colorClass = "text-purple-400";
|
|
13070
|
-
} else if (anc.type === "node") {
|
|
13071
|
-
Icon = FiBox;
|
|
13072
|
-
colorClass = "text-emerald-400";
|
|
13073
|
-
}
|
|
13074
|
-
return /* @__PURE__ */ React26.createElement(
|
|
13075
|
-
"div",
|
|
13076
|
-
{
|
|
13077
|
-
key: `${anc.type || "ancestry"}-${itemId}`,
|
|
13078
|
-
className: `
|
|
13079
|
-
flex items-center gap-2 rounded-md px-3 py-1.5 text-xs transition-all group/card border
|
|
13080
|
-
${isValid ? "bg-slate-800/60 border-white/10 hover:border-indigo-500/30 text-slate-200" : "bg-red-900/10 border-red-500/30 text-red-300/70 hover:bg-red-900/20"}
|
|
13081
|
-
`,
|
|
13082
|
-
title: isValid ? "" : "Esta informa\xE7\xE3o n\xE3o est\xE1 mais dispon\xEDvel neste contexto."
|
|
13083
|
-
},
|
|
13084
|
-
isValid ? /* @__PURE__ */ React26.createElement(
|
|
13085
|
-
"button",
|
|
13086
|
-
{
|
|
13087
|
-
onClick: () => onPlayAncestry(anc),
|
|
13088
|
-
className: `${colorClass} hover:text-white hover:bg-current/20 p-1 rounded transition-colors flex items-center justify-center`,
|
|
13089
|
-
title: "Focar no cen\xE1rio"
|
|
13090
|
-
},
|
|
13091
|
-
/* @__PURE__ */ React26.createElement(Icon, { size: 12 }),
|
|
13092
|
-
/* @__PURE__ */ React26.createElement(
|
|
13093
|
-
FiPlay,
|
|
13094
|
-
{
|
|
13095
|
-
size: 8,
|
|
13096
|
-
className: "ml-0.5 fill-current opacity-0 group-hover/card:opacity-100 transition-opacity"
|
|
13097
|
-
}
|
|
13098
|
-
)
|
|
13099
|
-
) : /* @__PURE__ */ React26.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ React26.createElement(FiAlertTriangle, { size: 10 })),
|
|
13100
|
-
/* @__PURE__ */ React26.createElement(
|
|
13101
|
-
"span",
|
|
13102
|
-
{
|
|
13103
|
-
className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}`
|
|
13104
|
-
},
|
|
13105
|
-
anc.name
|
|
13106
|
-
),
|
|
13107
|
-
canEdit && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(
|
|
13108
|
-
"div",
|
|
13109
|
-
{
|
|
13110
|
-
className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}`
|
|
13111
|
-
}
|
|
13112
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13113
|
-
"button",
|
|
13114
|
-
{
|
|
13115
|
-
onClick: () => onRemoveAncestry(group.id, itemId),
|
|
13116
|
-
className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
|
|
13117
|
-
title: "Remover men\xE7\xE3o"
|
|
13118
|
-
},
|
|
13119
|
-
/* @__PURE__ */ React26.createElement(FiX8, { size: 12 })
|
|
13120
|
-
))
|
|
13121
|
-
);
|
|
13122
|
-
})),
|
|
13123
|
-
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(
|
|
13124
|
-
"button",
|
|
13125
|
-
{
|
|
13126
|
-
onClick: () => onRequestPickAncestry(group.id),
|
|
13127
|
-
className: `
|
|
13128
|
-
flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium transition-colors
|
|
13129
|
-
${isPickingForThisGroup ? "text-indigo-300 animate-pulse" : "text-slate-500 hover:text-indigo-300 hover:bg-indigo-500/10"}
|
|
13130
|
-
`,
|
|
13131
|
-
title: "Adicionar Men\xE7\xE3o a este grupo"
|
|
13132
|
-
},
|
|
13133
|
-
isPickingForThisGroup ? /* @__PURE__ */ React26.createElement(FiCheckCircle, { size: 12 }) : /* @__PURE__ */ React26.createElement(FiSearch8, { size: 12 }),
|
|
13134
|
-
isPickingForThisGroup ? "Selecionando..." : "Adicionar"
|
|
13135
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13136
|
-
"button",
|
|
13137
|
-
{
|
|
13138
|
-
onClick: () => onAddSubgroup(group.id),
|
|
13139
|
-
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
13140
|
-
title: "Criar Subgrupo"
|
|
13141
|
-
},
|
|
13142
|
-
/* @__PURE__ */ React26.createElement(FiPlus10, { size: 14 })
|
|
13143
|
-
)), /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React26.createElement(
|
|
13144
|
-
"button",
|
|
13145
|
-
{
|
|
13146
|
-
onClick: () => onIndent(group.id),
|
|
13147
|
-
disabled: !canIndent,
|
|
13148
|
-
className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
|
|
13149
|
-
title: "Aninhar no grupo acima"
|
|
13150
|
-
},
|
|
13151
|
-
/* @__PURE__ */ React26.createElement(FiArrowRight2, { size: 14 })
|
|
13152
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13153
|
-
"button",
|
|
13154
|
-
{
|
|
13155
|
-
onClick: () => onOutdent(group.id),
|
|
13156
|
-
className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
13157
|
-
title: "Desaninhar"
|
|
13158
|
-
},
|
|
13159
|
-
/* @__PURE__ */ React26.createElement(FiArrowLeft3, { size: 14 })
|
|
13160
|
-
), /* @__PURE__ */ React26.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ React26.createElement(
|
|
13161
|
-
"button",
|
|
13162
|
-
{
|
|
13163
|
-
onClick: () => onDelete(group.id),
|
|
13164
|
-
className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
|
|
13165
|
-
title: "Remover Grupo"
|
|
13166
|
-
},
|
|
13167
|
-
/* @__PURE__ */ React26.createElement(FiTrash23, { size: 14 })
|
|
13168
|
-
)))
|
|
13169
|
-
), 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(
|
|
13170
13366
|
GroupItem,
|
|
13171
13367
|
{
|
|
13172
|
-
key:
|
|
13368
|
+
key: child.id,
|
|
13173
13369
|
index: idx,
|
|
13174
|
-
group:
|
|
13175
|
-
siblings: group.children,
|
|
13370
|
+
group: child,
|
|
13176
13371
|
onUpdate,
|
|
13177
13372
|
onDelete,
|
|
13178
13373
|
onAddSubgroup,
|
|
13179
13374
|
onIndent,
|
|
13180
13375
|
onOutdent,
|
|
13181
|
-
|
|
13182
|
-
|
|
13183
|
-
pickingGroupId,
|
|
13184
|
-
onPlayAncestry,
|
|
13185
|
-
availableIds,
|
|
13376
|
+
searchItems,
|
|
13377
|
+
onMentionClick,
|
|
13186
13378
|
canEdit
|
|
13187
13379
|
}
|
|
13188
13380
|
))));
|
|
@@ -13197,168 +13389,104 @@ function AncestryBoard({
|
|
|
13197
13389
|
onSave,
|
|
13198
13390
|
userRole
|
|
13199
13391
|
}) {
|
|
13200
|
-
const [
|
|
13201
|
-
const [
|
|
13202
|
-
const [
|
|
13203
|
-
const
|
|
13204
|
-
|
|
13205
|
-
const canEdit = useMemo11(() => {
|
|
13206
|
-
return userRole !== "viewer";
|
|
13207
|
-
}, [userRole]);
|
|
13208
|
-
useEffect21(() => {
|
|
13392
|
+
const [groups, setGroups] = useState27([]);
|
|
13393
|
+
const [isLoaded, setIsLoaded] = useState27(false);
|
|
13394
|
+
const [saveStatus, setSaveStatus] = useState27("idle");
|
|
13395
|
+
const canEdit = useMemo12(() => userRole !== "viewer", [userRole]);
|
|
13396
|
+
useEffect23(() => {
|
|
13209
13397
|
if (initialGroups && !isLoaded) {
|
|
13210
|
-
|
|
13398
|
+
const migrate = (list) => list.map((g) => ({
|
|
13399
|
+
id: g.id || uuidv411(),
|
|
13400
|
+
content: Array.isArray(g.content) ? g.content : [],
|
|
13401
|
+
// descarta dados legados
|
|
13402
|
+
children: migrate(g.children || [])
|
|
13403
|
+
}));
|
|
13404
|
+
setGroups(migrate(initialGroups));
|
|
13211
13405
|
setIsLoaded(true);
|
|
13212
13406
|
}
|
|
13213
13407
|
}, [initialGroups, isLoaded]);
|
|
13214
|
-
const
|
|
13215
|
-
const
|
|
13216
|
-
|
|
13217
|
-
|
|
13218
|
-
|
|
13219
|
-
|
|
13220
|
-
|
|
13408
|
+
const allSearchableItems = useMemo12(() => {
|
|
13409
|
+
const items = [];
|
|
13410
|
+
availableAncestries.forEach((anc) => {
|
|
13411
|
+
items.push({
|
|
13412
|
+
...anc,
|
|
13413
|
+
id: String(anc.ancestry_id),
|
|
13414
|
+
type: "ancestry",
|
|
13415
|
+
searchLabel: anc.name || "",
|
|
13416
|
+
searchDesc: anc.description || ""
|
|
13221
13417
|
});
|
|
13222
|
-
}
|
|
13223
|
-
|
|
13224
|
-
|
|
13225
|
-
const availableIds = useMemo11(() => {
|
|
13226
|
-
return new Set(availableAncestries.map((a) => String(a.ancestry_id)));
|
|
13227
|
-
}, [availableAncestries]);
|
|
13228
|
-
const allMentionableItems = useMemo11(() => {
|
|
13229
|
-
const ancestries = availableAncestries.map((a) => ({
|
|
13230
|
-
id: String(a.ancestry_id),
|
|
13231
|
-
ancestry_id: a.ancestry_id,
|
|
13232
|
-
name: a.name,
|
|
13233
|
-
description: a.description,
|
|
13234
|
-
type: "ancestry",
|
|
13235
|
-
ancestral_node: a.ancestral_node,
|
|
13236
|
-
is_private: a.is_private
|
|
13237
|
-
}));
|
|
13238
|
-
const nodes = availableNodes.map((n) => {
|
|
13418
|
+
});
|
|
13419
|
+
availableNodes.forEach((node) => {
|
|
13420
|
+
var _a;
|
|
13239
13421
|
let type = "node";
|
|
13240
|
-
if (
|
|
13241
|
-
else if (
|
|
13242
|
-
|
|
13243
|
-
|
|
13244
|
-
|
|
13245
|
-
description: n.description,
|
|
13422
|
+
if (node.is_quest) type = "quest";
|
|
13423
|
+
else if ((_a = node.version_node) == null ? void 0 : _a.is_version) type = "version";
|
|
13424
|
+
items.push({
|
|
13425
|
+
...node,
|
|
13426
|
+
id: String(node.id),
|
|
13246
13427
|
type,
|
|
13247
|
-
|
|
13248
|
-
|
|
13428
|
+
searchLabel: node.name || node.raw_title || "",
|
|
13429
|
+
searchDesc: node.description || ""
|
|
13430
|
+
});
|
|
13249
13431
|
});
|
|
13250
|
-
return
|
|
13432
|
+
return items;
|
|
13251
13433
|
}, [availableAncestries, availableNodes]);
|
|
13252
|
-
const sanitizeGroups = (
|
|
13253
|
-
|
|
13254
|
-
|
|
13255
|
-
|
|
13256
|
-
|
|
13257
|
-
|
|
13258
|
-
ancestry_id: a.ancestry_id,
|
|
13259
|
-
name: a.name,
|
|
13260
|
-
type: a.type || "ancestry"
|
|
13261
|
-
})),
|
|
13262
|
-
children: sanitizeGroups(g.children || [])
|
|
13263
|
-
}));
|
|
13264
|
-
};
|
|
13265
|
-
useEffect21(() => {
|
|
13434
|
+
const sanitizeGroups = (list) => list.map((g) => ({
|
|
13435
|
+
id: g.id,
|
|
13436
|
+
content: g.content || [],
|
|
13437
|
+
children: sanitizeGroups(g.children || [])
|
|
13438
|
+
}));
|
|
13439
|
+
useEffect23(() => {
|
|
13266
13440
|
if (!isLoaded || !onSave) return;
|
|
13267
|
-
const
|
|
13441
|
+
const id = setTimeout(async () => {
|
|
13268
13442
|
setSaveStatus("saving");
|
|
13269
|
-
const cleanData = sanitizeGroups(groups);
|
|
13270
13443
|
try {
|
|
13271
|
-
await onSave(
|
|
13444
|
+
await onSave(sanitizeGroups(groups));
|
|
13272
13445
|
setSaveStatus("saved");
|
|
13273
|
-
setTimeout(() =>
|
|
13274
|
-
|
|
13275
|
-
|
|
13276
|
-
} catch (error) {
|
|
13277
|
-
console.error("Erro ao salvar board:", error);
|
|
13446
|
+
setTimeout(() => setSaveStatus("idle"), 3e3);
|
|
13447
|
+
} catch (err) {
|
|
13448
|
+
console.error("Erro ao salvar board:", err);
|
|
13278
13449
|
setSaveStatus("error");
|
|
13279
13450
|
}
|
|
13280
13451
|
}, 3e3);
|
|
13281
|
-
return () => clearTimeout(
|
|
13452
|
+
return () => clearTimeout(id);
|
|
13282
13453
|
}, [groups, isLoaded, onSave]);
|
|
13283
|
-
|
|
13454
|
+
useEffect23(() => {
|
|
13284
13455
|
if (!isOpen) return;
|
|
13285
|
-
const
|
|
13456
|
+
const handler = (e) => {
|
|
13286
13457
|
if (e.key === "Escape") {
|
|
13287
|
-
|
|
13288
|
-
setPickingGroupId(null);
|
|
13289
|
-
} else {
|
|
13290
|
-
onClose();
|
|
13291
|
-
}
|
|
13458
|
+
onClose();
|
|
13292
13459
|
e.preventDefault();
|
|
13293
13460
|
e.stopPropagation();
|
|
13294
13461
|
}
|
|
13295
13462
|
};
|
|
13296
|
-
window.addEventListener("keydown",
|
|
13297
|
-
return () => window.removeEventListener("keydown",
|
|
13298
|
-
}, [isOpen, onClose
|
|
13299
|
-
const filtered = useMemo11(() => {
|
|
13300
|
-
const term = searchTerm.toLowerCase().trim();
|
|
13301
|
-
return allMentionableItems.filter((item) => {
|
|
13302
|
-
if (!term) return true;
|
|
13303
|
-
const nameMatch = item.name && item.name.toLowerCase().includes(term);
|
|
13304
|
-
const descMatch = item.description && item.description.toLowerCase().includes(term);
|
|
13305
|
-
let parentMatch = false;
|
|
13306
|
-
if (item.type === "ancestry") {
|
|
13307
|
-
const parentName = nodeNamesMap.get(String(item.ancestral_node)) || "";
|
|
13308
|
-
parentMatch = parentName.toLowerCase().includes(term);
|
|
13309
|
-
}
|
|
13310
|
-
return nameMatch || descMatch || parentMatch;
|
|
13311
|
-
});
|
|
13312
|
-
}, [allMentionableItems, searchTerm, nodeNamesMap]);
|
|
13463
|
+
window.addEventListener("keydown", handler);
|
|
13464
|
+
return () => window.removeEventListener("keydown", handler);
|
|
13465
|
+
}, [isOpen, onClose]);
|
|
13313
13466
|
const handleAddRootGroup = () => {
|
|
13314
|
-
|
|
13315
|
-
id: v4_default(),
|
|
13316
|
-
text: "",
|
|
13317
|
-
ancestries: [],
|
|
13318
|
-
children: []
|
|
13319
|
-
};
|
|
13320
|
-
setGroups((prev) => [newGroup, ...prev]);
|
|
13467
|
+
setGroups((prev) => [{ id: uuidv411(), content: [], children: [] }, ...prev]);
|
|
13321
13468
|
};
|
|
13322
13469
|
const handleAddSubgroup = (parentId) => {
|
|
13323
|
-
const newGroup = {
|
|
13324
|
-
|
|
13325
|
-
|
|
13326
|
-
|
|
13327
|
-
|
|
13328
|
-
};
|
|
13329
|
-
const addRecursive = (list) => {
|
|
13330
|
-
return list.map((g) => {
|
|
13331
|
-
if (g.id === parentId) {
|
|
13332
|
-
return { ...g, children: [newGroup, ...g.children] };
|
|
13333
|
-
}
|
|
13334
|
-
return { ...g, children: addRecursive(g.children) };
|
|
13335
|
-
});
|
|
13336
|
-
};
|
|
13337
|
-
setGroups((prev) => addRecursive(prev));
|
|
13470
|
+
const newGroup = { id: uuidv411(), content: [], children: [] };
|
|
13471
|
+
const add = (list) => list.map(
|
|
13472
|
+
(g) => g.id === parentId ? { ...g, children: [newGroup, ...g.children] } : { ...g, children: add(g.children) }
|
|
13473
|
+
);
|
|
13474
|
+
setGroups((prev) => add(prev));
|
|
13338
13475
|
};
|
|
13339
13476
|
const handleUpdateGroup = (id, newData) => {
|
|
13340
|
-
const
|
|
13341
|
-
|
|
13342
|
-
|
|
13343
|
-
|
|
13344
|
-
});
|
|
13345
|
-
};
|
|
13346
|
-
setGroups((prev) => updateRecursive(prev));
|
|
13477
|
+
const update = (list) => list.map(
|
|
13478
|
+
(g) => g.id === id ? newData : { ...g, children: update(g.children) }
|
|
13479
|
+
);
|
|
13480
|
+
setGroups((prev) => update(prev));
|
|
13347
13481
|
};
|
|
13348
13482
|
const handleDeleteGroup = (id) => {
|
|
13349
|
-
const
|
|
13350
|
-
|
|
13351
|
-
...g,
|
|
13352
|
-
children: deleteRecursive(g.children)
|
|
13353
|
-
}));
|
|
13354
|
-
};
|
|
13355
|
-
setGroups((prev) => deleteRecursive(prev));
|
|
13483
|
+
const del = (list) => list.filter((g) => g.id !== id).map((g) => ({ ...g, children: del(g.children) }));
|
|
13484
|
+
setGroups((prev) => del(prev));
|
|
13356
13485
|
};
|
|
13357
13486
|
const findGroupAndParent = (list, targetId, parent = null) => {
|
|
13358
13487
|
for (let i = 0; i < list.length; i++) {
|
|
13359
|
-
if (list[i].id === targetId)
|
|
13488
|
+
if (list[i].id === targetId)
|
|
13360
13489
|
return { group: list[i], parent, index: i, siblings: list };
|
|
13361
|
-
}
|
|
13362
13490
|
if (list[i].children.length > 0) {
|
|
13363
13491
|
const found = findGroupAndParent(list[i].children, targetId, list[i]);
|
|
13364
13492
|
if (found) return found;
|
|
@@ -13368,257 +13496,86 @@ function AncestryBoard({
|
|
|
13368
13496
|
};
|
|
13369
13497
|
const handleIndent = (id) => {
|
|
13370
13498
|
setGroups((prev) => {
|
|
13371
|
-
const
|
|
13372
|
-
const found = findGroupAndParent(
|
|
13499
|
+
const next = JSON.parse(JSON.stringify(prev));
|
|
13500
|
+
const found = findGroupAndParent(next, id);
|
|
13373
13501
|
if (!found || found.index === 0) return prev;
|
|
13374
13502
|
const { group, siblings, index } = found;
|
|
13375
|
-
const prevSibling = siblings[index - 1];
|
|
13376
13503
|
siblings.splice(index, 1);
|
|
13377
|
-
|
|
13378
|
-
return
|
|
13504
|
+
siblings[index - 1].children.push(group);
|
|
13505
|
+
return next;
|
|
13379
13506
|
});
|
|
13380
13507
|
};
|
|
13381
13508
|
const handleOutdent = (id) => {
|
|
13382
13509
|
setGroups((prev) => {
|
|
13383
|
-
const
|
|
13384
|
-
const found = findGroupAndParent(
|
|
13510
|
+
const next = JSON.parse(JSON.stringify(prev));
|
|
13511
|
+
const found = findGroupAndParent(next, id);
|
|
13385
13512
|
if (!found || !found.parent) return prev;
|
|
13386
13513
|
const { group, siblings, index, parent } = found;
|
|
13387
13514
|
siblings.splice(index, 1);
|
|
13388
|
-
const parentFound = findGroupAndParent(
|
|
13515
|
+
const parentFound = findGroupAndParent(next, parent.id);
|
|
13389
13516
|
if (parentFound) {
|
|
13390
13517
|
parentFound.siblings.splice(parentFound.index + 1, 0, group);
|
|
13391
13518
|
} else {
|
|
13392
|
-
|
|
13519
|
+
next.push(group);
|
|
13393
13520
|
}
|
|
13394
|
-
return
|
|
13521
|
+
return next;
|
|
13395
13522
|
});
|
|
13396
13523
|
};
|
|
13397
|
-
const
|
|
13398
|
-
|
|
13399
|
-
};
|
|
13400
|
-
const handleSelectAncestry = (item) => {
|
|
13401
|
-
if (pickingGroupId) {
|
|
13402
|
-
setGroups((prev) => {
|
|
13403
|
-
const addRecursive = (list) => {
|
|
13404
|
-
return list.map((g) => {
|
|
13405
|
-
if (g.id === pickingGroupId) {
|
|
13406
|
-
const currentId = item.id;
|
|
13407
|
-
const exists = g.ancestries.some(
|
|
13408
|
-
(a) => (a.id || a.ancestry_id) === currentId && a.type === item.type
|
|
13409
|
-
);
|
|
13410
|
-
if (exists) return g;
|
|
13411
|
-
return { ...g, ancestries: [...g.ancestries, item] };
|
|
13412
|
-
}
|
|
13413
|
-
return { ...g, children: addRecursive(g.children) };
|
|
13414
|
-
});
|
|
13415
|
-
};
|
|
13416
|
-
return addRecursive(prev);
|
|
13417
|
-
});
|
|
13418
|
-
setPickingGroupId(null);
|
|
13419
|
-
} else {
|
|
13420
|
-
let fullItem = item;
|
|
13421
|
-
if (item.type === "ancestry" || !item.type) {
|
|
13422
|
-
fullItem = availableAncestries.find(
|
|
13423
|
-
(a) => String(a.ancestry_id) === String(item.id || item.ancestry_id)
|
|
13424
|
-
) || item;
|
|
13425
|
-
} else {
|
|
13426
|
-
fullItem = availableNodes.find(
|
|
13427
|
-
(n) => String(n.id) === String(item.id)
|
|
13428
|
-
) || item;
|
|
13429
|
-
}
|
|
13430
|
-
onSelect(fullItem);
|
|
13431
|
-
}
|
|
13432
|
-
};
|
|
13433
|
-
const handlePlayFromGroup = (item) => {
|
|
13434
|
-
let fullItem = item;
|
|
13435
|
-
if (item.type === "ancestry" || !item.type) {
|
|
13436
|
-
fullItem = availableAncestries.find(
|
|
13437
|
-
(a) => String(a.ancestry_id) === String(item.id || item.ancestry_id)
|
|
13438
|
-
) || item;
|
|
13439
|
-
} else {
|
|
13440
|
-
fullItem = availableNodes.find(
|
|
13441
|
-
(n) => String(n.id) === String(item.id)
|
|
13442
|
-
) || item;
|
|
13443
|
-
}
|
|
13444
|
-
if (fullItem && onSelect) {
|
|
13445
|
-
onSelect(fullItem);
|
|
13446
|
-
}
|
|
13447
|
-
};
|
|
13448
|
-
const handleRemoveAncestryFromGroup = (groupId, itemId) => {
|
|
13449
|
-
setGroups((prev) => {
|
|
13450
|
-
const removeRecursive = (list) => {
|
|
13451
|
-
return list.map((g) => {
|
|
13452
|
-
if (g.id === groupId) {
|
|
13453
|
-
return {
|
|
13454
|
-
...g,
|
|
13455
|
-
ancestries: g.ancestries.filter(
|
|
13456
|
-
(a) => (a.id || a.ancestry_id) !== itemId
|
|
13457
|
-
)
|
|
13458
|
-
};
|
|
13459
|
-
}
|
|
13460
|
-
return { ...g, children: removeRecursive(g.children) };
|
|
13461
|
-
});
|
|
13462
|
-
};
|
|
13463
|
-
return removeRecursive(prev);
|
|
13464
|
-
});
|
|
13524
|
+
const handleMentionClick = (item) => {
|
|
13525
|
+
if (onSelect) onSelect(item);
|
|
13465
13526
|
};
|
|
13466
13527
|
if (!isOpen) return null;
|
|
13467
|
-
return /* @__PURE__ */
|
|
13528
|
+
return /* @__PURE__ */ React28.createElement(
|
|
13468
13529
|
"div",
|
|
13469
13530
|
{
|
|
13470
13531
|
className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
|
|
13471
13532
|
onClick: onClose
|
|
13472
13533
|
},
|
|
13473
|
-
/* @__PURE__ */
|
|
13534
|
+
/* @__PURE__ */ React28.createElement(
|
|
13474
13535
|
"div",
|
|
13475
13536
|
{
|
|
13476
13537
|
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",
|
|
13477
13538
|
onClick: (e) => e.stopPropagation()
|
|
13478
13539
|
},
|
|
13479
|
-
/* @__PURE__ */
|
|
13480
|
-
FiLoader5,
|
|
13481
|
-
{
|
|
13482
|
-
className: "animate-spin text-indigo-400",
|
|
13483
|
-
size: 12
|
|
13484
|
-
}
|
|
13485
|
-
), /* @__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(
|
|
13540
|
+
/* @__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(
|
|
13486
13541
|
"button",
|
|
13487
13542
|
{
|
|
13488
13543
|
onClick: handleAddRootGroup,
|
|
13489
|
-
className: "
|
|
13544
|
+
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"
|
|
13490
13545
|
},
|
|
13491
|
-
/* @__PURE__ */
|
|
13492
|
-
/* @__PURE__ */
|
|
13493
|
-
), /* @__PURE__ */
|
|
13546
|
+
/* @__PURE__ */ React28.createElement(FiPlus10, { size: 14, className: "text-indigo-400" }),
|
|
13547
|
+
/* @__PURE__ */ React28.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
|
|
13548
|
+
), /* @__PURE__ */ React28.createElement(
|
|
13494
13549
|
"button",
|
|
13495
13550
|
{
|
|
13496
13551
|
onClick: onClose,
|
|
13497
13552
|
className: "w-8 h-8 rounded-lg flex items-center justify-center text-slate-400 hover:text-white hover:bg-white/10 transition-colors"
|
|
13498
13553
|
},
|
|
13499
|
-
|
|
13554
|
+
/* @__PURE__ */ React28.createElement(FiX8, { size: 16 })
|
|
13500
13555
|
))),
|
|
13501
|
-
/* @__PURE__ */
|
|
13502
|
-
"div",
|
|
13503
|
-
{
|
|
13504
|
-
className: `
|
|
13505
|
-
flex flex-col border-r border-white/10 transition-all duration-300 flex-none
|
|
13506
|
-
${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
|
|
13507
|
-
min-w-[280px] max-w-[500px] bg-slate-900
|
|
13508
|
-
`
|
|
13509
|
-
},
|
|
13510
|
-
/* @__PURE__ */ React26.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ React26.createElement("div", { className: "relative group" }, /* @__PURE__ */ React26.createElement(
|
|
13511
|
-
FiSearch8,
|
|
13512
|
-
{
|
|
13513
|
-
className: `absolute left-3 top-1/2 -translate-y-1/2 transition-colors ${pickingGroupId ? "text-indigo-400" : "text-slate-500 group-focus-within:text-indigo-400"}`
|
|
13514
|
-
}
|
|
13515
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13516
|
-
"input",
|
|
13517
|
-
{
|
|
13518
|
-
type: "text",
|
|
13519
|
-
placeholder: pickingGroupId ? "Pesquise para adicionar..." : "Pesquisar (Ancestralidades e Nodes)",
|
|
13520
|
-
className: `
|
|
13521
|
-
w-full rounded-md pl-9 pr-4 py-2 text-sm transition-all focus:outline-none focus:ring-1 focus:ring-indigo-500 border
|
|
13522
|
-
${pickingGroupId ? "bg-indigo-950/30 border-indigo-500/30 text-white placeholder-indigo-300/50" : "bg-slate-950 border-white/10 text-slate-200 placeholder-slate-600"}
|
|
13523
|
-
`,
|
|
13524
|
-
value: searchTerm,
|
|
13525
|
-
onChange: (e) => setSearchTerm(e.target.value),
|
|
13526
|
-
autoFocus: !pickingGroupId
|
|
13527
|
-
}
|
|
13528
|
-
))),
|
|
13529
|
-
/* @__PURE__ */ React26.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((item) => {
|
|
13530
|
-
const isPicking = !!pickingGroupId;
|
|
13531
|
-
const isQuest = item.type === "quest";
|
|
13532
|
-
const isVersion = item.type === "version";
|
|
13533
|
-
const isNode = item.type === "node";
|
|
13534
|
-
let Icon = FiLayers6;
|
|
13535
|
-
let colorClass = "bg-slate-800 text-indigo-400 border-white/5";
|
|
13536
|
-
let pickingColorClass = "bg-indigo-500 text-white border-indigo-400";
|
|
13537
|
-
let hoverClass = "hover:bg-indigo-600/10 hover:border-indigo-500/30";
|
|
13538
|
-
let badge = null;
|
|
13539
|
-
if (isQuest) {
|
|
13540
|
-
Icon = FiCheckSquare3;
|
|
13541
|
-
colorClass = "bg-slate-800 text-amber-400 border-white/5";
|
|
13542
|
-
pickingColorClass = "bg-amber-500 text-white border-amber-400";
|
|
13543
|
-
hoverClass = "hover:bg-amber-500/10 hover:border-amber-500/30";
|
|
13544
|
-
badge = "Quest";
|
|
13545
|
-
} else if (isVersion) {
|
|
13546
|
-
Icon = FiGitBranch3;
|
|
13547
|
-
colorClass = "bg-slate-800 text-purple-400 border-white/5";
|
|
13548
|
-
pickingColorClass = "bg-purple-500 text-white border-purple-400";
|
|
13549
|
-
hoverClass = "hover:bg-purple-500/10 hover:border-purple-500/30";
|
|
13550
|
-
badge = "Ver";
|
|
13551
|
-
} else if (isNode) {
|
|
13552
|
-
Icon = FiBox;
|
|
13553
|
-
colorClass = "bg-slate-800 text-emerald-400 border-white/5";
|
|
13554
|
-
pickingColorClass = "bg-emerald-500 text-white border-emerald-400";
|
|
13555
|
-
hoverClass = "hover:bg-emerald-500/10 hover:border-emerald-500/30";
|
|
13556
|
-
badge = "Node";
|
|
13557
|
-
}
|
|
13558
|
-
return /* @__PURE__ */ React26.createElement(
|
|
13559
|
-
"div",
|
|
13560
|
-
{
|
|
13561
|
-
key: `${item.type}-${item.id}`,
|
|
13562
|
-
onClick: () => {
|
|
13563
|
-
if (isPicking) handleSelectAncestry(item);
|
|
13564
|
-
},
|
|
13565
|
-
className: `
|
|
13566
|
-
group relative flex items-start gap-3 p-3 text-left rounded-lg border transition-all duration-200
|
|
13567
|
-
${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 ${hoverClass} cursor-default`}
|
|
13568
|
-
`
|
|
13569
|
-
},
|
|
13570
|
-
/* @__PURE__ */ React26.createElement(
|
|
13571
|
-
"div",
|
|
13572
|
-
{
|
|
13573
|
-
className: `
|
|
13574
|
-
mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
|
|
13575
|
-
${isPicking ? pickingColorClass : `${colorClass} group-hover:bg-opacity-80`}
|
|
13576
|
-
`
|
|
13577
|
-
},
|
|
13578
|
-
isPicking ? /* @__PURE__ */ React26.createElement(FiPlus10, { size: 16 }) : /* @__PURE__ */ React26.createElement(Icon, { size: 14 })
|
|
13579
|
-
),
|
|
13580
|
-
/* @__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" }, item.name || "Sem Nome"), badge && /* @__PURE__ */ React26.createElement("span", { className: `text-[9px] px-1 py-0.5 rounded ${isQuest ? "bg-amber-500/10 text-amber-400" : isVersion ? "bg-purple-500/10 text-purple-400" : "bg-emerald-500/10 text-emerald-400"} border border-current opacity-50` }, badge), item.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")), item.type === "ancestry" && /* @__PURE__ */ React26.createElement("div", { className: "flex items-center gap-1.5 mt-0.5 text-[11px] text-slate-500 group-hover:text-indigo-200/70 transition-colors" }, /* @__PURE__ */ React26.createElement(FiCornerUpRight4, { size: 10 }), /* @__PURE__ */ React26.createElement("span", { className: "truncate max-w-[120px]" }, nodeNamesMap.get(String(item.ancestral_node)) || "Node Desconhecido")), item.description && /* @__PURE__ */ React26.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, item.description)),
|
|
13581
|
-
!isPicking && /* @__PURE__ */ React26.createElement(
|
|
13582
|
-
"button",
|
|
13583
|
-
{
|
|
13584
|
-
onClick: (e) => {
|
|
13585
|
-
e.stopPropagation();
|
|
13586
|
-
handleSelectAncestry(item);
|
|
13587
|
-
},
|
|
13588
|
-
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",
|
|
13589
|
-
title: "Renderizar / Focar"
|
|
13590
|
-
},
|
|
13591
|
-
/* @__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" }))
|
|
13592
|
-
)
|
|
13593
|
-
);
|
|
13594
|
-
}))
|
|
13595
|
-
), /* @__PURE__ */ React26.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ React26.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ React26.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-3 border-2 border-dashed border-white/5 rounded-xl m-4 bg-slate-900/20" }, /* @__PURE__ */ React26.createElement(FiLayers6, { size: 24, className: "opacity-20" }), /* @__PURE__ */ React26.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ React26.createElement(React26.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ React26.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ React26.createElement(React26.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ React26.createElement(
|
|
13556
|
+
/* @__PURE__ */ React28.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar bg-slate-950/30 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(
|
|
13596
13557
|
GroupItem,
|
|
13597
13558
|
{
|
|
13598
13559
|
key: group.id,
|
|
13599
13560
|
index,
|
|
13600
13561
|
group,
|
|
13601
|
-
siblings: groups,
|
|
13602
13562
|
onUpdate: handleUpdateGroup,
|
|
13603
13563
|
onDelete: handleDeleteGroup,
|
|
13604
13564
|
onAddSubgroup: handleAddSubgroup,
|
|
13605
13565
|
onIndent: handleIndent,
|
|
13606
13566
|
onOutdent: handleOutdent,
|
|
13607
|
-
|
|
13608
|
-
|
|
13609
|
-
pickingGroupId,
|
|
13610
|
-
onPlayAncestry: handlePlayFromGroup,
|
|
13611
|
-
availableIds,
|
|
13567
|
+
searchItems: allSearchableItems,
|
|
13568
|
+
onMentionClick: handleMentionClick,
|
|
13612
13569
|
canEdit
|
|
13613
13570
|
}
|
|
13614
|
-
)))
|
|
13615
|
-
/* @__PURE__ */
|
|
13571
|
+
))),
|
|
13572
|
+
/* @__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-end flex-shrink-0" }, /* @__PURE__ */ React28.createElement("span", null, groups.length, " grupos raiz"))
|
|
13616
13573
|
)
|
|
13617
13574
|
);
|
|
13618
13575
|
}
|
|
13619
13576
|
|
|
13620
13577
|
// src/components/MilestoneManager.jsx
|
|
13621
|
-
import
|
|
13578
|
+
import React29, { useState as useState28 } from "react";
|
|
13622
13579
|
import { FiTarget as FiTarget4, FiPlus as FiPlus11, FiTrash2 as FiTrash24, FiX as FiX9, FiCheck as FiCheck12, FiPauseCircle, FiPlayCircle } from "react-icons/fi";
|
|
13623
13580
|
function MilestoneManager({
|
|
13624
13581
|
isOpen,
|
|
@@ -13627,7 +13584,7 @@ function MilestoneManager({
|
|
|
13627
13584
|
onUpdateMilestones = () => {
|
|
13628
13585
|
}
|
|
13629
13586
|
}) {
|
|
13630
|
-
const [newMilestoneName, setNewMilestoneName] =
|
|
13587
|
+
const [newMilestoneName, setNewMilestoneName] = useState28("");
|
|
13631
13588
|
const handleAddMilestone = () => {
|
|
13632
13589
|
if (!newMilestoneName.trim()) return;
|
|
13633
13590
|
const newMilestone = {
|
|
@@ -13652,27 +13609,27 @@ function MilestoneManager({
|
|
|
13652
13609
|
};
|
|
13653
13610
|
if (!isOpen) return null;
|
|
13654
13611
|
const swallow = (e) => e.stopPropagation();
|
|
13655
|
-
return /* @__PURE__ */
|
|
13612
|
+
return /* @__PURE__ */ React29.createElement(
|
|
13656
13613
|
"div",
|
|
13657
13614
|
{
|
|
13658
13615
|
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",
|
|
13659
13616
|
onClick: onClose
|
|
13660
13617
|
},
|
|
13661
|
-
/* @__PURE__ */
|
|
13618
|
+
/* @__PURE__ */ React29.createElement(
|
|
13662
13619
|
"div",
|
|
13663
13620
|
{
|
|
13664
13621
|
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",
|
|
13665
13622
|
onClick: swallow
|
|
13666
13623
|
},
|
|
13667
|
-
/* @__PURE__ */
|
|
13624
|
+
/* @__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(
|
|
13668
13625
|
"button",
|
|
13669
13626
|
{
|
|
13670
13627
|
onClick: onClose,
|
|
13671
13628
|
className: "p-2 rounded-full hover:bg-white/10 text-slate-400 hover:text-white transition-colors"
|
|
13672
13629
|
},
|
|
13673
|
-
/* @__PURE__ */
|
|
13630
|
+
/* @__PURE__ */ React29.createElement(FiX9, { size: 20 })
|
|
13674
13631
|
)),
|
|
13675
|
-
/* @__PURE__ */
|
|
13632
|
+
/* @__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(
|
|
13676
13633
|
"input",
|
|
13677
13634
|
{
|
|
13678
13635
|
type: "text",
|
|
@@ -13682,47 +13639,47 @@ function MilestoneManager({
|
|
|
13682
13639
|
placeholder: "Adicionar novo milestone...",
|
|
13683
13640
|
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"
|
|
13684
13641
|
}
|
|
13685
|
-
), /* @__PURE__ */
|
|
13642
|
+
), /* @__PURE__ */ React29.createElement(
|
|
13686
13643
|
"button",
|
|
13687
13644
|
{
|
|
13688
13645
|
onClick: handleAddMilestone,
|
|
13689
13646
|
disabled: !newMilestoneName.trim(),
|
|
13690
13647
|
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"
|
|
13691
13648
|
},
|
|
13692
|
-
/* @__PURE__ */
|
|
13649
|
+
/* @__PURE__ */ React29.createElement(FiPlus11, { size: 18 }),
|
|
13693
13650
|
"Adicionar"
|
|
13694
13651
|
))),
|
|
13695
|
-
/* @__PURE__ */
|
|
13652
|
+
/* @__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(
|
|
13696
13653
|
"div",
|
|
13697
13654
|
{
|
|
13698
13655
|
key: ms.id,
|
|
13699
13656
|
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]"}`
|
|
13700
13657
|
},
|
|
13701
|
-
/* @__PURE__ */
|
|
13658
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ React29.createElement(
|
|
13702
13659
|
"div",
|
|
13703
13660
|
{
|
|
13704
13661
|
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"}`
|
|
13705
13662
|
}
|
|
13706
|
-
), /* @__PURE__ */
|
|
13707
|
-
/* @__PURE__ */
|
|
13663
|
+
), /* @__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"))),
|
|
13664
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React29.createElement(
|
|
13708
13665
|
"button",
|
|
13709
13666
|
{
|
|
13710
13667
|
onClick: () => handleToggleMilestoneStatus(ms.id),
|
|
13711
13668
|
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"}`,
|
|
13712
13669
|
title: ms.status === "active" ? "Inativar" : "Ativar"
|
|
13713
13670
|
},
|
|
13714
|
-
ms.status === "active" ? /* @__PURE__ */
|
|
13715
|
-
), /* @__PURE__ */
|
|
13671
|
+
ms.status === "active" ? /* @__PURE__ */ React29.createElement(FiPauseCircle, { size: 18 }) : /* @__PURE__ */ React29.createElement(FiPlayCircle, { size: 18 })
|
|
13672
|
+
), /* @__PURE__ */ React29.createElement(
|
|
13716
13673
|
"button",
|
|
13717
13674
|
{
|
|
13718
13675
|
onClick: () => handleRemoveMilestone(ms.id),
|
|
13719
13676
|
className: "p-2 rounded-lg hover:bg-red-500/20 text-slate-500 hover:text-red-400 transition-all",
|
|
13720
13677
|
title: "Remover"
|
|
13721
13678
|
},
|
|
13722
|
-
/* @__PURE__ */
|
|
13679
|
+
/* @__PURE__ */ React29.createElement(FiTrash24, { size: 18 })
|
|
13723
13680
|
))
|
|
13724
|
-
))) : /* @__PURE__ */
|
|
13725
|
-
/* @__PURE__ */
|
|
13681
|
+
))) : /* @__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."))),
|
|
13682
|
+
/* @__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))))
|
|
13726
13683
|
)
|
|
13727
13684
|
);
|
|
13728
13685
|
}
|
|
@@ -13808,13 +13765,13 @@ function XViewScene({
|
|
|
13808
13765
|
check_user_permission,
|
|
13809
13766
|
get_view_members
|
|
13810
13767
|
}) {
|
|
13811
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l
|
|
13768
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
13812
13769
|
const { data: session, status } = useSession();
|
|
13813
13770
|
const router = useRouter();
|
|
13814
13771
|
const searchParams = useSearchParams();
|
|
13815
13772
|
const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
|
|
13816
13773
|
const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
|
|
13817
|
-
const viewParams =
|
|
13774
|
+
const viewParams = useMemo13(() => {
|
|
13818
13775
|
if (encryptedConfig) {
|
|
13819
13776
|
const data = decryptData(encryptedConfig);
|
|
13820
13777
|
if (data) {
|
|
@@ -13823,7 +13780,7 @@ function XViewScene({
|
|
|
13823
13780
|
}
|
|
13824
13781
|
return null;
|
|
13825
13782
|
}, [encryptedConfig, session]);
|
|
13826
|
-
|
|
13783
|
+
useEffect24(() => {
|
|
13827
13784
|
async function verifyPermission() {
|
|
13828
13785
|
if (!viewParams || !session || !check_user_permission) return;
|
|
13829
13786
|
const { id, type, owner_id } = viewParams;
|
|
@@ -13860,65 +13817,65 @@ function XViewScene({
|
|
|
13860
13817
|
setIsLoading(false);
|
|
13861
13818
|
}
|
|
13862
13819
|
}, [viewParams, session, status, check_user_permission]);
|
|
13863
|
-
const sceneConfigId =
|
|
13864
|
-
const ownerId =
|
|
13865
|
-
const dbSaveUrl =
|
|
13820
|
+
const sceneConfigId = useMemo13(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
|
|
13821
|
+
const ownerId = useMemo13(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
|
|
13822
|
+
const dbSaveUrl = useMemo13(() => {
|
|
13866
13823
|
if (ownerId && sceneConfigId) {
|
|
13867
13824
|
return `x_view_dbs/${ownerId}/${sceneConfigId}`;
|
|
13868
13825
|
}
|
|
13869
13826
|
return null;
|
|
13870
13827
|
}, [ownerId, sceneConfigId]);
|
|
13871
|
-
const sceneSaveUrl =
|
|
13828
|
+
const sceneSaveUrl = useMemo13(() => {
|
|
13872
13829
|
if (ownerId && sceneConfigId) {
|
|
13873
13830
|
return `x_view_scenes/${ownerId}/${sceneConfigId}`;
|
|
13874
13831
|
}
|
|
13875
13832
|
return null;
|
|
13876
13833
|
}, [ownerId, sceneConfigId]);
|
|
13877
|
-
const ancestry_save_url =
|
|
13834
|
+
const ancestry_save_url = useMemo13(() => {
|
|
13878
13835
|
if (ownerId && sceneConfigId) {
|
|
13879
13836
|
return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
|
|
13880
13837
|
}
|
|
13881
13838
|
return null;
|
|
13882
13839
|
}, [ownerId, sceneConfigId]);
|
|
13883
|
-
const sceneDataRef =
|
|
13884
|
-
const parentDataRef =
|
|
13885
|
-
const ancestryDataRef =
|
|
13886
|
-
const [isLoading, setIsLoading] =
|
|
13887
|
-
const [permissionStatus, setPermissionStatus] =
|
|
13888
|
-
const [userPermissionRole, setUserPermissionRole] =
|
|
13889
|
-
const [viewMembers, setViewMembers] =
|
|
13890
|
-
const [isInitialized, setIsInitialized] =
|
|
13891
|
-
const [sceneVersion, setSceneVersion] =
|
|
13892
|
-
const [contextMenu, setContextMenu] =
|
|
13840
|
+
const sceneDataRef = useRef20(null);
|
|
13841
|
+
const parentDataRef = useRef20(null);
|
|
13842
|
+
const ancestryDataRef = useRef20(null);
|
|
13843
|
+
const [isLoading, setIsLoading] = useState29(true);
|
|
13844
|
+
const [permissionStatus, setPermissionStatus] = useState29("loading");
|
|
13845
|
+
const [userPermissionRole, setUserPermissionRole] = useState29(null);
|
|
13846
|
+
const [viewMembers, setViewMembers] = useState29([]);
|
|
13847
|
+
const [isInitialized, setIsInitialized] = useState29(false);
|
|
13848
|
+
const [sceneVersion, setSceneVersion] = useState29(0);
|
|
13849
|
+
const [contextMenu, setContextMenu] = useState29({
|
|
13893
13850
|
visible: false,
|
|
13894
13851
|
x: 0,
|
|
13895
13852
|
y: 0,
|
|
13896
13853
|
nodeData: null
|
|
13897
13854
|
});
|
|
13898
|
-
const [multiContextMenu, setMultiContextMenu] =
|
|
13855
|
+
const [multiContextMenu, setMultiContextMenu] = useState29({
|
|
13899
13856
|
visible: false,
|
|
13900
13857
|
x: 0,
|
|
13901
13858
|
y: 0,
|
|
13902
13859
|
nodeIds: null
|
|
13903
13860
|
});
|
|
13904
|
-
const [relationshipMenu, setRelationshipMenu] =
|
|
13861
|
+
const [relationshipMenu, setRelationshipMenu] = useState29({
|
|
13905
13862
|
visible: false,
|
|
13906
13863
|
x: 0,
|
|
13907
13864
|
y: 0,
|
|
13908
13865
|
linkObject: null
|
|
13909
13866
|
});
|
|
13910
|
-
const [creationMode, setCreationMode] =
|
|
13867
|
+
const [creationMode, setCreationMode] = useState29({
|
|
13911
13868
|
isActive: false,
|
|
13912
13869
|
sourceNodeData: null
|
|
13913
13870
|
});
|
|
13914
|
-
const [versionMode, setVersionMode] =
|
|
13871
|
+
const [versionMode, setVersionMode] = useState29({
|
|
13915
13872
|
isActive: false,
|
|
13916
13873
|
sourceNodeData: null
|
|
13917
13874
|
});
|
|
13918
|
-
const [questMode, setQuestMode] =
|
|
13919
|
-
const [hasFocusedInitial, setHasFocusedInitial] =
|
|
13920
|
-
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] =
|
|
13921
|
-
const [ancestryMode, setAncestryMode] =
|
|
13875
|
+
const [questMode, setQuestMode] = useState29({ isActive: false });
|
|
13876
|
+
const [hasFocusedInitial, setHasFocusedInitial] = useState29(false);
|
|
13877
|
+
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState29(false);
|
|
13878
|
+
const [ancestryMode, setAncestryMode] = useState29({
|
|
13922
13879
|
isActive: false,
|
|
13923
13880
|
tree: null,
|
|
13924
13881
|
selectedParentId: null,
|
|
@@ -13929,42 +13886,42 @@ function XViewScene({
|
|
|
13929
13886
|
ancestryDescriptionSections: [],
|
|
13930
13887
|
isAddingNodes: false
|
|
13931
13888
|
});
|
|
13932
|
-
const [readingMode, setReadingMode] =
|
|
13889
|
+
const [readingMode, setReadingMode] = useState29({
|
|
13933
13890
|
isActive: false,
|
|
13934
13891
|
ancestry: null,
|
|
13935
13892
|
branchStack: [],
|
|
13936
13893
|
autoAbstraction: false
|
|
13937
13894
|
});
|
|
13938
|
-
const [formPosition, setFormPosition] =
|
|
13895
|
+
const [formPosition, setFormPosition] = useState29({
|
|
13939
13896
|
left: 16,
|
|
13940
13897
|
top: 16,
|
|
13941
13898
|
opacity: 0
|
|
13942
13899
|
});
|
|
13943
|
-
const [detailsNode, setDetailsNode] =
|
|
13944
|
-
const [detailsLink, setDetailsLink] =
|
|
13945
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] =
|
|
13946
|
-
const [imageViewer, setImageViewer] =
|
|
13900
|
+
const [detailsNode, setDetailsNode] = useState29(null);
|
|
13901
|
+
const [detailsLink, setDetailsLink] = useState29(null);
|
|
13902
|
+
const [ancestryLinkDetails, setAncestryLinkDetails] = useState29(null);
|
|
13903
|
+
const [imageViewer, setImageViewer] = useState29({
|
|
13947
13904
|
visible: false,
|
|
13948
13905
|
images: [],
|
|
13949
13906
|
startIndex: 0
|
|
13950
13907
|
});
|
|
13951
|
-
const [editingAncestryRel, setEditingAncestryRel] =
|
|
13908
|
+
const [editingAncestryRel, setEditingAncestryRel] = useState29({
|
|
13952
13909
|
visible: false,
|
|
13953
13910
|
data: null,
|
|
13954
13911
|
path: null
|
|
13955
13912
|
});
|
|
13956
|
-
const [isImportModalOpen, setIsImportModalOpen] =
|
|
13957
|
-
const [importSuccessMessage, setImportSuccessMessage] =
|
|
13958
|
-
const [invalidTargetError, setInvalidTargetError] =
|
|
13959
|
-
const [highlightedNodeId, setHighlightedNodeId] =
|
|
13960
|
-
const [isAncestryBoardOpen, setIsAncestryBoardOpen] =
|
|
13961
|
-
const [ancestryBoardData, setAncestryBoardData] =
|
|
13962
|
-
const [isSidebarOpen, setIsSidebarOpen] =
|
|
13963
|
-
const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] =
|
|
13964
|
-
const mountRef =
|
|
13965
|
-
const tooltipRef =
|
|
13966
|
-
const formRef =
|
|
13967
|
-
const stateRef =
|
|
13913
|
+
const [isImportModalOpen, setIsImportModalOpen] = useState29(false);
|
|
13914
|
+
const [importSuccessMessage, setImportSuccessMessage] = useState29("");
|
|
13915
|
+
const [invalidTargetError, setInvalidTargetError] = useState29(null);
|
|
13916
|
+
const [highlightedNodeId, setHighlightedNodeId] = useState29(null);
|
|
13917
|
+
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState29(false);
|
|
13918
|
+
const [ancestryBoardData, setAncestryBoardData] = useState29([]);
|
|
13919
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState29(false);
|
|
13920
|
+
const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = useState29(false);
|
|
13921
|
+
const mountRef = useRef20(null);
|
|
13922
|
+
const tooltipRef = useRef20(null);
|
|
13923
|
+
const formRef = useRef20(null);
|
|
13924
|
+
const stateRef = useRef20({
|
|
13968
13925
|
readMode: {
|
|
13969
13926
|
currentMaxIndex: 0,
|
|
13970
13927
|
progressMap: {}
|
|
@@ -14028,10 +13985,10 @@ function XViewScene({
|
|
|
14028
13985
|
minWidth: 320,
|
|
14029
13986
|
maxWidth: maxReadPanelW
|
|
14030
13987
|
});
|
|
14031
|
-
|
|
13988
|
+
useEffect24(() => {
|
|
14032
13989
|
stateRef.current.ancestry = ancestryMode;
|
|
14033
13990
|
}, [ancestryMode]);
|
|
14034
|
-
|
|
13991
|
+
useEffect24(() => {
|
|
14035
13992
|
var _a2;
|
|
14036
13993
|
if (!isInitialized) return;
|
|
14037
13994
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -14054,10 +14011,10 @@ function XViewScene({
|
|
|
14054
14011
|
}
|
|
14055
14012
|
stateRef.current.nodeIdToParentFileMap = map;
|
|
14056
14013
|
}, [isInitialized, sceneVersion]);
|
|
14057
|
-
const handleNavigateBack =
|
|
14014
|
+
const handleNavigateBack = useCallback5(() => {
|
|
14058
14015
|
router.push("/dashboard/scenes");
|
|
14059
14016
|
}, [router]);
|
|
14060
|
-
const handleConfirmImport =
|
|
14017
|
+
const handleConfirmImport = useCallback5(
|
|
14061
14018
|
async (importPayload) => {
|
|
14062
14019
|
var _a2, _b2;
|
|
14063
14020
|
let files = [];
|
|
@@ -14185,7 +14142,7 @@ function XViewScene({
|
|
|
14185
14142
|
const handleOpenImageViewer = (images, startIndex) => {
|
|
14186
14143
|
setImageViewer({ visible: true, images, startIndex });
|
|
14187
14144
|
};
|
|
14188
|
-
const tweenToTarget =
|
|
14145
|
+
const tweenToTarget = useCallback5(
|
|
14189
14146
|
(target, zoomFactor = 1, forcedDirection = null) => {
|
|
14190
14147
|
const { camera, controls, tweenGroup } = stateRef.current;
|
|
14191
14148
|
if (!camera || !controls || !tweenGroup) return;
|
|
@@ -14211,7 +14168,7 @@ function XViewScene({
|
|
|
14211
14168
|
if (!t || typeof t.closest !== "function") return false;
|
|
14212
14169
|
return !!t.closest(".ui-overlay");
|
|
14213
14170
|
};
|
|
14214
|
-
const buildFullAncestryTree =
|
|
14171
|
+
const buildFullAncestryTree = useCallback5(
|
|
14215
14172
|
(idTree, nodes, ancestries = []) => {
|
|
14216
14173
|
if (!idTree) return null;
|
|
14217
14174
|
const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
|
|
@@ -14296,7 +14253,7 @@ function XViewScene({
|
|
|
14296
14253
|
},
|
|
14297
14254
|
[]
|
|
14298
14255
|
);
|
|
14299
|
-
const handleActivateTimeline =
|
|
14256
|
+
const handleActivateTimeline = useCallback5(() => {
|
|
14300
14257
|
const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
14301
14258
|
if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
|
|
14302
14259
|
while (timelineIntervalsGroup.children.length > 0) {
|
|
@@ -14456,7 +14413,7 @@ function XViewScene({
|
|
|
14456
14413
|
}
|
|
14457
14414
|
});
|
|
14458
14415
|
}, []);
|
|
14459
|
-
const handleVersionTimeline =
|
|
14416
|
+
const handleVersionTimeline = useCallback5((sourceMesh, versionMeshes) => {
|
|
14460
14417
|
const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
14461
14418
|
if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0)
|
|
14462
14419
|
return;
|
|
@@ -14593,7 +14550,7 @@ function XViewScene({
|
|
|
14593
14550
|
}
|
|
14594
14551
|
});
|
|
14595
14552
|
}, []);
|
|
14596
|
-
|
|
14553
|
+
useEffect24(() => {
|
|
14597
14554
|
async function fetchAllData(configPath, ownerId2) {
|
|
14598
14555
|
var _a2, _b2;
|
|
14599
14556
|
if (!get_scene_view_data) {
|
|
@@ -14698,12 +14655,12 @@ function XViewScene({
|
|
|
14698
14655
|
focusNodeId,
|
|
14699
14656
|
focusAncestryId
|
|
14700
14657
|
]);
|
|
14701
|
-
const isNodeInView =
|
|
14658
|
+
const isNodeInView = useCallback5((id) => {
|
|
14702
14659
|
const key = String(id);
|
|
14703
14660
|
const objs = stateRef.current.nodeObjects || {};
|
|
14704
14661
|
return !!objs[key];
|
|
14705
14662
|
}, []);
|
|
14706
|
-
const addOrUpdateNodeMesh =
|
|
14663
|
+
const addOrUpdateNodeMesh = useCallback5(
|
|
14707
14664
|
(nodeData, position, suppressVersionUpdate = false, forceShowQuestDate = false) => {
|
|
14708
14665
|
const {
|
|
14709
14666
|
graphGroup,
|
|
@@ -14744,7 +14701,7 @@ function XViewScene({
|
|
|
14744
14701
|
},
|
|
14745
14702
|
[]
|
|
14746
14703
|
);
|
|
14747
|
-
const handleActivateQuestLens =
|
|
14704
|
+
const handleActivateQuestLens = useCallback5(({ assigneeId, status: status2, milestoneId }) => {
|
|
14748
14705
|
var _a2;
|
|
14749
14706
|
const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
|
|
14750
14707
|
if (!nodeObjects || !tweenGroup || !graphGroup) return;
|
|
@@ -14958,7 +14915,7 @@ function XViewScene({
|
|
|
14958
14915
|
camTween.start();
|
|
14959
14916
|
}
|
|
14960
14917
|
}, [addOrUpdateNodeMesh]);
|
|
14961
|
-
|
|
14918
|
+
useEffect24(() => {
|
|
14962
14919
|
if (!isInitialized || !sceneDataRef.current) return;
|
|
14963
14920
|
const currentMount = mountRef.current;
|
|
14964
14921
|
if (!currentMount) return;
|
|
@@ -15714,7 +15671,7 @@ function XViewScene({
|
|
|
15714
15671
|
get_scene_view_data,
|
|
15715
15672
|
save_view_data
|
|
15716
15673
|
]);
|
|
15717
|
-
const handleGhostNodeImageChange =
|
|
15674
|
+
const handleGhostNodeImageChange = useCallback5((useImage, imageUrl) => {
|
|
15718
15675
|
const {
|
|
15719
15676
|
node: ghostNode,
|
|
15720
15677
|
line: ghostLine,
|
|
@@ -15762,7 +15719,7 @@ function XViewScene({
|
|
|
15762
15719
|
aura: newGhostNode.getObjectByName("aura")
|
|
15763
15720
|
};
|
|
15764
15721
|
}, []);
|
|
15765
|
-
const handleGhostNodeIntensityChange =
|
|
15722
|
+
const handleGhostNodeIntensityChange = useCallback5((newIntensity) => {
|
|
15766
15723
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
15767
15724
|
if (!ghostNode) return;
|
|
15768
15725
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -15783,7 +15740,7 @@ function XViewScene({
|
|
|
15783
15740
|
ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
|
|
15784
15741
|
}
|
|
15785
15742
|
}, []);
|
|
15786
|
-
const handleDetailNodeIntensityChange =
|
|
15743
|
+
const handleDetailNodeIntensityChange = useCallback5(
|
|
15787
15744
|
(nodeId, newIntensity) => {
|
|
15788
15745
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
15789
15746
|
if (!mesh) return;
|
|
@@ -15939,7 +15896,7 @@ function XViewScene({
|
|
|
15939
15896
|
mountRef.current.style.cursor = "default";
|
|
15940
15897
|
}
|
|
15941
15898
|
};
|
|
15942
|
-
const handleAncestryTreeUpdate =
|
|
15899
|
+
const handleAncestryTreeUpdate = useCallback5((newTree, extraData = null) => {
|
|
15943
15900
|
setAncestryMode((prev) => {
|
|
15944
15901
|
const prevTreeStr = JSON.stringify(prev.tree);
|
|
15945
15902
|
const newTreeStr = JSON.stringify(newTree);
|
|
@@ -15962,7 +15919,7 @@ function XViewScene({
|
|
|
15962
15919
|
};
|
|
15963
15920
|
});
|
|
15964
15921
|
}, []);
|
|
15965
|
-
const actionHandlerContext =
|
|
15922
|
+
const actionHandlerContext = useMemo13(
|
|
15966
15923
|
() => {
|
|
15967
15924
|
var _a2;
|
|
15968
15925
|
return {
|
|
@@ -16023,7 +15980,7 @@ function XViewScene({
|
|
|
16023
15980
|
const handleStartVersioning = (nodeData) => {
|
|
16024
15981
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
16025
15982
|
};
|
|
16026
|
-
const handleStartQuestQuick =
|
|
15983
|
+
const handleStartQuestQuick = useCallback5((questNode) => {
|
|
16027
15984
|
var _a2, _b2, _c2;
|
|
16028
15985
|
if (!questNode || !actionHandlerContext) return;
|
|
16029
15986
|
const allParentNodes = Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
|
|
@@ -16058,7 +16015,7 @@ function XViewScene({
|
|
|
16058
16015
|
}
|
|
16059
16016
|
setDetailsNode(updatedNode);
|
|
16060
16017
|
}, [session, actionHandlerContext]);
|
|
16061
|
-
const handleFinishQuestQuick =
|
|
16018
|
+
const handleFinishQuestQuick = useCallback5((questNode) => {
|
|
16062
16019
|
var _a2, _b2, _c2, _d2;
|
|
16063
16020
|
if (!questNode || !actionHandlerContext) return;
|
|
16064
16021
|
const {
|
|
@@ -16132,7 +16089,7 @@ function XViewScene({
|
|
|
16132
16089
|
setDetailsNode(null);
|
|
16133
16090
|
}
|
|
16134
16091
|
}, [session, actionHandlerContext, viewMembers, detailsNode]);
|
|
16135
|
-
const handleCancelQuest =
|
|
16092
|
+
const handleCancelQuest = useCallback5(() => {
|
|
16136
16093
|
const { graphGroup, ghostElements } = stateRef.current;
|
|
16137
16094
|
if (ghostElements.node && graphGroup) {
|
|
16138
16095
|
if (ghostElements.node.userData.labelObject) {
|
|
@@ -16191,13 +16148,15 @@ function XViewScene({
|
|
|
16191
16148
|
try {
|
|
16192
16149
|
await actions.save_view_data(sceneSaveUrl2, sceneFileData);
|
|
16193
16150
|
sceneDataRef2.current.quest_counter = currentCounter + 1;
|
|
16194
|
-
sceneDataRef2.current.quest_nodes = sceneFileData.quest_nodes;
|
|
16195
|
-
sceneDataRef2.current.quest_links = sceneFileData.quest_links;
|
|
16196
16151
|
stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
16197
16152
|
parentFileId: sceneConfigId2,
|
|
16198
16153
|
ownerId: ownerId2,
|
|
16199
16154
|
datasetName: "Quests Internas (View)"
|
|
16200
16155
|
});
|
|
16156
|
+
sceneDataRef2.current.quest_nodes = [...graphDataRef.current[sceneConfigId2].nodes];
|
|
16157
|
+
if (parentDataRef.current[sceneConfigId2]) {
|
|
16158
|
+
parentDataRef.current[sceneConfigId2].nodes = [...graphDataRef.current[sceneConfigId2].nodes];
|
|
16159
|
+
}
|
|
16201
16160
|
const finalPosition = stateRef2.current.ghostElements.node ? stateRef2.current.ghostElements.node.position.clone() : stateRef2.current.controls.target.clone();
|
|
16202
16161
|
const { graphGroup, ghostElements } = stateRef2.current;
|
|
16203
16162
|
if (ghostElements.node && graphGroup) {
|
|
@@ -16287,7 +16246,7 @@ function XViewScene({
|
|
|
16287
16246
|
}
|
|
16288
16247
|
userActionHandlers.handleCancelConnection(context);
|
|
16289
16248
|
};
|
|
16290
|
-
const handleClearAncestryVisuals =
|
|
16249
|
+
const handleClearAncestryVisuals = useCallback5((ancestryId) => {
|
|
16291
16250
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
16292
16251
|
const renderIndex = renderedAncestries.findIndex(
|
|
16293
16252
|
(a) => String(a.id) === String(ancestryId)
|
|
@@ -16305,7 +16264,7 @@ function XViewScene({
|
|
|
16305
16264
|
);
|
|
16306
16265
|
}
|
|
16307
16266
|
}, []);
|
|
16308
|
-
const handleRenderAncestry =
|
|
16267
|
+
const handleRenderAncestry = useCallback5(
|
|
16309
16268
|
async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
|
|
16310
16269
|
setContextMenu(
|
|
16311
16270
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -16799,7 +16758,7 @@ function XViewScene({
|
|
|
16799
16758
|
ancestryMode.isActive
|
|
16800
16759
|
]
|
|
16801
16760
|
);
|
|
16802
|
-
const handleRenderAbstractionTree =
|
|
16761
|
+
const handleRenderAbstractionTree = useCallback5(
|
|
16803
16762
|
(ancestryObject, targetNodeId = null) => {
|
|
16804
16763
|
setContextMenu(
|
|
16805
16764
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -16887,7 +16846,7 @@ function XViewScene({
|
|
|
16887
16846
|
handleClearAncestryVisuals
|
|
16888
16847
|
]
|
|
16889
16848
|
);
|
|
16890
|
-
const handleReadModeBranchNav =
|
|
16849
|
+
const handleReadModeBranchNav = useCallback5(
|
|
16891
16850
|
(nodeId, action, direction = "right") => {
|
|
16892
16851
|
const { ancestry, branchStack } = readingMode;
|
|
16893
16852
|
if (!ancestry || !ancestry.tree) return;
|
|
@@ -17065,13 +17024,13 @@ function XViewScene({
|
|
|
17065
17024
|
},
|
|
17066
17025
|
[readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]
|
|
17067
17026
|
);
|
|
17068
|
-
const handleReadModeHighlight =
|
|
17027
|
+
const handleReadModeHighlight = useCallback5((nodeId) => {
|
|
17069
17028
|
if (stateRef.current.highlightedNodeId !== nodeId) {
|
|
17070
17029
|
stateRef.current.highlightedNodeId = nodeId;
|
|
17071
17030
|
}
|
|
17072
17031
|
setHighlightedNodeId(nodeId);
|
|
17073
17032
|
}, []);
|
|
17074
|
-
const activeNodeBranches =
|
|
17033
|
+
const activeNodeBranches = useMemo13(() => {
|
|
17075
17034
|
if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree)
|
|
17076
17035
|
return null;
|
|
17077
17036
|
const fullTree = buildFullAncestryTree(
|
|
@@ -17115,7 +17074,7 @@ function XViewScene({
|
|
|
17115
17074
|
readingMode.branchStack,
|
|
17116
17075
|
ancestryDataRef.current
|
|
17117
17076
|
]);
|
|
17118
|
-
const backNavigationInfo =
|
|
17077
|
+
const backNavigationInfo = useMemo13(() => {
|
|
17119
17078
|
const { branchStack } = readingMode;
|
|
17120
17079
|
if (!branchStack || branchStack.length === 0) return null;
|
|
17121
17080
|
const lastStep = branchStack[branchStack.length - 1];
|
|
@@ -17126,7 +17085,7 @@ function XViewScene({
|
|
|
17126
17085
|
name: "Voltar para anterior"
|
|
17127
17086
|
};
|
|
17128
17087
|
}, [readingMode.branchStack]);
|
|
17129
|
-
const getReadModeDisplayContext =
|
|
17088
|
+
const getReadModeDisplayContext = useMemo13(() => {
|
|
17130
17089
|
const { ancestry, branchStack } = readingMode;
|
|
17131
17090
|
if (!ancestry) return null;
|
|
17132
17091
|
if (branchStack.length === 0) {
|
|
@@ -17169,7 +17128,7 @@ function XViewScene({
|
|
|
17169
17128
|
customProperties: branchProps
|
|
17170
17129
|
};
|
|
17171
17130
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
17172
|
-
const readModeAbstractionTree =
|
|
17131
|
+
const readModeAbstractionTree = useMemo13(() => {
|
|
17173
17132
|
if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
|
|
17174
17133
|
return null;
|
|
17175
17134
|
}
|
|
@@ -17188,7 +17147,7 @@ function XViewScene({
|
|
|
17188
17147
|
buildFullAncestryTree,
|
|
17189
17148
|
sceneVersion
|
|
17190
17149
|
]);
|
|
17191
|
-
const handleStartReadingAncestry =
|
|
17150
|
+
const handleStartReadingAncestry = useCallback5(
|
|
17192
17151
|
async (ancestryObject, renderMode = "full") => {
|
|
17193
17152
|
setContextMenu(
|
|
17194
17153
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -17231,7 +17190,7 @@ function XViewScene({
|
|
|
17231
17190
|
},
|
|
17232
17191
|
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
17233
17192
|
);
|
|
17234
|
-
const handleReadModeSectionChange =
|
|
17193
|
+
const handleReadModeSectionChange = useCallback5(
|
|
17235
17194
|
(activeSectionId) => {
|
|
17236
17195
|
const { ancestry, branchStack } = readingMode;
|
|
17237
17196
|
if (!ancestry || !readingMode.isActive) return;
|
|
@@ -17316,10 +17275,10 @@ function XViewScene({
|
|
|
17316
17275
|
ancestryDataRef.current
|
|
17317
17276
|
]
|
|
17318
17277
|
);
|
|
17319
|
-
const handleCloseReadMode =
|
|
17278
|
+
const handleCloseReadMode = useCallback5(() => {
|
|
17320
17279
|
setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
|
|
17321
17280
|
}, []);
|
|
17322
|
-
const handleAncestrySectionChange =
|
|
17281
|
+
const handleAncestrySectionChange = useCallback5(
|
|
17323
17282
|
(activeSectionId, ancestryOverride = null, rotation = 0) => {
|
|
17324
17283
|
var _a2, _b2;
|
|
17325
17284
|
const currentMode = stateRef.current.ancestry;
|
|
@@ -17381,7 +17340,7 @@ function XViewScene({
|
|
|
17381
17340
|
},
|
|
17382
17341
|
[handleRenderAncestry]
|
|
17383
17342
|
);
|
|
17384
|
-
const handleEditAncestry =
|
|
17343
|
+
const handleEditAncestry = useCallback5(
|
|
17385
17344
|
async (ancestryObject) => {
|
|
17386
17345
|
setContextMenu(
|
|
17387
17346
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -17436,7 +17395,7 @@ function XViewScene({
|
|
|
17436
17395
|
const handleSelectAncestryParent = (nodeId) => {
|
|
17437
17396
|
setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
|
|
17438
17397
|
};
|
|
17439
|
-
const handleRemoveFromAncestry =
|
|
17398
|
+
const handleRemoveFromAncestry = useCallback5((pathToRemove) => {
|
|
17440
17399
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
|
|
17441
17400
|
console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
|
|
17442
17401
|
return;
|
|
@@ -17461,7 +17420,7 @@ function XViewScene({
|
|
|
17461
17420
|
return { ...prev, tree: newTree };
|
|
17462
17421
|
});
|
|
17463
17422
|
}, []);
|
|
17464
|
-
const handleSaveAncestry =
|
|
17423
|
+
const handleSaveAncestry = useCallback5(
|
|
17465
17424
|
async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
|
|
17466
17425
|
const treeToUse = treeOverride || ancestryMode.tree;
|
|
17467
17426
|
const { isEditMode, currentAncestryId } = ancestryMode;
|
|
@@ -17697,7 +17656,7 @@ function XViewScene({
|
|
|
17697
17656
|
});
|
|
17698
17657
|
setEditingAncestryRel({ visible: false, data: null, path: null });
|
|
17699
17658
|
};
|
|
17700
|
-
const handleDeleteAncestry =
|
|
17659
|
+
const handleDeleteAncestry = useCallback5(
|
|
17701
17660
|
async (ancestryIdToDelete) => {
|
|
17702
17661
|
if (!ancestryIdToDelete) {
|
|
17703
17662
|
alert("ID da ancestralidade n\xE3o encontrado.");
|
|
@@ -17779,28 +17738,70 @@ function XViewScene({
|
|
|
17779
17738
|
},
|
|
17780
17739
|
[save_view_data, delete_file_action]
|
|
17781
17740
|
);
|
|
17782
|
-
const handleOpenAncestryBoard =
|
|
17741
|
+
const handleOpenAncestryBoard = useCallback5(() => {
|
|
17783
17742
|
setIsAncestryBoardOpen(true);
|
|
17784
17743
|
}, []);
|
|
17785
|
-
const
|
|
17744
|
+
const allAvailableNodes = useMemo13(() => {
|
|
17745
|
+
if (!parentDataRef.current) return [];
|
|
17746
|
+
return Object.values(parentDataRef.current).flatMap(
|
|
17747
|
+
(fileData) => fileData.nodes || []
|
|
17748
|
+
);
|
|
17749
|
+
}, [sceneVersion, isInitialized]);
|
|
17750
|
+
const allAvailableAncestries = useMemo13(() => {
|
|
17751
|
+
return ancestryDataRef.current || [];
|
|
17752
|
+
}, [sceneVersion, isInitialized]);
|
|
17753
|
+
const handleOpenReference = useCallback5(
|
|
17754
|
+
(referenceData) => {
|
|
17755
|
+
const { type, id } = referenceData;
|
|
17756
|
+
if (type === "node") {
|
|
17757
|
+
const targetNode = allAvailableNodes.find(
|
|
17758
|
+
(n) => String(n.id) === String(id)
|
|
17759
|
+
);
|
|
17760
|
+
if (targetNode) {
|
|
17761
|
+
setAncestryLinkDetails(null);
|
|
17762
|
+
setDetailsLink(null);
|
|
17763
|
+
setDetailsNode(targetNode);
|
|
17764
|
+
const sceneMesh = stateRef.current.nodeObjects[String(id)];
|
|
17765
|
+
if (sceneMesh) {
|
|
17766
|
+
tweenToTarget(sceneMesh);
|
|
17767
|
+
}
|
|
17768
|
+
} else {
|
|
17769
|
+
alert("Node original n\xE3o encontrado neste contexto.");
|
|
17770
|
+
}
|
|
17771
|
+
} else if (type === "ancestry") {
|
|
17772
|
+
const targetAncestry = allAvailableAncestries.find(
|
|
17773
|
+
(a) => String(a.ancestry_id) === String(id)
|
|
17774
|
+
);
|
|
17775
|
+
if (targetAncestry) {
|
|
17776
|
+
setDetailsNode(null);
|
|
17777
|
+
setDetailsLink(null);
|
|
17778
|
+
setAncestryLinkDetails(null);
|
|
17779
|
+
handleEditAncestry(targetAncestry);
|
|
17780
|
+
} else {
|
|
17781
|
+
alert("Ancestralidade original n\xE3o encontrada neste contexto.");
|
|
17782
|
+
}
|
|
17783
|
+
}
|
|
17784
|
+
},
|
|
17785
|
+
[
|
|
17786
|
+
allAvailableNodes,
|
|
17787
|
+
allAvailableAncestries,
|
|
17788
|
+
handleEditAncestry,
|
|
17789
|
+
tweenToTarget
|
|
17790
|
+
]
|
|
17791
|
+
);
|
|
17792
|
+
const handleSelectAncestryFromBoard = useCallback5(
|
|
17786
17793
|
(item) => {
|
|
17787
17794
|
setIsAncestryBoardOpen(false);
|
|
17788
17795
|
setIsSidebarOpen(false);
|
|
17789
|
-
if (item.type === "ancestry"
|
|
17796
|
+
if (item.type === "ancestry") {
|
|
17790
17797
|
handleStartReadingAncestry(item);
|
|
17791
17798
|
} else {
|
|
17792
|
-
|
|
17793
|
-
const sceneMesh = stateRef.current.nodeObjects[nodeId];
|
|
17794
|
-
if (sceneMesh) {
|
|
17795
|
-
tweenToTarget(sceneMesh);
|
|
17796
|
-
} else {
|
|
17797
|
-
console.warn("Objeto n\xE3o encontrado na cena para foco:", nodeId);
|
|
17798
|
-
}
|
|
17799
|
+
handleOpenReference({ type: "node", id: item.id });
|
|
17799
17800
|
}
|
|
17800
17801
|
},
|
|
17801
|
-
[handleStartReadingAncestry,
|
|
17802
|
+
[handleStartReadingAncestry, handleOpenReference]
|
|
17802
17803
|
);
|
|
17803
|
-
const handleSaveAncestryBoard =
|
|
17804
|
+
const handleSaveAncestryBoard = useCallback5(
|
|
17804
17805
|
async (groups) => {
|
|
17805
17806
|
if (!sceneConfigId || !viewParams || !session) return;
|
|
17806
17807
|
const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
|
|
@@ -17814,7 +17815,7 @@ function XViewScene({
|
|
|
17814
17815
|
},
|
|
17815
17816
|
[sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]
|
|
17816
17817
|
);
|
|
17817
|
-
const existingNodeTypes =
|
|
17818
|
+
const existingNodeTypes = useMemo13(() => {
|
|
17818
17819
|
if (!parentDataRef.current) {
|
|
17819
17820
|
return [];
|
|
17820
17821
|
}
|
|
@@ -17826,28 +17827,22 @@ function XViewScene({
|
|
|
17826
17827
|
).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
|
|
17827
17828
|
return [...new Set(allTypes)];
|
|
17828
17829
|
}, [parentDataRef.current, sceneVersion]);
|
|
17829
|
-
const searchableDbNodes =
|
|
17830
|
-
var _a2;
|
|
17830
|
+
const searchableDbNodes = useMemo13(() => {
|
|
17831
17831
|
if (!parentDataRef.current) {
|
|
17832
17832
|
return [];
|
|
17833
17833
|
}
|
|
17834
|
-
|
|
17834
|
+
return Object.entries(parentDataRef.current).flatMap(([dbId, fileData]) => {
|
|
17835
17835
|
const datasetName = fileData.dataset_name || `Dataset #${dbId.substring(0, 6)}`;
|
|
17836
17836
|
return (fileData.nodes || []).map((node) => ({
|
|
17837
17837
|
...node,
|
|
17838
17838
|
dataset_name: datasetName
|
|
17839
17839
|
}));
|
|
17840
|
+
}).filter((node) => {
|
|
17841
|
+
var _a2;
|
|
17842
|
+
return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
|
|
17840
17843
|
});
|
|
17841
|
-
|
|
17842
|
-
|
|
17843
|
-
dataset_name: "Quests Internas (View)"
|
|
17844
|
-
}));
|
|
17845
|
-
return [...datasetsPool, ...questsPool].filter((node) => {
|
|
17846
|
-
var _a3;
|
|
17847
|
-
return !((_a3 = node.version_node) == null ? void 0 : _a3.is_version);
|
|
17848
|
-
});
|
|
17849
|
-
}, [parentDataRef.current, (_b = sceneDataRef.current) == null ? void 0 : _b.quest_nodes, sceneVersion]);
|
|
17850
|
-
const handleAddExistingNode = useCallback4(
|
|
17844
|
+
}, [parentDataRef.current, sceneVersion]);
|
|
17845
|
+
const handleAddExistingNode = useCallback5(
|
|
17851
17846
|
(nodeId) => {
|
|
17852
17847
|
return userActionHandlers.handleAddExistingNodeById(
|
|
17853
17848
|
actionHandlerContext,
|
|
@@ -17856,7 +17851,7 @@ function XViewScene({
|
|
|
17856
17851
|
},
|
|
17857
17852
|
[actionHandlerContext]
|
|
17858
17853
|
);
|
|
17859
|
-
const handleUpdateMilestones =
|
|
17854
|
+
const handleUpdateMilestones = useCallback5(
|
|
17860
17855
|
async (newMilestones) => {
|
|
17861
17856
|
var _a2, _b2, _c2;
|
|
17862
17857
|
if (!sceneDataRef.current) return;
|
|
@@ -17902,7 +17897,7 @@ function XViewScene({
|
|
|
17902
17897
|
viewParams == null ? void 0 : viewParams.type
|
|
17903
17898
|
]
|
|
17904
17899
|
);
|
|
17905
|
-
const handleSaveCurrentView =
|
|
17900
|
+
const handleSaveCurrentView = useCallback5(async () => {
|
|
17906
17901
|
var _a2, _b2, _c2;
|
|
17907
17902
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
17908
17903
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
@@ -17945,61 +17940,13 @@ function XViewScene({
|
|
|
17945
17940
|
console.error("Erro na chamada de save_view_data:", error);
|
|
17946
17941
|
}
|
|
17947
17942
|
}, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
|
|
17948
|
-
const
|
|
17949
|
-
if (!parentDataRef.current) return [];
|
|
17950
|
-
return Object.values(parentDataRef.current).flatMap(
|
|
17951
|
-
(fileData) => fileData.nodes || []
|
|
17952
|
-
);
|
|
17953
|
-
}, [sceneVersion, isInitialized]);
|
|
17954
|
-
const allAvailableAncestries = useMemo12(() => {
|
|
17955
|
-
return ancestryDataRef.current || [];
|
|
17956
|
-
}, [sceneVersion, isInitialized]);
|
|
17957
|
-
const handleOpenReference = useCallback4(
|
|
17958
|
-
(referenceData) => {
|
|
17959
|
-
const { type, id } = referenceData;
|
|
17960
|
-
if (type === "node") {
|
|
17961
|
-
const targetNode = allAvailableNodes.find(
|
|
17962
|
-
(n) => String(n.id) === String(id)
|
|
17963
|
-
);
|
|
17964
|
-
if (targetNode) {
|
|
17965
|
-
setAncestryLinkDetails(null);
|
|
17966
|
-
setDetailsLink(null);
|
|
17967
|
-
setDetailsNode(targetNode);
|
|
17968
|
-
const sceneMesh = stateRef.current.nodeObjects[String(id)];
|
|
17969
|
-
if (sceneMesh) {
|
|
17970
|
-
tweenToTarget(sceneMesh);
|
|
17971
|
-
}
|
|
17972
|
-
} else {
|
|
17973
|
-
alert("Node original n\xE3o encontrado neste contexto.");
|
|
17974
|
-
}
|
|
17975
|
-
} else if (type === "ancestry") {
|
|
17976
|
-
const targetAncestry = allAvailableAncestries.find(
|
|
17977
|
-
(a) => String(a.ancestry_id) === String(id)
|
|
17978
|
-
);
|
|
17979
|
-
if (targetAncestry) {
|
|
17980
|
-
setDetailsNode(null);
|
|
17981
|
-
setDetailsLink(null);
|
|
17982
|
-
setAncestryLinkDetails(null);
|
|
17983
|
-
handleEditAncestry(targetAncestry);
|
|
17984
|
-
} else {
|
|
17985
|
-
alert("Ancestralidade original n\xE3o encontrada neste contexto.");
|
|
17986
|
-
}
|
|
17987
|
-
}
|
|
17988
|
-
},
|
|
17989
|
-
[
|
|
17990
|
-
allAvailableNodes,
|
|
17991
|
-
allAvailableAncestries,
|
|
17992
|
-
handleEditAncestry,
|
|
17993
|
-
tweenToTarget
|
|
17994
|
-
]
|
|
17995
|
-
);
|
|
17996
|
-
const handleToggleAncestryAddMode = useCallback4(() => {
|
|
17943
|
+
const handleToggleAncestryAddMode = useCallback5(() => {
|
|
17997
17944
|
setAncestryMode((prev) => ({
|
|
17998
17945
|
...prev,
|
|
17999
17946
|
isAddingNodes: !prev.isAddingNodes
|
|
18000
17947
|
}));
|
|
18001
17948
|
}, []);
|
|
18002
|
-
const handleFocusNode =
|
|
17949
|
+
const handleFocusNode = useCallback5(
|
|
18003
17950
|
(nodeData) => {
|
|
18004
17951
|
var _a2;
|
|
18005
17952
|
if (!nodeData) return;
|
|
@@ -18015,7 +17962,7 @@ function XViewScene({
|
|
|
18015
17962
|
},
|
|
18016
17963
|
[tweenToTarget]
|
|
18017
17964
|
);
|
|
18018
|
-
const availableDatasets =
|
|
17965
|
+
const availableDatasets = useMemo13(() => {
|
|
18019
17966
|
if (!sceneDataRef.current || !parentDataRef.current) return [];
|
|
18020
17967
|
return sceneDataRef.current.parent_dbs.map((db) => {
|
|
18021
17968
|
var _a2;
|
|
@@ -18025,11 +17972,11 @@ function XViewScene({
|
|
|
18025
17972
|
};
|
|
18026
17973
|
});
|
|
18027
17974
|
}, [sceneVersion, isInitialized]);
|
|
18028
|
-
const sourceNodeDatasetId = creationMode.sourceNodeData ? (
|
|
17975
|
+
const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(
|
|
18029
17976
|
String(creationMode.sourceNodeData.id)
|
|
18030
|
-
)) == null ? void 0 :
|
|
17977
|
+
)) == null ? void 0 : _b.parentFileId : null;
|
|
18031
17978
|
const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
|
|
18032
|
-
|
|
17979
|
+
useEffect24(() => {
|
|
18033
17980
|
if (isInitialized && focusNodeId && !hasFocusedInitial) {
|
|
18034
17981
|
const nodeObjects = stateRef.current.nodeObjects || {};
|
|
18035
17982
|
const targetMesh = nodeObjects[String(focusNodeId)];
|
|
@@ -18052,7 +17999,7 @@ function XViewScene({
|
|
|
18052
17999
|
hasFocusedInitial,
|
|
18053
18000
|
tweenToTarget
|
|
18054
18001
|
]);
|
|
18055
|
-
|
|
18002
|
+
useEffect24(() => {
|
|
18056
18003
|
if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
|
|
18057
18004
|
const ancestries = ancestryDataRef.current || [];
|
|
18058
18005
|
const targetAncestry = ancestries.find(
|
|
@@ -18077,7 +18024,7 @@ function XViewScene({
|
|
|
18077
18024
|
hasOpenedInitialAncestry,
|
|
18078
18025
|
handleStartReadingAncestry
|
|
18079
18026
|
]);
|
|
18080
|
-
|
|
18027
|
+
useEffect24(() => {
|
|
18081
18028
|
function handleKeyDown(event) {
|
|
18082
18029
|
var _a2, _b2, _c2;
|
|
18083
18030
|
const context = actionHandlerContext;
|
|
@@ -18200,10 +18147,10 @@ function XViewScene({
|
|
|
18200
18147
|
// <-- handleCancelQuest adicionado aqui
|
|
18201
18148
|
]);
|
|
18202
18149
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
18203
|
-
return /* @__PURE__ */
|
|
18150
|
+
return /* @__PURE__ */ React30.createElement(LoadingScreen, null);
|
|
18204
18151
|
}
|
|
18205
18152
|
if (permissionStatus === "denied") {
|
|
18206
|
-
return /* @__PURE__ */
|
|
18153
|
+
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(
|
|
18207
18154
|
"svg",
|
|
18208
18155
|
{
|
|
18209
18156
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -18213,7 +18160,7 @@ function XViewScene({
|
|
|
18213
18160
|
stroke: "currentColor",
|
|
18214
18161
|
className: "w-16 h-16 mx-auto"
|
|
18215
18162
|
},
|
|
18216
|
-
/* @__PURE__ */
|
|
18163
|
+
/* @__PURE__ */ React30.createElement(
|
|
18217
18164
|
"path",
|
|
18218
18165
|
{
|
|
18219
18166
|
strokeLinecap: "round",
|
|
@@ -18221,13 +18168,13 @@ function XViewScene({
|
|
|
18221
18168
|
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"
|
|
18222
18169
|
}
|
|
18223
18170
|
)
|
|
18224
|
-
)), /* @__PURE__ */
|
|
18171
|
+
)), /* @__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(
|
|
18225
18172
|
"button",
|
|
18226
18173
|
{
|
|
18227
18174
|
onClick: () => router.push("/dashboard/scenes"),
|
|
18228
18175
|
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"
|
|
18229
18176
|
},
|
|
18230
|
-
/* @__PURE__ */
|
|
18177
|
+
/* @__PURE__ */ React30.createElement(
|
|
18231
18178
|
"svg",
|
|
18232
18179
|
{
|
|
18233
18180
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -18237,7 +18184,7 @@ function XViewScene({
|
|
|
18237
18184
|
stroke: "currentColor",
|
|
18238
18185
|
className: "w-5 h-5"
|
|
18239
18186
|
},
|
|
18240
|
-
/* @__PURE__ */
|
|
18187
|
+
/* @__PURE__ */ React30.createElement(
|
|
18241
18188
|
"path",
|
|
18242
18189
|
{
|
|
18243
18190
|
strokeLinecap: "round",
|
|
@@ -18249,7 +18196,7 @@ function XViewScene({
|
|
|
18249
18196
|
"Voltar para Scenes"
|
|
18250
18197
|
)));
|
|
18251
18198
|
}
|
|
18252
|
-
return /* @__PURE__ */
|
|
18199
|
+
return /* @__PURE__ */ React30.createElement(
|
|
18253
18200
|
"div",
|
|
18254
18201
|
{
|
|
18255
18202
|
ref: mountRef,
|
|
@@ -18261,7 +18208,7 @@ function XViewScene({
|
|
|
18261
18208
|
cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
|
|
18262
18209
|
}
|
|
18263
18210
|
},
|
|
18264
|
-
userPermissionRole !== "link_viewer" && /* @__PURE__ */
|
|
18211
|
+
userPermissionRole !== "link_viewer" && /* @__PURE__ */ React30.createElement(
|
|
18265
18212
|
XViewSidebar,
|
|
18266
18213
|
{
|
|
18267
18214
|
dbNodes: searchableDbNodes,
|
|
@@ -18281,11 +18228,11 @@ function XViewScene({
|
|
|
18281
18228
|
onToggle: setIsSidebarOpen,
|
|
18282
18229
|
userRole: userPermissionRole,
|
|
18283
18230
|
viewMembers,
|
|
18284
|
-
milestones: ((
|
|
18231
|
+
milestones: ((_c = sceneDataRef.current) == null ? void 0 : _c.milestones) || [],
|
|
18285
18232
|
onOpenMilestoneManager: () => setIsMilestoneManagerOpen(true)
|
|
18286
18233
|
}
|
|
18287
18234
|
),
|
|
18288
|
-
creationMode.isActive && /* @__PURE__ */
|
|
18235
|
+
creationMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18289
18236
|
InSceneCreationForm,
|
|
18290
18237
|
{
|
|
18291
18238
|
onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
|
|
@@ -18306,8 +18253,8 @@ function XViewScene({
|
|
|
18306
18253
|
},
|
|
18307
18254
|
refEl: formRef,
|
|
18308
18255
|
existingTypes: existingNodeTypes,
|
|
18309
|
-
initialColor: (
|
|
18310
|
-
sourceTypes: (
|
|
18256
|
+
initialColor: (_d = creationMode.sourceNodeData) == null ? void 0 : _d.color,
|
|
18257
|
+
sourceTypes: (_e = creationMode.sourceNodeData) == null ? void 0 : _e.type,
|
|
18311
18258
|
onIntensityChange: handleGhostNodeIntensityChange,
|
|
18312
18259
|
onUploadFile: upload_file_action,
|
|
18313
18260
|
availableDatasets,
|
|
@@ -18317,7 +18264,7 @@ function XViewScene({
|
|
|
18317
18264
|
availableAncestries: allAvailableAncestries
|
|
18318
18265
|
}
|
|
18319
18266
|
),
|
|
18320
|
-
versionMode.isActive && /* @__PURE__ */
|
|
18267
|
+
versionMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18321
18268
|
InSceneVersionForm,
|
|
18322
18269
|
{
|
|
18323
18270
|
onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
|
|
@@ -18336,14 +18283,14 @@ function XViewScene({
|
|
|
18336
18283
|
transition: "opacity 200ms ease-out"
|
|
18337
18284
|
},
|
|
18338
18285
|
refEl: formRef,
|
|
18339
|
-
fixedType: (
|
|
18340
|
-
fixedColor: (
|
|
18286
|
+
fixedType: (_f = versionMode.sourceNodeData) == null ? void 0 : _f.type,
|
|
18287
|
+
fixedColor: (_g = versionMode.sourceNodeData) == null ? void 0 : _g.color,
|
|
18341
18288
|
onUploadFile: upload_file_action,
|
|
18342
18289
|
availableNodes: allAvailableNodes,
|
|
18343
18290
|
availableAncestries: allAvailableAncestries
|
|
18344
18291
|
}
|
|
18345
18292
|
),
|
|
18346
|
-
questMode.isActive && /* @__PURE__ */
|
|
18293
|
+
questMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18347
18294
|
InSceneQuestForm,
|
|
18348
18295
|
{
|
|
18349
18296
|
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
@@ -18365,13 +18312,13 @@ function XViewScene({
|
|
|
18365
18312
|
availableNodes: allAvailableNodes,
|
|
18366
18313
|
availableAncestries: allAvailableAncestries,
|
|
18367
18314
|
viewName: viewParams == null ? void 0 : viewParams.name,
|
|
18368
|
-
questCounter: ((
|
|
18315
|
+
questCounter: ((_h = sceneDataRef.current) == null ? void 0 : _h.quest_counter) || 1,
|
|
18369
18316
|
viewMembers,
|
|
18370
|
-
milestones: ((
|
|
18317
|
+
milestones: ((_i = sceneDataRef.current) == null ? void 0 : _i.milestones) || [],
|
|
18371
18318
|
onUpdateMilestones: handleUpdateMilestones
|
|
18372
18319
|
}
|
|
18373
18320
|
),
|
|
18374
|
-
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */
|
|
18321
|
+
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React30.createElement(
|
|
18375
18322
|
"div",
|
|
18376
18323
|
{
|
|
18377
18324
|
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"}`,
|
|
@@ -18384,7 +18331,7 @@ function XViewScene({
|
|
|
18384
18331
|
maxWidth: "92vw"
|
|
18385
18332
|
}
|
|
18386
18333
|
},
|
|
18387
|
-
/* @__PURE__ */
|
|
18334
|
+
/* @__PURE__ */ React30.createElement(
|
|
18388
18335
|
"div",
|
|
18389
18336
|
{
|
|
18390
18337
|
onPointerDown: (e) => {
|
|
@@ -18395,7 +18342,7 @@ function XViewScene({
|
|
|
18395
18342
|
title: "Arraste para redimensionar"
|
|
18396
18343
|
}
|
|
18397
18344
|
),
|
|
18398
|
-
/* @__PURE__ */
|
|
18345
|
+
/* @__PURE__ */ React30.createElement(
|
|
18399
18346
|
DescriptionReadModePanel,
|
|
18400
18347
|
{
|
|
18401
18348
|
key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
|
|
@@ -18430,7 +18377,7 @@ function XViewScene({
|
|
|
18430
18377
|
}
|
|
18431
18378
|
)
|
|
18432
18379
|
),
|
|
18433
|
-
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */
|
|
18380
|
+
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ React30.createElement(
|
|
18434
18381
|
CreateAncestryPanel,
|
|
18435
18382
|
{
|
|
18436
18383
|
ancestryMode,
|
|
@@ -18466,7 +18413,7 @@ function XViewScene({
|
|
|
18466
18413
|
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
18467
18414
|
}
|
|
18468
18415
|
),
|
|
18469
|
-
editingAncestryRel.visible && /* @__PURE__ */
|
|
18416
|
+
editingAncestryRel.visible && /* @__PURE__ */ React30.createElement(
|
|
18470
18417
|
AncestryRelationshipPanel,
|
|
18471
18418
|
{
|
|
18472
18419
|
data: editingAncestryRel.data,
|
|
@@ -18480,7 +18427,7 @@ function XViewScene({
|
|
|
18480
18427
|
onUploadFile: upload_file_action
|
|
18481
18428
|
}
|
|
18482
18429
|
),
|
|
18483
|
-
detailsNode && detailsNode.is_quest && /* @__PURE__ */
|
|
18430
|
+
detailsNode && detailsNode.is_quest && /* @__PURE__ */ React30.createElement(
|
|
18484
18431
|
QuestDetailsPanel,
|
|
18485
18432
|
{
|
|
18486
18433
|
node: detailsNode,
|
|
@@ -18502,11 +18449,11 @@ function XViewScene({
|
|
|
18502
18449
|
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName,
|
|
18503
18450
|
viewMembers,
|
|
18504
18451
|
currentUser: session == null ? void 0 : session.user,
|
|
18505
|
-
milestones: ((
|
|
18452
|
+
milestones: ((_j = sceneDataRef.current) == null ? void 0 : _j.milestones) || [],
|
|
18506
18453
|
onUpdateMilestones: handleUpdateMilestones
|
|
18507
18454
|
}
|
|
18508
18455
|
),
|
|
18509
|
-
detailsNode && !detailsNode.is_quest && /* @__PURE__ */
|
|
18456
|
+
detailsNode && !detailsNode.is_quest && /* @__PURE__ */ React30.createElement(
|
|
18510
18457
|
NodeDetailsPanel,
|
|
18511
18458
|
{
|
|
18512
18459
|
node: detailsNode,
|
|
@@ -18538,7 +18485,7 @@ function XViewScene({
|
|
|
18538
18485
|
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
18539
18486
|
}
|
|
18540
18487
|
),
|
|
18541
|
-
detailsLink && /* @__PURE__ */
|
|
18488
|
+
detailsLink && /* @__PURE__ */ React30.createElement(
|
|
18542
18489
|
RelationshipDetailsPanel,
|
|
18543
18490
|
{
|
|
18544
18491
|
link: detailsLink,
|
|
@@ -18552,7 +18499,7 @@ function XViewScene({
|
|
|
18552
18499
|
userRole: userPermissionRole
|
|
18553
18500
|
}
|
|
18554
18501
|
),
|
|
18555
|
-
ancestryLinkDetails && /* @__PURE__ */
|
|
18502
|
+
ancestryLinkDetails && /* @__PURE__ */ React30.createElement(
|
|
18556
18503
|
AncestryLinkDetailsPanel,
|
|
18557
18504
|
{
|
|
18558
18505
|
data: ancestryLinkDetails,
|
|
@@ -18563,7 +18510,7 @@ function XViewScene({
|
|
|
18563
18510
|
onUploadFile: upload_file_action
|
|
18564
18511
|
}
|
|
18565
18512
|
),
|
|
18566
|
-
/* @__PURE__ */
|
|
18513
|
+
/* @__PURE__ */ React30.createElement(
|
|
18567
18514
|
"div",
|
|
18568
18515
|
{
|
|
18569
18516
|
ref: tooltipRef,
|
|
@@ -18590,7 +18537,7 @@ function XViewScene({
|
|
|
18590
18537
|
}
|
|
18591
18538
|
}
|
|
18592
18539
|
),
|
|
18593
|
-
/* @__PURE__ */
|
|
18540
|
+
/* @__PURE__ */ React30.createElement(
|
|
18594
18541
|
ContextMenu,
|
|
18595
18542
|
{
|
|
18596
18543
|
data: contextMenu,
|
|
@@ -18623,7 +18570,7 @@ function XViewScene({
|
|
|
18623
18570
|
onFinishQuest: handleFinishQuestQuick
|
|
18624
18571
|
}
|
|
18625
18572
|
),
|
|
18626
|
-
/* @__PURE__ */
|
|
18573
|
+
/* @__PURE__ */ React30.createElement(
|
|
18627
18574
|
MultiNodeContextMenu,
|
|
18628
18575
|
{
|
|
18629
18576
|
data: multiContextMenu,
|
|
@@ -18643,7 +18590,7 @@ function XViewScene({
|
|
|
18643
18590
|
)
|
|
18644
18591
|
}
|
|
18645
18592
|
),
|
|
18646
|
-
/* @__PURE__ */
|
|
18593
|
+
/* @__PURE__ */ React30.createElement(
|
|
18647
18594
|
RelationshipContextMenu,
|
|
18648
18595
|
{
|
|
18649
18596
|
data: relationshipMenu,
|
|
@@ -18661,14 +18608,14 @@ function XViewScene({
|
|
|
18661
18608
|
onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
|
|
18662
18609
|
}
|
|
18663
18610
|
),
|
|
18664
|
-
/* @__PURE__ */
|
|
18611
|
+
/* @__PURE__ */ React30.createElement(
|
|
18665
18612
|
ImageViewer,
|
|
18666
18613
|
{
|
|
18667
18614
|
data: imageViewer,
|
|
18668
18615
|
onClose: () => setImageViewer({ ...imageViewer, visible: false })
|
|
18669
18616
|
}
|
|
18670
18617
|
),
|
|
18671
|
-
/* @__PURE__ */
|
|
18618
|
+
/* @__PURE__ */ React30.createElement(
|
|
18672
18619
|
AncestryBoard,
|
|
18673
18620
|
{
|
|
18674
18621
|
isOpen: isAncestryBoardOpen,
|
|
@@ -18681,29 +18628,29 @@ function XViewScene({
|
|
|
18681
18628
|
userRole: userPermissionRole
|
|
18682
18629
|
}
|
|
18683
18630
|
),
|
|
18684
|
-
/* @__PURE__ */
|
|
18631
|
+
/* @__PURE__ */ React30.createElement(
|
|
18685
18632
|
MilestoneManager,
|
|
18686
18633
|
{
|
|
18687
18634
|
isOpen: isMilestoneManagerOpen,
|
|
18688
18635
|
onClose: () => setIsMilestoneManagerOpen(false),
|
|
18689
|
-
milestones: ((
|
|
18636
|
+
milestones: ((_k = sceneDataRef.current) == null ? void 0 : _k.milestones) || [],
|
|
18690
18637
|
onUpdateMilestones: handleUpdateMilestones
|
|
18691
18638
|
}
|
|
18692
18639
|
),
|
|
18693
|
-
/* @__PURE__ */
|
|
18640
|
+
/* @__PURE__ */ React30.createElement(
|
|
18694
18641
|
ImportParentFileModal,
|
|
18695
18642
|
{
|
|
18696
18643
|
isOpen: isImportModalOpen,
|
|
18697
18644
|
onClose: () => setIsImportModalOpen(false),
|
|
18698
18645
|
onConfirm: handleConfirmImport,
|
|
18699
18646
|
session,
|
|
18700
|
-
parentDbs: ((
|
|
18647
|
+
parentDbs: ((_l = sceneDataRef.current) == null ? void 0 : _l.parent_dbs) || [],
|
|
18701
18648
|
onFetchAvailableFiles: import_parent_file_modal_get,
|
|
18702
18649
|
currentViewName: viewParams == null ? void 0 : viewParams.name,
|
|
18703
18650
|
currentAncestries: ancestryDataRef.current || []
|
|
18704
18651
|
}
|
|
18705
18652
|
),
|
|
18706
|
-
invalidTargetError && /* @__PURE__ */
|
|
18653
|
+
invalidTargetError && /* @__PURE__ */ React30.createElement(
|
|
18707
18654
|
"div",
|
|
18708
18655
|
{
|
|
18709
18656
|
className: "ui-overlay",
|
|
@@ -18728,13 +18675,13 @@ function XViewScene({
|
|
|
18728
18675
|
animation: "fadeInDown 0.5s cubic-bezier(0.16, 1, 0.3, 1)"
|
|
18729
18676
|
}
|
|
18730
18677
|
},
|
|
18731
|
-
/* @__PURE__ */
|
|
18678
|
+
/* @__PURE__ */ React30.createElement("style", null, `
|
|
18732
18679
|
@keyframes fadeInDown {
|
|
18733
18680
|
from { opacity: 0; transform: translate(-50%, -20px); }
|
|
18734
18681
|
to { opacity: 1; transform: translate(-50%, 0); }
|
|
18735
18682
|
}
|
|
18736
18683
|
`),
|
|
18737
|
-
/* @__PURE__ */
|
|
18684
|
+
/* @__PURE__ */ React30.createElement(
|
|
18738
18685
|
"svg",
|
|
18739
18686
|
{
|
|
18740
18687
|
width: "20",
|
|
@@ -18746,12 +18693,12 @@ function XViewScene({
|
|
|
18746
18693
|
strokeLinecap: "round",
|
|
18747
18694
|
strokeLinejoin: "round"
|
|
18748
18695
|
},
|
|
18749
|
-
/* @__PURE__ */
|
|
18750
|
-
/* @__PURE__ */
|
|
18751
|
-
/* @__PURE__ */
|
|
18696
|
+
/* @__PURE__ */ React30.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
18697
|
+
/* @__PURE__ */ React30.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
18698
|
+
/* @__PURE__ */ React30.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
18752
18699
|
),
|
|
18753
|
-
/* @__PURE__ */
|
|
18754
|
-
/* @__PURE__ */
|
|
18700
|
+
/* @__PURE__ */ React30.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
|
|
18701
|
+
/* @__PURE__ */ React30.createElement(
|
|
18755
18702
|
"button",
|
|
18756
18703
|
{
|
|
18757
18704
|
onClick: () => setInvalidTargetError(null),
|