diff --git a/editor/js/ui/common/editableList.js b/editor/js/ui/common/editableList.js index fbf74537a..901cd2bcd 100644 --- a/editor/js/ui/common/editableList.js +++ b/editor/js/ui/common/editableList.js @@ -86,6 +86,7 @@ this.uiHeight = this.element.height(); this.activeFilter = this.options.filter||null; + this.activeSort = this.options.sort||null; var minHeight = this.element.css("minHeight"); if (minHeight !== '0px') { @@ -181,6 +182,18 @@ }); return count; }, + _refreshSort: function() { + if (this.activeSort) { + var items = this.element.children(); + var that = this; + items.sort(function(A,B) { + return that.activeSort($(A).find(".red-ui-editableList-item-content").data('data'),$(B).find(".red-ui-editableList-item-content").data('data')); + }); + $.each(items,function(idx,li) { + that.element.append(li); + }) + } + }, width: function(desiredWidth) { this.uiWidth = desiredWidth; this._resize(); @@ -194,13 +207,13 @@ data = data || {}; var li = $('
  • '); var added = false; - if (this.options.sort) { + if (this.activeSort) { var items = this.items(); var skip = false; items.each(function(i,el) { if (added) { return } var itemData = el.data('data'); - if (that.options.sort(data,itemData) < 0) { + if (that.activeSort(data,itemData) < 0) { li.insertBefore(el.closest("li")); added = true; } @@ -242,7 +255,7 @@ } } - if (!that.options.sort) { + if (!that.activeSort) { setTimeout(function() { that.uiContainer.scrollTop(that.element.height()); },0); @@ -271,6 +284,12 @@ } return this._refreshFilter(); }, + sort: function(sort) { + if (sort !== undefined) { + this.activeSort = sort; + } + return this._refreshSort(); + }, length: function() { return this.element.children().length; } diff --git a/editor/js/ui/palette-editor.js b/editor/js/ui/palette-editor.js index 855dc5a6a..d44564a06 100644 --- a/editor/js/ui/palette-editor.js +++ b/editor/js/ui/palette-editor.js @@ -289,6 +289,7 @@ RED.palette.editor = (function() { $(el).removeClass('expanded'); }); filterInput.searchBox('value',""); + searchInput.searchBox('value',""); } function filterChange(val) { @@ -302,24 +303,78 @@ RED.palette.editor = (function() { } } - function initInstallTab() { - $("#palette-module-install-shade").show(); - $.getJSON('http://catalogue.nodered.org/catalogue.json',function(v) { - loadedList = v.modules; - searchInput.searchBox('count',loadedList.length); - loadedList.forEach(function(m) { + var catalogueCount; + var catalogueLoadStatus = []; + var catalogueLoadStart; + + var activeSort = sortModulesAZ; + + function handleCatalogResponse(catalog,index,v) { + catalogueLoadStatus.push(v); + if (v.modules) { + v.modules.forEach(function(m) { m.index = [m.id]; if (m.keywords) { m.index = m.index.concat(m.keywords); } + if (m.updated_at) { + m.timestamp = new Date(m.updated_at).getTime(); + } else { + m.timestamp = 0; + } m.index = m.index.join(",").toLowerCase(); }) - $("#palette-module-install-shade").hide(); - - }) - + loadedList = loadedList.concat(v.modules); + } + searchInput.searchBox('count',loadedList.length); + if (catalogueCount > 1) { + $(".palette-module-shade-status").html("Loading catalogues...
    "+catalogueLoadStatus.length+"/"+catalogueCount); + } + if (catalogueLoadStatus.length === catalogueCount) { + var delta = 250-(Date.now() - catalogueLoadStart); + setTimeout(function() { + $("#palette-module-install-shade").hide(); + },Math.max(delta,0)); + } } + + function initInstallTab() { + loadedList = []; + packageList.editableList('empty'); + $(".palette-module-shade-status").html("Loading catalogues..."); + var catalogues = RED.settings.theme('palette.catalogues')||['http://catalogue.nodered.org/catalogue.json']; + catalogueLoadStatus = []; + catalogueCount = catalogues.length; + if (catalogues.length > 1) { + $(".palette-module-shade-status").html("Loading catalogues...
    0/"+catalogues.length); + } + $("#palette-module-install-shade").show(); + catalogueLoadStart = Date.now(); + catalogues.forEach(function(catalog,index) { + $.getJSON(catalog, {_: new Date().getTime()},function(v) { + handleCatalogResponse(catalog,index,v); + }) + }); + } + + function refreshFilteredItems() { + packageList.editableList('empty'); + filteredList.sort(activeSort); + for (var i=0;i 10) { + packageList.editableList('addItem',{start:10,more:filteredList.length-10}) + } + } + function sortModulesAZ(A,B) { + return A.info.id.localeCompare(B.info.id); + } + function sortModulesRecent(A,B) { + return -1 * (A.info.timestamp-B.info.timestamp); + } + function init() { $(".palette-editor-button").show(); @@ -329,6 +384,12 @@ RED.palette.editor = (function() { onchange:function(tab) { $("#palette-editor .palette-editor-tab").hide(); tab.content.show(); + if (filterInput) { + filterInput.searchBox('value',""); + } + if (searchInput) { + searchInput.searchBox('value',""); + } if (tab.id === 'install') { initInstallTab(); if (searchInput) { @@ -395,10 +456,10 @@ RED.palette.editor = (function() { addItem: function(container,i,object) { var entry = object.info; var headerRow = $('
    ',{class:"palette-module-header"}).appendTo(container); - var titleRow = $('
    ').appendTo(headerRow); - $('',{class:"palette-module-name"}).html(entry.name).appendTo(titleRow); - var metaRow = $('
    ').appendTo(headerRow); - $('').html(entry.version).appendTo(metaRow.find(".palette-module-version")); + var titleRow = $('
    ').appendTo(headerRow); + $('').html(entry.name).appendTo(titleRow); + var metaRow = $('
    ').appendTo(headerRow); + $('').html(entry.version).appendTo(metaRow); var buttonRow = $('
    ',{class:"palette-module-meta"}).appendTo(headerRow); var setButton = $(' ').appendTo(buttonRow); var setCount = $('').appendTo(setButton); @@ -492,6 +553,8 @@ RED.palette.editor = (function() { content: installTab }) + var toolBar = $('
    ',{class:"palette-editor-toolbar"}).appendTo(installTab); + var searchDiv = $('
    ',{class:"palette-search"}).appendTo(installTab); searchInput = $('') .appendTo(searchDiv) @@ -500,17 +563,11 @@ RED.palette.editor = (function() { minimumLength: 2, change: function() { var searchTerm = $(this).val(); - packageList.editableList('empty'); if (searchTerm.length >= 2) { filteredList = loadedList.filter(function(m) { return (m.index.indexOf(searchTerm) > -1); }).map(function(f) { return {info:f}}); - for (var i=0;i 10) { - packageList.editableList('addItem',{start:10,more:filteredList.length-10}) - } + refreshFilteredItems(); searchInput.searchBox('count',filteredList.length+" / "+loadedList.length); } else { searchInput.searchBox('count',loadedList.length); @@ -518,14 +575,44 @@ RED.palette.editor = (function() { } }); - $('
    ').appendTo(installTab); + + $('').html('sort: ').appendTo(toolBar); + var sortGroup = $(' ').appendTo(toolBar); + var sortAZ = $('a-z').appendTo(sortGroup); + var sortRecent = $('recent').appendTo(sortGroup); + + sortAZ.click(function(e) { + e.preventDefault(); + if ($(this).hasClass("selected")) { + return; + } + $(this).addClass("selected"); + sortRecent.removeClass("selected"); + activeSort = sortModulesAZ; + refreshFilteredItems(); + }); + + sortRecent.click(function(e) { + e.preventDefault(); + if ($(this).hasClass("selected")) { + return; + } + $(this).addClass("selected"); + sortAZ.removeClass("selected"); + activeSort = sortModulesRecent; + refreshFilteredItems(); + }); - packageList = $('
      ',{id:"palette-module-list", style:"position: absolute;top: 35px;bottom: 0;left: 0;right: 0px;"}).appendTo(installTab).editableList({ + var refreshSpan = $('').appendTo(toolBar); + var refreshButton = $('').appendTo(refreshSpan); + refreshButton.click(function(e) { + e.preventDefault(); + initInstallTab(); + }) + + packageList = $('
        ',{id:"palette-module-list", style:"position: absolute;top: 78px;bottom: 0;left: 0;right: 0px;"}).appendTo(installTab).editableList({ addButton: false, - // sort: function(A,B) { - // return A.info.name.localeCompare(B.info.name); - // }, addItem: function(container,i,object) { if (object.more) { container.addClass('palette-module-more'); @@ -561,7 +648,11 @@ RED.palette.editor = (function() { installButton.click(function(e) { e.preventDefault(); installNodeModule(entry.id,shade,function(xhr) { - console.log(xhr); + if (xhr) { + if (xhr.responseJSON) { + RED.notify("Failed to install: "+entry.id+"
        "+xhr.responseJSON.message+"
        Check the log for more information","error",false,8000); + } + } }) }) if (nodeEntries.hasOwnProperty(entry.id)) { @@ -574,6 +665,7 @@ RED.palette.editor = (function() { } }); + $('
        ').appendTo(installTab); RED.events.on('registry:node-set-enabled', function(ns) { refreshNodeModule(ns.module); diff --git a/editor/sass/colors.scss b/editor/sass/colors.scss index 714e4f4ce..b2a691d99 100644 --- a/editor/sass/colors.scss +++ b/editor/sass/colors.scss @@ -20,6 +20,7 @@ $form-placeholder-color: #bbbbbb; $form-text-color: #444; $form-input-focus-color: rgba(85,150,230,0.8); $form-input-border-color: #ccc; +$form-input-border-selected-color: #aaa; $node-selected-color: #ff7f0e; diff --git a/editor/sass/mixins.scss b/editor/sass/mixins.scss index 4d8ada6fb..b83605962 100644 --- a/editor/sass/mixins.scss +++ b/editor/sass/mixins.scss @@ -82,11 +82,13 @@ @mixin workspace-button-toggle { @include workspace-button; color: $workspace-button-color-selected; - background: $workspace-button-background-active; + background:$workspace-button-background-active; &.selected:not(.disabled) { color: $workspace-button-color; background: $workspace-button-background; + border-bottom-width: 2px; + border-bottom-color: $form-input-border-selected-color; } } diff --git a/editor/sass/palette-editor.scss b/editor/sass/palette-editor.scss index a2880b7cc..70b575d89 100644 --- a/editor/sass/palette-editor.scss +++ b/editor/sass/palette-editor.scss @@ -38,6 +38,17 @@ padding: 0px; .disabled { background: #f3f3f3; + + .palette-module-name { + font-style: italic; + color: #aaa; + } + .palette-module-version { + color: #aaa; + } + + + } .red-ui-editableList-item-content { padding: 12px 8px; @@ -55,7 +66,17 @@ right:0; bottom:0 } + .palette-editor-toolbar { + background: #f3f3f3; + box-sizing: border-box; + padding: 8px 10px; + border-bottom: 1px solid $primary-border-color; + text-align: right; + .button-group { + margin-right: 10px; + } + } .palette-module-button-group { position: absolute; right: 0; @@ -72,7 +93,15 @@ right:0; background: rgba(255,255,255,0.8); text-align: center; + padding-top: 20px; } + #palette-module-install-shade { + padding-top: 80px; + } + .palette-module-shade-status { + color: #666; + } + .palette-module-meta { color: #666; position: relative; diff --git a/editor/sass/palette.scss b/editor/sass/palette.scss index 15089264c..988717013 100644 --- a/editor/sass/palette.scss +++ b/editor/sass/palette.scss @@ -53,15 +53,11 @@ overflow-y: auto; box-sizing:border-box; } -.palette-spinner { - padding-top: 40px; +#palette > .palette-spinner { + padding-top: 80px; } - .palette-search { - position: absolute; - top: 0; - left:0; - right:0; + position: relative; overflow: hidden; background: #ffffff; text-align: center;