nova-calendar icon indicating copy to clipboard operation
nova-calendar copied to clipboard

Supply the CalendarDataProvider to the CalendarController per instance instead of through global dependency injection

Open wdelfuego opened this issue 2 years ago • 2 comments

Right now, the CalendarController expects a CalendarDataProviderInterface which is supplied through dependency injection.

For that to work, users of this package need to manually bind their own calendar data provider to the CalendarDataProviderInterface class in the boot() method of their NovaServiceProvider:

use App\Providers\CalendarDataProvider;

public function register()
{
    $this->app->bind(CalendarDataProviderInterface::class, function($app) {
        return new CalendarDataProvider();
    });
}

It would be nice if instead, the calendar data provider could be supplied through the tool's constructor within the tools() method, like this:

use App\Providers\CalendarDataProvider;

public function tools()
{
    return [
        new NovaCalendar(new CalendarDataProvider),
    ];
}

That would open the door to having multiple instances of the calendar Tool, each with their own data provider. It would have the added benefit of making the installation of the package slightly simpler.

Any questions or doubts?

Add a comment to this issue and we'll talk about it.

wdelfuego avatar Apr 25 '22 12:04 wdelfuego

This is something I would definitely use as it'd allow me to separate certain types of events into their own calendar as currently some days can get very "cluttered" when there's a ton of stuff going on.

Violet-Vibes avatar Jul 19 '22 08:07 Violet-Vibes

I've been playing with this and have to choose from several approaches. Will probably be released in version 2.0 together with PHP7 support because I don't think I can do this without introducing breaking changes.

wdelfuego avatar Jul 19 '22 11:07 wdelfuego

Well with very little effort I was able to hack something together that allows for this. Here's how I did it.

First I needed to add multiple new routes that would all lead to the same calendar. So inside my NovaServiceProvider.php boot method I added


        $this->app->booted(function () {
            Nova::router(['nova', \Wdelfuego\NovaCalendar\Http\Middleware\Authorize::class], 'bookings-calendar')
            ->group(base_path('vendor/wdelfuego/nova-calendar/routes/inertia.php'));

            Nova::router(['nova', \Wdelfuego\NovaCalendar\Http\Middleware\Authorize::class], 'lessons-calendar')
            ->group(base_path('vendor/wdelfuego/nova-calendar/routes/inertia.php'));
        });

So now I have two routes that lead to my calendar /nova/bookings-calendar and /nova/lessons-calendar

Then, inside my CalendarDataProvider I simply need to know which route I'm on and based on this I'll use different resources.

Here's how I did that:



    public function novaResources(): array
    {
        switch(basename(request()->server('HTTP_REFERER'))) {
            case 'bookings-calendar':
                $resources = [
                    \App\Nova\Resources\Bookings\Booking::class => ['starts_at', 'ends_at'],
                ];
                break;

            case 'lessons-calendar':
                $resources = [
                    \App\Nova\Resources\Bookings\BookingLesson::class => 'created_at',
                ];
                break;
        }

        return $resources;
    }

And voila! Easy-peasy ;-)

vesper8 avatar Dec 07 '22 10:12 vesper8

Will be released in 2.0 for sure, already available on the dev branch

wdelfuego avatar Jan 24 '23 21:01 wdelfuego