feat: add node deletion confirmation modal and global sequence guard for dashboard
This commit is contained in:
@@ -4092,7 +4092,9 @@ async function loadExistingGroups() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stale-guard for node details fetches
|
// 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
|
* View node details
|
||||||
@@ -4105,7 +4107,7 @@ async function loadExistingGroups() {
|
|||||||
window.__nodeDetailsController = (typeof AbortController !== 'undefined') ? new AbortController() : null;
|
window.__nodeDetailsController = (typeof AbortController !== 'undefined') ? new AbortController() : null;
|
||||||
|
|
||||||
// Sequence guard to avoid race conditions
|
// Sequence guard to avoid race conditions
|
||||||
const requestId = ++__nodeDetailsSeq;
|
const requestId = ++window.__nodeDetailsSeq;
|
||||||
|
|
||||||
const nodeData = await window.apiJson(`/api/dashboard/farm-nodes/${nodeId}`, {
|
const nodeData = await window.apiJson(`/api/dashboard/farm-nodes/${nodeId}`, {
|
||||||
cache: 'no-store',
|
cache: 'no-store',
|
||||||
@@ -4113,7 +4115,7 @@ async function loadExistingGroups() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// If a newer request started, ignore this response
|
// If a newer request started, ignore this response
|
||||||
if (requestId !== __nodeDetailsSeq) return;
|
if (requestId !== window.__nodeDetailsSeq) return;
|
||||||
|
|
||||||
console.log('👁️ Loaded node details:', nodeData);
|
console.log('👁️ Loaded node details:', nodeData);
|
||||||
showNodeDetailsModal(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)
|
* Confirm node deletion (called from modal)
|
||||||
*/
|
*/
|
||||||
|
@@ -3,6 +3,9 @@
|
|||||||
* Handles communication between users and providers.
|
* Handles communication between users and providers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Guard against redeclaration
|
||||||
|
if (typeof MessagingSystem === 'undefined') {
|
||||||
|
|
||||||
class MessagingSystem {
|
class MessagingSystem {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.currentThread = null;
|
this.currentThread = null;
|
||||||
@@ -960,3 +963,5 @@ MessagingSystem.prototype.openThreadFromList = function(threadId) {
|
|||||||
// Open the specific thread in the old modal
|
// Open the specific thread in the old modal
|
||||||
this.openThread(threadId);
|
this.openThread(threadId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // End of MessagingSystem guard
|
||||||
|
@@ -37,7 +37,121 @@
|
|||||||
"deleted": null,
|
"deleted": null,
|
||||||
"deleted_at": null,
|
"deleted_at": null,
|
||||||
"deletion_reason": null,
|
"deletion_reason": null,
|
||||||
"nodes": [],
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": "grid_node_1",
|
||||||
|
"location": "Unknown, Belgium",
|
||||||
|
"status": "Online",
|
||||||
|
"capacity": {
|
||||||
|
"cpu_cores": 56,
|
||||||
|
"memory_gb": 188,
|
||||||
|
"storage_gb": 135975,
|
||||||
|
"bandwidth_mbps": 1000,
|
||||||
|
"ssd_storage_gb": 1863,
|
||||||
|
"hdd_storage_gb": 134112,
|
||||||
|
"ram_gb": 188
|
||||||
|
},
|
||||||
|
"used_capacity": {
|
||||||
|
"cpu_cores": 25,
|
||||||
|
"memory_gb": 92,
|
||||||
|
"storage_gb": 1021,
|
||||||
|
"bandwidth_mbps": 0,
|
||||||
|
"ssd_storage_gb": 1021,
|
||||||
|
"hdd_storage_gb": 0,
|
||||||
|
"ram_gb": 92
|
||||||
|
},
|
||||||
|
"uptime_percentage": 99.0,
|
||||||
|
"farming_start_date": "2025-08-10T03:03:44.241167749Z",
|
||||||
|
"last_updated": "2025-09-09T03:03:44.241194575Z",
|
||||||
|
"utilization_7_day_avg": 65.0,
|
||||||
|
"slice_formats_supported": [
|
||||||
|
"1x1",
|
||||||
|
"2x2",
|
||||||
|
"4x4"
|
||||||
|
],
|
||||||
|
"rental_options": null,
|
||||||
|
"total_base_slices": 0,
|
||||||
|
"allocated_base_slices": 0,
|
||||||
|
"earnings_today_usd": 0.0,
|
||||||
|
"grid_node_id": "1",
|
||||||
|
"available_combinations": [],
|
||||||
|
"slice_allocations": [],
|
||||||
|
"slice_last_calculated": null,
|
||||||
|
"marketplace_sla": {
|
||||||
|
"id": "sla-repair-90a36bcd-b6e2-45e7-872a-baeaa485f220",
|
||||||
|
"name": "Repaired Node SLA",
|
||||||
|
"uptime_guarantee": 99.8,
|
||||||
|
"response_time_hours": 24,
|
||||||
|
"resolution_time_hours": 48,
|
||||||
|
"penalty_rate": 0.01,
|
||||||
|
"uptime_guarantee_percentage": 99.8,
|
||||||
|
"base_slice_price": 0.5,
|
||||||
|
"bandwidth_guarantee_mbps": 100.0,
|
||||||
|
"last_updated": "2025-09-09T03:04:23.227212978Z"
|
||||||
|
},
|
||||||
|
"slice_pricing": {
|
||||||
|
"base_price_per_hour": 1.0,
|
||||||
|
"currency": "USD",
|
||||||
|
"pricing_multiplier": 1.0
|
||||||
|
},
|
||||||
|
"grid_data": {
|
||||||
|
"capacity": {
|
||||||
|
"bandwidth_mbps": 1000,
|
||||||
|
"cpu_cores": 56,
|
||||||
|
"hdd_storage_gb": 134112,
|
||||||
|
"memory_gb": 188,
|
||||||
|
"ram_gb": 188,
|
||||||
|
"ssd_storage_gb": 1863,
|
||||||
|
"storage_gb": 135975
|
||||||
|
},
|
||||||
|
"certification_type": "Diy",
|
||||||
|
"city": "Unknown",
|
||||||
|
"country": "Belgium",
|
||||||
|
"farm_id": 1,
|
||||||
|
"farm_name": "Freefarm",
|
||||||
|
"farming_policy_id": 1,
|
||||||
|
"grid_node_id": 1,
|
||||||
|
"last_updated": "2025-09-09T03:03:44.240833231Z",
|
||||||
|
"location": "Unknown, Belgium",
|
||||||
|
"node_id": 1,
|
||||||
|
"public_ips": [
|
||||||
|
"192.168.1.100"
|
||||||
|
],
|
||||||
|
"status": "Online",
|
||||||
|
"total_resources": {
|
||||||
|
"bandwidth_mbps": 1000,
|
||||||
|
"cpu_cores": 56,
|
||||||
|
"hdd_storage_gb": 134112,
|
||||||
|
"memory_gb": 188,
|
||||||
|
"ram_gb": 188,
|
||||||
|
"ssd_storage_gb": 1863,
|
||||||
|
"storage_gb": 135975
|
||||||
|
},
|
||||||
|
"uptime": 99.5,
|
||||||
|
"used_resources": {
|
||||||
|
"bandwidth_mbps": 0,
|
||||||
|
"cpu_cores": 25,
|
||||||
|
"hdd_storage_gb": 0,
|
||||||
|
"memory_gb": 92,
|
||||||
|
"ram_gb": 92,
|
||||||
|
"ssd_storage_gb": 1021,
|
||||||
|
"storage_gb": 1021
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"slice_formats": null,
|
||||||
|
"name": "Grid Node 1",
|
||||||
|
"region": "Belgium",
|
||||||
|
"node_type": "MyceliumNode",
|
||||||
|
"staking_options": null,
|
||||||
|
"availability_status": "Available",
|
||||||
|
"node_group_id": null,
|
||||||
|
"group_assignment_date": null,
|
||||||
|
"group_slice_format": null,
|
||||||
|
"group_slice_price": null,
|
||||||
|
"last_seen": "2025-09-09T03:03:44.241206636Z",
|
||||||
|
"health_score": 100.0
|
||||||
|
}
|
||||||
|
],
|
||||||
"resource_provider_earnings": [],
|
"resource_provider_earnings": [],
|
||||||
"resource_provider_settings": null,
|
"resource_provider_settings": null,
|
||||||
"slice_products": [],
|
"slice_products": [],
|
||||||
|
Reference in New Issue
Block a user