@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.mjs
CHANGED
|
@@ -15670,7 +15670,7 @@ function XViewScene({
|
|
|
15670
15670
|
stateRef.current.questTree = questTreeMode;
|
|
15671
15671
|
}, [questTreeMode]);
|
|
15672
15672
|
useEffect25(() => {
|
|
15673
|
-
var _a2;
|
|
15673
|
+
var _a2, _b2;
|
|
15674
15674
|
if (!isInitialized) return;
|
|
15675
15675
|
const map = /* @__PURE__ */ new Map();
|
|
15676
15676
|
const parentDbsArray = ((_a2 = sceneDataRef.current) == null ? void 0 : _a2.parent_dbs) || [];
|
|
@@ -15682,8 +15682,9 @@ function XViewScene({
|
|
|
15682
15682
|
(db) => String(db.db_id) === String(parentFileId)
|
|
15683
15683
|
);
|
|
15684
15684
|
const isCurrentView = String(parentFileId) === String(sceneConfigId);
|
|
15685
|
+
const isViewType = ((_b2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _b2.toLowerCase()) === "view";
|
|
15685
15686
|
const ownerId2 = (parentDbInfo == null ? void 0 : parentDbInfo.owner_id) || (isCurrentView ? viewParams == null ? void 0 : viewParams.owner_id : null);
|
|
15686
|
-
const datasetName = isCurrentView ? "Quests Internas (View)" : parentFile.dataset_name || `Dataset #${parentFileId.substring(0, 6)}`;
|
|
15687
|
+
const datasetName = isCurrentView && isViewType ? "Quests Internas (View)" : parentFile.dataset_name || `Dataset #${parentFileId.substring(0, 6)}`;
|
|
15687
15688
|
if (parentFile.nodes && ownerId2) {
|
|
15688
15689
|
for (const node of parentFile.nodes) {
|
|
15689
15690
|
map.set(String(node.id), { parentFileId, ownerId: ownerId2, datasetName });
|
|
@@ -15852,7 +15853,11 @@ function XViewScene({
|
|
|
15852
15853
|
};
|
|
15853
15854
|
const tweenToTarget = useCallback7(
|
|
15854
15855
|
(target, zoomFactor = 1, forcedDirection = null) => {
|
|
15855
|
-
const {
|
|
15856
|
+
const {
|
|
15857
|
+
camera: sceneCamera,
|
|
15858
|
+
controls: sceneControls,
|
|
15859
|
+
tweenGroup
|
|
15860
|
+
} = stateRef.current;
|
|
15856
15861
|
if (!sceneCamera || !sceneControls || !tweenGroup) return;
|
|
15857
15862
|
const targetPos = target instanceof THREE3.Mesh ? target.getWorldPosition(new THREE3.Vector3()) : target;
|
|
15858
15863
|
const controlsTween = new Tween2(sceneControls.target).to(targetPos, 1500).easing(Easing2.Cubic.Out);
|
|
@@ -16409,341 +16414,372 @@ function XViewScene({
|
|
|
16409
16414
|
},
|
|
16410
16415
|
[]
|
|
16411
16416
|
);
|
|
16412
|
-
const handleActivateReshapeLens = useCallback7(
|
|
16413
|
-
|
|
16414
|
-
|
|
16415
|
-
|
|
16416
|
-
|
|
16417
|
-
|
|
16418
|
-
|
|
16419
|
-
|
|
16420
|
-
|
|
16421
|
-
|
|
16422
|
-
if (mesh && mesh.material) {
|
|
16423
|
-
const opacityTween = new Tween2(mesh.material).to({ opacity: 1 }, 1200).easing(Easing2.Cubic.Out);
|
|
16424
|
-
tweenGroup.add(opacityTween);
|
|
16425
|
-
opacityTween.start();
|
|
16426
|
-
}
|
|
16427
|
-
if (mesh && mesh.userData && mesh.userData.labelObject) {
|
|
16428
|
-
mesh.userData.labelObject.visible = true;
|
|
16429
|
-
}
|
|
16430
|
-
});
|
|
16431
|
-
if (type === "Column") {
|
|
16432
|
-
const colSpacing = 80;
|
|
16433
|
-
const rowSpacing = 80;
|
|
16434
|
-
const numCols = columns || 4;
|
|
16435
|
-
activeNodeIds.forEach((id, index) => {
|
|
16436
|
-
const mesh = nodeObjects[id];
|
|
16437
|
-
const col = index % numCols;
|
|
16438
|
-
const row = Math.floor(index / numCols);
|
|
16439
|
-
const targetX = (col - (numCols - 1) / 2) * colSpacing;
|
|
16440
|
-
const targetY = -(row * rowSpacing) + 50;
|
|
16441
|
-
const posTween = new Tween2(mesh.position).to({ x: targetX, y: targetY, z: 0 }, 1500).easing(Easing2.Cubic.InOut);
|
|
16442
|
-
tweenGroup.add(posTween);
|
|
16443
|
-
posTween.start();
|
|
16444
|
-
if (mesh.userData.labelObject) {
|
|
16445
|
-
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
16446
|
-
const lblTween = new Tween2(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(Easing2.Cubic.InOut);
|
|
16447
|
-
tweenGroup.add(lblTween);
|
|
16448
|
-
lblTween.start();
|
|
16449
|
-
}
|
|
16450
|
-
sumX += targetX;
|
|
16451
|
-
sumY += targetY;
|
|
16452
|
-
nodeCount++;
|
|
16453
|
-
});
|
|
16454
|
-
} else if (type === "Circle") {
|
|
16455
|
-
const total = activeNodeIds.length;
|
|
16456
|
-
const radius = Math.max(80, total * 8);
|
|
16457
|
-
activeNodeIds.forEach((id, index) => {
|
|
16417
|
+
const handleActivateReshapeLens = useCallback7(
|
|
16418
|
+
({ type, columns, centerNodeId }) => {
|
|
16419
|
+
const { nodeObjects, tweenGroup, camera, controls } = stateRef.current;
|
|
16420
|
+
if (!nodeObjects || !tweenGroup || !camera || !controls) return;
|
|
16421
|
+
const activeNodeIds = Object.keys(nodeObjects);
|
|
16422
|
+
if (activeNodeIds.length === 0) return;
|
|
16423
|
+
let sumX = 0;
|
|
16424
|
+
let sumY = 0;
|
|
16425
|
+
let nodeCount = 0;
|
|
16426
|
+
activeNodeIds.forEach((id) => {
|
|
16458
16427
|
const mesh = nodeObjects[id];
|
|
16459
|
-
|
|
16460
|
-
|
|
16461
|
-
|
|
16462
|
-
|
|
16463
|
-
|
|
16464
|
-
|
|
16465
|
-
|
|
16466
|
-
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
16467
|
-
const lblTween = new Tween2(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(Easing2.Cubic.InOut);
|
|
16468
|
-
tweenGroup.add(lblTween);
|
|
16469
|
-
lblTween.start();
|
|
16470
|
-
}
|
|
16471
|
-
sumX += targetX;
|
|
16472
|
-
sumY += targetY;
|
|
16473
|
-
nodeCount++;
|
|
16474
|
-
});
|
|
16475
|
-
} else if (type === "Star") {
|
|
16476
|
-
const centerMesh = centerNodeId ? nodeObjects[String(centerNodeId)] : null;
|
|
16477
|
-
const orbitingNodeIds = activeNodeIds.filter((id) => id !== String(centerNodeId));
|
|
16478
|
-
const totalOrbiting = orbitingNodeIds.length;
|
|
16479
|
-
const radius = Math.max(80, totalOrbiting * 10);
|
|
16480
|
-
if (centerMesh) {
|
|
16481
|
-
const posTween = new Tween2(centerMesh.position).to({ x: 0, y: 0, z: 0 }, 1500).easing(Easing2.Cubic.InOut);
|
|
16482
|
-
tweenGroup.add(posTween);
|
|
16483
|
-
posTween.start();
|
|
16484
|
-
if (centerMesh.userData.labelObject) {
|
|
16485
|
-
const labelTarget = new THREE3.Vector3(0, 0, 0).add(centerMesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
16486
|
-
const lblTween = new Tween2(centerMesh.userData.labelObject.position).to(labelTarget, 1500).easing(Easing2.Cubic.InOut);
|
|
16487
|
-
tweenGroup.add(lblTween);
|
|
16488
|
-
lblTween.start();
|
|
16428
|
+
if (mesh && mesh.material) {
|
|
16429
|
+
const opacityTween = new Tween2(mesh.material).to({ opacity: 1 }, 1200).easing(Easing2.Cubic.Out);
|
|
16430
|
+
tweenGroup.add(opacityTween);
|
|
16431
|
+
opacityTween.start();
|
|
16432
|
+
}
|
|
16433
|
+
if (mesh && mesh.userData && mesh.userData.labelObject) {
|
|
16434
|
+
mesh.userData.labelObject.visible = true;
|
|
16489
16435
|
}
|
|
16490
|
-
sumX += 0;
|
|
16491
|
-
sumY += 0;
|
|
16492
|
-
nodeCount++;
|
|
16493
|
-
}
|
|
16494
|
-
orbitingNodeIds.forEach((id, index) => {
|
|
16495
|
-
const mesh = nodeObjects[id];
|
|
16496
|
-
const angle = totalOrbiting > 0 ? index / totalOrbiting * Math.PI * 2 : 0;
|
|
16497
|
-
const targetX = Math.cos(angle) * radius;
|
|
16498
|
-
const targetY = Math.sin(angle) * radius;
|
|
16499
|
-
const posTween = new Tween2(mesh.position).to({ x: targetX, y: targetY, z: 0 }, 1500).easing(Easing2.Cubic.InOut);
|
|
16500
|
-
tweenGroup.add(posTween);
|
|
16501
|
-
posTween.start();
|
|
16502
|
-
if (mesh.userData.labelObject) {
|
|
16503
|
-
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
16504
|
-
const lblTween = new Tween2(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(Easing2.Cubic.InOut);
|
|
16505
|
-
tweenGroup.add(lblTween);
|
|
16506
|
-
lblTween.start();
|
|
16507
|
-
}
|
|
16508
|
-
sumX += targetX;
|
|
16509
|
-
sumY += targetY;
|
|
16510
|
-
nodeCount++;
|
|
16511
16436
|
});
|
|
16512
|
-
}
|
|
16513
|
-
if (nodeCount > 0) {
|
|
16514
|
-
const centerX = sumX / nodeCount;
|
|
16515
|
-
const centerY = sumY / nodeCount;
|
|
16516
|
-
const targetFocus = new THREE3.Vector3(centerX, centerY, 0);
|
|
16517
|
-
const targetTween = new Tween2(controls.target).to({ x: targetFocus.x, y: targetFocus.y, z: targetFocus.z }, 1500).easing(Easing2.Cubic.InOut);
|
|
16518
|
-
tweenGroup.add(targetTween);
|
|
16519
|
-
targetTween.start();
|
|
16520
|
-
let zoomZ = 140;
|
|
16521
16437
|
if (type === "Column") {
|
|
16522
|
-
const
|
|
16523
|
-
|
|
16524
|
-
|
|
16525
|
-
|
|
16526
|
-
|
|
16527
|
-
|
|
16528
|
-
|
|
16529
|
-
|
|
16530
|
-
|
|
16531
|
-
|
|
16532
|
-
|
|
16533
|
-
|
|
16534
|
-
|
|
16535
|
-
|
|
16536
|
-
|
|
16537
|
-
|
|
16538
|
-
|
|
16539
|
-
|
|
16540
|
-
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
|
|
16545
|
-
|
|
16546
|
-
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16438
|
+
const colSpacing = 80;
|
|
16439
|
+
const rowSpacing = 80;
|
|
16440
|
+
const numCols = columns || 4;
|
|
16441
|
+
activeNodeIds.forEach((id, index) => {
|
|
16442
|
+
const mesh = nodeObjects[id];
|
|
16443
|
+
const col = index % numCols;
|
|
16444
|
+
const row = Math.floor(index / numCols);
|
|
16445
|
+
const targetX = (col - (numCols - 1) / 2) * colSpacing;
|
|
16446
|
+
const targetY = -(row * rowSpacing) + 50;
|
|
16447
|
+
const posTween = new Tween2(mesh.position).to({ x: targetX, y: targetY, z: 0 }, 1500).easing(Easing2.Cubic.InOut);
|
|
16448
|
+
tweenGroup.add(posTween);
|
|
16449
|
+
posTween.start();
|
|
16450
|
+
if (mesh.userData.labelObject) {
|
|
16451
|
+
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(
|
|
16452
|
+
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16453
|
+
);
|
|
16454
|
+
const lblTween = new Tween2(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(Easing2.Cubic.InOut);
|
|
16455
|
+
tweenGroup.add(lblTween);
|
|
16456
|
+
lblTween.start();
|
|
16457
|
+
}
|
|
16458
|
+
sumX += targetX;
|
|
16459
|
+
sumY += targetY;
|
|
16460
|
+
nodeCount++;
|
|
16461
|
+
});
|
|
16462
|
+
} else if (type === "Circle") {
|
|
16463
|
+
const total = activeNodeIds.length;
|
|
16464
|
+
const radius = Math.max(80, total * 8);
|
|
16465
|
+
activeNodeIds.forEach((id, index) => {
|
|
16466
|
+
const mesh = nodeObjects[id];
|
|
16467
|
+
const angle = index / total * Math.PI * 2;
|
|
16468
|
+
const targetX = Math.cos(angle) * radius;
|
|
16469
|
+
const targetY = Math.sin(angle) * radius;
|
|
16470
|
+
const posTween = new Tween2(mesh.position).to({ x: targetX, y: targetY, z: 0 }, 1500).easing(Easing2.Cubic.InOut);
|
|
16471
|
+
tweenGroup.add(posTween);
|
|
16472
|
+
posTween.start();
|
|
16473
|
+
if (mesh.userData.labelObject) {
|
|
16474
|
+
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(
|
|
16475
|
+
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16476
|
+
);
|
|
16477
|
+
const lblTween = new Tween2(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(Easing2.Cubic.InOut);
|
|
16478
|
+
tweenGroup.add(lblTween);
|
|
16479
|
+
lblTween.start();
|
|
16480
|
+
}
|
|
16481
|
+
sumX += targetX;
|
|
16482
|
+
sumY += targetY;
|
|
16483
|
+
nodeCount++;
|
|
16484
|
+
});
|
|
16485
|
+
} else if (type === "Star") {
|
|
16486
|
+
const centerMesh = centerNodeId ? nodeObjects[String(centerNodeId)] : null;
|
|
16487
|
+
const orbitingNodeIds = activeNodeIds.filter(
|
|
16488
|
+
(id) => id !== String(centerNodeId)
|
|
16489
|
+
);
|
|
16490
|
+
const totalOrbiting = orbitingNodeIds.length;
|
|
16491
|
+
const radius = Math.max(80, totalOrbiting * 10);
|
|
16492
|
+
if (centerMesh) {
|
|
16493
|
+
const posTween = new Tween2(centerMesh.position).to({ x: 0, y: 0, z: 0 }, 1500).easing(Easing2.Cubic.InOut);
|
|
16494
|
+
tweenGroup.add(posTween);
|
|
16495
|
+
posTween.start();
|
|
16496
|
+
if (centerMesh.userData.labelObject) {
|
|
16497
|
+
const labelTarget = new THREE3.Vector3(0, 0, 0).add(
|
|
16498
|
+
centerMesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16499
|
+
);
|
|
16500
|
+
const lblTween = new Tween2(centerMesh.userData.labelObject.position).to(labelTarget, 1500).easing(Easing2.Cubic.InOut);
|
|
16501
|
+
tweenGroup.add(lblTween);
|
|
16502
|
+
lblTween.start();
|
|
16503
|
+
}
|
|
16504
|
+
sumX += 0;
|
|
16505
|
+
sumY += 0;
|
|
16506
|
+
nodeCount++;
|
|
16507
|
+
}
|
|
16508
|
+
orbitingNodeIds.forEach((id, index) => {
|
|
16509
|
+
const mesh = nodeObjects[id];
|
|
16510
|
+
const angle = totalOrbiting > 0 ? index / totalOrbiting * Math.PI * 2 : 0;
|
|
16511
|
+
const targetX = Math.cos(angle) * radius;
|
|
16512
|
+
const targetY = Math.sin(angle) * radius;
|
|
16513
|
+
const posTween = new Tween2(mesh.position).to({ x: targetX, y: targetY, z: 0 }, 1500).easing(Easing2.Cubic.InOut);
|
|
16514
|
+
tweenGroup.add(posTween);
|
|
16515
|
+
posTween.start();
|
|
16516
|
+
if (mesh.userData.labelObject) {
|
|
16517
|
+
const labelTarget = new THREE3.Vector3(targetX, targetY, 0).add(
|
|
16518
|
+
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16519
|
+
);
|
|
16520
|
+
const lblTween = new Tween2(mesh.userData.labelObject.position).to(labelTarget, 1500).easing(Easing2.Cubic.InOut);
|
|
16521
|
+
tweenGroup.add(lblTween);
|
|
16522
|
+
lblTween.start();
|
|
16523
|
+
}
|
|
16524
|
+
sumX += targetX;
|
|
16525
|
+
sumY += targetY;
|
|
16526
|
+
nodeCount++;
|
|
16527
|
+
});
|
|
16557
16528
|
}
|
|
16558
|
-
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
|
|
16566
|
-
if (
|
|
16567
|
-
|
|
16568
|
-
|
|
16529
|
+
if (nodeCount > 0) {
|
|
16530
|
+
const centerX = sumX / nodeCount;
|
|
16531
|
+
const centerY = sumY / nodeCount;
|
|
16532
|
+
const targetFocus = new THREE3.Vector3(centerX, centerY, 0);
|
|
16533
|
+
const targetTween = new Tween2(controls.target).to({ x: targetFocus.x, y: targetFocus.y, z: targetFocus.z }, 1500).easing(Easing2.Cubic.InOut);
|
|
16534
|
+
tweenGroup.add(targetTween);
|
|
16535
|
+
targetTween.start();
|
|
16536
|
+
let zoomZ = 140;
|
|
16537
|
+
if (type === "Column") {
|
|
16538
|
+
const numRows = Math.ceil(nodeCount / (columns || 4));
|
|
16539
|
+
zoomZ = Math.max(140, numRows * 50);
|
|
16540
|
+
} else if (type === "Circle" || type === "Star") {
|
|
16541
|
+
const radius = Math.max(80, nodeCount * 8);
|
|
16542
|
+
zoomZ = radius * 2.5;
|
|
16543
|
+
}
|
|
16544
|
+
const camTween = new Tween2(camera.position).to({ x: targetFocus.x, y: targetFocus.y, z: zoomZ }, 1500).easing(Easing2.Cubic.InOut);
|
|
16545
|
+
tweenGroup.add(camTween);
|
|
16546
|
+
camTween.start();
|
|
16569
16547
|
}
|
|
16570
|
-
}
|
|
16571
|
-
|
|
16572
|
-
|
|
16573
|
-
|
|
16574
|
-
|
|
16575
|
-
|
|
16576
|
-
|
|
16577
|
-
|
|
16578
|
-
|
|
16579
|
-
|
|
16580
|
-
|
|
16581
|
-
|
|
16582
|
-
|
|
16583
|
-
|
|
16584
|
-
questsInCol.forEach((q, rowIndex) => {
|
|
16585
|
-
const timeInfo = questTimeInfos.get(String(q.id)) || { isUndated: true };
|
|
16586
|
-
let nodeY;
|
|
16587
|
-
if (!timeInfo.isUndated) {
|
|
16588
|
-
nodeY = timeToYMap.get(timeInfo.startDate.getTime());
|
|
16589
|
-
} else {
|
|
16590
|
-
const undatedOffset = sortedTimePoints.length > 0 ? sortedTimePoints.length * 5 : 0;
|
|
16591
|
-
nodeY = -40 - rowIndex * QUEST_LENS_ROW_SPACING - undatedOffset;
|
|
16592
|
-
}
|
|
16593
|
-
const posKey = `${statusName}_${nodeY}`;
|
|
16594
|
-
if (!positionGroups.has(posKey)) positionGroups.set(posKey, []);
|
|
16595
|
-
positionGroups.get(posKey).push(String(q.id));
|
|
16548
|
+
},
|
|
16549
|
+
[]
|
|
16550
|
+
);
|
|
16551
|
+
const handleActivateQuestLens = useCallback7(
|
|
16552
|
+
({ assigneeId, status: status2, milestoneId }) => {
|
|
16553
|
+
var _a2;
|
|
16554
|
+
const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
|
|
16555
|
+
if (!nodeObjects || !tweenGroup || !graphGroup) return;
|
|
16556
|
+
const allQuests = ((_a2 = sceneDataRef.current) == null ? void 0 : _a2.quest_nodes) || [];
|
|
16557
|
+
const filteredQuests = allQuests.filter((q) => {
|
|
16558
|
+
const matchAssignee = !assigneeId || String(q.assignee_id) === String(assigneeId);
|
|
16559
|
+
const matchStatus = !status2 ? q.status !== "Done" : String(q.status) === String(status2);
|
|
16560
|
+
const matchMilestone = !milestoneId || q.milestone_ids && q.milestone_ids.includes(milestoneId);
|
|
16561
|
+
return matchAssignee && matchStatus && matchMilestone;
|
|
16596
16562
|
});
|
|
16597
|
-
|
|
16598
|
-
|
|
16599
|
-
|
|
16600
|
-
if (oldLabel) {
|
|
16601
|
-
mesh.remove(oldLabel);
|
|
16602
|
-
if (oldLabel.material) oldLabel.material.dispose();
|
|
16603
|
-
}
|
|
16604
|
-
if (mesh.userData.timelineIntervalBar) {
|
|
16605
|
-
if (graphGroup) graphGroup.remove(mesh.userData.timelineIntervalBar);
|
|
16606
|
-
mesh.userData.timelineIntervalBar = null;
|
|
16607
|
-
}
|
|
16608
|
-
if (mesh.userData.timelineEndLabel) {
|
|
16609
|
-
if (graphGroup) graphGroup.remove(mesh.userData.timelineEndLabel);
|
|
16610
|
-
mesh.userData.timelineEndLabel = null;
|
|
16611
|
-
}
|
|
16612
|
-
});
|
|
16613
|
-
const nonFilteredNodeIds = Object.keys(nodeObjects).filter((id) => !filteredQuests.some((q) => String(q.id) === String(id)));
|
|
16614
|
-
const COMMON_START_X = startX - 100;
|
|
16615
|
-
const COMMON_COL_SPACING = 30;
|
|
16616
|
-
const COMMON_ROW_SPACING = 35;
|
|
16617
|
-
const MAX_COMMON_ROWS = 15;
|
|
16618
|
-
nonFilteredNodeIds.forEach((id, idx) => {
|
|
16619
|
-
const mesh = nodeObjects[id];
|
|
16620
|
-
if (!mesh) return;
|
|
16621
|
-
const col = Math.floor(idx / MAX_COMMON_ROWS);
|
|
16622
|
-
const row = idx % MAX_COMMON_ROWS;
|
|
16623
|
-
const targetX = COMMON_START_X - col * COMMON_COL_SPACING;
|
|
16624
|
-
const targetY = -(row * COMMON_ROW_SPACING) + 50;
|
|
16625
|
-
const targetZ = 0;
|
|
16626
|
-
if (mesh.material) {
|
|
16627
|
-
const opacityTween = new Tween2(mesh.material).to({ opacity: 1 }, 1200).easing(Easing2.Cubic.Out);
|
|
16628
|
-
tweenGroup.add(opacityTween);
|
|
16629
|
-
opacityTween.start();
|
|
16630
|
-
}
|
|
16631
|
-
if (mesh.userData.labelObject) {
|
|
16632
|
-
mesh.userData.labelObject.visible = true;
|
|
16633
|
-
const labelTargetPos = new THREE3.Vector3(targetX, targetY, targetZ).add(
|
|
16634
|
-
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16635
|
-
);
|
|
16636
|
-
const labelTween = new Tween2(mesh.userData.labelObject.position).to(labelTargetPos, 1500).easing(Easing2.Cubic.InOut);
|
|
16637
|
-
tweenGroup.add(labelTween);
|
|
16638
|
-
labelTween.start();
|
|
16563
|
+
if (filteredQuests.length === 0) {
|
|
16564
|
+
console.warn("Nenhuma quest encontrada para os filtros selecionados.");
|
|
16565
|
+
return;
|
|
16639
16566
|
}
|
|
16640
|
-
const
|
|
16641
|
-
|
|
16642
|
-
|
|
16643
|
-
|
|
16644
|
-
|
|
16645
|
-
|
|
16646
|
-
|
|
16647
|
-
if (
|
|
16648
|
-
|
|
16649
|
-
tweenGroup.add(fadeInTween);
|
|
16650
|
-
fadeInTween.start();
|
|
16567
|
+
const questsByStatus = {
|
|
16568
|
+
Backlog: [],
|
|
16569
|
+
"In Progress": [],
|
|
16570
|
+
Review: [],
|
|
16571
|
+
Done: []
|
|
16572
|
+
};
|
|
16573
|
+
filteredQuests.forEach((q) => {
|
|
16574
|
+
if (questsByStatus[q.status]) {
|
|
16575
|
+
questsByStatus[q.status].push(q);
|
|
16651
16576
|
}
|
|
16652
|
-
|
|
16653
|
-
|
|
16577
|
+
});
|
|
16578
|
+
const questTimeInfos = /* @__PURE__ */ new Map();
|
|
16579
|
+
const allActiveTimePoints = /* @__PURE__ */ new Set();
|
|
16580
|
+
filteredQuests.forEach((q) => {
|
|
16581
|
+
const info = parseDateProp(q.Date);
|
|
16582
|
+
questTimeInfos.set(String(q.id), info);
|
|
16583
|
+
if (!info.isUndated) {
|
|
16584
|
+
allActiveTimePoints.add(info.startDate.getTime());
|
|
16585
|
+
if (info.endDate && info.type === "interval") {
|
|
16586
|
+
allActiveTimePoints.add(info.endDate.getTime());
|
|
16587
|
+
}
|
|
16654
16588
|
}
|
|
16655
|
-
}
|
|
16656
|
-
|
|
16657
|
-
|
|
16658
|
-
|
|
16659
|
-
const
|
|
16660
|
-
|
|
16661
|
-
|
|
16662
|
-
|
|
16663
|
-
|
|
16664
|
-
|
|
16665
|
-
|
|
16666
|
-
|
|
16667
|
-
|
|
16668
|
-
|
|
16669
|
-
|
|
16670
|
-
|
|
16671
|
-
|
|
16672
|
-
|
|
16673
|
-
|
|
16674
|
-
|
|
16675
|
-
|
|
16676
|
-
|
|
16677
|
-
|
|
16678
|
-
|
|
16679
|
-
|
|
16680
|
-
|
|
16681
|
-
tweenGroup.add(lensTween);
|
|
16682
|
-
lensTween.start();
|
|
16683
|
-
sumX += finalX;
|
|
16684
|
-
sumY += targetY;
|
|
16685
|
-
questCount++;
|
|
16686
|
-
if (!timeInfo.isUndated && timeInfo.label && !mesh.getObjectByName("questDateLabel")) {
|
|
16687
|
-
const dateSprite = createTextSprite(timeInfo.label, 36);
|
|
16688
|
-
dateSprite.name = "questDateLabel";
|
|
16689
|
-
dateSprite.position.set(0, -5.5, 0);
|
|
16690
|
-
mesh.add(dateSprite);
|
|
16691
|
-
}
|
|
16692
|
-
if (timeInfo.type === "interval" && timeToYMap.has(timeInfo.endDate.getTime())) {
|
|
16693
|
-
const endY = timeToYMap.get(timeInfo.endDate.getTime());
|
|
16694
|
-
if (Math.abs(endY - targetY) > 0.1) {
|
|
16695
|
-
const barHeight = Math.abs(endY - targetY);
|
|
16696
|
-
const barGeometry = new THREE3.CylinderGeometry(
|
|
16697
|
-
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
16698
|
-
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
16699
|
-
1,
|
|
16700
|
-
16
|
|
16701
|
-
);
|
|
16702
|
-
const barMaterial = new THREE3.MeshStandardMaterial({
|
|
16703
|
-
color: TIMELINE_GOLD_COLOR,
|
|
16704
|
-
emissive: 12092939,
|
|
16705
|
-
emissiveIntensity: 0.4,
|
|
16706
|
-
transparent: true,
|
|
16707
|
-
opacity: TIMELINE_INTERVAL_BAR_OPACITY,
|
|
16708
|
-
roughness: 0.3,
|
|
16709
|
-
metalness: 0.8
|
|
16710
|
-
});
|
|
16711
|
-
const intervalBar = new THREE3.Mesh(barGeometry, barMaterial);
|
|
16712
|
-
intervalBar.userData.associatedNodeId = mesh.userData.id;
|
|
16713
|
-
intervalBar.position.set(finalX, (targetY + endY) / 2, -0.5);
|
|
16714
|
-
intervalBar.scale.y = barHeight;
|
|
16715
|
-
graphGroup.add(intervalBar);
|
|
16716
|
-
mesh.userData.timelineIntervalBar = intervalBar;
|
|
16717
|
-
const endLabel = createTextSprite(timeInfo.label.split(" - ")[1] || "", 30);
|
|
16718
|
-
endLabel.name = "timelineEndLabel";
|
|
16719
|
-
endLabel.position.set(finalX, endY + 4, 0);
|
|
16720
|
-
graphGroup.add(endLabel);
|
|
16721
|
-
mesh.userData.timelineEndLabel = endLabel;
|
|
16589
|
+
});
|
|
16590
|
+
const sortedTimePoints = Array.from(allActiveTimePoints).sort(
|
|
16591
|
+
(a, b) => a - b
|
|
16592
|
+
);
|
|
16593
|
+
const timeToYMap = /* @__PURE__ */ new Map();
|
|
16594
|
+
sortedTimePoints.forEach((ms, idx) => {
|
|
16595
|
+
timeToYMap.set(ms, idx * TIMELINE_LAYER_SPACING_Y);
|
|
16596
|
+
});
|
|
16597
|
+
const startX = -((QUEST_STATUS_ORDER.length - 1) * QUEST_LENS_COLUMN_SPACING) / 2;
|
|
16598
|
+
let sumX = 0;
|
|
16599
|
+
let sumY = 0;
|
|
16600
|
+
let questCount = 0;
|
|
16601
|
+
const positionGroups = /* @__PURE__ */ new Map();
|
|
16602
|
+
const NODE_X_GAP = 22;
|
|
16603
|
+
QUEST_STATUS_ORDER.forEach((statusName) => {
|
|
16604
|
+
const questsInCol = questsByStatus[statusName];
|
|
16605
|
+
questsInCol.forEach((q, rowIndex) => {
|
|
16606
|
+
const timeInfo = questTimeInfos.get(String(q.id)) || {
|
|
16607
|
+
isUndated: true
|
|
16608
|
+
};
|
|
16609
|
+
let nodeY;
|
|
16610
|
+
if (!timeInfo.isUndated) {
|
|
16611
|
+
nodeY = timeToYMap.get(timeInfo.startDate.getTime());
|
|
16612
|
+
} else {
|
|
16613
|
+
const undatedOffset = sortedTimePoints.length > 0 ? sortedTimePoints.length * 5 : 0;
|
|
16614
|
+
nodeY = -40 - rowIndex * QUEST_LENS_ROW_SPACING - undatedOffset;
|
|
16722
16615
|
}
|
|
16616
|
+
const posKey = `${statusName}_${nodeY}`;
|
|
16617
|
+
if (!positionGroups.has(posKey)) positionGroups.set(posKey, []);
|
|
16618
|
+
positionGroups.get(posKey).push(String(q.id));
|
|
16619
|
+
});
|
|
16620
|
+
});
|
|
16621
|
+
Object.values(nodeObjects).forEach((mesh) => {
|
|
16622
|
+
const oldLabel = mesh.getObjectByName("questDateLabel") || mesh.getObjectByName("timelineLabel");
|
|
16623
|
+
if (oldLabel) {
|
|
16624
|
+
mesh.remove(oldLabel);
|
|
16625
|
+
if (oldLabel.material) oldLabel.material.dispose();
|
|
16626
|
+
}
|
|
16627
|
+
if (mesh.userData.timelineIntervalBar) {
|
|
16628
|
+
if (graphGroup) graphGroup.remove(mesh.userData.timelineIntervalBar);
|
|
16629
|
+
mesh.userData.timelineIntervalBar = null;
|
|
16630
|
+
}
|
|
16631
|
+
if (mesh.userData.timelineEndLabel) {
|
|
16632
|
+
if (graphGroup) graphGroup.remove(mesh.userData.timelineEndLabel);
|
|
16633
|
+
mesh.userData.timelineEndLabel = null;
|
|
16634
|
+
}
|
|
16635
|
+
});
|
|
16636
|
+
const nonFilteredNodeIds = Object.keys(nodeObjects).filter(
|
|
16637
|
+
(id) => !filteredQuests.some((q) => String(q.id) === String(id))
|
|
16638
|
+
);
|
|
16639
|
+
const COMMON_START_X = startX - 100;
|
|
16640
|
+
const COMMON_COL_SPACING = 30;
|
|
16641
|
+
const COMMON_ROW_SPACING = 35;
|
|
16642
|
+
const MAX_COMMON_ROWS = 15;
|
|
16643
|
+
nonFilteredNodeIds.forEach((id, idx) => {
|
|
16644
|
+
const mesh = nodeObjects[id];
|
|
16645
|
+
if (!mesh) return;
|
|
16646
|
+
const col = Math.floor(idx / MAX_COMMON_ROWS);
|
|
16647
|
+
const row = idx % MAX_COMMON_ROWS;
|
|
16648
|
+
const targetX = COMMON_START_X - col * COMMON_COL_SPACING;
|
|
16649
|
+
const targetY = -(row * COMMON_ROW_SPACING) + 50;
|
|
16650
|
+
const targetZ = 0;
|
|
16651
|
+
if (mesh.material) {
|
|
16652
|
+
const opacityTween = new Tween2(mesh.material).to({ opacity: 1 }, 1200).easing(Easing2.Cubic.Out);
|
|
16653
|
+
tweenGroup.add(opacityTween);
|
|
16654
|
+
opacityTween.start();
|
|
16723
16655
|
}
|
|
16724
16656
|
if (mesh.userData.labelObject) {
|
|
16725
|
-
|
|
16726
|
-
|
|
16727
|
-
|
|
16657
|
+
mesh.userData.labelObject.visible = true;
|
|
16658
|
+
const labelTargetPos = new THREE3.Vector3(
|
|
16659
|
+
targetX,
|
|
16660
|
+
targetY,
|
|
16661
|
+
targetZ
|
|
16662
|
+
).add(mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0));
|
|
16728
16663
|
const labelTween = new Tween2(mesh.userData.labelObject.position).to(labelTargetPos, 1500).easing(Easing2.Cubic.InOut);
|
|
16729
16664
|
tweenGroup.add(labelTween);
|
|
16730
16665
|
labelTween.start();
|
|
16731
16666
|
}
|
|
16667
|
+
const sideTween = new Tween2(mesh.position).to({ x: targetX, y: targetY, z: targetZ }, 1500).easing(Easing2.Cubic.InOut);
|
|
16668
|
+
tweenGroup.add(sideTween);
|
|
16669
|
+
sideTween.start();
|
|
16732
16670
|
});
|
|
16733
|
-
|
|
16734
|
-
|
|
16735
|
-
|
|
16736
|
-
|
|
16737
|
-
|
|
16738
|
-
|
|
16739
|
-
|
|
16740
|
-
|
|
16741
|
-
|
|
16742
|
-
|
|
16743
|
-
|
|
16744
|
-
|
|
16745
|
-
|
|
16746
|
-
|
|
16671
|
+
filteredQuests.forEach((q) => {
|
|
16672
|
+
const mesh = nodeObjects[String(q.id)];
|
|
16673
|
+
if (mesh) {
|
|
16674
|
+
if (mesh.material) {
|
|
16675
|
+
const fadeInTween = new Tween2(mesh.material).to({ opacity: 1 }, 1200).easing(Easing2.Cubic.Out);
|
|
16676
|
+
tweenGroup.add(fadeInTween);
|
|
16677
|
+
fadeInTween.start();
|
|
16678
|
+
}
|
|
16679
|
+
if (mesh.userData.labelObject) {
|
|
16680
|
+
mesh.userData.labelObject.visible = true;
|
|
16681
|
+
}
|
|
16682
|
+
}
|
|
16683
|
+
});
|
|
16684
|
+
QUEST_STATUS_ORDER.forEach((statusName, colIndex) => {
|
|
16685
|
+
if (status2 && status2 !== statusName) return;
|
|
16686
|
+
const questsInCol = questsByStatus[statusName];
|
|
16687
|
+
const colX = startX + colIndex * QUEST_LENS_COLUMN_SPACING;
|
|
16688
|
+
questsInCol.forEach((q, rowIndex) => {
|
|
16689
|
+
const nodeId = String(q.id);
|
|
16690
|
+
let mesh = nodeObjects[nodeId];
|
|
16691
|
+
const timeInfo = questTimeInfos.get(nodeId) || { isUndated: true };
|
|
16692
|
+
let targetY;
|
|
16693
|
+
if (!timeInfo.isUndated) {
|
|
16694
|
+
targetY = timeToYMap.get(timeInfo.startDate.getTime());
|
|
16695
|
+
} else {
|
|
16696
|
+
const undatedOffset = sortedTimePoints.length > 0 ? sortedTimePoints.length * 5 : 0;
|
|
16697
|
+
targetY = -40 - rowIndex * QUEST_LENS_ROW_SPACING - undatedOffset;
|
|
16698
|
+
}
|
|
16699
|
+
const posKey = `${statusName}_${targetY}`;
|
|
16700
|
+
const group = positionGroups.get(posKey) || [nodeId];
|
|
16701
|
+
const indexInGroup = group.indexOf(nodeId);
|
|
16702
|
+
const xOffset = (indexInGroup - (group.length - 1) / 2) * NODE_X_GAP;
|
|
16703
|
+
const finalX = colX + xOffset;
|
|
16704
|
+
if (!mesh) {
|
|
16705
|
+
mesh = addOrUpdateNodeMesh(
|
|
16706
|
+
q,
|
|
16707
|
+
new THREE3.Vector3(finalX, 150, 0),
|
|
16708
|
+
true
|
|
16709
|
+
);
|
|
16710
|
+
}
|
|
16711
|
+
const lensTween = new Tween2(mesh.position).to({ x: finalX, y: targetY, z: 0 }, 1500).easing(Easing2.Cubic.InOut);
|
|
16712
|
+
tweenGroup.add(lensTween);
|
|
16713
|
+
lensTween.start();
|
|
16714
|
+
sumX += finalX;
|
|
16715
|
+
sumY += targetY;
|
|
16716
|
+
questCount++;
|
|
16717
|
+
if (!timeInfo.isUndated && timeInfo.label && !mesh.getObjectByName("questDateLabel")) {
|
|
16718
|
+
const dateSprite = createTextSprite(timeInfo.label, 36);
|
|
16719
|
+
dateSprite.name = "questDateLabel";
|
|
16720
|
+
dateSprite.position.set(0, -5.5, 0);
|
|
16721
|
+
mesh.add(dateSprite);
|
|
16722
|
+
}
|
|
16723
|
+
if (timeInfo.type === "interval" && timeToYMap.has(timeInfo.endDate.getTime())) {
|
|
16724
|
+
const endY = timeToYMap.get(timeInfo.endDate.getTime());
|
|
16725
|
+
if (Math.abs(endY - targetY) > 0.1) {
|
|
16726
|
+
const barHeight = Math.abs(endY - targetY);
|
|
16727
|
+
const barGeometry = new THREE3.CylinderGeometry(
|
|
16728
|
+
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
16729
|
+
TIMELINE_INTERVAL_BAR_RADIUS,
|
|
16730
|
+
1,
|
|
16731
|
+
16
|
|
16732
|
+
);
|
|
16733
|
+
const barMaterial = new THREE3.MeshStandardMaterial({
|
|
16734
|
+
color: TIMELINE_GOLD_COLOR,
|
|
16735
|
+
emissive: 12092939,
|
|
16736
|
+
emissiveIntensity: 0.4,
|
|
16737
|
+
transparent: true,
|
|
16738
|
+
opacity: TIMELINE_INTERVAL_BAR_OPACITY,
|
|
16739
|
+
roughness: 0.3,
|
|
16740
|
+
metalness: 0.8
|
|
16741
|
+
});
|
|
16742
|
+
const intervalBar = new THREE3.Mesh(barGeometry, barMaterial);
|
|
16743
|
+
intervalBar.userData.associatedNodeId = mesh.userData.id;
|
|
16744
|
+
intervalBar.position.set(finalX, (targetY + endY) / 2, -0.5);
|
|
16745
|
+
intervalBar.scale.y = barHeight;
|
|
16746
|
+
graphGroup.add(intervalBar);
|
|
16747
|
+
mesh.userData.timelineIntervalBar = intervalBar;
|
|
16748
|
+
const endLabel = createTextSprite(
|
|
16749
|
+
timeInfo.label.split(" - ")[1] || "",
|
|
16750
|
+
30
|
|
16751
|
+
);
|
|
16752
|
+
endLabel.name = "timelineEndLabel";
|
|
16753
|
+
endLabel.position.set(finalX, endY + 4, 0);
|
|
16754
|
+
graphGroup.add(endLabel);
|
|
16755
|
+
mesh.userData.timelineEndLabel = endLabel;
|
|
16756
|
+
}
|
|
16757
|
+
}
|
|
16758
|
+
if (mesh.userData.labelObject) {
|
|
16759
|
+
const labelTargetPos = new THREE3.Vector3(finalX, targetY, 0).add(
|
|
16760
|
+
mesh.userData.labelOffset || new THREE3.Vector3(0, 3.8, 0)
|
|
16761
|
+
);
|
|
16762
|
+
const labelTween = new Tween2(mesh.userData.labelObject.position).to(labelTargetPos, 1500).easing(Easing2.Cubic.InOut);
|
|
16763
|
+
tweenGroup.add(labelTween);
|
|
16764
|
+
labelTween.start();
|
|
16765
|
+
}
|
|
16766
|
+
});
|
|
16767
|
+
});
|
|
16768
|
+
if (questCount > 0) {
|
|
16769
|
+
const { camera: sceneCamera, controls: sceneControls } = stateRef.current;
|
|
16770
|
+
const centerX = sumX / questCount;
|
|
16771
|
+
const centerY = sumY / questCount;
|
|
16772
|
+
const targetFocus = new THREE3.Vector3(centerX, centerY, 0);
|
|
16773
|
+
const targetTween = new Tween2(sceneControls.target).to({ x: targetFocus.x, y: targetFocus.y, z: targetFocus.z }, 1500).easing(Easing2.Cubic.InOut);
|
|
16774
|
+
tweenGroup.add(targetTween);
|
|
16775
|
+
targetTween.start();
|
|
16776
|
+
const camTween = new Tween2(sceneCamera.position).to({ x: targetFocus.x, y: targetFocus.y, z: 140 }, 1500).easing(Easing2.Cubic.InOut);
|
|
16777
|
+
tweenGroup.add(camTween);
|
|
16778
|
+
camTween.start();
|
|
16779
|
+
}
|
|
16780
|
+
},
|
|
16781
|
+
[addOrUpdateNodeMesh]
|
|
16782
|
+
);
|
|
16747
16783
|
useEffect25(() => {
|
|
16748
16784
|
if (!isInitialized || !sceneDataRef.current) return;
|
|
16749
16785
|
const currentMount = mountRef.current;
|
|
@@ -17128,7 +17164,9 @@ function XViewScene({
|
|
|
17128
17164
|
const clickedNodeId = String(clickedNode.userData.id);
|
|
17129
17165
|
const parentId = String(currentSelectedParent);
|
|
17130
17166
|
if (clickedNodeId === parentId) {
|
|
17131
|
-
alert(
|
|
17167
|
+
alert(
|
|
17168
|
+
"Erro: N\xE3o \xE9 poss\xEDvel adicionar um Node como filho dele mesmo."
|
|
17169
|
+
);
|
|
17132
17170
|
return;
|
|
17133
17171
|
}
|
|
17134
17172
|
const parentInfo = stateRef.current.nodeIdToParentFileMap.get(clickedNodeId);
|
|
@@ -17477,7 +17515,11 @@ function XViewScene({
|
|
|
17477
17515
|
ancestryData: ancestryDataRef.current
|
|
17478
17516
|
});
|
|
17479
17517
|
(_b2 = stateRef.current.tweenGroup) == null ? void 0 : _b2.update(time);
|
|
17480
|
-
const {
|
|
17518
|
+
const {
|
|
17519
|
+
keysPressed,
|
|
17520
|
+
controls: sceneControls,
|
|
17521
|
+
camera: sceneCamera
|
|
17522
|
+
} = stateRef.current;
|
|
17481
17523
|
if (sceneControls && keysPressed) {
|
|
17482
17524
|
const panSpeed = 1.5;
|
|
17483
17525
|
const rotateSpeed = 0.02;
|
|
@@ -17501,10 +17543,18 @@ function XViewScene({
|
|
|
17501
17543
|
offset.multiplyScalar(factor);
|
|
17502
17544
|
sceneCamera.position.copy(sceneControls.target).add(offset);
|
|
17503
17545
|
} else if (!isCtrl && !isShift && (dirX !== 0 || dirY !== 0)) {
|
|
17504
|
-
const distance = sceneCamera.position.distanceTo(
|
|
17546
|
+
const distance = sceneCamera.position.distanceTo(
|
|
17547
|
+
sceneControls.target
|
|
17548
|
+
);
|
|
17505
17549
|
const currentPanSpeed = panSpeed * (distance / 100);
|
|
17506
|
-
const vecX = new THREE3.Vector3().setFromMatrixColumn(
|
|
17507
|
-
|
|
17550
|
+
const vecX = new THREE3.Vector3().setFromMatrixColumn(
|
|
17551
|
+
sceneCamera.matrix,
|
|
17552
|
+
0
|
|
17553
|
+
);
|
|
17554
|
+
const vecY = new THREE3.Vector3().setFromMatrixColumn(
|
|
17555
|
+
sceneCamera.matrix,
|
|
17556
|
+
1
|
|
17557
|
+
);
|
|
17508
17558
|
vecX.multiplyScalar(dirX * currentPanSpeed);
|
|
17509
17559
|
vecY.multiplyScalar(dirY * currentPanSpeed);
|
|
17510
17560
|
sceneCamera.position.add(vecX).add(vecY);
|
|
@@ -17901,115 +17951,143 @@ function XViewScene({
|
|
|
17901
17951
|
const handleStartVersioning = (nodeData) => {
|
|
17902
17952
|
userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
|
|
17903
17953
|
};
|
|
17904
|
-
const handleStartQuestQuick = useCallback7(
|
|
17905
|
-
|
|
17906
|
-
|
|
17907
|
-
|
|
17908
|
-
|
|
17909
|
-
|
|
17910
|
-
|
|
17911
|
-
|
|
17912
|
-
|
|
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
|
-
|
|
17950
|
-
}
|
|
17951
|
-
|
|
17952
|
-
|
|
17953
|
-
|
|
17954
|
-
|
|
17955
|
-
|
|
17956
|
-
|
|
17957
|
-
|
|
17958
|
-
|
|
17959
|
-
|
|
17960
|
-
|
|
17961
|
-
|
|
17962
|
-
|
|
17963
|
-
|
|
17964
|
-
|
|
17965
|
-
|
|
17966
|
-
|
|
17967
|
-
|
|
17968
|
-
|
|
17969
|
-
|
|
17954
|
+
const handleStartQuestQuick = useCallback7(
|
|
17955
|
+
(questNode) => {
|
|
17956
|
+
var _a2, _b2, _c2;
|
|
17957
|
+
if (!questNode || !actionHandlerContext) return;
|
|
17958
|
+
const allParentNodes = Object.values(parentDataRef.current).flatMap(
|
|
17959
|
+
(fileData) => fileData.nodes || []
|
|
17960
|
+
);
|
|
17961
|
+
const blockCheck = isQuestBlocked(questNode, allParentNodes);
|
|
17962
|
+
if (blockCheck.isBlocked) {
|
|
17963
|
+
alert(
|
|
17964
|
+
`Esta quest n\xE3o pode ser iniciada pois possui depend\xEAncias pendentes: ${blockCheck.pendingDependencies.map((d) => d.raw_title || d.name).join(", ")}`
|
|
17965
|
+
);
|
|
17966
|
+
return;
|
|
17967
|
+
}
|
|
17968
|
+
const {
|
|
17969
|
+
labelObject,
|
|
17970
|
+
labelOffset,
|
|
17971
|
+
aura,
|
|
17972
|
+
borderRing,
|
|
17973
|
+
timelineIntervalBar,
|
|
17974
|
+
timelineEndLabel,
|
|
17975
|
+
...cleanQuestNode
|
|
17976
|
+
} = questNode;
|
|
17977
|
+
const newTimeline = [
|
|
17978
|
+
...cleanQuestNode.timeline || [],
|
|
17979
|
+
createTimelineEntry(
|
|
17980
|
+
((_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.id) || "unknown",
|
|
17981
|
+
`Status "In Progress" - Respons\xE1vel: ${((_b2 = session == null ? void 0 : session.user) == null ? void 0 : _b2.name) || "usu\xE1rio"}`,
|
|
17982
|
+
"status_changed"
|
|
17983
|
+
)
|
|
17984
|
+
];
|
|
17985
|
+
const updatedNode = {
|
|
17986
|
+
...cleanQuestNode,
|
|
17987
|
+
status: "In Progress",
|
|
17988
|
+
color: "#eab308",
|
|
17989
|
+
assignee_id: (_c2 = session == null ? void 0 : session.user) == null ? void 0 : _c2.id,
|
|
17990
|
+
timeline: newTimeline
|
|
17991
|
+
};
|
|
17992
|
+
if (userActionHandlers.handleSaveNodeDetails) {
|
|
17993
|
+
userActionHandlers.handleSaveNodeDetails(
|
|
17994
|
+
actionHandlerContext,
|
|
17995
|
+
updatedNode,
|
|
17996
|
+
true
|
|
17997
|
+
);
|
|
17998
|
+
}
|
|
17999
|
+
setDetailsNode(updatedNode);
|
|
18000
|
+
},
|
|
18001
|
+
[session, actionHandlerContext]
|
|
18002
|
+
);
|
|
18003
|
+
const handleFinishQuestQuick = useCallback7(
|
|
18004
|
+
(questNode) => {
|
|
18005
|
+
var _a2, _b2, _c2, _d2;
|
|
18006
|
+
if (!questNode || !actionHandlerContext) return;
|
|
18007
|
+
const {
|
|
18008
|
+
labelObject,
|
|
18009
|
+
labelOffset,
|
|
18010
|
+
aura,
|
|
18011
|
+
borderRing,
|
|
18012
|
+
timelineIntervalBar,
|
|
18013
|
+
timelineEndLabel,
|
|
18014
|
+
...cleanQuestNode
|
|
18015
|
+
} = questNode;
|
|
18016
|
+
let nextAssigneeId = cleanQuestNode.assignee_id;
|
|
18017
|
+
let nextStatus = "Done";
|
|
18018
|
+
let newTimeline = [...cleanQuestNode.timeline || []];
|
|
18019
|
+
const reviewStack = [...cleanQuestNode.reviewStack || []];
|
|
18020
|
+
const currentReviewerIdx = reviewStack.findIndex(
|
|
18021
|
+
(r) => r.status !== "completed"
|
|
18022
|
+
);
|
|
18023
|
+
let nextIdxToAssign = 0;
|
|
18024
|
+
if (currentReviewerIdx !== -1 && reviewStack[currentReviewerIdx].userId === cleanQuestNode.assignee_id) {
|
|
18025
|
+
reviewStack[currentReviewerIdx].status = "completed";
|
|
18026
|
+
nextIdxToAssign = currentReviewerIdx + 1;
|
|
17970
18027
|
} else {
|
|
17971
|
-
|
|
17972
|
-
|
|
17973
|
-
|
|
18028
|
+
nextIdxToAssign = currentReviewerIdx !== -1 ? currentReviewerIdx : reviewStack.length;
|
|
18029
|
+
}
|
|
18030
|
+
if (nextIdxToAssign < reviewStack.length) {
|
|
18031
|
+
const remainingMandatory = reviewStack.slice(nextIdxToAssign).some((r) => r.mandatory);
|
|
18032
|
+
const hasAnyMandatory = reviewStack.some((r) => r.mandatory);
|
|
18033
|
+
if (!hasAnyMandatory || remainingMandatory) {
|
|
18034
|
+
const nextReviewer = reviewStack[nextIdxToAssign];
|
|
18035
|
+
nextAssigneeId = nextReviewer.userId;
|
|
18036
|
+
nextStatus = "Review";
|
|
18037
|
+
} else {
|
|
18038
|
+
nextStatus = "Done";
|
|
18039
|
+
for (let i = nextIdxToAssign; i < reviewStack.length; i++) {
|
|
18040
|
+
reviewStack[i].status = "skipped";
|
|
18041
|
+
}
|
|
17974
18042
|
}
|
|
18043
|
+
} else {
|
|
18044
|
+
nextStatus = "Done";
|
|
17975
18045
|
}
|
|
17976
|
-
|
|
17977
|
-
|
|
17978
|
-
|
|
17979
|
-
|
|
17980
|
-
|
|
17981
|
-
|
|
17982
|
-
|
|
17983
|
-
|
|
17984
|
-
|
|
17985
|
-
|
|
17986
|
-
)
|
|
17987
|
-
|
|
17988
|
-
|
|
17989
|
-
|
|
17990
|
-
|
|
17991
|
-
|
|
17992
|
-
|
|
17993
|
-
(
|
|
17994
|
-
|
|
17995
|
-
|
|
17996
|
-
|
|
17997
|
-
|
|
17998
|
-
|
|
17999
|
-
|
|
18000
|
-
|
|
18001
|
-
|
|
18002
|
-
|
|
18003
|
-
|
|
18004
|
-
|
|
18005
|
-
|
|
18006
|
-
|
|
18007
|
-
|
|
18008
|
-
|
|
18009
|
-
|
|
18010
|
-
|
|
18011
|
-
|
|
18012
|
-
|
|
18046
|
+
if (nextStatus === "Review") {
|
|
18047
|
+
const nextReviewerName = ((_a2 = viewMembers.find((m) => m.id === nextAssigneeId)) == null ? void 0 : _a2.name) || "revisor";
|
|
18048
|
+
newTimeline.push(
|
|
18049
|
+
createTimelineEntry(
|
|
18050
|
+
"system",
|
|
18051
|
+
`Status "Review" - Respons\xE1vel: ${nextReviewerName}`,
|
|
18052
|
+
"status_changed",
|
|
18053
|
+
{ metadata: { to_assignee_id: nextAssigneeId } }
|
|
18054
|
+
)
|
|
18055
|
+
);
|
|
18056
|
+
} else if (nextStatus === "Done") {
|
|
18057
|
+
const finisherName = ((_b2 = viewMembers.find(
|
|
18058
|
+
(m) => {
|
|
18059
|
+
var _a3;
|
|
18060
|
+
return m.id === (((_a3 = session == null ? void 0 : session.user) == null ? void 0 : _a3.id) || cleanQuestNode.assignee_id);
|
|
18061
|
+
}
|
|
18062
|
+
)) == null ? void 0 : _b2.name) || ((_c2 = session == null ? void 0 : session.user) == null ? void 0 : _c2.name) || "respons\xE1vel";
|
|
18063
|
+
newTimeline.push(
|
|
18064
|
+
createTimelineEntry(
|
|
18065
|
+
((_d2 = session == null ? void 0 : session.user) == null ? void 0 : _d2.id) || cleanQuestNode.assignee_id,
|
|
18066
|
+
`Status "Done" - Finalizado por ${finisherName}`,
|
|
18067
|
+
"status_changed"
|
|
18068
|
+
)
|
|
18069
|
+
);
|
|
18070
|
+
}
|
|
18071
|
+
const updatedNode = {
|
|
18072
|
+
...cleanQuestNode,
|
|
18073
|
+
status: nextStatus,
|
|
18074
|
+
color: nextStatus === "Done" ? "#22c55e" : "#a855f7",
|
|
18075
|
+
assignee_id: nextAssigneeId,
|
|
18076
|
+
reviewStack,
|
|
18077
|
+
timeline: newTimeline
|
|
18078
|
+
};
|
|
18079
|
+
if (userActionHandlers.handleSaveNodeDetails) {
|
|
18080
|
+
userActionHandlers.handleSaveNodeDetails(
|
|
18081
|
+
actionHandlerContext,
|
|
18082
|
+
updatedNode
|
|
18083
|
+
);
|
|
18084
|
+
}
|
|
18085
|
+
if (detailsNode && String(detailsNode.id) === String(cleanQuestNode.id)) {
|
|
18086
|
+
setDetailsNode(null);
|
|
18087
|
+
}
|
|
18088
|
+
},
|
|
18089
|
+
[session, actionHandlerContext, viewMembers, detailsNode]
|
|
18090
|
+
);
|
|
18013
18091
|
const handleCancelQuest = useCallback7(() => {
|
|
18014
18092
|
const { graphGroup, ghostElements } = stateRef.current;
|
|
18015
18093
|
if (ghostElements.node && graphGroup) {
|
|
@@ -18060,48 +18138,56 @@ function XViewScene({
|
|
|
18060
18138
|
if (questNodeId && sceneConfigId) {
|
|
18061
18139
|
const sceneData = sceneDataRef.current;
|
|
18062
18140
|
if (sceneData && sceneData.quest_nodes) {
|
|
18063
|
-
const questIndex = sceneData.quest_nodes.findIndex(
|
|
18141
|
+
const questIndex = sceneData.quest_nodes.findIndex(
|
|
18142
|
+
(q) => String(q.id) === String(questNodeId)
|
|
18143
|
+
);
|
|
18064
18144
|
if (questIndex !== -1) {
|
|
18065
18145
|
sceneData.quest_nodes[questIndex].quest_tree = formattedTree;
|
|
18066
18146
|
sceneData.quest_nodes[questIndex].quest_abstraction_tree = formattedAbstractionTree;
|
|
18067
18147
|
if (parentDataRef.current[sceneConfigId]) {
|
|
18068
|
-
const parentIndex = parentDataRef.current[sceneConfigId].nodes.findIndex(
|
|
18069
|
-
(q) => String(q.id) === String(questNodeId)
|
|
18070
|
-
);
|
|
18148
|
+
const parentIndex = parentDataRef.current[sceneConfigId].nodes.findIndex((q) => String(q.id) === String(questNodeId));
|
|
18071
18149
|
if (parentIndex !== -1) {
|
|
18072
18150
|
parentDataRef.current[sceneConfigId].nodes[parentIndex].quest_tree = formattedTree;
|
|
18073
18151
|
parentDataRef.current[sceneConfigId].nodes[parentIndex].quest_abstraction_tree = formattedAbstractionTree;
|
|
18074
18152
|
}
|
|
18075
18153
|
}
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
|
|
18079
|
-
|
|
18080
|
-
|
|
18081
|
-
|
|
18082
|
-
|
|
18083
|
-
|
|
18084
|
-
|
|
18085
|
-
|
|
18086
|
-
|
|
18087
|
-
|
|
18088
|
-
|
|
18089
|
-
|
|
18090
|
-
|
|
18091
|
-
|
|
18092
|
-
|
|
18093
|
-
|
|
18094
|
-
|
|
18095
|
-
|
|
18096
|
-
|
|
18097
|
-
|
|
18098
|
-
|
|
18099
|
-
|
|
18100
|
-
|
|
18101
|
-
|
|
18102
|
-
|
|
18103
|
-
|
|
18154
|
+
const sceneFileData = {
|
|
18155
|
+
...sceneData,
|
|
18156
|
+
nodes: sceneData.nodes || [],
|
|
18157
|
+
links: sceneData.links || [],
|
|
18158
|
+
quest_counter: sceneData.quest_counter || 1
|
|
18159
|
+
};
|
|
18160
|
+
delete sceneFileData.quest_nodes;
|
|
18161
|
+
delete sceneFileData.quest_links;
|
|
18162
|
+
delete sceneFileData.milestones;
|
|
18163
|
+
const questFileData = {
|
|
18164
|
+
nodes: sceneData.quest_nodes || [],
|
|
18165
|
+
links: sceneData.quest_links || [],
|
|
18166
|
+
milestones: sceneData.milestones || []
|
|
18167
|
+
};
|
|
18168
|
+
await save_view_data(sceneSaveUrl, sceneFileData);
|
|
18169
|
+
const questSaveUrl = sceneSaveUrl.replace(
|
|
18170
|
+
"x_view_scenes",
|
|
18171
|
+
"x_view_quests"
|
|
18172
|
+
);
|
|
18173
|
+
await save_view_data(questSaveUrl, questFileData);
|
|
18174
|
+
}
|
|
18175
|
+
const updatedNodeData = sceneData.quest_nodes[questIndex];
|
|
18176
|
+
const nodeMesh = (_a2 = stateRef.current.nodeObjects) == null ? void 0 : _a2[String(questNodeId)];
|
|
18177
|
+
if (nodeMesh) {
|
|
18178
|
+
nodeMesh.userData = {
|
|
18179
|
+
...nodeMesh.userData,
|
|
18180
|
+
...updatedNodeData
|
|
18181
|
+
};
|
|
18104
18182
|
}
|
|
18183
|
+
if (detailsNode && String(detailsNode.id) === String(questNodeId)) {
|
|
18184
|
+
setDetailsNode((prev) => ({
|
|
18185
|
+
...prev,
|
|
18186
|
+
quest_tree: formattedTree,
|
|
18187
|
+
quest_abstraction_tree: formattedAbstractionTree
|
|
18188
|
+
}));
|
|
18189
|
+
}
|
|
18190
|
+
setSceneVersion((v) => v + 1);
|
|
18105
18191
|
}
|
|
18106
18192
|
}
|
|
18107
18193
|
};
|
|
@@ -18163,21 +18249,33 @@ function XViewScene({
|
|
|
18163
18249
|
graphDataRef2.current[sceneConfigId2].nodes.push(newNode);
|
|
18164
18250
|
const sceneFileData = {
|
|
18165
18251
|
...sceneDataRef2.current,
|
|
18166
|
-
quest_nodes: graphDataRef2.current[sceneConfigId2].nodes,
|
|
18167
|
-
quest_links: graphDataRef2.current[sceneConfigId2].links,
|
|
18168
18252
|
quest_counter: currentCounter + 1
|
|
18169
18253
|
};
|
|
18254
|
+
delete sceneFileData.quest_nodes;
|
|
18255
|
+
delete sceneFileData.quest_links;
|
|
18256
|
+
delete sceneFileData.milestones;
|
|
18257
|
+
const questFileData = {
|
|
18258
|
+
nodes: graphDataRef2.current[sceneConfigId2].nodes,
|
|
18259
|
+
links: graphDataRef2.current[sceneConfigId2].links,
|
|
18260
|
+
milestones: sceneDataRef2.current.milestones || []
|
|
18261
|
+
};
|
|
18170
18262
|
try {
|
|
18171
18263
|
await actions.save_view_data(sceneSaveUrl2, sceneFileData);
|
|
18264
|
+
const questSaveUrl = sceneSaveUrl2.replace("x_view_scenes", "x_view_quests");
|
|
18265
|
+
await actions.save_view_data(questSaveUrl, questFileData);
|
|
18172
18266
|
sceneDataRef2.current.quest_counter = currentCounter + 1;
|
|
18173
18267
|
stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
|
|
18174
18268
|
parentFileId: sceneConfigId2,
|
|
18175
18269
|
ownerId: ownerId2,
|
|
18176
18270
|
datasetName: "Quests Internas (View)"
|
|
18177
18271
|
});
|
|
18178
|
-
sceneDataRef2.current.quest_nodes = [
|
|
18272
|
+
sceneDataRef2.current.quest_nodes = [
|
|
18273
|
+
...graphDataRef2.current[sceneConfigId2].nodes
|
|
18274
|
+
];
|
|
18179
18275
|
if (parentDataRef.current[sceneConfigId2]) {
|
|
18180
|
-
parentDataRef.current[sceneConfigId2].nodes = [
|
|
18276
|
+
parentDataRef.current[sceneConfigId2].nodes = [
|
|
18277
|
+
...graphDataRef2.current[sceneConfigId2].nodes
|
|
18278
|
+
];
|
|
18181
18279
|
}
|
|
18182
18280
|
const finalPosition = stateRef2.current.ghostElements.node ? stateRef2.current.ghostElements.node.position.clone() : stateRef2.current.controls.target.clone();
|
|
18183
18281
|
const { graphGroup, ghostElements } = stateRef2.current;
|
|
@@ -18242,11 +18340,22 @@ function XViewScene({
|
|
|
18242
18340
|
specificParentData.links.push(newLink);
|
|
18243
18341
|
const viewFilePayload = {
|
|
18244
18342
|
...sceneDataRef2.current,
|
|
18245
|
-
quest_nodes: specificParentData.nodes,
|
|
18246
|
-
quest_links: specificParentData.links,
|
|
18247
18343
|
quest_counter: sceneDataRef2.current.quest_counter || 1
|
|
18248
18344
|
};
|
|
18345
|
+
delete viewFilePayload.quest_nodes;
|
|
18346
|
+
delete viewFilePayload.quest_links;
|
|
18347
|
+
delete viewFilePayload.milestones;
|
|
18348
|
+
const questFilePayload = {
|
|
18349
|
+
nodes: specificParentData.nodes,
|
|
18350
|
+
links: specificParentData.links,
|
|
18351
|
+
milestones: sceneDataRef2.current.milestones || []
|
|
18352
|
+
};
|
|
18249
18353
|
await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
|
|
18354
|
+
const questSaveUrl = sceneSaveUrl2.replace(
|
|
18355
|
+
"x_view_scenes",
|
|
18356
|
+
"x_view_quests"
|
|
18357
|
+
);
|
|
18358
|
+
await context.actions.save_view_data(questSaveUrl, questFilePayload);
|
|
18250
18359
|
} else {
|
|
18251
18360
|
const specificParentData = JSON.parse(
|
|
18252
18361
|
JSON.stringify(graphDataRef2.current[parentFileIdToSave])
|
|
@@ -18279,9 +18388,7 @@ function XViewScene({
|
|
|
18279
18388
|
if (line.material) line.material.dispose();
|
|
18280
18389
|
});
|
|
18281
18390
|
renderedAncestries.splice(renderIndex, 1);
|
|
18282
|
-
stateRef.current.ancestryLinks = renderedAncestries.flatMap(
|
|
18283
|
-
(a) => a.lines
|
|
18284
|
-
);
|
|
18391
|
+
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
18285
18392
|
}
|
|
18286
18393
|
}, []);
|
|
18287
18394
|
const handleRenderAncestry = useCallback7(
|
|
@@ -18854,9 +18961,7 @@ function XViewScene({
|
|
|
18854
18961
|
});
|
|
18855
18962
|
};
|
|
18856
18963
|
renderVertical(fullTree, rootNodeMesh, rootTargetPos, 1);
|
|
18857
|
-
stateRef.current.ancestryLinks = renderedAncestries.flatMap(
|
|
18858
|
-
(a) => a.lines
|
|
18859
|
-
);
|
|
18964
|
+
stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
|
|
18860
18965
|
tweenToTarget(rootTargetPos, 0.7);
|
|
18861
18966
|
},
|
|
18862
18967
|
[
|
|
@@ -18991,10 +19096,7 @@ function XViewScene({
|
|
|
18991
19096
|
};
|
|
18992
19097
|
const descriptionText = targetAncestryInfo.description || "";
|
|
18993
19098
|
const savedSections = targetAncestryInfo.description_sections || [];
|
|
18994
|
-
const sections = parseDescriptionSections(
|
|
18995
|
-
descriptionText,
|
|
18996
|
-
savedSections
|
|
18997
|
-
);
|
|
19099
|
+
const sections = parseDescriptionSections(descriptionText, savedSections);
|
|
18998
19100
|
let focusTargetId = null;
|
|
18999
19101
|
if (popped && popped.nodeId) {
|
|
19000
19102
|
const mentionTag = `[[MENTION:node:${popped.nodeId}]]`;
|
|
@@ -19607,16 +19709,26 @@ function XViewScene({
|
|
|
19607
19709
|
const result = await save_view_data(finalSaveUrl, masterAncestryList);
|
|
19608
19710
|
if (result.success && isExternalSave && isEditMode && currentAncestryId && ancestry_save_url && get_ancestry_file) {
|
|
19609
19711
|
try {
|
|
19610
|
-
const viewDbResponse = await get_ancestry_file(
|
|
19712
|
+
const viewDbResponse = await get_ancestry_file(
|
|
19713
|
+
sceneConfigId,
|
|
19714
|
+
ownerId
|
|
19715
|
+
);
|
|
19611
19716
|
if (viewDbResponse.success && Array.isArray(viewDbResponse.data)) {
|
|
19612
|
-
const hasInViewDb = viewDbResponse.data.some(
|
|
19717
|
+
const hasInViewDb = viewDbResponse.data.some(
|
|
19718
|
+
(anc) => String(anc.ancestry_id) === String(currentAncestryId)
|
|
19719
|
+
);
|
|
19613
19720
|
if (hasInViewDb) {
|
|
19614
|
-
const updatedViewDb = viewDbResponse.data.filter(
|
|
19721
|
+
const updatedViewDb = viewDbResponse.data.filter(
|
|
19722
|
+
(anc) => String(anc.ancestry_id) !== String(currentAncestryId)
|
|
19723
|
+
);
|
|
19615
19724
|
await save_view_data(ancestry_save_url, updatedViewDb);
|
|
19616
19725
|
}
|
|
19617
19726
|
}
|
|
19618
19727
|
} catch (fallbackErr) {
|
|
19619
|
-
console.error(
|
|
19728
|
+
console.error(
|
|
19729
|
+
"Falha ao limpar c\xF3pia residual na edi\xE7\xE3o:",
|
|
19730
|
+
fallbackErr
|
|
19731
|
+
);
|
|
19620
19732
|
}
|
|
19621
19733
|
}
|
|
19622
19734
|
if (result.success) {
|
|
@@ -19727,7 +19839,10 @@ function XViewScene({
|
|
|
19727
19839
|
try {
|
|
19728
19840
|
let updatedAncestriesForFile;
|
|
19729
19841
|
if (get_ancestry_file && isExternalSave) {
|
|
19730
|
-
const remoteResponse = await get_ancestry_file(
|
|
19842
|
+
const remoteResponse = await get_ancestry_file(
|
|
19843
|
+
sourceFileId,
|
|
19844
|
+
sourceOwnerId
|
|
19845
|
+
);
|
|
19731
19846
|
if (remoteResponse.success && Array.isArray(remoteResponse.data)) {
|
|
19732
19847
|
updatedAncestriesForFile = remoteResponse.data.filter(
|
|
19733
19848
|
(anc) => String(anc.ancestry_id) !== String(ancestryIdToDelete)
|
|
@@ -19742,11 +19857,16 @@ function XViewScene({
|
|
|
19742
19857
|
(anc) => anc._source_file_id === sourceFileId && String(anc.ancestry_id) !== String(ancestryIdToDelete)
|
|
19743
19858
|
);
|
|
19744
19859
|
}
|
|
19745
|
-
const result = await save_view_data(
|
|
19860
|
+
const result = await save_view_data(
|
|
19861
|
+
finalSaveUrl,
|
|
19862
|
+
updatedAncestriesForFile
|
|
19863
|
+
);
|
|
19746
19864
|
if (result.success) {
|
|
19747
19865
|
success = true;
|
|
19748
19866
|
} else {
|
|
19749
|
-
throw new Error(
|
|
19867
|
+
throw new Error(
|
|
19868
|
+
result.error || "Ocorreu um erro desconhecido ao excluir."
|
|
19869
|
+
);
|
|
19750
19870
|
}
|
|
19751
19871
|
} catch (error) {
|
|
19752
19872
|
deletionError = error;
|
|
@@ -19755,15 +19875,25 @@ function XViewScene({
|
|
|
19755
19875
|
try {
|
|
19756
19876
|
const viewDbResponse = await get_ancestry_file(sceneConfigId, ownerId);
|
|
19757
19877
|
if (viewDbResponse.success && Array.isArray(viewDbResponse.data)) {
|
|
19758
|
-
const hasInViewDb = viewDbResponse.data.some(
|
|
19878
|
+
const hasInViewDb = viewDbResponse.data.some(
|
|
19879
|
+
(anc) => String(anc.ancestry_id) === String(ancestryIdToDelete)
|
|
19880
|
+
);
|
|
19759
19881
|
if (hasInViewDb) {
|
|
19760
|
-
const updatedViewDb = viewDbResponse.data.filter(
|
|
19761
|
-
|
|
19882
|
+
const updatedViewDb = viewDbResponse.data.filter(
|
|
19883
|
+
(anc) => String(anc.ancestry_id) !== String(ancestryIdToDelete)
|
|
19884
|
+
);
|
|
19885
|
+
const fallbackResult = await save_view_data(
|
|
19886
|
+
ancestry_save_url,
|
|
19887
|
+
updatedViewDb
|
|
19888
|
+
);
|
|
19762
19889
|
if (fallbackResult.success) success = true;
|
|
19763
19890
|
}
|
|
19764
19891
|
}
|
|
19765
19892
|
} catch (fallbackErr) {
|
|
19766
|
-
console.error(
|
|
19893
|
+
console.error(
|
|
19894
|
+
"Falha ao limpar c\xF3pia residual da View DB:",
|
|
19895
|
+
fallbackErr
|
|
19896
|
+
);
|
|
19767
19897
|
}
|
|
19768
19898
|
}
|
|
19769
19899
|
if (!success && deletionError) {
|
|
@@ -19941,23 +20071,28 @@ function XViewScene({
|
|
|
19941
20071
|
...sceneDataRef.current,
|
|
19942
20072
|
nodes: sceneDataRef.current.nodes || [],
|
|
19943
20073
|
links: sceneDataRef.current.links || [],
|
|
19944
|
-
|
|
19945
|
-
|
|
19946
|
-
|
|
20074
|
+
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
20075
|
+
};
|
|
20076
|
+
delete sceneFileData.quest_nodes;
|
|
20077
|
+
delete sceneFileData.quest_links;
|
|
20078
|
+
delete sceneFileData.milestones;
|
|
20079
|
+
const questFileData = {
|
|
20080
|
+
nodes: ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || sceneDataRef.current.quest_nodes || [],
|
|
20081
|
+
links: ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || sceneDataRef.current.quest_links || [],
|
|
19947
20082
|
milestones: newMilestones
|
|
19948
20083
|
};
|
|
19949
20084
|
try {
|
|
19950
20085
|
await save_view_data(sceneSaveUrl, sceneFileData);
|
|
20086
|
+
const questSaveUrl = sceneSaveUrl.replace(
|
|
20087
|
+
"x_view_scenes",
|
|
20088
|
+
"x_view_quests"
|
|
20089
|
+
);
|
|
20090
|
+
await save_view_data(questSaveUrl, questFileData);
|
|
19951
20091
|
} catch (error) {
|
|
19952
20092
|
console.error("Erro ao salvar milestones:", error);
|
|
19953
20093
|
}
|
|
19954
20094
|
},
|
|
19955
|
-
[
|
|
19956
|
-
sceneConfigId,
|
|
19957
|
-
sceneSaveUrl,
|
|
19958
|
-
save_view_data,
|
|
19959
|
-
viewParams == null ? void 0 : viewParams.type
|
|
19960
|
-
]
|
|
20095
|
+
[sceneConfigId, sceneSaveUrl, save_view_data, viewParams == null ? void 0 : viewParams.type]
|
|
19961
20096
|
);
|
|
19962
20097
|
const handleSaveCurrentView = useCallback7(async () => {
|
|
19963
20098
|
var _a2, _b2, _c2;
|
|
@@ -19991,13 +20126,25 @@ function XViewScene({
|
|
|
19991
20126
|
...sceneDataRef.current,
|
|
19992
20127
|
nodes: currentNodes,
|
|
19993
20128
|
links: currentLinks,
|
|
19994
|
-
|
|
19995
|
-
|
|
19996
|
-
|
|
20129
|
+
quest_counter: sceneDataRef.current.quest_counter || 1
|
|
20130
|
+
};
|
|
20131
|
+
delete sceneFileData.quest_nodes;
|
|
20132
|
+
delete sceneFileData.quest_links;
|
|
20133
|
+
delete sceneFileData.milestones;
|
|
20134
|
+
const questFileData = {
|
|
20135
|
+
nodes: isView ? ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || [] : sceneDataRef.current.quest_nodes || [],
|
|
20136
|
+
links: isView ? ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || [] : sceneDataRef.current.quest_links || [],
|
|
19997
20137
|
milestones: sceneDataRef.current.milestones || []
|
|
19998
20138
|
};
|
|
19999
20139
|
try {
|
|
20000
20140
|
await save_view_data(sceneSaveUrl, sceneFileData);
|
|
20141
|
+
if (isView) {
|
|
20142
|
+
const questSaveUrl = sceneSaveUrl.replace(
|
|
20143
|
+
"x_view_scenes",
|
|
20144
|
+
"x_view_quests"
|
|
20145
|
+
);
|
|
20146
|
+
await save_view_data(questSaveUrl, questFileData);
|
|
20147
|
+
}
|
|
20001
20148
|
} catch (error) {
|
|
20002
20149
|
console.error("Erro na chamada de save_view_data:", error);
|
|
20003
20150
|
}
|
|
@@ -20114,7 +20261,12 @@ function XViewScene({
|
|
|
20114
20261
|
if (isUiClear) {
|
|
20115
20262
|
const isView = ((_c2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _c2.toLowerCase()) === "view";
|
|
20116
20263
|
if (!isView) return;
|
|
20117
|
-
const {
|
|
20264
|
+
const {
|
|
20265
|
+
graphGroup,
|
|
20266
|
+
glowTexture,
|
|
20267
|
+
controls: sceneControls,
|
|
20268
|
+
nodeObjects
|
|
20269
|
+
} = stateRef.current;
|
|
20118
20270
|
if (graphGroup) {
|
|
20119
20271
|
let ghostPosition = sceneControls.target.clone();
|
|
20120
20272
|
const existingNodes = Object.values(nodeObjects);
|
|
@@ -20170,7 +20322,12 @@ function XViewScene({
|
|
|
20170
20322
|
setQuestMode({ isActive: true });
|
|
20171
20323
|
}
|
|
20172
20324
|
}
|
|
20173
|
-
const isArrowKey = [
|
|
20325
|
+
const isArrowKey = [
|
|
20326
|
+
"ArrowUp",
|
|
20327
|
+
"ArrowDown",
|
|
20328
|
+
"ArrowLeft",
|
|
20329
|
+
"ArrowRight"
|
|
20330
|
+
].includes(event.key);
|
|
20174
20331
|
if (isArrowKey) {
|
|
20175
20332
|
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;
|
|
20176
20333
|
if (isUiClear) {
|
|
@@ -20216,7 +20373,12 @@ function XViewScene({
|
|
|
20216
20373
|
if (isLoading || status === "loading" || permissionStatus === "loading") {
|
|
20217
20374
|
return /* @__PURE__ */ React32.createElement(LoadingScreen, null);
|
|
20218
20375
|
}
|
|
20219
|
-
const overlayHiddenStyle = questTreeMode.isActive ? {
|
|
20376
|
+
const overlayHiddenStyle = questTreeMode.isActive ? {
|
|
20377
|
+
opacity: 0,
|
|
20378
|
+
pointerEvents: "none",
|
|
20379
|
+
transform: "translateX(30px)",
|
|
20380
|
+
transition: "all 300ms ease-in-out"
|
|
20381
|
+
} : {};
|
|
20220
20382
|
if (permissionStatus === "denied") {
|
|
20221
20383
|
return /* @__PURE__ */ React32.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ React32.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ React32.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ React32.createElement(
|
|
20222
20384
|
"svg",
|
|
@@ -20681,18 +20843,12 @@ function XViewScene({
|
|
|
20681
20843
|
data: multiContextMenu,
|
|
20682
20844
|
userRole: userPermissionRole,
|
|
20683
20845
|
onClose: () => setMultiContextMenu((prev) => ({ ...prev, visible: false })),
|
|
20684
|
-
onDismissNodes: (ids) => userActionHandlers.handleDismissMultipleNodes(
|
|
20685
|
-
actionHandlerContext,
|
|
20686
|
-
ids
|
|
20687
|
-
),
|
|
20846
|
+
onDismissNodes: (ids) => userActionHandlers.handleDismissMultipleNodes(actionHandlerContext, ids),
|
|
20688
20847
|
onDismissOtherNodes: (ids) => userActionHandlers.handleDismissOtherMultipleNodes(
|
|
20689
20848
|
actionHandlerContext,
|
|
20690
20849
|
ids
|
|
20691
20850
|
),
|
|
20692
|
-
onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(
|
|
20693
|
-
actionHandlerContext,
|
|
20694
|
-
ids
|
|
20695
|
-
)
|
|
20851
|
+
onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
|
|
20696
20852
|
}
|
|
20697
20853
|
),
|
|
20698
20854
|
/* @__PURE__ */ React32.createElement(
|
|
@@ -20845,7 +21001,7 @@ async function save_view_data_logic(db_services, filename, data) {
|
|
|
20845
21001
|
}
|
|
20846
21002
|
}
|
|
20847
21003
|
async function get_scene_view_data_logic(db_services, scene_config, owner_id, type, session, focusNodeId = null, focusAncestryId = null) {
|
|
20848
|
-
var _a, _b;
|
|
21004
|
+
var _a, _b, _c;
|
|
20849
21005
|
try {
|
|
20850
21006
|
if (!session || !session.user) {
|
|
20851
21007
|
return { success: false, error: "Usu\xE1rio n\xE3o autenticado." };
|
|
@@ -20868,28 +21024,44 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
20868
21024
|
parentDbObjects.push({ db_id: scene_config, owner_id });
|
|
20869
21025
|
}
|
|
20870
21026
|
}
|
|
21027
|
+
const isView = type && type.toLowerCase() === "view";
|
|
20871
21028
|
const parentResponsesPromises = parentDbObjects.map(
|
|
20872
21029
|
(db_info) => db_services.get_file(`x_view_dbs/${db_info.owner_id}/${db_info.db_id}`)
|
|
20873
21030
|
);
|
|
21031
|
+
if (isView) {
|
|
21032
|
+
parentResponsesPromises.push(
|
|
21033
|
+
db_services.get_file(`x_view_quests/${owner_id}/${scene_config}`)
|
|
21034
|
+
);
|
|
21035
|
+
}
|
|
20874
21036
|
const parentResponsesResults = await Promise.allSettled(parentResponsesPromises);
|
|
20875
21037
|
const parentData = {};
|
|
21038
|
+
let questDataObj = null;
|
|
20876
21039
|
for (let i = 0; i < parentResponsesResults.length; i++) {
|
|
20877
21040
|
const result = parentResponsesResults[i];
|
|
21041
|
+
if (isView && i === parentResponsesResults.length - 1) {
|
|
21042
|
+
if (result.status === "fulfilled" && ((_a = result.value) == null ? void 0 : _a.success)) {
|
|
21043
|
+
questDataObj = result.value.data;
|
|
21044
|
+
}
|
|
21045
|
+
continue;
|
|
21046
|
+
}
|
|
20878
21047
|
const db_info = parentDbObjects[i];
|
|
20879
|
-
if (result.status === "fulfilled" && ((
|
|
21048
|
+
if (result.status === "fulfilled" && ((_b = result.value) == null ? void 0 : _b.success)) {
|
|
20880
21049
|
parentData[db_info.db_id] = result.value.data;
|
|
20881
21050
|
} else {
|
|
20882
21051
|
console.warn(
|
|
20883
21052
|
`Arquivo pai n\xE3o carregado: ${db_info.db_id}. Pode ter sido deletado.`,
|
|
20884
|
-
result.status === "rejected" ? result.reason : (
|
|
21053
|
+
result.status === "rejected" ? result.reason : (_c = result.value) == null ? void 0 : _c.error
|
|
20885
21054
|
);
|
|
20886
21055
|
}
|
|
20887
21056
|
}
|
|
20888
|
-
|
|
21057
|
+
const currentQuestNodes = (questDataObj == null ? void 0 : questDataObj.nodes) || sceneData.quest_nodes || [];
|
|
21058
|
+
const currentQuestLinks = (questDataObj == null ? void 0 : questDataObj.links) || sceneData.quest_links || [];
|
|
21059
|
+
const currentMilestones = (questDataObj == null ? void 0 : questDataObj.milestones) || sceneData.milestones || [];
|
|
21060
|
+
if (isView) {
|
|
20889
21061
|
parentData[scene_config] = {
|
|
20890
21062
|
dataset_name: "Quests Internas (View)",
|
|
20891
|
-
nodes:
|
|
20892
|
-
links:
|
|
21063
|
+
nodes: currentQuestNodes,
|
|
21064
|
+
links: currentQuestLinks
|
|
20893
21065
|
};
|
|
20894
21066
|
}
|
|
20895
21067
|
const allNodes = Object.values(parentData).flatMap((db) => db.nodes || []);
|
|
@@ -20921,7 +21093,12 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
|
|
|
20921
21093
|
const validatedSceneData = {
|
|
20922
21094
|
...sceneData,
|
|
20923
21095
|
nodes: validatedNodes,
|
|
20924
|
-
links: validatedLinks
|
|
21096
|
+
links: validatedLinks,
|
|
21097
|
+
// Re-injetando no validated para que o restante do sistema (e.g. XViewScene local state)
|
|
21098
|
+
// continue acessando as quests sem perceber a separação física
|
|
21099
|
+
quest_nodes: currentQuestNodes,
|
|
21100
|
+
quest_links: currentQuestLinks,
|
|
21101
|
+
milestones: currentMilestones
|
|
20925
21102
|
};
|
|
20926
21103
|
const ancestryFilePaths = [];
|
|
20927
21104
|
ancestryFilePaths.push({
|