From 8a076c01ab54d7cab5b144d58ce944e58fd647bf Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Thu, 17 Dec 2020 14:35:01 +0000 Subject: [PATCH 1/6] Support for library source plugins --- .../editor-client/src/js/ui/clipboard.js | 196 +++++++++--------- .../editor-client/src/js/ui/library.js | 99 +++++---- .../editor-client/src/sass/library.scss | 9 +- .../@node-red/runtime/lib/api/settings.js | 2 +- .../@node-red/runtime/lib/index.js | 2 +- .../@node-red/runtime/lib/library/index.js | 84 +++++++- .../plugin/test-plugin/library-filestore.html | 11 + .../plugin/test-plugin/library-filestore.js | 32 +++ .../resources/plugin/test-plugin/package.json | 3 +- 9 files changed, 283 insertions(+), 155 deletions(-) create mode 100644 test/resources/plugin/test-plugin/library-filestore.html create mode 100644 test/resources/plugin/test-plugin/library-filestore.js 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 bb82ecea3..eb3b7b6de 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 @@ -26,7 +26,8 @@ RED.clipboard = (function() { var currentPopoverError; var activeTab; var libraryBrowser; - var examplesBrowser; + + var activeLibraries = {}; var pendingImportConfig; @@ -93,7 +94,7 @@ RED.clipboard = (function() { $( this ).dialog( "close" ); } else { var flowToExport = $("#red-ui-clipboard-dialog-export-text").val(); - var selectedPath = libraryBrowser.getSelected(); + var selectedPath = activeLibraries[activeTab].getSelected(); if (!selectedPath.children) { selectedPath = selectedPath.parent; } @@ -159,12 +160,7 @@ RED.clipboard = (function() { if (activeTab === "red-ui-clipboard-dialog-import-tab-clipboard") { importNodes($("#red-ui-clipboard-dialog-import-text").val(),addNewFlow); } else { - var selectedPath; - if (activeTab === "red-ui-clipboard-dialog-import-tab-library") { - selectedPath = libraryBrowser.getSelected(); - } else { - selectedPath = examplesBrowser.getSelected(); - } + var selectedPath = activeLibraries[activeTab].getSelected(); if (selectedPath.path) { $.get('library/'+selectedPath.library+'/'+selectedPath.type+'/'+selectedPath.path, function(data) { importNodes(data,addNewFlow); @@ -254,11 +250,8 @@ RED.clipboard = (function() { ''+ ''+ ''+ - '
'+ - '
'+ - '
'+ - ''+ - '
'+ + '
'+ + ''+ '
'+ '
'+ '' @@ -280,8 +273,6 @@ RED.clipboard = (function() { ''+ ''+ ''+ - '
'+ - '
'+ ''+ ''+ '
'+ @@ -414,7 +405,7 @@ RED.clipboard = (function() { } },100); } else { - var file = libraryBrowser.getSelected(); + var file = activeLibraries[activeTab].getSelected(); if (file && file.label && !file.children) { $("#red-ui-clipboard-dialog-ok").button("enable"); } else { @@ -446,7 +437,7 @@ RED.clipboard = (function() { if (tab.id === "red-ui-clipboard-dialog-import-tab-clipboard") { $("#red-ui-clipboard-dialog-import-text").trigger("focus"); } else { - libraryBrowser.focus(); + activeLibraries[tab.id].focus(); } validateImport(); } @@ -455,54 +446,43 @@ RED.clipboard = (function() { id: "red-ui-clipboard-dialog-import-tab-clipboard", label: RED._("clipboard.clipboard") }); - tabs.addTab({ - id: "red-ui-clipboard-dialog-import-tab-library", - label: RED._("library.library") - }); - tabs.addTab({ - id: "red-ui-clipboard-dialog-import-tab-examples", - label: RED._("library.types.examples") - }); + + var libraries = RED.settings.libraries || []; + libraries.forEach(function(lib) { + var tabId = "red-ui-clipboard-dialog-import-tab-library-"+lib.id + tabs.addTab({ + id: tabId, + label: RED._(lib.label||lib.id) + }) + + var content = $('
') + .attr("id",tabId) + .hide() + .appendTo("#red-ui-clipboard-dialog-import-tabs-content"); + + var browser = RED.library.createBrowser({ + container: content, + onselect: function(file) { + if (file && file.label && !file.children) { + $("#red-ui-clipboard-dialog-ok").button("enable"); + } else { + $("#red-ui-clipboard-dialog-ok").button("disable"); + } + }, + onconfirm: function(item) { + if (item && item.label && !item.children) { + $("#red-ui-clipboard-dialog-ok").trigger("click"); + } + } + }) + loadFlowLibrary(browser,lib); + activeLibraries[tabId] = browser; + }) $("#red-ui-clipboard-dialog-tab-library-name").on("keyup", validateExportFilename); $("#red-ui-clipboard-dialog-tab-library-name").on('paste',function() { setTimeout(validateExportFilename,10)}); $("#red-ui-clipboard-dialog-export").button("enable"); - libraryBrowser = RED.library.createBrowser({ - container: $("#red-ui-clipboard-dialog-import-tab-library"), - onselect: function(file) { - if (file && file.label && !file.children) { - $("#red-ui-clipboard-dialog-ok").button("enable"); - } else { - $("#red-ui-clipboard-dialog-ok").button("disable"); - } - }, - onconfirm: function(item) { - if (item && item.label && !item.children) { - $("#red-ui-clipboard-dialog-ok").trigger("click"); - } - } - }) - loadFlowLibrary(libraryBrowser,"local",RED._("library.types.local")); - - examplesBrowser = RED.library.createBrowser({ - container: $("#red-ui-clipboard-dialog-import-tab-examples"), - onselect: function(file) { - if (file && file.label && !file.children) { - $("#red-ui-clipboard-dialog-ok").button("enable"); - } else { - $("#red-ui-clipboard-dialog-ok").button("disable"); - } - }, - onconfirm: function(item) { - if (item && item.label && !item.children) { - $("#red-ui-clipboard-dialog-ok").trigger("click"); - } - } - }) - loadFlowLibrary(examplesBrowser,"_examples_",RED._("library.types.examples")); - - dialogContainer.i18n(); $("#red-ui-clipboard-dialog-ok").show(); @@ -582,10 +562,12 @@ RED.clipboard = (function() { if (tab.id === "red-ui-clipboard-dialog-export-tab-clipboard") { $("#red-ui-clipboard-dialog-export").button("option","label", RED._("clipboard.export.copy")) $("#red-ui-clipboard-dialog-download").show(); + $("#red-ui-clipboard-dialog-export-tab-library-filename").hide(); } else { $("#red-ui-clipboard-dialog-export").button("option","label", RED._("clipboard.export.export")) $("#red-ui-clipboard-dialog-download").hide(); - libraryBrowser.focus(); + $("#red-ui-clipboard-dialog-export-tab-library-filename").show(); + activeLibraries[activeTab].focus(); } } @@ -594,26 +576,45 @@ RED.clipboard = (function() { id: "red-ui-clipboard-dialog-export-tab-clipboard", label: RED._("clipboard.clipboard") }); - tabs.addTab({ - id: "red-ui-clipboard-dialog-export-tab-library", - label: RED._("library.library") - }); + + + var libraries = RED.settings.libraries || []; + + libraries.forEach(function(lib) { + if (lib.readOnly) { + return + } + var tabId = "red-ui-clipboard-dialog-export-tab-library-"+lib.id + tabs.addTab({ + id: tabId, + label: RED._(lib.label||lib.id) + }) + + var content = $('
') + .attr("id",tabId) + .hide() + .insertBefore("#red-ui-clipboard-dialog-export-tab-library-filename"); + + var browser = RED.library.createBrowser({ + container: content, + folderTools: true, + onselect: function(file) { + if (file && file.label && !file.children) { + $("#red-ui-clipboard-dialog-tab-library-name").val(file.label); + } + }, + }) + loadFlowLibrary(browser,lib); + activeLibraries[tabId] = browser; + }) + + + $("#red-ui-clipboard-dialog-tab-library-name").on("keyup", validateExportFilename); $("#red-ui-clipboard-dialog-tab-library-name").on('paste',function() { setTimeout(validateExportFilename,10)}); $("#red-ui-clipboard-dialog-export").button("enable"); - libraryBrowser = RED.library.createBrowser({ - container: $("#red-ui-clipboard-dialog-export-tab-library-browser"), - folderTools: true, - onselect: function(file) { - if (file && file.label && !file.children) { - $("#red-ui-clipboard-dialog-tab-library-name").val(file.label); - } - } - }) - loadFlowLibrary(libraryBrowser,"local",RED._("library.types.local")); - var clipboardTabs = RED.tabs.create({ id: "red-ui-clipboard-dialog-export-tab-clipboard-tabs", onchange: function(tab) { @@ -852,35 +853,28 @@ RED.clipboard = (function() { $("#red-ui-clipboard-dialog-export-tab-clipboard-preview-list").treeList('data',treeData); } - function loadFlowLibrary(browser,library,label) { - // if (includeExamples) { - // listing.push({ - // library: "_examples_", - // type: "flows", - // icon: 'fa fa-hdd-o', - // label: RED._("library.types.examples"), - // path: "", - // children: function(done,item) { - // RED.library.loadLibraryFolder("_examples_","flows","",function(children) { - // item.children = children; - // done(children); - // }) - // } - // }) - // } + function loadFlowLibrary(browser,library) { browser.data([{ - library: library, + library: library.id, type: "flows", - icon: 'fa fa-hdd-o', - label: label, + icon: library.icon || 'fa fa-hdd-o', + label: RED._(library.label||library.id), path: "", expanded: true, - children: function(done, item) { - RED.library.loadLibraryFolder(library,"flows","",function(children) { - item.children = children; - done(children); - }) - } + children: [{ + library: library.id, + type: "flows", + icon: 'fa fa-cube', + label: "flows", + path: "", + expanded: true, + children: function(done, item) { + RED.library.loadLibraryFolder(library.id,"flows","",function(children) { + item.children = children; + done(children); + }) + } + }] }], true); } diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/library.js b/packages/node_modules/@node-red/editor-client/src/js/ui/library.js index 54d73c022..3872a38ea 100755 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/library.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/library.js @@ -216,31 +216,7 @@ RED.library = (function() { { id:'node-input-'+options.type+'-menu-open-library', label: RED._("library.openLibrary"), onselect: function() { - activeLibrary = options; - loadLibraryFolder("local",options.url, "", function(items) { - var listing = [{ - library: "local", - type: options.url, - icon: 'fa fa-hdd-o', - label: RED._("library.types.local"), - path: "", - expanded: true, - writable: false, - children: [{ - library: "local", - type: options.url, - icon: 'fa fa-cube', - label: options.type, - path: "", - expanded: true, - children: items - }] - }] - loadLibraryBrowser.data(listing); - setTimeout(function() { - loadLibraryBrowser.select(listing[0].children[0]); - },200); - }); + libraryEditor = ace.edit('red-ui-library-dialog-load-preview-text',{ useWorker: false }); @@ -256,6 +232,43 @@ RED.library = (function() { libraryEditor.renderer.$cursorLayer.element.style.opacity=0; libraryEditor.$blockScrolling = Infinity; + activeLibrary = options; + var listing = []; + var libraries = RED.settings.libraries || []; + libraries.forEach(function(lib) { + if (lib.types && lib.types.indexOf(options.url) === -1) { + return; + } + listing.push({ + library: lib.id, + type: options.url, + icon: lib.icon || 'fa fa-hdd-o', + label: RED._(lib.label||lib.id), + path: "", + expanded: true, + writable: false, + children: [{ + library: lib.id, + type: options.url, + icon: 'fa fa-cube', + label: options.type, + path: "", + expanded: false, + children: function(done, item) { + loadLibraryFolder(lib.id, options.url, "", function(children) { + item.children = children; + done(children); + }) + } + }] + }) + }); + loadLibraryBrowser.data(listing); + setTimeout(function() { + loadLibraryBrowser.select(listing[0].children[0]); + },200); + + var dialogHeight = 400; var winHeight = $(window).height(); if (winHeight < 570) { @@ -278,30 +291,40 @@ RED.library = (function() { } $("#red-ui-library-dialog-save-filename").attr("value",filename+"."+(options.ext||"txt")); - loadLibraryFolder("local",options.url, "", function(items) { - var listing = [{ - library: "local", + var listing = []; + var libraries = RED.settings.libraries || []; + libraries.forEach(function(lib) { + if (lib.types && lib.types.indexOf(options.url) === -1) { + return; + } + listing.push({ + library: lib.id, type: options.url, - icon: 'fa fa-hdd-o', - label: RED._("library.types.local"), + icon: lib.icon || 'fa fa-hdd-o', + label: RED._(lib.label||lib.id), path: "", expanded: true, writable: false, children: [{ - library: "local", + library: lib.id, type: options.url, icon: 'fa fa-cube', label: options.type, path: "", - expanded: true, - children: items + expanded: false, + children: function(done, item) { + loadLibraryFolder(lib.id, options.url, "", function(children) { + item.children = children; + done(children); + }) + } }] - }] - saveLibraryBrowser.data(listing); - setTimeout(function() { - saveLibraryBrowser.select(listing[0].children[0]); - },200); + }) }); + saveLibraryBrowser.data(listing); + setTimeout(function() { + saveLibraryBrowser.select(listing[0].children[0]); + },200); var dialogHeight = 400; var winHeight = $(window).height(); 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 89109f357..3ddf44a95 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 @@ -93,10 +93,9 @@ border:1px solid $primary-border-color; } -.red-ui-clipboard-dialog-tab-library { - .form-row { - margin-left: 10px; - } +#red-ui-clipboard-dialog-export-tab-library-filename { + height: auto !important; + margin-left: 10px; } #red-ui-clipboard-dialog { @@ -110,7 +109,7 @@ #red-ui-clipboard-dialog-tab-library-name { width: calc(100% - 120px); } -#red-ui-clipboard-dialog-export-tab-library-browser { +.red-ui-clipboard-dialog-tabs-content>div.red-ui-clipboard-dialog-export-tab-library-browser { height: calc(100% - 60px); margin-bottom: 13px; border-bottom: 1px solid $primary-border-color; diff --git a/packages/node_modules/@node-red/runtime/lib/api/settings.js b/packages/node_modules/@node-red/runtime/lib/api/settings.js index d96ec5b58..07d09e379 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/settings.js +++ b/packages/node_modules/@node-red/runtime/lib/api/settings.js @@ -81,7 +81,7 @@ var api = module.exports = { if (!runtime.settings.disableEditor) { safeSettings.context = runtime.nodes.listContextStores(); - + safeSettings.libraries = runtime.library.getLibraries(); if (util.isArray(runtime.settings.paletteCategories)) { safeSettings.paletteCategories = runtime.settings.paletteCategories; } diff --git a/packages/node_modules/@node-red/runtime/lib/index.js b/packages/node_modules/@node-red/runtime/lib/index.js index 0be1c6511..42e053baf 100644 --- a/packages/node_modules/@node-red/runtime/lib/index.js +++ b/packages/node_modules/@node-red/runtime/lib/index.js @@ -74,7 +74,6 @@ function init(userSettings,httpServer,_adminApi) { adminApi = _adminApi; } redNodes.init(runtime); - library.init(runtime); externalAPI.init(runtime); } @@ -104,6 +103,7 @@ function start() { return i18n.registerMessageCatalog("runtime",path.resolve(path.join(__dirname,"..","locales")),"runtime.json") .then(function() { return storage.init(runtime)}) .then(function() { return settings.load(storage)}) + .then(function() { return library.init(runtime)}) .then(function() { if (log.metric()) { diff --git a/packages/node_modules/@node-red/runtime/lib/library/index.js b/packages/node_modules/@node-red/runtime/lib/library/index.js index 8a4e6518e..293745f2d 100644 --- a/packages/node_modules/@node-red/runtime/lib/library/index.js +++ b/packages/node_modules/@node-red/runtime/lib/library/index.js @@ -15,21 +15,54 @@ **/ -var knownTypes = {}; +const {events} = require("@node-red/util") +const knownTypes = {}; +const libraries = {}; +const libraryPlugins = {}; -var libraries = {}; +// Libraries defined in the settings file. Their configurations +// cannot be modified in the editor. +let runtimeLibraries = []; +// Libraries defined by the user in the editor. +let userLibraries = []; function init(runtime) { - knownTypes = { - 'flows': 'node-red' - }; - libraries["_examples_"] = require("./examples"); - libraries["_examples_"].init(runtime); + events.on("registry:plugin-added", function(id) { + const plugin = runtime.plugins.getPlugin(id); + if (plugin.type === "node-red-library-source") { + libraryPlugins[plugin.id] = plugin; + + runtimeLibraries.forEach(library => { + if (library.type === id) { + library.local = false; + libraries[library.id] = new plugin.class(library) + if (libraries[library.id].init) { + libraries[library.id].init(); + } + } + }) + + + } + }) + + knownTypes.flows = 'node-red'; + + libraries["examples"] = require("./examples"); + libraries["examples"].init(runtime); libraries["local"] = require("./local"); libraries["local"].init(runtime); + try { + runtimeLibraries = runtime.settings.editorTheme.library.sources; + } catch(err) { + runtimeLibraries = []; + } + // userLibraries = runtime.settings.get("library") + + } function registerType(id,type) { @@ -56,7 +89,7 @@ function saveEntry(library,type,path,meta,body) { throw new Error(`Unknown library type '${type}'`); } if (libraries.hasOwnProperty(library)) { - if (libraries[library].hasOwnProperty("saveEntry")) { + if (libraries[library].saveEntry) { return libraries[library].saveEntry(type,path,meta,body); } else { throw new Error(`Library '${library}' is read-only`); @@ -66,8 +99,43 @@ function saveEntry(library,type,path,meta,body) { } } +function getLibraries() { + const libraryList = [ + { + id: "local", + label: "editor:library.types.local", + user: false, + icon: "fa fa-bath" + }, + { + id: "examples", + label: "editor:library.types.examples", + user: false, + readOnly: true, + types: ['flows'] + } + ]; + + for (let id in libraries) { + if (libraries.hasOwnProperty(id)) { + if (id !== 'local' && id !== 'examples') { + libraryList.push({ + id: id, + label: libraries[id].name || id, + user: false, + icon: libraries[id].icon + }) + } + } + } + + return libraryList; + +} + module.exports = { init: init, + getLibraries: getLibraries, register: registerType, getEntry: getEntry, saveEntry: saveEntry diff --git a/test/resources/plugin/test-plugin/library-filestore.html b/test/resources/plugin/test-plugin/library-filestore.html new file mode 100644 index 000000000..b4f1c0946 --- /dev/null +++ b/test/resources/plugin/test-plugin/library-filestore.html @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/test/resources/plugin/test-plugin/library-filestore.js b/test/resources/plugin/test-plugin/library-filestore.js new file mode 100644 index 000000000..61c8d9803 --- /dev/null +++ b/test/resources/plugin/test-plugin/library-filestore.js @@ -0,0 +1,32 @@ + +module.exports = function(RED) { + + class FileStorePlugin { + constructor(config) { + this.id = config.id; + this.name = config.name; + this.config = config; + this.icon = config.icon; + + console.log("FileStorePlugin",config) + } + async init() { + console.log("FileStorePlugin.init") + + } + async getEntry(type,path) { + console.log("FileStorePlugin.getLibraryEntry",type,path) + return [] + } + async saveEntry(type,path,meta,body) { + console.log("FileStorePlugin.saveLibraryEntry",type,path) + + } + } + + + RED.plugins.registerPlugin("node-red-library-filestore", { + type: "node-red-library-source", + class: FileStorePlugin + }) +} \ No newline at end of file diff --git a/test/resources/plugin/test-plugin/package.json b/test/resources/plugin/test-plugin/package.json index 1077042de..65487c656 100644 --- a/test/resources/plugin/test-plugin/package.json +++ b/test/resources/plugin/test-plugin/package.json @@ -6,7 +6,8 @@ "plugins": { "test": "test.js", "test-editor-plugin": "test-editor-plugin.html", - "test-runtime-plugin": "test-runtime-plugin.js" + "test-runtime-plugin": "test-runtime-plugin.js", + "library-filestore": "library-filestore.js" } } } From 3f9a29730f9ddcbb8ce2cadad5c77c77f9b4f2f6 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Fri, 22 Jan 2021 11:20:28 +0000 Subject: [PATCH 2/6] Add partial implementation of adding library sources via editor This adds lots of commented out code that provides a settings panel to add new library sources. It is incomplete as it doesn't actually add/update the library sources on the runtime. For 1.3, I'm focussing on allowing additional sources get added via the settings file only. I've done enough work on the editor side to convince myself more work is needed than I can justify at this time on what is otherwise not going to be a widely used feature. --- .../@node-red/editor-api/lib/editor/index.js | 1 + .../editor-api/lib/editor/library.js | 11 + .../editor-client/src/js/ui/clipboard.js | 7 +- .../editor-client/src/js/ui/library.js | 228 +++++++++++++++++- .../editor-client/src/sass/library.scss | 38 +++ .../editor-client/src/sass/projects.scss | 1 + .../@node-red/runtime/lib/api/library.js | 21 ++ .../@node-red/runtime/lib/library/examples.js | 6 +- .../@node-red/runtime/lib/library/index.js | 75 +++--- .../@node-red/runtime/lib/library/local.js | 4 +- .../plugin/test-plugin/library-filestore.html | 15 +- .../plugin/test-plugin/library-filestore.js | 17 +- .../locales/en-US/library-filestore.json | 8 + 13 files changed, 393 insertions(+), 39 deletions(-) create mode 100644 test/resources/plugin/test-plugin/locales/en-US/library-filestore.json diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/index.js b/packages/node_modules/@node-red/editor-api/lib/editor/index.js index 2e8333f3f..b2fdc1f6b 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/index.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/index.js @@ -93,6 +93,7 @@ module.exports = { // Library var library = require("./library"); library.init(runtimeAPI); + // editorApp.get("/library/:id",needsPermission("library.read"),library.getLibraryConfig); editorApp.get(/^\/library\/([^\/]+)\/([^\/]+)(?:$|\/(.*))/,needsPermission("library.read"),library.getEntry); editorApp.post(/^\/library\/([^\/]+)\/([^\/]+)\/(.*)/,needsPermission("library.write"),library.saveEntry); diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/library.js b/packages/node_modules/@node-red/editor-api/lib/editor/library.js index 89b92fd11..cd564b3f8 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/library.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/library.js @@ -24,6 +24,17 @@ module.exports = { init: function(_runtimeAPI) { runtimeAPI = _runtimeAPI; }, + // getLibraryConfig: function(req,res) { + // var opts = { + // user: req.user, + // library: req.params.id + // } + // runtimeAPI.library.getConfig(opts).then(function(result) { + // res.json(result); + // }).catch(function(err) { + // apiUtils.rejectHandler(req,res,err); + // }); + // }, getEntry: function(req,res) { var opts = { user: req.user, 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 eb3b7b6de..6ec719708 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 @@ -854,10 +854,15 @@ RED.clipboard = (function() { } function loadFlowLibrary(browser,library) { + var icon = 'fa fa-hdd-o'; + if (library.icon) { + var fullIcon = RED.utils.separateIconPath(library.icon); + icon = (fullIcon.module==="font-awesome"?"fa ":"")+fullIcon.file; + } browser.data([{ library: library.id, type: "flows", - icon: library.icon || 'fa fa-hdd-o', + icon: icon, label: RED._(library.label||library.id), path: "", expanded: true, diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/library.js b/packages/node_modules/@node-red/editor-client/src/js/ui/library.js index 3872a38ea..66e617229 100755 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/library.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/library.js @@ -483,9 +483,235 @@ RED.library = (function() { } } + // var libraryPlugins = {}; + // + // function showLibraryDetailsDialog(container, lib, done) { + // var dialog = $('
').addClass("red-ui-projects-dialog-list-dialog").hide().appendTo(container); + // $('
').addClass("red-ui-projects-dialog-list-dialog-header").text(lib?"Edit library source":"Add library source").appendTo(dialog); + // var formRow = $('
').appendTo(dialog); + // $('