Filament getTabs method for table on custom resource page

I have a resource DriverResource. I want to add a custom page with driver statistics to this resource and have tabs above the table. I added the tabs, they are displayed, but the content does not change when clicked. There are no errors in the console or logs My route path /admin/drivers/{driver_id}/statistics
<?php

namespace App\Filament\Resources\DriverResource\Pages;

use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Resources\Concerns\HasTabs;
use Filament\Tables\Concerns\InteractsWithTable;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use App\Filament\Resources\DriverResource;
use App\Models\OrderSegment;
use Filament\Resources\Pages\Page;
use Filament\Tables;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Filament\Resources\Components\Tab;

class DriverStatistics extends Page implements Tables\Contracts\HasTable, HasForms
{
use InteractsWithTable;
use InteractsWithForms;
use HasTabs;

protected static string $resource = DriverResource::class;
protected static string $view = 'filament.resources.driver-resource.pages.driver-statistics';

public function table(Tables\Table $table): Tables\Table
{
$driverId = request()->route('record');

return $table
->query(
OrderSegment::query()
->select()
->addSelect([
DB::raw('ST_AsText(pickup_location) as pickup_location'),
DB::raw('ST_AsText(destination_location) as destination_location')
])
->whereHas('order.shift.driver', function (EloquentBuilder $query) use ($driverId) {
$query->where('id', $driverId);
})
);//Code next will be comment, have max symbols discord
}
}
<?php

namespace App\Filament\Resources\DriverResource\Pages;

use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Resources\Concerns\HasTabs;
use Filament\Tables\Concerns\InteractsWithTable;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use App\Filament\Resources\DriverResource;
use App\Models\OrderSegment;
use Filament\Resources\Pages\Page;
use Filament\Tables;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Filament\Resources\Components\Tab;

class DriverStatistics extends Page implements Tables\Contracts\HasTable, HasForms
{
use InteractsWithTable;
use InteractsWithForms;
use HasTabs;

protected static string $resource = DriverResource::class;
protected static string $view = 'filament.resources.driver-resource.pages.driver-statistics';

public function table(Tables\Table $table): Tables\Table
{
$driverId = request()->route('record');

return $table
->query(
OrderSegment::query()
->select()
->addSelect([
DB::raw('ST_AsText(pickup_location) as pickup_location'),
DB::raw('ST_AsText(destination_location) as destination_location')
])
->whereHas('order.shift.driver', function (EloquentBuilder $query) use ($driverId) {
$query->where('id', $driverId);
})
);//Code next will be comment, have max symbols discord
}
}
No description
12 Replies
cepairda
cepairdaOP2mo ago
->columns([
Tables\Columns\TextColumn::make('pickup_address')->label('Откуда'),
Tables\Columns\TextColumn::make('destination_address')->label('Куда'),
Tables\Columns\TextColumn::make('price')->label('Цена'),
]);

public function getTabs(): array
{
return [
'today' => Tab::make('Today')
->modifyQueryUsing(fn (Builder $query) => $query->whereDate('created_at', Carbon::today())),

'week' => Tab::make('Week')
->modifyQueryUsing(fn (Builder $query) =>
$query->whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()])),

'month' => Tab::make('Month')
->modifyQueryUsing(fn (Builder $query) =>
$query->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()])),
];
}
->columns([
Tables\Columns\TextColumn::make('pickup_address')->label('Откуда'),
Tables\Columns\TextColumn::make('destination_address')->label('Куда'),
Tables\Columns\TextColumn::make('price')->label('Цена'),
]);

public function getTabs(): array
{
return [
'today' => Tab::make('Today')
->modifyQueryUsing(fn (Builder $query) => $query->whereDate('created_at', Carbon::today())),

'week' => Tab::make('Week')
->modifyQueryUsing(fn (Builder $query) =>
$query->whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()])),

'month' => Tab::make('Month')
->modifyQueryUsing(fn (Builder $query) =>
$query->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()])),
];
}
Dennis Koch
Dennis Koch2mo ago
$driverId = request()->route('record');
$driverId = request()->route('record');
Never use route params when working with Livewire. They aren't there on Livewire requests.
public function getTabs(): array
public function getTabs(): array
getTabs() is a feature of the ListPage and the logic is implemented there. If you just add a getTabs() I'd expect nothing to change. How did you get the tabs over the table?
cepairda
cepairdaOP2mo ago
I did it like in the example here https://github.com/filamentphp/filament/discussions/10127#discussioncomment-8206452 At the moment I made the type ListRecords instead Page. But there is a problem. I get the record only on the first page load. I understand that the problem is that I can't get record id. Inside DriverResource I declared a route. Then I want to use this id to get statistics
'stat' => Pages\StatDrivers::route('/{record}/statistics'),
'stat' => Pages\StatDrivers::route('/{record}/statistics'),
GitHub
Tabs in custom page · filamentphp filament · Discussion #10127
hello there! please need a help on how to make a tabs on custompage in filament? i have create a custom page named product linked with a resource named categoryResource.Then when i tried to use the...
cepairda
cepairdaOP2mo ago
<?php

namespace App\Filament\Resources\DriverResource\Pages;

use App\Filament\Resources\DriverResource;
use App\Models\Order;
use App\Models\OrderSegment;
use Filament\Actions;
use Filament\Resources\Components\Tab;
use Filament\Resources\Pages\Concerns\InteractsWithRecord;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Filament\Tables\Table;
use Filament\Tables\Columns\TextColumn;

class StatDrivers extends ListRecords
{
use InteractsWithRecord;

protected static string $resource = DriverResource::class;

protected function getTableQuery(): ?Builder
{
$driverId = request()->route('record');

return OrderSegment::query()
->select()
->addSelect([
DB::raw('ST_AsText(pickup_location) as pickup_location'),
DB::raw('ST_AsText(destination_location) as destination_location')
])
->whereHas('order.shift.driver', function (Builder $query) use ($driverId) {
$query->where('id', $driverId);
});
}

public function table(Table $table): Table
{
return $table
->query(
$this->getTableQuery()
)
->columns([
TextColumn::make('id')->label('From'),
TextColumn::make('status')->label('Where'),
TextColumn::make('shift_id')->label('Price'),
]);
//->defaultGroup('order_id');
}
//getTAbs below
}
<?php

namespace App\Filament\Resources\DriverResource\Pages;

use App\Filament\Resources\DriverResource;
use App\Models\Order;
use App\Models\OrderSegment;
use Filament\Actions;
use Filament\Resources\Components\Tab;
use Filament\Resources\Pages\Concerns\InteractsWithRecord;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Filament\Tables\Table;
use Filament\Tables\Columns\TextColumn;

class StatDrivers extends ListRecords
{
use InteractsWithRecord;

protected static string $resource = DriverResource::class;

protected function getTableQuery(): ?Builder
{
$driverId = request()->route('record');

return OrderSegment::query()
->select()
->addSelect([
DB::raw('ST_AsText(pickup_location) as pickup_location'),
DB::raw('ST_AsText(destination_location) as destination_location')
])
->whereHas('order.shift.driver', function (Builder $query) use ($driverId) {
$query->where('id', $driverId);
});
}

public function table(Table $table): Table
{
return $table
->query(
$this->getTableQuery()
)
->columns([
TextColumn::make('id')->label('From'),
TextColumn::make('status')->label('Where'),
TextColumn::make('shift_id')->label('Price'),
]);
//->defaultGroup('order_id');
}
//getTAbs below
}
public function getTabs(): array
{
return [
'all' => Tab::make(),
'today' => Tab::make('Today')
->modifyQueryUsing(fn (Builder $query) => $query->whereDate('created_at', Carbon::today())),

'week' => Tab::make('Week')
->modifyQueryUsing(fn (Builder $query) =>
$query->whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()])),

'month' => Tab::make('Month')
->modifyQueryUsing(fn (Builder $query) =>
$query->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()])),
];
}
public function getTabs(): array
{
return [
'all' => Tab::make(),
'today' => Tab::make('Today')
->modifyQueryUsing(fn (Builder $query) => $query->whereDate('created_at', Carbon::today())),

'week' => Tab::make('Week')
->modifyQueryUsing(fn (Builder $query) =>
$query->whereBetween('created_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()])),

'month' => Tab::make('Month')
->modifyQueryUsing(fn (Builder $query) =>
$query->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()])),
];
}
@Dennis Koch I did it and now it works, but I don't really like the way. Maybe I chose the wrong way.
class StatDrivers extends ListRecords
{
use InteractsWithRecord;

protected static string $resource = DriverResource::class;

public function mount(): void
{
parent::mount();

$this->record = $this->resolveRecord(request()->route('record'));
}
class StatDrivers extends ListRecords
{
use InteractsWithRecord;

protected static string $resource = DriverResource::class;

public function mount(): void
{
parent::mount();

$this->record = $this->resolveRecord(request()->route('record'));
}
Dennis Koch
Dennis Koch2mo ago
Nope, looks good to me. Just the property public $record doesn't work? 🤔
cepairda
cepairdaOP2mo ago
@Dennis Koch The page works fine, the tabs work. But the widgets don't work, despite the fact that I made the mount. Is there another way to mount ? For example, if I write statically 14, then the widgets work $this->driverId = 14;
class StatDrivers extends ListRecords
{
use ExposesTableToWidgets;

protected static string $resource = DriverResource::class;
public $driverId;

protected function getHeaderWidgets(): array
{
return [
DriverStatistics::class,
];
}

public function mount(): void
{
parent::mount();

//$this->record = $this->resolveRecord(request()->route('record'));
$this->driverId = request()->route('record');
}
class StatDrivers extends ListRecords
{
use ExposesTableToWidgets;

protected static string $resource = DriverResource::class;
public $driverId;

protected function getHeaderWidgets(): array
{
return [
DriverStatistics::class,
];
}

public function mount(): void
{
parent::mount();

//$this->record = $this->resolveRecord(request()->route('record'));
$this->driverId = request()->route('record');
}
Dennis Koch
Dennis Koch2mo ago
Hm that's weird. Did you try debugging whether request()->route('record') is null at any point?
cepairda
cepairdaOP2mo ago
I have the following error. At the same time, the page and pagination work fine, tabs switch without errors [2025-03-17 14:45:54] local.ERROR: Cannot assign null to property App\Filament\Resources\DriverResource\Pages\StatDrivers::$driverId of type int (View: /var/www/app/vendor/filament/widgets/resources/views/stats-overview-widget.blade.php) {"userId":1,"exception":"[object] (Illuminate\View\ViewException(code: 0): Cannot assign null to property App\Filament\Resources\DriverResource\Pages\StatDrivers::$driverId of type int (View: /var/www/app/vendor/filament/widgets/resources/views/stats-overview-widget.blade.php) at /var/www/app/app/Filament/Resources/DriverResource/Pages/StatDrivers.php:38)
Dennis Koch
Dennis Koch2mo ago
What does the widget look like?
cepairda
cepairdaOP2mo ago
GitHub
I created a ListRecords with a parameter in route and my widgets do...
Package Panel builder Package Version 3.3.0 How can we help you? This is my route in the driverresource file 'stat' => Pages\StatDrivers::route('/{record}/statistics'), If I use ...
Dennis Koch
Dennis Koch2mo ago
What happened if you use the $record instead of $driverId? I think the widgets can implement a InteractsWithRecord trait?
cepairda
cepairdaOP2mo ago
There is a conflict with this trait use ExposesTableToWidgets; @Dennis Koch This is because the trigger fires and the mount is called again, but it cannot find the route or record. See line #12
[previous exception] [object] (Illuminate\\Contracts\\Container\\BindingResolutionException(code: 0): Unable to resolve dependency [Parameter #0 [ <required> string|int $record ]] in class Filament\\Resources\\Pages\\ManageRelatedRecords at /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:197)
[stacktrace]
#0 /var/www/app/vendor/livewire/livewire/src/ImplicitlyBoundMethod.php(21): Illuminate\\Container\\BoundMethod::addDependencyForCallParameter(Object(Illuminate\\Foundation\\Application), Object(ReflectionParameter), Array, Array)
#1 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Livewire\\ImplicitlyBoundMethod::getMethodDependencies(Object(Illuminate\\Foundation\\Application), Array, Array)
#2 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::{closure:Illuminate\\Container\\BoundMethod::call():35}()
#3 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(95): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#4 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#5 /var/www/app/vendor/livewire/livewire/src/Wrapped.php(23): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array)
[previous exception] [object] (Illuminate\\Contracts\\Container\\BindingResolutionException(code: 0): Unable to resolve dependency [Parameter #0 [ <required> string|int $record ]] in class Filament\\Resources\\Pages\\ManageRelatedRecords at /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:197)
[stacktrace]
#0 /var/www/app/vendor/livewire/livewire/src/ImplicitlyBoundMethod.php(21): Illuminate\\Container\\BoundMethod::addDependencyForCallParameter(Object(Illuminate\\Foundation\\Application), Object(ReflectionParameter), Array, Array)
#1 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Livewire\\ImplicitlyBoundMethod::getMethodDependencies(Object(Illuminate\\Foundation\\Application), Array, Array)
#2 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::{closure:Illuminate\\Container\\BoundMethod::call():35}()
#3 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(95): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#4 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#5 /var/www/app/vendor/livewire/livewire/src/Wrapped.php(23): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array)
#6 /var/www/app/vendor/livewire/livewire/src/Features/SupportLifecycleHooks/SupportLifecycleHooks.php(134): Livewire\\Wrapped->__call('mount', Array)
#7 /var/www/app/vendor/livewire/livewire/src/Features/SupportLifecycleHooks/SupportLifecycleHooks.php(20): Livewire\\Features\\SupportLifecycleHooks\\SupportLifecycleHooks->callHook('mount', Array)
#8 /var/www/app/vendor/livewire/livewire/src/ComponentHook.php(19): Livewire\\Features\\SupportLifecycleHooks\\SupportLifecycleHooks->mount(Array, NULL)
#9 /var/www/app/vendor/livewire/livewire/src/ComponentHookRegistry.php(45): Livewire\\ComponentHook->callMount(Array, NULL)
#10 /var/www/app/vendor/livewire/livewire/src/EventBus.php(60): Livewire\\ComponentHookRegistry::{closure:Livewire\\ComponentHookRegistry::boot():39}(Object(App\\Filament\\Resources\\DriverResource\\Pages\\DriverStatistics), Array, NULL, NULL)
#11 /var/www/app/vendor/livewire/livewire/src/helpers.php(98): Livewire\\EventBus->trigger('mount', Object(App\\Filament\\Resources\\DriverResource\\Pages\\DriverStatistics), Array, NULL, NULL)
#12 /var/www/app/vendor/filament/filament/src/Widgets/Concerns/InteractsWithPageTable.php(79): Livewire\\trigger('mount', Object(App\\Filament\\Resources\\DriverResource\\Pages\\DriverStatistics), Array, NULL, NULL)
#13 /var/www/app/vendor/filament/filament/src/Widgets/Concerns/InteractsWithPageTable.php(97): App\\Filament\\Resources\\DriverResource\\Widgets\\DriverStatistics->getTablePageInstance()
#14 /var/www/app/app/Filament/Resources/DriverResource/Widgets/DriverStatistics.php(34): App\\Filament\\Resources\\DriverResource\\Widgets\\DriverStatistics->getPageTableQuery()
#6 /var/www/app/vendor/livewire/livewire/src/Features/SupportLifecycleHooks/SupportLifecycleHooks.php(134): Livewire\\Wrapped->__call('mount', Array)
#7 /var/www/app/vendor/livewire/livewire/src/Features/SupportLifecycleHooks/SupportLifecycleHooks.php(20): Livewire\\Features\\SupportLifecycleHooks\\SupportLifecycleHooks->callHook('mount', Array)
#8 /var/www/app/vendor/livewire/livewire/src/ComponentHook.php(19): Livewire\\Features\\SupportLifecycleHooks\\SupportLifecycleHooks->mount(Array, NULL)
#9 /var/www/app/vendor/livewire/livewire/src/ComponentHookRegistry.php(45): Livewire\\ComponentHook->callMount(Array, NULL)
#10 /var/www/app/vendor/livewire/livewire/src/EventBus.php(60): Livewire\\ComponentHookRegistry::{closure:Livewire\\ComponentHookRegistry::boot():39}(Object(App\\Filament\\Resources\\DriverResource\\Pages\\DriverStatistics), Array, NULL, NULL)
#11 /var/www/app/vendor/livewire/livewire/src/helpers.php(98): Livewire\\EventBus->trigger('mount', Object(App\\Filament\\Resources\\DriverResource\\Pages\\DriverStatistics), Array, NULL, NULL)
#12 /var/www/app/vendor/filament/filament/src/Widgets/Concerns/InteractsWithPageTable.php(79): Livewire\\trigger('mount', Object(App\\Filament\\Resources\\DriverResource\\Pages\\DriverStatistics), Array, NULL, NULL)
#13 /var/www/app/vendor/filament/filament/src/Widgets/Concerns/InteractsWithPageTable.php(97): App\\Filament\\Resources\\DriverResource\\Widgets\\DriverStatistics->getTablePageInstance()
#14 /var/www/app/app/Filament/Resources/DriverResource/Widgets/DriverStatistics.php(34): App\\Filament\\Resources\\DriverResource\\Widgets\\DriverStatistics->getPageTableQuery()

Did you find this page helpful?