Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

events not captured after months change #197

Open
lorenzoalulithos opened this issue Jul 2, 2024 · 2 comments
Open

events not captured after months change #197

lorenzoalulithos opened this issue Jul 2, 2024 · 2 comments
Labels
bug Something isn't working question Further information is requested

Comments

@lorenzoalulithos
Copy link

lorenzoalulithos commented Jul 2, 2024

I report a strange bug.

I am using the eventDidMount and eventDidMount methods to try to improve the smartphone responsive nature of the calendar.

So far so good, except that I have noticed that when I change the month, the events are no longer captured and the changes made to the DOM are restored.
The bug is triggered by increasing the months by 2 or decreasing them to more than 5.

This is my implementation:

   /**
     * @return string
     */
    public function eventDidMount(): string
    {
        return <<<JS
                function({ event, timeText, isStart, isEnd, isMirror, isPast, isFuture, isToday, el, view }){
                    el.setAttribute("x-tooltip", "tooltip");
                    el.setAttribute("x-data", "{ tooltip: '"+event.title+"' }");

                    el.style.backgroundColor = event.extendedProps.is_sent ? 'green' : 'red';

                    const weekButton = document.querySelector('button[title="Settimana"]');

                    if (weekButton) {
                        weekButton.textContent = 'Sett';

                        weekButton.addEventListener('click', () => {
                            if (weekButton.textContent.trim() !== 'Sett') {
                                weekButton.textContent = 'Sett';
                            }
                        });
                    }

                    const dayButton = document.querySelector('button[title="Giorno"]');

                    if (dayButton) {
                        dayButton.addEventListener('click', () => {
                            if (weekButton.textContent.trim() !== 'Sett') {
                                weekButton.textContent = 'Sett';
                            }
                        });
                    }
                }
            JS;
    }

     /**
     * @return string
     */
    public function eventContent(): string
    {
        return <<<JS
                function({ event, timeText, isStart, isEnd, isMirror, isPast, isFuture, isToday, el, view }){
                    let currentDate = document.getElementById('current-date');console.log(event._context.calendarApi.currentData, currentDate)
                    currentDate.innerText = event._context.calendarApi.currentData.viewTitle
                }
            JS;
    }

on load:
Screenshot 2024-07-02 alle 11 19 24

after 1 click
Screenshot 2024-07-02 alle 11 19 30

after 2 click:
Screenshot 2024-07-02 alle 11 19 35

as you can see, the month disappears and the button is not updated.

Using the console.log inside the methods nothing is printed out after the 2nd click.

EDIT:
I would add that I have found that the method is not triggered if there is no model in the selected month.

@saade
Copy link
Owner

saade commented Jul 10, 2024

I could not even render the calendar properly with the code you've provided. Can you make a simple reproduction repository so i can have a look?

@saade saade added bug Something isn't working question Further information is requested labels Jul 10, 2024
@lorenzoalulithos
Copy link
Author

@saade

I developed a workaround:

   return Visit::withDataRangeAndRoles(
            Arr::get($info, 'start'),
            Arr::get($info, 'end')
        )
                    ->get()
                    ->map(
                        fn (Visit $visit) => [
                            'id' => $visit->id,
                            'title' => $visit->company_name,
                            'start' => $visit->arrival_date,
                            'end' => $visit->departure_date,
                            'url' => $visit->resource_detail_url,
                            'shouldOpenUrlInNewTab' => false,
                            'is_sent' => $visit->is_sent,
                        ]
                    )
                    ->whenEmpty(function () use ($info) {
                        return collect([
                            [
                                'id' => 0,
                                'title' => 'fake-model',
                                'start' => Arr::get($info, 'start'),
                                'end' => Arr::get($info, 'end'),
                            ],
                        ]);
                    })
                    ->all();
    }

When the method returns an empty array I create a dummy object, which I remove in the 'eventDidMount' method

 public function eventDidMount(): string
    {
        return <<<JS
                function({ event, timeText, isStart, isEnd, isMirror, isPast, isFuture, isToday, el, view }){
                    el.setAttribute("x-tooltip", "tooltip");
                    el.setAttribute("x-data", "{ tooltip: '"+event.title+"' }");
                    
                    if(event.title === 'fake-model'){
                        el.style.display = 'none'
                    }

I also added this property to retrieve the value of the month.

final class CalendarWidget extends FullCalendarWidget
{
    /**
     * {@inheritDoc}
     */
    public $defaultAction;

    public string|Model|null $model = Visit::class;

    /**
     * @var string
     */
    public string $mountLabel = '';
@php
    use \Saade\FilamentFullCalendar\FilamentFullCalendarPlugin;
    use \App\Filament\Widgets\CalendarWidget;
    use \Filament\Support\Facades\FilamentAsset;

    /** @var FilamentFullCalendarPlugin $plugin */
    $plugin = FilamentFullCalendarPlugin::get();

    /** @var CalendarWidget $calendar */
    $calendar = $this;
@endphp

<x-filament-widgets::widget>
    <x-filament::section class="full-height-calendar-container">
        <div class="flex justify-between flex-1 mb-4">
            <div>{{$this->mountLabel}}</div>

            <x-filament-actions::actions :actions="$this->getCachedHeaderActions()" class="shrink-0"/>
        </div>

        <div class="filament-fullcalendar full-height-calendar-section" wire:ignore ax-load
             ax-load-src="{{ FilamentAsset::getAlpineComponentSrc('filament-fullcalendar-alpine', 'saade/filament-fullcalendar') }}"
             ax-load-css="{{ FilamentAsset::getStyleHref('filament-fullcalendar-styles', 'saade/filament-fullcalendar') }}"
             x-ignore x-data="fullcalendar({
                locale: @js($plugin->getLocale()),
                plugins: @js($plugin->getPlugins()),
                schedulerLicenseKey: @js($plugin->getSchedulerLicenseKey()),
                timeZone: @js($plugin->getTimezone()),
                config: @js($this->getConfig()),
                editable: @json($plugin->isEditable()),
                selectable: @json($plugin->isSelectable()),
                eventClassNames: {!! htmlspecialchars($this->eventClassNames(), ENT_COMPAT) !!},
                eventContent: {!! htmlspecialchars($this->eventContent(), ENT_COMPAT) !!},
                eventDidMount: {!! htmlspecialchars($this->eventDidMount(), ENT_COMPAT) !!},
                eventWillUnmount: {!! htmlspecialchars($this->eventWillUnmount(), ENT_COMPAT) !!},
            })">
        </div>
    </x-filament::section>

    <x-filament-actions::modals/>
</x-filament-widgets::widget>

I know that by setting the configurations I can have the name of the month automatically. But I had to do this to fidx the responsive from all devices :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants