adjusted html to new standard

This commit is contained in:
2025-10-13 10:06:08 +02:00
parent a061873537
commit 4213b18139
3 changed files with 905 additions and 950 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,18 +1,13 @@
<script type="module"> <!-- Load the dynamic menu & config endpoints -->
import * as menuUtils from "/generalFunctions/helper/menuUtils.js"; <script src="/monster/menu.js"></script>
<script src="/monster/configData.js"></script>
RED.nodes.registerType('monster', {
category: 'wbd typical',
color: '#4f8582',
<script>
RED.nodes.registerType("monster", {
category: "EVOLV",
color: "#4f8582",
defaults: { defaults: {
// Define default properties
name: { value: "", required: true },
enableLog: { value: false },
logLevel: { value: "error" },
// Define specific properties // Define specific properties
samplingtime: { value: 0 }, samplingtime: { value: 0 },
minvolume: { value: 5 }, minvolume: { value: 5 },
@@ -21,249 +16,128 @@ RED.nodes.registerType('monster', {
aquon_sample_name: { value: "" }, aquon_sample_name: { value: "" },
//define asset properties //define asset properties
uuid: { value: "" },
supplier: { value: "" }, supplier: { value: "" },
subType: { value: "" }, category: { value: "" },
assetType: { value: "" },
model: { value: "" }, model: { value: "" },
unit: { value: "" }, unit: { value: "" },
//logger properties
enableLog: { value: false },
logLevel: { value: "error" },
//physicalAspect
positionVsParent: { value: "" },
positionIcon: { value: "" },
hasDistance: { value: false },
distance: { value: 0 },
distanceUnit: { value: "m" },
distanceDescription: { value: "" }
}, },
inputs: 1, inputs: 1,
outputs: 4, outputs: 3,
inputLabels: ["Measurement Input"], inputLabels: ["Input"],
outputLabels: ["process", "dbase", "upstreamParent", "downstreamParent"], outputLabels: ["process", "dbase", "parent"],
icon: "font-awesome/fa-bath", icon: "font-awesome/fa-tachometer",
// Define label function
label: function () { label: function () {
return this.name || "Monsternamekast"; return this.positionIcon + " " + this.category.slice(0, -1) || "Monster";
}, },
oneditprepare: function() { oneditprepare: function() {
const node = this; // wait for the menu scripts to load
const waitForMenuData = () => {
// Define UI html elements if (window.EVOLV?.nodes?.monster?.initEditor) {
const elements = { window.EVOLV.nodes.monster.initEditor(this);
// Basic fields } else {
name: document.getElementById("node-input-name"), setTimeout(waitForMenuData, 50);
// specific fields
samplingtime: document.getElementById("node-input-samplingtime"),
minvolume: document.getElementById("node-input-minvolume"),
maxweight: document.getElementById("node-input-maxweight"),
emptyWeightBucket: document.getElementById("node-input-emptyWeightBucket"),
aquon_sample_name: document.getElementById("node-input-aquon_sample_name"),
// Logging fields
logCheckbox: document.getElementById("node-input-enableLog"),
logLevelSelect: document.getElementById("node-input-logLevel"),
rowLogLevel: document.getElementById("row-logLevel"),
// Asset fields
supplier: document.getElementById("node-input-supplier"),
subType: document.getElementById("node-input-subType"),
model: document.getElementById("node-input-model"),
unit: document.getElementById("node-input-unit"),
};
//this needs to live somewhere and for now we add it to every node file for simplicity
const projecSettingstURL = "http://localhost:1880/generalFunctions/settings/projectSettings.json";
try{
// Fetch project settings
menuUtils.fetchProjectData(projecSettingstURL)
.then((projectSettings) => {
//assign to node vars
node.configUrls = projectSettings.configUrls;
const { cloudConfigURL, localConfigURL } = menuUtils.getSpecificConfigUrl("monster",node.configUrls.cloud.taggcodeAPI);
node.configUrls.cloud.config = cloudConfigURL; // first call
node.configUrls.local.config = localConfigURL; // backup call
node.locationId = projectSettings.locationId;
node.uuid = projectSettings.uuid;
// Gets the ID of the active workspace (Flow)
const activeFlowId = RED.workspaces.active(); //fetches active flow id
node.processId = activeFlowId;
// UI elements across all nodes
menuUtils.fetchAndPopulateDropdowns(node.configUrls, elements, node); // function for all assets
menuUtils.initBasicToggles(elements);
})
}catch(e){
console.log("Error fetching project settings", e);
} }
};
waitForMenuData();
// your existing projectsettings & asset dropdown logic can remain here
document.getElementById("node-input-samplingtime");
document.getElementById("node-input-minvolume");
document.getElementById("node-input-maxweight");
document.getElementById("node-input-emptyWeightBucket");
document.getElementById("node-input-aquon_sample_name");
}, },
oneditsave: function() { oneditsave: function() {
const node = this; const node = this;
console.log(`------------ Saving changes to node ------------`); // save asset fields
console.log(`${node.uuid}`); if (window.EVOLV?.nodes?.monster?.assetMenu?.saveEditor) {
window.EVOLV.nodes.monster.assetMenu.saveEditor(this);
// Save basic properties }
[ "name", "supplier", "subType", "model" ,"unit" ].forEach( // save logger fields
(field) => (node[field] = document.getElementById(`node-input-${field}`).value || "") if (window.EVOLV?.nodes?.monster?.loggerMenu?.saveEditor) {
); window.EVOLV.nodes.monster.loggerMenu.saveEditor(this);
}
// Save numeric and boolean properties // save position field
["enableLog"].forEach( if (window.EVOLV?.nodes?.monster?.positionMenu?.saveEditor) {
(field) => (node[field] = document.getElementById(`node-input-${field}`).checked) window.EVOLV.nodes.monster.positionMenu.saveEditor(this);
);
["samplingtime","minvolume","maxweight","emptyWeightBucket","aquon_sample_name"].forEach(
(field) => (node[field] = parseFloat(document.getElementById(`node-input-${field}`).value) || 0)
);
node.logLevel = document.getElementById("node-input-logLevel").value || "info";
// 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");
}
if (node.subType && !node.unit) {
RED.notify("Unit must be set when specifying a subtype.", "error");
}
console.log("stored node modelData", node.modelMetadata);
console.log("------------ Changes saved to measurement node preparing to save to API ------------");
try{
// Fetch project settings
menuUtils.apiCall(node,node.configUrls)
.then((response) => {
//save response to node information
node.assetId = response.asset_id;
node.assetTagCode = response.asset_tag_number;
})
.catch((error) => {
console.log("Error during API call", error);
});
}catch(e){
console.log("Error saving assetID and tagnumber", e);
}
} }
["samplingtime", "minvolume", "maxweight", "emptyWeightBucket"].forEach((field) => {
const element = document.getElementById(`node-input-${field}`);
const value = parseFloat(element?.value) || 0;
console.log(`----------------> Saving ${field}: ${value}`);
node[field] = value;
}); });
["aquon_sample_name"].forEach((field) => {
const element = document.getElementById(`node-input-${field}`);
const value = element?.value || "";
console.log(`----------------> Saving ${field}: ${value}`);
node[field] = value;
});
}
});
</script> </script>
<!-- Main UI --> <!-- Main UI Template -->
<script type="text/html" data-template-name="monster"> <script type="text/html" data-template-name="monster">
<!-------------------------------------------INPUT NAME / TYPE -----------------------------------------------> <!-- speficic input -->
<!-- Node Name -->
<div class="form-row"> <div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> <label for="node-input-samplingtime"><i class="fa fa-clock-o"></i> Sampling time (h)</label>
<input type="text" id="node-input-name" placeholder="Measurement Name"> <input type="number" id="node-input-samplingtime" style="width:60%;" />
</div>
<div class="form-row">
<label for="node-input-minvolume"><i class="fa fa-clock-o"></i> Min volume (L)</label>
<input type="number" id="node-input-minvolume" style="width:60%;" />
</div>
<div class="form-row">
<label for="node-input-maxweight"><i class="fa fa-clock-o"></i> Max weight (kg)</label>
<input type="number" id="node-input-maxweight" style="width:60%;" />
</div>
<div class="form-row">
<label for="node-input-emptyWeightBucket"><i class="fa fa-clock-o"></i> Empty weight of bucket (kg)</label>
<input type="number" id="node-input-emptyWeightBucket" style="width:60%;" />
</div>
<div class="form-row">
<label for="node-input-aquon_sample_name"><i class="fa fa-clock-o"></i> Aquon sample name</label>
<input type="text" id="node-input-aquon_sample_name" style="width:60%;" />
</div> </div>
<!-- Sampling Time --> <!-- Asset fields injected here -->
<div class="form-row"> <div id="asset-fields-placeholder"></div>
<label for="node-input-samplingtime"><i class="fa fa-clock-o"></i> Sampling Time (hours)</label>
<input type="number" id="node-input-samplingtime" placeholder="Enter sampling time in hours" min="0" required>
</div>
<!-- Minimum Volume --> <!-- Logger fields injected here -->
<div class="form-row"> <div id="logger-fields-placeholder"></div>
<label for="node-input-minvolume"><i class="fa fa-tint"></i> Minimum Volume (liters)</label>
<input type="number" id="node-input-minvolume" placeholder="Enter minimum volume in liters" min="0" required>
</div>
<!-- Maximum Weight --> <!-- Position fields injected here -->
<div class="form-row"> <div id="position-fields-placeholder"></div>
<label for="node-input-maxweight"><i class="fa fa-balance-scale"></i> Maximum Weight (kg)</label>
<input type="number" id="node-input-maxweight" placeholder="Enter maximum weight in kg" min="0" required>
</div>
<!-- Empty Bucket Weight -->
<div class="form-row">
<label for="node-input-emptyWeightBucket"><i class="fa fa-bucket"></i> Empty Bucket Weight (kg)</label>
<input type="number" id="node-input-emptyWeightBucket" placeholder="Enter empty bucket weight in kg" min="0" required>
</div>
<!-- Aquon Sample Name -->
<div class="form-row">
<label for="node-input-aquon_sample_name"><i class="fa fa-flask"></i> Aquon Sample Name</label>
<input type="text" id="node-input-aquon_sample_name" placeholder="Enter Aquon sample name">
</div>
<!-- Optional Extended Fields: supplier, type, subType, model -->
<hr />
<div class="form-row">
<label for="node-input-supplier"
><i class="fa fa-industry"></i> Supplier</label>
<select id="node-input-supplier" style="width:60%;">
<option value="">(optional)</option>
</select>
</div>
<div class="form-row">
<label for="node-input-subType"
><i class="fa fa-puzzle-piece"></i> SubType</label>
<select id="node-input-subType" style="width:60%;">
<option value="">(optional)</option>
</select>
</div>
<div class="form-row">
<label for="node-input-model"><i class="fa fa-wrench"></i> Model</label>
<select id="node-input-model" style="width:60%;">
<option value="">(optional)</option>
</select>
</div>
<div class="form-row">
<label for="node-input-unit"><i class="fa fa-balance-scale"></i> Unit</label>
<select id="node-input-unit" style="width:60%;"></select>
</div>
<hr />
<!-- loglevel checkbox -->
<div class="form-row">
<label for="node-input-enableLog"
><i class="fa fa-cog"></i> Enable Log</label>
<input
type="checkbox"
id="node-input-enableLog"
style="width:20px; vertical-align:baseline;"
/>
<span>Enable logging</span>
</div>
<div class="form-row" id="row-logLevel">
<label for="node-input-logLevel"><i class="fa fa-cog"></i> Log Level</label>
<select id="node-input-logLevel" style="width:60%;">
<option value="info">Info</option>
<option value="debug">Debug</option>
<option value="warn">Warn</option>
<option value="error">Error</option>
</select>
</div>
</script> </script>
<script type="text/html" data-help-name="monster"> <script type="text/html" data-help-name="monster">
<p><b>Monster Node</b>: Configures and manages monster measurement data.</p> <p><b>Monster node</b>: Configure a monster asset.</p>
<p>Use this node to configure and manage monster measurement data. The node can be configured to handle various measurement parameters and asset properties.</p> <ul>
<li><b>Supplier:</b> Select a supplier to populate machine options.</li>
<li><b>SubType:</b> Select a subtype if applicable to further categorize the asset.</li> </ul>
<li><b>Model:</b> Define the specific model for more granular asset configuration.</li>
<li><b>Unit:</b> Assign a unit to standardize measurements or operations.</li>
<li><b>Sampling Time:</b> Define the sampling time in hours for measurements.</li>
<li><b>Minimum Volume:</b> Specify the minimum volume in liters.</li>
<li><b>Maximum Weight:</b> Specify the maximum weight in kilograms.</li>
<li><b>Empty Bucket Weight:</b> Define the weight of the empty bucket in kilograms.</li>
<li><b>Aquon Sample Name:</b> Provide the name for the Aquon sample.</li>
<li><b>Enable Log:</b> Enable or disable logging for this node.</li>
<li><b>Log Level:</b> Select the log level (Info, Debug, Warn, Error) for logging messages.</li>
</script> </script>