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,269 +1,143 @@
<script type="module">
import * as menuUtils from "/generalFunctions/helper/menuUtils.js";
<!-- Load the dynamic menu & config endpoints -->
<script src="/monster/menu.js"></script>
<script src="/monster/configData.js"></script>
RED.nodes.registerType('monster', {
category: 'wbd typical',
color: '#4f8582',
defaults: {
<script>
RED.nodes.registerType("monster", {
category: "EVOLV",
color: "#4f8582",
defaults: {
// Define default properties
name: { value: "", required: true },
enableLog: { value: false },
logLevel: { value: "error" },
// Define specific properties
samplingtime: { value: 0 },
minvolume: { value: 5 },
maxweight: { value: 22 },
emptyWeightBucket: { value: 3 },
aquon_sample_name: { value: "" },
// Define specific properties
samplingtime: { value: 0 },
minvolume: { value: 5 },
maxweight: { value: 22 },
emptyWeightBucket: { value: 3 },
aquon_sample_name: { value: "" },
//define asset properties
uuid: { value: "" },
supplier: { value: "" },
category: { value: "" },
assetType: { value: "" },
model: { value: "" },
unit: { value: "" },
//define asset properties
supplier: { value: "" },
subType: { value: "" },
model: { 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,
outputs: 4,
inputLabels: ["Measurement Input"],
outputLabels: ["process", "dbase", "upstreamParent", "downstreamParent"],
icon: "font-awesome/fa-bath",
outputs: 3,
inputLabels: ["Input"],
outputLabels: ["process", "dbase", "parent"],
icon: "font-awesome/fa-tachometer",
// Define label function
label: function() {
return this.name || "Monsternamekast";
label: function () {
return this.positionIcon + " " + this.category.slice(0, -1) || "Monster";
},
oneditprepare: function() {
const node = this;
// wait for the menu scripts to load
const waitForMenuData = () => {
if (window.EVOLV?.nodes?.monster?.initEditor) {
window.EVOLV.nodes.monster.initEditor(this);
} else {
setTimeout(waitForMenuData, 50);
}
};
waitForMenuData();
// Define UI html elements
const elements = {
// Basic fields
name: document.getElementById("node-input-name"),
// 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);
}
// 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() {
const node = this;
console.log(`------------ Saving changes to node ------------`);
console.log(`${node.uuid}`);
const node = this;
// Save basic properties
[ "name", "supplier", "subType", "model" ,"unit" ].forEach(
(field) => (node[field] = document.getElementById(`node-input-${field}`).value || "")
);
// Save numeric and boolean properties
["enableLog"].forEach(
(field) => (node[field] = document.getElementById(`node-input-${field}`).checked)
);
["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");
// save asset fields
if (window.EVOLV?.nodes?.monster?.assetMenu?.saveEditor) {
window.EVOLV.nodes.monster.assetMenu.saveEditor(this);
}
// save logger fields
if (window.EVOLV?.nodes?.monster?.loggerMenu?.saveEditor) {
window.EVOLV.nodes.monster.loggerMenu.saveEditor(this);
}
// save position field
if (window.EVOLV?.nodes?.monster?.positionMenu?.saveEditor) {
window.EVOLV.nodes.monster.positionMenu.saveEditor(this);
}
if (!node.unit) {
RED.notify("Unit selection is required.", "error");
}
["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;
});
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);
}
["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>
<!-- Main UI -->
<!-- Main UI Template -->
<script type="text/html" data-template-name="monster">
<!-------------------------------------------INPUT NAME / TYPE ----------------------------------------------->
<!-- Node Name -->
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Measurement Name">
</div>
<!-- Sampling Time -->
<!-- speficic input -->
<div class="form-row">
<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>
<label for="node-input-samplingtime"><i class="fa fa-clock-o"></i> Sampling time (h)</label>
<input type="number" id="node-input-samplingtime" style="width:60%;" />
</div>
<!-- Minimum Volume -->
<div class="form-row">
<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>
<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>
<!-- Maximum Weight -->
<div class="form-row">
<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>
<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>
<!-- 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>
<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>
<!-- 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">
<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>
<!-- 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 />
<!-- Asset fields injected here -->
<div id="asset-fields-placeholder"></div>
<!-- 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>
<!-- Logger fields injected here -->
<div id="logger-fields-placeholder"></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>
<!-- Position fields injected here -->
<div id="position-fields-placeholder"></div>
</script>
<script type="text/html" data-help-name="monster">
<p><b>Monster Node</b>: Configures and manages monster measurement data.</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>
<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>
<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>
<p><b>Monster node</b>: Configure a monster asset.</p>
<ul>
</ul>
</script>