From 20739c93a680d7085d0e71c0e4f9c0bb24018fb9 Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Wed, 20 Apr 2016 17:03:50 +0200 Subject: [PATCH] Persist settings on the server Persist personal settings federated sharing scopes Show new settings fields in read-only mode too Insert values on page load Return updated values; show inline success feedback Signed-off-by: Roeland Jago Douma --- settings/Controller/UsersController.php | 52 ++++++++++++++++++++-- settings/css/settings.css | 11 ++++- settings/js/federationsettingsview.js | 58 ++++++++++++++++++++----- settings/js/usersettings.js | 47 ++++++++++++++++++++ settings/personal.php | 13 ++++++ settings/routes.php | 3 +- settings/templates/personal.php | 34 +++++++++++++-- 7 files changed, 197 insertions(+), 21 deletions(-) create mode 100644 settings/js/usersettings.js diff --git a/settings/Controller/UsersController.php b/settings/Controller/UsersController.php index 89831a66aba..f06eabf6f96 100644 --- a/settings/Controller/UsersController.php +++ b/settings/Controller/UsersController.php @@ -493,17 +493,62 @@ class UsersController extends Controller { } /** - * Set the mail address of a user + * @todo add method description * * @NoAdminRequired * @NoSubadminRequired * @PasswordConfirmationRequired * + * @param string $userId + * @param string $displayname + * @param string $displaynameScope + * @param string $phone + * @param string $phoneScope + * @param string $email + * @param string $emailScope + * @param string $website + * @param string $websiteScope + * @param string $address + * @param string $addressScope + * @return DataResponse + */ + public function saveUserSettings($userId, + $displayname, $displaynameScope, + $phone, $phoneScope, + $email, $emailScope, + $website, $websiteScope, + $address, $addressScope) { + // TODO: implement + return new DataResponse( + array( + 'status' => 'success', + 'data' => array( + 'userId' => $userId, + 'displayname' => $displayname, + 'displaynameScope' => 'public', // force value for test purposes + 'email' => $email, + 'emailScope' => $emailScope, + 'website' => $website, + 'websiteScope' => $websiteScope, + 'address' => $address, + 'addressScope' => $addressScope, + 'message' => (string)$this->l10n->t('Settings saved') + ) + ), + Http::STATUS_OK + ); + } + + /** + * Set the mail address of a user + * + * @todo Merge into saveUserSettings + * * @param string $id * @param string $mailAddress * @return DataResponse */ - public function setMailAddress($id, $mailAddress) { + private function setMailAddress($id, $mailAddress) { $userId = $this->userSession->getUser()->getUID(); $user = $this->userManager->get($id); @@ -619,12 +664,13 @@ class UsersController extends Controller { * @NoAdminRequired * @NoSubadminRequired * @PasswordConfirmationRequired + * @todo merge into saveUserSettings * * @param string $username * @param string $displayName * @return DataResponse */ - public function setDisplayName($username, $displayName) { + private function setDisplayName($username, $displayName) { $currentUser = $this->userSession->getUser(); if ($username === null) { diff --git a/settings/css/settings.css b/settings/css/settings.css index fe3518ae6a3..4428f6130d6 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -78,6 +78,10 @@ input#openid, input#webdav { width:20em; } height: 100px; min-width: 300px; } +#personal-settings-container.no-edit > div { + height: 20px; + min-width: 200px; +} #personal-settings-container > div h2 span[class^="icon-"] { display: inline-block; margin-left: 5px; @@ -90,6 +94,12 @@ input#openid, input#webdav { width:20em; } .personal-settings-setting-box input[type="tel"] { width: 17em; } +#personal-settings-container > div > form span[class^="icon-checkmark"] { + position: absolute; + left: 239px; + top: 73px; + pointer-events: none; +} .federationScopeMenu { top: 66px; } @@ -101,7 +111,6 @@ input#openid, input#webdav { width:20em; } font-size: medium; } -#displaynameform, #lostpassword, #groups, #passwordform { diff --git a/settings/js/federationsettingsview.js b/settings/js/federationsettingsview.js index cf5158fa785..6a10d9f7f7e 100644 --- a/settings/js/federationsettingsview.js +++ b/settings/js/federationsettingsview.js @@ -1,4 +1,4 @@ -/* global OC */ +/* global OC, result */ /** * Copyright (c) 2016, Christoph Wurst @@ -22,7 +22,7 @@ if (options.config) { this._config = options.config; } else { - this._config = new OC.Backbone.Model() + this._config = new OC.Settings.UserSettings(); } this._inputFields = [ @@ -33,6 +33,21 @@ 'address' ]; + var self = this; + _.each(this._inputFields, function(field) { + // Initialize config model + self._config.set(field, $('#' + field).val()); + self._config.set(field + 'Scope', $('#' + field + 'scope').val()); + + // Set inputs whenever model values change + self.listenTo(self._config, 'change:' + field, function () { + self.$('#' + field).val(self._config.get(field)); + }); + self.listenTo(self._config, 'change:' + field + 'Scope', function () { + self._onScopeChanged(field, self._config.get(field + 'Scope')); + }); + }); + this._registerEvents(); }, @@ -53,6 +68,8 @@ // TODO: fix position without magic numbers var pos = ($heading.width() - $heading.find('label').width()) - 68; scopeMenu.$el.css('right', pos); + + self._onScopeChanged(field, self._config.get(field + 'Scope')); }); }, @@ -64,21 +81,30 @@ }, _onInputChanged: function(e) { - OC.msg.startSaving('#personal-settings-container .msg'); + var self = this; + var $target = $(e.target); var value = $target.val(); var field = $target.attr('id'); - console.log(field + ' changed to ' + value); this._config.set(field, value); - console.log(this._config.toJSON()); - // TODO: this._config.save(); - // TODO: OC.msg.finishedSaving('#personal-settings-container .msg', result); - // TODO: call _updateDisplayName after successful update + var savingData = this._config.save({ + error: function(jqXHR) { + OC.msg.finishedSaving('#personal-settings-container .msg', jqXHR); + } + }); + + $.when(savingData).done(function() { + //OC.msg.finishedSaving('#personal-settings-container .msg', result) + self._showInputChangeSuccess(field); + if (field === 'displayname') { + self._updateDisplayName(value); + } + }); }, _updateDisplayName: function(displayName) { // update displayName on the top right expand button - $('#expandDisplayName').text($('#displayName').val()); + $('#expandDisplayName').text(displayName); // update avatar if avatar is available if(!$('#removeavatar').hasClass('hidden')) { updateAvatar(); @@ -86,12 +112,20 @@ }, _onScopeChanged: function(field, scope) { - // TODO: save changes to the server - console.log(field + ' changed to ' + scope); - + this._config.set(field + 'Scope', scope); + // TODO: user loading/success feedback + this._config.save(); this._setFieldScopeIcon(field, scope); }, + _showInputChangeSuccess: function(field) { + var $icon = this.$('#' + field + 'form > span'); + $icon.fadeIn(200); + setTimeout(function() { + $icon.fadeOut(300); + }, 2000); + }, + _setFieldScopeIcon: function(field, scope) { var $icon = this.$('#' + field + 'form > h2 > span'); $icon.removeClass('icon-password'); diff --git a/settings/js/usersettings.js b/settings/js/usersettings.js new file mode 100644 index 00000000000..d8d089f83de --- /dev/null +++ b/settings/js/usersettings.js @@ -0,0 +1,47 @@ +/* global OC */ + +/** + * Copyright (c) 2016, Christoph Wurst + * + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +(function() { + 'use strict'; + + /** + * Model for storing and saving user settings + * + * @class UserSettings + */ + var UserSettings = OC.Backbone.Model.extend({ + url: OC.generateUrl('/settings/users/{id}/settings', {id: OC.currentUser}), + parse: function(data) { + if (_.isUndefined(data)) { + return null; + } + if (_.isUndefined(data.data)) { + return null; + } + data = data.data; + + var ignored = [ + 'userId', + 'message' + ]; + + _.each(ignored, function(ign) { + if (!_.isUndefined(data[ign])) { + delete data[ign]; + } + }); + + return data; + } + }); + + OC.Settings = OC.Settings || {}; + + OC.Settings.UserSettings = UserSettings; +})(); \ No newline at end of file diff --git a/settings/personal.php b/settings/personal.php index 1780dddb556..a18a88a9b63 100644 --- a/settings/personal.php +++ b/settings/personal.php @@ -47,6 +47,7 @@ $urlGenerator = \OC::$server->getURLGenerator(); OC_Util::addScript('settings', 'authtoken'); OC_Util::addScript('settings', 'authtoken_collection'); OC_Util::addScript('settings', 'authtoken_view'); +OC_Util::addScript('settings', 'usersettings'); OC_Util::addScript('settings', 'federationsettingsview'); OC_Util::addScript('settings', 'federationscopemenu'); OC_Util::addScript('settings', 'personal'); @@ -164,6 +165,18 @@ $tmpl->assign('activelanguage', $userLang); $tmpl->assign('passwordChangeSupported', OC_User::canUserChangePassword(OC_User::getUser())); $tmpl->assign('displayNameChangeSupported', OC_User::canUserChangeDisplayName(OC_User::getUser())); $tmpl->assign('displayName', OC_User::getDisplayName()); +// TODO: insert real data +$tmpl->assign('phone', '+43 660 56565 5446'); +$tmpl->assign('website', 'owncloud.org'); +$tmpl->assign('address', 'Stuttgart'); + +$tmpl->assign('avatarScope', 'contacts'); +$tmpl->assign('displayNameScope', 'public'); +$tmpl->assign('phoneScope', 'contacts'); +$tmpl->assign('emailScope', 'contacts'); +$tmpl->assign('websiteScope', 'public'); +$tmpl->assign('addressScope', 'private'); +// END TODO $tmpl->assign('enableAvatars', $config->getSystemValue('enable_avatars', true) === true); $tmpl->assign('avatarChangeSupported', OC_User::canUserChangeAvatar(OC_User::getUser())); $tmpl->assign('certs', $certificateManager->listCertificates()); diff --git a/settings/routes.php b/settings/routes.php index 58a57606312..ac4ade4f14a 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -50,8 +50,7 @@ $application->registerRoutes($this, [ ['name' => 'AppSettings#viewApps', 'url' => '/settings/apps', 'verb' => 'GET'], ['name' => 'AppSettings#listApps', 'url' => '/settings/apps/list', 'verb' => 'GET'], ['name' => 'SecuritySettings#trustedDomains', 'url' => '/settings/admin/security/trustedDomains', 'verb' => 'POST'], - ['name' => 'Users#setDisplayName', 'url' => '/settings/users/{username}/displayName', 'verb' => 'POST'], - ['name' => 'Users#setMailAddress', 'url' => '/settings/users/{id}/mailAddress', 'verb' => 'PUT'], + ['name' => 'Users#saveUserSettings', 'url' => '/settings/users/{username}/settings', 'verb' => 'POST'], ['name' => 'Users#stats', 'url' => '/settings/users/stats', 'verb' => 'GET'], ['name' => 'LogSettings#setLogLevel', 'url' => '/settings/admin/log/level', 'verb' => 'POST'], ['name' => 'LogSettings#getEntries', 'url' => '/settings/admin/log/entries', 'verb' => 'GET'], diff --git a/settings/templates/personal.php b/settings/templates/personal.php index 4fb9cefdeb0..3f59954b6dd 100644 --- a/settings/templates/personal.php +++ b/settings/templates/personal.php @@ -71,6 +71,8 @@ if($_['displayNameChangeSupported']) { +