Skip to content

Commit bf8a84a

Browse files
committed
Sorting: Started sort set routes and form
1 parent a34023f commit bf8a84a

File tree

7 files changed

+182
-6
lines changed

7 files changed

+182
-6
lines changed

app/Sorting/SortSetController.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace BookStack\Sorting;
4+
5+
use BookStack\Http\Controller;
6+
7+
class SortSetController extends Controller
8+
{
9+
public function __construct()
10+
{
11+
$this->middleware('can:settings-manage');
12+
// TODO - Test
13+
}
14+
15+
public function create()
16+
{
17+
return view('settings.sort-sets.create');
18+
}
19+
}

app/Sorting/SortSetOption.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,32 @@ enum SortSetOption: string
1313
case UpdateDateDesc = 'updated_date_desc';
1414
case ChaptersFirst = 'chapters_first';
1515
case ChaptersLast = 'chapters_last';
16+
17+
/**
18+
* Provide a translated label string for this option.
19+
*/
20+
public function getLabel(): string
21+
{
22+
$key = $this->value;
23+
$label = '';
24+
if (str_ends_with($key, '_asc')) {
25+
$key = substr($key, 0, -4);
26+
$label = trans('settings.sort_set_op_asc');
27+
} elseif (str_ends_with($key, '_desc')) {
28+
$key = substr($key, 0, -5);
29+
$label = trans('settings.sort_set_op_desc');
30+
}
31+
32+
$label = trans('settings.sort_set_op_' . $key) . ' ' . $label;
33+
return trim($label);
34+
}
35+
36+
/**
37+
* @return SortSetOption[]
38+
*/
39+
public static function allExcluding(array $options): array
40+
{
41+
$all = SortSetOption::cases();
42+
return array_diff($all, $options);
43+
}
1644
}

lang/en/settings.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,22 @@
8080
'sorting_book_default_desc' => 'Select the default sort set to apply to new books. This won\'t affect existing books, and can be overridden per-book.',
8181
'sorting_sets' => 'Sort Sets',
8282
'sorting_sets_desc' => 'These are predefined sorting operations which can be applied to content in the system.',
83+
'sort_set_create' => 'Create Sort Set',
84+
'sort_set_edit' => 'Edit Sort Set',
85+
'sort_set_details' => 'Sort Set Details',
86+
'sort_set_details_desc' => 'Set a name for this sort set, which will appear in lists when users are selecting a sort.',
87+
'sort_set_operations' => 'Sort Operations',
88+
'sort_set_operations_desc' => 'Configure the sort actions to be performed in this set by moving them from the list of available operations. Upon use, the operations will be applied in order, from top to bottom.',
89+
'sort_set_available_operations' => 'Available Operations',
90+
'sort_set_configured_operations' => 'Configured Operations',
91+
'sort_set_op_asc' => '(Asc)',
92+
'sort_set_op_desc' => '(Desc)',
93+
'sort_set_op_name' => 'Name - Alphabetical',
94+
'sort_set_op_name_numeric' => 'Name - Numeric',
95+
'sort_set_op_created_date' => 'Created Date',
96+
'sort_set_op_updated_date' => 'Updated Date',
97+
'sort_set_op_chapters_first' => 'Chapters First',
98+
'sort_set_op_chapters_last' => 'Chapters Last',
8399

84100
// Maintenance settings
85101
'maint' => 'Maintenance',

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,16 @@ class="setting-list-label">{{ trans('settings.sorting_book_default') }}</label>
4242

4343
@section('after-card')
4444
<div class="card content-wrap auto-height">
45-
<h2 class="list-heading">{{ trans('settings.sorting_sets') }}</h2>
46-
<p class="text-muted">{{ trans('settings.sorting_sets_desc') }}</p>
45+
<div class="flex-container-row items-center gap-m">
46+
<div class="flex">
47+
<h2 class="list-heading">{{ trans('settings.sorting_sets') }}</h2>
48+
<p class="text-muted">{{ trans('settings.sorting_sets_desc') }}</p>
49+
</div>
50+
<div>
51+
<a href="{{ url('/settings/sorting/sets/new') }}" class="button outline">{{ trans('settings.sort_set_create') }}</a>
52+
</div>
53+
</div>
54+
4755
{{-- TODO--}}
4856
</div>
4957
@endsection
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
@extends('layouts.simple')
2+
3+
@section('body')
4+
5+
<div class="container small">
6+
7+
@include('settings.parts.navbar', ['selected' => 'settings'])
8+
9+
<div class="card content-wrap auto-height">
10+
<h1 class="list-heading">{{ trans('settings.sort_set_create') }}</h1>
11+
12+
<form action="{{ url("/settings/sorting/sets") }}" method="POST">
13+
{{ csrf_field() }}
14+
@include('settings.sort-sets.parts.form', ['model' => null])
15+
16+
<div class="form-group text-right">
17+
<a href="{{ url("/settings/sorting") }}" class="button outline">{{ trans('common.cancel') }}</a>
18+
<button type="submit" class="button">{{ trans('common.save') }}</button>
19+
</div>
20+
</form>
21+
</div>
22+
</div>
23+
24+
@stop
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
2+
<div class="setting-list">
3+
<div class="grid half">
4+
<div>
5+
<label class="setting-list-label">{{ trans('settings.sort_set_details') }}</label>
6+
<p class="text-muted text-small">{{ trans('settings.sort_set_details_desc') }}</p>
7+
</div>
8+
<div>
9+
<div class="form-group">
10+
<label for="name">{{ trans('common.name') }}</label>
11+
@include('form.text', ['name' => 'name'])
12+
</div>
13+
</div>
14+
</div>
15+
16+
<div>
17+
<label class="setting-list-label">{{ trans('settings.sort_set_operations') }}</label>
18+
<p class="text-muted text-small">{{ trans('settings.sort_set_operations_desc') }}</p>
19+
20+
21+
22+
<div class="grid half">
23+
<div class="form-group">
24+
<label for="books" id="sort-set-configured-operations">{{ trans('settings.sort_set_configured_operations') }}</label>
25+
<ul refs="sort-set@configured-operations-list"
26+
aria-labelledby="sort-set-configured-operations"
27+
class="scroll-box">
28+
@foreach(($model?->getOptions() ?? []) as $option)
29+
<li data-id="{{ $option->value }}"
30+
class="scroll-box-item">
31+
<div class="handle px-s">@icon('grip')</div>
32+
<div>{{ $option->getLabel() }}</div>
33+
<div class="buttons flex-container-row items-center ml-auto px-xxs py-xs">
34+
<button type="button" data-action="move_up" class="icon-button p-xxs"
35+
title="{{ trans('entities.books_sort_move_up') }}">@icon('chevron-up')</button>
36+
<button type="button" data-action="move_down" class="icon-button p-xxs"
37+
title="{{ trans('entities.books_sort_move_down') }}">@icon('chevron-down')</button>
38+
<button type="button" data-action="remove" class="icon-button p-xxs"
39+
title="{{ trans('common.remove') }}">@icon('remove')</button>
40+
<button type="button" data-action="add" class="icon-button p-xxs"
41+
title="{{ trans('common.add') }}">@icon('add-small')</button>
42+
</div>
43+
</li>
44+
@endforeach
45+
</ul>
46+
</div>
47+
48+
<div class="form-group">
49+
<label for="books" id="sort-set-available-operations">{{ trans('settings.sort_set_available_operations') }}</label>
50+
<ul refs="sort-set@available-operations-list"
51+
aria-labelledby="sort-set-available-operations"
52+
class="scroll-box">
53+
@foreach(\BookStack\Sorting\SortSetOption::allExcluding($model?->getOptions() ?? []) as $option)
54+
<li data-id="{{ $option->value }}"
55+
class="scroll-box-item">
56+
<div class="handle px-s">@icon('grip')</div>
57+
<div>{{ $option->getLabel() }}</div>
58+
<div class="buttons flex-container-row items-center ml-auto px-xxs py-xs">
59+
<button type="button" data-action="move_up" class="icon-button p-xxs"
60+
title="{{ trans('entities.books_sort_move_up') }}">@icon('chevron-up')</button>
61+
<button type="button" data-action="move_down" class="icon-button p-xxs"
62+
title="{{ trans('entities.books_sort_move_down') }}">@icon('chevron-down')</button>
63+
<button type="button" data-action="remove" class="icon-button p-xxs"
64+
title="{{ trans('common.remove') }}">@icon('remove')</button>
65+
<button type="button" data-action="add" class="icon-button p-xxs"
66+
title="{{ trans('common.add') }}">@icon('add-small')</button>
67+
</div>
68+
</li>
69+
@endforeach
70+
</ul>
71+
</div>
72+
</div>
73+
</div>
74+
</div>

routes/web.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use BookStack\References\ReferenceController;
1414
use BookStack\Search\SearchController;
1515
use BookStack\Settings as SettingControllers;
16-
use BookStack\Sorting\BookSortController;
16+
use BookStack\Sorting as SortingControllers;
1717
use BookStack\Theming\ThemeController;
1818
use BookStack\Uploads\Controllers as UploadControllers;
1919
use BookStack\Users\Controllers as UserControllers;
@@ -67,16 +67,16 @@
6767
Route::get('/books/{slug}/edit', [EntityControllers\BookController::class, 'edit']);
6868
Route::put('/books/{slug}', [EntityControllers\BookController::class, 'update']);
6969
Route::delete('/books/{id}', [EntityControllers\BookController::class, 'destroy']);
70-
Route::get('/books/{slug}/sort-item', [BookSortController::class, 'showItem']);
70+
Route::get('/books/{slug}/sort-item', [SortingControllers\BookSortController::class, 'showItem']);
7171
Route::get('/books/{slug}', [EntityControllers\BookController::class, 'show']);
7272
Route::get('/books/{bookSlug}/permissions', [PermissionsController::class, 'showForBook']);
7373
Route::put('/books/{bookSlug}/permissions', [PermissionsController::class, 'updateForBook']);
7474
Route::get('/books/{slug}/delete', [EntityControllers\BookController::class, 'showDelete']);
7575
Route::get('/books/{bookSlug}/copy', [EntityControllers\BookController::class, 'showCopy']);
7676
Route::post('/books/{bookSlug}/copy', [EntityControllers\BookController::class, 'copy']);
7777
Route::post('/books/{bookSlug}/convert-to-shelf', [EntityControllers\BookController::class, 'convertToShelf']);
78-
Route::get('/books/{bookSlug}/sort', [BookSortController::class, 'show']);
79-
Route::put('/books/{bookSlug}/sort', [BookSortController::class, 'update']);
78+
Route::get('/books/{bookSlug}/sort', [SortingControllers\BookSortController::class, 'show']);
79+
Route::put('/books/{bookSlug}/sort', [SortingControllers\BookSortController::class, 'update']);
8080
Route::get('/books/{slug}/references', [ReferenceController::class, 'book']);
8181
Route::get('/books/{bookSlug}/export/html', [ExportControllers\BookExportController::class, 'html']);
8282
Route::get('/books/{bookSlug}/export/pdf', [ExportControllers\BookExportController::class, 'pdf']);
@@ -295,6 +295,13 @@
295295
Route::get('/settings/webhooks/{id}/delete', [ActivityControllers\WebhookController::class, 'delete']);
296296
Route::delete('/settings/webhooks/{id}', [ActivityControllers\WebhookController::class, 'destroy']);
297297

298+
// Sort Sets
299+
Route::get('/settings/sorting/sets/new', [SortingControllers\SortSetController::class, 'create']);
300+
Route::post('/settings/sorting/sets', [SortingControllers\SortSetController::class, 'store']);
301+
Route::get('/settings/sorting/sets/{id}', [SortingControllers\SortSetController::class, 'edit']);
302+
Route::put('/settings/sorting/sets/{id}', [SortingControllers\SortSetController::class, 'update']);
303+
Route::delete('/settings/sorting/sets/{id}', [SortingControllers\SortSetController::class, 'destroy']);
304+
298305
// Settings
299306
Route::get('/settings', [SettingControllers\SettingController::class, 'index'])->name('settings');
300307
Route::get('/settings/{category}', [SettingControllers\SettingController::class, 'category'])->name('settings.category');

0 commit comments

Comments
 (0)