Merge pull request #16556 from barryvdh/feat-stablesort

Make defaultKeySort configurable
This commit is contained in:
Dan Harrin
2025-06-26 11:15:01 +01:00
committed by GitHub
3 changed files with 67 additions and 7 deletions
@@ -92,6 +92,8 @@ trait CanSortRecords
$column->applySort($query, $sortDirection);
$this->applyDefaultKeySortToTableQuery($query);
return $query;
}
@@ -105,25 +107,52 @@ trait CanSortRecords
($sortColumn = $this->getTable()->getSortableVisibleColumn($defaultSort))
) {
$sortColumn->applySort($query, $sortDirection);
return $query;
}
if (is_string($defaultSort)) {
return $query->orderBy($defaultSort, $sortDirection);
} 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) { /** @phpstan-ignore nullCoalesce.property */
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.
*/
@@ -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);
}
}
@@ -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();