Migrate the app to Vue.js

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2018-01-18 12:25:52 +01:00
parent 52f8d75d1a
commit b12b391d7c
No known key found for this signature in database
GPG Key ID: 7076EA9751AACDDA
8 changed files with 10768 additions and 164 deletions

View File

@ -1,3 +1,4 @@
#updatenotification p,
#oca_updatenotification_section p {
margin: 25px 0;
}

View File

@ -1,84 +1,48 @@
/**
* Copyright (c) 2016 ownCloud Inc
* @copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @author Lukas Reschke <lukas@owncloud.com>
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
* @author Joas Schilling <coding@schilljs.com>
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*/
/**
* Creates a new authentication token and loads the updater URL
*/
var loginToken = '';
$(document).ready(function(){
$('#oca_updatenotification_button').click(function() {
// Load the new token
$.ajax({
url: OC.generateUrl('/apps/updatenotification/credentials')
}).success(function(data) {
loginToken = data;
$.ajax({
url: OC.webroot+'/updater/',
headers: {
'X-Updater-Auth': loginToken
},
method: 'POST',
success: function(data){
if(data !== 'false') {
var body = $('body');
$('head').remove();
body.html(data);
(function(OC, OCA, Vue, $) {
"use strict";
// Eval the script elements in the response
var dom = $(data);
dom.filter('script').each(function() {
eval(this.text || this.textContent || this.innerHTML || '');
});
OCA.UpdateNotification = OCA.UpdateNotification || {};
body.removeAttr('id');
body.attr('id', 'body-settings');
}
},
error: function(){
OC.Notification.showTemporary(t('updatenotification', 'Could not start updater, please try the manual update'));
$('#oca_updatenotification_button').addClass('hidden');
$('#oca_updatenotification_section .button').removeClass('hidden');
}
});
});
});
OCA.UpdateNotification.App = {
$('#release-channel').change(function() {
var newChannel = $('#release-channel').find(":selected").val();
if (newChannel === 'git' || newChannel === 'daily') {
$('#oca_updatenotification_groups em').removeClass('hidden');
} else {
$('#oca_updatenotification_groups em').addClass('hidden');
/** @type {number|null} */
interval: null,
/** @type {Vue|null} */
vm: null,
/**
* Initialise the app
*/
initialise: function() {
var data = JSON.parse($('#updatenotification').attr('data-json'));
this.vm = new Vue(OCA.UpdateNotification.Components.Root);
this.vm.newVersionString = data.newVersionString;
this.vm.lastCheckedDate = data.lastChecked;
this.vm.isUpdateChecked = data.isUpdateChecked;
this.vm.updaterEnabled = data.updaterEnabled;
this.vm.downloadLink = data.downloadLink;
this.vm.isNewVersionAvailable = data.isNewVersionAvailable;
this.vm.updateServerURL = data.updateServerURL;
this.vm.currentChannel = data.currentChannel;
this.vm.channels = data.channels;
this.vm.notifyGroups = data.notifyGroups;
this.vm.isDefaultUpdateServerURL = data.isDefaultUpdateServerURL;
}
};
})(OC, OCA, Vue, $);
$.post(
OC.generateUrl('/apps/updatenotification/channel'),
{
'channel': newChannel
},
function(data){
OC.msg.finishedAction('#channel_save_msg', data);
}
);
});
var $notificationTargetGroups = $('#oca_updatenotification_groups_list');
OC.Settings.setupGroupsSelect($notificationTargetGroups);
$notificationTargetGroups.change(function(ev) {
var groups = ev.val || [];
groups = JSON.stringify(groups);
OCP.AppConfig.setValue('updatenotification', 'notify_groups', groups);
});
$('#oca_updatenotification_section .icon-info').tooltip({placement: 'right'});
$(document).ready(function () {
OCA.UpdateNotification.App.initialise();
});

View File

@ -0,0 +1,165 @@
/**
* @copyright (c) 2018 Joas Schilling <coding@schilljs.com>
* @copyright (c) 2016 ownCloud Inc
*
* @author Joas Schilling <coding@schilljs.com>
* @author Lukas Reschke <lukas@owncloud.com>
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*/
(function(OC, OCA, OCP, t, $) {
"use strict";
OCA.UpdateNotification = OCA.UpdateNotification || {};
OCA.UpdateNotification.Components = OCA.UpdateNotification.Components || {};
OCA.UpdateNotification.Components.Root = {
template: '' +
'<div id="updatenotification" class="followupsection">' +
' <p>' +
' <template v-if="isNewVersionAvailable">' +
' <strong>{{newVersionAvailableString}}</strong>' +
' <input v-if="updaterEnabled" type="button" @click="clickUpdaterButton" id="oca_updatenotification_button" value="' + t('updatenotification', 'Open updater') + '">' +
' <a v-if="downloadLink" :href="downloadLink" class="button" :class="{ hidden: !updaterEnabled }">' + t('updatenotification', 'Download now') + '</a>' +
' </template>' +
' <template v-else-if="!isUpdateChecked">' + t('updatenotification', 'The update check is not yet finished. Please refresh the page.') + '</template>' +
' <template v-else>' +
' ' + t('updatenotification', 'Your version is up to date.') + '' +
' <span class="icon-info svg" :title="lastCheckedOnString"></span>' +
' </template>' +
'' +
' <template v-if="!isDefaultUpdateServerURL">' +
' <br />' +
' <em>' +
' ' + t('updatenotification', 'A non-default update server is in use to be checked for updates:') +
' <code>{{updateServerURL}}</code>' +
' </em>' +
' </template>' +
' </p>' +
'' +
' <p>' +
' <label for="release-channel">' + t('updatenotification', 'Update channel:') + '</label>' +
' <select id="release-channel" v-model="currentChannel" @change="changeReleaseChannel">' +
' <option v-for="channel in channels" :value="channel">{{channel}}</option>' +
' </select>' +
' <span id="channel_save_msg" class="msg"></span><br />' +
' <em>' + t('updatenotification', 'You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel.') + '</em><br />' +
' <em>' + t('updatenotification', 'Note that after a new release it can take some time before it shows up here. We roll out new versions spread out over time to our users and sometimes skip a version when issues are found.') + '</em>' +
' </p>' +
'' +
' <p id="oca_updatenotification_groups">' +
' ' + t('updatenotification', 'Notify members of the following groups about available updates:') +
' <input name="oca_updatenotification_groups_list" type="hidden" id="oca_updatenotification_groups_list" v-model="notifyGroups" @change="saveNotifyGroups" :value="notifyGroups" style="width: 400px"><br />' +
' <em v-if="currentChannel === \'daily\' || currentChannel === \'git\'">' + t('updatenotification', 'Only notification for app updates are available.') + '</em>' +
' <em v-if="currentChannel === \'daily\'">' + t('updatenotification', 'The selected update channel makes dedicated notifications for the server obsolete.') + '</em>' +
' <em v-if="currentChannel === \'git\'">' + t('updatenotification', 'The selected update channel does not support updates of the server.') + '</em>' +
' </p>' +
'</div>',
el: '#updatenotification',
data: {
newVersionString: '',
lastCheckedDate: '',
isUpdateChecked: false,
updaterEnabled: true,
downloadLink: '',
isNewVersionAvailable: false,
updateServerURL: '',
currentChannel: '',
channels: [],
notifyGroups: '',
isDefaultUpdateServerURL: true
},
_$el: null,
_$releaseChannel: null,
_$notifyGroups: null,
computed: {
newVersionAvailableString: function() {
return t('updatenotification', 'A new version is available: {newVersionString}', {
newVersionString: this.newVersionString
});
},
lastCheckedOnString: function() {
return t('updatenotification', 'Checked on {lastCheckedDate}', {
lastCheckedDate: this.lastCheckedDate
});
}
},
methods: {
/**
* Creates a new authentication token and loads the updater URL
*/
clickUpdaterButton: function() {
$.ajax({
url: OC.generateUrl('/apps/updatenotification/credentials')
}).success(function(data) {
$.ajax({
url: OC.getRootPath()+'/updater/',
headers: {
'X-Updater-Auth': data
},
method: 'POST',
success: function(data){
if(data !== 'false') {
var body = $('body');
$('head').remove();
body.html(data);
// Eval the script elements in the response
var dom = $(data);
dom.filter('script').each(function() {
eval(this.text || this.textContent || this.innerHTML || '');
});
body.removeAttr('id');
body.attr('id', 'body-settings');
}
},
error: function() {
OC.Notification.showTemporary(t('updatenotification', 'Could not start updater, please try the manual update'));
this.updaterEnabled = false;
}.bind(this)
});
}.bind(this));
},
changeReleaseChannel: function() {
this.currentChannel = this._$releaseChannel.val();
$.ajax({
url: OC.generateUrl('/apps/updatenotification/channel'),
type: 'POST',
data: {
'channel': this.currentChannel
},
success: function (data) {
OC.msg.finishedAction('#channel_save_msg', data);
}
});
},
saveNotifyGroups: function(e) {
var groups = e.val || [];
groups = JSON.stringify(groups);
OCP.AppConfig.setValue('updatenotification', 'notify_groups', groups);
}
},
mounted: function () {
this._$el = $(this.$el);
this._$releaseChannel = this._$el.find('#release-channel');
this._$notifyGroups = this._$el.find('#oca_updatenotification_groups_list');
this._$notifyGroups.on('change', function () {
this.$emit('input');
}.bind(this));
},
updated: function () {
OC.Settings.setupGroupsSelect(this._$notifyGroups);
this._$el.find('.icon-info').tooltip({placement: 'right'});
}
};
})(OC, OCA, OCP, t, $);

File diff suppressed because it is too large Load Diff

6
apps/updatenotification/js/vue.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -68,11 +68,10 @@ class Admin implements ISettings {
'production',
];
$currentChannel = Util::getChannel();
// Remove the currently used channel from the channels list
if(($key = array_search($currentChannel, $channels, true)) !== false) {
unset($channels[$key]);
if ($currentChannel === 'git') {
$channels[] = 'git';
}
$updateState = $this->updateChecker->getUpdateState();
$notifyGroups = json_decode($this->config->getAppValue('updatenotification', 'notify_groups', '["admin"]'), true);
@ -91,7 +90,11 @@ class Admin implements ISettings {
'updaterEnabled' => empty($updateState['updaterEnabled']) ? false : $updateState['updaterEnabled'],
'isDefaultUpdateServerURL' => $updateServerURL === $defaultUpdateServerURL,
'updateServerURL' => $updateServerURL,
'notify_groups' => implode('|', $notifyGroups),
'notifyGroups' => implode('|', $notifyGroups),
];
$params = [
'json' => json_encode($params),
];
return new TemplateResponse('updatenotification', 'admin', $params, '');

View File

@ -1,75 +1,23 @@
<?php
declare(strict_types=1);
script('updatenotification', 'admin');
style('updatenotification', 'admin');
/** @var array $_ */
/** @var bool $isNewVersionAvailable */
$isNewVersionAvailable = $_['isNewVersionAvailable'];
/** @var string $newVersionString */
$newVersionString = $_['newVersionString'];
/** @var bool $isUpdateChecked */
$isUpdateChecked = $_['isUpdateChecked'];
/** @var string $lastCheckedDate */
$lastCheckedDate = $_['lastChecked'];
/** @var array $channels */
$channels = $_['channels'];
/** @var string $currentChannel */
$currentChannel = $_['currentChannel'];
/** @var string $updateServerURL */
$updateServerURL = $_['updateServerURL'];
/** @var bool $isDefaultUpdateServerURL */
$isDefaultUpdateServerURL = $_['isDefaultUpdateServerURL'];
/**
* @copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @author Joas Schilling <coding@schilljs.com>
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*/
if (\OC::$server->getConfig()->getSystemValue('debug', false)) {
script('updatenotification', 'vue');
} else {
script('updatenotification', 'vue.min');
}
script('updatenotification', [
'components/root',
'admin',
]);
style('updatenotification', 'admin');
/** @var array $_ */
?>
<form id="oca_updatenotification_section" class="followupsection">
<p>
<?php if ($isNewVersionAvailable === true) { ?>
<strong><?php p($l->t('A new version is available: %s', [$newVersionString])); ?></strong>
<?php if ($_['updaterEnabled']) { ?>
<input type="button" id="oca_updatenotification_button" value="<?php p($l->t('Open updater')) ?>">
<?php } ?>
<?php if (!empty($_['downloadLink'])) { ?>
<a href="<?php p($_['downloadLink']); ?>" class="button<?php if ($_['updaterEnabled']) { p(' hidden'); } ?>"><?php p($l->t('Download now')) ?></a>
<?php } ?>
<?php } elseif (!$isUpdateChecked) { ?>
<?php p($l->t('The update check is not yet finished. Please refresh the page.')); ?>
<?php } else { ?>
<?php p($l->t('Your version is up to date.')); ?>
<span class="icon-info svg" title="<?php p($l->t('Checked on %s', [$lastCheckedDate])) ?>"></span>
<?php } ?>
<?php if (!$isDefaultUpdateServerURL) { ?>
<br />
<em>
<?php p($l->t('A non-default update server is in use to be checked for updates:')); ?>
<code><?php p($updateServerURL); ?></code>
</em>
<?php } ?>
</p>
<p>
<label for="release-channel"><?php p($l->t('Update channel:')) ?></label>
<select id="release-channel">
<option value="<?php p($currentChannel); ?>"><?php p($currentChannel); ?></option>
<?php foreach ($channels as $channel => $channelTitle){ ?>
<option value="<?php p($channelTitle) ?>">
<?php p($channelTitle) ?>
</option>
<?php } ?>
</select>
<span id="channel_save_msg" class="msg"></span><br />
<em><?php p($l->t('You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel.')); ?></em><br />
<em><?php p($l->t('Note that after a new release it can take some time before it shows up here. We roll out new versions spread out over time to our users and sometimes skip a version when issues are found.')); ?></em>
</p>
<p id="oca_updatenotification_groups">
<?php p($l->t('Notify members of the following groups about available updates:')); ?>
<input name="oca_updatenotification_groups_list" type="hidden" id="oca_updatenotification_groups_list" value="<?php p($_['notify_groups']) ?>" style="width: 400px"><br />
<em class="<?php if (!\in_array($currentChannel, ['daily', 'git'], true)) { p('hidden'); } ?>">
<?php p($l->t('Only notification for app updates are available.')); ?>
<?php if ($currentChannel === 'daily') { p($l->t('The selected update channel makes dedicated notifications for the server obsolete.')); } ?>
<?php if ($currentChannel === 'git') { p($l->t('The selected update channel does not support updates of the server.')); } ?>
</em>
</p>
</form>
<div id="updatenotification" data-json="<?php p($_['json']); ?>"></div>

View File

@ -65,10 +65,8 @@ class AdminTest extends TestCase {
'production',
];
$currentChannel = Util::getChannel();
// Remove the currently used channel from the channels list
if(($key = array_search($currentChannel, $channels, true)) !== false) {
unset($channels[$key]);
if ($currentChannel === 'git') {
$channels[] = 'git';
}
$this->config
@ -99,17 +97,19 @@ class AdminTest extends TestCase {
]);
$params = [
'isNewVersionAvailable' => true,
'isUpdateChecked' => true,
'lastChecked' => 'LastCheckedReturnValue',
'currentChannel' => Util::getChannel(),
'channels' => $channels,
'newVersionString' => '8.1.2',
'downloadLink' => 'https://downloads.nextcloud.org/server',
'updaterEnabled' => true,
'isDefaultUpdateServerURL' => true,
'updateServerURL' => 'https://updates.nextcloud.com/updater_server/',
'notify_groups' => 'admin',
'json' => json_encode([
'isNewVersionAvailable' => true,
'isUpdateChecked' => true,
'lastChecked' => 'LastCheckedReturnValue',
'currentChannel' => Util::getChannel(),
'channels' => $channels,
'newVersionString' => '8.1.2',
'downloadLink' => 'https://downloads.nextcloud.org/server',
'updaterEnabled' => true,
'isDefaultUpdateServerURL' => true,
'updateServerURL' => 'https://updates.nextcloud.com/updater_server/',
'notify_groups' => 'admin',
]),
];
$expected = new TemplateResponse('updatenotification', 'admin', $params, '');