diff --git a/measurement.html b/measurement.html index 5026783..b2f1ce2 100644 --- a/measurement.html +++ b/measurement.html @@ -51,21 +51,54 @@ setTimeout(waitForMenuData, 50); } }; + // Wait for the menu data to be ready before initializing the editor waitForMenuData(); + + // --------------- Initialize the dropdowns and other specific UI elements -------------- this should be derived from the config in the future (make config based menu) + // Populate smoothing methods dropdown + const smoothMethodSelect = document.getElementById('node-input-smooth_method'); + const options = window.EVOLV?.nodes?.measurement?.config?.smoothing?.smoothMethod?.rules?.values || []; + console.log("Smoothing methods options:", options); + // Clear existing options + smoothMethodSelect.innerHTML = ''; + + // Add empty option + const emptyOption = document.createElement('option'); + emptyOption.value = ''; + emptyOption.textContent = 'Select method...'; + smoothMethodSelect.appendChild(emptyOption); + + // Add smoothing method options + options.forEach(option => { + const optionElement = document.createElement('option'); + optionElement.value = option.value; + optionElement.textContent = option.value; + optionElement.title = option.description; // Add tooltip with full description + smoothMethodSelect.appendChild(optionElement); + }); + + // Set current value if it exists + if (this.smooth_method) { + smoothMethodSelect.value = this.smooth_method; + } + + //------------------- END OF CUSTOM config UI ELEMENTS ------------------- // }, oneditsave: function () { const node = this; - - console.log(`------------ Saving changes to node ------------`); - console.log(`${node.uuid}`); + + // Validate asset properties using the asset menu + if (window.EVOLV?.nodes?.measurement?.assetMenu?.saveEditor) { + success = window.EVOLV.nodes.measurement.assetMenu.saveEditor(this); + } // Save basic properties - ["name", "supplier", "category", "assetType", "model", "unit", "smooth_method"].forEach( + ["name", "smooth_method"].forEach( (field) => (node[field] = document.getElementById(`node-input-${field}`).value || "") ); // Save numeric and boolean properties - ["scaling", "enableLog", "simulator"].forEach( + ["scaling", "simulator"].forEach( (field) => (node[field] = document.getElementById(`node-input-${field}`).checked) ); @@ -74,23 +107,15 @@ ); node.logLevel = document.getElementById("node-input-logLevel").value || "info"; + node.enableLog = document.getElementById("node-input-enableLog").checked; // Validation checks if (node.scaling && (isNaN(node.i_min) || isNaN(node.i_max))) { RED.notify("Scaling enabled, but input range is incomplete!", "error"); } - if (!node.unit) { - RED.notify("Unit selection is required.", "error"); - } - // Validation checks - FIXED - if (node.assetType && !node.unit) { - RED.notify("Unit must be set when specifying a type.", "error"); - } - console.log("stored node modelData", node.modelMetadata); - console.log("------------ Changes saved to measurement node preparing to save to API ------------"); }, }); diff --git a/src/nodeClass.js b/src/nodeClass.js index b5fc689..819065b 100644 --- a/src/nodeClass.js +++ b/src/nodeClass.js @@ -1,7 +1,8 @@ /** * measurement.class.js * - * Encapsulates all Measurement node logic in a reusable class. + * Encapsulates all node logic in a reusable class. In future updates we can split this into multiple generic classes and use the config to specifiy which ones to use. + * This allows us to keep the Node-RED node clean and focused on wiring up the UI and event handlers. */ const { outputUtils, configManager } = require('generalFunctions'); const Measurement = require("../dependencies/measurement/measurement"); @@ -12,17 +13,17 @@ const Measurement = require("../dependencies/measurement/measurement"); class MeasurementNode { /** * Create a MeasurementNode. - * @param {object} config - Node-RED node configuration. + * @param {object} uiConfig - Node-RED node configuration. * @param {object} RED - Node-RED runtime API. */ - constructor(config, RED, nodeInstance) { + constructor(uiConfig, RED, nodeInstance) { // Preserve RED reference for HTTP endpoints if needed this.node = nodeInstance; this.RED = RED; // Load default & UI config - this._loadConfig(config); + this._loadConfig(uiConfig); // Instantiate core Measurement class this._setupMeasurementClass(); @@ -57,8 +58,10 @@ class MeasurementNode { asset: { tagCode: uiConfig.assetTagCode, supplier: uiConfig.supplier, - subType: uiConfig.subType, - model: uiConfig.model + category: uiConfig.category, + type: uiConfig.assetType, + model: uiConfig.model, + unit: uiConfig.unit }, scaling: { enabled: uiConfig.scaling, @@ -89,7 +92,7 @@ class MeasurementNode { } /** - * Bind Measurement events to Node-RED status updates. + * Bind Measurement events to Node-RED status updates. Using internal emitter. */ _bindEvents() { this.source.emitter.on('mAbs', (val) => {