Overhauled profile user editor
authorAlexander Ebert <ebert@woltlab.com>
Sat, 16 Jul 2016 11:42:48 +0000 (13:42 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Sat, 16 Jul 2016 11:42:56 +0000 (13:42 +0200)
com.woltlab.wcf/templates/user.tpl
com.woltlab.wcf/templates/userHeader.tpl
wcfsetup/install/files/js/WCF.User.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Dialog.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/User/Editor.js [new file with mode: 0644]
wcfsetup/install/files/lib/data/user/UserAction.class.php
wcfsetup/install/files/style/ui/userProfile.scss

index e42729dfd0c14157db55b63253a4a575515f65b8..57eeddd76d5fd9bc8a747a7a11b2ee8fc95af575 100644 (file)
@@ -6,14 +6,41 @@
        {event name='javascriptInclude'}
        <script data-relocate="true">
                {if $__wcf->getUser()->userID && $__wcf->getUser()->userID != $user->userID}
-                       require(['Language', 'WoltLab/WCF/Ui/User/Profile/Menu/Item/Ignore', 'WoltLab/WCF/Ui/User/Profile/Menu/Item/Follow'], function(Language, UiUserProfileMenuItemIgnore, UiUserProfileMenuItemFollow) {
+                       require(['Language', 'WoltLab/WCF/Ui/User/Editor', 'WoltLab/WCF/Ui/User/Profile/Menu/Item/Ignore', 'WoltLab/WCF/Ui/User/Profile/Menu/Item/Follow'], function(Language, UiUserEditor, UiUserProfileMenuItemIgnore, UiUserProfileMenuItemFollow) {
                                Language.addObject({
+                                       'wcf.acp.user.disable': '{lang}wcf.acp.user.disable{/lang}',
+                                       'wcf.acp.user.enable': '{lang}wcf.acp.user.enable{/lang}',
+                                       'wcf.user.ban': '{lang}wcf.user.ban{/lang}',
+                                       'wcf.user.banned': '{lang}wcf.user.banned{/lang}',
+                                       'wcf.user.ban.confirmMessage': '{lang}wcf.user.ban.confirmMessage{/lang}',
+                                       'wcf.user.ban.expires': '{lang}wcf.user.ban.expires{/lang}',
+                                       'wcf.user.ban.expires.description': '{lang}wcf.user.ban.expires.description{/lang}',
+                                       'wcf.user.ban.neverExpires': '{lang}wcf.user.ban.neverExpires{/lang}',
+                                       'wcf.user.ban.reason.description': '{lang}wcf.user.ban.reason.description{/lang}',
                                        'wcf.user.button.follow': '{lang}wcf.user.button.follow{/lang}',
                                        'wcf.user.button.unfollow': '{lang}wcf.user.button.unfollow{/lang}',
                                        'wcf.user.button.ignore': '{lang}wcf.user.button.ignore{/lang}',
-                                       'wcf.user.button.unignore': '{lang}wcf.user.button.unignore{/lang}'
+                                       'wcf.user.button.unignore': '{lang}wcf.user.button.unignore{/lang}',
+                                       'wcf.user.disableAvatar': '{lang}wcf.user.disableAvatar{/lang}',
+                                       'wcf.user.disableAvatar.confirmMessage': '{lang}wcf.user.disableAvatar.confirmMessage{/lang}',
+                                       'wcf.user.disableAvatar.expires': '{lang}wcf.user.disableAvatar.expires{/lang}',
+                                       'wcf.user.disableAvatar.expires.description': '{lang}wcf.user.disableAvatar.expires.description{/lang}',
+                                       'wcf.user.disableAvatar.neverExpires': '{lang}wcf.user.disableAvatar.neverExpires{/lang}',
+                                       'wcf.user.disableSignature': '{lang}wcf.user.disableSignature{/lang}',
+                                       'wcf.user.disableSignature.confirmMessage': '{lang}wcf.user.disableSignature.confirmMessage{/lang}',
+                                       'wcf.user.disableSignature.expires': '{lang}wcf.user.disableSignature.expires{/lang}',
+                                       'wcf.user.disableSignature.expires.description': '{lang}wcf.user.disableSignature.expires.description{/lang}',
+                                       'wcf.user.disableSignature.neverExpires': '{lang}wcf.user.disableSignature.neverExpires{/lang}',
+                                       'wcf.user.edit': '{lang}wcf.user.edit{/lang}',
+                                       'wcf.user.enableAvatar': '{lang}wcf.user.enableAvatar{/lang}',
+                                       'wcf.user.enableSignature': '{lang}wcf.user.enableSignature{/lang}',
+                                       'wcf.user.unban': '{lang}wcf.user.unban{/lang}'
                                });
                                
+                               {if $isAccessible}
+                                       UiUserEditor.init();
+                               {/if}
+                               
                                {if !$user->isIgnoredUser($__wcf->user->userID)}
                                        new UiUserProfileMenuItemFollow({@$user->userID}, {if $__wcf->getUserProfileHandler()->isFollowing($user->userID)}true{else}false{/if});
                                {/if}
                                });
                        {/if}
                        
-                       {if $isAccessible && $__wcf->user->userID != $user->userID}
-                               WCF.Language.addObject({
-                                       'wcf.user.ban': '{lang}wcf.user.ban{/lang}',
-                                       'wcf.user.ban.confirmMessage': '{lang}wcf.user.ban.confirmMessage{/lang}',
-                                       'wcf.user.ban.expires': '{lang}wcf.user.ban.expires{/lang}',
-                                       'wcf.user.ban.expires.description': '{lang}wcf.user.ban.expires.description{/lang}',
-                                       'wcf.user.ban.neverExpires': '{lang}wcf.user.ban.neverExpires{/lang}',
-                                       'wcf.user.ban.reason.description': '{lang}wcf.user.ban.reason.description{/lang}',
-                                       'wcf.user.unban': '{lang}wcf.user.unban{/lang}',
-                                       'wcf.user.disableAvatar': '{lang}wcf.user.disableAvatar{/lang}',
-                                       'wcf.user.ban.expires': '{lang}wcf.user.ban.expires{/lang}',
-                                       'wcf.user.ban.expires.description': '{lang}wcf.user.ban.expires.description{/lang}',
-                                       'wcf.user.ban.neverExpires': '{lang}wcf.user.ban.neverExpires{/lang}',
-                                       'wcf.user.disableAvatar.confirmMessage': '{lang}wcf.user.disableAvatar.confirmMessage{/lang}',
-                                       'wcf.user.disableAvatar.expires': '{lang}wcf.user.disableAvatar.expires{/lang}',
-                                       'wcf.user.disableAvatar.expires.description': '{lang}wcf.user.disableAvatar.expires.description{/lang}',
-                                       'wcf.user.disableAvatar.neverExpires': '{lang}wcf.user.disableAvatar.neverExpires{/lang}',
-                                       'wcf.user.disableSignature': '{lang}wcf.user.disableSignature{/lang}',
-                                       'wcf.user.disableSignature.confirmMessage': '{lang}wcf.user.disableSignature.confirmMessage{/lang}',
-                                       'wcf.user.disableSignature.expires': '{lang}wcf.user.disableSignature.expires{/lang}',
-                                       'wcf.user.disableSignature.expires.description': '{lang}wcf.user.disableSignature.expires.description{/lang}',
-                                       'wcf.user.disableSignature.neverExpires': '{lang}wcf.user.disableSignature.neverExpires{/lang}',
-                                       'wcf.user.edit': '{lang}wcf.user.edit{/lang}',
-                                       'wcf.user.enableAvatar': '{lang}wcf.user.enableAvatar{/lang}',
-                                       'wcf.user.enableSignature': '{lang}wcf.user.enableSignature{/lang}'
-                               });
-                               
-                               var $userInlineEditor = new WCF.User.InlineEditor('.userHeadline');
-                               $userInlineEditor.setPermissions({
-                                       canBanUser: {if $__wcf->session->getPermission('admin.user.canBanUser')}true{else}false{/if},
-                                       canDisableAvatar: {if $__wcf->session->getPermission('admin.user.canDisableAvatar')}true{else}false{/if},
-                                       canDisableSignature: {if $__wcf->session->getPermission('admin.user.canDisableSignature')}true{else}false{/if},
-                                       canEditUser: {if $__wcf->session->getPermission('admin.general.canUseAcp') && $__wcf->session->getPermission('admin.user.canEditUser')}true{else}false{/if}
-                               });
-                       {/if}
-                       
                        {if $__wcf->session->getPermission('user.profile.canReportContent')}
                                WCF.Language.addObject({
                                        'wcf.moderation.report.reportContent': '{lang}wcf.user.profile.report{/lang}',
index 3d567c8e751766cf2051147244049c43de86534b..e674a145bfe99535046cb849b0ce844cb514c4a4 100644 (file)
@@ -32,6 +32,9 @@
                                {if $__wcf->session->getPermission('admin.user.canDisableSignature')}
                                        data-disable-signature="{@$user->disableSignature}"
                                {/if}
+                               {if $__wcf->session->getPermission('admin.user.canEnableUser')}
+                                       data-is-disabled="{if $user->activationCode}true{else}false{/if}"
+                               {/if}
                                {/if}>
                                
                                <div class="layoutBoundary">
                                                                        <a class="jsTooltip" title="{lang}wcf.user.profile.management{/lang}"><span class="icon icon32 fa-cog"></span> <span class="invisible">{lang}wcf.user.profile.dropdown.management{/lang}</span></a>
                                                                        <ul class="userProfileButtonMenu" data-menu="management">
                                                                                {content}
+                                                                                       {event name='menuManagement'}
+                                                                                       
                                                                                        {if $isAccessible && $__wcf->user->userID != $user->userID && ($__wcf->session->getPermission('admin.user.canBanUser') || $__wcf->session->getPermission('admin.user.canDisableAvatar') || $__wcf->session->getPermission('admin.user.canDisableSignature') || ($__wcf->session->getPermission('admin.general.canUseAcp') && $__wcf->session->getPermission('admin.user.canEditUser')){event name='moderationDropdownPermissions'})}
-                                                                                               <li><a href="{link controller='UserEdit' object=$user isACP=true}{/link}" class="jsUserInlineEditor">{lang}wcf.user.edit{/lang}</a></li>
+                                                                                               {if $__wcf->session->getPermission('admin.user.canBanUser')}<li><a href="#" class="jsButtonUserBan">{lang}wcf.user.{if $user->banned}un{/if}ban{/lang}</a></li>{/if}
+                                                                                               {if $__wcf->session->getPermission('admin.user.canDisableAvatar')}<li><a href="#" class="jsButtonUserDisableAvatar">{lang}wcf.user.{if $user->disableAvatar}enable{else}disable{/if}Avatar{/lang}</a></li>{/if}
+                                                                                               {if $__wcf->session->getPermission('admin.user.canDisableSignature')}<li><a href="#" class="jsButtonUserDisableSignature">{lang}wcf.user.{if $user->disableSignature}enable{else}disable{/if}Signature{/lang}</a></li>{/if}
+                                                                                               {if $__wcf->session->getPermission('admin.user.canEnableUser')}<li><a href="#" class="jsButtonUserEnable">{lang}wcf.acp.user.{if $user->activationCode}enable{else}disable{/if}{/lang}</a></li>{/if}
+                                                                                               
+                                                                                               <li class="divider"><a href="{link controller='UserEdit' object=$user isACP=true}{/link}" class="jsUserInlineEditor">{lang}wcf.user.edit{/lang}</a></li>
                                                                                        {/if}
-                                                                               
-                                                                                       {event name='menuManagement'}
                                                                                {/content}
                                                                        </ul>
                                                                </li>
index f1e184a4fd57743675a42f604a6e303a11d2e1b9..43174020b6cfa4858b0d9891220c269dc42de111 100644 (file)
@@ -2931,363 +2931,3 @@ WCF.User.ObjectWatch.Subscribe = Class.extend({
                WCF.System.Event.fireEvent('com.woltlab.wcf.objectWatch', 'updatedSubscription', data);
        }
 });
-
-/**
- * Handles inline editing of users.
- */
-WCF.User.InlineEditor = WCF.InlineEditor.extend({
-       /**
-        * data of additional options
-        * @var object
-        */
-       _additionalOptions: { },
-       
-       /**
-        * dialog object
-        * @var jQuery
-        */
-       _dialog: null,
-       
-       /**
-        * list of permissions
-        * @var object
-        */
-       _permissions: { },
-       
-       /**
-        * @see WCF.InlineEditor.init()
-        */
-       init: function(elementSelector) {
-               this._super(elementSelector);
-               
-               WCF.System.ObjectStore.add('WCF.User.InlineEditor', this);
-       },
-       
-       /**
-        * @see WCF.InlineEditor._execute()
-        */
-       _execute: function(elementID, optionName) {
-               if (!this._validate(elementID, optionName)) {
-                       return false;
-               }
-               
-               var $data = { };
-               var $element = $('#' + elementID);
-               if (this._additionalOptions[optionName] !== undefined) {
-                       this._additionalOptions[optionName].callback(elementID);
-               }
-               else {
-                       switch (optionName) {
-                               case 'unban':
-                               case 'enableAvatar':
-                               case 'enableSignature':
-                                       switch (optionName) {
-                                               case 'unban':
-                                                       $data.banned = 0;
-                                               break;
-                                               
-                                               case 'enableAvatar':
-                                                       $data.disableAvatar = 0;
-                                               break;
-                                               
-                                               case 'enableSignature':
-                                                       $data.disableSignature = 0;
-                                               break;
-                                       }
-                                       
-                                       this._proxy.setOption('data', {
-                                               actionName: optionName,
-                                               className: 'wcf\\data\\user\\UserAction',
-                                               objectIDs: [ $element.data('objectID') ]
-                                       });
-                                       this._proxy.sendRequest();
-                               break;
-                               
-                               case 'ban':
-                               case 'disableAvatar':
-                               case 'disableSignature':
-                                       if (optionName == 'ban') {
-                                               $data.banned = 1;
-                                       }
-                                       else {
-                                               $data[optionName] = 1;
-                                       }
-                                       
-                                       this._showReasonDialog($element.data('objectID'), optionName);
-                               break;
-                               
-                               case 'advanced':
-                                       window.location = this._getTriggerElement($element).attr('href');
-                               break;
-                       }
-               }
-               
-               if ($.getLength($data)) {
-                       this._updateData.push({
-                               data: $data,
-                               elementID: elementID,
-                       });
-               }
-       },
-       
-       /**
-        * Executes an action with a reason.
-        * 
-        * @param       integer         userID
-        * @param       string          optionName
-        * @param       string          reason
-        */
-       _executeReasonAction: function(userID, optionName, reason) {
-               var $optionName = this._dialog.data('optionName');
-               
-               this._dialog.find('.innerError').remove();
-               
-               var $banExpires = '';
-               if (!$('#' + $optionName + 'NeverExpires').is(':checked')) {
-                       $banExpires = $('#' + $optionName + 'ExpiresDatePicker').val();
-                       if (!$banExpires) {
-                               this._dialog.find('#' + $optionName + 'ExpiresSettings > dd > small').prepend($('<small class="innerError" />').text(WCF.Language.get('wcf.global.form.error.empty')));
-                               return
-                       }
-               }
-               
-               var $parameters = { };
-               $parameters[$optionName + 'Reason'] = $('#' + $optionName + 'Reason').val();
-               $parameters[$optionName + 'Expires'] = $banExpires;
-               
-               this._proxy.setOption('data', {
-                       actionName: $optionName,
-                       className: 'wcf\\data\\user\\UserAction',
-                       objectIDs: [ this._dialog.data('userID') ],
-                       parameters: $parameters
-               });
-               this._proxy.sendRequest();
-       },
-       
-       /**
-        * Returns a specific permission.
-        * 
-        * @param       string          permission
-        * @return      integer
-        */
-       _getPermission: function(permission) {
-               if (this._permissions[permission]) {
-                       return this._permissions[permission];
-               }
-               
-               return 0;
-       },
-       
-       /**
-        * @see WCF.InlineEditor._getTriggerElement()
-        */
-       _getTriggerElement: function(element) {
-               return element.find('.jsUserInlineEditor');
-       },
-       
-       /**
-        * @see WCF.InlineEditor._setOptions()
-        */
-       _setOptions: function() {
-               this._options = [
-                       // banning
-                       { label: WCF.Language.get('wcf.user.ban'), optionName: 'ban' },
-                       { label: WCF.Language.get('wcf.user.unban'), optionName: 'unban' },
-                       
-                       // disabling avatar
-                       { label: WCF.Language.get('wcf.user.disableAvatar'), optionName: 'disableAvatar' },
-                       { label: WCF.Language.get('wcf.user.enableAvatar'), optionName: 'enableAvatar' },
-                       
-                       // disabling signature
-                       { label: WCF.Language.get('wcf.user.disableSignature'), optionName: 'disableSignature' },
-                       { label: WCF.Language.get('wcf.user.enableSignature'), optionName: 'enableSignature' }
-               ];
-               
-               for (var $optionName in this._additionalOptions) {
-                       this._options.push({ label: this._additionalOptions[$optionName].label, optionName: $optionName });
-               }
-               
-               // divider
-               this._options.push({ optionName: 'divider' });
-               
-               // redirect to ACP
-               this._options.push({ label: WCF.Language.get('wcf.user.edit'), optionName: 'advanced' });
-       },
-       
-       /**
-        * @see WCF.InlineEditor._show()
-        */
-       _show: function(event) {
-               var $element = $(event.currentTarget);
-               var $elementID = $element.data('elementID');
-               
-               if (!this._dropdowns[$elementID]) {
-                       var $dropdownMenu = $element.next('.dropdownMenu');
-                       
-                       if ($dropdownMenu) {
-                               this._dropdowns[$elementID] = $dropdownMenu;
-                               WCF.Dropdown.initDropdown(this._getTriggerElement(this._elements[$elementID]), true);
-                       }
-               }
-               
-               return this._super(event);
-       },
-       
-       /**
-        * Shows the dialog to enter a reason for executing the option with the
-        * given name.
-        * 
-        * @param       string          optionName
-        */
-       _showReasonDialog: function(userID, optionName) {
-               if (this._dialog) {
-                       this._dialog.remove();
-               }
-               
-               // create dialog
-               this._dialog = $('<div />').hide().appendTo(document.body);
-               this._dialog.append($('<div class="section"><dl><dt><label for="' + optionName + 'Reason">' + WCF.Language.get('wcf.global.reason') + '</label></dt><dd><textarea id="' + optionName + 'Reason" cols="40" rows="3" />' + (WCF.Language.get('wcf.user.' + optionName + '.reason.description') != 'wcf.user.' + optionName + '.reason.description' ? '<small>' + WCF.Language.get('wcf.user.' + optionName + '.reason.description') + '</small>' : '') + '</dd></dl><dl><dt></dt><dd><label for="' + optionName + 'NeverExpires"><input type="checkbox" name="' + optionName + 'NeverExpires" id="' + optionName + 'NeverExpires" checked> ' + WCF.Language.get('wcf.user.' + optionName + '.neverExpires') + '</label></dd></dl><dl id="' + optionName + 'ExpiresSettings" style="display: none;"><dt><label for="' + optionName + 'Expires">' + WCF.Language.get('wcf.user.' + optionName + '.expires') + '</label></dt><dd><input type="date" name="' + optionName + 'Expires" id="' + optionName + 'Expires" class="medium" min="' + new Date(TIME_NOW * 1000).toISOString() + '" data-ignore-timezone="true" /><small>' + WCF.Language.get('wcf.user.' + optionName + '.expires.description') + '</small></dd></dl></div>'));
-               this._dialog.append($('<div class="formSubmit"><button class="buttonPrimary" accesskey="s">' + WCF.Language.get('wcf.global.button.submit') + '</button></div>'));
-               
-               this._dialog.data('optionName', optionName).data('userID', userID);
-               
-               this._dialog.find('#' + optionName + 'NeverExpires').change(function() {
-                       $('#' + optionName + 'ExpiresSettings').toggle();
-               });
-               
-               this._dialog.find('button').click($.proxy(this._executeReasonAction, this));
-               
-               this._dialog.wcfDialog({
-                       title: WCF.Language.get('wcf.user.' + optionName + '.confirmMessage')
-               });
-       },
-       
-       /**
-        * @see WCF.InlineEditor._updateState()
-        */
-       _updateState: function(data) {
-               this._notification.show();
-               
-               for (var $i = 0, $length = this._updateData.length; $i < $length; $i++) {
-                       var $data = this._updateData[$i];
-                       var $element = $('#' + $data.elementID);
-                       
-                       for (var $property in $data.data) {
-                               $element.data($property, $data.data[$property]);
-                       }
-               }
-               
-               if (data.actionName == 'ban' || data.actionName == 'disableAvatar' || data.actionName == 'disableSignature') {
-                       this._dialog.wcfDialog('close');
-               }
-               
-               if (data.actionName == 'unban') {
-                       $('.userHeadline .jsUserBanned').remove();
-               }
-       },
-       
-       /**
-        * @see WCF.InlineEditor._validate()
-        */
-       _validate: function(elementID, optionName) {
-               var $user = $('#' + elementID);
-               
-               if (this._additionalOptions[optionName] !== undefined) {
-                       return true;
-               }
-               
-               switch (optionName) {
-                       case 'ban':
-                       case 'unban':
-                               if (!this._getPermission('canBanUser')) {
-                                       return false;
-                               }
-                               
-                               if (optionName == 'ban') {
-                                       return !$user.data('banned');
-                               }
-                               else {
-                                       return $user.data('banned');
-                               }
-                       break;
-                       
-                       case 'disableAvatar':
-                       case 'enableAvatar':
-                               if (!this._getPermission('canDisableAvatar')) {
-                                       return false;
-                               }
-                               
-                               if (optionName == 'disableAvatar') {
-                                       return !$user.data('disableAvatar');
-                               }
-                               else {
-                                       return $user.data('disableAvatar');
-                               }
-                       break;
-                       
-                       case 'disableSignature':
-                       case 'enableSignature':
-                               if (!this._getPermission('canDisableSignature')) {
-                                       return false;
-                               }
-                               
-                               if (optionName == 'disableSignature') {
-                                       return !$user.data('disableSignature');
-                               }
-                               else {
-                                       return $user.data('disableSignature');
-                               }
-                       break;
-                       
-                       case 'advanced':
-                               return this._getPermission('canEditUser');
-                       break;
-               }
-               
-               return false;
-       },
-       
-       /**
-        * Adds an additional option.
-        * 
-        * @param       string          label
-        * @param       string          optionName
-        * @param       function        callback
-        */
-       addOption: function(label, optionName, callback) {
-               if (!$.isFunction(callback)) {
-                       console.debug('[WCF.User.InlineEditor] Missing callback');
-               }
-               if (this._additionalOptions[optionName] !== undefined) {
-                       console.debug('[WCF.User.InlineEditor] Additional option with name "' + optionName + "' already exists");
-               }
-               
-               this._additionalOptions[optionName] = {
-                       callback: callback,
-                       label: label
-               };
-               
-               this._setOptions();
-       },
-       
-       /**
-        * Sets a permission.
-        * 
-        * @param       string          permission
-        * @param       integer         value
-        */
-       setPermission: function(permission, value) {
-               this._permissions[permission] = value;
-       },
-       
-       /**
-        * Sets permissions.
-        * 
-        * @param       object          permissions
-        */
-       setPermissions: function(permissions) {
-               for (var $permission in permissions) {
-                       this.setPermission($permission, permissions[$permission]);
-               }
-       }
-});
index 0ca68efd78a9a31db4da34f71db8ec9714ca4ead..f209cd3f80628c7552755f6a65d0845e2113b75a 100644 (file)
@@ -392,7 +392,7 @@ define(
                                }
                                
                                if (typeof data.onShow === 'function') {
-                                       data.onShow(id);
+                                       data.onShow(data.content);
                                }
                        }
                        
diff --git a/wcfsetup/install/files/js/WoltLab/WCF/Ui/User/Editor.js b/wcfsetup/install/files/js/WoltLab/WCF/Ui/User/Editor.js
new file mode 100644 (file)
index 0000000..c7cd50e
--- /dev/null
@@ -0,0 +1,228 @@
+/**
+ * Simple notification overlay.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2016 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLab/WCF/Ui/User/Editor
+ */
+define(['Ajax', 'Language', 'StringUtil', 'Dom/Util', 'Ui/Dialog', 'Ui/Notification'], function(Ajax, Language, StringUtil, DomUtil, UiDialog, UiNotification) {
+       "use strict";
+       
+       var _actionName = '';
+       var _userHeader = null;
+       
+       /**
+        * @exports     WoltLab/WCF/Ui/User/Editor
+        */
+       return {
+               /**
+                * Initializes the user editor.
+                */
+               init: function() {
+                       _userHeader = elBySel('.userProfileUser');
+                       
+                       // init buttons
+                       ['ban', 'disableAvatar', 'disableSignature', 'enable'].forEach((function(action) {
+                               var button = elBySel('.jsButtonUser' + StringUtil.ucfirst(action), _userHeader);
+                               
+                               // button is missing if users lacks the permission
+                               if (button) {
+                                       elData(button, 'action', action);
+                                       button.addEventListener(WCF_CLICK_EVENT, this._click.bind(this));
+                               }
+                       }).bind(this));
+               },
+               
+               /**
+                * Handles clicks on action buttons.
+                * 
+                * @param       {Event}         event           event object
+                * @protected
+                */
+               _click: function(event) {
+                       event.preventDefault();
+                       
+                       //noinspection JSCheckFunctionSignatures
+                       var action = elData(event.currentTarget, 'action');
+                       var actionName = '';
+                       switch (action) {
+                               case 'ban':
+                                       if (elDataBool(_userHeader, 'banned')) {
+                                               actionName = 'unban';
+                                       }
+                                       break;
+                               
+                               case 'disableAvatar':
+                                       if (elDataBool(_userHeader, 'disable-avatar')) {
+                                               actionName = 'enableAvatar';
+                                       }
+                                       break;
+                               
+                               case 'disableSignature':
+                                       if (elDataBool(_userHeader, 'disable-signature')) {
+                                               actionName = 'enableSignature';
+                                       }
+                                       break;
+                               
+                               case 'enable':
+                                       actionName = (elDataBool(_userHeader, 'is-disabled')) ? 'enable' : 'disable';
+                                       break;
+                       }
+                       
+                       if (actionName === '') {
+                               _actionName = action;
+                               
+                               UiDialog.open(this);
+                       }
+                       else {
+                               Ajax.api(this, {
+                                       actionName: actionName
+                               });
+                       }
+               },
+               
+               /**
+                * Handles form submit and input validation.
+                * 
+                * @param       {Event}         event           event object
+                * @protected
+                */
+               _submit: function(event) {
+                       event.preventDefault();
+                       
+                       var label = elById('wcfUiUserEditorExpiresLabel');
+                       var innerError = label.previousElementSibling;
+                       if (innerError.classList.contains('innerError')) elRemove(innerError);
+                       
+                       var expires = '';
+                       if (!elById('wcfUiUserEditorNeverExpires').checked) {
+                               expires = elById('wcfUiUserEditorExpiresDatePicker').value;
+                               if (expires === '') {
+                                       innerError = elCreate('small');
+                                       innerError.className = 'innerError';
+                                       innerError.textContent = Language.get('wcf.global.form.error.empty');
+                                       label.parentNode.insertBefore(innerError, label);
+                               }
+                       }
+                       
+                       var parameters = {};
+                       parameters[_actionName + 'Expires'] = expires;
+                       parameters[_actionName + 'Reason'] = elById('wcfUiUserEditorReason').value.trim();
+                       
+                       Ajax.api(this, {
+                               actionName: _actionName,
+                               parameters: parameters
+                       });
+               },
+               
+               _ajaxSuccess: function(data) {
+                       switch (data.actionName) {
+                               case 'ban':
+                               case 'unban':
+                                       elData(_userHeader, 'banned', (data.actionName === 'ban'));
+                                       elBySel('.jsButtonUserBan', _userHeader).textContent = Language.get('wcf.user.' + (data.actionName === 'ban' ? 'unban' : 'ban'));
+                                       
+                                       var contentTitle = elBySel('.contentTitle', _userHeader);
+                                       var banIcon = elBySel('.jsUserBanned', contentTitle);
+                                       if (data.actionName === 'ban') {
+                                               banIcon = elCreate('span');
+                                               banIcon.className = 'icon icon16 fa-lock jsUserBanned jsTooltip';
+                                               banIcon.title = Language.get('wcf.user.banned');
+                                               contentTitle.appendChild(banIcon);
+                                       }
+                                       else if (banIcon) {
+                                               elRemove(banIcon);
+                                       }
+                                       
+                                       break;
+                               
+                               case 'disableAvatar':
+                               case 'enableAvatar':
+                                       elData(_userHeader, 'disable-avatar', (data.actionName === 'disableAvatar'));
+                                       elBySel('.jsButtonUserDisableAvatar', _userHeader).textContent = Language.get('wcf.user.' + (data.actionName === 'disableAvatar' ? 'enable' : 'disable') + 'Avatar');
+                                       
+                                       break;
+                               
+                               case 'disableSignature':
+                               case 'enableSignature':
+                                       elData(_userHeader, 'disable-signature', (data.actionName === 'disableSignature'));
+                                       elBySel('.jsButtonUserDisableSignature', _userHeader).textContent = Language.get('wcf.user.' + (data.actionName === 'disableSignature' ? 'enable' : 'disable') + 'Signature');
+                                       
+                                       break;
+                               
+                               case 'enable':
+                               case 'disable':
+                                       elData(_userHeader, 'is-disabled', (data.actionName === 'disable'));
+                                       elBySel('.jsButtonUserEnable', _userHeader).textContent = Language.get('wcf.acp.user.' + (data.actionName === 'enable' ? 'disable' : 'enable'));
+                                       
+                                       break;
+                       }
+                       
+                       if (data.actionName === 'ban' || data.actionName === 'disableAvatar' || data.actionName === 'disableSignature') {
+                               UiDialog.close(this);
+                       }
+                       
+                       UiNotification.show();
+               },
+               
+               _ajaxSetup: function () {
+                       return {
+                               data: {
+                                       className: 'wcf\\data\\user\\UserAction',
+                                       objectIDs: [ elData(_userHeader, 'object-id') ]
+                               }
+                       };
+               },
+               
+               _dialogSetup: function() {
+                       return {
+                               id: 'wcfUiUserEditor',
+                               options: {
+                                       onSetup: (function (content) {
+                                               elById('wcfUiUserEditorNeverExpires').addEventListener('change', function () {
+                                                       window[(this.checked) ? 'elHide' : 'elShow'](elById('wcfUiUserEditorExpiresSettings'));
+                                               });
+                                               
+                                               elBySel('button.buttonPrimary', content).addEventListener(WCF_CLICK_EVENT, this._submit.bind(this));
+                                       }).bind(this),
+                                       onShow: function(content) {
+                                               UiDialog.setTitle('wcfUiUserEditor', Language.get('wcf.user.' + _actionName + '.confirmMessage'));
+                                               
+                                               var label = elById('wcfUiUserEditorReason').nextElementSibling;
+                                               var phrase = 'wcf.user.' + _actionName + '.reason.description';
+                                               label.textContent = Language.get(phrase);
+                                               window[(label.textContent === phrase) ? 'elHide' : 'elShow'](label);
+                                               
+                                               label = elById('wcfUiUserEditorNeverExpires').nextElementSibling;
+                                               label.textContent = Language.get('wcf.user.' + _actionName + '.neverExpires');
+                                               
+                                               label = elBySel('label[for="wcfUiUserEditorExpires"]', content);
+                                               label.textContent = Language.get('wcf.user.' + _actionName + '.expires');
+                                               
+                                               label = elById('wcfUiUserEditorExpiresLabel');
+                                               label.textContent = Language.get('wcf.user.' + _actionName + '.expires.description');
+                                       }
+                               },
+                               source: '<div class="section">'
+                                               + '<dl>'
+                                                       + '<dt><label for="wcfUiUserEditorReason">' + Language.get('wcf.global.reason') + '</label></dt>'
+                                                       + '<dd><textarea id="wcfUiUserEditorReason" cols="40" rows="3"></textarea><small></small></dd>'
+                                               + '</dl>'
+                                               + '<dl>'
+                                                       + '<dt></dt>'
+                                                       + '<dd><label><input type="checkbox" id="wcfUiUserEditorNeverExpires" checked> <span></span></label></dd>'
+                                               + '</dl>'
+                                               + '<dl id="wcfUiUserEditorExpiresSettings" style="display: none">'
+                                                       + '<dt><label for="wcfUiUserEditorExpires"></label></dt>'
+                                                       + '<dd>'
+                                                               + '<input type="date" name="wcfUiUserEditorExpires" id="wcfUiUserEditorExpires" class="medium" min="' + new Date(TIME_NOW * 1000).toISOString() + '" data-ignore-timezone="true">'
+                                                               + '<small id="wcfUiUserEditorExpiresLabel"></small>'
+                                                       + '</dd>'
+                                               +'</dl>'
+                                       + '</div>'
+                                       + '<div class="formSubmit"><button class="buttonPrimary">' + Language.get('wcf.global.button.submit') + '</button></div>'
+                       };
+               }
+       };
+});
index 7f626bf867eca25b14f8b323f2aa0de957d6ba84..c5b296ca3d1231f7ed8c694329e93e16b1d39f8e 100644 (file)
@@ -56,7 +56,7 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio
        /**
         * @inheritDoc
         */
-       protected $requireACP = ['create', 'delete', 'disable', 'enable'];
+       protected $requireACP = ['create', 'delete'];
        
        /**
         * Validates permissions and parameters.
index 37b4d8b0f31c02a15cef875bf11581a69a26cf9f..e127397ee4709d1d29a2d8c8b313fb136a403d82 100644 (file)
                        padding-bottom: 10px;
                        
                        > .contentTitle {
+                               align-items: center;
+                               display: flex;
                                flex: 0 0 auto;
                                margin-right: 10px;
+                               
+                               > .icon {
+                                       margin-left: 5px;
+                               }
                        }
                        
                        > .userTitleBadge {
                                padding: 5px 0;
                                position: absolute;
                                visibility: hidden;
+                               z-index: 1;
                                
                                @include screen-md-up {
                                        right: 0;