import { loadDeviceConfig, loadProtocolConfig, saveDeviceConfig, saveProtocolConfig } from './api.js'; import { createNavigation } from './navigation.js'; import { createDeviceDataController } from './device/deviceData.js'; import { bindDeviceFileActions, bindProtocolFileActions } from './device/deviceFile.js'; import { createSsidController } from './device/ssid.js'; import { createCanController } from './protocol/can.js'; import { createModbusController } from './protocol/modbus.js'; import { createOdometerController } from './protocol/odometer.js'; import { createOpcUaController } from './protocol/opcua.js'; import { createProtocolDataController } from './protocol/protocolData.js'; import { getRegisterConfigValidationError, isValidRegisterConfig } from './protocol/protocolValidation.js'; import { byId, queryAll } from './utils/dom.js'; function notifyLoadFailure(target, error) { const statusMatch = /Request failed: (\d+)/.exec(String(error?.message ?? '')); const statusText = statusMatch ? ` (HTTP ${statusMatch[1]})` : ''; const message = `${target} settings could not be loaded${statusText}. Please check the saved data on the backend.`; console.error(message, error); alert(message); } function isLegacySuccessMessage(data) { return String(data?.message ?? '').trim().toLowerCase() === 'success'; } function isLegacyProtocolPayload(data) { if (!data || typeof data !== 'object' || Array.isArray(data)) { return false; } return [ 'protocol', 'dev_type', 'can_input', 'dr_on', 'odo_on', 'MEID', 'MODBUS', 'OPC_UA', 'CAN', ].some((key) => Object.prototype.hasOwnProperty.call(data, key)); } function isSaveSuccessful(type, response) { if (!response.ok) { return false; } if (response.data?.success === true) { return true; } if (type === 'device' && isLegacySuccessMessage(response.data)) { return true; } if (type === 'protocol' && isLegacyProtocolPayload(response.data)) { return true; } return false; } async function initializeApp() { const navigation = createNavigation(); const ssidController = createSsidController({ listElement: byId('ssid-list'), templateElement: byId('ssid-template'), addButton: byId('add-ssid'), countryCodeInput: byId('wifi_country_code'), }); const deviceController = createDeviceDataController({ ssidController }); const protocolController = createProtocolDataController({ navigation, modbusController: createModbusController(), opcUaController: createOpcUaController(), canController: createCanController(), odometerController: createOdometerController(), }); navigation.initialize(); ssidController.bindEvents(); deviceController.initialize(); protocolController.initialize(); bindDeviceFileActions({ onLoadLocal: (data) => deviceController.loadFromData(data), getDownloadData: () => deviceController.collectDeviceData(), }); bindProtocolFileActions({ onLoadLocal: (data) => { const validationError = getRegisterConfigValidationError(data); if (validationError) { alert(`The contents of the selected file are not valid.\n${validationError}`); return; } protocolController.loadFromRegisterJson(data); }, getDownloadData: () => protocolController.normalizeRegisterForPost( protocolController.collectProtocolData(), ), }); queryAll('.save-file').forEach((button) => { button.addEventListener('click', async () => { const devicePayload = deviceController.collectDeviceData(); const protocolPayload = protocolController.normalizeRegisterForPost( protocolController.collectProtocolData(), ); const validationError = getRegisterConfigValidationError(protocolPayload); if (validationError) { alert(`Register settings are currently invalid.\n${validationError}`); return; } try { const [deviceResponse, protocolResponse] = await Promise.all([ saveDeviceConfig(devicePayload), saveProtocolConfig(protocolPayload), ]); const isDeviceSaved = isSaveSuccessful('device', deviceResponse); const isProtocolSaved = isSaveSuccessful('protocol', protocolResponse); if (isDeviceSaved && isProtocolSaved) { alert('saved successfully'); return; } const failureMessages = [ !isDeviceSaved ? (deviceResponse.data?.message || `Device save failed (${deviceResponse.status})`) : null, !isProtocolSaved ? (protocolResponse.data?.message || `Protocol save failed (${protocolResponse.status})`) : null, ].filter(Boolean); alert(failureMessages.join('\n') || 'save failure'); console.error('device response:', deviceResponse, 'protocol response:', protocolResponse); } catch (error) { console.error('Error during transfer:', error); alert('save failure'); } }); }); try { const deviceData = await loadDeviceConfig(); if (deviceData) { deviceController.loadFromData(deviceData); } else { deviceController.loadDefaults(); } } catch (error) { notifyLoadFailure('Device', error); } try { const protocolData = await loadProtocolConfig(); if (protocolData) { protocolController.loadFromRegisterJson(protocolData); } } catch (error) { notifyLoadFailure('Protocol', error); } } document.addEventListener('DOMContentLoaded', initializeApp);