summaryrefslogtreecommitdiffstats
path: root/apps/settings
diff options
context:
space:
mode:
authorCarl Schwan <carl@carlschwan.eu>2022-02-10 23:56:05 +0100
committerCarl Schwan <carl@carlschwan.eu>2022-02-17 17:52:03 +0100
commit7c8a901b841878c7d63940baa551f5982958874e (patch)
treefaf0c431d93cad5f294c4b09e14d3c1645f1bb5f /apps/settings
parentf5d1365bbd32fdcf2084eb2ad727a574529898d0 (diff)
downloadnextcloud-server-7c8a901b841878c7d63940baa551f5982958874e.tar.gz
nextcloud-server-7c8a901b841878c7d63940baa551f5982958874e.zip
Cleanup admin settings js files
* Move admin.js to webpack, so that this use the bundled jquery files instead of the deprecated window.$ Also fixing formatting * Remove log.js that seems to be from a time where logreader was bundled with server and I couldn't find an usage of it anymore * Fix recent regression in rebuild navigation function (now not depending on jquery anymore and bundled by webpack). Signed-off-by: Carl Schwan <carl@carlschwan.eu>
Diffstat (limited to 'apps/settings')
-rw-r--r--apps/settings/css/settings.scss15
-rw-r--r--apps/settings/js/admin.js333
-rw-r--r--apps/settings/js/apps.js113
-rw-r--r--apps/settings/js/log.js85
-rw-r--r--apps/settings/lib/Controller/AppSettingsController.php1
-rw-r--r--apps/settings/src/admin.js335
-rw-r--r--apps/settings/src/mixins/AppManagement.js27
-rw-r--r--apps/settings/src/service/rebuild-navigation.js130
-rw-r--r--apps/settings/src/store/apps.js16
-rw-r--r--apps/settings/templates/settings/frame.php3
10 files changed, 506 insertions, 552 deletions
diff --git a/apps/settings/css/settings.scss b/apps/settings/css/settings.scss
index 7b261d67181..d9073b9a138 100644
--- a/apps/settings/css/settings.scss
+++ b/apps/settings/css/settings.scss
@@ -1755,3 +1755,18 @@ doesnotexist:-o-prefocus, .strengthify-wrapper {
}
}
}
+
+.animated {
+ animation: blink-animation 1s steps(5, start) 4;
+}
+
+@keyframes blink-animation {
+ to {
+ opacity: 0.6;
+ }
+}
+@-webkit-keyframes blink-animation {
+ to {
+ opacity: 1;
+ }
+}
diff --git a/apps/settings/js/admin.js b/apps/settings/js/admin.js
deleted file mode 100644
index 20d9843fe14..00000000000
--- a/apps/settings/js/admin.js
+++ /dev/null
@@ -1,333 +0,0 @@
-window.addEventListener('DOMContentLoaded', function(){
- $('#excludedGroups,#linksExcludedGroups').each(function (index, element) {
- OC.Settings.setupGroupsSelect($(element));
- $(element).change(function(ev) {
- var groups = ev.val || [];
- groups = JSON.stringify(groups);
- OCP.AppConfig.setValue('core', $(this).attr('name'), groups);
- });
- });
-
-
- $('#loglevel').change(function(){
- $.post(OC.generateUrl('/settings/admin/log/level'), {level: $(this).val()},function(){
- OC.Log.reload();
- } );
- });
-
- $('#backgroundjobs span.crondate').tooltip({placement: 'top'});
-
- $('#backgroundjobs input').change(function(){
- if($(this).is(':checked')){
- var mode = $(this).val();
- if (mode === 'ajax' || mode === 'webcron' || mode === 'cron') {
- OCP.AppConfig.setValue('core', 'backgroundjobs_mode', mode, {
- success: function() {
- // clear cron errors on background job mode change
- OCP.AppConfig.deleteKey('core', 'cronErrors');
- }
- });
- }
- }
- });
-
- $('#shareAPIEnabled').change(function() {
- $('#shareAPI p:not(#enable)').toggleClass('hidden', !this.checked);
- });
-
- $('#enableEncryption').change(function() {
- $('#encryptionAPI div#EncryptionWarning').toggleClass('hidden');
- });
-
- $('#reallyEnableEncryption').click(function() {
- $('#encryptionAPI div#EncryptionWarning').toggleClass('hidden');
- $('#encryptionAPI div#EncryptionSettingsArea').toggleClass('hidden');
- OCP.AppConfig.setValue('core', 'encryption_enabled', 'yes');
- $('#enableEncryption').attr('disabled', 'disabled');
- });
-
- $('#startmigration').click(function(event){
- $(window).on('beforeunload.encryption', function(e) {
- return t('settings', 'Migration in progress. Please wait until the migration is finished');
- });
- event.preventDefault();
- $('#startmigration').prop('disabled', true);
- OC.msg.startAction('#startmigration_msg', t('settings', 'Migration started …'));
- $.post(OC.generateUrl('/settings/admin/startmigration'), '', function(data){
- OC.msg.finishedAction('#startmigration_msg', data);
- if (data['status'] === 'success') {
- $('#encryptionAPI div#selectEncryptionModules').toggleClass('hidden');
- $('#encryptionAPI div#migrationWarning').toggleClass('hidden');
- } else {
- $('#startmigration').prop('disabled', false);
- }
- $(window).off('beforeunload.encryption');
-
- });
- });
-
- $('#shareapiExpireAfterNDays').on('input', function() {
- this.value = this.value.replace(/\D/g, '');
- });
-
- $('#shareAPI input:not(.noJSAutoUpdate)').change(function() {
- var value = $(this).val();
- if ($(this).attr('type') === 'checkbox') {
- if (this.checked) {
- value = 'yes';
- } else {
- value = 'no';
- }
- }
- OCP.AppConfig.setValue('core', $(this).attr('name'), value);
- });
-
- $('#shareapiDefaultExpireDate').change(function() {
- $("#setDefaultExpireDate").toggleClass('hidden', !this.checked);
- });
-
- $('#shareapiDefaultInternalExpireDate').change(function() {
- $("#setDefaultInternalExpireDate").toggleClass('hidden', !this.checked);
- });
-
- $('#shareapiDefaultRemoteExpireDate').change(function() {
- $("#setDefaultRemoteExpireDate").toggleClass('hidden', !this.checked);
- });
-
- $('#publicShareDisclaimer').change(function() {
- $("#publicShareDisclaimerText").toggleClass('hidden', !this.checked);
- if(!this.checked) {
- savePublicShareDisclaimerText('');
- }
- });
-
- $('#shareApiDefaultPermissionsSection input').change(function(ev) {
- var $el = $('#shareApiDefaultPermissions');
- var $target = $(ev.target);
-
- var value = $el.val();
- if ($target.is(':checked')) {
- value = value | $target.val();
- } else {
- value = value & ~$target.val();
- }
-
- // always set read permission
- value |= OC.PERMISSION_READ;
-
- // this will trigger the field's change event and will save it
- $el.val(value).change();
-
- ev.preventDefault();
-
- return false;
- });
-
- var savePublicShareDisclaimerText = _.debounce(function(value) {
- var options = {
- success: function() {
- OC.msg.finishedSuccess('#publicShareDisclaimerStatus', t('settings', 'Saved'));
- },
- error: function() {
- OC.msg.finishedError('#publicShareDisclaimerStatus', t('settings', 'Not saved'));
- }
- };
-
- OC.msg.startSaving('#publicShareDisclaimerStatus');
- if (_.isString(value) && value !== '') {
- OCP.AppConfig.setValue('core', 'shareapi_public_link_disclaimertext', value, options);
- } else {
- $('#publicShareDisclaimerText').val('');
- OCP.AppConfig.deleteKey('core', 'shareapi_public_link_disclaimertext', options);
- }
- }, 500);
-
- $('#publicShareDisclaimerText').on('change, keyup', function() {
- savePublicShareDisclaimerText(this.value);
- });
-
- $('#shareapi_allow_share_dialog_user_enumeration').on('change', function() {
- $('#shareapi_restrict_user_enumeration_to_group_setting').toggleClass('hidden', !this.checked);
- $('#shareapi_restrict_user_enumeration_to_phone_setting').toggleClass('hidden', !this.checked);
- $('#shareapi_restrict_user_enumeration_combinewarning_setting').toggleClass('hidden', !this.checked);
- })
-
- $('#allowLinks').change(function() {
- $("#publicLinkSettings").toggleClass('hidden', !this.checked);
- $('#setDefaultExpireDate').toggleClass('hidden', !(this.checked && $('#shareapiDefaultExpireDate')[0].checked));
- });
-
- $('#mail_smtpauth').change(function() {
- if (!this.checked) {
- $('#mail_credentials').addClass('hidden');
- } else {
- $('#mail_credentials').removeClass('hidden');
- }
- });
-
- $('#mail_smtpmode').change(function() {
- if ($(this).val() !== 'smtp') {
- $('#setting_smtpauth').addClass('hidden');
- $('#setting_smtphost').addClass('hidden');
- $('#mail_smtpsecure_label').addClass('hidden');
- $('#mail_smtpsecure').addClass('hidden');
- $('#mail_credentials').addClass('hidden');
- $('#mail_sendmailmode_label, #mail_sendmailmode').removeClass('hidden');
- } else {
- $('#setting_smtpauth').removeClass('hidden');
- $('#setting_smtphost').removeClass('hidden');
- $('#mail_smtpsecure_label').removeClass('hidden');
- $('#mail_smtpsecure').removeClass('hidden');
- if ($('#mail_smtpauth').is(':checked')) {
- $('#mail_credentials').removeClass('hidden');
- }
- $('#mail_sendmailmode_label, #mail_sendmailmode').addClass('hidden');
- }
- });
-
- var changeEmailSettings = function() {
- if (OC.PasswordConfirmation.requiresPasswordConfirmation()) {
- OC.PasswordConfirmation.requirePasswordConfirmation(changeEmailSettings);
- return;
- }
-
- OC.msg.startSaving('#mail_settings_msg');
- $.ajax({
- url: OC.generateUrl('/settings/admin/mailsettings'),
- type: 'POST',
- data: $('#mail_general_settings_form').serialize(),
- success: function(){
- OC.msg.finishedSuccess('#mail_settings_msg', t('settings', 'Saved'));
- },
- error: function(xhr){
- OC.msg.finishedError('#mail_settings_msg', xhr.responseJSON);
- }
- });
- };
-
- var toggleEmailCredentials = function() {
- if (OC.PasswordConfirmation.requiresPasswordConfirmation()) {
- OC.PasswordConfirmation.requirePasswordConfirmation(toggleEmailCredentials);
- return;
- }
-
- OC.msg.startSaving('#mail_settings_msg');
- $.ajax({
- url: OC.generateUrl('/settings/admin/mailsettings/credentials'),
- type: 'POST',
- data: $('#mail_credentials_settings').serialize(),
- success: function(){
- OC.msg.finishedSuccess('#mail_settings_msg', t('settings', 'Saved'));
- },
- error: function(xhr){
- OC.msg.finishedError('#mail_settings_msg', xhr.responseJSON);
- }
- });
- };
-
- $('#mail_general_settings_form').change(changeEmailSettings);
- $('#mail_credentials_settings_submit').click(toggleEmailCredentials);
- $('#mail_smtppassword').click(function() {
- if (this.type === 'text' && this.value === '********') {
- this.type = 'password';
- this.value = '';
- }
- });
-
- $('#sendtestemail').click(function(event){
- event.preventDefault();
- OC.msg.startAction('#sendtestmail_msg', t('settings', 'Sending…'));
-
- $.ajax({
- url: OC.generateUrl('/settings/admin/mailtest'),
- type: 'POST',
- success: function(){
- OC.msg.finishedSuccess('#sendtestmail_msg', t('settings', 'Email sent'));
- },
- error: function(xhr){
- OC.msg.finishedError('#sendtestmail_msg', xhr.responseJSON);
- }
- });
- });
-
- $('#allowGroupSharing').change(function() {
- $('#allowGroupSharing').toggleClass('hidden', !this.checked);
- });
-
- $('#shareapiExcludeGroups').change(function() {
- $("#selectExcludedGroups").toggleClass('hidden', !this.checked);
- });
-
- var setupChecks = function () {
- // run setup checks then gather error messages
- $.when(
- OC.SetupChecks.checkWebDAV(),
- OC.SetupChecks.checkWellKnownUrl('GET', '/.well-known/webfinger', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true, [200, 404], true),
- OC.SetupChecks.checkWellKnownUrl('GET', '/.well-known/nodeinfo', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true, [200, 404], true),
- OC.SetupChecks.checkWellKnownUrl('PROPFIND', '/.well-known/caldav', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true),
- OC.SetupChecks.checkWellKnownUrl('PROPFIND', '/.well-known/carddav', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true),
- OC.SetupChecks.checkProviderUrl(OC.getRootPath() + '/ocm-provider/', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true),
- OC.SetupChecks.checkProviderUrl(OC.getRootPath() + '/ocs-provider/', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true),
- OC.SetupChecks.checkSetup(),
- OC.SetupChecks.checkGeneric(),
- OC.SetupChecks.checkWOFF2Loading(OC.filePath('core', '', 'fonts/NotoSans-Regular-latin.woff2'), OC.theme.docPlaceholderUrl),
- OC.SetupChecks.checkDataProtected()
- ).then(function (check1, check2, check3, check4, check5, check6, check7, check8, check9, check10, check11) {
- var messages = [].concat(check1, check2, check3, check4, check5, check6, check7, check8, check9, check10, check11);
- var $el = $('#postsetupchecks');
- $('#security-warning-state-loading').addClass('hidden');
-
- var hasMessages = false;
- var $errorsEl = $el.find('.errors');
- var $warningsEl = $el.find('.warnings');
- var $infoEl = $el.find('.info');
-
- for (var i = 0; i < messages.length; i++) {
- switch (messages[i].type) {
- case OC.SetupChecks.MESSAGE_TYPE_INFO:
- $infoEl.append('<li>' + messages[i].msg + '</li>');
- break;
- case OC.SetupChecks.MESSAGE_TYPE_WARNING:
- $warningsEl.append('<li>' + messages[i].msg + '</li>');
- break;
- case OC.SetupChecks.MESSAGE_TYPE_ERROR:
- default:
- $errorsEl.append('<li>' + messages[i].msg + '</li>');
- }
- }
-
- if ($errorsEl.find('li').length > 0) {
- $errorsEl.removeClass('hidden');
- hasMessages = true;
- }
- if ($warningsEl.find('li').length > 0) {
- $warningsEl.removeClass('hidden');
- hasMessages = true;
- }
- if ($infoEl.find('li').length > 0) {
- $infoEl.removeClass('hidden');
- hasMessages = true;
- }
-
- if (hasMessages) {
- $('#postsetupchecks-hint').removeClass('hidden');
- if ($errorsEl.find('li').length > 0) {
- $('#security-warning-state-failure').removeClass('hidden');
- } else {
- $('#security-warning-state-warning').removeClass('hidden');
- }
- } else {
- var securityWarning = $('#security-warning');
- if (securityWarning.children('ul').children().length === 0) {
- $('#security-warning-state-ok').removeClass('hidden');
- } else {
- $('#security-warning-state-failure').removeClass('hidden');
- }
- }
- });
- };
-
- if (document.getElementById('security-warning') !== null) {
- setupChecks();
- }
-});
diff --git a/apps/settings/js/apps.js b/apps/settings/js/apps.js
deleted file mode 100644
index a3c1650e445..00000000000
--- a/apps/settings/js/apps.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/* global Handlebars */
-OC.Settings = OC.Settings || {};
-OC.Settings.Apps = OC.Settings.Apps || {
- rebuildNavigation: function() {
- $.getJSON(OC.linkToOCS('core/navigation', 2) + 'apps?format=json').done(function(response){
- if(response.ocs.meta.status === 'ok') {
- var addedApps = {};
- var navEntries = response.ocs.data;
- var container = $('#navigation #apps ul');
-
- // remove disabled apps
- for (var i = 0; i < navEntries.length; i++) {
- var entry = navEntries[i];
- if(container.children('li[data-id="' + entry.id + '"]').length === 0) {
- addedApps[entry.id] = true;
- }
- }
- container.children('li[data-id]').each(function (index, el) {
- var id = $(el).data('id');
- // remove all apps that are not in the correct order
- if (!navEntries[index] || (navEntries[index] && navEntries[index].id !== $(el).data('id'))) {
- $(el).remove();
- $('#appmenu li[data-id='+id+']').remove();
- }
- });
-
- var previousEntry = {};
- // add enabled apps to #navigation and #appmenu
- for (var i = 0; i < navEntries.length; i++) {
- var entry = navEntries[i];
- if (container.children('li[data-id="' + entry.id + '"]').length === 0) {
- var li = $('<li></li>');
- li.attr('data-id', entry.id);
- var img = '<svg width="20" height="20" viewBox="0 0 20 20" alt="">';
- if (OCA.Theming && OCA.Theming.inverted) {
- img += '<defs><filter id="invert"><feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" /></filter></defs>';
- img += '<image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" xlink:href="' + entry.icon + '" class="app-icon" />';
- } else {
- img += '<image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet" xlink:href="' + entry.icon + '" class="app-icon" />';
- }
- img += '</svg>';
- var a = $('<a></a>').attr('href', entry.href);
- var filename = $('<span></span>');
- var loading = $('<div class="icon-loading-dark"></div>').css('display', 'none');
- filename.text(entry.name);
- a.prepend(loading);
- a.prepend(filename);
- a.prepend(img);
- li.append(a);
-
- // add app icon to the navigation
- var previousElement = $('#navigation li[data-id=' + previousEntry.id + ']');
- if (previousElement.length > 0) {
- previousElement.after(li);
- } else {
- $('#navigation #apps').prepend(li);
- }
-
- // draw attention to the newly added app entry
- // by flashing twice the more apps menu
- if(addedApps[entry.id]) {
- $('#header #more-apps')
- .animate({opacity: 0.5})
- .animate({opacity: 1})
- .animate({opacity: 0.5})
- .animate({opacity: 1});
- }
- }
-
- if ($('#appmenu').children('li[data-id="' + entry.id + '"]').length === 0) {
- var li = $('<li></li>');
- li.attr('data-id', entry.id);
- // Generating svg embedded image (see layout.user.php)
- var img = '<svg width="20" height="20" viewBox="0 0 20 20" alt="">';
- if (OCA.Theming && OCA.Theming.inverted) {
- img += '<defs><filter id="invert"><feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" /></filter></defs>';
- img += '<image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" xlink:href="' + entry.icon + '" class="app-icon" />';
- } else {
- img += '<image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet" xlink:href="' + entry.icon + '" class="app-icon" />';
- }
- img += '</svg>';
- var a = $('<a></a>').attr('href', entry.href);
- var filename = $('<span></span>');
- var loading = $('<div class="icon-loading-dark"></div>').css('display', 'none');
- filename.text(entry.name);
- a.prepend(loading);
- a.prepend(filename);
- a.prepend(img);
- li.append(a);
-
- // add app icon to the navigation
- var previousElement = $('#appmenu li[data-id=' + previousEntry.id + ']');
- if (previousElement.length > 0) {
- previousElement.after(li);
- } else {
- $('#appmenu').prepend(li);
- }
-
- if(addedApps[entry.id]) {
- li.animate({opacity: 0.5})
- .animate({opacity: 1})
- .animate({opacity: 0.5})
- .animate({opacity: 1});
- }
- }
- previousEntry = entry;
- }
-
- $(window).trigger('resize');
- }
- });
- }
-};
diff --git a/apps/settings/js/log.js b/apps/settings/js/log.js
deleted file mode 100644
index 45cc9321c24..00000000000
--- a/apps/settings/js/log.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * Copyright (c) 2012, Robin Appelman <icewind1991@gmail.com>
- * Copyright (c) 2013, Morris Jobke <morris.jobke@gmail.com>
- * This file is licensed under the Affero General Public License version 3 or later.
- * See the COPYING-README file.
- */
-
-/* global formatDate */
-
-OC.Log = {
- reload: function (count) {
- if (!count) {
- count = OC.Log.loaded;
- }
- OC.Log.loaded = 0;
- $('#log tbody').empty();
- OC.Log.getMore(count);
- },
- levels: ['Debug', 'Info', 'Warning', 'Error', 'Fatal'],
- loaded: 3,//are initially loaded
- getMore: function (count) {
- count = count || 10;
- $.get(OC.generateUrl('/settings/admin/log/entries'), {offset: OC.Log.loaded, count: count}, function (result) {
- OC.Log.addEntries(result.data);
- if (!result.remain) {
- $('#moreLog').hide();
- }
- $('#lessLog').show();
- });
- },
- showLess: function (count) {
- count = count || 10;
- //calculate remaining items - at least 3
- OC.Log.loaded = Math.max(3, OC.Log.loaded - count);
- $('#moreLog').show();
- // remove all non-remaining items
- $('#log tr').slice(OC.Log.loaded).remove();
- if (OC.Log.loaded <= 3) {
- $('#lessLog').hide();
- }
- },
- addEntries: function (entries) {
- for (var i = 0; i < entries.length; i++) {
- var entry = entries[i];
- var row = $('<tr/>');
- var levelTd = $('<td/>');
- levelTd.text(OC.Log.levels[entry.level]);
- row.append(levelTd);
-
- var appTd = $('<td/>');
- appTd.text(entry.app);
- row.append(appTd);
-
- var messageTd = $('<td/>');
- messageTd.addClass('log-message');
- messageTd.text(entry.message);
- row.append(messageTd);
-
- var timeTd = $('<td/>');
- timeTd.addClass('date');
- if (isNaN(entry.time)) {
- timeTd.text(entry.time);
- } else {
- timeTd.text(formatDate(entry.time * 1000));
- }
- row.append(timeTd);
-
- var userTd = $('<td/>');
- userTd.text(entry.user);
- row.append(userTd);
-
- $('#log').append(row);
- }
- OC.Log.loaded += entries.length;
- }
-};
-
-window.addEventListener('DOMContentLoaded', function () {
- $('#moreLog').click(function () {
- OC.Log.getMore();
- });
- $('#lessLog').click(function () {
- OC.Log.showLess();
- });
-});
diff --git a/apps/settings/lib/Controller/AppSettingsController.php b/apps/settings/lib/Controller/AppSettingsController.php
index 8dbe9fb2f07..77f807943cd 100644
--- a/apps/settings/lib/Controller/AppSettingsController.php
+++ b/apps/settings/lib/Controller/AppSettingsController.php
@@ -129,7 +129,6 @@ class AppSettingsController extends Controller {
* @return TemplateResponse
*/
public function viewApps(): TemplateResponse {
- \OC_Util::addScript('settings', 'apps');
$params = [];
$params['appstoreEnabled'] = $this->config->getSystemValueBool('appstoreenabled', true);
$params['updateCount'] = count($this->getAppsWithUpdates());
diff --git a/apps/settings/src/admin.js b/apps/settings/src/admin.js
new file mode 100644
index 00000000000..24f95ccb2a6
--- /dev/null
+++ b/apps/settings/src/admin.js
@@ -0,0 +1,335 @@
+import $ from 'jquery'
+import 'jquery-ui-dist/jquery-ui'
+
+window.addEventListener('DOMContentLoaded', () => {
+ $('#excludedGroups,#linksExcludedGroups').each((index, element) => {
+ OC.Settings.setupGroupsSelect($(element))
+ $(element).change((ev) => {
+ let groups = ev.val || []
+ groups = JSON.stringify(groups)
+ OCP.AppConfig.setValue('core', $(this).attr('name'), groups)
+ })
+ })
+
+ $('#loglevel').change(() => {
+ $.post(OC.generateUrl('/settings/admin/log/level'), { level: $(this).val() }, () => {
+ OC.Log.reload()
+ })
+ })
+
+ $('#backgroundjobs span.crondate').tooltip({ placement: 'top' })
+
+ $('#backgroundjobs input').change(() => {
+ if ($(this).is(':checked')) {
+ const mode = $(this).val()
+ if (mode === 'ajax' || mode === 'webcron' || mode === 'cron') {
+ OCP.AppConfig.setValue('core', 'backgroundjobs_mode', mode, {
+ success: () => {
+ // clear cron errors on background job mode change
+ OCP.AppConfig.deleteKey('core', 'cronErrors')
+ }
+ })
+ }
+ }
+ })
+
+ $('#shareAPIEnabled').change(() => {
+ $('#shareAPI p:not(#enable)').toggleClass('hidden', !this.checked)
+ })
+
+ $('#enableEncryption').change(() => {
+ $('#encryptionAPI div#EncryptionWarning').toggleClass('hidden')
+ })
+
+ $('#reallyEnableEncryption').click(() => {
+ $('#encryptionAPI div#EncryptionWarning').toggleClass('hidden')
+ $('#encryptionAPI div#EncryptionSettingsArea').toggleClass('hidden')
+ OCP.AppConfig.setValue('core', 'encryption_enabled', 'yes')
+ $('#enableEncryption').attr('disabled', 'disabled')
+ })
+
+ $('#startmigration').click((event) => {
+ $(window).on('beforeunload.encryption', (e) => {
+ return t('settings', 'Migration in progress. Please wait until the migration is finished')
+ })
+ event.preventDefault()
+ $('#startmigration').prop('disabled', true)
+ OC.msg.startAction('#startmigration_msg', t('settings', 'Migration started …'))
+ $.post(OC.generateUrl('/settings/admin/startmigration'), '', function(data) {
+ OC.msg.finishedAction('#startmigration_msg', data)
+ if (data.status === 'success') {
+ $('#encryptionAPI div#selectEncryptionModules').toggleClass('hidden')
+ $('#encryptionAPI div#migrationWarning').toggleClass('hidden')
+ } else {
+ $('#startmigration').prop('disabled', false)
+ }
+ $(window).off('beforeunload.encryption')
+
+ })
+ })
+
+ $('#shareapiExpireAfterNDays').on('input', function() {
+ this.value = this.value.replace(/\D/g, '')
+ })
+
+ $('#shareAPI input:not(.noJSAutoUpdate)').change(function() {
+ let value = $(this).val()
+ if ($(this).attr('type') === 'checkbox') {
+ if (this.checked) {
+ value = 'yes'
+ } else {
+ value = 'no'
+ }
+ }
+ OCP.AppConfig.setValue('core', $(this).attr('name'), value)
+ })
+
+ $('#shareapiDefaultExpireDate').change(function() {
+ $('setDefaultExpireDate').toggleClass('hidden', !this.checked)
+ })
+
+ $('#shareapiDefaultInternalExpireDate').change(function() {
+ $('#setDefaultInternalExpireDate').toggleClass('hidden', !this.checked)
+ })
+
+ $('#shareapiDefaultRemoteExpireDate').change(function() {
+ $('#setDefaultRemoteExpireDate').toggleClass('hidden', !this.checked)
+ })
+
+ $('#publicShareDisclaimer').change(function() {
+ $('#publicShareDisclaimerText').toggleClass('hidden', !this.checked)
+ if (!this.checked) {
+ savePublicShareDisclaimerText('')
+ }
+ })
+
+ $('#shareApiDefaultPermissionsSection input').change(function(ev) {
+ const $el = $('#shareApiDefaultPermissions')
+ const $target = $(ev.target)
+
+ let value = $el.val()
+ if ($target.is(':checked')) {
+ value = value | $target.val()
+ } else {
+ value = value & ~$target.val()
+ }
+
+ // always set read permission
+ value |= OC.PERMISSION_READ
+
+ // this will trigger the field's change event and will save it
+ $el.val(value).change()
+
+ ev.preventDefault()
+
+ return false
+ })
+
+ const savePublicShareDisclaimerText = _.debounce(function(value) {
+ const options = {
+ success: () => {
+ OC.msg.finishedSuccess('#publicShareDisclaimerStatus', t('settings', 'Saved'))
+ },
+ error: () => {
+ OC.msg.finishedError('#publicShareDisclaimerStatus', t('settings', 'Not saved'))
+ }
+ }
+
+ OC.msg.startSaving('#publicShareDisclaimerStatus')
+ if (_.isString(value) && value !== '') {
+ OCP.AppConfig.setValue('core', 'shareapi_public_link_disclaimertext', value, options)
+ } else {
+ $('#publicShareDisclaimerText').val('')
+ OCP.AppConfig.deleteKey('core', 'shareapi_public_link_disclaimertext', options)
+ }
+ }, 500)
+
+ $('#publicShareDisclaimerText').on('change, keyup', function() {
+ savePublicShareDisclaimerText(this.value)
+ })
+
+ $('#shareapi_allow_share_dialog_user_enumeration').on('change', function() {
+ $('#shareapi_restrict_user_enumeration_to_group_setting').toggleClass('hidden', !this.checked)
+ $('#shareapi_restrict_user_enumeration_to_phone_setting').toggleClass('hidden', !this.checked)
+ $('#shareapi_restrict_user_enumeration_combinewarning_setting').toggleClass('hidden', !this.checked)
+ })
+
+ $('#allowLinks').change(function() {
+ $('#publicLinkSettings').toggleClass('hidden', !this.checked)
+ $('#setDefaultExpireDate').toggleClass('hidden', !(this.checked && $('#shareapiDefaultExpireDate')[0].checked))
+ })
+
+ $('#mail_smtpauth').change(function() {
+ if (!this.checked) {
+ $('#mail_credentials').addClass('hidden')
+ } else {
+ $('#mail_credentials').removeClass('hidden')
+ }
+ })
+
+ $('#mail_smtpmode').change(function() {
+ if ($(this).val() !== 'smtp') {
+ $('#setting_smtpauth').addClass('hidden')
+ $('#setting_smtphost').addClass('hidden')
+ $('#mail_smtpsecure_label').addClass('hidden')
+ $('#mail_smtpsecure').addClass('hidden')
+ $('#mail_credentials').addClass('hidden')
+ $('#mail_sendmailmode_label, #mail_sendmailmode').removeClass('hidden')
+ } else {
+ $('#setting_smtpauth').removeClass('hidden')
+ $('#setting_smtphost').removeClass('hidden')
+ $('#mail_smtpsecure_label').removeClass('hidden')
+ $('#mail_smtpsecure').removeClass('hidden')
+ if ($('#mail_smtpauth').is(':checked')) {
+ $('#mail_credentials').removeClass('hidden')
+ }
+ $('#mail_sendmailmode_label, #mail_sendmailmode').addClass('hidden')
+ }
+ })
+
+ const changeEmailSettings = function() {
+ if (OC.PasswordConfirmation.requiresPasswordConfirmation()) {
+ OC.PasswordConfirmation.requirePasswordConfirmation(changeEmailSettings)
+ return
+ }
+
+ OC.msg.startSaving('#mail_settings_msg')
+ $.ajax({
+ url: OC.generateUrl('/settings/admin/mailsettings'),
+ type: 'POST',
+ data: $('#mail_general_settings_form').serialize(),
+ success: () => {
+ OC.msg.finishedSuccess('#mail_settings_msg', t('settings', 'Saved'))
+ },
+ error: (xhr) => {
+ OC.msg.finishedError('#mail_settings_msg', xhr.responseJSON)
+ }
+ })
+ }
+
+ const toggleEmailCredentials = function() {
+ if (OC.PasswordConfirmation.requiresPasswordConfirmation()) {
+ OC.PasswordConfirmation.requirePasswordConfirmation(toggleEmailCredentials)
+ return
+ }
+
+ OC.msg.startSaving('#mail_settings_msg')
+ $.ajax({
+ url: OC.generateUrl('/settings/admin/mailsettings/credentials'),
+ type: 'POST',
+ data: $('#mail_credentials_settings').serialize(),
+ success: () => {
+ OC.msg.finishedSuccess('#mail_settings_msg', t('settings', 'Saved'))
+ },
+ error: (xhr) => {
+ OC.msg.finishedError('#mail_settings_msg', xhr.responseJSON)
+ }
+ })
+ }
+
+ $('#mail_general_settings_form').change(changeEmailSettings)
+ $('#mail_credentials_settings_submit').click(toggleEmailCredentials)
+ $('#mail_smtppassword').click(() => {
+ if (this.type === 'text' && this.value === '********') {
+ this.type = 'password'
+ this.value = ''
+ }
+ })
+
+ $('#sendtestemail').click((event) => {
+ event.preventDefault()
+ OC.msg.startAction('#sendtestmail_msg', t('settings', 'Sending…'))
+
+ $.ajax({
+ url: OC.generateUrl('/settings/admin/mailtest'),
+ type: 'POST',
+ success: () => {
+ OC.msg.finishedSuccess('#sendtestmail_msg', t('settings', 'Email sent'))
+ },
+ error: (xhr) => {
+ OC.msg.finishedError('#sendtestmail_msg', xhr.responseJSON)
+ }
+ })
+ })
+
+ $('#allowGroupSharing').change(() => {
+ $('#allowGroupSharing').toggleClass('hidden', !this.checked)
+ })
+
+ $('#shareapiExcludeGroups').change(() => {
+ $('#selectExcludedGroups').toggleClass('hidden', !this.checked)
+ })
+
+ const setupChecks = () => {
+ // run setup checks then gather error messages
+ $.when(
+ OC.SetupChecks.checkWebDAV(),
+ OC.SetupChecks.checkWellKnownUrl('GET', '/.well-known/webfinger', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true, [200, 404], true),
+ OC.SetupChecks.checkWellKnownUrl('GET', '/.well-known/nodeinfo', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true, [200, 404], true),
+ OC.SetupChecks.checkWellKnownUrl('PROPFIND', '/.well-known/caldav', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true),
+ OC.SetupChecks.checkWellKnownUrl('PROPFIND', '/.well-known/carddav', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true),
+ OC.SetupChecks.checkProviderUrl(OC.getRootPath() + '/ocm-provider/', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true),
+ OC.SetupChecks.checkProviderUrl(OC.getRootPath() + '/ocs-provider/', OC.theme.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === true),
+ OC.SetupChecks.checkSetup(),
+ OC.SetupChecks.checkGeneric(),
+ OC.SetupChecks.checkWOFF2Loading(OC.filePath('core', '', 'fonts/NotoSans-Regular-latin.woff2'), OC.theme.docPlaceholderUrl),
+ OC.SetupChecks.checkDataProtected()
+ ).then((check1, check2, check3, check4, check5, check6, check7, check8, check9, check10, check11) => {
+ const messages = [].concat(check1, check2, check3, check4, check5, check6, check7, check8, check9, check10, check11)
+ const $el = $('#postsetupchecks')
+ $('#security-warning-state-loading').addClass('hidden')
+
+ let hasMessages = false
+ const $errorsEl = $el.find('.errors')
+ const $warningsEl = $el.find('.warnings')
+ const $infoEl = $el.find('.info')
+
+ for (let i = 0; i < messages.length; i++) {
+ switch (messages[i].type) {
+ case OC.SetupChecks.MESSAGE_TYPE_INFO:
+ $infoEl.append('<li>' + messages[i].msg + '</li>')
+ break
+ case OC.SetupChecks.MESSAGE_TYPE_WARNING:
+ $warningsEl.append('<li>' + messages[i].msg + '</li>')
+ break
+ case OC.SetupChecks.MESSAGE_TYPE_ERROR:
+ default:
+ $errorsEl.append('<li>' + messages[i].msg + '</li>')
+ }
+ }
+
+ if ($errorsEl.find('li').length > 0) {
+ $errorsEl.removeClass('hidden')
+ hasMessages = true
+ }
+ if ($warningsEl.find('li').length > 0) {
+ $warningsEl.removeClass('hidden')
+ hasMessages = true
+ }
+ if ($infoEl.find('li').length > 0) {
+ $infoEl.removeClass('hidden')
+ hasMessages = true
+ }
+
+ if (hasMessages) {
+ $('#postsetupchecks-hint').removeClass('hidden')
+ if ($errorsEl.find('li').length > 0) {
+ $('#security-warning-state-failure').removeClass('hidden')
+ } else {
+ $('#security-warning-state-warning').removeClass('hidden')
+ }
+ } else {
+ const securityWarning = $('#security-warning')
+ if (securityWarning.children('ul').children().length === 0) {
+ $('#security-warning-state-ok').removeClass('hidden')
+ } else {
+ $('#security-warning-state-failure').removeClass('hidden')
+ }
+ }
+ })
+ }
+
+ if (document.getElementById('security-warning') !== null) {
+ setupChecks()
+ }
+})
diff --git a/apps/settings/src/mixins/AppManagement.js b/apps/settings/src/mixins/AppManagement.js
index 96f2c1dad4a..cf44a37a53f 100644
--- a/apps/settings/src/mixins/AppManagement.js
+++ b/apps/settings/src/mixins/AppManagement.js
@@ -20,6 +20,9 @@
*
*/
+import { showError } from '@nextcloud/dialogs'
+import rebuildNavigation from '../service/rebuild-navigation.js'
+
export default {
computed: {
appGroups() {
@@ -109,33 +112,33 @@ export default {
},
forceEnable(appId) {
this.$store.dispatch('forceEnableApp', { appId, groups: [] })
- .then((response) => { OC.Settings.Apps.rebuildNavigation() })
- .catch((error) => { OC.Notification.show(error) })
+ .then((response) => { rebuildNavigation() })
+ .catch((error) => { showError(error) })
},
enable(appId) {
this.$store.dispatch('enableApp', { appId, groups: [] })
- .then((response) => { OC.Settings.Apps.rebuildNavigation() })
- .catch((error) => { OC.Notification.show(error) })
+ .then((response) => { rebuildNavigation() })
+ .catch((error) => { showError(error) })
},
disable(appId) {
this.$store.dispatch('disableApp', { appId })
- .then((response) => { OC.Settings.Apps.rebuildNavigation() })
- .catch((error) => { OC.Notification.show(error) })
+ .then((response) => { rebuildNavigation() })
+ .catch((error) => { showError(error) })
},
remove(appId) {
this.$store.dispatch('uninstallApp', { appId })
- .then((response) => { OC.Settings.Apps.rebuildNavigation() })
- .catch((error) => { OC.Notification.show(error) })
+ .then((response) => { rebuildNavigation() })
+ .catch((error) => { showError(error) })
},
install(appId) {
this.$store.dispatch('enableApp', { appId })
- .then((response) => { OC.Settings.Apps.rebuildNavigation() })
- .catch((error) => { OC.Notification.show(error) })
+ .then((response) => { rebuildNavigation() })
+ .catch((error) => { showError(error) })
},
update(appId) {
this.$store.dispatch('updateApp', { appId })
- .then((response) => { OC.Settings.Apps.rebuildNavigation() })
- .catch((error) => { OC.Notification.show(error) })
+ .then((response) => { rebuildNavigation() })
+ .catch((error) => { showError(error) })
},
},
}
diff --git a/apps/settings/src/service/rebuild-navigation.js b/apps/settings/src/service/rebuild-navigation.js
new file mode 100644
index 00000000000..57cb1e439bd
--- /dev/null
+++ b/apps/settings/src/service/rebuild-navigation.js
@@ -0,0 +1,130 @@
+import axios from '@nextcloud/axios'
+import { generateOcsUrl } from '@nextcloud/router'
+
+export default () => {
+ return axios.get(generateOcsUrl('core/navigation', 2) + '/apps?format=json')
+ .then(({ data }) => {
+ if (data.ocs.meta.statuscode !== 200) {
+ return
+ }
+
+ const addedApps = {}
+ const navEntries = data.ocs.data
+ const container = document.querySelector('#navigation #apps ul')
+
+ // remove disabled apps
+ navEntries.forEach((entry) => {
+ if (!container.querySelector('li[data-id="' + entry.id + '"]')) {
+ addedApps[entry.id] = true
+ }
+ })
+
+ container.querySelectorAll('li[data-id]').forEach((el, index) => {
+ const id = el.dataset.id
+ // remove all apps that are not in the correct order
+ if (!navEntries[index] || (navEntries[index] && navEntries[index].id !== id)) {
+ el.remove()
+ document.querySelector(`#appmenu li[data-id=${id}]`).remove()
+ }
+ })
+
+ let previousEntry = {}
+ // add enabled apps to #navigation and #appmenu
+ navEntries.forEach((entry) => {
+ if (container.querySelector(`li[data-id="${entry.id}"]`) === null) {
+ const li = document.createElement('li')
+ li.dataset.id = entry.id
+ const img = `<svg width="20" height="20" viewBox="0 0 20 20" alt="">
+ <defs>
+ <filter id="invertMenuMore-${entry.id}"><feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"></feColorMatrix></filter>
+ <mask id="hole">
+ <rect width="100%" height="100%" fill="white"></rect>
+ <circle r="4.5" cx="17" cy="3" fill="black"></circle>
+ </mask>
+ </defs>
+ <image x="0" y="0" width="16" height="16" filter="url(#invertMenuMore-${entry.id})" preserveAspectRatio="xMinYMin meet" xlink:href="${entry.icon}" class="app-icon" />
+ </svg>`
+
+ const imgElement = document.createElement('template')
+ imgElement.innerHTML = img
+
+ const a = document.createElement('a')
+ a.setAttribute('href', entry.href)
+
+ const filename = document.createElement('span')
+ filename.appendChild(document.createTextNode(entry.name))
+
+ const loading = document.createElement('div')
+ loading.setAttribute('class', 'unread-counter')
+ loading.style.display = 'none'
+
+ // draw attention to the newly added app entry
+ // by flashing twice the more apps menu
+ if (addedApps[entry.id]) {
+ a.classList.add('animated')
+ }
+
+ a.prepend(imgElement.content.firstChild, loading, filename)
+ li.append(a)
+
+ // add app icon to the navigation
+ const previousElement = document.querySelector(`#navigation li[data-id=${previousEntry.id}]`)
+ if (previousElement) {
+ previousElement.insertAdjacentElement('afterend', li)
+ } else {
+ document.querySelector('#navigation #apps ul').prepend(li)
+ }
+ }
+
+ if (document.getElementById('appmenu').querySelector(`li[data-id="${entry.id}"]`) === null) {
+ const li = document.createElement('li')
+ li.dataset.id = entry.id
+ // Generating svg embedded image (see layout.user.php)
+ let img
+ if (OCA.Theming && OCA.Theming.inverted) {
+ img = `<svg width="20" height="20" viewBox="0 0 20 20" alt="">
+ <defs>
+ <filter id="invert"><feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" /></filter>
+ </defs>
+ <image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" xlink:href="${entry.icon}" class="app-icon" />
+ </svg>`
+ } else {
+ img = `<svg width="20" height="20" viewBox="0 0 20 20" alt="">
+ <image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet" xlink:href="${entry.icon}" class="app-icon" />
+ </svg>`
+ }
+ const imgElement = document.createElement('template')
+ imgElement.innerHTML = img
+
+ const a = document.createElement('a')
+ a.setAttribute('href', entry.href)
+
+ const filename = document.createElement('span')
+ filename.appendChild(document.createTextNode(entry.name))
+
+ const loading = document.createElement('div')
+ loading.setAttribute('class', 'icon-loading-dark')
+ loading.style.display = 'none'
+
+ // draw attention to the newly added app entry
+ // by flashing twice the more apps menu
+ if (addedApps[entry.id]) {
+ a.classList.add('animated')
+ }
+
+ a.prepend(loading, filename, imgElement.content.firstChild)
+ li.append(a)
+
+ // add app icon to the navigation
+ const previousElement = document.querySelector('#appmenu li[data-id=' + previousEntry.id + ']')
+ if (previousElement) {
+ previousElement.insertAdjacentElement('afterend', li)
+ } else {
+ document.queryElementById('appmenu').prepend(li)
+ }
+ }
+ previousEntry = entry
+ })
+ window.dispatchEvent(new Event('resize'))
+ })
+}
diff --git a/apps/settings/src/store/apps.js b/apps/settings/src/store/apps.js
index 038b42e64c9..1efed274b32 100644
--- a/apps/settings/src/store/apps.js
+++ b/apps/settings/src/store/apps.js
@@ -25,6 +25,8 @@
import api from './api'
import Vue from 'vue'
import { generateUrl } from '@nextcloud/router'
+import { showError, showInfo } from '@nextcloud/dialogs'
+import '@nextcloud/dialogs/styles/toast.scss'
const state = {
apps: [],
@@ -37,7 +39,7 @@ const state = {
const mutations = {
APPS_API_FAILURE(state, error) {
- OC.Notification.showHtml(t('settings', 'An error occured during the request. Unable to proceed.') + '<br>' + error.error.response.data.data.message, { timeout: 7 })
+ showError(t('settings', 'An error occured during the request. Unable to proceed.') + '<br>' + error.error.response.data.data.message, { timeout: 7, isHTML: true })
console.error(state, error)
},
@@ -180,16 +182,16 @@ const actions = {
return api.get(generateUrl('apps/files'))
.then(() => {
if (response.data.update_required) {
- OC.dialogs.info(
+ showInfo(
t(
'settings',
'The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds.'
),
- t('settings', 'App update'),
- function() {
- window.location.reload()
- },
- true
+ {
+ onClick: () => window.location.reload(),
+ close: false,
+
+ }
)
setTimeout(function() {
location.reload()
diff --git a/apps/settings/templates/settings/frame.php b/apps/settings/templates/settings/frame.php
index 53987bf6074..6d017f07671 100644
--- a/apps/settings/templates/settings/frame.php
+++ b/apps/settings/templates/settings/frame.php
@@ -22,7 +22,8 @@
*/
style('settings', 'settings');
-script('settings', [ 'settings', 'admin', 'log']);
+script('settings', 'settings');
+\OCP\Util::addScript('settings', 'legacy-admin');
script('core', 'setupchecks');
script('files', 'jquery.fileupload');