diff --git a/application/controllers/Calendar.php b/application/controllers/Calendar.php index fe8edb27..9c555166 100644 --- a/application/controllers/Calendar.php +++ b/application/controllers/Calendar.php @@ -27,6 +27,7 @@ class Calendar extends EA_Controller { parent::__construct(); $this->load->model('appointments_model'); + $this->load->model('unavailabilities_model'); $this->load->model('customers_model'); $this->load->model('services_model'); $this->load->model('providers_model'); @@ -86,15 +87,35 @@ class Calendar extends EA_Controller { } } + $privileges = $this->roles_model->get_permissions_by_slug($role_slug); + + $available_providers = $this->providers_model->get_available_providers(); + + $available_services = $this->services_model->get_available_services(); + + script_vars([ + 'user_id' => $user_id, + 'role_slug' => $role_slug, + 'date_format' => setting('date_format'), + 'time_format' => setting('time_format'), + 'first_weekday' => setting('first_weekday'), + 'timezones' => $this->timezones->to_array(), + 'privileges' => $privileges, + 'available_providers' => $available_providers, + 'available_services' => $available_services, + 'customers' => [], // TODO: Remove the use of the pre-rendered customer set and only work with asynchronously fetched customer records. + ]); + html_vars([ 'page_title' => lang('calendar'), 'active_menu' => PRIV_APPOINTMENTS, 'user_display_name' => $this->accounts->get_user_display_name($user_id), + 'timezone' => session('timezone'), 'timezones' => $this->timezones->to_array(), - 'privileges' => $this->roles_model->get_permissions_by_slug($role_slug), + 'privileges' => $privileges, 'calendar_view' => request('view', $user['settings']['calendar_view']), - 'available_providers' => $this->providers_model->get_available_providers(), - 'available_services' => $this->services_model->get_available_services(), + 'available_providers' => $available_providers, + 'available_services' => $available_services, 'secretary_providers' => $secretary_providers, 'edit_appointment' => $edit_appointment, 'require_first_name' => setting('require_first_name'), @@ -134,7 +155,7 @@ class Calendar extends EA_Controller { if ($customer_data) { - $customer = json_decode($customer_data, TRUE); + $customer = $customer_data; $required_permissions = ! empty($customer['id']) ? can('add', PRIV_CUSTOMERS) @@ -155,7 +176,7 @@ class Calendar extends EA_Controller { if ($appointment_data) { - $appointment = json_decode($appointment_data, TRUE); + $appointment = $appointment_data; $required_permissions = ! empty($appointment['id']) ? can('add', PRIV_APPOINTMENTS) @@ -270,7 +291,7 @@ class Calendar extends EA_Controller { try { // Check privileges - $unavailable = json_decode(request('unavailable'), TRUE); + $unavailable = request('unavailable'); $required_permissions = ( ! isset($unavailable['id'])) ? can('add', PRIV_APPOINTMENTS) @@ -597,7 +618,7 @@ class Calendar extends EA_Controller { AND is_unavailable = 1 '; - $response['unavailables'] = $this->appointments_model->get($where_clause); + $response['unavailables'] = $this->unavailabilities_model->get($where_clause); } foreach ($response['unavailables'] as &$unavailable) diff --git a/application/views/pages/calendar.php b/application/views/pages/calendar.php index d0cd4f9c..ea1d05e4 100755 --- a/application/views/pages/calendar.php +++ b/application/views/pages/calendar.php @@ -16,6 +16,15 @@ * @var string $timezone * @var string $role_slug * @var array $privileges + * @var array $available_services + * @var array $timezones + * @var array $require_first_name + * @var array $require_last_name + * @var array $require_email + * @var array $require_phone_number + * @var array $require_address + * @var array $require_city + * @var array $require_zip_code */ ?> @@ -33,39 +42,19 @@ - - - - - - - - + + + + + + + + + + + + + @@ -151,11 +140,34 @@ - $timezones]) ?> + $available_services, + 'timezones' => $timezones, + 'require_first_name' => $require_first_name, + 'require_last_name' => $require_last_name, + 'require_email' => $require_email, + 'require_phone_number' => $require_phone_number, + 'require_address' => $require_address, + 'require_city' => $require_city, + 'require_zip_code' => $require_zip_code + ] + ) +?> - - - + $timezones, + 'timezone' => $timezone + ] + ) +?> diff --git a/assets/js/pages/backend_calendar_appointments_modal.js b/assets/js/components/manage_appointments_modal.js similarity index 71% rename from assets/js/pages/backend_calendar_appointments_modal.js rename to assets/js/components/manage_appointments_modal.js index ec43302f..dd3cd689 100755 --- a/assets/js/pages/backend_calendar_appointments_modal.js +++ b/assets/js/components/manage_appointments_modal.js @@ -14,22 +14,18 @@ * * This module implements the appointments modal functionality. * - * @module BackendCalendarAppointmentsModal + * Old Module Name: BackendCalendarAppointmentsModal */ -window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModal || {}; - -(function (exports) { - 'use strict'; - +App.Components.ManageAppointmentsModal = (function () { function updateTimezone() { - var providerId = $('#select-provider').val(); + const providerId = $('#select-provider').val(); - var provider = GlobalVariables.availableProviders.find(function (availableProvider) { + const provider = App.Vars.available_providers.find(function (availableProvider) { return Number(availableProvider.id) === Number(providerId); }); if (provider && provider.timezone) { - $('.provider-timezone').text(GlobalVariables.timezones[provider.timezone]); + $('.provider-timezone').text(App.Vars.timezones[provider.timezone]); } } @@ -37,35 +33,35 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa /** * Event: Manage Appointments Dialog Save Button "Click" * - * Stores the appointment changes or inserts a new appointment depending the dialog mode. + * Stores the appointment changes or inserts a new appointment depending on the dialog mode. */ - $('#manage-appointment #save-appointment').on('click', function () { + $('#manage-appointment #save-appointment').on('click', () => { // Before doing anything the appointment data need to be validated. if (!validateAppointmentForm()) { return; } // Prepare appointment data for AJAX request. - var $dialog = $('#manage-appointment'); + const $dialog = $('#manage-appointment'); // ID must exist on the object in order for the model to update the record and not to perform // an insert operation. - var startDatetime = moment($dialog.find('#start-datetime').datetimepicker('getDate')).format( + const startDatetime = moment($dialog.find('#start-datetime').datetimepicker('getDate')).format( 'YYYY-MM-DD HH:mm:ss' ); - var endDatetime = moment($dialog.find('#end-datetime').datetimepicker('getDate')).format( + const endDatetime = moment($dialog.find('#end-datetime').datetimepicker('getDate')).format( 'YYYY-MM-DD HH:mm:ss' ); - var appointment = { + const appointment = { id_services: $dialog.find('#select-service').val(), id_users_provider: $dialog.find('#select-provider').val(), start_datetime: startDatetime, end_datetime: endDatetime, location: $dialog.find('#appointment-location').val(), notes: $dialog.find('#appointment-notes').val(), - is_unavailable: false + is_unavailable: Number(false) }; if ($dialog.find('#appointment-id').val() !== '') { @@ -73,7 +69,7 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa appointment.id = $dialog.find('#appointment-id').val(); } - var customer = { + const customer = { first_name: $dialog.find('#first-name').val(), last_name: $dialog.find('#last-name').val(), email: $dialog.find('#email').val(), @@ -91,7 +87,7 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa } // Define success callback. - var successCallback = function (response) { + const successCallback = function (response) { // Display success message to the user. Backend.displayNotification(App.Lang.appointment_saved); @@ -102,35 +98,36 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa }; // Define error callback. - var errorCallback = function () { + const errorCallback = function () { $dialog.find('.modal-message').text(App.Lang.service_communication_error); $dialog.find('.modal-message').addClass('alert-danger').removeClass('d-none'); $dialog.find('.modal-body').scrollTop(0); }; // Save appointment data. - BackendCalendarApi.saveAppointment(appointment, customer, successCallback, errorCallback); + App.Http.Calendar.saveAppointment(appointment, customer, successCallback, errorCallback); }); /** * Event: Insert Appointment Button "Click" * - * When the user presses this button, the manage appointment dialog opens and lets the user to - * create a new appointment. + * When the user presses this button, the manage appointment dialog opens and lets the user create a new + * appointment. */ - $('#insert-appointment').on('click', function () { + $('#insert-appointment').on('click', () => { $('.popover').remove(); - BackendCalendarAppointmentsModal.resetAppointmentDialog(); - var $dialog = $('#manage-appointment'); + resetAppointmentDialog(); + + const $dialog = $('#manage-appointment'); // Set the selected filter item and find the next appointment time as the default modal values. if ($('#select-filter-item option:selected').attr('type') === 'provider') { - var providerId = $('#select-filter-item').val(); + const providerId = $('#select-filter-item').val(); - var providers = GlobalVariables.availableProviders.filter(function (provider) { - return Number(provider.id) === Number(providerId); - }); + const providers = App.Vars.available_providers.filter( + (provider) => Number(provider.id) === Number(providerId) + ); if (providers.length) { $dialog.find('#select-service').val(providers[0].services[0]).trigger('change'); @@ -144,17 +141,17 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa $dialog.find('#select-service option:first').prop('selected', true).trigger('change'); } - var serviceId = $dialog.find('#select-service').val(); + const serviceId = $dialog.find('#select-service').val(); - var service = GlobalVariables.availableServices.find(function (availableService) { - return Number(availableService.id) === Number(serviceId); - }); + const service = App.Vars.available_services.find( + (availableService) => Number(availableService.id) === Number(serviceId) + ); - var duration = service ? service.duration : 60; + const duration = service ? service.duration : 60; - var startMoment = moment(); + const startMoment = moment(); - var currentMin = parseInt(startMoment.format('mm')); + const currentMin = parseInt(startMoment.format('mm')); if (currentMin > 0 && currentMin < 15) { startMoment.set({minutes: 15}); @@ -168,14 +165,15 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa $dialog .find('#start-datetime') - .val(GeneralFunctions.formatDate(startMoment.toDate(), GlobalVariables.dateFormat, true)); + .val(App.Utils.Date.format(startMoment.toDate(), App.Vars.date_format, App.Vars.time_format, true)); $dialog .find('#end-datetime') .val( - GeneralFunctions.formatDate( + App.Utils.Date.format( startMoment.add(duration, 'minutes').toDate(), - GlobalVariables.dateFormat, + App.Vars.date_format, + App.Vars.time_format, true ) ); @@ -188,9 +186,11 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa /** * Event: Pick Existing Customer Button "Click" + * + * @param {jQuery.Event} */ - $('#select-customer').on('click', function () { - var $list = $('#existing-customers-list'); + $('#select-customer').on('click', (event) => { + const $list = $('#existing-customers-list'); if (!$list.is(':visible')) { $(this).find('span').text(App.Lang.hide); @@ -198,7 +198,7 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa $list.slideDown('slow'); $('#filter-existing-customers').fadeIn('slow'); $('#filter-existing-customers').val(''); - GlobalVariables.customers.forEach(function (customer) { + App.Vars.customers.forEach(function (customer) { $('
', { 'data-id': customer.id, 'text': customer.first_name + ' ' + customer.last_name @@ -207,17 +207,17 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa } else { $list.slideUp('slow'); $('#filter-existing-customers').fadeOut('slow'); - $(this).find('span').text(App.Lang.select); + $(event.target).find('span').text(App.Lang.select); } }); /** * Event: Select Existing Customer From List "Click" */ - $('#manage-appointment').on('click', '#existing-customers-list div', function () { - var customerId = $(this).attr('data-id'); + $('#manage-appointment').on('click', '#existing-customers-list div', (event) => { + const customerId = $(event.target).attr('data-id'); - var customer = GlobalVariables.customers.find(function (customer) { + const customer = App.Vars.customers.find(function (customer) { return Number(customer.id) === Number(customerId); }); @@ -236,66 +236,58 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa $('#select-customer').trigger('click'); // Hide the list. }); - var filterExistingCustomersTimeout = null; + let filterExistingCustomersTimeout = null; /** * Event: Filter Existing Customers "Change" */ - $('#filter-existing-customers').on('keyup', function () { + $('#filter-existing-customers').on('keyup', (event) => { if (filterExistingCustomersTimeout) { clearTimeout(filterExistingCustomersTimeout); } - var key = $(this).val().toLowerCase(); + const keyword = $(event.target).val().toLowerCase(); filterExistingCustomersTimeout = setTimeout(function () { - var $list = $('#existing-customers-list'); - - var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_customers'; - - var data = { - csrf_token: GlobalVariables.csrfToken, - key: key - }; + const $list = $('#existing-customers-list'); $('#loading').css('visibility', 'hidden'); - // Try to get the updated customer list. - $.post(url, data) - .done(function (response) { + App.Http.Customers.search(keyword, 50) + .done((response) => { $list.empty(); - response.forEach(function (customer) { + response.forEach((customer) => { $('
', { 'data-id': customer.id, 'text': customer.first_name + ' ' + customer.last_name }).appendTo($list); // Verify if this customer is on the old customer list. - var result = GlobalVariables.customers.filter(function (globalVariablesCustomer) { - return Number(globalVariablesCustomer.id) === Number(customer.id); + const result = App.Vars.customers.filter((existingCustomer) => { + return Number(existingCustomer.id) === Number(customer.id); }); // Add it to the customer list. if (!result.length) { - GlobalVariables.customers.push(customer); + App.Vars.customers.push(customer); } }); }) - .fail(function (jqXHR, textStatus, errorThrown) { + .fail(() => { // If there is any error on the request, search by the local client database. $list.empty(); - GlobalVariables.customers.forEach(function (customer, index) { + App.Vars.customers.forEach(function (customer, index) { if ( - customer.first_name.toLowerCase().indexOf(key) !== -1 || - customer.last_name.toLowerCase().indexOf(key) !== -1 || - customer.email.toLowerCase().indexOf(key) !== -1 || - customer.phone_number.toLowerCase().indexOf(key) !== -1 || - customer.address.toLowerCase().indexOf(key) !== -1 || - customer.city.toLowerCase().indexOf(key) !== -1 || - customer.zip_code.toLowerCase().indexOf(key) !== -1 || - customer.notes.toLowerCase().indexOf(key) !== -1 + customer.first_name.toLowerCase().indexOf(keyword) !== -1 || + customer.last_name.toLowerCase().indexOf(keyword) !== -1 || + customer.email.toLowerCase().indexOf(keyword) !== -1 || + customer.phone_number.toLowerCase().indexOf(keyword) !== -1 || + customer.address.toLowerCase().indexOf(keyword) !== -1 || + customer.city.toLowerCase().indexOf(keyword) !== -1 || + customer.zip_code.toLowerCase().indexOf(keyword) !== -1 || + customer.notes.toLowerCase().indexOf(keyword) !== -1 ) { $('
', { 'data-id': customer.id, @@ -316,35 +308,32 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa * When the user clicks on a service, its available providers should become visible. Also we need to * update the start and end time of the appointment. */ - $('#select-service').on('change', function () { - var serviceId = $('#select-service').val(); + $('#select-service').on('change', () => { + const serviceId = $('#select-service').val(); $('#select-provider').empty(); // Automatically update the service duration. - var service = GlobalVariables.availableServices.find(function (availableService) { + const service = App.Vars.available_services.find((availableService) => { return Number(availableService.id) === Number(serviceId); }); - var duration = service ? service.duration : 60; + const duration = service ? service.duration : 60; - var start = $('#start-datetime').datetimepicker('getDate'); + const start = $('#start-datetime').datetimepicker('getDate'); $('#end-datetime').datetimepicker('setDate', new Date(start.getTime() + duration * 60000)); // Update the providers select box. - GlobalVariables.availableProviders.forEach(function (provider) { - provider.services.forEach(function (providerServiceId) { - if ( - GlobalVariables.user.role_slug === Backend.DB_SLUG_PROVIDER && - Number(provider.id) !== GlobalVariables.user.id - ) { + App.Vars.available_providers.forEach((provider) => { + provider.services.forEach((providerServiceId) => { + if (App.Vars.role_slug === Backend.DB_SLUG_PROVIDER && Number(provider.id) !== App.Vars.user.id) { return; // continue } if ( - GlobalVariables.user.role_slug === Backend.DB_SLUG_SECRETARY && - GlobalVariables.secretaryProviders.indexOf(provider.id) === -1 + App.Vars.role_slug === Backend.DB_SLUG_SECRETARY && + App.Vars.secretaryProviders.indexOf(provider.id) === -1 ) { return; // continue } @@ -362,14 +351,14 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa /** * Event: Provider "Change" */ - $('#select-provider').on('change', function () { + $('#select-provider').on('change', () => { updateTimezone(); }); /** * Event: Enter New Customer Button "Click" */ - $('#new-customer').on('click', function () { + $('#new-customer').on('click', () => { $('#manage-appointment') .find( '#customer-id, #first-name, #last-name, #email, ' + @@ -385,8 +374,8 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa * This method resets the manage appointment dialog modal to its initial state. After that you can make * any modification might be necessary in order to bring the dialog to the desired state. */ - exports.resetAppointmentDialog = function () { - var $dialog = $('#manage-appointment'); + function resetAppointmentDialog() { + const $dialog = $('#manage-appointment'); // Empty form fields. $dialog.find('input, textarea').val(''); @@ -395,21 +384,19 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa // Prepare service and provider select boxes. $dialog.find('#select-service').val($dialog.find('#select-service').eq(0).attr('value')); - // Fill the providers listbox with providers that can serve the appointment's - // service and then select the user's provider. + // Fill the providers list box with providers that can serve the appointment's service and then select the + // user's provider. $dialog.find('#select-provider').empty(); - GlobalVariables.availableProviders.forEach(function (provider, index) { - var canProvideService = false; + App.Vars.available_providers.forEach((provider) => { + const serviceId = $dialog.find('#select-service').val(); - var serviceId = $dialog.find('#select-service').val(); - - var canProvideService = - provider.services.filter(function (providerServiceId) { + const canProvideService = + provider.services.filter((providerServiceId) => { return Number(providerServiceId) === Number(serviceId); }).length > 0; if (canProvideService) { - // Add the provider to the listbox. + // Add the provider to the list box. $dialog .find('#select-provider') .append(new Option(provider.first_name + ' ' + provider.last_name, provider.id)); @@ -423,19 +410,17 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa // Setup start and datetimepickers. // Get the selected service duration. It will be needed in order to calculate the appointment end datetime. - var serviceId = $dialog.find('#select-service').val(); + const serviceId = $dialog.find('#select-service').val(); - var service = GlobalVariables.availableServices.forEach(function (service) { - return Number(service.id) === Number(serviceId); - }); + const service = App.Vars.available_services.forEach((service) => Number(service.id) === Number(serviceId)); - var duration = service ? service.duration : 0; + const duration = service ? service.duration : 0; - var startDatetime = new Date(); - var endDatetime = moment().add(duration, 'minutes').toDate(); - var dateFormat; + const startDatetime = new Date(); + const endDatetime = moment().add(duration, 'minutes').toDate(); + let dateFormat; - switch (GlobalVariables.dateFormat) { + switch (App.Vars.date_format) { case 'DMY': dateFormat = 'dd/mm/yy'; break; @@ -446,15 +431,16 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa dateFormat = 'yy/mm/dd'; break; default: - throw new Error('Invalid GlobalVariables.dateFormat value.'); + throw new Error('Invalid App.Vars.date_format value.'); } - var firstWeekDay = GlobalVariables.firstWeekday; - var firstWeekDayNumber = GeneralFunctions.getWeekDayId(firstWeekDay); + const firstWeekDay = App.Vars.first_weekday; + + const firstWeekDayNumber = App.Utils.Date.getWeekdayId(firstWeekDay); $dialog.find('#start-datetime').datetimepicker({ dateFormat: dateFormat, - timeFormat: GlobalVariables.timeFormat === 'regular' ? 'h:mm tt' : 'HH:mm', + timeFormat: App.Vars.time_format === 'regular' ? 'h:mm tt' : 'HH:mm', // Translation dayNames: [ @@ -508,14 +494,14 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa minuteText: App.Lang.minutes, firstDay: firstWeekDayNumber, onClose: function () { - var serviceId = $('#select-service').val(); + const serviceId = $('#select-service').val(); // Automatically update the #end-datetime DateTimePicker based on service duration. - var service = GlobalVariables.availableServices.find(function (availableService) { - return Number(availableService.id) === Number(serviceId); - }); + const service = App.Vars.available_services.find( + (availableService) => Number(availableService.id) === Number(serviceId) + ); - var start = $('#start-datetime').datetimepicker('getDate'); + const start = $('#start-datetime').datetimepicker('getDate'); $('#end-datetime').datetimepicker('setDate', new Date(start.getTime() + service.duration * 60000)); } }); @@ -523,7 +509,7 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa $dialog.find('#end-datetime').datetimepicker({ dateFormat: dateFormat, - timeFormat: GlobalVariables.timeFormat === 'regular' ? 'h:mm tt' : 'HH:mm', + timeFormat: App.Vars.time_format === 'regular' ? 'h:mm tt' : 'HH:mm', // Translation dayNames: [ @@ -578,16 +564,17 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa firstDay: firstWeekDayNumber }); $dialog.find('#end-datetime').datetimepicker('setDate', endDatetime); - }; + } /** - * Validate the manage appointment dialog data. Validation checks need to - * run every time the data are going to be saved. + * Validate the manage appointment dialog data. + * + * Validation checks need to run every time the data are going to be saved. * * @return {Boolean} Returns the validation result. */ function validateAppointmentForm() { - var $dialog = $('#manage-appointment'); + const $dialog = $('#manage-appointment'); // Reset previous validation css formatting. $dialog.find('.is-invalid').removeClass('is-invalid'); @@ -595,9 +582,9 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa try { // Check required fields. - var missingRequiredField = false; + let missingRequiredField = false; - $dialog.find('.required').each(function (index, requiredField) { + $dialog.find('.required').each((index, requiredField) => { if ($(requiredField).val() === '' || $(requiredField).val() === null) { $(requiredField).addClass('is-invalid'); missingRequiredField = true; @@ -609,14 +596,14 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa } // Check email address. - if (!GeneralFunctions.validateEmail($dialog.find('#email').val())) { + if (!App.Utils.Validation.email($dialog.find('#email').val())) { $dialog.find('#email').addClass('is-invalid'); throw new Error(App.Lang.invalid_email); } // Check appointment start and end time. - var start = $('#start-datetime').datetimepicker('getDate'); - var end = $('#end-datetime').datetimepicker('getDate'); + const start = $('#start-datetime').datetimepicker('getDate'); + const end = $('#end-datetime').datetimepicker('getDate'); if (start > end) { $dialog.find('#start-datetime, #end-datetime').addClass('is-invalid'); throw new Error(App.Lang.start_date_before_end_error); @@ -629,7 +616,13 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa } } - exports.initialize = function () { + function initialize() { bindEventHandlers(); + } + + return { + resetAppointmentDialog, + bindEventHandlers, + initialize }; -})(window.BackendCalendarAppointmentsModal); +})(); diff --git a/assets/js/pages/backend_calendar_unavailability_events_modal.js b/assets/js/components/manage_unavailabilities_modal.js similarity index 78% rename from assets/js/pages/backend_calendar_unavailability_events_modal.js rename to assets/js/components/manage_unavailabilities_modal.js index 38a086ed..66c5ef2d 100755 --- a/assets/js/pages/backend_calendar_unavailability_events_modal.js +++ b/assets/js/components/manage_unavailabilities_modal.js @@ -14,25 +14,21 @@ * * This module implements the unavailability events modal functionality. * - * @module BackendCalendarUnavailabilityEventsModal + * Old Module Name: BackendCalendarUnavailabilityEventsModal */ -window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavailabilityEventsModal || {}; - -(function (exports) { - 'use strict'; - +App.Components.ManageUnavailabilitiesModal = (function () { function bindEventHandlers() { /** * Event: Manage Unavailable Dialog Save Button "Click" * * Stores the unavailable period changes or inserts a new record. */ - $('#manage-unavailable #save-unavailable').on('click', function () { - var $dialog = $('#manage-unavailable'); + $('#manage-unavailable #save-unavailable').on('click', () => { + const $dialog = $('#manage-unavailable'); $dialog.find('.modal-message').addClass('d-none'); $dialog.find('.is-invalid').removeClass('is-invalid'); - var startMoment = moment($dialog.find('#unavailable-start').datetimepicker('getDate')); + const startMoment = moment($dialog.find('#unavailable-start').datetimepicker('getDate')); if (!startMoment.isValid()) { $dialog.find('#unavailable-start').addClass('is-invalid'); @@ -40,7 +36,7 @@ window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavaila return; } - var endMoment = moment($dialog.find('#unavailable-end').datetimepicker('getDate')); + const endMoment = moment($dialog.find('#unavailable-end').datetimepicker('getDate')); if (!endMoment.isValid()) { $dialog.find('#unavailable-end').addClass('is-invalid'); @@ -62,7 +58,7 @@ window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavaila } // Unavailable period records go to the appointments table. - var unavailable = { + const unavailable = { start_datetime: startMoment.format('YYYY-MM-DD HH:mm:ss'), end_datetime: endMoment.format('YYYY-MM-DD HH:mm:ss'), notes: $dialog.find('#unavailable-notes').val(), @@ -74,7 +70,7 @@ window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavaila unavailable.id = $dialog.find('#unavailable-id').val(); } - var successCallback = function () { + const successCallback = () => { // Display success message to the user. Backend.displayNotification(App.Lang.unavailable_saved); @@ -86,7 +82,7 @@ window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavaila $('#select-filter-item').trigger('change'); }; - BackendCalendarApi.saveUnavailable(unavailable, successCallback, null); + App.Http.Calendar.saveUnavailable(unavailable, successCallback, null); }); /** @@ -95,14 +91,15 @@ window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavaila * When the user clicks this button a popup dialog appears and the use can set a time period where * he cannot accept any appointments. */ - $('#insert-unavailable').on('click', function () { - BackendCalendarUnavailabilityEventsModal.resetUnavailableDialog(); - var $dialog = $('#manage-unavailable'); + $('#insert-unavailable').on('click', () => { + resetUnavailableDialog(); + + const $dialog = $('#manage-unavailable'); // Set the default datetime values. - var startMoment = moment(); + const startMoment = moment(); - var currentMin = parseInt(startMoment.format('mm')); + const currentMin = parseInt(startMoment.format('mm')); if (currentMin > 0 && currentMin < 15) { startMoment.set({minutes: 15}); @@ -120,11 +117,16 @@ window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavaila $dialog .find('#unavailable-start') - .val(GeneralFunctions.formatDate(startMoment.toDate(), GlobalVariables.dateFormat, true)); + .val(App.Utils.Date.format(startMoment.toDate(), App.Vars.date_format, App.Vars.time_format, true)); $dialog .find('#unavailable-end') .val( - GeneralFunctions.formatDate(startMoment.add(1, 'hour').toDate(), GlobalVariables.dateFormat, true) + App.Utils.Date.format( + startMoment.add(1, 'hour').toDate(), + App.Vars.date_format, + App.Vars.time_format, + true + ) ); $dialog.find('.modal-header h3').text(App.Lang.new_unavailable_title); $dialog.modal('show'); @@ -137,19 +139,24 @@ window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavaila * Reset the "#manage-unavailable" dialog. Use this method to bring the dialog to the initial state * before it becomes visible to the user. */ - exports.resetUnavailableDialog = function () { - var $dialog = $('#manage-unavailable'); + function resetUnavailableDialog() { + const $dialog = $('#manage-unavailable'); $dialog.find('#unavailable-id').val(''); // Set default time values - var start = GeneralFunctions.formatDate(moment().toDate(), GlobalVariables.dateFormat, true); + const start = App.Utils.Date.format(moment().toDate(), App.Vars.date_format, App.Vars.time_format, true); - var end = GeneralFunctions.formatDate(moment().add(1, 'hour').toDate(), GlobalVariables.dateFormat, true); + const end = App.Utils.Date.format( + moment().add(1, 'hour').toDate(), + App.Vars.date_format, + App.Vars.time_format, + true + ); - var dateFormat; + let dateFormat; - switch (GlobalVariables.dateFormat) { + switch (App.Vars.date_format) { case 'DMY': dateFormat = 'dd/mm/yy'; break; @@ -161,12 +168,13 @@ window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavaila break; } - var fDay = GlobalVariables.firstWeekday; - var fDaynum = GeneralFunctions.getWeekDayId(fDay); + const firstWeekday = App.Vars.first_weekday; + + const firstWeekdayId = App.Utils.Date.getWeekdayId(firstWeekday); $dialog.find('#unavailable-start').datetimepicker({ dateFormat: dateFormat, - timeFormat: GlobalVariables.timeFormat === 'regular' ? 'h:mm tt' : 'HH:mm', + timeFormat: App.Vars.time_format === 'regular' ? 'h:mm tt' : 'HH:mm', // Translation dayNames: [ @@ -218,13 +226,13 @@ window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavaila timeText: App.Lang.time, hourText: App.Lang.hour, minuteText: App.Lang.minutes, - firstDay: fDaynum + firstDay: firstWeekdayId }); $dialog.find('#unavailable-start').val(start); $dialog.find('#unavailable-end').datetimepicker({ dateFormat: dateFormat, - timeFormat: GlobalVariables.timeFormat === 'regular' ? 'h:mm tt' : 'HH:mm', + timeFormat: App.Vars.time_format === 'regular' ? 'h:mm tt' : 'HH:mm', // Translation dayNames: [ @@ -276,23 +284,28 @@ window.BackendCalendarUnavailabilityEventsModal = window.BackendCalendarUnavaila timeText: App.Lang.time, hourText: App.Lang.hour, minuteText: App.Lang.minutes, - firstDay: fDaynum + firstDay: firstWeekdayId }); $dialog.find('#unavailable-end').val(end); // Clear the unavailable notes field. $dialog.find('#unavailable-notes').val(''); - }; + } - exports.initialize = function () { - var $unavailabilityProvider = $('#unavailable-provider'); + function initialize() { + const $unavailabilityProvider = $('#unavailable-provider'); - for (var index in GlobalVariables.availableProviders) { - var provider = GlobalVariables.availableProviders[index]; + for (const index in App.Vars.available_providers) { + const provider = App.Vars.available_providers[index]; $unavailabilityProvider.append(new Option(provider.first_name + ' ' + provider.last_name, provider.id)); } bindEventHandlers(); + } + + return { + resetUnavailableDialog, + initialize }; -})(window.BackendCalendarUnavailabilityEventsModal); +})(); diff --git a/assets/js/pages/backend_calendar_api.js b/assets/js/http/calendar_http_client.js similarity index 58% rename from assets/js/pages/backend_calendar_api.js rename to assets/js/http/calendar_http_client.js index 4b0c1958..fac779f8 100755 --- a/assets/js/pages/backend_calendar_api.js +++ b/assets/js/http/calendar_http_client.js @@ -10,52 +10,46 @@ * ---------------------------------------------------------------------------- */ /** - * Backend Calendar API + * Calendar HTTP Client * - * This module implements the AJAX requests for the calendar page. - * - * @module BackendCalendarApi + * Old Module Name: BackendCalendarApi */ -window.BackendCalendarApi = window.BackendCalendarApi || {}; - -(function (exports) { - 'use strict'; - +App.Http.Calendar = (function () { /** * Save Appointment * * This method stores the changes of an already registered appointment into the database, via an ajax call. * - * @param {Object} appointment Contain the new appointment data. The ID of the appointment MUST be already included. + * @param {Object} appointment Contain the new appointment data. The ID of the appointment must be already included. * The rest values must follow the database structure. * @param {Object} [customer] Optional, contains the customer data. * @param {Function} [successCallback] Optional, if defined, this function is going to be executed on post success. * @param {Function} [errorCallback] Optional, if defined, this function is going to be executed on post failure. */ - exports.saveAppointment = function (appointment, customer, successCallback, errorCallback) { - var url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_save_appointment'; + function saveAppointment(appointment, customer, successCallback, errorCallback) { + const url = App.Utils.Url.siteUrl('calendar/ajax_save_appointment'); - var data = { - csrf_token: GlobalVariables.csrfToken, - appointment_data: JSON.stringify(appointment) + const data = { + csrf_token: App.Vars.csrf_token, + appointment_data: appointment }; if (customer) { - data.customer_data = JSON.stringify(customer); + data.customer_data = customer; } - $.post(url, data) - .done(function (response) { + return $.post(url, data) + .done((response) => { if (successCallback) { successCallback(response); } }) - .fail(function (jqXHR, textStatus, errorThrown) { + .fail(() => { if (errorCallback) { errorCallback(); } }); - }; + } /** * Save unavailable period to database. @@ -64,26 +58,26 @@ window.BackendCalendarApi = window.BackendCalendarApi || {}; * @param {Function} successCallback The ajax success callback function. * @param {Function} errorCallback The ajax failure callback function. */ - exports.saveUnavailable = function (unavailable, successCallback, errorCallback) { - var url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_save_unavailable'; + function saveUnavailable(unavailable, successCallback, errorCallback) { + const url = App.Utils.Url.siteUrl('calendar/ajax_save_unavailable'); - var data = { - csrf_token: GlobalVariables.csrfToken, - unavailable: JSON.stringify(unavailable) + const data = { + csrf_token: App.Vars.csrf_token, + unavailable: unavailable }; - $.post(url, data) - .done(function (response) { + return $.post(url, data) + .done((response) => { if (successCallback) { successCallback(response); } }) - .fail(function (jqXHR, textStatus, errorThrown) { + .fail(() => { if (errorCallback) { errorCallback(); } }); - }; + } /** * Save working plan exception of work to database. @@ -94,54 +88,55 @@ window.BackendCalendarApi = window.BackendCalendarApi || {}; * @param {Function} successCallback The ajax success callback function. * @param {Function} errorCallback The ajax failure callback function. */ - exports.saveWorkingPlanException = function ( - date, - workingPlanException, - providerId, - successCallback, - errorCallback - ) { - var url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_save_working_plan_exception'; + function saveWorkingPlanException(date, workingPlanException, providerId, successCallback, errorCallback) { + const url = App.Utils.Url.siteUrl('calendar/ajax_save_working_plan_exception'); - var data = { - csrf_token: GlobalVariables.csrfToken, + const data = { + csrf_token: App.Vars.csrf_token, date: date, working_plan_exception: workingPlanException, provider_id: providerId }; - $.post(url, data) - .done(function (response) { + return $.post(url, data) + .done((response) => { if (successCallback) { successCallback(response); } }) - .fail(function (jqXHR, textStatus, errorThrown) { + .fail(() => { if (errorCallback) { errorCallback(); } }); - }; + } - exports.deleteWorkingPlanException = function (date, providerId, successCallback, errorCallback) { - var url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_delete_working_plan_exception'; + function deleteWorkingPlanException(date, providerId, successCallback, errorCallback) { + const url = App.Utils.Url.siteUrl('calendar/ajax_delete_working_plan_exception'); - var data = { - csrf_token: GlobalVariables.csrfToken, + const data = { + csrf_token: App.Vars.csrf_token, date: date, provider_id: providerId }; - $.post(url, data) - .done(function (response) { + return $.post(url, data) + .done((response) => { if (successCallback) { successCallback(response); } }) - .fail(function (jqXHR, textStatus, errorThrown) { + .fail(() => { if (errorCallback) { errorCallback(); } }); + } + + return { + saveAppointment, + saveUnavailable, + saveWorkingPlanException, + deleteWorkingPlanException }; -})(window.BackendCalendarApi); +})(); diff --git a/assets/js/pages/backend_calendar.js b/assets/js/pages/calendar.js similarity index 68% rename from assets/js/pages/backend_calendar.js rename to assets/js/pages/calendar.js index 1dc0ca36..36e7de42 100755 --- a/assets/js/pages/backend_calendar.js +++ b/assets/js/pages/calendar.js @@ -10,27 +10,21 @@ * ---------------------------------------------------------------------------- */ /** - * Backend Calendar + * Calendar Page * * This module contains functions that are used by the backend calendar page. - * - * @module BackendCalendar */ -window.BackendCalendar = window.BackendCalendar || {}; - -(function (exports) { - 'use strict'; - +App.Pages.Calendar = (function () { /** * Bind common event handlers. */ function bindEventHandlers() { - var $calendarPage = $('#calendar-page'); + const $calendarPage = $('#calendar-page'); - $calendarPage.on('click', '#toggle-fullscreen', function () { - var $toggleFullscreen = $(this); - var element = document.documentElement; - var isFullScreen = document.fullScreenElement || document.mozFullScreen || document.webkitIsFullScreen; + $calendarPage.on('click', '#toggle-fullscreen', (event) => { + const $toggleFullscreen = $(event.target); + const element = document.documentElement; + const isFullScreen = document.fullScreenElement || document.mozFullScreen || document.webkitIsFullScreen; if (isFullScreen) { // Exit fullscreen mode. @@ -60,10 +54,10 @@ window.BackendCalendar = window.BackendCalendar || {}; } }); - $('#insert-working-plan-exception').on('click', function () { - var providerId = $('#select-filter-item').val(); + $('#insert-working-plan-exception').on('click', () => { + const providerId = $('#select-filter-item').val(); - var provider = GlobalVariables.availableProviders.find(function (availableProvider) { + const provider = App.Vars.available_providers.find((availableProvider) => { return Number(availableProvider.id) === Number(providerId); }); @@ -71,19 +65,19 @@ window.BackendCalendar = window.BackendCalendar || {}; throw new Error('Provider could not be found: ' + providerId); } - App.Components.WorkingPlanExceptionsModal.add().done(function (date, workingPlanException) { - var successCallback = function () { + App.Components.WorkingPlanExceptionsModal.add().done((date, workingPlanException) => { + const successCallback = () => { Backend.displayNotification(App.Lang.working_plan_exception_saved); - var workingPlanExceptions = JSON.parse(provider.settings.working_plan_exceptions) || {}; + const workingPlanExceptions = JSON.parse(provider.settings.working_plan_exceptions) || {}; workingPlanExceptions[date] = workingPlanException; - for (var index in GlobalVariables.availableProviders) { - var availableProvider = GlobalVariables.availableProviders[index]; + for (let index in App.Vars.available_providers) { + const availableProvider = App.Vars.available_providers[index]; if (Number(availableProvider.id) === Number(providerId)) { - GlobalVariables.availableProviders[index].settings.working_plan_exceptions = + App.Vars.available_providers[index].settings.working_plan_exceptions = JSON.stringify(workingPlanExceptions); break; } @@ -92,7 +86,7 @@ window.BackendCalendar = window.BackendCalendar || {}; $('#select-filter-item').trigger('change'); // Update the calendar. }; - BackendCalendarApi.saveWorkingPlanException( + App.Http.Calendar.saveWorkingPlanException( date, workingPlanException, providerId, @@ -111,18 +105,26 @@ window.BackendCalendar = window.BackendCalendar || {}; * * @param {String} view Optional (default), the calendar view to be loaded. */ - exports.initialize = function (view) { - BackendCalendarGoogleSync.initialize(); - BackendCalendarAppointmentsModal.initialize(); - BackendCalendarUnavailabilityEventsModal.initialize(); + function initialize(view) { + App.Utils.CalendarGoogleSync.initialize(); + + App.Components.ManageAppointmentsModal.initialize(); + + App.Components.ManageUnavailabilitiesModal.initialize(); // Load and initialize the calendar view. if (view === 'table') { - BackendCalendarTableView.initialize(); + App.Utils.CalendarTableView.initialize(); } else { - BackendCalendarDefaultView.initialize(); + App.Utils.CalendarDefaultView.initialize(); } bindEventHandlers(); + } + + document.addEventListener('DOMContentLoaded', initialize); + + return { + initialize }; -})(window.BackendCalendar); +})(); diff --git a/assets/js/pages/backend_calendar_default_view.js b/assets/js/utils/calendar_default_view.js similarity index 81% rename from assets/js/pages/backend_calendar_default_view.js rename to assets/js/utils/calendar_default_view.js index ca4b0ee1..656060cc 100755 --- a/assets/js/pages/backend_calendar_default_view.js +++ b/assets/js/utils/calendar_default_view.js @@ -10,37 +10,30 @@ * ---------------------------------------------------------------------------- */ /** - * Backend Calendar + * Calendar Default View * * This module implements the default calendar view of backend. * - * @module BackendCalendarDefaultView + * Old Name: BackendCalendarDefaultView */ -window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; - -(function (exports) { - 'use strict'; - - // Constants - var FILTER_TYPE_PROVIDER = 'provider'; - var FILTER_TYPE_SERVICE = 'service'; - - // Variables - var lastFocusedEventData; // Contains event data for later use. +App.Utils.CalendarDefaultView = (function () { + const FILTER_TYPE_PROVIDER = 'provider'; + const FILTER_TYPE_SERVICE = 'service'; + let lastFocusedEventData; // Contains event data for later use. /** * Bind event handlers for the calendar view. */ function bindEventHandlers() { - var $calendarPage = $('#calendar-page'); + const $calendarPage = $('#calendar-page'); /** * Event: Reload Button "Click" * - * When the user clicks the reload button an 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', function () { - var calendarView = $('#calendar').fullCalendar('getView'); + $('#reload-appointments').on('click', () => { + const calendarView = $('#calendar').fullCalendar('getView'); refreshCalendarAppointments( $('#calendar'), @@ -56,8 +49,8 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; * * Hides the open popover element. */ - $calendarPage.on('click', '.close-popover', function () { - $(this).parents('.popover').popover('dispose'); + $calendarPage.on('click', '.close-popover', (event) => { + $(event.target).parents('.popover').popover('dispose'); }); /** @@ -65,31 +58,31 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; * * Enables the edit dialog of the selected calendar event. */ - $calendarPage.on('click', '.edit-popover', function () { - $(this).parents('.popover').popover('dispose'); + $calendarPage.on('click', '.edit-popover', () => { + $(event.target).parents('.popover').popover('dispose'); - var $dialog; - var startMoment; - var endMoment; + let $dialog; + let startMoment; + let endMoment; if (lastFocusedEventData.data.workingPlanException) { - var date = lastFocusedEventData.data.date; - var workingPlanException = lastFocusedEventData.data.workingPlanException; - var provider = lastFocusedEventData.data.provider; + const date = lastFocusedEventData.data.date; + const workingPlanException = lastFocusedEventData.data.workingPlanException; + const provider = lastFocusedEventData.data.provider; App.Components.WorkingPlanExceptionsModal.edit(date, workingPlanException).done(function ( date, workingPlanException ) { - var successCallback = function () { + const successCallback = function () { Backend.displayNotification(App.Lang.working_plan_exception_saved); - var workingPlanExceptions = JSON.parse(provider.settings.working_plan_exceptions) || {}; + const workingPlanExceptions = JSON.parse(provider.settings.working_plan_exceptions) || {}; workingPlanExceptions[date] = workingPlanException; - for (var index in GlobalVariables.availableProviders) { - var availableProvider = GlobalVariables.availableProviders[index]; + for (const index in App.Vars.available_providers) { + const availableProvider = App.Vars.available_providers[index]; if (Number(availableProvider.id) === Number(provider.id)) { availableProvider.settings.working_plan_exceptions = @@ -101,7 +94,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#select-filter-item').trigger('change'); // Update the calendar. }; - BackendCalendarApi.saveWorkingPlanException( + App.Http.Calendar.saveWorkingPlanException( date, workingPlanException, provider.id, @@ -110,10 +103,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; ); }); } else if (!lastFocusedEventData.data.is_unavailable) { - var appointment = lastFocusedEventData.data; + const appointment = lastFocusedEventData.data; $dialog = $('#manage-appointment'); - BackendCalendarAppointmentsModal.resetAppointmentDialog(); + App.Components.ManageAppointmentsModal.resetAppointmentDialog(); // Apply appointment data and show modal dialog. $dialog.find('.modal-header h3').text(App.Lang.edit_appointment_title); @@ -128,7 +121,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; endMoment = moment(appointment.end_datetime); $dialog.find('#end-datetime').datetimepicker('setDate', endMoment.toDate()); - var customer = appointment.customer; + const customer = appointment.customer; $dialog.find('#customer-id').val(appointment.id_users_customer); $dialog.find('#first-name').val(customer.first_name); $dialog.find('#last-name').val(customer.last_name); @@ -142,7 +135,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $dialog.find('#customer-notes').val(customer.notes); $dialog.modal('show'); } else { - var unavailable = lastFocusedEventData.data; + const unavailable = lastFocusedEventData.data; // Replace string date values with actual date objects. unavailable.start_datetime = lastFocusedEventData.start.format('YYYY-MM-DD HH:mm:ss'); @@ -151,7 +144,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; endMoment = moment(unavailable.end_datetime); $dialog = $('#manage-unavailable'); - BackendCalendarUnavailabilityEventsModal.resetUnavailableDialog(); + App.Components.ManageUnavailabilitiesModal.resetUnavailableDialog(); // Apply unavailable data to dialog. $dialog.find('.modal-header h3').text('Edit Unavailable Period'); @@ -170,31 +163,31 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; * 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. */ - $calendarPage.on('click', '.delete-popover', function () { - $(this).parents('.popover').popover('dispose'); + $calendarPage.on('click', '.delete-popover', (event) => { + $(event.target).parents('.popover').popover('dispose'); - var url; - var data; + let url; + let data; if (lastFocusedEventData.data.workingPlanException) { - var providerId = $('#select-filter-item').val(); + const providerId = $('#select-filter-item').val(); - var provider = GlobalVariables.availableProviders.find(function (availableProvider) { - return Number(availableProvider.id) === Number(providerId); - }); + const provider = App.Vars.available_providers.find( + (availableProvider) => Number(availableProvider.id) === Number(providerId) + ); if (!provider) { throw new Error('Provider could not be found: ' + providerId); } - var successCallback = function () { + const successCallback = () => { Backend.displayNotification(App.Lang.working_plan_exception_deleted); - var workingPlanExceptions = JSON.parse(provider.settings.working_plan_exceptions) || {}; + const workingPlanExceptions = JSON.parse(provider.settings.working_plan_exceptions) || {}; delete workingPlanExceptions[date]; - for (var index in GlobalVariables.availableProviders) { - var availableProvider = GlobalVariables.availableProviders[index]; + for (const index in App.Vars.available_providers) { + const availableProvider = App.Vars.available_providers[index]; if (Number(availableProvider.id) === Number(providerId)) { availableProvider.settings.working_plan_exceptions = JSON.stringify(workingPlanExceptions); @@ -205,29 +198,29 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#select-filter-item').trigger('change'); // Update the calendar. }; - var date = lastFocusedEventData.start.format('YYYY-MM-DD'); + const date = lastFocusedEventData.start.format('YYYY-MM-DD'); - BackendCalendarApi.deleteWorkingPlanException(date, providerId, successCallback); + App.Http.Calendar.deleteWorkingPlanException(date, providerId, successCallback); } else if (!lastFocusedEventData.data.is_unavailable) { - var buttons = [ + const buttons = [ { text: App.Lang.cancel, - click: function () { + click: () => { $('#message-box').dialog('close'); } }, { text: 'OK', click: function () { - url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_delete_appointment'; + url = App.Utils.Url.siteUrl('calendar/ajax_delete_appointment'); data = { - csrf_token: GlobalVariables.csrfToken, + csrf_token: App.Vars.csrf_token, appointment_id: lastFocusedEventData.data.id, delete_reason: $('#delete-reason').val() }; - $.post(url, data).done(function () { + $.post(url, data).done(() => { $('#message-box').dialog('close'); // Refresh calendar event items. @@ -237,7 +230,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; } ]; - GeneralFunctions.displayMessageBox( + App.Utils.Message.show( App.Lang.delete_appointment_title, App.Lang.write_appointment_removal_reason, buttons @@ -250,14 +243,14 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; }).appendTo('#message-box'); } else { // Do not display confirmation prompt. - url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_delete_unavailable'; + url = App.Utils.Url.siteUrl('calendar/ajax_delete_unavailable'); data = { - csrf_token: GlobalVariables.csrfToken, + csrf_token: App.Vars.csrf_token, unavailable_id: lastFocusedEventData.data.id }; - $.post(url, data).done(function () { + $.post(url, data).done(() => { $('#message-box').dialog('close'); // Refresh calendar event items. @@ -271,7 +264,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; * * Load the appointments that correspond to the select filter item and display them on the calendar. */ - $('#select-filter-item').on('change', function () { + $('#select-filter-item').on('change', () => { // If current value is service, then the sync buttons must be disabled. if ($('#select-filter-item option:selected').attr('type') === FILTER_TYPE_SERVICE) { $('#google-sync, #enable-sync, #insert-appointment, #insert-dropdown').prop('disabled', true); @@ -286,14 +279,14 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; editable: true }); - var providerId = $('#select-filter-item').val(); + const providerId = $('#select-filter-item').val(); - var provider = GlobalVariables.availableProviders.find(function (availableProvider) { + const provider = App.Vars.available_providers.find(function (availableProvider) { return Number(availableProvider.id) === Number(providerId); }); if (provider && provider.timezone) { - $('.provider-timezone').text(GlobalVariables.timezones[provider.timezone]); + $('.provider-timezone').text(App.Vars.timezones[provider.timezone]); } // If the user has already the sync enabled then apply the proper style changes. @@ -319,7 +312,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; * @return {Number} Returns the calendar element height in pixels. */ function getCalendarHeight() { - var result = + const result = window.innerHeight - $('#footer').outerHeight() - $('#header').outerHeight() - @@ -338,7 +331,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; return '-'; } - var notes = event.data.notes; + const notes = event.data.notes; return notes.length > 100 ? notes.substring(0, 100) + '...' : notes; } @@ -352,14 +345,14 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; function calendarEventClick(event, jsEvent) { $('.popover').popover('dispose'); // Close all open popovers. - var $html; - var displayEdit; - var displayDelete; + let $html; + let displayEdit; + let displayDelete; // Depending where the user clicked the event (title or empty space) we // need to use different selectors to reach the parent element. - var $parent = $(jsEvent.target.offsetParent); - var $altParent = $(jsEvent.target).parents().eq(1); + const $parent = $(jsEvent.target.offsetParent); + const $altParent = $(jsEvent.target).parents().eq(1); if ( $(this).hasClass('fc-unavailable') || @@ -368,12 +361,12 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; ) { displayEdit = ($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) && - GlobalVariables.user.privileges.appointments.edit === true + App.Vars.privileges.appointments.edit === true ? 'me-2' : 'd-none'; displayDelete = ($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) && - GlobalVariables.user.privileges.appointments.delete === true + App.Vars.privileges.appointments.delete === true ? 'me-2' : 'd-none'; // Same value at the time. @@ -384,9 +377,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'text': App.Lang.start }), $('', { - 'text': GeneralFunctions.formatDate( + 'text': App.Utils.Date.format( event.start.format('YYYY-MM-DD HH:mm:ss'), - GlobalVariables.dateFormat, + App.Vars.date_format, + App.Vars.time_format, true ) }), @@ -397,9 +391,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'text': App.Lang.end }), $('', { - 'text': GeneralFunctions.formatDate( + 'text': App.Utils.Date.format( event.end.format('YYYY-MM-DD HH:mm:ss'), - GlobalVariables.dateFormat, + App.Vars.date_format, + App.Vars.time_format, true ) }), @@ -462,7 +457,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; ) { displayDelete = ($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) && - GlobalVariables.user.privileges.appointments.delete === true + App.Vars.privileges.appointments.delete === true ? 'me-2' : 'd-none'; // Same value at the time. @@ -482,9 +477,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'text': App.Lang.start }), $('', { - 'text': GeneralFunctions.formatDate( + 'text': App.Utils.Date.format( event.data.date + ' ' + event.data.workingPlanException.start, - GlobalVariables.dateFormat, + App.Vars.date_format, + App.Vars.time_format, true ) }), @@ -495,9 +491,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'text': App.Lang.end }), $('', { - 'text': GeneralFunctions.formatDate( + 'text': App.Utils.Date.format( event.data.date + ' ' + event.data.workingPlanException.end, - GlobalVariables.dateFormat, + App.Vars.date_format, + App.Vars.time_format, true ) }), @@ -508,7 +505,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'text': App.Lang.timezone }), $('', { - 'text': GlobalVariables.timezones[event.data.provider.timezone] + 'text': App.Vars.timezones[event.data.provider.timezone] }), $('
'), @@ -555,8 +552,8 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; ] }); } else { - displayEdit = GlobalVariables.user.privileges.appointments.edit === true ? 'me-2' : 'd-none'; - displayDelete = GlobalVariables.user.privileges.appointments.delete === true ? 'me-2' : 'd-none'; + displayEdit = App.Vars.privileges.appointments.edit === true ? 'me-2' : 'd-none'; + displayDelete = App.Vars.privileges.appointments.delete === true ? 'me-2' : 'd-none'; $html = $('
', { 'html': [ @@ -565,9 +562,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'text': App.Lang.start }), $('', { - 'text': GeneralFunctions.formatDate( + 'text': App.Utils.Date.format( event.start.format('YYYY-MM-DD HH:mm:ss'), - GlobalVariables.dateFormat, + App.Vars.date_format, + App.Vars.time_format, true ) }), @@ -578,9 +576,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'text': App.Lang.end }), $('', { - 'text': GeneralFunctions.formatDate( + 'text': App.Utils.Date.format( event.end.format('YYYY-MM-DD HH:mm:ss'), - GlobalVariables.dateFormat, + App.Vars.date_format, + App.Vars.time_format, true ) }), @@ -591,7 +590,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'text': App.Lang.timezone }), $('', { - 'text': GlobalVariables.timezones[event.data.provider.timezone] + 'text': App.Vars.timezones[event.data.provider.timezone] }), $('
'), @@ -608,7 +607,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'class': 'd-inline-block me-2', 'text': App.Lang.provider }), - GeneralFunctions.renderMapIcon(event.data.provider), + App.Utils.CalendarEventPopover.renderMapIcon(event.data.provider), $('', { 'text': event.data.provider.first_name + ' ' + event.data.provider.last_name }), @@ -618,7 +617,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'class': 'd-inline-block me-2', 'text': App.Lang.customer }), - GeneralFunctions.renderMapIcon(event.data.customer), + App.Utils.CalendarEventPopover.renderMapIcon(event.data.customer), $('', { 'class': 'd-inline-block ms-1', 'text': event.data.customer.first_name + ' ' + event.data.customer.last_name @@ -629,7 +628,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'class': 'd-inline-block me-2', 'text': App.Lang.email }), - GeneralFunctions.renderMailIcon(event.data.customer.email), + App.Utils.CalendarEventPopover.renderMailIcon(event.data.customer.email), $('', { 'class': 'd-inline-block ms-1', 'text': event.data.customer.email @@ -640,7 +639,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; 'class': 'd-inline-block me-2', 'text': App.Lang.phone }), - GeneralFunctions.renderPhoneIcon(event.data.customer.phone_number), + App.Utils.CalendarEventPopover.renderPhoneIcon(event.data.customer.phone_number), $('', { 'class': 'd-inline-block ms-1', 'text': event.data.customer.phone_number @@ -727,14 +726,15 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; * @see updateAppointmentData() */ function calendarEventResize(event, delta, revertFunc) { - if (GlobalVariables.user.privileges.appointments.edit === false) { + if (App.Vars.privileges.appointments.edit === false) { revertFunc(); Backend.displayNotification(App.Lang.no_privileges_edit_appointments); return; } - var $calendar = $('#calendar'); - var successCallback; + const $calendar = $('#calendar'); + + let successCallback; if ($('#notification').is(':visible')) { $('#notification').hide('bind'); @@ -746,7 +746,9 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; .add({days: delta.days(), hours: delta.hours(), minutes: delta.minutes()}) .format('YYYY-MM-DD HH:mm:ss'); - var appointment = GeneralFunctions.clone(event.data); + const appointment = {...event.data}; + + appointment.is_unavailable = Number(appointment.is_unavailable); // Must delete the following because only appointment data should be provided to the AJAX call. delete appointment.customer; @@ -754,21 +756,21 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; delete appointment.service; // Success callback - successCallback = function () { + successCallback = () => { // Display success notification to user. - var undoFunction = function () { + const undoFunction = () => { appointment.end_datetime = event.data.end_datetime = moment(appointment.end_datetime) .add({days: -delta.days(), hours: -delta.hours(), minutes: -delta.minutes()}) .format('YYYY-MM-DD HH:mm:ss'); - var url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_save_appointment'; + const url = App.Utils.Url.siteUrl('calendar/ajax_save_appointment'); - var data = { - csrf_token: GlobalVariables.csrfToken, - appointment_data: JSON.stringify(appointment) + const data = { + csrf_token: App.Vars.csrf_token, + appointment_data: appointment }; - $.post(url, data).done(function () { + $.post(url, data).done(() => { $('#notification').hide('blind'); }); @@ -788,10 +790,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; }; // Update appointment data. - BackendCalendarApi.saveAppointment(appointment, null, successCallback); + App.Http.Calendar.saveAppointment(appointment, null, successCallback); } else { // Update unavailable time period. - var unavailable = { + const unavailable = { id: event.data.id, start_datetime: event.start.format('YYYY-MM-DD HH:mm:ss'), end_datetime: event.end.format('YYYY-MM-DD HH:mm:ss'), @@ -801,21 +803,23 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; event.data.end_datetime = unavailable.end_datetime; // Define success callback function. - successCallback = function () { + successCallback = () => { // Display success notification to user. - var undoFunction = function () { + const undoFunction = () => { unavailable.end_datetime = event.data.end_datetime = moment(unavailable.end_datetime) .add({minutes: -delta.minutes()}) .format('YYYY-MM-DD HH:mm:ss'); - var url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_save_unavailable'; + unavailable.is_unavailable = Number(unavailable.is_unavailable); - var data = { - csrf_token: GlobalVariables.csrfToken, - unavailable: JSON.stringify(unavailable) + const url = App.Utils.Url.siteUrl('calendar/ajax_save_unavailable'); + + const data = { + csrf_token: App.Vars.csrf_token, + unavailable: unavailable }; - $.post(url, data).done(function () { + $.post(url, data).done(() => { $('#notification').hide('blind'); }); @@ -835,7 +839,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $calendar.fullCalendar('updateEvent', event); }; - BackendCalendarApi.saveUnavailable(unavailable, successCallback, null); + App.Http.Calendar.saveUnavailable(unavailable, successCallback, null); } } @@ -877,7 +881,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; * @param {function} revertFunc */ function calendarEventDrop(event, delta, revertFunc) { - if (GlobalVariables.user.privileges.appointments.edit === false) { + if (App.Vars.privileges.appointments.edit === false) { revertFunc(); Backend.displayNotification(App.Lang.no_privileges_edit_appointments); return; @@ -887,11 +891,11 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#notification').hide('bind'); } - var successCallback; + let successCallback; if (!event.data.is_unavailable) { // Prepare appointment data. - var appointment = GeneralFunctions.clone(event.data); + const appointment = {...event.data}; // Must delete the following because only appointment data should be provided to the ajax call. delete appointment.customer; @@ -906,13 +910,15 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; .add({days: delta.days(), hours: delta.hours(), minutes: delta.minutes()}) .format('YYYY-MM-DD HH:mm:ss'); + appointment.is_unavailable = Number(appointment.is_unavailable); + event.data.start_datetime = appointment.start_datetime; event.data.end_datetime = appointment.end_datetime; // Define success callback function. - successCallback = function () { + successCallback = () => { // Define the undo function, if the user needs to reset the last change. - var undoFunction = function () { + const undoFunction = () => { appointment.start_datetime = moment(appointment.start_datetime) .add({days: -delta.days(), hours: -delta.hours(), minutes: -delta.minutes()}) .format('YYYY-MM-DD HH:mm:ss'); @@ -924,14 +930,14 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; event.data.start_datetime = appointment.start_datetime; event.data.end_datetime = appointment.end_datetime; - var url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_save_appointment'; + const url = App.Utils.Url.siteUrl('calendar/ajax_save_appointment'); - var data = { - csrf_token: GlobalVariables.csrfToken, - appointment_data: JSON.stringify(appointment) + const data = { + csrf_token: App.Vars.csrf_token, + appointment_data: appointment }; - $.post(url, data).done(function () { + $.post(url, data).done(() => { $('#notification').hide('blind'); }); @@ -949,18 +955,18 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; }; // Update appointment data. - BackendCalendarApi.saveAppointment(appointment, null, successCallback); + App.Http.Calendar.saveAppointment(appointment, null, successCallback); } else { // Update unavailable time period. - var unavailable = { + const unavailable = { id: event.data.id, start_datetime: event.start.format('YYYY-MM-DD HH:mm:ss'), end_datetime: event.end.format('YYYY-MM-DD HH:mm:ss'), id_users_provider: event.data.id_users_provider }; - successCallback = function () { - var undoFunction = function () { + successCallback = () => { + const undoFunction = () => { unavailable.start_datetime = moment(unavailable.start_datetime) .add({days: -delta.days(), minutes: -delta.minutes()}) .format('YYYY-MM-DD HH:mm:ss'); @@ -969,16 +975,19 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; .add({days: -delta.days(), minutes: -delta.minutes()}) .format('YYYY-MM-DD HH:mm:ss'); + unavailable.is_unavailable = Number(unavailable.is_unavailable); + event.data.start_datetime = unavailable.start_datetime; event.data.end_datetime = unavailable.end_datetime; - var url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_save_unavailable'; - var data = { - csrf_token: GlobalVariables.csrfToken, - unavailable: JSON.stringify(unavailable) + const url = App.Utils.Url.siteUrl('calendar/ajax_save_unavailable'); + + const data = { + csrf_token: App.Vars.csrf_token, + unavailable: unavailable }; - $.post(url, data).done(function () { + $.post(url, data).done(() => { $('#notification').hide('blind'); }); @@ -995,7 +1004,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#footer').css('position', 'static'); // Footer position fix. }; - BackendCalendarApi.saveUnavailable(unavailable, successCallback); + App.Http.Calendar.saveUnavailable(unavailable, successCallback); } } @@ -1021,12 +1030,12 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $(window).trigger('resize'); // Places the footer on the bottom. // Remove all open popovers. - $('.close-popover').each(function (index, closePopoverButton) { + $('.close-popover').each((index, closePopoverButton) => { $(closePopoverButton).parents('.popover').popover('dispose'); }); - // Add new pop overs. - $('.fv-events').each(function (index, eventElement) { + // Add new popovers. + $('.fv-events').each((index, eventElement) => { $(eventElement).popover(); }); } @@ -1041,10 +1050,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; */ function convertTitlesToHtml() { // Convert the titles to html code. - $('.fc-custom').each(function (index, customEventElement) { - var title = $(customEventElement).find('.fc-event-title').text(); + $('.fc-custom').each((index, customEventElement) => { + const title = $(customEventElement).find('.fc-event-title').text(); $(customEventElement).find('.fc-event-title').html(title); - var time = $(customEventElement).find('.fc-event-time').text(); + const time = $(customEventElement).find('.fc-event-time').text(); $(customEventElement).find('.fc-event-time').html(time); }); } @@ -1061,10 +1070,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; * @param {Date} endDate Visible end date of the calendar. */ function refreshCalendarAppointments($calendar, recordId, filterType, startDate, endDate) { - var url = GlobalVariables.baseUrl + '/index.php/calendar/ajax_get_calendar_appointments'; + const url = App.Utils.Url.siteUrl('calendar/ajax_get_calendar_appointments'); - var data = { - csrf_token: GlobalVariables.csrfToken, + const data = { + csrf_token: App.Vars.csrf_token, record_id: recordId, start_date: moment(startDate).format('YYYY-MM-DD'), end_date: moment(endDate).format('YYYY-MM-DD'), @@ -1073,18 +1082,17 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#loading').css('visibility', 'hidden'); - var calendarEventSource = []; + const calendarEventSource = []; return $.post(url, data) - .done(function (response) { - var $calendar = $('#calendar'); + .done((response) => { + const $calendar = $('#calendar'); $calendar.fullCalendar('removeEvents'); // Add appointments to calendar. - var appointmentEvents = []; - response.appointments.forEach(function (appointment) { - var appointmentEvent = { + response.appointments.forEach((appointment) => { + const appointmentEvent = { id: appointment.id, title: appointment.service.name + @@ -1103,14 +1111,14 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; // Add custom unavailable periods (they are always displayed on the calendar, even if the provider won't // work on that day). - response.unavailables.forEach(function (unavailable) { - var notes = unavailable.notes ? ' - ' + unavailable.notes : ''; + response.unavailables.forEach((unavailable) => { + let notes = unavailable.notes ? ' - ' + unavailable.notes : ''; if (unavailable.notes && unavailable.notes.length > 30) { notes = unavailable.notes.substring(0, 30) + '...'; } - var unavailabilityEvent = { + const unavailabilityEvent = { title: App.Lang.unavailable + notes, start: moment(unavailable.start_datetime), end: moment(unavailable.end_datetime), @@ -1124,44 +1132,44 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; calendarEventSource.push(unavailabilityEvent); }); - var calendarView = $('#calendar').fullCalendar('getView'); + const calendarView = $('#calendar').fullCalendar('getView'); if (filterType === FILTER_TYPE_PROVIDER && calendarView.name !== 'month') { - var provider = GlobalVariables.availableProviders.find(function (availableProvider) { - return Number(availableProvider.id) === Number(recordId); - }); + const provider = App.Vars.available_providers.find( + (availableProvider) => Number(availableProvider.id) === Number(recordId) + ); if (!provider) { throw new Error('Provider was not found.'); } - var workingPlan = JSON.parse(provider.settings.working_plan); - var workingPlanExceptions = JSON.parse(provider.settings.working_plan_exceptions); - var unavailabilityEvent; - var viewStart; - var viewEnd; - var breakStart; - var breakEnd; - var workingPlanExceptionStart; - var workingPlanExceptionEnd; - var weekdayNumber; - var weekdayName; - var weekdayDate; - var workingPlanExceptionEvent; - var startHour; - var endHour; - var workDateStart; - var workDateEnd; + const workingPlan = JSON.parse(provider.settings.working_plan); + const workingPlanExceptions = JSON.parse(provider.settings.working_plan_exceptions); + let unavailabilityEvent; + let viewStart; + let viewEnd; + let breakStart; + let breakEnd; + let workingPlanExceptionStart; + let workingPlanExceptionEnd; + let weekdayNumber; + let weekdayName; + let weekdayDate; + let workingPlanExceptionEvent; + let startHour; + let endHour; + let workDateStart; + let workDateEnd; // Sort the working plan starting with the first day as set in General settings to correctly align // breaks in the calendar display. - var firstWeekdayNumber = GeneralFunctions.getWeekDayId(GlobalVariables.firstWeekday); - var sortedWorkingPlan = GeneralFunctions.sortWeekDictionary(workingPlan, firstWeekdayNumber); + const firstWeekdayNumber = App.Utils.Date.getWeekdayId(App.Vars.first_weekday); + const sortedWorkingPlan = App.Utils.Date.sortWeekDictionary(workingPlan, firstWeekdayNumber); switch (calendarView.name) { case 'agendaDay': weekdayNumber = parseInt(calendarView.start.format('d')); - weekdayName = GeneralFunctions.getWeekdayName(weekdayNumber); + weekdayName = App.Utils.Date.getWeekdayName(weekdayNumber); weekdayDate = calendarView.start.clone().format('YYYY-MM-DD'); // Add working plan exception. @@ -1214,7 +1222,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; workDateStart.minute(parseInt(startHour[1])); if (viewStart < workDateStart) { - var unavailablePeriodBeforeWorkStarts = { + const unavailablePeriodBeforeWorkStarts = { title: App.Lang.not_working, start: viewStart, end: workDateStart, @@ -1235,7 +1243,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; workDateEnd.minute(parseInt(endHour[1])); if (viewEnd > workDateEnd) { - var unavailablePeriodAfterWorkEnds = { + const unavailablePeriodAfterWorkEnds = { title: App.Lang.not_working, start: workDateEnd, end: viewEnd, @@ -1249,18 +1257,18 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; } // Add unavailable periods for breaks. - sortedWorkingPlan[weekdayName].breaks.forEach(function (breakPeriod) { - var breakStartString = breakPeriod.start.split(':'); + sortedWorkingPlan[weekdayName].breaks.forEach((breakPeriod) => { + const breakStartString = breakPeriod.start.split(':'); breakStart = viewStart.clone(); breakStart.hour(parseInt(breakStartString[0])); breakStart.minute(parseInt(breakStartString[1])); - var breakEndString = breakPeriod.end.split(':'); + const breakEndString = breakPeriod.end.split(':'); breakEnd = viewStart.clone(); breakEnd.hour(parseInt(breakEndString[0])); breakEnd.minute(parseInt(breakEndString[1])); - var unavailablePeriod = { + const unavailablePeriod = { title: App.Lang.break, start: breakStart, end: breakEnd, @@ -1276,11 +1284,11 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; break; case 'agendaWeek': - var calendarDate = calendarView.start.clone(); + const calendarDate = calendarView.start.clone(); while (calendarDate < calendarView.end) { weekdayNumber = parseInt(calendarDate.format('d')); - weekdayName = GeneralFunctions.getWeekdayName(weekdayNumber); + weekdayName = App.Utils.Date.getWeekdayName(weekdayNumber); weekdayDate = calendarDate.format('YYYY-MM-DD'); // Add working plan exception event. @@ -1380,18 +1388,18 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; } // Add unavailable periods during day breaks. - sortedWorkingPlan[weekdayName].breaks.forEach(function (breakPeriod) { - var breakStartString = breakPeriod.start.split(':'); + sortedWorkingPlan[weekdayName].breaks.forEach((breakPeriod) => { + const breakStartString = breakPeriod.start.split(':'); breakStart = calendarDate.clone(); breakStart.hour(parseInt(breakStartString[0])); breakStart.minute(parseInt(breakStartString[1])); - var breakEndString = breakPeriod.end.split(':'); + const breakEndString = breakPeriod.end.split(':'); breakEnd = calendarDate.clone(); breakEnd.hour(parseInt(breakEndString[0])); breakEnd.minute(parseInt(breakEndString[1])); - var unavailabilityEvent = { + const unavailabilityEvent = { title: App.Lang.break, start: moment(calendarDate.format('YYYY-MM-DD') + ' ' + breakPeriod.start), end: moment(calendarDate.format('YYYY-MM-DD') + ' ' + breakPeriod.end), @@ -1411,17 +1419,17 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; } } }) - .always(function () { + .always(() => { $('#loading').css('visibility', ''); $calendar.fullCalendar('addEventSource', calendarEventSource); }); } - exports.initialize = function () { + function initialize() { // Dynamic date formats. - var columnFormat = {}; + let columnFormat = {}; - switch (GlobalVariables.dateFormat) { + switch (App.Vars.date_format) { case 'DMY': columnFormat = 'ddd D/M'; break; @@ -1432,14 +1440,14 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; break; default: - throw new Error('Invalid date format setting provided!', GlobalVariables.dateFormat); + throw new Error('Invalid date format setting provided!', App.Vars.date_format); } // Time formats - var timeFormat = ''; - var slotTimeFormat = ''; + let timeFormat = ''; + let slotTimeFormat = ''; - switch (GlobalVariables.timeFormat) { + switch (App.Vars.time_format) { case 'military': timeFormat = 'H:mm'; slotTimeFormat = 'H(:mm)'; @@ -1449,13 +1457,13 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; slotTimeFormat = 'h(:mm) a'; break; default: - throw new Error('Invalid time format setting provided!', GlobalVariables.timeFormat); + throw new Error('Invalid time format setting provided!', App.Vars.time_format); } - var defaultView = window.innerWidth < 468 ? 'agendaDay' : 'agendaWeek'; + const defaultView = window.innerWidth < 468 ? 'agendaDay' : 'agendaWeek'; - var firstWeekday = GlobalVariables.firstWeekday; - var firstWeekdayNumber = GeneralFunctions.getWeekDayId(firstWeekday); + const firstWeekday = App.Vars.first_weekday; + const firstWeekdayNumber = App.Utils.Date.getWeekdayId(firstWeekday); // Initialize page calendar $('#calendar').fullCalendar({ @@ -1479,7 +1487,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; // Selectable selectable: true, selectHelper: true, - select: function (start, end) { + select: (start, end) => { if (!start.hasTime() || !end.hasTime()) { return; } @@ -1487,21 +1495,21 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#insert-appointment').trigger('click'); // Preselect service & provider. - var service; + let service; if ($('#select-filter-item option:selected').attr('type') === FILTER_TYPE_SERVICE) { - service = GlobalVariables.availableServices.find(function (service) { - return Number(service.id) === Number($('#select-filter-item').val()); - }); + service = App.Vars.available_services.find( + (availableService) => Number(availableService.id) === Number($('#select-filter-item').val()) + ); $('#select-service').val(service.id).trigger('change'); } else { - var provider = GlobalVariables.availableProviders.find(function (provider) { - return Number(provider.id) === Number($('#select-filter-item').val()); - }); + const provider = App.Vars.available_providers.find( + (availableProvider) => Number(availableProvider.id) === Number($('#select-filter-item').val()) + ); - service = GlobalVariables.availableServices.find(function (service) { - return provider.services.indexOf(service.id) !== -1; - }); + service = App.Vars.available_services.find( + (availableService) => provider.services.indexOf(availableService.id) !== -1 + ); if (service) { $('#select-service').val(service.id); @@ -1608,12 +1616,12 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; calendarWindowResize(); // Fill the select list boxes of the page. - if (GlobalVariables.availableProviders.length > 0) { + if (App.Vars.available_providers.length > 0) { $('', { 'label': App.Lang.providers, 'type': 'providers-group', - 'html': GlobalVariables.availableProviders.map(function (availableProvider) { - var hasGoogleSync = availableProvider.settings.google_sync === '1' ? 'true' : 'false'; + 'html': App.Vars.available_providers.map(function (availableProvider) { + const hasGoogleSync = availableProvider.settings.google_sync === '1' ? 'true' : 'false'; return $('', { 'label': App.Lang.services, 'type': 'services-group', - 'html': GlobalVariables.availableServices.map(function (availableService) { - return $('