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

Add backend calendar controller #1313

Draft
wants to merge 8 commits into
base: wip/calendar-widget
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions modules/backend/behaviors/CalendarController.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,28 @@ 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
*/
public function __construct(\Backend\Classes\Controller $controller)
{
parent::__construct($controller);

// Build the configuration
$this->config = $this->makeConfig($controller->calendarConfig, $this->requiredConfig);
$this->config->modelClass = Str::normalizeClassName($this->config->modelClass);
/*
* Build configuration
*/
$config = $controller->calendarConfig ?: $this->calendarConfig;
$this->setConfig($config, $this->requiredConfig);
}

/**
Expand All @@ -72,7 +84,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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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
Expand Down
114 changes: 84 additions & 30 deletions modules/backend/widgets/Calendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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
*/
Expand All @@ -93,6 +108,17 @@ class Calendar extends WidgetBase
// INTERNAL
//

/**
* Available display modes for fullcalendar.js widget
*/
protected array $fullCalendarModes = [
// 'year' => 'multiMonthYear',
'month' => 'dayGridMonth',
'week' => 'timeGridWeek',
'day' => 'timeGridDay',
'list' => 'listMonth'
];

/**
* Collection of functions to apply to each list query.
*/
Expand Down Expand Up @@ -129,18 +155,22 @@ class Calendar extends WidgetBase
public function init()
{
$this->fillFromConfig([
// 'model',
'columns',
'recordUrl',
'recordOnClick',
'onClickDate',
'recordTitle',
'recordStart',
'recordEnd',
'recordAllDay',
'recordColor',
'recordTooltip',
'previewMode',
'searchList',
'availableDisplayModes',
'initialView',
'firstDay',
]);

// Initialize the search columns
Expand All @@ -153,7 +183,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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this commented out?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to add it based on the ListController but I get an error.
Need to take a closer look.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LukeTowers If I try to validate the model (as in Lists widget), then this error in throw :
Typed property Backend\Widgets\Calendar::$model must not be accessed before initialization.

Same if I try to add model to the fillFromConfig()method in plugin initialization.

}

/**
Expand All @@ -179,23 +215,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');
}
Expand All @@ -206,32 +229,63 @@ 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
{
if (!empty($this->fullCalendarModes[$this->initialView])) {
return $this->fullCalendarModes[$this->initialView];
}

return 'dayGridMonth';
}

/**
* 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)) {
$this->availableDisplayModes = [$this->availableDisplayModes];
}

$fullCalendarModes = [
'month' => 'dayGridMonth',
'week' => 'timeGridWeek',
'day' => 'timeGridDay',
'list' => 'listMonth'
];

$selectedModes = [];
foreach ($this->availableDisplayModes as $mode) {
if (!empty($fullCalendarModes[$mode])) {
$selectedModes[] = $fullCalendarModes[$mode];
if (!empty($this->fullCalendarModes[$mode])) {
$selectedModes[] = $this->fullCalendarModes[$mode];
}
}

return implode(',', $selectedModes);
}

Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -673,7 +728,6 @@ public function getRecords($startTime = 0 , $endTime = 0)
$records = $event;
}


$events = [];

$timeZone = new DateTimeZone(Config::get('app.timezone','UTC'));
Expand All @@ -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);
Expand Down
Loading
Loading