Filament's Table builder allows you to group your table rows by date out of the box, but what if you need to group by "month and year"? I encountered this need while working on a project that required viewing purchases grouped by month-year, and after some trial and error, I've figured it out!
Below is the snippet you need:
<?php
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Grouping\Group;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
class ReceiptResource extends Resource
{
protected static ?string $model = Purchase::class;
protected static ?string $label = 'Purchases';
public static function table(Table $table): Table
{
return $table
->recordTitleAttribute('vendor_name')
->columns([
// Ex: "Friday 23. September 2023"
Tables\Columns\TextColumn::make('date')->label('Purchase Date')->date('l j. F Y'),
Tables\Columns\TextColumn::make('vendor_name')->label('Vendor'),
Tables\Columns\TextColumn::make('total_amount')->label('Total Amount'),
])
->defaultGroup(
// Group the rows by Year and Month (2023-09, 2023-11 etc) instead of "date"
Group::make('date')
// Ex: "2023-10-0",
// Note: You need the "-0" at the end, so Carbon can parse the date.
->getKeyFromRecordUsing(
fn(Purchase $record): string => $record->date->format('Y-m-0')
)
// Ex: "September 2023"
->getTitleFromRecordUsing(
fn(Purchase $record): string => $record->date->format('F Y')
)
// Set the default ordering
->orderQueryUsing(
fn(Builder $query, string $direction) => $query->orderBy('date', 'desc')
)
// Hide "date: " in the Group title
->titlePrefixedWithLabel(false),
);
}
}
