node-red-contrib-prib-functions
Version:
Node-RED added node functions.
200 lines (196 loc) • 7.47 kB
HTML
<script type="text/javascript">
const nodeNameURL="MonitorSystem";
const geval=eval
try{
const url=nodeNameURL+"/svgHTML"
console.log("fetching "+url)
const xhr = new XMLHttpRequest()
xhr.open("GET", url)
xhr.onload = () => {
console.log("fetched "+url)
if (xhr.readyState == 4 && xhr.status == 200) {
try{
geval?.(xhr.response)
} catch(ex){
console.log("fetch: "+xhr.status);
}
} else {
console.error("fetch: "+xhr.status);
}
}
xhr.send()
} catch(ex) {
console.error("fetch: " +ex.message)
}
const nodeSvg={}
const nodeDetails={}
let svgUpdate=false
function drawAll() {
Object.keys(nodeDetails).forEach(id=>{
try{drawBase(id)} catch(ex) {console.error("draw "+id+" "+ex.stack)}
})
}
function drawBase(id) {
const svgBase=nodeSvg[id]
if(svgBase.element==null) {
svgBase.element=document.getElementById(id)
if(svgBase.element==null) return
}
if(svgBase.g) svgBase.g.remove()
try{
drawSVGElement(svgBase.element,
{action:"g",id:"_systemMonitor","font-size":10,style:"z-index:99999;",children:nodeDetails[id]},
id
)
} catch(ex) {
svgUpdate=false
if(ex.message.startsWith("element id not found")) return
console.error(ex.message + " for "+JSON.stringify(nodeDetails[id]))
}
}
function refreshState(){
const action=svgUpdate==true?"getDataUpdateSVG":"getDataSVG"
$.get( "/"+nodeNameURL+"/"+action+"/" )
.done(function(json) {
Object.assign(nodeDetails,json)
try{
drawAll()
svgUpdate=true
} catch (ex) {
svgUpdate=false
}
}).fail(function( jqXHR, textStatus, error ) {
console.error("Monitor System refresh state failed: "+jqXHR.status+" "+textStatus+ " error "+error)
});
}
if(!systemMonitor)
var systemMonitor=setInterval(refreshState, 1000)
/*globals RED */
RED.nodes.registerType('Monitor System', {
category: 'Monitor',
color: '#fdeea2',
defaults: {
name: {value: "",required:false},
metrics: {value: null,required:true},
graphs: {value: null,required:true}
},
inputs:0,
inputLabels: "in",
outputs:1,
outputLabels: ["out"],
icon: "icons8-heart-monitor-40.png",
label: function() {
console.log("*****+++++")
if(!nodeSvg.hasOwnProperty(this.id)) {
nodeSvg[this.id]={element:document.getElementById(this.id),actions:[{action:"text",x:0 ,y:60 ,children:["Waiting Refresh"]}]}
}
drawBase(this.id)
return this.name||this._("Monitor System");
},
labelStyle: function() {
return "node_label_italic";
},
oneditprepare: function() {
$("#node-input-metrics").typedInput({type:"metrics", types:[{
value: "metrics",
multiple: true,
options: [
{ value: "freeMemory", label: "Free Memory"},
{ value: "totalMemory", label: "Total Memory"},
{ value: "gaugeMemory", label: "Gauge Memory"},
{ value: "chartMemoryUsage", label: "Chart Memory"},
{ value: "heapStatistics", label: "Heap Statistics"},
{ value: "heapCodeStatistics", label: "Heap Code Statistics"},
{ value: "heapSpaceStatistics", label: "Heap Space Statistics"},
{ value: "loadAvg", label: "Load Avg"},
{ value: "memoryUsage", label: "Memory Usage"},
{ value: "resourceUsage", label: "Resource Usage"},
{ value: "chartLineResource", label: "Resource Chart"},
]
}]})
},
oneditsave: function() {
},
oneditresize: function() {
},
resizeRule : function(file,newWidth) {
},
button: {
enabled: function() {
return !this.changed;
},
onclick: function() {
if (this.changed) {
return RED.notify(RED._("workflow undeployed changes"),"warning");
}
let label=this._def.label.call(this);
if (label.length > 30) {
label = label.substring(0,50)+"...";
}
label=label.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
const node=this;
function sendCommand(element,action) {
$(element).dialog("close");
$.get( "/"+nodeNameURL+"/"+node.id+"/"+action )
.done(function(json) {
RED.notify(node._(nodeNameURL+" signal success",{label:label}),{type:"success",id:"Load Injector"});
$('<div></div>').appendTo('body').html(json2html(json))
.dialog({
modal: true,
title: (node.name||nodeNameURL)+" "+action,
zIndex: 10000,
autoOpen: true,
width: 'auto',
resizable: false,
buttons: {
close: function (event, ui) {
$(this).remove();
}
}
});
}).fail(function( jqXHR, textStatus, error ) {
if (jqXHR.status === 404) {
RED.notify(node._(nodeNameURL+" signal not deployed"),"error");
} else if (jqXHR.status === 500) {
RED.notify(node._(nodeNameURL+" signal inject failed with error "+(jqXHR.responseText||textStatus||error||"")),"error");
} else if (jqXHR.status === 0) {
RED.notify(node._(nodeNameURL+" signal no response"),"error");
} else {
RED.notify(node._(nodeNameURL+" signal unexpected status:"+jqXHR.status+" message:"+jqXHR.responseText||textStatus+" "+error),"error");
}
});
}
$('<div></div>').appendTo('body').html('<div>Choose Action</div>')
.dialog({
modal: true, title: (node.name||'Monitor System'), zIndex: 10000, autoOpen: true,
width: 'auto', resizable: false,
buttons: {
"Start": function () {
sendCommand(this,"Start");
},
"Stop": function () {
sendCommand(this,"Stop");
}
},
close: function (event, ui) {
$(this).remove();
}
});
}
}
});
</script>
<script type="text/x-red" data-template-name="Monitor System">
<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="Name">
</div>
<div class="form-row">
<label for="node-input-metrics"><i class="fa fa-tag"></i> Metrics</label>
<input type="text" id="node-input-metrics">
</div>
</script>
<script type="text/x-red" data-help-name="Monitor System">
<p>Displays counts of flows in diagram
</p>
</script>