Skip to content

Commit

Permalink
#1332 Add filters and pagination to users list
Browse files Browse the repository at this point in the history
  • Loading branch information
nadouani committed Jul 20, 2020
1 parent 7d4aa7d commit 0314a95
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 58 deletions.
3 changes: 0 additions & 3 deletions frontend/app/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,6 @@ angular.module('thehive', [
organisation: function($stateParams, OrganisationSrv) {
return OrganisationSrv.get($stateParams.organisation);
},
users: function($stateParams, OrganisationSrv) {
return OrganisationSrv.users($stateParams.organisation);
},
templates: function($stateParams, OrganisationSrv) {
return OrganisationSrv.caseTemplates($stateParams.organisation);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
self.currentUser = AuthenticationSrv.currentUser;

self.$onInit = function() {
// TODO FIX ME
self.canSetPass = true;
self.canSetPass = this.setPasswordEnabled;
};

self.reload = function() {
Expand Down Expand Up @@ -203,6 +202,7 @@
bindings: {
users: '<',
mfaEnabled: '<',
setPasswordEnabled: '<',
onReload: '&',
onEdit: '&'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,106 @@
'use strict';

angular.module('theHiveControllers').controller('OrgDetailsCtrl',
function($scope, $q, $uibModal, OrganisationSrv, NotificationSrv, UserSrv, organisation, users, templates, fields, appConfig, uiConfig) {
function($scope, $q, $uibModal, FilteringSrv, PaginatedQuerySrv, OrganisationSrv, NotificationSrv, UserSrv, organisation, /*users, */templates, fields, appConfig, uiConfig) {
var self = this;

this.uiConfig = uiConfig;
this.org = organisation;
this.users = users;
//this.users = users;
this.templates = templates;
this.fields = fields;
this.canChangeMfa = appConfig.config.capabilities.indexOf('mfa') !== -1;
this.canSetPass = appConfig.config.capabilities.indexOf('setPassword') !== -1;

this.getUserInfo = UserSrv.getCache;

this.reloadUsers = function() {
OrganisationSrv.users(self.org.name)
.then(function(users) {
self.users = users;
})
.catch(function(err) {
NotificationSrv.error('OrgDetailsCtrl', err.data, err.status);
this.$onInit = function() {
self.filtering = new FilteringSrv('user', 'user.list', {
version: 'v1',
defaults: {
showFilters: true,
showStats: false,
pageSize: 15,
//sort: ['-flag', '-startDate']
},
defaultFilter: []
});

self.filtering.initContext(self.org.name)
.then(function() {
self.loadUsers();

$scope.$watch('$vm.users.pageSize', function (newValue) {
self.filtering.setPageSize(newValue);
});
});
};

this.loadUsers = function() {

self.users = new PaginatedQuerySrv({
name: 'organisation-users',
version: 'v1',
skipStream: true,
sort: self.filtering.context.sort,
loadAll: false,
pageSize: self.filtering.context.pageSize,
filter: this.filtering.buildQuery(),
operations: [{
'_name': 'getOrganisation',
'idOrName': self.org.name
},
{
'_name': 'users'
}
],
config: {
headers: {
'X-Organisation': self.org.name
}
}
});
};

this.showUserDialog = function(user) {
UserSrv.openModal(user, self.org.name)
.then(function() {
self.reloadUsers();
self.loadUsers();
})
.catch(function(err) {
if (err && !_.isString(err)) {
NotificationSrv.error('OrgDetailsCtrl', err.data, err.status);
}
});
};

// Filtering
this.toggleFilters = function () {
this.filtering.toggleFilters();
};

this.filter = function () {
self.filtering.filter().then(this.applyFilters);
};

this.clearFilters = function () {
this.filtering.clearFilters()
.then(self.search);
};

this.removeFilter = function (index) {
self.filtering.removeFilter(index)
.then(self.search);
};

this.search = function () {
self.loadUsers();
self.filtering.storeContext();
};
this.addFilterValue = function (field, value) {
this.filtering.addFilterValue(field, value);
this.search();
};

});
})();
8 changes: 8 additions & 0 deletions frontend/app/scripts/services/common/QuerySrv.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@
};
}

if(options && options.config) {
config = _.extend({}, config, options.config);
}

return self.query(version, operations, config)
.then(function(response) {
return $q.resolve(response.data);
Expand Down Expand Up @@ -99,6 +103,10 @@
};
}

if(options && options.config) {
config = _.extend({}, config, options.config);
}

// Add filters
operations.push({'_name': 'count'});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
this.withStats = options.withStats || undefined;
this.extraData = options.extraData || undefined;
this.name = options.name || undefined;
this.config = options.config || {};

this.operations = options.operations;

Expand Down Expand Up @@ -130,7 +131,7 @@
filter: filters,
sort: self.getSort(),
page: self.getPage(),
config: {},
config: self.config,
withParent: false,
name: self.name
}).then(function(data) {
Expand All @@ -157,7 +158,7 @@
QuerySrv.count('v1', this.operations, {
filter: filters,
name: self.name,
config: {}
config: self.config,
}).then(function(total) {
self.total = total;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<div class="col-md-12" ng-show="$cmp.list.total > 0">
<div class="btn-toolbar" role="toolbar">
<div class="btn-group pull-right" role="group">
<page-sizer collection="$cmp.list" sizes="[1, 2, 10, 15, 30, 100]"></page-sizer>
<page-sizer collection="$cmp.list" sizes="[10, 15, 30, 100]"></page-sizer>
</div>
</div>

Expand Down
57 changes: 25 additions & 32 deletions frontend/app/views/components/org/user.list.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,38 @@
<a class="btn btn-primary pull-right" href ng-click="$ctrl.openModal('create', {})"><i class="fa fa-plus"></i> Add user</a>
</p> -->

<div class="row" ng-if="$ctrl.users.length === 0">
<div class="row" ng-if="$ctrl.users.total === 0">
<div class="col-md-12">
<div class="empty-message">No users defined.</div>
</div>
</div>

<div class="row" ng-if="$ctrl.users.length > 0">
<div class="row" ng-if="$ctrl.users.total > 0">
<div class="col-md-12">
<table class="table table-striped case-list valigned">
<thead>
<tr>
<th style="width: 120px">Status</th>
<th>User details</th>
<th></th>
<th style="width: 80px">Status</th>
<th>Login</th>
<th style="width: 150px">Full Name</th>
<th style="width: 140px">Profile</th>
<th>Password</th>
<th>API Key</th>
<th class="text-center" style="width: 100px" ng-if="$ctrl.mfaEnabled">MFA</th>
<th style="width: 180px"></th>
<th style="width: 100px"></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in $ctrl.users track by user._id">
<tr ng-repeat="user in $ctrl.users.values track by user._id">
<td>
<span class="label label-default label-lg" ng-class="{false: 'label-success', true: 'label-danger'}[user.locked]">{{user.locked === false ? 'Active' : 'Locked'}}</span>
</td>
<td>{{user.login}}</td>
<td>{{user.name}}</td>
<td>
<h4 class="media-heading">
<small class="mr-xxs">
<strong>Login:</strong> {{user.login}}</small>
</h4>
<h4 class="media-heading">
<small class="mr-xxs">
<strong>Full name:</strong> {{user.name}}</small>
</h4>
</td>
<td>
<h4 class="media-heading"
popover-trigger="'mouseenter'"
uib-popover-template="'permissionsPopoverTemplate.html'"
popover-title="Permissions">
<small class="mr-xxs">
<strong>Profile:</strong> {{user.profile}}</small>
</h4>
<span popover-trigger="'mouseenter'" uib-popover-template="'permissionsPopoverTemplate.html'" popover-title="Permissions">
{{user.profile}}
</span>
</td>
<td>
<span>
Expand Down Expand Up @@ -93,17 +82,21 @@ <h4 class="media-heading">
</span>
</td>
<td>
<span class="clickable mr-xxxs text-primary" ng-click="$ctrl.editUser(user)">
<i class="fa fa-edit"></i>Edit</span>
<span class="clickable mr-xxs text-primary" ng-click="$ctrl.editUser(user)" uib-tooltip="Edit User">
<i class="text-20 fa fa-edit"></i>
</span>

<span class="clickable mr-xxxs text-danger" ng-if="!user.locked && user._id !== $ctrl.currentUser._id" ng-click="$ctrl.lockUser(user, true)">
<i class="fa fa-ban"></i>Lock</span>
<span class="clickable mr-xxs text-primary" ng-if="!user.locked && user._id !== $ctrl.currentUser._id" ng-click="$ctrl.lockUser(user, true)" uib-tooltip="Lock User">
<i class="text-20 fa fa-lock"></i>
</span>

<span class="clickable mr-xxxs text-success" ng-if="user.locked && user._id !== $ctrl.currentUser._id" ng-click="$ctrl.lockUser(user, false)">
<i class="fa fa-refresh"></i>Unlock</span>
<span class="clickable mr-xxs text-primary" ng-if="user.locked && user._id !== $ctrl.currentUser._id" ng-click="$ctrl.lockUser(user, false)" uib-tooltip="Unlock User">
<i class="text-20 fa fa-unlock-alt"></i>
</span>

<span class="clickable mr-xxxs text-danger" ng-if="user._id !== $ctrl.currentUser._id" ng-click="$ctrl.removeUser(user)">
<i class="fa fa-trash"></i>Remove</span>
<span class="clickable mr-xxs text-danger" ng-if="user._id !== $ctrl.currentUser._id" ng-click="$ctrl.removeUser(user)" uib-tooltip="Delete User">
<i class="text-20 fa fa-trash"></i>
</span>
</td>
</tr>
</tbody>
Expand Down
30 changes: 24 additions & 6 deletions frontend/app/views/partials/admin/organisation/details.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,37 @@ <h3 class="box-title">
<div class="row mb-xs">
<div class="col-md-12">
<div class="btn-toolbar" role="toolbar">
<!-- <button class="btn btn-sm btn-primary" type="button" ng-click="$vm.addUser()">
<i class="fa fa-link"></i>
Add existing user
</button> -->

<button class="btn btn-sm btn-primary" type="button" ng-click="$vm.showUserDialog()">
<i class="fa fa-plus"></i>
Create new user
</button>

<div class="btn-group pull-right" role="group">
<page-sizer collection="$vm.users" sizes="[10, 15, 30, 100]"></page-sizer>
</div>

<div class="btn-group pull-right" role="group">
<button class="btn btn-sm" ng-class="{true: 'btn-primary', false:'btn-default'}[$vm.filtering.context.showFilters]" type="button" ng-click="$vm.toggleFilters()">
<i class="fa fa-search"></i> Filters
</button>
</div>
</div>
</div>

<div class="col-md-12">
<div class="mt-s filter-panel" ng-include="'views/partials/admin/organisation/list/filters.html'" ng-show="$vm.filtering.context.showFilters"></div>

<div class="row mt-s">
<div class="col-md-12 clearfix">

<filters-preview filters="$vm.filtering.context.filters"
on-clear-item="$vm.removeFilter(field)"
on-clear-all="$vm.clearFilters()"></filters-preview>
</div>
</div>
</div>
</div>
<org-user-list users="$vm.users" on-reload="$vm.reloadUsers()" on-edit="$vm.showUserDialog(user)" mfa-enabled="$vm.canChangeMfa"></org-user-list>
<org-user-list users="$vm.users" on-reload="$vm.loadUsers()" on-edit="$vm.showUserDialog(user)" set-password-enabled="$vm.canSetPass" mfa-enabled="$vm.canChangeMfa"></org-user-list>
</div>
</uib-tab>
<uib-tab index="1" if-permission="manageCaseTemplate">
Expand Down
38 changes: 38 additions & 0 deletions frontend/app/views/partials/admin/organisation/list/filters.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<div class="row">
<div class="col-md-12 active-filters">
<h4>Filters</h4>
<form ng-submit="$vm.search()">
<div class="row mb-xxxs" ng-repeat="filter in $vm.filtering.context.filters track by $index">
<div class="col-sm-4 col-md-4 col-lg-2">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="$vm.removeFilter($index)">
<i class="fa fa-times text-danger"></i>
</button>
</span>
<select class="form-control" ng-model="filter.field"
ng-options="item.name as item.name for (key, item) in $vm.filtering.attributes"
ng-change="$vm.filtering.setFilterField(filter, config.entity)"></select>
</div>
</div>
<div class="col-sm-8 col-md-8 col-lg-6">
<filter-editor metadata="$vm.filtering.metadata" filter="filter" entity="$vm.filtering.entity"></filter-editor>
</div>
</div>
<div class="mv-xs row">
<div class="col-sm-12 col-md-12 col-lg-8">
<a href class="btn btn-sm btn-link btn-clear" ng-click="$vm.filtering.addFilter()">
<i class="fa fa-plus"></i> Add a filter
</a>
<a href class="btn btn-sm btn-danger" ng-click="$vm.clearFilters()" ng-if="$vm.filtering.context.filters.length > 0">
<i class="fa fa-times"></i> Clear
</a>
<button href class="btn btn-sm btn-primary pull-right" type="submit" ng-if="$vm.filtering.context.filters.length > 0">
<i class="fa fa-search"></i> Search
</button>
</div>
</div>
</form>

</div>
</div>
4 changes: 2 additions & 2 deletions frontend/app/views/partials/case/case.list.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ <h3 class="box-title">List of cases ({{$vm.list.total || 0}} of {{$vm.caseStats.
<thead>
<tr>
<th style="width: 10px;" class="p-0"></th>
<th width="20px" if-permission="manageCase">
<input type="checkbox" ng-model="$vm.menu.selectAll" ng-change="$vm.selectAll()">
<th width="20px">
<input if-permission="manageCase" type="checkbox" ng-model="$vm.menu.selectAll" ng-change="$vm.selectAll()">
</th>
<th>Title</th>
<th style="width: 70px;"></th>
Expand Down

0 comments on commit 0314a95

Please sign in to comment.