mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
commit
87e537da90
31
Gruntfile.js
31
Gruntfile.js
@ -118,6 +118,24 @@ module.exports = function(grunt) {
|
|||||||
"editor/js/ui/touch/radialMenu.js"
|
"editor/js/ui/touch/radialMenu.js"
|
||||||
],
|
],
|
||||||
dest: "public/red/red.js"
|
dest: "public/red/red.js"
|
||||||
|
},
|
||||||
|
vendor: {
|
||||||
|
files: {
|
||||||
|
"public/vendor/vendor.js": [
|
||||||
|
"editor/vendor/jquery/js/jquery-1.11.1.min.js",
|
||||||
|
"editor/vendor/bootstrap/js/bootstrap.min.js",
|
||||||
|
"editor/vendor/jquery/js/jquery-ui-1.10.3.custom.min.js",
|
||||||
|
"editor/vendor/jquery/js/jquery.ui.touch-punch.min.js",
|
||||||
|
"editor/vendor/marked/marked.min.js",
|
||||||
|
"editor/vendor/orion/built-editor.min.js",
|
||||||
|
"editor/vendor/d3/d3.v3.min.js"
|
||||||
|
],
|
||||||
|
"public/vendor/vendor.css": [
|
||||||
|
"editor/vendor/orion/built-editor.css"
|
||||||
|
// TODO: resolve relative resource paths in
|
||||||
|
// bootstrap/FA/jquery
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
uglify: {
|
uglify: {
|
||||||
@ -214,7 +232,13 @@ module.exports = function(grunt) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
cwd: 'editor/vendor',
|
cwd: 'editor/vendor',
|
||||||
src: '**',
|
src: [
|
||||||
|
'ace/**',
|
||||||
|
'bootstrap/css/**',
|
||||||
|
'bootstrap/img/**',
|
||||||
|
'jquery/css/**',
|
||||||
|
'font-awesome/**'
|
||||||
|
],
|
||||||
expand: true,
|
expand: true,
|
||||||
dest: 'public/vendor/'
|
dest: 'public/vendor/'
|
||||||
},
|
},
|
||||||
@ -244,7 +268,8 @@ module.exports = function(grunt) {
|
|||||||
'nodes/*.demo',
|
'nodes/*.demo',
|
||||||
'nodes/core/**',
|
'nodes/core/**',
|
||||||
'red/**',
|
'red/**',
|
||||||
'public/**'
|
'public/**',
|
||||||
|
'editor/templates/**'
|
||||||
],
|
],
|
||||||
dest: path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>')
|
dest: path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>')
|
||||||
}]
|
}]
|
||||||
@ -333,7 +358,7 @@ module.exports = function(grunt) {
|
|||||||
|
|
||||||
grunt.registerTask('build',
|
grunt.registerTask('build',
|
||||||
'Builds editor content',
|
'Builds editor content',
|
||||||
['clean:build','concat:build','uglify:build','sass:build','copy:build','attachCopyright']);
|
['clean:build','concat:build','concat:vendor','uglify:build','sass:build','copy:build','attachCopyright']);
|
||||||
|
|
||||||
grunt.registerTask('dev',
|
grunt.registerTask('dev',
|
||||||
'Developer mode: run node-red, watch for source changes and build/restart',
|
'Developer mode: run node-red, watch for source changes and build/restart',
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
<title>Node-RED</title>
|
<title>Node-RED</title>
|
||||||
<link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
|
<link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
|
||||||
<link href="vendor/jquery/css/smoothness/jquery-ui-1.10.3.custom.min.css" rel="stylesheet" media="screen">
|
<link href="vendor/jquery/css/smoothness/jquery-ui-1.10.3.custom.min.css" rel="stylesheet" media="screen">
|
||||||
<link rel="stylesheet" type="text/css" href="vendor/orion/built-editor.css"/>
|
<link rel="stylesheet" href="vendor/font-awesome/css/font-awesome.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="vendor/font-awesome/css/font-awesome.min.css"/>
|
<link rel="stylesheet" href="vendor/vendor.css">
|
||||||
<link rel="stylesheet" href="red/style.min.css">
|
<link rel="stylesheet" href="red/style.min.css">
|
||||||
</head>
|
</head>
|
||||||
<body spellcheck="false">
|
<body spellcheck="false">
|
||||||
@ -168,15 +168,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="vendor/jquery/js/jquery-1.11.1.min.js"></script>
|
<script src="vendor/vendor.js"></script>
|
||||||
<script src="vendor/bootstrap/js/bootstrap.min.js"></script>
|
|
||||||
<script src="vendor/jquery/js/jquery-ui-1.10.3.custom.min.js"></script>
|
|
||||||
<script src="vendor/jquery/js/jquery.ui.touch-punch.min.js"></script>
|
|
||||||
<script src="vendor/marked/marked.min.js"></script>
|
|
||||||
<script src="vendor/orion/built-editor.min.js"></script>
|
|
||||||
<script src="vendor/ace/ace.js"></script>
|
<script src="vendor/ace/ace.js"></script>
|
||||||
<script src="vendor/ace/ext-language_tools.js"></script>
|
<script src="vendor/ace/ext-language_tools.js"></script>
|
||||||
<script src="vendor/d3/d3.v3.min.js"></script>
|
|
||||||
<script src="red/red.min.js"></script>
|
<script src="red/red.min.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -138,34 +138,37 @@ var RED = (function() {
|
|||||||
function loadEditor() {
|
function loadEditor() {
|
||||||
RED.menu.init({id:"btn-sidemenu",
|
RED.menu.init({id:"btn-sidemenu",
|
||||||
options: [
|
options: [
|
||||||
{id:"btn-sidebar",label:"Sidebar",toggle:true,onselect:RED.sidebar.toggleSidebar, selected: true},
|
{id:"menu-item-sidebar",label:"Sidebar",toggle:true,onselect:RED.sidebar.toggleSidebar, selected: true},
|
||||||
{id:"btn-node-status",label:"Display node status",toggle:true,onselect:toggleStatus, selected: true},
|
{id:"menu-item-status",label:"Display node status",toggle:true,onselect:toggleStatus, selected: true},
|
||||||
null,
|
null,
|
||||||
{id:"btn-import-menu",label:"Import",options:[
|
{id:"menu-item-import",label:"Import",options:[
|
||||||
{id:"btn-import-clipboard",label:"Clipboard",onselect:RED.clipboard.import},
|
{id:"menu-item-import-clipboard",label:"Clipboard",onselect:RED.clipboard.import},
|
||||||
{id:"btn-import-library",label:"Library",options:[]}
|
{id:"menu-item-import-library",label:"Library",options:[]}
|
||||||
]},
|
]},
|
||||||
{id:"btn-export-menu",label:"Export",disabled:true,options:[
|
{id:"menu-item-export",label:"Export",disabled:true,options:[
|
||||||
{id:"btn-export-clipboard",label:"Clipboard",disabled:true,onselect:RED.clipboard.export},
|
{id:"menu-item-export-clipboard",label:"Clipboard",disabled:true,onselect:RED.clipboard.export},
|
||||||
{id:"btn-export-library",label:"Library",disabled:true,onselect:RED.library.export}
|
{id:"menu-item-export-library",label:"Library",disabled:true,onselect:RED.library.export}
|
||||||
]},
|
]},
|
||||||
null,
|
null,
|
||||||
{id:"btn-config-nodes",label:"Configuration nodes",onselect:RED.sidebar.config.show},
|
{id:"menu-item-config-nodes",label:"Configuration nodes",onselect:RED.sidebar.config.show},
|
||||||
null,
|
null,
|
||||||
{id:"btn-subflow-menu",label:"Subflows", options: [
|
{id:"menu-item-subflow",label:"Subflows", options: [
|
||||||
{id:"btn-create-subflow",label:"Create subflow",onselect:RED.subflow.createSubflow},
|
{id:"menu-item-subflow-create",label:"Create subflow",onselect:RED.subflow.createSubflow},
|
||||||
{id:"btn-convert-subflow",label:"Selection to subflow",disabled:true,onselect:RED.subflow.convertToSubflow},
|
{id:"menu-item-subflow-convert",label:"Selection to subflow",disabled:true,onselect:RED.subflow.convertToSubflow},
|
||||||
]},
|
]},
|
||||||
null,
|
null,
|
||||||
{id:"btn-workspace-menu",label:"Workspaces",options:[
|
{id:"menu-item-workspace",label:"Workspaces",options:[
|
||||||
{id:"btn-workspace-add",label:"Add",onselect:RED.workspaces.add},
|
{id:"menu-item-workspace-add",label:"Add",onselect:RED.workspaces.add},
|
||||||
{id:"btn-workspace-edit",label:"Rename",onselect:RED.workspaces.edit},
|
{id:"menu-item-workspace-edit",label:"Rename",onselect:RED.workspaces.edit},
|
||||||
{id:"btn-workspace-delete",label:"Delete",onselect:RED.workspaces.remove},
|
{id:"menu-item-workspace-delete",label:"Delete",onselect:RED.workspaces.remove},
|
||||||
null
|
null
|
||||||
]},
|
]},
|
||||||
null,
|
null,
|
||||||
{id:"btn-keyboard-shortcuts",label:"Keyboard Shortcuts",onselect:RED.keyboard.showHelp},
|
{id:"menu-item-keyboard-shortcuts",label:"Keyboard Shortcuts",onselect:RED.keyboard.showHelp},
|
||||||
{id:"btn-help",label:"Node-RED Website", href:"http://nodered.org/docs"}
|
{id:"menu-item-help",
|
||||||
|
label: RED.settings.theme("menu.menu-item-help.label","Node-RED Website"),
|
||||||
|
href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs")
|
||||||
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -178,7 +181,8 @@ var RED = (function() {
|
|||||||
RED.workspaces.init();
|
RED.workspaces.init();
|
||||||
RED.clipboard.init();
|
RED.clipboard.init();
|
||||||
RED.view.init();
|
RED.view.init();
|
||||||
RED.deploy.init();
|
|
||||||
|
RED.deploy.init(RED.settings.theme("deployButton",null));
|
||||||
|
|
||||||
RED.keyboard.add(/* ? */ 191,{shift:true},function(){RED.keyboard.showHelp();d3.event.preventDefault();});
|
RED.keyboard.add(/* ? */ 191,{shift:true},function(){RED.keyboard.showHelp();d3.event.preventDefault();});
|
||||||
RED.comms.connect();
|
RED.comms.connect();
|
||||||
@ -192,7 +196,7 @@ var RED = (function() {
|
|||||||
$(function() {
|
$(function() {
|
||||||
|
|
||||||
if ((window.location.hostname !== "localhost") && (window.location.hostname !== "127.0.0.1")) {
|
if ((window.location.hostname !== "localhost") && (window.location.hostname !== "127.0.0.1")) {
|
||||||
document.title = "Node-RED : "+window.location.hostname;
|
document.title = document.title+" : "+window.location.hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
ace.require("ace/ext/language_tools");
|
ace.require("ace/ext/language_tools");
|
||||||
|
@ -119,13 +119,30 @@ RED.settings = (function () {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function theme(property,defaultValue) {
|
||||||
|
if (!RED.settings.editorTheme) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
var parts = property.split(".");
|
||||||
|
var v = RED.settings.editorTheme;
|
||||||
|
try {
|
||||||
|
for (var i=0;i<parts.length;i++) {
|
||||||
|
v = v[parts[i]];
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
} catch(err) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
load: load,
|
load: load,
|
||||||
set: set,
|
set: set,
|
||||||
get: get,
|
get: get,
|
||||||
remove: remove
|
remove: remove,
|
||||||
|
|
||||||
|
theme: theme
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
();
|
();
|
||||||
|
@ -129,13 +129,13 @@ RED.clipboard = (function() {
|
|||||||
init: function() {
|
init: function() {
|
||||||
RED.view.on("selection-changed",function(selection) {
|
RED.view.on("selection-changed",function(selection) {
|
||||||
if (!selection.nodes) {
|
if (!selection.nodes) {
|
||||||
RED.menu.setDisabled("btn-export-menu",true);
|
RED.menu.setDisabled("menu-item-export",true);
|
||||||
RED.menu.setDisabled("btn-export-clipboard",true);
|
RED.menu.setDisabled("menu-item-export-clipboard",true);
|
||||||
RED.menu.setDisabled("btn-export-library",true);
|
RED.menu.setDisabled("menu-item-export-library",true);
|
||||||
} else {
|
} else {
|
||||||
RED.menu.setDisabled("btn-export-menu",false);
|
RED.menu.setDisabled("menu-item-export",false);
|
||||||
RED.menu.setDisabled("btn-export-clipboard",false);
|
RED.menu.setDisabled("menu-item-export-clipboard",false);
|
||||||
RED.menu.setDisabled("btn-export-library",false);
|
RED.menu.setDisabled("menu-item-export-library",false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
RED.keyboard.add(/* e */ 69,{ctrl:true},function(){exportNodes();d3.event.preventDefault();});
|
RED.keyboard.add(/* e */ 69,{ctrl:true},function(){exportNodes();d3.event.preventDefault();});
|
||||||
|
@ -29,12 +29,43 @@ RED.deploy = (function() {
|
|||||||
$("#btn-deploy img").attr("src",deploymentTypes[type].img);
|
$("#btn-deploy img").attr("src",deploymentTypes[type].img);
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
|
||||||
|
|
||||||
var deployButton = $('<li><span class="deploy-button-group button-group">'+
|
/**
|
||||||
'<a id="btn-deploy" class="action-deploy disabled" href="#"><img id="btn-icn-deploy" src="red/images/deploy-full-o.png"> <span>Deploy</span></a>'+
|
* options:
|
||||||
'<a id="btn-deploy-options" data-toggle="dropdown" class="" href="#"><i class="fa fa-caret-down"></i></a>'+
|
* type: "default" - Button with drop-down options - no further customisation available
|
||||||
'</span></li>').prependTo(".header-toolbar");
|
* type: "simple" - Button without dropdown. Customisations:
|
||||||
|
* label: the text to display - default: "Deploy"
|
||||||
|
* icon : the icon to use. Null removes the icon. default: "red/images/deploy-full-o.png"
|
||||||
|
*/
|
||||||
|
function init(options) {
|
||||||
|
options = options || {};
|
||||||
|
var type = options.type || "default";
|
||||||
|
|
||||||
|
if (type == "default") {
|
||||||
|
$('<li><span class="deploy-button-group button-group">'+
|
||||||
|
'<a id="btn-deploy" class="deploy-button disabled" href="#"><img id="btn-deploy-icon" src="red/images/deploy-full-o.png"> <span>Deploy</span></a>'+
|
||||||
|
'<a id="btn-deploy-options" data-toggle="dropdown" class="deploy-button" href="#"><i class="fa fa-caret-down"></i></a>'+
|
||||||
|
'</span></li>').prependTo(".header-toolbar");
|
||||||
|
RED.menu.init({id:"btn-deploy-options",
|
||||||
|
options: [
|
||||||
|
{id:"deploymenu-item-full",toggle:"deploy-type",icon:"red/images/deploy-full.png",label:"Full",sublabel:"Deploys everything in the workspace",onselect:function(s) { if(s){changeDeploymentType("full")}}},
|
||||||
|
{id:"deploymenu-item-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.png",label:"Modified Flows",sublabel:"Only deploys flows that contain changed nodes", onselect:function(s) {if(s){changeDeploymentType("flows")}}},
|
||||||
|
{id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.png",label:"Modified Nodes",sublabel:"Only deploys nodes that have changed",onselect:function(s) { if(s){changeDeploymentType("nodes")}}}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
} else if (type == "simple") {
|
||||||
|
var label = options.label || "Deploy";
|
||||||
|
var icon = 'red/images/deploy-full-o.png';
|
||||||
|
if (options.hasOwnProperty('icon')) {
|
||||||
|
icon = options.icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('<li><span class="deploy-button-group button-group">'+
|
||||||
|
'<a id="btn-deploy" class="deploy-button disabled" href="#">'+
|
||||||
|
(icon?'<img id="btn-deploy-icon" src="'+icon+'"> ':'')+
|
||||||
|
'<span>'+label+'</span></a>'+
|
||||||
|
'</span></li>').prependTo(".header-toolbar");
|
||||||
|
}
|
||||||
|
|
||||||
$('#btn-deploy').click(function() { save(); });
|
$('#btn-deploy').click(function() { save(); });
|
||||||
|
|
||||||
@ -61,14 +92,6 @@ RED.deploy = (function() {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
RED.menu.init({id:"btn-deploy-options",
|
|
||||||
options: [
|
|
||||||
{id:"btn-deploy-full",toggle:"deploy-type",icon:"red/images/deploy-full.png",label:"Full",sublabel:"Deploys everything in the workspace",onselect:function(s) { if(s){changeDeploymentType("full")}}},
|
|
||||||
{id:"btn-deploy-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.png",label:"Modified Flows",sublabel:"Only deploys flows that contain changed nodes", onselect:function(s) {if(s){changeDeploymentType("flows")}}},
|
|
||||||
{id:"btn-deploy-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.png",label:"Modified Nodes",sublabel:"Only deploys nodes that have changed",onselect:function(s) { if(s){changeDeploymentType("nodes")}}}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
RED.nodes.on('change',function(state) {
|
RED.nodes.on('change',function(state) {
|
||||||
if (state.dirty) {
|
if (state.dirty) {
|
||||||
window.onbeforeunload = function() {
|
window.onbeforeunload = function() {
|
||||||
@ -114,8 +137,8 @@ RED.deploy = (function() {
|
|||||||
}
|
}
|
||||||
var nns = RED.nodes.createCompleteNodeSet();
|
var nns = RED.nodes.createCompleteNodeSet();
|
||||||
|
|
||||||
$("#btn-icn-deploy").removeClass('fa-download');
|
$("#btn-deploy-icon").removeClass('fa-download');
|
||||||
$("#btn-icn-deploy").addClass('spinner');
|
$("#btn-deploy-icon").addClass('spinner');
|
||||||
RED.nodes.dirty(false);
|
RED.nodes.dirty(false);
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -153,8 +176,8 @@ RED.deploy = (function() {
|
|||||||
RED.notify("<strong>Error</strong>: no response from server","error");
|
RED.notify("<strong>Error</strong>: no response from server","error");
|
||||||
}
|
}
|
||||||
}).always(function() {
|
}).always(function() {
|
||||||
$("#btn-icn-deploy").removeClass('spinner');
|
$("#btn-deploy-icon").removeClass('spinner');
|
||||||
$("#btn-icn-deploy").addClass('fa-download');
|
$("#btn-deploy-icon").addClass('fa-download');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -786,7 +786,7 @@ RED.editor = (function() {
|
|||||||
changes['name'] = editing_node.name;
|
changes['name'] = editing_node.name;
|
||||||
editing_node.name = newName;
|
editing_node.name = newName;
|
||||||
changed = true;
|
changed = true;
|
||||||
$("#btn-workspace-menu-"+editing_node.id.replace(".","-")).text("Subflow: "+newName);
|
$("#menu-item-workspace-menu-"+editing_node.id.replace(".","-")).text("Subflow: "+newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
RED.palette.refresh();
|
RED.palette.refresh();
|
||||||
|
@ -59,46 +59,53 @@ RED.keyboard = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var dialog = $('<div id="keyboard-help-dialog" class="hide">'+
|
var dialog = null;
|
||||||
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
|
|
||||||
'<table class="keyboard-shortcuts">'+
|
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">a</span></td><td>Select all nodes</td></tr>'+
|
|
||||||
'<tr><td><span class="help-key">Shift</span> + <span class="help-key">Click</span></td><td>Select all connected nodes</td></tr>'+
|
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">Click</span></td><td>Add/remove node from selection</td></tr>'+
|
|
||||||
'<tr><td><span class="help-key">Delete</span></td><td>Delete selected nodes or link</td></tr>'+
|
|
||||||
'<tr><td> </td><td></td></tr>'+
|
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">i</span></td><td>Import nodes</td></tr>'+
|
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">e</span></td><td>Export selected nodes</td></tr>'+
|
|
||||||
'</table>'+
|
|
||||||
'</div>'+
|
|
||||||
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
|
|
||||||
'<table class="keyboard-shortcuts">'+
|
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">Space</span></td><td>Toggle sidebar</td></tr>'+
|
|
||||||
'<tr><td></td><td></td></tr>'+
|
|
||||||
'<tr><td><span class="help-key">Delete</span></td><td>Delete selected nodes or link</td></tr>'+
|
|
||||||
'<tr><td></td><td></td></tr>'+
|
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">c</span></td><td>Copy selected nodes</td></tr>'+
|
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">x</span></td><td>Cut selected nodes</td></tr>'+
|
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">v</span></td><td>Paste nodes</td></tr>'+
|
|
||||||
'</table>'+
|
|
||||||
'</div>'+
|
|
||||||
'</div>')
|
|
||||||
.appendTo("body")
|
|
||||||
.dialog({
|
|
||||||
modal: true,
|
|
||||||
autoOpen: false,
|
|
||||||
width: "800",
|
|
||||||
title:"Keyboard shortcuts",
|
|
||||||
resizable: false,
|
|
||||||
open: function() {
|
|
||||||
RED.keyboard.disable();
|
|
||||||
},
|
|
||||||
close: function() {
|
|
||||||
RED.keyboard.enable();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function showKeyboardHelp() {
|
function showKeyboardHelp() {
|
||||||
|
if (!RED.settings.theme("menu.menu-item-keyboard-shortcuts",true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!dialog) {
|
||||||
|
dialog = $('<div id="keyboard-help-dialog" class="hide">'+
|
||||||
|
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
|
||||||
|
'<table class="keyboard-shortcuts">'+
|
||||||
|
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">a</span></td><td>Select all nodes</td></tr>'+
|
||||||
|
'<tr><td><span class="help-key">Shift</span> + <span class="help-key">Click</span></td><td>Select all connected nodes</td></tr>'+
|
||||||
|
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">Click</span></td><td>Add/remove node from selection</td></tr>'+
|
||||||
|
'<tr><td><span class="help-key">Delete</span></td><td>Delete selected nodes or link</td></tr>'+
|
||||||
|
'<tr><td> </td><td></td></tr>'+
|
||||||
|
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">i</span></td><td>Import nodes</td></tr>'+
|
||||||
|
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">e</span></td><td>Export selected nodes</td></tr>'+
|
||||||
|
'</table>'+
|
||||||
|
'</div>'+
|
||||||
|
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
|
||||||
|
'<table class="keyboard-shortcuts">'+
|
||||||
|
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">Space</span></td><td>Toggle sidebar</td></tr>'+
|
||||||
|
'<tr><td></td><td></td></tr>'+
|
||||||
|
'<tr><td><span class="help-key">Delete</span></td><td>Delete selected nodes or link</td></tr>'+
|
||||||
|
'<tr><td></td><td></td></tr>'+
|
||||||
|
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">c</span></td><td>Copy selected nodes</td></tr>'+
|
||||||
|
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">x</span></td><td>Cut selected nodes</td></tr>'+
|
||||||
|
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">v</span></td><td>Paste nodes</td></tr>'+
|
||||||
|
'</table>'+
|
||||||
|
'</div>'+
|
||||||
|
'</div>')
|
||||||
|
.appendTo("body")
|
||||||
|
.dialog({
|
||||||
|
modal: true,
|
||||||
|
autoOpen: false,
|
||||||
|
width: "800",
|
||||||
|
title:"Keyboard shortcuts",
|
||||||
|
resizable: false,
|
||||||
|
open: function() {
|
||||||
|
RED.keyboard.disable();
|
||||||
|
},
|
||||||
|
close: function() {
|
||||||
|
RED.keyboard.enable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
dialog.dialog("open");
|
dialog.dialog("open");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ RED.library = (function() {
|
|||||||
var li;
|
var li;
|
||||||
var a;
|
var a;
|
||||||
var ul = document.createElement("ul");
|
var ul = document.createElement("ul");
|
||||||
ul.id = "btn-import-library-submenu";
|
ul.id = "menu-item-import-library-submenu";
|
||||||
ul.className = "dropdown-menu";
|
ul.className = "dropdown-menu";
|
||||||
if (data.d) {
|
if (data.d) {
|
||||||
for (i in data.d) {
|
for (i in data.d) {
|
||||||
@ -63,7 +63,7 @@ RED.library = (function() {
|
|||||||
};
|
};
|
||||||
var menu = buildMenu(data,"");
|
var menu = buildMenu(data,"");
|
||||||
//TODO: need an api in RED.menu for this
|
//TODO: need an api in RED.menu for this
|
||||||
$("#btn-import-library-submenu").replaceWith(menu);
|
$("#menu-item-import-library-submenu").replaceWith(menu);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,17 +392,19 @@ RED.library = (function() {
|
|||||||
init: function() {
|
init: function() {
|
||||||
RED.view.on("selection-changed",function(selection) {
|
RED.view.on("selection-changed",function(selection) {
|
||||||
if (!selection.nodes) {
|
if (!selection.nodes) {
|
||||||
RED.menu.setDisabled("btn-export-menu",true);
|
RED.menu.setDisabled("menu-item-export",true);
|
||||||
RED.menu.setDisabled("btn-export-clipboard",true);
|
RED.menu.setDisabled("menu-item-export-clipboard",true);
|
||||||
RED.menu.setDisabled("btn-export-library",true);
|
RED.menu.setDisabled("menu-item-export-library",true);
|
||||||
} else {
|
} else {
|
||||||
RED.menu.setDisabled("btn-export-menu",false);
|
RED.menu.setDisabled("menu-item-export",false);
|
||||||
RED.menu.setDisabled("btn-export-clipboard",false);
|
RED.menu.setDisabled("menu-item-export-clipboard",false);
|
||||||
RED.menu.setDisabled("btn-export-library",false);
|
RED.menu.setDisabled("menu-item-export-library",false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
loadFlowLibrary();
|
if (RED.settings.theme("menu.menu-item-import-library") !== false) {
|
||||||
|
loadFlowLibrary();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
create: createUI,
|
create: createUI,
|
||||||
loadFlowLibrary: loadFlowLibrary,
|
loadFlowLibrary: loadFlowLibrary,
|
||||||
|
@ -23,6 +23,13 @@ RED.menu = (function() {
|
|||||||
function createMenuItem(opt) {
|
function createMenuItem(opt) {
|
||||||
var item;
|
var item;
|
||||||
|
|
||||||
|
if (opt !== null && opt.id) {
|
||||||
|
var themeSetting = RED.settings.theme("menu."+opt.id);
|
||||||
|
if (themeSetting === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setState() {
|
function setState() {
|
||||||
var savedStateActive = isSavedStateActive(opt.id);
|
var savedStateActive = isSavedStateActive(opt.id);
|
||||||
if (savedStateActive) {
|
if (savedStateActive) {
|
||||||
@ -113,7 +120,10 @@ RED.menu = (function() {
|
|||||||
var submenu = $('<ul id="'+opt.id+'-submenu" class="dropdown-menu"></ul>').appendTo(item);
|
var submenu = $('<ul id="'+opt.id+'-submenu" class="dropdown-menu"></ul>').appendTo(item);
|
||||||
|
|
||||||
for (var i=0;i<opt.options.length;i++) {
|
for (var i=0;i<opt.options.length;i++) {
|
||||||
createMenuItem(opt.options[i]).appendTo(submenu);
|
var li = createMenuItem(opt.options[i]);
|
||||||
|
if (li) {
|
||||||
|
li.appendTo(submenu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opt.disabled) {
|
if (opt.disabled) {
|
||||||
@ -148,9 +158,16 @@ RED.menu = (function() {
|
|||||||
|
|
||||||
var topMenu = $("<ul/>",{id:options.id+"-submenu", class:"dropdown-menu pull-right"}).insertAfter(button);
|
var topMenu = $("<ul/>",{id:options.id+"-submenu", class:"dropdown-menu pull-right"}).insertAfter(button);
|
||||||
|
|
||||||
|
var lastAddedSeparator = false;
|
||||||
for (var i=0;i<options.options.length;i++) {
|
for (var i=0;i<options.options.length;i++) {
|
||||||
var opt = options.options[i];
|
var opt = options.options[i];
|
||||||
createMenuItem(opt).appendTo(topMenu);
|
if (opt !== null || !lastAddedSeparator) {
|
||||||
|
var li = createMenuItem(opt);
|
||||||
|
if (li) {
|
||||||
|
li.appendTo(topMenu);
|
||||||
|
lastAddedSeparator = (opt === null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +193,7 @@ RED.menu = (function() {
|
|||||||
} else {
|
} else {
|
||||||
$("#"+id).removeClass("active");
|
$("#"+id).removeClass("active");
|
||||||
}
|
}
|
||||||
if (opt.onselect) {
|
if (opt && opt.onselect) {
|
||||||
opt.onselect.call(opt,state);
|
opt.onselect.call(opt,state);
|
||||||
}
|
}
|
||||||
setSavedState(id, state);
|
setSavedState(id, state);
|
||||||
@ -198,17 +215,20 @@ RED.menu = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setAction(id,action) {
|
function setAction(id,action) {
|
||||||
menuItems[id].onselect = action;
|
var opt = menuItems[id];
|
||||||
$("#"+id).click(function() {
|
if (opt) {
|
||||||
if ($(this).parent().hasClass("disabled")) {
|
opt.onselect = action;
|
||||||
return;
|
$("#"+id).click(function() {
|
||||||
}
|
if ($(this).parent().hasClass("disabled")) {
|
||||||
if (menuItems[id].toggle) {
|
return;
|
||||||
setSelected(id,!isSelected(id));
|
}
|
||||||
} else {
|
if (menuItems[id].toggle) {
|
||||||
menuItems[id].onselect.call(menuItems[id]);
|
setSelected(id,!isSelected(id));
|
||||||
}
|
} else {
|
||||||
});
|
menuItems[id].onselect.call(menuItems[id]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -51,14 +51,14 @@ RED.sidebar = (function() {
|
|||||||
sidebarSeparator.chartRight = winWidth-$("#workspace").width()-$("#workspace").offset().left-2;
|
sidebarSeparator.chartRight = winWidth-$("#workspace").width()-$("#workspace").offset().left-2;
|
||||||
|
|
||||||
|
|
||||||
if (!RED.menu.isSelected("btn-sidebar")) {
|
if (!RED.menu.isSelected("menu-item-sidebar")) {
|
||||||
sidebarSeparator.opening = true;
|
sidebarSeparator.opening = true;
|
||||||
var newChartRight = 15;
|
var newChartRight = 15;
|
||||||
$("#sidebar").addClass("closing");
|
$("#sidebar").addClass("closing");
|
||||||
$("#workspace").css("right",newChartRight);
|
$("#workspace").css("right",newChartRight);
|
||||||
$("#chart-zoom-controls").css("right",newChartRight+20);
|
$("#chart-zoom-controls").css("right",newChartRight+20);
|
||||||
$("#sidebar").width(0);
|
$("#sidebar").width(0);
|
||||||
RED.menu.setSelected("btn-sidebar",true);
|
RED.menu.setSelected("menu-item-sidebar",true);
|
||||||
eventHandler.emit("resize");
|
eventHandler.emit("resize");
|
||||||
}
|
}
|
||||||
sidebarSeparator.width = $("#sidebar").width();
|
sidebarSeparator.width = $("#sidebar").width();
|
||||||
@ -104,7 +104,7 @@ RED.sidebar = (function() {
|
|||||||
stop:function(event,ui) {
|
stop:function(event,ui) {
|
||||||
if (sidebarSeparator.closing) {
|
if (sidebarSeparator.closing) {
|
||||||
$("#sidebar").removeClass("closing");
|
$("#sidebar").removeClass("closing");
|
||||||
RED.menu.setSelected("btn-sidebar",false);
|
RED.menu.setSelected("menu-item-sidebar",false);
|
||||||
if ($("#sidebar").width() < 180) {
|
if ($("#sidebar").width() < 180) {
|
||||||
$("#sidebar").width(180);
|
$("#sidebar").width(180);
|
||||||
$("#workspace").css("right",208);
|
$("#workspace").css("right",208);
|
||||||
@ -138,7 +138,7 @@ RED.sidebar = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init () {
|
function init () {
|
||||||
RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){RED.menu.setSelected("btn-sidebar",!RED.menu.isSelected("btn-sidebar"));d3.event.preventDefault();});
|
RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){RED.menu.setSelected("menu-item-sidebar",!RED.menu.isSelected("menu-item-sidebar"));d3.event.preventDefault();});
|
||||||
showSidebar();
|
showSidebar();
|
||||||
RED.sidebar.info.show();
|
RED.sidebar.info.show();
|
||||||
}
|
}
|
||||||
|
@ -177,9 +177,9 @@ RED.subflow = (function() {
|
|||||||
|
|
||||||
RED.view.on("selection-changed",function(selection) {
|
RED.view.on("selection-changed",function(selection) {
|
||||||
if (!selection.nodes) {
|
if (!selection.nodes) {
|
||||||
RED.menu.setDisabled("btn-convert-subflow",true);
|
RED.menu.setDisabled("menu-item-subflow-convert",true);
|
||||||
} else {
|
} else {
|
||||||
RED.menu.setDisabled("btn-convert-subflow",false);
|
RED.menu.setDisabled("menu-item-subflow-convert",false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -259,8 +259,8 @@ RED.view = (function() {
|
|||||||
$("#workspace-subflow-add-input").toggleClass("disabled",activeSubflow.in.length > 0);
|
$("#workspace-subflow-add-input").toggleClass("disabled",activeSubflow.in.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
RED.menu.setDisabled("btn-workspace-edit", activeSubflow);
|
RED.menu.setDisabled("menu-item-workspace-edit", activeSubflow);
|
||||||
RED.menu.setDisabled("btn-workspace-delete",RED.workspaces.count() == 1 || activeSubflow);
|
RED.menu.setDisabled("menu-item-workspace-delete",RED.workspaces.count() == 1 || activeSubflow);
|
||||||
|
|
||||||
if (workspaceScrollPositions[event.workspace]) {
|
if (workspaceScrollPositions[event.workspace]) {
|
||||||
chart.scrollLeft(workspaceScrollPositions[event.workspace].left);
|
chart.scrollLeft(workspaceScrollPositions[event.workspace].left);
|
||||||
|
@ -102,18 +102,18 @@ RED.workspaces = (function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onadd: function(tab) {
|
onadd: function(tab) {
|
||||||
RED.menu.addItem("btn-workspace-menu",{
|
RED.menu.addItem("menu-item-workspace",{
|
||||||
id:"btn-workspace-menu-"+tab.id.replace(".","-"),
|
id:"menu-item-workspace-menu-"+tab.id.replace(".","-"),
|
||||||
label:tab.label,
|
label:tab.label,
|
||||||
onselect:function() {
|
onselect:function() {
|
||||||
workspace_tabs.activateTab(tab.id);
|
workspace_tabs.activateTab(tab.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
RED.menu.setDisabled("btn-workspace-delete",workspace_tabs.count() == 1);
|
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() == 1);
|
||||||
},
|
},
|
||||||
onremove: function(tab) {
|
onremove: function(tab) {
|
||||||
RED.menu.setDisabled("btn-workspace-delete",workspace_tabs.count() == 1);
|
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() == 1);
|
||||||
RED.menu.removeItem("btn-workspace-menu-"+tab.id.replace(".","-"));
|
RED.menu.removeItem("menu-item-workspace-menu-"+tab.id.replace(".","-"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ RED.workspaces = (function() {
|
|||||||
if (workspace.label != label) {
|
if (workspace.label != label) {
|
||||||
workspace_tabs.renameTab(workspace.id,label);
|
workspace_tabs.renameTab(workspace.id,label);
|
||||||
RED.nodes.dirty(true);
|
RED.nodes.dirty(true);
|
||||||
$("#btn-workspace-menu-"+workspace.id.replace(".","-")).text(label);
|
$("#menu-item-workspace-menu-"+workspace.id.replace(".","-")).text(label);
|
||||||
// TODO: update entry in menu
|
// TODO: update entry in menu
|
||||||
}
|
}
|
||||||
$( this ).dialog( "close" );
|
$( this ).dialog( "close" );
|
||||||
@ -195,7 +195,7 @@ RED.workspaces = (function() {
|
|||||||
$('#btn-workspace-add-tab').on("click",function(e) {addWorkspace(); e.preventDefault()});
|
$('#btn-workspace-add-tab').on("click",function(e) {addWorkspace(); e.preventDefault()});
|
||||||
RED.sidebar.on("resize",workspace_tabs.resize);
|
RED.sidebar.on("resize",workspace_tabs.resize);
|
||||||
|
|
||||||
RED.menu.setAction('btn-workspace-delete',function() {
|
RED.menu.setAction('menu-item-workspace-delete',function() {
|
||||||
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
|
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ RED.user = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dialog = $('<div id="node-dialog-login" class="hide">'+
|
var dialog = $('<div id="node-dialog-login" class="hide">'+
|
||||||
'<div style="display: inline-block;width: 250px; vertical-align: top; margin-right: 10px; margin-bottom: 20px;"><img src="red/images/node-red-256.png"/></div>'+
|
'<div style="display: inline-block;width: 250px; vertical-align: top; margin-right: 10px; margin-bottom: 20px;"><img id="node-dialog-login-image" src=""/></div>'+
|
||||||
'<div style="display: inline-block; width: 250px; vertical-align: bottom; margin-left: 10px; margin-bottom: 20px;">'+
|
'<div style="display: inline-block; width: 250px; vertical-align: bottom; margin-left: 10px; margin-bottom: 20px;">'+
|
||||||
'<form id="node-dialog-login-fields" class="form-horizontal" style="margin-bottom: 0px;"></form>'+
|
'<form id="node-dialog-login-fields" class="form-horizontal" style="margin-bottom: 0px;"></form>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
@ -45,6 +45,13 @@ RED.user = (function() {
|
|||||||
success: function(data) {
|
success: function(data) {
|
||||||
if (data.type == "credentials") {
|
if (data.type == "credentials") {
|
||||||
var i=0;
|
var i=0;
|
||||||
|
|
||||||
|
if (data.image) {
|
||||||
|
$("#node-dialog-login-image").attr("src",data.image);
|
||||||
|
} else {
|
||||||
|
$("#node-dialog-login-image").attr("src","red/images/node-red-256.png");
|
||||||
|
}
|
||||||
|
|
||||||
for (;i<data.prompts.length;i++) {
|
for (;i<data.prompts.length;i++) {
|
||||||
var field = data.prompts[i];
|
var field = data.prompts[i];
|
||||||
var row = $("<div/>",{class:"form-row"});
|
var row = $("<div/>",{class:"form-row"});
|
||||||
@ -110,10 +117,10 @@ RED.user = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateUserMenu() {
|
function updateUserMenu() {
|
||||||
$("#btn-usermenu-submenu li").remove();
|
$("#usermenu-submenu li").remove();
|
||||||
if (RED.settings.user.anonymous) {
|
if (RED.settings.user.anonymous) {
|
||||||
RED.menu.addItem("btn-usermenu",{
|
RED.menu.addItem("btn-usermenu",{
|
||||||
id:"btn-login",
|
id:"usermenu-item-login",
|
||||||
label:"Login",
|
label:"Login",
|
||||||
onselect: function() {
|
onselect: function() {
|
||||||
RED.user.login({cancelable:true},function() {
|
RED.user.login({cancelable:true},function() {
|
||||||
@ -126,11 +133,11 @@ RED.user = (function() {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
RED.menu.addItem("btn-usermenu",{
|
RED.menu.addItem("btn-usermenu",{
|
||||||
id:"btn-username",
|
id:"usermenu-item-username",
|
||||||
label:"<b>"+RED.settings.user.username+"</b>"
|
label:"<b>"+RED.settings.user.username+"</b>"
|
||||||
});
|
});
|
||||||
RED.menu.addItem("btn-usermenu",{
|
RED.menu.addItem("btn-usermenu",{
|
||||||
id:"btn-logout",
|
id:"usermenu-item-logout",
|
||||||
label:"Logout",
|
label:"Logout",
|
||||||
onselect: function() {
|
onselect: function() {
|
||||||
RED.user.logout();
|
RED.user.logout();
|
||||||
@ -144,13 +151,16 @@ RED.user = (function() {
|
|||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
if (RED.settings.user) {
|
if (RED.settings.user) {
|
||||||
$('<li><a id="btn-usermenu" class="button hide" data-toggle="dropdown" href="#"><i class="fa fa-user"></i></a></li>')
|
if (!RED.settings.editorTheme || !RED.settings.editorTheme.hasOwnProperty("userMenu")) {
|
||||||
.prependTo(".header-toolbar");
|
|
||||||
|
|
||||||
RED.menu.init({id:"btn-usermenu",
|
$('<li><a id="btn-usermenu" class="button hide" data-toggle="dropdown" href="#"><i class="fa fa-user"></i></a></li>')
|
||||||
options: []
|
.prependTo(".header-toolbar");
|
||||||
});
|
|
||||||
updateUserMenu();
|
RED.menu.init({id:"btn-usermenu",
|
||||||
|
options: []
|
||||||
|
});
|
||||||
|
updateUserMenu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
$activeButton: #121212;
|
||||||
|
|
||||||
|
$deployButton: #8C101C;
|
||||||
|
$deployButtonHover: #6E0A1E;
|
||||||
|
$deployButtonActive: #4C0A17;
|
||||||
|
|
||||||
|
$deployDisabledButton: #444;
|
||||||
|
$deployDisabledButtonHover: #555;
|
||||||
|
$deployDisabledButtonActive: #444;
|
||||||
|
|
||||||
|
$headerMenuBackground: #121212;
|
||||||
|
$headerMenuItemHover: #323232;
|
||||||
|
$headerMenuItemDivider: #464646;
|
||||||
|
|
||||||
#header {
|
#header {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -34,29 +48,29 @@ span.logo {
|
|||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
|
span {
|
||||||
|
vertical-align: middle;
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
span.logo span {
|
|
||||||
vertical-align: middle;
|
.header-toolbar {
|
||||||
font-size: 16px !important;
|
|
||||||
}
|
|
||||||
span.logo img {
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
#header ul.header-toolbar {
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
|
||||||
|
|
||||||
#header ul.header-toolbar > li {
|
> li {
|
||||||
padding: 0;
|
display: inline-block;
|
||||||
margin: 0;
|
padding: 0;
|
||||||
position: relative;
|
margin: 0;
|
||||||
}
|
position: relative;
|
||||||
|
|
||||||
#header ul.header-toolbar > li {
|
}
|
||||||
display: inline-block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
@ -68,7 +82,7 @@ span.logo img {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 14px;
|
font-size: 20px;
|
||||||
padding: 0px 12px;
|
padding: 0px 12px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #C7C7C7;
|
color: #C7C7C7;
|
||||||
@ -76,110 +90,96 @@ span.logo img {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
border-left: 2px solid #000;
|
border-left: 2px solid #000;
|
||||||
border-right: 2px solid #000;
|
border-right: 2px solid #000;
|
||||||
}
|
|
||||||
#header .button:not(.disabled):hover {
|
|
||||||
border-color: #323232;
|
|
||||||
}
|
|
||||||
|
|
||||||
#btn-deploy {
|
&:hover {
|
||||||
background: #8C101C; /*#d24741;*/
|
border-color: $headerMenuItemHover;
|
||||||
color: #eee !important;
|
}
|
||||||
}
|
|
||||||
#btn-deploy + a {
|
|
||||||
background: #8C101C; /*#BA403B;*/
|
|
||||||
color: #eee;
|
|
||||||
}
|
|
||||||
#btn-deploy + a:hover {
|
|
||||||
background: #6E0A1E; /*#AD3C38;*/
|
|
||||||
color: #eee;
|
|
||||||
}
|
|
||||||
#btn-deploy + a:active {
|
|
||||||
background: #4C0A17; /*#aa1f19;*/
|
|
||||||
color: #ccc;
|
|
||||||
}
|
|
||||||
span.deploy-button-group.open > #btn-deploy + a {
|
|
||||||
background: #121212 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#btn-deploy:not(.disabled):hover {
|
|
||||||
background: #6E0A1E; /*#ca3f39;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#btn-deploy:not(.disabled):active {
|
|
||||||
background: #4C0A17 /*#aa1f19*/ !important;
|
|
||||||
}
|
|
||||||
#btn-deploy:not(.disabled):active {
|
|
||||||
color: #ccc !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#btn-deploy.disabled {
|
|
||||||
cursor: default;
|
|
||||||
background: #444;
|
|
||||||
color: #999 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#btn-deploy.disabled + a {
|
|
||||||
background: #444;
|
|
||||||
color: #ddd;
|
|
||||||
}
|
|
||||||
#btn-deploy.disabled + a:hover {
|
|
||||||
background: #555;
|
|
||||||
color: #ddd;
|
|
||||||
}
|
|
||||||
#btn-deploy.disabled + a:active {
|
|
||||||
background: #444;
|
|
||||||
color: #ddd;
|
|
||||||
}
|
|
||||||
span.deploy-button-group.open > #btn-deploy.disabled + a {
|
|
||||||
background: #121212 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#btn-deploy img {
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
#btn-deploy.disabled img {
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-group {
|
.button-group {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: auto 15px;
|
margin: auto 15px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
background: #555;
|
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
.button-group > a {
|
.button-group > a {
|
||||||
|
display: inline-block;
|
||||||
float: left;
|
float: left;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
display: inline-block;
|
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
color: #ccc;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.button-group > a:last-child {
|
|
||||||
|
.deploy-button {
|
||||||
|
background: $deployButton;
|
||||||
|
color: #eee !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $deployButtonHover;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background: $deployButtonActive;
|
||||||
|
color: #ccc !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#btn-deploy {
|
||||||
|
|
||||||
|
padding: 4px 12px;
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: default;
|
||||||
|
background: $deployDisabledButton;
|
||||||
|
color: #999 !important;
|
||||||
|
|
||||||
|
img {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&+ #btn-deploy-options {
|
||||||
|
background: $deployDisabledButton;
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
&+ #btn-deploy-options:hover {
|
||||||
|
background: $deployDisabledButtonHover;
|
||||||
|
}
|
||||||
|
&+ #btn-deploy-options:active {
|
||||||
|
background: $deployDisabledButton;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.deploy-button-group.open {
|
||||||
|
#btn-deploy-options {
|
||||||
|
background: $activeButton !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#header .button {
|
#header .button {
|
||||||
font-size: 20px !important;
|
&:active, &.active {
|
||||||
}
|
background: $activeButton;
|
||||||
#header .button:active, #header .button.active {
|
}
|
||||||
background: #121212;
|
&:focus {
|
||||||
}
|
outline: none;
|
||||||
#header .button:focus {
|
}
|
||||||
outline: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#header li.open .button {
|
#header li.open .button {
|
||||||
background: #121212;
|
background: $activeButton;
|
||||||
border-color: #121212;
|
border-color: $activeButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#header ul.dropdown-menu {
|
#header ul.dropdown-menu {
|
||||||
background: #121212;
|
background: $headerMenuBackground;
|
||||||
width: 250px !important;
|
width: 250px !important;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
@ -219,12 +219,12 @@ span.deploy-button-group.open > #btn-deploy.disabled + a {
|
|||||||
|
|
||||||
#header ul.dropdown-menu > li:hover > a,
|
#header ul.dropdown-menu > li:hover > a,
|
||||||
#header ul.dropdown-menu > li:focus > a {
|
#header ul.dropdown-menu > li:focus > a {
|
||||||
background: #323232 !important;
|
background: $headerMenuItemHover !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header ul.dropdown-menu li.divider {
|
#header ul.dropdown-menu li.divider {
|
||||||
background: #464646;
|
background: $headerMenuItemDivider;
|
||||||
border-bottom-color: #323232;
|
border-bottom-color: $headerMenuItemHover;
|
||||||
}
|
}
|
||||||
#header ul.dropdown-menu li.disabled a {
|
#header ul.dropdown-menu li.disabled a {
|
||||||
color: #666;
|
color: #666;
|
||||||
|
@ -17,7 +17,9 @@
|
|||||||
|
|
||||||
#palette {
|
#palette {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px; left:10px; bottom: 10px;
|
top: 5px;
|
||||||
|
bottom: 10px;
|
||||||
|
left:10px;
|
||||||
background: #f3f3f3;
|
background: #f3f3f3;
|
||||||
width: 170px;
|
width: 170px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -29,13 +31,12 @@
|
|||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left:0;
|
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 35px;
|
bottom: 35px;
|
||||||
|
left:0;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
box-sizing:border-box;
|
box-sizing:border-box;
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
}
|
}
|
||||||
.palette-spinner {
|
.palette-spinner {
|
||||||
padding-top: 40px;
|
padding-top: 40px;
|
||||||
@ -53,7 +54,6 @@
|
|||||||
padding: 3px;
|
padding: 3px;
|
||||||
border-top: 1px solid #999;
|
border-top: 1px solid #999;
|
||||||
box-sizing:border-box;
|
box-sizing:border-box;
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
}
|
}
|
||||||
#palette-search i.fa-search {
|
#palette-search i.fa-search {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -82,7 +82,6 @@
|
|||||||
margin: 0px;
|
margin: 0px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
box-sizing:border-box;
|
box-sizing:border-box;
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#palette-search input:focus {
|
#palette-search input:focus {
|
||||||
|
@ -17,12 +17,13 @@
|
|||||||
|
|
||||||
|
|
||||||
#sidebar {
|
#sidebar {
|
||||||
width: 305px;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 10px; top: 5px; bottom:10px;
|
top: 5px;
|
||||||
|
right: 10px;
|
||||||
|
bottom: 10px;
|
||||||
|
width: 305px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
@include component-border;
|
@include component-border;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,17 +34,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#sidebar-content {
|
#sidebar-content {
|
||||||
|
position: absolute;
|
||||||
|
top: 30px;
|
||||||
|
right: 0;
|
||||||
|
bottom: 1px;
|
||||||
|
left: 0px;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
position: absolute;
|
|
||||||
top: 30px; left: 0px; right: 0; bottom: 1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar-separator {
|
#sidebar-separator {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: 316px;
|
||||||
|
bottom:10px;
|
||||||
width: 15px;
|
width: 15px;
|
||||||
background: url(images/grip.png) no-repeat 50% 50%;
|
background: url(images/grip.png) no-repeat 50% 50%;
|
||||||
position: absolute;
|
|
||||||
right: 316px; top: 5px; bottom:10px;
|
|
||||||
cursor: col-resize;
|
cursor: col-resize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#workspace {
|
|
||||||
margin-left: 160px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chart {
|
#chart {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -32,12 +28,16 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#workspace {
|
#workspace {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
top:5px; left:190px; bottom: 10px; right: 330px;
|
top:5px;
|
||||||
|
left:190px;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 330px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chart-zoom-controls {
|
#chart-zoom-controls {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom:30px; right: 350px;
|
bottom:30px; right: 350px;
|
||||||
|
182
editor/templates/index.mst
Normal file
182
editor/templates/index.mst
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<!--
|
||||||
|
Copyright 2013, 2015 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.
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>{{ page.title }}</title>
|
||||||
|
<link rel="icon" type="image/png" href="{{ page.favicon }}">
|
||||||
|
<link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
|
||||||
|
<link href="vendor/jquery/css/smoothness/jquery-ui-1.10.3.custom.min.css" rel="stylesheet" media="screen">
|
||||||
|
<link rel="stylesheet" href="vendor/font-awesome/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="vendor/vendor.css">
|
||||||
|
<link rel="stylesheet" href="red/style.min.css">
|
||||||
|
{{#page.css}}
|
||||||
|
<link rel="stylesheet" href="{{.}}">
|
||||||
|
{{/page.css}}
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body spellcheck="false">
|
||||||
|
<div id="header">
|
||||||
|
<span class="logo">{{#header.image}}<img src="{{.}}">{{/header.image}} <span>{{ header.title }}</span></span>
|
||||||
|
<ul class="header-toolbar hide">
|
||||||
|
<li><a id="btn-sidemenu" class="button" data-toggle="dropdown" href="#"><i class="fa fa-bars"></i></a></li>
|
||||||
|
<ul>
|
||||||
|
</div>
|
||||||
|
<div id="main-container" class="sidebar-closed hide">
|
||||||
|
<div id="palette">
|
||||||
|
<img src="red/images/spin.svg" class="palette-spinner hide"/>
|
||||||
|
<div id="palette-container" class="palette-scroll">
|
||||||
|
</div>
|
||||||
|
<div id="palette-search">
|
||||||
|
<i class="fa fa-search"></i><input id="palette-search-input" type="text" placeholder="filter"><a href="#" id="palette-search-clear"><i class="fa fa-times"></i></a></input>
|
||||||
|
</div>
|
||||||
|
</div><!-- /palette -->
|
||||||
|
|
||||||
|
<div id="workspace">
|
||||||
|
<ul id="workspace-tabs"></ul>
|
||||||
|
<div id="workspace-add-tab"><a id="btn-workspace-add-tab" href="#"><i class="fa fa-plus"></i></a></div>
|
||||||
|
<div id="chart"></div>
|
||||||
|
<div id="workspace-toolbar">
|
||||||
|
<a class="button" id="workspace-subflow-edit" href="#"><i class="fa fa-pencil"></i> edit name</a>
|
||||||
|
<a class="button disabled" id="workspace-subflow-add-input" href="#"><i class="fa fa-plus"></i> input</a>
|
||||||
|
<a class="button" id="workspace-subflow-add-output" href="#"><i class="fa fa-plus"></i> output</a>
|
||||||
|
<a class="button" id="workspace-subflow-delete" href="#"><i class="fa fa-trash"></i> delete subflow</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="chart-zoom-controls">
|
||||||
|
<div class="btn-group">
|
||||||
|
<a class="btn btn-mini" id="btn-zoom-out" href="#"><i class="fa fa-search-minus"></i></a>
|
||||||
|
<a class="btn btn-mini" id="btn-zoom-zero" href="#"><i class="fa fa-dot-circle-o"></i></a>
|
||||||
|
<a class="btn btn-mini" id="btn-zoom-in" href="#"><i class="fa fa-search-plus"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="sidebar">
|
||||||
|
<ul id="sidebar-tabs"></ul>
|
||||||
|
<div id="sidebar-content"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="sidebar-separator"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="notifications"></div>
|
||||||
|
<div id="dropTarget"><div>Drop the flow here<br/><i class="fa fa-download"></i></div></div>
|
||||||
|
|
||||||
|
<div id="dialog" class="hide"><form id="dialog-form" class="form-horizontal"></form></div>
|
||||||
|
<div id="node-config-dialog" class="hide"><form id="dialog-config-form" class="form-horizontal"></form><div class="form-tips" id="node-config-dialog-user-count"></div></div>
|
||||||
|
<div id="subflow-dialog" class="hide">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-row">
|
||||||
|
<label>Name</label><input type="text" id="subflow-input-name">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="form-tips" id="subflow-dialog-user-count"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="node-dialog-confirm-deploy" class="hide">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div id="node-dialog-confirm-deploy-config" style="text-align: center; padding-top: 30px;">
|
||||||
|
Some of the nodes are not properly configured. Are you sure you want to deploy?
|
||||||
|
</div>
|
||||||
|
<div id="node-dialog-confirm-deploy-unknown" style="text-align: center; padding-top: 10px;">
|
||||||
|
The workspace contains some unknown node types:
|
||||||
|
<ul style="width: 300px; margin: auto; text-align: left;" id="node-dialog-confirm-deploy-unknown-list"></ul>
|
||||||
|
Are you sure you want to deploy?
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="node-dialog-library-save-confirm" class="hide">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div style="text-align: center; padding-top: 30px;">
|
||||||
|
A <span id="node-dialog-library-save-type"></span> called <span id="node-dialog-library-save-name"></span> already exists. Overwrite?
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="node-dialog-library-save" class="hide">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-dialog-library-save-folder"><i class="fa fa-folder-open"></i> Folder</label>
|
||||||
|
<input type="text" id="node-dialog-library-save-folder" placeholder="Folder">
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-dialog-library-save-filename"><i class="fa fa-file"></i> Filename</label>
|
||||||
|
<input type="text" id="node-dialog-library-save-filename" placeholder="Filename">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="node-dialog-library-lookup" class="hide">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-row">
|
||||||
|
<ul id="node-dialog-library-breadcrumbs" class="breadcrumb">
|
||||||
|
<li class="active"><a href="#">Library</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div style="vertical-align: top; display: inline-block; height: 100%; width: 30%; padding-right: 20px;">
|
||||||
|
<div id="node-select-library" style="border: 1px solid #999; width: 100%; height: 100%; overflow:scroll;"><ul></ul></div>
|
||||||
|
</div>
|
||||||
|
<div style="vertical-align: top; display: inline-block;width: 65%; height: 100%;">
|
||||||
|
<div style="height: 100%; width: 95%;" class="node-text-editor" id="node-select-library-text" ></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</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="fa fa-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-library-dialog">
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-filename" ><i class="fa fa-file"></i> Filename:</label>
|
||||||
|
<input type="text" id="node-input-filename" placeholder="Filename">
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/x-red" data-template-name="subflow">
|
||||||
|
<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>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="vendor/vendor.js"></script>
|
||||||
|
<script src="vendor/ace/ace.js"></script>
|
||||||
|
<script src="vendor/ace/ext-language_tools.js"></script>
|
||||||
|
<script src="red/red.min.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -22,6 +22,8 @@ var Tokens = require("./tokens");
|
|||||||
var Users = require("./users");
|
var Users = require("./users");
|
||||||
var permissions = require("./permissions");
|
var permissions = require("./permissions");
|
||||||
|
|
||||||
|
var theme = require("../theme");
|
||||||
|
|
||||||
var settings = null;
|
var settings = null;
|
||||||
var log = require("../../log");
|
var log = require("../../log");
|
||||||
|
|
||||||
@ -80,6 +82,9 @@ function login(req,res) {
|
|||||||
"type":"credentials",
|
"type":"credentials",
|
||||||
"prompts":[{id:"username",type:"text",label:"Username"},{id:"password",type:"password",label:"Password"}]
|
"prompts":[{id:"username",type:"text",label:"Username"},{id:"password",type:"password",label:"Password"}]
|
||||||
}
|
}
|
||||||
|
if (theme.context().login && theme.context().login.image) {
|
||||||
|
response.image = theme.context().login.image;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
res.json(response);
|
res.json(response);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ var nodes = require("./nodes");
|
|||||||
var flows = require("./flows");
|
var flows = require("./flows");
|
||||||
var library = require("./library");
|
var library = require("./library");
|
||||||
var info = require("./info");
|
var info = require("./info");
|
||||||
|
var theme = require("./theme");
|
||||||
|
|
||||||
var auth = require("./auth");
|
var auth = require("./auth");
|
||||||
var needsPermission = auth.needsPermission;
|
var needsPermission = auth.needsPermission;
|
||||||
@ -41,9 +42,13 @@ function init(adminApp,storage) {
|
|||||||
|
|
||||||
// Editor
|
// Editor
|
||||||
if (!settings.disableEditor) {
|
if (!settings.disableEditor) {
|
||||||
|
ui.init(settings);
|
||||||
var editorApp = express();
|
var editorApp = express();
|
||||||
editorApp.get("/",ui.ensureSlash,ui.editor);
|
editorApp.get("/",ui.ensureSlash,ui.editor);
|
||||||
editorApp.get("/icons/:icon",ui.icon);
|
editorApp.get("/icons/:icon",ui.icon);
|
||||||
|
if (settings.editorTheme) {
|
||||||
|
editorApp.use("/theme",theme.init(settings));
|
||||||
|
}
|
||||||
editorApp.use("/",ui.editorResources);
|
editorApp.use("/",ui.editorResources);
|
||||||
adminApp.use(editorApp);
|
adminApp.use(editorApp);
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
var settings = require('../settings');
|
var settings = require('../settings');
|
||||||
|
var theme = require("./theme");
|
||||||
|
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
|
||||||
@ -23,7 +24,12 @@ module.exports = {
|
|||||||
httpNodeRoot: settings.httpNodeRoot,
|
httpNodeRoot: settings.httpNodeRoot,
|
||||||
version: settings.version,
|
version: settings.version,
|
||||||
user: req.user
|
user: req.user
|
||||||
};
|
}
|
||||||
|
|
||||||
|
var themeSettings = theme.settings();
|
||||||
|
if (themeSettings) {
|
||||||
|
safeSettings.editorTheme = themeSettings;
|
||||||
|
}
|
||||||
|
|
||||||
if (util.isArray(settings.paletteCategories)) {
|
if (util.isArray(settings.paletteCategories)) {
|
||||||
safeSettings.paletteCategories = settings.paletteCategories;
|
safeSettings.paletteCategories = settings.paletteCategories;
|
||||||
|
151
red/api/theme.js
Normal file
151
red/api/theme.js
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2015 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var express = require("express");
|
||||||
|
var util = require("util");
|
||||||
|
var path = require("path");
|
||||||
|
var fs = require("fs");
|
||||||
|
var clone = require("clone");
|
||||||
|
|
||||||
|
var defaultContext = {
|
||||||
|
page: {
|
||||||
|
title: "Node-RED",
|
||||||
|
favicon: "favicon.ico"
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
title: "Node-RED",
|
||||||
|
image: "red/images/node-red.png"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var themeContext = clone(defaultContext);
|
||||||
|
var themeSettings = null;
|
||||||
|
|
||||||
|
function serveFile(app,baseUrl,file) {
|
||||||
|
try {
|
||||||
|
var stats = fs.statSync(file);
|
||||||
|
var url = baseUrl+path.basename(file);
|
||||||
|
//console.log(url,"->",file);
|
||||||
|
app.get(url,function(req, res) {
|
||||||
|
res.sendfile(file);
|
||||||
|
});
|
||||||
|
return "theme"+url;
|
||||||
|
} catch(err) {
|
||||||
|
//TODO: log filenotfound
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(settings) {
|
||||||
|
var i;
|
||||||
|
var url;
|
||||||
|
themeContext = clone(defaultContext);
|
||||||
|
themeSettings = null;
|
||||||
|
|
||||||
|
if (settings.editorTheme) {
|
||||||
|
var theme = settings.editorTheme;
|
||||||
|
themeSettings = {};
|
||||||
|
|
||||||
|
var themeApp = express();
|
||||||
|
|
||||||
|
if (theme.page) {
|
||||||
|
if (theme.page.css) {
|
||||||
|
var styles = theme.page.css;
|
||||||
|
if (!util.isArray(styles)) {
|
||||||
|
styles = [styles];
|
||||||
|
}
|
||||||
|
themeContext.page.css = [];
|
||||||
|
|
||||||
|
for (i=0;i<styles.length;i++) {
|
||||||
|
url = serveFile(themeApp,"/css/",styles[i]);
|
||||||
|
if (url) {
|
||||||
|
themeContext.page.css.push(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme.page.favicon) {
|
||||||
|
url = serveFile(themeApp,"/favicon/",theme.page.favicon)
|
||||||
|
if (url) {
|
||||||
|
themeContext.page.favicon = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
themeContext.page.title = theme.page.title || themeContext.page.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme.header) {
|
||||||
|
|
||||||
|
themeContext.header.title = theme.header.title || themeContext.header.title;
|
||||||
|
if (theme.header.hasOwnProperty("image")) {
|
||||||
|
if (theme.header.image) {
|
||||||
|
url = serveFile(themeApp,"/header/",theme.header.image);
|
||||||
|
if (url) {
|
||||||
|
themeContext.header.image = url;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
themeContext.header.image = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme.deployButton) {
|
||||||
|
if (theme.deployButton.type == "simple") {
|
||||||
|
themeSettings.deployButton = {
|
||||||
|
type: "simple"
|
||||||
|
}
|
||||||
|
if (theme.deployButton.label) {
|
||||||
|
themeSettings.deployButton.label = theme.deployButton.label;
|
||||||
|
}
|
||||||
|
if (theme.deployButton.icon) {
|
||||||
|
url = serveFile(themeApp,"/deploy/",theme.deployButton.icon);
|
||||||
|
if (url) {
|
||||||
|
themeSettings.deployButton.icon = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme.hasOwnProperty("userMenu")) {
|
||||||
|
themeSettings.userMenu = theme.userMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme.login) {
|
||||||
|
if (theme.login.image) {
|
||||||
|
url = serveFile(themeApp,"/login/",theme.login.image);
|
||||||
|
if (url) {
|
||||||
|
themeContext.login = {
|
||||||
|
image: url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme.hasOwnProperty("menu")) {
|
||||||
|
themeSettings.menu = theme.menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
return themeApp;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
context: function() {
|
||||||
|
return themeContext;
|
||||||
|
},
|
||||||
|
settings: function() {
|
||||||
|
return themeSettings;
|
||||||
|
}
|
||||||
|
}
|
@ -17,8 +17,12 @@ var express = require('express');
|
|||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
|
|
||||||
|
var theme = require("./theme");
|
||||||
|
|
||||||
|
var Mustache = require("mustache");
|
||||||
|
|
||||||
var events = require("../events");
|
var events = require("../events");
|
||||||
var settings = require("../settings");
|
var settings;
|
||||||
|
|
||||||
var icon_paths = [path.resolve(__dirname + '/../../public/icons')];
|
var icon_paths = [path.resolve(__dirname + '/../../public/icons')];
|
||||||
var iconCache = {};
|
var iconCache = {};
|
||||||
@ -29,7 +33,16 @@ events.on("node-icon-dir",function(dir) {
|
|||||||
icon_paths.push(path.resolve(dir));
|
icon_paths.push(path.resolve(dir));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var templateDir = path.resolve(__dirname+"/../../editor/templates");
|
||||||
|
var editorTemplate;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
init: function(_settings) {
|
||||||
|
settings = _settings;
|
||||||
|
editorTemplate = fs.readFileSync(path.join(templateDir,"index.mst"),"utf8");
|
||||||
|
Mustache.parse(editorTemplate);
|
||||||
|
},
|
||||||
|
|
||||||
ensureSlash: function(req,res,next) {
|
ensureSlash: function(req,res,next) {
|
||||||
var parts = req.originalUrl.split("?");
|
var parts = req.originalUrl.split("?");
|
||||||
if (parts[0].slice(-1) != "/") {
|
if (parts[0].slice(-1) != "/") {
|
||||||
@ -56,7 +69,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
editor: function(req,res) {
|
editor: function(req,res) {
|
||||||
res.sendfile(path.resolve(__dirname + '/../../public/index.html'));
|
res.send(Mustache.render(editorTemplate,theme.context()));
|
||||||
},
|
},
|
||||||
editorResources: express.static(__dirname + '/../../public')
|
editorResources: express.static(__dirname + '/../../public')
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2014 IBM Corp.
|
* Copyright 2014, 2015 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -24,6 +24,8 @@ var app = express();
|
|||||||
var settings = require("../../../red/settings");
|
var settings = require("../../../red/settings");
|
||||||
var info = require("../../../red/api/info");
|
var info = require("../../../red/api/info");
|
||||||
|
|
||||||
|
var theme = require("../../../red/api/theme");
|
||||||
|
|
||||||
describe("info api", function() {
|
describe("info api", function() {
|
||||||
describe("settings handler", function() {
|
describe("settings handler", function() {
|
||||||
before(function() {
|
before(function() {
|
||||||
@ -34,12 +36,16 @@ describe("info api", function() {
|
|||||||
paletteCategories :["red","blue","green"]
|
paletteCategories :["red","blue","green"]
|
||||||
}
|
}
|
||||||
settings.init(userSettings);
|
settings.init(userSettings);
|
||||||
|
|
||||||
|
sinon.stub(theme,"settings",function() { return { test: 456 };});
|
||||||
|
|
||||||
app = express();
|
app = express();
|
||||||
app.get("/settings",info.settings);
|
app.get("/settings",info.settings);
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function() {
|
after(function() {
|
||||||
settings.reset();
|
settings.reset();
|
||||||
|
theme.settings.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns the filtered settings', function(done) {
|
it('returns the filtered settings', function(done) {
|
||||||
@ -53,6 +59,7 @@ describe("info api", function() {
|
|||||||
res.body.should.have.property("httpNodeRoot","testHttpNodeRoot");
|
res.body.should.have.property("httpNodeRoot","testHttpNodeRoot");
|
||||||
res.body.should.have.property("version","testVersion");
|
res.body.should.have.property("version","testVersion");
|
||||||
res.body.should.have.property("paletteCategories",["red","blue","green"]);
|
res.body.should.have.property("paletteCategories",["red","blue","green"]);
|
||||||
|
res.body.should.have.property("editorTheme",{test:456});
|
||||||
res.body.should.not.have.property("foo",123);
|
res.body.should.not.have.property("foo",123);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
103
test/red/api/theme_spec.js
Normal file
103
test/red/api/theme_spec.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2015 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var should = require("should");
|
||||||
|
var request = require('supertest');
|
||||||
|
var express = require('express');
|
||||||
|
var sinon = require('sinon');
|
||||||
|
var when = require('when');
|
||||||
|
var fs = require("fs");
|
||||||
|
|
||||||
|
var app = express();
|
||||||
|
var settings = require("../../../red/settings");
|
||||||
|
|
||||||
|
var theme = require("../../../red/api/theme");
|
||||||
|
|
||||||
|
describe("theme handler", function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
sinon.stub(fs,"statSync",function() { return true; });
|
||||||
|
});
|
||||||
|
afterEach(function() {
|
||||||
|
theme.init({});
|
||||||
|
fs.statSync.restore();
|
||||||
|
});
|
||||||
|
it("applies the default theme", function() {
|
||||||
|
var result = theme.init({});
|
||||||
|
should.not.exist(result);
|
||||||
|
|
||||||
|
var context = theme.context();
|
||||||
|
context.should.have.a.property("page");
|
||||||
|
context.page.should.have.a.property("title","Node-RED");
|
||||||
|
context.page.should.have.a.property("favicon","favicon.ico");
|
||||||
|
context.should.have.a.property("header");
|
||||||
|
context.header.should.have.a.property("title","Node-RED");
|
||||||
|
context.header.should.have.a.property("image","red/images/node-red.png");
|
||||||
|
|
||||||
|
should.not.exist(theme.settings());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("picks up custom theme", function() {
|
||||||
|
var result = theme.init({
|
||||||
|
editorTheme: {
|
||||||
|
page: {
|
||||||
|
title: "Test Page Title",
|
||||||
|
favicon: "/absolute/path/to/theme/icon",
|
||||||
|
css: "/absolute/path/to/custom/css/file"
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
title: "Test Header Title",
|
||||||
|
image: "/absolute/path/to/header/image" // or null to remove image
|
||||||
|
},
|
||||||
|
|
||||||
|
deployButton: {
|
||||||
|
type:"simple",
|
||||||
|
label:"Save",
|
||||||
|
icon: "/absolute/path/to/deploy/button/image" // or null to remove image
|
||||||
|
},
|
||||||
|
|
||||||
|
menu: { // Hide unwanted menu items by id. see editor/js/main.js:loadEditor for complete list
|
||||||
|
"menu-item-import-library": false,
|
||||||
|
"menu-item-export-library": false,
|
||||||
|
"menu-item-keyboard-shortcuts": false,
|
||||||
|
"menu-item-help": {
|
||||||
|
label: "Alternative Help Link Text",
|
||||||
|
url: "http://example.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
userMenu: false, // Hide the user-menu even if adminAuth is enabled
|
||||||
|
|
||||||
|
login: {
|
||||||
|
image: "/absolute/path/to/login/page/big/image" // a 256x256 image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
should.exist(result);
|
||||||
|
|
||||||
|
var context = theme.context();
|
||||||
|
context.should.have.a.property("page");
|
||||||
|
context.page.should.have.a.property("title","Test Page Title");
|
||||||
|
context.should.have.a.property("header");
|
||||||
|
context.header.should.have.a.property("title","Test Header Title");
|
||||||
|
|
||||||
|
var settings = theme.settings();
|
||||||
|
settings.should.have.a.property("deployButton");
|
||||||
|
settings.should.have.a.property("userMenu");
|
||||||
|
settings.should.have.a.property("menu");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user