Flowforge is a powerful Kanban board package for Laravel Filament 3 that works seamlessly with your existing Eloquent models. This package allows you to transform any model into a Kanban board with minimal configuration, without requiring additional database tables.
This guide will help you set up a Kanban board for your Laravel application in just a few minutes.
composer require relaticle/flowforge
For a basic Kanban board, your model needs:
title
or name
)status
or state
)order_column
) - required for drag & drop functionalityExample migration:
Schema::create('tasks', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('description')->nullable(); $table->string('status')->default('todo'); $table->integer('order_column')->nullable(); $table->timestamps();});
Use the provided command to create a basic board:
php artisan flowforge:make-board TasksBoard --model=Task
The command will only ask for:
This command will:
Add your new page to Filament's navigation:
// In app/Providers/Filament/AdminPanelProvider.php public function panel(Panel $panel): Panel{ return $panel // ... other configuration ->pages([ // ... other pages App\Filament\Pages\TasksBoardPage::class, ]);}
Go to your Filament admin panel and you should see your new Kanban board in the navigation!
The generated board is intentionally minimal - it gives you a working read-only board to start with. When you're ready to add interactive features, you can manually add the createAction()
and editAction()
methods following the examples in the Optional Methods section.
Flowforge offers several powerful features out of the box:
For your Kanban board to be fully functional, your model should have:
title
, name
)status
, state
)description
, content
) - optionalorder_column
, sort_order
) - required for drag & drop functionalityFor drag and drop ordering to work, you can either:
For a functional Kanban board, you only need to implement two methods:
public function getSubject(): Builder{ return Task::query();}
public function mount(): void{ $this ->titleField('title'); // Required: Field used for card titles ->columnField('status') // Required: Field that determines column placement ->columns([ // Required: Define your columns 'todo' => 'To Do', 'in_progress' => 'In Progress', 'completed' => 'Completed', ])}
Here's a complete example of a minimal read-only board:
<?php namespace App\Filament\Pages; use App\Models\Task;use Illuminate\Database\Eloquent\Builder;use Relaticle\Flowforge\Filament\Pages\KanbanBoardPage; class TasksBoardPage extends KanbanBoardPage{ protected static ?string $navigationIcon = 'heroicon-o-view-columns'; public function getSubject(): Builder { return Task::query(); } public function mount(): void { $this ->titleField('title'); ->columnField('status') ->columns([ 'todo' => 'To Do', 'in_progress' => 'In Progress', 'completed' => 'Completed', ]) }}
These methods are completely optional and only needed if you want specific functionality:
If you want users to be able to add new cards to the board, implement this method:
use Filament\Actions\Action;use Filament\Forms; public function createAction(Action $action): Action{ return $action ->iconButton() ->icon('heroicon-o-plus') ->modalHeading('Create Task') ->modalWidth('xl') ->form(function (Forms\Form $form) { return $form->schema([ Forms\Components\TextInput::make('title') ->required() ->placeholder('Enter task title') ->columnSpanFull(), Forms\Components\Textarea::make('description') ->columnSpanFull(), // Add more form fields as needed ]); });}
Note: If this method is not implemented, no "+" button will appear in column headers and users won't be able to create new cards.
If you want users to be able to edit existing cards, implement this method:
use Filament\Actions\Action;use Filament\Forms; public function editAction(Action $action): Action{ return $action ->modalHeading('Edit Task') ->modalWidth('xl') ->form(function (Forms\Form $form) { return $form->schema([ Forms\Components\TextInput::make('title') ->required() ->placeholder('Enter task title') ->columnSpanFull(), Forms\Components\Textarea::make('description') ->columnSpanFull(), Forms\Components\Select::make('status') ->options([ 'todo' => 'To Do', 'in_progress' => 'In Progress', 'completed' => 'Completed', ]) ->required(), // Add more form fields as needed ]); });}
Note: If this method is not implemented, cards will be read-only and users won't be able to edit them.
These settings enhance your board but are not required:
descriptionField(string)
: Field used for card descriptionsorderField(string)
: Field used to maintain card order (required for drag & drop)columnColors(array)
: Key-value pairs defining colors for each columncardLabel(string)
: Custom label for cards (defaults to model name)pluralCardLabel(string)
: Custom plural label for cardscardAttributes(array)
: Additional model attributes to display on cardscardAttributeColors(array)
: Key-value pairs defining colors for each card attributecardAttributeIcons(array)
: Key-value pairs defining icons for each card attributeinitialCardsCount(int)
: Number of cards initially loaded per column (default: 10)cardsIncrement(int)
: Number of cards to load when clicking "load more" (default: 5)Example with optional configuration:
public function mount(): void{ $this // Required configuration ->columnField('status') ->columns([ 'todo' => 'To Do', 'in_progress' => 'In Progress', 'completed' => 'Completed', ]) ->titleField('title') // Optional configuration ->descriptionField('description') ->orderField('order_column') ->columnColors([ 'todo' => 'blue', 'in_progress' => 'yellow', 'completed' => 'green', ]) ->cardLabel('Task') ->pluralCardLabel('Tasks') ->cardAttributes([ 'due_date' => 'Due Date', 'assignee.name' => 'Assigned To', ]) ->cardAttributeColors([ 'due_date' => 'red', 'assignee.name' => 'yellow', ]) ->cardAttributeIcons([ 'due_date' => 'heroicon-o-calendar', 'assignee.name' => 'heroicon-o-user', ]) ->initialCardsCount(15) ->cardsIncrement(10);}
Flowforge uses Tailwind CSS color classes for column styling. The available color options are:
white
slate
gray
zinc
neutral
stone
red
orange
amber
yellow
lime
green
emerald
teal
cyan
sky
blue
indigo
violet
purple
fuchsia
pink
rose
If you don't specify colors, they will be automatically assigned from this palette in a rotating manner.
For complex scenarios (like integration with custom fields), you can create a custom adapter by implementing KanbanAdapterInterface
or extending DefaultKanbanAdapter
. This is an advanced feature and only needed for special cases.
Issue: You can see cards but can't drag them between columns or reorder them.
Solution:
order_column
)orderField('order_column')
in your mount()
methodIssue: Your board appears empty or has fewer columns than expected.
Solution:
columnField()
matches a real field in your databasedd($this->getSubject()->get())
in your page class to debug your model dataIssue: Form submissions fail with validation errors.
Solution:
Issue: No create/edit options appear.
Solution:
createAction()
and/or editAction()
methodsIssue: Cards can be dragged but don't stay in place after reload.
Solution:
orderField()
method is set in your configurationIf you're still experiencing issues, try these steps:
Contributions are welcome! Please feel free to submit a Pull Request.
The MIT License (MIT). Please see License File for more information.