]> source.dussan.org Git - nextcloud-server.git/commitdiff
Persist settings on the server
authorChristoph Wurst <christoph@owncloud.com>
Wed, 20 Apr 2016 15:03:50 +0000 (17:03 +0200)
committerRoeland Jago Douma <roeland@famdouma.nl>
Mon, 21 Nov 2016 10:29:24 +0000 (11:29 +0100)
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 <roeland@famdouma.nl>
settings/Controller/UsersController.php
settings/css/settings.css
settings/js/federationsettingsview.js
settings/js/usersettings.js [new file with mode: 0644]
settings/personal.php
settings/routes.php
settings/templates/personal.php

index 89831a66abad0099cddc71ad085c639186b65aee..f06eabf6f9678303d0b59a84a413eb97d436600d 100644 (file)
@@ -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) {
index fe3518ae6a300202759c1c8b09eaf20a2f1c2389..4428f6130d6d21ecc7535223e79d056a9acdbb78 100644 (file)
@@ -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 {
index cf5158fa78577aeea5e5bbd3b1a36782b1fa6dc0..6a10d9f7f7e3a1d3641887eacc87ea501570281f 100644 (file)
@@ -1,4 +1,4 @@
-/* global OC */
+/* global OC, result */
 
 /**
  * Copyright (c) 2016, Christoph Wurst <christoph@owncloud.com>
@@ -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 = [
                                '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'));
                        });
                },
 
                },
 
                _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();
                },
 
                _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 (file)
index 0000000..d8d089f
--- /dev/null
@@ -0,0 +1,47 @@
+/* global OC */
+
+/**
+ * Copyright (c) 2016, Christoph Wurst <christoph@owncloud.com>
+ *
+ * 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
index 1780dddb5563c86baabf447db3349c6e2ca9010c..a18a88a9b6382856c3c3656a1fb444d9f5a663ed 100644 (file)
@@ -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());
index 58a576063128dac60dba5aca616d259fe49c9f58..ac4ade4f14ab4d6d1daa73b6cf77ca11f982bb83 100644 (file)
@@ -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'],
index 4fb9cefdeb0e537da8e883c91340277166828bfb..3f59954b6dd298e7f99311448f9077068b7abfb1 100644 (file)
@@ -71,6 +71,8 @@ if($_['displayNameChangeSupported']) {
                        <input type="text" id="displayname" name="displayname"
                               value="<?php p($_['displayName']) ?>"
                               autocomplete="on" autocapitalize="off" autocorrect="off" />
+                       <span class="icon-checkmark hidden"/>
+                       <input type="hidden" id="displaynamescope" value="<?php p($_['displayNameScope']) ?>">
                </form>
        </div>
        <div class="personal-settings-setting-box">
@@ -82,6 +84,8 @@ if($_['displayNameChangeSupported']) {
                        <input type="tel" id="phone" name="phone"
                               value="<?php p($_['phone']) ?>"
                               autocomplete="on" autocapitalize="off" autocorrect="off" />
+                       <span class="icon-checkmark hidden"/>
+                       <input type="hidden" id="phonescope" value="<?php p($_['phoneScope']) ?>">
                </form>
        </div>
        <div class="personal-settings-setting-box">
@@ -93,8 +97,10 @@ if($_['displayNameChangeSupported']) {
                        <input type="email" name="email" id="email" value="<?php p($_['email']); ?>"
                               placeholder="<?php p($l->t('Your email address')); ?>"
                               autocomplete="on" autocapitalize="off" autocorrect="off" />
+                       <input type="hidden" id="emailscope" value="<?php p($_['emailScope']) ?>">
                        <br />
                        <em><?php p($l->t('For password recovery and notifications')); ?></em>
+                       <span class="icon-checkmark hidden"/>
                </form>
        </div>
        <div class="personal-settings-setting-box">
@@ -106,6 +112,8 @@ if($_['displayNameChangeSupported']) {
                        <input type="text" name="website" id="website" value="<?php p($_['website']); ?>"
                               placeholder="<?php p($l->t('Your website')); ?>"
                               autocomplete="on" autocapitalize="off" autocorrect="off" />
+                       <span class="icon-checkmark hidden"/>
+                       <input type="hidden" id="websitescope" value="<?php p($_['websiteScope']) ?>">
                </form>
        </div>
        <div class="personal-settings-setting-box">
@@ -117,6 +125,8 @@ if($_['displayNameChangeSupported']) {
                        <input type="text" id="address" name="address"
                               value="<?php p($_['address']) ?>"
                               autocomplete="on" autocapitalize="off" autocorrect="off" />
+                       <span class="icon-checkmark hidden"/>
+                       <input type="hidden" id="addressscope" value="<?php p($_['addressScope']) ?>">
                </form>
        </div>
        <span class="msg"></span>
@@ -149,13 +159,31 @@ if($_['displayNameChangeSupported']) {
 <?php
 } else {
 ?>
-=======
->>>>>>> Add more personal information fields to the settings page for enhanced federated sharing
 <div id="lostpassword" class="section">
        <h2><?php echo $l->t('Email'); ?></h2>
        <span><?php if(isset($_['email'][0])) { p($_['email']); } else { p($l->t('No email address set')); }?></span>
+<div id="personal-settings-container" class="no-edit">
+       <div id="displaynameform" class="section">
+               <h2><?php p($l->t('Full name'));?></h2>
+               <span><?php if(isset($_['displayName'][0])) { p($_['displayName']); } else { p($l->t('No display name set')); } ?></span>
+       </div>
+       <div id="emailform" class="section">
+               <h2><?php p($l->t('Email')); ?></h2>
+               <span><?php if(isset($_['email'][0])) { p($_['email']); } else { p($l->t('No email address set')); }?></span>
+       </div>
+       <div id="phoneform" class="section">
+               <h2><?php p($l->t('Phone')); ?></h2>
+               <span><?php if(isset($_['phone'][0])) { p($_['phone']); } else { p($l->t('No phone number set')); }?></span>
+       </div>
+       <div id="websiteform" class="section">
+               <h2><?php p($l->t('Website')); ?></h2>
+               <span><?php if(isset($_['website'][0])) { p($_['website']); } else { p($l->t('No website set')); }?></span>
+       </div>
+       <div id="addressform" class="section">
+               <h2><?php p($l->t('Address')); ?></h2>
+               <span><?php if(isset($_['address'][0])) { p($_['address']); } else { p($l->t('No address set')); }?></span>
+       </div>
 </div>
-<!-- TODO: show phone/address -->
 <?php
 }
 ?>