mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
commit
e02189d092
@ -49,6 +49,18 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
|
<li class="dropdown-submenu pull-left"><a tabindex="-1" href="#"><i class="icon-th-large"></i> Workspaces</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a id="btn-workspace-add" tabindex="-1" href="#"><i class="icon-plus"></i> Add</a></li>
|
||||||
|
<li><a id="btn-workspace-edit" tabindex="-1" href="#"><i class="icon-edit"></i> Rename</a></li>
|
||||||
|
<li><a id="btn-workspace-delete" tabindex="-1" href="#"><i class="icon-minus"></i> Delete</a></li>
|
||||||
|
<li class="dropdown-submenu pull-left">
|
||||||
|
<a tabindex="-1" href="#"><i class="icon-share-alt"></i> Switch to...</a>
|
||||||
|
<ul id="workspace-menu-list" class="dropdown-menu"></ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="divider"></li>
|
||||||
<li><a id="btn-keyboard-shortcuts" tabindex="-1" href="#"><i class="icon-question-sign"></i> Keyboard Shortcuts</a></li>
|
<li><a id="btn-keyboard-shortcuts" tabindex="-1" href="#"><i class="icon-question-sign"></i> Keyboard Shortcuts</a></li>
|
||||||
<li><a id="btn-help" tabindex="-1" href="http://node-red.github.io/docs" target="_blank"><i class="icon-question-sign"></i> Help...</a></li>
|
<li><a id="btn-help" tabindex="-1" href="http://node-red.github.io/docs" target="_blank"><i class="icon-question-sign"></i> Help...</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -108,7 +120,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div><!-- /palette -->
|
</div><!-- /palette -->
|
||||||
|
|
||||||
<div id="chart"></div>
|
<div id="workspace">
|
||||||
|
<ul id="workspace-tabs"></ul>
|
||||||
|
<div id="workspace-add-tab"><a id="btn-workspace-add-tab" href="#"><i class="icon-plus"></i></a></div>
|
||||||
|
<div id="chart"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="chart-zoom-controls">
|
<div id="chart-zoom-controls">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
@ -119,12 +135,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
<div id="sidebar">
|
||||||
<ul id="sidebar-tabs">
|
<ul id="sidebar-tabs"></ul>
|
||||||
<li><a href="#tab-info">info</a></li>
|
<div id="sidebar-content"></div>
|
||||||
</ul>
|
|
||||||
<div id="sidebar-content">
|
|
||||||
<div id="tab-info" style="position: relative;"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar-separator"></div>
|
<div id="sidebar-separator"></div>
|
||||||
@ -231,6 +243,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="node-dialog-rename-workspace" class="hide">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-workspace-name" ><i class="icon-tag"></i> Name:</label>
|
||||||
|
<input type="text" id="node-input-workspace-name">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="node-dialog-delete-workspace" class="hide">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div style="text-align: center; padding-top: 30px;">
|
||||||
|
Are you sure you want to delete '<span id="node-dialog-delete-workspace-name"></span>'?
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/x-red" data-template-name="export-clipboard-dialog">
|
<script type="text/x-red" data-template-name="export-clipboard-dialog">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -265,6 +292,7 @@
|
|||||||
<script src="red/history.js"></script>
|
<script src="red/history.js"></script>
|
||||||
<script src="red/validators.js"></script>
|
<script src="red/validators.js"></script>
|
||||||
<script src="red/ui/keyboard.js"></script>
|
<script src="red/ui/keyboard.js"></script>
|
||||||
|
<script src="red/ui/tabs.js"></script>
|
||||||
<script src="red/ui/view.js"></script>
|
<script src="red/ui/view.js"></script>
|
||||||
<script src="red/ui/sidebar.js"></script>
|
<script src="red/ui/sidebar.js"></script>
|
||||||
<script src="red/ui/palette.js"></script>
|
<script src="red/ui/palette.js"></script>
|
||||||
|
@ -36,7 +36,15 @@ RED.history = function() {
|
|||||||
for (var i in ev.links) {
|
for (var i in ev.links) {
|
||||||
RED.nodes.removeLink(ev.links[i]);
|
RED.nodes.removeLink(ev.links[i]);
|
||||||
}
|
}
|
||||||
|
for (var i in ev.workspaces) {
|
||||||
|
RED.nodes.removeWorkspace(ev.workspaces[i].id);
|
||||||
|
RED.view.removeWorkspace(ev.workspaces[i]);
|
||||||
|
}
|
||||||
} else if (ev.t == "delete") {
|
} else if (ev.t == "delete") {
|
||||||
|
for (var i in ev.workspaces) {
|
||||||
|
RED.nodes.addWorkspace(ev.workspaces[i]);
|
||||||
|
RED.view.addWorkspace(ev.workspaces[i]);
|
||||||
|
}
|
||||||
for (var i in ev.nodes) {
|
for (var i in ev.nodes) {
|
||||||
RED.nodes.add(ev.nodes[i]);
|
RED.nodes.add(ev.nodes[i]);
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,20 @@ RED.nodes = function() {
|
|||||||
var configNodes = {};
|
var configNodes = {};
|
||||||
var links = [];
|
var links = [];
|
||||||
|
|
||||||
|
var defaultWorkspace;
|
||||||
|
var workspaces = {};
|
||||||
|
|
||||||
|
|
||||||
function registerType(nt,def) {
|
function registerType(nt,def) {
|
||||||
node_defs[nt] = def;
|
node_defs[nt] = def;
|
||||||
// TODO: too tightly coupled into palette UI
|
// TODO: too tightly coupled into palette UI
|
||||||
RED.palette.add(nt,def);
|
RED.palette.add(nt,def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getID() {
|
||||||
|
return (1+Math.random()*4294967295).toString(16);
|
||||||
|
}
|
||||||
|
|
||||||
function getType(type) {
|
function getType(type) {
|
||||||
return node_defs[type];
|
return node_defs[type];
|
||||||
}
|
}
|
||||||
@ -87,6 +95,28 @@ RED.nodes = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addWorkspace(ws) {
|
||||||
|
workspaces[ws.id] = ws;
|
||||||
|
}
|
||||||
|
function getWorkspace(id) {
|
||||||
|
return workspaces[id];
|
||||||
|
}
|
||||||
|
function removeWorkspace(id) {
|
||||||
|
delete workspaces[id];
|
||||||
|
var removedNodes = [];
|
||||||
|
var removedLinks = [];
|
||||||
|
for (var n in nodes) {
|
||||||
|
var node = nodes[n];
|
||||||
|
if (node.z == id) {
|
||||||
|
removedNodes.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var n in removedNodes) {
|
||||||
|
var rmlinks = removeNode(removedNodes[n].id);
|
||||||
|
removedLinks = removedLinks.concat(rmlinks);
|
||||||
|
}
|
||||||
|
return {nodes:removedNodes,links:removedLinks};
|
||||||
|
}
|
||||||
function getAllFlowNodes(node) {
|
function getAllFlowNodes(node) {
|
||||||
var visited = {};
|
var visited = {};
|
||||||
visited[node.id] = true;
|
visited[node.id] = true;
|
||||||
@ -120,6 +150,7 @@ RED.nodes = function() {
|
|||||||
if (n._def.category != "config") {
|
if (n._def.category != "config") {
|
||||||
node.x = n.x;
|
node.x = n.x;
|
||||||
node.y = n.y;
|
node.y = n.y;
|
||||||
|
node.z = n.z;
|
||||||
|
|
||||||
node.wires = [];
|
node.wires = [];
|
||||||
for(var i=0;i<n.outputs;i++) {
|
for(var i=0;i<n.outputs;i++) {
|
||||||
@ -166,6 +197,9 @@ RED.nodes = function() {
|
|||||||
//TODO: rename this (createCompleteNodeSet)
|
//TODO: rename this (createCompleteNodeSet)
|
||||||
function createCompleteNodeSet() {
|
function createCompleteNodeSet() {
|
||||||
var nns = [];
|
var nns = [];
|
||||||
|
for (var i in workspaces) {
|
||||||
|
nns.push(workspaces[i]);
|
||||||
|
}
|
||||||
for (var i in configNodes) {
|
for (var i in configNodes) {
|
||||||
nns.push(convertNode(configNodes[i]));
|
nns.push(convertNode(configNodes[i]));
|
||||||
}
|
}
|
||||||
@ -193,12 +227,27 @@ RED.nodes = function() {
|
|||||||
}
|
}
|
||||||
for (var i in newNodes) {
|
for (var i in newNodes) {
|
||||||
var n = newNodes[i];
|
var n = newNodes[i];
|
||||||
if (!getType(n.type)) {
|
if (n.type != "workspace" && !getType(n.type)) {
|
||||||
// TODO: get this UI thing out of here! (see below as well)
|
// TODO: get this UI thing out of here! (see below as well)
|
||||||
RED.notify("<strong>Failed to import nodes</strong>: unrecognised type '"+n.type+"'","error");
|
RED.notify("<strong>Failed to import nodes</strong>: unrecognised type '"+n.type+"'","error");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (var i in newNodes) {
|
||||||
|
var n = newNodes[i];
|
||||||
|
if (n.type === "workspace") {
|
||||||
|
if (defaultWorkspace == null) {
|
||||||
|
defaultWorkspace = n;
|
||||||
|
}
|
||||||
|
addWorkspace(n);
|
||||||
|
RED.view.addWorkspace(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (defaultWorkspace == null) {
|
||||||
|
defaultWorkspace = { type:"workspace", id:getID(), label:"Workspace 1" };
|
||||||
|
addWorkspace(defaultWorkspace);
|
||||||
|
RED.view.addWorkspace(defaultWorkspace);
|
||||||
|
}
|
||||||
|
|
||||||
var node_map = {};
|
var node_map = {};
|
||||||
var new_nodes = [];
|
var new_nodes = [];
|
||||||
@ -206,51 +255,57 @@ RED.nodes = function() {
|
|||||||
|
|
||||||
for (var i in newNodes) {
|
for (var i in newNodes) {
|
||||||
var n = newNodes[i];
|
var n = newNodes[i];
|
||||||
var def = getType(n.type);
|
if (n.type !== "workspace") {
|
||||||
if (def && def.category == "config") {
|
var def = getType(n.type);
|
||||||
if (!RED.nodes.node(n.id)) {
|
if (def && def.category == "config") {
|
||||||
var configNode = {id:n.id,type:n.type,users:[]};
|
if (!RED.nodes.node(n.id)) {
|
||||||
for (var d in def.defaults) {
|
var configNode = {id:n.id,type:n.type,users:[]};
|
||||||
configNode[d] = n[d];
|
for (var d in def.defaults) {
|
||||||
|
configNode[d] = n[d];
|
||||||
|
}
|
||||||
|
configNode.label = def.label;
|
||||||
|
configNode._def = def;
|
||||||
|
RED.nodes.add(configNode);
|
||||||
}
|
}
|
||||||
configNode.label = def.label;
|
|
||||||
configNode._def = def;
|
|
||||||
RED.nodes.add(configNode);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var node = {x:n.x,y:n.y,type:0,wires:n.wires};
|
|
||||||
if (createNewIds) {
|
|
||||||
node.id = (1+Math.random()*4294967295).toString(16);
|
|
||||||
} else {
|
} else {
|
||||||
node.id = n.id;
|
var node = {x:n.x,y:n.y,z:n.z,type:0,wires:n.wires};
|
||||||
}
|
if (createNewIds) {
|
||||||
node.type = n.type;
|
node.z = RED.view.getWorkspace();
|
||||||
node._def = def;
|
node.id = getID();
|
||||||
if (!node._def) {
|
} else {
|
||||||
node._def = {
|
node.id = n.id;
|
||||||
color:"#fee",
|
if (node.z == null || !workspaces[node.z]) {
|
||||||
defaults: {},
|
node.z = RED.view.getWorkspace();
|
||||||
label: "unknown: "+n.type,
|
|
||||||
labelStyle: "node_label_italic",
|
|
||||||
outputs: n.outputs||n.wires.length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
node.outputs = n.outputs||node._def.outputs;
|
|
||||||
|
|
||||||
for (var d in node._def.defaults) {
|
|
||||||
node[d] = n[d];
|
|
||||||
if (node._def.defaults[d].type) {
|
|
||||||
var configNode = RED.nodes.node(n[d]);
|
|
||||||
if (configNode) {
|
|
||||||
configNode.users.push(node);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
node.type = n.type;
|
||||||
|
node._def = def;
|
||||||
|
if (!node._def) {
|
||||||
|
node._def = {
|
||||||
|
color:"#fee",
|
||||||
|
defaults: {},
|
||||||
|
label: "unknown: "+n.type,
|
||||||
|
labelStyle: "node_label_italic",
|
||||||
|
outputs: n.outputs||n.wires.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node.outputs = n.outputs||node._def.outputs;
|
||||||
|
|
||||||
addNode(node);
|
for (var d in node._def.defaults) {
|
||||||
RED.editor.validateNode(node);
|
node[d] = n[d];
|
||||||
node_map[n.id] = node;
|
if (node._def.defaults[d].type) {
|
||||||
new_nodes.push(node);
|
var configNode = RED.nodes.node(n[d]);
|
||||||
|
if (configNode) {
|
||||||
|
configNode.users.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addNode(node);
|
||||||
|
RED.editor.validateNode(node);
|
||||||
|
node_map[n.id] = node;
|
||||||
|
new_nodes.push(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var i in new_nodes) {
|
for (var i in new_nodes) {
|
||||||
@ -284,6 +339,9 @@ RED.nodes = function() {
|
|||||||
addLink: addLink,
|
addLink: addLink,
|
||||||
remove: removeNode,
|
remove: removeNode,
|
||||||
removeLink: removeLink,
|
removeLink: removeLink,
|
||||||
|
addWorkspace: addWorkspace,
|
||||||
|
removeWorkspace: removeWorkspace,
|
||||||
|
workspace: getWorkspace,
|
||||||
eachNode: function(cb) {
|
eachNode: function(cb) {
|
||||||
for (var n in nodes) {
|
for (var n in nodes) {
|
||||||
cb(nodes[n]);
|
cb(nodes[n]);
|
||||||
@ -305,6 +363,7 @@ RED.nodes = function() {
|
|||||||
getAllFlowNodes: getAllFlowNodes,
|
getAllFlowNodes: getAllFlowNodes,
|
||||||
createExportableNodeSet: createExportableNodeSet,
|
createExportableNodeSet: createExportableNodeSet,
|
||||||
createCompleteNodeSet: createCompleteNodeSet,
|
createCompleteNodeSet: createCompleteNodeSet,
|
||||||
|
id: getID,
|
||||||
nodes: nodes, // TODO: exposed for d3 vis
|
nodes: nodes, // TODO: exposed for d3 vis
|
||||||
links: links // TODO: exposed for d3 vis
|
links: links // TODO: exposed for d3 vis
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,29 @@
|
|||||||
**/
|
**/
|
||||||
RED.sidebar = function() {
|
RED.sidebar = function() {
|
||||||
|
|
||||||
$('#sidebar').tabs();
|
//$('#sidebar').tabs();
|
||||||
|
var sidebar_tabs = RED.tabs.create({
|
||||||
|
id:"sidebar-tabs",
|
||||||
|
onchange:function(id) {
|
||||||
|
$("#sidebar-content").children().hide();
|
||||||
|
$("#"+id).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
function addTab(title,content) {
|
||||||
|
$("#sidebar-content").append(content);
|
||||||
|
$(content).hide();
|
||||||
|
sidebar_tabs.addTab({id:"tab-"+title,label:title});
|
||||||
|
//content.style.position = "absolute";
|
||||||
|
//$('#sidebar').tabs("refresh");
|
||||||
|
}
|
||||||
|
|
||||||
|
var content = document.createElement("div");
|
||||||
|
content.id = "tab-info";
|
||||||
|
content.style.paddingTop = "4px";
|
||||||
|
content.style.paddingLeft = "4px";
|
||||||
|
content.style.paddingRight = "4px";
|
||||||
|
|
||||||
|
addTab("info",content);
|
||||||
|
|
||||||
$('#btn-sidebar').click(function() {toggleSidebar();});
|
$('#btn-sidebar').click(function() {toggleSidebar();});
|
||||||
RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){toggleSidebar();d3.event.preventDefault();});
|
RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){toggleSidebar();d3.event.preventDefault();});
|
||||||
@ -28,8 +50,8 @@ RED.sidebar = function() {
|
|||||||
var winWidth = $(window).width();
|
var winWidth = $(window).width();
|
||||||
sidebarSeparator.start = ui.position.left;
|
sidebarSeparator.start = ui.position.left;
|
||||||
sidebarSeparator.width = $("#sidebar").width();
|
sidebarSeparator.width = $("#sidebar").width();
|
||||||
sidebarSeparator.chartWidth = $("#chart").width();
|
sidebarSeparator.chartWidth = $("#workspace").width();
|
||||||
sidebarSeparator.chartRight = winWidth-$("#chart").width()-$("#chart").offset().left-2;
|
sidebarSeparator.chartRight = winWidth-$("#workspace").width()-$("#workspace").offset().left-2;
|
||||||
sidebarSeparator.closing = false;
|
sidebarSeparator.closing = false;
|
||||||
},
|
},
|
||||||
drag: function(event,ui) {
|
drag: function(event,ui) {
|
||||||
@ -38,7 +60,7 @@ RED.sidebar = function() {
|
|||||||
|
|
||||||
if (newSidebarWidth > 180 && sidebarSeparator.chartWidth+d > 200) {
|
if (newSidebarWidth > 180 && sidebarSeparator.chartWidth+d > 200) {
|
||||||
var newChartRight = sidebarSeparator.chartRight-d;
|
var newChartRight = sidebarSeparator.chartRight-d;
|
||||||
$("#chart").css("right",newChartRight);
|
$("#workspace").css("right",newChartRight);
|
||||||
$("#chart-zoom-controls").css("right",newChartRight+20);
|
$("#chart-zoom-controls").css("right",newChartRight+20);
|
||||||
$("#sidebar").width(newSidebarWidth);
|
$("#sidebar").width(newSidebarWidth);
|
||||||
}
|
}
|
||||||
@ -50,6 +72,8 @@ RED.sidebar = function() {
|
|||||||
sidebarSeparator.closing = false;
|
sidebarSeparator.closing = false;
|
||||||
$("#sidebar").removeClass("closing");
|
$("#sidebar").removeClass("closing");
|
||||||
}
|
}
|
||||||
|
sidebar_tabs.resize();
|
||||||
|
RED.view.resize();
|
||||||
|
|
||||||
},
|
},
|
||||||
stop:function(event,ui) {
|
stop:function(event,ui) {
|
||||||
@ -63,9 +87,9 @@ RED.sidebar = function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function toggleSidebar() {
|
function toggleSidebar() {
|
||||||
if ($('#sidebar').tabs( "option", "active" ) === false) {
|
//if ($('#sidebar').tabs( "option", "active" ) === false) {
|
||||||
$('#sidebar').tabs( "option", "active",0);
|
// $('#sidebar').tabs( "option", "active",0);
|
||||||
}
|
//}
|
||||||
var btnSidebar = $("#btn-sidebar");
|
var btnSidebar = $("#btn-sidebar");
|
||||||
btnSidebar.toggleClass("active");
|
btnSidebar.toggleClass("active");
|
||||||
|
|
||||||
@ -77,15 +101,6 @@ RED.sidebar = function() {
|
|||||||
}
|
}
|
||||||
toggleSidebar();
|
toggleSidebar();
|
||||||
|
|
||||||
function addTab(title,content) {
|
|
||||||
var tab = document.createElement("li");
|
|
||||||
tab.innerHTML = '<a href="#tab-'+title+'">'+title+'</a>';
|
|
||||||
$("#sidebar-tabs").append(tab);
|
|
||||||
$("#sidebar-content").append(content);
|
|
||||||
|
|
||||||
$('#sidebar').tabs("refresh");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
addTab: addTab
|
addTab: addTab
|
||||||
|
103
public/red/ui/tabs.js
Normal file
103
public/red/ui/tabs.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2013 IBM Corp.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RED.tabs = function() {
|
||||||
|
|
||||||
|
|
||||||
|
function createTabs(options) {
|
||||||
|
var ul = $("#"+options.id)
|
||||||
|
ul.addClass("red-ui-tabs");
|
||||||
|
ul.children().first().addClass("active");
|
||||||
|
ul.children().addClass("red-ui-tab");
|
||||||
|
|
||||||
|
function onTabClick() {
|
||||||
|
activateTab($(this));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTabDblClick() {
|
||||||
|
if (options.ondblclick) {
|
||||||
|
options.ondblclick($(this).attr('href').slice(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function activateTab(link) {
|
||||||
|
if (typeof link === "string") {
|
||||||
|
link = ul.find("a[href='#"+link+"']");
|
||||||
|
}
|
||||||
|
if (!link.parent().hasClass("active")) {
|
||||||
|
ul.children().removeClass("active");
|
||||||
|
link.parent().addClass("active");
|
||||||
|
if (options.onchange) {
|
||||||
|
options.onchange(link.attr('href').slice(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function updateTabWidths() {
|
||||||
|
var tabs = ul.find("li.red-ui-tab");
|
||||||
|
var width = ul.width();
|
||||||
|
var tabCount = tabs.size();
|
||||||
|
var tabWidth = (width-6-(tabCount*7))/tabCount;
|
||||||
|
var pct = 100*tabWidth/width;
|
||||||
|
tabs.css({width:pct+"%"});
|
||||||
|
|
||||||
|
}
|
||||||
|
ul.find("li.red-ui-tab a").on("click",onTabClick).on("dblclick",onTabDblClick);
|
||||||
|
updateTabWidths();
|
||||||
|
|
||||||
|
return {
|
||||||
|
addTab: function(tab) {
|
||||||
|
var li = $("<li/>",{class:"red-ui-tab"}).appendTo(ul);
|
||||||
|
var link = $("<a/>",{href:"#"+tab.id}).appendTo(li);
|
||||||
|
link.html(tab.label);
|
||||||
|
link.on("click",onTabClick);
|
||||||
|
link.on("dblclick",onTabDblClick);
|
||||||
|
updateTabWidths();
|
||||||
|
if (options.onadd) {
|
||||||
|
options.onadd(tab);
|
||||||
|
}
|
||||||
|
link.attr("title",tab.label);
|
||||||
|
if (ul.find("li.red-ui-tab").size() == 1) {
|
||||||
|
activateTab(link);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeTab: function(id) {
|
||||||
|
var li = ul.find("a[href='#"+id+"']").parent();
|
||||||
|
if (li.hasClass("active")) {
|
||||||
|
var tab = li.prev();
|
||||||
|
if (tab.size() == 0) {
|
||||||
|
tab = li.next();
|
||||||
|
}
|
||||||
|
activateTab(tab.find("a"));
|
||||||
|
}
|
||||||
|
li.remove();
|
||||||
|
|
||||||
|
},
|
||||||
|
activateTab: activateTab,
|
||||||
|
resize: updateTabWidths,
|
||||||
|
count: function() {
|
||||||
|
return ul.find("li.red-ui-tab").size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
create: createTabs
|
||||||
|
}
|
||||||
|
}();
|
@ -13,6 +13,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
|
||||||
RED.view = function() {
|
RED.view = function() {
|
||||||
var space_width = 5000,
|
var space_width = 5000,
|
||||||
space_height = 5000,
|
space_height = 5000,
|
||||||
@ -21,6 +23,9 @@ RED.view = function() {
|
|||||||
node_width = 100,
|
node_width = 100,
|
||||||
node_height = 30;
|
node_height = 30;
|
||||||
|
|
||||||
|
var activeWorkspace = 0;
|
||||||
|
var workspaceScrollPositions = {};
|
||||||
|
|
||||||
var selected_link = null,
|
var selected_link = null,
|
||||||
mousedown_link = null,
|
mousedown_link = null,
|
||||||
mousedown_node = null,
|
mousedown_node = null,
|
||||||
@ -63,6 +68,62 @@ RED.view = function() {
|
|||||||
|
|
||||||
var drag_line = vis.append("svg:path").attr("class", "drag_line");
|
var drag_line = vis.append("svg:path").attr("class", "drag_line");
|
||||||
|
|
||||||
|
var workspace_tabs = RED.tabs.create({
|
||||||
|
id: "workspace-tabs",
|
||||||
|
onchange: function(id) {
|
||||||
|
RED.view.setWorkspace(id);
|
||||||
|
},
|
||||||
|
ondblclick: function(id) {
|
||||||
|
showRenameWorkspaceDialog(id);
|
||||||
|
},
|
||||||
|
onadd: function(tab) {
|
||||||
|
var menuli = $("<li/>");
|
||||||
|
var menuA = $("<a/>",{tabindex:"-1",href:"#"+tab.id}).appendTo(menuli);
|
||||||
|
menuA.html(tab.label);
|
||||||
|
menuA.on("click",function() {
|
||||||
|
workspace_tabs.activateTab(tab.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#workspace-menu-list').append(menuli);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var workspaceIndex = 0;
|
||||||
|
|
||||||
|
function addWorkspace() {
|
||||||
|
var tabId = RED.nodes.id();
|
||||||
|
do {
|
||||||
|
workspaceIndex += 1;
|
||||||
|
} while($("#workspace-tabs a[title='Workspace "+workspaceIndex+"']").size() != 0);
|
||||||
|
|
||||||
|
var ws = {type:"workspace",id:tabId,label:"Workspace "+workspaceIndex};
|
||||||
|
RED.nodes.addWorkspace(ws);
|
||||||
|
workspace_tabs.addTab(ws);
|
||||||
|
workspace_tabs.activateTab(tabId);
|
||||||
|
|
||||||
|
RED.history.push({t:'add',workspaces:[ws],dirty:dirty});
|
||||||
|
RED.view.dirty(true);
|
||||||
|
}
|
||||||
|
$('#btn-workspace-add-tab').on("click",addWorkspace);
|
||||||
|
$('#btn-workspace-add').on("click",addWorkspace);
|
||||||
|
$('#btn-workspace-edit').on("click",function() {
|
||||||
|
showRenameWorkspaceDialog(activeWorkspace);
|
||||||
|
});
|
||||||
|
$('#btn-workspace-delete').on("click",function() {
|
||||||
|
deleteWorkspace(activeWorkspace);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function deleteWorkspace(id) {
|
||||||
|
if (workspace_tabs.count() == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var ws = RED.nodes.workspace(id);
|
||||||
|
$( "#node-dialog-delete-workspace" ).dialog('option','workspace',ws);
|
||||||
|
$( "#node-dialog-delete-workspace-name" ).text(ws.label);
|
||||||
|
$( "#node-dialog-delete-workspace" ).dialog('open');
|
||||||
|
}
|
||||||
|
|
||||||
//d3.select(window).on("keydown", keydown);
|
//d3.select(window).on("keydown", keydown);
|
||||||
|
|
||||||
function canvasMouseDown() {
|
function canvasMouseDown() {
|
||||||
@ -214,7 +275,7 @@ RED.view = function() {
|
|||||||
clearSelection();
|
clearSelection();
|
||||||
}
|
}
|
||||||
RED.nodes.eachNode(function(n) {
|
RED.nodes.eachNode(function(n) {
|
||||||
if (!n.selected) {
|
if (n.z == activeWorkspace && !n.selected) {
|
||||||
n.selected = (n.x > x && n.x < x2 && n.y > y && n.y < y2);
|
n.selected = (n.x > x && n.x < x2 && n.y > y && n.y < y2);
|
||||||
if (n.selected) {
|
if (n.selected) {
|
||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
@ -281,7 +342,7 @@ RED.view = function() {
|
|||||||
mousePos[1] /= scaleFactor;
|
mousePos[1] /= scaleFactor;
|
||||||
mousePos[0] /= scaleFactor;
|
mousePos[0] /= scaleFactor;
|
||||||
|
|
||||||
var nn = { id:(1+Math.random()*4294967295).toString(16),x: mousePos[0],y:mousePos[1],w:node_width};
|
var nn = { id:(1+Math.random()*4294967295).toString(16),x: mousePos[0],y:mousePos[1],w:node_width,z:activeWorkspace};
|
||||||
|
|
||||||
nn.type = selected_tool;
|
nn.type = selected_tool;
|
||||||
nn._def = RED.nodes.getType(nn.type);
|
nn._def = RED.nodes.getType(nn.type);
|
||||||
@ -323,11 +384,13 @@ RED.view = function() {
|
|||||||
|
|
||||||
function selectAll() {
|
function selectAll() {
|
||||||
RED.nodes.eachNode(function(n) {
|
RED.nodes.eachNode(function(n) {
|
||||||
|
if (n.z == activeWorkspace) {
|
||||||
if (!n.selected) {
|
if (!n.selected) {
|
||||||
n.selected = true;
|
n.selected = true;
|
||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
moving_set.push({n:n});
|
moving_set.push({n:n});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
selected_link = null;
|
selected_link = null;
|
||||||
updateSelection();
|
updateSelection();
|
||||||
@ -587,7 +650,7 @@ RED.view = function() {
|
|||||||
if (mouse_mode != RED.state.JOINING) {
|
if (mouse_mode != RED.state.JOINING) {
|
||||||
// Don't bother redrawing nodes if we're drawing links
|
// Don't bother redrawing nodes if we're drawing links
|
||||||
|
|
||||||
var node = vis.selectAll(".nodegroup").data(RED.nodes.nodes,function(d){return d.id});
|
var node = vis.selectAll(".nodegroup").data(RED.nodes.nodes.filter(function(d) { return d.z == activeWorkspace }),function(d){return d.id});
|
||||||
node.exit().remove();
|
node.exit().remove();
|
||||||
|
|
||||||
var nodeEnter = node.enter().insert("svg:g").attr("class", "node nodegroup");
|
var nodeEnter = node.enter().insert("svg:g").attr("class", "node nodegroup");
|
||||||
@ -811,7 +874,7 @@ RED.view = function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var link = vis.selectAll(".link").data(RED.nodes.links);
|
var link = vis.selectAll(".link").data(RED.nodes.links.filter(function(d) { return d.source.z == activeWorkspace && d.target.z == activeWorkspace }));
|
||||||
|
|
||||||
link.enter().insert("svg:path",".node").attr("class","link")
|
link.enter().insert("svg:path",".node").attr("class","link")
|
||||||
.on("mousedown",function(d) {
|
.on("mousedown",function(d) {
|
||||||
@ -905,7 +968,7 @@ RED.view = function() {
|
|||||||
if (result) {
|
if (result) {
|
||||||
var new_nodes = result[0];
|
var new_nodes = result[0];
|
||||||
var new_links = result[1];
|
var new_links = result[1];
|
||||||
var new_ms = new_nodes.map(function(n) { return {n:n};});
|
var new_ms = new_nodes.map(function(n) { n.z = activeWorkspace; return {n:n};});
|
||||||
var new_node_ids = new_nodes.map(function(n){ return n.id; });
|
var new_node_ids = new_nodes.map(function(n){ return n.id; });
|
||||||
|
|
||||||
// TODO: pick a more sensible root node
|
// TODO: pick a more sensible root node
|
||||||
@ -982,6 +1045,94 @@ RED.view = function() {
|
|||||||
$( "#dialog" ).dialog("option","title","Import nodes").dialog( "open" );
|
$( "#dialog" ).dialog("option","title","Import nodes").dialog( "open" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showRenameWorkspaceDialog(id) {
|
||||||
|
var ws = RED.nodes.workspace(id);
|
||||||
|
$( "#node-dialog-rename-workspace" ).dialog("option","workspace",ws);
|
||||||
|
|
||||||
|
if (workspace_tabs.count() == 1) {
|
||||||
|
$( "#node-dialog-rename-workspace").next().find(".leftButton")
|
||||||
|
.prop('disabled',true)
|
||||||
|
.addClass("ui-state-disabled");
|
||||||
|
} else {
|
||||||
|
$( "#node-dialog-rename-workspace").next().find(".leftButton")
|
||||||
|
.prop('disabled',false)
|
||||||
|
.removeClass("ui-state-disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
$( "#node-input-workspace-name" ).val(ws.label);
|
||||||
|
$( "#node-dialog-rename-workspace" ).dialog("open");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$("#node-dialog-rename-workspace form" ).submit(function(e) { e.preventDefault();});
|
||||||
|
$( "#node-dialog-rename-workspace" ).dialog({
|
||||||
|
modal: true,
|
||||||
|
autoOpen: false,
|
||||||
|
width: 500,
|
||||||
|
title: "Rename workspace",
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
class: 'leftButton',
|
||||||
|
text: "Delete",
|
||||||
|
click: function() {
|
||||||
|
var workspace = $(this).dialog('option','workspace');
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
deleteWorkspace(workspace.id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Ok",
|
||||||
|
click: function() {
|
||||||
|
var workspace = $(this).dialog('option','workspace');
|
||||||
|
var label = $( "#node-input-workspace-name" ).val();
|
||||||
|
if (workspace.label != label) {
|
||||||
|
workspace.label = label;
|
||||||
|
var link = $("#workspace-tabs a[href='#"+workspace.id+"']");
|
||||||
|
link.attr("title",label);
|
||||||
|
link.text(label);
|
||||||
|
RED.view.dirty(true);
|
||||||
|
}
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Cancel",
|
||||||
|
click: function() {
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
$( "#node-dialog-delete-workspace" ).dialog({
|
||||||
|
modal: true,
|
||||||
|
autoOpen: false,
|
||||||
|
width: 500,
|
||||||
|
title: "Confirm delete",
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: "Ok",
|
||||||
|
click: function() {
|
||||||
|
var workspace = $(this).dialog('option','workspace');
|
||||||
|
RED.view.removeWorkspace(workspace);
|
||||||
|
var historyEvent = RED.nodes.removeWorkspace(workspace.id);
|
||||||
|
historyEvent.t = 'delete';
|
||||||
|
historyEvent.dirty = dirty;
|
||||||
|
historyEvent.workspaces = [workspace];
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
RED.view.dirty(true);
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Cancel",
|
||||||
|
click: function() {
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state:function(state) {
|
state:function(state) {
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
@ -990,6 +1141,59 @@ RED.view = function() {
|
|||||||
mouse_mode = state;
|
mouse_mode = state;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
addWorkspace: function(ws) {
|
||||||
|
workspace_tabs.addTab(ws);
|
||||||
|
workspace_tabs.resize();
|
||||||
|
if (workspace_tabs.count() == 1) {
|
||||||
|
$('#btn-workspace-delete').parent().addClass("disabled");
|
||||||
|
} else {
|
||||||
|
$('#btn-workspace-delete').parent().removeClass("disabled");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeWorkspace: function(ws) {
|
||||||
|
workspace_tabs.removeTab(ws.id);
|
||||||
|
$('#workspace-menu-list a[href="#'+ws.id+'"]').parent().remove();
|
||||||
|
if (workspace_tabs.count() == 1) {
|
||||||
|
$('#btn-workspace-delete').parent().addClass("disabled");
|
||||||
|
} else {
|
||||||
|
$('#btn-workspace-delete').parent().removeClass("disabled");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getWorkspace: function() {
|
||||||
|
return activeWorkspace;
|
||||||
|
},
|
||||||
|
setWorkspace: function(z) {
|
||||||
|
var chart = $("#chart");
|
||||||
|
if (activeWorkspace != 0) {
|
||||||
|
workspaceScrollPositions[activeWorkspace] = {
|
||||||
|
left:chart.scrollLeft(),
|
||||||
|
top:chart.scrollTop()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var scrollStartLeft = chart.scrollLeft();
|
||||||
|
var scrollStartTop = chart.scrollTop();
|
||||||
|
|
||||||
|
activeWorkspace = z;
|
||||||
|
if (workspaceScrollPositions[activeWorkspace]) {
|
||||||
|
chart.scrollLeft(workspaceScrollPositions[activeWorkspace].left);
|
||||||
|
chart.scrollTop(workspaceScrollPositions[activeWorkspace].top);
|
||||||
|
} else {
|
||||||
|
chart.scrollLeft(0);
|
||||||
|
chart.scrollTop(0);
|
||||||
|
}
|
||||||
|
var scrollDeltaLeft = chart.scrollLeft() - scrollStartLeft;
|
||||||
|
var scrollDeltaTop = chart.scrollTop() - scrollStartTop;
|
||||||
|
if (mouse_position != null) {
|
||||||
|
mouse_position[0] += scrollDeltaLeft;
|
||||||
|
mouse_position[1] += scrollDeltaTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearSelection();
|
||||||
|
RED.nodes.eachNode(function(n) {
|
||||||
|
n.dirty = true;
|
||||||
|
});
|
||||||
|
redraw();
|
||||||
|
},
|
||||||
redraw:redraw,
|
redraw:redraw,
|
||||||
dirty: function(d) {
|
dirty: function(d) {
|
||||||
if (d == null) {
|
if (d == null) {
|
||||||
@ -998,6 +1202,9 @@ RED.view = function() {
|
|||||||
setDirty(d);
|
setDirty(d);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
importNodes: importNodes
|
importNodes: importNodes,
|
||||||
|
resize: function() {
|
||||||
|
workspace_tabs.resize();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}();
|
}();
|
||||||
|
100
public/style.css
100
public/style.css
@ -40,10 +40,19 @@ a.brand img {
|
|||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chart {
|
#workspace {
|
||||||
margin-left: 160px;
|
margin-left: 160px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chart {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background: #e3e3e3;
|
background: #e3e3e3;
|
||||||
|
position: absolute;
|
||||||
|
bottom:0px;
|
||||||
|
top: 30px;
|
||||||
|
left:0px;
|
||||||
|
right:0px;
|
||||||
}
|
}
|
||||||
#chart-zoom-controls {
|
#chart-zoom-controls {
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
@ -144,6 +153,7 @@ a.brand img {
|
|||||||
|
|
||||||
#sidebar {
|
#sidebar {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
#sidebar.closing {
|
#sidebar.closing {
|
||||||
background: #eee;
|
background: #eee;
|
||||||
@ -161,7 +171,7 @@ a.brand img {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px; left:10px; bottom: 10px;
|
top: 5px; left:10px; bottom: 10px;
|
||||||
}
|
}
|
||||||
#chart {
|
#workspace {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
top:5px; left:160px; bottom: 10px; right: 330px;
|
top:5px; left:160px; bottom: 10px; right: 330px;
|
||||||
@ -184,7 +194,7 @@ a.brand img {
|
|||||||
|
|
||||||
.sidebar-closed > #sidebar { display: none; }
|
.sidebar-closed > #sidebar { display: none; }
|
||||||
.sidebar-closed > #sidebar-separator { display: none; }
|
.sidebar-closed > #sidebar-separator { display: none; }
|
||||||
.sidebar-closed > #chart { right: 10px !important; }
|
.sidebar-closed > #workspace { right: 10px !important; }
|
||||||
.sidebar-closed > #chart-zoom-controls { right: 30px !important; }
|
.sidebar-closed > #chart-zoom-controls { right: 30px !important; }
|
||||||
|
|
||||||
/* ---------- end layout ---------- */
|
/* ---------- end layout ---------- */
|
||||||
@ -224,14 +234,15 @@ a.brand img {
|
|||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chart, #palette, #sidebar {
|
#workspace, #palette, #sidebar {
|
||||||
border: 1px solid #000;
|
border: 1px solid #000;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
#sidebar-content {
|
#sidebar-content {
|
||||||
|
font-size: 1.2em;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50px; left: 5px; right: 0; bottom: 1px;
|
top: 30px; left: 0px; right: 0; bottom: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.node_label_italic {
|
.node_label_italic {
|
||||||
@ -558,3 +569,82 @@ div.node-info {
|
|||||||
border-radius:5px;
|
border-radius:5px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
#workspace-tabs {
|
||||||
|
margin-right: 28px;
|
||||||
|
}
|
||||||
|
#workspace-add-tab {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 29px;
|
||||||
|
width: 28px;
|
||||||
|
border-bottom: 1px solid #999;
|
||||||
|
}
|
||||||
|
#btn-workspace-add-tab {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
background: #e3e3e3;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 28px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#btn-workspace-add-tab:hover {
|
||||||
|
background: #efefef;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.red-ui-tabs {
|
||||||
|
list-style-type: none;
|
||||||
|
padding:5px 2px 0px 5px;
|
||||||
|
margin: 0;
|
||||||
|
display: block;
|
||||||
|
height: 24px;
|
||||||
|
border-bottom: 1px solid #999;
|
||||||
|
background: #e3e3e3;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.red-ui-tabs li {
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 1px solid #999;
|
||||||
|
border-top: 1px solid #999;
|
||||||
|
border-right: 1px solid #999;
|
||||||
|
border-bottom: 1px solid #999;
|
||||||
|
background: #e3e3e3;
|
||||||
|
margin: 0 5px 0 0;
|
||||||
|
height: 23px;
|
||||||
|
line-height: 17px;
|
||||||
|
max-width: 150px;
|
||||||
|
width: 14%;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.red-ui-tabs li a {
|
||||||
|
display: block;
|
||||||
|
padding: 3px 16px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
ul.red-ui-tabs li a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.red-ui-tabs li.active {
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid #fff;
|
||||||
|
}
|
||||||
|
ul.red-ui-tabs li.active a {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
ul.red-ui-tabs li.active a:hover {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
ul.red-ui-tabs li.red-ui-add-tab {
|
||||||
|
width: 25px;
|
||||||
|
border-top-right-radius: 15px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
ul.red-ui-tabs li.red-ui-add-tab a {
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
30
red/nodes.js
30
red/nodes.js
@ -292,9 +292,11 @@ var parseConfig = function() {
|
|||||||
missingTypes = [];
|
missingTypes = [];
|
||||||
for (var i in activeConfig) {
|
for (var i in activeConfig) {
|
||||||
var type = activeConfig[i].type;
|
var type = activeConfig[i].type;
|
||||||
var nt = node_type_registry.get(type);
|
if (type != "workspace") {
|
||||||
if (!nt && missingTypes.indexOf(type) == -1) {
|
var nt = node_type_registry.get(type);
|
||||||
missingTypes.push(type);
|
if (!nt && missingTypes.indexOf(type) == -1) {
|
||||||
|
missingTypes.push(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (missingTypes.length > 0) {
|
if (missingTypes.length > 0) {
|
||||||
@ -309,19 +311,21 @@ var parseConfig = function() {
|
|||||||
events.emit("nodes-starting");
|
events.emit("nodes-starting");
|
||||||
for (var i in activeConfig) {
|
for (var i in activeConfig) {
|
||||||
var nn = null;
|
var nn = null;
|
||||||
var nt = node_type_registry.get(activeConfig[i].type);
|
if (activeConfig[i].type != "workspace") {
|
||||||
if (nt) {
|
var nt = node_type_registry.get(activeConfig[i].type);
|
||||||
try {
|
if (nt) {
|
||||||
nn = new nt(activeConfig[i]);
|
try {
|
||||||
|
nn = new nt(activeConfig[i]);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
util.log("[red] "+activeConfig[i].type+" : "+err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
// console.log(nn);
|
||||||
util.log("[red] "+activeConfig[i].type+" : "+err);
|
if (nn == null) {
|
||||||
|
util.log("[red] unknown type: "+activeConfig[i].type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// console.log(nn);
|
|
||||||
if (nn == null) {
|
|
||||||
util.log("[red] unknown type: "+activeConfig[i].type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Clean up any orphaned credentials
|
// Clean up any orphaned credentials
|
||||||
var deletedCredentials = false;
|
var deletedCredentials = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user