/**
* Contains the functionality of the backend settings page. Can either work for
* system or user settings, but the actions allowed to the user are restricted to
* his role (only admin has full privileges).
*
* @namespace BackendSettings
*/
var BackendSettings = {
SETTINGS_SYSTEM: 'SETTINGS_SYSTEM',
SETTINGS_USER: 'SETTINGS_USER',
/**
* Use this WorkingPlan class instance to perform actions on the page's working plan
* tables.
*/
wp: {},
/**
* Tab settings object.
*
* @type {object}
*/
settings: {},
/**
* Initialize Page
*
* @param {bool} bindEventHandlers (OPTIONAL)Determines whether to bind the default event
* handlers (default = true).
* @returns {undefined}
*/
initialize: function(bindEventHandlers) {
if (bindEventHandlers == undefined) bindEventHandlers = true;
// Apply setting values from database.
$.each(GlobalVariables.settings.system, function(index, setting) {
$('input[data-field="' + setting.name + '"]').val(setting.value);
});
var workingPlan = {};
$.each(GlobalVariables.settings.system, function(index, setting) {
if (setting.name == 'company_working_plan') {
workingPlan = $.parseJSON(setting.value);
return false;
}
});
BackendSettings.wp = new WorkingPlan();
BackendSettings.wp.setup(workingPlan);
BackendSettings.wp.timepickers(false);
// Book Advance Timeout Spinner
$('#book-advance-timeout').spinner({
'min': 0
});
// Load user settings into form
$('#user-id').val(GlobalVariables.settings.user.id);
$('#first-name').val(GlobalVariables.settings.user.first_name);
$('#last-name').val(GlobalVariables.settings.user.last_name);
$('#email').val(GlobalVariables.settings.user.email);
$('#mobile-number').val(GlobalVariables.settings.user.mobile_number);
$('#phone-number').val(GlobalVariables.settings.user.phone_number);
$('#address').val(GlobalVariables.settings.user.address);
$('#city').val(GlobalVariables.settings.user.city);
$('#state').val(GlobalVariables.settings.user.state);
$('#zip-code').val(GlobalVariables.settings.user.zip_code);
$('#notes').val(GlobalVariables.settings.user.notes);
$('#username').val(GlobalVariables.settings.user.settings.username);
$('#password, #retype-password').val('');
if (GlobalVariables.settings.user.settings.notifications == true) {
$('#user-notifications').addClass('active');
} else {
$('#user-notifications').removeClass('active');
}
// Set default settings helper.
BackendSettings.settings = new SystemSettings();
if (bindEventHandlers) {
BackendSettings.bindEventHandlers();
$('#settings-page .nav li').first().addClass('active');
$('#settings-page .nav li').first().find('a').trigger('click');
}
// Apply Privileges
if (GlobalVariables.user.privileges.system_settings.edit == false) {
$('#general, #business-logic').find('select, input, textarea').prop('readonly', true);
$('#general, #business-logic').find('button').prop('disabled', true);
}
if (GlobalVariables.user.privileges.user_settings.edit == false) {
$('#user').find('select, input, textarea').prop('readonly', true);
$('#user').find('button').prop('disabled', true);
}
Backend.placeFooterToBottom();
},
/**
* Bind the backend/settings default event handlers. This method depends on the
* backend/settings html, so do not use this method on a different page.
*/
bindEventHandlers: function() {
BackendSettings.wp.bindEventHandlers();
/**
* Event: Tab "Click"
*
* Change the visible tab contents.
*/
$('.tab').click(function() {
// Bootstrap has a bug with toggle buttons. Their toggle state is lost when the
// button is hidden or shown. Show before anything else we need to store the toggle
// and apply it whenever the user tab is clicked..
var areNotificationsActive = $('#user-notifications').hasClass('active');
$(this).parent().find('.active').removeClass('active');
$(this).addClass('active');
$('.tab-content').hide();
if ($(this).hasClass('general-tab')) {
$('#general').show();
BackendSettings.settings = new SystemSettings();
} else if ($(this).hasClass('business-logic-tab')) {
$('#business-logic').show();
BackendSettings.settings = new SystemSettings();
} else if ($(this).hasClass('user-tab')) {
$('#user').show();
BackendSettings.settings = new UserSettings();
// Apply toggle state to user notifications button.
if (areNotificationsActive) {
$('#user-notifications').addClass('active');
} else {
$('#user-notifications').removeClass('active');
}
} else if ($(this).hasClass('about-tab')) {
$('#about').show();
}
Backend.placeFooterToBottom();
});
/**
* Event: Save Settings Button "Click"
*
* Store the setting changes into the database.
*/
$('.save-settings').click(function() {
var settings = BackendSettings.settings.get();
BackendSettings.settings.save(settings);
//////////////////////////////////////////////
//console.log('Settings To Save: ', settings);
//////////////////////////////////////////////
});
/**
* Event: Username "Focusout"
*
* When the user leaves the username input field we will need to check if the username
* is not taken by another record in the system. Usernames must be unique.
*/
$('#username').focusout(function() {
var $input = $(this);
if ($input.prop('readonly') == true || $input.val() == '') return;
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_validate_username';
var postData = {
'username': $input.val(),
'user_id': $input.parents().eq(2).find('#user-id').val()
};
$.post(postUrl, postData, function(response) {
///////////////////////////////////////////////////////
//console.log('Validate Username Response:', response);
///////////////////////////////////////////////////////
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
if (response == false) {
$input.css('border', '2px solid red');
Backend.displayNotification(EALang['username_already_exists']);
$input.attr('already-exists', 'true');
} else {
$input.css('border', '');
$input.attr('already-exists', 'false');
}
}, 'json');
});
}
};
/**
* "System Settings" Tab Helper
* @class SystemSettings
*/
var SystemSettings = function() {};
/**
* Save the system settings. This method is run after changes are detected on the
* tab input fields.
*
* @param {array} settings Contains the system settings data.
*/
SystemSettings.prototype.save = function(settings) {
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_settings';
var postData = {
'settings': JSON.stringify(settings),
'type': BackendSettings.SETTINGS_SYSTEM
};
$.post(postUrl, postData, function(response) {
///////////////////////////////////////////////////////////
console.log('Save General Settings Response:', response);
///////////////////////////////////////////////////////////
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
Backend.displayNotification(EALang['settings_saved']);
// Update the logo title on the header.
$('#header-logo span').text($('#company-name').val());
// We need to refresh the working plan.
var workingPlan = BackendSettings.wp.get();
$('.breaks').empty();
BackendSettings.wp.setup(workingPlan);
BackendSettings.wp.timepickers(false);
}, 'json');
};
/**
* Prepare the system settings array. This method uses the DOM elements of the
* backend/settings page, so it can't be used in another page.
*
* @returns {array} Returns the system settings array.
*/
SystemSettings.prototype.get = function() {
var settings = [];
// General Settings Tab
$('#general input').each(function() {
settings.push({
'name': $(this).attr('data-field'),
'value': $(this).val()
});
});
// Business Logic Tab
settings.push({
'name': 'company_working_plan',
'value': JSON.stringify(BackendSettings.wp.get())
});
settings.push({
'name': 'book_advance_timeout',
'value': $('#book-advance-timeout').val()
});
return settings;
};
/**
* Validate the settings data. If the validation fails then display a
* message to the user.
*
* @returns {bool} Returns the validation result.
*/
SystemSettings.prototype.validate = function() {
$('#general .required').css('border', '');
try {
// Validate required fields.
var missingRequired = false;
$('#general .required').each(function() {
if ($(this).val() == '' || $(this).val() == undefined) {
$(this).css('border', '2px solid red');
missingRequired = true;
}
});
if (missingRequired) {
throw EALang['fields_are_required'];
}
// Validate company email address.
if (!GeneralFunctions.validateEmail($('#company-email').val())) {
$('#company-email').css('border', '2px solid red');
throw EALang['invalid_email'];
}
return true;
} catch(exc) {
Backend.displayNotification(exc);
return false;
}
};
/**
* "User Settings" Tab Helper
* @class UserSettings
*/
var UserSettings = function() {};
/**
* Get the settings data for the user settings.
*
* @returns {object} Returns the user settings array.
*/
UserSettings.prototype.get = function() {
var user = {
'id': $('#user-id').val(),
'first_name': $('#first-name').val(),
'last_name': $('#last-name').val(),
'email': $('#email').val(),
'mobile_number': $('#mobile-number').val(),
'phone_number': $('#phone-number').val(),
'address': $('#address').val(),
'city': $('#city').val(),
'state': $('#state').val(),
'zip_code': $('#zip-code').val(),
'notes': $('#notes').val(),
'settings': {
'username': $('#username').val(),
'notifications': $('#user-notifications').hasClass('active')
}
};
if ($('#password').val() != '') {
user.settings.password = $('#password').val();
}
return user;
};
/**
* Store the user settings into the database.
*
* @param {array} settings Contains the user settings.
*/
UserSettings.prototype.save = function(settings) {
if (!BackendSettings.settings.validate(settings)) {
Backend.displayNotification(EALang['user_settings_are_invalid']);
return; // Validation failed, do not procceed.
}
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_settings';
var postData = {
'type': BackendSettings.SETTINGS_USER,
'settings': JSON.stringify(settings)
};
$.post(postUrl, postData, function(response) {
//////////////////////////////////////////////////////////
console.log('Save User Settings Response: ', response);
//////////////////////////////////////////////////////////
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
Backend.displayNotification(EALang['settings_saved']);
// Update footer greetings.
$('#footer-user-display-name').text('Hello, ' + $('#first-name').val() + ' ' + $('#last-name').val() + '!');
}, 'json');
};
/**
* Validate the settings data. If the validation fails then display a
* message to the user.
*
* @returns {bool} Returns the validation result.
*/
UserSettings.prototype.validate = function() {
$('#user .required').css('border', '');
$('#user').find('#password, #retype-password').css('border', '');
try {
// Validate required fields.
var missingRequired = false;
$('#user .required').each(function() {
if ($(this).val() == '' || $(this).val() == undefined) {
$(this).css('border', '2px solid red');
missingRequired = true;
}
});
if (missingRequired) {
throw EALang['fields_are_required'];
}
// Validate passwords (if provided).
if ($('#password').val() != $('#retype-password').val()) {
$('#password, #retype-password').css('border', '2px solid red');
throw EALang['passwords_mismatch'];
}
// Validate user email.
if (!GeneralFunctions.validateEmail($('#email').val())) {
$('#email').css('border', '2px solid red');
throw EALang['invalid_email'];
}
if ($('#username').attr('already-exists') === 'true') {
$('#username').css('border', '2px solid red');
throw EALang['username_already_exists'];
}
return true;
} catch(exc) {
Backend.displayNotification(exc);
return false;
}
};