EGroupware /
egroupware
| 1 | "use strict"; |
||
| 2 | /** |
||
| 3 | * EGroupware - Admin - Javascript UI |
||
| 4 | * |
||
| 5 | * @link: https://www.egroupware.org |
||
| 6 | * @package filemanager |
||
| 7 | * @author Ralf Becker <RalfBecker-AT-outdoor-training.de> |
||
| 8 | * @copyright (c) 2013-20 by Ralf Becker <RalfBecker-AT-outdoor-training.de> |
||
| 9 | * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License |
||
| 10 | */ |
||
| 11 | var __extends = (this && this.__extends) || (function () { |
||
| 12 | var extendStatics = function (d, b) { |
||
| 13 | extendStatics = Object.setPrototypeOf || |
||
| 14 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || |
||
| 15 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; |
||
| 16 | return extendStatics(d, b); |
||
| 17 | }; |
||
| 18 | return function (d, b) { |
||
| 19 | extendStatics(d, b); |
||
| 20 | function __() { this.constructor = d; } |
||
| 21 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); |
||
| 22 | }; |
||
| 23 | })(); |
||
| 24 | Object.defineProperty(exports, "__esModule", { value: true }); |
||
| 25 | /*egw:uses |
||
| 26 | /api/js/jsapi/egw_app.js |
||
| 27 | */ |
||
| 28 | require("jquery"); |
||
| 29 | require("jqueryui"); |
||
| 30 | require("../jsapi/egw_global"); |
||
| 31 | require("../etemplate/et2_types"); |
||
| 32 | var egw_app_1 = require("../../api/js/jsapi/egw_app"); |
||
| 33 | /** |
||
| 34 | * UI for Admin |
||
| 35 | * |
||
| 36 | * @augments AppJS |
||
| 37 | */ |
||
| 38 | var AdminApp = /** @class */ (function (_super) { |
||
| 39 | __extends(AdminApp, _super); |
||
| 40 | /** |
||
| 41 | * Constructor |
||
| 42 | * |
||
| 43 | * @memberOf app.classes.admin |
||
| 44 | */ |
||
| 45 | function AdminApp() { |
||
| 46 | var _this = |
||
| 47 | // call parent |
||
| 48 | _super.call(this) || this; |
||
| 49 | _this.appname = 'admin'; |
||
| 50 | /** |
||
| 51 | * reference to iframe |
||
| 52 | * |
||
| 53 | * {et2_iframe} |
||
| 54 | */ |
||
| 55 | _this.iframe = null; |
||
| 56 | /** |
||
| 57 | * reference to nextmatch |
||
| 58 | * |
||
| 59 | * {et2_extension_nextmatch} |
||
| 60 | */ |
||
| 61 | _this.nm = null; |
||
| 62 | /** |
||
| 63 | * Reference to div to hold AJAX loadable pages |
||
| 64 | * |
||
| 65 | * {et2_box} |
||
| 66 | */ |
||
| 67 | _this.ajax_target = null; |
||
| 68 | /** |
||
| 69 | * Reference to ACL edit dialog (not the list) |
||
| 70 | */ |
||
| 71 | _this.acl_dialog = null; |
||
| 72 | _this.tree = null; |
||
| 73 | /** |
||
| 74 | * No SSL |
||
| 75 | */ |
||
| 76 | _this.SSL_NONE = 0; |
||
| 77 | /** |
||
| 78 | * STARTTLS on regular tcp connection/port |
||
| 79 | */ |
||
| 80 | _this.SSL_STARTTLS = 1; |
||
| 81 | /** |
||
| 82 | * SSL (inferior to TLS!) |
||
| 83 | */ |
||
| 84 | _this.SSL_SSL = 3; |
||
| 85 | /** |
||
| 86 | * require TLS version 1+, no SSL version 2 or 3 |
||
| 87 | */ |
||
| 88 | _this.SSL_TLS = 2; |
||
| 89 | /** |
||
| 90 | * if set, verify certifcate (currently not implemented in Horde_Imap_Client!) |
||
| 91 | */ |
||
| 92 | _this.SSL_VERIFY = 8; |
||
| 93 | return _this; |
||
| 94 | } |
||
| 95 | /** |
||
| 96 | * Destructor |
||
| 97 | */ |
||
| 98 | AdminApp.prototype.destroy = function (_app) { |
||
| 99 | this.iframe = null; |
||
| 100 | this.nm = null; |
||
| 101 | this.acl_dialog = null; |
||
| 102 | this.tree = null; |
||
| 103 | // call parent |
||
| 104 | _super.prototype.destroy.call(this, _app); |
||
| 105 | }; |
||
| 106 | /** |
||
| 107 | * This function is called when the etemplate2 object is loaded |
||
| 108 | * and ready. If you must store a reference to the et2 object, |
||
| 109 | * make sure to clean it up in destroy(). |
||
| 110 | * |
||
| 111 | * @param {etemplate2} _et2 |
||
| 112 | * @param {string} _name name of template loaded |
||
| 113 | */ |
||
| 114 | AdminApp.prototype.et2_ready = function (_et2, _name) { |
||
| 115 | // call parent |
||
| 116 | _super.prototype.et2_ready.call(this, _et2, _name); |
||
| 117 | switch (_name) { |
||
| 118 | case 'admin.index': |
||
| 119 | var iframe = this.iframe = this.et2.getWidgetById('iframe'); |
||
| 120 | this.nm = this.et2.getWidgetById('nm'); |
||
| 121 | this.groups = this.et2.getWidgetById('groups'); |
||
| 122 | this.groups.set_disabled(true); |
||
| 123 | this.ajax_target = this.et2.getWidgetById('ajax_target'); |
||
| 124 | this.tree = this.et2.getWidgetById('tree'); |
||
| 125 | if (iframe) { |
||
| 126 | var self = this; |
||
| 127 | jQuery(iframe.getDOMNode()).off('load.admin') |
||
| 128 | .bind('load.admin', function () { |
||
| 129 | if (this.contentDocument.location.href.match(/(\/admin\/|\/admin\/index.php|menuaction=admin.admin_ui.index)/)) { |
||
| 130 | this.contentDocument.location.href = 'about:blank'; // stops redirect from admin/index.php |
||
| 131 | self.load(); // load own top-level index aka user-list |
||
| 132 | } |
||
| 133 | self._hide_navbar.call(self); |
||
| 134 | }); |
||
| 135 | } |
||
| 136 | if (this.ajax_target && this.et2.getArrayMgr('content').getEntry('ajax_target')) { |
||
| 137 | this.load(this.et2.getArrayMgr('content').getEntry('ajax_target')); |
||
| 138 | } |
||
| 139 | break; |
||
| 140 | case 'admin.customfield_edit': |
||
| 141 | // Load settings appropriate to currently set type |
||
| 142 | var widget = _et2.widgetContainer.getWidgetById('cf_type'); |
||
| 143 | this.cf_type_change(null, widget); |
||
| 144 | break; |
||
| 145 | case 'admin.mailaccount': |
||
| 146 | this.account_hide_not_applying(); |
||
| 147 | break; |
||
| 148 | case 'admin.cmds': |
||
| 149 | var selected = this.et2.getWidgetById('nm').getSelection(); |
||
| 150 | if (selected && selected.ids.length == 1) { |
||
| 151 | this.cmds_onselect(selected.ids); |
||
| 152 | } |
||
| 153 | else { |
||
| 154 | this.et2.getWidgetById('splitter').dock(); |
||
| 155 | } |
||
| 156 | break; |
||
| 157 | } |
||
| 158 | }; |
||
| 159 | /** |
||
| 160 | * Show given url in (visible) iframe or nextmatch with accounts (!_url) |
||
| 161 | * |
||
| 162 | * @param {string} [_url=] url to show in iframe or nothing for showing |
||
| 163 | */ |
||
| 164 | AdminApp.prototype.load = function (_url) { |
||
| 165 | if (this.iframe && this.iframe.getDOMNode().contentDocument.location.href |
||
| 166 | .match(/menuaction=admin.admin_statistics.submit.+required=true/) && (!_url || |
||
| 167 | !_url.match(/statistics=(postpone|canceled|submitted)/))) { |
||
| 168 | this.egw.message(this.egw.lang('Please submit (or postpone) statistic first'), 'info'); |
||
| 169 | return; // do not allow to leave statistics submit |
||
| 170 | } |
||
| 171 | // url outside EGroupware eg. eSyncPro linking to wikipedia |
||
| 172 | if (_url && _url.indexOf(this.egw.webserverUrl) == -1) { |
||
| 173 | window.open(_url, '_blank'); |
||
| 174 | return; |
||
| 175 | } |
||
| 176 | var ajax = false; |
||
| 177 | if (_url) { |
||
| 178 | // Try to load it without the iframe |
||
| 179 | ajax = _url.match(/ajax=true/) && _url.match(/menuaction=/); |
||
| 180 | if (ajax) { |
||
| 181 | if (this.ajax_target.node.children.length) { |
||
| 182 | // Node has children already? Check for loading over an |
||
| 183 | // existing etemplate, and remove it first |
||
| 184 | jQuery(this.ajax_target.node.children).each(function () { |
||
| 185 | var old = etemplate2.getById(this.id); |
||
| 186 | if (old) |
||
| 187 | old.clear(); |
||
| 188 | }); |
||
| 189 | jQuery(this.ajax_target.node).empty(); |
||
| 190 | } |
||
| 191 | this.egw.json(framework.activeApp.getMenuaction('ajax_exec', _url), |
||
| 192 | // It's important that the context is null, or etemplate2 |
||
| 193 | // won't load the template properly |
||
| 194 | [_url], this._ajax_load_callback, null, true, this).sendRequest(); |
||
| 195 | } |
||
| 196 | else { |
||
| 197 | this.iframe.set_src(_url); |
||
| 198 | } |
||
| 199 | var m = _url.match(/menuaction=([^&]+)(?:.*appname=(\w+))?/); |
||
| 200 | if (m && m.length >= 2) { |
||
| 201 | var app = m[2] ? m[2] : m[1].split('.')[0]; |
||
| 202 | this.tree.set_value('/apps/' + app + '/' + m[1]); |
||
| 203 | } |
||
| 204 | } |
||
| 205 | else { |
||
| 206 | this.egw.app_header(''); |
||
| 207 | // blank iframe, to not keep something running there |
||
| 208 | this.iframe.getDOMNode().contentDocument.location.href = 'about:blank'; |
||
| 209 | } |
||
| 210 | this.iframe.set_disabled(!_url || ajax); |
||
| 211 | this.nm.set_disabled(!!_url || ajax); |
||
| 212 | this.groups.set_disabled(true); |
||
| 213 | this.ajax_target.set_disabled(!ajax); |
||
| 214 | }; |
||
| 215 | /** |
||
| 216 | * Observer method receives update notifications from all applications |
||
| 217 | * |
||
| 218 | * App is responsible for only reacting to "messages" it is interested in! |
||
| 219 | * |
||
| 220 | * @param {string} _msg message (already translated) to show, eg. 'Entry deleted' |
||
| 221 | * @param {string} _app application name |
||
| 222 | * @param {(string|number)} _id id of entry to refresh or null |
||
| 223 | * @param {string} _type either 'update', 'edit', 'delete', 'add' or null |
||
| 224 | * - update: request just modified data from given rows. Sorting is not considered, |
||
| 225 | * so if the sort field is changed, the row will not be moved. |
||
| 226 | * - edit: rows changed, but sorting may be affected. Requires full reload. |
||
| 227 | * - delete: just delete the given rows clientside (no server interaction neccessary) |
||
| 228 | * - add: requires full reload for proper sorting |
||
| 229 | * @param {string} _msg_type 'error', 'warning' or 'success' (default) |
||
| 230 | * @param {string} _targetapp which app's window should be refreshed, default current |
||
| 231 | * @return {false|*} false to stop regular refresh, thought all observers are run |
||
| 232 | */ |
||
| 233 | AdminApp.prototype.observer = function (_msg, _app, _id, _type, _msg_type, _targetapp) { |
||
| 234 | switch (_app) { |
||
| 235 | case 'admin': |
||
| 236 | // if iframe is used --> refresh it |
||
| 237 | var iframe_node = this.iframe ? this.iframe.getDOMNode() : undefined; |
||
| 238 | var iframe_url = iframe_node ? iframe_node.contentDocument.location.href : undefined; |
||
| 239 | if (_id && iframe_url != 'about:blank') { |
||
| 240 | var refresh_done = false; |
||
| 241 | // Try for intelligent et2 refresh inside iframe |
||
| 242 | if (iframe_node && iframe_node.contentWindow && iframe_node.contentWindow.etemplate2) { |
||
| 243 | var templates = iframe_node.contentWindow.etemplate2.getByApplication('admin'); |
||
| 244 | for (var i = 0; i < templates.length; i++) { |
||
| 245 | templates[i].refresh(_msg, _app, _id, _type); |
||
| 246 | refresh_done = true; |
||
| 247 | } |
||
| 248 | } |
||
| 249 | if (!refresh_done) // --> reload iframe |
||
| 250 | { |
||
| 251 | this.load(iframe_url); |
||
| 252 | } |
||
| 253 | return false; // --> no regular refresh |
||
| 254 | } |
||
| 255 | // invalidate client-side account-cache |
||
| 256 | this.egw.invalidate_account(_id, _type); |
||
| 257 | // group deleted, added or updated |
||
| 258 | if (_id < 0) { |
||
| 259 | var tree = this.et2.getWidgetById('tree'); |
||
| 260 | var nm = this.et2.getWidgetById('nm'); |
||
| 261 | switch (_type) { |
||
| 262 | case 'delete': |
||
| 263 | tree.deleteItem('/groups/' + _id, false); |
||
| 264 | if (nm) |
||
| 265 | nm.getInstanceManager().submit(); |
||
| 266 | break; |
||
| 267 | default: // add, update, edit, null |
||
| 268 | if (nm) { |
||
| 269 | var activeFilters = nm.activeFilters; |
||
| 270 | nm.getInstanceManager().submit(); |
||
| 271 | var nm = this.et2.getWidgetById('nm'); |
||
| 272 | nm.applyFilters(activeFilters); |
||
| 273 | } |
||
| 274 | } |
||
| 275 | var refreshTree = this.et2.getWidgetById('tree'); |
||
| 276 | if (refreshTree) |
||
| 277 | refreshTree.refreshItem('/groups'); |
||
| 278 | return false; // --> no regular refresh |
||
| 279 | } |
||
| 280 | // not a user or group, eg. categories |
||
| 281 | else if (!_id) { |
||
| 282 | // Try just refreshing the nextmatch |
||
| 283 | if (this.nm) { |
||
| 284 | this.nm.refresh(); |
||
| 285 | } |
||
| 286 | if (this.groups) { |
||
| 287 | this.groups.refresh(); |
||
| 288 | } |
||
| 289 | if (this.et2 && this.et2.getWidgetById('nm') && this.nm !== this.et2.getWidgetById('nm')) { |
||
| 290 | this.et2.getWidgetById('nm').refresh(); |
||
| 291 | } |
||
| 292 | else { |
||
| 293 | // Load something else |
||
| 294 | this.load(); |
||
| 295 | } |
||
| 296 | return false; // --> no regular refresh needed |
||
| 297 | } |
||
| 298 | } |
||
|
0 ignored issues
–
show
Comprehensibility
introduced
by
Loading history...
|
|||
| 299 | }; |
||
| 300 | /** |
||
| 301 | * Hide navbar for idots template |
||
| 302 | * |
||
| 303 | * Just a hack for old idots, not neccesary for jdots |
||
| 304 | */ |
||
| 305 | AdminApp.prototype._hide_navbar = function () { |
||
| 306 | var document = this.iframe.getDOMNode().contentDocument; |
||
| 307 | if (!document) |
||
| 308 | return; // nothing we can do ... |
||
| 309 | // set white background, as transparent one lets account-list show through |
||
| 310 | document.getElementsByTagName('body')[0].style.backgroundColor = 'white'; |
||
| 311 | // hide navbar elements |
||
| 312 | var ids2hide = ['divLogo', 'topmenu', 'divAppIconBar', 'divStatusBar', 'tdSidebox', 'divAppboxHeader']; |
||
| 313 | for (var i = 0; i < ids2hide.length; ++i) { |
||
| 314 | var elem = document.getElementById(ids2hide[i]); |
||
| 315 | if (elem) |
||
| 316 | elem.style.display = 'none'; |
||
| 317 | } |
||
| 318 | }; |
||
| 319 | /** |
||
| 320 | * Set location of iframe for given _action and _sender (row) |
||
| 321 | * |
||
| 322 | * @param _action |
||
| 323 | * @param _senders |
||
| 324 | */ |
||
| 325 | AdminApp.prototype.iframe_location = function (_action, _senders) { |
||
| 326 | var id = _senders[0].id.split('::'); |
||
| 327 | var url = _action.data.url.replace(/(%24|\$)id/, id[1]); |
||
| 328 | this.load(url); |
||
| 329 | }; |
||
| 330 | /** |
||
| 331 | * Callback to load an etemplate |
||
| 332 | * |
||
| 333 | * @param {Object[]} _data |
||
| 334 | */ |
||
| 335 | AdminApp.prototype._ajax_load_callback = function (_data) { |
||
| 336 | if (!_data || _data.type != undefined) |
||
| 337 | return; |
||
| 338 | // Insert the content, etemplate will load into it |
||
| 339 | jQuery(this.ajax_target.node).append(typeof _data === 'string' ? _data : _data[0]); |
||
| 340 | }; |
||
| 341 | /** |
||
| 342 | * Link hander for jDots template to just reload our iframe, instead of reloading whole admin app |
||
| 343 | * |
||
| 344 | * @param _url |
||
| 345 | * @return boolean true, if linkHandler took care of link, false otherwise |
||
| 346 | */ |
||
| 347 | AdminApp.prototype.linkHandler = function (_url) { |
||
| 348 | var matches = _url.match(/menuaction=admin.admin_ui.index.*&load=([^&]+)/); |
||
| 349 | if (_url != 'about:blank' && (this.iframe != null && !_url.match('menuaction=admin.admin_ui.index') || matches)) { |
||
| 350 | if (matches) { |
||
| 351 | _url = _url.replace(/menuaction=admin.admin_ui.index/, 'menuaction=' + matches[1]).replace(/&(load=[^&]+)/g, ''); |
||
| 352 | } |
||
| 353 | this.load(_url); |
||
| 354 | return true; |
||
| 355 | } |
||
| 356 | // can not load our own index page, has to be done by framework |
||
| 357 | return false; |
||
| 358 | }; |
||
| 359 | /** |
||
| 360 | * Run an admin module / onclick callback for tree |
||
| 361 | * |
||
| 362 | * @param {string} _id id of clicked node |
||
| 363 | * @param {et2_tree} _widget reference to tree widget |
||
| 364 | */ |
||
| 365 | AdminApp.prototype.run = function (_id, _widget) { |
||
| 366 | var link = _widget.getUserData(_id, 'link'); |
||
| 367 | this.groups.set_disabled(true); |
||
| 368 | if (_id == '/accounts' || _id.substr(0, 8) == '/groups/') { |
||
| 369 | this.load(); |
||
| 370 | var parts = _id.split('/'); |
||
| 371 | this.nm.applyFilters({ filter: parts[2] ? parts[2] : '', search: '' }); |
||
| 372 | } |
||
| 373 | else if (_id === '/groups') { |
||
| 374 | this.load(); |
||
| 375 | this.group_list(); |
||
| 376 | } |
||
| 377 | else if (typeof link == 'undefined') { |
||
| 378 | _widget.openItem(_id, 'toggle'); |
||
| 379 | } |
||
| 380 | else if (link[0] == '/' || link.substr(0, 4) == 'http') { |
||
| 381 | link += (link.indexOf('?') >= 0 ? '&' : '?') + 'nonavbar=1'; |
||
| 382 | this.load(link); |
||
| 383 | } |
||
| 384 | else if (link.substr(0, 11) == 'javascript:') { |
||
| 385 | eval(link.substr(11)); |
||
|
0 ignored issues
–
show
|
|||
| 386 | } |
||
| 387 | }; |
||
| 388 | /** |
||
| 389 | * Show the group list in the main window |
||
| 390 | */ |
||
| 391 | AdminApp.prototype.group_list = function () { |
||
| 392 | this.nm.set_disabled(true); |
||
| 393 | this.groups.set_disabled(false); |
||
| 394 | }; |
||
| 395 | /** |
||
| 396 | * View, edit or delete a group callback for tree |
||
| 397 | * |
||
| 398 | * @param {object} _action egwAction |
||
| 399 | * @param {array} _senders egwActionObject _senders[0].id holds id |
||
| 400 | */ |
||
| 401 | AdminApp.prototype.group = function (_action, _senders) { |
||
| 402 | // Tree IDs look like /groups/ID, nm uses admin::ID |
||
| 403 | var from_nm = _senders[0].id.indexOf('::') > 0; |
||
| 404 | var account_id = _senders[0].id.split(from_nm ? '::' : '/')[from_nm ? 1 : 2]; |
||
| 405 | switch (_action.id) { |
||
| 406 | case 'view': |
||
| 407 | this.run(from_nm ? '/groups/' + account_id : _senders[0].id, this.et2.getWidgetById('tree')); |
||
| 408 | break; |
||
| 409 | case 'delete': |
||
| 410 | this.egw.json('admin_account::ajax_delete_group', [account_id, _action.data, this.et2._inst.etemplate_exec_id]).sendRequest(); |
||
| 411 | break; |
||
| 412 | default: |
||
| 413 | if (!_action.data.url) { |
||
| 414 | alert('Missing url in action ' + _action.id + '!'); |
||
|
0 ignored issues
–
show
Debugging Code
Best Practice
introduced
by
|
|||
| 415 | break; |
||
| 416 | } |
||
| 417 | var url = unescape(_action.data.url).replace('$id', account_id); |
||
| 418 | if (url[0] != '/' && url.substr(0, 4) != 'http') { |
||
| 419 | url = this.egw.link('/index.php', url); |
||
| 420 | } |
||
| 421 | if (_action.data.popup || _action.data.width && _action.data.height) { |
||
| 422 | this.egw.open_link(url, '_blank', _action.data.popup ? _action.data.popup : _action.data.width + 'x' + _action.data.height); |
||
| 423 | } |
||
| 424 | else { |
||
| 425 | this.load(url); |
||
| 426 | } |
||
| 427 | break; |
||
| 428 | } |
||
| 429 | }; |
||
| 430 | /** |
||
| 431 | * Modify an ACL entry |
||
| 432 | * |
||
| 433 | * @param {object} _action egwAction |
||
| 434 | * @param {array} _senders egwActionObject _senders[0].id holds the id "admin::app:account:location" |
||
| 435 | */ |
||
| 436 | AdminApp.prototype.acl = function (_action, _senders) { |
||
| 437 | var ids = []; |
||
| 438 | for (var i = 0; i < _senders.length; ++i) { |
||
| 439 | ids.push(_senders[i].id.split('::').pop()); // remove "admin::" prefix |
||
| 440 | } |
||
| 441 | // For edit, set some data from the list since it's already there |
||
| 442 | var content = _senders[0].id ? jQuery.extend({}, egw.dataGetUIDdata(_senders[0].id).data) : {}; |
||
| 443 | switch (_action.id) { |
||
| 444 | case 'delete': |
||
| 445 | this._acl_delete(ids); |
||
| 446 | break; |
||
| 447 | case 'add': |
||
| 448 | // No content, even if they clicked on a row |
||
| 449 | // Defaults set by _acl_content() based on nm values |
||
| 450 | content = {}; |
||
|
0 ignored issues
–
show
|
|||
| 451 | // Fall through |
||
| 452 | case 'edit': |
||
| 453 | this._acl_dialog(content); |
||
| 454 | break; |
||
| 455 | } |
||
| 456 | }; |
||
| 457 | AdminApp.prototype._acl_delete = function (ids) { |
||
| 458 | var app = egw.app_name(); // can be either admin or preferences! |
||
| 459 | if (app != 'admin') |
||
| 460 | app = 'preferences'; |
||
| 461 | var className = app + '_acl'; |
||
| 462 | var callback = function (_button_id, _value) { |
||
| 463 | if (_button_id != et2_dialog.OK_BUTTON) |
||
| 464 | return; |
||
| 465 | var request = egw.json(className + '::ajax_change_acl', [ids, null, _value, this.et2._inst.etemplate_exec_id], this._acl_callback, this, false, this) |
||
| 466 | .sendRequest(); |
||
| 467 | }.bind(this); |
||
| 468 | var modifications = {}; |
||
| 469 | var dialog_options = { |
||
| 470 | callback: callback, |
||
| 471 | title: this.egw.lang('Delete'), |
||
| 472 | buttons: et2_dialog.BUTTONS_OK_CANCEL, |
||
| 473 | value: { |
||
| 474 | content: {}, |
||
| 475 | sel_options: {}, |
||
| 476 | modifications: modifications, |
||
| 477 | readonlys: {} |
||
| 478 | }, |
||
| 479 | template: egw.webserverUrl + '/admin/templates/default/acl.delete.xet' |
||
| 480 | }; |
||
| 481 | // Handle policy documentation tab here |
||
| 482 | if (this.egw.user('apps').policy) { |
||
| 483 | dialog_options['width'] = 550; |
||
| 484 | dialog_options['height'] = 350, |
||
| 485 | modifications.tabs = { |
||
| 486 | add_tabs: true, |
||
| 487 | tabs: [{ |
||
| 488 | label: egw.lang('Documentation'), |
||
| 489 | template: 'policy.admin_cmd', |
||
| 490 | prepend: false |
||
| 491 | }] |
||
| 492 | }; |
||
| 493 | } |
||
| 494 | // Create the dialog |
||
| 495 | this.acl_dialog = et2_createWidget("dialog", dialog_options, et2_dialog._create_parent(app)); |
||
| 496 | }; |
||
| 497 | /** |
||
| 498 | * Create the ACL edit dialog, including defaults & fetching what can be found |
||
| 499 | * |
||
| 500 | * @param content List of content for the dialog template |
||
| 501 | * @param sel_options optional select options |
||
| 502 | * @param {etemplate2} etemplate of etemplate that 'owns' the dialog |
||
| 503 | * @param {string} app Name of app |
||
| 504 | * @param {function} callback |
||
| 505 | */ |
||
| 506 | AdminApp.prototype._acl_dialog = function (content, sel_options, etemplate, app, callback) { |
||
| 507 | if (typeof content == 'undefined') |
||
| 508 | content = {}; |
||
| 509 | // Determine which application we're running as |
||
| 510 | app = app ? app : egw.app_name(); |
||
| 511 | // can be either admin or preferences! |
||
| 512 | if (app != 'admin') |
||
| 513 | app = 'preferences'; |
||
| 514 | // Get by ID, since this.et2 isn't always the ACL list |
||
| 515 | var et2 = etemplate ? etemplate : etemplate2.getById('admin-acl').widgetContainer; |
||
| 516 | var className = app + '_acl'; |
||
| 517 | var acl_rights = {}; |
||
| 518 | var readonlys = { acl: {} }; |
||
| 519 | var modifications = {}; |
||
| 520 | // Select options are already here, just pull them and pass along |
||
| 521 | sel_options = et2.getArrayMgr('sel_options').data || {}; |
||
| 522 | // Some defaults |
||
| 523 | if (et2 && et2.getWidgetById('nm')) { |
||
| 524 | // This is which checkboxes are available for each app |
||
| 525 | acl_rights = et2.getWidgetById('nm').getArrayMgr('content').getEntry('acl_rights') || {}; |
||
| 526 | if (!content.acl_appname) { |
||
| 527 | // Pre-set appname to currently selected |
||
| 528 | content.acl_appname = et2.getWidgetById('filter2').getValue() || ""; |
||
| 529 | } |
||
| 530 | if (!content.acl_account) { |
||
| 531 | content.acl_account = et2.getWidgetById('nm').getArrayMgr('content').getEntry('account_id'); |
||
| 532 | } |
||
| 533 | if (!content.acl_location) { |
||
| 534 | content.acl_location = et2.getWidgetById('filter').getValue() == 'run' ? 'run' : null; |
||
| 535 | } |
||
| 536 | // If no admin rights, change UI to not allow adding access to apps |
||
| 537 | if (content.acl_location == 'run' && !egw.user('apps')['admin']) { |
||
| 538 | content.acl_location = null; |
||
| 539 | } |
||
| 540 | if (content.acl_location == 'run') { |
||
| 541 | // These are the apps the account has access to |
||
| 542 | // Fetch current values from server |
||
| 543 | this.egw.json(className + '::ajax_get_app_list', [content.acl_account], function (data) { content.apps = data; }, this, false, this) |
||
| 544 | .sendRequest(); |
||
| 545 | } |
||
| 546 | else { |
||
| 547 | // Restrict application selectbox to only apps that support ACL |
||
| 548 | sel_options.acl_appname = []; |
||
| 549 | for (var app_1 in acl_rights) { |
||
| 550 | sel_options.acl_appname.push({ value: app_1, label: this.egw.lang(app_1) }); |
||
| 551 | } |
||
| 552 | // Sort list |
||
| 553 | sel_options.acl_appname.sort(function (a, b) { |
||
| 554 | if (a.label > b.label) |
||
| 555 | return 1; |
||
| 556 | if (a.label < b.label) |
||
| 557 | return -1; |
||
| 558 | return 0; |
||
| 559 | }); |
||
| 560 | } |
||
| 561 | } |
||
| 562 | if (content.acl_appname) { |
||
| 563 | // Load checkboxes & their values |
||
| 564 | content.acl_rights = content.acl_rights ? parseInt(content.acl_rights) : null; |
||
| 565 | jQuery.extend(content, { acl: [], right: [], label: [] }); |
||
| 566 | for (var right in acl_rights[content.acl_appname]) { |
||
| 567 | // only user himself is allowed to grant private (16) rights |
||
| 568 | if (right == '16' && content['acl_account'] != egw.user('account_id')) { |
||
| 569 | readonlys.acl[content.acl.length] = true; |
||
| 570 | } |
||
| 571 | content.acl.push(content.acl_rights & parseInt(right)); |
||
| 572 | content.right.push(right); |
||
| 573 | content.label.push(egw.lang(acl_rights[content.acl_appname][right])); |
||
| 574 | } |
||
| 575 | } |
||
| 576 | if (content.acl_account && !egw.user('apps')['admin']) { |
||
| 577 | readonlys.acl_account = true; |
||
| 578 | } |
||
| 579 | if (content.acl_location) { |
||
| 580 | sel_options.acl_location = jQuery.extend({}, sel_options.acl_location); |
||
| 581 | this.egw.link_title('api-accounts', content.acl_location, function (title) { sel_options.acl_location[content.acl_location] = title; }); |
||
| 582 | } |
||
| 583 | var dialog_options = { |
||
| 584 | callback: jQuery.proxy(function (_button_id, _value) { |
||
| 585 | this.acl_dialog = null; |
||
| 586 | if (_button_id != et2_dialog.OK_BUTTON) |
||
| 587 | return; |
||
| 588 | // Restore account if it's readonly in dialog |
||
| 589 | if (!_value.acl_account) |
||
| 590 | _value.acl_account = content.acl_account; |
||
| 591 | // Handle no applications selected |
||
| 592 | if (typeof _value.apps == 'undefined' && content.acl_location == 'run') { |
||
| 593 | _value.apps = []; |
||
| 594 | } |
||
| 595 | // Only send the request if they entered everything (or selected no apps) |
||
| 596 | if (_value.acl_account && (_value.acl_appname && _value.acl_location || typeof _value.apps != 'undefined')) { |
||
| 597 | var id = []; |
||
| 598 | if (_value.acl_appname && _value.acl_account && _value.acl_location) { |
||
| 599 | id = _value.acl_appname + ':' + _value.acl_account + ':' + _value.acl_location; |
||
| 600 | if (content && content.id && id != content.id) { |
||
| 601 | // Changed the account or location, remove previous or we |
||
| 602 | // get a new line instead of an edit |
||
| 603 | this.egw.json(className + '::ajax_change_acl', [content.id, 0, [], this.et2._inst.etemplate_exec_id], null, this, false, this) |
||
| 604 | .sendRequest(); |
||
| 605 | } |
||
| 606 | id = [id]; |
||
| 607 | } |
||
| 608 | var rights = 0; |
||
| 609 | for (var i in _value.acl) { |
||
| 610 | rights += parseInt(_value.acl[i]); |
||
| 611 | } |
||
| 612 | if (typeof _value.apps != 'undefined' && !_value.acl_appname) { |
||
| 613 | rights = 1; |
||
| 614 | var removed = []; |
||
| 615 | // Loop through all apps, remove the ones with no permission |
||
| 616 | for (var idx in sel_options.filter2) { |
||
| 617 | var app = sel_options.filter2[idx].value || false; |
||
| 618 | if (!app) |
||
| 619 | continue; |
||
| 620 | var run_id = app + ":" + _value.acl_account + ":run"; |
||
| 621 | if (_value.apps.indexOf(app) < 0 && (content.apps.indexOf(app) >= 0 || content.apps.length == 0)) { |
||
| 622 | removed.push(run_id); |
||
| 623 | } |
||
| 624 | else if (_value.apps.indexOf(app) >= 0 && content.apps.indexOf(app) < 0) { |
||
| 625 | id.push(run_id); |
||
| 626 | } |
||
| 627 | } |
||
| 628 | // Remove any removed |
||
| 629 | if (removed.length > 0) { |
||
| 630 | this.egw.json(className + '::ajax_change_acl', [removed, 0, [], this.et2._inst.etemplate_exec_id], callback ? callback : this._acl_callback, this, false, this) |
||
| 631 | .sendRequest(); |
||
| 632 | } |
||
| 633 | } |
||
| 634 | this.egw.json(className + '::ajax_change_acl', [id, rights, _value, this.et2._inst.etemplate_exec_id], callback ? callback : this._acl_callback, this, false, this) |
||
| 635 | .sendRequest(); |
||
| 636 | } |
||
| 637 | }, this), |
||
| 638 | title: this.egw.lang('Access control'), |
||
| 639 | buttons: et2_dialog.BUTTONS_OK_CANCEL, |
||
| 640 | value: { |
||
| 641 | content: content, |
||
| 642 | sel_options: sel_options, |
||
| 643 | modifications: modifications, |
||
| 644 | readonlys: readonlys |
||
| 645 | }, |
||
| 646 | template: egw.webserverUrl + '/admin/templates/default/acl.edit.xet' |
||
| 647 | }; |
||
| 648 | // Handle policy documentation tab here |
||
| 649 | if (this.egw.user('apps').policy) { |
||
| 650 | dialog_options['width'] = 550; |
||
| 651 | dialog_options['height'] = 450, |
||
| 652 | modifications.tabs = { |
||
| 653 | add_tabs: true, |
||
| 654 | tabs: [{ |
||
| 655 | label: egw.lang('Documentation'), |
||
| 656 | template: 'policy.admin_cmd', |
||
| 657 | prepend: false |
||
| 658 | }] |
||
| 659 | }; |
||
| 660 | } |
||
| 661 | // Create the dialog |
||
| 662 | this.acl_dialog = et2_createWidget("dialog", dialog_options, et2_dialog._create_parent(app)); |
||
| 663 | }; |
||
| 664 | /** |
||
| 665 | * Change handler for ACL edit dialog application selectbox. |
||
| 666 | * Re-creates the dialog with the current values |
||
| 667 | * |
||
| 668 | * @param input |
||
| 669 | * @param widget |
||
| 670 | */ |
||
| 671 | AdminApp.prototype.acl_reopen_dialog = function (input, widget) { |
||
| 672 | var content = {}; |
||
| 673 | if (this.acl_dialog != null) { |
||
| 674 | content = this.acl_dialog.get_value() || {}; |
||
| 675 | // Destroy the dialog |
||
| 676 | this.acl_dialog.free(); |
||
| 677 | this.acl_dialog = null; |
||
| 678 | } |
||
| 679 | // Re-open the dialog |
||
| 680 | this._acl_dialog(content); |
||
| 681 | }; |
||
| 682 | /** |
||
| 683 | * Callback called on successfull call of serverside ACL handling |
||
| 684 | * |
||
| 685 | * @param {object} _data returned from server |
||
| 686 | */ |
||
| 687 | AdminApp.prototype._acl_callback = function (_data) { |
||
| 688 | // Avoid the window / framework / app and just refresh the etemplate |
||
| 689 | // Framework will try to refresh the opener |
||
| 690 | // Get by ID, since this.et2 isn't always the ACL list |
||
| 691 | var et2 = etemplate2.getById('admin-acl').widgetContainer; |
||
| 692 | et2.getInstanceManager().refresh(_data.msg, this.appname, _data.ids, _data.type); |
||
| 693 | }; |
||
| 694 | /** |
||
| 695 | * Check to see if admin has taken away access to a category |
||
| 696 | * |
||
| 697 | * @@param {widget} button add/apply pressed button |
||
| 698 | */ |
||
| 699 | AdminApp.prototype.check_owner = function (button) { |
||
| 700 | var select_owner = this.et2.getWidgetById('owner'); |
||
| 701 | var diff = []; |
||
| 702 | if (typeof select_owner != 'undefined') { |
||
| 703 | var owner = select_owner.get_value(); |
||
| 704 | } |
||
| 705 | if (typeof owner != 'object') { |
||
|
0 ignored issues
–
show
|
|||
| 706 | owner = [owner]; |
||
| 707 | } |
||
| 708 | // No owner probably means selectbox is read-only, so no need to check |
||
| 709 | if (owner == null) |
||
| 710 | return true; |
||
| 711 | var all_users = owner.indexOf('0') >= 0; |
||
| 712 | // If they checked all users, uncheck the others |
||
| 713 | if (all_users) { |
||
| 714 | select_owner.set_value(['0']); |
||
| 715 | return true; |
||
| 716 | } |
||
| 717 | // Find out what changed |
||
| 718 | var cat_original_owner = this.et2.getArrayMgr('content').getEntry('owner'); |
||
| 719 | if (cat_original_owner) { |
||
| 720 | var selected_groups = select_owner.get_value().toString(); |
||
| 721 | for (var i = 0; i < cat_original_owner.length; i++) { |
||
| 722 | if (selected_groups.search(cat_original_owner[i]) < 0) { |
||
| 723 | diff.push(cat_original_owner[i]); |
||
| 724 | } |
||
| 725 | } |
||
| 726 | if (diff.length > 0) { |
||
| 727 | var removed_cat_label = jQuery.map(select_owner.options.select_options, function (val, i) { |
||
| 728 | for (var j = 0; j <= diff.length; j++) { |
||
| 729 | if (diff[j] == val.value) { |
||
| 730 | return val.label; |
||
| 731 | } |
||
| 732 | } |
||
| 733 | }); |
||
| 734 | // Somebody will lose permission, give warning. |
||
| 735 | if (removed_cat_label) { |
||
| 736 | var msg = this.egw.lang('Removing access for groups may cause problems for data in this category. Are you sure? Users in these groups may no longer have access:'); |
||
| 737 | return et2_dialog.confirm(button, msg + removed_cat_label.join(',')); |
||
| 738 | } |
||
| 739 | } |
||
| 740 | } |
||
| 741 | return true; |
||
| 742 | }; |
||
| 743 | /** |
||
| 744 | * Show icon based on icon-selectbox, hide placeholder (broken image), if no icon selected |
||
| 745 | * |
||
| 746 | * @param {widget} widget select box widget |
||
| 747 | */ |
||
| 748 | AdminApp.prototype.change_icon = function (widget) { |
||
| 749 | var img = widget.getRoot().getWidgetById('icon_url'); |
||
| 750 | if (img) { |
||
| 751 | img.set_src(widget.getValue()); |
||
| 752 | } |
||
| 753 | }; |
||
| 754 | /** |
||
| 755 | * Add / edit an account |
||
| 756 | * |
||
| 757 | * @param {object} _action egwAction |
||
| 758 | * @param {array} _senders egwActionObject _senders[0].id holds account_id |
||
| 759 | */ |
||
| 760 | AdminApp.prototype.account = function (_action, _senders) { |
||
| 761 | var params = jQuery.extend({}, this.egw.link_get_registry('addressbook', 'edit')); |
||
| 762 | var popup = this.egw.link_get_registry('addressbook', 'edit_popup'); |
||
| 763 | switch (_action.id) { |
||
| 764 | case 'add': |
||
| 765 | params.owner = '0'; |
||
| 766 | break; |
||
| 767 | case 'copy': |
||
| 768 | params.owner = '0'; |
||
| 769 | params.copy = true; |
||
|
0 ignored issues
–
show
|
|||
| 770 | // Fall through |
||
| 771 | default: |
||
| 772 | params.account_id = _senders[0].id.split('::').pop(); // get last :: separated part |
||
| 773 | break; |
||
| 774 | } |
||
| 775 | this.egw.open_link(this.egw.link('/index.php', params), 'admin', popup); |
||
| 776 | }; |
||
| 777 | /** |
||
| 778 | * Submit statistic |
||
| 779 | * |
||
| 780 | * Webkit browsers (Chrome, Safari, ...) do NOT allow to call form.submit() from within onclick of a submit button. |
||
| 781 | * Therefor we first store our own form action, replace it with egroupware.org submit url and set a timeout calling |
||
| 782 | * submit_statistic again with just the form, to do the second submit to our own webserver |
||
| 783 | * |
||
| 784 | * @param {DOM} form |
||
| 785 | * @param {string} submit_url |
||
| 786 | * @return {boolean} |
||
| 787 | */ |
||
| 788 | AdminApp.prototype.submit_statistic = function (form, submit_url) { |
||
| 789 | var that = this; |
||
| 790 | var submit = function () { |
||
| 791 | // submit to egroupware.org |
||
| 792 | var method = form.method; |
||
| 793 | form.method = 'POST'; |
||
| 794 | var action = form.action; |
||
| 795 | form.action = submit_url; |
||
| 796 | var target = form.target; |
||
| 797 | form.target = '_blank'; |
||
| 798 | form.submit(); |
||
| 799 | // submit to own webserver |
||
| 800 | form.method = method; |
||
| 801 | form.action = action; |
||
| 802 | form.target = target; |
||
| 803 | that.et2.getInstanceManager().submit('submit'); |
||
| 804 | }; |
||
| 805 | // Safari does NOT allow to call form.submit() outside of onclick callback |
||
| 806 | // so we have to use browsers ugly synchron confirm |
||
| 807 | if (navigator.userAgent.match(/Safari/) && !navigator.userAgent.match(/Chrome/)) { |
||
| 808 | if (confirm(this.egw.lang('Submit displayed information?'))) { |
||
|
0 ignored issues
–
show
Debugging Code
Best Practice
introduced
by
|
|||
| 809 | submit(); |
||
| 810 | } |
||
| 811 | } |
||
| 812 | else { |
||
| 813 | et2_dialog.show_dialog(function (_button) { |
||
| 814 | if (_button == et2_dialog.YES_BUTTON) { |
||
| 815 | submit(); |
||
| 816 | } |
||
| 817 | }, this.egw.lang('Submit displayed information?'), '', {}, et2_dialog.BUTTON_YES_NO, et2_dialog.QUESTION_MESSAGE, undefined, egw); |
||
| 818 | } |
||
| 819 | return false; |
||
| 820 | }; |
||
| 821 | /** |
||
| 822 | * Change handler for when you change the type of a custom field. |
||
| 823 | * It toggles options / attributes as appropriate. |
||
| 824 | * @param {event object} e |
||
| 825 | * @param {widget object} widget |
||
| 826 | */ |
||
| 827 | AdminApp.prototype.cf_type_change = function (e, widget) { |
||
| 828 | var root = widget.getRoot(); |
||
| 829 | var attributes = widget.getArrayMgr('content').getEntry('attributes[' + widget.getValue() + ']') || {}; |
||
| 830 | root.getWidgetById('cf_values').set_statustext(widget.egw().lang(widget.getArrayMgr('content').getEntry('options[' + widget.getValue() + ']') || '')); |
||
| 831 | jQuery(root.getWidgetById('cf_len').getDOMNode()).toggle(attributes.cf_len && true); |
||
| 832 | jQuery(root.getWidgetById('cf_rows').getDOMNode()).toggle(attributes.cf_rows && true); |
||
| 833 | jQuery(root.getWidgetById('cf_values').getParentDOMNode()).toggle(attributes.cf_values && true); |
||
| 834 | }; |
||
| 835 | /** |
||
| 836 | * Change handler for when you delete a custom app type |
||
| 837 | * If Policy app is available, it asks for documentation |
||
| 838 | */ |
||
| 839 | AdminApp.prototype.cf_type_delete = function (e, widget) { |
||
| 840 | var callback = function (button, value) { |
||
| 841 | if (button === et2_dialog.YES_BUTTON) { |
||
| 842 | var values = jQuery.extend({}, this.getInstanceManager().getValues(this.getRoot()), value, { appname: this.getRoot().getArrayMgr('content').getEntry('content_types[appname]') }); |
||
| 843 | egw.json('admin.admin_customfields.ajax_delete_type', [values, this.getInstanceManager().etemplate_exec_id]).sendRequest(); |
||
| 844 | // Immediately remove the type |
||
| 845 | var types = this.getRoot().getWidgetById('types'); |
||
| 846 | var options = types.options.select_options; |
||
| 847 | var key; |
||
| 848 | for (key in options) { |
||
| 849 | if (options.hasOwnProperty(key) && key === types.getValue()) { |
||
| 850 | delete options[key]; |
||
| 851 | break; |
||
| 852 | } |
||
| 853 | } |
||
| 854 | types.set_select_options(options); |
||
| 855 | this.egw().message(''); |
||
| 856 | // Trigger load of status for existing type |
||
| 857 | types.set_value(Object.keys(options)[0]); |
||
| 858 | } |
||
| 859 | }.bind(widget); |
||
| 860 | if (egw.app('policy')) { |
||
| 861 | egw.includeJS(egw.link('/policy/js/app.js'), function () { |
||
| 862 | if (typeof app.policy === 'undefined' || typeof app.policy.confirm === 'undefined') { |
||
| 863 | app.policy = new app.classes.policy(); |
||
| 864 | } |
||
| 865 | var parent = et2_dialog._create_parent(widget.egw()); |
||
| 866 | var dialog = et2_createWidget("dialog", { |
||
| 867 | callback: callback, |
||
| 868 | template: egw.link('/policy/templates/default/admin_cmd_narrow.xet'), |
||
| 869 | title: egw.lang('Delete'), |
||
| 870 | buttons: et2_dialog.BUTTONS_YES_NO, |
||
| 871 | value: { content: {} }, |
||
| 872 | width: 'auto' |
||
| 873 | }, parent); |
||
| 874 | dialog.egw().message("Entries with a deleted type can cause problems.\nCheck for entries with this type before deleting.", 'warning'); |
||
| 875 | }); |
||
| 876 | } |
||
| 877 | else { |
||
| 878 | callback(et2_dialog.YES_BUTTON); |
||
| 879 | } |
||
| 880 | return false; |
||
| 881 | }; |
||
| 882 | /** |
||
| 883 | * Activate none standard SMTP mail accounts for selected users |
||
| 884 | * |
||
| 885 | * @param {egw_action} _action |
||
| 886 | * @param {array} _selected selected users |
||
| 887 | */ |
||
| 888 | AdminApp.prototype.emailadminActiveAccounts = function (_action, _selected) { |
||
| 889 | var menuaction = 'admin.admin_mail.ajax_activeAccounts'; |
||
| 890 | var accounts = []; |
||
| 891 | var msg1 = egw.lang('%1 accounts being activated', "" + Object.keys(_selected).length); |
||
| 892 | for (var i = 0; i < Object.keys(_selected).length; i++) { |
||
| 893 | accounts[i] = [{ id: _selected[i]['id'].split('::')[1], qouta: "", domain: "", status: _action.id == 'active' ? _action.id : '' }, this.et2._inst.etemplate_exec_id]; |
||
| 894 | } |
||
| 895 | var callbackDialog = function (btn) { |
||
| 896 | if (btn === et2_dialog.YES_BUTTON) { |
||
| 897 | // long task dialog for de/activation accounts |
||
| 898 | et2_dialog.long_task(function (_val, _resp) { |
||
| 899 | if (_val && _resp.type !== 'error') { |
||
| 900 | console.log(_val, _resp); |
||
|
0 ignored issues
–
show
|
|||
| 901 | } |
||
| 902 | else { |
||
|
0 ignored issues
–
show
Comprehensibility
Documentation
Best Practice
introduced
by
|
|||
| 903 | } |
||
| 904 | }, msg1, 'Mail Acounts Activation', menuaction, accounts, 'admin'); |
||
| 905 | } |
||
| 906 | }; |
||
| 907 | // confirmation dialog |
||
| 908 | et2_dialog.show_dialog(callbackDialog, egw.lang('Are you sure you want to %1 mail for selected accounts?', egw.lang(_action.id)), egw.lang('Active Mail Accounts'), {}, et2_dialog.BUTTON_YES_NO, et2_dialog.WARNING_MESSAGE, undefined, egw); |
||
| 909 | }; |
||
| 910 | /** |
||
| 911 | * Resize window methode |
||
| 912 | * |
||
| 913 | * @returns {undefined} |
||
| 914 | */ |
||
| 915 | AdminApp.prototype.wizard_popup_resize = function () { |
||
| 916 | var $main_div = jQuery('#popupMainDiv'); |
||
| 917 | var $et2 = jQuery('.et2_container'); |
||
| 918 | var w = { |
||
| 919 | width: egw_getWindowInnerWidth(), |
||
| 920 | height: egw_getWindowInnerHeight() |
||
| 921 | }; |
||
| 922 | // Use et2_container for width since #popupMainDiv is full width, but we still need |
||
| 923 | // to take padding/margin into account |
||
| 924 | var delta_width = w.width - ($et2.outerWidth(true) + ($main_div.outerWidth(true) - $main_div.width())); |
||
| 925 | var delta_height = w.height - ($et2.outerHeight(true) + ($main_div.outerHeight(true) - $main_div.height())); |
||
| 926 | if (delta_width != 0 || delta_height != 0) { |
||
| 927 | window.resizeTo(egw_getWindowOuterWidth() - delta_width, egw_getWindowOuterHeight() - delta_height); |
||
| 928 | } |
||
| 929 | }; |
||
| 930 | /** |
||
| 931 | * Switch account wizard to manual entry |
||
| 932 | */ |
||
| 933 | AdminApp.prototype.wizard_manual = function () { |
||
| 934 | jQuery('.emailadmin_manual').fadeToggle(); // not sure how to to this et2-isch |
||
| 935 | this.wizard_popup_resize(); // popup needs to be resized after toggling |
||
| 936 | }; |
||
| 937 | /** |
||
| 938 | * onclick for continue button to show progress animation |
||
| 939 | * |
||
| 940 | * @param {object} _event event-object or information about event |
||
| 941 | * @param {et2_baseWidget} _widget widget causing the event |
||
| 942 | */ |
||
| 943 | AdminApp.prototype.wizard_detect = function (_event, _widget) { |
||
| 944 | // we need to do a manual asynchronious submit to show progress animation |
||
| 945 | // default synchronious submit stops animation! |
||
| 946 | if (this.et2._inst.submit('button[continue]', true)) // true = async submit |
||
| 947 | { |
||
| 948 | var sieve_enabled = this.et2.getWidgetById('acc_sieve_enabled'); |
||
| 949 | if (!sieve_enabled || sieve_enabled.get_value()) { |
||
| 950 | jQuery('#admin-mailwizard_output').hide(); |
||
| 951 | jQuery('td.emailadmin_progress').show(); |
||
| 952 | } |
||
| 953 | } |
||
| 954 | return false; |
||
| 955 | }; |
||
| 956 | /** |
||
| 957 | * Set default port, if imap ssl-type changes |
||
| 958 | * |
||
| 959 | * @param {object} _event event-object or information about event |
||
| 960 | * @param {et2_baseWidget} _widget widget causing the event |
||
| 961 | */ |
||
| 962 | AdminApp.prototype.wizard_imap_ssl_onchange = function (_event, _widget) { |
||
| 963 | var ssl_type = _widget.get_value(); |
||
| 964 | this.et2.getWidgetById('acc_imap_port').set_value(ssl_type == this.SSL_SSL || ssl_type == this.SSL_TLS ? 993 : 143); |
||
| 965 | }; |
||
| 966 | /** |
||
| 967 | * Set default port, if imap ssl-type changes |
||
| 968 | * |
||
| 969 | * @param {object} _event event-object or information about event |
||
| 970 | * @param {et2_baseWidget} _widget widget causing the event |
||
| 971 | */ |
||
| 972 | AdminApp.prototype.wizard_smtp_ssl_onchange = function (_event, _widget) { |
||
| 973 | var ssl_type = _widget.get_value(); |
||
| 974 | this.et2.getWidgetById('acc_smtp_port').set_value(ssl_type == 'no' ? 25 : (ssl_type == this.SSL_SSL || ssl_type == this.SSL_TLS ? 465 : 587)); |
||
| 975 | }; |
||
| 976 | /** |
||
| 977 | * Set default port, if imap ssl-type changes |
||
| 978 | * |
||
| 979 | * @param {object} _event event-object or information about event |
||
| 980 | * @param {et2_baseWidget} _widget widget causing the event |
||
| 981 | */ |
||
| 982 | AdminApp.prototype.wizard_sieve_ssl_onchange = function (_event, _widget) { |
||
| 983 | var ssl_type = _widget.get_value(); |
||
| 984 | this.et2.getWidgetById('acc_sieve_port').set_value(ssl_type == this.SSL_SSL || ssl_type == this.SSL_TLS ? 5190 : 4190); |
||
| 985 | this.wizard_sieve_onchange(_event, _widget); |
||
| 986 | }; |
||
| 987 | /** |
||
| 988 | * Enable sieve, if user changes some setting |
||
| 989 | * |
||
| 990 | * @param {object} _event event-object or information about event |
||
| 991 | * @param {et2_baseWidget} _widget widget causing the event |
||
| 992 | */ |
||
| 993 | AdminApp.prototype.wizard_sieve_onchange = function (_event, _widget) { |
||
| 994 | this.et2.getWidgetById('acc_sieve_enabled').set_value(1); |
||
| 995 | }; |
||
| 996 | /** |
||
| 997 | * Switch to select multiple accounts |
||
| 998 | * |
||
| 999 | * @param {object} _event event-object or information about event |
||
| 1000 | * @param {et2_baseWidget} _widget widget causing the event |
||
| 1001 | */ |
||
| 1002 | AdminApp.prototype.edit_multiple = function (_event, _widget) { |
||
| 1003 | // hide multiple button |
||
| 1004 | _widget.set_disabled(true); |
||
| 1005 | // switch account-selection to multiple |
||
| 1006 | var account_id = this.et2.getWidgetById('account_id'); |
||
| 1007 | account_id.set_multiple(true); |
||
| 1008 | }; |
||
| 1009 | /** |
||
| 1010 | * Hide not applying fields, used as: |
||
| 1011 | * - onchange handler on account_id |
||
| 1012 | * - called from et2_ready for emailadmin.account template |
||
| 1013 | * |
||
| 1014 | * @param {object} _event event-object or information about event |
||
| 1015 | * @param {et2_baseWidget} _widget widget causing the event |
||
| 1016 | */ |
||
| 1017 | AdminApp.prototype.account_hide_not_applying = function (_event, _widget) { |
||
| 1018 | var account_id = this.et2.getWidgetById('account_id'); |
||
| 1019 | var ids = account_id && account_id.get_value ? account_id.get_value() : []; |
||
| 1020 | if (typeof ids == 'string') |
||
| 1021 | ids = ids.split(','); |
||
| 1022 | var multiple = ids.length >= 2 || ids[0] === '' || ids[0] < 0; |
||
| 1023 | //alert('multiple='+(multiple?'true':'false')+': '+ids.join(',')); |
||
| 1024 | // initial call |
||
| 1025 | if (typeof _widget == 'undefined') { |
||
| 1026 | if (!multiple) { |
||
| 1027 | jQuery('.emailadmin_no_single').hide(); |
||
| 1028 | } |
||
| 1029 | if (!this.egw.user('apps').admin) { |
||
| 1030 | jQuery('.emailadmin_no_user,#button\\[multiple\\]').hide(); |
||
| 1031 | } |
||
| 1032 | if (ids.length == 1) { |
||
| 1033 | // switch back to single selectbox |
||
| 1034 | account_id.set_multiple(false); |
||
| 1035 | this.et2.getWidgetById('button[multiple]').set_disabled(false); |
||
| 1036 | } |
||
| 1037 | } |
||
| 1038 | // switched to single user |
||
| 1039 | else if (!multiple) { |
||
| 1040 | jQuery('.emailadmin_no_single').fadeOut(); |
||
| 1041 | // switch back to single selectbox |
||
| 1042 | account_id.set_multiple(false); |
||
| 1043 | this.et2.getWidgetById('button[multiple]').set_disabled(false); |
||
| 1044 | } |
||
| 1045 | // switched to multiple user |
||
| 1046 | else { |
||
| 1047 | jQuery('.emailadmin_no_single').fadeIn(); |
||
| 1048 | } |
||
| 1049 | if (_event && _event.stopPropagation) |
||
| 1050 | _event.stopPropagation(); |
||
| 1051 | return false; |
||
| 1052 | }; |
||
| 1053 | /** |
||
| 1054 | * Callback if user changed account selction |
||
| 1055 | * |
||
| 1056 | * @param {object} _event event-object or information about event |
||
| 1057 | * @param {et2_baseWidget} _widget widget causing the event |
||
| 1058 | */ |
||
| 1059 | AdminApp.prototype.change_account = function (_event, _widget) { |
||
| 1060 | // todo check dirty and query user to a) save changes, b) discard changes, c) cancel selection |
||
| 1061 | _widget.getInstanceManager().submit(); |
||
| 1062 | }; |
||
| 1063 | /** |
||
| 1064 | * Callback if user changes notification folders: unset use-default checkbox |
||
| 1065 | * |
||
| 1066 | * @param {object} _event |
||
| 1067 | * @param {et2_widget} _widget |
||
| 1068 | */ |
||
| 1069 | AdminApp.prototype.change_folders = function (_event, _widget) { |
||
| 1070 | var use_default = this.et2.getWidgetById('notify_use_default'); |
||
| 1071 | if (use_default) |
||
| 1072 | use_default.set_value(false); |
||
| 1073 | }; |
||
| 1074 | /** |
||
| 1075 | * default onExecute for admin actions |
||
| 1076 | * |
||
| 1077 | * @param {object} _action |
||
| 1078 | * @param {object} _senders |
||
| 1079 | */ |
||
| 1080 | AdminApp.prototype.account_edit_action = function (_action, _senders) { |
||
| 1081 | if (_action.data.url) { |
||
| 1082 | this.egw.open_link(_action.data.url, _action.data.target || '_blank', _action.data.popup); |
||
| 1083 | } |
||
| 1084 | }; |
||
| 1085 | /** |
||
| 1086 | * Clear instance cache |
||
| 1087 | * |
||
| 1088 | * If there is an error on server-side, resend request with an parameter allowing |
||
| 1089 | * cache to use different method not requiring eg. so much memory |
||
| 1090 | */ |
||
| 1091 | AdminApp.prototype.clear_cache = function () { |
||
| 1092 | this.egw.message(this.egw.lang('Clear cache and register hooks') + "\n" + this.egw.lang('Please wait...'), 'info'); |
||
| 1093 | this.egw.json('admin.admin_hooks.ajax_clear_cache').sendRequest(true, undefined, jQuery.proxy(function (_xmlhttp, _err) { |
||
| 1094 | this.egw.json('admin.admin_hooks.ajax_clear_cache&errored=1').sendRequest(true); |
||
| 1095 | }, this)); |
||
| 1096 | }; |
||
| 1097 | /** |
||
| 1098 | * Export content of given field into relevant file |
||
| 1099 | */ |
||
| 1100 | AdminApp.prototype.smime_exportCert = function () { |
||
| 1101 | var $a = jQuery(document.createElement('a')).appendTo('body').hide(); |
||
| 1102 | var acc_id = this.et2.getArrayMgr("content").getEntry('acc_id'); |
||
| 1103 | var url = window.egw.webserverUrl + '/index.php?'; |
||
| 1104 | url += 'menuaction=mail.mail_ui.smimeExportCert'; |
||
| 1105 | url += '&acc_id=' + acc_id; |
||
| 1106 | $a.prop('href', url); |
||
| 1107 | $a.prop('download', ""); |
||
| 1108 | $a[0].click(); |
||
| 1109 | $a.remove(); |
||
| 1110 | }; |
||
| 1111 | /** |
||
| 1112 | * Create certificate generator dialog |
||
| 1113 | */ |
||
| 1114 | AdminApp.prototype.smime_genCertificate = function () { |
||
| 1115 | var self = this; |
||
| 1116 | et2_createWidget("dialog", { |
||
| 1117 | callback: function (_button_id, _value) { |
||
| 1118 | if (_button_id == 'create' && _value) { |
||
| 1119 | var isValid = true; |
||
| 1120 | var required = ['countryName', 'emailAddress']; |
||
| 1121 | var widget; |
||
| 1122 | // check the required fields |
||
| 1123 | for (var i = 0; i < required.length; i++) { |
||
| 1124 | if (_value[required[i]]) |
||
| 1125 | continue; |
||
| 1126 | widget = this.template.widgetContainer.getWidgetById(required[i]); |
||
| 1127 | widget.set_validation_error('This field is required!'); |
||
| 1128 | isValid = false; |
||
| 1129 | } |
||
| 1130 | // check mismatch passphrase |
||
| 1131 | if (_value.passphrase && _value.passphrase !== _value.passphraseConf) { |
||
| 1132 | var passphraseConf = this.template.widgetContainer.getWidgetById('passphrase'); |
||
| 1133 | passphraseConf.set_validation_error('Confirm passphrase is not match!'); |
||
| 1134 | isValid = false; |
||
| 1135 | } |
||
| 1136 | if (isValid) { |
||
| 1137 | egw.json('mail.mail_ui.ajax_smimeGenCertificate', _value, function (_cert) { |
||
| 1138 | if (_cert) { |
||
| 1139 | for (var key in _cert) { |
||
| 1140 | if (!_cert[key]) |
||
| 1141 | continue; |
||
| 1142 | switch (key) { |
||
| 1143 | case 'cert': |
||
| 1144 | self.et2.getWidgetById('smime_cert').set_value(_cert[key]); |
||
| 1145 | break; |
||
| 1146 | case 'privkey': |
||
| 1147 | self.et2.getWidgetById('acc_smime_password').set_value(_cert[key]); |
||
| 1148 | break; |
||
| 1149 | } |
||
| 1150 | } |
||
| 1151 | self.egw.message('New certificate information has been generated, please save your account if you want to store it.'); |
||
| 1152 | } |
||
| 1153 | }).sendRequest(true); |
||
| 1154 | } |
||
| 1155 | else { |
||
| 1156 | return false; |
||
| 1157 | } |
||
| 1158 | } |
||
| 1159 | }, |
||
| 1160 | title: egw.lang('Generate Certificate'), |
||
| 1161 | buttons: [ |
||
| 1162 | { text: this.egw.lang("Create"), id: "create", "class": "ui-priority-primary", "default": true }, |
||
| 1163 | { text: this.egw.lang("Cancel"), id: "cancel" } |
||
| 1164 | ], |
||
| 1165 | value: { |
||
| 1166 | content: { |
||
| 1167 | value: '' |
||
| 1168 | } |
||
| 1169 | }, |
||
| 1170 | template: egw.webserverUrl + '/mail/templates/default/smimeCertGen.xet?' + Date.now(), |
||
| 1171 | resizable: false, |
||
| 1172 | position: 'left top' |
||
| 1173 | }, et2_dialog._create_parent('mail')); |
||
| 1174 | }; |
||
| 1175 | /** |
||
| 1176 | * Triggers upload for background image and updates its taglist |
||
| 1177 | * |
||
| 1178 | * @param {type} node |
||
| 1179 | * @param {type} widget |
||
| 1180 | */ |
||
| 1181 | AdminApp.prototype.login_background_update = function (node, widget) { |
||
| 1182 | var taglist = widget._parent._children[0]; |
||
| 1183 | egw.json('admin.admin_config.ajax_upload_anon_images', [widget.get_value(), taglist.get_value()], function (_data) { |
||
| 1184 | taglist.set_value(_data); |
||
| 1185 | }).sendRequest(); |
||
| 1186 | }; |
||
| 1187 | /** |
||
| 1188 | * Set content of selected row |
||
| 1189 | * |
||
| 1190 | * @param {array} node |
||
| 1191 | * @returns |
||
| 1192 | */ |
||
| 1193 | AdminApp.prototype.cmds_onselect = function (node) { |
||
| 1194 | var splitter = this.et2.getWidgetById('splitter'); |
||
| 1195 | var cmds_preview = this.et2.getWidgetById('cmds_preview'); |
||
| 1196 | if (node.length != 1) { |
||
| 1197 | splitter.dock(); |
||
| 1198 | return; |
||
| 1199 | } |
||
| 1200 | if (splitter.isDocked()) { |
||
| 1201 | splitter.undock(); |
||
| 1202 | } |
||
| 1203 | var data = egw.dataGetUIDdata(node[0]); |
||
| 1204 | var policy_preview = this.et2.getWidgetById('policy_preview'); |
||
| 1205 | var id = node[0].replace('admin::', ''); |
||
| 1206 | if (app.policy) { |
||
| 1207 | cmds_preview.set_disabled(true); |
||
| 1208 | policy_preview.set_src(egw.link('/index.php', { |
||
| 1209 | menuaction: 'policy.EGroupware\\Policy\\History.view', |
||
| 1210 | 'cmd_id': id, |
||
| 1211 | 'cmd_template': "policy.admin_cmd_history" |
||
| 1212 | })); |
||
| 1213 | } |
||
| 1214 | else { |
||
| 1215 | policy_preview.set_disabled(true); |
||
| 1216 | cmds_preview.set_value({ content: [data.data] }); |
||
| 1217 | } |
||
| 1218 | }; |
||
| 1219 | return AdminApp; |
||
| 1220 | }(egw_app_1.EgwApp |
||
| 1221 | /** |
||
| 1222 | * @lends app.classes.admin |
||
| 1223 | */ |
||
| 1224 | )); |
||
| 1225 | app.classes.admin = AdminApp; |
||
| 1226 |