fix: Organisation UI and API improvements

- opened up the organisations controller to API actions
  - this includes index/add/edit/delete
  - uses the still new-ish standardised REST library
  - send GET requests to add/edit to view the parameters

- reworked the org index to paginate 60 items instead of 20 and to have a view all button
pull/1857/head
Iglocska 2017-01-20 10:33:38 +01:00
parent 75d8504de1
commit e8303537e7
5 changed files with 190 additions and 58 deletions

View File

@ -13,6 +13,18 @@ class RestResponseComponent extends Component {
'description' => "POST a User object in JSON format to this API to edit a user.",
'optional' => array('email', 'org_id', 'role_id', 'password', 'external_auth_required', 'external_auth_key', 'enable_password', 'nids_sid', 'server_id', 'gpgkey', 'certif_public', 'autoalert', 'contactalert', 'disabled', 'change_pw', 'termsaccepted', 'newsread')
)
),
'Organisation' => array(
'admin_add' => array(
'description' => "POST an Organisation object in JSON format to this API to create a new organsiation.",
'mandatory' => array('name'),
'optional' => array('anonymise', 'description', 'type', 'nationality', 'sector', 'uuid', 'contacts', 'local')
),
'admin_edit' => array(
'description' => "POST an Organisation object in JSON format to this API to create a new organsiation.",
'mandatory' => array('name'),
'optional' => array('anonymise', 'description', 'type', 'nationality', 'sector', 'uuid', 'contacts', 'local')
)
)
);
@ -30,7 +42,7 @@ class RestResponseComponent extends Component {
public function saveSuccessResponse($controller, $action, $id = false, $format = false, $message = false) {
$action = $this->__dissectAdminRouting($action);
if (!$message) {
$message = Inflector::singularize($controller) . ' ' . $action['action'] . 'ed';
$message = Inflector::singularize($controller) . ' ' . $action['action'] . ((substr($action['action'], -1) == 'e') ? 'd' : 'ed');
}
$response['name'] = $message;
$response['message'] = $response['name'];

View File

@ -38,17 +38,27 @@ class OrganisationsController extends AppController {
}
}
$this->set('passedArgs', json_encode($passedArgs));
$this->paginate = array(
'conditions' => $conditions,
'recursive' => -1,
);
$this->paginate['conditions'] = $conditions;
$usersPerOrg = $this->User->getMembersCount();
$orgs = $this->paginate();
if ($this->_isSiteAdmin()) {
$this->loadModel('User');
$org_creator_ids = array();
foreach ($orgs as $org) {
if (!in_array($org['Organisation']['created_by'], $org_creator_ids)) {
if ($this->_isRest()) {
unset($this->paginate['limit']);
$orgs = $this->Organisation->find('all', $this->paginate);
} else {
if (isset($this->params['named']['viewall']) && $this->params['named']['viewall']) {
$orgCount = $this->Organisation->find('count');
$this->paginate['limit'] = $orgCount;
}
$this->set('viewall', isset($this->params['named']['viewall']) ? $this->params['named']['viewall'] : false);
$orgs = $this->paginate();
}
$this->loadModel('User');
$org_creator_ids = array();
foreach ($orgs as $k => $org) {
if (isset($usersPerOrg[$org['Organisation']['id']])) {
$orgs[$k]['Organisation']['user_count'] = $usersPerOrg[$org['Organisation']['id']];
}
if ($this->_isSiteAdmin()) {
if (!in_array($org['Organisation']['created_by'], array_keys($org_creator_ids))) {
$email = $this->User->find('first', array('recursive' => -1, 'fields' => array('id', 'email'), 'conditions' => array('id' => $org['Organisation']['created_by'])));
if (!empty($email)) {
$org_creator_ids[$org['Organisation']['created_by']] = $email['User']['email'];
@ -56,23 +66,59 @@ class OrganisationsController extends AppController {
$org_creator_ids[$org['Organisation']['created_by']] = 'Unknown';
}
}
$orgs[$k]['Organisation']['created_by_email'] = $org_creator_ids[$org['Organisation']['created_by']];
}
$this->set('org_creator_ids', $org_creator_ids);
}
$this->set('scope', $scope);
$this->set('orgs', $orgs);
$this->set('members', $usersPerOrg);
if ($this->_isRest()) {
return $this->RestResponse->viewData($orgs, $this->response->type());
} else {
$this->set('named', $this->params['named']);
$this->set('scope', $scope);
$this->set('orgs', $orgs);
}
}
public function admin_add() {
if ($this->request->is('post')) {
if ($this->_isRest()) {
if (isset($this->request->data['request'])) {
$this->request->data = $this->request->data['request'];
}
if (!isset($this->request->data['Organisation'])) {
$this->request->data['Organisation'] = $this->request->data;
}
if (isset($this->request->data['Organisation']['id'])){
unset($this->request->data['Organisation']['id']);
}
}
$this->Organisation->create();
$this->request->data['Organisation']['created_by'] = $this->Auth->user('id');
if ($this->_isRest()) {
if (!isset($this->request->data['Organisation']['local'])) {
$this->request->data['Organisation']['local'] = true;
}
}
if ($this->Organisation->save($this->request->data)) {
$this->Session->setFlash('The organisation has been successfully added.');
$this->redirect(array('admin' => false, 'action' => 'index'));
if ($this->_isRest()) {
$org = $this->Organisation->find('first', array(
'conditions' => array('Organisation.id' => $this->Organisation->id),
'recursive' => -1
));
return $this->RestResponse->viewData($org, $this->response->type());
} else {
$this->Session->setFlash('The organisation has been successfully added.');
$this->redirect(array('admin' => false, 'action' => 'index'));
}
} else {
$this->Session->setFlash('The organisation could not be added.');
if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Organisations', 'admin_add', false, $this->Organisation->validationErrors, $this->response->type());
} else {
$this->Session->setFlash('The organisation could not be added.');
}
}
} else {
if ($this->_isRest()) {
return $this->RestResponse->describe('Organisations', 'admin_add', false, $this->response->type());
}
}
$this->set('countries', $this->_arrayToValuesIndexArray($this->Organisation->countries));
@ -82,12 +128,35 @@ class OrganisationsController extends AppController {
$this->Organisation->id = $id;
if (!$this->Organisation->exists()) throw new NotFoundException('Invalid organisation');
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->_isRest()) {
if (isset($this->request->data['request'])) {
$this->request->data = $this->request->data['request'];
}
if (!isset($this->request->data['Organisation'])) {
$this->request->data['Organisation'] = $this->request->data;
}
}
$this->request->data['Organisation']['id'] = $id;
if ($this->Organisation->save($this->request->data)) {
$this->Session->setFlash('Organisation updated.');
$this->redirect(array('admin' => false, 'action' => 'view', $this->Organisation->id));
if ($this->_isRest()) {
$org = $this->Organisation->find('first', array(
'conditions' => array('Organisation.id' => $this->Organisation->id),
'recursive' => -1
));
return $this->RestResponse->viewData($org, $this->response->type());
} else {
$this->Session->setFlash('Organisation updated.');
$this->redirect(array('admin' => false, 'action' => 'view', $this->Organisation->id));
}
} else {
$this->Session->setFlash('The organisation could not be updated.');
if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Organisations', 'admin_edit', false, $this->Organisation->validationErrors, $this->response->type());
$this->Session->setFlash('The organisation could not be updated.');
}
}
} else {
if ($this->_isRest()) {
return $this->RestResponse->describe('Organisations', 'admin_edit', false, $this->response->type());
}
}
$this->set('countries', $this->_arrayToValuesIndexArray($this->Organisation->countries));
@ -110,11 +179,19 @@ class OrganisationsController extends AppController {
if ($org['Organisation']['local']) $url = '/organisations/index';
else $url = '/organisations/index/remote';
if ($this->Organisation->delete()) {
$this->Session->setFlash(__('Organisation deleted'));
$this->redirect($url);
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Organisations', 'admin_delete', $id, $this->response->type());
} else {
$this->Session->setFlash(__('Organisation deleted'));
$this->redirect($url);
}
} else {
$this->Session->setFlash(__('Organisation could not be deleted. Generally organisations should never be deleted, instead consider moving them to the known remote organisations list. Alternatively, if you are certain that you would like to remove an organisation and are aware of the impact, make sure that there are no users or events still tied to this organisation before deleting it.'));
$this->redirect($url);
if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Organisations', 'admin_delete', $id, $this->Organisation->validationErrors, $this->response->type());
} else {
$this->Session->setFlash(__('Organisation could not be deleted. Generally organisations should never be deleted, instead consider moving them to the known remote organisations list. Alternatively, if you are certain that you would like to remove an organisation and are aware of the impact, make sure that there are no users or events still tied to this organisation before deleting it.'));
$this->redirect($url);
}
}
}
@ -134,18 +211,30 @@ class OrganisationsController extends AppController {
}
$org = $this->Organisation->find('first', array(
'conditions' => array('id' => $id),
'fields' => $fields
'fields' => $fields,
'recursive' => -1
));
$this->set('local', $org['Organisation']['local']);
if ($fullAccess) {
$creator = $this->Organisation->User->find('first', array('conditions' => array('User.id' => $org['Organisation']['created_by'])));
$this->set('creator', $creator);
$creator = $this->Organisation->User->find('first', array(
'conditions' => array('User.id' => $org['Organisation']['created_by']),
'fields' => array('email'),
'recursive' => -1
)
);
if (!empty($creator)) {
$org['Organisation']['created_by_email'] = $creator['User']['email'];
}
}
if ($this->_isRest()) {
$org['Organisation']['user_count'] = $this->Organisation->User->getMembersCount($org['Organisation']['id']);
return $this->RestResponse->viewData($org, $this->response->type());
} else {
$this->set('fullAccess', $fullAccess);
$this->set('org', $org);
$this->set('id', $id);
}
$this->set('fullAccess', $fullAccess);
$this->set('org', $org);
$this->set('id', $id);
}
public function landingpage($id) {

View File

@ -883,21 +883,32 @@ class User extends AppModel {
return $fields;
}
public function getMembersCount() {
public function getMembersCount($org_id = false) {
// for Organizations List
$conditions = array();
$findType = 'all';
if ($org_id !== false) {
$findType = 'first';
$conditions = array('User.org_id' => $org_id);
}
$fields = array('org_id', 'COUNT(User.id) AS num_members');
$params = array(
'fields' => $fields,
'recursive' => -1,
'group' => array('org_id'),
'order' => array('org_id'),
'conditions' => $conditions
);
$orgs = $this->find('all', $params);
$usersPerOrg = [];
foreach ($orgs as $key => $value) {
$usersPerOrg[$value['User']['org_id']] = $value[0]['num_members'];
$orgs = $this->find($findType, $params);
if ($org_id !== false) {
return $orgs[0]['num_members'];
} else {
$usersPerOrg = [];
foreach ($orgs as $key => $value) {
$usersPerOrg[$value['User']['org_id']] = $value[0]['num_members'];
}
return $usersPerOrg;
}
return $usersPerOrg;
}
public function findAdminsResponsibleForUser($user){

View File

@ -15,22 +15,37 @@
),
);
if (!in_array($scope, array_keys($texts))) $scope = 'local';
$partial = array();
foreach($named as $key => $value):
if ($key == 'page' || $key == 'viewall'):
continue;
endif;
$partial[] = h($key) . ':' . h($value);
endforeach;
$viewall_button_text = 'Paginate';
if (!$viewall):
$viewall_button_text = 'View all';
$partial[] = 'viewall:1';
endif;
?>
<h2><?php echo $texts[$scope]['text'] . $texts[$scope]['extra']; ?></h2>
<div class="pagination">
<ul>
<?php
$this->Paginator->options(array(
'update' => '.span12',
'evalScripts' => true,
'before' => '$(".progress").show()',
'complete' => '$(".progress").hide()',
));
echo $this->Paginator->prev('&laquo; ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span'));
echo $this->Paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span'));
echo $this->Paginator->next(__('next') . ' &raquo;', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'));
?>
<h2><?php echo $texts[$scope]['text'] . $texts[$scope]['extra']; ?></h2>
<div class="pagination">
<ul>
<?php
$this->Paginator->options(array(
'update' => '.span12',
'evalScripts' => true,
'before' => '$(".progress").show()',
'complete' => '$(".progress").hide()',
));
echo $this->Paginator->prev('&laquo; ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span'));
echo $this->Paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span'));
echo $this->Paginator->next(__('next') . ' &raquo;', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'));
?>
<li class="all">
<a href="<?php echo $baseurl . '/organisations/index/' . implode('/', $partial); ?>"><?php echo $viewall_button_text; ?></a>
</li>
</ul>
</div>
<div class="tabMenuFixedContainer" style="display:inline-block;">
@ -86,10 +101,12 @@ foreach ($orgs as $org): ?>
<td class="short" ondblclick="document.location.href ='/organisations/view/<?php echo $org['Organisation']['id'];?>'"><?php echo h($org['Organisation']['type']); ?></td>
<td><?php echo h($org['Organisation']['contacts']); ?></td>
<?php if ($isSiteAdmin): ?>
<td class="short" ondblclick="document.location.href ='/organisations/view/<?php echo $org['Organisation']['id'];?>'"><?php echo h($org_creator_ids[$org['Organisation']['created_by']]); ?></td>
<td class="short" ondblclick="document.location.href ='/organisations/view/<?php echo $org['Organisation']['id'];?>'">
<?php echo (isset($org['Organisation']['created_by_email'])) ? h($org['Organisation']['created_by_email']) : '&nbsp;'; ?>
</td>
<?php endif; ?>
<td class="short <?php echo $org['Organisation']['local'] ? 'green' : 'red';?>" ondblclick="document.location.href ='/organisations/view/<?php echo $org['Organisation']['id'];?>'"><?php echo $org['Organisation']['local'] ? 'Yes' : 'No';?></td>
<td class="short"><?php echo isset($members[$org['Organisation']['id']]) ? $members[$org['Organisation']['id']] : '0';?></td>
<td class="short"><?php echo isset($org['Organisation']['user_count']) ? $org['Organisation']['user_count'] : '0';?></td>
<td class="short action-links">
<?php if ($isSiteAdmin): ?>
<a href='/admin/organisations/edit/<?php echo $org['Organisation']['id'];?>' class = "icon-edit" title = "Edit"></a>
@ -117,6 +134,9 @@ endforeach; ?>
echo $this->Paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span'));
echo $this->Paginator->next(__('next') . ' &raquo;', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'));
?>
<li class="all">
<a href="<?php echo $baseurl . '/organisations/index/' . implode('/', $partial); ?>"><?php echo $viewall_button_text; ?></a>
</li>
</ul>
</div>

View File

@ -43,10 +43,10 @@
<dt><?php echo 'Created by'; ?></dt>
<dd>
<?php
if (isset($creator['User']['email'])) {
echo h($creator['User']['email']);
if (isset($org['Organisation']['created_by_email'])) {
echo h($org['Organisation']['created_by_email']);
} else {
echo "SYSTEM";
echo "Unknown";
}
?>
&nbsp;