From 11c76d3010fc09264fc71445e1a4edeff38b8dc3 Mon Sep 17 00:00:00 2001 From: Julia Aranovich Date: Wed, 15 Jul 2015 11:25:21 +0300 Subject: [PATCH] Fix for values sorting * utils.natsort is used to compare strings * numeric sorting for numbers * undefined or null values go last Closes-Bug: #1474377 Change-Id: I9070b2d818670e0566b5ca6da1663070717254d8 --- nailgun/static/translations/core.json | 1 + nailgun/static/utils.js | 11 ++++-- .../nodes_tab_screens/node.jsx | 2 +- .../nodes_tab_screens/node_list_screen.jsx | 35 +++++++++++-------- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/nailgun/static/translations/core.json b/nailgun/static/translations/core.json index 529e4feda1..6a2af7e045 100644 --- a/nailgun/static/translations/core.json +++ b/nailgun/static/translations/core.json @@ -22,6 +22,7 @@ "retry_button": "Retry Update", "apply_changes_button": "Apply Changes", "not_available": "N/A", + "not_specified" : "Not specified", "size": { "byte": "byte", "byte_plural": "bytes", diff --git a/nailgun/static/utils.js b/nailgun/static/utils.js index b85f989681..178fe04d48 100644 --- a/nailgun/static/utils.js +++ b/nailgun/static/utils.js @@ -339,8 +339,15 @@ define([ }; var model1Value = getValue(model1), model2Value = getValue(model2); - if (_.isString(model1Value)) return utils.natsort(model1Value, model2Value, options); - var result = model1Value - model2Value; + if (_.isString(model1Value) && _.isString(model1Value)) { + return utils.natsort(model1Value, model2Value, options); + } + var result; + if (_.isNumber(model1Value) && _.isNumber(model1Value)) { + result = model1Value - model2Value; + } else { + result = !model1Value && !model2Value ? 0 : !model1Value ? 1 : -1; + } return options.desc ? -result : result; } }; diff --git a/nailgun/static/views/cluster_page_tabs/nodes_tab_screens/node.jsx b/nailgun/static/views/cluster_page_tabs/nodes_tab_screens/node.jsx index c8e7355448..e00cf2de27 100644 --- a/nailgun/static/views/cluster_page_tabs/nodes_tab_screens/node.jsx +++ b/nailgun/static/views/cluster_page_tabs/nodes_tab_screens/node.jsx @@ -264,7 +264,7 @@ function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialo }; nodePanelClasses[status] = status; - var manufacturer = node.get('manufacturer'), + var manufacturer = node.get('manufacturer') || '', logoClasses = { 'manufacturer-logo': true }; diff --git a/nailgun/static/views/cluster_page_tabs/nodes_tab_screens/node_list_screen.jsx b/nailgun/static/views/cluster_page_tabs/nodes_tab_screens/node_list_screen.jsx index c5b8cb8d3e..a4464fa067 100644 --- a/nailgun/static/views/cluster_page_tabs/nodes_tab_screens/node_list_screen.jsx +++ b/nailgun/static/views/cluster_page_tabs/nodes_tab_screens/node_list_screen.jsx @@ -145,7 +145,7 @@ function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialo }, this); }, changeSearch: _.debounce(function(value) { - this.updateSearch(value); + this.updateSearch(_.trim(value)); }, 200, {leading: true}), clearSearchField: function() { this.updateSearch(''); @@ -236,7 +236,7 @@ function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialo if (this.state.search) { var search = this.state.search.toLowerCase(); if (!_.any(node.pick('name', 'mac', 'ip'), function(attribute) { - return _.contains(attribute.toLowerCase(), search); + return _.contains((attribute || '').toLowerCase(), search); })) { return false; } @@ -382,9 +382,11 @@ function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialo } {_.map(this.props.options, function(option, index) { return ( - @@ -504,6 +506,7 @@ function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialo break; case 'manufacturer': options = _.uniq(this.props.screenNodes.pluck('manufacturer')).map(function(manufacturer) { + manufacturer = manufacturer || ''; return { name: manufacturer.replace(/\s/g, '_'), label: manufacturer @@ -1085,6 +1088,16 @@ function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialo var uniqValueSorters = ['name', 'mac', 'ip'], activeSorters = _.uniq(_.flatten(_.map(this.props.activeSorters, _.keys))); + var composeNodeDiskSizesLabel = function(node) { + var diskSizes = node.resource('disks'); + return i18n('node_details.disks_amount', { + count: diskSizes.length, + size: diskSizes.map(function(size) { + return utils.showDiskSize(size) + ' ' + i18n('node_details.hdd'); + }).join(', ') + }); + }; + var groupingMethod = _.bind(function(node) { return (_.map(_.difference(activeSorters, uniqValueSorters), function(sorter) { if (sorter == 'roles') { @@ -1096,7 +1109,7 @@ function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialo }); } if (sorter == 'manufacturer') { - return node.get('manufacturer'); + return node.get('manufacturer') || i18n('common.not_specified'); } if (sorter == 'hdd') { return i18n('node_details.total_hdd', { @@ -1104,13 +1117,7 @@ function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialo }); } if (sorter == 'disks') { - var diskSizes = node.resource('disks'); - return i18n('node_details.disks_amount', { - count: diskSizes.length, - size: diskSizes.map(function(size) { - return utils.showDiskSize(size) + ' ' + i18n('node_details.hdd'); - }).join(', ') - }); + return composeNodeDiskSizesLabel(node); } if (sorter == 'ram') { return i18n('node_details.total_ram', { @@ -1132,7 +1139,7 @@ function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialo })); _.each(groups, function(group) { group[1].sort(function(node1, node2) { - return utils.multiSort(node1, node2, formattedSorters); + return utils.compare(node1, node2, formattedSorters); }); }); } @@ -1158,10 +1165,10 @@ function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialo result = _.indexOf(this.props.statusesToFilter, node1.getStatusSummary()) - _.indexOf(this.props.statusesToFilter, node2.getStatusSummary()); break; case 'manufacturer': - result = utils.natsort(node1.get('manufacturer'), node2.get('manufacturer')); + result = utils.compare(node1, node2, {attr: 'manufacturer'}); break; case 'disks': - result = utils.natsort(node1.resource('disks'), node2.resource('disks')); + result = utils.natsort(composeNodeDiskSizesLabel(node1), composeNodeDiskSizesLabel(node2)); break; default: result = node1.resource(sorterName) - node2.resource(sorterName);