marshmallow / filament-fullcalendar
与 Filament 集成的最受欢迎的 JavaScript 日历分支 💛
Requires
- php: ^8.0
- filament/filament: ^2.0
- illuminate/contracts: ^9.0|^10.0
- spatie/laravel-package-tools: ^1.11
Requires (Dev)
- nunomaduro/collision: ^6.0|^7.0
- nunomaduro/larastan: ^1.0|^2.0
- orchestra/testbench: ^7.0|^8.0
- pestphp/pest: ^1.21
- pestphp/pest-plugin-laravel: ^1.1
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
- phpunit/phpunit: ^9.5
- spatie/laravel-ray: ^1.26
This package is auto-updated.
Last update: 2024-08-31 00:37:08 UTC
README
特性
- 接受来自 FullCalendar 的所有配置
- 事件点击和拖拽事件
- 创建和编辑事件的模态框 新功能 v1.0
支持 Filament
目录
安装
您可以通过 composer 安装此包
composer require saade/filament-fullcalendar
您可以使用以下命令发布配置文件
php artisan vendor:publish --tag="filament-fullcalendar-config"
用法
由于该包 不会 自动将 FullCalendarWidget
小部件添加到您的 Filament 面板,您可以自由扩展小部件并自行定制。
- 首先,创建一个 Filament 小部件
php artisan make:filament-widget CalendarWidget
这将在此项目中创建一个新的
App\Filament\Widgets\CalendarWidget
类。
- 您新建的小部件应扩展此包中的
Saade\FilamentFullCalendar\Widgets\FullCalendarWidget
类
警告
不要忘记从生成的类中删除
protected static string $view
!
<?php namespace App\Filament\Widgets; use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget; class CalendarWidget extends FullCalendarWidget { /** * Return events that should be rendered statically on calendar. */ public function getViewData(): array { return [ [ 'id' => 1, 'title' => 'Breakfast!', 'start' => now() ], [ 'id' => 2, 'title' => 'Meeting with Pamela', 'start' => now()->addDay(), 'url' => 'https://some-url.com', 'shouldOpenInNewTab' => true, ] ]; } /** * 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. return []; } }
警告
您应该使用
getViewData
来显示初始数据,并使用fetchEvents
来在翻页时获取新事件。
这两个方法都应该返回一个 EventObject 数组。
配置
这是默认配置文件的正文。
您可以使用 FullCalendar 根对象上的任何属性。请参阅:FullCalendar 文档 了解可用选项。它支持其中大部分。
<?php /** * Consider this file the root configuration object for FullCalendar. * Any configuration added here, will be added to the calendar. * @see https://fullcalendar.io/docs#toc */ return [ 'timeZone' => config('app.timezone'), 'locale' => config('app.locale'), 'headerToolbar' => [ 'left' => 'prev,next today', 'center' => 'title', 'right' => 'dayGridMonth,dayGridWeek,dayGridDay' ], 'navLinks' => true, 'editable' => true, 'selectable' => false, 'dayMaxEvents' => true ];
样式
如果您正在 构建自定义 Filament 主题,则需要额外一步来使日历主题与您的自定义主题匹配。
将此行添加到您的 resources/css/filament.css
文件中(或您正在使用的任何文件)。
@import '../../vendor/saade/filament-fullcalendar/resources/css/filament-fullcalendar.css';
此文件的最终内容应类似于以下内容
@import '../../vendor/filament/forms/dist/module.esm.css';
+ @import '../../vendor/saade/filament-fullcalendar/resources/css/filament-fullcalendar.css';
@import 'tippy.js/dist/tippy.css';
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
监听事件
目前支持的唯一与事件相关的事件是: EventClick 和 EventDrop
它们默认被注释掉,以免 livewire 在未使用它们的情况下发送请求。您可以将它们粘贴到您的 CalendarWidget
类中。见: FiresEvents
自 v1.0.0 以来,我们使用 onEventClick
来打开编辑模态框。如果您需要挂钩此事件,请确保使用 parent::onEventClick()
调用原始方法,以保持模态框按预期打开。
/** * Triggered when the user clicks an event. */ public function onEventClick($event): void { parent::onEventClick($event); // your code } /** * Triggered when dragging stops and the event has moved to a different day/time. */ public function onEventDrop($newEvent, $oldEvent, $relatedEvents): void { // your code } /** * Triggered when event's resize stops. */ public function onEventResize($event, $oldEvent, $relatedEvents): void { // your code }
使用模态框创建和编辑事件。
自 v1.0.0 以来,您可以使用模态框创建和编辑事件。
要自定义模态框,请在此小部件中覆盖以下属性
protected string $modalWidth
protected string $modalLabel
保存和编辑事件的流程由您决定,因为这个插件不依赖于模型来保存日历事件。
创建事件
事件可以通过两种方式创建。
- 点击某一天(默认)
- 选择日期范围(在日历日上点击并拖动)(您需要同意此操作,在配置文件中设置
selectable => true
。)
这将打开创建事件模态框。
当创建表单提交时,它将在您的组件上调用 createEvent
函数。请确保将以下代码片段添加到您的日历类中。
public function createEvent(array $data): void { // Create the event with the provided $data. }
如果默认表单无法满足您的需求,您可以覆盖 getCreateEventFormSchema
并像正常 Filament 表单一样使用它。
protected static function getCreateEventFormSchema(): array { return [ Forms\Components\TextInput::make('title') ->required(), Forms\Components\DatePicker::make('start') ->required(), Forms\Components\DatePicker::make('end') ->default(null), ]; }
您可以通过覆盖 getCreateEventModalTitle()
方法来更改模态框标题为自定义标题
public function getCreateEventModalTitle(): string { return __('filament::resources/pages/create-record.title', ['label' => $this->getModalLabel()]); }
您可以通过覆盖 getCreateEventModalSubmitButtonLabel()
和 getCreateEventModalCloseButtonLabel()
方法来更改模态框按钮标签为自定义标签
public function getCreateEventModalSubmitButtonLabel(): string { return __('filament::resources/pages/create-record.form.actions.create.label'); } public function getCreateEventModalCloseButtonLabel(): string { return __('filament::resources/pages/create-record.form.actions.cancel.label'); }
编辑事件
可以通过在日历上点击事件来编辑事件。
这将打开编辑事件模态框。
当编辑表单提交时,它将在您的组件上调用 editEvent
函数。请确保将以下代码片段添加到您的日历类中。
public function editEvent(array $data): void { // Edit the event with the provided $data. /** * here you can access to 2 properties to perform update * 1. $this->event_id * 2. $this->event */ # $this->event_id // the value is retrieved from event's id key // eg: Appointment::find($this->event); # $this->event // model instance is resolved by user defined resolveEventRecord() funtion. See example below // eg: $this->event->update($data); } // Resolve Event record into Model property public function resolveEventRecord(array $data): Model { // Using Appointment class as example return Appointment::find($data['id']); }
如果默认表单无法满足您的需求,您可以覆盖 getEditEventFormSchema
并像正常 Filament 表单一样使用它。
protected static function getEditEventFormSchema(): array { return [ Forms\Components\TextInput::make('title') ->required(), Forms\Components\DatePicker::make('start') ->required(), Forms\Components\DatePicker::make('end') ->default(null), ]; }
您可以通过覆盖 getEditEventModalTitle()
方法来更改模态框标题为自定义标题
public function getCreateEventModalTitle(): string { return __('filament::resources/pages/create-record.title', ['label' => $this->getModalLabel()]); }
您可以通过覆盖 getEditEventModalSubmitButtonLabel()
和 getEditEventModalCloseButtonLabel()
方法来更改模态框按钮标签为自定义标签
public function getEditEventModalSubmitButtonLabel(): string { return __('filament::resources/pages/edit-record.form.actions.save.label'); } public function getEditEventModalCloseButtonLabel(): string { return $this->editEventForm->isDisabled() ? __('filament-support::actions/view.single.modal.actions.close.label') : __('filament::resources/pages/edit-record.form.actions.cancel.label'); }
授权操作
如果您想授权 view
操作,您可以覆盖此包附带的自定义授权方法。
public static function canView(?array $event = null): bool { // When event is null, MAKE SURE you allow View otherwise the entire widget/calendar won't be rendered if ($event === null) { return true; } // Returning 'false' will not show the event Modal. return true; }
如果您想授权 edit
或 create
操作,您可以覆盖此包附带的自定义授权方法。
public static function canCreate(): bool { // Returning 'false' will remove the 'Create' button on the calendar. return true; } public static function canEdit(?array $event = null): bool { // Returning 'false' will disable the edit modal when clicking on a event. return true; }
如果您想禁用所有操作或将日历保持为 v1.0.0 的原始状态,您可以为所有上述方法返回 false,或使用方便的关心 CantManageEvents
。这将禁用所有日历模态框。
class CalendarWidget extends FullCalendarWidget { use CantManageEvents; // ... }
监听取消模态框
如果您想了解模态框何时被取消,您可以向您的组件 $listener
数组添加以下 Livewire 事件。
protected $listeners = [ 'cancelledFullcalendarCreateEventModal' => 'onCreateEventCancelled', 'cancelledFullcalendarEditEventModal' => 'onEditEventCancelled', ];
刷新日历事件
如果您想刷新日历事件,您可以在您的组件类中调用 $this->refreshEvents()
。这将调用 getViewData()
并重新渲染日历上的事件。
public function yourMethod(): void { $this->refreshEvents(); }
根据日历视图过滤事件
如果您想根据当前在日历中显示的天数来筛选事件,您可以从 CanFetchEvents 特性实现 fetchInfo()
方法。将以下代码添加到您的日历组件
/** * FullCalendar will call this function whenever it needs new event data. * This is triggered when the user clicks prev/next or switches views. * * @see https://fullcalendar.io/docs/events-function * @param array $fetchInfo start and end date of the current view */ public function fetchEvents(array $fetchInfo): array { return []; }
您可以根据时间段 $fetchInfo['start']
和 $fetchInfo['end']
过滤事件。
示例
public function fetchEvents(array $fetchInfo): array { $schedules = Appointment::query() ->where([ ['start_at', '>=', $fetchInfo['start']], ['end_at', '<', $fetchInfo['end']], ]) ->get(); $data = $schedules->map( ... ); return $data; }
测试
composer test
变更日志
有关最近更改的更多信息,请参阅 变更日志。
贡献
有关详细信息,请参阅 贡献指南。
安全漏洞
有关如何报告安全漏洞的更多信息,请参阅 我们的安全策略。
鸣谢
许可
MIT 许可证(MIT)。有关更多信息,请参阅 许可文件。