Xóa scene con mà không xóa scene cha

This commit is contained in:
2026-06-09 21:26:47 +07:00
parent d39d3b3d53
commit 67825b04cc
22 changed files with 1185 additions and 1486 deletions
+1 -1
View File
@@ -371,7 +371,7 @@
<div id="delete-scene-confirm-modal" class="modal-overlay">
<div class="modal-content action-modal-content logout-modal-dark">
<h2 style="color: #fff; margin-bottom: 10px;">Xác nhận xóa Scene</h2>
<p style="color: #ccc; margin-bottom: 25px;">Bạn có chắc chắn muốn xóa Scene này? Toàn bộ các scene con liên kết và các hotspot sẽ bị xóa vĩnh viễn khỏi hệ thống.</p>
<p id="delete-scene-confirm-message" style="color: #ccc; margin-bottom: 25px;">Bạn có chắc chắn muốn xóa Scene này? Toàn bộ các scene con liên kết và các hotspot sẽ bị xóa vĩnh viễn khỏi hệ thống.</p>
<div class="action-buttons">
<button onclick="confirmDeleteScene()" class="delete-btn-large">Xóa vĩnh viễn</button>
<button onclick="closeDeleteSceneModal()" class="edit-btn-large" style="background: #6c757d;">Hủy bỏ</button>
+42 -8
View File
@@ -974,9 +974,46 @@ function closeActionModal() {
/**
* Mở modal xác nhận xóa scene
*/
window.deleteScene = function(sceneId) {
window.deleteScene = async function(sceneId, sceneData = null) { // Thêm sceneData để tránh fetch lại
sceneIdToDelete = sceneId;
document.getElementById('delete-scene-confirm-modal').style.display = 'flex';
const confirmModal = document.getElementById('delete-scene-confirm-modal');
const confirmMessageElem = document.getElementById('delete-scene-confirm-message'); // Giả định có element này trong HTML
if (!confirmModal || !confirmMessageElem) {
console.error("Delete confirmation modal elements not found.");
return;
}
const token = localStorage.getItem('jwt');
if (!token) {
showNotification('Vui lòng đăng nhập để thực hiện thao tác này.', 'warning');
return;
}
let sceneToConfirm = sceneData;
if (!sceneToConfirm) {
try {
// Fetch scene details nếu chưa có sẵn (ví dụ: xóa từ bản đồ)
const response = await fetch(`${API_BASE_URL}/scenes/${sceneId}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
sceneToConfirm = await response.json();
if (!response.ok) throw new Error(sceneToConfirm.message || 'Failed to fetch scene details for deletion.');
} catch (error) {
showNotification("Không thể chuẩn bị xóa scene: " + error.message, 'error');
return;
}
}
let message = '';
if (sceneToConfirm.isChildScene) {
message = `Bạn đang xóa cảnh "${sceneToConfirm.name || sceneToConfirm.title}". Cảnh này là một phần của tour khác. Việc xóa sẽ chỉ gỡ bỏ cảnh này và các liên kết đến nó. Các cảnh cha sẽ không bị ảnh hưởng. Bạn có chắc chắn muốn xóa?`;
} else {
message = `Bạn đang xóa cảnh "${sceneToConfirm.name || sceneToConfirm.title}". Cảnh này có thể là cảnh gốc hoặc cảnh không có liên kết đến. Việc xóa sẽ gỡ bỏ cảnh này VÀ TẤT CẢ CÁC CẢNH CON liên kết với nó trong tour. Thao tác này không thể hoàn tác. Bạn có chắc chắn muốn xóa?`;
}
confirmMessageElem.innerText = message;
confirmModal.style.display = 'flex';
};
window.closeDeleteSceneModal = function() {
@@ -1549,12 +1586,9 @@ async function loadMyScenes() {
openEditMetadataModal(scene, scene.isChildScene);
};
// Xử lý nút Xóa (Sẽ được hoàn thiện ở Bước 4)
document.getElementById(`delete-scene-${scene._id}`).onclick = () => {
dashboardReturnTab = 'my-scenes';
returnToDashboardAfterEdit = true;
closeDashboard();
deleteScene(scene._id);
// Xử lý nút Xóa
document.getElementById(`delete-scene-${scene._id}`).onclick = async () => {
await deleteScene(scene._id, scene); // Truyền đối tượng scene đầy đủ
};
// Xử lý nút Thống kê
+8 -3
View File
@@ -167,10 +167,15 @@ function applyViewerSecurity() {
const panoramaViewer = document.getElementById('panorama-viewer');
const handleContextMenu = (e) => {
// Nếu click trúng vào hotspot hiện có thì không xử lý tại đây
// để listener của hotspot (trong renderCustomHotspot) được chạy.
if (e.target.closest('.pnlm-custom-hotspot')) {
return;
}
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
return false; // Ngăn chặn menu chuột phải mặc định của trình duyệt
// Nếu viewer đang hoạt động, lấy tọa độ Pitch/Yaw tại điểm click
if (activeViewer) {
@@ -203,8 +208,8 @@ function applyViewerSecurity() {
};
// Sử dụng capture phase (true) để bắt sự kiện trước khi nó chạm đến Pannellum
// container.addEventListener('contextmenu', handleContextMenu, true); // Bỏ gắn sự kiện này
// panoramaViewer.addEventListener('contextmenu', handleContextMenu, true); // Bỏ gắn sự kiện này
container.addEventListener('contextmenu', handleContextMenu, true);
panoramaViewer.addEventListener('contextmenu', handleContextMenu, true);
// Block drag and drop
container.addEventListener('dragstart', (e) => {