From 965c2caca311c9c39bbc3e7eae5011e0d80b6818 Mon Sep 17 00:00:00 2001 From: David Ashby Date: Fri, 5 Jan 2024 21:47:34 -0500 Subject: [PATCH] refactoring and fix race condition --- frontend/files/app.js | 120 +++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/frontend/files/app.js b/frontend/files/app.js index e3b4431..a023322 100644 --- a/frontend/files/app.js +++ b/frontend/files/app.js @@ -5,7 +5,9 @@ var sortState = { var admin = false; -function init() { +var books; + +function checkAdminMode() { fetch("/api/mode") .then((response) => response.json()) .then((resp) => (admin = resp.Admin)) @@ -19,36 +21,32 @@ function init() { element.classList.remove("hidden"); } }); +} +function loadBookList() { fetch("/api/books") .then((response) => response.json()) - .then((books) => { + .then((list) => { // prepare response - books.forEach(apiResponseParsing); - document.getElementById("search").addEventListener("input", (e) => { - renderTable( - search( - books, - e.target.value, - document.getElementById("childrens").checked - ) - ); - }); - document.getElementById("childrens").addEventListener("change", (e) => { - renderTable( - search( - books, - document.getElementById("search").value, - e.target.checked - ) - ); - }); - renderTable( - search(books, "", document.getElementById("childrens").checked) - ); + list.forEach(apiResponseParsing); + books = list; + document.getElementById("search").addEventListener("input", rerender); + document.getElementById("childrens").addEventListener("change", rerender); + rerender(); }); } +function rerender() { + var searchValue = document.getElementById("search").value; + var childrens = document.getElementById("childrens").checked; + renderTable(search(searchValue, childrens)); +} + +function init() { + checkAdminMode(); + loadBookList(); +} + function renderAddBookView() { document.getElementById("current").innerHTML = AddBookTemplate(); document.getElementById("lookup").addEventListener("click", (e) => { @@ -61,26 +59,20 @@ function renderAddBookView() { }); document.getElementById("save").addEventListener("click", (e) => { e.preventDefault(); - fetch("/api/books", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - title: document.getElementById("title").value, - authors: document.getElementById("authors").value.split(";"), - sortAuthor: document.getElementById("sortAuthor").value, - "isbn-10": document.getElementById("isbn-10").value, - "isbn-13": document.getElementById("isbn-13").value, - publisher: document.getElementById("publisher").value, - format: document.getElementById("format").value, - genre: document.getElementById("genre").value, - series: document.getElementById("series").value, - volume: document.getElementById("volume").value, - year: document.getElementById("year").value, - coverURL: document.getElementById("coverURL").value, - }), + saveBook({ + title: document.getElementById("title").value, + authors: document.getElementById("authors").value.split(";"), + sortAuthor: document.getElementById("sortAuthor").value, + "isbn-10": document.getElementById("isbn-10").value, + "isbn-13": document.getElementById("isbn-13").value, + publisher: document.getElementById("publisher").value, + format: document.getElementById("format").value, + genre: document.getElementById("genre").value, + series: document.getElementById("series").value, + volume: document.getElementById("volume").value, + year: document.getElementById("year").value, + coverURL: document.getElementById("coverURL").value, }); - renderAddBookView(); - init(); }); } @@ -106,34 +98,35 @@ function saveBook(book) { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(book), + }).then(() => { + clearAddBookForm(); + loadBookList(); }); } -function renderTable(books, sortField) { +function renderTable(bookList, sortField) { if (sortField) { - if (sortState.sortBy === sortField && sortState.sortOrder === "asc") { - sortState.sortOrder = "desc"; - } else { - sortState.sortOrder = "asc"; - } + sortState.sortOrder = + sortState.sortBy === sortField && sortState.sortOrder === "asc" + ? "desc" + : "asc"; sortState.sortBy = sortField; } - books.sort((one, two) => + bookList.sort((one, two) => (one[sortState.sortBy] + one["sortTitle"]).localeCompare( two[sortState.sortBy] + two["sortTitle"] ) ); if (sortState.sortOrder === "desc") { - books.reverse(); + bookList.reverse(); } - books.forEach((e, i) => (e.rowNumber = i)); // re-key + bookList.forEach((e, i) => (e.rowNumber = i)); // re-key // rendering var bookElement = document.getElementById("books"); - bookElement.innerHTML = TableTemplate(books); + bookElement.innerHTML = TableTemplate(bookList); - var bookCount = document.getElementById("bookCount"); - bookCount.innerHTML = `${books.length} books`; + document.getElementById("bookCount").innerHTML = `${bookList.length} books`; // add listeners for selecting book to view Array.from(bookElement.querySelectorAll("tbody tr")) @@ -142,7 +135,7 @@ function renderTable(books, sortField) { row.addEventListener("click", (e) => { // add listener to swap current book document.getElementById("current").innerHTML = BookTemplate( - books[e.currentTarget.id] + bookList[e.currentTarget.id] ); }); }); @@ -151,7 +144,7 @@ function renderTable(books, sortField) { (row) => { row.addEventListener("click", function (e) { // only add callback when there's a sortBy attribute - renderTable(books, e.target.dataset.sortBy); + renderTable(bookList, e.target.dataset.sortBy); }); } ); @@ -175,9 +168,9 @@ function apiResponseParsing(book) { return book; } -function search(books, searchBy, includeChildrensBooks) { +function search(searchBy, includeChildrensBooks) { searchBy = searchCleaner(searchBy); - books = books.filter( + return books.filter( ({ title, authors, genre, publisher, series, year, childrens }) => { var inSearch = true; if (searchBy !== "") { @@ -196,7 +189,6 @@ function search(books, searchBy, includeChildrensBooks) { return inSearch; } ); - return books; } function titleCleaner(title) { @@ -222,6 +214,14 @@ function ISBNfromEAN(EAN) { return ISBN + (checkdigit === 10 ? "X" : checkdigit); } +function clearAddBookForm() { + document + .getElementById("newBookForm") + .childNodes.forEach((node) => + node.nodeName === "LABEL" ? (node.lastChild.value = "") : null + ); +} + function BookTemplate({ "isbn-13": isbn13, "isbn-10": isbn10,