Added pagination, sorting & searching to users list

As requested on #113
This commit is contained in:
Dan Brown 2016-05-22 10:44:31 +01:00
parent 23ab1f0c81
commit be517de7dc
7 changed files with 123 additions and 17 deletions

View File

@ -31,14 +31,21 @@ class UserController extends Controller
/** /**
* Display a listing of the users. * Display a listing of the users.
* @param Request $request
* @return Response * @return Response
*/ */
public function index() public function index(Request $request)
{ {
$this->checkPermission('users-manage'); $this->checkPermission('users-manage');
$users = $this->userRepo->getAllUsers(); $listDetails = [
'order' => $request->has('order') ? $request->get('order') : 'asc',
'search' => $request->has('search') ? $request->get('search') : '',
'sort' => $request->has('sort') ? $request->get('sort') : 'name',
];
$users = $this->userRepo->getAllUsersPaginatedAndSorted(20, $listDetails);
$this->setPageTitle('Users'); $this->setPageTitle('Users');
return view('users/index', ['users' => $users]); $users->appends($listDetails);
return view('users/index', ['users' => $users, 'listDetails' => $listDetails]);
} }
/** /**

View File

@ -51,6 +51,27 @@ class UserRepo
return $this->user->with('roles', 'avatar')->orderBy('name', 'asc')->get(); return $this->user->with('roles', 'avatar')->orderBy('name', 'asc')->get();
} }
/**
* Get all the users with their permissions in a paginated format.
* @param int $count
* @param $sortData
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function getAllUsersPaginatedAndSorted($count = 20, $sortData)
{
$query = $this->user->with('roles', 'avatar')->orderBy($sortData['sort'], $sortData['order']);
if ($sortData['search']) {
$term = '%' . $sortData['search'] . '%';
$query->where(function($query) use ($term) {
$query->where('name', 'like', $term)
->orWhere('email', 'like', $term);
});
}
return $query->paginate($count);
}
/** /**
* Creates a new user and attaches a role to them. * Creates a new user and attaches a role to them.
* @param array $data * @param array $data

View File

@ -59,3 +59,35 @@ function setting($key, $default = false)
$settingService = app('BookStack\Services\SettingService'); $settingService = app('BookStack\Services\SettingService');
return $settingService->get($key, $default); return $settingService->get($key, $default);
} }
/**
* Generate a url with multiple parameters for sorting purposes.
* Works out the logic to set the correct sorting direction
* Discards empty parameters and allows overriding.
* @param $path
* @param array $data
* @param array $overrideData
* @return string
*/
function sortUrl($path, $data, $overrideData = [])
{
$queryStringSections = [];
$queryData = array_merge($data, $overrideData);
// Change sorting direction is already sorted on current attribute
if (isset($overrideData['sort']) && $overrideData['sort'] === $data['sort']) {
$queryData['order'] = ($data['order'] === 'asc') ? 'desc' : 'asc';
} else {
$queryData['order'] = 'asc';
}
foreach ($queryData as $name => $value) {
$trimmedVal = trim($value);
if ($trimmedVal === '') continue;
$queryStringSections[] = urlencode($name) . '=' . urlencode($trimmedVal);
}
if (count($queryStringSections) === 0) return $path;
return $path . '?' . implode('&', $queryStringSections);
}

View File

@ -266,6 +266,7 @@ ul.pagination {
display: inline-block; display: inline-block;
list-style: none; list-style: none;
margin: $-m 0; margin: $-m 0;
padding-left: 1px;
li { li {
float: left; float: left;
} }
@ -300,6 +301,10 @@ ul.pagination {
} }
} }
.compact ul.pagination {
margin: 0;
}
.entity-list { .entity-list {
>div { >div {
padding: $-m 0; padding: $-m 0;

View File

@ -297,6 +297,12 @@ span.sep {
display: block; display: block;
} }
.action-header {
h1 {
margin-top: $-m;
}
}
/** /**
* Icons * Icons
*/ */

View File

@ -6,11 +6,15 @@
<div class="container small"> <div class="container small">
<h1>User Roles</h1> <div class="row action-header">
<div class="col-sm-8">
<p> <h1>User Roles</h1>
<a href="/settings/roles/new" class="text-pos"><i class="zmdi zmdi-lock-open"></i>Add new role</a> </div>
</p> <div class="col-sm-4">
<p></p>
<a href="/settings/roles/new" class="button float right pos"><i class="zmdi zmdi-lock-open"></i>Add new role</a>
</div>
</div>
<table class="table"> <table class="table">
<tr> <tr>

View File

@ -7,17 +7,42 @@
<div class="container small" ng-non-bindable> <div class="container small" ng-non-bindable>
<h1>Users</h1> <div class="row action-header">
@if(userCan('users-manage')) <div class="col-sm-8">
<p> <h1>Users</h1>
<a href="/settings/users/create" class="text-pos"><i class="zmdi zmdi-account-add"></i>Add new user</a> </div>
</p> <div class="col-sm-4">
@endif <p></p>
@if(userCan('users-manage'))
<a href="/settings/users/create" class="pos button float right"><i class="zmdi zmdi-account-add"></i>Add new user</a>
@endif
</div>
</div>
<div class="row">
<div class="col-sm-8">
<div class="compact">
{!! $users->links() !!}
</div>
</div>
<div class="col-sm-4">
<form method="get" class="float right" action="/settings/users">
@foreach(collect($listDetails)->except('search') as $name => $val)
<input type="hidden" name="{{$name}}" value="{{$val}}">
@endforeach
<input type="text" name="search" placeholder="Search Users" @if($listDetails['search']) value="{{$listDetails['search']}}" @endif>
</form>
</div>
</div>
<div class="text-center">
</div>
<table class="table"> <table class="table">
<tr> <tr>
<th></th> <th></th>
<th>Name</th> <th><a href="{{ sortUrl('/settings/users', $listDetails, ['sort' => 'name']) }}">Name</a></th>
<th>Email</th> <th><a href="{{ sortUrl('/settings/users', $listDetails, ['sort' => 'email']) }}">Email</a></th>
<th>User Roles</th> <th>User Roles</th>
</tr> </tr>
@foreach($users as $user) @foreach($users as $user)
@ -42,11 +67,17 @@
@endif @endif
</td> </td>
<td> <td>
<small> {{ $user->roles->implode('display_name', ', ') }}</small> @foreach($user->roles as $index => $role)
<small><a href="/settings/roles/{{$role->id}}">{{$role->display_name}}</a>@if($index !== count($user->roles) -1),@endif</small>
@endforeach
</td> </td>
</tr> </tr>
@endforeach @endforeach
</table> </table>
<div>
{!! $users->links() !!}
</div>
</div> </div>
@stop @stop