From 5b4287b991780662597682817c588e2e92c6310a Mon Sep 17 00:00:00 2001 From: Andrew Nacin Date: Tue, 1 Apr 2014 22:19:51 +0000 Subject: [PATCH] Theme Installer fixes: * Better more filters section. props sonjanyc for some mockups. * Better handling of no results. * Use # for hrefs. props matveb. see #27055. git-svn-id: https://develop.svn.wordpress.org/trunk@27896 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/themes.css | 98 ++++++++++++++++++++++++++++++---- src/wp-admin/js/theme.js | 92 ++++++++++++++++++++++++++++--- src/wp-admin/theme-install.php | 15 ++++-- 3 files changed, 185 insertions(+), 20 deletions(-) diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index 3dea4b7394..fba8b89d63 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -1150,8 +1150,6 @@ body.show-upload-theme .upload-theme + .theme-navigation + .theme-browser { display: inline-block; margin: 0 10px; padding: 15px 0; - -webkit-transition: border-color .1s ease-in; - transition: border-color .1s ease-in; } .theme-section.current, .theme-filter.current { @@ -1167,8 +1165,6 @@ body.show-upload-theme .upload-theme + .theme-navigation + .theme-browser { display: inline-block; margin: 0 10px; padding: 4px 6px; - -webkit-transition: color .1s ease-in, background .1s ease-in; - transition: color .1s ease-in, background .1s ease-in; } body.more-filters-opened .more-filters, body.more-filters-opened .more-filters:before { @@ -1177,8 +1173,6 @@ body.more-filters-opened .more-filters:before { border-radius: 2px; border: none; color: #fff; - -webkit-transition: color .1s ease-in, background .1s ease-in; - transition: color .1s ease-in, background .1s ease-in; } body.more-filters-opened .more-filters:hover, @@ -1230,20 +1224,97 @@ body.more-filters-opened .more-filters:focus:before { body.more-filters-opened .more-filters-container { display: block; } +body.more-filters-opened .theme-section.current { + border-bottom: none; +} +body.more-filters-opened .theme-browser, +body.more-filters-opened.filters-applied.loading-themes .theme-browser { + display: none; +} +body.more-filters-opened.filters-applied .theme-browser { + display: block; +} .more-filters-container .filters-group { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; float: left; - width: 20%; + width: 19%; + background: #fff; + margin: 0 1% 0 0; + border: 1px solid #e5e5e5; + -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04); + box-shadow: 0 1px 1px rgba(0,0,0,0.04); + padding: 10px; } .more-filters-container .feature-name { - margin-top: 0; + margin: 0; + position: relative; } .more-filters-container ol { list-style-type: none; + margin: 20px 0 0; + display: block; + font-size: 12px; +} +.theme-navigation .more-filters-container .apply-filters { + margin: 20px 0 0; +} +.theme-navigation .more-filters-container .clear-filters { + display: none; + margin: 20px 0 0 10px; +} +.more-filters-container .apply-filters span { + display: inline-block; + font-size: 12px; + text-indent: 10px; + opacity: 0.8; +} +.more-filters-container .filtering-by { + display: none; margin: 0; } +.more-filters-container .filtering-by > span { + font-weight: 600; +} +.more-filters-container .filtering-by .tags { + display: inline; +} +.more-filters-container .filtering-by .tag { + background: #fff; + border: 1px solid #e5e5e5; + box-shadow: 0 1px 1px rgba(0,0,0,0.04); + font-size: 11px; + margin: 0 5px; + padding: 4px 8px; +} +body.filters-applied .more-filters-container .filters-group, +body.filters-applied .more-filters-container a, +body.filters-applied .more-filters-container br { + display: none !important; +} +body.filters-applied .more-filters-container .filtering-by { + display: block; +} +body.filters-applied .more-filters-container { + padding: 20px; +} +p.no-themes { + color: #999; + font-size: 18px; + font-style: normal; + margin: 0; + padding: 0; + text-align: center; + display: none; +} +body.no-results p.no-themes { + display: block; +} +body.show-upload-theme p.no-themes { + display: none !important; +} + .theme-install-php .add-new-theme { display: none !important; @@ -1268,13 +1339,21 @@ body.more-filters-opened .more-filters-container { text-align: left; } .more-filters-container .filters-group { - width: 50%; + margin-bottom: 0; + margin-top: 5px; + width: 49%; } .more-filters-container .filters-group:nth-child(3n) { clear: left; } } +@media only screen and (max-width: 782px) { + .more-filters-container .filters-group { + width: 100%; + } +} + .rating { margin: 30px 0; } @@ -1717,6 +1796,7 @@ body.full-overlay-active { float: left; color: #777; line-height: 20px; + max-width: 100%; } #theme-installer .wp-full-overlay-header { diff --git a/src/wp-admin/js/theme.js b/src/wp-admin/js/theme.js index f2fdf0d84f..43df6a459f 100644 --- a/src/wp-admin/js/theme.js +++ b/src/wp-admin/js/theme.js @@ -255,6 +255,10 @@ themes.Collection = Backbone.Collection.extend({ self.trigger( 'update' ); self.trigger( 'query:success', count ); + if ( data.themes.length === 0 ) { + self.trigger( 'query:empty' ); + } + // Store the results and the query request queries.push( { themes: data.themes, request: request } ); }).fail( function() { @@ -277,6 +281,12 @@ themes.Collection = Backbone.Collection.extend({ }); } + if ( query.themes.length === 0 ) { + self.trigger( 'query:empty' ); + } else { + $( 'body' ).removeClass( 'no-results' ); + } + // Only trigger an update event since we already have the themes // on our cached object this.reset( query.themes ); @@ -330,7 +340,7 @@ themes.Collection = Backbone.Collection.extend({ beforeSend: function() { if ( ! paginated ) { // Spin it - $( 'body' ).addClass( 'loading-themes' ); + $( 'body' ).addClass( 'loading-themes' ).removeClass( 'no-results' ); } } }); @@ -657,6 +667,7 @@ themes.view.Preview = wp.Backbone.View.extend({ }, collapse: function() { + this.$el.toggleClass( 'collapsed' ).toggleClass( 'expanded' ); return false; } @@ -704,6 +715,10 @@ themes.view.Themes = wp.Backbone.View.extend({ } }); + this.listenTo( self.collection, 'query:empty', function() { + $( 'body' ).addClass( 'no-results' ); + }); + this.listenTo( this.parent, 'theme:scroll', function() { self.renderThemes( self.parent.page ); }); @@ -1143,7 +1158,10 @@ themes.view.Installer = themes.view.Appearance.extend({ 'click .theme-section': 'onSort', 'click .theme-filter': 'onFilter', 'click .more-filters': 'moreFilters', - 'click [type="checkbox"]': 'addFilter' + 'click .apply-filters': 'addFilter', + 'click [type="checkbox"]': 'filtersChecked', + 'click .clear-filters': 'clearFilters', + 'click .feature-name': 'filterSection' }, // Handles all the rendering of the public theme directory @@ -1217,6 +1235,8 @@ themes.view.Installer = themes.view.Appearance.extend({ event.preventDefault(); + $( 'body' ).removeClass( 'filters-applied more-filters-opened' ); + // Bail if this is already active if ( $el.hasClass( this.activeClass ) ) { return; @@ -1266,16 +1286,31 @@ themes.view.Installer = themes.view.Appearance.extend({ }, // Clicking on a checkbox triggers a tag request - addFilter: function() { - var tags = this.filtersChecked(), - request = { tag: tags }; + addFilter: function( event ) { + var name, + tags = this.filtersChecked(), + request = { tag: tags }, + filteringBy = $( '.filtering-by .tags' ); + + if ( event ) { + event.preventDefault(); + } + + $( 'body' ).addClass( 'filters-applied' ); + filteringBy.empty(); + + _.each( tags, function( tag ) { + name = $( 'label[for="feature-id-' + tag + '"]' ).text(); + filteringBy.append( '' + name + '' ); + }); // Get the themes by sending Ajax POST request to api.wordpress.org/themes // or searching the local cache this.collection.query( request ); }, - // Get the checked filters and return an array + // Get the checked filters + // @return {array} of tags or false filtersChecked: function() { var items = $( '.feature-group' ).find( ':checkbox' ), tags = []; @@ -1284,6 +1319,17 @@ themes.view.Installer = themes.view.Appearance.extend({ tags.push( $( item ).prop( 'value' ) ); }); + // When no filters are checked, restore initial state and return + if ( tags.length === 0 ) { + $( '.apply-filters' ).find( 'span' ).text( '' ); + $( '.clear-filters' ).hide(); + $( 'body' ).removeClass( 'filters-applied' ); + return false; + } + + $( '.apply-filters' ).find( 'span' ).text( tags.length ); + $( '.clear-filters' ).css( 'display', 'inline-block' ); + return tags; }, @@ -1304,8 +1350,40 @@ themes.view.Installer = themes.view.Appearance.extend({ }); }, - moreFilters: function() { + // Toggle the full filters navigation + moreFilters: function( event ) { + event.preventDefault(); + + if ( $( 'body' ).hasClass( 'filters-applied' ) ) { + return $( 'body' ).removeClass( 'filters-applied' ); + } + + // If the filters section is opened and filters are checked + // run the relevant query collapsing to filtered-by state + if ( $( 'body' ).hasClass( 'more-filters-opened' ) && this.filtersChecked() ) { + return this.addFilter(); + } + $( 'body' ).toggleClass( 'more-filters-opened' ); + }, + + // Expand/collapse each individual filter section + filterSection: function() { + $( event.target ).parent().toggleClass( 'open' ); + }, + + // Clears all the checked filters + // @uses filtersChecked() + clearFilters: function( event ) { + var items = $( '.feature-group' ).find( ':checkbox' ), + self = this; + + event.preventDefault(); + + _.each( items.filter( ':checked' ), function( item ) { + $( item ).prop( 'checked', false ); + return self.filtersChecked(); + }); } }); diff --git a/src/wp-admin/theme-install.php b/src/wp-admin/theme-install.php index 9653317c6d..5f61ad762e 100644 --- a/src/wp-admin/theme-install.php +++ b/src/wp-admin/theme-install.php @@ -118,8 +118,8 @@ include(ABSPATH . 'wp-admin/admin-header.php');
- +
@@ -140,12 +140,19 @@ include(ABSPATH . 'wp-admin/admin-header.php'); } ?>
+ + +
+ +
+
+


@@ -188,7 +195,7 @@ if ( $tab ) {