diff --git a/client/components/site-selector/index.jsx b/client/components/site-selector/index.jsx index 7dc3140eb61eb..420e71fea6fa2 100644 --- a/client/components/site-selector/index.jsx +++ b/client/components/site-selector/index.jsx @@ -115,6 +115,7 @@ module.exports = React.createClass( { } else { sites = this.props.sites.getVisible(); } + sites = this.props.sites.withSelectedFirst( sites ); // Render sites siteElements = sites.map( function( site ) { diff --git a/client/lib/sites-list/list.js b/client/lib/sites-list/list.js index 5c3d2e4f8286a..4cda51c0e759f 100644 --- a/client/lib/sites-list/list.js +++ b/client/lib/sites-list/list.js @@ -371,11 +371,7 @@ SitesList.prototype.getSite = function( siteID ) { } return this.get().filter( function( site ) { - // We need to check `slug` before `domain` to grab the correct site on certain - // clashes between a domain redirect and a Jetpack site, as well as domains - // on subfolders, but we also need to look for the `domain` as a last resort - // to cover mapped domains for regular WP.com sites. - return site.ID === siteID || site.slug === siteID || site.domain === siteID || site.wpcom_url === siteID; + return siteMatchesSiteId( site, siteID ); }, this ).shift(); }; @@ -577,4 +573,22 @@ SitesList.prototype.onUpdatedPlugin = function( site ) { } }; +SitesList.prototype.withSelectedFirst = function( sites ) { + if ( ! this.selected ) { + // we return a copy, so that we are consistent with returning a copy in the other case + return sites.slice(); + } + + return sites.filter( site => siteMatchesSiteId( site, this.selected ) ) + .concat( sites.filter( site => ! siteMatchesSiteId( site, this.selected ) ) ); +} + +function siteMatchesSiteId( site, siteID ) { + // We need to check `slug` before `domain` to grab the correct site on certain + // clashes between a domain redirect and a Jetpack site, as well as domains + // on subfolders, but we also need to look for the `domain` as a last resort + // to cover mapped domains for regular WP.com sites. + return site.ID === siteID || site.slug === siteID || site.domain === siteID || site.wpcom_url === siteID; +} + module.exports = SitesList; diff --git a/client/lib/sites-list/test/test.js b/client/lib/sites-list/test/test.js index e0a8c3cc256b3..bbcc9601e605d 100644 --- a/client/lib/sites-list/test/test.js +++ b/client/lib/sites-list/test/test.js @@ -101,4 +101,40 @@ describe( 'SitesList', function() { } ); } ); + describe( 'withSelectedFirst', function() { + it( 'should return empty array when given empty array', function() { + var sitesList = SitesList(); + assert.deepEqual( [], sitesList.withSelectedFirst( [] ) ); + } ); + it( 'should return an equal array if there is no selected element', function() { + var sitesList = SitesList(); + sitesList.selected = null; + assert.deepEqual( original, sitesList.withSelectedFirst( original ) ); + } ); + it( 'should keep the first element if it is selected', function() { + var sitesList = SitesList(); + sitesList.initialize( original.slice() ); + sitesList.selected = original[0].ID; + assert.deepEqual( original, sitesList.withSelectedFirst( original ) ); + } ); + it( 'should move the selected site to the front', function() { + var sitesList = SitesList(), + sites = [ {ID: 1}, {ID: 2}, {ID: 3} ]; + sitesList.initialize( sites.slice() ); + sitesList.selected = 2; + assert.deepEqual( [ {ID: 2}, {ID: 1}, {ID: 3}], sitesList.withSelectedFirst( sites ) ); + } ); + it( 'should not mutate original array', function() { + var sitesList = SitesList(), + sites = [ {ID: 1}, {ID: 2}, {ID: 3} ], + originalSites = sites.slice(), + after; + sitesList.initialize( sites.slice() ); + sitesList.selected = 2; + sitesList.withSelectedFirst( sites ); + after = assert.deepEqual( originalSites, sites ); + assert( after !== sites ); + } ); + } ); + } );