Move updatenotifications to webpack with .vue file

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2018-01-30 17:06:40 +01:00
parent b12b391d7c
commit 308c7db333
No known key found for this signature in database
GPG Key ID: 7076EA9751AACDDA
12 changed files with 6488 additions and 10706 deletions

2
.gitignore vendored
View File

@ -32,6 +32,8 @@
!/apps/testing !/apps/testing
!/apps/admin_audit !/apps/admin_audit
!/apps/updatenotification !/apps/updatenotification
/apps/updatenotification/js/merged.js
/apps/updatenotification/node_modules
!/apps/theming !/apps/theming
!/apps/twofactor_backupcodes !/apps/twofactor_backupcodes
!/apps/workflowengine !/apps/workflowengine

View File

@ -0,0 +1,47 @@
app_name=notifications
project_dir=$(CURDIR)/../$(app_name)
build_dir=$(CURDIR)/build
source_dir=$(build_dir)/$(app_name)
sign_dir=$(build_dir)/sign
all: package
dev-setup: clean npm-update build-js
npm-update:
rm -rf node_modules
npm update
build-js:
npm run dev
build-js-production:
npm run build
clean:
rm -rf $(build_dir)
package: clean build-js-production
mkdir -p $(source_dir)
rsync -a \
--exclude=/build \
--exclude=/docs \
--exclude=/js-src \
--exclude=/l10n/.tx \
--exclude=/tests \
--exclude=/.git \
--exclude=/.github \
--exclude=/CONTRIBUTING.md \
--exclude=/issue_template.md \
--exclude=/README.md \
--exclude=/.gitignore \
--exclude=/.scrutinizer.yml \
--exclude=/.travis.yml \
--exclude=/.drone.yml \
--exclude=/node_modules \
--exclude=/npm-debug.log \
--exclude=/package.json \
--exclude=/package-lock.json \
--exclude=/Makefile \
$(project_dir)/ $(source_dir)

View File

@ -7,12 +7,12 @@
* later. See the COPYING file. * later. See the COPYING file.
*/ */
(function(OC, OCA, Vue, $) { /* global $, define */
define(function (require) {
"use strict"; "use strict";
OCA.UpdateNotification = OCA.UpdateNotification || {}; return {
OCA.UpdateNotification.App = {
/** @type {number|null} */ /** @type {number|null} */
@ -26,7 +26,8 @@
*/ */
initialise: function() { initialise: function() {
var data = JSON.parse($('#updatenotification').attr('data-json')); var data = JSON.parse($('#updatenotification').attr('data-json'));
this.vm = new Vue(OCA.UpdateNotification.Components.Root); var Vue = require('vue');
this.vm = new Vue(require('./components/root.vue'));
this.vm.newVersionString = data.newVersionString; this.vm.newVersionString = data.newVersionString;
this.vm.lastCheckedDate = data.lastChecked; this.vm.lastCheckedDate = data.lastChecked;
@ -41,8 +42,4 @@
this.vm.isDefaultUpdateServerURL = data.isDefaultUpdateServerURL; this.vm.isDefaultUpdateServerURL = data.isDefaultUpdateServerURL;
} }
}; };
})(OC, OCA, Vue, $);
$(document).ready(function () {
OCA.UpdateNotification.App.initialise();
}); });

View File

@ -0,0 +1,188 @@
<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="l_open_updater">
<a v-if="downloadLink" :href="downloadLink" class="button" :class="{ hidden: !updaterEnabled }">{{l_download_now}}</a>
</template>
<template v-else-if="!isUpdateChecked">{{l_check_in_progress}}</template>
<template v-else>
{{l_up_to_date}}
<span class="icon-info svg" :title="lastCheckedOnString"></span>
</template>
<template v-if="!isDefaultUpdateServerURL">
<br />
<em>{{l_non_default_updater}} <code>{{updateServerURL}}</code></em>
</template>
</p>
<p>
<label for="release-channel">{{l_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>{{l_update_channel_newer}}</em><br />
<em>{{l_update_channel_delay}}</em>
</p>
<p id="oca_updatenotification_groups">
{{l_notify_groups}}
<input name="oca_updatenotification_groups_list" type="hidden" id="oca_updatenotification_groups_list" @change="saveNotifyGroups" :value="notifyGroups" style="width: 400px"><br />
<em v-if="currentChannel === 'daily' || currentChannel === 'git'">{{l_only_app_updates}}</em>
<em v-if="currentChannel === 'daily'">{{l_update_channel_daily}}</em>
<em v-if="currentChannel === 'git'">{{l_update_channel_git}}</em>
</p>
</div>
</template>
<script>
export default {
name: "root",
el: '#updatenotification',
data: function () {
return {
newVersionString: '',
lastCheckedDate: '',
isUpdateChecked: false,
updaterEnabled: true,
downloadLink: '',
isNewVersionAvailable: false,
updateServerURL: '',
currentChannel: '',
channels: [],
notifyGroups: '',
isDefaultUpdateServerURL: true
};
},
_$el: null,
_$releaseChannel: null,
_$notifyGroups: null,
computed: {
l_check_in_progress: function() {
return t('updatenotification', 'The update check is not yet finished. Please refresh the page.');
},
l_download_now: function() {
return t('updatenotification', 'Download now');
},
l_non_default_updater: function() {
return t('updatenotification', 'A non-default update server is in use to be checked for updates:');
},
l_notify_groups: function() {
return t('updatenotification', 'Notify members of the following groups about available updates:');
},
l_only_app_updates: function() {
return t('updatenotification', 'Only notification for app updates are available.');
},
l_open_updater: function() {
return t('updatenotification', 'Open updater');
},
l_up_to_date: function() {
return t('updatenotification', 'Your version is up to date.');
},
l_update_channel: function() {
return t('updatenotification', 'Update channel:');
},
l_update_channel_daily: function() {
return t('updatenotification', 'The selected update channel makes dedicated notifications for the server obsolete.');
},
l_update_channel_git: function() {
return t('updatenotification', 'The selected update channel does not support updates of the server.');
},
l_update_channel_newer: function() {
return t('updatenotification', 'You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel.');
},
l_update_channel_delay: function() {
return 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.');
},
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'});
}
}
</script>

View File

@ -0,0 +1,31 @@
/**
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global define, $ */
define(function(require) {
'use strict';
var App = require('./app');
$(function() {
App.initialise();
});
});

View File

@ -0,0 +1,55 @@
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './js-src/init.js',
output: {
path: path.resolve(__dirname, '../js'),
publicPath: '/',
filename: 'merged.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
},
esModule: false
// other vue-loader options go here
}
}
]
},
resolve: {
alias: {
'vue': process.env.NODE_ENV === 'production' ? 'vue/dist/vue.min.js' : 'vue/dist/vue.js'
}
},
performance: {
hints: false
},
devtool: '#eval-source-map'
};
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map';
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
]);
}

View File

@ -1,165 +0,0 @@
/**
* @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

File diff suppressed because one or more lines are too long

6122
apps/updatenotification/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
{
"name": "notifications",
"version": "2.2.0",
"description": "This app provides a backend and frontend for the notification API available in Nextcloud.",
"main": "init.js",
"directories": {
"lib": "lib",
"test": "tests"
},
"scripts": {
"dev": "cross-env NODE_ENV=development webpack --progress --hot --config js-src/webpack.config.js --watch",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules --config js-src/webpack.config.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/nextcloud/notifications.git"
},
"author": "Joas Schilling",
"license": "AGPL-3.0",
"bugs": {
"url": "https://github.com/nextcloud/notifications/issues"
},
"homepage": "https://github.com/nextcloud/notifications#readme",
"dependencies": {
"vue": "^2.5.13"
},
"devDependencies": {
"cross-env": "^5.1.3",
"css-loader": "^0.28.8",
"file-loader": "^1.1.6",
"vue-loader": "^13.7.0",
"vue-template-compiler": "^2.5.13",
"webpack": "^3.6.0"
}
}

View File

@ -8,15 +8,7 @@ declare(strict_types=1);
* This file is licensed under the Affero General Public License version 3 or * This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file. * later. See the COPYING file.
*/ */
if (\OC::$server->getConfig()->getSystemValue('debug', false)) { script('updatenotification', 'merged');
script('updatenotification', 'vue');
} else {
script('updatenotification', 'vue.min');
}
script('updatenotification', [
'components/root',
'admin',
]);
style('updatenotification', 'admin'); style('updatenotification', 'admin');
/** @var array $_ */ /** @var array $_ */
?> ?>