Organize app source
This commit is contained in:
307
js/trashRestoreDelete.js
Normal file
307
js/trashRestoreDelete.js
Normal file
@@ -0,0 +1,307 @@
|
||||
// trashRestoreDelete.js
|
||||
import { sendRequest } from './networkUtils.js';
|
||||
import { toggleVisibility, showToast } from './domUtils.js';
|
||||
import { loadFileList } from './fileManager.js';
|
||||
import { loadFolderTree } from './folderManager.js';
|
||||
|
||||
function showConfirm(message, onConfirm) {
|
||||
const modal = document.getElementById("customConfirmModal");
|
||||
const messageElem = document.getElementById("confirmMessage");
|
||||
const yesBtn = document.getElementById("confirmYesBtn");
|
||||
const noBtn = document.getElementById("confirmNoBtn");
|
||||
|
||||
if (!modal || !messageElem || !yesBtn || !noBtn) {
|
||||
if (confirm(message)) {
|
||||
onConfirm();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
messageElem.textContent = message;
|
||||
modal.style.display = "block";
|
||||
|
||||
// Clear any previous event listeners by cloning the node.
|
||||
const yesBtnClone = yesBtn.cloneNode(true);
|
||||
yesBtn.parentNode.replaceChild(yesBtnClone, yesBtn);
|
||||
const noBtnClone = noBtn.cloneNode(true);
|
||||
noBtn.parentNode.replaceChild(noBtnClone, noBtn);
|
||||
|
||||
yesBtnClone.addEventListener("click", () => {
|
||||
modal.style.display = "none";
|
||||
onConfirm();
|
||||
});
|
||||
noBtnClone.addEventListener("click", () => {
|
||||
modal.style.display = "none";
|
||||
});
|
||||
}
|
||||
|
||||
export function setupTrashRestoreDelete() {
|
||||
|
||||
// --- Attach listener to the restore button (created in auth.js) to open the modal.
|
||||
const restoreBtn = document.getElementById("restoreFilesBtn");
|
||||
if (restoreBtn) {
|
||||
restoreBtn.addEventListener("click", () => {
|
||||
toggleVisibility("restoreFilesModal", true);
|
||||
loadTrashItems();
|
||||
});
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
const retryBtn = document.getElementById("restoreFilesBtn");
|
||||
if (retryBtn) {
|
||||
retryBtn.addEventListener("click", () => {
|
||||
toggleVisibility("restoreFilesModal", true);
|
||||
loadTrashItems();
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
|
||||
// --- Restore Selected: Restore only the selected trash items.
|
||||
const restoreSelectedBtn = document.getElementById("restoreSelectedBtn");
|
||||
if (restoreSelectedBtn) {
|
||||
restoreSelectedBtn.addEventListener("click", () => {
|
||||
const selected = document.querySelectorAll("#restoreFilesList input[type='checkbox']:checked");
|
||||
const files = Array.from(selected).map(chk => chk.value);
|
||||
console.log("Restore Selected clicked, files:", files);
|
||||
if (files.length === 0) {
|
||||
showToast("No trash items selected for restore.");
|
||||
return;
|
||||
}
|
||||
fetch("restoreFiles.php", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-Token": window.csrfToken
|
||||
},
|
||||
body: JSON.stringify({ files })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showToast(data.success);
|
||||
toggleVisibility("restoreFilesModal", false);
|
||||
loadFileList(window.currentFolder);
|
||||
loadFolderTree(window.currentFolder);
|
||||
} else {
|
||||
showToast(data.error);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error restoring files:", err);
|
||||
showToast("Error restoring files.");
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error("restoreSelectedBtn not found.");
|
||||
}
|
||||
|
||||
// --- Restore All: Restore all trash items.
|
||||
const restoreAllBtn = document.getElementById("restoreAllBtn");
|
||||
if (restoreAllBtn) {
|
||||
restoreAllBtn.addEventListener("click", () => {
|
||||
const allChk = document.querySelectorAll("#restoreFilesList input[type='checkbox']");
|
||||
const files = Array.from(allChk).map(chk => chk.value);
|
||||
console.log("Restore All clicked, files:", files);
|
||||
if (files.length === 0) {
|
||||
showToast("Trash is empty.");
|
||||
return;
|
||||
}
|
||||
fetch("restoreFiles.php", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-Token": window.csrfToken
|
||||
},
|
||||
body: JSON.stringify({ files })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showToast(data.success);
|
||||
toggleVisibility("restoreFilesModal", false);
|
||||
loadFileList(window.currentFolder);
|
||||
loadFolderTree(window.currentFolder);
|
||||
|
||||
} else {
|
||||
showToast(data.error);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error restoring files:", err);
|
||||
showToast("Error restoring files.");
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error("restoreAllBtn not found.");
|
||||
}
|
||||
|
||||
// --- Delete Selected: Permanently delete selected trash items with confirmation.
|
||||
const deleteTrashSelectedBtn = document.getElementById("deleteTrashSelectedBtn");
|
||||
if (deleteTrashSelectedBtn) {
|
||||
deleteTrashSelectedBtn.addEventListener("click", () => {
|
||||
const selected = document.querySelectorAll("#restoreFilesList input[type='checkbox']:checked");
|
||||
const files = Array.from(selected).map(chk => chk.value);
|
||||
console.log("Delete Selected clicked, files:", files);
|
||||
if (files.length === 0) {
|
||||
showToast("No trash items selected for deletion.");
|
||||
return;
|
||||
}
|
||||
showConfirm("Are you sure you want to permanently delete the selected trash items?", () => {
|
||||
fetch("deleteTrashFiles.php", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-Token": window.csrfToken
|
||||
},
|
||||
body: JSON.stringify({ files })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showToast(data.success);
|
||||
loadTrashItems();
|
||||
loadFileList(window.currentFolder);
|
||||
loadFolderTree(window.currentFolder);
|
||||
} else {
|
||||
showToast(data.error);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error deleting trash files:", err);
|
||||
showToast("Error deleting trash files.");
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error("deleteTrashSelectedBtn not found.");
|
||||
}
|
||||
|
||||
// --- Delete All: Permanently delete all trash items with confirmation.
|
||||
const deleteAllBtn = document.getElementById("deleteAllBtn");
|
||||
if (deleteAllBtn) {
|
||||
deleteAllBtn.addEventListener("click", () => {
|
||||
showConfirm("Are you sure you want to permanently delete all trash items? This action cannot be undone.", () => {
|
||||
fetch("deleteTrashFiles.php", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-Token": window.csrfToken
|
||||
},
|
||||
body: JSON.stringify({ deleteAll: true })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showToast(data.success);
|
||||
toggleVisibility("restoreFilesModal", false);
|
||||
loadFileList(window.currentFolder);
|
||||
loadFolderTree(window.currentFolder);
|
||||
} else {
|
||||
showToast(data.error);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error deleting all trash files:", err);
|
||||
showToast("Error deleting all trash files.");
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error("deleteAllBtn not found.");
|
||||
}
|
||||
|
||||
// --- Close the Restore Modal ---
|
||||
const closeRestoreModal = document.getElementById("closeRestoreModal");
|
||||
if (closeRestoreModal) {
|
||||
closeRestoreModal.addEventListener("click", () => {
|
||||
toggleVisibility("restoreFilesModal", false);
|
||||
});
|
||||
} else {
|
||||
console.error("closeRestoreModal not found.");
|
||||
}
|
||||
|
||||
// --- Auto-purge old trash items (older than 3 days) ---
|
||||
autoPurgeOldTrash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads trash items from the server and updates the restore modal list.
|
||||
*/
|
||||
export function loadTrashItems() {
|
||||
fetch("getTrashItems.php", { credentials: "include" })
|
||||
.then(response => response.json())
|
||||
.then(trashItems => {
|
||||
const listContainer = document.getElementById("restoreFilesList");
|
||||
if (listContainer) {
|
||||
listContainer.innerHTML = "";
|
||||
trashItems.forEach(item => {
|
||||
const li = document.createElement("li");
|
||||
li.style.listStyle = "none";
|
||||
li.style.marginBottom = "5px";
|
||||
|
||||
const checkbox = document.createElement("input");
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.value = item.trashName;
|
||||
li.appendChild(checkbox);
|
||||
|
||||
const label = document.createElement("label");
|
||||
label.style.marginLeft = "8px";
|
||||
// Include the deletedBy username in the label text.
|
||||
const deletedBy = item.deletedBy ? item.deletedBy : "Unknown";
|
||||
label.textContent = `${item.originalName} (${deletedBy} trashed on ${new Date(item.trashedAt * 1000).toLocaleString()})`;
|
||||
li.appendChild(label);
|
||||
|
||||
listContainer.appendChild(li);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error loading trash items:", err);
|
||||
showToast("Error loading trash items.");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically purges (permanently deletes) trash items older than 3 days.
|
||||
*/
|
||||
function autoPurgeOldTrash() {
|
||||
fetch("getTrashItems.php", { credentials: "include" })
|
||||
.then(response => response.json())
|
||||
.then(trashItems => {
|
||||
const now = Date.now();
|
||||
const threeDays = 3 * 24 * 60 * 60 * 1000;
|
||||
const oldItems = trashItems.filter(item => (now - (item.trashedAt * 1000)) > threeDays);
|
||||
if (oldItems.length > 0) {
|
||||
const files = oldItems.map(item => item.trashName);
|
||||
fetch("deleteTrashFiles.php", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-Token": window.csrfToken
|
||||
},
|
||||
body: JSON.stringify({ files })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
console.log("Auto-purged old trash items:", data.success);
|
||||
loadTrashItems();
|
||||
} else {
|
||||
console.warn("Auto-purge warning:", data.error);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error auto-purging old trash items:", err);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error retrieving trash items for auto-purge:", err);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user