Skip to content

Revision of item list views #3821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Nov 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
986346a
Redesigned users list to be responsive and aligned
ssddanbrown Oct 29, 2022
0ef06fd
Extracted user list item to its own template
ssddanbrown Oct 29, 2022
98b59a1
Revised role index list to align with user list
ssddanbrown Oct 29, 2022
f75091a
Revised webhooks list to new format
ssddanbrown Oct 30, 2022
ec4cbbd
Refactored common list handling operations to new class
ssddanbrown Oct 30, 2022
2c114e1
Split out user controller preference methods to new controller
ssddanbrown Oct 30, 2022
ab184c0
Updated API tokens list to new responsive format
ssddanbrown Oct 30, 2022
2bbf7b2
Revised audit log list to new responsive format
ssddanbrown Oct 30, 2022
be320c5
Adjusted audit log row spacing a tad
ssddanbrown Oct 30, 2022
09f2bc2
Removed addition detail spacing in audit list
ssddanbrown Oct 30, 2022
9e8516c
Tweaked list spacings a little to align paddings
ssddanbrown Oct 30, 2022
80d2889
Updated tags list to new responsive format
ssddanbrown Oct 31, 2022
de807f8
Updated recycle bin list to new responsive layout
ssddanbrown Oct 31, 2022
d4e71e4
Revised revision list to responsive layout
ssddanbrown Oct 31, 2022
f809bd3
Updated tests to align with recent list changes
ssddanbrown Nov 1, 2022
7101ec0
Updated search term lists to flex layouts
ssddanbrown Nov 3, 2022
8ec6b07
Updated role permission table to responsive format
ssddanbrown Nov 3, 2022
6364c54
Fixed phpstan static usage warning, updated ci flows
ssddanbrown Nov 3, 2022
37afd35
Fixed use of array unpacking syntax
ssddanbrown Nov 3, 2022
9e8240a
Addressed additional unsupported array spread operation
ssddanbrown Nov 3, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/analyse-php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ jobs:
- name: Get Composer Cache Directory
id: composer-cache
run: |
echo "::set-output name=dir::$(composer config cache-files-dir)"
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

- name: Cache composer packages
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-8.1
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-migrations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
- name: Get Composer Cache Directory
id: composer-cache
run: |
echo "::set-output name=dir::$(composer config cache-files-dir)"
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

- name: Cache composer packages
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ matrix.php }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
- name: Get Composer Cache Directory
id: composer-cache
run: |
echo "::set-output name=dir::$(composer config cache-files-dir)"
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

- name: Cache composer packages
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ matrix.php }}
Expand Down
30 changes: 30 additions & 0 deletions app/Actions/Queries/WebhooksAllPaginatedAndSorted.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace BookStack\Actions\Queries;

use BookStack\Actions\Webhook;
use BookStack\Util\SimpleListOptions;
use Illuminate\Pagination\LengthAwarePaginator;

/**
* Get all the webhooks in the system in a paginated format.
*/
class WebhooksAllPaginatedAndSorted
{
public function run(int $count, SimpleListOptions $listOptions): LengthAwarePaginator
{
$query = Webhook::query()->select(['*'])
->withCount(['trackedEvents'])
->orderBy($listOptions->getSort(), $listOptions->getOrder());

if ($listOptions->getSearch()) {
$term = '%' . $listOptions->getSearch() . '%';
$query->where(function ($query) use ($term) {
$query->where('name', 'like', $term)
->orWhere('endpoint', 'like', $term);
});
}

return $query->paginate($count);
}
}
11 changes: 9 additions & 2 deletions app/Actions/TagRepo.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use BookStack\Auth\Permissions\PermissionApplicator;
use BookStack\Entities\Models\Entity;
use BookStack\Util\SimpleListOptions;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
Expand All @@ -20,8 +21,14 @@ public function __construct(PermissionApplicator $permissions)
/**
* Start a query against all tags in the system.
*/
public function queryWithTotals(string $searchTerm, string $nameFilter): Builder
public function queryWithTotals(SimpleListOptions $listOptions, string $nameFilter): Builder
{
$searchTerm = $listOptions->getSearch();
$sort = $listOptions->getSort();
if ($sort === 'name' && $nameFilter) {
$sort = 'value';
}

$query = Tag::query()
->select([
'name',
Expand All @@ -32,7 +39,7 @@ public function queryWithTotals(string $searchTerm, string $nameFilter): Builder
DB::raw('SUM(IF(entity_type = \'book\', 1, 0)) as book_count'),
DB::raw('SUM(IF(entity_type = \'bookshelf\', 1, 0)) as shelf_count'),
])
->orderBy($nameFilter ? 'value' : 'name');
->orderBy($sort, $listOptions->getOrder());

if ($nameFilter) {
$query->where('name', '=', $nameFilter);
Expand Down
35 changes: 35 additions & 0 deletions app/Auth/Queries/RolesAllPaginatedAndSorted.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace BookStack\Auth\Queries;

use BookStack\Auth\Role;
use BookStack\Util\SimpleListOptions;
use Illuminate\Pagination\LengthAwarePaginator;

/**
* Get all the roles in the system in a paginated format.
*/
class RolesAllPaginatedAndSorted
{
public function run(int $count, SimpleListOptions $listOptions): LengthAwarePaginator
{
$sort = $listOptions->getSort();
if ($sort === 'created_at') {
$sort = 'users.created_at';
}

$query = Role::query()->select(['*'])
->withCount(['users', 'permissions'])
->orderBy($sort, $listOptions->getOrder());

if ($listOptions->getSearch()) {
$term = '%' . $listOptions->getSearch() . '%';
$query->where(function ($query) use ($term) {
$query->where('display_name', 'like', $term)
->orWhere('description', 'like', $term);
});
}

return $query->paginate($count);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace BookStack\Auth\Queries;

use BookStack\Auth\User;
use BookStack\Util\SimpleListOptions;
use Illuminate\Pagination\LengthAwarePaginator;

/**
Expand All @@ -11,23 +12,23 @@
* user is assumed to be trusted. (Admin users).
* Email search can be abused to extract email addresses.
*/
class AllUsersPaginatedAndSorted
class UsersAllPaginatedAndSorted
{
/**
* @param array{sort: string, order: string, search: string} $sortData
*/
public function run(int $count, array $sortData): LengthAwarePaginator
public function run(int $count, SimpleListOptions $listOptions): LengthAwarePaginator
{
$sort = $sortData['sort'];
$sort = $listOptions->getSort();
if ($sort === 'created_at') {
$sort = 'users.created_at';
}

$query = User::query()->select(['*'])
->scopes(['withLastActivityAt'])
->with(['roles', 'avatar'])
->withCount('mfaValues')
->orderBy($sort, $sortData['order']);
->orderBy($sort, $listOptions->getOrder());

if ($sortData['search']) {
$term = '%' . $sortData['search'] . '%';
if ($listOptions->getSearch()) {
$term = '%' . $listOptions->getSearch() . '%';
$query->where(function ($query) use ($term) {
$query->where('name', 'like', $term)
->orWhere('email', 'like', $term);
Expand Down
8 changes: 0 additions & 8 deletions app/Auth/Role.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,6 @@ public static function getSystemRole(string $systemName): ?self
return static::query()->where('system_name', '=', $systemName)->first();
}

/**
* Get all visible roles.
*/
public static function visible(): Collection
{
return static::query()->where('hidden', '=', false)->orderBy('name')->get();
}

/**
* {@inheritdoc}
*/
Expand Down
46 changes: 26 additions & 20 deletions app/Http/Controllers/AuditLogController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace BookStack\Http\Controllers;

use BookStack\Actions\Activity;
use BookStack\Actions\ActivityType;
use BookStack\Util\SimpleListOptions;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

Expand All @@ -13,10 +15,15 @@ public function index(Request $request)
$this->checkPermission('settings-manage');
$this->checkPermission('users-manage');

$listDetails = [
'order' => $request->get('order', 'desc'),
$sort = $request->get('sort', 'activity_date');
$order = $request->get('order', 'desc');
$listOptions = (new SimpleListOptions('', $sort, $order))->withSortOptions([
'created_at' => trans('settings.audit_table_date'),
'type' => trans('settings.audit_table_event'),
]);

$filters = [
'event' => $request->get('event', ''),
'sort' => $request->get('sort', 'created_at'),
'date_from' => $request->get('date_from', ''),
'date_to' => $request->get('date_to', ''),
'user' => $request->get('user', ''),
Expand All @@ -25,39 +32,38 @@ public function index(Request $request)

$query = Activity::query()
->with([
'entity' => function ($query) {
$query->withTrashed();
},
'entity' => fn ($query) => $query->withTrashed(),
'user',
])
->orderBy($listDetails['sort'], $listDetails['order']);
->orderBy($listOptions->getSort(), $listOptions->getOrder());

if ($listDetails['event']) {
$query->where('type', '=', $listDetails['event']);
if ($filters['event']) {
$query->where('type', '=', $filters['event']);
}
if ($listDetails['user']) {
$query->where('user_id', '=', $listDetails['user']);
if ($filters['user']) {
$query->where('user_id', '=', $filters['user']);
}

if ($listDetails['date_from']) {
$query->where('created_at', '>=', $listDetails['date_from']);
if ($filters['date_from']) {
$query->where('created_at', '>=', $filters['date_from']);
}
if ($listDetails['date_to']) {
$query->where('created_at', '<=', $listDetails['date_to']);
if ($filters['date_to']) {
$query->where('created_at', '<=', $filters['date_to']);
}
if ($listDetails['ip']) {
$query->where('ip', 'like', $listDetails['ip'] . '%');
if ($filters['ip']) {
$query->where('ip', 'like', $filters['ip'] . '%');
}

$activities = $query->paginate(100);
$activities->appends($listDetails);
$activities->appends($request->all());

$types = DB::table('activities')->select('type')->distinct()->pluck('type');
$types = ActivityType::all();
$this->setPageTitle(trans('settings.audit'));

return view('settings.audit', [
'activities' => $activities,
'listDetails' => $listDetails,
'filters' => $filters,
'listOptions' => $listOptions,
'activityTypes' => $types,
]);
}
Expand Down
15 changes: 9 additions & 6 deletions app/Http/Controllers/BookController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use BookStack\Exceptions\NotFoundException;
use BookStack\Facades\Activity;
use BookStack\References\ReferenceFetcher;
use BookStack\Util\SimpleListOptions;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Throwable;
Expand All @@ -35,13 +36,16 @@ public function __construct(ShelfContext $entityContextManager, BookRepo $bookRe
/**
* Display a listing of the book.
*/
public function index()
public function index(Request $request)
{
$view = setting()->getForCurrentUser('books_view_type');
$sort = setting()->getForCurrentUser('books_sort', 'name');
$order = setting()->getForCurrentUser('books_sort_order', 'asc');
$listOptions = SimpleListOptions::fromRequest($request, 'books')->withSortOptions([
'name' => trans('common.sort_name'),
'created_at' => trans('common.sort_created_at'),
'updated_at' => trans('common.sort_updated_at'),
]);

$books = $this->bookRepo->getAllPaginated(18, $sort, $order);
$books = $this->bookRepo->getAllPaginated(18, $listOptions->getSort(), $listOptions->getOrder());
$recents = $this->isSignedIn() ? $this->bookRepo->getRecentlyViewed(4) : false;
$popular = $this->bookRepo->getPopular(4);
$new = $this->bookRepo->getRecentlyCreated(4);
Expand All @@ -56,8 +60,7 @@ public function index()
'popular' => $popular,
'new' => $new,
'view' => $view,
'sort' => $sort,
'order' => $order,
'listOptions' => $listOptions,
]);
}

Expand Down
31 changes: 16 additions & 15 deletions app/Http/Controllers/BookshelfController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use BookStack\Exceptions\ImageUploadException;
use BookStack\Exceptions\NotFoundException;
use BookStack\References\ReferenceFetcher;
use BookStack\Util\SimpleListOptions;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
Expand All @@ -30,18 +31,16 @@ public function __construct(BookshelfRepo $shelfRepo, ShelfContext $shelfContext
/**
* Display a listing of the book.
*/
public function index()
public function index(Request $request)
{
$view = setting()->getForCurrentUser('bookshelves_view_type');
$sort = setting()->getForCurrentUser('bookshelves_sort', 'name');
$order = setting()->getForCurrentUser('bookshelves_sort_order', 'asc');
$sortOptions = [
$listOptions = SimpleListOptions::fromRequest($request, 'bookshelves')->withSortOptions([
'name' => trans('common.sort_name'),
'created_at' => trans('common.sort_created_at'),
'updated_at' => trans('common.sort_updated_at'),
];
]);

$shelves = $this->shelfRepo->getAllPaginated(18, $sort, $order);
$shelves = $this->shelfRepo->getAllPaginated(18, $listOptions->getSort(), $listOptions->getOrder());
$recents = $this->isSignedIn() ? $this->shelfRepo->getRecentlyViewed(4) : false;
$popular = $this->shelfRepo->getPopular(4);
$new = $this->shelfRepo->getRecentlyCreated(4);
Expand All @@ -55,9 +54,7 @@ public function index()
'popular' => $popular,
'new' => $new,
'view' => $view,
'sort' => $sort,
'order' => $order,
'sortOptions' => $sortOptions,
'listOptions' => $listOptions,
]);
}

Expand Down Expand Up @@ -100,16 +97,21 @@ public function store(Request $request)
*
* @throws NotFoundException
*/
public function show(ActivityQueries $activities, string $slug)
public function show(Request $request, ActivityQueries $activities, string $slug)
{
$shelf = $this->shelfRepo->getBySlug($slug);
$this->checkOwnablePermission('bookshelf-view', $shelf);

$sort = setting()->getForCurrentUser('shelf_books_sort', 'default');
$order = setting()->getForCurrentUser('shelf_books_sort_order', 'asc');
$listOptions = SimpleListOptions::fromRequest($request, 'shelf_books')->withSortOptions([
'default' => trans('common.sort_default'),
'name' => trans('common.sort_name'),
'created_at' => trans('common.sort_created_at'),
'updated_at' => trans('common.sort_updated_at'),
]);

$sort = $listOptions->getSort();
$sortedVisibleShelfBooks = $shelf->visibleBooks()->get()
->sortBy($sort === 'default' ? 'pivot.order' : $sort, SORT_REGULAR, $order === 'desc')
->sortBy($sort === 'default' ? 'pivot.order' : $sort, SORT_REGULAR, $listOptions->getOrder() === 'desc')
->values()
->all();

Expand All @@ -124,8 +126,7 @@ public function show(ActivityQueries $activities, string $slug)
'sortedVisibleShelfBooks' => $sortedVisibleShelfBooks,
'view' => $view,
'activity' => $activities->entityActivity($shelf, 20, 1),
'order' => $order,
'sort' => $sort,
'listOptions' => $listOptions,
'referenceCount' => $this->referenceFetcher->getPageReferenceCountToEntity($shelf),
]);
}
Expand Down
Loading