@lv-x-software-house/x_view 1.2.6-dev.1 → 1.2.6-dev.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +791 -788
- package/dist/index.mjs +798 -796
- 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,126 @@ function AncestryBoard({
|
|
|
13197
13389
|
onSave,
|
|
13198
13390
|
userRole
|
|
13199
13391
|
}) {
|
|
13200
|
-
const [searchTerm, setSearchTerm] =
|
|
13201
|
-
const [groups, setGroups] =
|
|
13202
|
-
const [isLoaded, setIsLoaded] =
|
|
13203
|
-
const [
|
|
13204
|
-
const
|
|
13205
|
-
|
|
13206
|
-
return userRole !== "viewer";
|
|
13207
|
-
}, [userRole]);
|
|
13208
|
-
useEffect21(() => {
|
|
13392
|
+
const [searchTerm, setSearchTerm] = useState27("");
|
|
13393
|
+
const [groups, setGroups] = useState27([]);
|
|
13394
|
+
const [isLoaded, setIsLoaded] = useState27(false);
|
|
13395
|
+
const [saveStatus, setSaveStatus] = useState27("idle");
|
|
13396
|
+
const canEdit = useMemo12(() => userRole !== "viewer", [userRole]);
|
|
13397
|
+
useEffect23(() => {
|
|
13209
13398
|
if (initialGroups && !isLoaded) {
|
|
13210
|
-
|
|
13399
|
+
const migrate = (list) => list.map((g) => ({
|
|
13400
|
+
id: g.id || uuidv411(),
|
|
13401
|
+
content: Array.isArray(g.content) ? g.content : [],
|
|
13402
|
+
// descarta dados legados
|
|
13403
|
+
children: migrate(g.children || [])
|
|
13404
|
+
}));
|
|
13405
|
+
setGroups(migrate(initialGroups));
|
|
13211
13406
|
setIsLoaded(true);
|
|
13212
13407
|
}
|
|
13213
13408
|
}, [initialGroups, isLoaded]);
|
|
13214
|
-
const nodeNamesMap =
|
|
13409
|
+
const nodeNamesMap = useMemo12(() => {
|
|
13215
13410
|
const map = /* @__PURE__ */ new Map();
|
|
13216
|
-
|
|
13217
|
-
|
|
13218
|
-
|
|
13219
|
-
map.set(String(node.id), node.name);
|
|
13220
|
-
}
|
|
13221
|
-
});
|
|
13222
|
-
}
|
|
13411
|
+
availableNodes.forEach((n) => {
|
|
13412
|
+
if (n == null ? void 0 : n.id) map.set(String(n.id), n.name);
|
|
13413
|
+
});
|
|
13223
13414
|
return map;
|
|
13224
13415
|
}, [availableNodes]);
|
|
13225
|
-
const
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
|
|
13229
|
-
|
|
13230
|
-
|
|
13231
|
-
|
|
13232
|
-
|
|
13233
|
-
|
|
13234
|
-
|
|
13235
|
-
|
|
13236
|
-
|
|
13237
|
-
|
|
13238
|
-
const nodes = availableNodes.map((n) => {
|
|
13416
|
+
const allSearchableItems = useMemo12(() => {
|
|
13417
|
+
const items = [];
|
|
13418
|
+
availableAncestries.forEach((anc) => {
|
|
13419
|
+
items.push({
|
|
13420
|
+
...anc,
|
|
13421
|
+
id: String(anc.ancestry_id),
|
|
13422
|
+
type: "ancestry",
|
|
13423
|
+
searchLabel: anc.name || "",
|
|
13424
|
+
searchDesc: anc.description || ""
|
|
13425
|
+
});
|
|
13426
|
+
});
|
|
13427
|
+
availableNodes.forEach((node) => {
|
|
13428
|
+
var _a;
|
|
13239
13429
|
let type = "node";
|
|
13240
|
-
if (
|
|
13241
|
-
else if (
|
|
13242
|
-
|
|
13243
|
-
|
|
13244
|
-
|
|
13245
|
-
description: n.description,
|
|
13430
|
+
if (node.is_quest) type = "quest";
|
|
13431
|
+
else if ((_a = node.version_node) == null ? void 0 : _a.is_version) type = "version";
|
|
13432
|
+
items.push({
|
|
13433
|
+
...node,
|
|
13434
|
+
id: String(node.id),
|
|
13246
13435
|
type,
|
|
13247
|
-
|
|
13248
|
-
|
|
13436
|
+
searchLabel: node.name || node.raw_title || "",
|
|
13437
|
+
searchDesc: node.description || ""
|
|
13438
|
+
});
|
|
13249
13439
|
});
|
|
13250
|
-
return
|
|
13440
|
+
return items;
|
|
13251
13441
|
}, [availableAncestries, availableNodes]);
|
|
13252
|
-
const
|
|
13253
|
-
|
|
13254
|
-
|
|
13255
|
-
|
|
13256
|
-
|
|
13257
|
-
|
|
13258
|
-
|
|
13259
|
-
|
|
13260
|
-
|
|
13261
|
-
|
|
13262
|
-
|
|
13263
|
-
|
|
13264
|
-
|
|
13265
|
-
|
|
13442
|
+
const filtered = useMemo12(() => {
|
|
13443
|
+
const term = searchTerm.toLowerCase().trim();
|
|
13444
|
+
return allSearchableItems.filter((item) => {
|
|
13445
|
+
if (!term) return true;
|
|
13446
|
+
const labelMatch = (item.searchLabel || "").toLowerCase().includes(term);
|
|
13447
|
+
const descMatch = (item.searchDesc || "").toLowerCase().includes(term);
|
|
13448
|
+
let parentMatch = false;
|
|
13449
|
+
if (item.type === "ancestry") {
|
|
13450
|
+
const parentName = nodeNamesMap.get(String(item.ancestral_node)) || "";
|
|
13451
|
+
parentMatch = parentName.toLowerCase().includes(term);
|
|
13452
|
+
}
|
|
13453
|
+
return labelMatch || descMatch || parentMatch;
|
|
13454
|
+
});
|
|
13455
|
+
}, [allSearchableItems, searchTerm, nodeNamesMap]);
|
|
13456
|
+
const sanitizeGroups = (list) => list.map((g) => ({
|
|
13457
|
+
id: g.id,
|
|
13458
|
+
content: g.content || [],
|
|
13459
|
+
children: sanitizeGroups(g.children || [])
|
|
13460
|
+
}));
|
|
13461
|
+
useEffect23(() => {
|
|
13266
13462
|
if (!isLoaded || !onSave) return;
|
|
13267
|
-
const
|
|
13463
|
+
const id = setTimeout(async () => {
|
|
13268
13464
|
setSaveStatus("saving");
|
|
13269
|
-
const cleanData = sanitizeGroups(groups);
|
|
13270
13465
|
try {
|
|
13271
|
-
await onSave(
|
|
13466
|
+
await onSave(sanitizeGroups(groups));
|
|
13272
13467
|
setSaveStatus("saved");
|
|
13273
|
-
setTimeout(() =>
|
|
13274
|
-
|
|
13275
|
-
|
|
13276
|
-
} catch (error) {
|
|
13277
|
-
console.error("Erro ao salvar board:", error);
|
|
13468
|
+
setTimeout(() => setSaveStatus("idle"), 3e3);
|
|
13469
|
+
} catch (err) {
|
|
13470
|
+
console.error("Erro ao salvar board:", err);
|
|
13278
13471
|
setSaveStatus("error");
|
|
13279
13472
|
}
|
|
13280
13473
|
}, 3e3);
|
|
13281
|
-
return () => clearTimeout(
|
|
13474
|
+
return () => clearTimeout(id);
|
|
13282
13475
|
}, [groups, isLoaded, onSave]);
|
|
13283
|
-
|
|
13476
|
+
useEffect23(() => {
|
|
13284
13477
|
if (!isOpen) return;
|
|
13285
|
-
const
|
|
13478
|
+
const handler = (e) => {
|
|
13286
13479
|
if (e.key === "Escape") {
|
|
13287
|
-
|
|
13288
|
-
setPickingGroupId(null);
|
|
13289
|
-
} else {
|
|
13290
|
-
onClose();
|
|
13291
|
-
}
|
|
13480
|
+
onClose();
|
|
13292
13481
|
e.preventDefault();
|
|
13293
13482
|
e.stopPropagation();
|
|
13294
13483
|
}
|
|
13295
13484
|
};
|
|
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]);
|
|
13485
|
+
window.addEventListener("keydown", handler);
|
|
13486
|
+
return () => window.removeEventListener("keydown", handler);
|
|
13487
|
+
}, [isOpen, onClose]);
|
|
13313
13488
|
const handleAddRootGroup = () => {
|
|
13314
|
-
|
|
13315
|
-
id: v4_default(),
|
|
13316
|
-
text: "",
|
|
13317
|
-
ancestries: [],
|
|
13318
|
-
children: []
|
|
13319
|
-
};
|
|
13320
|
-
setGroups((prev) => [newGroup, ...prev]);
|
|
13489
|
+
setGroups((prev) => [{ id: uuidv411(), content: [], children: [] }, ...prev]);
|
|
13321
13490
|
};
|
|
13322
13491
|
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));
|
|
13492
|
+
const newGroup = { id: uuidv411(), content: [], children: [] };
|
|
13493
|
+
const add = (list) => list.map(
|
|
13494
|
+
(g) => g.id === parentId ? { ...g, children: [newGroup, ...g.children] } : { ...g, children: add(g.children) }
|
|
13495
|
+
);
|
|
13496
|
+
setGroups((prev) => add(prev));
|
|
13338
13497
|
};
|
|
13339
13498
|
const handleUpdateGroup = (id, newData) => {
|
|
13340
|
-
const
|
|
13341
|
-
|
|
13342
|
-
|
|
13343
|
-
|
|
13344
|
-
});
|
|
13345
|
-
};
|
|
13346
|
-
setGroups((prev) => updateRecursive(prev));
|
|
13499
|
+
const update = (list) => list.map(
|
|
13500
|
+
(g) => g.id === id ? newData : { ...g, children: update(g.children) }
|
|
13501
|
+
);
|
|
13502
|
+
setGroups((prev) => update(prev));
|
|
13347
13503
|
};
|
|
13348
13504
|
const handleDeleteGroup = (id) => {
|
|
13349
|
-
const
|
|
13350
|
-
|
|
13351
|
-
...g,
|
|
13352
|
-
children: deleteRecursive(g.children)
|
|
13353
|
-
}));
|
|
13354
|
-
};
|
|
13355
|
-
setGroups((prev) => deleteRecursive(prev));
|
|
13505
|
+
const del = (list) => list.filter((g) => g.id !== id).map((g) => ({ ...g, children: del(g.children) }));
|
|
13506
|
+
setGroups((prev) => del(prev));
|
|
13356
13507
|
};
|
|
13357
13508
|
const findGroupAndParent = (list, targetId, parent = null) => {
|
|
13358
13509
|
for (let i = 0; i < list.length; i++) {
|
|
13359
|
-
if (list[i].id === targetId)
|
|
13510
|
+
if (list[i].id === targetId)
|
|
13360
13511
|
return { group: list[i], parent, index: i, siblings: list };
|
|
13361
|
-
}
|
|
13362
13512
|
if (list[i].children.length > 0) {
|
|
13363
13513
|
const found = findGroupAndParent(list[i].children, targetId, list[i]);
|
|
13364
13514
|
if (found) return found;
|
|
@@ -13368,257 +13518,119 @@ function AncestryBoard({
|
|
|
13368
13518
|
};
|
|
13369
13519
|
const handleIndent = (id) => {
|
|
13370
13520
|
setGroups((prev) => {
|
|
13371
|
-
const
|
|
13372
|
-
const found = findGroupAndParent(
|
|
13521
|
+
const next = JSON.parse(JSON.stringify(prev));
|
|
13522
|
+
const found = findGroupAndParent(next, id);
|
|
13373
13523
|
if (!found || found.index === 0) return prev;
|
|
13374
13524
|
const { group, siblings, index } = found;
|
|
13375
|
-
const prevSibling = siblings[index - 1];
|
|
13376
13525
|
siblings.splice(index, 1);
|
|
13377
|
-
|
|
13378
|
-
return
|
|
13526
|
+
siblings[index - 1].children.push(group);
|
|
13527
|
+
return next;
|
|
13379
13528
|
});
|
|
13380
13529
|
};
|
|
13381
13530
|
const handleOutdent = (id) => {
|
|
13382
13531
|
setGroups((prev) => {
|
|
13383
|
-
const
|
|
13384
|
-
const found = findGroupAndParent(
|
|
13532
|
+
const next = JSON.parse(JSON.stringify(prev));
|
|
13533
|
+
const found = findGroupAndParent(next, id);
|
|
13385
13534
|
if (!found || !found.parent) return prev;
|
|
13386
13535
|
const { group, siblings, index, parent } = found;
|
|
13387
13536
|
siblings.splice(index, 1);
|
|
13388
|
-
const parentFound = findGroupAndParent(
|
|
13537
|
+
const parentFound = findGroupAndParent(next, parent.id);
|
|
13389
13538
|
if (parentFound) {
|
|
13390
13539
|
parentFound.siblings.splice(parentFound.index + 1, 0, group);
|
|
13391
13540
|
} else {
|
|
13392
|
-
|
|
13541
|
+
next.push(group);
|
|
13393
13542
|
}
|
|
13394
|
-
return
|
|
13543
|
+
return next;
|
|
13395
13544
|
});
|
|
13396
13545
|
};
|
|
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
|
-
});
|
|
13546
|
+
const handleMentionClick = (item) => {
|
|
13547
|
+
if (onSelect) onSelect(item);
|
|
13465
13548
|
};
|
|
13466
13549
|
if (!isOpen) return null;
|
|
13467
|
-
return /* @__PURE__ */
|
|
13550
|
+
return /* @__PURE__ */ React28.createElement(
|
|
13468
13551
|
"div",
|
|
13469
13552
|
{
|
|
13470
13553
|
className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
|
|
13471
13554
|
onClick: onClose
|
|
13472
13555
|
},
|
|
13473
|
-
/* @__PURE__ */
|
|
13556
|
+
/* @__PURE__ */ React28.createElement(
|
|
13474
13557
|
"div",
|
|
13475
13558
|
{
|
|
13476
13559
|
className: "bg-slate-950 border border-white/10 rounded-xl w-[98vw] h-[97vh] flex flex-col shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-200",
|
|
13477
13560
|
onClick: (e) => e.stopPropagation()
|
|
13478
13561
|
},
|
|
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(
|
|
13562
|
+
/* @__PURE__ */ React28.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React28.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ React28.createElement(FiLayers7, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React28.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-slate-900/50 border border-white/5" }, saveStatus === "saving" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(FiLoader5, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ React28.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ React28.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ React28.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-3" }, canEdit && /* @__PURE__ */ React28.createElement(
|
|
13486
13563
|
"button",
|
|
13487
13564
|
{
|
|
13488
13565
|
onClick: handleAddRootGroup,
|
|
13489
|
-
className: "
|
|
13566
|
+
className: "flex items-center gap-2 px-3 py-1.5 bg-white/5 hover:bg-white/10 border border-white/10 hover:border-white/20 backdrop-blur-sm text-slate-200 hover:text-white rounded-md transition-all duration-200 text-xs font-medium shadow-sm"
|
|
13490
13567
|
},
|
|
13491
|
-
/* @__PURE__ */
|
|
13492
|
-
/* @__PURE__ */
|
|
13493
|
-
), /* @__PURE__ */
|
|
13568
|
+
/* @__PURE__ */ React28.createElement(FiPlus10, { size: 14, className: "text-indigo-400" }),
|
|
13569
|
+
/* @__PURE__ */ React28.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
|
|
13570
|
+
), /* @__PURE__ */ React28.createElement(
|
|
13494
13571
|
"button",
|
|
13495
13572
|
{
|
|
13496
13573
|
onClick: onClose,
|
|
13497
13574
|
className: "w-8 h-8 rounded-lg flex items-center justify-center text-slate-400 hover:text-white hover:bg-white/10 transition-colors"
|
|
13498
13575
|
},
|
|
13499
|
-
|
|
13576
|
+
/* @__PURE__ */ React28.createElement(FiX8, { size: 16 })
|
|
13500
13577
|
))),
|
|
13501
|
-
/* @__PURE__ */
|
|
13502
|
-
"
|
|
13578
|
+
/* @__PURE__ */ React28.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col border-r border-white/10 w-[20%] min-w-[280px] max-w-[460px] bg-slate-900 flex-none" }, /* @__PURE__ */ React28.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ React28.createElement("div", { className: "relative group" }, /* @__PURE__ */ React28.createElement(FiSearch8, { className: "absolute left-3 top-1/2 -translate-y-1/2 text-slate-500 group-focus-within:text-indigo-400 transition-colors" }), /* @__PURE__ */ React28.createElement(
|
|
13579
|
+
"input",
|
|
13503
13580
|
{
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
|
|
13515
|
-
), /* @__PURE__ */ React26.createElement(
|
|
13516
|
-
"input",
|
|
13581
|
+
type: "text",
|
|
13582
|
+
placeholder: "Navegar nas ancestralidades e nodes\u2026",
|
|
13583
|
+
className: "w-full rounded-md pl-9 pr-4 py-2 text-sm bg-slate-950 border border-white/10 text-slate-200 placeholder-slate-600 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-all",
|
|
13584
|
+
value: searchTerm,
|
|
13585
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
|
13586
|
+
autoFocus: true
|
|
13587
|
+
}
|
|
13588
|
+
))), /* @__PURE__ */ React28.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
|
|
13589
|
+
const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
|
|
13590
|
+
return /* @__PURE__ */ React28.createElement(
|
|
13591
|
+
"div",
|
|
13517
13592
|
{
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
|
|
13523
|
-
|
|
13524
|
-
|
|
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",
|
|
13593
|
+
key: anc.id,
|
|
13594
|
+
className: "group relative flex items-start gap-3 p-3 text-left rounded-lg border border-white/5 bg-slate-800/40 hover:bg-indigo-600/10 hover:border-indigo-500/30 cursor-default transition-all duration-200"
|
|
13595
|
+
},
|
|
13596
|
+
/* @__PURE__ */ React28.createElement("div", { className: "mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border bg-slate-800 border-white/5 group-hover:bg-indigo-500 group-hover:text-white transition-all shadow-lg" }, anc.type === "quest" ? /* @__PURE__ */ React28.createElement(FiCheckSquare4, { size: 14, className: "text-emerald-400 group-hover:text-white" }) : anc.type === "version" ? /* @__PURE__ */ React28.createElement(FiGitBranch4, { size: 14, className: "text-amber-400 group-hover:text-white" }) : anc.type === "node" ? /* @__PURE__ */ React28.createElement(FiBox2, { size: 14, className: "text-slate-400 group-hover:text-white" }) : /* @__PURE__ */ React28.createElement(FiLayers7, { size: 14, className: "text-indigo-400 group-hover:text-white" })),
|
|
13597
|
+
/* @__PURE__ */ React28.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ React28.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React28.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.searchLabel || "Sem Nome"), /* @__PURE__ */ React28.createElement("span", { className: "text-[9px] px-1.5 py-0.5 rounded-full bg-white/5 text-slate-500 border border-white/5 uppercase tracking-tighter" }, anc.type)), anc.type === "ancestry" && /* @__PURE__ */ React28.createElement("div", { className: "flex items-center gap-1.5 mt-0.5 text-[11px] text-slate-500 group-hover:text-indigo-200/70 transition-colors" }, /* @__PURE__ */ React28.createElement(FiCornerUpRight4, { size: 10 }), /* @__PURE__ */ React28.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.searchDesc && /* @__PURE__ */ React28.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.searchDesc)),
|
|
13598
|
+
/* @__PURE__ */ React28.createElement(
|
|
13599
|
+
"button",
|
|
13560
13600
|
{
|
|
13561
|
-
|
|
13562
|
-
|
|
13563
|
-
if (
|
|
13601
|
+
onClick: (e) => {
|
|
13602
|
+
e.stopPropagation();
|
|
13603
|
+
if (onSelect) onSelect(anc);
|
|
13564
13604
|
},
|
|
13565
|
-
className:
|
|
13566
|
-
|
|
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
|
-
`
|
|
13605
|
+
className: "absolute right-2 bottom-2 opacity-0 group-hover:opacity-100 transition-all duration-300 transform translate-y-2 group-hover:translate-y-0 z-10",
|
|
13606
|
+
title: "Focar no cen\xE1rio"
|
|
13569
13607
|
},
|
|
13570
|
-
/* @__PURE__ */
|
|
13571
|
-
|
|
13572
|
-
|
|
13573
|
-
|
|
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(
|
|
13608
|
+
/* @__PURE__ */ React28.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ React28.createElement(FiPlay, { size: 14, className: "ml-0.5" }))
|
|
13609
|
+
)
|
|
13610
|
+
);
|
|
13611
|
+
}))), /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ React28.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ React28.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-3 border-2 border-dashed border-white/5 rounded-xl m-4 bg-slate-900/20" }, /* @__PURE__ */ React28.createElement(FiLayers7, { size: 24, className: "opacity-20" }), /* @__PURE__ */ React28.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ React28.createElement(React28.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ React28.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ React28.createElement(React28.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ React28.createElement(
|
|
13596
13612
|
GroupItem,
|
|
13597
13613
|
{
|
|
13598
13614
|
key: group.id,
|
|
13599
13615
|
index,
|
|
13600
13616
|
group,
|
|
13601
|
-
siblings: groups,
|
|
13602
13617
|
onUpdate: handleUpdateGroup,
|
|
13603
13618
|
onDelete: handleDeleteGroup,
|
|
13604
13619
|
onAddSubgroup: handleAddSubgroup,
|
|
13605
13620
|
onIndent: handleIndent,
|
|
13606
13621
|
onOutdent: handleOutdent,
|
|
13607
|
-
|
|
13608
|
-
|
|
13609
|
-
pickingGroupId,
|
|
13610
|
-
onPlayAncestry: handlePlayFromGroup,
|
|
13611
|
-
availableIds,
|
|
13622
|
+
searchItems: allSearchableItems,
|
|
13623
|
+
onMentionClick: handleMentionClick,
|
|
13612
13624
|
canEdit
|
|
13613
13625
|
}
|
|
13614
13626
|
))))),
|
|
13615
|
-
/* @__PURE__ */
|
|
13627
|
+
/* @__PURE__ */ React28.createElement("div", { className: "px-5 py-2 border-t border-white/10 bg-slate-950/50 text-xs text-slate-500 flex justify-between flex-shrink-0" }, /* @__PURE__ */ React28.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ React28.createElement("span", null, groups.length, " grupos raiz"))
|
|
13616
13628
|
)
|
|
13617
13629
|
);
|
|
13618
13630
|
}
|
|
13619
13631
|
|
|
13620
13632
|
// src/components/MilestoneManager.jsx
|
|
13621
|
-
import
|
|
13633
|
+
import React29, { useState as useState28 } from "react";
|
|
13622
13634
|
import { FiTarget as FiTarget4, FiPlus as FiPlus11, FiTrash2 as FiTrash24, FiX as FiX9, FiCheck as FiCheck12, FiPauseCircle, FiPlayCircle } from "react-icons/fi";
|
|
13623
13635
|
function MilestoneManager({
|
|
13624
13636
|
isOpen,
|
|
@@ -13627,7 +13639,7 @@ function MilestoneManager({
|
|
|
13627
13639
|
onUpdateMilestones = () => {
|
|
13628
13640
|
}
|
|
13629
13641
|
}) {
|
|
13630
|
-
const [newMilestoneName, setNewMilestoneName] =
|
|
13642
|
+
const [newMilestoneName, setNewMilestoneName] = useState28("");
|
|
13631
13643
|
const handleAddMilestone = () => {
|
|
13632
13644
|
if (!newMilestoneName.trim()) return;
|
|
13633
13645
|
const newMilestone = {
|
|
@@ -13652,27 +13664,27 @@ function MilestoneManager({
|
|
|
13652
13664
|
};
|
|
13653
13665
|
if (!isOpen) return null;
|
|
13654
13666
|
const swallow = (e) => e.stopPropagation();
|
|
13655
|
-
return /* @__PURE__ */
|
|
13667
|
+
return /* @__PURE__ */ React29.createElement(
|
|
13656
13668
|
"div",
|
|
13657
13669
|
{
|
|
13658
13670
|
className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-950/40 backdrop-blur-sm animate-in fade-in duration-300",
|
|
13659
13671
|
onClick: onClose
|
|
13660
13672
|
},
|
|
13661
|
-
/* @__PURE__ */
|
|
13673
|
+
/* @__PURE__ */ React29.createElement(
|
|
13662
13674
|
"div",
|
|
13663
13675
|
{
|
|
13664
13676
|
className: "w-full max-w-lg bg-slate-900/90 backdrop-blur-xl border border-white/10 rounded-2xl shadow-2xl flex flex-col max-h-[85vh] animate-in zoom-in-95 duration-300",
|
|
13665
13677
|
onClick: swallow
|
|
13666
13678
|
},
|
|
13667
|
-
/* @__PURE__ */
|
|
13679
|
+
/* @__PURE__ */ React29.createElement("div", { className: "px-6 py-4 border-b border-white/10 flex items-center justify-between" }, /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React29.createElement("div", { className: "p-2 rounded-lg bg-indigo-500/20 text-indigo-400" }, /* @__PURE__ */ React29.createElement(FiTarget4, { size: 20 })), /* @__PURE__ */ React29.createElement("div", null, /* @__PURE__ */ React29.createElement("h2", { className: "text-lg font-semibold text-slate-100" }, "Milestones"), /* @__PURE__ */ React29.createElement("p", { className: "text-xs text-slate-400" }, "Gerencie os marcos do seu cen\xE1rio"))), /* @__PURE__ */ React29.createElement(
|
|
13668
13680
|
"button",
|
|
13669
13681
|
{
|
|
13670
13682
|
onClick: onClose,
|
|
13671
13683
|
className: "p-2 rounded-full hover:bg-white/10 text-slate-400 hover:text-white transition-colors"
|
|
13672
13684
|
},
|
|
13673
|
-
/* @__PURE__ */
|
|
13685
|
+
/* @__PURE__ */ React29.createElement(FiX9, { size: 20 })
|
|
13674
13686
|
)),
|
|
13675
|
-
/* @__PURE__ */
|
|
13687
|
+
/* @__PURE__ */ React29.createElement("div", { className: "px-6 py-5 bg-white/5 border-b border-white/5" }, /* @__PURE__ */ React29.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React29.createElement(
|
|
13676
13688
|
"input",
|
|
13677
13689
|
{
|
|
13678
13690
|
type: "text",
|
|
@@ -13682,47 +13694,47 @@ function MilestoneManager({
|
|
|
13682
13694
|
placeholder: "Adicionar novo milestone...",
|
|
13683
13695
|
className: "flex-1 bg-slate-800/50 border border-white/10 rounded-xl px-4 py-2.5 text-sm text-slate-100 placeholder:text-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/40 focus:border-indigo-500/50 transition-all shadow-inner"
|
|
13684
13696
|
}
|
|
13685
|
-
), /* @__PURE__ */
|
|
13697
|
+
), /* @__PURE__ */ React29.createElement(
|
|
13686
13698
|
"button",
|
|
13687
13699
|
{
|
|
13688
13700
|
onClick: handleAddMilestone,
|
|
13689
13701
|
disabled: !newMilestoneName.trim(),
|
|
13690
13702
|
className: "px-4 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 disabled:opacity-30 disabled:cursor-not-allowed text-white text-sm font-medium transition-all flex items-center gap-2 shadow-lg shadow-indigo-500/20 active:scale-95"
|
|
13691
13703
|
},
|
|
13692
|
-
/* @__PURE__ */
|
|
13704
|
+
/* @__PURE__ */ React29.createElement(FiPlus11, { size: 18 }),
|
|
13693
13705
|
"Adicionar"
|
|
13694
13706
|
))),
|
|
13695
|
-
/* @__PURE__ */
|
|
13707
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex-1 overflow-y-auto px-6 py-4 custom-scrollbar" }, milestones.length > 0 ? /* @__PURE__ */ React29.createElement("div", { className: "space-y-3" }, milestones.map((ms) => /* @__PURE__ */ React29.createElement(
|
|
13696
13708
|
"div",
|
|
13697
13709
|
{
|
|
13698
13710
|
key: ms.id,
|
|
13699
13711
|
className: `group flex items-center justify-between p-4 rounded-xl border transition-all duration-200 ${ms.status === "active" ? "bg-slate-800/40 border-indigo-500/20 hover:border-indigo-500/40" : "bg-slate-900/40 border-white/5 opacity-60 grayscale-[0.3]"}`
|
|
13700
13712
|
},
|
|
13701
|
-
/* @__PURE__ */
|
|
13713
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ React29.createElement(
|
|
13702
13714
|
"div",
|
|
13703
13715
|
{
|
|
13704
13716
|
className: `w-2 h-2 rounded-full shrink-0 ${ms.status === "active" ? "bg-indigo-400 shadow-[0_0_8px_rgba(129,140,248,0.6)]" : "bg-slate-600"}`
|
|
13705
13717
|
}
|
|
13706
|
-
), /* @__PURE__ */
|
|
13707
|
-
/* @__PURE__ */
|
|
13718
|
+
), /* @__PURE__ */ React29.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ React29.createElement("span", { className: `text-sm font-medium truncate ${ms.status === "active" ? "text-slate-100" : "text-slate-400 line-through"}` }, ms.name), /* @__PURE__ */ React29.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-wider" }, ms.status === "active" ? "Ativo" : "Inativo"))),
|
|
13719
|
+
/* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React29.createElement(
|
|
13708
13720
|
"button",
|
|
13709
13721
|
{
|
|
13710
13722
|
onClick: () => handleToggleMilestoneStatus(ms.id),
|
|
13711
13723
|
className: `p-2 rounded-lg transition-all ${ms.status === "active" ? "hover:bg-slate-700 text-slate-400" : "hover:bg-indigo-500/20 text-indigo-400"}`,
|
|
13712
13724
|
title: ms.status === "active" ? "Inativar" : "Ativar"
|
|
13713
13725
|
},
|
|
13714
|
-
ms.status === "active" ? /* @__PURE__ */
|
|
13715
|
-
), /* @__PURE__ */
|
|
13726
|
+
ms.status === "active" ? /* @__PURE__ */ React29.createElement(FiPauseCircle, { size: 18 }) : /* @__PURE__ */ React29.createElement(FiPlayCircle, { size: 18 })
|
|
13727
|
+
), /* @__PURE__ */ React29.createElement(
|
|
13716
13728
|
"button",
|
|
13717
13729
|
{
|
|
13718
13730
|
onClick: () => handleRemoveMilestone(ms.id),
|
|
13719
13731
|
className: "p-2 rounded-lg hover:bg-red-500/20 text-slate-500 hover:text-red-400 transition-all",
|
|
13720
13732
|
title: "Remover"
|
|
13721
13733
|
},
|
|
13722
|
-
/* @__PURE__ */
|
|
13734
|
+
/* @__PURE__ */ React29.createElement(FiTrash24, { size: 18 })
|
|
13723
13735
|
))
|
|
13724
|
-
))) : /* @__PURE__ */
|
|
13725
|
-
/* @__PURE__ */
|
|
13736
|
+
))) : /* @__PURE__ */ React29.createElement("div", { className: "flex flex-col items-center justify-center py-12 text-center" }, /* @__PURE__ */ React29.createElement("div", { className: "p-4 rounded-full bg-slate-800/30 text-slate-600 mb-4" }, /* @__PURE__ */ React29.createElement(FiTarget4, { size: 40 })), /* @__PURE__ */ React29.createElement("h3", { className: "text-slate-400 font-medium" }, "Nenhum milestone definido"), /* @__PURE__ */ React29.createElement("p", { className: "text-xs text-slate-600 max-w-[200px] mt-1 italic" }, "Defina marcos importantes para orientar o progresso do projeto."))),
|
|
13737
|
+
/* @__PURE__ */ React29.createElement("div", { className: "px-6 py-4 border-t border-white/5 bg-slate-900/50 flex items-center justify-between rounded-b-2xl" }, /* @__PURE__ */ React29.createElement("div", { className: "flex gap-4" }, /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React29.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Total:"), /* @__PURE__ */ React29.createElement("span", { className: "text-xs font-bold text-slate-300" }, milestones.length)), /* @__PURE__ */ React29.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React29.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Ativos:"), /* @__PURE__ */ React29.createElement("span", { className: "text-xs font-bold text-indigo-400" }, milestones.filter((m) => m.status === "active").length))))
|
|
13726
13738
|
)
|
|
13727
13739
|
);
|
|
13728
13740
|
}
|
|
@@ -13808,13 +13820,13 @@ function XViewScene({
|
|
|
13808
13820
|
check_user_permission,
|
|
13809
13821
|
get_view_members
|
|
13810
13822
|
}) {
|
|
13811
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l
|
|
13823
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
13812
13824
|
const { data: session, status } = useSession();
|
|
13813
13825
|
const router = useRouter();
|
|
13814
13826
|
const searchParams = useSearchParams();
|
|
13815
13827
|
const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
|
|
13816
13828
|
const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
|
|
13817
|
-
const viewParams =
|
|
13829
|
+
const viewParams = useMemo13(() => {
|
|
13818
13830
|
if (encryptedConfig) {
|
|
13819
13831
|
const data = decryptData(encryptedConfig);
|
|
13820
13832
|
if (data) {
|
|
@@ -13823,7 +13835,7 @@ function XViewScene({
|
|
|
13823
13835
|
}
|
|
13824
13836
|
return null;
|
|
13825
13837
|
}, [encryptedConfig, session]);
|
|
13826
|
-
|
|
13838
|
+
useEffect24(() => {
|
|
13827
13839
|
async function verifyPermission() {
|
|
13828
13840
|
if (!viewParams || !session || !check_user_permission) return;
|
|
13829
13841
|
const { id, type, owner_id } = viewParams;
|
|
@@ -13860,65 +13872,65 @@ function XViewScene({
|
|
|
13860
13872
|
setIsLoading(false);
|
|
13861
13873
|
}
|
|
13862
13874
|
}, [viewParams, session, status, check_user_permission]);
|
|
13863
|
-
const sceneConfigId =
|
|
13864
|
-
const ownerId =
|
|
13865
|
-
const dbSaveUrl =
|
|
13875
|
+
const sceneConfigId = useMemo13(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
|
|
13876
|
+
const ownerId = useMemo13(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
|
|
13877
|
+
const dbSaveUrl = useMemo13(() => {
|
|
13866
13878
|
if (ownerId && sceneConfigId) {
|
|
13867
13879
|
return `x_view_dbs/${ownerId}/${sceneConfigId}`;
|
|
13868
13880
|
}
|
|
13869
13881
|
return null;
|
|
13870
13882
|
}, [ownerId, sceneConfigId]);
|
|
13871
|
-
const sceneSaveUrl =
|
|
13883
|
+
const sceneSaveUrl = useMemo13(() => {
|
|
13872
13884
|
if (ownerId && sceneConfigId) {
|
|
13873
13885
|
return `x_view_scenes/${ownerId}/${sceneConfigId}`;
|
|
13874
13886
|
}
|
|
13875
13887
|
return null;
|
|
13876
13888
|
}, [ownerId, sceneConfigId]);
|
|
13877
|
-
const ancestry_save_url =
|
|
13889
|
+
const ancestry_save_url = useMemo13(() => {
|
|
13878
13890
|
if (ownerId && sceneConfigId) {
|
|
13879
13891
|
return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
|
|
13880
13892
|
}
|
|
13881
13893
|
return null;
|
|
13882
13894
|
}, [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] =
|
|
13895
|
+
const sceneDataRef = useRef20(null);
|
|
13896
|
+
const parentDataRef = useRef20(null);
|
|
13897
|
+
const ancestryDataRef = useRef20(null);
|
|
13898
|
+
const [isLoading, setIsLoading] = useState29(true);
|
|
13899
|
+
const [permissionStatus, setPermissionStatus] = useState29("loading");
|
|
13900
|
+
const [userPermissionRole, setUserPermissionRole] = useState29(null);
|
|
13901
|
+
const [viewMembers, setViewMembers] = useState29([]);
|
|
13902
|
+
const [isInitialized, setIsInitialized] = useState29(false);
|
|
13903
|
+
const [sceneVersion, setSceneVersion] = useState29(0);
|
|
13904
|
+
const [contextMenu, setContextMenu] = useState29({
|
|
13893
13905
|
visible: false,
|
|
13894
13906
|
x: 0,
|
|
13895
13907
|
y: 0,
|
|
13896
13908
|
nodeData: null
|
|
13897
13909
|
});
|
|
13898
|
-
const [multiContextMenu, setMultiContextMenu] =
|
|
13910
|
+
const [multiContextMenu, setMultiContextMenu] = useState29({
|
|
13899
13911
|
visible: false,
|
|
13900
13912
|
x: 0,
|
|
13901
13913
|
y: 0,
|
|
13902
13914
|
nodeIds: null
|
|
13903
13915
|
});
|
|
13904
|
-
const [relationshipMenu, setRelationshipMenu] =
|
|
13916
|
+
const [relationshipMenu, setRelationshipMenu] = useState29({
|
|
13905
13917
|
visible: false,
|
|
13906
13918
|
x: 0,
|
|
13907
13919
|
y: 0,
|
|
13908
13920
|
linkObject: null
|
|
13909
13921
|
});
|
|
13910
|
-
const [creationMode, setCreationMode] =
|
|
13922
|
+
const [creationMode, setCreationMode] = useState29({
|
|
13911
13923
|
isActive: false,
|
|
13912
13924
|
sourceNodeData: null
|
|
13913
13925
|
});
|
|
13914
|
-
const [versionMode, setVersionMode] =
|
|
13926
|
+
const [versionMode, setVersionMode] = useState29({
|
|
13915
13927
|
isActive: false,
|
|
13916
13928
|
sourceNodeData: null
|
|
13917
13929
|
});
|
|
13918
|
-
const [questMode, setQuestMode] =
|
|
13919
|
-
const [hasFocusedInitial, setHasFocusedInitial] =
|
|
13920
|
-
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] =
|
|
13921
|
-
const [ancestryMode, setAncestryMode] =
|
|
13930
|
+
const [questMode, setQuestMode] = useState29({ isActive: false });
|
|
13931
|
+
const [hasFocusedInitial, setHasFocusedInitial] = useState29(false);
|
|
13932
|
+
const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState29(false);
|
|
13933
|
+
const [ancestryMode, setAncestryMode] = useState29({
|
|
13922
13934
|
isActive: false,
|
|
13923
13935
|
tree: null,
|
|
13924
13936
|
selectedParentId: null,
|
|
@@ -13929,42 +13941,42 @@ function XViewScene({
|
|
|
13929
13941
|
ancestryDescriptionSections: [],
|
|
13930
13942
|
isAddingNodes: false
|
|
13931
13943
|
});
|
|
13932
|
-
const [readingMode, setReadingMode] =
|
|
13944
|
+
const [readingMode, setReadingMode] = useState29({
|
|
13933
13945
|
isActive: false,
|
|
13934
13946
|
ancestry: null,
|
|
13935
13947
|
branchStack: [],
|
|
13936
13948
|
autoAbstraction: false
|
|
13937
13949
|
});
|
|
13938
|
-
const [formPosition, setFormPosition] =
|
|
13950
|
+
const [formPosition, setFormPosition] = useState29({
|
|
13939
13951
|
left: 16,
|
|
13940
13952
|
top: 16,
|
|
13941
13953
|
opacity: 0
|
|
13942
13954
|
});
|
|
13943
|
-
const [detailsNode, setDetailsNode] =
|
|
13944
|
-
const [detailsLink, setDetailsLink] =
|
|
13945
|
-
const [ancestryLinkDetails, setAncestryLinkDetails] =
|
|
13946
|
-
const [imageViewer, setImageViewer] =
|
|
13955
|
+
const [detailsNode, setDetailsNode] = useState29(null);
|
|
13956
|
+
const [detailsLink, setDetailsLink] = useState29(null);
|
|
13957
|
+
const [ancestryLinkDetails, setAncestryLinkDetails] = useState29(null);
|
|
13958
|
+
const [imageViewer, setImageViewer] = useState29({
|
|
13947
13959
|
visible: false,
|
|
13948
13960
|
images: [],
|
|
13949
13961
|
startIndex: 0
|
|
13950
13962
|
});
|
|
13951
|
-
const [editingAncestryRel, setEditingAncestryRel] =
|
|
13963
|
+
const [editingAncestryRel, setEditingAncestryRel] = useState29({
|
|
13952
13964
|
visible: false,
|
|
13953
13965
|
data: null,
|
|
13954
13966
|
path: null
|
|
13955
13967
|
});
|
|
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 =
|
|
13968
|
+
const [isImportModalOpen, setIsImportModalOpen] = useState29(false);
|
|
13969
|
+
const [importSuccessMessage, setImportSuccessMessage] = useState29("");
|
|
13970
|
+
const [invalidTargetError, setInvalidTargetError] = useState29(null);
|
|
13971
|
+
const [highlightedNodeId, setHighlightedNodeId] = useState29(null);
|
|
13972
|
+
const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState29(false);
|
|
13973
|
+
const [ancestryBoardData, setAncestryBoardData] = useState29([]);
|
|
13974
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState29(false);
|
|
13975
|
+
const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = useState29(false);
|
|
13976
|
+
const mountRef = useRef20(null);
|
|
13977
|
+
const tooltipRef = useRef20(null);
|
|
13978
|
+
const formRef = useRef20(null);
|
|
13979
|
+
const stateRef = useRef20({
|
|
13968
13980
|
readMode: {
|
|
13969
13981
|
currentMaxIndex: 0,
|
|
13970
13982
|
progressMap: {}
|
|
@@ -14028,10 +14040,10 @@ function XViewScene({
|
|
|
14028
14040
|
minWidth: 320,
|
|
14029
14041
|
maxWidth: maxReadPanelW
|
|
14030
14042
|
});
|
|
14031
|
-
|
|
14043
|
+
useEffect24(() => {
|
|
14032
14044
|
stateRef.current.ancestry = ancestryMode;
|
|
14033
14045
|
}, [ancestryMode]);
|
|
14034
|
-
|
|
14046
|
+
useEffect24(() => {
|
|
14035
14047
|
var _a2;
|
|
14036
14048
|
if (!isInitialized) return;
|
|
14037
14049
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -14054,10 +14066,10 @@ function XViewScene({
|
|
|
14054
14066
|
}
|
|
14055
14067
|
stateRef.current.nodeIdToParentFileMap = map;
|
|
14056
14068
|
}, [isInitialized, sceneVersion]);
|
|
14057
|
-
const handleNavigateBack =
|
|
14069
|
+
const handleNavigateBack = useCallback5(() => {
|
|
14058
14070
|
router.push("/dashboard/scenes");
|
|
14059
14071
|
}, [router]);
|
|
14060
|
-
const handleConfirmImport =
|
|
14072
|
+
const handleConfirmImport = useCallback5(
|
|
14061
14073
|
async (importPayload) => {
|
|
14062
14074
|
var _a2, _b2;
|
|
14063
14075
|
let files = [];
|
|
@@ -14185,7 +14197,7 @@ function XViewScene({
|
|
|
14185
14197
|
const handleOpenImageViewer = (images, startIndex) => {
|
|
14186
14198
|
setImageViewer({ visible: true, images, startIndex });
|
|
14187
14199
|
};
|
|
14188
|
-
const tweenToTarget =
|
|
14200
|
+
const tweenToTarget = useCallback5(
|
|
14189
14201
|
(target, zoomFactor = 1, forcedDirection = null) => {
|
|
14190
14202
|
const { camera, controls, tweenGroup } = stateRef.current;
|
|
14191
14203
|
if (!camera || !controls || !tweenGroup) return;
|
|
@@ -14211,7 +14223,7 @@ function XViewScene({
|
|
|
14211
14223
|
if (!t || typeof t.closest !== "function") return false;
|
|
14212
14224
|
return !!t.closest(".ui-overlay");
|
|
14213
14225
|
};
|
|
14214
|
-
const buildFullAncestryTree =
|
|
14226
|
+
const buildFullAncestryTree = useCallback5(
|
|
14215
14227
|
(idTree, nodes, ancestries = []) => {
|
|
14216
14228
|
if (!idTree) return null;
|
|
14217
14229
|
const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
|
|
@@ -14296,7 +14308,7 @@ function XViewScene({
|
|
|
14296
14308
|
},
|
|
14297
14309
|
[]
|
|
14298
14310
|
);
|
|
14299
|
-
const handleActivateTimeline =
|
|
14311
|
+
const handleActivateTimeline = useCallback5(() => {
|
|
14300
14312
|
const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
14301
14313
|
if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
|
|
14302
14314
|
while (timelineIntervalsGroup.children.length > 0) {
|
|
@@ -14456,7 +14468,7 @@ function XViewScene({
|
|
|
14456
14468
|
}
|
|
14457
14469
|
});
|
|
14458
14470
|
}, []);
|
|
14459
|
-
const handleVersionTimeline =
|
|
14471
|
+
const handleVersionTimeline = useCallback5((sourceMesh, versionMeshes) => {
|
|
14460
14472
|
const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
|
|
14461
14473
|
if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0)
|
|
14462
14474
|
return;
|
|
@@ -14593,7 +14605,7 @@ function XViewScene({
|
|
|
14593
14605
|
}
|
|
14594
14606
|
});
|
|
14595
14607
|
}, []);
|
|
14596
|
-
|
|
14608
|
+
useEffect24(() => {
|
|
14597
14609
|
async function fetchAllData(configPath, ownerId2) {
|
|
14598
14610
|
var _a2, _b2;
|
|
14599
14611
|
if (!get_scene_view_data) {
|
|
@@ -14698,12 +14710,12 @@ function XViewScene({
|
|
|
14698
14710
|
focusNodeId,
|
|
14699
14711
|
focusAncestryId
|
|
14700
14712
|
]);
|
|
14701
|
-
const isNodeInView =
|
|
14713
|
+
const isNodeInView = useCallback5((id) => {
|
|
14702
14714
|
const key = String(id);
|
|
14703
14715
|
const objs = stateRef.current.nodeObjects || {};
|
|
14704
14716
|
return !!objs[key];
|
|
14705
14717
|
}, []);
|
|
14706
|
-
const addOrUpdateNodeMesh =
|
|
14718
|
+
const addOrUpdateNodeMesh = useCallback5(
|
|
14707
14719
|
(nodeData, position, suppressVersionUpdate = false, forceShowQuestDate = false) => {
|
|
14708
14720
|
const {
|
|
14709
14721
|
graphGroup,
|
|
@@ -14744,7 +14756,7 @@ function XViewScene({
|
|
|
14744
14756
|
},
|
|
14745
14757
|
[]
|
|
14746
14758
|
);
|
|
14747
|
-
const handleActivateQuestLens =
|
|
14759
|
+
const handleActivateQuestLens = useCallback5(({ assigneeId, status: status2, milestoneId }) => {
|
|
14748
14760
|
var _a2;
|
|
14749
14761
|
const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
|
|
14750
14762
|
if (!nodeObjects || !tweenGroup || !graphGroup) return;
|
|
@@ -14958,7 +14970,7 @@ function XViewScene({
|
|
|
14958
14970
|
camTween.start();
|
|
14959
14971
|
}
|
|
14960
14972
|
}, [addOrUpdateNodeMesh]);
|
|
14961
|
-
|
|
14973
|
+
useEffect24(() => {
|
|
14962
14974
|
if (!isInitialized || !sceneDataRef.current) return;
|
|
14963
14975
|
const currentMount = mountRef.current;
|
|
14964
14976
|
if (!currentMount) return;
|
|
@@ -15714,7 +15726,7 @@ function XViewScene({
|
|
|
15714
15726
|
get_scene_view_data,
|
|
15715
15727
|
save_view_data
|
|
15716
15728
|
]);
|
|
15717
|
-
const handleGhostNodeImageChange =
|
|
15729
|
+
const handleGhostNodeImageChange = useCallback5((useImage, imageUrl) => {
|
|
15718
15730
|
const {
|
|
15719
15731
|
node: ghostNode,
|
|
15720
15732
|
line: ghostLine,
|
|
@@ -15762,7 +15774,7 @@ function XViewScene({
|
|
|
15762
15774
|
aura: newGhostNode.getObjectByName("aura")
|
|
15763
15775
|
};
|
|
15764
15776
|
}, []);
|
|
15765
|
-
const handleGhostNodeIntensityChange =
|
|
15777
|
+
const handleGhostNodeIntensityChange = useCallback5((newIntensity) => {
|
|
15766
15778
|
const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
|
|
15767
15779
|
if (!ghostNode) return;
|
|
15768
15780
|
const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
|
|
@@ -15783,7 +15795,7 @@ function XViewScene({
|
|
|
15783
15795
|
ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
|
|
15784
15796
|
}
|
|
15785
15797
|
}, []);
|
|
15786
|
-
const handleDetailNodeIntensityChange =
|
|
15798
|
+
const handleDetailNodeIntensityChange = useCallback5(
|
|
15787
15799
|
(nodeId, newIntensity) => {
|
|
15788
15800
|
const mesh = stateRef.current.nodeObjects[String(nodeId)];
|
|
15789
15801
|
if (!mesh) return;
|
|
@@ -15939,7 +15951,7 @@ function XViewScene({
|
|
|
15939
15951
|
mountRef.current.style.cursor = "default";
|
|
15940
15952
|
}
|
|
15941
15953
|
};
|
|
15942
|
-
const handleAncestryTreeUpdate =
|
|
15954
|
+
const handleAncestryTreeUpdate = useCallback5((newTree, extraData = null) => {
|
|
15943
15955
|
setAncestryMode((prev) => {
|
|
15944
15956
|
const prevTreeStr = JSON.stringify(prev.tree);
|
|
15945
15957
|
const newTreeStr = JSON.stringify(newTree);
|
|
@@ -15962,7 +15974,7 @@ function XViewScene({
|
|
|
15962
15974
|
};
|
|
15963
15975
|
});
|
|
15964
15976
|
}, []);
|
|
15965
|
-
const actionHandlerContext =
|
|
15977
|
+
const actionHandlerContext = useMemo13(
|
|
15966
15978
|
() => {
|
|
15967
15979
|
var _a2;
|
|
15968
15980
|
return {
|
|
@@ -16023,7 +16035,7 @@ function XViewScene({
|
|
|
16023
16035
|
const handleStartVersioning = (nodeData) => {
|
|
16024
16036
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
16025
16037
|
};
|
|
16026
|
-
const handleStartQuestQuick =
|
|
16038
|
+
const handleStartQuestQuick = useCallback5((questNode) => {
|
|
16027
16039
|
var _a2, _b2, _c2;
|
|
16028
16040
|
if (!questNode || !actionHandlerContext) return;
|
|
16029
16041
|
const allParentNodes = Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
|
|
@@ -16058,7 +16070,7 @@ function XViewScene({
|
|
|
16058
16070
|
}
|
|
16059
16071
|
setDetailsNode(updatedNode);
|
|
16060
16072
|
}, [session, actionHandlerContext]);
|
|
16061
|
-
const handleFinishQuestQuick =
|
|
16073
|
+
const handleFinishQuestQuick = useCallback5((questNode) => {
|
|
16062
16074
|
var _a2, _b2, _c2, _d2;
|
|
16063
16075
|
if (!questNode || !actionHandlerContext) return;
|
|
16064
16076
|
const {
|
|
@@ -16132,7 +16144,7 @@ function XViewScene({
|
|
|
16132
16144
|
setDetailsNode(null);
|
|
16133
16145
|
}
|
|
16134
16146
|
}, [session, actionHandlerContext, viewMembers, detailsNode]);
|
|
16135
|
-
const handleCancelQuest =
|
|
16147
|
+
const handleCancelQuest = useCallback5(() => {
|
|
16136
16148
|
const { graphGroup, ghostElements } = stateRef.current;
|
|
16137
16149
|
if (ghostElements.node && graphGroup) {
|
|
16138
16150
|
if (ghostElements.node.userData.labelObject) {
|
|
@@ -16191,13 +16203,15 @@ function XViewScene({
|
|
|
16191
16203
|
try {
|
|
16192
16204
|
await actions.save_view_data(sceneSaveUrl2, sceneFileData);
|
|
16193
16205
|
sceneDataRef2.current.quest_counter = currentCounter + 1;
|
|
16194
|
-
sceneDataRef2.current.quest_nodes = sceneFileData.quest_nodes;
|
|
16195
|
-
sceneDataRef2.current.quest_links = sceneFileData.quest_links;
|
|
16196
16206
|
stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
16197
16207
|
parentFileId: sceneConfigId2,
|
|
16198
16208
|
ownerId: ownerId2,
|
|
16199
16209
|
datasetName: "Quests Internas (View)"
|
|
16200
16210
|
});
|
|
16211
|
+
sceneDataRef2.current.quest_nodes = [...graphDataRef.current[sceneConfigId2].nodes];
|
|
16212
|
+
if (parentDataRef.current[sceneConfigId2]) {
|
|
16213
|
+
parentDataRef.current[sceneConfigId2].nodes = [...graphDataRef.current[sceneConfigId2].nodes];
|
|
16214
|
+
}
|
|
16201
16215
|
const finalPosition = stateRef2.current.ghostElements.node ? stateRef2.current.ghostElements.node.position.clone() : stateRef2.current.controls.target.clone();
|
|
16202
16216
|
const { graphGroup, ghostElements } = stateRef2.current;
|
|
16203
16217
|
if (ghostElements.node && graphGroup) {
|
|
@@ -16287,7 +16301,7 @@ function XViewScene({
|
|
|
16287
16301
|
}
|
|
16288
16302
|
userActionHandlers.handleCancelConnection(context);
|
|
16289
16303
|
};
|
|
16290
|
-
const handleClearAncestryVisuals =
|
|
16304
|
+
const handleClearAncestryVisuals = useCallback5((ancestryId) => {
|
|
16291
16305
|
const { renderedAncestries, ancestryGroup } = stateRef.current;
|
|
16292
16306
|
const renderIndex = renderedAncestries.findIndex(
|
|
16293
16307
|
(a) => String(a.id) === String(ancestryId)
|
|
@@ -16305,7 +16319,7 @@ function XViewScene({
|
|
|
16305
16319
|
);
|
|
16306
16320
|
}
|
|
16307
16321
|
}, []);
|
|
16308
|
-
const handleRenderAncestry =
|
|
16322
|
+
const handleRenderAncestry = useCallback5(
|
|
16309
16323
|
async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
|
|
16310
16324
|
setContextMenu(
|
|
16311
16325
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -16799,7 +16813,7 @@ function XViewScene({
|
|
|
16799
16813
|
ancestryMode.isActive
|
|
16800
16814
|
]
|
|
16801
16815
|
);
|
|
16802
|
-
const handleRenderAbstractionTree =
|
|
16816
|
+
const handleRenderAbstractionTree = useCallback5(
|
|
16803
16817
|
(ancestryObject, targetNodeId = null) => {
|
|
16804
16818
|
setContextMenu(
|
|
16805
16819
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -16887,7 +16901,7 @@ function XViewScene({
|
|
|
16887
16901
|
handleClearAncestryVisuals
|
|
16888
16902
|
]
|
|
16889
16903
|
);
|
|
16890
|
-
const handleReadModeBranchNav =
|
|
16904
|
+
const handleReadModeBranchNav = useCallback5(
|
|
16891
16905
|
(nodeId, action, direction = "right") => {
|
|
16892
16906
|
const { ancestry, branchStack } = readingMode;
|
|
16893
16907
|
if (!ancestry || !ancestry.tree) return;
|
|
@@ -17065,13 +17079,13 @@ function XViewScene({
|
|
|
17065
17079
|
},
|
|
17066
17080
|
[readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]
|
|
17067
17081
|
);
|
|
17068
|
-
const handleReadModeHighlight =
|
|
17082
|
+
const handleReadModeHighlight = useCallback5((nodeId) => {
|
|
17069
17083
|
if (stateRef.current.highlightedNodeId !== nodeId) {
|
|
17070
17084
|
stateRef.current.highlightedNodeId = nodeId;
|
|
17071
17085
|
}
|
|
17072
17086
|
setHighlightedNodeId(nodeId);
|
|
17073
17087
|
}, []);
|
|
17074
|
-
const activeNodeBranches =
|
|
17088
|
+
const activeNodeBranches = useMemo13(() => {
|
|
17075
17089
|
if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree)
|
|
17076
17090
|
return null;
|
|
17077
17091
|
const fullTree = buildFullAncestryTree(
|
|
@@ -17115,7 +17129,7 @@ function XViewScene({
|
|
|
17115
17129
|
readingMode.branchStack,
|
|
17116
17130
|
ancestryDataRef.current
|
|
17117
17131
|
]);
|
|
17118
|
-
const backNavigationInfo =
|
|
17132
|
+
const backNavigationInfo = useMemo13(() => {
|
|
17119
17133
|
const { branchStack } = readingMode;
|
|
17120
17134
|
if (!branchStack || branchStack.length === 0) return null;
|
|
17121
17135
|
const lastStep = branchStack[branchStack.length - 1];
|
|
@@ -17126,7 +17140,7 @@ function XViewScene({
|
|
|
17126
17140
|
name: "Voltar para anterior"
|
|
17127
17141
|
};
|
|
17128
17142
|
}, [readingMode.branchStack]);
|
|
17129
|
-
const getReadModeDisplayContext =
|
|
17143
|
+
const getReadModeDisplayContext = useMemo13(() => {
|
|
17130
17144
|
const { ancestry, branchStack } = readingMode;
|
|
17131
17145
|
if (!ancestry) return null;
|
|
17132
17146
|
if (branchStack.length === 0) {
|
|
@@ -17169,7 +17183,7 @@ function XViewScene({
|
|
|
17169
17183
|
customProperties: branchProps
|
|
17170
17184
|
};
|
|
17171
17185
|
}, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
|
|
17172
|
-
const readModeAbstractionTree =
|
|
17186
|
+
const readModeAbstractionTree = useMemo13(() => {
|
|
17173
17187
|
if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
|
|
17174
17188
|
return null;
|
|
17175
17189
|
}
|
|
@@ -17188,7 +17202,7 @@ function XViewScene({
|
|
|
17188
17202
|
buildFullAncestryTree,
|
|
17189
17203
|
sceneVersion
|
|
17190
17204
|
]);
|
|
17191
|
-
const handleStartReadingAncestry =
|
|
17205
|
+
const handleStartReadingAncestry = useCallback5(
|
|
17192
17206
|
async (ancestryObject, renderMode = "full") => {
|
|
17193
17207
|
setContextMenu(
|
|
17194
17208
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -17231,7 +17245,7 @@ function XViewScene({
|
|
|
17231
17245
|
},
|
|
17232
17246
|
[handleRenderAncestry, handleRenderAbstractionTree]
|
|
17233
17247
|
);
|
|
17234
|
-
const handleReadModeSectionChange =
|
|
17248
|
+
const handleReadModeSectionChange = useCallback5(
|
|
17235
17249
|
(activeSectionId) => {
|
|
17236
17250
|
const { ancestry, branchStack } = readingMode;
|
|
17237
17251
|
if (!ancestry || !readingMode.isActive) return;
|
|
@@ -17316,10 +17330,10 @@ function XViewScene({
|
|
|
17316
17330
|
ancestryDataRef.current
|
|
17317
17331
|
]
|
|
17318
17332
|
);
|
|
17319
|
-
const handleCloseReadMode =
|
|
17333
|
+
const handleCloseReadMode = useCallback5(() => {
|
|
17320
17334
|
setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
|
|
17321
17335
|
}, []);
|
|
17322
|
-
const handleAncestrySectionChange =
|
|
17336
|
+
const handleAncestrySectionChange = useCallback5(
|
|
17323
17337
|
(activeSectionId, ancestryOverride = null, rotation = 0) => {
|
|
17324
17338
|
var _a2, _b2;
|
|
17325
17339
|
const currentMode = stateRef.current.ancestry;
|
|
@@ -17381,7 +17395,7 @@ function XViewScene({
|
|
|
17381
17395
|
},
|
|
17382
17396
|
[handleRenderAncestry]
|
|
17383
17397
|
);
|
|
17384
|
-
const handleEditAncestry =
|
|
17398
|
+
const handleEditAncestry = useCallback5(
|
|
17385
17399
|
async (ancestryObject) => {
|
|
17386
17400
|
setContextMenu(
|
|
17387
17401
|
(prev) => prev.visible ? { ...prev, visible: false } : prev
|
|
@@ -17436,7 +17450,7 @@ function XViewScene({
|
|
|
17436
17450
|
const handleSelectAncestryParent = (nodeId) => {
|
|
17437
17451
|
setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
|
|
17438
17452
|
};
|
|
17439
|
-
const handleRemoveFromAncestry =
|
|
17453
|
+
const handleRemoveFromAncestry = useCallback5((pathToRemove) => {
|
|
17440
17454
|
if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
|
|
17441
17455
|
console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
|
|
17442
17456
|
return;
|
|
@@ -17461,7 +17475,7 @@ function XViewScene({
|
|
|
17461
17475
|
return { ...prev, tree: newTree };
|
|
17462
17476
|
});
|
|
17463
17477
|
}, []);
|
|
17464
|
-
const handleSaveAncestry =
|
|
17478
|
+
const handleSaveAncestry = useCallback5(
|
|
17465
17479
|
async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
|
|
17466
17480
|
const treeToUse = treeOverride || ancestryMode.tree;
|
|
17467
17481
|
const { isEditMode, currentAncestryId } = ancestryMode;
|
|
@@ -17697,7 +17711,7 @@ function XViewScene({
|
|
|
17697
17711
|
});
|
|
17698
17712
|
setEditingAncestryRel({ visible: false, data: null, path: null });
|
|
17699
17713
|
};
|
|
17700
|
-
const handleDeleteAncestry =
|
|
17714
|
+
const handleDeleteAncestry = useCallback5(
|
|
17701
17715
|
async (ancestryIdToDelete) => {
|
|
17702
17716
|
if (!ancestryIdToDelete) {
|
|
17703
17717
|
alert("ID da ancestralidade n\xE3o encontrado.");
|
|
@@ -17779,28 +17793,70 @@ function XViewScene({
|
|
|
17779
17793
|
},
|
|
17780
17794
|
[save_view_data, delete_file_action]
|
|
17781
17795
|
);
|
|
17782
|
-
const handleOpenAncestryBoard =
|
|
17796
|
+
const handleOpenAncestryBoard = useCallback5(() => {
|
|
17783
17797
|
setIsAncestryBoardOpen(true);
|
|
17784
17798
|
}, []);
|
|
17785
|
-
const
|
|
17799
|
+
const allAvailableNodes = useMemo13(() => {
|
|
17800
|
+
if (!parentDataRef.current) return [];
|
|
17801
|
+
return Object.values(parentDataRef.current).flatMap(
|
|
17802
|
+
(fileData) => fileData.nodes || []
|
|
17803
|
+
);
|
|
17804
|
+
}, [sceneVersion, isInitialized]);
|
|
17805
|
+
const allAvailableAncestries = useMemo13(() => {
|
|
17806
|
+
return ancestryDataRef.current || [];
|
|
17807
|
+
}, [sceneVersion, isInitialized]);
|
|
17808
|
+
const handleOpenReference = useCallback5(
|
|
17809
|
+
(referenceData) => {
|
|
17810
|
+
const { type, id } = referenceData;
|
|
17811
|
+
if (type === "node") {
|
|
17812
|
+
const targetNode = allAvailableNodes.find(
|
|
17813
|
+
(n) => String(n.id) === String(id)
|
|
17814
|
+
);
|
|
17815
|
+
if (targetNode) {
|
|
17816
|
+
setAncestryLinkDetails(null);
|
|
17817
|
+
setDetailsLink(null);
|
|
17818
|
+
setDetailsNode(targetNode);
|
|
17819
|
+
const sceneMesh = stateRef.current.nodeObjects[String(id)];
|
|
17820
|
+
if (sceneMesh) {
|
|
17821
|
+
tweenToTarget(sceneMesh);
|
|
17822
|
+
}
|
|
17823
|
+
} else {
|
|
17824
|
+
alert("Node original n\xE3o encontrado neste contexto.");
|
|
17825
|
+
}
|
|
17826
|
+
} else if (type === "ancestry") {
|
|
17827
|
+
const targetAncestry = allAvailableAncestries.find(
|
|
17828
|
+
(a) => String(a.ancestry_id) === String(id)
|
|
17829
|
+
);
|
|
17830
|
+
if (targetAncestry) {
|
|
17831
|
+
setDetailsNode(null);
|
|
17832
|
+
setDetailsLink(null);
|
|
17833
|
+
setAncestryLinkDetails(null);
|
|
17834
|
+
handleEditAncestry(targetAncestry);
|
|
17835
|
+
} else {
|
|
17836
|
+
alert("Ancestralidade original n\xE3o encontrada neste contexto.");
|
|
17837
|
+
}
|
|
17838
|
+
}
|
|
17839
|
+
},
|
|
17840
|
+
[
|
|
17841
|
+
allAvailableNodes,
|
|
17842
|
+
allAvailableAncestries,
|
|
17843
|
+
handleEditAncestry,
|
|
17844
|
+
tweenToTarget
|
|
17845
|
+
]
|
|
17846
|
+
);
|
|
17847
|
+
const handleSelectAncestryFromBoard = useCallback5(
|
|
17786
17848
|
(item) => {
|
|
17787
17849
|
setIsAncestryBoardOpen(false);
|
|
17788
17850
|
setIsSidebarOpen(false);
|
|
17789
|
-
if (item.type === "ancestry"
|
|
17851
|
+
if (item.type === "ancestry") {
|
|
17790
17852
|
handleStartReadingAncestry(item);
|
|
17791
17853
|
} 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
|
-
}
|
|
17854
|
+
handleOpenReference({ type: "node", id: item.id });
|
|
17799
17855
|
}
|
|
17800
17856
|
},
|
|
17801
|
-
[handleStartReadingAncestry,
|
|
17857
|
+
[handleStartReadingAncestry, handleOpenReference]
|
|
17802
17858
|
);
|
|
17803
|
-
const handleSaveAncestryBoard =
|
|
17859
|
+
const handleSaveAncestryBoard = useCallback5(
|
|
17804
17860
|
async (groups) => {
|
|
17805
17861
|
if (!sceneConfigId || !viewParams || !session) return;
|
|
17806
17862
|
const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
|
|
@@ -17814,7 +17870,7 @@ function XViewScene({
|
|
|
17814
17870
|
},
|
|
17815
17871
|
[sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]
|
|
17816
17872
|
);
|
|
17817
|
-
const existingNodeTypes =
|
|
17873
|
+
const existingNodeTypes = useMemo13(() => {
|
|
17818
17874
|
if (!parentDataRef.current) {
|
|
17819
17875
|
return [];
|
|
17820
17876
|
}
|
|
@@ -17826,28 +17882,22 @@ function XViewScene({
|
|
|
17826
17882
|
).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
|
|
17827
17883
|
return [...new Set(allTypes)];
|
|
17828
17884
|
}, [parentDataRef.current, sceneVersion]);
|
|
17829
|
-
const searchableDbNodes =
|
|
17830
|
-
var _a2;
|
|
17885
|
+
const searchableDbNodes = useMemo13(() => {
|
|
17831
17886
|
if (!parentDataRef.current) {
|
|
17832
17887
|
return [];
|
|
17833
17888
|
}
|
|
17834
|
-
|
|
17889
|
+
return Object.entries(parentDataRef.current).flatMap(([dbId, fileData]) => {
|
|
17835
17890
|
const datasetName = fileData.dataset_name || `Dataset #${dbId.substring(0, 6)}`;
|
|
17836
17891
|
return (fileData.nodes || []).map((node) => ({
|
|
17837
17892
|
...node,
|
|
17838
17893
|
dataset_name: datasetName
|
|
17839
17894
|
}));
|
|
17895
|
+
}).filter((node) => {
|
|
17896
|
+
var _a2;
|
|
17897
|
+
return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
|
|
17840
17898
|
});
|
|
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(
|
|
17899
|
+
}, [parentDataRef.current, sceneVersion]);
|
|
17900
|
+
const handleAddExistingNode = useCallback5(
|
|
17851
17901
|
(nodeId) => {
|
|
17852
17902
|
return userActionHandlers.handleAddExistingNodeById(
|
|
17853
17903
|
actionHandlerContext,
|
|
@@ -17856,7 +17906,7 @@ function XViewScene({
|
|
|
17856
17906
|
},
|
|
17857
17907
|
[actionHandlerContext]
|
|
17858
17908
|
);
|
|
17859
|
-
const handleUpdateMilestones =
|
|
17909
|
+
const handleUpdateMilestones = useCallback5(
|
|
17860
17910
|
async (newMilestones) => {
|
|
17861
17911
|
var _a2, _b2, _c2;
|
|
17862
17912
|
if (!sceneDataRef.current) return;
|
|
@@ -17902,7 +17952,7 @@ function XViewScene({
|
|
|
17902
17952
|
viewParams == null ? void 0 : viewParams.type
|
|
17903
17953
|
]
|
|
17904
17954
|
);
|
|
17905
|
-
const handleSaveCurrentView =
|
|
17955
|
+
const handleSaveCurrentView = useCallback5(async () => {
|
|
17906
17956
|
var _a2, _b2, _c2;
|
|
17907
17957
|
const { nodeObjects, allLinks } = stateRef.current;
|
|
17908
17958
|
if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
|
|
@@ -17945,61 +17995,13 @@ function XViewScene({
|
|
|
17945
17995
|
console.error("Erro na chamada de save_view_data:", error);
|
|
17946
17996
|
}
|
|
17947
17997
|
}, [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(() => {
|
|
17998
|
+
const handleToggleAncestryAddMode = useCallback5(() => {
|
|
17997
17999
|
setAncestryMode((prev) => ({
|
|
17998
18000
|
...prev,
|
|
17999
18001
|
isAddingNodes: !prev.isAddingNodes
|
|
18000
18002
|
}));
|
|
18001
18003
|
}, []);
|
|
18002
|
-
const handleFocusNode =
|
|
18004
|
+
const handleFocusNode = useCallback5(
|
|
18003
18005
|
(nodeData) => {
|
|
18004
18006
|
var _a2;
|
|
18005
18007
|
if (!nodeData) return;
|
|
@@ -18015,7 +18017,7 @@ function XViewScene({
|
|
|
18015
18017
|
},
|
|
18016
18018
|
[tweenToTarget]
|
|
18017
18019
|
);
|
|
18018
|
-
const availableDatasets =
|
|
18020
|
+
const availableDatasets = useMemo13(() => {
|
|
18019
18021
|
if (!sceneDataRef.current || !parentDataRef.current) return [];
|
|
18020
18022
|
return sceneDataRef.current.parent_dbs.map((db) => {
|
|
18021
18023
|
var _a2;
|
|
@@ -18025,11 +18027,11 @@ function XViewScene({
|
|
|
18025
18027
|
};
|
|
18026
18028
|
});
|
|
18027
18029
|
}, [sceneVersion, isInitialized]);
|
|
18028
|
-
const sourceNodeDatasetId = creationMode.sourceNodeData ? (
|
|
18030
|
+
const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(
|
|
18029
18031
|
String(creationMode.sourceNodeData.id)
|
|
18030
|
-
)) == null ? void 0 :
|
|
18032
|
+
)) == null ? void 0 : _b.parentFileId : null;
|
|
18031
18033
|
const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
|
|
18032
|
-
|
|
18034
|
+
useEffect24(() => {
|
|
18033
18035
|
if (isInitialized && focusNodeId && !hasFocusedInitial) {
|
|
18034
18036
|
const nodeObjects = stateRef.current.nodeObjects || {};
|
|
18035
18037
|
const targetMesh = nodeObjects[String(focusNodeId)];
|
|
@@ -18052,7 +18054,7 @@ function XViewScene({
|
|
|
18052
18054
|
hasFocusedInitial,
|
|
18053
18055
|
tweenToTarget
|
|
18054
18056
|
]);
|
|
18055
|
-
|
|
18057
|
+
useEffect24(() => {
|
|
18056
18058
|
if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
|
|
18057
18059
|
const ancestries = ancestryDataRef.current || [];
|
|
18058
18060
|
const targetAncestry = ancestries.find(
|
|
@@ -18077,7 +18079,7 @@ function XViewScene({
|
|
|
18077
18079
|
hasOpenedInitialAncestry,
|
|
18078
18080
|
handleStartReadingAncestry
|
|
18079
18081
|
]);
|
|
18080
|
-
|
|
18082
|
+
useEffect24(() => {
|
|
18081
18083
|
function handleKeyDown(event) {
|
|
18082
18084
|
var _a2, _b2, _c2;
|
|
18083
18085
|
const context = actionHandlerContext;
|
|
@@ -18200,10 +18202,10 @@ function XViewScene({
|
|
|
18200
18202
|
// <-- handleCancelQuest adicionado aqui
|
|
18201
18203
|
]);
|
|
18202
18204
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
18203
|
-
return /* @__PURE__ */
|
|
18205
|
+
return /* @__PURE__ */ React30.createElement(LoadingScreen, null);
|
|
18204
18206
|
}
|
|
18205
18207
|
if (permissionStatus === "denied") {
|
|
18206
|
-
return /* @__PURE__ */
|
|
18208
|
+
return /* @__PURE__ */ React30.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ React30.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ React30.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ React30.createElement(
|
|
18207
18209
|
"svg",
|
|
18208
18210
|
{
|
|
18209
18211
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -18213,7 +18215,7 @@ function XViewScene({
|
|
|
18213
18215
|
stroke: "currentColor",
|
|
18214
18216
|
className: "w-16 h-16 mx-auto"
|
|
18215
18217
|
},
|
|
18216
|
-
/* @__PURE__ */
|
|
18218
|
+
/* @__PURE__ */ React30.createElement(
|
|
18217
18219
|
"path",
|
|
18218
18220
|
{
|
|
18219
18221
|
strokeLinecap: "round",
|
|
@@ -18221,13 +18223,13 @@ function XViewScene({
|
|
|
18221
18223
|
d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
|
|
18222
18224
|
}
|
|
18223
18225
|
)
|
|
18224
|
-
)), /* @__PURE__ */
|
|
18226
|
+
)), /* @__PURE__ */ React30.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ React30.createElement("p", { className: "text-slate-400 mb-6" }, "Voc\xEA n\xE3o tem permiss\xE3o para acessar este conte\xFAdo. Solicite acesso ao propriet\xE1rio ou verifique se est\xE1 na conta correta."), /* @__PURE__ */ React30.createElement(
|
|
18225
18227
|
"button",
|
|
18226
18228
|
{
|
|
18227
18229
|
onClick: () => router.push("/dashboard/scenes"),
|
|
18228
18230
|
className: "flex items-center justify-center gap-2 w-full py-3 px-4 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors font-medium"
|
|
18229
18231
|
},
|
|
18230
|
-
/* @__PURE__ */
|
|
18232
|
+
/* @__PURE__ */ React30.createElement(
|
|
18231
18233
|
"svg",
|
|
18232
18234
|
{
|
|
18233
18235
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -18237,7 +18239,7 @@ function XViewScene({
|
|
|
18237
18239
|
stroke: "currentColor",
|
|
18238
18240
|
className: "w-5 h-5"
|
|
18239
18241
|
},
|
|
18240
|
-
/* @__PURE__ */
|
|
18242
|
+
/* @__PURE__ */ React30.createElement(
|
|
18241
18243
|
"path",
|
|
18242
18244
|
{
|
|
18243
18245
|
strokeLinecap: "round",
|
|
@@ -18249,7 +18251,7 @@ function XViewScene({
|
|
|
18249
18251
|
"Voltar para Scenes"
|
|
18250
18252
|
)));
|
|
18251
18253
|
}
|
|
18252
|
-
return /* @__PURE__ */
|
|
18254
|
+
return /* @__PURE__ */ React30.createElement(
|
|
18253
18255
|
"div",
|
|
18254
18256
|
{
|
|
18255
18257
|
ref: mountRef,
|
|
@@ -18261,7 +18263,7 @@ function XViewScene({
|
|
|
18261
18263
|
cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
|
|
18262
18264
|
}
|
|
18263
18265
|
},
|
|
18264
|
-
userPermissionRole !== "link_viewer" && /* @__PURE__ */
|
|
18266
|
+
userPermissionRole !== "link_viewer" && /* @__PURE__ */ React30.createElement(
|
|
18265
18267
|
XViewSidebar,
|
|
18266
18268
|
{
|
|
18267
18269
|
dbNodes: searchableDbNodes,
|
|
@@ -18281,11 +18283,11 @@ function XViewScene({
|
|
|
18281
18283
|
onToggle: setIsSidebarOpen,
|
|
18282
18284
|
userRole: userPermissionRole,
|
|
18283
18285
|
viewMembers,
|
|
18284
|
-
milestones: ((
|
|
18286
|
+
milestones: ((_c = sceneDataRef.current) == null ? void 0 : _c.milestones) || [],
|
|
18285
18287
|
onOpenMilestoneManager: () => setIsMilestoneManagerOpen(true)
|
|
18286
18288
|
}
|
|
18287
18289
|
),
|
|
18288
|
-
creationMode.isActive && /* @__PURE__ */
|
|
18290
|
+
creationMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18289
18291
|
InSceneCreationForm,
|
|
18290
18292
|
{
|
|
18291
18293
|
onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
|
|
@@ -18306,8 +18308,8 @@ function XViewScene({
|
|
|
18306
18308
|
},
|
|
18307
18309
|
refEl: formRef,
|
|
18308
18310
|
existingTypes: existingNodeTypes,
|
|
18309
|
-
initialColor: (
|
|
18310
|
-
sourceTypes: (
|
|
18311
|
+
initialColor: (_d = creationMode.sourceNodeData) == null ? void 0 : _d.color,
|
|
18312
|
+
sourceTypes: (_e = creationMode.sourceNodeData) == null ? void 0 : _e.type,
|
|
18311
18313
|
onIntensityChange: handleGhostNodeIntensityChange,
|
|
18312
18314
|
onUploadFile: upload_file_action,
|
|
18313
18315
|
availableDatasets,
|
|
@@ -18317,7 +18319,7 @@ function XViewScene({
|
|
|
18317
18319
|
availableAncestries: allAvailableAncestries
|
|
18318
18320
|
}
|
|
18319
18321
|
),
|
|
18320
|
-
versionMode.isActive && /* @__PURE__ */
|
|
18322
|
+
versionMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18321
18323
|
InSceneVersionForm,
|
|
18322
18324
|
{
|
|
18323
18325
|
onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
|
|
@@ -18336,14 +18338,14 @@ function XViewScene({
|
|
|
18336
18338
|
transition: "opacity 200ms ease-out"
|
|
18337
18339
|
},
|
|
18338
18340
|
refEl: formRef,
|
|
18339
|
-
fixedType: (
|
|
18340
|
-
fixedColor: (
|
|
18341
|
+
fixedType: (_f = versionMode.sourceNodeData) == null ? void 0 : _f.type,
|
|
18342
|
+
fixedColor: (_g = versionMode.sourceNodeData) == null ? void 0 : _g.color,
|
|
18341
18343
|
onUploadFile: upload_file_action,
|
|
18342
18344
|
availableNodes: allAvailableNodes,
|
|
18343
18345
|
availableAncestries: allAvailableAncestries
|
|
18344
18346
|
}
|
|
18345
18347
|
),
|
|
18346
|
-
questMode.isActive && /* @__PURE__ */
|
|
18348
|
+
questMode.isActive && /* @__PURE__ */ React30.createElement(
|
|
18347
18349
|
InSceneQuestForm,
|
|
18348
18350
|
{
|
|
18349
18351
|
onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
|
|
@@ -18365,13 +18367,13 @@ function XViewScene({
|
|
|
18365
18367
|
availableNodes: allAvailableNodes,
|
|
18366
18368
|
availableAncestries: allAvailableAncestries,
|
|
18367
18369
|
viewName: viewParams == null ? void 0 : viewParams.name,
|
|
18368
|
-
questCounter: ((
|
|
18370
|
+
questCounter: ((_h = sceneDataRef.current) == null ? void 0 : _h.quest_counter) || 1,
|
|
18369
18371
|
viewMembers,
|
|
18370
|
-
milestones: ((
|
|
18372
|
+
milestones: ((_i = sceneDataRef.current) == null ? void 0 : _i.milestones) || [],
|
|
18371
18373
|
onUpdateMilestones: handleUpdateMilestones
|
|
18372
18374
|
}
|
|
18373
18375
|
),
|
|
18374
|
-
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */
|
|
18376
|
+
readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React30.createElement(
|
|
18375
18377
|
"div",
|
|
18376
18378
|
{
|
|
18377
18379
|
className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col ${isReadModeResizing ? "transition-none" : "transition-all duration-300 ease-out"}`,
|
|
@@ -18384,7 +18386,7 @@ function XViewScene({
|
|
|
18384
18386
|
maxWidth: "92vw"
|
|
18385
18387
|
}
|
|
18386
18388
|
},
|
|
18387
|
-
/* @__PURE__ */
|
|
18389
|
+
/* @__PURE__ */ React30.createElement(
|
|
18388
18390
|
"div",
|
|
18389
18391
|
{
|
|
18390
18392
|
onPointerDown: (e) => {
|
|
@@ -18395,7 +18397,7 @@ function XViewScene({
|
|
|
18395
18397
|
title: "Arraste para redimensionar"
|
|
18396
18398
|
}
|
|
18397
18399
|
),
|
|
18398
|
-
/* @__PURE__ */
|
|
18400
|
+
/* @__PURE__ */ React30.createElement(
|
|
18399
18401
|
DescriptionReadModePanel,
|
|
18400
18402
|
{
|
|
18401
18403
|
key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
|
|
@@ -18430,7 +18432,7 @@ function XViewScene({
|
|
|
18430
18432
|
}
|
|
18431
18433
|
)
|
|
18432
18434
|
),
|
|
18433
|
-
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */
|
|
18435
|
+
ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ React30.createElement(
|
|
18434
18436
|
CreateAncestryPanel,
|
|
18435
18437
|
{
|
|
18436
18438
|
ancestryMode,
|
|
@@ -18466,7 +18468,7 @@ function XViewScene({
|
|
|
18466
18468
|
onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
|
|
18467
18469
|
}
|
|
18468
18470
|
),
|
|
18469
|
-
editingAncestryRel.visible && /* @__PURE__ */
|
|
18471
|
+
editingAncestryRel.visible && /* @__PURE__ */ React30.createElement(
|
|
18470
18472
|
AncestryRelationshipPanel,
|
|
18471
18473
|
{
|
|
18472
18474
|
data: editingAncestryRel.data,
|
|
@@ -18480,7 +18482,7 @@ function XViewScene({
|
|
|
18480
18482
|
onUploadFile: upload_file_action
|
|
18481
18483
|
}
|
|
18482
18484
|
),
|
|
18483
|
-
detailsNode && detailsNode.is_quest && /* @__PURE__ */
|
|
18485
|
+
detailsNode && detailsNode.is_quest && /* @__PURE__ */ React30.createElement(
|
|
18484
18486
|
QuestDetailsPanel,
|
|
18485
18487
|
{
|
|
18486
18488
|
node: detailsNode,
|
|
@@ -18502,11 +18504,11 @@ function XViewScene({
|
|
|
18502
18504
|
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName,
|
|
18503
18505
|
viewMembers,
|
|
18504
18506
|
currentUser: session == null ? void 0 : session.user,
|
|
18505
|
-
milestones: ((
|
|
18507
|
+
milestones: ((_j = sceneDataRef.current) == null ? void 0 : _j.milestones) || [],
|
|
18506
18508
|
onUpdateMilestones: handleUpdateMilestones
|
|
18507
18509
|
}
|
|
18508
18510
|
),
|
|
18509
|
-
detailsNode && !detailsNode.is_quest && /* @__PURE__ */
|
|
18511
|
+
detailsNode && !detailsNode.is_quest && /* @__PURE__ */ React30.createElement(
|
|
18510
18512
|
NodeDetailsPanel,
|
|
18511
18513
|
{
|
|
18512
18514
|
node: detailsNode,
|
|
@@ -18538,7 +18540,7 @@ function XViewScene({
|
|
|
18538
18540
|
currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
|
|
18539
18541
|
}
|
|
18540
18542
|
),
|
|
18541
|
-
detailsLink && /* @__PURE__ */
|
|
18543
|
+
detailsLink && /* @__PURE__ */ React30.createElement(
|
|
18542
18544
|
RelationshipDetailsPanel,
|
|
18543
18545
|
{
|
|
18544
18546
|
link: detailsLink,
|
|
@@ -18552,7 +18554,7 @@ function XViewScene({
|
|
|
18552
18554
|
userRole: userPermissionRole
|
|
18553
18555
|
}
|
|
18554
18556
|
),
|
|
18555
|
-
ancestryLinkDetails && /* @__PURE__ */
|
|
18557
|
+
ancestryLinkDetails && /* @__PURE__ */ React30.createElement(
|
|
18556
18558
|
AncestryLinkDetailsPanel,
|
|
18557
18559
|
{
|
|
18558
18560
|
data: ancestryLinkDetails,
|
|
@@ -18563,7 +18565,7 @@ function XViewScene({
|
|
|
18563
18565
|
onUploadFile: upload_file_action
|
|
18564
18566
|
}
|
|
18565
18567
|
),
|
|
18566
|
-
/* @__PURE__ */
|
|
18568
|
+
/* @__PURE__ */ React30.createElement(
|
|
18567
18569
|
"div",
|
|
18568
18570
|
{
|
|
18569
18571
|
ref: tooltipRef,
|
|
@@ -18590,7 +18592,7 @@ function XViewScene({
|
|
|
18590
18592
|
}
|
|
18591
18593
|
}
|
|
18592
18594
|
),
|
|
18593
|
-
/* @__PURE__ */
|
|
18595
|
+
/* @__PURE__ */ React30.createElement(
|
|
18594
18596
|
ContextMenu,
|
|
18595
18597
|
{
|
|
18596
18598
|
data: contextMenu,
|
|
@@ -18623,7 +18625,7 @@ function XViewScene({
|
|
|
18623
18625
|
onFinishQuest: handleFinishQuestQuick
|
|
18624
18626
|
}
|
|
18625
18627
|
),
|
|
18626
|
-
/* @__PURE__ */
|
|
18628
|
+
/* @__PURE__ */ React30.createElement(
|
|
18627
18629
|
MultiNodeContextMenu,
|
|
18628
18630
|
{
|
|
18629
18631
|
data: multiContextMenu,
|
|
@@ -18643,7 +18645,7 @@ function XViewScene({
|
|
|
18643
18645
|
)
|
|
18644
18646
|
}
|
|
18645
18647
|
),
|
|
18646
|
-
/* @__PURE__ */
|
|
18648
|
+
/* @__PURE__ */ React30.createElement(
|
|
18647
18649
|
RelationshipContextMenu,
|
|
18648
18650
|
{
|
|
18649
18651
|
data: relationshipMenu,
|
|
@@ -18661,14 +18663,14 @@ function XViewScene({
|
|
|
18661
18663
|
onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
|
|
18662
18664
|
}
|
|
18663
18665
|
),
|
|
18664
|
-
/* @__PURE__ */
|
|
18666
|
+
/* @__PURE__ */ React30.createElement(
|
|
18665
18667
|
ImageViewer,
|
|
18666
18668
|
{
|
|
18667
18669
|
data: imageViewer,
|
|
18668
18670
|
onClose: () => setImageViewer({ ...imageViewer, visible: false })
|
|
18669
18671
|
}
|
|
18670
18672
|
),
|
|
18671
|
-
/* @__PURE__ */
|
|
18673
|
+
/* @__PURE__ */ React30.createElement(
|
|
18672
18674
|
AncestryBoard,
|
|
18673
18675
|
{
|
|
18674
18676
|
isOpen: isAncestryBoardOpen,
|
|
@@ -18681,29 +18683,29 @@ function XViewScene({
|
|
|
18681
18683
|
userRole: userPermissionRole
|
|
18682
18684
|
}
|
|
18683
18685
|
),
|
|
18684
|
-
/* @__PURE__ */
|
|
18686
|
+
/* @__PURE__ */ React30.createElement(
|
|
18685
18687
|
MilestoneManager,
|
|
18686
18688
|
{
|
|
18687
18689
|
isOpen: isMilestoneManagerOpen,
|
|
18688
18690
|
onClose: () => setIsMilestoneManagerOpen(false),
|
|
18689
|
-
milestones: ((
|
|
18691
|
+
milestones: ((_k = sceneDataRef.current) == null ? void 0 : _k.milestones) || [],
|
|
18690
18692
|
onUpdateMilestones: handleUpdateMilestones
|
|
18691
18693
|
}
|
|
18692
18694
|
),
|
|
18693
|
-
/* @__PURE__ */
|
|
18695
|
+
/* @__PURE__ */ React30.createElement(
|
|
18694
18696
|
ImportParentFileModal,
|
|
18695
18697
|
{
|
|
18696
18698
|
isOpen: isImportModalOpen,
|
|
18697
18699
|
onClose: () => setIsImportModalOpen(false),
|
|
18698
18700
|
onConfirm: handleConfirmImport,
|
|
18699
18701
|
session,
|
|
18700
|
-
parentDbs: ((
|
|
18702
|
+
parentDbs: ((_l = sceneDataRef.current) == null ? void 0 : _l.parent_dbs) || [],
|
|
18701
18703
|
onFetchAvailableFiles: import_parent_file_modal_get,
|
|
18702
18704
|
currentViewName: viewParams == null ? void 0 : viewParams.name,
|
|
18703
18705
|
currentAncestries: ancestryDataRef.current || []
|
|
18704
18706
|
}
|
|
18705
18707
|
),
|
|
18706
|
-
invalidTargetError && /* @__PURE__ */
|
|
18708
|
+
invalidTargetError && /* @__PURE__ */ React30.createElement(
|
|
18707
18709
|
"div",
|
|
18708
18710
|
{
|
|
18709
18711
|
className: "ui-overlay",
|
|
@@ -18728,13 +18730,13 @@ function XViewScene({
|
|
|
18728
18730
|
animation: "fadeInDown 0.5s cubic-bezier(0.16, 1, 0.3, 1)"
|
|
18729
18731
|
}
|
|
18730
18732
|
},
|
|
18731
|
-
/* @__PURE__ */
|
|
18733
|
+
/* @__PURE__ */ React30.createElement("style", null, `
|
|
18732
18734
|
@keyframes fadeInDown {
|
|
18733
18735
|
from { opacity: 0; transform: translate(-50%, -20px); }
|
|
18734
18736
|
to { opacity: 1; transform: translate(-50%, 0); }
|
|
18735
18737
|
}
|
|
18736
18738
|
`),
|
|
18737
|
-
/* @__PURE__ */
|
|
18739
|
+
/* @__PURE__ */ React30.createElement(
|
|
18738
18740
|
"svg",
|
|
18739
18741
|
{
|
|
18740
18742
|
width: "20",
|
|
@@ -18746,12 +18748,12 @@ function XViewScene({
|
|
|
18746
18748
|
strokeLinecap: "round",
|
|
18747
18749
|
strokeLinejoin: "round"
|
|
18748
18750
|
},
|
|
18749
|
-
/* @__PURE__ */
|
|
18750
|
-
/* @__PURE__ */
|
|
18751
|
-
/* @__PURE__ */
|
|
18751
|
+
/* @__PURE__ */ React30.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
18752
|
+
/* @__PURE__ */ React30.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
18753
|
+
/* @__PURE__ */ React30.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
18752
18754
|
),
|
|
18753
|
-
/* @__PURE__ */
|
|
18754
|
-
/* @__PURE__ */
|
|
18755
|
+
/* @__PURE__ */ React30.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
|
|
18756
|
+
/* @__PURE__ */ React30.createElement(
|
|
18755
18757
|
"button",
|
|
18756
18758
|
{
|
|
18757
18759
|
onClick: () => setInvalidTargetError(null),
|