EnVisageOnline/Main/Source/EnVisage/Scripts/stateManagement.js

477 lines
18 KiB
JavaScript

/* Created by SA
* User settings and page state management functions
* ENV-815
*/
var C_PREFERENCES_GET_URL = "/User/GetPreferences";
var C_PREFERENCES_GET_URL_ASYNC = "/User/GetPagePreferences";
var C_PREFERENCES_SAVE_URL = "/User/SavePreferences";
var C_QUICKLINK_LOAD_URL = "/UserQuickLink/GetPreferences";
var pagePreferencesCache = {};
function getPageUrl() {
return window.location.pathname;
}
// get data-section attr value for the specified element
function getDataSection(element) {
var foundSection = '';
var sections = $(element).parents("*[data-section]");
if (sections && (sections.length > 0))
foundSection = $(sections).first().attr("data-section");
return foundSection;
}
// gather all values from elements with data-key attr for the element with the specified data-section attr value
function collectPreferences(dataSection) {
var items = [];
var dataSectionElement = $(document).find("*[data-section='" + dataSection + "']");
if (!dataSectionElement || (dataSectionElement.length < 1))
dataSectionElement = $(document);
var controlsToStore = $(dataSectionElement).find('*[data-key]');
for (var index = 0; index < controlsToStore.length; index++) {
var currentControl = controlsToStore[index];
var tagName = currentControl.tagName.toLowerCase();
if (tagName == 'input') {
var inputType = $(currentControl).attr('type');
tagName = tagName + '#' + inputType;
}
var dataKey = $(currentControl).attr('data-key');
var value = '';
switch (tagName) {
case 'input#checkbox':
case 'input#radio':
value = $(currentControl).prop('checked');
break;
case 'input#text':
case 'input#search':
case 'input#hidden':
value = $(currentControl).val();
break;
case 'select':
value = $(currentControl).val();
if ($(currentControl).attr('multiple') === 'multiple' && !!value && $.isArray(value))
value = value.join(',');
break;
};
items.push({
Key: dataKey,
Value: value
});
}
return items;
}
// save specified page preferences (data) to the database
function saveUserPagePreferences(data, dataSection, customPageUrl, callback) {
var pageUrl = customPageUrl;
if (!customPageUrl || (customPageUrl.length < 1))
pageUrl = getPageUrl();
var postData = {};
postData.data = JSON.stringify(data);
postData.url = pageUrl;
postData.section = dataSection;
$.post(C_PREFERENCES_SAVE_URL, postData, function (data) {
if(callback)
callback();
}).error(function (h, e) {
console.log("Save preferences error. h = " + h + ", e = " + e);
});
}
// Obsolete - use only Async version, ask AK for details
// load page preferences from quick link if there is a linkId param in QS
// otherwise (linkId not set or returned data is empty) loads page preferences for the specified (or current) page url
function loadUserPagePreferences(dataSection, customPageUrl) {
var pageUrl = customPageUrl;
if (typeof quickLinkData === 'undefined' && URI().query(true).linkId) {
$.ajax(C_QUICKLINK_LOAD_URL,
{
async: false,
data: { linkId: URI().query(true).linkId },
method: "POST",
success: function (response, textStatus, jqXHR) {
if (response && response.Status === "OK" && response.Data) {
quickLinkData = JSON.parse(response.Data);
if (quickLinkData[dataSection] && quickLinkData[dataSection].length != 0) {//
return quickLinkData[dataSection];
}
else {
if (!customPageUrl || (customPageUrl.length < 1))
pageUrl = getPageUrl();
var prefs = [];
if (typeof quickLinkData !== 'undefined' && quickLinkData[dataSection]) //
return quickLinkData[dataSection];
if (!dataSection || (dataSection.length < 1))
prefs;
$.ajax(C_PREFERENCES_GET_URL,
{
async: false,
data: { url: pageUrl, section: dataSection },
method: "POST",
success: function (response, textStatus, jqXHR) {
if (response && response.Status === "OK" && response.Data) {
prefs = JSON.parse(response.Data);
}
}
});
return prefs;
}
}
}
});
return quickLinkData[dataSection];
}
else {
if (!customPageUrl || (customPageUrl.length < 1))
pageUrl = getPageUrl();
var prefs = [];
if (typeof quickLinkData !== 'undefined' && quickLinkData[dataSection]) {
return quickLinkData[dataSection];
}
if (!dataSection || (dataSection.length < 1))
prefs;
$.ajax(C_PREFERENCES_GET_URL,
{
async: false,
data: { url: pageUrl, section: dataSection },
method: "POST",
success: function (response, textStatus, jqXHR) {
if (response && response.Status === "OK" && response.Data) {
prefs = JSON.parse(response.Data);
}
}
});
return prefs;
}
}
// loads page preferences for the specified (or current) page url
function loadUserPreferences(dataSection, customPageUrl) {
var pageUrl = customPageUrl;
if (!customPageUrl || (customPageUrl.length < 1))
pageUrl = getPageUrl();
var prefs = [];
$.ajax(C_PREFERENCES_GET_URL,
{
async: false,
data: { url: pageUrl, section: dataSection },
method: "POST",
success: function (response, textStatus, jqXHR) {
if (response && response.Status === "OK" && response.Data) {
prefs = JSON.parse(response.Data);
}
}
});
return prefs;
}
function restorePreferences(dataSection, data) {
if (!dataSection || (dataSection.length < 1) || typeof data === 'undefined')
return;
var dataSectionElement = $(document).find("*[data-section='" + dataSection + "']");
if (!dataSectionElement || (dataSectionElement.length < 1))
dataSectionElement = $(document);
for (var index = 0; index < data.length; index++) {
var currentRec = data[index];
var dataKey = currentRec.Key;
var value = currentRec.Value;
var prefsReceiver = $(dataSectionElement).find('*[data-key="' + dataKey + '"]');
if (prefsReceiver && (prefsReceiver.length > 0)) {
var tagName = prefsReceiver.get(0).tagName.toLowerCase();
if (tagName == 'input') {
var inputType = $(prefsReceiver).attr('type');
tagName = tagName + '#' + inputType;
}
switch (tagName) {
case 'input#checkbox':
case 'input#radio':
$(prefsReceiver).prop('checked', value);
break;
case 'input#text':
case 'input#hidden':
$(prefsReceiver).val(value);
break;
case 'select':
if ($(prefsReceiver).attr('multiple') === 'multiple' && !!value && !$.isArray(value))
value = value.split(',');
if (!!$(prefsReceiver).data("select2")) {
$(prefsReceiver).select2('val', value);
}
else {
$(prefsReceiver).val(value);
}
break;
default:
};
}
}
}
function generalizeUrl(url) {
var components = url.split("/");
var result = "";
for (var index = 1; index < (components.length - 1) ; index++) {
result += ("/" + components[index]);
}
return result;
}
function saveLastPageVisited(pageUrl) {
if (USER_PREFERENCE_LASTPAGE_URL == null || USER_PREFERENCE_LASTPAGE_URL == "") {
console.log("USER_PREFERENCE_LASTPAGE_URL constant is not registered in the main _Layout.cshtml");
return;
}
if (USER_PREFERENCE_LASTPAGE_SECTION == null || USER_PREFERENCE_LASTPAGE_SECTION == "") {
console.log("USER_PREFERENCE_LASTPAGE_SECTION constant is not registered in the main _Layout.cshtml");
return;
}
if (USER_PREFERENCE_LASTPAGE_KEY == null || USER_PREFERENCE_LASTPAGE_KEY == "") {
console.log("USER_PREFERENCE_LASTPAGE_KEY constant is not registered in the main _Layout.cshtml");
return;
}
var prefs = [];
prefs.push({
Key: USER_PREFERENCE_LASTPAGE_KEY,
Value: pageUrl
});
saveUserPagePreferences(prefs, USER_PREFERENCE_LASTPAGE_SECTION, USER_PREFERENCE_LASTPAGE_URL);
}
/* Page Preferences methods v. 2.0
* Updates:
* 1) introduced async data loading
* 2) introduced caching of loaded data
* 3) data modification function(s) update(s) cached data and then save new value to database
* 4) avoid collecting of data from DOM before saving but use cached data instead
* To-Do:
* 5) split loadUserPagePreferencesAsync to loadAsync and getDataSection (which only return cached data without any loading)
* 6) Implement it as a widget to simplify usage
* 7) assign change event handlers for all DOM nodes with data-key attributes to handle data update automatically
* 8) consider replacing data attributes with css classes. Maybe not necessary
*/
// load page preferences from quick link if there is a linkId param in QS
// otherwise (linkId not set or returned data is empty) loads page preferences for the specified (or current) page url
function getDataSectionOptions(dataSection)
{
if (Object.keys(pagePreferencesCache).length == 0 || pagePreferencesCache[dataSection] == null)
return null;
return pagePreferencesCache[dataSection];
}
function loadUserPagePreferencesAsync(dataSection, customPageUrl, force) {
// to-do: move callbacks to functions and reuse page callback in different places
//console.log('1');
var pageUrl = customPageUrl;
if (force) {
pagePreferencesCache = {};
}
if (Object.keys(pagePreferencesCache).length == 0 && URI().query(true).linkId) {
// load quick link page preferences if there is a linkId QS param
var linkPromise = $.ajax(C_QUICKLINK_LOAD_URL,
{
data: { linkId: URI().query(true).linkId },
method: "POST"
}).then(function (response) { // success quick link callback
//console.log('1.2');
if (response && response.Status === "OK" && response.Data) {
//console.log('1.3');
pagePreferencesCache = JSON.parse(response.Data);
}
//console.log('1.4');
//console.log(pagePreferencesCache);
// return page preferences for the specified dataSection
if (pagePreferencesCache[dataSection] && pagePreferencesCache[dataSection].length != 0) {//
//console.log('4');
var deferrer = $.Deferred();
deferrer.resolve(pagePreferencesCache[dataSection] || []);
return deferrer.promise();
}
else {
//console.log('5');
if (!customPageUrl || (customPageUrl.length < 1))
pageUrl = getPageUrl();
// return page preferences for the specified dataSection
if (Object.keys(pagePreferencesCache).length != 0 && pagePreferencesCache[dataSection]) //
{
var deferrer = $.Deferred();
deferrer.resolve(pagePreferencesCache[dataSection] || []);
return deferrer.promise();
}
//console.log('6');
// return entire page preferences object if dataSection was not specified
if (!dataSection || (dataSection.length < 1)) {
var deferrer = $.Deferred();
deferrer.resolve(pagePreferencesCache);
return deferrer.promise();
}
//console.log('7');
// if there is not specified section in page preferences then load them from common page preferences
// and union link preferences with page preferences
var pagePromise = $.ajax(C_PREFERENCES_GET_URL_ASYNC,
{
data: { url: pageUrl },
method: "POST"
}).then(function (response) { // success page callback
//console.log('8');
//console.log(response.Data);
if (response && response.Status === "OK" && response.Data) {
$.each(response.Data, function (key, item) {
// add only missing sections to the cache, DO NOT override link preferences
// because they have higher priority than page preferences
//console.log('9');
if (!pagePreferencesCache[key]) {
// Fix for non-JSON values in page preferences. Set them to pagePreferencesCache as is.
// We may face in 'item' with plain GUID values as well plain boolean values (true/false).
// See pref-keys CreateScenarioDefaultTemplate or USR_PREF_ISHOURS and USR_PREF_AVG.
// tryParseJson defined in pixel-admin.js, line 26135
pagePreferencesCache[key] = $(window).editableutils.tryParseJson(item, false);
}
});
}
//console.log('10');
return pagePreferencesCache[dataSection] || [];
}, function (response) { // fail page callback
throw 'An error occurred while loading page preferences missing in link options';
});
//console.log('7.1');
// console.log(pagePromise);
return pagePromise;
}
}, function (response) { // fail quick link callback
throw 'An error occurred while loading quick link page preferences';
});
return linkPromise;
}
else {
//console.log('11');
if (!customPageUrl || (customPageUrl.length < 1))
pageUrl = getPageUrl();
if (typeof Object.keys(pagePreferencesCache).length != 0 && pagePreferencesCache[dataSection]) {
//console.log('12');
var deferrer = $.Deferred();
deferrer.resolve(pagePreferencesCache[dataSection]);
return deferrer.promise();
}
if (!dataSection || (dataSection.length < 1)) {
//console.log('13');
var deferrer = $.Deferred();
deferrer.resolve(pagePreferencesCache);
return deferrer.promise();
}
var promise = $.ajax(C_PREFERENCES_GET_URL_ASYNC,
{
data: { url: pageUrl },
method: "POST"
}).then(function (response) {
if (response && response.Status === "OK" && response.Data) {
$.each(response.Data, function (key, item) {
// add only missing sections to the cache, DO NOT override existing data because it could be from quick link
if (!pagePreferencesCache[key]) {
// Fix for non-JSON values in page preferences. Set them to pagePreferencesCache as is.
// We may face in 'item' with plain GUID values as well plain boolean values (true/false).
// See pref-keys CreateScenarioDefaultTemplate or USR_PREF_ISHOURS and USR_PREF_AVG.
// tryParseJson defined in pixel-admin.js, line 26135
pagePreferencesCache[key] = $(window).editableutils.tryParseJson(item, false);
}
});
}
return pagePreferencesCache[dataSection] || [];
}, function (response) {
throw 'An error occurred while loading page preferences';
});
//console.log('15');
return promise;
}
}
// save specified page preferences (data) to the database
function updatePagePreferenceValueAsync(customPageUrl, dataSection, key, newValue) {
if (!dataSection) {
throw "Required dataSection arg is not set. Save page state cannot be performed.";
}
// use current page URL if customPageUrl is not specified
var pageUrl = customPageUrl;
if (!customPageUrl || (customPageUrl.length < 1))
pageUrl = getPageUrl();
// set new value in cached data
var section = pagePreferencesCache[dataSection];
if (!section) {
pagePreferencesCache[dataSection] = [];
section = pagePreferencesCache[dataSection];
}
var elem = null;
var i = 0;
for (i = 0; i < section.length; i++) {
if (section[i].Key === key)
{
elem = section[i];
break;
}
}
if (!elem) {
elem = {
Key: key,
Value: newValue
};
section.push(elem);
} else {
elem.Value = newValue;
section[i] = elem;
}
//console.log(pagePreferencesCache);
var postData = {};
postData.data = JSON.stringify(section);
postData.url = pageUrl;
postData.section = dataSection;
var promise = $.ajax(C_PREFERENCES_SAVE_URL,
{
data: postData,
method: "POST"
});
return promise;
}