Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Updates section to app management #6739

Merged
merged 5 commits into from
Oct 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions core/css/icons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
Expand Down
2 changes: 2 additions & 0 deletions lib/private/legacy/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,8 @@ public static function getAllApps() {
}
}

$apps = array_unique($apps);

return $apps;
}

Expand Down
29 changes: 29 additions & 0 deletions settings/Controller/AppSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -130,8 +131,10 @@ public function viewApps($category = '') {
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')],
Expand Down Expand Up @@ -273,6 +276,28 @@ private function getAppsForCategory($requestedCategory) {
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
*
Expand Down Expand Up @@ -301,6 +326,10 @@ public function listApps($category = '') {
return ($a < $b) ? -1 : 1;
});
break;
// updates
case 'updates':
$apps = $this->getAppsWithUpdates();
break;
// enabled apps
case 'enabled':
$apps = $appClass->listAllApps();
Expand Down
79 changes: 65 additions & 14 deletions settings/js/apps.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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
Expand All @@ -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 {
Expand All @@ -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;
Expand All @@ -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({
Expand Down Expand Up @@ -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....'));
Expand All @@ -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');
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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');
Expand Down
10 changes: 6 additions & 4 deletions settings/templates/apps.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
{{#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}}

Expand Down Expand Up @@ -65,9 +70,6 @@
</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}}
Expand Down Expand Up @@ -206,7 +208,7 @@
</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>
6 changes: 6 additions & 0 deletions tests/Settings/Controller/AppSettingsControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ public function testListCategories() {
'ident' => 'installed',
'displayName' => 'Your apps',
],
[
'id' => 4,
'ident' => 'updates',
'displayName' => 'Updates',
'counter' => 0,
],
[
'id' => 0,
'ident' => 'enabled',
Expand Down