From b1df6d5149a1ea824f5907badff5770623e930de Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 12 Jan 2021 18:23:15 +0000 Subject: [PATCH] Add preview of exported nodes to Export dialog --- .../editor-client/src/js/ui/clipboard.js | 158 ++++++++++++++++-- .../editor-client/src/sass/library.scss | 24 ++- .../editor-client/src/sass/tab-info.scss | 2 +- 3 files changed, 165 insertions(+), 19 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js b/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js index e46c88b4f..4ed618f6d 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js @@ -72,9 +72,7 @@ RED.clipboard = (function() { text: RED._("clipboard.export.copy"), click: function() { if (activeTab === "red-ui-clipboard-dialog-export-tab-clipboard") { - $("#red-ui-clipboard-dialog-export-text").select(); - document.execCommand("copy"); - document.getSelection().removeAllRanges(); + copyText($("#red-ui-clipboard-dialog-export-text").val()); RED.notify(RED._("clipboard.nodesExported"),{id:"clipboard"}); $( this ).dialog( "close" ); } else { @@ -222,14 +220,22 @@ RED.clipboard = (function() { ''+ '
'+ '
'+ - '
'+ - ''+ + '
'+ + '
    '+ '
    '+ - '
    '+ - ''+ - ''+ - ''+ - ''+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + ''+ + '
    '+ + '
    '+ + ''+ + ''+ + ''+ + ''+ + '
    '+ '
    '+ '
    '+ '
    '+ @@ -592,6 +598,30 @@ RED.clipboard = (function() { }) loadFlowLibrary(libraryBrowser,"local",RED._("library.types.local")); + var clipboardTabs = RED.tabs.create({ + id: "red-ui-clipboard-dialog-export-tab-clipboard-tabs", + onchange: function(tab) { + $(".red-ui-clipboard-dialog-export-tab-clipboard-tab").hide(); + $("#" + tab.id).show(); + } + }); + + clipboardTabs.addTab({ + id: "red-ui-clipboard-dialog-export-tab-clipboard-preview", + label: RED._("clipboard.exportNodes") + }); + + clipboardTabs.addTab({ + id: "red-ui-clipboard-dialog-export-tab-clipboard-json", + label: RED._("editor.types.json") + }); + + + var previewList = $("#red-ui-clipboard-dialog-export-tab-clipboard-preview-list").css({position:"absolute",top:0,right:0,bottom:0,left:0}).treeList({ + data: [] + }) + refreshExportPreview(); + $("#red-ui-clipboard-dialog-tab-library-name").val("flows.json").select(); dialogContainer.i18n(); @@ -630,10 +660,10 @@ RED.clipboard = (function() { } $(this).parent().children().removeClass('selected'); $(this).addClass('selected'); - var type = $(this).attr('id'); + var type = $(this).attr('id').substring("red-ui-clipboard-dialog-export-rng-".length); var flow = ""; var nodes = null; - if (type === 'red-ui-clipboard-dialog-export-rng-selected') { + if (type === 'selected') { var selection = RED.workspaces.selection(); if (selection.length > 0) { nodes = []; @@ -647,14 +677,14 @@ RED.clipboard = (function() { } // Don't include the subflow meta-port nodes in the exported selection nodes = RED.nodes.createExportableNodeSet(nodes.filter(function(n) { return n.type !== 'subflow'})); - } else if (type === 'red-ui-clipboard-dialog-export-rng-flow') { + } else if (type === 'flow') { var activeWorkspace = RED.workspaces.active(); nodes = RED.nodes.groups(activeWorkspace); nodes = nodes.concat(RED.nodes.filterNodes({z:activeWorkspace})); var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace); nodes.unshift(parentNode); nodes = RED.nodes.createExportableNodeSet(nodes); - } else if (type === 'red-ui-clipboard-dialog-export-rng-full') { + } else if (type === 'full') { nodes = RED.nodes.createCompleteNodeSet(false); } if (nodes !== null) { @@ -670,8 +700,10 @@ RED.clipboard = (function() { $("#red-ui-clipboard-dialog-export").addClass('disabled'); } $("#red-ui-clipboard-dialog-export-text").val(flow); - setTimeout(function() { $("#red-ui-clipboard-dialog-export-text").scrollTop(0); },50); - $("#red-ui-clipboard-dialog-export-text").trigger("focus"); + setTimeout(function() { + $("#red-ui-clipboard-dialog-export-text").scrollTop(0); + refreshExportPreview(type); + },50); }) $("#red-ui-clipboard-dialog-ok").hide(); @@ -717,6 +749,93 @@ RED.clipboard = (function() { } + function refreshExportPreview(type) { + + var flowData = $("#red-ui-clipboard-dialog-export-text").val() || "[]"; + var flow = JSON.parse(flowData); + var flows = {}; + var subflows = {}; + var nodes = []; + var nodesByZ = {}; + + var treeFlows = []; + var treeSubflows = []; + + flow.forEach(function(node) { + if (node.type === "tab") { + flows[node.id] = { + element: getFlowLabel(node,false), + deferBuild: type !== "flow", + expanded: type === "flow", + children: [] + }; + treeFlows.push(flows[node.id]) + } else if (node.type === "subflow") { + subflows[node.id] = { + element: getNodeLabel(node,false), + deferBuild: true, + children: [] + }; + treeSubflows.push(subflows[node.id]) + } else { + nodes.push(node); + } + }); + + var globalNodes = []; + var parentlessNodes = []; + + nodes.forEach(function(node) { + var treeNode = { + element: getNodeLabel(node, false, false) + }; + if (node.z) { + if (!flows[node.z] && !subflows[node.z]) { + parentlessNodes.push(treeNode) + } else if (flows[node.z]) { + flows[node.z].children.push(treeNode) + } else if (subflows[node.z]) { + subflows[node.z].children.push(treeNode) + } + } else { + globalNodes.push(treeNode); + } + }); + var treeData = []; + + if (parentlessNodes.length > 0) { + treeData = treeData.concat(parentlessNodes); + } + if (type === "flow") { + treeData = treeData.concat(treeFlows); + } else if (treeFlows.length > 0) { + treeData.push({ + label: RED._("menu.label.flows"), + deferBuild: treeFlows.length > 20, + expanded: treeFlows.length <= 20, + children: treeFlows + }) + } + if (treeSubflows.length > 0) { + treeData.push({ + label: RED._("menu.label.subflows"), + deferBuild: treeSubflows.length > 10, + expanded: treeSubflows.length <= 10, + children: treeSubflows + }) + } + if (globalNodes.length > 0) { + treeData.push({ + label: RED._("sidebar.info.globalConfig"), + deferBuild: globalNodes.length > 10, + expanded: globalNodes.length <= 10, + children: globalNodes + }) + } + + $("#red-ui-clipboard-dialog-export-tab-clipboard-preview-list").treeList('data',treeData); + } + function loadFlowLibrary(browser,library,label) { // if (includeExamples) { // listing.push({ @@ -756,6 +875,7 @@ RED.clipboard = (function() { } function copyText(value,element,msg) { var truncated = false; + var currentFocus = document.activeElement; if (typeof value !== "string" ) { value = JSON.stringify(value, function(key,value) { if (value !== null && typeof value === 'object') { @@ -787,7 +907,7 @@ RED.clipboard = (function() { if (truncated) { msg += "_truncated"; } - $("#red-ui-clipboard-hidden").val(value).select(); + $("#red-ui-clipboard-hidden").val(value).focus().select(); var result = document.execCommand("copy"); if (result && element) { var popover = RED.popover.create({ @@ -801,6 +921,10 @@ RED.clipboard = (function() { },1000); popover.open(); } + $("#red-ui-clipboard-hidden").val(""); + if (currentFocus) { + $(currentFocus).focus(); + } return result; } diff --git a/packages/node_modules/@node-red/editor-client/src/sass/library.scss b/packages/node_modules/@node-red/editor-client/src/sass/library.scss index 26b17f38e..89109f357 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/library.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/library.scss @@ -29,8 +29,30 @@ } } } -.red-ui-clipboard-dialog-tab-clipboard { + +#red-ui-clipboard-dialog-export-tab-clipboard-preview { + .red-ui-treeList-container,.red-ui-editableList-border { + border: none; + border-radius: 0; + } +} +#red-ui-clipboard-dialog-export-tab-clipboard-json { + padding: 10px 10px 0; +} +#red-ui-clipboard-dialog-import-tab-clipboard { padding: 10px; +} +.red-ui-clipboard-dialog-export-tab-clipboard-tab { + position: absolute; + top: 40px; + right: 0; + left: 0; + bottom: 0; +} + +.red-ui-clipboard-dialog-tab-clipboard { + + textarea { resize: none; width: 100%; diff --git a/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss b/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss index c28c0acfa..42d5462f7 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss @@ -326,7 +326,7 @@ div.red-ui-info-table { border-bottom: 1px solid $secondary-border-color; } } -.red-ui-info-outline,.red-ui-sidebar-help-toc, #red-ui-clipboard-dialog-import-conflicts-list { +.red-ui-info-outline,.red-ui-sidebar-help-toc, #red-ui-clipboard-dialog-import-conflicts-list, #red-ui-clipboard-dialog-export-tab-clipboard-preview { .red-ui-info-outline-item { display: inline-block; padding: 0;