smeserver-manager-jsquery/root/usr/share/javascript/StateRestore/js/StateRestoreCollection.js

1030 lines
47 KiB
JavaScript

var $;
var dataTable;
import StateRestore from './StateRestore';
export function setJQuery(jq) {
$ = jq;
dataTable = jq.fn.dataTable;
}
var StateRestoreCollection = /** @class */ (function () {
function StateRestoreCollection(settings, opts) {
var _this = this;
// Check that the required version of DataTables is included
if (!dataTable || !dataTable.versionCheck || !dataTable.versionCheck('1.10.0')) {
throw new Error('StateRestore requires DataTables 1.10 or newer');
}
// Check that Select is included
// eslint-disable-next-line no-extra-parens
if (!dataTable.Buttons) {
throw new Error('StateRestore requires Buttons');
}
var table = new dataTable.Api(settings);
this.classes = $.extend(true, {}, StateRestoreCollection.classes);
if (table.settings()[0]._stateRestore !== undefined) {
return;
}
// Get options from user
this.c = $.extend(true, {}, StateRestoreCollection.defaults, opts);
this.s = {
dt: table,
hasColReorder: dataTable.ColReorder !== undefined,
hasScroller: dataTable.Scroller !== undefined,
hasSearchBuilder: dataTable.SearchBuilder !== undefined,
hasSearchPanes: dataTable.SearchPanes !== undefined,
hasSelect: dataTable.select !== undefined,
states: []
};
this.s.dt.on('xhr', function (e, xhrsettings, json) {
// Has staterestore been used before? Is there anything to load?
if (json && json.stateRestore) {
_this._addPreDefined(json.stateRestore);
}
});
this.dom = {
background: $('<div class="' + this.classes.background + '"/>'),
checkboxInputRow: $('<div class="' + this.classes.formRow + '">' +
'<label class="' + this.classes.nameLabel + '">' +
this.s.dt.i18n('stateRestore.creationModal.toggleLabel', this.c.i18n.creationModal.toggleLabel) +
'</label>' +
'<div class="dtsr-input"></div>' +
'</div>'),
closeButton: $('<div class="' + this.classes.closeButton + '">x</div>'),
colReorderToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.colReorderToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.colReorder', this.c.i18n.creationModal.colReorder) +
'</div>'),
columnsSearchToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.columnsSearchToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.columns.search', this.c.i18n.creationModal.columns.search) +
'</div>'),
columnsVisibleToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.columnsVisibleToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.columns.visible', this.c.i18n.creationModal.columns.visible) +
'</div>'),
confirmation: $('<div class="' + this.classes.confirmation + '"/>'),
confirmationTitleRow: $('<div class="' + this.classes.confirmationTitleRow + '"></div>'),
createButtonRow: $('<div class="' + this.classes.formRow + ' ' + this.classes.modalFoot + '">' +
'<button class="' + this.classes.creationButton + ' ' + this.classes.dtButton + '">' +
this.s.dt.i18n('stateRestore.creationModal.button', this.c.i18n.creationModal.button) +
'</button>' +
'</div>'),
creation: $('<div class="' + this.classes.creation + '"/>'),
creationForm: $('<div class="' + this.classes.creationForm + '"/>'),
creationTitle: $('<div class="' + this.classes.creationText + '">' +
'<h2 class="' + this.classes.creationTitle + '">' +
this.s.dt.i18n('stateRestore.creationModal.title', this.c.i18n.creationModal.title) +
'</h2>' +
'</div>'),
dtContainer: $(this.s.dt.table().container()),
duplicateError: $('<span class="' + this.classes.modalError + '">' +
this.s.dt.i18n('stateRestore.duplicateError', this.c.i18n.duplicateError) +
'</span>'),
emptyError: $('<span class="' + this.classes.modalError + '">' +
this.s.dt.i18n('stateRestore.emptyError', this.c.i18n.emptyError) +
'</span>'),
lengthToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.lengthToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.length', this.c.i18n.creationModal.length) +
'</div>'),
nameInputRow: $('<div class="' + this.classes.formRow + '">' +
'<label class="' + this.classes.nameLabel + '">' +
this.s.dt.i18n('stateRestore.creationModal.name', this.c.i18n.creationModal.name) +
'</label>' +
'<div class="dtsr-input">' +
'<input class="' + this.classes.nameInput + '" type="text">' +
'</div>' +
'</div>'),
orderToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.orderToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.order', this.c.i18n.creationModal.order) +
'</div>'),
pagingToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.pagingToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.paging', this.c.i18n.creationModal.paging) +
'</div>'),
removeContents: $('<div class="' + this.classes.confirmationText + '"><span></span></div>'),
removeTitle: $('<div class="' + this.classes.creationText + '">' +
'<h2 class="' + this.classes.creationTitle + '">' +
this.s.dt.i18n('stateRestore.removeTitle', this.c.i18n.removeTitle) +
'</h2>' +
'</div>'),
scrollerToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.scrollerToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.scroller', this.c.i18n.creationModal.scroller) +
'</div>'),
searchBuilderToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.searchBuilderToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.searchBuilder', this.c.i18n.creationModal.searchBuilder) +
'</div>'),
searchPanesToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.searchPanesToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.searchPanes', this.c.i18n.creationModal.searchPanes) +
'</div>'),
searchToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.searchToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.search', this.c.i18n.creationModal.search) +
'</div>'),
selectToggle: $('<div class="' + this.classes.checkLabel + '">' +
'<input type="checkbox" class="' +
this.classes.selectToggle + ' ' +
this.classes.checkBox +
'" checked>' +
this.s.dt.i18n('stateRestore.creationModal.select', this.c.i18n.creationModal.select) +
'</div>')
};
table.settings()[0]._stateRestore = this;
this._searchForStates();
// Has staterestore been used before? Is there anything to load?
this._addPreDefined(this.c.preDefined);
var ajaxFunction;
var ajaxData = {
action: 'load'
};
if (typeof this.c.ajax === 'function') {
ajaxFunction = function () {
if (typeof _this.c.ajax === 'function') {
_this.c.ajax.call(_this.s.dt, ajaxData, function (s) { return _this._addPreDefined(s); });
}
};
}
else if (typeof this.c.ajax === 'string') {
ajaxFunction = function () {
$.ajax({
data: ajaxData,
success: function (data) {
_this._addPreDefined(data);
},
type: 'POST',
url: _this.c.ajax
});
};
}
if (typeof ajaxFunction === 'function') {
if (this.s.dt.settings()[0]._bInitComplete) {
ajaxFunction();
}
else {
this.s.dt.one('preInit.dtsr', function () {
ajaxFunction();
});
}
}
this.s.dt.on('destroy.dtsr', function () {
_this.destroy();
});
this.s.dt.on('draw.dtsr buttons-action.dtsr', function () { return _this.findActive(); });
return this;
}
/**
* Adds a new StateRestore instance to the collection based on the current properties of the table
*
* @param identifier The value that is used to identify a state.
* @returns The state that has been created
*/
StateRestoreCollection.prototype.addState = function (identifier, currentIdentifiers, options) {
var _this = this;
// If creation/saving is not allowed then return
if (!this.c.create || !this.c.save) {
return;
}
// Check if the state exists before creating a new ones
var state = this.getState(identifier);
var createFunction = function (id, toggles) {
if (id.length === 0) {
return 'empty';
}
else if (currentIdentifiers.includes(id)) {
return 'duplicate';
}
_this.s.dt.state.save();
var that = _this;
var successCallback = function () {
that.s.states.push(this);
that._collectionRebuild();
};
var currState = _this.s.dt.state();
currState.stateRestore = {
isPredefined: false,
state: id,
tableId: _this.s.dt.table().node().id
};
if (toggles.saveState) {
var opts = _this.c.saveState;
// We don't want to extend, but instead AND all properties of the saveState option
for (var _i = 0, _a = Object.keys(toggles.saveState); _i < _a.length; _i++) {
var key = _a[_i];
if (typeof toggles.saveState[key] === 'object') {
for (var _b = 0, _c = Object.keys(toggles.saveState[key]); _b < _c.length; _b++) {
var nestedKey = _c[_b];
if (!toggles.saveState[key][nestedKey]) {
opts[key][nestedKey] = false;
}
}
}
else if (!toggles.saveState[key]) {
opts[key] = false;
}
}
_this.c.saveState = opts;
}
var newState = new StateRestore(_this.s.dt.settings()[0], $.extend(true, {}, _this.c, options), id, currState, false, successCallback);
$(_this.s.dt.table().node()).on('dtsr-modal-inserted', function () {
newState.dom.confirmation.one('dtsr-remove', function () { return _this._removeCallback(newState.s.identifier); });
newState.dom.confirmation.one('dtsr-rename', function () { return _this._collectionRebuild(); });
newState.dom.confirmation.one('dtsr-save', function () { return _this._collectionRebuild(); });
});
return true;
};
// If there isn't already a state with this identifier
if (state === null) {
if (this.c.creationModal || options !== undefined && options.creationModal) {
this._creationModal(createFunction, identifier, options);
}
else {
var success = createFunction(identifier, {});
if (success === 'empty') {
throw new Error(this.s.dt.i18n('stateRestore.emptyError', this.c.i18n.emptyError));
}
else if (success === 'duplicate') {
throw new Error(this.s.dt.i18n('stateRestore.duplicateError', this.c.i18n.duplicateError));
}
}
}
else {
throw new Error(this.s.dt.i18n('stateRestore.duplicateError', this.c.i18n.duplicateError));
}
};
/**
* Removes all of the states, showing a modal to the user for confirmation
*
* @param removeFunction The action to be taken when the action is confirmed
*/
StateRestoreCollection.prototype.removeAll = function (removeFunction) {
// There are no states to remove so just return
if (this.s.states.length === 0) {
return;
}
var ids = this.s.states.map(function (state) { return state.s.identifier; });
var replacementString = ids[0];
if (ids.length > 1) {
replacementString = ids.slice(0, -1).join(', ') +
this.s.dt.i18n('stateRestore.removeJoiner', this.c.i18n.removeJoiner) +
ids.slice(-1);
}
$(this.dom.removeContents.children('span')).html(this.s.dt
.i18n('stateRestore.removeConfirm', this.c.i18n.removeConfirm)
.replace(/%s/g, replacementString));
this._newModal(this.dom.removeTitle, this.s.dt.i18n('stateRestore.removeSubmit', this.c.i18n.removeSubmit), removeFunction, this.dom.removeContents);
};
/**
* Removes all of the dom elements from the document for the collection and the stored states
*/
StateRestoreCollection.prototype.destroy = function () {
for (var _i = 0, _a = this.s.states; _i < _a.length; _i++) {
var state = _a[_i];
state.destroy();
}
$.each(this.dom, function (name, el) {
el.off().remove();
});
this.s.states = [];
this.s.dt.off('.dtsr');
$(this.s.dt.table().node()).off('.dtsr');
};
/**
* Identifies active states and updates their button to reflect this.
*
* @returns An array containing objects with the details of currently active states
*/
StateRestoreCollection.prototype.findActive = function () {
// Make sure that the state is up to date
this.s.dt.state.save();
var currState = this.s.dt.state();
var button;
// Make all of the buttons inactive so that only any that match will be marked as active
var buttons = this.s.dt.buttons().nodes();
for (var _i = 0, buttons_1 = buttons; _i < buttons_1.length; _i++) {
button = buttons_1[_i];
if ($(button).hasClass('dtsr-state') || $(button).children().hasClass('dtsr-state')) {
this.s.dt.button(button).active(false);
}
}
var results = [];
// Go through all of the states comparing if their state is the same to the current one
for (var _a = 0, _b = this.s.states; _a < _b.length; _a++) {
var state = _b[_a];
if (state.compare(currState)) {
results.push({
data: state.s.savedState,
name: state.s.identifier
});
// If so, find the corresponding button and mark it as active
for (var _c = 0, buttons_2 = buttons; _c < buttons_2.length; _c++) {
button = buttons_2[_c];
var btn = this.s.dt.button(button);
if (btn.text() === state.s.identifier) {
btn.active(true);
break;
}
}
}
}
return results;
};
/**
* Gets a single state that has the identifier matching that which is passed in
*
* @param identifier The value that is used to identify a state
* @returns The state that has been identified or null if no states have been identified
*/
StateRestoreCollection.prototype.getState = function (identifier) {
for (var _i = 0, _a = this.s.states; _i < _a.length; _i++) {
var state = _a[_i];
if (state.s.identifier === identifier) {
return state;
}
}
return null;
};
/**
* Gets an array of all of the states
*
* @returns Any states that have been identified
*/
StateRestoreCollection.prototype.getStates = function (ids) {
if (ids === undefined) {
return this.s.states;
}
else {
var states = [];
for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
var id = ids_1[_i];
var found = false;
for (var _a = 0, _b = this.s.states; _a < _b.length; _a++) {
var state = _b[_a];
if (id === state.s.identifier) {
states.push(state);
found = true;
break;
}
}
if (!found) {
states.push(undefined);
}
}
return states;
}
};
/**
* Reloads states that are set via datatables config or over ajax
*
* @param preDefined Object containing the predefined states that are to be reintroduced
*/
StateRestoreCollection.prototype._addPreDefined = function (preDefined) {
var _this = this;
// There is a potential issue here if sorting where the string parts of the name are the same,
// only the number differs and there are many states - but this wouldn't be usfeul naming so
// more of a priority to sort alphabetically
var states = Object.keys(preDefined).sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; });
var _loop_1 = function (state) {
for (var i = 0; i < this_1.s.states.length; i++) {
if (this_1.s.states[i].s.identifier === state) {
this_1.s.states.splice(i, 1);
}
}
var that = this_1;
var successCallback = function () {
that.s.states.push(this);
that._collectionRebuild();
};
var loadedState = preDefined[state];
var newState = new StateRestore(this_1.s.dt, $.extend(true, {}, this_1.c, loadedState.c !== undefined ?
{ saveState: loadedState.c.saveState } :
undefined, true), state, loadedState, true, successCallback);
newState.s.savedState = loadedState;
$(this_1.s.dt.table().node()).on('dtsr-modal-inserted', function () {
newState.dom.confirmation.one('dtsr-remove', function () { return _this._removeCallback(newState.s.identifier); });
newState.dom.confirmation.one('dtsr-rename', function () { return _this._collectionRebuild(); });
newState.dom.confirmation.one('dtsr-save', function () { return _this._collectionRebuild(); });
});
};
var this_1 = this;
for (var _i = 0, states_1 = states; _i < states_1.length; _i++) {
var state = states_1[_i];
_loop_1(state);
}
};
/**
* Rebuilds all of the buttons in the collection of states to make sure that states and text is up to date
*/
StateRestoreCollection.prototype._collectionRebuild = function () {
var button = this.s.dt.button('SaveStateRestore:name');
var stateButtons = [];
var i;
// Need to get the original configuration object, so we can rebuild it
// It might be nested, so need to traverse down the tree
if (button[0]) {
var idxs = button.index().split('-');
stateButtons = button[0].inst.c.buttons;
for (i = 0; i < idxs.length; i++) {
if (stateButtons[idxs[i]].buttons) {
stateButtons = stateButtons[idxs[i]].buttons;
}
else {
stateButtons = [];
break;
}
}
}
// remove any states from the previous rebuild - if they are still there they will be added later
for (i = 0; i < stateButtons.length; i++) {
if (stateButtons[i].extend === 'stateRestore') {
stateButtons.splice(i, 1);
i--;
}
}
if (this.c._createInSaved) {
stateButtons.push('createState');
}
var emptyText = '<span class="' + this.classes.emptyStates + '">' +
this.s.dt.i18n('stateRestore.emptyStates', this.c.i18n.emptyStates) +
'</span>';
// If there are no states display an empty message
if (this.s.states.length === 0) {
// Don't want the empty text included more than twice
if (!stateButtons.includes(emptyText)) {
stateButtons.push(emptyText);
}
}
else {
// There are states to add so there shouldn't be any empty text left!
while (stateButtons.includes(emptyText)) {
stateButtons.splice(stateButtons.indexOf(emptyText), 1);
}
// There is a potential issue here if sorting where the string parts of the name are the same,
// only the number differs and there are many states - but this wouldn't be usfeul naming so
// more of a priority to sort alphabetically
this.s.states = this.s.states.sort(function (a, b) {
var aId = a.s.identifier;
var bId = b.s.identifier;
return aId > bId ?
1 :
aId < bId ?
-1 :
0;
});
// Construct the split property of each button
for (var _i = 0, _a = this.s.states; _i < _a.length; _i++) {
var state = _a[_i];
var split = this.c.splitSecondaries.slice();
if (split.includes('updateState') && (!this.c.save || !state.c.save)) {
split.splice(split.indexOf('updateState'), 1);
}
if (split.includes('renameState') &&
(!this.c.save || !state.c.save || !this.c.rename || !state.c.rename)) {
split.splice(split.indexOf('renameState'), 1);
}
if (split.includes('removeState') && (!this.c.remove || !state.c.remove)) {
split.splice(split.indexOf('removeState'), 1);
}
stateButtons.push({
_stateRestore: state,
attr: {
title: state.s.identifier
},
config: {
split: split
},
extend: 'stateRestore',
text: StateRestore.entityEncode(state.s.identifier),
popoverTitle: StateRestore.entityEncode(state.s.identifier)
});
}
}
button.collectionRebuild(stateButtons);
// Need to disable the removeAllStates button if there are no states and it is present
var buttons = this.s.dt.buttons();
for (var _b = 0, buttons_3 = buttons; _b < buttons_3.length; _b++) {
var butt = buttons_3[_b];
if ($(butt.node).hasClass('dtsr-removeAllStates')) {
if (this.s.states.length === 0) {
this.s.dt.button(butt.node).disable();
}
else {
this.s.dt.button(butt.node).enable();
}
}
}
};
/**
* Displays a modal that is used to get information from the user to create a new state.
*
* @param buttonAction The action that should be taken when the button is pressed
* @param identifier The default identifier for the next new state
*/
StateRestoreCollection.prototype._creationModal = function (buttonAction, identifier, options) {
var _this = this;
this.dom.creation.empty();
this.dom.creationForm.empty();
this.dom.nameInputRow.find('input').val(identifier);
this.dom.creationForm.append(this.dom.nameInputRow);
var tableConfig = this.s.dt.settings()[0].oInit;
var toggle;
var togglesToInsert = [];
var toggleDefined = options !== undefined && options.toggle !== undefined;
// Order toggle - check toggle and saving enabled
if (((!toggleDefined || options.toggle.order === undefined) && this.c.toggle.order ||
toggleDefined && options.toggle.order) &&
this.c.saveState.order &&
(tableConfig.ordering === undefined || tableConfig.ordering)) {
togglesToInsert.push(this.dom.orderToggle);
}
// Search toggle - check toggle and saving enabled
if (((!toggleDefined || options.toggle.search === undefined) && this.c.toggle.search ||
toggleDefined && options.toggle.search) &&
this.c.saveState.search &&
(tableConfig.searching === undefined || tableConfig.searching)) {
togglesToInsert.push(this.dom.searchToggle);
}
// Paging toggle - check toggle and saving enabled
if (((!toggleDefined || options.toggle.paging === undefined) && this.c.toggle.paging ||
toggleDefined && options.toggle.paging) &&
this.c.saveState.paging &&
(tableConfig.paging === undefined || tableConfig.paging)) {
togglesToInsert.push(this.dom.pagingToggle);
}
// Page Length toggle - check toggle and saving enabled
if (((!toggleDefined || options.toggle.length === undefined) && this.c.toggle.length ||
toggleDefined && options.toggle.length) &&
this.c.saveState.length &&
(tableConfig.length === undefined || tableConfig.length)) {
togglesToInsert.push(this.dom.lengthToggle);
}
// ColReorder toggle - check toggle and saving enabled
if (this.s.hasColReorder &&
((!toggleDefined || options.toggle.colReorder === undefined) && this.c.toggle.colReorder ||
toggleDefined && options.toggle.colReorder) &&
this.c.saveState.colReorder) {
togglesToInsert.push(this.dom.colReorderToggle);
}
// Scroller toggle - check toggle and saving enabled
if (this.s.hasScroller &&
((!toggleDefined || options.toggle.scroller === undefined) && this.c.toggle.scroller ||
toggleDefined && options.toggle.scroller) &&
this.c.saveState.scroller) {
togglesToInsert.push(this.dom.scrollerToggle);
}
// SearchBuilder toggle - check toggle and saving enabled
if (this.s.hasSearchBuilder &&
((!toggleDefined || options.toggle.searchBuilder === undefined) && this.c.toggle.searchBuilder ||
toggleDefined && options.toggle.searchBuilder) &&
this.c.saveState.searchBuilder) {
togglesToInsert.push(this.dom.searchBuilderToggle);
}
// SearchPanes toggle - check toggle and saving enabled
if (this.s.hasSearchPanes &&
((!toggleDefined || options.toggle.searchPanes === undefined) && this.c.toggle.searchPanes ||
toggleDefined && options.toggle.searchPanes) &&
this.c.saveState.searchPanes) {
togglesToInsert.push(this.dom.searchPanesToggle);
}
// Select toggle - check toggle and saving enabled
if (this.s.hasSelect &&
((!toggleDefined || options.toggle.select === undefined) && this.c.toggle.select ||
toggleDefined && options.toggle.select) &&
this.c.saveState.select) {
togglesToInsert.push(this.dom.selectToggle);
}
// Columns toggle - check toggle and saving enabled
if (typeof this.c.toggle.columns === 'boolean' &&
((!toggleDefined || options.toggle.order === undefined) && this.c.toggle.columns ||
toggleDefined && options.toggle.order) &&
this.c.saveState.columns) {
togglesToInsert.push(this.dom.columnsSearchToggle);
togglesToInsert.push(this.dom.columnsVisibleToggle);
}
else if ((!toggleDefined || options.toggle.columns === undefined) && typeof this.c.toggle.columns !== 'boolean' ||
typeof options.toggle.order !== 'boolean') {
if (typeof this.c.saveState.columns !== 'boolean' && this.c.saveState.columns) {
// Column search toggle - check toggle and saving enabled
if ((
// columns.search is defined when passed in
toggleDefined &&
options.toggle.columns !== undefined &&
typeof options.toggle.columns !== 'boolean' &&
options.toggle.columns.search ||
// Columns search is not defined when passed in but is in defaults
(!toggleDefined ||
options.toggle.columns === undefined ||
typeof options.toggle.columns !== 'boolean' && options.toggle.columns.search === undefined) &&
typeof this.c.toggle.columns !== 'boolean' &&
this.c.toggle.columns.search) &&
this.c.saveState.columns.search) {
togglesToInsert.push(this.dom.columnsSearchToggle);
}
// Column visiblity toggle - check toggle and saving enabled
if ((
// columns.visible is defined when passed in
toggleDefined &&
options.toggle.columns !== undefined &&
typeof options.toggle.columns !== 'boolean' &&
options.toggle.columns.visible ||
// Columns visible is not defined when passed in but is in defaults
(!toggleDefined ||
options.toggle.columns === undefined ||
typeof options.toggle.columns !== 'boolean' && options.toggle.columns.visible === undefined) &&
typeof this.c.toggle.columns !== 'boolean' &&
this.c.toggle.columns.visible) &&
this.c.saveState.columns.visible) {
togglesToInsert.push(this.dom.columnsVisibleToggle);
}
}
else if (this.c.saveState.columns) {
togglesToInsert.push(this.dom.columnsSearchToggle);
togglesToInsert.push(this.dom.columnsVisibleToggle);
}
}
// Make sure that the toggles are displayed alphabetically
togglesToInsert.sort(function (a, b) {
var aVal = a.text();
var bVal = b.text();
if (aVal < bVal) {
return -1;
}
else if (aVal > bVal) {
return 1;
}
else {
return 0;
}
});
// Append all of the toggles that are to be inserted
var checkboxesEl = this.dom.checkboxInputRow
.appendTo(this.dom.creationForm)
.find('div.dtsr-input')
.empty();
// let checkboxes = $('<div class="'+this.classes.formRow+' '+this.classes.checkRow+'"></div>')
// .appendTo(this.dom.creationForm);
for (var _i = 0, togglesToInsert_1 = togglesToInsert; _i < togglesToInsert_1.length; _i++) {
toggle = togglesToInsert_1[_i];
checkboxesEl.append(toggle);
}
// Insert the toggle label next to the first check box
// $(this.dom.creationForm.children('div.'+this.classes.checkRow)[0]).prepend(this.dom.toggleLabel);
// Insert the creation modal and the background
this.dom.background.appendTo(this.dom.dtContainer);
this.dom.creation
.append(this.dom.creationTitle)
.append(this.dom.creationForm)
.append(this.dom.createButtonRow)
.appendTo(this.dom.dtContainer);
$(this.s.dt.table().node()).trigger('dtsr-modal-inserted');
// Allow the label to be clicked to toggle the checkbox
for (var _a = 0, togglesToInsert_2 = togglesToInsert; _a < togglesToInsert_2.length; _a++) {
toggle = togglesToInsert_2[_a];
$(toggle.children('label:last-child')).on('click', function () {
toggle.children('input').prop('checked', !toggle.children('input').prop('checked'));
});
}
var creationButton = $('button.' + this.classes.creationButton.replace(/ /g, '.'));
var inputs = this.dom.creationForm.find('input');
// If there is an input focus on that
if (inputs.length > 0) {
$(inputs[0]).focus();
}
// Otherwise focus on the confirmation button
else {
creationButton.focus();
}
var background = $('div.' + this.classes.background.replace(/ /g, '.'));
var keyupFunction = function (e) {
if (e.key === 'Enter') {
creationButton.click();
}
else if (e.key === 'Escape') {
background.click();
}
};
if (this.c.modalCloseButton) {
this.dom.creation.append(this.dom.closeButton);
this.dom.closeButton.on('click', function () { return background.click(); });
}
creationButton.on('click', function () {
// Get the values of the checkBoxes
var saveState = {
colReorder: _this.dom.colReorderToggle.find('input').is(':checked'),
columns: {
search: _this.dom.columnsSearchToggle.find('input').is(':checked'),
visible: _this.dom.columnsVisibleToggle.find('input').is(':checked')
},
length: _this.dom.lengthToggle.find('input').is(':checked'),
order: _this.dom.orderToggle.find('input').is(':checked'),
paging: _this.dom.pagingToggle.find('input').is(':checked'),
scroller: _this.dom.scrollerToggle.find('input').is(':checked'),
search: _this.dom.searchToggle.find('input').is(':checked'),
searchBuilder: _this.dom.searchBuilderToggle.find('input').is(':checked'),
searchPanes: _this.dom.searchPanesToggle.find('input').is(':checked'),
select: _this.dom.selectToggle.find('input').is(':checked')
};
// Call the buttons functionality passing in the identifier and what should be saved
var success = buttonAction($('input.' + _this.classes.nameInput.replace(/ /g, '.')).val(), { saveState: saveState });
if (success === true) {
// Remove the dom elements as operation has completed
_this.dom.background.remove();
_this.dom.creation.remove();
// Unbind the keyup function - don't want it to run unnecessarily on every keypress that occurs
$(document).unbind('keyup', keyupFunction);
}
else {
_this.dom.creation.children('.' + _this.classes.modalError).remove();
_this.dom.creation.append(_this.dom[success + 'Error']);
}
});
background.one('click', function () {
// Remove the dome elements as operation has been cancelled
_this.dom.background.remove();
_this.dom.creation.remove();
// Unbind the keyup function - don't want it to run unnecessarily on every keypress that occurs
$(document).unbind('keyup', keyupFunction);
// Rebuild the collection to ensure that the latest changes are present
_this._collectionRebuild();
});
// Have to listen to the keyup event as `escape` doesn't trigger keypress
$(document).on('keyup', keyupFunction);
// Need to save the state before the focus is lost when the modal is interacted with
this.s.dt.state.save();
};
/**
* This callback is called when a state is removed.
* This removes the state from storage and also strips it's button from the container
*
* @param identifier The value that is used to identify a state
*/
StateRestoreCollection.prototype._removeCallback = function (identifier) {
for (var i = 0; i < this.s.states.length; i++) {
if (this.s.states[i].s.identifier === identifier) {
this.s.states.splice(i, 1);
i--;
}
}
this._collectionRebuild();
return true;
};
/**
* Creates a new confirmation modal for the user to approve an action
*
* @param title The title that is to be displayed at the top of the modal
* @param buttonText The text that is to be displayed in the confirmation button of the modal
* @param buttonAction The action that should be taken when the confirmation button is pressed
* @param modalContents The contents for the main body of the modal
*/
StateRestoreCollection.prototype._newModal = function (title, buttonText, buttonAction, modalContents) {
var _this = this;
this.dom.background.appendTo(this.dom.dtContainer);
this.dom.confirmationTitleRow.empty().append(title);
var confirmationButton = $('<button class="' + this.classes.confirmationButton + ' ' + this.classes.dtButton + '">' +
buttonText +
'</button>');
this.dom.confirmation
.empty()
.append(this.dom.confirmationTitleRow)
.append(modalContents)
.append($('<div class="' + this.classes.confirmationButtons + '"></div>')
.append(confirmationButton))
.appendTo(this.dom.dtContainer);
$(this.s.dt.table().node()).trigger('dtsr-modal-inserted');
var inputs = modalContents.children('input');
// If there is an input focus on that
if (inputs.length > 0) {
$(inputs[0]).focus();
}
// Otherwise focus on the confirmation button
else {
confirmationButton.focus();
}
var background = $('div.' + this.classes.background.replace(/ /g, '.'));
var keyupFunction = function (e) {
// If enter same action as pressing the button
if (e.key === 'Enter') {
confirmationButton.click();
}
// If escape close modal
else if (e.key === 'Escape') {
background.click();
}
};
// When the button is clicked, call the appropriate action,
// remove the background and modal from the screen and unbind the keyup event.
confirmationButton.on('click', function () {
var success = buttonAction(true);
if (success === true) {
_this.dom.background.remove();
_this.dom.confirmation.remove();
$(document).unbind('keyup', keyupFunction);
confirmationButton.off('click');
}
else {
_this.dom.confirmation.children('.' + _this.classes.modalError).remove();
_this.dom.confirmation.append(_this.dom[success + 'Error']);
}
});
this.dom.confirmation.on('click', function (e) {
e.stopPropagation();
});
// When the button is clicked, remove the background and modal from the screen and unbind the keyup event.
background.one('click', function () {
_this.dom.background.remove();
_this.dom.confirmation.remove();
$(document).unbind('keyup', keyupFunction);
});
$(document).on('keyup', keyupFunction);
};
/**
* Private method that checks for previously created states on initialisation
*/
StateRestoreCollection.prototype._searchForStates = function () {
var _this = this;
var keys = Object.keys(localStorage);
var _loop_2 = function (key) {
// eslint-disable-next-line no-useless-escape
if (key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname + '$')) ||
key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname +
'_' + this_2.s.dt.table().node().id + '$'))) {
var loadedState_1 = JSON.parse(localStorage.getItem(key));
if (loadedState_1.stateRestore.isPreDefined ||
(loadedState_1.stateRestore.tableId &&
loadedState_1.stateRestore.tableId !== this_2.s.dt.table().node().id)) {
return "continue";
}
var that_1 = this_2;
var successCallback = function () {
this.s.savedState = loadedState_1;
that_1.s.states.push(this);
that_1._collectionRebuild();
};
var newState_1 = new StateRestore(this_2.s.dt, $.extend(true, {}, this_2.c, { saveState: loadedState_1.c.saveState }), loadedState_1.stateRestore.state, loadedState_1, false, successCallback);
$(this_2.s.dt.table().node()).on('dtsr-modal-inserted', function () {
newState_1.dom.confirmation.one('dtsr-remove', function () { return _this._removeCallback(newState_1.s.identifier); });
newState_1.dom.confirmation.one('dtsr-rename', function () { return _this._collectionRebuild(); });
newState_1.dom.confirmation.one('dtsr-save', function () { return _this._collectionRebuild(); });
});
}
};
var this_2 = this;
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
var key = keys_1[_i];
_loop_2(key);
}
};
StateRestoreCollection.version = '1.0.0';
StateRestoreCollection.classes = {
background: 'dtsr-background',
checkBox: 'dtsr-check-box',
checkLabel: 'dtsr-check-label',
checkRow: 'dtsr-check-row',
closeButton: 'dtsr-popover-close',
colReorderToggle: 'dtsr-colReorder-toggle',
columnsSearchToggle: 'dtsr-columns-search-toggle',
columnsVisibleToggle: 'dtsr-columns-visible-toggle',
confirmation: 'dtsr-confirmation',
confirmationButton: 'dtsr-confirmation-button',
confirmationButtons: 'dtsr-confirmation-buttons',
confirmationMessage: 'dtsr-confirmation-message dtsr-name-label',
confirmationText: 'dtsr-confirmation-text',
confirmationTitle: 'dtsr-confirmation-title',
confirmationTitleRow: 'dtsr-confirmation-title-row',
creation: 'dtsr-creation',
creationButton: 'dtsr-creation-button',
creationForm: 'dtsr-creation-form',
creationText: 'dtsr-creation-text',
creationTitle: 'dtsr-creation-title',
dtButton: 'dt-button',
emptyStates: 'dtsr-emptyStates',
formRow: 'dtsr-form-row',
leftSide: 'dtsr-left',
lengthToggle: 'dtsr-length-toggle',
modalError: 'dtsr-modal-error',
modalFoot: 'dtsr-modal-foot',
nameInput: 'dtsr-name-input',
nameLabel: 'dtsr-name-label',
orderToggle: 'dtsr-order-toggle',
pagingToggle: 'dtsr-paging-toggle',
rightSide: 'dtsr-right',
scrollerToggle: 'dtsr-scroller-toggle',
searchBuilderToggle: 'dtsr-searchBuilder-toggle',
searchPanesToggle: 'dtsr-searchPanes-toggle',
searchToggle: 'dtsr-search-toggle',
selectToggle: 'dtsr-select-toggle',
toggleLabel: 'dtsr-toggle-title'
};
StateRestoreCollection.defaults = {
_createInSaved: false,
ajax: false,
create: true,
creationModal: false,
i18n: {
creationModal: {
button: 'Create',
colReorder: 'Column Order',
columns: {
search: 'Column Search',
visible: 'Column Visibility'
},
length: 'Page Length',
name: 'Name:',
order: 'Sorting',
paging: 'Paging',
scroller: 'Scroll Position',
search: 'Search',
searchBuilder: 'SearchBuilder',
searchPanes: 'SearchPanes',
select: 'Select',
title: 'Create New State',
toggleLabel: 'Include:'
},
duplicateError: 'A state with this name already exists.',
emptyError: 'Name cannot be empty.',
emptyStates: 'No saved states',
removeConfirm: 'Are you sure you want to remove %s?',
removeError: 'Failed to remove state.',
removeJoiner: ' and ',
removeSubmit: 'Remove',
removeTitle: 'Remove State',
renameButton: 'Rename',
renameLabel: 'New Name for %s:',
renameTitle: 'Rename State'
},
modalCloseButton: true,
preDefined: {},
remove: true,
rename: true,
save: true,
saveState: {
colReorder: true,
columns: {
search: true,
visible: true
},
length: true,
order: true,
paging: true,
scroller: true,
search: true,
searchBuilder: true,
searchPanes: true,
select: true
},
splitSecondaries: [
'updateState',
'renameState',
'removeState'
],
toggle: {
colReorder: false,
columns: {
search: false,
visible: false
},
length: false,
order: false,
paging: false,
scroller: false,
search: false,
searchBuilder: false,
searchPanes: false,
select: false
}
};
return StateRestoreCollection;
}());
export default StateRestoreCollection;