Fix protocol discovery modal integration and timing issues

- Add robust modal opening with multiple fallback methods
- Implement proper timing waits for modal and dropdown loading
- Add comprehensive logging for debugging
- Fix field population sequence and validation
- Add waitForStationsLoaded method to handle async dropdown loading
- Ensure all form fields are properly populated including mapping_id
- Set default database source based on device name

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
openhands 2025-11-08 13:23:18 +00:00
parent 87cc40a802
commit 04404674ee
1 changed files with 170 additions and 37 deletions

View File

@ -398,59 +398,159 @@ class ProtocolDiscovery {
* Auto-populate the protocol mapping form with endpoint data
*/
autoPopulateProtocolForm(formData) {
console.log('Auto-populating protocol form with:', formData);
// First, open the "Add New Mapping" modal
this.openAddMappingModal();
// Wait a moment for the modal to open, then populate fields
// Wait for modal to be fully loaded and visible
const waitForModal = setInterval(() => {
const modal = document.getElementById('mapping-modal');
const isModalVisible = modal && modal.style.display !== 'none';
if (isModalVisible) {
clearInterval(waitForModal);
this.populateModalFields(formData);
}
}, 50);
// Timeout after 2 seconds
setTimeout(() => {
clearInterval(waitForModal);
const modal = document.getElementById('mapping-modal');
if (modal && modal.style.display !== 'none') {
this.populateModalFields(formData);
} else {
console.error('Modal did not open within timeout period');
this.showNotification('Could not open protocol mapping form. Please try opening it manually.', 'error');
}
}, 2000);
}
/**
* Populate modal fields with discovery data
*/
populateModalFields(formData) {
console.log('Populating modal fields with:', formData);
// Find and populate form fields in the modal
const mappingIdField = document.getElementById('mapping_id');
const protocolTypeField = document.getElementById('protocol_type');
const protocolAddressField = document.getElementById('protocol_address');
const stationIdField = document.getElementById('station_id');
const equipmentIdField = document.getElementById('equipment_id');
const dataTypeIdField = document.getElementById('data_type_id');
const dbSourceField = document.getElementById('db_source');
if (protocolTypeField) protocolTypeField.value = formData.protocol_type;
if (protocolAddressField) protocolAddressField.value = formData.protocol_address;
console.log('Found fields:', {
mappingIdField: !!mappingIdField,
protocolTypeField: !!protocolTypeField,
protocolAddressField: !!protocolAddressField,
stationIdField: !!stationIdField,
equipmentIdField: !!equipmentIdField,
dataTypeIdField: !!dataTypeIdField,
dbSourceField: !!dbSourceField
});
// Set station, equipment, and data type if they exist in our metadata
if (stationIdField && this.isValidStationId(formData.station_id)) {
stationIdField.value = formData.station_id;
// Trigger equipment dropdown update
stationIdField.dispatchEvent(new Event('change'));
// Populate mapping ID
if (mappingIdField) {
mappingIdField.value = formData.mapping_id;
console.log('Set mapping_id to:', formData.mapping_id);
}
// Populate protocol type
if (protocolTypeField) {
protocolTypeField.value = formData.protocol_type;
console.log('Set protocol_type to:', formData.protocol_type);
// Trigger protocol field updates
protocolTypeField.dispatchEvent(new Event('change'));
}
// Populate protocol address
if (protocolAddressField) {
protocolAddressField.value = formData.protocol_address;
console.log('Set protocol_address to:', formData.protocol_address);
}
// Set station, equipment, and data type if they exist in our metadata
if (stationIdField) {
// Wait for stations to be loaded if needed
this.waitForStationsLoaded(() => {
if (this.isValidStationId(formData.station_id)) {
stationIdField.value = formData.station_id;
console.log('Set station_id to:', formData.station_id);
// Trigger equipment dropdown update
stationIdField.dispatchEvent(new Event('change'));
// Wait for equipment to be loaded
setTimeout(() => {
if (equipmentIdField && this.isValidEquipmentId(formData.equipment_id)) {
equipmentIdField.value = formData.equipment_id;
console.log('Set equipment_id to:', formData.equipment_id);
}
if (dataTypeIdField && this.isValidDataTypeId(formData.data_type_id)) {
dataTypeIdField.value = formData.data_type_id;
console.log('Set data_type_id to:', formData.data_type_id);
}
// Set default database source
if (dbSourceField && !dbSourceField.value) {
dbSourceField.value = 'measurements.' + formData.device_name.toLowerCase().replace(/[^a-z0-9]/g, '_');
}
// Show success message
this.showNotification(`Protocol form populated with ${formData.device_name}. Please review and complete any missing information.`, 'success');
}, 100);
}
});
}
}
/**
* Open the "Add New Mapping" modal
*/
openAddMappingModal() {
// Look for the showAddMappingModal function or button click
console.log('Attempting to open Add New Mapping modal...');
// First try to use the global function
if (typeof showAddMappingModal === 'function') {
console.log('Using showAddMappingModal function');
showAddMappingModal();
} else {
return;
}
// Try to find and click the "Add New Mapping" button
const addButton = document.querySelector('button[onclick*="showAddMappingModal"]');
if (addButton) {
console.log('Found Add New Mapping button, clicking it');
addButton.click();
} else {
return;
}
// Try to find any button that might open the modal
const buttons = document.querySelectorAll('button');
for (let button of buttons) {
const text = button.textContent.toLowerCase();
if (text.includes('add') && text.includes('mapping')) {
console.log('Found Add Mapping button by text, clicking it');
button.click();
return;
}
}
// Last resort: try to show the modal directly
const modal = document.getElementById('mapping-modal');
if (modal) {
console.log('Found mapping-modal, showing it directly');
modal.style.display = 'block';
return;
}
console.error('Could not find any way to open the protocol mapping modal');
// Fallback: show a message to manually open the modal
this.showNotification('Please click "Add New Mapping" to create a protocol mapping with the discovered endpoint data.', 'info');
}
}
}
/**
* Get default protocol address based on endpoint type
@ -620,6 +720,39 @@ class ProtocolDiscovery {
if (!dataTypeSelect) return false;
return Array.from(dataTypeSelect.options).some(option => option.value === dataTypeId);
}
/**
* Wait for stations to be loaded in the dropdown
*/
waitForStationsLoaded(callback, maxWait = 3000) {
const stationSelect = document.getElementById('station_id');
if (!stationSelect) {
console.error('Station select element not found');
callback();
return;
}
// Check if stations are already loaded (more than just "Select Station")
if (stationSelect.options.length > 1) {
console.log('Stations already loaded:', stationSelect.options.length);
callback();
return;
}
// Wait for stations to load
const startTime = Date.now();
const checkInterval = setInterval(() => {
if (stationSelect.options.length > 1) {
console.log('Stations loaded after wait:', stationSelect.options.length);
clearInterval(checkInterval);
callback();
} else if (Date.now() - startTime > maxWait) {
console.warn('Timeout waiting for stations to load');
clearInterval(checkInterval);
callback();
}
}, 100);
}
}
// Initialize discovery when DOM is loaded