invaders-xx/filament-kanban-board
## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require invaders-xx/filament-kanban-board
php artisan vendor:publish --tag="filament-kanban-board-config"
AppServiceProvider or a dedicated service provider:
use InvadersXx\FilamentKanbanBoard\FilamentKanbanBoardPlugin;
public function boot(): void
{
FilamentKanbanBoardPlugin::make()
->register();
}
KanbanPage:
use InvadersXx\FilamentKanbanBoard\Pages\KanbanPage;
class MyKanbanPage extends KanbanPage
{
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static string $navigationGroup = 'Tasks';
public static function getColumns(): array
{
return [
'Backlog',
'In Progress',
'Review',
'Done',
];
}
public static function getCards(): array
{
return [
[
'id' => 1,
'title' => 'Task 1',
'column' => 'Backlog',
'description' => 'Description for Task 1',
],
// Add more cards...
];
}
}
filament.php under pages:
'pages' => [
\App\Filament\Pages\MyKanbanPage::class,
],
Quick Task Management:
Use the Kanban board to visualize and manage tasks for a sprint or project. Start by defining columns (e.g., To Do, In Progress, Done) and populate them with cards representing tasks. Drag-and-drop cards between columns to update their status.
Dynamic Data Fetching:
Override getCards() to fetch data dynamically from your database or API:
public static function getCards(): array
{
return Task::query()
->select('id', 'title', 'description', 'status')
->get()
->map(fn ($task) => [
'id' => $task->id,
'title' => $task->title,
'column' => $task->status,
'description' => $task->description,
])
->toArray();
}
Custom Card Rendering:
Extend card rendering by overriding getCardView():
public function getCardView(): string
{
return view('filament-kanban-board::card', [
'card' => $this->card,
]);
}
Customize the blade template in resources/views/filament-kanban-board.
Column Customization: Define column-specific configurations:
public static function getColumns(): array
{
return [
[
'name' => 'Backlog',
'color' => 'gray-100',
'width' => 25,
],
// Other columns...
];
}
Integration with Filament Resources: Attach the Kanban board to a Filament resource:
use InvadersXx\FilamentKanbanBoard\Resources\Concerns\HasKanbanBoard;
class TaskResource extends Resource
{
public static function getPages(): array
{
return [
'index' => Pages\ListTasks::route('/'),
'kanban' => Pages\KanbanTasks::route('/kanban'),
];
}
}
class KanbanTasks extends KanbanPage
{
use HasKanbanBoard;
protected static string $resource = TaskResource::class;
}
Real-Time Updates: Use Laravel Echo and Pusher to update the Kanban board in real-time:
// In your KanbanPage
public function updatedCard($cardId, $column)
{
Task::find($cardId)->update(['status' => $column]);
// Broadcast update if needed
}
Nested Cards: Implement nested cards for subtasks:
public static function getCards(): array
{
return Task::with('subtasks')->get()->map(fn ($task) => [
'id' => $task->id,
'title' => $task->title,
'column' => $task->status,
'subtasks' => $task->subtasks->map(fn ($subtask) => [
'id' => $subtask->id,
'title' => $subtask->title,
]),
]);
}
Customize the card view to render nested items.
Permissions and Access Control: Restrict access to specific columns or cards:
public function getColumns(): array
{
$columns = parent::getColumns();
if (!auth()->user()->can('view_all_columns')) {
unset($columns[2]); // Hide 'Review' column
}
return $columns;
}
Export Functionality: Add export buttons to CSV/JSON:
public function getHeaderActions(): array
{
return [
Action::make('export')
->icon('heroicon-o-arrow-down-tray')
->action(fn () => $this->exportCards()),
];
}
protected function exportCards()
{
return response()->json($this->getCards());
}
Column Widths:
['width' => 20] for a narrower column.Card ID Conflicts:
getCards().Performance with Large Datasets:
public static function getCards(): array
{
return Task::paginate(20)->items()->toArray();
}
load() to eager-load relationships.Caching:
getCards() result if data changes infrequently:
public static function getCards(): array
{
return Cache::remember('kanban_cards', now()->addHours(1), function () {
return Task::all()->toArray();
});
}
JavaScript Conflicts:
Check Console for Errors:
F12) to debug JavaScript errors, especially when dragging cards.Verify Data Structure:
getCards() returns an array of associative arrays with keys: id, title, column, and optionally description, color, etc.Clear Filament Cache:
php artisan filament:cache-reset
Inspect Network Requests:
Custom Styling:
// config/filament-kanban-board.php
'styles' => [
'card' => 'bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700',
'column' => 'bg-gray-50 dark:bg-gray-900',
],
Custom Actions:
public function getCardActions(): array
{
return [
Action::make('edit')
->icon('heroicon-o-pencil')
->url(fn ($card) => route('tasks.edit', $card['id'])),
];
}
Event Listeners:
event(new KanbanCardUpdated($cardId, $newColumn));
EventServiceProvider:
protected $listen = [
KanbanCardUpdated::class => [
TaskStatusUpdated::class,
],
];
Localization:
public static function getColumns(): array
{
return [
__('filament-kanban::columns.backlog'),
__('filament-kanban::columns.in_progress'),
];
}
php artisan vendor:publish --tag="filament-kanban-board-lang"
Testing:
How can I help you explore Laravel packages today?