Code refactoring and improvements for the default calendar view utility.

This commit is contained in:
Alex Tselegidis 2022-01-17 05:10:26 +01:00
parent 7f1302087a
commit 04ec3adaa0

View file

@ -10,35 +10,43 @@
* ---------------------------------------------------------------------------- */ * ---------------------------------------------------------------------------- */
/** /**
* Working plan utility. * Default calendar view utility.
* *
* This module implements the functionality of the default calendar view. * This module implements the functionality of the default calendar view.
* *
* Old Name: BackendCalendarDefaultView * Old Name: BackendCalendarDefaultView
*/ */
App.Utils.CalendarDefaultView = (function () { App.Utils.CalendarDefaultView = (function () {
const $calendarPage = $('#calendar-page');
const $reloadAppointments = $('#reload-appointments');
const $calendar = $('#calendar');
const $selectFilterItem = $('#select-filter-item');
const $appointmentsModal = $('#appointments-modal');
const $unavailabilitiesModal = $('#unavailabilities-modal');
const $header = $('#header');
const $footer = $('#footer');
const $notification = $('#notification');
const $calendarToolbar = $('#calendar-toolbar');
const FILTER_TYPE_PROVIDER = 'provider'; const FILTER_TYPE_PROVIDER = 'provider';
const FILTER_TYPE_SERVICE = 'service'; const FILTER_TYPE_SERVICE = 'service';
let lastFocusedEventData; // Contains event data for later use. let lastFocusedEventData; // Contains event data for later use.
/** /**
* Bind the event handlers. * Add the utility event listeners.
*/ */
function bindEventHandlers() { function addEventListeners() {
const $calendarPage = $('#calendar-page');
/** /**
* Event: Reload Button "Click" * Event: Reload Button "Click"
* *
* When the user clicks the reload button, the calendar items need to be refreshed. * When the user clicks the reload button, the calendar items need to be refreshed.
*/ */
$('#reload-appointments').on('click', () => { $reloadAppointments.on('click', () => {
const calendarView = $('#calendar').fullCalendar('getView'); const calendarView = $calendar.fullCalendar('getView');
refreshCalendarAppointments( refreshCalendarAppointments(
$('#calendar'), $calendar,
$('#select-filter-item').val(), $selectFilterItem.val(),
$('#select-filter-item').find('option:selected').attr('type'), $selectFilterItem.find('option:selected').attr('type'),
calendarView.start, calendarView.start,
calendarView.end calendarView.end
); );
@ -57,11 +65,14 @@ App.Utils.CalendarDefaultView = (function () {
* Event: Popover Edit Button "Click" * Event: Popover Edit Button "Click"
* *
* Enables the edit dialog of the selected calendar event. * Enables the edit dialog of the selected calendar event.
*
* @param {jQuery.Event} event
*/ */
$calendarPage.on('click', '.edit-popover', () => { $calendarPage.on('click', '.edit-popover', (event) => {
$(event.target).parents('.popover').popover('dispose'); const $target = $(event.target);
$target.closest('.popover').popover('dispose');
let $dialog;
let startMoment; let startMoment;
let endMoment; let endMoment;
@ -91,7 +102,7 @@ App.Utils.CalendarDefaultView = (function () {
} }
} }
$('#select-filter-item').trigger('change'); // Update the calendar. $selectFilterItem.trigger('change'); // Update the calendar.
}; };
App.Http.Calendar.saveWorkingPlanException( App.Http.Calendar.saveWorkingPlanException(
@ -104,36 +115,35 @@ App.Utils.CalendarDefaultView = (function () {
}); });
} else if (!lastFocusedEventData.data.is_unavailable) { } else if (!lastFocusedEventData.data.is_unavailable) {
const appointment = lastFocusedEventData.data; const appointment = lastFocusedEventData.data;
$dialog = $('#appointments-modal');
App.Components.AppointmentsModal.resetModal(); App.Components.AppointmentsModal.resetModal();
// Apply appointment data and show modal dialog. // Apply appointment data and show modal dialog.
$dialog.find('.modal-header h3').text(App.Lang.edit_appointment_title); $appointmentsModal.find('.modal-header h3').text(App.Lang.edit_appointment_title);
$dialog.find('#appointment-id').val(appointment.id); $appointmentsModal.find('#appointment-id').val(appointment.id);
$dialog.find('#select-service').val(appointment.id_services).trigger('change'); $appointmentsModal.find('#select-service').val(appointment.id_services).trigger('change');
$dialog.find('#select-provider').val(appointment.id_users_provider); $appointmentsModal.find('#select-provider').val(appointment.id_users_provider);
// Set the start and end datetime of the appointment. // Set the start and end datetime of the appointment.
startMoment = moment(appointment.start_datetime); startMoment = moment(appointment.start_datetime);
$dialog.find('#start-datetime').datetimepicker('setDate', startMoment.toDate()); $appointmentsModal.find('#start-datetime').datetimepicker('setDate', startMoment.toDate());
endMoment = moment(appointment.end_datetime); endMoment = moment(appointment.end_datetime);
$dialog.find('#end-datetime').datetimepicker('setDate', endMoment.toDate()); $appointmentsModal.find('#end-datetime').datetimepicker('setDate', endMoment.toDate());
const customer = appointment.customer; const customer = appointment.customer;
$dialog.find('#customer-id').val(appointment.id_users_customer); $appointmentsModal.find('#customer-id').val(appointment.id_users_customer);
$dialog.find('#first-name').val(customer.first_name); $appointmentsModal.find('#first-name').val(customer.first_name);
$dialog.find('#last-name').val(customer.last_name); $appointmentsModal.find('#last-name').val(customer.last_name);
$dialog.find('#email').val(customer.email); $appointmentsModal.find('#email').val(customer.email);
$dialog.find('#phone-number').val(customer.phone_number); $appointmentsModal.find('#phone-number').val(customer.phone_number);
$dialog.find('#address').val(customer.address); $appointmentsModal.find('#address').val(customer.address);
$dialog.find('#city').val(customer.city); $appointmentsModal.find('#city').val(customer.city);
$dialog.find('#zip-code').val(customer.zip_code); $appointmentsModal.find('#zip-code').val(customer.zip_code);
$dialog.find('#appointment-location').val(appointment.location); $appointmentsModal.find('#appointment-location').val(appointment.location);
$dialog.find('#appointment-notes').val(appointment.notes); $appointmentsModal.find('#appointment-notes').val(appointment.notes);
$dialog.find('#customer-notes').val(customer.notes); $appointmentsModal.find('#customer-notes').val(customer.notes);
$dialog.modal('show'); $appointmentsModal.modal('show');
} else { } else {
const unavailable = lastFocusedEventData.data; const unavailable = lastFocusedEventData.data;
@ -143,17 +153,16 @@ App.Utils.CalendarDefaultView = (function () {
unavailable.end_datetime = lastFocusedEventData.end.format('YYYY-MM-DD HH:mm:ss'); unavailable.end_datetime = lastFocusedEventData.end.format('YYYY-MM-DD HH:mm:ss');
endMoment = moment(unavailable.end_datetime); endMoment = moment(unavailable.end_datetime);
$dialog = $('#unavailabilities-modal');
App.Components.UnavailabilitiesModal.resetModal(); App.Components.UnavailabilitiesModal.resetModal();
// Apply unavailable data to dialog. // Apply unavailable data to dialog.
$dialog.find('.modal-header h3').text('Edit Unavailable Period'); $unavailabilitiesModal.find('.modal-header h3').text('Edit Unavailable Period');
$dialog.find('#unavailable-start').datetimepicker('setDate', startMoment.toDate()); $unavailabilitiesModal.find('#unavailable-start').datetimepicker('setDate', startMoment.toDate());
$dialog.find('#unavailable-id').val(unavailable.id); $unavailabilitiesModal.find('#unavailable-id').val(unavailable.id);
$dialog.find('#unavailable-provider').val(unavailable.id_users_provider); $unavailabilitiesModal.find('#unavailable-provider').val(unavailable.id_users_provider);
$dialog.find('#unavailable-end').datetimepicker('setDate', endMoment.toDate()); $unavailabilitiesModal.find('#unavailable-end').datetimepicker('setDate', endMoment.toDate());
$dialog.find('#unavailable-notes').val(unavailable.notes); $unavailabilitiesModal.find('#unavailable-notes').val(unavailable.notes);
$dialog.modal('show'); $unavailabilitiesModal.modal('show');
} }
}); });
@ -162,15 +171,19 @@ App.Utils.CalendarDefaultView = (function () {
* *
* Displays a prompt on whether the user wants the appointment to be deleted. If he confirms the * Displays a prompt on whether the user wants the appointment to be deleted. If he confirms the
* deletion then an AJAX call is made to the server and deletes the appointment from the database. * deletion then an AJAX call is made to the server and deletes the appointment from the database.
*
* @param {jQuery.Event} event
*/ */
$calendarPage.on('click', '.delete-popover', (event) => { $calendarPage.on('click', '.delete-popover', (event) => {
$(event.target).parents('.popover').popover('dispose'); const $target = $(event.target);
$target.parents('.popover').popover('dispose');
let url; let url;
let data; let data;
if (lastFocusedEventData.data.workingPlanException) { if (lastFocusedEventData.data.workingPlanException) {
const providerId = $('#select-filter-item').val(); const providerId = $selectFilterItem.val();
const provider = App.Vars.available_providers.find( const provider = App.Vars.available_providers.find(
(availableProvider) => Number(availableProvider.id) === Number(providerId) (availableProvider) => Number(availableProvider.id) === Number(providerId)
@ -195,7 +208,7 @@ App.Utils.CalendarDefaultView = (function () {
} }
} }
$('#select-filter-item').trigger('change'); // Update the calendar. $selectFilterItem.trigger('change'); // Update the calendar.
}; };
const date = lastFocusedEventData.start.format('YYYY-MM-DD'); const date = lastFocusedEventData.start.format('YYYY-MM-DD');
@ -224,7 +237,7 @@ App.Utils.CalendarDefaultView = (function () {
$('#message-box').dialog('close'); $('#message-box').dialog('close');
// Refresh calendar event items. // Refresh calendar event items.
$('#select-filter-item').trigger('change'); $selectFilterItem.trigger('change');
}); });
} }
} }
@ -254,7 +267,7 @@ App.Utils.CalendarDefaultView = (function () {
$('#message-box').dialog('close'); $('#message-box').dialog('close');
// Refresh calendar event items. // Refresh calendar event items.
$('#select-filter-item').trigger('change'); $selectFilterItem.trigger('change');
}); });
} }
}); });
@ -264,22 +277,22 @@ App.Utils.CalendarDefaultView = (function () {
* *
* Load the appointments that correspond to the select filter item and display them on the calendar. * Load the appointments that correspond to the select filter item and display them on the calendar.
*/ */
$('#select-filter-item').on('change', () => { $selectFilterItem.on('change', () => {
// If current value is service, then the sync buttons must be disabled. // If current value is service, then the sync buttons must be disabled.
if ($('#select-filter-item option:selected').attr('type') === FILTER_TYPE_SERVICE) { if ($selectFilterItem.find('option:selected').attr('type') === FILTER_TYPE_SERVICE) {
$('#google-sync, #enable-sync, #insert-appointment, #insert-dropdown').prop('disabled', true); $('#google-sync, #enable-sync, #insert-appointment, #insert-dropdown').prop('disabled', true);
$('#calendar').fullCalendar('option', { $calendar.fullCalendar('option', {
selectable: false, selectable: false,
editable: false editable: false
}); });
} else { } else {
$('#google-sync, #enable-sync, #insert-appointment, #insert-dropdown').prop('disabled', false); $('#google-sync, #enable-sync, #insert-appointment, #insert-dropdown').prop('disabled', false);
$('#calendar').fullCalendar('option', { $calendar.fullCalendar('option', {
selectable: true, selectable: true,
editable: true editable: true
}); });
const providerId = $('#select-filter-item').val(); const providerId = $selectFilterItem.val();
const provider = App.Vars.available_providers.find(function (availableProvider) { const provider = App.Vars.available_providers.find(function (availableProvider) {
return Number(availableProvider.id) === Number(providerId); return Number(availableProvider.id) === Number(providerId);
@ -290,7 +303,7 @@ App.Utils.CalendarDefaultView = (function () {
} }
// If the user has already the sync enabled then apply the proper style changes. // If the user has already the sync enabled then apply the proper style changes.
if ($('#select-filter-item option:selected').attr('google-sync') === 'true') { if ($selectFilterItem('option:selected').attr('google-sync') === 'true') {
$('#enable-sync').removeClass('btn-light').addClass('btn-secondary enabled'); $('#enable-sync').removeClass('btn-light').addClass('btn-secondary enabled');
$('#enable-sync span').text(App.Lang.disable_sync); $('#enable-sync span').text(App.Lang.disable_sync);
$('#google-sync').prop('disabled', false); $('#google-sync').prop('disabled', false);
@ -313,11 +326,7 @@ App.Utils.CalendarDefaultView = (function () {
*/ */
function getCalendarHeight() { function getCalendarHeight() {
const result = const result =
window.innerHeight - window.innerHeight - $footer.outerHeight() - $header.outerHeight() - $calendarToolbar.outerHeight() - 60; // 60 for fine tuning
$('#footer').outerHeight() -
$('#header').outerHeight() -
$('#calendar-toolbar').outerHeight() -
60; // 60 for fine tuning
return result > 500 ? result : 500; // Minimum height is 500px return result > 500 ? result : 500; // Minimum height is 500px
} }
@ -343,7 +352,9 @@ App.Utils.CalendarDefaultView = (function () {
* above the calendar item. * above the calendar item.
*/ */
function calendarEventClick(event, jsEvent) { function calendarEventClick(event, jsEvent) {
$('.popover').popover('dispose'); // Close all open popovers. const $target = $(jsEvent.target);
$calendarPage.find('.popover').popover('dispose'); // Close all open popovers.
let $html; let $html;
let displayEdit; let displayEdit;
@ -355,7 +366,7 @@ App.Utils.CalendarDefaultView = (function () {
const $altParent = $(jsEvent.target).parents().eq(1); const $altParent = $(jsEvent.target).parents().eq(1);
if ( if (
$(this).hasClass('fc-unavailable') || $target.hasClass('fc-unavailable') ||
$parent.hasClass('fc-unavailable') || $parent.hasClass('fc-unavailable') ||
$altParent.hasClass('fc-unavailable') $altParent.hasClass('fc-unavailable')
) { ) {
@ -451,7 +462,7 @@ App.Utils.CalendarDefaultView = (function () {
] ]
}); });
} else if ( } else if (
$(this).hasClass('fc-working-plan-exception') || $target.hasClass('fc-working-plan-exception') ||
$parent.hasClass('fc-working-plan-exception') || $parent.hasClass('fc-working-plan-exception') ||
$altParent.hasClass('fc-working-plan-exception') $altParent.hasClass('fc-working-plan-exception')
) { ) {
@ -459,7 +470,7 @@ App.Utils.CalendarDefaultView = (function () {
($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) && ($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) &&
App.Vars.privileges.appointments.delete === true App.Vars.privileges.appointments.delete === true
? 'me-2' ? 'me-2'
: 'd-none'; // Same value at the time. : 'd-none';
$html = $('<div/>', { $html = $('<div/>', {
'html': [ 'html': [
@ -537,7 +548,7 @@ App.Utils.CalendarDefaultView = (function () {
] ]
}), }),
$('<button/>', { $('<button/>', {
'class': 'edit-popover btn btn-primary ' + displayEdit, 'class': 'edit-popover btn btn-primary',
'html': [ 'html': [
$('<i/>', { $('<i/>', {
'class': 'fas fa-edit me-2' 'class': 'fas fa-edit me-2'
@ -698,7 +709,7 @@ App.Utils.CalendarDefaultView = (function () {
}); });
} }
$(jsEvent.target).popover({ $target.popover({
placement: 'top', placement: 'top',
title: event.title, title: event.title,
content: $html, content: $html,
@ -709,11 +720,13 @@ App.Utils.CalendarDefaultView = (function () {
lastFocusedEventData = event; lastFocusedEventData = event;
$(jsEvent.target).popover('toggle'); $target.popover('toggle');
// Fix popover position. // Fix popover position.
if ($('.popover').length > 0 && $('.popover').position().top < 200) { const $popover = $calendarPage.find('.popover');
$('.popover').css('top', '200px');
if ($popover.length > 0 && $popover.position().top < 200) {
$popover.css('top', '200px');
} }
} }
@ -732,12 +745,10 @@ App.Utils.CalendarDefaultView = (function () {
return; return;
} }
const $calendar = $('#calendar');
let successCallback; let successCallback;
if ($('#notification').is(':visible')) { if ($notification.is(':visible')) {
$('#notification').hide('bind'); $notification.hide('bind');
} }
if (!event.data.is_unavailable) { if (!event.data.is_unavailable) {
@ -771,7 +782,7 @@ App.Utils.CalendarDefaultView = (function () {
}; };
$.post(url, data).done(() => { $.post(url, data).done(() => {
$('#notification').hide('blind'); $notification.hide('blind');
}); });
revertFunc(); revertFunc();
@ -783,7 +794,7 @@ App.Utils.CalendarDefaultView = (function () {
'function': undoFunction 'function': undoFunction
} }
]); ]);
$('#footer').css('position', 'static'); // Footer position fix. $footer.css('position', 'static'); // Footer position fix.
// Update the event data for later use. // Update the event data for later use.
$calendar.fullCalendar('updateEvent', event); $calendar.fullCalendar('updateEvent', event);
@ -820,7 +831,7 @@ App.Utils.CalendarDefaultView = (function () {
}; };
$.post(url, data).done(() => { $.post(url, data).done(() => {
$('#notification').hide('blind'); $notification.hide('blind');
}); });
revertFunc(); revertFunc();
@ -833,7 +844,7 @@ App.Utils.CalendarDefaultView = (function () {
} }
]); ]);
$('#footer').css('position', 'static'); // Footer position fix. $footer.css('position', 'static'); // Footer position fix.
// Update the event data for later use. // Update the event data for later use.
$calendar.fullCalendar('updateEvent', event); $calendar.fullCalendar('updateEvent', event);
@ -852,7 +863,7 @@ App.Utils.CalendarDefaultView = (function () {
* @see getCalendarHeight() * @see getCalendarHeight()
*/ */
function calendarWindowResize() { function calendarWindowResize() {
$('#calendar').fullCalendar('option', 'height', getCalendarHeight()); $calendar.fullCalendar('option', 'height', getCalendarHeight());
} }
/** /**
@ -865,8 +876,8 @@ App.Utils.CalendarDefaultView = (function () {
*/ */
function calendarDayClick(date) { function calendarDayClick(date) {
if (!date.hasTime()) { if (!date.hasTime()) {
$('#calendar').fullCalendar('changeView', 'agendaDay'); $calendar.fullCalendar('changeView', 'agendaDay');
$('#calendar').fullCalendar('gotoDate', date); $calendar.fullCalendar('gotoDate', date);
} }
} }
@ -887,8 +898,8 @@ App.Utils.CalendarDefaultView = (function () {
return; return;
} }
if ($('#notification').is(':visible')) { if ($notification.is(':visible')) {
$('#notification').hide('bind'); $notification.hide('bind');
} }
let successCallback; let successCallback;
@ -938,7 +949,7 @@ App.Utils.CalendarDefaultView = (function () {
}; };
$.post(url, data).done(() => { $.post(url, data).done(() => {
$('#notification').hide('blind'); $notification.hide('blind');
}); });
revertFunc(); revertFunc();
@ -951,7 +962,7 @@ App.Utils.CalendarDefaultView = (function () {
} }
]); ]);
$('#footer').css('position', 'static'); // Footer position fix. $footer.css('position', 'static'); // Footer position fix.
}; };
// Update appointment data. // Update appointment data.
@ -988,7 +999,7 @@ App.Utils.CalendarDefaultView = (function () {
}; };
$.post(url, data).done(() => { $.post(url, data).done(() => {
$('#notification').hide('blind'); $notification.hide('blind');
}); });
revertFunc(); revertFunc();
@ -1001,7 +1012,7 @@ App.Utils.CalendarDefaultView = (function () {
} }
]); ]);
$('#footer').css('position', 'static'); // Footer position fix. $footer.css('position', 'static'); // Footer position fix.
}; };
App.Http.Calendar.saveUnavailable(unavailable, successCallback); App.Http.Calendar.saveUnavailable(unavailable, successCallback);
@ -1015,16 +1026,16 @@ App.Utils.CalendarDefaultView = (function () {
* display proper information to the user. * display proper information to the user.
*/ */
function calendarViewRender() { function calendarViewRender() {
if ($('#select-filter-item').val() === null) { if ($selectFilterItem.val() === null) {
return; return;
} }
refreshCalendarAppointments( refreshCalendarAppointments(
$('#calendar'), $calendar,
$('#select-filter-item').val(), $selectFilterItem.val(),
$('#select-filter-item option:selected').attr('type'), $('#select-filter-item option:selected').attr('type'),
$('#calendar').fullCalendar('getView').start, $calendar.fullCalendar('getView').start,
$('#calendar').fullCalendar('getView').end $calendar.fullCalendar('getView').end
); );
$(window).trigger('resize'); // Places the footer on the bottom. $(window).trigger('resize'); // Places the footer on the bottom.
@ -1086,8 +1097,6 @@ App.Utils.CalendarDefaultView = (function () {
return $.post(url, data) return $.post(url, data)
.done((response) => { .done((response) => {
const $calendar = $('#calendar');
$calendar.fullCalendar('removeEvents'); $calendar.fullCalendar('removeEvents');
// Add appointments to calendar. // Add appointments to calendar.
@ -1132,7 +1141,7 @@ App.Utils.CalendarDefaultView = (function () {
calendarEventSource.push(unavailabilityEvent); calendarEventSource.push(unavailabilityEvent);
}); });
const calendarView = $('#calendar').fullCalendar('getView'); const calendarView = $calendar.fullCalendar('getView');
if (filterType === FILTER_TYPE_PROVIDER && calendarView.name !== 'month') { if (filterType === FILTER_TYPE_PROVIDER && calendarView.name !== 'month') {
const provider = App.Vars.available_providers.find( const provider = App.Vars.available_providers.find(
@ -1466,7 +1475,7 @@ App.Utils.CalendarDefaultView = (function () {
const firstWeekdayNumber = App.Utils.Date.getWeekdayId(firstWeekday); const firstWeekdayNumber = App.Utils.Date.getWeekdayId(firstWeekday);
// Initialize page calendar // Initialize page calendar
$('#calendar').fullCalendar({ $calendar.fullCalendar({
defaultView: defaultView, defaultView: defaultView,
height: getCalendarHeight(), height: getCalendarHeight(),
editable: true, editable: true,
@ -1499,12 +1508,12 @@ App.Utils.CalendarDefaultView = (function () {
if ($('#select-filter-item option:selected').attr('type') === FILTER_TYPE_SERVICE) { if ($('#select-filter-item option:selected').attr('type') === FILTER_TYPE_SERVICE) {
service = App.Vars.available_services.find( service = App.Vars.available_services.find(
(availableService) => Number(availableService.id) === Number($('#select-filter-item').val()) (availableService) => Number(availableService.id) === Number($selectFilterItem.val())
); );
$('#select-service').val(service.id).trigger('change'); $appointmentsModal.find('#select-service').val(service.id).trigger('change');
} else { } else {
const provider = App.Vars.available_providers.find( const provider = App.Vars.available_providers.find(
(availableProvider) => Number(availableProvider.id) === Number($('#select-filter-item').val()) (availableProvider) => Number(availableProvider.id) === Number($selectFilterItem.val())
); );
service = App.Vars.available_services.find( service = App.Vars.available_services.find(
@ -1512,24 +1521,24 @@ App.Utils.CalendarDefaultView = (function () {
); );
if (service) { if (service) {
$('#select-service').val(service.id); $appointmentsModal.find('#select-service').val(service.id);
} }
if (!$('#select-service').val()) { if (!$appointmentsModal.find('#select-service').val()) {
$('#select-service option:first').prop('selected', true); $('#select-service option:first').prop('selected', true);
} }
$('#select-service').trigger('change'); $appointmentsModal.find('#select-service').trigger('change');
if (provider) { if (provider) {
$('#select-provider').val(provider.id); $appointmentsModal.find('#select-provider').val(provider.id);
} }
if (!$('#select-provider').val()) { if (!$appointmentsModal.find('#select-provider').val()) {
$('#select-provider option:first').prop('selected', true); $appointmentsModal.find('#select-provider option:first').prop('selected', true);
} }
$('#select-provider').trigger('change'); $appointmentsModal.find('#select-provider').trigger('change');
} }
// Preselect time // Preselect time
@ -1617,7 +1626,7 @@ App.Utils.CalendarDefaultView = (function () {
// Fill the select list boxes of the page. // Fill the select list boxes of the page.
if (App.Vars.available_providers.length > 0) { if (App.Vars.available_providers.length > 0) {
$('<optgroup/>', { $('<optgroup label=""/>', {
'label': App.Lang.providers, 'label': App.Lang.providers,
'type': 'providers-group', 'type': 'providers-group',
'html': App.Vars.available_providers.map(function (availableProvider) { 'html': App.Vars.available_providers.map(function (availableProvider) {
@ -1634,7 +1643,7 @@ App.Utils.CalendarDefaultView = (function () {
} }
if (App.Vars.available_services.length > 0) { if (App.Vars.available_services.length > 0) {
$('<optgroup/>', { $('<optgroup label=""/>', {
'label': App.Lang.services, 'label': App.Lang.services,
'type': 'services-group', 'type': 'services-group',
'html': App.Vars.available_services.map((availableService) => 'html': App.Vars.available_services.map((availableService) =>
@ -1649,17 +1658,18 @@ App.Utils.CalendarDefaultView = (function () {
// Check permissions. // Check permissions.
if (App.Vars.role_slug === Backend.DB_SLUG_PROVIDER) { if (App.Vars.role_slug === Backend.DB_SLUG_PROVIDER) {
$('#select-filter-item optgroup:eq(0)') $selectFilterItem
.find('optgroup:eq(0)')
.find('option[value="' + App.Vars.user_id + '"]') .find('option[value="' + App.Vars.user_id + '"]')
.prop('selected', true); .prop('selected', true);
$('#select-filter-item').prop('disabled', true); $selectFilterItem.prop('disabled', true);
} }
if (App.Vars.role_slug === Backend.DB_SLUG_SECRETARY) { if (App.Vars.role_slug === Backend.DB_SLUG_SECRETARY) {
// Remove the providers that are not connected to the secretary. // Remove the providers that are not connected to the secretary.
$('#select-filter-item optgroup:eq(1)').remove(); $selectFilterItem.find('optgroup:eq(1)').remove();
$('#select-filter-item option[type="provider"]').each((index, option) => { $selectFilterItem.find('option[type="provider"]').each((index, option) => {
const provider = App.Vars.secretary_providers.find( const provider = App.Vars.secretary_providers.find(
(secretaryProviderId) => Number($(option).val()) === Number(secretaryProviderId) (secretaryProviderId) => Number($(option).val()) === Number(secretaryProviderId)
); );
@ -1669,65 +1679,62 @@ App.Utils.CalendarDefaultView = (function () {
} }
}); });
if (!$('#select-filter-item option[type="provider"]').length) { if (!$selectFilterItem.find('option[type="provider"]').length) {
$('#select-filter-item optgroup[type="providers-group"]').remove(); $selectFilterItem('optgroup[type="providers-group"]').remove();
} }
} }
// Bind the default event handlers. // Bind the default event handlers.
bindEventHandlers(); addEventListeners();
$('#select-filter-item').trigger('change'); $selectFilterItem.trigger('change');
// Display the edit dialog if an appointment hash is provided. // Display the edit dialog if an appointment hash is provided.
if (App.Vars.edit_appointment) { if (App.Vars.edit_appointment) {
const $dialog = $('#appointments-modal');
const appointment = App.Vars.edit_appointment; const appointment = App.Vars.edit_appointment;
App.Components.resetAppointmentDialog();
$dialog.find('.modal-header h3').text(App.Lang.edit_appointment_title); App.Components.AppointmentsModal.resetModal();
$dialog.find('#appointment-id').val(appointment.id);
$dialog.find('#select-service').val(appointment.id_services).trigger('change'); $appointmentsModal.find('.modal-header h3').text(App.Lang.edit_appointment_title);
$dialog.find('#select-provider').val(appointment.id_users_provider); $appointmentsModal.find('#appointment-id').val(appointment.id);
$appointmentsModal.find('#select-service').val(appointment.id_services).trigger('change');
$appointmentsModal.find('#select-provider').val(appointment.id_users_provider);
// Set the start and end datetime of the appointment. // Set the start and end datetime of the appointment.
const startDatetime = moment(appointment.start_datetime); const startDatetime = moment(appointment.start_datetime);
$dialog.find('#start-datetime').datetimepicker('setDate', startDatetime); $appointmentsModal.find('#start-datetime').datetimepicker('setDate', startDatetime);
const endDatetime = moment(appointment.end_datetime); const endDatetime = moment(appointment.end_datetime);
$dialog.find('#end-datetime').datetimepicker('setDate', endDatetime); $appointmentsModal.find('#end-datetime').datetimepicker('setDate', endDatetime);
const customer = appointment.customer; const customer = appointment.customer;
$dialog.find('#customer-id').val(appointment.id_users_customer); $appointmentsModal.find('#customer-id').val(appointment.id_users_customer);
$dialog.find('#first-name').val(customer.first_name); $appointmentsModal.find('#first-name').val(customer.first_name);
$dialog.find('#last-name').val(customer.last_name); $appointmentsModal.find('#last-name').val(customer.last_name);
$dialog.find('#email').val(customer.email); $appointmentsModal.find('#email').val(customer.email);
$dialog.find('#phone-number').val(customer.phone_number); $appointmentsModal.find('#phone-number').val(customer.phone_number);
$dialog.find('#address').val(customer.address); $appointmentsModal.find('#address').val(customer.address);
$dialog.find('#city').val(customer.city); $appointmentsModal.find('#city').val(customer.city);
$dialog.find('#zip-code').val(customer.zip_code); $appointmentsModal.find('#zip-code').val(customer.zip_code);
$dialog.find('#appointment-location').val(appointment.location); $appointmentsModal.find('#appointment-location').val(appointment.location);
$dialog.find('#appointment-notes').val(appointment.notes); $appointmentsModal.find('#appointment-notes').val(appointment.notes);
$dialog.find('#customer-notes').val(customer.notes); $appointmentsModal.find('#customer-notes').val(customer.notes);
$dialog.modal('show'); $appointmentsModal.modal('show');
$('#calendar').fullCalendar('gotoDate', moment(appointment.start_datetime)); $calendar.fullCalendar('gotoDate', moment(appointment.start_datetime));
} }
if (!$('#select-filter-item option').length) { if (!$selectFilterItem.find('option').length) {
$('#calendar-actions button').prop('disabled', true); $('#calendar-actions button').prop('disabled', true);
} }
// Fine tune the footer's position only for this page. // Fine tune the footer's position only for this page.
if (window.innerHeight < 700) { if (window.innerHeight < 700) {
$('#footer').css('position', 'static'); $footer.css('position', 'static');
} }
// Automatically refresh the calendar page every 10 seconds (without loading animation). // Automatically refresh the calendar page every 10 seconds (without loading animation).
const $calendar = $('#calendar');
const $selectFilterItem = $('#select-filter-item');
setInterval(() => { setInterval(() => {
const calendarView = $calendar.fullCalendar('getView'); const calendarView = $calendar.fullCalendar('getView');