`;
}
setupFirmwareItemListeners() {
// Version item clicks (for editing)
const versionItems = this.findAllElements('.firmware-version-item.clickable');
versionItems.forEach(item => {
this.addEventListener(item, 'click', (e) => {
// Don't trigger if clicking on action buttons
if (e.target.closest('.firmware-version-actions')) {
return;
}
const name = item.getAttribute('data-name');
const version = item.getAttribute('data-version');
this.showEditFirmwareForm(name, version);
});
});
// Download buttons
const downloadBtns = this.findAllElements('.download-btn');
downloadBtns.forEach(btn => {
this.addEventListener(btn, 'click', (e) => {
e.stopPropagation();
const name = btn.getAttribute('data-name');
const version = btn.getAttribute('data-version');
this.downloadFirmware(name, version);
});
});
// Delete buttons
const deleteBtns = this.findAllElements('.delete-btn');
deleteBtns.forEach(btn => {
this.addEventListener(btn, 'click', (e) => {
e.stopPropagation();
const name = btn.getAttribute('data-name');
const version = btn.getAttribute('data-version');
this.showDeleteConfirmation(name, version);
});
});
}
showAddFirmwareForm() {
this.openFirmwareForm('Add Firmware', null, null);
}
showEditFirmwareForm(name, version) {
const groupedFirmware = this.viewModel.get('firmwareList') || [];
// Find the firmware in the grouped data
let firmware = null;
for (const group of groupedFirmware) {
if (group.name === name) {
firmware = group.firmware.find(f => f.version === version);
if (firmware) break;
}
}
if (firmware) {
this.openFirmwareForm('Edit Firmware', firmware, null);
}
}
openFirmwareForm(title, firmwareData, onCloseCallback) {
this.drawer.openDrawer(title, (contentContainer, setActiveComponent) => {
const formComponent = new FirmwareFormComponent(contentContainer, this.viewModel, this.eventBus);
setActiveComponent(formComponent);
formComponent.setFirmwareData(firmwareData);
formComponent.setOnSaveCallback(() => {
this.loadFirmwareList();
this.drawer.closeDrawer();
});
formComponent.setOnCancelCallback(() => {
this.drawer.closeDrawer();
});
formComponent.mount();
}, null, onCloseCallback, true); // Hide terminal button
}
async downloadFirmware(name, version) {
try {
const blob = await window.apiClient.downloadFirmwareFromRegistry(name, version);
// Create download link
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${name}-${version}.bin`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
this.showSuccess(`Firmware ${name} v${version} downloaded successfully`);
} catch (error) {
logger.error('Download failed:', error);
this.showError('Download failed: ' + error.message);
}
}
showDeleteConfirmation(name, version) {
this.showConfirmationDialog({
title: 'Delete Firmware',
message: `Are you sure you want to delete firmware "${name}" version "${version}"?
This action cannot be undone.`,
confirmText: 'Delete',
cancelText: 'Cancel',
onConfirm: () => this.deleteFirmware(name, version),
onCancel: () => {}
});
}
async deleteFirmware(name, version) {
try {
// Note: The registry API doesn't have a delete endpoint in the OpenAPI spec
// This would need to be implemented in the registry service
this.showError('Delete functionality not yet implemented in registry API');
} catch (error) {
logger.error('Delete failed:', error);
this.showError('Delete failed: ' + error.message);
}
}
handleSearch(event) {
const query = event.target.value;
this.viewModel.set('searchQuery', query);
}
updateSearchResults() {
// This method is called when searchQuery property changes
// The actual filtering is handled in renderFirmwareList
this.renderFirmwareList();
}
updateLoadingState() {
const isLoading = this.viewModel.get('isLoading');
const container = this.findElement('#firmware-list-container');
if (isLoading && container) {
container.innerHTML = `