From 7e4570d46f0b2192bde1bac8d75885fdeee1a1de Mon Sep 17 00:00:00 2001 From: nathangray Date: Tue, 19 Sep 2017 11:11:21 -0600 Subject: [PATCH] Admin - Add a group list --- admin/inc/class.admin_ui.inc.php | 211 ++++++++++++++++++++---------- admin/js/app.js | 34 ++++- admin/templates/default/app.css | 6 + admin/templates/default/index.xet | 40 ++++++ admin/templates/pixelegg/app.css | 5 + 5 files changed, 222 insertions(+), 74 deletions(-) diff --git a/admin/inc/class.admin_ui.inc.php b/admin/inc/class.admin_ui.inc.php index 8341db90b4..62d3289526 100644 --- a/admin/inc/class.admin_ui.inc.php +++ b/admin/inc/class.admin_ui.inc.php @@ -62,6 +62,16 @@ class admin_ui 'actions' => self::user_actions(), 'placeholder_actions' => array('add') ); + $content['groups'] = array( + 'get_rows' => 'admin_ui::get_groups', + 'no_cat' => true, + 'no_filter' => true, + 'no_filter2' => true, + 'row_id' => 'account_id', + 'actions' => self::group_actions(), + 'placeholder_actions' => array('add') + ); + //$content['msg'] = 'Hi Ralf ;-)'; $sel_options['tree'] = $this->tree_data(); $sel_options['filter'] = array('' => lang('All groups')); @@ -108,80 +118,16 @@ class admin_ui */ public static function tree_actions() { - $user_actions = self::user_actions(); + $actions = static::group_actions(); - $actions = array( - 'view' => array( - 'onExecute' => 'javaScript:app.admin.group', - 'caption' => 'Show members', - 'enableId' => '^/groups/-\\d+', - 'default' => true, - 'group' => $group=1, - ), - 'add' => array( - 'group' => $group, - )+$user_actions['add'], - 'acl' => array( - 'onExecute' => 'javaScript:app.admin.group', - 'caption' => 'Access control', - 'enableId' => '^/groups/-\\d+', - 'url' => 'menuaction=admin.admin_acl.index&account_id=$id', - 'popup' => '900x450', - 'icon' => 'lock', - 'group' => 2, - ), - ); - if (!$GLOBALS['egw']->acl->check('account_access',64,'admin')) // no rights to set ACL-rights + foreach($actions as $action_id => &$action) { - $actions['deny'] = array( - 'caption' => 'Deny access', - 'enableId' => '^/groups/-\\d+', - 'url' => 'menuaction=admin.admin_denyaccess.list_apps&account_id=$id', - 'onExecute' => 'javaScript:app.admin.group', - 'icon' => 'cancel', - 'group' => 2, - ); - } - $group = 5; // allow to place actions in different groups by hook, this is the default - // supporting both old way using $GLOBALS['menuData'] and new just returning data in hook - $apps = array_unique(array_merge(array('admin'), Api\Hooks::implemented('edit_group'))); - foreach($apps as $app) - { - $GLOBALS['menuData'] = $data = array(); - $data = Api\Hooks::single('edit_group', $app); - if (!is_array($data)) $data = $GLOBALS['menuData']; - //error_log(__METHOD__."() app $app returned ".array2string($data)); - foreach($data as $item) + if (!isset($action['enableId']) && !in_array($action_id, array('add'))) { - // allow hook to return "real" actions, but still support legacy: description, url, extradata, options - if (empty($item['caption'])) - { - $item['caption'] = $item['description']; - unset($item['description']); - } - if (isset($item['url']) && isset($item['extradata'])) - { - $item['url'] = $item['extradata'].'&account_id=$id'; - $item['id'] = substr($item['extradata'], 11); - unset($item['extradata']); - $matches = null; - if ($item['options'] && preg_match('/(egw_openWindowCentered2?|window.open)\([^)]+,(\d+),(\d+).*(title="([^"]+)")?/', $item['options'], $matches)) - { - $item['popup'] = $matches[2].'x'.$matches[3]; - $item['onExecute'] = 'javaScript:nm_action'; - if (isset($matches[5])) $item['tooltip'] = $matches[5]; - unset($item['options']); - } - } - if (empty($item['icon'])) $item['icon'] = $app.'/navbar'; - if (empty($item['group'])) $item['group'] = $group; - if (empty($item['onExecute'])) $item['onExecute'] = 'javaScript:app.admin.group'; - if (!isset($item['allowOnMultiple'])) $item['allowOnMultiple'] = false; - if (!isset($item['enableId'])) $item['enableId'] = '^/groups/-\\d+'; - - $actions[$item['id']] = $item; + $action['enableId'] = '^/groups/-\\d+'; } } + return $actions; } @@ -273,6 +219,90 @@ class admin_ui return $actions; } + /** + * Actions on groups + * + * @return array + */ + public static function group_actions() + { + $user_actions = self::user_actions(); + $actions = array( + 'view' => array( + 'onExecute' => 'javaScript:app.admin.group', + 'caption' => 'Show members', + 'default' => true, + 'group' => $group=1, + 'allowOnMultiple' => false + ), + 'add' => array( + 'group' => $group, + )+$user_actions['add'], + 'acl' => array( + 'onExecute' => 'javaScript:app.admin.group', + 'caption' => 'Access control', + 'url' => 'menuaction=admin.admin_acl.index&account_id=$id', + 'popup' => '900x450', + 'icon' => 'lock', + 'group' => 2, + 'allowOnMultiple' => false + ), + ); + if (!$GLOBALS['egw']->acl->check('account_access',64,'admin')) // no rights to set ACL-rights + { + $actions['deny'] = array( + 'caption' => 'Deny access', + 'url' => 'menuaction=admin.admin_denyaccess.list_apps&account_id=$id', + 'onExecute' => 'javaScript:app.admin.group', + 'icon' => 'cancel', + 'group' => 2, + 'allowOnMultiple' => false + ); + } + + $group = 5; // allow to place actions in different groups by hook, this is the default + + // supporting both old way using $GLOBALS['menuData'] and new just returning data in hook + $apps = array_unique(array_merge(array('admin'), Api\Hooks::implemented('edit_group'))); + foreach($apps as $app) + { + $GLOBALS['menuData'] = $data = array(); + $data = Api\Hooks::single('edit_group', $app); + if (!is_array($data)) $data = $GLOBALS['menuData']; + + foreach($data as $item) + { + // allow hook to return "real" actions, but still support legacy: description, url, extradata, options + if (empty($item['caption'])) + { + $item['caption'] = $item['description']; + unset($item['description']); + } + if (isset($item['url']) && isset($item['extradata'])) + { + $item['url'] = $item['extradata'].'&account_id=$id'; + $item['id'] = substr($item['extradata'], 11); + unset($item['extradata']); + $matches = null; + if ($item['options'] && preg_match('/(egw_openWindowCentered2?|window.open)\([^)]+,(\d+),(\d+).*(title="([^"]+)")?/', $item['options'], $matches)) + { + $item['popup'] = $matches[2].'x'.$matches[3]; + $item['onExecute'] = 'javaScript:nm_action'; + if (isset($matches[5])) $item['tooltip'] = $matches[5]; + unset($item['options']); + } + } + if (empty($item['icon'])) $item['icon'] = $app.'/navbar'; + if (empty($item['group'])) $item['group'] = $group; + if (empty($item['onExecute'])) $item['onExecute'] = 'javaScript:app.admin.group'; + if (!isset($item['allowOnMultiple'])) $item['allowOnMultiple'] = false; + + $actions[$item['id']] = $item; + } + } + return $actions; + } + /** * Callback for nextmatch to fetch users * @@ -318,6 +348,49 @@ class admin_ui return self::$accounts->total; } + /** + * Callback for the nextmatch to get groups + */ + public static function get_groups(&$query, &$rows) + { + $groups = $GLOBALS['egw']->accounts->search(array( + 'type' => 'groups', + 'order' => $query['order'], + 'sort' => $query['sort'], + 'start' => (int)$query['start'], + 'num_rows' => (int)$query['num_rows'] + )); + + $apps = array(); + foreach($GLOBALS['egw_info']['apps'] as $app => $data) + { + if (!$data['enabled'] || !$data['status'] || $data['status'] == 3) + { + continue; // do NOT show disabled apps, or our API (status = 3) + } + + $apps[] = $app; + } + + $rows = array(); + foreach($groups as &$group) + { + $run_rights = $GLOBALS['egw']->acl->get_user_applications($group['account_id'], false, false); + foreach($apps as $app) + { + if((boolean)$run_rights[$app]) + { + $group['apps'][] = $app; + } + } + + $group['members'] = $GLOBALS['egw']->accounts->members($group['account_id'],true); + $rows[] = $group; + } + + return $GLOBALS['egw']->accounts->total; + } + /** * Autoload tree from $_GET['id'] on */ diff --git a/admin/js/app.js b/admin/js/app.js index c0b8f8c4c8..0c143e7f16 100644 --- a/admin/js/app.js +++ b/admin/js/app.js @@ -89,6 +89,8 @@ app.classes.admin = AppJS.extend( case 'admin.index': var iframe = this.iframe = this.et2.getWidgetById('iframe'); this.nm = this.et2.getWidgetById('nm'); + this.groups = this.et2.getWidgetById('groups'); + this.groups.set_disabled(true); this.ajax_target = this.et2.getWidgetById('ajax_target'); if (iframe) { @@ -176,6 +178,7 @@ app.classes.admin = AppJS.extend( } this.iframe.set_disabled(!_url || ajax); this.nm.set_disabled(!!_url || ajax); + this.groups.set_disabled(true); this.ajax_target.set_disabled(!ajax); }, @@ -343,12 +346,20 @@ app.classes.admin = AppJS.extend( { var link = _widget.getUserData(_id, 'link'); + this.groups.set_disabled(true); + this.nm.set_disabled(false); + if (_id == '/accounts' || _id.substr(0, 8) == '/groups/') { this.load(); var parts = _id.split('/'); this.et2.getWidgetById('nm').applyFilters({ filter: parts[2] ? parts[2] : '', search: ''}); } + else if (_id === '/groups') + { + this.load(); + this.group_list(); + } else if (typeof link == 'undefined') { _widget.openItem(_id, 'toggle'); @@ -364,6 +375,16 @@ app.classes.admin = AppJS.extend( } }, + /** + * Show the group list in the main window + */ + group_list: function group_list() + { + this.nm.set_disabled(true); + this.groups.set_disabled(false); + }, + + /** * View, edit or delete a group callback for tree * @@ -372,14 +393,17 @@ app.classes.admin = AppJS.extend( */ group: function(_action, _senders) { + // Tree IDs look like /groups/ID, nm uses admin::ID + var from_nm = _senders[0].id.indexOf('::') > 0; + var account_id = _senders[0].id.split(from_nm ? '::' : '/')[from_nm ? 1 : 2]; + switch(_action.id) { case 'view': - this.run(_senders[0].id, this.et2.getWidgetById('tree')); + this.run(from_nm ? '/groups/'+account_id : _senders[0].id, this.et2.getWidgetById('tree')); break; case 'delete': - var account_id = _senders[0].id.split('/')[2]; this.egw.json('admin_account::ajax_delete_group', [account_id]).sendRequest(); break; @@ -389,14 +413,14 @@ app.classes.admin = AppJS.extend( alert('Missing url in action '+_action.id+'!'); break; } - var url = _action.data.url.replace('$id', _senders[0].id.split('/')[2]); + var url = unescape(_action.data.url).replace('$id', account_id); if (url[0] != '/' && url.substr(0, 4) != 'http') { url = this.egw.link('/index.php', url); } - if (_action.data.popup) + if (_action.data.popup || _action.data.width && _action.data.height) { - this.egw.open_link(url, '_blank', _action.data.popup); + this.egw.open_link(url, '_blank', _action.data.popup ? _action.data.popup : _action.data.width + 'x' + _action.data.height); } else { diff --git a/admin/templates/default/app.css b/admin/templates/default/app.css index 6da1b94948..4cf05f5a97 100644 --- a/admin/templates/default/app.css +++ b/admin/templates/default/app.css @@ -26,6 +26,12 @@ body { background-color: white; } +/** Group list */ +#admin-index_groups div.innerContainer { + overflow: auto; + max-height: 7em; +} + tr.adminAccountInactive .adminStatus { color: red; } diff --git a/admin/templates/default/index.xet b/admin/templates/default/index.xet index 821ab69d44..4c6efb3d75 100644 --- a/admin/templates/default/index.xet +++ b/admin/templates/default/index.xet @@ -46,9 +46,49 @@ +