import { get, set } from 'object-path';
/**
* @typedef {Object} SettingsProps
* @description An object representing customizable classes & HTML used for a certain table type.
* @property {string} table.class - The classes to apply on the `table` tag itself.
* @property {string|Function} table.row.class - The classes to apply on each row (`tr` tag).
* @property {string} table.sorting.sortNone - The HTML representing the sort icon when the column isn't sorted.
* @property {string} table.sorting.sortAsc - The HTML representing the sort icon when sorting the column ascending.
* @property {string} table.sorting.sortDesc - The HTML representing the sort icon when sorting the column descending.
* @property {string} pager.classes.pager - The class to apply on the pager's `ul` tag.
* @property {string} pager.classes.li - The class to apply on the page's `li` tag.
* @property {string} pager.classes.selected - The class to apply on the current page's `li` tag.
* @property {string} pager.classes.disabled - The class to apply on a disabled page's `li` tag.
* @property {string} pager.icons.previous - The HTML representing the *Previous page* icon.
* @property {string} pager.icons.next - The HTML representing the *Next page* icon.
* @tutorial custom-theme
*/
/**
* @summary Settings class used by Datatable's components to get various values, such as class names, labels, icons, etc etc.
* @description Settings class used by Datatable's components to get various values, such as class names, labels, icons, etc etc.
* Create a new instance of this class & customize it to use different CSS frameworks.
* The default Settings is for *Bootstrap 3/4* with *glyphicon*.
* To edit settings contained by an instance of this class, either edit the {@link Settings#properties} object, or use the {@link Settings#merge} method.
*
* @tutorial custom-theme
*/
class Settings {
/**
* Creates a new default instance of settings object.
*/
constructor(){
/**
* @member {SettingsProps} - Tree of settings values.
*/
this.properties = {
table: {
class: 'table table-hover table-striped',
row: {
class: '',
},
sorting: {
sortNone: '↕',
sortAsc: '↓',
sortDesc: '↑',
},
},
pager: {
classes: {
pager: 'pagination',
li: '',
selected: 'active',
disabled: 'disabled',
},
icons: {
previous: '<',
next: '>',
},
},
};
}
/**
* Get a value at a specific path.
*
* @param {(string | number | Array.<string | number>)} path - Path to the value to get.
* @returns {*} The value at the specified path
*/
get( path ){
return get( this.properties, path );
}
/**
* Defines a value at a specific path
*
* @param {(string | number | Array.<string | number>)} path - Path to the value to set.
* @param {*} value - New value to set.
* @returns {this} For chaining.
*/
set( path, value ){
set( this.properties, path, value );
return this;
}
/**
* Merges a new settings object within the Settings instance.
*
* @param {SettingsProps} settings - New settings object to merge with the current object of the Settings instance.
* @returns {this} For chaining.
*/
merge( settings ){
this.properties = this._mergeObjects( this.properties, settings );
return this;
}
/**
* Merges two objects deeply, and return the 1st parameter once transformed.
*
* @private
* @param {*} obj1 - The base item to merge, which will be returned.
* @param {*} obj2 - The object to inject into `obj1`.
* @returns {*} The first object once merged.
*/
_mergeObjects( obj1, obj2 ){
if ( !obj1 ){
obj1 = {};
}
for ( const key in obj2 ){
if ( typeof obj2[key] === 'object' ){
obj1[key] = this._mergeObjects( obj1[key], obj2[key] );
} else {
obj1[key] = obj2[key];
}
}
return obj1;
}
}
export default Settings;