/* eslint-disable import/prefer-default-export */ // модуль с логикой import { addBook, deleteLine, getAllCategoriesAndAuthors, getAllBooks, getBook, updateBook, } from "./lines-rest-api"; import { cntrls, createOption, createTableRow, imagePlaceholder, } from "./lines-ui"; // функция для заполнения списков авторов и категорий книг async function drawSelects() { const [categories, authors] = await getAllCategoriesAndAuthors(); cntrls.categoryInput.innerHTML = ""; cntrls.authorInput.innerHTML = ""; cntrls.categoryInput.appendChild(createOption("Выберите значение", "", true)); cntrls.authorInput.appendChild(createOption("Выберите значение", "", true)); categories.forEach((category) => { cntrls.categoryInput.appendChild(createOption(category.name, category.id)); }); authors.forEach((author) => { cntrls.authorInput.appendChild(createOption(author.name, author.id)); }); } // функция отрисовки таблицы async function drawTable() { console.info("Try to load data"); if (!cntrls.table) { return; } const data = await getAllBooks(); cntrls.table.innerHTML = ""; data.forEach((book, index) => { cntrls.table.appendChild( createTableRow( book, index, () => location.assign(`page-edit.html?id=${book.id}`), () => removeLine(book.id), ), ); }); } async function addLine(categoriesId, name, authorsId, year, image) { console.info("Try to add item"); // вызов метода REST API для добавления записи const data = await addBook(categoriesId, name, authorsId, year, image); console.info("Added"); console.info(data); // загрузка и заполнение table drawTable(); } async function editLine(id, categoriesId, name, authorsId, year, image) { console.info("Try to update item"); // вызов метода REST API для обновления записи const data = await updateBook(id, categoriesId, name, authorsId, year, image); console.info("Updated"); console.info(data); // загрузка и заполнение table drawTable(); } async function removeLine(id) { if (!confirm("Do you really want to remove this item?")) { console.info("Canceled"); return; } console.info("Try to remove item"); // вызов метода REST API для удаления записи const data = await deleteLine(id); console.info(data); // загрузка и заполнение table drawTable(); } // функция для обновления блока с превью выбранного изображения async function updateImagePreview() { // получение выбранного файла // возможен выбор нескольких файлов, поэтому необходимо получить только первый const file = cntrls.imageInput.files[0]; // чтение содержимого файла в виде base64 строки const fileContent = await readFile(file); console.info("base64 ", fileContent); // обновление атрибута src для тега img с id image-preview cntrls.imagePreview.src = fileContent; } // Функция для обработки создания и редактирования элементов таблицы через страницу export async function linesPageForm() { console.info("linesPageForm"); drawSelects(); drawTable(); const goBack = () => location.assign("./admin-page.html"); cntrls.imageInput.addEventListener("change", () => updateImagePreview()); // получение параметров GET-запроса из URL // параметры перечислены после символа ? (?id=1&color=black&...) const urlParams = new URLSearchParams(location.search); // получение значения конкретного параметра (id) // указан только при редактировании const currentId = urlParams.get("id"); // если id задан if (currentId) { try { const book = await getBook(currentId); cntrls.categoryInput.value = book.categoriesId; cntrls.nameInput.value = book.name; cntrls.authorInput.value = book.authorsId; cntrls.yearInput.value = book.year; cntrls.imagePreview.src = book.image ? book.image : imagePlaceholder; } catch { goBack(); } } cntrls.form.addEventListener("submit", async (event) => { console.info("Form onSubmit"); // отключение стандартного поведения формы при отправке // при отправке страница обновляется и JS перестает работать event.preventDefault(); event.stopPropagation(); // если форма не прошла валидацию, то ничего делать не нужно if (!cntrls.form.checkValidity()) { return; } let imageBase64 = ""; if (cntrls.imagePreview.src !== imagePlaceholder) { // Загрузка содержимого атрибута src тэга img с id image-preview // Здесь выполняется HTTP запрос с типом GET const result = await fetch(cntrls.imagePreview.src); // Получение из HTTP-ответа бинарного содержимого const blob = await result.blob(); // Получение base64 строки для файла imageBase64 = await readFile(blob); } if (!currentId) { await addLine( cntrls.categoryInput.value, cntrls.nameInput.value, cntrls.authorInput.value, cntrls.yearInput.value, imageBase64, ); } else { await editLine( currentId, cntrls.categoryInput.value, cntrls.nameInput.value, cntrls.authorInput.value, cntrls.yearInput.value, imageBase64, ); } goBack(); }); } // функция для получения содержимого файла в виде base64 строки // https://ru.wikipedia.org/wiki/Base64 async function readFile(file) { const reader = new FileReader(); // создание Promise-объекта для использования функции // с помощью await (асинхронно) без коллбэков (callback) // https://learn.javascript.ru/promise return new Promise((resolve, reject) => { // 2. "Возвращаем" содержимое когда файл прочитан // через вызов resolve // Если не использовать Promise, то всю работу по взаимодействию // с REST API пришлось бы делать в обработчике (callback) функции // onloadend reader.onloadend = () => { const fileContent = reader.result; // Здесь могла бы быть работа с REST API // Чтение заканчивает выполняться здесь resolve(fileContent); }; // 3. Возвращаем ошибку reader.onerror = () => { // Или здесь в случае ошибки reject(new Error("oops, something went wrong with the file reader.")); }; // Шаг 1. Сначала читаем файл // Чтение начинает выполняться здесь reader.readAsDataURL(file); }); }