Add (un)confirm email address acp actions
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / js / WoltLabSuite / Core / Acp / Ui / User / Editor.js
1 /**
2 * User editing capabilities for the user list.
3 *
4 * @author Alexander Ebert
5 * @copyright 2001-2019 WoltLab GmbH
6 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
7 * @module WoltLabSuite/Core/Acp/Ui/User/Editor
8 * @since 3.1
9 */
10 define(['Ajax', 'Core', 'EventHandler', 'Language', 'Ui/Notification', 'Ui/SimpleDropdown', 'WoltLabSuite/Core/Acp/Ui/User/Content/Remove/Handler'], function(Ajax, Core, EventHandler, Language, UiNotification, UiSimpleDropdown, RemoveContentHandler) {
11 "use strict";
12
13 /**
14 * @exports WoltLabSuite/Core/Acp/Ui/User/Editor
15 */
16 return {
17 /**
18 * Initializes the edit dropdown for each user.
19 */
20 init: function () {
21 elBySelAll('.jsUserRow', undefined, this._initUser.bind(this));
22
23 EventHandler.add('com.woltlab.wcf.acp.user', 'refresh', this._refreshUsers.bind(this));
24 },
25
26 /**
27 * Initializes the edit dropdown for a user.
28 *
29 * @param {Element} userRow
30 * @protected
31 */
32 _initUser: function (userRow) {
33 var userId = ~~elData(userRow, 'object-id');
34 var dropdownMenu = UiSimpleDropdown.getDropdownMenu('userListDropdown' + userId);
35 var legacyButtonContainer = elBySel('.jsLegacyButtons', userRow);
36
37 if (dropdownMenu.childElementCount === 0 && legacyButtonContainer.childElementCount === 0) {
38 elBySel('.dropdownToggle', userRow).classList.add('disabled');
39 return;
40 }
41
42 UiSimpleDropdown.registerCallback('userListDropdown' + userId, (function (identifier, action) {
43 if (action === 'open') {
44 this._rebuild(userId, dropdownMenu, legacyButtonContainer);
45 }
46 }).bind(this));
47
48 var editLink = elBySel('.jsEditLink', dropdownMenu);
49 if (editLink !== null) {
50 elBySel('.dropdownToggle', userRow).addEventListener('dblclick', function (event) {
51 event.preventDefault();
52
53 editLink.click();
54 });
55 }
56
57 var sendNewPassword = elBySel('.jsSendNewPassword', dropdownMenu);
58 if (sendNewPassword !== null) {
59 sendNewPassword.addEventListener(WCF_CLICK_EVENT, function (event) {
60 event.preventDefault();
61
62 // emulate clipboard selection
63 EventHandler.fire('com.woltlab.wcf.clipboard', 'com.woltlab.wcf.user', {
64 data: {
65 actionName: 'com.woltlab.wcf.user.sendNewPassword',
66 parameters: {
67 confirmMessage: Language.get('wcf.acp.user.action.sendNewPassword.confirmMessage'),
68 objectIDs: [userId]
69 }
70 },
71 responseData: {
72 actionName: 'com.woltlab.wcf.user.sendNewPassword',
73 objectIDs: [userId]
74 }
75 });
76 });
77 }
78
79 var deleteContent = elBySel('.jsDeleteContent', dropdownMenu);
80 if (deleteContent !== null) {
81 new RemoveContentHandler(deleteContent, userId);
82 }
83
84 var toggleConfirmEmail = elBySel('.jsConfirmEmailToggle', dropdownMenu);
85 if (toggleConfirmEmail !== null) {
86 toggleConfirmEmail.addEventListener(WCF_CLICK_EVENT, function (event) {
87 event.preventDefault();
88
89 Ajax.api({
90 _ajaxSetup: function () {
91 return {
92 data: {
93 actionName: (elDataBool(userRow, 'email-confirmed') ? 'un' : '') + 'confirmEmail',
94 className: 'wcf\\data\\user\\UserAction',
95 objectIDs: [userId]
96 }
97 };
98 }
99 }, null, function (data) {
100 elBySelAll('.jsUserRow', undefined, function(userRow) {
101 var userId = parseInt(elData(userRow, 'object-id'));
102 if (data.objectIDs.indexOf(userId) !== -1) {
103 var confirmEmailButton = elBySel('.jsConfirmEmailToggle', UiSimpleDropdown.getDropdownMenu('userListDropdown' + userId));
104
105 switch (data.actionName) {
106 case 'confirmEmail':
107 elData(userRow, 'email-confirmed', 'true');
108 confirmEmailButton.textContent = elData(confirmEmailButton, 'unconfirm-email-message');
109 break;
110
111 case 'unconfirmEmail':
112 elData(userRow, 'email-confirmed', 'false');
113 confirmEmailButton.textContent = elData(confirmEmailButton, 'confirm-email-message');
114 break;
115
116 default:
117 throw new Error("Unreachable");
118 }
119 }
120 });
121
122 UiNotification.show();
123 });
124 });
125 }
126 },
127
128 /**
129 * Rebuilds the dropdown by adding wrapper links for legacy buttons,
130 * that will eventually receive the click event.
131 *
132 * @param {int} userId
133 * @param {Element} dropdownMenu
134 * @param {Element} legacyButtonContainer
135 * @protected
136 */
137 _rebuild: function (userId, dropdownMenu, legacyButtonContainer) {
138 elBySelAll('.jsLegacyItem', dropdownMenu, elRemove);
139
140 // inject buttons
141 var button, item, link;
142 var items = [];
143 var deleteButton = null;
144 for (var i = 0, length = legacyButtonContainer.childElementCount; i < length; i++) {
145 button = legacyButtonContainer.children[i];
146 if (button.classList.contains('jsDeleteButton')) {
147 deleteButton = button;
148 continue;
149 }
150
151 item = elCreate('li');
152 item.className = 'jsLegacyItem';
153 item.innerHTML = '<a href="#"></a>';
154
155 link = item.children[0];
156 link.textContent = elData(button, 'tooltip') || button.title;
157 (function(button) {
158 link.addEventListener(WCF_CLICK_EVENT, function (event) {
159 event.preventDefault();
160
161 // forward click onto original button
162 if (button.nodeName === 'A') button.click();
163 else Core.triggerEvent(button, WCF_CLICK_EVENT);
164 });
165 })(button);
166
167 items.push(item);
168 }
169
170 while (items.length) {
171 dropdownMenu.insertBefore(items.pop(), dropdownMenu.firstElementChild);
172 }
173
174 if (deleteButton !== null) {
175 elBySel('.jsDispatchDelete', dropdownMenu).addEventListener(WCF_CLICK_EVENT, function (event) {
176 event.preventDefault();
177
178 Core.triggerEvent(deleteButton, WCF_CLICK_EVENT);
179 });
180 }
181
182 // check if there are visible items before each divider
183 for (i = 0, length = dropdownMenu.childElementCount; i < length; i++) {
184 elShow(dropdownMenu.children[i]);
185 }
186
187 var hasItem = false;
188 for (i = 0, length = dropdownMenu.childElementCount; i < length; i++) {
189 item = dropdownMenu.children[i];
190 if (item.classList.contains('dropdownDivider')) {
191 if (!hasItem) elHide(item);
192 }
193 else {
194 hasItem = true;
195 }
196 }
197 },
198
199 _refreshUsers: function (data) {
200 elBySelAll('.jsUserRow', undefined, function(userRow) {
201 var userId = parseInt(elData(userRow, 'object-id'));
202 if (data.userIds.indexOf(userId) !== -1) {
203 var userStatusIcons = elBySel('.userStatusIcons', userRow);
204
205 var banned = elDataBool(userRow, 'banned');
206 var iconBanned = elBySel('.jsUserStatusBanned', userRow);
207 if (banned && iconBanned === null) {
208 iconBanned = elCreate('span');
209 iconBanned.className = 'icon icon16 fa-lock jsUserStatusBanned jsTooltip';
210 iconBanned.title = Language.get('wcf.user.status.banned');
211 userStatusIcons.insertBefore(iconBanned, null);
212 }
213 else if (!banned && iconBanned !== null) {
214 elRemove(iconBanned);
215 }
216
217 var isDisabled = elDataBool(userRow, 'enabled') === false;
218 var iconIsDisabled = elBySel('.jsUserStatusIsDisabled', userRow);
219 if (isDisabled && iconIsDisabled === null) {
220 iconIsDisabled = elCreate('span');
221 iconIsDisabled.className = 'icon icon16 fa-power-off jsUserStatusIsDisabled jsTooltip';
222 iconIsDisabled.title = Language.get('wcf.user.status.isDisabled');
223 userStatusIcons.appendChild(iconIsDisabled);
224 }
225 else if (!isDisabled && iconIsDisabled !== null) {
226 elRemove(iconIsDisabled);
227 }
228 }
229 })
230 }
231 };
232 });