diff --git a/src/js/_enqueues/wp/updates.js b/src/js/_enqueues/wp/updates.js
index 9f3b80b843d46..458da2de79f47 100644
--- a/src/js/_enqueues/wp/updates.js
+++ b/src/js/_enqueues/wp/updates.js
@@ -1379,6 +1379,16 @@
* @type {Object}
*/
plugins = settings.plugins,
+ /**
+ * Plugin groups that Core handles on its own.
+ *
+ * @type {Array}
+ */
+ coreGroups = [
+ 'all', 'search', 'upgrade', 'active', 'inactive',
+ 'recently_activated', 'mustuse', 'dropins', 'paused',
+ 'auto-update-enabled', 'auto-update-disabled'
+ ],
remainingCount;
// Add a success message after deleting a plugin.
@@ -1447,6 +1457,24 @@
}
}
+ // Remove from custom groups added through the `plugins_list` filter.
+ _.each( _.keys( plugins ), function( group ) {
+ var $view;
+
+ if ( -1 !== _.indexOf( coreGroups, group ) || ! _.isArray( plugins[ group ] ) || -1 === _.indexOf( plugins[ group ], response.plugin ) ) {
+ return;
+ }
+
+ plugins[ group ] = _.without( plugins[ group ], response.plugin );
+ $view = $views.children( 'li.' + $.escapeSelector( group ) );
+
+ if ( plugins[ group ].length ) {
+ $view.find( '.count' ).text( '(' + plugins[ group ].length + ')' );
+ } else {
+ $view.remove();
+ }
+ } );
+
plugins.all = _.without( plugins.all, response.plugin );
if ( plugins.all.length ) {
@@ -1460,6 +1488,9 @@
}
}
+ // Remove the trailing separator left on the last view when the view after it was removed.
+ $views.find( 'li:last' ).html( function() { return $( this ).children(); } );
+
if ( $itemsCount.length && $currentView.length ) {
remainingCount = plugins[ $currentView.parent( 'li' ).attr('class') ].length;
$itemsCount.text(
diff --git a/tests/qunit/wp-admin/js/updates.js b/tests/qunit/wp-admin/js/updates.js
index 9d3948811abfd..500d74a63afed 100644
--- a/tests/qunit/wp-admin/js/updates.js
+++ b/tests/qunit/wp-admin/js/updates.js
@@ -122,6 +122,78 @@ jQuery( function( $ ) {
assert.equal( jQuery.ajax.getCall( 0 ).args[0].data.action, 'delete-plugin' );
assert.equal( jQuery.ajax.getCall( 0 ).args[0].data.slug, 'jetpack' );
} );
+ QUnit.test( 'Deleting a plugin should update the counts of custom plugin groups', function( assert ) {
+ var plugins = window._wpUpdatesSettings.plugins;
+
+ $( '#qunit-fixture' ).append(
+ '' +
+ '
' +
+ ''
+ );
+
+ window._wpUpdatesSettings.plugins = {
+ all: [ 'custom-a/custom-a.php', 'custom-b/custom-b.php', 'other/other.php' ],
+ demo_group: [ 'custom-a/custom-a.php', 'custom-b/custom-b.php' ],
+ single_group: [ 'custom-a/custom-a.php' ]
+ };
+
+ // Run the fade out callback right away.
+ sinon.stub( $.fn, 'fadeOut' ).callsFake( function( speed, callback ) {
+ return this.each( callback );
+ } );
+
+ wp.updates.deletePluginSuccess( { slug: 'custom-a', plugin: 'custom-a/custom-a.php', pluginName: 'Custom A' } );
+
+ $.fn.fadeOut.restore();
+
+ assert.equal( $( '.subsubsub .all .count' ).text(), '(2)', 'The All count should go down.' );
+ assert.equal( $( '.subsubsub .demo_group .count' ).text(), '(1)', 'The custom group count should go down.' );
+ assert.strictEqual( $( '.subsubsub .single_group' ).length, 0, 'An empty custom group should be removed.' );
+ assert.strictEqual( $( '.subsubsub .all' ).text(), 'All (2) |', 'Separators between views should be kept.' );
+ assert.strictEqual( $( '.subsubsub .demo_group' ).text(), 'Demo Group (1)', 'The new last view should not end with a separator.' );
+ assert.deepEqual( window._wpUpdatesSettings.plugins.demo_group, [ 'custom-b/custom-b.php' ], 'The deleted plugin should be removed from the custom group.' );
+
+ window._wpUpdatesSettings.plugins = plugins;
+ } );
+ QUnit.test( 'Deleting a plugin should only remove the view of an emptied custom group', function( assert ) {
+ var plugins = window._wpUpdatesSettings.plugins;
+
+ $( '#qunit-fixture' ).append(
+ '' +
+ '' +
+ ''
+ );
+
+ // A group key that matches the class of the count elements.
+ window._wpUpdatesSettings.plugins = {
+ all: [ 'custom-a/custom-a.php', 'other/other.php' ],
+ count: [ 'custom-a/custom-a.php' ]
+ };
+
+ sinon.stub( $.fn, 'fadeOut' ).callsFake( function( speed, callback ) {
+ return this.each( callback );
+ } );
+
+ wp.updates.deletePluginSuccess( { slug: 'custom-a', plugin: 'custom-a/custom-a.php', pluginName: 'Custom A' } );
+
+ $.fn.fadeOut.restore();
+
+ assert.strictEqual( $( '.subsubsub > li.count' ).length, 0, 'The emptied group view should be removed.' );
+ assert.strictEqual( $( '.subsubsub .all' ).text(), 'All (1)', 'The All view should keep its count.' );
+
+ window._wpUpdatesSettings.plugins = plugins;
+ } );
// QUnit.test( 'A successful update changes the message?', function( assert ) {} );
// QUnit.test( 'A failed update changes the message?', function( assert ) {} );