mirror of
https://github.com/filamentphp/filament.git
synced 2026-09-24 15:42:09 +08:00
[4.x] Fix last group summary (#19593)
* Fix last group summary * fix cursor pagination and add negative test * Update PostsTableWithCursorPagination.php * Update SummaryTest.php --------- Co-authored-by: Dan Harrin <git@danharrin.com>
This commit is contained in:
co-authored by
Dan Harrin
parent
bbe9ad4dbb
commit
dd580292da
@@ -1301,7 +1301,7 @@
|
||||
@endphp
|
||||
@endforeach
|
||||
|
||||
@if ($hasSummary && (! $isReordering) && filled($previousRecordGroupTitle) && ((! $records instanceof \Illuminate\Contracts\Pagination\Paginator) || (! $records->hasMorePages())))
|
||||
@if ($hasSummary && (! $isReordering) && filled($previousRecordGroupTitle) && $this->shouldRenderTrailingGroupedTableSummary($previousRecord))
|
||||
<table class="fi-ta-table">
|
||||
<tbody>
|
||||
@php
|
||||
@@ -2353,7 +2353,7 @@
|
||||
@endphp
|
||||
@endforeach
|
||||
|
||||
@if ($hasSummary && (! $isReordering) && filled($previousRecordGroupTitle) && ((! $records instanceof \Illuminate\Contracts\Pagination\Paginator) || (! $records->hasMorePages())))
|
||||
@if ($hasSummary && (! $isReordering) && filled($previousRecordGroupTitle) && $this->shouldRenderTrailingGroupedTableSummary($previousRecord))
|
||||
@php
|
||||
$groupColumn = $group->getColumn();
|
||||
$groupScopedAllTableSummaryQuery = $group->scopeQuery($this->getAllTableSummaryQuery(), $previousRecord);
|
||||
|
||||
@@ -4,13 +4,68 @@ namespace Filament\Tables\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Filament\Support\Services\RelationshipJoiner;
|
||||
use Illuminate\Contracts\Pagination\CursorPaginator;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Support\Str;
|
||||
use stdClass;
|
||||
|
||||
trait CanSummarizeRecords
|
||||
{
|
||||
/**
|
||||
* @param Model | array<string, mixed> | null $lastRecord
|
||||
*/
|
||||
public function shouldRenderTrailingGroupedTableSummary(Model | array | null $lastRecord): bool
|
||||
{
|
||||
if ($lastRecord === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$records = $this->getTableRecords();
|
||||
|
||||
$isPaginated = ($records instanceof Paginator) || ($records instanceof CursorPaginator);
|
||||
|
||||
if ((! $isPaginated) || (! $records->hasMorePages())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$group = $this->getTableGrouping();
|
||||
|
||||
if (! $group) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$query = $this->getFilteredSortedTableQuery();
|
||||
|
||||
if ($query === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($records instanceof CursorPaginator) {
|
||||
$nextCursor = $records->nextCursor();
|
||||
|
||||
if (! $nextCursor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$nextPageFirstRecord = (clone $query)
|
||||
->cursorPaginate(perPage: 1, cursor: $nextCursor)
|
||||
->items()[0] ?? null;
|
||||
} else {
|
||||
$nextPageFirstRecord = (clone $query)
|
||||
->skip($records->currentPage() * $records->perPage())
|
||||
->first();
|
||||
}
|
||||
|
||||
if ($nextPageFirstRecord === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $group->getStringKey($nextPageFirstRecord) !== $group->getStringKey($lastRecord);
|
||||
}
|
||||
|
||||
public function getAllTableSummaryQuery(): ?Builder
|
||||
{
|
||||
return $this->getFilteredTableQuery();
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Tests\Fixtures\Livewire;
|
||||
|
||||
use Filament\Actions\Concerns\InteractsWithActions;
|
||||
use Filament\Actions\Contracts\HasActions;
|
||||
use Filament\Schemas\Concerns\InteractsWithSchemas;
|
||||
use Filament\Schemas\Contracts\HasSchemas;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Enums\PaginationMode;
|
||||
use Filament\Tables\Table;
|
||||
use Filament\Tests\Fixtures\Models\Post;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Livewire\Component;
|
||||
|
||||
class PostsTableWithCursorPagination extends Component implements HasActions, HasSchemas, Tables\Contracts\HasTable
|
||||
{
|
||||
use InteractsWithActions;
|
||||
use InteractsWithSchemas;
|
||||
use Tables\Concerns\InteractsWithTable;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->query(Post::query())
|
||||
->paginationMode(PaginationMode::Cursor)
|
||||
->groups(fn () => [
|
||||
Tables\Grouping\Group::make('title'),
|
||||
])
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('title')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('rating')
|
||||
->summarize([
|
||||
Tables\Columns\Summarizers\Sum::make('sum'),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.table');
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,10 @@ use Filament\Schemas\Contracts\HasSchemas;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Filament\Tests\Fixtures\Livewire\PostsTable;
|
||||
use Filament\Tests\Fixtures\Livewire\PostsTableWithCursorPagination;
|
||||
use Filament\Tests\Fixtures\Models\Post;
|
||||
use Filament\Tests\Tables\TestCase;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Livewire\Component;
|
||||
|
||||
use function Filament\Tests\livewire;
|
||||
@@ -169,6 +169,46 @@ it('renders group summaries when page and all-table summaries are disabled', fun
|
||||
->assertDontSeeHtml('fi-ta-summary-header-row');
|
||||
});
|
||||
|
||||
it('renders the trailing group summary when the next page starts a different group', function (): void {
|
||||
Post::factory()->count(10)->create(['title' => 'A']);
|
||||
Post::factory()->create(['title' => 'B']);
|
||||
|
||||
livewire(PostsTable::class)
|
||||
->set('tableRecordsPerPage', 10)
|
||||
->set('tableGrouping', 'title')
|
||||
->assertSee('A summary')
|
||||
->assertDontSee('B summary');
|
||||
});
|
||||
|
||||
it('does not render the trailing group summary when the next page continues the same group', function (): void {
|
||||
Post::factory()->count(15)->create(['title' => 'A']);
|
||||
|
||||
livewire(PostsTable::class)
|
||||
->set('tableRecordsPerPage', 10)
|
||||
->set('tableGrouping', 'title')
|
||||
->assertDontSee('A summary');
|
||||
});
|
||||
|
||||
it('renders the trailing group summary with cursor pagination when the next page starts a different group', function (): void {
|
||||
Post::factory()->count(10)->create(['title' => 'A']);
|
||||
Post::factory()->create(['title' => 'B']);
|
||||
|
||||
livewire(PostsTableWithCursorPagination::class)
|
||||
->set('tableRecordsPerPage', 10)
|
||||
->set('tableGrouping', 'title')
|
||||
->assertSee('A summary')
|
||||
->assertDontSee('B summary');
|
||||
});
|
||||
|
||||
it('does not render the trailing group summary with cursor pagination when the next page continues the same group', function (): void {
|
||||
Post::factory()->count(15)->create(['title' => 'A']);
|
||||
|
||||
livewire(PostsTableWithCursorPagination::class)
|
||||
->set('tableRecordsPerPage', 10)
|
||||
->set('tableGrouping', 'title')
|
||||
->assertDontSee('A summary');
|
||||
});
|
||||
|
||||
class TestTableWithGroupSummariesOnly extends Component implements HasActions, HasSchemas, Tables\Contracts\HasTable
|
||||
{
|
||||
use InteractsWithActions;
|
||||
|
||||
Reference in New Issue
Block a user