Dia antes primera install
This commit is contained in:
336
node_modules/node-red-node-ui-table/node.js
generated
vendored
Normal file
336
node_modules/node-red-node-ui-table/node.js
generated
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var path = require('path');
|
||||
|
||||
var mergeTabulator = function(target,source) {
|
||||
if (typeof source === 'object') {
|
||||
Object.keys(source).forEach(element => {
|
||||
if (typeof source[element] !== "object") {
|
||||
target[element] = source[element];
|
||||
} else {
|
||||
if (!target.hasOwnProperty(element)) {
|
||||
target[element] = (Array.isArray(source[element])) ? [] : {};
|
||||
}
|
||||
// handle the columns array to merge columns if the field property matches. Otherwise push a new column
|
||||
if (element==='columns' && Array.isArray(source[element])){
|
||||
source[element].forEach(sourceElement => {
|
||||
let index = target[element].findIndex(targetElement => (
|
||||
(targetElement.field && sourceElement.field && targetElement.field===sourceElement.field) || // normal column object
|
||||
(targetElement.title && sourceElement.title && targetElement.title===sourceElement.title) // parent object with nested columns
|
||||
));
|
||||
if (index<0) { // add new column
|
||||
index=target[element].push({})-1;
|
||||
}
|
||||
mergeTabulator(target[element][index],sourceElement);
|
||||
})
|
||||
} else {
|
||||
mergeTabulator(target[element],source[element])
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
target=source;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function (RED) {
|
||||
function checkConfig(node, conf) {
|
||||
if (!conf || !conf.hasOwnProperty('group')) {
|
||||
node.error(RED._('table.error.no-group'));
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function HTML(config,dark) {
|
||||
var configAsJson = JSON.stringify(config, (key, value) => {
|
||||
// exclude the node description
|
||||
if (key === "info") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// replace single quotation mark (apostrophe) by html code in strings
|
||||
if (typeof (value) === "string") {
|
||||
return value.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
// all others leave unchanged
|
||||
return value;
|
||||
});
|
||||
|
||||
var mid = (dark) ? "_midnight" : "";
|
||||
var html = String.raw`
|
||||
<style>.nr-dashboard-ui_table { padding:0; }</style>
|
||||
<link href='ui-table/css/tabulator`+mid+`.min.css' rel='stylesheet' type='text/css'>
|
||||
<script type='text/javascript' src='ui-table/js/tabulator.js'></script>
|
||||
<div id='ui_table-{{$id}}' style="background-color:unset; border:unset;"></div>
|
||||
<input type='hidden' ng-init='init(` + configAsJson + `)'>
|
||||
`;
|
||||
return html;
|
||||
}
|
||||
|
||||
function TableNode(config) {
|
||||
var done = null;
|
||||
var node = this;
|
||||
try {
|
||||
RED.nodes.createNode(this, config);
|
||||
if (checkConfig(node, config)) {
|
||||
var ui = RED.require('node-red-dashboard')(RED);
|
||||
var sizes = ui.getSizes();
|
||||
// var luma = 255;
|
||||
// if (ui.hasOwnProperty("getTheme") && (ui.getTheme() !== undefined)) {
|
||||
// var rgb = parseInt(ui.getTheme()["page-sidebar-backgroundColor"].value.substring(1), 16); // convert rrggbb to decimal
|
||||
// luma = 0.2126 * ((rgb >> 16) & 0xff) + 0.7152 * ((rgb >> 8) & 0xff) + 0.0722 * ((rgb >> 0) & 0xff); // per ITU-R BT.709
|
||||
// }
|
||||
var html = HTML(config,ui.isDark());
|
||||
|
||||
done = ui.addWidget({
|
||||
node: node,
|
||||
width: config.width,
|
||||
height: (config.height > 2) ? config.height : 2, // min height to 2 so auto will show something
|
||||
format: html,
|
||||
templateScope: 'local',
|
||||
order: config.order || 0,
|
||||
group: config.group,
|
||||
forwardInputMessages: false,
|
||||
storeFrontEndInputAsState: false,
|
||||
|
||||
// to make msg.ui_control work without msg.payload we have to send msg.payload=null.
|
||||
// we correct this here into undefined to get the last known payload form currentValues[opt.node.id].
|
||||
convert: function (value) {
|
||||
if (value===null) value=undefined;
|
||||
return value;
|
||||
},
|
||||
// merge new ui_control messages into config.ui_control
|
||||
// Help needed: use the already build in ui_control mechanism from ui.js
|
||||
beforeEmit: function (msg, value) {
|
||||
// cache ui_control messages for new clients
|
||||
if (msg.hasOwnProperty('ui_control')) {
|
||||
if (!config.hasOwnProperty('ui_control')){
|
||||
config.ui_control={
|
||||
"tabulator":{
|
||||
"columns":config.columns
|
||||
}};
|
||||
}
|
||||
// use mergeTabulator to correctly merge columns arrays if field property matches
|
||||
mergeTabulator(config.ui_control,msg.ui_control);
|
||||
|
||||
// delete column definitions by sending a empty columns array (requires page reload)
|
||||
if (msg.ui_control.tabulator && msg.ui_control.tabulator.columns && Array.isArray(msg.ui_control.tabulator.columns) &&
|
||||
msg.ui_control.tabulator.columns.length==0) {
|
||||
|
||||
config.ui_control.tabulator.columns=[];
|
||||
config.ui_control.tabulator.autoColumns=true;
|
||||
}
|
||||
}
|
||||
return { msg: {
|
||||
payload: value,
|
||||
ui_control: config.ui_control,
|
||||
socketid: msg.socketid
|
||||
}};
|
||||
},
|
||||
beforeSend: function (msg, orig) {
|
||||
if (orig) { return orig.msg; }
|
||||
},
|
||||
initController: function ($scope, events) {
|
||||
$scope.inited = false;
|
||||
$scope.tabledata = [];
|
||||
var tablediv;
|
||||
var mergeObject = function(target,source) {
|
||||
if (typeof source === 'object') {
|
||||
Object.keys(source).forEach(element => {
|
||||
if (typeof source[element] !== "object") {
|
||||
target[element] = source[element];
|
||||
} else {
|
||||
if (!target.hasOwnProperty(element)) {
|
||||
target[element] = (Array.isArray(source[element])) ? [] : {};
|
||||
}
|
||||
mergeObject(target[element],source[element])
|
||||
}
|
||||
});
|
||||
} else {
|
||||
target = source;
|
||||
}
|
||||
};
|
||||
|
||||
var createTable = function(basediv, tabledata, columndata, outputs, ui_control) {
|
||||
// add id field if not already exists
|
||||
if (columndata.length>0 && tabledata.length>0 && tabledata[0] && typeof tabledata[0] === 'object' && !tabledata[0].hasOwnProperty('id')) {
|
||||
tabledata.map((row,index) => row.id = index);
|
||||
}
|
||||
var opts = {
|
||||
data: tabledata,
|
||||
layout: 'fitColumns',
|
||||
columns: columndata,
|
||||
autoColumns: columndata.length == 0,
|
||||
movableColumns: true,
|
||||
}
|
||||
if (!ui_control || !ui_control.tabulator) {
|
||||
var y = (columndata.length === 0) ? 25 : 32;
|
||||
if ($scope.height==2) { // auto height
|
||||
opts.height = (tabledata.length > 0 )? tabledata.length * y + 26 : $scope.height*(sizes.sy+sizes.cy);
|
||||
} else {
|
||||
opts.height = $scope.height*(sizes.sy+sizes.cy);
|
||||
}
|
||||
}
|
||||
else { // configuration via ui_control
|
||||
//as Object.assign is not supported by Internet Explorer
|
||||
//opts = Object.assign(opts, ui_control.tabulator);
|
||||
mergeObject(opts,ui_control.tabulator);
|
||||
var y = (opts.columns && (opts.columns.length > 0)) ? 32 : 25;
|
||||
if (ui_control.customHeight) {
|
||||
opts.height= ui_control.customHeight * y + 26;
|
||||
} else {
|
||||
if ($scope.height==2) { // auto height
|
||||
opts.height= (tabledata.length > 0 )? tabledata.length * y + 26 : $scope.height*(sizes.sy+sizes.cy);
|
||||
} else {
|
||||
opts.height = $scope.height*(sizes.sy+sizes.cy);
|
||||
}
|
||||
}
|
||||
} // end of configuration via ui_control
|
||||
|
||||
if ((outputs > 0) && !opts.hasOwnProperty('cellClick')) { // default cellClick if not already defined by ui_control
|
||||
opts.cellClick = function(e, cell) {
|
||||
$scope.send({topic:cell.getField(), payload:cell.getData(), row:(cell.getRow()).getPosition()});
|
||||
};
|
||||
}
|
||||
//turn autoColumns off if opts.columns is array with length > 0
|
||||
if (opts.columns && Array.isArray(opts.columns) && opts.columns.length>0) {
|
||||
opts.autoColumns = false;
|
||||
}
|
||||
// console.log("createTabulator",opts);
|
||||
if ($scope.table !== undefined) {
|
||||
$scope.table.destroy();
|
||||
}
|
||||
$scope.table = new Tabulator(basediv, opts);
|
||||
};
|
||||
$scope.init = function (config) {
|
||||
$scope.config = config;
|
||||
tablediv = '#ui_table-' + $scope.$eval('$id')
|
||||
var stateCheck = setInterval(function() {
|
||||
if (document.querySelector(tablediv) && $scope.tabledata) {
|
||||
clearInterval(stateCheck);
|
||||
$scope.inited = true;
|
||||
createTable(tablediv,$scope.tabledata,$scope.config.columns,$scope.config.outputs,$scope.config.ui_control);
|
||||
$scope.tabledata = [];
|
||||
}
|
||||
}, 200); // lowest setting on my side ... still fails sometimes ;)
|
||||
};
|
||||
$scope.$watch('msg', function (msg) {
|
||||
//console.log("ui-table message arrived:",msg);
|
||||
if (msg && msg.hasOwnProperty("ui_control") && msg.ui_control.hasOwnProperty("callback")) return msg; // to avoid loopback from callbacks. No better solution jet. Help needed.
|
||||
//console.log("ui-table msg: ", msg);
|
||||
|
||||
// configuration via ui_control
|
||||
if (msg && msg.hasOwnProperty("ui_control")) {
|
||||
|
||||
var addValueOrFunction = function (config,param,value) {
|
||||
if (typeof String.prototype.parseFunction != 'function') {
|
||||
String.prototype.parseFunction = function () {
|
||||
var funcReg = /function *\(([^()]*)\)[ \n\t]*{(.*)}/gmi;
|
||||
var match = funcReg.exec(this.replace(/\n/g, ' '));
|
||||
if (match) {
|
||||
return new Function(match[1].split(','), match[2]);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
var valueFunction;
|
||||
if (typeof value === "string" && (valueFunction = value.parseFunction())) {
|
||||
config[param]=valueFunction.bind($scope); // to enable this.send() for callback functions.
|
||||
}
|
||||
else config[param]= value;
|
||||
}
|
||||
|
||||
var addObject = function (destinationObject,sourceObject) {
|
||||
for (var element in sourceObject) {
|
||||
if (!destinationObject[element]) destinationObject[element]=(Array.isArray(sourceObject[element]))? [] : {};
|
||||
if (typeof sourceObject[element] === "object") {
|
||||
addObject(destinationObject[element],sourceObject[element])
|
||||
} else {
|
||||
addValueOrFunction(destinationObject,element,sourceObject[element]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$scope.config.ui_control) { $scope.config.ui_control={}; }
|
||||
|
||||
addObject($scope.config.ui_control,msg.ui_control);
|
||||
|
||||
} // end of configuration via ui_control
|
||||
|
||||
if (msg && msg.hasOwnProperty("payload")) {
|
||||
if (Array.isArray(msg.payload)) {
|
||||
$scope.tabledata = msg.payload;
|
||||
}
|
||||
|
||||
// commands to tabulator via msg.payload object
|
||||
if (typeof msg.payload === "object" && msg.payload!==null && !Array.isArray(msg.payload)) {
|
||||
if (msg.payload.hasOwnProperty("command") && $scope.table!==undefined) {
|
||||
if (!msg.payload.hasOwnProperty("arguments") || !Array.isArray(msg.payload.arguments)) {
|
||||
msg.payload.arguments=[];
|
||||
}
|
||||
if (msg.payload.returnPromise) {
|
||||
$scope.table[msg.payload.command].apply($scope.table,msg.payload.arguments).then(function(...args){
|
||||
$scope.send({topic:"success", ui_control: {callback:$scope.msg.payload.command}, return:$scope.msg.payload});
|
||||
}).catch(function(error){
|
||||
if (Object.keys(error).length>0) {
|
||||
$scope.send({topic:"error", ui_control: {callback:$scope.msg.payload.command}, return:$scope.msg.payload, error: error});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$scope.table[msg.payload.command].apply($scope.table,msg.payload.arguments);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
} // end of commands to tabulator via msg.payload object
|
||||
|
||||
}
|
||||
|
||||
if ($scope.inited == false) {
|
||||
return;
|
||||
} else {
|
||||
createTable(tablediv, $scope.tabledata, $scope.config.columns, $scope.config.outputs, $scope.config.ui_control);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (e) { console.log(e); }
|
||||
|
||||
node.on('close', function () {
|
||||
if (done) { done(); }
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType('ui_table', TableNode);
|
||||
|
||||
var uipath = 'ui';
|
||||
if (RED?.settings?.ui) { uipath = RED.settings.ui.path; }
|
||||
var fullPath = path.join('/', uipath, '/ui-table/*').replace(/\\/g, '/');
|
||||
RED.httpNode.get(fullPath, function (req, res) {
|
||||
var options = {
|
||||
root: __dirname + '/lib/',
|
||||
dotfiles: 'deny'
|
||||
};
|
||||
res.sendFile(req.params[0], options)
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user