]> BookStack Code Mirror - bookstack/commitdiff
Sorting: Renamed sort set to sort rule
authorDan Brown <redacted>
Tue, 11 Feb 2025 14:36:25 +0000 (14:36 +0000)
committerDan Brown <redacted>
Tue, 11 Feb 2025 14:36:25 +0000 (14:36 +0000)
Renamed based on feedback from Tim and Script on Discord.
Also fixed flaky test

30 files changed:
app/Activity/ActivityType.php
app/Console/Commands/AssignSortSetCommand.php
app/Entities/Models/Book.php
app/Entities/Repos/BookRepo.php
app/Sorting/BookSortController.php
app/Sorting/BookSorter.php
app/Sorting/SortRule.php [moved from app/Sorting/SortSet.php with 77% similarity]
app/Sorting/SortRuleController.php [moved from app/Sorting/SortSetController.php with 51% similarity]
app/Sorting/SortRuleOperation.php [moved from app/Sorting/SortSetOperation.php with 74% similarity]
database/factories/Entities/Models/BookFactory.php
database/factories/Sorting/SortRuleFactory.php [moved from database/factories/Sorting/SortSetFactory.php with 70% similarity]
database/migrations/2025_01_29_180933_create_sort_rules_table.php [moved from database/migrations/2025_01_29_180933_create_sort_sets_table.php with 82% similarity]
database/migrations/2025_02_05_150842_add_sort_rule_id_to_books.php [moved from database/migrations/2025_02_05_150842_add_sort_set_id_to_books.php with 79% similarity]
lang/en/entities.php
lang/en/settings.php
resources/js/components/index.ts
resources/js/components/sort-rule-manager.ts [moved from resources/js/components/sort-set-manager.ts with 93% similarity]
resources/views/books/parts/sort-box.blade.php
resources/views/books/sort.blade.php
resources/views/settings/categories/sorting.blade.php
resources/views/settings/sort-rules/create.blade.php [moved from resources/views/settings/sort-sets/create.blade.php with 70% similarity]
resources/views/settings/sort-rules/edit.blade.php [moved from resources/views/settings/sort-sets/edit.blade.php with 83% similarity]
resources/views/settings/sort-rules/parts/form.blade.php [moved from resources/views/settings/sort-sets/parts/form.blade.php with 53% similarity]
resources/views/settings/sort-rules/parts/operation.blade.php [moved from resources/views/settings/sort-sets/parts/operation.blade.php with 100% similarity]
resources/views/settings/sort-rules/parts/sort-rule-list-item.blade.php [moved from resources/views/settings/sort-sets/parts/sort-set-list-item.blade.php with 52% similarity]
routes/web.php
tests/Commands/AssignSortSetCommandTest.php
tests/Entity/PageTest.php
tests/Sorting/BookSortTest.php
tests/Sorting/SortRuleTest.php [moved from tests/Sorting/SortSetTest.php with 58% similarity]

index 4a648da6cfbdb5cb4f173026f5e96cb3f22c7059..a7f129f71d4317055f23062c22f05363beef5168 100644 (file)
@@ -71,9 +71,9 @@ class ActivityType
     const IMPORT_RUN = 'import_run';
     const IMPORT_DELETE = 'import_delete';
 
-    const SORT_SET_CREATE = 'sort_set_create';
-    const SORT_SET_UPDATE = 'sort_set_update';
-    const SORT_SET_DELETE = 'sort_set_delete';
+    const SORT_RULE_CREATE = 'sort_rule_create';
+    const SORT_RULE_UPDATE = 'sort_rule_update';
+    const SORT_RULE_DELETE = 'sort_rule_delete';
 
     /**
      * Get all the possible values.
index 484f69952553b4dd1c3c7156cfd674c7564310b0..6c9d3f7641a65d32e59fedaa2ebc65856ef16ac2 100644 (file)
@@ -4,7 +4,7 @@ namespace BookStack\Console\Commands;
 
 use BookStack\Entities\Models\Book;
 use BookStack\Sorting\BookSorter;
-use BookStack\Sorting\SortSet;
+use BookStack\Sorting\SortRule;
 use Illuminate\Console\Command;
 
 class AssignSortSetCommand extends Command
@@ -37,7 +37,7 @@ class AssignSortSetCommand extends Command
             return $this->listSortSets();
         }
 
-        $set = SortSet::query()->find($sortSetId);
+        $set = SortRule::query()->find($sortSetId);
         if ($this->option('all-books')) {
             $query = Book::query();
         } else if ($this->option('books-without-sort')) {
@@ -87,7 +87,7 @@ class AssignSortSetCommand extends Command
     protected function listSortSets(): int
     {
 
-        $sets = SortSet::query()->orderBy('id', 'asc')->get();
+        $sets = SortRule::query()->orderBy('id', 'asc')->get();
         $this->error("Sort set ID required!");
         $this->warn("\nAvailable sort sets:");
         foreach ($sets as $set) {
index 7d240e5cab9b41f5995611dccdff8a9be4fb7694..ede4fc7d5a670e5a1f5af8e36475b598e837e389 100644 (file)
@@ -2,7 +2,7 @@
 
 namespace BookStack\Entities\Models;
 
-use BookStack\Sorting\SortSet;
+use BookStack\Sorting\SortRule;
 use BookStack\Uploads\Image;
 use Exception;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
@@ -17,14 +17,14 @@ use Illuminate\Support\Collection;
  * @property string                                   $description
  * @property int                                      $image_id
  * @property ?int                                     $default_template_id
- * @property ?int                                     $sort_set_id
+ * @property ?int                                     $sort_rule_id
  * @property Image|null                               $cover
  * @property \Illuminate\Database\Eloquent\Collection $chapters
  * @property \Illuminate\Database\Eloquent\Collection $pages
  * @property \Illuminate\Database\Eloquent\Collection $directPages
  * @property \Illuminate\Database\Eloquent\Collection $shelves
  * @property ?Page                                    $defaultTemplate
- * @property ?SortSet                                 $sortSet
+ * @property ?SortRule                                 $sortRule
  */
 class Book extends Entity implements HasCoverImage
 {
@@ -88,9 +88,9 @@ class Book extends Entity implements HasCoverImage
     /**
      * Get the sort set assigned to this book, if existing.
      */
-    public function sortSet(): BelongsTo
+    public function sortRule(): BelongsTo
     {
-        return $this->belongsTo(SortSet::class);
+        return $this->belongsTo(SortRule::class);
     }
 
     /**
index b3b81164785a5248acc17b1f033356dfe6f1610b..92e6a81c337fcc45dbe7d15c477082454526adf2 100644 (file)
@@ -8,7 +8,7 @@ use BookStack\Entities\Models\Book;
 use BookStack\Entities\Tools\TrashCan;
 use BookStack\Exceptions\ImageUploadException;
 use BookStack\Facades\Activity;
-use BookStack\Sorting\SortSet;
+use BookStack\Sorting\SortRule;
 use BookStack\Uploads\ImageRepo;
 use Exception;
 use Illuminate\Http\UploadedFile;
@@ -35,8 +35,8 @@ class BookRepo
         Activity::add(ActivityType::BOOK_CREATE, $book);
 
         $defaultBookSortSetting = intval(setting('sorting-book-default', '0'));
-        if ($defaultBookSortSetting && SortSet::query()->find($defaultBookSortSetting)) {
-            $book->sort_set_id = $defaultBookSortSetting;
+        if ($defaultBookSortSetting && SortRule::query()->find($defaultBookSortSetting)) {
+            $book->sort_rule_id = $defaultBookSortSetting;
             $book->save();
         }
 
index 98d79d0fd1299d23349bb80c8f86cde3a3534e26..479d1972440dceca53e3c7291fa696d54c92b65b 100644 (file)
@@ -69,10 +69,10 @@ class BookSortController extends Controller
 
         if ($request->filled('auto-sort')) {
             $sortSetId = intval($request->get('auto-sort')) ?: null;
-            if ($sortSetId && SortSet::query()->find($sortSetId) === null) {
+            if ($sortSetId && SortRule::query()->find($sortSetId) === null) {
                 $sortSetId = null;
             }
-            $book->sort_set_id = $sortSetId;
+            $book->sort_rule_id = $sortSetId;
             $book->save();
             $sorter->runBookAutoSort($book);
             if (!$loggedActivityForBook) {
index b6fe33b9c3e905c1221ec4616a7ae6e3a147ebdd..7bf1b63f46cfa8d54b3b93b137523626f5fb597c 100644 (file)
@@ -16,7 +16,7 @@ class BookSorter
     ) {
     }
 
-    public function runBookAutoSortForAllWithSet(SortSet $set): void
+    public function runBookAutoSortForAllWithSet(SortRule $set): void
     {
         $set->books()->chunk(50, function ($books) {
             foreach ($books as $book) {
@@ -32,12 +32,12 @@ class BookSorter
      */
     public function runBookAutoSort(Book $book): void
     {
-        $set = $book->sortSet;
+        $set = $book->sortRule;
         if (!$set) {
             return;
         }
 
-        $sortFunctions = array_map(function (SortSetOperation $op) {
+        $sortFunctions = array_map(function (SortRuleOperation $op) {
             return $op->getSortFunction();
         }, $set->getOperations());
 
similarity index 77%
rename from app/Sorting/SortSet.php
rename to app/Sorting/SortRule.php
index cc8879f965782f58742c7131938dfaa45b4c476c..45e5514fd5f03dd03d5a71f4e3aba82a10796a73 100644 (file)
@@ -17,24 +17,24 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
  * @property Carbon $created_at
  * @property Carbon $updated_at
  */
-class SortSet extends Model implements Loggable
+class SortRule extends Model implements Loggable
 {
     use HasFactory;
 
     /**
-     * @return SortSetOperation[]
+     * @return SortRuleOperation[]
      */
     public function getOperations(): array
     {
-        return SortSetOperation::fromSequence($this->sequence);
+        return SortRuleOperation::fromSequence($this->sequence);
     }
 
     /**
-     * @param SortSetOperation[] $options
+     * @param SortRuleOperation[] $options
      */
     public function setOperations(array $options): void
     {
-        $values = array_map(fn (SortSetOperation $opt) => $opt->value, $options);
+        $values = array_map(fn (SortRuleOperation $opt) => $opt->value, $options);
         $this->sequence = implode(',', $values);
     }
 
@@ -45,7 +45,7 @@ class SortSet extends Model implements Loggable
 
     public function getUrl(): string
     {
-        return url("/settings/sorting/sets/{$this->id}");
+        return url("/settings/sorting/rules/{$this->id}");
     }
 
     public function books(): HasMany
similarity index 51%
rename from app/Sorting/SortSetController.php
rename to app/Sorting/SortRuleController.php
index 7b1c0bc4160fd10b131334715ad4be2d852c1325..96b8e8ef53e53827a13059ead622897cceba1d50 100644 (file)
@@ -6,7 +6,7 @@ use BookStack\Activity\ActivityType;
 use BookStack\Http\Controller;
 use Illuminate\Http\Request;
 
-class SortSetController extends Controller
+class SortRuleController extends Controller
 {
     public function __construct()
     {
@@ -15,9 +15,9 @@ class SortSetController extends Controller
 
     public function create()
     {
-        $this->setPageTitle(trans('settings.sort_set_create'));
+        $this->setPageTitle(trans('settings.sort_rule_create'));
 
-        return view('settings.sort-sets.create');
+        return view('settings.sort-rules.create');
     }
 
     public function store(Request $request)
@@ -27,28 +27,28 @@ class SortSetController extends Controller
             'sequence' => ['required', 'string', 'min:1'],
         ]);
 
-        $operations = SortSetOperation::fromSequence($request->input('sequence'));
+        $operations = SortRuleOperation::fromSequence($request->input('sequence'));
         if (count($operations) === 0) {
             return redirect()->withInput()->withErrors(['sequence' => 'No operations set.']);
         }
 
-        $set = new SortSet();
-        $set->name = $request->input('name');
-        $set->setOperations($operations);
-        $set->save();
+        $rule = new SortRule();
+        $rule->name = $request->input('name');
+        $rule->setOperations($operations);
+        $rule->save();
 
-        $this->logActivity(ActivityType::SORT_SET_CREATE, $set);
+        $this->logActivity(ActivityType::SORT_RULE_CREATE, $rule);
 
         return redirect('/settings/sorting');
     }
 
     public function edit(string $id)
     {
-        $set = SortSet::query()->findOrFail($id);
+        $rule = SortRule::query()->findOrFail($id);
 
-        $this->setPageTitle(trans('settings.sort_set_edit'));
+        $this->setPageTitle(trans('settings.sort_rule_edit'));
 
-        return view('settings.sort-sets.edit', ['set' => $set]);
+        return view('settings.sort-rules.edit', ['rule' => $rule]);
     }
 
     public function update(string $id, Request $request, BookSorter $bookSorter)
@@ -58,21 +58,21 @@ class SortSetController extends Controller
             'sequence' => ['required', 'string', 'min:1'],
         ]);
 
-        $set = SortSet::query()->findOrFail($id);
-        $operations = SortSetOperation::fromSequence($request->input('sequence'));
+        $rule = SortRule::query()->findOrFail($id);
+        $operations = SortRuleOperation::fromSequence($request->input('sequence'));
         if (count($operations) === 0) {
-            return redirect($set->getUrl())->withInput()->withErrors(['sequence' => 'No operations set.']);
+            return redirect($rule->getUrl())->withInput()->withErrors(['sequence' => 'No operations set.']);
         }
 
-        $set->name = $request->input('name');
-        $set->setOperations($operations);
-        $changedSequence = $set->isDirty('sequence');
-        $set->save();
+        $rule->name = $request->input('name');
+        $rule->setOperations($operations);
+        $changedSequence = $rule->isDirty('sequence');
+        $rule->save();
 
-        $this->logActivity(ActivityType::SORT_SET_UPDATE, $set);
+        $this->logActivity(ActivityType::SORT_RULE_UPDATE, $rule);
 
         if ($changedSequence) {
-            $bookSorter->runBookAutoSortForAllWithSet($set);
+            $bookSorter->runBookAutoSortForAllWithSet($rule);
         }
 
         return redirect('/settings/sorting');
@@ -80,16 +80,16 @@ class SortSetController extends Controller
 
     public function destroy(string $id, Request $request)
     {
-        $set = SortSet::query()->findOrFail($id);
+        $rule = SortRule::query()->findOrFail($id);
         $confirmed = $request->input('confirm') === 'true';
-        $booksAssigned = $set->books()->count();
+        $booksAssigned = $rule->books()->count();
         $warnings = [];
 
         if ($booksAssigned > 0) {
             if ($confirmed) {
-                $set->books()->update(['sort_set_id' => null]);
+                $rule->books()->update(['sort_rule_id' => null]);
             } else {
-                $warnings[] = trans('settings.sort_set_delete_warn_books', ['count' => $booksAssigned]);
+                $warnings[] = trans('settings.sort_rule_delete_warn_books', ['count' => $booksAssigned]);
             }
         }
 
@@ -98,16 +98,16 @@ class SortSetController extends Controller
             if ($confirmed) {
                 setting()->remove('sorting-book-default');
             } else {
-                $warnings[] = trans('settings.sort_set_delete_warn_default');
+                $warnings[] = trans('settings.sort_rule_delete_warn_default');
             }
         }
 
         if (count($warnings) > 0) {
-            return redirect($set->getUrl() . '#delete')->withErrors(['delete' => $warnings]);
+            return redirect($rule->getUrl() . '#delete')->withErrors(['delete' => $warnings]);
         }
 
-        $set->delete();
-        $this->logActivity(ActivityType::SORT_SET_DELETE, $set);
+        $rule->delete();
+        $this->logActivity(ActivityType::SORT_RULE_DELETE, $rule);
 
         return redirect('/settings/sorting');
     }
similarity index 74%
rename from app/Sorting/SortSetOperation.php
rename to app/Sorting/SortRuleOperation.php
index 7fdd0b002bff2d610f5bd27decb9c8c1d79fd5c8..0d8ff239f8da37240321a29c7b49031460b71c9d 100644 (file)
@@ -5,7 +5,7 @@ namespace BookStack\Sorting;
 use Closure;
 use Illuminate\Support\Str;
 
-enum SortSetOperation: string
+enum SortRuleOperation: string
 {
     case NameAsc = 'name_asc';
     case NameDesc = 'name_desc';
@@ -26,13 +26,13 @@ enum SortSetOperation: string
         $label = '';
         if (str_ends_with($key, '_asc')) {
             $key = substr($key, 0, -4);
-            $label = trans('settings.sort_set_op_asc');
+            $label = trans('settings.sort_rule_op_asc');
         } elseif (str_ends_with($key, '_desc')) {
             $key = substr($key, 0, -5);
-            $label = trans('settings.sort_set_op_desc');
+            $label = trans('settings.sort_rule_op_desc');
         }
 
-        $label = trans('settings.sort_set_op_' . $key) . ' ' . $label;
+        $label = trans('settings.sort_rule_op_' . $key) . ' ' . $label;
         return trim($label);
     }
 
@@ -43,12 +43,12 @@ enum SortSetOperation: string
     }
 
     /**
-     * @return SortSetOperation[]
+     * @return SortRuleOperation[]
      */
     public static function allExcluding(array $operations): array
     {
-        $all = SortSetOperation::cases();
-        $filtered = array_filter($all, function (SortSetOperation $operation) use ($operations) {
+        $all = SortRuleOperation::cases();
+        $filtered = array_filter($all, function (SortRuleOperation $operation) use ($operations) {
             return !in_array($operation, $operations);
         });
         return array_values($filtered);
@@ -57,12 +57,12 @@ enum SortSetOperation: string
     /**
      * Create a set of operations from a string sequence representation.
      * (values seperated by commas).
-     * @return SortSetOperation[]
+     * @return SortRuleOperation[]
      */
     public static function fromSequence(string $sequence): array
     {
         $strOptions = explode(',', $sequence);
-        $options = array_map(fn ($val) => SortSetOperation::tryFrom($val), $strOptions);
+        $options = array_map(fn ($val) => SortRuleOperation::tryFrom($val), $strOptions);
         return array_filter($options);
     }
 }
index 29403a2949c5d4b0bcdb6e3c4944e1324f6e04de..48d43d7a8b7921124a47be8ee42b63c09d2069f8 100644 (file)
@@ -27,7 +27,7 @@ class BookFactory extends Factory
             'slug'        => Str::random(10),
             'description' => $description,
             'description_html' => '<p>' . e($description) . '</p>',
-            'sort_set_id' => null,
+            'sort_rule_id' => null,
             'default_template_id' => null,
         ];
     }
similarity index 70%
rename from database/factories/Sorting/SortSetFactory.php
rename to database/factories/Sorting/SortRuleFactory.php
index 36e0a697677452867ef57990808110f239092eae..dafe8c3fa742e4f19101c262fff95a24246454f8 100644 (file)
@@ -2,25 +2,25 @@
 
 namespace Database\Factories\Sorting;
 
-use BookStack\Sorting\SortSet;
-use BookStack\Sorting\SortSetOperation;
+use BookStack\Sorting\SortRule;
+use BookStack\Sorting\SortRuleOperation;
 use Illuminate\Database\Eloquent\Factories\Factory;
 
-class SortSetFactory extends Factory
+class SortRuleFactory extends Factory
 {
     /**
      * The name of the factory's corresponding model.
      *
      * @var string
      */
-    protected $model = SortSet::class;
+    protected $model = SortRule::class;
 
     /**
      * Define the model's default state.
      */
     public function definition(): array
     {
-        $cases = SortSetOperation::cases();
+        $cases = SortRuleOperation::cases();
         $op = $cases[array_rand($cases)];
         return [
             'name' => $op->name . ' Sort',
similarity index 82%
rename from database/migrations/2025_01_29_180933_create_sort_sets_table.php
rename to database/migrations/2025_01_29_180933_create_sort_rules_table.php
index bf9780c5b7eff9bf5a03aab2d57a7a0ae93bb39b..37d20ddf618129c366462553a0fb25989b9e122e 100644 (file)
@@ -11,7 +11,7 @@ return new class extends Migration
      */
     public function up(): void
     {
-        Schema::create('sort_sets', function (Blueprint $table) {
+        Schema::create('sort_rules', function (Blueprint $table) {
             $table->increments('id');
             $table->string('name');
             $table->text('sequence');
@@ -24,6 +24,6 @@ return new class extends Migration
      */
     public function down(): void
     {
-        Schema::dropIfExists('sort_sets');
+        Schema::dropIfExists('sort_rules');
     }
 };
similarity index 79%
rename from database/migrations/2025_02_05_150842_add_sort_set_id_to_books.php
rename to database/migrations/2025_02_05_150842_add_sort_rule_id_to_books.php
index c0b32c552883f66141c220f036b03634b2a0e711..106db05caa0676cc74b07dcb40e0b4e728e41c64 100644 (file)
@@ -12,7 +12,7 @@ return new class extends Migration
     public function up(): void
     {
         Schema::table('books', function (Blueprint $table) {
-            $table->unsignedInteger('sort_set_id')->nullable()->default(null);
+            $table->unsignedInteger('sort_rule_id')->nullable()->default(null);
         });
     }
 
@@ -22,7 +22,7 @@ return new class extends Migration
     public function down(): void
     {
         Schema::table('books', function (Blueprint $table) {
-            $table->dropColumn('sort_set_id');
+            $table->dropColumn('sort_rule_id');
         });
     }
 };
index 28a209fa21a2b41f5c30909a5df732bcdf383747..a74785eaacde3ca5316d7153e1e6b139dc603829 100644 (file)
@@ -166,7 +166,7 @@ return [
     'books_search_this' => 'Search this book',
     'books_navigation' => 'Book Navigation',
     'books_sort' => 'Sort Book Contents',
-    '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.',
+    '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 rule can be set to automatically sort this book\'s contents upon changes.',
     'books_sort_auto_sort' => 'Auto Sort Option',
     'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
     'books_sort_named' => 'Sort Book :bookName',
index 344c186cb2f08c01ac59f827ffe6583902064faf..098479f3be0eddb36598123d69078f8ee6682b67 100644 (file)
@@ -77,32 +77,32 @@ return [
     // Sorting Settings
     'sorting' => 'Sorting',
     'sorting_book_default' => 'Default Book Sort',
-    '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.',
-    'sorting_sets' => 'Sort Sets',
-    'sorting_sets_desc' => 'These are predefined sorting operations which can be applied to content in the system.',
-    'sort_set_assigned_to_x_books' => 'Assigned to :count Book|Assigned to :count Books',
-    'sort_set_create' => 'Create Sort Set',
-    'sort_set_edit' => 'Edit Sort Set',
-    'sort_set_delete' => 'Delete Sort Set',
-    'sort_set_delete_desc' => 'Remove this sort set from the system. Books using this sort will revert to manual sorting.',
-    'sort_set_delete_warn_books' => 'This sort set is currently used on :count book(s). Are you sure you want to delete this?',
-    'sort_set_delete_warn_default' => 'This sort set is currently used as the default for books. Are you sure you want to delete this?',
-    'sort_set_details' => 'Sort Set Details',
-    'sort_set_details_desc' => 'Set a name for this sort set, which will appear in lists when users are selecting a sort.',
-    'sort_set_operations' => 'Sort Operations',
-    '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.',
-    'sort_set_available_operations' => 'Available Operations',
-    'sort_set_available_operations_empty' => 'No operations remaining',
-    'sort_set_configured_operations' => 'Configured Operations',
-    'sort_set_configured_operations_empty' => 'Drag/add operations from the "Available Operations" list',
-    'sort_set_op_asc' => '(Asc)',
-    'sort_set_op_desc' => '(Desc)',
-    'sort_set_op_name' => 'Name - Alphabetical',
-    'sort_set_op_name_numeric' => 'Name - Numeric',
-    'sort_set_op_created_date' => 'Created Date',
-    'sort_set_op_updated_date' => 'Updated Date',
-    'sort_set_op_chapters_first' => 'Chapters First',
-    'sort_set_op_chapters_last' => 'Chapters Last',
+    'sorting_book_default_desc' => 'Select the default sort role to apply to new books. This won\'t affect existing books, and can be overridden per-book.',
+    'sorting_rules' => 'Sort Rules',
+    'sorting_rules_desc' => 'These are predefined sorting operations which can be applied to content in the system.',
+    'sort_rule_assigned_to_x_books' => 'Assigned to :count Book|Assigned to :count Books',
+    'sort_rule_create' => 'Create Sort Rule',
+    'sort_rule_edit' => 'Edit Sort Rule',
+    'sort_rule_delete' => 'Delete Sort Rule',
+    'sort_rule_delete_desc' => 'Remove this sort rule from the system. Books using this sort will revert to manual sorting.',
+    'sort_rule_delete_warn_books' => 'This sort rule is currently used on :count book(s). Are you sure you want to delete this?',
+    'sort_rule_delete_warn_default' => 'This sort rule is currently used as the default for books. Are you sure you want to delete this?',
+    'sort_rule_details' => 'Sort Rule Details',
+    'sort_rule_details_desc' => 'Set a name for this sort rule, which will appear in lists when users are selecting a sort.',
+    'sort_rule_operations' => 'Sort Operations',
+    'sort_rule_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.',
+    'sort_rule_available_operations' => 'Available Operations',
+    'sort_rule_available_operations_empty' => 'No operations remaining',
+    'sort_rule_configured_operations' => 'Configured Operations',
+    'sort_rule_configured_operations_empty' => 'Drag/add operations from the "Available Operations" list',
+    'sort_rule_op_asc' => '(Asc)',
+    'sort_rule_op_desc' => '(Desc)',
+    'sort_rule_op_name' => 'Name - Alphabetical',
+    'sort_rule_op_name_numeric' => 'Name - Numeric',
+    'sort_rule_op_created_date' => 'Created Date',
+    'sort_rule_op_updated_date' => 'Updated Date',
+    'sort_rule_op_chapters_first' => 'Chapters First',
+    'sort_rule_op_chapters_last' => 'Chapters Last',
 
     // Maintenance settings
     'maint' => 'Maintenance',
index affa25fcf31ddb96fc29f32e4d62453bc66ca1af..10b8025db630137f4c4512edba8126e5780d8ec8 100644 (file)
@@ -50,7 +50,7 @@ export {ShelfSort} from './shelf-sort';
 export {Shortcuts} from './shortcuts';
 export {ShortcutInput} from './shortcut-input';
 export {SortableList} from './sortable-list';
-export {SortSetManager} from './sort-set-manager'
+export {SortRuleManager} from './sort-rule-manager'
 export {SubmitOnChange} from './submit-on-change';
 export {Tabs} from './tabs';
 export {TagManager} from './tag-manager';
similarity index 93%
rename from resources/js/components/sort-set-manager.ts
rename to resources/js/components/sort-rule-manager.ts
index c35ad41fe07ac1665b258351ef2b84c47a340708..ff08f4ab878ac88e2df6a912e01508f880585ac4 100644 (file)
@@ -3,7 +3,7 @@ import Sortable from "sortablejs";
 import {buildListActions, sortActionClickListener} from "../services/dual-lists";
 
 
-export class SortSetManager extends Component {
+export class SortRuleManager extends Component {
 
     protected input!: HTMLInputElement;
     protected configuredList!: HTMLElement;
@@ -25,7 +25,7 @@ export class SortSetManager extends Component {
         const scrollBoxes = [this.configuredList, this.availableList];
         for (const scrollBox of scrollBoxes) {
             new Sortable(scrollBox, {
-                group: 'sort-set-operations',
+                group: 'sort-rule-operations',
                 ghostClass: 'primary-background-light',
                 handle: '.handle',
                 animation: 150,
index 232616168f92e9af637b57161c93770bf022e972..6fdb1819e617742c96b47b7a6a7af9951e41e727 100644 (file)
@@ -9,18 +9,23 @@
                 <span>{{ $book->name }}</span>
             </div>
             <div class="flex-container-row items-center text-book">
-                @if($book->sortSet)
-                    <span title="{{ trans('entities.books_sort_auto_sort_active', ['sortName' => $book->sortSet->name]) }}">@icon('auto-sort')</span>
+                @if($book->sortRule)
+                    <span title="{{ trans('entities.books_sort_auto_sort_active', ['sortName' => $book->sortRule->name]) }}">@icon('auto-sort')</span>
                 @endif
             </div>
         </h5>
     </summary>
     <div class="sort-box-options pb-sm">
-        <button type="button" data-sort="name" class="button outline small">{{ trans('entities.books_sort_name') }}</button>
-        <button type="button" data-sort="created" class="button outline small">{{ trans('entities.books_sort_created') }}</button>
-        <button type="button" data-sort="updated" class="button outline small">{{ trans('entities.books_sort_updated') }}</button>
-        <button type="button" data-sort="chaptersFirst" class="button outline small">{{ trans('entities.books_sort_chapters_first') }}</button>
-        <button type="button" data-sort="chaptersLast" class="button outline small">{{ trans('entities.books_sort_chapters_last') }}</button>
+        <button type="button" data-sort="name"
+                class="button outline small">{{ trans('entities.books_sort_name') }}</button>
+        <button type="button" data-sort="created"
+                class="button outline small">{{ trans('entities.books_sort_created') }}</button>
+        <button type="button" data-sort="updated"
+                class="button outline small">{{ trans('entities.books_sort_updated') }}</button>
+        <button type="button" data-sort="chaptersFirst"
+                class="button outline small">{{ trans('entities.books_sort_chapters_first') }}</button>
+        <button type="button" data-sort="chaptersLast"
+                class="button outline small">{{ trans('entities.books_sort_chapters_last') }}</button>
     </div>
     <ul class="sortable-page-list sort-list">
 
index 3c59ac1e0928e1a2acde9e3c6afdae958d3ad119..e090708b1d71eb1597942cd363d9c3e6089fd4f6 100644 (file)
                         <p class="text-muted flex min-width-s mb-none">{{ trans('entities.books_sort_desc') }}</p>
                         <div class="min-width-s">
                             @php
-                                $autoSortVal = intval(old('auto-sort') ?? $book->sort_set_id ?? 0);
+                                $autoSortVal = intval(old('auto-sort') ?? $book->sort_rule_id ?? 0);
                             @endphp
                             <label for="auto-sort">{{ trans('entities.books_sort_auto_sort') }}</label>
                             <select id="auto-sort"
                                     name="auto-sort"
                                     form="sort-form"
                                     class="{{ $errors->has('auto-sort') ? 'neg' : '' }}">
-                                <option value="0" @if($autoSortVal === 0) selected @endif>-- {{ trans('common.none') }} --</option>
-                                @foreach(\BookStack\Sorting\SortSet::allByName() as $set)
-                                    <option value="{{$set->id}}"
-                                            @if($autoSortVal === $set->id) selected @endif
+                                <option value="0" @if($autoSortVal === 0) selected @endif>-- {{ trans('common.none') }}
+                                    --
+                                </option>
+                                @foreach(\BookStack\Sorting\SortRule::allByName() as $rule)
+                                    <option value="{{$rule->id}}"
+                                            @if($autoSortVal === $rule->id) selected @endif
                                     >
-                                        {{ $set->name }}
+                                        {{ $rule->name }}
                                     </option>
                                 @endforeach
                             </select>
index 6a52873e6abd9c6f2912bc585123137e89a9b8b7..9d1d9814b96bf0df67129efc6274b488c3f8794e 100644 (file)
@@ -1,7 +1,7 @@
 @extends('settings.layout')
 
 @php
-    $sortSets = \BookStack\Sorting\SortSet::allByName();
+    $sortRules = \BookStack\Sorting\SortRule::allByName();
 @endphp
 
 @section('card')
@@ -23,7 +23,7 @@
                         <option value="0" @if(intval(setting('sorting-book-default', '0')) === 0) selected @endif>
                             -- {{ trans('common.none') }} --
                         </option>
-                        @foreach($sortSets as $set)
+                        @foreach($sortRules as $set)
                             <option value="{{$set->id}}"
                                     @if(intval(setting('sorting-book-default', '0')) === $set->id) selected @endif
                             >
     <div class="card content-wrap auto-height">
         <div class="flex-container-row items-center gap-m">
             <div class="flex">
-                <h2 class="list-heading">{{ trans('settings.sorting_sets') }}</h2>
-                <p class="text-muted">{{ trans('settings.sorting_sets_desc') }}</p>
+                <h2 class="list-heading">{{ trans('settings.sorting_rules') }}</h2>
+                <p class="text-muted">{{ trans('settings.sorting_rules_desc') }}</p>
             </div>
             <div>
-                <a href="{{ url('/settings/sorting/sets/new') }}" class="button outline">{{ trans('settings.sort_set_create') }}</a>
+                <a href="{{ url('/settings/sorting/rules/new') }}"
+                   class="button outline">{{ trans('settings.sort_rule_create') }}</a>
             </div>
         </div>
 
-        @if(empty($sortSets))
+        @if(empty($sortRules))
             <p class="italic text-muted">{{ trans('common.no_items') }}</p>
         @else
             <div class="item-list">
-                @foreach($sortSets as $set)
-                    @include('settings.sort-sets.parts.sort-set-list-item', ['set' => $set])
+                @foreach($sortRules as $rule)
+                    @include('settings.sort-rules.parts.sort-rule-list-item', ['rule' => $rule])
                 @endforeach
             </div>
         @endif
similarity index 70%
rename from resources/views/settings/sort-sets/create.blade.php
rename to resources/views/settings/sort-rules/create.blade.php
index 16f2d2ac72cff6ff8c714285574cca89d4a18a09..e1d5c7c46304574d6a59024ee239211d73b2ca7a 100644 (file)
@@ -7,11 +7,11 @@
         @include('settings.parts.navbar', ['selected' => 'settings'])
 
         <div class="card content-wrap auto-height">
-            <h1 class="list-heading">{{ trans('settings.sort_set_create') }}</h1>
+            <h1 class="list-heading">{{ trans('settings.sort_rule_create') }}</h1>
 
-            <form action="{{ url("/settings/sorting/sets") }}" method="POST">
+            <form action="{{ url("/settings/sorting/rules") }}" method="POST">
                 {{ csrf_field() }}
-                @include('settings.sort-sets.parts.form', ['model' => null])
+                @include('settings.sort-rules.parts.form', ['model' => null])
 
                 <div class="form-group text-right">
                     <a href="{{ url("/settings/sorting") }}" class="button outline">{{ trans('common.cancel') }}</a>
similarity index 83%
rename from resources/views/settings/sort-sets/edit.blade.php
rename to resources/views/settings/sort-rules/edit.blade.php
index febcd9ffe1f888695ec12a325d78462dd9fa4feb..8bf04701fe0a7ccd627d8ca57763255307e4edf1 100644 (file)
@@ -7,13 +7,13 @@
         @include('settings.parts.navbar', ['selected' => 'settings'])
 
         <div class="card content-wrap auto-height">
-            <h1 class="list-heading">{{ trans('settings.sort_set_edit') }}</h1>
+            <h1 class="list-heading">{{ trans('settings.sort_rule_edit') }}</h1>
 
-            <form action="{{ $set->getUrl() }}" method="POST">
+            <form action="{{ $rule->getUrl() }}" method="POST">
                 {{ method_field('PUT') }}
                 {{ csrf_field() }}
 
-                @include('settings.sort-sets.parts.form', ['model' => $set])
+                @include('settings.sort-rules.parts.form', ['model' => $rule])
 
                 <div class="form-group text-right">
                     <a href="{{ url("/settings/sorting") }}" class="button outline">{{ trans('common.cancel') }}</a>
@@ -25,8 +25,8 @@
         <div id="delete" class="card content-wrap auto-height">
             <div class="flex-container-row items-center gap-l">
                 <div class="mb-m">
-                    <h2 class="list-heading">{{ trans('settings.sort_set_delete') }}</h2>
-                    <p class="text-muted mb-xs">{{ trans('settings.sort_set_delete_desc') }}</p>
+                    <h2 class="list-heading">{{ trans('settings.sort_rule_delete') }}</h2>
+                    <p class="text-muted mb-xs">{{ trans('settings.sort_rule_delete_desc') }}</p>
                     @if($errors->has('delete'))
                         @foreach($errors->get('delete') as $error)
                             <p class="text-neg mb-xs">{{ $error }}</p>
@@ -34,7 +34,7 @@
                     @endif
                 </div>
                 <div class="flex">
-                    <form action="{{ $set->getUrl() }}" method="POST">
+                    <form action="{{ $rule->getUrl() }}" method="POST">
                         {{ method_field('DELETE') }}
                         {{ csrf_field() }}
 
similarity index 53%
rename from resources/views/settings/sort-sets/parts/form.blade.php
rename to resources/views/settings/sort-rules/parts/form.blade.php
index 38db840ac57646c5783c4581bea12e96ad7834ef..d6de947b6c70bc1af88f91b003a703e7d27ab5ff 100644 (file)
@@ -1,8 +1,8 @@
 <div class="setting-list">
     <div class="grid half">
         <div>
-            <label class="setting-list-label">{{ trans('settings.sort_set_details') }}</label>
-            <p class="text-muted text-small">{{ trans('settings.sort_set_details_desc') }}</p>
+            <label class="setting-list-label">{{ trans('settings.sort_rule_details') }}</label>
+            <p class="text-muted text-small">{{ trans('settings.sort_rule_details_desc') }}</p>
         </div>
         <div>
             <div class="form-group">
         </div>
     </div>
 
-    <div component="sort-set-manager">
-        <label class="setting-list-label">{{ trans('settings.sort_set_operations') }}</label>
-        <p class="text-muted text-small">{{ trans('settings.sort_set_operations_desc') }}</p>
+    <div component="sort-rule-manager">
+        <label class="setting-list-label">{{ trans('settings.sort_rule_operations') }}</label>
+        <p class="text-muted text-small">{{ trans('settings.sort_rule_operations_desc') }}</p>
         @include('form.errors', ['name' => 'sequence'])
 
-        <input refs="sort-set-manager@input" type="hidden" name="sequence"
+        <input refs="sort-rule-manager@input" type="hidden" name="sequence"
                value="{{ old('sequence') ?? $model?->sequence ?? '' }}">
 
         @php
-            $configuredOps = old('sequence') ? \BookStack\Sorting\SortSetOperation::fromSequence(old('sequence')) : ($model?->getOperations() ?? []);
+            $configuredOps = old('sequence') ? \BookStack\Sorting\SortRuleOperation::fromSequence(old('sequence')) : ($model?->getOperations() ?? []);
         @endphp
 
         <div class="grid half">
             <div class="form-group">
                 <label for="books"
-                       id="sort-set-configured-operations">{{ trans('settings.sort_set_configured_operations') }}</label>
-                <ul refs="sort-set-manager@configured-operations-list"
-                    aria-labelledby="sort-set-configured-operations"
+                       id="sort-rule-configured-operations">{{ trans('settings.sort_rule_configured_operations') }}</label>
+                <ul refs="sort-rule-manager@configured-operations-list"
+                    aria-labelledby="sort-rule-configured-operations"
                     class="scroll-box configured-option-list">
-                    <li class="text-muted empty-state px-m py-s italic text-small">{{ trans('settings.sort_set_configured_operations_empty') }}</li>
+                    <li class="text-muted empty-state px-m py-s italic text-small">{{ trans('settings.sort_rule_configured_operations_empty') }}</li>
 
                     @foreach($configuredOps as $operation)
-                        @include('settings.sort-sets.parts.operation', ['operation' => $operation])
+                        @include('settings.sort-rules.parts.operation', ['operation' => $operation])
                     @endforeach
                 </ul>
             </div>
 
             <div class="form-group">
                 <label for="books"
-                       id="sort-set-available-operations">{{ trans('settings.sort_set_available_operations') }}</label>
-                <ul refs="sort-set-manager@available-operations-list"
-                    aria-labelledby="sort-set-available-operations"
+                       id="sort-rule-available-operations">{{ trans('settings.sort_rule_available_operations') }}</label>
+                <ul refs="sort-rule-manager@available-operations-list"
+                    aria-labelledby="sort-rule-available-operations"
                     class="scroll-box available-option-list">
-                    <li class="text-muted empty-state px-m py-s italic text-small">{{ trans('settings.sort_set_available_operations_empty') }}</li>
-                    @foreach(\BookStack\Sorting\SortSetOperation::allExcluding($configuredOps) as $operation)
-                        @include('settings.sort-sets.parts.operation', ['operation' => $operation])
+                    <li class="text-muted empty-state px-m py-s italic text-small">{{ trans('settings.sort_rule_available_operations_empty') }}</li>
+                    @foreach(\BookStack\Sorting\SortRuleOperation::allExcluding($configuredOps) as $operation)
+                        @include('settings.sort-rules.parts.operation', ['operation' => $operation])
                     @endforeach
                 </ul>
             </div>
similarity index 52%
rename from resources/views/settings/sort-sets/parts/sort-set-list-item.blade.php
rename to resources/views/settings/sort-rules/parts/sort-rule-list-item.blade.php
index 6c0b84047c09233e4b16907190da178f514e4a84..5236cb412a3897142b3b2c67adb3e24484694356 100644 (file)
@@ -1,12 +1,12 @@
 <div class="item-list-row flex-container-row py-xs px-m gap-m items-center">
     <div class="py-xs flex">
-        <a href="{{ $set->getUrl() }}">{{ $set->name }}</a>
+        <a href="{{ $rule->getUrl() }}">{{ $rule->name }}</a>
     </div>
     <div class="px-m text-small text-muted ml-auto">
-        {{ implode(', ', array_map(fn ($op) => $op->getLabel(), $set->getOperations())) }}
+        {{ implode(', ', array_map(fn ($op) => $op->getLabel(), $rule->getOperations())) }}
     </div>
     <div>
-        <span title="{{ trans_choice('settings.sort_set_assigned_to_x_books', $set->books_count ?? 0) }}"
-              class="flex fill-area min-width-xxs bold text-right text-book"><span class="opacity-60">@icon('book')</span>{{ $set->books_count ?? 0 }}</span>
+        <span title="{{ trans_choice('settings.sort_rule_assigned_to_x_books', $rule->books_count ?? 0) }}"
+              class="flex fill-area min-width-xxs bold text-right text-book"><span class="opacity-60">@icon('book')</span>{{ $rule->books_count ?? 0 }}</span>
     </div>
 </div>
\ No newline at end of file
index 62c120f202027f4db3c2b8b4e5d23ba1452c7f73..8184725834caae44f3dae98942d2bc981ec84406 100644 (file)
@@ -295,12 +295,12 @@ Route::middleware('auth')->group(function () {
     Route::get('/settings/webhooks/{id}/delete', [ActivityControllers\WebhookController::class, 'delete']);
     Route::delete('/settings/webhooks/{id}', [ActivityControllers\WebhookController::class, 'destroy']);
 
-    // Sort Sets
-    Route::get('/settings/sorting/sets/new', [SortingControllers\SortSetController::class, 'create']);
-    Route::post('/settings/sorting/sets', [SortingControllers\SortSetController::class, 'store']);
-    Route::get('/settings/sorting/sets/{id}', [SortingControllers\SortSetController::class, 'edit']);
-    Route::put('/settings/sorting/sets/{id}', [SortingControllers\SortSetController::class, 'update']);
-    Route::delete('/settings/sorting/sets/{id}', [SortingControllers\SortSetController::class, 'destroy']);
+    // Sort Rules
+    Route::get('/settings/sorting/rules/new', [SortingControllers\SortRuleController::class, 'create']);
+    Route::post('/settings/sorting/rules', [SortingControllers\SortRuleController::class, 'store']);
+    Route::get('/settings/sorting/rules/{id}', [SortingControllers\SortRuleController::class, 'edit']);
+    Route::put('/settings/sorting/rules/{id}', [SortingControllers\SortRuleController::class, 'update']);
+    Route::delete('/settings/sorting/rules/{id}', [SortingControllers\SortRuleController::class, 'destroy']);
 
     // Settings
     Route::get('/settings', [SettingControllers\SettingController::class, 'index'])->name('settings');
index 01cb5caa5e886797ed7db3d2206b9b445d1a48f9..659840a9bcc2a9486251316f4a5cebf6943c865d 100644 (file)
@@ -3,14 +3,14 @@
 namespace Commands;
 
 use BookStack\Entities\Models\Book;
-use BookStack\Sorting\SortSet;
+use BookStack\Sorting\SortRule;
 use Tests\TestCase;
 
 class AssignSortSetCommandTest extends TestCase
 {
     public function test_no_given_sort_set_lists_options()
     {
-        $sortSets = SortSet::factory()->createMany(10);
+        $sortSets = SortRule::factory()->createMany(10);
 
         $commandRun = $this->artisan('bookstack:assign-sort-set')
             ->expectsOutputToContain('Sort set ID required!')
@@ -37,7 +37,7 @@ class AssignSortSetCommandTest extends TestCase
 
     public function test_confirmation_required()
     {
-        $sortSet = SortSet::factory()->create();
+        $sortSet = SortRule::factory()->create();
 
         $this->artisan("bookstack:assign-sort-set {$sortSet->id} --all-books")
             ->expectsConfirmation('Are you sure you want to continue?', 'no')
@@ -49,7 +49,7 @@ class AssignSortSetCommandTest extends TestCase
 
     public function test_assign_to_all_books()
     {
-        $sortSet = SortSet::factory()->create();
+        $sortSet = SortRule::factory()->create();
         $booksWithoutSort = Book::query()->whereNull('sort_set_id')->count();
         $this->assertGreaterThan(0, $booksWithoutSort);
 
@@ -67,9 +67,9 @@ class AssignSortSetCommandTest extends TestCase
     {
         $totalBooks = Book::query()->count();
         $book = $this->entities->book();
-        $sortSetA = SortSet::factory()->create();
-        $sortSetB = SortSet::factory()->create();
-        $book->sort_set_id = $sortSetA->id;
+        $sortSetA = SortRule::factory()->create();
+        $sortSetB = SortRule::factory()->create();
+        $book->sort_rule_id = $sortSetA->id;
         $book->save();
 
         $booksWithoutSort = Book::query()->whereNull('sort_set_id')->count();
@@ -88,9 +88,9 @@ class AssignSortSetCommandTest extends TestCase
     public function test_assign_to_all_books_with_sort()
     {
         $book = $this->entities->book();
-        $sortSetA = SortSet::factory()->create();
-        $sortSetB = SortSet::factory()->create();
-        $book->sort_set_id = $sortSetA->id;
+        $sortSetA = SortRule::factory()->create();
+        $sortSetB = SortRule::factory()->create();
+        $book->sort_rule_id = $sortSetA->id;
         $book->save();
 
         $this->artisan("bookstack:assign-sort-set {$sortSetB->id} --books-with-sort={$sortSetA->id}")
@@ -99,7 +99,7 @@ class AssignSortSetCommandTest extends TestCase
             ->assertExitCode(0);
 
         $book->refresh();
-        $this->assertEquals($sortSetB->id, $book->sort_set_id);
+        $this->assertEquals($sortSetB->id, $book->sort_rule_id);
         $this->assertEquals(1, $sortSetB->books()->count());
     }
 
index deeead099110aa56271004cdc437e305678160ee..e444d165fb314193cb146e6d416a3ad677df74fd 100644 (file)
@@ -300,7 +300,7 @@ class PageTest extends TestCase
         ]);
 
         $resp = $this->asAdmin()->get('/pages/recently-updated');
-        $this->withHtml($resp)->assertElementContains('.entity-list .page:nth-child(1)', 'Updated 0 seconds ago by ' . $user->name);
+        $this->withHtml($resp)->assertElementContains('.entity-list .page:nth-child(1) small', 'by ' . $user->name);
     }
 
     public function test_recently_updated_pages_view_shows_parent_chain()
index a726da148985d6094deb10b5d48a44a195f0c94d..b30cec8b63602c9c99c4ec4c2df6d71ee0c0eb3d 100644 (file)
@@ -5,7 +5,7 @@ namespace Sorting;
 use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Page;
 use BookStack\Entities\Repos\PageRepo;
-use BookStack\Sorting\SortSet;
+use BookStack\Sorting\SortRule;
 use Tests\TestCase;
 
 class BookSortTest extends TestCase
@@ -223,13 +223,13 @@ class BookSortTest extends TestCase
 
     public function test_book_sort_item_shows_auto_sort_status()
     {
-        $sort = SortSet::factory()->create(['name' => 'My sort']);
+        $sort = SortRule::factory()->create(['name' => 'My sort']);
         $book = $this->entities->book();
 
         $resp = $this->asAdmin()->get($book->getUrl('/sort-item'));
         $this->withHtml($resp)->assertElementNotExists("span[title='Auto Sort Active: My sort']");
 
-        $book->sort_set_id = $sort->id;
+        $book->sort_rule_id = $sort->id;
         $book->save();
 
         $resp = $this->asAdmin()->get($book->getUrl('/sort-item'));
@@ -238,7 +238,7 @@ class BookSortTest extends TestCase
 
     public function test_auto_sort_options_shown_on_sort_page()
     {
-        $sort = SortSet::factory()->create();
+        $sort = SortRule::factory()->create();
         $book = $this->entities->book();
         $resp = $this->asAdmin()->get($book->getUrl('/sort'));
 
@@ -247,7 +247,7 @@ class BookSortTest extends TestCase
 
     public function test_auto_sort_option_submit_saves_to_book()
     {
-        $sort = SortSet::factory()->create();
+        $sort = SortRule::factory()->create();
         $book = $this->entities->book();
         $bookPage = $book->pages()->first();
         $bookPage->priority = 10000;
@@ -261,7 +261,7 @@ class BookSortTest extends TestCase
         $book->refresh();
         $bookPage->refresh();
 
-        $this->assertEquals($sort->id, $book->sort_set_id);
+        $this->assertEquals($sort->id, $book->sort_rule_id);
         $this->assertNotEquals(10000, $bookPage->priority);
 
         $resp = $this->get($book->getUrl('/sort'));
similarity index 58%
rename from tests/Sorting/SortSetTest.php
rename to tests/Sorting/SortRuleTest.php
index 5f30034bd773723e2d247ceb8ecc8cb83c6093a0..d0ff263df27362162653b0bb9a1dce0898f1f800 100644 (file)
@@ -4,26 +4,26 @@ namespace Sorting;
 
 use BookStack\Activity\ActivityType;
 use BookStack\Entities\Models\Book;
-use BookStack\Sorting\SortSet;
+use BookStack\Sorting\SortRule;
 use Tests\Api\TestsApi;
 use Tests\TestCase;
 
-class SortSetTest extends TestCase
+class SortRuleTest extends TestCase
 {
     use TestsApi;
 
     public function test_manage_settings_permission_required()
     {
-        $set = SortSet::factory()->create();
+        $rule = SortRule::factory()->create();
         $user = $this->users->viewer();
         $this->actingAs($user);
 
         $actions = [
             ['GET', '/settings/sorting'],
-            ['POST', '/settings/sorting/sets'],
-            ['GET', "/settings/sorting/sets/{$set->id}"],
-            ['PUT', "/settings/sorting/sets/{$set->id}"],
-            ['DELETE', "/settings/sorting/sets/{$set->id}"],
+            ['POST', '/settings/sorting/rules'],
+            ['GET', "/settings/sorting/rules/{$rule->id}"],
+            ['PUT', "/settings/sorting/rules/{$rule->id}"],
+            ['DELETE', "/settings/sorting/rules/{$rule->id}"],
         ];
 
         foreach ($actions as [$method, $path]) {
@@ -42,63 +42,63 @@ class SortSetTest extends TestCase
     public function test_create_flow()
     {
         $resp = $this->asAdmin()->get('/settings/sorting');
-        $this->withHtml($resp)->assertLinkExists(url('/settings/sorting/sets/new'));
+        $this->withHtml($resp)->assertLinkExists(url('/settings/sorting/rules/new'));
 
-        $resp = $this->get('/settings/sorting/sets/new');
-        $this->withHtml($resp)->assertElementExists('form[action$="/settings/sorting/sets"] input[name="name"]');
+        $resp = $this->get('/settings/sorting/rules/new');
+        $this->withHtml($resp)->assertElementExists('form[action$="/settings/sorting/rules"] input[name="name"]');
         $resp->assertSeeText('Name - Alphabetical (Asc)');
 
         $details = ['name' => 'My new sort', 'sequence' => 'name_asc'];
-        $resp = $this->post('/settings/sorting/sets', $details);
+        $resp = $this->post('/settings/sorting/rules', $details);
         $resp->assertRedirect('/settings/sorting');
 
-        $this->assertActivityExists(ActivityType::SORT_SET_CREATE);
-        $this->assertDatabaseHas('sort_sets', $details);
+        $this->assertActivityExists(ActivityType::SORT_RULE_CREATE);
+        $this->assertDatabaseHas('sort_rules', $details);
     }
 
     public function test_listing_in_settings()
     {
-        $set = SortSet::factory()->create(['name' => 'My super sort set', 'sequence' => 'name_asc']);
+        $rule = SortRule::factory()->create(['name' => 'My super sort rule', 'sequence' => 'name_asc']);
         $books = Book::query()->limit(5)->get();
         foreach ($books as $book) {
-            $book->sort_set_id = $set->id;
+            $book->sort_rule_id = $rule->id;
             $book->save();
         }
 
         $resp = $this->asAdmin()->get('/settings/sorting');
-        $resp->assertSeeText('My super sort set');
+        $resp->assertSeeText('My super sort rule');
         $resp->assertSeeText('Name - Alphabetical (Asc)');
         $this->withHtml($resp)->assertElementContains('.item-list-row [title="Assigned to 5 Books"]', '5');
     }
 
     public function test_update_flow()
     {
-        $set = SortSet::factory()->create(['name' => 'My sort set to update', 'sequence' => 'name_asc']);
+        $rule = SortRule::factory()->create(['name' => 'My sort rule to update', 'sequence' => 'name_asc']);
 
-        $resp = $this->asAdmin()->get("/settings/sorting/sets/{$set->id}");
+        $resp = $this->asAdmin()->get("/settings/sorting/rules/{$rule->id}");
         $respHtml = $this->withHtml($resp);
         $respHtml->assertElementContains('.configured-option-list', 'Name - Alphabetical (Asc)');
         $respHtml->assertElementNotContains('.available-option-list', 'Name - Alphabetical (Asc)');
 
         $updateData = ['name' => 'My updated sort', 'sequence' => 'name_desc,chapters_last'];
-        $resp = $this->put("/settings/sorting/sets/{$set->id}", $updateData);
+        $resp = $this->put("/settings/sorting/rules/{$rule->id}", $updateData);
 
         $resp->assertRedirect('/settings/sorting');
-        $this->assertActivityExists(ActivityType::SORT_SET_UPDATE);
-        $this->assertDatabaseHas('sort_sets', $updateData);
+        $this->assertActivityExists(ActivityType::SORT_RULE_UPDATE);
+        $this->assertDatabaseHas('sort_rules', $updateData);
     }
 
     public function test_update_triggers_resort_on_assigned_books()
     {
         $book = $this->entities->bookHasChaptersAndPages();
         $chapter = $book->chapters()->first();
-        $set = SortSet::factory()->create(['name' => 'My sort set to update', 'sequence' => 'name_asc']);
-        $book->sort_set_id = $set->id;
+        $rule = SortRule::factory()->create(['name' => 'My sort rule to update', 'sequence' => 'name_asc']);
+        $book->sort_rule_id = $rule->id;
         $book->save();
         $chapter->priority = 10000;
         $chapter->save();
 
-        $resp = $this->asAdmin()->put("/settings/sorting/sets/{$set->id}", ['name' => $set->name, 'sequence' => 'chapters_last']);
+        $resp = $this->asAdmin()->put("/settings/sorting/rules/{$rule->id}", ['name' => $rule->name, 'sequence' => 'chapters_last']);
         $resp->assertRedirect('/settings/sorting');
 
         $chapter->refresh();
@@ -107,48 +107,48 @@ class SortSetTest extends TestCase
 
     public function test_delete_flow()
     {
-        $set = SortSet::factory()->create();
+        $rule = SortRule::factory()->create();
 
-        $resp = $this->asAdmin()->get("/settings/sorting/sets/{$set->id}");
-        $resp->assertSeeText('Delete Sort Set');
+        $resp = $this->asAdmin()->get("/settings/sorting/rules/{$rule->id}");
+        $resp->assertSeeText('Delete Sort Rule');
 
-        $resp = $this->delete("settings/sorting/sets/{$set->id}");
+        $resp = $this->delete("settings/sorting/rules/{$rule->id}");
         $resp->assertRedirect('/settings/sorting');
 
-        $this->assertActivityExists(ActivityType::SORT_SET_DELETE);
-        $this->assertDatabaseMissing('sort_sets', ['id' => $set->id]);
+        $this->assertActivityExists(ActivityType::SORT_RULE_DELETE);
+        $this->assertDatabaseMissing('sort_rules', ['id' => $rule->id]);
     }
 
     public function test_delete_requires_confirmation_if_books_assigned()
     {
-        $set = SortSet::factory()->create();
+        $rule = SortRule::factory()->create();
         $books = Book::query()->limit(5)->get();
         foreach ($books as $book) {
-            $book->sort_set_id = $set->id;
+            $book->sort_rule_id = $rule->id;
             $book->save();
         }
 
-        $resp = $this->asAdmin()->get("/settings/sorting/sets/{$set->id}");
-        $resp->assertSeeText('Delete Sort Set');
+        $resp = $this->asAdmin()->get("/settings/sorting/rules/{$rule->id}");
+        $resp->assertSeeText('Delete Sort Rule');
 
-        $resp = $this->delete("settings/sorting/sets/{$set->id}");
-        $resp->assertRedirect("/settings/sorting/sets/{$set->id}#delete");
+        $resp = $this->delete("settings/sorting/rules/{$rule->id}");
+        $resp->assertRedirect("/settings/sorting/rules/{$rule->id}#delete");
         $resp = $this->followRedirects($resp);
 
-        $resp->assertSeeText('This sort set is currently used on 5 book(s). Are you sure you want to delete this?');
-        $this->assertDatabaseHas('sort_sets', ['id' => $set->id]);
+        $resp->assertSeeText('This sort rule is currently used on 5 book(s). Are you sure you want to delete this?');
+        $this->assertDatabaseHas('sort_rules', ['id' => $rule->id]);
 
-        $resp = $this->delete("settings/sorting/sets/{$set->id}", ['confirm' => 'true']);
+        $resp = $this->delete("settings/sorting/rules/{$rule->id}", ['confirm' => 'true']);
         $resp->assertRedirect('/settings/sorting');
-        $this->assertDatabaseMissing('sort_sets', ['id' => $set->id]);
-        $this->assertDatabaseMissing('books', ['sort_set_id' => $set->id]);
+        $this->assertDatabaseMissing('sort_rules', ['id' => $rule->id]);
+        $this->assertDatabaseMissing('books', ['sort_rule_id' => $rule->id]);
     }
 
     public function test_page_create_triggers_book_sort()
     {
         $book = $this->entities->bookHasChaptersAndPages();
-        $set = SortSet::factory()->create(['sequence' => 'name_asc,chapters_first']);
-        $book->sort_set_id = $set->id;
+        $rule = SortRule::factory()->create(['sequence' => 'name_asc,chapters_first']);
+        $book->sort_rule_id = $rule->id;
         $book->save();
 
         $resp = $this->actingAsApiEditor()->post("/api/pages", [
@@ -168,8 +168,8 @@ class SortSetTest extends TestCase
     public function test_name_numeric_ordering()
     {
         $book = Book::factory()->create();
-        $set = SortSet::factory()->create(['sequence' => 'name_numeric_asc']);
-        $book->sort_set_id = $set->id;
+        $rule = SortRule::factory()->create(['sequence' => 'name_numeric_asc']);
+        $book->sort_rule_id = $rule->id;
         $book->save();
         $this->permissions->regenerateForEntity($book);
 
Morty Proxy This is a proxified and sanitized view of the page, visit original site.