diff options
author | Julius Härtl <github@jus.li> | 2017-10-10 14:57:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-10 14:57:35 +0200 |
commit | 0def38b50ea7281b1c887833a966ce42ff016c36 (patch) | |
tree | 1bc25ac5d2742ea30217bb7a29bc4a065da53d30 | |
parent | 968d4f6396e30321a4f05f867edd581ba50c9e81 (diff) | |
parent | bee9ef83c65689990dba852b1944b5cf472eae43 (diff) | |
download | nextcloud-server-0def38b50ea7281b1c887833a966ce42ff016c36.tar.gz nextcloud-server-0def38b50ea7281b1c887833a966ce42ff016c36.zip |
Merge pull request #6739 from nextcloud/apps-management-updates
Add Updates section to app management
-rw-r--r-- | core/css/icons.scss | 7 | ||||
-rw-r--r-- | lib/private/legacy/app.php | 2 | ||||
-rw-r--r-- | settings/Controller/AppSettingsController.php | 29 | ||||
-rw-r--r-- | settings/js/apps.js | 79 | ||||
-rw-r--r-- | settings/templates/apps.php | 10 | ||||
-rw-r--r-- | tests/Settings/Controller/AppSettingsControllerTest.php | 6 |
6 files changed, 115 insertions, 18 deletions
diff --git a/core/css/icons.scss b/core/css/icons.scss index 7c47a3e12c8..6d855381fae 100644 --- a/core/css/icons.scss +++ b/core/css/icons.scss @@ -493,16 +493,23 @@ img, object, video, button, textarea, input, select { .icon-category-installed { background-image: url('../img/actions/user.svg?v=1'); } + .icon-category-enabled { background-image: url('../img/actions/checkmark.svg?v=1'); } + .icon-category-disabled { background-image: url('../img/actions/close.svg?v=1'); } + .icon-category-app-bundles { background-image: url('../img/categories/bundles.svg?v=1'); } +.icon-category-updates { + background-image: url('../img/actions/download.svg?v=1'); +} + .icon-category-files { background-image: url('../img/categories/files.svg?v=1'); } diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php index a33c9be20fc..627107a63a8 100644 --- a/lib/private/legacy/app.php +++ b/lib/private/legacy/app.php @@ -768,6 +768,8 @@ class OC_App { } } + $apps = array_unique($apps); + return $apps; } diff --git a/settings/Controller/AppSettingsController.php b/settings/Controller/AppSettingsController.php index ac77b2e7dd6..da59461e5fa 100644 --- a/settings/Controller/AppSettingsController.php +++ b/settings/Controller/AppSettingsController.php @@ -52,6 +52,7 @@ class AppSettingsController extends Controller { const CAT_DISABLED = 1; const CAT_ALL_INSTALLED = 2; const CAT_APP_BUNDLES = 3; + const CAT_UPDATES = 4; /** @var \OCP\IL10N */ private $l10n; @@ -130,8 +131,10 @@ class AppSettingsController extends Controller { private function getAllCategories() { $currentLanguage = substr($this->l10nFactory->findLanguage(), 0, 2); + $updateCount = count($this->getAppsWithUpdates()); $formattedCategories = [ ['id' => self::CAT_ALL_INSTALLED, 'ident' => 'installed', 'displayName' => (string)$this->l10n->t('Your apps')], + ['id' => self::CAT_UPDATES, 'ident' => 'updates', 'displayName' => (string)$this->l10n->t('Updates'), 'counter' => $updateCount], ['id' => self::CAT_ENABLED, 'ident' => 'enabled', 'displayName' => (string)$this->l10n->t('Enabled apps')], ['id' => self::CAT_DISABLED, 'ident' => 'disabled', 'displayName' => (string)$this->l10n->t('Disabled apps')], ['id' => self::CAT_APP_BUNDLES, 'ident' => 'app-bundles', 'displayName' => (string)$this->l10n->t('App bundles')], @@ -273,6 +276,28 @@ class AppSettingsController extends Controller { return $formattedApps; } + private function getAppsWithUpdates() { + $appClass = new \OC_App(); + $apps = $appClass->listAllApps(); + foreach($apps as $key => $app) { + $newVersion = \OC\Installer::isUpdateAvailable($app['id'], $this->appFetcher); + if($newVersion !== false) { + $apps[$key]['update'] = $newVersion; + } else { + unset($apps[$key]); + } + } + usort($apps, function ($a, $b) { + $a = (string)$a['name']; + $b = (string)$b['name']; + if ($a === $b) { + return 0; + } + return ($a < $b) ? -1 : 1; + }); + return $apps; + } + /** * Get all available apps in a category * @@ -301,6 +326,10 @@ class AppSettingsController extends Controller { return ($a < $b) ? -1 : 1; }); break; + // updates + case 'updates': + $apps = $this->getAppsWithUpdates(); + break; // enabled apps case 'enabled': $apps = $appClass->listAllApps(); diff --git a/settings/js/apps.js b/settings/js/apps.js index 39e800636cb..6406e37cbcb 100644 --- a/settings/js/apps.js +++ b/settings/js/apps.js @@ -58,8 +58,15 @@ OC.Settings.Apps = OC.Settings.Apps || { type:'GET', success:function (jsondata) { var html = template(jsondata); + var updateCategory = $.grep(jsondata, function(element, index) { + return element.ident === 'updates' + }); $('#apps-categories').html(html); $('#app-category-' + OC.Settings.Apps.State.currentCategory).addClass('active'); + if (updateCategory.length === 1) { + OC.Settings.Apps.State.availableUpdates = updateCategory[0].counter; + OC.Settings.Apps.refreshUpdateCounter(); + } }, complete: function() { $('#app-navigation').removeClass('icon-loading'); @@ -84,7 +91,6 @@ OC.Settings.Apps = OC.Settings.Apps || { $('#app-category-' + OC.Settings.Apps.State.currentCategory).removeClass('active'); $('#app-category-' + categoryId).addClass('active'); OC.Settings.Apps.State.currentCategory = categoryId; - OC.Settings.Apps.State.availableUpdates = 0; this._loadCategoryCall = $.ajax(OC.generateUrl('settings/apps/list?category={categoryId}', { categoryId: categoryId @@ -99,7 +105,7 @@ OC.Settings.Apps = OC.Settings.Apps || { return _.extend({level: 0}, app); }); var source; - if (categoryId === 'enabled' || categoryId === 'disabled' || categoryId === 'installed' || categoryId === 'app-bundles') { + if (categoryId === 'enabled' || categoryId === 'updates' || categoryId === 'disabled' || categoryId === 'installed' || categoryId === 'app-bundles') { source = $("#app-template-installed").html(); $('#apps-list').addClass('installed'); } else { @@ -122,6 +128,7 @@ OC.Settings.Apps = OC.Settings.Apps || { } var firstExperimental = false; + var hasNewUpdates = false; _.each(appList, function(app) { if(app.level === 0 && firstExperimental === false) { firstExperimental = true; @@ -131,19 +138,28 @@ OC.Settings.Apps = OC.Settings.Apps || { } if (app.update) { + hasNewUpdates = true; var $update = $('#app-' + app.id + ' .update'); $update.removeClass('hidden'); $update.val(t('settings', 'Update to %s').replace(/%s/g, app.update)); - OC.Settings.Apps.State.availableUpdates++; } }); - - if (OC.Settings.Apps.State.availableUpdates > 0) { - OC.Settings.Apps.State.$updateNotification = OC.Notification.show(n('settings', 'You have %n app update pending', 'You have %n app updates pending', OC.Settings.Apps.State.availableUpdates)); + // reload updates if a list with new updates is loaded + if (hasNewUpdates) { + OC.Settings.Apps.reloadUpdates(); + } else { + // hide update category after all updates are installed + // and the user is switching away from the empty updates view + OC.Settings.Apps.refreshUpdateCounter(); } } else { - $('#apps-list').addClass('hidden'); - $('#apps-list-empty').removeClass('hidden').find('h2').text(t('settings', 'No apps found for your version')); + if (categoryId === 'updates') { + OC.Settings.Apps.showEmptyUpdates(); + } else { + $('#apps-list').addClass('hidden'); + $('#apps-list-empty').removeClass('hidden').find('h2').text(t('settings', 'No apps found for your version')); + $('#app-list-empty-icon').addClass('icon-search').removeClass('icon-download'); + } } $('.enable.needs-download').tooltip({ @@ -517,6 +533,12 @@ OC.Settings.Apps = OC.Settings.Apps || { } }, + showEmptyUpdates: function() { + $('#apps-list').addClass('hidden'); + $('#apps-list-empty').removeClass('hidden').find('h2').text(t('settings', 'No app updates available')); + $('#app-list-empty-icon').removeClass('icon-search').addClass('icon-download'); + }, + updateApp:function(appId, element) { var oldButtonText = element.val(); element.val(t('settings','Updating....')); @@ -539,13 +561,14 @@ OC.Settings.Apps = OC.Settings.Apps || { var $version = $('#app-' + appId + ' .app-version'); $version.text(OC.Settings.Apps.State.apps[appId]['update']); - if (OC.Settings.Apps.State.$updateNotification) { - OC.Notification.hide(OC.Settings.Apps.State.$updateNotification); - } - OC.Settings.Apps.State.availableUpdates--; - if (OC.Settings.Apps.State.availableUpdates > 0) { - OC.Settings.Apps.State.$updateNotification = OC.Notification.show(n('settings', 'You have %n app update pending', 'You have %n app updates pending', OC.Settings.Apps.State.availableUpdates)); + OC.Settings.Apps.refreshUpdateCounter(); + + if (OC.Settings.Apps.State.currentCategory === 'updates') { + $('#app-' + appId).remove(); + if (OC.Settings.Apps.State.availableUpdates === 0) { + OC.Settings.Apps.showEmptyUpdates(); + } } } },'json'); @@ -656,6 +679,33 @@ OC.Settings.Apps = OC.Settings.Apps || { }); }, + reloadUpdates: function() { + if (this._loadUpdatesCall) { + this._loadUpdatesCall.abort(); + } + this._loadUpdatesCall = $.ajax(OC.generateUrl('settings/apps/list?category=updates'), { + type:'GET', + success: function (apps) { + OC.Settings.Apps.State.availableUpdates = apps.apps.length; + OC.Settings.Apps.refreshUpdateCounter(); + } + }); + }, + + refreshUpdateCounter: function() { + var $appCategoryUpdates = $('#app-category-updates'); + var $updateCount = $appCategoryUpdates.find('.app-navigation-entry-utils-counter'); + if (OC.Settings.Apps.State.availableUpdates > 0) { + $updateCount.html(OC.Settings.Apps.State.availableUpdates); + $appCategoryUpdates.show(); + } else { + $updateCount.empty(); + if (OC.Settings.Apps.State.currentCategory !== 'updates') { + $appCategoryUpdates.hide(); + } + } + }, + showErrorMessage: function(appId, message) { $('div#app-'+appId+' .warning') .show() @@ -703,6 +753,7 @@ OC.Settings.Apps = OC.Settings.Apps || { filter: function(query) { var $appList = $('#apps-list'), $emptyList = $('#apps-list-empty'); + $('#app-list-empty-icon').addClass('icon-search').removeClass('icon-download'); $appList.removeClass('hidden'); $appList.find('.section').removeClass('hidden'); $emptyList.addClass('hidden'); diff --git a/settings/templates/apps.php b/settings/templates/apps.php index 91a73fcbe56..5d519496598 100644 --- a/settings/templates/apps.php +++ b/settings/templates/apps.php @@ -19,6 +19,11 @@ script( {{#each this}} <li id="app-category-{{ident}}" data-category-id="{{ident}}" tabindex="0"> <a href="#" class="icon-category-{{ident}}">{{displayName}}</a> + <div class="app-navigation-entry-utils"> + <ul> + <li class="app-navigation-entry-utils-counter">{{ counter }}</li> + </ul> + </div> </li> {{/each}} @@ -65,9 +70,6 @@ script( </div> <div class="actions"> - <div class="app-dependencies update hidden"> - <p><?php p($l->t('This app has an update available.')); ?></p> - </div> <div class="warning hidden"></div> <input class="update hidden" type="submit" value="<?php p($l->t('Update to %s', array('{{update}}'))); ?>" data-appid="{{id}}" /> {{#if canUnInstall}} @@ -206,7 +208,7 @@ script( </svg> <div id="apps-list"></div> <div id="apps-list-empty" class="hidden emptycontent emptycontent-search"> - <div class="icon-search"></div> + <div id="app-list-empty-icon" class="icon-search"></div> <h2><?php p($l->t('No apps found for your version')) ?></h2> </div> </div> diff --git a/tests/Settings/Controller/AppSettingsControllerTest.php b/tests/Settings/Controller/AppSettingsControllerTest.php index 9633c771596..e264d0dfbfe 100644 --- a/tests/Settings/Controller/AppSettingsControllerTest.php +++ b/tests/Settings/Controller/AppSettingsControllerTest.php @@ -102,6 +102,12 @@ class AppSettingsControllerTest extends TestCase { 'displayName' => 'Your apps', ], [ + 'id' => 4, + 'ident' => 'updates', + 'displayName' => 'Updates', + 'counter' => 0, + ], + [ 'id' => 0, 'ident' => 'enabled', 'displayName' => 'Enabled apps', |