All pages

advanced

Moves and queries

Take over what a move does, run code before and after it, and shape the queries behind the board.

Customise a move

Override handleRecordMove() on your Kanban page to replace the default update:

php
<?php

namespace App\Filament\Pages;

use App\Models\Task;
use Illuminate\Database\Eloquent\Model;

class TasksKanban extends KanbanPage
{
    public function handleRecordMove(string $newStatus, Model $record): void
    {
        // Update the record's status
        $record->update(['status' => $newStatus]);

        // Log the move
        activity()
            ->performedOn($record)
            ->log("Task moved to {$newStatus}");
    }
}

When reordering is enabled, the new position is already set on $record by the time this runs, so a single update() persists both.

Before a move

Throw from here to stop a move that shouldn't happen:

php
public function beforeRecordMove(string $newStatus, Model $record): void
{
    if ($newStatus === 'completed' && ! $record->all_subtasks_completed) {
        throw new \Exception('Cannot complete task: all subtasks must be finished');
    }

    \Log::info("Attempting to move task {$record->id} to {$newStatus}");
}

After a move

php
public function afterRecordMove(mixed $oldStatus, string $newStatus, Model $record): void
{
    if ($newStatus === 'completed') {
        $record->assignee->notify(new TaskCompletedNotification($record));

        $record->update(['completed_at' => now()]);
    }

    \Log::info("Task {$record->id} moved from {$oldStatus} to {$newStatus}");
}

Reorder hooks

A drag that only changes position runs beforeRecordReorder(), handleRecordReorder(), and afterRecordReorder() instead, so status side effects stay out of it. See card reordering.

Query modifications

The board query

php
use Asmit\AdvancedKanban\Kanban;

Kanban::make()
    ->modifyQueryUsing(function ($query) {
        return $query->where('is_active', true);
    });

A single column's query

php
use Asmit\AdvancedKanban\Columns\KanbanColumn;

KanbanColumn::make('todo')
    ->modifyRecordQueryUsing(function ($query) {
        return $query->where('status', 'to_do')->orderBy('created_at', 'asc');
    });