Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Draft] UI Module prototype #621

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 249 additions & 11 deletions nodes/ui_base.html

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions nodes/ui_subgroup_i.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script type="text/javascript">
RED.nodes.registerType('ui_subgroup_i',{
category: 'config',
defaults: {
name: {value: "subgroup"},
group: {type: 'ui_group', required:false},
order: {value: 0},
subflow: {value: "", type: "*"},
subgroup: {type: 'ui_subgroup_t', required:true}
},
paletteLabel: 'dashboard subgroup instance',
inputs:0,
outputs:0,
hasUsers: false,
label: function() {
return this.name;},
labelStyle: function() { return this.name?"node_label_italic":""; },
oneditprepare: function() {
var subgroup = this.subgroup;
$("#edit-config-template").click(function(evt) {
RED.editor.editConfig("", "ui_subgroup_t", subgroup);
evt.stopPropagation();
evt.preventDefault();
});
}
});
</script>

<script type="text/html" data-template-name="ui_subgroup_i">
<div class="form-row">
<label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-config-input-name">
</div>
<div class="form-row">
<label for="node-config-input-group"><i class="fa fa-table"></i> Group</label>
<input type="text" id="node-config-input-group">
</div>
<div class="form-row" style="text-align: center;">
<a href="#" class="editor-button editor-button" id="edit-config-template">Edit Subgroup Template</a>
</div>
</script>

<script type="text/html" data-help-name="ui_subgroup_i">
<p>SubGroupIntance</p>
</script>
14 changes: 14 additions & 0 deletions nodes/ui_subgroup_i.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = function(RED) {
function SubGroupInsNode(config) {
RED.nodes.createNode(this, config);
this.config = {
name: config.name,
group: config.group,
order: config.order,
subflow: config.subflow,
subgroup: config.subgroup
};
}

RED.nodes.registerType("ui_subgroup_i", SubGroupInsNode);
};
52 changes: 52 additions & 0 deletions nodes/ui_subgroup_t.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script type="text/javascript">
RED.nodes.registerType('ui_subgroup_t',{
category: 'config',
defaults: {
name: {value: "subgroup"},
widgetOrder: {value: [], type: "*[]"},
width: {value: 1},
height: {value: 1}
},
paletteLabel: 'dashboard subgroup template',
inputs:0,
outputs:0,
hasUsers: false,
label: function() { return this.name; },
labelStyle: function() { return this.name?"node_label_italic":""; },
oneditprepare: function() {
$("#node-config-input-size").elementSizer({
width: "#node-config-input-width",
height: "#node-config-input-height",
subflow: "#node-config-input-subflow",
auto: false
});

$("#edit-config-layout").click(function(evt) {
alert('TODO Subgroup layout editor is not implemented.');
evt.stopPropagation();
evt.preventDefault();
});
}
});
</script>

<script type="text/html" data-template-name="ui_subgroup_t">
<div class="form-row">
<label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-config-input-name">
</div>
<div class="form-row">
<label><i class="fa fa-object-group"></i> Size</label>
<input type="hidden" id="node-config-input-width">
<input type="hidden" id="node-config-input-height">
<input type="hidden" id="node-config-input-subflow">
<button class="editor-button" id="node-config-input-size"></button>
</div>
<div class="form-row" style="text-align: center;">
<a href="#" class="editor-button editor-button" id="edit-config-layout">Edit Subgroup Layout</a>
</div>
</script>

<script type="text/html" data-help-name="ui_subgroup_t">
<p>SubGroupTemplate</p>
</script>
14 changes: 14 additions & 0 deletions nodes/ui_subgroup_t.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = function(RED) {
function SubGroupNode(config) {
RED.nodes.createNode(this, config);
this.config = {
name: config.name,
widgetOrder: config.order,
width: config.width,
height: config.height,
subflow: config.subflow
};
}

RED.nodes.registerType("ui_subgroup_t", SubGroupNode);
};
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@
"ui_link": "nodes/ui_link.js",
"ui_tab": "nodes/ui_tab.js",
"ui_group": "nodes/ui_group.js",
"ui_spacer": "nodes/ui_spacer.js"
"ui_spacer": "nodes/ui_spacer.js",
"ui_subgroup_t": "nodes/ui_subgroup_t.js",
"ui_subgroup_i": "nodes/ui_subgroup_i.js"
}
},
"dependencies": {
Expand Down
134 changes: 134 additions & 0 deletions ui.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

var inited = false;
var nodes = {}; // UI-MODULE PROTO

module.exports = function(RED) {
nodes = RED.nodes; // UI-MODULE PROTO

if (!inited) {
inited = true;
init(RED.server, RED.httpNode || RED.httpAdmin, RED.log, RED.settings);
Expand Down Expand Up @@ -44,6 +47,8 @@ var ev = new events.EventEmitter();
var params = {};
ev.setMaxListeners(0);

var displayed_subgroup = []; // UI-MODULE PROTO

// default manifest.json to be returned as required.
var mani = {
"name": "Node-RED Dashboard",
Expand Down Expand Up @@ -122,6 +127,113 @@ options:
if the returned msg has a property _dontSend, then it won't get sent.
*/
function add(opt) {

// UI-MODULE PROTO
//console.log("\n#",opt.node.type,"/",opt.control.label,"/",opt.node.id,"/",opt.node["_alias"]);
var isSubgroup = false;
if (opt.node["_alias"]) {
isSubgroup = true;

var subflow = nodes.getNode(opt.node.z);
if (subflow) {
var widget = opt.node["_alias"];
console.log("# Widget:", widget, opt.node.type);
console.log(" Belongs to Subflow instalce :", subflow.path);

var subflows = subflow.path.split('/');

// Get orders for all layers by repeating for each layer
var sf_inst_id = subflows.pop(); // Get the trailing subflow instance
while(sf_inst_id) {
var order = -1;
if (subflows.length > 0) {
sg_inst = getSubgroupInstance(sf_inst_id); // Get a subgroup instance
order = getOrderBySubgroup(sg_inst, widget); // Get order value for subgroup
console.log(" subflow instance=",sf_inst_id);
console.log(" widget or subgroup instance=", widget);
console.log(" order=", order);
} else {
console.log(" subgroup instance=", widget);
console.log(" order=", sg_inst.order);
}
widget = sg_inst.id; // Get the order value of the obtained subgroup instance
sf_inst_id = subflows.pop();
}
} else {
// TODO Cannot get subflow instance when subflow instance is placed in subflow.
console.log(" The subflow instance was not found.");
}
}

if (isSubgroup) {
//console.log("# SUBGROUP:", displayed_subgroup);
if (displayed_subgroup.indexOf(opt.node.z) != -1) {
//console.log("# ALREDY DISPLAY: subflow iinstance:", opt.node.z);
return;
}

var sg_height = 1;
var sg_width = 1;
var sg_order = 0;
var sg_group_id = null;

nodes.eachNode(function(node) {
if (node.type == 'ui_subgroup_i') {
if (node.subflow == opt.node.z) {
sg_group_id = node.group;
sg_order = node.order;
}
}
});

if (!sg_group_id) {
//console.log("# SUBGROUP-INSTANCE NOT FOUND:", opt.node.z);
return;
}

nodes.eachNode(function(node) {
if (node.type == 'ui_subgroup_t') {
var idx = node.widgetOrder.indexOf(opt.node["_alias"]);
if (idx != -1) {
sg_height = node.height;
sg_width = node.width;
}
};
});

var sg_group = nodes.getNode(sg_group_id);
if (!sg_group) {
//console.log("# GROUP NOT FOUND:", sg_group_id);
return;
}

var sg_tab = nodes.getNode(sg_group.config.tab);
if (!sg_tab) {
//console.log("# TAB NOT FOUND:", sg_tab);
return;
}

var sg_control = {
type: 'spacer',
order: sg_order,
width: sg_width,
height: sg_height
};

//console.log("# ADD SPACER FOR SUBGROUP");
var remove_sg = addControl(sg_tab, sg_group, sg_control);
displayed_subgroup.push(opt.node.z);

ev.on(updateValueEventName, function() {});
return function() {
ev.removeListener(updateValueEventName, function() {});
remove_sg();
displayed_subgroup = [];
};
}
// UI-MODULE PROTO


clearTimeout(removeStateTimers[opt.node.id]);
delete removeStateTimers[opt.node.id];

Expand Down Expand Up @@ -311,6 +423,28 @@ function add(opt) {
};
}

// Get subgroup instance definition from subflow instance ID
function getSubgroupInstance(sf_inst_id) {
var sg_inst = null;
nodes.eachNode(function(node) {
if (node.type == 'ui_subgroup_i' && node.subflow == sf_inst_id) {
sg_inst = node;
}
});
return sg_inst;
}

// Get order value from subgroup instance definition
function getOrderBySubgroup(sg_inst, widget) {
var order = -1;
nodes.eachNode(function(node) {
if (node.type == 'ui_subgroup_t' && node.id == sg_inst.subgroup) {
order = node.widgetOrder.indexOf(widget);
}
});
return order;
}

//from: https://stackoverflow.com/a/28592528/3016654
function join() {
var trimRegex = new RegExp('^\\/|\\/$','g');
Expand Down