mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Split cliboard and workspaces out of editor view
This commit is contained in:
parent
7bdb3181e2
commit
4078212089
@ -211,27 +211,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/x-red" data-template-name="export-clipboard-dialog">
|
|
||||||
<div class="form-row">
|
|
||||||
<label for="node-input-export" style="display: block; width:100%;"><i class="fa fa-clipboard"></i> Nodes:</label>
|
|
||||||
<textarea readonly style="font-family: monospace; font-size: 12px; background:rgb(226, 229, 255); padding-left: 0.5em;" class="input-block-level" id="node-input-export" rows="5"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="form-tips">
|
|
||||||
Select the text above and copy to the clipboard with Ctrl-A Ctrl-C.
|
|
||||||
</div>
|
|
||||||
</script>
|
|
||||||
<script type="text/x-red" data-template-name="export-library-dialog">
|
<script type="text/x-red" data-template-name="export-library-dialog">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-filename" ><i class="fa fa-file"></i> Filename:</label>
|
<label for="node-input-filename" ><i class="fa fa-file"></i> Filename:</label>
|
||||||
<input type="text" id="node-input-filename" placeholder="Filename">
|
<input type="text" id="node-input-filename" placeholder="Filename">
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-red" data-template-name="import-dialog">
|
|
||||||
<div class="form-row">
|
|
||||||
<label for="node-input-import"><i class="fa fa-clipboard"></i> Nodes:</label>
|
|
||||||
<textarea style="font-family: monospace; font-size: 12px; background:rgb(226, 229, 255); padding-left: 0.5em;" class="input-block-level" id="node-input-import" rows="5" placeholder="Paste nodes here"></textarea>
|
|
||||||
</div>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script type="text/x-red" data-template-name="subflow">
|
<script type="text/x-red" data-template-name="subflow">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -260,12 +246,14 @@
|
|||||||
<script src="red/ui/menu.js"></script>
|
<script src="red/ui/menu.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/tabs.js"></script>
|
||||||
|
<script src="red/ui/workspaces.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>
|
||||||
<script src="red/ui/tab-info.js"></script>
|
<script src="red/ui/tab-info.js"></script>
|
||||||
<script src="red/ui/tab-config.js"></script>
|
<script src="red/ui/tab-config.js"></script>
|
||||||
<script src="red/ui/editor.js"></script>
|
<script src="red/ui/editor.js"></script>
|
||||||
|
<script src="red/ui/clipboard.js"></script>
|
||||||
<script src="red/ui/library.js"></script>
|
<script src="red/ui/library.js"></script>
|
||||||
<script src="red/ui/notifications.js"></script>
|
<script src="red/ui/notifications.js"></script>
|
||||||
<script src="red/ui/subflow.js"></script>
|
<script src="red/ui/subflow.js"></script>
|
||||||
|
@ -47,20 +47,20 @@ RED.history = (function() {
|
|||||||
if (ev.workspaces) {
|
if (ev.workspaces) {
|
||||||
for (i=0;i<ev.workspaces.length;i++) {
|
for (i=0;i<ev.workspaces.length;i++) {
|
||||||
RED.nodes.removeWorkspace(ev.workspaces[i].id);
|
RED.nodes.removeWorkspace(ev.workspaces[i].id);
|
||||||
RED.view.removeWorkspace(ev.workspaces[i]);
|
RED.workspaces.remove(ev.workspaces[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ev.subflows) {
|
if (ev.subflows) {
|
||||||
for (i=0;i<ev.subflows.length;i++) {
|
for (i=0;i<ev.subflows.length;i++) {
|
||||||
RED.nodes.removeSubflow(ev.subflows[i]);
|
RED.nodes.removeSubflow(ev.subflows[i]);
|
||||||
RED.view.removeWorkspace(ev.subflows[i]);
|
RED.workspaces.remove(ev.subflows[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ev.t == "delete") {
|
} else if (ev.t == "delete") {
|
||||||
if (ev.workspaces) {
|
if (ev.workspaces) {
|
||||||
for (i=0;i<ev.workspaces.length;i++) {
|
for (i=0;i<ev.workspaces.length;i++) {
|
||||||
RED.nodes.addWorkspace(ev.workspaces[i]);
|
RED.nodes.addWorkspace(ev.workspaces[i]);
|
||||||
RED.view.addWorkspace(ev.workspaces[i]);
|
RED.workspaces.add(ev.workspaces[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ev.subflow) {
|
if (ev.subflow) {
|
||||||
@ -183,7 +183,7 @@ RED.history = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RED.nodes.removeSubflow(ev.subflow);
|
RED.nodes.removeSubflow(ev.subflow);
|
||||||
RED.view.removeWorkspace(ev.subflow);
|
RED.workspaces.remove(ev.subflow);
|
||||||
|
|
||||||
if (ev.removedLinks) {
|
if (ev.removedLinks) {
|
||||||
for (i=0;i<ev.removedLinks.length;i++) {
|
for (i=0;i<ev.removedLinks.length;i++) {
|
||||||
|
@ -275,12 +275,12 @@ var RED = (function() {
|
|||||||
{id:"btn-node-status",label:"Display node status",toggle:true,onselect:toggleStatus, selected: true},
|
{id:"btn-node-status",label:"Display node status",toggle:true,onselect:toggleStatus, selected: true},
|
||||||
null,
|
null,
|
||||||
{id:"btn-import-menu",label:"Import",options:[
|
{id:"btn-import-menu",label:"Import",options:[
|
||||||
{id:"btn-import-clipboard",label:"Clipboard",onselect:RED.view.showImportNodesDialog},
|
{id:"btn-import-clipboard",label:"Clipboard",onselect:RED.clipboard.import},
|
||||||
{id:"btn-import-library",label:"Library",options:[]}
|
{id:"btn-import-library",label:"Library",options:[]}
|
||||||
]},
|
]},
|
||||||
{id:"btn-export-menu",label:"Export",disabled:true,options:[
|
{id:"btn-export-menu",label:"Export",disabled:true,options:[
|
||||||
{id:"btn-export-clipboard",label:"Clipboard",disabled:true,onselect:RED.view.showExportNodesDialog},
|
{id:"btn-export-clipboard",label:"Clipboard",disabled:true,onselect:RED.clipboard.export},
|
||||||
{id:"btn-export-library",label:"Library",disabled:true,onselect:RED.view.showExportNodesLibraryDialog}
|
{id:"btn-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:"btn-config-nodes",label:"Configuration nodes",onselect:RED.sidebar.config.show},
|
||||||
@ -291,9 +291,9 @@ var RED = (function() {
|
|||||||
]},
|
]},
|
||||||
null,
|
null,
|
||||||
{id:"btn-workspace-menu",label:"Workspaces",options:[
|
{id:"btn-workspace-menu",label:"Workspaces",options:[
|
||||||
{id:"btn-workspace-add",label:"Add"},
|
{id:"btn-workspace-add",label:"Add",onselect:RED.workspaces.add},
|
||||||
{id:"btn-workspace-edit",label:"Rename"},
|
{id:"btn-workspace-edit",label:"Rename",onselect:RED.workspaces.edit},
|
||||||
{id:"btn-workspace-delete",label:"Delete"},
|
{id:"btn-workspace-delete",label:"Delete",onselect:RED.workspaces.remove},
|
||||||
null
|
null
|
||||||
]},
|
]},
|
||||||
null,
|
null,
|
||||||
@ -357,6 +357,8 @@ var RED = (function() {
|
|||||||
RED.palette.init();
|
RED.palette.init();
|
||||||
RED.sidebar.init();
|
RED.sidebar.init();
|
||||||
RED.subflow.init();
|
RED.subflow.init();
|
||||||
|
RED.workspaces.init();
|
||||||
|
RED.clipboard.init();
|
||||||
RED.view.init();
|
RED.view.init();
|
||||||
|
|
||||||
RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();});
|
RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();});
|
||||||
|
@ -429,16 +429,16 @@ RED.nodes = (function() {
|
|||||||
var exportedConfigNodes = {};
|
var exportedConfigNodes = {};
|
||||||
var exportedSubflows = {};
|
var exportedSubflows = {};
|
||||||
for (var n=0;n<set.length;n++) {
|
for (var n=0;n<set.length;n++) {
|
||||||
var node = set[n].n;
|
var node = set[n];
|
||||||
if (node.type.substring(0,8) == "subflow:") {
|
if (node.type.substring(0,8) == "subflow:") {
|
||||||
var subflowId = node.type.substring(8);
|
var subflowId = node.type.substring(8);
|
||||||
if (!exportedSubflows[subflowId]) {
|
if (!exportedSubflows[subflowId]) {
|
||||||
exportedSubflows[subflowId] = true;
|
exportedSubflows[subflowId] = true;
|
||||||
var subflow = getSubflow(subflowId);
|
var subflow = getSubflow(subflowId);
|
||||||
var subflowSet = [{n:subflow}];
|
var subflowSet = [subflow];
|
||||||
RED.nodes.eachNode(function(n) {
|
RED.nodes.eachNode(function(n) {
|
||||||
if (n.z == subflowId) {
|
if (n.z == subflowId) {
|
||||||
subflowSet.push({n:n});
|
subflowSet.push(n);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var exportableSubflow = createExportableNodeSet(subflowSet);
|
var exportableSubflow = createExportableNodeSet(subflowSet);
|
||||||
@ -543,7 +543,7 @@ RED.nodes = (function() {
|
|||||||
//"DO NOT DEPLOY while in this state.<br/>Either, add missing types to Node-RED, restart and then reload page,<br/>or delete unknown "+n.name+", rewire as required, and then deploy.","error");
|
//"DO NOT DEPLOY while in this state.<br/>Either, add missing types to Node-RED, restart and then reload page,<br/>or delete unknown "+n.name+", rewire as required, and then deploy.","error");
|
||||||
}
|
}
|
||||||
|
|
||||||
var activeWorkspace = RED.view.getWorkspace();
|
var activeWorkspace = RED.workspaces.active();
|
||||||
var activeSubflow = getSubflow(activeWorkspace);
|
var activeSubflow = getSubflow(activeWorkspace);
|
||||||
if (activeSubflow) {
|
if (activeSubflow) {
|
||||||
for (i=0;i<newNodes.length;i++) {
|
for (i=0;i<newNodes.length;i++) {
|
||||||
@ -589,7 +589,7 @@ RED.nodes = (function() {
|
|||||||
n.id = nid;
|
n.id = nid;
|
||||||
}
|
}
|
||||||
addWorkspace(n);
|
addWorkspace(n);
|
||||||
RED.view.addWorkspace(n);
|
RED.workspaces.add(n);
|
||||||
new_workspaces.push(n);
|
new_workspaces.push(n);
|
||||||
} else if (n.type === "subflow") {
|
} else if (n.type === "subflow") {
|
||||||
subflow_map[n.id] = n;
|
subflow_map[n.id] = n;
|
||||||
@ -634,9 +634,9 @@ RED.nodes = (function() {
|
|||||||
if (defaultWorkspace == null) {
|
if (defaultWorkspace == null) {
|
||||||
defaultWorkspace = { type:"tab", id:getID(), label:"Sheet 1" };
|
defaultWorkspace = { type:"tab", id:getID(), label:"Sheet 1" };
|
||||||
addWorkspace(defaultWorkspace);
|
addWorkspace(defaultWorkspace);
|
||||||
RED.view.addWorkspace(defaultWorkspace);
|
RED.workspaces.add(defaultWorkspace);
|
||||||
new_workspaces.push(defaultWorkspace);
|
new_workspaces.push(defaultWorkspace);
|
||||||
activeWorkspace = RED.view.getWorkspace();
|
activeWorkspace = RED.workspaces.active();
|
||||||
}
|
}
|
||||||
|
|
||||||
var node_map = {};
|
var node_map = {};
|
||||||
|
147
public/red/ui/clipboard.js
Normal file
147
public/red/ui/clipboard.js
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
RED.clipboard = (function() {
|
||||||
|
|
||||||
|
var dialog = $('<div id="clipboard-dialog" class="hide"><form class="dialog-form form-horizontal"></form></div>')
|
||||||
|
.appendTo("body")
|
||||||
|
.dialog({
|
||||||
|
modal: true,
|
||||||
|
autoOpen: false,
|
||||||
|
width: 500,
|
||||||
|
resizable: false,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
id: "clipboard-dialog-ok",
|
||||||
|
text: "Ok",
|
||||||
|
click: function() {
|
||||||
|
if (/Import/.test(dialog.dialog("option","title"))) {
|
||||||
|
RED.view.importNodes($("#clipboard-import").val());
|
||||||
|
}
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "clipboard-dialog-cancel",
|
||||||
|
text: "Cancel",
|
||||||
|
click: function() {
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "clipboard-dialog-close",
|
||||||
|
text: "Close",
|
||||||
|
click: function() {
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
open: function(e) {
|
||||||
|
$(this).parent().find(".ui-dialog-titlebar-close").hide();
|
||||||
|
RED.keyboard.disable();
|
||||||
|
},
|
||||||
|
close: function(e) {
|
||||||
|
RED.keyboard.enable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var dialogContainer = dialog.children(".dialog-form");
|
||||||
|
|
||||||
|
var exportNodesDialog = '<div class="form-row">'+
|
||||||
|
'<label for="node-input-export" style="display: block; width:100%;"><i class="fa fa-clipboard"></i> Nodes:</label>'+
|
||||||
|
'<textarea readonly style="resize: none; width: 100%; border-radius: 0px;font-family: monospace; font-size: 12px; background:#eee; padding-left: 0.5em; box-sizing:border-box;" id="clipboard-export" rows="5"></textarea>'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-tips">'+
|
||||||
|
'Select the text above and copy to the clipboard with Ctrl-C.'+
|
||||||
|
'</div>';
|
||||||
|
|
||||||
|
var importNodesDialog = '<div class="form-row">'+
|
||||||
|
'<textarea style="resize: none; width: 100%; border-radius: 0px;font-family: monospace; font-size: 12px; background:#eee; padding-left: 0.5em; box-sizing:border-box;" id="clipboard-import" rows="5" placeholder="Paste nodes here"></textarea>'+
|
||||||
|
'</div>';
|
||||||
|
|
||||||
|
|
||||||
|
function importNodes() {
|
||||||
|
dialogContainer.empty();
|
||||||
|
dialogContainer.append($(importNodesDialog));
|
||||||
|
$("#clipboard-dialog-ok").show();
|
||||||
|
$("#clipboard-dialog-cancel").show();
|
||||||
|
$("#clipboard-dialog-close").hide();
|
||||||
|
$("#clipboard-dialog-ok").button("disable");
|
||||||
|
$("#clipboard-import").keyup(function() {
|
||||||
|
var v = $(this).val();
|
||||||
|
try {
|
||||||
|
JSON.parse(v);
|
||||||
|
$(this).removeClass("input-error");
|
||||||
|
$("#clipboard-dialog-ok").button("enable");
|
||||||
|
} catch(err) {
|
||||||
|
if (v !== "") {
|
||||||
|
$(this).addClass("input-error");
|
||||||
|
}
|
||||||
|
$("#clipboard-dialog-ok").button("disable");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.dialog("option","title","Import nodes").dialog("open");
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportNodes() {
|
||||||
|
dialogContainer.empty();
|
||||||
|
dialogContainer.append($(exportNodesDialog));
|
||||||
|
$("#clipboard-dialog-ok").hide();
|
||||||
|
$("#clipboard-dialog-cancel").hide();
|
||||||
|
$("#clipboard-dialog-close").show();
|
||||||
|
var selection = RED.view.selection();
|
||||||
|
if (selection.nodes) {
|
||||||
|
var nns = RED.nodes.createExportableNodeSet(selection.nodes);
|
||||||
|
$("#clipboard-export")
|
||||||
|
.val(JSON.stringify(nns))
|
||||||
|
.focus(function() {
|
||||||
|
var textarea = $(this);
|
||||||
|
textarea.select();
|
||||||
|
textarea.mouseup(function() {
|
||||||
|
textarea.unbind("mouseup");
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
dialog.dialog("option","title","Export nodes to clipboard").dialog( "open" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: function() {
|
||||||
|
RED.view.on("selection-changed",function(selection) {
|
||||||
|
if (!selection.nodes) {
|
||||||
|
RED.menu.setDisabled("btn-export-menu",true);
|
||||||
|
RED.menu.setDisabled("btn-export-clipboard",true);
|
||||||
|
RED.menu.setDisabled("btn-export-library",true);
|
||||||
|
} else {
|
||||||
|
RED.menu.setDisabled("btn-export-menu",false);
|
||||||
|
RED.menu.setDisabled("btn-export-clipboard",false);
|
||||||
|
RED.menu.setDisabled("btn-export-library",false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
RED.keyboard.add(/* e */ 69,{ctrl:true},function(){exportNodes();d3.event.preventDefault();});
|
||||||
|
RED.keyboard.add(/* i */ 73,{ctrl:true},function(){importNodes();d3.event.preventDefault();});
|
||||||
|
},
|
||||||
|
import: importNodes,
|
||||||
|
export: exportNodes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
@ -234,24 +234,20 @@ RED.editor = (function() {
|
|||||||
editing_node.dirty = true;
|
editing_node.dirty = true;
|
||||||
validateNode(editing_node);
|
validateNode(editing_node);
|
||||||
RED.view.redraw();
|
RED.view.redraw();
|
||||||
} else if (RED.view.state() == RED.state.EXPORT) {
|
} else if (/Export nodes to library/.test($( "#dialog" ).dialog("option","title"))) {
|
||||||
if (/library/.test($( "#dialog" ).dialog("option","title"))) {
|
//TODO: move this to RED.library
|
||||||
//TODO: move this to RED.library
|
var flowName = $("#node-input-filename").val();
|
||||||
var flowName = $("#node-input-filename").val();
|
if (!/^\s*$/.test(flowName)) {
|
||||||
if (!/^\s*$/.test(flowName)) {
|
$.ajax({
|
||||||
$.ajax({
|
url:'library/flows/'+flowName,
|
||||||
url:'library/flows/'+flowName,
|
type: "POST",
|
||||||
type: "POST",
|
data: $("#node-input-filename").attr('nodes'),
|
||||||
data: $("#node-input-filename").attr('nodes'),
|
contentType: "application/json; charset=utf-8"
|
||||||
contentType: "application/json; charset=utf-8"
|
}).done(function() {
|
||||||
}).done(function() {
|
RED.library.loadFlowLibrary();
|
||||||
RED.library.loadFlowLibrary();
|
RED.notify("Saved nodes","success");
|
||||||
RED.notify("Saved nodes","success");
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (RED.view.state() == RED.state.IMPORT) {
|
|
||||||
RED.view.importNodes($("#node-input-import").val());
|
|
||||||
}
|
}
|
||||||
$( this ).dialog( "close" );
|
$( this ).dialog( "close" );
|
||||||
}
|
}
|
||||||
@ -500,7 +496,7 @@ RED.editor = (function() {
|
|||||||
class: 'leftButton',
|
class: 'leftButton',
|
||||||
text: "Edit flow",
|
text: "Edit flow",
|
||||||
click: function() {
|
click: function() {
|
||||||
RED.view.showSubflow(id);
|
RED.workspaces.show(id);
|
||||||
$("#node-dialog-ok").click();
|
$("#node-dialog-ok").click();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -380,6 +380,14 @@ RED.library = (function() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function exportFlow() {
|
||||||
|
//TODO: don't rely on the main dialog
|
||||||
|
var nns = RED.nodes.createExportableNodeSet(RED.view.selection().nodes);
|
||||||
|
$("#dialog-form").html($("script[data-template-name='export-library-dialog']").html());
|
||||||
|
$("#node-input-filename").attr('nodes',JSON.stringify(nns));
|
||||||
|
$( "#dialog" ).dialog("option","title","Export nodes to library").dialog( "open" );
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: function() {
|
init: function() {
|
||||||
RED.view.on("selection-changed",function(selection) {
|
RED.view.on("selection-changed",function(selection) {
|
||||||
@ -397,7 +405,9 @@ RED.library = (function() {
|
|||||||
loadFlowLibrary();
|
loadFlowLibrary();
|
||||||
},
|
},
|
||||||
create: createUI,
|
create: createUI,
|
||||||
loadFlowLibrary: loadFlowLibrary
|
loadFlowLibrary: loadFlowLibrary,
|
||||||
|
|
||||||
|
export: exportFlow
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -59,7 +59,6 @@ RED.sidebar = (function() {
|
|||||||
$("#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("btn-sidebar",true);
|
||||||
RED.view.resize();
|
|
||||||
eventHandler.emit("resize");
|
eventHandler.emit("resize");
|
||||||
}
|
}
|
||||||
sidebarSeparator.width = $("#sidebar").width();
|
sidebarSeparator.width = $("#sidebar").width();
|
||||||
@ -100,11 +99,9 @@ RED.sidebar = (function() {
|
|||||||
$("#sidebar").width(newSidebarWidth);
|
$("#sidebar").width(newSidebarWidth);
|
||||||
|
|
||||||
sidebar_tabs.resize();
|
sidebar_tabs.resize();
|
||||||
RED.view.resize();
|
|
||||||
eventHandler.emit("resize");
|
eventHandler.emit("resize");
|
||||||
},
|
},
|
||||||
stop:function(event,ui) {
|
stop:function(event,ui) {
|
||||||
RED.view.resize();
|
|
||||||
if (sidebarSeparator.closing) {
|
if (sidebarSeparator.closing) {
|
||||||
$("#sidebar").removeClass("closing");
|
$("#sidebar").removeClass("closing");
|
||||||
RED.menu.setSelected("btn-sidebar",false);
|
RED.menu.setSelected("btn-sidebar",false);
|
||||||
|
@ -18,7 +18,7 @@ RED.subflow = (function() {
|
|||||||
|
|
||||||
|
|
||||||
function getSubflow() {
|
function getSubflow() {
|
||||||
return RED.nodes.subflow(RED.view.getWorkspace());
|
return RED.nodes.subflow(RED.workspaces.active());
|
||||||
}
|
}
|
||||||
|
|
||||||
function findAvailableSubflowIOPosition(subflow) {
|
function findAvailableSubflowIOPosition(subflow) {
|
||||||
@ -39,7 +39,7 @@ RED.subflow = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addSubflowInput() {
|
function addSubflowInput() {
|
||||||
var subflow = RED.nodes.subflow(RED.view.getWorkspace());
|
var subflow = RED.nodes.subflow(RED.workspaces.active());
|
||||||
var position = findAvailableSubflowIOPosition(subflow);
|
var position = findAvailableSubflowIOPosition(subflow);
|
||||||
var newInput = {
|
var newInput = {
|
||||||
type:"subflow",
|
type:"subflow",
|
||||||
@ -79,7 +79,7 @@ RED.subflow = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addSubflowOutput(id) {
|
function addSubflowOutput(id) {
|
||||||
var subflow = RED.nodes.subflow(RED.view.getWorkspace());
|
var subflow = RED.nodes.subflow(RED.workspaces.active());
|
||||||
var position = findAvailableSubflowIOPosition(subflow);
|
var position = findAvailableSubflowIOPosition(subflow);
|
||||||
|
|
||||||
var newOutput = {
|
var newOutput = {
|
||||||
@ -120,7 +120,7 @@ RED.subflow = (function() {
|
|||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
$("#workspace-subflow-edit").click(function(event) {
|
$("#workspace-subflow-edit").click(function(event) {
|
||||||
RED.editor.editSubflow(RED.nodes.subflow(RED.view.getWorkspace()));
|
RED.editor.editSubflow(RED.nodes.subflow(RED.workspaces.active()));
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
$("#workspace-subflow-add-input").click(function(event) {
|
$("#workspace-subflow-add-input").click(function(event) {
|
||||||
@ -170,7 +170,7 @@ RED.subflow = (function() {
|
|||||||
dirty:startDirty
|
dirty:startDirty
|
||||||
});
|
});
|
||||||
|
|
||||||
RED.view.removeWorkspace(activeSubflow);
|
RED.workspaces.remove(activeSubflow);
|
||||||
RED.view.dirty(true);
|
RED.view.dirty(true);
|
||||||
RED.view.redraw();
|
RED.view.redraw();
|
||||||
});
|
});
|
||||||
@ -210,7 +210,7 @@ RED.subflow = (function() {
|
|||||||
subflow: subflow,
|
subflow: subflow,
|
||||||
dirty:RED.view.dirty()
|
dirty:RED.view.dirty()
|
||||||
});
|
});
|
||||||
RED.view.showSubflow(subflowId);
|
RED.workspaces.show(subflowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertToSubflow() {
|
function convertToSubflow() {
|
||||||
@ -328,7 +328,7 @@ RED.subflow = (function() {
|
|||||||
type:"subflow:"+subflow.id,
|
type:"subflow:"+subflow.id,
|
||||||
x: center[0],
|
x: center[0],
|
||||||
y: center[1],
|
y: center[1],
|
||||||
z: RED.view.getWorkspace(),
|
z: RED.workspaces.active(),
|
||||||
inputs: subflow.in.length,
|
inputs: subflow.in.length,
|
||||||
outputs: subflow.out.length,
|
outputs: subflow.out.length,
|
||||||
h: Math.max(30/*node_height*/,(subflow.out.length||0) * 15),
|
h: Math.max(30/*node_height*/,(subflow.out.length||0) * 15),
|
||||||
@ -381,7 +381,7 @@ RED.subflow = (function() {
|
|||||||
links:new_links,
|
links:new_links,
|
||||||
subflow: subflow,
|
subflow: subflow,
|
||||||
|
|
||||||
activeWorkspace: RED.view.getWorkspace(),
|
activeWorkspace: RED.workspaces.active(),
|
||||||
removedLinks: removedLinks,
|
removedLinks: removedLinks,
|
||||||
|
|
||||||
dirty:RED.view.dirty()
|
dirty:RED.view.dirty()
|
||||||
|
@ -148,7 +148,7 @@ RED.sidebar.info = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var subflow = RED.nodes.subflow(RED.view.getWorkspace());
|
var subflow = RED.nodes.subflow(RED.workspaces.active());
|
||||||
if (subflow) {
|
if (subflow) {
|
||||||
refresh(subflow);
|
refresh(subflow);
|
||||||
} else {
|
} else {
|
||||||
|
@ -29,14 +29,13 @@ RED.view = (function() {
|
|||||||
moveTouchCenter = [],
|
moveTouchCenter = [],
|
||||||
touchStartTime = 0;
|
touchStartTime = 0;
|
||||||
|
|
||||||
|
var workspaceScrollPositions = {};
|
||||||
|
|
||||||
|
|
||||||
var activeWorkspace = 0;
|
|
||||||
var activeSubflow = null;
|
var activeSubflow = null;
|
||||||
var activeNodes = [];
|
var activeNodes = [];
|
||||||
var activeLinks = [];
|
var activeLinks = [];
|
||||||
|
|
||||||
var workspaceScrollPositions = {};
|
|
||||||
|
|
||||||
var selected_link = null,
|
var selected_link = null,
|
||||||
mousedown_link = null,
|
mousedown_link = null,
|
||||||
mousedown_node = null,
|
mousedown_node = null,
|
||||||
@ -234,40 +233,38 @@ 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");
|
||||||
|
|
||||||
function updateActiveNodes() {
|
function updateActiveNodes() {
|
||||||
|
//TODO: remove direct access to RED.nodes.nodes
|
||||||
activeNodes = RED.nodes.nodes.filter(function(d) {
|
activeNodes = RED.nodes.nodes.filter(function(d) {
|
||||||
return d.z == activeWorkspace;
|
return d.z == RED.workspaces.active();
|
||||||
});
|
});
|
||||||
activeLinks = RED.nodes.links.filter(function(d) {
|
activeLinks = RED.nodes.links.filter(function(d) {
|
||||||
return d.source.z == activeWorkspace && d.target.z == activeWorkspace;
|
return d.source.z == RED.workspaces.active() && d.target.z == RED.workspaces.active();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var workspace_tabs = RED.tabs.create({
|
function init() {
|
||||||
id: "workspace-tabs",
|
RED.workspaces.on("change",function(event) {
|
||||||
onchange: function(tab) {
|
|
||||||
if (tab.type == "subflow") {
|
|
||||||
$("#workspace-toolbar").show();
|
|
||||||
} else {
|
|
||||||
$("#workspace-toolbar").hide();
|
|
||||||
}
|
|
||||||
var chart = $("#chart");
|
var chart = $("#chart");
|
||||||
if (activeWorkspace !== 0) {
|
if (event.old !== 0) {
|
||||||
workspaceScrollPositions[activeWorkspace] = {
|
workspaceScrollPositions[event.old] = {
|
||||||
left:chart.scrollLeft(),
|
left:chart.scrollLeft(),
|
||||||
top:chart.scrollTop()
|
top:chart.scrollTop()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var scrollStartLeft = chart.scrollLeft();
|
var scrollStartLeft = chart.scrollLeft();
|
||||||
var scrollStartTop = chart.scrollTop();
|
var scrollStartTop = chart.scrollTop();
|
||||||
|
|
||||||
activeWorkspace = tab.id;
|
activeSubflow = RED.nodes.subflow(event.workspace);
|
||||||
activeSubflow = RED.nodes.subflow(activeWorkspace);
|
|
||||||
if (activeSubflow) {
|
if (activeSubflow) {
|
||||||
$("#workspace-subflow-add-input").toggleClass("disabled",activeSubflow.in.length > 0);
|
$("#workspace-subflow-add-input").toggleClass("disabled",activeSubflow.in.length > 0);
|
||||||
}
|
}
|
||||||
if (workspaceScrollPositions[activeWorkspace]) {
|
|
||||||
chart.scrollLeft(workspaceScrollPositions[activeWorkspace].left);
|
RED.menu.setDisabled("btn-workspace-edit", activeSubflow);
|
||||||
chart.scrollTop(workspaceScrollPositions[activeWorkspace].top);
|
RED.menu.setDisabled("btn-workspace-delete",RED.workspaces.count() == 1 || activeSubflow);
|
||||||
|
|
||||||
|
if (workspaceScrollPositions[event.workspace]) {
|
||||||
|
chart.scrollLeft(workspaceScrollPositions[event.workspace].left);
|
||||||
|
chart.scrollTop(workspaceScrollPositions[event.workspace].top);
|
||||||
} else {
|
} else {
|
||||||
chart.scrollLeft(0);
|
chart.scrollLeft(0);
|
||||||
chart.scrollTop(0);
|
chart.scrollTop(0);
|
||||||
@ -278,10 +275,6 @@ RED.view = (function() {
|
|||||||
mouse_position[0] += scrollDeltaLeft;
|
mouse_position[0] += scrollDeltaLeft;
|
||||||
mouse_position[1] += scrollDeltaTop;
|
mouse_position[1] += scrollDeltaTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
RED.menu.setDisabled("btn-workspace-edit", activeSubflow);
|
|
||||||
RED.menu.setDisabled("btn-workspace-delete",workspace_tabs.count() == 1 || activeSubflow);
|
|
||||||
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
RED.nodes.eachNode(function(n) {
|
RED.nodes.eachNode(function(n) {
|
||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
@ -289,69 +282,8 @@ RED.view = (function() {
|
|||||||
updateSelection();
|
updateSelection();
|
||||||
updateActiveNodes();
|
updateActiveNodes();
|
||||||
redraw();
|
redraw();
|
||||||
},
|
|
||||||
ondblclick: function(tab) {
|
|
||||||
if (tab.type != "subflow") {
|
|
||||||
showRenameWorkspaceDialog(tab.id);
|
|
||||||
} else {
|
|
||||||
RED.editor.editSubflow(RED.nodes.subflow(tab.id));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onadd: function(tab) {
|
|
||||||
RED.menu.addItem("btn-workspace-menu",{
|
|
||||||
id:"btn-workspace-menu-"+tab.id.replace(".","-"),
|
|
||||||
label:tab.label,
|
|
||||||
onselect:function() {
|
|
||||||
workspace_tabs.activateTab(tab.id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
RED.menu.setDisabled("btn-workspace-delete",workspace_tabs.count() == 1);
|
|
||||||
updateActiveNodes();
|
|
||||||
},
|
|
||||||
onremove: function(tab) {
|
|
||||||
RED.menu.setDisabled("btn-workspace-delete",workspace_tabs.count() == 1);
|
|
||||||
RED.menu.removeItem("btn-workspace-menu-"+tab.id.replace(".","-"));
|
|
||||||
updateActiveNodes();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var workspaceIndex = 0;
|
|
||||||
|
|
||||||
function addWorkspace() {
|
|
||||||
var tabId = RED.nodes.id();
|
|
||||||
do {
|
|
||||||
workspaceIndex += 1;
|
|
||||||
} while($("#workspace-tabs a[title='Sheet "+workspaceIndex+"']").size() !== 0);
|
|
||||||
|
|
||||||
var ws = {type:"tab",id:tabId,label:"Sheet "+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);
|
|
||||||
}
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
$('#btn-workspace-add-tab').on("click",addWorkspace);
|
|
||||||
|
|
||||||
RED.menu.setAction('btn-workspace-add',addWorkspace);
|
|
||||||
RED.menu.setAction('btn-workspace-edit',function() {
|
|
||||||
showRenameWorkspaceDialog(activeWorkspace);
|
|
||||||
});
|
});
|
||||||
RED.menu.setAction('btn-workspace-delete',function() {
|
|
||||||
deleteWorkspace(activeWorkspace);
|
|
||||||
});
|
|
||||||
updateActiveNodes();
|
|
||||||
}
|
|
||||||
|
|
||||||
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');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function canvasMouseDown() {
|
function canvasMouseDown() {
|
||||||
@ -530,7 +462,7 @@ RED.view = (function() {
|
|||||||
clearSelection();
|
clearSelection();
|
||||||
}
|
}
|
||||||
RED.nodes.eachNode(function(n) {
|
RED.nodes.eachNode(function(n) {
|
||||||
if (n.z == activeWorkspace && !n.selected) {
|
if (n.z == RED.workspaces.active() && !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;
|
||||||
@ -625,7 +557,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,z:activeWorkspace};
|
var nn = { id:(1+Math.random()*4294967295).toString(16),x: mousePos[0],y:mousePos[1],w:node_width,z:RED.workspaces.active()};
|
||||||
|
|
||||||
nn.type = selected_tool;
|
nn.type = selected_tool;
|
||||||
nn._def = RED.nodes.getType(nn.type);
|
nn._def = RED.nodes.getType(nn.type);
|
||||||
@ -688,7 +620,7 @@ RED.view = (function() {
|
|||||||
|
|
||||||
function selectAll() {
|
function selectAll() {
|
||||||
RED.nodes.eachNode(function(n) {
|
RED.nodes.eachNode(function(n) {
|
||||||
if (n.z == activeWorkspace) {
|
if (n.z == RED.workspaces.active()) {
|
||||||
if (!n.selected) {
|
if (!n.selected) {
|
||||||
n.selected = true;
|
n.selected = true;
|
||||||
n.dirty = true;
|
n.dirty = true;
|
||||||
@ -960,7 +892,7 @@ RED.view = (function() {
|
|||||||
if (mouse_mode == RED.state.JOINING && mousedown_node) {
|
if (mouse_mode == RED.state.JOINING && mousedown_node) {
|
||||||
if (typeof TouchEvent != "undefined" && d3.event instanceof TouchEvent) {
|
if (typeof TouchEvent != "undefined" && d3.event instanceof TouchEvent) {
|
||||||
RED.nodes.eachNode(function(n) {
|
RED.nodes.eachNode(function(n) {
|
||||||
if (n.z == activeWorkspace) {
|
if (n.z == RED.workspaces.active()) {
|
||||||
var hw = n.w/2;
|
var hw = n.w/2;
|
||||||
var hh = n.h/2;
|
var hh = n.h/2;
|
||||||
if (n.x-hw<mouse_position[0] && n.x+hw> mouse_position[0] &&
|
if (n.x-hw<mouse_position[0] && n.x+hw> mouse_position[0] &&
|
||||||
@ -1246,7 +1178,7 @@ RED.view = (function() {
|
|||||||
vis.selectAll(".subflowinput").remove();
|
vis.selectAll(".subflowinput").remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
//var node = vis.selectAll(".nodegroup").data(RED.nodes.nodes.filter(function(d) { return d.z == activeWorkspace }),function(d){return d.id});
|
//var node = vis.selectAll(".nodegroup").data(RED.nodes.nodes.filter(function(d) { return d.z == RED.workspaces.active() }),function(d){return d.id});
|
||||||
var node = vis.selectAll(".nodegroup").data(activeNodes,function(d){return d.id});
|
var node = vis.selectAll(".nodegroup").data(activeNodes,function(d){return d.id});
|
||||||
node.exit().remove();
|
node.exit().remove();
|
||||||
|
|
||||||
@ -1712,8 +1644,6 @@ RED.view = (function() {
|
|||||||
RED.keyboard.add(/* - */ 189,{ctrl:true},function(){zoomOut();d3.event.preventDefault();});
|
RED.keyboard.add(/* - */ 189,{ctrl:true},function(){zoomOut();d3.event.preventDefault();});
|
||||||
RED.keyboard.add(/* 0 */ 48,{ctrl:true},function(){zoomZero();d3.event.preventDefault();});
|
RED.keyboard.add(/* 0 */ 48,{ctrl:true},function(){zoomZero();d3.event.preventDefault();});
|
||||||
RED.keyboard.add(/* v */ 86,{ctrl:true},function(){importNodes(clipboard);d3.event.preventDefault();});
|
RED.keyboard.add(/* v */ 86,{ctrl:true},function(){importNodes(clipboard);d3.event.preventDefault();});
|
||||||
RED.keyboard.add(/* e */ 69,{ctrl:true},function(){showExportNodesDialog();d3.event.preventDefault();});
|
|
||||||
RED.keyboard.add(/* i */ 73,{ctrl:true},function(){showImportNodesDialog();d3.event.preventDefault();});
|
|
||||||
|
|
||||||
// TODO: 'dirty' should be a property of RED.nodes - with an event callback for ui hooks
|
// TODO: 'dirty' should be a property of RED.nodes - with an event callback for ui hooks
|
||||||
function setDirty(d) {
|
function setDirty(d) {
|
||||||
@ -1744,7 +1674,7 @@ RED.view = (function() {
|
|||||||
var new_workspaces = result[2];
|
var new_workspaces = result[2];
|
||||||
var new_subflows = result[3];
|
var new_subflows = result[3];
|
||||||
|
|
||||||
var new_ms = new_nodes.filter(function(n) { return n.z == activeWorkspace }).map(function(n) { return {n:n};});
|
var new_ms = new_nodes.filter(function(n) { return n.z == RED.workspaces.active() }).map(function(n) { 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
|
||||||
@ -1816,136 +1746,6 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showExportNodesDialog() {
|
|
||||||
mouse_mode = RED.state.EXPORT;
|
|
||||||
var nns = RED.nodes.createExportableNodeSet(moving_set);
|
|
||||||
$("#dialog-form").html($("script[data-template-name='export-clipboard-dialog']").html());
|
|
||||||
$("#node-input-export").val(JSON.stringify(nns));
|
|
||||||
$("#node-input-export").focus(function() {
|
|
||||||
var textarea = $(this);
|
|
||||||
textarea.select();
|
|
||||||
textarea.mouseup(function() {
|
|
||||||
textarea.unbind("mouseup");
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
$( "#dialog" ).dialog("option","title","Export nodes to clipboard").dialog( "open" );
|
|
||||||
$("#node-input-export").focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
function showExportNodesLibraryDialog() {
|
|
||||||
mouse_mode = RED.state.EXPORT;
|
|
||||||
var nns = RED.nodes.createExportableNodeSet(moving_set);
|
|
||||||
$("#dialog-form").html($("script[data-template-name='export-library-dialog']").html());
|
|
||||||
$("#node-input-filename").attr('nodes',JSON.stringify(nns));
|
|
||||||
$( "#dialog" ).dialog("option","title","Export nodes to library").dialog( "open" );
|
|
||||||
}
|
|
||||||
|
|
||||||
function showImportNodesDialog() {
|
|
||||||
mouse_mode = RED.state.IMPORT;
|
|
||||||
$("#dialog-form").html($("script[data-template-name='import-dialog']").html());
|
|
||||||
$("#node-input-import").val("");
|
|
||||||
$( "#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 sheet",
|
|
||||||
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_tabs.renameTab(workspace.id,label);
|
|
||||||
RED.view.dirty(true);
|
|
||||||
$("#btn-workspace-menu-"+workspace.id.replace(".","-")).text(label);
|
|
||||||
// TODO: update entry in menu
|
|
||||||
}
|
|
||||||
$( this ).dialog( "close" );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Cancel",
|
|
||||||
click: function() {
|
|
||||||
$( this ).dialog( "close" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
open: function(e) {
|
|
||||||
RED.keyboard.disable();
|
|
||||||
},
|
|
||||||
close: function(e) {
|
|
||||||
RED.keyboard.enable();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$( "#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" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
open: function(e) {
|
|
||||||
RED.keyboard.disable();
|
|
||||||
},
|
|
||||||
close: function(e) {
|
|
||||||
RED.keyboard.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
function hideDropTarget() {
|
function hideDropTarget() {
|
||||||
$("#dropTarget").hide();
|
$("#dropTarget").hide();
|
||||||
RED.keyboard.remove(/* ESCAPE */ 27);
|
RED.keyboard.remove(/* ESCAPE */ 27);
|
||||||
@ -2004,30 +1804,12 @@ RED.view = (function() {
|
|||||||
mouse_mode = state;
|
mouse_mode = state;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addWorkspace: function(ws) {
|
|
||||||
workspace_tabs.addTab(ws);
|
|
||||||
workspace_tabs.resize();
|
|
||||||
},
|
|
||||||
removeWorkspace: function(ws) {
|
|
||||||
if (workspace_tabs.contains(ws.id)) {
|
|
||||||
workspace_tabs.removeTab(ws.id);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getWorkspace: function() {
|
|
||||||
return activeWorkspace;
|
|
||||||
},
|
|
||||||
showWorkspace: function(id) {
|
|
||||||
workspace_tabs.activateTab(id);
|
|
||||||
},
|
|
||||||
redraw: function(updateActive) {
|
redraw: function(updateActive) {
|
||||||
if (updateActive) {
|
if (updateActive) {
|
||||||
updateActiveNodes();
|
updateActiveNodes();
|
||||||
}
|
}
|
||||||
RED.nodes.eachSubflow(function(sf) {
|
RED.workspaces.refresh();
|
||||||
if (workspace_tabs.contains(sf.id)) {
|
|
||||||
workspace_tabs.renameTab(sf.id,"Subflow: "+sf.name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
redraw();
|
redraw();
|
||||||
},
|
},
|
||||||
dirty: function(d) {
|
dirty: function(d) {
|
||||||
@ -2039,14 +1821,15 @@ RED.view = (function() {
|
|||||||
},
|
},
|
||||||
focus: focusView,
|
focus: focusView,
|
||||||
importNodes: importNodes,
|
importNodes: importNodes,
|
||||||
resize: function() {
|
|
||||||
workspace_tabs.resize();
|
|
||||||
},
|
|
||||||
status: function(s) {
|
status: function(s) {
|
||||||
showStatus = s;
|
if (s == null) {
|
||||||
RED.nodes.eachNode(function(n) { n.dirty = true;});
|
return showStatus;
|
||||||
//TODO: subscribe/unsubscribe here
|
} else {
|
||||||
redraw();
|
showStatus = s;
|
||||||
|
RED.nodes.eachNode(function(n) { n.dirty = true;});
|
||||||
|
//TODO: subscribe/unsubscribe here
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
calculateTextWidth: calculateTextWidth,
|
calculateTextWidth: calculateTextWidth,
|
||||||
select: function(selection) {
|
select: function(selection) {
|
||||||
@ -2073,26 +1856,6 @@ RED.view = (function() {
|
|||||||
selection.link = selected_link;
|
selection.link = selected_link;
|
||||||
}
|
}
|
||||||
return selection;
|
return selection;
|
||||||
},
|
|
||||||
//TODO: should these move to an import/export module?
|
|
||||||
showImportNodesDialog: showImportNodesDialog,
|
|
||||||
showExportNodesDialog: showExportNodesDialog,
|
|
||||||
showExportNodesLibraryDialog: showExportNodesLibraryDialog,
|
|
||||||
addFlow: function() {
|
|
||||||
var ws = {type:"subflow",id:RED.nodes.id(),label:"Flow 1", closeable: true};
|
|
||||||
RED.nodes.addWorkspace(ws);
|
|
||||||
workspace_tabs.addTab(ws);
|
|
||||||
workspace_tabs.activateTab(ws.id);
|
|
||||||
return ws;
|
|
||||||
},
|
|
||||||
|
|
||||||
showSubflow: function(id) {
|
|
||||||
if (!workspace_tabs.contains(id)) {
|
|
||||||
var sf = RED.nodes.subflow(id);
|
|
||||||
workspace_tabs.addTab({type:"subflow",id:id,label:"Subflow: "+sf.name, closeable: true});
|
|
||||||
workspace_tabs.resize();
|
|
||||||
}
|
|
||||||
workspace_tabs.activateTab(id);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
273
public/red/ui/workspaces.js
Normal file
273
public/red/ui/workspaces.js
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
RED.workspaces = (function() {
|
||||||
|
|
||||||
|
var activeWorkspace = 0;
|
||||||
|
var workspaceIndex = 0;
|
||||||
|
|
||||||
|
function addWorkspace(ws) {
|
||||||
|
if (ws) {
|
||||||
|
workspace_tabs.addTab(ws);
|
||||||
|
workspace_tabs.resize();
|
||||||
|
} else {
|
||||||
|
var tabId = RED.nodes.id();
|
||||||
|
do {
|
||||||
|
workspaceIndex += 1;
|
||||||
|
} while($("#workspace-tabs a[title='Sheet "+workspaceIndex+"']").size() !== 0);
|
||||||
|
|
||||||
|
ws = {type:"tab",id:tabId,label:"Sheet "+workspaceIndex};
|
||||||
|
RED.nodes.addWorkspace(ws);
|
||||||
|
workspace_tabs.addTab(ws);
|
||||||
|
workspace_tabs.activateTab(tabId);
|
||||||
|
RED.history.push({t:'add',workspaces:[ws],dirty:RED.view.dirty()});
|
||||||
|
RED.view.dirty(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function deleteWorkspace(ws,force) {
|
||||||
|
if (workspace_tabs.count() == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var nodes = [];
|
||||||
|
if (!force) {
|
||||||
|
//TODO: remove direct access to RED.nodes.nodes
|
||||||
|
nodes = RED.nodes.nodes.filter(function(d) {
|
||||||
|
return d.z == ws.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (force || nodes.length === 0) {
|
||||||
|
removeWorkspace(ws);
|
||||||
|
var historyEvent = RED.nodes.removeWorkspace(ws.id);
|
||||||
|
historyEvent.t = 'delete';
|
||||||
|
historyEvent.dirty = RED.view.dirty();
|
||||||
|
historyEvent.workspaces = [ws];
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
RED.view.dirty(true);
|
||||||
|
} else {
|
||||||
|
$( "#node-dialog-delete-workspace" ).dialog('option','workspace',ws);
|
||||||
|
$( "#node-dialog-delete-workspace-name" ).text(ws.label);
|
||||||
|
$( "#node-dialog-delete-workspace" ).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");
|
||||||
|
}
|
||||||
|
|
||||||
|
var workspace_tabs = RED.tabs.create({
|
||||||
|
id: "workspace-tabs",
|
||||||
|
onchange: function(tab) {
|
||||||
|
if (tab.type == "subflow") {
|
||||||
|
$("#workspace-toolbar").show();
|
||||||
|
} else {
|
||||||
|
$("#workspace-toolbar").hide();
|
||||||
|
}
|
||||||
|
var event = {
|
||||||
|
old: activeWorkspace
|
||||||
|
}
|
||||||
|
activeWorkspace = tab.id;
|
||||||
|
event.workspace = activeWorkspace;
|
||||||
|
|
||||||
|
eventHandler.emit("change",event);
|
||||||
|
},
|
||||||
|
ondblclick: function(tab) {
|
||||||
|
if (tab.type != "subflow") {
|
||||||
|
showRenameWorkspaceDialog(tab.id);
|
||||||
|
} else {
|
||||||
|
RED.editor.editSubflow(RED.nodes.subflow(tab.id));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onadd: function(tab) {
|
||||||
|
RED.menu.addItem("btn-workspace-menu",{
|
||||||
|
id:"btn-workspace-menu-"+tab.id.replace(".","-"),
|
||||||
|
label:tab.label,
|
||||||
|
onselect:function() {
|
||||||
|
workspace_tabs.activateTab(tab.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
RED.menu.setDisabled("btn-workspace-delete",workspace_tabs.count() == 1);
|
||||||
|
},
|
||||||
|
onremove: function(tab) {
|
||||||
|
RED.menu.setDisabled("btn-workspace-delete",workspace_tabs.count() == 1);
|
||||||
|
RED.menu.removeItem("btn-workspace-menu-"+tab.id.replace(".","-"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#node-dialog-rename-workspace form" ).submit(function(e) { e.preventDefault();});
|
||||||
|
$( "#node-dialog-rename-workspace" ).dialog({
|
||||||
|
modal: true,
|
||||||
|
autoOpen: false,
|
||||||
|
width: 500,
|
||||||
|
title: "Rename sheet",
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
class: 'leftButton',
|
||||||
|
text: "Delete",
|
||||||
|
click: function() {
|
||||||
|
var workspace = $(this).dialog('option','workspace');
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
deleteWorkspace(workspace);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Ok",
|
||||||
|
click: function() {
|
||||||
|
var workspace = $(this).dialog('option','workspace');
|
||||||
|
var label = $( "#node-input-workspace-name" ).val();
|
||||||
|
if (workspace.label != label) {
|
||||||
|
workspace_tabs.renameTab(workspace.id,label);
|
||||||
|
RED.view.dirty(true);
|
||||||
|
$("#btn-workspace-menu-"+workspace.id.replace(".","-")).text(label);
|
||||||
|
// TODO: update entry in menu
|
||||||
|
}
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Cancel",
|
||||||
|
click: function() {
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
open: function(e) {
|
||||||
|
RED.keyboard.disable();
|
||||||
|
},
|
||||||
|
close: function(e) {
|
||||||
|
RED.keyboard.enable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$( "#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');
|
||||||
|
deleteWorkspace(workspace,true);
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Cancel",
|
||||||
|
click: function() {
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
open: function(e) {
|
||||||
|
RED.keyboard.disable();
|
||||||
|
},
|
||||||
|
close: function(e) {
|
||||||
|
RED.keyboard.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
$('#btn-workspace-add-tab').on("click",function(e) {addWorkspace(); e.preventDefault()});
|
||||||
|
RED.sidebar.on("resize",workspace_tabs.resize);
|
||||||
|
|
||||||
|
RED.menu.setAction('btn-workspace-delete',function() {
|
||||||
|
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: DRY
|
||||||
|
var eventHandler = (function() {
|
||||||
|
var handlers = {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
on: function(evt,func) {
|
||||||
|
handlers[evt] = handlers[evt]||[];
|
||||||
|
handlers[evt].push(func);
|
||||||
|
},
|
||||||
|
emit: function(evt,arg) {
|
||||||
|
if (handlers[evt]) {
|
||||||
|
for (var i=0;i<handlers[evt].length;i++) {
|
||||||
|
handlers[evt][i](arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
function removeWorkspace(ws) {
|
||||||
|
if (!ws) {
|
||||||
|
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
|
||||||
|
} else {
|
||||||
|
if (workspace_tabs.contains(ws.id)) {
|
||||||
|
workspace_tabs.removeTab(ws.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
init: init,
|
||||||
|
on: eventHandler.on,
|
||||||
|
add: addWorkspace,
|
||||||
|
remove: removeWorkspace,
|
||||||
|
|
||||||
|
edit: function(id) {
|
||||||
|
showRenameWorkspaceDialog(id||activeWorkspace);
|
||||||
|
},
|
||||||
|
contains: function(id) {
|
||||||
|
return workspace_tabs.contains(id);
|
||||||
|
},
|
||||||
|
count: function() {
|
||||||
|
return workspace_tabs.count();
|
||||||
|
},
|
||||||
|
active: function() {
|
||||||
|
return activeWorkspace
|
||||||
|
},
|
||||||
|
show: function(id) {
|
||||||
|
if (!workspace_tabs.contains(id)) {
|
||||||
|
var sf = RED.nodes.subflow(id);
|
||||||
|
if (sf) {
|
||||||
|
addWorkspace({type:"subflow",id:id,label:"Subflow: "+sf.name, closeable: true});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
workspace_tabs.activateTab(id);
|
||||||
|
},
|
||||||
|
refresh: function() {
|
||||||
|
RED.nodes.eachSubflow(function(sf) {
|
||||||
|
if (workspace_tabs.contains(sf.id)) {
|
||||||
|
workspace_tabs.renameTab(sf.id,"Subflow: "+sf.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resize: function() {
|
||||||
|
workspace_tabs.resize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -752,7 +752,7 @@ g.link_unknown path.link_line {
|
|||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dialog-form, #dialog-config-form {
|
.dialog-form, #dialog-form, #dialog-config-form {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user