Skip to content

Commit ec79517

Browse files
committed
Sorting: Added auto sort option to book sort UI
Includes indicator on books added to sort operation.
1 parent ccd9468 commit ec79517

File tree

8 files changed

+74
-18
lines changed

8 files changed

+74
-18
lines changed

app/Sorting/BookSortController.php

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,24 +44,40 @@ public function showItem(string $bookSlug)
4444
}
4545

4646
/**
47-
* Sorts a book using a given mapping array.
47+
* Update the sort options of a book, setting the auto-sort and/or updating
48+
* child order via mapping.
4849
*/
4950
public function update(Request $request, BookSorter $sorter, string $bookSlug)
5051
{
5152
$book = $this->queries->findVisibleBySlugOrFail($bookSlug);
5253
$this->checkOwnablePermission('book-update', $book);
54+
$loggedActivityForBook = false;
5355

54-
// Return if no map sent
55-
if (!$request->filled('sort-tree')) {
56-
return redirect($book->getUrl());
57-
}
56+
// Sort via map
57+
if ($request->filled('sort-tree')) {
58+
$sortMap = BookSortMap::fromJson($request->get('sort-tree'));
59+
$booksInvolved = $sorter->sortUsingMap($sortMap);
5860

59-
$sortMap = BookSortMap::fromJson($request->get('sort-tree'));
60-
$booksInvolved = $sorter->sortUsingMap($sortMap);
61+
// Rebuild permissions and add activity for involved books.
62+
foreach ($booksInvolved as $bookInvolved) {
63+
Activity::add(ActivityType::BOOK_SORT, $bookInvolved);
64+
if ($bookInvolved->id === $book->id) {
65+
$loggedActivityForBook = true;
66+
}
67+
}
68+
}
6169

62-
// Rebuild permissions and add activity for involved books.
63-
foreach ($booksInvolved as $bookInvolved) {
64-
Activity::add(ActivityType::BOOK_SORT, $bookInvolved);
70+
if ($request->filled('auto-sort')) {
71+
$sortSetId = intval($request->get('auto-sort')) ?: null;
72+
if ($sortSetId && SortSet::query()->find($sortSetId) === null) {
73+
$sortSetId = null;
74+
}
75+
$book->sort_set_id = $sortSetId;
76+
$book->save();
77+
$sorter->runBookAutoSort($book);
78+
if (!$loggedActivityForBook) {
79+
Activity::add(ActivityType::BOOK_SORT, $book);
80+
}
6581
}
6682

6783
return redirect($book->getUrl());

app/Sorting/SortSet.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use BookStack\Activity\Models\Loggable;
66
use BookStack\Entities\Models\Book;
77
use Carbon\Carbon;
8+
use Illuminate\Database\Eloquent\Collection;
89
use Illuminate\Database\Eloquent\Model;
910
use Illuminate\Database\Eloquent\Relations\HasMany;
1011

@@ -48,4 +49,12 @@ public function books(): HasMany
4849
{
4950
return $this->hasMany(Book::class);
5051
}
52+
53+
public static function allByName(): Collection
54+
{
55+
return static::query()
56+
->withCount('books')
57+
->orderBy('name', 'asc')
58+
->get();
59+
}
5160
}

lang/en/entities.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@
166166
'books_search_this' => 'Search this book',
167167
'books_navigation' => 'Book Navigation',
168168
'books_sort' => 'Sort Book Contents',
169-
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books.',
169+
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort option can be set to automatically sort this book\'s contents upon changes.',
170+
'books_sort_auto_sort' => 'Auto Sort Option',
171+
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
170172
'books_sort_named' => 'Sort Book :bookName',
171173
'books_sort_name' => 'Sort by Name',
172174
'books_sort_created' => 'Sort by Created Date',

resources/icons/auto-sort.svg

Lines changed: 1 addition & 0 deletions
Loading

resources/sass/_lists.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,10 @@
242242
margin-bottom: vars.$m;
243243
padding: vars.$m vars.$xl;
244244
position: relative;
245+
summary:focus {
246+
outline: 1px dashed var(--color-primary);
247+
outline-offset: 5px;
248+
}
245249
&::before {
246250
pointer-events: none;
247251
content: '';

resources/views/books/parts/sort-box.blade.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
<span>@icon('book')</span>
99
<span>{{ $book->name }}</span>
1010
</div>
11+
<div class="flex-container-row items-center text-book">
12+
@if($book->sortSet)
13+
<span title="{{ trans('entities.books_sort_auto_sort_active', ['sortName' => $book->sortSet->name]) }}">@icon('auto-sort')</span>
14+
@endif
15+
</div>
1116
</h5>
1217
</summary>
1318
<div class="sort-box-options pb-sm">

resources/views/books/sort.blade.php

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,36 @@
1818
<div>
1919
<div component="book-sort" class="card content-wrap auto-height">
2020
<h1 class="list-heading">{{ trans('entities.books_sort') }}</h1>
21-
<p class="text-muted">{{ trans('entities.books_sort_desc') }}</p>
21+
22+
<div class="flex-container-row gap-m wrap mb-m">
23+
<p class="text-muted flex min-width-s mb-none">{{ trans('entities.books_sort_desc') }}</p>
24+
<div class="min-width-s">
25+
@php
26+
$autoSortVal = intval(old('auto-sort') ?? $book->sort_set_id ?? 0);
27+
@endphp
28+
<label for="auto-sort">{{ trans('entities.books_sort_auto_sort') }}</label>
29+
<select id="auto-sort"
30+
name="auto-sort"
31+
form="sort-form"
32+
class="{{ $errors->has('auto-sort') ? 'neg' : '' }}">
33+
<option value="0" @if($autoSortVal === 0) selected @endif>-- {{ trans('common.none') }} --</option>
34+
@foreach(\BookStack\Sorting\SortSet::allByName() as $set)
35+
<option value="{{$set->id}}"
36+
@if($autoSortVal === $set->id) selected @endif
37+
>
38+
{{ $set->name }}
39+
</option>
40+
@endforeach
41+
</select>
42+
</div>
43+
</div>
2244

2345
<div refs="book-sort@sortContainer">
2446
@include('books.parts.sort-box', ['book' => $book, 'bookChildren' => $bookChildren])
2547
</div>
2648

27-
<form action="{{ $book->getUrl('/sort') }}" method="POST">
28-
{!! csrf_field() !!}
49+
<form id="sort-form" action="{{ $book->getUrl('/sort') }}" method="POST">
50+
{{ csrf_field() }}
2951
<input type="hidden" name="_method" value="PUT">
3052
<input refs="book-sort@input" type="hidden" name="sort-tree">
3153
<div class="list text-right">

resources/views/settings/categories/sorting.blade.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
@extends('settings.layout')
22

33
@php
4-
$sortSets = \BookStack\Sorting\SortSet::query()
5-
->withCount('books')
6-
->orderBy('name', 'asc')
7-
->get();
4+
$sortSets = \BookStack\Sorting\SortSet::allByName();
85
@endphp
96

107
@section('card')

0 commit comments

Comments
 (0)