From f48261453fb7a10e41084d3056fee7fca8854dd5 Mon Sep 17 00:00:00 2001 From: DamsFX Date: Thu, 20 Feb 2025 05:12:29 +0100 Subject: [PATCH 1/6] Update to fullcalendar v6.1.15 -add widget initial view config -add widget first day of week config -add model attribute config for all day event --- .../backend/behaviors/CalendarController.php | 23 +- .../docs/example.config_calendar.yaml | 46 +- modules/backend/widgets/Calendar.php | 96 +- .../calendar/assets/css/fullcalendar.css | 1439 -- .../calendar/assets/css/fullcalendar.min.css | 5 - .../widgets/calendar/assets/js/calendar.js | 47 +- .../calendar/assets/less/calendar.less | 21 +- .../vendor/fullcalendar/index.global.js | 14702 ++++++++++++++++ .../vendor/fullcalendar/index.global.min.js | 6 + .../fullcalendar/locales-all.global.min.js | 6 + .../widgets/calendar/partials/_calendar.php | 2 + 11 files changed, 14891 insertions(+), 1502 deletions(-) delete mode 100644 modules/backend/widgets/calendar/assets/css/fullcalendar.css delete mode 100644 modules/backend/widgets/calendar/assets/css/fullcalendar.min.css create mode 100644 modules/backend/widgets/calendar/assets/vendor/fullcalendar/index.global.js create mode 100644 modules/backend/widgets/calendar/assets/vendor/fullcalendar/index.global.min.js create mode 100644 modules/backend/widgets/calendar/assets/vendor/fullcalendar/locales-all.global.min.js diff --git a/modules/backend/behaviors/CalendarController.php b/modules/backend/behaviors/CalendarController.php index 2fe1599d4f..daa17bf413 100644 --- a/modules/backend/behaviors/CalendarController.php +++ b/modules/backend/behaviors/CalendarController.php @@ -53,6 +53,16 @@ class CalendarController extends ControllerBehavior */ protected array $requiredConfig = ['modelClass', 'searchList']; + /** + * @var array Visible actions in context of the controller + */ + protected $actions = ['calendar']; + + /** + * @var mixed Configuration for this behaviour + */ + public $calendarConfig = 'config_calendar.yaml'; + /** * Behavior constructor */ @@ -60,9 +70,16 @@ public function __construct(\Backend\Classes\Controller $controller) { parent::__construct($controller); + /* + * Build configuration + */ + $config = $controller->calendarConfig ?: $this->calendarConfig; + $this->setConfig($config, $this->requiredConfig); + + // Build the configuration - $this->config = $this->makeConfig($controller->calendarConfig, $this->requiredConfig); - $this->config->modelClass = Str::normalizeClassName($this->config->modelClass); + // $this->config = $this->makeConfig($controller->calendarConfig, $this->requiredConfig); + // $this->config->modelClass = Str::normalizeClassName($this->config->modelClass); } /** @@ -72,7 +89,7 @@ public function calendar(): void { $this->controller->pageTitle = $this->controller->pageTitle ? : Lang::get($this->getConfig( 'title', - 'luketowers.calendarwidget::lang.behaviors.calendar.title' + 'backend::lang.calendar.title' )); $this->controller->bodyClass = 'slim-container'; $this->makeCalendar(); diff --git a/modules/backend/behaviors/calendarcontroller/docs/example.config_calendar.yaml b/modules/backend/behaviors/calendarcontroller/docs/example.config_calendar.yaml index 934f51d0df..a1cf5aa8ae 100644 --- a/modules/backend/behaviors/calendarcontroller/docs/example.config_calendar.yaml +++ b/modules/backend/behaviors/calendarcontroller/docs/example.config_calendar.yaml @@ -5,12 +5,33 @@ # Model to use for getting the records to display on the calendar modelClass: Author\Plugin\Models\Event +# Calendar Title +title: 'backend::lang.calendar.title' + # Search columns # Used for configuration of additional columns to search by searchList: $/author/plugin/models/event/columns.yaml # Record URL -recordUrl: author/plugins/events/update/:event_id +recordUrl: author/plugins/events/update/:id + +# The property to use as the title displayed on the calendar +recordTitle: name + +# The property to use as the start time for the record +recordStart: start_at + +# The property to use as the end time for the record +recordEnd: end_at + +# The property to use as all day long event for the record +recordAllDay: all_day + +# The property to use as the background color displayed on the record, , '' = the default background color in the calendar.less +recordColor: event_color + +# The property to use as the content of the tooltip for the record +recordTooltip: [recordTitle] # Record on click @@ -32,24 +53,15 @@ recordUrl: author/plugins/events/update/:event_id # view: The current view @see https://fullcalendar.io/docs/v4/view-object onClickDate: $.wn.availabilitySlotController.onClickDate(:data, :date, :dateStr, :allDay, :dayEl, :event, :view) -# The property to use as the title displayed on the calendar -recordTitle: name - -# The property to use as the start time for the record -recordStart: start_time - -# The property to use as the end time for the record -recordEnd: end_time - -# The property to use as the background color displayed on the record, , '' = the default background color in the calendar.less -recordColor: event_color - -# The property to use as the content of the tooltip for the record -recordTooltip: [recordTitle] - # Available display modes to be supported in this instance availableDisplayModes: [month, week, day, list] +# Default view for calendar widget (month, week, day or list) +initialView: month + +# First day of week, 0=Sun, 1=Mon ... +firstDay: 0 + # Flag for whether calendar is read only or editable previewMode: true @@ -63,6 +75,8 @@ toolbar: # Search widget configuration search: prompt: backend::lang.list.search_prompt + +# The filter config file for the controller filter: calendar_filter.yaml # when filter gets applied, clear the client's cache of events, essentially start them over diff --git a/modules/backend/widgets/Calendar.php b/modules/backend/widgets/Calendar.php index bc331b9b83..25b7a2aa48 100644 --- a/modules/backend/widgets/Calendar.php +++ b/modules/backend/widgets/Calendar.php @@ -69,6 +69,11 @@ class Calendar extends WidgetBase */ public string $recordEnd = 'end_at'; + /** + * The model property to use as all day long event for the record + */ + public string $recordAllDay = 'all_day'; + /** * The model property to use to show the background color of this record, '' = the default background color in the calendar.less */ @@ -84,6 +89,16 @@ class Calendar extends WidgetBase */ public array $availableDisplayModes = []; + /** + * Initial calendar view, either mont, week, day or list + */ + public ?string $initialView = 'month'; + + /** + * First day of week, 0=Sun, 1=Mon ... + */ + public ?int $firstDay = 0; + /** * Calendar of CSS classes to apply to the Calendar container element */ @@ -129,6 +144,7 @@ class Calendar extends WidgetBase public function init() { $this->fillFromConfig([ + // 'model', 'columns', 'recordUrl', 'recordOnClick', @@ -136,11 +152,14 @@ public function init() 'recordTitle', 'recordStart', 'recordEnd', + 'recordAllDay', 'recordColor', 'recordTooltip', 'previewMode', 'searchList', 'availableDisplayModes', + 'initialView', + 'firstDay', ]); // Initialize the search columns @@ -153,7 +172,13 @@ public function init() } $this->searchColumns = $columns; - $this->calendarVisibleColumns = [$this->recordTitle, $this->recordStart, $this->recordEnd]; + $this->calendarVisibleColumns = [ + $this->recordTitle, + $this->recordStart, + $this->recordEnd, + ]; + + // $this->validateModel(); } /** @@ -179,23 +204,10 @@ public function getRecordUrl(Model $record): ?string */ protected function loadAssets() { - $this->addCss(['packages/core/main.min.css', 'packages/list/main.min.css', 'packages/daygrid/main.min.css', 'packages/timegrid/main.min.css'], '4.1.0'); - $this->addCss(['less/calendar.less'], 'Winter.Core'); - - //Tooltip - $this->addJs('packages/vendor/popper.min.js', '4.1.0'); - $this->addJs('packages/vendor/tooltip.min.js', '4.1.0'); - - //Calendar - $this->addJs('packages/core/main.min.js', '4.1.0'); - $this->addJs('packages/list/main.min.js', '4.1.0'); - $this->addJs('packages/daygrid/main.min.js', '4.1.0'); - $this->addJs('packages/timegrid/main.min.js', '4.1.0'); - $this->addJs('packages/interaction/main.min.js', '4.1.0'); - - // @see https://fullcalendar.io/docs/v4/timeZone - $this->addJs('packages/moment-timezone/main.min.js', '4.1.0'); + $this->addJs('vendor/fullcalendar/index.global.min.js', '6.1.15'); + $this->addJs('vendor/fullcalendar/locales-all.global.min.js', '6.1.15'); + $this->addCss(['less/calendar.less'], 'Winter.Core'); $this->addJs('js/calendar.cache.js', 'Winter.Core'); $this->addJs('js/calendar.js', 'Winter.Core'); } @@ -206,13 +218,55 @@ protected function loadAssets() public function prepareVars() { $this->vars['availableDisplayModes'] = $this->getDisplayModes(); + $this->vars['initialView'] = $this->getInitialView(); + $this->vars['firstDay'] = $this->firstDay; $this->vars['cssClasses'] = implode(' ', $this->cssClasses); } + /** + * Validate the supplied form model. + * + * @return mixed + */ + protected function validateModel() + { + if (!$this->model) { + throw new ApplicationException(Lang::get( + 'backend::lang.form.missing_model', + ['class'=>get_class($this->controller)] + )); + } + + $this->data = isset($this->data) + ? (object) $this->data + : $this->model; + + return $this->model; + } + + + + /** + * Get the fullcalendar.js initial view to be used + */ + protected function getInitialView(): string + { + $fullCalendarModes = [ + 'month' => 'dayGridMonth', + 'week' => 'timeGridWeek', + 'day' => 'timeGridDay', + 'list' => 'listMonth' + ]; + + if (!empty($fullCalendarModes[$this->initialView])) { + return $fullCalendarModes[$this->initialView]; + } + } + /** * Get the fullcalendar.js display modes to be used */ - protected function getDisplayModes(): array + protected function getDisplayModes(): string { // Convert our display modes to FullCalendar display modes if (!is_array($this->availableDisplayModes)) { @@ -624,7 +678,8 @@ public function prepareQuery($startTime = 0, $endTime = 0) * @param QueryBuilder $query * @return string md5 */ - protected function getCacheKey($query){ + protected function getCacheKey($query) + { $bindings = array_map(function ($binding) { return (string)$binding; }, $query->getBindings()); @@ -673,7 +728,6 @@ public function getRecords($startTime = 0 , $endTime = 0) $records = $event; } - $events = []; $timeZone = new DateTimeZone(Config::get('app.timezone','UTC')); @@ -699,7 +753,7 @@ public function getRecords($startTime = 0 , $endTime = 0) 'title' => $record->{$this->recordTitle}, 'start' => $record->{$this->recordStart}, 'end' => $record->{$this->recordEnd}, - 'allDay' => (bool) $record->allDay, + 'allDay' => (bool) $record->{$this->recordAllDay}, 'color' => empty($this->recordColor) ? '' : $record->{$this->recordColor}, 'tooltip' => $tooltip ], $timeZone); diff --git a/modules/backend/widgets/calendar/assets/css/fullcalendar.css b/modules/backend/widgets/calendar/assets/css/fullcalendar.css deleted file mode 100644 index 936a41f13c..0000000000 --- a/modules/backend/widgets/calendar/assets/css/fullcalendar.css +++ /dev/null @@ -1,1439 +0,0 @@ -/*! - * FullCalendar v4.0.0-alpha.4 - * Docs & License: https://fullcalendar.io/ - * (c) 2018 Adam Shaw - */ -.fc { - direction: ltr; - text-align: left; } - -.fc-rtl { - text-align: right; } - -body .fc { - /* extra precedence to overcome jqui */ - font-size: 1em; } - -/* Colors ---------------------------------------------------------------------------------------------------*/ -.fc-highlight { - /* when user is selecting cells */ - background: #bce8f1; - opacity: .3; } - -.fc-bgevent { - /* default look for background events */ - background: #8fdf82; - opacity: .3; } - -.fc-nonbusiness { - /* default look for non-business-hours areas */ - /* will inherit .fc-bgevent's styles */ - background: #d7d7d7; } - -/* Buttons (styled