laravellaravel-filamentfilamentphp

Filament 4 + Guava Calendar: eventClick action opens empty modal (record not passed to action?)


I’m using Filament 4 with the package guava-labs/filament-calendar. Everything works except eventClick actions: clicking an event opens an empty modal, and no data from the clicked record is passed to the action.

Widget code (AppointmentCalendar.php)

<?php

namespace App\Filament\Widgets;

use App\Models\Appointment;
use Carbon\WeekDay;
use Guava\Calendar\Enums\CalendarViewType;
use Guava\Calendar\ValueObjects\FetchInfo;
use Guava\Calendar\Filament\CalendarWidget;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;

class AppointmentCalendar extends CalendarWidget
{
    // Vista mensile semplice
    protected CalendarViewType $calendarView = CalendarViewType::DayGridMonth;

    protected ?string $locale = 'en';
    protected bool $useFilamentTimezone = true;
    protected WeekDay $firstDay = WeekDay::Monday;
    protected bool $eventClickEnabled = true;
    protected ?string $defaultEventClickAction = 'view';

    protected function getEvents(FetchInfo $info): Collection | array | Builder
    {
        return Appointment::query()
            ->whereDate('appointment_at', '>=', $info->start)
            ->whereDate('appointment_at', '<=', $info->end);
    }
}

Model implementing Eventable (Appointment.php)

class Appointment extends Model implements HasMedia, Eventable
{
    use InteractsWithMedia;

    protected $fillable = [
        'user_id',
        'deposit',
        'total_price',
        'appointment_at',
        'duration_hours',
        'duration_minutes',
        'subject',
        'size',
        'position',
    ];

    /** relazione con utente */
    public function user()
    {
        return $this->belongsTo(User::class);
    }
    public function artist()
    {
        return $this->belongsTo(User::class, 'artist_id');
    }

    /** media library */
    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('before_image')
            ->singleFile();

        $this->addMediaCollection('after_image')
            ->singleFile();
    }
    
    protected $casts = [
        'appointment_at' => 'datetime',
    ];

    public function toCalendarEvent(): CalendarEvent
    {
        $start = $this->appointment_at;
        $end = $start->clone()
            ->addHours($this->duration_hours)
            ->addMinutes($this->duration_minutes);

        // Colori per artista (placeholder, li sistemi come vuoi)
        $artistColors = [
            1 => ['#64ffe7', '#000000'], // bg, text
            2 => ['#ffe92e', '#000000'],
        ];

        [$bg, $fg] = $artistColors[$this->artist_id] ?? ['#666666', '#ffffff'];

        // Nomi cliente / artista
        $customerName = trim(
            ($this->user->detail->first_name ?? '') . ' ' . ($this->user->detail->last_name ?? '')
        ) ?: 'Cliente sconosciuto';

        $artistName = trim(
            ($this->artist->detail->first_name ?? '') . ' ' . ($this->artist->detail->last_name ?? '')
        ) ?: 'Artista';

        $title = sprintf(
            "–%s\n%s\n%s (%s)",
            $end->format('H:i'),
            $customerName,
            $this->subject,
            $artistName
        );

        return CalendarEvent::make($this)
            ->title($title)
            ->start($start)
            ->end($end)
            ->styles([
                'white-space' => 'pre-line', // fondamentale per andare a capo
                'line-height' => '1.2',
                'font-size'   => '12px',
                'overflow'    => 'hidden',
            ]);
    }

}

When I click an event: • The modal opens • BUT IT’S COMPLETELY EMPTY • $record in the infolist() closure is always null • No fields are displayed

protected ?string $defaultEventClickAction = 'edit';

the edit modal works, and the record is correctly passed.

So the issue only happens with custom click actions (view here).

How can I have a modal with view?

enter image description here


Solution

  • You must define a infolists method on Resource file (AppointmentResource.php)
    for example

    public static function infolist(Schema $schema): Schema
        {
            return $schema
                ->components([
                    Infolists\Components\TextEntry::make('deposit'),
                    Infolists\Components\TextEntry::make('subject'),
                    Infolists\Components\TextEntry::make('total_price')
                        ->columnSpanFull(),
                ]);
        }