The Power of Filament Actions & Widgets
I'm going to show you how to do this all while using Filament Widgets and Actions... using the Admin Panel
I will be using the Table Widgets here as an example but any other widgets should work in a similar fashion.
php artisan make:filament-page ChartOfAccounts
<?php namespace App\Filament\Pages; use Filament\Pages\Page; class ChartOfAccounts extends Page{ protected static ?string $navigationIcon = 'heroicon-o-home'; protected static ?int $navigationSort = -1; protected static string $view = 'filament.pages.chart-of-accounts';}
Create a New Folder called "Widgets" at App\Filament\Pages\{Widgets Folder}:
Inside the "Widgets" Folder create a new File as such... (Mine is called Assets.php):
<?php namespace App\Filament\Pages\Widgets; use App\Models\Asset;use Filament\Tables;use Filament\Forms;use App\Models\Company;use App\Models\Department;use Filament\Widgets\TableWidget as PageWidget;use Illuminate\Database\Eloquent\Builder; class Assets extends PageWidget{ protected int | string | array $columnSpan = [ 'md' => 2, 'xl' => 3, ]; protected function getTableQuery(): Builder { return Asset::query(); } protected function getTableColumns(): array { return [ Tables\Columns\TextColumn::make('company.name', 'name')->hidden(), Tables\Columns\TextColumn::make('department.name', 'name')->hidden(), Tables\Columns\TextColumn::make('code'), Tables\Columns\TextColumn::make('name'), Tables\Columns\TextColumn::make('type'), Tables\Columns\TextColumn::make('description')->hidden(), Tables\Columns\TextColumn::make('expense_transactions_sum_amount')->sum('expense_transactions', 'amount')->money('USD', 2)->label('Amount'), ]; } protected function getTableActions(): array { return [ Tables\Actions\ViewAction::make() ->form([ Forms\Components\Select::make('company_id') ->label('Company') ->options(Company::all()->pluck('name', 'id')->toArray()) ->reactive() ->afterStateUpdated(fn (callable $set) => $set('department_id', null)), Forms\Components\Select::make('department_id') ->label('Department') ->options(function (callable $get) { $company = Company::find($get('company_id')); if (! $company) { return Department::all()->pluck('name', 'id'); } return $company->departments->pluck('name', 'id'); }), Forms\Components\TextInput::make('code') ->required(), Forms\Components\TextInput::make('name') ->required() ->maxLength(255), Forms\Components\Select::make('type') ->required() ->options([ 'Current Asset' => 'Current Asset', 'Fixed Asset' => 'Fixed Asset', 'Tangible Asset' => 'Tangible Asset', 'Intangible Asset' => 'Intangible Asset', 'Operating Asset' => 'Operating Asset', 'Non-Operating Asset' => 'Non-Operating Asset', ]), Forms\Components\TextInput::make('description') ->maxLength(255), ]), Tables\Actions\EditAction::make() ->form([ Forms\Components\Select::make('company_id') ->label('Company') ->options(Company::all()->pluck('name', 'id')->toArray()) ->reactive() ->afterStateUpdated(fn (callable $set) => $set('department_id', null)), Forms\Components\Select::make('department_id') ->label('Department') ->options(function (callable $get) { $company = Company::find($get('company_id')); if (! $company) { return Department::all()->pluck('name', 'id'); } return $company->departments->pluck('name', 'id'); }), Forms\Components\TextInput::make('code') ->required(), Forms\Components\TextInput::make('name') ->required() ->maxLength(255), Forms\Components\Select::make('type') ->required() ->options([ 'Current Asset' => 'Current Asset', 'Fixed Asset' => 'Fixed Asset', 'Tangible Asset' => 'Tangible Asset', 'Intangible Asset' => 'Intangible Asset', 'Operating Asset' => 'Operating Asset', 'Non-Operating Asset' => 'Non-Operating Asset', ]), Forms\Components\TextInput::make('description') ->maxLength(255), ]) ]; } protected function isTablePaginationEnabled(): bool { return false; } protected function getTableHeaderActions(): array { return [ Tables\Actions\CreateAction::make() ->form([ Forms\Components\Select::make('company_id') ->label('Company') ->options(Company::all()->pluck('name', 'id')->toArray()) ->reactive() ->afterStateUpdated(fn (callable $set) => $set('department_id', null)), Forms\Components\Select::make('department_id') ->label('Department') ->options(function (callable $get) { $company = Company::find($get('company_id')); if (! $company) { return Department::all()->pluck('name', 'id'); } return $company->departments->pluck('name', 'id'); }), Forms\Components\TextInput::make('code') ->required(), Forms\Components\TextInput::make('name') ->required() ->maxLength(255), Forms\Components\Select::make('type') ->required() ->options([ 'Current Asset' => 'Current Asset', 'Fixed Asset' => 'Fixed Asset', 'Tangible Asset' => 'Tangible Asset', 'Intangible Asset' => 'Intangible Asset', 'Operating Asset' => 'Operating Asset', 'Non-Operating Asset' => 'Non-Operating Asset', ]), Forms\Components\TextInput::make('description') ->maxLength(255), ]) ]; } }
<?php namespace App\Filament\Pages\Widgets; use App\Models\Revenue;use Filament\Tables;use Filament\Forms;use App\Models\Company;use App\Models\Department;use Filament\Widgets\TableWidget as PageWidget;use Illuminate\Database\Eloquent\Builder; class Revenues extends PageWidget{ protected int | string | array $columnSpan = [ 'md' => 2, 'xl' => 3, ]; protected function getTableQuery(): Builder { return Revenue::query(); } protected function getTableColumns(): array { return [ Tables\Columns\TextColumn::make('company.name', 'name')->hidden(), Tables\Columns\TextColumn::make('department.name', 'name')->hidden(), Tables\Columns\TextColumn::make('code'), Tables\Columns\TextColumn::make('name'), Tables\Columns\TextColumn::make('type'), Tables\Columns\TextColumn::make('description')->hidden(), Tables\Columns\TextColumn::make('income_transactions_sum_amount')->sum('income_transactions', 'amount')->money('USD', 2)->label('Amount'), ]; } protected function getTableActions(): array { return [ Tables\Actions\ViewAction::make() ->form([ Forms\Components\Select::make('company_id') ->label('Company') ->options(Company::all()->pluck('name', 'id')->toArray()) ->reactive() ->afterStateUpdated(fn (callable $set) => $set('department_id', null)), Forms\Components\Select::make('department_id') ->label('Department') ->options(function (callable $get) { $company = Company::find($get('company_id')); if (! $company) { return Department::all()->pluck('name', 'id'); } return $company->departments->pluck('name', 'id'); }), Forms\Components\TextInput::make('code') ->required(), Forms\Components\TextInput::make('name') ->required() ->maxLength(255), Forms\Components\Select::make('type') ->required() ->options([ 'Revenue' => 'Revenue', ]), Forms\Components\TextInput::make('description') ->maxLength(255), ]), Tables\Actions\EditAction::make() ->form([ Forms\Components\Select::make('company_id') ->label('Company') ->options(Company::all()->pluck('name', 'id')->toArray()) ->reactive() ->afterStateUpdated(fn (callable $set) => $set('department_id', null)), Forms\Components\Select::make('department_id') ->label('Department') ->options(function (callable $get) { $company = Company::find($get('company_id')); if (! $company) { return Department::all()->pluck('name', 'id'); } return $company->departments->pluck('name', 'id'); }), Forms\Components\TextInput::make('code') ->required(), Forms\Components\TextInput::make('name') ->required() ->maxLength(255), Forms\Components\Select::make('type') ->required() ->options([ 'Revenue' => 'Revenue', ]), Forms\Components\TextInput::make('description') ->maxLength(255), ]) ]; } protected function isTablePaginationEnabled(): bool { return false; } protected function getTableHeaderActions(): array { return [ Tables\Actions\CreateAction::make() ->form([ Forms\Components\Select::make('company_id') ->label('Company') ->options(Company::all()->pluck('name', 'id')->toArray()) ->reactive() ->afterStateUpdated(fn (callable $set) => $set('department_id', null)), Forms\Components\Select::make('department_id') ->label('Department') ->options(function (callable $get) { $company = Company::find($get('company_id')); if (! $company) { return Department::all()->pluck('name', 'id'); } return $company->departments->pluck('name', 'id'); }), Forms\Components\TextInput::make('code') ->required(), Forms\Components\TextInput::make('name') ->required() ->maxLength(255), Forms\Components\Select::make('type') ->required() ->options([ 'Revenue' => 'Revenue', ]), Forms\Components\TextInput::make('description') ->maxLength(255), ]) ]; } }
<?php namespace App\Filament\Pages; use Filament\Pages\Page;use App\Filament\Pages\Widgets; class ChartOfAccounts extends Page{ protected static ?string $navigationIcon = 'heroicon-o-home'; protected static ?int $navigationSort = -1; protected static string $view = 'filament.pages.chart-of-accounts'; protected function getHeaderWidgets(): array { return [ Widgets\Assets::class, <-- 1st Widgets\Liabilities::class, <-- 2nd Widgets\Expenses::class, <-- 3rd Widgets\Revenues::class, <-- 4th Widgets\Equities::class, <-- 5th ]; } }
That's all, hope you find this helpful.. pretty neat trick. It is especially helpful if some of your models relate to each other like mine did, and it also reduces the amount of space you take up in your project especially if you are going to have a lot of content in your Project..
Here is the source code to my gitrepo if that helps you... GithubRepo
No comments yet…