From 4e01d235c7db31e9331e9a9415210513b95bb8cd Mon Sep 17 00:00:00 2001 From: "Barry vd. Heuvel" Date: Wed, 18 Jun 2025 15:54:11 +0200 Subject: [PATCH] Rename to defaultKeySort --- .../src/Concerns/CanPaginateRecords.php | 5 --- .../tables/src/Concerns/CanSortRecords.php | 44 ++++++++++++++++--- .../src/Table/Concerns/CanPaginateRecords.php | 14 ------ .../src/Table/Concerns/CanSortRecords.php | 14 ++++++ .../Resources/Pages/ListRecordsTest.php | 17 +++++++ 5 files changed, 68 insertions(+), 26 deletions(-) diff --git a/packages/tables/src/Concerns/CanPaginateRecords.php b/packages/tables/src/Concerns/CanPaginateRecords.php index ea8691ed70..d16e6a532e 100644 --- a/packages/tables/src/Concerns/CanPaginateRecords.php +++ b/packages/tables/src/Concerns/CanPaginateRecords.php @@ -30,11 +30,6 @@ trait CanPaginateRecords { $perPage = $this->getTableRecordsPerPage(); - if ($this->getTable()->getStableSort()) { - // Add orderBy key to ensure stable order results - $query->orderBy($query->getModel()->getQualifiedKeyName()); - } - if (version_compare(App::version(), '11.0', '>=')) { $total = $query->toBase()->getCountForPagination(); diff --git a/packages/tables/src/Concerns/CanSortRecords.php b/packages/tables/src/Concerns/CanSortRecords.php index 123afce35f..740501036f 100644 --- a/packages/tables/src/Concerns/CanSortRecords.php +++ b/packages/tables/src/Concerns/CanSortRecords.php @@ -92,6 +92,8 @@ trait CanSortRecords $column->applySort($query, $sortDirection); + $this->applyDefaultKeySortToTableQuery($query); + return $query; } @@ -105,25 +107,53 @@ trait CanSortRecords ($sortColumn = $this->getTable()->getSortableVisibleColumn($defaultSort)) ) { $sortColumn->applySort($query, $sortDirection); - - return $query; - } - - if (is_string($defaultSort)) { - return $query->orderBy($defaultSort, $sortDirection); + $this->applyDefaultKeySortToTableQuery($query); + } elseif (is_string($defaultSort)) { + $query->orderBy($defaultSort, $sortDirection); } if ($defaultSort instanceof Builder) { - return $defaultSort; + $query = $defaultSort; } if (filled($query->toBase()->orders)) { + $this->applyDefaultKeySortToTableQuery($query); + return $query; } return $query->orderBy($query->getModel()->getQualifiedKeyName()); } + protected function applyDefaultKeySortToTableQuery(Builder $query): Builder + { + if (! $this->getTable()->hasDefaultKeySort()) { + return $query; + } + + $qualifiedKeyName = $query->getModel()->getQualifiedKeyName(); + + foreach ($query->toBase()->orders ?? [] as $order) { + if (($order['column'] ?? null) === $qualifiedKeyName) { + return $query; + } + + if ( + is_string($order['column'] ?? null) && + str($order['column'] ?? null)->contains('.') && + str($order['column'] ?? null)->afterLast('.')->is( + str($qualifiedKeyName)->afterLast('.') + ) + ) { + return $query; + } + } + + $query->orderBy($qualifiedKeyName); + + return $query; + } + /** * @deprecated Override the `table()` method to configure the table. */ diff --git a/packages/tables/src/Table/Concerns/CanPaginateRecords.php b/packages/tables/src/Table/Concerns/CanPaginateRecords.php index 81b031bf7f..ba92f0566f 100644 --- a/packages/tables/src/Table/Concerns/CanPaginateRecords.php +++ b/packages/tables/src/Table/Concerns/CanPaginateRecords.php @@ -20,8 +20,6 @@ trait CanPaginateRecords protected bool | Closure $hasExtremePaginationLinks = false; - protected bool $stableSort = false; - public function defaultPaginationPageOption(int | string | Closure | null $option): static { $this->defaultPaginationPageOption = $option; @@ -68,13 +66,6 @@ trait CanPaginateRecords return $this; } - public function stableSort(?bool $value = true): static - { - $this->stableSort = $value; - - return $this; - } - public function getDefaultPaginationPageOption(): int | string | null { $option = $this->evaluate($this->defaultPaginationPageOption); @@ -100,11 +91,6 @@ trait CanPaginateRecords return $this->evaluate($this->paginationPageOptions) ?? [5, 10, 25, 50, 'all']; } - public function getStableSort(): bool - { - return $this->stableSort; - } - public function isPaginated(): bool { return $this->evaluate($this->isPaginated) && (! $this->isGroupsOnly()); diff --git a/packages/tables/src/Table/Concerns/CanSortRecords.php b/packages/tables/src/Table/Concerns/CanSortRecords.php index 4c364c1896..798e555e61 100644 --- a/packages/tables/src/Table/Concerns/CanSortRecords.php +++ b/packages/tables/src/Table/Concerns/CanSortRecords.php @@ -18,6 +18,8 @@ trait CanSortRecords protected string | Htmlable | Closure | null $defaultSortOptionLabel = null; + protected bool | Closure $hasDefaultKeySort = false; + public function defaultSort(string | Closure | null $column, string | Closure | null $direction = 'asc'): static { $this->defaultSort = $column; @@ -40,6 +42,13 @@ trait CanSortRecords return $this; } + public function defaultKeySort(bool | Closure $condition = true): static + { + $this->hasDefaultKeySort = $condition; + + return $this; + } + public function getSortableVisibleColumn(string $name): ?Column { $column = $this->getColumn($name); @@ -121,4 +130,9 @@ trait CanSortRecords { return $this->evaluate($this->defaultSortOptionLabel) ?? '-'; } + + public function hasDefaultKeySort(): bool + { + return (bool) $this->evaluate($this->hasDefaultKeySort); + } } diff --git a/tests/src/Panels/Resources/Pages/ListRecordsTest.php b/tests/src/Panels/Resources/Pages/ListRecordsTest.php index c7ecc24b4e..26e743007d 100644 --- a/tests/src/Panels/Resources/Pages/ListRecordsTest.php +++ b/tests/src/Panels/Resources/Pages/ListRecordsTest.php @@ -65,6 +65,23 @@ it('can sort posts by author', function () { ->assertCanSeeTableRecords($posts->sortByDesc('author.name'), inOrder: true); }); +it('can sort posts with default sort key', function () { + + $faker = fake()->unique(); + $posts = Post::factory()->count(10)->state(function () use ($faker) { + return [ + 'id' => $faker->randomDigit(), + 'title' => 'Lorem Ipsum', + ]; + })->create(); + + livewire(ListPosts::class) + ->sortTable('title') + ->assertCanSeeTableRecords($posts->sortBy([['title', 'asc'], ['id', 'asc']]), inOrder: true) + ->sortTable('title', 'desc') + ->assertCanSeeTableRecords($posts->sortBy([['title', 'desc'], ['id', 'asc']]), inOrder: true); +}); + it('can search posts by title', function () { $posts = Post::factory()->count(10)->create();