saade/filament-fullcalendar

最受欢迎的与Filament集成的JavaScript日历 💛

v3.2.2 2024-05-02 13:04 UTC

README

Latest Version on Packagist Total Downloads

Filament FullCalendar

功能

  • 高度可定制
  • 用于查看、创建、编辑和删除事件的模态框 由Filament Actions提供支持
  • Filament-y 主题
  • 等等!

目录


安装

您可以通过 composer 安装此包

composer require saade/filament-fullcalendar:^3.0

使用

  1. 首先,创建一个 Filament 小部件
php artisan make:filament-widget CalendarWidget

这将会在您的项目中创建一个新的小部件类。


  1. 您新创建的小部件应该继承自本包中的 Saade\FilamentFullCalendar\Widgets\FullCalendarWidget

警告

不要忘记从生成的类中删除 protected static string $view

您的部件应该如下所示

<?php

namespace App\Filament\Widgets;

use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget;

class CalendarWidget extends FullCalendarWidget
{
    /**
     * FullCalendar will call this function whenever it needs new event data.
     * This is triggered when the user clicks prev/next or switches views on the calendar.
     */
    public function fetchEvents(array $fetchInfo): array
    {
        // You can use $fetchInfo to filter events by date.
        // This method should return an array of event-like objects. See: https://github.com/saade/filament-fullcalendar/blob/3.x/#returning-events
        // You can also return an array of EventData objects. See: https://github.com/saade/filament-fullcalendar/blob/3.x/#the-eventdata-class
        return [];
    }
}

返回事件

fetchEvents 方法应该返回一个类似事件的对象数组。请参阅: FullCalendar 文档

<?php

namespace App\Filament\Widgets;

use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget;
use App\Filament\Resources\EventResource;
use App\Models\Event;

class CalendarWidget extends FullCalendarWidget
{

    public function fetchEvents(array $fetchInfo): array
    {
        return Event::query()
            ->where('starts_at', '>=', $fetchInfo['start'])
            ->where('ends_at', '<=', $fetchInfo['end'])
            ->get()
            ->map(
                fn (Event $event) => [
                    'title' => $event->id,
                    'start' => $event->starts_at,
                    'end' => $event->ends_at,
                    'url' => EventResource::getUrl(name: 'view', parameters: ['record' => $event]),
                    'shouldOpenUrlInNewTab' => true
                ]
            )
            ->all();
    }
}

EventData 类

如果您想以流畅的方式返回事件,可以使用 Saade\FilamentFullCalendar\Data\EventData 类。

<?php

namespace App\Filament\Widgets;

use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget;
use App\Filament\Resources\EventResource;
use App\Models\Event;

class CalendarWidget extends FullCalendarWidget
{

    public function fetchEvents(array $fetchInfo): array
    {
        return Event::query()
            ->where('starts_at', '>=', $fetchInfo['start'])
            ->where('ends_at', '<=', $fetchInfo['end'])
            ->get()
            ->map(
                fn (Event $event) => EventData::make()
                    ->id($event->uuid)
                    ->title($event->name)
                    ->start($event->starts_at)
                    ->end($event->ends_at)
                    ->url(
                        url: EventResource::getUrl(name: 'view', parameters: ['record' => $event]),
                        shouldOpenUrlInNewTab: true
                    )
            )
            ->toArray();
    }
}

配置

在您配置日历之前,您需要将 FilamentFullcalendarPlugin 添加到面板的 plugins 数组中。

<?php

namespace App\Providers\Filament;

use Filament\Panel;
use Filament\PanelProvider;
use Saade\FilamentFullCalendar\FilamentFullCalendarPlugin;

class AdminPanelProvider extends PanelProvider
{
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->default()
            ->id('admin')
            ->path('admin')
            ...
            ->plugin(
                FilamentFullCalendarPlugin::make()
                    ->schedulerLicenseKey()
                    ->selectable()
                    ->editable()
                    ->timezone()
                    ->locale()
                    ->plugins()
                    ->config()
            );
    }
}
<?php
namespace App\Filament\Widgets;

use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget;
use App\Models\Event;

class CalendarWidget extends FullCalendarWidget
{
    public Model | string | null $model = Event::class;

    public function config(): array
    {
        return [
            'firstDay' => 1,
            'headerToolbar' => [
                'left' => 'dayGridWeek,dayGridDay',
                'center' => 'title',
                'right' => 'prev,next today',
            ],
        ];
    }
}

可用方法

schedulerLicenseKey(string | null $licenseKey)

您的 FullCalendar 高级许可证密钥。(仅当您使用高级插件时才需要)

licenceKey(默认:null

selectable(bool $selectable)

允许用户通过点击和拖动来突出显示多个日期或时间段。请参阅: selectable

selectable(默认:false

editable(bool $editable)

这决定了事件是否可以被拖动和调整大小。请参阅: editable

editable(默认:false

timezone(string | null $timezone)

显示日期时使用的时区。请参阅: timezone

timezone(默认:config('app.timezone')

locale(string | null $locale)

显示文本和日期时使用的区域设置。请参阅: locale

locale(默认:config('app.locale')

plugins(array $plugins, bool $merge)

要启用的插件。如果您愿意,可以添加更多插件,或者通过将 false 作为方法的第二个参数传递来替换默认插件。可用的插件有: interaction, dayGrid, timeGrid, list, multiMonth, scrollGrid, timeline, adaptive, resource, resourceDayGrid, resourceTimeline, resourceTimeGrid, rrule, moment, momentTimezone 请参阅: 插件

插件 默认: ['dayGrid', 'timeGrid'] merge 默认: true

config(array $config)

日历的配置。并非所有配置都有一个专门的流畅方法与之交互,因此您可以传递FullCalendar TOC中列出的任何配置。见: FullCalendar 文档

config (默认: [])


与动作交互

此包利用了 Filament Actions 的强大功能,允许您查看、创建、编辑和删除事件。

要开始使用,您需要告诉小部件它应使用哪个模型来执行操作,并为查看、创建和编辑操作定义一个表单模式。

<?php

namespace App\Filament\Widgets;

use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget;
use App\Models\Event;

class CalendarWidget extends FullCalendarWidget
{
    public Model | string | null $model = Event::class;

    public function getFormSchema(): array
    {
        return [
            Forms\Components\TextInput::make('name'),

            Forms\Components\Grid::make()
                ->schema([
                    Forms\Components\DateTimePicker::make('starts_at'),

                    Forms\Components\DateTimePicker::make('ends_at'),
                ]),
        ];
    }
}

注意 请注意,表单模式不需要包含与FullCalendar事件对象相同的字段。您可以添加与您的模型一样多的字段。

就这样!现在您可以查看、创建、编辑和删除事件。

自定义动作

如果您想自定义操作,可以覆盖此包中提供的默认操作。操作的行为类似于任何其他 Filament Action,因此您可以像自定义任何其他 Filament Action 一样自定义它们。

<?php

namespace App\Filament\Widgets;

use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget;
use Saade\FilamentFullCalendar\Actions;
use App\Models\Event;

class CalendarWidget extends FullCalendarWidget
{
    public Model | string | null $model = Event::class;

    protected function headerActions(): array
    {
        return [
            Actions\CreateAction::make(),
        ];
    }

    protected function modalActions(): array
    {
        return [
            Actions\EditAction::make(),
            Actions\DeleteAction::make(),
        ];
    }

    protected function viewAction(): Action
    {
        return Actions\ViewAction::make();
    }

    public function getFormSchema(): array
    {
        return [
            Forms\Components\TextInput::make('name'),

            Forms\Components\Grid::make()
                ->schema([
                    Forms\Components\DateTimePicker::make('starts_at'),

                    Forms\Components\DateTimePicker::make('ends_at'),
                ]),
        ];
    }
}

授权动作

操作授权的行为类似于任何其他 Filament Action,因此您可以像自定义任何其他 Filament Action 一样自定义它们。


拦截事件

如果您想拦截事件,可以覆盖此包中提供的默认方法。

警告 如果您覆盖了以下任何方法,您需要调用父方法以保持日历按预期工作。

查看 InteractsWithEvents 以获取所有可用的事件监听器。


渲染钩子

如果您想自定义日历的事件渲染,可以使用Fullcalendar内置的 渲染钩子。所有钩子都受支持。

以下是如何使用 eventDidMount 钩子添加自定义实现的示例

    public function eventDidMount(): string
    {
        return <<<JS
            function({ event, timeText, isStart, isEnd, isMirror, isPast, isFuture, isToday, el, view }){
                // Write your custom implementation here
            }
        JS;
    }

另一个示例,请参阅 事件悬停提示


技巧

拖放后编辑事件

您可以通过在 EditAction 上使用 mountUsing 方法使用事件的新数据填充表单。

protected function modalActions(): array
 {
     return [
         Actions\EditAction::make()
             ->mountUsing(
                 function (Event $record, Forms\Form $form, array $arguments) {
                     $form->fill([
                         'name' => $record->name,
                         'starts_at' => $arguments['event']['start'] ?? $record->starts_at,
                         'ends_at' => $arguments['event']['end'] ?? $record->ends_at
                     ]);
                 }
             ),
         Actions\DeleteAction::make(),
     ];
 }

在日期选择时创建事件

您可以通过在 CreateAction 上使用 mountUsing 方法使用所选日期的日期填充表单。

use Saade\FilamentFullCalendar\Actions\CreateAction;

protected function headerActions(): array
 {
     return [
         Actions\CreateAction::make()
             ->mountUsing(
                 function (Forms\Form $form, array $arguments) {
                     $form->fill([
                         'starts_at' => $arguments['start'] ?? null,
                         'ends_at' => $arguments['end'] ?? null
                     ]);
                 }
             )
     ];
 }

使用附加数据创建事件

您可以通过在 CreateAction 上使用 mutateFormDataUsing 方法向事件添加额外的数据。

protected function headerActions(): array
 {
     return [
         Actions\CreateAction::make()
             ->mutateFormDataUsing(function (array $data): array {
                 return [
                     ...$data,
                     'calendar_id' => $this->record->id
                 ];
             })
     ];
 }

悬停时显示事件提示

您可以通过在 eventDidMount 方法上使用JavaScript添加提示,当用户悬停在事件上时完全显示事件标题。

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+"' }");
        }
    JS;
}

eventDidMount() 返回的JavaScript代码将被添加到 FullCalendar的 eventDidMount 事件渲染钩子

将小部件添加到 Blade 视图

按照 Filament 文档 知道如何将小部件添加到Blade视图中。

分享你的技巧

如果您想分享任何技巧,请提交一个PR并将其添加到此部分。


变更日志

有关最近更改的更多信息,请参阅 变更日志

贡献

有关详细信息,请参阅 贡献

安全漏洞

有关如何报告安全漏洞的详细信息,请参阅 我们的安全策略

鸣谢

许可

MIT 许可证。请参阅许可证文件获取更多信息。

Sponsor Saade