355 lines
12 KiB
JavaScript
355 lines
12 KiB
JavaScript
// SA. ENV-834
|
|
var contentLockerReloadUrl = "";
|
|
|
|
var timer;
|
|
var siteRoot = location.protocol + '//' + location.host;
|
|
var dtLastActivity;
|
|
var saveButton;
|
|
var deleteButton;
|
|
var editButton;
|
|
var canEnabledDelBtn;
|
|
var errorPlaceholder;
|
|
var checking;
|
|
var updating;
|
|
var dataIsEdited;
|
|
|
|
var dataEditedText = "Sorry, this {entity} is being edited by {username}. Please, try to <a href='" + contentLockerReloadUrl + "'>refresh</a> the page a little bit later.";
|
|
var dataExpiredText = "Sorry, this {entity} has been changed since your last visit. Please, <a href='" + contentLockerReloadUrl + "'>refresh</a> the page to get actual version.";
|
|
var timedInactivityText = "Sorry, you have exceeded the period of inactivity and we cannot save your changes now. Please reload the page to try edit this object again.";
|
|
var UserFinishedEditing = "{entity} is now available for editing. <a href='" + contentLockerReloadUrl + "'>Refresh</a> the page to load latest changes and start editing";
|
|
var serverErrorText = "Server is not responding";
|
|
var dataEditedPopover = "{entity} is being edited by {username}. Please, try again later.";
|
|
var serverError404Text = "It seems like the connection to the server was lost and server considered you left the edit page.";
|
|
var serverError401Text = "You are not authorized to edit the {entity}. Please, <a href='" + siteRoot + "/Account/Login'>sign in</a> and try to edit the {entity} again";
|
|
|
|
|
|
// call it when click on the link before redirect to locked page
|
|
function CheckLock(buttonId, tableId, fieldId) {
|
|
var contentLockerRequest = {
|
|
'tableId': tableId,
|
|
'fieldId': fieldId
|
|
};
|
|
var result = false;
|
|
|
|
$.ajax({
|
|
type: "post",
|
|
url: siteRoot + "/ContentLockerApi/IsLock",
|
|
data: contentLockerRequest,
|
|
async: false,
|
|
error: function (response) {
|
|
ShowPopover(buttonId, serverErrorText);
|
|
result = false;
|
|
},
|
|
success: function (response) {
|
|
if (response.Status == true) {
|
|
ShowPopover(buttonId, dataEditedPopover.replace(/\{username\}/g, response.LockedBy).replace(/\{entity\}/g, response.EntityTitle));
|
|
result = false;
|
|
}
|
|
else {
|
|
result = true;
|
|
}
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
function CheckingLocks(tableId, fieldId, externalReferencesCount, editButtonId, deleteButtonId, erorPlaceholderId) {
|
|
checking = true;
|
|
deleteButton = deleteButtonId;
|
|
editButton = editButtonId;
|
|
errorPlaceholder = erorPlaceholderId;
|
|
dataIsEdited = false;
|
|
if (externalReferencesCount > 0) {
|
|
canEnabledDelBtn = false;
|
|
}
|
|
else {
|
|
canEnabledDelBtn = true;
|
|
}
|
|
|
|
var contentLockerRequest = {
|
|
'tableId': tableId,
|
|
'fieldId': fieldId
|
|
};
|
|
IsLock(contentLockerRequest);
|
|
}
|
|
// call it on the edit page to lock the object
|
|
function StartEdit(tableId, fieldId, deleteButtonId, saveButtonId, erorPlaceholderId, timestamp) {
|
|
|
|
updating = true;
|
|
errorPlaceholder = erorPlaceholderId;
|
|
deleteButton = deleteButtonId;
|
|
saveButton = saveButtonId;
|
|
|
|
var contentLockerRequest = {
|
|
'tableId': tableId,
|
|
'fieldId': fieldId,
|
|
'timestamp': timestamp
|
|
};
|
|
$('#danger').hide();
|
|
AddLock(contentLockerRequest);
|
|
$(window).on('unload', function () {
|
|
RemoveLock(contentLockerRequest.tableId, contentLockerRequest.fieldId);
|
|
});
|
|
|
|
$("#lnkLogout").click(function () {
|
|
RemoveLock(contentLockerRequest.tableId, contentLockerRequest.fieldId);
|
|
});
|
|
}
|
|
// call it on the details (always) and edit page (if content is locked by someone else)
|
|
function IsLock(contentLockerRequest) {
|
|
if(!checking)
|
|
return;
|
|
var canGoOn = true;
|
|
$.ajax({
|
|
type: "post",
|
|
url: siteRoot + "/ContentLockerApi/IsLock",
|
|
data: contentLockerRequest,
|
|
error: function(response) {
|
|
$(editButton).addClass("disabled");
|
|
LockTabElements();
|
|
$(deleteButton).addClass("disabled");
|
|
RemoveErrorMessage();
|
|
if (response.status != null) {
|
|
if (response.status == 401)
|
|
ShowErrorMessage(serverError401Text.replace(/\{entity\}/g, response.EntityTitle), true);
|
|
else
|
|
ShowErrorMessage(serverErrorText, true);
|
|
} else
|
|
ShowErrorMessage(serverErrorText, true);
|
|
},
|
|
success: function(response) {
|
|
if (response == null || response.Status == null) {
|
|
$(editButton).addClass("disabled");
|
|
LockTabElements();
|
|
$(deleteButton).addClass("disabled");
|
|
RemoveErrorMessage();
|
|
ShowErrorMessage(serverErrorText, true);
|
|
} else {
|
|
if (response.Status == true) {
|
|
$(editButton).addClass("disabled");
|
|
LockTabElements();
|
|
$(deleteButton).addClass("disabled");
|
|
ShowErrorMessage(dataEditedText.replace(/\{username\}/g, response.LockedBy).replace(/\{entity\}/g, response.EntityTitle), false);
|
|
dataIsEdited = true;
|
|
} else {
|
|
if (dataIsEdited) {
|
|
RemoveErrorMessage();
|
|
canGoOn = false;
|
|
ShowErrorMessage(UserFinishedEditing.replace(/\{entity\}/g, response.EntityTitle, false), true);
|
|
}
|
|
dataIsEdited = false;
|
|
//$(editButton).removeClass("disabled");
|
|
///UnlockTabElements();
|
|
//if (canEnabledDelBtn) {
|
|
// $(deleteButton).removeClass("disabled");
|
|
//}
|
|
}
|
|
if (canGoOn) {
|
|
setTimeout(IsLock, _isLockCheckIntervalMs, contentLockerRequest);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
// call it to send lock ajax request to the server
|
|
function AddLock(contentLockerRequest) {
|
|
contentLockerReloadUrl = document.location.href;
|
|
var hashPos = contentLockerReloadUrl.indexOf('#');
|
|
|
|
if (hashPos > 0)
|
|
contentLockerReloadUrl = contentLockerReloadUrl.substr(0, hashPos);
|
|
|
|
$.ajax({
|
|
type: "post",
|
|
url: siteRoot + "/ContentLockerApi/AddLock",
|
|
data: contentLockerRequest,
|
|
error: function(response) {
|
|
$(saveButton).addClass("disabled");
|
|
LockTabElements();
|
|
$(deleteButton).addClass("disabled");
|
|
ShowErrorMessage(serverErrorText, true);
|
|
},
|
|
success: function (response) {
|
|
if (response == null || response.Status == null) {
|
|
$(saveButton).addClass("disabled");
|
|
LockTabElements();
|
|
$(deleteButton).addClass("disabled");
|
|
ShowErrorMessage(serverErrorText, true);
|
|
} else {
|
|
if (response.Status == true) {
|
|
$(saveButton).removeClass("disabled");
|
|
UnlockTabElements();
|
|
$(deleteButton).removeClass("disabled");
|
|
RemoveErrorMessage();
|
|
|
|
dtLastActivity = new Date().getTime();
|
|
setTimeout(UpdateLock, _isLockCheckIntervalMs, contentLockerRequest);
|
|
} else {
|
|
var errorMessage = '';
|
|
if (response.Code == 2) { // expired
|
|
errorMessage = dataExpiredText.replace(/\{username\}/g, response.LockedBy).replace(/\{entity\}/g, response.EntityTitle);
|
|
} else { // blocked by other person
|
|
errorMessage = dataEditedText.replace(/\{username\}/g, response.LockedBy).replace(/\{entity\}/g, response.EntityTitle);
|
|
}
|
|
$(saveButton).addClass("disabled");
|
|
LockTabElements();
|
|
$(deleteButton).addClass("disabled");
|
|
ShowErrorMessage(errorMessage, false);
|
|
CheckingLocks(contentLockerRequest.tableId, contentLockerRequest.fieldId, 0, saveButton, deleteButton, errorPlaceholder);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
// automatically called every X seconds to extend locked period
|
|
function UpdateLock(contentLockerRequest) {
|
|
if (!updating)
|
|
return;
|
|
$.ajax({
|
|
type: "post",
|
|
url: siteRoot + "/ContentLockerApi/UpdateLock",
|
|
data: contentLockerRequest,
|
|
error: function(returnval) {
|
|
$(saveButton).addClass("disabled");
|
|
LockTabElements();
|
|
$(deleteButton).addClass("disabled");
|
|
ShowErrorMessage(serverErrorText, true);
|
|
},
|
|
success: function(returnval) {
|
|
if (returnval == true) {
|
|
if (new Date().getTime() < dtLastActivity + _periodOfInactivity*1000) {
|
|
setTimeout(UpdateLock, _isLockCheckIntervalMs, contentLockerRequest);
|
|
} else {
|
|
$(saveButton).addClass("disabled");
|
|
LockTabElements();
|
|
$(deleteButton).addClass("disabled");
|
|
ShowErrorMessage(timedInactivityText, true);
|
|
RemoveLock(contentLockerRequest.tableId, contentLockerRequest.fieldId);
|
|
}
|
|
} else {
|
|
$(saveButton).addClass("disabled");
|
|
LockTabElements();
|
|
$(deleteButton).addClass("disabled");
|
|
ShowErrorMessage(serverErrorText, true);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
// call it if user leave the edit page or no activity for a long time
|
|
function RemoveLock(tableId, fieldId) {
|
|
var contentLockerRequest = {
|
|
'tableId': tableId,
|
|
'fieldId': fieldId
|
|
};
|
|
|
|
$.ajax({
|
|
type: "post",
|
|
async: false,
|
|
url: siteRoot + "/ContentLockerApi/RemoveLock",
|
|
data: contentLockerRequest
|
|
});
|
|
}
|
|
|
|
|
|
|
|
// reset timer of inactivity
|
|
function ResetInactivePeriod() {
|
|
dtLastActivity = new Date().getTime();
|
|
}
|
|
|
|
function ShowErrorMessage(errorText, enabledReloadLink) {
|
|
if (document.getElementById(errorPlaceholder).childElementCount == 0) {
|
|
var alertMsg = document.createElement('div');
|
|
alertMsg.className = "alert alert-danger";
|
|
|
|
var erormsg = document.createElement('span');
|
|
$(erormsg).html(errorText);
|
|
|
|
alertMsg.appendChild(erormsg);
|
|
|
|
if (enabledReloadLink) {
|
|
var linkPlaceholder = document.createElement('span');
|
|
$(linkPlaceholder).css('float','right');
|
|
|
|
var link = document.createElement('a');
|
|
link.href = 'javascript:reloadPage()'; // contentLockerReloadUrl; // SA. ENV-815
|
|
$(link).text("Reload");
|
|
|
|
linkPlaceholder.appendChild(link);
|
|
alertMsg.appendChild(linkPlaceholder);
|
|
}
|
|
document.getElementById(errorPlaceholder).appendChild(alertMsg);
|
|
}
|
|
}
|
|
|
|
// SA. ENV-815
|
|
function reloadPage() {
|
|
document.location.href = contentLockerReloadUrl;
|
|
}
|
|
|
|
function RemoveErrorMessage() {
|
|
var erorRootElement = document.getElementById(errorPlaceholder)
|
|
|
|
if (erorRootElement.childElementCount > 0)
|
|
|
|
while (erorRootElement.hasChildNodes()) {
|
|
erorRootElement.removeChild(erorRootElement.lastChild);
|
|
}
|
|
}
|
|
|
|
function ShowPopover(buttonId, message) {
|
|
var btn = $('#' + buttonId),
|
|
title = '<strong>Not allowed</strong><button type="button" class="close">×</button>';
|
|
btn.popover({
|
|
html: 'true',
|
|
title: title,
|
|
trigger: 'manual',
|
|
content: message,
|
|
template: '<div class="popover" style="min-width: 250px;"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
|
});
|
|
btn.popover('show');
|
|
|
|
// need to fix bug when popover title parameter didn't work when button had title attribute
|
|
btn.data('bs.popover').$tip.find('.popover-title').html(title);
|
|
var originalTitle = btn.data('original-title');
|
|
if (originalTitle) {
|
|
btn.attr('title', originalTitle);
|
|
btn.removeAttr('data-original-title');
|
|
}
|
|
|
|
btn.data('bs.popover').$tip.find('.popover-title').find('button.close').on('click', function (event) {
|
|
$('#' + buttonId).popover('destroy');
|
|
if (!event)
|
|
event = window.event;
|
|
event.stopPropagation();
|
|
});
|
|
}
|
|
|
|
function LockTabElements() {
|
|
var lockableElements = document.getElementsByClassName('lockable');
|
|
for (var i = 0; i < lockableElements.length; ++i) {
|
|
var item = lockableElements[i];
|
|
$(item).addClass("disabled");
|
|
}
|
|
}
|
|
|
|
function UnlockTabElements() {
|
|
var lockableElements = document.getElementsByClassName('lockable');
|
|
for (var i = 0; i < lockableElements.length; ++i) {
|
|
var item = lockableElements[i];
|
|
$(item).removeClass("disabled");
|
|
}
|
|
}
|
|
|
|
function StopChecking ()
|
|
{
|
|
checking = false;
|
|
}
|
|
|
|
function StopEdit()
|
|
{
|
|
updating = false;
|
|
}
|
|
|
|
|
|
|