From c670c023a7bcc40604e2bc1e53f13a402641bfb4 Mon Sep 17 00:00:00 2001 From: Alex Tselegidis Date: Wed, 6 May 2020 19:15:11 +0200 Subject: [PATCH] Performed major javascript refactoring for more consistncy and efficiency in the code base (work in progress) --- assets/js/backend_calendar.js | 30 +- assets/js/backend_calendar_api.js | 50 +- .../js/backend_calendar_appointments_modal.js | 139 ++-- assets/js/backend_calendar_default_view.js | 657 +++++++++--------- assets/js/backend_calendar_google_sync.js | 29 +- assets/js/backend_calendar_table_view.js | 140 ++-- assets/js/backend_categories_helper.js | 107 +-- assets/js/backend_customers_helper.js | 126 ++-- assets/js/backend_services.js | 23 +- assets/js/backend_services_helper.js | 103 +-- assets/js/backend_settings.js | 48 +- assets/js/backend_settings_system.js | 41 +- assets/js/backend_settings_user.js | 36 +- assets/js/backend_users.js | 73 +- assets/js/backend_users_admins.js | 95 +-- assets/js/backend_users_providers.js | 94 +-- assets/js/backend_users_secretaries.js | 99 +-- assets/js/frontend_book.js | 84 ++- assets/js/frontend_book_api.js | 169 +++-- assets/js/frontend_book_success.js | 8 +- assets/js/general_functions.js | 19 +- assets/js/installation.js | 34 +- assets/js/login.js | 1 + assets/js/working_plan.js | 20 +- 24 files changed, 1168 insertions(+), 1057 deletions(-) diff --git a/assets/js/backend_calendar.js b/assets/js/backend_calendar.js index 89e71ef6..b50f0f2d 100755 --- a/assets/js/backend_calendar.js +++ b/assets/js/backend_calendar.js @@ -29,39 +29,37 @@ window.BackendCalendar = window.BackendCalendar || {}; var $calendarPage = $('#calendar-page'); $calendarPage.on('click', '#toggle-fullscreen', function () { - var $target = $(this); + var $toggleFullscreen = $(this); var element = document.documentElement; - var isFullScreen = (document.fullScreenElement && document.fullScreenElement !== null) - || document.mozFullScreen - || document.webkitIsFullScreen; + var isFullScreen = document.fullScreenElement || document.mozFullScreen || document.webkitIsFullScreen; if (isFullScreen) { // Exit fullscreen mode. - if (document.exitFullscreen) + if (document.exitFullscreen) { document.exitFullscreen(); - else if (document.msExitFullscreen) + } else if (document.msExitFullscreen) { document.msExitFullscreen(); - else if (document.mozCancelFullScreen) + } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); - else if (document.webkitExitFullscreen) + } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); + } - $target + $toggleFullscreen .removeClass('btn-success') .addClass('btn-default'); - } else { // Switch to fullscreen mode. - if (element.requestFullscreen) + if (element.requestFullscreen) { element.requestFullscreen(); - else if (element.msRequestFullscreen) + } else if (element.msRequestFullscreen) { element.msRequestFullscreen(); - else if (element.mozRequestFullScreen) + } else if (element.mozRequestFullScreen) { element.mozRequestFullScreen(); - else if (element.webkitRequestFullscreen) + } else if (element.webkitRequestFullscreen) { element.webkitRequestFullscreen(); - - $target + } + $toggleFullscreen .removeClass('btn-default') .addClass('btn-success'); } diff --git a/assets/js/backend_calendar_api.js b/assets/js/backend_calendar_api.js index ec5be7ac..18e4c4cd 100755 --- a/assets/js/backend_calendar_api.js +++ b/assets/js/backend_calendar_api.js @@ -29,34 +29,30 @@ window.BackendCalendarApi = window.BackendCalendarApi || {}; * * @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. + * @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/backend_api/ajax_save_appointment'; + var data = { csrfToken: GlobalVariables.csrfToken, appointment_data: JSON.stringify(appointment) }; - if (customer !== undefined) { + if (customer) { data.customer_data = JSON.stringify(customer); } - $.ajax({ - url: url, - type: 'POST', - data: data, - dataType: 'json' - }) + $.post(url, data) .done(function (response) { - if (successCallback !== undefined) { + if (successCallback) { successCallback(response); } }) .fail(function (jqXHR, textStatus, errorThrown) { - if (errorCallback !== undefined) { + if (errorCallback) { errorCallback(); } }); @@ -70,19 +66,16 @@ window.BackendCalendarApi = window.BackendCalendarApi || {}; * @param {Function} errorCallback The ajax failure callback function. */ exports.saveUnavailable = function (unavailable, successCallback, errorCallback) { - var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_unavailable'; - var postData = { + var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_unavailable'; + + var data = { csrfToken: GlobalVariables.csrfToken, unavailable: JSON.stringify(unavailable) }; - $.ajax({ - type: 'POST', - url: postUrl, - data: postData, - success: successCallback, - error: errorCallback - }); + $.post(url, data) + .done(successCallback) + .fail(errorCallback); }; /** @@ -92,19 +85,16 @@ window.BackendCalendarApi = window.BackendCalendarApi || {}; * @param {Function} errorCallback The ajax failure callback function. */ exports.saveExtraPeriod = function (extra_periods, successCallback, errorCallback) { - var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_extra_period'; - var postData = { + var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_extra_period'; + + var data = { csrfToken: GlobalVariables.csrfToken, extra_period: JSON.stringify(extra_periods) }; - $.ajax({ - type: 'POST', - url: postUrl, - data: postData, - success: successCallback, - error: errorCallback - }); + $.post(url, data) + .done(successCallback) + .fail(errorCallback); } })(window.BackendCalendarApi); diff --git a/assets/js/backend_calendar_appointments_modal.js b/assets/js/backend_calendar_appointments_modal.js index 268a5139..ad07eeb6 100755 --- a/assets/js/backend_calendar_appointments_modal.js +++ b/assets/js/backend_calendar_appointments_modal.js @@ -26,7 +26,7 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa var providerId = $('#select-provider').val(); var provider = GlobalVariables.availableProviders.filter(function(availableProvider) { - return availableProvider.id == providerId; + return Number(availableProvider.id) === Number(providerId); }).shift(); if (provider && provider.timezone) { @@ -129,11 +129,11 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa var $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') { + if ($('#select-filter-item option:selected').attr('type') === 'provider') { var providerId = $('#select-filter-item').val(); var providers = GlobalVariables.availableProviders.filter(function (provider) { - return provider.id == providerId; + return Number(provider.id) === Number(providerId); }); if (providers.length) { @@ -147,7 +147,7 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa var serviceDuration = 0; $.each(GlobalVariables.availableServices, function (index, service) { - if (service.id == $dialog.find('#select-service').val()) { + if (Number(service.id) === Number($dialog.find('#select-service').val())) { serviceDuration = service.duration; return false; // exit loop } @@ -204,17 +204,17 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa $('#manage-appointment').on('click', '#existing-customers-list div', function () { var id = $(this).attr('data-id'); - $.each(GlobalVariables.customers, function (index, c) { - if (c.id == id) { - $('#customer-id').val(c.id); - $('#first-name').val(c.first_name); - $('#last-name').val(c.last_name); - $('#email').val(c.email); - $('#phone-number').val(c.phone_number); - $('#address').val(c.address); - $('#city').val(c.city); - $('#zip-code').val(c.zip_code); - $('#customer-notes').val(c.notes); + $.each(GlobalVariables.customers, function (index, customer) { + if (Number(customer.id) === Number(id)) { + $('#customer-id').val(customer.id); + $('#first-name').val(customer.first_name); + $('#last-name').val(customer.last_name); + $('#email').val(customer.email); + $('#phone-number').val(customer.phone_number); + $('#address').val(customer.address); + $('#city').val(customer.city); + $('#zip-code').val(customer.zip_code); + $('#customer-notes').val(customer.notes); return false; } }); @@ -228,56 +228,52 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa $('#filter-existing-customers').keyup(function () { var key = $(this).val().toLowerCase(); var $list = $('#existing-customers-list'); - var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_customers'; - var postData = { + + var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_customers'; + + var data = { csrfToken: GlobalVariables.csrfToken, key: key }; // Try to get the updated customer list. - $.ajax({ - type: 'POST', - url: postUrl, - data: postData, - dataType: 'json', - timeout: 1000, - global: false, - success: function (response) { + $.post(url, data) + .done(function (response) { $list.empty(); - $.each(response, function (index, c) { - $list.append('
' - + c.first_name + ' ' + c.last_name + '
'); + + response.forEach(function (customer, index) { + $list.append('
' + + customer.first_name + ' ' + customer.last_name + '
'); // Verify if this customer is on the old customer list. - var result = $.grep(GlobalVariables.customers, - function (e) { - return e.id == c.id; - }); + var result = GlobalVariables.customers.filter(function(globalVariablesCustomer) { + return Number(globalVariablesCustomer.id) === Number(customer.id); + }); // Add it to the customer list. - if (result.length == 0) { - GlobalVariables.customers.push(c); + if (!result.length) { + GlobalVariables.customers.push(customer); } - }); - }, - error: function (jqXHR, textStatus, errorThrown) { + }) + }) + .fail(function (jqXHR, textStatus, errorThrown) { // If there is any error on the request, search by the local client database. $list.empty(); - $.each(GlobalVariables.customers, function (index, c) { - if (c.first_name.toLowerCase().indexOf(key) != -1 - || c.last_name.toLowerCase().indexOf(key) != -1 - || c.email.toLowerCase().indexOf(key) != -1 - || c.phone_number.toLowerCase().indexOf(key) != -1 - || c.address.toLowerCase().indexOf(key) != -1 - || c.city.toLowerCase().indexOf(key) != -1 - || c.zip_code.toLowerCase().indexOf(key) != -1 - || c.notes.toLowerCase().indexOf(key) != -1) { - $list.append('
' - + c.first_name + ' ' + c.last_name + '
'); + + GlobalVariables.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) { + $list.append('
' + + customer.first_name + ' ' + customer.last_name + '
'); } }); - } - }); + }); }); /** @@ -287,22 +283,22 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa * update the start and end time of the appointment. */ $('#select-service').change(function () { - var sid = $('#select-service').val(); + var serviceId = $('#select-service').val(); $('#select-provider').empty(); // Automatically update the service duration. - $.each(GlobalVariables.availableServices, function (indexService, service) { - if (service.id == sid) { + $.each(GlobalVariables.availableServices, function (indexService, availableService) { + if (Number(availableService.id) === serviceId) { var start = $('#start-datetime').datetimepicker('getDate'); - $('#end-datetime').datetimepicker('setDate', new Date(start.getTime() + service.duration * 60000)); + $('#end-datetime').datetimepicker('setDate', new Date(start.getTime() + availableService.duration * 60000)); return false; // break loop } }); // Update the providers select box. $.each(GlobalVariables.availableProviders, function (indexProvider, provider) { - $.each(provider.services, function (indexService, serviceId) { - if (GlobalVariables.user.role_slug === Backend.DB_SLUG_PROVIDER && parseInt(provider.id) !== GlobalVariables.user.id) { + $.each(provider.services, function (indexService, providerServiceId) { + if (GlobalVariables.user.role_slug === Backend.DB_SLUG_PROVIDER && Number(provider.id) !== GlobalVariables.user.id) { return true; // continue } @@ -311,7 +307,7 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa } // If the current provider is able to provide the selected service, add him to the listbox. - if (serviceId == sid) { + if (Number(providerServiceId) === Number(serviceId)) { var optionHtml = ''; @@ -360,8 +356,10 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa $.each(GlobalVariables.availableProviders, function (index, provider) { var canProvideService = false; - $.each(provider.services, function (index, serviceId) { - if (serviceId == $dialog.find('#select-service').val()) { + var serviceId = $dialog.find('#select-service').val(); + + $.each(provider.services, function (index, providerServiceId) { + if (Number(providerServiceId) === Number(serviceId)) { canProvideService = true; return false; } @@ -381,9 +379,10 @@ 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(); var serviceDuration = 0; $.each(GlobalVariables.availableServices, function (index, service) { - if (service.id == $dialog.find('#select-service').val()) { + if (Number(service.id) === Number(serviceId)) { serviceDuration = service.duration; return false; } @@ -438,13 +437,13 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa minuteText: EALang.minutes, firstDay: firstWeekDayNumber, onClose: function () { - var sid = $('#select-service').val(); + var serviceId = $('#select-service').val(); // Automatically update the #end-datetime DateTimePicker based on service duration. - $.each(GlobalVariables.availableServices, function (indexService, service) { - if (service.id == sid) { + $.each(GlobalVariables.availableServices, function (indexService, availableService) { + if (Number(availableService.id) === Number(serviceId)) { var start = $('#start-datetime').datetimepicker('getDate'); - $('#end-datetime').datetimepicker('setDate', new Date(start.getTime() + service.duration * 60000)); + $('#end-datetime').datetimepicker('setDate', new Date(start.getTime() + availableService.duration * 60000)); return false; // break loop } }); @@ -501,20 +500,20 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa var missingRequiredField = false; $dialog.find('.required').each(function () { - if ($(this).val() == '' || $(this).val() == null) { + if ($(this).val() === '' || $(this).val() === null) { $(this).closest('.form-group').addClass('has-error'); missingRequiredField = true; } }); if (missingRequiredField) { - throw EALang.fields_are_required; + throw new Error(EALang.fields_are_required); } // Check email address. if (!GeneralFunctions.validateEmail($dialog.find('#email').val())) { $dialog.find('#email').closest('.form-group').addClass('has-error'); - throw EALang.invalid_email; + throw new Error(EALang.invalid_email); } // Check appointment start and end time. @@ -522,12 +521,12 @@ window.BackendCalendarAppointmentsModal = window.BackendCalendarAppointmentsModa var end = $('#end-datetime').datetimepicker('getDate'); if (start > end) { $dialog.find('#start-datetime, #end-datetime').closest('.form-group').addClass('has-error'); - throw EALang.start_date_before_end_error; + throw new Error(EALang.start_date_before_end_error); } return true; - } catch (exc) { - $dialog.find('.modal-message').addClass('alert-danger').text(exc).removeClass('hidden'); + } catch (error) { + $dialog.find('.modal-message').addClass('alert-danger').text(error.message).removeClass('hidden'); return false; } } diff --git a/assets/js/backend_calendar_default_view.js b/assets/js/backend_calendar_default_view.js index b63a0368..1f538291 100755 --- a/assets/js/backend_calendar_default_view.js +++ b/assets/js/backend_calendar_default_view.js @@ -67,7 +67,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; var $dialog; - if (lastFocusedEventData.data.is_unavailable == false) { + if (lastFocusedEventData.data.is_unavailable === '0') { var appointment = lastFocusedEventData.data; $dialog = $('#manage-appointment'); @@ -132,45 +132,54 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $calendarPage.on('click', '.delete-popover', function () { $(this).parents().eq(2).remove(); // Hide the popover. + var url; + var data; + // If id_role parameter exists the popover is an extra working day. if (lastFocusedEventData.data.hasOwnProperty('id_roles')) { // Do not display confirmation prompt. - var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_extra_period'; - var data = { + url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_extra_period'; + + data = { csrfToken: GlobalVariables.csrfToken, extra_period: lastFocusedEventData.start.format('YYYY-MM-DD'), provider_id: lastFocusedEventData.data.id }; - $.post(url, data, function (response) { - $('#message_box').dialog('close'); + $.post(url, data) + .done(function () { + $('#message_box').dialog('close'); - var extraWorkingPlan = jQuery.parseJSON(lastFocusedEventData.data.settings.extra_working_plan); - delete extraWorkingPlan[lastFocusedEventData.start.format('YYYY-MM-DD')]; - lastFocusedEventData.data.settings.extra_working_plan = JSON.stringify(extraWorkingPlan); + var extraWorkingPlan = jQuery.parseJSON(lastFocusedEventData.data.settings.extra_working_plan); + delete extraWorkingPlan[lastFocusedEventData.start.format('YYYY-MM-DD')]; + lastFocusedEventData.data.settings.extra_working_plan = JSON.stringify(extraWorkingPlan); - // Refresh calendar event items. - $('#select-filter-item').trigger('change'); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + // Refresh calendar event items. + $('#select-filter-item').trigger('change'); + }) + .fail(GeneralFunctions.ajaxFailureHandler); } - else if (lastFocusedEventData.data.is_unavailable == false) { + else if (lastFocusedEventData.data.is_unavailable === '0') { var buttons = [ { text: 'OK', click: function () { - var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_appointment'; - var data = { + url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_appointment'; + + data = { csrfToken: GlobalVariables.csrfToken, appointment_id: lastFocusedEventData.data.id, delete_reason: $('#delete-reason').val() }; - $.post(url, data, function (response) { - $('#message_box').dialog('close'); + $.post(url, data) + .done(function () { + $('#message_box').dialog('close'); - // Refresh calendar event items. - $('#select-filter-item').trigger('change'); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + // Refresh calendar event items. + $('#select-filter-item').trigger('change'); + }) + .fail(GeneralFunctions.ajaxFailureHandler); } }, { @@ -189,18 +198,21 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#delete-reason').css('width', '100%'); } else { // Do not display confirmation prompt. - var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_unavailable'; - var data = { + url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_unavailable'; + + data = { csrfToken: GlobalVariables.csrfToken, unavailable_id: lastFocusedEventData.data.id }; - $.post(url, data, function (response) { - $('#message_box').dialog('close'); + $.post(url, data) + .done(function () { + $('#message_box').dialog('close'); - // Refresh calendar event items. - $('#select-filter-item').trigger('change'); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + // Refresh calendar event items. + $('#select-filter-item').trigger('change'); + }) + .fail(GeneralFunctions.ajaxFailureHandler); } }); @@ -223,7 +235,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; var providerId = $('#select-filter-item').val(); var provider = GlobalVariables.availableProviders.filter(function(availableProvider) { - return availableProvider.id == providerId; + return Number(availableProvider.id) === Number(providerId); }).shift(); if (provider && provider.timezone) { @@ -278,10 +290,10 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; if ($(this).hasClass('fc-unavailable') || $parent.hasClass('fc-unavailable') || $altParent.hasClass('fc-unavailable')) { displayEdit = (($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) - && GlobalVariables.user.privileges.appointments.edit == true) + && GlobalVariables.user.privileges.appointments.edit === true) ? '' : 'hide'; displayDelete = (($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) - && GlobalVariables.user.privileges.appointments.delete == true) + && GlobalVariables.user.privileges.appointments.delete === true) ? '' : 'hide'; // Same value at the time. var notes = ''; @@ -309,7 +321,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; ''; } else if ($(this).hasClass('fc-extra') || $parent.hasClass('fc-extra') || $altParent.hasClass('fc-extra')) { displayDelete = (($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) - && GlobalVariables.user.privileges.appointments.delete == true) + && GlobalVariables.user.privileges.appointments.delete === true) ? '' : 'hide'; // Same value at the time. var provider = ''; @@ -341,9 +353,9 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; ''; } else { - displayEdit = (GlobalVariables.user.privileges.appointments.edit == true) + displayEdit = (GlobalVariables.user.privileges.appointments.edit === true) ? '' : 'hide'; - displayDelete = (GlobalVariables.user.privileges.appointments.delete == true) + displayDelete = (GlobalVariables.user.privileges.appointments.delete === true) ? '' : 'hide'; html = @@ -416,7 +428,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; * @see updateAppointmentData() */ function _calendarEventResize(event, delta, revertFunc, jsEvent, ui, view) { - if (GlobalVariables.user.privileges.appointments.edit == false) { + if (GlobalVariables.user.privileges.appointments.edit === false) { revertFunc(); Backend.displayNotification(EALang.no_privileges_edit_appointments); return; @@ -428,7 +440,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#notification').hide('bind'); } - if (event.data.is_unavailable == false) { + if (event.data.is_unavailable === false) { // Prepare appointment data. event.data.end_datetime = Date.parseExact( event.data.end_datetime, 'yyyy-MM-dd HH:mm:ss') @@ -458,10 +470,12 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; appointment_data: JSON.stringify(appointment) }; - $.post(url, data, function (response) { - $('#notification').hide('blind'); - revertFunc(); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + $.post(url, data) + .done(function () { + $('#notification').hide('blind'); + revertFunc(); + }) + .fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang.appointment_updated, [ @@ -477,7 +491,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; }; // Update appointment data. - BackendCalendarApi.saveAppointment(appointment, undefined, successCallback); + BackendCalendarApi.saveAppointment(appointment, null, successCallback); } else { // Update unavailable time period. var unavailable = { @@ -499,15 +513,18 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; .toString('yyyy-MM-dd HH:mm:ss'); var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_unavailable'; + var data = { csrfToken: GlobalVariables.csrfToken, unavailable: JSON.stringify(unavailable) }; - $.post(url, data, function (response) { - $('#notification').hide('blind'); - revertFunc(); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + $.post(url, data) + .done(function () { + $('#notification').hide('blind'); + revertFunc(); + }) + .fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang.unavailable_updated, [ @@ -559,7 +576,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; * on the calendar. We need to update the database with this change. This is done via an ajax call. */ function _calendarEventDrop(event, delta, revertFunc, jsEvent, ui, view) { - if (GlobalVariables.user.privileges.appointments.edit == false) { + if (GlobalVariables.user.privileges.appointments.edit === false) { revertFunc(); Backend.displayNotification(EALang.no_privileges_edit_appointments); return; @@ -569,7 +586,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#notification').hide('bind'); } - if (event.data.is_unavailable == false) { + if (event.data.is_unavailable === '0') { // Prepare appointment data. var appointment = GeneralFunctions.clone(event.data); @@ -609,15 +626,18 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; event.data.end_datetime = appointment.end_datetime; var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_appointment'; + var data = { csrfToken: GlobalVariables.csrfToken, appointment_data: JSON.stringify(appointment) }; - $.post(url, data, function (response) { - $('#notification').hide('blind'); - revertFunc(); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + $.post(url, data) + .done(function () { + $('#notification').hide('blind'); + revertFunc(); + }) + .fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang.appointment_updated, [ @@ -631,7 +651,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; }; // Update appointment data. - BackendCalendarApi.saveAppointment(appointment, undefined, successCallback); + BackendCalendarApi.saveAppointment(appointment, null, successCallback); } else { // Update unavailable time period. var unavailable = { @@ -662,10 +682,12 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; unavailable: JSON.stringify(unavailable) }; - $.post(url, data, function (response) { - $('#notification').hide('blind'); - revertFunc(); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + $.post(url, data) + .done(function () { + $('#notification').hide('blind'); + revertFunc(); + }) + .fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang.unavailable_updated, [ @@ -744,6 +766,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; */ function _refreshCalendarAppointments($calendar, recordId, filterType, startDate, endDate) { var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_get_calendar_appointments'; + var data = { csrfToken: GlobalVariables.csrfToken, record_id: recordId, @@ -752,232 +775,95 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; filter_type: filterType }; - $('#loading').css('visibility', 'hidden'); - return $.post(url, data, function (response) { - // Add appointments to calendar. - var calendarEvents = []; - var $calendar = $('#calendar'); + return $.post(url, data) + .done(function (response) { + // Add appointments to calendar. + var calendarEvents = []; + var $calendar = $('#calendar'); - $.each(response.appointments, function (index, appointment) { - var event = { - id: appointment.id, - title: appointment.service.name + ' - ' - + appointment.customer.first_name + ' ' - + appointment.customer.last_name, - start: moment(appointment.start_datetime), - end: moment(appointment.end_datetime), - allDay: false, - data: appointment // Store appointment data for later use. - }; + $.each(response.appointments, function (index, appointment) { + var event = { + id: appointment.id, + title: appointment.service.name + ' - ' + + appointment.customer.first_name + ' ' + + appointment.customer.last_name, + start: moment(appointment.start_datetime), + end: moment(appointment.end_datetime), + allDay: false, + data: appointment // Store appointment data for later use. + }; - calendarEvents.push(event); - }); + calendarEvents.push(event); + }); - $calendar.fullCalendar('removeEvents'); - $calendar.fullCalendar('addEventSource', calendarEvents); + $calendar.fullCalendar('removeEvents'); + $calendar.fullCalendar('addEventSource', calendarEvents); - var weekDays = [ - 'sunday', - 'monday', - 'tuesday', - 'wednesday', - 'thursday', - 'friday', - 'saturday' - ]; + var weekDays = [ + 'sunday', + 'monday', + 'tuesday', + 'wednesday', + 'thursday', + 'friday', + 'saturday' + ]; - // :: ADD PROVIDER'S UNAVAILABLE TIME PERIODS - var calendarView = $calendar.fullCalendar('getView').name; + // :: ADD PROVIDER'S UNAVAILABLE TIME PERIODS + var calendarView = $calendar.fullCalendar('getView').name; - if (filterType === FILTER_TYPE_PROVIDER && calendarView !== 'month') { - $.each(GlobalVariables.availableProviders, function (index, provider) { - if (provider.id == recordId) { - var workingPlan={}; - var workingPlanBulk = jQuery.parseJSON(provider.settings.working_plan); - var extraWorkingPlan = jQuery.parseJSON(provider.settings.extra_working_plan); - var unavailablePeriod; + if (filterType === FILTER_TYPE_PROVIDER && calendarView !== 'month') { + $.each(GlobalVariables.availableProviders, function (index, provider) { + if (Number(provider.id) === Number(recordId)) { + var workingPlan={}; + var workingPlanBulk = jQuery.parseJSON(provider.settings.working_plan); + var extraWorkingPlan = jQuery.parseJSON(provider.settings.extra_working_plan); + var unavailablePeriod; - // 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); - workingPlan = GeneralFunctions.sortWeekDictionary(workingPlanBulk, firstWeekdayNumber); + // 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); + workingPlan = GeneralFunctions.sortWeekDictionary(workingPlanBulk, firstWeekdayNumber); - switch (calendarView) { - case 'agendaDay': - var selectedDayName = GeneralFunctions - .getWeekdayName(parseInt($calendar.fullCalendar('getView').start.format('d'))); + switch (calendarView) { + case 'agendaDay': + var selectedDayName = GeneralFunctions + .getWeekdayName(parseInt($calendar.fullCalendar('getView').start.format('d'))); - // Add custom unavailable periods. - $.each(response.unavailables, function (index, unavailable) { - var notes = unavailable.notes ? ' - ' + unavailable.notes : ''; + // Add custom unavailable periods. + $.each(response.unavailables, function (index, unavailable) { + var notes = unavailable.notes ? ' - ' + unavailable.notes : ''; - if (unavailable.notes.length > 30) { - notes = unavailable.notes.substring(0, 30) + '...' - } + if (unavailable.notes.length > 30) { + notes = unavailable.notes.substring(0, 30) + '...' + } - var unavailablePeriod = { - title: EALang.unavailable + notes, - start: moment(unavailable.start_datetime), - end: moment(unavailable.end_datetime), - allDay: false, - color: '#879DB4', - editable: true, - className: 'fc-unavailable fc-custom', - data: unavailable - }; - - $calendar.fullCalendar('renderEvent', unavailablePeriod, false); - }); - - // Non-working day. - if (workingPlan[selectedDayName] == null) { - // Extra working plan day. - var selectedDay = $calendar.fullCalendar('getView').intervalStart.clone(); - selectedDay.locale('en'); - if (extraWorkingPlan != null && selectedDay.format() in extraWorkingPlan) { - workingPlan[selectedDay.format('dddd').toLowerCase()] = extraWorkingPlan[selectedDay.format('YYYY-MM-DD')]; - - var start_extra = selectedDay.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[selectedDay.format('YYYY-MM-DD')].start; - var end_extra = selectedDay.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[selectedDay.format('YYYY-MM-DD')].end; - - var extraPeriod = { - title: EALang.extra_period, - start: moment(start_extra, 'YYYY-MM-DD HH:mm', true), - end: moment(end_extra, 'YYYY-MM-DD HH:mm', true).add(1, 'day'), - allDay: true, - color: '#879DB4', - editable: false, - className: 'fc-extra fc-custom', - data: provider - }; - - $calendar.fullCalendar('renderEvent', extraPeriod, false); - } else { - unavailablePeriod = { - title: EALang.not_working, - start: $calendar.fullCalendar('getView').intervalStart.clone(), - end: $calendar.fullCalendar('getView').intervalEnd.clone(), + var unavailablePeriod = { + title: EALang.unavailable + notes, + start: moment(unavailable.start_datetime), + end: moment(unavailable.end_datetime), allDay: false, - color: '#BEBEBE', - editable: false, - className: 'fc-unavailable' + color: '#879DB4', + editable: true, + className: 'fc-unavailable fc-custom', + data: unavailable }; $calendar.fullCalendar('renderEvent', unavailablePeriod, false); + }); - return; // Go to next loop. - } - } + // Non-working day. + if (workingPlan[selectedDayName] === null) { + // Extra working plan day. + var selectedDay = $calendar.fullCalendar('getView').intervalStart.clone(); + selectedDay.locale('en'); + if (extraWorkingPlan && selectedDay.format() in extraWorkingPlan) { + workingPlan[selectedDay.format('dddd').toLowerCase()] = extraWorkingPlan[selectedDay.format('YYYY-MM-DD')]; - // Add unavailable period before work starts. - var calendarDateStart = moment($calendar.fullCalendar('getView').start.format('YYYY-MM-DD') + ' 00:00:00'); - var startHour = workingPlan[selectedDayName].start.split(':'); - var workDateStart = calendarDateStart.clone(); - workDateStart.hour(parseInt(startHour[0])); - workDateStart.minute(parseInt(startHour[1])); - - if (calendarDateStart < workDateStart) { - var unavailablePeriodBeforeWorkStarts = { - title: EALang.not_working, - start: calendarDateStart, - end: workDateStart, - allDay: false, - color: '#BEBEBE', - editable: false, - className: 'fc-unavailable' - }; - $calendar.fullCalendar('renderEvent', unavailablePeriodBeforeWorkStarts, false); - } - - // Add unavailable period after work ends. - var calendarDateEnd = moment($calendar.fullCalendar('getView').end.format('YYYY-MM-DD') + ' 00:00:00'); - var endHour = workingPlan[selectedDayName].end.split(':'); - var workDateEnd = calendarDateStart.clone(); - - workDateEnd.hour(parseInt(endHour[0])); - workDateEnd.minute(parseInt(endHour[1])); - - if (calendarDateEnd > workDateEnd) { - var unavailablePeriodAfterWorkEnds = { - title: EALang.not_working, - start: workDateEnd, - end: calendarDateEnd, - allDay: false, - color: '#BEBEBE', - editable: false, - className: 'fc-unavailable' - }; - - $calendar.fullCalendar('renderEvent', unavailablePeriodAfterWorkEnds, false); - } - - // Add unavailable periods for breaks. - var breakStart; - var breakEnd; - - $.each(workingPlan[selectedDayName].breaks, function (index, currentBreak) { - var breakStartString = currentBreak.start.split(':'); - breakStart = calendarDateStart.clone(); - breakStart.hour(parseInt(breakStartString[0])); - breakStart.minute(parseInt(breakStartString[1])); - - var breakEndString = currentBreak.end.split(':'); - breakEnd = calendarDateStart.clone(); - breakEnd.hour(parseInt(breakEndString[0])); - breakEnd.minute(parseInt(breakEndString[1])); - - var unavailablePeriod = { - title: EALang.break, - start: breakStart, - end: breakEnd, - allDay: false, - color: '#BEBEBE', - editable: false, - className: 'fc-unavailable fc-break' - }; - - $calendar.fullCalendar('renderEvent', unavailablePeriod, false); - }); - - break; - - case 'agendaWeek': - var currentDateStart = $calendar.fullCalendar('getView').start.clone(); - var currentDateEnd = currentDateStart.clone().add(1, 'days'); - - // Add custom unavailable periods (they are always displayed on the calendar, even if - // the provider won't work on that day). - $.each(response.unavailables, function (index, unavailable) { - var notes = unavailable.notes ? ' - ' + unavailable.notes : ''; - - if (unavailable.notes.length > 30) { - notes = unavailable.notes.substring(0, 30) + '...' - } - - unavailablePeriod = { - title: EALang.unavailable + notes, - start: moment(unavailable.start_datetime), - end: moment(unavailable.end_datetime), - allDay: false, - color: '#879DB4', - editable: true, - className: 'fc-unavailable fc-custom', - data: unavailable - }; - - $calendar.fullCalendar('renderEvent', unavailablePeriod, false); - }); - - $.each(workingPlan, function (index, workingDay) { - if (workingDay == null) { - // Check if the day is an extra working day added to the working plan - if (extraWorkingPlan != null && currentDateStart.format('YYYY-MM-DD') in extraWorkingPlan) { - workingDay = extraWorkingPlan[currentDateStart.format('YYYY-MM-DD')] - - var start_extra = currentDateStart.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[currentDateStart.format('YYYY-MM-DD')].start; - var end_extra = currentDateStart.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[currentDateStart.format('YYYY-MM-DD')].end; + var start_extra = selectedDay.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[selectedDay.format('YYYY-MM-DD')].start; + var end_extra = selectedDay.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[selectedDay.format('YYYY-MM-DD')].end; var extraPeriod = { title: EALang.extra_period, @@ -992,87 +878,83 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $calendar.fullCalendar('renderEvent', extraPeriod, false); } else { - // Add a full day unavailable event. unavailablePeriod = { title: EALang.not_working, - start: moment(currentDateStart.format('YYYY-MM-DD')), - end: moment(currentDateEnd.format('YYYY-MM-DD')), + start: $calendar.fullCalendar('getView').intervalStart.clone(), + end: $calendar.fullCalendar('getView').intervalEnd.clone(), allDay: false, color: '#BEBEBE', editable: false, className: 'fc-unavailable' }; - $calendar.fullCalendar('renderEvent', unavailablePeriod, true); - currentDateStart.add(1, 'days'); - currentDateEnd.add(1, 'days'); + $calendar.fullCalendar('renderEvent', unavailablePeriod, false); - return; // Go to the next loop. + return; // Go to next loop. } } - var start; - var end; - // Add unavailable period before work starts. - var workingDayStartString = workingDay.start.split(':'); - start = currentDateStart.clone(); - start.hour(parseInt(workingDayStartString[0])); - start.minute(parseInt(workingDayStartString[1])); + var calendarDateStart = moment($calendar.fullCalendar('getView').start.format('YYYY-MM-DD') + ' 00:00:00'); + var startHour = workingPlan[selectedDayName].start.split(':'); + var workDateStart = calendarDateStart.clone(); + workDateStart.hour(parseInt(startHour[0])); + workDateStart.minute(parseInt(startHour[1])); - if (currentDateStart < start) { - unavailablePeriod = { + if (calendarDateStart < workDateStart) { + var unavailablePeriodBeforeWorkStarts = { title: EALang.not_working, - start: moment(currentDateStart.format('YYYY-MM-DD') + ' 00:00:00'), - end: moment(currentDateStart.format('YYYY-MM-DD') + ' ' + workingDay.start + ':00'), + start: calendarDateStart, + end: workDateStart, allDay: false, color: '#BEBEBE', editable: false, className: 'fc-unavailable' }; - - $calendar.fullCalendar('renderEvent', unavailablePeriod, true); + $calendar.fullCalendar('renderEvent', unavailablePeriodBeforeWorkStarts, false); } // Add unavailable period after work ends. - var workingDayEndString = workingDay.end.split(':'); - end = currentDateStart.clone(); - end.hour(parseInt(workingDayEndString[0])); - end.minute(parseInt(workingDayEndString[1])); + var calendarDateEnd = moment($calendar.fullCalendar('getView').end.format('YYYY-MM-DD') + ' 00:00:00'); + var endHour = workingPlan[selectedDayName].end.split(':'); + var workDateEnd = calendarDateStart.clone(); - if (currentDateEnd > end) { - unavailablePeriod = { + workDateEnd.hour(parseInt(endHour[0])); + workDateEnd.minute(parseInt(endHour[1])); + + if (calendarDateEnd > workDateEnd) { + var unavailablePeriodAfterWorkEnds = { title: EALang.not_working, - start: moment(currentDateStart.format('YYYY-MM-DD') + ' ' + workingDay.end + ':00'), - end: moment(currentDateEnd.format('YYYY-MM-DD') + ' 00:00:00'), + start: workDateEnd, + end: calendarDateEnd, allDay: false, color: '#BEBEBE', editable: false, className: 'fc-unavailable' }; - $calendar.fullCalendar('renderEvent', unavailablePeriod, false); + $calendar.fullCalendar('renderEvent', unavailablePeriodAfterWorkEnds, false); } - // Add unavailable periods during day breaks. + // Add unavailable periods for breaks. var breakStart; var breakEnd; - $.each(workingDay.breaks, function (index, currentBreak) { + $.each(workingPlan[selectedDayName].breaks, function (index, currentBreak) { var breakStartString = currentBreak.start.split(':'); - breakStart = currentDateStart.clone(); + breakStart = calendarDateStart.clone(); breakStart.hour(parseInt(breakStartString[0])); breakStart.minute(parseInt(breakStartString[1])); var breakEndString = currentBreak.end.split(':'); - breakEnd = currentDateStart.clone(); + breakEnd = calendarDateStart.clone(); breakEnd.hour(parseInt(breakEndString[0])); breakEnd.minute(parseInt(breakEndString[1])); var unavailablePeriod = { title: EALang.break, - start: moment(currentDateStart.format('YYYY-MM-DD') + ' ' + currentBreak.start), - end: moment(currentDateStart.format('YYYY-MM-DD') + ' ' + currentBreak.end), + start: breakStart, + end: breakEnd, allDay: false, color: '#BEBEBE', editable: false, @@ -1082,16 +964,157 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $calendar.fullCalendar('renderEvent', unavailablePeriod, false); }); - currentDateStart.add(1, 'days'); - currentDateEnd.add(1, 'days'); - }); + break; - break; + case 'agendaWeek': + var currentDateStart = $calendar.fullCalendar('getView').start.clone(); + var currentDateEnd = currentDateStart.clone().add(1, 'days'); + + // Add custom unavailable periods (they are always displayed on the calendar, even if + // the provider won't work on that day). + $.each(response.unavailables, function (index, unavailable) { + var notes = unavailable.notes ? ' - ' + unavailable.notes : ''; + + if (unavailable.notes.length > 30) { + notes = unavailable.notes.substring(0, 30) + '...' + } + + unavailablePeriod = { + title: EALang.unavailable + notes, + start: moment(unavailable.start_datetime), + end: moment(unavailable.end_datetime), + allDay: false, + color: '#879DB4', + editable: true, + className: 'fc-unavailable fc-custom', + data: unavailable + }; + + $calendar.fullCalendar('renderEvent', unavailablePeriod, false); + }); + + $.each(workingPlan, function (index, workingDay) { + if (workingDay === null) { + // Check if the day is an extra working day added to the working plan + if (extraWorkingPlan && currentDateStart.format('YYYY-MM-DD') in extraWorkingPlan) { + workingDay = extraWorkingPlan[currentDateStart.format('YYYY-MM-DD')] + + var start_extra = currentDateStart.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[currentDateStart.format('YYYY-MM-DD')].start; + var end_extra = currentDateStart.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[currentDateStart.format('YYYY-MM-DD')].end; + + var extraPeriod = { + title: EALang.extra_period, + start: moment(start_extra, 'YYYY-MM-DD HH:mm', true), + end: moment(end_extra, 'YYYY-MM-DD HH:mm', true).add(1, 'day'), + allDay: true, + color: '#879DB4', + editable: false, + className: 'fc-extra fc-custom', + data: provider + }; + + $calendar.fullCalendar('renderEvent', extraPeriod, false); + } else { + // Add a full day unavailable event. + unavailablePeriod = { + title: EALang.not_working, + start: moment(currentDateStart.format('YYYY-MM-DD')), + end: moment(currentDateEnd.format('YYYY-MM-DD')), + allDay: false, + color: '#BEBEBE', + editable: false, + className: 'fc-unavailable' + }; + + $calendar.fullCalendar('renderEvent', unavailablePeriod, true); + currentDateStart.add(1, 'days'); + currentDateEnd.add(1, 'days'); + + return; // Go to the next loop. + } + } + + var start; + var end; + + // Add unavailable period before work starts. + var workingDayStartString = workingDay.start.split(':'); + start = currentDateStart.clone(); + start.hour(parseInt(workingDayStartString[0])); + start.minute(parseInt(workingDayStartString[1])); + + if (currentDateStart < start) { + unavailablePeriod = { + title: EALang.not_working, + start: moment(currentDateStart.format('YYYY-MM-DD') + ' 00:00:00'), + end: moment(currentDateStart.format('YYYY-MM-DD') + ' ' + workingDay.start + ':00'), + allDay: false, + color: '#BEBEBE', + editable: false, + className: 'fc-unavailable' + }; + + $calendar.fullCalendar('renderEvent', unavailablePeriod, true); + } + + // Add unavailable period after work ends. + var workingDayEndString = workingDay.end.split(':'); + end = currentDateStart.clone(); + end.hour(parseInt(workingDayEndString[0])); + end.minute(parseInt(workingDayEndString[1])); + + if (currentDateEnd > end) { + unavailablePeriod = { + title: EALang.not_working, + start: moment(currentDateStart.format('YYYY-MM-DD') + ' ' + workingDay.end + ':00'), + end: moment(currentDateEnd.format('YYYY-MM-DD') + ' 00:00:00'), + allDay: false, + color: '#BEBEBE', + editable: false, + className: 'fc-unavailable' + }; + + $calendar.fullCalendar('renderEvent', unavailablePeriod, false); + } + + // Add unavailable periods during day breaks. + var breakStart; + var breakEnd; + + $.each(workingDay.breaks, function (index, currentBreak) { + var breakStartString = currentBreak.start.split(':'); + breakStart = currentDateStart.clone(); + breakStart.hour(parseInt(breakStartString[0])); + breakStart.minute(parseInt(breakStartString[1])); + + var breakEndString = currentBreak.end.split(':'); + breakEnd = currentDateStart.clone(); + breakEnd.hour(parseInt(breakEndString[0])); + breakEnd.minute(parseInt(breakEndString[1])); + + var unavailablePeriod = { + title: EALang.break, + start: moment(currentDateStart.format('YYYY-MM-DD') + ' ' + currentBreak.start), + end: moment(currentDateStart.format('YYYY-MM-DD') + ' ' + currentBreak.end), + allDay: false, + color: '#BEBEBE', + editable: false, + className: 'fc-unavailable fc-break' + }; + + $calendar.fullCalendar('renderEvent', unavailablePeriod, false); + }); + + currentDateStart.add(1, 'days'); + currentDateEnd.add(1, 'days'); + }); + + break; + } } - } - }); - } - }, 'json') + }); + } + }) .fail(GeneralFunctions.ajaxFailureHandler) .always(function() { $('#loading').css('visibility', '') @@ -1168,18 +1191,20 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#insert-appointment').trigger('click'); // Preselect service & provider. + var service; + if ($('#select-filter-item option:selected').attr('type') === FILTER_TYPE_SERVICE) { - var service = GlobalVariables.availableServices.find(function (service) { - return service.id == $('#select-filter-item').val() + service = GlobalVariables.availableServices.find(function (service) { + return Number(service.id) === Number($('#select-filter-item').val()); }); $('#select-service').val(service.id).trigger('change'); } else { var provider = GlobalVariables.availableProviders.find(function (provider) { - return provider.id == $('#select-filter-item').val(); + return Number(provider.id) === Number($('#select-filter-item').val()); }); - var service = GlobalVariables.availableServices.find(function (service) { + service = GlobalVariables.availableServices.find(function (service) { return provider.services.indexOf(service.id) !== -1 }); @@ -1268,24 +1293,24 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; } // Check permissions. - if (GlobalVariables.user.role_slug == Backend.DB_SLUG_PROVIDER) { + if (GlobalVariables.user.role_slug === Backend.DB_SLUG_PROVIDER) { $('#select-filter-item optgroup:eq(0)') .find('option[value="' + GlobalVariables.user.id + '"]') .prop('selected', true); $('#select-filter-item').prop('disabled', true); } - if (GlobalVariables.user.role_slug == Backend.DB_SLUG_SECRETARY) { + if (GlobalVariables.user.role_slug === Backend.DB_SLUG_SECRETARY) { $('#select-filter-item optgroup:eq(1)').remove(); } - if (GlobalVariables.user.role_slug == Backend.DB_SLUG_SECRETARY) { + if (GlobalVariables.user.role_slug === Backend.DB_SLUG_SECRETARY) { // Remove the providers that are not connected to the secretary. $('#select-filter-item option[type="provider"]').each(function (index, option) { var found = false; - $.each(GlobalVariables.secretaryProviders, function (index, id) { - if ($(option).val() == id) { + $.each(GlobalVariables.secretaryProviders, function (index, secretaryProviderId) { + if (Number($(option).val()) === Number(secretaryProviderId)) { found = true; return false; } @@ -1296,7 +1321,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; } }); - if ($('#select-filter-item option[type="provider"]').length == 0) { + if (!$('#select-filter-item option[type="provider"]').length) { $('#select-filter-item optgroup[type="providers-group"]').remove(); } } @@ -1307,7 +1332,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; $('#select-filter-item').trigger('change'); // Display the edit dialog if an appointment hash is provided. - if (GlobalVariables.editAppointment != null) { + if (GlobalVariables.editAppointment) { var $dialog = $('#manage-appointment'); var appointment = GlobalVariables.editAppointment; BackendCalendarAppointmentsModal.resetAppointmentDialog(); @@ -1361,7 +1386,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {}; } }); - if ($('#select-filter-item option').length == 0) { + if (!$('#select-filter-item option').length) { $('#calendar-actions button').prop('disabled', true); } diff --git a/assets/js/backend_calendar_google_sync.js b/assets/js/backend_calendar_google_sync.js index 3acc5733..94f5aaa9 100644 --- a/assets/js/backend_calendar_google_sync.js +++ b/assets/js/backend_calendar_google_sync.js @@ -48,7 +48,7 @@ window.BackendCalendarGoogleSync = window.BackendCalendarGoogleSync || {}; // becomes "undefined" and when it comes back to the redirect URL it changes back. So check // whether the variable is undefined to avoid javascript errors. try { - if (windowHandle.document !== undefined) { + if (windowHandle.document) { if (windowHandle.document.URL.indexOf(redirectUrl) !== -1) { // The user has granted access to his data. windowHandle.close(); @@ -61,21 +61,24 @@ window.BackendCalendarGoogleSync = window.BackendCalendarGoogleSync || {}; // Display the calendar selection dialog. First we will get a list of the available // user's calendars and then we will display a selection modal so the user can select // the sync calendar. - var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_get_google_calendars'; - var postData = { + var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_get_google_calendars'; + + var data = { csrfToken: GlobalVariables.csrfToken, provider_id: $('#select-filter-item').val() }; - $.post(postUrl, postData, function (response) { - $('#google-calendar').empty(); - $.each(response, function () { - var option = ''; - $('#google-calendar').append(option); - }); + $.post(url, data) + .done(function (response) { + $('#google-calendar').empty(); + $.each(response, function () { + var option = ''; + $('#google-calendar').append(option); + }); - $('#select-google-calendar').modal('show'); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + $('#select-google-calendar').modal('show'); + }) + .fail(GeneralFunctions.ajaxFailureHandler); } } } catch (Error) { @@ -90,7 +93,7 @@ window.BackendCalendarGoogleSync = window.BackendCalendarGoogleSync || {}; // Update page elements and make an AJAX call to remove the google sync setting of the // selected provider. $.each(GlobalVariables.availableProviders, function (index, provider) { - if (provider.id == $('#select-filter-item').val()) { + if (Number(provider.id) === Number($('#select-filter-item').val())) { provider.settings.google_sync = '0'; provider.settings.google_token = null; @@ -112,6 +115,7 @@ window.BackendCalendarGoogleSync = window.BackendCalendarGoogleSync || {}; */ $('#select-calendar').click(function () { var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_select_google_calendar'; + var data = { csrfToken: GlobalVariables.csrfToken, provider_id: $('#select-filter-item').val(), @@ -166,6 +170,7 @@ window.BackendCalendarGoogleSync = window.BackendCalendarGoogleSync || {}; // Make an ajax call to the server in order to disable the setting // from the database. var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_disable_provider_sync'; + var data = { csrfToken: GlobalVariables.csrfToken, provider_id: providerId diff --git a/assets/js/backend_calendar_table_view.js b/assets/js/backend_calendar_table_view.js index 510f959f..df9a39ae 100755 --- a/assets/js/backend_calendar_table_view.js +++ b/assets/js/backend_calendar_table_view.js @@ -145,7 +145,7 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; var $dialog; - if (lastFocusedEventData.data.is_unavailable == false) { + if (lastFocusedEventData.data.is_unavailable === '0') { var appointment = lastFocusedEventData.data; $dialog = $('#manage-appointment'); @@ -210,44 +210,53 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; $calendar.on('click', '.delete-popover', function () { $(this).parents().eq(2).remove(); // Hide the popover. + var url; + var data; + // If id_role parameter exists the popover is an extra working day. if (lastFocusedEventData.data.hasOwnProperty('id_roles')) { // Do not display confirmation prompt. - var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_extra_period'; - var data = { + url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_extra_period'; + + data = { csrfToken: GlobalVariables.csrfToken, extra_period: lastFocusedEventData.start.format('YYYY-MM-DD'), provider_id: lastFocusedEventData.data.id }; - $.post(url, data, function (response) { - $('#message_box').dialog('close'); + $.post(url, data) + .done(function (response) { + $('#message_box').dialog('close'); - var extraWorkingPlan = jQuery.parseJSON(lastFocusedEventData.data.settings.extra_working_plan); - delete extraWorkingPlan[lastFocusedEventData.start.format('YYYY-MM-DD')]; - lastFocusedEventData.data.settings.extra_working_plan = JSON.stringify(extraWorkingPlan); + var extraWorkingPlan = jQuery.parseJSON(lastFocusedEventData.data.settings.extra_working_plan); + delete extraWorkingPlan[lastFocusedEventData.start.format('YYYY-MM-DD')]; + lastFocusedEventData.data.settings.extra_working_plan = JSON.stringify(extraWorkingPlan); - // Refresh calendar event items. - $('#select-filter-item').trigger('change'); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); - } else if (lastFocusedEventData.data.is_unavailable == false) { + // Refresh calendar event items. + $('#select-filter-item').trigger('change'); + }) + .fail(GeneralFunctions.ajaxFailureHandler); + } else if (lastFocusedEventData.data.is_unavailable === '0') { var buttons = [ { text: 'OK', click: function () { - var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_appointment'; - var data = { + url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_appointment'; + + data = { csrfToken: GlobalVariables.csrfToken, appointment_id: lastFocusedEventData.data.id, delete_reason: $('#delete-reason').val() }; - $.post(url, data, function (response) { - $('#message_box').dialog('close'); + $.post(url, data) + .done(function () { + $('#message_box').dialog('close'); - // Refresh calendar event items. - $('#select-filter-item').trigger('change'); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + // Refresh calendar event items. + $('#select-filter-item').trigger('change'); + }) + .fail(GeneralFunctions.ajaxFailureHandler); } }, { @@ -266,18 +275,21 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; $('#delete-reason').css('width', '100%'); } else { // Do not display confirmation prompt. - var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_unavailable'; - var data = { + url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_unavailable'; + + data = { csrfToken: GlobalVariables.csrfToken, unavailable_id: lastFocusedEventData.data.id }; - $.post(url, data, function (response) { - $('#message_box').dialog('close'); + $.post(url, data) + .done(function () { + $('#message_box').dialog('close'); - // Refresh calendar event items. - $('#select-filter-item').trigger('change'); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + // Refresh calendar event items. + $('#select-filter-item').trigger('change'); + }) + .fail(GeneralFunctions.ajaxFailureHandler); } }); } @@ -763,7 +775,7 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; var end = view.end.clone(); var selDayName = start.toDate().toString('dddd').toLowerCase(); - if (workingPlan[selDayName] == null) { + if (workingPlan[selDayName] === null) { var nonWorkingDay = { title: EALang.not_working, start: start, @@ -982,10 +994,10 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; if ($(this).hasClass('fc-unavailable') || $parent.hasClass('fc-unavailable') || $altParent.hasClass('fc-unavailable')) { displayEdit = (($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) - && GlobalVariables.user.privileges.appointments.edit == true) + && GlobalVariables.user.privileges.appointments.edit === true) ? '' : 'hide'; displayDelete = (($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) - && GlobalVariables.user.privileges.appointments.delete == true) + && GlobalVariables.user.privileges.appointments.delete === true) ? '' : 'hide'; // Same value at the time. var notes = ''; @@ -1013,7 +1025,7 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; ''; } else if ($(this).hasClass('fc-extra') || $parent.hasClass('fc-extra') || $altParent.hasClass('fc-extra')) { displayDelete = (($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom')) - && GlobalVariables.user.privileges.appointments.delete == true) + && GlobalVariables.user.privileges.appointments.delete === true) ? '' : 'hide'; // Same value at the time. var provider = ''; @@ -1045,9 +1057,9 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; ''; } else { - displayEdit = (GlobalVariables.user.privileges.appointments.edit == true) + displayEdit = (GlobalVariables.user.privileges.appointments.edit === true) ? '' : 'hide'; - displayDelete = (GlobalVariables.user.privileges.appointments.delete == true) + displayDelete = (GlobalVariables.user.privileges.appointments.delete === true) ? '' : 'hide'; html = @@ -1120,7 +1132,7 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; * @see updateAppointmentData() */ function onEventResize(event, delta, revertFunc, jsEvent, ui, view) { - if (GlobalVariables.user.privileges.appointments.edit == false) { + if (GlobalVariables.user.privileges.appointments.edit === false) { revertFunc(); Backend.displayNotification(EALang.no_privileges_edit_appointments); return; @@ -1132,7 +1144,9 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; $('#notification').hide('bind'); } - if (event.data.is_unavailable == false) { + var successCallback; + + if (event.data.is_unavailable === '0') { // Prepare appointment data. event.data.end_datetime = Date.parseExact( event.data.end_datetime, 'yyyy-MM-dd HH:mm:ss') @@ -1147,7 +1161,7 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; delete appointment.service; // Success callback - var successCallback = function () { + successCallback = function () { // Display success notification to user. var undoFunction = function () { appointment.end_datetime = event.data.end_datetime = Date.parseExact( @@ -1162,10 +1176,12 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; appointment_data: JSON.stringify(appointment) }; - $.post(url, data, function () { - $('#notification').hide('blind'); - revertFunc(); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + $.post(url, data) + .done(function () { + $('#notification').hide('blind'); + revertFunc(); + }) + .fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang.appointment_updated, [ @@ -1181,7 +1197,7 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; }; // Update appointment data. - BackendCalendarApi.saveAppointment(appointment, undefined, successCallback); + BackendCalendarApi.saveAppointment(appointment, null, successCallback); } else { // Update unavailable time period. var unavailable = { @@ -1194,7 +1210,7 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; event.data.end_datetime = unavailable.end_datetime; // Define success callback function. - var successCallback = function () { + successCallback = function () { // Display success notification to user. var undoFunction = function () { unavailable.end_datetime = event.data.end_datetime = Date.parseExact( @@ -1203,15 +1219,18 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; .toString('yyyy-MM-dd HH:mm:ss'); var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_unavailable'; + var data = { csrfToken: GlobalVariables.csrfToken, unavailable: JSON.stringify(unavailable) }; - $.post(url, data, function () { - $('#notification').hide('blind'); - revertFunc(); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + $.post(url, data) + .done(function () { + $('#notification').hide('blind'); + revertFunc(); + }) + .fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang.unavailable_updated, [ @@ -1237,8 +1256,8 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; * This event handler is triggered whenever the user drags and drops an event into a different position * on the calendar. We need to update the database with this change. This is done via an ajax call. */ - function onEventDrop(event, delta, revertFunc, jsEvent, ui, view) { - if (GlobalVariables.user.privileges.appointments.edit == false) { + function onEventDrop(event, delta, revertFunc) { + if (GlobalVariables.user.privileges.appointments.edit === false) { revertFunc(); Backend.displayNotification(EALang.no_privileges_edit_appointments); return; @@ -1250,7 +1269,7 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; var successCallback; - if (event.data.is_unavailable == false) { + if (event.data.is_unavailable === '0') { // Prepare appointment data. var appointment = GeneralFunctions.clone(event.data); @@ -1290,15 +1309,18 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; event.data.end_datetime = appointment.end_datetime; var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_appointment'; + var data = { csrfToken: GlobalVariables.csrfToken, appointment_data: JSON.stringify(appointment) }; - $.post(url, data, function () { - $('#notification').hide('blind'); - revertFunc(); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + $.post(url, data) + .done(function () { + $('#notification').hide('blind'); + revertFunc(); + }) + .fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang.appointment_updated, [ @@ -1312,7 +1334,7 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; }; // Update appointment data. - BackendCalendarApi.saveAppointment(appointment, undefined, successCallback); + BackendCalendarApi.saveAppointment(appointment, null, successCallback); } else { // Update unavailable time period. var unavailable = { @@ -1338,15 +1360,18 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; event.data.end_datetime = unavailable.end_datetime; var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_unavailable'; + var data = { csrfToken: GlobalVariables.csrfToken, unavailable: JSON.stringify(unavailable) }; - $.post(url, data, function () { - $('#notification').hide('blind'); - revertFunc(); - }, 'json').fail(GeneralFunctions.ajaxFailureHandler); + $.post(url, data) + .done(function () { + $('#notification').hide('blind'); + revertFunc(); + }) + .fail(GeneralFunctions.ajaxFailureHandler); }; Backend.displayNotification(EALang.unavailable_updated, [ @@ -1405,6 +1430,7 @@ window.BackendCalendarTableView = window.BackendCalendarTableView || {}; */ function getCalendarEvents(startDate, endDate) { var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_get_calendar_events'; + var data = { csrfToken: GlobalVariables.csrfToken, startDate: startDate.toString('yyyy-MM-dd'), diff --git a/assets/js/backend_categories_helper.js b/assets/js/backend_categories_helper.js index 5e931465..7666ceb5 100644 --- a/assets/js/backend_categories_helper.js +++ b/assets/js/backend_categories_helper.js @@ -169,41 +169,44 @@ * @param {Boolean} display Optional (false), if true then the selected record will be displayed on the form. */ CategoriesHelper.prototype.filter = function (key, selectId, display) { - var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_service_categories'; - var postData = { + var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_filter_service_categories'; + + var data = { csrfToken: GlobalVariables.csrfToken, key: key, limit: this.filterLimit }; - $.post(postUrl, postData, function (response) { - this.filterResults = response; + $.post(url, data) + .done(function (response) { + this.filterResults = response; - $('#filter-categories .results').html(''); - $.each(response, function (index, category) { - var html = this.getFilterHtml(category); - $('#filter-categories .results').append(html); - }.bind(this)); + $('#filter-categories .results').html(''); + $.each(response, function (index, category) { + var html = this.getFilterHtml(category); + $('#filter-categories .results').append(html); + }.bind(this)); - if (response.length === 0) { - $('#filter-categories .results').html('' + EALang.no_records_found + ''); - } else if (response.length === this.filterLimit) { - $('