@lv-x-software-house/x_view 1.2.6 → 1.2.7-dev.2
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 +697 -520
- package/dist/index.mjs +697 -520
- package/package.json +1 -1
- package/dist/server.js +0 -480
- package/dist/server.mjs +0 -445
package/dist/index.js
CHANGED
|
@@ -15607,7 +15607,7 @@ function XViewScene({
|
|
|
15607
15607
|
stateRef.current.questTree = questTreeMode;
|
|
15608
15608
|
}, [questTreeMode]);
|
|
15609
15609
|
(0, import_react33.useEffect)(() => {
|
|
15610
|
-
var _a2;
|
|
15610
|
+
var _a2, _b2;
|
|
15611
15611
|
if (!isInitialized) return;
|
|
15612
15612
|
const map = /* @__PURE__ */ new Map();
|
|
15613
15613
|
const parentDbsArray = ((_a2 = sceneDataRef.current) == null ? void 0 : _a2.parent_dbs) || [];
|
|
@@ -15619,8 +15619,9 @@ function XViewScene({
|
|
|
15619
15619
|
(db) => String(db.db_id) === String(parentFileId)
|
|
15620
15620
|
);
|
|
15621
15621
|
const isCurrentView = String(parentFileId) === String(sceneConfigId);
|
|
15622
|
+
const isViewType = ((_b2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _b2.toLowerCase()) === "view";
|
|
15622
15623
|
const ownerId2 = (parentDbInfo == null ? void 0 : parentDbInfo.owner_id) || (isCurrentView ? viewParams == null ? void 0 : viewParams.owner_id : null);
|
|
15623
|
-
const datasetName = isCurrentView ? "Quests Internas (View)" : parentFile.dataset_name || `Dataset #${parentFileId.substring(0, 6)}`;
|
|
15624
|
+
const datasetName = isCurrentView && isViewType ? "Quests Internas (View)" : parentFile.dataset_name || `Dataset #${parentFileId.substring(0, 6)}`;
|
|
15624
15625
|
if (parentFile.nodes && ownerId2) {
|
|
15625
15626
|
for (const node of parentFile.nodes) {
|
|
15626
15627
|
map.set(String(node.id), { parentFileId, ownerId: ownerId2, datasetName });
|
|
@@ -15789,7 +15790,11 @@ function XViewScene({
|
|
|
15789
15790
|
};
|
|
15790
15791
|
const tweenToTarget = (0, import_react33.useCallback)(
|
|
15791
15792
|
(target, zoomFactor = 1, forcedDirection = null) => {
|
|
15792
|
-
const {
|
|
15793
|
+
const {
|
|
15794
|
+
camera: sceneCamera,
|
|
15795
|
+
controls: sceneControls,
|
|
15796
|
+
tweenGroup
|
|
15797
|
+
} = stateRef.current;
|
|
15793
15798
|
if (!sceneCamera || !sceneControls || !tweenGroup) return;
|
|
15794
15799
|
const targetPos = target instanceof THREE3.Mesh ? target.getWorldPosition(new THREE3.Vector3()) : target;
|
|
15795
15800
|
const controlsTween = new import_tween2.Tween(sceneControls.target).to(targetPos, 1500).easing(import_tween2.Easing.Cubic.Out);
|
|
@@ -16346,341 +16351,372 @@ function XViewScene({
|
|
|
16346
16351
|
},
|
|
16347
16352
|
[]
|
|
16348
16353
|
);
|
|
16349
|
-
const handleActivateReshapeLens = (0, import_react33.useCallback)(
|
|
16350
|
-
|
|
16351
|
-
|
|
16352
|
-
|
|
16353
|
-
|
|
16354
|
-
|
|
16355
|
-
|
|
16356
|
-
|
|
16357
|
-
|
|
16358
|
-
|
|
16359
|
-
if (mesh && mesh.material) {
|
|
16360
|
-
const opacityTween = new import_tween2.Tween(mesh.material).to({ opacity: 1 }, 1200).easing(import_tween2.Easing.Cubic.Out);
|
|
16361
|
-
tweenGroup.add(opacityTween);
|
|
16362
|
-
opacityTween.start();
|
|
16363
|
-
}
|
|
16364
|
-
if (mesh && mesh.userData && mesh.userData.labelObject) {
|
|
16365
|
-
mesh.userData.labelObject.visible = true;
|
|
16366
|
-
}
|
|
16367
|
-
});
|
|
16368
|
-
if (type === "Column") {
|
|
16369
|
-
const colSpacing = 80;
|
|
16370
|
-
const rowSpacing = 80;
|
|
16371
|
-
const numCols = columns || 4;
|
|
16372
|
-
activeNodeIds.forEach((id, index) => {
|
|
16373
|
-
const mesh = nodeObjects[id];
|
|
16374
|
-
const col = index % numCols;
|
|
16375
|
-
const row = Math.floor(index / numCols);
|
|
16376
|
-
const targetX = (col - (numCols - 1) / 2) * colSpacing;
|
|
16377
|
-
const targetY = -(row * rowSpacing) + 50;
|
|
16378
|
-
const posTween = new import_tween2.Tween(mesh.position).to({ x: targetX, y: targetY, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16379
|
-
tweenGroup.add(posTween);
|
|
16380
|
-
posTween.start();
|
|
16381
|
-
if (mesh.userData.labelObject) {
|
|
16382
|
-
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
16383
|
-
const lblTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16384
|
-
tweenGroup.add(lblTween);
|
|
16385
|
-
lblTween.start();
|
|
16386
|
-
}
|
|
16387
|
-
sumX += targetX;
|
|
16388
|
-
sumY += targetY;
|
|
16389
|
-
nodeCount++;
|
|
16390
|
-
});
|
|
16391
|
-
} else if (type === "Circle") {
|
|
16392
|
-
const total = activeNodeIds.length;
|
|
16393
|
-
const radius = Math.max(80, total * 8);
|
|
16394
|
-
activeNodeIds.forEach((id, index) => {
|
|
16354
|
+
const handleActivateReshapeLens = (0, import_react33.useCallback)(
|
|
16355
|
+
({ type, columns, centerNodeId }) => {
|
|
16356
|
+
const { nodeObjects, tweenGroup, camera, controls } = stateRef.current;
|
|
16357
|
+
if (!nodeObjects || !tweenGroup || !camera || !controls) return;
|
|
16358
|
+
const activeNodeIds = Object.keys(nodeObjects);
|
|
16359
|
+
if (activeNodeIds.length === 0) return;
|
|
16360
|
+
let sumX = 0;
|
|
16361
|
+
let sumY = 0;
|
|
16362
|
+
let nodeCount = 0;
|
|
16363
|
+
activeNodeIds.forEach((id) => {
|
|
16395
16364
|
const mesh = nodeObjects[id];
|
|
16396
|
-
|
|
16397
|
-
|
|
16398
|
-
|
|
16399
|
-
|
|
16400
|
-
|
|
16401
|
-
|
|
16402
|
-
|
|
16403
|
-
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
16404
|
-
const lblTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16405
|
-
tweenGroup.add(lblTween);
|
|
16406
|
-
lblTween.start();
|
|
16407
|
-
}
|
|
16408
|
-
sumX += targetX;
|
|
16409
|
-
sumY += targetY;
|
|
16410
|
-
nodeCount++;
|
|
16411
|
-
});
|
|
16412
|
-
} else if (type === "Star") {
|
|
16413
|
-
const centerMesh = centerNodeId ? nodeObjects[String(centerNodeId)] : null;
|
|
16414
|
-
const orbitingNodeIds = activeNodeIds.filter((id) => id !== String(centerNodeId));
|
|
16415
|
-
const totalOrbiting = orbitingNodeIds.length;
|
|
16416
|
-
const radius = Math.max(80, totalOrbiting * 10);
|
|
16417
|
-
if (centerMesh) {
|
|
16418
|
-
const posTween = new import_tween2.Tween(centerMesh.position).to({ x: 0, y: 0, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16419
|
-
tweenGroup.add(posTween);
|
|
16420
|
-
posTween.start();
|
|
16421
|
-
if (centerMesh.userData.labelObject) {
|
|
16422
|
-
const labelTarget = new THREE3.Vector3(0, 0, 0).add(centerMesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
16423
|
-
const lblTween = new import_tween2.Tween(centerMesh.userData.labelObject.position).to(labelTarget, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16424
|
-
tweenGroup.add(lblTween);
|
|
16425
|
-
lblTween.start();
|
|
16365
|
+
if (mesh && mesh.material) {
|
|
16366
|
+
const opacityTween = new import_tween2.Tween(mesh.material).to({ opacity: 1 }, 1200).easing(import_tween2.Easing.Cubic.Out);
|
|
16367
|
+
tweenGroup.add(opacityTween);
|
|
16368
|
+
opacityTween.start();
|
|
16369
|
+
}
|
|
16370
|
+
if (mesh && mesh.userData && mesh.userData.labelObject) {
|
|
16371
|
+
mesh.userData.labelObject.visible = true;
|
|
16426
16372
|
}
|
|
16427
|
-
sumX += 0;
|
|
16428
|
-
sumY += 0;
|
|
16429
|
-
nodeCount++;
|
|
16430
|
-
}
|
|
16431
|
-
orbitingNodeIds.forEach((id, index) => {
|
|
16432
|
-
const mesh = nodeObjects[id];
|
|
16433
|
-
const angle = totalOrbiting > 0 ? index / totalOrbiting * Math.PI * 2 : 0;
|
|
16434
|
-
const targetX = Math.cos(angle) * radius;
|
|
16435
|
-
const targetY = Math.sin(angle) * radius;
|
|
16436
|
-
const posTween = new import_tween2.Tween(mesh.position).to({ x: targetX, y: targetY, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16437
|
-
tweenGroup.add(posTween);
|
|
16438
|
-
posTween.start();
|
|
16439
|
-
if (mesh.userData.labelObject) {
|
|
16440
|
-
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
16441
|
-
const lblTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16442
|
-
tweenGroup.add(lblTween);
|
|
16443
|
-
lblTween.start();
|
|
16444
|
-
}
|
|
16445
|
-
sumX += targetX;
|
|
16446
|
-
sumY += targetY;
|
|
16447
|
-
nodeCount++;
|
|
16448
16373
|
});
|
|
16449
|
-
}
|
|
16450
|
-
if (nodeCount > 0) {
|
|
16451
|
-
const centerX = sumX / nodeCount;
|
|
16452
|
-
const centerY = sumY / nodeCount;
|
|
16453
|
-
const targetFocus = new THREE3.Vector3(centerX, centerY, 0);
|
|
16454
|
-
const targetTween = new import_tween2.Tween(controls.target).to({ x: targetFocus.x, y: targetFocus.y, z: targetFocus.z }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16455
|
-
tweenGroup.add(targetTween);
|
|
16456
|
-
targetTween.start();
|
|
16457
|
-
let zoomZ = 140;
|
|
16458
16374
|
if (type === "Column") {
|
|
16459
|
-
const
|
|
16460
|
-
|
|
16461
|
-
|
|
16462
|
-
|
|
16463
|
-
|
|
16464
|
-
|
|
16465
|
-
|
|
16466
|
-
|
|
16467
|
-
|
|
16468
|
-
|
|
16469
|
-
|
|
16470
|
-
|
|
16471
|
-
|
|
16472
|
-
|
|
16473
|
-
|
|
16474
|
-
|
|
16475
|
-
|
|
16476
|
-
|
|
16477
|
-
|
|
16478
|
-
|
|
16479
|
-
|
|
16480
|
-
|
|
16481
|
-
|
|
16482
|
-
|
|
16483
|
-
|
|
16484
|
-
|
|
16485
|
-
|
|
16486
|
-
|
|
16487
|
-
|
|
16488
|
-
|
|
16489
|
-
|
|
16490
|
-
|
|
16491
|
-
|
|
16492
|
-
|
|
16493
|
-
|
|
16375
|
+
const colSpacing = 80;
|
|
16376
|
+
const rowSpacing = 80;
|
|
16377
|
+
const numCols = columns || 4;
|
|
16378
|
+
activeNodeIds.forEach((id, index) => {
|
|
16379
|
+
const mesh = nodeObjects[id];
|
|
16380
|
+
const col = index % numCols;
|
|
16381
|
+
const row = Math.floor(index / numCols);
|
|
16382
|
+
const targetX = (col - (numCols - 1) / 2) * colSpacing;
|
|
16383
|
+
const targetY = -(row * rowSpacing) + 50;
|
|
16384
|
+
const posTween = new import_tween2.Tween(mesh.position).to({ x: targetX, y: targetY, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16385
|
+
tweenGroup.add(posTween);
|
|
16386
|
+
posTween.start();
|
|
16387
|
+
if (mesh.userData.labelObject) {
|
|
16388
|
+
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(
|
|
16389
|
+
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16390
|
+
);
|
|
16391
|
+
const lblTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16392
|
+
tweenGroup.add(lblTween);
|
|
16393
|
+
lblTween.start();
|
|
16394
|
+
}
|
|
16395
|
+
sumX += targetX;
|
|
16396
|
+
sumY += targetY;
|
|
16397
|
+
nodeCount++;
|
|
16398
|
+
});
|
|
16399
|
+
} else if (type === "Circle") {
|
|
16400
|
+
const total = activeNodeIds.length;
|
|
16401
|
+
const radius = Math.max(80, total * 8);
|
|
16402
|
+
activeNodeIds.forEach((id, index) => {
|
|
16403
|
+
const mesh = nodeObjects[id];
|
|
16404
|
+
const angle = index / total * Math.PI * 2;
|
|
16405
|
+
const targetX = Math.cos(angle) * radius;
|
|
16406
|
+
const targetY = Math.sin(angle) * radius;
|
|
16407
|
+
const posTween = new import_tween2.Tween(mesh.position).to({ x: targetX, y: targetY, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16408
|
+
tweenGroup.add(posTween);
|
|
16409
|
+
posTween.start();
|
|
16410
|
+
if (mesh.userData.labelObject) {
|
|
16411
|
+
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(
|
|
16412
|
+
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16413
|
+
);
|
|
16414
|
+
const lblTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16415
|
+
tweenGroup.add(lblTween);
|
|
16416
|
+
lblTween.start();
|
|
16417
|
+
}
|
|
16418
|
+
sumX += targetX;
|
|
16419
|
+
sumY += targetY;
|
|
16420
|
+
nodeCount++;
|
|
16421
|
+
});
|
|
16422
|
+
} else if (type === "Star") {
|
|
16423
|
+
const centerMesh = centerNodeId ? nodeObjects[String(centerNodeId)] : null;
|
|
16424
|
+
const orbitingNodeIds = activeNodeIds.filter(
|
|
16425
|
+
(id) => id !== String(centerNodeId)
|
|
16426
|
+
);
|
|
16427
|
+
const totalOrbiting = orbitingNodeIds.length;
|
|
16428
|
+
const radius = Math.max(80, totalOrbiting * 10);
|
|
16429
|
+
if (centerMesh) {
|
|
16430
|
+
const posTween = new import_tween2.Tween(centerMesh.position).to({ x: 0, y: 0, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16431
|
+
tweenGroup.add(posTween);
|
|
16432
|
+
posTween.start();
|
|
16433
|
+
if (centerMesh.userData.labelObject) {
|
|
16434
|
+
const labelTarget = new THREE3.Vector3(0, 0, 0).add(
|
|
16435
|
+
centerMesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16436
|
+
);
|
|
16437
|
+
const lblTween = new import_tween2.Tween(centerMesh.userData.labelObject.position).to(labelTarget, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16438
|
+
tweenGroup.add(lblTween);
|
|
16439
|
+
lblTween.start();
|
|
16440
|
+
}
|
|
16441
|
+
sumX += 0;
|
|
16442
|
+
sumY += 0;
|
|
16443
|
+
nodeCount++;
|
|
16444
|
+
}
|
|
16445
|
+
orbitingNodeIds.forEach((id, index) => {
|
|
16446
|
+
const mesh = nodeObjects[id];
|
|
16447
|
+
const angle = totalOrbiting > 0 ? index / totalOrbiting * Math.PI * 2 : 0;
|
|
16448
|
+
const targetX = Math.cos(angle) * radius;
|
|
16449
|
+
const targetY = Math.sin(angle) * radius;
|
|
16450
|
+
const posTween = new import_tween2.Tween(mesh.position).to({ x: targetX, y: targetY, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16451
|
+
tweenGroup.add(posTween);
|
|
16452
|
+
posTween.start();
|
|
16453
|
+
if (mesh.userData.labelObject) {
|
|
16454
|
+
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(
|
|
16455
|
+
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16456
|
+
);
|
|
16457
|
+
const lblTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16458
|
+
tweenGroup.add(lblTween);
|
|
16459
|
+
lblTween.start();
|
|
16460
|
+
}
|
|
16461
|
+
sumX += targetX;
|
|
16462
|
+
sumY += targetY;
|
|
16463
|
+
nodeCount++;
|
|
16464
|
+
});
|
|
16494
16465
|
}
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
16499
|
-
|
|
16500
|
-
|
|
16501
|
-
|
|
16502
|
-
|
|
16503
|
-
if (
|
|
16504
|
-
|
|
16505
|
-
|
|
16466
|
+
if (nodeCount > 0) {
|
|
16467
|
+
const centerX = sumX / nodeCount;
|
|
16468
|
+
const centerY = sumY / nodeCount;
|
|
16469
|
+
const targetFocus = new THREE3.Vector3(centerX, centerY, 0);
|
|
16470
|
+
const targetTween = new import_tween2.Tween(controls.target).to({ x: targetFocus.x, y: targetFocus.y, z: targetFocus.z }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16471
|
+
tweenGroup.add(targetTween);
|
|
16472
|
+
targetTween.start();
|
|
16473
|
+
let zoomZ = 140;
|
|
16474
|
+
if (type === "Column") {
|
|
16475
|
+
const numRows = Math.ceil(nodeCount / (columns || 4));
|
|
16476
|
+
zoomZ = Math.max(140, numRows * 50);
|
|
16477
|
+
} else if (type === "Circle" || type === "Star") {
|
|
16478
|
+
const radius = Math.max(80, nodeCount * 8);
|
|
16479
|
+
zoomZ = radius * 2.5;
|
|
16480
|
+
}
|
|
16481
|
+
const camTween = new import_tween2.Tween(camera.position).to({ x: targetFocus.x, y: targetFocus.y, z: zoomZ }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16482
|
+
tweenGroup.add(camTween);
|
|
16483
|
+
camTween.start();
|
|
16506
16484
|
}
|
|
16507
|
-
}
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
|
|
16515
|
-
|
|
16516
|
-
|
|
16517
|
-
|
|
16518
|
-
|
|
16519
|
-
|
|
16520
|
-
|
|
16521
|
-
questsInCol.forEach((q, rowIndex) => {
|
|
16522
|
-
const timeInfo = questTimeInfos.get(String(q.id)) || { isUndated: true };
|
|
16523
|
-
let nodeY;
|
|
16524
|
-
if (!timeInfo.isUndated) {
|
|
16525
|
-
nodeY = timeToYMap.get(timeInfo.startDate.getTime());
|
|
16526
|
-
} else {
|
|
16527
|
-
const undatedOffset = sortedTimePoints.length > 0 ? sortedTimePoints.length * 5 : 0;
|
|
16528
|
-
nodeY = -40 - rowIndex * QUEST_LENS_ROW_SPACING - undatedOffset;
|
|
16529
|
-
}
|
|
16530
|
-
const posKey = `${statusName}_${nodeY}`;
|
|
16531
|
-
if (!positionGroups.has(posKey)) positionGroups.set(posKey, []);
|
|
16532
|
-
positionGroups.get(posKey).push(String(q.id));
|
|
16485
|
+
},
|
|
16486
|
+
[]
|
|
16487
|
+
);
|
|
16488
|
+
const handleActivateQuestLens = (0, import_react33.useCallback)(
|
|
16489
|
+
({ assigneeId, status: status2, milestoneId }) => {
|
|
16490
|
+
var _a2;
|
|
16491
|
+
const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
|
|
16492
|
+
if (!nodeObjects || !tweenGroup || !graphGroup) return;
|
|
16493
|
+
const allQuests = ((_a2 = sceneDataRef.current) == null ? void 0 : _a2.quest_nodes) || [];
|
|
16494
|
+
const filteredQuests = allQuests.filter((q) => {
|
|
16495
|
+
const matchAssignee = !assigneeId || String(q.assignee_id) === String(assigneeId);
|
|
16496
|
+
const matchStatus = !status2 ? q.status !== "Done" : String(q.status) === String(status2);
|
|
16497
|
+
const matchMilestone = !milestoneId || q.milestone_ids && q.milestone_ids.includes(milestoneId);
|
|
16498
|
+
return matchAssignee && matchStatus && matchMilestone;
|
|
16533
16499
|
});
|
|
16534
|
-
|
|
16535
|
-
|
|
16536
|
-
|
|
16537
|
-
if (oldLabel) {
|
|
16538
|
-
mesh.remove(oldLabel);
|
|
16539
|
-
if (oldLabel.material) oldLabel.material.dispose();
|
|
16540
|
-
}
|
|
16541
|
-
if (mesh.userData.timelineIntervalBar) {
|
|
16542
|
-
if (graphGroup) graphGroup.remove(mesh.userData.timelineIntervalBar);
|
|
16543
|
-
mesh.userData.timelineIntervalBar = null;
|
|
16544
|
-
}
|
|
16545
|
-
if (mesh.userData.timelineEndLabel) {
|
|
16546
|
-
if (graphGroup) graphGroup.remove(mesh.userData.timelineEndLabel);
|
|
16547
|
-
mesh.userData.timelineEndLabel = null;
|
|
16548
|
-
}
|
|
16549
|
-
});
|
|
16550
|
-
const nonFilteredNodeIds = Object.keys(nodeObjects).filter((id) => !filteredQuests.some((q) => String(q.id) === String(id)));
|
|
16551
|
-
const COMMON_START_X = startX - 100;
|
|
16552
|
-
const COMMON_COL_SPACING = 30;
|
|
16553
|
-
const COMMON_ROW_SPACING = 35;
|
|
16554
|
-
const MAX_COMMON_ROWS = 15;
|
|
16555
|
-
nonFilteredNodeIds.forEach((id, idx) => {
|
|
16556
|
-
const mesh = nodeObjects[id];
|
|
16557
|
-
if (!mesh) return;
|
|
16558
|
-
const col = Math.floor(idx / MAX_COMMON_ROWS);
|
|
16559
|
-
const row = idx % MAX_COMMON_ROWS;
|
|
16560
|
-
const targetX = COMMON_START_X - col * COMMON_COL_SPACING;
|
|
16561
|
-
const targetY = -(row * COMMON_ROW_SPACING) + 50;
|
|
16562
|
-
const targetZ = 0;
|
|
16563
|
-
if (mesh.material) {
|
|
16564
|
-
const opacityTween = new import_tween2.Tween(mesh.material).to({ opacity: 1 }, 1200).easing(import_tween2.Easing.Cubic.Out);
|
|
16565
|
-
tweenGroup.add(opacityTween);
|
|
16566
|
-
opacityTween.start();
|
|
16567
|
-
}
|
|
16568
|
-
if (mesh.userData.labelObject) {
|
|
16569
|
-
mesh.userData.labelObject.visible = true;
|
|
16570
|
-
const labelTargetPos = new THREE3.Vector3(targetX, targetY, targetZ).add(
|
|
16571
|
-
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16572
|
-
);
|
|
16573
|
-
const labelTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTargetPos, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16574
|
-
tweenGroup.add(labelTween);
|
|
16575
|
-
labelTween.start();
|
|
16500
|
+
if (filteredQuests.length === 0) {
|
|
16501
|
+
console.warn("Nenhuma quest encontrada para os filtros selecionados.");
|
|
16502
|
+
return;
|
|
16576
16503
|
}
|
|
16577
|
-
const
|
|
16578
|
-
|
|
16579
|
-
|
|
16580
|
-
|
|
16581
|
-
|
|
16582
|
-
|
|
16583
|
-
|
|
16584
|
-
if (
|
|
16585
|
-
|
|
16586
|
-
tweenGroup.add(fadeInTween);
|
|
16587
|
-
fadeInTween.start();
|
|
16504
|
+
const questsByStatus = {
|
|
16505
|
+
Backlog: [],
|
|
16506
|
+
"In Progress": [],
|
|
16507
|
+
Review: [],
|
|
16508
|
+
Done: []
|
|
16509
|
+
};
|
|
16510
|
+
filteredQuests.forEach((q) => {
|
|
16511
|
+
if (questsByStatus[q.status]) {
|
|
16512
|
+
questsByStatus[q.status].push(q);
|
|
16588
16513
|
}
|
|
16589
|
-
|
|
16590
|
-
|
|
16514
|
+
});
|
|
16515
|
+
const questTimeInfos = /* @__PURE__ */ new Map();
|
|
16516
|
+
const allActiveTimePoints = /* @__PURE__ */ new Set();
|
|
16517
|
+
filteredQuests.forEach((q) => {
|
|
16518
|
+
const info = parseDateProp(q.Date);
|
|
16519
|
+
questTimeInfos.set(String(q.id), info);
|
|
16520
|
+
if (!info.isUndated) {
|
|
16521
|
+
allActiveTimePoints.add(info.startDate.getTime());
|
|
16522
|
+
if (info.endDate && info.type === "interval") {
|
|
16523
|
+
allActiveTimePoints.add(info.endDate.getTime());
|
|
16524
|
+
}
|
|
16591
16525
|
}
|
|
16592
|
-
}
|
|
16593
|
-
|
|
16594
|
-
|
|
16595
|
-
|
|
16596
|
-
const
|
|
16597
|
-
|
|
16598
|
-
|
|
16599
|
-
|
|
16600
|
-
|
|
16601
|
-
|
|
16602
|
-
|
|
16603
|
-
|
|
16604
|
-
|
|
16605
|
-
|
|
16606
|
-
|
|
16607
|
-
|
|
16608
|
-
|
|
16609
|
-
|
|
16610
|
-
|
|
16611
|
-
|
|
16612
|
-
|
|
16613
|
-
|
|
16614
|
-
|
|
16615
|
-
|
|
16616
|
-
|
|
16617
|
-
|
|
16618
|
-
tweenGroup.add(lensTween);
|
|
16619
|
-
lensTween.start();
|
|
16620
|
-
sumX += finalX;
|
|
16621
|
-
sumY += targetY;
|
|
16622
|
-
questCount++;
|
|
16623
|
-
if (!timeInfo.isUndated && timeInfo.label && !mesh.getObjectByName("questDateLabel")) {
|
|
16624
|
-
const dateSprite = createTextSprite(timeInfo.label, 36);
|
|
16625
|
-
dateSprite.name = "questDateLabel";
|
|
16626
|
-
dateSprite.position.set(0, -5.5, 0);
|
|
16627
|
-
mesh.add(dateSprite);
|
|
16628
|
-
}
|
|
16629
|
-
if (timeInfo.type === "interval" && timeToYMap.has(timeInfo.endDate.getTime())) {
|
|
16630
|
-
const endY = timeToYMap.get(timeInfo.endDate.getTime());
|
|
16631
|
-
if (Math.abs(endY - targetY) > 0.1) {
|
|
16632
|
-
const barHeight = Math.abs(endY - targetY);
|
|
16633
|
-
const barGeometry = new THREE3.CylinderGeometry(
|
|
16634
|
-
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
16635
|
-
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
16636
|
-
1,
|
|
16637
|
-
16
|
|
16638
|
-
);
|
|
16639
|
-
const barMaterial = new THREE3.MeshStandardMaterial({
|
|
16640
|
-
color: TIMELINE_GOLD_COLOR,
|
|
16641
|
-
emissive: 12092939,
|
|
16642
|
-
emissiveIntensity: 0.4,
|
|
16643
|
-
transparent: true,
|
|
16644
|
-
opacity: TIMELINE_INTERVAL_BAR_OPACITY,
|
|
16645
|
-
roughness: 0.3,
|
|
16646
|
-
metalness: 0.8
|
|
16647
|
-
});
|
|
16648
|
-
const intervalBar = new THREE3.Mesh(barGeometry, barMaterial);
|
|
16649
|
-
intervalBar.userData.associatedNodeId = mesh.userData.id;
|
|
16650
|
-
intervalBar.position.set(finalX, (targetY + endY) / 2, -0.5);
|
|
16651
|
-
intervalBar.scale.y = barHeight;
|
|
16652
|
-
graphGroup.add(intervalBar);
|
|
16653
|
-
mesh.userData.timelineIntervalBar = intervalBar;
|
|
16654
|
-
const endLabel = createTextSprite(timeInfo.label.split(" - ")[1] || "", 30);
|
|
16655
|
-
endLabel.name = "timelineEndLabel";
|
|
16656
|
-
endLabel.position.set(finalX, endY + 4, 0);
|
|
16657
|
-
graphGroup.add(endLabel);
|
|
16658
|
-
mesh.userData.timelineEndLabel = endLabel;
|
|
16526
|
+
});
|
|
16527
|
+
const sortedTimePoints = Array.from(allActiveTimePoints).sort(
|
|
16528
|
+
(a, b) => a - b
|
|
16529
|
+
);
|
|
16530
|
+
const timeToYMap = /* @__PURE__ */ new Map();
|
|
16531
|
+
sortedTimePoints.forEach((ms, idx) => {
|
|
16532
|
+
timeToYMap.set(ms, idx * TIMELINE_LAYER_SPACING_Y);
|
|
16533
|
+
});
|
|
16534
|
+
const startX = -((QUEST_STATUS_ORDER.length - 1) * QUEST_LENS_COLUMN_SPACING) / 2;
|
|
16535
|
+
let sumX = 0;
|
|
16536
|
+
let sumY = 0;
|
|
16537
|
+
let questCount = 0;
|
|
16538
|
+
const positionGroups = /* @__PURE__ */ new Map();
|
|
16539
|
+
const NODE_X_GAP = 22;
|
|
16540
|
+
QUEST_STATUS_ORDER.forEach((statusName) => {
|
|
16541
|
+
const questsInCol = questsByStatus[statusName];
|
|
16542
|
+
questsInCol.forEach((q, rowIndex) => {
|
|
16543
|
+
const timeInfo = questTimeInfos.get(String(q.id)) || {
|
|
16544
|
+
isUndated: true
|
|
16545
|
+
};
|
|
16546
|
+
let nodeY;
|
|
16547
|
+
if (!timeInfo.isUndated) {
|
|
16548
|
+
nodeY = timeToYMap.get(timeInfo.startDate.getTime());
|
|
16549
|
+
} else {
|
|
16550
|
+
const undatedOffset = sortedTimePoints.length > 0 ? sortedTimePoints.length * 5 : 0;
|
|
16551
|
+
nodeY = -40 - rowIndex * QUEST_LENS_ROW_SPACING - undatedOffset;
|
|
16659
16552
|
}
|
|
16553
|
+
const posKey = `${statusName}_${nodeY}`;
|
|
16554
|
+
if (!positionGroups.has(posKey)) positionGroups.set(posKey, []);
|
|
16555
|
+
positionGroups.get(posKey).push(String(q.id));
|
|
16556
|
+
});
|
|
16557
|
+
});
|
|
16558
|
+
Object.values(nodeObjects).forEach((mesh) => {
|
|
16559
|
+
const oldLabel = mesh.getObjectByName("questDateLabel") || mesh.getObjectByName("timelineLabel");
|
|
16560
|
+
if (oldLabel) {
|
|
16561
|
+
mesh.remove(oldLabel);
|
|
16562
|
+
if (oldLabel.material) oldLabel.material.dispose();
|
|
16563
|
+
}
|
|
16564
|
+
if (mesh.userData.timelineIntervalBar) {
|
|
16565
|
+
if (graphGroup) graphGroup.remove(mesh.userData.timelineIntervalBar);
|
|
16566
|
+
mesh.userData.timelineIntervalBar = null;
|
|
16567
|
+
}
|
|
16568
|
+
if (mesh.userData.timelineEndLabel) {
|
|
16569
|
+
if (graphGroup) graphGroup.remove(mesh.userData.timelineEndLabel);
|
|
16570
|
+
mesh.userData.timelineEndLabel = null;
|
|
16571
|
+
}
|
|
16572
|
+
});
|
|
16573
|
+
const nonFilteredNodeIds = Object.keys(nodeObjects).filter(
|
|
16574
|
+
(id) => !filteredQuests.some((q) => String(q.id) === String(id))
|
|
16575
|
+
);
|
|
16576
|
+
const COMMON_START_X = startX - 100;
|
|
16577
|
+
const COMMON_COL_SPACING = 30;
|
|
16578
|
+
const COMMON_ROW_SPACING = 35;
|
|
16579
|
+
const MAX_COMMON_ROWS = 15;
|
|
16580
|
+
nonFilteredNodeIds.forEach((id, idx) => {
|
|
16581
|
+
const mesh = nodeObjects[id];
|
|
16582
|
+
if (!mesh) return;
|
|
16583
|
+
const col = Math.floor(idx / MAX_COMMON_ROWS);
|
|
16584
|
+
const row = idx % MAX_COMMON_ROWS;
|
|
16585
|
+
const targetX = COMMON_START_X - col * COMMON_COL_SPACING;
|
|
16586
|
+
const targetY = -(row * COMMON_ROW_SPACING) + 50;
|
|
16587
|
+
const targetZ = 0;
|
|
16588
|
+
if (mesh.material) {
|
|
16589
|
+
const opacityTween = new import_tween2.Tween(mesh.material).to({ opacity: 1 }, 1200).easing(import_tween2.Easing.Cubic.Out);
|
|
16590
|
+
tweenGroup.add(opacityTween);
|
|
16591
|
+
opacityTween.start();
|
|
16660
16592
|
}
|
|
16661
16593
|
if (mesh.userData.labelObject) {
|
|
16662
|
-
|
|
16663
|
-
|
|
16664
|
-
|
|
16594
|
+
mesh.userData.labelObject.visible = true;
|
|
16595
|
+
const labelTargetPos = new THREE3.Vector3(
|
|
16596
|
+
targetX,
|
|
16597
|
+
targetY,
|
|
16598
|
+
targetZ
|
|
16599
|
+
).add(mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
16665
16600
|
const labelTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTargetPos, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16666
16601
|
tweenGroup.add(labelTween);
|
|
16667
16602
|
labelTween.start();
|
|
16668
16603
|
}
|
|
16604
|
+
const sideTween = new import_tween2.Tween(mesh.position).to({ x: targetX, y: targetY, z: targetZ }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16605
|
+
tweenGroup.add(sideTween);
|
|
16606
|
+
sideTween.start();
|
|
16669
16607
|
});
|
|
16670
|
-
|
|
16671
|
-
|
|
16672
|
-
|
|
16673
|
-
|
|
16674
|
-
|
|
16675
|
-
|
|
16676
|
-
|
|
16677
|
-
|
|
16678
|
-
|
|
16679
|
-
|
|
16680
|
-
|
|
16681
|
-
|
|
16682
|
-
|
|
16683
|
-
|
|
16608
|
+
filteredQuests.forEach((q) => {
|
|
16609
|
+
const mesh = nodeObjects[String(q.id)];
|
|
16610
|
+
if (mesh) {
|
|
16611
|
+
if (mesh.material) {
|
|
16612
|
+
const fadeInTween = new import_tween2.Tween(mesh.material).to({ opacity: 1 }, 1200).easing(import_tween2.Easing.Cubic.Out);
|
|
16613
|
+
tweenGroup.add(fadeInTween);
|
|
16614
|
+
fadeInTween.start();
|
|
16615
|
+
}
|
|
16616
|
+
if (mesh.userData.labelObject) {
|
|
16617
|
+
mesh.userData.labelObject.visible = true;
|
|
16618
|
+
}
|
|
16619
|
+
}
|
|
16620
|
+
});
|
|
16621
|
+
QUEST_STATUS_ORDER.forEach((statusName, colIndex) => {
|
|
16622
|
+
if (status2 && status2 !== statusName) return;
|
|
16623
|
+
const questsInCol = questsByStatus[statusName];
|
|
16624
|
+
const colX = startX + colIndex * QUEST_LENS_COLUMN_SPACING;
|
|
16625
|
+
questsInCol.forEach((q, rowIndex) => {
|
|
16626
|
+
const nodeId = String(q.id);
|
|
16627
|
+
let mesh = nodeObjects[nodeId];
|
|
16628
|
+
const timeInfo = questTimeInfos.get(nodeId) || { isUndated: true };
|
|
16629
|
+
let targetY;
|
|
16630
|
+
if (!timeInfo.isUndated) {
|
|
16631
|
+
targetY = timeToYMap.get(timeInfo.startDate.getTime());
|
|
16632
|
+
} else {
|
|
16633
|
+
const undatedOffset = sortedTimePoints.length > 0 ? sortedTimePoints.length * 5 : 0;
|
|
16634
|
+
targetY = -40 - rowIndex * QUEST_LENS_ROW_SPACING - undatedOffset;
|
|
16635
|
+
}
|
|
16636
|
+
const posKey = `${statusName}_${targetY}`;
|
|
16637
|
+
const group = positionGroups.get(posKey) || [nodeId];
|
|
16638
|
+
const indexInGroup = group.indexOf(nodeId);
|
|
16639
|
+
const xOffset = (indexInGroup - (group.length - 1) / 2) * NODE_X_GAP;
|
|
16640
|
+
const finalX = colX + xOffset;
|
|
16641
|
+
if (!mesh) {
|
|
16642
|
+
mesh = addOrUpdateNodeMesh(
|
|
16643
|
+
q,
|
|
16644
|
+
new THREE3.Vector3(finalX, 150, 0),
|
|
16645
|
+
true
|
|
16646
|
+
);
|
|
16647
|
+
}
|
|
16648
|
+
const lensTween = new import_tween2.Tween(mesh.position).to({ x: finalX, y: targetY, z: 0 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16649
|
+
tweenGroup.add(lensTween);
|
|
16650
|
+
lensTween.start();
|
|
16651
|
+
sumX += finalX;
|
|
16652
|
+
sumY += targetY;
|
|
16653
|
+
questCount++;
|
|
16654
|
+
if (!timeInfo.isUndated && timeInfo.label && !mesh.getObjectByName("questDateLabel")) {
|
|
16655
|
+
const dateSprite = createTextSprite(timeInfo.label, 36);
|
|
16656
|
+
dateSprite.name = "questDateLabel";
|
|
16657
|
+
dateSprite.position.set(0, -5.5, 0);
|
|
16658
|
+
mesh.add(dateSprite);
|
|
16659
|
+
}
|
|
16660
|
+
if (timeInfo.type === "interval" && timeToYMap.has(timeInfo.endDate.getTime())) {
|
|
16661
|
+
const endY = timeToYMap.get(timeInfo.endDate.getTime());
|
|
16662
|
+
if (Math.abs(endY - targetY) > 0.1) {
|
|
16663
|
+
const barHeight = Math.abs(endY - targetY);
|
|
16664
|
+
const barGeometry = new THREE3.CylinderGeometry(
|
|
16665
|
+
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
16666
|
+
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
16667
|
+
1,
|
|
16668
|
+
16
|
|
16669
|
+
);
|
|
16670
|
+
const barMaterial = new THREE3.MeshStandardMaterial({
|
|
16671
|
+
color: TIMELINE_GOLD_COLOR,
|
|
16672
|
+
emissive: 12092939,
|
|
16673
|
+
emissiveIntensity: 0.4,
|
|
16674
|
+
transparent: true,
|
|
16675
|
+
opacity: TIMELINE_INTERVAL_BAR_OPACITY,
|
|
16676
|
+
roughness: 0.3,
|
|
16677
|
+
metalness: 0.8
|
|
16678
|
+
});
|
|
16679
|
+
const intervalBar = new THREE3.Mesh(barGeometry, barMaterial);
|
|
16680
|
+
intervalBar.userData.associatedNodeId = mesh.userData.id;
|
|
16681
|
+
intervalBar.position.set(finalX, (targetY + endY) / 2, -0.5);
|
|
16682
|
+
intervalBar.scale.y = barHeight;
|
|
16683
|
+
graphGroup.add(intervalBar);
|
|
16684
|
+
mesh.userData.timelineIntervalBar = intervalBar;
|
|
16685
|
+
const endLabel = createTextSprite(
|
|
16686
|
+
timeInfo.label.split(" - ")[1] || "",
|
|
16687
|
+
30
|
|
16688
|
+
);
|
|
16689
|
+
endLabel.name = "timelineEndLabel";
|
|
16690
|
+
endLabel.position.set(finalX, endY + 4, 0);
|
|
16691
|
+
graphGroup.add(endLabel);
|
|
16692
|
+
mesh.userData.timelineEndLabel = endLabel;
|
|
16693
|
+
}
|
|
16694
|
+
}
|
|
16695
|
+
if (mesh.userData.labelObject) {
|
|
16696
|
+
const labelTargetPos = new THREE3.Vector3(finalX, targetY, 0).add(
|
|
16697
|
+
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16698
|
+
);
|
|
16699
|
+
const labelTween = new import_tween2.Tween(mesh.userData.labelObject.position).to(labelTargetPos, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16700
|
+
tweenGroup.add(labelTween);
|
|
16701
|
+
labelTween.start();
|
|
16702
|
+
}
|
|
16703
|
+
});
|
|
16704
|
+
});
|
|
16705
|
+
if (questCount > 0) {
|
|
16706
|
+
const { camera: sceneCamera, controls: sceneControls } = stateRef.current;
|
|
16707
|
+
const centerX = sumX / questCount;
|
|
16708
|
+
const centerY = sumY / questCount;
|
|
16709
|
+
const targetFocus = new THREE3.Vector3(centerX, centerY, 0);
|
|
16710
|
+
const targetTween = new import_tween2.Tween(sceneControls.target).to({ x: targetFocus.x, y: targetFocus.y, z: targetFocus.z }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16711
|
+
tweenGroup.add(targetTween);
|
|
16712
|
+
targetTween.start();
|
|
16713
|
+
const camTween = new import_tween2.Tween(sceneCamera.position).to({ x: targetFocus.x, y: targetFocus.y, z: 140 }, 1500).easing(import_tween2.Easing.Cubic.InOut);
|
|
16714
|
+
tweenGroup.add(camTween);
|
|
16715
|
+
camTween.start();
|
|
16716
|
+
}
|
|
16717
|
+
},
|
|
16718
|
+
[addOrUpdateNodeMesh]
|
|
16719
|
+
);
|
|
16684
16720
|
(0, import_react33.useEffect)(() => {
|
|
16685
16721
|
if (!isInitialized || !sceneDataRef.current) return;
|
|
16686
16722
|
const currentMount = mountRef.current;
|
|
@@ -17065,7 +17101,9 @@ function XViewScene({
|
|
|
17065
17101
|
const clickedNodeId = String(clickedNode.userData.id);
|
|
17066
17102
|
const parentId = String(currentSelectedParent);
|
|
17067
17103
|
if (clickedNodeId === parentId) {
|
|
17068
|
-
alert(
|
|
17104
|
+
alert(
|
|
17105
|
+
"Erro: N\xE3o \xE9 poss\xEDvel adicionar um Node como filho dele mesmo."
|
|
17106
|
+
);
|
|
17069
17107
|
return;
|
|
17070
17108
|
}
|
|
17071
17109
|
const parentInfo = stateRef.current.nodeIdToParentFileMap.get(clickedNodeId);
|
|
@@ -17414,7 +17452,11 @@ function XViewScene({
|
|
|
17414
17452
|
ancestryData: ancestryDataRef.current
|
|
17415
17453
|
});
|
|
17416
17454
|
(_b2 = stateRef.current.tweenGroup) == null ? void 0 : _b2.update(time);
|
|
17417
|
-
const {
|
|
17455
|
+
const {
|
|
17456
|
+
keysPressed,
|
|
17457
|
+
controls: sceneControls,
|
|
17458
|
+
camera: sceneCamera
|
|
17459
|
+
} = stateRef.current;
|
|
17418
17460
|
if (sceneControls && keysPressed) {
|
|
17419
17461
|
const panSpeed = 1.5;
|
|
17420
17462
|
const rotateSpeed = 0.02;
|
|
@@ -17438,10 +17480,18 @@ function XViewScene({
|
|
|
17438
17480
|
offset.multiplyScalar(factor);
|
|
17439
17481
|
sceneCamera.position.copy(sceneControls.target).add(offset);
|
|
17440
17482
|
} else if (!isCtrl && !isShift && (dirX !== 0 || dirY !== 0)) {
|
|
17441
|
-
const distance = sceneCamera.position.distanceTo(
|
|
17483
|
+
const distance = sceneCamera.position.distanceTo(
|
|
17484
|
+
sceneControls.target
|
|
17485
|
+
);
|
|
17442
17486
|
const currentPanSpeed = panSpeed * (distance / 100);
|
|
17443
|
-
const vecX = new THREE3.Vector3().setFromMatrixColumn(
|
|
17444
|
-
|
|
17487
|
+
const vecX = new THREE3.Vector3().setFromMatrixColumn(
|
|
17488
|
+
sceneCamera.matrix,
|
|
17489
|
+
0
|
|
17490
|
+
);
|
|
17491
|
+
const vecY = new THREE3.Vector3().setFromMatrixColumn(
|
|
17492
|
+
sceneCamera.matrix,
|
|
17493
|
+
1
|
|
17494
|
+
);
|
|
17445
17495
|
vecX.multiplyScalar(dirX * currentPanSpeed);
|
|
17446
17496
|
vecY.multiplyScalar(dirY * currentPanSpeed);
|
|
17447
17497
|
sceneCamera.position.add(vecX).add(vecY);
|
|
@@ -17838,115 +17888,143 @@ function XViewScene({
|
|
|
17838
17888
|
const handleStartVersioning = (nodeData) => {
|
|
17839
17889
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
17840
17890
|
};
|
|
17841
|
-
const handleStartQuestQuick = (0, import_react33.useCallback)(
|
|
17842
|
-
|
|
17843
|
-
|
|
17844
|
-
|
|
17845
|
-
|
|
17846
|
-
|
|
17847
|
-
|
|
17848
|
-
|
|
17849
|
-
|
|
17850
|
-
|
|
17851
|
-
|
|
17852
|
-
|
|
17853
|
-
|
|
17854
|
-
|
|
17855
|
-
|
|
17856
|
-
|
|
17857
|
-
|
|
17858
|
-
|
|
17859
|
-
|
|
17860
|
-
|
|
17861
|
-
|
|
17862
|
-
|
|
17863
|
-
|
|
17864
|
-
|
|
17865
|
-
|
|
17866
|
-
|
|
17867
|
-
|
|
17868
|
-
|
|
17869
|
-
|
|
17870
|
-
|
|
17871
|
-
|
|
17872
|
-
|
|
17873
|
-
|
|
17874
|
-
|
|
17875
|
-
|
|
17876
|
-
|
|
17877
|
-
|
|
17878
|
-
|
|
17879
|
-
|
|
17880
|
-
|
|
17881
|
-
|
|
17882
|
-
|
|
17883
|
-
|
|
17884
|
-
|
|
17885
|
-
|
|
17886
|
-
|
|
17887
|
-
}
|
|
17888
|
-
|
|
17889
|
-
|
|
17890
|
-
|
|
17891
|
-
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
17899
|
-
|
|
17900
|
-
|
|
17901
|
-
|
|
17902
|
-
|
|
17903
|
-
|
|
17904
|
-
|
|
17905
|
-
|
|
17906
|
-
|
|
17891
|
+
const handleStartQuestQuick = (0, import_react33.useCallback)(
|
|
17892
|
+
(questNode) => {
|
|
17893
|
+
var _a2, _b2, _c2;
|
|
17894
|
+
if (!questNode || !actionHandlerContext) return;
|
|
17895
|
+
const allParentNodes = Object.values(parentDataRef.current).flatMap(
|
|
17896
|
+
(fileData) => fileData.nodes || []
|
|
17897
|
+
);
|
|
17898
|
+
const blockCheck = isQuestBlocked(questNode, allParentNodes);
|
|
17899
|
+
if (blockCheck.isBlocked) {
|
|
17900
|
+
alert(
|
|
17901
|
+
`Esta quest n\xE3o pode ser iniciada pois possui depend\xEAncias pendentes: ${blockCheck.pendingDependencies.map((d) => d.raw_title || d.name).join(", ")}`
|
|
17902
|
+
);
|
|
17903
|
+
return;
|
|
17904
|
+
}
|
|
17905
|
+
const {
|
|
17906
|
+
labelObject,
|
|
17907
|
+
labelOffset,
|
|
17908
|
+
aura,
|
|
17909
|
+
borderRing,
|
|
17910
|
+
timelineIntervalBar,
|
|
17911
|
+
timelineEndLabel,
|
|
17912
|
+
...cleanQuestNode
|
|
17913
|
+
} = questNode;
|
|
17914
|
+
const newTimeline = [
|
|
17915
|
+
...cleanQuestNode.timeline || [],
|
|
17916
|
+
createTimelineEntry(
|
|
17917
|
+
((_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.id) || "unknown",
|
|
17918
|
+
`Status "In Progress" - Respons\xE1vel: ${((_b2 = session == null ? void 0 : session.user) == null ? void 0 : _b2.name) || "usu\xE1rio"}`,
|
|
17919
|
+
"status_changed"
|
|
17920
|
+
)
|
|
17921
|
+
];
|
|
17922
|
+
const updatedNode = {
|
|
17923
|
+
...cleanQuestNode,
|
|
17924
|
+
status: "In Progress",
|
|
17925
|
+
color: "#eab308",
|
|
17926
|
+
assignee_id: (_c2 = session == null ? void 0 : session.user) == null ? void 0 : _c2.id,
|
|
17927
|
+
timeline: newTimeline
|
|
17928
|
+
};
|
|
17929
|
+
if (userActionHandlers.handleSaveNodeDetails) {
|
|
17930
|
+
userActionHandlers.handleSaveNodeDetails(
|
|
17931
|
+
actionHandlerContext,
|
|
17932
|
+
updatedNode,
|
|
17933
|
+
true
|
|
17934
|
+
);
|
|
17935
|
+
}
|
|
17936
|
+
setDetailsNode(updatedNode);
|
|
17937
|
+
},
|
|
17938
|
+
[session, actionHandlerContext]
|
|
17939
|
+
);
|
|
17940
|
+
const handleFinishQuestQuick = (0, import_react33.useCallback)(
|
|
17941
|
+
(questNode) => {
|
|
17942
|
+
var _a2, _b2, _c2, _d2;
|
|
17943
|
+
if (!questNode || !actionHandlerContext) return;
|
|
17944
|
+
const {
|
|
17945
|
+
labelObject,
|
|
17946
|
+
labelOffset,
|
|
17947
|
+
aura,
|
|
17948
|
+
borderRing,
|
|
17949
|
+
timelineIntervalBar,
|
|
17950
|
+
timelineEndLabel,
|
|
17951
|
+
...cleanQuestNode
|
|
17952
|
+
} = questNode;
|
|
17953
|
+
let nextAssigneeId = cleanQuestNode.assignee_id;
|
|
17954
|
+
let nextStatus = "Done";
|
|
17955
|
+
let newTimeline = [...cleanQuestNode.timeline || []];
|
|
17956
|
+
const reviewStack = [...cleanQuestNode.reviewStack || []];
|
|
17957
|
+
const currentReviewerIdx = reviewStack.findIndex(
|
|
17958
|
+
(r) => r.status !== "completed"
|
|
17959
|
+
);
|
|
17960
|
+
let nextIdxToAssign = 0;
|
|
17961
|
+
if (currentReviewerIdx !== -1 && reviewStack[currentReviewerIdx].userId === cleanQuestNode.assignee_id) {
|
|
17962
|
+
reviewStack[currentReviewerIdx].status = "completed";
|
|
17963
|
+
nextIdxToAssign = currentReviewerIdx + 1;
|
|
17907
17964
|
} else {
|
|
17908
|
-
|
|
17909
|
-
|
|
17910
|
-
|
|
17965
|
+
nextIdxToAssign = currentReviewerIdx !== -1 ? currentReviewerIdx : reviewStack.length;
|
|
17966
|
+
}
|
|
17967
|
+
if (nextIdxToAssign < reviewStack.length) {
|
|
17968
|
+
const remainingMandatory = reviewStack.slice(nextIdxToAssign).some((r) => r.mandatory);
|
|
17969
|
+
const hasAnyMandatory = reviewStack.some((r) => r.mandatory);
|
|
17970
|
+
if (!hasAnyMandatory || remainingMandatory) {
|
|
17971
|
+
const nextReviewer = reviewStack[nextIdxToAssign];
|
|
17972
|
+
nextAssigneeId = nextReviewer.userId;
|
|
17973
|
+
nextStatus = "Review";
|
|
17974
|
+
} else {
|
|
17975
|
+
nextStatus = "Done";
|
|
17976
|
+
for (let i = nextIdxToAssign; i < reviewStack.length; i++) {
|
|
17977
|
+
reviewStack[i].status = "skipped";
|
|
17978
|
+
}
|
|
17911
17979
|
}
|
|
17980
|
+
} else {
|
|
17981
|
+
nextStatus = "Done";
|
|
17912
17982
|
}
|
|
17913
|
-
|
|
17914
|
-
|
|
17915
|
-
|
|
17916
|
-
|
|
17917
|
-
|
|
17918
|
-
|
|
17919
|
-
|
|
17920
|
-
|
|
17921
|
-
|
|
17922
|
-
|
|
17923
|
-
)
|
|
17924
|
-
|
|
17925
|
-
|
|
17926
|
-
|
|
17927
|
-
|
|
17928
|
-
|
|
17929
|
-
|
|
17930
|
-
(
|
|
17931
|
-
|
|
17932
|
-
|
|
17933
|
-
|
|
17934
|
-
|
|
17935
|
-
|
|
17936
|
-
|
|
17937
|
-
|
|
17938
|
-
|
|
17939
|
-
|
|
17940
|
-
|
|
17941
|
-
|
|
17942
|
-
|
|
17943
|
-
|
|
17944
|
-
|
|
17945
|
-
|
|
17946
|
-
|
|
17947
|
-
|
|
17948
|
-
|
|
17949
|
-
|
|
17983
|
+
if (nextStatus === "Review") {
|
|
17984
|
+
const nextReviewerName = ((_a2 = viewMembers.find((m) => m.id === nextAssigneeId)) == null ? void 0 : _a2.name) || "revisor";
|
|
17985
|
+
newTimeline.push(
|
|
17986
|
+
createTimelineEntry(
|
|
17987
|
+
"system",
|
|
17988
|
+
`Status "Review" - Respons\xE1vel: ${nextReviewerName}`,
|
|
17989
|
+
"status_changed",
|
|
17990
|
+
{ metadata: { to_assignee_id: nextAssigneeId } }
|
|
17991
|
+
)
|
|
17992
|
+
);
|
|
17993
|
+
} else if (nextStatus === "Done") {
|
|
17994
|
+
const finisherName = ((_b2 = viewMembers.find(
|
|
17995
|
+
(m) => {
|
|
17996
|
+
var _a3;
|
|
17997
|
+
return m.id === (((_a3 = session == null ? void 0 : session.user) == null ? void 0 : _a3.id) || cleanQuestNode.assignee_id);
|
|
17998
|
+
}
|
|
17999
|
+
)) == null ? void 0 : _b2.name) || ((_c2 = session == null ? void 0 : session.user) == null ? void 0 : _c2.name) || "respons\xE1vel";
|
|
18000
|
+
newTimeline.push(
|
|
18001
|
+
createTimelineEntry(
|
|
18002
|
+
((_d2 = session == null ? void 0 : session.user) == null ? void 0 : _d2.id) || cleanQuestNode.assignee_id,
|
|
18003
|
+
`Status "Done" - Finalizado por ${finisherName}`,
|
|
18004
|
+
"status_changed"
|
|
18005
|
+
)
|
|
18006
|
+
);
|
|
18007
|
+
}
|
|
18008
|
+
const updatedNode = {
|
|
18009
|
+
...cleanQuestNode,
|
|
18010
|
+
status: nextStatus,
|
|
18011
|
+
color: nextStatus === "Done" ? "#22c55e" : "#a855f7",
|
|
18012
|
+
assignee_id: nextAssigneeId,
|
|
18013
|
+
reviewStack,
|
|
18014
|
+
timeline: newTimeline
|
|
18015
|
+
};
|
|
18016
|
+
if (userActionHandlers.handleSaveNodeDetails) {
|
|
18017
|
+
userActionHandlers.handleSaveNodeDetails(
|
|
18018
|
+
actionHandlerContext,
|
|
18019
|
+
updatedNode
|
|
18020
|
+
);
|
|
18021
|
+
}
|
|
18022
|
+
if (detailsNode && String(detailsNode.id) === String(cleanQuestNode.id)) {
|
|
18023
|
+
setDetailsNode(null);
|
|
18024
|
+
}
|
|
18025
|
+
},
|
|
18026
|
+
[session, actionHandlerContext, viewMembers, detailsNode]
|
|
18027
|
+
);
|
|
17950
18028
|
const handleCancelQuest = (0, import_react33.useCallback)(() => {
|
|
17951
18029
|
const { graphGroup, ghostElements } = stateRef.current;
|
|
17952
18030
|
if (ghostElements.node && graphGroup) {
|
|
@@ -17997,48 +18075,56 @@ function XViewScene({
|
|
|
17997
18075
|
if (questNodeId && sceneConfigId) {
|
|
17998
18076
|
const sceneData = sceneDataRef.current;
|
|
17999
18077
|
if (sceneData && sceneData.quest_nodes) {
|
|
18000
|
-
const questIndex = sceneData.quest_nodes.findIndex(
|
|
18078
|
+
const questIndex = sceneData.quest_nodes.findIndex(
|
|
18079
|
+
(q) => String(q.id) === String(questNodeId)
|
|
18080
|
+
);
|
|
18001
18081
|
if (questIndex !== -1) {
|
|
18002
18082
|
sceneData.quest_nodes[questIndex].quest_tree = formattedTree;
|
|
18003
18083
|
sceneData.quest_nodes[questIndex].quest_abstraction_tree = formattedAbstractionTree;
|
|
18004
18084
|
if (parentDataRef.current[sceneConfigId]) {
|
|
18005
|
-
const parentIndex = parentDataRef.current[sceneConfigId].nodes.findIndex(
|
|
18006
|
-
(q) => String(q.id) === String(questNodeId)
|
|
18007
|
-
);
|
|
18085
|
+
const parentIndex = parentDataRef.current[sceneConfigId].nodes.findIndex((q) => String(q.id) === String(questNodeId));
|
|
18008
18086
|
if (parentIndex !== -1) {
|
|
18009
18087
|
parentDataRef.current[sceneConfigId].nodes[parentIndex].quest_tree = formattedTree;
|
|
18010
18088
|
parentDataRef.current[sceneConfigId].nodes[parentIndex].quest_abstraction_tree = formattedAbstractionTree;
|
|
18011
18089
|
}
|
|
18012
18090
|
}
|
|
18013
|
-
|
|
18014
|
-
|
|
18015
|
-
|
|
18016
|
-
|
|
18017
|
-
|
|
18018
|
-
|
|
18019
|
-
|
|
18020
|
-
|
|
18021
|
-
|
|
18022
|
-
|
|
18023
|
-
|
|
18024
|
-
|
|
18025
|
-
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
|
|
18030
|
-
|
|
18031
|
-
|
|
18032
|
-
|
|
18033
|
-
|
|
18034
|
-
|
|
18035
|
-
|
|
18036
|
-
|
|
18037
|
-
|
|
18038
|
-
|
|
18039
|
-
|
|
18040
|
-
|
|
18091
|
+
const sceneFileData = {
|
|
18092
|
+
...sceneData,
|
|
18093
|
+
nodes: sceneData.nodes || [],
|
|
18094
|
+
links: sceneData.links || [],
|
|
18095
|
+
quest_counter: sceneData.quest_counter || 1
|
|
18096
|
+
};
|
|
18097
|
+
delete sceneFileData.quest_nodes;
|
|
18098
|
+
delete sceneFileData.quest_links;
|
|
18099
|
+
delete sceneFileData.milestones;
|
|
18100
|
+
const questFileData = {
|
|
18101
|
+
nodes: sceneData.quest_nodes || [],
|
|
18102
|
+
links: sceneData.quest_links || [],
|
|
18103
|
+
milestones: sceneData.milestones || []
|
|
18104
|
+
};
|
|
18105
|
+
await save_view_data(sceneSaveUrl, sceneFileData);
|
|
18106
|
+
const questSaveUrl = sceneSaveUrl.replace(
|
|
18107
|
+
"x_view_scenes",
|
|
18108
|
+
"x_view_quests"
|
|
18109
|
+
);
|
|
18110
|
+
await save_view_data(questSaveUrl, questFileData);
|
|
18111
|
+
}
|
|
18112
|
+
const updatedNodeData = sceneData.quest_nodes[questIndex];
|
|
18113
|
+
const nodeMesh = (_a2 = stateRef.current.nodeObjects) == null ? void 0 : _a2[String(questNodeId)];
|
|
18114
|
+
if (nodeMesh) {
|
|
18115
|
+
nodeMesh.userData = {
|
|
18116
|
+
...nodeMesh.userData,
|
|
18117
|
+
...updatedNodeData
|
|
18118
|
+
};
|
|
18041
18119
|
}
|
|
18120
|
+
if (detailsNode && String(detailsNode.id) === String(questNodeId)) {
|
|
18121
|
+
setDetailsNode((prev) => ({
|
|
18122
|
+
...prev,
|
|
18123
|
+
quest_tree: formattedTree,
|
|
18124
|
+
quest_abstraction_tree: formattedAbstractionTree
|
|
18125
|
+
}));
|
|
18126
|
+
}
|
|
18127
|
+
setSceneVersion((v) => v + 1);
|
|
18042
18128
|
}
|
|
18043
18129
|
}
|
|
18044
18130
|
};
|
|
@@ -18100,21 +18186,33 @@ function XViewScene({
|
|
|
18100
18186
|
graphDataRef2.current[sceneConfigId2].nodes.push(newNode);
|
|
18101
18187
|
const sceneFileData = {
|
|
18102
18188
|
...sceneDataRef2.current,
|
|
18103
|
-
quest_nodes: graphDataRef2.current[sceneConfigId2].nodes,
|
|
18104
|
-
quest_links: graphDataRef2.current[sceneConfigId2].links,
|
|
18105
18189
|
quest_counter: currentCounter + 1
|
|
18106
18190
|
};
|
|
18191
|
+
delete sceneFileData.quest_nodes;
|
|
18192
|
+
delete sceneFileData.quest_links;
|
|
18193
|
+
delete sceneFileData.milestones;
|
|
18194
|
+
const questFileData = {
|
|
18195
|
+
nodes: graphDataRef2.current[sceneConfigId2].nodes,
|
|
18196
|
+
links: graphDataRef2.current[sceneConfigId2].links,
|
|
18197
|
+
milestones: sceneDataRef2.current.milestones || []
|
|
18198
|
+
};
|
|
18107
18199
|
try {
|
|
18108
18200
|
await actions.save_view_data(sceneSaveUrl2, sceneFileData);
|
|
18201
|
+
const questSaveUrl = sceneSaveUrl2.replace("x_view_scenes", "x_view_quests");
|
|
18202
|
+
await actions.save_view_data(questSaveUrl, questFileData);
|
|
18109
18203
|
sceneDataRef2.current.quest_counter = currentCounter + 1;
|
|
18110
18204
|
stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
18111
18205
|
parentFileId: sceneConfigId2,
|
|
18112
18206
|
ownerId: ownerId2,
|
|
18113
18207
|
datasetName: "Quests Internas (View)"
|
|
18114
18208
|
});
|
|
18115
|
-
sceneDataRef2.current.quest_nodes = [
|
|
18209
|
+
sceneDataRef2.current.quest_nodes = [
|
|
18210
|
+
...graphDataRef2.current[sceneConfigId2].nodes
|
|
18211
|
+
];
|
|
18116
18212
|
if (parentDataRef.current[sceneConfigId2]) {
|
|
18117
|
-
parentDataRef.current[sceneConfigId2].nodes = [
|
|
18213
|
+
parentDataRef.current[sceneConfigId2].nodes = [
|
|
18214
|
+
...graphDataRef2.current[sceneConfigId2].nodes
|
|
18215
|
+
];
|
|
18118
18216
|
}
|
|
18119
18217
|
const finalPosition = stateRef2.current.ghostElements.node ? stateRef2.current.ghostElements.node.position.clone() : stateRef2.current.controls.target.clone();
|
|
18120
18218
|
const { graphGroup, ghostElements } = stateRef2.current;
|
|
@@ -18179,11 +18277,22 @@ function XViewScene({
|
|
|
18179
18277
|
specificParentData.links.push(newLink);
|
|
18180
18278
|
const viewFilePayload = {
|
|
18181
18279
|
...sceneDataRef2.current,
|
|
18182
|
-
quest_nodes: specificParentData.nodes,
|
|
18183
|
-
quest_links: specificParentData.links,
|
|
18184
18280
|
quest_counter: sceneDataRef2.current.quest_counter || 1
|
|
18185
18281
|
};
|
|
18282
|
+
delete viewFilePayload.quest_nodes;
|
|
18283
|
+
delete viewFilePayload.quest_links;
|
|
18284
|
+
delete viewFilePayload.milestones;
|
|
18285
|
+
const questFilePayload = {
|
|
18286
|
+
nodes: specificParentData.nodes,
|
|
18287
|
+
links: specificParentData.links,
|
|
18288
|
+
milestones: sceneDataRef2.current.milestones || []
|
|
18289
|
+
};
|
|
18186
18290
|
await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
|
|
18291
|
+
const questSaveUrl = sceneSaveUrl2.replace(
|
|
18292
|
+
"x_view_scenes",
|
|
18293
|
+
"x_view_quests"
|
|
18294
|
+
);
|
|
18295
|
+
await context.actions.save_view_data(questSaveUrl, questFilePayload);
|
|
18187
18296
|
} else {
|
|
18188
18297
|
const specificParentData = JSON.parse(
|
|
18189
18298
|
JSON.stringify(graphDataRef2.current[parentFileIdToSave])
|
|
@@ -18216,9 +18325,7 @@ function XViewScene({
|
|
|
18216
18325
|
if (line.material) line.material.dispose();
|
|
18217
18326
|
});
|
|
18218
18327
|
renderedAncestries.splice(renderIndex, 1);
|
|
18219
|
-
stateRef.current.ancestryLinks = renderedAncestries.flatMap(
|
|
18220
|
-
(a) => a.lines
|
|
18221
|
-
);
|
|
18328
|
+
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
18222
18329
|
}
|
|
18223
18330
|
}, []);
|
|
18224
18331
|
const handleRenderAncestry = (0, import_react33.useCallback)(
|
|
@@ -18791,9 +18898,7 @@ function XViewScene({
|
|
|
18791
18898
|
});
|
|
18792
18899
|
};
|
|
18793
18900
|
renderVertical(fullTree, rootNodeMesh, rootTargetPos, 1);
|
|
18794
|
-
stateRef.current.ancestryLinks = renderedAncestries.flatMap(
|
|
18795
|
-
(a) => a.lines
|
|
18796
|
-
);
|
|
18901
|
+
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
18797
18902
|
tweenToTarget(rootTargetPos, 0.7);
|
|
18798
18903
|
},
|
|
18799
18904
|
[
|
|
@@ -18928,10 +19033,7 @@ function XViewScene({
|
|
|
18928
19033
|
};
|
|
18929
19034
|
const descriptionText = targetAncestryInfo.description || "";
|
|
18930
19035
|
const savedSections = targetAncestryInfo.description_sections || [];
|
|
18931
|
-
const sections = parseDescriptionSections(
|
|
18932
|
-
descriptionText,
|
|
18933
|
-
savedSections
|
|
18934
|
-
);
|
|
19036
|
+
const sections = parseDescriptionSections(descriptionText, savedSections);
|
|
18935
19037
|
let focusTargetId = null;
|
|
18936
19038
|
if (popped && popped.nodeId) {
|
|
18937
19039
|
const mentionTag = `[[MENTION:node:${popped.nodeId}]]`;
|
|
@@ -19544,16 +19646,26 @@ function XViewScene({
|
|
|
19544
19646
|
const result = await save_view_data(finalSaveUrl, masterAncestryList);
|
|
19545
19647
|
if (result.success && isExternalSave && isEditMode && currentAncestryId && ancestry_save_url && get_ancestry_file) {
|
|
19546
19648
|
try {
|
|
19547
|
-
const viewDbResponse = await get_ancestry_file(
|
|
19649
|
+
const viewDbResponse = await get_ancestry_file(
|
|
19650
|
+
sceneConfigId,
|
|
19651
|
+
ownerId
|
|
19652
|
+
);
|
|
19548
19653
|
if (viewDbResponse.success && Array.isArray(viewDbResponse.data)) {
|
|
19549
|
-
const hasInViewDb = viewDbResponse.data.some(
|
|
19654
|
+
const hasInViewDb = viewDbResponse.data.some(
|
|
19655
|
+
(anc) => String(anc.ancestry_id) === String(currentAncestryId)
|
|
19656
|
+
);
|
|
19550
19657
|
if (hasInViewDb) {
|
|
19551
|
-
const updatedViewDb = viewDbResponse.data.filter(
|
|
19658
|
+
const updatedViewDb = viewDbResponse.data.filter(
|
|
19659
|
+
(anc) => String(anc.ancestry_id) !== String(currentAncestryId)
|
|
19660
|
+
);
|
|
19552
19661
|
await save_view_data(ancestry_save_url, updatedViewDb);
|
|
19553
19662
|
}
|
|
19554
19663
|
}
|
|
19555
19664
|
} catch (fallbackErr) {
|
|
19556
|
-
console.error(
|
|
19665
|
+
console.error(
|
|
19666
|
+
"Falha ao limpar c\xF3pia residual na edi\xE7\xE3o:",
|
|
19667
|
+
fallbackErr
|
|
19668
|
+
);
|
|
19557
19669
|
}
|
|
19558
19670
|
}
|
|
19559
19671
|
if (result.success) {
|
|
@@ -19664,7 +19776,10 @@ function XViewScene({
|
|
|
19664
19776
|
try {
|
|
19665
19777
|
let updatedAncestriesForFile;
|
|
19666
19778
|
if (get_ancestry_file && isExternalSave) {
|
|
19667
|
-
const remoteResponse = await get_ancestry_file(
|
|
19779
|
+
const remoteResponse = await get_ancestry_file(
|
|
19780
|
+
sourceFileId,
|
|
19781
|
+
sourceOwnerId
|
|
19782
|
+
);
|
|
19668
19783
|
if (remoteResponse.success && Array.isArray(remoteResponse.data)) {
|
|
19669
19784
|
updatedAncestriesForFile = remoteResponse.data.filter(
|
|
19670
19785
|
(anc) => String(anc.ancestry_id) !== String(ancestryIdToDelete)
|
|
@@ -19679,11 +19794,16 @@ function XViewScene({
|
|
|
19679
19794
|
(anc) => anc._source_file_id === sourceFileId && String(anc.ancestry_id) !== String(ancestryIdToDelete)
|
|
19680
19795
|
);
|
|
19681
19796
|
}
|
|
19682
|
-
const result = await save_view_data(
|
|
19797
|
+
const result = await save_view_data(
|
|
19798
|
+
finalSaveUrl,
|
|
19799
|
+
updatedAncestriesForFile
|
|
19800
|
+
);
|
|
19683
19801
|
if (result.success) {
|
|
19684
19802
|
success = true;
|
|
19685
19803
|
} else {
|
|
19686
|
-
throw new Error(
|
|
19804
|
+
throw new Error(
|
|
19805
|
+
result.error || "Ocorreu um erro desconhecido ao excluir."
|
|
19806
|
+
);
|
|
19687
19807
|
}
|
|
19688
19808
|
} catch (error) {
|
|
19689
19809
|
deletionError = error;
|
|
@@ -19692,15 +19812,25 @@ function XViewScene({
|
|
|
19692
19812
|
try {
|
|
19693
19813
|
const viewDbResponse = await get_ancestry_file(sceneConfigId, ownerId);
|
|
19694
19814
|
if (viewDbResponse.success && Array.isArray(viewDbResponse.data)) {
|
|
19695
|
-
const hasInViewDb = viewDbResponse.data.some(
|
|
19815
|
+
const hasInViewDb = viewDbResponse.data.some(
|
|
19816
|
+
(anc) => String(anc.ancestry_id) === String(ancestryIdToDelete)
|
|
19817
|
+
);
|
|
19696
19818
|
if (hasInViewDb) {
|
|
19697
|
-
const updatedViewDb = viewDbResponse.data.filter(
|
|
19698
|
-
|
|
19819
|
+
const updatedViewDb = viewDbResponse.data.filter(
|
|
19820
|
+
(anc) => String(anc.ancestry_id) !== String(ancestryIdToDelete)
|
|
19821
|
+
);
|
|
19822
|
+
const fallbackResult = await save_view_data(
|
|
19823
|
+
ancestry_save_url,
|
|
19824
|
+
updatedViewDb
|
|
19825
|
+
);
|
|
19699
19826
|
if (fallbackResult.success) success = true;
|
|
19700
19827
|
}
|
|
19701
19828
|
}
|
|
19702
19829
|
} catch (fallbackErr) {
|
|
19703
|
-
console.error(
|
|
19830
|
+
console.error(
|
|
19831
|
+
"Falha ao limpar c\xF3pia residual da View DB:",
|
|
19832
|
+
fallbackErr
|
|
19833
|
+
);
|
|
19704
19834
|
}
|
|
19705
19835
|
}
|
|
19706
19836
|
if (!success && deletionError) {
|
|
@@ -19878,23 +20008,28 @@ function XViewScene({
|
|
|
19878
20008
|
...sceneDataRef.current,
|
|
19879
20009
|
nodes: sceneDataRef.current.nodes || [],
|
|
19880
20010
|
links: sceneDataRef.current.links || [],
|
|
19881
|
-
|
|
19882
|
-
|
|
19883
|
-
|
|
20011
|
+
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
20012
|
+
};
|
|
20013
|
+
delete sceneFileData.quest_nodes;
|
|
20014
|
+
delete sceneFileData.quest_links;
|
|
20015
|
+
delete sceneFileData.milestones;
|
|
20016
|
+
const questFileData = {
|
|
20017
|
+
nodes: ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || sceneDataRef.current.quest_nodes || [],
|
|
20018
|
+
links: ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || sceneDataRef.current.quest_links || [],
|
|
19884
20019
|
milestones: newMilestones
|
|
19885
20020
|
};
|
|
19886
20021
|
try {
|
|
19887
20022
|
await save_view_data(sceneSaveUrl, sceneFileData);
|
|
20023
|
+
const questSaveUrl = sceneSaveUrl.replace(
|
|
20024
|
+
"x_view_scenes",
|
|
20025
|
+
"x_view_quests"
|
|
20026
|
+
);
|
|
20027
|
+
await save_view_data(questSaveUrl, questFileData);
|
|
19888
20028
|
} catch (error) {
|
|
19889
20029
|
console.error("Erro ao salvar milestones:", error);
|
|
19890
20030
|
}
|
|
19891
20031
|
},
|
|
19892
|
-
[
|
|
19893
|
-
sceneConfigId,
|
|
19894
|
-
sceneSaveUrl,
|
|
19895
|
-
save_view_data,
|
|
19896
|
-
viewParams == null ? void 0 : viewParams.type
|
|
19897
|
-
]
|
|
20032
|
+
[sceneConfigId, sceneSaveUrl, save_view_data, viewParams == null ? void 0 : viewParams.type]
|
|
19898
20033
|
);
|
|
19899
20034
|
const handleSaveCurrentView = (0, import_react33.useCallback)(async () => {
|
|
19900
20035
|
var _a2, _b2, _c2;
|
|
@@ -19928,13 +20063,25 @@ function XViewScene({
|
|
|
19928
20063
|
...sceneDataRef.current,
|
|
19929
20064
|
nodes: currentNodes,
|
|
19930
20065
|
links: currentLinks,
|
|
19931
|
-
|
|
19932
|
-
|
|
19933
|
-
|
|
20066
|
+
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
20067
|
+
};
|
|
20068
|
+
delete sceneFileData.quest_nodes;
|
|
20069
|
+
delete sceneFileData.quest_links;
|
|
20070
|
+
delete sceneFileData.milestones;
|
|
20071
|
+
const questFileData = {
|
|
20072
|
+
nodes: isView ? ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || [] : sceneDataRef.current.quest_nodes || [],
|
|
20073
|
+
links: isView ? ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || [] : sceneDataRef.current.quest_links || [],
|
|
19934
20074
|
milestones: sceneDataRef.current.milestones || []
|
|
19935
20075
|
};
|
|
19936
20076
|
try {
|
|
19937
20077
|
await save_view_data(sceneSaveUrl, sceneFileData);
|
|
20078
|
+
if (isView) {
|
|
20079
|
+
const questSaveUrl = sceneSaveUrl.replace(
|
|
20080
|
+
"x_view_scenes",
|
|
20081
|
+
"x_view_quests"
|
|
20082
|
+
);
|
|
20083
|
+
await save_view_data(questSaveUrl, questFileData);
|
|
20084
|
+
}
|
|
19938
20085
|
} catch (error) {
|
|
19939
20086
|
console.error("Erro na chamada de save_view_data:", error);
|
|
19940
20087
|
}
|
|
@@ -20051,7 +20198,12 @@ function XViewScene({
|
|
|
20051
20198
|
if (isUiClear) {
|
|
20052
20199
|
const isView = ((_c2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _c2.toLowerCase()) === "view";
|
|
20053
20200
|
if (!isView) return;
|
|
20054
|
-
const {
|
|
20201
|
+
const {
|
|
20202
|
+
graphGroup,
|
|
20203
|
+
glowTexture,
|
|
20204
|
+
controls: sceneControls,
|
|
20205
|
+
nodeObjects
|
|
20206
|
+
} = stateRef.current;
|
|
20055
20207
|
if (graphGroup) {
|
|
20056
20208
|
let ghostPosition = sceneControls.target.clone();
|
|
20057
20209
|
const existingNodes = Object.values(nodeObjects);
|
|
@@ -20107,7 +20259,12 @@ function XViewScene({
|
|
|
20107
20259
|
setQuestMode({ isActive: true });
|
|
20108
20260
|
}
|
|
20109
20261
|
}
|
|
20110
|
-
const isArrowKey = [
|
|
20262
|
+
const isArrowKey = [
|
|
20263
|
+
"ArrowUp",
|
|
20264
|
+
"ArrowDown",
|
|
20265
|
+
"ArrowLeft",
|
|
20266
|
+
"ArrowRight"
|
|
20267
|
+
].includes(event.key);
|
|
20111
20268
|
if (isArrowKey) {
|
|
20112
20269
|
const isUiClear = !stateRef.current.creation.isActive && !stateRef.current.connection.isActive && !stateRef.current.relink.isActive && !stateRef.current.ancestry.isActive && !((_d2 = context.versionMode) == null ? void 0 : _d2.isActive) && !contextMenu.visible && !multiContextMenu.visible && !relationshipMenu.visible && !readingMode.isActive && !isImportModalOpen && !isBoardsOpen && !isSidebarOpen && !isMilestoneManagerOpen && !detailsNode && !detailsLink && !ancestryLinkDetails && !imageViewer.visible && !editingAncestryRel.visible && !questMode.isActive;
|
|
20113
20270
|
if (isUiClear) {
|
|
@@ -20153,7 +20310,12 @@ function XViewScene({
|
|
|
20153
20310
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
20154
20311
|
return /* @__PURE__ */ import_react33.default.createElement(LoadingScreen, null);
|
|
20155
20312
|
}
|
|
20156
|
-
const overlayHiddenStyle = questTreeMode.isActive ? {
|
|
20313
|
+
const overlayHiddenStyle = questTreeMode.isActive ? {
|
|
20314
|
+
opacity: 0,
|
|
20315
|
+
pointerEvents: "none",
|
|
20316
|
+
transform: "translateX(30px)",
|
|
20317
|
+
transition: "all 300ms ease-in-out"
|
|
20318
|
+
} : {};
|
|
20157
20319
|
if (permissionStatus === "denied") {
|
|
20158
20320
|
return /* @__PURE__ */ import_react33.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react33.default.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ import_react33.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react33.default.createElement(
|
|
20159
20321
|
"svg",
|
|
@@ -20618,18 +20780,12 @@ function XViewScene({
|
|
|
20618
20780
|
data: multiContextMenu,
|
|
20619
20781
|
userRole: userPermissionRole,
|
|
20620
20782
|
onClose: () => setMultiContextMenu((prev) => ({ ...prev, visible: false })),
|
|
20621
|
-
onDismissNodes: (ids) => userActionHandlers.handleDismissMultipleNodes(
|
|
20622
|
-
actionHandlerContext,
|
|
20623
|
-
ids
|
|
20624
|
-
),
|
|
20783
|
+
onDismissNodes: (ids) => userActionHandlers.handleDismissMultipleNodes(actionHandlerContext, ids),
|
|
20625
20784
|
onDismissOtherNodes: (ids) => userActionHandlers.handleDismissOtherMultipleNodes(
|
|
20626
20785
|
actionHandlerContext,
|
|
20627
20786
|
ids
|
|
20628
20787
|
),
|
|
20629
|
-
onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(
|
|
20630
|
-
actionHandlerContext,
|
|
20631
|
-
ids
|
|
20632
|
-
)
|
|
20788
|
+
onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
|
|
20633
20789
|
}
|
|
20634
20790
|
),
|
|
20635
20791
|
/* @__PURE__ */ import_react33.default.createElement(
|
|
@@ -20782,7 +20938,7 @@ async function save_view_data_logic(db_services, filename, data) {
|
|
|
20782
20938
|
}
|
|
20783
20939
|
}
|
|
20784
20940
|
async function get_scene_view_data_logic(db_services, scene_config, owner_id, type, session, focusNodeId = null, focusAncestryId = null) {
|
|
20785
|
-
var _a, _b;
|
|
20941
|
+
var _a, _b, _c;
|
|
20786
20942
|
try {
|
|
20787
20943
|
if (!session || !session.user) {
|
|
20788
20944
|
return { success: false, error: "Usu\xE1rio n\xE3o autenticado." };
|
|
@@ -20805,28 +20961,44 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
20805
20961
|
parentDbObjects.push({ db_id: scene_config, owner_id });
|
|
20806
20962
|
}
|
|
20807
20963
|
}
|
|
20964
|
+
const isView = type && type.toLowerCase() === "view";
|
|
20808
20965
|
const parentResponsesPromises = parentDbObjects.map(
|
|
20809
20966
|
(db_info) => db_services.get_file(`x_view_dbs/${db_info.owner_id}/${db_info.db_id}`)
|
|
20810
20967
|
);
|
|
20968
|
+
if (isView) {
|
|
20969
|
+
parentResponsesPromises.push(
|
|
20970
|
+
db_services.get_file(`x_view_quests/${owner_id}/${scene_config}`)
|
|
20971
|
+
);
|
|
20972
|
+
}
|
|
20811
20973
|
const parentResponsesResults = await Promise.allSettled(parentResponsesPromises);
|
|
20812
20974
|
const parentData = {};
|
|
20975
|
+
let questDataObj = null;
|
|
20813
20976
|
for (let i = 0; i < parentResponsesResults.length; i++) {
|
|
20814
20977
|
const result = parentResponsesResults[i];
|
|
20978
|
+
if (isView && i === parentResponsesResults.length - 1) {
|
|
20979
|
+
if (result.status === "fulfilled" && ((_a = result.value) == null ? void 0 : _a.success)) {
|
|
20980
|
+
questDataObj = result.value.data;
|
|
20981
|
+
}
|
|
20982
|
+
continue;
|
|
20983
|
+
}
|
|
20815
20984
|
const db_info = parentDbObjects[i];
|
|
20816
|
-
if (result.status === "fulfilled" && ((
|
|
20985
|
+
if (result.status === "fulfilled" && ((_b = result.value) == null ? void 0 : _b.success)) {
|
|
20817
20986
|
parentData[db_info.db_id] = result.value.data;
|
|
20818
20987
|
} else {
|
|
20819
20988
|
console.warn(
|
|
20820
20989
|
`Arquivo pai n\xE3o carregado: ${db_info.db_id}. Pode ter sido deletado.`,
|
|
20821
|
-
result.status === "rejected" ? result.reason : (
|
|
20990
|
+
result.status === "rejected" ? result.reason : (_c = result.value) == null ? void 0 : _c.error
|
|
20822
20991
|
);
|
|
20823
20992
|
}
|
|
20824
20993
|
}
|
|
20825
|
-
|
|
20994
|
+
const currentQuestNodes = (questDataObj == null ? void 0 : questDataObj.nodes) || sceneData.quest_nodes || [];
|
|
20995
|
+
const currentQuestLinks = (questDataObj == null ? void 0 : questDataObj.links) || sceneData.quest_links || [];
|
|
20996
|
+
const currentMilestones = (questDataObj == null ? void 0 : questDataObj.milestones) || sceneData.milestones || [];
|
|
20997
|
+
if (isView) {
|
|
20826
20998
|
parentData[scene_config] = {
|
|
20827
20999
|
dataset_name: "Quests Internas (View)",
|
|
20828
|
-
nodes:
|
|
20829
|
-
links:
|
|
21000
|
+
nodes: currentQuestNodes,
|
|
21001
|
+
links: currentQuestLinks
|
|
20830
21002
|
};
|
|
20831
21003
|
}
|
|
20832
21004
|
const allNodes = Object.values(parentData).flatMap((db) => db.nodes || []);
|
|
@@ -20858,7 +21030,12 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
20858
21030
|
const validatedSceneData = {
|
|
20859
21031
|
...sceneData,
|
|
20860
21032
|
nodes: validatedNodes,
|
|
20861
|
-
links: validatedLinks
|
|
21033
|
+
links: validatedLinks,
|
|
21034
|
+
// Re-injetando no validated para que o restante do sistema (e.g. XViewScene local state)
|
|
21035
|
+
// continue acessando as quests sem perceber a separação física
|
|
21036
|
+
quest_nodes: currentQuestNodes,
|
|
21037
|
+
quest_links: currentQuestLinks,
|
|
21038
|
+
milestones: currentMilestones
|
|
20862
21039
|
};
|
|
20863
21040
|
const ancestryFilePaths = [];
|
|
20864
21041
|
ancestryFilePaths.push({
|