Handle authorization problems when saving article with JS

This commit is contained in:
Magnus Hoff 2017-11-24 17:04:36 +01:00
parent af358fe22c
commit 2e406f4480
2 changed files with 89 additions and 25 deletions

View file

@ -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);

View file

@ -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;