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