feat: add node deletion confirmation modal and global sequence guard for dashboard

This commit is contained in:
mik-tf
2025-09-08 23:06:58 -04:00
parent 5f850dd8f2
commit 138f67e02e
3 changed files with 166 additions and 4 deletions

View File

@@ -4092,7 +4092,9 @@ async function loadExistingGroups() {
}
// Stale-guard for node details fetches
let __nodeDetailsSeq = 0;
// Guard against redeclaration - use window scope to persist across reloads
window.__nodeDetailsSeq = window.__nodeDetailsSeq || 0;
let __nodeDetailsSeq = window.__nodeDetailsSeq;
/**
* View node details
@@ -4105,7 +4107,7 @@ async function loadExistingGroups() {
window.__nodeDetailsController = (typeof AbortController !== 'undefined') ? new AbortController() : null;
// Sequence guard to avoid race conditions
const requestId = ++__nodeDetailsSeq;
const requestId = ++window.__nodeDetailsSeq;
const nodeData = await window.apiJson(`/api/dashboard/farm-nodes/${nodeId}`, {
cache: 'no-store',
@@ -4113,7 +4115,7 @@ async function loadExistingGroups() {
});
// If a newer request started, ignore this response
if (requestId !== __nodeDetailsSeq) return;
if (requestId !== window.__nodeDetailsSeq) return;
console.log('👁️ Loaded node details:', nodeData);
showNodeDetailsModal(nodeData);
@@ -4123,6 +4125,47 @@ async function loadExistingGroups() {
}
}
/**
* Delete node configuration (show confirmation modal)
*/
async function deleteNodeConfiguration(nodeId) {
console.log('🗑️ Initiating node deletion for nodeId:', nodeId);
if (!nodeId) {
console.error('🗑️ No node ID provided for deletion');
showNotification('Error: No node ID provided', 'error');
return;
}
try {
// Fetch node data to get the node name for confirmation
console.log('🗑️ Fetching node data for deletion confirmation:', nodeId);
const nodeData = await window.apiJson(`/api/dashboard/farm-nodes/${nodeId}`, {
cache: 'no-store'
});
console.log('🗑️ Loaded node data for deletion:', nodeData);
// Set the pending delete node ID
window.pendingDeleteNodeId = nodeId;
// Update the modal with node information
const deleteNodeNameElement = document.getElementById('deleteNodeName');
if (deleteNodeNameElement) {
const nodeName = nodeData.name || `Node ${nodeId}`;
deleteNodeNameElement.textContent = nodeName;
}
// Show the delete confirmation modal
const deleteModal = new bootstrap.Modal(document.getElementById('deleteNodeModal'));
deleteModal.show();
} catch (error) {
console.error('🗑️ Error preparing node deletion:', error);
showNotification(`Failed to prepare node deletion: ${error.message}`, 'error');
}
}
/**
* Confirm node deletion (called from modal)
*/

View File

@@ -3,6 +3,9 @@
* Handles communication between users and providers.
*/
// Guard against redeclaration
if (typeof MessagingSystem === 'undefined') {
class MessagingSystem {
constructor() {
this.currentThread = null;
@@ -960,3 +963,5 @@ MessagingSystem.prototype.openThreadFromList = function(threadId) {
// Open the specific thread in the old modal
this.openThread(threadId);
};
} // End of MessagingSystem guard