F
Filament2mo ago
Zoltar

Best pratices for reporting page

HI, I would like to create a reporting page (tables, graphs etc) for my application. Reading the documentation I saw that I can use widgets. What is the best practice for creating a custom or resource page that uses both tables and widgets (StatsOverviewWidget or ChartWidget) sharing the same filters? Thanks always
Solution:
Thank you very much, as I imagined the problem was in the passage of the filters in the view. Your code gave me the solution ...
Jump to solution
22 Replies
toeknee
toeknee2mo ago
You can just create widgets and render them into a custom page? It depends if the widgets etc should all be dependant on the tablet, then a resource with graphs would be better. If you scope it better we can advise further.
Zoltar
ZoltarOP2mo ago
Simply, one page with: one table with filters one chart widget that depend from table filters one stats widget that depend from table fiters How do I retrieve the table filters in the widget?
toeknee
toeknee2mo ago
So build a standard page with a fitlerForm and inject those values into the queryies of each widget 🙂
Zoltar
ZoltarOP2mo ago
<?php

namespace App\Filament\Widgets;

use Filament\Tables;
use Filament\Tables\Table;
use Filament\Tables\Columns\TextColumn;

use Filament\Widgets\TableWidget as BaseWidget;

use Filament\Widgets\Concerns\InteractsWithPageFilters;

use Illuminate\Database\Eloquent\Builder;

use App\Models\Activity;

class ListUsersChart extends BaseWidget
{

use InteractsWithPageFilters;

public function table(Table $table): Table
{
$startDate = $this->filters['startDate'] ?? null;
$endDate = $this->filters['endDate'] ?? null;

return $table
->query(Activity::query()
->where('attiva','1') //Attive
->whereHas('pages') //Con Pagine
//->where('start_date', '>', $startDate)
//->withCount('user_activities')
->orderBy('data_inizio', 'asc')
->limit(5)
)
->columns([
TextColumn::make('titolo'),
]);
}
}
<?php

namespace App\Filament\Widgets;

use Filament\Tables;
use Filament\Tables\Table;
use Filament\Tables\Columns\TextColumn;

use Filament\Widgets\TableWidget as BaseWidget;

use Filament\Widgets\Concerns\InteractsWithPageFilters;

use Illuminate\Database\Eloquent\Builder;

use App\Models\Activity;

class ListUsersChart extends BaseWidget
{

use InteractsWithPageFilters;

public function table(Table $table): Table
{
$startDate = $this->filters['startDate'] ?? null;
$endDate = $this->filters['endDate'] ?? null;

return $table
->query(Activity::query()
->where('attiva','1') //Attive
->whereHas('pages') //Con Pagine
//->where('start_date', '>', $startDate)
//->withCount('user_activities')
->orderBy('data_inizio', 'asc')
->limit(5)
)
->columns([
TextColumn::make('titolo'),
]);
}
}
I create TableWidget and pass filtersForm but filter not read...can help me?
Zoltar
ZoltarOP2mo ago
filters are working ok
No description
toeknee
toeknee2mo ago
dd($this->filters); ?
toeknee
toeknee2mo ago
GitHub
How can I implement filtering for multiple widgets on a page? · fil...
I am trying to create a filter for multiple widgets. When the button is submitted, the HorizontalAlignmentColumnChart is hidden, and the filter popup on the chart cannot be clicked. There are some ...
Zoltar
ZoltarOP2mo ago
null
toeknee
toeknee2mo ago
Did you set the page Fitlers?
Zoltar
ZoltarOP2mo ago
the problem is much simpler..one filter for one widget Custom page with FilterForm
<?php

namespace App\Filament\Pages;

use Filament\Pages\Page;

use Filament\Forms\Form;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Section;

use Filament\Pages\Dashboard\Concerns\HasFiltersForm;

use App\Models\Activity;

class ReportActivities extends Page
{
use HasFiltersForm;

protected static ?int $navigationSort = 1;
protected static ?string $navigationIcon = 'heroicon-o-chart-bar';
protected static ?string $navigationLabel = 'Report';
protected static ?string $navigationGroup = 'Report';

protected static string $view = 'filament.pages.report-activities';

public function filtersForm(Form $form): Form
{
return $form
->schema([
Section::make()
->schema([
TextInput::make('test_filtro'),
])
->columns(3),
]);
}

}
<?php

namespace App\Filament\Pages;

use Filament\Pages\Page;

use Filament\Forms\Form;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Section;

use Filament\Pages\Dashboard\Concerns\HasFiltersForm;

use App\Models\Activity;

class ReportActivities extends Page
{
use HasFiltersForm;

protected static ?int $navigationSort = 1;
protected static ?string $navigationIcon = 'heroicon-o-chart-bar';
protected static ?string $navigationLabel = 'Report';
protected static ?string $navigationGroup = 'Report';

protected static string $view = 'filament.pages.report-activities';

public function filtersForm(Form $form): Form
{
return $form
->schema([
Section::make()
->schema([
TextInput::make('test_filtro'),
])
->columns(3),
]);
}

}
Relative view
<x-filament-panels::page>


{{ $this->filtersForm }}

@php
print_r($this->filters)
@endphp

@livewire(\App\Filament\Widgets\DemoWidget::class)

</x-filament-panels::page>
<x-filament-panels::page>


{{ $this->filtersForm }}

@php
print_r($this->filters)
@endphp

@livewire(\App\Filament\Widgets\DemoWidget::class)

</x-filament-panels::page>
Simple Widget
<?php
namespace App\Filament\Widgets;

use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;

use Filament\Widgets\Concerns\InteractsWithPageFilters;


class DemoWidget extends BaseWidget
{

use InteractsWithPageFilters;

protected function getStats(): array
{
$test_filtro = $this->filters['test_filtro'] ?? null;

return [
Stat::make('Test', $test_filtro)
->description('Test')
->descriptionIcon('heroicon-m-arrow-trending-up'),
];
}
}
<?php
namespace App\Filament\Widgets;

use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;

use Filament\Widgets\Concerns\InteractsWithPageFilters;


class DemoWidget extends BaseWidget
{

use InteractsWithPageFilters;

protected function getStats(): array
{
$test_filtro = $this->filters['test_filtro'] ?? null;

return [
Stat::make('Test', $test_filtro)
->description('Test')
->descriptionIcon('heroicon-m-arrow-trending-up'),
];
}
}
$this->filters is Widget is always null suggest? That's exactly what I'm looking at. the only difference is that the documentation uses BaseDashboard instead of Page
toeknee
toeknee2mo ago
So the that you get a full on DD means the field is defined. Make sure the filters are set to 'Live
return $form
->schema([
Section::make()
->schema([
TextInput::make('test_filtro')->live(debounce:500),
])
->columns(3),
]);
return $form
->schema([
Section::make()
->schema([
TextInput::make('test_filtro')->live(debounce:500),
])
->columns(3),
]);
Zoltar
ZoltarOP2mo ago
the filter is correctly on live print_r($this->filters) in view blade print the correct value of filter but when pass to widget it return null
No description
toeknee
toeknee2mo ago
what version of filament are you on?
Zoltar
ZoltarOP2mo ago
latest trying to update
toeknee
toeknee2mo ago
php artisan about
Zoltar
ZoltarOP2mo ago
3.2.121
toeknee
toeknee2mo ago
I am struggling to see why they would be empty, we inject them for a reason by using the trait :/
Zoltar
ZoltarOP2mo ago
that's right, the only difference is that I use a page instead of a dashboard i try to use dashboard instead of page...and NOT WORKING 😦 Ok find the problem...the problem...is the view blade
<?php

namespace App\Filament\Pages;

//use Filament\Pages\Page;
use Filament\Pages\Dashboard as BaseDashboard;

use Filament\Forms\Form;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Section;

use Filament\Pages\Dashboard\Concerns\HasFiltersForm;

use App\Models\Activity;

class ReportActivities extends BaseDashboard
{
use HasFiltersForm;

protected static string $routePath = 'finance';

protected static ?int $navigationSort = 1;
protected static ?string $navigationIcon = 'heroicon-o-chart-bar';
protected static ?string $navigationLabel = 'Report Attività - Dashboard';
protected static ?string $navigationGroup = 'Report';

//protected static string $view = 'filament.pages.report-activities';

public function filtersForm(Form $form): Form
{
return $form
->schema([
Section::make()
->schema([
TextInput::make('test_filtro'),
])
->columns(3),
]);
}

}
<?php

namespace App\Filament\Pages;

//use Filament\Pages\Page;
use Filament\Pages\Dashboard as BaseDashboard;

use Filament\Forms\Form;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Section;

use Filament\Pages\Dashboard\Concerns\HasFiltersForm;

use App\Models\Activity;

class ReportActivities extends BaseDashboard
{
use HasFiltersForm;

protected static string $routePath = 'finance';

protected static ?int $navigationSort = 1;
protected static ?string $navigationIcon = 'heroicon-o-chart-bar';
protected static ?string $navigationLabel = 'Report Attività - Dashboard';
protected static ?string $navigationGroup = 'Report';

//protected static string $view = 'filament.pages.report-activities';

public function filtersForm(Form $form): Form
{
return $form
->schema([
Section::make()
->schema([
TextInput::make('test_filtro'),
])
->columns(3),
]);
}

}
if i use dashboard without blade view its work...but it isnt my solution 😦
toeknee
toeknee2mo ago
Sooo that's easy then use a copy of the original blade view 😉
<x-filament-panels::page class="fi-dashboard-page">
@if (method_exists($this, 'filtersForm'))
{{ $this->filtersForm }}
@endif

<x-filament-widgets::widgets
:columns="$this->getColumns()"
:data="
[
...(property_exists($this, 'filters') ? ['filters' => $this->filters] : []),
...$this->getWidgetData(),
]
"
:widgets="$this->getVisibleWidgets()"
/>
</x-filament-panels::page>
<x-filament-panels::page class="fi-dashboard-page">
@if (method_exists($this, 'filtersForm'))
{{ $this->filtersForm }}
@endif

<x-filament-widgets::widgets
:columns="$this->getColumns()"
:data="
[
...(property_exists($this, 'filters') ? ['filters' => $this->filters] : []),
...$this->getWidgetData(),
]
"
:widgets="$this->getVisibleWidgets()"
/>
</x-filament-panels::page>
Solution
Zoltar
Zoltar2mo ago
Thank you very much, as I imagined the problem was in the passage of the filters in the view. Your code gave me the solution this is my custom view
<x-filament-panels::page>

@if (method_exists($this, 'filtersForm'))
{{ $this->filtersForm }}
@endif

@livewire(\App\Filament\Widgets\DemoWidget::class, (property_exists($this, 'filters') ? ['filters' => $this->filters] : []))

</x-filament-panels::page>
<x-filament-panels::page>

@if (method_exists($this, 'filtersForm'))
{{ $this->filtersForm }}
@endif

@livewire(\App\Filament\Widgets\DemoWidget::class, (property_exists($this, 'filters') ? ['filters' => $this->filters] : []))

</x-filament-panels::page>
Want results from more Discord servers?
Add your server