Handle authorization problems when saving article with JS
This commit is contained in:
parent
af358fe22c
commit
2e406f4480
2 changed files with 89 additions and 25 deletions
|
@ -20,6 +20,38 @@ function isEdited(form) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loginDialog(loginUrl) {
|
||||||
|
const loginDialogHtml = "<div class=popup><p>Your changes could not be saved</p><p>Log in and try again</p><div><button>Never mind</button> <a href='' target=login>Open login page</a></div></div>";
|
||||||
|
|
||||||
|
const dialog = document.createElement("div");
|
||||||
|
dialog.className = "modal-block";
|
||||||
|
dialog.innerHTML = loginDialogHtml;
|
||||||
|
|
||||||
|
const loginLink = dialog.querySelector("a");
|
||||||
|
const dismiss = dialog.querySelector("button");
|
||||||
|
|
||||||
|
loginLink.setAttribute("href", loginUrl);
|
||||||
|
|
||||||
|
document.body.appendChild(dialog);
|
||||||
|
loginLink.focus();
|
||||||
|
|
||||||
|
function remove() {
|
||||||
|
document.body.removeChild(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
loginLink.addEventListener("click", () => {
|
||||||
|
remove();
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
dismiss.addEventListener("click", () => {
|
||||||
|
remove();
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let hasBeenOpen = false;
|
let hasBeenOpen = false;
|
||||||
function openEditor() {
|
function openEditor() {
|
||||||
const container = document.querySelector(".container");
|
const container = document.querySelector(".container");
|
||||||
|
@ -53,6 +85,7 @@ function openEditor() {
|
||||||
|
|
||||||
const body = queryArgsFromForm(form);
|
const body = queryArgsFromForm(form);
|
||||||
textarea.disabled = true;
|
textarea.disabled = true;
|
||||||
|
// TODO Disable other interaction as well: title editor, cancel and OK buttons
|
||||||
|
|
||||||
fetch(
|
fetch(
|
||||||
form.getAttribute("action"),
|
form.getAttribute("action"),
|
||||||
|
@ -65,39 +98,47 @@ function openEditor() {
|
||||||
credentials: "same-origin",
|
credentials: "same-origin",
|
||||||
}
|
}
|
||||||
).then(response => {
|
).then(response => {
|
||||||
|
if ((response.status === 401) && (response.headers.has("location"))) {
|
||||||
|
return loginDialog(response.headers.get("location"))
|
||||||
|
.then(() => {
|
||||||
|
textarea.disabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!response.ok) throw new Error("Unexpected status code (" + response.status + ")");
|
if (!response.ok) throw new Error("Unexpected status code (" + response.status + ")");
|
||||||
|
|
||||||
return response.json();
|
return response.json()
|
||||||
}).then(result => {
|
.then(result => {
|
||||||
// Update url-bar, page title and footer
|
// Update url-bar, page title and footer
|
||||||
window.history.replaceState(null, result.title, result.slug == "" ? "." : result.slug);
|
window.history.replaceState(null, result.title, result.slug == "" ? "." : result.slug);
|
||||||
document.querySelector("title").textContent = result.title;
|
document.querySelector("title").textContent = result.title;
|
||||||
lastUpdated.innerHTML = result.last_updated;
|
lastUpdated.innerHTML = result.last_updated;
|
||||||
lastUpdated.classList.remove("missing");
|
lastUpdated.classList.remove("missing");
|
||||||
|
|
||||||
// Update body:
|
// Update body:
|
||||||
rendered.innerHTML = result.rendered;
|
rendered.innerHTML = result.rendered;
|
||||||
|
|
||||||
form.elements.title.value = result.title;
|
form.elements.title.value = result.title;
|
||||||
shadow.value = textarea.value = result.body;
|
shadow.value = textarea.value = result.body;
|
||||||
|
|
||||||
// Update form:
|
// Update form:
|
||||||
form.elements.base_revision.value = result.revision;
|
form.elements.base_revision.value = result.revision;
|
||||||
for (const element of form.elements) {
|
for (const element of form.elements) {
|
||||||
element.defaultValue = element.value;
|
element.defaultValue = element.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.conflict) {
|
if (!result.conflict) {
|
||||||
container.classList.remove('edit');
|
container.classList.remove('edit');
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea.disabled = false;
|
textarea.disabled = false;
|
||||||
autosizeTextarea(textarea, shadow);
|
autosizeTextarea(textarea, shadow);
|
||||||
|
|
||||||
if (result.conflict) {
|
if (result.conflict) {
|
||||||
alert("Your edit came into conflict with another change and has not been saved.\n" +
|
alert("Your edit came into conflict with another change and has not been saved.\n" +
|
||||||
"Please resolve the merge conflict and save again.");
|
"Please resolve the merge conflict and save again.");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
textarea.disabled = false;
|
textarea.disabled = false;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
|
@ -431,6 +431,29 @@ input[type="search"] {
|
||||||
background: #ceb;
|
background: #ceb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-block {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup {
|
||||||
|
position: fixed;
|
||||||
|
|
||||||
|
width: 300px;
|
||||||
|
left: calc(50% - 150px);
|
||||||
|
|
||||||
|
height: 150px;
|
||||||
|
top: calc(50% - 75px);
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
background: #eee;
|
||||||
|
box-shadow: 2px 2px 8px rgba(0,0,0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
@page {
|
@page {
|
||||||
margin: 25mm;
|
margin: 25mm;
|
||||||
|
|
Loading…
Reference in a new issue