* Created backend services page view file
* Organized backend_services.js file
This commit is contained in:
parent
f0b8ab45b5
commit
62a667cb9c
9 changed files with 479 additions and 17 deletions
|
@ -53,5 +53,7 @@ define('DB_SLUG_SECRETARY', 'secretary');
|
|||
define('FILTER_TYPE_PROVIDER', 'provider');
|
||||
define('FILTER_TYPE_SERVICE', 'service');
|
||||
|
||||
define('AJAX_SUCCESS', 'SUCCESS');
|
||||
define('AJAX_FAILURE', 'FAILURE');
|
||||
/* End of file constants.php */
|
||||
/* Location: ./application/config/constants.php */
|
|
@ -66,7 +66,21 @@ class Backend extends CI_Controller {
|
|||
}
|
||||
|
||||
public function services() {
|
||||
echo '<h1>Not implemented yet.</h1>';
|
||||
// @task Require user to be logged in the application.
|
||||
|
||||
$this->load->model('providers_model');
|
||||
$this->load->model('customers_model');
|
||||
$this->load->model('services_model');
|
||||
$this->load->model('settings_model');
|
||||
|
||||
$view['base_url'] = $this->config->item('base_url');
|
||||
$view['company_name'] = $this->settings_model->get_setting('company_name');
|
||||
$view['services'] = $this->services_model->get_batch();
|
||||
$view['categories'] = $this->services_model->get_all_categories();
|
||||
|
||||
$this->load->view('backend/header', $view);
|
||||
$this->load->view('backend/services', $view);
|
||||
$this->load->view('backend/footer', $view);
|
||||
}
|
||||
|
||||
public function providers() {
|
||||
|
|
|
@ -180,7 +180,7 @@ class Backend_api extends CI_Controller {
|
|||
}
|
||||
|
||||
if (!isset($warnings)) {
|
||||
echo json_encode('SUCCESS');
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
} else {
|
||||
echo json_encode(array(
|
||||
'warnings' => $warnings
|
||||
|
@ -262,7 +262,7 @@ class Backend_api extends CI_Controller {
|
|||
|
||||
// :: SEND RESPONSE TO CLIENT BROWSER
|
||||
if (!isset($warnings)) {
|
||||
echo json_encode('SUCCESS'); // Everything executed successfully.
|
||||
echo json_encode(AJAX_SUCCESS); // Everything executed successfully.
|
||||
} else {
|
||||
echo json_encode(array(
|
||||
'warnings' => $warnings // There were warnings during the operation.
|
||||
|
@ -294,7 +294,7 @@ class Backend_api extends CI_Controller {
|
|||
$this->providers_model->set_setting('google_sync', FALSE, $_POST['provider_id']);
|
||||
$this->providers_model->set_setting('google_token', NULL, $_POST['provider_id']);
|
||||
|
||||
echo json_encode('SUCCESS');
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
|
@ -397,7 +397,7 @@ class Backend_api extends CI_Controller {
|
|||
'warnings' => $warnings
|
||||
));
|
||||
} else {
|
||||
echo json_encode('SUCCESS');
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
}
|
||||
|
||||
} catch(Exception $exc) {
|
||||
|
@ -441,7 +441,7 @@ class Backend_api extends CI_Controller {
|
|||
'warnings' => $warnings
|
||||
));
|
||||
} else {
|
||||
echo json_encode('SUCCESS');
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
}
|
||||
|
||||
} catch(Exception $exc) {
|
||||
|
@ -461,7 +461,7 @@ class Backend_api extends CI_Controller {
|
|||
$this->load->model('customers_model');
|
||||
$customer = json_decode($_POST['customer'], true);
|
||||
$this->customers_model->add($customer);
|
||||
echo json_encode('SUCCESS');
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
|
@ -478,7 +478,7 @@ class Backend_api extends CI_Controller {
|
|||
try {
|
||||
$this->load->model('customers_model');
|
||||
$this->customers_model->delete($_POST['customer_id']);
|
||||
echo json_encode('SUCCESS');
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
|
@ -487,27 +487,84 @@ class Backend_api extends CI_Controller {
|
|||
}
|
||||
|
||||
public function ajax_save_service() {
|
||||
|
||||
try {
|
||||
$this->load->model('services_model');
|
||||
$service = json_decode($_POST['service'], true);
|
||||
$this->services_model->add($service);
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function ajax_delete_service() {
|
||||
|
||||
try {
|
||||
$this->load->model('services_model');
|
||||
$result = $this->services_model->delete($_POST['service_id']);
|
||||
echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE);
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function ajax_filter_services() {
|
||||
|
||||
try {
|
||||
$this->load->model('services_model');
|
||||
$key = $_POST['key']; // @task fix sql injection
|
||||
$where =
|
||||
'(name LIKE "%' . $key . '%" OR duration LIKE "%' . $key . '%" OR ' .
|
||||
'price LIKE "%' . $key . '%" OR currency LIKE "%' . $key . '%" OR ' .
|
||||
'description LIKE "%' . $key . '%")';
|
||||
$services = $this->services_model->get_batch($where);
|
||||
echo json_encode($services);
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function ajax_save_service_category() {
|
||||
|
||||
try {
|
||||
$this->load->model('services_model');
|
||||
$category = json_decode($_POST['category'], true);
|
||||
$this->services_model->add_category($category);
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function ajax_delete_service_category() {
|
||||
|
||||
try {
|
||||
$this->load->model('services_model');
|
||||
$result = $this->services_model->delete($_POST['category_id']);
|
||||
echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE);
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function ajax_filter_service_categories() {
|
||||
|
||||
try {
|
||||
$this->load->model('services_model');
|
||||
$key = $_POST['key']; // @task sql injection
|
||||
$where = '(name LIKE "%' . $key . '%" OR description LIKE "%' . $key . '%")';
|
||||
$categories = $this->services_model->get_categories($where);
|
||||
echo json_encode($categories);
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ class Google extends CI_Controller {
|
|||
}
|
||||
}
|
||||
|
||||
echo json_encode('SUCCESS');
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
|
|
|
@ -324,7 +324,8 @@ class Services_Model extends CI_Model {
|
|||
*
|
||||
* @return array Returns an array that contains all the service category records.
|
||||
*/
|
||||
public function get_all_categories() {
|
||||
public function get_all_categories($where = '') {
|
||||
if ($where !== '') $this->db->where($where);
|
||||
return $this->db->get('ea_service_categories')->result_array();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
<script type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/backend_services.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var GlobalVariables = {
|
||||
'baseUrl': <?php echo '"' . $base_url . '"'; ?>,
|
||||
'services': <?php echo json_encode($services); ?>,
|
||||
'categories': <?php echo json_encode($categories); ?>
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
BackendServices.initialize(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="services-page" class="row-fluid">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="services-tab tab active"><a>Services</a></li>
|
||||
<li class="categories-tab tab"><a>Categories</a></li>
|
||||
</ul>
|
||||
|
||||
<?php // SERVICES TAB ++++++++++++++++++++++++++++++++ ?>
|
||||
<div id="services" class="tab-content">
|
||||
<?php // FILTER SERVICES ?>
|
||||
<div class="filter span4">
|
||||
<div class="input-append">
|
||||
<input class="filter-key span12" type="text" />
|
||||
<button class="filter-services btn" type="button">Filter</button>
|
||||
</div>
|
||||
<h2>Services</h2>
|
||||
<div class="filter-results"></div>
|
||||
</div>
|
||||
|
||||
<div class="details span7">
|
||||
<div class="btn-toolbar">
|
||||
<div class="add-edit-delete-group btn-group">
|
||||
<button id="add-service" class="btn">
|
||||
<i class="icon-plus"></i>
|
||||
Add</button>
|
||||
<button id="edit-service" class="btn" disabled="disabled">
|
||||
<i class="icon-pencil"></i>
|
||||
Edit</button>
|
||||
<button id="delete-service" class="btn" disabled="disabled">
|
||||
<i class="icon-remove"></i>
|
||||
Delete</button>
|
||||
</div>
|
||||
|
||||
<div class="save-cancel-group btn-group" style="display:none;">
|
||||
<button id="save-service" class="btn">
|
||||
<i class="icon-ok"></i>
|
||||
Save</button>
|
||||
<button id="cancel-service" class="btn">
|
||||
<i class="icon-ban-circle"></i>
|
||||
Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Details</h2>
|
||||
<div class="form-message alert" style="display:none;"></div>
|
||||
|
||||
<input type="hidden" id="service-id" />
|
||||
|
||||
<label for="service-name">Name *</label>
|
||||
<input type="text" id="service-name" class="span7 required" />
|
||||
|
||||
<label for="service-duration">Duration</label>
|
||||
<input type="text" id="service-duration" class="span7" />
|
||||
|
||||
<label for="service-price">Price</label>
|
||||
<input type="text" id="service-price" class="span7" />
|
||||
|
||||
<label for="service-currency">Currency</label>
|
||||
<input type="text" id="service-currency" class="span7" />
|
||||
|
||||
<label for="service-description">Description</label>
|
||||
<textarea id="service-description" rows="4" class="span7"></textarea>
|
||||
|
||||
<label for="service-category">Category</label>
|
||||
<select id="service-category" class="span7"></select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php // CATEGORIES TAB ++++++++++++++++++++++++++++++++ ?>
|
||||
<div id="categories" class="tab-content" style="display:none;">
|
||||
<div class="filter span4">
|
||||
<div class="input-append">
|
||||
<input class="span12" type="text" class="filter-key" />
|
||||
<button type="button" class="btn" class="filter-services">Filter</button>
|
||||
</div>
|
||||
|
||||
<h2>Categories</h2>
|
||||
<div class="filter-results"></div>
|
||||
</div>
|
||||
|
||||
<div class="details span7">
|
||||
<div class="btn-toolbar">
|
||||
<div class="add-edit-delete-group btn-group">
|
||||
<button id="add-category" class="btn">
|
||||
<i class="icon-plus"></i>
|
||||
Add</button>
|
||||
<button id="edit-category" class="btn" disabled="disabled">
|
||||
<i class="icon-pencil"></i>
|
||||
Edit</button>
|
||||
<button id="delete-category" class="btn" disabled="disabled">
|
||||
<i class="icon-remove"></i>
|
||||
Delete</button>
|
||||
</div>
|
||||
|
||||
<div class="save-cancel-group btn-group" style="display:none;">
|
||||
<button id="save-category" class="btn">
|
||||
<i class="icon-ok"></i>
|
||||
Save</button>
|
||||
<button id="cancel-category" class="btn">
|
||||
<i class="icon-ban-circle"></i>
|
||||
Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Details</h2>
|
||||
<div class="form-message alert" style="display:none;"></div>
|
||||
|
||||
<label for="category-name">Name *</label>
|
||||
<input type="text" id="category-name" class="span7 required" />
|
||||
|
||||
<label for="category-description">Description</label>
|
||||
<textarea id="category-description" rows="4" class="span7"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -78,7 +78,12 @@ root {
|
|||
|
||||
/* BACKEND SERVICES PAGE
|
||||
-------------------------------------------------------------------- */
|
||||
|
||||
#services-page .tab-content { margin: 15px; }
|
||||
#services-page .nav { margin: 15px; }
|
||||
#services-page .nav li { cursor: pointer; }
|
||||
#services-page .service-row { padding: 10px 7px; border-radius: 3px; }
|
||||
#services-page .service-row:hover { cursor: pointer; background-color: #C6E7D5; }
|
||||
#services-page .selected-row { background-color: #EFFDF7; }
|
||||
|
||||
/* BACKEND PROVIDERS PAGE
|
||||
-------------------------------------------------------------------- */
|
||||
|
|
|
@ -87,5 +87,31 @@ var Backend = {
|
|||
|
||||
$('#notification').html(notificationHtml);
|
||||
$('#notification').show('blind');
|
||||
},
|
||||
|
||||
/**
|
||||
* All backend js code has the same way of dislaying exceptions that are raised on the
|
||||
* server during an ajax call.
|
||||
*
|
||||
* @param {object} response Contains the server response. If exceptions or warnings are
|
||||
* found, user friendly messages are going to be displayed to the user.
|
||||
* @returns {bool} Returns whether the the ajax callback should continue the execution or
|
||||
* stop, due to critical server exceptions.
|
||||
*/
|
||||
handleAjaxExceptions: function(response) {
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox(Backend.EXCEPTIONS_TITLE, Backend.EXCEPTIONS_MESSAGE);
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response.warnings) {
|
||||
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
|
||||
GeneralFunctions.displayMessageBox(Backend.WARNINGS_TITLE, Backend.WARNINGS_MESSAGE);
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
228
src/assets/js/backend_services.js
Normal file
228
src/assets/js/backend_services.js
Normal file
|
@ -0,0 +1,228 @@
|
|||
/**
|
||||
* This namespace handles the js functionality of the backend services page.
|
||||
*
|
||||
* @namespace BackendServices
|
||||
*/
|
||||
var BackendServices = {
|
||||
/**
|
||||
* Contains the basic record methods for the page.
|
||||
*
|
||||
* @type ServicesHelper|CategoriesHelper
|
||||
*/
|
||||
helper: {},
|
||||
|
||||
/**
|
||||
* Default initialize method of the page.
|
||||
*
|
||||
* @param {bool} bindEventHandlers (OPTIONAL) Determines whether to bind the
|
||||
* default event handlers (default: true).
|
||||
*/
|
||||
initialize: function(bindEventHandlers) {
|
||||
if (bindEventHandlers === undefined) bindEventHandlers = true;
|
||||
|
||||
// Fill available service categories listbox.
|
||||
$.each(GlobalVariables.categories, function(index, category) {
|
||||
var option = new Option(category.name, category.value);
|
||||
$('#service-category').append(option);
|
||||
});
|
||||
$('#service-category').append(new Option('- No Category -', null)).val('null');
|
||||
|
||||
// Instantiate helper object (service helper by default).
|
||||
BackendServices.helper = new ServicesHelper();
|
||||
BackendServices.helper.resetForm();
|
||||
BackendServices.helper.filter('');
|
||||
|
||||
$('#service-duration').spinner({
|
||||
'min': 0,
|
||||
'numberFormat': 'n Minutes'
|
||||
});
|
||||
|
||||
|
||||
if (bindEventHandlers) BackendServices.bindEventHandlers();
|
||||
},
|
||||
|
||||
/**
|
||||
* Binds the default event handlers of the backend services page. Do not use this method
|
||||
* if you include the "BackendServices" namespace on another page.
|
||||
*
|
||||
* @returns {undefined}
|
||||
*/
|
||||
bindEventHandlers: function() {
|
||||
/**
|
||||
* Event: Page Tab Button "Click"
|
||||
*
|
||||
* Changes the displayed tab.
|
||||
*/
|
||||
$('.tab').click(function() {
|
||||
$('.active').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
$('.tab-content').hide();
|
||||
|
||||
if ($(this).hasClass('services-tab')) { // display services tab
|
||||
$('#services').show();
|
||||
BackendServices.helper = new ServicesHelper();
|
||||
} else if ($(this).hasClass('categories-tab')) { // display categories tab
|
||||
$('#categories').show();
|
||||
BackendServices.helper = new CategoriesHelper();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Services Button "Click"
|
||||
*/
|
||||
$(' .filter-services').click(function() {
|
||||
var key = $('#services .filter-key').val();
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
BackendServices.helper.resetForm();
|
||||
BackendServices.helper.filter(key);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Service Row "Click"
|
||||
*
|
||||
* Display the selected service data to the user.
|
||||
*/
|
||||
$(document).on('click', '.service-row', function() {
|
||||
var service = { 'id': $(this).attr('data-id') };
|
||||
|
||||
$.each(BackendServices.helper.filterResults, function(index, item) {
|
||||
if (item.id === service.id) {
|
||||
service = item;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
BackendServices.helper.display(service);
|
||||
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This class contains the methods that will be used by the "Services" tab of the page.
|
||||
* @class ServicesHelper
|
||||
*/
|
||||
var ServicesHelper = function() {
|
||||
this.filterResults = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Save service record to database.
|
||||
*
|
||||
* @param {object} service Contains the service record data. If an 'id' value is provided
|
||||
* then the update operation is going to be executed.
|
||||
*/
|
||||
ServicesHelper.prototype.save = function(service) {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_service';
|
||||
var postData = { 'service': JSON.stringify(service) };
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
console.log('Save Service Response:', response);
|
||||
if (!Backend.handleAjaxExceptions(response)) return;
|
||||
|
||||
$('#services .add-edit-delete-group').show();
|
||||
$('#services .save-cancel-group').hide();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a service records from database.
|
||||
*
|
||||
* @param {int} id Record id to be deleted.
|
||||
*/
|
||||
ServicesHelper.prototype.delete = function(id) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates a service record.
|
||||
*
|
||||
* @param {object} service Contains the service data.
|
||||
* @returns {bool} Returns the validation result.
|
||||
*/
|
||||
ServicesHelper.prototype.validate = function(service) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets the service tab form back to its initial state.
|
||||
*/
|
||||
ServicesHelper.prototype.resetForm = function() {
|
||||
$('#services .details').find('input, textarea').val('');
|
||||
$('#service-category').val('null');
|
||||
$('#services .add-edit-delete-group').show();
|
||||
$('#services .save-cancel-group').hide();
|
||||
$('#edit-service, #delete-service').prop('disabled', true);
|
||||
$('#services .details').find('input, textarea').prop('readonly', true);
|
||||
$('#service-category').prop('disabled', true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Display a service record into the service form.
|
||||
*
|
||||
* @param {object} service Contains the service record data.
|
||||
*/
|
||||
ServicesHelper.prototype.display = function(service) {
|
||||
$('#service-id').val(service.id);
|
||||
$('#service-name').val(service.name);
|
||||
$('#service-duration').val(service.duration + ' min');
|
||||
$('#service-price').val(service.price);
|
||||
$('#service-currency').val(service.currency);
|
||||
$('#service-description').val(service.description);
|
||||
$('#service-category').val(service.id_service_categories);
|
||||
};
|
||||
|
||||
/**
|
||||
* Filters service records depending a string key.
|
||||
*
|
||||
* @param {string} key This is used to filter the service records of the database.
|
||||
*/
|
||||
ServicesHelper.prototype.filter = function(key) {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_services';
|
||||
var postData = { 'key': key };
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
/////////////////////////////////////////////////////
|
||||
console.log('Filter services response:', response);
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
if (!Backend.handleAjaxExceptions(response)) return;
|
||||
|
||||
BackendServices.helper.filterResults = response;
|
||||
$('#services .filter-results').html('');
|
||||
|
||||
$.each(response, function(index, service) {
|
||||
var html = ServicesHelper.prototype.getFilterHtml(service);
|
||||
$('#services .filter-results').append(html);
|
||||
});
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a service row html code that is going to be displayed on the filter results list.
|
||||
*
|
||||
* @param {object} service Contains the service record data.
|
||||
* @returns {string} The html code that represents the record on the filter results list.
|
||||
*/
|
||||
ServicesHelper.prototype.getFilterHtml = function(service) {
|
||||
var html =
|
||||
'<div class="service-row" data-id="' + service.id + '">' +
|
||||
'<strong>' + service.name + '</strong><br>' +
|
||||
service.duration + ' min - ' +
|
||||
service.price + ' ' + service.currency + '<br>' +
|
||||
'</div>';
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class contains the core method implementations that belong to the categories tab
|
||||
* of the backend services page.
|
||||
*
|
||||
* @class CategoriesHelper
|
||||
*/
|
||||
var CategoriesHelper = function() {
|
||||
this.filterResults = {};
|
||||
};
|
Loading…
Reference in a new issue