feat: introduce overlay dialog component
This commit is contained in:
@@ -7,6 +7,9 @@ class FirmwareComponent extends Component {
|
||||
logger.debug('FirmwareComponent: Container:', container);
|
||||
logger.debug('FirmwareComponent: Container ID:', container?.id);
|
||||
|
||||
// Initialize overlay dialog
|
||||
this.overlayDialog = null;
|
||||
|
||||
// Check if the dropdown exists in the container
|
||||
if (container) {
|
||||
const dropdown = container.querySelector('#specific-node-select');
|
||||
@@ -105,6 +108,9 @@ class FirmwareComponent extends Component {
|
||||
|
||||
logger.debug('FirmwareComponent: Mounting...');
|
||||
|
||||
// Initialize overlay dialog
|
||||
this.initializeOverlayDialog();
|
||||
|
||||
// Check if the dropdown exists when mounted
|
||||
const dropdown = this.findElement('#specific-node-select');
|
||||
logger.debug('FirmwareComponent: Mount - dropdown found:', !!dropdown);
|
||||
@@ -131,6 +137,24 @@ class FirmwareComponent extends Component {
|
||||
this.updateDeployButton();
|
||||
}
|
||||
|
||||
initializeOverlayDialog() {
|
||||
// Create overlay container if it doesn't exist
|
||||
let overlayContainer = document.getElementById('firmware-overlay-dialog');
|
||||
if (!overlayContainer) {
|
||||
overlayContainer = document.createElement('div');
|
||||
overlayContainer.id = 'firmware-overlay-dialog';
|
||||
overlayContainer.className = 'overlay-dialog';
|
||||
document.body.appendChild(overlayContainer);
|
||||
}
|
||||
|
||||
// Create and initialize the overlay dialog component
|
||||
if (!this.overlayDialog) {
|
||||
const overlayVM = new ViewModel();
|
||||
this.overlayDialog = new OverlayDialogComponent(overlayContainer, overlayVM, this.eventBus);
|
||||
this.overlayDialog.mount();
|
||||
}
|
||||
}
|
||||
|
||||
handleFileSelect(event) {
|
||||
const file = event.target.files[0];
|
||||
this.viewModel.setSelectedFile(file);
|
||||
@@ -160,15 +184,69 @@ class FirmwareComponent extends Component {
|
||||
const specificNode = this.viewModel.get('specificNode');
|
||||
|
||||
if (!file) {
|
||||
alert('Please select a firmware file first.');
|
||||
this.showConfirmationDialog({
|
||||
title: 'No File Selected',
|
||||
message: 'Please select a firmware file first.',
|
||||
confirmText: 'OK',
|
||||
cancelText: null,
|
||||
onConfirm: () => {},
|
||||
onCancel: null
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetType === 'specific' && !specificNode) {
|
||||
alert('Please select a specific node to update.');
|
||||
this.showConfirmationDialog({
|
||||
title: 'No Node Selected',
|
||||
message: 'Please select a specific node to update.',
|
||||
confirmText: 'OK',
|
||||
cancelText: null,
|
||||
onConfirm: () => {},
|
||||
onCancel: null
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Show confirmation dialog for deployment
|
||||
this.showDeploymentConfirmation(file, targetType, specificNode);
|
||||
}
|
||||
|
||||
showConfirmationDialog(options) {
|
||||
if (!this.overlayDialog) {
|
||||
this.initializeOverlayDialog();
|
||||
}
|
||||
|
||||
this.overlayDialog.show(options);
|
||||
}
|
||||
|
||||
showDeploymentConfirmation(file, targetType, specificNode) {
|
||||
let title, message;
|
||||
|
||||
if (targetType === 'all') {
|
||||
const nodes = this.viewModel.get('availableNodes') || [];
|
||||
title = 'Deploy to All Nodes';
|
||||
message = `Upload firmware "${file.name}" to all ${nodes.length} nodes?<br><br>This will update:<br>${nodes.map(n => `• ${n.hostname || n.ip}`).join('<br>')}`;
|
||||
} else if (targetType === 'specific') {
|
||||
title = 'Deploy to Specific Node';
|
||||
message = `Upload firmware "${file.name}" to node ${specificNode}?`;
|
||||
} else if (targetType === 'labels') {
|
||||
const nodes = this.viewModel.getAffectedNodesByLabels();
|
||||
const labels = this.viewModel.get('selectedLabels') || [];
|
||||
title = 'Deploy to Labeled Nodes';
|
||||
message = `Upload firmware "${file.name}" to ${nodes.length} node(s) matching labels (${labels.join(', ')})?<br><br>This will update:<br>${nodes.map(n => `• ${n.hostname || n.ip}`).join('<br>')}`;
|
||||
}
|
||||
|
||||
this.showConfirmationDialog({
|
||||
title: title,
|
||||
message: message,
|
||||
confirmText: 'Deploy',
|
||||
cancelText: 'Cancel',
|
||||
onConfirm: () => this.performDeployment(file, targetType, specificNode),
|
||||
onCancel: () => {}
|
||||
});
|
||||
}
|
||||
|
||||
async performDeployment(file, targetType, specificNode) {
|
||||
try {
|
||||
this.viewModel.startUpload();
|
||||
|
||||
@@ -185,7 +263,14 @@ class FirmwareComponent extends Component {
|
||||
|
||||
} catch (error) {
|
||||
logger.error('Firmware deployment failed:', error);
|
||||
alert(`Deployment failed: ${error.message}`);
|
||||
this.showConfirmationDialog({
|
||||
title: 'Deployment Failed',
|
||||
message: `Deployment failed: ${error.message}`,
|
||||
confirmText: 'OK',
|
||||
cancelText: null,
|
||||
onConfirm: () => {},
|
||||
onCancel: null
|
||||
});
|
||||
} finally {
|
||||
this.viewModel.completeUpload();
|
||||
}
|
||||
@@ -198,13 +283,17 @@ class FirmwareComponent extends Component {
|
||||
const nodes = response.members || [];
|
||||
|
||||
if (nodes.length === 0) {
|
||||
alert('No nodes available for firmware update.');
|
||||
this.showConfirmationDialog({
|
||||
title: 'No Nodes Available',
|
||||
message: 'No nodes available for firmware update.',
|
||||
confirmText: 'OK',
|
||||
cancelText: null,
|
||||
onConfirm: () => {},
|
||||
onCancel: null
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmed = confirm(`Upload firmware to all ${nodes.length} nodes? This will update: ${nodes.map(n => n.hostname || n.ip).join(', ')}`);
|
||||
if (!confirmed) return;
|
||||
|
||||
// Show upload progress area
|
||||
this.showUploadProgress(file, nodes);
|
||||
|
||||
@@ -222,9 +311,6 @@ class FirmwareComponent extends Component {
|
||||
|
||||
async uploadToSpecificNode(file, nodeIp) {
|
||||
try {
|
||||
const confirmed = confirm(`Upload firmware to node ${nodeIp}?`);
|
||||
if (!confirmed) return;
|
||||
|
||||
// Show upload progress area
|
||||
this.showUploadProgress(file, [{ ip: nodeIp, hostname: nodeIp }]);
|
||||
|
||||
@@ -266,12 +352,16 @@ class FirmwareComponent extends Component {
|
||||
try {
|
||||
const nodes = this.viewModel.getAffectedNodesByLabels();
|
||||
if (!nodes || nodes.length === 0) {
|
||||
alert('No nodes match the selected labels.');
|
||||
this.showConfirmationDialog({
|
||||
title: 'No Matching Nodes',
|
||||
message: 'No nodes match the selected labels.',
|
||||
confirmText: 'OK',
|
||||
cancelText: null,
|
||||
onConfirm: () => {},
|
||||
onCancel: null
|
||||
});
|
||||
return;
|
||||
}
|
||||
const labels = this.viewModel.get('selectedLabels') || [];
|
||||
const confirmed = confirm(`Upload firmware to ${nodes.length} node(s) matching labels (${labels.join(', ')})?`);
|
||||
if (!confirmed) return;
|
||||
|
||||
// Show upload progress area
|
||||
this.showUploadProgress(file, nodes);
|
||||
|
||||
Reference in New Issue
Block a user