Adding a Kanban Board per Resource in Filament PHP
When I started building Vendex, a vendor and proposal management system, I envisioned a way to streamline the process of managing proposals. I wanted to allow the admin to visualize proposals submitted for a project in a Kanban board format. The goal? Make it easy to drag and drop proposals across various statuses and manage them with a few clicks.
Instead of starting from scratch, I decided to leverage the excellent Filament Kanban Plugin. This plugin provides a robust foundation for building Kanban boards in Filament PHP applications. However, one challenge arose: the plugin didn’t natively support adding a Kanban board per resource. For Vendex, every project had its own unique set of proposals, so I needed to extend the functionality.
Here’s how I solved this, step by step.
Creating a Custom Kanban Page
To create a Kanban board tied to a specific resource (in my case, projects), I extended the plugin’s KanbanBoard class by creating a custom Filament page:
class ProjectProposals extends KanbanBoard { protected static string $model = Proposal::class; protected static string $statusEnum = ProposalStatus::class; protected static bool $shouldRegisterNavigation = false; protected static string $view = 'filament.app.pages.proposals.kanban.kanban-board'; protected static string $headerView = 'filament.app.pages.proposals.kanban.kanban-header'; protected static string $recordView = 'filament.app.pages.proposals.kanban.kanban-record'; protected static string $statusView = 'filament.app.pages.proposals.kanban.kanban-status'; public bool $disableEditModal = true; public ?int $project_id = null; public Project $project; public Proposal $proposal; public function mount(): void { parent::mount(); $this->project = Project::where('id', $this->project_id)->firstOrFail(); } public function getTitle(): string | Htmlable { return 'Project : ' . $this->project->title; } }
Breaking It Down: Customizing the Mount Function
The mount method is one of the first things to understand. Its role is to prepare the page for rendering. Here’s the critical piece:
public function mount(): void { parent::mount(); $this->project = Project::where('id', $this->project_id)->firstOrFail(); }
At first glance, this snippet looks simple, but it’s crucial.
- parent::mount();: This ensures that any initialization logic in the parent KanbanBoard class is executed. Skipping this could break core functionality provided by the plugin.
- Fetching the project: I used the where clause to retrieve the project associated with the provided project_id. The firstOrFail() method ensures the system throws a 404 error if no matching project is found, which is a safe way to handle invalid project IDs.
- Why store the project? By storing the project in the $project variable, I could access its details throughout the class without repeatedly querying the database.
Displaying the Board Title Dynamically
To give the admin a clear context of what they’re managing, I dynamically set the board title based on the project name:
public function getTitle(): string | Htmlable { return 'Project : ' . $this->project->title; }
This line ensures that when the Kanban page is loaded, the admin sees a heading like "Project: New Office Construction" instead of a generic title.
Fetching Records for the Kanban Board
Every Kanban column needs data, and the records method is responsible for retrieving the proposals for a specific project:
protected function records(): Collection { return $this->project->proposals() ->with(['project', 'vendor', 'user']) ->ordered() ->get(); }
Handling Status Changes
Dragging a proposal from one status to another triggers the onStatusChanged method:
public function onStatusChanged(int $recordId, string $status, array $fromOrderedIds, array $toOrderedIds): void { $proposal = Proposal::find($recordId); $proposal->update(['status' => $status]); Proposal::setNewOrder($toOrderedIds); if ($status === ProposalStatus::Accepted->value) { $vendor = Vendor::find($proposal->vendor->id); Mail::to($vendor)->send(new ProposalAccepted($vendor, $proposal)); Notification::make() ->title('Mail Sent To Vendor successfully') ->success() ->send(); } Notification::make() ->title('Status Changed successfully') ->success() ->send(); }
What Happens Here?
- Status Update: When a proposal’s status changes (e.g., from Pending to Accepted), it updates the status field in the database.
- Reordering Records: The new order of proposals in the target column is saved using setNewOrder().
- Sending Notifications: If the status is set to Accepted, the system sends an email to the vendor and notifies the admin of the successful action.
Adding Routes
To make the page accessible, I added a custom route in web.php:
Route::name('filament.') ->group(function () { foreach (Filament::getPanels() as $panel) { Route::get('/project/{project_id}/proposals', ProjectProposals::class) ->name('project.proposals'); } });
This route dynamically passes the project_id to the ProjectProposals page, ensuring each project has its own unique Kanban board.
Customizing Views
The Kanban plugin allows for highly customizable views. For Vendex, I created specific views for:
- Kanban Header: Displays project details.
- Kanban Record: Custom proposal cards.
- Kanban Status: Labels like Pending, Reviewed, Accepted.
These views were registered using properties like $headerView and $recordView.
Conclusion
By extending the Mokhosh Kanban plugin, I was able to integrate a dynamic, resource-specific Kanban board into Vendex. This approach not only saved development time but also provided a flexible way to manage proposals visually.
If you’re working on a similar Filament PHP project, consider checking out the Vendex to get started. With a little customization, the possibilities are endless!
Effortless Expiration Tracking for Busy Professionals
From invoices to contracts, get notified on time, every time, across email, SMS, and WhatsApp
Featured Products
Refdesk - Automated Reference Checking Software (SaaS)
Automated Reference Checking Software for modern organizations accelerates the hiring process by automating reference collection and verification, ensuring accurate and timely candidate assessments.
Buy for $69
CareCircle Manager
CareCircle Manager assists you in remembering, staying informed, organizing, and providing care to your community members.