Saltar al contenido
Filament Kanban Board
code

Detalles del ejemplo

Filament Kanban Board

Tablero Kanban interactivo con drag & drop para Filament. Columnas basadas en enums, reordenamiento con SortableJS (bundleado via esbuild), vistas publicables y personalizables, soporte para adjuntos (imágenes y archivos), quick add, y acciones de edición/eliminación con modales Filament.

Arquitectura

Este paquete sigue un diseño abstracto/headless: proporciona toda la lógica del tablero kanban (drag & drop, reordenamiento, CRUD, adjuntos), pero tú defines qué modelo, qué estados y qué formulario usar.

El paquete proporciona:

  • KanbanBoard — Página abstracta con toda la lógica del tablero
  • KanbanAttachment — Modelo polimórfico para adjuntos
  • HasKanbanAttachments — Trait para habilitar adjuntos en tu modelo
  • KanbanPlugin — Plugin de Filament para registrar las páginas
  • Vistas Blade publicables, CSS, traducciones (es/en) y configuración

Tú defines:

  • Tu modelo Eloquent (ej. Task, Ticket, Order...)
  • Tu enum de estados (las columnas del tablero)
  • Tu formulario de edición/creación (campos Filament)

Solo necesitas implementar 3 métodos abstractos:

getModel()          // → Tu modelo Eloquent
getStatusEnum()     // → Tu enum de columnas
getEditFormSchema() // → Tus campos de formulario

El paquete accede a los datos de tu modelo de forma dinámica mediante atributos configurables (getTitleAttribute(), getStatusAttribute(), etc.), lo que permite usar cualquier modelo sin importar cómo se llamen sus campos.

Instalación

composer require cursosdesarrolloweb/filament-kanban

Publica las migraciones (solo si usas adjuntos):

php artisan vendor:publish --tag="filament-kanban-migrations"
php artisan migrate

Publica la configuración (opcional):

php artisan vendor:publish --tag="filament-kanban-config"

Uso

1. Crea un enum de estados

Cada caso del enum representa una columna del tablero. Debe ser un BackedEnum con valores string e implementar HasLabel:

use Filament\Support\Contracts\HasLabel;

enum TaskStatus: string implements HasLabel
{
    case Pending = 'pending';
    case InProgress = 'in_progress';
    case Done = 'done';

    public function getLabel(): string
    {
        return match ($this) {
            self::Pending => 'Pendiente',
            self::InProgress => 'En progreso',
            self::Done => 'Hecho',
        };
    }
}

2. Crea tu modelo y migración

El paquete no incluye un modelo propio para las tarjetas — tú creas el tuyo. Esto permite que uses cualquier modelo (Task, Ticket, Order, Lead...) con los campos que tu proyecto necesite.

Como mínimo, tu modelo necesita 3 campos (los nombres son configurables):

  • Un campo de título (por defecto title)
  • Un campo de estado (por defecto status) — corresponde a las columnas del tablero
  • Un campo de orden (por defecto sort_order) — para el ordenamiento dentro de cada columna

Crea la migración

php artisan make:migration create_tasks_table
Schema::create('tasks', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('description')->nullable();
    $table->string('status')->default('pending');
    $table->integer('sort_order')->default(0);
    // Añade aquí los campos extra que necesites:
    // $table->string('priority')->nullable();
    // $table->date('due_date')->nullable();
    // $table->foreignId('user_id')->nullable()->constrained();
    $table->timestamps();
});

Crea el modelo

php artisan make:model Task
namespace App\Models;

use App\Enums\TaskStatus;
use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    protected $fillable = [
        'title',
        'description',
        'status',
        'sort_order',
        // Añade aquí todos los campos que sean fillable
    ];

    protected function casts(): array
    {
        return [
            'status' => TaskStatus::class,
            'sort_order' => 'integer',
        ];
    }
}

Importante: Todos los campos que uses en el formulario (getEditFormSchema()) deben estar en $fillable, o el modelo no los guardará.

Nombres de campo personalizados

Si tu modelo usa nombres distintos a los valores por defecto (ej. name en vez de title), sobrescribe los métodos correspondientes en tu página Kanban:

protected function getTitleAttribute(): string
{
    return 'name'; // default: 'title'
}

protected function getStatusAttribute(): string
{
    return 'state'; // default: 'status'
}

protected function getSortAttribute(): string
{
    return 'position'; // default: 'sort_order'
}

3. Crea tu página Kanban

Extiende KanbanBoard e implementa los 3 métodos abstractos:

use CursosDesarrolloWeb\Kanban\Pages\KanbanBoard;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;

class MyKanban extends KanbanBoard
{
    protected static ?string $navigationLabel = 'Mi Kanban';

    protected function getModel(): string
    {
        return Task::class;
    }

    protected function getStatusEnum(): string
    {
        return TaskStatus::class;
    }

    protected function getEditFormSchema(): array
    {
        return [
            TextInput::make('title')
                ->label('Título')
                ->required()
                ->maxLength(255),
            Select::make('status')
                ->label('Estado')
                ->options(TaskStatus::class)
                ->required(),
        ];
    }
}

4. Registra el plugin en tu panel

use CursosDesarrolloWeb\Kanban\KanbanPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            KanbanPlugin::make(),
        ]);
}

Si tu panel usa discoverPages() (que es lo habitual), tu página Kanban se registrará automáticamente y no necesitas hacer nada más.

Si tu página Kanban no está en la carpeta autodescubierta (ej. está en otro namespace o módulo), pásala explícitamente al plugin:

KanbanPlugin::make()
    ->pages([MyKanban::class]),

Personalización

Todos los métodos de personalización se sobrescriben en tu página Kanban (la clase que extiende KanbanBoard):

class MyKanban extends KanbanBoard
{
    // Aquí van todos los métodos de personalización
}

Para personalización visual (colores, tamaños, espaciado...), consulta la sección Personalización CSS donde se documentan todas las clases fi-kanban-* que puedes sobrescribir.

Vistas publicables

El paquete divide su interfaz en 6 vistas independientes que puedes publicar y personalizar:

views/
├── pages/
│   └── kanban-board.blade.php   ← Board completo (orquesta columnas)
├── column.blade.php             ← Columna (header + cards + quick-add)
├── column-header.blade.php      ← Cabecera (label, contador, botón +)
├── card.blade.php               ← Tarjeta (topbar, contenido, detalles, adjuntos)
├── quick-add.blade.php          ← Input inline para añadir rápido
└── attachment-list.blade.php    ← Listado de adjuntos en el modal de edición

Publicar todas las vistas

php artisan vendor:publish --tag="filament-kanban-views"

Esto copia las vistas a resources/views/vendor/filament-kanban/. Cualquier cambio se aplica a todos los boards de tu aplicación.

Personalizar por board

Si quieres que un board específico use una vista distinta sin afectar al resto, sobrescribe el método correspondiente en tu clase:

Método Default Controla
getColumnView() filament-kanban::column La columna completa
getColumnHeaderView() filament-kanban::column-header La cabecera de columna
getCardView() filament-kanban::card La tarjeta
getQuickAddView() filament-kanban::quick-add El input de añadido rápido

Ejemplo: card personalizada para un Sales Pipeline

Crea tu vista en resources/views/kanban/sales-card.blade.php:

@props([
    'record',
    'canReorder' => false,
    'canEdit' => false,
    'canDelete' => false,
    'priorityAttr' => null,
    'titleAttr' => 'title',
    'details' => [],
    'hasAttachments' => false,
    'imageUrl' => null,
    'attachCount' => 0,
])

@php
    $stage = $record->stage;
    $dealValue = $record->deal_value ?? 0;
    $percentage = min(100, round(($dealValue / 200000) * 100));
    $color = match($stage->value) {
        'new' => '#38bdf8',
        'qualified' => '#fbbf24',
        'won' => '#34d399',
        default => '#6366f1',
    };
@endphp

{{-- Top bar (mantén el drag handle y botones del paquete) --}}
<div class="fi-kanban-card-topbar">
    @if ($canReorder)
        <div class="fi-kanban-drag-handle">
            <x-filament::icon icon="heroicon-m-bars-2" style="width: 0.875rem; height: 0.875rem;" />
        </div>
    @endif
    @if ($canEdit || $canDelete)
        <div style="display: flex; align-items: center;">
            @if ($canEdit)
                <button type="button"
                    x-on:click.stop="$wire.mountAction('editRecord', { record: '{{ $record->getKey() }}' })"
                    class="fi-kanban-edit-btn">
                    <x-filament::icon icon="heroicon-m-pencil-square" style="width: 0.875rem; height: 0.875rem;" />
                </button>
            @endif
            @if ($canDelete)
                <button type="button"
                    x-on:click.stop="$wire.mountAction('deleteQuickRecord', { record: '{{ $record->getKey() }}' })"
                    class="fi-kanban-delete-btn">
                    <x-filament::icon icon="heroicon-m-trash" style="width: 0.875rem; height: 0.875rem;" />
                </button>
            @endif
        </div>
    @endif
</div>

{{-- Tu contenido custom --}}
<div class="fi-kanban-card-content">
    <div style="display: flex; align-items: center; gap: 0.375rem;">
        <x-filament::icon :icon="$stage->getIcon()"
            style="width: 1rem; height: 1rem; color: {{ $color }};" />
        <p class="fi-kanban-card-title" style="margin: 0;">{{ $record->company }}</p>
    </div>

    @if ($dealValue > 0)
        <div style="margin-top: 0.5rem;">
            <span style="font-size: 1.125rem; font-weight: 700; color: {{ $color }};">
                ${{ number_format($dealValue, 0) }}
            </span>
            <div style="height: 4px; border-radius: 9999px; background: rgba(148,163,184,0.2); margin-top: 0.25rem;">
                <div style="height: 100%; width: {{ $percentage }}%; border-radius: 9999px; background: {{ $color }};"></div>
            </div>
        </div>
    @endif
</div>

Y apunta a ella desde tu board:

class SalesPipeline extends KanbanBoard
{
    protected function getCardView(): string
    {
        return 'kanban.sales-card';
    }

    // ... resto de tu configuración
}

Nota: La vista recibe todas las props que necesitas ($record, $canReorder, $canEdit, $canDelete, $details, etc.). Consulta la vista card.blade.php del paquete como referencia para ver todas las props disponibles.

Colores de columnas

Los colores usan valores CSS (hex, rgb, rgba), no clases Tailwind:

protected function getColumnColors(): array
{
    return [
        'pending' => 'rgba(0,0,0,0.04)',
        'in_progress' => 'rgba(251,191,36,0.08)',
        'done' => 'rgba(52,211,153,0.08)',
    ];
}

protected function getColumnHeaderColors(): array
{
    return [
        'pending' => '#9ca3af',
        'in_progress' => '#fbbf24',
        'done' => '#34d399',
    ];
}

Prioridad visual en cards

Activa la barra de prioridad indicando qué atributo del modelo la contiene:

protected function getPriorityAttribute(): ?string
{
    return 'priority'; // default: null (desactivado)
}

Los valores de prioridad por defecto son low, medium, high y critical, con colores definidos en CSS. Si tu modelo usa valores distintos, sobrescribe:

protected function getPriorityValues(): array
{
    return ['low', 'medium', 'high'];
}

Y añade los estilos correspondientes en tu CSS:

.fi-kanban-priority--low { background: rgb(209, 213, 219); }
.fi-kanban-priority--medium { background: rgb(56, 189, 248); }
.fi-kanban-priority--high { background: rgb(251, 191, 36); }

Detalles en las cards

Añade información extra debajo del título. Tipos soportados: badge, date, avatar, text.

protected function getCardDetails(Model $record): array
{
    $details = [];

    if ($record->assignee) {
        $details[] = ['type' => 'avatar', 'value' => $record->assignee];
    }

    if ($record->due_date) {
        // urgency: true activa estilos de "próximo" (2 días) y "vencido"
        $details[] = ['type' => 'date', 'value' => $record->due_date, 'urgency' => true];
    }

    if ($record->category) {
        $details[] = ['type' => 'badge', 'value' => $record->category];
    }

    $details[] = ['type' => 'text', 'value' => 'Nota adicional'];

    return $details;
}

Eager loading de relaciones

protected function getRecordEagerLoads(): array
{
    return ['assignee', 'project'];
}

Quick add (añadido rápido)

El quick add permite crear tarjetas directamente desde cada columna. Puedes asignar valores por defecto:

protected function getQuickAddDefaults(string $status): array
{
    return [
        'priority' => 'medium',
        'user_id' => auth()->id(),
    ];
}

Para desactivar el quick add:

protected function hasQuickAdd(): bool
{
    return false;
}

Hook de cambio de estado

Se ejecuta cuando una tarjeta se mueve a otra columna por drag & drop. Devuelve un array con datos extra para actualizar:

protected function onStatusChanged(Model $record, string $newStatus): array
{
    if ($newStatus === TaskStatus::InProgress->value && $record->started_at === null) {
        return ['started_at' => now()];
    }

    if ($newStatus === TaskStatus::Done->value) {
        return ['completed_at' => now()];
    }

    return ['completed_at' => null];
}

Autorización

Controla quién puede crear, editar, eliminar o reordenar tarjetas:

protected function canCreateRecord(): bool
{
    return auth()->user()->can('create', Task::class);
}

protected function canEditRecord(Model $record): bool
{
    return auth()->user()->can('update', $record);
}

protected function canDeleteRecord(Model $record): bool
{
    return auth()->user()->can('delete', $record);
}

protected function canReorderRecords(): bool
{
    return auth()->user()->can('reorder', Task::class);
}

Ancho de columnas y animación

protected function getColumnWidth(): string
{
    return '24rem'; // default: '20rem'
}

protected function getCardAnimation(): int
{
    return 200; // milisegundos, default: 150
}

Adjuntos

Activación

  1. Publica y ejecuta la migración:
php artisan vendor:publish --tag="filament-kanban-migrations"
php artisan migrate
  1. Añade el trait a tu modelo:
use CursosDesarrolloWeb\Kanban\Concerns\HasKanbanAttachments;

class Task extends Model
{
    use HasKanbanAttachments;
}
  1. Activa los adjuntos en tu página (o en la configuración):
protected function hasAttachments(): bool
{
    return true;
}

Configuración de adjuntos

En config/filament-kanban.php:

'attachments' => [
    'enabled' => false,        // Activar/desactivar globalmente
    'disk' => 'public',        // Disco de almacenamiento
    'directory' => 'kanban-attachments', // Directorio
    'max_size' => 5120,        // Tamaño máximo en KB
    'accepted_types' => ['image/*', 'application/pdf', ...],
    'max_files' => 10,         // Máximo de archivos por tarjeta
],

Almacenamiento en disco

Los archivos se organizan por tarjeta en subdirectorios del disco configurado:

storage/app/public/
└── kanban-attachments/
    ├── 1/
    │   ├── foto.jpg
    │   └── documento.pdf
    ├── 2/
    │   └── captura.png
    └── 3/
        ├── informe.xlsx
        └── logo.svg

Cuando se crea o edita una tarjeta, los archivos subidos se mueven automáticamente a {directory}/{record_id}/. Si se eliminan adjuntos, los archivos también se borran del disco.

Modal de edición

Al abrir el modal de edición de una tarjeta con adjuntos:

  • Arriba: El formulario de edición con el campo FileUpload, que muestra los archivos existentes y permite subir nuevos
  • Abajo: Un listado de los adjuntos existentes con:
    • Thumbnail (si es imagen) o icono de documento
    • Nombre del archivo y tamaño
    • Botón de descarga directa
    • Botón de eliminar (con confirmación, borra registro y archivo del disco)

En la tarjeta

  • Las imágenes se muestran como miniatura en la tarjeta
  • Se muestra un contador de adjuntos con icono de clip, clicable para abrir el modal de edición
  • Los adjuntos usan relación polimórfica (MorphMany), por lo que funcionan con cualquier modelo
  • Puedes personalizar el modelo de adjuntos en la config: models.attachment

Personalización CSS — Sobrescribir clases fi-kanban-*

Todos los estilos del tablero usan clases CSS con prefijo fi-kanban-, siguiendo la convención de Filament (fi- = Filament). Todas incluyen variantes para dark mode con .dark .fi-kanban-*.

Cómo aplicar tus sobrescrituras

La forma recomendada es usar un custom theme de Filament. Si aún no tienes uno, créalo con:

php artisan make:filament-theme admin

Esto genera resources/css/filament/admin/theme.css. Añade tus sobrescrituras al final del archivo:

@import '../../../../vendor/filament/filament/resources/css/theme.css';

@source '../../../../app/Filament/**/*.php';

/* Tus sobrescrituras del kanban */
.fi-kanban-card {
    border-radius: 1rem;
    border-left: 4px solid var(--color-primary-500);
}

Registra el tema en tu panel provider y en vite.config.js:

// AdminPanelProvider.php
$panel->viteTheme('resources/css/filament/admin/theme.css');
// vite.config.js
input: [
    'resources/css/app.css',
    'resources/js/app.js',
    'resources/css/filament/admin/theme.css',
]

Clases disponibles

Tablero y columnas

Clase Descripción
.fi-kanban-board Contenedor principal del tablero (flex horizontal con scroll)
.fi-kanban-column Columna individual
.fi-kanban-column-header Cabecera de columna (label + contador)
.fi-kanban-column-label Texto del nombre de la columna
.fi-kanban-count Badge con número de tarjetas
.fi-kanban-col-bg--default Fondo por defecto de las columnas

Tarjetas

Clase Descripción
.fi-kanban-cards Contenedor de tarjetas (scroll vertical)
.fi-kanban-card Tarjeta individual
.fi-kanban-card-topbar Barra superior (drag handle + botones editar/eliminar)
.fi-kanban-card-content Contenido de la tarjeta
.fi-kanban-card-title Título de la tarjeta

Controles

Clase Descripción
.fi-kanban-create-btn Botón "+" en el header de columna para crear tarjeta
.fi-kanban-drag-handle Icono de arrastre (barras)
.fi-kanban-edit-btn Botón de editar (lápiz)
.fi-kanban-delete-btn Botón de eliminar (papelera, rojo)

Detalles de la tarjeta

Clase Descripción
.fi-kanban-details Contenedor de badges/fechas/texto
.fi-kanban-badge Etiqueta de texto
.fi-kanban-date Fecha con icono de calendario
.fi-kanban-date--normal Fecha sin urgencia
.fi-kanban-date--soon Fecha próxima (2 días o menos)
.fi-kanban-date--overdue Fecha vencida
.fi-kanban-text Texto auxiliar

Avatares (stacked)

Clase Descripción
.fi-kanban-avatars Contenedor de avatares apilados al pie de la card
.fi-kanban-avatar Avatar circular con iniciales (indigo, 1.625rem)

Prioridad

Clase Descripción
.fi-kanban-priority-strip Barra de prioridad
.fi-kanban-priority--low Prioridad baja (gris)
.fi-kanban-priority--medium Prioridad media (azul)
.fi-kanban-priority--high Prioridad alta (ámbar)
.fi-kanban-priority--critical Prioridad crítica (rojo)

Adjuntos (card)

Clase Descripción
.fi-kanban-thumbnail Contenedor de miniatura de imagen
.fi-kanban-attach-count Contador de adjuntos con icono
.fi-kanban-attach-count--clickable Estilo hover para el contador clicable

Adjuntos (modal de edición)

Clase Descripción
.fi-kanban-attachment-list Contenedor del listado de adjuntos
.fi-kanban-attachment-list-title Título "Adjuntos existentes (N)"
.fi-kanban-attachment-items Contenedor de items
.fi-kanban-attachment-item Fila de un adjunto
.fi-kanban-attachment-preview Contenedor de thumbnail/icono
.fi-kanban-attachment-thumb Imagen thumbnail
.fi-kanban-attachment-icon Icono de documento
.fi-kanban-attachment-info Nombre y tamaño
.fi-kanban-attachment-name Nombre del archivo
.fi-kanban-attachment-size Tamaño en KB
.fi-kanban-attachment-actions Contenedor de botones
.fi-kanban-attachment-download Botón de descarga
.fi-kanban-attachment-delete Botón de eliminar

Drag & drop (SortableJS)

Clase Descripción
.fi-kanban-ghost Placeholder que ocupa la posición destino durante el arrastre
.fi-kanban-chosen Tarjeta seleccionada (elevación con sombra)
.fi-kanban-drag Tarjeta mientras se arrastra

Quick add

Clase Descripción
.fi-kanban-quick-add Sección de añadido rápido
.fi-kanban-quick-add-btn Botón "Añadir tarjeta"
.fi-kanban-quick-input Textarea de entrada
.fi-kanban-quick-actions Contenedor de botones enviar/cancelar
.fi-kanban-quick-submit Botón de enviar
.fi-kanban-quick-cancel Botón de cancelar

Ejemplo de sobrescritura

Ejemplo para personalizar las tarjetas:

/* Cambiar el fondo de las tarjetas */
.fi-kanban-card {
    background: #f8fafc;
    border-radius: 1rem;
}
.dark .fi-kanban-card {
    background: rgb(15, 23, 42);
}

/* Hacer las prioridades más anchas */
.fi-kanban-priority-strip {
    width: 100%;
    height: 0.2rem;
}

/* Ocultar el drag handle en móvil */
@media (max-width: 768px) {
    .fi-kanban-drag-handle { display: none; }
}

Configuración completa

// config/filament-kanban.php
return [
    'board' => [
        'column_width' => '20rem',
        'card_animation' => 150,
        'quick_add' => true,
    ],

    'attachments' => [
        'enabled' => false,
        'disk' => 'public',
        'directory' => 'kanban-attachments',
        'max_size' => 5120,
        'accepted_types' => ['image/*', 'application/pdf', '.doc', '.docx', '.xls', '.xlsx', '.zip'],
        'max_files' => 10,
    ],

    'models' => [
        'attachment' => \CursosDesarrolloWeb\Kanban\Models\KanbanAttachment::class,
    ],

    'tables' => [
        'attachments' => 'kanban_attachments',
    ],
];

Traducciones

El paquete incluye traducciones en español e inglés. Las claves disponibles son:

Clave ES EN
kanban.board.add_card Añadir tarjeta Add card
kanban.board.add Añadir Add
kanban.board.cancel Cancelar Cancel
kanban.board.placeholder Escribe un título... Enter a title...
kanban.board.edit Editar Edit
kanban.board.delete Eliminar Delete
kanban.board.delete_confirm ¿Estás seguro de que quieres eliminar esta tarjeta? Are you sure you want to delete this card?
kanban.notifications.card_created Tarjeta creada Card created
kanban.notifications.card_deleted Tarjeta eliminada Card deleted
kanban.notifications.unauthorized No tienes permiso para realizar esta acción You are not authorized to perform this action
kanban.attachments.label Adjuntos Attachments
kanban.attachments.existing Adjuntos existentes Existing attachments
kanban.attachments.download Descargar Download
kanban.attachments.delete Eliminar adjunto Delete attachment
kanban.attachments.delete_confirm ¿Estás seguro de que quieres eliminar este adjunto? Are you sure you want to delete this attachment?

Para publicar y personalizar las traducciones:

php artisan vendor:publish --tag="filament-kanban-translations"

Métodos disponibles

Abstractos (obligatorios)

Método Retorno Descripción
getModel() string Clase Eloquent del modelo
getStatusEnum() string Enum BackedEnum con HasLabel
getEditFormSchema() array Componentes Filament para el formulario

Configuración de atributos

Método Default Descripción
getTitleAttribute() 'title' Campo del modelo mostrado como título
getStatusAttribute() 'status' Campo del modelo con el estado
getSortAttribute() 'sort_order' Campo del modelo para ordenamiento
getPriorityAttribute() null Campo de prioridad (null = desactivado)
getPriorityValues() ['low', 'medium', 'high', 'critical'] Valores de prioridad (mapean a clases CSS)

Vistas

Método Default Descripción
getColumnView() 'filament-kanban::column' Vista de la columna completa
getColumnHeaderView() 'filament-kanban::column-header' Vista de la cabecera de columna
getCardView() 'filament-kanban::card' Vista de la tarjeta
getQuickAddView() 'filament-kanban::quick-add' Vista del input de añadido rápido

Apariencia

Método Default Descripción
getColumnColors() [] Fondo de columnas (valores CSS, no Tailwind)
getColumnHeaderColors() [] Color del borde inferior del header
getCardDetails(Model) [] Detalles extra: badge, date, avatar, text
getColumnWidth() '20rem' Ancho de cada columna (valor CSS)
getCardAnimation() 150 Duración de animación en ms

Funcionalidades

Método Default Descripción
hasQuickAdd() true Habilitar añadido rápido
hasAttachments() false Habilitar adjuntos
getQuickAddDefaults(string) [] Valores por defecto al crear rápido
getRecordEagerLoads() [] Relaciones a precargar
onStatusChanged(Model, string) [] Hook al mover tarjeta (devuelve datos extra)

Acciones integradas

Cada columna y tarjeta incluye acciones Filament que se pueden sobrescribir:

Método Descripción
createRecordAction() Botón "+" en el header de columna. Abre modal con formulario y status pre-seleccionado
editRecordAction() Botón lápiz en la tarjeta. Abre modal de edición con opción de eliminar
deleteQuickRecordAction() Botón papelera en la tarjeta. Elimina con confirmación sin abrir modal

Autorización

Método Default Descripción
canCreateRecord() true Permiso para crear tarjetas (oculta "+", quick add)
canEditRecord(Model) true Permiso para editar una tarjeta (oculta lápiz)
canDeleteRecord(Model) true Permiso para eliminar una tarjeta (oculta papelera)
canReorderRecords() true Permiso para reordenar y mover tarjetas (oculta drag handle, desactiva drag & drop)

Requisitos

  • PHP 8.2+
  • Laravel 11+
  • Filament 4.x / 5.x

Licencia

Propietario - Solo para suscriptores de CursosDesarrolloWeb.